def read_uf(filename, field_names=None, additional_metadata=None, file_field_names=False, exclude_fields=None, delay_field_loading=False, **kwargs): """ Read a UF File. Parameters ---------- filename : str or file-like Name of Universal format file to read data from. field_names : dict, optional Dictionary mapping UF data type names to radar field names. If a data type found in the file does not appear in this dictionary or has a value of None it will not be placed in the radar.fields dictionary. A value of None, the default, will use the mapping defined in the Py-ART configuration file. additional_metadata : dict of dicts, optional Dictionary of dictionaries to retrieve metadata from during this read. This metadata is not used during any successive file reads unless explicitly included. A value of None, the default, will not introduct any addition metadata and the file specific or default metadata as specified by the Py-ART configuration file will be used. file_field_names : bool, optional True to force the use of the field names from the file in which case the `field_names` parameter is ignored. False will use to `field_names` parameter to rename fields. exclude_fields : list or None, optional List of fields to exclude from the radar object. This is applied after the `file_field_names` and `field_names` parameters. delay_field_loading : bool This option is not implemented in the function but included for compatability. Returns ------- radar : Radar Radar object. """ # test for non empty kwargs _test_arguments(kwargs) # create metadata retrieval object filemetadata = FileMetadata('uf', field_names, additional_metadata, file_field_names, exclude_fields) # Open UF file and get handle ufile = UFFile(filename) first_ray = ufile.rays[0] # time dts = ufile.get_datetimes() units = make_time_unit_str(min(dts)) time = filemetadata('time') time['units'] = units time['data'] = date2num(dts, units).astype('float32') # range _range = filemetadata('range') # assume that the number of gates and spacing from the first ray is # representative of the entire volume field_header = first_ray.field_headers[0] ngates = field_header['nbins'] start = field_header['range_start_m'] step = field_header['range_spacing_m'] # this gives distances to the start of each gate, add step/2 for center _range['data'] = np.arange(ngates, dtype='float32') * step + start _range['meters_to_center_of_first_gate'] = start _range['meters_between_gates'] = step # latitude, longitude and altitude latitude = filemetadata('latitude') longitude = filemetadata('longitude') altitude = filemetadata('altitude') lat, lon, height = first_ray.get_location() latitude['data'] = np.array([lat], dtype='float64') longitude['data'] = np.array([lon], dtype='float64') altitude['data'] = np.array([height], dtype='float64') # metadata metadata = filemetadata('metadata') metadata['original_container'] = 'UF' metadata['site_name'] = first_ray.mandatory_header['site_name'] metadata['radar_name'] = first_ray.mandatory_header['radar_name'] # sweep_start_ray_index, sweep_end_ray_index sweep_start_ray_index = filemetadata('sweep_start_ray_index') sweep_end_ray_index = filemetadata('sweep_end_ray_index') sweep_start_ray_index['data'] = ufile.first_ray_in_sweep sweep_end_ray_index['data'] = ufile.last_ray_in_sweep # sweep number sweep_number = filemetadata('sweep_number') sweep_number['data'] = np.arange(ufile.nsweeps, dtype='int32') # sweep_type scan_type = _UF_SWEEP_MODES[first_ray.mandatory_header['sweep_mode']] # sweep_mode sweep_mode = filemetadata('sweep_mode') sweep_mode['data'] = np.array(ufile.nsweeps * [_SWEEP_MODE_STR[scan_type]]) # elevation elevation = filemetadata('elevation') elevation['data'] = ufile.get_elevations() # azimuth azimuth = filemetadata('azimuth') azimuth['data'] = ufile.get_azimuths() # fixed_angle fixed_angle = filemetadata('fixed_angle') fixed_angle['data'] = ufile.get_sweep_fixed_angles() # fields fields = {} for uf_field_number, uf_field_dic in enumerate(first_ray.field_positions): uf_field_name = uf_field_dic['data_type'] field_name = filemetadata.get_field_name(uf_field_name) if field_name is None: continue field_dic = filemetadata(field_name) field_dic['data'] = ufile.get_field_data(uf_field_number) field_dic['_FillValue'] = get_fillvalue() fields[field_name] = field_dic # instrument_parameters instrument_parameters = _get_instrument_parameters(ufile, filemetadata) # scan rate scan_rate = filemetadata('scan_rate') scan_rate['data'] = ufile.get_sweep_rates() return Radar(time, _range, fields, metadata, scan_type, latitude, longitude, altitude, sweep_number, sweep_mode, fixed_angle, sweep_start_ray_index, sweep_end_ray_index, azimuth, elevation, scan_rate=scan_rate, instrument_parameters=instrument_parameters)
def read_sband_archive(filename, field_names=None, additional_metadata=None, file_field_names=False, exclude_fields=None, delay_field_loading=False, station=None, scans=None, linear_interp=True, **kwargs): """ Read a S band Archive file. Parameters ---------- filename : str Filename of S band Archive file. field_names : dict, optional Dictionary mapping S band moments to radar field names. If a data type found in the file does not appear in this dictionary or has a value of None it will not be placed in the radar.fields dictionary. A value of None, the default, will use the mapping defined in the metadata configuration file. additional_metadata : dict of dicts, optional Dictionary of dictionaries to retrieve metadata from during this read. This metadata is not used during any successive file reads unless explicitly included. A value of None, the default, will not introduct any addition metadata and the file specific or default metadata as specified by the metadata configuration file will be used. file_field_names : bool, optional True to use the S band field names for the field names. If this case the field_names parameter is ignored. The field dictionary will likely only have a 'data' key, unless the fields are defined in `additional_metadata`. exclude_fields : list or None, optional List of fields to exclude from the radar object. This is applied after the `file_field_names` and `field_names` parameters. delay_field_loading : bool, optional True to delay loading of field data from the file until the 'data' key in a particular field dictionary is accessed. In this case the field attribute of the returned Radar object will contain LazyLoadDict objects not dict objects. station : tuple or None, optional Three float tuple, include latitude, longitude and height of S band radar, first latitude, second longitude, third height (units: metre) scans : list or None, optional Read only specified scans from the file. None (the default) will read all scans. linear_interp : bool, optional True (the default) to perform linear interpolation between valid pairs of gates in low resolution rays in files mixed resolution rays. False will perform a nearest neighbor interpolation. This parameter is not used if the resolution of all rays in the file or requested sweeps is constant. Returns ------- radar : Radar Radar object containing all moments and sweeps/cuts in the volume. Gates not collected are masked in the field data. """ # test for non empty kwargs _test_arguments(kwargs) # create metadata retrieval object filemetadata = FileMetadata('nexrad_archive', field_names, additional_metadata, file_field_names, exclude_fields) # open the file and retrieve scan information nfile = SbandRadarFile(prepare_for_read(filename)) scan_info = nfile.scan_info(scans) # time time = filemetadata('time') time_start, _time = nfile.get_times(scans) time['data'] = _time time['units'] = make_time_unit_str(time_start) # range _range = filemetadata('range') first_gate, gate_spacing, last_gate = _find_range_params( scan_info, filemetadata) _range['data'] = np.arange(first_gate, last_gate, gate_spacing, 'float32') _range['meters_to_center_of_first_gate'] = float(first_gate) _range['meters_between_gates'] = float(gate_spacing) # metadata metadata = filemetadata('metadata') metadata['original_container'] = 'S band' vcp_pattern = nfile.get_vcp_pattern() if vcp_pattern is not None: metadata['vcp_pattern'] = vcp_pattern # scan_type scan_type = 'ppi' # latitude, longitude, altitude latitude = filemetadata('latitude') longitude = filemetadata('longitude') altitude = filemetadata('altitude') if station is None: lat, lon, alt = 0, 0, 0 else: lat, lon, alt = station latitude['data'] = np.array([lat], dtype='float64') longitude['data'] = np.array([lon], dtype='float64') altitude['data'] = np.array([alt], dtype='float64') # sweep_number, sweep_mode, fixed_angle, sweep_start_ray_index # sweep_end_ray_index sweep_number = filemetadata('sweep_number') sweep_mode = filemetadata('sweep_mode') sweep_start_ray_index = filemetadata('sweep_start_ray_index') sweep_end_ray_index = filemetadata('sweep_end_ray_index') if scans is None: nsweeps = int(nfile.nscans) else: nsweeps = len(scans) sweep_number['data'] = np.arange(nsweeps, dtype='int32') sweep_mode['data'] = np.array(nsweeps * ['azimuth_surveillance'], dtype='S') rays_per_scan = [s['nrays'] for s in scan_info] sweep_end_ray_index['data'] = np.cumsum(rays_per_scan, dtype='int32') - 1 rays_per_scan.insert(0, 0) sweep_start_ray_index['data'] = np.cumsum(rays_per_scan[:-1], dtype='int32') # azimuth, elevation, fixed_angle azimuth = filemetadata('azimuth') elevation = filemetadata('elevation') fixed_angle = filemetadata('fixed_angle') azimuth['data'] = nfile.get_azimuth_angles(scans) elevation['data'] = nfile.get_elevation_angles(scans).astype('float32') fixed_angle['data'] = nfile.get_target_angles(scans) # fields max_ngates = len(_range['data']) available_moments = set([m for scan in scan_info for m in scan['moments']]) interpolate = _find_scans_to_interp(scan_info, first_gate, gate_spacing, filemetadata) fields = {} for moment in available_moments: field_name = filemetadata.get_field_name(moment) if field_name is None: continue dic = filemetadata(field_name) dic['_FillValue'] = get_fillvalue() if delay_field_loading and moment not in interpolate: dic = LazyLoadDict(dic) data_call = _NEXRADLevel2StagedField(nfile, moment, max_ngates, scans) dic.set_lazy('data', data_call) else: mdata = nfile.get_data(moment, max_ngates, scans=scans) if moment in interpolate: interp_scans = interpolate[moment] warnings.warn( "Gate spacing is not constant, interpolating data in " + "scans %s for moment %s." % (interp_scans, moment), UserWarning) for scan in interp_scans: idx = scan_info[scan]['moments'].index(moment) moment_ngates = scan_info[scan]['ngates'][idx] start = sweep_start_ray_index['data'][scan] end = sweep_end_ray_index['data'][scan] _interpolate_scan(mdata, start, end, moment_ngates, linear_interp) dic['data'] = mdata fields[field_name] = dic # instrument_parameters nyquist_velocity = filemetadata('nyquist_velocity') unambiguous_range = filemetadata('unambiguous_range') nyquist_velocity['data'] = nfile.get_nyquist_vel(scans).astype('float32') unambiguous_range['data'] = ( nfile.get_unambigous_range(scans).astype('float32')) instrument_parameters = { 'unambiguous_range': unambiguous_range, 'nyquist_velocity': nyquist_velocity, } nfile.close() return Radar(time, _range, fields, metadata, scan_type, latitude, longitude, altitude, sweep_number, sweep_mode, fixed_angle, sweep_start_ray_index, sweep_end_ray_index, azimuth, elevation, instrument_parameters=instrument_parameters)
def read_sipam_cappi(filename, exclude_fields=[ "start_time", "stop_time", "time_bounds", "x0", "y0", "lat0", "lon0", "z0", "grid_mapping_0", ], include_fields=None, **kwargs): """ Read a netCDF grid file produced by Py-ART. Parameters ---------- filename : str Filename of netCDF grid file to read. This file must have been produced by :py:func:`write_grid` or have identical layout. Other Parameters ---------------- exclude_fields : list or None, optional List of fields to exclude from the radar object. This is applied after the `file_field_names` and `field_names` parameters. Set to None to include all fields specified by include_fields. include_fields : list or None, optional List of fields to include from the radar object. This is applied after the `file_field_names` and `field_names` parameters. Set to None to include all fields not specified by exclude_fields. Returns ------- grid : Grid Grid object containing gridded data. """ # test for non empty kwargs _test_arguments(kwargs) if exclude_fields is None: exclude_fields = [] reserved_variables = [ "time", "x", "y", "z", "origin_latitude", "origin_longitude", "origin_altitude", "point_x", "point_y", "point_z", "projection", "point_latitude", "point_longitude", "point_altitude", "radar_latitude", "radar_longitude", "radar_altitude", "radar_name", "radar_time", "base_time", "time_offset", "ProjectionCoordinateSystem", ] dset = netCDF4.Dataset(filename, mode="r") # metadata metadata = dict([(k, getattr(dset, k)) for k in dset.ncattrs()]) # required reserved variables time = _ncvar_to_dict(dset.variables["time"]) origin_latitude = { "data": [dset.variables["grid_mapping_0"].latitude_of_projection_origin], "long_name": "Latitude of projection origin", "units": "degree_N", } origin_longitude = { "data": [dset.variables["grid_mapping_0"].longitude_of_projection_origin], "long_name": "Longitude of projection origin", "units": "degree_E", } origin_altitude = None x = _ncvar_to_dict(dset.variables["x0"]) x["data"] = x["data"] * 1000 x["units"] = "m" y = _ncvar_to_dict(dset.variables["y0"]) y["data"] = y["data"] * 1000 y["units"] = "m" z = _ncvar_to_dict(dset.variables["z0"]) z["data"] = z["data"] * 1000 z["units"] = "m" # projection projection = {"data": [], "proj": "aeqd", "_include_lon_0_lat_0": "true"} projection.pop("data") # map _include_lon_0_lat_0 key to bool type if "_include_lon_0_lat_0" in projection: v = projection["_include_lon_0_lat_0"] projection["_include_lon_0_lat_0"] = {"true": True, "false": False}[v] # read in the fields fields = {} # fields in the file has a shape of (1, nz, ny, nx) with the leading 1 # indicating time but should shaped (nz, ny, nx) in the Grid object field_shape = tuple([len(dset.dimensions[d]) for d in ["z0", "y0", "x0"]]) field_shape_with_time = (1, ) + field_shape # check all non-reserved variables, those with the correct shape # are added to the field dictionary, if a wrong sized field is # detected a warning is raised field_keys = [k for k in dset.variables if k not in reserved_variables] for field in field_keys: if field in exclude_fields: continue if include_fields is not None: if field not in include_fields: continue field_dic = _ncvar_to_dict(dset.variables[field]) if field_dic["data"].shape == field_shape_with_time: field_dic["data"].shape = field_shape fields[field] = field_dic else: bad_shape = field_dic["data"].shape warnings.warn("Field %s skipped due to incorrect shape %s" % (field, bad_shape)) # radar_ variables if "radar_latitude" in dset.variables: radar_latitude = _ncvar_to_dict(dset.variables["radar_latitude"]) else: radar_latitude = { "long_name": "Latitude of radars used to make the grid.", "units": "degrees_north", "data": np.array([-3.1493]), } if "radar_longitude" in dset.variables: radar_longitude = _ncvar_to_dict(dset.variables["radar_longitude"]) else: radar_longitude = { "long_name": "Longitude of radars used to make the grid.", "units": "degrees_east", "data": np.array([-59.992]), } if "radar_altitude" in dset.variables: radar_altitude = _ncvar_to_dict(dset.variables["radar_altitude"]) else: radar_altitude = { "long_name": "Altitude of radars used to make the grid.", "units": "m", "data": np.array([102.4]), } if "radar_name" in dset.variables: radar_name = _ncvar_to_dict(dset.variables["radar_name"]) else: radar_name = { "long_name": "Name of radar used to make the grid", "data": np.array(["SIPAM"], dtype="<U1"), } if "radar_time" in dset.variables: radar_time = _ncvar_to_dict(dset.variables["radar_time"]) else: radar_time = None dset.close() return Grid( time, fields, metadata, origin_latitude, origin_longitude, origin_altitude, x, y, z, projection=projection, radar_latitude=radar_latitude, radar_longitude=radar_longitude, radar_altitude=radar_altitude, radar_name=radar_name, radar_time=radar_time, )
def c98dfile_archive(filename, field_names=None, additional_metadata=None, file_field_names=False, exclude_fields=None, cutnum=None, delay_field_loading=False, **kwargs): # test for non empty kwargs _test_arguments(kwargs) # create metadata retrieval object filemetadata = FileMetadata('c98d_archive', field_names, additional_metadata, file_field_names, exclude_fields) nfile = C98DRadFile(prepare_for_read(filename)) # scan_info = nfile.scan_info if cutnum is None: cutnum = nfile.scans else: cutnum = list(cutnum) # time time = filemetadata('time') _time = nfile.radial_info['seconds'] time['data'] = _time time['units'] = nfile.get_volume_start_time # range _range = filemetadata('range') _range['data'] = nfile.get_range('dBZ', cutnum) # _range['meters_to_center_of_first_gate'] = float(first_gate) # _range['meters_between_gates'] = float(gate_spacing) # fields fields = {} field_names = nfile.get_moment_type for field_name in field_names: dic = filemetadata(field_name) for i, cn in enumerate(cutnum): dic['_FillValue'] = get_fillvalue() if i == 0: dic['data'] = nfile.get_data(field_name, cn) else: fndata = nfile.get_data(field_name, cn) if fndata.shape[1] != dic['data'].shape[1]: if dic['data'].shape[1] - fndata.shape[1] > 0: apps = np.ones( (fndata.shape[0], dic['data'].shape[1] - fndata.shape[1])) * np.nan else: raise ValueError('something wrong!') fndata = np.c_[fndata, apps] dic['data'] = np.append(dic['data'], fndata, axis=0) fields.update({field_name: dic}) # scan_type scan_type = nfile.scan_type # latitude, longitude, altitude latitude = filemetadata('latitude') longitude = filemetadata('longitude') altitude = filemetadata('altitude') lat, lon, height = nfile.get_location latitude['data'] = np.array([lat], dtype='float64') longitude['data'] = np.array([lon], dtype='float64') altitude['data'] = np.array([height], dtype='float64') # sweep_number, sweep_mode, fixed_angle, sweep_start_ray_index # sweep_end_ray_index sweep_number = filemetadata('sweep_number') sweep_mode = filemetadata('sweep_mode') sweep_start_ray_index = filemetadata('sweep_start_ray_index') sweep_end_ray_index = filemetadata('sweep_end_ray_index') sweep_number['data'] = np.arange(nfile.cutnum, dtype='int32') sweep_mode['data'] = np.array(nfile.cutnum * ['azimuth_surveillance'], dtype='S') sweep_end_ray_index['data'] = np.array(nfile.cut_end) sweep_start_ray_index['data'] = np.array(nfile.cut_start) # azimuth, elevation, fixed_angle azimuth = filemetadata('azimuth') elevation = filemetadata('elevation') fixed_angle = filemetadata('fixed_angle') azimuth['data'] = np.array(nfile.get_azimuth) elevation['data'] = np.array(nfile.get_elevation) fixed_angle['data'] = nfile.get_target_angles # instrument_parameters nyquist_velocity = filemetadata('nyquist_velocity') unambiguous_range = filemetadata('unambiguous_range') nyquist_velocity['data'] = None unambiguous_range['data'] = None instrument_parameters = { 'unambiguous_range': unambiguous_range, 'nyquist_velocity': nyquist_velocity } return Radar(time, _range, fields, filemetadata, scan_type, latitude, longitude, altitude, sweep_number, sweep_mode, fixed_angle, sweep_start_ray_index, sweep_end_ray_index, azimuth, elevation, instrument_parameters=None)
def read_sipam_cappi(filename, exclude_fields=[ 'start_time', 'stop_time', 'time_bounds', 'x0', 'y0', 'lat0', 'lon0', 'z0', 'grid_mapping_0' ], include_fields=None, **kwargs): """ Read a netCDF grid file produced by Py-ART. Parameters ---------- filename : str Filename of netCDF grid file to read. This file must have been produced by :py:func:`write_grid` or have identical layout. Other Parameters ---------------- exclude_fields : list or None, optional List of fields to exclude from the radar object. This is applied after the `file_field_names` and `field_names` parameters. Set to None to include all fields specified by include_fields. include_fields : list or None, optional List of fields to include from the radar object. This is applied after the `file_field_names` and `field_names` parameters. Set to None to include all fields not specified by exclude_fields. Returns ------- grid : Grid Grid object containing gridded data. """ # test for non empty kwargs _test_arguments(kwargs) if exclude_fields is None: exclude_fields = [] reserved_variables = [ 'time', 'x', 'y', 'z', 'origin_latitude', 'origin_longitude', 'origin_altitude', 'point_x', 'point_y', 'point_z', 'projection', 'point_latitude', 'point_longitude', 'point_altitude', 'radar_latitude', 'radar_longitude', 'radar_altitude', 'radar_name', 'radar_time', 'base_time', 'time_offset', 'ProjectionCoordinateSystem'] dset = netCDF4.Dataset(filename, mode='r') # metadata metadata = dict([(k, getattr(dset, k)) for k in dset.ncattrs()]) # required reserved variables time = _ncvar_to_dict(dset.variables['time']) origin_latitude = { 'data': [dset.variables['grid_mapping_0'].latitude_of_projection_origin], 'long_name': 'Latitude of projection origin', 'units': 'degree_N' } origin_longitude = { 'data': [dset.variables['grid_mapping_0'].longitude_of_projection_origin], 'long_name': 'Longitude of projection origin', 'units': 'degree_E' } origin_altitude = None x = _ncvar_to_dict(dset.variables['x0']) x['data'] = x['data']*1000 x['units'] = 'm' y = _ncvar_to_dict(dset.variables['y0']) y['data'] = y['data']*1000 y['units'] = 'm' z = _ncvar_to_dict(dset.variables['z0']) z['data'] = z['data']*1000 z['units'] = 'm' # projection projection = { 'data': [], 'proj': 'aeqd', '_include_lon_0_lat_0': 'true' } projection.pop('data') # map _include_lon_0_lat_0 key to bool type if '_include_lon_0_lat_0' in projection: v = projection['_include_lon_0_lat_0'] projection['_include_lon_0_lat_0'] = {'true': True, 'false': False}[v] # read in the fields fields = {} # fields in the file has a shape of (1, nz, ny, nx) with the leading 1 # indicating time but should shaped (nz, ny, nx) in the Grid object field_shape = tuple([len(dset.dimensions[d]) for d in ['z0', 'y0', 'x0']]) field_shape_with_time = (1, ) + field_shape # check all non-reserved variables, those with the correct shape # are added to the field dictionary, if a wrong sized field is # detected a warning is raised field_keys = [k for k in dset.variables if k not in reserved_variables] for field in field_keys: if field in exclude_fields: continue if include_fields is not None: if field not in include_fields: continue field_dic = _ncvar_to_dict(dset.variables[field]) if field_dic['data'].shape == field_shape_with_time: field_dic['data'].shape = field_shape fields[field] = field_dic else: bad_shape = field_dic['data'].shape warnings.warn( 'Field %s skipped due to incorrect shape %s' % (field, bad_shape)) # radar_ variables if 'radar_latitude' in dset.variables: radar_latitude = _ncvar_to_dict(dset.variables['radar_latitude']) else: radar_latitude = { 'long_name': 'Latitude of radars used to make the grid.', 'units': 'degrees_north', 'data': np.array([-3.1493])} if 'radar_longitude' in dset.variables: radar_longitude = _ncvar_to_dict(dset.variables['radar_longitude']) else: radar_longitude = { 'long_name': 'Longitude of radars used to make the grid.', 'units': 'degrees_east', 'data': np.array([-59.992])} if 'radar_altitude' in dset.variables: radar_altitude = _ncvar_to_dict(dset.variables['radar_altitude']) else: radar_altitude = { 'long_name': 'Altitude of radars used to make the grid.', 'units': 'm', 'data': np.array([102.4])} if 'radar_name' in dset.variables: radar_name = _ncvar_to_dict(dset.variables['radar_name']) else: radar_name = { 'long_name': 'Name of radar used to make the grid', 'data': np.array(['SIPAM'], dtype='<U1')} if 'radar_time' in dset.variables: radar_time = _ncvar_to_dict(dset.variables['radar_time']) else: radar_time = None dset.close() return Grid( time, fields, metadata, origin_latitude, origin_longitude, origin_altitude, x, y, z, projection=projection, radar_latitude=radar_latitude, radar_longitude=radar_longitude, radar_altitude=radar_altitude, radar_name=radar_name, radar_time=radar_time)
def read_casa_netcdf(filename, **kwargs): """ Read a CASA NetCDF file. Parameters ---------- filename : str Name of CASA NetCDF file to read data from. Returns ------- radar : Radar Radar object. """ # test for non empty kwargs _test_arguments(kwargs) # create metadata retrieval object filemetadata = FileMetadata('casa_netcdf') # Open netCDF4 file dset = netCDF4.Dataset(filename) nrays = len(dset.dimensions['Radial']) nbins = len(dset.dimensions['Gate']) # latitude, longitude and altitude latitude = filemetadata('latitude') longitude = filemetadata('longitude') altitude = filemetadata('altitude') latitude['data'] = np.array([dset.Latitude], 'float64') longitude['data'] = np.array([dset.Longitude], 'float64') altitude['data'] = np.array([dset.Height], 'float64') # metadata metadata = filemetadata('metadata') metadata_mapping = { 'vcp-value': 'vcp', #not in casa 'radarName-value': 'RadarName', 'ConversionPlugin': 'conversion_software', #not in casa } for netcdf_attr, metadata_key in metadata_mapping.items(): if netcdf_attr in dset.ncattrs(): metadata[metadata_key] = dset.getncattr(netcdf_attr) # sweep_start_ray_index, sweep_end_ray_index sweep_start_ray_index = filemetadata('sweep_start_ray_index') sweep_end_ray_index = filemetadata('sweep_end_ray_index') sweep_start_ray_index['data'] = np.array([0], dtype='int32') sweep_end_ray_index['data'] = np.array([nrays - 1], dtype='int32') # sweep number sweep_number = filemetadata('sweep_number') sweep_number['data'] = np.array([0], dtype='int32') # sweep_type scan_type = 'ppi' # sweep_mode, fixed_angle sweep_mode = filemetadata('sweep_mode') fixed_angle = filemetadata('fixed_angle') sweep_mode['data'] = np.array(1 * ['azimuth_surveillance']) elev_mean = np.mean(dset.variables['Elevation']) fixed_angle['data'] = np.array([elev_mean], dtype='float32') # time time = filemetadata('time') start_time = datetime.datetime.utcfromtimestamp(dset.variables['Time'][0]) time['units'] = make_time_unit_str(start_time) time['data'] = np.zeros((nrays, ), dtype='float64') # range _range = filemetadata('range') step = dset.variables['GateWidth'][0] / 1e3 # * len(dset.variables['GateWidth'][:]))/1e6 _range['data'] = (np.arange(nbins, dtype='float32') * step + step / 2) _range['meters_to_center_of_first_gate'] = step / 2. _range['meters_between_gates'] = step # elevation elevation = filemetadata('elevation') elevation_angle = elev_mean elevation['data'] = np.ones((nrays, ), dtype='float32') * elevation_angle # azimuth azimuth = filemetadata('azimuth') azimuth['data'] = dset.variables['Azimuth'][:] # fields # Ryan Note: What is "TypeName"? # field_name = dset.TypeName # field_data = np.ma.array(dset.variables[field_name][:]) # if 'MissingData' in dset.ncattrs(): # field_data[field_data == dset.MissingData] = np.ma.masked # if 'RangeFolded' in dset.ncattrs(): # field_data[field_data == dset.RangeFolded] = np.ma.masked # fields = {field_name: filemetadata(field_name)} # fields[field_name]['data'] = field_data # fields[field_name]['units'] = dset.variables[field_name].Units # fields[field_name]['_FillValue'] = get_fillvalue() # borrowing from d3r_gcpex_nc.py ncvars = dset.variables keys = [k for k, v in ncvars.items() if v.dimensions == ('Radial', 'Gate')] fields = {} for key in keys: field_name = filemetadata.get_field_name(key) if field_name is None: field_name = key fields[field_name] = _ncvar_to_dict(ncvars[key]) # instrument_parameters instrument_parameters = {} if 'PRF-value' in dset.ncattrs(): dic = filemetadata('prt') prt = 1. / float(dset.getncattr('PRF-value')) dic['data'] = np.ones((nrays, ), dtype='float32') * prt instrument_parameters['prt'] = dic if 'PulseWidth-value' in dset.ncattrs(): dic = filemetadata('pulse_width') pulse_width = dset.getncattr('PulseWidth-value') * 1.e-6 dic['data'] = np.ones((nrays, ), dtype='float32') * pulse_width instrument_parameters['pulse_width'] = dic if 'NyquistVelocity-value' in dset.ncattrs(): dic = filemetadata('nyquist_velocity') nyquist_velocity = float(dset.getncattr('NyquistVelocity-value')) dic['data'] = np.ones((nrays, ), dtype='float32') * nyquist_velocity instrument_parameters['nyquist_velocity'] = dic if 'Beamwidth' in dset.variables: dic = filemetadata('radar_beam_width_h') dic['data'] = dset.variables['Beamwidth'][:] instrument_parameters['radar_beam_width_h'] = dic dset.close() return Radar(time, _range, fields, metadata, scan_type, latitude, longitude, altitude, sweep_number, sweep_mode, fixed_angle, sweep_start_ray_index, sweep_end_ray_index, azimuth, elevation, instrument_parameters=instrument_parameters)