LSSTApplications  19.0.0-14-gb0260a2+72efe9b372,20.0.0+7927753e06,20.0.0+8829bf0056,20.0.0+995114c5d2,20.0.0+b6f4b2abd1,20.0.0+bddc4f4cbe,20.0.0-1-g253301a+8829bf0056,20.0.0-1-g2b7511a+0d71a2d77f,20.0.0-1-g5b95a8c+7461dd0434,20.0.0-12-g321c96ea+23efe4bbff,20.0.0-16-gfab17e72e+fdf35455f6,20.0.0-2-g0070d88+ba3ffc8f0b,20.0.0-2-g4dae9ad+ee58a624b3,20.0.0-2-g61b8584+5d3db074ba,20.0.0-2-gb780d76+d529cf1a41,20.0.0-2-ged6426c+226a441f5f,20.0.0-2-gf072044+8829bf0056,20.0.0-2-gf1f7952+ee58a624b3,20.0.0-20-geae50cf+e37fec0aee,20.0.0-25-g3dcad98+544a109665,20.0.0-25-g5eafb0f+ee58a624b3,20.0.0-27-g64178ef+f1f297b00a,20.0.0-3-g4cc78c6+e0676b0dc8,20.0.0-3-g8f21e14+4fd2c12c9a,20.0.0-3-gbd60e8c+187b78b4b8,20.0.0-3-gbecbe05+48431fa087,20.0.0-38-ge4adf513+a12e1f8e37,20.0.0-4-g97dc21a+544a109665,20.0.0-4-gb4befbc+087873070b,20.0.0-4-gf910f65+5d3db074ba,20.0.0-5-gdfe0fee+199202a608,20.0.0-5-gfbfe500+d529cf1a41,20.0.0-6-g64f541c+d529cf1a41,20.0.0-6-g9a5b7a1+a1cd37312e,20.0.0-68-ga3f3dda+5fca18c6a4,20.0.0-9-g4aef684+e18322736b,w.2020.45
LSSTDataManagementBasePackage
optimizerDisplay.py
Go to the documentation of this file.
1 #
2 # LSST Data Management System
3 # Copyright 2008-2013 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 
23 import numpy
24 import matplotlib
25 import matplotlib.colors
26 from mpl_toolkits.axes_grid1 import make_axes_locatable
27 
28 from .densityPlot import hide_xticklabels, hide_yticklabels
29 from .. import modelfitLib
30 
31 __all__ = ("OptimizerDisplay", )
32 
33 
35 
36  def __init__(self, parent, sample):
37  self.parent = parent
38  self.sample = sample
39  # scale unit grid by trust radius
40  self.grid = parent.unitGrid * sample.get(parent.recorder.trust)
41  # offset grid to center it on the current parameter point
42  self.grid += sample.get(parent.recorder.parameters).reshape((1,)*parent.ndim + (parent.ndim,))
43  self._objectiveValues = None
44  self._objectiveModel = None
45  self.rejected = []
46 
47  def __getattr__(self, name):
48  # look for keys on the recorder and lookup fields for unknown attributes
49  return self.sample.get(getattr(self.parent.recorder, name))
50 
51  @property
52  def objectiveValues(self):
53  if self._objectiveValues is None:
54  self._objectiveValues = numpy.zeros(self.grid.shape[:-1], dtype=float)
55  self.parent.objective.fillObjectiveValueGrid(self.grid.reshape(-1, self.parent.ndim),
56  self._objectiveValues.reshape(-1))
57  good = numpy.isfinite(self._objectiveValues)
58  self._objectiveValues[numpy.logical_not(good)] = self._objectiveValues[good].max()
59  return self._objectiveValues
60 
61  @property
62  def objectiveModel(self):
63  if self._objectiveModel is None:
64  self._objectiveModel = numpy.zeros(self.grid.shape[:-1], dtype=float)
65  self.parent.recorder.fillObjectiveModelGrid(self.sample,
66  self.grid.reshape(-1, self.parent.ndim),
67  self._objectiveModel.reshape(-1))
68  return self._objectiveModel
69 
70 
72 
73  def __init__(self, history, model, objective, steps=11):
74  self.recorder = modelfitLib.OptimizerHistoryRecorder(history.schema)
75  # len(dimensions) == N in comments below
76  self.dimensions = list(model.getNonlinearNames()) + list(model.getAmplitudeNames())
77  self.ndim = len(self.dimensions)
78  self.track = []
79  self.objective = objective
80  # This creates a array with shape [steps, ..., steps, N] (a total of N+1 array dimensions):
81  # this is an N-dimensional grid, with the last dimension of the grid array giving the coordinates
82  # of each grid point.
83  # We slice mgrid to generate the basic grid, which is [N, steps, ..., steps]
84  mgridArgs = (slice(-1.0, 1.0, steps*1j),) * self.ndim
85  # We'll index the result of mgrid with these args to make first dimension last
86  transposeArgs = tuple(list(range(1, self.ndim+1)) + [0])
87  self.unitGrid = numpy.mgrid[mgridArgs].transpose(transposeArgs).copy()
88  current = None
89  for sample in history:
90  if sample.get(self.recorder.state) & modelfitLib.Optimizer.STATUS_STEP_REJECTED:
91  assert current is not None
92  current.rejected.append(sample)
93  continue
94  current = OptimizerIterationDisplay(self, sample)
95  self.track.append(current)
96 
97  def plot(self, xDim, yDim, n=0):
98  return OptimizerDisplayFigure(self, xDim=xDim, yDim=yDim, n=n)
99 
100 
102 
103  def __init__(self, parent, xDim, yDim, n=0):
104  self.parent = parent
105  self.xDim = xDim
106  self.yDim = yDim
107  self.j = self.parent.dimensions.index(self.xDim)
108  self.i = self.parent.dimensions.index(self.yDim)
109  self.yKey = self.parent.recorder.parameters[self.i]
110  self.xKey = self.parent.recorder.parameters[self.j]
111  self.zKey = self.parent.recorder.objective
112  # grid slice indices corresponding to the dimensions we're plotting
113  self.slice2d = [s//2 for s in self.parent.unitGrid.shape[:-1]]
114  self.slice2d[self.i] = slice(None)
115  self.slice2d[self.j] = slice(None)
116  self.slice2d = tuple(self.slice2d)
117  self.sliceX = [s//2 for s in self.parent.unitGrid.shape[:-1]]
118  self.sliceX[self.j] = slice(None)
119  self.sliceX = tuple(self.sliceX)
120  self.sliceY = [s//2 for s in self.parent.unitGrid.shape[:-1]]
121  self.sliceY[self.i] = slice(None)
122  self.sliceY = tuple(self.sliceY)
123  self.track = dict(
124  x=numpy.array([iteration.sample.get(self.xKey) for iteration in self.parent.track]),
125  y=numpy.array([iteration.sample.get(self.yKey) for iteration in self.parent.track]),
126  z=numpy.array([iteration.sample.get(self.zKey) for iteration in self.parent.track]),
127  )
128  self.n = n
129  self.figure = matplotlib.pyplot.figure(f"{xDim} vs {yDim}", figsize=(16, 8))
130  self.figure.subplots_adjust(left=0.025, right=0.975, bottom=0.08, top=0.95, wspace=0.12)
131  self.axes3d = self.figure.add_subplot(1, 2, 1, projection='3d')
132  self.axes3d.autoscale(False)
133  self.axes3d.set_xlabel(self.xDim)
134  self.axes3d.set_ylabel(self.yDim)
135  self.axes2d = self.figure.add_subplot(1, 2, 2)
136  self.axes2d.set_xlabel(self.xDim)
137  self.axes2d.set_ylabel(self.yDim)
138  self.axes2d.autoscale(False)
139  divider = make_axes_locatable(self.axes2d)
140  self.axesX = divider.append_axes("top", 1.5, pad=0.1, sharex=self.axes2d)
141  self.axesX.autoscale(False, axis='x')
142  hide_xticklabels(self.axesX)
143  self.axesY = divider.append_axes("right", 1.5, pad=0.1, sharey=self.axes2d)
144  self.axesY.autoscale(False, axis='y')
145  hide_yticklabels(self.axesY)
146  self.artists = []
147  self.guessExtent()
148  self.plotTrack()
149  self.plotRejected()
150  self.plotSurfaces()
151 
152  @property
153  def xlim(self):
154  return self._extent[:2]
155 
156  @property
157  def ylim(self):
158  return self._extent[2:4]
159 
160  @property
161  def zlim(self):
162  return self._extent[4:]
163 
164  def guessExtent(self):
165  current = self.parent.track[self.n]
166  x = current.sample.get(self.xKey)
167  y = current.sample.get(self.yKey)
168  zMin1 = current.objectiveValues[self.slice2d].min()
169  zMax1 = current.objectiveValues[self.slice2d].max()
170  zMin2 = current.objectiveModel[self.slice2d].min()
171  zMax2 = current.objectiveModel[self.slice2d].max()
172  self.setExtent(x0=x - current.trust, x1=x + current.trust,
173  y0=y - current.trust, y1=y + current.trust,
174  z0=min(zMin1, zMin2), z1=max(zMax1, zMax2), lock=False)
175 
176  def setExtent(self, x0=None, x1=None, y0=None, y1=None, z0=None, z1=None, lock=True):
177  if x0 is None:
178  x0 = self._extent[0]
179  if x1 is None:
180  x1 = self._extent[1]
181  if y0 is None:
182  y0 = self._extent[2]
183  if y1 is None:
184  y1 = self._extent[3]
185  if z0 is None:
186  z0 = self._extent[4]
187  if z1 is None:
188  z1 = self._extent[5]
189  self._extent = (x0, x1, y0, y1, z0, z1)
190  self._lock = lock
191  self.axes3d.set_xlim(*self.xlim)
192  self.axes3d.set_ylim(*self.ylim)
193  self.axes3d.set_zlim(*self.zlim)
194  self.axes2d.set_xlim(*self.xlim)
195  self.axes2d.set_ylim(*self.ylim)
196  self.axesX.set_ylim(*self.zlim)
197  self.axesY.set_xlim(*self.zlim)
198 
199  def _clipZ(self, x, y, z):
200  # clipping is currently disabled; more trouble than it's worth
201  if False:
202  mask = numpy.logical_or.reduce([x < self.xlim[0], x > self.xlim[1],
203  y < self.ylim[0], y > self.ylim[1],
204  z < self.zlim[0], z > self.zlim[1]],
205  axis=0)
206 
207  z[mask] = numpy.nan
208  return numpy.logical_not(mask).astype(int).sum() > 4
209  return True
210 
211  def _contour(self, axes, *args, **kwds):
212  self.artists.extend(axes.contour(*args, **kwds).collections)
213 
214  def plotTrack(self):
215  kwds = dict(markeredgewidth=0, markerfacecolor='g', color='g', marker='o')
216  self.axes3d.plot(self.track['x'], self.track['y'], self.track['z'], **kwds)
217  self.axes2d.plot(self.track['x'], self.track['y'], **kwds)
218  self.axesX.plot(self.track['x'], self.track['z'], **kwds)
219  self.axesY.plot(self.track['z'], self.track['y'], **kwds)
220 
221  def plotRejected(self):
222  kwds = dict(markeredgewidth=0, markerfacecolor='r', color='r', marker='v')
223  current = self.parent.track[self.n]
224  cx = current.sample.get(self.xKey)
225  cy = current.sample.get(self.yKey)
226  cz = current.sample.get(self.zKey)
227  for r in current.rejected:
228  x = [cx, r.get(self.xKey)]
229  y = [cy, r.get(self.yKey)]
230  z = [cz, r.get(self.zKey)]
231  self.artists.extend(self.axes3d.plot(x, y, z, **kwds))
232  self.artists.extend(self.axes2d.plot(x, y, **kwds))
233  self.artists.extend(self.axesX.plot(x, z, **kwds))
234  self.artists.extend(self.axesY.plot(z, y, **kwds))
235 
236  def plotSurfaces(self):
237  current = self.parent.track[self.n]
238 
239  # Start with 2-d and 3-d surfaces
240  x = current.grid[self.slice2d + (self.j,)]
241  y = current.grid[self.slice2d + (self.i,)]
242  z1 = current.objectiveValues[self.slice2d].copy()
243  z2 = current.objectiveModel[self.slice2d].copy()
244  norm = matplotlib.colors.Normalize(vmin=self.zlim[0], vmax=self.zlim[1])
245 
246  self._contour(self.axes2d, x, y, z1, cmap=matplotlib.cm.spring, norm=norm)
247  self._contour(self.axes2d, x, y, z2, cmap=matplotlib.cm.winter, norm=norm)
248 
249  # matplotlib doesn't do clipping in 3d, so we'll do that manually
250  if self._clipZ(x, y, z1):
251  self._contour(self.axes3d, x, y, z1, cmap=matplotlib.cm.spring, norm=norm)
252  self.artists.append(self.axes3d.plot_surface(x, y, z1, rstride=1, cstride=1,
253  cmap=matplotlib.cm.spring, norm=norm,
254  linewidth=0, antialiased=1, alpha=0.5))
255  if self._clipZ(x, y, z2):
256  self._contour(self.axes3d, x, y, z2, cmap=matplotlib.cm.winter, norm=norm)
257  self.artists.append(self.axes3d.plot_surface(x, y, z2, rstride=1, cstride=1,
258  cmap=matplotlib.cm.winter, norm=norm,
259  linewidth=0, antialiased=1, alpha=0.5))
260 
261  # Now the 1-d surfaces
262  self.artists.extend(self.axesX.plot(current.grid[self.sliceX + (self.j,)],
263  current.objectiveValues[self.sliceX], 'm-'))
264  self.artists.extend(self.axesX.plot(current.grid[self.sliceX + (self.j,)],
265  current.objectiveModel[self.sliceX], 'c-'))
266  self.artists.extend(self.axesY.plot(current.objectiveValues[self.sliceY],
267  current.grid[self.sliceY + (self.i,)], 'm-'))
268  self.artists.extend(self.axesY.plot(current.objectiveModel[self.sliceY],
269  current.grid[self.sliceY + (self.i,)], 'c-'))
270 
271  def move(self, n):
272  self.n = n
273  if not self._lock:
274  self.guessExtent()
275  for artist in self.artists:
276  try:
277  artist.remove()
278  except TypeError:
279  # sometimes matplotlib throws an exception even though everything worked fine
280  pass
281  self.artists = []
282  self.plotSurfaces()
283  self.plotRejected()
284  self.figure.canvas.draw()
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplayFigure.sliceX
sliceX
Definition: optimizerDisplay.py:117
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplayFigure._extent
_extent
Definition: optimizerDisplay.py:189
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplayFigure.zlim
def zlim(self)
Definition: optimizerDisplay.py:161
lsst::meas::modelfit.display.optimizerDisplay.OptimizerIterationDisplay.parent
parent
Definition: optimizerDisplay.py:37
lsst::meas::modelfit.display.densityPlot.hide_yticklabels
def hide_yticklabels(axes)
Definition: densityPlot.py:51
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplayFigure._contour
def _contour(self, axes, *args, **kwds)
Definition: optimizerDisplay.py:211
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplayFigure.axesY
axesY
Definition: optimizerDisplay.py:143
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplayFigure.__init__
def __init__(self, parent, xDim, yDim, n=0)
Definition: optimizerDisplay.py:103
lsst::meas::modelfit.display.optimizerDisplay.OptimizerIterationDisplay._objectiveValues
_objectiveValues
Definition: optimizerDisplay.py:43
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplayFigure.axes3d
axes3d
Definition: optimizerDisplay.py:131
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplayFigure.i
i
Definition: optimizerDisplay.py:108
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplayFigure.setExtent
def setExtent(self, x0=None, x1=None, y0=None, y1=None, z0=None, z1=None, lock=True)
Definition: optimizerDisplay.py:176
ast::append
std::shared_ptr< FrameSet > append(FrameSet const &first, FrameSet const &second)
Construct a FrameSet that performs two transformations in series.
Definition: functional.cc:33
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplayFigure.move
def move(self, n)
Definition: optimizerDisplay.py:271
lsst::meas::modelfit.display.optimizerDisplay.OptimizerIterationDisplay._objectiveModel
_objectiveModel
Definition: optimizerDisplay.py:44
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplayFigure.track
track
Definition: optimizerDisplay.py:123
lsst::meas::modelfit.display.optimizerDisplay.OptimizerIterationDisplay.grid
grid
Definition: optimizerDisplay.py:40
lsst::meas::algorithms.objectSizeStarSelector.plot
def plot(mag, width, centers, clusterId, marker="o", markersize=2, markeredgewidth=0, ltype='-', magType="model", clear=True)
Definition: objectSizeStarSelector.py:264
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplayFigure._lock
_lock
Definition: optimizerDisplay.py:190
lsst::meas::modelfit.display.optimizerDisplay.OptimizerIterationDisplay.objectiveModel
def objectiveModel(self)
Definition: optimizerDisplay.py:62
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplayFigure.yKey
yKey
Definition: optimizerDisplay.py:109
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplayFigure.parent
parent
Definition: optimizerDisplay.py:104
lsst::meas::modelfit.display.optimizerDisplay.OptimizerIterationDisplay.objectiveValues
def objectiveValues(self)
Definition: optimizerDisplay.py:52
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplayFigure._clipZ
def _clipZ(self, x, y, z)
Definition: optimizerDisplay.py:199
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplayFigure.ylim
def ylim(self)
Definition: optimizerDisplay.py:157
lsst::meas::modelfit.display.densityPlot.hide_xticklabels
def hide_xticklabels(axes)
Definition: densityPlot.py:46
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplay.dimensions
dimensions
Definition: optimizerDisplay.py:76
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplay.plot
def plot(self, xDim, yDim, n=0)
Definition: optimizerDisplay.py:97
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplayFigure.xlim
def xlim(self)
Definition: optimizerDisplay.py:153
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplayFigure.guessExtent
def guessExtent(self)
Definition: optimizerDisplay.py:164
lsst::meas::modelfit.display.optimizerDisplay.OptimizerIterationDisplay
Definition: optimizerDisplay.py:34
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplay.__init__
def __init__(self, history, model, objective, steps=11)
Definition: optimizerDisplay.py:73
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplayFigure.n
n
Definition: optimizerDisplay.py:128
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplayFigure.j
j
Definition: optimizerDisplay.py:107
max
int max
Definition: BoundedField.cc:104
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplayFigure.plotRejected
def plotRejected(self)
Definition: optimizerDisplay.py:221
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplay.unitGrid
unitGrid
Definition: optimizerDisplay.py:87
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplay
Definition: optimizerDisplay.py:71
lsst::meas::modelfit.display.optimizerDisplay.OptimizerIterationDisplay.__init__
def __init__(self, parent, sample)
Definition: optimizerDisplay.py:36
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplayFigure.plotSurfaces
def plotSurfaces(self)
Definition: optimizerDisplay.py:236
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplayFigure.slice2d
slice2d
Definition: optimizerDisplay.py:113
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplayFigure.xKey
xKey
Definition: optimizerDisplay.py:110
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplayFigure.zKey
zKey
Definition: optimizerDisplay.py:111
list
daf::base::PropertyList * list
Definition: fits.cc:913
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplay.recorder
recorder
Definition: optimizerDisplay.py:74
min
int min
Definition: BoundedField.cc:103
lsst::meas::modelfit.display.optimizerDisplay.OptimizerIterationDisplay.sample
sample
Definition: optimizerDisplay.py:38
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplayFigure.plotTrack
def plotTrack(self)
Definition: optimizerDisplay.py:214
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplayFigure.axes2d
axes2d
Definition: optimizerDisplay.py:135
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplayFigure.xDim
xDim
Definition: optimizerDisplay.py:105
lsst::meas::modelfit.display.optimizerDisplay.OptimizerIterationDisplay.rejected
rejected
Definition: optimizerDisplay.py:45
lsst::meas::modelfit.display.optimizerDisplay.OptimizerIterationDisplay.__getattr__
def __getattr__(self, name)
Definition: optimizerDisplay.py:47
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplayFigure.axesX
axesX
Definition: optimizerDisplay.py:140
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplay.ndim
ndim
Definition: optimizerDisplay.py:77
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplayFigure.artists
artists
Definition: optimizerDisplay.py:146
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplayFigure
Definition: optimizerDisplay.py:101
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplay.track
track
Definition: optimizerDisplay.py:78
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplayFigure.sliceY
sliceY
Definition: optimizerDisplay.py:120
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplayFigure.yDim
yDim
Definition: optimizerDisplay.py:106
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplay.objective
objective
Definition: optimizerDisplay.py:79
lsst::meas::modelfit.display.optimizerDisplay.OptimizerDisplayFigure.figure
figure
Definition: optimizerDisplay.py:129