ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/IPHCalignment2/TrackingTools/PatternTools/src/Trajectory.cc
Revision: 1.1
Committed: Fri Nov 25 16:38:25 2011 UTC (13 years, 5 months ago) by econte
Content type: text/plain
Branch: MAIN
CVS Tags: TBD2011, TBD_2011, HEAD
Log Message:
new IPHC alignment

File Contents

# Content
1 #include "TrackingTools/PatternTools/interface/Trajectory.h"
2 #include "boost/intrusive_ptr.hpp"
3 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
4 #include "FWCore/Utilities/interface/Exception.h"
5 #include "FWCore/MessageLogger/interface/MessageLogger.h"
6
7 #include "DataFormats/TrackerRecHit2D/interface/SiStripMatchedRecHit2D.h"
8 #include "DataFormats/TrackerRecHit2D/interface/ProjectedSiStripRecHit2D.h"
9 #include <Geometry/CommonDetUnit/interface/GeomDetUnit.h>
10 #include <Geometry/CommonDetUnit/interface/GeomDetType.h>
11
12
13 #include <algorithm>
14
15 using namespace std;
16
17 void Trajectory::pop() {
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
35 void Trajectory::push( const TrajectoryMeasurement& tm) {
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
67 Trajectory::RecHitContainer Trajectory::recHits(bool splitting) const {
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
134 TransientTrackingRecHit::ConstRecHitPointer hitA, hitB;
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")) << "\n";
162 hits.push_back(hitA);
163 hits.push_back(hitB);
164 }
165 }else if(typeid(*(itm->recHit()->hit())) == typeid(ProjectedSiStripRecHit2D)){
166 //hits.push_back(itm->recHit()->transientHits()[0]); //Use 2D SiStripRecHit
167 if(!itm->recHit()->transientHits()[0]->detUnit()->type().isEndcap()){
168 hits.push_back(itm->recHit()->transientHits()[0]->transientHits()[0]); //Use 1D SiStripRecHit
169 }else{
170 hits.push_back(itm->recHit()->transientHits()[0]); //Use 2D SiStripRecHit
171 }
172 // ===================================================================================
173 }else if(typeid(*(itm->recHit()->hit())) == typeid(SiStripRecHit2D)){
174 //hits.push_back(itm->recHit()); //Use 2D SiStripRecHit
175 if(!itm->recHit()->detUnit()->type().isEndcap()){
176 hits.push_back(itm->recHit()->transientHits()[0]); //Use 1D SiStripRecHit
177 }else{
178 hits.push_back(itm->recHit()); //Use 2D SiStripRecHit
179 }
180 }else{
181 hits.push_back(itm->recHit());
182 }
183 }//end loop on measurements
184 }
185 }
186
187 void Trajectory::validRecHits(ConstRecHitContainer & hits) const {
188 hits.reserve(foundHits());
189 for (Trajectory::DataContainer::const_iterator itm
190 = theData.begin(); itm != theData.end(); itm++)
191 if ((*itm).recHit()->isValid()) hits.push_back((*itm).recHit());
192 }
193
194
195 PropagationDirection const & Trajectory::direction() const {
196 if (theDirectionValidity) return theDirection;
197 else throw cms::Exception("TrackingTools/PatternTools","Trajectory::direction() requested but not set");
198 }
199
200 void Trajectory::check() const {
201 if ( theData.empty())
202 throw cms::Exception("TrackingTools/PatternTools","Trajectory::check() - information requested from empty Trajectory");
203 }
204
205 bool Trajectory::lost( const TransientTrackingRecHit& hit)
206 {
207 if ( hit.isValid()) return false;
208 else {
209 // // A DetLayer is always inactive in this logic.
210 // // The DetLayer is the Det of an invalid RecHit only if no DetUnit
211 // // is compatible with the predicted state, so we don't really expect
212 // // a hit in this case.
213
214 if(hit.geographicalId().rawId() == 0) {return false;}
215 else{
216 return hit.getType() == TrackingRecHit::missing;
217 }
218 }
219 }
220
221 bool Trajectory::isBad( const TransientTrackingRecHit& hit)
222 {
223 if ( hit.isValid()) return false;
224 else {
225 if(hit.geographicalId().rawId() == 0) {return false;}
226 else{
227 return hit.getType() == TrackingRecHit::bad;
228 }
229 }
230 }
231
232 TrajectoryStateOnSurface Trajectory::geometricalInnermostState() const {
233
234 check();
235
236 //if trajectory is in one half, return the end closer to origin point
237 if ( firstMeasurement().updatedState().globalMomentum().perp() > 1.0
238 && ( firstMeasurement().updatedState().globalPosition().basicVector().dot( firstMeasurement().updatedState().globalMomentum().basicVector() ) *
239 lastMeasurement().updatedState().globalPosition().basicVector().dot( lastMeasurement().updatedState().globalMomentum().basicVector() ) > 0 ) ) {
240 return (firstMeasurement().updatedState().globalPosition().mag() < lastMeasurement().updatedState().globalPosition().mag() ) ?
241 firstMeasurement().updatedState() : lastMeasurement().updatedState();
242 }
243
244 //more complicated in case of traversing and low-pt trajectories with loops
245 return closestMeasurement(GlobalPoint(0.0,0.0,0.0)).updatedState();
246
247 }
248
249
250 namespace {
251 /// used to determine closest measurement to given point
252 struct LessMag {
253 LessMag(GlobalPoint point) : thePoint(point) {}
254 bool operator()(const TrajectoryMeasurement& lhs,
255 const TrajectoryMeasurement& rhs) const{
256 if (lhs.updatedState().isValid() && rhs.updatedState().isValid())
257 return (lhs.updatedState().globalPosition() - thePoint).mag2() < (rhs.updatedState().globalPosition() -thePoint).mag2();
258 else
259 {
260 edm::LogError("InvalidStateOnMeasurement")<<"an updated state is not valid. result of LessMag comparator will be wrong.";
261 return false;
262 }
263 }
264 GlobalPoint thePoint;
265 };
266
267 }
268
269 TrajectoryMeasurement const & Trajectory::closestMeasurement(GlobalPoint point) const {
270 check();
271 vector<TrajectoryMeasurement>::const_iterator iter = std::min_element(measurements().begin(), measurements().end(), LessMag(point) );
272
273 return (*iter);
274 }
275
276 void Trajectory::reverse() {
277 // reverse the direction (without changing it if it's not along or opposite)
278 if (theDirection == alongMomentum) theDirection = oppositeToMomentum;
279 else if (theDirection == oppositeToMomentum) theDirection = alongMomentum;
280 // reverse the order of the hits
281 std::reverse(theData.begin(), theData.end());
282 }