Belle II Software development
SVDCrossTalkCalibrationsCollectorModule.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#include <svd/modules/svdCrossTalkCalibrationsCollector/SVDCrossTalkCalibrationsCollectorModule.h>
10
11#include <svd/modules/svdCrossTalkFinder/SVDCrossTalkFinderHelperFunctions.h>
12
13#include <vxd/geometry/GeoCache.h>
14
15#include <TH1F.h>
16
17#include <iostream>
18
19
20using namespace std;
21using namespace Belle2;
22
23
24REG_MODULE(SVDCrossTalkCalibrationsCollector);
25
27{
28 setDescription("This module collects the list of channels exhibiting crossTalk readout.");
29
31
32 addParam("SVDShaperDigits", m_svdShaperDigitsName,
33 "SVDShaperDigit collection name", string(""));
34
35 addParam("uSideOccupancyFactor", m_uSideOccupancyFactor,
36 "Multiple of the average occupancy for high occupancy strip classification", 2);
37
38 addParam("vSideOccupancyFactor", m_vSideOccupancyFactor,
39 "Multiple of the average occupancy for high occupancy strip classification", 2);
40
41 addParam("nAPVFactor", m_nAPVFactor,
42 "Number of APV chips with at least one high occupancy strips in event required for cross talk flag", 30);
43
44}
45
47{
48
50
51
52 m_histogramTree = new TTree("tree", "tree");
53 m_histogramTree->Branch("hist", "TH1F", &m_hist, 32000, 0);
54 m_histogramTree->Branch("layer", &m_layer, "layer/I");
55 m_histogramTree->Branch("ladder", &m_ladder, "ladder/I");
56 m_histogramTree->Branch("sensor", &m_sensor, "sensor/I");
57 m_histogramTree->Branch("side", &m_side, "side/I");
58
59 registerObject<TTree>("HTreeCrossTalkCalib", m_histogramTree);
60
61
62}
63
65{
66
67 std::string sensorName;
68 TH1F* sensorHist;
69 //Prepare histograms for payload.
71 for (auto& layers : geo.getLayers(VXD::SensorInfoBase::SVD)) {
72 for (auto& ladders : geo.getLadders(layers)) {
73 for (auto& sensors : geo.getSensors(ladders)) {
74 for (int side = 0; side <= 1; side++) {
75 occupancyPDFName(sensors, side, sensorName);
76 if (m_sensorHistograms.count(sensorName) == 0) {
77 if (layers.getLayerNumber() == 3 or side == 1) {
78 sensorHist = new TH1F(sensorName.c_str(), "", 768, 0, 768);
79 } else {
80 sensorHist = new TH1F(sensorName.c_str(), "", 512, 0, 512);
81 }
82 m_sensorHistograms[sensorName] = sensorHist;
83
84 }
85
86 }
87 }
88 }
89 }
90
91}
92
94{
95 //Vectors to hold event info.
96 vector<std::string> highOccChips_uSide ;
97 vector<std::string> highOccChips_vSide ;
98 vector<std::string> highOccChipsStripNum_uSide ;
99 vector<std::string> highOccChipsStripNum_vSide ;
100 vector<std::string> clusterStrips_uSide ;
101 vector<std::string> clusterStrips_vSide ;
102 vector<std::string> clusterChips_uSide ;
103 vector<int> strips_uSide;
104 vector<int> strips_vSide;
105
106 //loop over ShaperDigits
107 for (auto& svdShaperDigit : m_svdShaperDigits) {
108 //Remove L3 and +fw sensors, not affected by cross-talk
109 if (svdShaperDigit.getSensorID().getLayerNumber() == 3 or svdShaperDigit.getSensorID().getSensorNumber() == 1) {
110 continue;
111 }
112
113 int side = svdShaperDigit.isUStrip();
114 std::string sensorName;
115 occupancyPDFName(svdShaperDigit.getSensorID(), side, sensorName);
116
117 double sensorAverage = 0.;
118 calculateAverage(svdShaperDigit.getSensorID(), sensorAverage, side);
119 int stripID = svdShaperDigit.getCellID();
120 std::string sensorStripNum = sensorName + "." + std::to_string(stripID);
121 double stripOccupancy = m_OccupancyCal.getOccupancy(svdShaperDigit.getSensorID(), side, stripID);
122 //Clustering only works assuming digits are ordered.//
123 if (side == 1 && stripOccupancy > (m_uSideOccupancyFactor * sensorAverage)) {
124
125 int adjacentStrip = 0;
126 if (!strips_uSide.empty()) {
127 adjacentStrip = stripID - strips_uSide.back();
128 }
129 strips_uSide.push_back(stripID);
130 if (!highOccChips_uSide.empty() && sensorName == highOccChips_uSide.back() && adjacentStrip == 1) {
131 clusterChips_uSide.push_back(sensorName);
132 if (clusterStrips_uSide.empty() || clusterStrips_uSide.back() != sensorStripNum) {
133 clusterStrips_uSide.push_back(highOccChipsStripNum_uSide.back());
134 }
135 clusterStrips_uSide.push_back(sensorStripNum);
136 }
137 highOccChipsStripNum_uSide.push_back(sensorStripNum);
138 highOccChips_uSide.push_back(sensorName);
139 }
140
141 if (side == 0 && stripOccupancy > (m_vSideOccupancyFactor * sensorAverage)) {
142 int adjacentStrip = 0;
143 if (!strips_vSide.empty()) {
144 adjacentStrip = stripID - strips_vSide.back();
145 }
146 strips_vSide.push_back(stripID);
147 if (!highOccChips_vSide.empty() && sensorName == highOccChips_vSide.back() && adjacentStrip == 1) {
148 if (clusterStrips_vSide.empty() || clusterStrips_vSide.back() != sensorStripNum) {
149 clusterStrips_vSide.push_back(highOccChipsStripNum_vSide.back());
150 }
151 clusterStrips_vSide.push_back(sensorStripNum);
152 }
153 highOccChipsStripNum_vSide.push_back(sensorStripNum);
154 highOccChips_vSide.push_back(sensorName);
155 }
156
157 } //ShaperDigit loop
158
159 std::sort(clusterChips_uSide.begin(), clusterChips_uSide.end());
160 clusterChips_uSide.erase(unique(clusterChips_uSide.begin(), clusterChips_uSide.end()), clusterChips_uSide.end());
161 int numberOfClusterChips = std::distance(clusterChips_uSide.begin(), std::unique(clusterChips_uSide.begin(),
162 clusterChips_uSide.end()));
163
164// Crosstalk events flagged using u-side
165 if (numberOfClusterChips > m_nAPVFactor) {
166 for (auto& svdShaperDigit : m_svdShaperDigits) {
167 std::string sensorID = svdShaperDigit.getSensorID();
168 std::string digitID = sensorID + "." + std::to_string(svdShaperDigit.isUStrip());
169 std::string stripID = digitID + "." + std::to_string(svdShaperDigit.getCellID());
170 if (std::find(clusterStrips_uSide.begin(), clusterStrips_uSide.end(), stripID) != clusterStrips_uSide.end()) {
171 std::string sensorName;
172 occupancyPDFName(svdShaperDigit.getSensorID(), svdShaperDigit.isUStrip(), sensorName);
173 auto xTalkStrip = m_sensorHistograms.at(sensorName);
174 xTalkStrip->Fill(svdShaperDigit.getCellID(), 1);
175 }
176 if (std::find(clusterStrips_vSide.begin(), clusterStrips_vSide.end(), stripID) != clusterStrips_vSide.end()) {
177 std::string sensorName;
178 occupancyPDFName(svdShaperDigit.getSensorID(), svdShaperDigit.isUStrip(), sensorName);
179 auto xTalkStrip = m_sensorHistograms.at(sensorName);
180 xTalkStrip->Fill(svdShaperDigit.getCellID(), 1);
181 }
182
183
184 }//shaper digit loop
185 }
186} //Collector loop
187
188
190{}
191
193{
194 std::string sensorName;
196 for (auto& layers : geo.getLayers(VXD::SensorInfoBase::SVD)) {
197 for (auto& ladders : geo.getLadders(layers)) {
198 for (auto& sensors : geo.getSensors(ladders)) {
199 for (int side = 0; side <= 1; side++) {
200
201 occupancyPDFName(sensors, side, sensorName);
202 auto sensorOnMap = m_sensorHistograms.at(sensorName);
203 m_hist = sensorOnMap;
204 m_layer = sensors.getLayerNumber();
205 m_ladder = sensors.getLadderNumber();
206 m_sensor = sensors.getSensorNumber();
207 m_side = side;
208
209 getObjectPtr<TTree>("HTreeCrossTalkCalib")->Fill();
210
211 sensorOnMap->Delete();
212 }
213 }
214 }
215 }
216
217}
218
219
220void SVDCrossTalkCalibrationsCollectorModule::calculateAverage(const VxdID& sensorID, double& mean, int side)
221{
222 double nBins = 0;
223 if (side == 1) nBins = 768; //U-side 768 channels
224 else nBins = 512;
225 double count = 0;
226 for (int i = 0; i < nBins; i++) {
227 count += m_OccupancyCal.getOccupancy(sensorID, side, i);
228 }
229 mean = count / nBins;
230}
231
Calibration collector module base class.
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition: Module.cc:208
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition: Module.h:80
std::string m_svdShaperDigitsName
SVDShaperDigit collection name.
int m_uSideOccupancyFactor
Parameter to define high occupancy strips (some multiple above sensor average occupancy)
int m_vSideOccupancyFactor
Parameter to define high occupancy strips (some multiple above sensor average occupancy)
StoreArray< SVDShaperDigit > m_svdShaperDigits
The storeArray for svdShaperDigits.
std::map< std::string, TH1F * > m_sensorHistograms
map to store cross-talk strip histograms
void calculateAverage(const VxdID &sensorID, double &mean, int side)
Function to calculate sensor average occupancy.
SVDOccupancyCalibrations m_OccupancyCal
SVDOccupancy calibrations db object.
int m_nAPVFactor
Parameter to set number of sensors with possible cross-talk clusters required for event flagging.
float getOccupancy(const VxdID &sensorID, const bool &isU, const unsigned short &strip) const
This is the method for getting the occupancy, or the deviation from the average, still to be decided.
Class to faciliate easy access to sensor information of the VXD like coordinate transformations or pi...
Definition: GeoCache.h:39
const std::set< Belle2::VxdID > getLayers(SensorInfoBase::SensorType sensortype=SensorInfoBase::VXD)
Return a set of all known Layers.
Definition: GeoCache.cc:176
const std::set< Belle2::VxdID > & getSensors(Belle2::VxdID ladder) const
Return a set of all sensor IDs belonging to a given ladder.
Definition: GeoCache.cc:204
static GeoCache & getInstance()
Return a reference to the singleton instance.
Definition: GeoCache.cc:214
const std::set< Belle2::VxdID > & getLadders(Belle2::VxdID layer) const
Return a set of all ladder IDs belonging to a given layer.
Definition: GeoCache.cc:193
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:33
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition: Module.h:560
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
void occupancyPDFName(const VxdID &sensor, int side, std::string &PDFName)
Function to maintain common naming convention between calibration occupancy file generation and occup...
Abstract base class for different kinds of events.
STL namespace.