diff --git a/current/cal_current.py b/current/cal_current.py index 41901c9d323c31711453bfa3ed9c4b39ab0624af..b9b6c88cd5ff0be24612bdc5a43084e375817d92 100644 --- a/current/cal_current.py +++ b/current/cal_current.py @@ -513,11 +513,11 @@ class CalCurrentLaser(CalCurrent): convolved_gain_negative_cu.Reset() convolved_sum_cu.Reset() - signal_convolution(self.positive_cu[i],my_l.timePulse,convolved_positive_cu) - signal_convolution(self.negative_cu[i],my_l.timePulse,convolved_negative_cu) - signal_convolution(self.gain_positive_cu[i],my_l.timePulse,convolved_gain_positive_cu) - signal_convolution(self.gain_negative_cu[i],my_l.timePulse,convolved_gain_negative_cu) - signal_convolution(self.sum_cu[i],my_l.timePulse,convolved_sum_cu) + signal_convolution(self.positive_cu[i],convolved_positive_cu,[my_l.timePulse]) + signal_convolution(self.negative_cu[i],convolved_negative_cu,[my_l.timePulse]) + signal_convolution(self.gain_positive_cu[i],convolved_gain_positive_cu,[my_l.timePulse]) + signal_convolution(self.gain_negative_cu[i],convolved_gain_negative_cu,[my_l.timePulse]) + signal_convolution(self.sum_cu[i],convolved_sum_cu,[my_l.timePulse]) self.positive_cu[i] = convolved_positive_cu self.negative_cu[i] = convolved_negative_cu diff --git a/elec/readout.py b/elec/readout.py index cc11a57fe59a23a92500bfd34b2507892a35f427..fe079a6b1f603231e3531ee8b1a3c0862f027724 100644 --- a/elec/readout.py +++ b/elec/readout.py @@ -17,8 +17,6 @@ import ROOT from util.math import signal_convolution from util.output import output -time_step = 50e-12 - class Amplifier: """Get current after amplifier with convolution, for each reading electrode @@ -33,9 +31,6 @@ class Amplifier: CDet : None | float The capacitance of the detector - time_step : float - The readout time step (bin width) - Attributes --------- amplified_current : list[ROOT.TH1F] @@ -56,7 +51,7 @@ class Amplifier: --------- 2024/09/14 """ - def __init__(self, currents: list[ROOT.TH1F], amplifier_name: str, CDet = None, time_step = time_step): + def __init__(self, currents: list[ROOT.TH1F], amplifier_name: str, CDet = None): self.amplified_current = [] ele_json = "./setting/electronics/" + amplifier_name + ".json" @@ -67,7 +62,7 @@ class Amplifier: self.read_ele_num = len(currents) self.amplifier_define(CDet) - self.fill_amplifier_output(currents, time_step) + self.fill_amplifier_output(currents) self.set_scope_output(currents) def amplifier_define(self, CDet): @@ -118,7 +113,7 @@ class Amplifier: return scale - self.pulse_responce = pulse_responce_CSA + self.pulse_responce_list = [pulse_responce_CSA] self.scale = scale_CSA elif self.amplifier_parameters['ele_name'] == 'BB': @@ -143,7 +138,7 @@ class Amplifier: elif mode == "RC": tau_BB_RC = 1.0e-12 * BB_imp * CDet #BB RC - tau_BB_BW = 0.35 / (1.0e9*BB_bandwidth) / 2.2 #BB Tau + tau_BB_BW = 0.35 / (1.0e9*BB_bandwidth) / 2.2 #BB Tau, Rf*Cf? tau_BBA = math.sqrt(pow(tau_BB_RC,2)+pow(tau_BB_BW,2)) return 1/tau_BBA * math.exp(-t/tau_BBA) @@ -159,22 +154,46 @@ class Amplifier: return R_in elif mode == "RC": - BBGain = self.amplifier_parameters['BBGain'] - return BBGain * 1e3 + BB_Gain = self.amplifier_parameters['BB_Gain'] # kOhm ? + return BB_Gain * 1e3 - self.pulse_responce = pulse_responce_BB + self.pulse_responce_list = [pulse_responce_BB] self.scale = scale_BB - def fill_amplifier_output(self, currents: list[ROOT.TH1F], time_step): + elif self.amplifier_parameters['ele_name'] == 'ABCStar': + """ ABCStar parameter initialization""" + + def pulse_responce_ABCStar_input(t): + if t < 0: + return 0 + input_res = self.amplifier_parameters['input_res'] + return 1/(1e-12*CDet) * math.exp(-t/(1e-12*CDet*input_res)) + + def pulse_responce_ABCStar_RCfeedback(t): + if t < 0: + return 0 + input_res = self.amplifier_parameters['input_res'] + Cf = self.amplifier_parameters['Cf'] + Rf = self.amplifier_parameters['Rf'] + tau_amp = 1e-12 * Cf * input_res + tau_f = 1e-12 * Cf * Rf + return 1/tau_amp * math.exp(-t/tau_f) + + def scale_ABCStar(output_Q_max, input_Q_tot): + """ ABCStar scale function""" + return 1000.0 # V to mV + + self.pulse_responce_list = [pulse_responce_ABCStar_input, pulse_responce_ABCStar_RCfeedback] + self.scale = scale_ABCStar + + + def fill_amplifier_output(self, currents: list[ROOT.TH1F]): for i in range(self.read_ele_num): cu = currents[i] - n_bin = cu.GetNbinsX() - t_bin = cu.GetBinWidth(0) - time_duration = n_bin * t_bin self.amplified_current.append(ROOT.TH1F("electronics %s"%(self.amplified_current_name)+str(i+1), "electronics %s"%(self.amplified_current_name), - int(time_duration/time_step), 0, time_duration)) + cu.GetNbinsX(),cu.GetXaxis().GetXmin(),cu.GetXaxis().GetXmax())) self.amplified_current[i].Reset() - signal_convolution(cu, self.pulse_responce, self.amplified_current[i]) + signal_convolution(cu, self.amplified_current[i], self.pulse_responce_list) def set_scope_output(self, currents: list[ROOT.TH1F]): for i in range(self.read_ele_num): @@ -186,10 +205,10 @@ class Amplifier: def main(label): '''main function for readout.py to test the output of the given amplifier''' - my_th1f = ROOT.TH1F("my_th1f", "my_th1f", 200, 0, 10e-9) + my_th1f = ROOT.TH1F("my_th1f", "my_th1f", 600, 0, 30e-9) # input signal: square pulse for i in range(21, 41): - my_th1f.SetBinContent(i, 1e-5) + my_th1f.SetBinContent(i, 2e-6) # A ele = Amplifier([my_th1f], label) @@ -198,6 +217,8 @@ def main(label): origin_max = my_th1f.GetMaximum() amp_max = ele.amplified_current[0].GetMaximum() + print("amp_max =",amp_max,'mV') + ratio = origin_max/amp_max ele.amplified_current[0].Scale(ratio) ele.amplified_current[0].Draw("SAME HIST") diff --git a/util/math.py b/util/math.py index 017a5bb532e32ce4196b34b60144e0fd45f095eb..1d8c72aefeea4ec435fd98b9b98bd4ed7b60af6e 100644 --- a/util/math.py +++ b/util/math.py @@ -10,6 +10,7 @@ Description: ''' import math +from typing import Callable import numpy as np from scipy.interpolate import interp1d as p1d @@ -97,14 +98,24 @@ def get_common_interpolate_3d(data): return lndi(point) return f -def signal_convolution(signal_original: ROOT.TH1F, pulse_responce_function, signal_convolved: ROOT.TH1F): +def signal_convolution(signal_original: ROOT.TH1F, signal_convolved: ROOT.TH1F, pulse_responce_function_list: list[Callable[[float],float]]): so = signal_original - pr = pulse_responce_function sc = signal_convolved + st = ROOT.TH1F("signal_temp","signal_temp",so.GetNbinsX(),so.GetXaxis().GetXmin(),so.GetXaxis().GetXmax()) + st.Reset() + st.Add(so) + t_bin = so.GetBinWidth(0) # for uniform bin n_bin = so.GetNbinsX() - for i in range(n_bin): - so_i = so.GetBinContent(i) - for j in range(-i,n_bin-i): - pr_j = pr(j*t_bin) - sc.Fill((i+j)*t_bin + 1e-14, so_i*pr_j*t_bin) # 1e-14 resolves float error + for pr in pulse_responce_function_list: + for i in range(n_bin): + st_i = st.GetBinContent(i) + for j in range(-i,n_bin-i): + pr_j = pr(j*t_bin) + sc.Fill((i+j)*t_bin + 1e-14, st_i*pr_j*t_bin) # 1e-14 resolves float error + st.Reset() + st.Add(sc) + sc.Reset() + + sc.Add(st) +