5 A script to convert PRISM data from the CORAL project
6 to netCDF proxy data in the format of PACE-OCI
7 written by J.Scott on 2017/10/03 (joel.scott@nasa.gov)
14 from PRISM_module
import readL1B, readL2, readL3
15 from netCDF4
import Dataset
16 from datetime
import datetime, timedelta
19 parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter,description=
'''\
20 This script converts PRISM data from the CORAL project to netCDF
22 A single netCDF4 OB.DAAC L2 file of L1, L2, and L3 PRISM data products from the CORAL project
24 The argument-list is a set of --keyword value pairs.
26 prismcoral2nc.py --l1dir=$HOME/prm20160908t234616_rdn_v1p1 --l2dir=$HOME/prm20160908t234616_rb_v1p1 --l3dir=$HOME/prm20160908t234616_bc_v1p1
28 Compatibility: This script was developed for Python 3.6
30 /*=====================================================================*/
31 NASA Goddard Space Flight Center (GSFC)
32 Software distribution policy for Public Domain Software
34 The fd_matchup.py code is in the public domain, available without fee for
35 educational, research, non-commercial and commercial purposes. Users may
36 distribute this code to third parties provided that this statement appears
37 on all copies and that no charge is made for such copies.
39 NASA GSFC MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THE SOFTWARE
40 FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED
41 WARRANTY. NEITHER NASA GSFC NOR THE U.S. GOVERNMENT SHALL BE LIABLE FOR
42 ANY DAMAGE SUFFERED BY THE USER OF THIS SOFTWARE.
43 /*=====================================================================*/
46 parser.add_argument(
'--l1dir', nargs=1, required=
True, type=str, help=
'''\
47 String specifier for PRISM L1(B) data dir
48 (i.e. - folder where L1 tar.gz bundle was unzipped to)
51 parser.add_argument(
'--l2dir', nargs=1, required=
True, type=str, help=
'''\
52 String specifier for PRISM L2 data dir
53 (i.e. - folder where L2 tar.gz bundle was unzipped to)
56 parser.add_argument(
'--l3dir', nargs=1, required=
True, type=str, help=
'''\
57 String specifier for PRISM L3 data dir
58 (i.e. - folder where L3 tar.gz bundle was unzipped to)
61 parser.add_argument(
'--odir', nargs=1, type=str, default=([
'./']), help=(
'''\
62 OPTIONAL: output directory
63 If none provided, netCDF data will be saved to the current working directory
66 args=parser.parse_args()
68 if not args.l1dir
or not args.l2dir
or not args.l3dir:
69 parser.error(
"you must specify l1dir, l2dir, and l3dir")
74 if '/' in dict_args[
'l1dir'][0][-1]:
75 dict_args[
'l1dir'][0] = dict_args[
'l1dir'][0][:-1]
77 if '/' in dict_args[
'l2dir'][0][-1]:
78 dict_args[
'l2dir'][0] = dict_args[
'l2dir'][0][:-1]
80 if '/' in dict_args[
'l3dir'][0][-1]:
81 dict_args[
'l3dir'][0] = dict_args[
'l3dir'][0][:-1]
83 if '/' in dict_args[
'odir'][0][-1]:
84 dict_args[
'odir'][0] = dict_args[
'odir'][0][:-1]
87 print(
'Reading PRISM L1 files from:',dict_args[
'l1dir'][0])
88 dsL1 = readL1B(dict_args[
'l1dir'][0])
90 print(
'Reading PRISM L2 files from:',dict_args[
'l2dir'][0])
91 dsL2 =
readL2(dict_args[
'l2dir'][0])
93 print(
'Reading PRISM L3 files from:',dict_args[
'l3dir'][0])
94 dsL3 = readL3(dict_args[
'l3dir'][0])
97 dt_start = dsL1.hdr[
'rdn_img'][
'start datetime']
98 nc_fname = dt_start.strftime(
'PRM%Y%j%H%M%S.L2.nc')
101 nc_fullpath = dict_args[
'odir'][0] +
'/' + nc_fname
102 print(
'Creating netCDF4 file',nc_fullpath)
103 nc_fid = Dataset(nc_fullpath,
'w', clobber=
True, format=
'NETCDF4')
106 print(
'Creating global attributes')
107 nc_fid.title =
"PRISM Level-2 Data"
108 nc_fid.sensor =
"PRISM (Portable Remote Imaging SpectroMeter)"
109 nc_fid.instrument =
"PRISM"
110 nc_fid.platform =
"Tempus Applied Solutions Gulfstream-IV"
111 nc_fid.product_name = nc_fname
112 nc_fid.processing_version =
"V1.0"
113 nc_fid.prism_version = dsL1.hdr[
'rdn_img'][
'prism_version']
114 nc_fid.Conventions =
"CF-1.6"
115 nc_fid.institution =
"NASA Jet Propulsion Laboratory/California Institute of Technology"
116 nc_fid.license =
"https://science.nasa.gov/earth-science/earth-science-data/data-information-policy/"
117 nc_fid.naming_authority =
"gov.nasa.gsfc.sci.oceandata"
118 dt_now = datetime.now()
119 nc_fid.date_created = dt_now.strftime(
"%Y-%m-%dT%H:%M:%SZ")
120 nc_fid.keywords_vocabulary =
"NASA Global Change Master Directory (GCMD) Science Keywords"
121 nc_fid.stdname_vocabulary =
"NetCDF Climate and Forecast (CF) Metadata Convention"
122 nc_fid.creator_name =
"Jet Propulsion Laboratory/California Institute of Technology"
123 nc_fid.creator_email =
"sarah.r.lundeen@jpl.nasa.gov"
124 nc_fid.creator_url =
"https://prism.jpl.nasa.gov/index.html"
125 nc_fid.project =
"CORAL EVS-2"
126 nc_fid.project_url =
"https://coral.jpl.nasa.gov/"
127 nc_fid.publisher_name =
"NASA Goddard Space Flight Center (GSFC), OB.DAAC"
128 nc_fid.publisher_url =
"https://oceancolor.gsfc.nasa.gov"
129 nc_fid.publisher_email =
"data@oceancolor.gsfc.nasa.gov"
130 nc_fid.identifier_product_doi_authority =
"http://dx.doi.org"
131 nc_fid.identifier_product_doi =
"10.5067/PRISM/CORAL/L2/RBEN/V1"
132 nc_fid.processing_level =
"L2"
133 nc_fid.spatialResolution = dsL1.hdr[
'rdn_img'][
'map info'][5] +
" m"
134 nc_fid.flight_line = dt_start.strftime(
"prm%Y%j%H%M%S")
135 nc_fid.history =
"netCDF4 file created by OCSSW's prismcoral2nc.py using Level-1, Level-2, and Level-3 flight line data from the Portable Remote Imaging SpectroMeter (PRISM) instrument mounted on Tempus Applied Solutions Gulfstream-IV (G-IV) aircraft flying at a nominal operating altitude of 8.5 km from the COral Reef Airborne Laboratory (CORAL) Earth Venture Suborbital-2 (EVS-2) project. Input files were " + dict_args[
'l1dir'][0].split(
'/')[-1] +
', ' + dict_args[
'l2dir'][0].split(
'/')[-1] +
', and ' + dict_args[
'l3dir'][0].split(
'/')[-1];
136 nc_fid.time_coverage_start = dt_start.strftime(
"%Y-%m-%dT%H:%M:%SZ")
137 dt_end = dt_start + timedelta(microseconds=np.nanmax(dsL1.data[
'utc time']))
138 nc_fid.time_coverage_end = dt_end.strftime(
"%Y-%m-%dT%H:%M:%SZ")
139 nc_fid.northernmost_latitude =
float(np.nanmax(dsL1.data[
'latitude (wgs-84)']))
140 nc_fid.southernmost_latitude =
float(np.nanmin(dsL1.data[
'latitude (wgs-84)']))
141 nc_fid.easternmost_longitude =
float(np.nanmax(dsL1.data[
'longitude (wgs-84)']))
142 nc_fid.westernmost_longitude =
float(np.nanmin(dsL1.data[
'longitude (wgs-84)']))
143 nc_fid.geospatial_lat_units =
"degrees_north" ;
144 nc_fid.geospatial_lon_units =
"degrees_east" ;
145 nc_fid.geospatial_lat_max =
float(np.nanmax(dsL1.data[
'latitude (wgs-84)']))
146 nc_fid.geospatial_lat_min =
float(np.nanmin(dsL1.data[
'latitude (wgs-84)']))
147 nc_fid.geospatial_lon_max =
float(np.nanmax(dsL1.data[
'longitude (wgs-84)']))
148 nc_fid.geospatial_lon_min =
float(np.nanmin(dsL1.data[
'longitude (wgs-84)']))
149 nc_fid.day_night_flag =
"Day"
150 nc_fid.earth_sun_distance_correction =
float(np.nanmean(dsL1.data[
'earth-sun distance (au)']))
153 print(
'Creating dimensions')
154 nc_fid.createDimension(
'number_of_scans', dsL1.data[
'utc time'].shape[0])
155 nc_fid.createDimension(
'pixels_per_scan', dsL1.data[
'utc time'].shape[1])
156 nc_fid.createDimension(
'number_of_bands', len(dsL1.hdr[
'rdn_img'][
'wavelength']))
157 nc_fid.createDimension(
'number_of_benthic_bands', len(dsL2.hdr[
'rb_img'][
'wavelength']))
160 print(
'Creating groups')
161 nc_fid.createGroup(
'/sensor_band_parameters')
162 nc_fid.createGroup(
'/scan_line_attributes')
163 nc_fid.createGroup(
'/navigation_data')
164 nc_fid.createGroup(
'/observation_data')
165 nc_fid.createGroup(
'/derived_data')
168 print(
'Creating and writing sensor_band_parameters')
169 nc_wavelength = nc_fid.createVariable(
'/sensor_band_parameters/wavelength',
171 dimensions=(
'number_of_bands',),
174 chunksizes=(nc_fid.dimensions[
'number_of_bands'].size,),
176 nc_wavelength.long_name =
'Band center wavelengths'
177 nc_wavelength.units =
'nm'
178 nc_wavelength.valid_min = 350.0
179 nc_wavelength.valid_max = 1050.0
180 nc_wavelength[:] = [
float(d)
for d
in dsL1.hdr[
'rdn_img'][
'wavelength']]
182 nc_fwhm = nc_fid.createVariable(
'/sensor_band_parameters/fwhm',
184 dimensions=(
'number_of_bands',),
187 chunksizes=(nc_fid.dimensions[
'number_of_bands'].size,),
189 nc_fwhm.long_name =
'Band full-width half-maximums'
191 nc_fwhm.valid_min = 0.0
192 nc_fwhm.valid_max = 100.0
193 nc_fwhm[:] = [
float(d)
for d
in dsL1.hdr[
'rdn_img'][
'fwhm']][:nc_fid.dimensions[
'number_of_bands'].size]
195 nc_rbwavelength = nc_fid.createVariable(
'/sensor_band_parameters/benthic_wavelength',
197 dimensions=(
'number_of_benthic_bands',),
200 chunksizes=(nc_fid.dimensions[
'number_of_benthic_bands'].size,),
202 nc_rbwavelength.long_name =
'Band center benthic reflectance wavelengths'
203 nc_rbwavelength.units =
'nm'
204 nc_rbwavelength.valid_min = 350.0
205 nc_rbwavelength.valid_max = 1035.0
206 nc_rbwavelength[:] = [
float(d)
for d
in dsL2.hdr[
'rb_img'][
'wavelength']]
209 print(
'Creating and writing scan_line_attributes')
210 nc_scan_start_time = nc_fid.createVariable(
'/scan_line_attributes/scan_start_time',
212 dimensions=(
'number_of_scans',),
215 chunksizes=(nc_fid.dimensions[
'number_of_scans'].size,),
217 nc_scan_start_time.long_name =
'Scan start time (UTC)'
218 nc_scan_start_time.units =
'seconds'
219 nc_scan_start_time.valid_min = 0.
220 nc_scan_start_time.valid_max = 2000000000.
221 dsL1.data[
'scan_start_time'][np.isnan(dsL1.data[
'scan_start_time'])] = nc_scan_start_time._FillValue
222 nc_scan_start_time[:] = dsL1.data[
'scan_start_time']
224 nc_scan_end_time = nc_fid.createVariable(
'/scan_line_attributes/scan_end_time',
226 dimensions=(
'number_of_scans',),
229 chunksizes=(nc_fid.dimensions[
'number_of_scans'].size,),
231 nc_scan_end_time.long_name =
'Scan end time (UTC)'
232 nc_scan_end_time.units =
'seconds'
233 nc_scan_end_time.valid_min = 0.
234 nc_scan_end_time.valid_max = 2000000000.
235 dsL1.data[
'scan_end_time'][np.isnan(dsL1.data[
'scan_end_time'])] = nc_scan_end_time._FillValue
236 nc_scan_end_time[:] = dsL1.data[
'scan_end_time']
239 print(
'Creating and writing navigation_data')
240 nc_lon = nc_fid.createVariable(
'/navigation_data/longitude',
242 dimensions=(
'number_of_scans',
'pixels_per_scan'),
245 chunksizes=(1,nc_fid.dimensions[
'pixels_per_scan'].size),
247 nc_lon.long_name =
'Longitudes of pixel locations'
248 nc_lon.units =
'degrees_east'
249 nc_lon.valid_min = -180.
250 nc_lon.valid_max = 180.
251 dsL1.data[
'longitude (wgs-84)'][np.isnan(dsL1.data[
'longitude (wgs-84)'])] = nc_lon._FillValue
252 nc_lon[:,:] = dsL1.data[
'longitude (wgs-84)']
254 nc_lat = nc_fid.createVariable(
'/navigation_data/latitude',
256 dimensions=(
'number_of_scans',
'pixels_per_scan'),
259 chunksizes=(1,nc_fid.dimensions[
'pixels_per_scan'].size),
261 nc_lat.long_name =
'Latitudes of pixel locations'
262 nc_lat.units =
'degrees_north'
263 nc_lat.valid_min = -90.
264 nc_lat.valid_max = 90.
265 dsL1.data[
'latitude (wgs-84)'][np.isnan(dsL1.data[
'latitude (wgs-84)'])] = nc_lat._FillValue
266 nc_lat[:,:] = dsL1.data[
'latitude (wgs-84)']
268 nc_altitude = nc_fid.createVariable(
'/navigation_data/height',
270 dimensions=(
'number_of_scans',
'pixels_per_scan'),
273 chunksizes=(1,nc_fid.dimensions[
'pixels_per_scan'].size),
275 nc_altitude.long_name =
'Terrain height at pixel locations'
276 nc_altitude.units =
'meters'
277 nc_altitude.valid_min = -1000.
278 nc_altitude.valid_max = 10000.
279 dsL1.data[
'elevation (m)'][np.isnan(dsL1.data[
'elevation (m)'])] = nc_altitude._FillValue
280 nc_altitude[:,:] = dsL1.data[
'elevation (m)']
282 nc_range = nc_fid.createVariable(
'/navigation_data/range',
284 dimensions=(
'number_of_scans',
'pixels_per_scan'),
287 chunksizes=(1,nc_fid.dimensions[
'pixels_per_scan'].size),
289 nc_range.long_name =
'Aircraft-to-pixel range'
290 nc_range.units =
'meters'
291 nc_range.valid_min = 0.
292 nc_range.valid_max = 25000.
293 dsL1.data[
'path length (m)'][np.isnan(dsL1.data[
'path length (m)'])] = nc_range._FillValue
294 nc_range[:,:] = dsL1.data[
'path length (m)']
296 nc_senz = nc_fid.createVariable(
'/navigation_data/sensor_zenith',
298 dimensions=(
'number_of_scans',
'pixels_per_scan'),
301 chunksizes=(1,nc_fid.dimensions[
'pixels_per_scan'].size),
303 nc_senz.long_name =
'Sensor zenith angle at pixel locations'
304 nc_senz.units =
'degrees'
305 nc_senz.valid_min = 0.
306 nc_senz.valid_max = 90.
307 dsL1.data[
'to-sensor zenith (0 to 90 degrees from zenith)'][np.isnan(dsL1.data[
'to-sensor zenith (0 to 90 degrees from zenith)'])] = nc_senz._FillValue
308 nc_senz[:,:] = dsL1.data[
'to-sensor zenith (0 to 90 degrees from zenith)']
310 nc_sena = nc_fid.createVariable(
'/navigation_data/sensor_azimuth',
312 dimensions=(
'number_of_scans',
'pixels_per_scan'),
315 chunksizes=(1,nc_fid.dimensions[
'pixels_per_scan'].size),
317 nc_sena.long_name =
'Sensor azimuth angle at pixel locations'
318 nc_sena.units =
'degrees'
319 nc_sena.valid_min = 0.
320 nc_sena.valid_max = 360.
321 dsL1.data[
'to-sensor azimuth (0 to 360 degrees cw from n)'][np.isnan(dsL1.data[
'to-sensor azimuth (0 to 360 degrees cw from n)'])] = nc_sena._FillValue
322 nc_sena[:,:] = dsL1.data[
'to-sensor azimuth (0 to 360 degrees cw from n)']
324 nc_solz = nc_fid.createVariable(
'/navigation_data/solar_zenith',
326 dimensions=(
'number_of_scans',
'pixels_per_scan'),
329 chunksizes=(1,nc_fid.dimensions[
'pixels_per_scan'].size),
331 nc_solz.long_name =
'Solar zenith angle at pixel locations'
332 nc_solz.units =
'degrees'
333 nc_solz.valid_min = 0.
334 nc_solz.valid_max = 90.
335 dsL1.data[
'to-sun zenith (0 to 90 degrees from zenith)'][np.isnan(dsL1.data[
'to-sun zenith (0 to 90 degrees from zenith)'])] = nc_solz._FillValue
336 nc_solz[:,:] = dsL1.data[
'to-sun zenith (0 to 90 degrees from zenith)']
338 nc_sola = nc_fid.createVariable(
'/navigation_data/solar_azimuth',
340 dimensions=(
'number_of_scans',
'pixels_per_scan'),
343 chunksizes=(1,nc_fid.dimensions[
'pixels_per_scan'].size),
345 nc_sola.long_name =
'Solar azimuth angle at pixel locations'
346 nc_sola.units =
'degrees'
347 nc_sola.valid_min = 0.
348 nc_sola.valid_max = 360.
349 dsL1.data[
'to-sun azimuth (0 to 360 degrees cw from n)'][np.isnan(dsL1.data[
'to-sun azimuth (0 to 360 degrees cw from n)'])] = nc_sola._FillValue
350 nc_sola[:,:] = dsL1.data[
'to-sun azimuth (0 to 360 degrees cw from n)']
353 print(
'Creating and writing observation_data')
354 nc_lt = nc_fid.createVariable(
'/observation_data/Lt',
356 dimensions=(
'number_of_bands',
'number_of_scans',
'pixels_per_scan'),
359 chunksizes=(nc_fid.dimensions[
'number_of_bands'].size,1,nc_fid.dimensions[
'pixels_per_scan'].size),
361 nc_lt.long_name =
'Top of atmosphere radiance'
362 nc_lt.units =
'uW cm-2 nm-1 sr-1'
364 nc_lt.valid_max = 800.
365 dsL1.data[
'lt'][np.isnan(dsL1.data[
'lt'])] = nc_lt._FillValue
366 nc_lt[:,:,:] = dsL1.data[
'lt']
369 print(
'Creating and writing derived_data')
370 nc_rrs = nc_fid.createVariable(
'/derived_data/Rrs',
372 dimensions=(
'number_of_bands',
'number_of_scans',
'pixels_per_scan'),
375 chunksizes=(nc_fid.dimensions[
'number_of_bands'].size,1,nc_fid.dimensions[
'pixels_per_scan'].size),
377 nc_rrs.long_name =
'Remote sensing reflectance'
378 nc_rrs.units =
'sr-1'
379 nc_rrs.valid_min = 0.
380 nc_rrs.valid_max = 1000.
381 nc_rrs.comment =
'Scaled estimates of the water-leaving reflectance directly above the water surface for each measured wavelength, scaled by Pi with the assumption of a Lambertian surface. This is comparable to the Hemispherical Directed Reflectance Function (Shaepman-Strub et al., 2006). It is calculated using a variant of the ATREM atmospheric correction method (Gao et al., 1993; Gao et al., 2009). The modifications are described in texts by Thompson et al. (2015a and 2015b).'
382 nc_rrs.reference =
'Gao, B. C., Heidebrecht, K. B., & Goetz, A. F. (1993). Derivation of scaled surface reflectances from AVIRIS data. Remote sensing of Environment, 44(2-3), 165-178.; Gao, B. C., Montes, M. J., Davis, C. O., & Goetz, A. F. (2009). Atmospheric correction algorithms for hyperspectral remote sensing data of land and ocean. Remote Sensing of Environment, 113, S17-S24.; Schaepman-Strub, G., Schaepman, M. E., Painter, T. H., Dangel, S., & Martonchik, J. V. (2006). Reflectance quantities in optical remote sensing — Definitions and case studies. Remote sensing of environment, 103(1), 27-42.; Thompson, D. R., Gao, B. C., Green, R. O., Roberts, D. A., Dennison, P. E., & Lundeen, S. R. (2015a). Atmospheric correction for global mapping spectroscopy: ATREM advances for the HyspIRI preparatory campaign. Remote Sensing of Environment, 167, 64-77.; Thompson, D. R., Seidel, F. C., Gao, B. C., Gierach, M. M., Green, R. O., Kudela, R. M., & Mouroulis, P. (2015b). Optimizing irradiance estimates for coastal and inland water imaging spectroscopy. Geophysical Research Letters, 42(10), 4116-4123.'
383 dsL2.data[
'rrs'][np.isnan(dsL2.data[
'rrs'])] = nc_rrs._FillValue
384 nc_rrs[:,:,:] = dsL2.data[
'rrs']
386 nc_rb = nc_fid.createVariable(
'/derived_data/Rb',
388 dimensions=(
'number_of_benthic_bands',
'number_of_scans',
'pixels_per_scan'),
391 chunksizes=(nc_fid.dimensions[
'number_of_benthic_bands'].size,1,nc_fid.dimensions[
'pixels_per_scan'].size),
393 nc_rb.long_name =
'Benthic reflectance'
396 nc_rb.valid_max = 1000.
397 nc_rb.comment =
'Estimates of the diffuse bottom reflectance (i.e. the ratio of downwelling to upwelling flux) for each wavelength, formed by estimating the apparent optical properties AOPs) of the water column. The calculation uses the relationship for shallow-water reflectance described by Maritorena et al. (1994). The bottom reflectance is modeled using a linear nonnegative combination of a set of one or more basis endmembers from a suitable library of bottom reflectances. This process provides smooth-looking spectra across all wavelengths, but we note that values for longer wavelengths becomes less certain as the depth of the water increases.'
398 nc_rb.reference =
'Maritorena, S., Morel, A., & Gentili, B. (1994). Diffuse reflectance of oceanic shallow waters: Influence of water depth and bottom albedo. Limnology and oceanography, 39(7), 1689-1703.'
399 dsL2.data[
'rb'][np.isnan(dsL2.data[
'rb'])] = nc_rb._FillValue
400 nc_rb[:,:,:] = dsL2.data[
'rb']
402 nc_depth = nc_fid.createVariable(
'/derived_data/depth',
404 dimensions=(
'number_of_scans',
'pixels_per_scan'),
407 chunksizes=(1,nc_fid.dimensions[
'pixels_per_scan'].size),
409 nc_depth.long_name =
'water column depth'
410 nc_depth.units =
'meters'
411 nc_depth.valid_min = 0.
412 nc_depth.valid_max = 10000.
413 nc_depth.comment =
'Estimated depth of the water column used to derive benthic reflectance.'
414 dsL2.data[
'depth (m)'][np.isnan(dsL2.data[
'depth (m)'])] = nc_depth._FillValue
415 nc_depth[:,:] = dsL2.data[
'depth (m)']
417 nc_coral = nc_fid.createVariable(
'/derived_data/coral',
419 dimensions=(
'number_of_scans',
'pixels_per_scan'),
422 chunksizes=(1,nc_fid.dimensions[
'pixels_per_scan'].size),
424 nc_coral.long_name =
'Probability of coral benthic cover type'
425 nc_coral.units =
'unitless'
426 nc_coral.valid_min = 0.
427 nc_coral.valid_max = 1.
428 nc_coral.comment =
'Derived probability associated with coral as the benthic cover classification for each seafloor pixel.'
429 dsL3.data[
'coral'][np.isnan(dsL3.data[
'coral'])] = nc_coral._FillValue
430 nc_coral[:,:] = dsL3.data[
'coral']
432 nc_sand = nc_fid.createVariable(
'/derived_data/sand',
434 dimensions=(
'number_of_scans',
'pixels_per_scan'),
437 chunksizes=(1,nc_fid.dimensions[
'pixels_per_scan'].size),
439 nc_sand.long_name =
'Probability of sand benthic cover type'
440 nc_sand.units =
'unitless'
441 nc_sand.valid_min = 0.
442 nc_sand.valid_max = 1.
443 nc_sand.comment =
'Derived probability associated with sand as the benthic cover classification for each seafloor pixel.'
444 dsL3.data[
'sand'][np.isnan(dsL3.data[
'sand'])] = nc_sand._FillValue
445 nc_sand[:,:] = dsL3.data[
'sand']
447 nc_algae = nc_fid.createVariable(
'/derived_data/algae',
449 dimensions=(
'number_of_scans',
'pixels_per_scan'),
452 chunksizes=(1,nc_fid.dimensions[
'pixels_per_scan'].size),
454 nc_algae.long_name =
'Probability of algae benthic cover type'
455 nc_algae.units =
'unitless'
456 nc_algae.valid_min = 0.
457 nc_algae.valid_max = 1.
458 nc_algae.comment =
'Derived probability associated with algae as the benthic cover classification for each seafloor pixel.'
459 dsL3.data[
'algae'][np.isnan(dsL3.data[
'algae'])] = nc_algae._FillValue
460 nc_algae[:,:] = dsL3.data[
'algae']
464 print(
'Successfully created', nc_fullpath)
469 if __name__ ==
"__main__":
main()