gtool5 Fortran 90/95 Library 1.0.0-rc5
日本語
Loading...
Searching...
No Matches
gtvarcreatecopy.f90
Go to the documentation of this file.
1!> @file gtvarcreatecopy.f90
2!>
3!> @author Yasuhiro MORIKAWA, Eizi TOYODA
4!> @copyright Copyright (C) GFD Dennou Club, 2000-2026. All rights reserved. <br/>
5!> License is BSD-2-Clause. See [COPYRIGHT](@ref COPYRIGHT) in detail
6!>
7!> @en
8!> @brief Copy variable
9!>
10!> This subroutine is provided through gtdata_generic.
11!> @enden
12!>
13!> @ja
14!> @brief 変数のコピー
15!>
16!> このサブルーチンは gtdata_generic から提供されます。
17!> @endja
18!>
19
20!>
21!> @en
22!> @brief Create a copy of a variable
23!>
24!> Creates a variable at url with the same dimensions and attributes
25!> as copyfrom. Dimension variables are also duplicated if necessary.
26!> If copyvalue is set to .true., values are also duplicated.
27!> The created variable's ID is returned in var.
28!>
29!> Creation fails if the variable already exists, but continues by
30!> overwriting if overwrite == .true..
31!> (Note: overwrite behavior is not yet guaranteed.)
32!>
33!> If an error occurs during creation, outputs a message and terminates.
34!> If err is provided, returns .true. and program does not terminate.
35!>
36!> @note Dimension variable duplication is performed when copyfrom and
37!> url are in different files. This is designed for netCDF/an
38!> and may need changes when other file formats are added.
39!> @param[out] var Variable handle
40!> @param[in] url Destination URL
41!> @param[inout] copyfrom Source variable
42!> @param[in] copyvalue Copy values too (optional)
43!> @param[in] overwrite Allow overwrite (optional)
44!> @param[out] err Error flag (optional)
45!> @enden
46!>
47!> @ja
48!> @brief 変数のコピーを作成
49!>
50!> 変数 copyfrom と同じ次元、属性を持った変数を url に作成します。
51!> 必要ならば次元変数も複製されます。
52!> copyvalue を .true. に指定すると値も複製されます。
53!> 作成された変数の ID は var に返されます。
54!>
55!> 既存変数があるとき失敗しますが、overwrite == .true. であれば
56!> 上書きして続行します。(まだ overwrite の動作は保障されていません)。
57!>
58!> 作成の際にエラーが生じた場合、メッセージを出力してプログラムは
59!> 強制終了します。err を与えてある場合にはこの引数に .true.
60!> が返り、プログラムは終了しません。
61!>
62!> @note 次元変数の複製は copyfrom と url が異なるファイルに載っている
63!> 場合に行なわれる。これは netCDF/an を想定したものだが
64!> ほかのファイル形式が追加されたときには変更を要するかもしれない。
65!> @param[out] var 変数ハンドル
66!> @param[in] url コピー先URL
67!> @param[inout] copyfrom コピー元変数
68!> @param[in] copyvalue 値もコピー (省略可能)
69!> @param[in] overwrite 上書き許可 (省略可能)
70!> @param[out] err エラーフラグ (省略可能)
71!> @endja
72!>
73subroutine gtvarcreatecopyc(var, url, copyfrom, copyvalue, &
74 & overwrite, err)
75 use gtdata_types, only: gt_variable
76 use dc_types, only: string, token
78 use dc_url, only: urlsplit, gt_atmark
79 use dc_trace, only: beginsub, endsub
80 use dc_error, only: storeerror, gt_enomem
81 implicit none
82 intrinsic trim
83 type(gt_variable), intent(out) :: var
84 character(len = *), intent(in) :: url
85 type(gt_variable), intent(inout) :: copyfrom
86 logical, intent(in), optional :: copyvalue
87 logical, intent(in), optional :: overwrite
88 logical, intent(out), optional :: err
89 type(gt_variable), allocatable :: vDimSource(:)
90 type(gt_variable), allocatable :: vDimDest(:)
91 integer :: i, nd, stat
92 logical :: myerr
93 character(STRING) :: vpart, upart, desturl
94 character(TOKEN) :: xtype
95 character(len = *), parameter:: version = &
96 & '$Name: $' // &
97 & '$Id: gtvarcreatecopy.f90,v 1.1 2009-03-20 09:09:51 morikawa Exp $'
98continue
99 call beginsub('gtvarcreatecopy', 'url=%c copyfrom=%d', &
100 & c1=trim(url), i=(/copyfrom%mapid/), version=version)
101 stat = 0
102 myerr = .false.
103 !-----------------------------------------------------------------
104 ! コピーする変数の次元をコピー先のファイルに作成
105 !-----------------------------------------------------------------
106 !----- コピー元 copyfrom の次元変数の取得 -----
107 call inquire(copyfrom, alldims=nd)
108 allocate(vdimsource(nd), vdimdest(nd), stat=stat)
109 if (stat /= 0) goto 999
110 desturl = url
111 !----- コピー元 copyfrom の各次元情報を vDimSource に取り出し, -----
112 !----- それをコピー先 desturl へコピーしてその次元 ID を -----
113 !----- vDimDest に返してもらう. -----
114 do, i = 1, nd
115 call open(vdimsource(i), copyfrom, dimord=i, &
116 & count_compact=.true., err=myerr)
117 call gtvarcopydim(to=vdimdest(i), from=vdimsource(i), &
118 & target=desturl)
119 end do
120 !-----------------------------------------------------------------
121 ! 変数作成
122 !-----------------------------------------------------------------
123 !----- url に変数名が無い場合, コピー元の変数名を使用 -----
124 call urlsplit(url, var=vpart)
125 if (vpart == "") then
126 call inquire(copyfrom, url=upart)
127 call urlsplit(upart, var=vpart)
128 desturl = trim(desturl) // gt_atmark // trim(vpart)
129 end if
130 !----- 実際に変数作成 -----
131 call inquire(copyfrom, xtype=xtype)
132 call create(var, trim(desturl), dims=vdimdest, xtype=xtype, &
133 & overwrite=overwrite, err=myerr)
134 if (myerr) goto 990
135 call copy_attr(to=var, from=copyfrom, err=myerr)
136 if (myerr) goto 990
137 if (present(copyvalue)) then
138 if (copyvalue) then
139 call gtvarcopyvalue(to=var, from=copyfrom)
140 endif
141 endif
142 do, i = 1, nd
143 call close(vdimsource(i))
144 call close(vdimdest(i))
145 end do
146990 continue
147 deallocate(vdimsource, vdimdest, stat=stat)
148999 continue
149 if (stat /= 0) then
150 call storeerror(gt_enomem, "GTVarCreateCopy", err)
151 else if (present(err)) then
152 err = myerr
153 else if (myerr) then
154 call dumperror
155 end if
156 call endsub('gtvarcreatecopy', 'result=%d', i=(/var%mapid/))
157contains
158
159 ! from と同じ内容の次元変数を URL target で示される変数の作成時に
160 ! 次元として使えるように to に複写。
161 ! なるべく再オープンで済まそうとする。
162 ! 複写する場合もなるべく次元名を合わせようとする。
163 !
164 subroutine gtvarcopydim(to, from, target)
165 use gtdata_types
166 use dc_types, only: token, string
167 use dc_url, only: urlsplit, urlmerge, operator(.onthesamefile.)
169 type(gt_variable), intent(out):: to
170 type(gt_variable), intent(inout):: from
171 character(len = *), intent(in):: target
172 character(len = string):: url, file, dimname
173 character(len = token):: xtype
174 logical:: growable, myerr
175 integer:: length
176 continue
177 call beginsub('gtvarcopydim', 'from=%d target=<%c>', &
178 & i=(/from%mapid/), c1=trim(target))
179 !----- 同じファイル上にコピーする場合は参照カウンタを1つ回すだけ -----
180 call inquire(var=from, url=url)
181 if (trim(url) .onthesamefile. trim(target)) then
182 call open(to, from, dimord=0)
183 call endsub('gtvarcopydim', 'dup-handle')
184 return
185 endif
186 !----- 異なるファイル上にコピーする場合, 既に次元変数 from が -----
187 !----- target の次元変数として含まれるかチェック -----
188 call urlsplit(target, file=file)
189 if (lookupequivalent(to, from, file)) then
190 !----- 含まれる場合はそれで終了 -----
191 call endsub('gtvarcopydim', 'equivalent-exists')
192 return
193 else
194 !----- 含まれない場合次元変数 from を target 上に作成 -----
195 ! 次元変数 from が無制限次元である場合には長さを 0 に
196 call inquire(var=from, growable=growable, allcount=length)
197 if (growable) length = 0
198 call inquire(var=from, xtype=xtype, name=dimname)
199 !
200 url = urlmerge(file, dimname)
201 call create(to, trim(url), length, xtype, err=myerr)
202 if (myerr) then
203 ! 指定名称でうまくいかない場合は自動生成名にする
204 call create(to, trim(file), length, xtype)
205 endif
206 call copy_attr(to, from, myerr)
207 call gtvarcopyvalue(to, from)
208 call endsub('gtvarcopydim', 'created')
209 return
210 endif
211 end subroutine gtvarcopydim
212
213 !-----------------------------------------------------------------
214 ! ・ 次元変数 from が既に file にあるのかを判定
215 ! 次元変数 from がコピー先の nc ファイル file に既に
216 ! 存在するなら .TRUE. しないなら .FALSE. を result に返す.
217 ! result = .TRUE. が返る場合にはそれに該当する次元の ID を
218 ! to に返す.
219 ! - 判定条件は 1) from が無制限次元で, file も無制限次元を
220 ! 持つこと, または 2) 次元変数 from のサイズと一致する次元が
221 ! file 内にあり, 且つその次元の単位名が from の単位名と一致
222 ! すること.
223 ! ※ もしかすると条件が足りないかも知れない.
224 !-----------------------------------------------------------------
225 logical function lookupequivalent(to, from, file) result(result)
226 use dc_types, only: string
227 use dc_string, only: tochar
229 type(gt_variable), intent(out):: to
230 type(gt_variable), intent(in):: from
231 character(len = *), intent(in):: file
232 character(len = string):: url, units1, units2, reason
233 logical:: end, growable1, growable2
234 integer:: len1, len2
235 character(len = *), parameter:: subnam = "lookupequivalent"
236 call beginsub(subnam, 'from=%d file=<%c>', &
237 & i=(/from%mapid/), c1=trim(file))
238 result = .false.
239 !----- 次元変数 from のサイズと単位, 無制限次元かどうかを探査 -----
240 call inquire(from, allcount=len1, growable=growable1)
241 call get_attr(from, 'units', units1, default='')
242 !----- コピー先 file の変数情報を探査 -----
243 ! とりあえずは次元だけでなく全ての変数について開く
244 call gtvarsearch(file)
245 do
246 call gtvarsearch(url, end)
247 if (end) exit
248 call open(to, url, writable=.true., err=end)
249 if (end) exit
250 ! 次元変数のサイズと, 無制限次元かどうかを取得
251 ! (次元変数でないもののサイズは, 依存する次元変数のサイズを
252 ! 掛け合わせたものとなるので, もしかすると誤動作するかも).
253 call inquire(to, allcount=len2, growable=growable2)
254 ! 次元変数 from が無制限次元で, 且つ file 内の次元変数も
255 ! 無制限次元の場合は, 同じ次元変数と考える.
256 if (.not. growable1 .or. .not. growable2) then
257 ! 次元変数 from のサイズと file 内の次元変数のサイズが
258 ! 異なる場合はスキップ
259 if (len1 /= len2) then
260 call close(to)
261 cycle
262 endif
263 call get_attr(to, 'units', units2, default='')
264 ! 本当は dc_units で比較すべきだがとりあえず文字列比較
265 if (units1 /= units2) then
266 call close(to)
267 cycle
268 else
269 reason = 'length of from is ' // trim(tochar(len1)) // &
270 & '. units of from is ' // "[" // &
271 & trim(units1) // "]" // &
272 & '. And file has same length and units.'
273 endif
274 else
275 reason = 'from is UNLIMITED dimension, and file has it'
276 endif
277 result = .true.
278 call endsub(subnam, 'found (%c)', c1=trim(reason))
279 return
280 enddo
281 call endsub(subnam, 'not found')
282 end function lookupequivalent
283
284 ! すでに存在する変数について、値をコピーする。
285 !
286 subroutine gtvarcopyvalue(to, from)
287 use gtdata_types, only: gt_variable
289 use dc_error, only: dumperror
290 use dc_string
291 type(gt_variable), intent(inout):: to
292 type(gt_variable), intent(inout):: from
293 real, allocatable:: rbuffer(:)
294 logical:: err
295 integer:: siz, stat
296 !
297 call beginsub('gtvarcopyvalue')
298 ! 値のコピー
299 call slice(from)
300 call slice(to, compatible=from)
301 call inquire(from, size=siz)
302 allocate (rbuffer(siz))
303 do
304 call gtvargetreal(from, rbuffer, siz, err)
305 if (err) call dumperror()
306 call gtvarputreal(to, rbuffer, siz, err)
307 if (err) call dumperror()
308 call slice_next(from, stat=stat)
309 if (stat /= 0) exit
310 call slice_next(to, stat=stat)
311 enddo
312 deallocate (rbuffer)
313 call endsub('gtvarcopyvalue')
314 end subroutine gtvarcopyvalue
315
316end subroutine gtvarcreatecopyc
subroutine gtvarcreatecopyc(var, url, copyfrom, copyvalue, overwrite, err)
subroutine gtvarcopydim(to, from, target)
subroutine gtvargetreal(var, value, nvalue, err)
subroutine gtvarputreal(var, value, nvalue, err)
Procedure reference specification. Made as an external function to be replaceable in the future.
Definition dc_error.f90:592
Error handling module.
Definition dc_error.f90:454
subroutine, public storeerror(number, where, err, cause_c, cause_i)
Definition dc_error.f90:891
integer, parameter, public gt_enomem
Definition dc_error.f90:513
Handling character types.
Definition dc_string.f90:83
Debug tracing module.
Definition dc_trace.f90:150
subroutine, public beginsub(name, fmt, i, r, d, l, n, c1, c2, c3, ca, version)
Definition dc_trace.f90:476
subroutine, public endsub(name, fmt, i, r, d, l, n, c1, c2, c3, ca)
Definition dc_trace.f90:599
Provides kind type parameter values.
Definition dc_types.f90:55
integer, parameter, public token
Character length for word, token
Definition dc_types.f90:128
integer, parameter, public string
Character length for string
Definition dc_types.f90:137
Variable URL string parser.
Definition dc_url.f90:61
character, parameter, public gt_atmark
Definition dc_url.f90:96