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