Beispiel #1
0
def read_metadata(xmlbuffer):

    # Speciel decoders
    def dec_isoformat(rts):
        return datetime.strptime(rts, "%Y-%m-%dT%H:%M:%S.%fZ")
    def dec_orbit_number(rts):
        return int(rts[:5])    
    def dec_satellite_name(rts):
        return rts.replace('-', '')
    def dec_calibration_unit(rts):
        _trans = {'radar brightness': 'nrcs'}
        rts = rts.replace(' ', '-').lower()
        return rts

    attributes = {
        'product_level':  ('generalHeader/itemName', str),
        'satellite_name': ('productInfo/missionInfo/mission', dec_satellite_name),
        'orbit_number': ('productInfo/missionInfo/absOrbit', dec_orbit_number),
        'sensor_type': ('productInfo/acquisitionInfo/sensor', str),
        'beam_mode': ('productInfo/acquisitionInfo/imagingMode', str),
        'polarisation': ('productInfo/acquisitionInfo/polarisationList/polLayer', str),
        'beamid': ('productInfo/acquisitionInfo/elevationBeamConfiguration', str),
        'calibrated': ('productInfo/productVariantInfo/radiometricCorrection', str),
        'calibration_factor': ('calibration/calibrationConstant/calFactor', float),
        'calibration_beamid': ('calibration/calibrationConstant/beamID', str),
        'calibration_unit': ('productInfo/imageDataInfo/pixelValueID', dec_calibration_unit),
        'image_data_path': ('productComponents/imageData/file/location/path', str),
        'image_data_filename': ('productComponents/imageData/file/location/filename', str),
        'time_start': ('productInfo/sceneInfo/start/timeUTC', dec_isoformat),        
        'center_coor_lat': ('productInfo/sceneInfo/sceneCenterCoord/lat', float),
        'center_coor_lon': ('productInfo/sceneInfo/sceneCenterCoord/lon', float)
        }

    check_attributes = {'product_level': 'level 1b product',
                        'satellite_name': 'tsx',
                        'sensor_type': 'sar'}

    tree = etree.fromstring(xmlbuffer)
    
    # Check satellite, sensor and product level
    for key, val in check_attributes.items():
        try:
            path = attributes[key][0]
            attr = tree.xpath(path)[0].text.lower()
            if not attr.startswith(val):
                raise mipp.ReaderError("This does not look like a TSX SAR " +
                                       "Level 1B Product, %s is '%s' expected '%s'" %
                                       (key, attr, val))
        except IndexError:
            raise mipp.ReaderError("This does not look like a TSX SAR " +
                                   "Level 1B Product, could not find attribute '%s' (%s)" %
                                   (key, path))

    mda = Metadata()
    for key, val in attributes.items():
        setattr(mda, key, val[1](tree.xpath(val[0])[0].text))
    mda.image_filename = (mda.image_data_path + '/' + mda.image_data_filename)
    delattr(mda, 'image_data_path')
    delattr(mda, 'image_data_filename')
    return mda
