cloudnetpy 1.61.14__py3-none-any.whl → 1.61.16__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.
- cloudnetpy/categorize/atmos.py +1 -0
- cloudnetpy/categorize/atmos_utils.py +1 -1
- cloudnetpy/categorize/categorize.py +1 -0
- cloudnetpy/categorize/classify.py +1 -0
- cloudnetpy/categorize/containers.py +3 -1
- cloudnetpy/categorize/disdrometer.py +1 -0
- cloudnetpy/categorize/droplet.py +2 -2
- cloudnetpy/categorize/falling.py +1 -0
- cloudnetpy/categorize/freezing.py +1 -0
- cloudnetpy/categorize/insects.py +1 -0
- cloudnetpy/categorize/lidar.py +1 -0
- cloudnetpy/categorize/melting.py +1 -0
- cloudnetpy/categorize/model.py +1 -0
- cloudnetpy/categorize/mwr.py +1 -0
- cloudnetpy/categorize/radar.py +1 -0
- cloudnetpy/cloudnetarray.py +2 -0
- cloudnetpy/concat_lib.py +1 -0
- cloudnetpy/constants.py +1 -0
- cloudnetpy/datasource.py +5 -3
- cloudnetpy/instruments/basta.py +1 -0
- cloudnetpy/instruments/ceilo.py +2 -1
- cloudnetpy/instruments/cl61d.py +1 -0
- cloudnetpy/instruments/copernicus.py +2 -1
- cloudnetpy/instruments/disdrometer/parsivel.py +6 -4
- cloudnetpy/instruments/galileo.py +1 -0
- cloudnetpy/instruments/hatpro.py +1 -0
- cloudnetpy/instruments/lufft.py +1 -0
- cloudnetpy/instruments/mira.py +1 -0
- cloudnetpy/instruments/mrr.py +1 -1
- cloudnetpy/instruments/nc_lidar.py +1 -0
- cloudnetpy/instruments/nc_radar.py +1 -0
- cloudnetpy/instruments/pollyxt.py +1 -0
- cloudnetpy/instruments/radiometrics.py +2 -1
- cloudnetpy/instruments/rpg.py +2 -1
- cloudnetpy/instruments/rpg_reader.py +1 -1
- cloudnetpy/instruments/toa5.py +1 -1
- cloudnetpy/instruments/vaisala.py +7 -6
- cloudnetpy/instruments/weather_station.py +2 -3
- cloudnetpy/model_evaluation/file_handler.py +2 -2
- cloudnetpy/model_evaluation/metadata.py +1 -1
- cloudnetpy/model_evaluation/plotting/plot_tools.py +2 -2
- cloudnetpy/model_evaluation/plotting/plotting.py +11 -8
- cloudnetpy/model_evaluation/products/grid_methods.py +1 -1
- cloudnetpy/model_evaluation/products/model_products.py +7 -7
- cloudnetpy/model_evaluation/products/observation_products.py +8 -8
- cloudnetpy/model_evaluation/products/tools.py +5 -7
- cloudnetpy/model_evaluation/statistics/statistical_methods.py +2 -2
- cloudnetpy/output.py +3 -1
- cloudnetpy/plotting/plot_meta.py +2 -2
- cloudnetpy/plotting/plotting.py +8 -11
- cloudnetpy/products/classification.py +10 -9
- cloudnetpy/products/der.py +3 -2
- cloudnetpy/products/drizzle.py +3 -3
- cloudnetpy/products/drizzle_tools.py +1 -1
- cloudnetpy/products/ier.py +1 -0
- cloudnetpy/products/iwc.py +4 -3
- cloudnetpy/products/lwc.py +2 -3
- cloudnetpy/products/mwr_tools.py +2 -4
- cloudnetpy/products/product_tools.py +2 -1
- cloudnetpy/utils.py +9 -14
- cloudnetpy/version.py +1 -1
- {cloudnetpy-1.61.14.dist-info → cloudnetpy-1.61.16.dist-info}/METADATA +1 -1
- cloudnetpy-1.61.16.dist-info/RECORD +115 -0
- {cloudnetpy-1.61.14.dist-info → cloudnetpy-1.61.16.dist-info}/WHEEL +1 -1
- cloudnetpy-1.61.14.dist-info/RECORD +0 -115
- {cloudnetpy-1.61.14.dist-info → cloudnetpy-1.61.16.dist-info}/LICENSE +0 -0
- {cloudnetpy-1.61.14.dist-info → cloudnetpy-1.61.16.dist-info}/top_level.txt +0 -0
cloudnetpy/categorize/atmos.py
CHANGED
@@ -9,7 +9,7 @@ from cloudnetpy.constants import MM_H_TO_M_S
|
|
9
9
|
|
10
10
|
@dataclass
|
11
11
|
class ClassificationResult:
|
12
|
-
"""Result of classification"""
|
12
|
+
"""Result of classification."""
|
13
13
|
|
14
14
|
category_bits: np.ndarray
|
15
15
|
is_rain: np.ndarray
|
@@ -103,6 +103,8 @@ def _find_clutter(
|
|
103
103
|
"""Estimates clutter from doppler velocity.
|
104
104
|
|
105
105
|
Args:
|
106
|
+
v: 2D radar velocity.
|
107
|
+
is_rain: 2D boolean array denoting rain.
|
106
108
|
n_gates: Number of range gates from the ground where clutter is expected
|
107
109
|
to be found. Default is 10.
|
108
110
|
v_lim: Velocity threshold. Smaller values are classified as clutter.
|
cloudnetpy/categorize/droplet.py
CHANGED
cloudnetpy/categorize/falling.py
CHANGED
cloudnetpy/categorize/insects.py
CHANGED
cloudnetpy/categorize/lidar.py
CHANGED
cloudnetpy/categorize/melting.py
CHANGED
cloudnetpy/categorize/model.py
CHANGED
cloudnetpy/categorize/mwr.py
CHANGED
cloudnetpy/categorize/radar.py
CHANGED
cloudnetpy/cloudnetarray.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
"""CloudnetArray class."""
|
2
|
+
|
2
3
|
import math
|
3
4
|
from collections.abc import Sequence
|
4
5
|
|
@@ -62,6 +63,7 @@ class CloudnetArray:
|
|
62
63
|
Args:
|
63
64
|
time: 1D time array.
|
64
65
|
time_new: 1D new time array.
|
66
|
+
mask_zeros: Whether to mask 0 values in the returned array. Default is True.
|
65
67
|
|
66
68
|
Returns:
|
67
69
|
Time indices without data.
|
cloudnetpy/concat_lib.py
CHANGED
cloudnetpy/constants.py
CHANGED
cloudnetpy/datasource.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
"""Datasource module, containing the :class:`DataSource class
|
1
|
+
"""Datasource module, containing the :class:`DataSource` class."""
|
2
|
+
|
2
3
|
import logging
|
3
4
|
import os
|
4
5
|
from collections.abc import Callable
|
@@ -94,6 +95,7 @@ class DataSource:
|
|
94
95
|
attribute (dictionary).
|
95
96
|
name: CloudnetArray.name attribute. Default value is *key*.
|
96
97
|
units: CloudnetArray.units attribute.
|
98
|
+
dtype: CloudnetArray.data_type attribute.
|
97
99
|
|
98
100
|
"""
|
99
101
|
self.data[key] = CloudnetArray(variable, name or key, units, data_type=dtype)
|
@@ -101,10 +103,10 @@ class DataSource:
|
|
101
103
|
def get_date(self) -> list:
|
102
104
|
"""Returns date components.
|
103
105
|
|
104
|
-
Returns
|
106
|
+
Returns:
|
105
107
|
list: Date components [YYYY, MM, DD].
|
106
108
|
|
107
|
-
Raises
|
109
|
+
Raises:
|
108
110
|
RuntimeError: Not found or invalid date.
|
109
111
|
|
110
112
|
"""
|
cloudnetpy/instruments/basta.py
CHANGED
cloudnetpy/instruments/ceilo.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
"""Module for reading and processing Vaisala / Lufft ceilometers."""
|
2
|
+
|
2
3
|
from itertools import islice
|
3
4
|
|
4
5
|
import netCDF4
|
@@ -45,7 +46,7 @@ def ceilo2nc(
|
|
45
46
|
site_meta: Dictionary containing information about the site and instrument.
|
46
47
|
Required key value pairs are `name` and `altitude` (metres above mean
|
47
48
|
sea level). Also, 'calibration_factor' is recommended because the default
|
48
|
-
value is probably incorrect. If the
|
49
|
+
value is probably incorrect. If the background noise is *not*
|
49
50
|
range-corrected, you must define: {'range_corrected': False}.
|
50
51
|
You can also explicitly set the instrument model with
|
51
52
|
e.g. {'model': 'cl61d'}.
|
cloudnetpy/instruments/cl61d.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
"""Module for reading raw cloud radar data."""
|
2
|
+
|
2
3
|
import os
|
3
4
|
import tempfile
|
4
5
|
from tempfile import TemporaryDirectory
|
@@ -126,7 +127,7 @@ class Copernicus(ChilboltonRadar):
|
|
126
127
|
def mask_corrupted_values(self) -> None:
|
127
128
|
"""Experimental masking of corrupted Copernicus data.
|
128
129
|
|
129
|
-
Notes
|
130
|
+
Notes:
|
130
131
|
This method is based on a few days of test data only. Should be improved
|
131
132
|
and tested more carefully in the future.
|
132
133
|
"""
|
@@ -43,7 +43,7 @@ def parsivel2nc(
|
|
43
43
|
the instrument's operating instructions. Unknown values are indicated
|
44
44
|
with None. Telegram is required if the input file doesn't contain a
|
45
45
|
header.
|
46
|
-
timestamps:
|
46
|
+
timestamps: Specify list of timestamps if they are missing in the input file.
|
47
47
|
|
48
48
|
Returns:
|
49
49
|
UUID of the generated file.
|
@@ -450,7 +450,7 @@ def _parse_row(row_in: str, headers: list[str]) -> list:
|
|
450
450
|
def _read_toa5(filename: str | PathLike) -> dict[str, list]:
|
451
451
|
"""Read ASCII data from Campbell Scientific datalogger such as CR1000.
|
452
452
|
|
453
|
-
References
|
453
|
+
References:
|
454
454
|
CR1000 Measurement and Control System.
|
455
455
|
https://s.campbellsci.com/documents/us/manuals/cr1000.pdf
|
456
456
|
"""
|
@@ -616,8 +616,10 @@ def _read_typ_op4a(lines: list[str]) -> dict[str, Any]:
|
|
616
616
|
|
617
617
|
|
618
618
|
def _read_fmi(content: str):
|
619
|
-
"""Read format used by Finnish Meteorological Institute and University of
|
620
|
-
Helsinki
|
619
|
+
r"""Read format used by Finnish Meteorological Institute and University of
|
620
|
+
Helsinki.
|
621
|
+
|
622
|
+
Format consists of sequence of the following:
|
621
623
|
- "[YYYY-MM-DD HH:MM:SS\n"
|
622
624
|
- output of "CS/PA" command without non-printable characters at the end
|
623
625
|
- "]\n"
|
cloudnetpy/instruments/hatpro.py
CHANGED
cloudnetpy/instruments/lufft.py
CHANGED
cloudnetpy/instruments/mira.py
CHANGED
cloudnetpy/instruments/mrr.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
"""Module for reading Radiometrics MP3014 microwave radiometer data."""
|
2
|
+
|
2
3
|
import csv
|
3
4
|
import datetime
|
4
5
|
import logging
|
@@ -80,7 +81,7 @@ class Record(NamedTuple):
|
|
80
81
|
class Radiometrics:
|
81
82
|
"""Reader for level 2 files of Radiometrics microwave radiometers.
|
82
83
|
|
83
|
-
References
|
84
|
+
References:
|
84
85
|
Radiometrics (2008). Profiler Operator's Manual: MP-3000A, MP-2500A,
|
85
86
|
MP-1500A, MP-183A.
|
86
87
|
"""
|
cloudnetpy/instruments/rpg.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
"""This module contains RPG Cloud Radar related functions."""
|
2
|
+
|
2
3
|
import logging
|
3
4
|
import math
|
4
5
|
from collections.abc import Sequence
|
@@ -111,7 +112,7 @@ def create_one_day_data_record(rpg_objects: RpgObjects) -> dict:
|
|
111
112
|
def _stack_rpg_data(rpg_objects: RpgObjects) -> tuple[dict, dict]:
|
112
113
|
"""Combines data from hourly RPG objects.
|
113
114
|
|
114
|
-
Notes
|
115
|
+
Notes:
|
115
116
|
Ignores variable names starting with an underscore.
|
116
117
|
|
117
118
|
"""
|
@@ -164,7 +164,7 @@ def _decode_angles(
|
|
164
164
|
class HatproBin:
|
165
165
|
"""HATPRO binary file reader. Byte order is assumed to be little endian.
|
166
166
|
|
167
|
-
References
|
167
|
+
References:
|
168
168
|
Radiometer Physics (2014): Instrument Operation and Software Guide
|
169
169
|
Operation Principles and Software Description for RPG standard single
|
170
170
|
polarization radiometers (G5 series).
|
cloudnetpy/instruments/toa5.py
CHANGED
@@ -9,7 +9,7 @@ def read_toa5(
|
|
9
9
|
) -> tuple[dict[str, str], dict[str, str], list[dict[str, Any]]]:
|
10
10
|
"""Read ASCII data from Campbell Scientific datalogger such as CR1000.
|
11
11
|
|
12
|
-
References
|
12
|
+
References:
|
13
13
|
CR1000 Measurement and Control System.
|
14
14
|
https://s.campbellsci.com/documents/us/manuals/cr1000.pdf
|
15
15
|
"""
|
@@ -1,4 +1,5 @@
|
|
1
1
|
"""Module with classes for Vaisala ceilometers."""
|
2
|
+
|
2
3
|
import itertools
|
3
4
|
import logging
|
4
5
|
|
@@ -139,7 +140,7 @@ class VaisalaCeilo(Ceilometer):
|
|
139
140
|
|
140
141
|
@staticmethod
|
141
142
|
def _calc_date(time_lines) -> list:
|
142
|
-
"""Returns the date [yyyy, mm, dd]"""
|
143
|
+
"""Returns the date [yyyy, mm, dd]."""
|
143
144
|
return time_lines[0].split()[0].strip("-").split("-")
|
144
145
|
|
145
146
|
@classmethod
|
@@ -305,7 +306,7 @@ class ClCeilo(VaisalaCeilo):
|
|
305
306
|
class Ct25k(VaisalaCeilo):
|
306
307
|
"""Class for Vaisala CT25k ceilometer.
|
307
308
|
|
308
|
-
References
|
309
|
+
References:
|
309
310
|
https://www.manualslib.com/manual/1414094/Vaisala-Ct25k.html
|
310
311
|
|
311
312
|
"""
|
@@ -367,11 +368,11 @@ class Ct25k(VaisalaCeilo):
|
|
367
368
|
def split_string(string: str, indices: list) -> list:
|
368
369
|
"""Splits string between indices.
|
369
370
|
|
370
|
-
Notes
|
371
|
+
Notes:
|
371
372
|
It is possible to skip characters from the beginning and end of the
|
372
373
|
string but not from the middle.
|
373
374
|
|
374
|
-
Examples
|
375
|
+
Examples:
|
375
376
|
>>> s = 'abcde'
|
376
377
|
>>> indices = [1, 2, 4]
|
377
378
|
>>> split_string(s, indices)
|
@@ -384,7 +385,7 @@ def split_string(string: str, indices: list) -> list:
|
|
384
385
|
def values_to_dict(keys: tuple, values: list) -> dict:
|
385
386
|
"""Converts list elements to dictionary.
|
386
387
|
|
387
|
-
Examples
|
388
|
+
Examples:
|
388
389
|
>>> keys = ('a', 'b')
|
389
390
|
>>> values = [[1, 2], [1, 2], [1, 2], [1, 2]]
|
390
391
|
>>> values_to_dict(keys, values)
|
@@ -398,6 +399,6 @@ def values_to_dict(keys: tuple, values: list) -> dict:
|
|
398
399
|
|
399
400
|
|
400
401
|
def time_to_fraction_hour(time: str) -> float:
|
401
|
-
"""Returns time (hh:mm:ss) as fraction hour"""
|
402
|
+
"""Returns time (hh:mm:ss) as fraction hour."""
|
402
403
|
hour, minute, sec = time.split(":")
|
403
404
|
return int(hour) + (int(minute) * SEC_IN_MINUTE + int(sec)) / SEC_IN_HOUR
|
@@ -320,11 +320,10 @@ class KenttarovaWS(WS):
|
|
320
320
|
|
321
321
|
|
322
322
|
class HyytialaWS(WS):
|
323
|
-
"""
|
324
|
-
Hyytiälä rain-gauge variables: a = Pluvio400 and b = Pluvio200.
|
323
|
+
"""Hyytiälä rain-gauge variables: a = Pluvio400 and b = Pluvio200.
|
325
324
|
E.g.
|
326
325
|
- AaRNRT/mm = amount of non-real-time rain total (Pluvio400) [mm]
|
327
|
-
- BbRT/mm = Bucket content in real-time (Pluvio200) [mm]
|
326
|
+
- BbRT/mm = Bucket content in real-time (Pluvio200) [mm].
|
328
327
|
"""
|
329
328
|
|
330
329
|
def __init__(self, filenames: list[str], site_meta: dict):
|
@@ -145,7 +145,7 @@ def _augment_global_attributes(root_group: netCDF4.Dataset) -> None:
|
|
145
145
|
|
146
146
|
|
147
147
|
def _add_source(root_ground: netCDF4.Dataset, objects: tuple, files: tuple) -> None:
|
148
|
-
"""Generates source info for multiple files"""
|
148
|
+
"""Generates source info for multiple files."""
|
149
149
|
model, obs = objects
|
150
150
|
model_files, obs_file = files
|
151
151
|
source = f"Observation file: {os.path.basename(obs_file)}"
|
@@ -160,7 +160,7 @@ def _add_source(root_ground: netCDF4.Dataset, objects: tuple, files: tuple) -> N
|
|
160
160
|
|
161
161
|
|
162
162
|
def add_time_attribute(date: datetime) -> dict:
|
163
|
-
"""
|
163
|
+
"""Adds time attribute with correct units.
|
164
164
|
|
165
165
|
Args:
|
166
166
|
attributes: Attributes of variables.
|
@@ -114,7 +114,7 @@ REGRID_PRODUCT_ATTRIBUTES = {
|
|
114
114
|
comment=(
|
115
115
|
"Cloud fraction generated from observations and by volume,\n"
|
116
116
|
"averaged onto the models grid with height and time. Volume is\n"
|
117
|
-
"space
|
117
|
+
"space within four grid points."
|
118
118
|
),
|
119
119
|
),
|
120
120
|
"cf_A": MetaData(
|
@@ -13,7 +13,7 @@ def parse_wanted_names(
|
|
13
13
|
*,
|
14
14
|
advance: bool = False,
|
15
15
|
) -> tuple[list, list]:
|
16
|
-
"""Returns standard and advection lists of product types to plot"""
|
16
|
+
"""Returns standard and advection lists of product types to plot."""
|
17
17
|
if variables:
|
18
18
|
names = variables
|
19
19
|
else:
|
@@ -76,7 +76,7 @@ def sort_cycles(names: list, model: str) -> tuple[list, list]:
|
|
76
76
|
|
77
77
|
|
78
78
|
def read_data_characters(nc_file: str, name: str, model: str) -> tuple:
|
79
|
-
"""Gets dimensions and data for plotting"""
|
79
|
+
"""Gets dimensions and data for plotting."""
|
80
80
|
nc = netCDF4.Dataset(nc_file)
|
81
81
|
data = nc.variables[name][:]
|
82
82
|
data = mask_small_values(data, name)
|
@@ -7,9 +7,11 @@ import matplotlib as mpl
|
|
7
7
|
import matplotlib.pyplot as plt
|
8
8
|
import netCDF4
|
9
9
|
import numpy as np
|
10
|
+
from matplotlib.axes import Axes
|
10
11
|
from matplotlib.colorbar import Colorbar
|
11
12
|
from matplotlib.colors import ListedColormap
|
12
13
|
from matplotlib.patches import Patch
|
14
|
+
from matplotlib.pyplot import Figure
|
13
15
|
from mpl_toolkits.axes_grid1 import make_axes_locatable
|
14
16
|
from numpy import ma
|
15
17
|
|
@@ -187,6 +189,7 @@ def get_group_plots(
|
|
187
189
|
show (bool): Show figure before saving if True
|
188
190
|
cycle (str): Name of cycle if exists
|
189
191
|
title (bool): True or False if wanted to add title to subfig
|
192
|
+
include_xlimits (bool): Show labels at the ends of x-axis
|
190
193
|
"""
|
191
194
|
fig, ax = initialize_figure(len(names))
|
192
195
|
model_run = model
|
@@ -248,6 +251,7 @@ def get_pair_plots(
|
|
248
251
|
show (bool): Show figure before saving if True
|
249
252
|
cycle (str): Name of cycle if exists
|
250
253
|
title (bool): True or False if wanted add title to subfig
|
254
|
+
include_xlimits (bool): Show labels at the ends of x-axis
|
251
255
|
"""
|
252
256
|
variable_info = ATTRIBUTES[product]
|
253
257
|
model_ax = names[0]
|
@@ -306,6 +310,7 @@ def get_single_plots(
|
|
306
310
|
show (bool): Show figure before saving if True
|
307
311
|
cycle (str): Name of cycle if exists
|
308
312
|
title (bool): True or False if wanted to add title to subfig
|
313
|
+
include_xlimits (bool): Show labels at the ends of x-axis
|
309
314
|
"""
|
310
315
|
figs = []
|
311
316
|
axes = []
|
@@ -387,6 +392,7 @@ def get_statistic_plots(
|
|
387
392
|
image_name (str, optional): Saving name of generated fig
|
388
393
|
show (bool): Show figure before saving if True
|
389
394
|
cycle (str): Name of cycle if exists
|
395
|
+
title (bool): True or False if wanted to add title to subfig
|
390
396
|
"""
|
391
397
|
model_run = model
|
392
398
|
name = ""
|
@@ -687,8 +693,8 @@ def plot_vertical_profile(
|
|
687
693
|
ax.xaxis.grid(which="major")
|
688
694
|
|
689
695
|
|
690
|
-
def initialize_figure(n_subplots: int, stat: str = "") -> tuple:
|
691
|
-
"""Set up fig and ax object, if subplot"""
|
696
|
+
def initialize_figure(n_subplots: int, stat: str = "") -> tuple[Figure, list[Axes]]:
|
697
|
+
"""Set up fig and ax object, if subplot."""
|
692
698
|
if n_subplots <= 0:
|
693
699
|
n_subplots = 1
|
694
700
|
fig, axes = plt.subplots(n_subplots, 1, figsize=(16, 4 + (n_subplots - 1) * 4.8))
|
@@ -714,7 +720,6 @@ def initialize_figure(n_subplots: int, stat: str = "") -> tuple:
|
|
714
720
|
right=0.75,
|
715
721
|
hspace=0.2,
|
716
722
|
)
|
717
|
-
axes = axes.flatten()
|
718
723
|
if stat == "vertical" and n_subplots > 1:
|
719
724
|
fig, axes = plt.subplots(
|
720
725
|
int(n_subplots / 2),
|
@@ -731,10 +736,8 @@ def initialize_figure(n_subplots: int, stat: str = "") -> tuple:
|
|
731
736
|
right=0.75,
|
732
737
|
hspace=0.16,
|
733
738
|
)
|
734
|
-
|
735
|
-
|
736
|
-
axes = [axes]
|
737
|
-
return fig, axes
|
739
|
+
axes_list = [axes] if isinstance(axes, Axes) else axes.flatten().tolist()
|
740
|
+
return fig, axes_list
|
738
741
|
|
739
742
|
|
740
743
|
def init_colorbar(plot, axis) -> Colorbar:
|
@@ -750,7 +753,7 @@ def _set_title(
|
|
750
753
|
variable_info,
|
751
754
|
model_name: str = "",
|
752
755
|
) -> None:
|
753
|
-
"""Generates subtitles for different product types"""
|
756
|
+
"""Generates subtitles for different product types."""
|
754
757
|
parts = field_name.split("_")
|
755
758
|
if parts[0] == product:
|
756
759
|
title = _get_product_title(variable_info)
|
@@ -154,7 +154,7 @@ class ProductGrid:
|
|
154
154
|
x_ind: np.ndarray,
|
155
155
|
y_ind: np.ndarray,
|
156
156
|
) -> np.ndarray | None:
|
157
|
-
"""Reshapes True observation values to windows shape"""
|
157
|
+
"""Reshapes True observation values to windows shape."""
|
158
158
|
window_size = tl.get_obs_window_size(x_ind, y_ind)
|
159
159
|
if window_size is not None:
|
160
160
|
return self._obs_data[ind].reshape(window_size)
|
@@ -54,7 +54,7 @@ class ModelManager(DataSource):
|
|
54
54
|
self.resolution_h = self._get_horizontal_resolution()
|
55
55
|
|
56
56
|
def _read_cycle_name(self, model_file: str) -> str:
|
57
|
-
"""Get cycle name from model_metadata.py for saving variable name(s)"""
|
57
|
+
"""Get cycle name from model_metadata.py for saving variable name(s)."""
|
58
58
|
try:
|
59
59
|
cycles = self.model_info.cycle
|
60
60
|
if cycles is None:
|
@@ -68,7 +68,7 @@ class ModelManager(DataSource):
|
|
68
68
|
return ""
|
69
69
|
|
70
70
|
def _generate_products(self) -> None:
|
71
|
-
"""Process needed data of model to a ModelManager object"""
|
71
|
+
"""Process needed data of model to a ModelManager object."""
|
72
72
|
cls = importlib.import_module(__name__).ModelManager
|
73
73
|
try:
|
74
74
|
name = f"_get_{self._product}"
|
@@ -123,10 +123,10 @@ class ModelManager(DataSource):
|
|
123
123
|
return q * p / (287 * t)
|
124
124
|
|
125
125
|
def _add_variables(self) -> None:
|
126
|
-
"""Add basic variables off model and cycle"""
|
126
|
+
"""Add basic variables off model and cycle."""
|
127
127
|
|
128
128
|
def _add_common_variables() -> None:
|
129
|
-
"""Model variables that are always the same within cycles"""
|
129
|
+
"""Model variables that are always the same within cycles."""
|
130
130
|
wanted_vars = self.model_vars.common_var
|
131
131
|
if wanted_vars is None:
|
132
132
|
msg = f"Model {self.model} has no common variables"
|
@@ -140,7 +140,7 @@ class ModelManager(DataSource):
|
|
140
140
|
self.append_data(data, f"{var}")
|
141
141
|
|
142
142
|
def _add_cycle_variables() -> None:
|
143
|
-
"""Add cycle depending variables"""
|
143
|
+
"""Add cycle depending variables."""
|
144
144
|
wanted_vars = self.model_vars.cycle_var
|
145
145
|
if wanted_vars is None:
|
146
146
|
msg = f"Model {self.model} has no cycle variables"
|
@@ -160,7 +160,7 @@ class ModelManager(DataSource):
|
|
160
160
|
_add_cycle_variables()
|
161
161
|
|
162
162
|
def cut_off_extra_levels(self, data: np.ndarray) -> np.ndarray:
|
163
|
-
"""Remove unused levels (over 22km) from model data"""
|
163
|
+
"""Remove unused levels (over 22km) from model data."""
|
164
164
|
try:
|
165
165
|
level = self.model_info.level
|
166
166
|
except KeyError:
|
@@ -169,7 +169,7 @@ class ModelManager(DataSource):
|
|
169
169
|
return data[:, :level] if data.ndim > 1 else data[:level]
|
170
170
|
|
171
171
|
def _calculate_wind_speed(self) -> np.ndarray:
|
172
|
-
"""Real wind from x- and y-components"""
|
172
|
+
"""Real wind from x- and y-components."""
|
173
173
|
u = self.getvar("uwind")
|
174
174
|
v = self.getvar("vwind")
|
175
175
|
u = self.cut_off_extra_levels(u)
|