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
252 integer(I4B),
intent(in) :: inunitobs
253 integer(I4B),
intent(in) :: iout
256 integer(I4B) :: icol, istart, istop
257 character(len=LINELENGTH) :: string
258 logical :: flag_string
261 string = obsrv%IDstring
265 n = dis%noder_from_string(icol, istart, istop, inunitobs, &
266 iout, string, flag_string)
270 elseif (n == -2)
then
273 obsrv%FeatureName = string(istart:istop)
279 errmsg =
'Error reading data from ID string'
295 subroutine obs_df(this, iout, pkgname, filtyp, dis)
297 class(
obstype),
intent(inout) :: this
298 integer(I4B),
intent(in) :: iout
299 character(len=*),
intent(in) :: pkgname
300 character(len=*),
intent(in) :: filtyp
304 this%pkgName = pkgname
309 call this%parser%Initialize(this%inUnitObs, this%iout)
327 call this%obs_ar1(this%pkgName)
328 if (this%active)
then
329 call this%obs_ar2(this%dis)
351 obsrv => this%get_obs(i)
352 call obsrv%ResetCurrentValue()
369 call this%obsOutputList%ResetAllObsEmptyLines()
389 class(
obstype),
intent(inout) :: this
391 if (this%npakobs > 0)
then
392 call this%write_obs_simvals()
393 call this%obsOutputList%WriteAllObsLineReturns()
407 class(
obstype),
intent(inout) :: this
412 deallocate (this%active)
413 deallocate (this%inputFilename)
414 deallocate (this%obsData)
417 if (
associated(this%obstab))
then
418 call this%obstab%table_da()
419 deallocate (this%obstab)
420 nullify (this%obstab)
424 if (
associated(this%pakobs))
then
425 do i = 1, this%npakobs
426 obsrv => this%pakobs(i)%obsrv
429 nullify (this%pakobs(i)%obsrv)
431 deallocate (this%pakobs)
435 call this%obsOutputList%DeallocObsOutputList()
436 deallocate (this%obsOutputList)
439 call this%obslist%Clear()
442 nullify (this%inUnitObs)
458 real(DP),
intent(in) :: simval
460 character(len=LENOBSTYPE) :: obsTypeID
464 obstypeid = obsrv%ObsTypeId
465 obsdatum => this%get_obs_datum(obstypeid)
468 obsrv%CurrentTimeStepEndTime =
totim
471 if (obsdatum%Cumulative .and. simval /=
dnodata)
then
472 obsrv%CurrentTimeStepEndValue = obsrv%CurrentTimeStepEndValue + simval
474 obsrv%CurrentTimeStepEndValue = simval
490 class(
obstype),
intent(inout) :: this
491 character(len=*),
intent(in) :: obsrvType
493 logical,
intent(in) :: cumulative
494 integer(I4B),
intent(out) :: indx
497 character(len=LENOBSTYPE) :: obsTypeUpper
498 character(len=100) :: msg
501 if (obsrvtype ==
'')
then
502 msg =
'Programmer error: Invalid argument in store_obs_type.'
509 if (this%obsData(i)%ObsTypeID /=
'') cycle
516 msg =
'Size of obsData array is insufficient; ' &
517 //
'need to increase MAXOBSTYPES.'
523 obstypeupper = obsrvtype
527 this%obsData(indx)%ObsTypeID = obstypeupper
528 this%obsData(indx)%Cumulative = cumulative
546 allocate (this%active)
547 allocate (this%inputFilename)
548 allocate (this%obsOutputList)
552 this%active = .false.
553 this%inputFilename =
''
567 class(
obstype),
intent(inout) :: this
568 character(len=*),
intent(in) :: pkgname
570 10
format(/,
'The observation utility is active for "', a,
'"')
572 if (this%inUnitObs > 0)
then
576 write (this%iout, 10) trim(pkgname)
579 call this%read_obs_options()
582 call this%define_fmts()
597 class(
obstype),
intent(inout) :: this
602 character(len=LENOBSTYPE) :: obsTypeID
605 call this%read_observations()
607 call this%get_obs_array(this%npakobs, this%pakobs)
609 do i = 1, this%npakobs
610 obsrv => this%pakobs(i)%obsrv
612 obstypeid = obsrv%ObsTypeId
613 obsdat => this%get_obs_datum(obstypeid)
614 if (
associated(obsdat%ProcessIdPtr))
then
615 call obsdat%ProcessIdPtr(obsrv, dis, &
616 this%inUnitObs, this%iout)
619 this%inUnitObs, this%iout)
642 integer(I4B) :: localprecision
643 integer(I4B) :: localdigits
644 character(len=40) :: keyword
645 character(len=LINELENGTH) :: fname
646 type(
listtype),
pointer :: lineList => null()
647 logical :: continueread, found, endOfBlock
649 10
format(
'No options block found in OBS input. Defaults will be used.')
650 40
format(
'Text output number of digits of precision set to: ', i2)
651 50
format(
'Text output number of digits set to internal representation (G0).')
652 60
format(/,
'Processing observation options:',/)
660 inquire (unit=iin, name=fname)
661 this%inputFilename = fname
664 continueread = .false.
668 call this%parser%GetBlock(
'OPTIONS', found, ierr, &
669 supportopenclose=.true., blockrequired=.false.)
672 errmsg =
'End-of-file encountered while searching for'// &
673 ' OPTIONS in OBS '// &
674 'input file "'//trim(this%inputFilename)//
'"'
676 call this%parser%StoreErrorUnit()
677 elseif (.not. found)
then
678 this%blockTypeFound =
''
679 if (this%iout > 0)
write (this%iout, 10)
684 write (this%iout, 60)
686 call this%parser%GetNextLine(endofblock)
688 call this%parser%GetStringCaps(keyword)
689 select case (keyword)
693 if (localdigits /= -1)
then
694 errmsg =
'Error in OBS input: DIGITS has already been defined'
696 exit readblockoptions
703 localdigits = this%parser%GetInteger()
706 if (localdigits == 0)
then
707 write (this%iout, 50)
708 else if (localdigits < 1)
then
709 errmsg =
'Error in OBS input: Invalid value for DIGITS option'
711 exit readblockoptions
713 if (localdigits < 2) localdigits = 2
714 if (localdigits > 16) localdigits = 16
715 write (this%iout, 40) localdigits
719 write (this%iout,
'(a)')
'The PRINT_INPUT option has been specified.'
721 errmsg =
'Error in OBS input: Unrecognized option: '// &
724 exit readblockoptions
726 end do readblockoptions
730 call this%parser%StoreErrorUnit()
733 write (this%iout,
'(1x)')
736 if (localprecision > 0) this%iprecision = localprecision
737 if (localdigits >= 0) this%idigits = localdigits
752 50
format(
'(g', i2.2,
'.', i2.2,
')')
754 if (this%idigits == 0)
then
755 this%obsfmtcont =
'(G0)'
757 write (this%obsfmtcont, 50) this%idigits + 7, this%idigits
776 call this%read_obs_blocks(this%outputFilename)
779 call this%build_headers()
812 use iso_fortran_env,
only: int32
821 integer(int32) :: nobs
822 character(len=4) :: clenobsname
829 num = this%obsOutputList%Count()
830 all_obsfiles:
do i = 1, num
831 obsoutput => this%obsOutputList%Get(i)
832 nobs = obsoutput%nobs
836 if (obsoutput%FormattedOutput)
then
837 write (iu,
'(a)', advance=
'NO')
'time'
841 if (this%iprecision == 1)
then
843 write (iu)
'cont single'
844 else if (this%iprecision == 2)
then
846 write (iu)
'cont double'
850 write (iu) clenobsname
860 obsfile:
do ii = 1, nobs
861 obsrv => this%get_obs(idx)
862 if (obsoutput%FormattedOutput)
then
863 write (iu,
'(a,a)', advance=
'NO')
',', trim(obsrv%Name)
867 write (iu,
'(a)', advance=
'YES')
''
870 write (iu) obsrv%Name
888 class(
obstype),
intent(inout) :: this
889 integer(I4B),
intent(out) :: nObs
892 nobs = this%get_num()
893 if (
associated(obsarray))
deallocate (obsarray)
894 allocate (obsarray(nobs))
898 call this%set_obs_array(nobs, obsarray)
913 character(len=*),
intent(in) :: obstypeid
921 if (this%obsData(i)%ObsTypeID == obstypeid)
then
922 obsdatum => this%obsData(i)
927 if (.not.
associated(obsdatum))
then
928 errmsg =
'Observation type not found: '//trim(obstypeid)
944 class(
obstype),
intent(inout) :: this
945 integer(I4B),
intent(in) :: nObs
955 obsrv => this%get_obs(i)
956 obsarray(i)%obsrv => obsrv
972 integer(I4B),
intent(in) :: indx
988 class(
obstype),
intent(inout) :: this
989 character(len=*),
intent(inout) :: fname
991 integer(I4B) :: ierr, indexobsout, numspec
992 logical :: fmtd, found, endOfBlock
993 character(len=LENBIGLINE) :: pnamein, fnamein
994 character(len=LENHUGELINE) :: line
995 character(len=LINELENGTH) :: btagfound, message, word
996 character(len=LINELENGTH) :: title
997 character(len=LINELENGTH) :: tag
998 character(len=20) :: accarg, bin, fmtarg
1001 integer(I4B) :: ntabrows
1002 integer(I4B) :: ntabcols
1008 inquire (unit=this%parser%iuactive, name=pnamein)
1019 title =
'OBSERVATIONS READ FROM FILE "'//trim(fnamein)//
'"'
1020 call table_cr(this%obstab, fnamein, title)
1021 call this%obstab%table_df(ntabrows, ntabcols, this%iout, &
1028 call this%obstab%initialize_column(tag, 12, alignment=
tableft)
1029 tag =
'LOCATION DATA'
1031 tag =
'OUTPUT FILENAME'
1032 call this%obstab%initialize_column(tag, 80, alignment=
tableft)
1037 if (.not. found)
exit
1039 call this%parser%GetBlock(
'*', found, ierr, .true., .false., btagfound)
1040 if (.not. found)
then
1043 this%blockTypeFound = btagfound
1046 call this%parser%GetStringCaps(word)
1047 if (word /=
'FILEOUT')
then
1048 call store_error(
'CONTINUOUS keyword must be followed by '// &
1049 '"FILEOUT" then by filename.')
1054 call this%parser%GetString(fname)
1056 if (fname ==
'')
then
1057 message =
'Error reading OBS input file, likely due to bad'// &
1058 ' block or missing file name.'
1061 else if (this%obsOutputList%ContainsFile(fname))
then
1062 errmsg =
'OBS outfile "'//trim(fname)// &
1063 '" is provided more than once.'
1069 call this%parser%GetStringCaps(bin)
1070 if (bin ==
'BINARY')
then
1075 fmtarg =
'FORMATTED'
1076 accarg =
'SEQUENTIAL'
1082 call openfile(numspec, 0, fname,
'OBS OUTPUT', fmtarg, &
1087 call this%obsOutputList%Add(fname, numspec)
1088 indexobsout = this%obsOutputList%Count()
1089 obsoutput => this%obsOutputList%Get(indexobsout)
1090 obsoutput%FormattedOutput = fmtd
1093 select case (btagfound)
1097 readblockcontinuous:
do
1098 call this%parser%GetNextLine(endofblock)
1099 if (endofblock)
exit
1100 call this%parser%GetCurrentLine(line)
1102 indexobsout, this%obsData, &
1103 this%parser%iuactive)
1107 obsoutput => this%obsOutputList%Get(indexobsout)
1108 obsoutput%nobs = obsoutput%nobs + 1
1113 call obsrv%WriteTo(this%obstab, btagfound, fname)
1115 end do readblockcontinuous
1117 errmsg =
'Error: Observation block type not recognized: '// &
1125 call this%obstab%finalize_table()
1130 call this%parser%StoreErrorUnit()
1145 class(
obstype),
intent(inout) :: this
1148 integer(I4B) :: iprec
1149 integer(I4B) :: numobs
1150 character(len=20) :: fmtc
1155 iprec = this%iprecision
1156 fmtc = this%obsfmtcont
1158 numobs = this%obsList%Count()
1160 obsrv => this%get_obs(i)
1162 simval = obsrv%CurrentTimeStepEndValue
1163 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.