Пример #1
0
    def merge(cls, files: List[str], output: str):
        r"""
        Merge single-tilt standard data into a volumetric scan

        Args:
            files (List[str]): List of path of data to be merged

            output (str): The file path to store the merged data
        """
        with prepare_file(files[0]) as first_file:
            first_file.seek(160)
            task = np.frombuffer(first_file.read(256), SDD_task)
            cut_num = task["cut_number"][0]
            total_seek_bytes = first_file.tell() + 256 * cut_num
            all_tilt_data = [b""] * cut_num
            first_file.seek(0)
            header_bytes = first_file.read(total_seek_bytes)
            rad = np.frombuffer(first_file.read(64), SDD_rad_header)
            el_num = rad["elevation_number"][0] - 1
            first_file.seek(total_seek_bytes)
            all_tilt_data[el_num] = first_file.read()
            for f in files[1:]:
                with prepare_file(f) as buf:
                    buf.seek(total_seek_bytes)
                    rad = np.frombuffer(buf.read(64), SDD_rad_header)
                    buf.seek(total_seek_bytes)
                    el_num = rad["elevation_number"][0] - 1
                    all_tilt_data[el_num] = buf.read()
        with open(output, "wb") as out:
            out.write(header_bytes)
            out.write(b"".join(all_tilt_data))
Пример #2
0
 def __init__(self, file: Any, radar_type: Optional[str] = None, file_name: Optional[str] = None):
     r'''
     Parameters
     ----------
     file: str / obj with read method
         path directed to the file to read / file object
     radar_type: str, optional
         type of radar
     '''
     f = prepare_file(file)
     filename = Path(file).name if isinstance(file, str) else ''
     self.code, radartype = _detect_radartype(f, filename, type_assert=radar_type)
     if radar_type:
         if radartype is not radar_type:
             warnings.warn('Contradictory information from input radar type and\
                           radar type detected from input file.')
         self.radartype = radar_type
     else:
         self.radartype = radartype
     f.seek(0)
     if radartype in ['SA', 'SB']:
         self._SAB_handler(f)
     elif radartype in ['CA', 'CB']:
         self._SAB_handler(f, SAB=False)
     elif radartype is 'CC':
         self._CC_handler(f)
     elif radartype in ['SC', 'CD']:
         self._CD_handler(f)
     else:
         raise RadarDecodeError('Unrecognized data')
     self._update_radar_info()
     f.close()
Пример #3
0
 def __init__(
     self,
     file: Any,
     radar_type: Optional[str] = None,
     file_name: Optional[str] = None,
 ):
     f = prepare_file(file)
     filename = Path(file).name if isinstance(file, str) else ""
     self.code, t_infer = infer_type(f, filename)
     if radar_type:
         if t_infer != radar_type:
             warnings.warn(
                 "Contradictory information from input radar type and"
                 "radar type detected from input file.")
         self.radartype = radar_type
     else:
         if not t_infer:
             raise RadarDecodeError(
                 "Unable to determine the file type. Use `radar_type` keyword"
                 "to specify the radar type.")
         self.radartype = t_infer
     self.site_info = {}
     f.seek(0)
     if self.radartype in ["SA", "SB"]:
         self._SAB_handler(f)
     elif self.radartype in ["CA", "CB"]:
         self._SAB_handler(f, dtype="CAB")
     elif self.radartype == "CC2":
         self._CC2_handler(f)
     else:
         try:
             if self.radartype == "CC":
                 self._CC_handler(f)
             elif self.radartype in ["SC", "CD"]:
                 self._CD_handler(f)
             else:
                 raise RadarDecodeError("Unrecognized data")
         except Exception as err:
             # Currently there's no good way to differentiate the special
             # SC/CC files, so catch the exception of normal decoding process
             # and try this one if possible
             try:
                 f.seek(0)
                 self._SAB_handler(f, dtype="special")
             except:
                 raise err
     self._update_radar_info()
     # TODO: Override information
     if "longitude" in self.site_info:
         self.stationlon = self.site_info["longitude"]
     if "latitude" in self.site_info:
         self.stationlat = self.site_info["latitude"]
     if "height" in self.site_info:
         self.radarheight = self.site_info["height"]
     if "name" in self.site_info:
         self.name = self.site_info["name"]
     if self.code == None and self.name:
         # Use name as code when code is missing
         self.code = self.name
     f.close()
