CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_10_patch2/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.38 2012/06/09 03:54:38 amraktad 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 != chamberEnd; ++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] == 2 ) // TGeoBBox
00102       {
00103         segmentLength = det->shape[3];
00104       }
00105       else
00106       {   
00107         const double segmentLength = 15;
00108         fwLog( fwlog::kWarning ) << Form("FWMuonBuilder: unknown shape type in muon chamber with detId=%d. Setting segment length to %.0f cm.\n",  rawid, segmentLength);
00109       }
00110         
00111       if( ids.insert( rawid ).second &&  // ensure that we add same chamber only once
00112           ( chamber->detector() != MuonSubdetId::CSC || showEndcap ))
00113       {     
00114         pb->setupAddElement( shape, parentList );
00115       }
00116      
00117       for( std::vector<reco::MuonSegmentMatch>::const_iterator segment = chamber->segmentMatches.begin(),
00118                                                             segmentEnd = chamber->segmentMatches.end();
00119            segment != segmentEnd; ++segment )
00120       {
00121         float segmentPosition[3]  = {    segment->x,     segment->y, 0.0 };
00122         float segmentDirection[3] = { segment->dXdZ,  segment->dYdZ, 0.0 };
00123 
00124         float localSegmentInnerPoint[3];
00125         float localSegmentOuterPoint[3];
00126 
00127         fireworks::createSegment( chamber->detector(), true, 
00128                                   segmentLength, segmentLimit, 
00129                                   segmentPosition, segmentDirection,
00130                                   localSegmentInnerPoint, localSegmentOuterPoint );
00131       
00132         float globalSegmentInnerPoint[3];
00133         float globalSegmentOuterPoint[3];
00134 
00135         geom->localToGlobal( *det, localSegmentInnerPoint,  globalSegmentInnerPoint );
00136         geom->localToGlobal( *det, localSegmentOuterPoint,  globalSegmentOuterPoint );
00137 
00138         segmentSet->AddLine( globalSegmentInnerPoint[0], globalSegmentInnerPoint[1], globalSegmentInnerPoint[2],
00139                              globalSegmentOuterPoint[0], globalSegmentOuterPoint[1], globalSegmentOuterPoint[2] );
00140       }
00141     }
00142   }
00143   
00144   if( !matches.empty() ) 
00145     pb->setupAddElement( segmentSet.release(), parentList );
00146 }
00147 
00148 //______________________________________________________________________________
00149 
00150 bool
00151 buggyMuon( const reco::Muon* muon,
00152            const FWGeometry* geom )
00153 {
00154    if( !muon->standAloneMuon().isAvailable() ||
00155        !muon->standAloneMuon()->extra().isAvailable())
00156      return false;
00157    
00158    float localTrajectoryPoint[3];
00159    float globalTrajectoryPoint[3];
00160    
00161    const std::vector<reco::MuonChamberMatch>& matches = muon->matches();
00162    for( std::vector<reco::MuonChamberMatch>::const_iterator chamber = matches.begin(),
00163                                                          chamberEnd = matches.end();
00164         chamber != chamberEnd; ++chamber )
00165    {
00166       // expected track position
00167       localTrajectoryPoint[0] = chamber->x;
00168       localTrajectoryPoint[1] = chamber->y;
00169       localTrajectoryPoint[2] = 0;
00170 
00171       unsigned int rawid = chamber->id.rawId();
00172       if( geom->contains( rawid ))
00173       {
00174          geom->localToGlobal( rawid, localTrajectoryPoint, globalTrajectoryPoint );
00175          double phi = atan2( globalTrajectoryPoint[1], globalTrajectoryPoint[0] );
00176          if( cos( phi - muon->standAloneMuon()->innerPosition().phi()) < 0 )
00177             return true;
00178       }
00179    }
00180    return false;
00181 }
00182 
00183 }
00184 
00185 //
00186 // constructors and destructor
00187 //
00188 FWMuonBuilder::FWMuonBuilder()
00189 {
00190 }
00191 
00192 FWMuonBuilder::~FWMuonBuilder()
00193 {
00194 }
00195 
00196 //
00197 // member functions
00198 //
00199 //______________________________________________________________________________
00200 
00201 void
00202 FWMuonBuilder::calculateField( const reco::Muon& iData, FWMagField* field )
00203 {
00204    // if auto field estimation mode, do extra loop over muons.
00205    // use both inner and outer track if available
00206    if( field->getSource() == FWMagField::kNone )
00207    {
00208       if( fabs( iData.eta() ) > 2.0 || iData.pt() < 3 ) return;
00209       if( iData.innerTrack().isAvailable())
00210       {
00211          double estimate = fw::estimate_field( *( iData.innerTrack()), true );
00212          if( estimate >= 0 ) field->guessField( estimate );      
00213       }
00214       if( iData.outerTrack().isAvailable() )
00215       {
00216          double estimate = fw::estimate_field( *( iData.outerTrack()));
00217          if( estimate >= 0 ) field->guessFieldIsOn( estimate > 0.5 );
00218       }
00219    }
00220 }
00221 
00222 //______________________________________________________________________________
00223 
00224 void
00225 FWMuonBuilder::buildMuon( FWProxyBuilderBase* pb,
00226                           const reco::Muon* muon,
00227                           TEveElement* tList,
00228                           bool showEndcap,
00229                           bool tracksOnly )
00230 {
00231    calculateField( *muon, pb->context().getField());
00232   
00233    TEveRecTrack recTrack;
00234    recTrack.fBeta = 1.;
00235 
00236    // If we deal with a tracker muon we use the inner track and guide it
00237    // through the trajectory points from the reconstruction. Segments
00238    // represent hits. Matching between hits and the trajectory shows
00239    // how well the inner track matches with the muon hypothesis.
00240    //
00241    // In other cases we use a global muon track with a few states from 
00242    // the inner and outer tracks or just the outer track if it's the
00243    // only option
00244 
00245    if( muon->isTrackerMuon() && 
00246        muon->innerTrack().isAvailable() &&
00247        muon->isMatchesValid() &&
00248        !buggyMuon( &*muon, pb->context().getGeom()))
00249    {
00250       TEveTrack* trk = fireworks::prepareTrack( *(muon->innerTrack()),
00251                                                 pb->context().getMuonTrackPropagator(),
00252                                                 getRecoTrajectoryPoints( muon, pb->item()));
00253       trk->MakeTrack();
00254       pb->setupAddElement( trk, tList );
00255       if( ! tracksOnly )
00256          addMatchInformation( &(*muon), pb, tList, showEndcap );
00257       return;
00258    } 
00259 
00260    if( muon->isGlobalMuon() &&
00261        muon->globalTrack().isAvailable())
00262    {
00263       std::vector<TEveVector> extraPoints;
00264       if( muon->innerTrack().isAvailable() &&  muon->innerTrack()->extra().isAvailable())
00265       {
00266          extraPoints.push_back( TEveVector( muon->innerTrack()->innerPosition().x(),
00267                                             muon->innerTrack()->innerPosition().y(),
00268                                             muon->innerTrack()->innerPosition().z()));
00269          extraPoints.push_back( TEveVector( muon->innerTrack()->outerPosition().x(),
00270                                             muon->innerTrack()->outerPosition().y(),
00271                                             muon->innerTrack()->outerPosition().z()));
00272       }
00273       if( muon->outerTrack().isAvailable() &&  muon->outerTrack()->extra().isAvailable())
00274       {
00275          extraPoints.push_back( TEveVector( muon->outerTrack()->innerPosition().x(),
00276                                             muon->outerTrack()->innerPosition().y(),
00277                                             muon->outerTrack()->innerPosition().z()));
00278          extraPoints.push_back( TEveVector( muon->outerTrack()->outerPosition().x(),
00279                                             muon->outerTrack()->outerPosition().y(),
00280                                             muon->outerTrack()->outerPosition().z()));
00281       }
00282       TEveTrack* trk = fireworks::prepareTrack( *( muon->globalTrack()),
00283                                                 pb->context().getMuonTrackPropagator(),
00284                                                 extraPoints );
00285       trk->MakeTrack();
00286       pb->setupAddElement( trk, tList );
00287       return;
00288    }
00289 
00290    if( muon->innerTrack().isAvailable())
00291    {
00292       TEveTrack* trk = fireworks::prepareTrack( *( muon->innerTrack()), pb->context().getMuonTrackPropagator());
00293       trk->MakeTrack();
00294       pb->setupAddElement( trk, tList );
00295       return;
00296    }
00297 
00298    if( muon->outerTrack().isAvailable())
00299    {
00300       TEveTrack* trk = fireworks::prepareTrack( *( muon->outerTrack()), pb->context().getMuonTrackPropagator());
00301       trk->MakeTrack();
00302       pb->setupAddElement( trk, tList );
00303       return;
00304    }
00305    
00306    // if got that far it means we have nothing but a candidate
00307    // show it anyway.
00308    TEveTrack* trk = fireworks::prepareCandidate( *muon, pb->context().getMuonTrackPropagator());
00309    trk->MakeTrack();
00310    pb->setupAddElement( trk, tList );
00311 }