CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/RecoMuon/MuonSeedGenerator/src/MuonSeedBuilder.cc

Go to the documentation of this file.
00001 
00008 #include <RecoMuon/MuonSeedGenerator/src/MuonSeedBuilder.h>
00009 #include <RecoMuon/MuonSeedGenerator/src/MuonSeedCreator.h>
00010 #include <RecoMuon/MuonSeedGenerator/src/MuonSeedCleaner.h>
00011 
00012 // Data Formats 
00013 #include <DataFormats/TrajectorySeed/interface/TrajectorySeedCollection.h>
00014 #include <DataFormats/TrajectorySeed/interface/TrajectorySeed.h>
00015 #include <DataFormats/CSCRecHit/interface/CSCRecHit2DCollection.h>
00016 #include <DataFormats/CSCRecHit/interface/CSCRecHit2D.h>
00017 #include <DataFormats/CSCRecHit/interface/CSCSegmentCollection.h>
00018 #include <DataFormats/CSCRecHit/interface/CSCSegment.h>
00019 #include <DataFormats/DTRecHit/interface/DTRecSegment4DCollection.h>
00020 #include <DataFormats/DTRecHit/interface/DTRecSegment4D.h>
00021 
00022 // Geometry
00023 #include <Geometry/CommonDetUnit/interface/GeomDet.h>
00024 #include <TrackingTools/DetLayers/interface/DetLayer.h>
00025 #include <RecoMuon/MeasurementDet/interface/MuonDetLayerMeasurements.h>
00026 #include <RecoMuon/DetLayers/interface/MuonDetLayerGeometry.h>
00027 #include <RecoMuon/Records/interface/MuonRecoGeometryRecord.h>
00028 
00029 // muon service
00030 #include <TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h>
00031 #include <DataFormats/TrajectoryState/interface/PTrajectoryStateOnDet.h>
00032 
00033 // Framework
00034 #include <FWCore/ParameterSet/interface/ParameterSet.h>
00035 #include "FWCore/Framework/interface/Event.h"
00036 #include <FWCore/Framework/interface/ESHandle.h>
00037 #include <FWCore/MessageLogger/interface/MessageLogger.h> 
00038 #include <DataFormats/Common/interface/Handle.h>
00039 
00040 // C++
00041 #include <vector>
00042 #include <deque>
00043 #include <utility>
00044 
00045 //typedef std::pair<double, TrajectorySeed> seedpr ;
00046 //static bool ptDecreasing(const seedpr s1, const seedpr s2) { return ( s1.first > s2.first ); }
00047 //static bool lengthSorting(const TrajectorySeed s1, const TrajectorySeed s2) { return ( s1.nHits() > s2.nHits() ); }
00048 
00049 /*
00050  * Constructor
00051  */
00052 MuonSeedBuilder::MuonSeedBuilder(const edm::ParameterSet& pset){
00053 
00054   // Local Debug flag
00055   debug                = pset.getParameter<bool>("DebugMuonSeed");
00056 
00057   // enable the DT chamber
00058   enableDTMeasurement  = pset.getParameter<bool>("EnableDTMeasurement");
00059   theDTSegmentLabel    = pset.getParameter<edm::InputTag>("DTSegmentLabel");
00060 
00061   // enable the CSC chamber
00062   enableCSCMeasurement = pset.getParameter<bool>("EnableCSCMeasurement");
00063   theCSCSegmentLabel   = pset.getParameter<edm::InputTag>("CSCSegmentLabel");
00064 
00065   // Parameters for seed creation in endcap region
00066   minCSCHitsPerSegment = pset.getParameter<int>("minCSCHitsPerSegment");
00067   maxDeltaEtaCSC       = pset.getParameter<double>("maxDeltaEtaCSC");
00068   maxDeltaPhiCSC       = pset.getParameter<double>("maxDeltaPhiCSC");
00069 
00070   // Parameters for seed creation in overlap region
00071   maxDeltaEtaOverlap   = pset.getParameter<double>("maxDeltaEtaOverlap");
00072   maxDeltaPhiOverlap   = pset.getParameter<double>("maxDeltaPhiOverlap");
00073 
00074   // Parameters for seed creation in barrel region
00075   minDTHitsPerSegment  = pset.getParameter<int>("minDTHitsPerSegment");
00076   maxDeltaEtaDT        = pset.getParameter<double>("maxDeltaEtaDT");
00077   maxDeltaPhiDT        = pset.getParameter<double>("maxDeltaPhiDT");
00078 
00079   // Parameters to suppress combinatorics (ghosts)
00080   maxEtaResolutionDT   = pset.getParameter<double>("maxEtaResolutionDT"); 
00081   maxPhiResolutionDT   = pset.getParameter<double>("maxPhiResolutionDT"); 
00082   maxEtaResolutionCSC  = pset.getParameter<double>("maxEtaResolutionCSC"); 
00083   maxPhiResolutionCSC  = pset.getParameter<double>("maxPhiResolutionCSC"); 
00084 
00085   // muon service
00086   edm::ParameterSet serviceParameters = pset.getParameter<edm::ParameterSet>("ServiceParameters");
00087   theService        = new MuonServiceProxy(serviceParameters);
00088 
00089   // Class for forming muon seeds
00090   muonSeedCreate_   = new MuonSeedCreator( pset ); 
00091   muonSeedClean_    = new MuonSeedCleaner( pset ); 
00092 
00093 }
00094 
00095 /*
00096  * Destructor
00097  */
00098 MuonSeedBuilder::~MuonSeedBuilder(){
00099 
00100   delete muonSeedCreate_;
00101   delete muonSeedClean_;
00102   if (theService) delete theService;
00103 }
00104 
00105 /* 
00106  * build
00107  *
00108  * Where the segments are sorted out to make a protoTrack (vector of matching segments in different 
00109  * stations/layers).  The protoTrack is then passed to the seed creator to create CSC, DT or overlap seeds
00110  *
00111  */
00112 //void MuonSeedBuilder::build( MuonDetLayerMeasurements muonMeasurements, TrajectorySeedCollection& theSeeds ) {
00113 int MuonSeedBuilder::build( edm::Event& event, const edm::EventSetup& eventSetup, TrajectorySeedCollection& theSeeds ) {
00114 
00115 
00116   // Pass the Magnetic Field to where the seed is create
00117   muonSeedCreate_->setBField(BField);
00118 
00119   // Create temporary collection of seeds which will be cleaned up to remove combinatorics
00120   std::vector<TrajectorySeed> rawSeeds;
00121   std::vector<float> etaOfSeed;
00122   std::vector<float> phiOfSeed;
00123   std::vector<int> nSegOnSeed;
00124 
00125  // Instantiate the accessor (get the segments: DT + CSC but not RPC=false)
00126   MuonDetLayerMeasurements muonMeasurements(theDTSegmentLabel,theCSCSegmentLabel,edm::InputTag(),
00127                                             enableDTMeasurement,enableCSCMeasurement,false);
00128 
00129  // Instantiate the accessor (get the segments: DT + CSC but not RPC=false)
00130  // MuonDetLayerMeasurements muonMeasurements(enableDTMeasurement,enableCSCMeasurement,false,
00131  //                                          theDTSegmentLabel.label(),theCSCSegmentLabel.label());
00132 
00133 
00134   // 1) Get the various stations and store segments in containers for each station (layers)
00135  
00136   // 1a. get the DT segments by stations (layers):
00137   std::vector<DetLayer*> dtLayers = muonLayers->allDTLayers();
00138  
00139   SegmentContainer DTlist4 = muonMeasurements.recHits( dtLayers[3], event );
00140   SegmentContainer DTlist3 = muonMeasurements.recHits( dtLayers[2], event );
00141   SegmentContainer DTlist2 = muonMeasurements.recHits( dtLayers[1], event );
00142   SegmentContainer DTlist1 = muonMeasurements.recHits( dtLayers[0], event );
00143 
00144   // Initialize flags that a given segment has been allocated to a seed
00145   BoolContainer usedDTlist4(DTlist4.size(), false);
00146   BoolContainer usedDTlist3(DTlist3.size(), false);
00147   BoolContainer usedDTlist2(DTlist2.size(), false);
00148   BoolContainer usedDTlist1(DTlist1.size(), false);
00149 
00150   if (debug) {
00151     std::cout << "*** Number of DT segments is: " << DTlist4.size()+DTlist3.size()+DTlist2.size()+DTlist1.size() << std::endl;
00152     std::cout << "In MB1: " << DTlist1.size() << std::endl;
00153     std::cout << "In MB2: " << DTlist2.size() << std::endl;
00154     std::cout << "In MB3: " << DTlist3.size() << std::endl;
00155     std::cout << "In MB4: " << DTlist4.size() << std::endl;
00156   }
00157 
00158   // 1b. get the CSC segments by stations (layers):
00159   // 1b.1 Global z < 0
00160   std::vector<DetLayer*> cscBackwardLayers = muonLayers->backwardCSCLayers();    
00161   SegmentContainer CSClist4B = muonMeasurements.recHits( cscBackwardLayers[4], event );
00162   SegmentContainer CSClist3B = muonMeasurements.recHits( cscBackwardLayers[3], event );
00163   SegmentContainer CSClist2B = muonMeasurements.recHits( cscBackwardLayers[2], event );
00164   SegmentContainer CSClist1B = muonMeasurements.recHits( cscBackwardLayers[1], event ); // ME1/2 and 1/3
00165   SegmentContainer CSClist0B = muonMeasurements.recHits( cscBackwardLayers[0], event ); // ME11
00166 
00167   BoolContainer usedCSClist4B(CSClist4B.size(), false);
00168   BoolContainer usedCSClist3B(CSClist3B.size(), false);
00169   BoolContainer usedCSClist2B(CSClist2B.size(), false);
00170   BoolContainer usedCSClist1B(CSClist1B.size(), false);
00171   BoolContainer usedCSClist0B(CSClist0B.size(), false);
00172 
00173   // 1b.2 Global z > 0
00174   std::vector<DetLayer*> cscForwardLayers = muonLayers->forwardCSCLayers();
00175   SegmentContainer CSClist4F = muonMeasurements.recHits( cscForwardLayers[4], event );
00176   SegmentContainer CSClist3F = muonMeasurements.recHits( cscForwardLayers[3], event );
00177   SegmentContainer CSClist2F = muonMeasurements.recHits( cscForwardLayers[2], event );
00178   SegmentContainer CSClist1F = muonMeasurements.recHits( cscForwardLayers[1], event );
00179   SegmentContainer CSClist0F = muonMeasurements.recHits( cscForwardLayers[0], event );
00180 
00181   BoolContainer usedCSClist4F(CSClist4F.size(), false);
00182   BoolContainer usedCSClist3F(CSClist3F.size(), false);
00183   BoolContainer usedCSClist2F(CSClist2F.size(), false);
00184   BoolContainer usedCSClist1F(CSClist1F.size(), false);
00185   BoolContainer usedCSClist0F(CSClist0F.size(), false);
00186 
00187   if (debug) {
00188     std::cout << "*** Number of CSC segments is " << CSClist4F.size()+CSClist3F.size()+CSClist2F.size()+CSClist1F.size()+CSClist0F.size()+CSClist4B.size()+CSClist3B.size()+CSClist2B.size()+CSClist1B.size()+CSClist0B.size()<< std::endl;
00189     std::cout << "In ME11: " << CSClist0F.size()+CSClist0B.size() << std::endl;
00190     std::cout << "In ME12: " << CSClist1F.size()+CSClist1B.size() << std::endl;
00191     std::cout << "In ME2 : " << CSClist2F.size()+CSClist2B.size() << std::endl;
00192     std::cout << "In ME3 : " << CSClist3F.size()+CSClist3B.size() << std::endl;
00193     std::cout << "In ME4 : " << CSClist4F.size()+CSClist4B.size() << std::endl;
00194   }
00195 
00196 
00197   /* ******************************************************************************************************************
00198    * Form seeds in barrel region
00199    *
00200    * Proceed from inside -> out
00201    * ******************************************************************************************************************/
00202 
00203 
00204   // Loop over all possible MB1 segment to form seeds:
00205   int index = -1;
00206   for (SegmentContainer::iterator it = DTlist1.begin(); it != DTlist1.end(); ++it ){
00207 
00208     index++;
00209 
00210     if (usedDTlist1[index] == true) continue;
00211     if ( int ((*it)->recHits().size()) < minDTHitsPerSegment ) continue;
00212     if ((*it)->dimension() != 4) continue;
00213 
00214     //double dof = static_cast<double>( (*it)->degreesOfFreedom() ) ;
00215     //if ( ((*it)->chi2()/dof) > 20000.0 ) continue;
00216     
00217     // Global position of starting point for protoTrack
00218     GlobalPoint gp = (*it)->globalPosition();
00219     float eta_temp = gp.eta();
00220     float phi_temp = gp.phi();
00221     bool showeringBefore = false;
00222     NShowerSeg = 0; 
00223     if ( IdentifyShowering( DTlist1, usedDTlist1, eta_temp, phi_temp, -1, NShowerSeg )  ) showeringBefore = true ;
00224     int NShowers = 0; 
00225     if ( showeringBefore ) {
00226         //usedDTlist1[index] = true;
00227         NShowers++ ;
00228     }
00229      
00230     SegmentContainer protoTrack;
00231     protoTrack.push_back(*it);
00232 
00233     std::vector<int> layers;
00234     layers.push_back(-1);
00235 
00236     // Try adding segment from other stations
00237     if (foundMatchingSegment(3, protoTrack, DTlist2, usedDTlist2, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(-2);
00238     if ( showeringBefore )  NShowers++ ;
00239     if (foundMatchingSegment(3, protoTrack, DTlist3, usedDTlist3, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(-3);
00240     if ( showeringBefore )  NShowers++ ;
00241     if (foundMatchingSegment(3, protoTrack, DTlist4, usedDTlist4, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(-4);
00242     if ( showeringBefore )  NShowers++ ;
00243 
00244     // Check if in overlap region
00245     if (eta_temp > 0.8) {
00246       if (foundMatchingSegment(2, protoTrack, CSClist1F, usedCSClist1F, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(1);
00247       if ( showeringBefore )  NShowers++ ;
00248       if (foundMatchingSegment(2, protoTrack, CSClist2F, usedCSClist2F, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(2);
00249       if ( showeringBefore )  NShowers++ ;
00250       if (foundMatchingSegment(2, protoTrack, CSClist3F, usedCSClist3F, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(3);
00251       if ( showeringBefore )  NShowers++ ;
00252     } 
00253     else if (eta_temp < -0.8) {
00254       if (foundMatchingSegment(2, protoTrack, CSClist1B, usedCSClist1B, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(1);
00255       if ( showeringBefore )  NShowers++ ;
00256       if (foundMatchingSegment(2, protoTrack, CSClist2B, usedCSClist2B, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(2);
00257       if ( showeringBefore )  NShowers++ ;
00258       if (foundMatchingSegment(2, protoTrack, CSClist3B, usedCSClist3B, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(3);
00259       if ( showeringBefore )  NShowers++ ;
00260     }
00261  
00262 
00263     // adding showering information   
00264     if ( layers.size() < 2 && ShoweringSegments.size() > 0 ) {
00265        for (size_t i=0; i< ShoweringSegments.size(); i++) {
00266            if ( ShoweringLayers[i] > 0 ) {
00267               if ( ShoweringLayers[i] <= layers[ layers.size()-1] ) continue;
00268               protoTrack.push_back( ShoweringSegments[i] );
00269               layers.push_back( ShoweringLayers[i] );
00270            }
00271            if ( ShoweringLayers[i] < 0 && layers[ layers.size()-1] < 0 ) {
00272               if ( ShoweringLayers[i] >= layers[ layers.size()-1] ) continue;
00273               protoTrack.push_back( ShoweringSegments[i] );
00274               layers.push_back( ShoweringLayers[i] );
00275            }
00276        }
00277     }
00278     ShoweringSegments.clear() ;  
00279     ShoweringLayers.clear() ;  
00280 
00281     TrajectorySeed thisSeed;
00282 
00283     if (  layers.size() < 2 ) {
00284         thisSeed = muonSeedCreate_->createSeed(4, protoTrack, layers, NShowers, NShowerSeg );
00285     } else {
00286       if ( layers[ layers.size()-1] > 0 ) {
00287         thisSeed = muonSeedCreate_->createSeed(2, protoTrack, layers, NShowers, NShowerSeg );
00288       } else {
00289         thisSeed = muonSeedCreate_->createSeed(3, protoTrack, layers, NShowers, NShowerSeg ); 
00290       }
00291     }
00292     // Add the seeds to master collection
00293     rawSeeds.push_back(thisSeed); 
00294     etaOfSeed.push_back(eta_temp);
00295     phiOfSeed.push_back(phi_temp);
00296     nSegOnSeed.push_back( protoTrack.size() );
00297 
00298     // Marked segment as used
00299     usedDTlist1[index] = true;
00300   }
00301 
00302 
00303   // Loop over all possible MB2 segment to form seeds:
00304   index = -1;
00305   for (SegmentContainer::iterator it = DTlist2.begin(); it != DTlist2.end(); ++it ){
00306 
00307     index++;
00308 
00309     if (usedDTlist2[index] == true) continue;
00310     if ( int ((*it)->recHits().size()) < minDTHitsPerSegment ) continue;  
00311     if ((*it)->dimension() != 4) continue;
00312 
00313     //double dof = static_cast<double>( (*it)->degreesOfFreedom() ) ;
00314     //if ( ((*it)->chi2()/dof) > 20000.0 ) continue;
00315 
00316     // Global position of starting point for protoTrack
00317     GlobalPoint gp = (*it)->globalPosition();
00318     float eta_temp = gp.eta();
00319     float phi_temp = gp.phi();
00320     bool showeringBefore = false; 
00321     NShowerSeg = 0; 
00322     if ( IdentifyShowering( DTlist2, usedDTlist2, eta_temp, phi_temp, -2, NShowerSeg)  ) showeringBefore = true ;
00323     int NShowers = 0; 
00324     if ( showeringBefore ) {
00325        // usedDTlist2[index] = true;
00326         NShowers++ ;
00327     }
00328 
00329     SegmentContainer protoTrack;
00330     protoTrack.push_back(*it);
00331 
00332     std::vector<int> layers;
00333     layers.push_back(-2);
00334 
00335  
00336     // Try adding segment from other stations
00337     if (foundMatchingSegment(3, protoTrack, DTlist3, usedDTlist3, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(-3);
00338     if ( showeringBefore )  NShowers++ ;
00339     if (foundMatchingSegment(3, protoTrack, DTlist4, usedDTlist4, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(-4);
00340     if ( showeringBefore )  NShowers++ ;
00341 
00342     // Check if in overlap region
00343     if (eta_temp > 0.8) {
00344       if (foundMatchingSegment(2, protoTrack, CSClist1F, usedCSClist1F, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(1);
00345       if ( showeringBefore )  NShowers++ ;
00346       if (foundMatchingSegment(2, protoTrack, CSClist2F, usedCSClist2F, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(2);
00347       if ( showeringBefore )  NShowers++ ;
00348       if (foundMatchingSegment(2, protoTrack, CSClist3F, usedCSClist3F, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(3);
00349       if ( showeringBefore )  NShowers++ ;
00350     }
00351     else if (eta_temp < -0.8) {
00352       if (foundMatchingSegment(2, protoTrack, CSClist1B, usedCSClist1B, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(1);
00353       if ( showeringBefore )  NShowers++ ;
00354       if (foundMatchingSegment(2, protoTrack, CSClist2B, usedCSClist2B, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(2);
00355       if ( showeringBefore )  NShowers++ ;
00356       if (foundMatchingSegment(2, protoTrack, CSClist3B, usedCSClist3B, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(3);
00357       if ( showeringBefore )  NShowers++ ;
00358     }
00359 
00360     // adding showering information   
00361     if ( layers.size() < 2 && ShoweringSegments.size() > 0 ) {
00362        for (size_t i=0; i< ShoweringSegments.size(); i++) {
00363          if ( ShoweringLayers[i] > 0 ) {
00364             if ( ShoweringLayers[i] <= layers[ layers.size()-1] ) continue;
00365             protoTrack.push_back( ShoweringSegments[i] );
00366             layers.push_back( ShoweringLayers[i] );
00367          }
00368          if ( ShoweringLayers[i] < 0 && layers[ layers.size()-1] < 0 ) {
00369             if ( ShoweringLayers[i] >= layers[ layers.size()-1] ) continue;
00370             protoTrack.push_back( ShoweringSegments[i] );
00371             layers.push_back( ShoweringLayers[i] );
00372          }
00373        }
00374     }
00375     ShoweringSegments.clear() ;  
00376     ShoweringLayers.clear() ;  
00377 
00378   
00379     TrajectorySeed thisSeed;
00380 
00381     if ( layers.size() < 2 ) {
00382         thisSeed = muonSeedCreate_->createSeed(4, protoTrack, layers, NShowers, NShowerSeg );
00383     } else {
00384       if ( layers[ layers.size()-1] > 0 ) {
00385         thisSeed = muonSeedCreate_->createSeed(2, protoTrack, layers, NShowers, NShowerSeg );
00386       } else {
00387         thisSeed = muonSeedCreate_->createSeed(3, protoTrack, layers, NShowers, NShowerSeg ); 
00388       }
00389     }
00390     // Add the seeds to master collection
00391     rawSeeds.push_back(thisSeed); 
00392     etaOfSeed.push_back(eta_temp);
00393     phiOfSeed.push_back(phi_temp);
00394     nSegOnSeed.push_back( protoTrack.size() );
00395 
00396     // Marked segment as used
00397     usedDTlist2[index] = true;
00398   }
00399 
00400 
00401   // Loop over all possible MB3 segment to form seeds:
00402   index = -1;
00403   for (SegmentContainer::iterator it = DTlist3.begin(); it != DTlist3.end(); ++it ){
00404 
00405     index++;
00406 
00407     if (usedDTlist3[index] == true) continue;
00408     if ( int ((*it)->recHits().size()) < minDTHitsPerSegment ) continue;  
00409     if ((*it)->dimension() != 4) continue;
00410 
00411     //double dof = static_cast<double>( (*it)->degreesOfFreedom() ) ;
00412     //if ( ((*it)->chi2()/dof) > 20000.0 ) continue;
00413 
00414     // Global position of starting point for protoTrack
00415     GlobalPoint gp = (*it)->globalPosition();
00416     float eta_temp = gp.eta();
00417     float phi_temp = gp.phi();
00418     bool showeringBefore = false; 
00419     NShowerSeg = 0; 
00420     if ( IdentifyShowering( DTlist3, usedDTlist3, eta_temp, phi_temp, -3, NShowerSeg)  ) showeringBefore = true ;
00421     int NShowers = 0; 
00422     if ( showeringBefore ) {
00423        // usedDTlist3[index] = true;
00424         NShowers++ ;
00425     }
00426 
00427     SegmentContainer protoTrack;
00428     protoTrack.push_back(*it);
00429 
00430     std::vector<int> layers;
00431     layers.push_back(-3);
00432  
00433     // Try adding segment from other stations
00434     if (foundMatchingSegment(3, protoTrack, DTlist4, usedDTlist4, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(-4);
00435     if ( showeringBefore )  NShowers++ ;
00436 
00437     // Check if in overlap region
00438     if (eta_temp > 0.8) {
00439       if (foundMatchingSegment(2, protoTrack, CSClist1F, usedCSClist1F, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(1);
00440       if ( showeringBefore )  NShowers++ ;
00441       if (foundMatchingSegment(2, protoTrack, CSClist2F, usedCSClist2F, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(2);
00442       if ( showeringBefore )  NShowers++ ;
00443       if (foundMatchingSegment(2, protoTrack, CSClist3F, usedCSClist3F, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(3);
00444       if ( showeringBefore )  NShowers++ ;
00445     }
00446     else if (eta_temp < -0.8) {
00447       if (foundMatchingSegment(2, protoTrack, CSClist1B, usedCSClist1B, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(1);
00448       if ( showeringBefore )  NShowers++ ;
00449       if (foundMatchingSegment(2, protoTrack, CSClist2B, usedCSClist2B, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(2);
00450       if ( showeringBefore )  NShowers++ ;
00451       if (foundMatchingSegment(2, protoTrack, CSClist3B, usedCSClist3B, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(3);
00452       if ( showeringBefore )  NShowers++ ;
00453     }
00454     
00455     // adding showering information   
00456     if ( layers.size() < 2 && ShoweringSegments.size() > 0 ) {
00457        for (size_t i=0; i< ShoweringSegments.size(); i++) {
00458           if ( ShoweringLayers[i] > 0 ) {
00459              if ( ShoweringLayers[i] <= layers[ layers.size()-1] ) continue;
00460              protoTrack.push_back( ShoweringSegments[i] );
00461              layers.push_back( ShoweringLayers[i] );
00462           }
00463           if ( ShoweringLayers[i] < 0 && layers[ layers.size()-1] < 0 ) {
00464              if ( ShoweringLayers[i] >= layers[ layers.size()-1] ) continue;
00465              protoTrack.push_back( ShoweringSegments[i] );
00466              layers.push_back( ShoweringLayers[i] );
00467           }
00468        }
00469     }
00470     ShoweringSegments.clear() ;  
00471     ShoweringLayers.clear() ;  
00472 
00473     
00474     TrajectorySeed thisSeed;
00475     if ( layers.size() < 2 ) {
00476         thisSeed = muonSeedCreate_->createSeed(4, protoTrack, layers, NShowers, NShowerSeg );
00477     }else {
00478       if ( layers[ layers.size()-1] > 0 ) {
00479         thisSeed = muonSeedCreate_->createSeed(2, protoTrack, layers, NShowers, NShowerSeg );
00480       } else {
00481         thisSeed = muonSeedCreate_->createSeed(3, protoTrack, layers, NShowers, NShowerSeg ); 
00482       }
00483     }
00484 
00485     // Add the seeds to master collection
00486     rawSeeds.push_back(thisSeed); 
00487     etaOfSeed.push_back(eta_temp);
00488     phiOfSeed.push_back(phi_temp);
00489     nSegOnSeed.push_back( protoTrack.size() );
00490 
00491     // Marked segment as used
00492     usedDTlist3[index] = true;
00493   }
00494 
00495   /* *********************************************************************************************************************
00496    * Form seeds from backward endcap
00497    *
00498    * Proceed from inside -> out
00499    * *********************************************************************************************************************/
00500 
00501   // Loop over all possible ME11 segment to form seeds:
00502   index = -1;
00503 
00504   for (SegmentContainer::iterator it = CSClist0B.begin(); it != CSClist0B.end(); ++it ){
00505 
00506     index++;
00507 
00508     if (usedCSClist0B[index] == true) continue;
00509     if ( int ((*it)->recHits().size()) < minCSCHitsPerSegment ) continue;  
00510 
00511     //double dof = static_cast<double>( (*it)->degreesOfFreedom() ) ;
00512     //if ( ((*it)->chi2()/dof) > 20000.0 ) continue;
00513 
00514     // Global position of starting point for protoTrack
00515     GlobalPoint gp = (*it)->globalPosition();
00516     float eta_temp = gp.eta();
00517     float phi_temp = gp.phi();
00518     bool showeringBefore = false; 
00519     NShowerSeg = 0; 
00520     if ( IdentifyShowering( CSClist0B, usedCSClist0B, eta_temp, phi_temp, 0, NShowerSeg)  ) showeringBefore = true ;
00521     int NShowers = 0; 
00522     if ( showeringBefore ) {
00523        // usedCSClist0B[index] = true;
00524         NShowers++ ;
00525     }
00526 
00527     SegmentContainer protoTrack;
00528     protoTrack.push_back(*it);
00529 
00530     std::vector<int> layers;
00531     layers.push_back(0);
00532 
00533     // Try adding segment from other station
00534     if (foundMatchingSegment(1, protoTrack, CSClist1B, usedCSClist1B, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(1);
00535     if ( showeringBefore )  NShowers++ ;
00536     if (foundMatchingSegment(1, protoTrack, CSClist2B, usedCSClist2B, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(2);
00537     if ( showeringBefore )  NShowers++ ;
00538     if (foundMatchingSegment(1, protoTrack, CSClist3B, usedCSClist3B, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(3);
00539     if ( showeringBefore )  NShowers++ ;
00540     if (foundMatchingSegment(1, protoTrack, CSClist4B, usedCSClist4B, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(4);
00541     if ( showeringBefore )  NShowers++ ;
00542 
00543 
00544     // adding showering information   
00545     if ( layers.size() < 2 && ShoweringSegments.size() > 0 ) {
00546        for (size_t i=0; i< ShoweringSegments.size(); i++) {
00547            if ( ShoweringLayers[i] <= layers[ layers.size()-1] ) continue;
00548            protoTrack.push_back( ShoweringSegments[i] );
00549            layers.push_back( ShoweringLayers[i] );
00550        }
00551     }
00552     ShoweringSegments.clear() ;  
00553     ShoweringLayers.clear() ;  
00554 
00555 
00556     TrajectorySeed thisSeed;
00557     if ( layers.size() < 2 ) {
00558         thisSeed = muonSeedCreate_->createSeed(4, protoTrack, layers, NShowers, NShowerSeg );
00559     }else {
00560       if ( fabs( gp.eta() ) > 1.7  ) {
00561         thisSeed = muonSeedCreate_->createSeed(5, protoTrack, layers, NShowers, NShowerSeg );
00562       } else {
00563         thisSeed = muonSeedCreate_->createSeed(1, protoTrack, layers, NShowers, NShowerSeg );
00564       }
00565     }
00566 
00567     // Add the seeds to master collection
00568     rawSeeds.push_back(thisSeed);
00569     etaOfSeed.push_back(eta_temp);
00570     phiOfSeed.push_back(phi_temp);
00571     nSegOnSeed.push_back( protoTrack.size() );
00572 
00573     // mark this segment as used
00574     usedCSClist0B[index] = true;
00575   }
00576 
00577 
00578   // Loop over all possible ME1/2 ME1/3 segment to form seeds:
00579   index = -1;
00580   for (SegmentContainer::iterator it = CSClist1B.begin(); it != CSClist1B.end(); ++it ){
00581 
00582     index++;
00583 
00584     if (usedCSClist1B[index] == true) continue;
00585     if ( int ((*it)->recHits().size()) < minCSCHitsPerSegment ) continue;  
00586 
00587     //double dof = static_cast<double>( (*it)->degreesOfFreedom() ) ;
00588     //if ( ((*it)->chi2()/dof) > 20000.0 ) continue;
00589 
00590     // Global position of starting point for protoTrack
00591     GlobalPoint gp = (*it)->globalPosition();
00592     float eta_temp = gp.eta();
00593     float phi_temp = gp.phi();
00594     bool showeringBefore = false;
00595     NShowerSeg = 0; 
00596     if ( IdentifyShowering( CSClist1B, usedCSClist1B, eta_temp, phi_temp, 1, NShowerSeg)  ) showeringBefore = true ;
00597     int NShowers = 0; 
00598     if ( showeringBefore ) {
00599     //    usedCSClist1B[index] = true;
00600         NShowers++ ;
00601     }
00602 
00603     SegmentContainer protoTrack;
00604     protoTrack.push_back(*it);
00605     
00606     std::vector<int> layers;
00607     layers.push_back(1);
00608 
00609     // Try adding segment from other stations
00610     if (foundMatchingSegment(1, protoTrack, CSClist2B, usedCSClist2B, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(2);
00611     if ( showeringBefore )  NShowers++ ;
00612     if (foundMatchingSegment(1, protoTrack, CSClist3B, usedCSClist3B, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(3);
00613     if ( showeringBefore )  NShowers++ ;
00614     if (foundMatchingSegment(1, protoTrack, CSClist4B, usedCSClist4B, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(4);
00615     if ( showeringBefore )  NShowers++ ;
00616 
00617     // adding showering information   
00618     if ( layers.size() < 2 && ShoweringSegments.size() > 0 ) {
00619        for (size_t i=0; i< ShoweringSegments.size(); i++) {
00620            if ( ShoweringLayers[i] <= layers[ layers.size()-1] ) continue;
00621            protoTrack.push_back( ShoweringSegments[i] );
00622            layers.push_back( ShoweringLayers[i] );
00623        }
00624     }
00625     ShoweringSegments.clear() ;  
00626     ShoweringLayers.clear() ;  
00627 
00628      TrajectorySeed thisSeed; 
00629      if ( layers.size() < 2 ) {
00630        thisSeed = muonSeedCreate_->createSeed(4, protoTrack, layers, NShowers, NShowerSeg );
00631      } else {
00632        thisSeed = muonSeedCreate_->createSeed(1, protoTrack, layers, NShowers, NShowerSeg );
00633      }
00634      // Add the seeds to master collection
00635      rawSeeds.push_back(thisSeed);
00636      etaOfSeed.push_back(eta_temp);
00637      phiOfSeed.push_back(phi_temp);
00638      nSegOnSeed.push_back( protoTrack.size() );
00639 
00640      // mark this segment as used
00641      usedCSClist1B[index] = true;
00642 
00643   }
00644 
00645 
00646   // Loop over all possible ME2 segment to form seeds:
00647   index = -1;
00648   for (SegmentContainer::iterator it = CSClist2B.begin(); it != CSClist2B.end(); ++it ){
00649 
00650     index++;
00651 
00652     if (usedCSClist2B[index] == true) continue;
00653     if ( int ((*it)->recHits().size()) < minCSCHitsPerSegment ) continue;  
00654 
00655     double dof = static_cast<double>( (*it)->degreesOfFreedom() ) ;
00656     if ( ((*it)->chi2()/dof) > 20000.0 ) continue;
00657 
00658     // Global position of starting point for protoTrack
00659     GlobalPoint gp = (*it)->globalPosition();
00660     float eta_temp = gp.eta();
00661     float phi_temp = gp.phi();
00662     bool showeringBefore = false; 
00663     NShowerSeg = 0; 
00664     if ( IdentifyShowering( CSClist2B, usedCSClist2B, eta_temp, phi_temp, 2, NShowerSeg)  ) showeringBefore = true ;
00665     int NShowers = 0; 
00666     if ( showeringBefore ) {
00667        // usedCSClist2B[index] = true;
00668         NShowers++ ;
00669     }
00670 
00671     SegmentContainer protoTrack;
00672     protoTrack.push_back(*it);
00673 
00674     std::vector<int> layers;
00675     layers.push_back(2);
00676     
00677     // Try adding segment from other stations
00678     if (foundMatchingSegment(1, protoTrack, CSClist3B, usedCSClist3B, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(3);
00679     if ( showeringBefore )  NShowers++ ;
00680     if (foundMatchingSegment(1, protoTrack, CSClist4B, usedCSClist4B, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(4);
00681     if ( showeringBefore )  NShowers++ ;
00682 
00683     // adding showering information   
00684     if ( layers.size() < 2 && ShoweringSegments.size() > 0 ) {
00685        for (size_t i=0; i< ShoweringSegments.size(); i++) {
00686            if ( ShoweringLayers[i] <= layers[ layers.size()-1] ) continue;
00687            protoTrack.push_back( ShoweringSegments[i] );
00688            layers.push_back( ShoweringLayers[i] );
00689        }
00690     }
00691     ShoweringSegments.clear() ;  
00692     ShoweringLayers.clear() ;  
00693 
00694 
00695     TrajectorySeed thisSeed; 
00696     if ( layers.size() < 2) {
00697        thisSeed = muonSeedCreate_->createSeed(4, protoTrack, layers, NShowers, NShowerSeg );
00698     } else {
00699        thisSeed = muonSeedCreate_->createSeed(1, protoTrack, layers, NShowers, NShowerSeg );
00700     }
00701 
00702     // Add the seeds to master collection
00703     rawSeeds.push_back(thisSeed);
00704     etaOfSeed.push_back(eta_temp);
00705     phiOfSeed.push_back(phi_temp);
00706     nSegOnSeed.push_back( protoTrack.size() );
00707     // mark this segment as used
00708     usedCSClist2B[index] = true;
00709   }
00710 
00711   // Loop over all possible ME3 segment to form seeds:
00712   index = -1;
00713   for (SegmentContainer::iterator it = CSClist3B.begin(); it != CSClist3B.end(); ++it ){
00714 
00715     index++;
00716 
00717     if (usedCSClist3B[index] == true) continue;
00718     if ( int ((*it)->recHits().size()) < minCSCHitsPerSegment ) continue;  
00719 
00720     double dof = static_cast<double>( (*it)->degreesOfFreedom() ) ;
00721     if ( ((*it)->chi2()/dof) > 20000.0 ) continue;
00722 
00723     // Global position of starting point for protoTrack
00724     GlobalPoint gp = (*it)->globalPosition();
00725     float eta_temp = gp.eta();
00726     float phi_temp = gp.phi();
00727     bool showeringBefore = false; 
00728     NShowerSeg = 0; 
00729     if ( IdentifyShowering( CSClist3B, usedCSClist3B, eta_temp, phi_temp, 3, NShowerSeg)  ) showeringBefore = true ;
00730     int NShowers = 0; 
00731     if ( showeringBefore ) {
00732     //    usedCSClist3B[index] = true;
00733         NShowers++ ;
00734     }
00735 
00736     SegmentContainer protoTrack;
00737     protoTrack.push_back(*it);
00738 
00739     std::vector<int> layers;
00740     layers.push_back(2);
00741     
00742     // Try adding segment from other stations
00743     if (foundMatchingSegment(1, protoTrack, CSClist4B, usedCSClist4B, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(4);
00744     if ( showeringBefore )  NShowers++ ;
00745 
00746 
00747     // adding showering information   
00748     if ( layers.size() < 2 && ShoweringSegments.size() > 0 ) {
00749        for (size_t i=0; i< ShoweringSegments.size(); i++) {
00750            if ( ShoweringLayers[i] <= layers[ layers.size()-1] ) continue;
00751            protoTrack.push_back( ShoweringSegments[i] );
00752            layers.push_back( ShoweringLayers[i] );
00753        }
00754     }
00755     ShoweringSegments.clear() ;  
00756     ShoweringLayers.clear() ;  
00757 
00758     // mark this segment as used
00759     usedCSClist3B[index] = true;
00760 
00761     if ( layers.size() < 2 ) continue;
00762     TrajectorySeed thisSeed = muonSeedCreate_->createSeed(1, protoTrack, layers, NShowers, NShowerSeg ); 
00763 
00764     // Add the seeds to master collection
00765     rawSeeds.push_back(thisSeed);
00766     etaOfSeed.push_back(eta_temp);
00767     phiOfSeed.push_back(phi_temp);
00768     nSegOnSeed.push_back( protoTrack.size() );
00769   }
00770 
00771 
00772   /* *****************************************************************************************************************
00773    * Form seeds from forward endcap
00774    *
00775    * Proceed from inside -> out
00776    * *****************************************************************************************************************/
00777 
00778   // Loop over all possible ME11 segment to form seeds:
00779   index = -1;
00780   for (SegmentContainer::iterator it = CSClist0F.begin(); it != CSClist0F.end(); ++it ){
00781 
00782     index++;
00783   
00784     if (usedCSClist0F[index] == true) continue;
00785     if ( int ((*it)->recHits().size()) < minCSCHitsPerSegment ) continue;
00786     
00787     //double dof = static_cast<double>( (*it)->degreesOfFreedom() ) ;
00788     //if ( ((*it)->chi2()/dof) > 20000.0 ) continue;
00789 
00790     // Global position of starting point for protoTrack
00791     GlobalPoint gp = (*it)->globalPosition();
00792     float eta_temp = gp.eta();  
00793     float phi_temp = gp.phi();      
00794     bool showeringBefore = false; 
00795     NShowerSeg = 0; 
00796     if ( IdentifyShowering( CSClist0F, usedCSClist0F, eta_temp, phi_temp, 0, NShowerSeg)  ) showeringBefore = true ;
00797     int NShowers = 0; 
00798     if ( showeringBefore ) {
00799        // usedCSClist0F[index] = true;
00800         NShowers++ ;
00801     }
00802     
00803     SegmentContainer protoTrack;
00804     protoTrack.push_back(*it);
00805 
00806     std::vector<int> layers;
00807     layers.push_back(0);
00808 
00809     // Try adding segment from other station
00810     if (foundMatchingSegment(1, protoTrack, CSClist1F, usedCSClist1F, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(1);
00811     if ( showeringBefore )  NShowers++ ;
00812     if (foundMatchingSegment(1, protoTrack, CSClist2F, usedCSClist2F, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(2);
00813     if ( showeringBefore )  NShowers++ ;
00814     if (foundMatchingSegment(1, protoTrack, CSClist3F, usedCSClist3F, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(3);
00815     if ( showeringBefore )  NShowers++ ;
00816     if (foundMatchingSegment(1, protoTrack, CSClist4F, usedCSClist4F, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(4);
00817     if ( showeringBefore )  NShowers++ ;
00818 
00819 
00820     // adding showering information   
00821     if ( layers.size() < 2 && ShoweringSegments.size() > 0 ) {
00822        for (size_t i=0; i< ShoweringSegments.size(); i++) {
00823            if ( ShoweringLayers[i] <= layers[ layers.size()-1] ) continue;
00824            protoTrack.push_back( ShoweringSegments[i] );
00825            layers.push_back( ShoweringLayers[i] );
00826        }
00827     }
00828     ShoweringSegments.clear() ;  
00829     ShoweringLayers.clear() ;  
00830 
00831 
00832     TrajectorySeed thisSeed;
00833     if ( layers.size() < 2 ) {
00834         thisSeed = muonSeedCreate_->createSeed(4, protoTrack, layers, NShowers, NShowerSeg );
00835     } else {
00836       if ( fabs( gp.eta() ) > 1.7  ) {
00837         thisSeed = muonSeedCreate_->createSeed(5, protoTrack, layers, NShowers, NShowerSeg );
00838       } else {
00839         thisSeed = muonSeedCreate_->createSeed(1, protoTrack, layers, NShowers, NShowerSeg );
00840       }
00841     }
00842     // Add the seeds to master collection
00843     rawSeeds.push_back(thisSeed);
00844     etaOfSeed.push_back(eta_temp);
00845     phiOfSeed.push_back(phi_temp);
00846     nSegOnSeed.push_back( protoTrack.size() );
00847 
00848     // mark this segment as used
00849     usedCSClist0F[index] = true;
00850   }
00851   
00852 
00853   // Loop over all possible ME1/2 ME1/3 segment to form seeds:
00854   index = -1;
00855   for (SegmentContainer::iterator it = CSClist1F.begin(); it != CSClist1F.end(); ++it ){
00856     
00857     index++;
00858     
00859     if (usedCSClist1F[index] == true) continue;
00860     if ( int ((*it)->recHits().size()) < minCSCHitsPerSegment ) continue;
00861   
00862     //double dof = static_cast<double>( (*it)->degreesOfFreedom() ) ;
00863     //if ( ((*it)->chi2()/dof) > 20000.0 ) continue;
00864 
00865     // Global position of starting point for protoTrack
00866     GlobalPoint gp = (*it)->globalPosition();
00867     float eta_temp = gp.eta();
00868     float phi_temp = gp.phi();
00869     bool showeringBefore = false; 
00870     NShowerSeg = 0; 
00871     if ( IdentifyShowering( CSClist1F, usedCSClist1F, eta_temp, phi_temp, 1, NShowerSeg)  ) showeringBefore = true ;
00872     int NShowers = 0; 
00873     if ( showeringBefore ) {
00874      //   usedCSClist1F[index] = true;
00875         NShowers++ ;
00876     }
00877     
00878     SegmentContainer protoTrack;
00879     protoTrack.push_back(*it);
00880    
00881     std::vector<int> layers;
00882     layers.push_back(1);
00883 
00884     // Try adding segment from other stations
00885     if (foundMatchingSegment(1, protoTrack, CSClist2F, usedCSClist2F, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(2);
00886     if ( showeringBefore )  NShowers++ ;
00887     if (foundMatchingSegment(1, protoTrack, CSClist3F, usedCSClist3F, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(3);
00888     if ( showeringBefore )  NShowers++ ;
00889     if (foundMatchingSegment(1, protoTrack, CSClist4F, usedCSClist4F, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(4);
00890     if ( showeringBefore )  NShowers++ ;
00891 
00892   
00893     // adding showering information   
00894     if ( layers.size() < 2 && ShoweringSegments.size() > 0 ) {
00895        for (size_t i=0; i< ShoweringSegments.size(); i++) {
00896            if ( ShoweringLayers[i] <= layers[ layers.size()-1] ) continue;
00897            protoTrack.push_back( ShoweringSegments[i] );
00898            layers.push_back( ShoweringLayers[i] );
00899        }
00900     }
00901     ShoweringSegments.clear() ;  
00902     ShoweringLayers.clear() ;  
00903 
00904 
00905     TrajectorySeed thisSeed; 
00906     if ( layers.size() < 2) {
00907       thisSeed = muonSeedCreate_->createSeed(4, protoTrack, layers, NShowers, NShowerSeg );
00908     } else {
00909       thisSeed = muonSeedCreate_->createSeed(1, protoTrack, layers, NShowers, NShowerSeg );
00910     }
00911   
00912     // Add the seeds to master collection
00913     rawSeeds.push_back(thisSeed);
00914     etaOfSeed.push_back(eta_temp);
00915     phiOfSeed.push_back(phi_temp);
00916     nSegOnSeed.push_back( protoTrack.size() );
00917 
00918     // mark this segment as used
00919     usedCSClist1F[index] = true;
00920   } 
00921 
00922 
00923   // Loop over all possible ME2 segment to form seeds:
00924   index = -1;
00925   for (SegmentContainer::iterator it = CSClist2F.begin(); it != CSClist2F.end(); ++it ){
00926   
00927     index++;
00928 
00929     if (usedCSClist2F[index] == true) continue;
00930     if ( int ((*it)->recHits().size()) < minCSCHitsPerSegment ) continue;
00931   
00932     double dof = static_cast<double>( (*it)->degreesOfFreedom() ) ;
00933     if ( ((*it)->chi2()/dof) > 20000.0 ) continue;
00934 
00935     // Global position of starting point for protoTrack
00936     GlobalPoint gp = (*it)->globalPosition();
00937     float eta_temp = gp.eta();  
00938     float phi_temp = gp.phi();   
00939     bool showeringBefore = false; 
00940     NShowerSeg = 0; 
00941     if ( IdentifyShowering( CSClist2F, usedCSClist2F, eta_temp, phi_temp, 2, NShowerSeg)  ) showeringBefore = true ;
00942     int NShowers = 0; 
00943     if ( showeringBefore ) {
00944     //    usedCSClist2F[index] = true;
00945         NShowers++ ;
00946     }
00947    
00948     SegmentContainer protoTrack;
00949     protoTrack.push_back(*it);
00950   
00951     std::vector<int> layers;
00952     layers.push_back(2);
00953 
00954     // Try adding segment from other stations
00955     if (foundMatchingSegment(1, protoTrack, CSClist3F, usedCSClist3F, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(3);
00956     if ( showeringBefore )  NShowers++ ;
00957     if (foundMatchingSegment(1, protoTrack, CSClist4F, usedCSClist4F, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(4);
00958     if ( showeringBefore )  NShowers++ ;
00959   
00960 
00961     // adding showering information   
00962     if ( layers.size() < 2 && ShoweringSegments.size() > 0 ) {
00963        for (size_t i=0; i< ShoweringSegments.size(); i++) {
00964            if ( ShoweringLayers[i] <= layers[ layers.size()-1] ) continue;
00965            protoTrack.push_back( ShoweringSegments[i] );
00966            layers.push_back( ShoweringLayers[i] );
00967        }
00968     }
00969     ShoweringSegments.clear() ;  
00970     ShoweringLayers.clear() ;  
00971 
00972     TrajectorySeed thisSeed; 
00973     if ( layers.size() < 2) {
00974       thisSeed = muonSeedCreate_->createSeed(4, protoTrack, layers, NShowers, NShowerSeg );
00975     } else {
00976       thisSeed = muonSeedCreate_->createSeed(1, protoTrack, layers, NShowers, NShowerSeg );
00977     }
00978       
00979     // Add the seeds to master collection
00980     rawSeeds.push_back(thisSeed);  
00981     etaOfSeed.push_back(eta_temp); 
00982     phiOfSeed.push_back(phi_temp);
00983     nSegOnSeed.push_back( protoTrack.size() );
00984     
00985     // mark this segment as used
00986     usedCSClist2F[index] = true;
00987   }
00988 
00989   // Loop over all possible ME3 segment to form seeds:
00990   index = -1;
00991   for (SegmentContainer::iterator it = CSClist3F.begin(); it != CSClist3F.end(); ++it ){
00992   
00993     index++;
00994 
00995     if (usedCSClist3F[index] == true) continue;
00996     if ( int ((*it)->recHits().size()) < minCSCHitsPerSegment ) continue;
00997   
00998     double dof = static_cast<double>( (*it)->degreesOfFreedom() ) ;
00999     if ( ((*it)->chi2()/dof) > 20000.0 ) continue;
01000 
01001     // Global position of starting point for protoTrack
01002     GlobalPoint gp = (*it)->globalPosition();
01003     float eta_temp = gp.eta();  
01004     float phi_temp = gp.phi();   
01005     bool showeringBefore = false; 
01006     NShowerSeg = 0; 
01007     if ( IdentifyShowering( CSClist3F, usedCSClist3F, eta_temp, phi_temp, 3, NShowerSeg)  ) showeringBefore = true ;
01008     int NShowers = 0; 
01009     if ( showeringBefore ) {
01010      //   usedCSClist3F[index] = true;
01011         NShowers++ ;
01012     }
01013    
01014     SegmentContainer protoTrack;
01015     protoTrack.push_back(*it);
01016   
01017     std::vector<int> layers;
01018     layers.push_back(2);
01019 
01020     // Try adding segment from other stations
01021     if (foundMatchingSegment(1, protoTrack, CSClist4F, usedCSClist4F, eta_temp, phi_temp, layers[layers.size()-1], showeringBefore )) layers.push_back(4);
01022     if ( showeringBefore )  NShowers++ ;
01023   
01024 
01025     // adding showering information   
01026     if ( layers.size() < 2 && ShoweringSegments.size() > 0 ) {
01027        for (size_t i=0; i< ShoweringSegments.size(); i++) {
01028            if ( ShoweringLayers[i] <= layers[ layers.size()-1] ) continue;
01029            protoTrack.push_back( ShoweringSegments[i] );
01030            layers.push_back( ShoweringLayers[i] );
01031        }
01032     }
01033     ShoweringSegments.clear() ;  
01034     ShoweringLayers.clear() ;  
01035 
01036     // mark this segment as used
01037     usedCSClist3F[index] = true;
01038 
01039     if ( layers.size() < 2 ) continue;
01040 
01041     TrajectorySeed thisSeed = muonSeedCreate_->createSeed(1, protoTrack, layers, NShowers, NShowerSeg );
01042       
01043     // Add the seeds to master collection
01044     rawSeeds.push_back(thisSeed);  
01045     etaOfSeed.push_back(eta_temp); 
01046     phiOfSeed.push_back(phi_temp);
01047     nSegOnSeed.push_back( protoTrack.size() );
01048     
01049   }
01050 
01051 
01052   /* *********************************************************************************************************************
01053    * Clean up raw seed collection and pass to master collection
01054    * *********************************************************************************************************************/
01055 
01056   if (debug) std::cout << "*** CLEAN UP " << std::endl;
01057   if (debug) std::cout << "Number of seeds BEFORE " << rawSeeds.size() << std::endl;
01058 
01059 
01060   int goodSeeds = 0;
01061 
01062   theSeeds  = muonSeedClean_->seedCleaner(eventSetup,rawSeeds);
01063   goodSeeds = theSeeds.size();
01064 
01065   //std::cout << " === Before Cleaning : " << rawSeeds.size() <<std::endl;
01066   //std::cout << " => AFTER :" << goodSeeds << std::endl;
01067 
01068   if (debug) std::cout << "Number of seeds AFTER " << goodSeeds << std::endl;
01069 
01070 
01071   return goodSeeds;
01072 }
01073 
01074 
01075 
01076 /* *********************************************************************************************************************
01077  * Try to match segment from different station (layer)
01078  *
01079  * Note type = 1 --> endcap
01080  *           = 2 --> overlap
01081  *           = 3 --> barrel
01082  * *********************************************************************************************************************/
01083 
01085 bool MuonSeedBuilder::foundMatchingSegment( int type, SegmentContainer& protoTrack, SegmentContainer& segs, 
01086      BoolContainer& usedSeg, float& eta_last, float& phi_last, int& lastLayer, bool& showeringBefore  ) {
01087 
01088   bool ok = false;
01089   int scanlayer = (lastLayer < 0 ) ?  (lastLayer-1) : (lastLayer+1) ;
01090 
01091   if ( IdentifyShowering( segs, usedSeg, eta_last, phi_last, scanlayer, NShowerSeg )  ) {
01092      showeringBefore = true; 
01093      return ok ;
01094   }
01095 
01096   // Setup the searching cone-size
01097   // searching cone-size should changes with bending power
01098   double maxdEta;
01099   double maxdPhi;
01100   if ( type == 1 ) { 
01101     // CSC
01102     maxdEta = maxDeltaEtaCSC;
01103     if ( lastLayer == 0 || lastLayer == 1 ) {
01104        if ( fabs(eta_last) < 2.1 ) {  maxdPhi = maxDeltaPhiCSC; }
01105        else                        {  maxdPhi = 0.06;           }  
01106     } 
01107     else if (lastLayer== 2 ) {      maxdPhi = 0.5*maxDeltaPhiCSC; }
01108     else  {                         maxdPhi = 0.2*maxDeltaPhiCSC; }
01109 
01110   } else if ( type == 2 ) { 
01111     // Overlap
01112     maxdEta = maxDeltaEtaOverlap;
01113     if ( lastLayer == -1 ) {        maxdPhi = maxDeltaPhiDT;      }
01114     else {                          maxdPhi = maxDeltaPhiOverlap; }
01115 
01116   } else {
01117     // DT
01118     maxdEta = maxDeltaEtaDT;
01119     if ( lastLayer == -1 ) {       maxdPhi = maxDeltaPhiDT;     }
01120     else if ( lastLayer == -2 ) {  maxdPhi = 0.8*maxDeltaPhiDT; }
01121     else  {                        maxdPhi = 0.4*maxDeltaPhiDT; }
01122     
01123   }
01124   
01125   // if previous layer showers, limite the maxdPhi < 0.06
01126   if ( showeringBefore && maxdPhi > 0.03  ) maxdPhi = 0.03;
01127   // reset the showering flag
01128   showeringBefore = false ;
01129 
01130   // global phi/eta from previous segment 
01131   float eta_temp = eta_last;
01132   float phi_temp = phi_last;
01133 
01134   // Index counter to keep track of element used in segs 
01135   int          index = -1;
01136   int          best_match = index;
01137   float        best_R = sqrt( (maxdEta*maxdEta) + (maxdPhi*maxdPhi) );
01138   float        best_chi2 = 200;
01139   int          best_dimension = 2;
01140   int          best_nhits = minDTHitsPerSegment;
01141   if( type == 1 ) best_nhits = minCSCHitsPerSegment;
01142   // Loop over segments in other station (layer) and find candidate match 
01143   for (SegmentContainer::iterator it=segs.begin(); it!=segs.end(); ++it){
01144 
01145     index++;
01146 
01147     // Not to get confused:  eta_last is from the previous layer.
01148     // This is only to find the best set of segments by comparing at the distance layer-by-layer 
01149     GlobalPoint gp2 = (*it)->globalPosition(); 
01150     double dh = fabs( gp2.eta() - eta_temp ); 
01151     double df = fabs( gp2.phi() - phi_temp );
01152     double dR = sqrt( (dh*dh) + (df*df) );
01153 
01154     // dEta and dPhi should be within certain range
01155     bool case1 = (  dh  < maxdEta && df < maxdPhi ) ? true:false ;
01156     // for DT station 4 ; CSCSegment is always 4D 
01157     bool case2 = (  ((*it)->dimension()!= 4) && (dh< 0.5) && (df < maxdPhi) )  ? true:false ;
01158     if ( !case1 && !case2  ) continue;
01159      
01160     int NRechits = muonSeedClean_->NRecHitsFromSegment( &*(*it) ) ;
01161 
01162     if ( NRechits < best_nhits ) continue;
01163     best_nhits = NRechits ; 
01164 
01165     // reject 2D segments if 4D segments are available 
01166     if ( (*it)->dimension() < best_dimension ) continue;
01167     best_dimension = (*it)->dimension();
01168 
01169     // pick the segment with best chi2/dof within a fixed cone size
01170     if ( dR > best_R ) continue;
01171 
01172     // select smaller chi2/dof
01173     double dof = static_cast<double>( (*it)->degreesOfFreedom() ) ;
01175     if ( (*it)->chi2()/dof < 0.001 && NRechits < 6 && type == 1) continue; 
01176     if ( (*it)->chi2()/dof > best_chi2 ) continue;
01177     best_chi2 = (*it)->chi2()/dof ;
01178     best_match = index;
01179     // propagate the eta and phi to next layer
01180     if ((*it)->dimension() != 4 ) {
01181        phi_last = phi_last;
01182        eta_last = eta_last;    
01183     } else {
01184        phi_last = gp2.phi(); 
01185        eta_last = gp2.eta();
01186     }
01187   }   
01188 
01189   if (best_match < 0) return ok;
01190 
01191   // Add best matching segment to protoTrack:
01192   index = -1;
01193   for (SegmentContainer::iterator it=segs.begin(); it!=segs.end(); ++it){
01194       index++;
01195       if (index != best_match) continue;
01196       protoTrack.push_back(*it);
01197       usedSeg[best_match] = true;
01198       ok = true;     
01199   }
01200   return ok; 
01201 }
01202 
01203 
01204 bool MuonSeedBuilder::IdentifyShowering( SegmentContainer& segs, BoolContainer& usedSeg, float& eta_last, float& phi_last, int layer, int& NShoweringSegments ) {
01205 
01206   bool showering  = false ;  
01207 
01208   int  nSeg   = 0 ;
01209   int  nRhits = 0 ;
01210   double nChi2  = 9999. ;
01211   int theOrigin = -1;
01212   std::vector<int> badtag;
01213   int    index = -1;
01214   double aveEta = 0.0;
01215   for (SegmentContainer::iterator it = segs.begin(); it != segs.end(); ++it){
01216 
01217       index++;
01218       GlobalPoint gp = (*it)->globalPosition(); 
01219       double dh = gp.eta() - eta_last ;
01220       double df = gp.phi() - phi_last ;
01221       double dR = sqrt( (dh*dh) + (df*df) ) ;
01222 
01223       double dof = static_cast<double>( (*it)->degreesOfFreedom() );
01224       double nX2 = (*it)->chi2() / dof ;
01225 
01226       bool isDT = false ; 
01227       DetId geoId = (*it)->geographicalId();
01228       if ( geoId.subdetId() == MuonSubdetId::DT ) isDT = true;
01229 
01230       if (dR < 0.3 ) {
01231          nSeg++ ;
01232          badtag.push_back( index ) ;
01233          aveEta += fabs( gp.eta() ) ; 
01234          // pick up the best segment from showering chamber 
01235          int rh = muonSeedClean_->NRecHitsFromSegment( &*(*it) );
01236          if (rh < 6 && !isDT) continue;
01237          if (rh < 12 && isDT) continue;
01238          if ( rh > nRhits ) { 
01239             nRhits = rh ;
01240             if ( nX2 > nChi2 ) continue ;
01241             if (layer != 0 && layer != 1 && layer != -1 ) {
01242                theOrigin = index ;
01243             }
01244          }
01245       }
01246 
01247   }
01248   aveEta =  aveEta/static_cast<double>(nSeg) ;
01249   bool isME11A = (aveEta >= 2.1 &&  layer == 0) ? true : false ;
01250   bool isME12  = (aveEta >  1.2 && aveEta <= 1.65 && layer == 1) ? true : false ;
01251   bool isME11  = (aveEta >  1.65 && aveEta <= 2.1 && layer == 0) ? true : false ;
01252   bool is1stLayer = (layer == -1 || layer == 0 || isME12 || isME11 || isME11A) ? true : false ;
01253 
01254   NShoweringSegments += nSeg;
01255 
01256   if ( nSeg  > 3 && !isME11A ) showering = true ;
01257   if ( nSeg  > 6 &&  isME11A ) showering = true ;
01258 
01259   // if showering, flag all segments in order to skip this layer for pt estimation except 1st layer
01260   //std::cout<<" from Showering "<<std::endl;
01261   if (showering && !is1stLayer ) {
01262      for (std::vector<int>::iterator it = badtag.begin(); it != badtag.end(); ++it ) { 
01263          usedSeg[*it] = true;              
01264          if ( (*it) != theOrigin ) continue; 
01265          ShoweringSegments.push_back( segs[*it] );
01266          ShoweringLayers.push_back( layer );
01267      }
01268   }
01269   return showering ;
01270 
01271 }
01272 
01273 double MuonSeedBuilder::etaError(const GlobalPoint gp, double rErr) {
01274 
01275   double dHdTheta = 0.0;
01276   double dThetadR = 0.0;
01277   double etaErr = 1.0;
01278 
01279   if (gp.perp() != 0) {
01280 
01281      dHdTheta = ( gp.mag()+gp.z() )/gp.perp();
01282      dThetadR = gp.z() / gp.perp2() ;
01283      etaErr =  0.25 * (dHdTheta * dThetadR) * (dHdTheta * dThetadR) * rErr ;
01284   }
01285  
01286   return etaErr;
01287 }
01288