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