8#include <geometry/GeometryManager.h>
10#include <vxd/geometry/GeoCache.h>
13#include <framework/database/IntervalOfValidity.h>
14#include <framework/database/DBImportObjPtr.h>
16#include <svd/calibration/SVDHotStripsCalibrations.h>
17#include <svd/calibration/SVDOccupancyCalibrations.h>
18#include <svd/modules/svdCalibration/SVDHotStripFinderModule.h>
28 setDescription(
"The svdHotStripFinder module finds hot strips in SVD data SVDShaperDigit");
30 addParam(
"outputFileName",
m_rootFileName,
"Name of output root file.", std::string(
"SVDHotStripFinder.root"));
31 addParam(
"threshold",
m_thr,
"Threshold cut for Hot strip finder in percent",
float(4.0));
33 "number of strips used to compute the average occupancy, possible choices = 32, 64, 128. Default = -1, use all sensor strips.",
36 addParam(
"zeroSuppression",
m_zs,
"ZeroSuppression cut of the input SVDShaperDigits",
float(5));
43 addParam(
"useHSFinderV1",
m_useHSFinderV1,
"Set to false only if you want to test the second version of the algorithm",
46 "Absolute occupancy threshold: at a first loop, flag as Hot Strip (HS) all those whose occupancy > absOccThreshold",
float(0.2));
48 "Number of times the average sensor occupancy considered to fix the sensor dependent threshold, as for example occ_threshold = relOccPrec x occ_average",
50 addParam(
"verbose",
m_verbose,
" True by default, it allows to switch off the printing of all found HS.",
bool(
true));
72 B2RESULT(
"You are using the first version of the HSFinder algorithm (see SVDHotStripFinder::terminate in the module)");
73 else B2RESULT(
"You are using the modified version of the HSFinder algorithm (see SVDHotStripFinder::endRun in the module)");
81 TH1F hOccupancy768(
"Occupancy768_L@layerL@ladderS@sensor@view",
"Strip Occupancy of @layer.@ladder.@sensor @view/@side side", 768,
84 hOccupancy768.GetXaxis()->SetTitle(
"cellID");
85 TH1F hOccupancy512(
"Occupancy512_L@layerL@ladderS@sensor@view",
"Strip Occupancy of @layer.@ladder.@sensor @view/@side side", 512,
88 hOccupancy512.GetXaxis()->SetTitle(
"cellID");
91 TH1F hHotStrips768(
"HotStrips768_L@layerL@ladderS@sensor@view",
"Hot Strips of @layer.@ladder.@sensor @view/@side side", 768, 0,
93 hHotStrips768.GetXaxis()->SetTitle(
"cellID");
94 TH1F hHotStrips512(
"HotStrips512_L@layerL@ladderS@sensor@view",
"Hot Strips of @layer.@ladder.@sensor @view/@side side", 512, 0,
96 hHotStrips512.GetXaxis()->SetTitle(
"cellID");
99 TH1F hOccupancy_after768(
"OccupancyAfter768_L@layerL@ladderS@sensor@view",
100 "Non-Hot Strip Occupancy after HSF of @layer.@ladder.@sensor @view/@side side", 768, 0, 768);
101 hOccupancy_after768.GetXaxis()->SetTitle(
"cellID");
102 TH1F hOccupancy_after512(
"OccupancyAfter512_L@layerL@ladderS@sensor@view",
103 "Non-Hot Strip Occupancy after HSF of @layer.@ladder.@sensor @view/@side side", 512, 0, 512);
104 hOccupancy_after512.GetXaxis()->SetTitle(
"cellID");
107 TH1F hOccAll(
"occAll_L@layerL@ladderS@sensor@view",
"Strip Occupancy Distribution of @layer.@ladder.@sensor @view/@side side", 1000,
109 hOccAll.GetXaxis()->SetTitle(
"occupancy");
112 TH1F hOccHot(
"occHot_L@layerL@ladderS@sensor@view",
"Hot Strip Occupancy Distribution of @layer.@ladder.@sensor @view/@side side",
114 hOccHot.GetXaxis()->SetTitle(
"occupancy");
117 TH1F hOccAfter(
"occAfter_L@layerL@ladderS@sensor@view",
118 "Non-Hot Strip Occupancy Distribution of @layer.@ladder.@sensor @view/@side side", 1000, 0, 0.05);
119 hOccAfter.GetXaxis()->SetTitle(
"occupancy");
123 TH1F hDist(
"dist_L@layerL@ladderS@sensor@view",
"DSSD occupancy distribution of @layer.@ladder.@sensor @view/@side side", 100, 0,
125 hDist.GetXaxis()->SetTitle(
"occupancy");
128 TH1F hDist1(
"dist1_L@layerL@ladderS@sensor@view",
"DSSD true occupancy distribution of @layer.@ladder.@sensor @view/@side side",
131 hDist.GetXaxis()->SetTitle(
"occupancy");
133 TH2F hDist12(
"dist2d_L@layerL@ladderS@sensor@view",
134 "DSSD true vs sensor occupancy distribution of @layer.@ladder.@sensor @view/@side side", 1000, 0, 0.05, 1000, 0, 0.05);
135 hDist12.GetXaxis()->SetTitle(
"sensor occupancy");
136 hDist12.GetYaxis()->SetTitle(
"occupancy");
166 while (i < nDigits) {
188 TDirectory* oldDir =
nullptr;
189 TDirectory* dir_occuL[4] = {
nullptr,
nullptr,
nullptr,
nullptr};
195 dir_occuL[0] = oldDir->mkdir(
"layer3");
196 dir_occuL[1] = oldDir->mkdir(
"layer4");
197 dir_occuL[2] = oldDir->mkdir(
"layer5");
198 dir_occuL[3] = oldDir->mkdir(
"layer6");
209 occDBObjPtr.
construct(-99., Form(
"SVDOccupancy_exp%d_run%d_zs%1.1f", exp, run,
m_zs));
212 hotStripsDBObjPtr.
construct(0, Form(
"SVDHotStrips_exp%d_run%d_zs%1.1f_absThr%f_relOccPrec%f", exp, run,
m_zs,
m_absThr,
215 B2RESULT(
"number of events " << nevents);
219 std::set<Belle2::VxdID>::iterator itSvdLayers = svdLayers.begin();
220 while ((itSvdLayers != svdLayers.end())
221 && (itSvdLayers->getLayerNumber() != 7)) {
223 std::set<Belle2::VxdID> svdLadders = aGeometry.
getLadders(*itSvdLayers);
224 std::set<Belle2::VxdID>::iterator itSvdLadders = svdLadders.begin();
226 while (itSvdLadders != svdLadders.end()) {
228 std::set<Belle2::VxdID> svdSensors = aGeometry.
getSensors(*itSvdLadders);
229 std::set<Belle2::VxdID>::iterator itSvdSensors = svdSensors.begin();
231 while (itSvdSensors != svdSensors.end()) {
233 for (
int k = 0; k <
m_nSides; k ++) {
236 int layer = itSvdSensors->getLayerNumber();
237 int ladder = itSvdSensors->getLadderNumber();
238 int sensor = itSvdSensors->getSensorNumber();
242 if (!k && layer != 3) nstrips = 512;
244 double stripOcc[768];
245 for (
int i = 0; i < nstrips; i++) {stripOcc[i] = 0; hsflag[i] = 0;}
246 double stripOccAfterAbsCut[768];
248 for (
int l = 0; l < nstrips; l++) {
255 occDBObjPtr->set(layer, ladder, sensor, k, l, stripOcc[l]);
260 stripOccAfterAbsCut[l] = 0;
263 stripOccAfterAbsCut[l] = stripOcc[l];
266 B2DEBUG(1,
"Measured strip occupancy for strip " << l <<
":" << stripOccAfterAbsCut[l]);
272 while (moreHS &&
theHSFinder(stripOccAfterAbsCut, hsflag, nstrips)) {
273 moreHS =
theHSFinder(stripOccAfterAbsCut, hsflag, nstrips);
277 for (
int l = 0; l < nstrips; l++) {
278 hotStripsDBObjPtr->set(layer, ladder, sensor, k, l, (
int)hsflag[l]);
279 if (hsflag[l] == 0) {
286 TString aux_side =
"V/N";
287 if (k) aux_side =
"U/P";
288 if (
m_verbose) B2RESULT(
"HS found, occupancy = " << stripOcc[l] <<
", Layer: " << layer <<
" Ladder: " << ladder <<
" Sensor: "
290 " Side: " << k <<
" channel: " << l);
300 dir_occuL[layer - 3]->cd();
321 B2DEBUG(1,
" L" << layer <<
"." << ladder <<
"." << sensor <<
".isU=" << k);
350 hotStripsDBObjPtr.
import(iov);
351 B2RESULT(
"Imported to database.");
358 TDirectory* oldDir =
nullptr;
360 TDirectory* dir_occuL[4] = {
nullptr,
nullptr,
nullptr,
nullptr};
366 dir_occuL[0] = oldDir->mkdir(
"layer3");
367 dir_occuL[1] = oldDir->mkdir(
"layer4");
368 dir_occuL[2] = oldDir->mkdir(
"layer5");
369 dir_occuL[3] = oldDir->mkdir(
"layer6");
385 B2DEBUG(1,
"number of events " << nevents);
389 std::set<Belle2::VxdID>::iterator itSvdLayers = svdLayers.begin();
391 while ((itSvdLayers != svdLayers.end())
392 && (itSvdLayers->getLayerNumber() != 7)) {
394 std::set<Belle2::VxdID> svdLadders = aGeometry.
getLadders(*itSvdLayers);
395 std::set<Belle2::VxdID>::iterator itSvdLadders = svdLadders.begin();
397 while (itSvdLadders != svdLadders.end()) {
399 std::set<Belle2::VxdID> svdSensors = aGeometry.
getSensors(*itSvdLadders);
400 std::set<Belle2::VxdID>::iterator itSvdSensors = svdSensors.begin();
402 while (itSvdSensors != svdSensors.end()) {
404 for (
int k = 0; k <
m_nSides; k ++) {
407 int i = itSvdSensors->getLayerNumber() - 3;
408 int m = itSvdSensors->getLadderNumber() - 1;
409 int j = itSvdSensors->getSensorNumber() - 1;
410 float position1[768];
415 for (
int l = 0; l < 24; l++) {
419 for (
int l = 0; l < 768; l++) {
424 if (position1[l] == 0) { flag[l] = 0;}
429 div_t test = div(l, ibase);
430 nCltrk[test.quot] = nCltrk[test.quot] + position1[l];
435 for (
int l = 0; l < 768; l++) {
436 div_t test = div(l, ibase);
441 float tmp_occ = position1[l] / (float)nCltrk[test.quot];
442 float tmp_occ1 = position1[l] / (
float)nevents;
443 position1[l] = tmp_occ;
454 for (
int l = 0; l < 24; l++) {
460 for (
int l = 0; l < 768; l++) {
461 div_t test = div(l, ibase);
462 float threshold_corrections = 1.0;
466 threshold_corrections = threshold_corrections *
sqrt(768.0 / (
float)it1st);
467 if (ibase == 32) threshold_corrections = 24.0;
468 if (ibase == 64) threshold_corrections = 12.0;
469 if (ibase == 128) threshold_corrections = 6.0;
471 if (position1[l] > 0.01 *
m_thr * threshold_corrections) {
475 B2RESULT(
"1st pass HS found! Layer: " << i + 3 <<
" Ladder: " << m <<
" Sensor: " << j <<
" Side: " << k <<
" channel: " << l);
488 for (
int l = 0; l < 768; l++) {
489 div_t test = div(l, ibase);
490 position1[l] = position1[l] * nCltrk[test.quot] / (float)occupancy[test.quot];
491 float threshold_corrections = 1.0;
492 threshold_corrections = threshold_corrections *
sqrt(768.0 / (
float)it);
493 if (ibase == 32) threshold_corrections = 24.0;
494 if (ibase == 64) threshold_corrections = 12.0;
495 if (ibase == 128) threshold_corrections = 6.0;
497 if ((flag[l]) && (position1[l] > 0.01 *
m_thr * threshold_corrections)) {
501 B2RESULT(
"2nd pass HS FOUND! Layer: " << i + 3 <<
" Ladder: " << m <<
" Sensor: " << j <<
" Side: " << k <<
" channel: " << l);
508 for (
int l = 0; l < 768; l++) {
510 B2DEBUG(1, hsflag[l]);
515 if (hsflag[l] == 0) {
549 B2DEBUG(1,
" side " << i <<
" " << j <<
" " << m <<
" " << k);
556 for (
int iy = 0; iy < iths; iy++) {
582 while ((obj = nextH_occu()))
592 Int_t nbins, Double_t min, Double_t max,
593 const char* xtitle, TList* histoList)
596 TH1F* h =
new TH1F(name, title, nbins, min, max);
598 h->GetXaxis()->SetTitle(xtitle);
609 Int_t nbinsX, Double_t minX, Double_t maxX,
611 Int_t nbinsY, Double_t minY, Double_t maxY,
612 const char* titleY, TList* histoList)
615 TH2F* h =
new TH2F(name, title, nbinsX, minX, maxX, nbinsY, minY, maxY);
616 h->GetXaxis()->SetTitle(titleX);
617 h->GetYaxis()->SetTitle(titleY);
635 for (
int sector = 0; sector < N; sector++) {
638 double sensorOccAverage = 0;
641 sensorOccAverage = sensorOccAverage + stripOccAfterAbsCut[l];
642 if (stripOccAfterAbsCut[l] > 0) nafter++;
644 sensorOccAverage = sensorOccAverage / nafter;
646 B2DEBUG(1,
"Average occupancy: " << sensorOccAverage);
652 if (stripOccAfterAbsCut[l] > sensorOccAverage *
m_relOccPrec) {
655 stripOccAfterAbsCut[l] = 0;
bool import(const IntervalOfValidity &iov)
Import the object to database.
Class for importing a single object to the database.
void construct(Args &&... params)
Construct an object of type T in this DBImportObjPtr using the provided constructor arguments.
A class that describes the interval of experiments/runs for which an object in the database is valid.
void setDescription(const std::string &description)
Sets the description of the module.
template class for SVd histograms
void fill(const VxdID &vxdID, int view, Types ... args)
fill the histogram for
H * getHistogram(const VxdID &vxdID, int view)
get a reference to the histogram for
std::string m_rootFileName
root file name
TH1F * createHistogram1D(const char *name, const char *title, Int_t nbins, Double_t min, Double_t max, const char *xtitle, TList *histoList=nullptr)
create 1D histograms
StoreArray< SVDShaperDigit > m_storeDigits
shaper digits store array
float m_absThr
Absolute Occupancy Threshold cut for Hot strip finder.
SVDHistograms< TH1F > * hm_occupancy
strip occupancy per sensor
SVDHotStripFinderModule()
Constructor, for setting module description and parameters.
std::string m_ShaperDigitName
shaper digits name
SVDHistograms< TH1F > * hm_hot_strips
hot strips per sensor
virtual void initialize() override
Use this to initialize resources or memory your module needs.
SVDHistograms< TH2F > * hm_dist12
true occupancy VS sensor histograms
virtual void event() override
Called once for each event.
TList * m_histoList_occu
occupancy for low charge clusters
float m_relOccPrec
Relative precision on occupancy which is defined to be negligible for the hit background rate estimat...
virtual void endRun() override
Called once when a run ends.
TH1F * h_tot_dist1
absolute occupany histogram
SVDHistograms< TH1F > * hm_dist1
true occupancy histograms
virtual void terminate() override
Clean up anything you created in initialize().
SVDSummaryPlots * m_hHotStripsSummary
hot strip summary histo
bool theHSFinder(double *stripOccAfterAbsCut, int *hsflag, int nstrips)
return true if the strip is hot
static const int m_nSides
number of sides
StoreObjPtr< EventMetaData > m_eventMetaData
event meta data store array
SVDHistograms< TH1F > * hm_dist
occupancy histograms
virtual void beginRun() override
Called once before a new run begins.
SVDHistograms< TH1F > * hm_occAll
occupancy distribution - all strips
float m_zs
zero suppression cut for the input shaper digits
int m_lastExp
last valid experiment
virtual ~SVDHotStripFinderModule()
Use to clean up anything you created in the constructor.
int m_lastRun
last valid run
TH1F * h_nevents
number of events counting
TH1F * h_tot_dist
relative occupancy histogram
SVDHistograms< TH1F > * hm_occAfter
occupancy distribution - not hot strips
int m_firstExp
first valid experiment
TH2F * h_tot_dist12
2d distributiuons of occupancies
SVDHistograms< TH1F > * hm_occHot
occupancy distribution - hot strips
int m_firstRun
first valid run
TH1F * h_tot_dqm
number of hot strips per sensor
TH2F * createHistogram2D(const char *name, const char *title, Int_t nbinsX, Double_t minX, Double_t maxX, const char *titleX, Int_t nbinsY, Double_t minY, Double_t maxY, const char *titleY, TList *histoList=nullptr)
create 2D histograms
SVDHistograms< TH1F > * hm_occupancy_after
strip occupancy after removal of hot strips, per sensor
TFile * m_rootFilePtr
pointer at root file used for storing histograms
TH1F * h_tot_dqm1
number of hot strips per sensor for layer 3
bool m_verbose
False by default, it allows to switch on the printing of all found HS.
bool m_useHSFinderV1
use V1 finder
static std::string name
name of the SVDHotStripsCalibrations payload
static std::string name
name of the ccupancy payload
class to summarize SVD quantities per sensor and side
void fill(int layer, int ladder, int sensor, int view, float value)
fill the histogram for
TH2F * getHistogram(int view)
get a reference to the histogram for
Class to faciliate easy access to sensor information of the VXD like coordinate transformations or pi...
const std::set< Belle2::VxdID > getLayers(SensorInfoBase::SensorType sensortype=SensorInfoBase::VXD)
Return a set of all known Layers.
const std::set< Belle2::VxdID > & getSensors(Belle2::VxdID ladder) const
Return a set of all sensor IDs belonging to a given ladder.
static GeoCache & getInstance()
Return a reference to the singleton instance.
const std::set< Belle2::VxdID > & getLadders(Belle2::VxdID layer) const
Return a set of all ladder IDs belonging to a given layer.
Class to uniquely identify a any structure of the PXD and SVD.
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.
double sqrt(double a)
sqrt for double
Abstract base class for different kinds of events.