28 int const initialStride =
29 std::max(1, static_cast<int>(
std::sqrt(width * height / static_cast<double>(nSamples))));
31 for (
int stride = initialStride; stride >= 1; --stride) {
34 for (
int y = 0;
y < height;
y += stride) {
35 for (
int x = 0;
x < width;
x += stride) {
44 if (5 * vSample.
size() > 4 * nSamples) {
56 double sumz = 0, sumsq = 0;
57 for (
unsigned i = 0; i < vFlat.
size(); ++i) {
59 double const z = vFlat[i];
66 double const goodPix = nGoodPix;
67 double const tmp = sumsq / (goodPix - 1) - sumz * sumz / (goodPix * (goodPix - 1));
75 std::vector<T> const& vSample,
double const nSigmaClip,
int const nGrow,
int const minpix,
78 double const xscale = 2.0 / (vSample.
size() - 1);
88 int nGoodPix = vSample.
size();
89 int nGoodPixOld = nGoodPix + 1;
95 for (
int iteration = 0; iteration < nIter; ++iteration) {
96 if (nGoodPix < minpix || nGoodPix >= nGoodPixOld) {
100 double sum = nGoodPix;
101 double sumx = 0, sumy = 0, sumxx = 0, sumxy = 0;
104 double const x = xnorm[i];
105 double const y = vSample[i];
114 double delta = sum * sumxx - sumx * sumx;
117 intercept = (sumxx * sumy - sumx * sumxy) / delta;
118 slope = (sum * sumxy - sumx * sumy) / delta;
123 for (
unsigned i = 0; i < vSample.
size(); ++i) {
124 vFlat.
push_back(vSample[i] - (xnorm[i] * slope + intercept));
128 double const sigma = computeSigma(vFlat, vBadPix, nGoodPix);
129 double const hcut = sigma * nSigmaClip;
130 double const lcut = -hcut;
133 nGoodPixOld = nGoodPix;
136 for (
unsigned i = 0; i < vSample.
size(); ++i) {
137 double val = vFlat[i];
138 if (val < lcut || hcut < val) {
146 for (
unsigned x = 0;
x < vSample.
size(); ++
x) {
147 int imin = (
static_cast<int>(
x) > nGrow) ?
x - nGrow : -1;
149 for (
int i =
x; i > imin; --i) {
157 vBadPix = vBadPix_new;
161 *nGoodPixOut = nGoodPix;
170 getSample(image, nSamples, vSample);
171 int nPix = vSample.
size();
173 if (vSample.
empty()) {
183 double const zmin = vSample.
front();
184 double const zmax = vSample.
back();
185 int const iCenter = nPix / 2;
186 T median = (nPix & 1) ? vSample[iCenter] : (vSample[iCenter] + vSample[iCenter + 1]) / 2;
189 const int maxRejectionRatio = 2;
190 const int npixelsMin = 5;
192 int minpix =
std::max(npixelsMin, nPix / maxRejectionRatio);
193 int nGrow =
std::max(1, nPix / 100);
195 const double nSigmaClip = 2.5;
196 const int nIterations = 5;
200 #if 0 // unused, but calculated and potentially useful 201 double const zstart = ret.first;
203 double const zslope = ret.second;
206 if (nGoodPix < minpix) {
210 double const slope = zslope / contrast;
212 z1 =
std::max(zmin, median - iCenter * slope);
213 z2 =
std::min(zmax, median + (nPix - iCenter - 1) * slope);
220 #define INSTANTIATE_GETZSCALE(T) \ 221 template std::pair<double, double> getZScale(image::Image<T> const& image, int const nSamples, \ 222 double const contrast)
std::pair< double, double > getZScale(image::Image< T > const &image, int const nSamples=1000, double const contrast=0.25)
Calculate an IRAF/ds9-style zscaling.
int getHeight() const
Return the number of rows in the image.
#define INSTANTIATE_GETZSCALE(T)
A base class for image defects.
afw::table::Key< double > sigma
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
int getWidth() const
Return the number of columns in the image.
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects...
A class to represent a 2-dimensional array of pixels.
Reports errors that are due to events beyond the control of the program.