10#include <dqm/analysis/modules/DQMHistAnalysisCDCMonObj.h>
13#include <cdc/geometry/CDCGeometryPar.h>
40 setDescription(
"Modify and analyze the data quality histograms of CDCMonObj");
42 for (
int i = 0; i < 300; i++) {
46 for (
int i = 0; i < 56; i++)
m_hHits[i] =
nullptr;
57 if (!(*m_channelMapFromDB).isValid()) {
58 B2FATAL(
"Channel map is not valid");
63 B2FATAL(
"CDCGeometryp is not valid");
68 gStyle->SetOptStat(0);
69 gStyle->SetPalette(kViridis);
70 gStyle->SetPadTopMargin(0.1);
71 gStyle->SetPadRightMargin(0.05);
72 gStyle->SetPadBottomMargin(0.1);
73 gStyle->SetPadLeftMargin(0.15);
75 m_cMain =
new TCanvas(
"cdc_main",
"cdc_main", 1500, 1200);
78 m_cADC =
new TCanvas(
"cdc_adc",
"cdc_adc", 2000, 10000);
80 m_cTDC =
new TCanvas(
"cdc_tdc",
"cdc_tdc", 2000, 10000);
82 m_cHit =
new TCanvas(
"cdc_hit",
"cdc_hit", 1500, 6000);
85 B2DEBUG(20,
"DQMHistAnalysisCDCMonObj: initialized.");
92 const int isl = cm.getISuperLayer();
93 const int il = cm.getILayer();
94 const int iw = cm.getIWire();
95 const int iBoard = cm.getBoardID();
96 const int iCh = cm.getBoardChannel();
97 const WireID wireId(isl, il, iw);
98 m_chMap.insert(std::make_pair(wireId, std::make_pair(iBoard, iCh)));
104 for (
const auto& sense : geom.getSenseLayers()) {
105 int i = sense.getId();
106 if (i < 0 || i > 55) {
107 B2FATAL(
"no such sense layer");
114 for (
const auto& field : geom.getFieldLayers()) {
115 int i = field.getId();
116 if (i < 0 || i > 54) {
117 B2FATAL(
"no such sense layer");
121 m_fieldR[56] = geom.getOuterWall(0).getRmin();
122 m_fieldR[0] = geom.getInnerWall(0).getRmax();
129 for (
int ilayer = 0; ilayer < 56; ++ilayer) {
133 for (
int iwire = 0; iwire <
m_nSenseWires[ilayer]; ++iwire) {
134 float phi = dPhi * (iwire +
m_offset[ilayer]);
135 float phi1 = phi - dPhi * 0.5;
136 float phi2 = phi + dPhi * 0.5;
137 Double_t x_pos[] = {r1* (sin(phi)*tan(phi - phi1) + cos(phi)),
140 r1* (sin(phi)*tan(phi - phi2) + cos(phi))
142 Double_t y_pos[] = {r1* (-cos(phi)*tan(phi - phi1) + sin(phi)),
145 r1* (-cos(phi)*tan(phi - phi2) + sin(phi))
147 h->AddBin(4, x_pos, y_pos);
156 for (
int il = 0; il < 56; ++il) {
158 const int y =
m_hHits[il]->GetBinContent(iw + 1);
169 TH1D* hist = (TH1D*)h->Clone();
170 hist->SetBinContent(1, 0.0);
171 float m = hist->GetMean();
178 TH1D* hist = (TH1D*)h->Clone();
179 hist->SetBinContent(1, 0.0);
180 if (hist->GetMean() == 0) {
return 0.0;}
181 double quantiles[1] = {0.0};
182 double probSums[1] = {0.5};
183 hist->GetQuantiles(1, quantiles, probSums);
184 float median = quantiles[0];
191 const WireID w(layer, wire);
196 B2ERROR(
"no corresponding board/channel found layer " << layer <<
" wire " << wire);
197 return std::make_pair(-1, -1);
204 B2DEBUG(20,
"end run");
212 B2INFO(
"Histogram named m_hADC is not found.");
216 TF1* fitFunc[300] = {};
217 for (
int i = 0; i < 300; ++i) {
218 fitFunc[i] =
new TF1(Form(
"f%d", i),
"[0]+[6]*x+[1]*(exp([2]*(x-[3]))/(1+exp(-([4]-x)/[5])))",
219 4921 - 100, 4921 + 100);
220 fitFunc[i]->SetParLimits(6, 0, 0.1);
221 fitFunc[i]->SetParLimits(4, 4850., 5000.0);
222 fitFunc[i]->SetParLimits(5, 0, 50.0);
225 int neve =
m_hTDC->GetEntries();
226 if (neve == 0)neve = 1;
228 B2DEBUG(20,
"adc related");
231 TH1F* hADCMean =
new TH1F(
"hADCMean",
"ADC mean;board;adc mean", 300, 0, 300);
232 TH1F* hADC1000 =
new TH1F(
"ADC1000",
"ADC1000", 300, 0, 300);
233 TH1F* hADC0 =
new TH1F(
"ADC0",
"ADC0", 300, 0, 300);
236 std::vector<float> means = {};
237 std::vector<float> medians = {};
239 for (
int i = 0; i < 300; ++i) {
240 m_hADCs[i] =
m_hADC->ProjectionY(Form(
"hADC%d", i), i + 1, i + 1,
"");
241 m_hADCs[i]->SetTitle(Form(
"hADC%d", i));
242 float n =
static_cast<float>(
m_hADCs[i]->GetEntries());
245 hADC0->SetBinContent(i + 1, -0.1);
247 float n0 =
static_cast<float>(
m_hADCs[i]->GetBinContent(1));
249 B2DEBUG(21,
"bad adc bid " << i <<
" " << n0 <<
" " << n);
252 float bin1 =
m_hADCs[i]->GetBinContent(1);
256 medians.push_back(md);
257 hADCMean->SetBinContent(i + 1, m);
258 hADCMean->SetBinError(i + 1, 0);
259 double overflow =
m_hADCs[i]->GetBinContent(
m_hADCs[i]->GetNbinsX() + 1);
260 hADC1000->SetBinContent(i + 1, overflow / (overflow + n));
261 hADC0->SetBinContent(i + 1, bin1 / (overflow + n));
266 B2DEBUG(20,
"tdc related");
268 TH1F* hTDCEdge =
new TH1F(
"hTDCEdge",
"TDC edge;board;tdc edge [nsec]", 300, 0, 300);
269 TH1F* hTDCSlope =
new TH1F(
"hTDCSlope",
"TDC slope;board;tdc slope [nsec]", 300, 0, 300);
270 std::vector<float> tdcEdges = {};
271 std::vector<float> tdcSlopes = {};
272 for (
int i = 0; i < 300; ++i) {
273 m_hTDCs[i] =
m_hTDC->ProjectionY(Form(
"hTDC%d", i), i + 1, i + 1);
274 m_hTDCs[i]->SetTitle(Form(
"hTDC%d", i));
277 tdcEdges.push_back(0);
278 tdcSlopes.push_back(0);
280 double init_p0 =
m_hTDCs[i]->GetBinContent(700 + 60);
281 fitFunc[i]->SetParameters(init_p0, 100, 0.01, 4700, 4900, 2, 0.01);
282 fitFunc[i]->SetParameter(6, 0.02);
283 fitFunc[i]->SetParLimits(0, init_p0 - 200, init_p0 + 200);
284 int TDCfitstatus = -1;
286 TDCfitstatus =
m_hTDCs[i]->Fit(fitFunc[i],
"qM0",
"", 4850, 5000);
288 TDCfitstatus =
m_hTDCs[i]->Fit(fitFunc[i],
"qM0",
"", 4800, 5000);
290 float p4 = fitFunc[i]->GetParameter(4);
291 float p5 = fitFunc[i]->GetParameter(5);
293 if (TDCfitstatus != -1 && 4850 < p4 && p4 < 5000) {
294 hTDCEdge->SetBinContent(i + 1, p4);
295 hTDCEdge->SetBinError(i + 1, 0);
296 hTDCSlope->SetBinContent(i + 1, p5);
297 hTDCSlope->SetBinError(i + 1, 0);
299 tdcEdges.push_back(p4);
300 tdcSlopes.push_back(p5);
306 B2DEBUG(20,
"hit related");
307 TH1F* hHitPerLayer =
new TH1F(
"hHitPerLayer",
"hit/Layer;layer", 56, 0, 56);
308 TH1F* hHitRatePerWire =
new TH1F(
"hHitRatePerWire",
"hit rate (kHz)/Wire;layer", 56, 0, 56);
310 for (
int i = 0; i < 56; ++i) {
312 double tdcclock = 0.98255764;
313 if (i < 8) tdcwindow = 416;
314 else tdcwindow = 768;
315 m_hHits[i] =
m_hHit->ProjectionY(Form(
"hHit%d", i), i + 1, i + 1);
316 m_hHits[i]->SetTitle(Form(
"hHit%d", i));
320 for (
int j = 0; j < nBins; ++j) {
321 nhitSumL +=
m_hHits[i]->GetBinContent(j + 1);
324 hHitPerLayer->SetBinContent(i + 1, 1.0 * nhitSumL / neve);
325 hHitRatePerWire->SetBinContent(i + 1, (1.0 * nhitSumL / neve) / (1.0 * nBins * tdcwindow * tdcclock * 1e-6));
327 hHitPerLayer->SetBinContent(i + 1, nhitSumL);
328 hHitRatePerWire->SetBinContent(i + 1, (1.0 * nhitSumL) / (1.0 * nBins * tdcwindow * tdcclock * 1e-6));
330 hHitPerLayer->SetBinError(i + 1, 0);
331 hHitRatePerWire->SetBinError(i + 1, 0);
337 B2DEBUG(20,
"bad wire related");
338 hBadChannel =
new TH2F(
"hbadch",
"bad channel map;wire;layer", 400, 0, 400, 56, 0, 56);
339 for (
int i = 0; i < 400; ++i) {
340 for (
int j = 0; j < 56; ++j) {
345 hBadChannelBC =
new TH2F(
"hbadchBC",
"bad channel map per board/channel;board;channel", 300, 0, 300, 48, 0, 48);
346 for (
int i = 0; i < 300; ++i) {
347 for (
int j = 0; j < 48; ++j) {
354 h2p->SetTitle(
"bad wires in xy view");
355 h2p->GetXaxis()->SetTitle(
"X [cm]");
356 h2p->GetYaxis()->SetTitle(
"Y [cm]");
359 const int l = lw.first;
360 const int w = lw.second;
361 B2DEBUG(21,
"l " << l <<
" w " << w);
366 float dPhi =
static_cast<float>(2.0 * M_PI /
m_nSenseWires[l]);
367 float phi = dPhi * (w +
m_offset[l]);
368 float x = r * cos(phi);
369 float y = r * sin(phi);
370 h2p->Fill(x, y, 1.1);
373 B2DEBUG(20,
"writing");
377 hADCMean->SetMinimum(0);
378 hADCMean->SetMaximum(300);
379 hADCMean->DrawCopy();
382 hTDCEdge->SetMinimum(4800);
383 hTDCEdge->SetMaximum(5000);
384 hTDCEdge->DrawCopy();
387 hTDCSlope->SetMinimum(0);
388 hTDCSlope->SetMaximum(50);
389 hTDCSlope->DrawCopy();
398 hADC1000->DrawCopy();
404 hHitPerLayer->DrawCopy();
407 hHitRatePerWire->DrawCopy();
410 for (
int i = 0; i < 56; i++) {
416 m_cADC->Divide(6, 50, 0.0002, 0.0002);
417 m_cTDC->Divide(6, 50, 0.0002, 0.0002);
419 for (
int i = 0; i < 300; i++) {
421 Double_t max =
m_hADCs[i]->GetMaximum();
422 m_hADCs[i]->GetYaxis()->SetRangeUser(0, 3 * max);
427 fitFunc[i]->SetLineColor(kRed);
428 fitFunc[i]->Draw(
"same");
429 max =
m_hTDCs[i]->GetMaximum();
430 TLine* l1 =
new TLine(tdcEdges[i], 0, tdcEdges[i], max * 1.05);
431 l1->SetLineColor(kRed);
432 TLine* l0 =
new TLine(4910, 0, 4910, max * 1.05);
438 h2p->DrawCopy(
"col");
439 float superLayerR[10] = {16.3, 24.3, 35.66, 46.63, 57.55, 68.47,
440 79.39, 90.31, 101.23, 112.05
444 for (
int i = 0; i < 10; ++i) {
445 circs[i] =
new TEllipse(0, 0, superLayerR[i], superLayerR[i]);
446 circs[i]->SetFillStyle(4000);
447 circs[i]->SetLineStyle(kDashed);
448 circs[i]->SetLineColor(0);
449 circs[i]->Draw(
"same");
455 m_monObj->
setVariable(
"adcMean", std::accumulate(means.begin(), means.end(), 0.0) / means.size());
456 m_monObj->
setVariable(
"adcMeanMedianBoard", std::accumulate(medians.begin(), medians.end(), 0.0) / medians.size());
459 m_monObj->
setVariable(
"tdcEdge", std::accumulate(tdcEdges.begin(), tdcEdges.end(), 0.0) / (tdcEdges.size() - 1 - nDeadTDC));
461 m_monObj->
setVariable(
"tdcSlope", std::accumulate(tdcSlopes.begin(), tdcSlopes.end(), 0.0) / (tdcSlopes.size() - 1 - nDeadTDC));
469 delete hHitRatePerWire;
476 B2DEBUG(20,
"terminate called");
The Class for CDC geometry.
Class for accessing arrays of objects in the database.
Class for accessing objects in the database.
~DQMHistAnalysisCDCMonObjModule()
Destructor.
std::map< WireID, std::pair< int, int > > m_chMap
Channel map retrieved
TCanvas * m_cTDC
TDC panel.
void initialize() override final
Initialize the Module.
DQMHistAnalysisCDCMonObjModule()
Constructor.
std::string m_hname_hits
Hits histogram names.
DBArray< CDCChannelMap > * m_channelMapFromDB
Channel map retrieved from DB.
std::string m_name_dir
dqm histogram dir
std::vector< std::pair< int, int > > m_badChannels
bad wires list
int m_nSenseWires[56]
number of wires for each layer.
TCanvas * m_cHit
Hit panel.
TH1D * m_hTDCs[300]
TDC histograms with track associated hits for each board (0-299)
MonitoringObject * m_monObj
monitoring object
void terminate() override final
Termination action.
DBObjPtr< CDCGeometry > * m_cdcGeo
Geometry of CDC.
TH2F * m_hTDC
Summary of TDC histograms with track associated hits.
TH1D * m_hADCs[300]
ADC histograms with track associated hits for each board (0-299)
void makeBadChannelList()
make bad channel list.
TH2F * hBadChannel
bad channel map;wire;layer
std::pair< int, int > getBoardChannel(unsigned short layer, unsigned short wire)
Get board/channel from layer/wire.
TH2Poly * h2p
bad wires in xy view
TH1D * m_hHits[56]
hit histograms for each layer (0-55)
void endRun() override final
End-of-run action.
void configureBins(TH2Poly *h)
Configure bins of TH2Poly.
float getHistMean(TH1D *h) const
Get mean of ADC histogram excluding 0-th bin.
float m_offset[56]
Offset of sense layer
void beginRun() override final
Called when entering a new run.
TH2F * m_hADC
Summary of ADC histograms with track associated hits.
TH2F * hBadChannelBC
bad channel map per board/channel;board;channel
float m_fieldR[57]
Radius of field layer.
float getHistMedian(TH1D *h) const
Get median of ADC histogram excluding 0-th bin.
float m_senseR[56]
Radius of sense (+field) layer.
TCanvas * m_cADC
ADC panel.
std::string m_hname_btdc
Board TDC histogram name.
std::string m_hname_badc
Board ADC histogram name.
TCanvas * m_cMain
main panel
TH2F * m_hHit
Summary of hit histograms.
The base class for the histogram analysis module.
static MonitoringObject * getMonitoringObject(const std::string &name)
Get MonitoringObject with given name (new object is created if non-existing)
static TH1 * findHist(const std::string &histname, bool onlyIfUpdated=false)
Get histogram from list (no other search).
void setDescription(const std::string &description)
Sets the description of the module.
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
void setVariable(const std::string &var, float val, float upErr=-1., float dwErr=-1)
set value to float variable (new variable is made if not yet existing)
void addCanvas(TCanvas *canv)
Add Canvas to monitoring object.
Class to identify a wire inside the CDC.
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Abstract base class for different kinds of events.