disdrodb 0.1.2__py3-none-any.whl → 0.1.4__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.
Files changed (142) hide show
  1. disdrodb/__init__.py +68 -34
  2. disdrodb/_config.py +5 -4
  3. disdrodb/_version.py +16 -3
  4. disdrodb/accessor/__init__.py +20 -0
  5. disdrodb/accessor/methods.py +125 -0
  6. disdrodb/api/checks.py +177 -24
  7. disdrodb/api/configs.py +3 -3
  8. disdrodb/api/info.py +13 -13
  9. disdrodb/api/io.py +281 -22
  10. disdrodb/api/path.py +184 -195
  11. disdrodb/api/search.py +18 -9
  12. disdrodb/cli/disdrodb_create_summary.py +103 -0
  13. disdrodb/cli/disdrodb_create_summary_station.py +91 -0
  14. disdrodb/cli/disdrodb_run_l0.py +1 -1
  15. disdrodb/cli/disdrodb_run_l0_station.py +1 -1
  16. disdrodb/cli/disdrodb_run_l0a_station.py +1 -1
  17. disdrodb/cli/disdrodb_run_l0b.py +1 -1
  18. disdrodb/cli/disdrodb_run_l0b_station.py +3 -3
  19. disdrodb/cli/disdrodb_run_l0c.py +1 -1
  20. disdrodb/cli/disdrodb_run_l0c_station.py +3 -3
  21. disdrodb/cli/disdrodb_run_l1_station.py +2 -2
  22. disdrodb/cli/disdrodb_run_l2e_station.py +2 -2
  23. disdrodb/cli/disdrodb_run_l2m_station.py +2 -2
  24. disdrodb/configs.py +149 -4
  25. disdrodb/constants.py +61 -0
  26. disdrodb/data_transfer/download_data.py +127 -11
  27. disdrodb/etc/configs/attributes.yaml +339 -0
  28. disdrodb/etc/configs/encodings.yaml +473 -0
  29. disdrodb/etc/products/L1/global.yaml +13 -0
  30. disdrodb/etc/products/L2E/10MIN.yaml +12 -0
  31. disdrodb/etc/products/L2E/1MIN.yaml +1 -0
  32. disdrodb/etc/products/L2E/global.yaml +22 -0
  33. disdrodb/etc/products/L2M/10MIN.yaml +12 -0
  34. disdrodb/etc/products/L2M/GAMMA_ML.yaml +8 -0
  35. disdrodb/etc/products/L2M/NGAMMA_GS_LOG_ND_MAE.yaml +6 -0
  36. disdrodb/etc/products/L2M/NGAMMA_GS_ND_MAE.yaml +6 -0
  37. disdrodb/etc/products/L2M/NGAMMA_GS_Z_MAE.yaml +6 -0
  38. disdrodb/etc/products/L2M/global.yaml +26 -0
  39. disdrodb/issue/writer.py +2 -0
  40. disdrodb/l0/__init__.py +13 -0
  41. disdrodb/l0/configs/LPM/l0b_cf_attrs.yml +4 -4
  42. disdrodb/l0/configs/PARSIVEL/l0b_cf_attrs.yml +1 -1
  43. disdrodb/l0/configs/PARSIVEL/l0b_encodings.yml +3 -3
  44. disdrodb/l0/configs/PARSIVEL/raw_data_format.yml +1 -1
  45. disdrodb/l0/configs/PARSIVEL2/l0b_cf_attrs.yml +5 -5
  46. disdrodb/l0/configs/PARSIVEL2/l0b_encodings.yml +3 -3
  47. disdrodb/l0/configs/PARSIVEL2/raw_data_format.yml +1 -1
  48. disdrodb/l0/configs/PWS100/l0b_cf_attrs.yml +4 -4
  49. disdrodb/l0/configs/PWS100/raw_data_format.yml +1 -1
  50. disdrodb/l0/l0a_processing.py +37 -32
  51. disdrodb/l0/l0b_nc_processing.py +118 -8
  52. disdrodb/l0/l0b_processing.py +30 -65
  53. disdrodb/l0/l0c_processing.py +369 -259
  54. disdrodb/l0/readers/LPM/ARM/ARM_LPM.py +7 -0
  55. disdrodb/l0/readers/LPM/NETHERLANDS/DELFT_LPM_NC.py +66 -0
  56. disdrodb/l0/readers/LPM/SLOVENIA/{CRNI_VRH.py → UL.py} +3 -0
  57. disdrodb/l0/readers/LPM/SWITZERLAND/INNERERIZ_LPM.py +195 -0
  58. disdrodb/l0/readers/PARSIVEL/GPM/PIERS.py +0 -2
  59. disdrodb/l0/readers/PARSIVEL/JAPAN/JMA.py +4 -1
  60. disdrodb/l0/readers/PARSIVEL/NCAR/PECAN_MOBILE.py +1 -1
  61. disdrodb/l0/readers/PARSIVEL/NCAR/VORTEX2_2009.py +1 -1
  62. disdrodb/l0/readers/PARSIVEL2/ARM/ARM_PARSIVEL2.py +4 -0
  63. disdrodb/l0/readers/PARSIVEL2/BELGIUM/ILVO.py +168 -0
  64. disdrodb/l0/readers/PARSIVEL2/CANADA/UQAM_NC.py +69 -0
  65. disdrodb/l0/readers/PARSIVEL2/DENMARK/DTU.py +165 -0
  66. disdrodb/l0/readers/PARSIVEL2/FINLAND/FMI_PARSIVEL2.py +69 -0
  67. disdrodb/l0/readers/PARSIVEL2/FRANCE/ENPC_PARSIVEL2.py +255 -134
  68. disdrodb/l0/readers/PARSIVEL2/FRANCE/OSUG.py +525 -0
  69. disdrodb/l0/readers/PARSIVEL2/FRANCE/SIRTA_PARSIVEL2.py +1 -1
  70. disdrodb/l0/readers/PARSIVEL2/GPM/GCPEX.py +9 -7
  71. disdrodb/l0/readers/PARSIVEL2/KIT/BURKINA_FASO.py +1 -1
  72. disdrodb/l0/readers/PARSIVEL2/KIT/TEAMX.py +123 -0
  73. disdrodb/l0/readers/PARSIVEL2/{NETHERLANDS/DELFT.py → MPI/BCO_PARSIVEL2.py} +41 -71
  74. disdrodb/l0/readers/PARSIVEL2/MPI/BOWTIE.py +220 -0
  75. disdrodb/l0/readers/PARSIVEL2/NASA/APU.py +120 -0
  76. disdrodb/l0/readers/PARSIVEL2/NASA/LPVEX.py +109 -0
  77. disdrodb/l0/readers/PARSIVEL2/NCAR/FARM_PARSIVEL2.py +1 -0
  78. disdrodb/l0/readers/PARSIVEL2/NCAR/PECAN_FP3.py +1 -1
  79. disdrodb/l0/readers/PARSIVEL2/NCAR/PERILS_MIPS.py +126 -0
  80. disdrodb/l0/readers/PARSIVEL2/NCAR/PERILS_PIPS.py +165 -0
  81. disdrodb/l0/readers/PARSIVEL2/NCAR/VORTEX_SE_2016_P2.py +1 -1
  82. disdrodb/l0/readers/PARSIVEL2/NCAR/VORTEX_SE_2016_PIPS.py +20 -12
  83. disdrodb/l0/readers/PARSIVEL2/NETHERLANDS/DELFT_NC.py +5 -0
  84. disdrodb/l0/readers/PARSIVEL2/SPAIN/CENER.py +144 -0
  85. disdrodb/l0/readers/PARSIVEL2/SPAIN/CR1000DL.py +201 -0
  86. disdrodb/l0/readers/PARSIVEL2/SPAIN/LIAISE.py +137 -0
  87. disdrodb/l0/readers/PARSIVEL2/USA/C3WE.py +146 -0
  88. disdrodb/l0/readers/PWS100/FRANCE/ENPC_PWS100.py +105 -99
  89. disdrodb/l0/readers/PWS100/FRANCE/ENPC_PWS100_SIRTA.py +151 -0
  90. disdrodb/l1/__init__.py +5 -0
  91. disdrodb/l1/fall_velocity.py +46 -0
  92. disdrodb/l1/filters.py +34 -20
  93. disdrodb/l1/processing.py +46 -45
  94. disdrodb/l1/resampling.py +77 -66
  95. disdrodb/l1_env/routines.py +18 -3
  96. disdrodb/l2/__init__.py +7 -0
  97. disdrodb/l2/empirical_dsd.py +58 -10
  98. disdrodb/l2/processing.py +268 -117
  99. disdrodb/metadata/checks.py +132 -125
  100. disdrodb/metadata/standards.py +3 -1
  101. disdrodb/psd/fitting.py +631 -345
  102. disdrodb/psd/models.py +9 -6
  103. disdrodb/routines/__init__.py +54 -0
  104. disdrodb/{l0/routines.py → routines/l0.py} +316 -355
  105. disdrodb/{l1/routines.py → routines/l1.py} +76 -116
  106. disdrodb/routines/l2.py +1019 -0
  107. disdrodb/{routines.py → routines/wrappers.py} +98 -10
  108. disdrodb/scattering/__init__.py +16 -4
  109. disdrodb/scattering/axis_ratio.py +61 -37
  110. disdrodb/scattering/permittivity.py +504 -0
  111. disdrodb/scattering/routines.py +746 -184
  112. disdrodb/summary/__init__.py +17 -0
  113. disdrodb/summary/routines.py +4196 -0
  114. disdrodb/utils/archiving.py +434 -0
  115. disdrodb/utils/attrs.py +68 -125
  116. disdrodb/utils/cli.py +5 -5
  117. disdrodb/utils/compression.py +30 -1
  118. disdrodb/utils/dask.py +121 -9
  119. disdrodb/utils/dataframe.py +61 -7
  120. disdrodb/utils/decorators.py +31 -0
  121. disdrodb/utils/directories.py +35 -15
  122. disdrodb/utils/encoding.py +37 -19
  123. disdrodb/{l2 → utils}/event.py +15 -173
  124. disdrodb/utils/logger.py +14 -7
  125. disdrodb/utils/manipulations.py +81 -0
  126. disdrodb/utils/routines.py +166 -0
  127. disdrodb/utils/subsetting.py +214 -0
  128. disdrodb/utils/time.py +35 -177
  129. disdrodb/utils/writer.py +20 -7
  130. disdrodb/utils/xarray.py +5 -4
  131. disdrodb/viz/__init__.py +13 -0
  132. disdrodb/viz/plots.py +398 -0
  133. {disdrodb-0.1.2.dist-info → disdrodb-0.1.4.dist-info}/METADATA +4 -3
  134. {disdrodb-0.1.2.dist-info → disdrodb-0.1.4.dist-info}/RECORD +139 -98
  135. {disdrodb-0.1.2.dist-info → disdrodb-0.1.4.dist-info}/entry_points.txt +2 -0
  136. disdrodb/l1/encoding_attrs.py +0 -642
  137. disdrodb/l2/processing_options.py +0 -213
  138. disdrodb/l2/routines.py +0 -868
  139. /disdrodb/l0/readers/PARSIVEL/SLOVENIA/{UL_FGG.py → UL.py} +0 -0
  140. {disdrodb-0.1.2.dist-info → disdrodb-0.1.4.dist-info}/WHEEL +0 -0
  141. {disdrodb-0.1.2.dist-info → disdrodb-0.1.4.dist-info}/licenses/LICENSE +0 -0
  142. {disdrodb-0.1.2.dist-info → disdrodb-0.1.4.dist-info}/top_level.txt +0 -0
