module filenames 12,4 !----------------------------------------------------------------------- ! ! BOP ! ! !MODULE: filenames ! ! DESCRIPTION ! ! Module and methods to handle filenames needed for the model. This ! includes input filenames, and most output filenames that the model ! uses. All filenames that the model uses will use methods or data ! constructed by this module. In some cases (such as the cam_history module) ! other modules or routines will store the actual filenames used, but ! this module is used to determine the names. ! !----------------------------------------------------------------------- ! $Id$ !----------------------------------------------------------------------- use time_manager, only: get_curr_date, get_prev_date use shr_kind_mod, only: shr_kind_cs, shr_kind_cl use abortutils, only: endrun use cam_logfile, only: iulog implicit none ! ! !PUBLIC MEMBER FUNCTIONS ! public get_dir ! Get the directory name from a full path public interpret_filename_spec ! Interpret a filename specifier ! ! !PUBLIC DATA MEMBERS: ! ! Note: Only make data needed for namelist public, everything else should be private. ! ! Input datasets ! character(shr_kind_cl), public :: ncdata = 'ncdata' ! full pathname for initial dataset character(shr_kind_cl), public :: bnd_topo = 'bnd_topo' ! full pathname for topography dataset character(shr_kind_cl), public :: absems_data = 'absems_data' ! full pathname for time-invariant absorption dataset character(shr_kind_cl), public :: modal_optics = 'modal_optics' ! full pathname for time-invariant modal optics dataset character(shr_kind_cl), public :: isccpdata = 'isccpdata' ! full pathname for ISCCP input data character(shr_kind_cs), public :: caseid = ' ' ! Case identifier logical, public :: brnch_retain_casename = .false. !----------------------------------------------------------------------- ! EOP !----------------------------------------------------------------------- ! ! Private data used for filenames ! PRIVATE integer, parameter :: nlen = shr_kind_cl ! String length CONTAINS !----------------------------------------------------------------------- ! BOP ! ! !ROUTINE: get_dir ! ! !DESCRIPTION: Return the directory from a filename with a full path ! !----------------------------------------------------------------------- ! !INTERFACE: character(len=nlen) function get_dir( filepath ) 1 ! ! !PARAMETERS: ! character(len=*), intent(in) :: filepath ! Full path for a filename ! ! EOP ! integer :: filenameposition ! Character position for last character of directory ! Get the directory name of the input dataset filenameposition = index( filepath, '/', back=.true. ) if ( filenameposition == 0 )then get_dir = './' else get_dir = filepath(1:filenameposition) end if end function get_dir !----------------------------------------------------------------------- ! BOP ! ! !ROUTINE: interpret_filename_spec ! ! !DESCRIPTION: Create a filename from a filename specifyer. The ! filename specifyer includes codes for setting things such as the ! year, month, day, seconds in day, caseid, and tape number. This ! routine is private to filenames.F90 ! ! Interpret filename specifyer string with: ! ! %c for case, ! %t for optional number argument sent into function ! %y for year ! %m for month ! %d for day ! %s for second ! %% for the "%" character ! ! If the filename specifyer has spaces " ", they will be trimmed out ! of the resulting filename. ! !----------------------------------------------------------------------- ! !INTERFACE: character(len=nlen) function interpret_filename_spec( filename_spec, number, prev, case, & 7,9 yr_spec, mon_spec, day_spec, sec_spec ) ! ! !PARAMETERS: ! character(len=*), intent(in) :: filename_spec ! Filename specifier to use integer , intent(in), optional :: number ! Number to use for %t field logical , intent(in), optional :: prev ! If should label with previous time-step character(len=*), intent(in), optional :: case ! Optional casename integer , intent(in), optional :: yr_spec ! Simulation year integer , intent(in), optional :: mon_spec ! Simulation month integer , intent(in), optional :: day_spec ! Simulation day integer , intent(in), optional :: sec_spec ! Seconds into current simulation day ! ! EOP ! integer :: year ! Simulation year integer :: month ! Simulation month integer :: day ! Simulation day integer :: ncsec ! Seconds into current simulation day character(len=nlen) :: string ! Temporary character string character(len=nlen) :: format ! Format character string integer :: i, n ! Loop variables logical :: previous ! If should label with previous time-step logical :: done if ( len_trim(filename_spec) == 0 )then call endrun ('INTERPRET_FILENAME_SPEC: filename specifier is empty') end if if ( index(trim(filename_spec)," ") /= 0 )then call endrun ('INTERPRET_FILENAME_SPEC: filename specifier can not contain a space:'//trim(filename_spec)) end if ! ! Determine year, month, day and sec to put in filename ! if (present(yr_spec) .and. present(mon_spec) .and. present(day_spec) .and. present(sec_spec)) then year = yr_spec month = mon_spec day = day_spec ncsec = sec_spec else if ( .not. present(prev) ) then previous = .false. else previous = prev end if if ( previous ) then call get_prev_date(year, month, day, ncsec) else call get_curr_date(year, month, day, ncsec) end if end if ! ! Go through each character in the filename specifyer and interpret if special string ! i = 1 interpret_filename_spec = '' do while ( i <= len_trim(filename_spec) ) ! ! If following is an expansion string ! if ( filename_spec(i:i) == "%" )then i = i + 1 select case( filename_spec(i:i) ) case( 'c' ) ! caseid if ( present(case) )then string = trim(case) else string = trim(caseid) end if case( 't' ) ! number if ( .not. present(number) )then write(iulog,*) 'INTERPRET_FILENAME_SPEC: number needed in filename_spec' & , ', but not provided to subroutine' write(iulog,*) 'filename_spec = ', filename_spec call endrun end if if ( number > 999 ) then format = '(i4.4)' if ( number > 9999 ) then write(iulog,*) 'INTERPRET_FILENAME_SPEC: number is too large: ', number call endrun end if else if ( number > 99 ) then format = '(i3.3)' else if ( number > 9 ) then format = '(i2.2)' else format = '(i1.1)' end if write(string,format) number case( 'y' ) ! year if ( year > 99999 ) then format = '(i6.6)' else if ( year > 9999 ) then format = '(i5.5)' else format = '(i4.4)' end if write(string,format) year case( 'm' ) ! month write(string,'(i2.2)') month case( 'd' ) ! day write(string,'(i2.2)') day case( 's' ) ! second write(string,'(i5.5)') ncsec case( '%' ) ! percent character string = "%" case default call endrun ('INTERPRET_FILENAME_SPEC: Invalid expansion character: '//filename_spec(i:i)) end select ! ! Otherwise take normal text up to the next "%" character ! else n = index( filename_spec(i:), "%" ) if ( n == 0 ) n = len_trim( filename_spec(i:) ) + 1 if ( n == 0 ) exit string = filename_spec(i:n+i-2) i = n + i - 2 end if if ( len_trim(interpret_filename_spec) == 0 )then interpret_filename_spec = trim(string) else if ( (len_trim(interpret_filename_spec)+len_trim(string)) >= nlen )then call endrun ('INTERPRET_FILENAME_SPEC: Resultant filename too long') end if interpret_filename_spec = trim(interpret_filename_spec) // trim(string) end if i = i + 1 end do if ( len_trim(interpret_filename_spec) == 0 )then call endrun ('INTERPRET_FILENAME_SPEC: Resulting filename is empty') end if end function interpret_filename_spec end module filenames