23 use fckit_log_module,
only : fckit_log
39 character(len=max_string) :: filein, fileout
43 #define LISTED_TYPE obs_data 46 #include "oops/util/linkedList_i.f" 55 character(len=50) :: grpname
58 integer,
allocatable :: seqnos(:)
59 type(datetime),
allocatable :: times(:)
67 character(len=50) :: colname
70 real(kind=kind_real),
allocatable :: values(:,:)
84 #include "oops/util/linkedList_c.f" 90 type(
obs_data),
intent(inout) :: self
91 character(len=*),
intent(in) :: fin, fout
97 if (self%filein/=
"")
call obs_read(self)
98 call fckit_log%debug(
"TRACE: qg_obs_data:obs_setup: done")
106 type(
obs_data),
intent(inout) :: self
111 if (self%fileout/=
"")
call obs_write(self)
113 do while (
associated(self%grphead))
115 self%grphead=>jgrp%next
117 call datetime_delete(jgrp%times(jo))
119 deallocate(jgrp%times)
120 do while (
associated(jgrp%colhead))
122 jgrp%colhead=>jcol%next
123 deallocate(jcol%values)
133 subroutine obs_get(self, req, col, ovec)
136 character(len=*),
intent(in) ::
req, col
137 type(
obs_vect),
intent(inout) :: ovec
142 character(len=250) :: record
144 write(record,*)
"obs_get req=",
req 145 call fckit_log%info(record)
146 write(record,*)
"obs_get col=",col
147 call fckit_log%info(record)
151 if (.not.
associated(jgrp))
then 153 do while (
associated(jgrp))
154 write(record,*)
"Group ",jgrp%grpname,
" exists." 155 call fckit_log%info(record)
158 write(record,*)
"Cannot find ",
req,
" ." 159 call fckit_log%error(record)
160 call abor1_ftn(
"qg_obs_get: obs group not found")
165 if (.not.
associated(jcol))
call abor1_ftn(
"qg_obs_get: obs column not found")
168 if (
allocated(ovec%values))
deallocate(ovec%values)
171 allocate(ovec%values(ovec%ncol,ovec%nobs))
175 ovec%values(jc,jo)=jcol%values(jc,jo)
179 write(record,*)
"obs_get nobs, ncol=",jgrp%nobs,jcol%ncol
180 call fckit_log%debug(
"TRACE: " // record)
186 subroutine obs_put(self, req, col, ovec)
188 type(
obs_data),
intent(inout) :: self
189 character(len=*),
intent(in) ::
req, col
195 character(len=250) :: record
199 if (.not.
associated(jgrp))
then 201 do while (
associated(jgrp))
202 write(record,*)
"Group ",jgrp%grpname,
" exists." 203 call fckit_log%info(record)
206 write(record,*)
"Cannot find ",
req,
" ." 207 call fckit_log%error(record)
208 call abor1_ftn(
"qg_obs_put: obs group not found")
213 if (.not.
associated(jcol))
then 214 if (.not.
associated(jgrp%colhead))
call abor1_ftn(
"qg_obs_put: no locations")
216 do while (
associated(jcol%next))
224 allocate(jcol%values(jcol%ncol,jgrp%nobs))
228 if (ovec%nobs/=jgrp%nobs)
call abor1_ftn(
"qg_obs_put: error obs number")
229 if (ovec%ncol/=jcol%ncol)
call abor1_ftn(
"qg_obs_put: error col number")
232 jcol%values(jc,jo)=ovec%values(jc,jo)
240 subroutine obs_locations(c_key_self, lreq, c_req, c_t1, c_t2, c_key_locs) bind(c,name='qg_obsdb_locations_f90')
242 integer(c_int),
intent(in) :: c_key_self
243 integer(c_int),
intent(in) :: lreq
244 character(kind=c_char,len=1),
intent(in) :: c_req(lreq+1)
245 type(c_ptr),
intent(in) :: c_t1, c_t2
246 integer(c_int),
intent(in) :: c_key_locs
248 type(obs_data),
pointer :: self
249 character(len=lreq) :: req
250 type(datetime) :: t1, t2
251 type(qg_locs),
pointer :: locs
252 type(obs_vect) :: ovec
253 character(len=8) :: col=
"Location" 255 integer,
allocatable :: mobs(:)
258 call c_f_string(c_req, req)
259 call c_f_datetime(c_t1, t1)
260 call c_f_datetime(c_t2, t2)
273 deallocate(ovec%values)
280 subroutine obs_generate(c_key_self, lreq, c_req, c_conf, c_bgn, c_step, ktimes, kobs) bind(c,name='qg_obsdb_generate_f90')
282 integer(c_int),
intent(in) :: c_key_self
283 integer(c_int),
intent(in) :: lreq
284 character(kind=c_char,len=1),
intent(in) :: c_req(lreq+1)
285 type(c_ptr),
intent(in) :: c_conf
286 type(c_ptr),
intent(in) :: c_bgn
287 type(c_ptr),
intent(in) :: c_step
288 integer(c_int),
intent(in) :: ktimes
289 integer(c_int),
intent(inout) :: kobs
290 type(obs_data),
pointer :: self
291 character(len=lreq) :: req
292 type(datetime) :: bgn
293 type(duration) :: step
294 real(c_double) :: err
295 integer :: nobs, ncol
298 type(datetime),
allocatable :: times(:)
299 type(obs_vect) :: obsloc, obserr
302 call c_f_string(c_req, req)
303 call c_f_datetime(c_bgn, bgn)
304 call c_f_duration(c_step, step)
306 nlocs = config_get_int(c_conf,
"obs_density");
309 allocate(times(kobs))
312 call obs_create(self, trim(req), times, obsloc)
315 deallocate(obsloc%values)
318 err = config_get_real(c_conf,
"obs_error");
319 ncol = config_get_int(c_conf,
"nval");
321 obserr%values(:,:)=err
322 call obs_put(self, trim(req),
"ObsErr", obserr)
323 deallocate(obserr%values)
329 subroutine obs_nobs(c_key_self, lreq, c_req, kobs) bind(c,name='qg_obsdb_nobs_f90')
331 integer(c_int),
intent(in) :: c_key_self
332 integer(c_int),
intent(in) :: lreq
333 character(kind=c_char,len=1),
intent(in) :: c_req(lreq+1)
334 integer(c_int),
intent(inout) :: kobs
336 type(obs_data),
pointer :: self
337 character(len=lreq) :: req
341 call c_f_string(c_req, req)
352 type(obs_data),
intent(in) :: self
353 character(len=*),
intent(in) :: req, col
354 type(datetime),
intent(in) :: t1, t2
355 type(obs_vect),
intent(inout) :: ovec
357 type(group_data),
pointer :: jgrp
358 type(column_data),
pointer :: jcol
359 integer :: jo, jc, iobs
363 if (.not.
associated(jgrp))
call abor1_ftn(
"obs_time_get: obs group not found")
367 if (.not.
associated(jcol))
call abor1_ftn(
"obs_time_get: obs column not found")
372 if (t1<jgrp%times(jo) .and. jgrp%times(jo)<=t2) iobs=iobs+1
376 if (ovec%nobs/=iobs .or. ovec%ncol/=jcol%ncol)
then 377 if (
allocated(ovec%values))
deallocate(ovec%values)
380 allocate(ovec%values(ovec%ncol,ovec%nobs))
385 if (t1<jgrp%times(jo) .and. jgrp%times(jo)<=t2)
then 388 ovec%values(jc,iobs)=jcol%values(jc,jo)
399 type(obs_data),
intent(in) :: self
400 character(len=*),
intent(in) :: req
401 type(datetime),
intent(in) :: t1, t2
402 integer,
intent(inout) :: kobs
404 type(group_data),
pointer :: jgrp
409 if (.not.
associated(jgrp))
call abor1_ftn(
"obs_count: obs group not found")
414 if (t1<jgrp%times(jo) .and. jgrp%times(jo)<=t2) kobs=kobs+1
423 type(obs_data),
intent(in) :: self
424 character(len=*),
intent(in) :: req
425 type(datetime),
intent(in) :: t1, t2
426 integer,
intent(inout) :: kobs(:)
428 type(group_data),
pointer :: jgrp
433 if (.not.
associated(jgrp))
call abor1_ftn(
"obs_count: obs group not found")
438 if (t1<jgrp%times(jo) .and. jgrp%times(jo)<=t2)
then 450 type(obs_data),
intent(in) :: self
451 character(len=*),
intent(in) :: req
452 integer,
intent(inout) :: kobs
453 type(group_data),
pointer :: jgrp
457 if (
associated(jgrp))
then 469 type(obs_data),
intent(inout) :: self
470 character(len=*),
intent(in) :: req
471 type(datetime),
intent(in) :: times(:)
472 type(obs_vect),
intent(in) :: locs
473 type(group_data),
pointer :: igrp
477 if (
associated(igrp))
call abor1_ftn(
"obs_create: obs group already exists")
479 if (
associated(self%grphead))
then 481 do while (
associated(igrp%next))
487 allocate(self%grphead)
492 igrp%nobs=
size(times)
493 allocate(igrp%times(igrp%nobs))
494 igrp%times(:)=times(:)
496 allocate(igrp%colhead)
497 igrp%colhead%colname=
"Location" 499 allocate(igrp%colhead%values(3,igrp%nobs))
500 if (locs%ncol/=3)
call abor1_ftn(
"obs_create: error locations not 3D")
501 if (locs%nobs/=igrp%nobs)
call abor1_ftn(
"obs_create: error locations number")
504 igrp%colhead%values(jc,jo)=locs%values(jc,jo)
508 self%ngrp=self%ngrp+1
518 type(obs_data),
intent(inout) :: self
519 integer :: iin, icol, jo, jc, jg, ncol
520 type(group_data),
pointer :: jgrp
521 type(column_data),
pointer :: jcol
522 real(kind=kind_real),
allocatable :: ztmp(:)
523 character(len=20) :: stime
524 character(len=max_string+50) :: record
527 write(record,*)
'obs_read: opening ',trim(self%filein)
528 call fckit_log%info(record)
529 open(unit=iin, file=trim(self%filein), form=
'formatted', action=
'read')
534 allocate(self%grphead)
540 read(iin,*)jgrp%grpname
542 write(record,*)
'obs_read: reading ',jgrp%nobs,
' ',jgrp%grpname,
' observations.' 543 call fckit_log%info(record)
544 allocate(jgrp%times(jgrp%nobs))
550 allocate(jgrp%colhead)
556 read(iin,*)jcol%colname, jcol%ncol
558 allocate(jcol%values(jcol%ncol,jgrp%nobs))
563 read(iin,*)stime,ztmp(:)
564 call datetime_create(stime,jgrp%times(jo))
567 do while (
associated(jcol))
570 jcol%values(jc,jo)=ztmp(icol)
586 type(obs_data),
intent(in) :: self
587 integer :: iout, icol, jc, jo
588 type(group_data),
pointer :: jgrp
589 type(column_data),
pointer :: jcol
590 real(kind=kind_real),
allocatable :: ztmp(:)
591 character(len=20) :: stime
594 open(unit=iout, file=trim(self%fileout), form=
'formatted', action=
'write')
596 write(iout,*)self%ngrp
598 do while (
associated(jgrp))
599 write(iout,*)jgrp%grpname
600 write(iout,*)jgrp%nobs
604 do while (
associated(jcol))
612 do while (
associated(jcol))
613 write(iout,*)jcol%colname, jcol%ncol
622 do while (
associated(jcol))
625 ztmp(icol)=jcol%values(jc,jo)
629 call datetime_to_string(jgrp%times(jo),stime)
630 write(iout,*)stime,ztmp(:)
644 type(obs_data),
intent(in) :: self
645 character(len=*),
intent(in) :: req
646 type(group_data),
pointer,
intent(inout) :: find
649 do while (
associated(find))
650 if (find%grpname==req)
exit 659 type(group_data),
intent(in) :: grp
660 character(len=*),
intent(in) :: col
661 type(column_data),
pointer,
intent(inout) :: find
664 do while (
associated(find))
665 if (find%colname==col)
exit subroutine, public obs_put(self, req, col, ovec)
subroutine, public obs_setup(fin, fout, self)
Linked list implementation.
subroutine obs_time_get(self, req, col, t1, t2, ovec)
subroutine obs_read(self)
subroutine obs_create(self, req, times, locs)
integer, parameter max_string
type(registry_t), public qg_locs_registry
Linked list interface - defines registry_t type.
subroutine findgroup(self, req, find)
type(registry_t), public obs_data_registry
Linked list interface - defines registry_t type.
subroutine obs_generate(c_key_self, lreq, c_req, c_conf, c_bgn, c_step, ktimes, kobs)
subroutine generate_locations(c_conf, nlocs, ntimes, bgn, step, times, obsloc)
subroutine obs_nobs(c_key_self, lreq, c_req, kobs)
subroutine, public obs_get(self, req, col, ovec)
subroutine obs_write(self)
subroutine obs_count_indx(self, req, t1, t2, kobs)
Fortran module handling observation locations.
A type to represent a linked list of observation columns.
Handle observations for the QG model.
real(kind=kind_real), parameter req
Earth radius at equator (m)
subroutine, public obs_delete(self)
Fortran module to handle variables for the QG model.
subroutine, public obsvec_setup(self, nc, no)
subroutine findcolumn(grp, col, find)
Fortran module handling interpolated (to obs locations) model variables.
subroutine obs_locations(c_key_self, lreq, c_req, c_t1, c_t2, c_key_locs)
subroutine, public qg_loc_setup(self, lvec, kobs)
subroutine obs_count_all(self, req, kobs)
A type to represent a linked list of observation group data.
Fortran module for streamfunction observations for the QG model.
A type to represent observation data.
Fortran module handling observation vectors.
subroutine obs_count_time(self, req, t1, t2, kobs)
Fortran derived type to represent an observation vector.