|
7 | 7 | """
|
8 | 8 |
|
9 | 9 | from __future__ import (print_function, division)
|
10 |
| -import six |
11 |
| -from six.moves import range |
12 | 10 |
|
13 |
| -import sys |
14 |
| -import os |
15 | 11 | import warnings
|
16 |
| -import math |
17 | 12 | import numpy as np
|
18 |
| -import warnings |
19 | 13 | from scipy.stats import truncnorm
|
20 | 14 |
|
21 | 15 | try:
|
22 | 16 | from scipy.special import logsumexp
|
23 | 17 | except ImportError:
|
24 | 18 | from scipy.misc import logsumexp
|
25 | 19 |
|
26 |
| -__all__ = ["LOS_clouds_priortransform", "LOS_clouds_loglike_bin", |
27 |
| - "LOS_clouds_loglike_samples", |
| 20 | +__all__ = ["LOS_clouds_priortransform", "LOS_clouds_loglike_samples", |
28 | 21 | "kernel_tophat", "kernel_gauss", "kernel_lorentz"]
|
29 | 22 |
|
30 | 23 |
|
@@ -125,134 +118,9 @@ def LOS_clouds_priortransform(u, rlims=(0., 6.), dlims=(4., 19.),
|
125 | 118 | return x
|
126 | 119 |
|
127 | 120 |
|
128 |
| -def LOS_clouds_loglike_bin(theta, cdfs, xedges, yedges, interpolate=True): |
129 |
| - """ |
130 |
| - Compute the log-likelihood for the cumulative reddening along the |
131 |
| - line of sight (LOS) parameterized by `theta`, given input binned |
132 |
| - stellar posteriors/bounds generated by `.pdf.bin_pdfs_distred`. Assumes |
133 |
| - a uniform outlier model in distance and reddening across our binned |
134 |
| - posteriors. |
135 |
| -
|
136 |
| - Parameters |
137 |
| - ---------- |
138 |
| - theta : `~numpy.ndarray` of shape `(Nparams,)` |
139 |
| - A collection of parameters that characterizes the cumulative |
140 |
| - reddening along the LOS. Contains the fraction of outliers `P_b` |
141 |
| - followed by the foreground reddening `fred` and a series of |
142 |
| - `(dist, red)` pairs for each "cloud" along the LOS. |
143 |
| -
|
144 |
| - cdfs : `~numpy.ndarray` of shape `(Nobj, Nxbin, Nybin)` |
145 |
| - Binned versions of the CDFs. |
146 |
| -
|
147 |
| - xedges : `~numpy.ndarray` of shape `(Nxbin+1,)` |
148 |
| - The edges defining the bins in distance. |
149 |
| -
|
150 |
| - yedges : `~numpy.ndarray` of shape `(Nybin+1,)` |
151 |
| - The edges defining the bins in reddening. |
152 |
| -
|
153 |
| - interpolate : bool, optional |
154 |
| - Whether to linearly interpolate between bins (defined by their central |
155 |
| - positions). Default is `True`. |
156 |
| -
|
157 |
| - Returns |
158 |
| - ------- |
159 |
| - loglike : float |
160 |
| - The computed log-likelihood. |
161 |
| -
|
162 |
| - """ |
163 |
| - |
164 |
| - # Grab parameters. |
165 |
| - pb = theta[0] |
166 |
| - reds, dists = np.atleast_1d(theta[1::2]), np.atleast_1d(theta[2::2]) |
167 |
| - |
168 |
| - # Convert to bin coordinates. |
169 |
| - dx, dy = xedges[1] - xedges[0], yedges[1] - yedges[0] |
170 |
| - Nxedges, Nyedges = len(xedges), len(yedges) |
171 |
| - Nxbin, Nybin = Nxedges - 1, Nyedges - 1 |
172 |
| - x_ctrs = np.arange(0.5, Nxbin, 1.) |
173 |
| - y_ctrs = np.arange(0.5, Nybin, 1.) |
174 |
| - x = np.concatenate(([0], (dists - xedges[0]) / dx, [Nxbin])) |
175 |
| - y = (reds - yedges[0]) / dy |
176 |
| - |
177 |
| - # Find (x,y) neighbors in bin space. |
178 |
| - x1 = np.array(np.floor(x - 0.5), dtype='int') |
179 |
| - x2 = np.array(np.ceil(x - 0.5), dtype='int') |
180 |
| - y1 = np.array(np.floor(y - 0.5), dtype='int') |
181 |
| - y2 = np.array(np.ceil(y - 0.5), dtype='int') |
182 |
| - |
183 |
| - # Threshold values to bin edges. |
184 |
| - x1[np.where(x1 < 0)] = 0 |
185 |
| - x1[np.where(x1 >= Nxbin)] = Nxbin - 1 |
186 |
| - x2[np.where(x2 < 0)] = 0 |
187 |
| - x2[np.where(x2 >= Nxbin)] = Nxbin - 1 |
188 |
| - y1[np.where(y1 < 0)] = 0 |
189 |
| - y1[np.where(y1 >= Nybin)] = Nybin - 1 |
190 |
| - y2[np.where(y2 < 0)] = 0 |
191 |
| - y2[np.where(y2 >= Nybin)] = Nybin - 1 |
192 |
| - |
193 |
| - # Threshold (x,y) to edges (and shift to deal with centers). |
194 |
| - x[np.where(x < 0.5)] = 0.5 |
195 |
| - x[np.where(x > Nxbin - 0.5)] = Nxbin - 0.5 |
196 |
| - y[np.where(y < 0.5)] = 0.5 |
197 |
| - y[np.where(y > Nybin - 0.5)] = Nybin - 0.5 |
198 |
| - |
199 |
| - # Define "left" and "right" versions for xs. |
200 |
| - x1l, x1r = x1[:-1], x1[1:] |
201 |
| - x2l, x2r = x2[:-1], x2[1:] |
202 |
| - xl, xr = x[:-1], x[1:] |
203 |
| - |
204 |
| - # Compute integral along LOS using the provided CDFs. |
205 |
| - if interpolate: |
206 |
| - # Interpolate between bins (left side). |
207 |
| - # Define values q(x_i, y_i). |
208 |
| - q11, q12, q21, q22 = (cdfs[:, x1l, y1], cdfs[:, x1l, y2], |
209 |
| - cdfs[:, x2l, y1], cdfs[:, x2l, y2]) |
210 |
| - # Compute areas. |
211 |
| - dx1, dx2 = (xl - x_ctrs[x1l]), (x_ctrs[x2l] - xl) |
212 |
| - dy1, dy2 = (y - y_ctrs[y1]), (y_ctrs[y2] - y) |
213 |
| - # Interpolate in x. |
214 |
| - qp1, qp2 = (q11 * dx2 + q21 * dx1), (q12 * dx2 + q22 * dx1) |
215 |
| - xsel = np.where(~((dx1 > 0.) & (dx2 > 0.))) # deal with edges |
216 |
| - qp1[:, xsel], qp2[:, xsel] = q11[:, xsel], q12[:, xsel] # replace |
217 |
| - # Interpolate in y. |
218 |
| - cdf_left = qp1 * dy2 + qp2 * dy1 |
219 |
| - ysel = np.where(~((dy1 > 0.) & (dy2 > 0.))) # deal with edges |
220 |
| - cdf_left[ysel] = qp1[ysel] # replace edges |
221 |
| - |
222 |
| - # Interpolate between the bins (right side). |
223 |
| - # Define values q(x_i, y_i). |
224 |
| - q11, q12, q21, q22 = (cdfs[:, x1r, y1], cdfs[:, x1r, y2], |
225 |
| - cdfs[:, x2r, y1], cdfs[:, x2r, y2]) |
226 |
| - # Compute areas. |
227 |
| - dx1, dx2 = (xr - x_ctrs[x1r]), (x_ctrs[x2r] - xr) |
228 |
| - dy1, dy2 = (y - y_ctrs[y1]), (y_ctrs[y2] - y) |
229 |
| - # Interpolate in x. |
230 |
| - qp1, qp2 = (q11 * dx2 + q21 * dx1), (q12 * dx2 + q22 * dx1) |
231 |
| - xsel = np.where(~((dx1 > 0.) & (dx2 > 0.))) # deal with edges |
232 |
| - qp1[:, xsel], qp2[:, xsel] = q11[:, xsel], q12[:, xsel] # replace |
233 |
| - # Interpolate in y. |
234 |
| - cdf_right = qp1 * dy2 + qp2 * dy1 |
235 |
| - ysel = np.where(~((dy1 > 0.) & (dy2 > 0.))) # deal with edges |
236 |
| - cdf_right[ysel] = qp1[ysel] # replace edges |
237 |
| - else: |
238 |
| - # Just use the values from the bin we're currently in. |
239 |
| - cdf_left, cdf_right = cdfs[:, x1l, y1], cdfs[:, x1r, y1] |
240 |
| - |
241 |
| - # Compute likelihood. |
242 |
| - likes = np.sum(cdf_right - cdf_left, axis=1) |
243 |
| - |
244 |
| - # Add in outlier mixture model. Assume uniform in (x, y) with `pb` weight. |
245 |
| - likes = pb * (1. / (Nybin * Nxbin)) + (1. - pb) * likes |
246 |
| - |
247 |
| - # Compute total log-likelihood. |
248 |
| - loglike = np.sum(np.log(likes)) |
249 |
| - |
250 |
| - return loglike |
251 |
| - |
252 |
| - |
253 | 121 | def LOS_clouds_loglike_samples(theta, dsamps, rsamps, kernel='gauss',
|
254 | 122 | rlims=(0., 6.), template_reds=None,
|
255 |
| - Ndraws=25): |
| 123 | + Ndraws=25, additive_foreground=False): |
256 | 124 | """
|
257 | 125 | Compute the log-likelihood for the cumulative reddening along the
|
258 | 126 | line of sight (LOS) parameterized by `theta`, given a set of input
|
@@ -293,6 +161,10 @@ def LOS_clouds_loglike_samples(theta, dsamps, rsamps, kernel='gauss',
|
293 | 161 | Ndraws : int, optional
|
294 | 162 | The number of draws to use for each star. Default is `25`.
|
295 | 163 |
|
| 164 | + additive_foreground : bool, optional |
| 165 | + Whether the foreground is treated as just another value or added |
| 166 | + to all background values. Default is `False`. |
| 167 | +
|
296 | 168 | Returns
|
297 | 169 | -------
|
298 | 170 | loglike : float
|
@@ -336,6 +208,10 @@ def LOS_clouds_loglike_samples(theta, dsamps, rsamps, kernel='gauss',
|
336 | 208 | if template_reds is not None:
|
337 | 209 | reds[1:] *= template_reds[None, :, None] # reds[1:] are rescalings
|
338 | 210 |
|
| 211 | + # Adjust reddenings after the foreground if needed. |
| 212 | + if additive_foreground: |
| 213 | + reds[1:] += reds[0] # add foreground to background |
| 214 | + |
339 | 215 | # Define kernel parameters (mean, sigma) per LOS chunk.
|
340 | 216 | kparams = np.array([(r, rsmooth) for r in reds])
|
341 | 217 | kparams[0][1] = rsmooth0
|
|
0 commit comments