;+
;
; @file_comments
; lit les fichiers Vairmer en sort:
; un tableau 2d ou 3d en fonction de nomchamp qui est le nom
; du champ a extraire (2d s'il commence par SO et 3d s'il commence par VO)
; cette fonction modifie aussi les variables globales:
; varname: trois lettres: nom de l'experience
; vargrid: nom de la grille
; vardate: date (yy)yymmdd
; varexp: nom Vairmer du champ a tracer
;
; @obsolete
;
; @categories
; Graphics, Reading
;
; @examples
; IDL> resultat=lec('nom_Vairmer'[,date[,'nom_experience']])
;
; @param nomchamp {in}{required}
; 2 choix possibles:
; 1) nom de champ Vairmer (chaine de 8 caracteres en majuscule ou
; minuscule commencant par vo ou so). Dans cette methode on saute directement
; d'en-tete en en-tete jusqu'a trouver le bon fichier.
; 2) chaine de caracteres commencant par vo ou so suivit du
; numero de champ a aller chercher (par ex 'vo5'). Cette methode est un peu
; plus rapide car elle va directement chercher le fichier qui nous interesse.
;
; @param date {in}{optional}
; nombres de 6 ou 8 chiffres (anneemoisjour, par ex:19980507)
;
; @param nomexp {in}{optional}
; trois lettres designant le nom de l'experience
;
;
; @keyword ANOM {in}
; type du fichier vairmer par rapport auquel on doit calculer
; l'anomalie ('EX','AN','SE','MO','')
;
; @keyword ECRIT {in}
; permet d'imprimer tous les noms vairmer que contient le fichier.
; ds ce cas en input on met seulement 'vo' ou 'so' la fonction retourne le
; nombre de fichiers lus.
;
; @keyword BOITE
;
; @keyword EXPANOM {in}
; si on calcule l'anom par rapport a une exper differente
;
; @keyword FILENAME
; string pour passer directement le nom du champ sans
; utiliser les inputs: nom_Vairmer',date,'nom_experience'. Rq si
; ces inputs sont qd meme donnes ils ne sont pas modifies par
; filename.
;
; @keyword GRID
; lorsque ce mot clef est active, lec retourne la liste
; des types de grilles (T, U...) auxquelles se rapportent les
; variables. ds ce cas en input on met seulement 'vo' ou 'so'.
;
; @keyword NAME
; lorsque ce mot clef est active, lec retourne la liste
; des noms des variables. ds ce cas en input on met seulement
; 'vo' ou 'so'.
;
; @keyword TOUT
; oblige lec a lire le champ sur tout le domaine qui a
; etait selectionne pour la cession en cours (jpi,jpj,jpk)
;
; @returns
; un tableau 2 ou 3d. sans le mot cle /TOUT, sa taille est
; celle du sous domaine definit par domdef(nx,ny,nz). avec /TOUT le
; champ a la taille du domaine qui a etait selectionne pour la
; cession en cours (jpi,jpj,jpk).
; pour les sous domaines cf:
;
; Retourne -1 en cas d'erreur.
;
; @uses
; common.pro
; isnumber.pro
; fivardate.pro
;
; @history
; Sebastien Masson (smasson\@lodyc.jussieu.fr)
; 26/5/98
; Jerome Vialard : adaptation au format vairmer
; keyword anom et expanom
; 1/7/98
; Sebastien Masson (masque des terres)
; 14/8/98
; Sebastien Masson (decoupe pour les sous domaines...)
; 2/99
;
; @version
; $Id$
;
;-
FUNCTION lec, nomchamp,date,nomexp $
, ECRIT=ecrit, ANOM=anom, BOITE=boite, EXPANOM=expanom $
, TOUT=tout, GRID=grid, NAME=name, filename=FILENAME
;
compile_opt idl2, strictarrsubs, obsolete
;
@common
tempsun = systime(1) ; pour key_performance
z = -1
;
if keyword_set(filename) then BEGIN
CASE strupcase(strmid(!version.os_family, 0, 3)) of
'MAC':sep = ':'
'WIN':sep = '\'
ELSE:sep = '/'
ENDCASE
fname = strmid(filename, rstrpos(filename, sep)+1)
if n_elements(nomchamp) EQ 0 then nomchamp = strmid(fname,6, 2)
if n_elements(date) EQ 0 then date = long(strmid(fname,8))
if n_elements(nomexp) EQ 0 then nomexp = strmid(fname,0, 3)
endif
;
nomchamp=strupcase(nomchamp)
dim=string(format='(a2)',nomchamp)
;print, 'nom de l''experience: ',nomchamp
;------------------------------------------------------------
; specification de la date et de l'experience
;------------------------------------------------------------
case n_params() OF
0:BEGIN
if keyword_set(filename) then begin
rien=juldate(date)
prefix=nomexp
ENDIF ELSE return, report('Donnez un argument en entree ou utilisez le mot clef FILENAME')
END
1:date=long(day)+long(month)*100+long(year)*10000
2:rien=juldate(date)
3:begin
rien=juldate(date)
prefix=nomexp
end
endcase
;------------------------------------------------------------
; verification de la dim du fichier
;------------------------------------------------------------
if dim ne 'SO' and dim ne 'VO' then return, report('le nom du champ doit commencer par VO ou SO')
;------------------------------------------------------------
; constitution de l'adresse ou aller chercher le fichier
;--------------------------------------------------------------
s_fichier=ficdate(date,dim)
;--------------------------------------------------------------------
; ouverture du fichier a l'adresse s_fichier
;--------------------------------------------------------------------
openr, numlec, s_fichier, /get_lun,ERROR=err, /swap_if_little_endian
if err ne 0 then begin
; print,!err_string
return, -1
endif
;taille en octet du fichier
infofichier=fstat(numlec)
;---------------------------------------------------------------------
; definition de la taille du fichier a aller chercher: jpidta,jpjdta,jpkdta...
;---------------------------------------------------------------------
if n_elements(jpidta) EQ 0 THEN BEGIN
if n_elements(ixmindta) EQ 0 OR n_elements(ixmaxdta) EQ 0 then $
jpidta = jpiglo else jpidta = ixmaxdta-ixmindta+1
endif
if n_elements(jpjdta) EQ 0 THEN BEGIN
if n_elements(iymindta) EQ 0 OR n_elements(iymaxdta) EQ 0 then $
jpjdta = jpjglo else jpjdta = iymaxdta-iymindta+1
endif
if n_elements(jpkdta) EQ 0 THEN BEGIN
if n_elements(izmindta) EQ 0 OR n_elements(izmaxdta) EQ 0 then $
jpkdta = jpkglo else jpkdta = izmaxdta-izmindta+1
endif
;---------------------------------------------------------------------
; lecture des champs directement vers le champ ou l'en-tete que l'on recherche
; il faut savoir que:
; le fortran ajoute au debut et a la fin de chaque write 4 octets de controle
; les reels du model sont codes sur 4 octets
; un caractere fait 1 octet
;-----------------------------------------------------------------------
;4 chaines de 8 caracteres+un tableau de reels+4 trucs de controle (pour les
; 2 write):
if dim eq 'VO' then $
taillebloc=4*8+long(jpidta)*jpjdta*jpkdta*4+4*4 else $
taillebloc=4*8+long(jpidta)*jpjdta*4+4*4
;---------------------------------------------------------------------
; choix du type de lecture
;---------------------------------------------------------------------
typelec=strmid(nomchamp,2,strlen(nomchamp))
test=isnumber(typelec,numerochamp)
if test eq 0 then begin
;--------------------------------------------------------------------
; 1) LECTURE DIRECTE D'EN-TETE en EN-TETE
;--------------------------------------------------------------------
numerochamp=1
;---------------------------------------------------------------------
; lecture des noms de champ
;---------------------------------------------------------------------
resname = ''
resgrid = ''
while numerochamp*taillebloc le infofichier.size do begin
offset=(numerochamp-1)*taillebloc+4
a=assoc(numlec,bytarr(8,/nozero), offset)
varname=string(a[0])
if keyword_set(ecrit) OR keyword_set(name) OR keyword_set(grid) $
then begin
vargrid=a[1]
vargrid=string(vargrid[7])
vardate=strtrim(long(string(a[2])), 2)
varexp=strtrim(a[3], 2)
if keyword_set(ecrit) THEN $
print, numerochamp,' ',varname,' ',vargrid,' ',vardate,' ',varexp
resname = [resname, varname]
resgrid = [resgrid, vargrid]
endif
if nomchamp eq varname then begin
vargrid=a[1]
vargrid=string(vargrid[7])
vardate=strtrim(long(string(a[2])), 2)
varexp=strtrim(a[3], 2)
goto,sortieboucle
endif
numerochamp=numerochamp+1
ENDWHILE
free_lun,numlec
close, numlec
case 1 of
keyword_set(ecrit):return, numerochamp-1
keyword_set(name):return, resname[1:numerochamp-1]
keyword_set(grid):$
return, strmid(resgrid[1:numerochamp-1],0 > (strlen(resgrid[0])-2))
ELSE:return, report('Ce nom Vairmer de champ n''existe pas ds le fichier: '+infofichier.name)
endcase
endif else begin
;----------------------------------------------------------------------
; 2) LECTURE DIRECTEMENT DU CHAMP QUE L'ON VEUT
;---------------------------------------------------------------------
;---------------------------------------------------------------------
; test pour savoir si numero de champ est accessible
;---------------------------------------------------------------------
if taillebloc*numerochamp gt infofichier.size then $
return, report('Ce numero de champ n''existe pas. Le fichier '+infofichier.name+' ne contient que ',infofichier.size/taillebloc,' champs.')
;---------------------------------------------------------------------
; lecture de l'en-tete numero numerochamp
;---------------------------------------------------------------------
offset=(numerochamp-1)*taillebloc+4
a=assoc(numlec,bytarr(8,/nozero), offset)
varname=string(a[0])
vargrid=a[1]
vargrid=string(vargrid[7])
vardate=string(a[2])
varexp=string(a[3])
endelse
sortieboucle:
;---------------------------------------------------------------------
; lecture du champ lui-meme
;---------------------------------------------------------------------
offset=(numerochamp-1)*taillebloc+(8+4*8)+4
if dim eq 'VO' then $
a=assoc(numlec,fltarr(jpidta,jpjdta,jpkdta,/nozero), offset) else $
a=assoc(numlec,fltarr(jpidta,jpjdta,/nozero), offset)
z=a[0]
;---------------------------------------------------------------------
; on initialise les ixmindta, iymindta au besoin
;---------------------------------------------------------------------
if n_elements(ixmindta) EQ 0 OR n_elements(ixmaxdta) EQ 0 then BEGIN
ixmindta = 0
ixmaxdta = jpidta-1
endif
if n_elements(iymindta) EQ 0 OR n_elements(iymaxdta) EQ 0 then BEGIN
iymindta = 0
iymaxdta = jpjdta-1
endif
if n_elements(izmin) EQ 0 OR n_elements(izmax) EQ 0 then BEGIN
izmindta = 0
izmaxdta = jpkdta-1
endif
;---------------------------------------------------------------------
; on reduit z selon les valeurs de ixmindta, iymindta, ...
;---------------------------------------------------------------------
if dim EQ 'SO' then z = z[ixminmesh-ixmindta:ixmaxmesh-ixmindta $
,iyminmesh-iymindta:iymaxmesh-iymindta] $
ELSE z = z[ixminmesh-ixmindta:ixmaxmesh-ixmindta $
, iyminmesh-iymindta:iymaxmesh-iymindta, izminmesh-izmindta:izmaxmesh-izmindta]
;---------------------------------------------------------------------
; on shift z si key_shift est defini
;---------------------------------------------------------------------
if n_elements(key_shift) NE 0 THEN BEGIN
if dim EQ 'SO' then z = shift(z,key_shift, 0) $
ELSE z = shift(z,key_shift, 0, 0)
endif
;---------------------------------------------------------------------
; si /TOUT n''est pas active, on coupe z pour qu''il soit a la taille
; du zoom: nx,ny nz
;---------------------------------------------------------------------
if NOT keyword_set(tout) then BEGIN
;-------------------------------------------------------------
; changement de domaine
;-------------------------------------------------------------
if keyword_set(boite) then BEGIN
Case 1 Of
N_Elements(Boite) Eq 1:bte=[lon1, lon2, lat1, lat2, 0.,boite[0]]
N_Elements(Boite) Eq 2:bte=[lon1, lon2, lat1, lat2, boite[0],boite[1]]
N_Elements(Boite) Eq 4:bte=[Boite, prof1, prof2]
N_Elements(Boite) Eq 5:bte=[Boite[0:3], 0, Boite[4]]
N_Elements(Boite) Eq 6:bte=Boite
Else: return, report('Mauvaise Definition de Boite')
endcase
oldboite = [lon1, lon2, lat1, lat2, prof1, prof2]
domdef, bte,GRILLE=vargrid
ENDIF
;-------------------------------------------------------------
grille,mask,glam,gphi,gdep,nx,ny,nz,premierx,premiery,premierz,dernierx,derniery,dernierz
if nx EQ 1 OR ny EQ 1 OR nz EQ 1 then mask = reform(mask, nx, ny, nz, /over)
if dim EQ 'SO' then z = z[premierx:dernierx, premiery:derniery] $
ELSE z = z[premierx:dernierx, premiery:derniery, premierz:dernierz]
ENDIF ELSE BEGIN
case vargrid OF ; on recupere le mask en entier ds le cas ou /TOUT
'U':mask = umask() ; n''est pas active et on le choisit en fonction
'T':mask = tmask ; de la valeur de vargrid
'W':mask = tmask
'V':mask = vmask()
'F':mask = fmask()
ENDCASE
ENDELSE
;---------------------------------------------------------------------
; calcul d'une anomalie si le keyword anom est active
;---------------------------------------------------------------------
if keyword_set(anom) then begin
case anom of
'EX' : adate = 0
'AN' : adate = floor(date/10000)*10000
'SE' : adate = floor(date - floor(date/10000)*10000)/100 * 100
'MO' : adate = floor(date/100)*100
'DA' : adate = date - floor(date/10000)*10000
'' : adate = date - floor(date/10000)*10000
else : return, report('Anom doit etre egal a EX,AN,SE,MO,DA ')
endcase
if keyword_set(expanom) then nomexpa = expanom $
else nomexpa = nomexp
if keyword_set(bavard) THEN print, nomchamp,' - ',adate,' - ',nomexpa
z = z - lec(nomchamp,adate,nomexpa, TOUT = tout)
endif
;---------------------------------------------------------------------
; on masque les terres par valmask
;---------------------------------------------------------------------
IF n_elements(valmask) EQ 0 THEN valmask = 1e20
if dim EQ 'SO' then BEGIN
terre = where(mask[*,*,0] EQ 0)
if terre[0] NE -1 then z[terre] = valmask
ENDIF ELSE BEGIN
terre = where(mask[*,*,0] EQ 0)
if terre[0] NE -1 then z[where(mask EQ 0)] = valmask
ENDELSE
;---------------------------------------------------------------------
free_lun,numlec
close, numlec
;---------------------------------------------------------------------
if n_elements(oldboite) NE 0 then domdef, oldboite
IF keyword_set(key_performance) EQ 1 THEN print, 'temps lec', systime(1)-tempsun
;
return,reform(z)
end