53int bitcount(
unsigned int x) {
55 for (
b = 0;
x != 0;
x >>= 1) {
66void checkOnlyOneFlag(
unsigned int flags) {
67 if (bitcount(flags & ~
ERRORS) != 1) {
69 "Requested more than one type of statistic to make the image stack.");
76template <
typename ObjectVectorT,
typename WeightVectorT>
77void checkObjectsAndWeights(ObjectVectorT
const &objects, WeightVectorT
const &wvector) {
78 if (objects.size() == 0) {
82 if (!wvector.empty() && wvector.size() != objects.size()) {
84 str(boost::format(
"Weight vector has different length "
85 "from number of objects to be stacked: %d v. %d") %
86 wvector.size() % objects.size()));
90template <
typename ImageT>
93 for (
unsigned int i = 0; i < images.size(); ++i) {
94 if (images[i]->getDimensions() != dim) {
96 (boost::format(
"Bad dimensions for image %d: %dx%d vs %dx%d") % i %
97 images[i]->getDimensions().getX() % images[i]->getDimensions().getY() %
98 dim.getX() % dim.getY())
119template <
typename PixelT,
bool isWeighted,
bool useVariance>
124 WeightVector
const &wvector = WeightVector()) {
130 MaskedVector<PixelT> pixelSet(images.size());
131 WeightVector weights;
133 StatisticsControl sctrlTmp(sctrl);
137 assert(wvector.empty());
139 weights.resize(images.size());
141 sctrlTmp.setWeighted(
true);
142 }
else if (isWeighted) {
143 weights.assign(wvector.begin(), wvector.end());
145 sctrlTmp.setWeighted(
true);
147 assert(weights.empty() || weights.size() == images.size());
152 for (
unsigned int i = 0; i < images.size(); ++i) {
153 x_iterator
ptr = images[i]->row_begin(
y);
162 typename MaskedVector<PixelT>::iterator psPtr = pixelSet.begin();
163 WeightVector::iterator wtPtr = weights.begin();
164 for (
unsigned int i = 0; i < images.size(); ++rows[i], ++i, ++psPtr, ++wtPtr) {
167 *wtPtr = 1.0 / rows[i].variance();
177 int const npoint = stat.getValue(
NPOINT);
179 msk = sctrlTmp.getNoGoodPixelsMask();
180 }
else if (npoint == 1) {
192 if (stat.getValue(
NMASKED) > 0) {
193 for (
auto const &pair : maskMap) {
194 for (
auto pp = pixelSet.begin(); pp != pixelSet.end(); ++pp) {
195 if ((*pp).mask() & pair.first) {
207template <
typename PixelT,
bool isWeighted,
bool useVariance>
211 image::MaskPixel const excuse, WeightVector
const &wvector = WeightVector()) {
213 maskMap.
emplace_back(sctrl.getAndMask() & ~excuse, clipped);
214 computeMaskedImageStack<PixelT, isWeighted, useVariance>(imgStack, images, flags, sctrl, clipped, maskMap,
221template <
typename PixelT>
226 if (images.size() == 0) {
235template <
typename PixelT>
240 if (images.size() == 0) {
245 statisticsStack(*out, images, flags, sctrl, wvector, clipped, maskMap);
249template <
typename PixelT>
254 checkObjectsAndWeights(images, wvector);
255 checkOnlyOneFlag(flags);
256 checkImageSizes(out, images);
259 if (wvector.empty()) {
260 return computeMaskedImageStack<PixelT, true, true>(out, images, flags, sctrl, clipped,
263 return computeMaskedImageStack<PixelT, true, false>(out, images, flags, sctrl, clipped, excuse,
267 if (!wvector.empty()) {
269 "Weights passed on to statisticsStack are ignored as sctrl.getWeighted() is False."
270 "Set sctrl.setWeighted(True) for them to be used.");
272 return computeMaskedImageStack<PixelT, false, false>(out, images, flags, sctrl, clipped, excuse);
276template <
typename PixelT>
281 checkObjectsAndWeights(images, wvector);
282 checkOnlyOneFlag(flags);
283 checkImageSizes(out, images);
286 if (wvector.empty()) {
287 return computeMaskedImageStack<PixelT, true, true>(out, images, flags, sctrl, clipped,
290 return computeMaskedImageStack<PixelT, true, false>(out, images, flags, sctrl, clipped, maskMap,
294 return computeMaskedImageStack<PixelT, false, false>(out, images, flags, sctrl, clipped, maskMap);
314template <
typename PixelT,
bool isWeighted>
317 StatisticsControl
const &sctrl, WeightVector
const &weights = WeightVector()) {
318 MaskedVector<PixelT> pixelSet(images.size());
319 StatisticsControl sctrlTmp(sctrl);
322 MaskImposter<image::MaskPixel> msk;
324 if (!weights.empty()) {
325 sctrlTmp.setWeighted(
true);
331 for (
unsigned int i = 0; i != images.size(); ++i) {
332 (*pixelSet.getImage())(i, 0) = (*images[i])(
x,
y);
346template <
typename PixelT>
350 if (images.size() == 0) {
358template <
typename PixelT>
361 checkObjectsAndWeights(images, wvector);
362 checkOnlyOneFlag(flags);
363 checkImageSizes(out, images);
365 if (wvector.empty()) {
366 return computeImageStack<PixelT, false>(out, images, flags, sctrl);
368 return computeImageStack<PixelT, true>(out, images, flags, sctrl, wvector);
386template <
typename PixelT,
bool isWeighted>
389 StatisticsControl
const &sctrl, WeightVector
const &wvector = WeightVector()) {
392 Vect vecStack(vectors[0].size(), 0.0);
394 MaskedVector<PixelT> pixelSet(vectors.size());
396 StatisticsControl sctrlTmp(sctrl);
398 MaskImposter<image::MaskPixel> msk;
400 if (!wvector.empty()) {
401 sctrlTmp.setWeighted(
true);
405 for (
unsigned int x = 0;
x < vectors[0].size(); ++
x) {
406 typename MaskedVector<PixelT>::iterator psPtr = pixelSet.begin();
407 for (
unsigned int i = 0; i < vectors.size(); ++i, ++psPtr) {
408 psPtr.value() = (vectors[i])[
x];
423template <
typename PixelT>
427 checkObjectsAndWeights(vectors, wvector);
428 checkOnlyOneFlag(flags);
430 if (wvector.empty()) {
431 return computeVectorStack<PixelT, false>(vectors, flags, sctrl);
433 return computeVectorStack<PixelT, true>(vectors, flags, sctrl, wvector);
443template <
typename PixelT>
446 int x0 =
image.getX0();
447 int y0 =
image.getY0();
453 if (dimension ==
'x') {
456 typename MImage::y_iterator oEnd = imgOut->col_end(0);
457 for (
typename MImage::y_iterator oPtr = imgOut->col_begin(0); oPtr != oEnd; ++oPtr, ++
y) {
466 }
else if (dimension ==
'y') {
469 typename MImage::x_iterator oEnd = imgOut->row_end(0);
470 for (
typename MImage::x_iterator oPtr = imgOut->row_begin(0); oPtr != oEnd; ++oPtr, ++
x) {
480 "Can only run statisticsStack in x or y for single image.");
486template <
typename PixelT>
490 int const x0 =
image.getX0();
491 int const y0 =
image.getY0();
497 if (dimension ==
'x') {
500 typename MImage::y_iterator oEnd = imgOut->col_end(0);
501 for (
typename MImage::y_iterator oPtr = imgOut->col_begin(0); oPtr != oEnd; ++oPtr, ++
y) {
510 }
else if (dimension ==
'y') {
513 typename MImage::x_iterator oEnd = imgOut->row_end(0);
514 for (
typename MImage::x_iterator oPtr = imgOut->row_begin(0); oPtr != oEnd; ++oPtr, ++
x) {
524 "Can only run statisticsStack in x or y for single image.");
535#define INSTANTIATE_STACKS(TYPE) \
536 template std::shared_ptr<image::Image<TYPE>> statisticsStack<TYPE>( \
537 std::vector<std::shared_ptr<image::Image<TYPE>>> & images, Property flags, \
538 StatisticsControl const &sctrl, WeightVector const &wvector); \
539 template void statisticsStack<TYPE>( \
540 image::Image<TYPE> & out, std::vector<std::shared_ptr<image::Image<TYPE>>> & images, \
541 Property flags, StatisticsControl const &sctrl, WeightVector const &wvector); \
542 template std::shared_ptr<image::MaskedImage<TYPE>> statisticsStack<TYPE>( \
543 std::vector<std::shared_ptr<image::MaskedImage<TYPE>>> & images, Property flags, \
544 StatisticsControl const &sctrl, WeightVector const &wvector, image::MaskPixel, \
546 template std::shared_ptr<image::MaskedImage<TYPE>> statisticsStack<TYPE>( \
547 std::vector<std::shared_ptr<image::MaskedImage<TYPE>>> & images, Property flags, \
548 StatisticsControl const &sctrl, WeightVector const &wvector, image::MaskPixel, \
549 std::vector<std::pair<image::MaskPixel, image::MaskPixel>> const &); \
550 template void statisticsStack<TYPE>(image::MaskedImage<TYPE> & out, \
551 std::vector<std::shared_ptr<image::MaskedImage<TYPE>>> & images, \
552 Property flags, StatisticsControl const &sctrl, \
553 WeightVector const &wvector, image::MaskPixel, image::MaskPixel); \
554 template void statisticsStack<TYPE>( \
555 image::MaskedImage<TYPE> & out, std::vector<std::shared_ptr<image::MaskedImage<TYPE>>> & images, \
556 Property flags, StatisticsControl const &sctrl, WeightVector const &wvector, image::MaskPixel, \
557 std::vector<std::pair<image::MaskPixel, image::MaskPixel>> const &); \
558 template std::vector<TYPE> statisticsStack<TYPE>( \
559 std::vector<std::vector<TYPE>> & vectors, Property flags, \
560 StatisticsControl const &sctrl, WeightVector const &wvector); \
561 template std::shared_ptr<image::MaskedImage<TYPE>> statisticsStack(image::Image<TYPE> const &image, \
562 Property flags, char dimension, \
563 StatisticsControl const &sctrl); \
564 template std::shared_ptr<image::MaskedImage<TYPE>> statisticsStack( \
565 image::MaskedImage<TYPE> const &image, Property flags, char dimension, \
566 StatisticsControl const &sctrl);
568INSTANTIATE_STACKS(
double)
569INSTANTIATE_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.
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.
T emplace_back(T... args)
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.
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