示例#1
0
def test_plot():
    pathlist = glob.glob(
        os.path.join('tests', 'data', 'datastore', 'BTCN', '*'))
    sm = SiteMeasurements.from_pathlist(
        pathlist)[dt.datetime(2018, 5, 28):dt.datetime(2018, 5, 29)]
    srfs = [Sentinel2Blue(), Sentinel2Green()]
    # make sure all below modes don't fail:
    for with_errors in [False, True]:
        for types in ['toa', 'sr', ['toa', 'sr']]:
            plot(types, sm, srfs, with_errors=with_errors, show=False)
示例#2
0
# some spectral plots
if (0):
    import numpy as np
    import matplotlib.pyplot as plt
    from calval.satellites.srf import Sentinel2Green, Sentinel2Red, Landsat8Blue, NewsatBlue, NewsatRed
    from pyspectral.solar import (SolarIrradianceSpectrum,
                                  TOTAL_IRRADIANCE_SPECTRUM_2000ASTM)
    srr = SolarIrradianceSpectrum(TOTAL_IRRADIANCE_SPECTRUM_2000ASTM,
                                  dlambda=0.0005)
    srr.interpolate(ival_wavelength=(0.200, 2.000))
    print(srr.units)
    print(srr.ipol_wavelength, srr.ipol_irradiance)

    plt.figure()
    plt.plot(srr.ipol_wavelength, srr.ipol_irradiance, 'k-.')
    srf = Sentinel2Green()
    x = srr.ipol_wavelength * 1000
    vals = srf(x) * srr.ipol_irradiance
    avg = np.dot(srf(x), srr.ipol_irradiance) / np.sum(srf(x))
    plt.plot(srr.ipol_wavelength, vals, 'g-')
    plt.plot([srf.start / 1000, srf.end / 1000], [avg, avg], 'g--')

    srf = Sentinel2Red()
    x = srr.ipol_wavelength * 1000
    vals = srf(x) * srr.ipol_irradiance
    avg = np.dot(srf(x), srr.ipol_irradiance) / np.sum(srf(x))
    plt.plot(srr.ipol_wavelength, vals, 'r-')
    plt.plot([srf.start / 1000, srf.end / 1000], [avg, avg], 'r--')

    srf = Landsat8Blue()
    x = srr.ipol_wavelength * 1000
示例#3
0
 def __init__(self):
     super().__init__([
         Sentinel2Blue(), Sentinel2Green(), Sentinel2Red()
     ])
示例#4
0
def test_plot():
    # checks plot_srf doesn't fail
    srfs = [Sentinel2Red(), Sentinel2Green(), Sentinel2Blue()]
    plot_srfs(srfs, show=False, normalize_max=True)
示例#5
0
def test_sentinel():
    # comparing central wavelength to https://en.wikipedia.org/wiki/Sentinel-2
    assert Sentinel2Blue().center == pytest.approx(490, abs=10)
    assert Sentinel2Green().center == pytest.approx(560, abs=.10)
    assert Sentinel2Red().center == pytest.approx(665, abs=10)
    assert Sentinel2Nir().center == pytest.approx(833, abs=10)
示例#6
0
def test_as_dataframe():
    srf = Sentinel2Green()
    df = srf.as_dataframe()
    assert df['response'][srf.start] == srf(srf.start)
示例#7
0
class SentinelSceneData(SceneData):
    band_ex_irradiance = {
        _band_aliases['blue']: srf_exatmospheric_irradiance(Sentinel2Blue()),
        _band_aliases['green']: srf_exatmospheric_irradiance(Sentinel2Green()),
        _band_aliases['red']: srf_exatmospheric_irradiance(Sentinel2Red()),
        _band_aliases['nir']: srf_exatmospheric_irradiance(Sentinel2Nir())
    }

    def __init__(self, sceneinfo, path=None):
        super().__init__(sceneinfo, path)
        self.granule = self.sceneinfo._get_granule()
        self._read_product_metadata()
        self._read_l1_metadata()

    def _granule_mtd_path(self):
        return os.path.join(self.path, 'GRANULE', self.granule, 'MTD_TL.xml')

    def _product_mtd_path(self):
        return os.path.join(self.path,
                            'MTD_{}.xml'.format(self.sceneinfo._data.product))

    def _read_product_metadata(self):
        self.product_meta = metadata = parse_xml_metadata(
            self._product_mtd_path())
        data = metadata['General_Info']['Product_Image_Characteristics'][
            'Reflectance_Conversion']
        self.esuns = [
            data['Solar_Irradiance_List']['SOLAR_IRRADIANCE_{}'.format(
                _band_id(_band_aliases[band]))] for band in band_names
        ]
        self.sun_distance = np.sqrt(
            1.0 / data['U'])  # assuming U is `d(t)` of the TG
        data = metadata['Geometric_Info']['Product_Footprint'][
            'Product_Footprint']
        coords = data['Global_Footprint']['EXT_POS_LIST']
        self.corners = [(coords[i + 1], coords[i]) for i in range(0, 8, 2)]
        self.center = tuple(np.average(self.corners, axis=0))
        self.cloud_coverage = metadata['Quality_Indicators_Info'][
            'Cloud_Coverage_Assessment']

    def _read_l1_metadata(self):
        self.metadata = metadata = parse_tile_metadata(
            self._granule_mtd_path())
        self.timestamp = metadata['General_Info']['SENSING_TIME']

        def _view_angle(bandid):
            mean_view_list = metadata['Geometric_Info']['Tile_Angles'][
                'Mean_Viewing_Incidence_Angle_List']
            return mean_view_list['Mean_Viewing_Incidence_Angle_{}'.format(
                bandid)]

        assert _view_angle(_band_id(
            _band_aliases['green']))['AZIMUTH_ANGLE_unit'] == 'deg'
        # NOTE: Seem to be large differences between viewing angles of the channels
        # TODO: make per-channel calcs!
        angles = [
            _view_angle(_band_id(_band_aliases[band]))['AZIMUTH_ANGLE']
            for band in band_names
        ]
        view_average_azimuth = np.average(angles)
        angles = [
            _view_angle(_band_id(_band_aliases[band]))['ZENITH_ANGLE']
            for band in band_names
        ]
        view_average_zenith = np.average(angles)
        self.sat_average_angle = IncidenceAngle(view_average_azimuth,
                                                90 - view_average_zenith)
        sun_azimuth = metadata['Geometric_Info']['Tile_Angles'][
            'Mean_Sun_Angle']['AZIMUTH_ANGLE']
        sun_zenith = metadata['Geometric_Info']['Tile_Angles'][
            'Mean_Sun_Angle']['ZENITH_ANGLE']
        self.sun_average_angle = IncidenceAngle(sun_azimuth, 90 - sun_zenith)

    def get_metadata(self):
        meta = {
            'center': self.center,
            'esuns': self.esuns,
            'sun_distance': self.sun_distance,  # based on `U` from metadata
            'sat_average_angle': self.sat_average_angle.to_dict(),
            'sun_average_angle': self.sun_average_angle.to_dict(),
            'cloud_cover': self.cloud_coverage
        }
        return meta

    def get_scale(self, band, product):
        """ TODO: compute from metadata """
        return _scale_values[product]