NASA Logo
Ocean Color Science Software

ocssw V2022
l1aextract_netcdf.py
Go to the documentation of this file.
1 #! /usr/bin/env python3
2 
3 # Extractor for L1C files
4 
5 import argparse
6 import datetime
7 from dateutil import tz
8 import netCDF4
9 import numpy as np
10 from os.path import basename
11 import pathlib
12 from shutil import copyfile as cp
13 import sys
14 
15 from seadasutils.setupenv import env
16 from seadasutils.netcdf_utils import ncsubset_vars
17 
18 versionStr = "1.0_2024-11-06"
19 
20 class extract:
21 
22  def __init__(self, ifile, ofile=None,
23  spixl=None, epixl=None, sline=None, eline=None,
24  verbose=False):
25  # inputs
26  self.ifile = pathlib.Path(ifile)
27  self.ofile = pathlib.Path(ofile)
28  self.spixl = spixl
29  self.epixl = epixl
30  self.sline = sline
31  self.eline = eline
32  self.verbose = verbose
33 
34  # defaults
35  self.runtime = None
36  self.attrs = None
37 
38  # unused, but needed by setupenv.py
39  self.dirs = {}
40  self.ancdir = None
41  self.curdir = False
42  self.sensor = None
43  env(self) # run setupenv
44 
45  def runextract(self, subset):
46 
47  srcfile = self.ifile
48  if srcfile.exists():
49  dstfile = self.ofile
50  if self.verbose:
51  print('Extracting', srcfile)
52 
53  ncsubset_vars(srcfile, dstfile, subset, timestamp=self.runtime, verbose=self.verbose)
54 
55  # Read infile as netCDF dataset
56  infile = netCDF4.Dataset(srcfile, 'r')
57  # Read and write outfile as netCDF4 dataset
58  outfile = netCDF4.Dataset(dstfile, 'r+')
59 
60  #_____________________________________________________________________________________________________________________________________
61  # |
62  # Add extract_pixel/line_start/stop: |
63  #_________________________________________________________________________________|
64 
65  if 'extract_pixel_start' in infile.ncattrs():
66  outfile.extract_pixel_start = np.dtype('int32').type(infile.extract_pixel_start + self.spixl + 1)
67  outfile.extract_pixel_stop = np.dtype('int32').type(infile.extract_pixel_stop + self.epixl + 1)
68  outfile.extract_line_start = np.dtype('int32').type(infile.extract_line_start + self.sline + 1)
69  outfile.extract_line_stop = np.dtype('int32').type(infile.extract_line_stop + self.eline + 1)
70  else:
71  outfile.extract_pixel_start = np.dtype('int32').type(self.spixl + 1)
72  outfile.extract_pixel_stop = np.dtype('int32').type(self.epixl + 1)
73 
74  outfile.extract_line_start = np.dtype('int32').type(self.sline + 1)
75  outfile.extract_line_stop = np.dtype('int32').type(self.eline + 1)
76 
77  #_____________________________________________________________________________________________________________________________________
78  # |
79  # Modify time_coverage_start/end of output file: |
80  #_________________________________________________________________________________|
81 
82  # Read infile as netCDF dataset
83  infile = netCDF4.Dataset(srcfile, 'r')
84  # Read and write outfile as netCDF4 dataset
85  outfile = netCDF4.Dataset(dstfile, 'r+')
86  utc = tz.tzutc()
87  scantime = outfile.variables['time'][:]
88  stime = datetime.datetime.fromtimestamp(scantime[0],tz=utc)
89  etime = datetime.datetime.fromtimestamp(scantime[-1],tz=utc)
90  # Change outfile time_coverage_start/end
91  outfile.time_coverage_start = str(stime.strftime('%Y-%m-%dT%H:%M:%S') + 'Z')
92  outfile.time_coverage_end = str(etime.strftime('%Y-%m-%dT%H:%M:%S') + 'Z')
93 
94  def run(self):
95  # convert to zero-based index
96  self.spixl, self.epixl, self.sline, self.eline = \
97  (v-1 for v in (self.spixl, self.epixl, self.sline, self.eline))
98 
99  # extract file
100  subset = {'pixels':[self.spixl, self.epixl],
101  'scans': [self.sline, self.eline]}
102  infile = netCDF4.Dataset(self.ifile, 'r')
103  dims = list(infile.dimensions.keys())
104  infile.close()
105  if 'nsamp' in dims:
106  subset = {'nsamp':[self.spixl, self.epixl],
107  'lines':[self.sline, self.eline]}
108 
109  self.runextract(subset)
110 
111 def chk_pixl(args, infile):
112  if args.epixl == -1:
113  args.epixl = infile.dimensions['pixels'].size
114  if args.eline == -1:
115  args.eline = infile.dimensions['scans'].size
116  return args.spixl, args.epixl, args.sline, args.eline
117 
118 if __name__ == "__main__":
119  print("l1aextract_netcdf", versionStr)
120 
121  # parse command line
122  parser = argparse.ArgumentParser(
123  description='Extract specified area from an L1A netCDF file')
124  parser.add_argument('-v', '--verbose', help='print status messages',
125  action='store_true')
126  parser.add_argument('ifile',
127  help='SeaWiFS Level 1A input file')
128  parser.add_argument('ofile',
129  help='output file')
130 
131  group2 = parser.add_argument_group('pixel/line ranges (1-based)')
132  group2.add_argument('--spixl', type=int, help='start pixel', default = 1)
133  group2.add_argument('--epixl', type=int, help='end pixel', default = -1)
134 
135  group2.add_argument('--sline', type=int, help='start line', default = 1)
136  group2.add_argument('--eline', type=int, help='end line', default = -1)
137 
138  if len(sys.argv) == 1:
139  parser.print_help()
140  sys.exit(1)
141  args = parser.parse_args()
142 
143  # Read infile as netCDF dataset
144  infile = netCDF4.Dataset(args.ifile, 'r')
145 
146  args.spixl, args.epixl, args.sline, args.in_eline = chk_pixl(args, infile)
147 
148  # initialize
149  this = extract(ifile=args.ifile,
150  ofile=args.ofile,
151  spixl=args.spixl,
152  epixl=args.epixl,
153  sline=args.sline,
154  eline=args.eline,
155  verbose=args.verbose)
156 
157  this.run()
def __init__(self, ifile, ofile=None, spixl=None, epixl=None, sline=None, eline=None, verbose=False)
def runextract(self, subset)
list(APPEND LIBS ${NETCDF_LIBRARIES}) find_package(GSL REQUIRED) include_directories($
Definition: CMakeLists.txt:8
void print(std::ostream &stream, const char *format)
Definition: PrintDebug.hpp:38
def env(self)
Definition: setupenv.py:7
def chk_pixl(args, infile)
Definition: aerosol.c:136
def ncsubset_vars(srcfile, dstfile, subset, verbose=False, **kwargs)