Warning, /epic/bin/g4MaterialScan_raw_plot is written in an unsupported language. File is not indexed.
0001 #!/usr/bin/env python3
0002
0003 # SPDX-License-Identifier: LGPL-3.0-or-later
0004 # Copyright (C) 2024 Chao Peng
0005 '''
0006 A script to plot raw data output from the script g4MaterialScan_to_csv
0007 '''
0008
0009 import os
0010 import re
0011 import argparse
0012 import pandas as pd
0013 import numpy as np
0014 from matplotlib import pyplot as plt
0015 from matplotlib.ticker import AutoMinorLocator
0016
0017
0018 if __name__ == '__main__':
0019 parser = argparse.ArgumentParser(
0020 prog='g4MaterialScan_raw_plot',
0021 description = 'A python script to draw material thickness from raw output of g4MaterialScan_to_csv.'
0022 )
0023 parser.add_argument(
0024 'data_path',
0025 help='path to the raw data from scan (a csv file).'
0026 )
0027 parser.add_argument(
0028 '--path-lengths', default="0, 180, 600",
0029 help='path length points, separated by \",\".'
0030 )
0031 parser.add_argument(
0032 '--sep', default='\t',
0033 help='Seperator for the CSV file.'
0034 )
0035 parser.add_argument(
0036 '--font-size', type=float, default=18.,
0037 help='Font size of the plots.'
0038 )
0039 args = parser.parse_args()
0040
0041 # get the path length points
0042 pls = np.array([float(x.strip()) for x in args.path_lengths.split(',')])
0043 if len(pls) < 2:
0044 print('Need at least two points in --path-lengths')
0045 exit(-1)
0046
0047 # determine the eta and phi from path
0048 eta, phi = 0., 0.
0049 try:
0050 match = re.search(r'eta=([\d\-\.]*\d).*phi=([\d\-\.]*\d)', args.data_path)
0051 eta = float(match[1])
0052 phi = float(match[2])
0053 except:
0054 print('WARNING: Fail to determine eta, phi from data path, information may be incorrect.')
0055
0056 # read and process data
0057 df = pd.read_csv(args.data_path, sep=args.sep, index_col=0)
0058 df.loc[:, 'X0_cum'] = df['X0'].cumsum()
0059 df.loc[:, 'lambda_cum'] = df['lambda'].cumsum()
0060 # print(df)
0061
0062 # font size and colors
0063 fs = args.font_size
0064 prop_cycle = plt.rcParams['axes.prop_cycle']
0065 colors = prop_cycle.by_key()['color']
0066
0067 # plot X0 and lambda in the path length intervals [pl(i), pl(i+1)]
0068 fig, axs = plt.subplots(1, len(pls) - 1, figsize=(8 * (len(pls) - 1), 6), dpi=160,
0069 gridspec_kw=dict(left=0.1, right=0.92, top=0.95, wspace=0.4))
0070 for i, ax in enumerate(axs.flat):
0071 min_pl, max_pl = pls[i], pls[i + 1]
0072
0073 dfr = df[(df['path_length'] <= max_pl) & (df['path_length'] >= min_pl)]
0074 # X0
0075 ax.step(df['path_length'], df['X0_cum'], color=colors[0])
0076
0077 # lambda
0078 ax2 = ax.twinx()
0079 ax2.step(df['path_length'], df['lambda_cum'], color=colors[1], ls='--')
0080
0081
0082 ax.text(0.05, 0.95, r'$\eta={:.3f}, \phi={:.3f}^{{\circ}}$'.format(eta, phi),
0083 fontsize=fs, color=colors[2],
0084 horizontalalignment='left', verticalalignment='top', transform=ax.transAxes)
0085 # axis format
0086 ax.set_xlabel('Path Length [cm]', fontsize=fs)
0087 ax.set_ylabel('$X/X_0$ (Cumulative)', fontsize=fs, color=colors[0])
0088 ax2.set_ylabel('$\Lambda$ (Cumulative)', fontsize=fs, color=colors[1])
0089 ax.xaxis.set_minor_locator(AutoMinorLocator(5))
0090 ax.yaxis.set_minor_locator(AutoMinorLocator(5))
0091 ax2.yaxis.set_minor_locator(AutoMinorLocator(5))
0092 ax.set_xlim(min_pl, max_pl)
0093 ax.set_ylim(0, dfr['X0_cum'].max()*1.1)
0094 ax2.set_ylim(0, dfr['lambda_cum'].max()*1.1)
0095 ax.tick_params(direction='in', which='both', labelsize=fs)
0096 ax2.tick_params(direction='in', which='both', labelsize=fs)
0097 ax.grid(which='major', ls=':')
0098 ax.set_axisbelow(True)
0099 # save the plot with the same name
0100 save_path = '.'.join(args.data_path.split('.')[:-1]) + '.png'
0101 fig.savefig(save_path)
0102 print('Plot saved as \"{}\"'.format(save_path))