160 integer(I4B),
public :: iout = 0
161 integer(I4B),
public :: npakobs = 0
162 integer(I4B),
pointer,
public :: inunitobs => null()
163 character(len=LINELENGTH),
pointer,
public :: inputfilename => null()
164 character(len=2*LENPACKAGENAME + 4),
public :: pkgname =
''
165 character(len=LENFTYPE),
public :: filtyp =
''
166 logical,
pointer,
public :: active => null()
168 type(
obsdatatype),
dimension(:),
pointer,
public :: obsdata => null()
170 integer(I4B),
private :: iprecision = 2
171 integer(I4B),
private :: idigits = 0
172 character(len=LINELENGTH),
private :: outputfilename =
''
173 character(len=LINELENGTH),
private :: blocktypefound =
''
174 character(len=20),
private :: obsfmtcont =
''
175 logical,
private :: echo = .false.
176 logical,
private :: more
226 type(
obstype),
pointer,
intent(out) :: obs
227 integer(I4B),
pointer,
intent(in) :: inobs
230 call obs%allocate_scalars()
231 obs%inUnitObs => inobs
249 integer(I4B),
intent(in) :: inunitobs
250 integer(I4B),
intent(in) :: iout
253 integer(I4B) :: icol, istart, istop
254 character(len=LINELENGTH) :: string
255 logical :: flag_string
258 string = obsrv%IDstring
262 n = dis%noder_from_string(icol, istart, istop, inunitobs, &
263 iout, string, flag_string)
267 elseif (n == -2)
then
270 obsrv%FeatureName = string(istart:istop)
276 errmsg =
'Error reading data from ID string'
289 subroutine obs_df(this, iout, pkgname, filtyp, dis)
291 class(
obstype),
intent(inout) :: this
292 integer(I4B),
intent(in) :: iout
293 character(len=*),
intent(in) :: pkgname
294 character(len=*),
intent(in) :: filtyp
298 this%pkgName = pkgname
303 call this%parser%Initialize(this%inUnitObs, this%iout)
318 call this%obs_ar1(this%pkgName)
319 if (this%active)
then
320 call this%obs_ar2(this%dis)
339 obsrv => this%get_obs(i)
340 call obsrv%ResetCurrentValue()
354 call this%obsOutputList%ResetAllObsEmptyLines()
371 class(
obstype),
intent(inout) :: this
373 if (this%npakobs > 0)
then
374 call this%write_obs_simvals()
375 call this%obsOutputList%WriteAllObsLineReturns()
386 class(
obstype),
intent(inout) :: this
391 deallocate (this%active)
392 deallocate (this%inputFilename)
393 deallocate (this%obsData)
396 if (
associated(this%obstab))
then
397 call this%obstab%table_da()
398 deallocate (this%obstab)
399 nullify (this%obstab)
403 if (
associated(this%pakobs))
then
404 do i = 1, this%npakobs
405 obsrv => this%pakobs(i)%obsrv
408 nullify (this%pakobs(i)%obsrv)
410 deallocate (this%pakobs)
414 call this%obsOutputList%DeallocObsOutputList()
415 deallocate (this%obsOutputList)
418 call this%obslist%Clear()
421 nullify (this%inUnitObs)
434 real(DP),
intent(in) :: simval
436 character(len=LENOBSTYPE) :: obsTypeID
440 obstypeid = obsrv%ObsTypeId
441 obsdatum => this%get_obs_datum(obstypeid)
444 obsrv%CurrentTimeStepEndTime =
totim
447 if (obsdatum%Cumulative .and. simval /=
dnodata)
then
448 obsrv%CurrentTimeStepEndValue = obsrv%CurrentTimeStepEndValue + simval
450 obsrv%CurrentTimeStepEndValue = simval
463 class(
obstype),
intent(inout) :: this
464 character(len=*),
intent(in) :: obsrvType
466 logical,
intent(in) :: cumulative
467 integer(I4B),
intent(out) :: indx
470 character(len=LENOBSTYPE) :: obsTypeUpper
471 character(len=100) :: msg
474 if (obsrvtype ==
'')
then
475 msg =
'Programmer error: Invalid argument in store_obs_type.'
482 if (this%obsData(i)%ObsTypeID /=
'') cycle
489 msg =
'Size of obsData array is insufficient; ' &
490 //
'need to increase MAXOBSTYPES.'
496 obstypeupper = obsrvtype
500 this%obsData(indx)%ObsTypeID = obstypeupper
501 this%obsData(indx)%Cumulative = cumulative
516 allocate (this%active)
517 allocate (this%inputFilename)
518 allocate (this%obsOutputList)
522 this%active = .false.
523 this%inputFilename =
''
534 class(
obstype),
intent(inout) :: this
535 character(len=*),
intent(in) :: pkgname
537 10
format(/,
'The observation utility is active for "', a,
'"')
539 if (this%inUnitObs > 0)
then
543 write (this%iout, 10) trim(pkgname)
546 call this%read_obs_options()
549 call this%define_fmts()
561 class(
obstype),
intent(inout) :: this
566 character(len=LENOBSTYPE) :: obsTypeID
569 call this%read_observations()
571 call this%get_obs_array(this%npakobs, this%pakobs)
573 do i = 1, this%npakobs
574 obsrv => this%pakobs(i)%obsrv
576 obstypeid = obsrv%ObsTypeId
577 obsdat => this%get_obs_datum(obstypeid)
578 if (
associated(obsdat%ProcessIdPtr))
then
579 call obsdat%ProcessIdPtr(obsrv, dis, &
580 this%inUnitObs, this%iout)
583 this%inUnitObs, this%iout)
603 integer(I4B) :: localprecision
604 integer(I4B) :: localdigits
605 character(len=40) :: keyword
606 character(len=LINELENGTH) :: fname
607 type(
listtype),
pointer :: lineList => null()
608 logical :: continueread, found, endOfBlock
610 10
format(
'No options block found in OBS input. Defaults will be used.')
611 40
format(
'Text output number of digits of precision set to: ', i2)
612 50
format(
'Text output number of digits set to internal representation (G0).')
613 60
format(/,
'Processing observation options:',/)
621 inquire (unit=iin, name=fname)
622 this%inputFilename = fname
625 continueread = .false.
629 call this%parser%GetBlock(
'OPTIONS', found, ierr, &
630 supportopenclose=.true., blockrequired=.false.)
633 errmsg =
'End-of-file encountered while searching for'// &
634 ' OPTIONS in OBS '// &
635 'input file "'//trim(this%inputFilename)//
'"'
637 call this%parser%StoreErrorUnit()
638 elseif (.not. found)
then
639 this%blockTypeFound =
''
640 if (this%iout > 0)
write (this%iout, 10)
645 write (this%iout, 60)
647 call this%parser%GetNextLine(endofblock)
649 call this%parser%GetStringCaps(keyword)
650 select case (keyword)
654 if (localdigits /= -1)
then
655 errmsg =
'Error in OBS input: DIGITS has already been defined'
657 exit readblockoptions
664 localdigits = this%parser%GetInteger()
667 if (localdigits == 0)
then
668 write (this%iout, 50)
669 else if (localdigits < 1)
then
670 errmsg =
'Error in OBS input: Invalid value for DIGITS option'
672 exit readblockoptions
674 if (localdigits < 2) localdigits = 2
675 if (localdigits > 16) localdigits = 16
676 write (this%iout, 40) localdigits
680 write (this%iout,
'(a)')
'The PRINT_INPUT option has been specified.'
682 errmsg =
'Error in OBS input: Unrecognized option: '// &
685 exit readblockoptions
687 end do readblockoptions
691 call this%parser%StoreErrorUnit()
694 write (this%iout,
'(1x)')
697 if (localprecision > 0) this%iprecision = localprecision
698 if (localdigits >= 0) this%idigits = localdigits
710 50
format(
'(g', i2.2,
'.', i2.2,
')')
712 if (this%idigits == 0)
then
713 this%obsfmtcont =
'(G0)'
715 write (this%obsfmtcont, 50) this%idigits + 7, this%idigits
731 call this%read_obs_blocks(this%outputFilename)
734 call this%build_headers()
761 use iso_fortran_env,
only: int32
770 integer(int32) :: nobs
771 character(len=4) :: clenobsname
778 num = this%obsOutputList%Count()
779 all_obsfiles:
do i = 1, num
780 obsoutput => this%obsOutputList%Get(i)
781 nobs = obsoutput%nobs
785 if (obsoutput%FormattedOutput)
then
786 write (iu,
'(a)', advance=
'NO')
'time'
790 if (this%iprecision == 1)
then
792 write (iu)
'cont single'
793 else if (this%iprecision == 2)
then
795 write (iu)
'cont double'
799 write (iu) clenobsname
809 obsfile:
do ii = 1, nobs
810 obsrv => this%get_obs(idx)
811 if (obsoutput%FormattedOutput)
then
812 write (iu,
'(a,a)', advance=
'NO')
',', trim(obsrv%Name)
816 write (iu,
'(a)', advance=
'YES')
''
819 write (iu) obsrv%Name
834 class(
obstype),
intent(inout) :: this
835 integer(I4B),
intent(out) :: nObs
838 nobs = this%get_num()
839 if (
associated(obsarray))
deallocate (obsarray)
840 allocate (obsarray(nobs))
844 call this%set_obs_array(nobs, obsarray)
856 character(len=*),
intent(in) :: obstypeid
864 if (this%obsData(i)%ObsTypeID == obstypeid)
then
865 obsdatum => this%obsData(i)
870 if (.not.
associated(obsdatum))
then
871 errmsg =
'Observation type not found: '//trim(obstypeid)
884 class(
obstype),
intent(inout) :: this
885 integer(I4B),
intent(in) :: nObs
895 obsrv => this%get_obs(i)
896 obsarray(i)%obsrv => obsrv
909 integer(I4B),
intent(in) :: indx
922 class(
obstype),
intent(inout) :: this
923 character(len=*),
intent(inout) :: fname
925 integer(I4B) :: ierr, indexobsout, numspec
926 logical :: fmtd, found, endOfBlock
927 character(len=LENBIGLINE) :: pnamein, fnamein
928 character(len=LENHUGELINE) :: line
929 character(len=LINELENGTH) :: btagfound, message, word
930 character(len=LINELENGTH) :: title
931 character(len=LINELENGTH) :: tag
932 character(len=20) :: accarg, bin, fmtarg
935 integer(I4B) :: ntabrows
936 integer(I4B) :: ntabcols
942 inquire (unit=this%parser%iuactive, name=pnamein)
953 title =
'OBSERVATIONS READ FROM FILE "'//trim(fnamein)//
'"'
954 call table_cr(this%obstab, fnamein, title)
955 call this%obstab%table_df(ntabrows, ntabcols, this%iout, &
962 call this%obstab%initialize_column(tag, 12, alignment=
tableft)
963 tag =
'LOCATION DATA'
965 tag =
'OUTPUT FILENAME'
966 call this%obstab%initialize_column(tag, 80, alignment=
tableft)
971 if (.not. found)
exit
973 call this%parser%GetBlock(
'*', found, ierr, .true., .false., btagfound)
974 if (.not. found)
then
977 this%blockTypeFound = btagfound
980 call this%parser%GetStringCaps(word)
981 if (word /=
'FILEOUT')
then
982 call store_error(
'CONTINUOUS keyword must be followed by '// &
983 '"FILEOUT" then by filename.')
988 call this%parser%GetString(fname)
990 if (fname ==
'')
then
991 message =
'Error reading OBS input file, likely due to bad'// &
992 ' block or missing file name.'
995 else if (this%obsOutputList%ContainsFile(fname))
then
996 errmsg =
'OBS outfile "'//trim(fname)// &
997 '" is provided more than once.'
1003 call this%parser%GetStringCaps(bin)
1004 if (bin ==
'BINARY')
then
1009 fmtarg =
'FORMATTED'
1010 accarg =
'SEQUENTIAL'
1016 call openfile(numspec, 0, fname,
'OBS OUTPUT', fmtarg, &
1021 call this%obsOutputList%Add(fname, numspec)
1022 indexobsout = this%obsOutputList%Count()
1023 obsoutput => this%obsOutputList%Get(indexobsout)
1024 obsoutput%FormattedOutput = fmtd
1027 select case (btagfound)
1031 readblockcontinuous:
do
1032 call this%parser%GetNextLine(endofblock)
1033 if (endofblock)
exit
1034 call this%parser%GetCurrentLine(line)
1036 indexobsout, this%obsData, &
1037 this%parser%iuactive)
1041 obsoutput => this%obsOutputList%Get(indexobsout)
1042 obsoutput%nobs = obsoutput%nobs + 1
1047 call obsrv%WriteTo(this%obstab, btagfound, fname)
1049 end do readblockcontinuous
1051 errmsg =
'Error: Observation block type not recognized: '// &
1059 call this%obstab%finalize_table()
1064 call this%parser%StoreErrorUnit()
1076 class(
obstype),
intent(inout) :: this
1079 integer(I4B) :: iprec
1080 integer(I4B) :: numobs
1081 character(len=20) :: fmtc
1086 iprec = this%iprecision
1087 fmtc = this%obsfmtcont
1089 numobs = this%obsList%Count()
1091 obsrv => this%get_obs(i)
1093 simval = obsrv%CurrentTimeStepEndValue
1094 if (obsrv%FormattedOutput)
then
This module contains block parser methods.
This module contains simulation constants.
integer(i4b), parameter linelength
maximum length of a standard line
@ tableft
left justified table column
integer(i4b), parameter lenpackagename
maximum length of the package name
integer(i4b), parameter namedboundflag
named bound flag
real(dp), parameter dnodata
real no data constant
integer(i4b), parameter lenhugeline
maximum length of a huge line
integer(i4b), parameter lenbigline
maximum length of a big line
integer(i4b), parameter maxobstypes
maximum number of observation types
integer(i4b), parameter lenftype
maximum length of a package type (DIS, WEL, OC, etc.)
integer(i4b), parameter lenboundname
maximum length of a bound name
integer(i4b), parameter lenobsname
maximum length of a observation name
integer(i4b), parameter maxcharlen
maximum length of char string
integer(i4b), parameter lenobstype
maximum length of a observation type (CONTINUOUS)
This module defines variable data types.
This module contains the derived type ObsContainerType.
This module contains the derived types ObserveType and ObsDataType.
subroutine, public constructobservation(newObservation, defLine, numunit, formatted, indx, obsData, inunit)
@ brief Construct a new ObserveType
type(observetype) function, pointer, public getobsfromlist(list, idx)
@ brief Get an ObserveType from a list
subroutine, public addobstolist(list, obs)
@ brief Add a ObserveType to a list
This module contains the derived type ObsType.
subroutine write_obs_simvals(this)
@ brief Write observation data
subroutine read_obs_blocks(this, fname)
@ brief Read observation blocks
subroutine obs_da(this)
@ brief Deallocate observation data
type(obsdatatype) function, pointer get_obs_datum(this, obsTypeID)
@ brief Get an ObsDataType object
subroutine set_obs_array(this, nObs, obsArray)
@ brief Set observation array values
subroutine obs_bd_clear(this)
@ brief Clear observation output lines
subroutine obs_ar(this)
@ brief Allocate and read package observations
subroutine obs_ar1(this, pkgname)
@ brief Read observation options and output formats
subroutine read_observations(this)
@ brief Read observations
subroutine obs_ad(this)
@ brief Advance package observations
subroutine, public obs_cr(obs, inobs)
@ brief Create a new ObsType object
subroutine get_obs_array(this, nObs, obsArray)
@ brief Get an array of observations
subroutine read_obs_options(this)
@ brief Read observation options block
subroutine, public defaultobsidprocessor(obsrv, dis, inunitobs, iout)
@ brief Process IDstring provided for each observation
subroutine define_fmts(this)
@ brief Define observation output formats
subroutine obs_df(this, iout, pkgname, filtyp, dis)
@ brief Define some members of an ObsType object
integer(i4b) function get_num(this)
@ brief Get the number of observations
subroutine storeobstype(this, obsrvType, cumulative, indx)
@ brief Store observation type
subroutine build_headers(this)
@ brief Build observation headers
subroutine saveonesimval(this, obsrv, simval)
@ brief Save a simulated value
subroutine allocate_scalars(this)
@ brief Allocate observation scalars
subroutine obs_ot(this)
@ brief Output observation data
class(observetype) function, pointer get_obs(this, indx)
@ brief Get an ObserveType object
subroutine obs_ar2(this, dis)
@ brief Call procedure provided by package
This module defines the derived type ObsOutputListType.
This module defines the derived type ObsOutputType.
This module contains the ObsUtilityModule module.
subroutine, public write_fmtd_obs(fmtc, obsrv, obsOutputList, value)
@ brief Write formatted observation
subroutine, public write_unfmtd_obs(obsrv, iprec, obsOutputList, value)
@ brief Write unformatted observation
This module contains simulation methods.
subroutine, public store_error(msg, terminate)
Store an error message.
integer(i4b) function, public count_errors()
Return number of errors.
subroutine, public store_error_unit(iunit, terminate)
Store the file unit number.
This module contains simulation variables.
character(len=maxcharlen) errmsg
error message string
subroutine, public table_cr(this, name, title)
real(dp), pointer, public totim
time relative to start of simulation
A generic heterogeneous doubly-linked list.