PythonicDISORT 1.0.0__py3-none-any.whl → 1.0.2__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.
@@ -592,6 +592,6 @@ def _assemble_intensity_and_fluxes(
592
592
  # --------------------------------------------------------------------------------------------------------------------------
593
593
 
594
594
  if only_flux:
595
- return flux_up, flux_down, u0#, GC_collect_0, K_collect_0
595
+ return flux_up, flux_down, u0#, GC_collect_0, K_collect_0, B_collect_0
596
596
  else:
597
597
  return flux_up, flux_down, u0, u
@@ -82,12 +82,12 @@ def _solve_for_coeffs(
82
82
  GC_collect = np.empty((NFourier, NLayers, NQuad, NQuad))
83
83
  use_banded_solver = (NLayers >= use_banded_solver_NLayers)
84
84
  if use_banded_solver:
85
- sym_offset = 3 * N - 1
85
+ Nsupsubdiags = 3 * N - 1 # The number of super-diagonals equals the number of sub-diagonals
86
86
 
87
87
  # The following loops can easily be parallelized, but the speed-up is unlikely to be worth the overhead
88
88
  for m in range(NFourier):
89
89
  m_equals_0 = (m == 0)
90
- BDRF_bool = (NBDRF > m)
90
+ there_is_BDRF_mode = (NBDRF > m)
91
91
 
92
92
  G_collect_m = G_collect[m, :, :, :]
93
93
  K_collect_m = K_collect[m, :, :]
@@ -97,14 +97,20 @@ def _solve_for_coeffs(
97
97
  # Generate mathscr_D and mathscr_X (BDRF terms)
98
98
  # Just for this part, refer to section 3.4.2 of the Comprehensive Documentation
99
99
  # --------------------------------------------------------------------------------------------------------------------------
100
- if BDRF_bool:
101
- mathscr_D_neg = (1 + m_equals_0 * 1) * BDRF_Fourier_modes[m](mu_arr_pos, mu_arr_pos)
102
- R = mathscr_D_neg * mu_arr_pos_times_W[None, :]
103
-
104
- if there_is_beam_source:
105
- mathscr_X_pos = (mu0 * I0 / pi) * BDRF_Fourier_modes[m](
106
- mu_arr_pos, np.array([mu0])
107
- )[:, 0]
100
+ if there_is_BDRF_mode:
101
+ BDRF_Fourier_modes_m = BDRF_Fourier_modes[m]
102
+ if np.isscalar(BDRF_Fourier_modes_m):
103
+ mathscr_D_neg = (1 + m_equals_0 * 1) * BDRF_Fourier_modes_m
104
+ R = mathscr_D_neg * mu_arr_pos_times_W[None, :]
105
+ if there_is_beam_source:
106
+ mathscr_X_pos = (mu0 * I0 / pi) * BDRF_Fourier_modes_m
107
+ else:
108
+ mathscr_D_neg = (1 + m_equals_0 * 1) * BDRF_Fourier_modes_m(mu_arr_pos, mu_arr_pos)
109
+ R = mathscr_D_neg * mu_arr_pos_times_W[None, :]
110
+ if there_is_beam_source:
111
+ mathscr_X_pos = (mu0 * I0 / pi) * BDRF_Fourier_modes_m(
112
+ mu_arr_pos, np.array([mu0])
113
+ )[:, 0]
108
114
  # --------------------------------------------------------------------------------------------------------------------------
109
115
 
110
116
  # Assemble RHS
@@ -212,7 +218,7 @@ def _solve_for_coeffs(
212
218
  * np.exp(-scaled_tau_arr_with_0 / mu0)[l_range, None]
213
219
  ).ravel()
214
220
 
215
- if BDRF_bool:
221
+ if there_is_BDRF_mode:
216
222
  RHS = (
217
223
  np.concatenate(
218
224
  [
@@ -260,7 +266,7 @@ def _solve_for_coeffs(
260
266
  G_0_np
261
267
  * np.exp(K_collect_m[0, :N] * scaled_tau_arr_with_0[1])[None, :]
262
268
  )
263
- if BDRF_bool:
269
+ if there_is_BDRF_mode:
264
270
  LHS[-N:, -NQuad : -N] = (G_L_pn - R @ G_L_nn) * E_Lm1L[None, :]
265
271
  LHS[-N:, -N:] = G_L_pp - R @ G_L_np
266
272
  else:
@@ -298,8 +304,8 @@ def _solve_for_coeffs(
298
304
  # Solve the system
299
305
  if use_banded_solver:
300
306
  C_m = sc.linalg.solve_banded(
301
- (sym_offset, sym_offset),
302
- to_diag_ordered_form(LHS, sym_offset),
307
+ (Nsupsubdiags, Nsupsubdiags),
308
+ to_diag_ordered_form(LHS, Nsupsubdiags, Nsupsubdiags),
303
309
  RHS,
304
310
  True,
305
311
  True,
@@ -153,7 +153,7 @@ def _solve_for_gen_and_part_sols(
153
153
  alpha_arr[ind, :, :] = alpha
154
154
  beta_arr[ind, :, :] = beta
155
155
  no_shortcut_indices.append(ind)
156
- if m_equals_0 and there_is_iso_source:
156
+ if m_equals_0 and there_is_iso_source: # Keep the list empty if there is no isotropic source
157
157
  no_shortcut_indices_0.append(l)
158
158
 
159
159
  else:
@@ -192,7 +192,7 @@ def _solve_for_gen_and_part_sols(
192
192
  / K_arr[:, None, :]
193
193
  )
194
194
 
195
- # Eigenvector matrix
195
+ # Eigenvector matrices
196
196
  G_arr = np.concatenate(
197
197
  (
198
198
  (eigenvecs_GpG_arr - eigenvecs_GmG_arr) / 2,
@@ -203,7 +203,7 @@ def _solve_for_gen_and_part_sols(
203
203
 
204
204
  G_collect[no_shortcut_indices, :, :] = G_arr
205
205
  K_collect[no_shortcut_indices, :] = K_arr
206
- if len(no_shortcut_indices_0) > 0:
206
+ if len(no_shortcut_indices_0) > 0: # If there is no isotropic source this list will be empty
207
207
  G_inv_collect_0[no_shortcut_indices_0, :, :] = np.linalg.inv(
208
208
  G_collect[: len(no_shortcut_indices_0), :, :]
209
209
  )
@@ -44,7 +44,7 @@ def pydisort(
44
44
  omega_arr : array or float
45
45
  Single-scattering albedo of each atmospheric layer.
46
46
  NQuad : int
47
- Number of ``mu`` quadrature nodes.
47
+ Number of ``mu`` quadrature nodes, i.e. number of streams.
48
48
  Leg_coeffs_all : 2darray
49
49
  All available unweighted phase function Legendre coefficients.
50
50
  Each row pertains to an atmospheric layer (from top to bottom).
@@ -61,10 +61,10 @@ def pydisort(
61
61
  NFourier : optional, int
62
62
  Number of Fourier modes to use to construct the intensity function.
63
63
  b_pos : optional, 2darray or float
64
- Dirichlet boundary condition for the upward direction.
64
+ Dirichlet condition at the bottom boundary for the upward direction.
65
65
  Each column pertains to a Fourier mode (ascending order).
66
66
  b_neg : optional, 2darray or float
67
- Dirichlet boundary condition for the downward direction.
67
+ Dirichlet condition at the top boundary for the downward direction.
68
68
  Each column pertains to a Fourier mode (ascending order).
69
69
  only_flux : optional, bool
70
70
  Do NOT compute the intensity function?
@@ -76,8 +76,8 @@ def pydisort(
76
76
  NT_cor : optional, bool
77
77
  Perform Nakajima-Tanaka intensity corrections?
78
78
  BDRF_Fourier_modes : optional, list of functions
79
- BDRF Fourier modes, each a function with arguments ``mu, -mu_p`` of type array
80
- and which output has the same dimensions as the outer product of the two arrays.
79
+ BDRF Fourier modes, each a scalar, or a function with arguments ``mu, -mu_p`` of type array
80
+ which output has the same dimensions as the outer product of the two arrays.
81
81
  s_poly_coeffs : optional, array
82
82
  Polynomial coefficients of isotropic internal sources.
83
83
  Each row pertains to an atmospheric layer (from top to bottom).
@@ -86,7 +86,7 @@ def pydisort(
86
86
  At or above how many atmospheric layers should ``scipy.linalg.solve_banded`` be used?
87
87
  autograd_compatible : optional, bool
88
88
  If ``True``, the autograd package: https://github.com/HIPS/autograd can be used to compute
89
- the tau-derivatives of the output functions but ``pydisort`` will be less efficient.
89
+ the ``tau``-derivatives of the output functions but ``pydisort`` will be less efficient.
90
90
 
91
91
  Returns
92
92
  -------
@@ -97,9 +97,7 @@ def pydisort(
97
97
  Returns the diffuse flux magnitudes (same type and size as ``tau``).
98
98
  Pass ``is_antiderivative_wrt_tau = True`` (defaults to ``False``)
99
99
  to switch to an antiderivative of the function with respect to ``tau``.
100
- For example, ``Fp(1, is_antiderivative_wrt_tau=True) - Fp(0, is_antiderivative_wrt_tau=True)``
101
- will produce the tau-integral over ``[1, 0]`` assuming both values belong to the same layer, and
102
- ``Fp(tau_arr, is_antiderivative_wrt_tau = True) - Fp(np.insert(tau_arr[:-1] + 1e-15, 0, 0), is_antiderivative_wrt_tau = True)``
100
+ For example, ``Fp(tau_arr, is_antiderivative_wrt_tau = True) - Fp(np.insert(tau_arr[:-1] + 1e-15, 0, 0), is_antiderivative_wrt_tau = True)``
103
101
  will produce an array of the tau-integral over each layer.
104
102
  Pass ``return_tau_arr`` to return ``tau_arr`` (defaults to ``False``).
105
103
  Fm(tau) : function
@@ -234,8 +232,8 @@ def pydisort(
234
232
  raise ValueError("The number of phase function Legendre coefficients must be positive.")
235
233
  if not np.all(omega_arr * Leg_coeffs_all[:, 0] == omega_arr):
236
234
  raise ValueError("The first phase function Legendre coefficient must equal 1.")
237
- if not (np.all(0 <= Leg_coeffs_all) and np.all(Leg_coeffs_all <= 1)):
238
- raise ValueError("The phase function Legendre coefficients must all be between 0 and 1.")
235
+ if not (np.all(-1 <= Leg_coeffs_all) and np.all(Leg_coeffs_all <= 1)):
236
+ raise ValueError("The phase function Legendre coefficients must all be between -1 and 1.")
239
237
  if not NLeg <= NLeg_all:
240
238
  raise ValueError("`NLeg` cannot be larger than the number of phase function Legendre coefficients provided.")
241
239
  # Ensure that the first dimension of the following inputs corresponds to the number of layers
@@ -265,9 +263,9 @@ def pydisort(
265
263
  if I0 < 0:
266
264
  raise ValueError("The incident beam must have positive intensity.")
267
265
  if there_is_beam_source:
268
- if not 0 < mu0 and mu0 <= 1:
266
+ if not (0 < mu0 and mu0 <= 1):
269
267
  raise ValueError("The cosine of the polar angle of the incident beam must be between 0 and 1, excluding 0.")
270
- if not 0 <= phi0 and phi0 < 2 * pi:
268
+ if not (0 <= phi0 and phi0 < 2 * pi):
271
269
  raise ValueError("Provide the principal azimuthal angle for the incident beam (must be between 0 and 2pi, excluding 2pi).")
272
270
  # Ensure that the BC inputs are of the correct shape
273
271
  if len(np.atleast_1d(b_pos)) == 1:
@@ -299,14 +299,14 @@ def Planck(T, WVNM):
299
299
 
300
300
  Parameters
301
301
  ----------
302
- T : float or 1darray
302
+ T : float or array
303
303
  Temperatures in kelvin.
304
304
  WVNM : float
305
305
  Wavenumber with units m^-1.
306
306
 
307
307
  Returns
308
308
  -------
309
- float or 1darray
309
+ float or array
310
310
  Emitted power per unit area from a blackbody surface with units W / m^2.
311
311
 
312
312
  """
@@ -325,14 +325,15 @@ def Planck(T, WVNM):
325
325
 
326
326
 
327
327
  def blackbody_contrib_to_BCs(T, WVNMLO, WVNMHI, **kwargs):
328
- """Compute blackbody contribution to the BCs (``b_pos`` or ``b_neg``).
328
+ """Compute blackbody contribution to each BC (``b_pos`` or ``b_neg``),
329
+ i.e. the blackbody emission of that boundary, with units W / m^2.
329
330
  This convenience function is provided to help match the inputs for Stamnes' DISORT to those for PythonicDISORT.
330
331
  Users will have to manually adjust emissivities but ``PythonicDISORT.subroutines.generate_emissivity_from_BDRF``
331
332
  can help with that.
332
333
 
333
334
  Parameters
334
335
  ----------
335
- T : float or 1darray
336
+ T : float or array
336
337
  Temperatures in kelvin.
337
338
  WVNMLO : float
338
339
  Lower bound of wavenumber interval with units m^-1. This variable is identically named in Stamnes' DISORT.
@@ -341,6 +342,10 @@ def blackbody_contrib_to_BCs(T, WVNMLO, WVNMHI, **kwargs):
341
342
  **kwargs
342
343
  Keyword arguments to pass to ``scipy.integrate.quad_vec``.
343
344
 
345
+ Returns
346
+ -------
347
+ float or array
348
+ The blackbody emission of each boundary with units W / m^2.
344
349
  """
345
350
  return np.squeeze(sc.integrate.quad_vec(lambda WVNM: Planck(T, WVNM), WVNMLO, WVNMHI, **kwargs)[0])
346
351
 
@@ -351,15 +356,15 @@ def linear_spline_coefficients(x, y, check_inputs=True):
351
356
 
352
357
  Parameters
353
358
  ----------
354
- x : 1darray
359
+ x : array
355
360
  Array of `x` data points.
356
- y : 1darray
361
+ y : array
357
362
  Array of `y` data points.
358
363
 
359
364
  Returns
360
365
  -------
361
366
  2darray
362
- The coefficients with axes (segment, ascending polynomial order), as required by ``pydisort``.
367
+ The coefficients with axes (segment, ascending polynomial order) which is required by ``pydisort``.
363
368
 
364
369
  """
365
370
  # Input checks
@@ -379,15 +384,16 @@ def linear_spline_coefficients(x, y, check_inputs=True):
379
384
 
380
385
 
381
386
  def generate_s_poly_coeffs(tau_arr, TEMPER, WVNMLO, WVNMHI, **kwargs):
382
- """Generate ``s_poly_coeffs`` as required by ``pydisort``.
383
- This convenience function is provided to help match the inputs for Stamnes' DISORT to those for PythonicDISORT,
384
- however, users will have to manually adjust emissivities.
387
+ """Generate DISORT-equivalent ``s_poly_coeffs`` for input into ``pydisort``.
388
+ This convenience function is provided to help match the inputs for Stamnes' DISORT to those for PythonicDISORT.
389
+ Users will have to manually adjust emissivities, however, and they should note that PythonicDISORT allows much
390
+ more flexibility in choosing blackbody emission profiles than DISORT.
385
391
 
386
392
  Parameters
387
393
  ----------
388
394
  tau_arr : array or float
389
395
  Optical depth of the lower boundary of each atmospheric layer.
390
- TEMPER : 1darray
396
+ TEMPER : array
391
397
  Temperature in kelvin at each boundary / interface from top to bottom.
392
398
  This variable is identically named in Stamnes' DISORT.
393
399
  WVNMLO : float
@@ -419,7 +425,7 @@ def generate_s_poly_coeffs(tau_arr, TEMPER, WVNMLO, WVNMHI, **kwargs):
419
425
  def generate_emissivity_from_BDRF(N, zeroth_BDRF_Fourier_mode):
420
426
  """Use Kirchoff's law of thermal radiation to determine the (directional) emissivity
421
427
  of the surface given the zeroth Fourier mode of the Bi-Directional Reflectance Function (BDRF).
422
- This computation is internal to Stamnes' DISORT.
428
+ This computation is automatic and internal to Stamnes' DISORT.
423
429
  This function supplements ``PythonicDISORT.subroutines.blackbody_contrib_to_BCs``.
424
430
 
425
431
  Parameters
@@ -432,8 +438,8 @@ def generate_emissivity_from_BDRF(N, zeroth_BDRF_Fourier_mode):
432
438
 
433
439
  Returns
434
440
  -------
435
- 1darray
436
- Emissivity for the blackbody contribution to the lower boundary source `b_neg``.
441
+ array
442
+ Emissivity for the blackbody contribution to the lower boundary source ``b_neg``.
437
443
  """
438
444
  mu_arr_pos, W = Gauss_Legendre_quad(N)
439
445
  return 1 - 2 * zeroth_BDRF_Fourier_mode(mu_arr_pos, mu_arr_pos) * mu_arr_pos[None, :] @ W
@@ -452,29 +458,41 @@ def cache_BDRF_Fourier_modes(N, mu0, BDRF_Fourier_modes):
452
458
  mu0 : float
453
459
  Cosine of polar angle of the incident beam.
454
460
  BDRF_Fourier_modes : list of functions
455
- BDRF Fourier modes, each a function with arguments ``mu, -mu_p`` of type array
456
- and which output has the same dimensions as the outer product of the two arrays.
461
+ BDRF Fourier modes, each a scalar, or a function with arguments ``mu, -mu_p`` of type array
462
+ which output has the same dimensions as the outer product of the two arrays.
457
463
 
458
464
  Returns
459
465
  -------
460
466
  cached_BDRF_Fourier_modes : list of functions
461
467
  Cached BDRF Fourier modes, each a function with arguments ``mu, -mu_p`` of type array
462
- and which output has the same dimensions as the outer product of the two arrays.
468
+ and which output is a scalar (if the Fourier mode was a scalar)
469
+ or has the same dimensions as the outer product of the two arrays.
463
470
  """
464
471
  NBDRF = len(BDRF_Fourier_modes)
465
472
  mu_arr_pos = Gauss_Legendre_quad(N)[0]
466
473
 
467
- BDRF_Fourier_modes_evaluated = [
468
- BDRF_Fourier_modes[m](mu_arr_pos, np.append(mu_arr_pos, mu0)) for m in range(NBDRF)
474
+ [
475
+ (
476
+ None
477
+ if np.isscalar(BDRF_Fourier_modes[m])
478
+ else BDRF_Fourier_modes[m](mu_arr_pos, np.append(mu_arr_pos, mu0))
479
+ )
480
+ for m in range(NBDRF)
469
481
  ]
482
+
470
483
  cached_BDRF_Fourier_modes = [
471
484
  (
472
- lambda mu, neg_mup, m=m: BDRF_Fourier_modes_evaluated[m][:, [-1]]
473
- if len(neg_mup) == 1
474
- else BDRF_Fourier_modes_evaluated[m][:, :-1]
485
+ lambda mu, neg_mup, m=m: BDRF_Fourier_modes[m]
486
+ if np.isscalar(BDRF_Fourier_modes[m])
487
+ else (
488
+ BDRF_Fourier_modes_evaluated[m][:, [-1]]
489
+ if len(neg_mup) == 1
490
+ else BDRF_Fourier_modes_evaluated[m][:, :-1]
491
+ )
475
492
  )
476
493
  for m in range(NBDRF)
477
494
  ]
495
+
478
496
  return cached_BDRF_Fourier_modes
479
497
 
480
498
 
@@ -488,9 +506,9 @@ def affine_transform_poly_coeffs(poly_coeffs, a_arr, b_arr):
488
506
  poly_coeffs : 2darray
489
507
  Array with columns [C_0, C_1, ..., C_n].
490
508
  The rows correspond to different affine transformations.
491
- a_arr : 1darray
509
+ a_arr : array
492
510
  Scale factors.
493
- b_arr : 1darray
511
+ b_arr : array
494
512
  Translations.
495
513
 
496
514
  Returns
@@ -518,10 +536,11 @@ def affine_transform_poly_coeffs(poly_coeffs, a_arr, b_arr):
518
536
  return np.einsum("lij, lj -> li", T, poly_coeffs, optimize=True)
519
537
 
520
538
 
539
+
521
540
  def interpolate(u):
522
- """Polynomial (Barycentric) interpolation with respect to mu. The output
523
- is a function that is continuous and variable in all three arguments: mu, tau and phi.
524
- Discussed in sections 3.7 and 6.3 in the Comprehensive Documentation.
541
+ """Polynomial (Barycentric) interpolation with respect to ``mu``. The output
542
+ is a function that is continuous and variable in all three arguments: ``mu``, ``tau`` and ``phi``.
543
+ Discussed in sections 3.7 and 6.3 of the Comprehensive Documentation.
525
544
 
526
545
  Parameters
527
546
  ----------
@@ -611,22 +630,23 @@ def interpolate(u):
611
630
 
612
631
 
613
632
 
614
- def to_diag_ordered_form(A, sym_offset):
633
+ def to_diag_ordered_form(A, Nsuperdiags, Nsubdiags):
615
634
  """
616
- Convert a matrix A to the diagonal ordered form required by ``scipy.linalg.solve_banded``.
617
- We assume that the matrix has the same number of super- and sub-diagonals.
635
+ Convert some matrix A to the diagonal ordered form required by ``scipy.linalg.solve_banded``.
618
636
 
619
637
  Parameters
620
638
  ----------
621
639
  A : 2darray
622
640
  The square matrix to be converted.
623
- sym_offset : int
624
- The number of super- or sub-diagonals (assumed to be equal)
641
+ Nsuperdiags : int
642
+ The number of super-diagonals.
643
+ Nsubdiags : int
644
+ The number of sub-diagonals.
625
645
 
626
646
  Returns
627
647
  -------
628
648
  2darray
629
- The diagonal ordered form matrix as required by solve_banded.
649
+ The diagonal ordered form matrix as required by ``scipy.linalg.solve_banded``.
630
650
  """
631
651
  n = A.shape[0]
632
652
  indices = np.arange(n)
@@ -634,28 +654,29 @@ def to_diag_ordered_form(A, sym_offset):
634
654
  return np.concatenate(
635
655
  [
636
656
  A[
637
- indices - np.arange(sym_offset, -1, -1)[:, None],
657
+ indices - np.arange(Nsuperdiags, -1, -1)[:, None],
638
658
  indices[None, :],
639
659
  ],
640
660
  A[
641
- indices - np.arange(n - 1, n - sym_offset - 1, -1)[:, None],
661
+ indices - np.arange(n - 1, n - Nsubdiags - 1, -1)[:, None],
642
662
  indices[None, :],
643
663
  ],
644
664
  ],
645
665
  axis=0,
646
666
  )
647
667
 
668
+
648
669
 
649
- def _mathscr_v(tau, # Input optical depths
650
- l, # Layer index of each input optical depth
651
- Nscoeffs, # Number of isotropic source polynomial coefficients
652
- s_poly_coeffs, # Polynomial coefficients of isotropic source
653
- G, # Eigenvector matrices
654
- K, # Eigenvalues
655
- G_inv, # Inverse of eigenvector matrix
656
- mu_arr, # Quadrature nodes for both hemispheres
670
+ def _mathscr_v(tau, # Input optical depths
671
+ l, # Layer index of each input optical depth
672
+ Nscoeffs, # Number of isotropic source polynomial coefficients
673
+ s_poly_coeffs, # Polynomial coefficients of isotropic source
674
+ G, # Eigenvector matrices
675
+ K, # Eigenvalues
676
+ G_inv, # Inverse of eigenvector matrix
677
+ mu_arr, # Quadrature nodes for both hemispheres
657
678
  is_antiderivative_wrt_tau=False, # Switch to an antiderivative of the function?
658
- autograd_compatible=False, # Should the output functions be compatible with autograd?
679
+ autograd_compatible=False, # Should the output functions be compatible with autograd?
659
680
  ):
660
681
  """Particular solution for isotropic internal sources.
661
682
  Refer to section 3.6.1 of the Comprehensive Documentation.
@@ -664,22 +685,22 @@ def _mathscr_v(tau, # Input optical depths
664
685
  and ``_solve_for_coeffs`` functions which call it.
665
686
 
666
687
  Arguments of _mathscr_v
667
- | Variable | Shape |
668
- | --------------------------- | ------------------------------------- |
669
- | ``tau`` | ``Ntau`` |
670
- | ``l`` | ``Ntau`` |
671
- | ``Nscoeffs`` | scalar |
672
- | ``s_poly_coeffs`` | ``NLayers x Nscoeffs`` or ``Nscoeffs`` |
673
- | ``G`` | ``NLayers<= x NQuad x NQuad`` |
674
- | ``K`` | ``NLayers<= x NQuad`` |
688
+ | Variable | Shape |
689
+ | ----------------------------- | ----------------------------------------- |
690
+ | ``tau`` | ``Ntau`` |
691
+ | ``l`` | ``Ntau`` |
692
+ | ``Nscoeffs`` | scalar |
693
+ | ``s_poly_coeffs`` | ``NLayers x Nscoeffs`` |
694
+ | ``G`` | ``NLayers<= x NQuad x NQuad`` |
695
+ | ``K`` | ``NLayers<= x NQuad`` |
675
696
  | ``G_inv`` | ``NLayers<= x NQuad x NQuad`` or ``None`` |
676
- | ``mu_arr`` | ``NQuad`` |
677
- | ``is_antiderivative_wrt_tau`` | boolean |
678
- | ``autograd_compatible`` | boolean |
697
+ | ``mu_arr`` | ``NQuad`` |
698
+ | ``is_antiderivative_wrt_tau`` | boolean |
699
+ | ``autograd_compatible`` | boolean |
679
700
 
680
701
  Notable internal variables of _mathscr_v
681
- | Variable | Shape |
682
- | ---------------- | ----------------------------------- |
702
+ | Variable | Shape |
703
+ | ---------------- | ------------------------------------- |
683
704
  | i_arr | ``Nscoeffs`` |
684
705
  | i_arr_repeat | ``Nscoeffs*(Nscoeffs+1)/2`` | Using triangular number formula
685
706
  | j_arr | ``Nscoeffs*(Nscoeffs+1)/2`` | Using triangular number formula
@@ -694,8 +715,8 @@ def _mathscr_v(tau, # Input optical depths
694
715
  def mathscr_b(i):
695
716
  """
696
717
  Notable internal variables of mathscr_b
697
- | Variable | Shape |
698
- | ---------------- | ------------------------------------- |
718
+ | Variable | Shape |
719
+ | ---------------- | --------------------------------------- |
699
720
  | j_arr | ``i + 1`` |
700
721
  | s_poly_coeffs_nj | ``i + 1`` |
701
722
  | OUTPUT | ``Nscoeffs x (i + 1) x NQuad`` |
@@ -716,7 +737,7 @@ def _mathscr_v(tau, # Input optical depths
716
737
  shape = np.shape(K)
717
738
  i_arr = np.arange(Nscoeffs)
718
739
  i_arr_repeat = np.repeat(i_arr, i_arr + 1)
719
- j_arr = np.concatenate([np.arange(i + 1) for i in range(Nscoeffs)])
740
+ j_arr = np.concatenate([i_arr[:i] for i in range(1, Nscoeffs + 1)])
720
741
  s_poly_coeffs_nj = s_poly_coeffs[:, n - j_arr]
721
742
 
722
743
  mathscr_v_coeffs = np.zeros((Nscoeffs, shape[0], shape[1]))
@@ -752,7 +773,7 @@ def _mathscr_v(tau, # Input optical depths
752
773
 
753
774
  def _compare(results, mu_to_compare, reorder_mu, flux_up, flux_down, u=None):
754
775
  """Performs pointwise comparisons between results from Stamnes' DISORT,
755
- which are stored in .npz files, against results from PythonicDISORT. Used in our PyTests.
776
+ which are stored in ``.npz`` files, against results from PythonicDISORT. Used in our PyTests.
756
777
 
757
778
  """
758
779
  # Load saved results from Stamnes' DISORT
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PythonicDISORT
3
- Version: 1.0.0
3
+ Version: 1.0.2
4
4
  Summary: Discrete Ordinates Solver for the (1D) Radiative Transfer Equation in a single or multi-layer atmosphere.
5
5
  Author-email: Dion HO Jia Xu <dh3065@columbia.edu>
6
6
  Project-URL: Homepage, https://github.com/LDEO-CREW/Pythonic-DISORT
@@ -0,0 +1,11 @@
1
+ PythonicDISORT/__init__.py,sha256=V1obNzaFgqInxqYJ5h_r6JHbZRxx4VM5VgzCIS6EEzI,84
2
+ PythonicDISORT/_assemble_intensity_and_fluxes.py,sha256=M9mS2tD-GvMgze2MnHZEIarv7bpJsVe32fVPUEn0YpE,29911
3
+ PythonicDISORT/_solve_for_coeffs.py,sha256=Bb-C5OJt355x8_v8WFB2sJutBtSTAFNIX4OxLQJk9-0,16539
4
+ PythonicDISORT/_solve_for_gen_and_part_sols.py,sha256=_sPHgBTn58nOO0u13WCmCiDa6Qbv4HEu-7F_auFUcG4,13089
5
+ PythonicDISORT/pydisort.py,sha256=xeHeW_XcQwSwLYTwYr2tnBUPnu0RqSTrOppO2KEHiT8,38865
6
+ PythonicDISORT/subroutines.py,sha256=BFd0RqtmqzYF8J_ZE8KZB7GE5cl6ARHzbxqy0ewulbg,32517
7
+ pythonicdisort-1.0.2.dist-info/LICENSE.md,sha256=q1i1QVh0OLzK0fj6kaNRNWsM_KZca66JwWgWwbuCPlA,1092
8
+ pythonicdisort-1.0.2.dist-info/METADATA,sha256=-AEj3RRB4SbPh8aydWQtNmBlORzSEhjQ-kEhTjy9WBk,8310
9
+ pythonicdisort-1.0.2.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
10
+ pythonicdisort-1.0.2.dist-info/top_level.txt,sha256=aX6kCeI1E7naZz3xfw4_mIbWh5KBh9dmF3FIvgP5m3Y,15
11
+ pythonicdisort-1.0.2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.3.0)
2
+ Generator: setuptools (75.3.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,11 +0,0 @@
1
- PythonicDISORT/__init__.py,sha256=V1obNzaFgqInxqYJ5h_r6JHbZRxx4VM5VgzCIS6EEzI,84
2
- PythonicDISORT/_assemble_intensity_and_fluxes.py,sha256=NlOFy2DPjQLttIimJPHUcm6jbnh-19zmnjw04gtDU0c,29898
3
- PythonicDISORT/_solve_for_coeffs.py,sha256=8_3QZiE9DEpK0E9ryexOHbO8i81NjnrTL31AwKKH6Z0,16006
4
- PythonicDISORT/_solve_for_gen_and_part_sols.py,sha256=TaBGM5q82ZTEMG0SLM0uXivtESbP6JSiE4yZk7jrRKk,12975
5
- PythonicDISORT/pydisort.py,sha256=grY6RQv-l59K_Rs8204i0RHDvJn9A_KHfTXphbqeO14,38995
6
- PythonicDISORT/subroutines.py,sha256=UArS9Gg3Gr3X9Z2iXeU2g-Jrv9xfS83K6-eG-amjleA,31839
7
- PythonicDISORT-1.0.0.dist-info/LICENSE.md,sha256=q1i1QVh0OLzK0fj6kaNRNWsM_KZca66JwWgWwbuCPlA,1092
8
- PythonicDISORT-1.0.0.dist-info/METADATA,sha256=QTbNzHhdtsPjxKqNOgJnXCtqTPrZBbc8CAV2ZDwdIC4,8310
9
- PythonicDISORT-1.0.0.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
10
- PythonicDISORT-1.0.0.dist-info/top_level.txt,sha256=aX6kCeI1E7naZz3xfw4_mIbWh5KBh9dmF3FIvgP5m3Y,15
11
- PythonicDISORT-1.0.0.dist-info/RECORD,,