OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
rfft_oci.py
Go to the documentation of this file.
1 '''
2 * NAME: rfft_oci.py
3 *
4 * DESCRIPTION: Executable program to automate generation of VIIRS Deep Blue
5 * Aerosol products from a directory of L1A files specified in the command line.
6 
7 * USAGE: python mkern_viirs.py -i [input directory] -o [output directory]
8 
9 * Created on July 8, 2019
10 
11 * Author: Samuel Anderson
12 '''
13 
14 import os
15 import sys
16 import logging
17 import time
18 import optparse
19 import numpy as np
20 from numpy import linalg as la
21 from scipy.stats import lognorm
22 from scipy.integrate import quad
23 import matplotlib as mpl
24 import matplotlib.pyplot as plt
25 import matplotlib.image as mpimg
26 from mpl_toolkits.mplot3d import Axes3D
27 from PIL import Image as im
28 import tables
29 import xarray as xr
30 from netCDF4 import num2date
31 import bhmie as bh
32 import mie_kern as mkrn
33 LOG = logging.getLogger('mkern_viirs')
34 from itertools import permutations
35 from random import sample
36 from scipy.linalg import dft
37 
38 
41 
42 def main():
43 
44  args = sys.argv
45 
46  description = '''Generate mie kernal transforms.'''
47  usage = "usage: python mkern_viirs.py -i [input directory] -o [output directory]"
48  version = "v1"
49 
50  parser = optparse.OptionParser(description=description,usage=usage,version=version)
51 
52  # Mandatory arguments
53  mandatoryGroup = optparse.OptionGroup(parser, "Mandatory Arguments",
54  "At a minimum these arguments must be specified")
55 
56  mandatoryGroup.add_option('-i','--in',
57  action="store",
58  dest="idir" ,
59  type="string",
60  help="The full path of the input directory of L1B files to be processed")
61 
62  mandatoryGroup.add_option('-o','--out',
63  action="store",
64  dest="odir" ,
65  type="string",
66  help="The output directory path")
67 
68  parser.add_option_group(mandatoryGroup)
69 
70  # Optional arguments
71  optionalGroup = optparse.OptionGroup(parser, "Extra Options",
72  "These options may be used to customize behavior of this program.")
73 
74  optionalGroup.add_option('-k','--kern',
75  action="store",
76  dest="kern" ,
77  type="string",
78  help="The full path of an input kernel file")
79 
80  parser.add_option('-v', '--verbose',
81  dest='verbosity',
82  action="count",
83  default=0,
84  help='each occurrence increases verbosity 1 level from ERROR: -v=WARNING -vv=INFO -vvv=DEBUG')
85 
86  parser.add_option_group(optionalGroup)
87 
88  # Parse the arguments from the command line
89  (opt, args) = parser.parse_args()
90  # Set up the logging levels
91  levels = [logging.ERROR, logging.WARN, logging.INFO, logging.DEBUG]
92  logging.basicConfig(level = levels[opt.verbosity])
93  # Check that all of the mandatory options are given. If one or more
94  # are missing, print error message and exit...
95  mandatories = []
96  mand_errors = []
97  isMissingMand = False
98  for m,m_err in zip(mandatories,mand_errors):
99  if not opt.__dict__[m]:
100  isMissingMand = True
101  print(m_err)
102  if isMissingMand :
103  print("Incomplete mandatory arguments, aborting...")
104  return
105 
106  # Check that the output directory actually exists
107  opt.odir = os.path.expanduser(opt.odir)
108  LOG.info('Processing files in %s' % (opt.idir) )
109 
110  if not opt.odir:
111  dir = alg + datetime.now().isoformat()
112  o_path = os.getcwd() + dir
113  os.mkdir(o_path)
114  elif os.path.isdir(opt.odir):
115  o_path = opt.odir
116  elif os.path.isdir(os.path.dirname(opt.odir)):
117  o_path = opt.odir
118  os.mkdir(o_path)
119  else:
120  print("Output path invalid")
121  return
122 
123  color_lvl = 8
124  rgb = list(permutations(range(0,256,color_lvl),3))
125  colors = np.array(sample(rgb,120))
126  colors = colors/256.0
127 
128  start = 200
129  stop = 10000
130  m = 1.5+1.0E-10j
131  """
132  for re in np.linspace(1.30, 1.60, 10):
133  m = re+0j
134  name = str(int(re*100)) + "_scaled_"
135  start = 100/(re-1)
136  stop = 10000/(re-1)
137  mk = mkrn.mie_kern(name, 'oci', m, start, stop, 50)
138  kname = mk.save_all(opt.odir)
139  mk.generate()
140  kname = mk.save_all(opt.odir)
141  """
142  if not opt.kern:
143  r = np.real(m)
144  name = str(int(r*100))
145  mk = mkrn.mie_kern(name, 'oci', m, start, stop, 160)
146  mk.generate()
147  kname = mk.save_all(opt.odir)
148  else:
149  mk = mkrn.mie_kern()
150  mk.load(opt.kern)
151 
152  content_oci = os.listdir(opt.idir)
153  content_oci.sort()
154  for x in content_oci:
155  if x[0] == ".":
156  continue
157  inpath = opt.idir + "/" + x
158  if not os.path.isfile(inpath):
159  continue
160  # open oci file and read reflectances into matrix refl
161  fin = tables.open_file(inpath, 'a')
162  refl = np.append(fin.get_node("/", "observation_data/Lt_blue")[8:59], \
163  fin.get_node("/", "observation_data/Lt_red")[1:,:,:],axis=0)
164  shp = refl.shape
165 
166  rayl = (mk.wl[0]/mk.wl[:])**4
167  irayl = 1/rayl
168  unit = np.ones((mk.nwl,mk.nwl))
169  test = (unit.T*irayl).T
170  DFT = dft(mk.nwl)
171  RDFT = DFT*irayl
172  IRDFT = la.inv(RDFT)
173 
174  toc0 = time.perf_counter()
175  frefl = np.tensordot(RDFT,refl,(((1),(0))))
176  toc1 = time.perf_counter()
177  tpp = (toc1-toc0)/shp[1]/shp[2]
178  print("compute inversion", (toc1-toc0), "sec per oci granule,", tpp, "sec per pixel", flush=True)
179 
180  irefl1 = np.absolute(np.tensordot(IRDFT,frefl,(((1),(0)))))
181  toc2 = time.perf_counter()
182  tpp = (toc2-toc1)/shp[1]/shp[2]
183  print("reconstruct reflectance", (toc2-toc1), "sec per oci granule,", tpp, "sec per pixel", flush=True)
184 
185  err = la.norm(refl-irefl1, ord=2, axis=0)
186  toc3 = time.perf_counter()
187  tpp = (toc3-toc2)/shp[1]/shp[2]
188  print("compute rms error", (toc3-toc2), "sec per oci granule,", tpp, "sec per pixel", flush=True)
189 
190  frefl[0,:,:] = 0
191  irefl2 = np.absolute(np.tensordot(IRDFT,frefl,(((1),(0)))))
192  toc4 = time.perf_counter()
193  tpp = (toc4-toc3)/shp[1]/shp[2]
194  print("reconstruct reflectance", (toc2-toc1), "sec per oci granule,", tpp, "sec per pixel", flush=True)
195 
196  fname = opt.odir + "/RFFT_" + x + mk.name + ".png"
197  print( fname )
198 
199  plt.clf()
200  fig, axs = plt.subplots(nrows=2, ncols=2, figsize=(50, 30))
201  fig.suptitle('Rayleigh adapted fourier transform: ' )
202  axs[0,0].set(xlabel='Wavelength (Nm)', ylabel='Reflectance',
203  title='Measured Reflectance as a function of Wavelength')
204  axs[0,0].grid(b=True, which='both', axis='both')
205  axs[1,0].set(xlabel='wavelength', ylabel='Rayleigh-corrected Reflectance',
206  title='Rayleigh adapted Fourier Transform')
207  axs[1,0].grid(b=True, which='both', axis='both')
208  axs[1,1].set(xlabel='Root sum of squares error ', ylabel='Frequency in Granule',
209  title='Histogram of errors in reconstructed reflectance')
210  axs[1,1].grid(b=True, which='both', axis='both')
211  axs[0,1].set(title='Rayleigh-Corrected True color image')
212 
213  ro = irefl2[np.where(mk.wl==670)]
214  go = irefl2[np.where(mk.wl==550)]
215  bo = irefl2[np.where(mk.wl==485)]
216  maxo_all = max(np.max(ro), np.max(go), np.max(bo)) + 0.001
217  ro /= maxo_all
218  go /= maxo_all
219  bo /= maxo_all
220  gamma = 0.5
221  ga = np.ones_like(ro[0])*gamma
222  rg = np.power(ro[0], ga)
223  gg = np.power(go[0], ga)
224  bg = np.power(bo[0], ga)
225 
226  scale = 255
227  im_red = im.fromarray(np.uint8(np.clip(rg,0,1.0)*scale))
228  im_green = im.fromarray(np.uint8(np.clip(gg,0,1.0)*scale))
229  im_blue = im.fromarray(np.uint8(np.clip(bg,0,1.0)*scale))
230 
231  im_rgb = im.merge("RGB", (im_red, im_green, im_blue))
232  axs[0,1].imshow(im_rgb)
233  freq = range(mk.nwl)
234  column = 1050
235  for i in range(0,1700,100):
236  axs[0,0].plot(mk.wl,refl[:,i,column])
237  axs[0,0].plot(mk.wl,irefl1[:,i,column], color=colors[int(7*i)%120])
238  axs[1,0].plot(mk.wl,irefl2[:,i,column], color=colors[int(7*i)%120])
239  axs[0,1].scatter(column,i,marker=".",color=colors[int(7*i)%120])
240  ehist,be = np.histogram(err)
241  axs[1,1].semilogy(be[:-1],ehist)
242  # rhist,be = np.histogram(ratio, bins=20)
243  # axs[1,1].semilogy(be[:-1],rhist)
244  # plt.show(block=True)
245  plt.savefig(fname)
246  plt.close(fig)
247  fin.close()
248 
249  LOG.info('Exiting...')
250 
251 if __name__=='__main__':
252  sys.exit(main())
253 
list(APPEND LIBS ${PGSTK_LIBRARIES}) add_executable(atteph_info_modis atteph_info_modis.c) target_link_libraries(atteph_info_modis $
Definition: CMakeLists.txt:7
def main()
Main Function #.
Definition: rfft_oci.py:42
const char * str
Definition: l1c_msi.cpp:35