Due to the lapse in federal government funding, NASA is not updating this website. We sincerely regret this inconvenience.
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 ]
def get_sensor_bands(sensor, args=None)
Definition: meta.py:114
def get_sensor_label(sensor)
Definition: meta.py:28
list(APPEND LIBS ${NETCDF_LIBRARIES}) find_package(GSL REQUIRED) include_directories($
Definition: CMakeLists.txt:8