00001
00002
00003
00004
00005
00006
00007
00008
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
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
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
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
00056
00057 void
00058 FWElectronDetailView::build( const FWModelId &id, const reco::GsfElectron* iElectron )
00059 {
00060 if( !iElectron ) return;
00061
00062
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
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
00093 if( iElectron->superCluster().isAvailable() ) {
00094 addTrackPointsInCaloData( iElectron, lego );
00095 drawCrossHair( iElectron, lego, m_eveScene );
00096 addSceneInfo( iElectron, m_eveScene );
00097 }
00098
00099
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 );
00107 viewerGL()->AddOverlayElement( overlay );
00108 }
00109
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
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
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
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;
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
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
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
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
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
00313
00314
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
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
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
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
00421
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);