#!/opt/local/opkg/bin/python
"""
metranet library
================
functions to read METRANET files, require external shared library
srn_idl_py_lib.<ARCH>.so
.. autosummary::
:toctree: generated/
get_radar_site_info
get_library_path
get_library
read_polar
read_product
read_file
.. autosummary::
:toctree: generated/
:template: dev_template.rst
RadarData
Header_struPM
Header_struMS
Selex_Angle
"""
from __future__ import print_function
import ctypes
import os
import sys
import platform
import string
import time
from warnings import warn
import traceback
import numpy as np
from .dn_to_float import float_mapping, nyquist_vel
# some values valid for all sites
NPM_MOM = 11
NPH_MOM = 12
NPL_MOM = 9
# fix for python3
if sys.version_info[0] == 3:
def xrange(i):
return range(i)
class RadarData:
"""
A class for storing radar data.
Attributes
----------
type : str
type of data
data : numpy array or numpy masked array
array containing the data
scale : numpy array
array containing the scale used to transform the data from digital
to physical units
header : dict
dictionary containing metadata
pol_header : dict
dictionary containing metadata of the polar files
moment : str
moment name
"""
type = "RadarData"
def __init__(self, data=np.zeros(0),
scale=np.fromiter(xrange(256), dtype=np.uint), header=(),
pol_header=(), moment='ZH'):
self.data = data
self.scale = scale
self.header = header
self.pol_header = pol_header
self.moment = moment
class Header_struPM(ctypes.Structure):
"""
A class containing the data from the header of the polar PM files
Attributes
----------
_fields_: dict
A dictionary containing the metadata contained in the PM file
C-Structure of METRANET POLAR data PM format
struct moment_header_struct
{
unsigned int record_type; data format (moment1) + moment mask
unsigned int scan_id;
unsigned int host_id;
unsigned int start_angle;
unsigned int end_angle;
unsigned char ant_mode;
unsigned char total_sweep;
unsigned char current_sweep; 1-any number up to 99
unsigned char end_of_sweep; 0=not end, 1=end sweep, 2=end volume
short sequence; ray sequence number in a sweep
short total_record; total ray number in sweep
short pulses;
short num_gates;
int data_bytes;
unsigned short data_flag;
short data_time_residue; data time residue in 0.01 sec
unsigned int data_time; data time in second
short repeat_time;
char compressed; flag for compression of data
char priority; for file name use
float ny_quest;
float gate_width;
float w_ny_quest; may be used for other variable
float start_range;
};
"""
_fields_ = [
("record_type", ctypes.c_uint),
("scan_id", ctypes.c_int),
("host_id", ctypes.c_int),
("start_angle", ctypes.c_int),
("end_angle", ctypes.c_int),
("ant_mode", ctypes.c_ubyte),
("total_sweep", ctypes.c_ubyte),
("current_sweep", ctypes.c_ubyte),
("end_of_sweep", ctypes.c_ubyte),
("sequence", ctypes.c_short),
("total_record", ctypes.c_short),
("pulses", ctypes.c_short),
("num_gates", ctypes.c_short),
("data_bytes", ctypes.c_int),
("data_flag", ctypes.c_ushort),
("data_time_residue", ctypes.c_short),
("data_time", ctypes.c_uint),
("repeat_time", ctypes.c_short),
("compressed", ctypes.c_ubyte),
("priority", ctypes.c_ubyte),
("ny_quest", ctypes.c_float),
("gate_width", ctypes.c_float),
("w_ny_quest", ctypes.c_float),
("start_range", ctypes.c_float),
]
class Header_struMS(ctypes.Structure):
"""
A class containing the data from the header of the polar MS files
Attributes
----------
_fields_: dict
A dictionary containing the metadata contained in the MS file
C-Structure of METRANET POLAR data MS format
C-code from METRANET2/share/include/sweep_file.h
struct sweep_header
{
int8_t FileId[4]; //4:4
uint8_t Version; //1:5
uint8_t Spare1[3]; //3:8
uint32_t Length; //4:12
int8_t RadarName[16]; //16:28
int8_t ScanName[16]; //16:44
float RadarLat; //4:48
float RadarLon; //4:52
float RadarHeight; //4:56
uint8_t SequenceSweep; //1:57
uint8_t CurrentSweep; //1:58
uint8_t TotalSweep; //1:59
uint8_t AntMode; //1:60
uint8_t Priority; //1:61
uint8_t Quality; //1:62
uint8_t Spare2[2]; //2:64
uint16_t RepeatTime; //2:66
uint16_t NumMoments; //2:68
float GateWidth; //4:72
float WaveLength; //4:76
float PulseWidth; //4:80
float StartRange; //4:84
uint32_t MetaDataSize; //4:88
};
"""
_fields_ = [
("FileId", ctypes.c_int32),
("Version", ctypes.c_uint8),
("Spare1", ctypes.c_uint8*3),
("Length", ctypes.c_uint32),
("RadarName", ctypes.c_int8*16),
("ScanName", ctypes.c_int8*16),
("RadarLat", ctypes.c_float),
("RadarLon", ctypes.c_float),
("RadarHeight", ctypes.c_float),
("SequenceSweep", ctypes.c_uint8),
("CurrentSweep", ctypes.c_uint8),
("TotalSweep", ctypes.c_uint8),
("AntMode", ctypes.c_uint8),
("Priority", ctypes.c_uint8),
("Quality", ctypes.c_uint8),
("Spare2", ctypes.c_uint8*2),
("RepeatTime", ctypes.c_uint16),
("NumMoments", ctypes.c_uint16),
("GateWidth", ctypes.c_float),
("WaveLength", ctypes.c_float),
("PulseWidth", ctypes.c_float),
("StartRange", ctypes.c_float),
("MetaDataSize", ctypes.c_uint32),
]
class Selex_Angle:
"""
Class used to convert from digital number to angle
Attributes
----------
az : float
azimuth angle value (degrees or radiants)
el : float
elevation angle value (degrees or radiants)
"""
def __init__(self, angle=0, radiant=False):
if radiant:
reform = 2 * 3.1415926
else:
reform = 360.
self.az = (angle & 0xFFFF)/65535.*reform
self.el = (angle >> 16)/65535.*reform
def get_radar_site_info(verbose=False):
"""
return dictionary with radar'info
Returns
-------
radar_def : dict
dictionary containing radar site information
"""
radar_def_load = False
try:
import yaml
yaml_module = True
except ImportError:
yaml_module = False
if yaml_module:
metranet_yaml_file = "metranet.yaml"
path_yaml_file = [
"/store/msrad/python/library/radar/io/", "/opt/ccs4/python",
"/proj/lom/python/library/radar/io"]
for p in path_yaml_file:
full_file = p + "/" + metranet_yaml_file
if os.path.isfile(full_file):
print("look for Radar_Site_info from %s" % full_file)
try:
with open(full_file) as f:
radar_def = yaml.load(f)
radar_def_load = True
if verbose:
print("Read Radar_Site_info from %s" % full_file)
except OSError as ee:
warn(str(ee))
traceback.print_exc()
if not radar_def_load:
# HardCoded definition
print("**** HARD-CODED Radar site Value, may be not updated!!")
# some values valid for all sites
c_speed = 299792458 # m/s
radar_default = {}
radar_default['dwhname'] = 'undef'
radar_default['RadarCHY'] = float('nan')
radar_default['RadarCHX'] = float('nan')
radar_default['FileId'] = 1179665477
radar_default['Version'] = 0
radar_default['RadarName'] = "undef"
radar_default['ScanName'] = "undef"
radar_default['RadarLat'] = float('nan')
radar_default['RadarLon'] = float('nan')
radar_default['RadarHeight'] = float('nan')
radar_default['Frequency'] = float('nan')
radar_default['WaveLength'] = float('nan')
radar_default['PulseWidth'] = 0.5
radar_default['SweepsOrder'] = (
9, 7, 5, 3, 1, 19, 17, 15, 13, 11, 10, 8, 6, 4, 2, 20, 18, 16, 14,
12)
radar_default['NumMomentsPM'] = NPM_MOM
radar_default['NumMomentsPH'] = NPH_MOM
radar_default['NumMomentsPL'] = NPL_MOM
radar_def = {}
rname = 'A'
radar_def[rname] = radar_default.copy()
radar_def[rname]['dwhname'] = "ALB"
radar_def[rname]['RadarName'] = "Albis"
radar_def[rname]['RadarCHY'] = 681201
radar_def[rname]['RadarCHX'] = 237604
radar_def[rname]['RadarLat'] = 47.284333
radar_def[rname]['RadarLon'] = 8.512000
radar_def[rname]['RadarHeight'] = 938.0
radar_def[rname]['ScanName'] = "1095516672"
radar_def[rname]['Frequency'] = 5450e6
radar_def[rname]['WaveLength'] = (
c_speed/radar_def[rname]['Frequency']*1e2)
rname = 'D'
radar_def[rname] = radar_default.copy()
radar_def[rname]['dwhname'] = "DOL"
radar_def[rname]['RadarName'] = "Dole"
radar_def[rname]['RadarCHY'] = 497057
radar_def[rname]['RadarCHX'] = 142408
radar_def[rname]['RadarLat'] = 46.425113
radar_def[rname]['RadarLon'] = 6.099415
radar_def[rname]['RadarHeight'] = 1682.0
radar_def[rname]['ScanName'] = "1146047488"
radar_def[rname]['Frequency'] = 5430e6
radar_def[rname]['WaveLength'] = (
c_speed/radar_def[rname]['Frequency']*1e2)
rname = 'L'
radar_def[rname] = radar_default.copy()
radar_def[rname]['dwhname'] = "MLE"
radar_def[rname]['RadarName'] = "Lema"
radar_def[rname]['RadarCHY'] = 707957
radar_def[rname]['RadarCHX'] = 99762
radar_def[rname]['RadarLat'] = 46.040761
radar_def[rname]['RadarLon'] = 8.833217
radar_def[rname]['RadarHeight'] = 1626.0
radar_def[rname]['ScanName'] = "1279610112"
radar_def[rname]['Frequency'] = 5455e6
radar_def[rname]['WaveLength'] = (
c_speed/radar_def[rname]['Frequency']*1e2)
rname = 'P'
radar_def[rname] = radar_default.copy()
radar_def[rname]['dwhname'] = "PPM"
radar_def[rname]['RadarName'] = "PlaineMorte"
radar_def[rname]['RadarCHY'] = 603687
radar_def[rname]['RadarCHX'] = 135476
radar_def[rname]['RadarLat'] = 46.370646
radar_def[rname]['RadarLon'] = 7.486552
radar_def[rname]['RadarHeight'] = 2937.0
radar_def[rname]['ScanName'] = "0"
radar_def[rname]['Frequency'] = 5468e6
radar_def[rname]['WaveLength'] = (
c_speed/radar_def[rname]['Frequency']*1e2)
rname = 'W'
radar_def[rname] = radar_default.copy()
radar_def[rname]['dwhname'] = "WEI"
radar_def[rname]['RadarName'] = "WeissFluhGipfel"
radar_def[rname]['RadarCHY'] = 779700
radar_def[rname]['RadarCHX'] = 189790
radar_def[rname]['RadarLat'] = 47.284333
radar_def[rname]['RadarLon'] = 9.794458
radar_def[rname]['RadarHeight'] = 2850.0
radar_def[rname]['ScanName'] = "0"
radar_def[rname]['Frequency'] = 5433e6
radar_def[rname]['WaveLength'] = (
c_speed/radar_def[rname]['Frequency']*1e2)
return radar_def
def get_library_path():
"""
look for valid library path
Returns
-------
library_metranet_path : str
METRANET library path
"""
libray_paths = [
os.environ.get('METRANETLIB_PATH'),
"/store/msrad/idl/lib/radlib4", "/opt/ccs4/lib",
"/opt/local/opkg/share/ccs4/lib",
"/proj/lom/idl/lib/radlib4"]
library_metranet_path = ''
for p in libray_paths:
if p is not None:
if os.path.isdir(p):
library_metranet_path = p
break
if not library_metranet_path:
sys.exit(" ENV Variable library_metranet_path NOT defined")
return library_metranet_path
[docs]def get_library(verbose=False, momentms=True):
"""
return the link to C-shared library
Parameters
----------
verbose : Boolean
If true print out extra information
momentsms : Boolean
If true returns the link to the MS library
Returns
-------
metranet_lib : link
loaded METRANET C-library
"""
# default path
try:
library_metranet_path = get_library_path()
except SystemExit:
sys.exit('ERROR: METRANET library path not found')
# library system
library_metranet_linux = 'srn_idl_py_lib.x86_64'
library_metranet_sparc32 = 'srn_idl_py_lib.sparc32.so'
# library_metranet_sparc64 = 'srn_idl_py_lib.sparc64.so'
library_metranet = 'x'
if platform.system() == 'SunOS':
if platform.architecture()[0] == '64bit':
library_metranet = library_metranet_sparc32
else:
library_metranet = library_metranet_sparc32
if platform.system() == 'Linux':
if momentms:
library_metranet = library_metranet_linux + '.MS.so'
else:
library_metranet = library_metranet_linux + '.so'
if verbose:
print("library %s/%s:" % (library_metranet_path, library_metranet))
if library_metranet == 'x':
sys.exit("ERROR: Platform not found")
metranet_lib = ctypes.cdll.LoadLibrary(
library_metranet_path + '/' + library_metranet)
return metranet_lib
def read_polar(radar_file, moment="ZH", physic_value=False,
masked_array=False, verbose=False):
"""
Reads a METRANET polar data file
Parameters
----------
radar_file : str
file name
moment : str
moment name
physic_value : boolean
If true returns the physical value. Otherwise the digital value
masked_array : boolean
If true returns a numpy masked array with NaN values masked. Otherwise
returns a regular masked array with NaN values
verbose : boolean
If true prints out extra information
Returns
-------
ret_data : RadarData object
An object containing the information read from the file. None if
the file has not been properly read
"""
c_speed = 299792458 # m/s
ret_data = RadarData(moment=moment)
prd_header = {}
prd_data_level = ret_data.scale
# uppercase moment
moment = moment.upper()
# as big as possible
max_bins = 3000
max_azimuths = 500
if verbose:
print("Read POLAR file %s " % radar_file)
# read BINARY data
prdt_size = max_bins * max_azimuths
if moment == 'PHI':
prdt_size *= 2
prd_data = np.zeros(prdt_size, np.ushort)
else:
prd_data = np.zeros(prdt_size, np.ubyte)
bfile = os.path.basename(radar_file)
if (bfile.startswith('MS') or bfile.startswith('MH') or
bfile.startswith('ML')):
momentms = True
Header_stru = Header_struPM
else:
momentms = False
Header_stru = Header_struPM
t_pol_header = (Header_stru * max_azimuths)()
t_rad_header = (Header_struMS * 1)()
metranet_lib = get_library(momentms=momentms, verbose=verbose)
ret = metranet_lib.py_decoder_p2(
ctypes.c_char_p(radar_file.encode('utf-8')),
np.ctypeslib.as_ctypes(prd_data), ctypes.c_int(prdt_size),
ctypes.c_char_p(moment.encode('utf-8')), ctypes.byref(t_pol_header),
ctypes.byref(t_rad_header), ctypes.c_int(verbose))
if ret <= max_azimuths:
return None
if moment == 'PHI':
ret *= 0.5
# reshape matrix data
bins = t_pol_header[0].num_gates
nr_az = int(ret / bins)
if bins < 1:
# if num_gates is less than 1 (exception)
bins = ret/360
if nr_az > 360:
nr_az = 360
if nr_az < 360:
print("WARNING incomplete sweep")
if verbose:
print("ret=%d" % ret)
print("bins=%d" % bins)
print("nr_az=%d" % nr_az)
print("len(prd_data)=%d" % len(prd_data))
prd_data = prd_data[0: nr_az * bins]
prd_data = np.reshape(prd_data, (nr_az, bins))
# reorder pol_header
pol_header = (Header_stru * nr_az)()
for i in range(0, nr_az):
angle_start = Selex_Angle(t_pol_header[i].start_angle)
pol_header[int(angle_start.az)] = t_pol_header[i]
# Select scale
prd_data_level = float_mapping(moment, pol_header[0].data_time,
pol_header[0].scan_id,
pol_header[0].ny_quest)
if verbose:
print("prd_data shape ", prd_data.shape)
print("min/max prd_data: ", prd_data.min(), prd_data.max())
set(string.printable)
print("prd_data scan_id ", pol_header[0].scan_id)
print("prd_data host_id ", pol_header[0].host_id)
print("data level ", prd_data_level[0:10])
for i in range(0, nr_az, 10):
angle_start = Selex_Angle(pol_header[i].start_angle)
angle_end = Selex_Angle(pol_header[i].end_angle)
x = pol_header[i].num_gates / 2
print(("pol_header[%3d].num_gates: %d, time %d.%03d start_az/el:"
" %6.1f/%4.1f end_az/el: %6.1f/%4.1f real[%d]=%6.2f"
" ( raw=%5d)") %
(i, pol_header[i].num_gates, pol_header[i].data_time,
pol_header[i].data_time_residue, angle_start.az,
angle_start.el, angle_end.az, angle_end.el, x,
prd_data_level[prd_data[i, x]], prd_data[i, x]))
if physic_value:
ret_data.data = prd_data_level[prd_data]
if masked_array:
ret_data.data = np.ma.array(
ret_data.data, mask=np.isnan(ret_data.data))
if bfile[1] == 'L':
if moment in ('ZH', 'ZV', 'ZHC', 'ZVC'):
prd_data_level[1] = np.nan
ret_data.data = np.ma.masked_where(
prd_data == 1, ret_data.data)
else:
ret_data.data = prd_data
if masked_array:
ret_data.data = np.ma.array(
ret_data.data, mask=prd_data == 0)
if bfile[1] == 'L':
if moment in ('ZH', 'ZV', 'ZHC', 'ZVC'):
prd_data_level[1] = np.nan
ret_data.data = np.ma.masked_where(
prd_data == 1, ret_data.data)
# header
prd_header['pid'] = bfile[0:3]
prd_header['radar'] = bfile[2]
prd_header['moment'] = moment
prd_header['column'] = bins
prd_header['row'] = nr_az
# prd_header['elevation'] = "%03d" % pol_header[0].current_sweep
prd_header['volume_time'] = int(
pol_header[0].data_time - pol_header[0].data_time % 300 + 300)
prd_header['time'] = time.strftime(
'%y%j%H%M', time.gmtime(int(prd_header['volume_time'])))
prd_header["quality"] = bfile[12]
# if exists extended header, fill header
if t_rad_header[0].FileId > 0 and t_rad_header[0].GateWidth > 0.:
prd_header["FileId"] = t_rad_header[0].FileId
prd_header["Version"] = t_rad_header[0].Version
# prd_header["Spare1"] = t_rad_header[0].Spare1
# prd_header["Length"] = t_rad_header[0].Length
prd_header["RadarName"] = ctypes.string_at(
t_rad_header[0].RadarName)
prd_header["ScanName"] = ctypes.string_at(t_rad_header[0].ScanName)
prd_header["RadarLat"] = t_rad_header[0].RadarLat
prd_header["RadarLon"] = t_rad_header[0].RadarLon
prd_header["RadarHeight"] = t_rad_header[0].RadarHeight
prd_header["SequenceSweep"] = t_rad_header[0].SequenceSweep
prd_header["CurrentSweep"] = t_rad_header[0].CurrentSweep
prd_header["TotalSweep"] = t_rad_header[0].TotalSweep
prd_header["AntMode"] = t_rad_header[0].AntMode
prd_header["Priority"] = t_rad_header[0].Priority
# prd_header["Quality"] = t_rad_header[0].Quality
prd_header["quality"] = t_rad_header[0].Quality
# prd_header["Spare2"] = t_rad_header[0].Spare2
prd_header["RepeatTime"] = t_rad_header[0].RepeatTime
prd_header["NumMoments"] = t_rad_header[0].NumMoments
prd_header["GateWidth"] = t_rad_header[0].GateWidth
prd_header["WaveLength"] = t_rad_header[0].WaveLength
prd_header["Frequency"] = c_speed/(prd_header["WaveLength"]*1e-2)
prd_header["PulseWidth"] = t_rad_header[0].PulseWidth
prd_header["StartRange"] = t_rad_header[0].StartRange
prd_header["MetaDataSize"] = t_rad_header[0].MetaDataSize
# update with radar sweep radar
prd_header['radar'] = prd_header["RadarName"][0]
else:
# specific radar metadata not available (old PM/PH/PL format)
# from polar header
prd_header["CurrentSweep"] = pol_header[0].current_sweep
prd_header["TotalSweep"] = pol_header[0].total_sweep
prd_header["AntMode"] = pol_header[0].ant_mode
prd_header["RepeatTime"] = pol_header[0].repeat_time
prd_header["GateWidth"] = pol_header[0].gate_width
prd_header["StartRange"] = pol_header[0].start_range
prd_header["Priority"] = pol_header[0].priority
# from hard-coded table
rname = prd_header['radar']
radar_def = get_radar_site_info()
if rname in radar_def.keys():
prd_header["FileId"] = radar_def[rname]["FileId"]
prd_header["Version"] = radar_def[rname]["Version"]
prd_header["RadarName"] = radar_def[rname]["RadarName"]
prd_header["ScanName"] = radar_def[rname]["ScanName"]
prd_header["RadarLat"] = radar_def[rname]["RadarLat"]
prd_header["RadarLon"] = radar_def[rname]["RadarLon"]
prd_header["RadarHeight"] = radar_def[rname]["RadarHeight"]
prd_header["Frequency"] = radar_def[rname]["Frequency"]
prd_header["WaveLength"] = radar_def[rname]["WaveLength"]
prd_header["PulseWidth"] = radar_def[rname]["PulseWidth"]
prd_header["SequenceSweep"] = (
radar_def[rname]['SweepsOrder'].index(
pol_header[0].current_sweep))
if bfile[1] == 'M':
prd_header["NumMoments"] = radar_def[rname]['NumMomentsPM']
if bfile[1] == 'H':
prd_header["NumMoments"] = radar_def[rname]['NumMomentsPH']
if bfile[1] == 'L':
prd_header["NumMoments"] = radar_def[rname]['NumMomentsPL']
ret_data.header = prd_header
ret_data.scale = prd_data_level
ret_data.pol_header = pol_header
# change parameters in header
for i in range(nr_az):
ret_data.pol_header[i].total_record = nr_az
return ret_data
def read_product(radar_file, physic_value=False, masked_array=False,
verbose=False):
"""
Reads a METRANET cartesian data file
Parameters
----------
radar_file : str
file name
physic_value : boolean
If true returns the physical value. Otherwise the digital value
masked_array : boolean
If true returns a numpy masked array with NaN values masked. Otherwise
returns a regular masked array with NaN values
verbose : boolean
If true prints out extra information
Returns
-------
ret_data : RadarData object
An object containing the information read from the file. None if
the file has not been properly read
"""
ret_data = RadarData()
prd_header = {'row': 0, 'column': 0}
# read ASCII data
if verbose:
print("physic_value: ", physic_value)
print("File %s: read ASCII" % radar_file)
try:
with open(radar_file, 'rb') as data_file:
lines = data_file.readlines()
except OSError as ee:
warn(str(ee))
print("Unable to read file '%s'" % radar_file)
return None
for t_line in lines:
line = t_line.decode("utf-8").strip('\n')
if line.find('end_header') == -1:
data = line.split('=')
prd_header[data[0]] = data[1]
else:
break
# read BINARY data
prdt_size = int(prd_header['column']) * int(prd_header['row'])
if prdt_size < 1:
print("Error, no size found row=%3d column=%3d" %
(prd_header['row'], prd_header['column']))
return None
if verbose:
print("File %s: read BINARY data: expected %s bytes, " %
(radar_file, prdt_size), end='')
prd_data = np.zeros(
[int(prd_header['row']), int(prd_header['column'])], np.ubyte)
prd_data_level = np.zeros(256, np.float32)
metranet_lib = get_library(verbose=verbose)
ret = metranet_lib.py_decoder(
ctypes.c_char_p(radar_file.encode('utf-8')),
np.ctypeslib.as_ctypes(prd_data), ctypes.c_int(prdt_size),
np.ctypeslib.as_ctypes(prd_data_level), ctypes.c_int(verbose))
# convert 0 at end of array with NAN
conv_zero2nan = True
i = len(prd_data_level)
if prd_data_level.max() == prd_data_level.min():
prd_data_level = np.fromiter(xrange(256), dtype=np.uint32)
else:
while conv_zero2nan:
i -= 1
if i < 0:
conv_zero2nan = False
elif prd_data_level[i] == 0.0:
prd_data_level[i] = np.nan
else:
conv_zero2nan = False
if verbose:
print("Found %d bytes" % ret)
print("prd_data_level[10] = %f" % prd_data_level[10])
print("min/max prd_data: %d/%d" % (prd_data.min(), prd_data.max()))
print("first 100 bytes", prd_data[0:100, 0])
print("data level ", prd_data_level[0:10])
# ret_data = RadarData(
# data=prd_data, header=prd_header, scale=prd_data_level)
if physic_value:
ret_data.data = prd_data_level[prd_data]
if masked_array:
ret_data.data = np.ma.array(
ret_data.data, mask=np.isnan(ret_data.data))
ret_data.data = np.ma.masked_where(prd_data == 0, ret_data.data)
else:
ret_data.data = prd_data
if masked_array:
ret_data.data = np.ma.array(
ret_data.data, mask=prd_data == 0)
ret_data.header = prd_header
ret_data.scale = prd_data_level
return ret_data
def read_file(file, moment="ZH", physic_value=False, masked_array=False,
verbose=False):
"""
Reads a METRANET data file
Parameters
----------
file : str
file name
moment : str
moment name
physic_value : boolean
If true returns the physical value. Otherwise the digital value
masked_array : boolean
If true returns a numpy masked array with NaN values masked. Otherwise
returns a regular masked array with NaN values
verbose : boolean
If true prints out extra information
Returns
-------
ret_data : RadarData object
An object containing the information read from the file
"""
bfile = os.path.basename(file)
if (bfile.startswith('PM') or bfile.startswith('PH') or
bfile.startswith('PL') or bfile.startswith('MS') or
bfile.startswith('MH') or bfile.startswith('ML')):
# polar data from SITE (PH/PM/PL)
if verbose:
print("calling read_polar")
ret = read_polar(
file, moment=moment, physic_value=physic_value,
masked_array=masked_array, verbose=verbose)
else:
# cartesian / CCS4 products
if verbose:
print("calling read_product")
ret = read_product(
file, physic_value=physic_value, masked_array=masked_array,
verbose=verbose)
return ret