cloudnetpy 1.70.2__tar.gz → 1.71.1__tar.gz

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 (131) hide show
  1. {cloudnetpy-1.70.2/cloudnetpy.egg-info → cloudnetpy-1.71.1}/PKG-INFO +2 -1
  2. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/plotting/plot_meta.py +5 -0
  3. cloudnetpy-1.71.1/cloudnetpy/products/epsilon.py +202 -0
  4. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/version.py +2 -2
  5. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1/cloudnetpy.egg-info}/PKG-INFO +2 -1
  6. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy.egg-info/SOURCES.txt +1 -0
  7. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy.egg-info/requires.txt +1 -0
  8. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/pyproject.toml +1 -0
  9. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/LICENSE +0 -0
  10. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/MANIFEST.in +0 -0
  11. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/README.md +0 -0
  12. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/__init__.py +0 -0
  13. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/categorize/__init__.py +0 -0
  14. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/categorize/atmos_utils.py +0 -0
  15. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/categorize/attenuation.py +0 -0
  16. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/categorize/attenuations/__init__.py +0 -0
  17. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/categorize/attenuations/gas_attenuation.py +0 -0
  18. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/categorize/attenuations/liquid_attenuation.py +0 -0
  19. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/categorize/attenuations/melting_attenuation.py +0 -0
  20. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/categorize/attenuations/rain_attenuation.py +0 -0
  21. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/categorize/categorize.py +0 -0
  22. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/categorize/classify.py +0 -0
  23. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/categorize/containers.py +0 -0
  24. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/categorize/disdrometer.py +0 -0
  25. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/categorize/droplet.py +0 -0
  26. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/categorize/falling.py +0 -0
  27. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/categorize/freezing.py +0 -0
  28. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/categorize/insects.py +0 -0
  29. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/categorize/itu.py +0 -0
  30. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/categorize/lidar.py +0 -0
  31. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/categorize/melting.py +0 -0
  32. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/categorize/model.py +0 -0
  33. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/categorize/mwr.py +0 -0
  34. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/categorize/radar.py +0 -0
  35. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/cli.py +0 -0
  36. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/cloudnetarray.py +0 -0
  37. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/concat_lib.py +0 -0
  38. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/constants.py +0 -0
  39. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/datasource.py +0 -0
  40. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/exceptions.py +0 -0
  41. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/instruments/__init__.py +0 -0
  42. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/instruments/basta.py +0 -0
  43. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/instruments/campbell_scientific.py +0 -0
  44. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/instruments/ceilo.py +0 -0
  45. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/instruments/ceilometer.py +0 -0
  46. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/instruments/cl61d.py +0 -0
  47. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/instruments/cloudnet_instrument.py +0 -0
  48. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/instruments/copernicus.py +0 -0
  49. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/instruments/disdrometer/__init__.py +0 -0
  50. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/instruments/disdrometer/common.py +0 -0
  51. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/instruments/disdrometer/parsivel.py +0 -0
  52. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/instruments/disdrometer/thies.py +0 -0
  53. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/instruments/galileo.py +0 -0
  54. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/instruments/hatpro.py +0 -0
  55. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/instruments/instruments.py +0 -0
  56. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/instruments/lufft.py +0 -0
  57. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/instruments/mira.py +0 -0
  58. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/instruments/mrr.py +0 -0
  59. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/instruments/nc_lidar.py +0 -0
  60. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/instruments/nc_radar.py +0 -0
  61. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/instruments/pollyxt.py +0 -0
  62. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/instruments/radiometrics.py +0 -0
  63. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/instruments/rain_e_h3.py +0 -0
  64. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/instruments/rpg.py +0 -0
  65. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/instruments/rpg_reader.py +0 -0
  66. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/instruments/toa5.py +0 -0
  67. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/instruments/vaisala.py +0 -0
  68. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/instruments/weather_station.py +0 -0
  69. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/metadata.py +0 -0
  70. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/__init__.py +0 -0
  71. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/file_handler.py +0 -0
  72. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/metadata.py +0 -0
  73. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/model_metadata.py +0 -0
  74. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/plotting/__init__.py +0 -0
  75. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/plotting/plot_meta.py +0 -0
  76. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/plotting/plot_tools.py +0 -0
  77. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/plotting/plotting.py +0 -0
  78. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/products/__init__.py +0 -0
  79. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/products/advance_methods.py +0 -0
  80. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/products/grid_methods.py +0 -0
  81. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/products/model_products.py +0 -0
  82. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/products/observation_products.py +0 -0
  83. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/products/product_resampling.py +0 -0
  84. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/products/tools.py +0 -0
  85. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/statistics/__init__.py +0 -0
  86. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/statistics/statistical_methods.py +0 -0
  87. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/tests/__init__.py +0 -0
  88. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/tests/e2e/__init__.py +0 -0
  89. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/tests/e2e/conftest.py +0 -0
  90. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/tests/e2e/process_cf/__init__.py +0 -0
  91. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/tests/e2e/process_cf/main.py +0 -0
  92. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/tests/e2e/process_cf/tests.py +0 -0
  93. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/__init__.py +0 -0
  94. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/main.py +0 -0
  95. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/tests.py +0 -0
  96. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/__init__.py +0 -0
  97. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/main.py +0 -0
  98. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/tests.py +0 -0
  99. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/tests/unit/__init__.py +0 -0
  100. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/tests/unit/conftest.py +0 -0
  101. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/tests/unit/test_advance_methods.py +0 -0
  102. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/tests/unit/test_grid_methods.py +0 -0
  103. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/tests/unit/test_model_products.py +0 -0
  104. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/tests/unit/test_observation_products.py +0 -0
  105. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/tests/unit/test_plot_tools.py +0 -0
  106. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/tests/unit/test_plotting.py +0 -0
  107. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/tests/unit/test_statistical_methods.py +0 -0
  108. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/tests/unit/test_tools.py +0 -0
  109. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/model_evaluation/utils.py +0 -0
  110. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/output.py +0 -0
  111. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/plotting/__init__.py +0 -0
  112. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/plotting/plotting.py +0 -0
  113. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/products/__init__.py +0 -0
  114. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/products/classification.py +0 -0
  115. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/products/der.py +0 -0
  116. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/products/drizzle.py +0 -0
  117. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/products/drizzle_error.py +0 -0
  118. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/products/drizzle_tools.py +0 -0
  119. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/products/ier.py +0 -0
  120. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/products/iwc.py +0 -0
  121. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/products/lwc.py +0 -0
  122. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/products/mie_lu_tables.nc +0 -0
  123. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/products/mwr_tools.py +0 -0
  124. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/products/product_tools.py +0 -0
  125. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/py.typed +0 -0
  126. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy/utils.py +0 -0
  127. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy.egg-info/dependency_links.txt +0 -0
  128. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy.egg-info/entry_points.txt +0 -0
  129. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/cloudnetpy.egg-info/top_level.txt +0 -0
  130. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/docs/source/conf.py +0 -0
  131. {cloudnetpy-1.70.2 → cloudnetpy-1.71.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: cloudnetpy
3
- Version: 1.70.2
3
+ Version: 1.71.1
4
4
  Summary: Python package for Cloudnet processing
5
5
  Author: Simo Tukiainen
6
6
  License: MIT License
@@ -42,6 +42,7 @@ Requires-Python: >=3.10
42
42
  Description-Content-Type: text/markdown
43
43
  License-File: LICENSE
44
44
  Requires-Dist: cloudnetpy_qc>=1.15.0
45
+ Requires-Dist: doppy>=0.5.0
45
46
  Requires-Dist: matplotlib
46
47
  Requires-Dist: mwrpy>=1.2.0
47
48
  Requires-Dist: netCDF4
@@ -588,5 +588,10 @@ ATTRIBUTES = {
588
588
  "lwp": PlotMeta(
589
589
  zero_line=True,
590
590
  ),
591
+ "epsilon": PlotMeta(
592
+ cmap="inferno",
593
+ plot_range=(1e-7, 1e-1),
594
+ log_scale=True,
595
+ ),
591
596
  },
592
597
  }
