PythonicDISORT 1.1__py3-none-any.whl → 1.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.
@@ -201,7 +201,13 @@ def _assemble_intensity_and_fluxes(
201
201
  axis=-1,
202
202
  )
203
203
 
204
- if is_antiderivative_wrt_tau and there_is_beam_source:
204
+ direct_beam_contribution = 0
205
+ if is_antiderivative_wrt_tau:
206
+ if there_is_beam_source:
207
+ direct_beam_contribution = (B_collect / (-scale_tau / mu0)[None, :, None])[
208
+ :, l, :
209
+ ] * np.exp(-scaled_tau / mu0)[None, :, None]
210
+
205
211
  um = (
206
212
  np.einsum(
207
213
  "mtij, mtj -> mti",
@@ -209,23 +215,19 @@ def _assemble_intensity_and_fluxes(
209
215
  np.exp(exponent) / (scale_tau[None, :, None] * K_collect)[:, l, :],
210
216
  optimize=True,
211
217
  )
212
- + (B_collect / (-scale_tau / mu0)[None, :, None])[:, l, :]
213
- * np.exp(-scaled_tau / mu0)[None, :, None]
214
- )
215
- elif is_antiderivative_wrt_tau and not there_is_beam_source:
216
- um = np.einsum(
217
- "mtij, mtj -> mti",
218
- GC_collect[:, l, :, :],
219
- np.exp(exponent) / (scale_tau[None, l, None] * K_collect)[:, l, :],
220
- optimize=True,
218
+ + direct_beam_contribution
221
219
  )
222
- elif not is_antiderivative_wrt_tau and there_is_beam_source:
223
- um = np.einsum(
224
- "mtij, mtj -> mti", GC_collect[:, l, :, :], np.exp(exponent), optimize=True
225
- ) + B_collect[:, l, :] * np.exp(-scaled_tau / mu0)[None, :, None]
226
220
  else:
227
- um = np.einsum(
228
- "mtij, mtj -> mti", GC_collect[:, l, :, :], np.exp(exponent), optimize=True
221
+ if there_is_beam_source:
222
+ direct_beam_contribution = (
223
+ B_collect[:, l, :] * np.exp(-scaled_tau / mu0)[None, :, None]
224
+ )
225
+
226
+ um = (
227
+ np.einsum(
228
+ "mtij, mtj -> mti", GC_collect[:, l, :, :], np.exp(exponent), optimize=True
229
+ )
230
+ + direct_beam_contribution
229
231
  )
230
232
 
231
233
  # Contribution from particular solution for isotropic internal sources
@@ -255,6 +257,9 @@ def _assemble_intensity_and_fluxes(
255
257
  np.cos(np.arange(NFourier)[:, None] * (phi0 - phi)[None, :]),
256
258
  optimize=True,
257
259
  )
260
+
261
+ outputs = (rescale_factor * np.squeeze(u),)
262
+ outputs_len = 1
258
263
 
259
264
  if return_Fourier_error:
260
265
  exponent = np.concatenate(
@@ -264,7 +269,14 @@ def _assemble_intensity_and_fluxes(
264
269
  ],
265
270
  axis=-1,
266
271
  )
267
- if is_antiderivative_wrt_tau and there_is_beam_source:
272
+
273
+ direct_beam_contribution = 0
274
+ if is_antiderivative_wrt_tau:
275
+ if there_is_beam_source:
276
+ direct_beam_contribution = (
277
+ B_collect.T[-1, :, :] / (-scale_tau / mu0)[None, :]
278
+ )[:, l] * np.exp(-scaled_tau / mu0)[None, :]
279
+
268
280
  ulast = (
269
281
  np.einsum(
270
282
  "tij, tj -> it",
@@ -272,25 +284,21 @@ def _assemble_intensity_and_fluxes(
272
284
  np.exp(exponent) / (scale_tau[:, None] * K_collect[-1, :, :])[l, :],
273
285
  optimize=True,
274
286
  )
275
- + (B_collect.T[-1, :, :] / (-scale_tau / mu0)[None, :])[:, l]
276
- * np.exp(-scaled_tau / mu0)[None, :]
287
+ + direct_beam_contribution
277
288
  )
278
- elif is_antiderivative_wrt_tau and not there_is_beam_source:
279
- ulast = np.einsum(
280
- "tij, tj -> it",
281
- GC_collect[-1, l, :, :],
282
- np.exp(exponent) / (scale_tau[:, None] * K_collect[-1, :, :])[l, :],
283
- optimize=True,
284
- )
285
- elif not is_antiderivative_wrt_tau and not there_is_beam_source:
286
- ulast = np.einsum(
287
- "tij, tj -> it", GC_collect[-1, l, :, :], np.exp(exponent), optimize=True
288
- ) + B_collect.T[-1, :, l] * np.exp(-scaled_tau / mu0)[None, :]
289
289
  else:
290
- ulast = np.einsum(
291
- "tij, tj -> it", GC_collect[-1, l, :, :], np.exp(exponent), optimize=True
290
+ if there_is_beam_source:
291
+ direct_beam_contribution = (
292
+ B_collect.T[-1, :, l] * np.exp(-scaled_tau / mu0)[None, :]
293
+ )
294
+
295
+ ulast = (
296
+ np.einsum(
297
+ "tij, tj -> it", GC_collect[-1, l, :, :], np.exp(exponent), optimize=True
298
+ )
299
+ + direct_beam_contribution
292
300
  )
293
-
301
+
294
302
  u_abs = np.abs(u)
295
303
  Fourier_error = np.max(
296
304
  np.divide(
@@ -299,19 +307,18 @@ def _assemble_intensity_and_fluxes(
299
307
  ),
300
308
  u_abs,
301
309
  out=np.zeros_like(u_abs),
302
- where=u_abs > 1e-15,
310
+ where=u_abs > 1e-8,
303
311
  )
304
312
  )
305
313
 
306
- if return_tau_arr:
307
- return rescale_factor * np.squeeze(u), Fourier_error, tau_arr
308
- else:
309
- return rescale_factor * np.squeeze(u), Fourier_error
310
- else:
311
- if return_tau_arr:
312
- return rescale_factor * np.squeeze(u), tau_arr
313
- else:
314
- return rescale_factor * np.squeeze(u)
314
+ outputs += (Fourier_error,)
315
+ outputs_len += 1
316
+
317
+ if return_tau_arr:
318
+ outputs += (tau_arr,)
319
+ outputs_len += 1
320
+
321
+ return outputs[0] if outputs_len == 1 else outputs
315
322
  # --------------------------------------------------------------------------------------------------------------------------
316
323
 
317
324
  # Construct u0
@@ -363,7 +370,13 @@ def _assemble_intensity_and_fluxes(
363
370
  axis=-1,
364
371
  )
365
372
 
373
+ direct_beam_contribution = 0
366
374
  if is_antiderivative_wrt_tau and there_is_beam_source:
375
+ if there_is_beam_source:
376
+ direct_beam_contribution = (B_collect_0.T / (-scale_tau / mu0)[None, :])[
377
+ :, l
378
+ ] * np.exp(-scaled_tau / mu0)[None, :]
379
+
367
380
  u0 = (
368
381
  np.einsum(
369
382
  "tij, tj -> it",
@@ -371,25 +384,21 @@ def _assemble_intensity_and_fluxes(
371
384
  np.exp(exponent) / (scale_tau[:, None] * K_collect_0)[l, :],
372
385
  optimize=True,
373
386
  )
374
- + (B_collect_0.T / (-scale_tau / mu0)[None, :])[:, l]
375
- * np.exp(-scaled_tau / mu0)[None, :]
376
- )
377
- elif is_antiderivative_wrt_tau and not there_is_beam_source:
378
- u0 = np.einsum(
379
- "tij, tj -> it",
380
- GC_collect_0[l, :, :],
381
- np.exp(exponent) / (scale_tau[:, None] * K_collect_0)[l, :],
382
- optimize=True,
387
+ + direct_beam_contribution
383
388
  )
384
- elif not is_antiderivative_wrt_tau and there_is_beam_source:
385
- u0 = np.einsum(
386
- "tij, tj -> it", GC_collect_0[l, :, :], np.exp(exponent), optimize=True
387
- ) + B_collect_0.T[:, l] * np.exp(-scaled_tau / mu0)[None, :]
388
389
  else:
389
- u0 = np.einsum(
390
- "tij, tj -> it", GC_collect_0[l, :, :], np.exp(exponent), optimize=True
390
+ if there_is_beam_source:
391
+ direct_beam_contribution = (
392
+ B_collect_0.T[:, l] * np.exp(-scaled_tau / mu0)[None, :]
393
+ )
394
+
395
+ u0 = (
396
+ np.einsum(
397
+ "tij, tj -> it", GC_collect_0[l, :, :], np.exp(exponent), optimize=True
398
+ )
399
+ + direct_beam_contribution
391
400
  )
392
-
401
+
393
402
  # Contribution from particular solution for isotropic internal sources
394
403
  if there_is_iso_source:
395
404
  l_uniq, l_inv = np.unique(l, return_inverse=True)
@@ -405,14 +414,16 @@ def _assemble_intensity_and_fluxes(
405
414
  )
406
415
  u0 = u0 + _mathscr_v_contribution
407
416
 
408
- if return_tau_arr and _return_act_dscale_for_reclass:
409
- return rescale_factor * np.squeeze(u0), tau_arr, act_dscale_reclassification
410
- elif return_tau_arr and not _return_act_dscale_for_reclass:
411
- return rescale_factor * np.squeeze(u0), tau_arr
412
- elif not return_tau_arr and _return_act_dscale_for_reclass:
413
- return rescale_factor * np.squeeze(u0), act_dscale_reclassification
414
- else:
415
- return rescale_factor * np.squeeze(u0)
417
+ outputs = (rescale_factor * np.squeeze(u0),)
418
+ outputs_len = 1
419
+ if return_tau_arr:
420
+ outputs += (tau_arr,)
421
+ outputs_len += 1
422
+ if _return_act_dscale_for_reclass:
423
+ outputs += (act_dscale_reclassification,)
424
+ outputs_len += 1
425
+ return outputs[0] if outputs_len == 1 else outputs
426
+
416
427
  # --------------------------------------------------------------------------------------------------------------------------
417
428
 
418
429
  # Construct the flux functions (refer to section 3.8 of the Comprehensive Documentation)
@@ -463,15 +474,6 @@ def _assemble_intensity_and_fluxes(
463
474
  else:
464
475
  _mathscr_v_contribution = 0
465
476
 
466
- if there_is_beam_source and is_antiderivative_wrt_tau:
467
- direct_beam_contribution = (
468
- (B_pos / (-scale_tau / mu0)[None, :])[:, l] * np.exp(-scaled_tau / mu0)[None, :]
469
- )
470
- elif there_is_beam_source and not is_antiderivative_wrt_tau:
471
- direct_beam_contribution = B_pos[:, l] * np.exp(-scaled_tau / mu0)[None, :]
472
- else:
473
- direct_beam_contribution = 0
474
-
475
477
  exponent = np.concatenate(
476
478
  [
477
479
  K_collect_0[l, :N] * (scaled_tau - scaled_tau_arr_lm1)[:, None],
@@ -480,7 +482,13 @@ def _assemble_intensity_and_fluxes(
480
482
  axis=-1,
481
483
  )
482
484
 
485
+ direct_beam_contribution = 0
483
486
  if is_antiderivative_wrt_tau:
487
+ if there_is_beam_source:
488
+ direct_beam_contribution = (
489
+ (B_pos / (-scale_tau / mu0)[None, :])[:, l] * np.exp(-scaled_tau / mu0)[None, :]
490
+ )
491
+
484
492
  u0_pos = (
485
493
  np.einsum(
486
494
  "tij, tj -> it",
@@ -491,11 +499,15 @@ def _assemble_intensity_and_fluxes(
491
499
  + _mathscr_v_contribution
492
500
  )
493
501
  else:
502
+ if there_is_beam_source:
503
+ direct_beam_contribution = B_pos[:, l] * np.exp(-scaled_tau / mu0)[None, :]
504
+
494
505
  u0_pos = (
495
506
  np.einsum("tij, tj -> it", GC_pos[l, :, :], np.exp(exponent))
496
507
  + direct_beam_contribution
497
508
  + _mathscr_v_contribution
498
509
  )
510
+
499
511
  flux = 2 * pi * (mu_arr_pos * W) @ u0_pos
500
512
 
501
513
  if return_tau_arr:
@@ -543,20 +555,7 @@ def _assemble_intensity_and_fluxes(
543
555
  )
544
556
  else:
545
557
  _mathscr_v_contribution = 0
546
-
547
- if there_is_beam_source and is_antiderivative_wrt_tau:
548
- direct_beam_contribution = (B_neg / (-scale_tau / mu0)[None, l])[:, l] * np.exp(-scaled_tau / mu0)[None, :]
549
- direct_beam = I0 * mu0 * np.exp(-tau / mu0) * -mu0
550
- direct_beam_scaled = I0 * mu0 * np.exp(-scaled_tau / mu0) / (-scale_tau / mu0)[None, l]
551
- elif there_is_beam_source and not is_antiderivative_wrt_tau:
552
- direct_beam_contribution = B_neg[:, l] * np.exp(-scaled_tau / mu0)[None, :]
553
- direct_beam = I0 * mu0 * np.exp(-tau / mu0)
554
- direct_beam_scaled = I0 * mu0 * np.exp(-scaled_tau / mu0)
555
- else:
556
- direct_beam_contribution = 0
557
- direct_beam = 0
558
- direct_beam_scaled = 0
559
-
558
+
560
559
  exponent = np.concatenate(
561
560
  [
562
561
  K_collect_0[l, :N] * (scaled_tau - scaled_tau_arr_lm1)[:, None],
@@ -565,18 +564,32 @@ def _assemble_intensity_and_fluxes(
565
564
  axis=-1,
566
565
  )
567
566
 
567
+ direct_beam_contribution = 0
568
+ direct_beam = 0
569
+ direct_beam_scaled = 0
568
570
  if is_antiderivative_wrt_tau:
571
+ if there_is_beam_source:
572
+ direct_beam_contribution = (B_neg / (-scale_tau / mu0)[None, l])[:, l] * np.exp(-scaled_tau / mu0)[None, :]
573
+ direct_beam = I0 * mu0 * np.exp(-tau / mu0) * -mu0
574
+ direct_beam_scaled = I0 * mu0 * np.exp(-scaled_tau / mu0) / (-scale_tau / mu0)[None, l]
575
+
569
576
  u0_neg = (
570
577
  np.einsum("tij, tj -> it", GC_neg[l, :, :], np.exp(exponent) / (scale_tau[:, None] * K_collect_0)[l, :])
571
578
  + direct_beam_contribution
572
579
  + _mathscr_v_contribution
573
580
  )
574
581
  else:
582
+ if there_is_beam_source:
583
+ direct_beam_contribution = B_neg[:, l] * np.exp(-scaled_tau / mu0)[None, :]
584
+ direct_beam = I0 * mu0 * np.exp(-tau / mu0)
585
+ direct_beam_scaled = I0 * mu0 * np.exp(-scaled_tau / mu0)
586
+
575
587
  u0_neg = (
576
588
  np.einsum("tij, tj -> it", GC_neg[l, :, :], np.exp(exponent))
577
589
  + direct_beam_contribution
578
590
  + _mathscr_v_contribution
579
591
  )
592
+
580
593
  diffuse_flux = 2 * pi * (mu_arr_pos * W) @ u0_neg + direct_beam_scaled - direct_beam
581
594
 
582
595
  if return_tau_arr:
@@ -210,28 +210,12 @@ def _solve_for_gen_and_part_sols(
210
210
 
211
211
  # --------------------------------------------------------------------------------------------------------------------------
212
212
 
213
-
214
- if there_is_beam_source and there_is_iso_source:
215
- return (
216
- G_collect.reshape((NFourier, NLayers, NQuad, NQuad)),
217
- K_collect.reshape((NFourier, NLayers, NQuad)),
218
- B_collect.reshape((NFourier, NLayers, NQuad)),
219
- G_inv_collect_0,
220
- )
221
- elif there_is_beam_source and not there_is_iso_source:
222
- return (
223
- G_collect.reshape((NFourier, NLayers, NQuad, NQuad)),
224
- K_collect.reshape((NFourier, NLayers, NQuad)),
225
- B_collect.reshape((NFourier, NLayers, NQuad)),
226
- )
227
- elif not there_is_beam_source and there_is_iso_source:
228
- return (
229
- G_collect.reshape((NFourier, NLayers, NQuad, NQuad)),
230
- K_collect.reshape((NFourier, NLayers, NQuad)),
231
- G_inv_collect_0,
232
- )
233
- else:
234
- return (
235
- G_collect.reshape((NFourier, NLayers, NQuad, NQuad)),
236
- K_collect.reshape((NFourier, NLayers, NQuad)),
237
- )
213
+ outputs = (
214
+ G_collect.reshape((NFourier, NLayers, NQuad, NQuad)),
215
+ K_collect.reshape((NFourier, NLayers, NQuad)),
216
+ )
217
+ if there_is_beam_source:
218
+ outputs += (B_collect.reshape((NFourier, NLayers, NQuad)),)
219
+ if there_is_iso_source:
220
+ outputs += (G_inv_collect_0,)
221
+ return outputs
@@ -243,9 +243,10 @@ def pydisort(
243
243
  raise ValueError("The zeroth dimension of the shape of `s_poly_coeffs` does not match the number of layers which is deduced from the length of `tau_arr`.")
244
244
  # Value checks on the phase function Legendre coefficients
245
245
  if not np.all(omega_arr * Leg_coeffs_all[:, 0] == omega_arr):
246
- raise ValueError("The first phase function Legendre coefficient must equal 1.")
246
+ warnings.warn("The zeroth index phase function Legendre coefficient must be, and has been corrected to, 1.")
247
+ Leg_coeffs_all[:, 0] = 1
247
248
  if not (np.all(-1 <= Leg_coeffs_all) and np.all(Leg_coeffs_all <= 1)):
248
- raise ValueError("The phase function Legendre coefficients must all be between -1 and 1.")
249
+ raise ValueError("The phase function Legendre coefficients must all be between -1 and 1.")
249
250
  # Conditions on the number of quadrature angles (NQuad), Legendre coefficients (NLeg) and loops (NFourier)
250
251
  if not NQuad >= 2:
251
252
  raise ValueError("There must be at least two streams.")
@@ -256,7 +257,7 @@ def pydisort(
256
257
  if not NFourier <= NLeg:
257
258
  raise ValueError("The number of Fourier modes to use in the solution must be less than or equal to the number of phase function Legendre coefficients used.")
258
259
  if NFourier > 64 and not only_flux:
259
- warnings.warn("`NFourier` is large and may cause errors, consider decreasing `NFourier` to 64 and it probably should be even less.")
260
+ warnings.warn("`NFourier` is large and may cause errors, consider decreasing `NFourier` to 64 and it probably should be even less. By default `NFourier` equals `NQuad`.")
260
261
  # Not strictly necessary but there will be tremendous inaccuracies if this is violated
261
262
  if not NLeg <= NQuad:
262
263
  raise ValueError("There should be more streams than the number of phase function Legendre coefficients used.")
@@ -316,24 +317,31 @@ def pydisort(
316
317
  scale_tau = 1 - omega_arr * f_arr
317
318
  scaled_thickness_arr = scale_tau * thickness_arr
318
319
  scaled_tau_arr_with_0 = np.insert(np.cumsum(scaled_thickness_arr), 0, 0)
319
- weighted_scaled_Leg_coeffs = ((Leg_coeffs - f_arr[:, None]) / (1 - f_arr[:, None])) * (
320
- 2 * np.arange(NLeg) + 1
321
- )[None, :]
320
+ scaled_Leg_coeffs = (Leg_coeffs - f_arr[:, None]) / (1 - f_arr[:, None])
321
+ weighted_scaled_Leg_coeffs = scaled_Leg_coeffs * (2 * np.arange(NLeg) + 1)[None, :]
322
322
  scaled_omega_arr = (1 - f_arr) / scale_tau * omega_arr
323
323
 
324
324
  translations = scaled_tau_arr_with_0[:-1] - scale_tau * np.insert(tau_arr[:-1], 0, 0)
325
325
  scaled_s_poly_coeffs = (
326
326
  subroutines.affine_transform_poly_coeffs(s_poly_coeffs, scale_tau, translations)
327
327
  / scale_tau[:, None] # Divide by d\tau^* / d\tau
328
- )
328
+ ) * (1 - omega_arr[:, None]) # Enforce Kirchoff's Law of Thermal Radiation: absorptivity equals emissivity
329
329
 
330
330
  else:
331
331
  # This is a shortcut to the same results
332
332
  scale_tau = np.ones(NLayers)
333
333
  scaled_tau_arr_with_0 = np.insert(tau_arr, 0, 0)
334
- weighted_scaled_Leg_coeffs = Leg_coeffs * (2 * np.arange(NLeg) + 1)[None, :]
334
+ scaled_Leg_coeffs = Leg_coeffs
335
+ weighted_scaled_Leg_coeffs = scaled_Leg_coeffs * (2 * np.arange(NLeg) + 1)[None, :]
335
336
  scaled_omega_arr = omega_arr
336
- scaled_s_poly_coeffs = s_poly_coeffs
337
+ scaled_s_poly_coeffs = s_poly_coeffs * (1 - omega_arr[:, None]) # Enforce Kirchoff's Law of Thermal Radiation: absorptivity equals emissivity
338
+
339
+ if np.any(scaled_omega_arr > 1 - 1e-6):
340
+ warnings.warn("Some delta-scaled single-scattering albedos are very close to 1 which may cause numerical instability.")
341
+ if (np.any(-0.95 > scaled_Leg_coeffs[:, 1:]) and np.any(scaled_Leg_coeffs[:, 1:] > 0.95)):
342
+ warnings.warn("Some delta-scaled phase function Legendre coefficients have a magnitude that is very close to 1" +
343
+ " (this excludes the zeroth index coefficient which must be 1) and this may cause numerical instability.")
344
+
337
345
  # --------------------------------------------------------------------------------------------------------------------------
338
346
 
339
347
  # Rescale of sources
@@ -361,7 +369,7 @@ def pydisort(
361
369
  b_neg = (b_neg / rescale_factor).copy()
362
370
  # --------------------------------------------------------------------------------------------------------------------------
363
371
 
364
- if NT_cor and not only_flux and there_is_beam_source and np.any(f_arr > 0) and NLeg < NLeg_all:
372
+ if NT_cor and not only_flux and there_is_beam_source and np.any(f_arr > 0) and NLeg < NLeg_all and np.any(omega_arr > 0):
365
373
 
366
374
  ############################### Perform NT corrections on the intensity but not the flux ###############################
367
375
  ############################### Refer to section 3.7.2 of the Comprehensive Documentation ##############################
@@ -384,12 +384,11 @@ def linear_spline_coefficients(x, y, check_inputs=True):
384
384
 
385
385
 
386
386
 
387
- def generate_s_poly_coeffs(tau_arr, TEMPER, WVNMLO, WVNMHI, omega_arr=None, **kwargs):
387
+ def generate_s_poly_coeffs(tau_arr, TEMPER, WVNMLO, WVNMHI, **kwargs):
388
388
  """Generate DISORT-equivalent ``s_poly_coeffs`` for input into ``pydisort``.
389
389
  This convenience function is provided to help match the inputs for Stamnes' DISORT to those for PythonicDISORT.
390
- If ``omega_arr`` is specified, the coefficients will be multiplied by emissivity factors equal to ``1 - omega_arr``
391
- per Kirchoff's law of thermal radiation, and Kirchoff's law is enforced in Stamnes' DISORT.
392
- Otherwise, the emissivities will be set to 1 and users can multiply their own emissivity factors.
390
+ Note that the coefficients will be multiplied by emissivity factors equal to ``1 - omega_arr`` inside
391
+ `pydisort`, i.e. Kirchoff's law of thermal radiation is enforced, just like in Stamnes' DISORT.
393
392
 
394
393
  Parameters
395
394
  ----------
@@ -402,8 +401,6 @@ def generate_s_poly_coeffs(tau_arr, TEMPER, WVNMLO, WVNMHI, omega_arr=None, **kw
402
401
  Lower bound of wavenumber interval with units m^-1. This variable is identically named in Stamnes' DISORT.
403
402
  WVNMHI : float
404
403
  Upper bound of wavenumber interval with units m^-1. This variable is identically named in Stamnes' DISORT.
405
- omega_arr : optional, array or float
406
- Single-scattering albedo of each atmospheric layer which is required to compute the emissivity of each layer.
407
404
  **kwargs
408
405
  Keyword arguments to pass to ``scipy.integrate.quad_vec``.
409
406
 
@@ -426,26 +423,10 @@ def generate_s_poly_coeffs(tau_arr, TEMPER, WVNMLO, WVNMHI, omega_arr=None, **kw
426
423
  lambda WVNM: Planck(TEMPER, WVNM), WVNMLO, WVNMHI, **kwargs
427
424
  )[0]
428
425
 
429
- if omega_arr is None:
430
- return (
431
- linear_spline_coefficients(
432
- tau_arr_with_0, blackbody_emission_at_each_boundary, check_inputs=False
433
- )
434
- )
435
- elif np.isscalar(omega_arr):
436
- return (
437
- linear_spline_coefficients(
438
- tau_arr_with_0, blackbody_emission_at_each_boundary, check_inputs=False
439
- )
440
- * (1 - omega_arr)
441
- )
442
- else:
443
- return (
444
- linear_spline_coefficients(
445
- tau_arr_with_0, blackbody_emission_at_each_boundary, check_inputs=False
446
- )
447
- * (1 - omega_arr)[:, None]
448
- )
426
+ return linear_spline_coefficients(
427
+ tau_arr_with_0, blackbody_emission_at_each_boundary, check_inputs=False
428
+ )
429
+
449
430
 
450
431
 
451
432
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PythonicDISORT
3
- Version: 1.1
3
+ Version: 1.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
@@ -67,8 +67,8 @@ These notebooks double up as examples of how to use PythonicDISORT. The tests wh
67
67
  * Test Problem 5: Cloud C.1 Scattering, Beam Source
68
68
  * Test Problem 6: No Scattering, Increasingly Complex Sources (relevant for modeling longwave radiation)
69
69
  * Test Problem 7: Absorption + Scattering + All Possible Sources, Lambertian and Hapke Surface Reflectivities (one layer)
70
- * Test Problem 8: Absorbing / Isotropic-Scattering Medium With (two layers)
71
- * Test Problem 9: General Emitting / Absorbing / Scattering Medium with (many different layers)
70
+ * Test Problem 8: Absorbing / Isotropic-Scattering Medium (multiple layers)
71
+ * Test Problem 9: General Emitting / Absorbing / Scattering Medium (multiple layers)
72
72
  * Test Problem 11: Single-Layer vs. Multiple Layers (no corresponding Jupyter Notebook)
73
73
 
74
74
  # Installation
@@ -0,0 +1,11 @@
1
+ PythonicDISORT/__init__.py,sha256=V1obNzaFgqInxqYJ5h_r6JHbZRxx4VM5VgzCIS6EEzI,84
2
+ PythonicDISORT/_assemble_intensity_and_fluxes.py,sha256=okORQDxUWZgmMZmIRPNzIOqk8UQAcoc7o8Wr3wxrgDc,29261
3
+ PythonicDISORT/_solve_for_coeffs.py,sha256=Bb-C5OJt355x8_v8WFB2sJutBtSTAFNIX4OxLQJk9-0,16539
4
+ PythonicDISORT/_solve_for_gen_and_part_sols.py,sha256=InZPpyRkfmt7gq5r64FPHjXJVMV41ixZygJd4pWpLI4,12461
5
+ PythonicDISORT/pydisort.py,sha256=ULGw_fqcnC7JQ3voJr9oKlaB3yrDI_sKe5jOU0Xj2Rc,40043
6
+ PythonicDISORT/subroutines.py,sha256=d0mjOgxqSFoNZnLmOkuSWqO3HjojR9S-2orGZSdGJkU,33208
7
+ pythonicdisort-1.2.dist-info/LICENSE.md,sha256=q1i1QVh0OLzK0fj6kaNRNWsM_KZca66JwWgWwbuCPlA,1092
8
+ pythonicdisort-1.2.dist-info/METADATA,sha256=PLXXaPDMmva47U6AM6cNFSrb0J-FT9xCkiww8tsvE3c,8297
9
+ pythonicdisort-1.2.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
10
+ pythonicdisort-1.2.dist-info/top_level.txt,sha256=aX6kCeI1E7naZz3xfw4_mIbWh5KBh9dmF3FIvgP5m3Y,15
11
+ pythonicdisort-1.2.dist-info/RECORD,,
@@ -1,11 +0,0 @@
1
- PythonicDISORT/__init__.py,sha256=V1obNzaFgqInxqYJ5h_r6JHbZRxx4VM5VgzCIS6EEzI,84
2
- PythonicDISORT/_assemble_intensity_and_fluxes.py,sha256=H7XxaRBHNIxNZsB49onFcU1hAsBIFWCeTBJ4NhoCT4w,29926
3
- PythonicDISORT/_solve_for_coeffs.py,sha256=Bb-C5OJt355x8_v8WFB2sJutBtSTAFNIX4OxLQJk9-0,16539
4
- PythonicDISORT/_solve_for_gen_and_part_sols.py,sha256=NVAFve6FNIEiku4xqaXBAI4G2HYIbhjcLC_B0nhGXXM,13131
5
- PythonicDISORT/pydisort.py,sha256=jiPMLw-zcwRoZQq2IjZhAxiuHlhC3yY72wvAxAepfgg,39113
6
- PythonicDISORT/subroutines.py,sha256=rf36t8coXQdnMb0NrEfgrOWDWZHkkH6KDIE3COueEbQ,34034
7
- pythonicdisort-1.1.dist-info/LICENSE.md,sha256=q1i1QVh0OLzK0fj6kaNRNWsM_KZca66JwWgWwbuCPlA,1092
8
- pythonicdisort-1.1.dist-info/METADATA,sha256=boJu4nE6zzVbJrwuVJWv2M3PTQhJpoS87XeS9M8ki2U,8308
9
- pythonicdisort-1.1.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
10
- pythonicdisort-1.1.dist-info/top_level.txt,sha256=aX6kCeI1E7naZz3xfw4_mIbWh5KBh9dmF3FIvgP5m3Y,15
11
- pythonicdisort-1.1.dist-info/RECORD,,