00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "TrackingTools/TrackAssociator/interface/CachedTrajectory.h"
00011
00012 #include "TrackPropagation/SteppingHelixPropagator/interface/SteppingHelixPropagator.h"
00013 #include "DataFormats/GeometrySurface/interface/Plane.h"
00014 #include "Geometry/DTGeometry/interface/DTChamber.h"
00015 #include "Geometry/CSCGeometry/interface/CSCChamber.h"
00016 #include <deque>
00017 #include <algorithm>
00018
00019 CachedTrajectory::CachedTrajectory():propagator_(0){
00020 reset_trajectory();
00021 setMaxDetectorRadius();
00022 setMaxDetectorLength();
00023 setMinDetectorRadius();
00024 setMinDetectorLength();
00025 setPropagationStep();
00026 }
00027
00028 void CachedTrajectory::propagateForward(SteppingHelixStateInfo& state, float distance)
00029 {
00030
00031
00032 GlobalVector vector(state.momentum().unit());
00033 float r21 = 0;
00034 float r22 = vector.z()/sqrt(1-pow(vector.x(),2));
00035 float r23 = -vector.y()/sqrt(1-pow(vector.x(),2));
00036 float r31 = vector.x();
00037 float r32 = vector.y();
00038 float r33 = vector.z();
00039 float r11 = r22*r33-r23*r32;
00040 float r12 = r23*r31;
00041 float r13 = -r22*r31;
00042
00043 Surface::RotationType rotation(r11, r12, r13,
00044 r21, r22, r23,
00045 r31, r32, r33);
00046 Surface* target = new Plane(state.position()+vector*distance, rotation);
00047 if( const SteppingHelixPropagator* shp = dynamic_cast<const SteppingHelixPropagator*>(propagator_) )
00048 {
00049 try {
00050 state = shp->propagate(state, *target);
00051 }
00052 catch(cms::Exception &ex){
00053 edm::LogWarning("TrackAssociator") <<
00054 "Caught exception " << ex.category() << ": " << ex.explainSelf();
00055 edm::LogWarning("TrackAssociator") << "An exception is caught during the track propagation\n"
00056 << state.momentum().x() << ", " << state.momentum().y() << ", " << state.momentum().z();
00057 state = SteppingHelixStateInfo();
00058 }
00059 }
00060 else
00061 {
00062 FreeTrajectoryState fts;
00063 state.getFreeState( fts );
00064 TrajectoryStateOnSurface stateOnSurface = propagator_->propagate(fts, *target);
00065 state = SteppingHelixStateInfo( *(stateOnSurface.freeState()) );
00066 }
00067 delete target;
00068
00069
00070
00071 }
00072
00073
00074 bool CachedTrajectory::propagateAll(const SteppingHelixStateInfo& initialState)
00075 {
00076 if ( fullTrajectoryFilled_ ) {
00077 edm::LogWarning("TrackAssociator") << "Reseting all trajectories. Please call reset_trajectory() explicitely to avoid this message";
00078 reset_trajectory();
00079 }
00080
00081
00082
00083 reset_trajectory();
00084 if (propagator_==0) throw cms::Exception("FatalError") << "Track propagator is not defined\n";
00085 SteppingHelixStateInfo currentState(initialState);
00086
00087 while (currentState.position().perp()<maxRho_ && fabs(currentState.position().z())<maxZ_ ){
00088 LogTrace("TrackAssociator") << "[propagateAll] Propagate outward from (rho, r, z, phi) (" <<
00089 currentState.position().perp() << ", " << currentState.position().mag() << ", " <<
00090 currentState.position().z() << ", " << currentState.position().phi() << ")";
00091 propagateForward(currentState,step_);
00092 if (! currentState.isValid() ) {
00093 LogTrace("TrackAssociator") << "Failed to propagate the track; moving on\n";
00094 break;
00095 }
00096 LogTrace("TrackAssociator") << "\treached (rho, r, z, phi) (" <<
00097 currentState.position().perp() << ", " << currentState.position().mag() << ", " <<
00098 currentState.position().z() << ", " << currentState.position().phi() << ")";
00099 fullTrajectory_.push_back(currentState);
00100 }
00101
00102
00103 SteppingHelixStateInfo currentState2(initialState);
00104 SteppingHelixStateInfo previousState;
00105 while (currentState2.position().perp()>minRho_ || fabs(currentState2.position().z())>minZ_) {
00106 previousState=currentState2;
00107 propagateForward(currentState2,-step_);
00108 if (! currentState2.isValid() ) {
00109 LogTrace("TrackAssociator") << "Failed to propagate the track; moving on\n";
00110 break;
00111 }
00112 if(previousState.position().perp()- currentState2.position().perp() < 0) {
00113 LogTrace("TrackAssociator") << "Error: TrackAssociator has propogated the particle past the point of closest approach to IP" << std::endl;
00114 break;
00115 }
00116 LogTrace("TrackAssociator") << "[propagateAll] Propagated inward from (rho, r, z, phi) (" <<
00117 previousState.position().perp() << ", " << previousState.position().mag() << ", " <<
00118 previousState.position().z() << "," << previousState.position().phi() << ") to (" <<
00119 currentState2.position().perp() << ", " << currentState2.position().mag() << ", " <<
00120 currentState2.position().z() << ", " << currentState2.position().phi() << ")";
00121 fullTrajectory_.push_front(currentState2);
00122 }
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 LogTrace("TrackAssociator") << "Done with the track propagation in the detector. Number of steps: " << fullTrajectory_.size();
00138 fullTrajectoryFilled_ = true;
00139 return ! fullTrajectory_.empty();
00140 }
00141
00142 TrajectoryStateOnSurface CachedTrajectory::propagate(const Plane* plane)
00143 {
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 const float matchingDistance = 1;
00155
00156 int leftIndex = 0;
00157 int rightIndex = fullTrajectory_.size()-1;
00158 int closestPointOnLeft = 0;
00159
00160
00161 if ( sign( distance(plane, leftIndex) ) * sign( distance(plane, rightIndex) ) != -1 ) {
00162 LogTrace("TrackAssociator") << "Track didn't cross the plane:\n\tleft distance: "<<distance(plane, leftIndex)
00163 <<"\n\tright distance: " << distance(plane, rightIndex);
00164 return TrajectoryStateOnSurface();
00165 }
00166
00167 while (leftIndex + 1 < rightIndex) {
00168 closestPointOnLeft = int((leftIndex+rightIndex)/2);
00169 float dist = distance(plane,closestPointOnLeft);
00170
00171
00172 if (fabs(dist)<matchingDistance) {
00173
00174 if (closestPointOnLeft>0 && sign( distance(plane, closestPointOnLeft-1) ) * dist == -1)
00175 closestPointOnLeft--;
00176 break;
00177 }
00178
00179
00180 if (sign( distance(plane, leftIndex) * dist ) == -1)
00181 rightIndex = closestPointOnLeft;
00182 else
00183 leftIndex = closestPointOnLeft;
00184
00185
00186
00187
00188
00189
00190 }
00191 LogTrace("TrackAssociator") << "closestPointOnLeft: " << closestPointOnLeft
00192 << "\n\ttrajectory point (z,R,eta,phi): "
00193 << fullTrajectory_[closestPointOnLeft].position().z() << ", "
00194 << fullTrajectory_[closestPointOnLeft].position().perp() << " , "
00195 << fullTrajectory_[closestPointOnLeft].position().eta() << " , "
00196 << fullTrajectory_[closestPointOnLeft].position().phi()
00197 << "\n\tplane center (z,R,eta,phi): "
00198 << plane->position().z() << ", "
00199 << plane->position().perp() << " , "
00200 << plane->position().eta() << " , "
00201 << plane->position().phi();
00202
00203
00204
00205 if (const SteppingHelixPropagator* shp = dynamic_cast<const SteppingHelixPropagator*>(propagator_))
00206 {
00207 SteppingHelixStateInfo state;
00208 try {
00209 state = shp->propagate(fullTrajectory_[closestPointOnLeft], *plane);
00210 }
00211 catch(cms::Exception &ex){
00212 edm::LogWarning("TrackAssociator") <<
00213 "Caught exception " << ex.category() << ": " << ex.explainSelf();
00214 edm::LogWarning("TrackAssociator") << "An exception is caught during the track propagation\n"
00215 << state.momentum().x() << ", " << state.momentum().y() << ", " << state.momentum().z();
00216 return TrajectoryStateOnSurface();
00217 }
00218 return state.getStateOnSurface(*plane);
00219 }
00220 else
00221 {
00222 FreeTrajectoryState fts;
00223 fullTrajectory_[closestPointOnLeft].getFreeState(fts);
00224 return propagator_->propagate(fts, *plane);
00225 }
00226 }
00227
00228 std::pair<float,float> CachedTrajectory::trajectoryDelta( TrajectorType trajectoryType )
00229 {
00230
00231
00232
00233
00234
00235
00236
00237 std::pair<float,float> result(0,0);
00238 if ( ! stateAtIP_.isValid() ) {
00239 edm::LogWarning("TrackAssociator") << "State at IP is not known set. Cannot estimate trajectory change. " <<
00240 "Trajectory change is not taken into account in matching";
00241 return result;
00242 }
00243 switch (trajectoryType) {
00244 case IpToEcal:
00245 if ( ecalTrajectory_.empty() )
00246 edm::LogWarning("TrackAssociator") << "ECAL trajector is empty. Cannot estimate trajectory change. " <<
00247 "Trajectory change is not taken into account in matching";
00248 else return delta( stateAtIP_.momentum().theta(), ecalTrajectory_.front().position().theta(),
00249 stateAtIP_.momentum().phi(), ecalTrajectory_.front().position().phi() );
00250 break;
00251 case IpToHcal:
00252 if ( hcalTrajectory_.empty() )
00253 edm::LogWarning("TrackAssociator") << "HCAL trajector is empty. Cannot estimate trajectory change. " <<
00254 "Trajectory change is not taken into account in matching";
00255 else return delta( stateAtIP_.momentum().theta(), hcalTrajectory_.front().position().theta(),
00256 stateAtIP_.momentum().phi(), hcalTrajectory_.front().position().phi() );
00257 break;
00258 case IpToHO:
00259 if ( hoTrajectory_.empty() )
00260 edm::LogWarning("TrackAssociator") << "HO trajector is empty. Cannot estimate trajectory change. " <<
00261 "Trajectory change is not taken into account in matching";
00262 else return delta( stateAtIP_.momentum().theta(), hoTrajectory_.front().position().theta(),
00263 stateAtIP_.momentum().phi(), hoTrajectory_.front().position().phi() );
00264 break;
00265 case FullTrajectory:
00266 if ( fullTrajectory_.empty() )
00267 edm::LogWarning("TrackAssociator") << "Full trajector is empty. Cannot estimate trajectory change. " <<
00268 "Trajectory change is not taken into account in matching";
00269 else return delta( stateAtIP_.momentum().theta(), fullTrajectory_.back().position().theta(),
00270 stateAtIP_.momentum().phi(), fullTrajectory_.back().position().phi() );
00271 break;
00272 default:
00273 edm::LogWarning("TrackAssociator") << "Unkown or not supported trajector type. Cannot estimate trajectory change. " <<
00274 "Trajectory change is not taken into account in matching";
00275 }
00276 return result;
00277 }
00278
00279 std::pair<float,float> CachedTrajectory::delta(const double& theta1,
00280 const double& theta2,
00281 const double& phi1,
00282 const double& phi2)
00283 {
00284 std::pair<float,float> result(theta2 - theta1, phi2 - phi1 );
00285
00286 if ( fabs(result.second) > 2*M_PI-fabs(result.second) ) {
00287 if (result.second>0)
00288 result.second -= 2*M_PI;
00289 else
00290 result.second += 2*M_PI;
00291 }
00292 return result;
00293 }
00294
00295 void CachedTrajectory::getTrajectory(std::vector<SteppingHelixStateInfo>& trajectory,
00296 const FiducialVolume& volume,
00297 int steps)
00298 {
00299 if ( ! fullTrajectoryFilled_ ) throw cms::Exception("FatalError") << "trajectory is not defined yet. Please use propagateAll first.";
00300 if ( fullTrajectory_.empty() ) {
00301 LogTrace("TrackAssociator") << "Trajectory is empty. Move on";
00302 return;
00303 }
00304 if ( ! volume.isValid() ) {
00305 LogTrace("TrackAssociator") << "no trajectory is expected to be found since the fiducial volume is not valid";
00306 return;
00307 }
00308 double step = std::max(volume.maxR()-volume.minR(),volume.maxZ()-volume.minZ())/steps;
00309
00310 int closestPointOnLeft = -1;
00311
00312
00313 if ( !
00314 ( ( fullTrajectory_.front().position().perp() < volume.maxR() && fabs(fullTrajectory_.front().position().z()) < volume.maxZ() ) &&
00315 ( fullTrajectory_.back().position().perp() > volume.minR() || fabs(fullTrajectory_.back().position().z()) > volume.minZ() ) ))
00316 {
00317 LogTrace("TrackAssociator") << "Track didn't cross the region (R1,R2,L1,L2): " << volume.minR() << ", " << volume.maxR() <<
00318 ", " << volume.minZ() << ", " << volume.maxZ();
00319 return;
00320 }
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330 for(uint i=0; i<fullTrajectory_.size(); i++) {
00331
00332
00333
00334 if ( fullTrajectory_[i].position().perp()-volume.minR() > 0 || fabs(fullTrajectory_[i].position().z()) - volume.minZ() >0 )
00335 {
00336 if (i>0)
00337 closestPointOnLeft = i - 1;
00338 else
00339 closestPointOnLeft = 0;
00340 break;
00341 }
00342 }
00343 if (closestPointOnLeft == -1) throw cms::Exception("FatalError") << "This shouls never happen - internal logic error";
00344
00345 SteppingHelixStateInfo currentState(fullTrajectory_[closestPointOnLeft]);
00346 if ( currentState.position().x()*currentState.momentum().x() +
00347 currentState.position().y()*currentState.momentum().y() +
00348 currentState.position().z()*currentState.momentum().z() < 0 )
00349 step = -step;
00350
00351 while (currentState.position().perp() < volume.maxR() && fabs(currentState.position().z()) < volume.maxZ() )
00352 {
00353 propagateForward(currentState,step);
00354 if (! currentState.isValid() ) {
00355 LogTrace("TrackAssociator") << "Failed to propagate the track; moving on\n";
00356 break;
00357 }
00358
00359 if ( ( currentState.position().perp() < volume.maxR() && fabs(currentState.position().z()) < volume.maxZ() ) &&
00360 ( currentState.position().perp()-volume.minR() > 0 || fabs(currentState.position().z()) - volume.minZ() >0 ) )
00361 trajectory.push_back(currentState);
00362 }
00363 }
00364
00365 void CachedTrajectory::reset_trajectory() {
00366 fullTrajectory_.clear();
00367 ecalTrajectory_.clear();
00368 hcalTrajectory_.clear();
00369 hoTrajectory_.clear();
00370 wideEcalTrajectory_.clear();
00371 wideHcalTrajectory_.clear();
00372 wideHOTrajectory_.clear();
00373 fullTrajectoryFilled_ = false;
00374 }
00375
00376 void CachedTrajectory::findEcalTrajectory( const FiducialVolume& volume ) {
00377 LogTrace("TrackAssociator") << "getting trajectory in ECAL";
00378 getTrajectory(ecalTrajectory_, volume, 4 );
00379 LogTrace("TrackAssociator") << "# of points in ECAL trajectory:" << ecalTrajectory_.size();
00380 }
00381
00382 const std::vector<SteppingHelixStateInfo>& CachedTrajectory::getEcalTrajectory() {
00383 return ecalTrajectory_;
00384 }
00385
00386 void CachedTrajectory::findHcalTrajectory( const FiducialVolume& volume ) {
00387 LogTrace("TrackAssociator") << "getting trajectory in HCAL";
00388 getTrajectory(hcalTrajectory_, volume, 20 );
00389 LogTrace("TrackAssociator") << "# of points in HCAL trajectory:" << hcalTrajectory_.size();
00390 }
00391
00392 const std::vector<SteppingHelixStateInfo>& CachedTrajectory::getHcalTrajectory() {
00393 return hcalTrajectory_;
00394 }
00395
00396 void CachedTrajectory::findHOTrajectory( const FiducialVolume& volume ) {
00397 LogTrace("TrackAssociator") << "getting trajectory in HO";
00398 getTrajectory(hoTrajectory_, volume, 2 );
00399 LogTrace("TrackAssociator") << "# of points in HO trajectory:" << hoTrajectory_.size();
00400 }
00401
00402 const std::vector<SteppingHelixStateInfo>& CachedTrajectory::getHOTrajectory() {
00403 return hoTrajectory_;
00404 }
00405
00406 std::vector<GlobalPoint>*
00407 CachedTrajectory::getWideTrajectory(const std::vector<SteppingHelixStateInfo>& states,
00408 WideTrajectoryType wideTrajectoryType) {
00409 std::vector<GlobalPoint>* wideTrajectory = 0;
00410 switch (wideTrajectoryType) {
00411 case Ecal:
00412 LogTrace("TrackAssociator") << "Filling ellipses in Ecal trajectory";
00413 wideTrajectory = &wideEcalTrajectory_;
00414 break;
00415 case Hcal:
00416 LogTrace("TrackAssociator") << "Filling ellipses in Hcal trajectory";
00417 wideTrajectory = &wideHcalTrajectory_;
00418 break;
00419 case HO:
00420 LogTrace("TrackAssociator") << "Filling ellipses in HO trajectory";
00421 wideTrajectory = &wideHOTrajectory_;
00422 break;
00423 }
00424 if(!wideTrajectory) return 0;
00425
00426 for(std::vector<SteppingHelixStateInfo>::const_iterator state= states.begin();
00427 state != states.end(); state++) {
00428
00429
00430 GlobalVector vector(state->momentum().unit());
00431 float r21 = 0;
00432 float r22 = vector.z()/sqrt(1-pow(vector.x(),2));
00433 float r23 = -vector.y()/sqrt(1-pow(vector.x(),2));
00434 float r31 = vector.x();
00435 float r32 = vector.y();
00436 float r33 = vector.z();
00437 float r11 = r22*r33-r23*r32;
00438 float r12 = r23*r31;
00439 float r13 = -r22*r31;
00440
00441 Plane::RotationType rotation(r11, r12, r13,
00442 r21, r22, r23,
00443 r31, r32, r33);
00444 Plane* target = new Plane(state->position(), rotation);
00445
00446 TrajectoryStateOnSurface tsos = state->getStateOnSurface(*target);
00447
00448 if (!tsos.isValid()) {
00449 LogTrace("TrackAssociator") << "[getWideTrajectory] TSOS not valid";
00450 continue;
00451 }
00452 if (!tsos.hasError()) {
00453 LogTrace("TrackAssociator") << "[getWideTrajectory] TSOS does not have Errors";
00454 continue;
00455 }
00456 LocalError localErr = tsos.localError().positionError();
00457 localErr.scale(2);
00458 float xx = localErr.xx();
00459 float xy = localErr.xy();
00460 float yy = localErr.yy();
00461
00462 float denom = yy - xx;
00463 float phi = 0., phi_temp=0.;
00464 if(xy == 0 && denom==0) phi = M_PI_4;
00465 else phi = 0.5 * atan2(2.*xy,denom);
00466 phi_temp = phi;
00467
00468
00469 LocalError rotErr = localErr.rotate(-phi);
00470 float semi1 = sqrt(rotErr.xx());
00471 float semi2 = sqrt(rotErr.yy());
00472
00473
00474
00475
00476
00477
00478
00479
00480 Local2DPoint bounds[4];
00481 bounds[0] = Local2DPoint(semi1*cos(phi), semi1*sin(phi));
00482 bounds[1] = Local2DPoint(semi1*cos(phi+M_PI), semi1*sin(phi+M_PI));
00483 phi += M_PI_2;
00484 bounds[2] = Local2DPoint(semi2*cos(phi), semi2*sin(phi));
00485 bounds[3] = Local2DPoint(semi2*cos(phi+M_PI), semi2*sin(phi+M_PI));
00486
00487
00488
00489
00490 wideTrajectory->push_back(state->position());
00491 for(int index=0; index<4; ++index)
00492 wideTrajectory->push_back(target->toGlobal(bounds[index]));
00493
00494
00495
00496 }
00497
00498 return wideTrajectory;
00499 }
00500
00501 SteppingHelixStateInfo CachedTrajectory::getStateAtEcal()
00502 {
00503 if ( ecalTrajectory_.empty() )
00504 return SteppingHelixStateInfo();
00505 else
00506 return ecalTrajectory_.front();
00507 }
00508
00509 SteppingHelixStateInfo CachedTrajectory::getStateAtHcal()
00510 {
00511 if ( hcalTrajectory_.empty() )
00512 return SteppingHelixStateInfo();
00513 else
00514 return hcalTrajectory_.front();
00515 }
00516
00517 SteppingHelixStateInfo CachedTrajectory::getStateAtHO()
00518 {
00519 if ( hoTrajectory_.empty() )
00520 return SteppingHelixStateInfo();
00521 else
00522 return hoTrajectory_.front();
00523 }
00524
00525
00526 SteppingHelixStateInfo CachedTrajectory::getInnerState() {
00527 if(fullTrajectory_.empty() )
00528 return SteppingHelixStateInfo();
00529 else
00530 return fullTrajectory_.front();
00531 }
00532
00533
00534 SteppingHelixStateInfo CachedTrajectory::getOuterState() {
00535 if(fullTrajectory_.empty() )
00536 return SteppingHelixStateInfo();
00537 else
00538 return fullTrajectory_.back();
00539 }
00540