gtool5 Fortran 90/95 Library 1.0.0-rc5
日本語
Loading...
Searching...
No Matches
gtvarslice.f90
Go to the documentation of this file.
1
20
63subroutine gtvarslice(var, dimord, start, count, stride)
64 use gtdata_types, only: gt_variable
67 use dc_error, only: nf90_enotvar, storeerror
69 implicit none
70 type(gt_variable), intent(in):: var
71 integer, intent(in):: dimord
72 integer, intent(in), optional:: start
73 integer, intent(in), optional:: count
74 integer, intent(in), optional:: stride
75 type(gt_dimmap), allocatable:: map(:)
76 integer:: vid, maxindex, maxcount, nd, stat
77 logical:: growable_dimension
78continue
79 call beginsub('GTVarSlice', 'var%%mapid=%d dimord=%d', &
80 & i=(/var%mapid, dimord/))
81 call gtvar_dump(var)
82 call map_lookup(var, vid=vid, ndims=nd)
83 if (vid < 0) then
84 call storeerror(nf90_enotvar, "GTVarSlice")
85 endif
86
87 if (vid > 0) then
88 call query_growable(vid, growable_dimension)
89 else
90 growable_dimension = .false.
91 endif
92
93 if (nd == 0) goto 999
94 allocate(map(nd))
95 call map_lookup(var, map=map)
96
97 if (dimord <= 0 .or. dimord > size(map)) goto 998
98
99 call dbgmessage('map(dimord): originally start=%d count=%d stride=%d', &
100 & i=(/map(dimord)%start, map(dimord)%count, map(dimord)%stride/))
101 maxindex = map(dimord)%allcount
102 if (.not. growable_dimension) then
103 call dbgmessage('maxindex=%d', i=(/maxindex/))
104 endif
105
106 if (present(start)) then
107 if (start < 0) then
108 map(dimord)%start = max(1, maxindex + 1 + start)
109 else if (growable_dimension) then
110 map(dimord)%start = max(1, start)
111 else
112 map(dimord)%start = min(maxindex, max(1, start))
113 endif
114 call dbgmessage('start=%d (%d specified)', i=(/map(dimord)%start, start/))
115 endif
116
117 if (present(stride)) then
118 map(dimord)%stride = stride
119 if (stride == 0) map(dimord)%stride = 1
120 call dbgmessage('stride=%d (%d specified)', &
121 & i=(/map(dimord)%stride, stride/))
122 endif
123
124 if (present(count)) then
125 map(dimord)%count = abs(count)
126 if (count == 0) map(dimord)%count = 1
127 call dbgmessage('count=%d (%d specified)', &
128 & i=(/map(dimord)%count, count/))
129 if (growable_dimension) then
130 maxcount = map(dimord)%start + &
131 & (map(dimord)%count - 1) * abs(map(dimord)%stride)
132 map(dimord)%allcount = max(map(dimord)%allcount, maxcount)
133 call dbgmessage('allcount=%d ', i=(/map(dimord)%allcount/))
134 end if
135 endif
136
137 if (.not. growable_dimension) then
138 maxcount = 1 + (maxindex - map(dimord)%start) / map(dimord)%stride
139 map(dimord)%count = max(1, min(maxcount, map(dimord)%count))
140 call dbgmessage('count=%d ', i=(/map(dimord)%count/))
141 endif
142 call map_set(var, map, stat)
143 if (stat /= 0) goto 998
144
145 call endsub('GTVarSlice')
146 deallocate(map)
147 return
148
149998 continue
150 deallocate(map)
151999 continue
152 call endsub('GTVarSlice', 'err skipped')
153end subroutine gtvarslice
154
209subroutine gtvarslicec(var, string, err)
210 use gtdata_types, only: gt_variable
211 use gtdata_generic, only: slice
212 use dc_trace, only: beginsub, endsub
213 use dc_url, only: gt_comma
215 type(gt_variable), intent(inout) :: var
216 character(len = *), intent(in) :: string
217 logical, intent(out) :: err
218 integer:: is, ie
219continue
220 call beginsub('GTVarSliceC', 'var=%d lim=<%c>', &
221 & i=(/var%mapid/), c1=trim(string))
222 call gtvar_dump(var)
223 ! コンマで区切って解釈
224 is = 1
225 do
226 ie = index(string(is: ), gt_comma)
227 if (ie == 0) exit
228 call limit_one(string(is: is+ie-2))
229 is = is + ie
230 if (is > len(string)) exit
231 enddo
232 call limit_one(string(is: ))
233 err = .false.
234 call endsub('GTVarSliceC')
235 return
236contains
237
238 subroutine limit_one(string)
239 use dc_url, only: gt_equal
240 use dc_string, only: strieq, stoi
242 character(len = *), intent(in):: string
243 integer:: equal, dimord
244 integer:: start, count, stride
245 logical:: myerr
246
247 if (string == '') return
248
249 if (strieq(string(1:4), "IGN:")) then
250 ! 隠蔽型指定子 ign:<dim> または ign:<dim>=<start>
251 equal = index(string, gt_equal)
252 if (equal == 0) then
253 start = 1
254 else
255 start = stoi(string(equal+1: ), default=1)
256 endif
257 dimord = dimname_to_dimord(var, string(5: equal-1))
258 call slice(var, dimord, start, 1, 1)
259 call del_dim(var, dimord, myerr)
260 return
261 endif
262
263 ! 限定型指定子 <dim>=<start>:<finish>:<stride>
264 !
265 equal = index(string, gt_equal)
266 if (equal == 0) return
267 dimord = dimname_to_dimord(var, string(1: equal-1))
268 if (dimord <= 0) return
269 !
270 call region_spec(dimord, string(equal+1: ), start, count, stride)
271 call slice(var, dimord, start, count, stride)
272 end subroutine limit_one
273
274 !
275 ! 範囲指定の = のあとを : で区切ってマップにいれる
276 !
277 subroutine region_spec(dimord, string, start, count, stride)
278 use dc_types, only: token
279 use dc_string, only: index_ofs, stoi
280 use dc_url, only: gt_circumflex, gt_colon
282 integer, intent(in):: dimord
283 integer, intent(out):: start, count, stride
284 character(len = *), intent(in):: string
285 integer:: colon, prev_colon, finish, dimlo, dimhi
286 character(len = token):: val(3)
287 continue
288 colon = index(string, gt_colon)
289 if (colon == 0) then
290 ! コロンがない場合は上下端に同じ値
291 val(1) = string(1: )
292 val(2) = val(1)
293 val(3) = ""
294 else
295 val(1) = string(1: colon - 1)
296 prev_colon = colon
297 colon = index_ofs(string, colon + 1, gt_colon)
298 if (colon > 0) then
299 val(2) = string(prev_colon + 1: colon - 1)
300 val(3) = string(colon + 1: )
301 else
302 val(2) = string(prev_colon + 1: )
303 val(3) = ""
304 endif
305 endif
306 if (val(3) == "") val(3) = "^1"
307
308 if (val(1)(1:1) == gt_circumflex) then
309 start = stoi(val(1)(2: ))
310 else if (val(1) == val(2)) then
311 start = nint(value_to_index(dimord, val(1)))
312 else
313 start = floor(value_to_index(dimord, val(1)))
314 endif
315 if (val(2) == val(1)) then
316 finish = start
317 else if (val(2)(1:1) == gt_circumflex) then
318 finish = stoi(val(2)(2: ))
319 else
320 finish = ceiling(value_to_index(dimord, val(2)))
321 endif
322
323 call dimrange(var, dimord, dimlo, dimhi)
324 start = min(max(dimlo, start), dimhi)
325 finish = min(max(dimlo, finish), dimhi)
326 count = abs(finish - start) + 1
327
328 if (val(3)(1:1) == gt_circumflex) then
329 stride = stoi(val(3)(2: ))
330 else
331 stride = stoi(val(3))
332 endif
333 stride = sign(stride, finish - start)
334 end subroutine region_spec
335
336 real function value_to_index(dimord, value) result(result)
337 !
338 ! GTVarSlice の引数 *var* に格納される変数の次元 *dimord*
339 ! に格納されるデータのうち, *value* が格納される
340 ! 格子番号を整数値にして返します.
341 !
342 ! 例えば次元に以下のデータが格納されているとします.
343 !
344 ! 0.05 0.1 0.15 0.20 0.25 0.30
345 !
346 ! この場合, *value* に 0.15 が与えられれば戻り値は 3. となります.
347 ! また *value* に 0.225 が与えられれば戻り値は 4.5 となります.
348 !
349 !
350 use gtdata_types, only: gt_variable
351 use gtdata_generic, only: get, open, close, inquire
352 use dc_string, only: stod
353 use dc_types, only: sp_eps
355 integer, intent(in):: dimord
356 character(len = *), intent(in):: value
357 type(gt_variable):: axisvar
358 real, allocatable:: axisval(:)
359 real:: val
360 integer:: i, n
361 logical:: myerr
362 continue
363 call beginsub('value_to_index', 'var=%d dimord=%d value=%c', &
364 & i=(/var%mapid, dimord/), c1=trim(value))
365
366 call open(axisvar, var, dimord, count_compact=.true., &
367 & inherit_slice=.false., err=myerr)
368 if (myerr) then
369 result = -1.0
370 return
371 endif
372 call inquire(axisvar, allcount=n)
373 allocate(axisval(n))
374 call get(axisvar, axisval, n, err=myerr)
375 call close(axisvar)
376 if (myerr) then
377 result = -1.0
378 return
379 else if (size(axisval) < 2) then
380 result = 1.0
381 goto 900
382 endif
383
384 val = real(stod(value), kind=kind(axisval))
385
386 ! call DbgMessage('value=%f axis=(/%*r/)', r=(/val, axisval(:)/), &
387 ! & n=(/size(axisval)/))
388
389 do, i = 1, size(axisval) - 1
390 if (abs(axisval(i + 1) - axisval(i)) <= sp_eps) then
391 result = real(i) + 0.5
392 goto 900
393 endif
394 result = real(i) + (val - axisval(i)) / (axisval(i + 1) - axisval(i))
395 if (result <= (i + 1)) goto 900
396 enddo
397
398900 continue
399 call endsub('value_to_index', 'value(%c) =~ index(%r)', &
400 & c1=trim(value), r=(/result/))
401 if (allocated(axisval)) then
402 deallocate(axisval)
403 endif
404 end function value_to_index
405
406end subroutine gtvarslicec
subroutine limit_one(string)
subroutine gtvarslicec(var, string, err)
subroutine gtvarslice(var, dimord, start, count, stride)
Error handling module.
Definition dc_error.f90:454
subroutine, public storeerror(number, where, err, cause_c, cause_i)
Definition dc_error.f90:891
Handling character types.
Definition dc_string.f90:83
Debug tracing module.
Definition dc_trace.f90:150
subroutine, public dbgmessage(fmt, i, r, d, l, n, c1, c2, c3, ca)
Definition dc_trace.f90:661
subroutine, public beginsub(name, fmt, i, r, d, l, n, c1, c2, c3, ca, version)
Definition dc_trace.f90:457
subroutine, public endsub(name, fmt, i, r, d, l, n, c1, c2, c3, ca)
Definition dc_trace.f90:580
Provides kind type parameter values.
Definition dc_types.f90:55
real(sp), parameter, public sp_eps
Machine epsilon for single precision real number.
Definition dc_types.f90:87
integer, parameter, public token
Character length for word, token
Definition dc_types.f90:128
Variable URL string parser.
Definition dc_url.f90:61
character, parameter, public gt_comma
Definition dc_url.f90:102
character, parameter, public gt_equal
Definition dc_url.f90:104
character, parameter, public gt_colon
Definition dc_url.f90:100
character, parameter, public gt_circumflex
Definition dc_url.f90:106
subroutine, public map_lookup(var, vid, map, ndims)
subroutine map_set(var, map, stat)
subroutine, public query_growable(vid, result)
integer function, public ndims(vid)