CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/Fireworks/Muons/src/FWMuonBuilder.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     Muons
00004 // Class  :     FWMuonBuilder
00005 // $Id: FWMuonBuilder.cc,v 1.35 2010/09/07 15:46:48 yana Exp $
00006 //
00007 
00008 #include "TEveVSDStructs.h"
00009 #include "TEveTrack.h"
00010 #include "TEveStraightLineSet.h"
00011 #include "TEveGeoNode.h"
00012 #include "TGeoArb8.h"
00013 
00014 #include "Fireworks/Core/interface/FWEventItem.h"
00015 #include "Fireworks/Core/interface/FWMagField.h"
00016 #include "Fireworks/Core/interface/FWProxyBuilderBase.h"
00017 #include "Fireworks/Core/interface/FWGeometry.h"
00018 #include "Fireworks/Core/interface/fwLog.h"
00019 
00020 #include "Fireworks/Candidates/interface/CandidateUtils.h"
00021 
00022 #include "Fireworks/Tracks/interface/TrackUtils.h"
00023 #include "Fireworks/Tracks/interface/estimate_field.h"
00024 
00025 #include "Fireworks/Muons/interface/FWMuonBuilder.h"
00026 #include "Fireworks/Muons/interface/SegmentUtils.h"
00027 
00028 #include "DataFormats/MuonReco/interface/Muon.h"
00029 #include "DataFormats/TrackReco/interface/Track.h"
00030 #include "DataFormats/MuonDetId/interface/MuonSubdetId.h"
00031 
00032 namespace  {
00033 std::vector<TEveVector> getRecoTrajectoryPoints( const reco::Muon* muon,
00034                                                  const FWEventItem* iItem )
00035 {
00036    std::vector<TEveVector> points;
00037    const FWGeometry* geom = iItem->getGeom();
00038    
00039    float localTrajectoryPoint[3];
00040    float globalTrajectoryPoint[3];
00041    
00042    const std::vector<reco::MuonChamberMatch>& matches = muon->matches();
00043    for( std::vector<reco::MuonChamberMatch>::const_iterator chamber = matches.begin(),
00044                                                          chamberEnd = matches.end();
00045         chamber != matches.end(); ++chamber )
00046    {
00047       // expected track position
00048       localTrajectoryPoint[0] = chamber->x;
00049       localTrajectoryPoint[1] = chamber->y;
00050       localTrajectoryPoint[2] = 0;
00051 
00052       unsigned int rawid = chamber->id.rawId();
00053       if( geom->contains( rawid ))
00054       {
00055          geom->localToGlobal( rawid, localTrajectoryPoint, globalTrajectoryPoint );
00056          points.push_back( TEveVector(globalTrajectoryPoint[0],
00057                                       globalTrajectoryPoint[1],
00058                                       globalTrajectoryPoint[2] ));
00059       }
00060    }
00061    return points;
00062 }
00063 
00064 //______________________________________________________________________________
00065 
00066 void addMatchInformation( const reco::Muon* muon,
00067                           FWProxyBuilderBase* pb,
00068                           TEveElement* parentList,
00069                           bool showEndcap )
00070 {
00071   std::set<unsigned int> ids;
00072   const FWGeometry* geom = pb->context().getGeom();
00073   
00074   const std::vector<reco::MuonChamberMatch>& matches = muon->matches();
00075    
00076   //need to use auto_ptr since the segmentSet may not be passed to muonList
00077   std::auto_ptr<TEveStraightLineSet> segmentSet( new TEveStraightLineSet );
00078   // FIXME: This should be set elsewhere.
00079   segmentSet->SetLineWidth( 4 );
00080 
00081   for( std::vector<reco::MuonChamberMatch>::const_iterator chamber = matches.begin(), 
00082                                                        chambersEnd = matches.end(); 
00083        chamber != chambersEnd; ++chamber )
00084   {
00085     unsigned int rawid = chamber->id.rawId();
00086     float segmentLength = 0.0;
00087     float segmentLimit  = 0.0;
00088 
00089     if( geom->contains( rawid ))
00090     {
00091       TEveGeoShape* shape = geom->getEveShape( rawid );
00092       shape->SetElementName( "Chamber" );
00093       shape->RefMainTrans().Scale( 0.999, 0.999, 0.999 );
00094 
00095       FWGeometry::IdToInfoItr det = geom->find( rawid );
00096       if( det->shape[0] == 1 ) // TGeoTrap
00097       {
00098         segmentLength = det->shape[3];
00099         segmentLimit  = det->shape[4];
00100       }
00101       else if( det->shape[0] == 0 ) // TGeoBBox
00102       {
00103         segmentLength = det->shape[3];
00104       }
00105         
00106       if( ids.insert( rawid ).second &&  // ensure that we add same chamber only once
00107           ( chamber->detector() != MuonSubdetId::CSC || showEndcap ))
00108       {     
00109         pb->setupAddElement( shape, parentList );
00110       }
00111      
00112       for( std::vector<reco::MuonSegmentMatch>::const_iterator segment = chamber->segmentMatches.begin(),
00113                                                             segmentEnd = chamber->segmentMatches.end();
00114            segment != segmentEnd; ++segment )
00115       {
00116         float segmentPosition[3]  = {    segment->x,     segment->y, 0.0 };
00117         float segmentDirection[3] = { segment->dXdZ,  segment->dYdZ, 0.0 };
00118 
00119         float localSegmentInnerPoint[3];
00120         float localSegmentOuterPoint[3];
00121 
00122         fireworks::createSegment( chamber->detector(), true, 
00123                                   segmentLength, segmentLimit, 
00124                                   segmentPosition, segmentDirection,
00125                                   localSegmentInnerPoint, localSegmentOuterPoint );
00126       
00127         float globalSegmentInnerPoint[3];
00128         float globalSegmentOuterPoint[3];
00129 
00130         geom->localToGlobal( *det, localSegmentInnerPoint,  globalSegmentInnerPoint );
00131         geom->localToGlobal( *det, localSegmentOuterPoint,  globalSegmentOuterPoint );
00132 
00133         segmentSet->AddLine( globalSegmentInnerPoint[0], globalSegmentInnerPoint[1], globalSegmentInnerPoint[2],
00134                              globalSegmentOuterPoint[0], globalSegmentOuterPoint[1], globalSegmentOuterPoint[2] );
00135       }
00136     }
00137   }
00138   
00139   if( !matches.empty() ) 
00140     pb->setupAddElement( segmentSet.release(), parentList );
00141 }
00142 
00143 //______________________________________________________________________________
00144 
00145 bool
00146 buggyMuon( const reco::Muon* muon,
00147            const FWGeometry* geom )
00148 {
00149    if( !muon->standAloneMuon().isAvailable() ||
00150        !muon->standAloneMuon()->extra().isAvailable())
00151      return false;
00152    
00153    float localTrajectoryPoint[3];
00154    float globalTrajectoryPoint[3];
00155    
00156    const std::vector<reco::MuonChamberMatch>& matches = muon->matches();
00157    for( std::vector<reco::MuonChamberMatch>::const_iterator chamber = matches.begin(),
00158                                                          chamberEnd = matches.end();
00159         chamber != chamberEnd; ++chamber )
00160    {
00161       // expected track position
00162       localTrajectoryPoint[0] = chamber->x;
00163       localTrajectoryPoint[1] = chamber->y;
00164       localTrajectoryPoint[2] = 0;
00165 
00166       unsigned int rawid = chamber->id.rawId();
00167       if( geom->contains( rawid ))
00168       {
00169          geom->localToGlobal( rawid, localTrajectoryPoint, globalTrajectoryPoint );
00170          double phi = atan2( globalTrajectoryPoint[1], globalTrajectoryPoint[0] );
00171          if( cos( phi - muon->standAloneMuon()->innerPosition().phi()) < 0 )
00172             return true;
00173       }
00174    }
00175    return false;
00176 }
00177 
00178 }
00179 
00180 //
00181 // constructors and destructor
00182 //
00183 FWMuonBuilder::FWMuonBuilder()
00184 {
00185 }
00186 
00187 FWMuonBuilder::~FWMuonBuilder()
00188 {
00189 }
00190 
00191 //
00192 // member functions
00193 //
00194 //______________________________________________________________________________
00195 
00196 void
00197 FWMuonBuilder::calculateField( const reco::Muon& iData, FWMagField* field )
00198 {
00199    // if auto field estimation mode, do extra loop over muons.
00200    // use both inner and outer track if available
00201    if( field->getSource() == FWMagField::kNone )
00202    {
00203       if( fabs( iData.eta() ) > 2.0 || iData.pt() < 3 ) return;
00204       if( iData.innerTrack().isAvailable())
00205       {
00206          double estimate = fw::estimate_field( *( iData.innerTrack()), true );
00207          if( estimate >= 0 ) field->guessField( estimate );      
00208       }
00209       if( iData.outerTrack().isAvailable() )
00210       {
00211          double estimate = fw::estimate_field( *( iData.outerTrack()));
00212          if( estimate >= 0 ) field->guessFieldIsOn( estimate > 0.5 );
00213       }
00214    }
00215 }
00216 
00217 //______________________________________________________________________________
00218 
00219 void
00220 FWMuonBuilder::buildMuon( FWProxyBuilderBase* pb,
00221                           const reco::Muon* muon,
00222                           TEveElement* tList,
00223                           bool showEndcap,
00224                           bool tracksOnly )
00225 {
00226    calculateField( *muon, pb->context().getField());
00227   
00228    TEveRecTrack recTrack;
00229    recTrack.fBeta = 1.;
00230 
00231    // If we deal with a tracker muon we use the inner track and guide it
00232    // through the trajectory points from the reconstruction. Segments
00233    // represent hits. Matching between hits and the trajectory shows
00234    // how well the inner track matches with the muon hypothesis.
00235    //
00236    // In other cases we use a global muon track with a few states from 
00237    // the inner and outer tracks or just the outer track if it's the
00238    // only option
00239 
00240    if( muon->isTrackerMuon() && 
00241        muon->innerTrack().isAvailable() &&
00242        muon->isMatchesValid() &&
00243        !buggyMuon( &*muon, pb->context().getGeom()))
00244    {
00245       TEveTrack* trk = fireworks::prepareTrack( *(muon->innerTrack()),
00246                                                 pb->context().getMuonTrackPropagator(),
00247                                                 getRecoTrajectoryPoints( muon, pb->item()));
00248       trk->MakeTrack();
00249       pb->setupAddElement( trk, tList );
00250       if( ! tracksOnly )
00251          addMatchInformation( &(*muon), pb, tList, showEndcap );
00252       return;
00253    } 
00254 
00255    if( muon->isGlobalMuon() &&
00256        muon->globalTrack().isAvailable())
00257    {
00258       std::vector<TEveVector> extraPoints;
00259       if( muon->innerTrack().isAvailable() &&  muon->innerTrack()->extra().isAvailable())
00260       {
00261          extraPoints.push_back( TEveVector( muon->innerTrack()->innerPosition().x(),
00262                                             muon->innerTrack()->innerPosition().y(),
00263                                             muon->innerTrack()->innerPosition().z()));
00264          extraPoints.push_back( TEveVector( muon->innerTrack()->outerPosition().x(),
00265                                             muon->innerTrack()->outerPosition().y(),
00266                                             muon->innerTrack()->outerPosition().z()));
00267       }
00268       if( muon->outerTrack().isAvailable() &&  muon->outerTrack()->extra().isAvailable())
00269       {
00270          extraPoints.push_back( TEveVector( muon->outerTrack()->innerPosition().x(),
00271                                             muon->outerTrack()->innerPosition().y(),
00272                                             muon->outerTrack()->innerPosition().z()));
00273          extraPoints.push_back( TEveVector( muon->outerTrack()->outerPosition().x(),
00274                                             muon->outerTrack()->outerPosition().y(),
00275                                             muon->outerTrack()->outerPosition().z()));
00276       }
00277       TEveTrack* trk = fireworks::prepareTrack( *( muon->globalTrack()),
00278                                                 pb->context().getMuonTrackPropagator(),
00279                                                 extraPoints );
00280       trk->MakeTrack();
00281       pb->setupAddElement( trk, tList );
00282       return;
00283    }
00284 
00285    if( muon->innerTrack().isAvailable())
00286    {
00287       TEveTrack* trk = fireworks::prepareTrack( *( muon->innerTrack()), pb->context().getMuonTrackPropagator());
00288       trk->MakeTrack();
00289       pb->setupAddElement( trk, tList );
00290       return;
00291    }
00292 
00293    if( muon->outerTrack().isAvailable())
00294    {
00295       TEveTrack* trk = fireworks::prepareTrack( *( muon->outerTrack()), pb->context().getMuonTrackPropagator());
00296       trk->MakeTrack();
00297       pb->setupAddElement( trk, tList );
00298       return;
00299    }
00300    
00301    // if got that far it means we have nothing but a candidate
00302    // show it anyway.
00303    TEveTrack* trk = fireworks::prepareCandidate( *muon, pb->context().getMuonTrackPropagator());
00304    trk->MakeTrack();
00305    pb->setupAddElement( trk, tList );
00306 }