!! Copyright (C) Stichting Deltares, 2005-2020. !! !! This file is part of iMOD. !! !! This program is free software: you can redistribute it and/or modify !! it under the terms of the GNU General Public License as published by !! the Free Software Foundation, either version 3 of the License, or !! (at your option) any later version. !! !! This program is distributed in the hope that it will be useful, !! but WITHOUT ANY WARRANTY; without even the implied warranty of !! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the !! GNU General Public License for more details. !! !! You should have received a copy of the GNU General Public License !! along with this program. If not, see . !! !! Contact: imod.support@deltares.nl !! Stichting Deltares !! P.O. Box 177 !! 2600 MH Delft, The Netherlands. !! MODULE MOD_IDFTIMESERIE USE WINTERACTER USE RESOURCE USE MODPLOT USE MOD_MAIN_UTL USE MOD_IDFPLOT USE MOD_DBL USE MOD_QKSORT USE IMODVAR, ONLY : DP_KIND,SP_KIND,IDIAGERROR USE MOD_COLOURS, ONLY : ICOLOR USE MOD_PREF_PAR, ONLY : PREFVAL USE MOD_IDF, ONLY : IDFREAD,IDFGETVAL,IDFDEALLOCATEX,IDFOPEN,IDFIROWICOL,IDFNULLIFY USE MOD_IDF_PAR,ONLY : IDFOBJ USE MOD_GRAPH, ONLY : GRAPH_PLOTAXES,AXESOBJ,GRAPHUNITS,GRAPHAREA USE MOD_UTL, ONLY : ITOS,UTL_DIRINFO,UTL_PLOTLOCATIONIDF,UTL_GETRELEVANTDIR,UTL_CAP,UTL_GETAXESCALES,SXVALUE,SYVALUE,NSX,NSY, & UTL_JDATETOIDATE,UTL_FILLDATES,JD,UTL_MESSAGEHANDLE,RTOS,JD,JDATETOGDATE,& UTL_GETUNIT,UTL_HIDESHOWDIALOG,UTL_IDATETOJDATE,UTL_DRAWLEGENDBOX,UTL_IDFGETDATES,UTL_IDFGETDATE, & UTL_PLOT1BITMAP,UTL_PLOT2BITMAP,UTL_WSELECTFILE,JDATETOFDATE,UTL_IMODVERSION,ITIMETOGDATE,UTL_JDATETOIDATE, & UTL_GETHELP USE MOD_IDFGETVALUE, ONLY : IDFGETVALUE_FIELDS USE MOD_MANAGER_UTL, ONLY : MANAGER_UTL_UPDATE,MANAGER_UTL_CLOSE,MANAGER_UTL_ADDFILE USE MOD_IDFTIMESERIE_UTL USE MOD_IDFTIMESERIE_PAR USE MOD_IPF, ONLY : IPFINIT,IPFDEALLOCATE,IPFREAD USE MOD_IPFGETVALUE, ONLY : IPFGETVALUE_MOUSEMOVE,ISEL,JIPF,IPFGETVALUE_ADJIP,IPFGETVALUE_PLOTCURRENTPOS USE MOD_IPFASSFILE, ONLY : IPFDIMENSIONASSFILE USE MOD_IPFASSFILE_UTL USE MOD_IPF_PAR, ONLY : NIPF,IPF,ASSF USE DATEVAR USE MOD_IPF_LABEL, ONLY : IMOD3D_LABELS USE MOD_OSD, ONLY : OSD_OPEN,OSD_TIMER REAL(KIND=DP_KIND),PRIVATE :: XMIN,XMAX,YMIN,YMAX,Y2MIN,Y2MAX,XINT,YINT,Y2INT !## graph dimensions INTEGER,PRIVATE :: IDURATION CONTAINS !###====================================================================== SUBROUTINE IDFTIMESERIE_MAIN() !###====================================================================== IMPLICIT NONE TYPE(WIN_MESSAGE) :: MESSAGE INTEGER :: ITYPE,IDOWN,NDOWN,I,J,IFIX,IWINDOW,IROW,ICOL,IPLOT,JROW,JCOL REAL(KIND=DP_KIND) :: X,Y,MOUSEX,MOUSEY CALL MAIN_UTL_INACTMODULE(ID_TIMESERIES) IF(IDIAGERROR.EQ.1)RETURN CALL WMENUSETSTATE(ID_TIMESERIES,2,1) !## close manager if opened! CALL UTL_HIDESHOWDIALOG(ID_DMANAGER,0) CALL WDIALOGLOAD(ID_DTIMESERIES,ID_DTIMESERIES) !## open Date select window and open IDF files IF(.NOT.IDFTIMESERIE_INIT())THEN CALL IDFTIMESERIE_CLOSE() RETURN ENDIF CALL IDFTIMESERIE_INITBITMAP() CALL WINDOWSELECT(0) ICLRRASTER=WRGB(220,220,220) CALL IDFTIMESERIE_FIELDSMAINMENU(0) CALL WDIALOGSELECT(ID_DTIMESERIES) CALL UTL_DIALOGSHOW(-0,65,0,2) IDOWN = 0 NDOWN = 0 !## number of downs X = 0.0D0 Y = 0.0D0 ISEL = 0 IFIX = 0 IWINDOW= 0 NPLUS = 0 !## nothing yet added to ipf file JROW =0 JCOL =0 CALL IDFTIMESERIE_START(IDOWN,NDOWN) !## start hoovering DO CALL WMESSAGE(ITYPE,MESSAGE) MOUSEX=DBLE(MESSAGE%GX)+OFFSETX MOUSEY=DBLE(MESSAGE%GY)+OFFSETY SELECT CASE (ITYPE) CASE (MENUSELECT) CALL WINDOWSELECT(MPW%IWIN) CALL IGRSELECT(DRAWWIN,MPW%IWIN) CALL DBL_IGRAREA(0.0D0,0.0D0,1.0D0,1.0D0) CALL DBL_IGRUNITS(MPW%XMIN,MPW%YMIN,MPW%XMAX,MPW%YMAX,IOFFSET=1) !## what to overtake ??? ! CALL IMOD1MENUSELECT(MESSAGE) CALL IDFTIMESERIE_INITFILES(NDOWN,X,Y) !## mouse-move CASE (MOUSEMOVE) IF(MESSAGE%WIN.EQ.MPW%IWIN)THEN IF(IWINDOW.EQ.MESSAGE%WIN)THEN CALL WINDOWSELECT(0) CALL WINDOWOUTSTATUSBAR(1,'X:'//TRIM(RTOS(MOUSEX,'G',7))//' m, Y:'//TRIM(RTOS(MOUSEY,'G',7))//' m') IF(IDOWN.EQ.1)THEN IF(NIPF.GT.0)THEN IF(IFIX.EQ.0)THEN !## remove previous one - if available IF(ISEL.NE.0)CALL IPFGETVALUE_ADJIP(1,5) !## leftmouse pressed, give number 5 CALL IPFGETVALUE_MOUSEMOVE(MOUSEX,MOUSEY,0,ID_DTIMESERIES) !## set new one CALL IPFGETVALUE_ADJIP(1,5) !## leftmouse pressed, give number 5 ENDIF ENDIF IF(WINFOMOUSE(MOUSECURSOR).NE.ID_CURSORIDFVALUE)CALL WCURSORSHAPE(ID_CURSORIDFVALUE) !## get new column/row numbers CALL IDFIROWICOL(IDF(1,1),IROW,ICOL,MOUSEX,MOUSEY) IF((JROW.EQ.0.AND.JCOL.EQ.0).OR. & (IROW.NE.JROW.OR.ICOL.NE.JCOL))THEN IF(JROW.NE.0.AND.JCOL.NE.0)THEN CALL IGRCOLOURN(WRGB(255,255,255)) CALL UTL_PLOTLOCATIONIDF(IDF(1,1),JROW,JCOL) ENDIF !## get irow/icol current idf X=MOUSEX; Y=MOUSEY CALL IDFTIMESERIE_CALC(X,Y,0) CALL IDFTIMESERIE_IPF() !## if duration lines to be plotted, sort results CALL IDFTIMESERIE_DURATION() CALL IDFTIMESERIES_RESIDUALS() CALL IDFTIMESERIE_PLOT(X,Y) CALL IGRCOLOURN(WRGB(255,255,255)) CALL UTL_PLOTLOCATIONIDF(IDF(1,1),IROW,ICOL) JCOL=ICOL; JROW=IROW ENDIF ELSE IF(WINFOMOUSE(MOUSECURSOR).NE.CURARROW)CALL WCURSORSHAPE(CURARROW) ENDIF ELSE IF(WINFOMOUSE(MOUSECURSOR).NE.CURARROW)CALL WCURSORSHAPE(CURARROW) ENDIF !## reset to entire window CALL WINDOWSELECT(MPW%IWIN) CALL IGRSELECT(DRAWWIN,MPW%IWIN) CALL DBL_IGRAREA(0.0D0,0.0D0,1.0D0,1.0D0) CALL DBL_IGRUNITS(MPW%XMIN,MPW%YMIN,MPW%XMAX,MPW%YMAX,IOFFSET=1) IWINDOW=MESSAGE%WIN ELSEIF(MESSAGE%WIN.EQ.ID_DTIMESERIESTAB1)THEN IF(WINFOMOUSE(MOUSECURSOR).NE.CURCROSSHAIR)CALL WCURSORSHAPE(CURCROSSHAIR) IF(NDOWN.GT.0.AND.SUM(NFILES).GT.0)THEN IF(IWINDOW.EQ.MESSAGE%WIN)CALL IDFTIMESERIE_PLOTXY(REAL(MESSAGE%GX,8),REAL(MESSAGE%GY,8)) !## childwindow - size for the bitmap CALL WDIALOGSELECT(ID_DTIMESERIESTAB1) CALL IGRSELECT(DRAWFIELD,IDF_PICTURE1) CALL DBL_IGRAREA(0.0D0,0.0D0,1.0D0,1.0D0) CALL DBL_IGRUNITS(GRAPHUNITS(1,1),GRAPHUNITS(2,1),GRAPHUNITS(3,1),GRAPHUNITS(4,1)) IWINDOW=MESSAGE%WIN ENDIF ENDIF CASE (TABCHANGED) SELECT CASE (MESSAGE%VALUE2) CASE (ID_DTIMESERIESTAB1) CALL IDFTIMESERIE_PLOT(X,Y) END SELECT CASE (MOUSEBUTDOWN) SELECT CASE (MESSAGE%VALUE1) CASE (1) IF(IDOWN.EQ.1)THEN CALL IDFTIMESERIE_CALC(X,Y,1) CALL IDFTIMESERIE_IPF() !## if duration lines to be plotted, sort results CALL IDFTIMESERIE_DURATION() CALL IDFTIMESERIES_RESIDUALS() CALL IDFTIMESERIE_PLOT(X,Y) ENDIF CASE (3) IF(IDOWN.EQ.1)THEN !## turn on preference tab ... CALL WDIALOGSELECT(ID_DTIMESERIES) CALL WDIALOGTABSTATE(IDF_TAB,ID_DTIMESERIESTAB2,1) IDOWN =0 CALL WDIALOGSELECT(ID_DTIMESERIESTAB1) CALL WDIALOGFIELDSTATE(ID_DRAW,1) CALL WCURSORSHAPE(CURARROW) !## get irow/icol current idf CALL IDFTIMESERIE_CALC(X,Y,1) CALL IDFTIMESERIE_IPF() !## if duration lines to be plotted, sort results CALL IDFTIMESERIE_DURATION() CALL IDFTIMESERIES_RESIDUALS() CALL IDFTIMESERIE_PLOT(X,Y) CALL WDIALOGSELECT(ID_DTIMESERIES) CALL WDIALOGPUTSTRING(IDF_LABEL2,'') ENDIF END SELECT CASE (PUSHBUTTON) SELECT CASE (MESSAGE%WIN) CASE (ID_DTIMESERIES) SELECT CASE (MESSAGE%VALUE1) CASE (IDHELP) CALL UTL_GETHELP('5.2.1','TMO.TT.DrawTS') CASE (IDCANCEL,ID_CLOSE) EXIT END SELECT CASE (ID_DTIMESERIESTAB1) SELECT CASE (MESSAGE%VALUE1) CASE (ID_ZOOMFULL) CALL IDFTIMESERIE_ZOOMFULL(X,Y) CASE (ID_ZOOMBOX,ID_ZOOMIN,ID_ZOOMOUT,ID_MOVE) CALL IDFTIMESERIE_ZOOM(MESSAGE%VALUE1,X,Y) !## add current point to the opened ipf file CASE (ID_PLUS) CALL IDFTIMESERIE_PLUS(X,Y) CASE (ID_PLUSSAVE) CALL IDFTIMESERIE_PLUSSAVE() CASE (ID_PLUSLOAD) CALL IDFTIMESERIE_PLUSLOAD() CASE (ID_DRAW) CALL IDFTIMESERIE_START(IDOWN,NDOWN) CASE (ID_SAVEAS) CALL IDFTIMESERIE_SAVE() CASE (ID_COPY) CALL WCLIPBOARDPUTBITMAP(IDFS_IBITMAP) CASE (ID_LEGEND) CALL IDFTIMESERIE_LEGENDCOLOUR(X,Y) END SELECT CASE (ID_DTIMESERIESTAB2) SELECT CASE (MESSAGE%VALUE1) END SELECT CASE (ID_DTIMESERIESTAB3) SELECT CASE (MESSAGE%VALUE1) CASE (IDF_LABELING) J=0 DO IPLOT=1,MXMPLOT IF(MP(IPLOT)%ISEL.AND.MP(IPLOT)%IPLOT.EQ.2)THEN J=J+1 IF(J.EQ.JIPF)EXIT ENDIF ENDDO CALL IMOD3D_LABELS(JIPF,IPLOT) CALL IDFPLOTFAST(0) CALL IDFTIMESERIE_INITFILES(NDOWN,X,Y) END SELECT END SELECT CASE (FIELDCHANGED) SELECT CASE (MESSAGE%WIN) CASE (ID_DTIMESERIES) SELECT CASE (MESSAGE%VALUE1) END SELECT CASE (ID_DTIMESERIESTAB1) SELECT CASE (MESSAGE%VALUE1) END SELECT CASE (ID_DTIMESERIESTAB2) SELECT CASE (MESSAGE%VALUE1) !## new field CASE (IDF_CHECK1,IDF_CHECK2) CALL WDIALOGSELECT(ID_DTIMESERIESTAB2) CALL IDFTIMESERIE_FIELDS(IDURATION) !## date changed CASE (IDF_INTEGER1,IDF_MENU1,IDF_INTEGER2, & IDF_INTEGER3,IDF_MENU2,IDF_INTEGER4) CALL WDIALOGSELECT(ID_DTIMESERIESTAB2) CALL IDFTIMESERIE_FIELDS(IDURATION) !## switch to duration lines CASE (IDF_CHECK3) CALL IDFTIMESERIE_DURATION_FIELDS() CALL IDFTIMESERIE_CALC(X,Y,1) CALL IDFTIMESERIE_IPF() !## if duration lines to be plotted, sort results CALL IDFTIMESERIE_DURATION() CALL IDFTIMESERIES_RESIDUALS() CALL IDFTIMESERIE_PLOT(X,Y) !## compute residuals CASE (IDF_CHECK4) CALL IDFTIMESERIE_RESIDUAL_FIELDS() CALL IDFTIMESERIES_RESIDUALS() CALL IDFTIMESERIE_PLOT(X,Y) !## fix secondary y-axes CASE (IDF_CHECK5) CALL IDFTIMESERIE_RESIDUAL_FIELDS() END SELECT CASE (ID_DTIMESERIESTAB3) SELECT CASE (MESSAGE%VALUE1) !## variable point/fixed point for ipf CASE (IDF_CHECK1) CALL WDIALOGSELECT(ID_DTIMESERIESTAB3) CALL WDIALOGGETCHECKBOX(IDF_CHECK1,IFIX) END SELECT END SELECT !## bitmap scrolled, renew top-left pixel coordinates CASE (BITMAPSCROLLED) MPW%IX=MESSAGE%VALUE1 MPW%IY=MESSAGE%VALUE2 CASE (EXPOSE,RESIZE) ! IF(MESSAGE%WIN.EQ.0)CALL IMOD1EXPOSERESIZE() IF(MESSAGE%WIN.EQ.ID_DTIMESERIESTAB1.AND.SUM(NFILES).NE.0)THEN CALL IDFTIMESERIE_INITBITMAP() CALL IDFTIMESERIE_PLOT(X,Y) ENDIF END SELECT END DO !## has been a timeserie plotted IF(NDOWN.GT.0)THEN CALL IGRCOLOURN(WRGB(255,255,255)) CALL IDFIROWICOL(IDF(1,1),IROW,ICOL,X,Y) CALL UTL_PLOTLOCATIONIDF(IDF(1,1),IROW,ICOL) IF(NIPF.GT.0)THEN CALL IPFGETVALUE_PLOTCURRENTPOS() !## remove previous one - if available DO I=1,NIPF; IPF(1)%IP=INT(0,1); ENDDO ENDIF ENDIF CALL IDFTIMESERIE_CLOSE() END SUBROUTINE IDFTIMESERIE_MAIN !###==================================================================== SUBROUTINE IDFTIMESERIE_START(IDOWN,NDOWN) !###==================================================================== IMPLICIT NONE INTEGER,INTENT(OUT) :: IDOWN,NDOWN INTEGER :: I IDOWN=1 NDOWN=NDOWN+1 CALL WDIALOGSELECT(ID_DTIMESERIES) CALL WDIALOGPUTSTRING(IDF_LABEL2,'Press RIGHT mouse button to stop hoovering') !## turn off preference tab ... CALL WDIALOGTABSTATE(IDF_TAB,ID_DTIMESERIESTAB2,0) CALL WDIALOGSELECT(ID_DTIMESERIESTAB1) CALL WDIALOGFIELDSTATE(ID_DRAW,0) CALL WCURSORSHAPE(ID_CURSORIDFVALUE) CALL WDIALOGFIELDSTATE(ID_SAVEAS,1) CALL WDIALOGFIELDSTATE(ID_COPY,1) CALL WDIALOGFIELDSTATE(ID_LEGEND,1) CALL WDIALOGFIELDSTATE(IDF_CHECK1,1) CALL WDIALOGFIELDSTATE(ID_ZOOMIN,1) CALL WDIALOGFIELDSTATE(ID_ZOOMOUT,1) CALL WDIALOGFIELDSTATE(ID_ZOOMFULL,1) CALL WDIALOGFIELDSTATE(ID_ZOOMBOX,1) CALL WDIALOGFIELDSTATE(ID_MOVE,1) CALL WDIALOGFIELDSTATE(ID_PLUS,1) CALL WDIALOGFIELDSTATE(IDF_LABEL2,1) CALL WDIALOGCLEARFIELD(IDF_LABEL2) CALL WDIALOGSELECT(ID_DTIMESERIESTAB2) CALL WDIALOGFIELDSTATE(IDF_CHECK1,1) CALL WDIALOGFIELDSTATE(IDF_CHECK2,1) CALL WDIALOGFIELDSTATE(IDF_CHECK3,1) !## residuals only possible whenever... I=0 IF(NIDF.EQ.2.AND.NIPF.EQ.0)I=1 IF(NIDF.EQ.1.AND.NIPF.EQ.1)I=1 CALL WDIALOGFIELDSTATE(IDF_CHECK4,I) END SUBROUTINE IDFTIMESERIE_START !###==================================================================== SUBROUTINE IDFTIMESERIE_INITFILES(NDOWN,X,Y) !###==================================================================== IMPLICIT NONE REAL(KIND=DP_KIND),INTENT(IN) :: X,Y INTEGER,INTENT(IN) :: NDOWN INTEGER :: I,J,IROW,ICOL REAL(KIND=DP_KIND) :: DXY !## reopen files DO I=1,NIDF DO J=1,MFILES(I) CALL WINDOWOUTSTATUSBAR(4,'Re-opening '//TRIM(IDF(I,J)%FNAME)//'...') IF(.NOT.IDFOPEN(IDF(I,J)%IU,IDF(I,J)%FNAME,'RO',IDF(I,J)%ITYPE,0,IQUESTION=0))THEN ENDIF ENDDO ENDDO CALL WINDOWOUTSTATUSBAR(4,'') !## allocate memory for ipf-plotting, they will be read in memory and drawn from that CALL IPFINIT() IF(NIPF.GT.0)THEN IF(.NOT.ALLOCATED(ASSF))CALL IPFASSFILEALLOCATE(1) ENDIF CALL IDFTIMESERIE_INITBITMAP() DXY=(MPW%XMAX-MPW%XMIN)/500.0D0 CALL IDFTIMESERIE_FIELDSMAINMENU(0) !## plot current (last) location IF(NDOWN.GT.0)THEN CALL IGRCOLOURN(WRGB(255,255,255)) CALL IDFIROWICOL(IDF(1,1),IROW,ICOL,X,Y) CALL UTL_PLOTLOCATIONIDF(IDF(1,1),IROW,ICOL) ENDIF !## redraw timeserie to be sure all memory is allocated again CALL IDFTIMESERIE_IPF() END SUBROUTINE IDFTIMESERIE_INITFILES !###==================================================================== SUBROUTINE IDFTIMESERIE_PLOTXY(X,Y) !###==================================================================== REAL(KIND=DP_KIND),INTENT(IN) :: X,Y REAL(KIND=DP_KIND) :: D INTEGER :: I CHARACTER(LEN=20) :: CDATE CALL WDIALOGSELECT(ID_DTIMESERIESTAB1) I=MAXVAL(LTYPE%IAXES)-MINVAL(LTYPE%IAXES) IF(IDURATION.EQ.0)THEN CDATE=JDATETOFDATE(X,MINDATE) IF(I.EQ.0)THEN CALL WDIALOGPUTSTRING(IDF_LABEL2,'Current Value: x-axes: '//TRIM(CDATE)// & '; y-axes : '//TRIM(RTOS(Y,'F',7))) ELSE D=(Y-GRAPHUNITS(2,1))/(GRAPHUNITS(4,1)-GRAPHUNITS(2,1)) D= GRAPHUNITS(5,1)+(D*(GRAPHUNITS(6,1)-GRAPHUNITS(5,1))) CALL WDIALOGPUTSTRING(IDF_LABEL2,'Current Value: x-axes: '//TRIM(CDATE)// & '; y-axes : '//TRIM(RTOS(Y,'F',7))// & '; 2y-axes : '//TRIM(RTOS(D,'F',7))) ENDIF ELSE IF(I.EQ.0)THEN CALL WDIALOGPUTSTRING(IDF_LABEL2,'Current Value: x-axes: '//TRIM(RTOS(X,'F',7))// & '; y-axes : '//TRIM(RTOS(Y,'F',7))) ELSE D=(Y-GRAPHUNITS(2,1))/(GRAPHUNITS(4,1)-GRAPHUNITS(2,1)) D= GRAPHUNITS(5,1)+(D*(GRAPHUNITS(6,1)-GRAPHUNITS(5,1))) CALL WDIALOGPUTSTRING(IDF_LABEL2,'Current Value: x-axes: '//TRIM(RTOS(X,'F',7))// & '; y-axes : '//TRIM(RTOS(Y,'F',7))// & '; 2y-axes : '//TRIM(RTOS(D,'F',7))) ENDIF ENDIF END SUBROUTINE IDFTIMESERIE_PLOTXY !###==================================================================== SUBROUTINE IDFTIMESERIE_PLUS(X,Y) !###==================================================================== IMPLICIT NONE REAL(KIND=DP_KIND),INTENT(IN) :: X,Y IF(.NOT.ASSOCIATED(IPFPLUS))ALLOCATE(IPFPLUS(100)) NPLUS=NPLUS+1 IF(SIZE(IPFPLUS).LT.NPLUS)THEN ALLOCATE(IPFDUM(SIZE(IPFPLUS)*2)) IPFDUM(1:SIZE(IPFPLUS))=IPFPLUS DEALLOCATE(IPFPLUS) IPFPLUS=>IPFDUM DEALLOCATE(IPFDUM) ENDIF IPFPLUS(NPLUS)%X =X IPFPLUS(NPLUS)%Y =Y IPFPLUS(NPLUS)%ID=NPLUS CALL WDIALOGSELECT(ID_DTIMESERIESTAB1) CALL WDIALOGFIELDSTATE(ID_PLUSSAVE,1) CALL WDIALOGPUTSTRING(IDF_LABEL3,'Added '//TRIM(ITOS(NPLUS))//' points') CALL IDFTIMESERIE_PLUSPLOTPOINT() END SUBROUTINE IDFTIMESERIE_PLUS !###==================================================================== SUBROUTINE IDFTIMESERIE_PLUSSAVE() !###==================================================================== IMPLICIT NONE CHARACTER(LEN=256) :: FNAME,LINE INTEGER :: IOS,I,J,IU,JU IF(.NOT.UTL_WSELECTFILE('iMOD Point file (*.ipf)|*.ipf|',SAVEDIALOG+PROMPTON+DIRCHANGE+APPENDEXT,& FNAME,'Save Current Timeseries sequentually within an ipf (*.ipf)'))RETURN IU=UTL_GETUNIT() CALL OSD_OPEN(IU,FILE=FNAME,STATUS='REPLACE',FORM='FORMATTED',ACTION='WRITE',IOSTAT=IOS) IF(IOS.NE.0)THEN CALL WMESSAGEBOX(OKONLY,INFORMATIONICON,COMMONOK,'Cannot write to output file:'//CHAR(13)//TRIM(FNAME),'Info') RETURN ENDIF CALL UTL_MESSAGEHANDLE(0) J=INDEX(FNAME,'\',.TRUE.) WRITE(IU,*) NPLUS WRITE(IU,*) 3 WRITE(IU,*) 'X-coord.' WRITE(IU,*) 'Y-coord.' WRITE(IU,*) 'ID' WRITE(IU,*) '3,TXT' DO I=1,NPLUS LINE=TRIM(RTOS(IPFPLUS(I)%X,'F',3))//','//TRIM(RTOS(IPFPLUS(I)%Y,'F',3))//',ts_'//TRIM(ITOS(IPFPLUS(I)%ID)) WRITE(IU,*) TRIM(LINE) JU=UTL_GETUNIT() LINE=FNAME(:J)//'ts_'//TRIM(ITOS(IPFPLUS(I)%ID))//'.txt' CALL OSD_OPEN(JU,FILE=TRIM(LINE),STATUS='REPLACE',FORM='FORMATTED',ACTION='WRITE',IOSTAT=IOS) IF(IOS.NE.0)THEN CALL WMESSAGEBOX(OKONLY,INFORMATIONICON,COMMONOK,'Cannot write to output file:'//CHAR(13)//TRIM(FNAME),'Info') RETURN ENDIF !## compute timeseries CALL IDFTIMESERIE_CALC(IPFPLUS(I)%X,IPFPLUS(I)%Y,1) !## get ipf point, if available IF(NIPF.GT.0)THEN !## remove previous one - if available IF(ISEL.NE.0)CALL IPFGETVALUE_ADJIP(1,5) !## remove 5 CALL IPFGETVALUE_MOUSEMOVE(IPFPLUS(I)%X,IPFPLUS(I)%Y,0,ID_DTIMESERIES) !## set new one CALL IPFGETVALUE_ADJIP(1,5) !## leftmouse pressed, give number 5 CALL IDFTIMESERIE_IPF() ENDIF !## if duration lines to be plotted, sort results CALL IDFTIMESERIE_DURATION() CALL IDFTIMESERIES_RESIDUALS() CALL IDFTIMESERIE_SAVE_DATA(JU,1) CLOSE(JU) END DO CLOSE(IU) CALL UTL_MESSAGEHANDLE(1) CALL WDIALOGSELECT(ID_DTIMESERIESTAB1) CALL WDIALOGFIELDSTATE(ID_PLUSSAVE,0) NPLUS=0 CALL WDIALOGPUTSTRING(IDF_LABEL3,'None Added') CALL MANAGER_UTL_ADDFILE(FNAME) CALL WMESSAGEBOX(OKONLY,INFORMATIONICON,COMMONYES,'Sucesfully saved IPF-file:'//CHAR(13)//TRIM(FNAME)//CHAR(13)// & 'The file has been added to the iMOD-manager','Information') END SUBROUTINE IDFTIMESERIE_PLUSSAVE !###==================================================================== SUBROUTINE IDFTIMESERIE_PLUSLOAD() !###==================================================================== IMPLICIT NONE CHARACTER(LEN=256) :: FNAME INTEGER :: IOS,I,IU,N !FNAME=TRIM(PREFVAL(1))//'\*.ipf' IF(.NOT.UTL_WSELECTFILE('iMOD Point file (*.ipf)|*.ipf|',LOADDIALOG+PROMPTON+DIRCHANGE+APPENDEXT,& FNAME,'Open ipf to use points (*.ipf)'))RETURN IU=UTL_GETUNIT() CALL OSD_OPEN(IU,FILE=FNAME,STATUS='OLD',FORM='FORMATTED',ACTION='READ,DENYWRITE',IOSTAT=IOS) IF(IOS.NE.0)THEN CALL WMESSAGEBOX(OKONLY,INFORMATIONICON,COMMONOK,'Cannot open IPF:'//CHAR(13)//TRIM(FNAME),'Info') RETURN ENDIF READ(IU,*,IOSTAT=IOS) NPLUS IF(.NOT.IDFTIMESERIE_PLUSLOAD_CLEAR(IOS,IU,'Error reading first record'))RETURN READ(IU,*,IOSTAT=IOS) N IF(.NOT.IDFTIMESERIE_PLUSLOAD_CLEAR(IOS,IU,'Error reading second record'))RETURN DO I=1,N READ(IU,*,IOSTAT=IOS) IF(.NOT.IDFTIMESERIE_PLUSLOAD_CLEAR(IOS,IU,'Error reading attribute label: '//TRIM(ITOS(I))))RETURN END DO READ(IU,*,IOSTAT=IOS) IF(.NOT.IDFTIMESERIE_PLUSLOAD_CLEAR(IOS,IU,'Error reading txtcol and/or extent'))RETURN IF(.NOT.ASSOCIATED(IPFPLUS))ALLOCATE(IPFPLUS(MAX(100,NPLUS))) DO I=1,NPLUS READ(IU,*,IOSTAT=IOS) IPFPLUS(I)%X,IPFPLUS(I)%Y IF(.NOT.IDFTIMESERIE_PLUSLOAD_CLEAR(IOS,IU,'Error reading record '//TRIM(ITOS(I))))RETURN IPFPLUS(I)%ID=I END DO CLOSE(IU) NPLUS=I-1 CALL WDIALOGSELECT(ID_DTIMESERIESTAB1) CALL WDIALOGFIELDSTATE(ID_PLUSSAVE,1) ! IPFPLUS(NPLUS)%ID=NPLUS CALL WDIALOGSELECT(ID_DTIMESERIESTAB1) CALL WDIALOGFIELDSTATE(ID_PLUSSAVE,1) CALL WDIALOGPUTSTRING(IDF_LABEL3,'Added '//TRIM(ITOS(NPLUS))//' points') CALL IDFTIMESERIE_PLUSPLOTPOINT() END SUBROUTINE IDFTIMESERIE_PLUSLOAD !###==================================================================== LOGICAL FUNCTION IDFTIMESERIE_PLUSLOAD_CLEAR(IOS,IU,TXT) !###==================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: IOS,IU CHARACTER(LEN=*),INTENT(IN) :: TXT IDFTIMESERIE_PLUSLOAD_CLEAR=.TRUE. IF(IOS.EQ.0)RETURN CLOSE(IU) CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,TRIM(TXT),'Error') IDFTIMESERIE_PLUSLOAD_CLEAR=.FALSE. END FUNCTION IDFTIMESERIE_PLUSLOAD_CLEAR !###==================================================================== SUBROUTINE IDFTIMESERIE_ZOOM(IDZ,X,Y) !###==================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: IDZ REAL(KIND=DP_KIND),INTENT(IN) :: X,Y REAL(KIND=DP_KIND),PARAMETER :: FZIN =0.75 REAL(KIND=DP_KIND),PARAMETER :: FZOUT=1.5 TYPE(WIN_MESSAGE) :: MESSAGE INTEGER :: ITYPE,IDOWN,IDCURSOR,I REAL(KIND=DP_KIND) :: FZ,XC1,YC1,XC2,YC2,XC3,YC3,DX,DY LOGICAL :: LEX INTEGER,DIMENSION(11) :: ID DATA ID/ID_DRAW,ID_SAVEAS,ID_COPY,ID_PLUS,ID_PLUSSAVE,ID_LEGEND,ID_ZOOMIN,ID_ZOOMOUT,ID_ZOOMFULL,ID_ZOOMBOX,ID_MOVE/ CALL WDIALOGSELECT(ID_DTIMESERIES) CALL WDIALOGTABSTATE(IDF_TAB,ID_DTIMESERIESTAB2,0) CALL WDIALOGTABSTATE(IDF_TAB,ID_DTIMESERIESTAB3,0) CALL WDIALOGSELECT(ID_DTIMESERIESTAB2) CALL WDIALOGPUTCHECKBOX(IDF_CHECK1,0) !## x -axes CALL WDIALOGPUTCHECKBOX(IDF_CHECK2,0) !## y -axes IF(MAXVAL(LTYPE%IAXES).NE.MINVAL(LTYPE%IAXES))THEN CALL WDIALOGPUTCHECKBOX(IDF_CHECK5,1) !## fix y2-axes ELSE CALL WDIALOGPUTCHECKBOX(IDF_CHECK5,0) !## inactivate y2-axes ENDIF CALL IDFTIMESERIE_FIELDS(IDURATION) CALL IDFTIMESERIE_RESIDUAL_FIELDS() CALL WDIALOGSELECT(ID_DTIMESERIESTAB1) DO I=1,SIZE(ID); IF(ID(I).NE.IDZ)CALL WDIALOGFIELDSTATE(ID(I),0); END DO !## childwindow - size for the bitmap CALL WDIALOGSELECT(ID_DTIMESERIESTAB1) CALL IGRSELECT(DRAWFIELD,IDF_PICTURE1) CALL DBL_IGRAREA(0.0D0,0.0D0,1.0D0,1.0D0) CALL DBL_IGRUNITS(GRAPHUNITS(1,1),GRAPHUNITS(2,1),GRAPHUNITS(3,1),GRAPHUNITS(4,1)) IF(IDZ.EQ.ID_ZOOMIN)THEN FZ=FZIN; IDCURSOR=ID_CURSORPOINTPLUS ELSEIF(IDZ.EQ.ID_ZOOMOUT)THEN FZ=FZOUT; IDCURSOR=ID_CURSORPOINTMIN ELSEIF(IDZ.EQ.ID_ZOOMBOX)THEN IDCURSOR=ID_CURSORZOOMRECTANGLE ELSEIF(IDZ.EQ.ID_MOVE)THEN IDCURSOR=ID_CURSORHAND ENDIF CALL WCURSORSHAPE(IDCURSOR) IDOWN=0 LEX =.FALSE. XC1 =0.0D0 YC1 =0.0D0 DO CALL WMESSAGE(ITYPE, MESSAGE) IF(MESSAGE%WIN.EQ.ID_DTIMESERIESTAB1)THEN SELECT CASE(ITYPE) CASE(MOUSEMOVE) CALL IDFTIMESERIE_PLOTXY(REAL(MESSAGE%GX,8),REAL(MESSAGE%GY,8)) XC2=DBLE(MESSAGE%GX) YC2=DBLE(MESSAGE%GY) IF(IDZ.EQ.ID_MOVE)THEN IF(IDOWN.GT.0)THEN DX=XC1-XC2 DY=YC1-YC2 XMAX=XMAX+DX XMIN=XMIN+DX YMAX=YMAX+DY YMIN=YMIN+DY CALL IDFTIMESERIES_ZOOMUPDATE(X,Y) ENDIF ELSEIF(IDZ.EQ.ID_ZOOMBOX)THEN IF(IDOWN.GT.0)THEN !## select proper bitmap CALL IGRSELECT(DRAWBITMAP,IDFS_IBITMAP) CALL DBL_IGRAREA(0.0D0,0.0D0,1.0D0,1.0D0) CALL DBL_IGRUNITS(GRAPHUNITS(1,1),GRAPHUNITS(2,1),GRAPHUNITS(3,1),GRAPHUNITS(4,1)) CALL IGRPLOTMODE(MODEXOR) CALL IGRCOLOURN(WRGB(255,255,255)) CALL IGRFILLPATTERN(OUTLINE) CALL IGRLINETYPE(DASHED) IF(LEX)CALL DBL_IGRRECTANGLE(XC1,YC1,XC3,YC3) LEX=.FALSE. IF(IDOWN.EQ.1)THEN IF(XC1.NE.XC2.AND.YC1.NE.YC2)LEX=.TRUE. IF(LEX)CALL DBL_IGRRECTANGLE(XC1,YC1,XC2,YC2) ENDIF CALL WDIALOGSELECT(ID_DTIMESERIESTAB1) CALL IGRSELECT(DRAWFIELD,IDF_PICTURE1) CALL WBITMAPPUT(IDFS_IBITMAP,0,1) !## childwindow - size for the bitmap CALL WDIALOGSELECT(ID_DTIMESERIESTAB1) CALL IGRSELECT(DRAWFIELD,IDF_PICTURE1) CALL DBL_IGRAREA(0.0D0,0.0D0,1.0D0,1.0D0) CALL DBL_IGRUNITS(GRAPHUNITS(1,1),GRAPHUNITS(2,1),GRAPHUNITS(3,1),GRAPHUNITS(4,1)) ENDIF ENDIF XC3=XC2 YC3=YC2 CASE (MOUSEBUTUP) IF(IDZ.EQ.ID_MOVE)THEN SELECT CASE (MESSAGE%VALUE1) CASE (1) CALL WCURSORSHAPE(ID_CURSORHAND) IDOWN=0 END SELECT ENDIF CASE (MOUSEBUTDOWN) IF(IDZ.EQ.ID_ZOOMIN.OR.IDZ.EQ.ID_ZOOMOUT)THEN SELECT CASE (MESSAGE%VALUE1) CASE (1) XC2 = XC3 YC2 = YC3 DX = XMAX-XMIN DY = YMAX-YMIN XMAX= XC2+0.5*DX*FZ XMIN= XC2-0.5*DX*FZ YMIN= YC2-0.5*DY*FZ YMAX= YC2+0.5*DY*FZ CALL IDFTIMESERIES_ZOOMUPDATE(X,Y) CASE (3) EXIT END SELECT ELSEIF(IDZ.EQ.ID_MOVE)THEN SELECT CASE (MESSAGE%VALUE1) CASE (1) IF(IDOWN.EQ.0)THEN XC1 =XC2 YC1 =YC2 IDOWN=1 CALL WCURSORSHAPE(ID_CURSORHANDGREP) ENDIF CASE (3) EXIT END SELECT ELSEIF(IDZ.EQ.ID_ZOOMBOX)THEN SELECT CASE (MESSAGE%VALUE1) CASE (1) IF(IDOWN.EQ.0)THEN XC1 =XC2 YC1 =YC2 IDOWN=1 ELSE XMAX=MAX(XC1,XC3) XMIN=MIN(XC1,XC3) YMAX=MAX(YC1,YC3) YMIN=MIN(YC1,YC3) EXIT ENDIF END SELECT ENDIF END SELECT ENDIF ENDDO CALL WCURSORSHAPE(CURARROW) IF(IDZ.EQ.ID_ZOOMBOX)THEN CALL IGRPLOTMODE(MODECOPY) CALL IGRLINETYPE(SOLIDLINE) ENDIF CALL IDFTIMESERIES_ZOOMUPDATE(X,Y) CALL WDIALOGSELECT(ID_DTIMESERIES) CALL WDIALOGTABSTATE(IDF_TAB,ID_DTIMESERIESTAB2,1) IF(NIPF.GT.0)CALL WDIALOGTABSTATE(IDF_TAB,ID_DTIMESERIESTAB3,1) CALL WDIALOGSELECT(ID_DTIMESERIESTAB2) CALL WDIALOGPUTCHECKBOX(IDF_CHECK1,1) CALL WDIALOGPUTCHECKBOX(IDF_CHECK2,1) CALL IDFTIMESERIE_FIELDS(IDURATION) CALL IDFTIMESERIE_RESIDUAL_FIELDS() CALL WDIALOGSELECT(ID_DTIMESERIESTAB1) DO I=1,SIZE(ID); IF(ID(I).NE.IDZ)CALL WDIALOGFIELDSTATE(ID(I),1); END DO END SUBROUTINE IDFTIMESERIE_ZOOM !###==================================================================== SUBROUTINE IDFTIMESERIE_ZOOMFULL(X,Y) !###==================================================================== IMPLICIT NONE REAL(KIND=DP_KIND),INTENT(IN) :: X,Y CALL WDIALOGSELECT(ID_DTIMESERIESTAB2) CALL WDIALOGPUTCHECKBOX(IDF_CHECK1,0) CALL WDIALOGPUTCHECKBOX(IDF_CHECK2,0) CALL WDIALOGPUTCHECKBOX(IDF_CHECK5,0) CALL IDFTIMESERIE_FIELDS(IDURATION) CALL IDFTIMESERIE_RESIDUAL_FIELDS() CALL WDIALOGSELECT(ID_DTIMESERIESTAB1) CALL IDFTIMESERIE_PLOT(X,Y) END SUBROUTINE IDFTIMESERIE_ZOOMFULL !###====================================================================== SUBROUTINE IDFTIMESERIES_ZOOMUPDATE(X,Y) !###====================================================================== IMPLICIT NONE REAL(KIND=DP_KIND),INTENT(IN) :: X,Y INTEGER :: I CALL WDIALOGSELECT(ID_DTIMESERIESTAB2) I=5; AXES%XINT=(XMAX-XMIN)/REAL(I) ! !## get nice axes finally ! IF(ICODE.EQ.1)CALL UTL_GETAXESCALES(XMIN,YMIN,XMAX,YMAX) ! IF(ICODE.EQ.0)THEN CALL IDFTIMESERIE_PUTMINMAXX(XMIN,XMAX,AXES%XINT,IDURATION) ! ELSE ! CALL IDFTIMESERIE_PUTMINMAXX(SXVALUE(1),SXVALUE(NSX),SXVALUE(2)-SXVALUE(1),IDURATION) ! ENDIF CALL WDIALOGPUTCHECKBOX(IDF_CHECK1,1) I=5; AXES%YINT=(YMAX-YMIN)/REAL(I) ! IF(ICODE.EQ.0)THEN CALL IDFTIMESERIE_PUTMINMAXY(YMIN,YMAX,AXES%YINT) ! ELSE ! CALL IDFTIMESERIE_PUTMINMAXY(SYVALUE(1),SYVALUE(NSY),SYVALUE(2)-SYVALUE(1)) ! ENDIF CALL WDIALOGPUTCHECKBOX(IDF_CHECK2,1) CALL IDFTIMESERIE_FIELDS(IDURATION) CALL IDFTIMESERIE_PLOT(X,Y) CALL WDIALOGSELECT(ID_DTIMESERIESTAB2) CALL WDIALOGPUTCHECKBOX(IDF_CHECK1,0) CALL WDIALOGPUTCHECKBOX(IDF_CHECK2,0) CALL WDIALOGSELECT(ID_DTIMESERIESTAB1) !## childwindow - size for the bitmap CALL WDIALOGSELECT(ID_DTIMESERIESTAB1) CALL IGRSELECT(DRAWFIELD,IDF_PICTURE1) CALL DBL_IGRAREA(0.0D0,0.0D0,1.0D0,1.0D0) CALL DBL_IGRUNITS(GRAPHUNITS(1,1),GRAPHUNITS(2,1),GRAPHUNITS(3,1),GRAPHUNITS(4,1)) END SUBROUTINE IDFTIMESERIES_ZOOMUPDATE !###====================================================================== SUBROUTINE IDFTIMESERIE_LEGENDCOLOUR(X,Y) !###====================================================================== IMPLICIT NONE REAL(KIND=DP_KIND),INTENT(IN) :: X,Y INTEGER :: NROW,IROW,ICOL,I,IRGB,ITYPE TYPE(WIN_MESSAGE) :: MESSAGE CALL WDIALOGLOAD(ID_DTIMESERIESCOLOURS,ID_DTIMESERIESCOLOURS) NROW=NIDF; IF(NIPF.GT.0)THEN; NROW=NROW+ASSF(1)%NCASS-1; ENDIF IF(IRESIDUAL.EQ.1)NROW=NROW+1 CALL WGRIDROWS(IDF_GRID1,NROW) IF(NROW.EQ.1)CALL WGRIDPUTMENU(IDF_GRID1,6,(/'First'/),1,(/1/),1) IROW=0 DO I=1,NIDF IROW=IROW+1 CALL WGRIDPUTCELLSTRING(IDF_GRID1,1,IROW,TRIM(LEGENDNAME(I))) CALL WGRIDPUTCELLINTEGER(IDF_GRID1,2,IROW,LTYPE(IROW)%ICLR) CALL WGRIDPUTCELLOPTION(IDF_GRID1,3,IROW,LTYPE(IROW)%IWIDTH) CALL WGRIDPUTCELLOPTION(IDF_GRID1,4,IROW,LTYPE(IROW)%ITYPE) CALL WGRIDPUTCELLOPTION(IDF_GRID1,5,IROW,LTYPE(IROW)%ISTYLE) CALL WGRIDPUTCELLOPTION(IDF_GRID1,6,IROW,LTYPE(IROW)%IAXES) CALL WGRIDCOLOURCELL(IDF_GRID1,2,IROW,LTYPE(IROW)%ICLR,LTYPE(IROW)%ICLR) END DO !## draw ipf-timeserie IF(NIPF.GT.0)THEN DO I=1,ASSF(1)%NCASS-1 IROW=IROW+1 CALL WGRIDPUTCELLSTRING(IDF_GRID1,1,IROW,TRIM(IPF(JIPF)%ALIAS)//':'//ASSF(1)%ATTRIB(I+1)) CALL WGRIDPUTCELLINTEGER(IDF_GRID1,2,IROW,LTYPE(IROW)%ICLR) CALL WGRIDPUTCELLOPTION(IDF_GRID1,3,IROW,LTYPE(IROW)%IWIDTH) CALL WGRIDPUTCELLOPTION(IDF_GRID1,4,IROW,LTYPE(IROW)%ITYPE) CALL WGRIDPUTCELLOPTION(IDF_GRID1,5,IROW,LTYPE(IROW)%ISTYLE) CALL WGRIDPUTCELLOPTION(IDF_GRID1,6,IROW,LTYPE(IROW)%IAXES) CALL WGRIDCOLOURCELL(IDF_GRID1,2,IROW,LTYPE(IROW)%ICLR,LTYPE(IROW)%ICLR) ENDDO ENDIF IF(IRESIDUAL.EQ.1)THEN IROW=IROW+1 CALL WGRIDPUTCELLSTRING(IDF_GRID1,1,IROW,'Difference') CALL WGRIDPUTCELLINTEGER(IDF_GRID1,2,IROW,LTYPE(IROW)%ICLR) CALL WGRIDPUTCELLOPTION(IDF_GRID1,3,IROW,LTYPE(IROW)%IWIDTH) CALL WGRIDPUTCELLOPTION(IDF_GRID1,4,IROW,LTYPE(IROW)%ITYPE) CALL WGRIDPUTCELLOPTION(IDF_GRID1,5,IROW,LTYPE(IROW)%ISTYLE) CALL WGRIDPUTCELLOPTION(IDF_GRID1,6,IROW,LTYPE(IROW)%IAXES) CALL WGRIDCOLOURCELL(IDF_GRID1,2,IROW,LTYPE(IROW)%ICLR,LTYPE(IROW)%ICLR) ENDIF CALL UTL_DIALOGSHOW(-1,-1,0,3) DO CALL WMESSAGE(ITYPE,MESSAGE) SELECT CASE (ITYPE) CASE (PUSHBUTTON) SELECT CASE (MESSAGE%VALUE1) CASE (IDCANCEL) EXIT CASE (IDOK) DO IROW=1,NROW CALL WGRIDGETCELLINTEGER(IDF_GRID1,2,IROW,LTYPE(IROW)%ICLR) CALL WGRIDGETCELLMENU(IDF_GRID1,3,IROW,LTYPE(IROW)%IWIDTH) CALL WGRIDGETCELLMENU(IDF_GRID1,4,IROW,LTYPE(IROW)%ITYPE) CALL WGRIDGETCELLMENU(IDF_GRID1,5,IROW,LTYPE(IROW)%ISTYLE) CALL WGRIDGETCELLMENU(IDF_GRID1,6,IROW,LTYPE(IROW)%IAXES) END DO EXIT CASE (IDHELP) CALL UTL_GETHELP('5.2.2','TMO.TT.Leg') END SELECT CASE (FIELDCHANGED) SELECT CASE (MESSAGE%VALUE2) CASE (IDF_GRID1) CALL WGRIDPOS(MESSAGE%Y,ICOL,IROW) IF(ICOL.EQ.2)THEN CALL WGRIDGETCELLINTEGER(IDF_GRID1,2,IROW,IRGB) CALL WSELECTCOLOUR(IRGB) IF(WINFODIALOG(4).EQ.1)CALL WGRIDPUTCELLINTEGER(IDF_GRID1,2,IROW,IRGB) CALL WGRIDCOLOURCELL(IDF_GRID1,2,IROW,IRGB,IRGB) CALL WGRIDSETCELL(IDF_GRID1,1,IROW) ENDIF END SELECT END SELECT ENDDO CALL WDIALOGUNLOAD() CALL WDIALOGSELECT(ID_DTIMESERIESTAB2) IF(MAXVAL(LTYPE%IAXES).NE.MINVAL(LTYPE%IAXES))THEN CALL WDIALOGFIELDSTATE(IDF_CHECK5,1) ELSE CALL WDIALOGFIELDSTATE(IDF_CHECK5,0) CALL WDIALOGPUTCHECKBOX(IDF_CHECK5,0) ENDIF CALL IDFTIMESERIE_RESIDUAL_FIELDS() CALL WDIALOGSELECT(ID_DTIMESERIES) CALL IDFTIMESERIE_INITBITMAP() CALL IDFTIMESERIE_PLOT(X,Y) END SUBROUTINE IDFTIMESERIE_LEGENDCOLOUR !###====================================================================== SUBROUTINE IDFTIMESERIE_INITBITMAP() !###====================================================================== IMPLICIT NONE INTEGER :: IW,IH !## childwindow - size for the bitmap CALL WDIALOGSELECT(ID_DTIMESERIESTAB1) CALL IGRSELECT(DRAWFIELD,IDF_PICTURE1) IF(IDFS_IBITMAP.NE.0)CALL WBITMAPDESTROY(IDFS_IBITMAP) IW=WINFODRAWABLE(DRAWABLEWIDTH) IH=WINFODRAWABLE(DRAWABLEHEIGHT) CALL WBITMAPCREATE(IDFS_IBITMAP,IW,IH) END SUBROUTINE IDFTIMESERIE_INITBITMAP !###====================================================================== SUBROUTINE IDFTIMESERIE_IPF() !###====================================================================== IMPLICIT NONE CHARACTER(LEN=256) :: FNAME INTEGER :: I,J INTEGER :: IYR,IMH,IDY IF(NIPF.EQ.0)RETURN !## nothing selected yet IF(JIPF.LE.0)RETURN !## no associated file with ipf IF(IPF(JIPF)%ACOL.EQ.0)RETURN !## find directory I =INDEXNOCASE(IPF(JIPF)%FNAME,'\',.TRUE.) FNAME=IPF(JIPF)%FNAME(1:I-1) FNAME=TRIM(FNAME)//'\'//TRIM(IPF(JIPF)%INFO(IPF(JIPF)%ACOL,ISEL))//'.'//TRIM(ADJUSTL(IPF(JIPF)%FEXT)) !## read dimensions of associated file and read the associated file CALL IPFDIMENSIONASSFILE(1,FNAME,IPF(JIPF)%IAXES) IF(ASSF(1)%ITOPIC.NE.1)THEN CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'You cannot select an IPF file for the TimeSeries Tool'//CHAR(13)// & 'That does not contain timeseries'//CHAR(13)// & 'The file has been excluded for the rest of this session','Error') !## turn if off for the rest to avoid repetition of this message IPF(JIPF)%ACOL=0 RETURN ENDIF ASSF(1)%ASSCOL1=IPF(JIPF)%ASSCOL1 !## column used with dlf ASSF(1)%ASSCOL2=IPF(JIPF)%ASSCOL2 !## on default not used --- border rings !## make copy from assf() into tsipf() --- for duration purposes IF(ALLOCATED(TSIPF))THEN DO I=1,SIZE(TSIPF) IF(ASSOCIATED(TSIPF(I)%IDATE))DEALLOCATE(TSIPF(I)%IDATE) IF(ASSOCIATED(TSIPF(I)%VALUE))DEALLOCATE(TSIPF(I)%VALUE) IF(ASSOCIATED(TSIPF(I)%IYR))DEALLOCATE(TSIPF(I)%IYR) IF(ASSOCIATED(TSIPF(I)%IMH))DEALLOCATE(TSIPF(I)%IMH) IF(ASSOCIATED(TSIPF(I)%IDY))DEALLOCATE(TSIPF(I)%IDY) IF(ASSOCIATED(TSIPF(I)%IHR))DEALLOCATE(TSIPF(I)%IHR) IF(ASSOCIATED(TSIPF(I)%IMT))DEALLOCATE(TSIPF(I)%IMT) IF(ASSOCIATED(TSIPF(I)%ISC))DEALLOCATE(TSIPF(I)%ISC) END DO DEALLOCATE(TSIPF) ENDIF ALLOCATE(TSIPF(ASSF(1)%NCASS-1)) DO J=1,ASSF(1)%NCASS-1 ALLOCATE(TSIPF(J)%IDATE(ASSF(1)%NRASS)) ALLOCATE(TSIPF(J)%VALUE(ASSF(1)%NRASS)) ALLOCATE(TSIPF(J)%IYR(ASSF(1)%NRASS)) ALLOCATE(TSIPF(J)%IMH(ASSF(1)%NRASS)) ALLOCATE(TSIPF(J)%IDY(ASSF(1)%NRASS)) ALLOCATE(TSIPF(J)%IHR(ASSF(1)%NRASS)) ALLOCATE(TSIPF(J)%IMT(ASSF(1)%NRASS)) ALLOCATE(TSIPF(J)%ISC(ASSF(1)%NRASS)) END DO DO I=1,ASSF(1)%NRASS DO J=1,ASSF(1)%NCASS-1 TSIPF(J)%IDATE(I)=ASSF(1)%IDATE(I)-MINDATE TSIPF(J)%VALUE(I)=ASSF(1)%MEASURE(J,I) ASSF(1)%IDATE(I)=UTL_JDATETOIDATE(INT(ASSF(1)%IDATE(I))) CALL IDATETOGDATE(INT(ASSF(1)%IDATE(I)),IYR,IMH,IDY) TSIPF(J)%IYR(I)=IYR TSIPF(J)%IMH(I)=IMH TSIPF(J)%IDY(I)=IDY TSIPF(J)%IHR(I)=0 TSIPF(J)%IMT(I)=0 TSIPF(J)%ISC(I)=0 ENDDO ENDDO END SUBROUTINE IDFTIMESERIE_IPF !###====================================================================== SUBROUTINE IDFTIMESERIE_CALC(X,Y,IFAST) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: IFAST INTEGER,PARAMETER :: XSPEED=50 !## hundreds of a second REAL(KIND=DP_KIND),INTENT(IN) :: X,Y INTEGER :: I,J,K,IROW,ICOL,ITIC,ITOC TYPE(WIN_MESSAGE) :: MESSAGE INTEGER :: ITYPE CALL WDIALOGSELECT(ID_DTIMESERIESTAB1) CALL WDIALOGFIELDSTATE(IDF_PROGRESS1,1) CALL WDIALOGFIELDSTATE(IDF_LABEL1,1) NFILES=MFILES K =0 DO I=1,NIDF CALL WMESSAGEPEEK(ITYPE,MESSAGE) !## stop when right mouse button pressed IF(ITYPE.EQ.MOUSEBUTDOWN.AND.MESSAGE%VALUE1.EQ.3)EXIT IF(IFAST.EQ.0)CALL OSD_TIMER(ITIC) DO J=1,NFILES(I) !## determine irow/icol for current x/y CALL IDFIROWICOL(IDF(I,J),IROW,ICOL,X,Y) IF(ICOL.NE.0.AND.IROW.NE.0)THEN TS(I)%VALUE(J)=IDFGETVAL(IDF(I,J),IROW,ICOL,LTYPE(I)%UNITS) ELSE !## all nodata value TS(I)%VALUE=IDF(I,J)%NODATA ENDIF K=K+1 IF(IFAST.EQ.0)THEN CALL OSD_TIMER(ITOC) IF(ITOC-ITIC.GT.XSPEED.AND.J.GT.10)EXIT ELSE CALL WDIALOGPUTPROGRESSBAR(IDF_PROGRESS1,K,0) CALL WDIALOGPUTSTRING(IDF_LABEL1,TRIM(ITOS(K*100/SUM(MFILES)))//'%') ENDIF ENDDO NFILES(I)=MIN(NFILES(I),J) ENDDO !## fill progress bar CALL WDIALOGPUTPROGRESSBAR(IDF_PROGRESS1,SUM(NFILES),0) CALL WDIALOGPUTSTRING(IDF_LABEL1,TRIM(ITOS(SUM(NFILES)*100/SUM(MFILES)))//'%') CALL WDIALOGSELECT(ID_DTIMESERIES) IF(SUM(NFILES).NE.SUM(MFILES))THEN CALL WDIALOGPUTSTRING(IDF_LABEL1,'Press LEFT mouse button to complete timeserie') ELSE CALL WDIALOGPUTSTRING(IDF_LABEL1,'') CALL WDIALOGSELECT(ID_DTIMESERIESTAB1) CALL WDIALOGFIELDSTATE(IDF_PROGRESS1,3) CALL WDIALOGFIELDSTATE(IDF_LABEL1,3) ENDIF END SUBROUTINE IDFTIMESERIE_CALC !###====================================================================== SUBROUTINE IDFTIMESERIE_DURATION() !###====================================================================== IMPLICIT NONE INTEGER :: I,J CALL WDIALOGSELECT(ID_DTIMESERIESTAB2) CALL WDIALOGGETSTRING(IDF_STRING1,AXES%XTITLE) AXES%LDATE=.TRUE. IF(IDURATION.EQ.0)THEN !## (ref)fill in dates DO I=1,NIDF DO J=1,NFILES(I) IF(IDF(I,J)%JD.NE.0)THEN !## correct date to be zero at mindate TS(I)%IDATE(J)=REAL(IDF(I,J)%JD)-MINDATE IF(IDF(I,J)%DAYFRACTION.GT.0.0D0)TS(I)%IDATE(J)=TS(I)%IDATE(J)+IDF(I,J)%DAYFRACTION TS(I)%IYR(J)=IDF(I,J)%IYR TS(I)%IMH(J)=IDF(I,J)%IMH TS(I)%IDY(J)=IDF(I,J)%IDY TS(I)%IHR(J)=IDF(I,J)%IHR TS(I)%IMT(J)=IDF(I,J)%IMT TS(I)%ISC(J)=IDF(I,J)%ISC ENDIF END DO ENDDO RETURN ENDIF !## sort results upto now ... for cummulative distributions DO I=1,NIDF CALL QKSORT(NFILES(I),TS(I)%VALUE,V2=TS(I)%IDATE) DO J=1,NFILES(I) TS(I)%IDATE(J)=100.0D0*REAL(J)/REAL(NFILES(I)) END DO ENDDO IF(NIPF.GT.0)THEN DO I=1,SIZE(TSIPF) CALL QKSORT(SIZE(TSIPF(I)%IDATE),TSIPF(I)%VALUE,V2=TSIPF(I)%IDATE) DO J=1,SIZE(TSIPF(I)%IDATE) TSIPF(I)%IDATE(J)=100.0D0*REAL(J)/REAL(SIZE(TSIPF(I)%IDATE)) END DO END DO ENDIF AXES%LDATE=.FALSE. END SUBROUTINE IDFTIMESERIE_DURATION !###====================================================================== SUBROUTINE IDFTIMESERIE_DURATION_FIELDS() !###====================================================================== IMPLICIT NONE INTEGER :: I,J CALL WDIALOGSELECT(ID_DTIMESERIESTAB2) CALL WDIALOGGETCHECKBOX(IDF_CHECK3,IDURATION) !## residuals only possible whenever... I=0 IF(NIDF.EQ.2.AND.NIPF.EQ.0)I=ABS(IDURATION-1) IF(NIDF.EQ.1.AND.NIPF.EQ.1)I=ABS(IDURATION-1) CALL WDIALOGFIELDSTATE(IDF_CHECK4,I) CALL WDIALOGPUTCHECKBOX(IDF_CHECK4,0) CALL WDIALOGPUTCHECKBOX(IDF_CHECK1,0) CALL WDIALOGPUTCHECKBOX(IDF_CHECK2,0) IF(IDURATION.EQ.0)THEN; I=1; J=3 ELSE; I=3; J=1; ENDIF !## hide date settings CALL WDIALOGFIELDSTATE(IDF_LABEL1,I) CALL WDIALOGFIELDSTATE(IDF_LABEL2,I) CALL WDIALOGFIELDSTATE(IDF_LABEL5,I) CALL WDIALOGFIELDSTATE(IDF_LABEL6,I) CALL WDIALOGFIELDSTATE(IDF_INTEGER1,I) CALL WDIALOGFIELDSTATE(IDF_INTEGER2,I) CALL WDIALOGFIELDSTATE(IDF_INTEGER3,I) CALL WDIALOGFIELDSTATE(IDF_INTEGER4,I) CALL WDIALOGFIELDSTATE(IDF_REAL3,I) CALL WDIALOGFIELDSTATE(IDF_MENU1,I) CALL WDIALOGFIELDSTATE(IDF_MENU2,I) CALL WDIALOGFIELDSTATE(IDF_STRING4,I) CALL WDIALOGFIELDSTATE(IDF_STRING5,I) !## hide duration settings CALL WDIALOGFIELDSTATE(IDF_LABEL9,J) CALL WDIALOGFIELDSTATE(IDF_LABEL10,J) CALL WDIALOGFIELDSTATE(IDF_LABEL11,J) CALL WDIALOGFIELDSTATE(IDF_LABEL12,J) CALL WDIALOGFIELDSTATE(IDF_REAL5,J) CALL WDIALOGFIELDSTATE(IDF_REAL6,J) CALL WDIALOGFIELDSTATE(IDF_REAL7,J) IF(I.EQ.1)CALL WDIALOGPUTSTRING(IDF_STRING1,'Date [dd/mm/yyyy]') IF(J.EQ.1)CALL WDIALOGPUTSTRING(IDF_STRING1,'Cummalitive Distribution Function [CDF] (%)') CALL IDFTIMESERIE_FIELDS(IDURATION) CALL IDFTIMESERIE_RESIDUAL_FIELDS() END SUBROUTINE IDFTIMESERIE_DURATION_FIELDS !###====================================================================== SUBROUTINE IDFTIMESERIE_RESIDUAL_FIELDS() !###====================================================================== IMPLICIT NONE INTEGER :: I CALL WDIALOGSELECT(ID_DTIMESERIESTAB2) CALL WDIALOGGETCHECKBOX(IDF_CHECK4,IRESIDUAL) CALL WDIALOGGETCHECKBOX(IDF_CHECK5,I) CALL WDIALOGFIELDSTATE(IDF_LABEL8,I) CALL WDIALOGFIELDSTATE(IDF_LABEL13,I) CALL WDIALOGFIELDSTATE(IDF_LABEL14,I) CALL WDIALOGFIELDSTATE(IDF_LABEL16,I) CALL WDIALOGFIELDSTATE(IDF_REAL8,I) CALL WDIALOGFIELDSTATE(IDF_REAL9,I) CALL WDIALOGFIELDSTATE(IDF_REAL10,I) CALL WDIALOGFIELDSTATE(IDF_STRING3,I) END SUBROUTINE IDFTIMESERIE_RESIDUAL_FIELDS !###====================================================================== SUBROUTINE IDFTIMESERIES_RESIDUALS() !###====================================================================== IMPLICIT NONE INTEGER :: I,II,J,K,N,NT,IROW,IYR,IMH,IDY,IHR,IMT,ISC INTEGER,ALLOCATABLE,DIMENSION(:) :: IT,TSIDATE INTEGER(KIND=8) :: PCKTIME_TS,PCKTIME_TSDIFF,PCKTIME_TSIPF REAL(KIND=DP_KIND) :: FRAC REAL(KIND=DP_KIND),ALLOCATABLE,DIMENSION(:) :: XV REAL(KIND=DP_KIND),ALLOCATABLE,DIMENSION(:) :: RTIME !## clean array IF(ALLOCATED(TSDIFF))THEN DO I=1,SIZE(TSDIFF) IF(ASSOCIATED(TSDIFF(I)%IDATE))DEALLOCATE(TSDIFF(I)%IDATE) IF(ASSOCIATED(TSDIFF(I)%VALUE))DEALLOCATE(TSDIFF(I)%VALUE) END DO DEALLOCATE(TSDIFF) ENDIF IROW=NIDF; IF(NIPF.GT.0)IROW=IROW+ASSF(1)%NCASS-1; IROW=IROW+1; LTYPE(IROW)%IAXES=1 CALL WDIALOGSELECT(ID_DTIMESERIESTAB2) CALL WDIALOGPUTSTRING(IDF_STRING3,'Fluxes (m3/day)') IF(IRESIDUAL.EQ.0)RETURN LTYPE(IROW)%IAXES=2 CALL WDIALOGPUTSTRING(IDF_STRING3,'Difference') !## Get all dates from IDF (and IPF) and sort them N=SUM(NFILES) IF(NIPF.GT.0)THEN DO I=1,SIZE(TSIPF) N=N+SIZE(TSIPF(I)%IDATE) ENDDO ENDIF ALLOCATE(RTIME(N)); RTIME=0.0D0 !## IDF K=0 DO J=1,NIDF DO I=1,NFILES(J) IYR=TS(J)%IYR(I); IMH=TS(J)%IMH(I) IDY=TS(J)%IDY(I); IHR=TS(J)%IHR(I) IMT=TS(J)%IMT(I); ISC=TS(J)%ISC(I) K=K+1 RTIME(K)=IYR*10000000000+IMH*100000000+IDY*1000000+IHR*10000+IMT*100+ISC ENDDO ENDDO !## IPF IF(NIPF.GT.0)THEN DO J=1,SIZE(TSIPF) DO I=1,SIZE(TSIPF(J)%IDATE) IYR=TSIPF(J)%IYR(I); IMH=TSIPF(J)%IMH(I) IDY=TSIPF(J)%IDY(I); IHR=TSIPF(J)%IHR(I) IMT=TSIPF(J)%IMT(I); ISC=TSIPF(J)%ISC(I) K=K+1 RTIME(K)=IYR*10000000000+IMH*100000000+IDY*1000000+IHR*10000+IMT*100+ISC ENDDO ENDDO ENDIF CALL UTL_WSORT(RTIME,1,K) !## Check RTIME on doubles and count number of unique values DO II=1,2 N=1 DO I=2,SIZE(RTIME) IF(ABS(RTIME(I)-RTIME(I-1)).GT.0.5)THEN N=N+1 IF(II.EQ.2)THEN CALL ITIMETOGDATE(INT8(RTIME(I)),TSDIFF(1)%IYR(N),TSDIFF(1)%IMH(N),TSDIFF(1)%IDY(N),TSDIFF(1)%IHR(N),TSDIFF(1)%IMT(N),TSDIFF(1)%ISC(N)) TSDIFF(1)%IDATE(N)=JD(TSDIFF(1)%IYR(N),TSDIFF(1)%IMH(N),TSDIFF(1)%IDY(N)) FRAC=(TSDIFF(1)%IHR(N)*24*60*60+TSDIFF(1)%IMT(N)*60+TSDIFF(1)%ISC(N))/86400.0D0 TSDIFF(1)%IDATE(N)=TSDIFF(1)%IDATE(N)+FRAC ENDIF ENDIF ENDDO IF(II.EQ.1)THEN ALLOCATE(TSDIFF(1)) ALLOCATE(TSDIFF(1)%IDATE(N)) ALLOCATE(TSDIFF(1)%VALUE(N)) ALLOCATE(TSDIFF(1)%IYR(N)) ALLOCATE(TSDIFF(1)%IMH(N)) ALLOCATE(TSDIFF(1)%IDY(N)) ALLOCATE(TSDIFF(1)%IHR(N)) ALLOCATE(TSDIFF(1)%IMT(N)) ALLOCATE(TSDIFF(1)%ISC(N)) TSDIFF(1)%NODATA=-999.99 CALL ITIMETOGDATE(INT8(RTIME(1)),TSDIFF(1)%IYR(1),TSDIFF(1)%IMH(1),TSDIFF(1)%IDY(1),TSDIFF(1)%IHR(1),TSDIFF(1)%IMT(1),TSDIFF(1)%ISC(1)) TSDIFF(1)%IDATE(1)=JD(TSDIFF(1)%IYR(1),TSDIFF(1)%IMH(1),TSDIFF(1)%IDY(1)) ENDIF ENDDO DEALLOCATE(RTIME) ALLOCATE(TSIDATE(SIZE(TSDIFF(1)%IDATE))) DO I=2,SIZE(TSDIFF(1)%IDATE) TSIDATE(I)=TSDIFF(1)%IDATE(I)-TSDIFF(1)%IDATE(I-1) ENDDO TSIDATE(1)=0.0D0 TSDIFF(1)%IDATE(1)=0.0D0 DO I=2,SIZE(TSDIFF(1)%IDATE) TSDIFF(1)%IDATE(I)=TSDIFF(1)%IDATE(I-1)+TSIDATE(I) ENDDO ALLOCATE(IT(2),XV(2)) !## initialise IT=1 TSDIFF(1)%VALUE=TSDIFF(1)%NODATA !## change it for ipf's J=NIDF IF(NIPF.GT.0)THEN PCKTIME_TSDIFF=TSDIFF(1)%IYR(1)*10000000000+TSDIFF(1)%IMH(1)*100000000+TSDIFF(1)%IDY(1)*1000000+TSDIFF(1)%IHR(1)*10000+TSDIFF(1)%IMT(1)*100+TSDIFF(1)%ISC(1) DO K=1,SIZE(TSIPF) J=J+1 DO I=1,SIZE(TSIPF(K)%IDATE) PCKTIME_TSIPF = TSIPF(1)%IYR(I)*10000000000+TSIPF(1)%IMH(I)*100000000+TSIPF(1)%IDY(I)*1000000+TSIPF(1)%IHR(I)*10000+TSIPF(1)%IMT(I)*100+TSIPF(1)%ISC(I) IF(PCKTIME_TSIPF.GE.PCKTIME_TSDIFF)THEN IT(J)=I EXIT ENDIF END DO ENDDO ENDIF !## compute difference DO I=1,N PCKTIME_TSDIFF=TSDIFF(1)%IYR(I)*10000000000+TSDIFF(1)%IMH(I)*100000000+TSDIFF(1)%IDY(I)*1000000+TSDIFF(1)%IHR(I)*10000+TSDIFF(1)%IMT(I)*100+TSDIFF(1)%ISC(I) NT=0 J =0 !## get idf value DO K=1,NIDF J=J+1 !## package time PCKTIME_TS=TS(K)%IYR(IT(J))*10000000000+TS(K)%IMH(IT(J))*100000000+TS(K)%IDY(IT(J))*1000000+TS(K)%IHR(IT(J))*10000+TS(K)%IMT(IT(J))*100+TS(K)%ISC(IT(J)) IF(PCKTIME_TS.EQ.PCKTIME_TSDIFF)THEN NT =NT+1 XV(NT)=TS(K)%VALUE(IT(J)) IT(J) =MIN(SIZE(TS(K)%VALUE),IT(J)+1) ENDIF END DO !## get ipf value IF(NIPF.GT.0)THEN !## check first column of associated file only! DO K=1,1 J=J+1 PCKTIME_TSIPF = TSIPF(1)%IYR(IT(J))*10000000000+TSIPF(1)%IMH(IT(J))*100000000+TSIPF(1)%IDY(IT(J))*1000000+TSIPF(1)%IHR(IT(J))*10000+TSIPF(1)%IMT(IT(J))*100+TSIPF(1)%ISC(IT(J)) IF(PCKTIME_TSIPF.EQ.PCKTIME_TSDIFF)THEN NT =NT+1 XV(NT)=TSIPF(K)%VALUE(IT(J)) IT(J)=IT(J)+1 ENDIF END DO ENDIF !## exist both, ready to compute difference IF(NT.EQ.2)THEN TSDIFF(1)%VALUE(I)=XV(1)-XV(2) ENDIF ENDDO DEALLOCATE(IT,XV) END SUBROUTINE IDFTIMESERIES_RESIDUALS !###====================================================================== SUBROUTINE IDFTIMESERIE_SAVE() !###====================================================================== IMPLICIT NONE CHARACTER(LEN=256) :: FNAME CHARACTER(LEN=1000) :: LINE INTEGER :: IU,IOS,I,J CHARACTER(LEN=100) :: EXTRAINFO IF(.NOT.UTL_WSELECTFILE('Comma-delimited file (*.csv)|*.csv|',SAVEDIALOG+PROMPTON+DIRCHANGE+APPENDEXT,& FNAME,'Save Current Timeseries in a comma-delimited file (*.csv)'))RETURN IU=UTL_GETUNIT() CALL OSD_OPEN(IU,FILE=FNAME,STATUS='REPLACE',FORM='FORMATTED',ACTION='WRITE',IOSTAT=IOS) IF(IOS.NE.0)THEN CALL WMESSAGEBOX(OKONLY,INFORMATIONICON,COMMONOK,'Cannot write to output file:'//CHAR(13)// & TRIM(FNAME),'Info') RETURN ENDIF WRITE(IU,'(A)') TRIM(UTL_IMODVERSION())//' Timeseries' CALL IOSDATE(I,J,IOS) LINE=TRIM(ITOS(IOS))//'/'//TRIM(CDATE(J))//'/'//TRIM(ITOS(I)) WRITE(IU,'(A)') 'Created on: '//TRIM(LINE) WRITE(IU,*) LINE='"DATE"' DO I=1,NIDF LINE=TRIM(LINE)//CHAR(IDELIM)//'"'//TRIM(LEGENDNAME(I))//'"' ENDDO IF(NIPF.GT.0)THEN CALL IDFTIMESERIE_EXTRAINFO(EXTRAINFO) DO I=1,ASSF(1)%NCASS-1 LINE=TRIM(LINE)//CHAR(IDELIM)//'"'//TRIM(IPF(JIPF)%ALIAS)//':'//TRIM(ASSF(1)%ATTRIB(I+1))//' '//TRIM(EXTRAINFO)//'"' END DO ENDIF IF(IRESIDUAL.EQ.1)THEN LINE=TRIM(LINE)//CHAR(IDELIM)//'"Difference"' ENDIF WRITE(IU,'(A)') TRIM(LINE) CALL IDFTIMESERIE_SAVE_DATA(IU,0) CLOSE(IU) CALL WMESSAGEBOX(OKONLY,INFORMATIONICON,COMMONOK,'Successfully written output to:'//CHAR(13)//TRIM(FNAME),'Info') END SUBROUTINE IDFTIMESERIE_SAVE !###====================================================================== SUBROUTINE IDFTIMESERIE_SAVE_DATA(IU,ITYPE) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: IU,ITYPE CHARACTER(LEN=1000) :: LINE REAL(KIND=DP_KIND) :: MINT INTEGER :: I,K,NT,ILOOP,NPER INTEGER,ALLOCATABLE,DIMENSION(:) :: IT REAL(KIND=DP_KIND),PARAMETER :: NODATA=-999.99D0 NT=NIDF IF(NIPF.GT.0)NT=NT+SIZE(TSIPF) IF(IRESIDUAL.EQ.1)NT=NT+1 !## pointer to position to be exported ALLOCATE(IT(NT)) !## process them (double loop with/without writing) DO ILOOP=1,ITYPE+1 IT=1; NPER=0 !## continue till all date are processed DO NPER=NPER+1 K=0 !## find minimal MINT=10.0D10 DO I=1,NIDF K=K+1 IF(NFILES(I).GT.1)THEN IF(IT(K).EQ.0)THEN WRITE(*,*) 'IDF-file '//TRIM(ITOS(K))//' is finished, datapoint will be empty in csv-file' ELSE IF(TS(I)%IDATE(IT(K)).LE.MINT)MINT=TS(I)%IDATE(IT(K)) ENDIF ENDIF ENDDO IF(NIPF.GT.0)THEN DO I=1,SIZE(TSIPF) K=K+1; IF(TSIPF(I)%IDATE(IT(K)).LE.MINT)MINT=TSIPF(I)%IDATE(IT(K)) ENDDO ENDIF IF(IRESIDUAL.EQ.1)THEN DO I=1,SIZE(TSDIFF) K=K+1; IF(TSDIFF(I)%IDATE(IT(K)).LE.MINT)MINT=TSDIFF(I)%IDATE(IT(K)) ENDDO ENDIF IF(ITYPE.EQ.0)LINE=JDATETOFDATE(MINT,MINDATE,0) !## csv IF(ITYPE.EQ.1)LINE=JDATETOFDATE(MINT,MINDATE,2) !## ipf !## write result with t.eq.mint K=0 DO I=1,NIDF K=K+1 IF(NFILES(I).GT.1)THEN IF(IT(K).EQ.0)THEN LINE=TRIM(LINE)//CHAR(IDELIM)//TRIM(RTOS(NODATA,'F',3)) ELSEIF(TS(I)%IDATE(IT(K)).EQ.MINT.AND.IT(K).GT.0)THEN LINE=TRIM(LINE)//CHAR(IDELIM)//TRIM(RTOS(TS(I)%VALUE(IT(K)),'F',7)) IT(K)=IT(K)+1; IF(IT(K).GT.SIZE(TS(I)%IDATE))IT(K)=0 !## finished ELSE LINE=TRIM(LINE)//CHAR(IDELIM)//TRIM(RTOS(NODATA,'F',3)) ENDIF ENDIF ENDDO IF(NIPF.GT.0)THEN DO I=1,SIZE(TSIPF) K=K+1 IF(TSIPF(I)%IDATE(IT(K)).EQ.MINT)THEN LINE=TRIM(LINE)//CHAR(IDELIM)//TRIM(RTOS(TSIPF(I)%VALUE(IT(K)),'F',7)) IT(K)=IT(K)+1; IF(IT(K).GT.SIZE(TSIPF(I)%IDATE))IT(K)=0 !## finished ELSE LINE=TRIM(LINE)//CHAR(IDELIM)//TRIM(RTOS(NODATA,'F',3)) ENDIF ENDDO ENDIF IF(IRESIDUAL.EQ.1)THEN DO I=1,SIZE(TSDIFF) K=K+1 IF(TSDIFF(I)%IDATE(IT(K)).EQ.MINT)THEN LINE=TRIM(LINE)//CHAR(IDELIM)//TRIM(RTOS(TSDIFF(I)%VALUE(IT(K)),'F',7)) IT(K)=IT(K)+1; IF(IT(K).GT.SIZE(TSDIFF(I)%IDATE))IT(K)=0 !## finished ELSE LINE=TRIM(LINE)//CHAR(IDELIM)//TRIM(RTOS(NODATA,'F',3)) ENDIF ENDDO ENDIF IF(ILOOP.EQ.2.OR.ITYPE.EQ.0)WRITE(IU,'(A)') TRIM(LINE) !## finished all DO I=1,NIDF !## check whether variable timeseries are finished - disregard the rest IF(NFILES(I).GT.1.AND.IT(I).NE.0)EXIT ENDDO !## all variable timeseries finished IF(I.GT.NIDF)EXIT ENDDO !## write header for IPF files IF(ILOOP.EQ.1.AND.ITYPE.EQ.1)THEN WRITE(IU,*) NPER WRITE(IU,*) NT+1 !## inclusive date attribute LINE='"Date"'//CHAR(IDELIM)//TRIM(RTOS(NODATA,'F',3)) WRITE(IU,'(A)') TRIM(LINE) DO I=1,NIDF LINE='"'//TRIM(LEGENDNAME(I))//'"'//CHAR(IDELIM)//TRIM(RTOS(NODATA,'F',3)) WRITE(IU,'(A)') TRIM(LINE) ENDDO IF(NIPF.GT.0)THEN DO I=1,ASSF(1)%NCASS-1 LINE='"'//TRIM(IPF(JIPF)%ALIAS)//':'//TRIM(ASSF(1)%ATTRIB(I+1))//'"'//CHAR(IDELIM)//TRIM(RTOS(NODATA,'F',3)) WRITE(IU,'(A)') TRIM(LINE) END DO ENDIF IF(IRESIDUAL.EQ.1)THEN LINE='"Difference"'//CHAR(IDELIM)//TRIM(RTOS(NODATA,'F',3)) WRITE(IU,'(A)') TRIM(LINE) ENDIF ENDIF ENDDO DEALLOCATE(IT) END SUBROUTINE IDFTIMESERIE_SAVE_DATA !###====================================================================== SUBROUTINE IDFTIMESERIE_PLOT(X,Y) !###====================================================================== IMPLICIT NONE REAL(KIND=DP_KIND),INTENT(IN) :: X,Y INTEGER :: IFIXX,IFIXY,IFIXY2 IF(SUM(NFILES).EQ.0)RETURN !## compute min-max IF(.NOT.IDFTIMESERIE_MINMAX(IFIXX,IFIXY,IFIXY2))THEN CALL WDIALOGSELECT(ID_DTIMESERIES) CALL WDIALOGSETTAB(IDF_TAB,ID_DTIMESERIESTAB2) RETURN ENDIF CALL IGRCOLOURN(WRGB(255,255,255)) !## select proper bitmap CALL IGRSELECT(DRAWBITMAP,IDFS_IBITMAP) !## change plotmode CALL IGRPLOTMODE(MODECOPY) !## plot axis and correct xmin,ymin,xmax,ymax for axes CALL DBL_IGRAREA(0.0D0,0.0D0,1.0D0,1.0D0) AXES%XMIN =XMIN AXES%XMAX =XMAX AXES%YMIN =YMIN AXES%YMAX =YMAX AXES%IFIXX =IFIXX AXES%IFIXY =IFIXY AXES%IFIXY2=IFIXY2 AXES%XINT =XINT AXES%YINT =YINT AXES%XOFFSET=MINDATE CALL WDIALOGSELECT(ID_DTIMESERIESTAB2) CALL WDIALOGGETSTRING(IDF_STRING2,AXES%YTITLE) IF(MINVAL(LTYPE%IAXES).EQ.MAXVAL(LTYPE%IAXES))THEN AXES%IAXES=(/1,0/) !## left/bottom axes only AXES%DXAXESR=150.0D0 ELSE AXES%Y2MIN =Y2MIN AXES%Y2MAX =Y2MAX AXES%Y2INT =Y2INT AXES%IAXES=(/1,1/) !## left/right/bottom axes only AXES%DXAXESR=AXES%DXAXESL CALL WDIALOGGETSTRING(IDF_STRING3,AXES%Y2TITLE) ENDIF AXES%ICLRBACKGROUND=WRGB(123,152,168) !## plot axes and set units CALL GRAPH_PLOTAXES(AXES,1) !## store values IF(IFIXX .EQ.0)CALL IDFTIMESERIE_PUTMINMAXX (XMIN ,XMAX ,AXES%XINT,IDURATION) IF(IFIXY .EQ.0)CALL IDFTIMESERIE_PUTMINMAXY (YMIN ,YMAX ,AXES%YINT) IF(IFIXY2.EQ.0)CALL IDFTIMESERIE_PUTMINMAXY2(Y2MIN,Y2MAX,AXES%Y2INT) CALL IDFTIMESERIE_GRAPH(X,Y) CALL WDIALOGSELECT(ID_DTIMESERIESTAB1) CALL IGRSELECT(DRAWFIELD,IDF_PICTURE1) CALL WBITMAPPUT(IDFS_IBITMAP,0,1) !## reset to entire window CALL WINDOWSELECT(MPW%IWIN) CALL IGRSELECT(DRAWWIN,MPW%IWIN) CALL DBL_IGRAREA(0.0D0,0.0D0,1.0D0,1.0D0) CALL DBL_IGRUNITS(MPW%XMIN,MPW%YMIN,MPW%XMAX,MPW%YMAX,IOFFSET=1) END SUBROUTINE IDFTIMESERIE_PLOT !###====================================================================== LOGICAL FUNCTION IDFTIMESERIE_MINMAX(IFIXX,IFIXY,IFIXY2) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(OUT) :: IFIXX,IFIXY,IFIXY2 INTEGER :: I,J,IAXE,IFXY(2),IROW REAL(KIND=DP_KIND) :: Y(2,2) IDFTIMESERIE_MINMAX=.FALSE. CALL WDIALOGSELECT(ID_DTIMESERIESTAB2) CALL WDIALOGGETCHECKBOX(IDF_CHECK1,IFIXX) CALL WDIALOGGETCHECKBOX(IDF_CHECK2,IFIXY) CALL WDIALOGGETCHECKBOX(IDF_CHECK5,IFIXY2) IFXY(1)=IFIXY; IFXY(2)=IFIXY2 !## compute x-axes IF(IFIXX.EQ.0)THEN !## determine min/max values for x axes XMIN= 10.0D10 XMAX=-10.0D10 DO I=1,NIDF DO J=1,NFILES(I) XMIN=MIN(XMIN,TS(I)%IDATE(J)) XMAX=MAX(XMAX,TS(I)%IDATE(J)) END DO END DO IF(NIPF.GT.0)THEN DO I=1,SIZE(TSIPF) DO J=1,SIZE(TSIPF(I)%IDATE) XMIN=MIN(XMIN,TSIPF(I)%IDATE(J)) XMAX=MAX(XMAX,TSIPF(I)%IDATE(J)) END DO END DO ENDIF !## trim to the given mindate/maxdate IF(IDURATION.EQ.0)THEN XMIN=MAX(0.0D0,XMIN) XMAX=MIN(REAL(MAXDATE-MINDATE+1),XMAX) ENDIF CALL IDFTIMESERIE_PUTMINMAXX(XMIN,XMAX,AXES%XINT,IDURATION) ENDIF !## check axes Y(1,1)=10.0D10; Y(2,1)=-10.0D10 Y(1,2)=10.0D10; Y(2,2)=-10.0D10 DO IAXE=1,2 IF(IFXY(IAXE).EQ.0)THEN IROW=0 !## determine min/max values for y axes DO I=1,NIDF IROW=IROW+1 IF(LTYPE(IROW)%IAXES.EQ.IAXE)THEN DO J=1,NFILES(I) IF(TS(I)%VALUE(J).NE.IDF(I,J)%NODATA)THEN Y(1,IAXE)=MIN(Y(1,IAXE),TS(I)%VALUE(J)) Y(2,IAXE)=MAX(Y(2,IAXE),TS(I)%VALUE(J)) ENDIF END DO ENDIF END DO IF(NIPF.GT.0)THEN DO I=1,SIZE(TSIPF) IROW=IROW+1 IF(LTYPE(IROW)%IAXES.EQ.IAXE)THEN DO J=1,SIZE(TSIPF(I)%IDATE) IF(TSIPF(I)%VALUE(J).NE.ASSF(1)%NODATA(I+1))THEN Y(1,IAXE)=MIN(Y(1,IAXE),TSIPF(I)%VALUE(J)) Y(2,IAXE)=MAX(Y(2,IAXE),TSIPF(I)%VALUE(J)) ENDIF END DO ENDIF ENDDO ENDIF IF(IRESIDUAL.EQ.1)THEN IROW=IROW+1; IF(LTYPE(IROW)%IAXES.EQ.IAXE)THEN DO J=1,SIZE(TSDIFF(1)%IDATE) IF(TSDIFF(1)%VALUE(J).NE.TSDIFF(1)%NODATA)THEN Y(1,IAXE)=MIN(Y(1,IAXE),TSDIFF(1)%VALUE(J)) Y(2,IAXE)=MAX(Y(2,IAXE),TSDIFF(1)%VALUE(J)) ENDIF END DO ENDIF ENDIF !## no values found at all! IF(Y(2,IAXE).LT.Y(1,IAXE))THEN; Y(1,IAXE)=-1;Y(2,IAXE)=1; ENDIF !## flat line IF(ABS(Y(2,IAXE)-Y(1,IAXE)).LE.0.01D0)THEN; Y(1,IAXE)=Y(1,IAXE)-0.01D0; Y(2,IAXE)=Y(2,IAXE)+0.01D0; ENDIF IF(IAXE.EQ.1)THEN; YMIN=Y(1,1) ; YMAX=Y(2,1) ; CALL IDFTIMESERIE_PUTMINMAXY(YMIN,YMAX,AXES%YINT); ENDIF IF(IAXE.EQ.2)THEN; Y2MIN=Y(1,2); Y2MAX=Y(2,2); CALL IDFTIMESERIE_PUTMINMAXY2(Y2MIN,Y2MAX,AXES%Y2INT); ENDIF ENDIF ENDDO CALL IDFTIMESERIE_GETMINMAXX(XMIN,XMAX,XINT,IFIXX,IDURATION) IF(XMAX.LE.XMIN)THEN IF(IDURATION.EQ.0)CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'FromDate ('// & TRIM(ITOS(UTL_JDATETOIDATE(INT(XMIN))))//') is beyond EndDate ('// & TRIM(ITOS(UTL_JDATETOIDATE(INT(XMAX))))//')','Error') IF(IDURATION.EQ.1)CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'Maximum percentage ('// & TRIM(RTOS(XMAX,'*',1))//') is beyond minimum percentage ('//TRIM(RTOS(XMIN,'*',1))//')','Error') RETURN ENDIF IF(IFIXY.EQ.1)THEN CALL IDFTIMESERIE_GETMINMAXY(YMIN,YMAX,YINT,IFIXY) IF(YMAX.LE.YMIN)THEN CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'First Y-axes: Minimum Y-value ('//TRIM(RTOS(YMIN,'*',1))// & ') is beyond Maximum Y-value ('//TRIM(RTOS(YMAX,'*',1))//')','Error') RETURN ENDIF ENDIF IF(IFIXY2.EQ.1)THEN CALL IDFTIMESERIE_GETMINMAXY2(Y2MIN,Y2MAX,Y2INT,IFIXY2) IF(Y2MAX.LE.Y2MIN)THEN CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'Secondary Y-axes: Minimum Y-value ('//TRIM(RTOS(Y2MIN,'*',1))// & ') is beyond Maximum Y-value ('//TRIM(RTOS(Y2MAX,'*',1))//')','Error') RETURN ENDIF ENDIF IDFTIMESERIE_MINMAX=.TRUE. END FUNCTION IDFTIMESERIE_MINMAX !###====================================================================== SUBROUTINE IDFTIMESERIE_GRAPH(XC,YC) !###====================================================================== IMPLICIT NONE REAL(KIND=DP_KIND),INTENT(IN) :: XC,YC INTEGER :: I,IWD,IWS,IROW REAL(KIND=DP_KIND) :: DX,DY,CHH,BOXX,OFFX,SX_RATIO,Y,X1,X2,Y1,Y2 CHARACTER(LEN=100) :: EXTRAINFO CALL IGRLINETYPE(SOLIDLINE) CALL IGRFILLPATTERN(SOLID) !## get current textsizes CHH=WINFOGRREAL(GRAPHICSCHHEIGHT) IF(NIPF.EQ.0)THEN DY =CHH* NIDF ELSE DY =CHH*(NIDF+ASSF(1)%NCASS-1) ENDIF !## drawable settings IWD=WINFODRAWABLE(DRAWABLEWIDTH) !## screen setting IWS=WINFOSCREEN(SCREENWIDTH) !## ratio's SX_RATIO=REAL(IWS)/REAL(IWD) DX=GRAPHUNITS(3,1)-GRAPHUNITS(1,1) OFFX=(DX/250.0D0)*SX_RATIO BOXX=OFFX*4.0D0 IF(NIPF.EQ.0)THEN DY=DY/REAL(NIDF) ELSE DY=DY/REAL(NIDF+ASSF(1)%NCASS-1) ENDIF Y =YMAX+0.5D0*DY CALL DBL_WGRTEXTORIENTATION(ALIGNRIGHT) CALL DBL_WGRTEXTSTRING(XMAX-OFFX,YMIN+0.75*DY,'[x='//TRIM(RTOS(XC,'F',3))//' ; y='//TRIM(RTOS(YC,'F',3))//']') CALL DBL_WGRTEXTORIENTATION(ALIGNLEFT) IROW=0 DO I=1,NIDF !## for legend purposes use the ymin/ymax axes CALL DBL_IGRUNITS(XMIN,YMIN,XMAX,YMAX) Y=Y-DY IROW=IROW+1 !## plot axes-text CALL IGRCOLOURN(WRGB(0,0,0)) CALL DBL_WGRTEXTSTRING(XMIN+OFFX+BOXX,Y-0.5*DY,' '//TRIM(LEGENDNAME(I))) !## type ltype meegeven naar utl_drawlegendbox? X1=XMIN+OFFX Y1=Y-DY+0.1D0*DY X2=XMIN+OFFX+BOXX Y2=Y-0.1D0*DY CALL UTL_DRAWLEGENDBOX(X1,Y1,X2,Y2,LTYPE(IROW)%ICLR, & LTYPE(IROW)%IWIDTH,LTYPE(IROW)%ITYPE-1,1) CALL IGRLINETYPE(LTYPE(IROW)%ITYPE-1) CALL IGRLINEWIDTH(LTYPE(IROW)%IWIDTH) IF(LTYPE(IROW)%IAXES.EQ.1)CALL DBL_IGRUNITS(XMIN, YMIN,XMAX, YMAX) IF(LTYPE(IROW)%IAXES.EQ.2)CALL DBL_IGRUNITS(XMIN,Y2MIN,XMAX,Y2MAX) !## time constant IF(NFILES(I).EQ.1)THEN IF(TS(I)%VALUE(1).NE.IDF(I,1)%NODATA)THEN CALL DBL_IGRMOVETO(XMIN,TS(I)%VALUE(1)) CALL DBL_IGRLINETO(XMAX,TS(I)%VALUE(1)) ENDIF ELSE CALL IDFTIMESERIE_GRAPHLINES(NFILES(I),TS(I)%IDATE(:),TS(I)%VALUE(:),IDF(I,1)%NODATA,LTYPE(IROW)%ISTYLE,.TRUE.) ENDIF END DO !## draw ipf-timeserie IF(NIPF.GT.0)THEN !## call extrainfo on legend string CALL IDFTIMESERIE_EXTRAINFO(EXTRAINFO) DO I=1,SIZE(TSIPF) !## for legend purposes use the ymin/ymax axes CALL DBL_IGRUNITS(XMIN,YMIN,XMAX,YMAX) Y=Y-DY IROW=IROW+1 CALL IGRCOLOURN(WRGB(0,0,0)) CALL DBL_WGRTEXTSTRING(XMIN+(2.0*OFFX)+BOXX,Y-0.5*DY,TRIM(IPF(JIPF)%ALIAS)//':'//TRIM(ASSF(1)%ATTRIB(I+1))//' '//TRIM(EXTRAINFO)) X1=XMIN+OFFX Y1=Y-DY+0.1D0*DY X2=XMIN+OFFX+BOXX Y2=Y-0.1D0*DY CALL UTL_DRAWLEGENDBOX(X1,Y1,X2,Y2,LTYPE(IROW)%ICLR,LTYPE(IROW)%IWIDTH, & LTYPE(IROW)%ITYPE-1,1)!OUTLINE) IF(LTYPE(IROW)%IAXES.EQ.1)CALL DBL_IGRUNITS(XMIN, YMIN,XMAX, YMAX) IF(LTYPE(IROW)%IAXES.EQ.2)CALL DBL_IGRUNITS(XMIN,Y2MIN,XMAX,Y2MAX) CALL IGRLINETYPE(LTYPE(IROW)%ITYPE-1) CALL IGRLINEWIDTH(LTYPE(IROW)%IWIDTH) CALL IDFTIMESERIE_GRAPHLINES(SIZE(TSIPF(I)%IDATE),TSIPF(I)%IDATE(:),TSIPF(I)%VALUE(:), & ASSF(1)%NODATA(I+1),LTYPE(IROW)%ISTYLE,.TRUE.) ENDDO ENDIF IF(IRESIDUAL.EQ.1)THEN !## for legend purposes use the ymin/ymax axes CALL DBL_IGRUNITS(XMIN,YMIN,XMAX,YMAX) Y=Y-DY IROW=IROW+1 !## plot axes-text CALL IGRCOLOURN(WRGB(0,0,0)) CALL DBL_WGRTEXTSTRING(XMIN+(2.0*OFFX)+BOXX,Y-0.5*DY,'Difference') X1=XMIN+OFFX Y1=Y-DY+0.1D0*DY X2=XMIN+OFFX+BOXX Y2=Y-0.1D0*DY CALL UTL_DRAWLEGENDBOX(X1,Y1,X2,Y2,LTYPE(IROW)%ICLR,LTYPE(IROW)%IWIDTH, & LTYPE(IROW)%ITYPE-1,1)!OUTLINE) CALL IGRCOLOURN(WRGB(0,0,0)) IF(LTYPE(IROW)%IAXES.EQ.1)CALL DBL_IGRUNITS(XMIN, YMIN,XMAX, YMAX) IF(LTYPE(IROW)%IAXES.EQ.2)CALL DBL_IGRUNITS(XMIN,Y2MIN,XMAX,Y2MAX) CALL IGRCOLOURN(LTYPE(IROW)%ICLR) CALL IGRLINETYPE(LTYPE(IROW)%ITYPE-1) CALL IGRLINEWIDTH(LTYPE(IROW)%IWIDTH) CALL IDFTIMESERIE_GRAPHLINES(SIZE(TSDIFF(1)%IDATE),TSDIFF(1)%IDATE(:),TSDIFF(1)%VALUE(:),TSDIFF(1)%NODATA, & LTYPE(IROW)%ISTYLE,.FALSE.) ENDIF CALL IGRFILLPATTERN(OUTLINE) CALL IGRLINETYPE(SOLIDLINE) CALL IGRLINEWIDTH(1) END SUBROUTINE IDFTIMESERIE_GRAPH !###====================================================================== SUBROUTINE IDFTIMESERIE_GRAPHLINES(N,X,Y,NODATA,ISTYLE,LRESET) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: N,ISTYLE REAL(KIND=DP_KIND),INTENT(IN),DIMENSION(N) :: X,Y REAL(KIND=DP_KIND),INTENT(IN) :: NODATA LOGICAL,INTENT(IN) :: LRESET LOGICAL :: LEX INTEGER :: I REAL(KIND=DP_KIND) :: X2 !## continuous IF(ISTYLE.EQ.1)THEN LEX=.FALSE.; X2=-HUGE(1.0D0) DO I=1,N IF(Y(I).NE.NODATA)THEN IF(X(I).GT.X2)THEN IF(.NOT.LEX)CALL DBL_IGRMOVETO(X(I),Y(I)) IF(LEX)CALL DBL_IGRLINETO(X(I),Y(I)) LEX=.TRUE. ELSE !## stop if times are not sequentially EXIT ENDIF ELSE IF(LRESET)LEX=.FALSE. ENDIF X2=X(I) END DO !## blockline ELSEIF(ISTYLE.EQ.2)THEN LEX=.FALSE.; X2=-HUGE(1.0D0) DO I=1,N IF(Y(I).NE.NODATA)THEN IF(X(I).GT.X2)THEN IF(.NOT.LEX)CALL DBL_IGRMOVETO(X(I),Y(I)) IF(LEX)THEN; CALL DBL_IGRLINETO(X(I),Y(I-1)); CALL DBL_IGRLINETO(X(I),Y(I)); ENDIF LEX=.TRUE. ELSE !## stop if times are not sequentially EXIT ENDIF ELSE IF(LRESET)LEX=.FALSE. ENDIF X2=X(I) ENDDO ENDIF END SUBROUTINE IDFTIMESERIE_GRAPHLINES !###====================================================================== SUBROUTINE IDFTIMESERIE_EXTRAINFO(EXTRAINFO) !###====================================================================== IMPLICIT NONE CHARACTER(LEN=*),INTENT(OUT) :: EXTRAINFO INTEGER :: I,J INTEGER,ALLOCATABLE,DIMENSION(:) :: IP ALLOCATE(IP(IPF(JIPF)%NCOL)) CALL WDIALOGSELECT(ID_DTIMESERIESTAB3) CALL WDIALOGGETMENU(IDF_MENU1,IP) CALL WDIALOGSELECT(ID_DTIMESERIESTAB1) EXTRAINFO='[' J=0 DO I=1,IPF(JIPF)%NCOL IF(IP(I).EQ.1)THEN J=J+1 IF(J.EQ.1)THEN EXTRAINFO=TRIM(EXTRAINFO)//TRIM(IPF(JIPF)%ATTRIB(I))//'='//TRIM(IPF(JIPF)%INFO(I,ISEL)) ELSE EXTRAINFO=TRIM(EXTRAINFO)//';'//TRIM(IPF(JIPF)%ATTRIB(I))//'='//TRIM(IPF(JIPF)%INFO(I,ISEL)) ENDIF ENDIF END DO IF(LEN_TRIM(EXTRAINFO).EQ.1)THEN EXTRAINFO='' ELSE EXTRAINFO=TRIM(EXTRAINFO)//']' ENDIF DEALLOCATE(IP) END SUBROUTINE IDFTIMESERIE_EXTRAINFO !###====================================================================== LOGICAL FUNCTION IDFTIMESERIE_INIT() !###====================================================================== IMPLICIT NONE INTEGER :: IPLOT,I,J IDFTIMESERIE_INIT=.FALSE. IDFS_IBITMAP=0 NULLIFY(IPFPLUS) !## fill dialog with information for selected idf's NIDF=0; DO IPLOT=1,MXMPLOT IF(MP(IPLOT)%ISEL.AND.MP(IPLOT)%IPLOT.EQ.1)NIDF=NIDF+1 ENDDO !## allocate memory for ipf-plotting, they will be read in memory and drawn from that CALL IPFINIT() !## nothing to do IF(NIDF.EQ.0.AND.NIPF.EQ.0)THEN CALL WMESSAGEBOX(OKONLY,INFORMATIONICON,COMMONOK,'You should select at least one'//CHAR(13)// & 'IDF with date information, e.g. head_20010101_l1.idf or'//CHAR(13)// & 'head_20080101151530_l1.idf or/and'//CHAR(13)//'IPF with associated files','Information') RETURN ENDIF CALL WDIALOGSELECT(ID_DTIMESERIES) IF(NIPF.EQ.0)THEN CALL WDIALOGTABSTATE(IDF_TAB,ID_DTIMESERIESTAB3,0) ELSE !## read the ipf files I=0 DO IPLOT=1,MXMPLOT IF(MP(IPLOT)%ISEL.AND.MP(IPLOT)%IPLOT.EQ.2)THEN I=I+1 CALL WINDOWSELECT(0) !## check whether information for current ipf is already in memory IF(UTL_CAP(IPF(I)%FNAME,'U').EQ.UTL_CAP(MP(IPLOT)%IDFNAME,'U'))THEN CALL WINDOWOUTSTATUSBAR(3,'RF Memory ...') ELSE CALL WINDOWOUTSTATUSBAR(3,'RF Disc ...') IF(.NOT.IPFREAD(IPLOT,I))THEN CALL IPFDEALLOCATE() CALL WINDOWOUTSTATUSBAR(3,'') RETURN ENDIF ENDIF ENDIF END DO DO I=1,NIPF; IF(IPF(I)%ACOL.EQ.0)EXIT; ENDDO IF(I.LE.NIPF)THEN CALL WMESSAGEBOX(OKONLY,INFORMATIONICON,COMMONOK,'Make sure all selected ipf"s files have associated files in them!'//CHAR(13)//& 'The following ipf does not have associated files:'//CHAR(13)//TRIM(IPF(I)%FNAME),'Information') RETURN ENDIF CALL IPFASSFILEALLOCATE(1) ENDIF ALLOCATE(NFILES(NIDF),MFILES(NIDF)); NFILES=0; MFILES=0 !## get number of dates IF(.NOT.IDFTIMESERIE_DATES(1))RETURN CALL UTL_MESSAGEHANDLE(0) !## dimension idf ALLOCATE(IDF(SIZE(NFILES),MAXVAL(NFILES))) DO I=1,NIDF; DO J=1,MAXVAL(NFILES); CALL IDFNULLIFY(IDF(I,J)); ENDDO; ENDDO ALLOCATE(LTYPE(NIDF+10),LEGENDNAME(NIDF)) !## initiate colours LTYPE(1:SIZE(LTYPE))%ICLR =ICOLOR(1:SIZE(LTYPE)) LTYPE(1:SIZE(LTYPE))%IWIDTH=1 LTYPE(1:SIZE(LTYPE))%ITYPE =1 LTYPE(1:SIZE(LTYPE))%ISTYLE=1 LTYPE(1:SIZE(LTYPE))%IAXES =1 LTYPE(1:SIZE(LTYPE))%UNITS =1 !## get them all and read properties! NIDF=0 DO IPLOT=1,MXMPLOT IF(MP(IPLOT)%ISEL.AND.MP(IPLOT)%IPLOT.EQ.1)THEN NIDF=NIDF+1 !## asign colour to it (overwrite default) LTYPE(NIDF)%ICLR =MP(IPLOT)%SCOLOR LTYPE(NIDF)%UNITS=MP(IPLOT)%UNITS LEGENDNAME(NIDF) =MP(IPLOT)%IDFNAME DO J=1,NFILES(NIDF) CALL WINDOWOUTSTATUSBAR(4,'Reading '//TRIM(LISTFILES(J,NIDF))//'...') IF(.NOT.IDFREAD(IDF(NIDF,J),LISTFILES(J,NIDF),0))RETURN ENDDO ENDIF ENDDO !## get legend name in case nidf=1 IF(NIDF.EQ.1)THEN I=INDEX(LEGENDNAME(1),'\',.TRUE.) IF(I.NE.0)LEGENDNAME(1)=LEGENDNAME(1)(I+1:) !## correct legendname to describe as much as neccessary to distinguish between eachother ELSE CALL UTL_GETRELEVANTDIR(LEGENDNAME,NIDF) ENDIF ALLOCATE(TS(NIDF)) DO I=1,NIDF NULLIFY(TS(I)%IDATE); NULLIFY(TS(I)%VALUE); NULLIFY(TS(I)%IYR) NULLIFY(TS(I)%IMH); NULLIFY(TS(I)%IDY); NULLIFY(TS(I)%IHR) NULLIFY(TS(I)%IMT); NULLIFY(TS(I)%ISC) ALLOCATE(TS(I)%IDATE(NFILES(I))) ALLOCATE(TS(I)%VALUE(NFILES(I))) ALLOCATE(TS(I)%IYR(NFILES(I))) ALLOCATE(TS(I)%IMH(NFILES(I))) ALLOCATE(TS(I)%IDY(NFILES(I))) ALLOCATE(TS(I)%IHR(NFILES(I))) ALLOCATE(TS(I)%IMT(NFILES(I))) ALLOCATE(TS(I)%ISC(NFILES(I))) END DO MFILES=NFILES NFILES=0 CALL WDIALOGSELECT(ID_DTIMESERIESTAB1) CALL WDIALOGRANGEPROGRESSBAR(IDF_PROGRESS1,0,SUM(MFILES)) AXES%ICLRRASTER=WRGB(220,220,220) !WRGB(200,200,200)!ICLRRASTER AXES%XFACTOR=1.0D0 AXES%YFACTOR=1.0D0 AXES%DXAXESL=40.0D0 AXES%DYAXESB=20.0D0 AXES%DYAXEST=75.0 ! AXES%DXAXESR=150.0D0 AXES%TFONT=FFHELVETICA !## text-font ! AXES%IAXES=(/1,0/) !## left/bottom axes only ! AXES%XTITLE='Date [dd/mm/yyyy]' AXES%YTITLE='' ! AXES%LDATE=.TRUE. IDURATION=0 CALL WDIALOGSELECT(ID_DTIMESERIESTAB1) CALL WDIALOGPUTIMAGE(ID_DRAW,ID_ICONSELECTPOINT,1) CALL WDIALOGPUTIMAGE(ID_SAVEAS,ID_ICONSAVEAS,1) CALL WDIALOGFIELDSTATE(ID_SAVEAS,0) CALL WDIALOGPUTIMAGE(ID_COPY,ID_ICONCOPY,1) CALL WDIALOGFIELDSTATE(ID_COPY,0) CALL WDIALOGPUTIMAGE(ID_LEGEND,ID_ICONLEGEND,1) CALL WDIALOGFIELDSTATE(ID_LEGEND,0) CALL WDIALOGPUTIMAGE(IDF_CHECK1,ID_ICONCALC,1) CALL WDIALOGFIELDSTATE(IDF_CHECK1,2) CALL WDIALOGPUTIMAGE(ID_ZOOMIN,ID_ICONZOOMIN,1) CALL WDIALOGPUTIMAGE(ID_ZOOMOUT,ID_ICONZOOMOUT,1) CALL WDIALOGPUTIMAGE(ID_ZOOMFULL,ID_ICONZOOMFULL,1) CALL WDIALOGPUTIMAGE(ID_ZOOMBOX,ID_ICONZOOMBOX,1) CALL WDIALOGPUTIMAGE(ID_MOVE,ID_ICONMOVE,1) CALL WDIALOGPUTIMAGE(ID_PLUS,ID_ICONPLUS,1) CALL WDIALOGPUTIMAGE(ID_PLUSSAVE,ID_ICONPLUSSAVE,1) CALL WDIALOGPUTIMAGE(ID_PLUSLOAD,ID_ICONOPEN,1) CALL WDIALOGFIELDSTATE(ID_PLUS,0) CALL WDIALOGFIELDSTATE(ID_PLUSSAVE,0) CALL WDIALOGFIELDSTATE(ID_ZOOMIN,0) CALL WDIALOGFIELDSTATE(ID_ZOOMOUT,0) CALL WDIALOGFIELDSTATE(ID_ZOOMFULL,0) CALL WDIALOGFIELDSTATE(ID_ZOOMBOX,0) CALL WDIALOGFIELDSTATE(ID_MOVE,0) CALL WDIALOGFIELDSTATE(IDF_PROGRESS1,3) CALL WDIALOGFIELDSTATE(IDF_LABEL1,3) CALL WDIALOGFIELDSTATE(IDF_LABEL2,3) CALL WDIALOGSELECT(ID_DTIMESERIESTAB2) CALL WDIALOGPUTMENU(IDF_MENU1,CDATE,12,4) CALL WDIALOGPUTMENU(IDF_MENU2,CDATE,12,3) CALL WDIALOGPUTINTEGER(IDF_INTEGER1,14) CALL WDIALOGPUTINTEGER(IDF_INTEGER3,28) CALL WDIALOGPUTINTEGER(IDF_INTEGER2,1996) CALL WDIALOGPUTINTEGER(IDF_INTEGER4,2004) CALL IDFTIMESERIE_FIELDS(IDURATION) CALL WDIALOGFIELDSTATE(IDF_CHECK1,0) CALL WDIALOGFIELDSTATE(IDF_CHECK2,0) CALL WDIALOGFIELDSTATE(IDF_CHECK3,0) CALL WDIALOGFIELDSTATE(IDF_CHECK4,0) CALL WDIALOGPUTSTRING(IDF_STRING1,'Date (yyyy/mm/dd)') CALL WDIALOGPUTSTRING(IDF_STRING2,'Heads (m+NAP)') CALL WDIALOGPUTSTRING(IDF_STRING3,'Fluxes (m3/day)') CALL IDFTIMESERIE_DURATION_FIELDS() CALL WINDOWOUTSTATUSBAR(3,'') CALL WINDOWOUTSTATUSBAR(4,'') CALL UTL_MESSAGEHANDLE(1) IF(ALLOCATED(GRAPHUNITS))DEALLOCATE(GRAPHUNITS) IF(ALLOCATED(GRAPHAREA)) DEALLOCATE(GRAPHAREA) ALLOCATE(GRAPHUNITS(6,1),GRAPHAREA(4,1)) GRAPHUNITS(1,1)=0.0D0 GRAPHUNITS(2,1)=0.0D0 GRAPHUNITS(3,1)=1.0D0 GRAPHUNITS(4,1)=1.0D0 GRAPHUNITS(5,1)=0.0D0 GRAPHUNITS(6,1)=1.0D0 GRAPHAREA(1,1) =0.0D0 GRAPHAREA(2,1) =0.0D0 GRAPHAREA(3,1) =1.0D0 GRAPHAREA(4,1) =1.0D0 IDFTIMESERIE_INIT=.TRUE. END FUNCTION IDFTIMESERIE_INIT END MODULE MOD_IDFTIMESERIE