LDMX Software
QualityFlagAnalyzer.cxx
Go to the documentation of this file.
1
9
10#include <cmath>
11
14
15namespace trigscint {
16
17QualityFlagAnalyzer::QualityFlagAnalyzer(const std::string& name,
18 framework::Process& process)
19 : Analyzer(name, process) {}
20
21void QualityFlagAnalyzer::configure(framework::config::Parameters& parameters) {
22 input_event_col_ = parameters.get<std::string>("input_event_collection");
23 input_event_pass_name_ = parameters.get<std::string>("input_event_pass_name");
24 input_hit_col_ = parameters.get<std::string>("input_hit_collection");
25 input_hit_pass_name_ = parameters.get<std::string>("input_hit_pass_name");
26 peds_ = parameters.get<std::vector<double> >("pedestals");
27 gain_ = parameters.get<std::vector<double> >("gain");
28 start_sample_ = parameters.get<int>("start_sample");
29
30 std::cout << " [ QualityFlagAnalyzer ] In configure(), got parameters "
31 << "\n\t inputEventCollection = " << input_event_col_
32 << "\n\t inputEventPassName = " << input_event_pass_name_
33 << "\n\t inputHitCollection = " << input_hit_col_
34 << "\n\t inputHitPassName = " << input_hit_pass_name_
35 << "\n\t startSample = " << start_sample_
36 << "\n\t pedestals[0] = " << peds_[0]
37 << "\n\t gain[0] = " << gain_[0] << "\t." << std::endl;
38
39 return;
40}
41
42void QualityFlagAnalyzer::analyze(const framework::Event& event) {
43 const auto channels{event.getCollection<trigscint::EventReadout>(
44 input_event_col_, input_event_pass_name_)};
45 const auto hits{event.getCollection<trigscint::TestBeamHit>(
46 input_hit_col_, input_hit_pass_name_)};
47
48 int ev_nb = event.getEventNumber();
49 // while (evNb < 0 ) {
50 // ldmx_log(debug) << "event number = " << evNb << " < 0; incrementing event
51 // number "; evNb++;
52 //}
53 int n_chan = channels.size();
54 ldmx_log(debug) << "in event " << ev_nb << "; n_channels_ = " << n_chan;
55
56 bool exists_intermediate_pe = false;
57 float hit_pes[N_CHANNELS] = {0.};
58
59 // ok. get each channel, and find the associated hit, using bar nb.
60
61 for (auto chan : channels) {
62 std::vector<float> q = chan.getQ();
63 std::vector<float> q_err = chan.getQError();
64 std::vector<int> tdc = chan.getTDC();
65 // int nTimeSamp = q.size();
66 int bar = chan.getChanID();
67
68 int flag = chan.getQualityFlag();
69
70 // check if this is messing up flag
71 for (auto hit : hits) { // we will be ok even if there is no match
72 if (hit.getBarID() == bar) {
73 flag = hit.getQualityFlag();
74 hit_pes[bar] = hit.getPE();
75 if (flag == 0 && bar < 12 && 15 < hit.getPE() && hit.getPE() < 40)
76 exists_intermediate_pe = true;
77 }
78 }
79
80 ldmx_log(debug) << "Got event flag " << flag;
81
82 // if flag = 0, fill for clean versions of the usual event displays
83 if (flag == 0 && ev_nb < n_ev_ &&
84 bar < N_CHANNELS) { // stick within the predefined histogram array
85 for (int i_t = 0; i_t < q.size(); i_t++) {
86 ldmx_log(debug) << "in event " << ev_nb << "; channel " << bar
87 << ", got charge[" << i_t << "] = " << q.at(i_t);
88 h_out_[ev_nb][bar]->SetBinContent(i_t + start_sample_, q.at(i_t));
89 h_out_[ev_nb][bar]->SetBinError(i_t + start_sample_,
90 fabs(q_err.at(i_t)));
91 } // if within the number of events to plot individually
92 } // over time samples
93
94 // now select on flags_
95 // special case: flag = 0 (this will happen to all eventually, so catch it
96 // now
97 if (flag == 0 && n_ev_drawn_[n_flags_ - 1] < n_ev_) {
98 // then draw if we haven't collected enough
99 int fill_nb = n_ev_drawn_[n_flags_ - 1];
100 for (int i_t = 0; i_t < q.size(); i_t++) { // fill this plot with all q
101 h_out_flag_[n_flags_ - 1][fill_nb][bar]->SetBinContent(
102 i_t + start_sample_, q.at(i_t));
103 h_out_flag_[n_flags_ - 1][fill_nb][bar]->SetBinError(
104 i_t + start_sample_, fabs(q_err.at(i_t)));
105 }
106 // keep track of actual event number
107 h_out_flag_[n_flags_ - 1][fill_nb][bar]->GetYaxis()->SetTitle(
108 Form("Q, flag 0, chan %i, ev %i [fC]", bar, ev_nb));
109 n_ev_drawn_[n_flags_ -
110 1]++; // update filled event counter for this flag (0)
111 } // if nothing was flagged
112 else { // hit was flagged somehow
113 for (int i_f = 0; i_f < n_flags_ - 1; i_f++) { // do all but the last
114 int fill_nb = n_ev_drawn_[i_f];
115 ldmx_log(debug) << "Checking flag " << flags_[i_f];
116 // we're starting from the high numbers and iteratively subtracting
117 if (flag >= flags_[i_f]) {
118 ldmx_log(debug) << "Checking flag " << flags_[i_f];
119 if (fill_nb < n_ev_) { // then 1. this flag must be raised 2. draw if
120 // we haven't collected enough
121 for (int i_t = 0; i_t < q.size();
122 i_t++) { // fill this plot with all
123 // q
124 h_out_flag_[i_f][fill_nb][bar]->SetBinContent(i_t + start_sample_,
125 q.at(i_t));
126 h_out_flag_[i_f][fill_nb][bar]->SetBinError(i_t + start_sample_,
127 fabs(q_err.at(i_t)));
128 } // over time samples
129 h_out_flag_[i_f][fill_nb][bar]->GetYaxis()->SetTitle(Form(
130 "Q, flag %i, chan %i, ev %i [fC]", flags_[i_f], bar, ev_nb));
131 n_ev_drawn_[i_f]++; // update filled event counter for this flag
132 }
133 flag -= flags_[i_f]; // subtract that flag from sum
134 } // if this flag
135 } // over flags_
136 } // if any non-zero flag
137 } // over channels
138
139 // select 15 < PE < 40 events
140 if (exists_intermediate_pe && pe_fill_nb_ < n_ev_) {
141 // then 1. this flag must be raised 2. draw if we
142 // haven't collected enough
143 ldmx_log(debug) << "Got at least one intermediate PE channel";
144 for (auto chan : channels) {
145 std::vector<float> q = chan.getQ();
146 std::vector<float> q_err = chan.getQError();
147 std::vector<int> tdc = chan.getTDC();
148 // int nTimeSamp = q.size();
149 int bar = chan.getChanID();
150 for (int i_t = 0; i_t < q.size(); i_t++) { // fill this plot with all q
151 h_out_pe_[pe_fill_nb_][bar]->SetBinContent(i_t + start_sample_,
152 q.at(i_t));
153 h_out_pe_[pe_fill_nb_][bar]->SetBinError(i_t + start_sample_,
154 fabs(q_err.at(i_t)));
155 } // over time samples
156 h_out_pe_[pe_fill_nb_][bar]->GetYaxis()->SetTitle(
157 Form("Q, chan %i, ev %i, PE %.2f", bar, ev_nb, hit_pes[bar]));
158 } // over channels
159 pe_fill_nb_++; // update filled event counter for this flag
160 } // if fill
161
162 return;
163}
164
165void QualityFlagAnalyzer::onProcessStart() {
166 ldmx_log(trace)
167 << "\n\n Process starts! My analyzer should do something -- like "
168 "print this \n\n";
169 getHistoDirectory();
170
171 int n_time_samp = 40;
172 int p_emax = 100;
173 int n_p_ebins = 5 * p_emax;
174 // float Qmax = PEmax / (6250. / 4.e6);
175 // float Qmin = -10;
176 // int nQbins = (Qmax - Qmin) / 4;
177
178 ldmx_log(debug) << "Setting up histograms... ";
179
180 for (int i_b = 0; i_b < N_CHANNELS; i_b++) {
181 h_pe_[i_b] = new TH1F(Form("hPE_chan%i", i_b), Form(";PE, chan%i", i_b),
182 n_p_ebins, 0, p_emax);
183 }
184
185 for (int i_e = 0; i_e < n_ev_; i_e++) {
186 for (int i_b = 0; i_b < N_CHANNELS; i_b++) {
187 h_out_[i_e][i_b] =
188 new TH1F(Form("hCharge_chan%i_ev%i", i_b, i_e),
189 Form(";time sample; Q, channel %i, event %i [fC]", i_b, i_e),
190 n_time_samp, -0.5, n_time_samp - 0.5);
191 h_out_pe_[i_e][i_b] =
192 new TH1F(Form("hCharge_PEcut_chan%i_nb%i", i_b, i_e),
193 Form(";time sample; Q, channel %i, event %i [fC]", i_b, i_e),
194 n_time_samp, -0.5, n_time_samp - 0.5);
195 for (int i_f = 0; i_f < n_flags_; i_f++) {
196 h_out_flag_[i_f][i_e][i_b] = new TH1F(
197 Form("hCharge_flag%i_chan%i_nb%i", flags_[i_f], i_b, i_e),
198 Form(";time sample; Q, flag %i, chan %i, ev %i [fC]", i_f, i_b,
199 i_e),
200 n_time_samp, -0.5,
201 n_time_samp - 0.5); // less confusing to name them upon actual use
202 // h_out_flag_[iF][iE][iB] = new TH1F("hCharge_flag", "",
203 // nTimeSamp,-0.5,nTimeSamp-0.5);
204 }
205 }
206 }
207
208 h_td_cfire_chan_vs_event_ = new TH2F(
209 "h_td_cfire_chan_vs_event_", ";channel with TDC < 63;event number",
210 N_CHANNELS, -0.5, N_CHANNELS - 0.5, n_ev_, 0, n_ev_);
211
212 pe_fill_nb_ = 0;
213 ldmx_log(debug) << "done setting up histograms";
214
215 return;
216}
217
218void QualityFlagAnalyzer::onProcessEnd() { return; }
219
220} // namespace trigscint
221
#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.
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).
This class represents the linearised QIE output from the trigger scintillator, in charge (fC).
Definition TestBeamHit.h:24