Belle II Software development
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
18using namespace Belle2;
19
20
21SpacePointTrackCand::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
66const 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
83const 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
100const 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
132void 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
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)
156void 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: " <<
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
207std::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 necessary 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".
const std::vector< const Belle2::SpacePoint * > & getHits() const
get hits (space points) of track candidate
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 referee 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.
@ 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.