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