CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Trajectory.cc
Go to the documentation of this file.
2 #include "boost/intrusive_ptr.hpp"
6 
11 
12 
13 #include <algorithm>
14 
15 using namespace std;
16 
18  if (!empty()) {
19  if(theData.back().recHit()->isValid()) {
20  theNumberOfFoundHits--;
21  theChiSquared -= theData.back().estimate();
22  }
23  else if(lost(* (theData.back().recHit()) )) {
24  theNumberOfLostHits--;
25  }
26  else if(isBad(* (theData.back().recHit()) ) && theData.back().recHit()->geographicalId().det()==DetId::Muon ) {
27  theChiSquaredBad -= theData.back().estimate();
28  }
29 
30  theData.pop_back();
31  }
32 }
33 
34 
36  push( tm, tm.estimate());
37 }
38 
39 void Trajectory::push( const TrajectoryMeasurement& tm, double chi2Increment)
40 {
41  theData.push_back(tm);
42  if ( tm.recHit()->isValid()) {
43  theChiSquared += chi2Increment;
44  theNumberOfFoundHits++;
45  }
46  // else if (lost( tm.recHit()) && !inactive(tm.recHit().det())) theNumberOfLostHits++;
47  else if (lost( *(tm.recHit()) ) ) {
48  theNumberOfLostHits++;
49  }
50 
51  else if (isBad( *(tm.recHit()) ) && tm.recHit()->geographicalId().det()==DetId::Muon ) {
52  theChiSquaredBad += chi2Increment;
53  }
54 
55  // in case of a Trajectory constructed without direction,
56  // determine direction from the radii of the first two measurements
57 
58  if ( !theDirectionValidity && theData.size() >= 2) {
59  if (theData[0].updatedState().globalPosition().perp() <
60  theData.back().updatedState().globalPosition().perp())
61  theDirection = alongMomentum;
62  else theDirection = oppositeToMomentum;
63  theDirectionValidity = true;
64  }
65 }
66 
68  RecHitContainer hits;
69  recHitsV(hits,splitting);
70  return hits;
71 }
72 
73 
74 int Trajectory::ndof(bool bon) const {
75  const Trajectory::RecHitContainer transRecHits = recHits();
76 
77  int dof = 0;
78  int dofBad = 0;
79 
80  for(Trajectory::RecHitContainer::const_iterator rechit = transRecHits.begin();
81  rechit != transRecHits.end(); ++rechit) {
82  if((*rechit)->isValid())
83  dof += (*rechit)->dimension();
84  else if( isBad(**rechit) && (*rechit)->geographicalId().det()==DetId::Muon )
85  dofBad += (*rechit)->dimension();
86  }
87 
88  // If dof!=0 (there is at least 1 valid hit),
89  // return ndof=ndof(fit)
90  // If dof=0 (all rec hits are invalid, only for STA trajectories),
91  // return ndof=ndof(invalid hits)
92  if(dof) {
93  int constr = bon ? 5 : 4;
94  return std::max(dof - constr, 0);
95  }
96  else {
97  // A STA can have < 5 (invalid) hits
98  // if this is the case ==> ndof = 1
99  // (to avoid divisions by 0)
100  int constr = bon ? 5 : 4;
101  return std::max(dofBad - constr, 1);
102  }
103 }
104 
105 
106 
107 void Trajectory::recHitsV(ConstRecHitContainer & hits,bool splitting) const {
108  hits.reserve(theData.size());
109  if(!splitting){
110  for (Trajectory::DataContainer::const_iterator itm
111  = theData.begin(); itm != theData.end(); itm++){
112  hits.push_back((*itm).recHit());
113  }
114  }else{
115  for (Trajectory::DataContainer::const_iterator itm
116  = theData.begin(); itm != theData.end(); itm++){
117 
118  // ====== WARNING: this is a temporary solution =========
119  // all this part of code should be implemented internally
120  // in the TrackingRecHit classes. The concrete types of rechit
121  // should be transparent to the Trajectory class
122 
123  if( typeid(*(itm->recHit()->hit())) == typeid(SiStripMatchedRecHit2D)){
124  LocalPoint firstLocalPos =
125  itm->updatedState().surface().toLocal(itm->recHit()->transientHits()[0]->globalPosition());
126 
127  LocalPoint secondLocalPos =
128  itm->updatedState().surface().toLocal(itm->recHit()->transientHits()[1]->globalPosition());
129 
130  LocalVector Delta = secondLocalPos - firstLocalPos;
131  float scalar = Delta.z() * (itm->updatedState().localDirection().z());
132 
133 
135 
136  // Get 2D strip Hits from a matched Hit.
137  //hitA = itm->recHit()->transientHits()[0];
138  //hitB = itm->recHit()->transientHits()[1];
139 
140  // Get 2D strip Hits from a matched Hit. Then get the 1D hit from the 2D hit
141  if(!itm->recHit()->transientHits()[0]->detUnit()->type().isEndcap()){
142  hitA = itm->recHit()->transientHits()[0]->transientHits()[0];
143  hitB = itm->recHit()->transientHits()[1]->transientHits()[0];
144  }else{ //don't use 1D hit in the endcap yet
145  hitA = itm->recHit()->transientHits()[0];
146  hitB = itm->recHit()->transientHits()[1];
147  }
148 
149  if( (scalar>=0 && direction()==alongMomentum) ||
150  (scalar<0 && direction()==oppositeToMomentum)){
151  hits.push_back(hitA);
152  hits.push_back(hitB);
153  }else if( (scalar>=0 && direction()== oppositeToMomentum) ||
154  (scalar<0 && direction()== alongMomentum)){
155  hits.push_back(hitB);
156  hits.push_back(hitA);
157  }else {
158  //throw cms::Exception("Error in Trajectory::recHitsV(). Direction is not defined");
159  edm::LogError("Trajectory_recHitsV_UndefinedTrackDirection")
160  << "Error in Trajectory::recHitsV: scalar = " << scalar
161  << ", direction = " << (direction()==alongMomentum ? "along " : (direction()==oppositeToMomentum ? "opposite " : "undefined "))
162  << theDirection <<"\n";
163  hits.push_back(hitA);
164  hits.push_back(hitB);
165  }
166  }else if(typeid(*(itm->recHit()->hit())) == typeid(ProjectedSiStripRecHit2D)){
167  //hits.push_back(itm->recHit()->transientHits()[0]); //Use 2D SiStripRecHit
168  if(!itm->recHit()->transientHits()[0]->detUnit()->type().isEndcap()){
169  hits.push_back(itm->recHit()->transientHits()[0]->transientHits()[0]); //Use 1D SiStripRecHit
170  }else{
171  hits.push_back(itm->recHit()->transientHits()[0]); //Use 2D SiStripRecHit
172  }
173  // ===================================================================================
174  }else if(typeid(*(itm->recHit()->hit())) == typeid(SiStripRecHit2D)){
175  //hits.push_back(itm->recHit()); //Use 2D SiStripRecHit
176  if(!itm->recHit()->detUnit()->type().isEndcap()){
177  hits.push_back(itm->recHit()->transientHits()[0]); //Use 1D SiStripRecHit
178  }else{
179  hits.push_back(itm->recHit()); //Use 2D SiStripRecHit
180  }
181  }else{
182  hits.push_back(itm->recHit());
183  }
184  }//end loop on measurements
185  }
186 }
187 
189  hits.reserve(foundHits());
190  for (Trajectory::DataContainer::const_iterator itm
191  = theData.begin(); itm != theData.end(); itm++)
192  if ((*itm).recHit()->isValid()) hits.push_back((*itm).recHit());
193 }
194 
195 
197  if (theDirectionValidity) return theDirection;
198  else throw cms::Exception("TrackingTools/PatternTools","Trajectory::direction() requested but not set");
199 }
200 
201 void Trajectory::check() const {
202  if ( theData.empty())
203  throw cms::Exception("TrackingTools/PatternTools","Trajectory::check() - information requested from empty Trajectory");
204 }
205 
207 {
208  if ( hit.isValid()) return false;
209  else {
210  // // A DetLayer is always inactive in this logic.
211  // // The DetLayer is the Det of an invalid RecHit only if no DetUnit
212  // // is compatible with the predicted state, so we don't really expect
213  // // a hit in this case.
214 
215  if(hit.geographicalId().rawId() == 0) {return false;}
216  else{
217  return hit.getType() == TrackingRecHit::missing;
218  }
219  }
220 }
221 
223 {
224  if ( hit.isValid()) return false;
225  else {
226  if(hit.geographicalId().rawId() == 0) {return false;}
227  else{
228  return hit.getType() == TrackingRecHit::bad;
229  }
230  }
231 }
232 
234 
235  check();
236 
237  //if trajectory is in one half, return the end closer to origin point
238  if ( firstMeasurement().updatedState().globalMomentum().perp() > 1.0
239  && ( firstMeasurement().updatedState().globalPosition().basicVector().dot( firstMeasurement().updatedState().globalMomentum().basicVector() ) *
240  lastMeasurement().updatedState().globalPosition().basicVector().dot( lastMeasurement().updatedState().globalMomentum().basicVector() ) > 0 ) ) {
241  return (firstMeasurement().updatedState().globalPosition().mag() < lastMeasurement().updatedState().globalPosition().mag() ) ?
242  firstMeasurement().updatedState() : lastMeasurement().updatedState();
243  }
244 
245  //more complicated in case of traversing and low-pt trajectories with loops
246  return closestMeasurement(GlobalPoint(0.0,0.0,0.0)).updatedState();
247 
248 }
249 
250 
251 namespace {
253  struct LessMag {
254  LessMag(GlobalPoint point) : thePoint(point) {}
255  bool operator()(const TrajectoryMeasurement& lhs,
256  const TrajectoryMeasurement& rhs) const{
257  if (lhs.updatedState().isValid() && rhs.updatedState().isValid())
258  return (lhs.updatedState().globalPosition() - thePoint).mag2() < (rhs.updatedState().globalPosition() -thePoint).mag2();
259  else
260  {
261  edm::LogError("InvalidStateOnMeasurement")<<"an updated state is not valid. result of LessMag comparator will be wrong.";
262  return false;
263  }
264  }
265  GlobalPoint thePoint;
266  };
267 
268 }
269 
271  check();
272  vector<TrajectoryMeasurement>::const_iterator iter = std::min_element(measurements().begin(), measurements().end(), LessMag(point) );
273 
274  return (*iter);
275 }
276 
278  // reverse the direction (without changing it if it's not along or opposite)
279  if (theDirection == alongMomentum) theDirection = oppositeToMomentum;
280  else if (theDirection == oppositeToMomentum) theDirection = alongMomentum;
281  // reverse the order of the hits
282  std::reverse(theData.begin(), theData.end());
283 }
static bool lost(const TransientTrackingRecHit &hit)
Definition: Trajectory.cc:206
ConstRecHitPointer const & recHit() const
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
GlobalPoint globalPosition() const
void check() const
Definition: Trajectory.cc:201
PropagationDirection
TrajectoryMeasurement const & closestMeasurement(GlobalPoint) const
Definition: Trajectory.cc:270
TrajectoryStateOnSurface geometricalInnermostState() const
Definition: Trajectory.cc:233
void recHitsV(ConstRecHitContainer &cont, bool splitting=false) const
Definition: Trajectory.cc:107
TransientTrackingRecHit::ConstRecHitContainer ConstRecHitContainer
Definition: Trajectory.h:43
ConstRecHitContainer recHits(bool splitting=false) const
Definition: Trajectory.cc:67
PropagationDirection const & direction() const
Definition: Trajectory.cc:196
uint32_t rawId() const
get the raw id
Definition: DetId.h:43
const T & max(const T &a, const T &b)
bool check(const DataFrame &df, bool capcheck, bool dvercheck)
T z() const
Definition: PV3DBase.h:64
T mag2() const
The vector magnitude squared. Equivalent to vec.dot(vec)
void validRecHits(ConstRecHitContainer &cont) const
Definition: Trajectory.cc:188
#define end
Definition: vmac.h:37
int ndof(bool bon=true) const
Definition: Trajectory.cc:74
static bool isBad(const TransientTrackingRecHit &hit)
Definition: Trajectory.cc:222
Type getType() const
void pop()
Definition: Trajectory.cc:17
ConstRecHitContainer RecHitContainer
Definition: Trajectory.h:44
bool isValid() const
T perp() const
Magnitude of transverse component.
#define begin
Definition: vmac.h:30
T dot(const Basic3DVector &v) const
Scalar product, or &quot;dot&quot; product, with a vector of same type.
void reverse()
Definition: Trajectory.cc:277
TrajectoryStateOnSurface const & updatedState() const
DetId geographicalId() const
void push(const TrajectoryMeasurement &tm)
Definition: Trajectory.cc:35
*vegas h *****************************************************used in the default bin number in original ***version of VEGAS is ***a higher bin number might help to derive a more precise ***grade subtle point
Definition: invegas.h:5
double scalar(const CLHEP::HepGenMatrix &m)
Return the matrix as a scalar. Raise an assertion if the matris is not .
Definition: matutil.cc:183