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

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

Final version:

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