@@ -20,7 +20,7 @@ import time
20
20
  from typing import Optional
21
21
 
22
22
  from disdrodb.api.search import available_stations, get_required_product
23
- from disdrodb.utils.cli import _execute_cmd
23
+ from disdrodb.utils.cli import execute_cmd
24
24
 
25
25
  ####--------------------------------------------------------------------------.
26
26
  #### Run DISDRODB Station Processing
@@ -91,7 +91,7 @@ def run_l0_station(
91
91
  debugging_mode : bool
92
92
  If ``True``, it reduces the amount of data to process.
93
93
  For L0A, it processes just the first 3 raw data files for each station.
94
- For L0B, it processes just the first 100 rows of 3 L0A files for each station.
94
+ For L0B, it processes 100 rows sampled from 3 L0A files for each station.
95
95
  The default value is ``False``.
96
96
  data_archive_dir : str (optional)
97
97
  The directory path where the DISDRODB Data Archive is located.
@@ -239,7 +239,7 @@ def run_l0a_station(
239
239
  ],
240
240
  )
241
241
  # Execute command
242
- _execute_cmd(cmd)
242
+ execute_cmd(cmd)
243
243
 
244
244
 
245
245
  def run_l0b_station(
@@ -323,7 +323,7 @@ def run_l0b_station(
323
323
  ],
324
324
  )
