Belle II Software  release-06-00-14
DQMEventProcessorBase.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 <tracking/dqmUtils/DQMEventProcessorBase.h>
10 #include <tracking/dqmUtils/DQMHistoModuleBase.h>
11 
12 #include <framework/datastore/StoreArray.h>
13 #include <vxd/geometry/GeoTools.h>
14 #include <vxd/geometry/SensorInfoBase.h>
15 
16 using namespace std;
17 using namespace Belle2;
18 
19 void DQMEventProcessorBase::Run()
20 {
21  StoreArray<RecoTrack> recoTracks(m_recoTracksStoreArrayName);
22  if (!recoTracks.isOptional()) {
23  B2DEBUG(22, "Missing recoTracks array in event() for " + m_histoModule->getName() + " module.");
24  return;
25  }
26  StoreArray<Track> tracks(m_tracksStoreArrayName);
27  if (!tracks.isOptional()) {
28  B2DEBUG(22, "Missing recoTracks array in event() for " + m_histoModule->getName() + " module.");
29  return;
30  }
31 
32  try {
33  m_iTrack = 0;
34  m_iTrackVXD = 0;
35  m_iTrackCDC = 0;
36  m_iTrackVXDCDC = 0;
37 
38  for (const Track& track : tracks) {
39  ProcessTrack(track);
40  }
41 
42  m_histoModule->FillTrackIndexes(m_iTrack, m_iTrackVXD, m_iTrackCDC, m_iTrackVXDCDC);
43  } catch (const std::exception& e) {
44  B2WARNING("Exception " + std::string(e.what()) + " in " + m_histoModule->getName() + " module!");
45  } catch (...) {
46  B2WARNING("Unhandled exception in " + m_histoModule->getName() + " module!");
47  }
48 }
49 
50 void DQMEventProcessorBase::ProcessTrack(const Track& track)
51 {
52  auto recoTracksVector = track.getRelationsTo<RecoTrack>(m_recoTracksStoreArrayName);
53  if (!recoTracksVector.size())
54  return;
55 
56  m_recoTrack = recoTracksVector[0];
57 
58  int nPXDClusters = 0;
59  if (!m_runningOnHLT) {
60  RelationVector<PXDCluster> pxdClusters = DataStore::getRelationsWithObj<PXDCluster>(m_recoTrack);
61  nPXDClusters = (int)pxdClusters.size();
62  }
63  RelationVector<SVDCluster> svdClusters = DataStore::getRelationsWithObj<SVDCluster>(m_recoTrack);
64  int nSVDClusters = (int)svdClusters.size();
65  RelationVector<CDCHit> cdcHits = DataStore::getRelationsWithObj<CDCHit>(m_recoTrack);
66  int nCDCHits = (int)cdcHits.size();
67 
68  // This method allways returns TrackFitResult so there's no need to check if it's not nullptr
69  auto trackFitResult = track.getTrackFitResultWithClosestMass(Const::pion);
70 
71  TString message = ConstructMessage(trackFitResult, nPXDClusters, nSVDClusters, nCDCHits);
72  B2DEBUG(20, message.Data());
73 
74  FillTrackFitResult(trackFitResult);
75  m_histoModule->FillHitNumbers(nPXDClusters, nSVDClusters, nCDCHits);
76 
77  if (m_recoTrack->wasFitSuccessful())
78  ProcessSuccessfulFit();
79 
80  m_iTrack++;
81  if (((nPXDClusters > 0) || (nSVDClusters > 0)) && (nCDCHits == 0))
82  m_iTrackVXD++;
83  if (((nPXDClusters == 0) && (nSVDClusters == 0)) && (nCDCHits > 0))
84  m_iTrackCDC++;
85  if (((nPXDClusters > 0) || (nSVDClusters > 0)) && (nCDCHits > 0))
86  m_iTrackVXDCDC++;
87 }
88 
89 TString DQMEventProcessorBase::ConstructMessage(const TrackFitResult* trackFitResult, int nPXDClusters, int nSVDClusters,
90  int nCDCHits)
91 {
92  return Form("%s: track %3i, Mom: %f, %f, %f, Pt: %f, Mag: %f, Hits: PXD %i SVD %i CDC %i Suma %i\n",
93  m_histoModule->getName().c_str(),
94  m_iTrack,
95  (float)trackFitResult->getMomentum().Px(),
96  (float)trackFitResult->getMomentum().Py(),
97  (float)trackFitResult->getMomentum().Pz(),
98  (float)trackFitResult->getMomentum().Pt(),
99  (float)trackFitResult->getMomentum().Mag(),
100  nPXDClusters, nSVDClusters, nCDCHits, nPXDClusters + nSVDClusters + nCDCHits
101  );
102 }
103 
104 void DQMEventProcessorBase::FillTrackFitResult(const TrackFitResult* trackFitResult)
105 {
106  if (m_runningOnHLT) {
107  m_histoModule->FillMomentumAngles(trackFitResult);
108  m_histoModule->FillMomentumCoordinates(trackFitResult);
109  }
110  m_histoModule->FillHelixParametersAndCorrelations(trackFitResult);
111 }
112 
113 void DQMEventProcessorBase::ProcessSuccessfulFit()
114 {
115  // function wasFitSuccessful already checked if TrackFitStatus is not nullptr so it's not necessary to do so
116  m_histoModule->FillTrackFitStatus(m_recoTrack->getTrackFitStatus());
117 
118  m_isNotFirstHit = false;
119 
120  for (auto recoHitInfo : m_recoTrack->getRecoHitInformations(true)) {
121  ProcessRecoHit(recoHitInfo);
122  }
123 }
124 
125 void DQMEventProcessorBase::ProcessRecoHit(RecoHitInformation* recoHitInfo)
126 {
127  if (!recoHitInfo) {
128  B2DEBUG(20, "Missing genfit::pxd recoHitInfo in event() for " + m_histoModule->getName() + " module.");
129  return;
130  }
131 
132  if (!recoHitInfo->useInFit())
133  return;
134 
135  bool isPXD = recoHitInfo->getTrackingDetector() == RecoHitInformation::c_PXD;
136  bool isSVD = recoHitInfo->getTrackingDetector() == RecoHitInformation::c_SVD;
137  if (!isPXD && !isSVD)
138  return;
139 
140  auto fitterInfo = m_recoTrack->getCreatedTrackPoint(recoHitInfo)->getFitterInfo();
141  if (!fitterInfo)
142  return;
143 
144  m_rawSensorResidual = new TVectorT<double>(fitterInfo->getResidual(0, false).getState());
145 
146  if (isPXD && ! m_runningOnHLT) {
147  ProcessPXDRecoHit(recoHitInfo);
148  } else if (isSVD) {
149  ProcessSVDRecoHit(recoHitInfo);
150  }
151 
152  delete m_rawSensorResidual;
153 }
154 
155 void DQMEventProcessorBase::ProcessPXDRecoHit(RecoHitInformation* recoHitInfo)
156 {
157  m_position.SetX(recoHitInfo->getRelatedTo<PXDCluster>()->getU());
158  m_position.SetY(recoHitInfo->getRelatedTo<PXDCluster>()->getV());
159  m_residual_um.SetX(m_rawSensorResidual->GetMatrixArray()[0] / Unit::um);
160  m_residual_um.SetY(m_rawSensorResidual->GetMatrixArray()[1] / Unit::um);
161 
162  m_sensorID = recoHitInfo->getRelatedTo<PXDCluster>()->getSensorID();
163  ComputeCommonVariables();
164 
165  FillCommonHistograms();
166 
167  m_histoModule->FillUBResidualsPXD(m_residual_um);
168  m_histoModule->FillHalfShellsPXD(m_globalResidual_um, IsNotYang(m_sensorID.getLadderNumber(), m_layerNumber));
169 
170  if (m_produce1Dres)
171  m_histoModule->FillUB1DResidualsSensor(m_residual_um, m_sensorIndex);
172  if (m_produce2Dres)
173  m_histoModule->FillUB2DResidualsSensor(m_residual_um, m_sensorIndex);
174 
175  SetCommonPrevVariables();
176 }
177 
178 void DQMEventProcessorBase::ProcessSVDRecoHit(RecoHitInformation* recoHitInfo)
179 {
180  if (recoHitInfo->getRelatedTo<SVDCluster>()->isUCluster()) {
181  m_position.SetX(recoHitInfo->getRelatedTo<SVDCluster>()->getPosition());
182  m_residual_um.SetX(m_rawSensorResidual->GetMatrixArray()[0] / Unit::um);
183  } else {
184  m_position.SetY(recoHitInfo->getRelatedTo<SVDCluster>()->getPosition());
185  m_residual_um.SetY(m_rawSensorResidual->GetMatrixArray()[0] / Unit::um);
186  }
187 
188  m_sensorID = recoHitInfo->getRelatedTo<SVDCluster>()->getSensorID();
189  if (m_sensorIDPrev == m_sensorID) {
190  ComputeCommonVariables();
191 
192  if (! m_runningOnHLT) {
193  FillCommonHistograms();
194 
195  m_histoModule->FillUBResidualsSVD(m_residual_um);
196  m_histoModule->FillHalfShellsSVD(m_globalResidual_um, IsNotMat(m_sensorID.getLadderNumber(), m_layerNumber));
197 
198  if (m_produce1Dres)
199  m_histoModule->FillUB1DResidualsSensor(m_residual_um, m_sensorIndex);
200  if (m_produce2Dres)
201  m_histoModule->FillUB2DResidualsSensor(m_residual_um, m_sensorIndex);
202  }
203 
204  SetCommonPrevVariables();
205  }
206 
207  m_sensorIDPrev = m_sensorID;
208 }
209 
210 void DQMEventProcessorBase::ComputeCommonVariables()
211 {
212  auto sensorInfo = &VXD::GeoCache::get(m_sensorID);
213  m_globalResidual_um = sensorInfo->vectorToGlobal(m_residual_um, true);
214  TVector3 globalPosition = sensorInfo->pointToGlobal(m_position, true);
215 
216  m_phi_deg = globalPosition.Phi() / Unit::deg;
217  m_theta_deg = globalPosition.Theta() / Unit::deg;
218 
219  m_layerNumber = m_sensorID.getLayerNumber();
220 
221  auto gTools = VXD::GeoCache::getInstance().getGeoTools();
222  m_layerIndex = gTools->getLayerIndex(m_layerNumber);
223  m_correlationIndex = m_layerIndex - gTools->getFirstLayer();
224  m_sensorIndex = gTools->getSensorIndex(m_sensorID);
225 }
226 
227 void DQMEventProcessorBase::FillCommonHistograms()
228 {
229  if (m_isNotFirstHit && ((m_layerNumber - m_layerNumberPrev) == 1)) {
230  m_histoModule->FillTRClusterCorrelations(m_phi_deg, m_phiPrev_deg, m_theta_deg, m_thetaPrev_deg, m_correlationIndex);
231  } else {
232  m_isNotFirstHit = true;
233  }
234 
235  m_histoModule->FillTRClusterHitmap(m_phi_deg, m_theta_deg, m_layerIndex);
236 }
237 
238 void DQMEventProcessorBase::SetCommonPrevVariables()
239 {
240  m_layerNumberPrev = m_layerNumber;
241  m_phiPrev_deg = m_phi_deg;
242  m_thetaPrev_deg = m_theta_deg;
243 }
244 
245 bool DQMEventProcessorBase::IsNotYang(int ladderNumber, int layerNumber)
246 {
247  switch (layerNumber) {
248  case 1:
249  return ladderNumber < 5 || ladderNumber > 8;
250  case 2:
251  return ladderNumber < 7 || ladderNumber > 12;
252  default:
253  return true;
254  }
255 }
256 
257 bool DQMEventProcessorBase::IsNotMat(int ladderNumber, int layerNumber)
258 {
259  switch (layerNumber) {
260  case 3:
261  return ladderNumber < 3 || ladderNumber > 5;
262  case 4:
263  return ladderNumber < 4 || ladderNumber > 8;
264  case 5:
265  return ladderNumber < 5 || ladderNumber > 10;
266  case 6:
267  return ladderNumber < 6 || ladderNumber > 13;
268  default:
269  return true;
270  }
271 }
The PXD Cluster class This class stores all information about reconstructed PXD clusters The position...
Definition: PXDCluster.h:30
float getV() const
Get v coordinate of hit position.
Definition: PXDCluster.h:136
float getU() const
Get u coordinate of hit position.
Definition: PXDCluster.h:131
This class stores additional information to every CDC/SVD/PXD hit stored in a RecoTrack.
RecoHitDetector getTrackingDetector() const
Get the detector this hit comes from.
bool useInFit() const
Get the flag, whether this his should be used in a fit or not.
This is the Reconstruction Event-Data Model Track.
Definition: RecoTrack.h:76
Class for type safe access to objects that are referred to in relations.
size_t size() const
Get number of relations.
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
bool isUCluster() const
Get the direction of strips.
Definition: SVDCluster.h:109
float getPosition(double v=0) const
Get the coordinate of reconstructed hit.
Definition: SVDCluster.h:116
bool isOptional(const std::string &name="")
Tell the DataStore about an optional input.
Accessor to arrays stored in the data store.
Definition: StoreArray.h:113
Values of the result of a track fit with a given particle hypothesis.
TVector3 getMomentum() const
Getter for vector of momentum at closest approach of track in r/phi projection.
Class that bundles various TrackFitResults.
Definition: Track.h:25
Abstract base class for different kinds of events.