class SubtractBackgroundConfig(pexConfig.Config): """!Config for SubtractBackgroundTask @note Many of these fields match fields in lsst.afw.math.BackgroundControl, the control class for lsst.afw.math.makeBackground """ statisticsProperty = pexConfig.ChoiceField( doc="type of statistic to use for grid points", dtype=str, default="MEANCLIP", allowed={ "MEANCLIP": "clipped mean", "MEAN": "unclipped mean", "MEDIAN": "median", } ) undersampleStyle = pexConfig.ChoiceField( doc="behaviour if there are too few points in grid for requested interpolation style", dtype=str, default="REDUCE_INTERP_ORDER", allowed={ "THROW_EXCEPTION": "throw an exception if there are too few points", "REDUCE_INTERP_ORDER": "use an interpolation style with a lower order.", "INCREASE_NXNYSAMPLE": "Increase the number of samples used to make the interpolation grid.", }, ) binSize = pexConfig.RangeField( doc="how large a region of the sky should be used for each background point", dtype=int, default=128, min=1, ) binSizeX = pexConfig.RangeField( doc=("Sky region size to be used for each background point in X direction. " "If 0, the binSize config is used."), dtype=int, default=0, min=0, ) binSizeY = pexConfig.RangeField( doc=("Sky region size to be used for each background point in Y direction. " "If 0, the binSize config is used."), dtype=int, default=0, min=0, ) algorithm = pexConfig.ChoiceField( doc="how to interpolate the background values. This maps to an enum; see afw::math::Background", dtype=str, default="AKIMA_SPLINE", optional=True, allowed={ "CONSTANT": "Use a single constant value", "LINEAR": "Use linear interpolation", "NATURAL_SPLINE": "cubic spline with zero second derivative at endpoints", "AKIMA_SPLINE": "higher-level nonlinear spline that is more robust to outliers", "NONE": "No background estimation is to be attempted", }, ) ignoredPixelMask = pexConfig.ListField( doc="Names of mask planes to ignore while estimating the background", dtype=str, default=["BAD", "EDGE", "DETECTED", "DETECTED_NEGATIVE", "NO_DATA", ], itemCheck=lambda x: x in afwImage.Mask().getMaskPlaneDict().keys(), ) isNanSafe = pexConfig.Field( doc="Ignore NaNs when estimating the background", dtype=bool, default=False, ) useApprox = pexConfig.Field( doc="Use Approximate (Chebyshev) to model background.", dtype=bool, default=True, ) approxOrderX = pexConfig.Field( doc="Approximation order in X for background Chebyshev (valid only with useApprox=True)", dtype=int, default=6, ) # Note: Currently X- and Y-orders must be equal due to a limitation in math::Chebyshev1Function2 # The following is being added so that the weighting attribute can also be configurable for the # call to afwMath.ApproximateControl approxOrderY = pexConfig.Field( doc="Approximation order in Y for background Chebyshev (valid only with useApprox=True)", dtype=int, default=-1, ) weighting = pexConfig.Field( doc="Use inverse variance weighting in calculation (valid only with useApprox=True)", dtype=bool, default=True, )
class MatchPessimisticBConfig(pexConfig.Config): """Configuration for MatchPessimisticBTask """ numBrightStars = pexConfig.RangeField( doc="Number of bright stars to use. Sets the max number of patterns " "that can be tested.", dtype=int, default=200, min=2, ) minMatchedPairs = pexConfig.RangeField( doc="Minimum number of matched pairs; see also minFracMatchedPairs.", dtype=int, default=30, min=2, ) minFracMatchedPairs = pexConfig.RangeField( doc="Minimum number of matched pairs as a fraction of the smaller of " "the number of reference stars or the number of good sources; " "the actual minimum is the smaller of this value or " "minMatchedPairs.", dtype=float, default=0.3, min=0, max=1, ) matcherIterations = pexConfig.RangeField( doc="Number of softening iterations in matcher.", dtype=int, default=5, min=1, ) maxOffsetPix = pexConfig.RangeField( doc="Maximum allowed shift of WCS, due to matching (pixel). " "When changing this value, the " "LoadReferenceObjectsConfig.pixelMargin should also be updated.", dtype=int, default=300, max=4000, ) maxRotationDeg = pexConfig.RangeField( doc="Rotation angle allowed between sources and position reference " "objects (degrees).", dtype=float, default=1.0, max=6.0, ) numPointsForShape = pexConfig.Field( doc="Number of points to define a shape for matching.", dtype=int, default=6, ) numPointsForShapeAttempt = pexConfig.Field( doc="Number of points to try for creating a shape. This value should " "be greater than or equal to numPointsForShape. Besides " "loosening the signal to noise cut in the 'matcher' SourceSelector, " "increasing this number will solve CCDs where no match was found.", dtype=int, default=6, ) minMatchDistPixels = pexConfig.RangeField( doc="Distance in units of pixels to always consider a source-" "reference pair a match. This prevents the astrometric fitter " "from over-fitting and removing stars that should be matched and " "allows for inclusion of new matches as the wcs improves.", dtype=float, default=1.0, min=0.0, max=6.0, ) numPatternConsensus = pexConfig.Field( doc="Number of implied shift/rotations from patterns that must agree " "before it a given shift/rotation is accepted. This is only used " "after the first softening iteration fails and if both the " "number of reference and source objects is greater than " "numBrightStars.", dtype=int, default=3, ) numRefRequireConsensus = pexConfig.Field( doc="If the available reference objects exceeds this number, " "consensus/pessimistic mode will enforced regardless of the " "number of available sources. Below this optimistic mode (" "exit at first match rather than requiring numPatternConsensus to " "be matched) can be used. If more sources are required to match, " "decrease the signal to noise cut in the sourceSelector.", dtype=int, default=1000, ) maxRefObjects = pexConfig.RangeField( doc="Maximum number of reference objects to use for the matcher. The " "absolute maximum allowed for is 2 ** 16 for memory reasons.", dtype=int, default=2**16, min=0, max=2**16 + 1, ) def validate(self): pexConfig.Config.validate(self) if self.numPointsForShapeAttempt < self.numPointsForShape: raise ValueError("numPointsForShapeAttempt must be greater than " "or equal to numPointsForShape.") if self.numPointsForShape > self.numBrightStars: raise ValueError("numBrightStars must be greater than " "numPointsForShape.")
class CharacterizeImageConfig(pipeBase.PipelineTaskConfig, pipelineConnections=CharacterizeImageConnections ): """!Config for CharacterizeImageTask""" doMeasurePsf = pexConfig.Field( dtype=bool, default=True, doc= "Measure PSF? If False then for all subsequent operations use either existing PSF " "model when present, or install simple PSF model when not (see installSimplePsf " "config options)") doWrite = pexConfig.Field( dtype=bool, default=True, doc="Persist results?", ) doWriteExposure = pexConfig.Field( dtype=bool, default=True, doc= "Write icExp and icExpBackground in addition to icSrc? Ignored if doWrite False.", ) psfIterations = pexConfig.RangeField( dtype=int, default=2, min=1, doc="Number of iterations of detect sources, measure sources, " "estimate PSF. If useSimplePsf is True then 2 should be plenty; " "otherwise more may be wanted.", ) background = pexConfig.ConfigurableField( target=SubtractBackgroundTask, doc="Configuration for initial background estimation", ) detection = pexConfig.ConfigurableField(target=SourceDetectionTask, doc="Detect sources") doDeblend = pexConfig.Field(dtype=bool, default=True, doc="Run deblender input exposure") deblend = pexConfig.ConfigurableField( target=SourceDeblendTask, doc="Split blended source into their components") measurement = pexConfig.ConfigurableField( target=SingleFrameMeasurementTask, doc="Measure sources") doApCorr = pexConfig.Field( dtype=bool, default=True, doc="Run subtasks to measure and apply aperture corrections") measureApCorr = pexConfig.ConfigurableField( target=MeasureApCorrTask, doc="Subtask to measure aperture corrections") applyApCorr = pexConfig.ConfigurableField( target=ApplyApCorrTask, doc="Subtask to apply aperture corrections") # If doApCorr is False, and the exposure does not have apcorrections already applied, the # active plugins in catalogCalculation almost certainly should not contain the characterization plugin catalogCalculation = pexConfig.ConfigurableField( target=CatalogCalculationTask, doc="Subtask to run catalogCalculation plugins on catalog") useSimplePsf = pexConfig.Field( dtype=bool, default=True, doc= "Replace the existing PSF model with a simplified version that has the same sigma " "at the start of each PSF determination iteration? Doing so makes PSF determination " "converge more robustly and quickly.", ) installSimplePsf = pexConfig.ConfigurableField( target=InstallGaussianPsfTask, doc="Install a simple PSF model", ) refObjLoader = pexConfig.ConfigurableField( target=LoadIndexedReferenceObjectsTask, doc="reference object loader", ) ref_match = pexConfig.ConfigurableField( target=RefMatchTask, doc= "Task to load and match reference objects. Only used if measurePsf can use matches. " "Warning: matching will only work well if the initial WCS is accurate enough " "to give good matches (roughly: good to 3 arcsec across the CCD).", ) measurePsf = pexConfig.ConfigurableField( target=MeasurePsfTask, doc="Measure PSF", ) repair = pexConfig.ConfigurableField( target=RepairTask, doc="Remove cosmic rays", ) checkUnitsParseStrict = pexConfig.Field( doc= "Strictness of Astropy unit compatibility check, can be 'raise', 'warn' or 'silent'", dtype=str, default="raise", ) def setDefaults(self): super().setDefaults() # just detect bright stars; includeThresholdMultipler=10 seems large, # but these are the values we have been using self.detection.thresholdValue = 5.0 self.detection.includeThresholdMultiplier = 10.0 self.detection.doTempLocalBackground = False # do not deblend, as it makes a mess self.doDeblend = False # measure and apply aperture correction; note: measuring and applying aperture # correction are disabled until the final measurement, after PSF is measured self.doApCorr = True # minimal set of measurements needed to determine PSF self.measurement.plugins.names = [ "base_PixelFlags", "base_SdssCentroid", "base_SdssShape", "base_GaussianFlux", "base_PsfFlux", "base_CircularApertureFlux", ] def validate(self): if self.doApCorr and not self.measurePsf: raise RuntimeError( "Must measure PSF to measure aperture correction, " "because flags determined by PSF measurement are used to identify " "sources used to measure aperture correction")
class SourceDeblendConfig(pexConf.Config): edgeHandling = pexConf.ChoiceField( doc= 'What to do when a peak to be deblended is close to the edge of the image', dtype=str, default='ramp', allowed={ 'clip': 'Clip the template at the edge AND the mirror of the edge.', 'ramp': 'Ramp down flux at the image edge by the PSF', 'noclip': 'Ignore the edge when building the symmetric template.', }) strayFluxToPointSources = pexConf.ChoiceField( doc='When the deblender should attribute stray flux to point sources', dtype=str, default='necessary', allowed={ 'necessary': 'When there is not an extended object in the footprint', 'always': 'Always', 'never': ('Never; stray flux will not be attributed to any deblended child ' 'if the deblender thinks all peaks look like point sources'), }) findStrayFlux = pexConf.Field( dtype=bool, default=True, doc='Find stray flux---flux not claimed by any child in the deblender.' ) assignStrayFlux = pexConf.Field( dtype=bool, default=True, doc='Assign stray flux to deblend children. Implies findStrayFlux.') strayFluxRule = pexConf.ChoiceField( doc='How to split flux among peaks', dtype=str, default='trim', allowed={ 'r-to-peak': '~ 1/(1+R^2) to the peak', 'r-to-footprint': ('~ 1/(1+R^2) to the closest pixel in the footprint. ' 'CAUTION: this can be computationally expensive on large footprints!' ), 'nearest-footprint': ('Assign 100% to the nearest footprint (using L-1 norm aka ' 'Manhattan distance)'), 'trim': ('Shrink the parent footprint to pixels that are not assigned to children' ) }) clipStrayFluxFraction = pexConf.Field( dtype=float, default=0.001, doc=('When splitting stray flux, clip fractions below ' 'this value to zero.')) psfChisq1 = pexConf.Field( dtype=float, default=1.5, optional=False, doc=('Chi-squared per DOF cut for deciding a source is ' 'a PSF during deblending (un-shifted PSF model)')) psfChisq2 = pexConf.Field( dtype=float, default=1.5, optional=False, doc=('Chi-squared per DOF cut for deciding a source is ' 'PSF during deblending (shifted PSF model)')) psfChisq2b = pexConf.Field( dtype=float, default=1.5, optional=False, doc=('Chi-squared per DOF cut for deciding a source is ' 'a PSF during deblending (shifted PSF model #2)')) maxNumberOfPeaks = pexConf.Field( dtype=int, default=0, doc=("Only deblend the brightest maxNumberOfPeaks peaks in the parent" " (<= 0: unlimited)")) maxFootprintArea = pexConf.Field( dtype=int, default=1000000, doc=("Maximum area for footprints before they are ignored as large; " "non-positive means no threshold applied")) maxFootprintSize = pexConf.Field( dtype=int, default=0, doc=("Maximum linear dimension for footprints before they are ignored " "as large; non-positive means no threshold applied")) minFootprintAxisRatio = pexConf.Field( dtype=float, default=0.0, doc=("Minimum axis ratio for footprints before they are ignored " "as large; non-positive means no threshold applied")) notDeblendedMask = pexConf.Field( dtype=str, default="NOT_DEBLENDED", optional=True, doc="Mask name for footprints not deblended, or None") tinyFootprintSize = pexConf.RangeField( dtype=int, default=2, min=2, inclusiveMin=True, doc=('Footprints smaller in width or height than this value will ' 'be ignored; minimum of 2 due to PSF gradient calculation.')) propagateAllPeaks = pexConf.Field( dtype=bool, default=False, doc=('Guarantee that all peaks produce a child source.')) catchFailures = pexConf.Field( dtype=bool, default=False, doc=( "If True, catch exceptions thrown by the deblender, log them, " "and set a flag on the parent, instead of letting them propagate up" )) maskPlanes = pexConf.ListField( dtype=str, default=["SAT", "INTRP", "NO_DATA"], doc="Mask planes to ignore when performing statistics") maskLimits = pexConf.DictField( keytype=str, itemtype=float, default={}, doc= ("Mask planes with the corresponding limit on the fraction of masked pixels. " "Sources violating this limit will not be deblended."), )
class MatchOptimisticBConfig(pexConfig.Config): """Configuration for MatchOptimisticBTask """ maxMatchDistArcSec = pexConfig.RangeField( doc="Maximum separation between reference objects and sources " "beyond which they will not be considered a match (arcsec)", dtype=float, default=3, min=0, ) numBrightStars = pexConfig.RangeField( doc="Number of bright stars to use", dtype=int, default=50, min=2, ) minMatchedPairs = pexConfig.RangeField( doc="Minimum number of matched pairs; see also minFracMatchedPairs", dtype=int, default=30, min=2, ) minFracMatchedPairs = pexConfig.RangeField( doc="Minimum number of matched pairs as a fraction of the smaller of " "the number of reference stars or the number of good sources; " "the actual minimum is the smaller of this value or minMatchedPairs", dtype=float, default=0.3, min=0, max=1, ) maxOffsetPix = pexConfig.RangeField( doc="Maximum allowed shift of WCS, due to matching (pixel). " "When changing this value, the LoadReferenceObjectsConfig.pixelMargin should also be updated.", dtype=int, default=300, max=4000, ) maxRotationDeg = pexConfig.RangeField( doc= "Rotation angle allowed between sources and position reference objects (degrees)", dtype=float, default=1.0, max=6.0, ) allowedNonperpDeg = pexConfig.RangeField( doc="Allowed non-perpendicularity of x and y (degree)", dtype=float, default=3.0, max=45.0, ) numPointsForShape = pexConfig.Field( doc="number of points to define a shape for matching", dtype=int, default=6, ) maxDeterminant = pexConfig.Field( doc= "maximum determinant of linear transformation matrix for a usable solution", dtype=float, default=0.02, )
class MatchBackgroundsConfig(pexConfig.Config): usePolynomial = pexConfig.Field( dtype=bool, doc="Fit background difference with Chebychev polynomial interpolation " "(using afw.math.Approximate)? If False, fit with spline interpolation using afw.math.Background", default=False) order = pexConfig.Field( dtype=int, doc= "Order of Chebyshev polynomial background model. Ignored if usePolynomial False", default=8) badMaskPlanes = pexConfig.ListField( doc="Names of mask planes to ignore while estimating the background", dtype=str, default=[ "NO_DATA", "DETECTED", "DETECTED_NEGATIVE", "SAT", "BAD", "INTRP", "CR" ], itemCheck=lambda x: x in afwImage.Mask().getMaskPlaneDict(), ) gridStatistic = pexConfig.ChoiceField( dtype=str, doc="Type of statistic to estimate pixel value for the grid points", default="MEAN", allowed={ "MEAN": "mean", "MEDIAN": "median", "MEANCLIP": "clipped mean" }) undersampleStyle = pexConfig.ChoiceField( doc= "Behaviour if there are too few points in grid for requested interpolation style. " "Note: INCREASE_NXNYSAMPLE only allowed for usePolynomial=True.", dtype=str, default="REDUCE_INTERP_ORDER", allowed={ "THROW_EXCEPTION": "throw an exception if there are too few points", "REDUCE_INTERP_ORDER": "use an interpolation style with a lower order.", "INCREASE_NXNYSAMPLE": "Increase the number of samples used to make the interpolation grid.", }) binSize = pexConfig.Field( doc= "Bin size for gridding the difference image and fitting a spatial model", dtype=int, default=256) interpStyle = pexConfig.ChoiceField( dtype=str, doc= "Algorithm to interpolate the background values; ignored if usePolynomial is True" "Maps to an enum; see afw.math.Background", default="AKIMA_SPLINE", allowed={ "CONSTANT": "Use a single constant value", "LINEAR": "Use linear interpolation", "NATURAL_SPLINE": "cubic spline with zero second derivative at endpoints", "AKIMA_SPLINE": "higher-level nonlinear spline that is more robust to outliers", "NONE": "No background estimation is to be attempted", }) numSigmaClip = pexConfig.Field( dtype=int, doc= "Sigma for outlier rejection; ignored if gridStatistic != 'MEANCLIP'.", default=3) numIter = pexConfig.Field( dtype=int, doc= "Number of iterations of outlier rejection; ignored if gridStatistic != 'MEANCLIP'.", default=2) bestRefWeightCoverage = pexConfig.RangeField( dtype=float, doc= "Weight given to coverage (number of pixels that overlap with patch), " "when calculating best reference exposure. Higher weight prefers exposures with high coverage." "Ignored when reference visit is supplied", default=0.4, min=0., max=1.) bestRefWeightVariance = pexConfig.RangeField( dtype=float, doc= "Weight given to image variance when calculating best reference exposure. " "Higher weight prefers exposures with low image variance. Ignored when reference visit is supplied", default=0.4, min=0., max=1.) bestRefWeightLevel = pexConfig.RangeField( dtype=float, doc= "Weight given to mean background level when calculating best reference exposure. " "Higher weight prefers exposures with low mean background level. " "Ignored when reference visit is supplied.", default=0.2, min=0., max=1.) approxWeighting = pexConfig.Field( dtype=bool, doc= ("Use inverse-variance weighting when approximating background offset model? " "This will fail when the background offset is constant " "(this is usually only the case in testing with artificial images)." "(usePolynomial=True)"), default=True, ) gridStdevEpsilon = pexConfig.RangeField( dtype=float, doc= "Tolerance on almost zero standard deviation in a background-offset grid bin. " "If all bins have a standard deviation below this value, the background offset model " "is approximated without inverse-variance weighting. (usePolynomial=True)", default=1e-8, min=0.)
class PhotoCalConfig(pexConf.Config): """Config for PhotoCal""" magLimit = pexConf.Field( dtype = float, default = 22.0, doc = "Don't use objects fainter than this magnitude", ) doWriteOutput = pexConf.Field( dtype = bool, default = True, doc = "Write a field name astrom_usedByPhotoCal to the schema", ) fluxField = pexConf.Field( dtype = str, default = "slot_CalibFlux_flux", doc = ("Name of the source flux field to use. The associated flag field\n" "('<name>_flags') will be implicitly included in badFlags."), ) applyColorTerms = pexConf.Field( dtype = bool, default = None, doc = ("Apply photometric color terms to reference stars? One of:\n" "None: apply if colorterms and photoCatName are not None;\n" " fail if color term data is not available for the specified ref catalog and filter.\n" "True: always apply colorterms; fail if color term data is not available for the\n" " specified reference catalog and filter.\n" "False: do not apply."), optional = True, ) goodFlags = pexConf.ListField( dtype = str, default = [], doc = "List of source flag fields that must be set for a source to be used.", ) badFlags = pexConf.ListField( dtype = str, default = ["base_PixelFlags_flag_edge", "base_PixelFlags_flag_interpolated", "base_PixelFlags_flag_saturated"], doc = "List of source flag fields that will cause a source to be rejected when they are set.", ) sigmaMax = pexConf.Field( dtype = float, default = 0.25, doc = "maximum sigma to use when clipping", optional = True, ) nSigma = pexConf.Field( dtype = float, default = 3.0, doc = "clip at nSigma", ) useMedian = pexConf.Field( dtype = bool, default = True, doc = "use median instead of mean to compute zeropoint", ) nIter = pexConf.Field( dtype = int, default = 20, doc = "number of iterations", ) colorterms = pexConf.ConfigField( dtype = ColortermLibrary, doc = "Library of photometric reference catalog name: color term dict", ) photoCatName = pexConf.Field( dtype = str, optional = True, doc = ("Name of photometric reference catalog; used to select a color term dict in colorterms." " see also applyColorTerms"), ) magErrFloor = pexConf.RangeField( dtype = float, default = 0.0, doc = "Additional magnitude uncertainty to be added in quadrature with measurement errors.", min = 0.0, ) def validate(self): pexConf.Config.validate(self) if self.applyColorTerms and self.photoCatName is None: raise RuntimeError("applyColorTerms=True requires photoCatName is non-None") if self.applyColorTerms and len(self.colorterms.data) == 0: raise RuntimeError("applyColorTerms=True requires colorterms be provided")
class SourceDetectionConfig(pexConfig.Config): """!Configuration parameters for the SourceDetectionTask """ minPixels = pexConfig.RangeField( doc= "detected sources with fewer than the specified number of pixels will be ignored", dtype=int, optional=False, default=1, min=0, ) isotropicGrow = pexConfig.Field( doc="Pixels should be grown as isotropically as possible (slower)", dtype=bool, optional=False, default=False, ) combinedGrow = pexConfig.Field( doc= "Grow all footprints at the same time? This allows disconnected footprints to merge.", dtype=bool, default=True, ) nSigmaToGrow = pexConfig.Field( doc= "Grow detections by nSigmaToGrow * [PSF RMS width]; if 0 then do not grow", dtype=float, default=2.4, # 2.4 pixels/sigma is roughly one pixel/FWHM ) returnOriginalFootprints = pexConfig.Field( doc= "Grow detections to set the image mask bits, but return the original (not-grown) footprints", dtype=bool, optional=False, default=False, ) thresholdValue = pexConfig.RangeField( doc= "Threshold for footprints; exact meaning and units depend on thresholdType.", dtype=float, optional=False, default=5.0, min=0.0, ) includeThresholdMultiplier = pexConfig.RangeField( doc="Include threshold relative to thresholdValue", dtype=float, default=1.0, min=0.0, ) thresholdType = pexConfig.ChoiceField( doc="specifies the desired flavor of Threshold", dtype=str, optional=False, default="stdev", allowed={ "variance": "threshold applied to image variance", "stdev": "threshold applied to image std deviation", "value": "threshold applied to image value", "pixel_stdev": "threshold applied to per-pixel std deviation", }, ) thresholdPolarity = pexConfig.ChoiceField( doc= "specifies whether to detect positive, or negative sources, or both", dtype=str, optional=False, default="positive", allowed={ "positive": "detect only positive sources", "negative": "detect only negative sources", "both": "detect both positive and negative sources", }, ) adjustBackground = pexConfig.Field( dtype=float, doc="Fiddle factor to add to the background; debugging only", default=0.0, ) reEstimateBackground = pexConfig.Field( dtype=bool, doc="Estimate the background again after final source detection?", default=True, optional=False, ) background = pexConfig.ConfigurableField( doc="Background re-estimation; ignored if reEstimateBackground false", target=SubtractBackgroundTask, ) tempLocalBackground = pexConfig.ConfigurableField( doc= ("A local (small-scale), temporary background estimation step run between " "detecting above-threshold regions and detecting the peaks within " "them; used to avoid detecting spuerious peaks in the wings."), target=SubtractBackgroundTask, ) doTempLocalBackground = pexConfig.Field( dtype=bool, doc= "Enable temporary local background subtraction? (see tempLocalBackground)", default=True, ) tempWideBackground = pexConfig.ConfigurableField( doc= ("A wide (large-scale) background estimation and removal before footprint and peak detection. " "It is added back into the image after detection. The purpose is to suppress very large " "footprints (e.g., from large artifacts) that the deblender may choke on." ), target=SubtractBackgroundTask, ) doTempWideBackground = pexConfig.Field( dtype=bool, doc= "Do temporary wide (large-scale) background subtraction before footprint detection?", default=False, ) nPeaksMaxSimple = pexConfig.Field( dtype=int, doc=("The maximum number of peaks in a Footprint before trying to " "replace its peaks using the temporary local background"), default=1, ) nSigmaForKernel = pexConfig.Field( dtype=float, doc= ("Multiple of PSF RMS size to use for convolution kernel bounding box size; " "note that this is not a half-size. The size will be rounded up to the nearest odd integer" ), default=7.0, ) statsMask = pexConfig.ListField( dtype=str, doc= "Mask planes to ignore when calculating statistics of image (for thresholdType=stdev)", default=['BAD', 'SAT', 'EDGE', 'NO_DATA'], ) def setDefaults(self): self.tempLocalBackground.binSize = 64 self.tempLocalBackground.algorithm = "AKIMA_SPLINE" self.tempLocalBackground.useApprox = False # Background subtraction to remove a large-scale background (e.g., scattered light); restored later. # Want to keep it from exceeding the deblender size limit of 1 Mpix, so half that is reasonable. self.tempWideBackground.binSize = 512 self.tempWideBackground.algorithm = "AKIMA_SPLINE" self.tempWideBackground.useApprox = False # Ensure we can remove even bright scattered light that is DETECTED for maskPlane in ("DETECTED", "DETECTED_NEGATIVE"): if maskPlane in self.tempWideBackground.ignoredPixelMask: self.tempWideBackground.ignoredPixelMask.remove(maskPlane)