325
325
  # Execute command
326
- _execute_cmd(cmd)
326
+ execute_cmd(cmd)
327
327
 
328
328
 
329
329
  def run_l0c_station(
@@ -407,7 +407,7 @@ def run_l0c_station(
407
407
  ],
408
408
  )
409
409
  # Execute command
410
- _execute_cmd(cmd)
410
+ execute_cmd(cmd)
411
411
 
412
412
 
413
413
  def run_l1_station(
@@ -483,7 +483,7 @@ def run_l1_station(
483
483
  ],
484
484
  )
485
485
  # Execute command
486
- _execute_cmd(cmd)
486
+ execute_cmd(cmd)
487
487
 
488
488
 
489
489
  def run_l2e_station(
@@ -559,7 +559,7 @@ def run_l2e_station(
559
559
  ],
560
560
  )
561
561
  # Execute command
562
- _execute_cmd(cmd)
562
+ execute_cmd(cmd)
563
563
 
564
564
 
565
565
  def run_l2m_station(
@@ -635,7 +635,33 @@ def run_l2m_station(
635
635
  ],
636
636
  )
637
637
  # Execute command
638
- _execute_cmd(cmd)
638
+ execute_cmd(cmd)
639
+
640
+
641
+ def create_summary_station(
642
+ data_source,
643
+ campaign_name,
644
+ station_name,
645
+ parallel=False,
646
+ data_archive_dir=None,
647
+ ):
648
+ """Create summary figures and tables for a DISDRODB station."""
649
+ # Define command
650
+ cmd = " ".join(
651
+ [
652
+ "disdrodb_create_summary_station",
653
+ # Station arguments
654
+ data_source,
655
+ campaign_name,
656
+ station_name,
657
+ "--data_archive_dir",
658
+ str(data_archive_dir),
659
+ "--parallel",
660
+ str(parallel),
661
+ ],
662
+ )
663
+ # Execute command
664
+ execute_cmd(cmd)
639
665
 
