Skip to content

Commit cf7892c

Browse files
committed
Add bowtie
1 parent 1aa1d44 commit cf7892c

File tree

5 files changed

+107
-8
lines changed

5 files changed

+107
-8
lines changed

cloudnetpy/instruments/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from .basta import basta2nc
2+
from .bowtie import bowtie2nc
23
from .ceilo import ceilo2nc
34
from .copernicus import copernicus2nc
45
from .disdrometer import parsivel2nc, thies2nc

cloudnetpy/instruments/bowtie.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
from os import PathLike
2+
3+
from cloudnetpy import output
4+
from cloudnetpy.constants import G_TO_KG, MM_H_TO_M_S
5+
from cloudnetpy.instruments.instruments import FMCW94
6+
from cloudnetpy.instruments.nc_radar import NcRadar
7+
from cloudnetpy.metadata import MetaData
8+
9+
10+
def bowtie2nc(
11+
bowtie_file: str | PathLike,
12+
output_file: str,
13+
site_meta: dict,
14+
uuid: str | None = None,
15+
date: str | None = None,
16+
) -> str:
17+
"""Converts data from 'Bowtie' cloud radar on RV-Meteor into
18+
Cloudnet Level 1b netCDF file.
19+
20+
Args:
21+
bowtie_file: Input filename.
22+
output_file: Output filename.
23+
site_meta: Dictionary containing information about the site. Required key
24+
value pair is `name`. Optional are `latitude`, `longitude`, `altitude`.
25+
uuid: Set specific UUID for the file.
26+
date: Expected date as YYYY-MM-DD of all profiles in the file.
27+
28+
Returns:
29+
UUID of the generated file.
30+
31+
Raises:
32+
ValidTimeStampError: No valid timestamps found.
33+
34+
"""
35+
keymap = {
36+
"Zh": "Zh",
37+
"v": "v",
38+
"width": "width",
39+
"ldr": "ldr",
40+
"kurt": "kurtosis",
41+
"Skew": "skewness",
42+
"SNR": "SNR",
43+
"time": "time",
44+
"range": "range",
45+
"lwp": "lwp",
46+
"SurfRelHum": "relative_humidity",
47+
"rain": "rainfall_rate",
48+
"Nyquist_velocity": "nyquist_velocity",
49+
"range_offsets": "chirp_start_indices",
50+
}
51+
52+
with Bowtie(bowtie_file, site_meta) as bowtie:
53+
bowtie.init_data(keymap)
54+
bowtie.add_time_and_range()
55+
if date is not None:
56+
bowtie.check_date(date)
57+
bowtie.add_radar_specific_variables()
58+
bowtie.add_site_geolocation()
59+
bowtie.add_height()
60+
bowtie.convert_units()
61+
bowtie.test_if_all_masked()
62+
attributes = output.add_time_attribute(ATTRIBUTES, bowtie.date)
63+
output.update_attributes(bowtie.data, attributes)
64+
return output.save_level1b(bowtie, output_file, uuid)
65+
66+
67+
class Bowtie(NcRadar):
68+
def __init__(self, full_path: str | PathLike, site_meta: dict):
69+
super().__init__(full_path, site_meta)
70+
self.instrument = FMCW94
71+
self.date = self.get_date()
72+
73+
def convert_units(self):
74+
self.data["lwp"].data *= G_TO_KG
75+
self.data["rainfall_rate"].data *= MM_H_TO_M_S
76+
self.data["relative_humidity"].data /= 100
77+
78+
def check_date(self, date: str):
79+
if "-".join(self.date) != date:
80+
msg = f"Expected date {date} does not match the file date {self.date}"
81+
raise ValueError(msg)
82+
83+
84+
ATTRIBUTES: dict = {
85+
"v": MetaData(
86+
long_name="Doppler velocity",
87+
units="m s-1",
88+
comment=(
89+
"This parameter is the radial component of the velocity, with positive\n"
90+
"velocities are away from the radar. It was corrected for the heave\n"
91+
"motion of the ship. A rolling average over 3 time steps has been\n"
92+
"applied to it."
93+
),
94+
),
95+
}

cloudnetpy/instruments/rpg.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -445,10 +445,6 @@ def _filter_zenith_angle(zenith: ma.MaskedArray) -> np.ndarray:
445445
long_name="Number of spectral samples in each chirp sequence",
446446
units="1",
447447
),
448-
"chirp_start_indices": MetaData(
449-
long_name="Chirp sequences start indices",
450-
units="1",
451-
),
452448
"number_of_averaged_chirps": MetaData(
453449
long_name="Number of averaged chirps in sequence",
454450
units="1",
@@ -517,10 +513,6 @@ def _filter_zenith_angle(zenith: ma.MaskedArray) -> np.ndarray:
517513
long_name="PC temperature",
518514
units="K",
519515
),
520-
"skewness": MetaData(
521-
long_name="Skewness of spectra",
522-
units="1",
523-
),
524516
"kurtosis": MetaData(
525517
long_name="Kurtosis of spectra",
526518
units="1",

cloudnetpy/metadata.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ class MetaData(NamedTuple):
9393
long_name="Kurtosis of spectra",
9494
units="1",
9595
),
96+
"skewness": MetaData(
97+
long_name="Skewness of spectra",
98+
units="1",
99+
),
96100
"nyquist_velocity": MetaData(long_name="Nyquist velocity", units="m s-1"),
97101
"radar_frequency": MetaData(long_name="Radar transmit frequency", units="GHz"),
98102
"beta": MetaData(
@@ -190,4 +194,8 @@ class MetaData(NamedTuple):
190194
units="dB",
191195
comment="SNR threshold used in data screening.",
192196
),
197+
"chirp_start_indices": MetaData(
198+
long_name="Chirp sequences start indices",
199+
units="1",
200+
),
193201
}

cloudnetpy/output.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ def _get_netcdf_dimensions(obj) -> dict:
5858
# RPG cloud radar
5959
if "chirp_start_indices" in obj.data:
6060
dimensions["chirp_sequence"] = len(obj.data["chirp_start_indices"][:])
61+
# Bowtie
62+
if "range_offsets" in obj.data:
63+
dimensions["chirp_sequence"] = len(obj.data["range_offsets"][:])
6164
# disdrometer
6265
if hasattr(obj, "n_diameter") and hasattr(obj, "n_velocity"):
6366
dimensions["diameter"] = obj.n_diameter

0 commit comments

Comments
 (0)