Belle II Software  release-06-01-15
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 
12 #include <TMath.h>
13 
14 using namespace std;
15 using namespace Belle2;
16 using namespace SoftwareTrigger;
17 
18 REG_MODULE(SVDOccupancyAnalysis)
19 
20 SVDOccupancyAnalysisModule::SVDOccupancyAnalysisModule() : Module()
21 {
22 
23  setDescription("This module check performances of SVD reconstruction of VXD TB data");
24 
25  addParam("outputFileName", m_rootFileName, "Name of output root file.", std::string("SVDOccupancyAnalysis_output.root"));
26 
27  addParam("skipHLTRejectedEvents", m_skipRejectedEvents, "If TRUE skip events rejected by HLT", bool(false));
28  addParam("groupNevents", m_group, "Number of events to group", float(10000));
29  addParam("FADCmode", m_FADCmode,
30  "FADC mode: if true the approximation to integer is done", bool(false));
31  addParam("minZScut", m_minZS, "Minimum ZS cut", float(3));
32  addParam("maxZScut", m_maxZS, "Maximum ZS cut", float(6));
33  addParam("pointsZScut", m_pointsZS, "Number of ZS cuts", int(8));
34 
35  addParam("ShaperDigitsName", m_ShaperDigitName, "Name of ShaperDigit Store Array.", std::string(""));
36 }
37 
38 SVDOccupancyAnalysisModule::~SVDOccupancyAnalysisModule()
39 {
40 
41 }
42 
44 {
45 
46  m_eventMetaData.isRequired();
47  m_svdShapers.isRequired(m_ShaperDigitName);
48  B2INFO(" ShaperDigits: " << m_ShaperDigitName);
49 
50  m_rootFilePtr = new TFile(m_rootFileName.c_str(), "RECREATE");
51 
52  m_nEvents = 0;
53 
54 }
55 
56 
58 {
59 
60 
61  m_occ_L3U = new TH1F("occL3U", "Occupancy Distribution for L3 U side", m_distr_Nbins, m_distr_min, m_distr_max);
62  m_occ_L3U->GetXaxis()->SetTitle("occupancy(%)");
63  m_occ_L3V = new TH1F("occL3V", "Occupancy Distribution for L3 V side", m_distr_Nbins, m_distr_min, m_distr_max);
64  m_occ_L3V->GetXaxis()->SetTitle("occupancy(%)");
65  m_occ_L4U = new TH1F("occL4U", "Occupancy Distribution for L4 U side", m_distr_Nbins, m_distr_min, m_distr_max);
66  m_occ_L4U->GetXaxis()->SetTitle("occupancy(%)");
67  m_occ_L4V = new TH1F("occL4V", "Occupancy Distribution for L4 V side", m_distr_Nbins, m_distr_min, m_distr_max);
68  m_occ_L4V->GetXaxis()->SetTitle("occupancy(%)");
69  m_occ_L5U = new TH1F("occL5U", "Occupancy Distribution for L5 U side", m_distr_Nbins, m_distr_min, m_distr_max);
70  m_occ_L5U->GetXaxis()->SetTitle("occupancy(%)");
71  m_occ_L5V = new TH1F("occL5V", "Occupancy Distribution for L5 V side", m_distr_Nbins, m_distr_min, m_distr_max);
72  m_occ_L5V->GetXaxis()->SetTitle("occupancy(%)");
73  m_occ_L6U = new TH1F("occL6U", "Occupancy Distribution for L6 U side", m_distr_Nbins, m_distr_min, m_distr_max);
74  m_occ_L6U->GetXaxis()->SetTitle("occupancy(%)");
75  m_occ_L6V = new TH1F("occL6V", "Occupancy Distribution for L6 V side", m_distr_Nbins, m_distr_min, m_distr_max);
76  m_occ_L6V->GetXaxis()->SetTitle("occupancy(%)");
77 
78 
80 
81  //collect the list of all SVD Modules in the geometry here
82  std::vector<VxdID> sensors = geo.getListOfSensors();
83  for (VxdID& aVxdID : sensors) {
84  VXD::SensorInfoBase info = geo.getSensorInfo(aVxdID);
85  if (info.getType() != VXD::SensorInfoBase::SVD) continue;
86  m_SVDModules.push_back(aVxdID); // reorder, sort would be better
87  }
88  std::sort(m_SVDModules.begin(), m_SVDModules.end()); // back to natural order
89 
90  m_hit = new SVDSummaryPlots("hits@view", "Number of hits on @view/@side Side");
91 
92  TH1F h_dist("dist_L@layerL@ladderS@sensor@view",
93  "Occupancy Distribution (layer @layer, ladder @ladder, sensor @sensor, side@view/@side)",
95  h_dist.GetXaxis()->SetTitle("occupancy (%)");
96  m_histo_dist = new SVDHistograms<TH1F>(h_dist);
97 
98  TH1F h_occ_768("occ768_L@layerL@ladderS@sensor@view", "Occupancy (layer @layer, ladder @ladder, sensor @sensor, side@view/@side)",
99  768, 0, 768);
100  h_occ_768.GetXaxis()->SetTitle("cellID");
101  TH1F h_occ_512("occ512_L@layerL@ladderS@sensor@view", "Occupancy (layer @layer, ladder @ladder, sensor @sensor, side@view/@side)",
102  512, 0, 512);
103  h_occ_512.GetXaxis()->SetTitle("cellID");
104  m_histo_occ = new SVDHistograms<TH1F>(h_occ_768, h_occ_768, h_occ_768, h_occ_512);
105 
106 
107  TH1F h_zsVSocc("occVSzs_L@layerL@ladderS@sensor@view",
108  "Average Occupancy VS Zero Suppression (layer @layer, ladder @ladder, sensor @sensor, side@view/@side)", m_pointsZS, m_minZS,
109  m_maxZS);
110  h_zsVSocc.GetXaxis()->SetTitle("ZS cut");
111  m_histo_zsOcc = new SVDHistograms<TH1F>(h_zsVSocc);
112 
113 
114  TH1F h_zsVSoccSQ("zsVSoccSQ_L@layerL@ladderS@sensor@view",
115  "Average Occupancy VS (ZS cut)^2 (layer @layer, ladder @ladder, sensor @sensor, side@view/@side)", 100, TMath::Power(m_minZS,
116  2) - 5, TMath::Power(m_maxZS, 2));
117  h_zsVSoccSQ.GetXaxis()->SetTitle("(ZS cut)^2");
118  m_histo_zsOccSQ = new SVDHistograms<TH1F>(h_zsVSoccSQ);
119 
120 
121  TH2F h_occtdep_768("occ768VSevt_L@layerL@ladderS@sensor@view",
122  "Average Occupancy VS Event Number (layer @layer, ladder @ladder, sensor @sensor, side@view/@side)",
123  1000, 0, 1000, 768, 0, 768);
124  h_occtdep_768.GetXaxis()->SetTitle(Form("evt number/%1.0f", m_group));
125  h_occtdep_768.GetYaxis()->SetTitle("cellID");
126 
127  TH2F h_occtdep_512("occ512VSevt_L@layerL@ladderS@sensor@view",
128  "Average Occupancy VS Event Number (layer @layer, ladder @ladder, sensor @sensor, side@view/@side)",
129  1000, 0, 1000, 512, 0, 512);
130  h_occtdep_512.GetXaxis()->SetTitle(Form("evt number/%1.0f", m_group));
131  h_occtdep_512.GetYaxis()->SetTitle("cellID");
132 
133  m_histo_occtdep = new SVDHistograms<TH2F>(h_occtdep_768, h_occtdep_768, h_occtdep_768, h_occtdep_512);
134 
135 }
136 
138 {
139 
141  const bool eventAccepted = FinalTriggerDecisionCalculator::getFinalTriggerDecision(*m_resultStoreObjectPointer);
142  if (!eventAccepted) return;
143  }
144 
145  m_nEvents++;
146  int nEvent = m_eventMetaData->getEvent();
147 
148  //shaper digits
149  for (int digi = 0 ; digi < m_svdShapers.getEntries(); digi++) {
150 
151 
152  VxdID::baseType theVxdID = (VxdID::baseType)m_svdShapers[digi]->getSensorID();
153  int side = m_svdShapers[digi]->isUStrip();
154 
155  //fill standard occupancy plot, for default zero suppression
156  m_histo_occtdep->fill(theVxdID, side, nEvent / m_group, m_svdShapers[digi]->getCellID());
157 
158  m_hit->fill(theVxdID, side, 1);
159 
160  m_histo_occ->fill(theVxdID, side, m_svdShapers[digi]->getCellID());
161 
162  float noise = m_NoiseCal.getNoise(theVxdID, side, m_svdShapers[digi]->getCellID());
163  float step = (m_maxZS - m_minZS) / m_pointsZS;
164 
165  for (int z = 0; z <= m_pointsZS; z++) {
166  int nOKSamples = 0;
167  float cutMinSignal = (m_minZS + step * z) * noise;
168 
169  if (m_FADCmode) {
170  cutMinSignal = cutMinSignal + 0.5;
171  cutMinSignal = (int)cutMinSignal;
172  }
173 
174 
175  Belle2::SVDShaperDigit::APVFloatSamples samples_vec = m_svdShapers[digi]->getSamples();
176 
177  for (int k = 0; k < 6; k ++)
178  if (samples_vec[k] > cutMinSignal)
179  nOKSamples++;
180 
181  if (nOKSamples > 0) {
182  m_histo_zsOcc->fill(theVxdID, side, m_minZS + z * step);
183  m_histo_zsOccSQ->fill(theVxdID, side, TMath::Power(m_minZS + z * step, 2));
184  }
185  }
186 
187  }
188 
189  //loop on sensors, fill and clear
190  for (unsigned int i = 0; i < m_SVDModules.size(); i++) {
191  B2DEBUG(10, "module " << i << "," << m_SVDModules[i]);
192  float nStripsV = 512;
193  if (m_SVDModules[i].getLayerNumber() == 3)
194  nStripsV = 768;
195 
196  double occU = 100. * m_hit->getValue(m_SVDModules[i], 1) / 768;
197  double occV = 100. * m_hit->getValue(m_SVDModules[i], 0) / nStripsV;
198 
199  m_histo_dist->fill(m_SVDModules[i], 1, occU);
200  m_histo_dist->fill(m_SVDModules[i], 0, occV);
201 
202  if (m_SVDModules[i].getLayerNumber() == 3) {
203  m_occ_L3U->Fill(occU);
204  m_occ_L3V->Fill(occV);
205  }
206  if (m_SVDModules[i].getLayerNumber() == 4) {
207  m_occ_L4U->Fill(occU);
208  m_occ_L4V->Fill(occV);
209  }
210  if (m_SVDModules[i].getLayerNumber() == 5) {
211  m_occ_L5U->Fill(occU);
212  m_occ_L5V->Fill(occV);
213  }
214  if (m_SVDModules[i].getLayerNumber() == 6) {
215  m_occ_L6U->Fill(occU);
216  m_occ_L6V->Fill(occV);
217  }
218 
219  }
220 
221  (m_hit->getHistogram(0))->Reset();
222  (m_hit->getHistogram(1))->Reset();
223 
224 }
225 
226 
228 {
229 
230 }
231 
232 
234 {
235 
236  if (m_rootFilePtr != nullptr) {
237  m_rootFilePtr->cd();
238 
239  TDirectory* oldDir = gDirectory;
240 
241  m_occ_L3U->Write();
242  m_occ_L3V->Write();
243  m_occ_L4U->Write();
244  m_occ_L4V->Write();
245  m_occ_L5U->Write();
246  m_occ_L5V->Write();
247  m_occ_L6U->Write();
248  m_occ_L6V->Write();
249 
251 
252  for (auto layer : geoCache.getLayers(VXD::SensorInfoBase::SVD)) {
253  TString layerName = Form("occupancyL%d", layer.getLayerNumber());
254  TDirectory* dir_layer = oldDir->mkdir(layerName.Data());
255  dir_layer->cd();
256  for (auto ladder : geoCache.getLadders(layer))
257  for (Belle2::VxdID sensor : geoCache.getSensors(ladder))
258  for (int view = SVDHistograms<TH1F>::VIndex ; view < SVDHistograms<TH1F>::UIndex + 1; view++) {
259  (m_histo_dist->getHistogram(sensor, view))->Write();
260 
261  (m_histo_occ->getHistogram(sensor, view))->Scale(1. / m_nEvents);
262  (m_histo_occ->getHistogram(sensor, view))->Write();
263 
264  int nStrips = 768;
265  if (sensor.getLayerNumber() != 3 && view == SVDHistograms<TH1F>::VIndex)
266  nStrips = 512;
267 
268  (m_histo_zsOcc->getHistogram(sensor, view))->Scale(1. / m_nEvents / nStrips);
269  (m_histo_zsOcc->getHistogram(sensor, view))->Write();
270  (m_histo_zsOccSQ->getHistogram(sensor, view))->Scale(1. / m_nEvents / nStrips);
271  (m_histo_zsOccSQ->getHistogram(sensor, view))->Write();
272 
273  (m_histo_occtdep->getHistogram(sensor, view))->Scale(1. / m_group);
274  (m_histo_occtdep->getHistogram(sensor, view))->Write();
275  }
276  }
277 
278  m_rootFilePtr->Close();
279 
280  }
281 }
282 
283 
Base class for Modules.
Definition: Module.h:72
void fill(const VxdID &vxdID, int view, Types ... args)
fill the histogram for
Definition: SVDHistograms.h:77
H * getHistogram(const VxdID &vxdID, int view)
get a reference to the histogram for
Definition: SVDHistograms.h:56
float getNoise(const VxdID &sensorID, const bool &isU, const unsigned short &strip) const
This is the method for getting the noise.
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
Initialize the Module.
TH1F * m_occ_L4V
occupancy distribution for L4 V-side sensors
virtual void event() override
This method is the core of the module.
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
This method is called if the current run ends.
float m_group
number of events to compute occupancy for occ VS time
virtual void terminate() override
This method is called at the end of the event processing.
TH1F * m_occ_L6U
occupancy distribution for L6 U-side sensors
float m_minZS
minimum zero suppresion 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
Called when entering a new run.
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
float getValue(const VxdID &vxdID, int view)
get the value contained in the corresponding bin, given VxdID and view
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...
Definition: GeoCache.h:39
const std::vector< VxdID > getListOfSensors() const
Get list of all sensors.
Definition: GeoCache.cc:58
const SensorInfoBase & getSensorInfo(Belle2::VxdID id) const
Return a referecne to the SensorInfo of a given SensorID.
Definition: GeoCache.cc:66
static GeoCache & getInstance()
Return a reference to the singleton instance.
Definition: GeoCache.cc:213
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:33
unsigned short baseType
The base integer type for VxdID.
Definition: VxdID.h:36
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
Abstract base class for different kinds of events.