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