pycontrails 0.42.0__cp311-cp311-win_amd64.whl → 0.42.2__cp311-cp311-win_amd64.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.
Potentially problematic release.
This version of pycontrails might be problematic. Click here for more details.
- pycontrails/_version.py +2 -2
- pycontrails/core/cache.py +4 -6
- pycontrails/core/datalib.py +5 -2
- pycontrails/core/fleet.py +59 -7
- pycontrails/core/flight.py +175 -49
- pycontrails/core/flightplan.py +238 -0
- pycontrails/core/interpolation.py +11 -15
- pycontrails/core/met.py +5 -5
- pycontrails/core/models.py +4 -0
- pycontrails/core/rgi_cython.cp311-win_amd64.pyd +0 -0
- pycontrails/core/vector.py +17 -12
- pycontrails/datalib/ecmwf/common.py +14 -19
- pycontrails/ext/bada/__init__.py +6 -6
- pycontrails/ext/cirium/__init__.py +2 -2
- pycontrails/models/cocip/cocip.py +37 -39
- pycontrails/models/cocip/cocip_params.py +37 -30
- pycontrails/models/cocip/cocip_uncertainty.py +47 -58
- pycontrails/models/cocip/radiative_forcing.py +220 -193
- pycontrails/models/cocip/wake_vortex.py +96 -91
- pycontrails/models/humidity_scaling.py +265 -8
- pycontrails/models/issr.py +1 -1
- pycontrails/models/quantiles/era5_ensemble_quantiles.npy +0 -0
- pycontrails/models/quantiles/iagos_quantiles.npy +0 -0
- pycontrails/models/sac.py +2 -0
- pycontrails/physics/geo.py +2 -1
- pycontrails/utils/json.py +3 -3
- {pycontrails-0.42.0.dist-info → pycontrails-0.42.2.dist-info}/METADATA +4 -7
- {pycontrails-0.42.0.dist-info → pycontrails-0.42.2.dist-info}/RECORD +32 -29
- {pycontrails-0.42.0.dist-info → pycontrails-0.42.2.dist-info}/LICENSE +0 -0
- {pycontrails-0.42.0.dist-info → pycontrails-0.42.2.dist-info}/NOTICE +0 -0
- {pycontrails-0.42.0.dist-info → pycontrails-0.42.2.dist-info}/WHEEL +0 -0
- {pycontrails-0.42.0.dist-info → pycontrails-0.42.2.dist-info}/top_level.txt +0 -0
|
@@ -12,6 +12,7 @@ from __future__ import annotations
|
|
|
12
12
|
from dataclasses import dataclass
|
|
13
13
|
|
|
14
14
|
import numpy as np
|
|
15
|
+
import numpy.typing as npt
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
@dataclass
|
|
@@ -150,8 +151,10 @@ rf_const = RFConstants()
|
|
|
150
151
|
|
|
151
152
|
|
|
152
153
|
def habit_weights(
|
|
153
|
-
r_vol_um:
|
|
154
|
-
|
|
154
|
+
r_vol_um: npt.NDArray[np.float_],
|
|
155
|
+
habit_distributions: npt.NDArray[np.float_],
|
|
156
|
+
radius_threshold_um: npt.NDArray[np.float_],
|
|
157
|
+
) -> npt.NDArray[np.float_]:
|
|
155
158
|
r"""Assign weights to different ice particle habits for each waypoint.
|
|
156
159
|
|
|
157
160
|
For each waypoint, the distinct mix of ice particle habits are approximated
|
|
@@ -167,18 +170,18 @@ def habit_weights(
|
|
|
167
170
|
|
|
168
171
|
Parameters
|
|
169
172
|
----------
|
|
170
|
-
r_vol_um : np.
|
|
173
|
+
r_vol_um : npt.NDArray[np.float_]
|
|
171
174
|
Contrail ice particle volume mean radius, [:math:`\mu m`]
|
|
172
|
-
habit_distributions : np.
|
|
175
|
+
habit_distributions : npt.NDArray[np.float_]
|
|
173
176
|
Habit weight distributions.
|
|
174
177
|
See :attr:`CocipParams().habit_distributions`
|
|
175
|
-
radius_threshold_um : np.
|
|
178
|
+
radius_threshold_um : npt.NDArray[np.float_]
|
|
176
179
|
Radius thresholds for habit distributions.
|
|
177
180
|
See :attr:`CocipParams.radius_threshold_um`
|
|
178
181
|
|
|
179
182
|
Returns
|
|
180
183
|
-------
|
|
181
|
-
np.
|
|
184
|
+
npt.NDArray[np.float_]
|
|
182
185
|
Array with shape ``n_waypoints x 8 columns``, where each column is the weights to the ice
|
|
183
186
|
particle habits, [:math:`[0 - 1]`], and the sum of each column should be equal to 1.
|
|
184
187
|
|
|
@@ -189,7 +192,7 @@ def habit_weights(
|
|
|
189
192
|
if there is a size mistmatch with ``radius_threshold_um``.
|
|
190
193
|
"""
|
|
191
194
|
# all rows of the habit weights should sum to 1
|
|
192
|
-
if not np.all(np.
|
|
195
|
+
if not np.all(np.round(np.sum(habit_distributions, axis=1), 3) == 1):
|
|
193
196
|
raise ValueError("Habit weight distributions must sum to 1 across columns")
|
|
194
197
|
|
|
195
198
|
if habit_distributions.shape[0] != (radius_threshold_um.size + 1):
|
|
@@ -199,24 +202,27 @@ def habit_weights(
|
|
|
199
202
|
)
|
|
200
203
|
|
|
201
204
|
# assign ice particle habits for each waypoint
|
|
202
|
-
|
|
205
|
+
idx = habit_weight_regime_idx(r_vol_um, radius_threshold_um)
|
|
206
|
+
return habit_distributions[idx]
|
|
203
207
|
|
|
204
208
|
|
|
205
|
-
def habit_weight_regime_idx(
|
|
209
|
+
def habit_weight_regime_idx(
|
|
210
|
+
r_vol_um: npt.NDArray[np.float_], radius_threshold_um: npt.NDArray[np.float_]
|
|
211
|
+
) -> npt.NDArray[np.intp]:
|
|
206
212
|
r"""
|
|
207
213
|
Determine regime of ice particle habits based on contrail ice particle volume mean radius.
|
|
208
214
|
|
|
209
215
|
Parameters
|
|
210
216
|
----------
|
|
211
|
-
r_vol_um : np.
|
|
217
|
+
r_vol_um : npt.NDArray[np.float_]
|
|
212
218
|
Contrail ice particle volume mean radius, [:math:`\mu m`]
|
|
213
|
-
radius_threshold_um : np.
|
|
219
|
+
radius_threshold_um : npt.NDArray[np.float_]
|
|
214
220
|
Radius thresholds for habit distributions.
|
|
215
221
|
See :attr:`CocipParams.radius_threshold_um`
|
|
216
222
|
|
|
217
223
|
Returns
|
|
218
224
|
-------
|
|
219
|
-
np.
|
|
225
|
+
npt.NDArray[np.intp]
|
|
220
226
|
Row index of the habit distribution in array :attr:`CocipParams().habit_distributions`
|
|
221
227
|
"""
|
|
222
228
|
# find the regime for each waypoint using thresholds
|
|
@@ -228,7 +234,9 @@ def habit_weight_regime_idx(r_vol_um: np.ndarray, radius_threshold_um: np.ndarra
|
|
|
228
234
|
return idx
|
|
229
235
|
|
|
230
236
|
|
|
231
|
-
def effective_radius_by_habit(
|
|
237
|
+
def effective_radius_by_habit(
|
|
238
|
+
r_vol_um: npt.NDArray[np.float_], habit_idx: npt.NDArray[np.intp]
|
|
239
|
+
) -> np.ndarray:
|
|
232
240
|
r"""Calculate the effective radius ``r_eff_um`` via the mean ice particle radius and habit type.
|
|
233
241
|
|
|
234
242
|
The ``habit_idx`` corresponds to the habit types in ``rf_const.habits``.
|
|
@@ -237,15 +245,15 @@ def effective_radius_by_habit(r_vol_um: np.ndarray, habit_idx: np.ndarray) -> np
|
|
|
237
245
|
|
|
238
246
|
Parameters
|
|
239
247
|
----------
|
|
240
|
-
r_vol_um : np.
|
|
248
|
+
r_vol_um : npt.NDArray[np.float_]
|
|
241
249
|
Contrail ice particle volume mean radius, [:math:`\mu m`]
|
|
242
|
-
habit_idx : np.
|
|
250
|
+
habit_idx : npt.NDArray[np.intp]
|
|
243
251
|
Habit type index for the contrail ice particle, corresponding to the
|
|
244
252
|
habits in ``rf_const.habits``.
|
|
245
253
|
|
|
246
254
|
Returns
|
|
247
255
|
-------
|
|
248
|
-
np.
|
|
256
|
+
npt.NDArray[np.float_]
|
|
249
257
|
Effective radius of ice particles for each combination of ``r_vol_um``
|
|
250
258
|
and ``habit_idx``, [:math:`\mu m`]
|
|
251
259
|
|
|
@@ -253,167 +261,180 @@ def effective_radius_by_habit(r_vol_um: np.ndarray, habit_idx: np.ndarray) -> np
|
|
|
253
261
|
----------
|
|
254
262
|
- :cite:`schumannEffectiveRadiusIce2011`
|
|
255
263
|
"""
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
264
|
+
cond_list = [
|
|
265
|
+
habit_idx == 0,
|
|
266
|
+
habit_idx == 1,
|
|
267
|
+
habit_idx == 2,
|
|
268
|
+
habit_idx == 3,
|
|
269
|
+
habit_idx == 4,
|
|
270
|
+
habit_idx == 5,
|
|
271
|
+
habit_idx == 6,
|
|
272
|
+
habit_idx == 7,
|
|
273
|
+
]
|
|
274
|
+
func_list = [
|
|
275
|
+
effective_radius_sphere,
|
|
276
|
+
effective_radius_solid_column,
|
|
277
|
+
effective_radius_hollow_column,
|
|
278
|
+
effective_radius_rough_aggregate,
|
|
279
|
+
effective_radius_rosette,
|
|
280
|
+
effective_radius_plate,
|
|
281
|
+
effective_radius_droxtal,
|
|
282
|
+
effective_radius_myhre,
|
|
283
|
+
0.0,
|
|
284
|
+
]
|
|
285
|
+
return np.piecewise(r_vol_um, cond_list, func_list)
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
def effective_radius_sphere(r_vol_um: npt.NDArray[np.float_]) -> npt.NDArray[np.float_]:
|
|
270
289
|
r"""
|
|
271
290
|
Calculate the effective radius of contrail ice particles assuming a sphere particle habit.
|
|
272
291
|
|
|
273
292
|
Parameters
|
|
274
293
|
----------
|
|
275
|
-
r_vol_um : np.
|
|
294
|
+
r_vol_um : npt.NDArray[np.float_]
|
|
276
295
|
Contrail ice particle volume mean radius, [:math:`\mu m`]
|
|
277
296
|
|
|
278
297
|
Returns
|
|
279
298
|
-------
|
|
280
|
-
np.
|
|
299
|
+
npt.NDArray[np.float_]
|
|
281
300
|
Effective radius, [:math:`\mu m`]
|
|
282
301
|
"""
|
|
283
|
-
return np.minimum(r_vol_um, 25)
|
|
302
|
+
return np.minimum(r_vol_um, 25.0)
|
|
284
303
|
|
|
285
304
|
|
|
286
|
-
def effective_radius_solid_column(r_vol_um: np.
|
|
305
|
+
def effective_radius_solid_column(r_vol_um: npt.NDArray[np.float_]) -> npt.NDArray[np.float_]:
|
|
287
306
|
r"""
|
|
288
307
|
Calculate the effective radius of contrail ice particles assuming a solid column particle habit.
|
|
289
308
|
|
|
290
309
|
Parameters
|
|
291
310
|
----------
|
|
292
|
-
r_vol_um : np.
|
|
311
|
+
r_vol_um : npt.NDArray[np.float_]
|
|
293
312
|
Contrail ice particle volume mean radius, [:math:`\mu m`]
|
|
294
313
|
|
|
295
314
|
Returns
|
|
296
315
|
-------
|
|
297
|
-
np.
|
|
316
|
+
npt.NDArray[np.float_]
|
|
298
317
|
Effective radius, [:math:`\mu m`]
|
|
299
318
|
"""
|
|
300
319
|
r_eff_um = (
|
|
301
320
|
0.2588 * np.exp(-(6.912e-3 * r_vol_um)) + 0.6372 * np.exp(-(3.142e-4 * r_vol_um))
|
|
302
321
|
) * r_vol_um
|
|
303
|
-
|
|
304
|
-
|
|
322
|
+
is_small = r_vol_um <= 42.2
|
|
323
|
+
r_eff_um[is_small] = 0.824 * r_vol_um[is_small]
|
|
324
|
+
return np.minimum(r_eff_um, 45.0)
|
|
305
325
|
|
|
306
326
|
|
|
307
|
-
def effective_radius_hollow_column(r_vol_um: np.
|
|
327
|
+
def effective_radius_hollow_column(r_vol_um: npt.NDArray[np.float_]) -> npt.NDArray[np.float_]:
|
|
308
328
|
r"""Calculate the effective radius of ice particles assuming a hollow column particle habit.
|
|
309
329
|
|
|
310
330
|
Parameters
|
|
311
331
|
----------
|
|
312
|
-
r_vol_um : np.
|
|
332
|
+
r_vol_um : npt.NDArray[np.float_]
|
|
313
333
|
Contrail ice particle volume mean radius, [:math:`\mu m`]
|
|
314
334
|
|
|
315
335
|
Returns
|
|
316
336
|
-------
|
|
317
|
-
np.
|
|
337
|
+
npt.NDArray[np.float_]
|
|
318
338
|
Effective radius, [:math:`\mu m`]
|
|
319
339
|
"""
|
|
320
340
|
r_eff_um = (
|
|
321
341
|
0.2281 * np.exp(-(7.359e-3 * r_vol_um)) + 0.5651 * np.exp(-(3.350e-4 * r_vol_um))
|
|
322
342
|
) * r_vol_um
|
|
323
|
-
|
|
324
|
-
|
|
343
|
+
is_small = r_vol_um <= 39.7
|
|
344
|
+
r_eff_um[is_small] = 0.729 * r_vol_um[is_small]
|
|
345
|
+
return np.minimum(r_eff_um, 45.0)
|
|
325
346
|
|
|
326
347
|
|
|
327
|
-
def effective_radius_rough_aggregate(r_vol_um: np.
|
|
348
|
+
def effective_radius_rough_aggregate(r_vol_um: npt.NDArray[np.float_]) -> npt.NDArray[np.float_]:
|
|
328
349
|
r"""Calculate the effective radius of ice particles assuming a rough aggregate particle habit.
|
|
329
350
|
|
|
330
351
|
Parameters
|
|
331
352
|
----------
|
|
332
|
-
r_vol_um : np.
|
|
353
|
+
r_vol_um : npt.NDArray[np.float_]
|
|
333
354
|
Contrail ice particle volume mean radius, [:math:`\mu m`]
|
|
334
355
|
|
|
335
356
|
Returns
|
|
336
357
|
-------
|
|
337
|
-
np.
|
|
358
|
+
npt.NDArray[np.float_]
|
|
338
359
|
Effective radius, [:math:`\mu m`]
|
|
339
360
|
"""
|
|
340
361
|
r_eff_um = 0.574 * r_vol_um
|
|
341
|
-
return np.minimum(r_eff_um, 45)
|
|
362
|
+
return np.minimum(r_eff_um, 45.0)
|
|
342
363
|
|
|
343
364
|
|
|
344
|
-
def effective_radius_rosette(r_vol_um: np.
|
|
365
|
+
def effective_radius_rosette(r_vol_um: npt.NDArray[np.float_]) -> npt.NDArray[np.float_]:
|
|
345
366
|
r"""
|
|
346
367
|
Calculate the effective radius of contrail ice particles assuming a rosette particle habit.
|
|
347
368
|
|
|
348
369
|
Parameters
|
|
349
370
|
----------
|
|
350
|
-
r_vol_um : np.
|
|
371
|
+
r_vol_um : npt.NDArray[np.float_]
|
|
351
372
|
Contrail ice particle volume mean radius, [:math:`\mu m`]
|
|
352
373
|
|
|
353
374
|
Returns
|
|
354
375
|
-------
|
|
355
|
-
np.
|
|
376
|
+
npt.NDArray[np.float_]
|
|
356
377
|
Effective radius, [:math:`\mu m`]
|
|
357
378
|
"""
|
|
358
379
|
r_eff_um = r_vol_um * (
|
|
359
380
|
0.1770 * np.exp(-(2.144e-2 * r_vol_um)) + 0.4267 * np.exp(-(3.562e-4 * r_vol_um))
|
|
360
381
|
)
|
|
361
|
-
return np.minimum(r_eff_um, 45)
|
|
382
|
+
return np.minimum(r_eff_um, 45.0)
|
|
362
383
|
|
|
363
384
|
|
|
364
|
-
def effective_radius_plate(r_vol_um: np.
|
|
385
|
+
def effective_radius_plate(r_vol_um: npt.NDArray[np.float_]) -> npt.NDArray[np.float_]:
|
|
365
386
|
r"""
|
|
366
387
|
Calculate the effective radius of contrail ice particles assuming a plate particle habit.
|
|
367
388
|
|
|
368
389
|
Parameters
|
|
369
390
|
----------
|
|
370
|
-
r_vol_um : np.
|
|
391
|
+
r_vol_um : npt.NDArray[np.float_]
|
|
371
392
|
Contrail ice particle volume mean radius, [:math:`\mu m`]
|
|
372
393
|
|
|
373
394
|
Returns
|
|
374
395
|
-------
|
|
375
|
-
np.
|
|
396
|
+
npt.NDArray[np.float_]
|
|
376
397
|
Effective radius, [:math:`\mu m`]
|
|
377
398
|
"""
|
|
378
399
|
r_eff_um = r_vol_um * (
|
|
379
400
|
0.1663 + 0.3713 * np.exp(-(0.0336 * r_vol_um)) + 0.3309 * np.exp(-(0.0035 * r_vol_um))
|
|
380
401
|
)
|
|
381
|
-
return np.minimum(r_eff_um, 45)
|
|
402
|
+
return np.minimum(r_eff_um, 45.0)
|
|
382
403
|
|
|
383
404
|
|
|
384
|
-
def effective_radius_droxtal(r_vol_um: np.
|
|
405
|
+
def effective_radius_droxtal(r_vol_um: npt.NDArray[np.float_]) -> npt.NDArray[np.float_]:
|
|
385
406
|
r"""
|
|
386
407
|
Calculate the effective radius of contrail ice particles assuming a droxtal particle habit.
|
|
387
408
|
|
|
388
409
|
Parameters
|
|
389
410
|
----------
|
|
390
|
-
r_vol_um : np.
|
|
411
|
+
r_vol_um : npt.NDArray[np.float_]
|
|
391
412
|
Contrail ice particle volume mean radius, [:math:`\mu m`]
|
|
392
413
|
|
|
393
414
|
Returns
|
|
394
415
|
-------
|
|
395
|
-
np.
|
|
416
|
+
npt.NDArray[np.float_]
|
|
396
417
|
Effective radius, [:math:`\mu m`]
|
|
397
418
|
"""
|
|
398
419
|
r_eff_um = 0.94 * r_vol_um
|
|
399
|
-
return np.minimum(r_eff_um, 45)
|
|
420
|
+
return np.minimum(r_eff_um, 45.0)
|
|
400
421
|
|
|
401
422
|
|
|
402
|
-
def effective_radius_myhre(r_vol_um: np.
|
|
423
|
+
def effective_radius_myhre(r_vol_um: npt.NDArray[np.float_]) -> npt.NDArray[np.float_]:
|
|
403
424
|
r"""
|
|
404
425
|
Calculate the effective radius of contrail ice particles assuming a sphere particle habit.
|
|
405
426
|
|
|
406
427
|
Parameters
|
|
407
428
|
----------
|
|
408
|
-
r_vol_um : np.
|
|
429
|
+
r_vol_um : npt.NDArray[np.float_]
|
|
409
430
|
Contrail ice particle volume mean radius, [:math:`\mu m`]
|
|
410
431
|
|
|
411
432
|
Returns
|
|
412
433
|
-------
|
|
413
|
-
np.
|
|
434
|
+
npt.NDArray[np.float_]
|
|
414
435
|
Effective radius, [:math:`\mu m`]
|
|
415
436
|
"""
|
|
416
|
-
return np.minimum(r_vol_um, 45)
|
|
437
|
+
return np.minimum(r_vol_um, 45.0)
|
|
417
438
|
|
|
418
439
|
|
|
419
440
|
# -----------------
|
|
@@ -422,14 +443,14 @@ def effective_radius_myhre(r_vol_um: np.ndarray) -> np.ndarray:
|
|
|
422
443
|
|
|
423
444
|
|
|
424
445
|
def longwave_radiative_forcing(
|
|
425
|
-
r_vol_um: np.
|
|
426
|
-
olr: np.
|
|
427
|
-
air_temperature: np.
|
|
428
|
-
tau_contrail: np.
|
|
429
|
-
tau_cirrus: np.
|
|
430
|
-
habit_weights_: np.
|
|
431
|
-
r_eff_um: np.
|
|
432
|
-
) -> np.
|
|
446
|
+
r_vol_um: npt.NDArray[np.float_],
|
|
447
|
+
olr: npt.NDArray[np.float_],
|
|
448
|
+
air_temperature: npt.NDArray[np.float_],
|
|
449
|
+
tau_contrail: npt.NDArray[np.float_],
|
|
450
|
+
tau_cirrus: npt.NDArray[np.float_],
|
|
451
|
+
habit_weights_: npt.NDArray[np.float_],
|
|
452
|
+
r_eff_um: npt.NDArray[np.float_] | None = None,
|
|
453
|
+
) -> npt.NDArray[np.float_]:
|
|
433
454
|
r"""
|
|
434
455
|
Calculate the local contrail longwave radiative forcing (:math:`RF_{LW}`).
|
|
435
456
|
|
|
@@ -437,28 +458,28 @@ def longwave_radiative_forcing(
|
|
|
437
458
|
|
|
438
459
|
Parameters
|
|
439
460
|
----------
|
|
440
|
-
r_vol_um : np.
|
|
461
|
+
r_vol_um : npt.NDArray[np.float_]
|
|
441
462
|
Contrail ice particle volume mean radius, [:math:`\mu m`]
|
|
442
|
-
olr : np.
|
|
463
|
+
olr : npt.NDArray[np.float_]
|
|
443
464
|
Outgoing longwave radiation at each waypoint, [:math:`W m^{-2}`]
|
|
444
|
-
air_temperature : np.
|
|
465
|
+
air_temperature : npt.NDArray[np.float_]
|
|
445
466
|
Ambient temperature at each waypoint, [:math:`K`]
|
|
446
|
-
tau_contrail : np.
|
|
467
|
+
tau_contrail : npt.NDArray[np.float_]
|
|
447
468
|
Contrail optical depth at each waypoint
|
|
448
|
-
tau_cirrus : np.
|
|
469
|
+
tau_cirrus : npt.NDArray[np.float_]
|
|
449
470
|
Optical depth of numerical weather prediction (NWP) cirrus above the
|
|
450
471
|
contrail at each waypoint
|
|
451
|
-
habit_weights_ : np.
|
|
472
|
+
habit_weights_ : npt.NDArray[np.float_]
|
|
452
473
|
Weights to different ice particle habits for each waypoint,
|
|
453
474
|
``n_waypoints x 8`` (habit) columns, [:math:`[0 - 1]`]
|
|
454
|
-
r_eff_um : np.
|
|
475
|
+
r_eff_um : npt.NDArray[np.float_], optional
|
|
455
476
|
Provide effective radius corresponding to elements in ``r_vol_um``, [:math:`\mu m`].
|
|
456
477
|
Defaults to None, which means the effective radius will be calculated using ``r_vol_um``
|
|
457
478
|
and habit types in :func:`effective_radius_by_habit`.
|
|
458
479
|
|
|
459
480
|
Returns
|
|
460
481
|
-------
|
|
461
|
-
np.
|
|
482
|
+
npt.NDArray[np.float_]
|
|
462
483
|
Local contrail longwave radiative forcing (positive), [:math:`W m^{-2}`]
|
|
463
484
|
|
|
464
485
|
Raises
|
|
@@ -472,25 +493,25 @@ def longwave_radiative_forcing(
|
|
|
472
493
|
"""
|
|
473
494
|
# get list of habit weight indexs where the weights > 0
|
|
474
495
|
# this is a tuple of (np.array[waypoint index], np.array[habit type index])
|
|
475
|
-
habit_weight_mask = habit_weights_ > 0
|
|
476
|
-
|
|
496
|
+
habit_weight_mask = habit_weights_ > 0.0
|
|
497
|
+
idx0, idx1 = np.nonzero(habit_weight_mask)
|
|
477
498
|
|
|
478
499
|
# Convert parametric coefficients for vectorized operations
|
|
479
|
-
delta_t = rf_const.delta_t[
|
|
480
|
-
delta_lc = rf_const.delta_lc[
|
|
481
|
-
delta_lr = rf_const.delta_lr[
|
|
482
|
-
k_t = rf_const.k_t[
|
|
483
|
-
T_0 = rf_const.T_0[
|
|
500
|
+
delta_t = rf_const.delta_t[idx1]
|
|
501
|
+
delta_lc = rf_const.delta_lc[idx1]
|
|
502
|
+
delta_lr = rf_const.delta_lr[idx1]
|
|
503
|
+
k_t = rf_const.k_t[idx1]
|
|
504
|
+
T_0 = rf_const.T_0[idx1]
|
|
484
505
|
|
|
485
|
-
olr_h = olr[
|
|
486
|
-
tau_cirrus_h = tau_cirrus[
|
|
487
|
-
tau_contrail_h = tau_contrail[
|
|
488
|
-
air_temperature_h = air_temperature[
|
|
506
|
+
olr_h = olr[idx0]
|
|
507
|
+
tau_cirrus_h = tau_cirrus[idx0]
|
|
508
|
+
tau_contrail_h = tau_contrail[idx0]
|
|
509
|
+
air_temperature_h = air_temperature[idx0]
|
|
489
510
|
|
|
490
511
|
# effective radius
|
|
491
512
|
if r_eff_um is None:
|
|
492
|
-
r_vol_um_h = r_vol_um[
|
|
493
|
-
r_eff_um_h = effective_radius_by_habit(r_vol_um_h,
|
|
513
|
+
r_vol_um_h = r_vol_um[idx0]
|
|
514
|
+
r_eff_um_h = effective_radius_by_habit(r_vol_um_h, idx1)
|
|
494
515
|
else:
|
|
495
516
|
if not isinstance(r_eff_um, np.ndarray) or r_eff_um.shape != olr.shape:
|
|
496
517
|
raise ValueError(
|
|
@@ -498,7 +519,7 @@ def longwave_radiative_forcing(
|
|
|
498
519
|
f" {olr.shape}"
|
|
499
520
|
)
|
|
500
521
|
|
|
501
|
-
r_eff_um_h = r_eff_um[
|
|
522
|
+
r_eff_um_h = r_eff_um[idx0]
|
|
502
523
|
|
|
503
524
|
# Longwave radiation calculations
|
|
504
525
|
e_lw = olr_reduction_natural_cirrus(tau_cirrus_h, delta_lc)
|
|
@@ -509,29 +530,29 @@ def longwave_radiative_forcing(
|
|
|
509
530
|
rf_lw_per_habit = (
|
|
510
531
|
(olr_h - k_t * (air_temperature_h - T_0))
|
|
511
532
|
* e_lw
|
|
512
|
-
* (1 - np.exp(-delta_t * f_lw * tau_contrail_h))
|
|
533
|
+
* (1.0 - np.exp(-delta_t * f_lw * tau_contrail_h))
|
|
513
534
|
)
|
|
514
|
-
rf_lw_per_habit = np.maximum(rf_lw_per_habit, 0)
|
|
535
|
+
rf_lw_per_habit = np.maximum(rf_lw_per_habit, 0.0)
|
|
515
536
|
|
|
516
537
|
# Weight and sum the RF contributions of each habit type according the habit weight
|
|
517
538
|
# regime at the waypoint
|
|
518
539
|
# see eqn (12) in :cite:`schumannParametricRadiativeForcing2012`
|
|
519
540
|
# use fancy indexing to re-assign values to 2d array of waypoint x habit type
|
|
520
541
|
rf_lw_weighted = np.zeros_like(habit_weights_)
|
|
521
|
-
rf_lw_weighted[
|
|
542
|
+
rf_lw_weighted[idx0, idx1] = rf_lw_per_habit * habit_weights_[habit_weight_mask]
|
|
522
543
|
return np.sum(rf_lw_weighted, axis=1)
|
|
523
544
|
|
|
524
545
|
|
|
525
546
|
def shortwave_radiative_forcing(
|
|
526
|
-
r_vol_um: np.
|
|
527
|
-
sdr: np.
|
|
528
|
-
rsr: np.
|
|
529
|
-
sd0: np.
|
|
530
|
-
tau_contrail: np.
|
|
531
|
-
tau_cirrus: np.
|
|
532
|
-
habit_weights_: np.
|
|
533
|
-
r_eff_um: np.
|
|
534
|
-
) -> np.
|
|
547
|
+
r_vol_um: npt.NDArray[np.float_],
|
|
548
|
+
sdr: npt.NDArray[np.float_],
|
|
549
|
+
rsr: npt.NDArray[np.float_],
|
|
550
|
+
sd0: npt.NDArray[np.float_],
|
|
551
|
+
tau_contrail: npt.NDArray[np.float_],
|
|
552
|
+
tau_cirrus: npt.NDArray[np.float_],
|
|
553
|
+
habit_weights_: npt.NDArray[np.float_],
|
|
554
|
+
r_eff_um: npt.NDArray[np.float_] | None = None,
|
|
555
|
+
) -> npt.NDArray[np.float_]:
|
|
535
556
|
r"""
|
|
536
557
|
Calculate the local contrail shortwave radiative forcing (:math:`RF_{SW}`).
|
|
537
558
|
|
|
@@ -539,30 +560,30 @@ def shortwave_radiative_forcing(
|
|
|
539
560
|
|
|
540
561
|
Parameters
|
|
541
562
|
----------
|
|
542
|
-
r_vol_um : np.
|
|
563
|
+
r_vol_um : npt.NDArray[np.float_]
|
|
543
564
|
Contrail ice particle volume mean radius, [:math:`\mu m`]
|
|
544
|
-
sdr : np.
|
|
565
|
+
sdr : npt.NDArray[np.float_]
|
|
545
566
|
Solar direct radiation, [:math:`W m^{-2}`]
|
|
546
|
-
rsr : np.
|
|
567
|
+
rsr : npt.NDArray[np.float_]
|
|
547
568
|
Reflected solar radiation, [:math:`W m^{-2}`]
|
|
548
|
-
sd0 : np.
|
|
569
|
+
sd0 : npt.NDArray[np.float_]
|
|
549
570
|
Solar constant, [:math:`W m^{-2}`]
|
|
550
|
-
tau_contrail : np.
|
|
571
|
+
tau_contrail : npt.NDArray[np.float_]
|
|
551
572
|
Contrail optical depth for each waypoint
|
|
552
|
-
tau_cirrus : np.
|
|
573
|
+
tau_cirrus : npt.NDArray[np.float_]
|
|
553
574
|
Optical depth of numerical weather prediction (NWP) cirrus above the
|
|
554
575
|
contrail for each waypoint.
|
|
555
|
-
habit_weights_ : np.
|
|
576
|
+
habit_weights_ : npt.NDArray[np.float_]
|
|
556
577
|
Weights to different ice particle habits for each waypoint,
|
|
557
578
|
``n_waypoints x 8`` (habit) columns, [:math:`[0 - 1]`]
|
|
558
|
-
r_eff_um : np.
|
|
579
|
+
r_eff_um : npt.NDArray[np.float_], optional
|
|
559
580
|
Provide effective radius corresponding to elements in ``r_vol_um``, [:math:`\mu m`].
|
|
560
581
|
Defaults to None, which means the effective radius will be calculated using ``r_vol_um``
|
|
561
582
|
and habit types in :func:`effective_radius_by_habit`.
|
|
562
583
|
|
|
563
584
|
Returns
|
|
564
585
|
-------
|
|
565
|
-
np.
|
|
586
|
+
npt.NDArray[np.float_]
|
|
566
587
|
Local contrail shortwave radiative forcing (negative), [:math:`W m^{-2}`]
|
|
567
588
|
|
|
568
589
|
Raises
|
|
@@ -575,7 +596,7 @@ def shortwave_radiative_forcing(
|
|
|
575
596
|
- :cite:`schumannParametricRadiativeForcing2012`
|
|
576
597
|
"""
|
|
577
598
|
# create mask for daytime (sdr > 0)
|
|
578
|
-
day = sdr > 0
|
|
599
|
+
day = sdr > 0.0
|
|
579
600
|
|
|
580
601
|
# short circuit if no waypoints occur during the day
|
|
581
602
|
if not day.any():
|
|
@@ -583,34 +604,34 @@ def shortwave_radiative_forcing(
|
|
|
583
604
|
|
|
584
605
|
# get list of habit weight indexs where the weights > 0
|
|
585
606
|
# this is a tuple of (np.array[waypoint index], np.array[habit type index])
|
|
586
|
-
habit_weight_mask = day.reshape(day.size, 1) & (habit_weights_ > 0)
|
|
587
|
-
|
|
607
|
+
habit_weight_mask = day.reshape(day.size, 1) & (habit_weights_ > 0.0)
|
|
608
|
+
idx0, idx1 = np.nonzero(habit_weight_mask)
|
|
588
609
|
|
|
589
610
|
# Convert parametric coefficients for vectorized operations
|
|
590
|
-
t_a = rf_const.t_a[
|
|
591
|
-
A_mu = rf_const.A_mu[
|
|
592
|
-
B_mu = rf_const.B_mu[
|
|
593
|
-
C_mu = rf_const.C_mu[
|
|
594
|
-
delta_sr = rf_const.delta_sr[
|
|
595
|
-
F_r = rf_const.F_r[
|
|
596
|
-
gamma_lower = rf_const.gamma_lower[
|
|
597
|
-
gamma_upper = rf_const.gamma_upper[
|
|
598
|
-
delta_sc = rf_const.delta_sc[
|
|
599
|
-
delta_sc_aps = rf_const.delta_sc_aps[
|
|
600
|
-
|
|
601
|
-
sdr_h = sdr[
|
|
602
|
-
rsr_h = rsr[
|
|
603
|
-
sd0_h = sd0[
|
|
604
|
-
tau_contrail_h = tau_contrail[
|
|
605
|
-
tau_cirrus_h = tau_cirrus[
|
|
611
|
+
t_a = rf_const.t_a[idx1]
|
|
612
|
+
A_mu = rf_const.A_mu[idx1]
|
|
613
|
+
B_mu = rf_const.B_mu[idx1]
|
|
614
|
+
C_mu = rf_const.C_mu[idx1]
|
|
615
|
+
delta_sr = rf_const.delta_sr[idx1]
|
|
616
|
+
F_r = rf_const.F_r[idx1]
|
|
617
|
+
gamma_lower = rf_const.gamma_lower[idx1]
|
|
618
|
+
gamma_upper = rf_const.gamma_upper[idx1]
|
|
619
|
+
delta_sc = rf_const.delta_sc[idx1]
|
|
620
|
+
delta_sc_aps = rf_const.delta_sc_aps[idx1]
|
|
621
|
+
|
|
622
|
+
sdr_h = sdr[idx0]
|
|
623
|
+
rsr_h = rsr[idx0]
|
|
624
|
+
sd0_h = sd0[idx0]
|
|
625
|
+
tau_contrail_h = tau_contrail[idx0]
|
|
626
|
+
tau_cirrus_h = tau_cirrus[idx0]
|
|
606
627
|
|
|
607
628
|
albedo_ = albedo(sdr_h, rsr_h)
|
|
608
|
-
mue = np.minimum(
|
|
629
|
+
mue = np.minimum(sdr_h / sd0_h, 1.0)
|
|
609
630
|
|
|
610
631
|
# effective radius
|
|
611
632
|
if r_eff_um is None:
|
|
612
|
-
r_vol_um_h = r_vol_um[
|
|
613
|
-
r_eff_um_h = effective_radius_by_habit(r_vol_um_h,
|
|
633
|
+
r_vol_um_h = r_vol_um[idx0]
|
|
634
|
+
r_eff_um_h = effective_radius_by_habit(r_vol_um_h, idx1)
|
|
614
635
|
else:
|
|
615
636
|
if not isinstance(r_eff_um, np.ndarray) or r_eff_um.shape != sdr.shape:
|
|
616
637
|
raise ValueError(
|
|
@@ -618,7 +639,7 @@ def shortwave_radiative_forcing(
|
|
|
618
639
|
f" {sdr.shape}"
|
|
619
640
|
)
|
|
620
641
|
|
|
621
|
-
r_eff_um_h = r_eff_um[
|
|
642
|
+
r_eff_um_h = r_eff_um[idx0]
|
|
622
643
|
|
|
623
644
|
# Local contrail shortwave radiative forcing calculations
|
|
624
645
|
alpha_c = contrail_albedo(
|
|
@@ -638,19 +659,21 @@ def shortwave_radiative_forcing(
|
|
|
638
659
|
|
|
639
660
|
# calculate the RF SW per habit type
|
|
640
661
|
# see eqn (5) in :cite:`schumannParametricRadiativeForcing2012`
|
|
641
|
-
rf_sw_per_habit = np.minimum(-sdr_h * ((t_a - albedo_) ** 2) * alpha_c * e_sw, 0)
|
|
662
|
+
rf_sw_per_habit = np.minimum(-sdr_h * ((t_a - albedo_) ** 2) * alpha_c * e_sw, 0.0)
|
|
642
663
|
|
|
643
664
|
# Weight and sum the RF contributions of each habit type according the
|
|
644
665
|
# habit weight regime at the waypoint
|
|
645
666
|
# see eqn (12) in :cite:`schumannParametricRadiativeForcing2012`
|
|
646
667
|
# use fancy indexing to re-assign values to 2d array of waypoint x habit type
|
|
647
668
|
rf_sw_weighted = np.zeros_like(habit_weights_)
|
|
648
|
-
rf_sw_weighted[
|
|
669
|
+
rf_sw_weighted[idx0, idx1] = rf_sw_per_habit * habit_weights_[habit_weight_mask]
|
|
649
670
|
|
|
650
671
|
return np.sum(rf_sw_weighted, axis=1)
|
|
651
672
|
|
|
652
673
|
|
|
653
|
-
def net_radiative_forcing(
|
|
674
|
+
def net_radiative_forcing(
|
|
675
|
+
rf_lw: npt.NDArray[np.float_], rf_sw: npt.NDArray[np.float_]
|
|
676
|
+
) -> npt.NDArray[np.float_]:
|
|
654
677
|
"""
|
|
655
678
|
Calculate the local contrail net radiative forcing (rf_net).
|
|
656
679
|
|
|
@@ -658,20 +681,22 @@ def net_radiative_forcing(rf_lw: np.ndarray, rf_sw: np.ndarray) -> np.ndarray:
|
|
|
658
681
|
|
|
659
682
|
Parameters
|
|
660
683
|
----------
|
|
661
|
-
rf_lw : np.
|
|
684
|
+
rf_lw : npt.NDArray[np.float_]
|
|
662
685
|
local contrail longwave radiative forcing, [:math:`W m^{-2}`]
|
|
663
|
-
rf_sw : np.
|
|
686
|
+
rf_sw : npt.NDArray[np.float_]
|
|
664
687
|
local contrail shortwave radiative forcing, [:math:`W m^{-2}`]
|
|
665
688
|
|
|
666
689
|
Returns
|
|
667
690
|
-------
|
|
668
|
-
np.
|
|
691
|
+
npt.NDArray[np.float_]
|
|
669
692
|
local contrail net radiative forcing, [:math:`W m^{-2}`]
|
|
670
693
|
"""
|
|
671
694
|
return rf_lw + rf_sw
|
|
672
695
|
|
|
673
696
|
|
|
674
|
-
def olr_reduction_natural_cirrus(
|
|
697
|
+
def olr_reduction_natural_cirrus(
|
|
698
|
+
tau_cirrus: npt.NDArray[np.float_], delta_lc: npt.NDArray[np.float_]
|
|
699
|
+
) -> npt.NDArray[np.float_]:
|
|
675
700
|
"""
|
|
676
701
|
Calculate reduction in outgoing longwave radiation (OLR) due to the presence of natural cirrus.
|
|
677
702
|
|
|
@@ -680,45 +705,47 @@ def olr_reduction_natural_cirrus(tau_cirrus: np.ndarray, delta_lc: np.ndarray) -
|
|
|
680
705
|
|
|
681
706
|
Parameters
|
|
682
707
|
----------
|
|
683
|
-
tau_cirrus : np.
|
|
708
|
+
tau_cirrus : npt.NDArray[np.float_]
|
|
684
709
|
Optical depth of numerical weather prediction (NWP) cirrus above the
|
|
685
710
|
contrail for each waypoint.
|
|
686
|
-
delta_lc : np.
|
|
711
|
+
delta_lc : npt.NDArray[np.float_]
|
|
687
712
|
Habit specific parameter to approximate the reduction of the outgoing
|
|
688
713
|
longwave radiation at the contrail level due to natural cirrus above the contrail.
|
|
689
714
|
|
|
690
715
|
Returns
|
|
691
716
|
-------
|
|
692
|
-
np.
|
|
717
|
+
npt.NDArray[np.float_]
|
|
693
718
|
Reduction of outgoing longwave radiation
|
|
694
719
|
"""
|
|
695
720
|
# e_lw calculations
|
|
696
721
|
return np.exp(-delta_lc * tau_cirrus)
|
|
697
722
|
|
|
698
723
|
|
|
699
|
-
def contrail_effective_emissivity(
|
|
724
|
+
def contrail_effective_emissivity(
|
|
725
|
+
r_eff_um: npt.NDArray[np.float_], delta_lr: npt.NDArray[np.float_]
|
|
726
|
+
) -> npt.NDArray[np.float_]:
|
|
700
727
|
r"""Calculate the effective emissivity of the contrail, ``f_lw``.
|
|
701
728
|
|
|
702
729
|
Refer to Eq. (3) of Schumann et al. (2012).
|
|
703
730
|
|
|
704
731
|
Parameters
|
|
705
732
|
----------
|
|
706
|
-
r_eff_um : np.
|
|
733
|
+
r_eff_um : npt.NDArray[np.float_]
|
|
707
734
|
Effective radius for each waypoint, n_waypoints x 8 (habit) columns, [:math:`\mu m`]
|
|
708
735
|
See :func:`effective_radius_habit`.
|
|
709
|
-
delta_lr : np.
|
|
736
|
+
delta_lr : npt.NDArray[np.float_]
|
|
710
737
|
Habit specific parameter to approximate the effective emissivity of the contrail.
|
|
711
738
|
|
|
712
739
|
Returns
|
|
713
740
|
-------
|
|
714
|
-
np.
|
|
741
|
+
npt.NDArray[np.float_]
|
|
715
742
|
Effective emissivity of the contrail
|
|
716
743
|
"""
|
|
717
744
|
# f_lw calculations
|
|
718
|
-
return 1 - np.exp(-delta_lr * r_eff_um)
|
|
745
|
+
return 1.0 - np.exp(-delta_lr * r_eff_um)
|
|
719
746
|
|
|
720
747
|
|
|
721
|
-
def albedo(sdr: np.
|
|
748
|
+
def albedo(sdr: npt.NDArray[np.float_], rsr: npt.NDArray[np.float_]) -> npt.NDArray[np.float_]:
|
|
722
749
|
"""
|
|
723
750
|
Calculate albedo along contrail waypoint.
|
|
724
751
|
|
|
@@ -730,35 +757,35 @@ def albedo(sdr: np.ndarray, rsr: np.ndarray) -> np.ndarray:
|
|
|
730
757
|
|
|
731
758
|
Parameters
|
|
732
759
|
----------
|
|
733
|
-
sdr : np.
|
|
760
|
+
sdr : npt.NDArray[np.float_]
|
|
734
761
|
Solar direct radiation, [:math:`W m^{-2}`]
|
|
735
|
-
rsr : np.
|
|
762
|
+
rsr : npt.NDArray[np.float_]
|
|
736
763
|
Reflected solar radiation, [:math:`W m^{-2}`]
|
|
737
764
|
|
|
738
765
|
Returns
|
|
739
766
|
-------
|
|
740
|
-
np.
|
|
767
|
+
npt.NDArray[np.float_]
|
|
741
768
|
Albedo value, [:math:`[0 - 1]`]
|
|
742
769
|
"""
|
|
743
|
-
day = sdr > 0
|
|
770
|
+
day = sdr > 0.0
|
|
744
771
|
albedo_ = np.zeros(sdr.shape)
|
|
745
772
|
albedo_[day] = rsr[day] / sdr[day]
|
|
746
|
-
albedo_.clip(0, 1, out=albedo_)
|
|
773
|
+
albedo_.clip(0.0, 1.0, out=albedo_)
|
|
747
774
|
return albedo_
|
|
748
775
|
|
|
749
776
|
|
|
750
777
|
def contrail_albedo(
|
|
751
|
-
tau_contrail: np.
|
|
752
|
-
mue: np.
|
|
753
|
-
r_eff_um: np.
|
|
754
|
-
A_mu: np.
|
|
755
|
-
B_mu: np.
|
|
756
|
-
C_mu: np.
|
|
757
|
-
delta_sr: np.
|
|
758
|
-
F_r: np.
|
|
759
|
-
gamma_lower: np.
|
|
760
|
-
gamma_upper: np.
|
|
761
|
-
) -> np.
|
|
778
|
+
tau_contrail: npt.NDArray[np.float_],
|
|
779
|
+
mue: npt.NDArray[np.float_],
|
|
780
|
+
r_eff_um: npt.NDArray[np.float_],
|
|
781
|
+
A_mu: npt.NDArray[np.float_],
|
|
782
|
+
B_mu: npt.NDArray[np.float_],
|
|
783
|
+
C_mu: npt.NDArray[np.float_],
|
|
784
|
+
delta_sr: npt.NDArray[np.float_],
|
|
785
|
+
F_r: npt.NDArray[np.float_],
|
|
786
|
+
gamma_lower: npt.NDArray[np.float_],
|
|
787
|
+
gamma_upper: npt.NDArray[np.float_],
|
|
788
|
+
) -> npt.NDArray[np.float_]:
|
|
762
789
|
r"""
|
|
763
790
|
Calculate the contrail albedo, ``alpha_c``.
|
|
764
791
|
|
|
@@ -766,48 +793,48 @@ def contrail_albedo(
|
|
|
766
793
|
|
|
767
794
|
Parameters
|
|
768
795
|
----------
|
|
769
|
-
tau_contrail : np.
|
|
796
|
+
tau_contrail : npt.NDArray[np.float_]
|
|
770
797
|
Contrail optical depth for each waypoint
|
|
771
|
-
mue : np.
|
|
798
|
+
mue : npt.NDArray[np.float_]
|
|
772
799
|
Cosine of the solar zenith angle (theta), mue = cos(theta) = sdr/sd0
|
|
773
|
-
r_eff_um : np.
|
|
800
|
+
r_eff_um : npt.NDArray[np.float_]
|
|
774
801
|
Effective radius for each waypoint, n_waypoints x 8 (habit) columns, [:math:`\mu m`]
|
|
775
802
|
See :func:`effective_radius_habit`.
|
|
776
|
-
A_mu : np.
|
|
803
|
+
A_mu : npt.NDArray[np.float_]
|
|
777
804
|
Habit-specific parameter to approximate the albedo of the contrail
|
|
778
|
-
B_mu : np.
|
|
805
|
+
B_mu : npt.NDArray[np.float_]
|
|
779
806
|
Habit-specific parameter to approximate the SZA-dependent contrail sideward scattering
|
|
780
|
-
C_mu : np.
|
|
807
|
+
C_mu : npt.NDArray[np.float_]
|
|
781
808
|
Habit-specific parameter to approximate the albedo of the contrail
|
|
782
|
-
delta_sr : np.
|
|
809
|
+
delta_sr : npt.NDArray[np.float_]
|
|
783
810
|
Habit-specific parameter to approximate the effective contrail optical depth
|
|
784
|
-
F_r : np.
|
|
811
|
+
F_r : npt.NDArray[np.float_]
|
|
785
812
|
Habit-specific parameter to approximate the effective contrail optical depth
|
|
786
|
-
gamma_lower : np.
|
|
813
|
+
gamma_lower : npt.NDArray[np.float_]
|
|
787
814
|
Habit-specific parameter to approximate the contrail reflectances
|
|
788
|
-
gamma_upper : np.
|
|
815
|
+
gamma_upper : npt.NDArray[np.float_]
|
|
789
816
|
Habit-specific parameter to approximate the contrail reflectances
|
|
790
817
|
|
|
791
818
|
Returns
|
|
792
819
|
-------
|
|
793
|
-
np.
|
|
820
|
+
npt.NDArray[np.float_]
|
|
794
821
|
Contrail albedo for each waypoint and ice particle habit
|
|
795
822
|
"""
|
|
796
|
-
tau_aps = tau_contrail * (1 - F_r * (1 - np.exp(-delta_sr * r_eff_um)))
|
|
823
|
+
tau_aps = tau_contrail * (1.0 - F_r * (1 - np.exp(-delta_sr * r_eff_um)))
|
|
797
824
|
tau_eff = tau_aps / (mue + 1e-6)
|
|
798
|
-
r_c = 1 - np.exp(-gamma_upper * tau_eff)
|
|
825
|
+
r_c = 1.0 - np.exp(-gamma_upper * tau_eff)
|
|
799
826
|
r_c_aps = np.exp(-gamma_lower * tau_eff)
|
|
800
827
|
|
|
801
|
-
f_mu = (2 * (1 - mue)) ** B_mu - 1
|
|
828
|
+
f_mu = (2.0 * (1.0 - mue)) ** B_mu - 1.0
|
|
802
829
|
return r_c * (C_mu + (A_mu * r_c_aps * f_mu))
|
|
803
830
|
|
|
804
831
|
|
|
805
832
|
def effective_tau_cirrus(
|
|
806
|
-
tau_cirrus: np.
|
|
807
|
-
mue: np.
|
|
808
|
-
delta_sc: np.
|
|
809
|
-
delta_sc_aps: np.
|
|
810
|
-
) -> np.
|
|
833
|
+
tau_cirrus: npt.NDArray[np.float_],
|
|
834
|
+
mue: npt.NDArray[np.float_],
|
|
835
|
+
delta_sc: npt.NDArray[np.float_],
|
|
836
|
+
delta_sc_aps: npt.NDArray[np.float_],
|
|
837
|
+
) -> npt.NDArray[np.float_]:
|
|
811
838
|
r"""
|
|
812
839
|
Calculate the effective optical depth of natural cirrus above the contrail, ``e_sw``.
|
|
813
840
|
|
|
@@ -815,21 +842,21 @@ def effective_tau_cirrus(
|
|
|
815
842
|
|
|
816
843
|
Parameters
|
|
817
844
|
----------
|
|
818
|
-
tau_cirrus : np.
|
|
845
|
+
tau_cirrus : npt.NDArray[np.float_]
|
|
819
846
|
Optical depth of numerical weather prediction (NWP) cirrus above the
|
|
820
847
|
contrail for each waypoint.
|
|
821
|
-
mue : np.
|
|
848
|
+
mue : npt.NDArray[np.float_]
|
|
822
849
|
Cosine of the solar zenith angle (theta), mue = cos(theta) = sdr/sd0
|
|
823
|
-
delta_sc : np.
|
|
850
|
+
delta_sc : npt.NDArray[np.float_]
|
|
824
851
|
Habit-specific parameter to account for the optical depth of natural
|
|
825
852
|
cirrus above the contrail
|
|
826
|
-
delta_sc_aps : np.
|
|
853
|
+
delta_sc_aps : npt.NDArray[np.float_]
|
|
827
854
|
Habit-specific parameter to account for the optical depth of natural
|
|
828
855
|
cirrus above the contrail
|
|
829
856
|
|
|
830
857
|
Returns
|
|
831
858
|
-------
|
|
832
|
-
np.
|
|
859
|
+
npt.NDArray[np.float_]
|
|
833
860
|
Effective optical depth of natural cirrus above the contrail,
|
|
834
861
|
``n_waypoints x 8`` (habit) columns.
|
|
835
862
|
"""
|