00001 #include "TrackingTools/PatternTools/interface/Trajectory.h"
00002 #include "boost/intrusive_ptr.hpp"
00003 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
00004 #include "FWCore/Utilities/interface/Exception.h"
00005
00006 #include "DataFormats/TrackerRecHit2D/interface/SiStripMatchedRecHit2D.h"
00007 #include "DataFormats/TrackerRecHit2D/interface/ProjectedSiStripRecHit2D.h"
00008
00009
00010 using namespace std;
00011
00012 void Trajectory::pop() {
00013 if (!empty()) {
00014 if (theData.back().recHit()->isValid()) theNumberOfFoundHits--;
00015 else if(lost(* (theData.back().recHit()) )) theNumberOfLostHits--;
00016 theData.pop_back();
00017 }
00018 }
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 void Trajectory::push( const TrajectoryMeasurement& tm) {
00050 push( tm, tm.estimate());
00051 }
00052
00053 void Trajectory::push( const TrajectoryMeasurement& tm, double chi2Increment)
00054 {
00055 theData.push_back(tm);
00056 if ( tm.recHit()->isValid()) {
00057 theNumberOfFoundHits++;
00058 }
00059
00060 else if (lost( *(tm.recHit()) ) ) theNumberOfLostHits++;
00061
00062
00063 theChiSquared += chi2Increment;
00064
00065
00066
00067
00068 if ( !theDirectionValidity && theData.size() >= 2) {
00069 if (theData[0].updatedState().globalPosition().perp() <
00070 theData.back().updatedState().globalPosition().perp())
00071 theDirection = alongMomentum;
00072 else theDirection = oppositeToMomentum;
00073 theDirectionValidity = true;
00074 }
00075 }
00076
00077 Trajectory::RecHitContainer Trajectory::recHits(bool splitting) const {
00078 RecHitContainer hits;
00079 recHitsV(hits,splitting);
00080 return hits;
00081 }
00082
00083
00084 int Trajectory::ndof(bool bon) const {
00085 const Trajectory::RecHitContainer transRecHits = recHits();
00086
00087 int dof = 0;
00088
00089 for(Trajectory::RecHitContainer::const_iterator rechit = transRecHits.begin();
00090 rechit != transRecHits.end(); ++rechit)
00091 if ((*rechit)->isValid()) dof += (*rechit)->dimension();
00092
00093 int constr = bon ? 5 : 4;
00094 return std::max(dof - constr, 0);
00095 }
00096
00097
00098
00099 void Trajectory::recHitsV(ConstRecHitContainer & hits,bool splitting) const {
00100 hits.reserve(theData.size());
00101 if(!splitting){
00102 for (Trajectory::DataContainer::const_iterator itm
00103 = theData.begin(); itm != theData.end(); itm++){
00104 hits.push_back((*itm).recHit());
00105 }
00106 }else{
00107 for (Trajectory::DataContainer::const_iterator itm
00108 = theData.begin(); itm != theData.end(); itm++){
00109
00110
00111
00112
00113
00114
00115 if( typeid(*(itm->recHit()->hit())) == typeid(SiStripMatchedRecHit2D)){
00116 LocalPoint firstLocalPos =
00117 itm->updatedState().surface().toLocal(itm->recHit()->transientHits()[0]->globalPosition());
00118
00119 LocalPoint secondLocalPos =
00120 itm->updatedState().surface().toLocal(itm->recHit()->transientHits()[1]->globalPosition());
00121
00122 LocalVector Delta = secondLocalPos - firstLocalPos;
00123 float scalar = Delta.z() * (itm->updatedState().localDirection().z());
00124
00125 if( (scalar>0 && direction()==alongMomentum) ||
00126 (scalar<0 && direction()==oppositeToMomentum)){
00127 hits.push_back(itm->recHit()->transientHits()[0]);
00128 hits.push_back(itm->recHit()->transientHits()[1]);
00129 }else if( (scalar>0 && direction()== oppositeToMomentum) ||
00130 (scalar<0 && direction()== alongMomentum)){
00131 hits.push_back(itm->recHit()->transientHits()[1]);
00132 hits.push_back(itm->recHit()->transientHits()[0]);
00133 }else
00134 throw cms::Exception("Error in Trajectory::recHitsV(). Direction is not defined");
00135 }else if(typeid(*(itm->recHit()->hit())) == typeid(ProjectedSiStripRecHit2D)){
00136 hits.push_back(itm->recHit()->transientHits()[0]);
00137
00138 }else{
00139 hits.push_back(itm->recHit());
00140 }
00141 }
00142 }
00143 }
00144
00145 void Trajectory::validRecHits(ConstRecHitContainer & hits) const {
00146 hits.reserve(foundHits());
00147 for (Trajectory::DataContainer::const_iterator itm
00148 = theData.begin(); itm != theData.end(); itm++)
00149 if ((*itm).recHit()->isValid()) hits.push_back((*itm).recHit());
00150 }
00151
00152
00153 PropagationDirection const & Trajectory::direction() const {
00154 if (theDirectionValidity) return theDirection;
00155 else throw cms::Exception("TrackingTools/PatternTools","Trajectory::direction() requested but not set");
00156 }
00157
00158 void Trajectory::check() const {
00159 if ( theData.empty())
00160 throw cms::Exception("TrackingTools/PatternTools","Trajectory::check() - information requested from empty Trajectory");
00161 }
00162
00163 bool Trajectory::lost( const TransientTrackingRecHit& hit)
00164 {
00165 if ( hit.isValid()) return false;
00166 else {
00167
00168
00169
00170
00171
00172 if(hit.geographicalId().rawId() == 0) {return false;}
00173 else{
00174 return hit.getType() == TrackingRecHit::missing;
00175 }
00176 }
00177 }
00178
00179 TrajectoryStateOnSurface Trajectory::geometricalInnermostState() const {
00180
00181 check();
00182
00183
00184 if ( firstMeasurement().updatedState().globalMomentum().perp() > 1.0
00185 && ( firstMeasurement().updatedState().globalPosition().basicVector().dot( firstMeasurement().updatedState().globalMomentum().basicVector() ) *
00186 lastMeasurement().updatedState().globalPosition().basicVector().dot( lastMeasurement().updatedState().globalMomentum().basicVector() ) > 0 ) ) {
00187 return (firstMeasurement().updatedState().globalPosition().mag() < lastMeasurement().updatedState().globalPosition().mag() ) ?
00188 firstMeasurement().updatedState() : lastMeasurement().updatedState();
00189 }
00190
00191
00192 return closestMeasurement(GlobalPoint(0.0,0.0,0.0)).updatedState();
00193
00194 }
00195
00196 TrajectoryMeasurement const & Trajectory::closestMeasurement(GlobalPoint point) const {
00197 check();
00198 vector<TrajectoryMeasurement>::const_iterator iter = std::min_element(measurements().begin(), measurements().end(), LessMag(point) );
00199
00200 return (*iter);
00201 }