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