Skip to content
Snippets Groups Projects
extract_multi_x0.py 4.52 KiB
Newer Older
import numpy as np
import matplotlib.pyplot as plt
import os
import argparse

def extract_x0_values(filename):
    """Extract x0 values from a single file"""
    x0_values = []
    counter = 0
    with open(filename, 'r') as file:
        for line in file:
            if '|     0 Average Material' in line:
                counter += 1
                items = [item.strip() for item in line.split('|')]
                x0_value = float(items[1].split()[10])
                x0_values.append(x0_value)
                print(f"Processing file {filename}: ", counter, " x0: ", x0_value)
    return x0_values

def process_multiple_files(file_list, bins, bias):
    """Process multiple files and return their x0 matrices"""
    theta_bins = bins + 1
    phi_bins = bins*2 + 1
    range_theta = [bias, theta_bins-bias]
    
    matrices = []
    for file in file_list:
        x0_values = extract_x0_values(file)
        x0_matrix = np.array(x0_values).reshape(theta_bins, phi_bins)[range_theta[0]:range_theta[1], :]
        matrices.append(x0_matrix)
    
    return matrices

def plot_accumulated_projections(matrices, output_file, bins, bias, labels):
    """Plot accumulated projections"""
    theta_bins = bins + 1
    phi_bins = bins*2 + 1
    range_theta = [bias, theta_bins-bias]
    
    # Create angle arrays
    phi = np.linspace(-180, 180, phi_bins)
    theta = np.linspace(range_theta[0]*180/theta_bins, range_theta[1]*180/theta_bins, range_theta[1]-range_theta[0])
    
    # Create figure
    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(20, 8))
    
    # Accumulation data
    accumulated_theta = np.zeros_like(theta)
    accumulated_phi = np.zeros_like(phi)
    
    colors = plt.cm.viridis(np.linspace(0, 1, len(matrices)))
    
    # Plot phi projection
    for i, matrix in enumerate(matrices):
        phi_projection = np.sum(matrix, axis=0) / (range_theta[1]-range_theta[0])
        accumulated_phi += phi_projection
        ax1.fill_between(phi, accumulated_phi, accumulated_phi - phi_projection, 
                        label=labels[i], color=colors[i], alpha=0.6)
    
    # Plot theta projection
    for i, matrix in enumerate(matrices):
        theta_projection = np.sum(matrix, axis=1) / phi_bins
        accumulated_theta += theta_projection
        ax2.fill_between(theta, accumulated_theta, accumulated_theta - theta_projection,
                        label=labels[i], color=colors[i], alpha=0.6)
    
    # Set phi projection plot
    ax1.set_title('Accumulated Projection along Phi', fontsize=14, pad=10)
    ax1.set_xlabel('Phi (degree)', fontsize=12)
    ax1.set_ylabel('Accumulated X/X0', fontsize=12)
    ax1.grid(True, linestyle='--', alpha=0.7)
    ax1.legend(fontsize=10)
    ax1.spines['top'].set_visible(False)
    ax1.spines['right'].set_visible(False)
    
    # Set theta projection plot
    ax2.set_title('Accumulated Projection along Theta', fontsize=14, pad=10)
    ax2.set_xlabel('Theta (degree)', fontsize=12)
    ax2.set_ylabel('Accumulated X/X0', fontsize=12)
    ax2.grid(True, linestyle='--', alpha=0.7)
    ax2.legend(fontsize=10)
    ax2.spines['top'].set_visible(False)
    ax2.spines['right'].set_visible(False)
    
    plt.suptitle('Detector Material Budget Accumulation Analysis', fontsize=16, y=0.95)
    plt.tight_layout()
    
    plt.savefig(output_file, dpi=600, bbox_inches='tight')
    plt.show()

def main():
    parser = argparse.ArgumentParser(description='Process multiple material scan data and generate accumulated distribution plots.')
    parser.add_argument('--input_files', nargs='+', required=True,
                        help='List of input files in order')
    parser.add_argument('--labels', nargs='+', required=True,
                        help='Labels for each input file')
    parser.add_argument('--output_file', default='accumulated_material_budget.png',
                        help='Output PNG file path')
    parser.add_argument('--bins', type=int, default=100,
                        help='theta bins is "bins"+1, phi bins is "bins"*2+1, (default: 100)')
    parser.add_argument('--bias', type=int, default=0,
                        help='Bias value for theta range (default: 0)')
    
    args = parser.parse_args()
    
    if len(args.input_files) != len(args.labels):
        raise ValueError("Number of input files must match number of labels!")
    
    # Process all input files
    matrices = process_multiple_files(args.input_files, args.bins, args.bias)
    
    # Plot accumulated graphs
    plot_accumulated_projections(matrices, args.output_file, args.bins, args.bias, args.labels)

if __name__ == '__main__':
    main()