[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[dennou-ruby:001790] Re: GrADS_Gridded#each_att



水田さま(&西澤さま)

堀之内です。

gave で GrADS が開けなくなったという問題ですが、返事が遅くなって
すみません。

問題はちと根が深いです。VArrayを経由する配列データに関しては、デー
タ形式が隠蔽出来てるように思いますが、引っ掛かったのは個々の配列
でなく、ファイル内共通のグローバル属性です。gave は問題の箇所で、
グローバル属性を得るべく、NetCDFの場合にうまく行くやり方で、ファ
イルオブジェクトに直接問合わせています。NetCDFに限らず、グローバ
ルな属性が発生することは自然ではありますが、ファイルオブジェクト
に直接問合わせることでVArray-->GPhys の、データ形式隠蔽が破れて
しまいます。ファイルから直接取得するグローバル属性は、GPhys 内の
自動処理とは関係ないので、もっぱら読んで参考にするための文字情報
となると思います。gave でも、単にリストを出せるようにしているだ
けです。とは言え、一般に参考になる情報が書いてあると分かっている
のですから、読めるようにしたほうがいいのは確かです。

一つの解決方法は、諸々の自己記述型ファイル形式取り扱いクラスで、
グローバル属性の扱いを統一することです。指摘されたように、GPhys 
や GrADS_Gridded で採用している Hash 的な属性を、 NetCDF に合わ
せる(一個一個の属性をオブジェクト化する)のは相性が悪いです。一
方、逆に NetCDF に Hash 的属性用と同じインターフェースを作るのは
簡単です。ただ、ちょっと美しくない。。。

そこで、提案です。

* gave に関して > 西澤さま

  下に書くように、実は GrADS_Gridded はグローバル属性用インター
  フェースをまだ持ってませんので、現状では対応できません。そこ
  で、応急処置として、

  gave(現在のCVS版):l.1008:
            f.each_att{|att|
              val = att.get
              if val.class==NArray then
                val = att.get.to_a.join(",")
              end
              attr_list.set_item(att.name, val)
            }
  を

         if( f.respond_to?(:each_att) )
         end

  でくるんで貰えないでしょうか。
   
* GrADS_Gridded に関して > 水田さま

  ファイル内の変数である GrADS_Var には、natts, att_names,
  att(name) がありますが、GrADS 形式の格子点データセット全体を代表
  する GrADS_Gridded には書き込み用の put_att しかありません。つま
  りグローバル属性が読めないことになってます。すみませんが作って
  頂けると嬉しいです。個々の変数を読むために必要な欠損値やらエンディ
  アンやらの情報は、各変数を通して適切に処理されるわけですから
  グローバル属性にしなくていいと思います。すると、残るのは、"dset",
  "title" ぐらいでしょうか。その場合は、natts, att_names の帰り値
  は固定的に 2, ["dset", "title"] ということになりますね。

  合わせてお願いがあります。GrADS_Var では読み込みメソッドが
  att(name) となってますが、put_att(name,val) との名前の釣り合い
  を考えて、get_att(name) に変えて貰えないでしょうか
  (GrADS_Var, GrADS_Gridded 共通で)。これで NetCDF#att との
  紛らわしさも減りますし。つまり、属性関連メソッドのフルセットは、
  natts, att_names, get_att(name), put_att(name,val) です。

  あとは、NetCDF にもそういうインターフェースを私が取り付けるか
  どうかどうかですね。そうしない場合は上の if 節に else か elsif 
  を入れて対応することになります。いずれにしろ新しいケースへの
  対応は簡単で、上で

            f.each_att{|att|
              val = att.get

  となってる部分を、以下のようにするだけ。

            f.att_names.each{|name|
              val = f.get_att(name)


> 水田です。
> 
> > > (現在の) gave で GrADS ファイルを開こうとすると次のようなエラー
> > > がでます。
> > > 
> > > undefined method `each_att' for #<GrADS_Gridded:0x410dc5b8>
> > > /usr/local/bin/gave:1000:in `file_open'
> > > /usr/local/bin/gave:662:in `initialize'
> > > /usr/local/bin/gave:662:in `call'
> > > /usr/local/bin/gave:263:in `initialize'
> > > /usr/local/bin/gave:261:in `call'
> > > /usr/local/bin/gave:1455:in `main'
> > > /usr/local/bin/gave:1455:in `start'
> > > /usr/local/bin/gave:1481
> > > 
> > > GrADS_Gridded に each_att がないと撥られるわけです。
> > > あったほうがいいのは確かなので、すみませんが作って
> > > いただけると嬉しいです。
> 
> NetCDF の each_att などは NetCDFAtt クラスを返すわけですが、
> それに対応して GrADSAtt みたいなクラスを作ったほうがいいのでしょうか?
> 現状では属性関連の部分は Attribute クラスを使ってますので
> この手のメソッドではそれをやめてそういうクラスを作らないと NetCDF と 
> GrADS で異なった動作になってしまいます。
> 
> gave側で違いを吸収してもらって、NetCDFAttが返ってきてもAttributeが返って
> きてもいいようにしてもらうっていう手もありますが。。