Source code for instruments.bowtie

import datetime
from os import PathLike
from uuid import UUID

import numpy as np
from numpy import ma

from cloudnetpy import output
from cloudnetpy.constants import G_TO_KG, MM_H_TO_M_S
from cloudnetpy.exceptions import ValidTimeStampError
from cloudnetpy.instruments.instruments import FMCW94
from cloudnetpy.instruments.nc_radar import NcRadar
from cloudnetpy.instruments.rpg import RPG_ATTRIBUTES
from cloudnetpy.metadata import MetaData
from cloudnetpy.utils import bit_field_definition, get_uuid


[docs] def bowtie2nc( bowtie_file: str | PathLike, output_file: str | PathLike, site_meta: dict, uuid: str | UUID | None = None, date: str | datetime.date | None = None, ) -> UUID: """Converts 'BOW-TIE' RV-Meteor cloud radar data into Cloudnet Level 1b netCDF file. Args: bowtie_file: Input filename. output_file: Output filename. site_meta: Dictionary containing information about the site. Required key value pair is `name`. Optional are `latitude`, `longitude`, `altitude`. uuid: Set specific UUID for the file. date: Expected date as YYYY-MM-DD of all profiles in the file. Returns: UUID of the generated file. Raises: ValidTimeStampError: No valid timestamps found. """ keymap = { "Zh": "Zh", "v": "v", "width": "width", "ldr": "ldr", "kurt": "kurtosis", "Skew": "skewness", "SNR": "SNR", "time": "time", "range": "range", "lwp": "lwp", "SurfRelHum": "relative_humidity", "rain": "rainfall_rate", "Nyquist_velocity": "nyquist_velocity", "range_offsets": "chirp_start_indices", } if isinstance(date, str): date = datetime.date.fromisoformat(date) uuid = get_uuid(uuid) with Bowtie(bowtie_file, site_meta) as bowtie: bowtie.init_data(keymap) bowtie.add_time_and_range() if date is not None: bowtie.check_date(date) bowtie.add_radar_specific_variables() bowtie.add_site_geolocation() bowtie.add_height() bowtie.convert_units() bowtie.fix_chirp_start_indices() bowtie.test_if_all_masked() bowtie.add_correction_bits() attributes = output.add_time_attribute(ATTRIBUTES, bowtie.date) output.update_attributes(bowtie.data, attributes) output.save_level1b(bowtie, output_file, uuid) return uuid
class Bowtie(NcRadar): def __init__(self, full_path: str | PathLike, site_meta: dict) -> None: super().__init__(full_path, site_meta) self.instrument = FMCW94 self.date = self.get_date() def convert_units(self) -> None: self.data["lwp"].data *= G_TO_KG self.data["rainfall_rate"].data *= MM_H_TO_M_S self.data["relative_humidity"].data /= 100 def fix_chirp_start_indices(self) -> None: array = self.data["chirp_start_indices"].data self.data["chirp_start_indices"].data = np.array(array, dtype=np.int32) self.data["chirp_start_indices"].data_type = "int32" def add_correction_bits(self) -> None: bits = ma.ones(self.data["v"].data.shape, dtype=np.uint32) bits.mask = self.data["v"].data.mask self.append_data(bits, "correction_bits") def check_date(self, date: datetime.date) -> None: if self.date != date: raise ValidTimeStampError ATTRIBUTES = RPG_ATTRIBUTES | { "v": MetaData( long_name="Doppler velocity", units="m s-1", comment=( "This parameter is the radial component of the velocity, with positive\n" "velocities are away from the radar. It was corrected for the heave\n" "motion of the ship. A rolling average over 3 time steps has been\n" "applied to it." ), dimensions=("time", "range"), ), "correction_bits": MetaData( long_name="Correction bits", units="1", definition=bit_field_definition({0: """Doppler velocity is dealiased."""}), comment=( "This parameter is a bit field that indicates which corrections have\n" "been applied to radar measurements." ), dimensions=("time", "range"), ), "nyquist_velocity": MetaData( long_name="Nyquist velocity", units="m s-1", dimensions=("time", "chirp_sequence"), ), }