-
Notifications
You must be signed in to change notification settings - Fork 1
/
lfNcUtil.py
126 lines (110 loc) · 3.9 KB
/
lfNcUtil.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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import re, os
import netCDF4
import numpy as np
def ncCloneFileStructure(inputFilePath, outputFilePath, timeVarName='time', timeVarUnits='', calendar='', defaultMissingValue=1E10, complevel=4):
if os.path.isfile(outputFilePath):
os.remove(outputFilePath)
zlib = complevel > 1
ids = netCDF4.Dataset(inputFilePath)
ods = netCDF4.Dataset(outputFilePath, 'w')
try:
#Copying attributes
for k in ids.ncattrs():
att = ids.getncattr(k)
ods.setncattr(k, att)
#Copying dimensions
for dname, dm in ids.dimensions.iteritems():
ods.createDimension(dname, len(dm) if (not dm.isunlimited()) and (dname!=timeVarName) else None)
if not ids.variables.has_key(dname):
continue
vrbl = ids.variables[dname]
ovrbl = ods.createVariable(dname, vrbl.datatype, vrbl.dimensions, zlib=zlib, complevel=complevel)
ovrbl.setncatts({k: vrbl.getncattr(k) for k in vrbl.ncattrs()})
if dname == timeVarName:
if calendar != '':
clndr = calendar
else:
try:
clndr = vrbl.calendar
except:
clndr = 'gregorian'
ovrbl.calendar = clndr
if timeVarUnits != '':
ovrbl.units = timeVarUnits
else:
ovrbl[:] = vrbl[:]
for varName in ids.variables:
if varName in ods.variables:
continue
vrbl = ids.variables[varName]
fillValue = vrbl._FillValue if '_FillValue' in vrbl.ncattrs() else defaultMissingValue
if re.match('(.*)float(.*)', vrbl.datatype.name):
ovrbl = ods.createVariable(vrbl.name, vrbl.datatype, vrbl.dimensions, fill_value=fillValue,
zlib=zlib, complevel=complevel)
else:
ovrbl = ods.createVariable(vrbl.name, vrbl.datatype, vrbl.dimensions)
ovrbl.setncatts({k: vrbl.getncattr(k) for k in vrbl.ncattrs()})
if (not 'missing_value' in ovrbl.ncattrs()):
ovrbl.setncattr('missing_value', fillValue)
finally:
ids.close()
ods.close()
def lfNcSliceTime(inputFilePath, outputFilePath, startTime, endTime, timeVarName='time', complevel=4):
# getting time limits
ids = netCDF4.Dataset(inputFilePath)
intmnc = ids.variables[timeVarName]
tmunits = intmnc.units
try:
clndr = intmnc.calendar
except:
clndr = 'standard'
intmnum = intmnc[:]
inTm = netCDF4.num2date(intmnum, tmunits, clndr)
stTmNum = int(np.round(netCDF4.date2num(startTime, tmunits, clndr)))
stTmNumIndx = np.where(intmnum >= stTmNum)[0][0]
if not endTime is None:
endTmNum = netCDF4.date2num(endTime, tmunits, clndr)
endtmIII = np.where(intmnum <= endTmNum)[0]
endTmNumIndx = endtmIII[-1] + 1 if len(endtmIII) > 0 else -1
else:
endTmNumIndx = -1
if endTmNumIndx >= len(intmnum):
endTmNumIndx = -1
ids.close()
tmslice = slice(stTmNumIndx, endTmNumIndx) if endTmNumIndx != -1 else slice(stTmNumIndx, None)
#copying file structure
ncCloneFileStructure(inputFilePath, outputFilePath, timeVarName, tmunits, clndr, complevel=complevel)
#copying values
ids = netCDF4.Dataset(inputFilePath)
ods = netCDF4.Dataset(outputFilePath, 'r+')
dims = ods.dimensions
for varName in ids.variables:
if varName == timeVarName:
ivrbl = ids.variables[varName]
ovrbl = ods.variables[varName]
tmunits = ovrbl.units
try:
clndr = ovrbl.calendar
except:
clndr = 'standard'
otmnum = netCDF4.date2num(inTm, tmunits, clndr)
ovrbl[:] = otmnum[tmslice]
if varName in dims:
continue
ivrbl = ids.variables[varName]
ovrbl = ods.variables[varName]
ovdims = ovrbl.dimensions
if timeVarName in ovdims:
timeDimIndx = ovdims.index(timeVarName)
indx = []
for idim in range(len(ovdims)):
ss = tmslice if idim==timeDimIndx else slice(None)
indx.append(ss)
ovrbl[:] = ivrbl[indx]
else:
try:
ovrbl[:] = ivrbl[:]
except:
pass
ids.close()
ods.close()