Completed
Push — develop ( 6f2955...d01bab )
by Adam
11s
created

MsiRSR._load()   C

Complexity

Conditions 7

Size

Total Lines 33

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
c 1
b 0
f 0
dl 0
loc 33
rs 5.5
1
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3
4
# Copyright (c) 2018 Adam.Dybbroe
5
6
# Author(s):
7
8
#   Adam.Dybbroe <[email protected]>
9
10
# This program is free software: you can redistribute it and/or modify
11
# it under the terms of the GNU General Public License as published by
12
# the Free Software Foundation, either version 3 of the License, or
13
# (at your option) any later version.
14
15
# This program is distributed in the hope that it will be useful,
16
# but WITHOUT ANY WARRANTY; without even the implied warranty of
17
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
# GNU General Public License for more details.
19
20
# You should have received a copy of the GNU General Public License
21
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
23
"""
24
Reading the original agency formattet Sentinel-2 MSI relative spectral responses
25
26
https://earth.esa.int/documents/247904/685211/S2-SRF_COPE-GSEG-EOPG-TN-15-0007_3.0.xlsx
27
28
"""
29
30
import os
31
from xlrd import open_workbook
32
import numpy as np
33
from pyspectral.utils import convert2hdf5 as tohdf5
34
from pyspectral.raw_reader import InstrumentRSR
35
import logging
36
LOG = logging.getLogger(__name__)
37
38
39
MSI_BAND_NAMES = {}
40
MSI_BAND_NAMES['S2A'] = {'S2A_SR_AV_B1': 'B01',
41
                         'S2A_SR_AV_B2': 'B02',
42
                         'S2A_SR_AV_B3': 'B03',
43
                         'S2A_SR_AV_B4': 'B04',
44
                         'S2A_SR_AV_B5': 'B05',
45
                         'S2A_SR_AV_B6': 'B06',
46
                         'S2A_SR_AV_B7': 'B07',
47
                         'S2A_SR_AV_B8': 'B08',
48
                         'S2A_SR_AV_B8A': 'B8A',
49
                         'S2A_SR_AV_B9': 'B09',
50
                         'S2A_SR_AV_B10': 'B10',
51
                         'S2A_SR_AV_B11': 'B11',
52
                         'S2A_SR_AV_B12': 'B12'}
53
MSI_BAND_NAMES['S2B'] = {'S2B_SR_AV_B1': 'B01',
54
                         'S2B_SR_AV_B2': 'B02',
55
                         'S2B_SR_AV_B3': 'B03',
56
                         'S2B_SR_AV_B4': 'B04',
57
                         'S2B_SR_AV_B5': 'B05',
58
                         'S2B_SR_AV_B6': 'B06',
59
                         'S2B_SR_AV_B7': 'B07',
60
                         'S2B_SR_AV_B8': 'B08',
61
                         'S2B_SR_AV_B8A': 'B8A',
62
                         'S2B_SR_AV_B9': 'B09',
63
                         'S2B_SR_AV_B10': 'B10',
64
                         'S2B_SR_AV_B11': 'B11',
65
                         'S2B_SR_AV_B12': 'B12'}
66
67
SHEET_HEADERS = {'Spectral Responses (S2A)': 'S2A',
68
                 'Spectral Responses (S2B)': 'S2B'}
69
70
PLATFORM_SHORT_NAME = {'Sentinel-2A': 'S2A',
71
                       'Sentinel-2B': 'S2B'}
72
73
74
class MsiRSR(InstrumentRSR):
75
76
    """Class for Sentinel-2 MSI RSR"""
77
78
    def __init__(self, bandname, platform_name):
79
        """
80
        Read the Sentinel-2 MSI relative spectral responses for all channels.
81
82
        """
83
        super(MsiRSR, self).__init__(bandname, platform_name)
84
85
        self.instrument = 'msi'
86
        self._get_options_from_config()
87
88
        LOG.debug("Filename: %s", str(self.path))
89
        if os.path.exists(self.path):
90
            self._load()
91
        else:
92
            raise IOError("Couldn't find an existing file for this band: " +
93
                          str(self.bandname))
94
95
    def _load(self, scale=0.001):
96
        """Load the Sentinel-2 MSI relative spectral responses
97
        """
98
99
        with open_workbook(self.path) as wb_:
100
            for sheet in wb_.sheets():
101
                if sheet.name not in SHEET_HEADERS.keys():
102
                    continue
103
104
                plt_short_name = PLATFORM_SHORT_NAME.get(self.platform_name)
105
                if plt_short_name != SHEET_HEADERS.get(sheet.name):
106
                    continue
107
108
                wvl = sheet.col_values(0, 1)
109
                for idx in range(1, sheet.row_len(0)):
110
                    ch_name = MSI_BAND_NAMES[plt_short_name].get(str(sheet.col_values(idx, 0, 1)[0]))
111
                    if ch_name != self.bandname:
112
                        continue
113
114
                    resp = sheet.col_values(idx, 1)
115
                    resp = np.array(resp)
116
                    resp = np.where(resp == '', 0, resp).astype('float32')
117
                    mask = np.less_equal(resp, 0.00001)
118
                    wvl0 = np.ma.masked_array(wvl, mask=mask)
119
                    wvl_mask = np.ma.masked_outside(wvl, wvl0.min() - 2, wvl0.max() + 2)
120
121
                    wvl = wvl_mask.compressed()
122
                    resp = np.ma.masked_array(resp, mask=wvl_mask.mask).compressed()
123
                    self.rsr = {'wavelength': wvl / 1000., 'response': resp}
124
125
                    break
126
127
                break
128
129
130
def main():
131
    """Main"""
132
    bands = MSI_BAND_NAMES['S2A'].values()
133
    bands.sort()
134
    for platform_name in ['Sentinel-2A', ]:
135
        tohdf5(MsiRSR, platform_name, bands)
136
137
    bands = MSI_BAND_NAMES['S2B'].values()
138
    bands.sort()
139
    for platform_name in ['Sentinel-2B', ]:
140
        tohdf5(MsiRSR, platform_name, bands)
141
142
143
if __name__ == "__main__":
144
    main()
145