@@ -26,7 +26,8 @@ module lfric_xios_time_axis_mod
2626 use lfric_ncdf_field_mod, only: lfric_ncdf_field_type
2727 use lfric_ncdf_file_mod, only: lfric_ncdf_file_type
2828 use lfric_xios_read_mod, only: read_field_time_var
29- use lfric_xios_utils_mod, only: parse_date_as_xios, seconds_from_date
29+ use lfric_xios_utils_mod, only: parse_date_as_xios, seconds_from_date, &
30+ read_time_data
3031 use lfric_xios_diag_mod, only: get_field_axis_ref
3132 use linked_list_data_mod, only: linked_list_data_type
3233 use log_mod, only: log_event, log_scratch_space, &
@@ -80,8 +81,6 @@ module lfric_xios_time_axis_mod
8081 procedure, public :: initialise
8182 !> Sets up aspects of time_axis after XIOS is initialised
8283 procedure, public :: setup
83- !> Reads time data with XIOS
84- procedure, private :: read_time_data
8584 !> Getter for time axis name
8685 procedure, public :: get_name
8786 !> Procedure for cycling through time data to find the correct entry
@@ -121,7 +120,7 @@ module lfric_xios_time_axis_mod
121120 end subroutine regridder
122121 end interface
123122
124- public :: regridder
123+ public :: regridder, read_time_dim
125124
126125contains
127126
@@ -202,6 +201,7 @@ contains
202201
203202 type(xios_date) :: start_date, time_origin
204203 character(str_max_filename) :: file_name
204+ integer(i_def) :: i
205205
206206 call log_event( "Performing post-XIOS context set-up for time_axis_type ["// &
207207 trim(self%name)//"]", LOG_LEVEL_TRACE )
@@ -223,116 +223,11 @@ contains
223223 end do
224224
225225 ! Read time data
226- call self%read_time_data(trim(file_name))
226+ self%time_data = read_time_data(trim(file_name))
227+ self%index_data = (/ (i, i=1, size(self%time_data)) /)
227228
228229 end subroutine setup
229230
230- !> @brief Read time data into time axis using NetCDF tools
231- subroutine read_time_data(self, file_path)
232-
233- implicit none
234-
235- class(time_axis_type), intent(inout) :: self
236- character(len=*), intent(in) :: file_path
237-
238- ! Local variables for XIOS interface
239- integer(i_def) :: time_axis_size, i, t
240- real(r_def), allocatable :: input_data(:)
241- character(str_def) :: time_units, ref_date_str, var_id, dim_id
242- character(str_long) :: unit_attr
243- character(str_def), parameter :: valid_units(4) = &
244- (/'seconds', 'days ', 'hours ', 'months '/)
245- type(xios_duration) :: ref_time, mean_time, month_duration
246- type(xios_date) :: ref_date
247- integer(i_def), parameter :: len_date = 18 ! Length of CF date is 18 characters
248- integer(i_def), parameter :: len_delim = 7 ! Delimiter between unit and
249- ! date is 7 characters
250-
251- ! NetCDF reading variables
252- type(lfric_ncdf_file_type) :: file_ncdf
253- type(lfric_ncdf_dims_type) :: time_dim
254- type(lfric_ncdf_field_type) :: time_var
255-
256- file_ncdf = lfric_ncdf_file_type( trim(file_path)//".nc", &
257- open_mode=FILE_OP_OPEN, &
258- io_mode=FILE_MODE_READ )
259-
260- ! Plant func ancils have non-CF-compliant time representation so we need to
261- ! account for that for the time being
262- if (file_ncdf%contains_var("time")) then
263- var_id = "time"
264- dim_id = "time"
265- else if (file_ncdf%contains_var("month_number")) then
266- var_id = "month_number"
267- dim_id = "month_number"
268- else
269- call log_event( "Invalid representation of time in file ["// &
270- trim(file_path)//"]", log_level_error)
271- end if
272-
273- ! Get size of time axis from file
274- time_dim = lfric_ncdf_dims_type(trim(dim_id), file_ncdf)
275- time_axis_size = time_dim%get_size()
276- allocate( input_data( time_axis_size ) )
277- allocate( self%time_data( time_axis_size ) )
278- allocate( self%index_data( time_axis_size ) )
279- self%index_data = (/ (i, i=1, size(input_data)) /)
280-
281- ! Read the time data from the ancil file
282- time_var = lfric_ncdf_field_type(trim(var_id), file_ncdf)
283- call time_var%read_data(input_data)
284-
285- ! Read time units and reference date from file
286- if (file_ncdf%contains_var("time")) then
287- unit_attr = time_var%get_char_attribute("units")
288- time_units = unit_attr( 1 : len(trim(unit_attr))-len_date-len_delim )
289- if ( .not. any( valid_units == trim(adjustl(time_units)) ) ) then
290- write( log_scratch_space,'(A,A)' ) "Invalid units for "//trim(self%name)// &
291- " time axis: "// trim(time_units)
292- call log_event( log_scratch_space, LOG_LEVEL_ERROR )
293- end if
294- ref_date_str = unit_attr( len(trim(unit_attr))-len_date : len(trim(unit_attr)) )
295- ref_date = parse_date_as_xios(trim(adjustl(ref_date_str)))
296- else if (file_ncdf%contains_var("month_number")) then
297- ! Non CF files are given the bare minimum treatment
298- time_units = "months"
299- ref_date = xios_date(1970, 01, 01, 00, 00, 00)
300- end if
301-
302- call file_ncdf%close_file()
303-
304- ! Convert input time data to xios_date type
305- do t = 1, time_axis_size
306- ref_time = xios_duration(0, 0, 0, 0, 0, 0)
307- if ( trim(adjustl(time_units)) == "seconds" ) then
308- ref_time%second = input_data(t)
309- else if ( trim(adjustl(time_units)) == "hours" ) then
310- ref_time%hour = input_data(t)
311- else if ( trim(adjustl(time_units)) == "days" ) then
312- ref_time%day = input_data(t)
313- else if ( trim(adjustl(time_units)) == "months" ) then
314- ! Offset months backwards to account for monthly mean
315- ref_time%month = input_data(t) - 1
316- end if
317- self%time_data(t) = ref_date + ref_time
318- end do
319-
320- ! Correct "months" data to be monthly mean - centred on middle of month.
321- ! This can't be done above as the conversion to seconds can only be done
322- ! with xios_date objects, not xios_durations
323- if ( time_units == "months" ) then
324- mean_time = xios_duration(0, 0, 0, 0, 0, 0)
325- month_duration = xios_duration(0, 1, 0, 0, 0, 0)
326- do t = 1, time_axis_size
327- mean_time%second = ( &
328- seconds_from_date(self%time_data(t)+month_duration) - &
329- seconds_from_date(self%time_data(t)) ) / 2
330- self%time_data(t) = self%time_data(t) + mean_time
331- end do
332- end if
333-
334- end subroutine read_time_data
335-
336231 !> @brief Returns the time_axis name.
337232 !> @return output_name The time axis name
338233 function get_name(self) result(output_name)
@@ -727,4 +622,17 @@ contains
727622
728623 end subroutine interp_field_1d
729624
625+ function read_time_dim(path) result(time_dim)
626+
627+ implicit none
628+
629+ character(*), intent(in) :: path
630+ type(xios_date), allocatable :: time_data(:)
631+ integer(i_def) :: time_dim
632+
633+ time_data = read_time_data(path)
634+ time_dim = size(time_data)
635+
636+ end function read_time_dim
637+
730638end module lfric_xios_time_axis_mod
0 commit comments