49 int bitcount(
unsigned int x) {
51 for (
b = 0;
x != 0;
x >>= 1) {
62 void checkOnlyOneFlag(
unsigned int flags) {
63 if (bitcount(flags & ~
ERRORS) != 1) {
65 "Requested more than one type of statistic to make the image stack.");
72 template <
typename ObjectVectorT,
typename WeightVectorT>
73 void checkObjectsAndWeights(ObjectVectorT
const &objects, WeightVectorT
const &wvector) {
74 if (objects.size() == 0) {
78 if (!wvector.empty() && wvector.size() != objects.size()) {
81 "from number of objects to be stacked: %d v. %d") %
82 wvector.size() % objects.size()));
86 template <
typename ImageT>
89 for (
unsigned int i = 0; i < images.size(); ++i) {
90 if (images[i]->getDimensions() != dim) {
92 (
boost::format(
"Bad dimensions for image %d: %dx%d vs %dx%d") % i %
93 images[i]->getDimensions().getX() % images[i]->getDimensions().getY() %
94 dim.getX() % dim.getY())
115 template <
typename PixelT,
bool isWeighted,
bool useVariance>
120 WeightVector
const &wvector = WeightVector()) {
126 MaskedVector<PixelT> pixelSet(images.size());
127 WeightVector weights;
129 StatisticsControl sctrlTmp(sctrl);
133 assert(wvector.empty());
135 weights.resize(images.size());
137 sctrlTmp.setWeighted(
true);
138 }
else if (isWeighted) {
139 weights.assign(wvector.begin(), wvector.end());
141 sctrlTmp.setWeighted(
true);
143 assert(weights.empty() || weights.size() == images.size());
148 for (
unsigned int i = 0; i < images.size(); ++i) {
149 x_iterator
ptr = images[i]->row_begin(
y);
159 WeightVector::iterator wtPtr = weights.begin();
160 for (
unsigned int i = 0; i < images.size(); ++rows[i], ++i, ++psPtr, ++wtPtr) {
163 *wtPtr = 1.0 / rows[i].variance();
168 Statistics stat = isWeighted ?
makeStatistics(pixelSet, weights, eflags, sctrlTmp)
173 int const npoint = stat.getValue(
NPOINT);
175 msk = sctrlTmp.getNoGoodPixelsMask();
176 }
else if (npoint == 1) {
188 if (stat.getValue(
NMASKED) > 0) {
189 for (
auto const &pair : maskMap) {
190 for (
auto pp = pixelSet.begin(); pp != pixelSet.end(); ++pp) {
191 if ((*pp).mask() & pair.first) {
203 template <
typename PixelT,
bool isWeighted,
bool useVariance>
207 image::MaskPixel const excuse, WeightVector
const &wvector = WeightVector()) {
210 computeMaskedImageStack<PixelT, isWeighted, useVariance>(imgStack, images, flags, sctrl, clipped, maskMap,
217 template <
typename PixelT>
222 if (images.size() == 0) {
231 template <
typename PixelT>
236 if (images.size() == 0) {
241 statisticsStack(*out, images, flags, sctrl, wvector, clipped, maskMap);
245 template <
typename PixelT>
250 checkObjectsAndWeights(images, wvector);
251 checkOnlyOneFlag(flags);
252 checkImageSizes(out, images);
255 if (wvector.empty()) {
256 return computeMaskedImageStack<PixelT, true, true>(out, images, flags, sctrl, clipped,
259 return computeMaskedImageStack<PixelT, true, false>(out, images, flags, sctrl, clipped, excuse,
263 return computeMaskedImageStack<PixelT, false, false>(out, images, flags, sctrl, clipped, excuse);
267 template <
typename PixelT>
272 checkObjectsAndWeights(images, wvector);
273 checkOnlyOneFlag(flags);
274 checkImageSizes(out, images);
277 if (wvector.empty()) {
278 return computeMaskedImageStack<PixelT, true, true>(out, images, flags, sctrl, clipped,
281 return computeMaskedImageStack<PixelT, true, false>(out, images, flags, sctrl, clipped, maskMap,
285 return computeMaskedImageStack<PixelT, false, false>(out, images, flags, sctrl, clipped, maskMap);
305 template <
typename PixelT,
bool isWeighted>
308 StatisticsControl
const &sctrl, WeightVector
const &weights = WeightVector()) {
309 MaskedVector<PixelT> pixelSet(images.size());
310 StatisticsControl sctrlTmp(sctrl);
313 MaskImposter<image::MaskPixel> msk;
315 if (!weights.empty()) {
316 sctrlTmp.setWeighted(
true);
322 for (
unsigned int i = 0; i != images.size(); ++i) {
323 (*pixelSet.getImage())(i, 0) = (*images[i])(
x,
y);
337 template <
typename PixelT>
341 if (images.size() == 0) {
349 template <
typename PixelT>
352 checkObjectsAndWeights(images, wvector);
353 checkOnlyOneFlag(flags);
354 checkImageSizes(out, images);
356 if (wvector.empty()) {
357 return computeImageStack<PixelT, false>(out, images, flags, sctrl);
359 return computeImageStack<PixelT, true>(out, images, flags, sctrl, wvector);
377 template <
typename PixelT,
bool isWeighted>
380 StatisticsControl
const &sctrl, WeightVector
const &wvector = WeightVector()) {
383 Vect vecStack(vectors[0].size(), 0.0);
385 MaskedVector<PixelT> pixelSet(vectors.size());
387 StatisticsControl sctrlTmp(sctrl);
389 MaskImposter<image::MaskPixel> msk;
391 if (!wvector.empty()) {
392 sctrlTmp.setWeighted(
true);
396 for (
unsigned int x = 0;
x < vectors[0].size(); ++
x) {
398 for (
unsigned int i = 0; i < vectors.size(); ++i, ++psPtr) {
399 psPtr.value() = (vectors[i])[
x];
414 template <
typename PixelT>
418 checkObjectsAndWeights(vectors, wvector);
419 checkOnlyOneFlag(flags);
421 if (wvector.empty()) {
422 return computeVectorStack<PixelT, false>(vectors, flags, sctrl);
424 return computeVectorStack<PixelT, true>(vectors, flags, sctrl, wvector);
434 template <
typename PixelT>
437 int x0 =
image.getX0();
438 int y0 =
image.getY0();
444 if (dimension ==
'x') {
447 typename MImage::y_iterator oEnd = imgOut->col_end(0);
448 for (
typename MImage::y_iterator oPtr = imgOut->col_begin(0); oPtr != oEnd; ++oPtr, ++
y) {
457 }
else if (dimension ==
'y') {
460 typename MImage::x_iterator oEnd = imgOut->row_end(0);
461 for (
typename MImage::x_iterator oPtr = imgOut->row_begin(0); oPtr != oEnd; ++oPtr, ++
x) {
471 "Can only run statisticsStack in x or y for single image.");
477 template <
typename PixelT>
481 int const x0 =
image.getX0();
482 int const y0 =
image.getY0();
488 if (dimension ==
'x') {
491 typename MImage::y_iterator oEnd = imgOut->col_end(0);
492 for (
typename MImage::y_iterator oPtr = imgOut->col_begin(0); oPtr != oEnd; ++oPtr, ++
y) {
501 }
else if (dimension ==
'y') {
504 typename MImage::x_iterator oEnd = imgOut->row_end(0);
505 for (
typename MImage::x_iterator oPtr = imgOut->row_begin(0); oPtr != oEnd; ++oPtr, ++
x) {
515 "Can only run statisticsStack in x or y for single image.");
526 #define INSTANTIATE_STACKS(TYPE) \
527 template std::shared_ptr<image::Image<TYPE>> statisticsStack<TYPE>( \
528 std::vector<std::shared_ptr<image::Image<TYPE>>> & images, Property flags, \
529 StatisticsControl const &sctrl, WeightVector const &wvector); \
530 template void statisticsStack<TYPE>( \
531 image::Image<TYPE> & out, std::vector<std::shared_ptr<image::Image<TYPE>>> & images, \
532 Property flags, StatisticsControl const &sctrl, WeightVector const &wvector); \
533 template std::shared_ptr<image::MaskedImage<TYPE>> statisticsStack<TYPE>( \
534 std::vector<std::shared_ptr<image::MaskedImage<TYPE>>> & images, Property flags, \
535 StatisticsControl const &sctrl, WeightVector const &wvector, image::MaskPixel, \
537 template std::shared_ptr<image::MaskedImage<TYPE>> statisticsStack<TYPE>( \
538 std::vector<std::shared_ptr<image::MaskedImage<TYPE>>> & images, Property flags, \
539 StatisticsControl const &sctrl, WeightVector const &wvector, image::MaskPixel, \
540 std::vector<std::pair<image::MaskPixel, image::MaskPixel>> const &); \
541 template void statisticsStack<TYPE>(image::MaskedImage<TYPE> & out, \
542 std::vector<std::shared_ptr<image::MaskedImage<TYPE>>> & images, \
543 Property flags, StatisticsControl const &sctrl, \
544 WeightVector const &wvector, image::MaskPixel, image::MaskPixel); \
545 template void statisticsStack<TYPE>( \
546 image::MaskedImage<TYPE> & out, std::vector<std::shared_ptr<image::MaskedImage<TYPE>>> & images, \
547 Property flags, StatisticsControl const &sctrl, WeightVector const &wvector, image::MaskPixel, \
548 std::vector<std::pair<image::MaskPixel, image::MaskPixel>> const &); \
549 template std::vector<TYPE> statisticsStack<TYPE>( \
550 std::vector<std::vector<TYPE>> & vectors, Property flags, \
551 StatisticsControl const &sctrl, WeightVector const &wvector); \
552 template std::shared_ptr<image::MaskedImage<TYPE>> statisticsStack(image::Image<TYPE> const &image, \
553 Property flags, char dimension, \
554 StatisticsControl const &sctrl); \
555 template std::shared_ptr<image::MaskedImage<TYPE>> statisticsStack( \
556 image::MaskedImage<TYPE> const &image, Property flags, char dimension, \
557 StatisticsControl const &sctrl);
559 INSTANTIATE_STACKS(
double)
560 INSTANTIATE_STACKS(
float)