definition_dicts.py 6.76 KB
Newer Older
1
2
3
4
5
6
7
# -*- coding: utf-8 -*-

import collections
import re

import numpy as np

8
9
from ..config import GMS_config as CFG

10
11
12
13
14
15
16
17
18
19
20
21
__author__ = 'Daniel Scheffler'

dtype_lib_Python_IDL = {'bool_': 0, 'uint8': 1, 'int8': 1, 'int_': 1, 'int16': 2, 'uint16': 12, 'int32': 3,
                        'uint32': 13, 'int64': 14, 'uint64': 15, 'float32': 4, 'float64': 5, 'complex_': 6,
                        'complex64': 9}
dtype_lib_IDL_Python = {0: np.bool_, 1: np.uint8, 2: np.int16, 3: np.int32, 4: np.float32, 5: np.float64,
                        6: np.complex64, 9: np.complex128, 12: np.uint16, 13: np.uint32, 14: np.int64, 15: np.uint64}
dtype_lib_GDAL_Python = {"uint8": 1, "int8": 1, "uint16": 2, "int16": 3, "uint32": 4, "int32": 5, "float32": 6,
                         "float64": 7, "complex64": 10, "complex128": 11}
proc_chain = ['L1A', 'L1B', 'L1C', 'L2A', 'L2B', 'L2C']
db_jobs_statistics_def = {'downloaded': 1, 'started': 2, None: 2, 'L1A': 3, 'L1B': 4, 'L1C': 5, 'L2A': 6, 'L2B': 7,
                          'L2C': 8, 'FAILED': 9}
22
23
24


def get_GMS_sensorcode(GMS_identifier):
25
26
    # type: (dict) -> str

27
28
29
    Satellite, Sensor, Subsystem = (GMS_identifier['Satellite'], GMS_identifier['Sensor'], GMS_identifier['Subsystem'])
    Sensor = Sensor[:-1] if re.match('SPOT', Satellite, re.I) and Sensor[-1] not in ['1', '2'] else Sensor
    meta_sensorcode = Satellite + '_' + Sensor + ('_' + Subsystem if Subsystem not in ["", None] else "")
30
    sensorcode_dic = {
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
        'ALOS_AVNIR-2': 'AVNIR-2',
        'Landsat-4_TM': 'TM4',  # call from layerstacker
        'Landsat-4_TM_SAM': 'TM4',  # call from metadata object
        'Landsat-5_TM': 'TM5',
        'Landsat-5_TM_SAM': 'TM5',
        'Landsat-7_ETM+': 'TM7',
        'Landsat-7_ETM+_SAM': 'TM7',
        'Landsat-8_OLI': 'LDCM',
        'Landsat-8_OLI_TIRS': 'LDCM',
        'Landsat-8_LDCM': 'LDCM',
        'SPOT-1_HRV1': 'SPOT1a',  # MS
        'SPOT-1_HRV2': 'SPOT1b',
        'SPOT-2_HRV1': 'SPOT2a',
        'SPOT-2_HRV2': 'SPOT2b',
        'SPOT-3_HRV1': 'SPOT3a',
        'SPOT-3_HRV2': 'SPOT3b',
        'SPOT-4_HRVIR1': 'SPOT4a',
        'SPOT-4_HRVIR2': 'SPOT4b',
        'SPOT-5_HRG1': 'SPOT5a',  # PAN HRG2A
        'SPOT-5_HRG2': 'SPOT5b',  # MS HRG2J
        'RapidEye-1_MSI': 'RE1',
        'RapidEye-2_MSI': 'RE2',
        'RapidEye-3_MSI': 'RE3',
        'RapidEye-4_MSI': 'RE4',
        'RapidEye-5_MSI': 'RE5',
        'SRTM_SRTM2': 'SRTM2',
        'Terra_ASTER': 'AST_full',
        'Terra_ASTER_VNIR1': 'AST_V1',
        'Terra_ASTER_VNIR2': 'AST_V2',
        'Terra_ASTER_SWIR': 'AST_S',
        'Terra_ASTER_TIR': 'AST_T',
        'Sentinel-2A_MSI': 'S2A_full',
        'Sentinel-2B_MSI': 'S2B_full',
        'Sentinel-2A_MSI_S2A10': 'S2A10',
        'Sentinel-2A_MSI_S2A20': 'S2A20',
        'Sentinel-2A_MSI_S2A60': 'S2A60',
        'Sentinel-2B_MSI_S2B10': 'S2B10',
        'Sentinel-2B_MSI_S2B20': 'S2B20',
        'Sentinel-2B_MSI_S2B60': 'S2B60'
70
71
72
73
74
    }
    try:
        return sensorcode_dic[meta_sensorcode]
    except KeyError:
        raise KeyError('Sensor %s is not included in sensorcode dictionary and can not be converted into GMS '
75
                       'sensorcode.' % meta_sensorcode)