640
666
 
641
667
  ####--------------------------------------------------------------------------.
@@ -794,7 +820,7 @@ def run_l0b(
794
820
  If ``False``, the files are processed sequentially in a single process.
795
821
  debugging_mode : bool
796
822
  If ``True``, it reduces the amount of data to process.
797
- For L0B, it processes just the first 100 rows of 3 L0A files.
823
+ For L0B, it processes 100 rows sampled from 3 L0A files.
798
824
  The default value is ``False``.
799
825
  data_archive_dir : str (optional)
800
826
  The directory path where the DISDRODB Data Archive is located.
@@ -1033,7 +1059,7 @@ def run_l0(
1033
1059
  debugging_mode : bool
1034
1060
  If ``True``, it reduces the amount of data to process.
1035
1061
  For L0A, it processes just the first 3 raw data files.
1036
- For L0B, it processes just the first 100 rows of 3 L0A files.
1062
+ For L0B, it processes 100 rows sampled from 3 L0A files.
1037
1063
  The default value is ``False``.
1038
1064
  data_archive_dir : str (optional)
1039
1065
  The directory path where the DISDRODB Data Archive is located.
@@ -1409,4 +1435,66 @@ def run_l2m(
1409
1435
  print(f"{product} processing of {data_source} {campaign_name} {station_name} station ended.")
1410
1436
 
1411
1437
 
1438
+ def create_summary(
1439
+ data_sources=None,
1440
+ campaign_names=None,
1441
+ station_names=None,
1442
+ parallel=False,
1443
+ data_archive_dir=None,
1444
+ metadata_archive_dir=None,
1445
+ ):
1446
+ """Create summary figures and tables for a set of DISDRODB station.
1447
+
1448
+ Parameters
1449
+ ----------
1450
+ data_sources : list
1451
+ Name of data source(s) to process.
1452
+ The name(s) must be UPPER CASE.
1453
+ If campaign_names and station are not specified, process all stations.
1454
+ The default value is ``None``.
1455
+ campaign_names : list
1456
+ Name of the campaign(s) to process.
1457
+ The name(s) must be UPPER CASE.
1458
+ The default value is ``None``.
1459
+ station_names : list
1460
+ Station names to process.
1461
+ The default value is ``None``.
1462
+ data_archive_dir : str (optional)
1463
+ The directory path where the DISDRODB Data Archive is located.
1464
+ The directory path must end with ``<...>/DISDRODB``.
1465
+ If ``None``, it uses the ``data_archive_dir`` path specified
1466
+ in the DISDRODB active configuration.
1467
+ """
1468
+ # Get list of available stations
1469
+ list_info = available_stations(
1470
+ # DISDRODB root directories
1471
+ data_archive_dir=data_archive_dir,
1472
+ metadata_archive_dir=metadata_archive_dir,
1473
+ # Stations arguments
1474
+ data_sources=data_sources,
1475
+ campaign_names=campaign_names,
1476
+ station_names=station_names,
1477
+ # Search options
1478
+ product="L2E",
1479
+ product_kwargs={"rolling": False, "sample_interval": 60},
1480
+ raise_error_if_empty=True,
1481
+ )
1482
+
1483
+ # Loop over stations
1484
+ print(f"Creation of summaries for {len(list_info)} stations has started.")
1485
+ for data_source, campaign_name, station_name in list_info:
1486
+ # Run processing
1487
+ create_summary_station(
1488
+ # DISDRODB root directories
1489
+ data_archive_dir=data_archive_dir,
1490
+ # Station arguments
1491
+ data_source=data_source,
1492
+ campaign_name=campaign_name,
1493
+ station_name=station_name,
1494
+ # Processing option
1495
+ parallel=parallel,
1496
+ )
1497
+ print("Creation of station summaries has terminated.")
1498
+
1499
+
1412
1500
  ####--------------------------------------------------------------------------.
@@ -17,12 +17,24 @@
17
17
  """Implement PSD scattering routines."""
18
18
 
19
19
 
20
- from disdrodb.scattering.axis_ratio import available_axis_ratio, get_axis_ratio
21
- from disdrodb.scattering.routines import available_radar_bands, get_radar_parameters
20
+ from disdrodb.scattering.axis_ratio import available_axis_ratio_models, get_axis_ratio_model
21
+ from disdrodb.scattering.permittivity import available_permittivity_models, get_refractive_index
22
+ from disdrodb.scattering.routines import (
23
+ RADAR_OPTIONS,
24
+ RADAR_VARIABLES,
25
+ available_radar_bands,
26
+ get_radar_parameters,
27
+ load_scatterer,
28
+ )
22
29
 
23
30
  __all__ = [
24
- "available_axis_ratio",
31
+ "RADAR_OPTIONS",
32
+ "RADAR_VARIABLES",
33
+ "available_axis_ratio_models",
34
+ "available_permittivity_models",
25
35
  "available_radar_bands",
26
- "get_axis_ratio",
36
+ "get_axis_ratio_model",
27
37
  "get_radar_parameters",
38
+ "get_refractive_index",
39
+ "load_scatterer",
28
40
  ]
@@ -14,70 +14,90 @@
14
14
  # You should have received a copy of the GNU General Public License
15
15
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
16
  # -----------------------------------------------------------------------------.
17
- """Implement drop axis ratio theoretical models."""
17
+ """Implement drop (vertical-to-horizontal) axis ratio theoretical models."""
18
18
 
19
19
  import numpy as np
20
20
  import xarray as xr
21
21
 
22
22
 
23
- def available_axis_ratio():
24
- """Return a list of the available drop axis ratio methods."""
25
- return list(AXIS_RATIO_METHODS)
23
+ def available_axis_ratio_models():
24
+ """Return a list of the available drop axis ratio models."""
25
+ return list(AXIS_RATIO_MODELS)
26
26
 
27
27
 
28
- def get_axis_ratio_method(method):
29
- """Return the specified drop axis ratio method."""
30
- method = check_axis_ratio(method)
31
- return AXIS_RATIO_METHODS[method]
28
+ def get_axis_ratio_model(model):
29
+ """Return the specified drop axis ratio model.
32
30
 
31
+ Parameters
32
+ ----------
33
+ model : str
34
+ The model to use for calculating the axis ratio. Available models are:
35
+ 'Thurai2005', 'Thurai2007', 'Battaglia2010', 'Brandes2002',
36
+ 'Pruppacher1970', 'Beard1987', 'Andsager1999'.
37
+
38
+ Returns
39
+ -------
40
+ callable
41
+ A function which compute the vertical-to-horizontal axis ratio given a
42
+ particle diameter in mm.
33
43
 
34
- def check_axis_ratio(method):
35
- """Check validity of the specified drop axis ratio method."""
36
- available_methods = available_axis_ratio()
37
- if method not in available_methods:
38
- raise ValueError(f"{method} is an invalid axis-ratio method. Valid methods: {available_methods}.")
39
- return method
44
+ Notes
45
+ -----
46
+ This function serves as a wrapper to various axis ratio models for raindrops.
47
+ It returns the appropriate model based on the `model` parameter.
40
48
 
49
+ Please note that the axis ratio function to be provided to pyTmatrix expects to
50
+ return a horizontal-to-vertical axis ratio !
41
51
 
42
- def get_axis_ratio(diameter, method):
43
52
  """
44
- Compute the axis ratio of raindrops using the specified method.
53
+ model = check_axis_ratio_model(model)
54
+ return AXIS_RATIO_MODELS[model]
55
+
56
+
57
+ def check_axis_ratio_model(model):
58
+ """Check validity of the specified drop axis ratio model."""
59
+ available_models = available_axis_ratio_models()
60
+ if model not in available_models:
61
+ raise ValueError(f"{model} is an invalid axis-ratio model. Valid models: {available_models}.")
62
+ return model
63
+
64
+
65
+ def get_axis_ratio(diameter, model):
66
+ """
67
+ Compute the axis ratio of raindrops using the specified model.
45
68
 
46
69
  Parameters
47
70
  ----------
48
71
  diameter : array-like
49
72
  Raindrops diameter in mm.
50
- method : str
51
- The method to use for calculating the axis ratio. Available methods are:
73
+ model : str
74
+ The axis ratio model to use for calculating the axis ratio. Available models are:
52
75
  'Thurai2005', 'Thurai2007', 'Battaglia2010', 'Brandes2002',
53
76
  'Pruppacher1970', 'Beard1987', 'Andsager1999'.
54
77
 
55
78
  Returns
56
79
  -------
57
80
  axis_ratio : array-like
58
- Calculated axis ratios corresponding to the input diameters.
59
-
60
- Raises
61
- ------
62
- ValueError
63
- If the specified method is not one of the available methods.
81
+ The vertical-to-horizontal drop axis ratio corresponding to the input diameters.
82
+ Values of 1 indicate spherical particles, while values <1 indicate oblate particles.
83
+ Values >1 means prolate particles.
64
84
 
65
85
  Notes
66
86
  -----
67
87
  This function serves as a wrapper to various axis ratio models for raindrops.
68
- It selects and applies the appropriate model based on the `method` parameter.
88
+ It selects and applies the appropriate model based on the `model` parameter.
69
89
 
70
90
  Examples
71
91
  --------
72
92
  >>> diameter = np.array([0.5, 1.0, 2.0, 3.0])
73
- >>> axis_ratio = get_axis_ratio(diameter, method="Brandes2002")
93
+ >>> axis_ratio = get_axis_ratio(diameter, model="Brandes2002")
74
94
 
75
95
  """
76
96
  # Retrieve axis ratio function
77
- func = get_axis_ratio_method(method)
97
+ axis_ratio_func = get_axis_ratio_model(model)
78
98
 
79
99
  # Retrieve axis ratio
80
- axis_ratio = func(diameter)
100
+ axis_ratio = axis_ratio_func(diameter)
81
101
 
82
102
  # Clip values between 0 and 1
83
103
  axis_ratio = np.clip(axis_ratio, 0, 1)
@@ -86,7 +106,7 @@ def get_axis_ratio(diameter, method):
86
106
 
87
107
  def get_axis_ratio_andsager_1999(diameter):
88
108
  """
89
- Compute the axis ratio of raindrops using the Andsager et al. (1999) method.
109
+ Compute the axis ratio of raindrops using the Andsager et al. (1999) model.
90
110
 
91
111
  Parameters
92
112
  ----------
@@ -145,7 +165,7 @@ def get_axis_ratio_andsager_1999(diameter):
145
165
 
146
166
  def get_axis_ratio_battaglia_2010(diameter):
147
167
  """
148
- Compute the axis ratio of raindrops using the Battaglia et al. (2010) method.
168
+ Compute the axis ratio of raindrops using the Battaglia et al. (2010) model.
149
169
 
150
170
  Parameters
151
171
  ----------
@@ -185,7 +205,7 @@ def get_axis_ratio_battaglia_2010(diameter):
185
205
 
186
206
  def get_axis_ratio_beard_1987(diameter):
187
207
  """
188
- Compute the axis ratio of raindrops using the Beard and Chuang (1987) method.
208
+ Compute the axis ratio of raindrops using the Beard and Chuang (1987) model.
189
209
 
190
210
  Parameters
191
211
  ----------
@@ -214,7 +234,7 @@ def get_axis_ratio_beard_1987(diameter):
214
234
 
215
235
  def get_axis_ratio_brandes_2002(diameter):
216
236
  """
217
- Compute the axis ratio of raindrops using the Brandes et al. (2002) method.
237
+ Compute the axis ratio of raindrops using the Brandes et al. (2002) model.
218
238
 
219
239
  Parameters
220
240
  ----------
@@ -243,7 +263,7 @@ def get_axis_ratio_brandes_2002(diameter):
243
263
 
244
264
  def get_axis_ratio_pruppacher_1970(diameter):
245
265
  """
246
- Compute the axis ratio of raindrops using the Pruppacher and Pitter (1971) method.
266
+ Compute the axis ratio of raindrops using the Pruppacher and Pitter (1971) model.
247
267
 
248
268
  Parameters
249
269
  ----------
@@ -273,7 +293,9 @@ def get_axis_ratio_pruppacher_1970(diameter):
273
293
 
274
294
  def get_axis_ratio_thurai_2005(diameter):
275
295
  """
276
- Compute the axis ratio of raindrops using the Thurai et al. (2005) method.
296
+ Compute the axis ratio of raindrops using the Thurai et al. (2005) model.
297
+
298
+ This model is assumed to be valid only for particles up to 5 mm.
277
299
 
278
300
  Parameters
279
301
  ----------
@@ -291,13 +313,12 @@ def get_axis_ratio_thurai_2005(diameter):
291
313
  J. Atmos. Oceanic Technol., 22, 966-978, https://doi.org/10.1175/JTECH1767.1
292
314
 
293
315
  """
294
- # Valid between 1 and 5 mm
295
316
  axis_ratio = 0.9707 + 4.26e-2 * diameter - 4.29e-2 * diameter**2 + 6.5e-3 * diameter**3 - 3e-4 * diameter**4
296
317
  return axis_ratio
297
318
 
298
319
 
299
320
  def get_axis_ratio_thurai_2007(diameter):
300
- """Compute the axis ratio of raindrops using the Thurai et al. (2007) method.
321
+ """Compute the axis ratio of raindrops using the Thurai et al. (2007) model.
301
322
 
302
323
  Parameters
303
324
  ----------
@@ -330,10 +351,13 @@ def get_axis_ratio_thurai_2007(diameter):
330
351
  # Combine axis ratio
331
352
  axis_ratio_below_1_5 = xr.where(diameter > 0.7, axis_ratio_below_1_5, axis_ratio_below_0_7)
332
353
  axis_ratio = xr.where(diameter > 1.5, axis_ratio_above_1_5, axis_ratio_below_1_5)
354
+
355
+ # Ensure np.nan is preserved in arrays
356
+ axis_ratio = xr.where(np.isnan(diameter), np.nan, axis_ratio)
333
357
  return axis_ratio
334
358
 
335
359
 
336
- AXIS_RATIO_METHODS = {
360
+ AXIS_RATIO_MODELS = {
337
361
  "Thurai2005": get_axis_ratio_thurai_2005,
338
362
  "Thurai2007": get_axis_ratio_thurai_2007,
339
363
  "Battaglia2010": get_axis_ratio_battaglia_2010,