Пример #4
0
 def __init__(self, file:Any):
     f = prepare_file(file)
     header = np.frombuffer(f.read(1024), SWAN_dtype)
     xdim, ydim, zdim = header['x_grid_num'][0], header['y_grid_num'][0], header['z_grid_num'][0]
     dtype = header['m_data_type'][0]
     data_size = int(xdim) * int(ydim) * int(zdim) * self.size_conv[dtype]
     bittype = self.dtype_conv[dtype]
     data_body = np.frombuffer(f.read(data_size), bittype).astype(int)
     if zdim == 1:
         out = data_body.reshape(xdim, ydim)
     else:
         out = data_body.reshape(zdim, xdim, ydim)
     self.data_time = datetime.datetime(header['year'], header['month'], header['day'], header['hour'], header['minute'])
     # TODO: Recognize correct product name
     self.product_name = b''.join(header['data_name'][0, :4]).decode()
     start_lon = header['start_lon'][0]
     start_lat = header['start_lat'][0]
     center_lon = header['center_lon'][0]
     center_lat = header['center_lat'][0]
     end_lon = center_lon * 2 - start_lon
     end_lat = center_lat * 2 - start_lat
     #x_reso = header['x_reso'][0]
     #y_reso = header['y_reso'][0]
     self.lon = np.linspace(start_lon, end_lon, xdim) # For shape compatibility
     self.lat = np.linspace(start_lat, end_lat, ydim)
     if self.product_name == 'CR':
         self.data = np.ma.array((out - 66) / 2, mask=(out==0))
     else:
         self.data = np.ma.array(out, mask=(out==0))
Пример #5
0
 def __init__(self, file):
     self.f = prepare_file(file)
     self._parse()
     self._update_radar_info()
     self.stationlat = self.geo["lat"][0]
     self.stationlon = self.geo["lon"][0]
     self.radarheight = self.geo["height"][0]
     if self.name == "None":
         self.name = self.code
     del self.geo
     self.f.close()
Пример #6
0
 def __init__(self, file):
     self.f = prepare_file(file)
     self._parse()
     self._update_radar_info()
     self.stationlat = self.geo['lat'][0]
     self.stationlon = self.geo['lon'][0]
     self.radarheight = self.geo['height'][0]
     if self.name == 'None':
         self.name = self.code
     del self.geo
     self.f.close()
Пример #7
0
 def __init__(
     self,
     file: Any,
     radar_type: Optional[str] = None,
     file_name: Optional[str] = None,
 ):
     r"""
     Parameters
     ----------
     file: str / obj with read method
         path directed to the file to read / file object
     radar_type: str, optional
         type of radar
     """
     f = prepare_file(file)
     filename = Path(file).name if isinstance(file, str) else ""
     self.code, radartype = _detect_radartype(f,
                                              filename,
                                              type_assert=radar_type)
     if radar_type:
         if radartype is not radar_type:
             warnings.warn(
                 "Contradictory information from input radar type and\
                           radar type detected from input file.")
         self.radartype = radar_type
     else:
         self.radartype = radartype
     f.seek(0)
     if radartype in ["SA", "SB"]:
         self._SAB_handler(f)
     elif radartype in ["CA", "CB"]:
         self._SAB_handler(f, dtype="CAB")
     else:
         try:
             if radartype == "CC":
                 self._CC_handler(f)
             elif radartype in ["SC", "CD"]:
                 self._CD_handler(f)
             else:
                 raise RadarDecodeError("Unrecognized data")
         except Exception as err:
             # Currently there's no good way to differentiate the special
             # SC/CC files, so catch the exception of normal decoding process
             # and try this one if possible
             try:
                 f.seek(0)
                 self._SAB_handler(f, dtype="special")
             except:
                 raise err
     self._update_radar_info()
     f.close()
Пример #8
0
 def __init__(self, file: Any):
     with prepare_file(file) as self.f:
         self._parse()
     self._update_radar_info()
     # In standard data, station information stored in file
     # has higher priority, so we override some information.
     self.stationlat = self.geo["lat"]
     self.stationlon = self.geo["lon"]
     self.radarheight = self.geo["height"]
     if self.name == "None":
         # Last resort to find info
         self.name = self.geo["name"]
     self.angleindex_r = self.available_tilt("REF")  # API consistency
     del self.geo
