import ROOT
import numpy as np
Crystal Ball function for PDF
def pdf(x, para):
A, mean, sigmaL, alphaL, sigmaR, alphaR = para
x = np.asarray(x)
if x.ndim == 0:
x = np.array([x])
answer = np.zeros(x.shape)
left = x < mean
right = np.logical_not(left)
top = np.square(x - mean)
bottomL = 2 * (sigmaL * sigmaL + alphaL * top[left])
bottomR = 2 * (sigmaR * sigmaR + alphaR * top[right])
answer[left] = A * np.exp(-np.divide(top[left], bottomL))
answer[right] = A * np.exp(-np.divide(top[right], bottomR))
return answer
Function to guess initial parameters
def popt_guesses(bin_centers, bin_heights, prev_guess):
mean_guess = bin_centers[np.argmax(bin_heights)]
sigma_guess = np.sqrt(np.average((bin_centers - mean_guess) ** 2, weights=bin_heights))
sigmaL_guess = sigma_guess
sigmaR_guess = sigma_guess
if prev_guess is None:
alphaL_guess = 0.07 # Adjusted from 7e-2 to 0.07
alphaR_guess = 0.07
else:
alphaL_guess = prev_guess[3]
alphaR_guess = prev_guess[5]
A_guess = np.max(bin_heights) / pdf(0, [1, mean_guess, sigmaL_guess, alphaL_guess, sigmaR_guess, alphaR_guess])
p0 = [A_guess[0], mean_guess, sigmaL_guess, alphaL_guess, sigmaR_guess, alphaR_guess]
return p0
Function to fit histograms
def fit_histograms(input_file_name, output_file_name, output_txt_file):
# Open the input ROOT file
input_file = ROOT.TFile(input_file_name, “READ”)
if input_file.IsZombie():
print(f"Error: Could not open the input file {input_file_name}")
return
# Create a canvas for drawing
canvas = ROOT.TCanvas("canvas", "canvas", 800, 600)
# Prepare the output text file
with open(output_txt_file, 'w') as txt_file:
# Write header
txt_file.write("bin_low bin_high mean sigma mean_error sigma_error\n")
# Get list of keys in the input file
keys = input_file.GetListOfKeys()
# Loop over all keys in the file
for key in keys:
obj = key.ReadObj()
# Check if the object is a histogram and has the expected name format
if isinstance(obj, ROOT.TH1) and obj.GetName().startswith("response_"):
# Extract bin centers and heights
bin_centers = np.array([obj.GetBinCenter(i) for i in range(1, obj.GetNbinsX() + 1)])
bin_heights = np.array([obj.GetBinContent(i) for i in range(1, obj.GetNbinsX() + 1)])
p0 = popt_guesses(bin_centers, bin_heights, None)
# Create a TF1 object for fitting
fit_func = ROOT.TF1("fit_func", pdf, bin_centers[0], bin_centers[-1], len(p0))
for i, p in enumerate(p0):
fit_func.SetParameter(i, p)
# Perform the fit
fit_result = obj.Fit("fit_func", "S")
# Extract the fitted parameters and their errors
popt = [fit_func.GetParameter(i) for i in range(len(p0))]
perr = [fit_func.GetParError(i) for i in range(len(p0))]
# Extract bin range from histogram name
name_parts = obj.GetName().split('_')
bin_low = float(name_parts[1])
bin_high = float(name_parts[2])
# Write the results to the text file
txt_file.write(f"{bin_low} {bin_high} {popt[1]} {popt[2]} {perr[1]} {perr[2]}\n")
# Write the histogram to the output ROOT file
output_file.cd()
obj.Write()
# Draw the histogram and fit result on the canvas
obj.Draw()
fit_func.Draw("same")
# Save the canvas as an image file
image_file_name = f"{obj.GetName()}.png"
canvas.SaveAs(image_file_name)
# Close the input and output ROOT files
input_file.Close()
output_file.Close()
if name == “main”:
import sys
if len(sys.argv) != 4:
print("Usage: python fit_histograms.py <input_file> <output_file> <output_txt_file>")
sys.exit(1)
input_file_name = sys.argv[1]
output_file_name = sys.argv[2]
output_txt_file = sys.argv[3]
# Create the output ROOT file
output_file = ROOT.TFile(output_file_name, "RECREATE")
if output_file.IsZombie():
print(f"Error: Could not create the output file {output_file_name}")
sys.exit(1)
fit_histograms(input_file_name, output_file_name, output_txt_file)
print(f"Results written to {output_txt_file}")
this is the error
Traceback (most recent call last):
File “/Users/gursharansingh/Desktop/project/fit_with_cruijff.py”, line 128, in
fit_histograms(input_file_name, output_file_name, output_txt_file)
File “/Users/gursharansingh/Desktop/project/fit_with_cruijff.py”, line 80, in fit_histograms
fit_result = obj.Fit(“fit_func”, “S”)
^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: none of the 2 overloaded methods succeeded. Full details:
TFitResultPtr TH1::Fit(TF1* f1, const char* option = “”, const char* goption = “”, double xmin = 0, double xmax = 0) =>
TypeError: could not convert argument 1
TFitResultPtr TH1::Fit(const char* formula, const char* option = “”, const char* goption = “”, double xmin = 0, double xmax = 0) =>
AbortSignal: abort from C++; program state was reset
(myrootwork) gursharansingh@Gursharans-MacBook-Air project % python3 fit_with_cruijff.py response_histograms.root hello.root hello.txt
Traceback (most recent call last):
File “/Users/gursharansingh/Desktop/project/fit_with_cruijff.py”, line 128, in
fit_histograms(input_file_name, output_file_name, output_txt_file)
File “/Users/gursharansingh/Desktop/project/fit_with_cruijff.py”, line 75, in fit_histograms
fit_func = ROOT.TF1(“fit_func”, pdf(), bin_centers[0], bin_centers[-1], len(p0))
^^^^^
TypeError: pdf() missing 2 required positional arguments: ‘x’ and ‘para’