class ApertureTaskConfig(pexConfig.Config): apRad = pexConfig.Field(doc="Radius of aperture", dtype=int, default=4)
class PhotoCalConfig(pexConf.Config): """Config for PhotoCal""" match = pexConf.ConfigField("Match to reference catalog", DirectMatchConfigWithoutLoader) reserve = pexConf.ConfigurableField(target=ReserveSourcesTask, doc="Reserve sources from fitting") fluxField = pexConf.Field( dtype=str, default="slot_CalibFlux_instFlux", doc= ("Name of the source instFlux 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, ) 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") def setDefaults(self): pexConf.Config.setDefaults(self) self.match.sourceSelection.doFlags = True self.match.sourceSelection.flags.bad = [ "base_PixelFlags_flag_edge", "base_PixelFlags_flag_interpolated", "base_PixelFlags_flag_saturated", ] self.match.sourceSelection.doUnresolved = True
class CharacterizeImageConfig(pexConfig.Config): """!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=LoadAstrometryNetObjectsTask, 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): pexConfig.Config.setDefaults(self) # 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 # 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 PsfexPsfDeterminerConfig(measAlg.BasePsfDeterminerConfig): __nEigenComponents = pexConfig.Field( doc="number of eigen components for PSF kernel creation", dtype=int, default=4, ) spatialOrder = pexConfig.Field( doc="specify spatial order for PSF kernel creation", dtype=int, default=2, check=lambda x: x >= 0, ) sizeCellX = pexConfig.Field( doc="size of cell used to determine PSF (pixels, column direction)", dtype=int, default=256, # minValue = 10, check=lambda x: x >= 10, ) sizeCellY = pexConfig.Field( doc="size of cell used to determine PSF (pixels, row direction)", dtype=int, default=sizeCellX.default, # minValue = 10, check=lambda x: x >= 10, ) __nStarPerCell = pexConfig.Field( doc="number of stars per psf cell for PSF kernel creation", dtype=int, default=3, ) samplingSize = pexConfig.Field( doc="Resolution of the internal PSF model relative to the pixel size; " "e.g. 0.5 is equal to 2x oversampling", dtype=float, default=1, ) badMaskBits = pexConfig.ListField( doc="List of mask bits which cause a source to be rejected as bad " "N.b. INTRP is used specially in PsfCandidateSet; it means \"Contaminated by neighbour\"", dtype=str, default=["INTRP", "SAT"], ) psfexBasis = pexConfig.ChoiceField( doc= "BASIS value given to psfex. PIXEL_AUTO will use the requested samplingSize only if " "the FWHM < 3 pixels. Otherwise, it will use samplingSize=1. PIXEL will always use the " "requested samplingSize", dtype=str, allowed={ "PIXEL": "Always use requested samplingSize", "PIXEL_AUTO": "Only use requested samplingSize when FWHM < 3", }, default='PIXEL', optional=False, ) __borderWidth = pexConfig.Field( doc= "Number of pixels to ignore around the edge of PSF candidate postage stamps", dtype=int, default=0, ) __nStarPerCellSpatialFit = pexConfig.Field( doc="number of stars per psf Cell for spatial fitting", dtype=int, default=5, ) __constantWeight = pexConfig.Field( doc= "Should each PSF candidate be given the same weight, independent of magnitude?", dtype=bool, default=True, ) __nIterForPsf = pexConfig.Field( doc="number of iterations of PSF candidate star list", dtype=int, default=3, ) tolerance = pexConfig.Field( doc="tolerance of spatial fitting", dtype=float, default=1e-2, ) lam = pexConfig.Field( doc="floor for variance is lam*data", dtype=float, default=0.05, ) reducedChi2ForPsfCandidates = pexConfig.Field( doc="for psf candidate evaluation", dtype=float, default=2.0, ) spatialReject = pexConfig.Field( doc="Rejection threshold (stdev) for candidates based on spatial fit", dtype=float, default=3.0, ) recentroid = pexConfig.Field( doc="Should PSFEX be permitted to recentroid PSF candidates?", dtype=bool, default=False, ) def setDefaults(self): self.kernelSize = 41
class CrosstalkConfig(pexConfig.Config): minPixelToMask = pexConfig.Field(dtype=float, default=45000, doc="Set crosstalk mask plane for pixels over this value") crosstalkMaskPlane = pexConfig.Field(dtype=str, default="CROSSTALK", doc="Name for crosstalk mask plane") coeffs = pexConfig.ConfigField(dtype=CrosstalkCoeffsConfig, doc="Crosstalk coefficients")
class StarGalaxyFeaturesConfig(pexConfig.Config): """Config for making the files of features needed to train the star galaxy classifier """ filters = pexConfig.ListField( doc="Filters", dtype=str, default=["HSC-G", "HSC-R", "HSC-I", "HSC-Z", "HSC-Y"]) seeingColName = pexConfig.Field( doc="Column name for seeing columns used in addSeeing", dtype=str, default="base_SdssShape_psf") psfColName = pexConfig.Field( doc="Column name for PSF flux columns used in addMagnitudes", dtype=str, default="base_PsfFlux_instFlux") modelColName = pexConfig.Field( doc= "Column name for model flux columns used in addSNFlux and addMagnitudes", dtype=str, default="modelfit_CModel_instFlux") truthRaColName = pexConfig.Field( doc="Column name for RA column in the truth table", dtype=str, default="coord_ra") truthDecColName = pexConfig.Field( doc="Column name for Declination column in the truth table", dtype=str, default="coord_dec") truthClassColName = pexConfig.Field( doc= "Column name for Classification column in the truth table, star = 0 and galaxy = 1", dtype=str, default="MU_CLASS") truthMatchRadius = pexConfig.Field( doc= "Match radius for matching between the truth table and the input catalog default is 0.5 \ arcseconds.", dtype=float, default=0.5 / 3600) cleanRadius = pexConfig.Field( doc= "Match radius inside which to remove neighbours. Default is 1.5 arcseconds which was found to \ remove sources affecting the classifier.", dtype=float, default=1.5 / 3600) magLim = pexConfig.Field( doc= "Magnitude limit for the output features, the default truth table uses a catalog that is \ trusted to 25th in i so this limit is used.", dtype=float, default=25.0)
class ImageMapReduceConfig(pexConfig.Config): """Configuration parameters for the ImageMapReduceTask """ mapperSubtask = pexConfig.ConfigurableField( doc="Subtask to run on each subimage", target=ImageMapperSubtask, ) reducerSubtask = pexConfig.ConfigurableField( doc="Subtask to combine results of mapperSubTask", target=ImageReducerSubtask, ) # Separate cellCentroidsX and cellCentroidsY since pexConfig.ListField accepts limited dtypes # (i.e., no Point2D). The resulting set of centroids is the "vertical stack" of # `cellCentroidsX` and `cellCentroidsY`, i.e. for (1,2), (3,4) respectively, the # resulting centroids are ((1,3), (2,4)). cellCentroidsX = pexConfig.ListField( dtype=float, doc="""Input X centroids around which to place subimages. If None, use grid config options below.""", optional=True, default=None ) cellCentroidsY = pexConfig.ListField( dtype=float, doc="""Input Y centroids around which to place subimages. If None, use grid config options below.""", optional=True, default=None ) cellSizeX = pexConfig.Field( dtype=float, doc="""Dimensions of each grid cell in x direction""", default=10., check=lambda x: x > 0. ) cellSizeY = pexConfig.Field( dtype=float, doc="""Dimensions of each grid cell in y direction""", default=10., check=lambda x: x > 0. ) gridStepX = pexConfig.Field( dtype=float, doc="""Spacing between subsequent grid cells in x direction. If equal to cellSizeX, then there is no overlap in the x direction.""", default=10., check=lambda x: x > 0. ) gridStepY = pexConfig.Field( dtype=float, doc="""Spacing between subsequent grid cells in y direction. If equal to cellSizeY, then there is no overlap in the y direction.""", default=10., check=lambda x: x > 0. ) borderSizeX = pexConfig.Field( dtype=float, doc="""Dimensions of grid cell border in +/- x direction, to be used for generating `expandedSubExposure`.""", default=5., check=lambda x: x > 0. ) borderSizeY = pexConfig.Field( dtype=float, doc="""Dimensions of grid cell border in +/- y direction, to be used for generating `expandedSubExposure`.""", default=5., check=lambda x: x > 0. ) adjustGridOption = pexConfig.ChoiceField( dtype=str, doc="""Whether and how to adjust grid to fit evenly within, and cover entire image""", default="spacing", allowed={ "spacing": "adjust spacing between centers of grid cells (allowing overlaps)", "size": "adjust the sizes of the grid cells (disallowing overlaps)", "none": "do not adjust the grid sizes or spacing" } ) scaleByFwhm = pexConfig.Field( dtype=bool, doc="""Scale cellSize/gridStep/borderSize/overlapSize by PSF FWHM rather than pixels?""", default=True ) returnSubImages = pexConfig.Field( dtype=bool, doc="""Return the input subExposures alongside the processed ones (for debugging)""", default=False ) ignoreMaskPlanes = pexConfig.ListField( dtype=str, doc="""Mask planes to ignore for sigma-clipped statistics""", default=("INTRP", "EDGE", "DETECTED", "SAT", "CR", "BAD", "NO_DATA", "DETECTED_NEGATIVE") )
class ProcessBrightStarsConfig( pipeBase.PipelineTaskConfig, pipelineConnections=ProcessBrightStarsConnections): """Configuration parameters for ProcessBrightStarsTask """ magLimit = pexConfig.Field( dtype=float, doc= "Magnitude limit, in Gaia G; all stars brighter than this value will be processed", default=18) stampSize = pexConfig.ListField( dtype=int, doc="Size of the stamps to be extracted, in pixels", default=(250, 250)) modelStampBuffer = pexConfig.Field( dtype=float, doc= "'Buffer' factor to be applied to determine the size of the stamp the processed stars will " "be saved in. This will also be the size of the extended PSF model.", default=1.1) doRemoveDetected = pexConfig.Field( dtype=bool, doc= "Whether DETECTION footprints, other than that for the central object, should be changed to " "BAD", default=True) doApplyTransform = pexConfig.Field( dtype=bool, doc= "Apply transform to bright star stamps to correct for optical distortions?", default=True) warpingKernelName = pexConfig.ChoiceField(dtype=str, doc="Warping kernel", default="lanczos5", allowed={ "bilinear": "bilinear interpolation", "lanczos3": "Lanczos kernel of order 3", "lanczos4": "Lanczos kernel of order 4", "lanczos5": "Lanczos kernel of order 5", }) annularFluxRadii = pexConfig.ListField( dtype=int, doc= "Inner and outer radii of the annulus used to compute the AnnularFlux for normalization, " "in pixels.", default=(40, 50)) annularFluxStatistic = pexConfig.ChoiceField( dtype=str, doc="Type of statistic to use to compute annular flux.", default="MEANCLIP", allowed={ "MEAN": "mean", "MEDIAN": "median", "MEANCLIP": "clipped mean", }) numSigmaClip = pexConfig.Field( dtype=float, doc= "Sigma for outlier rejection; ignored if annularFluxStatistic != 'MEANCLIP'.", default=4) numIter = pexConfig.Field( dtype=int, doc= "Number of iterations of outlier rejection; ignored if annularFluxStatistic != 'MEANCLIP'.", default=3) badMaskPlanes = pexConfig.ListField( dtype=str, doc= "Mask planes that, if set, lead to associated pixels not being included in the computation of the" " annular flux.", default=('BAD', 'CR', 'CROSSTALK', 'EDGE', 'NO_DATA', 'SAT', 'SUSPECT', 'UNMASKEDNAN')) minPixelsWithinFrame = pexConfig.Field( dtype=int, doc= "Minimum number of pixels that must fall within the stamp boundary for the bright star to be" " saved when its center is beyond the exposure boundary.", default=50) doApplySkyCorr = pexConfig.Field( dtype=bool, doc="Apply full focal plane sky correction before extracting stars?", default=True) discardNanFluxStars = pexConfig.Field( dtype=bool, doc="Should stars with NaN annular flux be discarded?", default=False) refObjLoader = pexConfig.ConfigurableField( target=LoadIndexedReferenceObjectsTask, doc="Reference object loader for astrometric calibration.", ) def setDefaults(self): self.refObjLoader.ref_dataset_name = "gaia_dr2_20200414"
class ScarletDeblendConfig(pexConfig.Config): """MultibandDeblendConfig Configuration for the multiband deblender. The parameters are organized by the parameter types, which are - Stopping Criteria: Used to determine if the fit has converged - Position Fitting Criteria: Used to fit the positions of the peaks - Constraints: Used to apply constraints to the peaks and their components - Other: Parameters that don't fit into the above categories """ # Stopping Criteria maxIter = pexConfig.Field( dtype=int, default=300, doc=("Maximum number of iterations to deblend a single parent")) relativeError = pexConfig.Field(dtype=float, default=1e-4, doc=("Change in the loss function between" "iterations to exit fitter")) # Blend Configuration options edgeDistance = pexConfig.Field( dtype=int, default=1, doc="All sources with flux within `edgeDistance` from the edge " "will be considered edge sources.") # Constraints morphThresh = pexConfig.Field( dtype=float, default=1, doc="Fraction of background RMS a pixel must have" "to be included in the initial morphology") monotonic = pexConfig.Field(dtype=bool, default=True, doc="Make models monotonic") symmetric = pexConfig.Field(dtype=bool, default=False, doc="Make models symmetric") # Other scarlet paremeters useWeights = pexConfig.Field( dtype=bool, default=True, doc=("Whether or not use use inverse variance weighting." "If `useWeights` is `False` then flat weights are used")) modelPsfSize = pexConfig.Field(dtype=int, default=11, doc="Model PSF side length in pixels") modelPsfSigma = pexConfig.Field(dtype=float, default=0.8, doc="Define sigma for the model frame PSF") saveTemplates = pexConfig.Field( dtype=bool, default=True, doc="Whether or not to save the SEDs and templates") processSingles = pexConfig.Field( dtype=bool, default=True, doc="Whether or not to process isolated sources in the deblender") sourceModel = pexConfig.Field( dtype=str, default="double", doc= ("How to determine which model to use for sources, from\n" "- 'single': use a single component for all sources\n" "- 'double': use a bulge disk model for all sources\n" "- 'compact': use a single component model, initialzed with a point source morphology, " " for all sources\n" "- 'point': use a point-source model for all sources\n" "- 'fit: use a PSF fitting model to determine the number of components (not yet implemented)" )) downgrade = pexConfig.Field( dtype=bool, default=False, doc= "Whether or not to downgrade the number of components for sources in small bounding boxes" ) # Mask-plane restrictions badMask = pexConfig.ListField( dtype=str, default=["BAD", "CR", "NO_DATA", "SAT", "SUSPECT"], doc="Whether or not to process isolated sources in the deblender") statsMask = pexConfig.ListField( dtype=str, default=["SAT", "INTRP", "NO_DATA"], doc="Mask planes to ignore when performing statistics") maskLimits = pexConfig.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."), ) # Size restrictions maxNumberOfPeaks = pexConfig.Field( dtype=int, default=0, doc=("Only deblend the brightest maxNumberOfPeaks peaks in the parent" " (<= 0: unlimited)")) maxFootprintArea = pexConfig.Field( dtype=int, default=1000000, doc=("Maximum area for footprints before they are ignored as large; " "non-positive means no threshold applied")) maxFootprintSize = pexConfig.Field( dtype=int, default=0, doc=("Maximum linear dimension for footprints before they are ignored " "as large; non-positive means no threshold applied")) minFootprintAxisRatio = pexConfig.Field( dtype=float, default=0.0, doc=("Minimum axis ratio for footprints before they are ignored " "as large; non-positive means no threshold applied")) # Failure modes fallback = pexConfig.Field( dtype=bool, default=True, doc= "Whether or not to fallback to a smaller number of components if a source does not initialize" ) notDeblendedMask = pexConfig.Field( dtype=str, default="NOT_DEBLENDED", optional=True, doc="Mask name for footprints not deblended, or None") catchFailures = pexConfig.Field( dtype=bool, default=True, doc=( "If True, catch exceptions thrown by the deblender, log them, " "and set a flag on the parent, instead of letting them propagate up" ))
class Config1(pexConf.Config): f = pexConf.Field("Config1.f", float, default=4)
class DetectorConfig(pexConfig.Config): """A configuration that represents (and can be used to construct) a Detector. """ transformDict = pexConfig.ConfigField( "Dictionary of camera transforms keyed on the transform type.", TransformMapConfig) name = pexConfig.Field("Name of detector slot", str) id = pexConfig.Field("ID of detector slot", int) bbox_x0 = pexConfig.Field("x0 of pixel bounding box", int) bbox_y0 = pexConfig.Field("y0 of pixel bounding box", int) bbox_x1 = pexConfig.Field("x1 of pixel bounding box", int) bbox_y1 = pexConfig.Field("y1 of pixel bounding box", int) detectorType = pexConfig.Field( "Detector type: SCIENCE=0, FOCUS=1, GUIDER=2, WAVEFRONT=3", int) physicalType = pexConfig.Field( "How this specific detector is constructed; e.g. CCD, E2V, HgCdTe ", str, default="CCD") serial = pexConfig.Field( "Serial string associated with this specific detector", str) offset_x = pexConfig.Field( "x offset from the origin of the camera in mm in the transposed system.", float) offset_y = pexConfig.Field( "y offset from the origin of the camera in mm in the transposed system.", float) refpos_x = pexConfig.Field( "x position of the reference point in the detector in pixels " "in transposed coordinates.", float) refpos_y = pexConfig.Field( "y position of the reference point in the detector in pixels " "in transposed coordinates.", float) yawDeg = pexConfig.Field( "yaw (rotation about z) of the detector in degrees. " "This includes any necessary rotation to go from " "detector coordinates to camera coordinates " "after optional transposition.", float) pitchDeg = pexConfig.Field( "pitch (rotation about y) of the detector in degrees", float) rollDeg = pexConfig.Field( "roll (rotation about x) of the detector in degrees", float) pixelSize_x = pexConfig.Field("Pixel size in the x dimension in mm", float) pixelSize_y = pexConfig.Field("Pixel size in the y dimension in mm", float) # Depending on the choice of detector coordinates, the pixel grid may need # to be transposed before rotation to put it in camera coordinates. transposeDetector = pexConfig.Field( "Transpose the pixel grid before orienting in focal plane?", bool) crosstalk = pexConfig.ListField( dtype=float, doc= ("Flattened crosstalk coefficient matrix; should have nAmps x nAmps entries. " "Once 'reshape'-ed, ``coeffs[i][j]`` is the fraction of the j-th amp present on the i-th amp." ), optional=True) # Accessors to get "compiled" versions of parameters. def getCrosstalk(self, numAmps): """Return a 2-D numpy array of crosstalk coefficients of the proper shape""" if not self.crosstalk: return None if numAmps != int(np.sqrt(len(self.crosstalk))): numAmps = int(np.sqrt(len(self.crosstalk))) try: return np.array(self.crosstalk, dtype=np.float32).reshape( (numAmps, numAmps)) except Exception as e: raise RuntimeError( f"Cannot reshape 'crosstalk' coefficients to square matrix: {e}" ) @property def bbox(self): """Return the detector bounding box from the separate box endpoint values. """ return geom.BoxI(geom.PointI(self.bbox_x0, self.bbox_y0), geom.PointI(self.bbox_x1, self.bbox_y1)) @property def offset(self): """Return the detector offset as a Point2D from the separate config values. """ return geom.Point2D(self.offset_x, self.offset_y) @property def refPos(self): """Return the detector reference position as a Point2D from the separate config values. """ return geom.Point2D(self.refpos_x, self.refpos_y) @property def orientation(self): """Return the cameraGeom.Orientation() object defined by the configuration values. """ return Orientation(self.offset, self.refPos, geom.Angle(self.yawDeg, geom.degrees), geom.Angle(self.pitchDeg, geom.degrees), geom.Angle(self.rollDeg, geom.degrees)) @property def pixelSize(self): """Return the pixel size as an Extent2D from the separate values. """ return geom.Extent2D(self.pixelSize_x, self.pixelSize_y)
class FinalizeCharacterizationConfig(pipeBase.PipelineTaskConfig, pipelineConnections=FinalizeCharacterizationConnections): """Configuration for FinalizeCharacterizationTask.""" source_selector = sourceSelectorRegistry.makeField( doc="How to select sources", default="science" ) id_column = pexConfig.Field( doc='Name of column in isolated_star_sources with source id.', dtype=str, default='sourceId', ) reserve_selection = pexConfig.ConfigurableField( target=ReserveIsolatedStarsTask, doc='Task to select reserved stars', ) make_psf_candidates = pexConfig.ConfigurableField( target=measAlg.MakePsfCandidatesTask, doc='Task to make psf candidates from selected stars.', ) psf_determiner = measAlg.psfDeterminerRegistry.makeField( 'PSF Determination algorithm', default='piff' ) measurement = pexConfig.ConfigurableField( target=SingleFrameMeasurementTask, doc='Measure sources for aperture corrections' ) measure_ap_corr = pexConfig.ConfigurableField( target=MeasureApCorrTask, doc="Subtask to measure aperture corrections" ) apply_ap_corr = pexConfig.ConfigurableField( target=ApplyApCorrTask, doc="Subtask to apply aperture corrections" ) def setDefaults(self): super().setDefaults() source_selector = self.source_selector['science'] source_selector.setDefaults() # We use the source selector only to select out flagged objects # and signal-to-noise. Isolated, unresolved sources are handled # by the isolated star catalog. source_selector.doFlags = True source_selector.doSignalToNoise = True source_selector.doFluxLimit = False source_selector.doUnresolved = False source_selector.doIsolated = False source_selector.signalToNoise.minimum = 20.0 source_selector.signalToNoise.maximum = 1000.0 source_selector.signalToNoise.fluxField = 'base_GaussianFlux_instFlux' source_selector.signalToNoise.errField = 'base_GaussianFlux_instFluxErr' source_selector.flags.bad = ['base_PixelFlags_flag_edge', 'base_PixelFlags_flag_interpolatedCenter', 'base_PixelFlags_flag_saturatedCenter', 'base_PixelFlags_flag_crCenter', 'base_PixelFlags_flag_bad', 'base_PixelFlags_flag_interpolated', 'base_PixelFlags_flag_saturated', 'slot_Centroid_flag', 'base_GaussianFlux_flag'] # Configure aperture correction to select only high s/n sources (that # were used in the psf modeling) to avoid background problems when # computing the aperture correction map. self.measure_ap_corr.sourceSelector = 'science' ap_selector = self.measure_ap_corr.sourceSelector['science'] ap_selector.doFluxLimit = False ap_selector.doFlags = True ap_selector.doUnresolved = False ap_selector.doSignalToNoise = True ap_selector.doIsolated = False ap_selector.flags.good = ['calib_psf_used'] ap_selector.flags.bad = [] ap_selector.signalToNoise.minimum = 200.0 ap_selector.signalToNoise.maximum = None ap_selector.signalToNoise.fluxField = 'base_PsfFlux_instFlux' ap_selector.signalToNoise.errField = 'base_PsfFlux_instFluxErr' import lsst.meas.modelfit # noqa: F401 import lsst.meas.extensions.photometryKron # noqa: F401 import lsst.meas.extensions.convolved # noqa: F401 import lsst.meas.extensions.gaap # noqa: F401 import lsst.meas.extensions.shapeHSM # noqa: F401 # Set up measurement defaults self.measurement.plugins.names = [ 'base_PsfFlux', 'base_GaussianFlux', 'modelfit_DoubleShapeletPsfApprox', 'modelfit_CModel', 'ext_photometryKron_KronFlux', 'ext_convolved_ConvolvedFlux', 'ext_gaap_GaapFlux', 'ext_shapeHSM_HsmShapeRegauss', 'ext_shapeHSM_HsmSourceMoments', 'ext_shapeHSM_HsmPsfMoments', 'ext_shapeHSM_HsmSourceMomentsRound', ] self.measurement.slots.modelFlux = 'modelfit_CModel' self.measurement.plugins['ext_convolved_ConvolvedFlux'].seeing.append(8.0) self.measurement.plugins['ext_gaap_GaapFlux'].sigmas = [ 0.5, 0.7, 1.0, 1.5, 2.5, 3.0 ] self.measurement.plugins['ext_gaap_GaapFlux'].doPsfPhotometry = True self.measurement.slots.shape = 'ext_shapeHSM_HsmSourceMoments' self.measurement.slots.psfShape = 'ext_shapeHSM_HsmPsfMoments' self.measurement.plugins['ext_shapeHSM_HsmShapeRegauss'].deblendNChild = "" # Turn off slot setting for measurement for centroid and shape # (for which we use the input src catalog measurements) self.measurement.slots.centroid = None self.measurement.slots.apFlux = None self.measurement.slots.calibFlux = None names = self.measurement.plugins['ext_convolved_ConvolvedFlux'].getAllResultNames() self.measure_ap_corr.allowFailure += names names = self.measurement.plugins["ext_gaap_GaapFlux"].getAllGaapResultNames() self.measure_ap_corr.allowFailure += names
class IngestIndexedReferenceConfig(pexConfig.Config): ref_dataset_name = pexConfig.Field( dtype=str, default='cal_ref_cat', doc='String to pass to the butler to retrieve persisted files.', ) level = pexConfig.Field( dtype=int, default=8, doc='Default HTM level. Level 8 gives ~0.08 sq deg per trixel.', ) file_reader = pexConfig.ConfigurableField( target=TextReaderTask, doc='Task to use to read the files. Default is to expect text files.') ra_name = pexConfig.Field( dtype=str, doc="Name of RA column", ) dec_name = pexConfig.Field( dtype=str, doc="Name of Dec column", ) mag_column_list = pexConfig.ListField( dtype=str, doc= """The values in the reference catalog are assumed to be in AB magnitudes. List of column names to use for photometric information. At least one entry is required.""" ) mag_err_column_map = pexConfig.DictField( keytype=str, itemtype=str, default={}, doc= "A map of magnitude column name (key) to magnitude error column (value)." ) is_photometric_name = pexConfig.Field( dtype=str, optional=True, doc= 'Name of column stating if satisfactory for photometric calibration (optional).' ) is_resolved_name = pexConfig.Field( dtype=str, optional=True, doc='Name of column stating if the object is resolved (optional).') is_variable_name = pexConfig.Field( dtype=str, optional=True, doc= 'Name of column stating if the object is measured to be variable (optional).' ) id_name = pexConfig.Field( dtype=str, optional=True, doc='Name of column to use as an identifier (optional).') extra_col_names = pexConfig.ListField( dtype=str, default=[], doc='Extra columns to add to the reference catalog.') def validate(self): pexConfig.Config.validate(self) if not (self.ra_name and self.dec_name and self.mag_column_list): raise ValueError( "ra_name and dec_name and at least one entry in mag_column_list must be" + " supplied.") if len(self.mag_err_column_map) > 0 and not len( self.mag_column_list) == len(self.mag_err_column_map): raise ValueError( "If magnitude errors are provided, all magnitudes must have an error column" )
class ReferenceMatchConfig(pexConfig.Config): ref = pexConfig.ConfigField( dtype=CatalogConfig, doc="Columns and properties of the reference catalog") refDialect = pexConfig.ConfigField( dtype=CsvConfig, doc= "CSV format of the reference catalog file (delimiter, quoting, etc...)" ) pos = pexConfig.ConfigField( dtype=CatalogConfig, doc="Columns and properties of the position catalog") posDialect = pexConfig.ConfigField( dtype=CsvConfig, doc= "CSV format of the position catalog file (delimiter, quoting, etc...)") expDialect = pexConfig.ConfigField( dtype=CsvConfig, doc= "CSV format of the exposure metadata file (delimiter, quoting, etc...)" ) outDialect = pexConfig.ConfigField( dtype=CsvConfig, doc="CSV format of the output file (delimiter, quoting, etc...)") radius = pexConfig.RangeField(dtype=float, doc="Match radius (arcsec)", default=2.0, min=0.0, inclusiveMin=False) parallaxThresh = pexConfig.RangeField( dtype=float, doc="Parallax threshold (milliarcsec). Positions of reference catalog " "entries with parallax below this value will not be subject to " "reduction from barycentric to geocentric place.", default=10.0, min=0.0) doOutputRefExtras = pexConfig.Field( dtype=bool, doc="If set, match records will contain the proper-motion/parallax " "corrected position of the reference object at the epoch of the " "matched position, as well as flags indicating which corrections " "were performed.", default=True) expIdKey = pexConfig.Field( dtype=str, default="Computed_ccdExposureId", doc="Name of metadata key corresponding to the exposure ID") def getRadius(self): """Return the radius parameter value as an lsst.afw.geom.Angle""" return self.radius * afwGeom.arcseconds def getParallaxThresh(self): """Return the self.parallaxThresh parameter value as an lsst.afw.geom.Angle""" return self.parallaxThresh / 1000.0 * afwGeom.arcseconds
class AddConfig(pipeBase.PipelineTaskConfig, pipelineConnections=AddConnections): addend = pexConfig.Field(doc="amount to add", dtype=int, default=3)
class PsfexStarSelectorConfig(BaseStarSelectorTask.ConfigClass): fluxName = pexConfig.Field( dtype=str, doc="Name of photometric flux key ", default="base_PsfFlux", ) fluxErrName = pexConfig.Field( dtype=str, doc="Name of phot. flux err. key", default="", ) minFwhm = pexConfig.Field( dtype=float, doc="Maximum allowed FWHM ", default=2, ) maxFwhm = pexConfig.Field( dtype=float, doc="Minimum allowed FWHM ", default=10, ) maxFwhmVariability = pexConfig.Field( dtype=float, doc="Allowed FWHM variability (1.0 = 100%)", default=0.2, ) maxbad = pexConfig.Field( dtype=int, doc="Max number of bad pixels ", default=0, check=lambda x: x >= 0, ) maxbadflag = pexConfig.Field(dtype=bool, doc="Filter bad pixels? ", default=True) maxellip = pexConfig.Field( dtype=float, doc="Maximum (A-B)/(A+B) ", default=0.3, check=lambda x: x >= 0.0, ) minsn = pexConfig.Field( dtype=float, doc="Minimum S/N for candidates", default=100, check=lambda x: x >= 0.0, ) def validate(self): pexConfig.Config.validate(self) if self.fluxErrName == "": self.fluxErrName = self.fluxName + ".err" elif self.fluxErrName != self.fluxName + ".err": raise pexConfig.FieldValidationError( "fluxErrName (%s) doesn't correspond to fluxName (%s)" % (self.fluxErrName, self.fluxName)) if self.minFwhm > self.maxFwhm: raise pexConfig.FieldValidationError( "minFwhm (%f) > maxFwhm (%f)" % (self.minFwhm, self.maxFwhm)) def setDefaults(self): self.badFlags = [ "base_PixelFlags_flag_edge", "base_PixelFlags_flag_saturatedCenter", "base_PixelFlags_flag_crCenter", "base_PixelFlags_flag_bad", "base_PixelFlags_flag_suspectCenter", "base_PsfFlux_flag", #"parent", # actually this is a test on deblend_nChild ]
class SourceAssocConfig(pexConfig.Config): """Configuration parameters for SourceAssocTask. """ inputLevel = pexConfig.Field(dtype=str, default="sensor", doc=""" Level of input datasets identified by the inputSourceDataset and inputCalexpMetadataDataset configuration parameters. """) inputSourceDataset = pexConfig.Field( dtype=str, default="src", doc="Name of the butler dataset for input sources.") inputCalexpMetadataDataset = pexConfig.Field(dtype=str, default="calexp_md", doc=""" Name of the butler dataset for calibrated exposure metadata. Note that this dataset must yield metadata for the calibrated exposures that the sources from inputSourceDataset were detected and measured on; otherwise, the SourceAssoc pipeline behavior is undefined. """) sourceProcessing = pexConfig.ConfigField( dtype=apCluster.SourceProcessingConfig, doc=""" Source processing parameters. To see their descriptions: >>> from lsst.ap.cluster import SourceProcessingConfig >>> help(SourceProcessingConfig) """) clustering = pexConfig.ConfigField(dtype=apCluster.ClusteringConfig, doc=""" Source clustering parameters. To see their descriptions: >>> from lsst.ap.cluster import ClusteringConfig >>> help(ClusteringConfig) """) doCluster = pexConfig.Field(dtype=bool, default=True, doc=""" If set to True, then "good" sources are clustered with the OPTICS algorithm - this is an attempt to group sources from individual exposures which correspond to measurements of the same astronomical object. If set to False, then running SourceAssocTask reduces to simply processing sources - this involves adding exposure ID, filter, and middle-of-exposure time fields to each source, as well as computation of sky-coordinate errors from centroid errors. In other words, sources are prepared for database ingest into the LSST Source database table, but are not associated with one another. Note that a "good" source is one with valid sky-coordinates and which has not been identified as "bad" by one of the flag fields listed in the sourceProcessing.badFlagFields configuration parameter. """) doDiscardNoiseClusters = pexConfig.Field( dtype=bool, default=True, doc="Discard single source clusters?") doWriteClusters = pexConfig.Field(dtype=bool, default=True, doc=""" Write source clusters to persistent storage via the butler? Source clusters are stored as lsst.ap.cluster.SourceClusterCatalog instances; one such catalog is stored per sky-tile. The corresponding butler dataset name is "object", so they can be retrieved using e.g.: >>> clusters = butler.get("object", skyTile=12345) Note that if no clusters were generated for a sky-tile, say because the doCluster configuration parameter was set to False, then nothing (not even an empty catalog!) is written to persistent storage. In other words: >>> butler.datasetExists("object", skyTile=12345) can return False, even after SourceAssocTask has been run on sky-tile 12345. """) algorithmFlags = pexConfig.DictField(keytype=str, itemtype=str, doc=""" A dictionary mapping from algorithm names to strings containing comma separated lists of flag field names. If any flag is set for a source, then that source is ignored when computing the measurement mean of the corresponding algorithm. """) doWriteSources = pexConfig.Field(dtype=bool, default=True, doc=""" Write processed "good" sources to persistent storage via the butler? A "good" source is one with valid coordinates and which has not been identified as "bad" by one of the flag fields listed in the sourceProcessing.badFlagFields configuration parameter. Sources are stored as lsst.afw.table.SourceCatalog instances; one such catalog is stored per sky-tile. The corresponding butler dataset name is "source", so they can be retrieved using e.g.: >>> sources = butler.get("source", skyTile=12345) Note that if no "good" sources were identified for a sky-tile, then nothing (not even an empty catalog!) is written to persistent storage. In other words: >>> butler.datasetExists("source", skyTile=12345) can return False. In this case, the clustering algorithm had no input, so no "object" dataset will have been written for the sky-tile either. """) doWriteBadSources = pexConfig.Field(dtype=bool, default=True, doc=""" Write processed "bad" sources to persistent storage via the butler? A "bad" source is one with valid coordinates and for which at least one of the flag fields listed in the sourceProcessing.badFlagFields configuration parameter has been set. Bad sources are stored as lsst.afw.table.SourceCatalog instances; one such catalog is stored per sky-tile. The corresponding butler dataset name is "badSource", so they can be retrieved using e.g.: >>> badSources = butler.get("badSource", skyTile=12345) If no "bad" sources were identified in the sky-tile, no dataset is written (not even an empty catalog). """) doWriteInvalidSources = pexConfig.Field(dtype=bool, default=True, doc=""" Write "invalid" sources to persistent storage via the butler? An "invalid" source is one with invalid coordinates/centroid, e.g. because the centroid algorithm failed. Invalid sources are stored as lsst.afw.table.SourceCatalog instances; one such catalog is stored per sky-tile. The corresponding butler dataset name is "invalidSource", so they can be retrieved using e,g,: >>> invalidSources = butler.get("invalidSource", skyTile=12345) As for the other datasets, if no "invalid" sources were identified for the sky-tile, no dataset is written. """) sourceHistogramResolution = pexConfig.RangeField( dtype=int, default=2000, min=1, doc="X and Y resolution of 2D source position histograms.") doMakeSourceHistogram = pexConfig.Field(dtype=bool, default=True, doc=""" Make 2D histogram of "good" source positions? If set, a square image covering the sky-tile being processed and with resolution equal to sourceHistogramResolution will be created. The value of each pixel in this image will be the number of "good" sources inside that pixel. """) doMakeBadSourceHistogram = pexConfig.Field(dtype=bool, default=True, doc=""" Make 2D histogram of "bad" source positions? If set, a square image covering the sky-tile being processed and with resolution equal to sourceHistogramResolution will be created. The value of each pixel in this image will be the number of "bad" sources inside that pixel. """) doWriteSourceHistogram = pexConfig.Field(dtype=bool, default=True, doc=""" Write "good" source histogram to persistent storage via the butler? If True, one histogram image is written per sky-tile containing at least one "good" source, via the butler. The corresponding dataset name is "sourceHist", and the type of these histograms is lsst.afw.image.DecoratedImageU. They can be retrieved using e.g.: >>> img = butler.get("sourceHist", skyTile=12345) """) doWriteBadSourceHistogram = pexConfig.Field(dtype=bool, default=True, doc=""" Write "bad" source histogram to persistent storage via the butler? If True, one histogram image is written per sky-tile containing at least one "bad" source, via the butler. The corresponding dataset name is "badSourceHist", and the type of these histograms is lsst.afw.image.DecoratedImageU. They can be retrieved using e.g.: >>> img = butler.get("badSourceHist", skyTile=12345) """) measPrefix = pexConfig.Field(dtype=str, optional=True, default=None, doc=""" Prefix for all source measurement fields. Must match the value of the lsst.meas.algorithms.SourceMeasurementConfig prefix configuration parameter, which is typically available as measurement.prefix in the CCD processing task configuration. """) measSlots = pexConfig.ConfigField(dtype=measAlgorithms.SourceSlotConfig, doc=""" Mapping from algorithms to special aliases in lsst.afw.table.SourceTable. Must match the value of the lsst.meas.algorithms.SourceMeasurementConfig slots configuration parameter, which is typically available as measurement.slots in the CCD processing task configuration. For the details: >>> from lsst.meas.algorithms import SourceSlotConfig >>> help(SourceSlotConfig) """) def setDefaults(self): self.sourceProcessing.badFlagFields = [ "flags.negative", "flags.pixel.edge", "shape.sdss.flags.unweightedbad", ] flags = ",".join([ "flags.negative", "flags.badcentroid", "flags.pixel.edge", "flags.pixel.interpolated.center", "flags.pixel.saturated.center", ]) self.algorithmFlags = { "flux.gaussian": "flux.gaussian.flags," + flags, "flux.naive": "flux.naive.flags," + flags, "flux.psf": "flux.psf.flags," + flags, "flux.sinc": "flux.sinc.flags," + flags, "flux.kron": "flux.kron.flags,flux.kron.flags.aperture," + flags, "multishapelet.exp.flux": "multishapelet.exp.flux.flags," + flags, "multishapelet.dev.flux": "multishapelet.dev.flux.flags," + flags, "multishapelet.combo.flux": "multishapelet.combo.flux.flags," + flags, "shape.sdss": "shape.sdss.flags.unweightedbad," + flags, }
class InsertFakesConfig(PipelineTaskConfig, pipelineConnections=InsertFakesConnections): """Config for inserting fake sources Notes ----- The default column names are those from the University of Washington sims database. """ raColName = pexConfig.Field( doc="RA column name used in the fake source catalog.", dtype=str, default="raJ2000", ) decColName = pexConfig.Field( doc="Dec. column name used in the fake source catalog.", dtype=str, default="decJ2000", ) doCleanCat = pexConfig.Field( doc="If true removes bad sources from the catalog.", dtype=bool, default=True, ) diskHLR = pexConfig.Field( doc= "Column name for the disk half light radius used in the fake source catalog.", dtype=str, default="DiskHalfLightRadius", ) bulgeHLR = pexConfig.Field( doc= "Column name for the bulge half light radius used in the fake source catalog.", dtype=str, default="BulgeHalfLightRadius", ) magVar = pexConfig.Field( doc= "The column name for the magnitude calculated taking variability into account. In the format " "``filter name``magVar, e.g. imagVar for the magnitude in the i band.", dtype=str, default="%smagVar", ) nDisk = pexConfig.Field( doc= "The column name for the sersic index of the disk component used in the fake source catalog.", dtype=str, default="disk_n", ) nBulge = pexConfig.Field( doc= "The column name for the sersic index of the bulge component used in the fake source catalog.", dtype=str, default="bulge_n", ) aDisk = pexConfig.Field( doc= "The column name for the semi major axis length of the disk component used in the fake source" "catalog.", dtype=str, default="a_d", ) aBulge = pexConfig.Field( doc= "The column name for the semi major axis length of the bulge component.", dtype=str, default="a_b", ) bDisk = pexConfig.Field( doc= "The column name for the semi minor axis length of the disk component.", dtype=str, default="b_d", ) bBulge = pexConfig.Field( doc= "The column name for the semi minor axis length of the bulge component used in the fake source " "catalog.", dtype=str, default="b_b", ) paDisk = pexConfig.Field( doc= "The column name for the PA of the disk component used in the fake source catalog.", dtype=str, default="pa_disk", ) paBulge = pexConfig.Field( doc= "The column name for the PA of the bulge component used in the fake source catalog.", dtype=str, default="pa_bulge", ) fakeType = pexConfig.Field( doc= "What type of fake catalog to use, snapshot (includes variability in the magnitudes calculated " "from the MJD of the image), static (no variability) or filename for a user defined fits" "catalog.", dtype=str, default="static", ) calibFluxRadius = pexConfig.Field( doc="Radius for the calib flux (in pixels).", dtype=float, default=12.0, ) coaddName = pexConfig.Field( doc="The name of the type of coadd used", dtype=str, default="deep", )
class ProductionLevelConfig(pexConfig.Config): # class that handles production level configurationClass = pexConfig.Field("configuration class", str)
class AddConfig(pexConfig.Config): addend = pexConfig.Field(doc="amount to add", dtype=float, default=3.1)
class ProcessImageConfig(pexConfig.Config): psf = pexConfig.ConfigurableField(target=BuildControlPsfTask, doc="PSF determination") measurement = pexConfig.ConfigurableField( target=SingleFrameMeasurementTask, doc="Source measurement") varianceBorderWidth = pexConfig.Field( dtype=int, default=1, doc= ("Use a border of this many pixels around each postage stamp (combined over the full image)" " to compute the variance")) dataType = pexConfig.Field(dtype=str, default='', doc=("default data type")) maxObjects = pexConfig.Field( dtype=int, default=None, optional=True, doc=("If this is not None, then only process this many objects.")) numPerRow = pexConfig.Field(dtype=int, default=100, optional=True, doc=("How many objects per row")) doDetection = pexConfig.Field(dtype=bool, default=False, doc=("run source detection on the image")) detection = pexConfig.ConfigurableField( target=SourceDetectionTask, doc="detection algorithm", ) deblend = pexConfig.ConfigurableField( target=SourceDeblendTask, doc="deblend algorithm", ) addGridPoints = pexConfig.Field( dtype=bool, default=False, doc= ("add footprints at the grid points if they are not in the detection list" )) addGridDist = pexConfig.Field( dtype=float, default=6., doc= ("add objects grid points that do not have a source within this distance" )) writeGridDist = pexConfig.Field( dtype=bool, default=False, doc=("Write out distance to closest grid point")) correlatedNoiseFile = pexConfig.Field( doc= "File that contains list of k values and power spectrum to use with correlated noise. Still" " needs to be scaled by noise variance. For BFD only", dtype=str, default='', ) doCorrelatedNoise = pexConfig.Field( doc="Run with correlated noise", dtype=bool, default=False, ) recomputeVariance = pexConfig.Field( doc="recompute Variance after deblending", dtype=bool, default=False, ) addTruthCols = pexConfig.ListField( dtype=str, default=[], optional=True, doc="List of columns to store in truth table") truthPrefix = pexConfig.Field(dtype=str, default='truth', optional=True, doc="Prefix for truth values") matchTruth = pexConfig.Field( doc="match the detected objects to truth", dtype=bool, default=False, ) matchTol = pexConfig.Field( doc="match tolerance to truth if no size information available", dtype=float, default=3, ) PIXEL_SCALE = pexConfig.Field( doc="pixel scale in arcsec/pixel", dtype=float, default=0.168, ) def setDefaults(self): pexConfig.Config.setDefaults(self) # self.measurement.slots.centroid = "centroid.sdss" # self.measurement.slots.instFlux = None # self.measurement.slots.modelFlux = "cmodel.flux" # self.measurement.slots.calibFlux = None # self.measurement.slots.apFlux = "flux.sinc" # self.measurement.plugins.names = ["shape.sdss", "flux.sinc", "flux.psf", "shape.hsm.regauss", # "flux.kron", "cmodel", "classification.extendedness"] # ] # self.measurement.plugins.names |= lsst.meas.extensions.multiShapelet.algorithms # self.measurement.plugins['classification.extendedness'].fluxRatio = 0.985 if bfdAvailable: self.measurement.plugins.names |= ["bfdKMoment"] self.measurement.plugins['bfdKMoment'].sigma = 2 self.measurement.plugins['bfdKMoment'].useRecVariance = False self.measurement.plugins['bfdKMoment'].useTableVariance = True self.measurement.plugins['bfdKMoment'].shift = True self.measurement.plugins['bfdKMoment'].wIndex = 4 self.measurement.plugins['bfdKMoment'].useNoisePs = False self.detection.thresholdValue = 5 self.detection.reEstimateBackground = False
class MultConfig(pexConfig.Config): multiplicand = pexConfig.Field(doc="amount by which to multiply", dtype=float, default=2.5)
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)
class SourceDetectionConfig(pexConfig.Config): 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, ) nSigmaToGrow = pexConfig.Field( doc="Grow detections by nSigmaToGrow * sigma; 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", 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.ConfigField( dtype=BackgroundConfig, doc="Background re-estimation configuration") footprintBackground = pexConfig.ConfigField( dtype=BackgroundConfig, doc="A seperate background estimation and removal before footprint and peak detection. "\ "It is added back into the image after detection." ) doFootprintBackground = pexConfig.Field( dtype=bool, doc="Do background subtraction before footprint detection?", default=False) def setDefaults(self): self.footprintBackground.binSize = 64 self.footprintBackground.algorithm = "AKIMA_SPLINE" self.footprintBackground.useApprox = False
class Config2(pexConfig.Config): f = pexConfig.Field(doc="Config2.f", dtype=float, default=0.5, check=lambda x: x > 0)
class BackgroundConfig(pexConfig.Config): 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=10) algorithm = pexConfig.ChoiceField( doc= "how to interpolate the background values. This maps to an enum; see afw::math::Background", dtype=str, default="NATURAL_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.MaskU().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, ) approxOrder = pexConfig.Field( doc= "Apprimation order for background Chebyshev (valid only with useApprox=True)", dtype=int, default=6, ) def validate(self): pexConfig.Config.validate(self) # Allow None to be used as an equivalent for "NONE", even though C++ expects the latter. if self.algorithm is None: self.algorithm = "NONE"
class ProcessCcdWithFakesConfig( PipelineTaskConfig, pipelineConnections=ProcessCcdWithFakesConnections): """Config for inserting fake sources Notes ----- The default column names are those from the UW sims database. """ doApplyExternalGlobalPhotoCalib = pexConfig.Field( dtype=bool, default=False, doc="Whether to apply an external photometric calibration via an " "`lsst.afw.image.PhotoCalib` object. Uses the " "`externalPhotoCalibName` config option to determine which " "calibration to use. Uses a global calibration.") doApplyExternalTractPhotoCalib = pexConfig.Field( dtype=bool, default=False, doc="Whether to apply an external photometric calibration via an " "`lsst.afw.image.PhotoCalib` object. Uses the " "`externalPhotoCalibName` config option to determine which " "calibration to use. Uses a per tract calibration.") externalPhotoCalibName = pexConfig.ChoiceField( doc="What type of external photo calib to use.", dtype=str, default="jointcal", allowed={ "jointcal": "Use jointcal_photoCalib", "fgcm": "Use fgcm_photoCalib", "fgcm_tract": "Use fgcm_tract_photoCalib" }) doApplyExternalGlobalSkyWcs = pexConfig.Field( dtype=bool, default=False, doc="Whether to apply an external astrometric calibration via an " "`lsst.afw.geom.SkyWcs` object. Uses the " "`externalSkyWcsName` config option to determine which " "calibration to use. Uses a global calibration.") doApplyExternalTractSkyWcs = pexConfig.Field( dtype=bool, default=False, doc="Whether to apply an external astrometric calibration via an " "`lsst.afw.geom.SkyWcs` object. Uses the " "`externalSkyWcsName` config option to determine which " "calibration to use. Uses a per tract calibration.") externalSkyWcsName = pexConfig.ChoiceField( doc="What type of updated WCS calib to use.", dtype=str, default="jointcal", allowed={"jointcal": "Use jointcal_wcs"}) coaddName = pexConfig.Field( doc="The name of the type of coadd used", dtype=str, default="deep", ) srcFieldsToCopy = pexConfig.ListField( dtype=str, default=("calib_photometry_reserved", "calib_photometry_used", "calib_astrometry_used", "calib_psf_candidate", "calib_psf_used", "calib_psf_reserved"), doc=("Fields to copy from the `src` catalog to the output catalog " "for matching sources Any missing fields will trigger a " "RuntimeError exception.")) matchRadiusPix = pexConfig.Field( dtype=float, default=3, doc= ("Match radius for matching icSourceCat objects to sourceCat objects (pixels)" ), ) doMatchVisit = pexConfig.Field(dtype=bool, default=False, doc="Match visit to trim the fakeCat") calibrate = pexConfig.ConfigurableField(target=CalibrateTask, doc="The calibration task to use.") insertFakes = pexConfig.ConfigurableField( target=InsertFakesTask, doc="Configuration for the fake sources") def setDefaults(self): super().setDefaults() self.calibrate.measurement.plugins[ "base_PixelFlags"].masksFpAnywhere.append("FAKE") self.calibrate.measurement.plugins[ "base_PixelFlags"].masksFpCenter.append("FAKE") self.calibrate.doAstrometry = False self.calibrate.doWriteMatches = False self.calibrate.doPhotoCal = False self.calibrate.detection.reEstimateBackground = False
class AstrometricErrorQaConfig(pexConfig.Config): cameras = pexConfig.ListField(dtype = str, doc = "Cameras to run AstrometricErrorQaTask", default = ("lsstSim", "hscSim", "suprimecam", "cfht", "sdss", "coadd")) maxErr = pexConfig.Field(dtype = float, doc = "Maximum astrometric error (in arcseconds)", default = 0.5)
class PcaPsfDeterminerConfig(pexConfig.Config): nonLinearSpatialFit = pexConfig.Field( doc="Use non-linear fitter for spatial variation of Kernel", dtype=bool, default=False, ) nEigenComponents = pexConfig.Field( doc="number of eigen components for PSF kernel creation", dtype=int, default=4, ) spatialOrder = pexConfig.Field( doc="specify spatial order for PSF kernel creation", dtype=int, default=2, ) sizeCellX = pexConfig.Field( doc="size of cell used to determine PSF (pixels, column direction)", dtype=int, default=256, # minValue = 10, check=lambda x: x >= 10, ) sizeCellY = pexConfig.Field( doc="size of cell used to determine PSF (pixels, row direction)", dtype=int, default=sizeCellX.default, # minValue = 10, check=lambda x: x >= 10, ) nStarPerCell = pexConfig.Field( doc="number of stars per psf cell for PSF kernel creation", dtype=int, default=3, ) kernelSize = pexConfig.Field( doc= "radius of the kernel to create, relative to the square root of the stellar quadrupole moments", dtype=float, default=10.0, ) kernelSizeMin = pexConfig.Field( doc="Minimum radius of the kernel", dtype=int, default=25, ) kernelSizeMax = pexConfig.Field( doc="Maximum radius of the kernel", dtype=int, default=45, ) borderWidth = pexConfig.Field( doc= "Number of pixels to ignore around the edge of PSF candidate postage stamps", dtype=int, default=0, ) nStarPerCellSpatialFit = pexConfig.Field( doc="number of stars per psf Cell for spatial fitting", dtype=int, default=5, ) constantWeight = pexConfig.Field( doc= "Should each PSF candidate be given the same weight, independent of magnitude?", dtype=bool, default=True, ) nIterForPsf = pexConfig.Field( doc="number of iterations of PSF candidate star list", dtype=int, default=3, ) tolerance = pexConfig.Field( doc="tolerance of spatial fitting", dtype=float, default=1e-2, ) lam = pexConfig.Field( doc="floor for variance is lam*data", dtype=float, default=0.05, ) reducedChi2ForPsfCandidates = pexConfig.Field( doc="for psf candidate evaluation", dtype=float, default=2.0, ) spatialReject = pexConfig.Field( doc="Rejection threshold (stdev) for candidates based on spatial fit", dtype=float, default=3.0, ) pixelThreshold = pexConfig.Field( doc= "Threshold (stdev) for rejecting extraneous pixels around candidate; applied if positive", dtype=float, default=0.0, ) doRejectBlends = pexConfig.Field( doc="Reject candidates that are blended?", dtype=bool, default=False, ) doMaskBlends = pexConfig.Field( doc="Mask blends in image?", dtype=bool, default=True, )
class EmulateHscCoaddConfig(CoaddBaseTask.ConfigClass): """Config for EmulateHscCoaddTask """ # input image, mask (optional) and variance fits files imgInName = pexConfig.Field("Name of input image", str, "") mskInName = pexConfig.Field("Name of input mask", str, "") varInName = pexConfig.Field("Name of input variance image", str, "") # if input is a weight image, it will take the inverse weight = pexConfig.Field("Set if variance file is weight", bool, False) # used for tests only test = pexConfig.Field("Output", bool, False) # mag zero point of the input data image mag0 = pexConfig.Field("Magnitude zero point", float, 27.0) # used for the PSF measurement magLim = pexConfig.Field("Magnitude faint limit for PSF measurement", float, 23.0) # used for the PSF measurement charImage_package = pexConfig.Field( "Package to load the charImage config from (default: obs_subaru)", str, "obs_subaru") # config for the tasks we will call to get PSF and aperture corrections charImage = pexConfig.ConfigurableField( target=CharacterizeImageTask, doc="""Task to characterize a science exposure: - detect sources, usually at high S/N - estimate the background, which is subtracted from the image and returned as field "background" - estimate a PSF model, which is added to the exposure - interpolate over defects and cosmic rays, updating the image, variance and mask planes """, ) # this is not currently used, but we configure it so that we can call # the processCcd config directly calibrate = pexConfig.ConfigurableField( target=CalibrateTask, doc="""Task to perform astrometric and photometric calibration: - refine the WCS in the exposure - refine the Calib photometric calibration object in the exposure - detect sources, usually at low S/N """, ) # bright mask stuff doMaskBrightObjects = pexConfig.Field( dtype=bool, default=True, doc="Set mask and flag bits for bright objects?") brightObjectMaskName = pexConfig.Field( dtype=str, default="BRIGHT_OBJECT", doc="Name of mask bit used for bright objects") # no longer used #initialPsf = pexConfig.ConfigField( # dtype=InitialPsfConfig, doc=InitialPsfConfig.__doc__) #detection = pexConfig.ConfigurableField( # target=measAlg.SourceDetectionTask, # doc="Initial (high-threshold) detection phase for calibration", #) #measurement = pexConfig.ConfigurableField( # target=measBase.SingleFrameMeasurementTask, # doc="Initial measurements used to feed PSF determination and aperture correction determination", #) # measurePsf = pexConfig.ConfigurableField(target = MeasurePsfTask, doc = "") # # N.b. These configuration options only set the bitplane config.brightObjectMaskName # To make this useful you *must* also configure the flags.pixel algorithm, for example # by adding # config.measurement.plugins["base_PixelFlags"].masksFpCenter.append("BRIGHT_OBJECT") # config.measurement.plugins["base_PixelFlags"].masksFpAnywhere.append("BRIGHT_OBJECT") # to your measureCoaddSources.py and forcedPhotCoadd.py config overrides # def setDefaults(self): pexConfig.Config.setDefaults(self) fluxMag0 = pow(10.0, +0.4 * self.mag0) """ self.measurePsf.starSelector['objectSize'].sourceFluxField = \ "base_PsfFlux_flux" self.measurePsf.starSelector['objectSize'].fluxMin = \ fluxMag0 * pow(10.0, -0.4*self.magLim) """ # self.charImage.measurement.plugins.names.add("ext_convolved_ConvolvedFlux") # load processCcd config from lsst.utils import getPackageDir configDir = os.path.join(getPackageDir(self.charImage_package), "config") self.load(os.path.join(configDir, "processCcd.py")) # we don't perform any calibration self.calibrate.photoCal.applyColorTerms = False self.charImage.measurePsf.starSelector['objectSize'].fluxMin = \ fluxMag0 * pow(10.0, -0.4*self.magLim) self.doUndeblended(self.charImage, "base_PsfFlux") self.doUndeblended(self.charImage, "ext_photometryKron_KronFlux") # No aperture correction for circular apertures self.doUndeblended(self.charImage, "base_CircularApertureFlux", []) self.doUndeblended( self.charImage, "ext_convolved_ConvolvedFlux", self.charImage.measurement.plugins["ext_convolved_ConvolvedFlux"]. getAllResultNames()) # Disable registration for apCorr of undeblended convolved; apCorr will be done through the deblended proxy self.charImage.measurement.undeblended[ "ext_convolved_ConvolvedFlux"].registerForApCorr = False # no longer used # self.detection.includeThresholdMultiplier = 10.0 # self.detection.doFootprintBackground = False # self.measurePsf.reserve.fraction = 0.0 # self.measurePsf.reserve.fraction = 0.2 def doUndeblended(self, config, algName, fluxList=None): """Activate undeblended measurements of algorithm Parameters ---------- algName : `str` Algorithm name. fluxList : `list` of `str`, or `None` List of flux columns to register for aperture correction. If `None`, then this will be the `algName` appended with `_flux`. taken from [...]/obs_subaru/6.6.1-hsc+1/config/processCcd.py """ if algName not in config.measurement.plugins: return if fluxList is None: fluxList = [algName + "_flux"] config.measurement.undeblended.names.add(algName) config.measurement.undeblended[algName] = config.measurement.plugins[ algName] for flux in fluxList: config.applyApCorr.proxies["undeblended_" + flux] = flux