LSSTApplications  18.1.0
LSSTDataManagementBasePackage
cModelDisplay.py
Go to the documentation of this file.
1 __all__ = ("displayReconstructedCmodel", "displayReconstrucedCmodelMpl",
2  "buildCModelImages", "reconstructCModel")
3 
4 import numpy as np
5 import matplotlib.pyplot as plt
6 
7 import lsst.afw.image as afwImage
8 import lsst.meas.modelfit as measMod
9 import lsst.shapelet as shapelet
10 
11 
12 def displayReconstructedCmodel(exposure, record, config, display="mpl"):
13  """ Display an image, the Cmodel, and residuals
14 
15  Parameters
16  ----------
17  exposure : `lsst.afw.image.Exposure`
18  Exposure object that contains the source which was modeled
19  record : `lsst.afw.table.SourceRecord`
20  Record object which contains the measurements made on the source
21  config : `lsst.meas.modelfit.CModel(SingleFrame/Forced)Config`
22  Configuration object of the CModel plugin used in the measurement
23  process
24  display : `str`, optional
25  Display in which to render the data, may be mpl for matplotlib or afw
26  for afwDisplay, defaults to mpl
27 
28  Raises
29  ------
30  `NotImplementedError`
31  If the display backend specified is not implemented
32  """
33 
34  if display == "mpl":
35  displayReconstrucedCmodelMpl(exposure, record, config)
36  elif display == "afw":
37  raise NotImplementedError("The afw display backend is not yet "
38  "implemented")
39  else:
40  raise NotImplementedError("The display backend '{}' is not a supported"
41  "backend".format(display))
42 
43 
44 def displayReconstrucedCmodelMpl(exposure, record, config):
45  """ Display an image, the Cmodel, and residuals using matplotlib
46 
47  Parameters
48  ----------
49  exposure : `lsst.afw.image.Exposure`
50  Exposure object that contains the source which was modeled
51  record : `lsst.afw.table.SourceRecord`
52  Record object which contains the measurements made on the source
53  config : `lsst.meas.modelfit.CModel(SingleFrame/Forced)Config`
54  Configuration object of the CModel plugin used in the measurement
55  process
56  """
57 
58  subImage, devIm, expIm, jointIm = buildCModelImages(exposure, record,
59  config)
60  # Get the min and max values for the sub image to use for scaling
61  subImMin = subImage.array.min()
62  subImMax = subImage.array.max()
63 
64  # Calculate the scaling to use for the residual images
65  devResidual = subImage.array-devIm.array
66  expResidual = subImage.array-expIm.array
67  jointResidual = subImage.array-jointIm.array
68  residualList = (devResidual, expResidual, jointResidual)
69 
70  differences = [(x.max()-x.max()) for x in residualList]
71  maxDifferenceIndex = np.argmax(differences)
72  resImMin = residualList[maxDifferenceIndex].min()
73  resImMax = residualList[maxDifferenceIndex].max()
74 
75  # Build the image figure
76  fig, axes = plt.subplots(3, 3, sharex='col', sharey='row', figsize=(8, 5))
77  fig.subplots_adjust(left=0.25, right=0.8)
78  lCBar = fig.add_axes([0.1, 0.15, 0.05, 0.7])
79  rCBar = fig.add_axes([0.85, 0.15, 0.05, 0.7])
80 
81  # Populate just the exposures in the appropriate places
82  for i in range(3):
83  axes[i, 0].imshow(subImage.array, vmin=subImMin, vmax=subImMax)
84 
85  # Populate dev panels
86  axes[0, 1].imshow(devIm.array, vmin=subImMin, vmax=subImMax)
87  axes[0, 2].imshow(devResidual, vmin=resImMin, vmax=resImMax, cmap="BrBG")
88 
89  # Populate exp panels
90  axes[1, 1].imshow(expIm.array, vmin=subImMin, vmax=subImMax)
91  axes[1, 2].imshow(expResidual, vmin=resImMin, vmax=resImMax, cmap="BrBG")
92 
93  # Populate joint panels
94  axes[2, 1].imshow(jointIm.array, vmin=subImMin, vmax=subImMax)
95  axes[2, 2].imshow(jointResidual, vmin=resImMin, vmax=resImMax, cmap="BrBG")
96 
97  axes[0, 0].set_title("Image")
98  axes[0, 1].set_title("Model")
99  axes[0, 2].set_title('Residuals')
100 
101  axes[0, 0].set_ylabel("Dev")
102  axes[1, 0].set_ylabel("Exp")
103  axes[2, 0].set_ylabel("Joint")
104 
105  fig.colorbar(axes[0, 0].get_images()[0], lCBar)
106  lCBar.yaxis.set_ticks_position('left')
107  fig.colorbar(axes[maxDifferenceIndex, 2].get_images()[0], rCBar)
108 
109  plt.show()
110 
111 
112 def buildCModelImages(exposure, record, config):
113  """ Create Images out of the CModel for the given record
114 
115  Parameters
116  ----------
117  exposure : `lsst.afw.image.Exposure`
118  Exposure object that contains the source which was modeled
119  record : `lsst.afw.table.SourceRecord`
120  Record object which contains the measurements made on the source
121  config : `lsst.meas.modelfit.CModel(SingleFrame/Forced)Config`
122  Configuration object of the CModel plugin used in the measurement
123  process
124 
125  Returns
126  -------
127  subImage : `lsst.afw.image.ImageF`
128  Sub image of the original data taken from a region defined by the
129  bounding box of the footprint for the object defined in the given
130  source record
131  devIm : `lsst.afw.image.ImageF`
132  Image created from the dev component of the CModel for the supplied
133  record at the same pixel locations as subImage
134  expIm: `lsst.afw.image.ImageF`
135  Image created from the exp component of the CModel for the supplied
136  record at the same pixel locations as subImage
137  jointIm :
138  Image created from the joint fit of the dev and exp components of the
139  CModel for the supplied record at the same pixel locations as subImage
140  """
141 
142  dev, exp, jointDev, jointExp = reconstructCModel(exposure, record, config)
143  # Get exposure cutout
144  footBBox = record.getFootprint().getBBox()
145  subImage = afwImage.ImageF(exposure.getImage(), footBBox)
146 
147  # Build the psf
148  shapeletPsfKey = shapelet.MultiShapeletFunctionKey(
149  record.schema[config.psfName])
150  psfApprox = record.get(shapeletPsfKey)
151 
152  # Build the dev Image from the shapelet function
153  devIm = afwImage.ImageF(footBBox)
154  dev = dev.convolve(psfApprox)
155  dev.evaluate().addToImage(devIm)
156 
157  # Build the exp image from the shapelet function
158  expIm = afwImage.ImageF(footBBox)
159  exp = exp.convolve(psfApprox)
160  exp.evaluate().addToImage(expIm)
161 
162  # Build the joint image from the shapelet function
163  jointIm = afwImage.ImageF(footBBox)
164  jointDev = jointDev.convolve(psfApprox)
165  jointExp = jointExp.convolve(psfApprox)
166  jointDev.evaluate().addToImage(jointIm)
167  jointExp.evaluate().addToImage(jointIm)
168 
169  return subImage, devIm, expIm, jointIm
170 
171 
172 def reconstructCModel(exposure, record, config):
173  """ Reconstruct the CModel for the given record
174 
175  Parameters
176  ----------
177  exposure : `lsst.afw.image.Exposure`
178  Exposure object that contains the source which was modeled
179  record : `lsst.afw.table.SourceRecord`
180  Record object which contains the measurements made on the source
181  config : `lsst.meas.modelfit.CModel(SingleFrame/Forced)Config`
182  Configuration object of the CModel plugin used in the measurement
183  process
184 
185  Returns
186  -------
187  devShapelet : `lsst.shapelet.MultiShapeletFunction`
188  Multi-component shapelet model of the dev component of CModel
189  expShapelet : `lsst.shapelet.MultiShapeletFunction`
190  Multi-component shapelet model fo the exp component of CModel
191  devJointShapelet : `lsst.shapelet.MultiShapeletFunction`
192  Multi-component shapelet model of the dev component of CModel jointly
193  fit with the exp component
194  expJointShapelet : `lsst.shapelet.MultiShapeletFunction`
195  Multi-component shapelet model of the exp component of Cmodel jointly
196  fit with the dev component
197  """
198 
199  # build a unit system transformation object
200  center = record.getCentroid()
201  position = exposure.getWcs().pixelToSky(center)
202  measSys = measMod.UnitSystem(exposure)
203  approxFlux = record.get("base_PsfFlux_instFlux")
204  fitSys = measMod.UnitSystem(position, exposure.getPhotoCalib(), approxFlux)
205  fitSysToMeasSys = measMod.LocalUnitTransform(center, fitSys, measSys)
206 
207  # Build the Shapelet objects
208  ctrl = config.makeControl()
209  baseName = "modelfit_CModel"
210  nonlinearKeys = ["{}_{{model}}_nonlinear_{p}".format(baseName, p=p)
211  for p in range(3)]
212  fixedKeys = ["{}_{{model}}_fixed_{p}".format(baseName, p=p)
213  for p in range(2)]
214  fluxKey = "{}_{{model}}_instFlux".format(baseName)
215 
216  # fetch the aperture corrections, if this fails set it to one
217  try:
218  apCorr = record.get("{}_apCorr".format(baseName))
219  except Exception:
220  print("Warning, problem retrieving aperture correction, using a value"
221  " of 1")
222  apCorr = 1
223 
224  # Get parameters for the dev model
225  devNonLinearParams = np.array([record.get(key.format(model="dev"))
226  for key in nonlinearKeys])
227  devFixedParams = np.array([record.get(key.format(model="dev"))
228  for key in fixedKeys])
229  devAmp = np.array([record.get(fluxKey.format(model="dev"))])
230  devAmp /= apCorr
231  devShapelet = ctrl.dev.getModel().makeShapeletFunction(devNonLinearParams,
232  devAmp,
233  devFixedParams)
234  devShapelet.transformInPlace(fitSysToMeasSys.geometric)
235 
236  # Get parameters for the exp model
237  expNonLinearParams = np.array([record.get(key.format(model="exp"))
238  for key in nonlinearKeys])
239  expFixedParams = np.array([record.get(key.format(model="exp"))
240  for key in fixedKeys])
241  expAmp = np.array([record.get(fluxKey.format(model="exp"))])
242  expAmp /= apCorr
243  expShapelet = ctrl.exp.getModel().makeShapeletFunction(expNonLinearParams,
244  expAmp,
245  expFixedParams)
246  expShapelet.transformInPlace(fitSysToMeasSys.geometric)
247 
248  # Get joint shapelet model
249  fracDev = record.get("{}_fracDev".format(baseName))
250  jointFlux = np.array([record.get("{}_instFlux".format(baseName))])
251  jointFlux /= apCorr
252  devJointShapelet = ctrl.dev.getModel()\
253  .makeShapeletFunction(devNonLinearParams, jointFlux*fracDev,
254  devFixedParams)
255  devJointShapelet.transformInPlace(fitSysToMeasSys.geometric)
256 
257  expJointShapelet = ctrl.exp.getModel()\
258  .makeShapeletFunction(expNonLinearParams, jointFlux*(1-fracDev),
259  expFixedParams)
260  expJointShapelet.transformInPlace(fitSysToMeasSys.geometric)
261 
262  return devShapelet, expShapelet, devJointShapelet, expJointShapelet
def displayReconstructedCmodel(exposure, record, config, display="mpl")
def reconstructCModel(exposure, record, config)
Class that maps MultiShapeletFunction objects to fields in afw::table objects.
Definition: FunctorKeys.h:161
int min
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
Definition: history.py:168
int max
def displayReconstrucedCmodelMpl(exposure, record, config)
void addToImage(boost::shared_ptr< afw::image::Image< double > > image, std::vector< boost::shared_ptr< afw::image::Image< double > >> const &imgVector, std::vector< double > const &weightVector)
Definition: CoaddPsf.cc:192
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects...
def buildCModelImages(exposure, record, config)