Go to the documentation of this file.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 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00006
00007 #include "DataFormats/TrackerRecHit2D/interface/SiStripMatchedRecHit2D.h"
00008 #include "DataFormats/TrackerRecHit2D/interface/ProjectedSiStripRecHit2D.h"
00009 #include <Geometry/CommonDetUnit/interface/GeomDetUnit.h>
00010 #include <Geometry/CommonDetUnit/interface/GeomDetType.h>
00011
00012
00013 #include <algorithm>
00014
00015 using namespace std;
00016
00017 void Trajectory::pop() {
00018 if (!empty()) {
00019 if(theData.back().recHit()->isValid()) {
00020 theNumberOfFoundHits--;
00021 theChiSquared -= theData.back().estimate();
00022 }
00023 else if(lost(* (theData.back().recHit()) )) {
00024 theNumberOfLostHits--;
00025 }
00026 else if(isBad(* (theData.back().recHit()) ) && theData.back().recHit()->geographicalId().det()==DetId::Muon ) {
00027 theChiSquaredBad -= theData.back().estimate();
00028 }
00029
00030 theData.pop_back();
00031 }
00032 }
00033
00034
00035 void Trajectory::push( const TrajectoryMeasurement& tm) {
00036 push( tm, tm.estimate());
00037 }
00038
00039 void Trajectory::push( const TrajectoryMeasurement& tm, double chi2Increment)
00040 {
00041 theData.push_back(tm);
00042 if ( tm.recHit()->isValid()) {
00043 theChiSquared += chi2Increment;
00044 theNumberOfFoundHits++;
00045 }
00046
00047 else if (lost( *(tm.recHit()) ) ) {
00048 theNumberOfLostHits++;
00049 }
00050
00051 else if (isBad( *(tm.recHit()) ) && tm.recHit()->geographicalId().det()==DetId::Muon ) {
00052 theChiSquaredBad += chi2Increment;
00053 }
00054
00055
00056
00057
00058 if ( !theDirectionValidity && theData.size() >= 2) {
00059 if (theData[0].updatedState().globalPosition().perp() <
00060 theData.back().updatedState().globalPosition().perp())
00061 theDirection = alongMomentum;
00062 else theDirection = oppositeToMomentum;
00063 theDirectionValidity = true;
00064 }
00065 }
00066
00067 Trajectory::RecHitContainer Trajectory::recHits(bool splitting) const {
00068 RecHitContainer hits;
00069 recHitsV(hits,splitting);
00070 return hits;
00071 }
00072
00073
00074 int Trajectory::ndof(bool bon) const {
00075 const Trajectory::RecHitContainer transRecHits = recHits();
00076
00077 int dof = 0;
00078 int dofBad = 0;
00079
00080 for(Trajectory::RecHitContainer::const_iterator rechit = transRecHits.begin();
00081 rechit != transRecHits.end(); ++rechit) {
00082 if((*rechit)->isValid())
00083 dof += (*rechit)->dimension();
00084 else if( isBad(**rechit) && (*rechit)->geographicalId().det()==DetId::Muon )
00085 dofBad += (*rechit)->dimension();
00086 }
00087
00088
00089
00090
00091
00092 if(dof) {
00093 int constr = bon ? 5 : 4;
00094 return std::max(dof - constr, 0);
00095 }
00096 else {
00097
00098
00099
00100 int constr = bon ? 5 : 4;
00101 return std::max(dofBad - constr, 1);
00102 }
00103 }
00104
00105
00106
00107 void Trajectory::recHitsV(ConstRecHitContainer & hits,bool splitting) const {
00108 hits.reserve(theData.size());
00109 if(!splitting){
00110 for (Trajectory::DataContainer::const_iterator itm
00111 = theData.begin(); itm != theData.end(); itm++){
00112 hits.push_back((*itm).recHit());
00113 }
00114 }else{
00115 for (Trajectory::DataContainer::const_iterator itm
00116 = theData.begin(); itm != theData.end(); itm++){
00117
00118
00119
00120
00121
00122
00123 if( typeid(*(itm->recHit()->hit())) == typeid(SiStripMatchedRecHit2D)){
00124 LocalPoint firstLocalPos =
00125 itm->updatedState().surface().toLocal(itm->recHit()->transientHits()[0]->globalPosition());
00126
00127 LocalPoint secondLocalPos =
00128 itm->updatedState().surface().toLocal(itm->recHit()->transientHits()[1]->globalPosition());
00129
00130 LocalVector Delta = secondLocalPos - firstLocalPos;
00131 float scalar = Delta.z() * (itm->updatedState().localDirection().z());
00132
00133
00134 TransientTrackingRecHit::ConstRecHitPointer hitA, hitB;
00135
00136
00137
00138
00139
00140
00141 if(!itm->recHit()->transientHits()[0]->detUnit()->type().isEndcap()){
00142 hitA = itm->recHit()->transientHits()[0]->transientHits()[0];
00143 hitB = itm->recHit()->transientHits()[1]->transientHits()[0];
00144 }else{
00145 hitA = itm->recHit()->transientHits()[0];
00146 hitB = itm->recHit()->transientHits()[1];
00147 }
00148
00149 if( (scalar>=0 && direction()==alongMomentum) ||
00150 (scalar<0 && direction()==oppositeToMomentum)){
00151 hits.push_back(hitA);
00152 hits.push_back(hitB);
00153 }else if( (scalar>=0 && direction()== oppositeToMomentum) ||
00154 (scalar<0 && direction()== alongMomentum)){
00155 hits.push_back(hitB);
00156 hits.push_back(hitA);
00157 }else {
00158
00159 edm::LogError("Trajectory_recHitsV_UndefinedTrackDirection") <<
00160 "Error in Trajectory::recHitsV: scalar = " << scalar <<
00161 ", direction = " << (direction()==alongMomentum ? "along" : (direction()==oppositeToMomentum ? "opposite" : "undefined")) << "\n";
00162 hits.push_back(hitA);
00163 hits.push_back(hitB);
00164 }
00165 }else if(typeid(*(itm->recHit()->hit())) == typeid(ProjectedSiStripRecHit2D)){
00166
00167 if(!itm->recHit()->transientHits()[0]->detUnit()->type().isEndcap()){
00168 hits.push_back(itm->recHit()->transientHits()[0]->transientHits()[0]);
00169 }else{
00170 hits.push_back(itm->recHit()->transientHits()[0]);
00171 }
00172
00173 }else if(typeid(*(itm->recHit()->hit())) == typeid(SiStripRecHit2D)){
00174
00175 if(!itm->recHit()->detUnit()->type().isEndcap()){
00176 hits.push_back(itm->recHit()->transientHits()[0]);
00177 }else{
00178 hits.push_back(itm->recHit());
00179 }
00180 }else{
00181 hits.push_back(itm->recHit());
00182 }
00183 }
00184 }
00185 }
00186
00187 void Trajectory::validRecHits(ConstRecHitContainer & hits) const {
00188 hits.reserve(foundHits());
00189 for (Trajectory::DataContainer::const_iterator itm
00190 = theData.begin(); itm != theData.end(); itm++)
00191 if ((*itm).recHit()->isValid()) hits.push_back((*itm).recHit());
00192 }
00193
00194
00195 PropagationDirection const & Trajectory::direction() const {
00196 if (theDirectionValidity) return theDirection;
00197 else throw cms::Exception("TrackingTools/PatternTools","Trajectory::direction() requested but not set");
00198 }
00199
00200 void Trajectory::check() const {
00201 if ( theData.empty())
00202 throw cms::Exception("TrackingTools/PatternTools","Trajectory::check() - information requested from empty Trajectory");
00203 }
00204
00205 bool Trajectory::lost( const TransientTrackingRecHit& hit)
00206 {
00207 if ( hit.isValid()) return false;
00208 else {
00209
00210
00211
00212
00213
00214 if(hit.geographicalId().rawId() == 0) {return false;}
00215 else{
00216 return hit.getType() == TrackingRecHit::missing;
00217 }
00218 }
00219 }
00220
00221 bool Trajectory::isBad( const TransientTrackingRecHit& hit)
00222 {
00223 if ( hit.isValid()) return false;
00224 else {
00225 if(hit.geographicalId().rawId() == 0) {return false;}
00226 else{
00227 return hit.getType() == TrackingRecHit::bad;
00228 }
00229 }
00230 }
00231
00232 TrajectoryStateOnSurface Trajectory::geometricalInnermostState() const {
00233
00234 check();
00235
00236
00237 if ( firstMeasurement().updatedState().globalMomentum().perp() > 1.0
00238 && ( firstMeasurement().updatedState().globalPosition().basicVector().dot( firstMeasurement().updatedState().globalMomentum().basicVector() ) *
00239 lastMeasurement().updatedState().globalPosition().basicVector().dot( lastMeasurement().updatedState().globalMomentum().basicVector() ) > 0 ) ) {
00240 return (firstMeasurement().updatedState().globalPosition().mag() < lastMeasurement().updatedState().globalPosition().mag() ) ?
00241 firstMeasurement().updatedState() : lastMeasurement().updatedState();
00242 }
00243
00244
00245 return closestMeasurement(GlobalPoint(0.0,0.0,0.0)).updatedState();
00246
00247 }
00248
00249
00250 namespace {
00252 struct LessMag {
00253 LessMag(GlobalPoint point) : thePoint(point) {}
00254 bool operator()(const TrajectoryMeasurement& lhs,
00255 const TrajectoryMeasurement& rhs) const{
00256 if (lhs.updatedState().isValid() && rhs.updatedState().isValid())
00257 return (lhs.updatedState().globalPosition() - thePoint).mag2() < (rhs.updatedState().globalPosition() -thePoint).mag2();
00258 else
00259 {
00260 edm::LogError("InvalidStateOnMeasurement")<<"an updated state is not valid. result of LessMag comparator will be wrong.";
00261 return false;
00262 }
00263 }
00264 GlobalPoint thePoint;
00265 };
00266
00267 }
00268
00269 TrajectoryMeasurement const & Trajectory::closestMeasurement(GlobalPoint point) const {
00270 check();
00271 vector<TrajectoryMeasurement>::const_iterator iter = std::min_element(measurements().begin(), measurements().end(), LessMag(point) );
00272
00273 return (*iter);
00274 }
00275
00276 void Trajectory::reverse() {
00277
00278 if (theDirection == alongMomentum) theDirection = oppositeToMomentum;
00279 else if (theDirection == oppositeToMomentum) theDirection = alongMomentum;
00280
00281 std::reverse(theData.begin(), theData.end());
00282 }