lsst.meas.modelfit g396055baef+b110d0aa47
modelFitAdapters.py
Go to the documentation of this file.
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
23import numpy
24from .densityPlot import mergeDefaults
25from .. import modelfitLib
26
27__all__ = ("SamplingDataAdapter", "OptimizerTrackLayer", "OptimizerDataAdapter",)
28
29
31
32 def __init__(self, record):
33 self.record = record
34 self.pdf = record.getPdf()
35 self.dimensions = list(record.getInterpreter().getParameterNames())
36
37 def eval1d(self, dim, x):
38 i = self.dimensions.index(dim)
39 z = numpy.zeros(x.shape, dtype=float)
40 if i >= self.pdf.getDimension():
41 return None
42 projection = self.pdf.project(i)
43 projection.evaluate(x.reshape(x.shape + (1,)), z)
44 return z
45
46 def eval2d(self, xDim, yDim, x, y):
47 i = self.dimensions.index(yDim)
48 j = self.dimensions.index(xDim)
49 z = numpy.zeros(x.size, dtype=float)
50 if i >= self.pdf.getDimension() or j >= self.pdf.getDimension():
51 return None
52 projection = self.pdf.project(j, i)
53 xy = numpy.zeros((x.size, 2), dtype=float)
54 xy[:, 0] = x.flatten()
55 xy[:, 1] = y.flatten()
56 projection.evaluate(xy, z)
57 return z.reshape(x.shape)
58
59
61
62 def __init__(self, record):
63 ModelFitDataAdapter.__init__(self, record)
64 self.samples = record.getSamples().copy(deep=True)
65 self.values = self.samples["parameters"]
66 self.weights = self.samples["weight"]
67 self.setRangesFromQuantiles(0.001, 0.999)
68 assert self.values.shape[1] == len(self.dimensions)
69
70 def setRangesFromQuantiles(self, lower, upper):
71 fractions = numpy.array([lower, upper], dtype=float)
72 ranges = self.record.getInterpreter().computeParameterQuantiles(self.record, fractions)
73 self.lower = {dim: ranges[i, 0] for i, dim in enumerate(self.dimensions)}
74 self.upper = {dim: ranges[i, 1] for i, dim in enumerate(self.dimensions)}
75
76
78
79 defaults = dict(
80 accepted=dict(
81 marker='.', linestyle='-', color='c',
82 markevery=(1, 1), # (start, stride): don't put a marker on the first point
83 ),
84 rejected=dict(
85 marker='.', linestyle='-', color='k', alpha=0.5,
86 markevery=3, # marker at every third point, so we only mark the rejected points
87 ),
88 )
89
90 def __init__(self, tag, accepted=None, rejected=None):
91 self.tag = tag
92 self.accepted = mergeDefaults(accepted, self.defaults['accepted'])
93 self.rejected = mergeDefaults(rejected, self.defaults['rejected'])
94
95 def plotX(self, axes, data, dim):
96 pass
97
98 def plotY(self, axes, data, dim):
99 pass
100
101 def plotXY(self, axes, data, xDim, yDim):
102 i = data.dimensions.index(yDim)
103 j = data.dimensions.index(xDim)
104 artists = []
105 artists.extend(axes.plot(data.rejected[:, j], data.rejected[:, i], **self.rejected))
106 artists.extend(axes.plot(data.accepted[:, j], data.accepted[:, i], **self.accepted))
107 return artists
108
109
111
112 def __init__(self, record):
113 ModelFitDataAdapter.__init__(self, record)
114 self.samples = record.getSamples().copy(deep=True)
115 self.parameters = self.samples["parameters"]
116 self.state = self.samples["state"]
117 # The first point is neither accepted nor rejected, so we test on rejected and !rejected so
118 # as to include the first point with the accepted points
119 mask = (self.state & modelfitLib.Optimizer.STATUS_STEP_REJECTED).astype(bool)
120 self.accepted = self.parameters[numpy.logical_not(mask)]
121 # For each rejected point, we have three path points: the rejected point, the last accepted point,
122 # and a NaN to tell matplotlib not to connect to the next one.
123 # Note that the defaults for OptimizerTrackLayer use markevery=3 to only put markers on
124 # the rejected points
125 rejected = []
126 current = self.parameters[0]
127 nans = numpy.array([numpy.nan] * self.parameters.shape[1], dtype=float)
128 for parameters, isRejected in zip(self.parameters, mask):
129 if isRejected:
130 rejected.extend([parameters, current, nans])
131 else:
132 current = parameters
133 self.rejected = numpy.array(rejected)
134 self.lower = {}
135 self.upper = {}
136 for i, dim in enumerate(self.dimensions):
137 projected = self.pdf[0].project(i)
138 mu = projected.getMu()
139 sigma = projected.getSigma()**0.5
140 self.lower[dim] = min(self.accepted[:, i].min(), mu - 3*sigma)
141 self.upper[dim] = max(self.accepted[:, i].max(), mu + 3*sigma)
142 # Now we setup some special points for a CrossPointsLayer
143 self.points = numpy.zeros((2, self.parameters.shape[1]), dtype=float)
144 record.getInterpreter().packParameters(
145 self.record['initial.nonlinear'], self.record['initial.amplitudes'],
146 self.points[0, :]
147 )
148 record.getInterpreter().packParameters(
149 self.record['fit.nonlinear'], self.record['fit.amplitudes'],
150 self.points[1, :]
151 )
string project
Definition: conf.py:10