def _get_ancillary_metadata(mtl_doc, wo_doc, mtl_name_offset=None, order_dir_offset=None, properties_offsets=None): #: :type: Path specified_path = _get_node_text( order_dir_offset, wo_doc, Path) if order_dir_offset and wo_doc else None used_file_name = _get( mtl_doc, *mtl_name_offset) if mtl_name_offset and mtl_doc else None # Read any properties of the ancillary file form the MTL. properties = {} if mtl_doc and properties_offsets: for property_name, offset in properties_offsets.items(): val = _get(mtl_doc, *offset) if val: properties[property_name] = val if not specified_path or not specified_path.exists(): _LOG.warning('No path found to locate ancillary file %s', used_file_name) # If there's no information of the ancillary, don't bother. if (not used_file_name) and (not properties): return None return ptype.AncillaryMetadata(name=used_file_name, properties=properties) if specified_path.is_file(): # They specified an exact file to Pinkmatter rather than a search directory. file_path = specified_path else: # Else is a directory. # Find the file that was used inside it. # No file was used by Pinkmatter (Eg. TIRS ancillary in an OLI dataset) if not used_file_name: return None file_path = _get_file(specified_path, used_file_name) _LOG.info('Found ancillary path %s', file_path) return ptype.AncillaryMetadata.from_file(file_path, properties=properties)
# ground_control_points_model=47, # geometric_rmse_model=4.582, # geometric_rmse_model_x=3.370, # geometric_rmse_model_y=3.104, bands={} ), lineage=ptype.LineageMetadata( algorithm=ptype.AlgorithmMetadata( name='LPGS', version='12.5.0', parameters={} ), ancillary_quality='DEFINITIVE', ancillary={ 'cpf': ptype.AncillaryMetadata( name='L7CPF20050101_20050331.09' ), # We have the properties (quality) of the ancillary but not the file. 'ephemeris': ptype.AncillaryMetadata( properties={'type': 'DEFINITIVE'} ) } ) ) class TestMtlRead(unittest.TestCase): def test_ls7_equivalence(self): assert_expected_mtl( Path(os.path.join(os.path.dirname(__file__), FILENAME)), EXPECTED_OUT
def fill_metadata(self, dataset, path, additional_files=()): """ :type additional_files: tuple[Path] :type dataset: ptype.DatasetMetadata :type path: Path :rtype: ptype.DatasetMetadata """ dataset.ga_level = 'P55' # Copy relevant fields from source nbar. if 'nbar' in dataset.lineage.source_datasets: source_ortho = dataset.lineage.source_datasets['nbar'] borrow_single_sourced_fields(dataset, source_ortho) # TODO, it'd be better to grab this from the images, but they're generated after # this code is run. Copying from Source will do for now dataset.grid_spatial = deepcopy( dataset.lineage.source_datasets['nbar'].grid_spatial) contiguous_data_bit = 0b100000000 dataset.grid_spatial.projection.valid_data = self.calculate_valid_data_region( path, contiguous_data_bit) dataset.format_ = ptype.FormatMetadata('GeoTIFF') with open(str(path.joinpath(self.METADATA_FILE))) as f: pq_metadata = yaml.load(f, Loader=Loader) if not dataset.lineage: dataset.lineage = ptype.LineageMetadata() dataset.lineage.algorithm = ptype.AlgorithmMetadata( name='pqa', version=str( pq_metadata['algorithm_information']['software_version']), doi=pq_metadata['algorithm_information']['pq_doi']) # Add ancillary files ancils = pq_metadata['ancillary'] ancil_files = {} for name, values in ancils.items(): ancil_files[name] = ptype.AncillaryMetadata( type_=name, name=values['data_source'], uri=values['data_file'], file_owner=values['user'], # PyYAML parses these as datetimes already. access_dt=values['accessed'], modification_dt=values['modified']) if ancil_files: dataset.lineage.ancillary = ancil_files product_flags = {} # Record which tests where run in 'product_flags' for test_name, val in pq_metadata['tests_run'].items(): product_flags['tested_%s' % test_name] = val dataset.product_flags = product_flags return dataset
def fill_metadata(self, dataset, path, additional_files=()): """ :type additional_files: tuple[Path] :type dataset: ptype.DatasetMetadata :type path: Path :rtype: ptype.DatasetMetadata """ with open(str(path.joinpath(self.METADATA_FILE))) as f: nbar_metadata = yaml.load(f, Loader=Loader) # Copy relevant fields from source ortho. if 'level1' in dataset.lineage.source_datasets: source_ortho = dataset.lineage.source_datasets['level1'] borrow_single_sourced_fields(dataset, source_ortho) # TODO, it'd be better to grab this from the images, but they're generated after # this code is run. Copying from Source will do for now dataset.grid_spatial = deepcopy( dataset.lineage.source_datasets['level1'].grid_spatial) dataset.grid_spatial.projection.valid_data = self.calculate_valid_data_region( path) if not dataset.lineage: dataset.lineage = ptype.LineageMetadata() self._fill_algorithm_information( dataset, nbar_metadata['algorithm_information']) dataset.product_doi = nbar_metadata['algorithm_information'][ 'arg25_doi'] # Extract ancillary file data and values parameters = {} ancils = nbar_metadata['ancillary_data'] brdfs = ancils.pop('brdf', {}) brdf_ancils = { '_'.join((band_name, 'brdf', ancil_type)): values for band_name, ancil_types in brdfs.items() for ancil_type, values in ancil_types.items() } ancils.update(brdf_ancils) # Add algorithm parameters for name, values in ancils.items(): parameters[name] = values['value'] if parameters: dataset.lineage.algorithm.parameters = parameters # Add ancillary files ancil_files = {} for name, values in ancils.items(): if 'data_file' not in values: continue ancil_files[name] = ptype.AncillaryMetadata( type_=name, name=values['data_file'].rpartition('/')[2], uri=values['data_file'], file_owner=values['user'], # PyYAML parses these as datetimes already. access_dt=values['accessed'], modification_dt=values['modified']) if ancil_files: dataset.lineage.ancillary = ancil_files # All NBARs are P54. (source: Lan Wei) dataset.ga_level = 'P54' dataset.format_ = ptype.FormatMetadata('GeoTIFF') return dataset
def _build_ls8_ortho(): _reset_runtime_id() return ptype.DatasetMetadata( id_=uuid.UUID('17b92c16-51d3-11e4-909d-005056bb6972'), ga_label='LS8_OLITIRS_OTH_P51_GALPGS01-002_101_078_20141012', product_type='GAORTHO01', creation_dt=dateutil.parser.parse('2014-10-12 05:46:20'), size_bytes=2386550 * 1024, platform=ptype.PlatformMetadata(code='LANDSAT-8'), instrument=ptype.InstrumentMetadata(name='OLI_TIRS', type_="Multi-Spectral", operation_mode='PUSH-BROOM'), format_=ptype.FormatMetadata(name='GeoTiff', version=1), extent=ptype.ExtentMetadata( reference_system='WGS84', coord=ptype.CoordPolygon(ul=ptype.Coord(lat=-24.97, lon=133.97969), ur=ptype.Coord(lat=-24.96826, lon=136.24838), lr=ptype.Coord(lat=-26.96338, lon=136.26962), ll=ptype.Coord(lat=-26.96528, lon=133.96233)), from_dt=dateutil.parser.parse("2014-10-12T00:55:54"), center_dt=dateutil.parser.parse("2014-10-12T00:56:06"), to_dt=dateutil.parser.parse("2014-10-12T00:56:18"), ), grid_spatial=ptype.GridSpatialMetadata( dimensions=[ ptype.DimensionMetadata(name='sample', resolution=25.0, size=9161), ptype.DimensionMetadata(name='line', resolution=25.0, size=9161) ], projection=ptype.ProjectionMetadata( centre_point=ptype.Point(511512.500000, 7127487.500000), geo_ref_points=ptype.PointPolygon( ul=ptype.Point(397012.5, 7237987.5), ur=ptype.Point(626012.5, 7237987.5), ll=ptype.Point(397012.5, 7016987.5), lr=ptype.Point(626012.5, 7016987.5)), datum='GDA94', ellipsoid='GRS80', point_in_pixel='UL', map_projection='UTM', resampling_option='CUBIC_CONVOLUTION', zone=-53)), browse={ 'medium': ptype.BrowseMetadata(path=Path( 'product/LS8_OLITIRS_OTH_P51_GALPGS01-032_101_078_20141012.jpg' ), file_type='image/jpg', cell_size=219.75, red_band=7, green_band=5, blue_band=1), 'full': ptype.BrowseMetadata(path=Path( 'LS8_OLITIRS_OTH_P51_GALPGS01-032_101_078_20141012_FR.jpg'), file_type='image/jpg', cell_size=25.0, red_band=7, green_band=5, blue_band=1) }, image=ptype.ImageMetadata( satellite_ref_point_start=ptype.Point(101, 78), cloud_cover_percentage=0, cloud_cover_details=None, sun_elevation=58.00268508, sun_azimuth=59.41814014, ground_control_points_model=420, geometric_rmse_model=4.610, geometric_rmse_model_x=3.527, geometric_rmse_model_y=2.968, # TODO: What are these two? viewing_incidence_angle_long_track=0, viewing_incidence_angle_x_track=0, bands={ 'coastal_aerosol': ptype.BandMetadata( path=Path('product/LC81010782014285LGN00_B1.TIF'), number=1, type_='reflective', cell_size=25.0, ), 'visible_blue': ptype.BandMetadata( path=Path('product/LC81010782014285LGN00_B2.TIF'), number=2, type_='reflective', cell_size=25.0, ), 'visible_green': ptype.BandMetadata( path=Path('product/LC81010782014285LGN00_B3.TIF'), number=3, type_='reflective', cell_size=25.0, ), 'visible_red': ptype.BandMetadata( path=Path('product/LC81010782014285LGN00_B4.TIF'), number=4, type_='reflective', cell_size=25.0, ), 'near_infrared': ptype.BandMetadata( path=Path('product/LC81010782014285LGN00_B5.TIF'), number=5, type_='reflective', cell_size=25.0, ), 'short_wave_infrared1': ptype.BandMetadata( path=Path('product/LC81010782014285LGN00_B6.TIF'), number=6, type_='reflective', cell_size=25.0, ), 'short_wave_infrared2': ptype.BandMetadata( path=Path('product/LC81010782014285LGN00_B7.TIF'), number=7, type_='reflective', cell_size=25.0, ), 'panchromatic': ptype.BandMetadata( path=Path('product/LC81010782014285LGN00_B8.TIF'), number=8, type_='panchromatic', cell_size=12.50, shape=ptype.Point(17761, 18241), ), 'cirrus': ptype.BandMetadata( path=Path('product/LC81010782014285LGN00_B9.TIF'), number=9, type_='atmosphere', ), 'thermal_infrared1': ptype.BandMetadata( path=Path('product/LC81010782014285LGN00_B10.TIF'), number=10, type_='thermal', cell_size=25.0, shape=ptype.Point(8881, 9121), ), 'thermal_infrared2': ptype.BandMetadata( path=Path('product/LC81010782014285LGN00_B11.TIF'), number=11, type_='thermal', cell_size=25.0, shape=ptype.Point(8881, 9121), ), 'quality': ptype.BandMetadata( path=Path('product/LC81010782014285LGN00_BQA.TIF'), number='QA', type_='quality', ) }), lineage=ptype.LineageMetadata( algorithm=ptype.AlgorithmMetadata( name='Pinkmatter Landsat Processor', version='3.3.3104', parameters={ 'resampling': 'CC', 'radiometric_correction': 'CPF', 'orientation': 'NUP', 'hemisphere': 'S', }), machine=ptype.MachineMetadata( hostname='rhe-jm-prod08.prod.lan', type_id='jobmanager', uname= 'Linux rhe-jm-dev08.dev.lan 2.6.32-279.22.1.el6.x86_64 #1 SMP Sun Oct ' '12 ' '09:21:40 EST 2014 x86_64 x86_64 x86_64 GNU/Linux'), ancillary={ 'cpf': ptype.AncillaryMetadata( name='L8CPF20141001_20141231.01', uri= '/eoancillarydata/sensor-specific/LANDSAT8/CalibrationParameterFile' '/L8CPF20141001_20141231.01'), 'bpf_tirs': ptype.AncillaryMetadata( name='LT8BPF20141012002432_20141012020301.01', uri= '/eoancillarydata/sensor-specific/LANDSAT8/BiasParameterFile/2014/10' '/LT8BPF20141012002432_20141012020301.01'), 'bpf_oli': ptype.AncillaryMetadata( name='LO8BPF20141012002825_20141012011100.01', uri= '/eoancillarydata/sensor-specific/LANDSAT8/BiasParameterFile/2014/10' '/LT8BPF20141012002432_20141012020301.01'), 'rlut': ptype.AncillaryMetadata(name='L8RLUT20130211_20431231v09.h5') }, source_datasets={'satellite_telemetry_data': _build_ls8_raw()}))
cloud_cover_percentage=0.01, sun_azimuth=59.57807899, sun_elevation=57.89670734, sun_earth_distance=0.998137, ground_control_points_model=420, geometric_rmse_model=4.61, geometric_rmse_model_x=2.968, geometric_rmse_model_y=3.527, bands={}), lineage=ptype.LineageMetadata( algorithm=ptype.AlgorithmMetadata(name='LPGS', version='2.3.0', parameters={}), ancillary={ 'rlut': ptype.AncillaryMetadata(name='L8RLUT20130211_20431231v09.h5'), 'bpf_tirs': ptype.AncillaryMetadata( name='LT8BPF20141012002432_20141012011154.02'), 'bpf_oli': ptype.AncillaryMetadata( name='LO8BPF20141012002825_20141012011100.01'), 'cpf': ptype.AncillaryMetadata(name='L8CPF20141001_20141231.01') })) class TestMtlRead(unittest.TestCase): def test_ls8_equivalence(self): assert_expected_mtl( Path(os.path.join(os.path.dirname(__file__), FILENAME)),