9 #include <svd/modules/svdCrossTalkCalibrationsCollector/SVDCrossTalkCalibrationsCollectorModule.h>
11 #include <svd/modules/svdCrossTalkFinder/SVDCrossTalkFinderHelperFunctions.h>
13 #include <vxd/geometry/GeoCache.h>
28 setDescription(
"This module collects the list of channels exhibiting crossTalk readout.");
30 setPropertyFlags(c_ParallelProcessingCertified);
32 addParam(
"SVDShaperDigits", m_svdShaperDigitsName,
33 "SVDShaperDigit collection name",
string(
""));
35 addParam(
"uSideOccupancyFactor", m_uSideOccupancyFactor,
36 "Multiple of the average occupancy for high occupancy strip classification", 2);
38 addParam(
"vSideOccupancyFactor", m_vSideOccupancyFactor,
39 "Multiple of the average occupancy for high occupancy strip classification", 2);
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);
46 void SVDCrossTalkCalibrationsCollectorModule::prepare()
49 m_svdShaperDigits.isRequired(m_svdShaperDigitsName);
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");
59 registerObject<TTree>(
"HTreeCrossTalkCalib", m_histogramTree);
64 void SVDCrossTalkCalibrationsCollectorModule::startRun()
67 std::string sensorName;
71 for (
auto& layers : geo.
getLayers(VXD::SensorInfoBase::SVD)) {
73 for (
auto& sensors : geo.
getSensors(ladders)) {
74 for (
int side = 0; side <= 1; side++) {
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);
80 sensorHist =
new TH1F(sensorName.c_str(),
"", 512, 0, 512);
82 m_sensorHistograms[sensorName] = sensorHist;
93 void SVDCrossTalkCalibrationsCollectorModule::collect()
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;
107 for (
auto& svdShaperDigit : m_svdShaperDigits) {
109 if (svdShaperDigit.getSensorID().getLayerNumber() == 3 or svdShaperDigit.getSensorID().getSensorNumber() == 1) {
113 int side = svdShaperDigit.isUStrip();
114 std::string sensorName;
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);
123 if (side == 1 && stripOccupancy > (m_uSideOccupancyFactor * sensorAverage)) {
125 int adjacentStrip = 0;
126 if (!strips_uSide.empty()) {
127 adjacentStrip = stripID - strips_uSide.back();
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());
135 clusterStrips_uSide.push_back(sensorStripNum);
137 highOccChipsStripNum_uSide.push_back(sensorStripNum);
138 highOccChips_uSide.push_back(sensorName);
141 if (side == 0 && stripOccupancy > (m_vSideOccupancyFactor * sensorAverage)) {
142 int adjacentStrip = 0;
143 if (!strips_vSide.empty()) {
144 adjacentStrip = stripID - strips_vSide.back();
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());
151 clusterStrips_vSide.push_back(sensorStripNum);
153 highOccChipsStripNum_vSide.push_back(sensorStripNum);
154 highOccChips_vSide.push_back(sensorName);
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()));
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);
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);
189 void SVDCrossTalkCalibrationsCollectorModule::finish()
192 void SVDCrossTalkCalibrationsCollectorModule::closeRun()
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++) {
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();
209 getObjectPtr<TTree>(
"HTreeCrossTalkCalib")->Fill();
211 sensorOnMap->Delete();
220 void SVDCrossTalkCalibrationsCollectorModule::calculateAverage(
const VxdID& sensorID,
double& mean,
int side)
223 if (side == 1) nBins = 768;
226 for (
int i = 0; i < nBins; i++) {
227 count += m_OccupancyCal.getOccupancy(sensorID, side, i);
229 mean = count / nBins;
Calibration collector module base class.
Collector module used to create the histograms needed for the cross talk calibration.
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.
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.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
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.