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 "))
00162 << theDirection <<"\n";
00163 hits.push_back(hitA);
00164 hits.push_back(hitB);
00165 }
00166 }else if(typeid(*(itm->recHit()->hit())) == typeid(ProjectedSiStripRecHit2D)){
00167
00168 if(!itm->recHit()->transientHits()[0]->detUnit()->type().isEndcap()){
00169 hits.push_back(itm->recHit()->transientHits()[0]->transientHits()[0]);
00170 }else{
00171 hits.push_back(itm->recHit()->transientHits()[0]);
00172 }
00173
00174 }else if(typeid(*(itm->recHit()->hit())) == typeid(SiStripRecHit2D)){
00175
00176 if(!itm->recHit()->detUnit()->type().isEndcap()){
00177 hits.push_back(itm->recHit()->transientHits()[0]);
00178 }else{
00179 hits.push_back(itm->recHit());
00180 }
00181 }else{
00182 hits.push_back(itm->recHit());
00183 }
00184 }
00185 }
00186 }
00187
00188 void Trajectory::validRecHits(ConstRecHitContainer & hits) const {
00189 hits.reserve(foundHits());
00190 for (Trajectory::DataContainer::const_iterator itm
00191 = theData.begin(); itm != theData.end(); itm++)
00192 if ((*itm).recHit()->isValid()) hits.push_back((*itm).recHit());
00193 }
00194
00195
00196 PropagationDirection const & Trajectory::direction() const {
00197 if (theDirectionValidity) return theDirection;
00198 else throw cms::Exception("TrackingTools/PatternTools","Trajectory::direction() requested but not set");
00199 }
00200
00201 void Trajectory::check() const {
00202 if ( theData.empty())
00203 throw cms::Exception("TrackingTools/PatternTools","Trajectory::check() - information requested from empty Trajectory");
00204 }
00205
00206 bool Trajectory::lost( const TransientTrackingRecHit& hit)
00207 {
00208 if ( hit.isValid()) return false;
00209 else {
00210
00211
00212
00213
00214
00215 if(hit.geographicalId().rawId() == 0) {return false;}
00216 else{
00217 return hit.getType() == TrackingRecHit::missing;
00218 }
00219 }
00220 }
00221
00222 bool Trajectory::isBad( const TransientTrackingRecHit& hit)
00223 {
00224 if ( hit.isValid()) return false;
00225 else {
00226 if(hit.geographicalId().rawId() == 0) {return false;}
00227 else{
00228 return hit.getType() == TrackingRecHit::bad;
00229 }
00230 }
00231 }
00232
00233 TrajectoryStateOnSurface Trajectory::geometricalInnermostState() const {
00234
00235 check();
00236
00237
00238 if ( firstMeasurement().updatedState().globalMomentum().perp() > 1.0
00239 && ( firstMeasurement().updatedState().globalPosition().basicVector().dot( firstMeasurement().updatedState().globalMomentum().basicVector() ) *
00240 lastMeasurement().updatedState().globalPosition().basicVector().dot( lastMeasurement().updatedState().globalMomentum().basicVector() ) > 0 ) ) {
00241 return (firstMeasurement().updatedState().globalPosition().mag() < lastMeasurement().updatedState().globalPosition().mag() ) ?
00242 firstMeasurement().updatedState() : lastMeasurement().updatedState();
00243 }
00244
00245
00246 return closestMeasurement(GlobalPoint(0.0,0.0,0.0)).updatedState();
00247
00248 }
00249
00250
00251 namespace {
00253 struct LessMag {
00254 LessMag(GlobalPoint point) : thePoint(point) {}
00255 bool operator()(const TrajectoryMeasurement& lhs,
00256 const TrajectoryMeasurement& rhs) const{
00257 if (lhs.updatedState().isValid() && rhs.updatedState().isValid())
00258 return (lhs.updatedState().globalPosition() - thePoint).mag2() < (rhs.updatedState().globalPosition() -thePoint).mag2();
00259 else
00260 {
00261 edm::LogError("InvalidStateOnMeasurement")<<"an updated state is not valid. result of LessMag comparator will be wrong.";
00262 return false;
00263 }
00264 }
00265 GlobalPoint thePoint;
00266 };
00267
00268 }
00269
00270 TrajectoryMeasurement const & Trajectory::closestMeasurement(GlobalPoint point) const {
00271 check();
00272 vector<TrajectoryMeasurement>::const_iterator iter = std::min_element(measurements().begin(), measurements().end(), LessMag(point) );
00273
00274 return (*iter);
00275 }
00276
00277 void Trajectory::reverse() {
00278
00279 if (theDirection == alongMomentum) theDirection = oppositeToMomentum;
00280 else if (theDirection == oppositeToMomentum) theDirection = alongMomentum;
00281
00282 std::reverse(theData.begin(), theData.end());
00283 }