!----- AGPL -------------------------------------------------------------------- ! ! Copyright (C) Stichting Deltares, 2017-2021. ! ! This file is part of Delft3D (D-Flow Flexible Mesh component). ! ! Delft3D is free software: you can redistribute it and/or modify ! it under the terms of the GNU Affero General Public License as ! published by the Free Software Foundation version 3. ! ! Delft3D 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 Affero General Public License for more details. ! ! You should have received a copy of the GNU Affero General Public License ! along with Delft3D. If not, see . ! ! contact: delft3d.support@deltares.nl ! Stichting Deltares ! P.O. Box 177 ! 2600 MH Delft, The Netherlands ! ! All indications and logos of, and references to, "Delft3D", ! "D-Flow Flexible Mesh" and "Deltares" are registered trademarks of Stichting ! Deltares, and remain the property of Stichting Deltares. All rights reserved. ! !------------------------------------------------------------------------------- ! $Id$ ! $HeadURL$ !> DFMOUTPUT - A postprocessing tool for output files from D-Flow Flexible Mesh. !! Combines several commands/operations into a single program. !! !! Available commands: !! * mapmerge - Merge multiple _map.nc files into a single one, intended for merging partioned output files. !! * max25 - Filter for histories. !! * extract - (not implemented) Extract time series on certain locations from _his.nc files. !! * convert - (not implemented) Convert old format map files into UGRID compliant map files. !! !! $Id$ program dfmoutput use IR_Precision ! Integers and reals precision definition. use Data_Type_Command_Line_Interface, only: Type_Command_Line_Interface ! Definition of Type_Command_Line_Interface. use dfmoutput_version_module use dfm_params use dfm_merge use m_alloc use precision, only : hp use dfm_max25_getdata use dfm_gen_filter !----------------------------------------------------------------------------------------------------------------------------------- !----------------------------------------------------------------------------------------------------------------------------------- implicit none type(Type_Command_Line_Interface) :: cli !< Command Line Interface (CLI). integer(I4P) :: ierr !< Error trapping flag. character(len=MAXNAMELEN), allocatable :: infiles(:) !< Input file name(s) character(len=MAXNAMELEN) :: listfile !< List file containing all input file name(s) character(len=MAXNAMELEN), allocatable :: outfiles(:) !< Output file name(s) character(len=32 ) :: filter_length !< filter lengths given for max25 character(len=32 ) :: var_name !< variable name given for max25 character(len=MAXNAMELEN) :: rec character(len=12) :: coeff(3) real(kind=hp) :: rcoeff(3) integer :: ninfiles integer :: i, fp logical :: exist logical :: force !----------------------------------------------------------------------------------------------------------------------------------- !----------------------------------------------------------------------------------------------------------------------------------- !! initializing Command Line Interface call cli%init(progname = dfmoutput_basename, & version = dfmoutput_version, & description = 'Tool for handling D-Flow FM output files', & examples = ["dfmoutput mapmerge --infile model_0000_map.nc model_0001_map.nc", & "dfmoutput max_running_mean --infile hisfile.nc ", & "dfmoutput max25 --infile hisfile.nc ", & "dfmoutput genfilter --infile hisfile.nc --intval 6 "]) ! "dfmoutput extract --station='stat A' model_his.nc "]) ! setting Command Line Arguments call cli%add(switch='--verbose', switch_ab='-d', help='Print verbose diagnostics output.', required=.false., act='store_true', def='.false.') ! Set up MAPMERGE command call cli%add_group(group='mapmerge',description='Merge multiple map files from parallel run into one.') ! set Command Line Arguments of mapmerge command call cli%add(group='mapmerge',switch='--infile', switch_ab='-i', help='One or more input files.',required=.false.,act='store',def=char(0),valname='FILE',nargs='+') call cli%add(group='mapmerge',switch='--listfile',switch_ab='-F', help='Pass contents of LISTFILE as input files.',required=.false.,act='store',def='',valname='LISTFILE') call cli%add(group='mapmerge',switch='--outfile', switch_ab='-o', help='Write output to file DSTFILE. Default: _merged_map.nc',required=.false.,act='store',def='',valname='DSTFILE') call cli%add(group='mapmerge',switch='--force', switch_ab='-f', help='Force overwriting of existing output file.',required=.false.,act='store_true',def='.false.') call cli%add(group='mapmerge',switch='--time', switch_ab='-t', help='Only select certain time(s) from input files.'//char(10)// & 'A time argument can be one of:'//char(10)// & ' NUMBER time index in file, starting at 1.'//char(10)// & ' ''{'' DATETIME ''}'' datetime (ISO8601, e.g., 2015-07-31T15:37:28)'//char(10)// & ' ''LAST'' last available time in input file.', & required=.false.,act='store',def='',valname='TIME[:TIME2]') !! Set up MAX_RUNNING_MEAN command call cli%add_group(group='max_running_mean',description='Get max_running_mean value and other derived properties from his file.') call cli%add(group='max_running_mean',switch='--infile', switch_ab='-i', help='One input files.',required=.true.,act='store',def=char(0),valname='FILE') call cli%add(group='max_running_mean',switch='--filterlength', switch_ab='-l', help='Filter length. Default: 13,25',required=.false.,act='store',def='13,25',valname='FILTERLENGTH') call cli%add(group='max_running_mean',switch='--varname', help='Variable name. Default: waterlevel',required=.false.,act='store',def='waterlevel',valname='WATERLEVEL') call cli%add(group='max_running_mean',switch='--outfile', switch_ab='-o', help='Write output to file OUTFILE. Default: max_running_mean.out',required=.false.,act='store',def='max_running_mean.out',valname='OUTFILE') !! Set up MAX25 command call cli%add_group(group='max25',description='Get max25 value and other derived properties from his file.') call cli%add(group='max25',switch='--infile', switch_ab='-i', help='One input files.',required=.true.,act='store',def=char(0),valname='FILE') call cli%add(group='max25',switch='--filterlength', switch_ab='-l', help='Filter length. Default: 13,25',required=.false.,act='store',def='13,25',valname='FILTERLENGTH') call cli%add(group='max25',switch='--varname', help='Variable name. Default: waterlevel',required=.false.,act='store',def='waterlevel',valname='WATERLEVEL') call cli%add(group='max25',switch='--outfile', switch_ab='-o', help='Write output to file OUTFILE. Default: max25.out',required=.false.,act='store',def='max25.out',valname='OUTFILE') !! Set up gen_filter command call cli%add_group(group='genfilter',description='Get maximum value based on a generic filter.') call cli%add(group='genfilter',switch='--infile', switch_ab='-i', help='One input files.',required=.true.,act='store',def=char(0),valname='FILE') call cli%add(group='genfilter',switch='--varname', help='Variable name. Default: waterlevel',required=.false.,act='store',def='waterlevel',valname='WATERLEVEL') call cli%add(group='genfilter',switch='--outfile', switch_ab='-o', help='Write output to file OUTFILE. Default: max.out',required=.false.,act='store',def='max.out',valname='OUTFILE') call cli%add(group='genfilter',switch='--intval', help='filter period in terms of timesteps. Default: 6',required=.false.,act='store',def='6',valname='INTVAL') call cli%add(group='genfilter',switch='--coefimpl', help='Filter coefficient; impl. part. Default: 0.3',required=.false.,act='store',def='0.3',valname='COEFIMP') call cli%add(group='genfilter',switch='--coefexpl', help='Filter coefficient; expl. part. Default: 0.3',required=.false.,act='store',def='0.3',valname='COEFEXPL') !! Set up EXTRACT command !call cli%add_group(group='extract',description='Extract time series from a his file.') !call cli%add(group='extract', switch='--infile', switch_ab='-i', help='Read input from file SRCFILE.', required=.true., act='store', def='', valname='SRCFILE') !call cli%add(group='extract', switch='--outfile', switch_ab='-o', help='Write output to file DSTFILE.', required=.true., act='store', def='', valname='DSTFILE') !! Set up CONVERT command !call cli%add_group(group='convert',description='Convert file format') !call cli%add(group='convert', switch='--infile', switch_ab='-i', help='Read input from file SRCFILE.', required=.true., act='store', def='', valname='SRCFILE') !call cli%add(group='convert', switch='--outfile', switch_ab='-o', help='Write output to file DSTFILE.', required=.true., act='store', def='', valname='DSTFILE') !call cli%add(group='convert', switch='--informat', switch_ab='-if', help='Input format of SRCFILE.', required=.true., act='store', def='', valname='FILE', choices='CF-OLD,HIS') !call cli%add(group='convert', switch='--outformat', switch_ab='-of', help='Output format of SRCFILE.', required=.true., act='store', def='', valname='FILE', choices='UGRID,CSV') ! parsing Command Line Interface call cli%parse(error=ierr) if (ierr /= 0) goto 888 ! Check general options call cli%get(switch='-d', val = verbose_mode, error=ierr) if (verbose_mode) then write (*,'(a)') 'VERBOSE MODE' end if !----------------------------------------------------------------------------------------------------------------------------------- !! Start this run: Check which actual command needs to be done ! MAPMERGE command if (cli%run_command('mapmerge')) then if (verbose_mode) then write (*,'(a)') 'MAPMERGE mode' end if !! -i FILE1 [FILE2 ...] call cli%get_varying(group='mapmerge', switch='-i', val = infiles, error=ierr) if (ierr /= 0) goto 888 if (allocated(infiles)) then if (infiles(1)(1:1) /= char(0)) then ! Test for missing argument (dummy default was set to char(0)) ninfiles = size(infiles) else ninfiles = 0 end if else ninfiles = 0 end if !! -F LISTFILE1 (alternative for -i) call cli%get(group='mapmerge', switch='-F', val = listfile, error=ierr) if (ierr /= 0) goto 888 if (len_trim(listfile) > 0) then inquire(file=trim(listfile),exist=exist) if (exist) then open (newunit=fp, file = trim(listfile), action='read') ninfiles = 0 do read (fp, '(a)', end=100) rec if (len_trim(rec) > 0) then ninfiles = ninfiles + 1 end if end do 100 continue call realloc(infiles, ninfiles) rewind(fp) i = 0 do read (fp, '(a)', end=101) rec if (len_trim(rec) > 0) then i = i + 1 infiles(i) = trim(rec) end if end do 101 continue close (fp) else write (*,'(a)') 'Warning: dfmoutput: List file '''//trim(listfile)//'''not found.' end if end if !! -o OUTFILE allocate(outfiles(1)) outfiles(1) = '' call cli%get(group='mapmerge', switch='-o', val = outfiles(1), error=ierr) if (ierr /= 0) goto 888 call cli%get(group='mapmerge', switch='-f', val = force, error=ierr) if (ierr /= 0) goto 888 ierr = dfm_merge_mapfiles(infiles, ninfiles, outfiles(1), force) ! MAX_RUNNING_MEAN command for water levels else if (cli%run_command('max_running_mean')) then allocate(infiles(1)) allocate(outfiles(1)) call cli%get(group='max_running_mean', switch='-i', val = infiles(1), error=ierr) if (ierr /= 0) goto 888 call cli%get(group='max_running_mean', switch='-o', val = outfiles(1), error=ierr) if (ierr /= 0) goto 888 call cli%get(group='max_running_mean', switch='--varname', val = var_name, error=ierr) if (ierr /= 0) goto 888 call cli%get(group='max_running_mean', switch='-l', val = filter_length, error=ierr) if (ierr /= 0) goto 888 if (verbose_mode) then write(*,*) 'arguments for max25: ', trim(infiles(1)), ', ', trim(outfiles(1)), ', ', trim(var_name), ', ', trim(filter_length) endif call fmgetdata_running_mean(trim(infiles(1)), trim(outfiles(1)), trim(var_name), trim(filter_length)) ! MAX25 command for water levels else if (cli%run_command('max25')) then allocate(infiles(1)) allocate(outfiles(1)) call cli%get(group='max25', switch='-i', val = infiles(1), error=ierr) if (ierr /= 0) goto 888 call cli%get(group='max25', switch='-o', val = outfiles(1), error=ierr) if (ierr /= 0) goto 888 call cli%get(group='max25', switch='--varname', val = var_name, error=ierr) if (ierr /= 0) goto 888 call cli%get(group='max25', switch='-l', val = filter_length, error=ierr) if (ierr /= 0) goto 888 if (verbose_mode) then write(*,*) 'arguments for max25: ', trim(infiles(1)), ', ', trim(outfiles(1)), ', ', trim(var_name), ', ', trim(filter_length) endif call fmgetdata(trim(infiles(1)), trim(outfiles(1)), trim(var_name), trim(filter_length)) ! genfilter command for water levels else if (cli%run_command('genfilter')) then allocate(infiles(1)) allocate(outfiles(1)) call cli%get(group='genfilter', switch='-i', val = infiles(1), error=ierr) if (ierr /= 0) goto 888 call cli%get(group='genfilter', switch='-o', val = outfiles(1), error=ierr) if (ierr /= 0) goto 888 call cli%get(group='genfilter', switch='--varname', val = var_name, error=ierr) if (ierr /= 0) goto 888 call cli%get(group='genfilter', switch='--intval', val = coeff(1), error=ierr) if (ierr /= 0) goto 888 call cli%get(group='genfilter', switch='--coefimpl', val = coeff(2), error=ierr) if (ierr /= 0) goto 888 call cli%get(group='genfilter', switch='--coefexpl', val = coeff(3), error=ierr) if (ierr /= 0) goto 888 do i=1,3 read(coeff(i),*) rcoeff(i) enddo if (verbose_mode) then write(*,*) 'arguments for genfilter: ', trim(infiles(1)), ', ', trim(outfiles(1)), ', ', trim(var_name) write(*,*) 'coefficients: ', rcoeff endif call gen_filter(trim(infiles(1)), trim(outfiles(1)), trim(var_name), rcoeff(1), rcoeff(2), rcoeff(3)) ! EXTRACT command else if (cli%run_command('extract')) then write (*,'(a)') 'Error: EXTRACT command not implemented yet.' goto 999 ! CONVERT command else if (cli%run_command('convert')) then write (*,'(a)') 'Error: CONVERT command not implemented yet.' goto 999 end if goto 999 888 continue ! Error handling write (*,'(a)') 'Error code: '//trim(str(n=ierr)) 999 continue if (allocated(infiles)) deallocate(infiles) if (allocated(outfiles)) deallocate(outfiles) !!----------------------------------------------------------------------------------------------------------------------------------- end program dfmoutput