Belle II Software  release-06-01-15
SVDDQMClustersOnTrackModule.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/svdDQM/SVDDQMClustersOnTrackModule.h"
10 
11 #include <hlt/softwaretrigger/core/FinalTriggerDecisionCalculator.h>
12 #include <framework/datastore/DataStore.h>
13 #include <framework/datastore/StoreObjPtr.h>
14 #include <framework/datastore/StoreArray.h>
15 #include <framework/dataobjects/EventMetaData.h>
16 #include <svd/dataobjects/SVDShaperDigit.h>
17 #include <svd/dataobjects/SVDRecoDigit.h>
18 #include <svd/dataobjects/SVDCluster.h>
19 #include <tracking/dataobjects/RecoTrack.h>
20 #include <vxd/geometry/GeoTools.h>
21 
22 #include "TDirectory.h"
23 
24 using namespace std;
25 using namespace Belle2;
26 using namespace SoftwareTrigger;
27 
28 //-----------------------------------------------------------------
29 // Register the Module
30 //-----------------------------------------------------------------
31 REG_MODULE(SVDDQMClustersOnTrack)
32 
33 
34 //-----------------------------------------------------------------
35 // Implementation
36 //-----------------------------------------------------------------
37 
39 {
40  //Set module properties
41  setDescription("SVD DQM module for clusters related to tracks.");
42 
43  setPropertyFlags(c_ParallelProcessingCertified); // specify this flag if you need parallel processing
44  addParam("skipHLTRejectedEvents", m_skipRejectedEvents, "If True, skip events rejected by HLT.", bool(true));
45  addParam("TriggerBin", m_tb, "select events for a specific trigger bin, if -1 then no selection is applied (default)", int(-1));
46  addParam("histogramDirectoryName", m_histogramDirectoryName, "Name of the directory where histograms will be placed.",
47  std::string("SVDClsTrk"));
48  addParam("desynchronizeSVDTime", m_desynchSVDTime,
49  "if True, svd time back in SVD time reference", bool(false));
50  addParam("EventInfo", m_svdEventInfoName, "SVDEventInfo StoreArray name.", std::string(""));
51  addParam("Clusters", m_svdClustersName, "SVDCluster StoreArray name.", std::string(""));
52  addParam("RecoDigits", m_svdRecoDigitsName, "SVDRecoDigits StoreArray name.", std::string(""));
53  addParam("ShaperDigits", m_svdShaperDigitsName, "SVDShaperDigits StoreArray name.", std::string(""));
54 
55  m_histoList = new TList();
56 }
57 
58 
59 SVDDQMClustersOnTrackModule::~SVDDQMClustersOnTrackModule()
60 {
61 }
62 
63 //------------------------------------------------------------------
64 // Function to define histograms
65 //-----------------------------------------------------------------
66 
67 void SVDDQMClustersOnTrackModule::defineHisto()
68 {
69  auto gTools = VXD::GeoCache::getInstance().getGeoTools();
70  if (gTools->getNumberOfLayers() == 0) {
71  B2FATAL("Missing geometry for VXD, check steering file.");
72  }
73  if (gTools->getNumberOfSVDLayers() == 0) {
74  B2WARNING("Missing geometry for SVD, SVD-DQM is skipped.");
75  return;
76  }
77 
78  // Create a separate histogram directories and cd into it.
79  TDirectory* oldDir = gDirectory;
80  if (m_histogramDirectoryName != "") {
81  oldDir->mkdir(m_histogramDirectoryName.c_str());// do not use return value with ->cd(), its ZERO if dir already exists
82  oldDir->cd(m_histogramDirectoryName.c_str());
83  }
84 
85  int ChargeBins = 80;
86  float ChargeMax = 160;
87  int SNRBins = 50;
88  float SNRMax = 100;
89  int TimeBins = 300;
90  float TimeMin = -150;
91  float TimeMax = 150;
92 
93  int MaxBinBins = 6;
94  int MaxBinMax = 6;
95 
96  TString refFrame = "in FTSW reference";
97  if (m_desynchSVDTime)
98  refFrame = "in SVD reference";
99 
100 
101  //----------------------------------------------------------------
102  // Charge of clusters for L3/L456 sensors
103  //----------------------------------------------------------------
104  TString name = "SVDTRK_ClusterChargeU3";
105  TString title = "SVD U-Cluster-on-Track Charge for layer 3 sensors";
106  m_clsTrkChargeU3 = new TH1F(name.Data(), title.Data(), ChargeBins, 0, ChargeMax);
107  m_clsTrkChargeU3->GetXaxis()->SetTitle("cluster charge [ke-]");
108  m_clsTrkChargeU3->GetYaxis()->SetTitle("count");
109  m_histoList->Add(m_clsTrkChargeU3);
110  name = "SVDTRK_ClusterChargeV3";
111  title = "SVD V-Cluster-on-Track Charge for layer 3 sensors";
112  m_clsTrkChargeV3 = new TH1F(name.Data(), title.Data(), ChargeBins, 0, ChargeMax);
113  m_clsTrkChargeV3->GetXaxis()->SetTitle("cluster charge [ke-]");
114  m_clsTrkChargeV3->GetYaxis()->SetTitle("count");
115  m_histoList->Add(m_clsTrkChargeV3);
116 
117  name = "SVDTRK_ClusterChargeU456";
118  title = "SVD U-Cluster-on-Track Charge for layers 4,5,6 sensors";
119  m_clsTrkChargeU456 = new TH1F(name.Data(), title.Data(), ChargeBins, 0, ChargeMax);
120  m_clsTrkChargeU456->GetXaxis()->SetTitle("cluster charge [ke-]");
121  m_clsTrkChargeU456->GetYaxis()->SetTitle("count");
122  m_histoList->Add(m_clsTrkChargeU456);
123 
124  name = "SVDTRK_ClusterChargeV456";
125  title = "SVD V-Cluster-on-Track Charge for layers 4,5,6 sensors";
126  m_clsTrkChargeV456 = new TH1F(name.Data(), title.Data(), ChargeBins, 0, ChargeMax);
127  m_clsTrkChargeV456->GetXaxis()->SetTitle("cluster charge [ke-]");
128  m_clsTrkChargeV456->GetYaxis()->SetTitle("count");
129  m_histoList->Add(m_clsTrkChargeV456);
130 
131  //----------------------------------------------------------------
132  // SNR of clusters for L3/L456 sensors
133  //----------------------------------------------------------------
134  name = "SVDTRK_ClusterSNRU3";
135  title = "SVD U-Cluster-on-Track SNR for layer 3 sensors";
136  m_clsTrkSNRU3 = new TH1F(name.Data(), title.Data(), SNRBins, 0, SNRMax);
137  m_clsTrkSNRU3->GetXaxis()->SetTitle("cluster SNR");
138  m_clsTrkSNRU3->GetYaxis()->SetTitle("count");
139  m_histoList->Add(m_clsTrkSNRU3);
140  name = "SVDTRK_ClusterSNRV3";
141  title = "SVD V-Cluster-on-Track SNR for layer 3 sensors";
142  m_clsTrkSNRV3 = new TH1F(name.Data(), title.Data(), SNRBins, 0, SNRMax);
143  m_clsTrkSNRV3->GetXaxis()->SetTitle("cluster SNR");
144  m_clsTrkSNRV3->GetYaxis()->SetTitle("count");
145  m_histoList->Add(m_clsTrkSNRV3);
146 
147  name = "SVDTRK_ClusterSNRU456";
148  title = "SVD U-Cluster-on-Track SNR for layers 4,5,6 sensors";
149  m_clsTrkSNRU456 = new TH1F(name.Data(), title.Data(), SNRBins, 0, SNRMax);
150  m_clsTrkSNRU456->GetXaxis()->SetTitle("cluster SNR");
151  m_clsTrkSNRU456->GetYaxis()->SetTitle("count");
152  m_histoList->Add(m_clsTrkSNRU456);
153  name = "SVDTRK_ClusterSNRV456";
154  title = "SVD V-Cluster-on-Track SNR for layers 4,5,6 sensors";
155  m_clsTrkSNRV456 = new TH1F(name.Data(), title.Data(), SNRBins, 0, SNRMax);
156  m_clsTrkSNRV456->GetXaxis()->SetTitle("cluster SNR");
157  m_clsTrkSNRV456->GetYaxis()->SetTitle("count");
158  m_histoList->Add(m_clsTrkSNRV456);
159 
160  //----------------------------------------------------------------
161  // Time of clusters for L3/L456 sensors
162  //----------------------------------------------------------------
163  name = "SVDTRK_ClusterTimeU3";
164  title = Form("SVD U-Cluster-on-Track Time %s for layer 3 sensors", refFrame.Data());
165  m_clsTrkTimeU3 = new TH1F(name.Data(), title.Data(), TimeBins, TimeMin, TimeMax);
166  m_clsTrkTimeU3->GetXaxis()->SetTitle("cluster time (ns)");
167  m_clsTrkTimeU3->GetYaxis()->SetTitle("count");
168  m_histoList->Add(m_clsTrkTimeU3);
169  name = "SVDTRK_ClusterTimeV3";
170  title = Form("SVD V-Cluster-on-Track Time %s for layer 3 sensors", refFrame.Data());
171  m_clsTrkTimeV3 = new TH1F(name.Data(), title.Data(), TimeBins, TimeMin, TimeMax);
172  m_clsTrkTimeV3->GetXaxis()->SetTitle("cluster time (ns)");
173  m_clsTrkTimeV3->GetYaxis()->SetTitle("count");
174  m_histoList->Add(m_clsTrkTimeV3);
175 
176  name = "SVDTRK_ClusterTimeU456";
177  title = Form("SVD U-Cluster-on-Track Time %s for layers 4,5,6 sensors", refFrame.Data());
178  m_clsTrkTimeU456 = new TH1F(name.Data(), title.Data(), TimeBins, TimeMin, TimeMax);
179  m_clsTrkTimeU456->GetXaxis()->SetTitle("cluster time (ns)");
180  m_clsTrkTimeU456->GetYaxis()->SetTitle("count");
181  m_histoList->Add(m_clsTrkTimeU456);
182  name = "SVDTRK_ClusterTimeV456";
183  title = Form("SVD V-Cluster-on-Track Time %s for layers 4,5,6 sensors", refFrame.Data());
184  m_clsTrkTimeV456 = new TH1F(name.Data(), title.Data(), TimeBins, TimeMin, TimeMax);
185  m_clsTrkTimeV456->GetXaxis()->SetTitle("cluster time (ns)");
186  m_clsTrkTimeV456->GetYaxis()->SetTitle("count");
187  m_histoList->Add(m_clsTrkTimeV456);
188 
189  //----------------------------------------------------------------
190  // EventT0 vs Time of clusters for U and V sides
191  //----------------------------------------------------------------
192  name = "SVDTRK_ClusterTimeUvsEventT0";
193  title = Form("SVD U-Cluster-on-Track Time vs EventT0 %s for layer 3 sensors", refFrame.Data());
194  m_clsTrkTimeUEvtT0 = new TH2F(name.Data(), title.Data(), TimeBins, TimeMin, TimeMax, 100, -50, 50);
195  m_clsTrkTimeUEvtT0->GetXaxis()->SetTitle("clusters time (ns)");
196  m_clsTrkTimeUEvtT0->GetYaxis()->SetTitle("EventT0 (ns)");
197  m_histoList->Add(m_clsTrkTimeUEvtT0);
198  name = "SVDTRK_ClusterTimeVvsEventT0";
199  title = Form("SVD V-Cluster-on-Track Time vs EventT0 %s for layer 3 sensors", refFrame.Data());
200  m_clsTrkTimeVEvtT0 = new TH2F(name.Data(), title.Data(), TimeBins, TimeMin, TimeMax, 100, -50, 50);
201  m_clsTrkTimeVEvtT0->GetXaxis()->SetTitle("cluster time (ns)");
202  m_clsTrkTimeVEvtT0->GetYaxis()->SetTitle("EventT0 (ns)");
203  m_histoList->Add(m_clsTrkTimeVEvtT0);
204 
205  //----------------------------------------------------------------
206  // MaxBin of strips for all sensors (offline ZS)
207  //----------------------------------------------------------------
208  name = "SVDTRK_StripMaxBinUAll";
209  title = "SVD U-Strip-on-Track MaxBin for all sensors";
210  m_stripMaxBinUAll = new TH1F(name.Data(), title.Data(), MaxBinBins, 0, MaxBinMax);
211  m_stripMaxBinUAll->GetXaxis()->SetTitle("max bin");
212  m_stripMaxBinUAll->GetYaxis()->SetTitle("count");
213  m_histoList->Add(m_stripMaxBinUAll);
214  name = "SVDTRK_StripMaxBinVAll";
215  title = "SVD V-Strip-on-Track MaxBin for all sensors";
216  m_stripMaxBinVAll = new TH1F(name.Data(), title.Data(), MaxBinBins, 0, MaxBinMax);
217  m_stripMaxBinVAll->GetXaxis()->SetTitle("max bin");
218  m_stripMaxBinVAll->GetYaxis()->SetTitle("count");
219  m_histoList->Add(m_stripMaxBinVAll);
220 
221 
222  oldDir->cd();
223 }
224 
225 
226 void SVDDQMClustersOnTrackModule::initialize()
227 {
228  // Register histograms (calls back defineHisto)
229  REG_HISTOGRAM
230 
231  auto gTools = VXD::GeoCache::getInstance().getGeoTools();
232  if (gTools->getNumberOfSVDLayers() != 0) {
233 
234  m_svdEventInfo.isOptional(m_svdEventInfoName);
235  m_eventT0.isOptional();
236  m_tracks.isOptional();
237  m_resultStoreObjectPointer.isOptional();
238 
239  }
240 }
241 
242 void SVDDQMClustersOnTrackModule::beginRun()
243 {
244  auto gTools = VXD::GeoCache::getInstance().getGeoTools();
245  if (gTools->getNumberOfSVDLayers() == 0) return;
246 
247  //reset histograms
248  TObject* obj;
249  TIter nextH(m_histoList);
250  while ((obj = nextH()))
251  if (obj->InheritsFrom("TH1")) {
252  ((TH1F*)obj)->Reset();
253  }
254 }
255 
256 void SVDDQMClustersOnTrackModule::event()
257 {
258 
259  if (!m_tracks.isValid()) {
260  B2WARNING("Missing Tracks StoreArray. Skipping SVDDQMClustersOnTrack");
261  return;
262  }
263 
264  if (!m_svdEventInfo.isValid())
265  m_tb = -1;
266  else {
267  if (m_tb != -1)
268  if (m_svdEventInfo->getModeByte().getTriggerBin() != m_tb)
269  return;
270  }
271 
272  StoreObjPtr<EventMetaData> evtMetaData;
273  m_expNumber = evtMetaData->getExperiment();
274  m_runNumber = evtMetaData->getRun();
275 
276  // get EventT0 if present and valid
277  double eventT0 = -1000;
278  if (m_eventT0.isOptional())
279  if (m_eventT0.isValid())
280  if (m_eventT0->hasEventT0())
281  eventT0 = m_eventT0->getEventT0();
282 
283  // if svd time in SVD time reference is shown, eventT0 is also synchronized with SVD reference frame, firstFrame = 0
284  if (m_desynchSVDTime && m_svdEventInfo.isValid())
285  eventT0 = eventT0 - m_svdEventInfo->getSVD2FTSWTimeShift(0);
286 
287  //check HLT decision and increase number of events only if the event has been accepted
288 
289  if (m_skipRejectedEvents && (m_resultStoreObjectPointer.isValid())) {
290  const bool eventAccepted = FinalTriggerDecisionCalculator::getFinalTriggerDecision(*m_resultStoreObjectPointer);
291  if (!eventAccepted) return;
292  }
293 
294  auto gTools = VXD::GeoCache::getInstance().getGeoTools();
295  if (gTools->getNumberOfSVDLayers() == 0) return;
296 
297  // Add experiment and run number to the title of selected histograms (CR shifter plots)
298  TString runID = TString::Format(" ~ Exp%d Run%d", m_expNumber, m_runNumber);
299  TObject* obj;
300  TIter nextH(m_histoList);
301  while ((obj = nextH()))
302  if (obj->InheritsFrom("TH1")) {
303  if (((TString)obj->GetTitle()).Contains(runID) == false) {
304  ((TH1F*)obj)->SetTitle(obj->GetTitle() + runID);
305  }
306  }
307 
308  for (const Track& track : m_tracks) {
309 
310  const TrackFitResult* tfr = track.getTrackFitResultWithClosestMass(Const::pion);
311  if (not tfr) continue;
312 
313  const RecoTrack* recoTrack = track.getRelated<RecoTrack>();
314  if (not recoTrack) continue;
315 
316  for (const SVDCluster& svdCluster : recoTrack->getRelationsWith<SVDCluster>(m_svdClustersName)) {
317 
318  int iLayer = svdCluster.getSensorID().getLayerNumber();
319 
320  float time = svdCluster.getClsTime();
321  if (m_desynchSVDTime && m_svdEventInfo.isValid())
322  time = time - m_svdEventInfo->getSVD2FTSWTimeShift(svdCluster.getFirstFrame());
323 
324  if (svdCluster.isUCluster()) {
325 
326  m_clsTrkTimeUEvtT0->Fill(time, eventT0);
327 
328  if (iLayer == 3) {
329  if (m_clsTrkChargeU3 != nullptr) m_clsTrkChargeU3->Fill(svdCluster.getCharge() / 1000.0); // in kelectrons
330  if (m_clsTrkSNRU3 != nullptr) m_clsTrkSNRU3->Fill(svdCluster.getSNR());
331  if (m_clsTrkTimeU3 != nullptr) m_clsTrkTimeU3->Fill(time);
332  } else {
333  if (m_clsTrkChargeU456 != nullptr) m_clsTrkChargeU456->Fill(svdCluster.getCharge() / 1000.0); // in kelectrons
334  if (m_clsTrkSNRU456 != nullptr) m_clsTrkSNRU456->Fill(svdCluster.getSNR());
335  if (m_clsTrkTimeU456 != nullptr) m_clsTrkTimeU456->Fill(time);
336  }
337 
338  for (const SVDRecoDigit& recoDigit : svdCluster.getRelationsTo<SVDRecoDigit>(m_svdRecoDigitsName)) {
339 
340  SVDShaperDigit* shaper = recoDigit.getRelatedTo<SVDShaperDigit>(m_svdShaperDigitsName);
341  if (m_stripMaxBinUAll != nullptr and shaper != nullptr) m_stripMaxBinUAll->Fill(shaper->getMaxTimeBin());
342  }
343 
344 
345  } else {
346 
347  m_clsTrkTimeVEvtT0->Fill(time, eventT0);
348 
349  if (iLayer == 3) {
350  if (m_clsTrkChargeV3 != nullptr) m_clsTrkChargeV3->Fill(svdCluster.getCharge() / 1000.0); // in kelectrons
351  if (m_clsTrkSNRV3 != nullptr) m_clsTrkSNRV3->Fill(svdCluster.getSNR());
352  if (m_clsTrkTimeV3 != nullptr) m_clsTrkTimeV3->Fill(time);
353  } else {
354  if (m_clsTrkChargeV456 != nullptr) m_clsTrkChargeV456->Fill(svdCluster.getCharge() / 1000.0); // in kelectrons
355  if (m_clsTrkSNRV456 != nullptr) m_clsTrkSNRV456->Fill(svdCluster.getSNR());
356  if (m_clsTrkTimeV456 != nullptr) m_clsTrkTimeV456->Fill(time);
357  }
358 
359  for (const SVDRecoDigit& recoDigit : svdCluster.getRelationsTo<SVDRecoDigit>(m_svdRecoDigitsName)) {
360 
361  SVDShaperDigit* shaper = recoDigit.getRelatedTo<SVDShaperDigit>(m_svdShaperDigitsName);
362  if (m_stripMaxBinVAll != nullptr and shaper != nullptr) m_stripMaxBinVAll->Fill(shaper->getMaxTimeBin());
363  }
364 
365  }
366 
367  }
368  }
369 }
370 
371 
372 void SVDDQMClustersOnTrackModule::terminate()
373 {
374 
375  delete m_histoList;
376 
377 }
HistoModule.h is supposed to be used instead of Module.h for the modules with histogram definitions t...
Definition: HistoModule.h:29
This is the Reconstruction Event-Data Model Track.
Definition: RecoTrack.h:76
RelationVector< TO > getRelationsTo(const std::string &name="", const std::string &namedRelation="") const
Get the relations that point from this object to another store array.
RelationVector< T > getRelationsWith(const std::string &name="", const std::string &namedRelation="") const
Get the relations between this object and another store array.
TO * getRelatedTo(const std::string &name="", const std::string &namedRelation="") const
Get the object to which this object has a relation.
The SVD Cluster class This class stores all information about reconstructed SVD clusters.
Definition: SVDCluster.h:28
SVD DQM Module for Clusters related to Tracks.
The SVD RecoDigit class.
Definition: SVDRecoDigit.h:43
The SVD ShaperDigit class.
int getMaxTimeBin() const
Get the max bin.
Type-safe access to single objects in the data store.
Definition: StoreObjPtr.h:95
Values of the result of a track fit with a given particle hypothesis.
Class that bundles various TrackFitResults.
Definition: Track.h:25
#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.