From 016ba85389ce01327ba9baa2d909785bbd1cf54d Mon Sep 17 00:00:00 2001 From: "Ryan@WorkStation" Date: Wed, 21 Feb 2024 16:24:40 -0500 Subject: [PATCH] added experimental Simulation Helper using Python --- Cleopatra/SimHelper.py | 132 ++++++++++++++++++++++++++++++++++ Cleopatra/Simulation_Helper.C | 38 +++++----- Cleopatra/nuclear_data.py | 4 +- 3 files changed, 153 insertions(+), 21 deletions(-) create mode 100755 Cleopatra/SimHelper.py diff --git a/Cleopatra/SimHelper.py b/Cleopatra/SimHelper.py new file mode 100755 index 0000000..70b439b --- /dev/null +++ b/Cleopatra/SimHelper.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python3 + +#============== experimental Simulation Helper using PyROOT and PyQT +# +# need pip install PyQt6 +# need to make at Cleopatra +# +#===================================================== + +import sys +from PyQt6.QtCore import Qt +from PyQt6.QtWidgets import QApplication, QWidget, QMainWindow, QLabel, QPushButton, QVBoxLayout, QPlainTextEdit, QGroupBox, QGridLayout +import subprocess +import ROOT +import webbrowser + +def SaveTxtFromEditor(): + if presentFileName != "" : + with open(presentFileName, "w") as f: + f.write(editor.toPlainText()) + +def LoadTxtToEditor(txtFileName): + global presentFileName + SaveTxtFromEditor() + + presentFileName = txtFileName + with open(txtFileName) as f: + text = f.read() + editor.setPlainText(text) + +def RunSimulation(): + SaveTxtFromEditor() + bash_command = "../Cleopatra/SimTransfer reactionConfig.txt detectorGeo.txt 0 '' transfer.root" + process = subprocess.Popen(bash_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + output, error = process.communicate() + if process.returncode != 0: + print("Error:", error.decode()) + else: + print("Output:", output.decode()) + + +def OpenHttpServer(): + global ser, file, tree + file = ROOT.TFile("transfer.root", "read") + tree = file.Get("tree") + + hEZ = ROOT.TH2F("hEZ", "E - Z; z[mm]; e[MeV]", 400, -600, 0, 400, 0, 10) + hXY = ROOT.TH2F("hXY", "Array; X[mm]; Y[MeV]", 200, -20, 20, 200, -20, 20) + hRecoilXY = ROOT.TH2F("hRecoilXY", "Recoil; X[mm]; Y[MeV]", 400, -60, 60, 400, -60, 60) + hThetaCMZ = ROOT.TH2F("hThetaCMZ", "TheatCM - Z; X[mm]; thetaCM [deg]", 400, -600, 0, 400, 0, 60) + hExCal = ROOT.TH1F("hExCal", "ExCal; MeV", 400, -1, 5) + + + for event in tree: + if( event.hit != 1 or event.thetaCM < 10 or event.loop != 1) : continue + + hEZ.Fill(event.array_hit_z, event.energy_light) # x, y + hXY.Fill(event.xArray, event.yArray) + hRecoilXY.Fill(event.xRecoil, event.yRecoil) + hThetaCMZ.Fill(event.array_hit_z, event.thetaCM) + hExCal.Fill(event.ExCal) + + + ser = ROOT.THttpServer("http:9876") + # ser.SetJSROOT("https://root.cern.ch/js/latest/") + + ser.Register("/", hEZ) + ser.Register("/", hXY) + ser.Register("/", hRecoilXY) + ser.Register("/", hThetaCMZ) + ser.Register("/", hExCal) + + ser.SetItemField("/","_layout","grid4x4") + ser.SetItemField("/","_drawitem","[hEZ, hRecoilXY, hExCal, hThetaCM]") + + webbrowser.open("http://localhost:9876/") + + +######################################################## +if __name__ == "__main__": + + app = QApplication(sys.argv) + editor = QPlainTextEdit() + + presentFileName = "" + + ser = None + file = None + tree = None + + window = QMainWindow() + window.setWindowTitle("Simulation Helper") + window.setFixedSize(800, 1000) + + mainWidget = QWidget() + window.setCentralWidget(mainWidget) + + layout = QGridLayout() + mainWidget.setLayout(layout) + + reactionGroup = QGroupBox("Reaction", window) + layout.addWidget(reactionGroup, 0, 0) + reactionLayout = QVBoxLayout(reactionGroup) + + bDetGeo = QPushButton("Detector Geo", reactionGroup) + reactionLayout.addWidget(bDetGeo) + bDetGeo.clicked.connect(lambda : LoadTxtToEditor("detectorGeo.txt")) + + bReactionConfig = QPushButton("Reaction Config", reactionGroup) + reactionLayout.addWidget(bReactionConfig) + bReactionConfig.clicked.connect(lambda : LoadTxtToEditor("reactionConfig.txt")) + + bSim = QPushButton("Simulation", reactionGroup) + reactionLayout.addWidget(bSim) + bSim.clicked.connect(RunSimulation) + + bTest = QPushButton("Open Browser", reactionGroup) + reactionLayout.addWidget(bTest) + bTest.clicked.connect(OpenHttpServer) + + layout.addWidget(editor, 0, 1, 5, 5) + LoadTxtToEditor("detectorGeo.txt") + + # # Create PyQtGraph plot + # plot = PlotWidget() + # plot_item = plot.getPlotItem() + # plot_item.plot(x=[1, 2, 3], y=[4, 6, 2]) + # layout.addWidget(plot) + + # Show the window and start the event loop + window.show() + sys.exit(app.exec()) \ No newline at end of file diff --git a/Cleopatra/Simulation_Helper.C b/Cleopatra/Simulation_Helper.C index dff90ee..11cedbe 100644 --- a/Cleopatra/Simulation_Helper.C +++ b/Cleopatra/Simulation_Helper.C @@ -287,32 +287,32 @@ MyMainFrame::MyMainFrame(const TGWindow *p,UInt_t w,UInt_t h) { } - {//====================== Nuclear data API - TGGroupFrame * dataFrame = new TGGroupFrame(hframe1, "Nuclear Data", kVerticalFrame); - hframe1->AddFrame(dataFrame, new TGLayoutHints(kLHintsCenterX, 5,5,3,4)); + // {//====================== Nuclear data API + // TGGroupFrame * dataFrame = new TGGroupFrame(hframe1, "Nuclear Data", kVerticalFrame); + // hframe1->AddFrame(dataFrame, new TGLayoutHints(kLHintsCenterX, 5,5,3,4)); - TGHorizontalFrame * hfData = new TGHorizontalFrame(dataFrame); dataFrame->AddFrame(hfData, new TGLayoutHints(kLHintsNormal, 0, 0, 5, 0)); + // TGHorizontalFrame * hfData = new TGHorizontalFrame(dataFrame); dataFrame->AddFrame(hfData, new TGLayoutHints(kLHintsNormal, 0, 0, 5, 0)); - TGVerticalFrame * vfLabel = new TGVerticalFrame(hfData, 200); hfData->AddFrame(vfLabel ); - TGVerticalFrame * vfTxt = new TGVerticalFrame(hfData); hfData->AddFrame(vfTxt); + // TGVerticalFrame * vfLabel = new TGVerticalFrame(hfData, 200); hfData->AddFrame(vfLabel ); + // TGVerticalFrame * vfTxt = new TGVerticalFrame(hfData); hfData->AddFrame(vfTxt); - TGLayoutHints * haha = new TGLayoutHints(kLHintsRight | kLHintsCenterY, 5,5,5,2); - TGLayoutHints * kaka = new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 5,5,0,0); + // TGLayoutHints * haha = new TGLayoutHints(kLHintsRight | kLHintsCenterY, 5,5,5,2); + // TGLayoutHints * kaka = new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 5,5,0,0); - TGLabel * lb1 = new TGLabel(vfLabel, "Nuclear Name :"); vfLabel->AddFrame(lb1, haha); - TGLabel * lb2 = new TGLabel(vfLabel, "Max Ex [MeV] :"); vfLabel->AddFrame(lb2, haha); + // TGLabel * lb1 = new TGLabel(vfLabel, "Nuclear Name :"); vfLabel->AddFrame(lb1, haha); + // TGLabel * lb2 = new TGLabel(vfLabel, "Max Ex [MeV] :"); vfLabel->AddFrame(lb2, haha); - txtName = new TGTextEntry(vfTxt, "25F"); vfTxt->AddFrame(txtName, kaka); txtName->Resize(50, 20); - txtEx = new TGTextEntry(vfTxt, "0"); vfTxt->AddFrame(txtEx, kaka); txtEx->Resize(50, 20); + // txtName = new TGTextEntry(vfTxt, "25F"); vfTxt->AddFrame(txtName, kaka); txtName->Resize(50, 20); + // txtEx = new TGTextEntry(vfTxt, "0"); vfTxt->AddFrame(txtEx, kaka); txtEx->Resize(50, 20); - TGTextButton *GetData = new TGTextButton(dataFrame, "Get Data"); - GetData->SetWidth(150); - GetData->SetHeight(40); - GetData->ChangeOptions( GetData->GetOptions() | kFixedSize ); - GetData->Connect("Clicked()","MyMainFrame",this,"GetData()"); - dataFrame->AddFrame(GetData,new TGLayoutHints(kLHintsRight, 5,5,3,4)); - } + // TGTextButton *GetData = new TGTextButton(dataFrame, "Get Data"); + // GetData->SetWidth(150); + // GetData->SetHeight(40); + // GetData->ChangeOptions( GetData->GetOptions() | kFixedSize ); + // GetData->Connect("Clicked()","MyMainFrame",this,"GetData()"); + // dataFrame->AddFrame(GetData,new TGLayoutHints(kLHintsRight, 5,5,3,4)); + // } TGTextButton *exit = new TGTextButton(hframe1,"Exit", "gApplication->Terminate(0)"); exit->SetWidth(150); diff --git a/Cleopatra/nuclear_data.py b/Cleopatra/nuclear_data.py index 8c0b858..63fe7a6 100755 --- a/Cleopatra/nuclear_data.py +++ b/Cleopatra/nuclear_data.py @@ -45,7 +45,7 @@ def FindSym(Z): return 'na' def Mass(A, Z): try : - BEA = float(haha['binding'][haha['z']==Z][haha['n']==(A-Z)])/1000 + BEA = float(haha['binding'][haha['z']==Z][haha['n']==(A-Z)].iloc[0])/1000 return (A-Z)*mn + Z*mp - A * BEA except : return -404 @@ -87,7 +87,7 @@ def Info(AZ): try : Z = temp['z'][0] N = temp['n'][0] - mass = Z*mp + N*mn - (Z+N)*temp['binding']/1000 + mass = float(Z*mp + N*mn - (Z+N)*temp['binding'].iloc[0]/1000) halfLife = temp['half_life_sec'][0] print(" A : %3d, Z : %3d, N : %3d, Mass : %.4f MeV" % (Z+N, Z, N, mass)) print("Jpi : %3s, half-live : %s sec" % (temp['jp'][0], halfLife))