OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
meta.py
Go to the documentation of this file.
1 import numpy as np
2 
3 SENSOR_LABEL = { # http://www.ioccg.org/sensors/seawifs.html
4  'CZCS' : 'Nimbus-7',
5  'TM' : 'Landsat-5',
6  'ETM' : 'Landsat-7',
7  'OLI' : 'Landsat-8',
8  'OSMI' : 'Arirang-1',
9  'POLDER' : 'POLDER',
10  'AER' : 'AERONET',
11  'OCTS' : 'ADEOS-1',
12  'SEAWIFS': 'OrbView-2',
13  'VI' : 'Suomi-NPP',
14  'MOS' : 'MOS-1',
15  'MOD' : 'MODIS',
16  'MODA' : 'MODIS-Aqua',
17  'MODT' : 'MODIS-Terra',
18  'MSI' : 'Sentinel-2',
19  'S2A' : 'Sentinel-2A',
20  'S2B' : 'Sentinel-2B',
21  'OLCI' : 'Sentinel-3',
22  'MERIS' : 'Envisat-1',
23  'HICO' : 'HICO',
24  'HYPER' : '1nm Hyperspectral',
25  'PRISMA' : 'PRISMA',
26 }
27 
28 def get_sensor_label(sensor):
29  sensor, *ext = sensor.split('-')
30  assert(sensor in SENSOR_LABEL), f'Unknown sensor: {sensor}'
31 
32  label = SENSOR_LABEL[sensor]
33  if 'pan' in ext:
34  label += '+Pan'
35  return label
36 
37 # --------------------------------------------------------------
38 
39 SENSOR_BANDS = {
40  'CZCS' : [ 443, 520, 550, 670 ],
41  'TM' : [ 490, 560, 660 ],
42  'ETM' : [ 483, 560, 662 ],
43  'ETM-pan' : [ 483, 560, 662, 706],
44  'OLI' : [ 443, 482, 561, 655 ],
45  'OLI-SOLID' : [ 443, 482, 561, 655 ],
46  'OLI-pan' : [ 443, 482, 561, 589, 655, ],
47  'OLI-full' : [ 443, 482, 561, 655, 865],
48  'OLI-nan' : [ 443, 482, 561, 589, 655, 865],
49  'OLI-rho' : [ 443, 482, 561, 655, 865, 1609],
50  'OSMI' : [412, 443, 490, 555, 765 ],
51  'POLDER' : [ 443, 490, 565, 670, 765 ],
52  'AER' : [412, 442, 490, 560, 668 ],
53  'OCTS' : [412, 443, 490, 520, 565, 670, 765 ],
54  'SEAWIFS' : [412, 443, 490, 510, 555, 670, 765 ],
55  'VI' : [410, 443, 486, 551, 671, 745 ],
56  'VI-SOLID' : [410, 443, 486, 551, 671, ],
57  'MOS' : [408, 443, 485, 520, 570, 615, 650, 685, 750 ],
58  'MOD' : [412, 443, 469, 488, 531, 551, 555, 645, 667, 678, 748 ],
59  'MOD-IOP' : [412, 443, 469, 488, 531, 551, 555, 645, 667, 678, ],
60  'MOD-sat' : [412, 443, 469, 488, 531, 551, 555, 645, 667, 678, ],
61  'MOD-poly' : [412, 443, 488, 531, 551, 667, 678, 748 ],
62  'MOD-SOLID' : [412, 443, 488, 551, 667, 678, ],
63  'MSI' : [ 443, 490, 560, 665, 705, 740, 783],
64  'MSI-SOLID' : [ 443, 490, 560, 665, 705, ],
65  'MSI-rho' : [ 443, 490, 560, 665, 705, 740, 783, 865],
66  'OLCI' : [411, 442, 490, 510, 560, 619, 664, 673, 681, 708, 753, 778],
67  'OLCI-full' : [411, 442, 490, 510, 560, 619, 664, 673, 681, 708, 753, 761, 764, 767, 778],
68  'OLCI-poly' : [411, 442, 490, 510, 560, 619, 664, 681, 708, 753, 778],
69  'OLCI-sam' : [411, 442, 490, 510, 560, 619, 664, 673, 681, 708, 753, ],
70  'OLCI-SOLID': [411, 442, 490, 510, 560, 619, 664, 673, 681, ],
71  'MERIS' : [412, 442, 490, 510, 560, 620, 665, 681, 708, 753, 760, 778],
72 
73  'HICO-full' : [409, 415, 421, 426, 432, 438, 444, 449, 455, 461, 467, 472, 478, 484, 490, 495, 501, 507,
74  512, 518, 524, 530, 535, 541, 547, 553, 558, 564, 570, 575, 581, 587, 593, 598, 604, 610,
75  616, 621, 627, 633, 638, 644, 650, 656, 661, 667, 673, 679, 684, 690, 696, 701, 707, 713,
76  719, 724, 730, 736, 742, 747, 753, 759, 764, 770, 776, 782, 787],
77  # 'HICO-chl' : [501, 507, 512, 518, 524, 530, 535, 541, 547, 553, 558, 564, 570, 575, 581, 587, 593, 598,
78  # 604, 610, 616, 621, 627, 633, 638, 644, 650, 656, 661, 667, 673, 679, 684, 690, 696, 701,
79  # 707, 713],
80  'HICO-IOP' : [409, 415, 421, 426, 432, 438, 444, 449, 455, 461, 467, 472, 478, 484, 490, 495, 501, 507,
81  512, 518, 524, 530, 535, 541, 547, 553, 558, 564, 570, 575, 581, 587, 593, 598, 604, 610,
82  616, 621, 627, 633, 638, 644, 650, 656, 661, 667, 673, 679, 684, 690], # absorption data becomes negative > 690nm
83  'HICO' : [409, 415, 421, 426, 432, 438, 444, 449, 455, 461, 467, 472, 478, 484, 490, 495, 501, 507,
84  512, 518, 524, 530, 535, 541, 547, 553, 558, 564, 570, 575, 581, 587, 593, 598, 604, 610,
85  616, 621, 627, 633, 638, 644, 650, 656, 661, 667, 673, 679, 684, 690, 696, 701, 707, 713],
86  'HICO-sat' : [501, 507,
87  512, 518, 524, 530, 535, 541, 547, 553, 558, 564, 570, 575, 581, 587, 593, 598, 604, 610,
88  616, 621, 627, 633, 638, 644, 650, 656, 661, 667, 673, 679, 684, 690, 696, 701, 707, 713,
89  719, 724],
90 
91  'PRISMA-sat': [500, 507, 515, 523, 530, 538, 546, 554, 563, 571, 579, 588, 596, 605, 614, 623, 632, 641, 651,
92  660, 670, 679, 689, 699, 709, 719],
93  'PRISMA' : [411, 419, 427, 434, 441, 449, 456, 464, 471, 478, 485, 493, 500, 507, 515, 523, 530, 538,
94  546, 554, 563, 571, 579, 588, 596, 605, 614, 623, 632, 641, 651, 660, 670, 679, 689, 699,
95  709, 719, 729, 739, 749, 760, 770, 781, 791],
96 
97  'HYPER' : list(range(400, 799)),
98  'HYPER-nan' : list(range(400, 801)),
99 }
100 
101 duplicates = {
102  'MOD' : ['MODA', 'MODT'],
103  'MSI' : ['S2A', 'S2B'],
104 }
105 
106 # Add duplicate sensors
107 for sensor in list(SENSOR_BANDS.keys()):
108  for sensor2, dups in duplicates.items():
109  if sensor2 in sensor:
110  for dup in dups:
111  SENSOR_BANDS[sensor.replace(sensor2, dup)] = SENSOR_BANDS[sensor]
112 
113 
114 def get_sensor_bands(sensor, args=None):
115  assert(sensor in SENSOR_BANDS), f'Unknown sensor: {sensor}'
116  bands = set()
117  if args is not None:
118 
119  # Specific bands can be passed via args in order to override those used
120  if hasattr(args, 'bands'):
121  return np.array(args.bands.split(',') if isinstance(bands, str) else args.bands)
122 
123  # The provided bands can change if satellite bands with certain products are requested
124  elif args.sat_bands:
125  product_keys = {
126  'chl' : ['chl'],
127  'IOP' : ['aph', 'a*ph', 'ag', 'ad'],
128  }
129 
130  for key, products in product_keys.items():
131  for product in args.product.split(','):
132  if (f'{sensor}-{key}' in SENSOR_BANDS) and (product in products):
133  bands |= set(SENSOR_BANDS[f'{sensor}-{key}'])
134 
135  if len(bands) == 0 and f'{sensor}-sat' in SENSOR_BANDS:
136  sensor = f'{sensor}-sat'
137 
138  if len(bands) == 0:
139  bands = SENSOR_BANDS[sensor]
140  return np.sort(list(bands))
141 
142 # --------------------------------------------------------------
143 
144 # Ancillary parameters for certain models
145 ANCILLARY = [
146  'humidity', # Relative humidity (%)
147  'ice_frac', # Ice fraction (0=no ice, 1=all ice)
148  'no2_frac', # Fraction of tropospheric NO2 above 200m
149  'no2_strat', # Stratospheric NO2 (molecules/cm^2)
150  'no2_tropo', # Tropospheric NO2 (molecules/cm^2)
151  'ozone', # Ozone concentration (cm)
152  'pressure', # Surface pressure (millibars)
153  'mwind', # Meridional wind speed @ 10m (m/s)
154  'zwind', # Zonal wind speed @ 10m (m/s)
155  'windangle', # Wind direction @ 10m (degree)
156  'windspeed', # Wind speed @ 10m (m/s)
157  'scattang', # Scattering angle (degree)
158  'senz', # Sensor zenith angle (degree)
159  'sola', # Solar azimuth angle (degree)
160  'solz', # Solar zenith angle (degree)
161  'water_vapor', # Precipitable water vapor (g/cm^2)
162  'time_diff', # Difference between in situ measurement and satellite overpass (in situ prior to overpass = negative)
163 ]
164 
165 # Ancillary parameters which are periodic (e.g. 0 degrees == 360 degrees)
166 PERIODIC = [
167  'windangle',
168 ]
list(APPEND LIBS ${PGSTK_LIBRARIES}) add_executable(atteph_info_modis atteph_info_modis.c) target_link_libraries(atteph_info_modis $
Definition: CMakeLists.txt:7
def get_sensor_bands(sensor, args=None)
Definition: meta.py:114
def get_sensor_label(sensor)
Definition: meta.py:28