GooseEYE 0.9.1
Loading...
Searching...
No Matches
Ensemble_C2.hpp
Go to the documentation of this file.
1
7#ifndef GOOSEEYE_ENSEMBLE_C2_HPP
8#define GOOSEEYE_ENSEMBLE_C2_HPP
9
10#include "GooseEYE.h"
11
12namespace GooseEYE {
13
14template <class T, class M>
15inline void Ensemble::C2(const T& f, const T& g, const M& fmask, const M& gmask)
16{
17 using value_type = typename T::value_type;
18 using mask_type = typename M::value_type;
19
20 static_assert(std::is_integral<value_type>::value, "Integral image required.");
21 static_assert(std::is_integral<mask_type>::value, "Integral mask required.");
22
23 GOOSEEYE_ASSERT(xt::has_shape(f, g.shape()), std::out_of_range);
24 GOOSEEYE_ASSERT(xt::has_shape(f, fmask.shape()), std::out_of_range);
25 GOOSEEYE_ASSERT(xt::has_shape(f, gmask.shape()), std::out_of_range);
26 GOOSEEYE_ASSERT(f.dimension() == m_shape_orig.size(), std::out_of_range);
27 GOOSEEYE_ASSERT(xt::all(xt::equal(fmask, 0) || xt::equal(fmask, 1)), std::out_of_range);
28 GOOSEEYE_ASSERT(xt::all(xt::equal(gmask, 0) || xt::equal(gmask, 1)), std::out_of_range);
29 GOOSEEYE_ASSERT(m_stat == Type::C2 || m_stat == Type::Unset, std::out_of_range);
30
31 // lock statistic
32 m_stat = Type::C2;
33
34 // not periodic (default): mask padded items
35 xt::pad_mode pad_mode = xt::pad_mode::constant;
36 int mask_value = 1;
37
38 // periodic: unmask padded items
39 if (m_periodic) {
40 pad_mode = xt::pad_mode::periodic;
41 mask_value = 0;
42 }
43
44 // apply padding
45 array_type::tensor<value_type, 3> F = xt::pad(xt::atleast_3d(f), m_pad, pad_mode);
46 array_type::tensor<value_type, 3> G = xt::pad(xt::atleast_3d(g), m_pad, pad_mode);
48 xt::pad(xt::atleast_3d(fmask), m_pad, xt::pad_mode::constant, mask_value);
50 xt::pad(xt::atleast_3d(gmask), m_pad, xt::pad_mode::constant, mask_value);
51
52 // compute correlation
53 for (size_t h = m_pad[0][0]; h < F.shape(0) - m_pad[0][1]; ++h) {
54 for (size_t i = m_pad[1][0]; i < F.shape(1) - m_pad[1][1]; ++i) {
55 for (size_t j = m_pad[2][0]; j < F.shape(2) - m_pad[2][1]; ++j) {
56 // - skip masked
57 if (Fmask(h, i, j)) {
58 continue;
59 }
60 // - get comparison sub-matrix
61 auto Gi = xt::view(
62 G,
63 xt::range(h - m_pad[0][0], h + m_pad[0][1] + 1),
64 xt::range(i - m_pad[1][0], i + m_pad[1][1] + 1),
65 xt::range(j - m_pad[2][0], j + m_pad[2][1] + 1));
66 // - get inverse of comparison mask
67 auto Gmii = 1.0 - xt::view(
68 Gmask,
69 xt::range(h - m_pad[0][0], h + m_pad[0][1] + 1),
70 xt::range(i - m_pad[1][0], i + m_pad[1][1] + 1),
71 xt::range(j - m_pad[2][0], j + m_pad[2][1] + 1));
72 // - correlation (account for mask)
73 if (F(h, i, j) != 0) {
74 m_first += xt::where(xt::equal(F(h, i, j), Gi), Gmii, 0.0);
75 }
76 // - normalisation
77 m_norm += Gmii;
78 }
79 }
80 }
81}
82
83template <class T>
84inline void Ensemble::C2(const T& f, const T& g)
85{
86 array_type::array<int> mask = xt::zeros<int>(f.shape());
87 C2(f, g, mask, mask);
88}
89
90} // namespace GooseEYE
91
92#endif
void C2(const T &f, const T &g)
Add realization to 2-point cluster function: P(f(i) == g(i + di)).
#define GOOSEEYE_ASSERT(expr, assertion)
All assertions are implemented as:
Definition config.h:91
xt::xtensor< T, N > tensor
Fixed (static) rank array.
Definition config.h:155
Toolbox to compute statistics.
Definition config.h:128