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

Last change on this file since 238 was 238, checked in by pinsard, 17 years ago

improvements/corrections of some *.pro headers

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