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
Public Member Functions | Static Public Attributes | List of all members
lsst.pipe.tasks.registerImage.RegisterTask Class Reference
Inheritance diagram for lsst.pipe.tasks.registerImage.RegisterTask:

Public Member Functions

def run
 
def matchSources
 
def fitWcs
 
def warpExposure
 
def warpSources
 

Static Public Attributes

 ConfigClass = RegisterConfig
 

Detailed Description

Task to register (align) multiple images.

The 'run' method provides a revised Wcs from matches and fitting sources.
Additional methods are provided as a convenience to warp an exposure
('warpExposure') and sources ('warpSources') with the new Wcs.

Definition at line 50 of file registerImage.py.

Member Function Documentation

def lsst.pipe.tasks.registerImage.RegisterTask.fitWcs (   self,
  matches,
  inputWcs,
  inputBBox 
)
Fit Wcs to matches

The fitting includes iterative sigma-clipping.

@param matches: List of matches (first is target, second is input)
@param inputWcs: Original input Wcs
@param inputBBox: Bounding box of input image
@return Wcs

Definition at line 97 of file registerImage.py.

97 
98  def fitWcs(self, matches, inputWcs, inputBBox):
99  """Fit Wcs to matches
100 
101  The fitting includes iterative sigma-clipping.
102 
103  @param matches: List of matches (first is target, second is input)
104  @param inputWcs: Original input Wcs
105  @param inputBBox: Bounding box of input image
106  @return Wcs
107  """
108  copyMatches = type(matches)(matches)
109  refCoordKey = copyMatches[0].first.getTable().getCoordKey()
110  inCentroidKey = copyMatches[0].second.getTable().getCentroidKey()
111  for i in range(self.config.sipIter):
112  sipFit = makeCreateWcsWithSip(copyMatches, inputWcs, self.config.sipOrder, inputBBox)
113  self.log.logdebug("Registration WCS RMS iteration %d: %f pixels" %
114  (i, sipFit.getScatterInPixels()))
115  wcs = sipFit.getNewWcs()
116  dr = [m.first.get(refCoordKey).angularSeparation(
117  wcs.pixelToSky(m.second.get(inCentroidKey))).asArcseconds() for
118  m in copyMatches]
119  dr = numpy.array(dr)
120  rms = math.sqrt((dr*dr).mean()) # RMS from zero
121  rms = max(rms, 1.0e-9) # Don't believe any RMS smaller than this
122  self.log.logdebug("Registration iteration %d: rms=%f" % (i, rms))
123  good = numpy.where(dr < self.config.sipRej*rms)[0]
124  numBad = len(copyMatches) - len(good)
125  self.log.logdebug("Registration iteration %d: rejected %d" % (i, numBad))
126  if numBad == 0:
127  break
128  copyMatches = type(matches)(copyMatches[i] for i in good)
129 
130  sipFit = makeCreateWcsWithSip(copyMatches, inputWcs, self.config.sipOrder, inputBBox)
131  self.log.info("Registration WCS: final WCS RMS=%f pixels from %d matches" %
132  (sipFit.getScatterInPixels(), len(copyMatches)))
133  self.metadata.set("SIP_RMS", sipFit.getScatterInPixels())
134  self.metadata.set("SIP_GOOD", len(copyMatches))
135  self.metadata.set("SIP_REJECTED", len(matches) - len(copyMatches))
136  wcs = sipFit.getNewWcs()
137  return wcs
CreateWcsWithSip< MatchT > makeCreateWcsWithSip(std::vector< MatchT > const &matches, afw::image::Wcs const &linearWcs, int const order, afw::geom::Box2I const &bbox=afw::geom::Box2I(), int const ngrid=0)
Factory function for CreateWcsWithSip.
def lsst.pipe.tasks.registerImage.RegisterTask.matchSources (   self,
  inputSources,
  templateSources 
)
Match sources between the input and template

The order of the input arguments matters (because the later Wcs
fitting assumes a particular order).

@param inputSources: Source catalog of the input frame
@param templateSources: Source of the target frame
@return Match list

Definition at line 79 of file registerImage.py.

79 
80  def matchSources(self, inputSources, templateSources):
81  """Match sources between the input and template
82 
83  The order of the input arguments matters (because the later Wcs
84  fitting assumes a particular order).
85 
86  @param inputSources: Source catalog of the input frame
87  @param templateSources: Source of the target frame
88  @return Match list
89  """
90  matches = afwTable.matchRaDec(templateSources, inputSources,
91  self.config.matchRadius*afwGeom.arcseconds)
92  self.log.info("Matching within %.1f arcsec: %d matches" % (self.config.matchRadius, len(matches)))
93  self.metadata.set("MATCH_NUM", len(matches))
94  if len(matches) == 0:
95  raise RuntimeError("Unable to match source catalogs")
96  return matches
std::vector< Match< typename Cat::Record, typename Cat::Record > > matchRaDec(Cat const &cat, Angle radius, bool symmetric=true)
def lsst.pipe.tasks.registerImage.RegisterTask.run (   self,
  inputSources,
  inputWcs,
  inputBBox,
  templateSources 
)
Register (align) an input exposure to the template

