Skip to content
Snippets Groups Projects
Commit ccf8c63a authored by Sebastian Müller's avatar Sebastian Müller 🐈
Browse files

mo_temporal_aggregation: add day2mon_sum; make mon_avg intent(out)

parent e7ebf6d0
No related branches found
No related tags found
1 merge request!78mLM related updates
Pipeline #204681 failed with stages
in 11 minutes and 47 seconds
......@@ -4,7 +4,10 @@
!> \brief Temporal aggregation for time series (averaging)
!> \details This module does temporal aggregation (averaging) of time series
!> \authors Oldrich Rakovec, Rohini Kumar
!> \changelog
!! - Pallav Shrestha, Jun 2019
!! - changed the output argument I/O from INOUT to OUT
!> \authors Oldrich Rakovec, Rohini Kumar, Pallav Shrestha
!> \date October 2015
!> \copyright Copyright 2005-\today, the CHS Developers, Sabine Attinger: All rights reserved.
!! FORCES is released under the LGPLv3+ license \license_note
......@@ -18,6 +21,7 @@ MODULE mo_temporal_aggregation
PUBLIC :: day2mon_average ! converts daily time series to monthly
PUBLIC :: hour2day_average ! converts hourly time series to daily
PUBLIC :: day2mon_sum ! converts daily time series to monthly sums
! ------------------------------------------------------------------
......@@ -29,7 +33,7 @@ MODULE mo_temporal_aggregation
!> \param[in] "integer(i4) :: year" year of the starting time
!> \param[in] "integer(i4) :: month" month of the starting time
!> \param[in] "integer(i4) :: day" day of the starting time
!> \param[inout] "real(sp/dp) :: mon_average(:)" array of monthly averaged values
!> \param[out] "real(sp/dp) :: mon_average(:)" array of monthly averaged values
!> \param[in] "real(sp/dp), optional :: misval" missing value definition
!> \param[in] "logical, optional :: rm_misval" switch to exclude missing values
......@@ -66,6 +70,27 @@ MODULE mo_temporal_aggregation
! ------------------------------------------------------------------
!> \brief Day-to-month sum (day2mon_sum)
!> \details converts daily time series to monthly sums
!> \param[in] "real(sp/dp) :: daily_data(:)" array of daily time series
!> \param[in] "integer(i4) :: year" year of the starting time
!> \param[in] "integer(i4) :: month" month of the starting time
!> \param[in] "integer(i4) :: day" day of the starting time
!> \param[out] "real(sp/dp) :: mon_sum(:)" array of monthly summed values
!> \param[in] "real(sp/dp), optional :: misval" missing value definition
!> \param[in] "logical, optional :: rm_misval" switch to exclude missing values
!> \author Pallav Kumar Shrestha
!> \date Apr 2019
INTERFACE day2mon_sum
MODULE PROCEDURE day2mon_sum_dp
END INTERFACE day2mon_sum
! ------------------------------------------------------------------
PRIVATE
! ------------------------------------------------------------------
......@@ -81,7 +106,7 @@ CONTAINS
INTEGER(i4), INTENT(IN) :: monthS ! month of the initial time step
INTEGER(i4), INTENT(IN) :: dayS ! day of the initial time step
REAL(dp), dimension(:), allocatable, INTENT(INOUT) :: mon_avg ! array of the monthly averages
REAL(dp), dimension(:), allocatable, INTENT(OUT) :: mon_avg ! array of the monthly averages
REAL(dp), optional, INTENT(IN) :: misval ! missing value definition
logical, optional, INTENT(IN) :: rm_misval ! switch to remove missing values
......@@ -155,6 +180,7 @@ CONTAINS
end do
! calculate monthly averages
if(allocated(mon_avg)) deallocate(mon_avg)
allocate(mon_avg(nmonths))
mon_avg(:) = missing
kk = 0
......@@ -273,4 +299,119 @@ CONTAINS
END SUBROUTINE hour2day_average_dp
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
SUBROUTINE day2mon_sum_dp(daily_data, yearS, monthS, dayS, mon_sum, misval, rm_misval)
IMPLICIT NONE
REAL(dp), dimension(:), INTENT(IN) :: daily_data ! array of daily data
INTEGER(i4), INTENT(IN) :: yearS ! year of the initial time step
INTEGER(i4), INTENT(IN) :: monthS ! month of the initial time step
INTEGER(i4), INTENT(IN) :: dayS ! day of the initial time step
REAL(dp), dimension(:), allocatable, INTENT(OUT) :: mon_sum ! array of the monthly sums
REAL(dp), optional, INTENT(IN) :: misval ! missing value definition
logical, optional, INTENT(IN) :: rm_misval ! switch to remove missing values
! local variables
INTEGER(i4) :: ndays, tt, kk ! number of days, indices
INTEGER(i4) :: start_day, end_day ! size of input array, size of days
INTEGER(i4) :: y, m
INTEGER(i4) :: year, month, day ! variables for date
INTEGER(i4) :: yearE, monthE, dayE ! vatiables for End date
REAL(dp) :: newTime
REAL(dp), dimension(:, :), allocatable :: nCounter_m ! counter number of days in months (w/ data)
REAL(dp), dimension(:, :), allocatable :: nCounter_m_full ! counter number of days in months (complete)
REAL(dp), dimension(:, :), allocatable :: mon_sum_temp_2d ! monthly sum temporary variable
REAL(dp), dimension(:), allocatable :: mon_sum_temp_1d ! monthly sum temporary variable
INTEGER(i4) :: nmonths ! number of days, number of months
LOGICAL :: remove ! switch for considering missing data
REAL(dp) :: missing ! switch for reading missing value or default -9999.
if (present(misval)) then
missing = misval
else
missing = -9999._dp
end if
if (present(rm_misval)) then
remove = rm_misval
else
remove = .FALSE.
end if
! get total number of days
ndays = SIZE(daily_data)
! assign initial julian day
start_day = julday(dayS, monthS, yearS)
! calculate last julian day
end_day = start_day + ndays - 1_i4
! get year, month and day of the end date:
call dec2date(real(end_day, dp), yy = yearE, mm = monthE, dd = dayE)
! get number of days with data for each month
allocate(nCounter_m(yearS : yearE, 12))
allocate(nCounter_m_full(yearS : yearE, 12))
allocate(mon_sum_temp_2d(yearS : yearE, 12))
nCounter_m(:, :) = 0
nCounter_m_full(:, :) = 0
mon_sum_temp_2d(:, :) = 0.0_dp
newTime = real(start_day, dp)
! calculate monthly sums
do tt = 1, (end_day - start_day + 1)
call dec2date((newTime + tt - 1), yy = year, mm = month, dd = day)
nCounter_m_full(year, month) = nCounter_m_full(year, month) + 1.0_dp
if (abs(daily_data(tt) - missing) .lt. eps_dp) cycle
mon_sum_temp_2d(year, month) = mon_sum_temp_2d(year, month) + daily_data(tt)
nCounter_m(year, month) = nCounter_m(year, month) + 1.0_dp
end do
! calculate number of months
nmonths = 0
do y = yearS, yearE
do m = 1, 12
if ((y .EQ. yearS) .AND. (m .LT. monthS)) cycle
if ((y .EQ. yearE) .AND. (m .GT. monthE)) cycle
nmonths = nmonths + 1
end do
end do
! store monthly sums
allocate(mon_sum_temp_1d(nmonths))
mon_sum_temp_1d(:) = missing
kk = 0
do y = yearS, yearE
do m = 1, 12
if ((y .EQ. yearS) .AND. (m .LT. monthS)) cycle
if ((y .EQ. yearE) .AND. (m .GT. monthE)) cycle
kk = kk + 1
if ((nCounter_m(y, m) .GT. 0) .AND. &
(abs(nCounter_m_full(y, m) - nCounter_m(y, m)) .LT. eps_dp)) then
mon_sum_temp_1d(kk) = mon_sum_temp_2d(y, m)
else if ((nCounter_m(y, m) .GT. 0) .AND. remove) then
mon_sum_temp_1d(kk) = mon_sum_temp_2d(y, m)
end if
end do
end do
if(allocated(mon_sum)) deallocate(mon_sum)
allocate(mon_sum(nmonths))
mon_sum = mon_sum_temp_1d
deallocate(nCounter_m_full)
deallocate(nCounter_m)
deallocate(mon_sum_temp_2d)
deallocate(mon_sum_temp_1d)
END SUBROUTINE day2mon_sum_dp
END MODULE mo_temporal_aggregation
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment