gtvarcreatecopy.f90
Go to the documentation of this file.
1 !
2 != 変数のコピー
3 !
4 ! Authors:: Yasuhiro MORIKAWA, Eizi TOYODA
5 ! Version:: $Id: gtvarcreatecopy.f90,v 1.1 2009-03-20 09:09:51 morikawa Exp $
6 ! Tag Name:: $Name: $
7 ! Copyright:: Copyright (C) GFD Dennou Club, 2000-2005. All rights reserved.
8 ! License:: See COPYRIGHT[link:../../COPYRIGHT]
9 !
10 ! 以下のサブルーチン, 関数は gtdata_generic から提供されます。
11 !
12 
13 subroutine gtvarcreatecopyc(var, url, copyfrom, copyvalue, &
14  & overwrite, err)
15  !
16  !== 変数のコピー
17  !
18  ! 変数 *copyfrom* と同じ次元、属性を持った変数を *url* に作成します。
19  ! 必要ならば次元変数も複製されます。
20  ! *copyvalue* を <tt>.true.</tt> に指定すると値も複製されます。
21  ! 作成された変数の ID は var に返されます。
22  !
23  ! 既存変数があるとき失敗しますが、
24  ! overwrite == .true. であれば上書きして続行します。
25  ! (まだ *overwrite* の動作は保障されていません)。
26  !
27  ! 作成の際にエラーが生じた場合、メッセージを出力してプログラムは
28  ! 強制終了します。*err* を与えてある場合にはこの引数に .true.
29  ! が返り、プログラムは終了しません。
30  !
31  !--
32  ! なお、次元変数の複製は copyfrom と url が異なるファイルに
33  ! 載っている場合に行なわれる。これは netCDF/an を想定したものだが
34  ! ほかのファイル形式が追加されたときには変更を要するかもしれない。
35  !++
36  !
37  use gtdata_types, only: gt_variable
38  use dc_types, only: string, token
40  use dc_url, only: urlsplit, gt_atmark
41  use dc_trace, only: beginsub, endsub
42  use dc_error, only: storeerror, gt_enomem
43  implicit none
44  intrinsic trim
45  type(gt_variable), intent(out) :: var
46  character(len = *), intent(in) :: url
47  type(gt_variable), intent(inout) :: copyfrom
48  logical, intent(in), optional :: copyvalue
49  logical, intent(in), optional :: overwrite
50  logical, intent(out), optional :: err
51  type(gt_variable), allocatable :: vDimSource(:)
52  type(gt_variable), allocatable :: vDimDest(:)
53  integer :: i, nd, stat
54  logical :: myerr
55  character(STRING) :: vpart, upart, desturl
56  character(TOKEN) :: xtype
57  character(len = *), parameter:: version = &
58  & '$Name: $' // &
59  & '$Id: gtvarcreatecopy.f90,v 1.1 2009-03-20 09:09:51 morikawa Exp $'
60 continue
61  call beginsub('gtvarcreatecopy', 'url=%c copyfrom=%d', &
62  & c1=trim(url), i=(/copyfrom%mapid/), version=version)
63  stat = 0
64  myerr = .false.
65  !-----------------------------------------------------------------
66  ! コピーする変数の次元をコピー先のファイルに作成
67  !-----------------------------------------------------------------
68  !----- コピー元 copyfrom の次元変数の取得 -----
69  call inquire(copyfrom, alldims=nd)
70  allocate(vdimsource(nd), vdimdest(nd), stat=stat)
71  if (stat /= 0) goto 999
72  desturl = url
73  !----- コピー元 copyfrom の各次元情報を vDimSource に取り出し, -----
74  !----- それをコピー先 desturl へコピーしてその次元 ID を -----
75  !----- vDimDest に返してもらう. -----
76  do, i = 1, nd
77  call open(vdimsource(i), copyfrom, dimord=i, &
78  & count_compact=.true., err=myerr)
79  call gtvarcopydim(to=vdimdest(i), from=vdimsource(i), &
80  & target=desturl)
81  end do
82  !-----------------------------------------------------------------
83  ! 変数作成
84  !-----------------------------------------------------------------
85  !----- url に変数名が無い場合, コピー元の変数名を使用 -----
86  call urlsplit(url, var=vpart)
87  if (vpart == "") then
88  call inquire(copyfrom, url=upart)
89  call urlsplit(upart, var=vpart)
90  desturl = trim(desturl) // gt_atmark // trim(vpart)
91  end if
92  !----- 実際に変数作成 -----
93  call inquire(copyfrom, xtype=xtype)
94  call create(var, trim(desturl), dims=vdimdest, xtype=xtype, &
95  & overwrite=overwrite, err=myerr)
96  if (myerr) goto 990
97  call copy_attr(to=var, from=copyfrom, err=myerr)
98  if (myerr) goto 990
99  if (present(copyvalue)) then
100  if (copyvalue) then
101  call gtvarcopyvalue(to=var, from=copyfrom)
102  endif
103  endif
104  do, i = 1, nd
105  call close(vdimsource(i))
106  call close(vdimdest(i))
107  end do
108 990 continue
109  deallocate(vdimsource, vdimdest, stat=stat)
110 999 continue
111  if (stat /= 0) then
112  call storeerror(gt_enomem, "GTVarCreateCopy", err)
113  else if (present(err)) then
114  err = myerr
115  else if (myerr) then
116  call dumperror
117  end if
118  call endsub('gtvarcreatecopy', 'result=%d', i=(/var%mapid/))
119 contains
120 
121  ! from と同じ内容の次元変数を URL target で示される変数の作成時に
122  ! 次元として使えるように to に複写。
123  ! なるべく再オープンで済まそうとする。
124  ! 複写する場合もなるべく次元名を合わせようとする。
125  !
126  subroutine gtvarcopydim(to, from, target)
128  use dc_types, only: token, string
129  use dc_url, only: urlsplit, urlmerge, operator(.onthesamefile.)
131  type(gt_variable), intent(out):: to
132  type(gt_variable), intent(inout):: from
133  character(len = *), intent(in):: target
134  character(len = string):: url, file, dimname
135  character(len = token):: xtype
136  logical:: growable, myerr
137  integer:: length
138  continue
139  call beginsub('gtvarcopydim', 'from=%d target=<%c>', &
140  & i=(/from%mapid/), c1=trim(target))
141  !----- 同じファイル上にコピーする場合は参照カウンタを1つ回すだけ -----
142  call inquire(var=from, url=url)
143  if (trim(url) .onthesamefile. trim(target)) then
144  call open(to, from, dimord=0)
145  call endsub('gtvarcopydim', 'dup-handle')
146  return
147  endif
148  !----- 異なるファイル上にコピーする場合, 既に次元変数 from が -----
149  !----- target の次元変数として含まれるかチェック -----
150  call urlsplit(target, file=file)
151  if (lookupequivalent(to, from, file)) then
152  !----- 含まれる場合はそれで終了 -----
153  call endsub('gtvarcopydim', 'equivalent-exists')
154  return
155  else
156  !----- 含まれない場合次元変数 from を target 上に作成 -----
157  ! 次元変数 from が無制限次元である場合には長さを 0 に
158  call inquire(var=from, growable=growable, allcount=length)
159  if (growable) length = 0
160  call inquire(var=from, xtype=xtype, name=dimname)
161  !
162  url = urlmerge(file, dimname)
163  call create(to, trim(url), length, xtype, err=myerr)
164  if (myerr) then
165  ! 指定名称でうまくいかない場合は自動生成名にする
166  call create(to, trim(file), length, xtype)
167  endif
168  call copy_attr(to, from, myerr)
169  call gtvarcopyvalue(to, from)
170  call endsub('gtvarcopydim', 'created')
171  return
172  endif
173  end subroutine gtvarcopydim
174 
175  !-----------------------------------------------------------------
176  ! ・ 次元変数 from が既に file にあるのかを判定
177  ! 次元変数 from がコピー先の nc ファイル file に既に
178  ! 存在するなら .TRUE. しないなら .FALSE. を result に返す.
179  ! result = .TRUE. が返る場合にはそれに該当する次元の ID を
180  ! to に返す.
181  ! - 判定条件は 1) from が無制限次元で, file も無制限次元を
182  ! 持つこと, または 2) 次元変数 from のサイズと一致する次元が
183  ! file 内にあり, 且つその次元の単位名が from の単位名と一致
184  ! すること.
185  ! ※ もしかすると条件が足りないかも知れない.
186  !-----------------------------------------------------------------
187  logical function lookupequivalent(to, from, file) result(result)
188  use dc_types, only: string
189  use dc_string, only: tochar
191  type(gt_variable), intent(out):: to
192  type(gt_variable), intent(in):: from
193  character(len = *), intent(in):: file
194  character(len = string):: url, units1, units2, reason
195  logical:: end, growable1, growable2
196  integer:: len1, len2
197  character(len = *), parameter:: subnam = "lookupequivalent"
198  call beginsub(subnam, 'from=%d file=<%c>', &
199  & i=(/from%mapid/), c1=trim(file))
200  result = .false.
201  !----- 次元変数 from のサイズと単位, 無制限次元かどうかを探査 -----
202  call inquire(from, allcount=len1, growable=growable1)
203  call get_attr(from, 'units', units1, default='')
204  !----- コピー先 file の変数情報を探査 -----
205  ! とりあえずは次元だけでなく全ての変数について開く
206  call gtvarsearch(file)
207  do
208  call gtvarsearch(url, end)
209  if (end) exit
210  call open(to, url, writable=.true., err=end)
211  if (end) exit
212  ! 次元変数のサイズと, 無制限次元かどうかを取得
213  ! (次元変数でないもののサイズは, 依存する次元変数のサイズを
214  ! 掛け合わせたものとなるので, もしかすると誤動作するかも).
215  call inquire(to, allcount=len2, growable=growable2)
216  ! 次元変数 from が無制限次元で, 且つ file 内の次元変数も
217  ! 無制限次元の場合は, 同じ次元変数と考える.
218  if (.not. growable1 .or. .not. growable2) then
219  ! 次元変数 from のサイズと file 内の次元変数のサイズが
220  ! 異なる場合はスキップ
221  if (len1 /= len2) then
222  call close(to)
223  cycle
224  endif
225  call get_attr(to, 'units', units2, default='')
226  ! 本当は dc_units で比較すべきだがとりあえず文字列比較
227  if (units1 /= units2) then
228  call close(to)
229  cycle
230  else
231  reason = 'length of from is ' // trim(tochar(len1)) // &
232  & '. units of from is ' // "[" // &
233  & trim(units1) // "]" // &
234  & '. And file has same length and units.'
235  endif
236  else
237  reason = 'from is UNLIMITED dimension, and file has it'
238  endif
239  result = .true.
240  call endsub(subnam, 'found (%c)', c1=trim(reason))
241  return
242  enddo
243  call endsub(subnam, 'not found')
244  end function lookupequivalent
245 
246  ! すでに存在する変数について、値をコピーする。
247  !
248  subroutine gtvarcopyvalue(to, from)
251  use dc_error, only: dumperror
252  use dc_string
253  type(gt_variable), intent(inout):: to
254  type(gt_variable), intent(inout):: from
255  real, allocatable:: rbuffer(:)
256  logical:: err
257  integer:: siz, stat
258  !
259  call beginsub('gtvarcopyvalue')
260  ! 値のコピー
261  call slice(from)
262  call slice(to, compatible=from)
263  call inquire(from, size=siz)
264  allocate (rbuffer(siz))
265  do
266  call gtvargetreal(from, rbuffer, siz, err)
267  if (err) call dumperror()
268  call gtvarputreal(to, rbuffer, siz, err)
269  if (err) call dumperror()
270  call slice_next(from, stat=stat)
271  if (stat /= 0) exit
272  call slice_next(to, stat=stat)
273  enddo
274  deallocate (rbuffer)
275  call endsub('gtvarcopyvalue')
276  end subroutine gtvarcopyvalue
277 
278 end subroutine gtvarcreatecopyc
integer, parameter, public token
単語やキーワードを保持する文字型変数の種別型パラメタ
Definition: dc_types.f90:109
logical function lookupequivalent(to, from, file)
character, parameter, public gt_atmark
Definition: dc_url.f90:79
subroutine gtvarputreal(var, value, nvalue, err)
Definition: gtvarputnum.f90:64
integer, parameter, public gt_enomem
Definition: dc_error.f90:534
subroutine, public storeerror(number, where, err, cause_c, cause_i)
Definition: dc_error.f90:830
subroutine gtvarcreatecopyc(var, url, copyfrom, copyvalue, overwrite, err)
subroutine gtvarcopydim(to, from, target)
subroutine gtvarcopyvalue(to, from)
subroutine, public beginsub(name, fmt, i, r, d, L, n, c1, c2, c3, ca, version)
Definition: dc_trace.f90:351
文字型変数の操作.
Definition: dc_string.f90:24
種別型パラメタを提供します。
Definition: dc_types.f90:49
subroutine dumperror()
Definition: dc_error.f90:942
subroutine, public endsub(name, fmt, i, r, d, L, n, c1, c2, c3, ca)
Definition: dc_trace.f90:446
subroutine gtvargetreal(var, value, nvalue, err)
Definition: gtvargetnum.f90:85
integer, parameter, public string
文字列を保持する 文字型変数の種別型パラメタ
Definition: dc_types.f90:118