PyTransit 2.9.2__py3-none-any.whl → 2.10.0__py3-none-any.whl

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.
pytransit/__init__.py CHANGED
@@ -41,7 +41,10 @@ Date
41
41
 
42
42
  """
43
43
 
44
- __version__ = '2.9.2'
44
+ try:
45
+ from ._version import version as __version__
46
+ except ImportError:
47
+ __version__ = '0+unknown'
45
48
 
46
49
  # Generic
47
50
  # -------
pytransit/_version.py ADDED
@@ -0,0 +1,24 @@
1
+ # file generated by vcs-versioning
2
+ # don't change, don't track in version control
3
+ from __future__ import annotations
4
+
5
+ __all__ = [
6
+ "__version__",
7
+ "__version_tuple__",
8
+ "version",
9
+ "version_tuple",
10
+ "__commit_id__",
11
+ "commit_id",
12
+ ]
13
+
14
+ version: str
15
+ __version__: str
16
+ __version_tuple__: tuple[int | str, ...]
17
+ version_tuple: tuple[int | str, ...]
18
+ commit_id: str | None
19
+ __commit_id__: str | None
20
+
21
+ __version__ = version = '2.10.0'
22
+ __version_tuple__ = version_tuple = (2, 10, 0)
23
+
24
+ __commit_id__ = commit_id = 'gd00e4aa7f'
pytransit/lpf/lpf.py CHANGED
@@ -505,7 +505,7 @@ class BaseLPF(LogPosteriorFunction):
505
505
  self._additional_log_priors.append(T14)
506
506
 
507
507
  def add_as_prior(self, mean: float, std: float) -> None:
508
- """Add a normal prior on the scaled semi-major axis :math:`(a / R_\star)`.
508
+ r"""Add a normal prior on the scaled semi-major axis :math:`(a / R_\star)`.
509
509
 
510
510
  Parameters
511
511
  ----------
@@ -2,7 +2,7 @@ from numba import njit
2
2
  from typing import Optional
3
3
 
4
4
  from numpy import (sqrt, sin, arctan2, pi, nan, zeros, floor, arccos, linspace, ndarray, atleast_1d,
5
- atleast_2d, asarray, full, empty, concatenate, array, broadcast_to)
5
+ atleast_2d, asarray, full, empty, concatenate, array, broadcast_to, int64)
6
6
  from numpy.polynomial import Polynomial
7
7
  from scipy.special import roots_jacobi, roots_legendre
8
8
 
@@ -578,6 +578,72 @@ def ldm_table(mu: ndarray, wf: ndarray, t0: float, dt: float, ldp: ndarray, out:
578
578
  out[ig] = num / den
579
579
 
580
580
 
581
+ @njit(fastmath=True)
582
+ def ldm_table_map(mu: ndarray, wf: ndarray, t0: float, dt: float, nmu: int):
583
+ """The linear map from a tabulated profile to the mean intensity table.
584
+
585
+ `ldm_table` is linear in the profile, and its nodes, weights, and interpolation stencils depend
586
+ only on the planet, so the map can be built once and applied to any number of profiles with
587
+ `ldm_table_banded`. This is what lets the spectroscopy model share the work between its
588
+ wavelength bins.
589
+
590
+ Each table node only reads the profile across the planet, so its row of the map is nonzero in a
591
+ narrow band. Returns the ``(ng, nmu)`` map and, for every row, the first and one-past-the-last
592
+ nonzero column.
593
+ """
594
+ ng, nn = mu.shape
595
+ wt = zeros((ng, nmu))
596
+ lo = empty(ng, dtype=int64)
597
+ hi = empty(ng, dtype=int64)
598
+ for ig in range(ng):
599
+ den = 0.0
600
+ for q in range(nn):
601
+ den += wf[ig, q]
602
+ for q in range(nn):
603
+ w = wf[ig, q]
604
+ if w == 0.0:
605
+ continue
606
+ w /= den
607
+ x = (sqrt(mu[ig, q]) - t0) / dt
608
+ if x <= 0.0:
609
+ wt[ig, 0] += w
610
+ elif x >= nmu - 1:
611
+ wt[ig, nmu - 1] += w
612
+ else:
613
+ i = int(x) - 1
614
+ if i < 0:
615
+ i = 0
616
+ elif i > nmu - 4:
617
+ i = nmu - 4
618
+ u = x - i
619
+ wt[ig, i] -= w * (u - 1) * (u - 2) * (u - 3) / 6.0
620
+ wt[ig, i + 1] += w * u * (u - 2) * (u - 3) / 2.0
621
+ wt[ig, i + 2] -= w * u * (u - 1) * (u - 3) / 2.0
622
+ wt[ig, i + 3] += w * u * (u - 1) * (u - 2) / 6.0
623
+
624
+ lo[ig] = 0
625
+ while lo[ig] < nmu - 1 and wt[ig, lo[ig]] == 0.0:
626
+ lo[ig] += 1
627
+ hi[ig] = nmu
628
+ while hi[ig] > lo[ig] + 1 and wt[ig, hi[ig] - 1] == 0.0:
629
+ hi[ig] -= 1
630
+ return wt, lo, hi
631
+
632
+
633
+ @njit(fastmath=True)
634
+ def ldm_table_banded(wt: ndarray, lo: ndarray, hi: ndarray, ldp: ndarray, scale: float, out: ndarray) -> None:
635
+ """The mean intensity table of one profile from the banded map of `ldm_table_map`, times `scale`."""
636
+ for ig in range(wt.shape[0]):
637
+ # Slicing the band first lets the loop index start from zero, which numba needs to drop its
638
+ # negative index check and vectorise the sum.
639
+ w = wt[ig, lo[ig]:hi[ig]]
640
+ p = ldp[lo[ig]:hi[ig]]
641
+ s = 0.0
642
+ for j in range(w.size):
643
+ s += w[j] * p[j]
644
+ out[ig] = scale * s
645
+
646
+
581
647
  def _cubic_matrices() -> ndarray:
582
648
  """Maps from four stencil values to the cubic's coefficients in the local interval variable.
