|
| 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 | +} |
0 commit comments