plotastrodata 1.4.6__tar.gz → 1.4.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. {plotastrodata-1.4.6 → plotastrodata-1.4.7}/PKG-INFO +1 -1
  2. {plotastrodata-1.4.6 → plotastrodata-1.4.7}/plotastrodata/__init__.py +1 -1
  3. {plotastrodata-1.4.6 → plotastrodata-1.4.7}/plotastrodata/fitting_utils.py +34 -29
  4. {plotastrodata-1.4.6 → plotastrodata-1.4.7}/plotastrodata/los_utils.py +2 -2
  5. {plotastrodata-1.4.6 → plotastrodata-1.4.7}/plotastrodata.egg-info/PKG-INFO +1 -1
  6. {plotastrodata-1.4.6 → plotastrodata-1.4.7}/LICENSE +0 -0
  7. {plotastrodata-1.4.6 → plotastrodata-1.4.7}/README.md +0 -0
  8. {plotastrodata-1.4.6 → plotastrodata-1.4.7}/plotastrodata/analysis_utils.py +0 -0
  9. {plotastrodata-1.4.6 → plotastrodata-1.4.7}/plotastrodata/const_utils.py +0 -0
  10. {plotastrodata-1.4.6 → plotastrodata-1.4.7}/plotastrodata/coord_utils.py +0 -0
  11. {plotastrodata-1.4.6 → plotastrodata-1.4.7}/plotastrodata/ext_utils.py +0 -0
  12. {plotastrodata-1.4.6 → plotastrodata-1.4.7}/plotastrodata/fft_utils.py +0 -0
  13. {plotastrodata-1.4.6 → plotastrodata-1.4.7}/plotastrodata/fits_utils.py +0 -0
  14. {plotastrodata-1.4.6 → plotastrodata-1.4.7}/plotastrodata/matrix_utils.py +0 -0
  15. {plotastrodata-1.4.6 → plotastrodata-1.4.7}/plotastrodata/other_utils.py +0 -0
  16. {plotastrodata-1.4.6 → plotastrodata-1.4.7}/plotastrodata/plot_utils.py +0 -0
  17. {plotastrodata-1.4.6 → plotastrodata-1.4.7}/plotastrodata.egg-info/SOURCES.txt +0 -0
  18. {plotastrodata-1.4.6 → plotastrodata-1.4.7}/plotastrodata.egg-info/dependency_links.txt +0 -0
  19. {plotastrodata-1.4.6 → plotastrodata-1.4.7}/plotastrodata.egg-info/not-zip-safe +0 -0
  20. {plotastrodata-1.4.6 → plotastrodata-1.4.7}/plotastrodata.egg-info/requires.txt +0 -0
  21. {plotastrodata-1.4.6 → plotastrodata-1.4.7}/plotastrodata.egg-info/top_level.txt +0 -0
  22. {plotastrodata-1.4.6 → plotastrodata-1.4.7}/setup.cfg +0 -0
  23. {plotastrodata-1.4.6 → plotastrodata-1.4.7}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: plotastrodata
3
- Version: 1.4.6
3
+ Version: 1.4.7
4
4
  Summary: plotastrodata is a tool for astronomers to create figures from FITS files and perform fundamental data analyses with ease.
5
5
  Home-page: https://github.com/yusukeaso-astron/plotastrodata
6
6
  Download-URL: https://github.com/yusukeaso-astron/plotastrodata
@@ -1,4 +1,4 @@
1
1
  import warnings
2
2
 
3
3
  warnings.simplefilter('ignore', UserWarning)
4
- __version__ = '1.4.6'
4
+ __version__ = '1.4.7'
@@ -25,7 +25,7 @@ def logp(x: np.ndarray) -> float:
25
25
  """
26
26
  if global_progressbar:
27
27
  bar.update(1)
28
- if np.all((global_bounds[0] < x) & (x < global_bounds[1])):
28
+ if np.all((global_bounds[:, 0] < x) & (x < global_bounds[:, 1])):
29
29
  return 0
30
30
  else:
31
31
  return -np.inf
@@ -42,7 +42,7 @@ class EmceeCorner():
42
42
  """Make bounds, logl, and logp for ptemcee.
43
43
 
44
44
  Args:
45
- bounds (np.ndarray): Bounds for ptemcee in the shape of (2, dim).
45
+ bounds (np.ndarray): Bounds for ptemcee in the shape of (dim, 2).
46
46
  logl (function, optional): Log likelihood for ptemcee. Defaults to None.
47
47
  model (function, optional): Model function to make a log likelihood function. Defaults to None.
48
48
  xdata (np.ndarray, optional): Input for the model function. Defaults to None.
@@ -52,13 +52,17 @@ class EmceeCorner():
52
52
  percent (list, optional): The lower and upper percnetiles to be calculated. Defaults to [16, 84].
