OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
generate_gas_transmittance_tables.py
Go to the documentation of this file.
1 #!/usr/bin/env python3
2 # Amir Ibrahim - November 2017
3 
4 # IMPORTS
5 from datetime import datetime
6 import time
7 import os
8 import re
9 import sys
10 import numpy as np
11 import pandas as pd
12 from scipy.interpolate import interp1d
13 import requests
14 from netCDF4 import Dataset
15 import argparse
16 import json
17 import collections
18 from pathlib import Path
19 import tempfile
20 
21 __version__ = '1.3.0_2020-12-11'
22 global verbose
23 
24 # Define the sensor to generate the table
25 
26 
29 
30 #sensorInfoFile = os.path.join(os.environ['OCDATAROOT'] , 'common','SensorInfo.json')
31 #with open(sensorInfoFile, 'r') as myfile:
32 # sensorDefs=myfile.read()
33 #
34 
37 
38 sensors = collections.defaultdict(dict)
39 
40 sensors['modisa']['name'] = "MODIS-Aqua"
41 sensors['modisa']['rsr'] = "aqua_modis_RSR.nc"
42 sensors['modist']['name'] = "MODIS-Terra"
43 sensors['modist']['rsr'] = "terra_modis_RSR.nc"
44 sensors['seawifs']['name'] = "SeaWiFS"
45 sensors['seawifs']['rsr'] = "orbview-2_seawifs_RSR.nc"
46 sensors['meris']['name'] = "MERIS"
47 sensors['meris']['rsr'] = "envisat_meris_RSR.nc"
48 sensors['octs']['name'] = "OCTS"
49 sensors['octs']['rsr'] = "adeos_octs_RSR.nc"
50 sensors['czcs']['name'] = "CZCS"
51 sensors['czcs']['rsr'] = "nimbus-7_czcs_RSR.nc"
52 sensors['viirsn']['name'] = "VIIRS-SNPP"
53 sensors['viirsn']['rsr'] = "suomi-npp_viirs_RSR.nc"
54 sensors['viirsj1']['name'] = "VIIRS-JPSS1"
55 sensors['viirsj1']['rsr'] = "jpss-1_viirs_RSR.nc"
56 sensors['aviris']['name'] = "AVIRIS"
57 sensors['aviris']['rsr'] = "aviris_RSR.nc"
58 sensors['oci']['name'] = "OCI"
59 sensors['oci']['rsr'] = "pace_oci_RSR.nc"
60 sensors['s3aolci']['name'] = "OLCI-S3A"
61 sensors['s3aolci']['rsr'] = "sentinel-3a_olci_RSR.nc"
62 sensors['s3bolci']['name'] = "OLCI-S3B"
63 sensors['s3bolci']['rsr'] = "sentinel-3b_olci_RSR.nc"
64 sensors['hico']['name'] = "HICO"
65 sensors['hico']['rsr'] = "iss_hico_RSR.nc"
66 sensors['oli']['name'] = "Landsat-8 OLI"
67 sensors['oli']['rsr'] = "landsat-8_oli_RSR.nc"
68 sensors['goci']['name'] = "GOCI"
69 sensors['goci']['rsr'] = "coms_goci_RSR.nc"
70 sensors['ocm1']['name'] = "OCM-1"
71 sensors['ocm1']['rsr'] = "irs-p4_ocm_RSR.nc"
72 sensors['ocm2']['name'] = "OCM-2"
73 sensors['ocm2']['rsr'] = "oceansat-2_ocm-2_RSR.nc"
74 sensors['osmi']['name'] = "OSMI"
75 sensors['osmi']['rsr'] = "kompsat_osmi_RSR.nc"
76 sensors['misr']['name'] = "MISR"
77 sensors['misr']['rsr'] = "terra_misr_RSR.nc"
78 
79 
80 
81 
82 def gaussian(x, mu, sig):
83  ''' Calculate gaussian filter
84  Input: wavelength, band cetner, FWHM
85  Output: Guassian filter
86  '''
87  sig = sig/2.355
88  return np.exp(-np.power(x - mu, 2.) / (2 * np.power(sig, 2.)))
89 
90 def get_hico_Rsr (all_wl):
91  ''' Calculate HICO RSR - for testing and comparing to operational code
92  Input: Wavelength (nm) at which the RSR will be calculates,
93  for this exercise, use the water vapor tx wavelength
94  Output: hico band center, RSR
95  '''
96  hico_wl=np.array([352.528,444.176,535.824,627.472,719.12,810.768,902.416,994.064,
97  358.256,449.904,541.552,633.2,724.848,816.496,908.144,999.79,
98  363.984,455.632,547.28,638.928,730.576,822.224,913.872,1005.52,
99  369.712,461.36,553.008,644.656,736.304,827.952,919.6,1011.25,
100  375.44,467.088,558.736,650.384,742.032,833.68,925.328,1016.98,
101  381.168,472.816,564.464,656.112,747.76,839.408,931.056,1022.7,
102  386.896,478.544,570.192,661.84,753.488,845.136,936.784,1028.43,
103  392.624,484.272,575.92,667.568,759.216,850.864,942.512,1034.16,
104  398.352,490,581.648,673.296,764.944,856.592,948.24,1039.89,
105  404.08,495.728,587.376,679.024,770.672,862.32,953.968,1045.62,
106  409.808,501.456,593.104,684.752,776.4,868.048,959.696,1051.34,
107  415.536,507.184,598.832,690.48,782.128,873.776,965.424,1057.07,
108  421.264,512.912,604.56,696.208,787.856,879.504,971.152,1062.8,
109  426.992,518.64,610.288,701.936,793.584,885.232,976.88,1068.53,
110  432.72,524.368,616.016,707.664,799.312,890.96,982.608,1074.26,
111  438.448,530.096,621.744,713.392,805.04,896.688,988.336,1079.98])
112  hico_wl = np.sort(hico_wl[:,np.newaxis],axis=0)
113  fwhm = []
114  for wl in hico_wl:
115  if(wl<745):
116  fwhm = np.append(fwhm,10)
117  elif(wl>745):
118  fwhm = np.append(fwhm,20)
119  fwhm = fwhm[:,np.newaxis]
120  Rsr = gaussian(all_wl, hico_wl, fwhm)
121  #Rsr = Rsr.transpose()
122  hico_wl = hico_wl.ravel()
123  return hico_wl, Rsr
124 
125 def read_sensor_RSR (sensor):
126  ''' Reads a sensor spectral response (RSR) from the OCW through https
127  Input: Sensor name (string)
128  Output: normalized Rsr (numpy 2-d array - wavelength x sensor band),
129  wavelength,
130  sensor band labels,
131  '''
132  global verbose
133 
134  defpath = 'https://oceancolor.gsfc.nasa.gov/docs/rsr/'
135  webpath = 'undefined'
136 
137  try:
138  webpath = defpath + sensors[sensor]['rsr']
139  if verbose:
140  print("Reading spectral response function from %s" % webpath)
141  except:
142  print("Unkown sensor")
143  sys.exit()
144 
145  tmpdir = tempfile.TemporaryDirectory()
146  tmpfile = Path(tmpdir.name + '/' + sensors[sensor]['rsr'])
147  r = requests.get(webpath, stream=True)
148 
149  if (r.status_code == requests.codes.ok):
150  with open(tmpfile, 'wb') as fd:
151  for chunk in r.iter_content(chunk_size=128):
152  fd.write(chunk)
153 
154  ncid = Dataset(tmpfile,'r')
155  wavelength = ncid['wavelength'][:]
156  Rsr = ncid['RSR'][:][:]
157  labels = ncid['bands'][:]
158  return wavelength, Rsr, labels
159  else:
160  print("Received error: %s" % r.status_code)
161  print("while attempting to retrieve %s" % webpath)
162  sys.exit()
163 
164 
165 def read_TPVMR ():
166  ''' Reads temprature, pressure, and vmr profiles from nc file in /common for
167  models: 0:Tropical,1:Mid Latitude Summer,2:Mid Latitude Winter,
168  3:Subarctic Summer,4:Subarctic Winter,5:US Standard 1962,6:User Defined Model
169  Input: None
170  Output: dp, vmrm
171  '''
172  abscf_path = os.environ.get('OCSSWROOT') + '/share/common/'
173  tpvmr = Dataset(abscf_path + 'atrem_tpvmr.nc')
174  p = np.array(tpvmr.variables['p'])
175  #t = np.array(tpvmr.variables['t'])
176  vmr = np.array(tpvmr.variables['vmr'])
177  vmr = vmr.transpose()*1e-6
178  p = p.transpose()/1013
179  vmrm= np.empty([len(vmr)-1,7])
180  DP= np.empty([len(vmr)-1,7])
181  for i in range(0,len(vmr)-1):
182  vmrm[i] = 0.5*(vmr[i] + vmr[i+1])
183  DP[i] = p[i] - p[i+1]
184  return DP, vmrm, p
185 
187  ''' Reads gas (water vapor) absorption coeff. from a nc file in /common
188  Input: None
189  Output: waveno, A
190  '''
191  abscf_path = os.environ.get('OCSSWROOT') + '/share/common/'
192  a = Dataset(abscf_path + 'abscf_gas.nc')
193  waveno = np.array(a.variables['waveno'])
194  A = np.array(a.variables['abscf_h2o'])
195  return waveno, A
196 
198  ''' Reads gas (CO2) absorption coeff. from a nc file in /common
199  Input: None
200  Output: waveno, A
201  '''
202  abscf_path = os.environ.get('OCSSWROOT') + '/share/common/'
203  a = Dataset(abscf_path + 'abscf_gas.nc')
204  waveno = np.array(a.variables['waveno'])
205  A = np.array(a.variables['abscf_co2'])
206  return waveno, A
207 
209  ''' Reads gas (O2) absorption coeff. from a nc file in /common
210  Input: None
211  Output: waveno, A
212  '''
213  abscf_path = os.environ.get('OCSSWROOT') + '/share/common/'
214  a = Dataset(abscf_path + 'abscf_gas.nc')
215  waveno = np.array(a.variables['waveno'])
216  A = np.array(a.variables['abscf_o2'])
217  return waveno, A
218 
220  ''' Reads gas (N2O) absorption coeff. from a nc file in /common
221  Input: None
222  Output: waveno, A
223  '''
224  abscf_path = os.environ.get('OCSSWROOT') + '/share/common/'
225  a = Dataset(abscf_path + 'abscf_gas.nc')
226  waveno = np.array(a.variables['waveno'])
227  A = np.array(a.variables['abscf_n2o'])
228  return waveno, A
229 
231  ''' Reads gas (CO) absorption coeff. from a nc file in /common
232  Input: None
233  Output: waveno, A
234  '''
235  abscf_path = os.environ.get('OCSSWROOT') + '/share/common/'
236  a = Dataset(abscf_path + 'abscf_gas.nc')
237  waveno = np.array(a.variables['waveno'])
238  A = np.array(a.variables['abscf_co'])
239  return waveno, A
240 
242  ''' Reads gas (CH4) absorption coeff. from a nc file in /common
243  Input: None
244  Output: waveno, A
245  '''
246  abscf_path = os.environ.get('OCSSWROOT') + '/share/common/'
247  a = Dataset(abscf_path + 'abscf_gas.nc')
248  waveno = np.array(a.variables['waveno'])
249  A = np.array(a.variables['abscf_ch4'])
250  return waveno, A
251 
252 def LBL_trans_H2O (waveno, A, dp, vmrm, wv):
253  ''' Calculate LBL water vapor transmittance
254  Input: wave number, absorption coefficients, delta-pressure,
255  volume mixing ratio (ppm), water vapor amount (cm)
256  Output: LBL water vapor transmittance
257  '''
258  T = np.empty([int(3e5),len(wv),6])
259  #wv = wv[:,np.newaxis].transpose()
260  Q = 2.15199993E+25
261  for i in range(6):
262  DP = dp[:,i]
263  DP = DP[:,np.newaxis]
264  VMRM = vmrm[:,i]
265  VMRM = VMRM[:,np.newaxis]
266  C = (Q*28.966 / 6.0225e23 / 1e-6)*DP*VMRM
267  C = C/ (np.sum(Q*VMRM*DP)/3.34e22) #----------> Normalization
268  for w in range(len(wv)):
269  T[:,w,i] = np.prod(np.exp(-A*np.reshape(C, [len(C), 1]) * wv[w]), axis=0)
270  return T
271 
272 def LBL_trans_O2 (waveno, A):
273  ''' Calculate LBL O2 transmittance
274  Input: wave number, absorption coefficients, delta-pressure,
275  volume mixing ratio (ppm), water vapor amount (cm)
276  Output: LBL water vapor transmittance
277  '''
278  abscf_path = os.environ.get('OCSSWROOT') + '/share/common/'
279  tpvmr = Dataset(abscf_path + 'atrem_tpvmr.nc')
280  p = np.array(tpvmr.variables['p'])
281  pp = p[5,:]/1013
282  DP = np.empty(19)
283  for i in range(19):
284  DP[i] = pp[i] - pp[i+1]
285  T = np.empty([int(3e5)])
286  #wv = wv[:,np.newaxis].transpose()
287  Q = 2.15199993E+25
288  #CO2 = np.linspace(340,400,10)
289  VMRM = (0.21)
290  C = (Q*28.966) / 6.0225e23 / 1e-6
291  A[:,9001:106600] = A[:,9001:106600]*2.6
292  T = np.prod(np.exp(-A*VMRM*C*np.reshape(DP,[-1,1])), axis=0)
293  return T
294 
295 def LBL_trans_N2O (waveno, A):
296  ''' Calculate LBL N2O transmittance
297  Input: wave number, absorption coefficients, delta-pressure,
298  volume mixing ratio (ppm), water vapor amount (cm)
299  Output: LBL water vapor transmittance
300  '''
301  abscf_path = os.environ.get('OCSSWROOT') + '/share/common/'
302  tpvmr = Dataset(abscf_path + 'atrem_tpvmr.nc')
303  p = np.array(tpvmr.variables['p'])
304  pp = p[5,:]/1013
305  DP = np.empty(19)
306  for i in range(19):
307  DP[i] = pp[i] - pp[i+1]
308  T = np.empty([int(3e5)])
309  #wv = wv[:,np.newaxis].transpose()
310  Q = 2.15199993E+25
311  #CO2 = np.linspace(340,400,10)
312  VMRM = 0.3*1.0E-06
313  C = (Q*28.966) / 6.0225e23 / 1e-6
314  T = np.prod(np.exp(-A*VMRM*C*np.reshape(DP,[-1,1])), axis=0)
315  return T
316 
317 def LBL_trans_CO (waveno, A):
318  ''' Calculate LBL CO transmittance
319  Input: wave number, absorption coefficients, delta-pressure,
320  volume mixing ratio (ppm), water vapor amount (cm)
321  Output: LBL water vapor transmittance
322  '''
323  abscf_path = os.environ.get('OCSSWROOT') + '/share/common/'
324  tpvmr = Dataset(abscf_path + 'atrem_tpvmr.nc')
325  p = np.array(tpvmr.variables['p'])
326  pp = p[5,:]/1013
327  DP = np.empty(19)
328  for i in range(19):
329  DP[i] = pp[i] - pp[i+1]
330  T = np.empty([int(3e5)])
331  #wv = wv[:,np.newaxis].transpose()
332  Q = 2.15199993E+25
333  #CO2 = np.linspace(340,400,10)
334  VMRM = 0.1*1.0E-06
335  C = (Q*28.966) / 6.0225e23 / 1e-6
336  T = np.prod(np.exp(-A*VMRM*C*np.reshape(DP,[-1,1])), axis=0)
337  return T
338 
339 def LBL_trans_CO2 (waveno, A, CO2):
340  ''' Calculate LBL CO2 transmittance
341  Input: wave number, absorption coefficients, delta-pressure,
342  volume mixing ratio (ppm), water vapor amount (cm)
343  Output: LBL water vapor transmittance
344  '''
345  abscf_path = os.environ.get('OCSSWROOT') + '/share/common/'
346  tpvmr = Dataset(abscf_path + 'atrem_tpvmr.nc')
347  p = np.array(tpvmr.variables['p'])
348  pp = p[5,:]/1013
349  DP = np.empty(19)
350  for i in range(19):
351  DP[i] = pp[i] - pp[i+1]
352  T = np.empty([int(3e5)])
353  #wv = wv[:,np.newaxis].transpose()
354  Q = 2.15199993E+25
355  #CO2 = np.linspace(340,400,10)
356  VMRM = CO2*1.0E-06
357  C = (Q*28.966) / 6.0225e23 / 1e-6
358  T = np.prod(np.exp(-A*VMRM*C*np.reshape(DP,[-1,1])), axis=0)
359  return T
360 
361 def LBL_trans_CH4 (waveno, A):
362  ''' Calculate LBL CH4 transmittance
363  Input: wave number, absorption coefficients, delta-pressure,
364  volume mixing ratio (ppm), water vapor amount (cm)
365  Output: LBL water vapor transmittance
366  '''
367  abscf_path = os.environ.get('OCSSWROOT') + '/share/common/'
368  tpvmr = Dataset(abscf_path + 'atrem_tpvmr.nc')
369  p = np.array(tpvmr.variables['p'])
370  pp = p[5,:]/1013
371  DP = np.empty(19)
372  for i in range(19):
373  DP[i] = pp[i] - pp[i+1]
374  T = np.empty([int(3e5)])
375  #wv = wv[:,np.newaxis].transpose()
376  Q = 2.15199993E+25
377  #CO2 = np.linspace(340,400,10)
378  VMRM = 1.8*1.0E-06
379  C = (Q*28.966) / 6.0225e23 / 1e-6
380  T = np.prod(np.exp(-A*VMRM*C*np.reshape(DP,[-1,1])), axis=0)
381  return T
382 
383 def calc_wv_trans_sensor (waveno, T, wavelength, Rsr, bands, wv):
384  ''' Calculate the water vapor transmittance within a sensor band after applying sensor RSR
385  Input: wave number, LBL transmittance, RSR wavelength, RSR, band centers, water vapor
386  Output: water vapor transmittance per sensor band, Interpolated RSR to LBL wavelength,
387  LBL wavelength, testing variable (to be removed)
388  '''
389  F0_path = os.environ.get('OCSSWROOT') + '/share/common/'
390  F0_file = F0_path + 'Thuillier_F0.dat'
391  F0 = np.array(pd.read_csv(F0_file, skiprows= 15, delimiter='\s', names=['λ','F0'], engine='python'))
392  trans_sensor = np.empty([6,len(bands),len(wv)])
393  Rsr_f = interp1d(wavelength,Rsr,kind='nearest',fill_value="extrapolate")
394  F0_f = interp1d(F0[:,0],F0[:,1],kind='nearest',fill_value="extrapolate")
395  all_wl = np.append(1e7/waveno,np.arange(np.min(1e7/waveno)-0.1,299.91,-0.1))
396  Rsr_int = Rsr_f(all_wl)
397  F0_int = F0_f(all_wl)
398  for i in range(6):
399  for j,_ in enumerate(bands):
400  for k, _ in enumerate(wv):
401  trans_sensor[i,j,k] = np.trapz((all_wl),
402  np.append(T[:,k,i],np.repeat(1,len(all_wl)-len(waveno)))
403  *Rsr_int[j,:]*F0_int)/np.trapz(all_wl,F0_int*Rsr_int[j,:])
404  z=np.append(T[:,k,i],np.repeat(1,len(all_wl)-len(waveno)))
405  return trans_sensor, Rsr_int, all_wl, z
406 
407 def calc_trans_sensor (waveno, T, wavelength, Rsr, bands):
408  ''' Calculate the transmittance within a sensor band after applying sensor RSR
409  Input: wave number, LBL transmittance, RSR wavelength, RSR, band centers, water vapor
410  Output: water vapor transmittance per sensor band, Interpolated RSR to LBL wavelength,
411  LBL wavelength, testing variable (to be removed)
412  '''
413  F0_path = os.environ.get('OCSSWROOT') + '/share/common/'
414  F0_file = F0_path + 'Thuillier_F0.dat'
415  F0 = np.array(pd.read_csv(F0_file, skiprows= 15, delimiter='\s', names=['λ','F0'], engine='python'))
416  trans_sensor = np.empty([len(bands)])
417  Rsr_f = interp1d(wavelength,Rsr,kind='nearest',fill_value="extrapolate")
418  F0_f = interp1d(F0[:,0],F0[:,1],kind='nearest',fill_value="extrapolate")
419  all_wl = np.append(1e7/waveno,np.arange(np.min(1e7/waveno)-0.1,299.91,-0.1))
420  Rsr_int = Rsr_f(all_wl)
421  F0_int = F0_f(all_wl)
422  for i,_ in enumerate(bands):
423  trans_sensor[i] = np.trapz((all_wl),
424  np.append(T[:],np.repeat(1,len(all_wl)-len(waveno)))
425  *Rsr_int[i,:]*F0_int)/np.trapz(all_wl,F0_int*Rsr_int[i,:])
426 
427  return trans_sensor
428 
429 def create_nc(sensor, ofile, waterVapor, bands, models, history=None):
430  """
431  This function opens and defines products for output as a netcdf file
432  """
433 
434  if verbose:
435  print("Writing netCDF file: %s" % ofile)
436  # Create the netCDF file and add dimensions
437  dataset = Dataset(ofile, 'w',format='NETCDF4')
438  dataset.createDimension('n_water_vapor', len(waterVapor))
439  dataset.createDimension('nmodels', len(models))
440  dataset.createDimension('nwavelengths', len(bands))
441 
442  # Set global attributes
443  dataset.title = "Atmospheric gas transmittance table"
444  dataset.description = "Atmospheric gas transmittance table for " + sensors[sensor]['name'] + " generated for a US Standard Atmosphere"
445  dataset.date_created = (datetime.fromtimestamp(time.time()).strftime('%Y-%m-%dT%H:%M:%SZ')).encode('ascii')
446  dataset.creator_name = "Amir Ibrahim, NASA/GSFC/OBPG"
447  dataset.creator_email = "data@oceancolor.gsfc.nasa.gov"
448  dataset.creator_url = "https://oceancolor.gsfc.nasa.gov"
449  dataset.product_name=ofile.encode("ascii")
450  dataset.history=history.encode("ascii")
451 # dataset.source = 'generate_gas_tables.py'
452 
453  # Create the table data sets
454  waterVaporSDS = dataset.createVariable('water_vapor', np.float32, ('n_water_vapor',))
455  modelSDS = dataset.createVariable('model', str, 'nmodels')
456  bandSDS = dataset.createVariable('wavelength', np.float32, ('nwavelengths',))
457  wvTransSDS = dataset.createVariable('water_vapor_transmittance', np.float32,('nmodels','nwavelengths','n_water_vapor'))
458  co2TransSDS = dataset.createVariable('carbon_dioxide_transmittance', np.float32,('nwavelengths'))
459  coTransSDS = dataset.createVariable('carbon_monoxide_transmittance', np.float32,('nwavelengths'))
460  ch4TransSDS = dataset.createVariable('methane_transmittance', np.float32,('nwavelengths'))
461  n2oTransSDS = dataset.createVariable('nitrous_oxide_transmittance', np.float32,('nwavelengths'))
462  o2TransSDS = dataset.createVariable('oxygen_transmittance', np.float32,('nwavelengths'))
463 
464  # Add some variable attributes
465  waterVaporSDS.long_name = 'water vapor concentration'
466  waterVaporSDS.units = 'cm'
467  modelSDS.long_name = 'US Standard atmosphere model'
468  modelSDS.units = ''
469  bandSDS.long_name = 'wavelength'
470  bandSDS.units = 'nm'
471 
472  wvTransSDS.long_name = 'water vapor transmittance'
473  wvTransSDS.valid_min = 0
474  wvTransSDS.valid_max = 1
475 
476  co2TransSDS.long_name = 'carbon dioxide transmittance'
477  co2TransSDS.valid_min = 0
478  co2TransSDS.valid_max = 1
479 
480  coTransSDS.long_name = 'carbon monoxide transmittance'
481  coTransSDS.valid_min = 0
482  coTransSDS.valid_max = 1
483 
484  ch4TransSDS.long_name = 'methane transmittance'
485  ch4TransSDS.valid_min = 0
486  ch4TransSDS.valid_max = 1
487 
488  n2oTransSDS.long_name = 'nitrous oxide transmittance'
489  n2oTransSDS.valid_min = 0
490  n2oTransSDS.valid_max = 1
491 
492  o2TransSDS.long_name = 'oxygen transmittance'
493  o2TransSDS.valid_min = 0
494  o2TransSDS.valid_max = 1
495 
496  # Write the static data
497  waterVaporSDS[:] = waterVapor
498  modelSDS[:] = models
499  bandSDS[:] = bands
500 
501  return dataset
502 
503 def write_transmittance(ncid,product,transmittance):
504  ncid[product][:] = transmittance
505 
506 def close_nc(ncid):
507  # Close the file
508  ncid.close()
509 
510 def main():
511  """
512  Primary driver of the program; get command line arguments, check the files
513  specified and kick off the processing
514  """
515  global verbose
516  parser = argparse.ArgumentParser(description=\
517  'Generates gas transmittance tables and writes them into a netCDF file')
518  parser.add_argument('--version', action='version', version='%(prog)s ' + __version__)
519  parser.add_argument('sensor', type=str,
520  choices=['modisa',
521  'modist',
522  'viirsn',
523  'viirsj1',
524  'seawifs',
525  'meris',
526  's3aolci',
527  's3bolci',
528  'hico',
529  'oli',
530  'goci',
531  'ocm1',
532  'ocm2',
533  'osmi',
534  'aviris',
535  'octs',
536  'czcs',
537  'oci',
538  'misr'],
539  default='modis-aqua', help='Sensor for which to generate the table')
540  parser.add_argument('--output_file', type=str, default='gas_transmittance.nc', help='output netCDF LUT filename; default is <SENSOR>_gas_transmittance.nc')
541  parser.add_argument('--verbose', '-v', action='store_true')
542 
543  args = parser.parse_args()
544 
545  verbose = args.verbose
546 
547  ofile = args.output_file
548  if ofile == 'gas_transmittance.nc':
549  ofile = '_'.join([args.sensor,ofile])
550 
551  if verbose:
552  print("Generating %s ..." % ofile)
553 
554  # these are the water vapor values at which the transmittance are calculated (From Bo-Cai LOWTRAN tables)
555  wv = np.array([0,0.002,0.004,0.008,0.012,0.016,0.02,0.024,0.028,0.032,0.036,0.04,0.08,0.12,0.16,0.2,0.24,0.28,
556  0.32,0.36,0.4,0.44,0.48,0.52,0.56,0.6,0.64,0.68,0.72,0.76,0.8,0.84,0.88,0.92,0.96,1,1.04,1.08,
557  1.12,1.16,1.2,1.24,1.28,1.32,1.36,1.4,1.44,1.48,1.52,1.56,1.6,1.64,1.68,1.72,1.76,1.8,1.84,1.88,
558  1.92,1.96,2,2.04,2.08,2.12,2.16,2.2,2.24,2.28,2.32,2.36,2.4,2.44,2.48,2.52,2.56,2.6,2.64,2.68,
559  2.72,2.76,2.8,2.84,2.88,2.92,2.96,3,3.04,3.08,3.12,3.16,3.2,3.24,3.28,3.32,3.36,3.4,3.44,3.48,
560  3.52,3.56,3.6,3.64,3.68,3.72,3.76,3.8,3.84,3.88,3.92,3.96,4,4.2,4.4,4.6,4.8,5,5.2,5.4,5.6,5.8,
561  6,6.2,6.4,6.6,6.8,7,7.2,7.4,7.6,7.8,8,8.4,8.8,9.2,9.6,10,10.4,10.8,11.2,11.6,12,12.4,12.8,13.2,
562  13.6,14,14.4,14.8,15.2,15.6,16,16.4,16.8,17.2,17.6,18,18.4,18.8,19.2,19.6,20,20.4,20.8,21.2,
563  21.6,22,22.4,22.8,23.2,23.6,24,24.8,25.6,26.4,27.2,28,28.8,29.6,30.4,31.2,32,32.8,33.6,34.4,
564  35.2,36,36.8,37.6,38.4,39.2,40,42,44,46,48,50,52,54,56,58,60,64,68,72,76,80,88,96,104,112,120,
565  128,136,144,152,160,168,176,188,200])
566  #wv = np.array([1,2])
567 
568  # These are the standard models
569  models = np.array(['Tropical','Mid Latitude Summer','Mid Latitude Winter','Subarctic Summer',
570  'Subarctic Winter','US Standard 1962'],dtype='str')
571 
572  # Load sensor RSR
573  wavelength, Rsr, bands = read_sensor_RSR(args.sensor)
574 
575  # Open a netCDF file that will contain the per sensor water vapor transmittance
576  history = ''
577  history = "{} {}".format(parser.prog,args.sensor)
578  if args.output_file != 'gas_transmittance.nc':
579  history += " --output_file {}".format(ofile)
580 
581  ncid = create_nc(args.sensor, ofile, wv, bands, models, history=history)
582 
583  # water vapor transmittance
584  # Load delta-pressure and volume mixing ratio of water vapor for all 6 standard models
585  if verbose:
586  print("Loading delta-pressure and volume mixing ratio of water vapor for all 6 standard models")
587  dp,vmrm,p = read_TPVMR()
588 
589  # Load water vapor absorption coefficients and wave numbers
590  if verbose:
591  print("Loading water vapor absorption coefficients and wave numbers")
592  waveno,A = read_gas_abscf()
593 
594  # Calculate the LBL water vapor transmittance
595  if verbose:
596  print("Calculating water vapor transmittance")
597  T_wv = LBL_trans_H2O(waveno,A,dp,vmrm,wv)
598 
599  # Apply the sensor RSR on the LBL to get the water vapor transmittance within the sensor's band
600  if verbose:
601  print("Convolving water vapor transmittance with sensor specrtal response")
602  sensor_trans_w, R,all_wl, z = calc_wv_trans_sensor(waveno, T_wv, wavelength, Rsr, bands, wv)
603 
604  if verbose:
605  print("Writing water vapor transmittance")
606  write_transmittance(ncid,'water_vapor_transmittance',sensor_trans_w)
607 
608  # CO2 transmittance
609  if verbose:
610  print("Loading carbon dixoide absorption coefficients and wave numbers")
611  waveno, A_co2 = read_gas_abscf_co2()
612 
613  if verbose:
614  print("Calculating carbon dioxide transmittance")
615  T_co2 = LBL_trans_CO2(waveno,A_co2, 400)
616 
617  if verbose:
618  print("Convolving carbon dioxide transmittance with sensor specrtal response")
619  sensor_trans_co2 = calc_trans_sensor(waveno, T_co2, wavelength, Rsr, bands)
620 
621  if verbose:
622  print("Writing carbon dioxide transmittance")
623  write_transmittance(ncid,'carbon_dioxide_transmittance',sensor_trans_co2)
624 
625  # O2 transmittance
626  if verbose:
627  print("Loading oxygen absorption coefficients and wave numbers")
628  waveno, A_o2 = read_gas_abscf_o2()
629 
630  if verbose:
631  print("Calculating oxygen transmittance")
632  T_o2 = LBL_trans_O2(waveno,A_o2)
633 
634  if verbose:
635  print("Convolving oxygen transmittance with sensor specrtal response")
636  sensor_trans_o2 = calc_trans_sensor(waveno, T_o2, wavelength, Rsr, bands)
637 
638  if verbose:
639  print("Writing oxygen transmittance")
640  write_transmittance(ncid,'oxygen_transmittance',sensor_trans_o2)
641 
642  # NO2 transmittance
643  if verbose:
644  print("Loading nitrous oxide absorption coefficients and wave numbers")
645  waveno, A_n2o = read_gas_abscf_n2o()
646 
647  if verbose:
648  print("Calculating nitrous oxide transmittance")
649  T_n2o = LBL_trans_N2O(waveno,A_n2o)
650 
651  if verbose:
652  print("Convolving nitrous oxide transmittance with sensor specrtal response")
653  sensor_trans_no2 = calc_trans_sensor(waveno, T_n2o, wavelength, Rsr, bands)
654 
655  if verbose:
656  print("Writing nitrous oxide transmittance")
657  write_transmittance(ncid,'nitrous_oxide_transmittance',sensor_trans_no2)
658 
659  # CO transmittance
660  if verbose:
661  print("Loading carbon monoxide absorption coefficients and wave numbers")
662  waveno, A_co = read_gas_abscf_co()
663 
664  if verbose:
665  print("Calculating carbon monoxide transmittance")
666  T_co = LBL_trans_CO(waveno,A_co)
667 
668  if verbose:
669  print("Convolving carbon monoxide transmittance with sensor specrtal response")
670  sensor_trans_co = calc_trans_sensor(waveno, T_co, wavelength, Rsr, bands)
671 
672  if verbose:
673  print("Writing carbon monoxide transmittance")
674  write_transmittance(ncid,'carbon_monoxide_transmittance',sensor_trans_co)
675 
676  # CH4 transmittance
677  if verbose:
678  print("Loading methane absorption coefficients and wave numbers")
679  waveno, A_ch4 = read_gas_abscf_ch4()
680 
681  if verbose:
682  print("Calculating methane transmittance")
683  T_ch4 = LBL_trans_CH4(waveno,A_ch4)
684 
685  if verbose:
686  print("Convolving methane transmittance with sensor specrtal response")
687  sensor_trans_ch4 = calc_trans_sensor(waveno, T_ch4, wavelength, Rsr, bands)
688 
689  if verbose:
690  print("Writing methane transmittance")
691  write_transmittance(ncid,'methane_transmittance',sensor_trans_ch4)
692 
693  close_nc(ncid)
694  if verbose:
695  print("Processing complete!")
696 
697 # The following allows the file to be imported without immediately executing.
698 if __name__ == '__main__':
699  sys.exit(main())
def create_nc(sensor, ofile, waterVapor, bands, models, history=None)
def write_transmittance(ncid, product, transmittance)
character(len=1000) if
Definition: names.f90:13
def calc_trans_sensor(waveno, T, wavelength, Rsr, bands)
def calc_wv_trans_sensor(waveno, T, wavelength, Rsr, bands, wv)