583
649
 
@@ -608,8 +674,15 @@ def cubic_coefficients(tab: ndarray) -> ndarray:
608
674
  Lagrange interpolant on a stencil shifted inwards at the ends, so the interpolation is fourth
609
675
  order everywhere including the first and last intervals.
610
676
  """
677
+ c = zeros((tab.size - 1, 4))
678
+ cubic_coefficients_into(tab, c)
679
+ return c
680
+
681
+
682
+ @njit(fastmath=True)
683
+ def cubic_coefficients_into(tab: ndarray, out: ndarray) -> None:
684
+ """`cubic_coefficients` written into `out`, which has ``tab.size - 1`` rows."""
611
685
  n = tab.size
612
- c = zeros((n - 1, 4))
613
686
  for i in range(n - 1):
614
687
  j = i - 1
615
688
  if j < 0:
@@ -618,17 +691,16 @@ def cubic_coefficients(tab: ndarray) -> ndarray:
618
691
  j = n - 4
619
692
  s = i - j
620
693
  for r in range(4):
621
- c[i, r] = (CUBIC_MATRICES[s, r, 0] * tab[j] + CUBIC_MATRICES[s, r, 1] * tab[j + 1]
622
- + CUBIC_MATRICES[s, r, 2] * tab[j + 2] + CUBIC_MATRICES[s, r, 3] * tab[j + 3])
623
- return c
694
+ out[i, r] = (CUBIC_MATRICES[s, r, 0] * tab[j] + CUBIC_MATRICES[s, r, 1] * tab[j + 1]
695
+ + CUBIC_MATRICES[s, r, 2] * tab[j + 2] + CUBIC_MATRICES[s, r, 3] * tab[j + 3])
624
696
 
625
697
 
626
698
  @njit(fastmath=True)
627
- def ldm_lookup(g: float, gc: float, n1: int, coef: ndarray) -> float:
628
- """The mean intensity under the planet at grazing parameter g from the split cubic table.
699
+ def ldm_interval(g: float, gc: float, n1: int, nc: int):
700
+ """The interval of the split cubic table holding grazing parameter g, and g's position in it.
629
701
 
630
- `coef` holds the interval coefficients of both segments back to back: ``n1 - 1`` intervals
631
- covering [0, gc] and the rest covering [gc, 1].
702
+ `nc` is the number of intervals in the table. Returns the interval index and the local
703
+ position in [0, 1) that `ldm_lookup` evaluates the interval's cubic at.
632
704
  """
633
705
  if g < gc:
634
706
  x = g / gc * (n1 - 1)
@@ -636,14 +708,24 @@ def ldm_lookup(g: float, gc: float, n1: int, coef: ndarray) -> float:
636
708
  if i > n1 - 2:
637
709
  i = n1 - 2
638
710
  else:
639
- n2 = coef.shape[0] - (n1 - 1) + 1
711
+ n2 = nc - (n1 - 1) + 1
640
712
  x = (g - gc) / (1.0 - gc) * (n2 - 1)
641
713
  i = int(x)
642
714
  if i > n2 - 2:
643
715
  i = n2 - 2
644
716
  x += n1 - 1
645
717
  i += n1 - 1