53
53
  """
54
54
  global global_bounds, global_progressbar
55
- global_bounds = np.array(bounds) if len(bounds) < 3 else np.transpose(bounds)
55
+ if len(bounds[0]) > 3:
56
+ global_bounds = np.transpose(bounds)
57
+ print('bounds has been transposed because its shape is (2, dim).')
58
+ else:
59
+ global_bounds = np.array(bounds)
56
60
  global_progressbar = progressbar
57
61
  if logl is None and not (None in [model, xdata, ydata]):
58
62
  def logl(x: np.ndarray) -> float:
59
63
  return np.sum((ydata - model(xdata, *x))**2 / sigma**2) / (-2)
60
64
  self.bounds = global_bounds
61
- self.dim = len(self.bounds[0])
65
+ self.dim = len(self.bounds)
62
66
  self.logl = logl
63
67
  self.logp = logp
64
68
  self.percent = percent
@@ -99,7 +103,8 @@ class EmceeCorner():
99
103
  i += 1
100
104
  if pos0 is None:
101
105
  pos0 = np.random.rand(ntemps, nwalkers, self.dim) \
102
- * (self.bounds[1] - self.bounds[0]) + self.bounds[0]
106
+ * (self.bounds[:, 1] - self.bounds[:, 0]) \
107
+ + self.bounds[:, 0]
103
108
  if not pt:
104
109
  pos0 = pos0[0]
105
110
  if pt:
@@ -112,7 +117,7 @@ class EmceeCorner():
112
117
  else:
113
118
  sampler = ptemcee.Sampler(**pars)
114
119
  sampler.run_mcmc(pos0, nsteps)
115
- samples = sampler.chain[0, :, nburnin:, :] # temperature, walker, step, dim
120
+ samples = sampler.chain[0, :, nburnin:, :] # temperatures, walkers, steps, dim
116
121
  else:
117
122
  if ncores > 1:
118
123
  print('Use logl as log_prob_fn to avoid function-in-function.')
@@ -130,7 +135,7 @@ class EmceeCorner():
130
135
  else:
131
136
  sampler = emcee.EnsembleSampler(**pars)
132
137
  sampler.run_mcmc(pos0, nsteps)
133
- samples = sampler.chain[:, nburnin:, :] # walker, step, dim
138
+ samples = sampler.chain[:, nburnin:, :] # walkers, steps, dim
134
139
  if grcheck:
135
140
  # Gelman-Rubin statistics #
136
141
  B = np.std(np.mean(samples, axis=1), axis=0)
@@ -165,7 +170,7 @@ class EmceeCorner():
165
170
  print('')
166
171
 
167
172
  def plotcorner(self, show: bool = False,
168
- savefig: str | None = None, labels: list[float] | None = None,
173
+ savefig: str | None = None, labels: list[str] | None = None,
169
174
  cornerrange: list[float] | None = None) -> None:
170
175
  """Make the corner plot from self.samples.
171
176
 
@@ -178,7 +183,7 @@ class EmceeCorner():
178
183
  if labels is None:
179
184
  labels = [f'Par {i:d}' for i in range(self.dim)]
180
185
  if cornerrange is None:
181
- cornerrange = np.transpose(self.bounds)
186
+ cornerrange = self.bounds
182
187
  corner.corner(np.reshape(self.samples, (-1, self.dim)), truths=self.popt,
183
188
  quantiles=[self.percent[0] / 100, 0.5, self.percent[1] / 100],
184
189
  show_titles=True, labels=labels, range=cornerrange)
@@ -190,7 +195,7 @@ class EmceeCorner():
190
195
 
191
196
  def plotchain(self, show: bool = False, savefig: str = None,
192
197
  labels: list = None, ylim: list = None):
193
- """Plot parameters as a function of steps using self.samples.
198
+ """Plot parameters as a function of steps using self.samples. This method plots nine lines: percent[0], 50%, percent[1] percentiles (over the steps by 1% binning) of percent[0], 50%, percent[1] percentiles (over the walkers).
194
199
 
195
200
  Args:
196
201
  show (bool, optional): Whether to show the chain plot. Defaults to False.
@@ -201,18 +206,18 @@ class EmceeCorner():
201
206
  if labels is None:
202
207
  labels = [f'Par {i:d}' for i in range(self.dim)]
203
208
  if ylim is None:
204
- ylim = np.transpose(self.bounds)
209
+ ylim = self.bounds
205
210
  fig = plt.figure(figsize=(4, 2 * self.dim))
206
211
  x = np.arange(np.shape(self.samples)[1])
