source: trunk/SRC/ToBeReviewed/WIDGET/AUTOUR_de_XXX/scanfile.pro @ 218

Last change on this file since 218 was 218, checked in by smasson, 17 years ago

add gv and ggv in ps viewers list

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 11.4 KB
Line 
1;+
2; @file_comments
3;
4;
5; @categories
6;
7;
8; @param NAMEFILE
9;
10;
11; @keyword GRID {default='T'}{type=scalar string}
12; Used to specify on which grid type are located the data
13;
14; @keyword _EXTRA
15; Used to pass your keywords to isafile and ncdf_getaxis
16;
17; @returns
18;
19;
20; @uses
21;
22;
23; @restrictions
24;
25;
26; @examples
27;
28;
29; @history
30;
31;
32; @version
33; $Id$
34;
35; @todo
36; seb : I don't know what to do with that...
37;
38;-
39;
40;  liste des presupposes:
41;       1) le fichier a lire est un fichier netcdf
42;       2) le nom de ce fichier finit
43;       par U.nc, V.nc, W.nc, T.nc ou F.nc, la lettre avant le
44;       nc designant la grille a laquelle se rapporte la champ.
45;       Si tel n''est pas la cas, le fichier est attribue a la grille
46;       T.
47;       3) ce fichier contient une dimension infinie qui doit etre
48;       celle qui se rapporte au temps et au mois 2 autres dimensions
49;       dont les noms sont 'x','lon...','xi_...' et 'y','lat...' ou
50;       'eta_...' ou bien en majuscule.
51;       4) il doit exiter ds ce fichier une unique variable n''ayant
52;       qu''une dimension et etant la dimension temporelle. cette
53;       variable sera prise comme axe des temps. Rq: si plusieurs
54;       variables verifient ces criteres on considere la premiere
55;       variable
56;       5) Cette variable axe des temps doit contenir l''attribut
57;       'units'qui doit etre ecrit suivant la syntaxe:
58;               "seconds since 0001-01-01 00:00:00"
59;               "hours since 0001-01-01 00:00:00"
60;               "days since 1979-01-01 00:59:59"
61;               "months since 1979-01-01 00:59:59"
62;               "years since 1979-01-01 00:59:59"
63;
64; je crois que c''est tout!
65;
66;        GRID='[UTVWF]' to specify the type of grid. Defaut is (1)
67;        based on the name of the file if the file ends by
68;        GRID[._][TUVFW].NC (not case sensible) or (2) T if case (1)
69;        is not found.
70;
71;------------------------------------------------------------
72FUNCTION scanfile, namefile, GRID = GRID, _extra = ex
73;
74  compile_opt idl2, strictarrsubs
75;
76@common
77;------------------------------------------------------------
78; filename
79;------------------------------------------------------------
80  fullname = isafile(filename = namefile, IODIRECTORY = iodir, _extra = ex)
81  IF size(fullname, /type) NE 7 THEN return, -1
82;------------------------------------------------------------
83; open file
84;------------------------------------------------------------
85  cdfid = ncdf_open(fullname)
86;------------------------------------------------------------
87; What contains the file?
88;------------------------------------------------------------
89  inside = ncdf_inquire(cdfid)  ;
90;------------------------------------------------------------
91; name of all dimensions
92;------------------------------------------------------------
93  namedim = strarr(inside.ndims)
94  for dimiq = 0, inside.ndims-1 do begin
95    ncdf_diminq, cdfid, dimiq, tmpname, value
96    namedim[dimiq] = strlowcase(tmpname)
97  ENDFOR
98;------------------------------------------------------------
99; x/y dimensions id
100;------------------------------------------------------------
101  ncdf_getaxis, cdfid, dimidx, dimidy, _extra = ex
102;------------------------------------------------------------
103; name of all variables
104;------------------------------------------------------------
105; we keep only the variables containing at least x, y and time dimension (if existing...)
106  namevar = strarr(inside.nvars)
107  for varid = 0, inside.nvars-1 do begin
108    invar = ncdf_varinq(cdfid, varid) ; what contains the variable?
109    if (inter(invar.dim, dimidx))[0] NE -1 AND $
110       (inter(invar.dim, dimidy))[0] NE -1 AND $
111       ((where(invar.dim EQ inside.recdim))[0] NE -1 OR inside.recdim EQ -1) $
112    THEN namevar[varid] = invar.name
113  ENDFOR
114  namevar = namevar[where(namevar NE '')]
115;------------------------------------------------------------
116; find vargrid for each selected variable...
117;------------------------------------------------------------
118  listgrid = strarr(n_elements(namevar))
119; default definitions
120  IF keyword_set(grid) THEN vargrid = strupcase(grid) ELSE vargrid = 'T'
121; look for values of vargrid for each variable
122  IF finite(glamu[0]) EQ 1 AND NOT keyword_set(grid) THEN BEGIN
123; for each variable, look if we in one of the case corresponding to ROMS conventions?
124    FOR i = 0, n_elements(namevar)-1 do begin
125      invar = ncdf_varinq(cdfid, namevar[i])
126      tmpnm = namedim[invar.dim]
127; are we in one of the case corresponding to ROMS conventions?
128      CASE 1 OF
129        tmpnm[2 <(invar.ndims-1)] EQ 's_w':vargrid = 'W'
130        tmpnm[0] EQ 'xi_rho' AND tmpnm[1] EQ 'eta_rho':listgrid[i] = 'T'
131        tmpnm[0] EQ 'xi_u'   AND tmpnm[1] EQ 'eta_u'  :listgrid[i] = 'U'
132        tmpnm[0] EQ 'xi_v'   AND tmpnm[1] EQ 'eta_v'  :listgrid[i] = 'V'
133        tmpnm[0] EQ 'xi_psi' AND tmpnm[1] EQ 'eta_psi':listgrid[i] = 'F'
134        tmpnm[0] EQ 'xi_rho' AND tmpnm[1] EQ 'eta_v'  :listgrid[i] = 'V'
135        tmpnm[0] EQ 'xi_u'   AND tmpnm[1] EQ 'eta_rho':listgrid[i] = 'U'
136        tmpnm[0] EQ 'xi_u'   AND tmpnm[1] EQ 'eta_v'  :listgrid[i] = 'F'
137        ELSE:
138      ENDCASE
139    ENDFOR
140    empty = where(listgrid EQ '')
141    IF empty[0] NE -1 THEN BEGIN   
142; could we define the grid type from the file name??
143      pattern = ['GRID.', 'GRID_', 'GRID', 'UPID_', '30ID_']
144      gdtype = ['T', 'U', 'V', 'W', 'F']
145      fnametest = strupcase(fullname)
146      FOR i = 0, n_elements(pattern)-1 DO BEGIN
147        FOR j = 0, n_elements(gdtype)-1 DO BEGIN
148          substr = pattern[i]+gdtype[j]
149          pos = strpos(fnametest, substr)
150          IF pos NE -1 THEN $
151             vargrid = strmid(fnametest, pos+strlen(substr)-1, 1)
152        ENDFOR
153      ENDFOR
154      listgrid[empty] = vargrid
155    ENDIF
156  ENDIF ELSE listgrid[*] = vargrid
157;------------------------------------------------------------
158; time axis
159;------------------------------------------------------------
160  date0fk = date2jul(19000101)
161  IF inside.recdim EQ -1 THEN BEGIN
162    jpt = 1
163    time = date0fk
164    fakecal = 1
165  ENDIF ELSE BEGIN
166    ncdf_diminq, cdfid, inside.recdim, timedimname, jpt
167; we look for the variable containing the time axis
168; we look for the first variable having for only dimension inside.recdim
169    varid = 0
170    repeat BEGIN
171      IF varid LT inside.nvars THEN BEGIN
172        invar = ncdf_varinq(cdfid, varid)
173        varid = varid+1       
174      ENDIF ELSE varid = 0
175    endrep until (n_elements(invar.dim) EQ 1 AND invar.dim[0] EQ inside.recdim) OR (varid EQ 0)
176    varid = varid-1
177;
178    CASE 1 OF
179      varid EQ -1:BEGIN
180        dummy = report('the file '+fullname+' has no time axis.!C we create a fake calendar ...')
181        fakecal = 1
182        time = date0fk + lindgen(1>jpt)
183      END
184      invar.natts EQ 0:BEGIN
185        dummy = report('the variable '+invar.name+' has no attribut.!C we create a fake calendar ...')
186        fakecal = 1
187        time = date0fk + lindgen(1>jpt)
188      END
189      ELSE:BEGIN
190;
191; we want to know which attributes are attached to the time variable...
192;
193        attnames = strarr(invar.natts)
194        for attiq = 0, invar.natts-1 do attnames[attiq] = ncdf_attname(cdfid, varid, attiq)
195        if (where(attnames EQ 'units'))[0] EQ -1 then BEGIN
196          dummy = report('Attribut ''units'' not found for the variable '+invar.name+'!C we create a fake calendar ...')
197          fakecal = 1
198          time = date0fk + lindgen(1>jpt)
199        ENDIF ELSE BEGIN
200; we read the time axis
201          ncdf_varget, cdfid, varid, time
202          time = double(time)
203          ncdf_attget, cdfid, varid, 'units', value
204; time_counter:units = "seconds since 0001-01-01 00:00:00" ;
205; time_counter:units = "hours since 0001-01-01 00:00:00" ;
206; time_counter:units = "days since 1979-01-01 00:00:00" ;
207; time_counter:units = "months since 1979-01-01 00:00:00" ;
208; time_counter:units = "years since 1979-01-01 00:00:00" ;
209          value = strtrim(strcompress(string(value)), 2)
210          mots = str_sep(value, ' ')
211          unite = mots[0]
212          unite = strlowcase(unite)
213          IF strpos(unite, 's', strlen(unite)-1) NE -1 THEN unite = strmid(unite, 0, strlen(unite)-1)
214          IF strpos(unite, 'julian_') NE -1 THEN unite = strmid(unite, 7)
215          err = 0
216          IF unite NE 'second' AND unite NE 'hour' AND unite NE 'day' $
217             AND unite NE 'month' AND unite NE 'year' THEN BEGIN
218            dummy = report('time units does not start with seconds/hours/days/months/years')
219            err = 1
220          ENDIF
221          IF stregex(value, '[^ ]* since ([0-9]){1,4}-([0-9]){1,2}-([0-9]){1,2}.*', /boolean) EQ 0 THEN BEGIN
222            dummy = report('attribut units of time has not the good format: [^ ]* since ([0-9]){1,4}-([0-9]){1,2}-([0-9]){1,2}.*')
223            err = 1
224          ENDIF
225          IF err GT 0 THEN BEGIN
226            fakecal = 1
227            time = date0fk + lindgen(1>jpt)
228          ENDIF ELSE BEGIN
229            debut = str_sep(mots[2], '-')
230;
231; now we try to find the attribut called calendar...
232; the the attribute "calendar" exists?
233; If no, we suppose that the calendar is gregorian calendar
234;
235            if (where(attnames EQ 'calendar'))[0] NE -1 then BEGIN
236              ncdf_attget, cdfid, varid, 'calendar', value
237              value = string(value)
238              CASE value OF
239                'noleap':key_caltype = 'noleap'
240                '360d':key_caltype = '360d'
241                'greg':IF n_elements(key_caltype) EQ 0 THEN key_caltype = 'greg'
242                ELSE:BEGIN
243;            notused = report('Unknown calendar: '+value+', we use greg calendar.')
244                  key_caltype = 'greg'
245                END
246              ENDCASE
247            ENDIF ELSE BEGIN
248;        notused = report('Unknown calendar, we use '+key_caltype+' calendar.')
249              IF n_elements(key_caltype) EQ 0 THEN key_caltype = 'greg'
250            ENDELSE
251;
252; BEWARE we have to get back the calendar attribute and ajust time by consequence...
253;
254;
255; We pass time in IDL julian days
256;
257            case unite of
258              'second':time = julday(debut[1], debut[2], debut[0])+time/86400.d
259              'hour':time = julday(debut[1], debut[2], debut[0])+time/24.d
260              'day':time = julday(debut[1], debut[2], debut[0])+time
261              'month':BEGIN
262                if total(fix(time) NE time) NE 0 then $ ; we switch to days with 30d/m
263                   time = julday(debut[1], debut[2], debut[0])+round(time*30) $
264                ELSE for t = 0, n_elements(time)-1 DO $
265                   time[t] = julday(debut[1]+time[t], debut[2], debut[0])
266              END
267              'year':BEGIN
268                if total(fix(time) NE time) NE 0 then $ ; we switch to days with 365d/y
269                   time = julday(debut[1], debut[2], debut[0])+round(time*365) $
270                ELSE for t = 0, n_elements(time)-1 do $
271                   time[t] = julday(debut[1], debut[2], debut[0]+time[t])
272              END
273            ENDCASE
274;
275; high frequency calendar: more than one element per day
276            IF max(histogram([long(time-time[0])])) GT 1 THEN fakecal = 1 ELSE fakecal = 0
277            date0fk = date2jul(19000101)
278            IF keyword_set(fakecal) THEN time = date0fk+lindgen(1>jpt) $
279            ELSE time = long(time)
280;
281          ENDELSE
282        ENDELSE
283      END
284    ENDCASE
285  ENDELSE
286;------------------------------------------------------------
287  ncdf_close, cdfid
288;------------------------------------------------------------
289  return, {filename:fullname, time_counter:time, listvar:namevar $
290           , listgrid:strupcase(listgrid), caltype:key_caltype $
291           , fakecal:date0fk*fakecal}
292end
Note: See TracBrowser for help on using the repository browser.