Belle II Software development
SVDOccupancyAnalysisModule.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/svdPerformance/SVDOccupancyAnalysisModule.h>
10#include <hlt/softwaretrigger/core/FinalTriggerDecisionCalculator.h>
11#include <framework/utilities/MathHelpers.h>
12
13#include <TMath.h>
14
15using namespace std;
16using namespace Belle2;
17using namespace SoftwareTrigger;
18
19REG_MODULE(SVDOccupancyAnalysis);
20
22{
23
24 setDescription("This module check performances of SVD reconstruction of VXD TB data");
25
26 addParam("outputFileName", m_rootFileName, "Name of output root file.", std::string("SVDOccupancyAnalysis_output.root"));
27
28 addParam("skipHLTRejectedEvents", m_skipRejectedEvents, "If TRUE skip events rejected by HLT", bool(false));
29 addParam("groupNevents", m_group, "Number of events to group", float(10000));
30 addParam("FADCmode", m_FADCmode,
31 "FADC mode: if true the approximation to integer is done", bool(false));
32 addParam("minZScut", m_minZS, "Minimum ZS cut", float(3));
33 addParam("maxZScut", m_maxZS, "Maximum ZS cut", float(6));
34 addParam("pointsZScut", m_pointsZS, "Number of ZS cuts", int(8));
35
36 addParam("ShaperDigitsName", m_ShaperDigitName, "Name of ShaperDigit Store Array.", std::string(""));
37}
38
40{
41
42 m_eventMetaData.isRequired();
44 B2INFO(" ShaperDigits: " << m_ShaperDigitName);
45
46 m_rootFilePtr = new TFile(m_rootFileName.c_str(), "RECREATE");
47
48 m_nEvents = 0;
49
50}
51
52
54{
55
56
57 m_occ_L3U = new TH1F("occL3U", "Occupancy Distribution for L3 U side", m_distr_Nbins, m_distr_min, m_distr_max);
58 m_occ_L3U->GetXaxis()->SetTitle("occupancy(%)");
59 m_occ_L3V = new TH1F("occL3V", "Occupancy Distribution for L3 V side", m_distr_Nbins, m_distr_min, m_distr_max);
60 m_occ_L3V->GetXaxis()->SetTitle("occupancy(%)");
61 m_occ_L4U = new TH1F("occL4U", "Occupancy Distribution for L4 U side", m_distr_Nbins, m_distr_min, m_distr_max);
62 m_occ_L4U->GetXaxis()->SetTitle("occupancy(%)");
63 m_occ_L4V = new TH1F("occL4V", "Occupancy Distribution for L4 V side", m_distr_Nbins, m_distr_min, m_distr_max);
64 m_occ_L4V->GetXaxis()->SetTitle("occupancy(%)");
65 m_occ_L5U = new TH1F("occL5U", "Occupancy Distribution for L5 U side", m_distr_Nbins, m_distr_min, m_distr_max);
66 m_occ_L5U->GetXaxis()->SetTitle("occupancy(%)");
67 m_occ_L5V = new TH1F("occL5V", "Occupancy Distribution for L5 V side", m_distr_Nbins, m_distr_min, m_distr_max);
68 m_occ_L5V->GetXaxis()->SetTitle("occupancy(%)");
69 m_occ_L6U = new TH1F("occL6U", "Occupancy Distribution for L6 U side", m_distr_Nbins, m_distr_min, m_distr_max);
70 m_occ_L6U->GetXaxis()->SetTitle("occupancy(%)");
71 m_occ_L6V = new TH1F("occL6V", "Occupancy Distribution for L6 V side", m_distr_Nbins, m_distr_min, m_distr_max);
72 m_occ_L6V->GetXaxis()->SetTitle("occupancy(%)");
73
74
76
77 //collect the list of all SVD Modules in the geometry here
78 std::vector<VxdID> sensors = geo.getListOfSensors();
79 for (VxdID& aVxdID : sensors) {
80 VXD::SensorInfoBase info = geo.getSensorInfo(aVxdID);
81 if (info.getType() != VXD::SensorInfoBase::SVD) continue;
82 m_SVDModules.push_back(aVxdID); // reorder, sort would be better
83 }
84 std::sort(m_SVDModules.begin(), m_SVDModules.end()); // back to natural order
85
86 m_hit = new SVDSummaryPlots("hits@view", "Number of hits on @view/@side Side");
87
88 TH1F h_dist("dist_L@layerL@ladderS@sensor@view",
89 "Occupancy Distribution (layer @layer, ladder @ladder, sensor @sensor, side@view/@side)",
91 h_dist.GetXaxis()->SetTitle("occupancy (%)");
93
94 TH1F h_occ_768("occ768_L@layerL@ladderS@sensor@view", "Occupancy (layer @layer, ladder @ladder, sensor @sensor, side@view/@side)",
95 768, 0, 768);
96 h_occ_768.GetXaxis()->SetTitle("cellID");
97 TH1F h_occ_512("occ512_L@layerL@ladderS@sensor@view", "Occupancy (layer @layer, ladder @ladder, sensor @sensor, side@view/@side)",
98 512, 0, 512);
99 h_occ_512.GetXaxis()->SetTitle("cellID");
100 m_histo_occ = new SVDHistograms<TH1F>(h_occ_768, h_occ_768, h_occ_768, h_occ_512);
101
102
103 TH1F h_zsVSocc("occVSzs_L@layerL@ladderS@sensor@view",
104 "Average Occupancy VS Zero Suppression (layer @layer, ladder @ladder, sensor @sensor, side@view/@side)", m_pointsZS, m_minZS,
105 m_maxZS);
106 h_zsVSocc.GetXaxis()->SetTitle("ZS cut");
107 m_histo_zsOcc = new SVDHistograms<TH1F>(h_zsVSocc);
108
109
110 TH1F h_zsVSoccSQ("zsVSoccSQ_L@layerL@ladderS@sensor@view",
111 "Average Occupancy VS (ZS cut)^2 (layer @layer, ladder @ladder, sensor @sensor, side@view/@side)", 100, square(m_minZS) - 5,
112 square(m_maxZS));
113 h_zsVSoccSQ.GetXaxis()->SetTitle("(ZS cut)^2");
114 m_histo_zsOccSQ = new SVDHistograms<TH1F>(h_zsVSoccSQ);
115
116
117 TH2F h_occtdep_768("occ768VSevt_L@layerL@ladderS@sensor@view",
118 "Average Occupancy VS Event Number (layer @layer, ladder @ladder, sensor @sensor, side@view/@side)",
119 1000, 0, 1000, 768, 0, 768);
120 h_occtdep_768.GetXaxis()->SetTitle(Form("evt number/%1.0f", m_group));
121 h_occtdep_768.GetYaxis()->SetTitle("cellID");
122
123 TH2F h_occtdep_512("occ512VSevt_L@layerL@ladderS@sensor@view",
124 "Average Occupancy VS Event Number (layer @layer, ladder @ladder, sensor @sensor, side@view/@side)",
125 1000, 0, 1000, 512, 0, 512);
126 h_occtdep_512.GetXaxis()->SetTitle(Form("evt number/%1.0f", m_group));
127 h_occtdep_512.GetYaxis()->SetTitle("cellID");
128
129 m_histo_occtdep = new SVDHistograms<TH2F>(h_occtdep_768, h_occtdep_768, h_occtdep_768, h_occtdep_512);
130
131}
132
134{
135
138 if (!eventAccepted) return;
139 }
140
141 m_nEvents++;
142 int nEvent = m_eventMetaData->getEvent();
143
144 //shaper digits
145 for (int digi = 0 ; digi < m_svdShapers.getEntries(); digi++) {
146
147
148 VxdID::baseType theVxdID = (VxdID::baseType)m_svdShapers[digi]->getSensorID();
149 int side = m_svdShapers[digi]->isUStrip();
150
151 //fill standard occupancy plot, for default zero suppression
152 m_histo_occtdep->fill(theVxdID, side, nEvent / m_group, m_svdShapers[digi]->getCellID());
153
154 m_hit->fill(theVxdID, side, 1);
155
156 m_histo_occ->fill(theVxdID, side, m_svdShapers[digi]->getCellID());
157
158 float noise = m_NoiseCal.getNoise(theVxdID, side, m_svdShapers[digi]->getCellID());
159 float step = (m_maxZS - m_minZS) / m_pointsZS;
160
161 for (int z = 0; z <= m_pointsZS; z++) {
162 int nOKSamples = 0;
163 float cutMinSignal = (m_minZS + step * z) * noise;
164
165 if (m_FADCmode) {
166 cutMinSignal = cutMinSignal + 0.5;
167 cutMinSignal = (int)cutMinSignal;
168 }
169
170
171 Belle2::SVDShaperDigit::APVFloatSamples samples_vec = m_svdShapers[digi]->getSamples();
172
173 for (int k = 0; k < 6; k ++)
174 if (samples_vec[k] > cutMinSignal)
175 nOKSamples++;
176
177 if (nOKSamples > 0) {
178 m_histo_zsOcc->fill(theVxdID, side, m_minZS + z * step);
179 m_histo_zsOccSQ->fill(theVxdID, side, square(m_minZS + z * step));
180 }
181 }
182
183 }
184
185 //loop on sensors, fill and clear
186 for (unsigned int i = 0; i < m_SVDModules.size(); i++) {
187 B2DEBUG(10, "module " << i << "," << m_SVDModules[i]);
188 float nStripsV = 512;
189 if (m_SVDModules[i].getLayerNumber() == 3)
190 nStripsV = 768;
191
192 double occU = 100. * m_hit->getValue(m_SVDModules[i], 1) / 768;
193 double occV = 100. * m_hit->getValue(m_SVDModules[i], 0) / nStripsV;
194
195 m_histo_dist->fill(m_SVDModules[i], 1, occU);
196 m_histo_dist->fill(m_SVDModules[i], 0, occV);
197
198 if (m_SVDModules[i].getLayerNumber() == 3) {
199 m_occ_L3U->Fill(occU);
200 m_occ_L3V->Fill(occV);
201 }
202 if (m_SVDModules[i].getLayerNumber() == 4) {
203 m_occ_L4U->Fill(occU);
204 m_occ_L4V->Fill(occV);
205 }
206 if (m_SVDModules[i].getLayerNumber() == 5) {
207 m_occ_L5U->Fill(occU);
208 m_occ_L5V->Fill(occV);
209 }
210 if (m_SVDModules[i].getLayerNumber() == 6) {
211 m_occ_L6U->Fill(occU);
212 m_occ_L6V->Fill(occV);
213 }
214
215 }
216
217 (m_hit->getHistogram(0))->Reset();
218 (m_hit->getHistogram(1))->Reset();
219
220}
221
222
224{
225
226 if (m_rootFilePtr != nullptr) {
227 m_rootFilePtr->cd();
228
229 TDirectory* oldDir = gDirectory;
230
231 m_occ_L3U->Write();
232 m_occ_L3V->Write();
233 m_occ_L4U->Write();
234 m_occ_L4V->Write();
235 m_occ_L5U->Write();
236 m_occ_L5V->Write();
237 m_occ_L6U->Write();
238 m_occ_L6V->Write();
239
241
242 for (auto layer : geoCache.getLayers(VXD::SensorInfoBase::SVD)) {
243 TString layerName = Form("occupancyL%d", layer.getLayerNumber());
244 TDirectory* dir_layer = oldDir->mkdir(layerName.Data());
245 dir_layer->cd();
246 for (auto ladder : geoCache.getLadders(layer))
247 for (Belle2::VxdID sensor : geoCache.getSensors(ladder))
248 for (int view = SVDHistograms<TH1F>::VIndex ; view < SVDHistograms<TH1F>::UIndex + 1; view++) {
249 (m_histo_dist->getHistogram(sensor, view))->Write();
250
251 (m_histo_occ->getHistogram(sensor, view))->Scale(1. / m_nEvents);
252 (m_histo_occ->getHistogram(sensor, view))->Write();
253
254 int nStrips = 768;
255 if (sensor.getLayerNumber() != 3 && view == SVDHistograms<TH1F>::VIndex)
256 nStrips = 512;
257
258 (m_histo_zsOcc->getHistogram(sensor, view))->Scale(1. / m_nEvents / nStrips);
259 (m_histo_zsOcc->getHistogram(sensor, view))->Write();
260 (m_histo_zsOccSQ->getHistogram(sensor, view))->Scale(1. / m_nEvents / nStrips);
261 (m_histo_zsOccSQ->getHistogram(sensor, view))->Write();
262
263 (m_histo_occtdep->getHistogram(sensor, view))->Scale(1. / m_group);
264 (m_histo_occtdep->getHistogram(sensor, view))->Write();
265 }
266 }
267
268 m_rootFilePtr->Close();
269
270 }
271}
272
273
void setDescription(const std::string &description)
Sets the description of the module.
Definition Module.cc:214
Module()
Constructor.
Definition Module.cc:30
template class for SVd histograms
SVDSummaryPlots * m_hit
hit number summary histogram
int m_pointsZS
number of steps for different ZS cuts
bool m_skipRejectedEvents
if true skip events rejected by HLT
bool m_FADCmode
if true, ZS done with same algorithm as on FADC
SVDHistograms< TH1F > * m_histo_occ
occupancy histograms
std::string m_ShaperDigitName
ShaperDigit StoreArray name.
virtual void initialize() override
check StoreArrays & create rootfile
TH1F * m_occ_L4V
occupancy distribution for L4 V-side sensors
virtual void event() override
fill histograms
SVDHistograms< TH2F > * m_histo_occtdep
occupancy VS event number
SVDHistograms< TH1F > * m_histo_zsOccSQ
occupancy VS ZS cut swuared histograms
std::vector< VxdID > m_SVDModules
IDs of all SVD Modules to iterate over.
SVDNoiseCalibrations m_NoiseCal
SVDNoise calibrations db object.
virtual void endRun() override
write histogrmas
float m_group
number of events to compute occupancy for occ VS time
TH1F * m_occ_L6U
occupancy distribution for L6 U-side sensors
float m_minZS
minimum zero suppression cut
TH1F * m_occ_L5U
occupancy distribution for L5 U-side sensors
StoreObjPtr< EventMetaData > m_eventMetaData
Event Meta Data StoreObjectPointer.
SVDHistograms< TH1F > * m_histo_dist
occupancy distribution histograms
float m_distr_Nbins
number of bins of occupancy distributions
virtual void beginRun() override
create histograms
TH1F * m_occ_L4U
occupancy distribution for L4 U-side sensors
TH1F * m_occ_L6V
occupancy distribution for L6 V-side sensors
float m_distr_max
max of occupancy distributions
float m_distr_min
min of occupancy distributions
TH1F * m_occ_L3V
occupancy distribution for L3 V-side sensors
StoreObjPtr< SoftwareTriggerResult > m_resultStoreObjectPointer
Store Object for reading the trigger decision.
TH1F * m_occ_L3U
occupancy distribution for L3 U-side sensors
TFile * m_rootFilePtr
pointer at root file used for storing histograms
SVDHistograms< TH1F > * m_histo_zsOcc
occupancy VS ZScut histograms
StoreArray< SVDShaperDigit > m_svdShapers
SVDShaperDigit StoreArray.
TH1F * m_occ_L5V
occupancy distribution for L5 V-side sensors
std::array< APVFloatSampleType, c_nAPVSamples > APVFloatSamples
array of APVFloatSampleType objects
class to summarize SVD quantities per sensor and side
static bool getFinalTriggerDecision(const SoftwareTriggerResult &result, bool forgetTotalResult=false)
Calculate the final cut decision using all "total_results" of all sub triggers in the software trigge...
Class to facilitate easy access to sensor information of the VXD like coordinate transformations or p...
Definition GeoCache.h:38
const std::vector< VxdID > getListOfSensors() const
Get list of all sensors.
Definition GeoCache.cc:59
const SensorInfoBase & getSensorInfo(Belle2::VxdID id) const
Return a reference to the SensorInfo of a given SensorID.
Definition GeoCache.cc:67
static GeoCache & getInstance()
Return a reference to the singleton instance.
Definition GeoCache.cc:214
Base class to provide Sensor Information for PXD and SVD.
Class to uniquely identify a any structure of the PXD and SVD.
Definition VxdID.h:32
unsigned short baseType
The base integer type for VxdID.
Definition VxdID.h:35
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:559
constexpr T square(const T &x)
Calculate the square of the input.
Definition MathHelpers.h:21
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition Module.h:649
Abstract base class for different kinds of events.
STL namespace.