207
212
  naverage = max(1, len(x) // 100)
208
213
  nend = len(x) - len(x) % 100 if naverage > 1 else len(x)
209
214
  x = x[:nend:naverage]
210
215
  for i in range(self.dim):
211
- y = self.samples[:, :, i]
216
+ y = self.samples[:, :, i] # walkers, steps, dim
212
217
  plist = [self.percent[0], 50, self.percent[1]]
213
- y = [np.percentile(y, p, axis=0) for p in plist]
218
+ y = [np.percentile(y, p, axis=0) for p in plist] # percent over the walkers, steps
214
219
  y = [[np.percentile(np.reshape(yy[:nend], (naverage, -1)), p, axis=0)
215
- for p in plist] for yy in y]
220
+ for p in plist] for yy in y] # percent over the walkers, percent over the steps
216
221
  ax = fig.add_subplot(self.dim, 1, i + 1)
217
222
  for yy, l, c in zip(y, [1, 2, 1], ['c', 'b', 'c']):
218
223
  for yyy, w in zip(yy, [0.25, 1, 0.25]):
@@ -244,7 +249,7 @@ class EmceeCorner():
244
249
  if type(log) is bool:
245
250
  log = [log] * self.dim
246
251
  pargrid = []
247
- for a, b, c, d in zip(*global_bounds, ngrid, log):
252
+ for a, b, c, d in zip(self.bounds[:, 0], self.bounds[:, 1], ngrid, log):
248
253
  pargrid.append(np.geomspace(a, b, c) if d else np.linspace(a, b, c))
249
254
  p = np.exp(self.logl(np.meshgrid(*pargrid[::-1], indexing='ij')[::-1]))
250
255
  p[p < pcut] = 0
@@ -260,8 +265,6 @@ class EmceeCorner():
260
265
  axlist = [tuple(np.delete(adim, i)) for i in adim[::-1]] # adim[::-1] is becuase the 0th parameter is the innermost axis.
261
266
  p1d = [np.sum(p * vol, axis=a) / np.sum(vol, axis=a) for a in axlist]
262
267
  evidence = np.sum(p * vol) / np.sum(vol)
263
- p1dcum = [np.cumsum(q * w) / np.transpose([np.sum(q * w)])
264
- for q, w in zip(p1d, dpar)]
265
268
  if np.all(p == 0):
266
269
  print('All posterior is below pcut.')
267
270
  self.popt = np.full(self.dim, np.nan)
@@ -269,16 +272,17 @@ class EmceeCorner():
269
272
  self.pmid = np.full(self.dim, np.nan)
270
273
  self.phigh = np.full(self.dim, np.nan)
271
274
  else:
272
- iopt = np.unravel_index(np.argmax(p), np.shape(p))[::-1]
273
- self.popt = [t[i] for t, i in zip(pargrid, iopt)]
275
+ i_max = np.unravel_index(np.argmax(p), np.shape(p))[::-1]
276
+ self.popt = np.array([p[i] for p, i in zip(pargrid, i_max)])
274
277
 
275
278
  def getpercentile(percent: float):
276
- idxmin = [np.argmin(np.abs(q - percent)) for q in p1dcum]
277
- return np.array([t[i] for t, i in zip(pargrid, idxmin)])
279
+ a = [np.percentile(g, percent, method='inverted_cdf', weights=p)
280
+ for g, p in zip(pargrid, p1d)]
281
+ return np.array(a)
278
282
 
279
- self.plow = getpercentile(self.percent[0] / 100)
280
- self.pmid = getpercentile(0.5)
281
- self.phigh = getpercentile(self.percent[1] / 100)
283
+ self.plow = getpercentile(self.percent[0])
284
+ self.pmid = getpercentile(50)
285
+ self.phigh = getpercentile(self.percent[1])
282
286
  self.p = p
283
287
  self.p1d = p1d
284
288
  self.pargrid = pargrid
@@ -287,7 +291,7 @@ class EmceeCorner():
287
291
 
288
292
  def plotongrid(self, show: bool = False, savefig: str | None = None,
289
293
  labels: list[str] = None, cornerrange: list[float] = None,
290
- cmap: str = 'binary', levels: list[float] = [0.001, 0.01, 0.1]) -> None:
294
+ cmap: str = 'binary', levels: list[float] = [0.011109, 0.135335, 0.606531]) -> None:
291
295
  """Make the corner plot from the posterior calculated on a grid.
292
296
 
293
297
  Args:
@@ -296,13 +300,13 @@ class EmceeCorner():
296
300
  labels (list, optional): Labels for the corner plot. Defaults to None.
297
301
  cornerrange (list, optional): Range for the corner plot. Defaults to None.
298
302
  cmap: (str, optional): cmap for matplotlib.pyplot.plt.pcolormesh(). Defaults to 'binary'.
299
- levels: (list, optional): levels for matplotlib.pyplot.plt.contour() relative to the peak. Defaults to [0.001, 0.01, 0.1].
303
+ levels: (list, optional): levels for matplotlib.pyplot.plt.contour() relative to the peak. Defaults to [exp(-0.5*3^2), exp(-0.5*2^2), exp(-0.5*1^2)].
300
304
  """