Beispiel #2
0
def read_manifest(filename, **mdax):
    """Read a Sentinel-1 manifest file, and extract selected parameters.

    :Parameters:
        filename : str
            Path to manifest file.

    :Returns:
        manifest : Metadata object
            Selected paramters
    """
    def parse_orbit(elm):
        if elm.get('type').lower() == 'start':
            return int(elm.text)

    def parse_text(elm):
        return elm.text

    def parse_tolower(elm):
        return elm.text.lower()

    def parse_satellite(elm):
        if elm.text.lower().startswith('sen'):
            return elm.text.lower()

    def parse_time(elm):
        return datetime.strptime(elm.text, "%Y-%m-%dT%H:%M:%S.%f")

    def parse_coordinates(elm):
        cor = elm.text.split()
        arr = []
        for c in cor:
            y, x =  [float(i) for i in c.split(',')]
            arr.append((x, y))
        return arr

    def parse_files(elm):
        fname = elm.get('href')        
        if fname and fname.startswith('./measurement/'):
            return os.path.join(basedir, fname[2:])
    
    named_decoder = {
        '{http://www.esa.int/safe/sentinel-1.0}startTime': (
            'start_time', 1, parse_time),
        '{http://www.esa.int/safe/sentinel-1.0}stopTime': (
            'stop_time', 1, parse_time),
        '{http://www.opengis.net/gml}coordinates': (
            'coordinates', 1, parse_coordinates),
        '{http://www.esa.int/safe/sentinel-1.0}orbitNumber': (
            'orbit_number', 1, parse_orbit),
        '{http://www.esa.int/safe/sentinel-1.0/sentinel-1/sar/level-1}mode': (
            'instrument_mode', 1, parse_tolower),
        '{http://www.esa.int/safe/sentinel-1.0}familyName': (
            'satellite', 1, parse_satellite), # dublicated !
        '{http://www.esa.int/safe/sentinel-1.0/sentinel-1}pass': (
            'pass', 1, parse_tolower),
        '{http://www.esa.int/safe/sentinel-1.0/sentinel-1/sar/level-1}transmitterReceiverPolarisation': (
            'polarisations', 2, parse_tolower),
        '{http://www.esa.int/safe/sentinel-1.0/sentinel-1/sar/level-1}productClassDescription': (
            'description', 1, parse_text),
        '{http://www.esa.int/safe/sentinel-1.0/sentinel-1/sar/level-1}productType': (
            'product_type', 1, parse_tolower),
        'fileLocation': (
            'files', 2, parse_files),
        }

    tags = named_decoder.keys()

    manifest = Metadata()
    basedir = os.path.dirname(filename)

    with open(filename) as fp:
        xml = etree.parse(fp)
        for e in xml.getroot().iter():
            if e.tag in tags:
                name, count, decoder =  named_decoder[e.tag]
                value = decoder(e)
                if value:
                    if count > 1:
                        try: 
                            getattr(manifest, name).append(value)
                        except AttributeError:
                            setattr(manifest, name, [value])
                    else:
                        setattr(manifest, name, value)

    # Add extra metadata 
    for key, val in mdax.items():
        if not hasattr(manifest, key):
            setattr(manifest, key, val)

    try:
        resolution = manifest.resolution_class
        channels = {}
        for pol in manifest.polarisations:
            _text = '-'.join([manifest.mission_id, manifest.instrument_mode, manifest.product_type, pol])
            _name = '-'.join([manifest.instrument_mode, resolution, pol])
            for fn in manifest.files:
                if os.path.basename(fn).startswith(_text):
                    channels[_name] = fn
        manifest.channels = channels
        manifest.pixel_spacing = PIXEL_SPACING[manifest.instrument_mode + '-' + resolution]
    except AttributeError:
        pass
                
    return manifest
Beispiel #3
0
def read_metadata(xmlbuffer):

    # Speciel decoders
    def dec_isoformat(rts):
        return datetime.strptime(rts, "%Y-%m-%dT%H:%M:%S.%fZ")

    def dec_orbit_number(rts):
        return int(rts[:5])

    def dec_satellite_name(rts):
        return rts.replace('-', '')

    def dec_calibration_unit(rts):
        _trans = {'radar brightness': 'nrcs'}
        rts = rts.replace(' ', '-').lower()
        return rts

    attributes = {
        'product_level': ('generalHeader/itemName', str),
        'satellite_name':
        ('productInfo/missionInfo/mission', dec_satellite_name),
        'orbit_number': ('productInfo/missionInfo/absOrbit', dec_orbit_number),
        'sensor_type': ('productInfo/acquisitionInfo/sensor', str),
        'beam_mode': ('productInfo/acquisitionInfo/imagingMode', str),
        'polarisation':
        ('productInfo/acquisitionInfo/polarisationList/polLayer', str),
        'beamid':
        ('productInfo/acquisitionInfo/elevationBeamConfiguration', str),
        'calibrated': ('productInfo/productVariantInfo/radiometricCorrection',
                       str),
        'calibration_factor': ('calibration/calibrationConstant/calFactor',
                               float),
        'calibration_beamid': ('calibration/calibrationConstant/beamID', str),
        'calibration_unit': ('productInfo/imageDataInfo/pixelValueID',
                             dec_calibration_unit),
        'image_data_path': ('productComponents/imageData/file/location/path',
                            str),
        'image_data_filename':
        ('productComponents/imageData/file/location/filename', str),
        'time_start': ('productInfo/sceneInfo/start/timeUTC', dec_isoformat),
        'center_coor_lat': ('productInfo/sceneInfo/sceneCenterCoord/lat',
                            float),
        'center_coor_lon': ('productInfo/sceneInfo/sceneCenterCoord/lon',
                            float)
    }

    check_attributes = {
        'product_level': 'level 1b product',
        'satellite_name': 'tsx',
        'sensor_type': 'sar'
    }

    tree = etree.fromstring(xmlbuffer)

    # Check satellite, sensor and product level
    for key, val in check_attributes.items():
        try:
            path = attributes[key][0]
            attr = tree.xpath(path)[0].text.lower()
            if not attr.startswith(val):
                raise mipp.ReaderError(
                    "This does not look like a TSX SAR " +
                    "Level 1B Product, %s is '%s' expected '%s'" %
                    (key, attr, val))
        except IndexError:
            raise mipp.ReaderError(
                "This does not look like a TSX SAR " +
                "Level 1B Product, could not find attribute '%s' (%s)" %
                (key, path))

    mda = Metadata()
    for key, val in attributes.items():
        setattr(mda, key, val[1](tree.xpath(val[0])[0].text))
    mda.image_filename = (mda.image_data_path + '/' + mda.image_data_filename)
    delattr(mda, 'image_data_path')
    delattr(mda, 'image_data_filename')
    return mda