The sources must have RA,Dec set, and accurate to within the
'matchRadius' of the configuration in order to facilitate source
matching.  We fit a new Wcs, but do NOT set it in the input exposure.

@param inputSources: Sources from input exposure
@param inputWcs: Wcs of input exposure
@param inputBBox: Bounding box of input exposure
@param templateSources: Sources from template exposure
@return Struct(matches: Matches between sources,
       wcs: Wcs for input in frame of template,
       )

Definition at line 60 of file registerImage.py.

60 
61  def run(self, inputSources, inputWcs, inputBBox, templateSources):
62  """Register (align) an input exposure to the template
63 
64  The sources must have RA,Dec set, and accurate to within the
65  'matchRadius' of the configuration in order to facilitate source
66  matching. We fit a new Wcs, but do NOT set it in the input exposure.
67 
68  @param inputSources: Sources from input exposure
69  @param inputWcs: Wcs of input exposure
70  @param inputBBox: Bounding box of input exposure
71  @param templateSources: Sources from template exposure
72  @return Struct(matches: Matches between sources,
73  wcs: Wcs for input in frame of template,
74  )
75  """
76  matches = self.matchSources(inputSources, templateSources)
77  wcs = self.fitWcs(matches, inputWcs, inputBBox)
78  return Struct(matches=matches, wcs=wcs)
def lsst.pipe.tasks.registerImage.RegisterTask.warpExposure (   self,
  inputExp,
  newWcs,
  templateWcs,
  templateBBox 
)
Warp input exposure to template frame

There are a variety of data attached to the exposure (e.g., PSF, Calib
and other metadata), but we do not attempt to warp these to the template
frame.

@param inputExp: Input exposure, to be warped
@param newWcs: Revised Wcs for input exposure
@param templateWcs: Target Wcs
@param templateBBox: Target bounding box
@return Warped exposure

Definition at line 138 of file registerImage.py.

139  def warpExposure(self, inputExp, newWcs, templateWcs, templateBBox):
140  """Warp input exposure to template frame
141 
142  There are a variety of data attached to the exposure (e.g., PSF, Calib
143  and other metadata), but we do not attempt to warp these to the template
144  frame.
145 
146  @param inputExp: Input exposure, to be warped
147  @param newWcs: Revised Wcs for input exposure
148  @param templateWcs: Target Wcs
149  @param templateBBox: Target bounding box
150  @return Warped exposure
151  """
152  warper = Warper.fromConfig(self.config.warper)
153  copyExp = inputExp.Factory(inputExp.getMaskedImage(), newWcs)
154  alignedExp = warper.warpExposure(templateWcs, copyExp, destBBox=templateBBox)
155  return alignedExp
def lsst.pipe.tasks.registerImage.RegisterTask.warpSources (   self,
  inputSources,
  newWcs,
  templateWcs,
  templateBBox 
)
Warp sources to the new frame

It would be difficult to transform all possible quantities of potential
interest between the two frames.  We therefore update only the sky and
pixel coordinates.

@param inputSources: Sources on input exposure, to be warped
@param newWcs: Revised Wcs for input exposure
@param templateWcs: Target Wcs
@param templateBBox: Target bounding box
@return Warped sources

Definition at line 156 of file registerImage.py.

157  def warpSources(self, inputSources, newWcs, templateWcs, templateBBox):
158  """Warp sources to the new frame
159 
160  It would be difficult to transform all possible quantities of potential
161  interest between the two frames. We therefore update only the sky and
162  pixel coordinates.
163 
164  @param inputSources: Sources on input exposure, to be warped
165  @param newWcs: Revised Wcs for input exposure
166  @param templateWcs: Target Wcs
167  @param templateBBox: Target bounding box
168  @return Warped sources
169  """
170  alignedSources = inputSources.copy(True)
171  if not isinstance(templateBBox, afwGeom.Box2D):
172  # There is no method Box2I::contains(Point2D)
173  templateBBox = afwGeom.Box2D(templateBBox)
174  table = alignedSources.getTable()
175  coordKey = table.getCoordKey()
176  centroidKey = table.getCentroidKey()
177  centroidErrKey = table.getCentroidErrKey()
178  deleteList = []
179  for i, s in enumerate(alignedSources):
180  oldCentroid = s.get(centroidKey)
181  newCoord = newWcs.pixelToSky(oldCentroid)
182  newCentroid = templateWcs.skyToPixel(newCoord)
183  if not templateBBox.contains(newCentroid):
184  deleteList.append(i)
185  continue
186  s.set(coordKey, newCoord)
187  s.set(centroidKey, newCentroid)
188 
189  for i in reversed(deleteList): # Delete from back so we don't change indices
190  del alignedSources[i]
191 
192  return alignedSources
A floating-point coordinate rectangle geometry.
Definition: Box.h:271

Member Data Documentation

lsst.pipe.tasks.registerImage.RegisterTask.ConfigClass = RegisterConfig
static

Definition at line 58 of file registerImage.py.


The documentation for this class was generated from the following file: