51double const IQ_TO_STDEV = 0.741301109252802;
57 bool operator()(T)
const {
60 template <
typename Ta,
typename Tb>
61 bool operator()(Ta, Tb)
const {
64 template <
typename Ta,
typename Tb,
typename Tc>
65 bool operator()(Ta, Tb, Tc)
const {
74 bool operator()(T)
const {
77 template <
typename Ta,
typename Tb>
78 bool operator()(Ta, Tb)
const {
81 template <
typename Ta,
typename Tb,
typename Tc>
82 bool operator()(Ta, Tb, Tc)
const {
91 bool operator()(T val)
const {
97class CheckValueLtMin {
99 template <
typename Tval,
typename Tmin>
100 bool operator()(Tval val, Tmin
min)
const {
101 return (
static_cast<Tmin
>(val) <
min);
106class CheckValueGtMax {
108 template <
typename Tval,
typename Tmax>
109 bool operator()(Tval val, Tmax
max)
const {
110 return (
static_cast<Tmax
>(val) >
max);
115class CheckClipRange {
117 template <
typename Tval,
typename Tcen,
typename Tmax>
118 bool operator()(Tval val, Tcen center, Tmax cliplimit)
const {
119 Tmax tmp =
fabs(val - center);
120 return (tmp <= cliplimit);
125using ChkFin = CheckFinite;
126using ChkMin = CheckValueLtMin;
127using ChkMax = CheckValueGtMax;
128using ChkClip = CheckClipRange;
129using AlwaysT = AlwaysTrue;
130using AlwaysF = AlwaysFalse;
135inline double varianceError(
double const variance,
int const n) {
136 return 2 * (n - 1) * variance * variance /
static_cast<double>(n * n);
140using StandardReturn = std::tuple<int, double, Statistics::Value, Statistics::Value, double, double, image::MaskPixel>;
155template <
typename IsFinite,
typename HasValueLtMin,
typename HasValueGtMax,
typename InClipRange,
156 bool useWeights,
typename ImageT,
typename MaskT,
typename VarianceT,
typename WeightT>
157StandardReturn processPixels(ImageT
const &img, MaskT
const &msk, VarianceT
const &var,
158 WeightT
const &weights,
int const,
int const nCrude,
int const stride,
159 double const meanCrude,
double const cliplimit,
160 bool const weightsAreMultiplicative,
int const andMask,
161 bool const calcErrorFromInputVariance,
162 bool const calcErrorMosaicMode,
163 std::vector<double>
const &maskPropagationThresholds) {
173 double min = (nCrude) ? meanCrude : MAX_DOUBLE;
174 double max = (nCrude) ? meanCrude : -MAX_DOUBLE;
178 std::vector<double> rejectedWeightsByBit(maskPropagationThresholds.
size(), 0.0);
180 for (
int iY = 0; iY < img.getHeight(); iY += stride) {
181 typename MaskT::x_iterator mptr = msk.row_begin(iY);
182 typename VarianceT::x_iterator vptr = var.row_begin(iY);
183 typename WeightT::x_iterator wptr = weights.row_begin(iY);
185 for (
typename ImageT::x_iterator ptr = img.row_begin(iY),
end = ptr + img.getWidth(); ptr !=
end;
186 ++ptr, ++mptr, ++vptr, ++wptr) {
187 if (IsFinite()(*ptr) && !(*mptr & andMask) &&
188 InClipRange()(*ptr, meanCrude, cliplimit)) {
190 double const delta = (*ptr - meanCrude);
193 double weight = *wptr;
194 if (weightsAreMultiplicative) {
204 sumw2 += weight * weight;
205 sumx += weight * delta;
206 sumx2 += weight * delta * delta;
208 if (calcErrorFromInputVariance) {
209 double const var = *vptr;
210 sumvw2 += var * weight * weight;
212 if (calcErrorMosaicMode) {
213 double const var = *vptr;
214 sumvw += var * weight;
218 sumx2 += delta * delta;
220 if (calcErrorFromInputVariance) {
221 double const var = *vptr;
224 if (calcErrorMosaicMode) {
225 double const var = *vptr;
230 allPixelOrMask |= *mptr;
232 if (HasValueLtMin()(*ptr,
min)) {
235 if (HasValueGtMax()(*ptr,
max)) {
240 for (
int bit = 0, nBits = maskPropagationThresholds.
size(); bit < nBits; ++bit) {
246 if (!weightsAreMultiplicative) {
250 weight = 1.0 / weight;
253 rejectedWeightsByBit[bit] += weight;
265 double mean, variance;
270 for (
int bit = 0, nBits = maskPropagationThresholds.
size(); bit < nBits; ++bit) {
271 double hypotheticalTotalWeight = sumw + rejectedWeightsByBit[bit];
272 rejectedWeightsByBit[bit] /= hypotheticalTotalWeight;
273 if (rejectedWeightsByBit[bit] > maskPropagationThresholds[bit]) {
274 allPixelOrMask |= (1 << bit);
282 variance = sumx2 / sumw -
::pow(mean, 2);
283 variance *= sumw * sumw / (sumw * sumw - sumw2);
286 if (calcErrorFromInputVariance) {
287 meanVar = sumvw2 / (sumw * sumw);
288 }
else if (calcErrorMosaicMode){
289 meanVar = sumvw / sumw;
291 meanVar = variance * sumw2 / (sumw * sumw);
294 double varVar = varianceError(variance, n);
296 sumx += sumw * meanCrude;
300 max, allPixelOrMask);
303template <
typename IsFinite,
typename HasValueLtMin,
typename HasValueGtMax,
typename InClipRange,
304 bool useWeights,
typename ImageT,
typename MaskT,
typename VarianceT,
typename WeightT>
305StandardReturn processPixels(ImageT
const &img, MaskT
const &msk, VarianceT
const &var,
306 WeightT
const &weights,
int const flags,
int const nCrude,
int const stride,
307 double const meanCrude,
double const cliplimit,
308 bool const weightsAreMultiplicative,
int const andMask,
309 bool const calcErrorFromInputVariance,
bool const calcErrorMosaicMode,
310 bool doGetWeighted, std::vector<double>
const &maskPropagationThresholds) {
312 return processPixels<IsFinite, HasValueLtMin, HasValueGtMax, InClipRange, true>(
313 img, msk, var, weights, flags, nCrude, 1, meanCrude, cliplimit, weightsAreMultiplicative,
314 andMask, calcErrorFromInputVariance, calcErrorMosaicMode, maskPropagationThresholds);
316 return processPixels<IsFinite, HasValueLtMin, HasValueGtMax, InClipRange, false>(
317 img, msk, var, weights, flags, nCrude, 1, meanCrude, cliplimit, weightsAreMultiplicative,
318 andMask, calcErrorFromInputVariance, calcErrorMosaicMode, maskPropagationThresholds);
322template <
typename IsFinite,
typename HasValueLtMin,
typename HasValueGtMax,
typename InClipRange,
323 bool useWeights,
typename ImageT,
typename MaskT,
typename VarianceT,
typename WeightT>
324StandardReturn processPixels(ImageT
const &img, MaskT
const &msk, VarianceT
const &var,
325 WeightT
const &weights,
int const flags,
int const nCrude,
int const stride,
326 double const meanCrude,
double const cliplimit,
327 bool const weightsAreMultiplicative,
int const andMask,
328 bool const calcErrorFromInputVariance,
329 bool const calcErrorMosaicMode,
bool doCheckFinite,
bool doGetWeighted,
330 std::vector<double>
const &maskPropagationThresholds) {
332 return processPixels<CheckFinite, HasValueLtMin, HasValueGtMax, InClipRange, useWeights>(
333 img, msk, var, weights, flags, nCrude, 1, meanCrude, cliplimit, weightsAreMultiplicative,
334 andMask, calcErrorFromInputVariance, calcErrorMosaicMode, doGetWeighted, maskPropagationThresholds);
336 return processPixels<AlwaysTrue, HasValueLtMin, HasValueGtMax, InClipRange, useWeights>(
337 img, msk, var, weights, flags, nCrude, 1, meanCrude, cliplimit, weightsAreMultiplicative,
338 andMask, calcErrorFromInputVariance, calcErrorMosaicMode, doGetWeighted, maskPropagationThresholds);
362template <
typename ImageT,
typename MaskT,
typename VarianceT,
typename WeightT>
363StandardReturn getStandard(ImageT
const &img, MaskT
const &msk, VarianceT
const &var, WeightT
const &weights,
364 int const flags,
bool const weightsAreMultiplicative,
int const andMask,
365 bool const calcErrorFromInputVariance,
bool const calcErrorMosaicMode,
366 bool doCheckFinite,
bool doGetWeighted,
367 std::vector<double>
const &maskPropagationThresholds) {
371 double meanCrude = 0.0;
374 int const nPix = img.getWidth() * img.getHeight();
382 double cliplimit = -1;
383 StandardReturn values = processPixels<ChkFin, AlwaysF, AlwaysF, AlwaysT, true>(
384 img, msk, var, weights, flags, nCrude, strideCrude, meanCrude, cliplimit,
385 weightsAreMultiplicative, andMask, calcErrorFromInputVariance, calcErrorMosaicMode,
386 doCheckFinite, doGetWeighted, maskPropagationThresholds);
387 nCrude = std::get<0>(values);
388 double sumCrude = std::get<1>(values);
392 meanCrude = sumCrude / nCrude;
399 if (flags & (
MIN |
MAX)) {
400 return processPixels<ChkFin, ChkMin, ChkMax, AlwaysT, true>(
401 img, msk, var, weights, flags, nCrude, 1, meanCrude, cliplimit, weightsAreMultiplicative,
402 andMask, calcErrorFromInputVariance, calcErrorMosaicMode,
true, doGetWeighted,
403 maskPropagationThresholds);
405 return processPixels<ChkFin, AlwaysF, AlwaysF, AlwaysT, true>(
406 img, msk, var, weights, flags, nCrude, 1, meanCrude, cliplimit, weightsAreMultiplicative,
407 andMask, calcErrorFromInputVariance, calcErrorMosaicMode, doCheckFinite, doGetWeighted,
408 maskPropagationThresholds);
433template <
typename ImageT,
typename MaskT,
typename VarianceT,
typename WeightT>
434StandardReturn getStandard(ImageT
const &img, MaskT
const &msk, VarianceT
const &var, WeightT
const &weights,
435 int const flags, std::pair<double, double>
const clipinfo,
436 bool const weightsAreMultiplicative,
int const andMask,
437 bool const calcErrorFromInputVariance,
bool const calcErrorMosaicMode,
438 bool doCheckFinite,
bool doGetWeighted,
439 std::vector<double>
const &maskPropagationThresholds) {
440 double const center = clipinfo.first;
441 double const cliplimit = clipinfo.second;
450 int const stride = 1;
453 if (flags & (
MIN |
MAX)) {
454 return processPixels<ChkFin, ChkMin, ChkMax, ChkClip, true>(
455 img, msk, var, weights, flags, nCrude, stride, center, cliplimit, weightsAreMultiplicative,
456 andMask, calcErrorFromInputVariance, calcErrorMosaicMode,
true, doGetWeighted,
457 maskPropagationThresholds);
459 return processPixels<ChkFin, AlwaysF, AlwaysF, ChkClip, true>(
460 img, msk, var, weights, flags, nCrude, stride, center, cliplimit, weightsAreMultiplicative,
461 andMask, calcErrorFromInputVariance, calcErrorMosaicMode, doCheckFinite, doGetWeighted,
462 maskPropagationThresholds);
474template <
typename Pixel>
475typename enable_if<!is_integral<Pixel>::value,
double>::type
476percentile(std::vector<Pixel> &img,
double const fraction) {
477 assert(fraction >= 0.0 && fraction <= 1.0);
479 int const n = img.
size();
482 double const idx = fraction * (n - 1);
490 int const q1 =
static_cast<int>(idx);
491 int const q2 = q1 + 1;
493 auto mid1 = img.
begin() + q1;
494 auto mid2 = img.
begin() + q2;
495 if (fraction > 0.5) {
503 double val1 =
static_cast<double>(*mid1);
504 double val2 =
static_cast<double>(*mid2);
505 double w1 = (
static_cast<double>(q2) - idx);
506 double w2 = (idx -
static_cast<double>(q1));
507 return w1 * val1 + w2 * val2;
530 computeQuantile(
typename std::vector<T>::const_iterator
begin,
531 typename std::vector<T>::const_iterator
end,
540 for (
auto ptr =
begin; ptr !=
end; ++ptr) {
541 auto const val = *ptr;
544 }
else if (val == naive) {
549 return naive - 0.5 + (target -
left)/middle;
560 template <
typename Pixel>
561 typename enable_if<is_integral<Pixel>::value,
double>::type
562 percentile(std::vector<Pixel> &img,
double const fraction) {
563 assert(fraction >= 0.0 && fraction <= 1.0);
565 auto const n = img.
size();
579 double const idx = fraction*(n - 1);
581 auto midP = img.
begin() +
static_cast<int>(idx);
583 auto const naiveP = *midP;
585 return computeQuantile(img.
begin(), img.
end(), naiveP, fraction*n);
590using MedianQuartileReturn = std::tuple<double, double, double>;
599 template <
typename Pixel>
600 typename enable_if<!is_integral<Pixel>::value, MedianQuartileReturn>::type
601 medianAndQuartiles(std::vector<Pixel> &img) {
602 int const n = img.
size();
605 double const idx50 = 0.50 * (n - 1);
606 double const idx25 = 0.25 * (n - 1);
607 double const idx75 = 0.75 * (n - 1);
614 int const q50a =
static_cast<int>(idx50);
615 int const q50b = q50a + 1;
616 int const q25a =
static_cast<int>(idx25);
617 int const q25b = q25a + 1;
618 int const q75a =
static_cast<int>(idx75);
619 int const q75b = q75a + 1;
621 auto mid50a = img.
begin() + q50a;
622 auto mid50b = img.
begin() + q50b;
623 auto mid25a = img.
begin() + q25a;
624 auto mid25b = img.
begin() + q25b;
625 auto mid75a = img.
begin() + q75a;
626 auto mid75b = img.
begin() + q75b;
639 double val50a =
static_cast<double>(*mid50a);
640 double val50b =
static_cast<double>(*mid50b);
641 double w50a = (
static_cast<double>(q50b) - idx50);
642 double w50b = (idx50 -
static_cast<double>(q50a));
643 double median = w50a * val50a + w50b * val50b;
645 double val25a =
static_cast<double>(*mid25a);
646 double val25b =
static_cast<double>(*mid25b);
647 double w25a = (
static_cast<double>(q25b) - idx25);
648 double w25b = (idx25 -
static_cast<double>(q25a));
649 double q1 = w25a * val25a + w25b * val25b;
651 double val75a =
static_cast<double>(*mid75a);
652 double val75b =
static_cast<double>(*mid75b);
653 double w75a = (
static_cast<double>(q75b) - idx75);
654 double w75b = (idx75 -
static_cast<double>(q75a));
655 double q3 = w75a * val75a + w75b * val75b;
657 return MedianQuartileReturn(median, q1, q3);
659 return MedianQuartileReturn(img[0], img[0], img[0]);
661 return MedianQuartileReturn(NaN, NaN, NaN);
672 template <
typename Pixel>
673 typename enable_if<is_integral<Pixel>::value, MedianQuartileReturn>::type
674 medianAndQuartiles(std::vector<Pixel> &img) {
675 auto const n = img.
size();
678 return MedianQuartileReturn(NaN, NaN, NaN);
680 return MedianQuartileReturn(img[0], img[0], img[0]);
692 auto mid25 = img.
begin() +
static_cast<int>(0.25*(n - 1));
693 auto mid50 = img.
begin() +
static_cast<int>(0.50*(n - 1));
694 auto mid75 = img.
begin() +
static_cast<int>(0.75*(n - 1));
701 double const q1 = computeQuantile(img.
begin(), mid50, *mid25,
703 double const median = computeQuantile(mid25, mid75, *mid50,
704 0.50*n - (mid25 - img.
begin()));
705 double const q3 = computeQuantile(mid50, img.
end(), *mid75,
706 0.75*n - (mid50 - img.
begin()));
708 return MedianQuartileReturn(median, q1, q3);
720template <
typename IsFinite,
typename ImageT,
typename MaskT,
typename VarianceT>
721std::shared_ptr<std::vector<typename ImageT::Pixel> > makeVectorCopy(ImageT
const &img, MaskT
const &msk,
722 VarianceT
const &,
int const andMask) {
725 std::shared_ptr<std::vector<typename ImageT::Pixel> > imgcp(
new std::vector<typename ImageT::Pixel>(0));
727 for (
int i_y = 0; i_y < img.getHeight(); ++i_y) {
728 typename MaskT::x_iterator mptr = msk.row_begin(i_y);
729 for (
typename ImageT::x_iterator ptr = img.row_begin(i_y),
end = img.row_end(i_y); ptr !=
end;
731 if (IsFinite()(*ptr) && !(*mptr & andMask)) {
732 imgcp->push_back(*ptr);
743 int oldSize = _maskPropagationThresholds.size();
744 if (oldSize <= bit) {
747 return _maskPropagationThresholds[bit];
751 int oldSize = _maskPropagationThresholds.size();
752 if (oldSize <= bit) {
753 int newSize = bit + 1;
754 _maskPropagationThresholds.resize(newSize);
755 for (
int i = oldSize; i < bit; ++i) {
756 _maskPropagationThresholds[i] = 1.0;
759 _maskPropagationThresholds[bit] = threshold;
764 if (statisticsProperty.
size() == 0) {
765 statisticsProperty[
"NOTHING"] =
NOTHING;
766 statisticsProperty[
"ERRORS"] =
ERRORS;
767 statisticsProperty[
"NPOINT"] =
NPOINT;
768 statisticsProperty[
"MEAN"] =
MEAN;
769 statisticsProperty[
"STDEV"] =
STDEV;
770 statisticsProperty[
"VARIANCE"] =
VARIANCE;
771 statisticsProperty[
"MEDIAN"] =
MEDIAN;
772 statisticsProperty[
"IQRANGE"] =
IQRANGE;
773 statisticsProperty[
"MEANCLIP"] =
MEANCLIP;
774 statisticsProperty[
"STDEVCLIP"] =
STDEVCLIP;
776 statisticsProperty[
"MIN"] =
MIN;
777 statisticsProperty[
"MAX"] =
MAX;
778 statisticsProperty[
"SUM"] =
SUM;
779 statisticsProperty[
"MEANSQUARE"] =
MEANSQUARE;
780 statisticsProperty[
"ORMASK"] =
ORMASK;
781 statisticsProperty[
"NCLIPPED"] =
NCLIPPED;
782 statisticsProperty[
"NMASKED"] =
NMASKED;
784 return statisticsProperty[property];
787template <
typename ImageT,
typename MaskT,
typename VarianceT>
797 _varianceclip(NaN, NaN),
803 _weightsAreMultiplicative(false) {
804 doStatistics(img, msk, var, var, _flags, _sctrl);
809bool isEmpty(T
const &t) {
819template <
typename ImageT1,
typename ImageT2>
820void checkDimensions(ImageT1
const &image1, ImageT2
const &image2) {
821 if (image1.getDimensions() != image2.getDimensions()) {
822 throw LSST_EXCEPT(pexExceptions::InvalidParameterError,
823 (boost::format(
"Image sizes don't match: %s vs %s") % image1.getDimensions() %
824 image2.getDimensions())
830template <
typename ImageT,
typename PixelT>
832template <
typename ImageT,
typename PixelT>
836template <
typename ImageT,
typename MaskT,
typename VarianceT,
typename WeightT>
846 _varianceclip(NaN, NaN),
852 _weightsAreMultiplicative(true) {
853 if (!isEmpty(weights)) {
854 if (_sctrl.getWeightedIsSet() && !_sctrl.getWeighted()) {
856 "You must use the weights if you provide them");
859 _sctrl.setWeighted(
true);
861 doStatistics(img, msk, var, weights, _flags, _sctrl);
864template <
typename ImageT,
typename MaskT,
typename VarianceT,
typename WeightT>
865void Statistics::doStatistics(ImageT
const &img, MaskT
const &msk, VarianceT
const &var,
869 throw LSST_EXCEPT(pexExceptions::InvalidParameterError,
870 "Both calcErrorFromInputVariance and calcErrorMosaicMode are True");
873 int const num = img.getWidth() * img.getHeight();
876 throw LSST_EXCEPT(pexExceptions::InvalidParameterError,
"Image contains no pixels");
878 checkDimensions(img, msk);
879 checkDimensions(img, var);
881 checkDimensions(img, weights);
888 StandardReturn standard =
889 getStandard(img, msk, var, weights, flags, _weightsAreMultiplicative, _sctrl.
getAndMask(),
892 _sctrl._maskPropagationThresholds);
894 _n = std::get<0>(standard);
895 _sum = std::get<1>(standard);
896 _mean = std::get<2>(standard);
897 _variance = std::get<3>(standard);
898 _min = std::get<4>(standard);
899 _max = std::get<5>(standard);
900 _allPixelOrMask = std::get<6>(standard);
912 std::shared_ptr<std::vector<typename ImageT::Pixel> > imgcp;
913 if (_sctrl.getNanSafe()) {
914 imgcp = makeVectorCopy<ChkFin>(img, msk, var, _sctrl.getAndMask());
916 imgcp = makeVectorCopy<AlwaysT>(img, msk, var, _sctrl.getAndMask());
921 _median =
Value(percentile(*imgcp, 0.5), NaN);
923 MedianQuartileReturn mq = medianAndQuartiles(*imgcp);
924 _median =
Value(std::get<0>(mq), NaN);
925 _iqrange = std::get<2>(mq) - std::get<1>(mq);
929 for (
int i_i = 0; i_i < _sctrl.getNumIter(); ++i_i) {
930 if (_varianceclip.first < 0) {
934 _varianceclip.first = 0.0;
936 double const center = ((i_i > 0) ? _meanclip : _median).first;
937 double const hwidth = (i_i > 0 && _n > 1)
938 ? _sctrl.getNumSigmaClip() *
std::sqrt(_varianceclip.first)
939 : _sctrl.getNumSigmaClip() * IQ_TO_STDEV * _iqrange;
940 std::pair<double, double>
const clipinfo(center, hwidth);
942 StandardReturn clipped = getStandard(
943 img, msk, var, weights, flags, clipinfo, _weightsAreMultiplicative,
944 _sctrl.getAndMask(), _sctrl.getCalcErrorFromInputVariance(),
945 _sctrl.getCalcErrorMosaicMode(), _sctrl.getNanSafe(),
946 _sctrl.getWeighted(), _sctrl._maskPropagationThresholds);
948 int const nClip = std::get<0>(clipped);
949 _nClipped = _n - nClip;
950 _meanclip = std::get<2>(clipped);
951 double const varClip = std::get<3>(clipped).first;
953 _varianceclip =
Value(varClip, varianceError(varClip, nClip));
964 if (!(prop & _flags)) {
965 throw LSST_EXCEPT(pexExceptions::InvalidParameterError,
966 (boost::format(
"You didn't ask me to calculate %d") % prop).str());
972 ret.first =
static_cast<double>(_n);
979 ret.first =
static_cast<double>(_nClipped);
986 ret.first =
static_cast<double>(_nMasked);
993 ret.first =
static_cast<double>(_sum);
1001 ret.first = _mean.first;
1003 ret.second =
::sqrt(_mean.second);
1007 ret.first = _meanclip.first;
1009 ret.second =
::sqrt(_meanclip.second);
1015 ret.first = _variance.first;
1017 ret.second =
::sqrt(_variance.second);
1021 ret.first =
sqrt(_variance.first);
1023 ret.second = 0.5 *
::sqrt(_variance.second) / ret.first;
1027 ret.first = _varianceclip.first;
1029 ret.second = ret.second;
1033 ret.first =
sqrt(_varianceclip.first);
1035 ret.second = 0.5 *
::sqrt(_varianceclip.second) / ret.first;
1040 ret.first = (_n - 1) /
static_cast<double>(_n) * _variance.first +
::pow(_mean.first, 2);
1042 ret.second =
::sqrt(2 *
::pow(ret.first / _n, 2));
1060 ret.first = _median.first;
1066 ret.first = _iqrange;
1079 "getValue() may only be called without a parameter"
1080 " if you asked for only one statistic");
1104 _variance(NaN, NaN),
1107 _meanclip(NaN, NaN),
1108 _varianceclip(NaN, NaN),
1114 throw LSST_EXCEPT(pexExceptions::InvalidParameterError,
1115 "Statistics<Mask> only supports NPOINT and SUM");
1122 throw LSST_EXCEPT(pexExceptions::InvalidParameterError,
"Image contains no pixels");
1129 for (
int y = 0; y != msk.
getHeight(); ++y) {
1144 return Statistics(msk, msk, msk, flags, sctrl);
1155#define STAT Statistics
1159#define INSTANTIATE_MASKEDIMAGE_STATISTICS(TYPE) \
1160 template STAT::Statistics(image::Image<TYPE> const &img, image::Mask<image::MaskPixel> const &msk, \
1161 image::Image<VPixel> const &var, int const flags, \
1162 StatisticsControl const &sctrl); \
1163 template STAT::Statistics(image::Image<TYPE> const &img, image::Mask<image::MaskPixel> const &msk, \
1164 image::Image<VPixel> const &var, image::Image<VPixel> const &weights, \
1165 int const flags, StatisticsControl const &sctrl); \
1166 template STAT::Statistics(image::Image<TYPE> const &img, image::Mask<image::MaskPixel> const &msk, \
1167 image::Image<VPixel> const &var, ImageImposter<VPixel> const &weights, \
1168 int const flags, StatisticsControl const &sctrl)
1170#define INSTANTIATE_MASKEDIMAGE_STATISTICS_NO_MASK(TYPE) \
1171 template STAT::Statistics(image::Image<TYPE> const &img, MaskImposter<image::MaskPixel> const &msk, \
1172 image::Image<VPixel> const &var, int const flags, \
1173 StatisticsControl const &sctrl); \
1174 template STAT::Statistics(image::Image<TYPE> const &img, MaskImposter<image::MaskPixel> const &msk, \
1175 image::Image<VPixel> const &var, image::Image<VPixel> const &weights, \
1176 int const flags, StatisticsControl const &sctrl)
1178#define INSTANTIATE_MASKEDIMAGE_STATISTICS_NO_VAR(TYPE) \
1179 template STAT::Statistics(image::Image<TYPE> const &img, image::Mask<image::MaskPixel> const &msk, \
1180 MaskImposter<VPixel> const &var, int const flags, \
1181 StatisticsControl const &sctrl); \
1182 template STAT::Statistics(image::Image<TYPE> const &img, image::Mask<image::MaskPixel> const &msk, \
1183 MaskImposter<VPixel> const &var, image::Image<VPixel> const &weights, \
1184 int const flags, StatisticsControl const &sctrl); \
1185 template STAT::Statistics(image::Image<TYPE> const &img, image::Mask<image::MaskPixel> const &msk, \
1186 MaskImposter<VPixel> const &var, ImageImposter<VPixel> const &weights, \
1187 int const flags, StatisticsControl const &sctrl)
1189#define INSTANTIATE_REGULARIMAGE_STATISTICS(TYPE) \
1190 template STAT::Statistics(image::Image<TYPE> const &img, MaskImposter<image::MaskPixel> const &msk, \
1191 MaskImposter<VPixel> const &var, int const flags, \
1192 StatisticsControl const &sctrl)
1194#define INSTANTIATE_VECTOR_STATISTICS(TYPE) \
1195 template STAT::Statistics(ImageImposter<TYPE> const &img, MaskImposter<image::MaskPixel> const &msk, \
1196 MaskImposter<VPixel> const &var, int const flags, \
1197 StatisticsControl const &sctrl); \
1198 template STAT::Statistics(ImageImposter<TYPE> const &img, MaskImposter<image::MaskPixel> const &msk, \
1199 MaskImposter<VPixel> const &var, ImageImposter<VPixel> const &weights, \
1200 int const flags, StatisticsControl const &sctrl)
1202#define INSTANTIATE_IMAGE_STATISTICS(T) \
1203 INSTANTIATE_MASKEDIMAGE_STATISTICS(T); \
1204 INSTANTIATE_MASKEDIMAGE_STATISTICS_NO_VAR(T); \
1205 INSTANTIATE_MASKEDIMAGE_STATISTICS_NO_MASK(T); \
1206 INSTANTIATE_REGULARIMAGE_STATISTICS(T); \
1207 INSTANTIATE_VECTOR_STATISTICS(T)
1209INSTANTIATE_IMAGE_STATISTICS(
double);
1210INSTANTIATE_IMAGE_STATISTICS(
float);
1211INSTANTIATE_IMAGE_STATISTICS(
int);
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
int getWidth() const
Return the number of columns in the image.
int getHeight() const
Return the number of rows in the image.
x_iterator row_begin(int y) const
Return an x_iterator to the start of the y'th row.
x_iterator row_end(int y) const
Return an x_iterator to the end of the y'th row.
A class to represent a 2-dimensional array of pixels.
Represent a 2-dimensional array of bitmask pixels.
A Mask wrapper to provide an infinite_iterator for Mask::row_begin().
Pass parameters to a Statistics object.
double getMaskPropagationThreshold(int bit) const
When pixels with the given bit are rejected, we count what fraction the rejected pixels would have co...
bool getCalcErrorFromInputVariance() const noexcept
int getAndMask() const noexcept
void setMaskPropagationThreshold(int bit, double threshold)
bool getWeighted() const noexcept
bool getCalcErrorMosaicMode() const noexcept
bool getNanSafe() const noexcept
Value getResult(Property const prop=NOTHING) const
Return the value and error in the specified statistic (e.g.
double getError(Property const prop=NOTHING) const
Return the error in the desired property (if specified in the constructor)
Statistics(ImageT const &img, MaskT const &msk, VarianceT const &var, int const flags, StatisticsControl const &sctrl=StatisticsControl())
Constructor for Statistics object.
double getValue(Property const prop=NOTHING) const
Return the value of the desired property (if specified in the constructor)
std::pair< double, double > Value
The type used to report (value, error) for desired statistics.
Reports invalid arguments.
std::int32_t MaskPixel
default type for Masks and MaskedImage Masks
float VariancePixel
default type for MaskedImage variance 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
@ ORMASK
get the or-mask of all pixels used.
@ ERRORS
Include errors of requested quantities.
@ VARIANCECLIP
estimate sample N-sigma clipped variance (N set in StatisticsControl, default=3)
@ MEANSQUARE
find mean value of square of pixel values
@ MIN
estimate sample minimum
@ NCLIPPED
number of clipped points
@ NOTHING
We don't want anything.
@ STDEV
estimate sample standard deviation
@ NMASKED
number of masked points
@ STDEVCLIP
estimate sample N-sigma clipped stdev (N set in StatisticsControl, default=3)
@ VARIANCE
estimate sample variance
@ MEDIAN
estimate sample median
@ MAX
estimate sample maximum
@ SUM
find sum of pixels in the image
@ IQRANGE
estimate sample inter-quartile range
@ MEAN
estimate sample mean
@ MEANCLIP
estimate sample N-sigma clipped mean (N set in StatisticsControl, default=3)
@ NPOINT
number of sample points
Property stringToStatisticsProperty(std::string const property)
Conversion function to switch a string to a Property (see Statistics.h)
decltype(sizeof(void *)) size_t
g2d::python::Image< bool > Mask