00001 #include "RecoMuon/TrackerSeedGenerator/plugins/TSGForRoadSearch.h"
00002
00003 #include <Geometry/Records/interface/GlobalTrackingGeometryRecord.h>
00004
00005 #include <RecoTracker/Record/interface/CkfComponentsRecord.h>
00006 #include <MagneticField/Records/interface/IdealMagneticFieldRecord.h>
00007 #include <TrackingTools/Records/interface/TrackingComponentsRecord.h>
00008
00009 #include <TrackingTools/TransientTrack/interface/TransientTrack.h>
00010 #include <TrackingTools/DetLayers/interface/BarrelDetLayer.h>
00011 #include <TrackingTools/DetLayers/interface/ForwardDetLayer.h>
00012
00013 #include <FWCore/MessageLogger/interface/MessageLogger.h>
00014 #include <TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h>
00015
00016 #include <RecoTracker/TkDetLayers/interface/GeometricSearchTracker.h>
00017
00018 #include "RecoTracker/TkNavigation/interface/StartingLayerFinder.h"
00019 #include "TrackPropagation/SteppingHelixPropagator/interface/SteppingHelixPropagator.h"
00020
00021 #include "RecoMuon/TrackingTools/interface/MuonServiceProxy.h"
00022 #include "RecoMuon/TrackingTools/interface/MuonErrorMatrix.h"
00023
00024 #include <TrackingTools/KalmanUpdators/interface/KFUpdator.h>
00025 #include "TrackingTools/GeomPropagators/interface/StateOnTrackerBound.h"
00026
00027 TSGForRoadSearch::TSGForRoadSearch(const edm::ParameterSet & par){
00028
00029 theOption = par.getParameter<unsigned int>("option");
00030 theCopyMuonRecHit = par.getParameter<bool>("copyMuonRecHit");
00031
00032 double Chi2 = par.getParameter<double>("maxChi2");
00033 theChi2Estimator = new Chi2MeasurementEstimator(Chi2,sqrt(Chi2));
00034
00035 thePropagatorName = par.getParameter<std::string>("propagatorName");
00036 thePropagatorCompatibleName = par.getParameter<std::string>("propagatorCompatibleName");
00037
00038 theCategory = "TSGForRoadSearch|TrackerSeedGenerator";
00039
00040 theManySeeds = par.getParameter<bool>("manySeeds");
00041 if (theManySeeds){ theUpdator = new KFUpdator();}
00042 else{ theUpdator=0;}
00043
00044 edm::ParameterSet errorMatrixPset = par.getParameter<edm::ParameterSet>("errorMatrixPset");
00045 if (!errorMatrixPset.empty()){
00046 theAdjustAtIp = errorMatrixPset.getParameter<bool>("atIP");
00047 theErrorMatrixAdjuster = new MuonErrorMatrix(errorMatrixPset);}
00048 else {
00049 theAdjustAtIp =false;
00050 theErrorMatrixAdjuster=0;}
00051 }
00052 TSGForRoadSearch::~TSGForRoadSearch(){
00053 delete theChi2Estimator;
00054 if (theUpdator) delete theUpdator;
00055 if (theErrorMatrixAdjuster) delete theErrorMatrixAdjuster;
00056 }
00057
00058
00059 void TSGForRoadSearch::init(const MuonServiceProxy* service){
00060 theProxyService = service;
00061 }
00062
00063 void TSGForRoadSearch::setEvent(const edm::Event &event){
00064
00065 if (theManySeeds){
00066 theProxyService->eventSetup().get<CkfComponentsRecord>().get(theMeasurementTracker);
00067 if (!theMeasurementTracker.isValid()){edm::LogError(theCategory)<<"measurement tracker geometry not found ";}
00068 }
00069 theProxyService->eventSetup().get<TrackerRecoGeometryRecord>().get(theGeometricSearchTracker);
00070 }
00071
00072
00073
00074 void TSGForRoadSearch::trackerSeeds(const TrackCand & muonTrackCand, const TrackingRegion& region, std::vector<TrajectorySeed> & result){
00075 switch (theOption){
00076 case 0:
00077 makeSeeds_0(*muonTrackCand.second,result);break;
00078 case 1:
00079 makeSeeds_1(*muonTrackCand.second,result);break;
00080 case 2:
00081 makeSeeds_2(*muonTrackCand.second,result);break;
00082 case 3:
00083 makeSeeds_3(*muonTrackCand.second,result);break;
00084 case 4:
00085 makeSeeds_4(*muonTrackCand.second,result);break;
00086 }
00087 }
00088
00089 bool TSGForRoadSearch::notAtIPtsos(TrajectoryStateOnSurface & state){
00090 LogDebug(theCategory)<<"outer state: "<<state;
00091 if (theErrorMatrixAdjuster && !theAdjustAtIp){
00092 theErrorMatrixAdjuster->adjust(state);
00093 LogDebug(theCategory)<<"outer state after rescale: "<<state;
00094 }
00095 return true;
00096 }
00097
00098 bool TSGForRoadSearch::IPfts(const reco::Track & muon, FreeTrajectoryState & fts){
00099
00100 fts = trajectoryStateTransform::initialFreeState(muon,&*theProxyService->magneticField());
00101 LogDebug(theCategory)<<"pure L2 state: "<<fts;
00102 if (fts.position().mag()==0 && fts.momentum().mag()==0){ edm::LogError(theCategory)<<"initial state of muon is (0,0,0)(0,0,0). no seed.";
00103 return false;}
00104
00105
00106 if (theErrorMatrixAdjuster && theAdjustAtIp){ theErrorMatrixAdjuster->adjust(fts);
00107 LogDebug(theCategory)<<"after adjusting the error matrix: "<<fts;}
00108
00109 return true;
00110 }
00111
00112
00113
00114
00115 void TSGForRoadSearch::makeSeeds_0(const reco::Track & muon, std::vector<TrajectorySeed>& result){
00116
00117 FreeTrajectoryState cIPFTS;
00118 if (!IPfts(muon, cIPFTS)) return;
00119
00120
00121 const std::vector<BarrelDetLayer*> & blc = theGeometricSearchTracker->tibLayers();
00122 TrajectoryStateOnSurface inner = theProxyService->propagator(thePropagatorName)->propagate(cIPFTS,blc.front()->surface());
00123 if ( !inner.isValid() ) {LogDebug(theCategory) <<"inner state is not valid. no seed."; return;}
00124
00125
00126 if (!notAtIPtsos(inner)) return;
00127
00128 double z = inner.globalPosition().z();
00129
00130 const std::vector<ForwardDetLayer*> &ptidc = theGeometricSearchTracker->posTidLayers();
00131 const std::vector<ForwardDetLayer*> &ptecc = theGeometricSearchTracker->posTecLayers();
00132 const std::vector<ForwardDetLayer*> &ntidc = theGeometricSearchTracker->negTidLayers();
00133 const std::vector<ForwardDetLayer*> &ntecc = theGeometricSearchTracker->negTecLayers();
00134
00135 const DetLayer *inLayer = 0;
00136 if( fabs(z) < ptidc.front()->surface().position().z() ) {
00137 inLayer = blc.front();
00138 } else if ( fabs(z) < ptecc.front()->surface().position().z() ) {
00139 inLayer = ( z < 0 ) ? ntidc.front() : ptidc.front() ;
00140 } else {
00141 inLayer = ( z < 0 ) ? ntecc.front() : ptecc.front() ;
00142 }
00143
00144
00145 std::vector< DetLayer::DetWithState > compatible;
00146 compatible.reserve(10);
00147 inLayer->compatibleDetsV(inner,*theProxyService->propagator(thePropagatorCompatibleName),*theChi2Estimator,compatible);
00148
00149
00150 while (compatible.size()==0) {
00151 switch ( inLayer->subDetector() ) {
00152 case GeomDetEnumerators::PixelBarrel:
00153 case GeomDetEnumerators::PixelEndcap:
00154 case GeomDetEnumerators::TOB:
00155 case GeomDetEnumerators::TEC:
00156 LogDebug(theCategory)<<"from inside-out, trying TEC or TOB layers. no seed.";
00157 return;
00158 break;
00159 case GeomDetEnumerators::TIB:
00160 inLayer = ( z < 0 ) ? ntidc.front() : ptidc.front() ;
00161 break;
00162 case GeomDetEnumerators::TID:
00163 inLayer = ( z < 0 ) ? ntecc.front() : ptecc.front() ;
00164 break;
00165 default:
00166 LogDebug(theCategory)<<"subdetectorid is not a tracker sub-dectector id. skipping.";
00167 return;
00168 }
00169 inLayer->compatibleDetsV(inner,*theProxyService->propagator(thePropagatorCompatibleName),*theChi2Estimator,compatible);
00170 }
00171
00172 pushTrajectorySeed(muon,compatible,alongMomentum,result);
00173
00174 return;
00175 }
00176
00177 void TSGForRoadSearch::makeSeeds_1(const reco::Track & muon, std::vector<TrajectorySeed>& result){
00178 edm::LogError(theCategory)<<"option 1 of TSGForRoadSearch is not implemented yet. Please use 0,3 or 4. no seed.";
00179 return;
00180 }
00181
00182 void TSGForRoadSearch::makeSeeds_2(const reco::Track & muon, std::vector<TrajectorySeed>& result){
00183 edm::LogError(theCategory)<<"option 2 of TSGForRoadSearch is not implemented yet. Please use 0,3 or 4. no seed.";
00184 return;
00185 }
00186
00187
00188
00189
00190 void TSGForRoadSearch::makeSeeds_3(const reco::Track & muon, std::vector<TrajectorySeed>& result){
00191
00192 FreeTrajectoryState cIPFTS;
00193 if (!IPfts(muon, cIPFTS)) return;
00194
00195
00196 const std::vector<BarrelDetLayer*> &blc = theGeometricSearchTracker->tobLayers();
00197
00198
00199 StateOnTrackerBound onBounds(theProxyService->propagator(thePropagatorName).product());
00200 TrajectoryStateOnSurface outer = onBounds(cIPFTS);
00201
00202 if ( !outer.isValid() ) {LogDebug(theCategory) <<"outer state is not valid. no seed."; return;}
00203
00204
00205 if (!notAtIPtsos(outer)) return;
00206
00207 double z = outer.globalPosition().z();
00208
00209 const std::vector<ForwardDetLayer*> &ptecc = theGeometricSearchTracker->posTecLayers();
00210 const std::vector<ForwardDetLayer*> &ntecc = theGeometricSearchTracker->negTecLayers();
00211
00212 LogDebug(theCategory)<<"starting looking for a compatible layer from: "<<outer<<"\nz: "<<z<<"TEC1 z: "<<ptecc.front()->surface().position().z();
00213
00214 unsigned int layerShift=0;
00215 const DetLayer *inLayer = 0;
00216 if (fabs(z) < ptecc.front()->surface().position().z() ){
00217 inLayer = *(blc.rbegin()+layerShift);
00218 LogTrace(theCategory)<<"choosing TOB layer with shift: "<<layerShift;
00219 } else {
00220 unsigned int tecIt=1;
00221 for (; tecIt!=ptecc.size();tecIt++){
00222 LogTrace(theCategory)<<"checking surface with shift: "<<tecIt
00223 <<"z: "<<ptecc[tecIt]->surface().position().z();
00224 if (fabs(z) < ptecc[tecIt]->surface().position().z())
00225 {inLayer = ( z < 0 ) ? ntecc[tecIt-1] : ptecc[tecIt-1] ;
00226 layerShift=tecIt-1;
00227 LogTrace(theCategory)<<"choosing TEC layer with shift: "<<layerShift
00228 <<" and z: "<<inLayer->surface().position().z();
00229 break;}}
00230 if (!inLayer) {inLayer = ( z < 0 ) ? ntecc.back() : ptecc.back();
00231 LogTrace(theCategory)<<"choosing last TEC layer with z: "<<inLayer->surface().position().z();
00232 }
00233 }
00234
00235
00236 std::vector< DetLayer::DetWithState > compatible;
00237 compatible.reserve(10);
00238 inLayer->compatibleDetsV(outer,*theProxyService->propagator(thePropagatorCompatibleName),*theChi2Estimator,compatible);
00239
00240
00241 while (compatible.size()==0) {
00242 switch ( inLayer->subDetector() ) {
00243 case GeomDetEnumerators::PixelBarrel:
00244 case GeomDetEnumerators::PixelEndcap:
00245 case GeomDetEnumerators::TIB:
00246 case GeomDetEnumerators::TID:
00247 case GeomDetEnumerators::TOB:
00248 layerShift++;
00249 if (layerShift>=blc.size()){
00250 LogDebug(theCategory) <<"all barrel layers are exhausted to find starting state. no seed,";
00251 return;}
00252 inLayer = *(blc.rbegin()+layerShift);
00253 break;
00254 case GeomDetEnumerators::TEC:
00255 if (layerShift==0){
00256 LogDebug(theCategory) <<"failed to get a compatible module on a TEC layer, using the last TOB layer.";
00257 inLayer = *(blc.rbegin()+layerShift);
00258 }
00259 else{
00260 layerShift--;
00261 LogDebug(theCategory) <<"reaching more in with layer "<<layerShift<<" in TEC";
00262 inLayer = ( z < 0 ) ? ntecc[layerShift] : ptecc[layerShift] ;
00263 }
00264 break;
00265 default:
00266 edm::LogError(theCategory)<<"subdetectorid is not a tracker sub-dectector id. skipping.";
00267 return;
00268 }
00269 inLayer->compatibleDetsV(outer,*theProxyService->propagator(thePropagatorCompatibleName),*theChi2Estimator,compatible);
00270 }
00271
00272 pushTrajectorySeed(muon,compatible,oppositeToMomentum,result);
00273
00274 return;
00275 }
00276
00277
00278
00279
00280
00281 void TSGForRoadSearch::makeSeeds_4(const reco::Track & muon, std::vector<TrajectorySeed>& result){
00282
00283 FreeTrajectoryState cIPFTS;
00284 if (!IPfts(muon, cIPFTS)) return;
00285
00286
00287 const std::vector<BarrelDetLayer*> & blc = theGeometricSearchTracker->pixelBarrelLayers();
00288 if (blc.empty()){edm::LogError(theCategory)<<"want to start from pixel layer, but no barrel exists. trying without pixel.";
00289 makeSeeds_0(muon, result);
00290 return;}
00291
00292 TrajectoryStateOnSurface inner = theProxyService->propagator(thePropagatorName)->propagate(cIPFTS,blc.front()->surface());
00293 if ( !inner.isValid() ) {LogDebug(theCategory) <<"inner state is not valid. no seed."; return;}
00294
00295
00296 if (!notAtIPtsos(inner)) return;
00297
00298 double z = inner.globalPosition().z();
00299
00300 const std::vector<ForwardDetLayer*> &ppxlc = theGeometricSearchTracker->posPixelForwardLayers();
00301 const std::vector<ForwardDetLayer*> &npxlc = theGeometricSearchTracker->negPixelForwardLayers();
00302 const std::vector<ForwardDetLayer*> &ptidc = theGeometricSearchTracker->posTidLayers();
00303 const std::vector<ForwardDetLayer*> &ptecc = theGeometricSearchTracker->posTecLayers();
00304 const std::vector<ForwardDetLayer*> &ntidc = theGeometricSearchTracker->negTidLayers();
00305 const std::vector<ForwardDetLayer*> &ntecc = theGeometricSearchTracker->negTecLayers();
00306
00307 if ((ppxlc.empty() || npxlc.empty()) && (ptidc.empty() || ptecc.empty()) )
00308 { edm::LogError(theCategory)<<"want to start from pixel layer, but no forward layer exists. trying without pixel.";
00309 makeSeeds_0(muon, result);
00310 return;}
00311
00312 const DetLayer *inLayer = 0;
00313 std::vector<ForwardDetLayer*>::const_iterator layerIt ;
00314
00315 double fz=fabs(z);
00316
00317
00318 if (fz < fabs(((z>0)?ppxlc:npxlc).front()->surface().position().z())){
00319 inLayer = blc.front();}
00320 else if (fz < fabs(((z>0)?ppxlc:npxlc).back()->surface().position().z())){
00321 layerIt = ((z>0)?ppxlc:npxlc).begin();
00322 inLayer= *layerIt;}
00323 else if (fz < fabs(((z>0)?ptidc:ntidc).front()->surface().position().z())){
00324 layerIt = ((z>0)?ppxlc:npxlc).end()-1;
00325 inLayer= *layerIt;}
00326 else if (fz < fabs(((z>0)?ptecc:ntecc).front()->surface().position().z())){
00327 layerIt = ((z>0)?ptidc:ntidc).begin();
00328 inLayer= *layerIt;}
00329 else if (fz < fabs(((z>0)?ptecc:ntecc).back()->surface().position().z())){
00330 layerIt = ((z>0)?ptecc:ntecc).begin();
00331 inLayer= *layerIt;}
00332 else {
00333 edm::LogWarning(theCategory)<<"the state is not consistent with any tracker layer:\n"
00334 <<inner;
00335 return;}
00336
00337
00338 std::vector< DetLayer::DetWithState > compatible;
00339 compatible.reserve(10);
00340 inLayer->compatibleDetsV(inner,*theProxyService->propagator(thePropagatorCompatibleName),*theChi2Estimator,compatible);
00341
00342
00343 if (compatible.size()==0){
00344 std::vector<ForwardDetLayer*>::const_iterator pxlEnd = (z>0)? ppxlc.end() : npxlc.end();
00345 std::vector<ForwardDetLayer*>::const_iterator tidEnd = (z>0)? ptidc.end() : ntidc.end();
00346 std::vector<ForwardDetLayer*>::const_iterator tecEnd = (z>0)? ptecc.end() : ntecc.end();
00347 std::vector<ForwardDetLayer*>::const_iterator pxlBegin = (z>0)? ppxlc.begin() : npxlc.begin();
00348 std::vector<ForwardDetLayer*>::const_iterator tidBegin = (z>0)? ptidc.begin() : ntidc.begin();
00349 std::vector<ForwardDetLayer*>::const_iterator tecBegin = (z>0)? ptecc.begin() : ntecc.begin();
00350
00351
00352 if (!dynamic_cast<const ForwardDetLayer*>(inLayer)) layerIt =pxlBegin--;
00353
00354 while (compatible.size()==0) {
00355 switch ( (*layerIt)->subDetector() ) {
00356 case GeomDetEnumerators::PixelEndcap:
00357 {
00358 layerIt++;
00359
00360 if (layerIt==pxlEnd) layerIt=tidBegin;
00361 break;
00362 }
00363 case GeomDetEnumerators::TID:
00364 {
00365 layerIt++;
00366
00367 if (layerIt==tidEnd) layerIt = tecBegin;
00368 break;
00369 }
00370 case GeomDetEnumerators::TEC:
00371 {
00372 layerIt++;
00373 if (layerIt==tecEnd){
00374 edm::LogWarning(theCategory)<<"ran out of layers to find a seed: no seed.";
00375 return;}
00376 }
00377 case GeomDetEnumerators::PixelBarrel: { edm::LogError(theCategory)<<"this should not happen... ever. Please report. GeomDetEnumerators::PixelBarrel. no seed."; return;}
00378 case GeomDetEnumerators::TIB: { edm::LogError(theCategory)<<"this should not happen... ever. Please report. GeomDetEnumerators::TIB. no seed."; return;}
00379 case GeomDetEnumerators::TOB: { edm::LogError(theCategory)<<"this should not happen... ever. Please report. GeomDetEnumerators::TOB. no seed."; return;}
00380 default: { edm::LogError(theCategory)<<"Subdetector id is not a tracker sub-detector id. no seed."; return;}
00381 }
00382
00383 (*layerIt)->compatibleDetsV(inner,*theProxyService->propagator(thePropagatorCompatibleName),*theChi2Estimator,compatible);
00384 }
00385 }
00386
00387 pushTrajectorySeed(muon,compatible,alongMomentum,result);
00388
00389 return;
00390 }
00391
00392
00393 #include <TrackingTools/PatternTools/interface/TrajectoryMeasurement.h>
00394 #include <TrackingTools/MeasurementDet/interface/MeasurementDet.h>
00395
00396 void TSGForRoadSearch::pushTrajectorySeed(const reco::Track & muon, std::vector<DetLayer::DetWithState > & compatible, PropagationDirection direction, std::vector<TrajectorySeed>& result)const {
00397
00398 if (compatible.empty()){
00399 LogDebug(theCategory)<<"pushTrajectorySeed with no compatible module. 0 seed.";
00400 return;}
00401
00402 if (theManySeeds){
00403
00404
00405
00406 for (std::vector<DetLayer::DetWithState >::iterator DWSit = compatible.begin(); DWSit!=compatible.end();++DWSit){
00407 bool aBareTS=false;
00408 const GeomDet * gd = DWSit->first;
00409 if (!gd){edm::LogError(theCategory)<<"GeomDet is not valid."; continue;}
00410 const MeasurementDet * md= theMeasurementTracker->idToDet(gd->geographicalId());
00411 std::vector<TrajectoryMeasurement> tmp = md->fastMeasurements(DWSit->second,DWSit->second,*theProxyService->propagator(thePropagatorCompatibleName),*theChi2Estimator);
00412
00413
00414 for (std::vector<TrajectoryMeasurement>::iterator Mit = tmp.begin(); Mit!=tmp.end();++Mit){
00415 TrajectoryStateOnSurface predState(Mit->predictedState());
00416 TrajectoryMeasurement::ConstRecHitPointer hit = Mit->recHit();
00417 TrajectorySeed::recHitContainer rhContainer;
00418 if (theCopyMuonRecHit){
00419 LogDebug(theCategory)<<"copying ("<<muon.recHitsSize()<<") muon recHits";
00420
00421 for (trackingRecHit_iterator trit = muon.recHitsBegin(); trit!=muon.recHitsEnd();trit++) {
00422 rhContainer.push_back( (*trit).get()->clone() ); }}
00423
00424 if ( hit->isValid()) {
00425 TrajectoryStateOnSurface upState(theUpdator->update(predState,*hit));
00426
00427 PTrajectoryStateOnDet const & PTSOD = trajectoryStateTransform::persistentState(upState,gd->geographicalId().rawId());
00428 LogDebug(theCategory)<<"state used to build a trajectory seed: \n"<<upState
00429 <<"on detector: "<<gd->geographicalId().rawId();
00430
00431 if (theCopyMuonRecHit){
00432 edm::LogError(theCategory)<<"not a bare seed and muon hits are copied. dumping the muon hits.";
00433 rhContainer.clear();}
00434 rhContainer.push_back(hit->hit()->clone());
00435
00436 result.push_back(TrajectorySeed(PTSOD,rhContainer,direction));
00437 }
00438 else {
00439
00440 if (!aBareTS){
00441 aBareTS=true;
00442
00443 PTrajectoryStateOnDet const & PTSOD = trajectoryStateTransform::persistentState(predState,gd->geographicalId().rawId());
00444 LogDebug(theCategory)<<"state used to build a bare trajectory seed: \n"<<predState
00445 <<"on detector: "<<gd->geographicalId().rawId();
00446
00447 result.push_back(TrajectorySeed(PTSOD,rhContainer,direction));
00448 }
00449 }
00450
00451 }
00452
00453
00454 }
00455 }
00456 else{
00457
00458
00459 PTrajectoryStateOnDet const& PTSOD = trajectoryStateTransform::persistentState(compatible.front().second,compatible.front().first->geographicalId().rawId());
00460 LogDebug(theCategory)<<"state used to build a bare trajectory seed: \n"<<compatible.front().second
00461 <<"on detector: "<<compatible.front().first->geographicalId().rawId();
00462
00463 TrajectorySeed::recHitContainer rhContainer;
00464 if (theCopyMuonRecHit){
00465 LogDebug(theCategory)<<"copying ("<<muon.recHitsSize()<<") muon recHits";
00466
00467 for (trackingRecHit_iterator trit = muon.recHitsBegin(); trit!=muon.recHitsEnd();trit++) {
00468 rhContainer.push_back( (*trit).get()->clone() ); }}
00469
00470
00471 result.push_back(TrajectorySeed(PTSOD,rhContainer,direction));
00472 }
00473 return;
00474 }