15 USE mo_kind,
ONLY : i4, dp
16 USE mo_os,
ONLY : check_path_isfile
72 subroutine read_timeseries(filename, fileunit, periodStart, periodEnd, optimize, opti_function, data, mask, &
75 use mo_julian,
only : julday
76 use mo_message,
only : error_message
77 use mo_string_utils,
only : num2str
82 character(len = *),
intent(in) :: filename
85 integer(i4),
intent(in) :: fileunit
88 integer(i4),
dimension(3),
intent(in) :: periodstart
91 integer(i4),
dimension(3),
intent(in) :: periodend
94 logical,
intent(in) :: optimize
96 integer(i4),
intent(in) :: opti_function
99 real(dp),
dimension(:),
allocatable,
intent(out) :: data
102 logical,
dimension(:),
allocatable,
optional,
intent(out) :: mask
105 integer(i4),
optional,
intent(out) :: nmeasperday
108 real(dp) :: nodata_file
111 integer(i4) :: timestep_file
114 integer(i4),
dimension(3) :: periodstart_file
117 integer(i4),
dimension(3) :: periodend_file
120 integer(i4),
dimension(5) :: time_file
122 integer(i4) :: i, j, i_max, ios
125 integer(i4) :: idx_st_period
128 integer(i4) :: idx_en_period
131 integer(i4) :: idx_st_file
134 integer(i4) :: idx_en_file
137 integer(i4) :: startjul_file
140 integer(i4) :: endjul_file
143 integer(i4) :: startjul_period
146 integer(i4) :: endjul_period
149 integer(i4) :: length_file
152 integer(i4) :: length_period
156 real(dp),
dimension(:),
allocatable :: data_file
159 character(256) :: dummy
163 call check_path_isfile(path = filename, raise=.true.)
164 open(unit = fileunit, file = filename, action =
'read', status =
'old')
166 read(fileunit,
'(a256)') dummy
167 read(fileunit, *) dummy, nodata_file
168 read(fileunit, *) dummy, timestep_file
169 read(fileunit, *) dummy, (periodstart_file(i), i = 1, 3)
170 read(fileunit, *) dummy, (periodend_file(i), i = 1, 3)
172 if ((timestep_file .lt. 1_i4) .or. (timestep_file .gt. 1440_i4))
then
173 call error_message(
'***ERROR: Number of measurements per day has to be between 1 (daily) and 1440 (every minute)! ', &
178 startjul_period = julday(periodstart(3), periodstart(2), periodstart(1))
179 endjul_period = julday(periodend(3), periodend(2), periodend(1))
180 startjul_file = julday(periodstart_file(3), periodstart_file(2), periodstart_file(1))
181 endjul_file = julday(periodend_file(3), periodend_file(2), periodend_file(1))
183 if (((startjul_period < startjul_file) .OR. (endjul_period > endjul_file)) &
184 .AND. optimize .and. ((opti_function .le. 9_i4) .or. &
185 (opti_function .eq. 14_i4) .or. &
186 (opti_function .eq. 31_i4) .or. &
187 (opti_function .eq. 33_i4)))
then
189 call error_message(
'***ERROR: Simulation period is not covered by observations! ', trim(filename))
193 allocate(
data ((endjul_period - startjul_period + 1_i4) * timestep_file))
195 allocate(data_file((endjul_file - startjul_file + 1_i4) * timestep_file))
196 data_file = nodata_file
198 if (
present(mask))
then
199 allocate(mask((endjul_period - startjul_period + 1_i4) * timestep_file))
204 i_max = (endjul_file - startjul_file + 1_i4) * timestep_file
207 read(fileunit, *, iostat=ios) (time_file(j), j = 1, 5), data_file(i)
208 if ( ios /= 0 )
call error_message( &
209 "ERROR: wanted to read ", num2str(i_max),
" time-steps from ", &
210 filename,
", but reached end-of-file at ", num2str(i) &
213 time_file(1) = time_file(2) + 1
215 length_file = (endjul_file - startjul_file + 1)
216 length_period = (endjul_period - startjul_period + 1)
220 if ((startjul_period .ge. startjul_file) .and. (endjul_period .le. endjul_file))
then
222 idx_en_period = length_period * timestep_file
223 idx_st_file = (startjul_period - startjul_file) * timestep_file + 1
224 idx_en_file = (idx_st_file + length_period - 1) * timestep_file
229 if ((startjul_period .lt. startjul_file) .and. (endjul_period .gt. endjul_file))
then
230 idx_st_period = (startjul_file - startjul_period) * timestep_file + 1
231 idx_en_period = (idx_st_period + length_file - 1) * timestep_file
233 idx_en_file = length_file * timestep_file
238 if ((startjul_period .ge. startjul_file) .and. (endjul_period .gt. endjul_file))
then
240 idx_en_period = (endjul_file - startjul_period) * timestep_file + 1
241 idx_st_file = (startjul_period - startjul_file) * timestep_file + 1
242 idx_en_file = length_file * timestep_file
247 if ((startjul_period .lt. startjul_file) .and. (endjul_period .le. endjul_file))
then
248 idx_st_period = (startjul_file - startjul_period) * timestep_file + 1
249 idx_en_period = (length_period) * timestep_file
251 idx_en_file = (endjul_period - startjul_file) * timestep_file + 1
254 data(idx_st_period : idx_en_period) = data_file(idx_st_file : idx_en_file)
256 if (
present(mask))
then
257 where (abs(
data - nodata_file) .lt. tiny(1.0_dp))
262 if (
present(nmeasperday))
then
263 nmeasperday = timestep_file
Routines to read files containing timeseries data.
subroutine, public read_timeseries(filename, fileunit, periodstart, periodend, optimize, opti_function, data, mask, nmeasperday)
Reads time series in ASCII format.