PRO CMP_POL_MOD FORWARD_FUNCTION GETHDFPAR, GETPOLPATH, GETMODPATH, getReflectance, SEARCHPATH, histo2D COMMON COMDIRS, CFGFIL, DIRSEP, RACDIR, CPMBAS, CPMFIL, CPMNAM, POLBAS, POLNAM, POLFIL, $ MODBAS, MODPRD, MODNAM, MODFIL, FHCPM, SDCPM, MGIDS, MGNAMES, MGORDER, $ MODLAL, MODLOL, OW, psats, Ploneq, deroulWdth COMMON INITS, InitExec Initialisations InitExec = 0 CMP_POL_MOD_GUI END FUNCTION Comparer, grModis, tchannel, toldir, minDyn, maxDyn, msg, widbase COMMON COMDIRS PrintStep, widbase, 'Recherche des fichiers' DeroulId = WIDGET_INFO(widbase, FIND_BY_UNAME='DDeroul') vmax = 1.0 ; Valeur maximale, en reflectance, utilisée pour la visualisation et les plots ; Récupération du chemin du fichier Polder ; POLFIL = GETPOLPATH(STRMID(POLNAM,0,STRLEN(POLNAM)-2)+'?D') ; msg = 'Fichier POLDER associé ' + POLFIL + ' pas trouvé' ; IF POLFIL EQ '' THEN RETURN, 0 ; POLNAM = STRMID(POLFIL,STRLEN(POLFIL)-STRLEN(POLNAM)) ; WIDGET_CONTROL, WIDGET_INFO(widbase, FIND_BY_UNAME='TPolFil'), SET_VALUE=POLNAM POLFIL = GETPOLPATH(POLNAM) msg = 'Fichier POLDER associé ' + POLFIL + ' pas trouvé' IF POLFIL EQ '' THEN BEGIN POLFIL = GETPOLPATH(STRMID(POLNAM,0,STRLEN(POLNAM)-2)+'?D') IF POLFIL EQ '' THEN RETURN, 0 IF DIALOG_MESSAGE(msg+'. Utiliser '+POLFIL+'?', /Question) NE 'Yes' THEN RETURN, 0 POLNAM = STRMID(POLFIL,STRLEN(POLFIL)-STRLEN(POLNAM)) WIDGET_CONTROL, WIDGET_INFO(widbase, FIND_BY_UNAME='TPolFil'), SET_VALUE=POLNAM END ; Récupération du chemin du fichier Modis numGr = MGORDER[grModis] msg = 'Granule MODIS désiré ' + MGNAMES[numGr] + ' pas trouvé' MODFIL = GETMODPATH(MGNAMES[numGr]) IF MODFIL EQ '' THEN RETURN, 0 ; Récupération des données utiles dans le fichier de coïncidences HDF_SD_FILEINFO, SDCPM, nsds, attr grpgap = numGr*nsds/N_ELEMENTS(MGNAMES) HDF_SD_GETDATA, HDF_SD_SELECT(SDCPM, HDF_SD_NAMETOINDEX(SDCPM, 'Pixels Polder concernés') + grpgap), prec HDF_SD_GETDATA, HDF_SD_SELECT(SDCPM, HDF_SD_NAMETOINDEX(SDCPM, 'Nombre de coïncidences') + grpgap), Nco HDF_SD_GETDATA, HDF_SD_SELECT(SDCPM, HDF_SD_NAMETOINDEX(SDCPM, 'Lignes Modis') + grpgap), lin HDF_SD_GETDATA, HDF_SD_SELECT(SDCPM, HDF_SD_NAMETOINDEX(SDCPM, 'Colonnes Modis') + grpgap), col HDF_SD_GETDATA, HDF_SD_SELECT(SDCPM, HDF_SD_NAMETOINDEX(SDCPM, 'Distance') + grpgap), dist Npo = N_ELEMENTS(prec) Ncomax = N_ELEMENTS(lin)/Npo PRINT, 'Nombre de pixels Polder concernés : ', Npo PRINT, 'Nombre maximal de pixels Modis par pixel Polder : ', Ncomax ; Lecture des mesures POLDER sur les pixels donnés par la table de coincidence PrintStep, widbase, 'Extraction des données POLDER' conv = 1.5E-3*!DTOR data = BYTARR(648) channels = [15, 17, 19, 21, 27] ; Permet de repérer les canaux POLDER [443, 490, 565, 670, 865] nm chann = channels[where(tchannel, Nwl)] RESU = FLTARR(Nwl, Npo, 2) ; Dans ce tableau, on met les réflectances POLDER/MODIS GEOM = FLTARR( 2, Npo, 2) ; Dans ce tableau, on met la géometrie POLDER/MODIS OPENR, Plun, POLFIL, /GET_LUN, ERR=err, /SWAP_IF_LITTLE_ENDIAN FOR i=0l, Npo-1 DO BEGIN IF (i MOD 1000) EQ 0 THEN WIDGET_CONTROL, DeroulId, SCR_XSIZE=FIX(deroulWdth*i/FLOAT(Npo)) POINT_LUN, Plun, 180 + 648l*prec[i] READU, Plun, data Ndir = data[43] Dir = REFORM(data[46:45+Ndir*43], 43, Ndir) VZA = REFORM(Dir[7, *]*256l+ Dir[8, *])*conv ; angle zénithal de visée idir = MIN(VZA, id) Dir = Dir [*, id] ; On ne garde que la direction la plus proche du Nadir SZA = (Dir[ 5]*256l+ Dir[ 6])*conv ; angle zénithal solaire fac = 1.E-4/COS(SZA) RESU[*, i, 0] = (Dir[chann]*256 + Dir[chann+1])*fac GEOM[0, i, 0] = (Dir[7]*256l + Dir[ 8])*conv ; Ici, on garde l'angle de visée POLDER GEOM[1, i, 0] = (Dir[9]*256l + Dir[10])*conv*4. ; Ici, on garde l'angle azimutal ENDFOR FREE_LUN, Plun WIDGET_CONTROL, DeroulId, SCR_XSIZE=deroulWdth ; Ouverture du fichier MODIS PrintStep, widbase, 'Extraction des données MODIS' modsd = HDF_SD_START(MODFIL, /READ) ; ; On récupère les dimensions des données id = HDF_SD_SELECT(modsd, HDF_SD_NAMETOINDEX(modsd, 'EV_1KM_RefSB')) HDF_SD_DIMGET, HDF_SD_DIMGETID(id, 0), COUNT=d0 & HDF_SD_DIMGET, HDF_SD_DIMGETID(id, 1), COUNT=d1 TMRef=FLTARR(d0, d1, Nwl) & TMVal=BYTARR(d0, d1, Nwl) ; On récupère les réflectances D'abord canaux à 1 km, puis à 500m et enfin 250 m sdsNames = ['EV_1KM_RefSB', 'EV_500_Aggr1km_RefSB', 'EV_250_Aggr1km_RefSB'] resols = ['1 km', '500 m', '250 m'] md0 = [0, 2, 3] & md1 = [1, 2, 4] & rm = [1, 2, 1, 0, 1] ; positions des canaux dans les fichiers Polder et Modis ;--------------------------------------------------------------------------------- ; 'EV_1KM_RefSB' ; 0, 8 , 405 - 420 ; 1, 9 , 438 - 448 POLDER 443 nm ; 2, 10 , 483 - 493 POLDER 490 nm ; 3, 11 , 526 - 536 ; 4, 12 , 546 - 556 ; 5, 13lo, 662 - 672 ; 6, 13hi, 662 - 672 ; 7, 14lo, 673 - 683 ; 8, 14hi, 673 - 683 ; 9, 15 , 743 - 753 ;10, 16 , 862 - 877 ;11, 17 , 890 - 920 ;12, 18 , 931 - 941 ;13, 19 , 915 - 965 ;14, 26 , 1360 -1390 ;--------------------------------------------------------------------------------- ; 'EV_500_Aggr1km_RefSB' ; 0, 3 , 459 - 479 ; 1, 4 , 545 - 565 POLDER 565 nm ; 2, 5 , 1230 -1250 ; 3, 6 , 1628 -1652 ; 0, 7 , 2105 -2155 ;--------------------------------------------------------------------------------- ; 'EV_250_Aggr1km_RefSB' ; 0, 1 , 620 - 670 POLDER 670 nm ; 1, 2 , 841 - 876 POLDER 865 nm ;--------------------------------------------------------------------------------- dim0 = 0 ww = FLOAT(deroulWdth)/N_ELEMENTS(resols) FOR ir = 0, N_ELEMENTS(resols) -1 DO dim0 = dim0 + getReflectance(modsd, sdsNames[ir], dim0, $ rm[md0[ir]:md1[ir]], tchannel[md0[ir]:md1[ir]], TMRef, TMVal, resols[ir], DeroulId, ir*ww, ww) ; On récupère aussi la géométrie de visée. On passe en azimuth relatif: convention POLDER. PrintStep, widbase, 'Lecture et interpolation de la géométrie de visée MODIS' SZA_low = GETHDFPAR(modsd, 'SolarZenith') & VZA_low = GETHDFPAR(modsd, 'SensorZenith') AZI_low = (72000l - GETHDFPAR(modsd, 'SensorAzimuth') + GETHDFPAR(modsd, 'SolarAzimuth')) MOD 36000 PRINT, 'extraction MODIS terminée' extrapolate_modis, VZA_low, VZA, DeroulId, 0, deroulWdth/3 extrapolate_modis, AZI_low, AZI, DeroulId, deroulWdth/3, deroulWdth/3 extrapolate_modis, SZA_low, SZA, DeroulId, 2*deroulWdth/3, deroulWdth/3 ; A ce niveau, on a des luminances normalisees. Passage en reflectance fac = 1./COS(SZA*!DTOR*0.01) FOR i = 0, Nwl - 1 DO TMref[*, *, i] = TMRef[*, *, i]*fac ; Ici, on fait une visualisation de la zone (3 canaux). Echantillonage tous les 5 km PrintStep, widbase, 'visualisation de la zone' samplex = INDGEN(271)*5 + 2 & sampley = INDGEN(406)*5 + 2 chan = [4, 3, 2] visu = BYTE((TMref[samplex, *, *]/vmax*255)<255) & visu=visu[*, sampley, chan] FOR i=0, 2 DO visu[*, *, i] = ROTATE(visu[*, *, i], 7) DEVICE, /DECOMPOSE resol = GET_SCREEN_SIZE() WINDOW, xsize=271, ysize=406, ypos=0, TITLE='Visualisation '+MGNAMES[numGr] tv, visu, TRUE=3 OW = INTARR(6) OW[0] = !D.WINDOW ; On fait la moyenne des reflectances mesurées sur la zone PrintStep, widbase, 'Génération des graphiques de comparaison' refs = FLTARR(Ncomax, Nwl) FOR i=0l, Npo-1 DO BEGIN IF (i MOD 1000) EQ 0 THEN WIDGET_CONTROL, DeroulId, SCR_XSIZE=FIX(deroulWdth*i/FLOAT(Npo)) FOR j=0, Nco[i]-1 DO refs[j, *]=TMref[col[j, i], lin[j, i], *] RESU[*, i, 1] = TOTAL(refs[0:Nco[i]-1, *], 1)/Nco[i] ; On récupère la géométrie de visée du pixel central dmin = MIN(dist[*, i], j) ; j est le numéro du pixel le plus proche du centre GEOM[0, i, 1] = VZA[col[j, i], lin[j, i]] & GEOM[1, i, 1] = AZI[col[j, i], lin[j, i]] ENDFOR GEOM[*, *, 1] = GEOM[*, *, 1]*0.01*!DTOR WIDGET_CONTROL, DeroulId, SCR_XSIZE=deroulWdth ;On limite l'écart entre les directions de visée cosEcart = COS(toldir[0]*!DTOR) LIMDIR = REFORM(COS(GEOM[0, *, 1])*COS(GEOM[0, *, 0]) + SIN(GEOM[0, *, 1])*SIN(GEOM[0, *, 0])*COS(GEOM[1, *, 0] $ - GEOM[1, *, 1])) LIMIT = WHERE(LIMDIR GE cosEcart, Count) msg = 'Tolérance angulaire entre les directions de visée trop faible. Aucun pixel trouvé.' IF LIMIT[0] EQ -1 THEN RETURN, 0 print, Count, ' pixels concernés sur ', Npo, ' en coïncidence' RESU = RESU[*, LIMIT, *] ; On fabrique les plots de comparaison DEVICE, DECOMPOSE=0 ;aeropalette, nc=nc ;loadct, 13 loadct, 2 !P.BACKGROUND = 0 & !P.COLOR = 255 axes=['POLDER2', 'MODIS'] tit=['443 nm', '490 nm', '565 nm', '670 nm', '865 nm'] tit1 = tit[where(tchannel)] siz = 250 xwth = siz + 10 & ywth = siz + 30 nxw = FIX(resol[0])/xwth FOR i=0, Nwl-1 DO OW[i+1] = histo2D(resu[i, *, 0], resu[i, *, 1], [minDyn, maxDyn], i + 1, tit1[i], axes, siz, $ resol[0] - 1 - (xwth)*(1 + i MOD nxw), resol[1] - 1 - ywth - ywth*(i/nxw)) OW = OW[0:Nwl] return, 1 PrintStep, widbase, 'Terminé' END PRO TopBaseDir_event, Event CASE widget_info(Event.id, /UNAME) of 'BCoi' : SetBaseDir, Event 'BPol' : SetBaseDir, Event 'BMod' : SetBaseDir, Event 'BFin' : CloseWindow, Event ENDCASE END PRO CMP_POL_MOD_DIR_GUI, GROUP_LEADER=wGroup, _EXTRA=_VWBExtra_ TopBaseDir = Widget_Base(GROUP_LEADER=wGroup, UNAME='TopBaseDir', TITLE='Répertoires racines des données', $ XOFFSET=5, YOFFSET=5, NOTIFY_REALIZE='Realisation', SPACE=15, XPAD=3, YPAD=3, COLUMN=1) CoiBase = Widget_Base(TopBaseDir, UNAME='CoiBase', COLUMN=1) CoiBase1 = Widget_Base(CoiBase, UNAME='CoiBase1', ROW=1) LCoi= Widget_Label(CoiBase1, /ALIGN_LEFT ,VALUE='Répertoire racine des tables de coïncidences') CoiBase2 = Widget_Base(CoiBase, UNAME='CoiBase2', SPACE=5, ROW=1) TCoi = Widget_Text(CoiBase2, UNAME='TCoi', XSIZE=STRLEN('G:/ICAREDEV/POLDER2/P2L1TBG1016013.CPM.hdf ')) BCoi = Widget_Button(CoiBase2, UNAME='BCoi', /ALIGN_CENTER, VALUE='Choisir') PolBase = Widget_Base(TopBaseDir, UNAME='PolBase', COLUMN=1) PolBase1 = Widget_Base(PolBase, UNAME='PolBase1', ROW=1) LPol = Widget_Label(PolBase1, /ALIGN_LEFT ,VALUE='Répertoire racine des données POLDER2') PolBase2 = Widget_Base(PolBase, UNAME='PolBase2', SPACE=5, ROW=1) TPol = Widget_Text(PolBase2, UNAME='TPol', XSIZE=STRLEN('G:/ICAREDEV/POLDER2/P2L1TBG1016013.CPM.hdf ')) BPol = Widget_Button(PolBase2, UNAME='BPol', /ALIGN_CENTER, VALUE='Choisir') ModBase = Widget_Base(TopBaseDir, UNAME='ModBase', COLUMN=1) ModBase1 = Widget_Base(ModBase, UNAME='ModBase1', ROW=1) LMod = Widget_Label(ModBase1, /ALIGN_LEFT ,VALUE='Répertoire racine des données MODIS') ModBase2 = Widget_Base(ModBase, UNAME='ModBase2', SPACE=5, ROW=1) TMod = Widget_Text(ModBase2, UNAME='TMod', XSIZE=STRLEN('G:/ICAREDEV/POLDER2/P2L1TBG1016013.CPM.hdf ')) BMod = Widget_Button(ModBase2, UNAME='BMod', /ALIGN_CENTER, /ALIGN_BOTTOM, VALUE='Choisir') BFin = Widget_Button(TopBaseDir, UNAME='BFin', /ALIGN_CENTER, VALUE='Terminer') Widget_Control, /REALIZE, TopBaseDir XManager, 'TopBaseDir', TopBaseDir, /NO_BLOCK END PRO SetBaseDir, Event COMMON COMDIRS CASE Event.ID OF WIDGET_INFO(Event.top, FIND_BY_UNAME='BCoi') : title = 'tables de coïncidences' WIDGET_INFO(Event.top, FIND_BY_UNAME='BPol') : title = 'données POLDER2' WIDGET_INFO(Event.top, FIND_BY_UNAME='BMod') : title = 'données MODIS' ENDCASE CASE Event.ID OF WIDGET_INFO(Event.top, FIND_BY_UNAME='BCoi') : dir = CPMBAS WIDGET_INFO(Event.top, FIND_BY_UNAME='BPol') : dir = POLBAS WIDGET_INFO(Event.top, FIND_BY_UNAME='BMod') : dir = MODBAS ENDCASE dir = DIALOG_PICKFILE(PATH=dir, /DIRECTORY, TITLE='Répertoire racine des '+title) IF dir EQ '' THEN RETURN CASE Event.ID OF WIDGET_INFO(Event.top, FIND_BY_UNAME='BCoi') : CPMBAS = dir WIDGET_INFO(Event.top, FIND_BY_UNAME='BPol') : POLBAS = dir WIDGET_INFO(Event.top, FIND_BY_UNAME='BMod') : MODBAS = dir ENDCASE SETCONFIG Realisation, Event.top END PRO Realisation, wWidget COMMON COMDIRS WIDGET_CONTROL, WIDGET_INFO(wWidget, FIND_BY_UNAME='TCoi'), SET_VALUE=CPMBAS WIDGET_CONTROL, WIDGET_INFO(wWidget, FIND_BY_UNAME='TPol'), SET_VALUE=POLBAS WIDGET_CONTROL, WIDGET_INFO(wWidget, FIND_BY_UNAME='TMod'), SET_VALUE=MODBAS END PRO CloseWindow, Event WIDGET_CONTROL, Event.top, /DESTROY END FUNCTION histo2D, tab1, tab2, range, iplot, tit, axes, siz, xpos, ypos, NC=nc, REGRESS=regress IF NOT KEYWORD_SET(nc) THEN nc=255 window, iplot, xsize=siz, ysize=siz, TIT=tit, xpos=xpos, ypos=ypos valid = WHERE((tab1 GE range[0]) AND (tab1 LE range[1]) AND $ (tab2 GE range[0]) AND (tab2 LE range[1]), count) ic = FIX((tab1-range[0])/(range[1]-range[0])*100.)<99 il = FIX((tab2-range[0])/(range[1]-range[0])*100.)<99 xgr = siz - 210 IF valid[0] GE 0 THEN BEGIN addr = ic[valid]+il[valid]*100l VISU = INTARR(100, 100) FOR i=0l, count-1 DO visu[addr[i]] = visu[addr[i]] + 1 s=SORT(visu) & vmax = visu[s[100*100-10]] visu = BYTE((visu/FLOAT(vmax)*(nc-3.)) < (nc-3.) ) visu [WHERE(visu EQ 0)] = !P.BACKGROUND tv, REBIN(visu, 200, 200, /SAMPLE), xgr, 40 ENDIF plot, range, range, xstyle=1, ystyle=1, /NOERASE, POS=[xgr, 40, xgr + 199, 239], /DEVICE, XTIT=axes[0], YTIT=axes[1] IF KEYWORD_SET(regress) AND valid[0] GE 0 THEN BEGIN dr = POLY_FIT(tab1, tab2, 1) oplot, range, dr[1]*range + dr[0], color=254 dd = 'pente: '+STRING(dr[1], FORMAT='(f8.5)') xyouts, xgr + 20, 200, dd, /DEVICE, color=254 END return, !D.WINDOW END ;============================================================================================== ;---------------------------------------------------------------------------------------------- PRO DrawGranule, base, ng, clr WIDGET_CONTROL, WIDGET_INFO(base, FIND_BY_UNAME='DOrbites'), GET_VALUE=orbid InitDisplay, orbid, clr draw_orb, ng, WIDGET_INFO(WIDGET_INFO(base, FIND_BY_UNAME='DProject'), /DROPLIST_SELECT) END ;============================================================================================== ; Cette procédure trace les orbites ;---------------------------------------------------------------------------------------------- PRO draw_orb, grModis, proj COMMON COMDIRS Ploneq = 0. IF grModis GE 0 THEN BEGIN vdrf = HDF_VD_FIND(FHCPM, 'Infos Polder') vdid = HDF_VD_ATTACH(FHCPM, vdrf, /READ) nrec = HDF_VD_READ(vdid, Ploneq , FIELDS="Longitude noeud descendant") nrec = HDF_VD_READ(vdid, Platmin, FIELDS="Latitude minimale") nrec = HDF_VD_READ(vdid, Platmax, FIELDS="Latitude maximale") HDF_VD_DETACH, vdid vdrf = HDF_VD_FIND(FHCPM, 'Infos Modis') vdid = HDF_VD_ATTACH(FHCPM, vdrf, /READ) nrec = HDF_VD_READ(vdid, Mloneq , FIELDS="Longitude noeud descendant") nrec = HDF_VD_READ(vdid, Mlatext, FIELDS="Latitudes extrêmes") nrec = HDF_VD_READ(vdid, Mlonext, FIELDS="Longitudes extrêmes") HDF_VD_DETACH, vdid ENDIF limit=[-90., -180., 90., 180.] & londel = 45 latlab = (FIX(Ploneq)/londel - 2)*londel CASE proj OF 0 : MAP_SET, 0., Ploneq, LIMIT=limit, LONDEL=londel, LATLAB=latlab, POS=[-0.1, -0.1, 1.1, 1.05], /LABEL, /NOBORDER, /CONTINENTS, /GRID, /ISOTROPIC, $ /CYLINDRICAL, LATALIGN=0, LONALIGN=1 1 : MAP_SET, 0., Ploneq, LIMIT=limit, LONDEL=londel, LATLAB=latlab, POS=[0.00, 0.01, 0.97, 0.9], /LABEL, /NOBORDER, /CONTINENTS, /GRID, /ISOTROPIC, $ /AITOFF , /HORIZON, LATALIGN=0, LONALIGN=1 2 : MAP_SET, 0., Ploneq, LIMIT=limit, LONDEL=londel, LATLAB=latlab, POS=[0., 0.01, 1., 0.99] , /LABEL, /NOBORDER, /CONTINENTS, /GRID, /ISOTROPIC, $ /ORTHOGRAPHIC, /HORIZON, LATALIGN=0, LONALIGN=1 3 : MAP_SET, 0., Ploneq, LIMIT=limit, LONDEL=londel, LATLAB=latlab, POS=[0., 0.01, 1., 0.99] , /LABEL, /NOBORDER, /CONTINENTS, /GRID, /ISOTROPIC, $ /SINUSOIDAL , /HORIZON, LATALIGN=0, LONALIGN=1 ENDCASE IF grModis LT 0 THEN return numgran = MGORDER[grModis] ; Tracé de l'orbite POLDER. draw_sat_orb, (*psats).polder, Ploneq, Platmin, Platmax, 1, 1, 1 ; Tracé de l'orbite MODIS. FOR j = 0, N_ELEMENTS(MGNAMES) - 1 DO BEGIN $ draw_sat_orb, (*psats).modis, Mloneq[j], Mlatext[2, j], Mlatext[0, j], 3, 0, 1 XYOUTS, (Mlonext[1, j] > Mlonext[2, j]) + 3, (Mlatext[2, j] + Mlatext[0, j])/2 - 5, MGNAMES(MGORDER[j]), COL=3 ENDFOR draw_sat_orb, (*psats).modis, Mloneq[numgran], Mlatext[2, numgran], Mlatext[0, numgran], 3, 1, 3 x1 = 25 & x2 = 110 & x3 = 530 & y0 = 5 XYOUTS, x1, y0, 'POLDER', COL=1, /DEVICE XYOUTS, x2, y0, 'MODIS' , COL=3, /DEVICE XYOUTS, x3, y0, 'Granule MODIS courant', COL=3, /DEVICE plots, [x1 - 20, x1 - 5], [y0 + 4, y0 + 4], col=1, /DEVICE plots, [x2 - 20, x2 - 5], [y0 + 4, y0 + 4], col=3, /DEVICE plots, [x3 - 20, x3 - 5], [y0 + 4, y0 + 4], col=3, thick = 3, /DEVICE END ;============================================================================================== ; Cette procédure trace une orbite d'un satellite ;---------------------------------------------------------------------------------------------- PRO draw_sat_orb, sat, loneq, latmin0, latmax0, col, trace, thick COMMON COMDIRS Rte = 6378.14D & Rtp = 6357.2D & perT = 24.*3600.D & Npos = 101 maxlatval = 180D - sat.inclin inclin = sat.inclin*!DTOR & alphaV = sat.alphaV*!DTOR per = sat.cycle*3600.D*24/sat.Norb Rt = SQRT(Rtp^2 + (Rte^2 - Rtp^2)*cos(inclin)^2) alti = Sat.alti + Rte - Rt alpha = 2*ATAN((1. - SQRT(1. - TAN(alphaV)^2*(alti/Rt+2)*alti/Rt))/(TAN(alphaV)*(alti/Rt+2))) IF trace EQ 1 THEN BEGIN lat = -maxlatval + INDGEN(Npos)*2.*maxlatval/(Npos - 1) lonP = loneq + !RADEG*(per*sin(lat*!DTOR)/(perT*sin(inclin)) - ASIN(tan(lat*!DTOR)/tan(inclin))) OPLOT, lonP, lat, col=col, LINESTYLE=2 ENDIF latmin = !RADEG*ASIN((sin(latmin0*!DTOR) - cos(inclin)*sin(alpha))/cos(alpha)) latmax = !RADEG*ASIN((sin(latmax0*!DTOR) + cos(inclin)*sin(alpha))/cos(alpha)) lat = latmin + INDGEN(Npos)*(latmax - latmin)/(Npos - 1) Nlat = N_ELEMENTS(lat) sinwt = sin(lat*!DTOR)/sin(inclin) & wt = ASIN(sinwt) latP = !RADEG*ASIN(sin(inclin)*cos(alpha)*sinwt + cos(inclin)*sin(alpha)) lonP = loneq - !RADEG*(ASIN((cos(inclin)*cos(alpha)*sinwt - sin(inclin)*sin(alpha))/cos(latP*!DTOR)) - wt*per/perT) OPLOT, lonP, latP, col=col, LINESTYLE=ls, THICK=thick latP = !RADEG*ASIN(sin(inclin)*cos(alpha)*sinwt - cos(inclin)*sin(alpha)) lonP = loneq - !RADEG*(ASIN((cos(inclin)*cos(alpha)*sinwt + sin(inclin)*sin(alpha))/cos(latP*!DTOR)) - wt*per/perT) OPLOT, lonP, latP, col=col, LINESTYLE=ls, THICK=thick alphaP = -alpha + INDGEN(Npos)*2.*alpha/(Npos -1) sinwtP = sin(lat[0]*!DTOR)/sin(inclin) & wtP = ASIN(sinwtP) latP = !RADEG*ASIN(sin(inclin)*cos(alphaP)*sinwtP + cos(inclin)*sin(alphaP)) lonP = loneq - !RADEG*(ASIN((cos(inclin)*cos(alphaP)*sinwtP - sin(inclin)*sin(alphaP))/cos(latP*!DTOR)) - wtP*per/perT) OPLOT, lonP, latP, col=col, LINESTYLE=ls, THICK=thick sinwtP = sin(lat[Nlat - 1]*!DTOR)/sin(inclin) & wtP = ASIN(sinwtP) latP = !RADEG*ASIN(sin(inclin)*cos(alphaP)*sinwtP + cos(inclin)*sin(alphaP)) lonP = loneq - !RADEG*(ASIN((cos(inclin)*cos(alphaP)*sinwtP - sin(inclin)*sin(alphaP))/cos(latP*!DTOR)) - wtP*per/perT) OPLOT, lonP, latP, col=col, LINESTYLE=ls, THICK=thick END PRO TopBase_event, Event CASE widget_info(Event.id, /UNAME) of 'MOuvrir' : GetTabCoi, Event 'MRepert' : SetBaseDirs, Event 'MQuitter': Quitter, Event 'DProject': ChangeGranule, Event 'DModFil' : ChangeGranule, Event 'CBEcart' : CBEcartChecked, Event 'TEcart' : BREAK 'BGo' : OnGo, Event ELSE : SlctBase_event, Event ENDCASE END PRO CMP_POL_MOD_GUI, GROUP_LEADER=wGroup, _EXTRA=_VWBExtra_ ; Creation TopLevelBase ; ===================== TopBase = WIDGET_BASE(TITLE='Comparaisons POLDER2/MODIS', NOTIFY_REALIZE='TopWindowRealize', MBAR=MenuBar, /ROW) ; Creation menus ; ============== MFichier = Widget_Button(MenuBar , VALUE='Fichier' , UNAME='MFichier', /MENU) MOuvrir = Widget_Button(MFichier, VALUE='Ouvrir' , UNAME='MOuvrir') MPrefer = Widget_Button(MFichier, VALUE='Options' , UNAME='MPrefer' , /MENU, /SEPARATOR ) MRepert = Widget_Button(MPrefer , VALUE='Répertoires', UNAME='MRepert') MQuitter = Widget_Button(MFichier, VALUE='Quitter' , UNAME='MQuitter', /SEPARATOR) ; Creation zone de contrôle ; ========================= CtrlBase = WIDGET_BASE(TopBase, ROW=10, /BASE_ALIGN_CENTER, XPAD=0, YPAD=0) ; Creation zone fichiers ; ====================== FileBase = WIDGET_BASE(CtrlBase, /COLUMN, /BASE_ALIGN_CENTER, FRAME=2) TTabCoi = CW_FIELD(FileBase, UNAME='TTabCoi', TITLE='Table des coïncidences :', /STRING, /NOEDIT, $ XSIZE=STRLEN('P2L1TBG1016013.CPM.hdf ')) P2MBase = WIDGET_BASE(FileBase, COLUMN=2, /BASE_ALIGN_CENTER, /GRID_LAYOUT) TPolFil = CW_FIELD(P2MBase, UNAME='TPolFil', TITLE='POLDER 2', /STRING, /NOEDIT, /COLUMN, $ XSIZE=STRLEN('P2L1TBG1025049BD ')) ModBase = WIDGET_BASE(P2MBase, /COLUMN, /BASE_ALIGN_CENTER) LModFil = Widget_Label(ModBase, VALUE='MODIS') DModFil = Widget_Droplist(ModBase, UNAME='DModFil', SENSITIVE=0) geom = WIDGET_INFO(FileBase, /GEOMETRY) CtrlWidth = geom.scr_xsize-4 ; Creation zone sélection ; ======================== CMP_POL_MOD_SLC_GUI, CtrlBase, CtrlWidth ; Creation zone paramètres ; ======================== ParmBase = WIDGET_BASE(CtrlBase, UNAME='ParmBase', /COLUMN, /BASE_ALIGN_CENTER, FRAME=2, SENSITIVE=0, XSIZE=CtrlWidth) MnxBase = WIDGET_BASE(ParmBase, COLUMN=2, /BASE_ALIGN_CENTER, /GRID_LAYOUT) TMinDyn = CW_FIELD(MnxBase, UNAME='TMinDyn', TITLE='Minimum :', /FLOATING, /ROW, VALUE=[ '0.0' ], $ /ALL_EVENTS, XSIZE=STRLEN('0.00000')) TMaxDyn = CW_FIELD(MnxBase, UNAME='TMaxDyn', TITLE='Maximum :', /FLOATING, /ROW, VALUE=[ '1.0' ], $ /ALL_EVENTS, XSIZE=STRLEN('1.00000')) EcrtBase = Widget_Base(ParmBase, /COLUMN, YPAD=0) WBEcart = Widget_Base(EcrtBase, /COLUMN ,/NONEXCLUSIVE, YPAD=0) CBEcart = Widget_Button(WBEcart, UNAME='CBEcart', /ALIGN_LEFT , UVALUE=0, $ VALUE='Ecart maximal entre les directions de visée') TEcart = CW_FIELD(EcrtBase, UNAME='TEcart', UVALUE='0', TITLE='Valeur (en °) :', /INTEGER, /ROW, $ /ALL_EVENTS, XSIZE=STRLEN('360 ')) WIDGET_CONTROL, TEcart, SENSITIVE=0 CMP_POL_MOD_PRM_GUI, ParmBase, CtrlWidth ; Creation zone exécution ; ======================== ExecBase = WIDGET_BASE(CtrlBase, UNAME='ExecBase', /COLUMN, /BASE_ALIGN_CENTER, FRAME=2, $ SENSITIVE=0, XSIZE=CtrlWidth) BGo = Widget_Button(ExecBase, UNAME='BGo', /ALIGN_CENTER, VALUE='GO!') WBDeroul = Widget_Base(ExecBase, UNAME='WBDeroul' , XOFFSET=11, YOFFSET=387, SCR_XSIZE=279, $ SCR_YSIZE=60, MAP=0, TITLE='IDL', SPACE=3, XPAD=3, YPAD=3) DDeroul = Widget_Draw(WBDeroul, UNAME='DDeroul', YOFFSET=30, SCR_XSIZE=275, SCR_YSIZE=24) TDeroul = Widget_Text(WBDeroul, UNAME='TDeroul', SCR_XSIZE=275, XSIZE=20, YSIZE=1) ; Creation zone de visualisation ; ============================== VisuBase = WIDGET_BASE(TopBase, /COLUMN, /BASE_ALIGN_CENTER, FRAME=2) draw_xsize = 700 & draw_ysize = 400 DProject = Widget_Droplist(VisuBase, UNAME='DProject', TITLE='Type de projection', $ VALUE=['Cylindrique équidistante', 'Aitoff', 'Orthographique', 'Sinusoïdale']) DOrbites = Widget_Draw(VisuBase, UNAME='DOrbites', SCR_XSIZE=draw_xsize, SCR_YSIZE=draw_ysize) ; Réalisation ; =========== Widget_Control, /REALIZE, TopBase XManager, 'TopBase', TopBase, /NO_BLOCK END PRO GetTabCoi, Event FORWARD_FUNCTION initFiles COMMON INITS COMMON COMDIRS firsttime = (CPMFIL EQ '') WHILE 1 do begin filein = DIALOG_PICKFILE(PATH=CPMBAS, FILTER='*.CPM.hdf', /FIX_FILTER) if filein EQ '' then return if initFiles(filein, message) then break Result = DIALOG_MESSAGE(message, /ERROR) ENDWHILE WIDGET_CONTROL, WIDGET_INFO(Event.top, FIND_BY_UNAME='TTabCoi'), /SENSITIVE, SET_VALUE=CPMNAM WIDGET_CONTROL, WIDGET_INFO(Event.top, FIND_BY_UNAME='TPolFil'), /SENSITIVE, SET_VALUE=POLNAM WIDGET_CONTROL, WIDGET_INFO(Event.top, FIND_BY_UNAME='DModFil'), /SENSITIVE, SET_VALUE=MGNAMES[MGORDER], SET_UVALUE=1 WIDGET_CONTROL, WIDGET_INFO(Event.top, FIND_BY_UNAME='ParmBase'), /SENSITIVE IF firsttime THEN WIDGET_CONTROL, WIDGET_INFO(Event.top, FIND_BY_UNAME='SlctBase'), /SENSITIVE WIDGET_CONTROL, WIDGET_INFO(Event.top, FIND_BY_UNAME='ExecBase'), SENSITIVE = InitExec ; Visualisation des orbites ChangeGranule, Event END PRO SetBaseDirs, Event CMP_POL_MOD_DIR_GUI END PRO TopWindowRealize, wWidget COMMON COMDIRS geom = WIDGET_INFO(WIDGET_INFO(wWidget, FIND_BY_UNAME='DDeroul'), /GEOMETRY) deroulWdth = geom.scr_xsize WIDGET_CONTROL, WIDGET_INFO(wWidget, FIND_BY_UNAME='DModFil'), SET_UVALUE=0 DrawGranule, wWidget, -1, 0 END PRO ChangeGranule, Event WIDGET_CONTROL, WIDGET_INFO(Event.top, FIND_BY_UNAME='DModFil'), GET_UVALUE=created IF created THEN ng = WIDGET_INFO(WIDGET_INFO(Event.top, FIND_BY_UNAME='DModFil'), /DROPLIST_SELECT) ELSE ng = -1 IF WIDGET_INFO(Event.id, /UNAME) NE 'DProject' THEN clr = 1 ELSE clr = 0 DrawGranule, Event.top, ng, clr END PRO CBEcartChecked, Event WIDGET_CONTROL, Event.ID, SET_UVALUE=Event.SELECT WIDGET_CONTROL, WIDGET_INFO(Event.top, FIND_BY_UNAME='TEcart' ), SENSITIVE=Event.select END PRO Quitter, Event DeleteWindows WIDGET_CONTROL, event.top, /DESTROY HEAP_GC END PRO SetBaseDir, Event COMMON COMDIRS CASE Event.ID OF WIDGET_INFO(Event.top, FIND_BY_UNAME='BCoi') : title = 'tables de coïncidences' WIDGET_INFO(Event.top, FIND_BY_UNAME='BPol') : title = 'données POLDER2' WIDGET_INFO(Event.top, FIND_BY_UNAME='BMod') : title = 'données MODIS' ENDCASE dir = DIALOG_PICKFILE(PATH='.', /DIRECTORY, TITLE='Répertoire racine des '+title) CASE Event.ID OF WIDGET_INFO(Event.top, FIND_BY_UNAME='BCoi') : CPMBAS = dir WIDGET_INFO(Event.top, FIND_BY_UNAME='BPol') : POLBAS = dir WIDGET_INFO(Event.top, FIND_BY_UNAME='BMod') : MODBAS = dir ENDCASE Realisation, Event.top END PRO Realisation, wWidget COMMON COMDIRS WIDGET_CONTROL, WIDGET_INFO(wWidget, FIND_BY_UNAME='TCoi'), SET_VALUE=CPMBAS WIDGET_CONTROL, WIDGET_INFO(wWidget, FIND_BY_UNAME='TPol'), SET_VALUE=POLBAS WIDGET_CONTROL, WIDGET_INFO(wWidget, FIND_BY_UNAME='TMod'), SET_VALUE=MODBAS END PRO CloseWindow, Event WIDGET_CONTROL, Event.top, /DESTROY END FUNCTION getDynRange, Event, dynMin, dynMax WIDGET_CONTROL, WIDGET_INFO(Event.top, FIND_BY_UNAME='TMinDyn'), GET_VALUE=sDynMin WIDGET_CONTROL, WIDGET_INFO(Event.top, FIND_BY_UNAME='TMaxDyn'), GET_VALUE=sDynMax mn = FLOAT(sDynMin) & mx = FLOAT(sDynMax) IF mn LT 0. OR mn GE 1. OR mx LE 0. OR mx GT 1. OR mn GE mx THEN BEGIN Result = DIALOG_MESSAGE('Dynamique invalide', /ERROR) return, 0 ENDIF dynMin = mn & dynMax = mx return, 1 END FUNCTION getEcartAng, Event, ecart WIDGET_CONTROL, WIDGET_INFO(Event.top, FIND_BY_UNAME='CBEcart'), GET_UVALUE=ve WIDGET_CONTROL, WIDGET_INFO(Event.top, FIND_BY_UNAME='TEcart' ), GET_VALUE=ec IF ve EQ '0' THEN BEGIN ecart = 180 ENDIF ELSE BEGIN IF ec LE 0 OR ec GT 180 THEN BEGIN Result = DIALOG_MESSAGE('Ecart angulaire invalide', /ERROR) return, 0 ENDIF ecart = ec ENDELSE return,1 END PRO CMP_POL_MOD_SLC_GUI, CtrlBase, CtrlWidth SlctBase = WIDGET_BASE(CtrlBase, UNAME='SlctBase', /COLUMN, /BASE_ALIGN_CENTER, FRAME=2, SENSITIVE=0, $ XSIZE=CtrlWidth, SPACE=0) MakeCheckButtons, SlctBase, '443', '438-448 nm (1 km)' MakeCheckButtons, SlctBase, '490', '483-493 nm (1 km)' MakeCheckButtons, SlctBase, '565', '545-565 nm (500 m)' MakeCheckButtons, SlctBase, '670', '620-670 nm (250 m)' MakeCheckButtons, SlctBase, '865', '841-876 nm (250 m)' END PRO MakeCheckButtons, base, wlth, mlab WB = Widget_Base(base, COLUMN=2,/GRID_LAYOUT) WB1 = Widget_Base(WB, /ROW, /ALIGN_RIGHT,/BASE_ALIGN_RIGHT, YPAD=1) LP = Widget_Label(WB1, /ALIGN_RIGHT, VALUE=wlth+' nm') WB2 = Widget_Base(WB, /ROW, /NONEXCLUSIVE, /BASE_ALIGN_LEFT, YPAD=0) CB = Widget_Button(WB2, UNAME='CB'+wlth, /ALIGN_LEFT, UVALUE=0, VALUE=mlab) END PRO CMP_POL_MOD_PRM_GUI, PrmBase, CtrlWidth END PRO SlctBase_event, Event CBChecked, Event END PRO CBChecked, Event v = Event.SELECT WIDGET_CONTROL, Event.ID, SET_UVALUE=v WIDGET_CONTROL, WIDGET_INFO(Event.top, FIND_BY_UNAME='CB443'), GET_UVALUE=v0 WIDGET_CONTROL, WIDGET_INFO(Event.top, FIND_BY_UNAME='CB490'), GET_UVALUE=v1 WIDGET_CONTROL, WIDGET_INFO(Event.top, FIND_BY_UNAME='CB565'), GET_UVALUE=v2 WIDGET_CONTROL, WIDGET_INFO(Event.top, FIND_BY_UNAME='CB670'), GET_UVALUE=v3 WIDGET_CONTROL, WIDGET_INFO(Event.top, FIND_BY_UNAME='CB865'), GET_UVALUE=v4 IF (v EQ v0 + v1 + v2 + v3 + v4) THEN BEGIN WIDGET_CONTROL, WIDGET_INFO(Event.top, FIND_BY_UNAME='ExecBase'), SENSITIVE=v ENDIF END PRO OnGo, Event FORWARD_FUNCTION Comparer, getDynRange, getEcartAng DeleteWindows IF NOT (getDynRange(Event, dynMin, dynMax) AND getEcartAng(Event, ecart)) THEN return WIDGET_CONTROL, WIDGET_INFO(Event.top, FIND_BY_UNAME='CB443' ), GET_UVALUE=v0 WIDGET_CONTROL, WIDGET_INFO(Event.top, FIND_BY_UNAME='CB490' ), GET_UVALUE=v1 WIDGET_CONTROL, WIDGET_INFO(Event.top, FIND_BY_UNAME='CB565' ), GET_UVALUE=v2 WIDGET_CONTROL, WIDGET_INFO(Event.top, FIND_BY_UNAME='CB670' ), GET_UVALUE=v3 WIDGET_CONTROL, WIDGET_INFO(Event.top, FIND_BY_UNAME='CB865' ), GET_UVALUE=v4 WIDGET_CONTROL, WIDGET_INFO(Event.top, FIND_BY_UNAME='DDeroul'), SCR_XSIZE=0 WIDGET_CONTROL, WIDGET_INFO(Event.top, FIND_BY_UNAME='WBDeroul'), MAP=1 if NOT Comparer(WIDGET_INFO(WIDGET_INFO(Event.top, FIND_BY_UNAME='DModFil'), /DROPLIST_SELECT), [v0, v1, v2, v3, v4], $ ecart, dynMin, dynMax, message, Event.top) then Result = DIALOG_MESSAGE(message, /ERROR) WIDGET_CONTROL, WIDGET_INFO(Event.top, FIND_BY_UNAME='WBDeroul'), MAP=0 END PRO Initialisations FORWARD_FUNCTION GETHDFPAR, GETPOLPATH, GETMODPATH, getReflectance, SEARCHPATH, histo2D COMMON COMDIRS CASE !VERSION.OS_FAMILY OF 'MacOS' : BEGIN DIRSEP = ':' & CFGFIL = 'CMP_POL_MOD.cfm' END 'unix' : BEGIN DIRSEP = '/' & CFGFIL = 'CMP_POL_MOD.cfu' END 'Windows': BEGIN DIRSEP = '\' & CFGFIL = 'CMP_POL_MOD.cfw' END ENDCASE CPMFIL = '' & MODPRD = 'MOD021KM' GETCONFIG ; Infos ADEOS2 / POLDER2 polder={sat: 'ADEOS2', cap: 'POLDER2', cycle: 4, Norb: 57, alti: 802.92D, inclin: 98.62D, alphaV: 51.D } ; Infos TERRA / MODIS modis ={sat: 'TERRA' , cap: 'MODIS' , cycle: 16, Norb: 233, alti: 705.00D, inclin: 98.20D, alphaV: 55.D } sats = {polder: polder, modis: modis} psats = PTR_NEW(sats, /NO_COPY) OW = INTARR(1) OW[0] = -1 END ;============================================================================================== ; Cette fonction initialise les différents fichiers ;---------------------------------------------------------------------------------------------- FUNCTION initFiles, cpmpath, msg COMMON COMDIRS CPMFIL = cpmpath pos = STRPOS(CPMFIL, DIRSEP, /REVERSE_SEARCH) IF pos GE 0 THEN CPMNAM = STRMID(CPMFIL, pos + 1) ELSE CPMNAM = CPMFIL msg = CPMFIL + ' n''est pas un fichier de coïncidence valide' IF NOT HDF_ISHDF(cpmpath) THEN GOTO, ERR FHCPM = HDF_OPEN(cpmpath, /READ) IF FHCPM LT 0 THEN GOTO, ERR SDCPM = HDF_SD_START(cpmpath, /READ) IF SDCPM LT 0 THEN GOTO, ERR ; Récupération du nom du fichier Polder HDF_SD_ATTRINFO, SDCPM, HDF_SD_ATTRFIND(SDCPM, "Polder Source"), DATA=POLNAM ; Récupération des noms des granules Modis MGIDS = HDF_VG_LONE(FHCPM) mghs = LONARR(N_ELEMENTS(mgids)) MGNAMES = STRARR(N_ELEMENTS(MGIDS)) nbg = 0 FOR g = 0, N_ELEMENTS(mghs) - 1 DO BEGIN mghs[g] = HDF_VG_ATTACH(FHCPM, mgids[g], /READ) HDF_VG_GETINFO, mghs[g], NAME=mgname IF NOT STREGEX(mgname, 'A20[0-9]+\.[0-9]+' , /BOOLEAN) THEN CONTINUE MGNAMES[nbg]=mgname & nbg = nbg + 1 ENDFOR MGNAMES = REFORM(MGNAMES[0:nbg-1]) & MODLAL = FLTARR(4, nbg) & MODLOL = FLTARR(4, nbg) MGORDER = SORT(MGNAMES) return, 1 ERR: ; Arrivé ici, il y a eu un problème IF SDCPM GE 0 THEN HDF_SD_END, SDCPM SDCPM = -1 IF FHCPM GE 0 THEN HDF_CLOSE, FHCPM FHCPM = -1 return, 0 END PRO SETCONFIG COMMON COMDIRS OPENw, un, CFGFIL, /GET_LUN, ERROR=err IF err NE 0 THEN RETURN PRINTF, un, CPMBAS & PRINTF, un, POLBAS & PRINTF, un, MODBAS CLOSE, un END PRO GETCONFIG COMMON COMDIRS OPENR, un, CFGFIL, /GET_LUN, ERROR=err CPMBAS = '.'+DIRSEP & POLBAS = '.'+DIRSEP & MODBAS = '.'+DIRSEP IF err NE 0 THEN BEGIN SETCONFIG ENDIF ELSE BEGIN READF, un, CPMBAS & READF, un, POLBAS & READF, un, MODBAS CLOSE, un ENDELSE END ;============================================================================================== ; Cette fonction retourne le chemin d'un fichier Polder ;---------------------------------------------------------------------------------------------- FUNCTION GETPOLPATH, polname COMMON COMDIRS return, SEARCHPATH(POLBAS, polname) END ;============================================================================================== ; Cette fonction retourne le chemin d'un fichier Modis ;---------------------------------------------------------------------------------------------- FUNCTION GETMODPATH, modGname COMMON COMDIRS return, SEARCHPATH(MODBAS, MODPRD+'.'+modGname+'.*.hdf') END ;============================================================================================== ; Cette fonction recherche le chemin d'un fichier dans une arborescence ;---------------------------------------------------------------------------------------------- FUNCTION SEARCHPATH, basedir, fname FORWARD_FUNCTION SearchMacPath, SearchUnxPath, SearchWinPath CASE !VERSION.OS_FAMILY OF 'MacOS' : RETURN, SearchMacPath(basedir, fname) 'unix' : RETURN, SearchUnxPath(basedir, fname) 'Windows': RETURN, SearchWinPath(basedir, fname) ENDCASE END ;---------------------------------------------------------------------------------------------- FUNCTION SearchMacPath, basedir, fname COMMON COMDIRS Result = FINDFILE(basedir+fname, COUNT=pnb) IF pnb EQ 1 THEN return, Result[0] Result = FINDFILE(basedir+'*', COUNT=pnb) FOR i = 2, pnb-1 DO BEGIN IF NOT FILE_TEST(Result[i], /DIRECTORY) THEN CONTINUE p = SearchMacPath(Result[i], fname) IF p NE '' THEN return, p ENDFOR return, '' END ;---------------------------------------------------------------------------------------------- FUNCTION SearchUnxPath, basedir, fname COMMON COMDIRS Result = FINDFILE(basedir+fname, COUNT=pnb) IF pnb EQ 1 THEN return, Result[0] Result = FINDFILE(basedir, COUNT=pnb) FOR i = 0, pnb-1 DO BEGIN IF NOT (FILE_TEST(basedir+Result[i], /DIRECTORY) OR $ FILE_TEST(basedir+Result[i], /SYMLINK)) THEN CONTINUE p = SearchUnxPath(basedir+Result[i]+'/', fname) IF p NE '' THEN return, p ENDFOR return, '' END ;---------------------------------------------------------------------------------------------- FUNCTION SearchWinPath, basedir, fname COMMON COMDIRS Result = FINDFILE(basedir+fname, COUNT=pnb) IF pnb EQ 1 THEN return, Result[0] Result = FINDFILE(basedir+'*', COUNT=pnb) FOR i = 2, pnb-1 DO BEGIN IF NOT FILE_TEST(Result[i], /DIRECTORY) THEN CONTINUE p = SearchWinPath(Result[i], fname) IF p NE '' THEN return, p ENDFOR return, '' END ;============================================================================================== ; Cette fonction retourne un champ a partir du numero du SDS et du nom du parametre ;---------------------------------------------------------------------------------------------- FUNCTION GETHDFPAR, idfile, name id_par = HDF_SD_NAMETOINDEX(idfile, name) id = HDF_SD_SELECT(idfile, id_par) HDF_SD_GETDATA, id, par RETURN, par END ;============================================================================================== ; Cette fonction lit un fichier modis, recupere lat et lon, et interpole les coordonnées ; geographiques sur la meme grille que les données ;---------------------------------------------------------------------------------------------- PRO extrapolate_modis, par, par_int, DeroulId, w0, w s = SIZE(par) Ncol = s[1] & Nlin = s[2] & Ncol_i = 5*Ncol-1 & Nlin_i = 5*Nlin X = (INDGEN(Ncol_i)+3.)/5. ; Interpolation suivant les colonnes. Tous les 5 points Y = (INDGEN(10 )+3.)/5. ; Interpolation suivant les lignes. Tous les 5 points par_int = FLTARR(Ncol_i, Nlin_i) & par2 = FLTARR(Ncol+2, 4) FOR iline = 0, Nlin-1, 2 DO BEGIN ; Boucle sur les bandeaux IF (iline MOD 50) EQ 0 THEN WIDGET_CONTROL, DeroulId, SCR_XSIZE=FIX(w0 + w*iline/FLOAT(Nlin)) par2[1:Ncol, 1:2] = par[*, iline:iline+1] par2[*, 0] = 2*par2[*, 1] - par2[*, 2] & par2[*, 3] = 2*par2[*, 2] - par2[*, 1] par2[0, *] = 2*par2[1, *] - par2[2, *] & par2[Ncol+1, *] = 2*par2[Ncol, *] - par2[Ncol-1, *] par_int[*, 5*iline:5*iline+9] = INTERPOLATE(par2, X, Y, /GRID) ENDFOR WIDGET_CONTROL, DeroulId, SCR_XSIZE=FIX(w0 + w) END ;============================================================================================== ; Cette fonction recupère des reflectances Modis ;---------------------------------------------------------------------------------------------- FUNCTION getReflectance, sdid, sdsName, dim0p, M, testTab, TMRef, TMVal, canaux, DeroulId, w0, w sel = where(testTab, nch) IF nch LE 0 THEN return, 0 PRINT, ' Lecture canaux Modis à '+canaux id = HDF_SD_SELECT(sdid, HDF_SD_NAMETOINDEX(sdid, sdsName)) HDF_SD_GETDATA, id, Mref ; On récupère les paramètres d'étalonnage HDF_SD_ATTRINFO, id, HDF_SD_ATTRFIND(id, 'reflectance_scales') , DATA=Ref_Scale HDF_SD_ATTRINFO, id, HDF_SD_ATTRFIND(id, 'reflectance_offsets'), DATA=Ref_Offset FOR i = 0, nch - 1 DO BEGIN WIDGET_CONTROL, DeroulId, SCR_XSIZE=FIX(w0 + w*(i+1)/FLOAT(nch)) TMRef[*, *, dim0p+i] = (Mref[*, *, M[i]] - Ref_Offset[M[i]])*Ref_Scale[M[i]] TMVal[*, *, dim0p+i] = Mref[*, *, M[i]] LE 32767 END WIDGET_CONTROL, DeroulId, SCR_XSIZE=FIX(w0 + w) return, nch END ;============================================================================== ; Cette procédure réinitialise le Display ;---------------------------------------------------------------------------------------------- PRO InitDisplay, disp, clr COMMON COMDIRS IF clr THEN DeleteWindows tvlct, r, g, b, /get & N = 0 r[N] = 0 & g[N] = 0 & b[N] = 0 & N = N + 1 r[N] = 255 & g[N] = 0 & b[N] = 0 & N = N + 1 r[N] = 0 & g[N] = 255 & b[N] = 0 & N = N + 1 r[N] = 0 & g[N] = 0 & b[N] = 255 & N = N + 1 r[N] = 255 & g[N] = 255 & b[N] = 255 & N = N + 1 tvlct,r,g,b !P.BACKGROUND = N - 1 & !P.COLOR = 0 DEVICE, DECOMPOSE=0 WSET, disp ERASE END ;============================================================================== ; Cette procédure supprime les fenêtres et en actualise la liste ;------------------------------------------------------------------------------ PRO DeleteWindows COMMON COMDIRS for i = 0, N_ELEMENTS(OW) - 1 DO IF OW[i] GE 0 THEN WDelete, OW[i] OW = OW[0:0] & OW[0] = -1 END ;============================================================================== ; Cette procédure informe sur le déroulement d'une comparaison ;------------------------------------------------------------------------------ PRO PrintStep, widbase, msg WIDGET_CONTROL, WIDGET_INFO(widbase, FIND_BY_UNAME='TDeroul'), /SENSITIVE, SET_VALUE=msg END