source: lmdz_wrf/trunk/tools/ORforcing_reconstruct.py @ 1750

Last change on this file since 1750 was 1750, checked in by lfita, 7 years ago

Final working version of the script with multiple attributes

File size: 9.5 KB
Line 
1# Reconstructing ORCHIDEE's forcing files as matrices for a gien area
2# L. Fita, CIMA. December 2017
3#
4import numpy as np
5from netCDF4 import Dataset as NetCDFFile
6import os
7import re
8import numpy.ma as ma
9# Importing generic tools file 'generic_tools.py'
10import generic_tools as gen
11import nc_var_tools as ncvar
12import subprocess as sub
13import module_ForSci as Sci
14from optparse import OptionParser
15
16parser = OptionParser()
17parser.add_option("-f", "--fileHEader", dest="fh", help="header of files",           \
18  metavar="VALUE")
19parser.add_option("-L", "--latitude", dest="latn", help="name of the variable latitiude", \
20  metavar="VALUE")
21parser.add_option("-l", "--longitude", dest="lonn", help="name of the variable longitiude", \
22  metavar="VALUE")
23parser.add_option("-v", "--Variables", dest="varns", help="',' separated list of variables", \
24  metavar="VALUE")
25parser.add_option("-y", "--year", dest="year", help="year to process",               \
26  metavar="VALUE")
27
28(opts, args) = parser.parse_args()
29
30####### ###### ##### #### ### ## #
31
32filen = opts.fh + opts.year + '.nc'
33
34# Variable whcih provides the indices of a 1D vector from the dimy, dimx space
35indvar = 'land'
36
37# 2D longitude, latitude matrices
38lonvar = opts.lonn
39latvar = opts.latn
40
41# Range to retrieve
42Xmin=-90.25
43#Xmin='all'
44Xmax=-33.25
45Ymin=-67.25
46Ymax=15.25
47
48# Variables to reconstruct
49#variable = 'all'
50variable = opts.varns
51
52# Resolution
53resX = 0.5
54resY = 0.5
55
56# Minimum difference from matrix to localized point
57maxdiff = 0.05
58
59# Projection of the matrix
60matProj = 'latlon'
61
62#######    #######
63## MAIN
64    #######
65main = 'ORforcing_reconstruct.py'
66fname = 'ORforcing_reconstruct.py'
67
68onc = NetCDFFile(filen, 'r')
69
70availProj = ['latlon']
71
72ofilen = 'reconstruct_matrix_' + opts.year + '.nc'
73
74ncvars = onc.variables.keys()
75
76varstocheck = [indvar, lonvar, latvar]
77for vn in varstocheck:
78    if not gen.searchInlist(ncvars, vn):
79        print gen.errormsg
80        print '  ' + main + ": file '" + filen + "' does not have variable '" + vn + \
81          "' !!"
82        print '    available ones:', ncvars
83        quit(-1)
84
85oind = onc.variables[indvar]
86olon = onc.variables[lonvar]
87olat = onc.variables[latvar]
88
89indv = oind[:]
90lonv = olon[:]
91latv = olat[:]
92
93vecdimn = oind.dimensions[0]
94if len(olon.dimensions) == 2:
95    Xdimn = olon.dimensions[1]
96    Ydimn = olon.dimensions[0]
97    dimx = lonv.shape[1]
98    dimy = lonv.shape[0]
99elif len(olon.dimensions) == 1:
100    Xdimn = olon.dimensions[0]
101    Ydimn = olat.dimensions[0]
102    dimx = lonv.shape[0]
103    dimy = latv.shape[0]
104    lonv, latv = np.meshgrid(lonv, latv)
105
106# Fortran indices, first 1
107indv = indv - 1
108
109veclon = np.zeros((len(indv)), dtype=np.float)
110veclat = np.zeros((len(indv)), dtype=np.float)
111
112# Construct veclon, veclat
113for iid in range(len(indv)):
114    iy = int((indv[iid]-1)/dimx)
115    ix = int(indv[iid] - iy*dimx - 1)
116    veclon[iid] = lonv[iy,ix]
117    veclat[iid] = latv[iy,ix]
118
119if not gen.searchInlist(availProj, matProj):
120    print errormsg
121    print '  ' + fname + ": projection '" + matProj + "' not available !!"
122    print '    available ones:', availProj
123    quit(-1)
124
125ncdims = onc.dimensions
126
127if variable == 'all':
128    varns = ncvars
129else:
130    varns = variable.split(',')
131    for vn in varns:
132        if not gen.searchInlist(ncvars, vn):
133            print gen.errormsg
134            print '  ' + fname + ": file '" + filen + "' does not have " +           \
135              " variable '" + vn + "' !!"
136            print '  available ones:', ncvars
137            quit(-1)
138
139if gen.searchInlist(olon.ncattrs(), 'units'):
140    xunits = olon.getncattr('units')
141else:
142    xunits = '-'
143if gen.searchInlist(olat.ncattrs(), 'units'):
144    yunits = olat.getncattr('units')
145else:
146   yunits = '-'
147
148if type(Xmin) == type('2') and Xmin == 'all':
149    Xmin = np.min(lonv)
150    Xmax = np.max(lonv)
151    Ymin = np.min(latv)
152    Ymax = np.max(latv)
153
154# Matrix values
155if matProj == 'latlon':
156    dimx = int((Xmax - Xmin+resX)/resX)
157    dimy = int((Ymax - Ymin+resY)/resY)
158
159matindt, matXt, matYt = Sci.module_scientific.reconstruct_matrix(vectorxpos=veclon,  \
160  vectorypos=veclat, dvec=veclon.shape[0], xmin=Xmin, xmax=Xmax, ymin=Ymin,ymax=Ymax,\
161  dmatx=dimx, dmaty=dimy, matproj=matProj, maxdiff=maxdiff)
162
163matind = matindt.transpose()
164# Fortran like, First 1
165matind = np.where(matind != -1, matind - 1, matind)
166
167# Creation of file
168onewnc = NetCDFFile(ofilen, 'w')
169
170# Dimensions
171newdim = onewnc.createDimension('x', dimx)
172newdim = onewnc.createDimension('y', dimy)
173
174# Variable-dimension
175newvar = onewnc.createVariable('lon', 'f8', ('y', 'x'))
176newvar[:] = matXt.transpose()
177ncvar.basicvardef(newvar, 'lon', 'Longitude', 'degrees_east')   
178
179newvar = onewnc.createVariable('lat', 'f8', ('y', 'x'))
180newvar[:] = matYt.transpose()
181ncvar.basicvardef(newvar, 'lat', 'Latitude', 'degrees_north')   
182onewnc.sync()
183
184# Variable indices
185newvar = onewnc.createVariable('vec1D_matind', 'i', ('y', 'x'), fill_value=-1)
186newvar[:] = matind
187ncvar.basicvardef(newvar, 'vec1D_matind', 'matrix with the equivalencies from 1D ' + \
188  'vector indices', '-')
189ncvar.set_attribute(newvar, 'coordinates', 'lon lat')
190
191# Looking for equivalencies in the 1D vector
192matlonlat = matind.copy()
193for j in range(dimy):
194    for i in range(dimx):
195        if matind[j,i] != -1:
196            matlonlat[j,i] = indv[matind[j,i]]
197
198newvar = onewnc.createVariable('lonlat_matind', 'i', ('y', 'x'), fill_value=-1)
199newvar[:] = matlonlat
200ncvar.basicvardef(newvar, 'lonlat_matind', 'matrix with the equivalencies from ' +   \
201  '2D lon, lat matrices', '-')
202ncvar.set_attribute(newvar, 'coordinates', 'lon lat')
203onewnc.sync()
204
205# Getting variables
206for vn in varns:
207    if not onewnc.variables.has_key(vn):
208        ovar = onc.variables[vn]
209        indn = ovar.dimensions
210        vardims = []
211        shapevar = []
212        for dn in indn:
213            if not gen.searchInlist(onewnc.dimensions, dn) and dn != Xdimn and   \
214              dn != Ydimn:
215                if onc.dimensions[dn].isunlimited():
216                    newdim = onewnc.createDimension(dn, None)
217                else:
218                    newdim = onewnc.createDimension(dn, len(onc.dimensions[dn]))
219               
220            if dn == vecdimn: 
221                vardims.append('y')
222                vardims.append('x')
223                shapevar.append(dimy)
224                shapevar.append(dimx)
225            else: 
226                vardims.append(dn)
227                shapevar.append(len(onc.dimensions[dn]))
228
229        if ovar.dtype == type(int(2)):
230            newvar= onewnc.createVariable(vn,ncvar.nctype(ovar.dtype),tuple(vardims),\
231              fill_value=gen.fillValueI)
232            varvals = np.ones(tuple(shapevar), dtype=ovar.dtype)*gen.fillValueI
233        elif ovar.dtype == type(np.int32(2)):
234            newvar= onewnc.createVariable(vn,ncvar.nctype(ovar.dtype),tuple(vardims),\
235              fill_value=gen.fillValueI)
236            varvals = np.ones(tuple(shapevar), dtype=ovar.dtype)*gen.fillValueI
237        elif ovar.dtype == type(np.int64(2)):
238            newvar= onewnc.createVariable(vn,ncvar.nctype(ovar.dtype),tuple(vardims),\
239              fill_value=gen.fillValueI)
240            varvals = np.ones(tuple(shapevar), dtype=ovar.dtype)*gen.fillValueI
241        elif ovar.dtype == type(np.float(2.)):
242            newvar= onewnc.createVariable(vn,ncvar.nctype(ovar.dtype),tuple(vardims),\
243              fill_value=gen.fillValueF)
244            varvals = np.ones(tuple(shapevar), dtype=ovar.dtype)*gen.fillValueF
245        elif ovar.dtype == type(np.float32(2.)):
246            newvar= onewnc.createVariable(vn,ncvar.nctype(ovar.dtype),tuple(vardims),\
247              fill_value=gen.fillValueF)
248            varvals = np.ones(tuple(shapevar), dtype=ovar.dtype)*gen.fillValueF
249        else:
250            print gen.errormsg
251            print '  ' + fname + ': variable type:', ovar.dtype, ' not ready !!'
252            quit(-1)
253
254        print '  reconstructing:', vn, '...'
255        # Filling variable. It would be faster if we can avoid this loop... I'm feeling lazy!
256        if not gen.searchInlist(vardims,'x') and not gen.searchInlist(vardims,'y'):
257            newvar[:] = ovar[:] 
258        else:
259            ovart = ovar[:].transpose()
260            if newvar.dtype == type(float(2.)) or newvar.dtype == type(np.float(2.)) \
261              or newvar.dtype == type(np.float32(2)) or                              \
262              newvar.dtype == type(np.float64(2)):
263                newvals = Sci.module_scientific.fill3dr_2dvec(matind=matindt,        \
264                  inmat=ovart, id1=ovart.shape[0], id2=ovart.shape[1],               \
265                  od1=newvar.shape[2], od2=newvar.shape[1], od3=newvar.shape[0])
266            else:
267                newvals = Sci.module_scientific.fill3di_2dvec(matind=matindt,        \
268                  inmat=ovart, id1=ovart.shape[0], id2=ovart.shape[1],               \
269                  od1=newvar.shape[2], od2=newvar.shape[1], od3=newvar.shape[0])
270            newvar[:] = newvals.transpose()
271
272        # Attributes
273        for atn in ovar.ncattrs():
274            if atn != '_FillValue' and atn != 'units':
275                atv = ovar.getncattr(atn)
276                ncvar.set_attribute(newvar, atn, atv)
277        ncvar.set_attribute(newvar, 'coordinates', 'lon lat')
278        onewnc.sync()
279   
280# Global attributes
281for atn in onc.ncattrs():
282    atv = ovar.getncattr(atn)
283    ncvar.set_attribute(onewnc, atn, atv)
284onewnc.sync()
285ncvar.add_global_PyNCplot(onewnc, main, fname, '0.1')
286onc.close()
287
288# Reconstructing times
289otime = onewnc.variables['time']
290ncvar.set_attribute(otime, 'units', 'seconds since ' + opts.year + '-01-01 00:00:00')
291
292onewnc.sync()
293onewnc.close()
294
295print fname + ": Successful writing of file '" + ofilen + ".nc' !!"
Note: See TracBrowser for help on using the repository browser.