Пример #9
0
 def __init__(self, file: Any, product: Optional[str] = None):
     f = prepare_file(file)
     header = np.frombuffer(f.read(1024), SWAN_dtype)
     xdim, ydim, zdim = (
         header["x_grid_num"][0],
         header["y_grid_num"][0],
         header["z_grid_num"][0],
     )
     dtype = header["m_data_type"][0]
     data_size = int(xdim) * int(ydim) * int(zdim) * self.size_conv[dtype]
     bittype = self.dtype_conv[dtype]
     data_body = np.frombuffer(f.read(data_size), bittype).astype(int)
     # Convert data to i4 to avoid overflow in later calculation
     if zdim == 1:
         # 2D data
         out = data_body.reshape(ydim, xdim)
     else:
         # 3D data
         out = data_body.reshape(zdim, ydim, xdim)
     self.data_time = datetime.datetime(
         header["year"][0],
         header["month"][0],
         header["day"][0],
         header["hour"][0],
         header["minute"][0],
     )
     # TODO: Recognize correct product name
     product_name = ((b"".join(header["data_name"]).decode(
         "gbk", "ignore").replace("\x00", "")) if not product else product)
     self.product_name = product_name
     for pname in ["CR", "3DREF"]:
         if product_name.startswith(pname):
             self.product_name = pname
     start_lon = header["start_lon"][0]
     start_lat = header["start_lat"][0]
     center_lon = header["center_lon"][0]
     center_lat = header["center_lat"][0]
     end_lon = center_lon * 2 - start_lon
     end_lat = center_lat * 2 - start_lat
     # x_reso = header['x_reso'][0]
     # y_reso = header['y_reso'][0]
     self.lon = np.linspace(start_lon, end_lon,
                            xdim)  # For shape compatibility
     self.lat = np.linspace(start_lat, end_lat, ydim)
     if self.product_name in ["CR", "3DREF"]:
         self.data = (np.ma.masked_equal(out, 0) - 66) / 2
     else:
         # Leave data unchanged because the scale and offset are unclear
         self.data = np.ma.masked_equal(out, 0)
Пример #10
0
 def __init__(self, file: Any):
     r'''
     Parameters
     ----------
     file: str
         path directed to the file to read
     '''
     self.f = prepare_file(file)
     self._parse()
     self.f.close()
     self._update_radar_info()
     if self.name == 'None':
         # Last resort to find info
         self.stationlat = self.geo['lat'][0]
         self.stationlon = self.geo['lon'][0]
         self.radarheight = self.geo['height'][0]
         self.name = self.code
     self.angleindex_r = self.available_tilt('REF')  # API consistency
     del self.geo
Пример #11
0
 def __init__(self, file: Any):
     r"""
     Parameters
     ----------
     file: str
         path directed to the file to read
     """
     self.f = prepare_file(file)
     self._parse()
     self.f.close()
     self._update_radar_info()
     # In standard data, station information stored in file
     # has higher priority, so we override some information.
     self.stationlat = self.geo["lat"][0]
     self.stationlon = self.geo["lon"][0]
     self.radarheight = self.geo["height"][0]
     if self.name == "None":
         # Last resort to find info
         self.name = self.code
     self.angleindex_r = self.available_tilt("REF")  # API consistency
     del self.geo
Пример #12
0
 def __init__(
     self,
     file: Any,
     radar_type: Optional[str] = None,
     file_name: Optional[str] = None,
 ):
     r"""
     Parameters
     ----------
     file: str / obj with read method
         path directed to the file to read / file object
     radar_type: str, optional
         type of radar
     """
     f = prepare_file(file)
     filename = Path(file).name if isinstance(file, str) else ""
     self.code, radartype = _detect_radartype(f,
                                              filename,
                                              type_assert=radar_type)
     if radar_type:
         if radartype is not radar_type:
             warnings.warn(
                 "Contradictory information from input radar type and\
                           radar type detected from input file.")
         self.radartype = radar_type
     else:
         self.radartype = radartype
     f.seek(0)
     if radartype in ["SA", "SB"]:
         self._SAB_handler(f)
     elif radartype in ["CA", "CB"]:
         self._SAB_handler(f, SAB=False)
     elif radartype is "CC":
         self._CC_handler(f)
     elif radartype in ["SC", "CD"]:
         self._CD_handler(f)
     else:
         raise RadarDecodeError("Unrecognized data")
     self._update_radar_info()
     f.close()
