forked from janjaapmeijer/oceanpy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
netcdf.py
82 lines (67 loc) · 3.18 KB
/
netcdf.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import os
from netCDF4 import Dataset, date2num
import xml.etree.ElementTree as ElementTree
import OceanPy
from datetime import datetime
import numpy as np
try:
from urllib.request import urlopen
except ImportError:
from urllib import urlopen
class createNetCDF(object):
def __init__(self, output_file):
self.output_file = output_file
if os.path.isfile(output_file):
self.dataset = Dataset(output_file, 'r+')
else:
self.dataset = Dataset(output_file, 'w')
def add_dims(self, dims):
''' Create dimensions of variables to store in NetCDF '''
for dimname, size in dims.items():
self.dataset.createDimension(dimname=dimname, size=size)
# TODO: let function work inside netcdf
def add_glob_attr(self, glob_attr):
''' Add global attributes '''
time_now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
attr = {'Conventions': 'CF-1.6',
'Metadata_Conventions': 'Unidata Dataset Discovery v1.0',
'history': 'Created on %s with %s' % (time_now, os.path.basename(__file__))
}
for key in attr.keys():
if not hasattr(self.dataset, 'Conventions') and key not in glob_attr.keys():
setattr(self.dataset, key, attr[key])
for key in glob_attr.keys():
setattr(self.dataset, key, glob_attr[key])
def create_vars(self, vars):
# open cf conventions standard names xml file
root = ElementTree.parse(
urlopen('http://cfconventions.org/Data/cf-standard-names/current/src/cf-standard-name-table.xml'))
# check if var_name is in standard names xml file and if so save in dict with according unit and description
standard_names = {}
for child in root.findall('entry'):
standard_names[child.get('id')] = (child.findtext('canonical_units'), child.findtext('description'))
for varname, values in vars.items():
standard_name, datatype, dimensions, data = values
# if '/' in varname:
# group = os.path.dirname(varname)
# self.dataset.createGroup(group)
# create variables
var = self.dataset.createVariable(varname, datatype, dimensions)
# add variable attributes
if standard_name.split()[-1] in standard_names.keys():
var.standard_name = standard_name.split()[-1]
if standard_name.split()[-1] == 'time':
calendar = 'standard'
var.units = 'seconds since 1970-01-01 00:00'
data = date2num(data, units=var.units, calendar=calendar)
else:
var.units = standard_names[standard_name.split()[-1]][0]
var.long_name = standard_name
# var.description = standard_names[varname.split()[-1]][1]
# add data to variables
var[:] = np.ma.filled(data.astype(float), np.nan) # data
def delete_vars(self, vars):
# https://stackoverflow.com/questions/15141563/python-netcdf-making-a-copy-of-all-variables-and-attributes-but-one/32002401
pass
def close(self):
self.dataset.close()