1 | #!/u/acolmd/san0/Python/64bits/epd-7.1-2-rh5-x86_64/bin/python |
---|
2 | if __name__ == "__main__": |
---|
3 | import subprocess |
---|
4 | import sys |
---|
5 | from os import system,unlink |
---|
6 | from glob import glob |
---|
7 | from optparse import OptionParser |
---|
8 | from myplot import errormess |
---|
9 | from ic import check_file, merge_atm_sfc |
---|
10 | ############################# |
---|
11 | ### Get options and variables |
---|
12 | parser = OptionParser() |
---|
13 | parser.add_option('-g','--generate', action='store_true',dest='generate', default=False,help='Generate netcdf files') |
---|
14 | parser.add_option('-c','--clean', action='store_true',dest='clean', default=False,help='Clean mrams_ files') |
---|
15 | parser.add_option('--deepclean', action='store_true',dest='deepclean', default=False,help='Clean everything') |
---|
16 | (opt,args) = parser.parse_args() |
---|
17 | if opt.deepclean: |
---|
18 | for zfile in ['converted_files','figures']: |
---|
19 | subprocess.call(['touch',zfile],shell=False) |
---|
20 | subprocess.call(['rm','-rf',zfile],shell=False) |
---|
21 | subprocess.call(['mkdir',zfile],shell=False) |
---|
22 | if opt.clean: |
---|
23 | subprocess.call(['touch','converted_files/mramsout_d_dummy'],shell=False) |
---|
24 | for f in glob ('converted_files/mramsout_d*'): |
---|
25 | unlink(f) |
---|
26 | if opt.generate: |
---|
27 | opath='./converted_files/' |
---|
28 | ipath='./vis/' |
---|
29 | # for grid in ['g1','g2','g3','g4']: ## INDEX 4 OF TEST CASE HOLDEN DOES NOT WORK (CDO ERROR) |
---|
30 | for grid in ['g1','g2','g3']: |
---|
31 | outfileatm='holden_ls150-atm-S-'+grid+'.nc' |
---|
32 | outfilesfc='holden_ls150-sfc-S-'+grid+'.nc' |
---|
33 | outfilecat='mramsout_d' |
---|
34 | infileatm='holden_ls150-atm-S-'+grid+'.ctl' |
---|
35 | infilesfc='holden_ls150-sfc-S-'+grid+'.ctl' |
---|
36 | print '- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -' |
---|
37 | err=check_file(opath+outfileatm) |
---|
38 | print '=> Begining conversion for File '+infileatm+' -> in -> '+outfileatm |
---|
39 | if err == 1: subprocess.call(['cdo','-f','nc','import_binary',ipath+infileatm,opath+outfileatm],shell=False) |
---|
40 | print '=> File '+infileatm+' -> converted in -> '+outfileatm |
---|
41 | err=check_file(opath+outfilesfc) |
---|
42 | print '=> Begining conversion for File '+infilesfc+' -> in -> '+outfilesfc |
---|
43 | if err == 1: subprocess.call(['cdo','-f','nc','import_binary',ipath+infilesfc,opath+outfilesfc],shell=False) |
---|
44 | print '=> File '+infilesfc+' -> converted in -> '+outfilesfc |
---|
45 | print '- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -' |
---|
46 | print '=> Begining concatenation for Files '+outfilesfc+' and '+outfileatm |
---|
47 | merge_atm_sfc(opath+outfilesfc,opath+outfileatm,opath+outfilecat) |
---|
48 | print '=> Files concatenated !' |
---|
49 | print '- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -' |
---|
50 | |
---|
51 | # subprocess.call(cmdstring,shell=False) |
---|
52 | |
---|
53 | # Check if a file is present and readable |
---|
54 | def check_file(filename): |
---|
55 | from os import path, access, R_OK # W_OK for write permission. |
---|
56 | PATH=filename |
---|
57 | if path.exists(PATH) and path.isfile(PATH) and access(PATH, R_OK): |
---|
58 | return 0 # file exists and is readable |
---|
59 | else: |
---|
60 | return 1 # file is not present and/or readable |
---|
61 | |
---|
62 | # Find lat lon center of the grid |
---|
63 | def find_center(lon,lat,xlon,xlat): |
---|
64 | import numpy as np |
---|
65 | i_lon=0 ; i_lat = 0 ; i_lon2 = 0 ; i_lat2=0 |
---|
66 | if len(lon)%2!=0:i_lon=np.floor(len(lon)/2) # no +1 because arrays start from 0 |
---|
67 | if len(lat)%2!=0:i_lat=np.floor(len(lat)/2) # no +1 because arrays start from 0 |
---|
68 | if i_lon == 0: |
---|
69 | i_lon=len(lon)/2 -1 |
---|
70 | i_lon2=len(lon)/2 |
---|
71 | if i_lat == 0: |
---|
72 | i_lat=len(lat)/2 -1 |
---|
73 | i_lat2=len(lat)/2 |
---|
74 | if i_lon2 == 0 and i_lat2 == 0: |
---|
75 | cen_lon = xlon[i_lat,i_lon] |
---|
76 | cen_lat = xlat[i_lat,i_lon] |
---|
77 | if i_lon2 != 0 and i_lat2 != 0: |
---|
78 | cen_lon = (xlon[i_lat,i_lon] + xlon[i_lat2,i_lon2] + xlon[i_lat,i_lon2] + xlon[i_lat2,i_lon])/4. |
---|
79 | cen_lat = (xlat[i_lat,i_lon] + xlat[i_lat2,i_lon2] + xlat[i_lat,i_lon2] + xlat[i_lat2,i_lon])/4. |
---|
80 | if i_lon2 != 0 and i_lat2 == 0: |
---|
81 | cen_lon = (xlon[i_lat,i_lon] + xlon[i_lat,i_lon2])/2. |
---|
82 | cen_lon = (xlat[i_lat,i_lon] + xlat[i_lat,i_lon2])/2. |
---|
83 | if i_lon2 == 0 and i_lat2 != 0: |
---|
84 | cen_lon = (xlon[i_lat,i_lon] + xlon[i_lat2,i_lon])/2. |
---|
85 | cen_lon = (xlat[i_lat,i_lon] + xlat[i_lat2,i_lon])/2. |
---|
86 | return cen_lon,cen_lat |
---|
87 | |
---|
88 | # Merge atm and sfc netcdf. cdo cat does not work for that. (neither does ncecat) |
---|
89 | def merge_atm_sfc(fsfc,fatm,fmerged): |
---|
90 | from os import system |
---|
91 | from netCDF4 import Dataset |
---|
92 | import numpy as np |
---|
93 | import subprocess |
---|
94 | |
---|
95 | # Calendar |
---|
96 | path_calendar='/san0/acolmd/SVN/trunk/MESOSCALE/LMD_MM_MARS/SIMU/calendar' |
---|
97 | gcm_sol=[] |
---|
98 | gcm_ls=[] |
---|
99 | mmm_date=[] |
---|
100 | calendar = open(path_calendar, 'r') |
---|
101 | calendar.readline() #get rid of the first line |
---|
102 | calendar_l=calendar.readlines() |
---|
103 | for line in calendar_l: |
---|
104 | s=str.split(line) |
---|
105 | gcm_sol=np.append(gcm_sol,np.float(s[1])) |
---|
106 | gcm_ls=np.append(gcm_ls,np.float(s[2])) |
---|
107 | mmm_date=np.append(mmm_date,s[3]) |
---|
108 | calendar.close() |
---|
109 | calendar_l=0. |
---|
110 | |
---|
111 | # Constants |
---|
112 | grav=3.72 |
---|
113 | |
---|
114 | # Grid properties |
---|
115 | ls_simu_start=147. #ls of start simu |
---|
116 | # lt_start="07:30:00" #local time of start simu at cen_lon # read in .ctl |
---|
117 | # NOTE: I ASSUME THE LT_START IN .CTL FOR MRAMS IS LOCAL TIME OF START AT LONGITUDE 0 |
---|
118 | dx=[240000.,80000.,26667,8889] |
---|
119 | dy=dx |
---|
120 | |
---|
121 | # Date management |
---|
122 | idx=np.abs(gcm_ls - ls_simu_start).argmin() |
---|
123 | date_start=mmm_date[idx] |
---|
124 | # USER: fill the date you want to analyse: |
---|
125 | days=[16,17,18] |
---|
126 | |
---|
127 | # Grid id |
---|
128 | if 'g1' in fatm: |
---|
129 | gid=1 |
---|
130 | elif 'g2' in fatm: |
---|
131 | gid=2 |
---|
132 | elif 'g3' in fatm: |
---|
133 | gid=3 |
---|
134 | else: |
---|
135 | gid=4 |
---|
136 | |
---|
137 | # Load datasets |
---|
138 | atm=Dataset(fatm) ; sfc=Dataset(fsfc) |
---|
139 | |
---|
140 | # reconstruct dimensions |
---|
141 | lon = atm.variables['lon'] ; nlon = len(lon) |
---|
142 | lat = atm.variables['lat'] ; nlat = len(lat) |
---|
143 | lev = atm.variables['lev'] ; nlev = len(lev) |
---|
144 | time = atm.variables['time'] ; ntime = len(time) |
---|
145 | units_time=time.units[12:len(time.units)] |
---|
146 | |
---|
147 | # date from mrams file: |
---|
148 | year_mrams, month_mrams, day_mrams, hour_mrams, minute_mrams, second_mrams = date_to_time(units_time) |
---|
149 | lt_start = hour_mrams+':'+minute_mrams+':'+second_mrams |
---|
150 | # or date from calendar with initial Ls: |
---|
151 | year, month, day, hour, minute, second = date_to_time(date_start,lt_start) |
---|
152 | dt=(time[1]-time[0])*60. |
---|
153 | daylength=3600.*24./(dt*60.) |
---|
154 | |
---|
155 | i=0 |
---|
156 | imax=np.floor(len(time)/daylength) |
---|
157 | while (i < imax+1): |
---|
158 | i=i+1 |
---|
159 | dayslab=[int((i-1)*daylength),int(daylength*i)] |
---|
160 | if i==imax+1: dayslab=[int((i-1)*daylength),len(time)] |
---|
161 | fmerged_slab=fmerged+'0'+str(gid)+'_'+time_to_date(mmm_date[idx+i-1],lt_start) |
---|
162 | err=check_file(fmerged_slab) |
---|
163 | year, month, day, hour, minute, second = date_to_time(mmm_date[idx+i-1],lt_start) |
---|
164 | if int(day) in days: |
---|
165 | print ' -->> hyperslab : ',dayslab,' => mramsout_d0'+str(gid)+'_'+time_to_date(mmm_date[idx+i-1],lt_start) |
---|
166 | else: |
---|
167 | err=0 |
---|
168 | print ' -->> hyperslab : ',dayslab,' => mramsout_d0'+str(gid)+'_'+time_to_date(mmm_date[idx+i-1],lt_start)+' --> Skipped' |
---|
169 | if err == 1: |
---|
170 | # prepare merged file |
---|
171 | subprocess.call(['touch',fmerged_slab],shell=False) |
---|
172 | subprocess.call(['rm','-rf',fmerged_slab],shell=False) |
---|
173 | merged_file = Dataset(fmerged_slab, 'w', format='NETCDF3_64BIT') |
---|
174 | merged_file.description = 'MRAMS merged atm and sfc converted (netcdf) file.' |
---|
175 | ## Dimensions |
---|
176 | merged_file.createDimension('Time', None) |
---|
177 | merged_file.createDimension('bottom_top',nlev) |
---|
178 | merged_file.createDimension('south_north',nlat) |
---|
179 | merged_file.createDimension('west_east',nlon) |
---|
180 | merged_file.createDimension('bottom_top_stag',nlev+1) # very important for PHTOT in API |
---|
181 | # merged_file.createDimension('south_north_stag',nlat+1) |
---|
182 | # merged_file.createDimension('west_east_stag',nlon+1) |
---|
183 | ## Variables for dimensions |
---|
184 | times = merged_file.createVariable('Time', 'f', ('Time',)) |
---|
185 | times[:] = time[dayslab[0]:dayslab[1]] |
---|
186 | altitudes = merged_file.createVariable('bottom_top', 'f', ('bottom_top',)) |
---|
187 | altitudes[:] = lev[:] |
---|
188 | latitudes = merged_file.createVariable('south_north', 'f', ('south_north',)) |
---|
189 | latitudes[:] = lat[:] |
---|
190 | longitudes = merged_file.createVariable('west_east', 'f', ('west_east',)) |
---|
191 | longitudes[:] = lon[:] |
---|
192 | ## Set attributes |
---|
193 | setattr(merged_file, 'TITLE', 'OUTPUT FROM MRAMS MODEL') |
---|
194 | setattr(merged_file, 'START_DATE', time_to_date(mmm_date[idx],lt_start)) |
---|
195 | setattr(merged_file, 'SIMULATION_START_DATE', time_to_date(mmm_date[idx],lt_start)) |
---|
196 | setattr(merged_file, 'WEST-EAST_GRID_DIMENSION', nlon+1) |
---|
197 | setattr(merged_file, 'SOUTH-NORTH_GRID_DIMENSION', nlat+1) |
---|
198 | setattr(merged_file, 'BOTTOM-TOP_GRID_DIMENSION', nlev+1) |
---|
199 | setattr(merged_file, 'DX', np.float(dx[gid-1])) |
---|
200 | setattr(merged_file, 'DY', np.float(dy[gid-1])) |
---|
201 | setattr(merged_file, 'DT', np.float(dt)) |
---|
202 | setattr(merged_file, 'GRID_TYPE', 'C') # |
---|
203 | setattr(merged_file, 'GRID_ID', gid) |
---|
204 | setattr(merged_file, 'PARENT_ID', gid-1) |
---|
205 | setattr(merged_file, 'MAP_PROJ', 2) # |
---|
206 | setattr(merged_file, 'JULYR', year) |
---|
207 | setattr(merged_file, 'JULDAY', gcm_sol[idx+i-1]) |
---|
208 | setattr(merged_file, 'WEST-EAST_PATCH_START_UNSTAG' , 1) |
---|
209 | setattr(merged_file, 'WEST-EAST_PATCH_END_UNSTAG' , nlon) |
---|
210 | setattr(merged_file, 'WEST-EAST_PATCH_START_STAG' , 1) |
---|
211 | setattr(merged_file, 'WEST-EAST_PATCH_END_STAG' , nlon) ### |
---|
212 | setattr(merged_file, 'SOUTH-NORTH_PATCH_START_UNSTAG' , 1) |
---|
213 | setattr(merged_file, 'SOUTH-NORTH_PATCH_END_UNSTAG' , nlat) |
---|
214 | setattr(merged_file, 'SOUTH-NORTH_PATCH_START_STAG' , 1) |
---|
215 | setattr(merged_file, 'SOUTH-NORTH_PATCH_END_STAG' , nlat) ### |
---|
216 | setattr(merged_file, 'BOTTOM-TOP_PATCH_START_UNSTAG' , 1) |
---|
217 | setattr(merged_file, 'BOTTOM-TOP_PATCH_END_UNSTAG' , nlev) |
---|
218 | setattr(merged_file, 'BOTTOM-TOP_PATCH_START_STAG' , 1) |
---|
219 | setattr(merged_file, 'BOTTOM-TOP_PATCH_END_STAG' , nlev+1) |
---|
220 | ## Set grid variables |
---|
221 | xlon = merged_file.createVariable('XLONG', 'f', ('Time','south_north','west_east',)) |
---|
222 | xlat = merged_file.createVariable('XLAT', 'f', ('Time','south_north','west_east',)) |
---|
223 | print ' glon -> XLON' ; xlon[:,:,:] = sfc.variables['glon'][dayslab[0]:dayslab[1],:,:] |
---|
224 | print ' glat -> XLAT' ; xlat[:,:,:] = sfc.variables['glat'][dayslab[0]:dayslab[1],:,:] |
---|
225 | cen_lon, cen_lat = find_center(lon,lat,xlon[0,:,:],xlat[0,:,:]) |
---|
226 | setattr(merged_file, 'CEN_LAT', cen_lat) |
---|
227 | setattr(merged_file, 'CEN_LON', cen_lon) |
---|
228 | ## Renaming |
---|
229 | print ' topo -> HGT' ; hgt = merged_file.createVariable('HGT', 'f', ('Time','south_north','west_east',)) |
---|
230 | hgt[:,:,:] = sfc.variables['topo'][dayslab[0]:dayslab[1],:,:] |
---|
231 | print ' tempk -> tk' ; tk = merged_file.createVariable('tk', 'f', ('Time','bottom_top','south_north','west_east',)) |
---|
232 | tk[:,:,:,:] = atm.variables['tempk'][dayslab[0]:dayslab[1],:,:,:] |
---|
233 | print ' press -> PTOT' ; ptot = merged_file.createVariable('PTOT', 'f', ('Time','bottom_top','south_north','west_east',)) |
---|
234 | ptot[:,:,:,:] = atm.variables['press'][dayslab[0]:dayslab[1],:,:,:] |
---|
235 | u = merged_file.createVariable('U', 'f', ('Time','bottom_top','south_north','west_east',)) |
---|
236 | v = merged_file.createVariable('V', 'f', ('Time','bottom_top','south_north','west_east',)) |
---|
237 | w = merged_file.createVariable('W', 'f', ('Time','bottom_top','south_north','west_east',)) |
---|
238 | print ' u_avg -> U' ; u[:,:,:,:] = atm.variables['u_avg'][dayslab[0]:dayslab[1],:,:,:] |
---|
239 | print ' v_avg -> V' ; v[:,:,:,:] = atm.variables['v_avg'][dayslab[0]:dayslab[1],:,:,:] |
---|
240 | print ' w_avg -> W' ; w[:,:,:,:] = atm.variables['w_avg'][dayslab[0]:dayslab[1],:,:,:] |
---|
241 | tke = merged_file.createVariable('TKE', 'f', ('Time','bottom_top','south_north','west_east',)) |
---|
242 | print ' sgs_tke -> TKE' ; tke[:,:,:,:] = atm.variables['sgs_tke'][dayslab[0]:dayslab[1],:,:,:] |
---|
243 | tau_dust = merged_file.createVariable('TAU_DUST', 'f', ('Time','south_north','west_east',)) |
---|
244 | print ' dust_sfc_od_vis -> TAU_DUST' ; tau_dust[:,:,:] = atm.variables['dust_sfc_od_vis'][dayslab[0]:dayslab[1],:,:] |
---|
245 | z_lyrmid_agl = merged_file.createVariable('z_lyrmid_agl', 'f', ('Time','bottom_top','south_north','west_east',)) |
---|
246 | print ' z_lyrmid_agl -> z_lyrmid_agl' ; z_lyrmid_agl[:,:,:,:] = atm.variables['z_lyrmid_agl'][dayslab[0]:dayslab[1],:,:,:] |
---|
247 | # Compute PHTOT for API |
---|
248 | print ' Computing PHTOT' |
---|
249 | phtot = merged_file.createVariable('PHTOT', 'f', ('Time','bottom_top_stag','south_north','west_east',)) |
---|
250 | phtot[:,0:nlev,:,:]=z_lyrmid_agl[:,:,:,:]*grav ; phtot[:,nlev,:,:]=0. |
---|
251 | for l in np.arange(nlev): |
---|
252 | phtot[:,l,:,:]=phtot[:,l,:,:] + grav*hgt[:,:,:] |
---|
253 | |
---|
254 | merged_file.close() |
---|
255 | |
---|
256 | def date_to_time(date,ltstart=None): |
---|
257 | year=date[0:4] |
---|
258 | month=date[5:7] |
---|
259 | day=date[8:10] |
---|
260 | hour=date[11:13] |
---|
261 | minute=date[14:16] |
---|
262 | second=date[17:19] |
---|
263 | if ltstart is not None: |
---|
264 | hour=ltstart[0:2] |
---|
265 | minute=ltstart[3:5] |
---|
266 | second=ltstart[6:8] |
---|
267 | return year,month,day,hour,minute,second |
---|
268 | |
---|
269 | def time_to_date(date,ltstart=None): |
---|
270 | if ltstart is not None: return date[0:11]+ltstart |
---|
271 | else: return date |
---|