Пример #13
0
 def __init__(self, file: Any):
     f = prepare_file(file)
     header = np.frombuffer(f.read(1024), SWAN_dtype)
     xdim, ydim, zdim = header['x_grid_num'][0], header['y_grid_num'][
         0], header['z_grid_num'][0]
     dtype = header['m_data_type'][0]
     data_size = int(xdim) * int(ydim) * int(zdim) * self.size_conv[dtype]
     bittype = self.dtype_conv[dtype]
     data_body = np.frombuffer(f.read(data_size), bittype).astype(int)
     # Convert data to i4 to avoid overflow in later calculation
     if zdim == 1:
         # 2D data
         out = data_body.reshape(xdim, ydim)
     else:
         # 3D data
         out = data_body.reshape(zdim, ydim, xdim)
     self.data_time = datetime.datetime(header['year'], header['month'],
                                        header['day'], header['hour'],
                                        header['minute'])
     # TODO: Recognize correct product name
     self.product_name = b''.join(header['data_name']).decode().replace(
         '\x00', '')
     start_lon = header['start_lon'][0]
     start_lat = header['start_lat'][0]
     center_lon = header['center_lon'][0]
     center_lat = header['center_lat'][0]
     end_lon = center_lon * 2 - start_lon
     end_lat = center_lat * 2 - start_lat
     #x_reso = header['x_reso'][0]
     #y_reso = header['y_reso'][0]
     self.lon = np.linspace(start_lon, end_lon,
                            xdim)  # For shape compatibility
     self.lat = np.linspace(start_lat, end_lat, ydim)
     if self.product_name in ['CR', '3DREF']:
         self.data = (np.ma.masked_equal(out, 0) - 66) / 2
     else:
         # Leave data unchanged because the scale and offset are unclear
         self.data = np.ma.masked_equal(out, 0)
Пример #14
0
 def __init__(self, file):
     f = prepare_file(file)
     filename = Path(file).name if isinstance(file, str) else ""
     try:
         self.code = self.name = filename.split("_")[3]
     except IndexError:
         self.code = self.name = "None"
     self._d = data = np.frombuffer(f.read(), dtype=PA_radial)
     self.stationlon = data["header"]["longitude"][0] * 360 / 65535
     self.stationlat = data["header"]["latitude"][0] * 360 / 65535
     self.radarheight = data["header"]["height"][0] * 1000 / 65535
     self.scantime = datetime.datetime.utcfromtimestamp(
         data["data"]["radial_time"][0])
     self.reso = np.round(
         data["data"]["gate_length"][0] * 1000 / 65535) / 1000
     self.first_gate_dist = (
         np.round(data["data"]["first_gate_dist"][0] * 1000 / 65535) / 1000)
     el_num = data["data"]["el_num"][0]
     az_num = data["data"]["az_num"][0]
     radial_num = 2000
     el = data["data"]["elevation"].astype(int) * 360 / 65535
     self.el = el.reshape(az_num, el_num).max(axis=0)
     self.data = dict()
     self.aux = dict()
     # fmt:off
     tref = (np.ma.masked_equal(
         data["data"]["tref"].reshape(az_num, el_num, radial_num),
         255).astype(int) * 106 / 255 - 20)
     ref = (np.ma.masked_equal(
         data["data"]["ref"].reshape(az_num, el_num, radial_num),
         255).astype(int) * 106 / 255 - 20)
     vel = (np.ma.masked_equal(
         data["data"]["vel"].reshape(az_num, el_num, radial_num),
         255).astype(int) * 101 / 255 - 50)
     sw = (np.ma.masked_equal(
         data["data"]["sw"].reshape(az_num, el_num, radial_num),
         255).astype(int) * 101 / 255 - 50)
     zdr = (np.ma.masked_equal(
         data["data"]["zdr"].reshape(az_num, el_num, radial_num),
         255).astype(int) * 16 / 255 - 5)
     phi = (np.ma.masked_equal(
         data["data"]["phi"].reshape(az_num, el_num, radial_num),
         255).astype(int) * 181 / 255)
     kdp = (np.ma.masked_equal(
         data["data"]["kdp"].reshape(az_num, el_num, radial_num),
         255).astype(int) * 31 / 255 - 10)
     rho = (np.ma.masked_equal(
         data["data"]["rho"].reshape(az_num, el_num, radial_num),
         255).astype(int) * 1.1 / 255)
     # fmt:on
     az = data["data"]["azimuth"].astype(int).reshape(az_num,
                                                      el_num) * 360 / 65535
     for el_idx in range(el_num):
         self.data[el_idx] = dict()
         self.data[el_idx]["TREF"] = tref[:, el_idx, :]
         self.data[el_idx]["REF"] = ref[:, el_idx, :]
         self.data[el_idx]["VEL"] = vel[:, el_idx, :]
         self.data[el_idx]["SW"] = sw[:, el_idx, :]
         self.data[el_idx]["ZDR"] = zdr[:, el_idx, :]
         self.data[el_idx]["PHI"] = phi[:, el_idx, :]
         self.data[el_idx]["KDP"] = kdp[:, el_idx, :]
         self.data[el_idx]["RHO"] = rho[:, el_idx, :]
         self.aux[el_idx] = dict()
         self.aux[el_idx]["azimuth"] = az[:, el_idx]