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