41 badMaskPlanes=(
"NO_DATA",
"INTRP",
"BAD",
"SAT",
"EDGE"), detectionThreshold=5):
42 """Make detection mask and set the mask plane
44 Creat a binary image from a masked image by setting all data
with signal-to-
45 noise below some threshold to zero,
and all data above the threshold to one.
46 If the binning parameter has been set, this procedure will be preceded by a
47 weighted binning of the data
in order to smooth the result, after which the
48 result
is scaled back to the original dimensions. Set the detection mask
49 plane
with this binary image.
54 Image to be (optionally) binned
and converted
55 forceSlowBin : bool (optional)
56 Force usage of slower binning method to check that the two methods
58 binning : int (optional)
59 Number of pixels by which to bin image
60 detectedPlane : str (optional)
61 Name of mask
with pixels that were detected above threshold
in image
62 badMaskPlanes : set (optional)
63 Names of masks
with pixels that are rejected
64 detectionThreshold : float (optional)
65 Boundary
in signal-to-noise between non-detections
and detections
for
66 making a binary image
from the original input image
68 data = maskedImage.image.array
69 weights = 1 / maskedImage.variance.array
70 mask = maskedImage.getMask()
72 detectionMask = ((mask.array & mask.getPlaneBitMask(detectedPlane)))
73 badPixelMask = mask.getPlaneBitMask(badMaskPlanes)
74 badMask = (mask.array & badPixelMask) > 0
75 fitMask = detectionMask.astype(bool) & ~badMask
77 fitData = np.copy(data)
79 fitWeights = np.copy(weights)
80 fitWeights[~fitMask] = 0
84 ymax, xmax = fitData.shape
85 if (ymax % binning == 0)
and (xmax % binning == 0)
and (
not forceSlowBin):
87 binNumeratorReshape = (fitData * fitWeights).reshape(ymax // binning, binning,
88 xmax // binning, binning)
89 binDenominatorReshape = fitWeights.reshape(binNumeratorReshape.shape)
90 binnedNumerator = binNumeratorReshape.sum(axis=3).sum(axis=1)
91 binnedDenominator = binDenominatorReshape.sum(axis=3).sum(axis=1)
94 warnings.warn(
'Using slow binning method--consider choosing a binsize that evenly divides '
95 f
'into the image size, so that {ymax} mod binning == 0 '
96 f
'and {xmax} mod binning == 0')
97 xarray = np.arange(xmax)
98 yarray = np.arange(ymax)
99 xmesh, ymesh = np.meshgrid(xarray, yarray)
100 xbins = np.arange(0, xmax + binning, binning)
101 ybins = np.arange(0, ymax + binning, binning)
102 numerator = fitWeights * fitData
103 binnedNumerator, *_ = scipy.stats.binned_statistic_2d(ymesh.ravel(), xmesh.ravel(),
104 numerator.ravel(), statistic=
'sum',
106 binnedDenominator, *_ = scipy.stats.binned_statistic_2d(ymesh.ravel(), xmesh.ravel(),
107 fitWeights.ravel(), statistic=
'sum',
109 binnedData = np.zeros(binnedNumerator.shape)
110 ind = binnedDenominator != 0
111 np.divide(binnedNumerator, binnedDenominator, out=binnedData, where=ind)
112 binnedWeight = binnedDenominator
113 binMask = (binnedData * binnedWeight**0.5) > detectionThreshold
114 tmpOutputMask = binMask.repeat(binning, axis=0)[:ymax]
115 outputMask = tmpOutputMask.repeat(binning, axis=1)[:, :xmax]
117 outputMask = (fitData * fitWeights**0.5) > detectionThreshold
120 maskedImage.mask.array &= ~maskedImage.mask.getPlaneBitMask(detectedPlane)
123 maskedImage.mask.array[outputMask] |= maskedImage.mask.getPlaneBitMask(detectedPlane)