250 MODULE diag_table_mod
252 USE fms2_io_mod,
ONLY: ascii_read
256 & diag_other, diag_ocean, diag_all,
coord_type, append_pelist_name, pelist_name
258 USE platform_mod,
ONLY: fms_file_len
268 CHARACTER(len=128) :: module_name, field_name, output_name, file_name
269 CHARACTER(len=50) :: time_sampling
270 CHARACTER(len=50) :: time_method
271 CHARACTER(len=50) :: spatial_ops
272 TYPE(coord_type) :: regional_coords
279 INTEGER :: output_freq
280 INTEGER :: file_format
281 INTEGER :: new_file_freq
282 INTEGER :: file_duration
283 INTEGER :: iTime_units
284 INTEGER :: iOutput_freq_units
285 INTEGER :: iNew_file_freq_units
286 INTEGER :: iFile_duration_units
287 CHARACTER(len=FMS_FILE_LEN) :: file_name
288 CHARACTER(len=10) :: output_freq_units
289 CHARACTER(len=10) :: time_units
290 CHARACTER(len=128) :: long_name
291 CHARACTER(len=10) :: new_file_freq_units
292 CHARACTER(len=25) :: start_time_s
293 CHARACTER(len=10) :: file_duration_units
294 CHARACTER(len=10) :: filename_time_bounds
295 TYPE(time_type) :: start_time
301 CHARACTER(len=*),
PARAMETER :: UNALLOWED_QTE =
"'"//
'"'
302 CHARACTER(len=*),
PARAMETER :: UNALLOWED_ALL = unallowed_qte//
","
319 INTEGER,
INTENT(in),
OPTIONAL :: diag_subset
320 INTEGER,
INTENT(out),
OPTIONAL,
TARGET :: istat
322 CHARACTER(len=*),
INTENT(out),
OPTIONAL :: err_msg
325 INTEGER,
PARAMETER :: dt_line_length = 256
327 INTEGER :: record_len
330 INTEGER :: commentstart
331 INTEGER :: diag_subset_output
332 INTEGER :: nfields, nfiles
334 INTEGER,
TARGET :: mystat
335 INTEGER,
POINTER :: pstat
337 CHARACTER(len=5) :: line_number
338 CHARACTER(len=256) :: record_line
339 CHARACTER(len=256) :: local_err_msg
340 CHARACTER(len=:),
DIMENSION(:),
ALLOCATABLE :: diag_table
341 integer :: base_time_int(6)
347 IF (
PRESENT(istat) )
THEN
355 IF (
PRESENT(diag_subset) )
THEN
356 diag_subset_output = diag_subset
358 diag_subset_output = diag_all
361 call ascii_read(
'diag_table', diag_table, num_lines=num_lines)
364 READ (unit=diag_table(1), fmt=*, iostat=mystat) global_descriptor
365 IF ( mystat /= 0 )
THEN
368 'Error reading the global descriptor from the diagnostic table.', err_msg) )
RETURN
372 READ (unit=diag_table(2), fmt=*, iostat=mystat) base_time_int
373 IF ( mystat /= 0 )
THEN
375 IF (
fms_error_handler(
'diag_manager_init',
'Error reading the base date from the diagnostic table.', &
383 pass:
DO npass = 1, 2
384 parser:
DO line_num=3, num_lines
388 READ (diag_table(line_num), fmt=
'(A)', iostat=mystat) record_line
390 WRITE (line_number,
'(I5)') line_num
392 IF ( mystat > 0 )
THEN
393 IF (
mpp_pe() == mpp_root_pe() ) &
394 &
CALL error_mesg(
"diag_table_mod::parse_diag_table",&
395 &
"Problem reading the diag_table (line:" //line_number//
").", fatal)
397 ELSE IF ( mystat < 0 )
THEN
402 record_len = len_trim(record_line)
405 commentstart = index(record_line,
'#')
406 IF ( commentstart .NE. 0 ) record_line = record_line(1:commentstart-1)
407 IF ( len_trim(record_line) == 0 .OR. record_len == 0 ) cycle parser
409 init:
IF ( npass == 1 )
THEN
411 temp_file =
parse_file_line(line=record_line, istat=mystat, err_msg=local_err_msg)
413 IF ( mystat > 0 )
THEN
414 CALL error_mesg(
"diag_table_mod::parse_diag_table",&
415 & trim(local_err_msg)//
" (line:" //trim(line_number)//
").", fatal)
416 ELSE IF ( mystat < 0 )
THEN
417 IF (
mpp_pe() == mpp_root_pe() )&
418 &
CALL error_mesg(
"diag_table_mod::parse_diag_table",&
419 & trim(local_err_msg)//
" (line: "//trim(line_number)//
").", warning)
421 ELSE IF ( (diag_subset_output == diag_other .AND. index(lowercase(temp_file%file_name),
"ocean").NE.0)&
422 & .OR. (diag_subset_output == diag_ocean .AND. index(lowercase(temp_file%file_name),
"ocean").EQ.0)&
425 ELSE IF ( temp_file%new_file_freq > 0 )
THEN
427 CALL init_file(temp_file%file_name, temp_file%output_freq, temp_file%iOutput_freq_units, &
428 & temp_file%file_format, temp_file%iTime_units, temp_file%long_name, 1, &
429 & temp_file%new_file_freq, temp_file%iNew_file_freq_units,&
430 & temp_file%start_time, temp_file%file_duration, temp_file%iFile_duration_units, &
431 & temp_file%filename_time_bounds)
433 CALL init_file(temp_file%file_name, temp_file%output_freq, temp_file%iOutput_freq_units, &
434 & temp_file%file_format, temp_file%iTime_units, temp_file%long_name, 1)
441 IF ( .NOT.
is_a_file(trim(record_line)) )
THEN
442 temp_field =
parse_field_line(line=record_line, istat=mystat, err_msg=local_err_msg)
445 IF ( mystat > 0 )
THEN
446 CALL error_mesg(
"diag_table_mod::parse_diag_table",&
447 & trim(local_err_msg)//
" (line: "//trim(line_number)//
").",fatal)
448 ELSE IF ( mystat < 0 )
THEN
449 IF (
mpp_pe() == mpp_root_pe() )&
450 &
CALL error_mesg(
"diag_table_mod::Parse_diag_table",&
451 & trim(local_err_msg)//
" (line: "//trim(line_number)//
").",warning)
453 ELSE IF ((diag_subset_output == diag_other .AND. index(lowercase(temp_field%file_name),
"ocean").NE.0)&
454 &.OR. (diag_subset_output == diag_ocean .AND. index(lowercase(temp_field%file_name),
"ocean").EQ.0)&
457 ELSE IF ( lowercase(trim(temp_field%spatial_ops)) ==
'none' )
THEN
459 CALL init_output_field(temp_field%module_name, temp_field%field_name, temp_field%output_name, &
460 & temp_field%file_name, temp_field%time_method, temp_field%pack, 1)
463 CALL init_output_field(temp_field%module_name, temp_field%field_name, temp_field%output_name, &
464 & temp_field%file_name, temp_field%time_method, temp_field%pack, 1, temp_field%regional_coords)
468 nfields = nfields + 1
475 DEALLOCATE(diag_table)
479 IF ( local_err_msg /=
'' )
THEN
481 IF (
fms_error_handler(
'diag_table_mod::parse_diag_table', trim(local_err_msg), err_msg) )
RETURN
492 CHARACTER(len=*),
INTENT(in) :: line
493 INTEGER,
INTENT(out),
OPTIONAL,
TARGET :: istat
497 CHARACTER(len=*),
INTENT(out),
OPTIONAL :: err_msg
500 INTEGER,
TARGET :: mystat
501 INTEGER,
POINTER :: pstat
502 INTEGER :: year, month, day, hour, minute, second
503 CHARACTER(len=256) :: local_err_msg
505 IF (
PRESENT(istat) )
THEN
526 IF ( mystat > 0 )
THEN
528 IF (
fms_error_handler(
'diag_table_mod::parse_file_line',
'Incorrect file description format in diag_table.', &
536 &
'Unallowed character in file_name in the diag_table.', err_msg) )
RETURN
541 &
'Unallowed character in output_freq_units in the diag_table.', err_msg) )
RETURN
546 &
'Unallowed character in time_units in the diag_table.', err_msg) )
RETURN
551 &
'Unallowed character in long_name in the diag_table.', err_msg) )
RETURN
553 IF ( scan(
parse_file_line%new_file_freq_units, unallowed_all) > 0 )
THEN
556 &
'Unallowed character in new_file_freq_units in the diag_table.', err_msg) )
RETURN
561 &
'Unallowed character in start_time_s in the diag_table.', err_msg) )
RETURN
563 IF ( scan(
parse_file_line%file_duration_units, unallowed_all) > 0 )
THEN
566 &
'Unallowed character in file_duration_units in the diag_table.', err_msg) )
RETURN
577 &
'Invalid file format for file description in the diag_table.',&
589 IF (
fms_error_handler(
'diag_table_mod::parse_file_line',
'Invalid time axis units in diag_table.', err_msg) )&
594 IF (
fms_error_handler(
'diag_table_mod::parse_file_line',
'Invalid output frequency units in diag_table.', &
599 IF (
fms_error_handler(
'diag_table_mod::parse_file_line',
'Invalid new file frequency units in diag_table.', &
604 IF (
fms_error_handler(
'diag_table_mod::parse_file_line',
'Invalid file duration units in diag_table.',err_msg))&
616 READ (
parse_file_line%start_time_s, fmt=*, iostat=mystat) year, month, day, hour, minute, second
617 IF ( mystat /= 0 )
THEN
620 &
'Invalid start time in the file description in diag_table.', err_msg) )
RETURN
623 IF ( local_err_msg /=
'' )
THEN
625 IF (
fms_error_handler(
'diag_table_mod::parse_file_line', local_err_msg, err_msg) )
RETURN
636 END IF new_file_freq_present
647 &
'filename_time_bounds must be "begin", "middle", "end".', err_msg) )
RETURN
661 CHARACTER(len=*),
INTENT(in) :: line
662 INTEGER,
INTENT(out),
OPTIONAL,
TARGET :: istat
666 CHARACTER(len=*),
OPTIONAL,
INTENT(out) :: err_msg
669 INTEGER,
TARGET :: mystat
670 INTEGER,
POINTER :: pstat
672 IF (
PRESENT(istat) )
THEN
682 IF ( mystat /= 0 )
THEN
684 IF ( fms_error_handler(
'diag_table_mod::parse_field_line',&
685 &
'Field description format is incorrect in diag_table.', err_msg) )
RETURN
691 IF ( fms_error_handler(
'diag_table_mod::parse_field_line',&
692 &
'Unallowed character in module_name in the diag_table.', err_msg) )
RETURN
696 IF ( fms_error_handler(
'diag_table_mod::parse_field_line',&
697 &
'Unallowed character in field_name in the diag_table.', err_msg) )
RETURN
701 IF ( fms_error_handler(
'diag_table_mod::parse_field_line',&
702 &
'Unallowed character in output_name in the diag_table.', err_msg) )
RETURN
706 IF ( fms_error_handler(
'diag_table_mod::parse_field_line',&
707 &
'Unallowed character in file_name in the diag_table.', err_msg) )
RETURN
711 IF ( fms_error_handler(
'diag_table_mod::parse_field_line',&
712 &
'Unallowed character in time_sampling in the diag_table.', err_msg) )
RETURN
716 IF ( fms_error_handler(
'diag_table_mod::parse_field_line',&
717 &
'Unallowed character in time_method in the diag_table.', err_msg) )
RETURN
721 IF ( fms_error_handler(
'diag_table_mod::parse_field_line',&
722 &
'Unallowed character in spatial_ops in the diag_table.', err_msg) )
RETURN
731 IF ( fms_error_handler(
'diag_table_mod::parse_field_line',&
732 &
'Packing is out of range for the field description in diag_table.', err_msg) )
RETURN
737 IF ( mystat /= 0 )
THEN
738 IF ( fms_error_handler(
'diag_table_mod::parse_field_line',&
739 &
'Error in regional output description for field description in diag_table.', err_msg) )
RETURN
750 CHARACTER(len=*),
INTENT(in) :: line
752 CHARACTER(len=5) :: first
756 #if defined __PATHSCALE__ || defined _CRAYFTN
760 CHARACTER(len=10) :: secondstring
761 INTEGER :: comma1, comma2, linelen
764 comma1 = index(line,
',') + 1
765 comma2 = index(line(comma1:linelen),
',') + comma1 - 2
768 secondstring = adjustl(line(comma1:comma2))
769 READ (unit=secondstring, fmt=
'(I)', iostat=mystat) second
771 READ (unit=line, fmt=*, iostat=mystat) first, second
781 CHARACTER(len=*),
INTENT(IN) :: file_name_string
783 INTEGER :: file_name_len
787 file_name_len = len_trim(file_name_string)
790 IF ( file_name_len > 2 )
THEN
791 IF ( file_name_string(file_name_len-2:file_name_len) ==
'.nc' )
THEN
793 file_name_len = file_name_len - 3
799 IF ( append_pelist_name )
THEN
817 CHARACTER(len=*),
INTENT(IN) :: unit_string
819 SELECT CASE (trim(unit_string))
842 END MODULE diag_table_mod
type(time_type) function get_base_time()
gets the module variable base_time
subroutine set_base_time(base_time_int)
Set the module variable base_time.
Define the region for field output.
pure character(len=128) function fix_file_name(file_name_string)
Fixes the file name for use with diagnostic file and field initializations.
subroutine initialize_output_arrays()
Allocate the file, in and out field arrays after reading the diag_table file. (CURRENTLY EMPTY)
type(field_description_type) function parse_field_line(line, istat, err_msg)
Parse a field description line from the diag_table file.
type(file_description_type) function parse_file_line(line, istat, err_msg)
parse_file_line parses a file description line from the diag_table file, and returns a TYPE(file_desc...
pure logical function is_a_file(line)
Determines if a line from the diag_table file is a file.
subroutine, public parse_diag_table(diag_subset, istat, err_msg)
Parse the diag_table in preparation for diagnostic output.
pure integer function find_unit_ivalue(unit_string)
Return the integer value for the given time unit.
Private type to hold field information for the diag table.
Private type to hold file information for the diag table.
subroutine, public init_input_field(module_name, field_name, tile_count)
Initialize the input field.
subroutine, public init_file(name, output_freq, output_units, format, time_units, long_name, tile_count, new_file_freq, new_file_freq_units, start_time, file_duration, file_duration_units, filename_time_bounds)
Initialize the output file.
subroutine, public init_output_field(module_name, field_name, output_name, output_file, time_method, pack, tile_count, local_coord)
Initialize the output field.
subroutine, public check_duplicate_output_fields(err_msg)
Checks to see if output_name and output_file are unique in output_fields.
logical function, public fms_error_handler(routine, message, err_msg)
Facilitates the control of fatal error conditions.
subroutine, public error_mesg(routine, message, level)
Print notes, warnings and error messages; terminates program for warning and error messages....
integer function mpp_pe()
Returns processor ID.
Given an input date in year, month, days, etc., creates a time_type that represents this time interva...
Type to represent amounts of time. Implemented as seconds and days to allow for larger intervals.