@@ -0,0 +1,202 @@
1
+ from os import PathLike
2
+ from pathlib import Path
3
+
4
+ import doppy
5
+ import doppy.netcdf
6
+ import netCDF4
7
+ import numpy as np
8
+ import numpy.typing as npt
9
+ import scipy.constants
10
+ from doppy.product.turbulence import HorizontalWind, Options, Turbulence, VerticalWind
11
+ from scipy.interpolate import LinearNDInterpolator, NearestNDInterpolator
12
+
13
+ import cloudnetpy
14
+ from cloudnetpy.output import copy_variables
15
+ from cloudnetpy.utils import get_time, get_uuid
16
+
17
+
18
+ def generate_epsilon_from_lidar(
19
+ doppler_lidar_file: str | PathLike,
20
+ doppler_lidar_wind_file: str | PathLike,
21
+ output_file: str | PathLike,
22
+ uuid: str | None,
23
+ ):
24
+ sliding_window_in_seconds = 3 * 60
25
+ uuid = uuid if uuid is not None else get_uuid()
26
+ opts = _get_options(doppler_lidar_file)
27
+ opts.period = sliding_window_in_seconds
28
+ vert = _vertical_wind_from_doppler_lidar_file(doppler_lidar_file)
29
+ hori = _horizontal_wind_from_doppler_lidar_file(doppler_lidar_wind_file)
30
+ turb = Turbulence.from_winds(vert, hori, opts)
31
+
32
+ with (
33
+ netCDF4.Dataset(Path(doppler_lidar_file), "r") as nc_src,
34
+ doppy.netcdf.Dataset(Path(output_file), format="NETCDF4_CLASSIC") as nc,
35
+ ):
36
+ nc.add_dimension("time")
37
+ nc.add_dimension("height", size=len(turb.height))
38
+ nc.add_time(
39
+ name="time",
40
+ dimensions=("time",),
41
+ standard_name="time",
42
+ long_name="Time UTC",
43
+ data=turb.time,
44
+ dtype="f8",
45
+ )
46
+ nc.add_variable(
47
+ name="height",
48
+ dimensions=("height",),
49
+ units="m",
50
+ data=turb.height,
51
+ standard_name=nc_src["height"].standard_name,
52
+ long_name=nc_src["height"].long_name,
53
+ dtype="f4",
54
+ )
55
+ nc.add_variable(
56
+ name="epsilon",
57
+ dimensions=("time", "height"),
58
+ units="m2 s-3",
59
+ data=turb.turbulent_kinetic_energy_dissipation_rate,
60
+ mask=turb.mask,
61
+ dtype="f4",
62
+ long_name="Dissipation rate of turbulent kinetic energy",
63
+ )
64
+ nc.add_scalar_variable(
65
+ name="ray_accumulation_time",
66
+ units="s",
67
+ long_name="Ray accumulation time",
68
+ data=opts.ray_accumulation_time,
69
+ dtype="f4",
70
+ )
71
+ nc.add_scalar_variable(
72
+ name="rolling_window_period",
73
+ units="s",
74
+ long_name="Rolling window period",
75
+ data=opts.period,
76
+ dtype="f4",
77
+ )
78
+
79
+ nc.add_attribute("file_uuid", uuid)
80
+ nc.add_attribute("cloudnet_file_type", "epsilon-lidar")
81
+ nc.add_attribute("doppy_version", doppy.__version__)
82
+ nc.add_attribute("cloudnetpy_version", cloudnetpy.__version__)
83
+ nc.add_attribute(
84
+ "title",
85
+ "Dissipation rate of turbulent kinetic energy (lidar) "
86
+ f"from {nc_src.location}",
87
+ )
88
+
89
+ copy_attributes_from_src(doppler_lidar_file, output_file)
90
+
91
+ with (
92
+ netCDF4.Dataset(output_file, "r+") as nc_out,
93
+ netCDF4.Dataset(doppler_lidar_file, "r") as nc_src_stare,
94
+ netCDF4.Dataset(doppler_lidar_wind_file, "r") as nc_src_wind,
95
+ ):
96
+ copy_variables(
97
+ nc_src_stare, nc_out, ("latitude", "longitude", "altitude", "source")
98
+ )
99
+ nc_out.source_file_uuids = f"{nc_src_stare.file_uuid}, {nc_src_wind.file_uuid}"
100
+ sources = {nc_src_stare.source, nc_src_wind.source}
101
+ nc_out.source = ", ".join(sources)
102
+ history = (
103
+ f"{get_time()} - epsilon-lidar file created using doppy "
104
+ f"v{doppy.__version__} and cloudnetpy v{cloudnetpy.__version__}\n"
105
+ f"{nc_src_stare.history}\n"
106
+ f"{nc_src_wind.history}"
107
+ )
108
+ history = "\n".join(
109
+ line.strip() for line in history.splitlines() if line.strip()
110
+ )
111
+ nc_out.history = history
112
+ nc_out.references = "https://doi.org/10.1175/2010JTECHA1455.1"
113
+ return uuid
114
+
115
+
116
+ def copy_attributes_from_src(src: str | PathLike, trg: str | PathLike) -> None:
117
+ with netCDF4.Dataset(src, "r") as nc_src, netCDF4.Dataset(trg, "a") as nc_trg:
118
+ for attr in ("year", "month", "day", "location", "Conventions"):
119
+ nc_trg.setncattr(attr, nc_src.getncattr(attr))
120
+
121
+
122
+ def _horizontal_wind_from_doppler_lidar_file(
123
+ doppler_lidar_wind_file: str | PathLike,
124
+ ) -> HorizontalWind:
125
+ with netCDF4.Dataset(doppler_lidar_wind_file, "r") as nc:
126
+ time = _datetime64_from_nc_var(nc["time"])
127
+ height = np.array(nc["height"][:].data, dtype=np.float64)
128
+ uwind = np.array(nc["uwind"][:].data, dtype=np.float64)
129
+ vwind = np.array(nc["vwind"][:].data, dtype=np.float64)
130
+ umask = np.array(nc["uwind"][:].mask, dtype=np.bool_)
131
+ vmask = np.array(nc["vwind"][:].mask, dtype=np.bool_)
132
+ V = np.sqrt(uwind**2 + vwind**2)
133
+ mask = umask | vmask
134
+ t = np.broadcast_to(time[:, None], mask.shape)[~mask]
135
+ h = np.broadcast_to(height[None, :], mask.shape)[~mask]
136
+ interp_linear = LinearNDInterpolator(list(zip(t, h, strict=False)), V[~mask])
137
+ interp_nearest = NearestNDInterpolator(list(zip(t, h, strict=False)), V[~mask])
138
+ T, H = np.meshgrid(time, height, indexing="ij")
139
+ V_linear = interp_linear(T, H)
140
+ V_nearest = interp_nearest(T, H)
141
+ isnan = np.isnan(V_linear)
142
+ V_interp = V_linear
143
+ V_interp[isnan] = V_nearest[isnan]
144
+ if np.isnan(V_interp).any():
145
+ msg = "Unexpected nans"
146
+ raise ValueError(msg)
147
+ return HorizontalWind(time=time, height=height, V=V_interp)
148
+
149
+
150
+ def _get_options(doppler_lidar_file: str | PathLike) -> Options:
151
+ with netCDF4.Dataset(doppler_lidar_file, "r") as nc:
152
+ if "ray_accumulation_time" in nc.variables:
153
+ return Options(ray_accumulation_time=nc["ray_accumulation_time"][:])
154
+ if "pulses_per_ray" in nc.variables:
155
+ prf = _infer_pulse_repetition_frequency(
156
+ np.array(nc["range"][:].data, dtype=np.float64)
157
+ )
158
+ return Options(ray_accumulation_time=float(nc["pulses_per_ray"][:] / prf))
159
+ msg = "Missing ray info"
160
+ raise ValueError(msg)
161
+
162
+
163
+ def _infer_pulse_repetition_frequency(range_: npt.NDArray[np.float64]):
164
+ c = scipy.constants.c
165
+ dist = range_.max() - range_.min()
166
+ round_trip_time = 2 * dist / c
167
+
168
+ T_LOW = 1 / 10_000 # Halo XR instruments operate on lower frequency
169
+ T_HIGH = 1 / 15_000 # Rest should operate on higher frequency
170
+ if round_trip_time / T_HIGH < 1:
171
+ return 15e3
172
+ if round_trip_time / T_LOW < 1:
173
+ return 10e3
174
+ msg = f"Suspiciously large range ({dist}m). " "Cannot infer pulse repetition rate"
175
+ raise ValueError(msg)
176
+
177
+
178
+ def _vertical_wind_from_doppler_lidar_file(
179
+ doppler_lidar_file: str | PathLike,
180
+ ) -> VerticalWind:
181
+ with netCDF4.Dataset(doppler_lidar_file, "r") as nc:
182
+ time = _datetime64_from_nc_var(nc["time"])
183
+ height = np.array(nc["height"][:].data, dtype=np.float64)
184
+ w = np.array(nc["v"][:].data, dtype=np.float64)
185
+ mask = np.array(nc["v"][:].mask, dtype=np.bool_)
186
+ if isinstance(mask, np.ndarray) and mask.any():
187
+ w[mask] = np.nan
188
+
189
+ return VerticalWind(time=time, height=height, w=w, mask=mask)
190
+
191
+
192
+ def _datetime64_from_nc_var(var: netCDF4.Variable) -> npt.NDArray[np.datetime64]:
193
+ return np.array(
194
+ netCDF4.num2date(
195
+ var[:].data,
196
+ units=var.units,
197
+ calendar=var.calendar,
198
+ only_use_cftime_datetimes=False,
199
+ only_use_python_datetimes=True,
200
+ ),
201
+ dtype="datetime64[us]",
202
+ )
@@ -1,4 +1,4 @@
1
1
  MAJOR = 1
