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)
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
LSST DM logging module built on log4cxx.
#define LOGL_WARN(logger, message...)
Log a warn-level message using a varargs/printf style interface.
#define LOG_GET(logger)
Returns a Log object associated with logger.
int getWidth() const
Return the number of columns in the image.
int getHeight() const
Return the number of rows in the image.
A class to represent a 2-dimensional array of pixels.
A class to manipulate images, masks, and variance as a single object.
int getHeight() const
Return the number of rows in the image.
lsst::afw::image::pixel::Pixel< ImagePixelT, MaskPixelT, VariancePixelT > Pixel
A Pixel in the MaskedImage.
x_iterator row_end(int y) const
Return an x_iterator to the end of the image.
x_iterator row_begin(int y) const
Return an x_iterator to the start of the image.
MaskedImageIterator< typename Image::iterator, typename Mask::iterator, typename Variance::iterator > iterator
Pass parameters to a Statistics object.
bool getWeighted() const noexcept
A class to evaluate image statistics.
double getError(Property const prop=NOTHING) const
Return the error in the desired property (if specified in the constructor)
double getValue(Property const prop=NOTHING) const
Return the value of the desired property (if specified in the constructor)
An integer coordinate rectangle.
Reports invalid arguments.
Reports attempts to exceed implementation-defined length limits for some classes.
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
Statistics makeStatistics(lsst::afw::image::Image< Pixel > const &img, lsst::afw::image::Mask< image::MaskPixel > const &msk, int const flags, StatisticsControl const &sctrl=StatisticsControl())
Handle a watered-down front-end to the constructor (no variance)
Property
control what is calculated
@ ERRORS
Include errors of requested quantities.
@ NCLIPPED
number of clipped points
@ NMASKED
number of masked points
@ NPOINT
number of sample points
std::shared_ptr< lsst::afw::image::Image< PixelT > > statisticsStack(std::vector< std::shared_ptr< lsst::afw::image::Image< PixelT >>> &images, Property flags, StatisticsControl const &sctrl=StatisticsControl(), std::vector< lsst::afw::image::VariancePixel > const &wvector=std::vector< lsst::afw::image::VariancePixel >(0))
A function to compute some statistics of a stack of Images.
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
A base class for image defects.