|
libsim Versione 8.0.0
|
◆ volgrid6d_compute_stat_proc_metamorph()
Specialized method for statistically processing a set of data by integration/differentiation. This method performs statistical processing by integrating (accumulating) in time values representing time-average rates or fluxes, (stat_proc_input=0 stat_proc=1) or by transforming a time-integrated (accumulated) value in a time-average rate or flux (stat_proc_input=1 stat_proc=0). Analysis/observation or forecast timeranges are processed. The only operation performed is respectively multiplying or dividing the values by the length of the time interval in seconds. The output that volgrid6d object contains elements from the original volume this satisfying the conditions
Output data will have timerange of type stat_proc (1 or 0) and p1 and p2 equal to the corresponding input values. 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 949 del file volgrid6d_class_compute.F90. 950! Copyright (C) 2010 ARPA-SIM <urpsim@smr.arpa.emr.it>
951! authors:
952! Davide Cesari <dcesari@arpa.emr.it>
953! Paolo Patruno <ppatruno@arpa.emr.it>
954
955! This program is free software; you can redistribute it and/or
956! modify it under the terms of the GNU General Public License as
957! published by the Free Software Foundation; either version 2 of
958! the License, or (at your option) any later version.
959
960! This program is distributed in the hope that it will be useful,
961! but WITHOUT ANY WARRANTY; without even the implied warranty of
962! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
963! GNU General Public License for more details.
964
965! You should have received a copy of the GNU General Public License
966! along with this program. If not, see <http://www.gnu.org/licenses/>.
967#include "config.h"
968!> Extension of volgrid6d_class with methods for performing simple
969!! statistical operations on entire volumes of data. This module
970!! includes methods for performing operations such as (re)averaging
971!! and (re)cumulation in time of entire volgrid6d_class::volgrid6d
972!! objects.
973!!
974!! \ingroup volgrid6d
982IMPLICIT NONE
983
984CONTAINS
985
986!> General-purpose method for computing a statistical processing on
987!! data in a volgrid6d object already processed with the same statistical
988!! processing, on a different time interval specified by \a step and
989!! \a start. This method tries to apply all the suitable specialized
990!! statistical processing methods according to the input and output
991!! statistical processing requested. The argument \a stat_proc_input
992!! determines which data will be processed, while the \a stat_proc
993!! argument determines the type of statistical process to be applied
994!! and which will be owned by output data.
995!!
996!! The possible combinations are:
997!!
998!! - \a stat_proc_input = 254
999!! - \a stat_proc = 0 average instantaneous observations
1000!! - \a stat_proc = 2 compute maximum of instantaneous observations
1001!! - \a stat_proc = 3 compute minimum of instantaneous observations
1002!! - \a stat_proc = 4 compute difference of instantaneous observations
1003!!
1004!! processing is computed on longer time intervals by aggregation,
1005!! see the description of volgrid6d_compute_stat_proc_agg()
1006!!
1007!! - \a stat_proc_input = *
1008!! - \a stat_proc = 254 consider statistically processed values as
1009!! instantaneous without any extra processing
1010!!
1011!! see the description of volgrid6d_decompute_stat_proc()
1012!!
1013!! - \a stat_proc_input = 0, 1, 2, 3, 4, 200
1014!! - \a stat_proc = \a stat_proc_input recompute input data on
1015!! different intervals
1016!!
1017!! the same statistical processing is applied to obtain data
1018!! processed on a different interval, either longer, by
1019!! aggregation, or shorter, by differences, see the description of
1020!! volgrid6d_recompute_stat_proc_agg() and
1021!! volgrid6d_recompute_stat_proc_diff() respectively; it is also
1022!! possible to provide \a stat_proc_input \a /= \a stat_proc, but
1023!! it has to be used with care.
1024!!
1025!! - \a stat_proc_input = 0
1026!! - \a stat_proc = 1
1027!!
1028!! a time-averaged rate or flux is transformed into a
1029!! time-integrated value (sometimes called accumulated) on the same
1030!! interval by multiplying the values by the length of the time
1031!! interval in seconds, keeping constant all the rest, including
1032!! the variable; the unit of the variable implicitly changes
1033!! accordingly, this is supported officially in grib2 standard, in
1034!! the other cases it is a forcing of the standards.
1035!!
1036!! - \a stat_proc_input = 1
1037!! - \a stat_proc = 0
1038!!
1039!! a time-integrated value (sometimes called accumulated) is
1040!! transformed into a time-averaged rate or flux on the same
1041!! interval by dividing the values by the length of the time
1042!! interval in seconds, see also the previous description of the
1043!! opposite computation.
1044!!
1045!! If a particular statistical processing cannot be performed on the
1046!! input data, the program continues with a warning and, if requested,
1047!! the input data is passed over to the volume specified by the \a
1048!! other argument, in order to allow continuation of processing. All
1049!! the other parameters are passed over to the specifical statistical
1050!! processing methods and are documented there.
1051SUBROUTINE volgrid6d_compute_stat_proc(this, that, stat_proc_input, stat_proc, &
1052 step, start, full_steps, frac_valid, max_step, weighted, clone)
1053TYPE(volgrid6d),INTENT(inout) :: this !< volume providing data to be recomputed, it is not modified by the method, apart from performing a \a volgrid6d_alloc_vol on it
1054TYPE(volgrid6d),INTENT(out) :: that !< output volume which will contain the recomputed data
1055INTEGER,INTENT(in) :: stat_proc_input !< type of statistical processing of data that has to be processed (from grib2 table), only data having timerange of this type will be processed, the actual statistical processing performed and which will appear in the output volume, is however determined by \a stat_proc argument
1056INTEGER,INTENT(in) :: stat_proc !< type of statistical processing to be recomputed (from grib2 table), data in output volume \a that will have a timerange of this type
1057TYPE(timedelta),INTENT(in) :: step !< length of the step over which the statistical processing is performed
1058TYPE(datetime),INTENT(in),OPTIONAL :: start !< start of statistical processing interval
1059LOGICAL,INTENT(in),OPTIONAL :: full_steps !< if \a .TRUE. apply processing only on intervals starting at a forecast time or a reference time modulo \a step
1060REAL,INTENT(in),OPTIONAL :: frac_valid !< minimum fraction of valid data required for considering acceptable a recomputed value, default=1.
1061TYPE(timedelta),INTENT(in),OPTIONAL :: max_step ! maximum allowed distance in time between two single valid data within a dataset, for the dataset to be eligible for statistical processing
1062LOGICAL,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
1063LOGICAL , INTENT(in),OPTIONAL :: clone !< if provided and \c .TRUE. , clone the gaid's from \a this to \a that
1064
1065INTEGER :: dtmax, dtstep
1066
1067
1068IF (stat_proc_input == 254) THEN
1069 CALL l4f_category_log(this%category, l4f_info, &
1070 'computing statistical processing by aggregation '//&
1072
1073 CALL volgrid6d_compute_stat_proc_agg(this, that, stat_proc, &
1074 step, start, full_steps, max_step, clone)
1075
1076ELSE IF (stat_proc == 254) THEN
1077 CALL l4f_category_log(this%category, l4f_error, &
1078 'statistical processing to instantaneous data not implemented for gridded fields')
1079 CALL raise_error()
1080
1081ELSE IF (stat_proc_input == stat_proc .OR. &
1082 (stat_proc == 0 .OR. stat_proc == 2 .OR. stat_proc == 3)) THEN
1083! avg, min and max can be computed from any input, with care
1084
1085 IF (count(this%timerange(:)%timerange == stat_proc_input) == 0) THEN
1086 CALL l4f_category_log(this%category, l4f_warn, &
1088! return an empty volume, without signaling error
1090 CALL volgrid6d_alloc_vol(that)
1091
1092 ELSE
1093! euristically determine whether aggregation or difference is more suitable
1094 dtmax = maxval(this%timerange(:)%p2, &
1095 mask=(this%timerange(:)%timerange == stat_proc))
1097
1098#ifdef DEBUG
1099 CALL l4f_category_log(this%category, l4f_debug, &
1101#endif
1102
1103 IF (dtstep <= dtmax) THEN
1104 CALL l4f_category_log(this%category, l4f_info, &
1105 'recomputing statistically processed data by difference '// &
1107 CALL volgrid6d_recompute_stat_proc_diff(this, that, stat_proc, step, &
1108 full_steps, start, clone)
1109 ELSE
1110 CALL l4f_category_log(this%category, l4f_info, &
1111 'recomputing statistically processed data by aggregation '// &
1113 CALL volgrid6d_recompute_stat_proc_agg(this, that, stat_proc, step, start, &
1114 full_steps, frac_valid, clone, stat_proc_input)
1115 ENDIF
1116 ENDIF
1117
1118ELSE ! IF (stat_proc_input /= stat_proc) THEN
1119 IF ((stat_proc_input == 0 .AND. stat_proc == 1) .OR. &
1120 (stat_proc_input == 1 .AND. stat_proc == 0)) THEN
1121 CALL l4f_category_log(this%category, l4f_info, &
1122 'computing statistically processed data by integration/differentiation '// &
1124 CALL volgrid6d_compute_stat_proc_metamorph(this, that, stat_proc_input, &
1125 stat_proc, clone)
1126 ELSE
1127 CALL l4f_category_log(this%category, l4f_error, &
1129 ' not implemented or does not make sense')
1130 CALL raise_error()
1131 ENDIF
1132
1133ENDIF
1134
1135END SUBROUTINE volgrid6d_compute_stat_proc
1136
1137
1138!> Specialized method for statistically processing a set of data
1139!! already processed with the same statistical processing, on a
1140!! different time interval. This method performs statistical
1141!! processing by aggregation of shorter intervals.
1142!!
1143!! The output \a that volgrid6d object contains elements from the original volume
1144!! \a this satisfying the conditions
1145!! - timerange (vol7d_timerange_class::vol7d_timerange::timerange)
1146!! of type \a stat_proc (or \a stat_proc_input if provided)
1147!! - any p1 (analysis/observation or forecast)
1148!! - p2 > 0 (processing interval non null, non instantaneous data)
1149!! and equal to a multiplier of \a step
1150!!
1151!! Output data will have timerange of type \a stat_proc and p2 = \a
1152!! step. The supported statistical processing methods (parameter \a
1153!! stat_proc) are:
1154!!
1155!! - 0 average
1156!! - 1 accumulation
1157!! - 2 maximum
1158!! - 3 minimum
1159!! - 4 difference
1160!! - 200 vectorial mean
1161!!
1162!! The start of processing period can be computed automatically from
1163!! the input intervals as the first possible interval modulo \a step,
1164!! or, for a better control, it can be specified explicitely by the
1165!! optional argument \a start. Be warned that, in the final volume,
1166!! the first reference time will actually be \a start \a + \a step,
1167!! since \a start indicates the beginning of first processing
1168!! interval, while reference time (for analysis/oservation) is the end
1169!! of the interval.
1170!!
1171!! The purpose of the optional argument \a stat_proc_input is to allow
1172!! processing with a certain statistical processing operator a dataset
1173!! already processed with a different operator, by specifying the
1174!! latter as stat_proc_input; this is useful, for example, if one
1175!! wants to compute the monthly average of daily maximum temperatures;
1176!! however this has to be used with care since the resulting data
1177!! volume will not carry all the information about the processing
1178!! which has been done, in the previous case, for example, the
1179!! temperatures will simply look like monthly average temperatures.
1180SUBROUTINE volgrid6d_recompute_stat_proc_agg(this, that, stat_proc, &
1181 step, start, full_steps, frac_valid, clone, stat_proc_input)
1182TYPE(volgrid6d),INTENT(inout) :: this !< volume providing data to be recomputed, it is not modified by the method, apart from performing a \a volgrid6d_alloc_vol on it
1183TYPE(volgrid6d),INTENT(out) :: that !< output volume which will contain the recomputed data
1184INTEGER,INTENT(in) :: stat_proc !< type 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
1185TYPE(timedelta),INTENT(in) :: step !< length of the step over which the statistical processing is performed
1186TYPE(datetime),INTENT(in),OPTIONAL :: start !< start of statistical processing interval
1187LOGICAL,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
1188REAL,INTENT(in),OPTIONAL :: frac_valid !< minimum fraction of valid data required for considering acceptable a recomputed value, default=1.
1189LOGICAL, INTENT(in),OPTIONAL :: clone !< if provided and \c .TRUE. , clone the gaid's from \a this to \a that
1190INTEGER,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
1191
1192INTEGER :: tri
1193INTEGER i, j, n, n1, ndtr, i3, i6
1194TYPE(arrayof_ttr_mapper),POINTER :: map_ttr(:,:)
1195INTEGER,POINTER :: dtratio(:)
1196REAL :: lfrac_valid
1197LOGICAL :: lclone
1198REAL,POINTER :: voldatiin(:,:), voldatiout(:,:)
1199
1200
1201NULLIFY(voldatiin, voldatiout)
1202IF (PRESENT(stat_proc_input)) THEN
1203 tri = stat_proc_input
1204ELSE
1205 tri = stat_proc
1206ENDIF
1207IF (PRESENT(frac_valid)) THEN
1208 lfrac_valid = frac_valid
1209ELSE
1210 lfrac_valid = 1.0
1211ENDIF
1212
1214! be safe
1215CALL volgrid6d_alloc_vol(this)
1216
1217! when volume is not decoded it is better to clone anyway to avoid
1218! overwriting fields
1219lclone = optio_log(clone) .OR. .NOT.ASSOCIATED(this%voldati)
1220! initialise the output volume
1222CALL volgrid6d_alloc(that, dim=this%griddim%dim, ntimerange=1, &
1223 nlevel=SIZE(this%level), nvar=SIZE(this%var), ini=.false.)
1224that%level = this%level
1225that%var = this%var
1226
1227CALL recompute_stat_proc_agg_common(this%time, this%timerange, stat_proc, tri, &
1228 step, this%time_definition, that%time, that%timerange, map_ttr, &
1229 dtratio=dtratio, start=start, full_steps=full_steps)
1230
1231CALL volgrid6d_alloc_vol(that, decode=ASSOCIATED(this%voldati))
1232
1233do_otimerange: DO j = 1, SIZE(that%timerange)
1234 do_otime: DO i = 1, SIZE(that%time)
1235
1236 DO n1 = 1, SIZE(dtratio)
1237 IF (dtratio(n1) <= 0) cycle ! safety check
1238
1239 DO i6 = 1, SIZE(this%var)
1240 DO i3 = 1, SIZE(this%level)
1241 CALL volgrid_get_vol_2d(that, i3, i, j, i6, voldatiout)
1242 ndtr = 0
1243 DO n = 1, map_ttr(i,j)%arraysize
1244 IF (map_ttr(i,j)%array(n)%extra_info == dtratio(n1)) THEN
1245 ndtr = ndtr + 1
1246 CALL volgrid_get_vol_2d(this, i3, map_ttr(i,j)%array(n)%it, &
1247 map_ttr(i,j)%array(n)%itr, i6, voldatiin)
1248
1249 IF (ndtr == 1) THEN
1250 voldatiout = voldatiin
1251 IF (lclone) THEN
1253 map_ttr(i,j)%array(n)%itr,i6), that%gaid(i3,i,j,i6))
1254 ELSE
1255 that%gaid(i3,i,j,i6) = this%gaid(i3, map_ttr(i,j)%array(n)%it, &
1256 map_ttr(i,j)%array(n)%itr,i6)
1257 ENDIF
1258
1259 ELSE ! second or more time
1260 SELECT CASE(stat_proc)
1261 CASE (0, 200, 1, 4) ! average, vectorial mean, accumulation, difference
1263 voldatiout(:,:) = voldatiout(:,:) + voldatiin(:,:)
1264 ELSEWHERE
1265 voldatiout(:,:) = rmiss
1266 END WHERE
1267 CASE(2) ! maximum
1269 voldatiout(:,:) = max(voldatiout(:,:), voldatiin(:,:))
1270 ELSEWHERE
1271 voldatiout(:,:) = rmiss
1272 END WHERE
1273 CASE(3) ! minimum
1275 voldatiout(:,:) = min(voldatiout(:,:), voldatiin(:,:))
1276 ELSEWHERE
1277 voldatiout(:,:) = rmiss
1278 END WHERE
1279 END SELECT
1280
1281 ENDIF ! first time
1282 ENDIF ! dtratio(n1)
1283 ENDDO ! ttr
1284
1285#ifdef DEBUG
1286 CALL l4f_log(l4f_debug, &
1287 'compute_stat_proc_agg, ndtr/dtratio/frac_valid: '// &
1289#endif
1290 IF (ndtr > 0) THEN ! why this condition was not here before?
1291 IF (real(ndtr)/real(dtratio(n1)) >= lfrac_valid) THEN ! success
1292 IF (stat_proc == 0) THEN ! average
1294 voldatiout(:,:) = voldatiout(:,:)/ndtr
1295 END WHERE
1296 ENDIF
1297 CALL volgrid_set_vol_2d(that, i3, i, j, i6, voldatiout)
1298#ifdef DEBUG
1299 CALL l4f_log(l4f_debug, &
1300 'compute_stat_proc_agg, coding lev/t/tr/var: '// &
1302#endif
1303 ELSE
1304! must nullify the output gaid here, otherwise an incomplete field will be output
1305 IF (lclone) THEN
1307 ELSE
1309 ENDIF
1310#ifdef DEBUG
1311 CALL l4f_log(l4f_debug, &
1312 'compute_stat_proc_agg, skipping lev/t/tr/var: '// &
1314#endif
1315 ENDIF
1316 ENDIF ! ndtr > 0
1317
1318 ENDDO ! level
1319 ENDDO ! var
1320 ENDDO ! dtratio
1322 ENDDO do_otime
1323ENDDO do_otimerange
1324
1325DEALLOCATE(dtratio, map_ttr)
1326
1327END SUBROUTINE volgrid6d_recompute_stat_proc_agg
1328
1329
1330!> Method for statistically processing a set of instantaneous data.
1331!! This method performs statistical processing by aggregation of
1332!! instantaneous data.
1333!!
1334!! The output \a that volgrid6d object contains elements from the original volume
1335!! \a this satisfying the conditions
1336!! - timerange (vol7d_timerange_class::vol7d_timerange::timerange)
1337!! of type 254 (instantaeous)
1338!! - any p1 (analysis/observation or forecast)
1339!! - p2 = 0 (processing interval null, instantaneous data)
1340!!
1341!! Output data will have timerange of type \a stat_proc, and p2 = \a
1342!! step. The supported statistical processing methods (parameter \a
1343!! stat_proc) are:
1344!!
1345!! - 0 average
1346!! - 2 maximum
1347!! - 3 minimum
1348!! - 4 difference
1349!!
1350!! A maximum distance in time for input valid data can be assigned
1351!! with the optional argument \a max_step, in order to filter datasets
1352!! with too long "holes".
1353SUBROUTINE volgrid6d_compute_stat_proc_agg(this, that, stat_proc, &
1354 step, start, full_steps, max_step, clone)
1355TYPE(volgrid6d),INTENT(inout) :: this !< volume providing data to be recomputed, it is not modified by the method, apart from performing a \a volgrid6d_alloc_vol on it
1356TYPE(volgrid6d),INTENT(out) :: that !< output volume which will contain the recomputed data
1357INTEGER,INTENT(in) :: stat_proc !< type 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
1358TYPE(timedelta),INTENT(in) :: step !< length of the step over which the statistical processing is performed
1359TYPE(datetime),INTENT(in),OPTIONAL :: start !< start of statistical processing interval
1360LOGICAL,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
1361TYPE(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
1362LOGICAL , INTENT(in),OPTIONAL :: clone !< if provided and \c .TRUE. , clone the gaid's from \a this to \a that
1363
1364INTEGER :: tri
1365INTEGER i, j, n, ninp, i3, i6
1366TYPE(arrayof_ttr_mapper),POINTER :: map_ttr(:,:)
1367TYPE(timedelta) :: lmax_step
1368LOGICAL :: lclone
1369REAL,POINTER :: voldatiin(:,:), voldatiout(:,:)
1370
1371
1372NULLIFY(voldatiin, voldatiout)
1373tri = 254
1374IF (PRESENT(max_step)) THEN
1375 lmax_step = max_step
1376ELSE
1377 lmax_step = timedelta_max
1378ENDIF
1379
1381! be safe
1382CALL volgrid6d_alloc_vol(this)
1383
1384! when volume is not decoded it is better to clone anyway to avoid
1385! overwriting fields
1386lclone = optio_log(clone) .OR. .NOT.ASSOCIATED(this%voldati)
1387! initialise the output volume
1389CALL volgrid6d_alloc(that, dim=this%griddim%dim, ntimerange=1, &
1390 nlevel=SIZE(this%level), nvar=SIZE(this%var), ini=.false.)
1391that%level = this%level
1392that%var = this%var
1393
1394CALL recompute_stat_proc_agg_common(this%time, this%timerange, stat_proc, tri, &
1395 step, this%time_definition, that%time, that%timerange, map_ttr, &
1396 start=start, full_steps=full_steps)
1397
1398CALL volgrid6d_alloc_vol(that, decode=ASSOCIATED(this%voldati))
1399
1400do_otimerange: DO j = 1, SIZE(that%timerange)
1401 do_otime: DO i = 1, SIZE(that%time)
1402 ninp = map_ttr(i,j)%arraysize
1403 IF (ninp <= 0) cycle do_otime
1404
1405 IF (stat_proc == 4) THEN ! check validity for difference
1406 IF (map_ttr(i,j)%array(1)%extra_info /= 1 .OR. &
1407 map_ttr(i,j)%array(ninp)%extra_info /= 2) THEN
1409 cycle do_otime
1410 ENDIF
1411 ELSE
1412! check validity condition (missing values in volume are not accounted for)
1413 DO n = 2, ninp
1414 IF (map_ttr(i,j)%array(n)%time - map_ttr(i,j)%array(n-1)%time > &
1415 lmax_step) THEN
1417 cycle do_otime
1418 ENDIF
1419 ENDDO
1420 ENDIF
1421
1422 DO i6 = 1, SIZE(this%var)
1423 DO i3 = 1, SIZE(this%level)
1424 CALL volgrid_get_vol_2d(that, i3, i, j, i6, voldatiout)
1425
1426 IF (stat_proc == 4) THEN ! special treatment for difference
1427 IF (lclone) THEN
1429 map_ttr(i,j)%array(1)%itr,i6), that%gaid(i3,i,j,i6))
1430 ELSE
1431 that%gaid(i3,i,j,i6) = this%gaid(i3, map_ttr(i,j)%array(1)%it, &
1432 map_ttr(i,j)%array(1)%itr,i6)
1433 ENDIF
1434! improve the next workflow?
1435 CALL volgrid_get_vol_2d(this, i3, map_ttr(i,j)%array(ninp)%it, &
1436 map_ttr(i,j)%array(ninp)%itr, i6, voldatiin)
1437 voldatiout = voldatiin
1438 CALL volgrid_get_vol_2d(this, i3, map_ttr(i,j)%array(1)%it, &
1439 map_ttr(i,j)%array(1)%itr, i6, voldatiin)
1440
1442 voldatiout(:,:) = voldatiout(:,:) - voldatiin(:,:)
1443 ELSEWHERE
1444 voldatiout(:,:) = rmiss
1445 END WHERE
1446
1447 ELSE ! other stat_proc
1448 DO n = 1, ninp
1449 CALL volgrid_get_vol_2d(this, i3, map_ttr(i,j)%array(n)%it, &
1450 map_ttr(i,j)%array(n)%itr, i6, voldatiin)
1451
1452 IF (n == 1) THEN
1453 voldatiout = voldatiin
1454 IF (lclone) THEN
1456 map_ttr(i,j)%array(n)%itr,i6), that%gaid(i3,i,j,i6))
1457 ELSE
1458 that%gaid(i3,i,j,i6) = this%gaid(i3, map_ttr(i,j)%array(n)%it, &
1459 map_ttr(i,j)%array(n)%itr,i6)
1460 ENDIF
1461
1462 ELSE ! second or more time
1463 SELECT CASE(stat_proc)
1464 CASE (0, 1) ! average, accumulation
1466 voldatiout(:,:) = voldatiout(:,:) + voldatiin(:,:)
1467 ELSEWHERE
1468 voldatiout(:,:) = rmiss
1469 END WHERE
1470 CASE(2) ! maximum
1472 voldatiout(:,:) = max(voldatiout(:,:), voldatiin(:,:))
1473 ELSEWHERE
1474 voldatiout(:,:) = rmiss
1475 END WHERE
1476 CASE(3) ! minimum
1478 voldatiout(:,:) = min(voldatiout(:,:), voldatiin(:,:))
1479 ELSEWHERE
1480 voldatiout(:,:) = rmiss
1481 END WHERE
1482 END SELECT
1483
1484 ENDIF ! first time
1485 ENDDO
1486 IF (stat_proc == 0) THEN ! average
1488 voldatiout(:,:) = voldatiout(:,:)/ninp
1489 END WHERE
1490 ENDIF
1491 ENDIF
1492 CALL volgrid_set_vol_2d(that, i3, i, j, i6, voldatiout)
1493 ENDDO ! level
1494 ENDDO ! var
1496 ENDDO do_otime
1497ENDDO do_otimerange
1498
1499DEALLOCATE(map_ttr)
1500
1501
1502END SUBROUTINE volgrid6d_compute_stat_proc_agg
1503
1504
1505!> Specialized method for statistically processing a set of data
1506!! already processed with the same statistical processing, on a
1507!! different time interval. This method performs statistical
1508!! processing by difference of different intervals. Data with both
1509!! analysis/observation or forecast timerange are processed.
1510!!
1511!! The output \a that volgrid6d object contains elements from the original volume
1512!! \a this satisfying the conditions
1513!! - timerange (vol7d_timerange_class::vol7d_timerange::timerange)
1514!! of type \a stat_proc
1515!! - any p1 (analysis/observation or forecast)
1516!! - p2 > 0 (processing interval non null, non instantaneous data)
1517!! and equal to a multiplier of \a step if \a full_steps is \c .TRUE.
1518!!
1519!! Output data will have timerange of type \a stat_proc and p2 = \a
1520!! step. The supported statistical processing methods (parameter \a
1521!! stat_proc) are:
1522!!
1523!! - 0 average
1524!! - 1 accumulation
1525!! - 4 difference
1526!!
1527!! Input volume may have any value of \a this%time_definition, and
1528!! that value will be conserved in the output volume.
1529SUBROUTINE volgrid6d_recompute_stat_proc_diff(this, that, stat_proc, step, full_steps, start, clone)
1530TYPE(volgrid6d),INTENT(inout) :: this !< volume providing data to be recomputed, it is not modified by the method, apart from performing a \a volgrid6d_alloc_vol on it
1531TYPE(volgrid6d),INTENT(out) :: that !< output volume which will contain the recomputed data
1532INTEGER,INTENT(in) :: stat_proc !< type 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
1533TYPE(timedelta),INTENT(in) :: step !< length of the step over which the statistical processing is performed
1534LOGICAL,INTENT(in),OPTIONAL :: full_steps !< if provided and \a .TRUE., process only data having processing interval (p2) equal to a multiple of \a step
1535TYPE(datetime),INTENT(in),OPTIONAL :: start !< if provided, together with \a full_steps, processes data on intervals starting at \a start +- an integer amount of \a step intervals
1536LOGICAL,INTENT(in),OPTIONAL :: clone !< if provided and \c .TRUE. , clone the gaid's from \a this to \a that
1537INTEGER :: i3, i4, i6, i, j, k, l, nitr, steps
1538INTEGER,ALLOCATABLE :: map_tr(:,:,:,:,:), f(:), keep_tr(:,:,:)
1539REAL,POINTER :: voldatiin1(:,:), voldatiin2(:,:), voldatiout(:,:)
1540!LOGICAL,POINTER :: mask_timerange(:)
1541LOGICAL :: lclone
1542TYPE(vol7d_var),ALLOCATABLE :: varbufr(:)
1543
1544
1545! be safe
1546CALL volgrid6d_alloc_vol(this)
1547! when volume is not decoded it is better to clone anyway to avoid
1548! overwriting fields
1549lclone = optio_log(clone) .OR. .NOT.ASSOCIATED(this%voldati)
1550! initialise the output volume
1552CALL volgrid6d_alloc(that, dim=this%griddim%dim, &
1553 nlevel=SIZE(this%level), nvar=SIZE(this%var), ini=.false.)
1554that%level = this%level
1555that%var = this%var
1556
1557! compute length of cumulation step in seconds
1559
1560! compute the statistical processing relations, output time and
1561! timerange are defined here
1562CALL recompute_stat_proc_diff_common(this%time, this%timerange, stat_proc, step, &
1563 that%time, that%timerange, map_tr, f, keep_tr, &
1564 this%time_definition, full_steps, start)
1565nitr = SIZE(f)
1566
1567! complete the definition of the output volume
1568CALL volgrid6d_alloc_vol(that, decode=ASSOCIATED(this%voldati))
1569! allocate workspace once
1570IF (.NOT.ASSOCIATED(that%voldati)) THEN
1571 ALLOCATE(voldatiin1(this%griddim%dim%nx, this%griddim%dim%ny), &
1572 voldatiin2(this%griddim%dim%nx, this%griddim%dim%ny), &
1573 voldatiout(this%griddim%dim%nx, this%griddim%dim%ny))
1574ENDIF
1575
1576! copy the timeranges already satisfying the requested step, if any
1577DO i4 = 1, SIZE(this%time)
1578 DO i = 1, nitr
1580 l = keep_tr(i, i4, 1)
1581 k = keep_tr(i, i4, 2)
1582#ifdef DEBUG
1583 CALL l4f_category_log(this%category, l4f_debug, &
1586#endif
1587 DO i6 = 1, SIZE(this%var)
1588 DO i3 = 1, SIZE(this%level)
1590 IF (lclone) THEN
1592 ELSE
1593 that%gaid(i3,l,k,i6) = this%gaid(i3,i4,f(i),i6)
1594 ENDIF
1595 IF (ASSOCIATED(that%voldati)) THEN
1596 that%voldati(:,:,i3,l,k,i6) = this%voldati(:,:,i3,i4,f(i),i6)
1597 ELSE
1598 CALL volgrid_get_vol_2d(this, i3, i4, f(i), i6, voldatiout)
1599 CALL volgrid_set_vol_2d(that, i3, l, k, i6, voldatiout)
1600 ENDIF
1601 ENDIF
1602 ENDDO
1603 ENDDO
1604 ENDIF
1605 ENDDO
1606ENDDO
1607
1608! varbufr required for setting posdef, optimize with an array
1609IF (stat_proc == 1) THEN
1610 ALLOCATE(varbufr(SIZE(this%var)))
1611 DO i6 = 1, SIZE(this%var)
1612 varbufr(i6) = convert(this%var(i6))
1613 CALL vol7d_var_features_set(varbufr(i6))
1614 ENDDO
1615ENDIF
1616! compute statistical processing
1617DO l = 1, SIZE(this%time)
1618 DO k = 1, nitr
1619 DO j = 1, SIZE(this%time)
1620 DO i = 1, nitr
1622 DO i6 = 1, SIZE(this%var)
1623 DO i3 = 1, SIZE(this%level)
1624
1627! take the gaid from the second time/timerange contributing to the
1628! result (l,f(k))
1629 IF (lclone) THEN
1631 that%gaid(i3,map_tr(i,j,k,l,1),map_tr(i,j,k,l,2),i6))
1632 ELSE
1633 that%gaid(i3,map_tr(i,j,k,l,1),map_tr(i,j,k,l,2),i6) = &
1634 this%gaid(i3,l,f(k),i6)
1635 ENDIF
1636
1637! get/set 2d sections API is used
1638 CALL volgrid_get_vol_2d(this, i3, l, f(k), i6, voldatiin1)
1639 CALL volgrid_get_vol_2d(this, i3, j, f(i), i6, voldatiin2)
1640 IF (ASSOCIATED(that%voldati)) &
1641 CALL volgrid_get_vol_2d(that, i3, &
1642 map_tr(i,j,k,l,1), map_tr(i,j,k,l,2), i6, voldatiout)
1643
1644 IF (stat_proc == 0) THEN ! average
1646 voldatiout(:,:) = &
1647 (voldatiin1(:,:)*this%timerange(f(k))%p2 - &
1648 voldatiin2(:,:)*this%timerange(f(i))%p2)/ &
1649 steps
1650 ELSEWHERE
1651 voldatiout(:,:) = rmiss
1652 END WHERE
1653 ELSE IF (stat_proc == 1 .OR. stat_proc == 4) THEN ! acc, diff
1655 voldatiout(:,:) = voldatiin1(:,:) - voldatiin2(:,:)
1656 ELSEWHERE
1657 voldatiout(:,:) = rmiss
1658 END WHERE
1659 IF (stat_proc == 1) THEN
1660 CALL vol7d_var_features_posdef_apply(varbufr(i6), voldatiout)
1661 ENDIF
1662 ENDIF
1663
1664 CALL volgrid_set_vol_2d(that, i3, &
1665 map_tr(i,j,k,l,1), map_tr(i,j,k,l,2), i6, voldatiout)
1666
1667 ENDIF
1668 ENDDO
1669 ENDDO
1670 ENDIF
1671 ENDDO
1672 ENDDO
1673 ENDDO
1674ENDDO
1675
1676IF (.NOT.ASSOCIATED(that%voldati)) THEN
1677 DEALLOCATE(voldatiin1, voldatiin2, voldatiout)
1678ENDIF
1679
1680END SUBROUTINE volgrid6d_recompute_stat_proc_diff
1681
1682
1683!> Specialized method for statistically processing a set of data
1684!! by integration/differentiation.
1685!! This method performs statistical processing by integrating
1686!! (accumulating) in time values representing time-average rates or
1687!! fluxes, (\a stat_proc_input=0 \a stat_proc=1) or by transforming a
1688!! time-integrated (accumulated) value in a time-average rate or flux
1689!! (\a stat_proc_input=1 \a stat_proc=0). Analysis/observation or
1690!! forecast timeranges are processed. The only operation performed is
1691!! respectively multiplying or dividing the values by the length of
1692!! the time interval in seconds.
1693!!
1694!! The output \a that volgrid6d object contains elements from the
1695!! original volume \a this satisfying the conditions
1696!! - timerange (vol7d_timerange_class::vol7d_timerange::timerange)
1697!! of type \a stat_proc_input (0 or 1)
1698!! - any p1 (analysis/observation or forecast)
1699!! - p2 > 0 (processing interval non null, non instantaneous data)
1700!!
1701!! Output data will have timerange of type \a stat_proc (1 or 0) and
1702!! p1 and p2 equal to the corresponding input values. The supported
1703!! statistical processing methods (parameter \a stat_proc) are:
1704!!
1705!! - 0 average
1706!! - 1 accumulation
1707!!
1708!! Input volume may have any value of \a this%time_definition, and
1709!! that value will be conserved in the output volume.
1710SUBROUTINE volgrid6d_compute_stat_proc_metamorph(this, that, stat_proc_input, stat_proc, clone)
1711TYPE(volgrid6d),INTENT(inout) :: this !< volume providing data to be recomputed, it is not modified by the method, apart from performing a \a volgrid6d_alloc_vol on it
1712TYPE(volgrid6d),INTENT(out) :: that !< output volume which will contain the recomputed data
1713INTEGER,INTENT(in) :: stat_proc_input !< type of statistical processing of data that has to be processed (from grib2 table), only data having timerange of this type will be processed, the actual statistical processing performed and which will appear in the output volume, is however determined by \a stat_proc argument
1714INTEGER,INTENT(in) :: stat_proc !< type of statistical processing to be recomputed (from grib2 table), data in output volume \a that will have a timerange of this type
1715LOGICAL , INTENT(in),OPTIONAL :: clone !< if provided and \c .TRUE. , clone the gaid's from \a this to \a that
1716
1717INTEGER :: j, i3, i4, i6
1718INTEGER,POINTER :: map_tr(:)
1719REAL,POINTER :: voldatiin(:,:), voldatiout(:,:)
1720REAL,ALLOCATABLE :: int_ratio(:)
1721LOGICAL :: lclone
1722
1723NULLIFY(voldatiin, voldatiout)
1724
1725! be safe
1726CALL volgrid6d_alloc_vol(this)
1727! when volume is not decoded it is better to clone anyway to avoid
1728! overwriting fields
1729lclone = optio_log(clone) .OR. .NOT.ASSOCIATED(this%voldati)
1730
1731IF (.NOT.((stat_proc_input == 0 .AND. stat_proc == 1) .OR. &
1732 (stat_proc_input == 1 .AND. stat_proc == 0))) THEN
1733
1734 CALL l4f_category_log(this%category, l4f_warn, &
1735 'compute_stat_proc_metamorph, can only be applied to average->accumulated timerange and viceversa')
1736! return an empty volume, without signaling error
1738 CALL volgrid6d_alloc_vol(that)
1739 RETURN
1740ENDIF
1741
1742! initialise the output volume
1744CALL volgrid6d_alloc(that, dim=this%griddim%dim, ntime=SIZE(this%time), &
1745 nlevel=SIZE(this%level), nvar=SIZE(this%var), ini=.false.)
1746that%time = this%time
1747that%level = this%level
1748that%var = this%var
1749
1750CALL compute_stat_proc_metamorph_common(stat_proc_input, this%timerange, stat_proc, &
1751 that%timerange, map_tr)
1752
1753! complete the definition of the output volume
1754CALL volgrid6d_alloc_vol(that, decode=ASSOCIATED(this%voldati))
1755
1756IF (stat_proc == 0) THEN ! average -> integral
1757 int_ratio = 1./real(that%timerange(:)%p2)
1758ELSE ! cumulation
1759 int_ratio = real(that%timerange(:)%p2)
1760ENDIF
1761
1762DO i6 = 1, SIZE(this%var)
1763 DO j = 1, SIZE(map_tr)
1764 DO i4 = 1, SIZE(that%time)
1765 DO i3 = 1, SIZE(this%level)
1766
1767 IF (lclone) THEN
1769 ELSE
1770 that%gaid(i3,i4,map_tr(j),i6) = this%gaid(i3,i4,j,i6)
1771 ENDIF
1772 CALL volgrid_get_vol_2d(this, i3, i4, map_tr(j), i6, voldatiin)
1773 CALL volgrid_get_vol_2d(that, i3, i4, j, i6, voldatiout)
1775 voldatiout = voldatiin*int_ratio(j)
1776 ELSEWHERE
1777 voldatiout = rmiss
1778 END WHERE
1779 CALL volgrid_set_vol_2d(that, i3, i4, j, i6, voldatiout)
1780 ENDDO
1781 ENDDO
1782 ENDDO
1783ENDDO
1784
1785
1786END SUBROUTINE volgrid6d_compute_stat_proc_metamorph
1787
1788!> Method for building a volume containing the vertical coordinate as
1789!! a variable.
1790!! This method produces a volgrid6d volume, derived from \a this,
1791!! containing a single variable, horizontally constant, on the same
1792!! input levels, which describes the vertical coordinate in the form
1793!! of a physical variable. The grid, time and timerange metadata are
1794!! the same as for the original volume. Only a single vertical level
1795!! type, the one matching the \a level argument, is converted to a
1796!! variable. The \a level argument can also indicate the layer between
1797!! two surfaces of the same type, in that case the variable
1798!! representing the vertical coordinate will be set to the value of
1799!! the midpoint between the two layers. If something goes wrong,
1800!! e.g. no level matches \a level argument or the level canot be
1801!! converted to a physical value, an empty volume is returned.
1802SUBROUTINE volgrid6d_compute_vert_coord_var(this, level, volgrid_lev)
1803TYPE(volgrid6d),INTENT(in) :: this !< volume with the vertical levels
1804TYPE(vol7d_level),INTENT(in) :: level !< vertical level to be converted to variable, only the type(s) of level are used not the value(s)
1805TYPE(volgrid6d),INTENT(out) :: volgrid_lev !< output volume with the variable describing the vertical coordinate
1806
1807INTEGER :: nlev, i, ii, iii, iiii
1808TYPE(grid_id) :: out_gaid
1809LOGICAL,ALLOCATABLE :: levmask(:)
1810TYPE(volgrid6d_var) :: lev_var
1811
1813IF (.NOT.ASSOCIATED(this%gaid)) THEN
1814 CALL l4f_log(l4f_error, 'volgrid6d_compute_vert_coord_var: input volume not allocated')
1815 RETURN
1816ENDIF
1817! if layer, both surfaces must be of the same type
1819 CALL l4f_log(l4f_error, 'volgrid6d_compute_vert_coord_var: requested (mixed) layer type not valid')
1820 RETURN
1821ENDIF
1822
1823! look for valid levels to be converted to vars
1824ALLOCATE(levmask(SIZE(this%level)))
1825levmask = this%level%level1 == level%level1 .AND. &
1826 this%level%level2 == level%level2 .AND. c_e(this%level%l1)
1828nlev = count(levmask)
1829IF (nlev == 0) THEN
1830 CALL l4f_log(l4f_error, 'volgrid6d_compute_vert_coord_var: requested level type not available')
1831 RETURN
1832ENDIF
1833
1834out_gaid = grid_id_new()
1835gaidloop: DO i=1 ,SIZE(this%gaid,1)
1836 DO ii=1 ,SIZE(this%gaid,2)
1837 DO iii=1 ,SIZE(this%gaid,3)
1838 DO iiii=1 ,SIZE(this%gaid,4)
1841 EXIT gaidloop
1842 ENDIF
1843 ENDDO
1844 ENDDO
1845 ENDDO
1846ENDDO gaidloop
1847
1848! look for variable corresponding to level
1849lev_var = convert(vol7d_var_new(btable=vol7d_level_to_var(level)), &
1850 grid_id_template=out_gaid)
1852 CALL l4f_log(l4f_error, 'volgrid6d_compute_vert_coord_var: no variable corresponds to requested level type')
1853 RETURN
1854ENDIF
1855
1856! prepare output volume
1858 time_definition=this%time_definition) !, categoryappend=categoryappend)
1859CALL volgrid6d_alloc(volgrid_lev, ntime=SIZE(this%time), nlevel=nlev, &
1860 ntimerange=SIZE(this%timerange), nvar=1)
1861! fill metadata
1862volgrid_lev%time = this%time
1863volgrid_lev%level = pack(this%level, mask=levmask)
1864volgrid_lev%timerange = this%timerange
1865volgrid_lev%var(1) = lev_var
1866
1867CALL volgrid6d_alloc_vol(volgrid_lev, decode=.true.)
1868! fill data
1869DO i = 1, nlev
1871 volgrid_lev%voldati(:,:,i,:,:,:) = real(volgrid_lev%level(i)%l1 + &
1872 volgrid_lev%level(i)%l2)* &
1873 vol7d_level_to_var_factor(volgrid_lev%level(i))/2.
1874 ELSE
1875 volgrid_lev%voldati(:,:,i,:,:,:) = real(volgrid_lev%level(i)%l1)* &
1876 vol7d_level_to_var_factor(volgrid_lev%level(i))
1877 ENDIF
1878ENDDO
1879! fill gaid for subsequent export
1881 DO i=1 ,SIZE(volgrid_lev%gaid,1)
1882 DO ii=1 ,SIZE(volgrid_lev%gaid,2)
1883 DO iii=1 ,SIZE(volgrid_lev%gaid,3)
1884 DO iiii=1 ,SIZE(volgrid_lev%gaid,4)
1886 ENDDO
1887 ENDDO
1888 ENDDO
1889 ENDDO
1891ENDIF
1892
1893END SUBROUTINE volgrid6d_compute_vert_coord_var
1894
Restituiscono il valore dell'oggetto nella forma desiderata. Definition datetime_class.F90:322 Costruttori per le classi datetime e timedelta. Definition datetime_class.F90:311 Functions that return a trimmed CHARACTER representation of the input variable. Definition datetime_class.F90:349 Restituiscono il valore dell'oggetto in forma di stringa stampabile. Definition datetime_class.F90:327 Make a deep copy, if possible, of the grid identifier. Definition grid_id_class.F90:336 Apply the conversion function this to values. Definition volgrid6d_var_class.F90:396 This module defines an abstract interface to different drivers for access to files containing gridded... Definition grid_id_class.F90:249 Module for basic statistical computations taking into account missing data. Definition simple_stat.f90:25 This module contains functions that are only for internal use of the library. Definition stat_proc_engine.F90:211 Extension of volgrid6d_class with methods for performing simple statistical operations on entire volu... Definition volgrid6d_class_compute.F90:214 This module defines objects and methods for managing data volumes on rectangular georeferenced grids. Definition volgrid6d_class.F90:240 Class for managing physical variables in a grib 1/2 fashion. Definition volgrid6d_var_class.F90:218 |