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