Belle II Software  release-08-01-10
SVDB4CommissioningPlotsModule.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 #include <svd/modules/svdPerformance/SVDB4CommissioningPlotsModule.h>
9 #include <framework/datastore/RelationVector.h>
10 #include <time.h>
11 #include <mdst/dataobjects/HitPatternVXD.h>
12 #include <vxd/geometry/GeoCache.h>
13 
14 #include <boost/foreach.hpp>
15 
16 using namespace std;
17 using namespace Belle2;
18 
19 REG_MODULE(SVDB4CommissioningPlots);
20 
21 SVDB4CommissioningPlotsModule::SVDB4CommissioningPlotsModule() : Module()
22  , m_nTracks(0), m_Pvalue(), m_mom(0), m_nSVDhits(0)
23 {
24 
25  setDescription("This module check performances of SVD reconstruction on Commissioning data");
26 
27  addParam("outputFileName", m_rootFileName, "Name of output root file.", std::string("SVDB4CommissioningPlots_output.root"));
28 
29  addParam("RecoDigitsName", m_RecoDigitName, "Name of RecoDigit Store Array.", std::string("SVDRecoDigits"));
30  addParam("ClustersName", m_ClusterName, "Name of Cluster Store Array.", std::string("SVDClusters"));
31  addParam("TrackListName", m_TrackName, "Name of Track Store Array.", std::string("Tracks"));
32  addParam("TrackFitResultListName", m_TrackFitResultName, "Name of TracksFitResult Store Array.", std::string("TrackFitResults"));
33  addParam("plotRecoDigits", m_plotRecoDigits,
34  "Set true to produce the plots for RecoDigits (false by default)", m_plotRecoDigits);
35 }
36 
38 {
39 
40  m_svdRecos.isOptional(m_RecoDigitName);
42  m_Tracks.isOptional(m_TrackName);
44  m_tfr.isOptional(m_TrackFitResultName);
45 
46  B2INFO(" RecoDigits: " << m_RecoDigitName);
47  B2INFO(" Clusters: " << m_ClusterName);
48  B2INFO(" Tracks: " << m_TrackName);
49  B2INFO(" TrackFitResults: " << m_TrackFitResultName);
50 
51 
52 
53  m_rootFilePtr = new TFile(m_rootFileName.c_str(), "RECREATE");
54 
55  m_ntracks = 0;
56 }
57 
59 {
60  m_nEvents = 0;
61 
62  //RECO DIGITS
63  TH1F hRecoCharge("reco_charge_L@layerL@ladderS@sensor@view",
64  "Charge of RecoDigits in @layer.@ladder.@sensor @view/@side side",
65  100, 0, 1000);
66  hRecoCharge.GetXaxis()->SetTitle("charge (ke-)");
67  h_recoCharge = new SVDHistograms<TH1F>(hRecoCharge);
68 
69  TH1F hRecoEnergy("reco_energy_L@layerL@ladderS@sensor@view",
70  "Energy of RecoDigits in @layer.@ladder.@sensor @view/@side side",
71  100, 0, 360);
72  hRecoEnergy.GetXaxis()->SetTitle("energy (keV)");
73  h_recoEnergy = new SVDHistograms<TH1F>(hRecoEnergy);
74 
75  TH1F hRecoTime("reco_time_L@layerL@ladderS@sensor@view",
76  "Time of RecoDigits in @layer.@ladder.@sensor @view/@side side",
77  200, -100, 100);
78  hRecoTime.GetXaxis()->SetTitle("time (ns)");
79  h_recoTime = new SVDHistograms<TH1F>(hRecoTime);
80 
81  TH1F hRecoNoise("reco_noise_L@layerL@ladderS@sensor@view",
82  "Noise of RecoDigits in @layer.@ladder.@sensor @view/@side side",
83  200, 300, 1800);
84  hRecoNoise.GetXaxis()->SetTitle("strip noise (e-)");
85  h_recoNoise = new SVDHistograms<TH1F>(hRecoNoise);
86 
87  //CLUSTER NOT RELATED TO TRACKS
88  TH1F hClusterCharge("cluster_charge_L@layerL@ladderS@sensor@view",
89  "Charge of Clusters in @layer.@ladder.@sensor @view/@side side",
90  100, 0, 100);
91  hClusterCharge.GetXaxis()->SetTitle("charge (ke-)");
92  h_clusterCharge = new SVDHistograms<TH1F>(hClusterCharge);
93 
94  TH1F hClusterSize("cluster_size_L@layerL@ladderS@sensor@view",
95  "Clusters Size for @layer.@ladder.@sensor @view/@side side",
96  20, 0, 20);
97  hClusterSize.GetXaxis()->SetTitle("cluster size");
98  h_clusterSize = new SVDHistograms<TH1F>(hClusterSize);
99 
100  TH1F hClusterSNR("cluster_SNR_L@layerL@ladderS@sensor@view",
101  "SNR of Clusters in @layer.@ladder.@sensor @view/@side side",
102  100, 0, 140);
103  hClusterSNR.GetXaxis()->SetTitle("SNR");
104  h_clusterSNR = new SVDHistograms<TH1F>(hClusterSNR);
105 
106  TH1F hClusterEnergy("cluster_energy_L@layerL@ladderS@sensor@view",
107  "Energy of Clusters in @layer.@ladder.@sensor @view/@side side",
108  100, 0, 360);
109  hClusterEnergy.GetXaxis()->SetTitle("energy (keV)");
110  h_clusterEnergy = new SVDHistograms<TH1F>(hClusterEnergy);
111 
112  TH1F hClusterTime("cluster_time_L@layerL@ladderS@sensor@view",
113  "Time of Clusters in @layer.@ladder.@sensor @view/@side side",
114  200, -100, 100);
115  hClusterTime.GetXaxis()->SetTitle("time (ns)");
116  h_clusterTime = new SVDHistograms<TH1F>(hClusterTime);
117 
118  //CLUSTER RELATED TO TRACKS
119  TH1F hClusterTrkCharge("clusterTrk_charge_L@layerL@ladderS@sensor@view",
120  "Charge of Clusters Related to Tracks in @layer.@ladder.@sensor @view/@side side",
121  100, 0, 100);
122  hClusterTrkCharge.GetXaxis()->SetTitle("charge (ke-)");
123  h_clusterTrkCharge = new SVDHistograms<TH1F>(hClusterTrkCharge);
124 
125  TH1F hClusterTrkSize("clusterTrk_size_L@layerL@ladderS@sensor@view",
126  "Cluster Size for @layer.@ladder.@sensor @view/@side side",
127  20, 0, 20);
128  hClusterTrkSize.GetXaxis()->SetTitle("cluster size");
129  h_clusterTrkSize = new SVDHistograms<TH1F>(hClusterTrkSize);
130 
131  TH1F hClusterTrkSNR("clusterTrk_SNR_L@layerL@ladderS@sensor@view",
132  "SNR of Clusters Related to Tracks in @layer.@ladder.@sensor @view/@side side",
133  100, 0, 140);
134  hClusterTrkSNR.GetXaxis()->SetTitle("SNR");
135  h_clusterTrkSNR = new SVDHistograms<TH1F>(hClusterTrkSNR);
136 
137  TH1F hClusterTrkEnergy("clusterTrk_energy_L@layerL@ladderS@sensor@view",
138  "Energy of Clusters Related to Tracks in @layer.@ladder.@sensor @view/@side side",
139  100, 0, 360);
140  hClusterTrkEnergy.GetXaxis()->SetTitle("energy (keV)");
141  h_clusterTrkEnergy = new SVDHistograms<TH1F>(hClusterTrkEnergy);
142 
143  TH1F hClusterTrkTime("clusterTrk_time_L@layerL@ladderS@sensor@view",
144  "Time of Clusters Related to Tracks in @layer.@ladder.@sensor @view/@side side",
145  200, -100, 100);
146  hClusterTrkTime.GetXaxis()->SetTitle("time (ns)");
147  h_clusterTrkTime = new SVDHistograms<TH1F>(hClusterTrkTime);
148 
149  TH1F hClusterTrkInterstripPos("clusterTrk_interstripPos_L@layerL@ladderS@sensor@view",
150  "Interstrip Position of Clusters Related to Tracks in @layer.@ladder.@sensor @view/@side side",
151  400, 0, 1);
152  hClusterTrkInterstripPos.GetXaxis()->SetTitle("interstrip position");
153  h_clusterTrkInterstripPos = new SVDHistograms<TH1F>(hClusterTrkInterstripPos);
154 
155  //tracks
156  m_nTracks = new TH1F("h1nTracks", "number of Tracks per event", 50, 0, 50);
157  m_nTracks->GetXaxis()->SetTitle("n Tracks");
158  m_Pvalue = new TH1F("h1pValue", "Tracks p value", 100, 0, 1);
159  m_Pvalue->GetXaxis()->SetTitle("p value");
160  m_mom = new TH1F("h1momentum", " Tracks Momentum", 200, 0, 10);
161  m_mom->GetXaxis()->SetTitle("p (GeV/c)");
162  m_nSVDhits = new TH1F("h1nSVDhits", "# SVD hits per track", 20, 0, 20);
163  m_nSVDhits->GetXaxis()->SetTitle("# SVD hits");
164 
165 
166 }
167 
169 {
170 
171  // StoreObjPtr<EventMetaData> eventMD;
172 
173  m_nEvents++;
174  float c_eTOkeV = 3.6 / 1000; //keV = e * c_eTOkeV
175 
176  //tracks
177  if (m_Tracks) {
178  m_nTracks->Fill(m_Tracks.getEntries());
179  m_ntracks += m_Tracks.getEntries();
180  }
181  BOOST_FOREACH(Track & track, m_Tracks) {
182 
183  const TrackFitResult* tfr = track.getTrackFitResultWithClosestMass(Const::pion);
184  if (tfr) {
185  m_Pvalue->Fill(tfr->getPValue());
186  m_mom->Fill(tfr->getMomentum().R());
187  m_nSVDhits->Fill((tfr->getHitPatternVXD()).getNSVDHits());
188  }
189 
190  RelationVector<RecoTrack> theRC = DataStore::getRelationsWithObj<RecoTrack>(&track);
191  RelationVector<SVDCluster> svdClustersTrack = DataStore::getRelationsWithObj<SVDCluster>(theRC[0]);
192 
193  for (int cl = 0 ; cl < (int)svdClustersTrack.size(); cl++) {
194 
195  float clCharge = svdClustersTrack[cl]->getCharge();
196  float clEnergy = svdClustersTrack[cl]->getCharge() * c_eTOkeV;
197  int clSize = svdClustersTrack[cl]->getSize();
198  float clSN = svdClustersTrack[cl]->getSNR();
199  float clTime = svdClustersTrack[cl]->getClsTime();
200  float clPosition = svdClustersTrack[cl]->getPosition();
201  VxdID::baseType theVxdID = (VxdID::baseType)svdClustersTrack[cl]->getSensorID();
202  int side = svdClustersTrack[cl]->isUCluster();
203 
204  const VXD::SensorInfoBase* aSensorInfo = &VXD::GeoCache::getInstance().getSensorInfo(theVxdID);
205  float pitch = aSensorInfo->getVPitch();
206  if (side == 1)
207  pitch = aSensorInfo->getUPitch();
208  float clInterstripPos = fmod(clPosition, pitch) / pitch;
209 
210  h_clusterTrkCharge->fill(theVxdID, side, clCharge / 1000.);
211  h_clusterTrkSize->fill(theVxdID, side, clSize);
212  h_clusterTrkSNR->fill(theVxdID, side, clSN);
213  h_clusterTrkEnergy->fill(theVxdID, side, clEnergy);
214  h_clusterTrkTime->fill(theVxdID, side, clTime);
215  h_clusterTrkInterstripPos->fill(theVxdID, side, clInterstripPos);
216 
217  // if(svdClustersTrack.size()%2 != 0)
218  // B2INFO(" Event Number = "<<eventMD->getEvent()<<" "<<theVxdID<<"."<<side<<" position = "<<svdClustersTrack[cl]->getPosition()<<" charge = "<<svdClustersTrack[cl]->getCharge());
219 
220  }
221  }
222 
223  if (m_Tracks)
224  B2DEBUG(29, "%%%%%%%% NEW EVENT, number of Tracks = " << m_Tracks.getEntries());
225 
226  //reco digits
227  if (m_plotRecoDigits) {
228  if (m_svdRecos.isValid()) {
229  for (int digi = 0 ; digi < m_svdRecos.getEntries(); digi++) {
230 
231  VxdID::baseType theVxdID = (VxdID::baseType)m_svdRecos[digi]->getSensorID();
232  int side = m_svdRecos[digi]->isUStrip();
233  int cellID = m_svdRecos[digi]->getCellID();
234 
235  float thisNoise = m_NoiseCal.getNoiseInElectrons(theVxdID, side, cellID);
236 
237  h_recoNoise->fill(theVxdID, side, thisNoise);
238  h_recoCharge->fill(theVxdID, side, m_svdRecos[digi]->getCharge() / 1000.);
239  h_recoEnergy->fill(theVxdID, side, m_svdRecos[digi]->getCharge()*c_eTOkeV);
240  h_recoTime->fill(theVxdID, side, m_svdRecos[digi]->getTime());
241  }
242  }
243  }
244 
245 
246  //clusters NOT related to tracks
247  for (int cl = 0 ; cl < m_svdClusters.getEntries(); cl++) {
248 
249  float clCharge = m_svdClusters[cl]->getCharge();
250  float clEnergy = m_svdClusters[cl]->getCharge() * c_eTOkeV;
251  int clSize = m_svdClusters[cl]->getSize();
252  float clTime = m_svdClusters[cl]->getClsTime();
253  float clSN = m_svdClusters[cl]->getSNR();
254 
255  RelationVector<RecoTrack> theRC = DataStore::getRelationsWithObj<RecoTrack>(m_svdClusters[cl]);
256 
257  bool isAssigned = false;
258  // for(int r = 0; r<(int)theRC.size(); r++){
259  if (theRC.size() > 0) {
260  RelationVector<Track> theT = DataStore::getRelationsWithObj<Track>(theRC[0]);
261  if (theT.size() > 0)
262  isAssigned = true;
263  // }
264  }
265 
266  if (isAssigned)
267  continue;
268 
269  VxdID::baseType theVxdID = (VxdID::baseType)m_svdClusters[cl]->getSensorID();
270  int side = m_svdClusters[cl]->isUCluster();
271 
272  h_clusterCharge->fill(theVxdID, side, clCharge / 1000.);
273  h_clusterSize->fill(theVxdID, side, clSize);
274  h_clusterSNR->fill(theVxdID, side, clSN);
275  h_clusterEnergy->fill(theVxdID, side, clEnergy);
276  h_clusterTime->fill(theVxdID, side, clTime);
277  }
278 }
279 
280 
282 {
283  B2INFO("SVDB4CommissioningPlotsModule::endRun(), writing the histograms");
284 
285  if (m_rootFilePtr != nullptr) {
286  m_rootFilePtr->cd();
287 
288  TDirectory* oldDir = gDirectory;
289 
290  TDirectory* dir_track = oldDir->mkdir("tracks");
291  dir_track->cd();
292  m_nTracks->Write();
293  m_Pvalue->Write();
294  m_mom->Write();
295  m_nSVDhits->Write();
296 
297  TDirectory* dir_reco = oldDir->mkdir("recoDigits");
298  TDirectory* dir_clusterAssigned = oldDir->mkdir("clusters_assigned");
299  TDirectory* dir_clusterNotAssigned = oldDir->mkdir("clusters_not_assigned");
300 
302 
303  for (auto layer : geoCache.getLayers(VXD::SensorInfoBase::SVD)) {
304  TString layerName = Form("layer%d", layer.getLayerNumber());
305  TDirectory* dir_reco_layer = dir_reco->mkdir(layerName.Data());
306  TDirectory* dir_clusterAssigned_layer = dir_clusterAssigned->mkdir(layerName.Data());
307  TDirectory* dir_clusterNotAssigned_layer = dir_clusterNotAssigned->mkdir(layerName.Data());
308  for (auto ladder : geoCache.getLadders(layer))
309  for (Belle2::VxdID sensor : geoCache.getSensors(ladder))
310  for (int view = SVDHistograms<TH1F>::VIndex ; view < SVDHistograms<TH1F>::UIndex + 1; view++) {
311 
312  if (m_plotRecoDigits) {
313  dir_reco_layer->cd();
314  (h_recoCharge->getHistogram(sensor, view))->Write();
315  (h_recoEnergy->getHistogram(sensor, view))->Write();
316  (h_recoTime->getHistogram(sensor, view))->Write();
317  (h_recoNoise->getHistogram(sensor, view))->Write();
318  }
319  dir_clusterAssigned_layer->cd();
320  (h_clusterTrkCharge->getHistogram(sensor, view))->Write();
321  (h_clusterTrkSNR->getHistogram(sensor, view))->Write();
322  (h_clusterTrkSize->getHistogram(sensor, view))->Write();
323  (h_clusterTrkEnergy->getHistogram(sensor, view))->Write();
324  (h_clusterTrkTime->getHistogram(sensor, view))->Write();
325  (h_clusterTrkInterstripPos->getHistogram(sensor, view))->Write();
326  dir_clusterNotAssigned_layer->cd();
327  (h_clusterCharge->getHistogram(sensor, view))->Write();
328  (h_clusterSNR->getHistogram(sensor, view))->Write();
329  (h_clusterSize->getHistogram(sensor, view))->Write();
330  (h_clusterEnergy->getHistogram(sensor, view))->Write();
331  (h_clusterTime->getHistogram(sensor, view))->Write();
332  }
333  }
334 
335  m_rootFilePtr->Close();
336 
337  }
338 
339 }
static const ChargedStable pion
charged pion particle
Definition: Const.h:652
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
Class for type safe access to objects that are referred to in relations.
size_t size() const
Get number of relations.
SVDHistograms< TH1F > * h_clusterTrkSNR
SVDClusters SNR.
bool m_plotRecoDigits
Produce plots for SVDRecoDigits when True.
SVDHistograms< TH1F > * h_clusterTrkCharge
SVDClusters Charge.
virtual void initialize() override
check StoreArrays & create rootfile
StoreArray< SVDCluster > m_svdClusters
SVDCluster StoreArray.
virtual void event() override
fill histograms
StoreArray< TrackFitResult > m_tfr
TrackFitResult StoreArray.
SVDNoiseCalibrations m_NoiseCal
SVDNoise Calibrations db object.
virtual void endRun() override
write histogrmas
SVDHistograms< TH1F > * h_recoEnergy
SVDRecoDigits Energy.
SVDHistograms< TH1F > * h_clusterTrkEnergy
SVDClusters Energy.
SVDHistograms< TH1F > * h_clusterEnergy
SVDClusters Energy.
SVDHistograms< TH1F > * h_clusterSNR
SVDClusters SNR.
std::string m_TrackName
Track StoreArray name.
std::string m_RecoDigitName
SVDRecoDigit StoreArray name.
SVDHistograms< TH1F > * h_recoNoise
SVDRecoDigits Noise.
virtual void beginRun() override
create histograms
std::string m_TrackFitResultName
TrackFitResult name.
SVDHistograms< TH1F > * h_clusterSize
SVDClusters Size.
SVDHistograms< TH1F > * h_recoCharge
SVDRecoDigits Charge.
SVDHistograms< TH1F > * h_clusterTime
SVDClusters Time.
SVDHistograms< TH1F > * h_recoTime
SVDRecoDigits Time.
StoreArray< RecoTrack > m_recoTracks
RecoTrack StoreArray.
std::string m_ClusterName
SVDCluster StoreArray name.
StoreArray< SVDRecoDigit > m_svdRecos
SVDRecoDigit StoreArray.
SVDHistograms< TH1F > * h_clusterTrkTime
SVDClusters Time.
SVDHistograms< TH1F > * h_clusterCharge
SVDClusters Charge.
StoreArray< Track > m_Tracks
Track StoreArray.
TFile * m_rootFilePtr
pointer at root file used for storing histograms
SVDHistograms< TH1F > * h_clusterTrkSize
SVDClusters Size.
SVDHistograms< TH1F > * h_clusterTrkInterstripPos
SVDClusters InterstripPosition.
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 getNoiseInElectrons(const VxdID &sensorID, const bool &isU, const unsigned short &strip) const
This method provides the correct noise conversion into electrons, taking into account that the noise ...
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
bool isOptional(const std::string &name="")
Tell the DataStore about an optional input.
int getEntries() const
Get the number of objects in the array.
Definition: StoreArray.h:216
Values of the result of a track fit with a given particle hypothesis.
double getPValue() const
Getter for Chi2 Probability of the track fit.
ROOT::Math::XYZVector getMomentum() const
Getter for vector of momentum at closest approach of track in r/phi projection.
HitPatternVXD getHitPatternVXD() const
Getter for the hit pattern in the VXD;.
Class that bundles various TrackFitResults.
Definition: Track.h:25
Class to faciliate easy access to sensor information of the VXD like coordinate transformations or pi...
Definition: GeoCache.h:39
const SensorInfoBase & getSensorInfo(Belle2::VxdID id) const
Return a referecne 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.
double getUPitch(double v=0) const
Return the pitch of the sensor.
double getVPitch(double v=0) const
Return the pitch of the sensor.
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
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
Abstract base class for different kinds of events.