TEveCalo2DGL.cxx

Go to the documentation of this file.
00001 // @(#)root/eve:$Id: TEveCalo2DGL.cxx 37352 2010-12-06 19:27:22Z matevz $
00002 // Author: Matevz Tadel 2007
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 #include "TEveCalo2DGL.h"
00013 #include "TEveCalo.h"
00014 #include "TEveProjections.h"
00015 #include "TEveProjectionManager.h"
00016 #include "TEveRGBAPalette.h"
00017 
00018 #include "TGLRnrCtx.h"
00019 #include "TGLPhysicalShape.h"
00020 #include "TGLSelectRecord.h"
00021 #include "TGLIncludes.h"
00022 #include "TGLUtil.h"
00023 #include "TAxis.h"
00024 
00025 //______________________________________________________________________________
00026 // OpenGL renderer class for TEveCalo2D.
00027 //
00028 
00029 ClassImp(TEveCalo2DGL);
00030 
00031 //______________________________________________________________________________
00032 TEveCalo2DGL::TEveCalo2DGL() :
00033    TGLObject(),
00034    fM(0)
00035 {
00036    // Constructor.
00037 
00038    // fDLCache = kFALSE; // Disable display list.
00039    fMultiColor = kTRUE;
00040 }
00041 
00042 /******************************************************************************/
00043 
00044 //______________________________________________________________________________
00045 Bool_t TEveCalo2DGL::SetModel(TObject* obj, const Option_t* /*opt*/)
00046 {
00047    // Set model object.
00048 
00049    fM = SetModelDynCast<TEveCalo2D>(obj);
00050    return kTRUE;
00051 }
00052 
00053 //______________________________________________________________________________
00054 void TEveCalo2DGL::SetBBox()
00055 {
00056    // Set bounding box.
00057 
00058    SetAxisAlignedBBox(((TEveCalo2D*)fExternalObj)->AssertBBox());
00059 }
00060 
00061 /******************************************************************************/
00062 //______________________________________________________________________________
00063 Bool_t TEveCalo2DGL::IsRPhi() const
00064 {
00065    // Is current projection type RPhi
00066 
00067    return fM->fManager->GetProjection()->GetType() == TEveProjection::kPT_RPhi;
00068 }
00069 
00070 //______________________________________________________________________________
00071 void TEveCalo2DGL::MakeRPhiCell(Float_t phiMin, Float_t phiMax,
00072                                    Float_t towerH, Float_t offset) const
00073 {
00074    // Calculate vertices for the calorimeter cell in RPhi projection.
00075    // Returns outside radius of the tower.
00076 
00077    using namespace TMath;
00078 
00079    Float_t r1 = fM->fBarrelRadius + offset;
00080    Float_t r2 = r1 + towerH;
00081 
00082    Float_t pnts[8];
00083 
00084    pnts[0] = r1*Cos(phiMin); pnts[1] = r1*Sin(phiMin);
00085    pnts[2] = r2*Cos(phiMin); pnts[3] = r2*Sin(phiMin);
00086    pnts[4] = r2*Cos(phiMax); pnts[5] = r2*Sin(phiMax);
00087    pnts[6] = r1*Cos(phiMax); pnts[7] = r1*Sin(phiMax);
00088 
00089    Float_t x, y, z;
00090    glBegin(GL_QUADS);
00091    for (Int_t i = 0; i < 4; ++i)
00092    {
00093       x = pnts[2*i];
00094       y = pnts[2*i+1];
00095       z = 0.f;
00096       fM->fManager->GetProjection()->ProjectPoint(x, y, z, fM->fDepth);
00097       glVertex3f(x, y, z);
00098    }
00099    glEnd();
00100 }
00101 
00102 //______________________________________________________________________________
00103 void TEveCalo2DGL::DrawRPhi(TGLRnrCtx & rnrCtx, TEveCalo2D::vBinCells_t& cellLists) const
00104 {
00105    // Draw calorimeter cells in RPhi projection.
00106 
00107    TEveCaloData* data = fM->GetData();
00108    Int_t    nSlices  = data->GetNSlices();
00109    Float_t *sliceVal = new Float_t[nSlices];
00110    TEveCaloData::CellData_t cellData;
00111    Float_t towerH;
00112 
00113    UInt_t nPhi = data->GetPhiBins()->GetNbins();
00114    TAxis* axis = data->GetPhiBins();
00115    for(UInt_t phiBin = 1; phiBin <= nPhi; ++phiBin)
00116    {
00117       if (cellLists[phiBin] )
00118       {
00119          // reset values
00120          Float_t off = 0;
00121          for (Int_t s=0; s<nSlices; ++s)
00122             sliceVal[s] = 0;
00123 
00124          // sum eta cells
00125          TEveCaloData::vCellId_t* cids = cellLists[phiBin];
00126          for (TEveCaloData::vCellId_i it = cids->begin(); it != cids->end(); it++)
00127          {
00128             data->GetCellData(*it, cellData);
00129             sliceVal[(*it).fSlice] += cellData.Value(fM->fPlotEt)*(*it).fFraction;
00130          }
00131 
00132          if (rnrCtx.SecSelection()) {
00133             glLoadName(phiBin); // set name-stack phi bin
00134             glPushName(0);
00135          }
00136          for (Int_t s = 0; s < nSlices; ++s)
00137          {
00138             if (rnrCtx.SecSelection())  glLoadName(s); // set name-stack slice
00139             fM->SetupColorHeight(sliceVal[s], s, towerH);
00140             MakeRPhiCell(axis->GetBinLowEdge(phiBin), axis->GetBinUpEdge(phiBin), towerH, off);
00141             off += towerH;
00142          }
00143          if (rnrCtx.SecSelection()) glPopName(); // slice
00144       }
00145    }
00146 
00147    delete [] sliceVal;
00148 }
00149 
00150 //______________________________________________________________________________
00151 void TEveCalo2DGL::DrawRPhiHighlighted(std::vector<TEveCaloData::vCellId_t*>& cellLists) const
00152 {
00153    // Draw selected calorimeter cells in RPhi projection.
00154 
00155    static const TEveException eh("TEveCalo2DGL::DrawRPhiHighlighted ");
00156 
00157    TEveCaloData* data = fM->fData;
00158    TEveCaloData::CellData_t cellData;
00159    Int_t  nSlices  = data->GetNSlices();
00160    UInt_t nPhiBins = data->GetPhiBins()->GetNbins();
00161    Float_t *sliceVal    = new Float_t[nSlices];
00162    Float_t *sliceValRef = new Float_t[nSlices];
00163    Float_t  towerH, towerHRef;
00164 
00165    TAxis* axis = data->GetPhiBins();
00166    for(UInt_t phiBin = 1; phiBin <= nPhiBins; ++phiBin)
00167    {
00168       if (cellLists[phiBin])
00169       {
00170          if (!fM->fCellLists[phiBin])
00171             throw eh + "selected cell not in cell list cache.";
00172 
00173          Float_t off = 0;
00174          // selected eta sum
00175          for (Int_t s=0; s<nSlices; ++s) sliceVal[s] = 0;
00176          TEveCaloData::vCellId_t& cids = *(cellLists[phiBin]);
00177          for (TEveCaloData::vCellId_i i=cids.begin(); i!=cids.end(); i++) {
00178             data->GetCellData((*i), cellData);
00179             sliceVal[i->fSlice] += cellData.Value(fM->fPlotEt)*(*i).fFraction;
00180          }
00181          // referenced eta sum
00182          for (Int_t s=0; s<nSlices; ++s) sliceValRef[s] = 0;
00183          TEveCaloData::vCellId_t& cidsRef = *(fM->fCellLists[phiBin]);
00184          for (TEveCaloData::vCellId_i i=cidsRef.begin(); i!=cidsRef.end(); i++) {
00185             data->GetCellData(*i, cellData);
00186             sliceValRef[i->fSlice] += cellData.Value(fM->fPlotEt)*(*i).fFraction;
00187          }
00188          // draw
00189          for (Int_t s = 0; s < nSlices; ++s)  {
00190             fM->SetupColorHeight(sliceValRef[s], s, towerHRef);
00191             if (sliceVal[s] > 0)
00192             {
00193                fM->SetupColorHeight(sliceVal[s], s, towerH);
00194                MakeRPhiCell(axis->GetBinLowEdge(phiBin), axis->GetBinUpEdge(phiBin), towerH, off);
00195             }
00196             off += towerHRef;
00197          }
00198       }
00199    }
00200 
00201    delete [] sliceVal;
00202    delete [] sliceValRef;
00203 }
00204 
00205 
00206 /*******************************************************************************/
00207 /*******************************************************************************/
00208 
00209 //______________________________________________________________________________
00210 void TEveCalo2DGL::MakeRhoZCell(Float_t thetaMin, Float_t thetaMax,
00211                                 Float_t& offset, Bool_t isBarrel,  Bool_t phiPlus, Float_t towerH) const
00212 {
00213    // Draw cell in RhoZ projection.
00214 
00215    using namespace TMath;
00216 
00217    Float_t pnts[8];
00218 
00219    Float_t sin1 = Sin(thetaMin);
00220    Float_t cos1 = Cos(thetaMin);
00221    Float_t sin2 = Sin(thetaMax);
00222    Float_t cos2 = Cos(thetaMax);
00223 
00224    if (isBarrel)
00225    {
00226       Float_t r1 = fM->fBarrelRadius/Abs(Sin(0.5f*(thetaMin+thetaMax))) + offset;
00227       Float_t r2 = r1 + towerH;
00228 
00229       pnts[0] = r1*sin1; pnts[1] = r1*cos1;
00230       pnts[2] = r2*sin1; pnts[3] = r2*cos1;
00231       pnts[4] = r2*sin2; pnts[5] = r2*cos2;
00232       pnts[6] = r1*sin2; pnts[7] = r1*cos2;
00233    }
00234    else
00235    {
00236       // endcap
00237       Float_t r1 = fM->GetEndCapPos()/Abs(Cos(0.5f*(thetaMin+thetaMax))) + offset;
00238       Float_t r2 = r1 + towerH;
00239 
00240       pnts[0] = r1*sin1; pnts[1] = r1*cos1;
00241       pnts[2] = r2*sin1; pnts[3] = r2*cos1;
00242       pnts[4] = r2*sin2; pnts[5] = r2*cos2;
00243       pnts[6] = r1*sin2; pnts[7] = r1*cos2;
00244    }
00245 
00246    glBegin(GL_QUADS);
00247    Float_t x, y, z;
00248    for (Int_t i = 0; i < 4; ++i)
00249    {
00250       x = 0.f;
00251       y = phiPlus ? Abs(pnts[2*i]) : -Abs(pnts[2*i]);
00252       z = pnts[2*i+1];
00253       fM->fManager->GetProjection()->ProjectPoint(x, y, z, fM->fDepth);
00254       glVertex3f(x, y, z);
00255    }
00256    glEnd();
00257 }
00258 
00259 //______________________________________________________________________________
00260 void TEveCalo2DGL::DrawRhoZ(TGLRnrCtx & rnrCtx, TEveCalo2D::vBinCells_t& cellLists) const
00261 {
00262    // Draw calorimeter in RhoZ projection.
00263 
00264    TEveCaloData* data = fM->GetData();
00265    Int_t nSlices = data->GetNSlices();
00266 
00267    TEveCaloData::CellData_t cellData;
00268    Float_t *sliceValsUp  = new Float_t[nSlices];
00269    Float_t *sliceValsLow = new Float_t[nSlices];
00270    Bool_t   isBarrel;
00271    Float_t  towerH;
00272    Float_t transEta = fM->GetTransitionEta();
00273 
00274    TAxis* axis = data->GetEtaBins();
00275    UInt_t nEta = axis->GetNbins();
00276    for (UInt_t etaBin = 1; etaBin <= nEta; ++etaBin)
00277    {
00278       if (cellLists[etaBin] )
00279       {
00280          assert(fM->fCellLists[etaBin]);
00281          Float_t etaMin = axis->GetBinLowEdge(etaBin);
00282          Float_t etaMax = axis->GetBinUpEdge(etaBin);
00283          Float_t thetaMin = TEveCaloData::EtaToTheta(etaMax);
00284          Float_t thetaMax = TEveCaloData::EtaToTheta(etaMin);
00285 
00286          // clear
00287          Float_t offUp  = 0;
00288          Float_t offLow = 0;
00289          for (Int_t s = 0; s < nSlices; ++s) {
00290             sliceValsUp [s] = 0;
00291             sliceValsLow[s] = 0;
00292          }
00293          // values
00294          TEveCaloData::vCellId_t* cids = cellLists[etaBin];
00295          for (TEveCaloData::vCellId_i it = cids->begin(); it != cids->end(); ++it)
00296          {
00297             data->GetCellData(*it, cellData);
00298             if (cellData.Phi() > 0)
00299                sliceValsUp [it->fSlice] += cellData.Value(fM->fPlotEt)*(*it).fFraction;
00300             else
00301                sliceValsLow[it->fSlice] += cellData.Value(fM->fPlotEt)*(*it).fFraction;
00302          }
00303 
00304          isBarrel = true;
00305          if ((etaMax > 0 && etaMax > transEta) ||
00306              (etaMin < 0 && etaMin < -transEta))
00307          {
00308             isBarrel = false;
00309          }
00310 
00311          // draw
00312          if (rnrCtx.SecSelection()) glLoadName(etaBin); // name-stack eta bin
00313          if (rnrCtx.SecSelection()) glPushName(0);
00314 
00315          for (Int_t s = 0; s < nSlices; ++s)
00316          {
00317             if (rnrCtx.SecSelection()) glLoadName(s);  // name-stack slice
00318             if (rnrCtx.SecSelection()) glPushName(0);
00319             //  phi +
00320             if (sliceValsUp[s])
00321             {
00322                if (rnrCtx.SecSelection()) glLoadName(1);  // name-stack phi sign
00323                fM->SetupColorHeight(sliceValsUp[s], s, towerH);
00324                MakeRhoZCell(thetaMin, thetaMax, offUp, isBarrel, kTRUE , towerH);
00325                offUp += towerH;
00326             }
00327             // phi -
00328             if (sliceValsLow[s])
00329             {
00330                if (rnrCtx.SecSelection()) glLoadName(0);  // name-stack phi sign
00331                fM->SetupColorHeight(sliceValsLow[s], s, towerH);
00332                MakeRhoZCell(thetaMin, thetaMax, offLow, isBarrel, kFALSE , towerH);
00333                offLow += towerH;
00334             }
00335             if (rnrCtx.SecSelection())  glPopName(); // phi sign is pos
00336          }
00337          //
00338          if (rnrCtx.SecSelection())  glPopName(); // slice
00339       }
00340    }
00341 
00342    delete [] sliceValsUp;
00343    delete [] sliceValsLow;
00344 }
00345 
00346 //______________________________________________________________________________
00347 void TEveCalo2DGL::DrawRhoZHighlighted(std::vector<TEveCaloData::vCellId_t*>& cellLists) const
00348 {
00349    // Draw selected calorimeter cells in RhoZ projection.
00350 
00351    static const TEveException eh("TEveCalo2DGL::DrawRhoZHighlighted ");
00352 
00353    TEveCaloData* data = fM->GetData();
00354    TAxis* axis        = data->GetEtaBins();
00355    UInt_t nEtaBins    = axis->GetNbins();
00356    Int_t  nSlices     = data->GetNSlices();
00357 
00358    Float_t *sliceValsUp     = new Float_t[nSlices];
00359    Float_t *sliceValsLow    = new Float_t[nSlices];
00360    Float_t *sliceValsUpRef  = new Float_t[nSlices];
00361    Float_t *sliceValsLowRef = new Float_t[nSlices];
00362 
00363    Bool_t   isBarrel;
00364    Float_t  towerH, towerHRef, offUp, offLow;
00365    TEveCaloData::CellData_t cellData;
00366 
00367    for (UInt_t etaBin = 1; etaBin <= nEtaBins; ++etaBin)
00368    {
00369       if (cellLists[etaBin])
00370       {
00371          if (!fM->fCellLists[etaBin])
00372             throw(eh + "selected cell not in cell list cache.");
00373 
00374          offUp = 0; offLow =0;
00375          // selected phi sum
00376          for (Int_t s = 0; s < nSlices; ++s) {
00377             sliceValsUp[s] = 0; sliceValsLow[s] = 0;
00378          }
00379          TEveCaloData::vCellId_t& cids = *(cellLists[etaBin]);
00380          for (TEveCaloData::vCellId_i i=cids.begin(); i!=cids.end(); i++) {
00381             data->GetCellData(*i, cellData);
00382             if (cellData.Phi() > 0)
00383                sliceValsUp [i->fSlice] += cellData.Value(fM->fPlotEt)*(*i).fFraction;
00384             else
00385                sliceValsLow[i->fSlice] += cellData.Value(fM->fPlotEt)*(*i).fFraction;
00386          }
00387 
00388          // reference phi sum
00389          for (Int_t s = 0; s < nSlices; ++s) {
00390             sliceValsUpRef[s] = 0; sliceValsLowRef[s] = 0;
00391          }
00392          TEveCaloData::vCellId_t& cidsRef = *(fM->fCellLists[etaBin]);
00393          for (TEveCaloData::vCellId_i i=cidsRef.begin(); i!=cidsRef.end(); i++) {
00394             data->GetCellData(*i, cellData);
00395             if (cellData.Phi() > 0)
00396                sliceValsUpRef [i->fSlice] += cellData.Value(fM->fPlotEt)*(*i).fFraction;
00397             else
00398                sliceValsLowRef[i->fSlice] += cellData.Value(fM->fPlotEt)*(*i).fFraction;
00399          }
00400 
00401          isBarrel = TMath::Abs(axis->GetBinCenter(etaBin)) < fM->GetTransitionEta();
00402          for (Int_t s = 0; s < nSlices; ++s)
00403          {
00404             Float_t thetaMin = TEveCaloData::EtaToTheta(axis->GetBinUpEdge(etaBin));
00405             Float_t thetaMax = TEveCaloData::EtaToTheta(axis->GetBinLowEdge(etaBin));
00406             //  phi +
00407             fM->SetupColorHeight(sliceValsUpRef[s], s, towerHRef);
00408             if (sliceValsUp[s] > 0) {
00409                fM->SetupColorHeight(sliceValsUp[s], s, towerH);
00410                MakeRhoZCell(thetaMin, thetaMax, offUp, isBarrel, kTRUE , towerH);
00411             }
00412             offUp += towerHRef;
00413 
00414             // phi -
00415             fM->SetupColorHeight(sliceValsLowRef[s], s, towerHRef);
00416             if (sliceValsLow[s] > 0) {
00417                fM->SetupColorHeight(sliceValsLow[s], s, towerH);
00418                MakeRhoZCell(thetaMin, thetaMax, offLow, isBarrel, kFALSE , towerH);
00419             }
00420             offLow += towerHRef;
00421          } // slices
00422       } // if eta bin
00423    } //eta bin
00424 
00425    delete [] sliceValsUp;
00426    delete [] sliceValsLow;
00427    delete [] sliceValsUpRef;
00428    delete [] sliceValsLowRef;
00429 }
00430 
00431 //______________________________________________________________________________
00432 void TEveCalo2DGL::DirectDraw(TGLRnrCtx & rnrCtx) const
00433 {
00434    // Render with OpenGL.
00435 
00436    TGLCapabilitySwitch light_off(GL_LIGHTING,  kFALSE);
00437    TGLCapabilitySwitch cull_off (GL_CULL_FACE, kFALSE);
00438 
00439    glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT);
00440    glEnable(GL_BLEND);
00441    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00442 
00443    if (fM->fCellIdCacheOK == kFALSE)
00444       fM->BuildCellIdCache();
00445 
00446    fM->AssertPalette();
00447 
00448    if (rnrCtx.SecSelection()) glPushName(0);
00449    if (IsRPhi())
00450       DrawRPhi(rnrCtx, fM->fCellLists);
00451    else
00452       DrawRhoZ(rnrCtx, fM->fCellLists);
00453    if (rnrCtx.SecSelection()) glPopName();
00454    glPopAttrib();
00455 }
00456 
00457 //______________________________________________________________________________
00458 void TEveCalo2DGL::DrawHighlight(TGLRnrCtx& rnrCtx, const TGLPhysicalShape* /*pshp*/, Int_t /*lvl*/) const
00459 {
00460    // Draw towers in highlight mode.
00461 
00462    static const TEveException eh("TEveCalo2DGL::DrawHighlight ");
00463 
00464    if (fM->fData->GetCellsSelected().empty() && fM->fData->GetCellsHighlighted().empty())
00465       return;
00466 
00467    glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT |GL_POLYGON_BIT );
00468    glDisable(GL_LIGHTING);
00469    glDisable(GL_CULL_FACE);
00470    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00471 
00472    TGLUtil::LineWidth(2);
00473    TGLUtil::LockColor();
00474    try
00475    {
00476       if (!fM->fData->GetCellsHighlighted().empty())
00477       {
00478          glColor4ubv(rnrCtx.ColorSet().Selection(3).CArr());
00479 
00480          if (IsRPhi())
00481             DrawRPhiHighlighted(fM->fCellListsHighlighted);
00482          else
00483             DrawRhoZHighlighted(fM->fCellListsHighlighted);
00484       }
00485       if (!fM->fData->GetCellsSelected().empty())
00486       {
00487          Float_t dr[2];
00488          glGetFloatv(GL_DEPTH_RANGE,dr);
00489          glColor4ubv(rnrCtx.ColorSet().Selection(1).CArr());
00490          glDepthRange(dr[0], 0.8*dr[1]);
00491          if (IsRPhi())
00492             DrawRPhiHighlighted(fM->fCellListsSelected);
00493          else
00494             DrawRhoZHighlighted(fM->fCellListsSelected);
00495 
00496          glDepthRange(dr[0], dr[1]);
00497       }
00498    }
00499    catch (TEveException& exc)
00500    {
00501       Warning(eh, "%s", exc.what());
00502    }
00503 
00504    TGLUtil::UnlockColor();
00505    glPopAttrib();
00506 }
00507 
00508 //______________________________________________________________________________
00509 void TEveCalo2DGL::ProcessSelection(TGLRnrCtx & /*rnrCtx*/, TGLSelectRecord & rec)
00510 {
00511    // Processes tower selection in eta bin or phi bin.
00512    // Virtual function from TGLogicalShape. Called from TGLViewer.
00513 
00514    TEveCaloData::vCellId_t sel;
00515    if (rec.GetN() > 2)
00516    {
00517       Int_t bin   = rec.GetItem(1);
00518       Int_t slice = rec.GetItem(2);
00519       for (TEveCaloData::vCellId_i it = fM->fCellLists[bin]->begin();
00520            it != fM->fCellLists[bin]->end(); ++it)
00521       {
00522          if ((*it).fSlice == slice)
00523          {
00524             if (IsRPhi())
00525             {
00526                sel.push_back(*it);
00527             }
00528             else
00529             {
00530                assert(rec.GetN() > 3);
00531                Bool_t is_upper = (rec.GetItem(3) == 1);
00532                TEveCaloData::CellData_t cd;
00533                fM->fData->GetCellData(*it, cd);
00534                if ((is_upper && cd.Phi() > 0) || (!is_upper && cd.Phi() < 0))
00535                   sel.push_back(*it);
00536             }
00537          }
00538       }
00539    }
00540    fM->fData->ProcessSelection(sel, rec);
00541 }

Generated on Tue Jul 5 14:16:10 2011 for ROOT_528-00b_version by  doxygen 1.5.1