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,
'e3)')
714 if (this%idigits == 0)
then
715 this%obsfmtcont =
'(G0)'
717 write (this%obsfmtcont, 50) this%idigits + 8, this%idigits
733 call this%read_obs_blocks(this%outputFilename)
736 call this%build_headers()
763 use iso_fortran_env,
only: int32
772 integer(int32) :: nobs
773 character(len=4) :: clenobsname
780 num = this%obsOutputList%Count()
781 all_obsfiles:
do i = 1, num
782 obsoutput => this%obsOutputList%Get(i)
783 nobs = obsoutput%nobs
787 if (obsoutput%FormattedOutput)
then
788 write (iu,
'(a)', advance=
'NO')
'time'
792 if (this%iprecision == 1)
then
794 write (iu)
'cont single'
795 else if (this%iprecision == 2)
then
797 write (iu)
'cont double'
801 write (iu) clenobsname
811 obsfile:
do ii = 1, nobs
812 obsrv => this%get_obs(idx)
813 if (obsoutput%FormattedOutput)
then
814 write (iu,
'(a,a)', advance=
'NO')
',', trim(obsrv%Name)
818 write (iu,
'(a)', advance=
'YES')
''
821 write (iu) obsrv%Name
836 class(
obstype),
intent(inout) :: this
837 integer(I4B),
intent(out) :: nObs
840 nobs = this%get_num()
841 if (
associated(obsarray))
deallocate (obsarray)
842 allocate (obsarray(nobs))
846 call this%set_obs_array(nobs, obsarray)
858 character(len=*),
intent(in) :: obstypeid
866 if (this%obsData(i)%ObsTypeID == obstypeid)
then
867 obsdatum => this%obsData(i)
872 if (.not.
associated(obsdatum))
then
873 errmsg =
'Observation type not found: '//trim(obstypeid)
886 class(
obstype),
intent(inout) :: this
887 integer(I4B),
intent(in) :: nObs
897 obsrv => this%get_obs(i)
898 obsarray(i)%obsrv => obsrv
911 integer(I4B),
intent(in) :: indx
924 class(
obstype),
intent(inout) :: this
925 character(len=*),
intent(inout) :: fname
927 integer(I4B) :: ierr, indexobsout, numspec
928 logical :: fmtd, found, endOfBlock
929 character(len=LENBIGLINE) :: pnamein, fnamein
930 character(len=LENHUGELINE) :: line
931 character(len=LINELENGTH) :: btagfound, message, word
932 character(len=LINELENGTH) :: title
933 character(len=LINELENGTH) :: tag
934 character(len=20) :: accarg, bin, fmtarg
937 integer(I4B) :: ntabrows
938 integer(I4B) :: ntabcols
944 inquire (unit=this%parser%iuactive, name=pnamein)
955 title =
'OBSERVATIONS READ FROM FILE "'//trim(fnamein)//
'"'
956 call table_cr(this%obstab, fnamein, title)
957 call this%obstab%table_df(ntabrows, ntabcols, this%iout, &
964 call this%obstab%initialize_column(tag, 12, alignment=
tableft)
965 tag =
'LOCATION DATA'
967 tag =
'OUTPUT FILENAME'
968 call this%obstab%initialize_column(tag, 80, alignment=
tableft)
973 if (.not. found)
exit
975 call this%parser%GetBlock(
'*', found, ierr, .true., .false., btagfound)
976 if (.not. found)
then
979 this%blockTypeFound = btagfound
982 call this%parser%GetStringCaps(word)
983 if (word /=
'FILEOUT')
then
984 call store_error(
'CONTINUOUS keyword must be followed by '// &
985 '"FILEOUT" then by filename.')
990 call this%parser%GetString(fname)
992 if (fname ==
'')
then
993 message =
'Error reading OBS input file, likely due to bad'// &
994 ' block or missing file name.'
997 else if (this%obsOutputList%ContainsFile(fname))
then
998 errmsg =
'OBS outfile "'//trim(fname)// &
999 '" is provided more than once.'
1005 call this%parser%GetStringCaps(bin)
1006 if (bin ==
'BINARY')
then
1011 fmtarg =
'FORMATTED'
1012 accarg =
'SEQUENTIAL'
1018 call openfile(numspec, 0, fname,
'OBS OUTPUT', fmtarg, &
1023 call this%obsOutputList%Add(fname, numspec)
1024 indexobsout = this%obsOutputList%Count()
1025 obsoutput => this%obsOutputList%Get(indexobsout)
1026 obsoutput%FormattedOutput = fmtd
1029 select case (btagfound)
1033 readblockcontinuous:
do
1034 call this%parser%GetNextLine(endofblock)
1035 if (endofblock)
exit
1036 call this%parser%GetCurrentLine(line)
1038 indexobsout, this%obsData, &
1039 this%parser%iuactive)
1043 obsoutput => this%obsOutputList%Get(indexobsout)
1044 obsoutput%nobs = obsoutput%nobs + 1
1049 call obsrv%WriteTo(this%obstab, btagfound, fname)
1051 end do readblockcontinuous
1053 errmsg =
'Error: Observation block type not recognized: '// &
1061 call this%obstab%finalize_table()
1066 call this%parser%StoreErrorUnit()
1078 class(
obstype),
intent(inout) :: this
1081 integer(I4B) :: iprec
1082 integer(I4B) :: numobs
1083 character(len=20) :: fmtc
1088 iprec = this%iprecision
1089 fmtc = this%obsfmtcont
1091 numobs = this%obsList%Count()
1093 obsrv => this%get_obs(i)
1095 simval = obsrv%CurrentTimeStepEndValue
1096 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.