LSST Applications g180d380827+0f66a164bb,g2079a07aa2+86d27d4dc4,g2305ad1205+7d304bc7a0,g29320951ab+500695df56,g2bbee38e9b+0e5473021a,g337abbeb29+0e5473021a,g33d1c0ed96+0e5473021a,g3a166c0a6a+0e5473021a,g3ddfee87b4+e42ea45bea,g48712c4677+36a86eeaa5,g487adcacf7+2dd8f347ac,g50ff169b8f+96c6868917,g52b1c1532d+585e252eca,g591dd9f2cf+c70619cc9d,g5a732f18d5+53520f316c,g5ea96fc03c+341ea1ce94,g64a986408d+f7cd9c7162,g858d7b2824+f7cd9c7162,g8a8a8dda67+585e252eca,g99cad8db69+469ab8c039,g9ddcbc5298+9a081db1e4,ga1e77700b3+15fc3df1f7,gb0e22166c9+60f28cb32d,gba4ed39666+c2a2e4ac27,gbb8dafda3b+c92fc63c7e,gbd866b1f37+f7cd9c7162,gc120e1dc64+02c66aa596,gc28159a63d+0e5473021a,gc3e9b769f7+b0068a2d9f,gcf0d15dbbd+e42ea45bea,gdaeeff99f8+f9a426f77a,ge6526c86ff+84383d05b3,ge79ae78c31+0e5473021a,gee10cc3b42+585e252eca,gff1a9f87cc+f7cd9c7162,w.2024.17
LSST Data Management Base Package
Loading...
Searching...
No Matches
Stack.cc
Go to the documentation of this file.
1// -*- lsst-c++ -*-
2
3/*
4 * LSST Data Management System
5 * Copyright 2008, 2009, 2010 LSST Corporation.
6 *
7 * This product includes software developed by the
8 * LSST Project (http://www.lsst.org/).
9 *
10 * This program is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the LSST License Statement and
21 * the GNU General Public License along with this program. If not,
22 * see <http://www.lsstcorp.org/LegalNotices/>.
23 */
24
25/*
26 * Provide functions to stack images
27 *
28 */
29#include <vector>
30#include <cassert>
31#include <memory>
32
33#include "lsst/pex/exceptions.h"
34#include "lsst/afw/math/Stack.h"
36#include "lsst/log/Log.h"
37
39
40namespace {
41 LOG_LOGGER _log = LOG_GET("lsst.afw.math.Stack");
42}
43
44namespace lsst {
45namespace afw {
46namespace math {
47
48namespace {
49using WeightVector = std::vector<WeightPixel>; // vector of weights (yes, really)
53int bitcount(unsigned int x) {
54 int b;
55 for (b = 0; x != 0; x >>= 1) {
56 if (x & 01) {
57 b++;
58 }
59 }
60 return b;
61}
62
66void checkOnlyOneFlag(unsigned int flags) {
67 if (bitcount(flags & ~ERRORS) != 1) {
69 "Requested more than one type of statistic to make the image stack.");
70 }
71}
72
76template <typename ObjectVectorT, typename WeightVectorT>
77void checkObjectsAndWeights(ObjectVectorT const &objects, WeightVectorT const &wvector) {
78 if (objects.size() == 0) {
79 throw LSST_EXCEPT(pexExcept::LengthError, "Please specify at least one object to stack");
80 }
81
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()));
87 }
88}
89
90template <typename ImageT>
91void checkImageSizes(ImageT const &out, std::vector<std::shared_ptr<ImageT>> const &images) {
92 lsst::geom::Extent2I const &dim = out.getDimensions();
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())
99 .str());
100 }
101 }
102}
103
104/* ************************************************************************** *
105 *
106 * stack MaskedImages
107 *
108 * ************************************************************************** */
109
111
119template <typename PixelT, bool isWeighted, bool useVariance>
120void computeMaskedImageStack(image::MaskedImage<PixelT> &imgStack,
122 Property flags, StatisticsControl const &sctrl, image::MaskPixel const clipped,
124 WeightVector const &wvector = WeightVector()) {
125 // get a list of row_begin iterators
126 using x_iterator = typename image::MaskedImage<PixelT>::x_iterator;
128 rows.reserve(images.size());
129
130 MaskedVector<PixelT> pixelSet(images.size()); // a pixel from x,y for each image
131 WeightVector weights; // weights; non-const version
132 //
133 StatisticsControl sctrlTmp(sctrl);
134
135 if (useVariance) { // weight using the variance image
136 assert(isWeighted);
137 assert(wvector.empty());
138
139 weights.resize(images.size());
140
141 sctrlTmp.setWeighted(true);
142 } else if (isWeighted) {
143 weights.assign(wvector.begin(), wvector.end());
144
145 sctrlTmp.setWeighted(true);
146 }
147 assert(weights.empty() || weights.size() == images.size());
148
149 // loop over x,y ... the loop over the stack to fill pixelSet
150 // - get the stats on pixelSet and put the value in the output image at x,y
151 for (int y = 0; y != imgStack.getHeight(); ++y) {
152 for (unsigned int i = 0; i < images.size(); ++i) {
153 x_iterator ptr = images[i]->row_begin(y);
154 if (y == 0) {
155 rows.push_back(ptr);
156 } else {
157 rows[i] = ptr;
158 }
159 }
160
161 for (x_iterator ptr = imgStack.row_begin(y), end = imgStack.row_end(y); ptr != end; ++ptr) {
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) {
165 *psPtr = *rows[i];
166 if (useVariance) { // we're weighting using the variance
167 *wtPtr = 1.0 / rows[i].variance();
168 }
169 }
170
171 Property const eflags = static_cast<Property>(flags | NPOINT | ERRORS | NCLIPPED | NMASKED);
172 Statistics stat = isWeighted ? makeStatistics(pixelSet, weights, eflags, sctrlTmp)
173 : makeStatistics(pixelSet, eflags, sctrlTmp);
174
175 PixelT variance = ::pow(stat.getError(flags), 2);
176 image::MaskPixel msk(stat.getOrMask());
177 int const npoint = stat.getValue(NPOINT);
178 if (npoint == 0) {
179 msk = sctrlTmp.getNoGoodPixelsMask();
180 } else if (npoint == 1) {
181 /*
182 * you should be using sctrl.setCalcErrorFromInputVariance(true) if you want to avoid
183 * getting a variance of NaN when you only have one input
184 */
185 }
186 // Check to see if any pixels were rejected due to clipping
187 if (stat.getValue(NCLIPPED) > 0) {
188 msk |= clipped;
189 }
190 // Check to see if any pixels were rejected by masking, and apply
191 // any associated masks to the result.
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) {
196 msk |= pair.second;
197 break;
198 }
199 }
200 }
201 }
202
203 *ptr = typename image::MaskedImage<PixelT>::Pixel(stat.getValue(flags), msk, variance);
204 }
205 }
206}
207template <typename PixelT, bool isWeighted, bool useVariance>
208void computeMaskedImageStack(image::MaskedImage<PixelT> &imgStack,
210 Property flags, StatisticsControl const &sctrl, image::MaskPixel const clipped,
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,
215 wvector);
216}
218
219} // end anonymous namespace
220
221template <typename PixelT>
224 StatisticsControl const &sctrl, WeightVector const &wvector, image::MaskPixel clipped,
225 image::MaskPixel excuse) {
226 if (images.size() == 0) {
227 throw LSST_EXCEPT(pexExcept::LengthError, "Please specify at least one image to stack");
228 }
230 new image::MaskedImage<PixelT>(images[0]->getDimensions()));
231 statisticsStack(*out, images, flags, sctrl, wvector, clipped, excuse);
232 return out;
233}
234
235template <typename PixelT>
238 StatisticsControl const &sctrl, WeightVector const &wvector, image::MaskPixel clipped,
240 if (images.size() == 0) {
241 throw LSST_EXCEPT(pexExcept::LengthError, "Please specify at least one image to stack");
242 }
244 new image::MaskedImage<PixelT>(images[0]->getDimensions()));
245 statisticsStack(*out, images, flags, sctrl, wvector, clipped, maskMap);
246 return out;
247}
248
249template <typename PixelT>
252 StatisticsControl const &sctrl, WeightVector const &wvector, image::MaskPixel clipped,
253 image::MaskPixel excuse) {
254 checkObjectsAndWeights(images, wvector);
255 checkOnlyOneFlag(flags);
256 checkImageSizes(out, images);
257
258 if (sctrl.getWeighted()) {
259 if (wvector.empty()) {
260 return computeMaskedImageStack<PixelT, true, true>(out, images, flags, sctrl, clipped,
261 excuse); // use variance
262 } else {
263 return computeMaskedImageStack<PixelT, true, false>(out, images, flags, sctrl, clipped, excuse,
264 wvector); // use wvector
265 }
266 } else {
267 if (!wvector.empty()) {
268 LOGL_WARN(_log,
269 "Weights passed on to statisticsStack are ignored as sctrl.getWeighted() is False."
270 "Set sctrl.setWeighted(True) for them to be used.");
271 }
272 return computeMaskedImageStack<PixelT, false, false>(out, images, flags, sctrl, clipped, excuse);
273 }
274}
275
276template <typename PixelT>
279 StatisticsControl const &sctrl, WeightVector const &wvector, image::MaskPixel clipped,
281 checkObjectsAndWeights(images, wvector);
282 checkOnlyOneFlag(flags);
283 checkImageSizes(out, images);
284
285 if (sctrl.getWeighted()) {
286 if (wvector.empty()) {
287 return computeMaskedImageStack<PixelT, true, true>(out, images, flags, sctrl, clipped,
288 maskMap); // use variance
289 } else {
290 return computeMaskedImageStack<PixelT, true, false>(out, images, flags, sctrl, clipped, maskMap,
291 wvector); // use wvector
292 }
293 } else {
294 return computeMaskedImageStack<PixelT, false, false>(out, images, flags, sctrl, clipped, maskMap);
295 }
296}
297
298namespace {
299/* ************************************************************************** *
300 *
301 * stack Images
302 *
303 * All the work is done in the function comuteImageStack.
304 * A boolean template variable has been used to allow the compiler to generate the different instantiations
305 * to handle cases when we are, or are not, weighting
306 *
307 * ************************************************************************** */
314template <typename PixelT, bool isWeighted>
315void computeImageStack(image::Image<PixelT> &imgStack,
316 std::vector<std::shared_ptr<image::Image<PixelT>>> &images, Property flags,
317 StatisticsControl const &sctrl, WeightVector const &weights = WeightVector()) {
318 MaskedVector<PixelT> pixelSet(images.size()); // a pixel from x,y for each image
319 StatisticsControl sctrlTmp(sctrl);
320
321 // set the mask to be an infinite iterator
322 MaskImposter<image::MaskPixel> msk;
323
324 if (!weights.empty()) {
325 sctrlTmp.setWeighted(true);
326 }
327
328 // get the desired statistic
329 for (int y = 0; y != imgStack.getHeight(); ++y) {
330 for (int x = 0; x != imgStack.getWidth(); ++x) {
331 for (unsigned int i = 0; i != images.size(); ++i) {
332 (*pixelSet.getImage())(i, 0) = (*images[i])(x, y);
333 }
334
335 if (isWeighted) {
336 imgStack(x, y) = makeStatistics(pixelSet, weights, flags, sctrlTmp).getValue();
337 } else {
338 imgStack(x, y) = makeStatistics(pixelSet, weights, flags, sctrlTmp).getValue();
339 }
340 }
341 }
342}
343
344} // end anonymous namespace
345
346template <typename PixelT>
349 StatisticsControl const &sctrl, WeightVector const &wvector) {
350 if (images.size() == 0) {
351 throw LSST_EXCEPT(pexExcept::LengthError, "Please specify at least one image to stack");
352 }
353 std::shared_ptr<image::Image<PixelT>> out(new image::Image<PixelT>(images[0]->getDimensions()));
354 statisticsStack(*out, images, flags, sctrl, wvector);
355 return out;
356}
357
358template <typename PixelT>
360 Property flags, StatisticsControl const &sctrl, WeightVector const &wvector) {
361 checkObjectsAndWeights(images, wvector);
362 checkOnlyOneFlag(flags);
363 checkImageSizes(out, images);
364
365 if (wvector.empty()) {
366 return computeImageStack<PixelT, false>(out, images, flags, sctrl);
367 } else {
368 return computeImageStack<PixelT, true>(out, images, flags, sctrl, wvector);
369 }
370}
371
372/* ************************************************************************** *
373 *
374 * stack VECTORS
375 *
376 * ************************************************************************** */
377
378namespace {
379
386template <typename PixelT, bool isWeighted>
387std::vector<PixelT> computeVectorStack(
388 std::vector<std::vector<PixelT>> &vectors, Property flags,
389 StatisticsControl const &sctrl, WeightVector const &wvector = WeightVector()) {
390 // create the image to be returned
391 using Vect = std::vector<PixelT>;
392 Vect vecStack(vectors[0].size(), 0.0);
393
394 MaskedVector<PixelT> pixelSet(vectors.size()); // values from a given pixel of each image
395
396 StatisticsControl sctrlTmp(sctrl);
397 // set the mask to be an infinite iterator
398 MaskImposter<image::MaskPixel> msk;
399
400 if (!wvector.empty()) {
401 sctrlTmp.setWeighted(true);
402 }
403
404 // collect elements from the stack into the MaskedVector to do stats
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];
409 }
410
411 if (isWeighted) {
412 (vecStack)[x] = makeStatistics(pixelSet, wvector, flags, sctrlTmp).getValue(flags);
413 } else {
414 (vecStack)[x] = makeStatistics(pixelSet, flags, sctrlTmp).getValue(flags);
415 }
416 }
417
418 return vecStack;
419}
420
421} // end anonymous namespace
422
423template <typename PixelT>
426 StatisticsControl const &sctrl, WeightVector const &wvector) {
427 checkObjectsAndWeights(vectors, wvector);
428 checkOnlyOneFlag(flags);
429
430 if (wvector.empty()) {
431 return computeVectorStack<PixelT, false>(vectors, flags, sctrl);
432 } else {
433 return computeVectorStack<PixelT, true>(vectors, flags, sctrl, wvector);
434 }
435}
436
437/* ************************************************************************ *
438 *
439 * XY row column stacking
440 *
441 * ************************************************************************ */
442
443template <typename PixelT>
445 char dimension, StatisticsControl const &sctrl) {
446 int x0 = image.getX0();
447 int y0 = image.getY0();
448 using MImage = image::MaskedImage<PixelT>;
450
451 // do each row or column, one at a time
452 // - create a subimage with a bounding box, and get the stats and assign the value to the output image
453 if (dimension == 'x') {
454 imgOut = std::shared_ptr<MImage>(new MImage(lsst::geom::Extent2I(1, image.getHeight())));
455 int y = y0;
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) {
461 Statistics stat = makeStatistics(subImage, flags | ERRORS, sctrl);
462 *oPtr = typename image::MaskedImage<PixelT>::Pixel(stat.getValue(), 0x0,
463 stat.getError() * stat.getError());
464 }
465
466 } else if (dimension == 'y') {
467 imgOut = std::shared_ptr<MImage>(new MImage(lsst::geom::Extent2I(image.getWidth(), 1)));
468 int x = x0;
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) {
474 Statistics stat = makeStatistics(subImage, flags | ERRORS, sctrl);
475 *oPtr = typename image::MaskedImage<PixelT>::Pixel(stat.getValue(), 0x0,
476 stat.getError() * stat.getError());
477 }
478 } else {
480 "Can only run statisticsStack in x or y for single image.");
481 }
482
483 return imgOut;
484}
485
486template <typename PixelT>
488 Property flags, char dimension,
489 StatisticsControl const &sctrl) {
490 int const x0 = image.getX0();
491 int const y0 = image.getY0();
492 using MImage = image::MaskedImage<PixelT>;
494
495 // do each row or column, one at a time
496 // - create a subimage with a bounding box, and get the stats and assign the value to the output image
497 if (dimension == 'x') {
498 imgOut = std::shared_ptr<MImage>(new MImage(lsst::geom::Extent2I(1, image.getHeight())));
499 int y = 0;
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) {
505 Statistics stat = makeStatistics(subImage, flags | ERRORS, sctrl);
506 *oPtr = typename image::MaskedImage<PixelT>::Pixel(stat.getValue(), 0x0,
507 stat.getError() * stat.getError());
508 }
509
510 } else if (dimension == 'y') {
511 imgOut = std::shared_ptr<MImage>(new MImage(lsst::geom::Extent2I(image.getWidth(), 1)));
512 int x = 0;
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) {
518 Statistics stat = makeStatistics(subImage, flags | ERRORS, sctrl);
519 *oPtr = typename image::MaskedImage<PixelT>::Pixel(stat.getValue(), 0x0,
520 stat.getError() * stat.getError());
521 }
522 } else {
524 "Can only run statisticsStack in x or y for single image.");
525 }
526
527 return imgOut;
528}
529
530/*
531 * Explicit Instantiations
532 *
533 */
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, \
545 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);
567
568INSTANTIATE_STACKS(double)
569INSTANTIATE_STACKS(float)
571} // namespace math
572} // namespace afw
573} // namespace lsst
AmpInfoBoxKey bbox
Definition Amplifier.cc:117
int end
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition Exception.h:48
afw::table::Key< afw::table::Array< VariancePixelT > > variance
LSST DM logging module built on log4cxx.
#define LOGL_WARN(logger, message...)
Log a warn-level message using a varargs/printf style interface.
Definition Log.h:547
#define LOG_GET(logger)
Returns a Log object associated with logger.
Definition Log.h:75
#define LOG_LOGGER
Definition Log.h:714
uint64_t * ptr
Definition RangeSet.cc:95
int y
Definition SpanSet.cc:48
table::Key< int > b
T begin(T... args)
int getWidth() const
Return the number of columns in the image.
Definition ImageBase.h:294
int getHeight() const
Return the number of rows in the image.
Definition ImageBase.h:296
A class to represent a 2-dimensional array of pixels.
Definition Image.h:51
A class to manipulate images, masks, and variance as a single object.
Definition MaskedImage.h:74
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.
MaskedImageIterator< typename Image::iterator, typename Mask::iterator, typename Variance::iterator > iterator
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.
Definition Statistics.h:83
bool getWeighted() const noexcept
Definition Statistics.h:129
A class to evaluate image statistics.
Definition Statistics.h:222
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.
Definition Box.h:55
Reports invalid arguments.
Definition Runtime.h:66
Reports attempts to exceed implementation-defined length limits for some classes.
Definition Runtime.h:76
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)
Definition Statistics.h:361
Property
control what is calculated
Definition Statistics.h:53
@ ERRORS
Include errors of requested quantities.
Definition Statistics.h:55
@ NCLIPPED
number of clipped points
Definition Statistics.h:71
@ NMASKED
number of masked points
Definition Statistics.h:72
@ NPOINT
number of sample points
Definition Statistics.h:56
T push_back(T... args)
T reserve(T... args)