Due to the lapse in federal government funding, NASA is not updating this website. We sincerely regret this inconvenience.
NASA Logo
Ocean Color Science Software

ocssw V2022
l2merge.py
Go to the documentation of this file.
1 #! /usr/bin/env python3
2 
3 '''
4 This L2 aggregator script will:
5 1. Take in L2 files
6 2. Merge data
7 '''
8 
9 import argparse
10 import pathlib
11 import sys
12 import netCDF4
13 import os
14 
15 __version__ = "1.0"
16 verbose = False
17 
18 
19 # Copy groups from topB to topA
20 
21 def copyGroups(topA, topB):
22  for group_name, group in topB.groups.items():
23  topA.createGroup(group_name)
24 
25  # Copy group attributes
26  for attr in group.ncattrs():
27  topA[group_name].setncattr(attr, group.getncattr(attr))
28 
29  # bail before copying variables from the geophysical_data group
30  if group_name == "geophysical_data":
31  continue
32 
33  if verbose:
34  print("copying variables for group", group_name, ":")
35 
36  # Iterate through variables and copy all variables and their attributes
37  for name, variable in group.variables.items():
38  if verbose:
39  print(" ", name)
40 
41  if "_FillValue" in variable.ncattrs():
42  fill_value = variable.getncattr("_FillValue")
43  else:
44  fill_value = None
45 
46  topA[group_name].createVariable(name, variable.datatype, variable.dimensions, fill_value=fill_value)
47 
48  for attr in variable.ncattrs():
49  if attr != "_FillValue":
50  topA[group_name].variables[name].setncattr(attr, variable.getncattr(attr))
51 
52  topA[group_name].variables[name][:] = variable[:]
53 
54  if len(group.groups) != 0:
55  copyGroups(topA[group_name], group)
56 
57 
58 def merge(idatasets, mergefile, products):
59 
60  # delete output file if it exists
61  try:
62  os.remove(mergefile)
63  except OSError as e:
64  pass
65 
66  # Create output file
67  orootgrp = netCDF4.Dataset(pathlib.Path(mergefile), "w", format="NETCDF4")
68 
69  # Create dimensions for output file. Note all L2 files will/should have the same dimensions.
70  for name, dim in idatasets[0].dimensions.items():
71  orootgrp.createDimension(name, len(dim) if not dim.isunlimited() else None)
72 
73  # copy global attributes from first L2 file into mergefile
74  for attr in idatasets[0].ncattrs():
75  if attr == "product_name":
76  orootgrp.setncattr(attr, mergefile)
77  else:
78  orootgrp.setncattr(attr, idatasets[0].getncattr(attr))
79 
80  # recursively copy first dataset's contents into orootgrp except for geophysical_data
81  copyGroups(orootgrp, idatasets[0])
82 
83  if verbose:
84  print("copying variables for group geophysical_data:")
85 
86  # merge geophysical_data
87  # combining geophysical data from each dataset in idatasets
88  geophysical_data = orootgrp["/geophysical_data"]
89  for ds in idatasets:
90  for name, ivariable in ds['/geophysical_data'].variables.items():
91  if name in products:
92  if (name not in geophysical_data.variables):
93  if verbose:
94  print(" ", name)
95 
96  if "_FillValue" in ivariable.ncattrs():
97  fill_value = ivariable.getncattr("_FillValue")
98  else:
99  fill_value = None
100  ovariable = geophysical_data.createVariable(name, ivariable.datatype, ivariable.dimensions, fill_value=fill_value)
101 
102  for attr in ivariable.ncattrs():
103  #create a new attribute name/value pair
104  if attr != "_FillValue":
105  ovariable.setncattr(attr, ivariable.getncattr(attr))
106 
107  ovariable[:] = ivariable[:]
108 
109  orootgrp.close()
110 
111 
112 if __name__ == "__main__":
113 
114  # parse command line
115  parser = argparse.ArgumentParser(
116  description='Merge Level 2 files')
117  parser.add_argument('--version', action='store_true', help='print program version')
118  parser.add_argument('-v', '--verbose', help='print status messages', action='store_true')
119  parser.add_argument('ifile', help='Input text file specifying L2 files to be merged')
120  parser.add_argument('ofile', help='Output netcdf file which will contain merged L2 file data')
121  parser.add_argument('--product', type=str, help='product(s) to map; comma separated', default = "None")
122 
123  print("l2merge", __version__)
124  if len(sys.argv) == 1:
125  parser.print_help()
126  sys.exit(1)
127 
128  if(sys.argv[1] == "--version"):
129  sys.exit(0)
130 
131  args = parser.parse_args()
132  verbose = args.verbose
133 
134  # Read and store each line in the .txt infile as a netcdf dataset
135  idatasets = []
136  try:
137  with open(args.ifile) as infile:
138  for line in infile:
139  idatasets.append(netCDF4.Dataset(line.strip(), 'r'))
140  except IOError as e:
141  print("Error when trying to open input file: ", e)
142  infile.close()
143 
144  products = args.product.split(",")
145  products.append("l2_flags")
146 
147  print("Merging datasets...")
148  try:
149  merge(idatasets, args.ofile, products)
150  print("Merging was successful")
151  except Exception as e:
152  print("Unable to merge L2 files: ", e)
def merge(idatasets, mergefile, products)
Definition: l2merge.py:58
character(len=1000) if
Definition: names.f90:13
def copyGroups(topA, topB)
Definition: l2merge.py:21
void print(std::ostream &stream, const char *format)
Definition: PrintDebug.hpp:38