Beispiel #4
0
def read_metadata(xmlbuffer):
    mda = Metadata()    

    # Speciel decoders
    def dec_timeformat(strn):
        strn = strn.split('.')        
        return (datetime.strptime(strn[0], "%Y-%m-%d %H:%M:%S") + 
                timedelta(seconds=float('.' + strn[1])))
    def dec_orbit_number(strn):
        return int(strn[:5])

    attributes = (
        ('_ROOT_/Attribute', {
                'Satellite ID': ('satellite_name', str),
                'Product Filename': ('image_filename', str),
                'Product Type': ('product_type', str),
                'Acquisition Station ID': ('facility_id', str),
                'Scene Sensing Start UTC': ('time_start', dec_timeformat),
                'Scene Sensing Stop UTC': ('time_stop', dec_timeformat),
                'Orbit Number': ('orbit_number', dec_orbit_number),
                'Sample Format': ('product_format', str),
                'Image Scale': ('image_scale', str),
                'Image Layers': ('layers', int),
                'Bits per Sample': ('bits_per_sample', int),
                'Samples per Pixel': ('samples_per_pixel', int),
                }),
        
        ('MBI/Attribute', {
                'Column Spacing': ('sample_spacing', float),
                'Line Spacing': ('line_spacing', float)
                }),

        ('S01/Attribute', {            
                'Polarisation': ('polarisation', str),
                }),
        )

    tree = etree.fromstring(xmlbuffer)

    #
    # Get Atrributes
    #
    for path, attr in attributes:
        names = attr.keys()
        path = tree.xpath(path)
        for i in path:
            name = i.attrib['Name']
            if name in names:
                names.remove(name)
                val = i.text
                setattr(mda, attr[name][0], attr[name][1](val))

    

    satid = 'CSK'
    if not mda.satellite_name.upper().startswith(satid):
        raise mipp.ReaderError(
            "This does not look like a CosmoSkymed product, " + 
            "satellite ID does now start with '%s'"%satid)

    mda.image_filename = os.path.splitext(mda.image_filename)[0] + '.MBI.tif'

    mda.no_data_value = 0
    mda.calibrated = 'NOTCALIBRATED'

    return mda
Beispiel #5
0
def read_metadata(xmlbuffer):
    mda = Metadata()

    # Speciel decoders
    def dec_timeformat(strn):
        strn = strn.split('.')
        return (datetime.strptime(strn[0], "%Y-%m-%d %H:%M:%S") +
                timedelta(seconds=float('.' + strn[1])))

    def dec_orbit_number(strn):
        return int(strn[:5])

    attributes = (
        ('_ROOT_/Attribute', {
            'Satellite ID': ('satellite_name', str),
            'Product Filename': ('image_filename', str),
            'Product Type': ('product_type', str),
            'Acquisition Station ID': ('facility_id', str),
            'Scene Sensing Start UTC': ('time_start', dec_timeformat),
            'Scene Sensing Stop UTC': ('time_stop', dec_timeformat),
            'Orbit Number': ('orbit_number', dec_orbit_number),
            'Sample Format': ('product_format', str),
            'Image Scale': ('image_scale', str),
            'Image Layers': ('layers', int),
            'Bits per Sample': ('bits_per_sample', int),
            'Samples per Pixel': ('samples_per_pixel', int),
        }),
        ('MBI/Attribute', {
            'Column Spacing': ('sample_spacing', float),
            'Line Spacing': ('line_spacing', float)
        }),
        ('S01/Attribute', {
            'Polarisation': ('polarisation', str),
        }),
    )

    tree = etree.fromstring(xmlbuffer)

    #
    # Get Atrributes
    #
    for path, attr in attributes:
        names = attr.keys()
        path = tree.xpath(path)
        for i in path:
            name = i.attrib['Name']
            if name in names:
                names.remove(name)
                val = i.text
                setattr(mda, attr[name][0], attr[name][1](val))

    satid = 'CSK'
    if not mda.satellite_name.upper().startswith(satid):
        raise mipp.ReaderError(
            "This does not look like a CosmoSkymed product, " +
            "satellite ID does now start with '%s'" % satid)

    mda.image_filename = os.path.splitext(mda.image_filename)[0] + '.MBI.tif'

    mda.no_data_value = 0
    mda.calibrated = 'NOTCALIBRATED'

    return mda
