1 #include <geometry/GeometryManager.h>
3 #include <vxd/geometry/GeoCache.h>
6 #include <framework/database/IntervalOfValidity.h>
7 #include <framework/database/DBImportObjPtr.h>
9 #include <svd/calibration/SVDHotStripsCalibrations.h>
10 #include <svd/calibration/SVDOccupancyCalibrations.h>
11 #include <svd/modules/svdCalibration/SVDHotStripFinderModule.h>
21 setDescription(
"The svdHotStripFinder module finds hot strips in SVD data SVDShaperDigit");
23 addParam(
"outputFileName", m_rootFileName,
"Name of output root file.", std::string(
"SVDHotStripFinder.root"));
24 addParam(
"threshold", m_thr,
"Threshold cut for Hot strip finder in percent",
float(4.0));
25 addParam(
"searchBase", m_base,
26 "number of strips used to compute the average occupancy, possible choices = 32, 64, 128. Default = -1, use all sensor strips.",
29 addParam(
"zeroSuppression", m_zs,
"ZeroSuppression cut of the input SVDShaperDigits",
float(5));
30 addParam(
"firstExp", m_firstExp,
"experiment number",
int(-1));
31 addParam(
"firstRun", m_firstRun,
"run number",
int(-1));
32 addParam(
"lastExp", m_lastExp,
"open iov",
int(-1));
33 addParam(
"lastRun", m_lastRun,
"open iov",
int(-1));
34 addParam(
"ShaperDigits", m_ShaperDigitName,
"shaper digit name", std::string(
""));
36 addParam(
"useHSFinderV1", m_useHSFinderV1,
"Set to false only if you want to test the second version of the algorithm",
38 addParam(
"absOccThreshold", m_absThr,
39 "Absolute occupancy threshold: at a first loop, flag as Hot Strip (HS) all those whose occupancy > absOccThreshold",
float(0.2));
40 addParam(
"relOccPrec", m_relOccPrec,
41 "Number of times the average sensor occupancy considered to fix the sensor dependent threshold, as for example occ_threshold = relOccPrec x occ_average",
43 addParam(
"verbose", m_verbose,
" True by default, it allows to switch off the printing of all found HS.",
bool(
true));
48 SVDHotStripFinderModule::~SVDHotStripFinderModule()
53 void SVDHotStripFinderModule::initialize()
56 m_eventMetaData.isRequired();
57 m_storeDigits.isRequired(m_ShaperDigitName);
59 B2DEBUG(25,
" ShaperDigits: " << m_ShaperDigitName);
61 m_histoList_occu =
new TList;
63 m_rootFilePtr =
new TFile(m_rootFileName.c_str(),
"RECREATE");
65 B2RESULT(
"You are using the first version of the HSFinder algorithm (see SVDHotStripFinder::terminate in the module)");
66 else B2RESULT(
"You are using the modified version of the HSFinder algorithm (see SVDHotStripFinder::endRun in the module)");
69 void SVDHotStripFinderModule::beginRun()
74 TH1F hOccupancy768(
"Occupancy768_L@layerL@ladderS@sensor@view",
"Strip Occupancy of @layer.@ladder.@sensor @view/@side side", 768,
77 hOccupancy768.GetXaxis()->SetTitle(
"cellID");
78 TH1F hOccupancy512(
"Occupancy512_L@layerL@ladderS@sensor@view",
"Strip Occupancy of @layer.@ladder.@sensor @view/@side side", 512,
81 hOccupancy512.GetXaxis()->SetTitle(
"cellID");
82 hm_occupancy =
new SVDHistograms<TH1F>(hOccupancy768, hOccupancy768, hOccupancy768, hOccupancy512);
84 TH1F hHotStrips768(
"HotStrips768_L@layerL@ladderS@sensor@view",
"Hot Strips of @layer.@ladder.@sensor @view/@side side", 768, 0,
86 hHotStrips768.GetXaxis()->SetTitle(
"cellID");
87 TH1F hHotStrips512(
"HotStrips512_L@layerL@ladderS@sensor@view",
"Hot Strips of @layer.@ladder.@sensor @view/@side side", 512, 0,
89 hHotStrips512.GetXaxis()->SetTitle(
"cellID");
90 hm_hot_strips =
new SVDHistograms<TH1F>(hHotStrips768, hHotStrips768, hHotStrips768, hHotStrips512);
92 TH1F hOccupancy_after768(
"OccupancyAfter768_L@layerL@ladderS@sensor@view",
93 "Non-Hot Strip Occupancy after HSF of @layer.@ladder.@sensor @view/@side side", 768, 0, 768);
94 hOccupancy_after768.GetXaxis()->SetTitle(
"cellID");
95 TH1F hOccupancy_after512(
"OccupancyAfter512_L@layerL@ladderS@sensor@view",
96 "Non-Hot Strip Occupancy after HSF of @layer.@ladder.@sensor @view/@side side", 512, 0, 512);
97 hOccupancy_after512.GetXaxis()->SetTitle(
"cellID");
98 hm_occupancy_after =
new SVDHistograms<TH1F>(hOccupancy_after768, hOccupancy_after768, hOccupancy_after768, hOccupancy_after512);
100 TH1F hOccAll(
"occAll_L@layerL@ladderS@sensor@view",
"Strip Occupancy Distribution of @layer.@ladder.@sensor @view/@side side", 1000,
102 hOccAll.GetXaxis()->SetTitle(
"occupancy");
105 TH1F hOccHot(
"occHot_L@layerL@ladderS@sensor@view",
"Hot Strip Occupancy Distribution of @layer.@ladder.@sensor @view/@side side",
107 hOccHot.GetXaxis()->SetTitle(
"occupancy");
110 TH1F hOccAfter(
"occAfter_L@layerL@ladderS@sensor@view",
111 "Non-Hot Strip Occupancy Distribution of @layer.@ladder.@sensor @view/@side side", 1000, 0, 0.05);
112 hOccAfter.GetXaxis()->SetTitle(
"occupancy");
116 TH1F hDist(
"dist_L@layerL@ladderS@sensor@view",
"DSSD occupancy distribution of @layer.@ladder.@sensor @view/@side side", 100, 0,
118 hDist.GetXaxis()->SetTitle(
"occupancy");
121 TH1F hDist1(
"dist1_L@layerL@ladderS@sensor@view",
"DSSD true occupancy distribution of @layer.@ladder.@sensor @view/@side side",
124 hDist.GetXaxis()->SetTitle(
"occupancy");
126 TH2F hDist12(
"dist2d_L@layerL@ladderS@sensor@view",
127 "DSSD true vs sensor occupancy distribution of @layer.@ladder.@sensor @view/@side side", 1000, 0, 0.05, 1000, 0, 0.05);
128 hDist12.GetXaxis()->SetTitle(
"sensor occupancy");
129 hDist12.GetYaxis()->SetTitle(
"occupancy");
133 m_hHotStripsSummary =
new SVDSummaryPlots(
"hotStripsSummary@view",
"Number of HotStrips on @view/@side Side");
137 h_tot_dqm = createHistogram1D(
"htodqm",
"HS per sensor", 28, 0, 28.0,
"HS per sensor", m_histoList_occu);
138 h_tot_dqm1 = createHistogram1D(
"htodqm1",
"HS per sensor1", 350, 0, 350.0,
"HS per sensor ", m_histoList_occu);
140 h_tot_dist = createHistogram1D(
"htotdist",
"Occupancy distribution", 1000, 0, 0.05,
"Relative occupancy", m_histoList_occu);
141 h_tot_dist1 = createHistogram1D(
"htotdist1",
"True occupancy distribution", 1000, 0, 0.05,
"occupancy", m_histoList_occu);
142 h_tot_dist12 = createHistogram2D(
"htotdist2d",
"True vs sensor occupancy distribution", 1000, 0, 0.05,
"sensor occupancy", 1000, 0,
143 0.05,
"occupancy", m_histoList_occu);
144 h_nevents = createHistogram1D(
"hnevents",
"Number of events", 1, 0, 1,
"", m_histoList_occu);
148 void SVDHotStripFinderModule::event()
151 int nDigits = m_storeDigits.getEntries();
152 h_nevents->Fill(0.0);
159 while (i < nDigits) {
160 VxdID theVxdID = m_storeDigits[i]->getSensorID();
161 int side = m_storeDigits[i]->isUStrip();
162 int CellID = m_storeDigits[i]->getCellID();
164 hm_occupancy->fill(theVxdID, side, CellID);
173 void SVDHotStripFinderModule::endRun()
176 int exp = m_eventMetaData->getExperiment();
177 int run = m_eventMetaData->getRun();
179 if (!m_useHSFinderV1) {
181 TDirectory* oldDir = NULL;
182 TDirectory* dir_occuL[4] = {NULL, NULL, NULL, NULL};
185 if (m_rootFilePtr != NULL) {
188 dir_occuL[0] = oldDir->mkdir(
"layer3");
189 dir_occuL[1] = oldDir->mkdir(
"layer4");
190 dir_occuL[2] = oldDir->mkdir(
"layer5");
191 dir_occuL[3] = oldDir->mkdir(
"layer6");
197 int nevents = h_nevents->GetEntries();
202 occDBObjPtr.
construct(-99., Form(
"SVDOccupancy_exp%d_run%d_zs%1.1f", exp, run, m_zs));
205 hotStripsDBObjPtr.
construct(0, Form(
"SVDHotStrips_exp%d_run%d_zs%1.1f_absThr%f_relOccPrec%f", exp, run, m_zs, m_absThr,
208 B2RESULT(
"number of events " << nevents);
211 std::set<Belle2::VxdID> svdLayers = aGeometry.
getLayers(VXD::SensorInfoBase::SVD);
212 std::set<Belle2::VxdID>::iterator itSvdLayers = svdLayers.begin();
214 while ((itSvdLayers != svdLayers.end())
215 && (itSvdLayers->getLayerNumber() != 7)) {
217 std::set<Belle2::VxdID> svdLadders = aGeometry.
getLadders(*itSvdLayers);
218 std::set<Belle2::VxdID>::iterator itSvdLadders = svdLadders.begin();
220 while (itSvdLadders != svdLadders.end()) {
222 std::set<Belle2::VxdID> svdSensors = aGeometry.
getSensors(*itSvdLadders);
223 std::set<Belle2::VxdID>::iterator itSvdSensors = svdSensors.begin();
225 while (itSvdSensors != svdSensors.end()) {
227 for (
int k = 0; k < m_nSides; k ++) {
230 int layer = itSvdSensors->getLayerNumber();
231 int ladder = itSvdSensors->getLadderNumber();
232 int sensor = itSvdSensors->getSensorNumber();
236 if (!k && layer != 3) nstrips = 512;
238 double stripOcc[768];
239 for (
int i = 0; i < nstrips; i++) {stripOcc[i] = 0; hsflag[i] = 0;}
240 double stripOccAfterAbsCut[768];
241 (hm_occupancy->getHistogram(*itSvdSensors, k))->Scale(1. / nevents);
242 for (
int l = 0; l < nstrips; l++) {
246 stripOcc[l] = (double)(hm_occupancy->getHistogram(*itSvdSensors, k)->GetBinContent(l + 1));
249 occDBObjPtr->
set(layer, ladder, sensor, k, l, stripOcc[l]);
250 hm_occAll->fill(*itSvdSensors, k, stripOcc[l]);
253 if (stripOcc[l] > m_absThr) {
254 stripOccAfterAbsCut[l] = 0;
257 stripOccAfterAbsCut[l] = stripOcc[l];
260 B2DEBUG(1,
"Measured strip occupancy for strip " << l <<
":" << stripOccAfterAbsCut[l]);
266 while (moreHS && theHSFinder(stripOccAfterAbsCut, hsflag, nstrips)) {
267 moreHS = theHSFinder(stripOccAfterAbsCut, hsflag, nstrips);
271 for (
int l = 0; l < nstrips; l++) {
272 hotStripsDBObjPtr->
set(layer, ladder, sensor, k, l, (
int)hsflag[l]);
273 if (hsflag[l] == 0) {
274 hm_occupancy_after->getHistogram(*itSvdSensors, k)->SetBinContent(l + 1 , stripOccAfterAbsCut[l]);
275 hm_occAfter->fill(*itSvdSensors, k, stripOccAfterAbsCut[l]);
277 hm_hot_strips->getHistogram(*itSvdSensors, k)->SetBinContent(l + 1, 1);
278 hm_occHot->fill(*itSvdSensors, k, stripOcc[l]);
280 TString aux_side =
"V/N";
281 if (k) aux_side =
"U/P";
282 if (m_verbose) B2RESULT(
"HS found, occupancy = " << stripOcc[l] <<
", Layer: " << layer <<
" Ladder: " << ladder <<
" Sensor: "
284 " Side: " << k <<
" channel: " << l);
290 for (
int s = 0; s < hm_hot_strips->getHistogram(*itSvdSensors, k)->GetEntries(); s++)
291 m_hHotStripsSummary->fill(*itSvdSensors, k, 1);
293 if (m_rootFilePtr != NULL) {
294 dir_occuL[layer - 3]->cd();
295 hm_occupancy->getHistogram(*itSvdSensors, k)->Write();
296 hm_hot_strips->getHistogram(*itSvdSensors, k)->SetLineColor(kBlack);
297 hm_hot_strips->getHistogram(*itSvdSensors, k)->SetMarkerColor(kBlack);
298 hm_hot_strips->getHistogram(*itSvdSensors, k)->SetFillStyle(3001);
299 hm_hot_strips->getHistogram(*itSvdSensors, k)->SetFillColor(kBlack);
300 hm_hot_strips->getHistogram(*itSvdSensors, k)->Write();
301 hm_occupancy_after->getHistogram(*itSvdSensors, k)->SetLineColor(kRed);
302 hm_occupancy_after->getHistogram(*itSvdSensors, k)->SetMarkerColor(kRed);
303 hm_occupancy_after->getHistogram(*itSvdSensors, k)->Write();
304 hm_occAll->getHistogram(*itSvdSensors, k)->Write();
305 hm_occHot->getHistogram(*itSvdSensors, k)->SetLineColor(kBlack);
306 hm_occHot->getHistogram(*itSvdSensors, k)->SetFillStyle(3001);
307 hm_occHot->getHistogram(*itSvdSensors, k)->SetFillColor(kBlack);
308 hm_occHot->getHistogram(*itSvdSensors, k)->SetMarkerColor(kBlack);
309 hm_occHot->getHistogram(*itSvdSensors, k)->Write();
310 hm_occAfter->getHistogram(*itSvdSensors, k)->SetLineColor(kRed);
311 hm_occAfter->getHistogram(*itSvdSensors, k)->SetMarkerColor(kRed);
312 hm_occAfter->getHistogram(*itSvdSensors, k)->Write();
315 B2DEBUG(1,
" L" << layer <<
"." << ladder <<
"." << sensor <<
".isU=" << k);
326 if (m_rootFilePtr != NULL) {
328 m_hHotStripsSummary->getHistogram(0)->Write();
329 m_hHotStripsSummary->getHistogram(1)->Write();
332 m_rootFilePtr->Close();
334 if (m_firstExp == -1)
338 if (m_firstRun == -1)
345 hotStripsDBObjPtr.
import(iov);
346 B2RESULT(
"Imported to database.");
350 void SVDHotStripFinderModule::terminate()
352 if (m_useHSFinderV1) {
353 TDirectory* oldDir = NULL;
355 TDirectory* dir_occuL[4] = {NULL, NULL, NULL, NULL};
358 if (m_rootFilePtr != NULL) {
361 dir_occuL[0] = oldDir->mkdir(
"layer3");
362 dir_occuL[1] = oldDir->mkdir(
"layer4");
363 dir_occuL[2] = oldDir->mkdir(
"layer5");
364 dir_occuL[3] = oldDir->mkdir(
"layer6");
375 int nevents = h_nevents->GetEntries();
380 B2DEBUG(1,
"number of events " << nevents);
383 std::set<Belle2::VxdID> svdLayers = aGeometry.
getLayers(VXD::SensorInfoBase::SVD);
384 std::set<Belle2::VxdID>::iterator itSvdLayers = svdLayers.begin();
386 while ((itSvdLayers != svdLayers.end())
387 && (itSvdLayers->getLayerNumber() != 7)) {
389 std::set<Belle2::VxdID> svdLadders = aGeometry.
getLadders(*itSvdLayers);
390 std::set<Belle2::VxdID>::iterator itSvdLadders = svdLadders.begin();
392 while (itSvdLadders != svdLadders.end()) {
394 std::set<Belle2::VxdID> svdSensors = aGeometry.
getSensors(*itSvdLadders);
395 std::set<Belle2::VxdID>::iterator itSvdSensors = svdSensors.begin();
397 while (itSvdSensors != svdSensors.end()) {
399 for (
int k = 0; k < m_nSides; k ++) {
402 int i = itSvdSensors->getLayerNumber() - 3;
403 int m = itSvdSensors->getLadderNumber() - 1;
404 int j = itSvdSensors->getSensorNumber() - 1;
405 float position1[768];
410 for (
int l = 0; l < 24; l++) {
414 for (
int l = 0; l < 768; l++) {
416 position1[l] = hm_occupancy->getHistogram(*itSvdSensors, k)->GetBinContent(l + 1);
419 if (position1[l] == 0) { flag[l] = 0;}
424 div_t test = div(l, ibase);
425 nCltrk[test.quot] = nCltrk[test.quot] + position1[l];
430 for (
int l = 0; l < 768; l++) {
431 div_t test = div(l, ibase);
436 float tmp_occ = position1[l] / (float)nCltrk[test.quot];
437 float tmp_occ1 = position1[l] / (
float)nevents;
438 position1[l] = tmp_occ;
440 hm_dist->fill(*itSvdSensors, k, tmp_occ);
441 h_tot_dist->Fill(tmp_occ);
442 hm_dist1->fill(*itSvdSensors, k, tmp_occ1);
443 h_tot_dist1->Fill(tmp_occ1);
444 hm_dist12->fill(*itSvdSensors, k, tmp_occ, tmp_occ1);
445 h_tot_dist12->Fill(tmp_occ, tmp_occ1);
449 for (
int l = 0; l < 24; l++) {
455 for (
int l = 0; l < 768; l++) {
456 div_t test = div(l, ibase);
457 float threshold_corrections = 1.0;
461 threshold_corrections = threshold_corrections * sqrt(768.0 / (
float)it1st);
462 if (ibase == 32) threshold_corrections = 24.0;
463 if (ibase == 64) threshold_corrections = 12.0;
464 if (ibase == 128) threshold_corrections = 6.0;
466 if (position1[l] > 0.01 * m_thr * threshold_corrections) {
470 B2RESULT(
"1st pass HS found! Layer: " << i + 3 <<
" Ladder: " << m <<
" Sensor: " << j <<
" Side: " << k <<
" channel: " << l);
474 occupancy[test.quot] = occupancy[test.quot] + hm_occupancy->getHistogram(*itSvdSensors, k)->GetBinContent(l + 1);
483 for (
int l = 0; l < 768; l++) {
484 div_t test = div(l, ibase);
485 position1[l] = position1[l] * nCltrk[test.quot] / (float)occupancy[test.quot];
486 float threshold_corrections = 1.0;
487 threshold_corrections = threshold_corrections * sqrt(768.0 / (
float)it);
488 if (ibase == 32) threshold_corrections = 24.0;
489 if (ibase == 64) threshold_corrections = 12.0;
490 if (ibase == 128) threshold_corrections = 6.0;
492 if ((flag[l]) && (position1[l] > 0.01 * m_thr * threshold_corrections)) {
496 B2RESULT(
"2nd pass HS FOUND! Layer: " << i + 3 <<
" Ladder: " << m <<
" Sensor: " << j <<
" Side: " << k <<
" channel: " << l);
503 for (
int l = 0; l < 768; l++) {
505 B2DEBUG(1, hsflag[l]);
507 float tmpOcc = hm_occupancy->getHistogram(*itSvdSensors, k)->GetBinContent(l + 1) / (double)nevents;
508 hm_occAll->fill(*itSvdSensors, k, tmpOcc);
510 if (hsflag[l] == 0) {
511 hm_occupancy_after->getHistogram(*itSvdSensors, k)->SetBinContent(l + 1, tmpOcc);
512 hm_occAfter->fill(*itSvdSensors, k, tmpOcc);
514 hm_hot_strips->getHistogram(*itSvdSensors, k)->SetBinContent(l + 1, 1);
515 hm_occHot->fill(*itSvdSensors, k, tmpOcc);
519 if (m_rootFilePtr != NULL) {
520 hm_occupancy->getHistogram(*itSvdSensors, k)->Scale(1.0 / (
double)nevents);
523 hm_occupancy->getHistogram(*itSvdSensors, k)->Write();
524 hm_hot_strips->getHistogram(*itSvdSensors, k)->SetLineColor(kBlack);
525 hm_hot_strips->getHistogram(*itSvdSensors, k)->SetFillStyle(3001);
526 hm_hot_strips->getHistogram(*itSvdSensors, k)->SetFillColor(kBlack);
527 hm_hot_strips->getHistogram(*itSvdSensors, k)->SetMarkerColor(kBlack);
528 hm_hot_strips->getHistogram(*itSvdSensors, k)->Write();
529 hm_occupancy_after->getHistogram(*itSvdSensors, k)->SetLineColor(kRed);
530 hm_occupancy_after->getHistogram(*itSvdSensors, k)->SetMarkerColor(kRed);
531 hm_occupancy_after->getHistogram(*itSvdSensors, k)->Write();
532 hm_occAll->getHistogram(*itSvdSensors, k)->Write();
533 hm_occHot->getHistogram(*itSvdSensors, k)->SetLineColor(kBlack);
534 hm_occHot->getHistogram(*itSvdSensors, k)->SetFillStyle(3001);
535 hm_occHot->getHistogram(*itSvdSensors, k)->SetFillColor(kBlack);
536 hm_occHot->getHistogram(*itSvdSensors, k)->SetMarkerColor(kBlack);
537 hm_occHot->getHistogram(*itSvdSensors, k)->Write();
538 hm_occAfter->getHistogram(*itSvdSensors, k)->SetLineColor(kRed);
539 hm_occAfter->getHistogram(*itSvdSensors, k)->SetMarkerColor(kRed);
540 hm_occAfter->getHistogram(*itSvdSensors, k)->Write();
544 B2DEBUG(1,
" side " << i <<
" " << j <<
" " << m <<
" " << k);
551 for (
int iy = 0; iy < iths; iy++) {
552 h_tot_dqm->Fill(
float(itsensor));
553 h_tot_dqm1->Fill(
float(itsensor));
556 for (
int s = 0; s < hm_hot_strips->getHistogram(*itSvdSensors, k)->GetEntries(); s++)
557 m_hHotStripsSummary->fill(*itSvdSensors, k, 1);
569 if (m_rootFilePtr != NULL) {
572 m_hHotStripsSummary->getHistogram(0)->Write();
573 m_hHotStripsSummary->getHistogram(1)->Write();
576 TIter nextH_occu(m_histoList_occu);
577 while ((obj = nextH_occu()))
580 m_rootFilePtr->Close();
586 TH1F* SVDHotStripFinderModule::createHistogram1D(
const char* name,
const char* title,
587 Int_t nbins, Double_t min, Double_t max,
588 const char* xtitle, TList* histoList)
591 TH1F* h =
new TH1F(name, title, nbins, min, max);
593 h->GetXaxis()->SetTitle(xtitle);
603 TH2F* SVDHotStripFinderModule::createHistogram2D(
const char* name,
const char* title,
604 Int_t nbinsX, Double_t minX, Double_t maxX,
606 Int_t nbinsY, Double_t minY, Double_t maxY,
607 const char* titleY, TList* histoList)
610 TH2F* h =
new TH2F(name, title, nbinsX, minX, maxX, nbinsY, minY, maxY);
611 h->GetXaxis()->SetTitle(titleX);
612 h->GetYaxis()->SetTitle(titleY);
621 bool SVDHotStripFinderModule::theHSFinder(
double* stripOccAfterAbsCut,
int* hsflag,
int nstrips)
628 int N = nstrips / m_base;
630 for (
int sector = 0; sector < N; sector++) {
633 double sensorOccAverage = 0;
635 for (
int l = sector * m_base; l < sector * m_base + m_base; l++) {
636 sensorOccAverage = sensorOccAverage + stripOccAfterAbsCut[l];
637 if (stripOccAfterAbsCut[l] > 0) nafter++;
639 sensorOccAverage = sensorOccAverage / nafter;
641 B2DEBUG(1,
"Average occupancy: " << sensorOccAverage);
643 for (
int l = sector * m_base; l < sector * m_base + m_base; l++) {
647 if (stripOccAfterAbsCut[l] > sensorOccAverage * m_relOccPrec) {
650 stripOccAfterAbsCut[l] = 0;