; ; liste des presupposes: ; 1) le fichier a lire est un fichier netcdf ; 2) le nom de ce fichier finit ; par U.nc, V.nc, W.nc, T.nc ou F.nc, la lettre avant le ; nc designant la grille a laquelle se rapporte la champ. ; Si tel n''est pas la cas, le fichier est attribue a la grille ; T. ; 3) ce fichier contient une dimension infinie qui doit etre ; celle qui se rapporte au temps et au mois 2 autres dimensions ; dont les noms sont 'x','lon','longitude' et 'y','lat' ou ; 'latitude' ou bien en majuscule. ; 4) il doit exiter ds ce fichier une unique variable n''ayant ; qu''une dimension et etant la dimension temporelle. cette ; variable sera prise comme axe des temps. Rq: si plusieurs ; variables verifient ces criteres on considere la premiere ; variable ; 5) Cette variable axe des temps doit contenir l''attribut ; 'units'qui doit etre ecrit suivant la syntaxe: ; "seconds since 0001-01-01 00:00:00" ; "hours since 0001-01-01 00:00:00" ; "days since 1979-01-01 00:59:59" ; "months since 1979-01-01 00:59:59" ; "years since 1979-01-01 00:59:59" ; ; je crois que c''est tout! ; ; ;------------------------------------------------------------ FUNCTION scanfile, nomficher, _extra = ex @common ;------------------------------------------------------------ ; bidouille pour utiliser les mots cles (on passe par des variables ; declarees ds un common) ;------------------------------------------------------------ res = -1 ;------------------------------------------------------------ ; choix du nom du fichier ;------------------------------------------------------------ nom = isafile(filename = nomficher, IODIRECTORY = iodir, _extra = ex) ;------------------------------------------------------------ ; ouverture du fichier nom ;------------------------------------------------------------ cdfid = ncdf_open(nom) ;------------------------------------------------------------ ; que contient le fichier?? ;------------------------------------------------------------ contient = ncdf_inquire(cdfid); ; find vargrid ... vargrid = 'T' ; default definition pattern = ['GRID.', 'GRID_', 'GRID', 'UPID_', '30ID_'] gdtype = ['T', 'U', 'V', 'W', 'F'] fnametest = strupcase(nom) FOR i = 0, n_elements(pattern)-1 DO BEGIN FOR j = 0, n_elements(gdtype)-1 DO BEGIN substr = pattern[i]+gdtype[j] pos = strpos(fnametest, substr) IF pos NE -1 THEN $ vargrid = strmid(fnametest, pos+strlen(substr)-1, 1) ENDFOR ENDFOR ;------------------------------------------------------------ ; nom des differentes variables ;------------------------------------------------------------ ; on ne garde les noms de variable uniquement si cette variable ; contient au moins les dimensions qui doivent etre appelles x et y ; et la dimension infinie nomdim = strarr(contient.ndims) for dimiq = 0, contient.ndims-1 do begin ncdf_diminq, cdfid, dimiq, name, value ; nom et valeur de la dimension nomdim[dimiq] = strlowcase(name) ENDFOR indexdimx = where(nomdim EQ 'x' OR nomdim EQ 'lon' OR nomdim EQ 'longitude' OR nomdim EQ 'xt_i7_156' OR nomdim EQ 'xi_rho' OR nomdim EQ 'xi_u' OR nomdim EQ 'xi_v' OR nomdim EQ 'xi_psi') indexdimx = indexdimx[0] if indexdimx EQ -1 then begin print, 'one of the dimensions must have the name: ''x'' or ''lon'' or ''longitude'' or ''xt_i7_156''' stop endif indexdimy = where(nomdim EQ 'y' OR nomdim EQ 'lat' OR nomdim EQ 'latitude' OR nomdim EQ 'yt_j6_75' OR nomdim EQ 'eta_rho' OR nomdim EQ 'eta_u' OR nomdim EQ 'eta_v' OR nomdim EQ 'eta_psi') indexdimy = indexdimy[0] if indexdimy EQ -1 then begin print, 'one of the dimensions must have the name: ''y'' or ''lat'' or ''latitude'' or ''yt_j6_75''' stop endif ; namevar = strarr(contient.nvars) for varid = 0, contient.nvars-1 do begin varcontient = ncdf_varinq(cdfid, varid) ; que contient la variable if (where(varcontient.dim EQ indexdimx))[0] NE -1 AND $ (where(varcontient.dim EQ indexdimy))[0] NE -1 AND $ (where(varcontient.dim EQ contient.recdim))[0] NE -1 THEN namevar[varid] = varcontient.name ENDFOR namevar = namevar[where(namevar NE '')] listgrid = replicate(vargrid, n_elements(namevar)) ;------------------------------------------------------------ ; on recupere l''axe des temps ;------------------------------------------------------------ ; on recupere le nom de la variable contenant l''axe des temps varid = 0 repeat BEGIN ; tant que l''on a pas trouve une variable qui n''a qu'' ; une dimension: la dimension infinie varcontient = ncdf_varinq(cdfid, varid) ; que contient la variable varid = varid+1 endrep until n_elements(varcontient.dim) EQ 1 AND varcontient.dim[0] EQ contient.recdim ; varid = varid-1 ; ; we want to know which attrributes are attached to the time variable... ; if varcontient.natts EQ 0 then BEGIN ncdf_close, cdfid return, report('the variable '+varcontient.name+' has no attribut.!C we need attribut ''units'' for the calendar ...') endif attnames = strarr(varcontient.natts) for attiq = 0, varcontient.natts-1 do attnames[attiq] = ncdf_attname(cdfid, varid, attiq) if (where(attnames EQ 'units'))[0] EQ -1 then BEGIN ncdf_close, cdfid return, report('Attribut ''units'' not found for the variable '+varid.name+'we need it for the calendar...') endif ; on lit l''axe des temps ncdf_varget, cdfid, varid, time time = double(time) ncdf_attget, cdfid, varid, 'units', value ; time_counter:units = "seconds since 0001-01-01 00:00:00" ; ; time_counter:units = "hours since 0001-01-01 00:00:00" ; ; time_counter:units = "days since 1979-01-01 00:00:00" ; ; time_counter:units = "months since 1979-01-01 00:00:00" ; ; time_counter:units = "years since 1979-01-01 00:00:00" ; value = strtrim(strcompress(string(value)), 2) mots = str_sep(value, ' ') unite = mots[0] debut = str_sep(mots[2], '-') ; ; now we try to find the attribut called calendar... ; the the attribute "calendar" exists? ; If no, we suppose that the calendar is gregorian calendar ; if (where(attnames EQ 'calendar'))[0] NE -1 then BEGIN ncdf_attget, cdfid, varid, 'calendar', value value = string(value) CASE value OF '360d':key_caltype = '360d' 'greg':IF n_elements(key_caltype) EQ 0 THEN key_caltype = 'greg' ELSE:BEGIN ; notused = report('Unknown calendar: '+value+', we use greg calendar.') key_caltype = 'greg' END ENDCASE ENDIF ELSE BEGIN ; notused = report('Unknown calendar, we use '+key_caltype+' calendar.') IF n_elements(key_caltype) EQ 0 THEN key_caltype = 'greg' ENDELSE ; ; ATTENTION il faut recuperer l''attribut calendar et ajuster time en ; consequense... ; ; ; on passe time en jour julien d''idl ; on suppose qu''on utilise le vrai calendrier. ; unite = strlowcase(unite) IF strpos(unite, 's', strlen(unite)-1) NE -1 THEN unite = strmid(unite, 0, strlen(unite)-1) IF strpos(unite, 'julian_') NE -1 THEN unite = strmid(unite, 7) case unite of 'second':time = julday(debut[1], debut[2], debut[0])+time/(long(24)*3600) 'hour':time = julday(debut[1], debut[2], debut[0])+time/(long(24)) 'day':time = julday(debut[1], debut[2], debut[0])+time 'month':BEGIN if total(fix(time) NE time) NE 0 then $ ; we switch to days with 30d/m time = julday(debut[1], debut[2], debut[0])+round(time*30) $ ELSE for t = 0, n_elements(time)-1 DO $ time[t] = julday(debut[1]+time[t], debut[2], debut[0]) END 'year':BEGIN if total(fix(time) NE time) NE 0 then $ ; we switch to days with 365d/y time = julday(debut[1], debut[2], debut[0])+round(time*365) $ ELSE for t = 0, n_elements(time)-1 do $ time[t] = julday(debut[1], debut[2], debut[0]+time[t]) END ENDCASE time = long(time) ;------------------------------------------------------------ return, {filename:nom, time_counter:time, listvar:namevar, listgrid:strupcase(listgrid), calendartype:key_caltype} end