301
305
  adim = np.arange(self.dim)
302
306
  if labels is None:
303
307
  labels = [f'Par {i:d}' for i in adim]
304
308
  if cornerrange is None:
305
- cornerrange = np.transpose(self.bounds)
309
+ cornerrange = self.bounds
306
310
  x = self.pargrid
307
311
  y = self.p1d
308
312
  fig = plt.figure(figsize=(2 * self.dim * 1.2, 2 * self.dim))
@@ -322,7 +326,7 @@ class EmceeCorner():
322
326
  s2 = '_{-' + f'{s2:.2f}' + '}'
323
327
  s0 = s0 + s1 + s2
324
328
  ax[k] = fig.add_subplot(self.dim, self.dim, k + 1)
325
- ax[k].plot(x[i], y[i], 'k-')
329
+ ax[k].plot(x[i], y[i], 'k-', drawstyle='steps-mid')
326
330
  ax[k].axvline(self.popt[i])
327
331
  ax[k].axvline(self.plow[i], linestyle='--', color='k')
328
332
  ax[k].axvline(self.pmid[i], linestyle='--', color='k')
@@ -371,7 +375,7 @@ class EmceeCorner():
371
375
  """Calculate the Bayesian evidence for a model using dynamic nested sampling through dynesty.
372
376
  """
373
377
  def prior_transform(u):
374
- return self.bounds[0] + (self.bounds[1] - self.bounds[0]) * u
378
+ return self.bounds[:, 0] + (self.bounds[:, 1] - self.bounds[:, 0]) * u
375
379
  dsampler = DNS(loglikelihood=self.logl,
376
380
  prior_transform=prior_transform,
377
381
  ndim=self.dim, **kwargs)
@@ -379,4 +383,5 @@ class EmceeCorner():
379
383
  results = dsampler.results
380
384
  evidence = np.exp(results.logz[-1])
381
385
  error = evidence * results.logzerr[-1]
386
+ self.evidence = evidence
382
387
  return {'evidence': evidence, 'error': error}
@@ -12,7 +12,7 @@ def obs2sys(xobs: np.ndarray, yobs: np.ndarray, zobs: np.ndarray,
12
12
  xobs (np.ndarray): Observed x-coordinates. The distance to the east.
13
13
  yobs (np.ndarray): Observed y-coordinates. The distance to the north.
14
14
  zobs (np.ndarray): Observed z-coordinates. The line-of-sight distance.
15
- pa (float, optional): Position angle of the system in degrees from yobs (north) to xobs (east). Defaults to 0.
15
+ pa (float, optional): Position angle of the "blueshifted outflow" (not the disk major axis) in degrees from yobs (north) to xobs (east). Defaults to 0.
16
16
  incl (float, optional): Inclination of the system in degrees. i=0 means face-on. Defaults to 0.
17
17
  phi0 (float, optional): Azimuthal angle of the system in degrees, relative to the system that is observed. Defaults to 0.
18
18
  theta0 (float, optional): Polar angle of the x-axis of the system in degrees, relative to the x-axis of the system that is observed. Defaults to pi/2.
@@ -47,7 +47,7 @@ def sys2obs(xsys: np.ndarray, ysys: np.ndarray, zsys: np.ndarray,
47
47
  xsys (np.ndarray): System x-coordinates (or r).
48
48
  ysys (np.ndarray): System y-coordinates (or theta).
49
49
  zsys (np.ndarray): System z-coordinates (or phi).
50
- pa (float, optional): Position angle of the system in degrees from yobs (north) to xobs (east). Defaults to 0.
50
+ pa (float, optional): Position angle of the "blueshifted outflow" (not the disk major axis) in degrees from yobs (north) to xobs (east). Defaults to 0.
51
51
  incl (float, optional): Inclination of the system in degrees. i=0 means face-on. Defaults to 0.
52
52
  phi0 (float, optional): Azimuthal angle of the system in degrees, relative to the system that is observed. Defaults to 0.
53
53
  theta0 (float, optional): Polar angle of the x-axis of the system in degrees, relative to the x-axis of the system that is observed. Defaults to pi/2.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: plotastrodata
3
- Version: 1.4.6
3
+ Version: 1.4.7
4
4
  Summary: plotastrodata is a tool for astronomers to create figures from FITS files and perform fundamental data analyses with ease.
5
5
  Home-page: https://github.com/yusukeaso-astron/plotastrodata
6
6
  Download-URL: https://github.com/yusukeaso-astron/plotastrodata
File without changes
File without changes
File without changes
File without changes