646
- a = x - i
718
+ return i, x - i
719
+
720
+
721
+ @njit(fastmath=True)
722
+ def ldm_lookup(g: float, gc: float, n1: int, coef: ndarray) -> float:
723
+ """The mean intensity under the planet at grazing parameter g from the split cubic table.
724
+
725
+ `coef` holds the interval coefficients of both segments back to back: ``n1 - 1`` intervals
726
+ covering [0, gc] and the rest covering [gc, 1].
727
+ """
728
+ i, a = ldm_interval(g, gc, n1, coef.shape[0])
647
729
  return coef[i, 0] + a * (coef[i, 1] + a * (coef[i, 2] + a * coef[i, 3]))
648
730
 
649
731
 
@@ -657,5 +739,5 @@ def split_cubic_coefficients(tab: ndarray, n1: int, out: ndarray) -> None:
657
739
  """
658
740
  # The split node is stored twice, once as the last node of the first segment and once as
659
741
  # the first node of the second, so the second segment starts at index n1.
660
- out[:n1 - 1] = cubic_coefficients(tab[:n1])
661
- out[n1 - 1:] = cubic_coefficients(tab[n1:])
742
+ cubic_coefficients_into(tab[:n1], out[:n1 - 1])
743
+ cubic_coefficients_into(tab[n1:], out[n1 - 1:])
@@ -1,19 +1,68 @@
1
- from math import fabs, floor
1
+ from math import floor
2
2
 
3
3
  from meepmeep.backends.numba.point2d import sep_c, solve2d, bounding_box
4
4
  from numba import njit, prange, get_num_threads, set_num_threads
5
- from numpy import zeros, dot, ndarray, isnan, nan, mean, floor, fabs, max, empty
5
+ from numpy import zeros, ndarray, isnan, nan, mean, max, empty, int64
6
6
 
7
- from .common import (g_nodes, ldm_nodes, ldm_table, split_cubic_coefficients, split_point, ldm_lookup,
8
- valid_radius_ratios)
7
+ from .common import (g_nodes, ldm_nodes, ldm_table_map, ldm_table_banded, split_cubic_coefficients, split_point,
8
+ ldm_interval, valid_radius_ratios)
9
9
  from .common import circle_circle_intersection_area_kite as ccia
10
10
 
11
11
 
12
- @njit(parallel=False, fastmath=False)
13
- def tsmodel_serial(times: ndarray,
14
- k: ndarray, t0: ndarray, p: ndarray, a: ndarray, i: ndarray, e: ndarray, w: ndarray,
15
- nsamples: ndarray, exptimes: ndarray, ldp: ndarray, istar: ndarray,
16
- pt0: float, pdt: float, rules: ndarray, ng: int) -> ndarray:
12
+ @njit(fastmath=False)
13
+ def transit_samples(times: ndarray, t0: float, p: float, xyc: ndarray, k: float, kmax: float,
14
+ gc: float, n1: int, nc: int, nsamples: int, exptime: float,
15
+ interval: ndarray, ipts: ndarray, basis: ndarray, area: ndarray) -> int:
16
+ """The geometry of every exposure sample that overlaps the star, shared by all the wavelength bins.
17
+
18
+ For each overlapping sample, stores its exposure index, the mean intensity table interval it
19
+ falls in, the cubic basis ``(a, a**2, a**3)`` at its position in that interval, and the three
20
+ overlap area terms the bins combine as ``area[0] + area[1] * (k / k_mean)**2 + area[2] * (k - k_mean)``.
21
+ The area terms are divided by the number of samples, so the bins can sum the samples directly.
22
+
23
+ Returns the number of overlapping samples.
24
+ """
25
+ bt1, bt4 = bounding_box(k, xyc)
26
+ bt1 -= 0.0015 + exptime
27
+ bt4 += 0.0015 + exptime
28
+
29
+ n = 0
30
+ for ipt in range(times.size):
31
+ epoch = floor((times[ipt] - t0 + 0.5 * p) / p)
32
+ tc = times[ipt] - (t0 + epoch * p)
33
+ if not (bt1 <= tc <= bt4):
34
+ continue
35
+ for isample in range(1, nsamples + 1):
36
+ z = sep_c(tc + exptime * ((isample - 0.5) / nsamples - 0.5), xyc)
37
+ ap0, kappa = ccia(1.0, k, z)
38
+ dadk = 2.0 * k * kappa
39
+ if ap0 == 0.0 and dadk == 0.0:
40
+ continue
41
+ i, a = ldm_interval(z / (1.0 + k), gc, n1, nc)
42
+ ipts[n] = ipt
43
+ interval[n] = i
44
+ basis[n, 0] = a
45
+ basis[n, 1] = a * a
46
+ basis[n, 2] = a * a * a
47
+
48
+ # The area is exact while the planet is fully on the disk, and linear in k - k_mean across the limb.
49
+ if z <= 1.0 - kmax:
50
+ area[n, 0] = 0.0
51
+ area[n, 1] = ap0 / nsamples
52
+ area[n, 2] = 0.0
53
+ else:
54
+ area[n, 0] = ap0 / nsamples
55
+ area[n, 1] = 0.0
56
+ area[n, 2] = dadk / nsamples
57
+ n += 1
58
+ return n
59
+
60
+
61
+ def _tsmodel(times: ndarray,
62
+ k: ndarray, t0: ndarray, p: ndarray, a: ndarray, i: ndarray, e: ndarray, w: ndarray,
63
+ nsamples: ndarray, exptimes: ndarray, ldp: ndarray, istar: ndarray,
64
+ pt0: float, pdt: float, rules: ndarray, ng: int) -> ndarray:
65
+ """The transmission spectroscopy model. Compiled both serially and in parallel over the wavelength bins."""
17
66
  if k.ndim != 2:
18
67
  raise ValueError(" The radius ratios must be given as a 2D array with shape (npv, npb)")
19
68
 
@@ -26,15 +75,22 @@ def tsmodel_serial(times: ndarray,
26
75
  npt = times.size
27
76
  npv = k.shape[0]
28
77
  npb = k.shape[1]
78
+ nmu = ldp.shape[2]
79
+ ns = nsamples[0]
80
+ nc = ng - 2 # Number of intervals in the split mean intensity table
29
81
 
30
-
31
- flux = zeros((npv, npb, npt)) # Model flux
82
+ flux = empty((npv, npb, npt)) # Model flux
32
83
  nq = rules.shape[2]
33
- coef = zeros((npb, ng - 2, 4)) # Split cubic coefficients of the mean intensity tables
84
+ tables = empty((npb, ng)) # Mean intensity tables
85
+ coef = empty((npb, nc, 4)) # Split cubic coefficients of the mean intensity tables
34
86
  mu = empty((ng, 2 * nq))
35
87
  wf = zeros((ng, 2 * nq))
36
- ldm = empty(ng)
37
- xyc = zeros((2, 5)) # Taylor series coefficients for the (x, y) position
88
+
89
+ # Geometry of the overlapping exposure samples
90
+ ipts = empty(npt * ns, dtype=int64)
91
+ interval = empty(npt * ns, dtype=int64)
92
+ basis = empty((npt * ns, 3))
93
+ area = empty((npt * ns, 3))
38
94
 
39
95
  for ipv in range(npv):
40
96
  if isnan(a[ipv]) or (a[ipv] <= 1.0) or (e[ipv] < 0.0) or not valid_radius_ratios(k[ipv]):
@@ -44,141 +100,55 @@ def tsmodel_serial(times: ndarray,
44
100
  kmean = mean(k[ipv])
45
101
  kmax = max(k[ipv])
46
102
  afac = k[ipv] ** 2 / kmean ** 2
103
+ dk = k[ipv] - kmean
47
104
 
48
105
  # -----------------------------------#
49
106
  # Calculate the limb darkening means #
50
107
  # -----------------------------------#
108
+ # The table is linear in the profile, so the map from a profile to its table is built once
109
+ # and applied to every bin. Dividing by the stellar intensity here saves a division per bin
110
+ # and exposure later.
51
111
  gs, n1 = g_nodes(kmean, ng)
52
112
  gc = split_point(kmean)
53
113
  ldm_nodes(kmean, gs, rules, mu, wf)
54
- for ipb in range(npb):
55
- ldm_table(mu, wf, pt0, pdt, ldp[ipv, ipb, :], ldm)
56
- split_cubic_coefficients(ldm, n1, coef[ipb])
57
-
58
- # -----------------------------------------------------#
59
- # Calculate the Taylor series expansions for the orbit #
60
- # -----------------------------------------------------#
61
- xyc[:, :] = solve2d(0.0, p[ipv], a[ipv], i[ipv], e[ipv], w[ipv])
114
+ wt, lo, hi = ldm_table_map(mu, wf, pt0, pdt, nmu)
115
+ for ipb in prange(npb):
116
+ ldm_table_banded(wt, lo, hi, ldp[ipv, ipb], 1.0 / istar[ipv, ipb], tables[ipb])
117
+ split_cubic_coefficients(tables[ipb], n1, coef[ipb])
118
+
119
+ # ------------------------------------------#
120
+ # Calculate the geometry shared by the bins #
121
+ # ------------------------------------------#
122
+ xyc = solve2d(0.0, p[ipv], a[ipv], i[ipv], e[ipv], w[ipv])
123
+ nsm = transit_samples(times, t0[ipv], p[ipv], xyc, kmean, kmax, gc, n1, nc, ns, exptimes[0],
124
+ interval, ipts, basis, area)
62
125
 
63
126
  # ---------------------------#
64
- # Calculate the bounding box #
127
+ # Calculate the light curves #
65
128
  # ---------------------------#
66
- bt1, bt4 = bounding_box(kmean, xyc)
67
- bt1 -= 0.0015 + exptimes[0]
68
- bt4 += 0.0015 + exptimes[0]
69
-
70
- # --------------------------#
71
- # Calculate the light curve #
72
- # --------------------------#
73
- for ipt in range(npt):
74
- epoch = floor((times[ipt] - t0[ipv] + 0.5 * p[ipv]) / p[ipv])
75
- tc = times[ipt] - (t0[ipv] + epoch * p[ipv])
76
- if not (bt1 <= tc <= bt4):
77
- flux[ipv, :, ipt] = 1.0
78
- else:
79
- for isample in range(1, nsamples[0] + 1):
80
- time_offset = exptimes[0] * ((isample - 0.5) / nsamples[0] - 0.5)
81
- z = sep_c(tc + time_offset, xyc)
82
- ap0, kappa = ccia(1.0, kmean, z)
83
- dadk = 2.0*kmean*kappa
84
- if z <= 1.0 - kmax:
85
- for ipb in range(npb):
86
- iplanet = ldm_lookup(z / (1.0 + kmean), gc, n1, coef[ipb])
87
- flux[ipv, ipb, ipt] += (istar[ipv, ipb] - iplanet * ap0 * afac[ipb]) / istar[ipv, ipb]
88
- else:
89
- for ipb in range(npb):
90
- iplanet = ldm_lookup(z / (1.0 + kmean), gc, n1, coef[ipb])
91
- flux[ipv, ipb, ipt] += (istar[ipv, ipb] - iplanet * (ap0 + (k[ipv, ipb]-kmean)*dadk)) / istar[ipv, ipb]
92
- flux[ipv, :, ipt] /= nsamples[0]
129
+ for ipb in prange(npb):
130
+ f = flux[ipv, ipb]
131
+ c = coef[ipb]
132
+ f[:] = 1.0
133
+ for s in range(nsm):
134
+ ci = c[interval[s]]
135
+ iplanet = ci[0] + basis[s, 0] * ci[1] + basis[s, 1] * ci[2] + basis[s, 2] * ci[3]
136
+ f[ipts[s]] -= iplanet * (area[s, 0] + area[s, 1] * afac[ipb] + area[s, 2] * dk[ipb])
93
137
  return flux
94
138
 
95
139
 
96
- @njit(parallel=True, fastmath=False)
97
- def tsmodel_parallel(times: ndarray,
98
- k: ndarray, t0: ndarray, p: ndarray, a: ndarray, i: ndarray, e: ndarray, w: ndarray,
99
- nsamples: ndarray, exptimes: ndarray, ldp: ndarray, istar: ndarray,
100
- pt0: float, pdt: float, rules: ndarray, ng: int,
101
- nthreads: int) -> ndarray:
140
+ tsmodel_serial = njit(parallel=False, fastmath=False)(_tsmodel)
141
+ _tsmodel_parallel = njit(parallel=True, fastmath=False)(_tsmodel)
142
+
102
143
 
144
+ @njit
145
+ def tsmodel_parallel(times: ndarray,
146
+ k: ndarray, t0: ndarray, p: ndarray, a: ndarray, i: ndarray, e: ndarray, w: ndarray,
147
+ nsamples: ndarray, exptimes: ndarray, ldp: ndarray, istar: ndarray,
148
+ pt0: float, pdt: float, rules: ndarray, ng: int,
149
+ nthreads: int) -> ndarray:
103
150
  nthreads_current = get_num_threads()
104
151
  set_num_threads(nthreads)
105
-
106
- if k.ndim != 2:
107
- raise ValueError(" The radius ratios must be given as a 2D array with shape (npv, npb)")
108
-
109
- if ldp.ndim != 3:
110
- raise ValueError("The limb darkening profiles must be given as a 3D array with shape (npv, npb, nmu)")
111
-
112
- if k.shape[1] != ldp.shape[1]:
113
- raise ValueError("The transmission spectrum transit model requires that the number or radius ratios and the number of passbands match.")
114
-
115
- npt = times.size
116
- npv = k.shape[0]
117
- npb = k.shape[1]
118
-
119
- flux = zeros((npv, npb, npt)) # Model flux
120
- nq = rules.shape[2]
121
- coef = zeros((npb, ng - 2, 4)) # Split cubic coefficients of the mean intensity tables
122
- mu = empty((ng, 2 * nq))
123
- wf = zeros((ng, 2 * nq))
124
- ldm = empty(ng)
125
- xyc = zeros((2, 5)) # Taylor series coefficients for the (x, y) position
126
-
127
- for ipv in range(npv):
128
- if isnan(a[ipv]) or (a[ipv] <= 1.0) or (e[ipv] < 0.0) or not valid_radius_ratios(k[ipv]):
129
- flux[ipv, :, :] = nan
130
- continue
131
-
132
- kmean = mean(k[ipv])
133
- kmax = max(k[ipv])
134
- afac = k[ipv] ** 2 / kmean ** 2
135
-
136
- # -----------------------------------#
137
- # Calculate the limb darkening means #
138
- # -----------------------------------#
139
- gs, n1 = g_nodes(kmean, ng)
140
- gc = split_point(kmean)
141
- ldm_nodes(kmean, gs, rules, mu, wf)
142
- for ipb in range(npb):
143
- ldm_table(mu, wf, pt0, pdt, ldp[ipv, ipb, :], ldm)
144
- split_cubic_coefficients(ldm, n1, coef[ipb])
145
-
146
- # -----------------------------------------------------#
147
- # Calculate the Taylor series expansions for the orbit #
148
- # -----------------------------------------------------#
149
- xyc[:, :] = solve2d(0.0, p[ipv], a[ipv], i[ipv], e[ipv], w[ipv])
150
-
151
- # ---------------------------#
152
- # Calculate the bounding box #
153
- # ---------------------------#
154
- bt1, bt4 = bounding_box(kmean, xyc)
155
- bt1 -= 0.0015 + exptimes[0]
156
- bt4 += 0.0015 + exptimes[0]
157
-
158
- # --------------------------#
159
- # Calculate the light curve #
160
- # --------------------------#
161
- for ipt in prange(npt):
162
- epoch = floor((times[ipt] - t0[ipv] + 0.5 * p[ipv]) / p[ipv])
163
- tc = times[ipt] - (t0[ipv] + epoch * p[ipv])
164
- if not (bt1 <= tc <= bt4):
165
- flux[ipv, :, ipt] = 1.0
166
- else:
167
- for isample in range(1, nsamples[0] + 1):
168
- time_offset = exptimes[0] * ((isample - 0.5) / nsamples[0] - 0.5)
169
- z = sep_c(tc + time_offset, xyc)
170
- ap0, kappa = ccia(1.0, kmean, z)
171
- dadk = 2.0*kmean*kappa
172
- for ipb in range(npb):
173
- if z <= 1.0 - kmax:
174
- for ipb in range(npb):
175
- iplanet = ldm_lookup(z / (1.0 + kmean), gc, n1, coef[ipb])
176
- flux[ipv, ipb, ipt] += (istar[ipv, ipb] - iplanet * ap0 * afac[ipb]) / istar[ipv, ipb]
177
- else:
178
- for ipb in range(npb):
179
- iplanet = ldm_lookup(z / (1.0 + kmean), gc, n1, coef[ipb])
180
- flux[ipv, ipb, ipt] += (istar[ipv, ipb] - iplanet * (
181
- ap0 + (k[ipv, ipb] - kmean) * dadk)) / istar[ipv, ipb]
182
- flux[ipv, :, ipt] /= nsamples[0]
152
+ flux = _tsmodel_parallel(times, k, t0, p, a, i, e, w, nsamples, exptimes, ldp, istar, pt0, pdt, rules, ng)
183
153
  set_num_threads(nthreads_current)
184
- return flux
154
+ return flux
@@ -28,7 +28,7 @@
28
28
  # along with this program. If not, see <https://www.gnu.org/licenses/>.
29
29
  from typing import Union, List, Optional
30
30
 
31
- from numpy import ndarray, isscalar, atleast_2d, atleast_1d, array, zeros, pi
31
+ from numpy import ndarray, isscalar, atleast_2d, atleast_1d, array, zeros, pi, ascontiguousarray
32
32
  from pytransit.models.roadrunner.common import calculate_weights_3d
33
33
  from scipy.integrate import trapezoid
34
34
 
@@ -154,6 +154,7 @@ class TransmissionSpectroscopyModel(RoadRunnerModel):
154
154
  for ipv in range(npv):
155
155
  for ipb in range(npb):
156
156
  istar[ipv, ipb] = 2 * pi * trapezoid(self._ldz * ldpi[ipv, ipb], self._ldz)
157
+ ldp = ascontiguousarray(ldp)
157
158
 
158
159
  if self.parallel:
159
160
  flux = tsmodel_parallel(self.time, k, t0, p, a, i, e, w, self.nsamples, self.exptimes,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PyTransit
3
- Version: 2.9.2
3
+ Version: 2.10.0
4
4
  Summary: Fast and painless exoplanet transit light curve modelling.
5
5
  Author-email: Hannu Parviainen <hpparvi@gmail.com>
6
6
  License: GPLv2
@@ -42,6 +42,7 @@ PyTransit
42
42
  =========
43
43
 
44
44
  [![Licence](http://img.shields.io/badge/license-GPLv2-blue.svg?style=flat)](http://www.gnu.org/licenses/gpl-2.0.html)
45
+ [![Documentation Status](https://readthedocs.org/projects/pytransit/badge/?version=stable)](https://pytransit.readthedocs.io/en/stable/)
45
46
  [![MNRAS](https://img.shields.io/badge/MNRAS-10.1093%2Fmnras%2Fstv894-blue.svg)](http://mnras.oxfordjournals.org/content/450/3/3233)
46
47
  [![arXiv](http://img.shields.io/badge/arXiv-1504.07433-blue.svg?style=flat)](http://arxiv.org/abs/1504.07433)
47
48
  [![ASCL](https://img.shields.io/badge/ASCL-A1505.024-blue.svg?style=flat)](http://ascl.net/1505.024)
@@ -1,4 +1,5 @@
1
- pytransit/__init__.py,sha256=wbx421r999MaoFLG2jQT9xxuLiO12CjD3rAqCnR85XQ,3406
1
+ pytransit/__init__.py,sha256=IVzjo9sDVfDGfmXNobVblugXWyRZgeWbyTNivP4uNO8,3488
2
+ pytransit/_version.py,sha256=Lxklg9HTweyVZKDc1n479t5P2z89i9gcwyKNcMCstwg,530
2
3
  pytransit/limb_darkening.py,sha256=OeBPhUWXGKe_QFWcuSMv0b1sR6HbCdrYtTlYhPX-L_c,3538
3
4
  pytransit/contamination/__init__.py,sha256=l2TQSaQSc5S0-6YVB_VXu1ddr4_H8GAw4ypNBV2lgNY,1603
4
5
  pytransit/contamination/contamination.py,sha256=-BvHXWTFz3FA7p25YA0ABE5OQhwwZFEsM4oIsgjP7nM,14891
@@ -11,7 +12,7 @@ pytransit/lpf/__init__.py,sha256=SxPyGKv6BYIAR-C1c7oKfEsyHhbsjNofiFNMEWBOOPA,126
11
12
  pytransit/lpf/cntlpf.py,sha256=CW88sAfLfeRyT1YWNQqiiG1tQhdFfLoyAa-k0dTEFs0,5915
12
13
  pytransit/lpf/eclipselpf.py,sha256=ry4aAijqCuJ2AkRma80KPQT6s0xeteSdyvpinlTK7BU,7924
13
14
  pytransit/lpf/logposteriorfunction.py,sha256=4J9cYc5taqCksO8ePDMNAlOrZIXck5k6ZeFEKmEXzPQ,18764
14
- pytransit/lpf/lpf.py,sha256=GJWOH8sN45s2ytoauk9xOXacZECN3G60sQZqLXcuoWs,26778
15
+ pytransit/lpf/lpf.py,sha256=DtAJO64fK3tq-VZ_3qK1uCD92PSXeb1kvEoJ8a-EwHw,26779
15
16
  pytransit/lpf/mclpf.py,sha256=5hYRu5m5pyf9DKihhI4uKXQ-Wr6vCVI3ZCl6cTaHXgE,2271
16
17
  pytransit/lpf/mptlpf.py,sha256=nVqP1wwnKv8DJkrWwIEm5OPzA-LImlQLX4l3IwafewQ,6254
17
18
  pytransit/lpf/ocllpf.py,sha256=7U1hb_V7M1UNDNlQamv9sGmzuuE2SFX1q5J7DGQUKjE,3273
@@ -90,20 +91,20 @@ pytransit/models/opencl/ma_uniform.cl,sha256=p56RTe7y5W4d07ARvNRZc4CkM6JP0Sc5p3c
90
91
  pytransit/models/opencl/orbits.cl,sha256=MG1QVUXSgnubjUi1JWvz_9AJIXh6nUll1tA4EOfxnZA,4230
91
92
  pytransit/models/opencl/qpower2.cl,sha256=KDBItLYAyegPupO4YHjBUlzgVP_mr2st5aLtd-5bItQ,4498
92
93
  pytransit/models/roadrunner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
93
- pytransit/models/roadrunner/common.py,sha256=7CPykGwD-zC1tCXQCoCQnCCzyCworu3K102hhRP8miI,23734
94
+ pytransit/models/roadrunner/common.py,sha256=YdYymuXvpC1XbAlECJVyxympbi3VWLWq7MSpvSth2v4,26872
94
95
  pytransit/models/roadrunner/ecintersection.py,sha256=I-QX-j3cf2nyeyGO_m3thOBgtZlJ8i9sFxCBjqLb-os,20461
95
96
  pytransit/models/roadrunner/esmodel.py,sha256=L-9xI-Jo_qXyRFQ1F_IeyJsDS-CbdYhH92Al-FNh21E,5474
96
97
  pytransit/models/roadrunner/model_eclipse.py,sha256=UIDCQZPQT52tfad9XtJgJpzAPorly3NvRDWOJMCdI18,3125
97
98
  pytransit/models/roadrunner/model_ecspec.py,sha256=uao37pDV2a0_rnyqPuMjkEbj6lUG5Swiu1i_LY7N1wU,2651
98
99
  pytransit/models/roadrunner/model_full.py,sha256=o8VB7e1cQdnrd81zPmgG0xdDOhoDPUQ-rlab4xNyYu8,6849
99
100
  pytransit/models/roadrunner/model_simple.py,sha256=qEZiDxgXwvnfznzWYlmeLYBnlR8Bp4E1rnC-8t95L-8,5843
100
- pytransit/models/roadrunner/model_trspec.py,sha256=CruVo9LqDkcnwUp6_uzAE_n5sHxWJoTuRJypVqS6Rj0,8077
101
+ pytransit/models/roadrunner/model_trspec.py,sha256=IOR6OY41vv8qTmSC-DGJ2AD5W1QbiWWoOXU2nyilKF4,6696
101
102
  pytransit/models/roadrunner/opmodel.py,sha256=v-Ptc-E2a4Vbe5d0qjjAVJT9rUTX9hb2YItC8Qm_w-U,13876
102
103
  pytransit/models/roadrunner/opmodel_full.py,sha256=baH78JCwkWJJE4Yjms2Jf64MVd9_nYPhdibezeJQxPI,12588
103
104
  pytransit/models/roadrunner/rrmodel.cl,sha256=MGBDT4bW8vHU0wSjOzF4GFK_YzZlcoMUFvwz_1B8X1Q,16782
104
105
  pytransit/models/roadrunner/rrmodel.py,sha256=0qcjayQ7S5EHRUM5KP3qqLAF-97RiV0lKrvPPIihTnM,16180
105
106
  pytransit/models/roadrunner/rrmodel_cl.py,sha256=SdnarHFI_yetl8xY1u7Rs6Tgh9p70RZpEYFymtDgvTw,27921
106
- pytransit/models/roadrunner/tsmodel.py,sha256=S1xlWJyDhNUnAL2tm-RqCe6hsadR-je4xgX18R5II6I,7461
107
+ pytransit/models/roadrunner/tsmodel.py,sha256=FbbgZSD_T6vuuNXkzaokGMmDiIFc0GZ7HhZmk3W2sFQ,7517
107
108
  pytransit/orbits/__init__.py,sha256=Asb5OytXI9duU0MGF5ufV0QCD9m5Ku_S-pPOkqQIFfM,884
108
109
  pytransit/orbits/orbits.py,sha256=e8Gt3VL8dk9HXnsEDfE6gsjRtE7QyvNgCKYkdTFvk-w,4936
109
110
  pytransit/orbits/orbits_py.py,sha256=BqP89e5s7sXe-Q2-SIYFTD5lbJfrHBNRV5xmrNHC0o8,20423
@@ -136,8 +137,8 @@ pytransit/utils/io/__init__.py,sha256=Wh74NDb7IA_cXpvnQBtoAccZXYzm4oqvHJp8lHgWf7
136
137
  pytransit/utils/io/base.py,sha256=VH8LPu-Fzjv2kOftf91py_sRlgJBHMUtu0QyCI2kymc,15984
137
138
  pytransit/utils/io/lcdata.py,sha256=PIy3iKbuCj_ytk8IZ9bIFsrwNxLnGC2VtO336eg4tJI,32924
138
139
  pytransit/utils/io/rvdata.py,sha256=9hx0HjN5xmX6jvu73on6mLYZl50aCzuuz9RoKhJaaIg,7229
139
- pytransit-2.9.2.dist-info/licenses/LICENSE,sha256=s6DMeIC72jjJFdFX2MTU3lCz_4UCUQAcCMtxAqYBiv0,18045
140
- pytransit-2.9.2.dist-info/METADATA,sha256=O8qI3Uc0S0tDUqJJf0-Z-UN5oTvV2AdOeMTw-qLz6e4,5718
141
- pytransit-2.9.2.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
142
- pytransit-2.9.2.dist-info/top_level.txt,sha256=Y4wC10N9yBBNslkDDVW6JTmTjMRD5GPgu992lWf6rwk,10
143
- pytransit-2.9.2.dist-info/RECORD,,
140
+ pytransit-2.10.0.dist-info/licenses/LICENSE,sha256=s6DMeIC72jjJFdFX2MTU3lCz_4UCUQAcCMtxAqYBiv0,18045
141
+ pytransit-2.10.0.dist-info/METADATA,sha256=Gnd204JSUeLfeShGWVYvOS8TjE-c8kO73Ruv5JH8A0s,5856
142
+ pytransit-2.10.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
143
+ pytransit-2.10.0.dist-info/top_level.txt,sha256=Y4wC10N9yBBNslkDDVW6JTmTjMRD5GPgu992lWf6rwk,10
144
+ pytransit-2.10.0.dist-info/RECORD,,