Skip to content

Commit

Permalink
Merge pull request #298 from pytroll/feature-sentinel-2-msi-reader
Browse files Browse the repository at this point in the history
Implement sentinel 2 MSI reader
  • Loading branch information
mraspaud authored May 22, 2018
2 parents e49c634 + b3c532c commit 40ea3e2
Show file tree
Hide file tree
Showing 3 changed files with 182 additions and 14 deletions.
137 changes: 137 additions & 0 deletions satpy/etc/composites/msi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
sensor_name: visir/msi


modifiers:

rayleigh_corrected:
compositor: !!python/name:satpy.composites.PSPRayleighReflectance
atmosphere: us-standard
aerosol_type: rayleigh_only
prerequisites:
- name: 'B04'
modifiers: [sunz_corrected]
optional_prerequisites:
- satellite_azimuth_angle
- satellite_zenith_angle
- solar_azimuth_angle
- solar_zenith_angle

rayleigh_corrected_marine_clean:
compositor: !!python/name:satpy.composites.PSPRayleighReflectance
atmosphere: us-standard
aerosol_type: marine_clean_aerosol
prerequisites:
- name: 'B04'
modifiers: [sunz_corrected]
optional_prerequisites:
- satellite_azimuth_angle
- satellite_zenith_angle
- solar_azimuth_angle
- solar_zenith_angle

rayleigh_corrected_marine_tropical:
compositor: !!python/name:satpy.composites.PSPRayleighReflectance
atmosphere: tropical
aerosol_type: marine_tropical_aerosol
prerequisites:
- name: 'B04'
modifiers: [sunz_corrected]
optional_prerequisites:
- satellite_azimuth_angle
- satellite_zenith_angle
- solar_azimuth_angle
- solar_zenith_angle

rayleigh_corrected_desert:
compositor: !!python/name:satpy.composites.PSPRayleighReflectance
atmosphere: tropical
aerosol_type: desert_aerosol
prerequisites:
- name: 'B04'
modifiers: [sunz_corrected]
optional_prerequisites:
- satellite_azimuth_angle
- satellite_zenith_angle
- solar_azimuth_angle
- solar_zenith_angle

rayleigh_corrected_land:
compositor: !!python/name:satpy.composites.PSPRayleighReflectance
atmosphere: us-standard
aerosol_type: continental_average_aerosol
prerequisites:
- name: 'B04'
modifiers: [sunz_corrected]
optional_prerequisites:
- satellite_azimuth_angle
- satellite_zenith_angle
- solar_azimuth_angle
- solar_zenith_angle


composites:
true_color:
compositor: !!python/name:satpy.composites.GenericCompositor
prerequisites:
- name: 'B04'
modifiers: [effective_solar_pathlength_corrected, rayleigh_corrected]
- name: 'B03'
modifiers: [effective_solar_pathlength_corrected, rayleigh_corrected]
- name: 'B02'
modifiers: [effective_solar_pathlength_corrected, rayleigh_corrected]
standard_name: true_color

true_color_land:
compositor: !!python/name:satpy.composites.GenericCompositor
prerequisites:
- name: 'B04'
modifiers: [effective_solar_pathlength_corrected, rayleigh_corrected_land]
- name: 'B03'
modifiers: [effective_solar_pathlength_corrected, rayleigh_corrected_land]
- name: 'B02'
modifiers: [effective_solar_pathlength_corrected, rayleigh_corrected_land]
standard_name: true_color

true_color_desert:
compositor: !!python/name:satpy.composites.GenericCompositor
prerequisites:
- name: 'B04'
modifiers: [effective_solar_pathlength_corrected, rayleigh_corrected_desert]
- name: 'B03'
modifiers: [effective_solar_pathlength_corrected, rayleigh_corrected_desert]
- name: 'B02'
modifiers: [effective_solar_pathlength_corrected, rayleigh_corrected_desert]
standard_name: true_color

true_color_marine_clean:
compositor: !!python/name:satpy.composites.GenericCompositor
prerequisites:
- name: 'B04'
modifiers: [effective_solar_pathlength_corrected, rayleigh_corrected_marine_clean]
- name: 'B03'
modifiers: [effective_solar_pathlength_corrected, rayleigh_corrected_marine_clean]
- name: 'B02'
modifiers: [effective_solar_pathlength_corrected, rayleigh_corrected_marine_clean]
standard_name: true_color

true_color_marine_tropical:
compositor: !!python/name:satpy.composites.GenericCompositor
prerequisites:
- name: 'B04'
modifiers: [effective_solar_pathlength_corrected, rayleigh_corrected_marine_tropical]
- name: 'B03'
modifiers: [effective_solar_pathlength_corrected, rayleigh_corrected_marine_tropical]
- name: 'B02'
modifiers: [effective_solar_pathlength_corrected, rayleigh_corrected_marine_tropical]
standard_name: true_color

true_color_raw:
compositor: !!python/name:satpy.composites.GenericCompositor
prerequisites:
- name: 'B04'
#modifiers: [effective_solar_pathlength_corrected]
- name: 'B03'
#modifiers: [effective_solar_pathlength_corrected]
- name: 'B02'
#modifiers: [effective_solar_pathlength_corrected]
standard_name: true_color
25 changes: 23 additions & 2 deletions satpy/etc/readers/safe_msi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,27 @@ datasets:
B01:
name: B01
sensor: MSI
wavelength: [1, 2, 3]
resolution: 50
wavelength: [0.415, 0.443, 0.470]
resolution: 60
file_type: safe_granule

B02:
name: B02
sensor: MSI
wavelength: [0.440, 0.490, 0.540]
resolution: 10
file_type: safe_granule

B03:
name: B03
sensor: MSI
wavelength: [0.540, 0.560, 0.580]
resolution: 10
file_type: safe_granule

B04:
name: B04
sensor: MSI
wavelength: [0.645, 0.665, 0.685]
resolution: 10
file_type: safe_granule
34 changes: 22 additions & 12 deletions satpy/readers/safe_msi.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,18 @@
"""

import logging
import os
import xml.etree.ElementTree as ET
# import os
# import xml.etree.ElementTree as ET

import glymur
import numpy as np
from osgeo import gdal
# from osgeo import gdal
from xarray import DataArray
from dask.array import from_delayed
from dask import delayed

from geotiepoints.geointerpolator import GeoInterpolator
from satpy.dataset import Dataset
from satpy import CHUNK_SIZE
# from geotiepoints.geointerpolator import GeoInterpolator
from satpy.readers.file_handlers import BaseFileHandler

logger = logging.getLogger(__name__)
Expand All @@ -54,14 +57,21 @@ def get_dataset(self, key, info):
return

logger.debug('Reading %s.', key.name)
QUANTIFICATION_VALUE = 10000
QUANTIFICATION_VALUE = 10000.
jp2 = glymur.Jp2k(self.filename)
data = jp2[:] / (QUANTIFICATION_VALUE + 0.0)

proj = Dataset(data,
copy=False,
units='%',
standard_name='reflectance')
bitdepth = 0
for seg in jp2.codestream.segment:
try:
bitdepth = max(bitdepth, seg.bitdepth[0])
except AttributeError:
pass
jp2.dtype = (np.uint8 if bitdepth <= 8 else np.uint16)
data = from_delayed(delayed(jp2.read)(), jp2.shape, jp2.dtype)
data = data.rechunk(CHUNK_SIZE) / QUANTIFICATION_VALUE * 100

proj = DataArray(data, dims=['y', 'x'])
proj.attrs = info.copy()
proj.attrs['units'] = '%'
return proj

@property
Expand Down

0 comments on commit 40ea3e2

Please sign in to comment.