libsim Versione 7.2.6

◆ vol7d_recompute_stat_proc_agg()

subroutine vol7d_recompute_stat_proc_agg ( type(vol7d), intent(inout) this,
type(vol7d), intent(out) that,
integer, intent(in) stat_proc,
type(timedelta), intent(in) step,
type(datetime), intent(in), optional start,
logical, intent(in), optional full_steps,
real, intent(in), optional frac_valid,
type(vol7d), intent(inout), optional other,
integer, intent(in), optional stat_proc_input )

Specialized method for statistically processing a set of data already processed with the same statistical processing, on a different time interval.

This method performs statistical processing by aggregation of shorter intervals. Only floating point single or double precision data are processed.

The output that vol7d object contains elements from the original volume this satisfying the conditions

  • real single or double precision variables
  • timerange (vol7d_timerange_class::vol7d_timerange::timerange) of type stat_proc (or stat_proc_input if provided)
  • any p1 (analysis/observation or forecast)
  • p2 > 0 (processing interval non null, non instantaneous data) and equal to a multiplier of step

Output data will have timerange of type stat_proc and p2 = step. The supported statistical processing methods (parameter stat_proc) are:

  • 0 average
  • 1 accumulation
  • 2 maximum
  • 3 minimum
  • 4 difference
  • 6 standard deviation
  • 200 vectorial mean

The start of processing period can be computed automatically from the input intervals as the first possible interval modulo step, or, for a better control, it can be specified explicitly by the optional argument start. Notice that start indicates the beginning of the processing interval, so in the final volume, the first datum may have time equal to start + step, e.g. in the case when time is the verification time, which is typical for observed datasets.

The purpose of the optional argument stat_proc_input is to allow processing with a certain statistical processing operator a dataset already processed with a different operator, by specifying the latter as stat_proc_input; this is useful, for example, if one wants to compute the monthly average of daily maximum temperatures; however this has to be used with care since the resulting data volume will not carry all the information about the processing which has been done, in the previous case, for example, the temperatures will simply look like monthly average temperatures.

Parametri
[in,out]thisvolume providing data to be recomputed, it is not modified by the method, apart from performing a vol7d_alloc_vol on it
[out]thatoutput volume which will contain the recomputed data
[in]stat_proctype of statistical processing to be recomputed (from grib2 table), only data having timerange of this type will be recomputed and will appear in the output volume
[in]steplength of the step over which the statistical processing is performed
[in]startstart of statistical processing interval
[in]full_stepsif .TRUE. and start is not provided, apply processing only on intervals starting at a forecast time or a reference time modulo step
[in]frac_validminimum fraction of valid data required for considering acceptable a recomputed value, default=1.
[in,out]otheroptional volume that, on exit, is going to contain the data that did not contribute to the statistical processing
[in]stat_proc_inputto be used with care, type of statistical processing of data that has to be processed (from grib2 table), only data having timerange of this type will be recomputed, the actual statistical processing performed and which will appear in the output volume, is however determined by stat_proc argument

Definizione alla linea 434 del file vol7d_class_compute.F90.

