def convert_cfunits(from_value, from_unit, wanted_unit=None, suppress_unit=False): """ Use the cfunits-python package to handle the interaction with udunits2 """ try: from cfunits import Units except ImportError: raise Exception("cfunits option relies on cfunits-python package") ZERO = False if float(from_value) == 0: # special Zero handling if from_unit != '1': warnings.warn("""Found a 0, udunits2 breaks, so we are assuming that this is not a non-zero based conversion like temperature""" ) ZERO = True from_value = 1. if wanted_unit: return Units.conform(from_value, Units(from_unit), Units(wanted_unit)) out = Units(" ".join((str(from_value), from_unit))).format() split_out = out.split(' ') if len(split_out) == 1: out = (1., split_out[0]) else: if ZERO: out = (0.0, split_out[1]) else: out = (float(split_out[0]), split_out[1]) if suppress_unit: return out[0] return out
def gallon2liter(value): if value: return Units.conform(int(value), Units('gallon / day'), Units('liter / second'), inplace=True) return 0.0
def get_value(self, name, out=None, units=None, angle=None, at=None, method=None): if out is None: grid = self.get_var_grid(name) dtype = self.get_var_type(name) if dtype == "": raise ValueError("{name} not understood".format(name=name)) loc = self.get_var_grid_loc(name) out = np.empty(self.get_grid_dim(grid, loc), dtype=dtype) self.bmi.get_value(name, out) if name in self._interpolators and at is not None: out[:] = self._interpolators[name].interpolate(at) from_units = Units(self.get_var_units(name)) if units is not None: to_units = Units(units) else: to_units = from_units if units is not None and from_units != to_units: Units.conform(out, from_units, to_units, inplace=True) # if units is not None: # try: # from_units = self.get_var_units(name) # except AttributeError, NotImplementedError: # pass # else: # Units.conform(out, Units(from_units), Units(units), # inplace=True) if angle not in ("azimuth", "math", None): raise ValueError("angle not understood") if angle == "azimuth" and "azimuth" not in name: transform_math_to_azimuth(out, to_units) elif angle == "math" and "azimuth" in name: transform_azimuth_to_math(out, to_units) return out
def get_value(self, name, out=None, units=None, angle=None, at=None, method=None): if out is None: grid = self.get_var_grid(name) dtype = self.get_var_type(name) if dtype == '': raise ValueError('{name} not understood'.format(name=name)) out = np.empty(self.get_grid_size(grid), dtype=dtype) bmi_call(self.bmi.get_value, name, out) if name in self._interpolators and at is not None: out[:] = self._interpolators[name].interpolate(at) from_units = Units(self.get_var_units(name)) if units is not None: to_units = Units(units) else: to_units = from_units if units is not None and from_units != to_units: Units.conform(out, from_units, to_units, inplace=True) # if units is not None: # try: # from_units = self.get_var_units(name) # except AttributeError, NotImplementedError: # pass # else: # Units.conform(out, Units(from_units), Units(units), # inplace=True) if angle not in ('azimuth', 'math', None): raise ValueError('angle not understood') if angle == 'azimuth' and 'azimuth' not in name: transform_math_to_azimuth(out, to_units) elif angle == 'math' and 'azimuth' in name: transform_azimuth_to_math(out, to_units) return out
def wrap(self, units=None): time = val_or_raise(func, (self._base, )) if units is not None: try: from_units = Units(self.get_time_units()) to_units = Units(units) except AttributeError, NotImplementedError: pass else: if not from_units.equals(to_units): time = Units.conform(time, from_units, to_units)
def wrap(self, name, out=None, units=None): """Get a value by name. Parameters ---------- name : str CSDMS standard name. out : ndarray, optional Buffer to place values. units : str, optional Convert units of the returned values. Returns ------- ndarray Array of values (or *out*, if provided). """ if out is None: grid = self.get_var_grid(name) dtype = self.get_var_type(name) if dtype == '': print self.get_output_var_names() raise ValueError('{name} not understood'.format(name=name)) out = np.empty(self.get_grid_size(grid), dtype=dtype) val_or_raise(func, (self._base, name, out)) if units is not None: try: from_units = self.get_var_units(name) except AttributeError, NotImplementedError: pass else: Units.conform(out, Units(from_units), Units(units), inplace=True)
def time_from(self, time, units): if units is None: return time try: # units_str = self.time_units units_str = self.time_units except (AttributeError, NotImplementedError): pass else: to_units = Units(units_str) from_units = Units(units) if not from_units.equals(to_units): time = Units.conform(time, from_units, to_units) return time
def test_get_field_with_overloaded_units(self): rd = self.test_data.get_rd('cancm4_tas', kwds={'conform_units_to': 'celsius'}) preload = [False, True] for pre in preload: field = rd.get() # conform units argument needs to be attached to a field variable self.assertEqual(field.variables['tas']._conform_units_to, Units('celsius')) sub = field.get_time_region({'year': [2009], 'month': [5]}) if pre: # if we wanted to load the data prior to subset then do so and manually perform the units conversion to_test = Units.conform(sub.variables['tas'].value, sub.variables['tas'].cfunits, Units('celsius')) # assert the conform attribute makes it though the subset self.assertEqual(sub.variables['tas']._conform_units_to, Units('celsius')) value = sub.variables['tas'].value self.assertAlmostEqual(np.ma.mean(value), 5.921925206338206) self.assertAlmostEqual(np.ma.median(value), 10.745431900024414) if pre: # assert the manually converted array matches the loaded value self.assertNumpyAll(to_test, value)
def convert_units(input_vals, input_unit, output_unit): """ Convert the units of an array of values Params ------- input_vals : Numpy array Values to convert input_unit : str Unit corresponding to the input values output_unit : str Desired unit to covert the values to Return ------- Numpy array """ conv_vals = Units.conform(input_vals, Units(input_unit), Units(output_unit)) return conv_vals
def conform(*args, **kwargs): return cfUnits.conform(*args, **kwargs)
def test_Units_conform(self): self.assertEqual(Units.conform(0.5, Units('km'), Units('m')), 500) self.assertEqual(Units.conform(360, Units('second'), Units('minute')), 6) x = Units.conform([360], Units('second'), Units('minute')) self.assertIsInstance(x, numpy.ndarray) self.assertEqual(x.dtype, numpy.dtype('float64')) self.assertTrue(numpy.allclose(x, 6)) x = Units.conform((360, 720), Units('second'), Units('minute')) self.assertIsInstance(x, numpy.ndarray) self.assertEqual(x.dtype, numpy.dtype('float64')) self.assertTrue(numpy.allclose(x, [6, 12])) x = Units.conform([360.0, 720.0], Units('second'), Units('minute')) self.assertIsInstance(x, numpy.ndarray) self.assertEqual(x.dtype, numpy.dtype('float64')) self.assertTrue(numpy.allclose(x, [6, 12])) x = Units.conform([[360, 720]], Units('second'), Units('minute')) self.assertIsInstance(x, numpy.ndarray) self.assertEqual(x.dtype, numpy.dtype('float64')) self.assertTrue(numpy.allclose(x, [[6, 12]])) v = numpy.array([360.0, 720.0]) x = Units.conform(v, Units('second'), Units('minute')) self.assertIsInstance(x, numpy.ndarray) self.assertEqual(x.dtype, numpy.dtype('float64')) self.assertTrue(numpy.allclose(x, [6, 12]), x) v = numpy.array([360, 720]) x = Units.conform(v, Units('second'), Units('minute'), inplace=True) self.assertIsInstance(x, numpy.ndarray) self.assertEqual(x.dtype, numpy.dtype('float64')) self.assertTrue(numpy.allclose(x, [6, 12])) self.assertTrue(numpy.allclose(x, v)) x = Units.conform(35, Units('degrees_C'), Units('degrees_F')) self.assertIsInstance(x, float) self.assertTrue(numpy.allclose(x, 95)) x = Units.conform([35], Units('degrees_C'), Units('degrees_F')) self.assertIsInstance(x, numpy.ndarray) self.assertEqual(x.dtype, numpy.dtype('float64')) self.assertTrue(numpy.allclose(x, 95)) x = Units.conform(35, Units('degrees_C'), Units('degrees_F'), inplace=True) self.assertIsInstance(x, float) self.assertTrue(numpy.allclose(x, 95)) x = Units.conform([35], Units('degrees_C'), Units('degrees_F'), inplace=True) self.assertIsInstance(x, numpy.ndarray) self.assertEqual(x.dtype, numpy.dtype('float64')) self.assertTrue(numpy.allclose(x, 95)) with self.assertRaises(ValueError): Units.conform(1, Units('m'), Units('second'))
def _convert(val, from_units, to_units): from_units, to_units = Units(from_units), Units(to_units) if from_units.equals(to_units): return val else: return Units.conform(val, from_units, to_units)
def __init__(self, inputFileName, gdalDataset, gdalMetadata, logLevel=30, rmMetadatas=['NETCDF_VARNAME', '_Unsigned', 'ScaleRatio', 'ScaleOffset', 'dods_variable'], **kwargs): # Remove 'NC_GLOBAL#' and 'GDAL_' and 'NANSAT_' # from keys in gdalDataset tmpGdalMetadata = {} geoMetadata = {} origin_is_nansat = False if not gdalMetadata: raise WrongMapperError for key in gdalMetadata.keys(): newKey = key.replace('NC_GLOBAL#', '').replace('GDAL_', '') if 'NANSAT_' in newKey: geoMetadata[newKey.replace('NANSAT_', '')] = gdalMetadata[key] origin_is_nansat = True else: tmpGdalMetadata[newKey] = gdalMetadata[key] gdalMetadata = tmpGdalMetadata fileExt = os.path.splitext(inputFileName)[1] # Get file names from dataset or subdataset subDatasets = gdalDataset.GetSubDatasets() if len(subDatasets) == 0: fileNames = [inputFileName] else: fileNames = [f[0] for f in subDatasets] # add bands with metadata and corresponding values to the empty VRT metaDict = [] xDatasetSource = '' yDatasetSource = '' firstXSize = 0 firstYSize = 0 for _, fileName in enumerate(fileNames): subDataset = gdal.Open(fileName) # choose the first dataset whith grid if (firstXSize == 0 and firstYSize == 0 and subDataset.RasterXSize > 1 and subDataset.RasterYSize > 1): firstXSize = subDataset.RasterXSize firstYSize = subDataset.RasterYSize firstSubDataset = subDataset # get projection from the first subDataset projection = firstSubDataset.GetProjection() # take bands whose sizes are same as the first band. if (subDataset.RasterXSize == firstXSize and subDataset.RasterYSize == firstYSize): if projection == '': projection = subDataset.GetProjection() if ('GEOLOCATION_X_DATASET' in fileName or 'longitude' in fileName): xDatasetSource = fileName elif ('GEOLOCATION_Y_DATASET' in fileName or 'latitude' in fileName): yDatasetSource = fileName else: for iBand in range(subDataset.RasterCount): subBand = subDataset.GetRasterBand(iBand+1) bandMetadata = subBand.GetMetadata_Dict() if 'PixelFunctionType' in bandMetadata: bandMetadata.pop('PixelFunctionType') sourceBands = iBand + 1 # sourceBands = i*subDataset.RasterCount + iBand + 1 # generate src metadata src = {'SourceFilename': fileName, 'SourceBand': sourceBands} # set scale ratio and scale offset scaleRatio = bandMetadata.get( 'ScaleRatio', bandMetadata.get( 'scale', bandMetadata.get('scale_factor', ''))) if len(scaleRatio) > 0: src['ScaleRatio'] = scaleRatio scaleOffset = bandMetadata.get( 'ScaleOffset', bandMetadata.get( 'offset', bandMetadata.get( 'add_offset', ''))) if len(scaleOffset) > 0: src['ScaleOffset'] = scaleOffset # sate DataType src['DataType'] = subBand.DataType # generate dst metadata # get all metadata from input band dst = bandMetadata # set wkv and bandname dst['wkv'] = bandMetadata.get('standard_name', '') # first, try the name metadata if 'name' in bandMetadata: bandName = bandMetadata['name'] else: # if it doesn't exist get name from NETCDF_VARNAME bandName = bandMetadata.get('NETCDF_VARNAME', '') if len(bandName) == 0: bandName = bandMetadata.get( 'dods_variable', '' ) # remove digits added by gdal in # exporting to netcdf... if (len(bandName) > 0 and origin_is_nansat and fileExt == '.nc'): if bandName[-1:].isdigit(): bandName = bandName[:-1] if bandName[-1:].isdigit(): bandName = bandName[:-1] # if still no bandname, create one if len(bandName) == 0: bandName = 'band_%03d' % iBand dst['name'] = bandName # remove non-necessary metadata from dst for rmMetadata in rmMetadatas: if rmMetadata in dst: dst.pop(rmMetadata) # append band with src and dst dictionaries metaDict.append({'src': src, 'dst': dst}) # create empty VRT dataset with geolocation only VRT.__init__(self, firstSubDataset, srcMetadata=gdalMetadata) # add bands with metadata and corresponding values to the empty VRT self._create_bands(metaDict) # Create complex data bands from 'xxx_real' and 'xxx_imag' bands # using pixelfunctions rmBands = [] for iBandNo in range(self.dataset.RasterCount): iBand = self.dataset.GetRasterBand(iBandNo + 1) iBandName = iBand.GetMetadataItem('name') # find real data band if iBandName.find("_real") != -1: realBandNo = iBandNo realBand = self.dataset.GetRasterBand(realBandNo + 1) realDtype = realBand.GetMetadataItem('DataType') bandName = iBandName.replace(iBandName.split('_')[-1], '')[0:-1] for jBandNo in range(self.dataset.RasterCount): jBand = self.dataset.GetRasterBand(jBandNo + 1) jBandName = jBand.GetMetadataItem('name') # find an imaginary data band corresponding to the real # data band and create complex data band from the bands if jBandName.find(bandName+'_imag') != -1: imagBandNo = jBandNo imagBand = self.dataset.GetRasterBand(imagBandNo + 1) imagDtype = imagBand.GetMetadataItem('DataType') dst = imagBand.GetMetadata() dst['name'] = bandName dst['PixelFunctionType'] = 'ComplexData' dst['dataType'] = 10 src = [{'SourceFilename': fileNames[realBandNo], 'SourceBand': 1, 'DataType': realDtype}, {'SourceFilename': fileNames[imagBandNo], 'SourceBand': 1, 'DataType': imagDtype}] self._create_band(src, dst) self.dataset.FlushCache() rmBands.append(realBandNo + 1) rmBands.append(imagBandNo + 1) # Delete real and imaginary bands if len(rmBands) != 0: self.delete_bands(rmBands) if len(projection) == 0: # projection was not set automatically # get projection from GCPProjection projection = geoMetadata.get('GCPProjection', '') if len(projection) == 0: # no projection was found in dataset or metadata: # generate WGS84 by default projection = NSR().wkt # fix problem with MET.NO files where a, b given in m and XC/YC in km if ('UNIT["kilometre"' in projection and ',SPHEROID["Spheroid",6378273,7.331926543631893e-12]' in projection): projection = projection.replace( ',SPHEROID["Spheroid",6378273,7.331926543631893e-12]', '') # set projection self.dataset.SetProjection(self.repare_projection(projection)) # check if GCPs were added from input dataset gcps = firstSubDataset.GetGCPs() gcpProjection = firstSubDataset.GetGCPProjection() # if no GCPs in input dataset: try to add GCPs from metadata if not gcps: gcps = self.add_gcps_from_metadata(geoMetadata) # if yet no GCPs: try to add GCPs from variables if not gcps: gcps = self.add_gcps_from_variables(inputFileName) if gcps: if len(gcpProjection) == 0: # get GCP projection and repare gcpProjection = self.repare_projection(geoMetadata. get('GCPProjection', '')) # add GCPs to dataset self.dataset.SetGCPs(gcps, gcpProjection) self.dataset.SetProjection('') self._remove_geotransform() # Find proper bands and insert GEOLOCATION ARRAY into dataset if len(xDatasetSource) > 0 and len(yDatasetSource) > 0: self.add_geolocationArray(GeolocationArray(xDatasetSource, yDatasetSource)) elif not gcps: # if no GCPs found and not GEOLOCATION ARRAY set: # Set Nansat Geotransform if it is not set automatically geoTransform = self.dataset.GetGeoTransform() if len(geoTransform) == 0: geoTransformStr = geoMetadata.get('GeoTransform', '(0|1|0|0|0|0|1)') geoTransform = eval(geoTransformStr.replace('|', ',')) self.dataset.SetGeoTransform(geoTransform) subMetadata = firstSubDataset.GetMetadata() ### GET START TIME from METADATA time_coverage_start = None if 'start_time' in gdalMetadata: time_coverage_start = parse_time(gdalMetadata['start_time']) elif 'start_date' in gdalMetadata: time_coverage_start = parse_time(gdalMetadata['start_date']) elif 'time_coverage_start' in gdalMetadata: time_coverage_start = parse_time( gdalMetadata['time_coverage_start']) ### GET END TIME from METADATA time_coverage_end = None if 'stop_time' in gdalMetadata: time_coverage_start = parse_time(gdalMetadata['stop_time']) elif 'stop_date' in gdalMetadata: time_coverage_start = parse_time(gdalMetadata['stop_date']) elif 'time_coverage_stop' in gdalMetadata: time_coverage_start = parse_time( gdalMetadata['time_coverage_stop']) elif 'end_time' in gdalMetadata: time_coverage_start = parse_time(gdalMetadata['end_time']) elif 'end_date' in gdalMetadata: time_coverage_start = parse_time(gdalMetadata['end_date']) elif 'time_coverage_end' in gdalMetadata: time_coverage_start = parse_time( gdalMetadata['time_coverage_end']) ### GET start time from time variable if (time_coverage_start is None and cfunitsInstalled and 'time#standard_name' in subMetadata and subMetadata['time#standard_name'] == 'time' and 'time#units' in subMetadata and 'time#calendar' in subMetadata): # get data from netcdf data ncFile = netcdf_file(inputFileName, 'r') timeLength = ncFile.variables['time'].shape[0] timeValueStart = ncFile.variables['time'][0] timeValueEnd = ncFile.variables['time'][-1] ncFile.close() try: timeDeltaStart = Units.conform(timeValueStart, Units(subMetadata['time#units'], calendar=subMetadata['time#calendar']), Units('days since 1950-01-01')) except ValueError: self.logger.error('calendar units are wrong: %s' % subMetadata['time#calendar']) else: time_coverage_start = (datetime.datetime(1950,1,1) + datetime.timedelta(float(timeDeltaStart))) if timeLength > 1: timeDeltaEnd = Units.conform(timeValueStart, Units(subMetadata['time#units'], calendar=subMetadata['time#calendar']), Units('days since 1950-01-01')) else: timeDeltaEnd = timeDeltaStart + 1 time_coverage_end = (datetime.datetime(1950,1,1) + datetime.timedelta(float(timeDeltaEnd))) ## finally set values of time_coverage start and end if available if time_coverage_start is not None: self.dataset.SetMetadataItem('time_coverage_start', time_coverage_start.isoformat()) if time_coverage_end is not None: self.dataset.SetMetadataItem('time_coverage_end', time_coverage_end.isoformat()) if 'sensor' not in gdalMetadata: self.dataset.SetMetadataItem('sensor', 'unknown') if 'satellite' not in gdalMetadata: self.dataset.SetMetadataItem('satellite', 'unknown') if 'source_type' not in gdalMetadata: self.dataset.SetMetadataItem('source_type', 'unknown') if 'platform' not in gdalMetadata: self.dataset.SetMetadataItem('platform', 'unknown') if 'instrument' not in gdalMetadata: self.dataset.SetMetadataItem('instrument', 'unknown') self.logger.info('Use generic mapper - OK!')
def __init__(self, inputFileName, gdalDataset, gdalMetadata, logLevel=30, rmMetadatas=[ 'NETCDF_VARNAME', '_Unsigned', 'ScaleRatio', 'ScaleOffset', 'dods_variable' ], **kwargs): # Remove 'NC_GLOBAL#' and 'GDAL_' and 'NANSAT_' # from keys in gdalDataset tmpGdalMetadata = {} geoMetadata = {} origin_is_nansat = False if not gdalMetadata: raise WrongMapperError for key in gdalMetadata.keys(): newKey = key.replace('NC_GLOBAL#', '').replace('GDAL_', '') if 'NANSAT_' in newKey: geoMetadata[newKey.replace('NANSAT_', '')] = gdalMetadata[key] origin_is_nansat = True else: tmpGdalMetadata[newKey] = gdalMetadata[key] gdalMetadata = tmpGdalMetadata fileExt = os.path.splitext(inputFileName)[1] # Get file names from dataset or subdataset subDatasets = gdalDataset.GetSubDatasets() if len(subDatasets) == 0: fileNames = [inputFileName] else: fileNames = [f[0] for f in subDatasets] # add bands with metadata and corresponding values to the empty VRT metaDict = [] xDatasetSource = '' yDatasetSource = '' firstXSize = 0 firstYSize = 0 for _, fileName in enumerate(fileNames): subDataset = gdal.Open(fileName) # choose the first dataset whith grid if (firstXSize == 0 and firstYSize == 0 and subDataset.RasterXSize > 1 and subDataset.RasterYSize > 1): firstXSize = subDataset.RasterXSize firstYSize = subDataset.RasterYSize firstSubDataset = subDataset # get projection from the first subDataset projection = firstSubDataset.GetProjection() # take bands whose sizes are same as the first band. if (subDataset.RasterXSize == firstXSize and subDataset.RasterYSize == firstYSize): if projection == '': projection = subDataset.GetProjection() if ('GEOLOCATION_X_DATASET' in fileName or 'longitude' in fileName): xDatasetSource = fileName elif ('GEOLOCATION_Y_DATASET' in fileName or 'latitude' in fileName): yDatasetSource = fileName else: for iBand in range(subDataset.RasterCount): subBand = subDataset.GetRasterBand(iBand + 1) bandMetadata = subBand.GetMetadata_Dict() if 'PixelFunctionType' in bandMetadata: bandMetadata.pop('PixelFunctionType') sourceBands = iBand + 1 # sourceBands = i*subDataset.RasterCount + iBand + 1 # generate src metadata src = { 'SourceFilename': fileName, 'SourceBand': sourceBands } # set scale ratio and scale offset scaleRatio = bandMetadata.get( 'ScaleRatio', bandMetadata.get( 'scale', bandMetadata.get('scale_factor', ''))) if len(scaleRatio) > 0: src['ScaleRatio'] = scaleRatio scaleOffset = bandMetadata.get( 'ScaleOffset', bandMetadata.get( 'offset', bandMetadata.get('add_offset', ''))) if len(scaleOffset) > 0: src['ScaleOffset'] = scaleOffset # sate DataType src['DataType'] = subBand.DataType # generate dst metadata # get all metadata from input band dst = bandMetadata # set wkv and bandname dst['wkv'] = bandMetadata.get('standard_name', '') # first, try the name metadata if 'name' in bandMetadata: bandName = bandMetadata['name'] else: # if it doesn't exist get name from NETCDF_VARNAME bandName = bandMetadata.get('NETCDF_VARNAME', '') if len(bandName) == 0: bandName = bandMetadata.get( 'dods_variable', '') # remove digits added by gdal in # exporting to netcdf... if (len(bandName) > 0 and origin_is_nansat and fileExt == '.nc'): if bandName[-1:].isdigit(): bandName = bandName[:-1] if bandName[-1:].isdigit(): bandName = bandName[:-1] # if still no bandname, create one if len(bandName) == 0: bandName = 'band_%03d' % iBand dst['name'] = bandName # remove non-necessary metadata from dst for rmMetadata in rmMetadatas: if rmMetadata in dst: dst.pop(rmMetadata) # append band with src and dst dictionaries metaDict.append({'src': src, 'dst': dst}) # create empty VRT dataset with geolocation only VRT.__init__(self, firstSubDataset, srcMetadata=gdalMetadata) # add bands with metadata and corresponding values to the empty VRT self._create_bands(metaDict) # Create complex data bands from 'xxx_real' and 'xxx_imag' bands # using pixelfunctions rmBands = [] for iBandNo in range(self.dataset.RasterCount): iBand = self.dataset.GetRasterBand(iBandNo + 1) iBandName = iBand.GetMetadataItem('name') # find real data band if iBandName.find("_real") != -1: realBandNo = iBandNo realBand = self.dataset.GetRasterBand(realBandNo + 1) realDtype = realBand.GetMetadataItem('DataType') bandName = iBandName.replace(iBandName.split('_')[-1], '')[0:-1] for jBandNo in range(self.dataset.RasterCount): jBand = self.dataset.GetRasterBand(jBandNo + 1) jBandName = jBand.GetMetadataItem('name') # find an imaginary data band corresponding to the real # data band and create complex data band from the bands if jBandName.find(bandName + '_imag') != -1: imagBandNo = jBandNo imagBand = self.dataset.GetRasterBand(imagBandNo + 1) imagDtype = imagBand.GetMetadataItem('DataType') dst = imagBand.GetMetadata() dst['name'] = bandName dst['PixelFunctionType'] = 'ComplexData' dst['dataType'] = 10 src = [{ 'SourceFilename': fileNames[realBandNo], 'SourceBand': 1, 'DataType': realDtype }, { 'SourceFilename': fileNames[imagBandNo], 'SourceBand': 1, 'DataType': imagDtype }] self._create_band(src, dst) self.dataset.FlushCache() rmBands.append(realBandNo + 1) rmBands.append(imagBandNo + 1) # Delete real and imaginary bands if len(rmBands) != 0: self.delete_bands(rmBands) if len(projection) == 0: # projection was not set automatically # get projection from GCPProjection projection = geoMetadata.get('GCPProjection', '') if len(projection) == 0: # no projection was found in dataset or metadata: # generate WGS84 by default projection = NSR().wkt # fix problem with MET.NO files where a, b given in m and XC/YC in km if ('UNIT["kilometre"' in projection and ',SPHEROID["Spheroid",6378273,7.331926543631893e-12]' in projection): projection = projection.replace( ',SPHEROID["Spheroid",6378273,7.331926543631893e-12]', '') # set projection self.dataset.SetProjection(self.repare_projection(projection)) # check if GCPs were added from input dataset gcps = firstSubDataset.GetGCPs() gcpProjection = firstSubDataset.GetGCPProjection() # if no GCPs in input dataset: try to add GCPs from metadata if not gcps: gcps = self.add_gcps_from_metadata(geoMetadata) # if yet no GCPs: try to add GCPs from variables if not gcps: gcps = self.add_gcps_from_variables(inputFileName) if gcps: if len(gcpProjection) == 0: # get GCP projection and repare gcpProjection = self.repare_projection( geoMetadata.get('GCPProjection', '')) # add GCPs to dataset self.dataset.SetGCPs(gcps, gcpProjection) self.dataset.SetProjection('') self._remove_geotransform() # Find proper bands and insert GEOLOCATION ARRAY into dataset if len(xDatasetSource) > 0 and len(yDatasetSource) > 0: self.add_geolocationArray( GeolocationArray(xDatasetSource, yDatasetSource)) elif not gcps: # if no GCPs found and not GEOLOCATION ARRAY set: # Set Nansat Geotransform if it is not set automatically geoTransform = self.dataset.GetGeoTransform() if len(geoTransform) == 0: geoTransformStr = geoMetadata.get('GeoTransform', '(0|1|0|0|0|0|1)') geoTransform = eval(geoTransformStr.replace('|', ',')) self.dataset.SetGeoTransform(geoTransform) subMetadata = firstSubDataset.GetMetadata() ### GET START TIME from METADATA time_coverage_start = None if 'start_time' in gdalMetadata: time_coverage_start = parse_time(gdalMetadata['start_time']) elif 'start_date' in gdalMetadata: time_coverage_start = parse_time(gdalMetadata['start_date']) elif 'time_coverage_start' in gdalMetadata: time_coverage_start = parse_time( gdalMetadata['time_coverage_start']) ### GET END TIME from METADATA time_coverage_end = None if 'stop_time' in gdalMetadata: time_coverage_start = parse_time(gdalMetadata['stop_time']) elif 'stop_date' in gdalMetadata: time_coverage_start = parse_time(gdalMetadata['stop_date']) elif 'time_coverage_stop' in gdalMetadata: time_coverage_start = parse_time( gdalMetadata['time_coverage_stop']) elif 'end_time' in gdalMetadata: time_coverage_start = parse_time(gdalMetadata['end_time']) elif 'end_date' in gdalMetadata: time_coverage_start = parse_time(gdalMetadata['end_date']) elif 'time_coverage_end' in gdalMetadata: time_coverage_start = parse_time(gdalMetadata['time_coverage_end']) ### GET start time from time variable if (time_coverage_start is None and cfunitsInstalled and 'time#standard_name' in subMetadata and subMetadata['time#standard_name'] == 'time' and 'time#units' in subMetadata and 'time#calendar' in subMetadata): # get data from netcdf data ncFile = netcdf_file(inputFileName, 'r') timeLength = ncFile.variables['time'].shape[0] timeValueStart = ncFile.variables['time'][0] timeValueEnd = ncFile.variables['time'][-1] ncFile.close() try: timeDeltaStart = Units.conform( timeValueStart, Units(subMetadata['time#units'], calendar=subMetadata['time#calendar']), Units('days since 1950-01-01')) except ValueError: self.logger.error('calendar units are wrong: %s' % subMetadata['time#calendar']) else: time_coverage_start = ( datetime.datetime(1950, 1, 1) + datetime.timedelta(float(timeDeltaStart))) if timeLength > 1: timeDeltaEnd = Units.conform( timeValueStart, Units(subMetadata['time#units'], calendar=subMetadata['time#calendar']), Units('days since 1950-01-01')) else: timeDeltaEnd = timeDeltaStart + 1 time_coverage_end = (datetime.datetime(1950, 1, 1) + datetime.timedelta(float(timeDeltaEnd))) ## finally set values of time_coverage start and end if available if time_coverage_start is not None: self.dataset.SetMetadataItem('time_coverage_start', time_coverage_start.isoformat()) if time_coverage_end is not None: self.dataset.SetMetadataItem('time_coverage_end', time_coverage_end.isoformat()) if 'sensor' not in gdalMetadata: self.dataset.SetMetadataItem('sensor', 'unknown') if 'satellite' not in gdalMetadata: self.dataset.SetMetadataItem('satellite', 'unknown') if 'source_type' not in gdalMetadata: self.dataset.SetMetadataItem('source_type', 'unknown') if 'platform' not in gdalMetadata: self.dataset.SetMetadataItem('platform', 'unknown') if 'instrument' not in gdalMetadata: self.dataset.SetMetadataItem('instrument', 'unknown') self.logger.info('Use generic mapper - OK!')
def test_Units_conform(self): """Tests the `conform` class method on `Units`.""" self.assertEqual(Units.conform(0.5, Units("km"), Units("m")), 500) self.assertEqual(Units.conform(360, Units("second"), Units("minute")), 6) x = Units.conform([360], Units("second"), Units("minute")) self.assertIsInstance(x, numpy.ndarray) self.assertEqual(x.dtype, numpy.dtype("float64")) self.assertTrue(numpy.allclose(x, 6)) x = Units.conform((360, 720), Units("second"), Units("minute")) self.assertIsInstance(x, numpy.ndarray) self.assertEqual(x.dtype, numpy.dtype("float64")) self.assertTrue(numpy.allclose(x, [6, 12])) x = Units.conform([360.0, 720.0], Units("second"), Units("minute")) self.assertIsInstance(x, numpy.ndarray) self.assertEqual(x.dtype, numpy.dtype("float64")) self.assertTrue(numpy.allclose(x, [6, 12])) x = Units.conform([[360, 720]], Units("second"), Units("minute")) self.assertIsInstance(x, numpy.ndarray) self.assertEqual(x.dtype, numpy.dtype("float64")) self.assertTrue(numpy.allclose(x, [[6, 12]])) v = numpy.array([360.0, 720.0]) x = Units.conform(v, Units("second"), Units("minute")) self.assertIsInstance(x, numpy.ndarray) self.assertEqual(x.dtype, numpy.dtype("float64")) self.assertTrue(numpy.allclose(x, [6, 12]), x) v = numpy.array([360, 720]) x = Units.conform(v, Units("second"), Units("minute"), inplace=True) self.assertIsInstance(x, numpy.ndarray) self.assertEqual(x.dtype, numpy.dtype("float64")) self.assertTrue(numpy.allclose(x, [6, 12])) self.assertTrue(numpy.allclose(x, v)) x = Units.conform(35, Units("degrees_C"), Units("degrees_F")) self.assertIsInstance(x, float) self.assertTrue(numpy.allclose(x, 95)) x = Units.conform([35], Units("degrees_C"), Units("degrees_F")) self.assertIsInstance(x, numpy.ndarray) self.assertEqual(x.dtype, numpy.dtype("float64")) self.assertTrue(numpy.allclose(x, 95)) x = Units.conform(35, Units("degrees_C"), Units("degrees_F"), inplace=True) self.assertIsInstance(x, float) self.assertTrue(numpy.allclose(x, 95)) x = Units.conform([35], Units("degrees_C"), Units("degrees_F"), inplace=True) self.assertIsInstance(x, numpy.ndarray) self.assertEqual(x.dtype, numpy.dtype("float64")) self.assertTrue(numpy.allclose(x, 95)) with self.assertRaises(ValueError): Units.conform(1, Units("m"), Units("second"))
def test_Units_conform(self): self.assertTrue(Units.conform(0.5, Units('km'), Units('m')) == 500) self.assertTrue( Units.conform(360, Units('second'), Units('minute')) == 6) with self.assertRaises(ValueError): Units.conform(1, Units('m'), Units('second'))