OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
dtdb_oci.py
Go to the documentation of this file.
1 '''
2 * NAME: dtdb_oci.py
3 *
4 * DESCRIPTION: Executable program to automate download of L1A files in specified date-time range.
5 
6 * USAGE: dtdb_oci.py -b [start date-time] -e [end date-time] -o [output directory]
7 
8 * Created on August, 2021
9 
10 * Author: Samuel Anderson
11 '''
12 
13 import os
14 import sys
15 from datetime import datetime, date
16 import viirs_files as vf
17 import optparse as optparse
18 import logging
19 LOG = logging.getLogger('dtdb_oci')
20 
21 #str_url ="http://oceandata.sci.gsfc.nasa.gov/cgi/getfile/"
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 "
24 str_wdir ="-P "
25 
26 def init_dir(inpath):
27  files = []
28  dircontents = os.listdir(inpath)
29  dircontents.sort()
30  for x in dircontents:
31  if x[0] == ".":
32  continue
33  infilepath = inpath + x
34  if not os.path.isfile(infilepath):
35  continue
36  files.append(infilepath)
37  return files
38 
39 def hour2min(hour, min):
40  tot_min = hour*6000 + min
41  return tot_min
42 
43 def min2hour(tot_min):
44  h = tot_min//6000
45  day = h//24
46  hour = h - day*24
47  min = tot_min - h*6000
48  return day, hour, min
49 
50 def date2day(year, month, day):
51  day_of_year = date(year, month, day).timetuple().tm_yday
52  return day_of_year
53 
54 def day2date(year, day_of_year):
55  daystr = '{:03}'.format(day_of_year)
56  dt = datetime.strptime(str(year)+"-"+daystr,"%Y-%j")
57  return dt.year, dt.month, dt.day
58 
59 def getDtFilename(l1b_name):
60  DtFilename = l1b_name.replace("L1B", "L2.AER_DT")
61  return DtFilename
62 
63 def getDbFilename(l1b_name):
64  DbFilename = l1b_name.replace("L1B", "L2.AER_DB")
65  return DbFilename
66 
67 
70 
71 def main():
72 
73  args = sys.argv
74 
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]"
77  version = "v1"
78 
79  parser = optparse.OptionParser(description=description,usage=usage,version=version)
80 
81  # Mandatory arguments
82  mandatoryGroup = optparse.OptionGroup(parser, "Mandatory Arguments",
83  "At a minimum these arguments must be specified")
84 
85  parser.add_option_group(mandatoryGroup)
86 
87  mandatoryGroup.add_option('-b','--begin',
88  action="store",
89  dest="begin" ,
90  type="string",
91  help="Begin date-time")
92 
93  mandatoryGroup.add_option('-e','--end',
94  action="store",
95  dest="end" ,
96  type="string",
97  help="End date-time")
98 
99  mandatoryGroup.add_option('-d','--alg',
100  action="store",
101  dest="alg" ,
102  type="string",
103  help="Dark Target (dt) or Deep Blue (db)")
104 
105  mandatoryGroup.add_option('--l2_par',
106  action="store",
107  dest="l2_par" ,
108  type="string",
109  help="The full path of the L2 PCF")
110 
111  # Optional arguments
112  optionalGroup = optparse.OptionGroup(parser, "Extra Options",
113  "These options may be used to customize behavior of this program.")
114 
115  optionalGroup.add_option('--geo',
116  action="store_true",
117  dest="geo" ,
118  default=False,
119  help="Write geolocation group (default no)")
120 
121  optionalGroup.add_option('--anc',
122  action="store_true",
123  dest="anc" ,
124  default=False,
125  help="Write ancillary group (default no)")
126 
127  optionalGroup.add_option('--obs',
128  action="store_true",
129  dest="obs" ,
130  default=False,
131  help="Write observations group (default no)")
132 
133  optionalGroup.add_option('--glint',
134  action="store_true",
135  dest="glint" ,
136  default=False,
137  help="Do not mask glint (default no)")
138 
139  optionalGroup.add_option('--cloud',
140  action="store_true",
141  dest="cloud" ,
142  default=False,
143  help="Do not mask clouds (default no)")
144 
145  optionalGroup.add_option('--float',
146  action="store_true",
147  dest="float" ,
148  default=False,
149  help="Floating point rather than short integer format (default no)")
150 
151  optionalGroup.add_option('-o','--output_path',
152  action="store",
153  dest="odir" ,
154  type="string",
155  help="The full path of the target directory for L1A files")
156 
157  parser.add_option('-v', '--verbose',
158  dest='verbosity',
159  action="count",
160  default=0,
161  help='each occurrence increases verbosity 1 level from ERROR: -v=WARNING -vv=INFO -vvv=DEBUG')
162 
163  parser.add_option_group(optionalGroup)
164 
165  # Parse the arguments from the command line
166  (options, args) = parser.parse_args()
167 
168  # Set up the logging levels
169  levels = [logging.ERROR, logging.WARN, logging.INFO, logging.DEBUG]
170  logging.basicConfig(level = levels[options.verbosity])
171 
172  # Check that all of the mandatory options are given. If one or more
173  # are missing, print error message and exit...
174  mandatories = []
175  mand_errors = []
176  isMissingMand = False
177  for m,m_err in zip(mandatories,mand_errors):
178  if not options.__dict__[m]:
179  isMissingMand = True
180  print (m_err)
181  if isMissingMand :
182  parser.error("Incomplete mandatory arguments, aborting...")
183 
184  # Check that the output directory actually exist
185  options.outputPath = os.path.expanduser(options.odir)
186 
187  # Check that we don't have mutually exclusive options
188 
189  LOG.info('Downloading L1B in %s' % (options.odir) )
190 
191  if os.path.isdir(options.outputPath):
192  o_path = options.outputPath
193  elif os.path.isdir(os.path.dirname(options.outputPath)):
194  o_path = options.outputPath
195  os.mkdir(o_path)
196  else:
197  print ("Output path invalid")
198  return
199 
200  str_l1b_dir = o_path + "/l1b/"
201  if not os.path.isdir(str_l1b_dir):
202  os.mkdir(str_l1b_dir)
203  str_dt_dir = o_path + "/dt/"
204  if not os.path.isdir(str_dt_dir):
205  os.mkdir(str_dt_dir)
206  str_db_dir = o_path + "/db/"
207  if not os.path.isdir(str_db_dir):
208  os.mkdir(str_db_dir)
209  str_anc_dir = o_path + "/anc/"
210  if not os.path.isdir(str_anc_dir):
211  os.mkdir(str_anc_dir)
212  str_cld_dir = o_path + "/cld/"
213  if not os.path.isdir(str_cld_dir):
214  os.mkdir(str_cld_dir)
215 
216  # Download L1A files
217 
218  byear = int(options.begin[0:4])
219  bday = int(options.begin[4:7])
220  bhour = int(options.begin[7:9])
221  bmin = ((int(options.begin[9:13]) + 499)//500) * 500
222  btmin = hour2min(bhour, bmin)
223  eyear = int(options.end[0:4])
224  eday = int(options.end[4:7])
225  ehour = int(options.end[7:9])
226  emin = (int(options.end[9:13])//500) * 500
227  etmin = hour2min(ehour, emin)
228 
229  algs = []
230  if options.alg == "darktarget":
231  algs = ["darktarget"]
232  elif options.alg == "deepblue":
233  algs = ["deepblue"]
234  elif options.alg == "all":
235  algs = ["darktarget", "deepblue"]
236  else:
237  print ("No algorithm specified. Exiting ...")
238  return
239 
240  if byear != eyear:
241  print ("Beginning and end years must be the same. Exiting ...")
242  return
243  elif eday >= bday:
244  t = btmin
245  t24 = hour2min(24,0)
246  tal = etmin + t24*(eday - bday)
247  while t < tal:
248 # get l1b
249  d, h, s = min2hour(t)
250  year, month, day = day2date(byear, bday+d)
251  str_date_time = "%04d%02d%02dT%02d%04d" % (byear, month, day, h, s)
252  str_l1b_name = "PACE_OCI_SIM." + str_date_time + ".L1B.V7.nc"
253  print ("Processing: " + str_l1b_name)
254  sfl1b = str_l1b_dir + str_l1b_name
255  l1b_files = init_dir( str_l1b_dir )
256  if (not sfl1b in l1b_files):
257  srpath = str_url + str_l1b_name
258  command = str_wget + str_wdir + str_l1b_dir + " " + srpath
259  print (command)
260  result = os.system(command)
261 # get cloud mask
262  str_cld_name = "PACE_OCI_SIM." + str_date_time + ".L2.CLDMASK.nc"
263  sfcld = str_cld_dir + str_cld_name
264  cld_files = init_dir( str_cld_dir )
265  if (not sfcld in cld_files):
266  srpath = str_url + str_cld_name
267  command = str_wget + str_wdir + str_cld_dir + " " + srpath
268  print (command)
269  result = os.system(command)
270 # get gdas1 if necessary
271  year, month, day = day2date(byear, bday+d)
272  str_date_hour = "%04d%02d%02dT%02d%04d" % (byear, month, day, h, 0)
273  str_anc_name = "GMAO_MERRA2." + str_date_hour + ".MET.nc"
274  gdas1 = str_anc_dir + str_anc_name
275  anc_files = init_dir( str_anc_dir )
276  if not gdas1 in anc_files:
277  arpath = str_url + str_anc_name
278  command = str_wget + str_wdir + str_anc_dir + " " + arpath
279  print (command)
280  result = os.system(command)
281 # get gdas2 if necessary
282  if (h==23):
283  year, month, day = day2date(byear, bday+d+1)
284  str_date_hour = "%04d%02d%02dT%02d%04d" % (byear, month, day, 0, 0)
285  else:
286  str_date_hour = "%04d%02d%02dT%02d%04d" % (byear, month, day, h+1, 0)
287  str_anc_name = "GMAO_MERRA2." + str_date_hour + ".MET.nc"
288  gdas2 = str_anc_dir + str_anc_name
289  if not gdas2 in anc_files:
290  arpath = str_url + str_anc_name
291  command = str_wget + str_wdir + str_anc_dir + " " + arpath
292  print (command)
293  result = os.system(command)
294 # run the aerosol detection algorithms
295  for alg in algs:
296  if alg == "deepblue":
297  alg_str = "deepblue "
298  opath = str_db_dir + getDbFilename(str_l1b_name)
299  else:
300  alg_str = "darktarget "
301  opath = str_dt_dir + getDtFilename(str_l1b_name)
302  l2par = options.l2_par
303  ialg = " alg=" + alg_str
304  il1b = " ifile=" + sfl1b
305  ianc1 = " gdas1=" + gdas1
306  ianc2 = " gdas2=" + gdas2
307  icld = " cldmask=" + sfcld
308  opth = " ofile=" + opath
309  ogeo = " geolocation" if options.geo else ""
310  oanc = " ancillary" if options.anc else ""
311  oobs = " observations" if options.obs else ""
312  oglnt = " mask_glint=off" if options.glint else ""
313  ocld = " mask_cloud=off" if options.cloud else ""
314  oflt= " short_format=off" if options.float else ""
315  lprw = " lines_per_rw=10"
316  command = "dtdb " + l2par + ialg + il1b + ianc1 + ianc2 + icld + opth + ogeo + oanc + oobs + oglnt + ocld + oflt + lprw
317  print(command)
318  result = os.system(command)
319 # command = "rm " + sfl1b
320  result = os.system(command)
321 
322  t += 500
323 
324  else:
325  print ("Invalid start and end dates specified. Exiting ...")
326  return
327 
328  print ("All L1A files downloaded")
329 
330  LOG.info('Exiting...')
331  return 0
332 
333 if __name__=='__main__':
334  sys.exit(main())
335 
def date2day(year, month, day)
Definition: dtdb_oci.py:50
def min2hour(tot_min)
Definition: dtdb_oci.py:43
def getDtFilename(l1b_name)
Definition: dtdb_oci.py:59
def init_dir(inpath)
Definition: dtdb_oci.py:26
def day2date(year, day_of_year)
Definition: dtdb_oci.py:54
def getDbFilename(l1b_name)
Definition: dtdb_oci.py:63
def main()
Main Function #.
Definition: dtdb_oci.py:71
const char * str
Definition: l1c_msi.cpp:35
def hour2min(hour, min)
Definition: dtdb_oci.py:39