LSSTApplications  10.0-2-g4f67435,11.0.rc2+1,11.0.rc2+12,11.0.rc2+3,11.0.rc2+4,11.0.rc2+5,11.0.rc2+6,11.0.rc2+7,11.0.rc2+8
LSSTDataManagementBasePackage
calibrate.py
Go to the documentation of this file.
1 #
2 # LSST Data Management System
3 # Copyright 2008, 2009, 2010, 2011 LSST Corporation.
4 #
5 # This product includes software developed by the
6 # LSST Project (http://www.lsst.org/).
7 #
8 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
12 #
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
17 #
18 # You should have received a copy of the LSST License Statement and
19 # the GNU General Public License along with this program. If not,
20 # see <http://www.lsstcorp.org/LegalNotices/>.
21 #
22 import math
23 
24 import lsst.daf.base as dafBase
25 import lsst.pex.config as pexConfig
26 import lsst.afw.math as afwMath
27 import lsst.afw.table as afwTable
28 import lsst.meas.algorithms as measAlg
29 import lsst.pipe.base as pipeBase
30 from lsst.meas.base import BasePlugin, SingleFrameMeasurementTask, MeasureApCorrTask
31 from lsst.meas.astrom import AstrometryTask
32 from .photoCal import PhotoCalTask
33 from .repair import RepairTask
34 from .measurePsf import MeasurePsfTask
35 
36 class InitialPsfConfig(pexConfig.Config):
37  """!Describes the initial PSF used for detection and measurement before we do PSF determination."""
38 
39  model = pexConfig.ChoiceField(
40  dtype = str,
41  doc = "PSF model type",
42  default = "SingleGaussian",
43  allowed = {
44  "SingleGaussian": "Single Gaussian model",
45  "DoubleGaussian": "Double Gaussian model",
46  },
47  )
48  pixelScale = pexConfig.Field(
49  dtype = float,
50  doc = "Pixel size (arcsec). Only needed if no Wcs is provided",
51  default = 0.25,
52  )
53  fwhm = pexConfig.Field(
54  dtype = float,
55  doc = "FWHM of PSF model (arcsec)",
56  default = 1.0,
57  )
58  size = pexConfig.Field(
59  dtype = int,
60  doc = "Size of PSF model (pixels)",
61  default = 15,
62  )
63 
64 class CalibrateConfig(pexConfig.Config):
65  initialPsf = pexConfig.ConfigField(dtype=InitialPsfConfig, doc=InitialPsfConfig.__doc__)
66  doBackground = pexConfig.Field(
67  dtype = bool,
68  doc = "Subtract background (after computing it, if not supplied)?",
69  default = True,
70  )
71  doPsf = pexConfig.Field(
72  dtype = bool,
73  doc = "Perform PSF fitting?",
74  default = True,
75  )
76  doMeasureApCorr = pexConfig.Field(
77  dtype = bool,
78  doc = "Compute aperture corrections?",
79  default = True,
80  )
81  doAstrometry = pexConfig.Field(
82  dtype = bool,
83  doc = "Compute astrometric solution?",
84  default = True,
85  )
86  doPhotoCal = pexConfig.Field(
87  dtype = bool,
88  doc = "Compute photometric zeropoint?",
89  default = True,
90  )
91  background = pexConfig.ConfigField(
92  dtype = measAlg.estimateBackground.ConfigClass,
93  doc = "Background estimation configuration"
94  )
95  repair = pexConfig.ConfigurableField(
96  target = RepairTask,
97  doc = "Interpolate over defects and cosmic rays",
98  )
99  detection = pexConfig.ConfigurableField(
100  target = measAlg.SourceDetectionTask,
101  doc = "Initial (high-threshold) detection phase for calibration",
102  )
103  initialMeasurement = pexConfig.ConfigurableField(
104  target = SingleFrameMeasurementTask,
105  doc = "Initial measurements used to feed PSF determination and aperture correction determination",
106  )
107  measurePsf = pexConfig.ConfigurableField(
108  target = MeasurePsfTask,
109  doc = "Measure PSF",
110  )
111  measurement = pexConfig.ConfigurableField(
112  target = SingleFrameMeasurementTask,
113  doc = "Post-PSF-determination measurements used to feed other calibrations",
114  )
115  measureApCorr = pexConfig.ConfigurableField(
116  target = MeasureApCorrTask,
117  doc = "subtask to measure aperture corrections"
118  )
119  astrometry = pexConfig.ConfigurableField(
120  target = AstrometryTask,
121  doc = "fit WCS of exposure",
122  )
123  photocal = pexConfig.ConfigurableField(
124  target = PhotoCalTask,
125  doc = "peform photometric calibration",
126  )
127 
128  def validate(self):
129  pexConfig.Config.validate(self)
130  if self.doPhotoCal and not self.doAstrometry:
131  raise ValueError("Cannot do photometric calibration without doing astrometric matching")
132  if self.doMeasureApCorr and self.measureApCorr.inputFilterFlag == "calib_psfUsed" and not self.doPsf:
133  raise ValueError("Cannot measure aperture correction with inputFilterFlag=calib_psfUsed"
134  " unless doPsf is also True")
135  if self.measurement.doApplyApCorr.startswith("yes") and not self.doMeasureApCorr:
136  raise ValueError("Cannot set measurement.doApplyApCorr to 'yes...'"
137  " unless doMeasureApCorr is True")
138 
139  def setDefaults(self):
140  self.detection.includeThresholdMultiplier = 10.0
141  self.initialMeasurement.algorithms.names -= ["base_ClassificationExtendedness"]
142  self.initialMeasurement.doApplyApCorr = "no" # no aperture correction data yet
143  self.measurement.doApplyApCorr = "yes"
144  initflags = [x for x in self.measurePsf.starSelector["catalog"].badStarPixelFlags]
145  self.measurePsf.starSelector["catalog"].badStarPixelFlags.extend(initflags)
146  self.background.binSize = 1024
147 
148 ## \addtogroup LSST_task_documentation
149 ## \{
150 ## \page CalibrateTask
151 ## \ref CalibrateTask_ "CalibrateTask"
152 ## \copybrief CalibrateTask
153 ## \}
154 
155 class CalibrateTask(pipeBase.Task):
156  """!
157 \anchor CalibrateTask_
158 
159 \brief Calibrate an exposure: measure PSF, subtract background, measure astrometry and photometry
160 
161 \section pipe_tasks_calibrate_Contents Contents
162 
163  - \ref pipe_tasks_calibrate_Purpose
164  - \ref pipe_tasks_calibrate_Initialize
165  - \ref pipe_tasks_calibrate_IO
166  - \ref pipe_tasks_calibrate_Config
167  - \ref pipe_tasks_calibrate_Metadata
168  - \ref pipe_tasks_calibrate_Debug
169  - \ref pipe_tasks_calibrate_Example
170 
171 \section pipe_tasks_calibrate_Purpose Description
172 
173 \copybrief CalibrateTask
174 
175 Calculate an Exposure's zero-point given a set of flux measurements of stars matched to an input catalogue.
176 The type of flux to use is specified by CalibrateConfig.fluxField.
177 
178 The algorithm clips outliers iteratively, with parameters set in the configuration.
179 
180 \note This task can adds fields to the schema, so any code calling this task must ensure that
181 these columns are indeed present in the input match list; see \ref pipe_tasks_calibrate_Example
182 
183 \section pipe_tasks_calibrate_Initialize Task initialisation
184 
185 \copydoc \_\_init\_\_
186 
187 CalibrateTask delegates most of its work to a set of sub-Tasks:
188 <DL>
189 <DT> repair \ref RepairTask_ "RepairTask"
190 <DD> Interpolate over defects such as bad columns and cosmic rays. This task is called twice; once
191 before the %measurePsf step and again after the PSF has been measured.
192 <DT> detection \ref SourceDetectionTask_ "SourceDetectionTask"
193 <DD> Initial (high-threshold) detection phase for calibration
194 <DT> initialMeasurement \ref SingleFrameMeasurementTask_ "SingleFrameMeasurementTask"
195 <DD> Make the initial measurements used to feed PSF determination and aperture correction determination
196 <DT> astrometry \ref AstrometryTask_ "AstrometryTask"
197 <DD> Solve the astrometry. May be disabled by setting CalibrateTaskConfig.doAstrometry to be False.
198 This task is called twice; once before the %measurePsf step and again after the PSF has been measured.
199 <DT> %measurePsf \ref MeasurePsfTask_ "MeasurePsfTask"
200 <DD> Estimate the PSF. May be disabled by setting CalibrateTaskConfig.doPsf to be False. If requested
201 the astrometry is solved before this is called, so if you disable the astrometry the %measurePsf
202 task won't have access to objects positions.
203 <DT> measurement \ref SingleFrameMeasurementTask_ "SingleFrameMeasurementTask"
204 <DD> Post-PSF-determination measurements used to feed other calibrations
205 <DT> photocal \ref PhotoCalTask_ "PhotoCalTask"
206 <DD> Solve for the photometric zeropoint.
207 May be disabled by setting CalibrateTaskConfig.doPhotoCal to be False.
208 \em N.b. Requires that \c astrometry was successfully run.
209 </DL>
210 
211 You can replace any of these subtasks if you wish, see \ref calibrate_MyAstrometryTask.
212 \note These task APIs are not well controlled, so replacing a task is a matter of matching
213 a poorly specified interface. We will be working on this over the first year of construction.
214 
215 \section pipe_tasks_calibrate_IO Invoking the Task
216 
217 \copydoc run
218 
219 \section pipe_tasks_calibrate_Config Configuration parameters
220 
221 See \ref CalibrateConfig
222 
223 #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
224 
225 \section pipe_tasks_calibrate_Metadata Quantities set in Metadata
226 
227 <DL>
228 <DT>Task metadata
229 <DD>
230 <DL>
231 <DT> MAGZERO <DD> Measured zeropoint (DN per second)
232 </DL>
233 
234 <DT> Exposure metadata
235 <DD>
236 <DL>
237 <DT> MAGZERO_RMS <DD> MAGZERO's RMS == return.sigma
238 <DT> MAGZERO_NOBJ <DD> Number of stars used == return.ngood
239 <DT> COLORTERM1 <DD> ?? (always 0.0)
240 <DT> COLORTERM2 <DD> ?? (always 0.0)
241 <DT> COLORTERM3 <DD> ?? (always 0.0)
242 </DL>
243 </DL>
244 
245 #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
246 
247 \section pipe_tasks_calibrate_Debug Debug variables
248 
249 The \link lsst.pipe.base.cmdLineTask.CmdLineTask command line task\endlink interface supports a
250 flag \c -d to import \b debug.py from your \c PYTHONPATH; see \ref baseDebug for more about \b debug.py files.
251 
252 The calibrate task has a debug dictionary with keys which correspond to stages of the CalibrationTask
253 processing:
254 <DL>
255 <DT>repair
256 <DD> Fixed defects and masked cosmic rays with a guessed PSF. Action: show the exposure.
257 <DT>background
258 <DD> Subtracted background (no sources masked). Action: show the exposure
259 <DT>PSF_repair
260 <DD> Fixed defects and removed cosmic rays with an estimated PSF. Action: show the exposure
261 <DT>PSF_background
262 <DD> Subtracted background (calibration sources masked). Action: show the exposure
263 <DT>calibrate
264 <DD> Just before astro/photo calibration. Action: show the exposure, and
265  - sources as smallish green o
266  - matches (if exposure has a Wcs).
267  - catalog position as a largish yellow +
268  - source position as a largish red x
269 </DL>
270 The values are the \c ds9 frame to display in (if >= 1); if <= 0, nothing's displayed.
271 There's an example \ref pipe_tasks_calibrate_Debug_example "here".
272 
273 Some subtasks may also have their own debug information; see individual Task documentation.
274 
275 \section pipe_tasks_calibrate_Example A complete example of using CalibrateTask
276 
277 This code is in \link calibrateTask.py\endlink in the examples directory, and can be run as \em e.g.
278 \code
279 examples/calibrateTask.py --ds9
280 \endcode
281 \dontinclude calibrateTask.py
282 
283 Import the task (there are some other standard imports; read the file if you're curious)
284 \skipline CalibrateTask
285 
286 Create the detection task
287 \skip CalibrateTask.ConfigClass
288 \until config=config
289 Note that we're using a custom AstrometryTask (because we don't have a valid astrometric catalogue handy);
290 see \ref calibrate_MyAstrometryTask.
291 
292 We're now ready to process the data (we could loop over multiple exposures/catalogues using the same
293 task objects) and unpack the results
294 \skip loadData
295 \until sources
296 
297 We then might plot the results (\em e.g. if you set \c --ds9 on the command line)
298 \skip display
299 \until dot
300 
301 \subsection calibrate_MyAstrometryTask Using a Custom Astrometry Task
302 
303 The first thing to do is define my own task:
304 \dontinclude calibrateTask.py
305 \skip MyAstrometryTask
306 \skip MyAstrometryTask
307 \until super
308 
309 Then we need our own \c run method. First unpack the filtername and wcs
310 \skip run
311 \until wcs
312 Then build a "reference catalog" by shamelessly copying the catalog of detected sources
313 \skip schema
314 \until get("photometric")
315 (you need to set "flux" as well as \c filterName due to a bug in the photometric calibration code;
316 <A HREF=https://jira.lsstcorp.org/browse/DM-933>DM-933</A>).
317 
318 Then "match" by zipping up the two catalogs,
319 \skip matches
320 \until append
321 and finally return the desired results.
322 \skip return
323 \until )
324 
325 <HR>
326 \anchor pipe_tasks_calibrate_Debug_example
327 To investigate the \ref pipe_tasks_calibrate_Debug, put something like
328 \code{.py}
329  import lsstDebug
330  def DebugInfo(name):
331  di = lsstDebug.getInfo(name) # N.b. lsstDebug.Info(name) would call us recursively
332  if name == "lsst.pipe.tasks.calibrate":
333  di.display = dict(
334  repair = 1,
335  calibrate = 2,
336  )
337 
338  return di
339 
340  lsstDebug.Info = DebugInfo
341 \endcode
342 into your debug.py file and run calibrateTask.py with the \c --debug flag.
343  """
344  ConfigClass = CalibrateConfig
345  _DefaultName = "calibrate"
346 
347  def __init__(self, **kwargs):
348  """!
349  Create the calibration task
350 
351  \param **kwargs keyword arguments to be passed to lsst.pipe.base.task.Task.__init__
352  """
353  pipeBase.Task.__init__(self, **kwargs)
354 
355  # the calibrate Source Catalog is divided into two catalogs to allow measurement to be run twice
356  # schema1 contains everything except what is added by the second measurement task.
357  # Before the second measurement task is run, self.schemaMapper transforms the sources into
358  # the final output schema, at the same time renaming the measurement fields to "initial_"
359  self.schema1 = afwTable.SourceTable.makeMinimalSchema()
361  self.makeSubtask("repair")
362  self.makeSubtask("detection", schema=self.schema1)
363  beginInitial = self.schema1.getFieldCount()
364  self.makeSubtask("initialMeasurement", schema=self.schema1, algMetadata=self.algMetadata)
365  endInitial = self.schema1.getFieldCount()
366 
367  # create subtasks that are run with schema1 (and possibly also the final schema)
368  self.makeSubtask("measurePsf", schema=self.schema1)
369  self.makeSubtask("astrometry", schema=self.schema1)
370 
371  # create a schemaMapper to map schema1 into the final schema
373  separator = "_"
374  count = 0
375  for item in self.schema1:
376  count = count + 1
377  field = item.getField()
378  name = field.getName()
379  if count > beginInitial and count <= endInitial:
380  name = "initial" + separator + name
381  self.schemaMapper.addMapping(item.key, name)
382 
383  # create subtasks that are run only with the final schema
384  schema = self.schemaMapper.editOutputSchema()
385  self.makeSubtask("measurement", schema=schema, algMetadata=self.algMetadata)
386  self.makeSubtask("measureApCorr", schema=schema)
387  self.makeSubtask("photocal", schema=schema)
388 
389  # the final schema is the same as the schemaMapper output
390  self.schema = self.schemaMapper.getOutputSchema()
391 
392  def getCalibKeys(self):
393  """!
394  Return a sequence of schema keys that represent fields that should be propagated from
395  icSrc to src by ProcessCcdTask.
396  """
397  if self.config.doPsf:
398  return (self.measurePsf.candidateKey, self.measurePsf.usedKey)
399  else:
400  return ()
401 
402  @pipeBase.timeMethod
403  def run(self, exposure, defects=None, idFactory=None):
404  """!Run the calibration task on an exposure
405 
406  \param[in,out] exposure Exposure to calibrate; measured PSF will be installed there as well
407  \param[in] defects List of defects on exposure
408  \param[in] idFactory afw.table.IdFactory to use for source catalog.
409  \return a pipeBase.Struct with fields:
410  - exposure: Repaired exposure
411  - backgrounds: A list of background models applied in the calibration phase
412  - psf: Point spread function
413  - sources: Sources used in calibration
414  - matches: A list of reference object/source matches (an lsst.afw.table.ReferenceMatchVector)
415  - matchMeta: Metadata about the field (an lsst.daf.base.PropertyList)
416  - photocal: Output of photocal subtask
417 
418  It is moderately important to provide a decent initial guess for the seeing if you want to
419  deal with cosmic rays. If there's a PSF in the exposure it'll be used; failing that the
420  CalibrateConfig.initialPsf is consulted (although the pixel scale will be taken from the
421  WCS if available).
422 
423  If the exposure contains an lsst.afw.image.Calib object with the exposure time set, MAGZERO
424  will be set in the task metadata.
425  """
426  assert exposure is not None, "No exposure provided"
427 
428  if not exposure.hasPsf():
429  self.installInitialPsf(exposure)
430  if idFactory is None:
431  idFactory = afwTable.IdFactory.makeSimple()
432  backgrounds = afwMath.BackgroundList()
433  keepCRs = True # At least until we know the PSF
434  self.repair.run(exposure, defects=defects, keepCRs=keepCRs)
435  self.display('repair', exposure=exposure)
436 
437  if self.config.doBackground:
438  with self.timer("background"):
439  bg, exposure = measAlg.estimateBackground(exposure, self.config.background, subtract=True)
440  backgrounds.append(bg)
441  self.display('background', exposure=exposure)
442 
443  # Make both tables from the same detRet, since detection can only be run once
444  table1 = afwTable.SourceTable.make(self.schema1, idFactory)
445  table1.setMetadata(self.algMetadata)
446  detRet = self.detection.makeSourceCatalog(table1, exposure)
447  sources1 = detRet.sources
448  if detRet.fpSets.background:
449  backgrounds.append(detRet.fpSets.background)
450 
451  # do the initial measurement. This is normally done for star selection, but do it
452  # even if the psf is not going to be calculated for consistency
453  self.initialMeasurement.run(exposure, sources1, allowApCorr=False)
454 
455  if self.config.doPsf:
456  if self.config.doAstrometry:
457  astromRet = self.astrometry.run(exposure, sources1)
458  matches = astromRet.matches
459  else:
460  # If doAstrometry is False, we force the Star Selector to either make them itself
461  # or hope it doesn't need them.
462  matches = None
463  psfRet = self.measurePsf.run(exposure, sources1, matches=matches)
464  psf = psfRet.psf
465  elif exposure.hasPsf():
466  psf = exposure.getPsf()
467  else:
468  psf = None
469 
470  # Wash, rinse, repeat with proper PSF
471 
472  if self.config.doPsf:
473  self.repair.run(exposure, defects=defects, keepCRs=None)
474  self.display('PSF_repair', exposure=exposure)
475 
476  if self.config.doBackground:
477  # Background estimation ignores (by default) pixels with the
478  # DETECTED bit set, so now we re-estimate the background,
479  # ignoring sources. (see BackgroundConfig.ignoredPixelMask)
480  with self.timer("background"):
481  # Subtract background
482  bg, exposure = measAlg.estimateBackground(
483  exposure, self.config.background, subtract=True,
484  statsKeys=('BGMEAN2', 'BGVAR2'))
485  self.log.info("Fit and subtracted background")
486  backgrounds.append(bg)
487 
488  self.display('PSF_background', exposure=exposure)
489 
490  # make a second table with which to do the second measurement
491  # the schemaMapper will copy the footprints and ids, which is all we need.
492  table2 = afwTable.SourceTable.make(self.schema, idFactory)
493  table2.setMetadata(self.algMetadata)
494  sources = afwTable.SourceCatalog(table2)
495  # transfer to a second table -- note that the slots do not have to be reset here
496  # as long as measurement.run follows immediately
497  sources.extend(sources1, self.schemaMapper)
498 
499  if self.config.doMeasureApCorr:
500  # Run measurement through all flux measurements (all have the same execution order),
501  # then apply aperture corrections, then run the rest of the measurements
502  self.measurement.run(exposure, sources, endOrder=BasePlugin.APCORR_ORDER)
503  apCorrMap = self.measureApCorr.run(bbox=exposure.getBBox(), catalog=sources).apCorrMap
504  exposure.getInfo().setApCorrMap(apCorrMap)
505  self.measurement.run(exposure, sources, beginOrder=BasePlugin.APCORR_ORDER)
506  else:
507  self.measurement.run(exposure, sources)
508 
509  if self.config.doAstrometry:
510  astromRet = self.astrometry.run(exposure, sources)
511  matches = astromRet.matches
512  matchMeta = astromRet.matchMeta
513  else:
514  matches, matchMeta = None, None
515 
516  if self.config.doPhotoCal:
517  assert(matches is not None)
518  try:
519  photocalRet = self.photocal.run(exposure, matches)
520  except Exception, e:
521  self.log.warn("Failed to determine photometric zero-point: %s" % e)
522  photocalRet = None
523  self.metadata.set('MAGZERO', float("NaN"))
524 
525  if photocalRet:
526  self.log.info("Photometric zero-point: %f" % photocalRet.calib.getMagnitude(1.0))
527  exposure.getCalib().setFluxMag0(photocalRet.calib.getFluxMag0())
528  metadata = exposure.getMetadata()
529  # convert to (mag/sec/adu) for metadata
530  try:
531  magZero = photocalRet.zp - 2.5 * math.log10(exposure.getCalib().getExptime() )
532  metadata.set('MAGZERO', magZero)
533  except:
534  self.log.warn("Could not set normalized MAGZERO in header: no exposure time")
535  metadata.set('MAGZERO_RMS', photocalRet.sigma)
536  metadata.set('MAGZERO_NOBJ', photocalRet.ngood)
537  metadata.set('COLORTERM1', 0.0)
538  metadata.set('COLORTERM2', 0.0)
539  metadata.set('COLORTERM3', 0.0)
540  else:
541  photocalRet = None
542  self.display('calibrate', exposure=exposure, sources=sources, matches=matches)
543 
544  return pipeBase.Struct(
545  exposure = exposure,
546  backgrounds = backgrounds,
547  psf = psf,
548  sources = sources,
549  matches = matches,
550  matchMeta = matchMeta,
551  photocal = photocalRet,
552  )
553 
554  def installInitialPsf(self, exposure):
555  """!Initialise the calibration procedure by setting the PSF to a configuration-defined guess.
556 
557  \param[in,out] exposure Exposure to process; fake PSF will be installed here.
558  \throws AssertionError If exposure or exposure.getWcs() are None
559  """
560  assert exposure, "No exposure provided"
561 
562  wcs = exposure.getWcs()
563  if wcs:
564  pixelScale = wcs.pixelScale().asArcseconds()
565  else:
566  pixelScale = self.config.initialPsf.pixelScale
567 
568  cls = getattr(measAlg, self.config.initialPsf.model + "Psf")
569 
570  fwhm = self.config.initialPsf.fwhm/pixelScale
571  size = self.config.initialPsf.size
572  self.log.info("installInitialPsf fwhm=%s pixels; size=%s pixels" % (fwhm, size))
573  psf = cls(size, size, fwhm/(2*math.sqrt(2*math.log(2))))
574  exposure.setPsf(psf)
def __init__
Create the calibration task.
Definition: calibrate.py:347
def getCalibKeys
Return a sequence of schema keys that represent fields that should be propagated from icSrc to src by...
Definition: calibrate.py:392
Class for storing ordered metadata with comments.
Definition: PropertyList.h:81
A mapping between the keys of two Schemas, used to copy data between them.
Definition: SchemaMapper.h:19
Describes the initial PSF used for detection and measurement before we do PSF determination.
Definition: calibrate.py:36
def installInitialPsf
Initialise the calibration procedure by setting the PSF to a configuration-defined guess...
Definition: calibrate.py:554
Custom catalog class for record/table subclasses that are guaranteed to have an ID, and should generally be sorted by that ID.
Definition: fwd.h:55
def run
Run the calibration task on an exposure.
Definition: calibrate.py:403
Calibrate an exposure: measure PSF, subtract background, measure astrometry and photometry.
Definition: calibrate.py:155