libsim Versione 7.2.6
|
◆ volgrid6d_recompute_stat_proc_diff()
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 difference of different intervals. Data with both analysis/observation or forecast timerange are processed. The output that volgrid6d object contains elements from the original volume this satisfying the conditions
Output data will have timerange of type stat_proc and p2 = step. The supported statistical processing methods (parameter stat_proc) are:
Input volume may have any value of thistime_definition, and that value will be conserved in the output volume.
Definizione alla linea 768 del file volgrid6d_class_compute.F90. 769LOGICAL :: lclone
770
771NULLIFY(voldatiin, voldatiout)
772
773! be safe
774CALL volgrid6d_alloc_vol(this)
775! when volume is not decoded it is better to clone anyway to avoid
776! overwriting fields
777lclone = optio_log(clone) .OR. .NOT.ASSOCIATED(this%voldati)
778
779IF (.NOT.((stat_proc_input == 0 .AND. stat_proc == 1) .OR. &
780 (stat_proc_input == 1 .AND. stat_proc == 0))) THEN
781
782 CALL l4f_category_log(this%category, l4f_warn, &
783 'compute_stat_proc_metamorph, can only be applied to average->accumulated timerange and viceversa')
784! return an empty volume, without signaling error
785 CALL init(that)
786 CALL volgrid6d_alloc_vol(that)
787 RETURN
788ENDIF
789
790! initialise the output volume
791CALL init(that, griddim=this%griddim, time_definition=this%time_definition)
792CALL volgrid6d_alloc(that, dim=this%griddim%dim, ntime=SIZE(this%time), &
793 nlevel=SIZE(this%level), nvar=SIZE(this%var), ini=.false.)
794that%time = this%time
795that%level = this%level
796that%var = this%var
797
798CALL compute_stat_proc_metamorph_common(stat_proc_input, this%timerange, stat_proc, &
799 that%timerange, map_tr)
800
801! complete the definition of the output volume
802CALL volgrid6d_alloc_vol(that, decode=ASSOCIATED(this%voldati))
803
804IF (stat_proc == 0) THEN ! average -> integral
805 int_ratio = 1./real(that%timerange(:)%p2)
806ELSE ! cumulation
807 int_ratio = real(that%timerange(:)%p2)
808ENDIF
809
810DO i6 = 1, SIZE(this%var)
811 DO j = 1, SIZE(map_tr)
812 DO i4 = 1, SIZE(that%time)
813 DO i3 = 1, SIZE(this%level)
814
815 IF (lclone) THEN
816 CALL copy(this%gaid(i3,i4,map_tr(j),i6), that%gaid(i3,i4,j,i6))
817 ELSE
818 that%gaid(i3,i4,map_tr(j),i6) = this%gaid(i3,i4,j,i6)
819 ENDIF
820 CALL volgrid_get_vol_2d(this, i3, i4, map_tr(j), i6, voldatiin)
821 CALL volgrid_get_vol_2d(that, i3, i4, j, i6, voldatiout)
822 WHERE (c_e(voldatiin))
823 voldatiout = voldatiin*int_ratio(j)
824 ELSEWHERE
825 voldatiout = rmiss
826 END WHERE
827 CALL volgrid_set_vol_2d(that, i3, i4, j, i6, voldatiout)
828 ENDDO
829 ENDDO
830 ENDDO
831ENDDO
832
833
834END SUBROUTINE volgrid6d_compute_stat_proc_metamorph
835
836!> Method for building a volume containing the vertical coordinate as
837!! a variable.
838!! This method produces a volgrid6d volume, derived from \a this,
839!! containing a single variable, horizontally constant, on the same
840!! input levels, which describes the vertical coordinate in the form
841!! of a physical variable. The grid, time and timerange metadata are
842!! the same as for the original volume. Only a single vertical level
843!! type, the one matching the \a level argument, is converted to a
844!! variable. The \a level argument can also indicate the layer between
845!! two surfaces of the same type, in that case the variable
846!! representing the vertical coordinate will be set to the value of
847!! the midpoint between the two layers. If something goes wrong,
848!! e.g. no level matches \a level argument or the level canot be
849!! converted to a physical value, an empty volume is returned.
850SUBROUTINE volgrid6d_compute_vert_coord_var(this, level, volgrid_lev)
851TYPE(volgrid6d),INTENT(in) :: this !< volume with the vertical levels
852TYPE(vol7d_level),INTENT(in) :: level !< vertical level to be converted to variable, only the type(s) of level are used not the value(s)
853TYPE(volgrid6d),INTENT(out) :: volgrid_lev !< output volume with the variable describing the vertical coordinate
854
855INTEGER :: nlev, i, ii, iii, iiii
856TYPE(grid_id) :: out_gaid
857LOGICAL,ALLOCATABLE :: levmask(:)
858TYPE(volgrid6d_var) :: lev_var
859
860CALL init(volgrid_lev) ! initialise to null
861IF (.NOT.ASSOCIATED(this%gaid)) THEN
862 CALL l4f_log(l4f_error, 'volgrid6d_compute_vert_coord_var: input volume not allocated')
863 RETURN
864ENDIF
865! if layer, both surfaces must be of the same type
866IF (c_e(level%level2) .AND. level%level1 /= level%level2) THEN
867 CALL l4f_log(l4f_error, 'volgrid6d_compute_vert_coord_var: requested (mixed) layer type not valid')
868 RETURN
869ENDIF
870
871! look for valid levels to be converted to vars
872ALLOCATE(levmask(SIZE(this%level)))
873levmask = this%level%level1 == level%level1 .AND. &
874 this%level%level2 == level%level2 .AND. c_e(this%level%l1)
875IF (c_e(level%level2)) levmask = levmask .AND. c_e(this%level%l2)
876nlev = count(levmask)
877IF (nlev == 0) THEN
878 CALL l4f_log(l4f_error, 'volgrid6d_compute_vert_coord_var: requested level type not available')
879 RETURN
880ENDIF
881
882out_gaid = grid_id_new()
883gaidloop: DO i=1 ,SIZE(this%gaid,1)
884 DO ii=1 ,SIZE(this%gaid,2)
885 DO iii=1 ,SIZE(this%gaid,3)
886 DO iiii=1 ,SIZE(this%gaid,4)
887 IF (c_e(this%gaid(i,ii,iii,iiii))) THEN ! conserve first valid gaid
888 CALL copy(this%gaid(i,ii,iii,iiii), out_gaid)
889 EXIT gaidloop
890 ENDIF
891 ENDDO
892 ENDDO
893 ENDDO
894ENDDO gaidloop
895
896! look for variable corresponding to level
897lev_var = convert(vol7d_var_new(btable=vol7d_level_to_var(level)), &
898 grid_id_template=out_gaid)
899IF (.NOT.c_e(lev_var)) THEN
900 CALL l4f_log(l4f_error, 'volgrid6d_compute_vert_coord_var: no variable corresponds to requested level type')
901 RETURN
902ENDIF
903
904! prepare output volume
905CALL init(volgrid_lev, griddim=this%griddim, &
906 time_definition=this%time_definition) !, categoryappend=categoryappend)
907CALL volgrid6d_alloc(volgrid_lev, ntime=SIZE(this%time), nlevel=nlev, &
908 ntimerange=SIZE(this%timerange), nvar=1)
909! fill metadata
910volgrid_lev%time = this%time
911volgrid_lev%level = pack(this%level, mask=levmask)
912volgrid_lev%timerange = this%timerange
913volgrid_lev%var(1) = lev_var
914
915CALL volgrid6d_alloc_vol(volgrid_lev, decode=.true.)
|