OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
l2mapgen.py
Go to the documentation of this file.
1 #!/usr/bin/env python3
2 import argparse
3 import sys
4 import re
5 import subprocess
6 import os
7 import seadasutils.MetaUtils as MetaUtils
8 from seadasutils.ParamUtils import ParamProcessing
9 
10 def getBinRes(resolution):
11  resvalue = 2000
12 
13  if "km" in resolution:
14  resvalue = float(resolution.strip('km')) * 1000.
15  elif "m" in resolution:
16  resvalue = float(resolution.strip('m'))
17  elif "deg" in resolution:
18  resvalue = float(resolution.strip('deg')) * 111312.
19 
20  if resvalue <= 99.0 :
21  return 'HH'
22  elif resvalue < 250.0:
23  return 'HQ'
24  elif resvalue < 500.0:
25  return 'Q'
26  elif resvalue < 1150.0:
27  return 'H'
28  elif resvalue < 2300.0:
29  return '1'
30  elif resvalue < 4600.0:
31  return '2'
32  elif resvalue < 9200. :
33  return '4'
34  else:
35  return '9'
36 
37 if __name__ == "__main__":
38 
39  parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter,description='''\
40  This program takes a product from a L2 file, maps it using a Plate Carree cylindrical projection,
41  and produces a gray scale PGM or color PPM file.
42 
43  The arguments can be specified on the commandline, or put into a parameter file,
44  or the two methods can be used together, with commandline over-riding.''',add_help=True)
45  parser.add_argument('--parfile', type=str, help='input parameter file')
46  parser.add_argument('ifile', nargs='?', type=str, help='input file (L1A/B file or file with list)')
47  parser.add_argument('--geofile', nargs='?', type=str,help='input file geolocation file name')
48  parser.add_argument('--ofile', type=str, help='output file name; default = <ifile>.L2_MAP.<oformat extension>')
49  parser.add_argument('--product', type=str, help='product(s) to map; comma separated')
50  parser.add_argument('--resolution', type=str, default='2.0km', help='''\
51 
52  resolution
53  -----------------
54  #.#: resolution in meters
55  #.#km: resolution in kilometers
56  #.#deg: resolution in degrees
57  ''')
58  parser.add_argument('--oformat', choices=['netcdf4','hdf4','png','ppm','tiff'], type=str, default="png", help=('''\
59  output file format
60  --------------------------------------------------------
61  netcdf4: netCDF4 file, can contain more than one product
62  hdf4: HDF4 file (old SMI format)
63  png: PNG image file
64  ppm: PPM image file
65  tiff: TIFF file with georeference tags
66  '''))
67  parser.add_argument('--north', type=float, help=('Northern most Latitude (-999=file north)'))
68  parser.add_argument('--south', type=float, help=('Southern most Latitude (-999=file south)'))
69  parser.add_argument('--east', type=float, help=('Eastern most Latitude (-999=file east)'))
70  parser.add_argument('--west', type=float, help=('Western most Latitude (-999=file west)'))
71  parser.add_argument('--projection', type=str,default='platecarree', help='''\
72  enter a proj.4 projection string or choose one of the following
73  predefined projections:
74  --------------------------------------------------------------
75  smi: Standard Mapped image, cylindrical projection, uses
76  central_meridian. n,s,e,w default to whole globe.
77  projection="+proj=eqc +lat_0=<central_meridian>"
78  platecarree: Plate Carree image, cylindrical projection, uses
79  central_meridian
80  projection="+proj=eqc +lat_0=<central_meridian>"
81  mollweide: Mollweide projection
82  projection="+proj=moll +lat_0=<central_meridian>"
83  lambert: Lambert conformal conic projection
84  projection="+proj=lcc +lat_0=<central_meridian>"
85  albersconic: Albers equal-area conic projection
86  projection="+proj=aea +lat_0=<central_meridian>"
87  mercator: Mercator cylindrical map projection
88  projection="+proj=merc +lat_0=<central_meridian>"
89  ease2: Ease Grid 2 projection
90  projection="+proj=cea +lon_0=0 +lat_ts=30 +ellps=WGS84
91  +datum=WGS84 +units=m +lat_0=<central_meridian>"
92  conus: USA Contiguous Albers Equal Area-Conic projection, USGS"
93  projection="+proj=aea +lat_1=29.5 +lat_2=45.5
94  +lat_0=23.0 +lon_0=-96 +x_0=0 +y_0=0
95  +ellps=GRS80 +datum=NAD83 +units=m +no_defs"
96  ''')
97  parser.add_argument('--central_meridian', type=float, help='central meridian for projection in deg east. Only used for smi, mollweide and raw projection')
98  parser.add_argument('--palfile', type=str, help='palette filename. Default uses file for product in product.xml')
99  parser.add_argument('--fudge', type=float,default=1.0, help='fudge factor used to modify size of L3 pixels')
100  parser.add_argument('--threshold', type=float,default=0, help='minimum percentage of filled pixels before an image is generated')
101  parser.add_argument('--datamin', type=float, help=('minimum value for scaling (default from product.xml)'))
102  parser.add_argument('--datamax', type=float, help=('maximum value for scaling (default from product.xml)'))
103  parser.add_argument('--scaletype', choices=['linear','log','arctan'],type=float, help='''\
104  data scaling type (default from product.xml)
105  ---------------------------------------------
106  linear: linear scaling
107  log: logarithmic scaling
108  arctan: arc tangent scaling
109 
110  ''')
111  parser.add_argument('--keep-intermediates', action='store_true',default=False, help='Do not delete the intermediate L2/L3B files produced')
112  parser.add_argument('-v','--verbose',action='count',default=0, help="Let's get chatty. Two -v's a better than one.")
113 
114  args=parser.parse_args()
115 
116  if args.parfile:
117  param_proc = ParamProcessing(parfile=args.parfile)
118  param_proc.parseParFile()
119  for param in (param_proc.params['main'].keys()):
120  value = param_proc.params['main'][param]
121  if hasattr(args,param):
122  setattr(args,param,value)
123  elif param == 'file':
124  args.ifile = value
125 
126  if not args.ifile:
127  parser.error("You must specify an input file either on the command line or in a parameter file")
128 
129  if not args.product:
130  parser.error("You must specify at least one product to map, either on the command line or in a parameter file")
131 
132  if not args.ofile:
133  extension = args.oformat
134  if extension == 'netcdf4':
135  extension = 'nc'
136  setattr(args,'ofile',args.ifile + '.L2_MAP.' + extension)
137 
138  default_opts=["product", "datamin", "datamax", "scaletype", "palfile", "north", "south", "east", "west", "central_meridian"]
139  l2bin_opts = ["product", "resolution"]
140  l3map_opts = ["product", "resolution", "oformat", "north", "south", "west", "east", "projection", "central_meridian", "palfile", "fudge", "threshold"]
141 
142  tmpfile = args.ifile + '.L3b'
143 
144  if args.verbose > 1:
145  print(args)
146 
147  # Build the l2bin command line
148  clo = ["l2bin"]
149  clo.append('flaguse=ATMFAIL,CLDICE,BOWTIEDEL')
150  clo.append("ifile=" + args.ifile)
151  clo.append("ofile=" + tmpfile)
152  clo.append("area_weighting=1")
153  for l2bin_opt in l2bin_opts:
154  if getattr(args,l2bin_opt):
155  if l2bin_opt == 'resolution':
156  clo.append(l2bin_opt + "=" + getBinRes(str(getattr(args,l2bin_opt))))
157  elif l2bin_opt == 'product':
158  clo.append("l3bprod" + "=" + str(getattr(args,l2bin_opt)))
159  else:
160  clo.append(l2bin_opt + "=" + str(getattr(args,l2bin_opt)))
161 
162  if args.verbose:
163  print("l2bin parameters:")
164  print(clo)
165 
166  try:
167  if args.verbose > 1:
168  subprocess.run(clo,check=True)
169  else:
170  subprocess.run(clo,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,check=True)
171  if args.verbose:
172  print("Generated bin file %s" % tmpfile)
173 
174  except subprocess.CalledProcessError as e:
175  print("Process error ({0}): message:{1}".format(str(e.returncode), e.output))
176  sys.exit()
177 
178  # Build the l3mapgen command line
179  clo = ["l3mapgen"]
180  clo.append('ifile=' + tmpfile)
181  clo.append('interp=nearest')
182  for opt in l3map_opts:
183  if getattr(args,opt):
184  if type(getattr(args,opt)) is bool: # handle boolean options
185  clo.append(opt + "=1" )
186  elif opt == 'product':
187  if args.oformat == 'netcdf4':
188  clo.append("product=" + args.product)
189  else:
190  clo.append(opt + "=" + str(getattr(args,opt)))
191 
192  if args.verbose:
193  print("l3mapgen parameters:")
194  print(clo)
195 
196  if args.oformat == 'netcdf4':
197  try:
198  clo.append('ofile=' + args.ofile)
199  if args.verbose > 1:
200  subprocess.run(clo,check=True)
201  else:
202  subprocess.run(clo,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,check=True)
203  if args.verbose:
204  print("Generated map file %s" % args.ofile)
205  except subprocess.CalledProcessError as e:
206  print("Process error ({0}): message:{1}".format(str(e.returncode), e.output))
207  sys.exit()
208  else:
209  for prod in args.product.split(','):
210  prod_clo = clo
211  prod_clo.append("product=" + prod)
212  ofile = args.ofile
213 
214  if len(args.product.split(',')) > 1:
215  ofile = args.ofile.replace(args.oformat,'') + prod + '.' + args.oformat
216 
217  prod_clo.append('ofile=' + ofile)
218  try:
219  if args.verbose > 1:
220  subprocess.run(prod_clo,check=True)
221  else:
222  subprocess.run(prod_clo,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,check=True)
223  if args.verbose:
224  print("Generated map file %s" % ofile)
225  except subprocess.CalledProcessError as e:
226  print("Process error ({0}): message:{1}".format(str(e.returncode), e.output))
227  sys.exit()
228 
229  if not args.keep_intermediates:
230  os.remove(tmpfile)
231  if args.verbose:
232  print("Deleted %s" % tmpfile)
def getBinRes(resolution)
Definition: l2mapgen.py:10