CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch13/src/RecoMET/METAlgorithms/src/CSCHaloAlgo.cc

Go to the documentation of this file.
00001 #include "RecoMET/METAlgorithms/interface/CSCHaloAlgo.h"
00002 #include "FWCore/Common/interface/TriggerNames.h"
00003 /*
00004   [class]:  CSCHaloAlgo
00005   [authors]: R. Remington, The University of Florida
00006   [description]: See CSCHaloAlgo.h
00007   [date]: October 15, 2009
00008 */
00009 using namespace reco;
00010 using namespace std;
00011 using namespace edm;
00012 #include "TMath.h"
00013 
00014 CSCHaloAlgo::CSCHaloAlgo()
00015 {
00016   deta_threshold = 0.;
00017   min_inner_radius = 0.;
00018   max_inner_radius = 9999.;
00019   min_outer_radius = 0.;
00020   max_outer_radius = 9999.;
00021   dphi_threshold = 999.;
00022   norm_chi2_threshold = 999.;
00023   recHit_t0=200;
00024   recHit_twindow=500;
00025   expected_BX=3;
00026   
00027   min_outer_theta = 0.;
00028   max_outer_theta = TMath::Pi();
00029   
00030   matching_dphi_threshold = 0.18; //radians
00031   matching_deta_threshold = 0.4;
00032   matching_dwire_threshold = 5.;
00033 }
00034 
00035 reco::CSCHaloData CSCHaloAlgo::Calculate(const CSCGeometry& TheCSCGeometry,
00036                                          edm::Handle<reco::TrackCollection>& TheCSCTracks, 
00037                                          edm::Handle<reco::MuonCollection>& TheMuons,
00038                                          edm::Handle<CSCSegmentCollection>& TheCSCSegments, 
00039                                          edm::Handle<CSCRecHit2DCollection>& TheCSCRecHits,
00040                                          edm::Handle < L1MuGMTReadoutCollection >& TheL1GMTReadout,
00041                                          edm::Handle<edm::TriggerResults>& TheHLTResults,
00042                                          const edm::TriggerNames * triggerNames, const edm::Handle<CSCALCTDigiCollection>& TheALCTs)
00043 {
00044   reco::CSCHaloData TheCSCHaloData;
00045   if( TheCSCTracks.isValid() )
00046     {
00047       for( reco::TrackCollection::const_iterator iTrack = TheCSCTracks->begin() ; iTrack != TheCSCTracks->end() ; iTrack++ )
00048         {
00049           bool StoreTrack = false;
00050           // Calculate global phi coordinate for central most rechit in the track
00051           float innermost_global_z = 1500.;
00052           float outermost_global_z = 0.;
00053           GlobalPoint InnerMostGlobalPosition(0.,0.,0.);  // smallest abs(z)
00054           GlobalPoint OuterMostGlobalPosition(0.,0.,0.);  // largest abs(z)
00055           int nCSCHits = 0;
00056           for(unsigned int j = 0 ; j < iTrack->extra()->recHits().size(); j++ )
00057             {
00058               edm::Ref<TrackingRecHitCollection> hit( iTrack->extra()->recHits(), j );
00059               if( !hit->isValid() ) continue;
00060               DetId TheDetUnitId(hit->geographicalId());
00061               if( TheDetUnitId.det() != DetId::Muon ) continue;
00062               if( TheDetUnitId.subdetId() != MuonSubdetId::CSC ) continue;
00063 
00064               const GeomDetUnit *TheUnit = TheCSCGeometry.idToDetUnit(TheDetUnitId);
00065               LocalPoint TheLocalPosition = hit->localPosition();  
00066               const BoundPlane& TheSurface = TheUnit->surface();
00067               const GlobalPoint TheGlobalPosition = TheSurface.toGlobal(TheLocalPosition);
00068 
00069               float z = TheGlobalPosition.z();
00070               if( TMath::Abs(z) < innermost_global_z )
00071                 {
00072                   innermost_global_z = TMath::Abs(z);
00073                   InnerMostGlobalPosition = GlobalPoint( TheGlobalPosition);
00074                 }
00075               if( TMath::Abs(z) > outermost_global_z )
00076                 {
00077                   outermost_global_z = TMath::Abs(z);
00078                   OuterMostGlobalPosition = GlobalPoint( TheGlobalPosition );
00079                 }
00080               nCSCHits ++;
00081             }
00082 
00083           if( nCSCHits < 3 ) continue; // This needs to be optimized, but is the minimum 
00084  
00085           if( OuterMostGlobalPosition.x() == 0. || OuterMostGlobalPosition.y() == 0. || OuterMostGlobalPosition.z() == 0. ) 
00086             continue;
00087           if( InnerMostGlobalPosition.x() == 0. || InnerMostGlobalPosition.y() == 0. || InnerMostGlobalPosition.z() == 0. )
00088             continue;
00089           
00090           //Its a CSC Track,store it if it passes halo selection 
00091           StoreTrack = true;      
00092 
00093           float deta = TMath::Abs( OuterMostGlobalPosition.eta() - InnerMostGlobalPosition.eta() );
00094           float dphi = TMath::ACos( TMath::Cos( OuterMostGlobalPosition.phi() - InnerMostGlobalPosition.phi() ) ) ;
00095           float theta = iTrack->outerMomentum().theta();
00096           float innermost_x = InnerMostGlobalPosition.x() ;
00097           float innermost_y = InnerMostGlobalPosition.y();
00098           float outermost_x = OuterMostGlobalPosition.x();
00099           float outermost_y = OuterMostGlobalPosition.y();
00100           float innermost_r = TMath::Sqrt(innermost_x *innermost_x + innermost_y * innermost_y );
00101           float outermost_r = TMath::Sqrt(outermost_x *outermost_x + outermost_y * outermost_y );
00102           
00103           if( deta < deta_threshold )
00104             StoreTrack = false;
00105           if( theta > min_outer_theta && theta < max_outer_theta )
00106             StoreTrack = false;
00107           if( dphi > dphi_threshold )
00108             StoreTrack = false;
00109           if( innermost_r < min_inner_radius )
00110             StoreTrack = false;
00111           if( innermost_r > max_inner_radius )
00112             StoreTrack = false;
00113           if( outermost_r < min_outer_radius )
00114             StoreTrack = false;
00115           if( outermost_r > max_outer_radius )
00116             StoreTrack  = false;
00117           if( iTrack->normalizedChi2() > norm_chi2_threshold )
00118             StoreTrack = false;
00119 
00120 
00121 
00122           if( StoreTrack )
00123             {
00124               TheCSCHaloData.GetCSCTrackImpactPositions().push_back( InnerMostGlobalPosition );
00125 
00126               edm::Ref<TrackCollection> TheTrackRef( TheCSCTracks, iTrack - TheCSCTracks->begin() ) ;
00127               TheCSCHaloData.GetTracks().push_back( TheTrackRef );
00128             }
00129         }
00130     }
00131 
00132    if( TheHLTResults.isValid() )
00133      {
00134        bool EventPasses = false;
00135        for( unsigned int index = 0 ; index < vIT_HLTBit.size(); index++)
00136          {
00137            if( vIT_HLTBit[index].label().size() )
00138              {
00139                //Get the HLT bit and check to make sure it is valid 
00140                unsigned int bit = triggerNames->triggerIndex( vIT_HLTBit[index].label().c_str());
00141                if( bit < TheHLTResults->size() )
00142                  {
00143                    //If any of the HLT names given by the user accept, then the event passes
00144                    if( TheHLTResults->accept( bit ) && !TheHLTResults->error( bit ) )
00145                      {
00146                        EventPasses = true;
00147                      }
00148                  }
00149              }
00150          }
00151        if( EventPasses )
00152          TheCSCHaloData.SetHLTBit(true);
00153        else
00154          TheCSCHaloData.SetHLTBit(false);
00155      }
00156 
00157    if( TheL1GMTReadout.isValid() )
00158      {
00159        L1MuGMTReadoutCollection const *gmtrc = TheL1GMTReadout.product ();
00160        std::vector < L1MuGMTReadoutRecord > gmt_records = gmtrc->getRecords ();
00161        std::vector < L1MuGMTReadoutRecord >::const_iterator igmtrr;
00162        
00163        int icsc = 0;
00164        int PlusZ = 0 ;
00165        int MinusZ = 0 ;
00166        // Check to see if CSC BeamHalo trigger is tripped
00167        for (igmtrr = gmt_records.begin (); igmtrr != gmt_records.end (); igmtrr++)
00168          {
00169            std::vector < L1MuRegionalCand >::const_iterator iter1;
00170            std::vector < L1MuRegionalCand > rmc;
00171            rmc = igmtrr->getCSCCands ();
00172            for (iter1 = rmc.begin (); iter1 != rmc.end (); iter1++)
00173              {
00174               if (!(*iter1).empty ())
00175                 {
00176                   if ((*iter1).isFineHalo ())
00177                     {
00178                       float halophi = iter1->phiValue();
00179                       halophi = halophi > TMath::Pi() ? halophi - 2.*TMath::Pi() : halophi;
00180                       float haloeta = iter1->etaValue();
00181                       bool HaloIsGood = true;
00182                       // Check if halo trigger is faked by any collision muons
00183                       if( TheMuons.isValid() )
00184                         {
00185                           float dphi = 9999.;
00186                           float deta = 9999.;
00187                           for( reco::MuonCollection::const_iterator mu = TheMuons->begin(); mu != TheMuons->end() && HaloIsGood ; mu++ )
00188                             {
00189                               // Don't match with SA-only muons
00190                               if( mu->isStandAloneMuon() && !mu->isTrackerMuon() && !mu->isGlobalMuon() )  continue;
00191                               
00192                               /*
00193                               if(!mu->isTrackerMuon())
00194                                 {
00195                                   if( mu->isStandAloneMuon() )
00196                                     {
00197                                       //make sure that this SA muon is not actually a halo-like muon
00198                                       float theta =  mu->outerTrack()->outerMomentum().theta();
00199                                       float deta = TMath::Abs(mu->outerTrack()->outerPosition().eta() - mu->outerTrack()->innerPosition().eta());
00200                                       if( theta < min_outer_theta || theta > max_outer_theta )  //halo-like
00201                                         continue;
00202                                       else if ( deta > deta_threshold ) //halo-like
00203                                         continue;
00204                                     }
00205                                 }
00206                               */
00207                             
00208                               const std::vector<MuonChamberMatch> chambers = mu->matches();
00209                               for(std::vector<MuonChamberMatch>::const_iterator iChamber = chambers.begin();
00210                                   iChamber != chambers.end() ; iChamber ++ )
00211                                 {
00212                                   if( iChamber->detector() != MuonSubdetId::CSC ) continue;
00213                                   for( std::vector<reco::MuonSegmentMatch>::const_iterator iSegment = iChamber->segmentMatches.begin() ; 
00214                                        iSegment != iChamber->segmentMatches.end(); ++iSegment )
00215                                     {
00216                                       edm::Ref<CSCSegmentCollection> cscSegment = iSegment->cscSegmentRef;
00217                                       std::vector<CSCRecHit2D> hits = cscSegment -> specificRecHits();
00218                                       for( std::vector<CSCRecHit2D>::iterator iHit = hits.begin();
00219                                            iHit != hits.end() ; iHit++ )
00220                                         {
00221                                           DetId TheDetUnitId(iHit->cscDetId());
00222                                           const GeomDetUnit *TheUnit = TheCSCGeometry.idToDetUnit(TheDetUnitId);
00223                                           LocalPoint TheLocalPosition = iHit->localPosition();
00224                                           const BoundPlane& TheSurface = TheUnit->surface();
00225                                           GlobalPoint TheGlobalPosition = TheSurface.toGlobal(TheLocalPosition);
00226                                           
00227                                           float phi_ = TheGlobalPosition.phi();
00228                                           float eta_ = TheGlobalPosition.eta();
00229                                           deta = deta < TMath::Abs( eta_ - haloeta ) ? deta : TMath::Abs( eta_ - haloeta );
00230                                           dphi = dphi < TMath::Abs( phi_ - halophi ) ? dphi : TMath::Abs( phi_ - halophi );
00231                                         }
00232                                     }
00233                                 }
00234                               if ( dphi < matching_dphi_threshold && deta < matching_deta_threshold) 
00235                                 HaloIsGood = false; // i.e., collision muon likely faked halo trigger
00236                             }
00237                         }
00238                       if( !HaloIsGood ) 
00239                         continue;
00240                       if( (*iter1).etaValue() > 0 )
00241                         PlusZ++;
00242                       else
00243                         MinusZ++;
00244                     }
00245                   else
00246                     icsc++;
00247                 }
00248              }
00249          }
00250        TheCSCHaloData.SetNumberOfHaloTriggers(PlusZ, MinusZ);
00251      }
00252 
00253    // Loop over CSCALCTDigi collection to look for out-of-time chamber triggers 
00254    // A collision muon in real data should only have ALCTDigi::getBX() = 3 ( in MC, it will be 6 )
00255    // Note that there could be two ALCTs per chamber 
00256    short int n_alctsP=0;
00257    short int n_alctsM=0;
00258    if(TheALCTs.isValid())
00259      {
00260        for (CSCALCTDigiCollection::DigiRangeIterator j=TheALCTs->begin(); j!=TheALCTs->end(); j++) 
00261          {
00262            const CSCALCTDigiCollection::Range& range =(*j).second;
00263            CSCDetId detId((*j).first.rawId());
00264            for (CSCALCTDigiCollection::const_iterator digiIt = range.first; digiIt!=range.second; ++digiIt)
00265              {
00266                if( (*digiIt).isValid() && ( (*digiIt).getBX() < expected_BX ) )
00267                  {
00268                    int digi_endcap  = detId.endcap();
00269                    int digi_station = detId.station();
00270                    int digi_ring    = detId.ring();
00271                    int digi_chamber = detId.chamber();
00272                    int digi_wire    = digiIt->getKeyWG();
00273                    if( digi_station == 1 && digi_ring == 4 )   //hack
00274                      digi_ring = 1;
00275                    
00276                    bool DigiIsGood = true;
00277                    int dwire = 999.;
00278                    if( TheMuons.isValid() ) 
00279                      {
00280                        //Check if there are any collision muons with hits in the vicinity of the digi
00281                        for(reco::MuonCollection::const_iterator mu = TheMuons->begin(); mu!= TheMuons->end() && DigiIsGood ; mu++ )
00282                          {
00283                            if( !mu->isTrackerMuon() && !mu->isGlobalMuon() && mu->isStandAloneMuon() ) continue;
00284                            /*
00285                              if(!mu->isTrackerMuon())
00286                                 {
00287                                   if( mu->isStandAloneMuon() )
00288                                     {
00289                                       //make sure that this SA muon is not actually a halo-like muon
00290                                       float theta =  mu->outerTrack()->outerMomentum().theta();
00291                                       float deta = TMath::Abs(mu->outerTrack()->outerPosition().eta() - mu->outerTrack()->innerPosition().eta());
00292                                       if( theta < min_outer_theta || theta > max_outer_theta )  //halo-like
00293                                         continue;
00294                                       else if ( deta > deta_threshold ) //halo-like
00295                                         continue;
00296                                     }
00297                                     }
00298                            */
00299                           
00300                            const std::vector<MuonChamberMatch> chambers = mu->matches();
00301                            for(std::vector<MuonChamberMatch>::const_iterator iChamber = chambers.begin();
00302                                iChamber != chambers.end(); iChamber ++ )
00303                              {
00304                                if( iChamber->detector() != MuonSubdetId::CSC ) continue;
00305                                for( std::vector<reco::MuonSegmentMatch>::const_iterator iSegment = iChamber->segmentMatches.begin();
00306                                     iSegment != iChamber->segmentMatches.end(); iSegment++ )
00307                                  {
00308                                    edm::Ref<CSCSegmentCollection> cscSegRef = iSegment->cscSegmentRef;
00309                                    std::vector<CSCRecHit2D> hits = cscSegRef->specificRecHits();
00310                                    for( std::vector<CSCRecHit2D>::iterator iHit = hits.begin();
00311                                         iHit != hits.end(); iHit++ )
00312                                      {
00313                                        if( iHit->cscDetId().endcap() != digi_endcap ) continue;
00314                                        if( iHit->cscDetId().station() != digi_station ) continue;
00315                                        if( iHit->cscDetId().ring() != digi_ring ) continue;
00316                                        if( iHit->cscDetId().chamber() != digi_chamber ) continue;
00317                                        CSCRecHit2D::ChannelContainer hitwires = iHit->wgroups();
00318                                        int nwires = hitwires.size();
00319                                        int center_id = nwires/2 + 1;
00320                                        int hit_wire = hitwires[center_id -1 ];
00321                                        dwire = dwire < TMath::Abs(hit_wire - digi_wire)? dwire : TMath::Abs(hit_wire - digi_wire );
00322                                      }
00323                                  }
00324                              }
00325                            if( dwire <= matching_dwire_threshold ) 
00326                              DigiIsGood = false;  // collision-like muon is close to this digi
00327                          }
00328                      }
00329                    // only count out of time digis if they are not matched to collision muons
00330                    if( DigiIsGood ) 
00331                      {
00332                        if( detId.endcap() == 1 ) 
00333                          n_alctsP++;
00334                        else if ( detId.endcap() ==  2) 
00335                          n_alctsM++;
00336                      }
00337                  }
00338              }
00339          }
00340      }
00341    TheCSCHaloData.SetNOutOfTimeTriggers(n_alctsP,n_alctsM);
00342 
00343    // Loop over the CSCRecHit2D collection to look for out-of-time recHits
00344    // Out-of-time is defined as tpeak outside [t_0 + TOF - t_window, t_0 + TOF + t_window]
00345    // where t_0 and t_window are configurable parameters
00346    short int n_recHitsP = 0;
00347    short int n_recHitsM = 0;
00348    if( TheCSCRecHits.isValid() )
00349      {
00350        CSCRecHit2DCollection::const_iterator dRHIter;
00351        for (dRHIter = TheCSCRecHits->begin(); dRHIter != TheCSCRecHits->end(); dRHIter++) 
00352          {
00353            if ( !((*dRHIter).isValid()) ) continue;  // only interested in valid hits
00354            CSCDetId idrec = (CSCDetId)(*dRHIter).cscDetId();
00355            float RHTime = (*dRHIter).tpeak();
00356            LocalPoint rhitlocal = (*dRHIter).localPosition();
00357            const CSCChamber* chamber = TheCSCGeometry.chamber(idrec);
00358            GlobalPoint globalPosition = chamber->toGlobal(rhitlocal);
00359            float globZ = globalPosition.z();
00360            if ( RHTime < (recHit_t0 - recHit_twindow) )
00361              {
00362                if( globZ > 0 )
00363                  n_recHitsP++;
00364                else
00365                  n_recHitsM++;
00366              }
00367            
00368            /*
00369 
00370            float globX = globalPosition.x();
00371            float globY = globalPosition.y();
00372            float globZ = globalPosition.z();
00373            float TOF = (sqrt(globX*globX+ globY*globY + globZ*globZ))/29.9792458 ; //cm -> ns
00374            if ( (RHTime < (recHit_t0 + TOF - recHit_twindow)) || (RHTime > (recHit_t0 + TOF + recHit_twindow)) )
00375              {
00376                if( globZ > 0 ) 
00377                  n_recHitsP++;
00378                else
00379                  n_recHitsM++;
00380              }
00381            */
00382          }
00383      }
00384    TheCSCHaloData.SetNOutOfTimeHits(n_recHitsP+n_recHitsM);
00385 
00386    return TheCSCHaloData;
00387 }
00388 
00389