source: trunk/src/interp_erai_t2m.pro

Last change on this file was 204, checked in by pinsard, 10 years ago

fix thanks to coding rules; typo

  • Property svn:keywords set to Id
File size: 14.4 KB
Line 
1;+
2;
3; ===================
4; interp_erai_t2m.pro
5; ===================
6;
7; .. function:: interp_erai_t2m(yyyymmddb,yyyymmdde, eraitype)
8;
9; DESCRIPTION
10; ===========
11;
12; Interpolation of t2 from ERA-I grid to OAFLUX grid
13;
14; If eraitype is set to 1,
15; :file:`${PROJECT_ID}/20c3m_erai_t2_TROP_1989_2009.nc`
16; containing
17; t2 from ERA-I
18; has been produced by
19; :ref:`compute_erai_daily_region_2d.sh`.
20;
21; If eraitype is set to 2,
22; :file:`${PROJECT_ID}/erai_t2m_{yyyyb}_{yyyye}.nc`
23; containing
24; t2m from ERA-I
25; has been produced by
26; :ref:`concat_eraiy.sh`.
27;
28; :file:`${PROJECT_ID}/mask_oaflux_30N30S.nc`
29; containing OAFLUX grid
30; has been produced by
31; :func:`oaflux_mask_30n30s`.
32;
33; Interpolated t2
34; is written in
35; :file:`${PROJECT_OD}/erai_t2m_{yyyymmdd}_{yyyymmdd}_oafluxgrid.nc`
36; if this file not already exists.
37;
38; This output file
39; :file:`${PROJECT_OD}/erai_t2m_{yyyymmdd}_{yyyymmdd}_oafluxgrid.nc`
40; must be processed after by
41; :func:`t2m_correction_ncdf`.
42;
43; .. only:: man
44;
45;    Figure is visible on PDF and HTML documents only.
46;
47; .. only:: html or latex
48;
49;     .. graphviz::
50;
51;        digraph interp_erai_t2m {
52;
53;           file_in_erai1 [shape=ellipse,fontname=Courier,label="${PROJECT_ID}/20c3m_erai_t2_TROP_1989_2009.nc"];
54;           file_in_erai2 [shape=ellipse,fontname=Courier,label="${PROJECT_ID}/erai_t2m_{yyyyb}_{yyyye}.nc"];
55;           mask [shape=ellipse,fontname=Courier,label="${PROJECT_ID}/mask_oaflux_30N30S.nc"];
56;           file_out [shape=ellipse,fontname=Courier,label="${PROJECT_OD}/erai_t2m_{yyyymmdd}_{yyyymmdd}_oafluxgrid.nc"];
57;
58;           interp_erai_t2m [shape=box,
59;           fontname=Courier,
60;           color=blue,
61;           URL="http://forge.ipsl.jussieu.fr/tropflux/browser/trunk/src/interp_erai_t2m.pro",
62;           label="${PROJECT}/src/interp_erai_t2m.pro"];
63;
64;           {file_in_erai1 file_in_erai2 mask} -> {interp_erai_t2m} -> {file_out}
65;
66;        }
67;
68; SEE ALSO
69; ========
70;
71; :ref:`interpolate_data`
72;
73; Used by :ref:`tropflux.sh`
74;
75; :ref:`project_profile.sh`
76;
77; :ref:`compute_erai_daily_region_2d.sh`
78; :ref:`concat_eraiy.sh`
79;
80; :func:`oaflux_mask_30n30s`
81;
82; :func:`report <saxo:report>`
83; :func:`isadirectory <saxo:isadirectory>`
84; :func:`isafile <saxo:isafile>`
85; :func:`initncdf <saxo:initncdf>`
86; :func:`read_ncdf <saxo:read_ncdf>`
87; :func:`ncdf_lec <saxo:ncdf_lec>`
88; :func:`domdef <saxo:domdef>`
89; :func:`call_interp2d <saxo:call_interp2d>`
90; :func:`ncdf_quickwrite <saxo:ncdf_quickwrite>`
91; :func:`ncdf_getatt <saxo:ncdf_getatt>`
92;
93; :func:`t2m_correction_ncdf`
94;
95; EXAMPLES
96; ========
97;
98; With ERA-I type 1:
99;
100; .. code-block:: idl
101;
102;    .compile file_interp
103;    yyyymmddb = 20000101L
104;    yyyymmdde = 20001231L
105;    eraitype = 1
106;    result = interp_erai_t2m(yyyymmddb, yyyymmdde, eraitype)
107;    print, result
108;
109; With ERA-I type 2:
110;
111; .. code-block:: idl
112;
113;    .compile file_interp
114;    yyyymmddb = 20000101L
115;    yyyymmdde = 20001231L
116;    eraitype = 2
117;    result = interp_erai_t2m(yyyymmddb, yyyymmdde, eraitype)
118;    print, result
119;
120; TODO
121; ====
122;
123; scientific validation (strange look of data with ncview now)
124;
125; check [yyyymmddb,yyyymmdde] validity
126;
127; check if [yyyymmddb,yyyymmdde] is included in ERA-I file
128;
129; what happen if yyyymmdde > 20091231 : need to read an other ERA-I file
130;
131; make it work : pb on loholt1 idl8
132;
133; reach end but bad time and t2m values :
134;
135; .. code-block:: bash
136;
137;     ncks -v t2m  -d time,0,1 -d latitude,0,1 -d longitude,0,1 /homedata/pinsard/tropflux_d/erai_t2m_19890101_20091231_oafluxgrid.nc
138;     latitude[0]=-29.5 degrees_north
139;     latitude[1]=-28.5 degrees_north
140;
141;     longitude[0]=30.5 degrees_east
142;     longitude[1]=31.5 degrees_east
143;
144;     time[0]=9.96920996839e+36 latitude[0]=-29.5 longitude[0]=30.5 t2m[0]=9.96921e+36 degK
145;     time[0]=9.96920996839e+36 latitude[0]=-29.5 longitude[1]=31.5 t2m[1]=9.96921e+36 degK
146;     time[0]=9.96920996839e+36 latitude[1]=-28.5 longitude[0]=30.5 t2m[350]=9.96921e+36 degK
147;     time[0]=9.96920996839e+36 latitude[1]=-28.5 longitude[1]=31.5 t2m[351]=9.96921e+36 degK
148;     time[1]=9.96920996839e+36 latitude[0]=-29.5 longitude[0]=30.5 t2m[21000]=9.96921e+36 degK
149;     time[1]=9.96920996839e+36 latitude[0]=-29.5 longitude[1]=31.5 t2m[21001]=9.96921e+36 degK
150;     time[1]=9.96920996839e+36 latitude[1]=-28.5 longitude[0]=30.5 t2m[21350]=9.96921e+36 degK
151;     time[1]=9.96920996839e+36 latitude[1]=-28.5 longitude[1]=31.5 t2m[21351]=9.96921e+36 degK
152;
153;     time[0]=9.96920996839e+36 hours since 1957-01-01 00:00:0.0
154;     time[1]=9.96920996839e+36 hours since 1957-01-01 00:00:0.0
155;
156; loholt1 idl6 : end without error but looking with ncview all brown !
157;
158; strange view (lat and lon shift with ncview) : check grid init
159;
160; remove useless netcdf_read or choose between read_ncdf and ncdf_lec
161;
162; check time values
163;
164; why use :func:`call_interp2d <saxo:call_interp2d>` : this is an hidden function of SAXO
165; see :func:`file_interp <saxo:file_interp>`
166;
167; use as input a file produced by compute_erai_daily_region_2d.sh or
168; get_erai.py + grib to netcdf conversion
169;
170; coding rules
171;
172; hard coded time in module name and in output filename
173;
174; why two "initncdf, fullfilename_msk"
175;
176; hard coded attributes for t2m (missing value, short name, axis) and time (origin) : use ncdf_getatt
177;
178; CF conventions
179;
180; check OUTMASK_IND and SET_OUTMSKVAL added to call_interp2d call
181;
182; KNOWN ISSUES
183; ============
184;
185; test of existence of fullfilename_msk not very efficient because
186; MUST_EXIST keyword of :func:`isafile <saxo:isafile>` not yet implemented
187;
188; EVOLUTIONS
189; ==========
190;
191; $Id$
192;
193; $URL: svn+ssh://pinsard@forge.ipsl.jussieu.fr/ipsl/forge/projets/tropflux/svn/trunk/src/interp_erai_t2m.pro $
194;
195; - fplod 20120704T113504Z cratos (Linux)
196;
197;   * add eraitype parameter
198;   * deal with time units (days vs hours) and time origin
199;
200; - fplod 20120319
201;
202;   * taking project_overwrite into account
203;
204; - fplod 20120306
205;
206;   * try to add compile_opt seems to be incompatible with ncdf_quickwrite
207;   * pro -> function
208;
209; - pinsard 2011-08-23T09:09:16Z loholt1.ipsl.polytechnique.fr (Linux)
210;
211;   * retry on loholt1 with idl8 and idl6
212;
213; - pinsard 2011-08-08T16:11:48Z loholt1.ipsl.polytechnique.fr (Linux)
214;
215;   * remove ncdf_quickwrite exercices
216;
217; - fplod 20110808T094156Z cratos (Linux)
218;
219;   * add OUTMASK_IND and SET_OUTMSKVAL to call_interp2d call
220;
221; - fplod 20110103T153734Z aedon.locean-ipsl.upmc.fr (Darwin)
222;
223;   * computed first and last dates
224;   * start using ncdf_getatt instead of hard coded attributes
225;
226; - fplod 20101223T130406Z aedon.locean-ipsl.upmc.fr (Darwin)
227;
228;   * replace /Volumes/PRAVEEN/TropFlux/input_uncor/ by ${TROPFLUX_OD}
229;   * complete documentation
230;   * get time dimension in data file
231;   * replace read_ncdf by ncdf_lec
232;
233;     usage of timestep keyword in read_ncdf was not efficient because of memory problem :
234;     can not read the whole time range (ok with 7580, not ok with 7591 while need is 7670
235;
236;     .. parsed-literal::
237;
238;        % Unable to allocate memory: to make array.
239;        Cannot allocate memory
240;
241;     When timestep keyword is not used we can see these messages:
242;
243;     .. parsed-literal::
244;
245;        /usr/work/incas/fplod/tropflux_d/20c3m_erai_t2_TROP_1989_2009.nc has no time axis variable
246;
247;     given by Praveen
248;
249;     .. parsed-literal::
250
251;        Value of Julian date is out of allowed range
252;
253;        % Array used to subscript array contains out of range subscript: DATAIN
254;
255; - fplod 20101222T163216Z aedon.locean-ipsl.upmc.fr (Darwin)
256;
257;   * replace /Volumes/PRAVEEN/ERAI_global by ${TROPFLUX_ID}
258;
259; - fplod 20101217T140745Z aedon.locean-ipsl.upmc.fr (Darwin)
260;
261;   * remove hard coded directory for mask_oaflux_30N30S.nc
262;
263; - fplod 20101215T112140Z aedon.locean-ipsl.upmc.fr (Darwin)
264;
265;   * add graph in header
266;
267; - fplod 20101214T093615Z aedon.locean-ipsl.upmc.fr (Darwin)
268;
269;   * minimal header
270;
271; - pbk 2008
272;
273;   * creation
274;
275;-
276function interp_erai_t2m $
277, yyyymmddb $
278, yyyymmdde $
279, eraitype
280;
281;++compile_opt idl2, strictarrsubs, logical_predicate
282;
283@cm_4cal
284@cm_4data
285@cm_4mesh
286@cm_4data
287@cm_project
288;
289; Return to caller if errors
290ON_ERROR, 2
291;
292result = -1
293;
294usage = 'result = interp_erai_t2m(yyyymmddb, yyyymmdde, eraitype)'
295nparam = N_PARAMS()
296IF (nparam NE 3) THEN BEGIN
297    ras = report(['Incorrect number of arguments.' $
298    + '!C' $
299    + 'Usage : ' + usage])
300    return, result
301ENDIF
302
303; check for input directory
304;
305; test if ${PROJECT_ID} defined
306CASE project_id_env OF
307    '' :  BEGIN
308        msg = 'eee : ${PROJECT_ID} is not defined'
309        ras = report(msg)
310        return, result
311    END
312    ELSE : BEGIN
313        msg = 'iii : ${PROJECT_ID} is ' + project_id_env
314        ras = report(msg)
315    END
316ENDCASE
317;
318iodirin = isadirectory(project_id_env)
319;
320; existence and protection of ${PROJECT_ID}
321IF (FILE_TEST(iodirin, /DIRECTORY, /EXECUTABLE, /READ) EQ 0) THEN BEGIN
322    msg = 'eee : the directory' + iodirin  + ' is not accessible.'
323    ras = report(msg)
324    return, result
325ENDIF
326;
327; build mask filename
328filename_msk='mask_oaflux_30N30S.nc'
329;
330; check if this file exists
331msg='iii : looking for ' + filename_msk
332ras = report(msg)
333fullfilename_msk = isafile(iodirin + filename_msk, NEW=0, /MUST_EXIST)
334IF fullfilename_msk[0] EQ '' THEN BEGIN
335    msg = 'eee : the file ' + fullfilename_msk + ' was not found.'
336    ras = report(msg)
337    return, result
338ENDIF
339;
340; build t2 filename
341IF eraitype EQ 1 THEN BEGIN
342    erai_var = 't2'
343    filename_t2 = '20c3m_erai_t2_TROP_1989_2009.nc'
344    tutoday = 24.d
345    tmporig = date2jul(19570101L,month=immo,day=iddo,year=iyyyyo)
346endif
347IF (eraitype eq 2) THEN BEGIN
348    erai_var = 't2m'
349    tmpb = date2jul(yyyymmddb,month=immb,day=iddb,year=iyyyyb)
350    tmpe = date2jul(yyyymmdde,month=imme,day=idde,year=iyyyye)
351    filename_t2 = 'erai_' + erai_var + '_' + string(iyyyyb,format='(I4.4)') + '_' + string(iyyyye,format='(I4.4)') + '.nc'
352    tutoday = 1.d
353    tmporig = date2jul(19500101L,month=immo,day=iddo,year=iyyyyo)
354ENDIF
355;
356; check if this file exists
357msg='iii : looking for ' + filename_t2
358ras = report(msg)
359fullfilename_t2 = isafile(iodirin + filename_t2, NEW=0, /MUST_EXIST)
360IF fullfilename_t2[0] EQ '' THEN BEGIN
361    msg = 'eee : the file ' + fullfilename_t2 + ' was not found.'
362    ras = report(msg)
363    return, result
364ENDIF
365;
366; test if ${PROJECT_OD} defined
367CASE project_od_env OF
368    '' : BEGIN
369        msg = 'eee : ${PROJECT_OD} is not defined'
370        ras = report(msg)
371        return, result
372    END
373    ELSE : BEGIN
374        msg = 'iii : ${PROJECT_OD} is ' + project_od_env
375        ras = report(msg)
376    END
377ENDCASE
378;
379; check if output data will be possible
380iodirout = isadirectory(project_od_env)
381;
382; existence and protection
383IF (FILE_TEST(iodirout, /DIRECTORY, /WRITE) EQ 0) THEN BEGIN
384    msg = 'eee : the directory' + iodirout  + ' was not found.'
385    ras = report(msg)
386    return, result
387ENDIF
388;
389; build output filename
390filename_out = 'erai_t2m_' +  string(yyyymmddb,format='(I8.8)') + '_' + string(yyyymmdde,format='(I8.8)') + '_oafluxgrid.nc'
391fullfilename_out = iodirout + filename_out
392; in order to avoid unexpected overwritten
393IF ((FILE_TEST(fullfilename_out) EQ 1)  AND (project_overwrite EQ 0)) THEN BEGIN
394    msg = 'eee : the file ' + fullfilename_out  + ' already exists.'
395    ras = report(msg)
396    return, result
397ENDIF
398;
399; define grid parameters with t2 file
400initncdf, fullfilename_t2
401domdef
402latin=reform(gphit[0,*])
403lonin=reform(glamt[*,0])
404print, 'lat grid from data',min(latin),max(latin),latin[1]-latin[0]
405print, 'lon grid from data',min(lonin),max(lonin),lonin[1]-lonin[0]
406;
407;; get time in t2 file
408;timein=ncdf_lec(fullfilename_t2,var='time')
409;jptin=n_elements(timein)
410;print, 'time steps from data ', jptin
411;print, 'The first 10 time values (variable timein) = ', timein[0:9]
412;
413; find first and last dates yyyymmdd
414;; they will be written in global attributes of output file
415;da=jul2date(julday(01, 01, 1957,timein[0]))
416;cda0=string(da,format='(i8.8)')
417;da=jul2date(julday(01, 01, 1957,timein[jptin-1]))
418;cda1=string(da,format='(i8.8)')
419;print, 'first date ', cda0
420;print, 'last date ' , cda1
421;
422; read t2 data
423;++ pb memory t2min=read_ncdf("t2",0,jptin-1,/timestep,file=fullfilename_t2,/nostr)
424; the following line is here just to prepare replacement of read_ncdf by ncdf_lec
425;t2min_read_ncdf=read_ncdf("t2",0,10,/timestep,file=fullfilename_t2,/nostr)
426;help, t2min_read_ncdf
427;++print, 'The first 10 time values (variable time) = ', time[0:9]
428;++print, 'time steps after read_ncdf (variable jpt) ', jpt
429;t2min=ncdf_lec(fullfilename_t2,var=erai_var)
430
431t2min=read_ncdf(erai_var,yyyymmddb-.5d,yyyymmdde,file=fullfilename_t2,/nost)
432;; time:units = "hours since 1957-01-01 00:00:0.0" ;
433timein=tutoday*(time-julday(immo,iddo,iyyyyo,0,0,0))
434jptin=n_elements(timein)
435da=jul2date(time[0])
436cda0=string(da,format='(i8.8)')
437da=jul2date(time[jpt-1])
438cda1=string(da,format='(i8.8)')
439print, 't2m first date ', cda0
440print, 't2m last date ' , cda1
441help, t2min
442;
443mskin=glamt*0.+1.
444;
445; define grid parameters with mask file
446initncdf, fullfilename_msk
447domdef
448latout=reform(gphit[0,*])
449lonout=reform(glamt[*,0])
450print, 'lat grid from mask ',min(latout),max(latout),latout[1]-latout[0]
451print, 'lon grid from mask ',min(lonout),max(lonout),lonout[1]-lonout[0]
452mskout=read_ncdf("msk", file=fullfilename_msk,/nostr)
453;
454help, t2min,lonin,latin,mskin,lonout,latout,mskout
455;
456; interpolation and mask
457t2mout=fltarr(jpi,jpj,jptin)
458for jt=0,jptin-1 do begin
459    tab=reform(t2min[*,*,jt])
460    t2mout[*,*,jt]=call_interp2d(tab,lonin,latin,mskin $
461    , lonout,latout,method="bilinear" $
462    , OUTMASK_IND=mskout, SET_OUTMSKVAL=mskout)
463    t2mout[*,*,jt]=t2mout[*,*,jt]*mskout+(1.-mskout)*1.e20
464endfor
465;
466initncdf, fullfilename_msk
467;
468lat=latout
469lon=lonout
470ncfile='!' + fullfilename_out
471ncdf_getatt, fullfilename_msk, 'longitude', units=units
472ncdf_getatt, fullfilename_msk, 'longitude', long_name=long_name
473lon_attr={units:units, long_name:long_name}
474ncdf_getatt, fullfilename_msk, 'latitude', units=units
475ncdf_getatt, fullfilename_msk, 'latitude', long_name=long_name
476lat_attr={units:units, long_name:long_name}
477ncdf_getatt, fullfilename_t2, 'time', units=units
478ncdf_getatt, fullfilename_t2, 'time', long_name=long_name
479time_attr={units:units, long_name:long_name, time_origin:' 1957-JAN-01 00:00:00'}
480globattr={source:'Data are from ECMWF ERA-Interim reanalysis', timerange:cda0+' - '+cda1}
481ncdf_getatt, fullfilename_t2, erai_var, units=units
482ncdf_getatt, fullfilename_t2, erai_var, long_name=long_name
483t2m_attr={units:units, long_name:long_name, missing_value:1e20, short_name:'t2m',axis:'TYX'}
484;
485help, t2mout
486help, timein
487ncfields = 't2m[longitude,latitude,*time]=t2mout:t2m_attr; ' $
488+ 'longitude[]=lon:lon_attr; ' $
489+ 'latitude[]=lat:lat_attr; ' $
490+ 'time[]=timein:time_attr ' $
491+ ' @globattr'
492@ncdf_quickwrite
493;
494result = 0
495return, result
496;
497end
Note: See TracBrowser for help on using the repository browser.