CODで遊ぶ の変更点


#author("2024-03-08T16:58:51+09:00","default:masami","masami")
#author("2024-03-08T17:00:36+09:00;2024-03-08T16:58:51+09:00","default:masami","masami")
*CODで遊ぶ (2016/04/16作成)(2017/05/25追加、訂正など) [#h7f2db8a]
#contents
----
-(2019/01/08) cod_list.txtを使わない[[結晶構造検索COD_SQL版]]が出来たことで、今後cod_list.txtの更新は多分行わなくなる予定です。
-(2018/08/09) CODをupdateしたら、cifが別のdirectoryにも入るようで、cifを全部ダウンロードし直している。cod/tags/v0.10/cif/へ。
-(2018/04/06) cod_list.txtを最新にupdateした。04/05にuploadしたものは不完全でしたので、もしそれをダウンロードした方は再度ダウンロードしてください。
-(2017/05/26) Xojoで簡単なGUI検索プログラムを作ってみた(Mac, Win)。そちらは[結晶構造の検索GUI版]を参照。このページはなくなってます。[[結晶構造検索COD_SQL版]]をご覧ください。
-結晶構造データベース・無料(Google検索用)
**CODとは [#s11136dc]
-Crystallography Open Database([[COD:https://www.crystallography.net/]])は、結晶構造のオープンデータベースであり、biopolymerを除いた、有機および無機結晶を対象としている。現在(2019/01/12)、40.2万件が登録されている。&color(red){無料で結晶構造データベースを使うことができる。};鉱物を扱う者としては、アメリカ鉱物学会等の鉱物構造データベースがCODへ提供されているところが重要な点である。IUCr、ACSの雑誌で出版されたcifデータは自動的に登録されるようになっている。雑誌によってはCODへ結晶構造データのデポジットを推奨するところもある。
-CODは個人のPC等に自由にダウンロードすることができるので、それを研究・教育等に利用することができる。例えば、CODサイトで行っている検索は、php, mysqlが使えれば、ローカルPCでも実施することができる。最近、CODで遊んでいるので、いくつか紹介する。下で述べるようにCOD自体をダウンロードしなくても遊べることが色々とあります。
**CODのダウンロード [#d6805521]
-CODのwikiにダウンロード方法が書かれているのでそれを参考にする。UNIX系(Mac OS Xも)であれば、Subversionを使って、以下のようにすればよい。なお、現在データ量は膨大なので(40GB弱、2016/04/14)、ハードディスク容量に注意しよう。最初のダウンロードには長時間かかる。
次のコマンドで、CODをダウンロードする。
 > svn co svn://www.crystallography.net/cod
 % svn co svn://www.crystallography.net/cod
CODは常に更新しているので、時々アップデートする必要がある。まずcodディレクトリーに移動してから、
 > cd cod
 > svn update
 % cd cod
 % svn update
もしアップデートで怒られたら、指示通りにclean upを実行する
 > svn cleanup
 % svn cleanup
アップデートしようとしたら、アップグレードするように言われる時がある。その場合は、
 > svn upgrade
 % svn upgrade
**鉱物名を取り出す [#s004ce3d]
-膨大なcifファイルがあるが、そこから情報を取り出してみよう。以下はMac上での処理だが、Linuxでもほぼ同じ。私の場合、鉱物を扱うことが多いので、鉱物名で検索できれば便利である。鉱物名はcifファイル中では、"_chemical_name_mineral"というタグで入っているので(入ってないcifも多数存在する)、それを読めばよい。そうして得た鉱物名をそのcifファイル名とともにテキストファイルに書き出しておけば、後でそのファイルを使って、ローカルで鉱物名で検索することや、鉱物のみを対象とする処理等で利用できる。そこで簡単なPythonのコードを書いて試してみた。cifファイルが3層のディレクトリ下に分配されているので、まずディレクトリのリストを得て、一段降りて、それを3回繰り返して、最後にcifファイルが実際に入っているディレクトリへ到着する。そこでcifファイルのリストを得て、それらを1つづつ処理する。Macの場合は、.DS_Storeというファイルが自動的にディレクトリ内にできるので、それをリストから除外する処理も必要となる。私のMacbook AirだとCOD全部処理するのに8分くらいかかったが、SSDを使っているので、これは速い方だった。HDD内臓のMac miniで試すと1時間以上かかった。"_chemical_name_mineral"には鉱物でない場合でも適当な内容が入っていることがあるが、その判定は不可能なので、そのままにしている。そうして出来たのが[[鉱物名リスト:https://mkanzaki.sakura.ne.jp/data/minerals_in_cod.txt]]である。なお、鉱物の場合は温度や圧力を変えたデータや固溶体も多いため、同じ鉱物名でも、たくさんのcifファイルが存在する(たとえばforsterite)。そういう意味では、"_publ_section_title"の情報や組成(_chemical_formula_sum)を一緒に取り出して表示すればいいかもしれない(それは既に実行中。下を参照)。ここでは"_chemical_name_mineral"タグのみの処理であるが、中央部分を変えれば様々な情報を集めることができそうである。それほど長くはないので、コードをペーストしておく。4行目のbaseは自分の環境に合わせて直す必要がある。
 #!/usr/bin/python
 import os,sys
 
 base = '/Users/masami/cod/cif/' # cif base directory, change here!
 list_basedir = ['1','2','3','4','5','6','7','8','9']
 #list_basedir = ['1'] # for test purpose, use limited list...
 for i in range(0,len(list_basedir)):
 	dir1 = base + list_basedir[i] + '/' # first-level directory
 	os.chdir(dir1) # move to second-level directory
 	list_1 = os.listdir('.') # 
 	if '.DS_Store' in list_1: # .DS_Store exists?
 		list_1.remove('.DS_Store') # remove .DS_Store
 	for j in range(0,len(list_1)):
 		dir2 = dir1 + list_1[j] + '/'
 		os.chdir(dir2) # move to 3rd-level directory
 		list_2 = os.listdir('.') 
 		if '.DS_Store' in list_2: # .DS_Store exists?
 			list_2.remove('.DS_Store') # remove .DS_Store
 		for k in range(0,len(list_2)):
 			dir3 = dir2 + list_2[k] + '/'
 			os.chdir(dir3) # move to 4th-level directory
 			list_3 = os.listdir('.')
 			if '.DS_Store' in list_3: # .DS_Store exists?
 				list_3.remove('.DS_Store') # remove .DS_Store
 			# list_3 contains cif file name list in this directory
 			for l in range(0,len(list_3)):  # process cif file
 				fin = open(list_3[l],'r') # open cif file
 				contents = fin.readlines() # read all contents in memory
 				fin.close() # close cif file
 				for line in contents: # for each line of cif  file (in memory)
 					try:
 						if '_chemical_name_mineral' in  line: # Does this tag exist?
 							tmp = line.strip() # strip \n
 							t = len(tmp) # length of tmp string
 							mineral_name = tmp[33:t] # get mineral name
 							if len(mineral_name) == 0: # if empty, break
 								break
 							else: # next line, remove ' and spaces
 								mineral_name = mineral_name.replace("'","").strip()
 								# make first letter to lower case
 								mineral_name = mineral_name[0].lower() + mineral_name[1:]
 								print mineral_name + ',' + list_3[l] #list_3[l] = cif filename
 								break
 					except: # tag not available in this cif
 						break	

-これを使っている時に問題があって、途中で止めるには、control-cを押す。バックグラウンドで実行中なら、psコマンドでpid番号を見つけて、killする。
-(2016/05/13) COD内のファイルを眺めていたら、同じ様に抽出したテキストファイルが存在していた。これはmysql directoryにあるので、mysqlでの検索にこれを使っているのだろう。data.txtという名前で、私が作ったのよりははるかに情報が入っているが、その分でかい(300 MB)。
**Vestaでオープン [#xcb0ee21]
-上記の[[鉱物名リスト:https://mkanzaki.sakura.ne.jp/data/minerals_in_cod.txt]]をターミナル上ならgrepを使うか、GUIならテキストエディタで開いて、検索すれば鉱物名に対応するcifファイル番号がすぐ分かる。次はgrepでの検索の例。
 % grep forsterite minerals_in_cod.txt
 forsterite,9000166.cif
 forsterite,9000167.cif
 forsterite,9000267.cif
 以下省略
-実際にCOD全部をダウンロードしてなくても、その特定のcifファイルだけを得ることは簡単にできる。以下のようにウェブブラウザから、cifファイル名を直接指定してやれば、cifファイルがダウンロードされるので、それをVesta等で開けばよい。さらに後で示すようにcurlコマンドを使えば、ダウンロードを自動化することができる。以前は/cod/の部分が不要だったが、最近はないとダメなようだ
 https://www.crystallography.net/cod/9000166.cif
-COD自体をダウンロードしている場合には、cifファイル本体はcodディレクトリから数えて5層下にあるので、GUI操作だとファイル名からファイルまでたどり着くのは結構面倒である(MacならSpotlightで検索した方が早いだろう)。cifファイル名からそれがあるディレクトリは一意に決まるので、cifファイル名を引数に与えると、ファイルを探して、Vestaで開いてくれる簡単なPythonコードも作った。これくらいならUnixのshellでできなくもないが。コードは短いので下に直接ペーストしておく。もちろんbase部分はそれぞれの環境に応じて変えないといけない。
 #!/usr/bin/python
 import sys,subprocess
 base = '/Users/masami/cod/cif/' # cif base directory, change here
 fname = sys.argv[1]
 dir = base + fname[0] + '/' + fname[1:3] + '/' + fname[3:5] + '/' + fname
 cmd = "open -a VESTA " + dir
 subprocess.call(cmd.split(" "))
たとえばこれをvesta.pyとして保存し、実行権限をつけて以下のように実行すると、cifファイルの内容が結晶構造としてVesta上に表示される。
 > chmod 755 vesta.py
 > ./vesta.py 9000166.cif
 % chmod 755 vesta.py
 % ./vesta.py 9000166.cif
**さらに簡単にVestaでオープン(2016/04/26) [#i1aafb2e]
-上記ファイルを使ってみると、鉱物構造をちょっと調べるのに便利なので、さらにVestaでオープンするコードを改良した。COD自体をダウンロードしてない方の場合、上記のままだと、検索後に見たいファイルをCODサイトからダウンロードする必要がある。検索、ダウンロード、Vestaでオープンと3ステップも必要なのは面倒である。そこで、それらを1つのPythonコード内で行うようにした。ダウンロードにはcurlコマンドを利用している。このコードでは、検索する鉱物名を引数として渡すと、検索して、存在しない場合は即終了。1つのみ存在の場合は、直ちにダウンロードして表示する。複数ある場合は、番号付きリストが出てくるので、その番号を選んでやると、ダウンロードされて、Vestaで表示される。当然インターネットにつながってないとダメ。また、上記の[[鉱物名リスト:https://www.misasa.okayama-u.ac.jp/~masami/minerals_in_cod.txt]]が必要である(現在は下記の化学組成を含む方をダウンロードしてください)。このコードもそれほど長くないので、ペーストしておく。鉱物リストファイルの場所を(mineral_file)、自分の環境に合わせて変える必要がある。Linuxの場合、Vestaを呼び出すところを変える必要がある。文字だけでは便利さが伝わらないかもしれないので、使っているところの[[movie:https://www.misasa.okayama-u.ac.jp/~masami/images/cod_demo1.mov]]を置いておきます。(2016/09/09追記)しばしば同じ鉱物でも沢山あって何が違うかよくわからない場合が多いので、JeditXで自動的にcifファイルをオープンする部分を追加した(とりあえずコメントアウトしているが)。

 #!/usr/bin/python
 import sys,subprocess
 # curl version
 list = ['' for i in range(500)]
 min_name = sys.argv[1]
 mineral_file = '/Users/masami/minerals_in_cod.txt' # mineral-list, change here
 try: # text file open
	 fin = open(mineral_file,'r')
 except IOError, (errno, msg): # file not found
 	print 'minerals_in_cod.txt is missing.'
 	exit()
 contents = fin.readlines() # read all lines in cif file to contents
 fin.close() # close file
 find = 0
 for line in contents:
 	if min_name in line: # mineral name in a line?
 		find = find + 1
 		list[find] = line.strip() # strip \n
 		print str(find) + ": " + list[find] 
 if find == 0:
 	print "No such mineral in the list."
 	exit()
 elif find == 1: # just one, no selection
 	input_no = 1
 else: # select by number
 	print "Select by number? (0 to stop)."
 	input_no = input('>>> ')
 if (input_no <= 0) or (input_no > find):
 	exit()
 s = list[input_no].index(",")
 t = len(list[input_no])
 fname = list[input_no][s+1:t] # get file name
 cmd = "curl -s -o" + " " + fname + " " + "https://www.crystallography.net/cod/" + fname
 subprocess.call(cmd.split(" ")) # Get specified cif file from the COD site by curl   
 cmd = "open -a VESTA" + " " + fname
 subprocess.call(cmd.split(" ")) # open VESTA using a downloaded cif file  
 #cmd = "open -a Jedit\ X" + " " + fname
 #subprocess.call(cmd,shell=True) # open cif file by JeditX			 
 exit()
 # end of the code, mkanzaki@me.com
使い方は、terminal上では次のような感じ。moganiteを検索すると、3つ存在したので、2番目を選んでいる。9005115.cifがCODサイトからダウンロードされ、Vestaに表示される。なお、そのcifファイルはカレントディレクトリに保存されているので、後で再利用できる。
 > ./vesta_curl.py moganite
 % ./vesta_curl.py moganite
 1: moganite,9002648.cif
 2: moganite,9002649.cif
 3: moganite,9005115.cif
 Select by number? (0 to stop).
 >>> 2
**化学組成なども取り出したリストで検索(2016/05/06) [#ef240960]
-上記は鉱物名だけだったが、化学組成、空間群、化学物質名、鉱物名を取り出したリストを最近作った。実は鉱物名が付いているcifファイルは多くなく、全体の3%くらいにすぎない。こちらは全cifファイルから抽出しているので、16 MBと巨大になっている。ダウンロードは[[ここ:https://www.misasa.okayama-u.ac.jp/~masami/cod_list.txt]]から。それ用の検索用codeも作った。そちらは[[ここ:https://www.misasa.okayama-u.ac.jp/~masami/vesta_chem.py]]。それらについては、[[結晶構造の検索]]にまとめてある。
-なお、CODをダウンロードしている場合は、ローカルディスク上を探すために、少しコードを変えるが、それは[[こちら:https://www.misasa.okayama-u.ac.jp/~masami/vesta_chem2.py]]からダウンロードできる。これの6行目を実際にCODを置いている場所に応じて直す必要がある。
-このPythonプログラムはGUIでないので、多くの方には使いずらいかもしれない。Xojoで簡単なGUIの検索アプリを作ろうとしていて、どうすればXojoからOS Xのコマンド(curlなど)を実行できるか勉強中。以下のようにshell.Excecuteを使えばいいようだ。ボタンを追加して、それのAction eventで以下のコードを書いておく。実行して、ボタンをクリックすると、9000166.cifをダウンロードして、Vesta, Jeditで表示された。
 Dim Sh As New Shell
 Sh.Execute( "curl -s -o ~/test.cif https://www.crystallography.net/cod/9000166.cif" )
 Sh.Execute( "open -a VESTA ~/test.cif" )
 Sh.Execute( "open -a Jedit\ X ~/test.cif" )
-下図のような簡単なGUI検索プログラムを何とか作った。テスト中。
#image(https://www.misasa.okayama-u.ac.jp/~masami/images/COD_search.png,center,80%)
**cifファイルから粉末回折パターンを計算する(2016/05/06) [#y9e2d468]
-これらの結晶構造データ(cifファイル)から、粉末X線回折パターンを作成することができる。もっとも簡単な方法は(VestaとRIETAN-FPのユーザーの場合は)、Vestaでcifを読んで、そこから粉末回折パターンをRIETAN-FPで計算させる方法である。ただ、CODの膨大な数のファイルをマニュアルで処理するのは困難なので、cifファイルからRIETAN-FPの入力ファイル(.ins)を自動作成するコードが必要となる。最近、そのようなPythonコードを開発中である。現在、数千のcifファイルを処理して、テストを行っているが、どうしても空間群指定のかなり特殊なケース等が数件出てしまう。非標準な場合の対応はその場しのぎの汚い処理なので、コードの公開は難しい。もう少しrefineして、全cifファイルを処理する予定。この計算は1日近くかかりそう。lstファイルを処理して、各ピークの強度を抽出してやればよいが、パターン自体も計算されているので、パターン自体で検索することも可能になる(検索時間はかかりそうだが)。検索するソフトの方がまだ手付かずだが。
**実測と計算回折パターンの比較 [#ab0833e4]
-まだ検索ソフトには取り掛かってないが、ちょうど測定データを同定する必要があったので、応急処置で上記等を組み合わせて、候補の計算パターンと測定パターンが比較ができるようにした。以下はそのやり方。
--回折装置、私の場合はリガクの測定データ(.asc)をPlot2(Macのアプリ)で読める様に変換する
--検索コード(上記)で見つけたcifファイルを、これも上記のcifからRIETAN-FPの入力ファイル.insを作るコードで処理する
--insファイルから粉末パターンのシミュレーションをRIETAN-FPで実行。
--強度データ(gpd)をPlot2で読める様に変換(これもPythonコード)
--Plot2でそれらを読み込んで比較する
-Plot2に自動で読み込ませる部分がうまくいかなかった。Appstoreからではなく、Plot2のHPから直接ダウンロードしたバージョンだと、コマンドラインから、ASCIIファイルでも読み込めるようになる。ただし1つのファイルだけ。1つのファイルに全部詰め込んでおけばいいのだろうが。
 cmd = "/Applications/Plot2.1.1/Plot2x.app/Contents/MacOS/Plot2x -i " + dir3 + " &" 
 subprocess.call(cmd,shell=True)
-Jeditは実行ファイル名やディレクトリー名にスペースを使うのをやめてほしい。Pythonから実行させる時にsubprocess.call(cmd.split(" "))を使うと、Jedit\ Xのスペースが問題になる。そのため、subprocess.call(cmd.split(" "))をやめて、subprocess.call(cmd,shell=True)を使っている。
 cmd = "open -a Jedit\ X" + " " + filename
 subprocess.call(cmd,shell=True)				 
**他のCOD関連wikiページ [#vcdb184b]
-[[結晶構造検索COD_SQL版]] GUIのCOD検索プログラムでSQLを使って直接CODへアクセスして、検索する。検索結果をVestaですぐ眺めることができる。
-[[結晶構造の検索]] Macのterminal上からPythonを使って検索する方法を書いてます。CUIの好きな方はご覧ください。こちらも私の作ったインデックスファイルを使ってますが、PythonからCODへ直接SQL queryを送って検索することも可能なはずです。
-[[CODへデポジット]] CODデータベースはフリーですが、ボランティアが構造情報をデポジットすることで成り立ってます(一部雑誌は自動的にデポジットされますが)。皆さんもデポジットしましょう。