CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/Fireworks/Electrons/plugins/FWElectronDetailView.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     Electrons
00004 // Class  :     FWElectronDetailView
00005 // $Id: FWElectronDetailView.cc,v 1.59 2011/02/28 10:32:01 amraktad Exp $
00006 //
00007 
00008 // ROOT includes
00009 #include "TLatex.h"
00010 #include "TEveCalo.h"
00011 #include "TEveStraightLineSet.h"
00012 #include "TEvePointSet.h"
00013 #include "TEveScene.h"
00014 #include "TEveViewer.h"
00015 #include "TGLViewer.h"
00016 #include "TGLOverlay.h"
00017 #include "TCanvas.h"
00018 #include "TLegend.h"
00019 #include "TEveCaloLegoOverlay.h"
00020 #include "TRootEmbeddedCanvas.h"
00021 
00022 // Fireworks includes
00023 #include "Fireworks/Electrons/plugins/FWElectronDetailView.h"
00024 #include "Fireworks/Calo/interface/FWECALDetailViewBuilder.h"
00025 #include "Fireworks/Core/interface/FWColorManager.h"
00026 #include "Fireworks/Core/interface/FWModelId.h"
00027 #include "Fireworks/Core/interface/FWEventItem.h"
00028 #include "Fireworks/Core/interface/FWGLEventHandler.h"
00029 
00030 // CMSSW includes
00031 #include "DataFormats/EcalDetId/interface/EcalSubdetector.h"
00032 #include "DataFormats/EgammaCandidates/interface/GsfElectron.h"
00033 #include "DataFormats/EgammaCandidates/interface/GsfElectronFwd.h"
00034 
00035 
00036 //
00037 // constructors and destructor
00038 //
00039 FWElectronDetailView::FWElectronDetailView() :
00040    m_data(0),
00041    m_builder(0),
00042    m_legend(0)
00043 {
00044 }
00045 
00046 FWElectronDetailView::~FWElectronDetailView()
00047 {  
00048    m_eveViewer->GetGLViewer()->DeleteOverlayElements(TGLOverlayElement::kUser);
00049 
00050    delete m_builder;
00051    if (m_data) m_data->DecDenyDestroy();
00052 }
00053 
00054 //
00055 // member functions
00056 //
00057 void
00058 FWElectronDetailView::build( const FWModelId &id, const reco::GsfElectron* iElectron )
00059 {
00060    if( !iElectron ) return;
00061    // If SuperCluster reference is not stored,
00062    // take eta and phi of a Candidate
00063    double eta = 0;
00064    double phi = 0;
00065    if( iElectron->superCluster().isAvailable() ) {
00066       eta = iElectron->caloPosition().eta();
00067       phi = iElectron->caloPosition().phi();
00068    }
00069    else 
00070    {
00071       eta = iElectron->eta();
00072       phi = iElectron->phi();
00073    }
00074 
00075    // build ECAL objects
00076    m_builder = new FWECALDetailViewBuilder( id.item()->getEvent(), id.item()->getGeom(),
00077                                             eta, phi, 25);
00078  
00079    m_builder->showSuperClusters();
00080    if( iElectron->superCluster().isAvailable() )
00081       m_builder->showSuperCluster( *(iElectron->superCluster() ), kYellow);
00082    TEveCaloLego* lego = m_builder->build();
00083    m_data = lego->GetData();
00084    m_eveScene->AddElement( lego );
00085 
00086    m_legend = new TLegend(0.01, 0.01, 0.99, 0.99, 0, "NDC");
00087    m_legend->SetTextSize(0.075);
00088    m_legend->SetBorderSize(0);
00089    m_legend->SetMargin(0.15);
00090    m_legend->SetEntrySeparation(0.05);
00091 
00092    // add Electron specific details
00093    if( iElectron->superCluster().isAvailable() ) {
00094       addTrackPointsInCaloData( iElectron, lego );
00095       drawCrossHair( iElectron, lego, m_eveScene );
00096       addSceneInfo( iElectron, m_eveScene );
00097    }
00098    
00099    // draw axis at the window corners
00100    if (1)
00101    {
00102    TEveCaloLegoOverlay* overlay = new TEveCaloLegoOverlay();
00103    overlay->SetShowPlane( kFALSE );
00104    overlay->SetShowPerspective( kFALSE );
00105    overlay->SetCaloLego( lego );
00106    overlay->SetShowScales( 1 ); // temporary
00107    viewerGL()->AddOverlayElement( overlay );
00108    }
00109    // set event handler and flip camera to top view at beginning
00110    viewerGL()->SetCurrentCamera( TGLViewer::kCameraOrthoXOY );
00111    FWGLEventHandler* eh =
00112       new FWGLEventHandler( (TGWindow*)viewerGL()->GetGLWidget(), (TObject*)viewerGL(), lego );
00113    viewerGL()->SetEventHandler( eh );
00114    viewerGL()->ResetCamerasAfterNextUpdate();
00115    viewerGL()->UpdateScene(kFALSE);
00116    gEve->Redraw3D();
00117 
00118    setTextInfo( id, iElectron );
00119 }
00120 
00121 double
00122 FWElectronDetailView::deltaEtaSuperClusterTrackAtVtx( const reco::GsfElectron &electron )
00123 {
00124    return electron.deltaEtaSuperClusterTrackAtVtx();
00125 }
00126 
00127 double
00128 FWElectronDetailView::deltaPhiSuperClusterTrackAtVtx( const reco::GsfElectron &electron )
00129 {
00130    return electron.deltaPhiSuperClusterTrackAtVtx();
00131 }
00132 
00133 void
00134 FWElectronDetailView::setTextInfo( const FWModelId& id, const reco::GsfElectron *electron )
00135 {
00136    m_infoCanvas->cd();
00137 
00138    float_t x  = 0.02;
00139    float_t x2 = 0.52;
00140    float   y  = 0.95;
00141 
00142    TLatex* latex = new TLatex( x, y, "" );
00143    const double textsize( 0.05 );
00144    latex->SetTextSize( 2*textsize );
00145 
00146    latex->DrawLatex( x, y, id.item()->modelName( id.index() ).c_str() );
00147    y -= latex->GetTextSize()*0.6;
00148 
00149    latex->SetTextSize( textsize );
00150    float lineH = latex->GetTextSize()*0.6;
00151 
00152    latex->DrawLatex( x, y, Form( " E_{T} = %.1f GeV, #eta = %0.2f, #varphi = %0.2f",
00153                                  electron->et(), electron->eta(), electron->phi()) );
00154    y -= lineH;
00155    // summary
00156    if( electron->charge() > 0 )
00157       latex->DrawLatex( x, y, " charge = +1" );
00158    else
00159       latex->DrawLatex( x, y, " charge = -1" );
00160    y -= lineH;
00161 
00162    if( electron->superCluster().isAvailable() ) {     
00163       // delta phi/eta in
00164       latex->DrawLatex( x, y, "SuperCluster vs inner state extrapolation" );
00165       y -= lineH;
00166       latex->DrawLatex(  x, y, TString::Format(" #Delta#eta_{in} = %.3f",   electron->deltaEtaSuperClusterTrackAtVtx()) );
00167       latex->DrawLatex( x2, y, TString::Format("#Delta#varphi_{in} = %.3f", electron->deltaPhiSuperClusterTrackAtVtx()) );
00168       y -= lineH;
00169 
00170       // delta phi/eta out
00171       latex->DrawLatex( x, y, "SeedCluster vs outer state extrapolation" );
00172       y -= lineH;
00173 
00174       latex->DrawLatex(  x, y, TString::Format(" #Delta#eta_{out} = %.3f",    electron->deltaEtaSeedClusterTrackAtCalo()) );
00175       latex->DrawLatex( x2, y, TString::Format(" #Delta#varphi_{out} = %.3f", electron->deltaPhiSeedClusterTrackAtCalo()) );
00176       y -= 2*lineH;
00177    } else {
00178      latex->DrawLatex( x, y, "Ref to SuperCluster is not available" );
00179    }
00180 
00181    latex->DrawLatex(x, y, TString::Format(" Tracker driven seed: %s", electron->trackerDrivenSeed() ? "YES" : "NO"));
00182    y -= lineH;
00183    latex->DrawLatex(x, y, TString::Format(" ECAL driven seed: %s",    electron->ecalDrivenSeed() ? "YES" : "NO"));
00184    y -= lineH;
00185 
00186    y = m_builder->makeLegend( 0.02, y );
00187    y -= lineH;
00188 
00189    m_legend->SetY2(y);
00190    m_legend->Draw();
00191    m_legend = 0; // Deleted together with TPad.
00192 }
00193 
00194 void
00195 FWElectronDetailView::drawCrossHair (const reco::GsfElectron* i, TEveCaloLego *lego, TEveElementList* tList)
00196 {
00197    unsigned int subdetId( 0 );
00198    
00199    if( !i->superCluster()->seed()->hitsAndFractions().empty() )
00200       subdetId = i->superCluster()->seed()->hitsAndFractions().front().first.subdetId();
00201 
00202    double ymax = lego->GetPhiMax();
00203    double ymin = lego->GetPhiMin();
00204    double xmax = lego->GetEtaMax();
00205    double xmin = lego->GetEtaMin();
00206 
00207    // draw crosshairs for track intersections
00208 
00209    {
00210       const double eta = i->superCluster()->seed()->position().eta() -
00211                          i->deltaEtaSeedClusterTrackAtCalo();
00212       const double phi = i->superCluster()->seed()->position().phi() -
00213                          i->deltaPhiSeedClusterTrackAtCalo();
00214 
00215       TEveStraightLineSet *trackpositionAtCalo = new TEveStraightLineSet("sc trackpositionAtCalo");
00216       trackpositionAtCalo->SetPickable(kTRUE);
00217       trackpositionAtCalo->SetTitle("Track position at Calo propagating from the outermost state");
00218       if (subdetId == EcalBarrel)
00219       {
00220          trackpositionAtCalo->AddLine(eta, ymin, 0, eta, ymax, 0);
00221          trackpositionAtCalo->AddLine(xmin, phi, 0, xmax, phi, 0);
00222       }
00223       else if (subdetId == EcalEndcap)
00224       {
00225          TVector3 pos;
00226          pos.SetPtEtaPhi(i->superCluster()->seed()->position().rho(), eta, phi);
00227          trackpositionAtCalo->AddLine(pos.X(), ymin, 0, pos.X(), ymax, 0);
00228          trackpositionAtCalo->AddLine(xmin, pos.Y(), 0, xmax,pos.Y(),0);
00229       }
00230       trackpositionAtCalo->SetDepthTest(kFALSE);
00231       trackpositionAtCalo->SetLineColor(kBlue);
00232       tList->AddElement(trackpositionAtCalo);
00233 
00234       m_legend->AddEntry(trackpositionAtCalo, "From outermost state", "l");
00235    }
00236    //
00237    // pin position
00238    //
00239    {
00240       TEveStraightLineSet *pinposition = new TEveStraightLineSet("pin position");
00241       pinposition->SetPickable(kTRUE);
00242       pinposition->SetTitle("Track position at Calo propagating from the innermost state");
00243       Double_t eta = i->caloPosition().eta() - deltaEtaSuperClusterTrackAtVtx(*i);
00244       Double_t phi = i->caloPosition().phi() - deltaPhiSuperClusterTrackAtVtx(*i);
00245 
00246       if (subdetId == EcalBarrel)
00247       {
00248          pinposition->AddLine(eta, ymax, 0, eta, ymin, 0);
00249          pinposition->AddLine(xmin, phi, 0, xmax, phi, 0);
00250       }
00251       else if (subdetId == EcalEndcap)
00252       {
00253          TVector3 pos;
00254          pos.SetPtEtaPhi(i->caloPosition().rho(), eta, phi);
00255          pinposition->AddLine(pos.X(),ymin, 0, pos.X(), ymax, 0);
00256          pinposition->AddLine(xmin, pos.Y(), 0, xmax, pos.Y(), 0);
00257       }
00258       pinposition->SetDepthTest(kFALSE);
00259       pinposition->SetLineColor(kRed);
00260       tList->AddElement(pinposition);
00261 
00262       m_legend->AddEntry(pinposition, "From innermost state", "l");
00263    }
00264 }
00265 
00266 Bool_t
00267 FWElectronDetailView::checkRange( Double_t &em, Double_t& eM, Double_t &pm, Double_t& pM,
00268                                   Double_t eta, Double_t phi )
00269 {
00270    Bool_t changed = kFALSE;
00271 
00272    //check eta
00273    if (eta < em)
00274    {
00275       em = eta;
00276       changed = kTRUE;
00277    }
00278    else if (eta > eM)
00279    {
00280       eM = eta;
00281       changed = kTRUE;
00282    }
00283 
00284    // check phi
00285    if (phi < pm)
00286    {
00287       pm = phi;
00288       changed = kTRUE;
00289    }
00290    else if (phi > pM)
00291    {
00292       pM = phi;
00293       changed = kTRUE;
00294    }
00295    return changed;
00296 }
00297 
00298 void
00299 FWElectronDetailView::addTrackPointsInCaloData( const reco::GsfElectron *i, TEveCaloLego* lego )
00300 {
00301    unsigned int subdetId(0);
00302 
00303    if ( !i->superCluster()->seed()->hitsAndFractions().empty() )
00304       subdetId = i->superCluster()->seed()->hitsAndFractions().front().first.subdetId();
00305 
00306    TEveCaloDataVec* data = (TEveCaloDataVec*)lego->GetData();
00307    Double_t em, eM, pm, pM;
00308    data->GetEtaLimits(em, eM);
00309    data->GetPhiLimits(pm, pM);
00310    data->IncDenyDestroy();
00311    Bool_t changed = kFALSE;
00312    // add cells in third layer if necessary
00313 
00314    //   trackpositionAtCalo
00315    {
00316       double eta = i->superCluster()->seed()->position().eta() -
00317                    i->deltaEtaSeedClusterTrackAtCalo();
00318       double phi = i->superCluster()->seed()->position().phi() -
00319                    i->deltaPhiSeedClusterTrackAtCalo();
00320 
00321       if (subdetId == EcalBarrel)
00322       {
00323          if (checkRange(em, eM, pm, pM, eta, phi))
00324             changed = kTRUE;
00325       }
00326       else if (subdetId == EcalEndcap) {
00327          TVector3 pos;
00328          pos.SetPtEtaPhi(i->superCluster()->seed()->position().rho(),eta, phi);
00329          if (checkRange(em, eM, pm, pM, pos.X(), pos.Y()))
00330             changed = kTRUE;
00331 
00332       }
00333    }
00334    // pinposition
00335    {
00336       double eta = i->caloPosition().eta() - deltaEtaSuperClusterTrackAtVtx(*i);
00337       double phi = i->caloPosition().phi() - deltaPhiSuperClusterTrackAtVtx(*i);
00338       if (subdetId == EcalBarrel)
00339       {
00340          if (checkRange(em, eM, pm, pM, eta, phi))
00341             changed = kTRUE;
00342       }
00343       else if (subdetId == EcalEndcap) {
00344          TVector3 pos;
00345          pos.SetPtEtaPhi(i->caloPosition().rho(), eta, phi);
00346          if (checkRange(em, eM, pm, pM, pos.X(), pos.Y()))
00347             changed = kTRUE;
00348       }
00349    }
00350    if (changed)
00351    {
00352       data->AddTower(em, eM, pm, pM);
00353       data->FillSlice(2, 0);   data->DataChanged();
00354 
00355       lego->ComputeBBox();
00356       Double_t legoScale = ((eM - em) < (pM - pm)) ? (eM - em) : (pM - pm);
00357       lego->InitMainTrans();
00358       lego->RefMainTrans().SetScale(legoScale, legoScale, legoScale*0.5);
00359       lego->RefMainTrans().SetPos((eM+em)*0.5, (pM+pm)*0.5, 0);
00360       lego->ElementChanged(true);
00361    }
00362 }
00363 
00364 void
00365 FWElectronDetailView::addSceneInfo(const reco::GsfElectron *i, TEveElementList* tList)
00366 {
00367    unsigned int subdetId(0);
00368 
00369    if ( !i->superCluster()->seed()->hitsAndFractions().empty() )
00370       subdetId = i->superCluster()->seed()->hitsAndFractions().front().first.subdetId();
00371 
00372    // centroids
00373    Double_t x(0), y(0), z(0);
00374    Double_t delta(0.02);
00375    if (subdetId == EcalEndcap) delta = 2.5;
00376    TEveStraightLineSet *scposition = new TEveStraightLineSet("sc position");
00377    scposition->SetPickable(kTRUE);
00378    scposition->SetTitle("Super cluster centroid");
00379    if (subdetId == EcalBarrel) {
00380       x = i->caloPosition().eta();
00381       y = i->caloPosition().phi();
00382    } else if (subdetId == EcalEndcap) {
00383       x = i->caloPosition().x();
00384       y = i->caloPosition().y();
00385    }
00386    scposition->AddLine(x-delta,y,z,x+delta,y,z);
00387    scposition->AddLine(x,y-delta,z,x,y+delta,z);
00388    scposition->AddLine(x,y,z-delta,x,y,z+delta);
00389    scposition->SetLineColor(kBlue);
00390    scposition->SetLineWidth(2);
00391    scposition->SetDepthTest(kFALSE);
00392    tList->AddElement(scposition);
00393 
00394    scposition->SetMarkerColor(kBlue);
00395    scposition->SetMarkerStyle(2);
00396    m_legend->AddEntry(scposition, "Super cluster centroid", "p");
00397 
00398    // seed position
00399    TEveStraightLineSet *seedposition = new TEveStraightLineSet("seed position");
00400    seedposition->SetTitle("Seed cluster centroid");
00401    seedposition->SetPickable(kTRUE);
00402    if (subdetId == EcalBarrel) {
00403       x  = i->superCluster()->seed()->position().eta();
00404       y  = i->superCluster()->seed()->position().phi();
00405    } else if (subdetId == EcalEndcap) {
00406       x  = i->superCluster()->seed()->position().x();
00407       y  = i->superCluster()->seed()->position().y();
00408    }
00409    seedposition->AddLine(x-delta,y-delta,z,x+delta,y+delta,z);
00410    seedposition->AddLine(x-delta,y+delta,z,x+delta,y-delta,z);
00411    seedposition->SetLineColor(kRed);
00412    seedposition->SetLineWidth(2);
00413    seedposition->SetDepthTest(kFALSE);
00414    tList->AddElement(seedposition);
00415 
00416    seedposition->SetMarkerColor(kRed);
00417    seedposition->SetMarkerStyle(5);
00418    m_legend->AddEntry(seedposition, "Seed cluster centroid", "p");
00419 
00420    // electron direction (show it if it's within
00421    // the area of interest)
00422    if ( fabs(i->phi()-i->caloPosition().phi())< 25*0.0172 &&
00423         fabs(i->eta()-i->caloPosition().eta())< 25*0.0172 )
00424    {
00425       TEveStraightLineSet *eldirection = new TEveStraightLineSet("seed position");
00426       eldirection->SetTitle("Electron direction at vertex");
00427       eldirection->SetPickable(kTRUE);
00428       if (subdetId == EcalBarrel) {
00429          x = i->eta();
00430          y = i->phi();
00431       }else{
00432          x = 310*fabs(tan(i->theta()))*cos(i->phi());
00433          y = 310*fabs(tan(i->theta()))*sin(i->phi());
00434       }
00435       eldirection->AddLine(x-delta,y-delta,z,x+delta,y+delta,z);
00436       eldirection->AddLine(x-delta,y+delta,z,x+delta,y-delta,z);
00437       eldirection->SetLineColor(kGreen);
00438       eldirection->SetDepthTest(kFALSE);
00439       tList->AddElement(eldirection);
00440 
00441       eldirection->SetMarkerColor(kGreen);
00442       eldirection->SetMarkerStyle(5);
00443       m_legend->AddEntry(eldirection, "Direction at vertex", "p");
00444    }
00445 }
00446 
00447 REGISTER_FWDETAILVIEW(FWElectronDetailView,Electron);