CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/RecoTracker/TkNavigation/src/SimpleNavigableLayer.cc

Go to the documentation of this file.
00001 #include "RecoTracker/TkNavigation/interface/SimpleNavigableLayer.h"
00002 
00003 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00004 
00005 #include "DataFormats/GeometrySurface/interface/BoundCylinder.h"
00006 #include "DataFormats/GeometrySurface/interface/BoundDisk.h"
00007 #include "TrackingTools/PatternTools/interface/TransverseImpactPointExtrapolator.h"
00008 #include <set>
00009 #include <TrackingTools/TrackAssociator/interface/DetIdInfo.h>
00010 
00011 using namespace std;
00012 
00013 TrajectoryStateOnSurface SimpleNavigableLayer::crossingState(const FreeTrajectoryState& fts,
00014                                                              PropagationDirection dir) const{
00015   TSOS propState;
00016   //self propagating. step one: go close to the center
00017   GlobalPoint initialPoint = fts.position();
00018   TransverseImpactPointExtrapolator middle;
00019   GlobalPoint center(0,0,0);
00020   propState = middle.extrapolate(fts, center, propagator(dir));
00021   if ( !propState.isValid()) return TrajectoryStateOnSurface();
00022   
00023   FreeTrajectoryState & dest = *propState.freeState();
00024   GlobalPoint middlePoint = dest.position();
00025   const double toCloseToEachOther=1e-4;
00026   if ( (middlePoint-initialPoint).mag() < toCloseToEachOther){
00027     LogDebug("SimpleNavigableLayer")<<"initial state and PCA are identical. Things are bound to fail. Do not add the link.";
00028     return TrajectoryStateOnSurface();
00029   }
00030   
00031   std::string dirS;
00032   if (dir==alongMomentum) dirS = "alongMomentum";
00033   else if (dir==oppositeToMomentum) dirS = "oppositeToMomentum";
00034   else dirS = "anyDirection";
00035   
00036   LogDebug("SimpleNavigableLayer")<<"self propagating("<< dir <<") from:\n"
00037                                   <<fts<<"\n"
00038                                   <<dest<<"\n"
00039                                   <<" and the direction is: "<<dir<<" = "<<dirS;
00040   
00041   //second propagation to go on the other side of the barrel
00042   //propState = propagator(dir).propagate( dest, detLayer()->specificSurface());
00043   propState = propagator(dir).propagate( dest, detLayer()->surface());
00044   if ( !propState.isValid()) return TrajectoryStateOnSurface();
00045   
00046   FreeTrajectoryState & dest2 = *propState.freeState();
00047   GlobalPoint finalPoint = dest2.position();
00048   LogDebug("SimpleNavigableLayer")<<"second propagation("<< dir <<") to: \n"
00049                                   <<dest2;
00050   double finalDot = (middlePoint - initialPoint).basicVector().dot((finalPoint-middlePoint).basicVector());
00051   if (finalDot<0){ // check that before and after are in different side.
00052     LogDebug("SimpleNavigableLayer")<<"switch side back: ABORT.";
00053     return TrajectoryStateOnSurface();
00054   }
00055   return propState;
00056 }
00057 
00058 bool SimpleNavigableLayer::wellInside( const FreeTrajectoryState& fts,
00059                                        PropagationDirection dir,
00060                                        const BarrelDetLayer* bl,
00061                                        DLC& result) const
00062 {
00063   TSOS propState ;
00064 
00065   if (bl==detLayer()){
00066     propState = crossingState(fts,dir);
00067     if (!propState.isValid()) return false;
00068   }else{
00069     propState= propagator(dir).propagate( fts, bl->specificSurface());
00070   }
00071 
00072   if ( !propState.isValid()) return false;
00073  
00074   //if requested check that the layer is crossed on the right side
00075   if (theCheckCrossingSide){
00076     bool backTobackTransverse = (fts.position().x()*propState.globalPosition().x() + fts.position().y()*propState.globalPosition().y())<0;
00077     bool backToback = propState.globalPosition().basicVector().dot(fts.position().basicVector())<0;
00078 
00079     if (backTobackTransverse || backToback ){
00080       LogTrace("TkNavigation") << "Crossing over prevented!\nStaring from (x,y,z,r) (" 
00081                                << fts.position().x()<<","<< fts.position().y()<<","<< fts.position().z()<<","<<fts.position().perp()
00082                                << ") going to TSOS (x,y,z,r)" 
00083                                << propState.globalPosition().x()<<","<< propState.globalPosition().y()<<","<< propState.globalPosition().z()<<","<<propState.globalPosition().perp()<<")";
00084       return false;
00085     
00086     /*
00087     //we have to check the crossing side only if we are going to something smaller
00088     if (fts.position().perp()>bl->specificSurface().radius() || 
00089     fabs(fts.position().z())>bl->surface().bounds().length()/2. ){
00090     if (propState.globalPosition().basicVector().dot(fts.position().basicVector())<0){
00091     LogTrace("TkNavigation") << "Crossing over prevented!\nStaring from (x,y,z,r) (" 
00092     << fts.position().x()<<","<< fts.position().y()<<","<< fts.position().z()<<","<<fts.position().perp()
00093     << ") going to TSOS (x,y,z,r)" 
00094     << propState.globalPosition().x()<<","<< propState.globalPosition().y()<<","<< propState.globalPosition().z()<<","<<propState.globalPosition().perp()<<")";; 
00095     return false;
00096     }
00097     }   
00098     */
00099     }}
00100 
00101   const Bounds& bounds( bl->specificSurface().bounds());
00102   float length = bounds.length() / 2.f;
00103 
00104   // take into account the thickness of the layer
00105   float deltaZ = bounds.thickness()/2. / 
00106     fabs( tan( propState.globalDirection().theta()));
00107 
00108   // take into account the error on the predicted state
00109   const float nSigma = theEpsilon;  // temporary reuse of epsilon
00110   if (propState.hasError()) {
00111     deltaZ += nSigma * sqrt( fts.cartesianError().position().czz());
00112   }
00113 
00114   // cout << "SimpleNavigableLayer BarrelDetLayer deltaZ = " << deltaZ << endl;
00115 
00116   float zpos = propState.globalPosition().z();
00117   if ( fabs( zpos) < length + deltaZ) result.push_back( bl);
00118 
00119   if ( fabs( zpos) < length - deltaZ) return true;
00120   else return false;
00121 }
00122 
00123 bool SimpleNavigableLayer::wellInside( const FreeTrajectoryState& fts,
00124                                        PropagationDirection dir,
00125                                        const ForwardDetLayer* fl,
00126                                        DLC& result) const
00127 {
00128   TSOS propState = propagator(dir).propagate( fts, fl->specificSurface());
00129   if ( !propState.isValid()) return false;
00130 
00131   if (fl==detLayer()){
00132     LogDebug("SimpleNavigableLayer")<<"self propagating from:\n"
00133                                     <<fts<<"\n to \n"
00134                                     <<*propState.freeState();
00135   }
00136 
00137   //if requested avoids crossing over the tracker 
00138   if (theCheckCrossingSide){
00139     bool backTobackTransverse = (fts.position().x()*propState.globalPosition().x() + fts.position().y()*propState.globalPosition().y())<0;
00140     bool backToback = propState.globalPosition().basicVector().dot(fts.position().basicVector())<0;
00141 
00142     if (backTobackTransverse || backToback ){
00143       LogTrace("TkNavigation") << "Crossing over prevented!\nStaring from (x,y,z,r) (" 
00144                                << fts.position().x()<<","<< fts.position().y()<<","<< fts.position().z()<<","<<fts.position().perp()
00145                                << ") going to TSOS (x,y,z,r)" 
00146                                << propState.globalPosition().x()<<","<< propState.globalPosition().y()<<","<< propState.globalPosition().z()<<","<<propState.globalPosition().perp()<<")";; 
00147       return false;
00148     
00149   //    if (fts.position().z()*propState.globalPosition().z() < 0) return false;
00150     }}
00151 
00152 
00153   float rpos = propState.globalPosition().perp();
00154   float innerR = fl->specificSurface().innerRadius();
00155   float outerR = fl->specificSurface().outerRadius();
00156  
00157   // take into account the thickness of the layer
00158   float deltaR = fl->surface().bounds().thickness()/2. *
00159     fabs( tan( propState.localDirection().theta()));
00160 
00161   // take into account the error on the predicted state
00162   const float nSigma = theEpsilon;
00163   if (propState.hasError()) {
00164     LocalError err = propState.localError().positionError();
00165     // ignore correlation for the moment...
00166     deltaR += nSigma * sqrt(err.xx() + err.yy());
00167   }
00168 
00169   // cout << "SimpleNavigableLayer BarrelDetLayer deltaR = " << deltaR << endl;
00170 
00171   if ( innerR-deltaR < rpos && rpos < outerR+deltaR) result.push_back( fl);
00172   
00173   if ( innerR+deltaR < rpos && rpos < outerR-deltaR) return true;
00174   else return false;
00175 }
00176 
00177 bool SimpleNavigableLayer::wellInside( const FreeTrajectoryState& fts,
00178                                        PropagationDirection dir,
00179                                        const DLC& layers,
00180                                        DLC& result) const
00181 {
00182 
00183   // cout << "Entering SimpleNavigableLayer::wellInside" << endl;
00184 
00185   for (DLC::const_iterator i = layers.begin(); i != layers.end(); i++) {
00186     const BarrelDetLayer* bl = dynamic_cast<const BarrelDetLayer*>(*i);
00187     if ( bl != 0) {
00188       if (wellInside( fts, dir, bl, result)) return true;
00189     }
00190     else {
00191       const ForwardDetLayer* fl = dynamic_cast<const ForwardDetLayer*>(*i);
00192       if ( fl == 0) edm::LogError("TkNavigation") << "dynamic_cast<const ForwardDetLayer*> failed" ;
00193       if (wellInside( fts, dir, fl, result)) return true;
00194     }
00195   }
00196   return false;
00197 }
00198 
00199 bool SimpleNavigableLayer::wellInside( const FreeTrajectoryState& fts,
00200                                        PropagationDirection dir,
00201                                        ConstBDLI begin, ConstBDLI end,
00202                                        DLC& result) const
00203 {
00204   for ( ConstBDLI i = begin; i < end; i++) {
00205     if (wellInside( fts, dir, *i, result)) return true;
00206   }
00207   return false;
00208 }
00209 
00210 bool SimpleNavigableLayer::wellInside( const FreeTrajectoryState& fts,
00211                                        PropagationDirection dir,
00212                                        ConstFDLI begin, ConstFDLI end,
00213                                        DLC& result) const
00214 {
00215   for ( ConstFDLI i = begin; i < end; i++) {
00216     if (wellInside( fts, dir, *i, result)) return true;
00217   }
00218   return false;
00219 }
00220 
00221 Propagator& SimpleNavigableLayer::propagator( PropagationDirection dir) const
00222 {
00223 #ifndef CMS_NO_MUTABLE
00224   thePropagator.setPropagationDirection(dir);
00225   return thePropagator;
00226 #else
00227   SimpleNavigableLayer* mthis = const_cast<SimpleNavigableLayer*>(this);
00228   mthis->thePropagator.setPropagationDirection(dir);
00229   return mthis->thePropagator;
00230 #endif
00231 }
00232 
00233 void SimpleNavigableLayer::pushResult( DLC& result, const BDLC& tmp) const 
00234 {
00235   for ( ConstBDLI i = tmp.begin(); i != tmp.end(); i++) {
00236     result.push_back(*i);
00237   }
00238 }
00239 
00240 void SimpleNavigableLayer::pushResult( DLC& result, const FDLC& tmp) const 
00241 {
00242   for ( ConstFDLI i = tmp.begin(); i != tmp.end(); i++) {
00243     result.push_back(*i);
00244   }
00245 }
00246 
00247 std::vector< const DetLayer * > SimpleNavigableLayer::compatibleLayers (const FreeTrajectoryState &fts, 
00248                                                                         PropagationDirection timeDirection,
00249                                                                         int& counter) const {
00250   typedef std::vector<const DetLayer*> Lvect;
00251   typedef std::set<const DetLayer *> Lset;  
00252 
00253   Lvect empty,result;
00254   result.reserve(15); //that's a max
00255   Lset collect; //a container of unique instances. to avoid duplicates
00256   
00257   Lset layerToTry,nextLayerToTry;//set used for iterations
00258   //initiate the first iteration
00259   Lvect someLayers(nextLayers(fts,timeDirection));
00260   layerToTry.insert(someLayers.begin(),someLayers.end());
00261   
00262   while (!layerToTry.empty() && (counter++)<=150){
00263     LogDebug("SimpleNavigableLayer")
00264       <<counter<<"] going to check on : "<<layerToTry.size()<<" next layers.";
00265     //clear this set first, it will be swaped with layerToTry
00266     nextLayerToTry.clear();
00267     for (Lset::iterator toTry=layerToTry.begin();toTry!=layerToTry.end();++toTry){
00268       //add the layer you tried.
00269       LogDebug("SimpleNavigableLayer")
00270         <<counter<<"] adding layer with pointer: "<<(*toTry)
00271         <<" first detid: "<<DetIdInfo::info((*toTry)->basicComponents().front()->geographicalId());
00272       collect.insert( (*toTry) );
00273       
00274       //find the next layers from it
00275       Lvect nextLayers( (*toTry)->nextLayers(fts,timeDirection) );
00276       LogDebug("SimpleNavigableLayer")
00277         <<counter<<"] this layer has : "<<nextLayers.size()<<" next layers.";
00278       for (Lvect::iterator next=nextLayers.begin();next!=nextLayers.end();++next){
00279         //if the next layer is not already in the collected layers, add it for next round.
00280         bool alreadyTested=false;
00281         for (Lset::iterator testMe=collect.begin();testMe!=collect.end();++testMe){ //find method does not work well!
00282           if ((*testMe) == (*next))
00283             {alreadyTested=true;break;}
00284         }
00285         //      if ( collect.find(*next)!=collect.end()){ //find method does not work it seems...
00286         if (!alreadyTested){
00287           nextLayerToTry.insert( *next );
00288           LogDebug("SimpleNavigableLayer")
00289             <<counter<<"] to try next, layer with pointer: "<<(*next)
00290             <<" first detid: "<<DetIdInfo::info((*next)->basicComponents().front()->geographicalId());
00291         }
00292         else{
00293           LogDebug("SimpleNavigableLayer")
00294             <<counter<<"] skipping for next tryout, layer with pointer: "<<(*next)
00295             <<" first detid: "<<DetIdInfo::info((*next)->basicComponents().front()->geographicalId());
00296           //for (Lset::iterator testMe=collect.begin();testMe!=collect.end();++testMe){  LogTrace("SimpleNavigableLayer") <<"pointer collected:" <<(*testMe); }
00297         }
00298       }
00299       LogDebug("SimpleNavigableLayer")
00300         <<counter<<"] "<<nextLayerToTry.size()<<" layers to try next so far.";
00301     }
00302     //swap now that you where to go next.
00303     layerToTry.swap(nextLayerToTry);
00304   }
00305   if(counter>=150) {
00306     edm::LogWarning("SimpleNavigableLayer") << "WARNING: compatibleLayers() more than 150 iterations!!! Bailing out..";
00307     counter = -1;return empty;
00308   }
00309 
00310   result.insert(result.end(),collect.begin(),collect.end()); //cannot do a swap it seems
00311   LogDebug("SimpleNavigableLayer")
00312       <<"Number of compatible layers: "<<result.size();
00313   return result;
00314 
00315 
00316 }