LISE++ファイルは、テキストファイルで作られているのでPythonで容易に読み取ることができる。
[]
で囲まれた文字列をカテゴリ、その中で記述された =
で区切られたKeyとValueを辞書型で詰めている。;
以降はコメントとして無視している。
def read_lise_lpp(filename): import re try: f = open(filename) lines = f.readlines() except: f = open(filename,encoding="utf-8") lines = f.readlines() f.close() obj = {} obj["Version"] = lines[0].strip() catgegory = None for line in lines[1:]: line = line.strip() if line=="":continue # section if line[0]=="{" and line[-1]=="}":continue # catgegory if line[0]=="[" and line[-1]=="]": catgegory=line[1:-1] obj[catgegory]={} continue # comments if ';' in line: comment_pos = line.index(';') line = line[:comment_pos] # key and value line = line.strip(' ') equal_pos = line.index('=') key = line[0:equal_pos] value = line[equal_pos+1:] key = key.strip(' ') key = re.sub('\s+', ' ', key) value = value.strip(" ") value = re.sub('\s+', ' ', value) obj[catgegory][key]=value return obj
RIBFのBigRIPSで実験するときのBeamDumpの設定を調べる関数を紹介する。RIBFのウェブサイトにPOSTでデータ取得している。
def get_beam_dump(obj,verbose=False): AZQ = obj["settings"]["A,Z,Q"] Energy = obj["settings"]["Energy"] TargetContents = obj["target"]["Target contents"] TargetThickness = obj["target"]["Target thickness"].split(",")[1] D1Brho = float(obj["D1_DipoleSettings"]["Brho"].replace(" Tm","")) return get_beam_dump_impl(AZQ,Energy,TargetContents,TargetThickness,D1Brho,verbose) def get_beam_dump_impl(AZQ,Energy,TargetContents,TargetThickness,D1Brho,verbose=False): import requests import json arguments={"Status":"Error","AZQ":AZQ, "Energy":Energy, "TargetContents":TargetContents, "TargetThickness":TargetThickness, "D1Brho":D1Brho} if AZQ=="238U 86+" and Energy=="345 MeV/u":Bnum=0 elif AZQ=="136Xe52+" and Energy=="345 MeV/u":Bnum=1 elif AZQ=="124Xe52+" and Energy=="345 MeV/u":Bnum=2 elif AZQ=="86Kr36+" and Energy=="345 MeV/u":Bnum=3 elif AZQ=="78Kr36+" and Energy=="345 MeV/u":Bnum=4 elif AZQ=="70Zn30+" and Energy=="345 MeV/u":Bnum=5 elif AZQ=="48Ca20+" and Energy=="345 MeV/u":Bnum=6 elif AZQ=="40Ca20+" and Energy=="345 MeV/u":Bnum=7 elif AZQ=="36Ar18+" and Energy=="345 MeV/u":Bnum=8 elif AZQ=="18O 8+" and Energy=="345 MeV/u":Bnum=9 elif AZQ=="18O 8+" and Energy=="250 MeV/u":Bnum=10 elif AZQ=="18O 8+" and Energy=="230 MeV/u":Bnum=11 elif AZQ=="16O 8+" and Energy=="345 MeV/u":Bnum=12 elif AZQ=="16O 8+" and Energy=="250 MeV/u":Bnum=13 elif AZQ=="14N 7+" and Energy=="250 MeV/u":Bnum=14 elif AZQ=="4He2+" and Energy=="320 MeV/u":Bnum=15 elif AZQ=="2H 1+" and Energy=="250 MeV/u":Bnum=16 else: if verbose:print(arguments) return arguments if type(TargetThickness) is not str: TargetThickness = str(TargetThickness) if TargetContents=="0,4,1,9.012" or TargetContents=="Be": if TargetThickness=="0.1":Tnum=0 elif TargetThickness=="0.5":Tnum=1 elif TargetThickness in ["1","2","3","4","5","6","7","8","9","10","11","12"]:Tnum=int(TargetThickness)+2 elif TargetThickness=="15":Tnum=15 elif TargetThickness=="17":Tnum=16 elif TargetThickness=="20":Tnum=17 elif TargetThickness=="30":Tnum=18 elif TargetThickness=="40":Tnum=19 else: if verbose:print(arguments) return arguments elif TargetContents=="0,74,1,183.85" or TargetContents=="W": if TargetThickness=="0.1":Tnum=20 elif TargetThickness=="0.2":Tnum=21 elif TargetThickness=="0.3":Tnum=22 elif TargetThickness=="0.5":Tnum=23 elif TargetThickness=="1":Tnum=24 elif TargetThickness=="1.4":Tnum=25 elif TargetThickness=="2.1":Tnum=26 elif TargetThickness=="2.8":Tnum=27 else: if verbose:print(arguments) return arguments else: if verbose:print(arguments) return arguments if TargetContents=='0,4,1,9.012': TargetContents='Be' elif TargetContents=='0,74,1,183.85': TargetContents='W' payload = {'Bnum': Bnum,'Tnum': Tnum,'D1Brho': D1Brho,'btnExec': ''} files = {(None, None)} ret = requests.post('https://ribf.riken.jp/BigRIPSInfo/beamdump/result.php', files=files,data=payload) lines = ret.text.split("\n") status={} status["Status"]="OK" left = lines[46][lines[46].index(">")+1:lines[46].index('mm')].strip(' ') right = lines[48][lines[48].index(">")+1:lines[48].index('mm')].strip(' ') status["Left"]= "---" if left=="---" else float(left) status["Right"]= "---" if right=="---" else float(right) if verbose: payload['Beam']=AZQ+' '+Energy payload['Target']=TargetContents+' '+TargetThickness+'mmt' del payload['btnExec'] print(payload,"-->",status) return status
使い方は直接パラメータを指定するか、LISE++ファイルから読み取るかの2種類ある。
# 直接パラメータを指定する方法 print(get_beam_dump_impl(AZQ="238U 86+",Energy="345 MeV/u",TargetContents="Be",TargetThickness=0.1,D1Brho=7.0,verbose=True)) # LISEファイルから関数`read_lise_lpp`で読み取った辞書型を使う方法 import requests url = "http://ribf.riken.jp/BigRIPSInfo/lise/238U_Be_fission_Standard_LAA.lpp" with open("lise.lpp", "w") as f: f.write(requests.get(url).text) print(get_beam_dump(read_lise_lpp("lise.lpp"),verbose=True))
標準出力は次のようになる
{'Bnum': 0, 'Tnum': 0, 'D1Brho': 7.0, 'Beam': '238U 86+ 345 MeV/u', 'Target': 'Be 0.1mmt'} --> {'Status': 'OK', 'Left': -55.0, 'Right': 125.0} {'Status': 'OK', 'Left': -55.0, 'Right': 125.0} {'Bnum': 0, 'Tnum': 6, 'D1Brho': 8.1005, 'Beam': '238U 86+ 345 MeV/u', 'Target': 'Be 4mmt'} --> {'Status': 'OK', 'Left': -125.0, 'Right': 125.0} {'Status': 'OK', 'Left': -125.0, 'Right': 125.0}
RIBFの Calculation for the position of the beam dump で直接調べても良い (が大量にチェックする時は大変)。まあ、用途は限られているが...