source: trunk/UTIL/PYTHON/mcs.py @ 417

Last change on this file since 417 was 417, checked in by acolaitis, 14 years ago

PYTHON
######

mcs.py script is pretty finished now. Usage:

mcs.py -f diagfi16.nc -m /san0/acolmd/DATA/MCS/MCS_processeddata/MCSdata_binned_MY29.nc -i -x --var temp --override

where -i specify that you want to interpolate your file on MCS pressure levels, -x get rids of aps and bps in the output, --override forces zrecast to work even if a z-recasted file is already present.

  • Property svn:executable set to *
File size: 11.6 KB
Line 
1#!/usr/bin/env python
2
3### A. Colaitis
4
5##
6#   This routine transforms a diagfi.nc file into a diagfi_MCS.nc file where
7#   the fields are directly comparable to those contained in MCS data, i.e.
8#   fields are re-binned at times over the ranges specified in the MCS file.
9###
10
11###########################################################################################
12###########################################################################################
13### What is below relate to running the file as a command line executable (very convenient)
14if __name__ == "__main__":
15   import sys
16   from optparse import OptionParser    ### to be replaced by argparse
17   from netCDF4 import Dataset
18   from os import system,path
19   from times import sol2ls
20   import numpy as np
21   from mymath import find_nearest
22   from myplot import getfield,separatenames
23   from make_netcdf import make_gcm_netcdf
24   from zrecast_wrapper import call_zrecast
25   parser = OptionParser() 
26
27   #############################
28   ### Options
29   parser.add_option('-f', '--file',   action='store',dest='file',     type="string",  default=None,  help='[NEEDED] filename.')
30   parser.add_option('-m', '--mfile',  action='store',dest='mcsfile',     type="string",  default=None,  help='[NEEDED] filename for MCS comparison.')
31   parser.add_option('-v', '--var',    action='append',dest='var',      type="string",  default=None,  help='[NEEDED] Variables to process. (coma-separated list. aps and bps are always included.)')
32   parser.add_option('-x', action='store_true',dest='recast',     default=False,  help='Force aps and bps to be ommited in output file (usefull if your file is already recasted along z) [False]')
33   parser.add_option('-i', '--zrecast', action='store_true', dest='zrecast', default=False, help='Cast zrecast.e on diagfi file with MCS pressure levels. Will pass this operation is recasted file is already present, unless --override is specified. [False]')
34   parser.add_option('--override', action='store_true', dest='override', default=False, help='Force zrecast.e to act even if recasted file is already present(will erase previous recasted file) [False]')
35
36   #############################
37   ### Get options and variables
38   (opt,args) = parser.parse_args()
39
40   #############################
41   ### Load and check data
42
43   if opt.var is None:
44      print "You must specify at least a field to process with -v."
45      exit()
46
47   # Zrecast
48
49   varznames=separatenames(opt.var[0])
50
51   if opt.zrecast:
52      if (path.exists(opt.file[0:len(opt.file)-3]+"_P.nc") and (not opt.override)):
53         print "--> "+opt.file[0:len(opt.file)-3]+"_P.nc"
54         print "Recasted file is already there, skipping interpolation. [use --override to force interpolation]"
55         filename=opt.file[0:len(opt.file)-3]+"_P.nc"
56      else:
57         print "--> "+opt.file[0:len(opt.file)-3]+"_P.nc"
58         filename=call_zrecast (  interp_mode   = 2, \
59                    input_name      = [opt.file], \
60                    fields  = varznames, \
61                    predifined = 'mcs')[0]
62
63   # Files
64
65   print "--> Loading diagfi dataset."
66
67   nc=Dataset(filename)
68   ncmcs=Dataset(opt.mcsfile)
69
70   # Dimensions
71
72   lon=nc.variables["longitude"][:]
73   lat=nc.variables["latitude"][:]
74   alt=nc.variables["altitude"][:]
75   time=nc.variables["Time"][:] # in fraction of sols
76   if "controle" in nc.variables:
77      controle=nc.variables["controle"][:]
78      day_ini=controle[3]%669
79   else:
80      if opt.zrecast:
81         nccontrol=Dataset(opt.file)
82         if "controle" in nccontrol.variables:
83            controle=nccontrol.variables["controle"][:]
84            day_ini=controle[3]%669
85         else:
86            print "Error: could not find controle variable in diagfi."
87            day_ini=input("Please type initial sol number:")%669
88   time[:]=time[:]+day_ini
89   nx=len(lon)
90   ny=len(lat)
91   nz=len(alt)
92   nt=len(time)
93   lstime=sol2ls(time)
94
95   # MCS
96
97   print "--> Loading and preparing MCS dataset."
98
99   dtimemintmp=ncmcs.variables["dtimemin"][:,:,:]
100   dtimemaxtmp=ncmcs.variables["dtimemax"][:,:,:]
101   ntimemintmp=ncmcs.variables["ntimemin"][:,:,:]
102   ntimemaxtmp=ncmcs.variables["ntimemax"][:,:,:]
103   lonmcs=ncmcs.variables["longitude"][:]
104   latmcs=ncmcs.variables["latitude"][:]
105   timemcs=ncmcs.variables["time"][:]%360 # IN LS
106
107   dtimemin=np.ma.masked_where(dtimemintmp < 0.,dtimemintmp)
108   dtimemin.set_fill_value([np.NaN])
109   dtimemax=np.ma.masked_where(dtimemaxtmp < 0.,dtimemaxtmp)
110   dtimemax.set_fill_value([np.NaN])
111   ntimemin=np.ma.masked_where(ntimemintmp < 0.,ntimemintmp)
112   ntimemin.set_fill_value([np.NaN])
113   ntimemax=np.ma.masked_where(ntimemaxtmp < 0.,ntimemaxtmp)
114   ntimemax.set_fill_value([np.NaN])
115
116   # Variables to treat
117
118   print "--> Preparing diagfi dataset."
119
120   varz=[]
121   n=0
122   for zn in varznames:
123       load=getfield(nc,zn)
124       if opt.zrecast:
125          load=np.ma.masked_where(load < -1.e-30,load)
126          load.set_fill_value([np.NaN])
127          load=load.filled()
128       varz.append(load)
129       print "Found: "+zn+" with dimensions: "
130       print np.array(varz[n]).shape
131       n=n+1
132
133   nzvar=len(varz)
134   dimensions={}
135   vv=0
136   for var in varz:
137       a=len(np.array(var).shape)
138       if a == 3: dimensions[vv]=a
139       elif a == 4: dimensions[vv]=a
140       else:
141          print "Warning, only 3d and 4d variables are supported for time-recasting"
142          exit()
143       vv=vv+1
144
145   # Variables to save but not treated (only along z, or phisinit-like files)
146
147   aps=nc.variables["aps"][:]
148   bps=nc.variables["bps"][:]
149   fullnames=["aps","bps"]
150   for name in varznames:
151       fullnames.append("d"+name)
152       fullnames.append("n"+name)
153   print "Will output: "
154   if opt.recast: print fullnames[2:]
155   else: print fullnames
156   #############################
157   ### Building
158   #############################
159
160   ### We loop over chunks of gcm data corresponding to MCS time dimension
161   ### Bin sizes for mcs data is 5 degrees ls centered on value
162   varday=np.zeros([len(timemcs),nz,ny,nx])
163   varnight=np.zeros([len(timemcs),nz,ny,nx])
164   vardayout=np.zeros([nzvar,len(timemcs),nz,ny,nx])
165   varnightout=np.zeros([nzvar,len(timemcs),nz,ny,nx])
166   vardayout=np.ma.masked_invalid(vardayout)
167   varnightout=np.ma.masked_invalid(varnightout)
168   i=0
169   for ls in timemcs:
170       lsstart=ls-2.5
171       lsstop=ls+2.5
172       istart=find_nearest(lstime,lsstart,strict=True)
173       istop=find_nearest(lstime,lsstop,strict=True)
174       varchk=0
175       if ((istart is np.NaN) or (istop is np.NaN)):
176          vardayout[:,i,:,:,:]=np.NaN
177          varnightout[:,i,:,:,:]=np.NaN
178          print "Time interval skipped. Ls MCS: (",lsstart,';',lsstop,')',"// Ls diagfi: (",lstime.min(),';',lstime.max(),')'
179          i=i+1
180          continue
181       print "--->> Processing Data. Ls MCS: (",lsstart,';',lsstop,')',"// Ls diagfi: (",lstime.min(),';',lstime.max(),')'
182       # warning, python's convention is that the second index of array[a:b] is the array index of element after the one being picked last.
183       # for that reason, array[0:0] is nan and array[0:1] is only one value. Hence, len(array[a:b+1]) is b-a+1 and not b-a+2
184       print "     .initialisation."
185       
186       
187       varchk=np.zeros([nzvar,istop-istart+1,nz,ny,nx])
188       vv=0
189       for variable in varz:
190           if dimensions[vv] is 3:
191              varchk[vv,:,0,:,:]=variable[istart:istop+1,:,:]
192           else:
193              varchk[vv,:,:,:,:]=variable[istart:istop+1,:,:,:]
194           vv=vv+1
195       varchktime=time[istart:istop+1]
196       ndays=np.floor(varchktime[len(varchktime)-1])-np.floor(varchktime[0])
197       dtmichk=dtimemin[i,:,:]
198       dtmachk=dtimemax[i,:,:]
199       ntmichk=ntimemin[i,:,:]
200       ntmachk=ntimemax[i,:,:]
201       dtmichk.set_fill_value(np.NaN)
202       dtmachk.set_fill_value(np.NaN)
203       ntmichk.set_fill_value(np.NaN)
204       ntmachk.set_fill_value(np.NaN)
205       dtmichk=dtmichk.filled()
206       dtmachk=dtmachk.filled()
207       ntmichk=ntmichk.filled()
208       ntmachk=ntmachk.filled()
209
210   ### We iterate for each day in the chunk, on each grid point we find
211   ### the closest corresponding MCS grid point and the index of the
212   ### time in the chunk closest to the time in the closest MCS grid point.
213   ### (yea it's complicated)
214
215       vartmpnight=np.zeros([nzvar,ndays,nz,ny,nx])
216       vartmpday=np.zeros([nzvar,ndays,nz,ny,nx])
217       nd=0
218       print "     .time indices MCS grid -> diagfi grid."
219       while nd < ndays:
220
221          daystart=find_nearest(varchktime-varchktime[0],nd)
222          daystop=find_nearest(varchktime-varchktime[0],nd+1)
223#          varchktime_lon=np.zeros([daystop-daystart+1,len(lon)])
224          ix=0
225          for x in lon:
226
227             varchktime_lon = 24.*(varchktime[daystart:daystop+1]-varchktime[daystart]) + x/15.
228
229             iy=0
230             for y in lat:
231                niy=find_nearest(latmcs,y)
232                nix=find_nearest(lonmcs,x)
233                nitdtmichk=find_nearest(varchktime_lon,dtmichk[niy,nix])
234                nitdtmachk=find_nearest(varchktime_lon,dtmachk[niy,nix])
235                nitntmichk=find_nearest(varchktime_lon,ntmichk[niy,nix])
236                nitntmachk=find_nearest(varchktime_lon,ntmachk[niy,nix])
237                for vv in np.arange(nzvar):
238                   if ((nitdtmichk is np.NaN) or (nitdtmachk is np.NaN)):
239                       vartmpday[vv,nd,:,iy,ix]=np.NaN
240                   elif nitdtmichk > nitdtmachk:
241                       vartmpday[vv,nd,:,iy,ix]=(np.mean(varchk[vv,daystart+nitdtmichk:daystop+1,:,iy,ix],axis=0)+np.mean(varchk[vv,daystart:daystart+nitdtmachk+1,:,iy,ix],axis=0))/2.
242                   else:
243                       vartmpday[vv,nd,:,iy,ix]=np.mean(varchk[vv,daystart+nitdtmichk:daystart+nitdtmachk+1,:,iy,ix],axis=0)
244                   if ((nitntmichk is np.NaN) or (nitntmachk is np.NaN)):
245                       vartmpnight[vv,nd,:,iy,ix]=np.NaN
246                   elif nitntmichk > nitntmachk:
247                       vartmpnight[vv,nd,:,iy,ix]=(np.mean(varchk[vv,daystart+nitntmichk:daystop+1,:,iy,ix],axis=0)+np.mean(varchk[vv,daystart:daystart+nitntmachk+1,:,iy,ix],axis=0))/2.
248                   else:                                                           
249                       vartmpnight[vv,nd,:,iy,ix]=np.mean(varchk[vv,daystart+nitntmichk:daystart+nitntmachk+1,:,iy,ix],axis=0)
250                iy=iy+1
251             ix=ix+1
252          nd=nd+1
253
254       print "     .creating bins."
255
256       vartmpdaymasked=np.ma.masked_invalid(vartmpday)
257       vartmpnightmasked=np.ma.masked_invalid(vartmpnight)
258       for vv in np.arange(nzvar):
259          vardayout[vv,i,:,:,:]=np.ma.mean(vartmpdaymasked[vv,:,:,:,:],axis=0)
260          varnightout[vv,i,:,:,:]=np.ma.mean(vartmpnightmasked[vv,:,:,:,:],axis=0)
261          print "          ."+varznames[vv]+".done"
262       i=i+1
263
264   print "--->> Preparing Data for ncdf. Missing value is NaN."
265
266   vardayout=np.ma.masked_invalid(vardayout)
267   varnightout=np.ma.masked_invalid(varnightout)
268   vardayout.set_fill_value([np.NaN])
269   varnightout.set_fill_value([np.NaN])
270
271   all=[aps,bps]
272   for vv in np.arange(nzvar):
273       if dimensions[vv] == 3:
274          all.append(vardayout[vv,:,0,:,:].filled())
275          all.append(varnightout[vv,:,0,:,:].filled())
276       elif dimensions[vv] == 4:
277          all.append(vardayout[vv,:,:,:,:].filled())
278          all.append(varnightout[vv,:,:,:,:].filled())
279
280   if opt.recast:
281      all=all[2:]
282      fullnames=fullnames[2:] 
283
284   make_gcm_netcdf (zfilename="diagfi_MCS.nc", \
285                        zdescription="Temperatures from diagfi reworked to match MCS format", \
286                        zlon=lon, \
287                        zlat=lat, \
288                        zalt=alt, \
289                        ztime=timemcs, \
290                        zvariables=all, \
291                        znames=fullnames)
Note: See TracBrowser for help on using the repository browser.