1 from past.builtins
import basestring
2 from builtins
import object
32 import lsst.pex.config
33 import lsst.daf.persistence
35 import lsst.afw.geom.ellipses
36 import lsst.afw.display.ds9
38 from ..measureCcd
import MeasureCcdTask
39 from ..measureCoadd
import MeasureCoaddTask
40 from ..measureMulti
import MeasureMultiTask
41 from ..
import modelfitLib
43 from .densityPlot
import *
44 from .modelFitAdapters
import *
45 from .optimizerDisplay
import *
47 __all__ = (
"Interactive", )
51 """Interactive analysis helper class
53 This class manages a butler, calexp, modelfits catalog, and an instance
54 of a Measure*Task, allowing individual objects to be re-fit and plotted.
57 def __init__(self, root, tag=None, config=None, dataId=None, mode="ccd"):
58 """Construct an interactive analysis object.
60 @param[in] rerun Output directory, relative to $S13_DATA_DIR/output.
61 measureCcd.py (or measureCoadd.py if mode='coadd') must
62 have been run (possibly with prepOnly=True) previously
63 with this output directory.
64 @param[in] tag Tag associated with the run; see BaseMeasureConfig.tag.
65 If None, config must not be (and config.tag will be used).
66 @param[in] config ConfigClass instance; if None, it will be loaded from disk.
67 @param[in] dataId Butler data ID of the image to analyze.
68 @param[in] mode One of "ccd", "coadd", or "multi", indicating whether
69 to use MeasureCcdTask, MeasureCoaddTask, or MeasureMultiTask.
72 self.
butler = lsst.daf.persistence.Butler(root)
75 if self.
mode ==
"ccd":
77 dataId = dict(visit=100, raft=
"2,2", sensor=
"1,1")
78 self.
dataRef = self.butler.dataRef(
"calexp", dataId=dataId)
79 configName =
"measureCcd_config"
80 TaskClass = MeasureCcdTask
81 elif self.
mode ==
"coadd":
83 dataId = dict(tract=0, patch=
"2,2", filter=
"i")
84 self.
dataRef = self.butler.dataRef(
"deepCoadd_calexp", dataId=dataId)
85 configName =
"deep_measureCoadd_config"
86 TaskClass = MeasureCoaddTask
87 elif self.mode.startswith(
"multi"):
89 dataId = dict(tract=0, patch=
"2,2", filter=
"i")
90 self.
dataRef = self.butler.dataRef(
"deepCoadd_calexp", dataId=dataId)
91 configName =
"deep_measureMulti_config"
92 TaskClass = MeasureMultiTask
94 config = self.butler.get(configName, tag=tag, immediate=
True)
98 raise ValueError(
"tag and config arguments cannot both be None")
101 config.tag =
"intermediate"
106 """Re-fit the object indicated by the given record sequential index or source ID,
107 returning the record.
109 likelihood = self.task.makeLikelihood(self.
inputs, outRecord)
110 self.task.fitter.run(likelihood, outRecord)
114 """Plot a representation of the posterior distribution from a ModelFitRecord.
117 recordId = records[0].getId()
118 figure = matplotlib.pyplot.figure(recordId, figsize=(10, 10))
121 for record
in records:
122 assert record.getId() == recordId
123 if modelfitLib.MarginalSamplingInterpreter.cast(record.getInterpreter()):
124 data[
"marginal"] = SamplingDataAdapter(record)
125 layers[
"marginal.samples"] = HistogramLayer(
"direct")
126 layers[
"marginal.proposal"] = SurfaceLayer(
"direct")
127 elif modelfitLib.DirectSamplingInterpreter.cast(record.getInterpreter()):
128 data[
"direct"] = SamplingDataAdapter(record)
129 layers[
"direct.samples"] = HistogramLayer(
"direct")
130 layers[
"direct.proposal"] = SurfaceLayer(
"direct")
131 elif modelfitLib.OptimizerInterpreter.cast(record.getInterpreter()):
132 data[
"optimizer"] = OptimizerDataAdapter(record)
133 layers[
"optimizer.track"] = OptimizerTrackLayer(
"optimizer")
134 layers[
"optimizer.pdf"] = SurfaceLayer(
"optimizer",
135 kwds1d=dict(color=
'g'),
136 kwds2d=dict(cmap=matplotlib.cm.Greens))
137 layers[
"optimizer.points"] = CrossPointsLayer(
"optimizer")
139 raise ValueError(
"Unknown or missing interpreter")
140 p = DensityPlot(figure, **data)
141 p.layers.update(layers)
146 likelihood = self.task.makeLikelihood(self.
inputs, record)
147 objective = modelfitLib.OptimizerObjective.makeFromLikelihood(likelihood, self.task.prior)
148 return OptimizerDisplay(record.getSamples(), self.task.model, objective)
150 def displayResiduals(self, record, nonlinear="fit", amplitudes="fit", doApplyWeights=False):
151 """Display the data postage stamp along with the model image and residuals in ds9.
153 @param[in] record ModelFitRecord defining the object to display
154 @param[in] nonlinear Vector of nonlinear parameters, or a string prefix (see below)
155 @param[in] amplitudes Vector of linear parameters, or a string prefix (see below)
156 @param[in] doApplyWeights Whether to show the weighted images used directly in the fit
157 or the original unweighted data.
159 String prefixes are used to extract the parameters from the record. Usually the following
161 fit ------- use record.get("fit.*"); the best-fit parameters
162 initial --- use record.get("initial.*"); the initial parameters
164 likelihood = self.task.makeLikelihood(self.
inputs, record)
166 if isinstance(nonlinear, basestring):
167 nonlinear = record.get(nonlinear +
".nonlinear")
169 assert nonlinear.shape == (likelihood.getNonlinearDim(),)
171 matrix = numpy.zeros((likelihood.getAmplitudeDim(), likelihood.getDataDim()),
172 dtype=modelfitLib.Pixel).transpose()
173 likelihood.computeModelMatrix(matrix, nonlinear, doApplyWeights)
175 if isinstance(amplitudes, basestring):
176 amplitudes = record.get(amplitudes +
".amplitudes")
178 assert amplitudes.shape == (likelihood.getAmplitudeDim(),)
180 bbox = record.getFootprint().getBBox()
182 flatModel = numpy.zeros(likelihood.getDataDim(), dtype=modelfitLib.Pixel)
183 flatModel[:] = numpy.dot(matrix, amplitudes)
185 imgData = lsst.afw.image.MaskedImageF(self.inputs.exposure.getMaskedImage(), bbox,
186 lsst.afw.image.PARENT,
True)
187 bitmask = imgData.getMask().addMaskPlane(
"FIT_REGION")
188 regionMask = lsst.afw.image.MaskU(bbox)
189 lsst.afw.detection.setMaskFromFootprint(regionMask, record.getFootprint(), bitmask)
190 dataMask = imgData.getMask()
191 dataMask |= regionMask
193 imgData.getImage().set(0.0)
194 imgData.getVariance().set(0.0)
195 flatData = likelihood.getData()
196 lsst.afw.detection.expandArray(record.getFootprint(), flatData, imgData.getImage().getArray(),
198 imgModel = lsst.afw.image.MaskedImageF(lsst.afw.image.ImageF(bbox), regionMask)
199 lsst.afw.detection.expandArray(record.getFootprint(), flatModel, imgModel.getImage().getArray(),
201 imgResiduals = lsst.afw.image.MaskedImageF(imgData,
True)
202 imgResiduals -= imgModel
203 mosaic = lsst.afw.display.utils.Mosaic()
205 mosaic.append(imgData,
"data")
206 mosaic.append(imgModel,
"model")
207 mosaic.append(imgResiduals,
"data-model")
208 grid = mosaic.makeMosaic()
209 lsst.afw.display.ds9.mtv(grid)
210 lsst.afw.display.ds9.setMaskTransparency(85)