10#include "TPaveLabel.h"
14#include <TParameter.h>
22 std::optional<std::pair<size_t, size_t>> spill_on_off_threshold)
27 assert(noise_threshold > 0);
36 FairRootManager* ioman = FairRootManager::Instance();
37 if (ioman !=
nullptr) {
43 LOG(info) <<
"CbmStsChannelQA configuration:";
46 LOG(info) <<
"Noisy channel S/B thresholds: " <<
fSBThreshold;
48 LOG(info) << Form(
"Spill OFF: RefDet_DigiRate < %lu",
fSpillThresholds->first);
49 LOG(info) << Form(
"Spill ON: RefDet_DigiRate > %lu",
fSpillThresholds->second);
52 LOG(info) <<
"No Spill section defined. Using all time slices";
63 LOG(debug) << Form(
"Booking histograms for module_addr: 0x%x", address);
70 h_name = Form(
"0x%x_charge_vs_channel%s", address, modifier);
72 fH2D[h_name] = std::make_unique<TH2D>(h_name.c_str(), h_name.c_str(), 2048, 0, 2048, 31, 1, 32);
73 fH2D[h_name]->GetXaxis()->SetTitle(
"Channel_{StsDigi}");
74 fH2D[h_name]->GetYaxis()->SetTitle(
"Charge_{StsDigi} [ADC]");
77 h_name = Form(
"0x%x_dt_vs_charge%s", address, modifier);
78 fH2D[h_name] = std::make_unique<TH2D>(h_name.c_str(), h_name.c_str(), 31, 1, 32, t_binning.n_of_bins,
79 t_binning.x_min, t_binning.x_max);
80 fH2D[h_name]->GetYaxis()->SetTitle(
"Charge_{StsDigi} [ADC]");
81 fH2D[h_name]->GetYaxis()->SetTitle(
"Time difference [ns]");
84 h_name = Form(
"0x%x_dt_vs_channel%s", address, modifier);
85 fH2D[h_name] = std::make_unique<TH2D>(h_name.c_str(), h_name.c_str(), 2048, 0, 2048, t_binning.n_of_bins,
86 t_binning.x_min, t_binning.x_max);
87 fH2D[h_name]->GetXaxis()->SetTitle(
"Channel_{StsDigi}");
88 fH2D[h_name]->GetYaxis()->SetTitle(
"Time difference [ns]");
97 for (
int chn = 0; chn < 2048; chn++) {
105 LOG(info) <<
"Running CbmStsChannelQA ...";
115 int fSpillStatus = 0;
120 std::string str_spill;
121 switch (fSpillStatus) {
138 LOG(info) << Form(
"TS %d\t-\t Spill section: %s",
entry_, str_spill.c_str());
143 for (
size_t sts_digi_idx = 0; sts_digi_idx < nb_sts_digis; sts_digi_idx++) {
144 const CbmStsDigi* sts_digi = &sts_digis_[sts_digi_idx];
145 int32_t sts_digi_addr = sts_digi->
GetAddress();
146 int32_t sts_digi_chan = sts_digi->
GetChannel();
147 int32_t sts_digi_char = sts_digi->GetCharge();
148 double sts_digi_time = sts_digi->GetTime();
153 for (
int chn = 0; chn < 2048; chn++) {
158 fH2D[Form(
"0x%x_charge_vs_channel%s", sts_digi_addr, str_spill.c_str())]->Fill(sts_digi_chan, sts_digi_char);
161 fH2D[Form(
"0x%x_dt_vs_charge%s", sts_digi_addr, str_spill.c_str())]->Fill(
162 sts_digi_char, sts_digi_time -
fLastDigiTime[sts_digi_addr][sts_digi_chan]);
163 fH2D[Form(
"0x%x_dt_vs_channel%s", sts_digi_addr, str_spill.c_str())]->Fill(
164 sts_digi_chan, sts_digi_time -
fLastDigiTime[sts_digi_addr][sts_digi_chan]);
179 auto h = (TH1D*)
fH2D[Form(
"0x%x_charge_vs_channel%s", module_addr, mod)]->ProjectionX();
180 for (
int chn = 0; chn < 2048; chn++) {
181 double entries =
h->GetBinContent(chn + 1);
193 TH1D* h_sgn =
fH2D[Form(
"0x%x_charge_vs_channel:spill_on", module_addr)]->ProjectionX();
194 TH1D* h_bkg =
fH2D[Form(
"0x%x_charge_vs_channel:spill_off", module_addr)]->ProjectionX();
198 h_sgn->Add(h_bkg, -1);
200 for (
int chn = 0; chn < 2048; chn++) {
201 double sgn = h_sgn->GetBinContent(chn + 1);
202 double bkg = h_bkg->GetBinContent(chn + 1);
204 if (bkg == 0)
continue;
206 double sb_ratio =
sgn / bkg;
209 LOG(debug) << Form(
"Noisy channel 0x%x: %d, \tS/B: %0.4f", module_addr, chn, sb_ratio);
218 std::string f_name =
"cbm_sts_channel_qa_report.root";
219 std::unique_ptr<TFile> o_root_file = std::make_unique<TFile>(f_name.c_str(),
"RECREATE");
220 int pad_size_x = 1000;
221 int pad_size_y = 1000;
223 std::string c_name = Form(
"0x%x_channel", module_addr);
224 std::unique_ptr<TCanvas> c = std::make_unique<TCanvas>(c_name.c_str(), c_name.c_str(), pad_size_x, pad_size_y);
225 TH1D* h_sgn =
fH2D[Form(
"0x%x_charge_vs_channel:spill_on", module_addr)]->ProjectionX();
226 TH1D* h_bkg =
fH2D[Form(
"0x%x_charge_vs_channel:spill_off", module_addr)]->ProjectionX();
228 LOG(debug) << Form(
"Building report for 0x%x", module_addr);
232 h_sgn->SetLineColor(kRed);
233 h_bkg->SetLineColor(kBlack);
238 h_sgn->SetFillColorAlpha(kRed, 0.2);
239 h_bkg->SetFillColorAlpha(kBlack, 0.2);
241 double h_sgn_max = h_sgn->GetMaximum();
242 double h_bkg_max = h_bkg->GetMaximum();
243 double max = std::max(h_sgn_max, h_bkg_max);
245 h_sgn->SetMaximum(1.05 *
max);
246 h_bkg->SetMaximum(1.05 *
max);
250 gPad->SetLeftMargin(0.15);
251 gPad->SetBottomMargin(0.12);
252 gPad->SetTopMargin(0.10);
253 gPad->SetRightMargin(0.12);
255 h_sgn->Draw(
"histo");
256 h_bkg->Draw(
"histo same");
260 LOG(debug) << Form(
"Drawing %d noisy channel markers: %lu", module_addr,
fNoisyChannelList[module_addr].
size());
262 TBox chn_box = TBox(chn + 0.2, 0.99 *
max, chn + 0.8, 1.01 *
max);
263 chn_box.SetLineColor(kBlue);
264 chn_box.SetFillColor(kBlue);
269 c->Write(Form(
"0x%x_channel:spill_on_vs_off.png", module_addr));
286 std::unique_ptr<TFile> out_file = std::make_unique<TFile>(
"cbm_sts_channel_qa.root",
"UPDATE");
290 std::ofstream dead_info(
"sts_dead_channels.info");
291 std::ofstream dead_par(
"sts_dead_channels.par");
292 dead_info << Form(
"# Module\t Number of dead channels\n");
293 int n_of_dead_chn = 0;
295 dead_info << Form(
"0x%x\t%lu\n", module_addr, list.size());
296 for (
int& dead_chn : list) {
297 dead_par << module_addr <<
"\t" << dead_chn << std::endl;
299 n_of_dead_chn += list.size();
301 dead_info << Form(
"# Total Number of dead channels: %d\n", n_of_dead_chn);
303 std::ofstream noisy_info(
"sts_noisy_channels.info");
304 std::ofstream noisy_par(
"sts_noisy_channels.par");
305 noisy_info << Form(
"# Module\t Number of noisy channels\n");
306 int n_of_noisy_chn = 0;
308 noisy_info << Form(
"0x%x\t%lu\n", module_addr, list.size());
309 for (
int& noisy_chn : list) {
310 noisy_par << module_addr <<
"\t" << noisy_chn << std::endl;
312 n_of_noisy_chn += list.size();
314 noisy_info << Form(
"# Total Number of noisy channels: %d\n", n_of_noisy_chn);
@ kSts
Silicon Tracking System.
friend fscal max(fscal x, fscal y)
friend fscal sgn(fscal x)
static constexpr size_t size()
static CbmDigiManager * Instance()
Static instance.
std::unordered_set< int32_t > fAddressBook
std::map< std::string, std::unique_ptr< TH2D > > fH2D
void SaveToFile()
It write all mapped objects to the FairRunAna sink file.
std::map< std::string, std::unique_ptr< TH1D > > fH1D
CbmDigiManager * fDigiManager
std::map< int32_t, std::vector< int > > fNoisyChannelList
void BookHistograms(int32_t)
Book histograms.
const int fActiveMinEntries
std::map< int32_t, std::vector< int > > fDeadChannelList
std::vector< const char * > fSpillSections
const double fSBThreshold
std::map< int32_t, double[2048]> fLastDigiTime
CbmStsChannelQA()=default
void CheckNoisyChannels()
Check for dead channels. Fills fNoisyChannelList map.
const std::optional< std::pair< size_t, size_t > > fSpillThresholds
void CheckDeadChannels()
Check for dead channels. Fills fDeadChannelList map.
Data class for a single-channel message in the STS.
XPU_D uint16_t GetChannel() const
Channel number in module @value Channel number.
XPU_D int32_t GetAddress() const
Data class with information on a STS local track.
Structure to hold the binning for 1D histogram.