diff --git a/Dockerfile b/Dockerfile index 0c28078..7171a9f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -23,7 +23,7 @@ RUN apt-get install -y dpkg-dev cmake g++ gcc binutils libx11-dev libxpm-dev lib #RUN python3 --version && python3 -m ensurepip RUN python3 -m pip install --upgrade pip -RUN python3 -m pip install pandas numpy matplotlib MarkupSafe wandb uproot setuptools awkward-pandas +RUN python3 -m pip install pandas numpy matplotlib MarkupSafe wandb uproot setuptools awkward-pandas plotly RUN python3 -m pip install --no-cache-dir torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # # # # GEANT diff --git a/bind/G4Calo.py b/bind/G4Calo.py index 3473b48..9d04486 100644 --- a/bind/G4Calo.py +++ b/bind/G4Calo.py @@ -1,6 +1,8 @@ from minicalo import ConstructionWrapper from minicalo import G4System as _G4System +import plotly.graph_objects as go +import numpy as np import os import subprocess import uproot @@ -34,25 +36,167 @@ class G4System(_G4System): df = ttree["Hits;1"].arrays(library="pd") return df - def displayEvent(self): - f_to_conv = max( - filter(lambda x: x.endswith(".prim"), os.listdir()), key=os.path.getctime - ) - # Convert the .prim file to an eps graphic. - subprocess.run(["dawn", "-d", f_to_conv], stderr=subprocess.DEVNULL) - # Convert the eps graphic to png graphic. - subprocess.run( - [ - "gs", - "-DEPSCrop", - "-dSAFER", - "-sDEVICE=png256", - "-r600", - "-o", - "event_raw.png", - f_to_conv.replace(".prim", ".eps"), - ], - stdout=subprocess.DEVNULL, - ) - subprocess.run(["convert", "event_raw.png", "-trim", "event.png"]) - display(Image("event.png", width=500)) + def displayEvent(self, particleSpec, minEnergy_GeV, maxEnergy_GeV=-1, sensor_width=np.array([50])): + # for loop over all layers + event = self.run_batch(1, particleSpec, minEnergy_GeV, maxEnergy_GeV) + to_plot = [] + material_dict = {} + + z0=0 + # loop over materials + for layer_i, layer in enumerate(reversed(self.cw.getLayers())): + layer_i = len(self.cw.getLayers()) - layer_i -1 + + # + # plot layers + # + layer_hx = sensor_width / 2. + layer_hy = sensor_width / 2. + layer_z = layer.thickness + layer_material = layer.material + + # add material to materials if it is not already in there + if layer_material not in material_dict.keys(): + material_dict[layer_material] = {'name': layer_material, + 'color': col_dict[layer_material], + 'showlegend': False, + 'flatshading': True, + 'opacity': 0.2} + # add legend entry + to_plot.append(go.Mesh3d(x=[None], y=[None], z=[None], i=[0], j=[0], k=[0], + color=material_dict[layer_material]['color'], + showlegend=True, name=layer_material)) + + to_plot.append(go.Mesh3d( + # 8 vertices of a cube + x = np.array([-1, -1, 1, 1, -1, -1, 1, 1]) * layer_hx, + y = np.array([-1, 1, 1, -1, -1, 1, 1, -1]) * layer_hy, + z = np.array([0, 0, 0, 0, -layer_z, -layer_z, -layer_z, -layer_z]) + z0, + **ijk_cube, + **material_dict[layer_material] + )) + z0 += layer_z + + # + # sensors + # + + # if there are sensors in the current layer, add them + if layer_i in event['sensor_layer'].to_numpy(): + is_in_layer = event['sensor_layer'].to_numpy() == layer_i + z = event['sensor_dz'].to_numpy()[is_in_layer] + n_sensors = len(z) + z=z[0] + + xy_centers, hwidth = calculate_sensor_centers(n_sensors, sensor_width) + + # loop over all sensors in current layer and add them to plot + for (x_center, y_center), energy in zip(xy_centers, event['sensor_energy'].to_numpy()[is_in_layer]): + to_plot.append(go.Mesh3d( + # 8 vertices of a cube + x = np.array([-1, -1, 1, 1, -1, -1, 1, 1]) * hwidth + x_center, + y = np.array([-1, 1, 1, -1, -1, 1, 1, -1]) * hwidth + y_center, + z = np.array([0, 0, 0, 0, z, z, z, z]) + z0, + **ijk_cube, + flatshading=True, + color='black', + name='Sensor', + opacity= max(0.03, float(energy / event['total_dep_energy'].to_numpy())), + showlegend=False, + )) + + z0 += z + # add legend entry for sensors + to_plot.append(go.Mesh3d(x=[None], y=[None], z=[None], i=[0], j=[0], k=[0], + color='black', showlegend=True, name='Sensors')) + + # add black-white colorbar for sensor hits + to_plot.append(go.Surface( + z=[[0, 0], [0, 0]], + colorscale=[[0, 'white'], [1, 'black']], + showscale=True, + cmin=0, + cmax=1, + colorbar=dict( + title='Fraction of total deposited Energy', + tickvals=[0, 1], + ticktext=['0', '1'], + ticks='outside', + ticklen=10, + ), + )) + + # + # add red arrow for incoming particle + # + to_plot.append( + go.Scatter3d( + x=[0, 0], + y=[0, 0], + z=[-10, -2], + mode='lines+text', + line=dict(color='red', width=3), # You can change the color and width of the arrow + text=['Incoming ' + particleSpec], + textposition='bottom center', + hoverinfo='text', + showlegend=False, + )) + + # + # finally show plot + # + + fig = go.Figure(data=[ + *to_plot + ]) + fig.update_layout(legend=dict(x=0)) + # add legend + fig.show() + + + + + +# +# some helpers +# + +def calculate_sensor_centers(X, square_size): + sensor_size = square_size / np.sqrt(X) + hsensor_size = sensor_size / 2. + centers = [] + + for j in range(int(np.sqrt(X))): + for i in range(int(np.sqrt(X))): + x_center = -25 + (i + 0.5) * sensor_size + y_center = -25 + (j + 0.5) * sensor_size + centers.append((x_center[0], y_center[0])) + + return centers, hsensor_size[0] + + +ijk_cube = { + "i": [7, 0, 0, 0, 4, 4, 6, 6, 4, 0, 3, 2], + "j": [3, 4, 1, 2, 5, 6, 5, 2, 0, 1, 6, 3], + "k": [0, 7, 2, 3, 6, 7, 1, 1, 5, 5, 7, 6], + } + + + +col_dict = { + # active materials + "G4_POLYSTYRENE": 'red', + "G4_PLASTIC_SC_VINYLTOLUENE": 'blue', + "G4_BGO": 'green', + "G4_LSO": 'yellow', + "G4_LYSO": 'orange', + "G4_CESIUM_IODIDE": 'purple', + "G4_PbWO4": 'pink', + "G4_Si": 'brown', + # passive materials + "G4_Pb": 'darkgrey', + "G4_Fe": 'lightgrey', + "G4_W": 'grey', + "G4_Cu": 'dimgray', + "G4_BRASS": 'slategrey', +} \ No newline at end of file diff --git a/bind/bindings.cpp b/bind/bindings.cpp index 89cc578..304eaa3 100644 --- a/bind/bindings.cpp +++ b/bind/bindings.cpp @@ -8,27 +8,65 @@ namespace py = pybind11; + template void makeConstructionWrapper(M & m, std::string name){ py::class_(m, name.data()).def(py::init()) .def("addLayer", &ConstructionWrapper::addLayer, py::arg("thickness"), py::arg("material"), py::arg("isActive")=true, py::arg("nx")=1, py::arg("ny")=-1) + .def("getXYWidth", &ConstructionWrapper::getXYWidth) + // bind overloaded getLayers function + .def("getLayers", (std::vector & (ConstructionWrapper::*)()) &ConstructionWrapper::getLayers) + .def("getLayers", (const std::vector & (ConstructionWrapper::*)() const) &ConstructionWrapper::getLayers) .def("getNSensors", &ConstructionWrapper::getNSensors); } -template -void makeG4System(M& m, std::string name){ + + +template +void makeG4System(M &m, std::string name) +{ py::class_(m, name.data()).def(py::init()) - .def("init", &G4System::init, py::arg("cw")) - .def("run_gui", &G4System::run_gui) - .def("run_batch", &G4System::run_batch, py::arg("nEvents"), py::arg("partSpecies"), py::arg("minEnergy_GeV"), py::arg("maxEnergy_GeV")) - .def("run_visualize", &G4System::run_visualize, py::arg("partSpecies"), py::arg("minEnergy_GeV"), py::arg("maxEnergy_GeV")) + .def("init", &G4System::init, py::arg("cw")).def("run_visualize", &G4System::run_visualize, py::arg("partSpecies"), py::arg("minEnergy_GeV"), py::arg("maxEnergy_GeV")) + .def("run_gui", &G4System::run_gui).def("run_batch", &G4System::run_batch, py::arg("nEvents"), py::arg("partSpecies"), py::arg("minEnergy_GeV"), py::arg("maxEnergy_GeV")) .def("applyUICommand", &G4System::applyUICommand, py::arg("command")) - .def("printMaterial", &G4System::printMaterial, py::arg("name")); + .def("displayEvent", &G4System::displayEvent) + .def("printMaterial", &G4System::printMaterial, py::arg("name")) + .def("check", &G4System::check) + .def_readwrite("cw", &G4System::cw); + } -PYBIND11_MODULE(minicalo, m) { +// create bindings for Layer class +template +void makeLayer(M &m, std::string name){ + py::class_(m, name.data()).def(py::init()) + .def_readwrite("thickness", &Layer::thickness) + .def_readwrite("material", &Layer::material) + .def_readwrite("nx", &Layer::nx) + .def_readwrite("ny", &Layer::ny) + .def_readwrite("isActive", &Layer::isActive) + .def_readwrite("sens_xwidth", &Layer::sens_xwidth) + .def_readwrite("sens_ywidth", &Layer::sens_ywidth) + .def_readwrite("sensors", &Layer::sensors); +} + +// create bindings for sensor class +template +void makeSensor(M &m, std::string name){ + py::class_(m, name.data()).def(py::init()) + .def("getEnergy", &Sensor::getEnergy) + .def("getPos", &Sensor::getPos) + .def("getSize", &Sensor::getSize); +} + + + +PYBIND11_MODULE(minicalo, m) +{ m.doc() = "pybind11 plugin"; // optional module docstring makeConstructionWrapper(m, "ConstructionWrapper"); makeG4System(m, "G4System"); + makeSensor(m, "Sensor"); + makeLayer(m, "Layer"); } \ No newline at end of file diff --git a/bind/example.ipynb b/bind/example.ipynb new file mode 100644 index 0000000..2fc9d82 --- /dev/null +++ b/bind/example.ipynb @@ -0,0 +1,1045 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "hovertemplate": "x=%{x}
y=%{y}
z=%{z}", + "legendgroup": "", + "marker": { + "color": "#636efa", + "symbol": "circle" + }, + "mode": "markers", + "name": "", + "scene": "scene", + "showlegend": false, + "type": "scatter3d", + "x": [ + 1, + 2, + 3, + 4, + 5 + ], + "y": [ + 5, + 4, + 3, + 2, + 1 + ], + "z": [ + 10, + 20, + 15, + 25, + 30 + ] + }, + { + "line": { + "color": "red", + "width": 2 + }, + "opacity": 0.2, + "type": "scatter3d", + "x": [ + -1, + 1, + 1, + -1, + -1, + 1, + 1, + -1, + -1 + ], + "y": [ + -1, + -1, + 1, + 1, + -1, + -1, + 1, + 1, + -1 + ], + "z": [ + 0, + 0, + 0, + 0, + 30, + 30, + 30, + 30, + 0 + ] + } + ], + "layout": { + "legend": { + "tracegroupgap": 0 + }, + "margin": { + "t": 60 + }, + "scene": { + "domain": { + "x": [ + 0, + 1 + ], + "y": [ + 0, + 1 + ] + }, + "dragmode": "orbit", + "xaxis": { + "title": { + "text": "X Label" + } + }, + "yaxis": { + "title": { + "text": "Y Label" + } + }, + "zaxis": { + "title": { + "text": "Z Label" + } + } + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmapgl" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "#E5ECF6", + "showlakes": true, + "showland": true, + "subunitcolor": "white" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "polar": { + "angularaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "radialaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "zaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "baxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "caxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Interactive 3D Scatter Plot" + } + } + }, + "text/html": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from G4Calo import ConstructionWrapper, G4System\n", + "\n", + "cw = ConstructionWrapper() #the width of the calorimeter is 50 cm times 50 cm (also steerable, but I'd leave it)\n", + "\n", + "cw.addLayer(3,\"G4_Si\",True, 7)\n", + "cw.addLayer(4,\"G4_Pb\",False) \n", + "cw.addLayer(3,\"G4_Si\",True, 7)\n", + "cw.addLayer(4,\"G4_Pb\",False)\n", + "cw.addLayer(3,\"G4_Si\",True, 7)\n", + "cw.addLayer(4,\"G4_Pb\",False)\n", + "\n", + "G4s = G4System()\n", + "G4s.init(cw)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "G4s.displayEvent(\"pi-\", 100000)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "df = G4s.run_batch(10, 'gamma',1 , 1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "df" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "caloML", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.16" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/include/ConstructionWrapper.hh b/include/ConstructionWrapper.hh index 477d9d6..0ad2378 100644 --- a/include/ConstructionWrapper.hh +++ b/include/ConstructionWrapper.hh @@ -68,9 +68,9 @@ public: std::vector& getLayers() ; const std::vector& getLayers() const; - double getXYWidth() const{ - return xywidth; - } + double getXYWidth() const; + + void resetSensorEnergies()const;//energies are mutable int getNSensors()const{ int n_sensors = 0; diff --git a/include/G4System.hh b/include/G4System.hh index 3e85711..9f59b67 100644 --- a/include/G4System.hh +++ b/include/G4System.hh @@ -43,6 +43,8 @@ void applyUICommand(const std::string& command){ UImanager->ApplyCommand(command); } +ConstructionWrapper cw; + void displayEvent()const{}; //just a placeholder, this will be implemented in python void printMaterial(const std::string& name)const; diff --git a/src/ConstructionWrapper.cc b/src/ConstructionWrapper.cc index 2505906..7f2b2a1 100644 --- a/src/ConstructionWrapper.cc +++ b/src/ConstructionWrapper.cc @@ -68,6 +68,11 @@ std::vector & ConstructionWrapper::getLayers(){ return layers; } + +double ConstructionWrapper::getXYWidth() const{ + return xywidth; +} + void ConstructionWrapper::resetSensorEnergies()const { for(const auto & layer : layers){ for(const auto & sensor : layer.sensors){ diff --git a/src/G4System.cc b/src/G4System.cc index 44f25a6..2e82f0b 100644 --- a/src/G4System.cc +++ b/src/G4System.cc @@ -33,6 +33,8 @@ void G4System::init(ConstructionWrapper &CW){ //delete actionInitialization; } + // save layers of CW to G4System class + G4System::cw = CW; G4String session;