Belle II Software development
MaterialRay.py
1#!/usr/bin/env python3
2
3
10
11from matplotlib import pyplot as pl
12from basf2 import logging, LogLevel, create_path, process
13from hist_utils import hist2array
14import ROOT as root
15import numpy as np
16import matplotlib as mpl
17mpl.use("Agg")
18
19# Don't show all the info messages
20logging.log_level = LogLevel.ERROR
21
22# create path
23main = create_path()
24# We need to process one event so we need the EventInfoSetter
25main.add_module("EventInfoSetter", evtNumList=[1])
26# We need the geometry parameters
27main.add_module("Gearbox")
28# as well as the geometry. We assign regions to each creator which allows to
29# split the material budget by region instead of material.
30geometry = main.add_module(
31 "Geometry",
32 logLevel=LogLevel.INFO,
33 assignRegions=True)
34# MaterialScan uses the Geant4 setup which is created by the FullSim module so
35# we need this as well
36main.add_module('FullSim')
37# And finally the MaterialScan module
38materialscan = main.add_module("MaterialScan", logLevel=LogLevel.INFO)
39materialscan.param({
40 # Filename for output File
41 'Filename': 'MaterialRay.root',
42 'spherical': False,
43 'planar': False,
44
45 'ray': True,
46 'ray.theta': 140,
47 'ray.phi': 0,
48 # Alternatively one can set the direction of the ray directly
49 # 'ray.direction': [1, 0, 0],
50 # Max depth for the scan in cm (x axis limit on the histogram). 0 = no limit
51 'ray.maxDepth': 0,
52 # Bin width (roughly) for the output histogram in cm
53 'ray.sampleDepth': 0.1,
54 # Opening angle for the rays: If <=0 only one ray is shot. Otherwise all
55 # rays will be distributed randomly in a cone with this opening angle in
56 # degrees, distributed uniformly in the area (flat in cos(theta)
57 'ray.opening': 0.05,
58 # Number of rays to shoot if opening>0
59 'ray.count': 1000,
60})
61
62# Do the MaterialScan, can take some time depending on the number of steps
63process(main)
64
65# Done, start plotting
66rmaterial_file = root.TFile("MaterialRay.root")
67
68
69def plot_hist(region, **argk):
70 """Get the histogram for a given region from the file and plot it. Return the histogram data and edges"""
71 h = rmaterial_file.Get(f"Ray/{region}_x0")
72 if not h:
73 return None
74 data, edges = hist2array(h, return_edges=True)
75 data = np.append(data, 0)
76 edges[-1][-1] = h.GetXaxis().GetXmax()
77 # now plot
78 pl.plot(edges[0], data, drawstyle="steps-post", **argk)
79 return data, edges[0]
80
81
82# Get the all materials plot:
83all_data, mat_edges = plot_hist("All_Regions", label="All regions", c="k")
84
85# Now plot the different regions separately
86for region in ["BeamPipe", "PXD", "SVD", "CDC", "ARICH", "TOP", "ECL", "EKLM", "BKLM", "STR", "COIL"]:
87 plot_hist(region, label=region)
88
89# Log scale anyone?
90# pl.yscale("log")
91pl.ylim(ymin=0)
92pl.xlim(xmin=mat_edges[0], xmax=mat_edges[-1] + 1)
93pl.xlabel("Flight length [cm]")
94pl.ylabel(f"Radiation length [$X_0 / {mat_edges[1] - mat_edges[0]:.3g}$ cm]")
95pl.legend(loc="best")
96pl.tight_layout()
97pl.savefig("MaterialRay.pdf")