1 |
econte |
1.1 |
#ifndef CkfPattern_TempTrajectory_H
|
2 |
|
|
#define CkfPattern_TempTrajectory_H
|
3 |
|
|
|
4 |
|
|
#include "TrackingTools/PatternTools/interface/TrajectoryMeasurement.h"
|
5 |
|
|
#include "DataFormats/TrajectorySeed/interface/PropagationDirection.h"
|
6 |
|
|
#include "DataFormats/TrajectorySeed/interface/TrajectorySeed.h"
|
7 |
|
|
#include "TrackingTools/TransientTrackingRecHit/interface/TransientTrackingRecHit.h"
|
8 |
|
|
#include "DataFormats/Common/interface/OwnVector.h"
|
9 |
|
|
|
10 |
|
|
#include <vector>
|
11 |
|
|
#include <algorithm>
|
12 |
|
|
#include <boost/shared_ptr.hpp>
|
13 |
|
|
#include "TrackingTools/PatternTools/interface/bqueue.h"
|
14 |
|
|
|
15 |
|
|
#include "TrackingTools/PatternTools/interface/Trajectory.h"
|
16 |
|
|
|
17 |
|
|
/** A class for detailed particle trajectory representation.
|
18 |
|
|
* It is used during trajectory building to "grow" a trajectory.
|
19 |
|
|
* The trajectory is represented as an ordered sequence of
|
20 |
|
|
* TrajectoryMeasurement objects with a stack-like interface.
|
21 |
|
|
* The measurements are added to the Trajectory in the order of
|
22 |
|
|
* increasing precision: each new TrajectoryMeasurement is assumed to improve
|
23 |
|
|
* the precision of the last one, normally by adding a constraint from
|
24 |
|
|
* a new RecHit.
|
25 |
|
|
* However the Trajectory class does not have the means to verify
|
26 |
|
|
* that measurements are added in the correct order, and thus cannot
|
27 |
|
|
* guarantee the order, which is the responsibility of the
|
28 |
|
|
* TrajectoryBuilder. The Trajectory provides some security by
|
29 |
|
|
* allowing to add or remove measurements only on one of it's ends,
|
30 |
|
|
* with push(TM) and pop() methods. The last measurement in a Trajectory
|
31 |
|
|
* can thus be either the innermost (closest to the interaction point)
|
32 |
|
|
* or the outermost, depending on the way the Trajectory was built.
|
33 |
|
|
* The direction of building is represented as a PropagationDirection,
|
34 |
|
|
* which has two possible values: alongMomentum (outwards) and
|
35 |
|
|
* oppositeToMomentum (inwards), and is accessed with the direction()
|
36 |
|
|
* method.
|
37 |
|
|
*/
|
38 |
|
|
|
39 |
|
|
|
40 |
|
|
class TempTrajectory
|
41 |
|
|
{
|
42 |
|
|
public:
|
43 |
|
|
|
44 |
|
|
typedef cmsutils::bqueue<TrajectoryMeasurement> DataContainer;
|
45 |
|
|
typedef TransientTrackingRecHit::ConstRecHitContainer ConstRecHitContainer;
|
46 |
|
|
typedef ConstRecHitContainer RecHitContainer;
|
47 |
|
|
|
48 |
|
|
|
49 |
|
|
/** Default constructor of an empty trajectory with undefined seed and
|
50 |
|
|
* undefined direction. This constructor is necessary in order to transiently
|
51 |
|
|
* copy vector<Trajectory> in the edm::Event
|
52 |
|
|
*/
|
53 |
|
|
|
54 |
|
|
TempTrajectory() :
|
55 |
|
|
theChiSquared(0),
|
56 |
|
|
theNumberOfFoundHits(0), theNumberOfLostHits(0),
|
57 |
|
|
theDirection(alongMomentum), theDirectionValidity(false),
|
58 |
|
|
theValid(true)
|
59 |
|
|
{}
|
60 |
|
|
|
61 |
|
|
|
62 |
|
|
/** Constructor of an empty trajectory with undefined direction.
|
63 |
|
|
* The direction will be defined at the moment of the push of a second
|
64 |
|
|
* measurement, from the relative radii of the first and second
|
65 |
|
|
* measurements.
|
66 |
|
|
*/
|
67 |
|
|
|
68 |
|
|
TempTrajectory( const TrajectorySeed& seed) :
|
69 |
|
|
theSeed( new TrajectorySeed(seed) ),
|
70 |
|
|
theChiSquared(0),
|
71 |
|
|
theNumberOfFoundHits(0), theNumberOfLostHits(0),
|
72 |
|
|
theDirection(alongMomentum), theDirectionValidity(false),
|
73 |
|
|
theValid(true)
|
74 |
|
|
{}
|
75 |
|
|
|
76 |
|
|
/** Constructor of an empty trajectory with defined direction.
|
77 |
|
|
* No check is made in the push method that measurements are
|
78 |
|
|
* added in the correct direction.
|
79 |
|
|
*/
|
80 |
|
|
TempTrajectory( const TrajectorySeed& seed, PropagationDirection dir) :
|
81 |
|
|
theSeed( new TrajectorySeed(seed) ),
|
82 |
|
|
theChiSquared(0),
|
83 |
|
|
theNumberOfFoundHits(0), theNumberOfLostHits(0),
|
84 |
|
|
theDirection(dir), theDirectionValidity(true),
|
85 |
|
|
theValid(true)
|
86 |
|
|
{}
|
87 |
|
|
|
88 |
|
|
/** Constructor of an empty trajectory with defined direction.
|
89 |
|
|
* No check is made in the push method that measurements are
|
90 |
|
|
* added in the correct direction.
|
91 |
|
|
*/
|
92 |
|
|
TempTrajectory( const boost::shared_ptr<const TrajectorySeed> & seed, PropagationDirection dir) :
|
93 |
|
|
theSeed( seed ),
|
94 |
|
|
theChiSquared(0),
|
95 |
|
|
theNumberOfFoundHits(0), theNumberOfLostHits(0),
|
96 |
|
|
theDirection(dir), theDirectionValidity(true),
|
97 |
|
|
theValid(true)
|
98 |
|
|
{}
|
99 |
|
|
|
100 |
|
|
|
101 |
|
|
/** Constructor of an empty trajectory with defined direction.
|
102 |
|
|
* No check is made in the push method that measurements are
|
103 |
|
|
* added in the correct direction.
|
104 |
|
|
*/
|
105 |
|
|
TempTrajectory(PropagationDirection dir) :
|
106 |
|
|
theChiSquared(0),
|
107 |
|
|
theNumberOfFoundHits(0), theNumberOfLostHits(0),
|
108 |
|
|
theDirection(dir), theDirectionValidity(true),
|
109 |
|
|
theValid(true)
|
110 |
|
|
{}
|
111 |
|
|
|
112 |
|
|
|
113 |
|
|
#if defined( __GXX_EXPERIMENTAL_CXX0X__)
|
114 |
|
|
|
115 |
|
|
TempTrajectory(TempTrajectory const & rh) :
|
116 |
|
|
theSeed(rh.theSeed),
|
117 |
|
|
theData(rh.theData),
|
118 |
|
|
theChiSquared(rh.theChiSquared),
|
119 |
|
|
theNumberOfFoundHits(rh.theNumberOfFoundHits), theNumberOfLostHits(rh.theNumberOfLostHits),
|
120 |
|
|
theDirection(rh.theDirection), theDirectionValidity(rh.theDirectionValidity),theValid(rh.theValid)
|
121 |
|
|
{}
|
122 |
|
|
|
123 |
|
|
|
124 |
|
|
TempTrajectory & operator=(TempTrajectory const & rh) {
|
125 |
|
|
DataContainer aData(rh.theData);
|
126 |
|
|
using std::swap;
|
127 |
|
|
swap(theData,aData);
|
128 |
|
|
theSeed = rh.theSeed;
|
129 |
|
|
theChiSquared=rh.theChiSquared;
|
130 |
|
|
theNumberOfFoundHits=rh.theNumberOfFoundHits;
|
131 |
|
|
theNumberOfLostHits=rh.theNumberOfLostHits;
|
132 |
|
|
theDirection=rh.theDirection;
|
133 |
|
|
theDirectionValidity=rh.theDirectionValidity;
|
134 |
|
|
theValid=rh.theValid;
|
135 |
|
|
|
136 |
|
|
return *this;
|
137 |
|
|
|
138 |
|
|
}
|
139 |
|
|
|
140 |
|
|
|
141 |
|
|
TempTrajectory(TempTrajectory && rh) :
|
142 |
|
|
theSeed(std::move(rh.theSeed)),
|
143 |
|
|
theData(std::move(rh.theData)),
|
144 |
|
|
theChiSquared(rh.theChiSquared),
|
145 |
|
|
theNumberOfFoundHits(rh.theNumberOfFoundHits), theNumberOfLostHits(rh.theNumberOfLostHits),
|
146 |
|
|
theDirection(rh.theDirection), theDirectionValidity(rh.theDirectionValidity),
|
147 |
|
|
theValid(rh.theValid)
|
148 |
|
|
{}
|
149 |
|
|
|
150 |
|
|
TempTrajectory & operator=(TempTrajectory && rh) {
|
151 |
|
|
using std::swap;
|
152 |
|
|
swap(theSeed,rh.theSeed);
|
153 |
|
|
swap(theData,rh.theData);
|
154 |
|
|
theChiSquared=rh.theChiSquared;
|
155 |
|
|
theNumberOfFoundHits=rh.theNumberOfFoundHits;
|
156 |
|
|
theNumberOfLostHits=rh.theNumberOfLostHits;
|
157 |
|
|
theDirection=rh.theDirection;
|
158 |
|
|
theDirectionValidity=rh.theDirectionValidity;
|
159 |
|
|
theValid=rh.theValid;
|
160 |
|
|
|
161 |
|
|
return *this;
|
162 |
|
|
|
163 |
|
|
}
|
164 |
|
|
|
165 |
|
|
|
166 |
|
|
#endif
|
167 |
|
|
|
168 |
|
|
|
169 |
|
|
|
170 |
|
|
/// construct TempTrajectory from standard Trajectory
|
171 |
|
|
TempTrajectory( const Trajectory& traj);
|
172 |
|
|
|
173 |
|
|
/// destruct a TempTrajectory
|
174 |
|
|
// trivial destructor, but must be out-of-line for code size issues
|
175 |
|
|
// https://hypernews.cern.ch/HyperNews/CMS/get/code-perf/247.html
|
176 |
|
|
~TempTrajectory() ;
|
177 |
|
|
|
178 |
|
|
/** Add a new measurement to a Trajectory.
|
179 |
|
|
* The Chi2 of the trajectory is incremented by the value
|
180 |
|
|
* of tm.estimate() .
|
181 |
|
|
*/
|
182 |
|
|
void push( const TrajectoryMeasurement& tm);
|
183 |
|
|
#if defined( __GXX_EXPERIMENTAL_CXX0X__)
|
184 |
|
|
void push(TrajectoryMeasurement&& tm);
|
185 |
|
|
#endif
|
186 |
|
|
/** Add a new sets of measurements to a Trajectory
|
187 |
|
|
* The sorting of hits in the other trajectory must match the one
|
188 |
|
|
* inside this trajectory (that is, both along or both opposite to momentum)
|
189 |
|
|
*/
|
190 |
|
|
void push( const TempTrajectory & segment);
|
191 |
|
|
|
192 |
|
|
/** Add a new sets of measurements to a Trajectory
|
193 |
|
|
* Exactly like push(TempTrajectory), but it doesn't copy the data
|
194 |
|
|
* (the input segment will be reset to an empty one)
|
195 |
|
|
*/
|
196 |
|
|
void join( TempTrajectory & segment);
|
197 |
|
|
|
198 |
|
|
|
199 |
|
|
|
200 |
|
|
/** same as the one-argument push, but the trajectory Chi2 is incremented
|
201 |
|
|
* by chi2Increment. Useful e.g. in trajectory smoothing.
|
202 |
|
|
*/
|
203 |
|
|
void push( const TrajectoryMeasurement& tm, double chi2Increment);
|
204 |
|
|
#if defined( __GXX_EXPERIMENTAL_CXX0X__)
|
205 |
|
|
void push( TrajectoryMeasurement&& tm, double chi2Increment);
|
206 |
|
|
#endif
|
207 |
|
|
/** Remove the last measurement from the trajectory.
|
208 |
|
|
*/
|
209 |
|
|
void pop();
|
210 |
|
|
|
211 |
|
|
/** Access to the last measurement.
|
212 |
|
|
* It's the most precise one in a trajectory before smoothing.
|
213 |
|
|
* It's the outermost measurement if direction() == alongMomentum,
|
214 |
|
|
* the innermost one if direction() == oppositeToMomentum.
|
215 |
|
|
*/
|
216 |
|
|
const TrajectoryMeasurement & lastMeasurement() const {
|
217 |
|
|
check(); return theData.back();
|
218 |
|
|
}
|
219 |
|
|
|
220 |
|
|
/** Access to the first measurement.
|
221 |
|
|
* It is the least precise one in a trajectory before smoothing.
|
222 |
|
|
* It is precise in a smoothed trajectory.
|
223 |
|
|
* It's the innermost measurement if direction() == alongMomentum,
|
224 |
|
|
* the outermost one if direction() == oppositeToMomentum.
|
225 |
|
|
*/
|
226 |
|
|
const TrajectoryMeasurement & firstMeasurement() const {
|
227 |
|
|
check(); return theData.front();
|
228 |
|
|
}
|
229 |
|
|
|
230 |
|
|
/** Return all measurements in a container.
|
231 |
|
|
*/
|
232 |
|
|
const DataContainer & measurements() const { return theData; }
|
233 |
|
|
/// obsolete name, use measurements() instead.
|
234 |
|
|
//DataContainer data() const { return measurements();}
|
235 |
|
|
|
236 |
|
|
/** Return all RecHits in a container.
|
237 |
|
|
*/
|
238 |
|
|
//ConstRecHitContainer recHits() const;
|
239 |
|
|
|
240 |
|
|
/** Number of valid RecHits used to determine the trajectory.
|
241 |
|
|
* Can be less than the number of measurements in data() since
|
242 |
|
|
* detector layers crossed without using RecHits from them are also
|
243 |
|
|
* stored as measurements.
|
244 |
|
|
*/
|
245 |
|
|
|
246 |
|
|
int foundHits() const { return theNumberOfFoundHits;}
|
247 |
|
|
|
248 |
|
|
/** Number of detector layers crossed without valid RecHits.
|
249 |
|
|
* Used mainly as a criteria for abandoning a trajectory candidate
|
250 |
|
|
* during trajectory building.
|
251 |
|
|
*/
|
252 |
|
|
|
253 |
|
|
int lostHits() const { return theNumberOfLostHits;}
|
254 |
|
|
|
255 |
|
|
/// True if trajectory has no measurements.
|
256 |
|
|
bool empty() const { return theData.empty();}
|
257 |
|
|
|
258 |
|
|
/// Value of the raw Chi2 of the trajectory, not normalised to the N.D.F.
|
259 |
|
|
double chiSquared() const { return theChiSquared;}
|
260 |
|
|
|
261 |
|
|
/** Direction of "growing" of the trajectory.
|
262 |
|
|
* Possible values are alongMomentum (outwards) and
|
263 |
|
|
* oppositeToMomentum (inwards).
|
264 |
|
|
*/
|
265 |
|
|
PropagationDirection direction() const;
|
266 |
|
|
|
267 |
|
|
/** Returns true if the Trajectory is valid.
|
268 |
|
|
* Trajectories are invalidated e.g. during ambiguity resolution.
|
269 |
|
|
*/
|
270 |
|
|
bool isValid() const { return theValid;}
|
271 |
|
|
|
272 |
|
|
/// Method to invalidate a trajectory. Useful during ambiguity resolution.
|
273 |
|
|
void invalidate() { theValid = false;}
|
274 |
|
|
|
275 |
|
|
/// Access to the seed used to reconstruct the Trajectory
|
276 |
|
|
const TrajectorySeed & seed() const { return *theSeed;}
|
277 |
|
|
|
278 |
|
|
|
279 |
|
|
/** Definition of inactive Det from the Trajectory point of view.
|
280 |
|
|
*/
|
281 |
|
|
static bool inactive(//const Det& det
|
282 |
|
|
){return false;}//FIXME
|
283 |
|
|
|
284 |
|
|
/** Definition of what it means for a hit to be "lost".
|
285 |
|
|
* This definition is also used by the TrajectoryBuilder.
|
286 |
|
|
*/
|
287 |
|
|
static bool lost( const TransientTrackingRecHit& hit);
|
288 |
|
|
|
289 |
|
|
/// Redundant method, returns the layer of lastMeasurement() .
|
290 |
|
|
const DetLayer* lastLayer() const {
|
291 |
|
|
check(); return theData.back().layer();
|
292 |
|
|
}
|
293 |
|
|
|
294 |
|
|
/// Convert to a standard Trajectory
|
295 |
|
|
Trajectory toTrajectory() const ;
|
296 |
|
|
|
297 |
|
|
/// Pops out all the invalid hits on the tail
|
298 |
|
|
void popInvalidTail() ;
|
299 |
|
|
private:
|
300 |
|
|
|
301 |
|
|
void pushAux( const TrajectoryMeasurement& tm, double chi2Increment);
|
302 |
|
|
|
303 |
|
|
private:
|
304 |
|
|
|
305 |
|
|
|
306 |
|
|
boost::shared_ptr<const TrajectorySeed> theSeed;
|
307 |
|
|
DataContainer theData;
|
308 |
|
|
|
309 |
|
|
float theChiSquared;
|
310 |
|
|
|
311 |
|
|
signed short theNumberOfFoundHits;
|
312 |
|
|
signed short theNumberOfLostHits;
|
313 |
|
|
|
314 |
|
|
PropagationDirection theDirection;
|
315 |
|
|
bool theDirectionValidity;
|
316 |
|
|
bool theValid;
|
317 |
|
|
|
318 |
|
|
|
319 |
|
|
void check() const;
|
320 |
|
|
};
|
321 |
|
|
|
322 |
|
|
#endif
|