cloudnetpy 1.96.1__tar.gz → 1.96.3__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.
- {cloudnetpy-1.96.1/cloudnetpy.egg-info → cloudnetpy-1.96.3}/PKG-INFO +2 -2
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/categorize/attenuations/__init__.py +2 -2
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/categorize/classify.py +1 -1
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/categorize/containers.py +2 -1
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/categorize/falling.py +1 -1
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/categorize/freezing.py +1 -1
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/categorize/insects.py +24 -2
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/categorize/melting.py +42 -6
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/categorize/radar.py +3 -6
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/cli.py +8 -2
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/constants.py +16 -16
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/disdronator/parsivel.py +2 -1
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/disdronator/process.py +8 -8
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/fd12p.py +3 -4
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/hatpro.py +2 -2
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/mwr3c.py +1 -1
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/mwrlos.py +1 -1
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/radiometrics.py +6 -5
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/rain_e_h3.py +3 -4
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/weather_station.py +12 -6
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/plotting/plotting.py +2 -1
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/products/advance_methods.py +2 -1
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/products/model_products.py +1 -1
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/unit/test_model_products.py +1 -1
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/plotting/plotting.py +11 -10
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/products/cod.py +1 -4
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/products/der.py +6 -4
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/products/drizzle.py +2 -3
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/products/drizzle_error.py +3 -5
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/products/epsilon_lidar.py +2 -3
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/products/iwc_weather_radar.py +3 -2
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/products/mwr_tools.py +17 -3
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/utils.py +2 -1
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/version.py +1 -1
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3/cloudnetpy.egg-info}/PKG-INFO +2 -2
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy.egg-info/requires.txt +1 -1
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/pyproject.toml +1 -1
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/LICENSE +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/MANIFEST.in +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/README.md +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/__init__.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/arm.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/categorize/__init__.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/categorize/atmos_utils.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/categorize/attenuation.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/categorize/attenuations/gas_attenuation.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/categorize/attenuations/liquid_attenuation.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/categorize/attenuations/melting_attenuation.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/categorize/attenuations/rain_attenuation.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/categorize/categorize.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/categorize/disdrometer.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/categorize/droplet.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/categorize/lidar.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/categorize/model.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/categorize/mwr.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/cloudnetarray.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/concat_lib.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/datasource.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/disdronator/__init__.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/disdronator/lpm.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/disdronator/rd80.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/disdronator/utils.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/exceptions.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/__init__.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/arm_ceilo.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/arm_ld.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/arm_utils.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/basta.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/bowtie.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/ceilo.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/ceilometer.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/cl61d.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/cloudnet_instrument.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/copernicus.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/da10.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/dealias.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/disdrometer.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/galileo.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/instruments.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/kazr.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/lufft.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/mira.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/mmcr.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/mrr.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/nc_lidar.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/nc_radar.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/pollyxt.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/rpg.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/rpg_reader.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/toa5.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/vaisala.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/instruments/weather_radar.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/metadata.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/__init__.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/file_handler.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/metadata.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/model_metadata.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/plotting/__init__.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/plotting/plot_meta.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/plotting/plot_tools.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/products/__init__.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/products/grid_methods.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/products/observation_products.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/products/product_resampling.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/products/tools.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/statistics/__init__.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/statistics/statistical_methods.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/__init__.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/e2e/__init__.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/e2e/conftest.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/e2e/process_cf/__init__.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/e2e/process_cf/main.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/e2e/process_cf/tests.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/__init__.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/main.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/tests.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/__init__.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/main.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/tests.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/unit/__init__.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/unit/conftest.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/unit/test_advance_methods.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/unit/test_grid_methods.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/unit/test_observation_products.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/unit/test_plot_tools.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/unit/test_plotting.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/unit/test_statistical_methods.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/unit/test_tools.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/utils.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/output.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/plotting/__init__.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/plotting/plot_meta.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/products/__init__.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/products/classification.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/products/drizzle_tools.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/products/epsilon_radar.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/products/ier.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/products/iwc.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/products/lwc.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/products/mie_lu_tables.nc +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/products/product_tools.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/py.typed +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy.egg-info/SOURCES.txt +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy.egg-info/dependency_links.txt +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy.egg-info/entry_points.txt +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy.egg-info/top_level.txt +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/docs/source/conf.py +0 -0
- {cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cloudnetpy
|
|
3
|
-
Version: 1.96.
|
|
3
|
+
Version: 1.96.3
|
|
4
4
|
Summary: Python package for Cloudnet processing
|
|
5
5
|
Author: Simo Tukiainen
|
|
6
6
|
License: MIT License
|
|
@@ -43,7 +43,7 @@ Requires-Dist: ceilopyter>=0.2.0
|
|
|
43
43
|
Requires-Dist: cloudnet-api-client
|
|
44
44
|
Requires-Dist: doppy>=0.5.0
|
|
45
45
|
Requires-Dist: matplotlib
|
|
46
|
-
Requires-Dist: mwrpy>=1.
|
|
46
|
+
Requires-Dist: mwrpy>=1.7.0
|
|
47
47
|
Requires-Dist: netCDF4
|
|
48
48
|
Requires-Dist: requests
|
|
49
49
|
Requires-Dist: rpgpy>=0.14.5
|
|
@@ -31,7 +31,7 @@ def calc_two_way_attenuation(
|
|
|
31
31
|
"""Calculates two-way attenuation (dB) for given specific attenuation
|
|
32
32
|
(dB km-1) and height above ground level (m).
|
|
33
33
|
"""
|
|
34
|
-
path_lengths = path_lengths_from_ground(height_agl) * con.M_TO_KM
|
|
34
|
+
path_lengths = path_lengths_from_ground(height_agl) * con.M_TO_KM
|
|
35
35
|
one_way_attenuation = specific_attenuation * path_lengths
|
|
36
36
|
accumulated_attenuation = ma.cumsum(one_way_attenuation, axis=1)
|
|
37
|
-
return accumulated_attenuation *
|
|
37
|
+
return accumulated_attenuation * 2 # two way
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
import numpy.typing as npt
|
|
3
|
+
from atmoslib.constants import T0
|
|
3
4
|
from numpy import ma
|
|
4
5
|
from scipy import ndimage
|
|
5
6
|
|
|
@@ -18,7 +19,6 @@ from cloudnetpy.categorize.containers import (
|
|
|
18
19
|
ClassificationResult,
|
|
19
20
|
Observations,
|
|
20
21
|
)
|
|
21
|
-
from cloudnetpy.constants import T0
|
|
22
22
|
from cloudnetpy.products.product_tools import CategoryBits, QualityBits
|
|
23
23
|
|
|
24
24
|
|
|
@@ -4,10 +4,11 @@ from os import PathLike
|
|
|
4
4
|
|
|
5
5
|
import numpy as np
|
|
6
6
|
import numpy.typing as npt
|
|
7
|
+
from atmoslib.constants import T0
|
|
7
8
|
from numpy import ma
|
|
8
9
|
|
|
9
10
|
from cloudnetpy import utils
|
|
10
|
-
from cloudnetpy.constants import MM_H_TO_M_S
|
|
11
|
+
from cloudnetpy.constants import MM_H_TO_M_S
|
|
11
12
|
from cloudnetpy.products.product_tools import CategoryBits
|
|
12
13
|
|
|
13
14
|
from .disdrometer import Disdrometer
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
import numpy as np
|
|
4
4
|
import numpy.typing as npt
|
|
5
|
+
from atmoslib.constants import T0
|
|
5
6
|
from numpy import ma
|
|
6
7
|
|
|
7
8
|
from cloudnetpy.categorize import atmos_utils
|
|
8
9
|
from cloudnetpy.categorize.containers import ClassData
|
|
9
|
-
from cloudnetpy.constants import T0
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
def find_falling_hydrometeors(
|
|
@@ -4,12 +4,12 @@ import logging
|
|
|
4
4
|
|
|
5
5
|
import numpy as np
|
|
6
6
|
import numpy.typing as npt
|
|
7
|
+
from atmoslib.constants import T0
|
|
7
8
|
from numpy import ma
|
|
8
9
|
from scipy.interpolate import interp1d
|
|
9
10
|
|
|
10
11
|
from cloudnetpy import utils
|
|
11
12
|
from cloudnetpy.categorize.containers import ClassData
|
|
12
|
-
from cloudnetpy.constants import T0
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
def find_freezing_region(obs: ClassData, melting_layer: npt.NDArray) -> npt.NDArray:
|
|
@@ -58,7 +58,9 @@ def _insect_probability(obs: ClassData) -> tuple[npt.NDArray, npt.NDArray]:
|
|
|
58
58
|
prob_from_ldr = _calc_prob_from_ldr(prob)
|
|
59
59
|
prob_from_others = _calc_prob_from_all(prob)
|
|
60
60
|
prob_from_others = _adjust_for_radar(obs, prob, prob_from_others)
|
|
61
|
-
|
|
61
|
+
prob_from_others = _adjust_for_lidar(obs, prob_from_others)
|
|
62
|
+
is_ldr = ~ma.getmaskarray(obs.ldr) if hasattr(obs, "ldr") else None
|
|
63
|
+
prob_combined = _fill_missing_pixels(prob_from_ldr, prob_from_others, is_ldr)
|
|
62
64
|
return prob_combined, prob_from_others
|
|
63
65
|
|
|
64
66
|
|
|
@@ -147,11 +149,31 @@ def _adjust_for_radar(
|
|
|
147
149
|
return prob_from_others
|
|
148
150
|
|
|
149
151
|
|
|
152
|
+
def _adjust_for_lidar(
|
|
153
|
+
obs: ClassData,
|
|
154
|
+
prob_from_others: npt.NDArray,
|
|
155
|
+
weight: float = 0.8,
|
|
156
|
+
) -> npt.NDArray:
|
|
157
|
+
"""Reduces probability above the lidar signal, where liquid may be hidden."""
|
|
158
|
+
is_beta = ~ma.getmaskarray(obs.beta)
|
|
159
|
+
n_gates = is_beta.shape[1]
|
|
160
|
+
top = n_gates - np.argmax(is_beta[:, ::-1], axis=1)
|
|
161
|
+
top[~is_beta.any(axis=1)] = 0
|
|
162
|
+
above_lidar = np.arange(n_gates)[np.newaxis, :] >= top[:, np.newaxis]
|
|
163
|
+
prob_from_others[above_lidar] *= weight
|
|
164
|
+
return prob_from_others
|
|
165
|
+
|
|
166
|
+
|
|
150
167
|
def _fill_missing_pixels(
|
|
151
168
|
prob_from_ldr: npt.NDArray,
|
|
152
169
|
prob_from_others: npt.NDArray,
|
|
170
|
+
is_ldr: npt.NDArray | None = None,
|
|
153
171
|
) -> npt.NDArray:
|
|
154
|
-
|
|
172
|
+
"""Combines probabilities trusting measured ldr over other parameters."""
|
|
173
|
+
prob = np.maximum(prob_from_ldr, prob_from_others)
|
|
174
|
+
if is_ldr is not None:
|
|
175
|
+
prob[is_ldr] = prob_from_ldr[is_ldr]
|
|
176
|
+
return prob
|
|
155
177
|
|
|
156
178
|
|
|
157
179
|
def _screen_insects(
|
|
@@ -2,13 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
import numpy as np
|
|
4
4
|
import numpy.typing as npt
|
|
5
|
+
from atmoslib.constants import T0
|
|
5
6
|
from numpy import ma
|
|
6
7
|
from scipy.ndimage import gaussian_filter
|
|
7
8
|
|
|
8
9
|
from cloudnetpy import utils
|
|
9
10
|
from cloudnetpy.categorize import droplet
|
|
10
11
|
from cloudnetpy.categorize.containers import ClassData
|
|
11
|
-
|
|
12
|
+
|
|
13
|
+
MIN_LAPSE_RATE = 0.004 # K m-1
|
|
14
|
+
MIN_LDR_COVERAGE = 0.5
|
|
15
|
+
T0_TOLERANCE = 1 # K
|
|
12
16
|
|
|
13
17
|
|
|
14
18
|
def find_melting_layer(obs: ClassData, *, smooth: bool = True) -> npt.NDArray:
|
|
@@ -27,11 +31,15 @@ def find_melting_layer(obs: ClassData, *, smooth: bool = True) -> npt.NDArray:
|
|
|
27
31
|
The peak in *ldr* is the primary parameter we analyze. If
|
|
28
32
|
*ldr* has a proper peak, and *v* < -1 m/s in the base, melting layer
|
|
29
33
|
has been found. If *ldr* is missing we only analyze the behaviour
|
|
30
|
-
of *v*, which is always present, to detect the melting layer.
|
|
34
|
+
of *v*, which is always present, to detect the melting layer. If *ldr*
|
|
35
|
+
covers the profile but shows no peak, there is no melting layer.
|
|
31
36
|
|
|
32
37
|
Model temperature is used to limit the melting layer search to a certain
|
|
33
38
|
temperature range around 0 C. For ECMWF the range is -4..+3, and for
|
|
34
|
-
the rest -8..+6.
|
|
39
|
+
the rest -8..+6. Model temperature must also reach -1 C in the profile,
|
|
40
|
+
and the search is limited in altitude above the highest 0 C level,
|
|
41
|
+
because in temperature inversions the temperature range alone may
|
|
42
|
+
span several kilometers.
|
|
35
43
|
|
|
36
44
|
Notes:
|
|
37
45
|
This melting layer detection method is novel and needs to be validated.
|
|
@@ -63,7 +71,7 @@ def find_melting_layer(obs: ClassData, *, smooth: bool = True) -> npt.NDArray:
|
|
|
63
71
|
t_range = _find_model_temperature_range(obs.model_type)
|
|
64
72
|
|
|
65
73
|
for ind, t_prof in enumerate(obs.tw):
|
|
66
|
-
temp_indices = _get_temp_indices(t_prof, t_range)
|
|
74
|
+
temp_indices = _get_temp_indices(t_prof, t_range, obs.height)
|
|
67
75
|
if len(temp_indices) <= 1:
|
|
68
76
|
continue
|
|
69
77
|
z_prof = obs.z[ind, temp_indices]
|
|
@@ -90,6 +98,8 @@ def find_melting_layer(obs: ClassData, *, smooth: bool = True) -> npt.NDArray:
|
|
|
90
98
|
z_prof,
|
|
91
99
|
)
|
|
92
100
|
except (ValueError, IndexError, AssertionError):
|
|
101
|
+
if _has_ldr_coverage(ldr_prof, v_prof):
|
|
102
|
+
continue
|
|
93
103
|
height = obs.height[temp_indices]
|
|
94
104
|
if hasattr(obs, "width"):
|
|
95
105
|
width_prof = obs.width[ind, temp_indices]
|
|
@@ -104,6 +114,16 @@ def find_melting_layer(obs: ClassData, *, smooth: bool = True) -> npt.NDArray:
|
|
|
104
114
|
return melting_layer
|
|
105
115
|
|
|
106
116
|
|
|
117
|
+
def _has_ldr_coverage(ldr_prof: npt.NDArray | None, v_prof: npt.NDArray) -> bool:
|
|
118
|
+
"""Checks if ldr covers enough of the profile to rule out melting layer."""
|
|
119
|
+
if ldr_prof is None:
|
|
120
|
+
return False
|
|
121
|
+
is_v = ~ma.getmaskarray(v_prof)
|
|
122
|
+
is_ldr = ~ma.getmaskarray(ldr_prof)
|
|
123
|
+
n_ldr = np.count_nonzero(is_ldr & is_v)
|
|
124
|
+
return bool(n_ldr >= MIN_LDR_COVERAGE * np.count_nonzero(is_v))
|
|
125
|
+
|
|
126
|
+
|
|
107
127
|
def _find_melting_layer_from_ldr(
|
|
108
128
|
ldr_prof: npt.NDArray,
|
|
109
129
|
ldr_dprof: npt.NDArray,
|
|
@@ -166,12 +186,28 @@ def _basetop(dprof: npt.NDArray, pind: int) -> tuple[int, int]:
|
|
|
166
186
|
return base, top
|
|
167
187
|
|
|
168
188
|
|
|
169
|
-
def _get_temp_indices(
|
|
189
|
+
def _get_temp_indices(
|
|
190
|
+
t_prof: npt.NDArray, t_range: tuple, height: npt.NDArray | None = None
|
|
191
|
+
) -> npt.NDArray:
|
|
170
192
|
"""Finds indices of temperature profile covering the given range."""
|
|
171
|
-
|
|
193
|
+
in_range = (t_prof > min(t_range) + T0) & (t_prof < max(t_range) + T0)
|
|
194
|
+
if height is not None:
|
|
195
|
+
in_range &= height <= _find_max_height(t_prof, t_range, height)
|
|
196
|
+
ind = np.where(in_range)[0]
|
|
172
197
|
return np.array([]) if len(ind) == 0 else np.arange(np.min(ind), np.max(ind) + 1)
|
|
173
198
|
|
|
174
199
|
|
|
200
|
+
def _find_max_height(t_prof: npt.NDArray, t_range: tuple, height: npt.NDArray) -> float:
|
|
201
|
+
"""Finds maximum melting layer height assuming realistic lapse rate."""
|
|
202
|
+
warm = np.where(t_prof >= T0)[0]
|
|
203
|
+
if len(warm) == 0:
|
|
204
|
+
# Model may be slightly too cold when melting layer is near the ground
|
|
205
|
+
warm = np.where(t_prof >= T0 - T0_TOLERANCE)[0]
|
|
206
|
+
if len(warm) == 0:
|
|
207
|
+
return -np.inf
|
|
208
|
+
return height[warm[-1]] - min(t_range) / MIN_LAPSE_RATE
|
|
209
|
+
|
|
210
|
+
|
|
175
211
|
def _find_model_temperature_range(model_type: str) -> tuple[float, float]:
|
|
176
212
|
"""Returns temperature range around 0C for given model type."""
|
|
177
213
|
if model_type == "gdas1":
|
|
@@ -7,11 +7,10 @@ from os import PathLike
|
|
|
7
7
|
import numpy as np
|
|
8
8
|
import numpy.typing as npt
|
|
9
9
|
from numpy import ma
|
|
10
|
-
from scipy import constants
|
|
11
10
|
|
|
12
11
|
from cloudnetpy import utils
|
|
13
12
|
from cloudnetpy.categorize.attenuations import RadarAttenuation
|
|
14
|
-
from cloudnetpy.constants import GHZ_TO_HZ, SEC_IN_HOUR, SPEED_OF_LIGHT
|
|
13
|
+
from cloudnetpy.constants import GHZ_TO_HZ, LN_TO_DB, SEC_IN_HOUR, SPEED_OF_LIGHT
|
|
15
14
|
from cloudnetpy.datasource import DataSource
|
|
16
15
|
|
|
17
16
|
|
|
@@ -265,8 +264,7 @@ class Radar(DataSource):
|
|
|
265
264
|
"""
|
|
266
265
|
noise_threshold = 3
|
|
267
266
|
n_pulses = _number_of_independent_pulses()
|
|
268
|
-
|
|
269
|
-
z_precision = ma.divide(ln_to_log10, np.sqrt(n_pulses)) * (
|
|
267
|
+
z_precision = ma.divide(LN_TO_DB, np.sqrt(n_pulses)) * (
|
|
270
268
|
1 + (utils.db2lin(z_power_min - z_power) / noise_threshold)
|
|
271
269
|
)
|
|
272
270
|
|
|
@@ -439,8 +437,7 @@ class Radar(DataSource):
|
|
|
439
437
|
|
|
440
438
|
|
|
441
439
|
def _prf_to_folding_velocity(prf: npt.NDArray, radar_frequency: float) -> npt.NDArray:
|
|
442
|
-
ghz_to_hz = 1e9
|
|
443
440
|
if len(prf) != 1:
|
|
444
441
|
msg = "Unable to determine folding velocity"
|
|
445
442
|
raise RuntimeError(msg)
|
|
446
|
-
return prf[0] *
|
|
443
|
+
return prf[0] * SPEED_OF_LIGHT / (4 * radar_frequency * GHZ_TO_HZ)
|
|
@@ -928,9 +928,11 @@ def main() -> None:
|
|
|
928
928
|
)
|
|
929
929
|
parser.add_argument(
|
|
930
930
|
"--show",
|
|
931
|
-
|
|
931
|
+
nargs="?",
|
|
932
|
+
const=True,
|
|
932
933
|
default=False,
|
|
933
|
-
|
|
934
|
+
metavar="VARIABLES",
|
|
935
|
+
help="Show plotted image, optionally only given variables (comma-separated)",
|
|
934
936
|
)
|
|
935
937
|
parser.add_argument(
|
|
936
938
|
"--dl",
|
|
@@ -980,6 +982,10 @@ def main() -> None:
|
|
|
980
982
|
default=None,
|
|
981
983
|
)
|
|
982
984
|
args = parser.parse_args()
|
|
985
|
+
if isinstance(args.show, str):
|
|
986
|
+
if args.variables is None:
|
|
987
|
+
args.variables = args.show
|
|
988
|
+
args.show = True
|
|
983
989
|
|
|
984
990
|
logger = logging.getLogger()
|
|
985
991
|
logger.setLevel(logging.INFO)
|
|
@@ -1,24 +1,21 @@
|
|
|
1
1
|
"""Constants used in Cloudnet processing."""
|
|
2
2
|
|
|
3
|
+
import math
|
|
3
4
|
from typing import Final
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
T_FREEZING: Final = 273.15
|
|
7
|
+
"""Freezing point of water at standard pressure (K), i.e. 0 degrees Celsius"""
|
|
7
8
|
|
|
8
|
-
# Ratio of the molecular weight of water vapor to dry air
|
|
9
|
-
MW_RATIO: Final = 0.62198
|
|
10
|
-
|
|
11
|
-
# Specific gas constant for dry air (J kg-1 K-1)
|
|
12
|
-
RS: Final = 287.058
|
|
13
|
-
|
|
14
|
-
# ice density kg m-3
|
|
15
9
|
RHO_ICE: Final = 917
|
|
10
|
+
"""Ice density (kg m-3)"""
|
|
11
|
+
|
|
12
|
+
RHO_WATER: Final = 1000
|
|
13
|
+
"""Liquid water density (kg m-3)"""
|
|
16
14
|
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
SPEED_OF_LIGHT: Final = 299_792_458
|
|
16
|
+
"""Speed of light in vacuum (m s-1)"""
|
|
19
17
|
|
|
20
|
-
#
|
|
21
|
-
SPEED_OF_LIGHT: Final = 3.0e8
|
|
18
|
+
# Unit conversions
|
|
22
19
|
SEC_IN_MINUTE: Final = 60
|
|
23
20
|
SEC_IN_HOUR: Final = 3600
|
|
24
21
|
SEC_IN_DAY: Final = 86400
|
|
@@ -35,7 +32,10 @@ MM_H_TO_M_S: Final = 1 / M_S_TO_MM_H
|
|
|
35
32
|
GHZ_TO_HZ: Final = 1e9
|
|
36
33
|
HZ_TO_GHZ: Final = 1e-9
|
|
37
34
|
HPA_TO_PA: Final = 100
|
|
38
|
-
PA_TO_HPA: Final = 1 / HPA_TO_PA
|
|
39
35
|
KM_H_TO_M_S: Final = 1000 / SEC_IN_HOUR
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
|
|
37
|
+
CM_TO_KG_M2: Final = 10
|
|
38
|
+
"""Liquid water equivalent cm to kg m-2"""
|
|
39
|
+
|
|
40
|
+
LN_TO_DB: Final = 10 / math.log(10)
|
|
41
|
+
"""Natural logarithm of a power ratio to decibels"""
|
|
@@ -9,6 +9,7 @@ import netCDF4
|
|
|
9
9
|
import numpy as np
|
|
10
10
|
import numpy.typing as npt
|
|
11
11
|
|
|
12
|
+
from cloudnetpy.constants import M_S_TO_MM_H
|
|
12
13
|
from cloudnetpy.disdronator.process import DisdroL1
|
|
13
14
|
from cloudnetpy.disdronator.utils import convert_to_numpy
|
|
14
15
|
|
|
@@ -434,7 +435,7 @@ def _read_parsivel2nc(filename: str | PathLike) -> ParsivelOutput:
|
|
|
434
435
|
time = cftime.num2pydate(nc["time"][:], units=nc["time"].units)
|
|
435
436
|
data = {num: nc[key][:] for key, num in PARSIVEL2NC_KEYS.items()}
|
|
436
437
|
# The data logger converts mm/h to m/s, so we need to revert this.
|
|
437
|
-
data[1] *=
|
|
438
|
+
data[1] *= M_S_TO_MM_H
|
|
438
439
|
# The data logger attempts to convert temperature from °C to K, but this
|
|
439
440
|
# is incorrectly done only for the first value.
|
|
440
441
|
data[12][0] -= 273
|
|
@@ -4,6 +4,7 @@ import numpy as np
|
|
|
4
4
|
import numpy.typing as npt
|
|
5
5
|
from numpy import ma
|
|
6
6
|
|
|
7
|
+
from cloudnetpy import constants
|
|
7
8
|
from cloudnetpy.disdronator.utils import make_rain_mask
|
|
8
9
|
|
|
9
10
|
|
|
@@ -63,10 +64,9 @@ def process_l2(l1: DisdroL1) -> DisdroL2:
|
|
|
63
64
|
area_mm2 = (
|
|
64
65
|
l1.area_eff if l1.area_eff is not None else np.repeat(l1.area_nom, n_diameter)
|
|
65
66
|
)
|
|
66
|
-
area_m2 = area_mm2 *
|
|
67
|
-
diameter_m = l1.diameter
|
|
68
|
-
interval_h = interval /
|
|
69
|
-
rho_w = 1e-6 # kg mm-3
|
|
67
|
+
area_m2 = area_mm2 * constants.MM2_TO_M2
|
|
68
|
+
diameter_m = l1.diameter * constants.MM_TO_M
|
|
69
|
+
interval_h = interval / constants.SEC_IN_HOUR
|
|
70
70
|
|
|
71
71
|
if spec.ndim == 2:
|
|
72
72
|
number_concentration = spec / (
|
|
@@ -81,10 +81,10 @@ def process_l2(l1: DisdroL1) -> DisdroL2:
|
|
|
81
81
|
energy_flux = (
|
|
82
82
|
np.pi
|
|
83
83
|
/ 12
|
|
84
|
-
*
|
|
84
|
+
* constants.RHO_WATER
|
|
85
85
|
* np.sum(
|
|
86
86
|
spec
|
|
87
|
-
*
|
|
87
|
+
* diameter_m**3
|
|
88
88
|
* l1.velocity**2
|
|
89
89
|
/ (area_m2 * interval_h[:, np.newaxis]),
|
|
90
90
|
axis=1,
|
|
@@ -138,10 +138,10 @@ def process_l2(l1: DisdroL1) -> DisdroL2:
|
|
|
138
138
|
energy_flux = (
|
|
139
139
|
np.pi
|
|
140
140
|
/ 12
|
|
141
|
-
*
|
|
141
|
+
* constants.RHO_WATER
|
|
142
142
|
* np.sum(
|
|
143
143
|
spec_rain
|
|
144
|
-
*
|
|
144
|
+
* diameter_m[:, np.newaxis] ** 3
|
|
145
145
|
* l1.velocity**2
|
|
146
146
|
/ (area_m2[:, np.newaxis] * interval_h[:, np.newaxis, np.newaxis]),
|
|
147
147
|
axis=(1, 2),
|
|
@@ -9,6 +9,7 @@ import numpy as np
|
|
|
9
9
|
from numpy import ma
|
|
10
10
|
|
|
11
11
|
from cloudnetpy import output
|
|
12
|
+
from cloudnetpy.constants import MM_H_TO_M_S, MM_TO_M
|
|
12
13
|
from cloudnetpy.exceptions import ValidTimeStampError
|
|
13
14
|
from cloudnetpy.instruments import instruments
|
|
14
15
|
from cloudnetpy.instruments.cloudnet_instrument import CSVFile
|
|
@@ -122,11 +123,9 @@ class FD12P(CSVFile):
|
|
|
122
123
|
|
|
123
124
|
def convert_units(self) -> None:
|
|
124
125
|
precipitation_rate = self.data["precipitation_rate"][:]
|
|
125
|
-
self.data["precipitation_rate"].data =
|
|
126
|
-
precipitation_rate / 3600 / 1000
|
|
127
|
-
) # mm/h -> m/s
|
|
126
|
+
self.data["precipitation_rate"].data = precipitation_rate * MM_H_TO_M_S
|
|
128
127
|
for key in ("precipitation_amount", "snowfall_amount"):
|
|
129
|
-
self.data[key].data = self.data[key][:]
|
|
128
|
+
self.data[key].data = self.data[key][:] * MM_TO_M
|
|
130
129
|
|
|
131
130
|
def screen_all_masked(self) -> None:
|
|
132
131
|
is_valid = np.ones_like(self.data["time"][:], dtype=np.bool_)
|
|
@@ -10,6 +10,7 @@ import numpy as np
|
|
|
10
10
|
from numpy import ma
|
|
11
11
|
|
|
12
12
|
from cloudnetpy import output, utils
|
|
13
|
+
from cloudnetpy.constants import CM_TO_KG_M2
|
|
13
14
|
from cloudnetpy.datasource import DataSource
|
|
14
15
|
from cloudnetpy.exceptions import ValidTimeStampError
|
|
15
16
|
from cloudnetpy.instruments.arm_utils import concatenate_files, read_geolocation
|
|
@@ -17,7 +18,6 @@ from cloudnetpy.instruments.cloudnet_instrument import CloudnetInstrument
|
|
|
17
18
|
from cloudnetpy.instruments.instruments import MWR3C
|
|
18
19
|
from cloudnetpy.metadata import COMMON_ATTRIBUTES
|
|
19
20
|
|
|
20
|
-
CM_TO_KG_M2 = 10
|
|
21
21
|
MISSING_VALUE = -9999
|
|
22
22
|
MAX_OFF_ZENITH = 1.0 # deg
|
|
23
23
|
RAW_VARIABLES = (
|
|
@@ -10,6 +10,7 @@ import numpy as np
|
|
|
10
10
|
from numpy import ma
|
|
11
11
|
|
|
12
12
|
from cloudnetpy import output, utils
|
|
13
|
+
from cloudnetpy.constants import CM_TO_KG_M2
|
|
13
14
|
from cloudnetpy.datasource import DataSource
|
|
14
15
|
from cloudnetpy.exceptions import ValidTimeStampError
|
|
15
16
|
from cloudnetpy.instruments.arm_utils import concatenate_files, read_geolocation
|
|
@@ -17,7 +18,6 @@ from cloudnetpy.instruments.cloudnet_instrument import CloudnetInstrument
|
|
|
17
18
|
from cloudnetpy.instruments.instruments import WVR1100
|
|
18
19
|
from cloudnetpy.metadata import COMMON_ATTRIBUTES
|
|
19
20
|
|
|
20
|
-
CM_TO_KG_M2 = 10
|
|
21
21
|
RAW_VARIABLES = ("time", "liq", "vap", "qc_liq", "qc_vap", "wet_window")
|
|
22
22
|
|
|
23
23
|
|
|
@@ -18,6 +18,7 @@ from numpy import ma
|
|
|
18
18
|
|
|
19
19
|
from cloudnetpy import output, utils
|
|
20
20
|
from cloudnetpy.cloudnetarray import CloudnetArray
|
|
21
|
+
from cloudnetpy.constants import CM_TO_KG_M2, G_TO_KG
|
|
21
22
|
from cloudnetpy.exceptions import InconsistentDataError, ValidTimeStampError
|
|
22
23
|
from cloudnetpy.instruments import instruments
|
|
23
24
|
from cloudnetpy.metadata import MetaData
|
|
@@ -236,8 +237,8 @@ class RadiometricsMP:
|
|
|
236
237
|
_process_superblock()
|
|
237
238
|
|
|
238
239
|
self.data["time"] = np.array(times, dtype="datetime64[s]")
|
|
239
|
-
self.data["lwp"] = np.array(lwps) # mm
|
|
240
|
-
self.data["iwv"] = np.array(iwvs) *
|
|
240
|
+
self.data["lwp"] = np.array(lwps) # mm = kg m-2
|
|
241
|
+
self.data["iwv"] = np.array(iwvs) * CM_TO_KG_M2
|
|
241
242
|
if irt_times:
|
|
242
243
|
self.data["irt"] = _find_closest(
|
|
243
244
|
np.array(irt_times, dtype="datetime64[s]"),
|
|
@@ -259,7 +260,7 @@ class RadiometricsMP:
|
|
|
259
260
|
if ah_times:
|
|
260
261
|
self.data["absolute_humidity"] = _find_closest(
|
|
261
262
|
np.array(ah_times, dtype="datetime64[s]"),
|
|
262
|
-
np.array(ahs)
|
|
263
|
+
np.array(ahs) * G_TO_KG, # g m-3 => kg m-3
|
|
263
264
|
self.data["time"],
|
|
264
265
|
)
|
|
265
266
|
|
|
@@ -312,8 +313,8 @@ class RadiometricsWVR:
|
|
|
312
313
|
],
|
|
313
314
|
dtype="datetime64[s]",
|
|
314
315
|
)
|
|
315
|
-
self.data["lwp"] = np.array(self.raw_data["LiqCM"]) *
|
|
316
|
-
self.data["iwv"] = np.array(self.raw_data["VapCM"]) *
|
|
316
|
+
self.data["lwp"] = np.array(self.raw_data["LiqCM"]) * CM_TO_KG_M2
|
|
317
|
+
self.data["iwv"] = np.array(self.raw_data["VapCM"]) * CM_TO_KG_M2
|
|
317
318
|
is_zenith = np.abs(np.array(self.raw_data["ELact"]) - 90.0) < 1.0
|
|
318
319
|
tb23_valid = np.array(self.raw_data["TbSky23"]) > 0
|
|
319
320
|
tb31_valid = np.array(self.raw_data["TbSky31"]) > 0
|
|
@@ -6,6 +6,7 @@ from uuid import UUID
|
|
|
6
6
|
import numpy as np
|
|
7
7
|
|
|
8
8
|
from cloudnetpy import output
|
|
9
|
+
from cloudnetpy.constants import MM_H_TO_M_S, MM_TO_M
|
|
9
10
|
from cloudnetpy.exceptions import ValidTimeStampError
|
|
10
11
|
from cloudnetpy.instruments import instruments
|
|
11
12
|
from cloudnetpy.instruments.cloudnet_instrument import CSVFile
|
|
@@ -165,7 +166,5 @@ class RainEH3(CSVFile):
|
|
|
165
166
|
|
|
166
167
|
def convert_units(self) -> None:
|
|
167
168
|
rainfall_rate = self.data["rainfall_rate"][:]
|
|
168
|
-
self.data["rainfall_rate"].data = rainfall_rate
|
|
169
|
-
self.data["rainfall_amount"].data =
|
|
170
|
-
self.data["rainfall_amount"][:] / 1000
|
|
171
|
-
) # mm -> m
|
|
169
|
+
self.data["rainfall_rate"].data = rainfall_rate * MM_H_TO_M_S
|
|
170
|
+
self.data["rainfall_amount"].data = self.data["rainfall_amount"][:] * MM_TO_M
|
|
@@ -14,7 +14,13 @@ from numpy import ma
|
|
|
14
14
|
|
|
15
15
|
from cloudnetpy import output
|
|
16
16
|
from cloudnetpy.cloudnetarray import CloudnetArray
|
|
17
|
-
from cloudnetpy.constants import
|
|
17
|
+
from cloudnetpy.constants import (
|
|
18
|
+
HPA_TO_PA,
|
|
19
|
+
MM_H_TO_M_S,
|
|
20
|
+
MM_TO_M,
|
|
21
|
+
SEC_IN_HOUR,
|
|
22
|
+
SEC_IN_MINUTE,
|
|
23
|
+
)
|
|
18
24
|
from cloudnetpy.exceptions import ValidTimeStampError
|
|
19
25
|
from cloudnetpy.instruments import instruments
|
|
20
26
|
from cloudnetpy.instruments.cloudnet_instrument import CSVFile
|
|
@@ -147,7 +153,9 @@ class WS(CSVFile):
|
|
|
147
153
|
if "rainfall_rate" not in self.data:
|
|
148
154
|
return
|
|
149
155
|
rainfall_rate = self.data["rainfall_rate"][:]
|
|
150
|
-
self.data["rainfall_rate"].data =
|
|
156
|
+
self.data["rainfall_rate"].data = (
|
|
157
|
+
rainfall_rate * MM_TO_M / SEC_IN_MINUTE
|
|
158
|
+
) # mm/min -> m/s
|
|
151
159
|
|
|
152
160
|
def convert_pressure(self) -> None:
|
|
153
161
|
if "air_pressure" not in self.data:
|
|
@@ -249,9 +257,7 @@ class PalaiseauWS(WS):
|
|
|
249
257
|
self.data[key] = CloudnetArray(array_masked, key)
|
|
250
258
|
|
|
251
259
|
def convert_rainfall_amount(self) -> None:
|
|
252
|
-
self.data["rainfall_amount"].data =
|
|
253
|
-
self.data["rainfall_amount"][:] / 1000
|
|
254
|
-
) # mm -> m
|
|
260
|
+
self.data["rainfall_amount"].data = self.data["rainfall_amount"][:] * MM_TO_M
|
|
255
261
|
|
|
256
262
|
def _validate_header(self, header: list[str]) -> None:
|
|
257
263
|
column_titles = [row for row in header if "Col." in row]
|
|
@@ -710,7 +716,7 @@ class LimassolWS(WS):
|
|
|
710
716
|
def convert_rainfall_rate(self) -> None:
|
|
711
717
|
rainfall_rate = self.data["rainfall_rate"][:]
|
|
712
718
|
self.data["rainfall_rate"].data = (
|
|
713
|
-
rainfall_rate / (10 *
|
|
719
|
+
rainfall_rate * MM_TO_M / (10 * SEC_IN_MINUTE)
|
|
714
720
|
) # mm/(10 min) -> m/s
|
|
715
721
|
|
|
716
722
|
|
|
@@ -18,6 +18,7 @@ from mpl_toolkits.axes_grid1 import make_axes_locatable
|
|
|
18
18
|
from numpy import ma
|
|
19
19
|
|
|
20
20
|
import cloudnetpy.model_evaluation.plotting.plot_tools as p_tools
|
|
21
|
+
from cloudnetpy.constants import T_FREEZING
|
|
21
22
|
from cloudnetpy.model_evaluation.plotting.plot_meta import ATTRIBUTES, PlotMeta
|
|
22
23
|
from cloudnetpy.model_evaluation.statistics.statistical_methods import DayStatistics
|
|
23
24
|
from cloudnetpy.plotting.plotting import (
|
|
@@ -205,7 +206,7 @@ def plot_colormesh(
|
|
|
205
206
|
data = data.T
|
|
206
207
|
vmin, vmax = variable_info.plot_range
|
|
207
208
|
if variable_info.clabel == "\u00b0C":
|
|
208
|
-
data = data -
|
|
209
|
+
data = data - T_FREEZING
|
|
209
210
|
if variable_info.plot_scale == "logarithmic":
|
|
210
211
|
data, vmin, vmax = lin2log(data, vmin, vmax)
|
|
211
212
|
cmap = plt.get_cmap(variable_info.cbar, 22)
|
{cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/products/advance_methods.py
RENAMED
|
@@ -5,6 +5,7 @@ import scipy.stats
|
|
|
5
5
|
from numpy import ma
|
|
6
6
|
|
|
7
7
|
import cloudnetpy.utils as cl_tools
|
|
8
|
+
from cloudnetpy.constants import T_FREEZING
|
|
8
9
|
from cloudnetpy.model_evaluation.model_metadata import MODEL_PREFIX
|
|
9
10
|
from cloudnetpy.model_evaluation.products.model_products import ModelManager
|
|
10
11
|
from cloudnetpy.model_evaluation.products.observation_products import ObservationManager
|
|
@@ -49,7 +50,7 @@ class AdvanceProductMethods:
|
|
|
49
50
|
cf = self.getvar_from_object("cf")
|
|
50
51
|
h = self.getvar_from_object("h")
|
|
51
52
|
temperature = self._model_obj.getvar("temperature")
|
|
52
|
-
t_screened = self.remove_extra_levels(temperature -
|
|
53
|
+
t_screened = self.remove_extra_levels(temperature - T_FREEZING)
|
|
53
54
|
iwc, lwc = (self._model_obj.get_water_content(var) for var in ["iwc", "lwc"])
|
|
54
55
|
coeffs = self.set_frequency_parameters()
|
|
55
56
|
z_sen = self.fit_z_sensitivity(h)
|
{cloudnetpy-1.96.1 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/products/model_products.py
RENAMED
|
@@ -3,9 +3,9 @@ from os import PathLike
|
|
|
3
3
|
|
|
4
4
|
import numpy as np
|
|
5
5
|
import numpy.typing as npt
|
|
6
|
+
from atmoslib.constants import RS
|
|
6
7
|
from numpy import ma
|
|
7
8
|
|
|
8
|
-
from cloudnetpy.constants import RS
|
|
9
9
|
from cloudnetpy.datasource import DataSource
|
|
10
10
|
from cloudnetpy.exceptions import ModelDataError
|
|
11
11
|
from cloudnetpy.model_evaluation.model_metadata import (
|
|
@@ -3,7 +3,7 @@ import numpy as np
|
|
|
3
3
|
import pytest
|
|
4
4
|
from numpy import testing
|
|
5
5
|
|
|
6
|
-
from
|
|
6
|
+
from atmoslib.constants import RS
|
|
7
7
|
from cloudnetpy.exceptions import ModelDataError
|
|
8
8
|
from cloudnetpy.model_evaluation.products.model_products import ModelManager
|
|
9
9
|
|