LSSTApplications  10.0+286,10.0+36,10.0+46,10.0-2-g4f67435,10.1+152,10.1+37,11.0,11.0+1,11.0-1-g47edd16,11.0-1-g60db491,11.0-1-g7418c06,11.0-2-g04d2804,11.0-2-g68503cd,11.0-2-g818369d,11.0-2-gb8b8ce7
LSSTDataManagementBasePackage
forcedPhotCcd.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 #
3 # LSST Data Management System
4 # Copyright 2008, 2009, 2010, 2014 LSST Corporation.
5 #
6 # This product includes software developed by the
7 # LSST Project (http://www.lsst.org/).
8 #
9 # This program is free software: you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation, either version 3 of the License, or
12 # (at your option) any later version.
13 #
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
18 #
19 # You should have received a copy of the LSST License Statement and
20 # the GNU General Public License along with this program. If not,
21 # see <http://www.lsstcorp.org/LegalNotices/>.
22 #
23 
24 import argparse
25 
26 import lsst.pex.config
27 import lsst.pipe.base
28 import lsst.afw.image
29 import lsst.afw.table
30 
31 from .forcedPhotImage import ProcessImageForcedTask, ProcessImageForcedConfig
32 
33 try:
34  from lsst.meas.mosaic import applyMosaicResults
35 except ImportError:
36  applyMosaicResults = None
37 
38 __all__ = ("ForcedPhotCcdConfig", "ForcedPhotCcdTask")
39 
40 class ForcedPhotCcdDataIdContainer(lsst.pipe.base.DataIdContainer):
41  """A version of DataIdContainer specialized for forced photometry on CCDs.
42 
43  Required because we need to add "tract" to the raw data ID keys, and that's tricky.
44  This IdContainer assumes that a calexp is being measured using the detection information
45  from the set of coadds which intersect with the calexp. a set of reference catalog
46  from a coadd which overlaps it. It needs the calexp id (e.g. visit, raft, sensor), but it
47  also uses the tract to decide what set of coadds to use. The references from the tract
48  whose patches intersect with the calexp are used.
49  """
50  def makeDataRefList(self, namespace):
51  """Make self.refList from self.idList
52  """
53  for dataId in self.idList:
54  if "tract" not in dataId:
55  raise argparse.ArgumentError(None, "--id must include tract")
56  tract = dataId.pop("tract")
57  # making a DataRef for src fills out any missing keys and allows us to iterate
58  for srcDataRef in namespace.butler.subset("src", dataId=dataId):
59  forcedDataId = srcDataRef.dataId.copy()
60  forcedDataId['tract'] = tract
61  dataRef = namespace.butler.dataRef(
62  datasetType = "forced_src",
63  dataId = forcedDataId,
64  )
65  self.refList.append(dataRef)
66 
67 class ForcedPhotCcdConfig(ProcessImageForcedConfig):
68  doApplyUberCal = lsst.pex.config.Field(
69  dtype = bool,
70  doc = "Apply meas_mosaic ubercal results to input calexps?",
71  default = False
72  )
73 
74 ## @addtogroup LSST_task_documentation
75 ## @{
76 ## @page processForcedCcdTask
77 ## ForcedPhotCcdTask
78 ## @copybrief ForcedPhotCcdTask
79 ## @}
80 
81 class ForcedPhotCcdTask(ProcessImageForcedTask):
82  """!
83  A command-line driver for performing forced measurement on CCD images
84 
85  This task is a subclass of ForcedPhotImageTask which is specifically for doing forced
86  measurement on a single CCD exposure, using as a reference catalog the detections which
87  were made on overlapping coadds.
88 
89  The run method (inherited from ForcedPhotImageTask) takes a lsst.daf.persistence.ButlerDataRef
90  argument that corresponds to a single CCD. This should contain the data ID keys that correspond to
91  the "forced_src" dataset (the output dataset for ForcedPhotCcdTask), which are typically all those
92  used to specify the "calexp" dataset (e.g. visit, raft, sensor for LSST data) as well as a coadd
93  tract. The tract is used to look up the appropriate coadd measurement catalogs to use as references
94  (e.g. deepCoadd_src; see CoaddSrcReferencesTask for more information). While the tract must be given
95  as part of the dataRef, the patches are determined automatically from the bounding box and WCS of the
96  calexp to be measured, and the filter used to fetch references is set via config
97  (BaseReferencesConfig.filter).
98 
99  In addition to the run method, ForcedPhotCcdTask overrides several methods of ForcedPhotImageTask
100  to specialize it for single-CCD processing, including makeIdFactory(), fetchReferences(), and
101  getExposure(). None of these should be called directly by the user, though it may be useful
102  to override them further in subclasses.
103  """
104 
105  ConfigClass = ForcedPhotCcdConfig
106  RunnerClass = lsst.pipe.base.ButlerInitializedTaskRunner
107  _DefaultName = "forcedPhotCcd"
108  dataPrefix = ""
109 
110  def makeIdFactory(self, dataRef):
111  """Create an object that generates globally unique source IDs from per-CCD IDs and the CCD ID.
112 
113  @param dataRef Data reference from butler. The "ccdExposureId_bits" and "ccdExposureId"
114  datasets are accessed. The data ID must have the keys that correspond
115  to ccdExposureId, which is generally the same that correspond to "calexp"
116  (e.g. visit, raft, sensor for LSST data).
117  """
118  expBits = dataRef.get("ccdExposureId_bits")
119  expId = long(dataRef.get("ccdExposureId"))
120  return lsst.afw.table.IdFactory.makeSource(expId, 64 - expBits)
121 
122  def fetchReferences(self, dataRef, exposure):
123  """Return a SourceCatalog of sources which overlap the exposure.
124 
125  The returned catalog is sorted by ID and guarantees that all included children have their
126  parent included and that all Footprints are valid.
127 
128  @param dataRef Data reference from butler corresponding to the image to be measured;
129  should have tract, patch, and filter keys.
130  @param exposure lsst.afw.image.Exposure to be measured (used only to obtain a Wcs and
131  bounding box).
132 
133  All work is delegated to the references subtask; see CoaddSrcReferencesTask for information
134  about the default behavior.
135  """
136  references = lsst.afw.table.SourceCatalog(self.references.schema)
137  badParents = set()
138  unfiltered = self.references.fetchInBox(dataRef, exposure.getBBox(), exposure.getWcs())
139  for record in unfiltered:
140  if record.getFootprint() is None or record.getFootprint().getArea() == 0:
141  if record.getParent() != 0:
142  self.log.warn("Skipping reference %s (child of %s) with bad Footprint" %
143  (record.getId(), record.getParent()))
144  else:
145  self.log.warn("Skipping reference parent %s with bad Footprint" % (record.getId(),))
146  badParents.add(record.getId())
147  elif record.getParent() not in badParents:
148  references.append(record)
149  references.sort() # need to ensure catalog is in ID order so find methods work
150  return references
151 
152  def getExposure(self, dataRef):
153  """Read input exposure to measure
154 
155  @param dataRef Data reference from butler. Only the 'calexp' dataset is used,
156  unless config.doApplyUberCal is true, in which case the corresponding
157  meas_mosaic outputs are used as well.
158  """
159  exposure = ProcessImageForcedTask.getExposure(self, dataRef)
160  if not self.config.doApplyUberCal:
161  return exposure
162  if applyMosaicResults is None:
163  raise RuntimeError(
164  "Cannot use improved calibrations for %s because meas_mosaic could not be imported."
165  % dataRef.dataId
166  )
167  else:
168  applyMosaicResults(dataRef, calexp=exposure)
169  return exposure
170 
171  def _getConfigName(self):
172  """!Return the name of the config dataset. Forces config comparison from run-to-run
173  """
174  return self.dataPrefix + "forcedPhotCcd_config"
175 
176  def _getMetadataName(self):
177  """!Return the name of the metadata dataset. Forced metadata to be saved
178  """
179  return self.dataPrefix + "forcedPhotCcd_metadata"
180 
181  @classmethod
183  parser = lsst.pipe.base.ArgumentParser(name=cls._DefaultName)
184  parser.add_id_argument("--id", "forced_src", help="data ID, with raw CCD keys + tract",
185  ContainerClass=ForcedPhotCcdDataIdContainer)
186  return parser
187 
188 
static boost::shared_ptr< IdFactory > makeSource(RecordId expId, int reserved)
Return an IdFactory that includes another, fixed ID in the higher-order bits.
A command-line driver for performing forced measurement on CCD images.
def _getConfigName
Return the name of the config dataset.
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 _getMetadataName
Return the name of the metadata dataset.