2 * NAME: dtdb_viirs_l1a.py
4 * DESCRIPTION: Executable program to automate download of L1A files in specified date-time range.
6 * USAGE: dtdb_viirs_l1a.py -b [start date-time] -e [end date-time] -o [output directory]
8 * Created on February 27, 2021
10 * Author: Samuel Anderson
15 from datetime
import datetime
16 import viirs_files
as vf
17 import optparse
as optparse
19 LOG = logging.getLogger(
'dtdb_viirs_l1a')
22 str_url =
"https://oceandata.sci.gsfc.nasa.gov/ob/getfile/"
23 str_wget =
"wget --load-cookies ~/.urs_cookies --save-cookies ~/.urs_cookies --auth-no-challenge=on --content-disposition "
28 dircontents = os.listdir(inpath)
33 infilepath = inpath + x
34 if not os.path.isfile(infilepath):
36 files.append(infilepath)
40 tot_min = hour*6000 + min
47 min = tot_min - h*6000
51 day_of_year = date(year, month, day).timetuple().tm_yday
55 daystr =
'{:03}'.format(day_of_year)
56 dt = datetime.strptime(
str(year)+
"-"+daystr,
"%Y-%j")
57 return dt.year, dt.month, dt.day
60 DtFilename = l1b_name.replace(
"L1B",
"L2.AER_DT")
64 DbFilename = l1b_name.replace(
"L1B",
"L2.AER_DB")
75 description =
'''Download L1A files in specified date-time range.'''
76 usage =
"usage: get_viirs_l1a.py -b [start date-time] -e [end date-time] -o [output directory]"
79 parser = optparse.OptionParser(description=description,usage=usage,version=version)
82 mandatoryGroup = optparse.OptionGroup(parser,
"Mandatory Arguments",
83 "At a minimum these arguments must be specified")
85 parser.add_option_group(mandatoryGroup)
87 mandatoryGroup.add_option(
'-b',
'--begin',
91 help=
"Begin date-time")
93 mandatoryGroup.add_option(
'-e',
'--end',
99 mandatoryGroup.add_option(
'-z',
'--platform',
103 help=
"VIIRS Platform (snpp, jpss1 or jpss2")
105 mandatoryGroup.add_option(
'-d',
'--alg',
109 help=
"Dark Target (dt) or Deep Blue (db)")
111 mandatoryGroup.add_option(
'--l1_par',
115 help=
"The full path of the L1 PCF")
117 mandatoryGroup.add_option(
'--l2_par',
121 help=
"The full path of the L2 PCF")
124 optionalGroup = optparse.OptionGroup(parser,
"Extra Options",
125 "These options may be used to customize behavior of this program.")
127 optionalGroup.add_option(
'--bowtie',
131 help=
"Remove bowtie fill values (default no)")
133 optionalGroup.add_option(
'--geo',
137 help=
"Write geolocation group (default no)")
139 optionalGroup.add_option(
'--anc',
143 help=
"Write ancillary group (default no)")
145 optionalGroup.add_option(
'--obs',
149 help=
"Write observations group (default no)")
151 optionalGroup.add_option(
'--stats',
155 help=
"Write statistics group (default no)")
157 optionalGroup.add_option(
'--glint',
161 help=
"Do not mask glint (default no)")
163 optionalGroup.add_option(
'--cloud',
167 help=
"Do not mask clouds (default no)")
169 optionalGroup.add_option(
'--float',
173 help=
"Floating point rather than short integer format (default no)")
175 optionalGroup.add_option(
'-o',
'--output_path',
179 help=
"The full path of the target directory for L1A files")
181 parser.add_option(
'-v',
'--verbose',
185 help=
'each occurrence increases verbosity 1 level from ERROR: -v=WARNING -vv=INFO -vvv=DEBUG')
187 parser.add_option_group(optionalGroup)
190 (options, args) = parser.parse_args()
193 levels = [logging.ERROR, logging.WARN, logging.INFO, logging.DEBUG]
194 logging.basicConfig(level = levels[options.verbosity])
200 isMissingMand =
False
201 for m,m_err
in zip(mandatories,mand_errors):
202 if not options.__dict__[m]:
206 parser.error(
"Incomplete mandatory arguments, aborting...")
209 options.outputPath = os.path.expanduser(options.odir)
213 LOG.info(
'Downloading L1A in %s' % (options.odir) )
215 if not options.outputPath:
216 dir =
"L1B_" + datetime.now().isoformat()
217 o_path = os.getcwd() + dir
219 elif os.path.isdir(options.outputPath):
220 o_path = options.outputPath
221 elif os.path.isdir(os.path.dirname(options.outputPath)):
222 o_path = options.outputPath
225 print (
"Output path invalid")
228 str_l1a_dir = o_path +
"/l1a/"
229 if not os.path.isdir(str_l1a_dir):
230 os.mkdir(str_l1a_dir)
231 str_l1b_dir = o_path +
"/l1b/"
232 if not os.path.isdir(str_l1b_dir):
233 os.mkdir(str_l1b_dir)
234 str_geo_dir = o_path +
"/geo/"
235 if not os.path.isdir(str_geo_dir):
236 os.mkdir(str_geo_dir)
237 str_dt_dir = o_path +
"/dt/"
238 if not os.path.isdir(str_dt_dir):
240 str_db_dir = o_path +
"/db/"
241 if not os.path.isdir(str_db_dir):
243 str_anc_dir = o_path +
"/anc/"
244 if not os.path.isdir(str_anc_dir):
245 os.mkdir(str_anc_dir)
249 byear =
int(options.begin[0:4])
250 bday =
int(options.begin[4:7])
251 bhour =
int(options.begin[7:9])
252 bmin = ((
int(options.begin[9:13]) + 599)//600) * 600
254 eyear =
int(options.end[0:4])
255 eday =
int(options.end[4:7])
256 ehour =
int(options.end[7:9])
257 emin = (
int(options.end[9:13])//600) * 600
261 if options.platform ==
"snpp":
262 str_platform =
".L1A_SNPP.nc"
263 elif options.platform ==
"jpss1":
264 str_platform =
".L1A_JPSS1.nc"
265 elif options.platform ==
"jpss2":
266 str_platform =
".L1A_JPSS2.nc"
269 if options.alg ==
"darktarget":
270 algs = [
"darktarget"]
271 elif options.alg ==
"deepblue":
273 elif options.alg ==
"all":
274 algs = [
"darktarget",
"deepblue"]
276 print (
"No algorithm specified. Exiting ...")
280 print (
"Beginning and end years must be the same. Exiting ...")
285 tal = etmin + t24*(eday - bday)
289 str_date_time =
"%04d%03d%02d%04d" % (byear, bday+d, h, s)
290 str_l1a_name =
"V" + str_date_time + str_platform
291 print (
"Processing: " + str_l1a_name)
292 sfl1a = str_l1a_dir + str_l1a_name
294 l1a_file = vf.l1_file(sfl1a)
295 str_geo_name = l1a_file.getGeoMFilename()
296 gmod = str_geo_dir + str_geo_name
298 lmod = str_l1b_dir + l1a_file.getModFilename()
300 if (
not sfl1a
in l1a_files)
and (
not lmod
in l1b_files):
301 srpath = str_url + str_l1a_name
302 command = str_wget + str_wdir + str_l1a_dir +
" " + srpath
304 result = os.system(command)
306 year, month, day =
day2date(byear, bday+d)
307 str_date_hour =
"%04d%02d%02dT%02d%04d" % (byear, month, day, h, 0)
308 str_anc_name =
"GMAO_MERRA2." + str_date_hour +
".MET.nc"
309 gdas1 = str_anc_dir + str_anc_name
311 if not gdas1
in anc_files:
312 arpath = str_url + str_anc_name
313 command = str_wget + str_wdir + str_anc_dir +
" " + arpath
315 result = os.system(command)
318 year, month, day =
day2date(byear, bday+d+1)
319 str_date_hour =
"%04d%02d%02dT%02d%04d" % (byear, month, day, 0, 0)
321 str_date_hour =
"%04d%02d%02dT%02d%04d" % (byear, month, day, h+1, 0)
322 str_anc_name =
"GMAO_MERRA2." + str_date_hour +
".MET.nc"
323 gdas2 = str_anc_dir + str_anc_name
324 if not gdas2
in anc_files:
325 arpath = str_url + str_anc_name
326 command = str_wget + str_wdir + str_anc_dir +
" " + arpath
328 result = os.system(command)
330 if not gmod
in geo_files:
331 grpath = str_url + str_geo_name
332 command = str_wget + str_wdir + str_geo_dir +
" " + grpath
334 result = os.system(command)
335 print (
"geo file: " + gmod)
337 if not lmod
in l1b_files:
338 command =
"calibrate_viirs " + options.l1_par +
" ifile=" + sfl1a +
" l1bfile_mod=" + lmod
340 result = os.system(command)
341 print (
"l1b file: " + lmod)
344 cgmod =
"geo_resam_" + datetime.now().strftime(
"%f") +
".nc"
345 command =
"cp " + gmod +
" " + cgmod
346 result = os.system(command)
347 clmod =
"l1b_resam_" + datetime.now().strftime(
"%f") +
".nc"
348 command =
"cp " + lmod +
" " + clmod
349 result = os.system(command)
350 command =
"resam_viirs " +
"ifile=" + clmod +
" geofile=" + cgmod
351 print (
"Resampling granule to fill bowtie regions")
352 result = os.system(command)
359 if alg ==
"deepblue":
360 alg_str =
"deepblue "
361 opath = str_db_dir + l1a_file.getDbFilename()
363 alg_str =
"darktarget "
364 opath = str_dt_dir + l1a_file.getDtFilename()
365 l2par =
" par=" + options.l2_par
366 ialg =
" alg=" + alg_str
367 il1b =
" ifile=" + clmod
368 igeo =
" geofile=" + cgmod
369 ianc1 =
" gdas1=" + gdas1
370 ianc2 =
" gdas2=" + gdas2
371 opth =
" ofile=" + opath
372 ogeo =
" geolocation" if options.geo
else ""
373 oanc =
" ancillary" if options.anc
else ""
374 oobs =
" observations" if options.obs
else ""
375 ostat =
" statistics" if options.stats
else ""
376 oglnt =
" mask_glint=off" if options.glint
else ""
377 ocld =
" mask_cloud=off" if options.cloud
else ""
378 oflt=
" short_format=off" if options.float
else ""
379 lprw =
" lines_per_rw=10"
380 command =
"dtdb " + l2par + ialg + il1b + igeo + ianc1 + ianc2 + opth + ogeo + oanc + oobs + ostat + oglnt + ocld + oflt + lprw
382 result = os.system(command)
384 result = os.system(command)
389 print (
"Invalid start and end dates specified. Exiting ...")
392 print (
"All L1A files in range processed")
394 LOG.info(
'Exiting...')
397 if __name__==
'__main__':