Line data Source code
1 : module filenames
2 :
3 : ! Module and methods to handle filenames needed for the model. This
4 : ! includes input filenames, and most output filenames that the model
5 : ! uses. All filenames that the model uses will use methods or data
6 : ! constructed by this module. In some cases (such as the cam_history module)
7 : ! other modules or routines will store the actual filenames used, but
8 : ! this module is used to determine the names.
9 :
10 : use time_manager, only: get_curr_date, get_prev_date
11 : use shr_kind_mod, only: cl=>shr_kind_cl
12 : use cam_control_mod, only: caseid
13 : use cam_abortutils, only: endrun
14 : use cam_logfile, only: iulog
15 :
16 : implicit none
17 : private
18 : save
19 :
20 : public get_dir ! Get the directory name from a full path
21 : public interpret_filename_spec ! Interpret a filename specifier
22 :
23 : !===============================================================================
24 : CONTAINS
25 : !===============================================================================
26 :
27 768 : character(len=cl) function get_dir( filepath )
28 :
29 : ! Return the directory from a filename with a full path
30 :
31 : ! arguments
32 : character(len=*), intent(in) :: filepath ! Full path for a filename
33 :
34 : ! local variables
35 : integer :: filenameposition ! Character position for last character of directory
36 : !-----------------------------------------------------------------------------
37 :
38 : ! Get the directory name of the input dataset
39 768 : filenameposition = index( filepath, '/', back=.true. )
40 768 : if ( filenameposition == 0 )then
41 768 : get_dir = './'
42 : else
43 0 : get_dir = filepath(1:filenameposition)
44 : end if
45 :
46 768 : end function get_dir
47 :
48 : !===============================================================================
49 :
50 249600 : character(len=cl) function interpret_filename_spec( filename_spec, number, prev, case, &
51 : yr_spec, mon_spec, day_spec, sec_spec, flag_spec )
52 :
53 : ! Create a filename from a filename specifier. The
54 : ! filename specifyer includes codes for setting things such as the
55 : ! year, month, day, seconds in day, caseid, and tape number. This
56 : ! routine is private to filenames.F90
57 : !
58 : ! Interpret filename specifyer string with:
59 : !
60 : ! %c for case,
61 : ! %t for optional number argument sent into function
62 : ! %y for year
63 : ! %m for month
64 : ! %d for day
65 : ! %s for second
66 : ! %% for the "%" character
67 : !
68 : ! If the filename specifyer has spaces " ", they will be trimmed out
69 : ! of the resulting filename.
70 :
71 : ! arguments
72 : character(len=*), intent(in) :: filename_spec ! Filename specifier to use
73 : integer , intent(in), optional :: number ! Number to use for %t field
74 : logical , intent(in), optional :: prev ! If should label with previous time-step
75 : character(len=*), intent(in), optional :: case ! Optional casename
76 : integer , intent(in), optional :: yr_spec ! Simulation year
77 : integer , intent(in), optional :: mon_spec ! Simulation month
78 : integer , intent(in), optional :: day_spec ! Simulation day
79 : integer , intent(in), optional :: sec_spec ! Seconds into current simulation day
80 : character(len=*), intent(in), optional :: flag_spec ! flag for accumulated or instantaneous
81 :
82 : ! Local variables
83 : integer :: year ! Simulation year
84 : integer :: month ! Simulation month
85 : integer :: day ! Simulation day
86 : integer :: ncsec ! Seconds into current simulation day
87 : character(len=1) :: flag
88 : character(len=cl) :: string ! Temporary character string
89 : character(len=cl) :: format ! Format character string
90 : integer :: i, n ! Loop variables
91 : logical :: previous ! If should label with previous time-step
92 : logical :: done
93 : !-----------------------------------------------------------------------------
94 :
95 249600 : if ( len_trim(filename_spec) == 0 )then
96 0 : call endrun ('INTERPRET_FILENAME_SPEC: filename specifier is empty')
97 : end if
98 249600 : if ( index(trim(filename_spec)," ") /= 0 )then
99 0 : call endrun ('INTERPRET_FILENAME_SPEC: filename specifier can not contain a space:'//trim(filename_spec))
100 : end if
101 : !
102 : ! Determine year, month, day and sec to put in filename
103 : !
104 249600 : if (present(yr_spec) .and. present(mon_spec) .and. present(day_spec) .and. present(sec_spec)) then
105 3840 : year = yr_spec
106 3840 : month = mon_spec
107 3840 : day = day_spec
108 3840 : ncsec = sec_spec
109 : else
110 245760 : if ( .not. present(prev) ) then
111 : previous = .false.
112 : else
113 245760 : previous = prev
114 : end if
115 245760 : if ( previous ) then
116 0 : call get_prev_date(year, month, day, ncsec)
117 : else
118 245760 : call get_curr_date(year, month, day, ncsec)
119 : end if
120 : end if
121 249600 : if (present(flag_spec)) then
122 245760 : flag = flag_spec
123 : else
124 3840 : flag = ''
125 : end if
126 : !
127 : ! Go through each character in the filename specifyer and interpret if special string
128 : !
129 249600 : i = 1
130 249600 : interpret_filename_spec = ''
131 3482880 : do while ( i <= len_trim(filename_spec) )
132 : !
133 : ! If following is an expansion string
134 : !
135 3233280 : if ( filename_spec(i:i) == "%" )then
136 1739520 : i = i + 1
137 1739520 : select case( filename_spec(i:i) )
138 : case( 'c' ) ! caseid
139 249600 : if ( present(case) )then
140 768 : string = trim(case)
141 : else
142 248832 : string = trim(caseid)
143 : end if
144 : case( 't' ) ! number
145 245760 : if ( .not. present(number) )then
146 0 : write(iulog,*) 'INTERPRET_FILENAME_SPEC: number needed in filename_spec' &
147 0 : , ', but not provided to subroutine'
148 0 : write(iulog,*) 'filename_spec = ', filename_spec
149 0 : call endrun
150 : end if
151 245760 : if ( number > 999 ) then
152 0 : format = '(i4.4)'
153 0 : if ( number > 9999 ) then
154 0 : write(iulog,*) 'INTERPRET_FILENAME_SPEC: number is too large: ', number
155 0 : call endrun
156 : end if
157 245760 : else if ( number > 99 ) then
158 0 : format = '(i3.3)'
159 245760 : else if ( number > 9 ) then
160 0 : format = '(i2.2)'
161 : else
162 245760 : format = '(i1.1)'
163 : end if
164 245760 : write(string,format) number
165 : case( 'y' ) ! year
166 249600 : if ( year > 99999 ) then
167 0 : format = '(i6.6)'
168 249600 : else if ( year > 9999 ) then
169 0 : format = '(i5.5)'
170 : else
171 249600 : format = '(i4.4)'
172 : end if
173 249600 : write(string,format) year
174 : case( 'm' ) ! month
175 249600 : write(string,'(i2.2)') month
176 : case( 'd' ) ! day
177 249600 : write(string,'(i2.2)') day
178 : case( 's' ) ! second
179 249600 : write(string,'(i5.5)') ncsec
180 : case( 'f' ) ! flag
181 245760 : write(string,'(a)') flag
182 : case( '%' ) ! percent character
183 0 : string = "%"
184 : case default
185 1739520 : call endrun ('INTERPRET_FILENAME_SPEC: Invalid expansion character: '//filename_spec(i:i))
186 : end select
187 : !
188 : ! Otherwise take normal text up to the next "%" character
189 : !
190 : else
191 1493760 : n = index( filename_spec(i:), "%" )
192 1493760 : if ( n == 0 ) n = len_trim( filename_spec(i:) ) + 1
193 249600 : if ( n == 0 ) exit
194 1493760 : string = filename_spec(i:n+i-2)
195 : i = n + i - 2
196 : end if
197 3233280 : if ( len_trim(interpret_filename_spec) == 0 )then
198 249600 : interpret_filename_spec = trim(string)
199 : else
200 2983680 : if ( (len_trim(interpret_filename_spec)+len_trim(string)) >= cl )then
201 0 : call endrun ('INTERPRET_FILENAME_SPEC: Resultant filename too long')
202 : end if
203 2983680 : interpret_filename_spec = trim(interpret_filename_spec) // trim(string)
204 : end if
205 3233280 : i = i + 1
206 :
207 : end do
208 249600 : if ( len_trim(interpret_filename_spec) == 0 )then
209 0 : call endrun ('INTERPRET_FILENAME_SPEC: Resulting filename is empty')
210 : end if
211 :
212 249600 : end function interpret_filename_spec
213 :
214 : end module filenames
|