Help us understand the problem. What is going on with this article?

rubyistがpycallでpython::Dictデータで苦労した話

rubyistがpycallでpython::Dictデータで苦労した話

PyCall Ruby版
Tips
にほぼ完璧な対応報告がある.
さらに,numpy特有の記法

# 最後の行へのアクセス pythonだと m[-1,:] と書くところ

などと,rubyistにわかりやるいnumpyの解説まで付いている.

という風に簡単にできそうに見える...

複雑なデータ構造だとお手上げ

ところが,複雑なpythonのデータ構造を扱う時には
非常に苦労する.原因はdictのkeyがよくわからないから.
単純な文字を取る時にはいいが,少し複雑な文字ではうまく取れないようだ.

以下の通りにしてpymatgenにあるVasprun::tdosあるいは
Vasprun::compolete_dos などが取れる.

ところが,

p spd_dos = dosrun.complete_dos.get_spd_dos() とすると,

{<OrbitalType.s: 0>: <pymatgen.electronic_structure.dos.Dos
object at 0x102dd4710>, <OrbitalType.p: 1>:
<pymatgen.electronic_structure.dos.Dos object at 0x102dc2dd8>,
<OrbitalType.d: 2>: <pymatgen.electronic_structure.dos.Dos
object at 0x102d962b0>}

と出力される.これはspd_dos('OrbitalType.s')で取れそうに思うが
だめ.そこで,

p s_d = spd_dos.to_a[0][1].densities

として

array([  0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
         0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
...
      ])

python::arrayにして,さらに

s_list = PyCall::List.(s_d.to_a[0][1]).to_a

としてhashをarrayにしてvalsを取り出し,さらにそれをto_aでrubyが解釈できるdata構造に変換している.

慣れると同じcodeの繰り返しなんでそれほど苦労しなくなるが,
多分時間が経てば忘れるね.
そこをlibに組み込んで欲しいが,dictを直接読むのは文字だけのよう...
code書いて,pull reqかけてみるか.

densitiesやenergyはnameがわからないとどうしようもなくて,
これは,pymatgenのsource codeを読んで見つける.
どうもpycallを使うには,こういうのを繰り返す必要がありそうだ.

require 'pycall/import'
include PyCall::Import

pyimport :sys
pyimport 'numpy', as: :np
pyfrom 'pymatgen.io.vasp.outputs', import: :Vasprun

# dos
dosrun = Vasprun.("../dos_calc_fine/vasprun.xml")
e_object = (dosrun.tdos.energies - dosrun.efermi)
energy = PyCall::List.(e_object).to_a
spd_dos = dosrun.complete_dos.get_spd_dos()
spd = PyCall::Dict.(spd_dos)
s_d = spd.to_a[0][1].densities
s_list = PyCall::List.(s_d.to_a[0][1]).to_a
p_d = spd.to_a[1][1].densities
p_list = PyCall::List.(p_d.to_a[0][1]).to_a
d_d = spd.to_a[2][1].densities
d_list = PyCall::List.(d_d.to_a[0][1]).to_a
tdos = dosrun.tdos.densities
t_list = PyCall::List.(tdos.to_a[0][1]).to_a

require 'numo/gnuplot'
Numo.gnuplot do
  set yrange: '[-10:10]'
  plot [s_list, energy, w: :l, title: 's'],
  [p_list, energy, w: :l, title: 'p'],
  [d_list, energy, w: :l, title: 'd'],
  [t_list, energy, w: :l, title: 'total']
end
daddygongon
Ruby, VASP, Maple, boundary, nucleation, Al, Ti, Mg, SiC, Si
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした