Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-09-07 04:37:48

0001 #include "RecoMuon/TrackerSeedGenerator/plugins/TSGForRoadSearch.h"
0002 
0003 #include <Geometry/Records/interface/GlobalTrackingGeometryRecord.h>
0004 #include <RecoTracker/Record/interface/CkfComponentsRecord.h>
0005 #include <MagneticField/Records/interface/IdealMagneticFieldRecord.h>
0006 #include <TrackingTools/Records/interface/TrackingComponentsRecord.h>
0007 
0008 #include <TrackingTools/TransientTrack/interface/TransientTrack.h>
0009 #include <TrackingTools/DetLayers/interface/BarrelDetLayer.h>
0010 #include <TrackingTools/DetLayers/interface/ForwardDetLayer.h>
0011 
0012 #include <FWCore/MessageLogger/interface/MessageLogger.h>
0013 #include <TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h>
0014 
0015 #include <RecoTracker/TkDetLayers/interface/GeometricSearchTracker.h>
0016 
0017 #include "TrackPropagation/SteppingHelixPropagator/interface/SteppingHelixPropagator.h"
0018 
0019 #include "RecoMuon/TrackingTools/interface/MuonServiceProxy.h"
0020 #include "RecoMuon/TrackingTools/interface/MuonErrorMatrix.h"
0021 #include "DataFormats/TrackerCommon/interface/TrackerTopology.h"
0022 
0023 #include <TrackingTools/KalmanUpdators/interface/KFUpdator.h>
0024 #include "TrackingTools/GeomPropagators/interface/StateOnTrackerBound.h"
0025 
0026 TSGForRoadSearch::TSGForRoadSearch(const edm::ParameterSet &par, edm::ConsumesCollector &iC)
0027     : theGeometricSearchTrackerToken(iC.esConsumes()) {
0028   theOption = par.getParameter<unsigned int>("option");
0029   theCopyMuonRecHit = par.getParameter<bool>("copyMuonRecHit");
0030 
0031   double Chi2 = par.getParameter<double>("maxChi2");
0032   theChi2Estimator = new Chi2MeasurementEstimator(Chi2, sqrt(Chi2));
0033 
0034   thePropagatorName = par.getParameter<std::string>("propagatorName");
0035   thePropagatorCompatibleName = par.getParameter<std::string>("propagatorCompatibleName");
0036 
0037   theCategory = "TSGForRoadSearch|TrackerSeedGenerator";
0038 
0039   theManySeeds = par.getParameter<bool>("manySeeds");
0040   if (theManySeeds) {
0041     theUpdator = new KFUpdator();
0042   } else {
0043     theUpdator = nullptr;
0044   }
0045 
0046   edm::ParameterSet errorMatrixPset = par.getParameter<edm::ParameterSet>("errorMatrixPset");
0047   if (!errorMatrixPset.empty()) {
0048     theAdjustAtIp = errorMatrixPset.getParameter<bool>("atIP");
0049     theErrorMatrixAdjuster = new MuonErrorMatrix(errorMatrixPset);
0050   } else {
0051     theAdjustAtIp = false;
0052     theErrorMatrixAdjuster = nullptr;
0053   }
0054 
0055   theMeasurementTrackerEventTag = par.getParameter<edm::InputTag>("MeasurementTrackerEvent");
0056   theMeasurementTrackerEvent = nullptr;
0057 
0058   theMeasurementTrackerEventToken = iC.consumes<MeasurementTrackerEvent>(theMeasurementTrackerEventTag);
0059 }
0060 
0061 TSGForRoadSearch::~TSGForRoadSearch() {
0062   delete theChi2Estimator;
0063   if (theUpdator)
0064     delete theUpdator;
0065   if (theErrorMatrixAdjuster)
0066     delete theErrorMatrixAdjuster;
0067 }
0068 
0069 void TSGForRoadSearch::init(const MuonServiceProxy *service) { theProxyService = service; }
0070 
0071 void TSGForRoadSearch::setEvent(const edm::Event &event) {
0072   //get the measurementtracker
0073   theGeometricSearchTracker = theProxyService->eventSetup().getHandle(theGeometricSearchTrackerToken);
0074 
0075   edm::Handle<MeasurementTrackerEvent> data;
0076   event.getByToken(theMeasurementTrackerEventToken, data);
0077   theMeasurementTrackerEvent = &*data;
0078 }
0079 
0080 void TSGForRoadSearch::trackerSeeds(const TrackCand &muonTrackCand,
0081                                     const TrackingRegion &region,
0082                                     const TrackerTopology *tTopo,
0083                                     std::vector<TrajectorySeed> &result) {
0084   switch (theOption) {
0085     case 0:
0086       makeSeeds_0(*muonTrackCand.second, result);
0087       break;
0088     case 1:
0089       makeSeeds_1(*muonTrackCand.second, result);
0090       break;
0091     case 2:
0092       makeSeeds_2(*muonTrackCand.second, result);
0093       break;
0094     case 3:
0095       makeSeeds_3(*muonTrackCand.second, result);
0096       break;
0097     case 4:
0098       makeSeeds_4(*muonTrackCand.second, result);
0099       break;
0100   }
0101 }
0102 
0103 bool TSGForRoadSearch::notAtIPtsos(TrajectoryStateOnSurface &state) {
0104   LogDebug(theCategory) << "outer state: " << state;
0105   if (theErrorMatrixAdjuster && !theAdjustAtIp) {
0106     theErrorMatrixAdjuster->adjust(state);
0107     LogDebug(theCategory) << "outer state after rescale: " << state;
0108   }
0109   return true;
0110 }
0111 
0112 bool TSGForRoadSearch::IPfts(const reco::Track &muon, FreeTrajectoryState &fts) {
0113   fts = trajectoryStateTransform::initialFreeState(muon, &*theProxyService->magneticField());
0114   LogDebug(theCategory) << "pure L2 state: " << fts;
0115   if (fts.position().mag() == 0 && fts.momentum().mag() == 0) {
0116     edm::LogError(theCategory) << "initial state of muon is (0,0,0)(0,0,0). no seed.";
0117     return false;
0118   }
0119 
0120   //rescale the error at IP
0121   if (theErrorMatrixAdjuster && theAdjustAtIp) {
0122     theErrorMatrixAdjuster->adjust(fts);
0123     LogDebug(theCategory) << "after adjusting the error matrix: " << fts;
0124   }
0125 
0126   return true;
0127 }
0128 
0129 //-----------------------------------------
0130 // inside-out generator option NO pixel used
0131 //-----------------------------------------
0132 void TSGForRoadSearch::makeSeeds_0(const reco::Track &muon, std::vector<TrajectorySeed> &result) {
0133   //get the state at IP
0134   FreeTrajectoryState cIPFTS;
0135   if (!IPfts(muon, cIPFTS))
0136     return;
0137 
0138   //take state at inner surface and check the first part reached
0139   const std::vector<const BarrelDetLayer *> &blc = theGeometricSearchTracker->tibLayers();
0140   TrajectoryStateOnSurface inner =
0141       theProxyService->propagator(thePropagatorName)->propagate(cIPFTS, blc.front()->surface());
0142   if (!inner.isValid()) {
0143     LogDebug(theCategory) << "inner state is not valid. no seed.";
0144     return;
0145   }
0146 
0147   //rescale the error
0148   if (!notAtIPtsos(inner))
0149     return;
0150 
0151   double z = inner.globalPosition().z();
0152 
0153   const std::vector<const ForwardDetLayer *> &ptidc = theGeometricSearchTracker->posTidLayers();
0154   const std::vector<const ForwardDetLayer *> &ptecc = theGeometricSearchTracker->posTecLayers();
0155   const std::vector<const ForwardDetLayer *> &ntidc = theGeometricSearchTracker->negTidLayers();
0156   const std::vector<const ForwardDetLayer *> &ntecc = theGeometricSearchTracker->negTecLayers();
0157 
0158   const DetLayer *inLayer = nullptr;
0159   if (fabs(z) < ptidc.front()->surface().position().z()) {
0160     inLayer = blc.front();
0161   } else if (fabs(z) < ptecc.front()->surface().position().z()) {
0162     inLayer = (z < 0) ? ntidc.front() : ptidc.front();
0163   } else {
0164     inLayer = (z < 0) ? ntecc.front() : ptecc.front();
0165   }
0166 
0167   //find out at least one compatible detector reached
0168   std::vector<DetLayer::DetWithState> compatible;
0169   compatible.reserve(10);
0170   inLayer->compatibleDetsV(
0171       inner, *theProxyService->propagator(thePropagatorCompatibleName), *theChi2Estimator, compatible);
0172 
0173   //loop the parts until at least a compatible is found
0174   while (compatible.empty()) {
0175     switch (GeomDetEnumerators::subDetGeom[inLayer->subDetector()]) {
0176       case GeomDetEnumerators::PixelBarrel:
0177       case GeomDetEnumerators::PixelEndcap:
0178       case GeomDetEnumerators::TOB:
0179       case GeomDetEnumerators::TEC:
0180         LogDebug(theCategory) << "from inside-out, trying TEC or TOB layers. no seed.";
0181         return;
0182         break;
0183       case GeomDetEnumerators::TIB:
0184         inLayer = (z < 0) ? ntidc.front() : ptidc.front();
0185         break;
0186       case GeomDetEnumerators::TID:
0187         inLayer = (z < 0) ? ntecc.front() : ptecc.front();
0188         break;
0189       default:
0190         LogDebug(theCategory) << "subdetectorid is not a tracker sub-dectector id. skipping.";
0191         return;
0192     }
0193     inLayer->compatibleDetsV(
0194         inner, *theProxyService->propagator(thePropagatorCompatibleName), *theChi2Estimator, compatible);
0195   }
0196 
0197   pushTrajectorySeed(muon, compatible, alongMomentum, result);
0198 
0199   return;
0200 }
0201 
0202 void TSGForRoadSearch::makeSeeds_1(const reco::Track &muon, std::vector<TrajectorySeed> &result) {
0203   edm::LogError(theCategory) << "option 1 of TSGForRoadSearch is not implemented yet. Please use 0,3 or 4. no seed.";
0204   return;
0205 }
0206 
0207 void TSGForRoadSearch::makeSeeds_2(const reco::Track &muon, std::vector<TrajectorySeed> &result) {
0208   edm::LogError(theCategory) << "option 2 of TSGForRoadSearch is not implemented yet. Please use 0,3 or 4. no seed.";
0209   return;
0210 }
0211 
0212 //---------------------------------
0213 // outside-in seed generator option
0214 //---------------------------------
0215 void TSGForRoadSearch::makeSeeds_3(const reco::Track &muon, std::vector<TrajectorySeed> &result) {
0216   //get the state at IP
0217   FreeTrajectoryState cIPFTS;
0218   if (!IPfts(muon, cIPFTS))
0219     return;
0220 
0221   //take state at outer surface and check the first part reached
0222   const std::vector<const BarrelDetLayer *> &blc = theGeometricSearchTracker->tobLayers();
0223 
0224   //  TrajectoryStateOnSurface outer = theProxyService->propagator(thePropagatorName)->propagate(cIPFTS,blc.back()->surface());
0225   StateOnTrackerBound onBounds(theProxyService->propagator(thePropagatorName).product());
0226   TrajectoryStateOnSurface outer = onBounds(cIPFTS);
0227 
0228   if (!outer.isValid()) {
0229     LogDebug(theCategory) << "outer state is not valid. no seed.";
0230     return;
0231   }
0232 
0233   //rescale the error
0234   if (!notAtIPtsos(outer))
0235     return;
0236 
0237   double z = outer.globalPosition().z();
0238 
0239   const std::vector<const ForwardDetLayer *> &ptecc = theGeometricSearchTracker->posTecLayers();
0240   const std::vector<const ForwardDetLayer *> &ntecc = theGeometricSearchTracker->negTecLayers();
0241 
0242   LogDebug(theCategory) << "starting looking for a compatible layer from: " << outer << "\nz: " << z
0243                         << "TEC1 z: " << ptecc.front()->surface().position().z();
0244 
0245   unsigned int layerShift = 0;
0246   const DetLayer *inLayer = nullptr;
0247   if (fabs(z) < ptecc.front()->surface().position().z()) {
0248     inLayer = *(blc.rbegin() + layerShift);
0249     LogTrace(theCategory) << "choosing TOB layer with shift: " << layerShift;
0250   } else {
0251     unsigned int tecIt = 1;
0252     for (; tecIt != ptecc.size(); tecIt++) {
0253       LogTrace(theCategory) << "checking surface with shift: " << tecIt
0254                             << "z: " << ptecc[tecIt]->surface().position().z();
0255       if (fabs(z) < ptecc[tecIt]->surface().position().z()) {
0256         inLayer = (z < 0) ? ntecc[tecIt - 1] : ptecc[tecIt - 1];
0257         layerShift = tecIt - 1;
0258         LogTrace(theCategory) << "choosing TEC layer with shift: " << layerShift
0259                               << " and z: " << inLayer->surface().position().z();
0260         break;
0261       }
0262     }
0263     if (!inLayer) {
0264       inLayer = (z < 0) ? ntecc.back() : ptecc.back();
0265       LogTrace(theCategory) << "choosing last TEC layer with z: " << inLayer->surface().position().z();
0266     }
0267   }
0268 
0269   //find out at least one compatible detector reached
0270   std::vector<DetLayer::DetWithState> compatible;
0271   compatible.reserve(10);
0272   inLayer->compatibleDetsV(
0273       outer, *theProxyService->propagator(thePropagatorCompatibleName), *theChi2Estimator, compatible);
0274 
0275   //loop the parts until at least a compatible is found
0276   while (compatible.empty()) {
0277     switch (GeomDetEnumerators::subDetGeom[inLayer->subDetector()]) {
0278       case GeomDetEnumerators::PixelBarrel:
0279       case GeomDetEnumerators::PixelEndcap:
0280       case GeomDetEnumerators::TIB:
0281       case GeomDetEnumerators::TID:
0282       case GeomDetEnumerators::TOB:
0283         layerShift++;
0284         if (layerShift >= blc.size()) {
0285           LogDebug(theCategory) << "all barrel layers are exhausted to find starting state. no seed,";
0286           return;
0287         }
0288         inLayer = *(blc.rbegin() + layerShift);
0289         break;
0290       case GeomDetEnumerators::TEC:
0291         if (layerShift == 0) {
0292           LogDebug(theCategory) << "failed to get a compatible module on a TEC layer, using the last TOB layer.";
0293           inLayer = *(blc.rbegin() + layerShift);
0294         } else {
0295           layerShift--;
0296           LogDebug(theCategory) << "reaching more in with layer " << layerShift << " in TEC";
0297           inLayer = (z < 0) ? ntecc[layerShift] : ptecc[layerShift];
0298         }
0299         break;
0300       default:
0301         edm::LogError(theCategory) << "subdetectorid is not a tracker sub-dectector id. skipping.";
0302         return;
0303     }
0304     inLayer->compatibleDetsV(
0305         outer, *theProxyService->propagator(thePropagatorCompatibleName), *theChi2Estimator, compatible);
0306   }
0307 
0308   pushTrajectorySeed(muon, compatible, oppositeToMomentum, result);
0309 
0310   return;
0311 }
0312 
0313 //-----------------------------------------
0314 // inside-out generator option, using pixel
0315 //-----------------------------------------
0316 void TSGForRoadSearch::makeSeeds_4(const reco::Track &muon, std::vector<TrajectorySeed> &result) {
0317   //get the state at IP
0318   FreeTrajectoryState cIPFTS;
0319   if (!IPfts(muon, cIPFTS))
0320     return;
0321 
0322   //take state at inner surface and check the first part reached
0323   const std::vector<const BarrelDetLayer *> &blc = theGeometricSearchTracker->pixelBarrelLayers();
0324   if (blc.empty()) {
0325     edm::LogError(theCategory) << "want to start from pixel layer, but no barrel exists. trying without pixel.";
0326     makeSeeds_0(muon, result);
0327     return;
0328   }
0329 
0330   TrajectoryStateOnSurface inner =
0331       theProxyService->propagator(thePropagatorName)->propagate(cIPFTS, blc.front()->surface());
0332   if (!inner.isValid()) {
0333     LogDebug(theCategory) << "inner state is not valid. no seed.";
0334     return;
0335   }
0336 
0337   //rescale the error
0338   if (!notAtIPtsos(inner))
0339     return;
0340 
0341   double z = inner.globalPosition().z();
0342 
0343   const std::vector<const ForwardDetLayer *> &ppxlc = theGeometricSearchTracker->posPixelForwardLayers();
0344   const std::vector<const ForwardDetLayer *> &npxlc = theGeometricSearchTracker->negPixelForwardLayers();
0345   const std::vector<const ForwardDetLayer *> &ptidc = theGeometricSearchTracker->posTidLayers();
0346   const std::vector<const ForwardDetLayer *> &ptecc = theGeometricSearchTracker->posTecLayers();
0347   const std::vector<const ForwardDetLayer *> &ntidc = theGeometricSearchTracker->negTidLayers();
0348   const std::vector<const ForwardDetLayer *> &ntecc = theGeometricSearchTracker->negTecLayers();
0349 
0350   if ((ppxlc.empty() || npxlc.empty()) && (ptidc.empty() || ptecc.empty())) {
0351     edm::LogError(theCategory) << "want to start from pixel layer, but no forward layer exists. trying without pixel.";
0352     makeSeeds_0(muon, result);
0353     return;
0354   }
0355 
0356   const DetLayer *inLayer = nullptr;
0357   std::vector<const ForwardDetLayer *>::const_iterator layerIt;
0358 
0359   double fz = fabs(z);
0360 
0361   //simple way of finding a first layer to try out
0362   if (fz < fabs(((z > 0) ? ppxlc : npxlc).front()->surface().position().z())) {
0363     inLayer = blc.front();
0364   } else if (fz < fabs(((z > 0) ? ppxlc : npxlc).back()->surface().position().z())) {
0365     layerIt = ((z > 0) ? ppxlc : npxlc).begin();
0366     inLayer = *layerIt;
0367   } else if (fz < fabs(((z > 0) ? ptidc : ntidc).front()->surface().position().z())) {
0368     layerIt = ((z > 0) ? ppxlc : npxlc).end() - 1;
0369     inLayer = *layerIt;
0370   } else if (fz < fabs(((z > 0) ? ptecc : ntecc).front()->surface().position().z())) {
0371     layerIt = ((z > 0) ? ptidc : ntidc).begin();
0372     inLayer = *layerIt;
0373   } else if (fz < fabs(((z > 0) ? ptecc : ntecc).back()->surface().position().z())) {
0374     layerIt = ((z > 0) ? ptecc : ntecc).begin();
0375     inLayer = *layerIt;
0376   } else {
0377     edm::LogWarning(theCategory) << "the state is not consistent with any tracker layer:\n" << inner;
0378     return;
0379   }
0380 
0381   //find out at least one compatible detector reached
0382   std::vector<DetLayer::DetWithState> compatible;
0383   compatible.reserve(10);
0384   inLayer->compatibleDetsV(
0385       inner, *theProxyService->propagator(thePropagatorCompatibleName), *theChi2Estimator, compatible);
0386 
0387   //if none were found. you should do something more.
0388   if (compatible.empty()) {
0389     std::vector<const ForwardDetLayer *>::const_iterator pxlEnd = (z > 0) ? ppxlc.end() : npxlc.end();
0390     std::vector<const ForwardDetLayer *>::const_iterator tidEnd = (z > 0) ? ptidc.end() : ntidc.end();
0391     std::vector<const ForwardDetLayer *>::const_iterator tecEnd = (z > 0) ? ptecc.end() : ntecc.end();
0392     std::vector<const ForwardDetLayer *>::const_iterator pxlBegin = (z > 0) ? ppxlc.begin() : npxlc.begin();
0393     std::vector<const ForwardDetLayer *>::const_iterator tidBegin = (z > 0) ? ptidc.begin() : ntidc.begin();
0394     std::vector<const ForwardDetLayer *>::const_iterator tecBegin = (z > 0) ? ptecc.begin() : ntecc.begin();
0395 
0396     //go to first disk if not already in a disk situation
0397     if (!dynamic_cast<const ForwardDetLayer *>(inLayer))
0398       layerIt = pxlBegin--;
0399 
0400     while (compatible.empty()) {
0401       switch (GeomDetEnumerators::subDetGeom[(*layerIt)->subDetector()]) {
0402         case GeomDetEnumerators::PixelEndcap: {
0403           layerIt++;
0404           //if end of list reached. go to the first TID
0405           if (layerIt == pxlEnd)
0406             layerIt = tidBegin;
0407           break;
0408         }
0409         case GeomDetEnumerators::TID: {
0410           layerIt++;
0411           //if end of list reached. go to the first TEC
0412           if (layerIt == tidEnd)
0413             layerIt = tecBegin;
0414           break;
0415         }
0416         case GeomDetEnumerators::TEC: {
0417           layerIt++;
0418           if (layerIt == tecEnd) {
0419             edm::LogWarning(theCategory) << "ran out of layers to find a seed: no seed.";
0420             return;
0421           }
0422           break;
0423         }
0424         case GeomDetEnumerators::PixelBarrel: {
0425           edm::LogError(theCategory)
0426               << "this should not happen... ever. Please report. GeomDetEnumerators::PixelBarrel. no seed.";
0427           return;
0428         }
0429         case GeomDetEnumerators::TIB: {
0430           edm::LogError(theCategory)
0431               << "this should not happen... ever. Please report. GeomDetEnumerators::TIB. no seed.";
0432           return;
0433         }
0434         case GeomDetEnumerators::TOB: {
0435           edm::LogError(theCategory)
0436               << "this should not happen... ever. Please report. GeomDetEnumerators::TOB. no seed.";
0437           return;
0438         }
0439         default: {
0440           edm::LogError(theCategory) << "Subdetector id is not a tracker sub-detector id. no seed.";
0441           return;
0442         }
0443       }  //switch
0444 
0445       (*layerIt)->compatibleDetsV(
0446           inner, *theProxyService->propagator(thePropagatorCompatibleName), *theChi2Estimator, compatible);
0447     }  //while
0448   }  //if size==0
0449 
0450   pushTrajectorySeed(muon, compatible, alongMomentum, result);
0451 
0452   return;
0453 }
0454 
0455 #include <TrackingTools/PatternTools/interface/TrajectoryMeasurement.h>
0456 #include <TrackingTools/MeasurementDet/interface/MeasurementDet.h>
0457 
0458 void TSGForRoadSearch::pushTrajectorySeed(const reco::Track &muon,
0459                                           std::vector<DetLayer::DetWithState> &compatible,
0460                                           PropagationDirection direction,
0461                                           std::vector<TrajectorySeed> &result) const {
0462   if (compatible.empty()) {
0463     LogDebug(theCategory) << "pushTrajectorySeed with no compatible module. 0 seed.";
0464     return;
0465   }
0466 
0467   if (theManySeeds) {
0468     //finf out every compatible measurements
0469     for (std::vector<DetLayer::DetWithState>::iterator DWSit = compatible.begin(); DWSit != compatible.end(); ++DWSit) {
0470       bool aBareTS = false;
0471       const GeomDet *gd = DWSit->first;
0472       if (!gd) {
0473         edm::LogError(theCategory) << "GeomDet is not valid.";
0474         continue;
0475       }
0476       MeasurementDetWithData md = theMeasurementTrackerEvent->idToDet(gd->geographicalId());
0477       std::vector<TrajectoryMeasurement> tmp = md.fastMeasurements(
0478           DWSit->second, DWSit->second, *theProxyService->propagator(thePropagatorCompatibleName), *theChi2Estimator);
0479       //make a trajectory seed for each of them
0480 
0481       for (std::vector<TrajectoryMeasurement>::iterator Mit = tmp.begin(); Mit != tmp.end(); ++Mit) {
0482         TrajectoryStateOnSurface predState(Mit->predictedState());
0483         TrajectoryMeasurement::ConstRecHitPointer hit = Mit->recHit();
0484         TrajectorySeed::RecHitContainer rhContainer;
0485         if (theCopyMuonRecHit) {
0486           LogDebug(theCategory) << "copying (" << muon.recHitsSize() << ") muon recHits";
0487           //copy the muon rechit into the seed
0488           for (trackingRecHit_iterator trit = muon.recHitsBegin(); trit != muon.recHitsEnd(); trit++) {
0489             rhContainer.push_back((*trit)->clone());
0490           }
0491         }
0492 
0493         if (hit->isValid()) {
0494           TrajectoryStateOnSurface upState(theUpdator->update(predState, *hit));
0495 
0496           PTrajectoryStateOnDet const &PTSOD =
0497               trajectoryStateTransform::persistentState(upState, gd->geographicalId().rawId());
0498           LogDebug(theCategory) << "state used to build a trajectory seed: \n"
0499                                 << upState << "on detector: " << gd->geographicalId().rawId();
0500           //add the tracking rechit
0501           if (theCopyMuonRecHit) {
0502             edm::LogError(theCategory) << "not a bare seed and muon hits are copied. dumping the muon hits.";
0503             rhContainer.clear();
0504           }
0505           rhContainer.push_back(hit->hit()->clone());
0506 
0507           result.push_back(TrajectorySeed(PTSOD, rhContainer, direction));
0508         } else {
0509           //rec hit is not valid. put a bare TrajectorySeed, only once !
0510           if (!aBareTS) {
0511             aBareTS = true;
0512 
0513             PTrajectoryStateOnDet const &PTSOD =
0514                 trajectoryStateTransform::persistentState(predState, gd->geographicalId().rawId());
0515             LogDebug(theCategory) << "state used to build a bare trajectory seed: \n"
0516                                   << predState << "on detector: " << gd->geographicalId().rawId();
0517 
0518             result.push_back(TrajectorySeed(PTSOD, rhContainer, direction));
0519           }
0520         }
0521       }
0522     }
0523   } else {
0524     //transform it into a PTrajectoryStateOnDet
0525 
0526     PTrajectoryStateOnDet const &PTSOD = trajectoryStateTransform::persistentState(
0527         compatible.front().second, compatible.front().first->geographicalId().rawId());
0528     LogDebug(theCategory) << "state used to build a bare trajectory seed: \n"
0529                           << compatible.front().second
0530                           << "on detector: " << compatible.front().first->geographicalId().rawId();
0531 
0532     TrajectorySeed::RecHitContainer rhContainer;
0533     if (theCopyMuonRecHit) {
0534       LogDebug(theCategory) << "copying (" << muon.recHitsSize() << ") muon recHits";
0535       //copy the muon rechit into the seed
0536       for (trackingRecHit_iterator trit = muon.recHitsBegin(); trit != muon.recHitsEnd(); trit++) {
0537         rhContainer.push_back((*trit)->clone());
0538       }
0539     }
0540 
0541     //add this seed to the list and return it
0542     result.push_back(TrajectorySeed(PTSOD, rhContainer, direction));
0543   }
0544   return;
0545 }