4 * DESCRIPTION: Executable program to merge afrt (radiative
5 * transfer) NetCDF4 files
7 * USAGE: python merge_afrt.py -p [PCF file path] -wl [wavelength range]
8 -sd [particle model range] -tau [optical depth range]
9 -wnd [wind speed range]
11 * Created on October 09, 2018
13 * Author: Samuel Anderson
19 from datetime
import datetime
as dt
20 import optparse
as optparse
22 LOG = logging.getLogger(
'afrt')
35 description =
'''Merge AFRT NetCDF output files.'''
36 usage =
"usage: python merge_afrt.py -d [dir] -wl [wavelength id range] -sd [model id range] -tau [tau id range] -wnd [wnd id range] -o [output directory] [options]"
39 parser = optparse.OptionParser(description=description,usage=usage,version=version)
42 mandatoryGroup = optparse.OptionGroup(parser,
"Mandatory Arguments",
43 "At a minimum these arguments must be specified")
45 parser.add_option_group(mandatoryGroup)
47 mandatoryGroup.add_option(
'-d',
'--idir',
51 help=
"The input directory")
54 optionalGroup = optparse.OptionGroup(parser,
"Extra Options",
55 "These options may be used to customize behavior of this program.")
57 optionalGroup.add_option(
'-f',
'--fname',
61 help=
"File name of intermediate product names")
63 optionalGroup.add_option(
'-l',
'--wl',
68 help=
"Range of wavelength indices")
70 optionalGroup.add_option(
'-s',
'--sd',
75 help=
"Range of particle model indices")
77 optionalGroup.add_option(
'-t',
'--tau',
82 help=
"Range of optical depth indices")
84 optionalGroup.add_option(
'-w',
'--wnd',
89 help=
"Range of wind speed indices")
91 optionalGroup.add_option(
'-o',
'--odir',
95 help=
"The output directory")
97 parser.add_option(
'-v',
'--verbose',
101 help=
'each occurrence increases verbosity 1 level from ERROR: -v=WARNING -vv=INFO -vvv=DEBUG')
103 parser.add_option_group(optionalGroup)
106 (opt, args) = parser.parse_args()
109 levels = [logging.ERROR, logging.WARN, logging.INFO, logging.DEBUG]
110 logging.basicConfig(level = levels[opt.verbosity])
116 isMissingMand =
False
117 for m,m_err
in zip(mandatories,mand_errors):
118 if not opt.__dict__[m]:
121 parser.error(
"Incomplete mandatory arguments, aborting...")
125 LOG.info(
'Merging radiative transfer tables in %s' % (opt.odir) )
127 if os.path.isdir(opt.odir):
129 elif os.path.isdir(os.path.dirname(opt.odir)):
133 print (
"Output path invalid")
135 if not os.path.isdir(opt.idir):
139 with open(opt.fname)
as fp:
140 contents = fp.readlines()
144 command =
"wget -N --content-disposition https://oceandata.sci.gsfc.nasa.gov/cgi/gethiddenfile/" + fn
146 subprocess.run(command, shell=
True)
148 listing = os.listdir(opt.idir)
153 fpath = opt.idir +
"/" + x
154 if not os.path.isfile(fpath):
156 if not tables.is_hdf5_file(fpath):
158 if not (x.find(
"RT") >= 0):
161 h5file = tables.open_file(fpath,
"r")
162 toa = h5file.get_node(
'/',
"TOA_RADIANCE")
164 wl = h5file.get_node(
'/',
"wavelength_index")
165 if wl[0]<opt.wl[0]
or wl[1]>opt.wl[1]:
168 sd = h5file.get_node(
'/',
"model_index")
169 if sd[0]<opt.sd[0]
or sd[1]>opt.sd[1]:
172 tau = h5file.get_node(
'/',
"tau_index")
173 if tau[0]<opt.tau[0]
or tau[1]>opt.tau[1]:
176 wnd = h5file.get_node(
'/',
"wind_index")
177 if wnd[0]<opt.wnd[0]
or wnd[1]>opt.wnd[1]:
180 valid_files.append(fpath)
186 if len(valid_files) == 0:
187 print(
"Exiting...no valid files in input directory.")
190 sdd = opt.sd[1]-opt.sd[0]+1
191 wld = opt.wl[1]-opt.wl[0]+1
192 taud = opt.tau[1]-opt.tau[0]+1
193 wndd = opt.wnd[1]-opt.wnd[0]+1
200 rstr =
"_MD%(s0)d-%(s1)d_WL%(l0)d-%(l1)d_TA%(t0)d-%(t1)d_WD%(w0)d-%(w1)d" % \
201 {
"s0":opt.sd[0],
"s1":opt.sd[1],
"l0":opt.wl[0],
"l1":opt.wl[1],
"t0":opt.tau[0],
"t1":opt.tau[1],
"w0":opt.wnd[0],
"w1":opt.wnd[1]}
203 ofilepath = opt.odir +
"/" + stitle + rstr
204 of = tables.open_file(ofilepath,
"w",
"Output of AF Radiative Transfer.")
205 atom = tables.Float64Atom()
206 BOA_RADIANCE_a = of.create_carray(
"/",
'BOA_RADIANCE', atom, (sdd,wld,taud,wndd,szad,thed,phid,stkd),
"")
207 BOA_DIFFUSE_a = of.create_carray(
"/",
'BOA_DIFFUSE', atom, (sdd,wld,taud,wndd,szad),
"")
208 BOA_DIRECT_a = of.create_carray(
"/",
'BOA_DIRECT', atom, (sdd,wld,taud,wndd,szad),
"")
209 HEM_REFLECTANCE_a = of.create_carray(
"/",
'HEM_REFLECTANCE', atom, (sdd,wld,taud,wndd,szad),
"")
210 SBAR_a = of.create_carray(
"/",
'SBAR', atom, (sdd,wld,taud,wndd,szad),
"")
211 TAU_AEROSOL_a = of.create_carray(
"/",
'TAU_AEROSOL', atom, (sdd,wld,taud,wndd),
"")
212 TAU_H2O_a = of.create_carray(
"/",
'TAU_H2O', atom, (sdd,wld,taud,wndd),
"")
213 TAU_OZONE_a = of.create_carray(
"/",
'TAU_OZONE', atom, (sdd,wld,taud,wndd),
"")
214 TAU_RAYLEIGH_a = of.create_carray(
"/",
'TAU_RAYLEIGH', atom, (sdd,wld,taud,wndd),
"")
215 TAU_TOTAL_a = of.create_carray(
"/",
'TAU_TOTAL', atom, (sdd,wld,taud,wndd),
"")
216 TOA_RADIANCE_a = of.create_carray(
"/",
'TOA_RADIANCE', atom, (sdd,wld,taud,wndd,szad,thed,phid,stkd),
"")
217 TOA_DIFFUSE_a = of.create_carray(
"/",
'TOA_DIFFUSE', atom, (sdd,wld,taud,wndd,szad),
"")
219 FTW_DIRECT_OCEAN_a = of.create_carray(
"/",
'FTW_DIRECT_OCEAN', atom, (sdd,wld,taud,wndd,szad),
"")
220 FTW_DIFFUSE_OCEAN_a = of.create_carray(
"/",
'FTW_DIFFUSE_OCEAN', atom, (sdd,wld,taud,wndd,szad),
"")
221 FTW_UP_DIFFUSE_OCEAN_BELOW_a = of.create_carray(
"/",
'FTW_UP_DIFFUSE_OCEAN_BELOW', atom, (sdd,wld,taud,wndd,szad),
"")
222 FTW_UP_DIFFUSE_OCEAN_ABOVE_a = of.create_carray(
"/",
'FTW_UP_DIFFUSE_OCEAN_ABOVE', atom, (sdd,wld,taud,wndd,szad),
"")
223 HEM_TRANS_REF_a = of.create_carray(
"/",
'HEM_TRANS_REF', atom, (sdd,wld,taud,wndd,szad),
"")
224 HEM_REFL_REF_a = of.create_carray(
"/",
'HEM_REFL_REF', atom, (sdd,wld,taud,wndd,szad),
"")
225 HEM_DIRECT_REF_a = of.create_carray(
"/",
'HEM_DIRECT_REF', atom, (sdd,wld,taud,wndd,szad),
"")
226 HEM_DIFFUSE_REF_a = of.create_carray(
"/",
'HEM_DIFFUSE_REF', atom, (sdd,wld,taud,wndd,szad),
"")
227 SZA_a = of.create_carray(
"/",
'SZA', atom, (szad,),
"")
228 PHI_a = of.create_carray(
"/",
'PHI', atom, (phid,),
"")
229 THETA_a = of.create_carray(
"/",
'THETA', atom, (thed,),
"")
230 AOT_550_a = of.create_carray(
"/",
'AOT_550', atom, (taud,),
"")
231 WAVELENGTH_a = of.create_carray(
"/",
'WAVELENGTH', atom, (wld,),
"")
232 WIND_SPEED_a = of.create_carray(
"/",
'WIND_SPEED', atom, (wndd,),
"")
233 atom = tables.Int32Atom()
234 wavelength_index_a = of.create_carray(
"/",
'wavelength_index', atom, (2,),
"")
235 model_index_a = of.create_carray(
"/",
'model_index', atom, (2,),
"")
236 tau_index_a = of.create_carray(
"/",
'tau_index', atom, (2,),
"")
237 wind_index_a = of.create_carray(
"/",
'wind_index', atom, (2,),
"")
243 for fpath
in valid_files:
245 ifile = tables.open_file(fpath,
"r")
246 l[:] = ifile.get_node(
"/",
"wavelength_index")[:]
247 s[:] = ifile.get_node(
"/",
"model_index")[:]
248 t[:] = ifile.get_node(
"/",
"tau_index")[:]
249 w[:] = ifile.get_node(
"/",
"wind_index")[:]
254 BOA_RADIANCE_a[s[0]:s[1],l[0]:l[1],t[0]:t[1],w[0]:w[1],:,:,:,:] = \
255 ifile.get_node(
"/",
"BOA_RADIANCE")[0:s[1]-s[0],0:l[1]-l[0],0:t[1]-t[0],0:w[1]-w[0],:,:,:,:]
256 BOA_DIFFUSE_a[s[0]:s[1],l[0]:l[1],t[0]:t[1],w[0]:w[1]:] = \
257 ifile.get_node(
"/",
"BOA_DIFFUSE")[0:s[1]-s[0],0:l[1]-l[0],0:t[1]-t[0],0:w[1]-w[0],:]
258 BOA_DIRECT_a[s[0]:s[1],l[0]:l[1],t[0]:t[1],w[0]:w[1]:] = \
259 ifile.get_node(
"/",
"BOA_DIRECT")[0:s[1]-s[0],0:l[1]-l[0],0:t[1]-t[0],0:w[1]-w[0],:]
260 HEM_REFLECTANCE_a[s[0]:s[1],l[0]:l[1],t[0]:t[1],w[0]:w[1]:] = \
261 ifile.get_node(
"/",
"HEM_REFLECTANCE")[0:s[1]-s[0],0:l[1]-l[0],0:t[1]-t[0],0:w[1]-w[0],:]
262 SBAR_a[s[0]:s[1],l[0]:l[1],t[0]:t[1],w[0]:w[1],:] = \
263 ifile.get_node(
"/",
"SBAR")[0:s[1]-s[0],0:l[1]-l[0],0:t[1]-t[0],0:w[1]-w[0],:]
264 TAU_AEROSOL_a[s[0]:s[1],l[0]:l[1],t[0]:t[1],w[0]:w[1]] = \
265 ifile.get_node(
"/",
"TAU_AEROSOL")[0:s[1]-s[0],0:l[1]-l[0],0:t[1]-t[0],0:w[1]-w[0]]
266 TAU_H2O_a[s[0]:s[1],l[0]:l[1],t[0]:t[1],w[0]:w[1]] = \
267 ifile.get_node(
"/",
"TAU_H2O")[0:s[1]-s[0],0:l[1]-l[0],0:t[1]-t[0],0:w[1]-w[0]]
268 TAU_OZONE_a[s[0]:s[1],l[0]:l[1],t[0]:t[1],w[0]:w[1]] = \
269 ifile.get_node(
"/",
"TAU_OZONE")[0:s[1]-s[0],0:l[1]-l[0],0:t[1]-t[0],0:w[1]-w[0]]
270 TAU_RAYLEIGH_a[s[0]:s[1],l[0]:l[1],t[0]:t[1],w[0]:w[1]] = \
271 ifile.get_node(
"/",
"TAU_RAYLEIGH")[0:s[1]-s[0],0:l[1]-l[0],0:t[1]-t[0],0:w[1]-w[0]]
272 TAU_TOTAL_a[s[0]:s[1],l[0]:l[1],t[0]:t[1],w[0]:w[1]] = \
273 ifile.get_node(
"/",
"TAU_TOTAL")[0:s[1]-s[0],0:l[1]-l[0],0:t[1]-t[0],0:w[1]-w[0]]
274 TOA_RADIANCE_a[s[0]:s[1],l[0]:l[1],t[0]:t[1],w[0]:w[1],:,:,:,:] = \
275 ifile.get_node(
"/",
"TOA_RADIANCE")[0:s[1]-s[0],0:l[1]-l[0],0:t[1]-t[0],0:w[1]-w[0],:,:,:,:]
276 TOA_DIFFUSE_a[s[0]:s[1],l[0]:l[1],t[0]:t[1],w[0]:w[1],:] = \
277 ifile.get_node(
"/",
"TOA_DIFFUSE")[0:s[1]-s[0],0:l[1]-l[0],0:t[1]-t[0],0:w[1]-w[0],:]
280 FTW_DIRECT_OCEAN_a[s[0]:s[1],l[0]:l[1],t[0]:t[1],w[0]:w[1]:] = \
281 ifile.get_node(
"/",
"FTW_DIRECT_OCEAN")[0:s[1]-s[0],0:l[1]-l[0],0:t[1]-t[0],0:w[1]-w[0],:]
282 FTW_DIFFUSE_OCEAN_a[s[0]:s[1],l[0]:l[1],t[0]:t[1],w[0]:w[1]:] = \
283 ifile.get_node(
"/",
"FTW_DIFFUSE_OCEAN")[0:s[1]-s[0],0:l[1]-l[0],0:t[1]-t[0],0:w[1]-w[0],:]
284 FTW_UP_DIFFUSE_OCEAN_BELOW_a[s[0]:s[1],l[0]:l[1],t[0]:t[1],w[0]:w[1]:] = \
285 ifile.get_node(
"/",
"FTW_UP_DIFFUSE_OCEAN_BELOW")[0:s[1]-s[0],0:l[1]-l[0],0:t[1]-t[0],0:w[1]-w[0],:]
286 FTW_UP_DIFFUSE_OCEAN_ABOVE_a[s[0]:s[1],l[0]:l[1],t[0]:t[1],w[0]:w[1]:] = \
287 ifile.get_node(
"/",
"FTW_UP_DIFFUSE_OCEAN_ABOVE")[0:s[1]-s[0],0:l[1]-l[0],0:t[1]-t[0],0:w[1]-w[0],:]
288 HEM_TRANS_REF_a[s[0]:s[1],l[0]:l[1],t[0]:t[1],w[0]:w[1]:] = \
289 ifile.get_node(
"/",
"HEM_TRANS_REF")[0:s[1]-s[0],0:l[1]-l[0],0:t[1]-t[0],0:w[1]-w[0],:]
290 HEM_REFL_REF_a[s[0]:s[1],l[0]:l[1],t[0]:t[1],w[0]:w[1]:] = \
291 ifile.get_node(
"/",
"HEM_REFL_REF")[0:s[1]-s[0],0:l[1]-l[0],0:t[1]-t[0],0:w[1]-w[0],:]
292 HEM_DIRECT_REF_a[s[0]:s[1],l[0]:l[1],t[0]:t[1],w[0]:w[1]:] = \
293 ifile.get_node(
"/",
"HEM_DIRECT_REF")[0:s[1]-s[0],0:l[1]-l[0],0:t[1]-t[0],0:w[1]-w[0],:]
294 HEM_DIFFUSE_REF_a[s[0]:s[1],l[0]:l[1],t[0]:t[1],w[0]:w[1]:] = \
295 ifile.get_node(
"/",
"HEM_DIFFUSE_REF")[0:s[1]-s[0],0:l[1]-l[0],0:t[1]-t[0],0:w[1]-w[0],:]
296 SZA_a[:] = ifile.get_node(
"/",
"SZA")[:]
297 PHI_a[:] = ifile.get_node(
"/",
"PHI")[:]
298 THETA_a[:] = ifile.get_node(
"/",
"THETA")[:]
299 AOT_550_a[t[0]:t[1]] = ifile.get_node(
"/",
"AOT")[:]
300 WAVELENGTH_a[l[0]:l[1]] = ifile.get_node(
"/",
"WAVELENGTH")[:]
301 WIND_SPEED_a[w[0]:w[1]] = ifile.get_node(
"/",
"WIND_SPEED")[:]
308 wavelength_index_a[:] = opt.wl[:]
309 model_index_a[:] = opt.sd[:]
310 tau_index_a[:] = opt.tau[:]
311 wind_index_a[:] = opt.wnd[:]
315 print(
"Merge complete at " + ofilepath)
316 LOG.info(
'Exiting...')
319 if __name__==
'__main__':