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
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
00042
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){
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
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
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 }}
00100
00101 const Bounds& bounds( bl->specificSurface().bounds());
00102 float length = bounds.length() / 2.f;
00103
00104
00105 float deltaZ = bounds.thickness()/2. /
00106 fabs( tan( propState.globalDirection().theta()));
00107
00108
00109 const float nSigma = theEpsilon;
00110 if (propState.hasError()) {
00111 deltaZ += nSigma * sqrt( fts.cartesianError().position().czz());
00112 }
00113
00114
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
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
00150 }}
00151
00152
00153 float rpos = propState.globalPosition().perp();
00154 float innerR = fl->specificSurface().innerRadius();
00155 float outerR = fl->specificSurface().outerRadius();
00156
00157
00158 float deltaR = fl->surface().bounds().thickness()/2. *
00159 fabs( tan( propState.localDirection().theta()));
00160
00161
00162 const float nSigma = theEpsilon;
00163 if (propState.hasError()) {
00164 LocalError err = propState.localError().positionError();
00165
00166 deltaR += nSigma * sqrt(err.xx() + err.yy());
00167 }
00168
00169
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
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);
00255 Lset collect;
00256
00257 Lset layerToTry,nextLayerToTry;
00258
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
00266 nextLayerToTry.clear();
00267 for (Lset::iterator toTry=layerToTry.begin();toTry!=layerToTry.end();++toTry){
00268
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
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
00280 bool alreadyTested=false;
00281 for (Lset::iterator testMe=collect.begin();testMe!=collect.end();++testMe){
00282 if ((*testMe) == (*next))
00283 {alreadyTested=true;break;}
00284 }
00285
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
00297 }
00298 }
00299 LogDebug("SimpleNavigableLayer")
00300 <<counter<<"] "<<nextLayerToTry.size()<<" layers to try next so far.";
00301 }
00302
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());
00311 LogDebug("SimpleNavigableLayer")
00312 <<"Number of compatible layers: "<<result.size();
00313 return result;
00314
00315
00316 }