Files
geant4/examples/extended/exoticphysics/channeling/ch2/analysis_ch2.py
T
2024-12-06 11:11:40 +01:00

114 lines
3.8 KiB
Python
Executable File

#!/usr/bin/env python
# coding: utf-8
# Read and plot the simulation results of particle interactions in Oriented Crystals
# obatined through example ch2, which is baed on G4ChannelingFastSimModel.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import os
import uproot
################################### INPUT ############################################
# Set path and filename of the simulation file
G4_sim_path = ""
root_file = "results"
Nmax = 1e5 #max number of events to elaborate
save_fig = True
fig_path = G4_sim_path
apply_collimation = False
coll_angle = 20/8627 #rad
NbinE = 25
rangeE = [0, 10] #MeV
NbinTheta = 100
rangeTheta = [-1, 2] #mrad
######################################################################################
# Create figure directory if it does not exist
if fig_path != '' and not os.path.exists(fig_path):
os.makedirs(fig_path)
print('created fig_path:', fig_path)
# Open the simulation output root file
rf = uproot.open(G4_sim_path + root_file + '.root')
rf_content = [item.split(';')[0] for item in rf.keys()]
print('rf_content:', rf_content, '\n')
# Import the scoring ntuples and convert them into pandas dataframes
branches = ["eventID", "volume", "x", "y", "angle_x", "angle_y",
"Ekin" , "particle", "particleID", "parentID"]
df_in = rf['crystal'].arrays(branches, library='pd')
df_out = rf['detector'].arrays(branches, library='pd')
df_ph = rf['detector_photons'].arrays(branches, library='pd')
# Define in and out dataframes
df_in_all_primary = df_in[df_in.parentID == 0]
df_out_all_primary = df_out[df_out.parentID == 0]
Nmax = min([int(Nmax), len(df_out_all_primary)])
df_in_primary = df_in_all_primary[:Nmax]
df_out_primary = df_out_all_primary[:Nmax]
# Select only the columns useful for deflection
df_in_primary_sel = df_in_primary[["eventID", "angle_x", "angle_y"]]
df_out_primary_sel = df_out_primary[["eventID", "angle_x", "angle_y"]]
del df_in_primary, df_out_primary
# Array with photon energies and angles
Eph = df_ph['Ekin'].values #MeV
Nph = len(Eph)
print("number of emitted photons:", Nph)
thetaX_ph = df_ph['angle_x'].values*1e3 #rad -> mrad
thetaY_ph = df_ph['angle_y'].values*1e3 #rad -> mrad
# Take only the photons inside the collimator acceptance
theta_ph = np.sqrt(thetaX_ph**2 + thetaY_ph**2)
if apply_collimation:
thetaX_ph = thetaX_ph[theta_ph <= coll_angle]
thetaY_ph = thetaY_ph[theta_ph <= coll_angle]
Eph = Eph[theta_ph <= coll_angle]
theta_ph = theta_ph[theta_ph <= coll_angle]
# Calculate the scored photon energy spectrum
spectrum, EbinEdges = np.histogram(Eph, bins=NbinE, range=rangeE, density=True)
Ebin = EbinEdges[:-1] + (EbinEdges[1]-EbinEdges[0])*0.5
spectral_intensity = Ebin * spectrum
# Plot the photon energy spectrum
fig = plt.figure(figsize=(13, 6))
fs = 16
lw = 2
bw = 0.6
plt.subplot(1,2,1)
plt.bar(Ebin, spectrum, width=bw, linewidth=lw, alpha=1, label='')
plt.title('Emitted photon spectrum')
plt.xlabel('E [MeV]', fontsize=fs)
plt.ylabel('1/N$\\times$dN/dE', fontsize=fs)
plt.yscale('log')
plt.subplot(1,2,2)
plt.bar(Ebin, spectral_intensity, width=bw, linewidth=lw, alpha=1, label='')
plt.title('Emitted photon spectral intensity')
plt.xlabel('E [MeV]', fontsize=fs)
plt.ylabel('1/N$\\times$dW/dE', fontsize=fs)
plt.yscale('log')
if save_fig:
plt.savefig(fig_path + 'spectrum.jpg')
plt.close()
# Plot angle_x distribution at the detector
thetaXdistrib, thetaEdges = np.histogram(df_out_primary_sel["angle_x"].values*1e3, \
bins=NbinTheta, range=rangeTheta, density=True)
thetabin = thetaEdges[:-1] + (thetaEdges[1]-thetaEdges[0])*0.5
plt.figure(figsize=(9, 6))
plt.plot(thetabin, thetaXdistrib, linewidth=lw, alpha=1, label='')
plt.xlabel('$\\theta_X$ [mrad]', fontsize=fs)
plt.ylabel('1/N$\\times$dN/d$\\theta_X$', fontsize=fs)
if save_fig:
plt.savefig(fig_path + 'thetaXdistribution.jpg')
plt.close()