54 int bitcount(
unsigned int x) {
56 for (
b = 0;
x != 0;
x >>= 1) {
67 void checkOnlyOneFlag(
unsigned int flags) {
68 if (bitcount(flags & ~
ERRORS) != 1) {
70 "Requested more than one type of statistic to make the image stack.");
77 template <
typename ObjectVectorT,
typename WeightVectorT>
78 void checkObjectsAndWeights(ObjectVectorT
const &objects, WeightVectorT
const &wvector) {
79 if (objects.size() == 0) {
83 if (!wvector.empty() && wvector.size() != objects.size()) {
86 "from number of objects to be stacked: %d v. %d") %
87 wvector.size() % objects.size()));
91 template <
typename ImageT>
94 for (
unsigned int i = 0; i < images.size(); ++i) {
95 if (images[i]->getDimensions() != dim) {
97 (
boost::format(
"Bad dimensions for image %d: %dx%d vs %dx%d") % i %
98 images[i]->getDimensions().getX() % images[i]->getDimensions().getY() %
99 dim.getX() % dim.getY())
120 template <
typename PixelT,
bool isWeighted,
bool useVariance>
125 WeightVector
const &wvector = WeightVector()) {
131 MaskedVector<PixelT> pixelSet(images.size());
132 WeightVector weights;
134 StatisticsControl sctrlTmp(sctrl);
138 assert(wvector.empty());
140 weights.resize(images.size());
142 sctrlTmp.setWeighted(
true);
143 }
else if (isWeighted) {
144 weights.assign(wvector.begin(), wvector.end());
146 sctrlTmp.setWeighted(
true);
148 assert(weights.empty() || weights.size() == images.size());
153 for (
unsigned int i = 0; i < images.size(); ++i) {
154 x_iterator
ptr = images[i]->row_begin(
y);
164 WeightVector::iterator wtPtr = weights.begin();
165 for (
unsigned int i = 0; i < images.size(); ++rows[i], ++i, ++psPtr, ++wtPtr) {
168 *wtPtr = 1.0 / rows[i].variance();
173 Statistics stat = isWeighted ?
makeStatistics(pixelSet, weights, eflags, sctrlTmp)
178 int const npoint = stat.getValue(
NPOINT);
180 msk = sctrlTmp.getNoGoodPixelsMask();
181 }
else if (npoint == 1) {
193 if (stat.getValue(
NMASKED) > 0) {
194 for (
auto const &pair : maskMap) {
195 for (
auto pp = pixelSet.begin(); pp != pixelSet.end(); ++pp) {
196 if ((*pp).mask() & pair.first) {
208 template <
typename PixelT,
bool isWeighted,
bool useVariance>
212 image::MaskPixel const excuse, WeightVector
const &wvector = WeightVector()) {
215 computeMaskedImageStack<PixelT, isWeighted, useVariance>(imgStack, images, flags, sctrl, clipped, maskMap,
222 template <
typename PixelT>
227 if (images.size() == 0) {
236 template <
typename PixelT>
241 if (images.size() == 0) {
246 statisticsStack(*out, images, flags, sctrl, wvector, clipped, maskMap);
250 template <
typename PixelT>
255 checkObjectsAndWeights(images, wvector);
256 checkOnlyOneFlag(flags);
257 checkImageSizes(out, images);
260 if (wvector.empty()) {
261 return computeMaskedImageStack<PixelT, true, true>(out, images, flags, sctrl, clipped,
264 return computeMaskedImageStack<PixelT, true, false>(out, images, flags, sctrl, clipped, excuse,
268 if (!wvector.empty()) {
270 "Weights passed on to statisticsStack are ignored as sctrl.getWeighted() is False."
271 "Set sctrl.setWeighted(True) for them to be used.");
273 return computeMaskedImageStack<PixelT, false, false>(out, images, flags, sctrl, clipped, excuse);
277 template <
typename PixelT>
282 checkObjectsAndWeights(images, wvector);
283 checkOnlyOneFlag(flags);
284 checkImageSizes(out, images);
287 if (wvector.empty()) {
288 return computeMaskedImageStack<PixelT, true, true>(out, images, flags, sctrl, clipped,
291 return computeMaskedImageStack<PixelT, true, false>(out, images, flags, sctrl, clipped, maskMap,
295 return computeMaskedImageStack<PixelT, false, false>(out, images, flags, sctrl, clipped, maskMap);
315 template <
typename PixelT,
bool isWeighted>
318 StatisticsControl
const &sctrl, WeightVector
const &weights = WeightVector()) {
319 MaskedVector<PixelT> pixelSet(images.size());
320 StatisticsControl sctrlTmp(sctrl);
323 MaskImposter<image::MaskPixel> msk;
325 if (!weights.empty()) {
326 sctrlTmp.setWeighted(
true);
332 for (
unsigned int i = 0; i != images.size(); ++i) {
333 (*pixelSet.getImage())(i, 0) = (*images[i])(
x,
y);
347 template <
typename PixelT>
351 if (images.size() == 0) {
359 template <
typename PixelT>
362 checkObjectsAndWeights(images, wvector);
363 checkOnlyOneFlag(flags);
364 checkImageSizes(out, images);
366 if (wvector.empty()) {
367 return computeImageStack<PixelT, false>(out, images, flags, sctrl);
369 return computeImageStack<PixelT, true>(out, images, flags, sctrl, wvector);
387 template <
typename PixelT,
bool isWeighted>
390 StatisticsControl
const &sctrl, WeightVector
const &wvector = WeightVector()) {
393 Vect vecStack(vectors[0].size(), 0.0);
395 MaskedVector<PixelT> pixelSet(vectors.size());
397 StatisticsControl sctrlTmp(sctrl);
399 MaskImposter<image::MaskPixel> msk;
401 if (!wvector.empty()) {
402 sctrlTmp.setWeighted(
true);
406 for (
unsigned int x = 0;
x < vectors[0].size(); ++
x) {
408 for (
unsigned int i = 0; i < vectors.size(); ++i, ++psPtr) {
409 psPtr.value() = (vectors[i])[
x];
424 template <
typename PixelT>
428 checkObjectsAndWeights(vectors, wvector);
429 checkOnlyOneFlag(flags);
431 if (wvector.empty()) {
432 return computeVectorStack<PixelT, false>(vectors, flags, sctrl);
434 return computeVectorStack<PixelT, true>(vectors, flags, sctrl, wvector);
444 template <
typename PixelT>
447 int x0 =
image.getX0();
448 int y0 =
image.getY0();
454 if (dimension ==
'x') {
457 typename MImage::y_iterator oEnd = imgOut->col_end(0);
458 for (
typename MImage::y_iterator oPtr = imgOut->col_begin(0); oPtr != oEnd; ++oPtr, ++
y) {
467 }
else if (dimension ==
'y') {
470 typename MImage::x_iterator oEnd = imgOut->row_end(0);
471 for (
typename MImage::x_iterator oPtr = imgOut->row_begin(0); oPtr != oEnd; ++oPtr, ++
x) {
481 "Can only run statisticsStack in x or y for single image.");
487 template <
typename PixelT>
491 int const x0 =
image.getX0();
492 int const y0 =
image.getY0();
498 if (dimension ==
'x') {
501 typename MImage::y_iterator oEnd = imgOut->col_end(0);
502 for (
typename MImage::y_iterator oPtr = imgOut->col_begin(0); oPtr != oEnd; ++oPtr, ++
y) {
511 }
else if (dimension ==
'y') {
514 typename MImage::x_iterator oEnd = imgOut->row_end(0);
515 for (
typename MImage::x_iterator oPtr = imgOut->row_begin(0); oPtr != oEnd; ++oPtr, ++
x) {
525 "Can only run statisticsStack in x or y for single image.");
536 #define INSTANTIATE_STACKS(TYPE) \
537 template std::shared_ptr<image::Image<TYPE>> statisticsStack<TYPE>( \
538 std::vector<std::shared_ptr<image::Image<TYPE>>> & images, Property flags, \
539 StatisticsControl const &sctrl, WeightVector const &wvector); \
540 template void statisticsStack<TYPE>( \
541 image::Image<TYPE> & out, std::vector<std::shared_ptr<image::Image<TYPE>>> & images, \
542 Property flags, StatisticsControl const &sctrl, WeightVector const &wvector); \
543 template std::shared_ptr<image::MaskedImage<TYPE>> statisticsStack<TYPE>( \
544 std::vector<std::shared_ptr<image::MaskedImage<TYPE>>> & images, Property flags, \
545 StatisticsControl const &sctrl, WeightVector const &wvector, image::MaskPixel, \
547 template std::shared_ptr<image::MaskedImage<TYPE>> statisticsStack<TYPE>( \
548 std::vector<std::shared_ptr<image::MaskedImage<TYPE>>> & images, Property flags, \
549 StatisticsControl const &sctrl, WeightVector const &wvector, image::MaskPixel, \
550 std::vector<std::pair<image::MaskPixel, image::MaskPixel>> const &); \
551 template void statisticsStack<TYPE>(image::MaskedImage<TYPE> & out, \
552 std::vector<std::shared_ptr<image::MaskedImage<TYPE>>> & images, \
553 Property flags, StatisticsControl const &sctrl, \
554 WeightVector const &wvector, image::MaskPixel, image::MaskPixel); \
555 template void statisticsStack<TYPE>( \
556 image::MaskedImage<TYPE> & out, std::vector<std::shared_ptr<image::MaskedImage<TYPE>>> & images, \
557 Property flags, StatisticsControl const &sctrl, WeightVector const &wvector, image::MaskPixel, \
558 std::vector<std::pair<image::MaskPixel, image::MaskPixel>> const &); \
559 template std::vector<TYPE> statisticsStack<TYPE>( \
560 std::vector<std::vector<TYPE>> & vectors, Property flags, \
561 StatisticsControl const &sctrl, WeightVector const &wvector); \
562 template std::shared_ptr<image::MaskedImage<TYPE>> statisticsStack(image::Image<TYPE> const &image, \
563 Property flags, char dimension, \
564 StatisticsControl const &sctrl); \
565 template std::shared_ptr<image::MaskedImage<TYPE>> statisticsStack( \
566 image::MaskedImage<TYPE> const &image, Property flags, char dimension, \
567 StatisticsControl const &sctrl);
569 INSTANTIATE_STACKS(
double)
570 INSTANTIATE_STACKS(
float)