mirror of
https://github.com/jwinterm/geant4-radiation-labs.git
synced 2026-10-17 05:41:25 +02:00
133 lines
3.5 KiB
Python
133 lines
3.5 KiB
Python
"""Generate action_classes.png for Lab 3.
|
|
|
|
Shows the nested Geant4 user-action hierarchy (Run -> Event -> Step) as
|
|
three concentric boxes, each labelled with the corresponding B1 class and
|
|
the work that class will do after Lab 3's modifications.
|
|
|
|
Layout strategy: each layer reserves a "header strip" at its top for its
|
|
title and 2-3 body lines, and the next inner box starts BELOW that strip
|
|
so nothing overlaps.
|
|
"""
|
|
|
|
import os
|
|
|
|
import matplotlib.pyplot as plt
|
|
from matplotlib.patches import FancyBboxPatch
|
|
|
|
OUT_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
OUT_PATH = os.path.join(OUT_DIR, "action_classes.png")
|
|
|
|
# Figure coordinates (data units = arbitrary).
|
|
FIG_W = 11.0
|
|
FIG_H = 7.4
|
|
|
|
# Outer Run box.
|
|
RUN_BOX = (0.4, 0.6, 10.2, 6.4) # x, y, w, h
|
|
# Inner Event box. Top is 1.5 units below Run top to leave room for header.
|
|
EVENT_BOX = (1.05, 1.0, 8.9, 4.55)
|
|
# Innermost Step box. Top is 1.4 units below Event top.
|
|
STEP_BOX = (1.7, 1.45, 7.6, 2.7)
|
|
|
|
LAYERS = [
|
|
{
|
|
"rect": RUN_BOX,
|
|
"color": "#cfe2ff",
|
|
"title": "Run — RunAction",
|
|
"lines": [
|
|
"BeginOfRunAction(): open CSV file, define ntuple",
|
|
"EndOfRunAction(): write & close CSV file",
|
|
],
|
|
},
|
|
{
|
|
"rect": EVENT_BOX,
|
|
"color": "#fff3cd",
|
|
"title": "Event — EventAction",
|
|
"lines": [
|
|
"BeginOfEventAction(): reset fEdep = 0",
|
|
"EndOfEventAction(): write fEdep to ntuple",
|
|
],
|
|
},
|
|
{
|
|
"rect": STEP_BOX,
|
|
"color": "#d4edda",
|
|
"title": "Step — SteppingAction",
|
|
"lines": [
|
|
"UserSteppingAction(): add",
|
|
" aStep->GetTotalEnergyDeposit()",
|
|
"to EventAction's running total",
|
|
],
|
|
},
|
|
]
|
|
|
|
|
|
def main() -> None:
|
|
fig, ax = plt.subplots(figsize=(FIG_W, FIG_H))
|
|
ax.set_xlim(0, FIG_W)
|
|
ax.set_ylim(0, FIG_H)
|
|
ax.axis("off")
|
|
|
|
# Draw boxes back-to-front so inner boxes paint over parent fills.
|
|
for layer in LAYERS:
|
|
x, y, w, h = layer["rect"]
|
|
patch = FancyBboxPatch(
|
|
(x, y),
|
|
w,
|
|
h,
|
|
boxstyle="round,pad=0.05",
|
|
facecolor=layer["color"],
|
|
edgecolor="black",
|
|
linewidth=1.6,
|
|
)
|
|
ax.add_patch(patch)
|
|
|
|
# Place title + body in each layer's header strip (above the inner box).
|
|
for layer in LAYERS:
|
|
x, y, w, h = layer["rect"]
|
|
title_y = y + h - 0.45
|
|
ax.text(
|
|
x + 0.3,
|
|
title_y,
|
|
layer["title"],
|
|
ha="left",
|
|
va="center",
|
|
fontsize=12,
|
|
fontweight="bold",
|
|
)
|
|
for i, line in enumerate(layer["lines"]):
|
|
ax.text(
|
|
x + 0.45,
|
|
title_y - 0.4 - i * 0.32,
|
|
line,
|
|
ha="left",
|
|
va="center",
|
|
fontsize=10,
|
|
family="monospace",
|
|
)
|
|
|
|
ax.set_title(
|
|
"Geant4 User-Action Hierarchy in Example B1\n"
|
|
"(all classes are in namespace B1)",
|
|
fontsize=13,
|
|
fontweight="bold",
|
|
pad=10,
|
|
)
|
|
|
|
ax.text(
|
|
FIG_W / 2,
|
|
0.25,
|
|
"Each Run contains many Events; each Event contains many Steps.",
|
|
ha="center",
|
|
va="center",
|
|
fontsize=10,
|
|
style="italic",
|
|
color="#444",
|
|
)
|
|
|
|
plt.tight_layout()
|
|
fig.savefig(OUT_PATH, dpi=200, bbox_inches="tight")
|
|
print(f"Wrote {OUT_PATH}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|