@@ -32,7 +32,7 @@ namespace foam
32
32
namespace
33
33
{
34
34
35
- template <typename T, typename E, EnableIf<std:: decay_t <E>, IsImage> = false >
35
+ template <typename T, typename E>
36
36
auto computeGeometry (E&& src, T poni1, T poni2, T pixel1, T pixel2)
37
37
{
38
38
auto shape = src.shape ();
@@ -51,20 +51,13 @@ auto computeGeometry(E&& src, T poni1, T poni2, T pixel1, T pixel2)
51
51
return geometry;
52
52
}
53
53
54
- template <typename T, typename E, EnableIf<std::decay_t <E>, IsImage> = false >
55
- auto histogramAI (E&& src, const xt::xtensor<T, 2 >& geometry, T q_min, T q_max,
56
- size_t n_bins, size_t min_count=1 )
54
+ template <typename E1 , typename E2 , typename E3 , typename T>
55
+ void histogramAI (E1 && src, const E2 & geometry, E3 & hist, T q_min, T q_max, size_t n_bins, size_t min_count)
57
56
{
58
- auto shape = src.shape ();
59
-
60
- using vector_type = ReducedVectorType<E, T>;
61
-
62
57
T norm = T (1 ) / (q_max - q_min);
63
-
64
- vector_type edges = xt::linspace<T>(q_min, q_max, n_bins + 1 );
65
- vector_type hist = xt::zeros<T>({ n_bins });
66
58
xt::xtensor<size_t , 1 > counts = xt::zeros<size_t >({ n_bins });
67
59
60
+ auto shape = src.shape ();
68
61
for (size_t i = 0 ; i < shape[0 ]; ++i)
69
62
{
70
63
for (size_t j = 0 ; j < shape[1 ]; ++j)
@@ -103,7 +96,21 @@ auto histogramAI(E&& src, const xt::xtensor<T, 2>& geometry, T q_min, T q_max,
103
96
else
104
97
hist (i) /= counts (i);
105
98
}
99
+ }
100
+
101
+ template <typename T, typename E, EnableIf<std::decay_t <E>, IsImage> = false >
102
+ auto histogramAI (E&& src, const xt::xtensor<T, 2 >& geometry, T q_min, T q_max,
103
+ size_t n_bins, size_t min_count=1 )
104
+ {
105
+ auto shape = src.shape ();
106
106
107
+ using vector_type = ReducedVectorType<E, T>;
108
+
109
+ vector_type hist = xt::zeros<T>({ n_bins });
110
+
111
+ histogramAI (std::forward<E>(src), geometry, hist, q_min, q_max, n_bins, min_count);
112
+
113
+ vector_type edges = xt::linspace<T>(q_min, q_max, n_bins + 1 );
107
114
auto && centers = 0.5 * (xt::view (edges, xt::range (0 , -1 )) + xt::view (edges, xt::range (1 , xt::placeholders::_)));
108
115
109
116
return std::make_pair<vector_type, vector_type>(centers, std::move (hist));
@@ -119,6 +126,43 @@ auto histogramAI(E&& src, T poni1, T poni2, T pixel1, T pixel2, size_t npt, size
119
126
return histogramAI<T>(std::forward<E>(src), geometry, bounds[0 ], bounds[1 ], npt, min_count);
120
127
}
121
128
129
+ template <typename T, typename E, EnableIf<std::decay_t <E>, IsImageArray> = false >
130
+ auto histogramAI (E&& src, const xt::xtensor<T, 2 >& geometry, T q_min, T q_max,
131
+ size_t n_bins, size_t min_count=1 )
132
+ {
133
+ size_t np = src.shape ()[0 ];
134
+
135
+ using vector_type = ReducedVectorTypeFromArray<E, T>;
136
+ using image_type = ReducedImageType<E, T>;
137
+
138
+ image_type hist = xt::zeros<T>({ np, n_bins });
139
+
140
+ #if defined(FOAM_USE_TBB)
141
+ tbb::parallel_for (tbb::blocked_range<int >(0 , np),
142
+ [&src, &geometry, &hist, q_min, q_max, n_bins, min_count]
143
+ (const tbb::blocked_range<int > &block)
144
+ {
145
+ for (int k=block.begin (); k != block.end (); ++k)
146
+ {
147
+ #else
148
+ for (size_t k = 0 ; k < np; ++k)
149
+ {
150
+ #endif
151
+ auto hist_view = xt::view (hist, k, xt::all ());
152
+ histogramAI (xt::view (src, k, xt::all (), xt::all ()), geometry, hist_view,
153
+ q_min, q_max, n_bins, min_count);
154
+ }
155
+ #if defined(FOAM_USE_TBB)
156
+ }
157
+ );
158
+ #endif
159
+
160
+ vector_type edges = xt::linspace<T>(q_min, q_max, n_bins + 1 );
161
+ auto && centers = 0.5 * (xt::view (edges, xt::range (0 , -1 )) + xt::view (edges, xt::range (1 , xt::placeholders::_)));
162
+
163
+ return std::make_pair<vector_type, image_type>(centers, std::move (hist));
164
+ }
165
+
122
166
} // namespace
123
167
124
168
enum class AzimuthalIntegrationMethod
@@ -186,6 +230,10 @@ class AzimuthalIntegrator
186
230
template <typename E, EnableIf<std::decay_t <E>, IsImage> = false >
187
231
auto integrate1d (E&& src, size_t npt, size_t min_count=1 ,
188
232
AzimuthalIntegrationMethod method=AzimuthalIntegrationMethod::HISTOGRAM);
233
+
234
+ template <typename E, EnableIf<std::decay_t <E>, IsImageArray> = false >
235
+ auto integrate1d (E&& src, size_t npt, size_t min_count=1 ,
236
+ AzimuthalIntegrationMethod method=AzimuthalIntegrationMethod::HISTOGRAM);
189
237
};
190
238
191
239
template <typename T>
@@ -249,6 +297,34 @@ auto AzimuthalIntegrator<T>::integrate1d(E&& src,
249
297
}
250
298
}
251
299
300
+ template <typename T>
301
+ template <typename E, EnableIf<std::decay_t <E>, IsImageArray>>
302
+ auto AzimuthalIntegrator<T>::integrate1d (E&& src,
303
+ size_t npt,
304
+ size_t min_count,
305
+ AzimuthalIntegrationMethod method)
306
+ {
307
+ if (npt == 0 ) npt = 1 ;
308
+
309
+ auto src_shape = src.shape ();
310
+ std::array<size_t , 2 > q_shape = q_.shape ();
311
+ if (!initialized_ || src_shape[1 ] != q_shape[0 ] || src_shape[2 ] != q_shape[1 ])
312
+ {
313
+ initQ (xt::view (src, 0 , xt::all (), xt::all ()));
314
+ initialized_ = true ;
315
+ }
316
+
317
+ switch (method)
318
+ {
319
+ case AzimuthalIntegrationMethod::HISTOGRAM:
320
+ {
321
+ return histogramAI (std::forward<E>(src), q_, q_min_, q_max_, npt, min_count);
322
+ }
323
+ default :
324
+ throw std::runtime_error (" Unknown azimuthal integration method" );
325
+ }
326
+ }
327
+
252
328
/* *
253
329
* class for finding the center of concentric rings in an image.
254
330
*/
0 commit comments