Beispiel #6
0
def read_manifest(filename, **mdax):
    """Read a Sentinel-1 manifest file, and extract selected parameters.

    :Parameters:
        filename : str
            Path to manifest file.

    :Returns:
        manifest : Metadata object
            Selected paramters
    """
    def parse_orbit(elm):
        if elm.get('type').lower() == 'start':
            return int(elm.text)

    def parse_text(elm):
        return elm.text

    def parse_tolower(elm):
        return elm.text.lower()

    def parse_satellite(elm):
        if elm.text.lower().startswith('sen'):
            return elm.text.lower()

    def parse_time(elm):
        return datetime.strptime(elm.text, "%Y-%m-%dT%H:%M:%S.%f")

    def parse_coordinates(elm):
        cor = elm.text.split()
        arr = []
        for c in cor:
            y, x = [float(i) for i in c.split(',')]
            arr.append((x, y))
        return arr

    def parse_files(elm):
        fname = elm.get('href')
        if fname and fname.startswith('./measurement/'):
            return os.path.join(basedir, fname[2:])

    named_decoder = {
        '{http://www.esa.int/safe/sentinel-1.0}startTime': ('start_time', 1,
                                                            parse_time),
        '{http://www.esa.int/safe/sentinel-1.0}stopTime': ('stop_time', 1,
                                                           parse_time),
        '{http://www.opengis.net/gml}coordinates': ('coordinates', 1,
                                                    parse_coordinates),
        '{http://www.esa.int/safe/sentinel-1.0}orbitNumber': ('orbit_number',
                                                              1, parse_orbit),
        '{http://www.esa.int/safe/sentinel-1.0/sentinel-1/sar/level-1}mode':
        ('instrument_mode', 1, parse_tolower),
        '{http://www.esa.int/safe/sentinel-1.0}familyName':
        ('satellite', 1, parse_satellite),  # dublicated !
        '{http://www.esa.int/safe/sentinel-1.0/sentinel-1}pass':
        ('pass', 1, parse_tolower),
        '{http://www.esa.int/safe/sentinel-1.0/sentinel-1/sar/level-1}transmitterReceiverPolarisation':
        ('polarisations', 2, parse_tolower),
        '{http://www.esa.int/safe/sentinel-1.0/sentinel-1/sar/level-1}productClassDescription':
        ('description', 1, parse_text),
        '{http://www.esa.int/safe/sentinel-1.0/sentinel-1/sar/level-1}productType':
        ('product_type', 1, parse_tolower),
        'fileLocation': ('files', 2, parse_files),
    }

    tags = named_decoder.keys()

    manifest = Metadata()
    basedir = os.path.dirname(filename)

    with open(filename) as fp:
        xml = etree.parse(fp)
        for e in xml.getroot().iter():
            if e.tag in tags:
                name, count, decoder = named_decoder[e.tag]
                value = decoder(e)
                if value:
                    if count > 1:
                        try:
                            getattr(manifest, name).append(value)
                        except AttributeError:
                            setattr(manifest, name, [value])
                    else:
                        setattr(manifest, name, value)

    # Add extra metadata
    for key, val in mdax.items():
        if not hasattr(manifest, key):
            setattr(manifest, key, val)

    try:
        resolution = manifest.resolution_class
        channels = {}
        for pol in manifest.polarisations:
            _text = '-'.join([
                manifest.mission_id, manifest.instrument_mode,
                manifest.product_type, pol
            ])
            _name = '-'.join([manifest.instrument_mode, resolution, pol])
            for fn in manifest.files:
                if os.path.basename(fn).startswith(_text):
                    channels[_name] = fn
        manifest.channels = channels
        manifest.pixel_spacing = PIXEL_SPACING[manifest.instrument_mode + '-' +
                                               resolution]
    except AttributeError:
        pass

    return manifest