436DEALLOCATE(ttr_mask)
437
438CALL makeother()
439
440CONTAINS
441
442SUBROUTINE makeother()
443IF (PRESENT(other)) THEN ! create volume with the remaining data for further processing
444 CALL vol7d_copy(this, other, miss=.false., sort=.false., unique=.false., &
445 ltimerange=(this%timerange(:)%timerange /= tri .OR. this%timerange(:)%p2 == imiss &
446 .OR. this%timerange(:)%p2 == 0)) ! or MOD(steps, this%timerange(:)%p2) == 0
447ENDIF
448END SUBROUTINE makeother
449
450END SUBROUTINE vol7d_recompute_stat_proc_agg
451
452
453!> Method for statistically processing a set of instantaneous data.
454!! This method performs statistical processing by aggregation of
455!! instantaneous data. Only floating point single or double precision
456!! data are processed.
457!!
458!! The output \a that vol7d object contains elements from the original volume
459!! \a this satisfying the conditions
460!! - real single or double precision variables
461!! - timerange (vol7d_timerange_class::vol7d_timerange::timerange)
462!! of type 254 (instantaeous)
463!! - any p1 (analysis/observation or forecast)
464!! - p2 = 0 (processing interval null, instantaneous data)
465!!
466!! Output data will have timerange of type \a stat_proc, and p2 = \a
467!! step. The supported statistical processing methods (parameter \a
468!! stat_proc) are:
469!!
470!! - 0 average
471!! - 2 maximum
472!! - 3 minimum
473!! - 4 difference
474!! - 6 standard deviation
475!! - 201 mode (only for wind direction sectors)
476!!
477!! In the case of average, it is possible to weigh the data
478!! proportionally to the length of the time interval for which every
479!! single value is valid, i.e. halfway between the time level of the
480!! value itself and the time of its nearest valid neighbours (argument
481!! \a weighted). A maximum distance in time for input valid data can
482!! be assigned with the optional argument \a max_step, in order to
483!! filter datasets with too long "holes".
484SUBROUTINE vol7d_compute_stat_proc_agg(this, that, stat_proc, &
485 step, start, full_steps, max_step, weighted, other)
486TYPE(vol7d),INTENT(inout) :: this !< volume providing data to be computed, it is not modified by the method, apart from performing a \a vol7d_alloc_vol on it
487TYPE(vol7d),INTENT(out) :: that !< output volume which will contain the computed data
488INTEGER,INTENT(in) :: stat_proc !< type of statistical processing to be computed (from grib2 table)
489TYPE(timedelta),INTENT(in) :: step !< length of the step over which the statistical processing is performed
490TYPE(datetime),INTENT(in),OPTIONAL :: start !< start of statistical processing interval
491LOGICAL,INTENT(in),OPTIONAL :: full_steps !< if \a .TRUE. and \a start is not provided, apply processing only on intervals starting at a forecast time or a reference time modulo \a step
492TYPE(timedelta),INTENT(in),OPTIONAL :: max_step !< maximum allowed distance in time between two contiguougs valid data within an interval, for the interval to be eligible for statistical processing
493LOGICAL,INTENT(in),OPTIONAL :: weighted !< if provided and \c .TRUE., the statistical process is computed, if possible, by weighting every value with a weight proportional to its validity interval
494TYPE(vol7d),INTENT(inout),OPTIONAL :: other !< optional volume that, on exit, is going to contain the data that did not contribute to the accumulation computation
495!INTEGER,INTENT(in),OPTIONAL :: stat_proc_input !< to be used with care, type of statistical processing of data that has to be processed (from grib2 table), only data having timerange of this type will be recomputed, the actual statistical processing performed and which will appear in the output volume, is however determined by \a stat_proc argument
496
497TYPE(vol7d) :: v7dtmp
498INTEGER :: tri
499INTEGER :: i, j, n, ninp, ndtr, i1, i3, i5, i6, vartype, maxsize
500TYPE(timedelta) :: lmax_step, act_max_step
501TYPE(datetime) :: pstart, pend, reftime
502TYPE(arrayof_ttr_mapper),POINTER :: map_ttr(:,:)
503REAL,ALLOCATABLE :: tmpvolr(:)
504DOUBLE PRECISION,ALLOCATABLE :: tmpvold(:), weights(:)
505LOGICAL,ALLOCATABLE :: lin_mask(:)
506LOGICAL :: lweighted
507CHARACTER(len=8) :: env_var
508
509IF (PRESENT(max_step)) THEN
510 lmax_step = max_step
511ELSE
512 lmax_step = timedelta_max
513ENDIF
514lweighted = optio_log(weighted)
515tri = 254
516! enable bad behavior for climat database
517env_var = ''
518CALL getenv('LIBSIM_CLIMAT_BEHAVIOR', env_var)
519lweighted = lweighted .AND. len_trim(env_var) == 0
520! only average can be weighted
521lweighted = lweighted .AND. stat_proc == 0
522
523! be safe
524CALL vol7d_alloc_vol(this)
525! initial check
526
527! cleanup the original volume
528CALL vol7d_smart_sort(this, lsort_time=.true.) ! time-ordered volume needed
529CALL vol7d_reform(this, miss=.false., sort=.false., unique=.true.)
530! copy everything except time and timerange
531CALL vol7d_copy(this, v7dtmp, ltime=(/.false./), ltimerange=(/.false./))
532
533! create new volume
534CALL init(that, time_definition=this%time_definition)
535! compute the output time and timerange and all the required mappings
536CALL recompute_stat_proc_agg_common(this%time, this%timerange, stat_proc, tri, &
537 step, this%time_definition, that%time, that%timerange, map_ttr, start=start, &
538 full_steps=full_steps)
539! merge with information from original volume
540CALL vol7d_merge(that, v7dtmp)
541
542maxsize = maxval(map_ttr(:,:)%arraysize)
543ALLOCATE(tmpvolr(maxsize), tmpvold(maxsize), lin_mask(maxsize), weights(maxsize))
544do_otimerange: DO j = 1, SIZE(that%timerange)
545 do_otime: DO i = 1, SIZE(that%time)
546 ninp = map_ttr(i,j)%arraysize
547 IF (ninp <= 0) cycle do_otime
548! required for some computations
549 CALL time_timerange_get_period(that%time(i), that%timerange(j), &
550 that%time_definition, pstart, pend, reftime)
551
552 IF (ASSOCIATED(this%voldatir)) THEN
553 DO i1 = 1, SIZE(this%ana)
554 DO i3 = 1, SIZE(this%level)
555 DO i6 = 1, SIZE(this%network)
556 DO i5 = 1, SIZE(this%dativar%r)
557! stat_proc difference treated separately here
558 IF (stat_proc == 4) THEN
559 IF (ninp >= 2) THEN
560 IF (map_ttr(i,j)%array(1)%extra_info == 1 .AND. &
561 map_ttr(i,j)%array(ninp)%extra_info == 2) THEN
562 IF (c_e(this%voldatir(i1,map_ttr(i,j)%array(1)%it,i3, &
563 map_ttr(i,j)%array(1)%itr,i5,i6)) .AND. &
564 c_e(this%voldatir(i1,map_ttr(i,j)%array(ninp)%it,i3, &
565 map_ttr(i,j)%array(ninp)%itr,i5,i6))) THEN
566 that%voldatir(i1,i,i3,j,i5,i6) = &
567 this%voldatir(i1,map_ttr(i,j)%array(ninp)%it,i3, &
568 map_ttr(i,j)%array(ninp)%itr,i5,i6) - &
569 this%voldatir(i1,map_ttr(i,j)%array(1)%it,i3, &
570 map_ttr(i,j)%array(1)%itr,i5,i6)
571 ENDIF
572 ENDIF
573 ENDIF
574 cycle
575 ENDIF
576! other stat_proc
577 vartype = vol7d_vartype(this%dativar%r(i5))
578 lin_mask = .false.
579 ndtr = 0
580 DO n = 1, ninp
581 IF (c_e(this%voldatir(i1,map_ttr(i,j)%array(n)%it,i3, &
582 map_ttr(i,j)%array(n)%itr,i5,i6))) THEN
583 ndtr = ndtr + 1
584 tmpvolr(ndtr) = this%voldatir(i1,map_ttr(i,j)%array(n)%it,i3, &
585 map_ttr(i,j)%array(n)%itr,i5,i6)
586 lin_mask(n) = .true.
587 ENDIF
588 ENDDO
589 IF (ndtr == 0) cycle
590 IF (lweighted) THEN
591 CALL compute_stat_proc_agg_sw(map_ttr(i,j)%array(1:ninp)%time, &
592 pstart, pend, lin_mask(1:ninp), act_max_step, weights)
593 ELSE
594 CALL compute_stat_proc_agg_sw(map_ttr(i,j)%array(1:ninp)%time, &
595 pstart, pend, lin_mask(1:ninp), act_max_step)
596 ENDIF
597 IF (act_max_step > lmax_step) cycle
598
599 SELECT CASE(stat_proc)
600 CASE (0) ! average
601 IF (lweighted) THEN
602 that%voldatir(i1,i,i3,j,i5,i6) = &
603 sum(real(weights(1:ndtr))*tmpvolr(1:ndtr))
604 ELSE
605 that%voldatir(i1,i,i3,j,i5,i6) = &
606 sum(tmpvolr(1:ndtr))/ndtr
607 ENDIF
608 CASE (2) ! maximum
609 that%voldatir(i1,i,i3,j,i5,i6) = &
610 maxval(tmpvolr(1:ndtr))
611 CASE (3) ! minimum
612 that%voldatir(i1,i,i3,j,i5,i6) = &
613 minval(tmpvolr(1:ndtr))
614 CASE (6) ! stddev
615 that%voldatir(i1,i,i3,j,i5,i6) = &
616 stat_stddev(tmpvolr(1:ndtr))
617 CASE (201) ! mode
618! mode only for angles at the moment, with predefined histogram
619 IF (vartype == var_dir360) THEN
620! remove undefined wind direction (=0), improve check?
621! and reduce to interval [22.5,382.5[
622 WHERE (tmpvolr(1:ndtr) == 0.0)
623 tmpvolr(1:ndtr) = rmiss
624 ELSE WHERE (tmpvolr(1:ndtr) < 22.5 .AND. tmpvolr(1:ndtr) > 0.0)
625 tmpvolr(1:ndtr) = tmpvolr(1:ndtr) + 360.
626 END WHERE
627 that%voldatir(i1,i,i3,j,i5,i6) = &
628 stat_mode_histogram(tmpvolr(1:ndtr), &
629 8, 22.5, 382.5)
630 ENDIF
631 END SELECT
632 ENDDO
633 ENDDO
634 ENDDO
635 ENDDO
636 ENDIF
637

Generated with Doxygen.