Belle II Software  release-06-02-00
SpacePointTrackCand.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 // SpacePointTrackCand.h
10 #include <tracking/spacePointCreation/SpacePointTrackCand.h>
11 
12 #include <TDatabasePDG.h>
13 #include <TVectorD.h>
14 
15 // debugging
16 #include <sstream> // used in print method
17 
18 using namespace std;
19 using namespace Belle2;
20 
21 
22 SpacePointTrackCand::SpacePointTrackCand(const std::vector<const Belle2::SpacePoint*>& spacePoints, int pdgCode,
23  double charge, int mcTrackID)
24 {
25  m_pdg = pdgCode;
26  m_q = charge;
27  m_MCTrackID = mcTrackID;
28 
29  double index = 0;
30  for (const SpacePoint* spacePoint : spacePoints) {
31  m_trackSpacePoints.push_back(spacePoint);
32  m_sortingParameters.push_back(index);
33  index++;
34  }
35 }
36 
37 // 'Equal To' operator for easier comparison of SpacePointTrackCands (e.g. for testing this class)
38 // bool operator== (SpacePointTrackCand& lhs, SpacePointTrackCand& rhs)
40 {
41  const auto& lhsHits = this->getHits();
42  const auto& rhsHits = rhs.getHits();
43 
44  // if one TrackCand has no SpacePoint, equality is not possible and further comparing is not needed
45  if (lhsHits.size() == 0 || rhsHits.size() == 0) {
46  B2DEBUG(80, "At least one of the SpacePointTrackCands does not contain any SpacePoints");
47  return false;
48  }
49 
50  // compare number of SpacePoints in TrackCandidate, return false if not equal
51  if (lhsHits.size() != rhsHits.size()) {
52  B2DEBUG(80, "Numbers of SpacePoints in SpacePointTrackCands do not match");
53  return false;
54  }
55 
56  // compare pointers to SpacePoint, if one is not equal, return false
57  for (unsigned int iSP = 0; iSP < lhsHits.size(); ++iSP) {
58  if (lhsHits[iSP] != rhsHits[iSP]) {
59  B2DEBUG(80, "SpacePoints " << iSP << " do not match");
60  return false;
61  }
62  }
63  return true;
64 }
65 
66 // get SpacePoints in range
67 const std::vector<const Belle2::SpacePoint*> SpacePointTrackCand::getHitsInRange(int firstIndex, int lastIndex) const
68 {
69  if (lastIndex < firstIndex) { // exchange ranges if they are in wrong order
70  int tmp = firstIndex;
71  firstIndex = lastIndex;
72  lastIndex = tmp;
73  }
74  // check if the indices are in range!
75  if (firstIndex < 0 || uint(lastIndex) > m_trackSpacePoints.size() || uint(firstIndex) > m_trackSpacePoints.size()
76  || lastIndex < 0) {
77  throw SPTCIndexOutOfBounds();
78  }
79  const std::vector<const SpacePoint*> spacePoints(m_trackSpacePoints.begin() + firstIndex, m_trackSpacePoints.begin() + lastIndex);
80  return spacePoints;
81 }
82 
83 // get Sorting Parameters in range
84 const std::vector<double> SpacePointTrackCand::getSortingParametersInRange(int firstIndex, int lastIndex) const
85 {
86  if (lastIndex < firstIndex) { // exchange ranges if they are in wrong order
87  int tmp = firstIndex;
88  firstIndex = lastIndex;
89  lastIndex = tmp;
90  }
91  // check if the indices are in range!
92  if (firstIndex < 0 || uint(lastIndex) > m_sortingParameters.size() || uint(firstIndex) > m_sortingParameters.size()
93  || lastIndex < 0) {
94  throw SPTCIndexOutOfBounds();
95  }
96  const std::vector<double> sortingParams(m_sortingParameters.begin() + firstIndex, m_sortingParameters.begin() + lastIndex);
97  return sortingParams;
98 }
99 
100 // get sorted hits
101 const std::vector<const SpacePoint*> SpacePointTrackCand::getSortedHits() const
102 {
103  std::vector<std::pair<const SpacePoint*, double>> sortVector;
104  sortVector.reserve(m_trackSpacePoints.size());
105  for (unsigned int index = 0; index < m_trackSpacePoints.size(); ++index) {
106  sortVector.push_back(std::make_pair(m_trackSpacePoints.at(index), m_sortingParameters.at(index)));
107  }
108 
109  std::sort(sortVector.begin(), sortVector.end(), [](const std::pair<const SpacePoint*, double>& a,
110  const std::pair<const SpacePoint*, double>& b) {
111  return a.second < b.second;
112  });
113 
114 
115  std::vector<const SpacePoint*> sortedSpacePoints;
116  //sortedSpacePoints.reserve(m_trackSpacePoints.size());
117  for (auto pair : sortVector) {
118  sortedSpacePoints.push_back(pair.first);
119  }
120 
121  return sortedSpacePoints;
122 }
123 
124 // more or less copy pasted from genfit::TrackCand
125 void SpacePointTrackCand::setPdgCode(int pdgCode)
126 {
127  m_pdg = pdgCode;
128  TParticlePDG* part = TDatabasePDG::Instance()->GetParticle(m_pdg);
129  m_q = part->Charge() / (3.); // charge returned in units of |e|/3 by TParticlePDG -> Charge()
130 }
131 
132 // set sorting parameters
133 void SpacePointTrackCand::setSortingParameters(const std::vector<double>& sortParams)
134 {
135  if (sortParams.size() != m_sortingParameters.size())
136  throw SPTCSortingParameterSizeInvalid();
137  for (size_t iSP = 0; iSP < sortParams.size(); ++iSP) {
138  m_sortingParameters.at(iSP) = sortParams.at(iSP);
139  }
140 }
141 
142 // remove a SpacePoint by index
143 void SpacePointTrackCand::removeSpacePoint(int indexInTrackCand)
144 {
145  // check if the index is in bounds
146  if (uint(indexInTrackCand) >= m_trackSpacePoints.size()) { throw SPTCIndexOutOfBounds(); }
147 
148  // erase the entry from vector
149  m_trackSpacePoints.erase(m_trackSpacePoints.begin() + indexInTrackCand);
150  m_sortingParameters.erase(m_sortingParameters.begin() + indexInTrackCand);
151 }
152 
153 // genfit::TrackCand prints to stdout, as does the Print method from ROOT TVectorD (which is invoked here).
154 // I build a stringstrem, which I then hand over B2DEBUG
155 // there is a somewhat nasty hack to intercept the output to the stdout by redirecting the stdout to a buffer, which can then be put into a stringstream. This is however platform-dependent and not very C++ like and therefore not done here (this would be needed for having the ROOT output in the log files which are created from within a steering file)
156 // however the LogSystem provides a way to check if ROOT output is actually needed (check the LogLevel and the DebugLevel)
157 void SpacePointTrackCand::print(int debuglevel, const Option_t* option) const
158 {
159  stringstream output;
160  output << " ======= SpacePointTrackCand::print() ======= \n";
161  output << "This track candidate has " << m_trackSpacePoints.size() << " SpacePoints\n";
162  output << "mcTrackId: " << m_MCTrackID << "\n";
163  output << "seed values for 6D state : \n";
164  B2DEBUG(debuglevel, output.str());
165 
166  // reset the output stream
167  output.str(std::string(""));
168  output.clear();
169 
170  // Only print this if the debuglevel is high enough
171  if (LogSystem::Instance().isLevelEnabled(LogConfig::c_Debug, debuglevel, PACKAGENAME())) { m_state6D.Print(option); }
172 
173  output << "estimates of Track Candidate: \n";
174  output << "q = " << m_q << "\n";
175  output << "pdgCode = " << m_pdg << "\n";
176  output << ", QI = " << m_qualityIndicator << "\n";
177 
178  unsigned nSP = 0;
179  for (const SpacePoint* spacePoint : getHits()) {
180  // COULDDO: implement a print method for SpacePoints
181  output << "SpacePoint " << nSP << " has Index " << spacePoint->getArrayIndex() << " in StoreArray " << spacePoint->getArrayName() <<
182  "." << "\n";
183  nSP++;
184  }
185 
186  B2DEBUG(debuglevel, output.str());
187 
188  // reset the output stream
189  output.str(std::string(""));
190  output.clear();
191 
192  output << "referee properties of this SPTC:\n";
193  output << "checked for SPs on same sensors: " << this->hasRefereeStatus(c_checkedSameSensors) << " -> result: " <<
194  this->hasRefereeStatus(c_hitsOnSameSensor) << "\n";
195  output << "checked for min distance between SPs: " << this->hasRefereeStatus(c_checkedMinDistance) << " -> result: " <<
196  this->hasRefereeStatus(c_hitsLowDistance) << "\n";
197  output << "checked for curling: " << this->checkedForCurling() << " -> result: " << this->isCurling() <<
198  ", part of a curling SPTC: " << this->isPartOfCurlingTrack() << "\n";
199  output << "direction of flight: " << m_flightDirection << ", removed SpacePoints: " << this->hasRefereeStatus(
200  c_removedHits) << "\n";
201  output << "omitted Clusters: " << hasRefereeStatus(c_omittedClusters) << ", single Cluster SPs: " << hasRefereeStatus(
202  c_singleClustersSPs) << "\n";
203  B2DEBUG(debuglevel, output.str());
204 }
205 
206 // get referee status as string
207 // COULDDO: this can possibly be done with switch - case, which is probably faster
208 std::string SpacePointTrackCand::getRefereeStatusString(std::string delimiter) const
209 {
210  std::string statusString;
211  if (getRefereeStatus() == 0) return statusString; // return empty string if there is no status
212  if (hasRefereeStatus(c_checkedByReferee)) statusString += "checkedByReferee" + delimiter;
213  if (hasRefereeStatus(c_checkedClean)) statusString += "checkedClean" + delimiter;
214  if (hasRefereeStatus(c_hitsOnSameSensor)) statusString += "hitsOnSameSensor" + delimiter;
215  if (hasRefereeStatus(c_hitsLowDistance)) statusString += "hitsLowDistance" + delimiter;
216  if (hasRefereeStatus(c_removedHits)) statusString += "removedHits" + delimiter;
217  if (hasRefereeStatus(c_checkedTrueHits)) statusString += "checkedTrueHits" + delimiter;
218  if (hasRefereeStatus(c_checkedSameSensors)) statusString += "checkedSameSensors" + delimiter;
219  if (hasRefereeStatus(c_checkedMinDistance)) statusString += "checkedMinDistance" + delimiter;
220  if (hasRefereeStatus(c_curlingTrack)) statusString += "curlingTrack" + delimiter;
221  if (hasRefereeStatus(c_omittedClusters)) statusString += "omittedClusters" + delimiter;
222  if (hasRefereeStatus(c_singleClustersSPs)) statusString += "singleClusterSPs" + delimiter;
223  if (hasRefereeStatus(c_isActive)) statusString += "isActive" + delimiter;
224  if (hasRefereeStatus(c_isReserved)) statusString += "isReserved" + delimiter;
225 
226  statusString.erase(statusString.end() - delimiter.size(),
227  statusString.end()); // remove last delimiter -> no error catching SHOULD be neccessary since the case of an empty (==0) refereeStatus is already dealt with above!
228  return statusString;
229 }
Storage for (VXD) SpacePoint-based track candidates.
const std::vector< const Belle2::SpacePoint * > & getHits() const
get hits (space points) of track candidate
SpacePoint typically is build from 1 PXDCluster or 1-2 SVDClusters.
Definition: SpacePoint.h:42
bool operator==(const DecayNode &node1, const DecayNode &node2)
Compare two Decay Nodes: They are equal if All daughter decay nodes are equal or one of the daughter ...
Definition: DecayNode.cc:48
Abstract base class for different kinds of events.