source: trunk/procs/nc_read.pro

Last change on this file was 229, checked in by ericg, 14 years ago

Various improvements on ensembles and time axis bug correction in compute_time.pro

  • Property svn:keywords set to Id
File size: 7.6 KB
Line 
1;+
2;
3; Reading any netcdf file
4;
5; @param FILE_NAME {in}{required}{type=string}
6;
7; @param VAR_NAME {in}{required}{type=string}
8; variable name
9;
10; @param NCDF_DB {in}{required}{type=string}
11; <location>:<path> or just <path>
12;
13; @keyword BOXZOOM
14;
15; @keyword TIME_1
16;
17; @keyword TIME_2
18;
19; @keyword ALL_DATA
20;
21; @keyword NO_MEAN
22;
23; @returns
24; structure
25; -1 in case of error
26;
27; @examples
28;
29; IDL> file_name='ginette'
30; IDL> var_name='temp_1'
31; IDL> ncdf_db='local:./'
32; IDL> vert_type='z'
33; IDL> result=nc_read(file_name, var_name, ncdf_db)
34; IDL> help, result,/structure
35; IDL> print, result
36;
37; @uses
38; <pro>common</pro>
39; <propost_it>com_eg</propost_it>
40;
41; <pro>ncdf_getatt</pro>
42;
43; @todo
44;
45; explication sur vert_type
46;
47; realistic example
48;
49; @history
50;
51; - fplod 20091210T135516Z aedon.locean-ipsl.upmc.fr (Darwin)
52;
53;   * check parameters
54;
55; @version
56; $Id$
57;
58;-
59FUNCTION nc_read, file_name, var_name, ncdf_db $
60         , BOXZOOM=boxzoom $
61         , TIME_1=time_1 $
62         , TIME_2=time_2 $
63         , ALL_DATA=all_data $
64         , NO_MEAN=no_mean
65;
66  compile_opt idl2, strictarrsubs
67;
68@common
69@com_eg
70;
71   IF debug_w THEN BEGIN
72    info = report('enter ...')
73   ENDIF
74;
75; Return to caller if errors
76;++ ON_ERROR, 2
77;
78 usage='result=nc_read(file_name, var_name, ncdf_db '$
79         + ', BOXZOOM=boxzoom' $
80         + ', TIME_1=time_1' $
81         + ', TIME_2=time_2' $
82         + ', ALL_DATA=all_data' $
83         + ', NO_MEAN=no_mean)'
84
85 nparam = N_PARAMS()
86 IF (nparam LT 3) THEN BEGIN
87    ras = report(['Incorrect number of arguments.' $
88          + '!C' $
89          + 'Usage : ' + usage])
90    return, -1
91 ENDIF
92
93 arg_type = size(file_name,/type)
94 IF (arg_type NE 7) THEN BEGIN
95   ras = report(['Incorrect arg type file_name' $
96          + '!C' $
97          + 'Usage : ' + usage])
98   return, -1
99 ENDIF
100
101 arg_type = size(var_name,/type)
102 IF (arg_type NE 7) THEN BEGIN
103   ras = report(['Incorrect arg type var_name' $
104          + '!C' $
105          + 'Usage : ' + usage])
106   return, -1
107 ENDIF
108
109 arg_type = size(ncdf_db,/type)
110 IF (arg_type NE 7) THEN BEGIN
111   ras = report(['Incorrect arg type ncdf_db' $
112          + '!C' $
113          + 'Usage : ' + usage])
114   return, -1
115 ENDIF
116
117 common_type=size(vert_type,/type)
118 IF (common_type NE 7) THEN BEGIN
119   ras = report(['Incorrect common type vert_type' $
120          + '!C' $
121          + 'Usage : ' + usage])
122   return, -1
123 ENDIF
124
125   IF NOT keyword_set(TIME_1) THEN BEGIN
126    time_1 = 1
127   ENDIF
128   IF NOT keyword_set(TIME_2) THEN BEGIN
129    time_2 = time_1
130   ENDIF
131   IF debug_w THEN BEGIN
132    print, '  Before read_ncdf, key_yreverse=', key_yreverse
133   ENDIF
134
135; decide which subdomain of data to read
136   IF debug_w THEN BEGIN
137    print, '     keyword_set(ALL_DATA) : ', keyword_set(ALL_DATA)
138   ENDIF
139   IF keyword_set(ALL_DATA) THEN BEGIN
140      tout = 1
141   ENDIF ELSE BEGIN
142      tout = 0
143   ENDELSE
144   CASE vert_type OF
145      'z' : zindex = 0
146      'level' : zindex = 1
147      ELSE: zindex = 0
148   ENDCASE
149
150; local directory
151   IF strpos(ncdf_db, ':') GE 1 THEN BEGIN
152    directory = (strsplit(ncdf_db, ':', /EXTRACT))[1]
153   ENDIF ELSE BEGIN
154    directory = ncdf_db
155   ENDELSE
156
157; Find the variable's attribute
158   ncdf_getatt, directory+file_name, var_name, add_offset = add_offset, scale_factor = scale_factor, $
159    missing_value = missing_value, units = units, calendar = calendar, long_name = long_name
160
161   IF debug_w THEN BEGIN
162      print, '   nc_read: netCDF file attributes:  add_offset =', add_offset,', scale_factor = ', scale_factor,', missing_value =', missing_value,', units =', units, ', calendar = ', calendar,', long_name =', long_name
163   ENDIF
164     
165; By default units for the Z axis are meters
166   IF n_elements(gdept) GT 1 THEN BEGIN
167      IF name_level NE '-' THEN BEGIN
168         ncdf_getatt, directory+file_name, name_level, units = units_depth
169      ENDIF ELSE BEGIN
170         units_depth = 'm'
171      ENDELSE
172   ENDIF ELSE BEGIN
173      units_depth = ''
174   ENDELSE
175
176; Check consistency between time_2 computed from param in cmdline and the max number
177; of time steps found in the file.
178   jpt_max = find_jptmax(file_name, IODIRECTORY = directory)
179   IF time_2-time_1+1 GT jpt_max AND jpt_max NE -1 THEN BEGIN
180    time_2 = time_1+jpt_max-1
181   ENDIF
182
183; Read the data with a call to read_ncdf
184   IF debug_w THEN BEGIN
185    print, '     '
186    print, '     Reading raw data from ', file_name
187    IF keyword_set(boxzoom) THEN BEGIN
188     print, '     boxzoom before=', boxzoom
189    ENDIF
190   ENDIF
191   lec_data = read_ncdf(var_name, time_1-1, time_2-1, BOXZOOM = boxzoom, FILENAME = directory+file_name, $
192                        /TIMESTEP, TOUT = tout, /NOSTRUCT, /CONT_NOFILL, GRID = vargrid, $
193                        ZINVAR = zinvar, ZINDEX = zindex)
194   field_dim = (size(lec_data))[0]
195   IF field_dim LE 0 THEN BEGIN
196    print, '  Something wrong happened in read_ncdf '
197    return, -1
198   ENDIF
199
200   IF debug_w THEN BEGIN
201    print, '     '
202    IF keyword_set(boxzoom) THEN BEGIN
203     print, '    boxzoom after=', boxzoom
204    ENDIF
205    print, '    firstxt,firstyt,firstzt=', firstxt, firstyt, firstzt
206    print, '    lastxt,lastyt,lastzt=', lastxt, lastyt, lastzt
207    print, '    zinvar=', zinvar
208    print, '     jpt=', jpt
209    print, '     key_shift=', key_shift
210    print, '     After read_ncdf, key_yreverse=',key_yreverse
211    print, '     help, lec_data='
212    help, lec_data
213    print, '     '
214   ENDIF
215
216; Average data along vertical if needed and update some features
217; needed for plt (data_direc, name_suff)
218   
219; if ensemble, no mean done here for now (read_ncdf does not handle ensembles yet)
220; see data_read for mean and model/ensemble extraction
221   IF ensbl_code NE '' THEN BEGIN
222      no_mean = 1
223   ENDIF
224
225   name_suff = ''
226   data_direc = ''
227   update_data, TAB = lec_data, VNAME = var_name, BOXZOOM = boxzoom, ZUNITS = units_depth, $
228    ZINVAR = zinvar, SUFFIX = name_suff, D_DIREC = data_direc, $
229    TIME_1 = time_1, TIME_2 = time_2, NO_MEAN = no_mean
230   field_dim = (size(lec_data))[0]
231
232; Field attributes
233   field = {name: '', data: lec_data, legend: '', units: '', origin: '', dim: 0, direc: data_direc}
234   field.name = var_name
235   field.origin = directory+file_name
236   field.legend = long_name+name_suff
237   field.units = units
238   field.dim = field_dim
239
240; replace NaN with valmask
241;   idx_t = where (~finite(field.data))
242;   IF idx_t[0] NE -1 THEN BEGIN
243;    field.data(idx_t) = valmask
244;   ENDIF
245
246; get valmask (might need valmask = float(string(valmask))
247   valmask = 1.e20
248   IF size(missing_value, /TYPE) EQ 4 OR size(missing_value, /TYPE) EQ 5 THEN BEGIN
249      valmask = missing_value
250      ; ensure valmask is positive
251      IF valmask LT 0 THEN BEGIN
252         print, '      *** Warning valmask is negative - changing sign: ', valmask
253         idx_t = where (field.data EQ valmask)
254         IF idx_t[0] NE -1 THEN BEGIN
255          field.data[idx_t] = -valmask
256         ENDIF
257         valmask = -valmask
258         idx_t=0                ; free memory
259      ENDIF
260   ENDIF
261
262   IF debug_w THEN BEGIN
263    print, '     valmask=',valmask
264   ENDIF
265
266; if pseudo 3d mask, read mask file and set masked points to valmask
267; still to do
268
269; min/max
270
271   chardim = ' - dim = '
272   FOR i = 1, (size(field.data))[0] DO BEGIN
273      chardim = chardim+string((size(field.data))[i], format = '(I5)')
274   ENDFOR
275
276   idx_valmsk = (where (field.data EQ valmask))
277   idx_novalmsk = (where (field.data NE valmask))
278   minf = idx_valmsk[0] EQ -1 ? min(field.data) : min(field.data[idx_novalmsk])
279   maxf = idx_valmsk[0] EQ -1 ? max(field.data) : max(field.data[idx_novalmsk])
280
281   print, ' = ',field.legend, '    [min/max = ',minf , maxf,'  ', field.units,' - masked values = ',valmask, chardim, ']'
282
283   IF debug_w THEN BEGIN
284    info = report('leaving ...')
285   ENDIF
286
287   return, field
288
289END
Note: See TracBrowser for help on using the repository browser.