Completed
Pull Request — develop (#23)
by Adam
23s
created

MsiRSR   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 54
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 54
rs 10
wmc 9

2 Methods

Rating   Name   Duplication   Size   Complexity  
C _load() 0 33 7
A __init__() 0 16 2
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
31
import os
32
from xlrd import open_workbook
33
import numpy as np
34
from pyspectral.utils import convert2hdf5 as tohdf5
35
36
import logging
37
LOG = logging.getLogger(__name__)
38
39
from pyspectral.config import get_config
40
from pyspectral.raw_reader import InstrumentRSR
41
42
MSI_BAND_NAMES = {}
43
MSI_BAND_NAMES['S2A'] = {'S2A_SR_AV_B1': 'B01',
44
                         'S2A_SR_AV_B2': 'B02',
45
                         'S2A_SR_AV_B3': 'B03',
46
                         'S2A_SR_AV_B4': 'B04',
47
                         'S2A_SR_AV_B5': 'B05',
48
                         'S2A_SR_AV_B6': 'B06',
49
                         'S2A_SR_AV_B7': 'B07',
50
                         'S2A_SR_AV_B8': 'B08',
51
                         'S2A_SR_AV_B8A': 'B8A',
52
                         'S2A_SR_AV_B9': 'B09',
53
                         'S2A_SR_AV_B10': 'B10',
54
                         'S2A_SR_AV_B11': 'B11',
55
                         'S2A_SR_AV_B12': 'B12'}
56
MSI_BAND_NAMES['S2B'] = {'S2B_SR_AV_B1': 'B01',
57
                         'S2B_SR_AV_B2': 'B02',
58
                         'S2B_SR_AV_B3': 'B03',
59
                         'S2B_SR_AV_B4': 'B04',
60
                         'S2B_SR_AV_B5': 'B05',
61
                         'S2B_SR_AV_B6': 'B06',
62
                         'S2B_SR_AV_B7': 'B07',
63
                         'S2B_SR_AV_B8': 'B08',
64
                         'S2B_SR_AV_B8A': 'B8A',
65
                         'S2B_SR_AV_B9': 'B09',
66
                         'S2B_SR_AV_B10': 'B10',
67
                         'S2B_SR_AV_B11': 'B11',
68
                         'S2B_SR_AV_B12': 'B12'}
69
70
SHEET_HEADERS = {'Spectral Responses (S2A)': 'S2A',
71
                 'Spectral Responses (S2B)': 'S2B'}
72
73
PLATFORM_SHORT_NAME = {'Sentinel-2A': 'S2A',
74
                       'Sentinel-2B': 'S2B'}
75
76
77
class MsiRSR(InstrumentRSR):
78
79
    """Class for Sentinel-2 MSI RSR"""
80
81
    def __init__(self, bandname, platform_name):
82
        """
83
        Read the Sentinel-2 MSI relative spectral responses for all channels.
84
85
        """
86
        super(MsiRSR, self).__init__(bandname, platform_name)
87
88
        self.instrument = 'msi'
89
        self._get_options_from_config()
90
91
        LOG.debug("Filename: %s", str(self.path))
92
        if os.path.exists(self.path):
93
            self._load()
94
        else:
95
            raise IOError("Couldn't find an existing file for this band: " +
96
                          str(self.bandname))
97
98
    def _load(self, scale=0.001):
99
        """Load the Sentinel-2 MSI relative spectral responses
100
        """
101
102
        with open_workbook(self.path) as wb_:
103
            for sheet in wb_.sheets():
104
                if sheet.name not in SHEET_HEADERS.keys():
105
                    continue
106
107
                plt_short_name = PLATFORM_SHORT_NAME.get(self.platform_name)
108
                if plt_short_name != SHEET_HEADERS.get(sheet.name):
109
                    continue
110
111
                wvl = sheet.col_values(0, 1)
112
                for idx in range(1, sheet.row_len(0)):
113
                    ch_name = MSI_BAND_NAMES[plt_short_name].get(str(sheet.col_values(idx, 0, 1)[0]))
114
                    if ch_name != self.bandname:
115
                        continue
116
117
                    resp = sheet.col_values(idx, 1)
118
                    resp = np.array(resp)
119
                    resp = np.where(resp == '', 0, resp).astype('float32')
120
                    mask = np.less_equal(resp, 0.00001)
121
                    wvl0 = np.ma.masked_array(wvl, mask=mask)
122
                    wvl_mask = np.ma.masked_outside(wvl, wvl0.min() - 2, wvl0.max() + 2)
123
124
                    wvl = wvl_mask.compressed()
125
                    resp = np.ma.masked_array(resp, mask=wvl_mask.mask).compressed()
126
                    self.rsr = {'wavelength': wvl / 1000., 'response': resp}
127
128
                    break
129
130
                break
131
132
133
def main():
134
    """Main"""
135
    bands = MSI_BAND_NAMES['S2A'].values()
136
    bands.sort()
137
    for platform_name in ['Sentinel-2A', ]:
138
        tohdf5(MsiRSR, platform_name, bands)
139
140
    bands = MSI_BAND_NAMES['S2B'].values()
141
    bands.sort()
142
    for platform_name in ['Sentinel-2B', ]:
143
        tohdf5(MsiRSR, platform_name, bands)
144
145
146
if __name__ == "__main__":
147
    main()
148
149
    #this = MsiRSR('ch5', 'Sentinel-2A')
150