2
- MINOR = 70
3
- PATCH = 2
2
+ MINOR = 71
3
+ PATCH = 1
4
4
  __version__ = f"{MAJOR}.{MINOR}.{PATCH}"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: cloudnetpy
3
- Version: 1.70.2
3
+ Version: 1.71.1
4
4
  Summary: Python package for Cloudnet processing
5
5
  Author: Simo Tukiainen
6
6
  License: MIT License
@@ -42,6 +42,7 @@ Requires-Python: >=3.10
42
42
  Description-Content-Type: text/markdown
43
43
  License-File: LICENSE
44
44
  Requires-Dist: cloudnetpy_qc>=1.15.0
45
+ Requires-Dist: doppy>=0.5.0
45
46
  Requires-Dist: matplotlib
46
47
  Requires-Dist: mwrpy>=1.2.0
47
48
  Requires-Dist: netCDF4
@@ -119,6 +119,7 @@ cloudnetpy/products/der.py
119
119
  cloudnetpy/products/drizzle.py
120
120
  cloudnetpy/products/drizzle_error.py
121
121
  cloudnetpy/products/drizzle_tools.py
122
+ cloudnetpy/products/epsilon.py
122
123
  cloudnetpy/products/ier.py
123
124
  cloudnetpy/products/iwc.py
124
125
  cloudnetpy/products/lwc.py
@@ -1,4 +1,5 @@
1
1
  cloudnetpy_qc>=1.15.0
2
+ doppy>=0.5.0
2
3
  matplotlib
3
4
  mwrpy>=1.2.0
4
5
  netCDF4
@@ -18,6 +18,7 @@ classifiers = [
18
18
  ]
19
19
  dependencies = [
20
20
  "cloudnetpy_qc>=1.15.0",
21
+ "doppy>=0.5.0",
21
22
  "matplotlib",
22
23
  "mwrpy>=1.2.0",
23
24
  "netCDF4",
File without changes
File without changes
File without changes
File without changes