76
77


78
def get_mask_classdefinition(maskname, satellite):
79
    if maskname == 'mask_nodata':
80
        return {'No data': 0,
81
                'Data': 1}
82
    elif maskname == 'mask_clouds':
83
        legends = {
84
            'FMASK': {
85
                'No Data': 0,
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
                'Clear': 1,
                'Cloud': 2,
                'Shadow': 3,
                'Snow': 4,
                'Water': 5},
            # seems to be outdated:
            # {'Clear Land': 0, 'Clear Water': 1, 'Cloud Shadow': 2, 'Snow': 3, 'Cloud': 4, 'No data': 255}
            'Classical Bayesian': {
                'Clear': 10,
                'Thick Clouds': 20,
                'Thin Clouds': 30,
                'Snow': 40},  # Classical Bayesian py_tools_ah
            'SICOR': {
                'Clear': 10,
                'Water': 20,
101
102
                'Shadow': 30,
                'Cirrus': 40,
103
104
105
                'Cloud': 50,
                'Snow': 60}  # SICOR
        }
106

107
        return legends[CFG.job.cloud_masking_algorithm[satellite]]
108
    else:
109
        raise ValueError("'%s' is not a supported mask name." % maskname)
110
111


Daniel Scheffler's avatar
Bugfix    
Daniel Scheffler committed
112
113
def get_mask_colormap(maskname):
    if maskname == 'mask_clouds':
114
115
116
        # return collections.OrderedDict(zip(['No data','Clear','Thick Clouds','Thin Clouds','Snow','Unknown Class'],
        #                                     [[0,0,0] ,[0,255,0],[80,80,80], [175,175,175],[255,255,255],[255,0,0]]))
        return collections.OrderedDict((
117
118
119
120
121
122
123
124
125
126
            ('No data', [0, 0, 0]),
            ('Clear', [0, 255, 0]),
            ('Water', [0, 0, 255]),
            ('Shadow', [50, 50, 50]),
            ('Cirrus', [175, 175, 175]),
            ('Cloud', [80, 80, 80]),
            ('Snow', [255, 255, 255]),
            ('Unknown Class', [255, 0, 0]),))
    else:
        return None
Daniel Scheffler's avatar
Bugfix    
Daniel Scheffler committed
127
128


129
130
131
def get_outFillZeroSaturated(dtype):
    """Returns the values for 'fill-', 'zero-' and 'saturated' pixels of an image
    to be written with regard to the target data type.
132

133
    :param dtype: data type of the image to be written"""
134

135
    dtype = str(np.dtype(dtype))
136
137
138
139
140
    assert dtype in ['bool', 'int8', 'uint8', 'int16', 'uint16', 'float32'], \
        "get_outFillZeroSaturated: Unknown dType: '%s'." % dtype
    dict_outFill = {'bool': None, 'int8': -128, 'uint8': 0, 'int16': -9999, 'uint16': 9999, 'float32': -9999.}
    dict_outZero = {'bool': None, 'int8': 0, 'uint8': 1, 'int16': 0, 'uint16': 0, 'float32': 0.}
    dict_outSaturated = {'bool': None, 'int8': 127, 'uint8': 256, 'int16': 32767, 'uint16': 65535, 'float32': 65535.}
141
142
143
    return dict_outFill[dtype], dict_outZero[dtype], dict_outSaturated[dtype]


144
145
146
147
148
149
150
151
152
153
154
def is_dataset_provided_as_fullScene(GMS_identifier):
    # type: (dict) -> bool
    """Returns True if the dataset belonging to the given GMS_identifier is provided as full scene and returns False if
     it is provided as multiple tiles.

    :param GMS_identifier:
    :return:
    """

    sensorcode = get_GMS_sensorcode(GMS_identifier)
    dict_fullScene_or_tiles = {
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
        'AVNIR-2': True,
        'AST_full': False,
        'AST_V1': True,
        'AST_V2': True,
        'AST_S': True,
        'AST_T': True,
        'TM4': True,
        'TM5': True,
        'TM7': True,
        'LDCM': True,
        'SPOT1a': True,
        'SPOT2a': True,
        'SPOT3a': True,
        'SPOT4a': True,
        'SPOT5a': True,
        'SPOT1b': True,
        'SPOT2b': True,
        'SPOT3b': True,
        'SPOT4b': True,
        'SPOT5b': True,
        'RE5': False,
        'S2A_full': False,  # FIXME this changed for S2 in 08/2016
        'S2A10': False,
        'S2A20': False,
        'S2A60': False,
        'S2B10': False,
        'S2B20': False,
        'S2B60': False, }
183
    return dict_fullScene_or_tiles[sensorcode]