Beispiel #7
0
def read_metadata(xml_file):
    metadata = Metadata()

    # XML Namespace
    ns_rs2 = {'xsi': 'http://www.rsi.ca/rs2/prod/xml/schemas'}

    # Speciel decoders
    def dec_isoformat(rts):
        return datetime.strptime(rts, "%Y-%m-%dT%H:%M:%S.%fZ")

    def dec_orbit_number(rts):
        return int(rts[:5])

    attributes = {
        'product_id': ('xsi:productId', str),
        'satellite_name': ('xsi:sourceAttributes/xsi:satellite', str),
        'sensor_name': ('xsi:sourceAttributes/xsi:sensor', str),
        'beam_mode': ('xsi:sourceAttributes/xsi:beamModeMnemonic', str),
        'facility_id': ('xsi:sourceAttributes/xsi:inputDatasetFacilityId',
                        str),
        'start_time': ('xsi:sourceAttributes/xsi:rawDataStartTime',
                       dec_isoformat),
        'orbit_number':
        ('xsi:sourceAttributes/xsi:orbitAndAttitude/xsi:orbitInformation/xsi:orbitDataFile',
         dec_orbit_number),
        'product_format': ('xsi:imageAttributes/xsi:productFormat', str),
        'bits_per_sample':
        ('xsi:imageAttributes/xsi:rasterAttributes/xsi:bitsPerSample', int),
        'samples':
        ('xsi:imageAttributes/xsi:rasterAttributes/xsi:numberOfSamplesPerLine',
         int),
        'lines': ('xsi:imageAttributes/xsi:rasterAttributes/xsi:numberOfLines',
                  int),
        'sample_spacing':
        ('xsi:imageAttributes/xsi:rasterAttributes/xsi:sampledPixelSpacing',
         float),
        'line_spacing':
        ('xsi:imageAttributes/xsi:rasterAttributes/xsi:sampledLineSpacing',
         float),
        'data_files': ('xsi:imageAttributes/xsi:fullResolutionImageData', str),
        'center_lat': ('centre_lat', str),
        'center_lon': ('centre_lon', str),
        'tie_point_lines': ('tie_point_lines', str),
        'tie_point_samples': ('tie_point_samples', str),
        'tie_point_line_jump': ('tie_point_line_jump', str),
        'tie_point_sample_jump': ('tie_point_sample_jump', str)
    }

    tree = etree.parse(xml_file)

    # Get some attributes
    for key, (att, dec) in attributes.items():
        if att.startswith('xsi'):
            rec = tree.xpath(att, namespaces=ns_rs2)
            if len(rec) > 1:
                val = tuple([dec(i.text) for i in rec])
            else:
                val = dec(rec[0].text)
            setattr(metadata, key, val)

    #
    # Get tiepoints
    #
    tiepoints_xpath = 'xsi:imageAttributes/xsi:geographicInformation/xsi:geolocationGrid/xsi:imageTiePoint'
    tiepoints_tree = tree.xpath(tiepoints_xpath, namespaces=ns_rs2)
    tiepoints_count = len(tiepoints_tree)

    pix_coordinates = numpy.zeros((tiepoints_count, 2))
    geo_coordinates = numpy.zeros((tiepoints_count, 2))
    counter = 0
    for elm in tiepoints_tree:
        if elm.tag.endswith('imageTiePoint'):
            pixel, line, lat, lon = None, None, None, None
            for i in elm.iter():
                if i.getparent().tag.endswith('imageCoordinate'):
                    if i.tag.endswith('pixel'):
                        pixel = float(i.text)
                    elif i.tag.endswith('line'):
                        line = float(i.text)
                elif i.getparent().tag.endswith('geodeticCoordinate'):
                    if i.tag.endswith('latitude'):
                        lat = float(i.text)
                    elif i.tag.endswith('longitude'):
                        lon = float(i.text)
            if None not in (pixel, line, lat, lon):
                pix_coordinates[counter] = [line, pixel]
                geo_coordinates[counter] = [lat, lon]
        counter += 1

    if counter > 0:
        setattr(metadata, 'tiepoints',
                TiePoints(pix_coordinates, geo_coordinates))

    return metadata