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

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

add x/ydimname and cleaning to solve ticket:61

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 11.4 KB
RevLine 
[150]1;+
2; @file_comments
[2]3;
[150]4;
5; @categories
6;
7;
8; @param NAMEFILE
9;
10;
[221]11; @keyword GRID {default='T'}{type=scalar string}
12; Used to specify on which grid type are located the data
[150]13;
14; @keyword _EXTRA
[221]15; Used to pass your keywords to isafile and ncdf_getaxis
[150]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;
[2]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
[69]49;       dont les noms sont 'x','lon...','xi_...' et 'y','lat...' ou
50;       'eta_...' ou bien en majuscule.
[2]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;
[69]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.
[2]70;
71;------------------------------------------------------------
[69]72FUNCTION scanfile, namefile, GRID = GRID, _extra = ex
[114]73;
74  compile_opt idl2, strictarrsubs
75;
[2]76@common
77;------------------------------------------------------------
[69]78; filename
[2]79;------------------------------------------------------------
[69]80  fullname = isafile(filename = namefile, IODIRECTORY = iodir, _extra = ex)
[221]81  IF size(fullname, /type) NE 7 THEN return, -1
[2]82;------------------------------------------------------------
[69]83; open file
[2]84;------------------------------------------------------------
[69]85  cdfid = ncdf_open(fullname)
[2]86;------------------------------------------------------------
[69]87; What contains the file?
[2]88;------------------------------------------------------------
[221]89  inside = ncdf_inquire(cdfid)  ;
[2]90;------------------------------------------------------------
[69]91; name of all dimensions
[2]92;------------------------------------------------------------
[221]93  namedim = strarr(inside.ndims)
94  for dimiq = 0, inside.ndims-1 do begin
[69]95    ncdf_diminq, cdfid, dimiq, tmpname, value
96    namedim[dimiq] = strlowcase(tmpname)
[49]97  ENDFOR
[69]98;------------------------------------------------------------
[221]99; x/y dimensions id
100;------------------------------------------------------------
101  ncdf_getaxis, cdfid, dimidx, dimidy, _extra = ex
102;------------------------------------------------------------
[69]103; name of all variables
104;------------------------------------------------------------
105; we keep only the variables containing at least x, y and time dimension (if existing...)
[221]106  namevar = strarr(inside.nvars)
107  for varid = 0, inside.nvars-1 do begin
[69]108    invar = ncdf_varinq(cdfid, varid) ; what contains the variable?
[172]109    if (inter(invar.dim, dimidx))[0] NE -1 AND $
110       (inter(invar.dim, dimidy))[0] NE -1 AND $
[221]111       ((where(invar.dim EQ inside.recdim))[0] NE -1 OR inside.recdim EQ -1) $
[69]112    THEN namevar[varid] = invar.name
[49]113  ENDFOR
114  namevar = namevar[where(namevar NE '')]
[2]115;------------------------------------------------------------
[172]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;------------------------------------------------------------
[69]158; time axis
[2]159;------------------------------------------------------------
[69]160  date0fk = date2jul(19000101)
[221]161  IF inside.recdim EQ -1 THEN BEGIN
[69]162    jpt = 1
163    time = date0fk
164    fakecal = 1
165  ENDIF ELSE BEGIN
[221]166    ncdf_diminq, cdfid, inside.recdim, timedimname, jpt
[69]167; we look for the variable containing the time axis
[221]168; we look for the first variable having for only dimension inside.recdim
[69]169    varid = 0
170    repeat BEGIN
[221]171      IF varid LT inside.nvars THEN BEGIN
[167]172        invar = ncdf_varinq(cdfid, varid)
173        varid = varid+1       
174      ENDIF ELSE varid = 0
[221]175    endrep until (n_elements(invar.dim) EQ 1 AND invar.dim[0] EQ inside.recdim) OR (varid EQ 0)
[69]176    varid = varid-1
[49]177;
[69]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
[181]182        time = date0fk + lindgen(1>jpt)
[69]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
[181]187        time = date0fk + lindgen(1>jpt)
[69]188      END
189      ELSE:BEGIN
[49]190;
[69]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
[167]196          dummy = report('Attribut ''units'' not found for the variable '+invar.name+'!C we create a fake calendar ...')
[69]197          fakecal = 1
[181]198          time = date0fk + lindgen(1>jpt)
[69]199        ENDIF ELSE BEGIN
[150]200; we read the time axis
[69]201          ncdf_varget, cdfid, varid, time
202          time = double(time)
203          ncdf_attget, cdfid, varid, 'units', value
[2]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" ;
[69]209          value = strtrim(strcompress(string(value)), 2)
210          mots = str_sep(value, ' ')
211          unite = mots[0]
[198]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)
[172]215          err = 0
[198]216          IF unite NE 'second' AND unite NE 'hour' AND unite NE 'day' $
217             AND unite NE 'month' AND unite NE 'year' THEN BEGIN
[172]218            dummy = report('time units does not start with seconds/hours/days/months/years')
219            err = 1
220          ENDIF
[199]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}.*')
[198]223            err = 1
224          ENDIF
[172]225          IF err GT 0 THEN BEGIN
226            fakecal = 1
[181]227            time = date0fk + lindgen(1>jpt)
[172]228          ENDIF ELSE BEGIN
229            debut = str_sep(mots[2], '-')
[2]230;
[49]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
[2]234;
[172]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
[49]243;            notused = report('Unknown calendar: '+value+', we use greg calendar.')
[172]244                  key_caltype = 'greg'
245                END
246              ENDCASE
247            ENDIF ELSE BEGIN
[49]248;        notused = report('Unknown calendar, we use '+key_caltype+' calendar.')
[172]249              IF n_elements(key_caltype) EQ 0 THEN key_caltype = 'greg'
250            ENDELSE
[49]251;
[167]252; BEWARE we have to get back the calendar attribute and ajust time by consequence...
[2]253;
254;
[167]255; We pass time in IDL julian days
[2]256;
[172]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
[69]274;
275; high frequency calendar: more than one element per day
[172]276            IF max(histogram([long(time-time[0])])) GT 1 THEN fakecal = 1 ELSE fakecal = 0
277            date0fk = date2jul(19000101)
[181]278            IF keyword_set(fakecal) THEN time = date0fk+lindgen(1>jpt) $
[172]279            ELSE time = long(time)
[69]280;
[172]281          ENDELSE
[69]282        ENDELSE
283      END
284    ENDCASE
285  ENDELSE
[2]286;------------------------------------------------------------
[69]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}
[2]292end
Note: See TracBrowser for help on using the repository browser.