物理の駅 Physics station by 現役研究者

テクノロジーは共有されてこそ栄える

LISE++ファイルをPythonで読み取りBeamDumpの設定を調べる

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 で直接調べても良い (が大量にチェックする時は大変)。まあ、用途は限られているが...