LDMX Software
QIEAnalyzer.cxx
Go to the documentation of this file.
1
9
10#include <algorithm>
11#include <cmath>
12
14
15namespace trigscint {
16
17QIEAnalyzer::QIEAnalyzer(const std::string& name, framework::Process& process)
18 : Analyzer(name, process) {}
19
20void QIEAnalyzer::configure(framework::config::Parameters& parameters) {
21 input_col_ = parameters.get<std::string>("input_collection");
22 input_pass_name_ = parameters.get<std::string>("input_pass_name");
23 peds_ = parameters.get<std::vector<double> >("pedestals");
24 gain_ = parameters.get<std::vector<double> >("gain");
25 start_sample_ = parameters.get<int>("start_sample");
26 // bounded by the h_out_ array size
27 n_ev_ = std::clamp(parameters.get<int>("n_event_displays"), 0, n_ev_tdc_);
28
29 ldmx_log(trace) << "In configure(), got parameters "
30 << "\n\t inputCollection = " << input_col_
31 << "\n\t inputPassName = " << input_pass_name_
32 << "\n\t startSample = " << start_sample_
33 << "\n\t pedestals[0] = " << peds_[0]
34 << "\n\t gain[0] = " << gain_[0] << "\t.";
35
36 return;
37}
38
39void QIEAnalyzer::analyze(const framework::Event& event) {
40 const auto channels{event.getCollection<trigscint::EventReadout>(
41 input_col_, input_pass_name_)};
42
43 int ev_nb = event.getEventNumber();
44 // while (evNb < 0 ) {
45 // ldmx_log(debug) << "event number = " << evNb << " < 0; incrementing event
46 // number "; evNb++;
47 //}
48 int num_chan = channels.size();
49 ldmx_log(debug) << "in event " << ev_nb << "; num_channels = " << num_chan;
50
51 for (auto chan : channels) {
52 std::vector<float> q = chan.getQ();
53 std::vector<float> q_err = chan.getQError();
54 std::vector<int> tdc = chan.getTDC();
55 // int nTimeSamp = q.size();
56 int bar = chan.getChanID();
57 float q_tot = 0;
58 float q_ped_subtracted_avg = 0;
59 int first_t = start_sample_ - 1;
60 int n_samp_above = 0;
61 int n_samp_above_event_ped = 0;
62 float subtr_pe = 0;
63 float subtr_q = 0;
64 float ped = chan.getPedestal();
65 for (int i_t = 0; i_t < q.size(); i_t++) {
66 ldmx_log(debug) << "in event " << ev_nb << "; channel " << bar
67 << ", got charge[" << i_t << "] = " << q.at(i_t);
68 if (ev_nb < n_ev_tdc_ && bar < n_channels_) {
69 // stick within the predefined histogram array
70 const bool display{ev_nb < n_ev_};
71 // h_out_[evNb][bar]->Fill(iT+start_sample_, q.at(iT));
72 if (display) {
73 h_out_[ev_nb][bar]->SetBinContent(i_t + start_sample_, q.at(i_t));
74 h_out_[ev_nb][bar]->SetBinError(i_t + start_sample_,
75 fabs(q_err.at(i_t)));
76 }
77 if (tdc.at(i_t) < 63) {
78 ldmx_log(info) << "Found fired TDC = " << tdc.at(i_t)
79 << " at time sample " << i_t << " in channel " << bar
80 << " and event " << ev_nb;
81 // for some reason, the style settings are washed out later...
82 if (display) {
83 h_out_[ev_nb][bar]->SetLineColor(kRed + 1);
84 h_out_[ev_nb][bar]->SetMarkerColor(
85 h_out_[ev_nb][bar]->GetLineColor());
86 h_out_[ev_nb][bar]->SetMarkerSize(0.2);
87 }
88
89 if (i_t + start_sample_ > 0)
90 h_tdc_fire_chan_vs_event_->Fill(bar, ev_nb, i_t + start_sample_);
91 else
92 h_tdc_fire_chan_vs_event_->Fill(bar, ev_nb);
93 }
94 } // if within the number of events to plot individually
95 if (q.at(i_t) > 2 * fabs(peds_[bar])) {
96 // integrate all charge well above
97 // ped to convert to a PE count
98 q_tot += q.at(i_t);
99 q_ped_subtracted_avg += q.at(i_t) - chan.getPedestal();
100 // peds_[ bar ];
101 n_samp_above++;
102 ldmx_log(debug) << " above channel overall pedestal: " << q.at(i_t)
103 << " > " << 2 * fabs(peds_[bar]);
104
105 // keep track of first time sample above threshold
106 if (first_t == start_sample_ - 1) first_t = start_sample_ + i_t;
107 } // if above threshold
108 if (q.at(i_t) > ped) {
109 subtr_q += q.at(i_t) - peds_[bar];
110 n_samp_above_event_ped++;
111 ldmx_log(debug) << " above channel event pedestal: " << q.at(i_t)
112 << " > " << ped;
113 } // if above channel event pedestal
114 } // over time samples
115 float pe = q_tot * 6250. / gain_[bar];
116 subtr_pe = subtr_q * 6250. / gain_[bar];
117 h_tot_q_vs_ped_[bar]->Fill(ped, q_tot);
118 h_pe_[bar]->Fill(pe);
119 h_pe_vs_t_[bar]->Fill(first_t, pe);
120 if (n_samp_above > 0) {
121 q_ped_subtracted_avg /= n_samp_above;
122 h_ped_subtracted_avg_q_vs_t_[bar]->Fill(first_t, q_ped_subtracted_avg);
123 h_avg_q_vs_t_[bar]->Fill(first_t, q_tot / n_samp_above);
124 }
125 // if (chan.getPedestal() < 40. ) {
126 // subtrQ = subtrPE/(6250./4.e6); //undo conversion
127 ldmx_log(debug) << "filling qTot histograms";
128 h_ped_subtracted_tot_q_vs_ped_[bar]->Fill(ped, subtr_q);
129 if (ped < 40) // avoid case where we have saturation and a plateau as much
130 // as possible
131 h_ped_subtracted_tot_q_vs_n_[bar]->Fill(n_samp_above_event_ped, subtr_q);
132 h_ped_subtracted_pe_vs_n_[bar]->Fill(n_samp_above_event_ped, subtr_pe);
133 h_ped_subtracted_pe_vs_t_[bar]->Fill(first_t, subtr_pe);
134 ldmx_log(debug) << " done filling qTot histograms";
135 // }
136 } // over channels
137
138 return;
139}
140
141void QIEAnalyzer::onProcessStart() {
142 ldmx_log(trace)
143 << "\n\n Process starts! My analyzer should do something -- like "
144 "print this \n\n";
145 getHistoDirectory();
146
147 int n_time_samp = 68; // 40
148 int p_emax = 100;
149 int n_p_ebins = 5 * p_emax;
150 float qmax = p_emax / (6250. / 4.e6);
151 float qmin = -10;
152 int n_qbins = (qmax - qmin) / 4;
153
154 ldmx_log(debug) << "Setting up histograms... ";
155
156 for (int i_b = 0; i_b < n_channels_; i_b++) {
157 h_pe_[i_b] = new TH1F(Form("h_pe_chan%i", i_b), Form(";PE, chan%i", i_b),
158 n_p_ebins, 0, p_emax);
159 h_pe_vs_t_[i_b] = new TH2F(
160 Form("h_pe_vs_t__chan%i", i_b),
161 Form(";First time sample above summing threshold;PE, chan%i", i_b),
162 n_time_samp + 1, -1.5, n_time_samp - 0.5, n_p_ebins, 0, p_emax);
163 h_ped_subtracted_avg_q_vs_t_[i_b] = new TH2F(
164 Form("hPedSubtrAvgQvsT_chan%i", i_b),
165 Form(";First time sample above threshold;Pedestal subtracted average "
166 "Q, chan%i [fC]",
167 i_b),
168 n_time_samp + 1, -1.5, n_time_samp - 0.5, n_qbins / 10, qmin,
169 qmax / 10.);
170 h_ped_subtracted_tot_q_vs_ped_[i_b] =
171 new TH2F(Form("hPedSubtrTotQvsPed_chan%i", i_b),
172 Form(";Channel event pedestal [fC];Event pedestal subtracted "
173 "total Q, chan%i [fC]",
174 i_b),
175 1010, qmin, 1000, 10010, -10,
176 10000); // nQbins/2,Qmin,Qmax/5., nQbins,Qmin,2*Qmax);
177 h_ped_subtracted_tot_q_vs_n_[i_b] =
178 new TH2F(Form("hPedSubtrTotQvsN_chan%i", i_b),
179 Form(";Number of time samples added; Event pedestal "
180 "subtracted total Q, chan%i [fC]",
181 i_b),
182 n_time_samp + 1, -1.5, n_time_samp - 0.5, 10010, -10, 10000);
183 h_tot_q_vs_ped_[i_b] = new TH2F(
184 Form("h_tot_q_vs_ped__chan%i", i_b),
185 Form(";Channel event pedestal [fC];Event total Q, chan%i [fC]", i_b),
186 1010, qmin, 1000, 10010, -10,
187 10000); // nQbins/2,Qmin,Qmax/5., nQbins,Qmin,2*Qmax);
188 h_ped_subtracted_pe_vs_n_[i_b] = new TH2F(
189 Form("hPedSubtrPEvsN_chan%i", i_b),
190 Form(";Number of time samples above threshold;Pedestal "
191 "subtracted PE, chan%i [fC]",
192 i_b),
193 n_time_samp + 1, -1.5, n_time_samp - 0.5, n_p_ebins, 0, p_emax);
194 h_ped_subtracted_pe_vs_t_[i_b] = new TH2F(
195 Form("hPedSubtrPEvsT_chan%i", i_b),
196 Form(";First time sample above threshold;Pedestal subtracted "
197 "PE, chan%i [fC]",
198 i_b),
199 n_time_samp + 1, -1.5, n_time_samp - 0.5, n_p_ebins, 0, p_emax);
200 h_avg_q_vs_t_[i_b] = new TH2F(
201 Form("h_avg_q_vs_t_chan%i", i_b),
202 Form(";First time sample above threshold;Average Q, chan%i [fC]", i_b),
203 n_time_samp + 1, -1.5, n_time_samp - 0.5, n_qbins / 10, qmin,
204 qmax / 10);
205 }
206
207 for (int i_e = 0; i_e < n_ev_; i_e++) {
208 for (int i_b = 0; i_b < n_channels_; i_b++) {
209 h_out_[i_e][i_b] =
210 new TH1F(Form("hCharge_chan%i_ev%i", i_b, i_e),
211 Form(";time sample; Q, channel %i, event %i [fC]", i_b, i_e),
212 n_time_samp, -0.5, n_time_samp - 0.5);
213 }
214 }
215
216 h_tdc_fire_chan_vs_event_ = new TH2F(
217 "h_tdc_fire_chan_vs_event", ";channel with TDC < 63;event number",
218 n_channels_, -0.5, n_channels_ - 0.5, n_ev_tdc_, 0, n_ev_tdc_);
219
220 ldmx_log(debug) << "done setting up histograms";
221
222 return;
223}
224
225void QIEAnalyzer::onProcessEnd() { return; }
226
227} // namespace trigscint
228
#define DECLARE_ANALYZER(CLASS)
Macro which allows the framework to construct an analyzer given its name during configuration.
Class that stores full reconstructed (linearized) readout QIE sample from the TS.
Implements an event buffer system for storing event data.
Definition Event.h:40
Class which represents the process under execution.
Definition Process.h:34
Class encapsulating parameters for configuring a processor.
Definition Parameters.h:26
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:75
This class represents the linearised QIE output from the trigger scintillator, in charge (fC).