#include "TEveCaloLegoGL.h"
#include "TEveCalo.h"
#include "TEveRGBAPalette.h"
#include "TGLIncludes.h"
#include "TGLRnrCtx.h"
#include "TGLSelectRecord.h"
#include "TGLScene.h"
#include "TGLCamera.h"
#include "TGLContext.h"
#include "TGLUtil.h"
#include "TAxis.h"
#include "TObjString.h"
#include "TH2.h"
#include "THLimitsFinder.h"
ClassImp(TEveCaloLegoGL);
TEveCaloLegoGL::TEveCaloLegoGL() :
TGLObject(),
fDataMax(0),
fZAxisStep(0),
fEtaAxis(0),
fPhiAxis(0),
fXAxisAtt(),
fYAxisAtt(),
fZAxisAtt(),
fAxisPainter(),
fDLCacheOK(kFALSE),
fM(0),
fNBinSteps(5),
fBinSteps(0),
fTowerPicked(-1)
{
fDLCache = kFALSE;
fBinSteps = new Int_t[fNBinSteps];
fBinSteps[0] = 1;
fBinSteps[1] = 2;
fBinSteps[2] = 5;
fBinSteps[3] = 8;
fBinSteps[4] = 20;
fXAxisAtt.SetTMNDim(2);
fXAxisAtt.SetTextAlign(TGLAxisAttrib::kCenterDown);
fXAxisAtt.SetNdivisions(710);
fXAxisAtt.SetLabelSize(0.05);
fXAxisAtt.SetTitleSize(0.05);
fXAxisAtt.SetTitleFontName("symbol");
fXAxisAtt.SetTitle("h");
fYAxisAtt = fXAxisAtt;
fYAxisAtt.RefDir().Set(0., 1., 0.);
fYAxisAtt.SetNdivisions(510);
fYAxisAtt.SetTitle("f");
fZAxisAtt.RefDir().Set(0., 0., 1.);
fZAxisAtt.SetTextAlign(TGLAxisAttrib::kLeft);
fZAxisAtt.SetRelativeFontSize(kTRUE);
fZAxisAtt.SetLabelSize(0.07);
fZAxisAtt.SetTitleSize(0.07);
}
TEveCaloLegoGL::~TEveCaloLegoGL()
{
delete [] fBinSteps;
}
Bool_t TEveCaloLegoGL::SetModel(TObject* obj, const Option_t* )
{
if (SetModelCheckClass(obj, TEveCaloLego::Class())) {
fM = dynamic_cast<TEveCaloLego*>(obj);
return kTRUE;
}
return kFALSE;
}
void TEveCaloLegoGL::SetBBox()
{
SetAxisAlignedBBox(((TEveCaloLego*)fExternalObj)->AssertBBox());
}
void TEveCaloLegoGL::DLCacheDrop()
{
for (SliceDLMap_i i = fDLMap.begin(); i != fDLMap.end(); ++i)
i->second = 0;
TGLObject::DLCacheDrop();
}
void TEveCaloLegoGL::DLCachePurge()
{
static const TEveException eH("TEveCaloLegoGL::DLCachePurge ");
if (fDLMap.empty()) return;
for (SliceDLMap_i i = fDLMap.begin(); i != fDLMap.end(); ++i)
{
if (fScene) {
fScene->GetGLCtxIdentity()->RegisterDLNameRangeToWipe(i->second, 1);
} else {
glDeleteLists(i->second, 1);
}
i->second = 0;
}
TGLObject::DLCachePurge();
}
void TEveCaloLegoGL::MakeQuad(Float_t x1, Float_t y1, Float_t z1,
Float_t xw, Float_t yw, Float_t h) const
{
Float_t x2 = x1+xw;
Float_t y2 = y1+yw;
Float_t z2 = z1+h;
if (x1<fM->GetEtaMin()) x1= fM->GetEtaMin();
if (x2>fM->GetEtaMax()) x2= fM->GetEtaMax();
if (y1<fM->GetPhiMin()) y1= fM->GetPhiMin();
if (y2>fM->GetPhiMax()) y2= fM->GetPhiMax();
glBegin(GL_QUADS);
{
glNormal3f(0, 0, -1);
glVertex3f(x2, y2, z1);
glVertex3f(x2, y1, z1);
glVertex3f(x1, y1, z1);
glVertex3f(x1, y2, z1);
glNormal3f(0, 0, 1);
glVertex3f(x2, y2, z2);
glVertex3f(x1, y2, z2);
glVertex3f(x1, y1, z2);
glVertex3f(x2, y1, z2);
glNormal3f(1, 0, 0);
glVertex3f(x2, y2, z1);
glVertex3f(x2, y2, z2);
glVertex3f(x2, y1, z2);
glVertex3f(x2, y1, z1);
glNormal3f(-1, 0, 0);
glVertex3f(x1, y2, z1);
glVertex3f(x1, y1, z1);
glVertex3f(x1, y1, z2);
glVertex3f(x1, y2, z2);
glNormal3f(0, 1, 0);
glVertex3f(x2, y2, z1);
glVertex3f(x1, y2, z1);
glVertex3f(x1, y2, z2);
glVertex3f(x2, y2, z2);
glNormal3f(0, -1, 0);
glVertex3f(x2, y1, z1);
glVertex3f(x2, y1, z2);
glVertex3f(x1, y1, z2);
glVertex3f(x1, y1, z1);
}
glEnd();
}
void TEveCaloLegoGL::MakeDisplayList() const
{
TEveCaloData::CellData_t cellData;
Int_t prevTower = 0;
Float_t offset = 0;
Int_t nSlices = fM->fData->GetNSlices();
for (Int_t s = 0; s < nSlices; ++s)
{
if (fDLMap.empty() || fDLMap[s] == 0)
fDLMap[s] = glGenLists(1);
glNewList(fDLMap[s], GL_COMPILE);
for (UInt_t i = 0; i < fM->fCellList.size(); ++i)
{
if (fM->fCellList[i].fSlice > s) continue;
if (fM->fCellList[i].fTower != prevTower)
{
offset = 0;
prevTower = fM->fCellList[i].fTower;
}
fM->fData->GetCellData(fM->fCellList[i], fM->fPhi, fM->fPhiOffset, cellData);
if (s == fM->fCellList[i].fSlice)
{
glLoadName(i);
MakeQuad(cellData.EtaMin(), cellData.PhiMin(), offset,
cellData.EtaDelta(), cellData.PhiDelta(), cellData.Value(fM->fPlotEt));
}
offset += cellData.Value(fM->fPlotEt);
}
glEndList();
}
fDLCacheOK=kTRUE;
}
void TEveCaloLegoGL::DrawZAxis(TGLRnrCtx &rnrCtx, Float_t azX, Float_t azY) const
{
glPushMatrix();
glTranslatef(azX, azY, 0);
TGLMatrix modview;
glGetDoublev(GL_MODELVIEW_MATRIX, modview.Arr());
TGLVertex3 worldRef(azX, azY, fDataMax*0.5);
fZAxisAtt.SetAxisColor(fM->fGridColor);
fZAxisAtt.SetRng(0, fDataMax);
fZAxisAtt.SetNdivisions( fM->fNZSteps*100+10);
fZAxisAtt.RefTMOff(0) = rnrCtx.RefCamera().ViewportDeltaToWorld(worldRef, -10, 0, &modview);
fZAxisAtt.SetTitle(Form("Et[GeV] %s", TEveUtil::FormAxisValue(fDataMax)));
fZAxisAtt.RefTitlePos().Set(0, 0, fDataMax*1.05);
fAxisPainter.Paint(rnrCtx, fZAxisAtt);
glPopMatrix();
}
void TEveCaloLegoGL::DrawZScales3D(TGLRnrCtx & rnrCtx,
Float_t x0, Float_t x1,
Float_t y0, Float_t y1) const
{
const GLdouble *pm = rnrCtx.RefCamera().RefLastNoPickProjM().CArr();
GLdouble mm[16];
GLint vp[4];
glGetDoublev(GL_MODELVIEW_MATRIX, mm);
glGetIntegerv(GL_VIEWPORT, vp);
GLdouble x[4];
GLdouble y[4];
GLdouble z[4];
gluProject(x0, y0, 0, mm, pm, vp, &x[0], &y[0], &z[0]);
gluProject(x1, y0, 0, mm, pm, vp, &x[1], &y[1], &z[1]);
gluProject(x1, y1, 0, mm, pm, vp, &x[2], &y[2], &z[2]);
gluProject(x0, y1, 0, mm, pm, vp, &x[3], &y[3], &z[3]);
Int_t idxLeft = 0;
Float_t xt = x[0];
for (Int_t i = 1; i < 4; ++i)
{
if (x[i] < xt)
{
xt = x[i];
idxLeft = i;
}
}
Float_t azX = 0, azY = 0;
switch(idxLeft)
{
case 0:
azX = x0; azY = y0;
break;
case 1:
azX = x1; azY = y0;
break;
case 2:
azX = x1; azY = y1;
break;
case 3:
azX = x0; azY = y1;
break;
}
TGLUtil::Color(fM->fGridColor);
if (fM->fBoxMode)
{
Double_t zt = 1.f;
Int_t idxDepth = 0;
for (Int_t i = 0; i < 4; ++i)
{
if (z[i] < zt)
{
zt = z[i];
idxDepth = i;
}
}
Double_t zm = 1.f;
Int_t idxDepthT = 0;
for (Int_t i = 0; i < 4; ++i)
{
if (z[i] < zm && z[i] >= zt && i != idxDepth)
{
zm = z[i];
idxDepthT = i;
}
}
if (idxDepth == idxLeft) idxDepth =idxDepthT;
Float_t ayX = 0;
Float_t axY = 0;
Float_t cX = 0, cY = 0;
switch (idxDepth)
{
case 0:
axY=y1; ayX=x1;
cX=x0; cY=y0;
break;
case 1:
axY=y1; ayX=x0;
cX= x1; cY=y0;
break;
case 2:
axY=y0; ayX=x0;
cX=x1; cY=y1;
break;
case 3:
axY=y0; ayX=x1;
cX= x0; cY=y1;
break;
}
glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT);
glLineWidth(1);
glBegin(GL_LINES);
glVertex3f(x0, axY, 0); glVertex3f(x0, axY, fDataMax);
glVertex3f(x1, axY, 0); glVertex3f(x1, axY, fDataMax);
glVertex3f(ayX, y0, 0); glVertex3f(ayX, y0, fDataMax);
glVertex3f(ayX, y1, 0); glVertex3f(ayX, y1, fDataMax);
if (fM->fBoxMode == TEveCaloLego::kFrontBack)
{
glVertex3f(cX, cY, 0); glVertex3f(cX, cY, fDataMax);
}
glVertex3f(x0, axY, fDataMax); glVertex3f(x1, axY, fDataMax);
glVertex3f(ayX, y0, fDataMax); glVertex3f(ayX, y1, fDataMax);
if (fM->fBoxMode == TEveCaloLego::kFrontBack)
{
glVertex3f(cX, cY, fDataMax); glVertex3f(cX, axY, fDataMax);
glVertex3f(cX, cY, fDataMax); glVertex3f(ayX, cY, fDataMax);
}
glEnd();
glPopAttrib();
glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT);
glLineStipple(1, 0x5555);
glEnable(GL_LINE_STIPPLE);
glBegin(GL_LINES);
Int_t nhs = TMath::CeilNint(fDataMax/fZAxisStep);
Float_t hz = 0;
for (Int_t i = 1; i <= nhs; ++i, hz += fZAxisStep)
{
glVertex3f(x0, axY, hz); glVertex3f(x1, axY, hz);
glVertex3f(ayX, y0, hz); glVertex3f(ayX, y1, hz);
}
glEnd();
glPopAttrib();
}
DrawZAxis(rnrCtx, azX, azY);
if (fTowerPicked >= 0)
{
TEveCaloData::CellData_t cd;
fM->fData->GetCellData(fM->fCellList[fTowerPicked], fM->fPhi, fM->fPhiOffset, cd);
switch(idxLeft)
{
case 0:
azX = cd.EtaMin(); azY = cd.PhiMin();
break;
case 1:
azX = cd.EtaMax(); azY = cd.PhiMin();
break;
case 2:
azX = cd.EtaMax(); azY = cd.PhiMax();
break;
case 3:
azX = cd.EtaMin(); azY = cd.PhiMax();
break;
}
DrawZAxis(rnrCtx, azX, azY);
}
}
void TEveCaloLegoGL::DrawXYScales(TGLRnrCtx & rnrCtx,
Float_t x0, Float_t x1,
Float_t y0, Float_t y1) const
{
const GLdouble *pm = rnrCtx.RefCamera().RefLastNoPickProjM().CArr();
GLdouble mm[16];
GLint vp[4];
glGetDoublev(GL_MODELVIEW_MATRIX, mm);
glGetIntegerv(GL_VIEWPORT, vp);
GLdouble y, z[4], x[4];
gluProject(x0, y0, 0, mm, pm, vp, &x[0], &y, &z[0]);
gluProject(x1, y0, 0, mm, pm, vp, &x[1], &y, &z[1]);
gluProject(x1, y1, 0, mm, pm, vp, &x[2], &y, &z[2]);
gluProject(x0, y1, 0, mm, pm, vp, &x[3], &y, &z[3]);
Float_t zt = 1.f;
Float_t zm = 0.f;
Int_t idx = 0;
for (Int_t i = 0; i < 4; ++i)
{
if (z[i] < zt)
{
zt = z[i];
idx = i;
}
if (z[i] > zm) zm = z[i];
}
if (zm - zt < 1e-2) idx = 0;
Float_t axY = 0, ayX = 0;
Float_t axtX = 0, aytY = 0;
switch (idx)
{
case 0:
axY = y0; ayX = x0;
axtX = x1; aytY = y1;
break;
case 1:
ayX = x1; axY = y0;
axtX = x0; aytY = y1;
break;
case 2:
ayX = x1; axY = y1;
axtX = x0; aytY = y0;
break;
case 3:
ayX = x0; axY = y1;
axtX = x1; aytY = y0;
break;
}
Float_t zOff = -fDataMax*0.03;
Float_t yOff = 0.03*TMath::Sign(y1-y0, axY);
Float_t xOff = 0.03*TMath::Sign(x1-x0, ayX);
Float_t rxy = (fPhiAxis->GetXmax()-fPhiAxis->GetXmin())/(fEtaAxis->GetXmax()-fEtaAxis->GetXmin());
(rxy>1) ? yOff /= rxy : xOff *=rxy;
if (fXAxisAtt.GetRelativeFontSize() == kFALSE)
{
fXAxisAtt.SetAbsLabelFontSize(fZAxisAtt.GetAbsLabelFontSize());
fXAxisAtt.SetAbsTitleFontSize(Int_t(fZAxisAtt.GetAbsTitleFontSize()*0.8));
}
fXAxisAtt.SetRng(x0, x1);
fXAxisAtt.SetAxisColor(fM->fGridColor);
fXAxisAtt.RefTMOff(0).Set(0, yOff, 0);
fXAxisAtt.RefTMOff(1).Set(0, 0, zOff);
fXAxisAtt.RefTitlePos().Set(axtX, 0, 0);
glPushMatrix();
glTranslatef(0, axY, 0);
fAxisPainter.Paint(rnrCtx, fXAxisAtt);
glPopMatrix();
fYAxisAtt.SetRng(y0, y1);
fYAxisAtt.SetAxisColor(fM->fGridColor);
fYAxisAtt.RefTMOff(0).Set(xOff, 0, 0);
fYAxisAtt.RefTMOff(1).Set(0, 0, zOff);
fYAxisAtt.SetAbsLabelFontSize(fXAxisAtt.GetAbsLabelFontSize());
fYAxisAtt.SetAbsTitleFontSize(fXAxisAtt.GetAbsTitleFontSize());
fYAxisAtt.RefTitlePos().Set(0, aytY, 0);
glPushMatrix();
glTranslatef(ayX, 0, 0);
fAxisPainter.Paint(rnrCtx, fYAxisAtt);
glPopMatrix();
}
Int_t TEveCaloLegoGL::GetGridStep(Int_t axId, TGLRnrCtx &rnrCtx) const
{
GLdouble x0, y0, z0, x1, y1, z1;
GLdouble mm[16];
GLint vp[4];
glGetDoublev(GL_MODELVIEW_MATRIX, mm);
glGetIntegerv(GL_VIEWPORT, vp);
const GLdouble *pm = rnrCtx.RefCamera().RefLastNoPickProjM().CArr();
if (axId == 0)
{
Float_t bw = (fEtaAxis->GetXmax()-fEtaAxis->GetXmin())/fEtaAxis->GetNbins();
for (Int_t i=0; i<fNBinSteps; ++i)
{
gluProject(fM->GetEta(), fM->GetPhi(), 0, mm, pm, vp, &x0, &y0, &z0);
gluProject(fM->GetEta()+fBinSteps[i]*bw, fM->GetPhi(), 0, mm, pm, vp, &x1, &y1, &z1);
Float_t gapsqr = (x0-x1)*(x0-x1) + (y0-y1)*(y0-y1);
if (gapsqr > fM->fBinWidth*fM->fBinWidth)
return fBinSteps[i];
}
}
else if (axId == 1)
{
Double_t bw = (fPhiAxis->GetXmax()-fPhiAxis->GetXmin())/fPhiAxis->GetNbins();
for (Int_t i=0; i<fNBinSteps; ++i)
{
gluProject(fM->GetEta(), fM->GetPhi(), 0, mm, pm, vp, &x0, &y0, &z0);
gluProject(fM->GetEta(), fM->GetPhi()+fBinSteps[i]*bw, 0, mm, pm, vp, &x1, &y1, &z1);
Float_t gapsqr = (x0-x1)*(x0-x1) + (y0-y1)*(y0-y1);
if (gapsqr > fM->fBinWidth*fM->fBinWidth)
return fBinSteps[i];
}
}
return 1;
}
void TEveCaloLegoGL::DrawHistBase(TGLRnrCtx &rnrCtx) const
{
using namespace TMath;
Int_t es = GetGridStep(0, rnrCtx);
Int_t ps = GetGridStep(1, rnrCtx);
Float_t eta0 = fM->fEtaMin;
Float_t eta1 = fM->fEtaMax;
Float_t phi0 = fM->GetPhiMin();
Float_t phi1 = fM->GetPhiMax();
TGLCapabilitySwitch lights_off(GL_LIGHTING, kFALSE);
TGLCapabilitySwitch sw_blend(GL_BLEND, kTRUE);
TGLUtil::Color(fM->fGridColor);
glBegin(GL_LINES);
glVertex2f(eta0, phi0);
glVertex2f(eta0, phi1);
glVertex2f(eta1, phi0);
glVertex2f(eta1, phi1);
glVertex2f(eta0, phi0);
glVertex2f(eta1, phi0);
glVertex2f(eta0, phi1);
glVertex2f(eta1, phi1);
if ((es == 1 && ps == 1) || fM->fProjection == TEveCaloLego::k3D)
{
for (Int_t i=fEtaAxis->GetFirst(); i<fEtaAxis->GetLast(); i+= es)
{
glVertex2f(fEtaAxis->GetBinUpEdge(i), phi0);
glVertex2f(fEtaAxis->GetBinUpEdge(i), phi1);
}
}
else
{
Int_t nEta = CeilNint((fEtaAxis->GetLast()-fEtaAxis->GetFirst())/es);
Float_t etaStep = (eta1-eta0)/nEta;
Float_t eta = eta0;
while (eta < eta1)
{
glVertex2f(eta, phi0);
glVertex2f(eta, phi1);
eta += etaStep;
}
}
Int_t nPhi = CeilNint((phi1-phi0)/(fPhiAxis->GetBinWidth(1)*ps));
Float_t phi, phiStep;
if (ps>1)
{
phiStep = (phi1-phi0)/nPhi;
phi = phi0;
}
else
{
phiStep = fPhiAxis->GetBinWidth(1);
phi = phiStep*CeilNint(phi0/phiStep);
}
while (phi < phi1)
{
glVertex2f(eta0, phi);
glVertex2f(eta1, phi);
phi+=phiStep;
}
glEnd();
glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT | GL_POLYGON_BIT);
glLineWidth(2);
if ( fM->fProjection == TEveCaloLego::k3D || rnrCtx.RefCamera().GetCamBase().GetBaseVec(1).Z() == 0)
DrawZScales3D(rnrCtx, eta0, eta1, phi0, phi1);
if (fM->fProjection == TEveCaloLego::k2D || rnrCtx.RefCamera().GetCamBase().GetBaseVec(1).Z() != 0)
fXAxisAtt.SetRelativeFontSize(kTRUE);
else
fXAxisAtt.SetRelativeFontSize(kFALSE);
DrawXYScales(rnrCtx, eta0, eta1, phi0, phi1);
glPopAttrib();
}
void TEveCaloLegoGL::DrawCells3D(TGLRnrCtx & rnrCtx) const
{
{
for(SliceDLMap_i i = fDLMap.begin(); i != fDLMap.end(); ++i)
{
TGLUtil::Color(fM->GetDataSliceColor(i->first));
glCallList(i->second);
}
}
{
if (rnrCtx.SceneStyle() == TGLRnrCtx::kFill)
{
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glDisable(GL_POLYGON_OFFSET_FILL);
TGLUtil::Color(1);
for (SliceDLMap_i i = fDLMap.begin(); i != fDLMap.end(); ++i)
glCallList(i->second);
}
}
}
void TEveCaloLegoGL::DrawCells2D(TGLRnrCtx & rnrCtx) const
{
using namespace TMath;
static const TEveException eh("TEveCaloLegoGL::DrawCells2D ");
fM->AssertPalette();
UChar_t col[4];
Color_t defCol = fM->GetDataSliceColor(0);
Int_t es = GetGridStep(0, rnrCtx);
Int_t ps = GetGridStep(1, rnrCtx);
if (es==1 && ps==1)
{
TEveCaloData::CellData_t cellData;
Int_t name = 0;
Int_t prevTower = 0;
Float_t sum = 0;
Float_t x1=0, x2=0, y1=0, y2=0;
for (TEveCaloData::vCellId_t::iterator it=fM->fCellList.begin(); it!=fM->fCellList.end(); it++)
{
fM->fData->GetCellData(*it, fM->fPhi, fM->fPhiOffset, cellData);
glLoadName(name);
glBegin(GL_QUADS);
if ((*it).fTower != prevTower)
{
if (fM->f2DMode == TEveCaloLego::kValColor)
{
fM->fPalette->ColorFromValue(FloorNint(sum), col);
TGLUtil::Color4ubv(col);
x1 = cellData.EtaMin();
x2 = cellData.EtaMax();
y1 = cellData.PhiMin();
y2 = cellData.PhiMax();
if (x1<fM->GetEtaMin()) x1 = fM->GetEtaMin();
if (x1>fM->GetEtaMax()) x2 = fM->GetEtaMax();
if (y1<fM->GetPhiMin()) y1 = fM->GetPhiMin();
if (y2>fM->GetPhiMax()) y2 = fM->GetPhiMax();
}
else if (fM->f2DMode == TEveCaloLego::kValSize)
{
TGLUtil::Color(defCol);
Float_t etaW = (cellData.EtaDelta()*sum*0.5f)/fDataMax;
Float_t phiW = (cellData.PhiDelta()*sum*0.5f)/fDataMax;
x1 = (cellData.Eta()-etaW < fM->GetEtaMin()) ? fM->GetEtaMin(): cellData.Eta()-etaW;
x2 = (cellData.Eta()+etaW > fM->GetEtaMax()) ? fM->GetEtaMax(): cellData.Eta()+etaW;
y1 = (cellData.Phi()-phiW < fM->GetPhiMin()) ? fM->GetPhiMin(): cellData.Phi()-phiW;
y2 = (cellData.Phi()+phiW > fM->GetPhiMax()) ? fM->GetPhiMax(): cellData.Phi()+phiW;
}
glVertex3f(x1, y1, sum);
glVertex3f(x2, y1, sum);
glVertex3f(x2, y2, sum);
glVertex3f(x1, y2, sum);
sum = cellData.Value(fM->fPlotEt);
prevTower = (*it).fTower;
}
else
{
sum += cellData.Value(fM->fPlotEt);
}
glEnd();
name++;
};
}
else
{
Float_t eta0 = fM->fEtaMin;
Float_t eta1 = fM->fEtaMax;
Float_t phi0 = fM->GetPhiMin();
Float_t phi1 = fM->GetPhiMax();
Int_t nEta = CeilNint((fEtaAxis->GetLast()-fEtaAxis->GetFirst())/es);
Int_t nPhi = CeilNint((phi1-phi0)/(fPhiAxis->GetBinWidth(1)*ps));
Float_t etaStep = (eta1-eta0)/nEta;
Float_t phiStep = (phi1-phi0)/nPhi;
std::vector<Float_t> vec;
vec.assign((nEta)*(nPhi), 0.f);
TEveCaloData::CellData_t cd;
Float_t left, right, up, down;
for (TEveCaloData::vCellId_t::iterator it=fM->fCellList.begin(); it!=fM->fCellList.end(); it++)
{
fM->fData->GetCellData(*it, fM->fPhi, fM->fPhiOffset, cd);
Int_t iMin = FloorNint((cd.EtaMin()- eta0)/etaStep);
Int_t iMax = CeilNint ((cd.EtaMax()- eta0)/etaStep);
Int_t jMin = FloorNint((cd.PhiMin()- phi0)/phiStep);
Int_t jMax = CeilNint ((cd.PhiMax()- phi0)/phiStep);
for (Int_t i=iMin; i<iMax; i++)
{
if (i<0 || iMax>nEta) continue;
left = i*etaStep;
right = (i+1)*etaStep;
if (i == iMin)
left = cd.EtaMin()-eta0;
if (i == (iMax-1))
right = cd.EtaMax()-eta0;
for (Int_t j=jMin; j<jMax; j++)
{
if (j<0 || jMax>nPhi) continue;
down = j*phiStep;
up = down +phiStep;
if (j == jMin)
down = cd.PhiMin() -phi0;
if (j == (jMax-1))
up = cd.PhiMax() -phi0;
vec[i*nPhi+j] += cd.Value(fM->fPlotEt)*(right-left)*(up-down);
}
}
}
Float_t surf = etaStep*phiStep;
Float_t maxv = 0;
for (UInt_t i =0; i<vec.size(); i++)
{
vec[i] /= surf;
if (vec[i] > maxv) maxv=vec[i];
}
Float_t scale = fM->fData->GetMaxVal(fM->fPlotEt)/maxv;
Float_t logMax = Log(maxv+1);
Float_t scaleLog =fM->fData->GetMaxVal(fM->fPlotEt)/logMax;
Float_t threshold = fM->GetDataSliceThreshold(0);
for (Int_t s=1; s<fM->fData->GetNSlices(); s++)
{
if (threshold > fM->GetDataSliceThreshold(s))
threshold = fM->GetDataSliceThreshold(s);
}
Float_t etaW, phiW;
Int_t cid = 0;
glBegin(GL_QUADS);
for (std::vector<Float_t>::iterator it=vec.begin(); it !=vec.end(); it++)
{
if ((*it)>threshold)
{
Float_t logVal = Log(*it+1);
Float_t eta = Int_t(cid/nPhi)*etaStep + eta0;
Float_t phi = (cid -Int_t(cid/nPhi)*nPhi)*phiStep + phi0;
if (fM->f2DMode == TEveCaloLego::kValColor)
{
fM->fPalette->ColorFromValue((Int_t)(logVal*scaleLog), col);
TGLUtil::Color4ubv(col);
glVertex3f(eta , phi, (*it)*scale);
glVertex3f(eta+etaStep, phi, (*it)*scale);
glVertex3f(eta+etaStep, phi+phiStep, (*it)*scale);
glVertex3f(eta , phi+phiStep, (*it)*scale);
}
else if (fM->f2DMode == TEveCaloLego::kValSize)
{
TGLUtil::Color(defCol);
eta += etaStep*0.5f;
phi += phiStep*0.5f;
etaW = etaStep*0.5f*logVal/logMax;
phiW = phiStep*0.5f*logVal/logMax;
glVertex3f(eta -etaW, phi -phiW, (*it)*scale);
glVertex3f(eta +etaW, phi -phiW, (*it)*scale);
glVertex3f(eta +etaW, phi +phiW, (*it)*scale);
glVertex3f(eta -etaW, phi +phiW, (*it)*scale);
}
}
cid++;
}
glEnd();
}
}
void TEveCaloLegoGL::DirectDraw(TGLRnrCtx & rnrCtx) const
{
fEtaAxis = fM->fData->GetEtaBins();
fPhiAxis = fM->fData->GetPhiBins();
Bool_t cells3D;
if (fM->fProjection == TEveCaloLego::kAuto)
cells3D = (! (rnrCtx.RefCamera().IsOrthographic() && rnrCtx.RefCamera().GetCamBase().GetBaseVec(1).Z()));
else if (fM->fProjection == TEveCaloLego::k2D)
cells3D = kFALSE;
else
cells3D = kTRUE;
fDataMax = fM->GetMaxVal();
Int_t ondiv;
Double_t omin, omax;
THLimitsFinder::Optimize(0, fDataMax, fM->fNZSteps, omin, omax, ondiv, fZAxisStep);
if (fM->fCellIdCacheOK == kFALSE)
{
fDLCacheOK = kFALSE;
fM->BuildCellIdCache();
}
if (cells3D && fDLCacheOK == kFALSE) MakeDisplayList();
glPushMatrix();
Double_t em, eM, pm, pM;
fM->fData->GetEtaLimits(em, eM);
fM->fData->GetPhiLimits(pm, pM);
Double_t unit = ((eM-em) < (pM-pm)) ? (eM-em):(pM-pm);
Float_t sx = (eM-em)/fM->GetEtaRng();
Float_t sy = (pM-pm)/fM->GetPhiRng();
glScalef(sx/unit, sy/unit, fM->GetValToHeight());
glTranslatef(-fM->GetEta(), -fM->fPhi, 0);
glPushAttrib(GL_LINE_BIT | GL_POLYGON_BIT);
glLineWidth(1);
glDisable(GL_LIGHTING);
glEnable(GL_NORMALIZE);
glEnable(GL_POLYGON_OFFSET_FILL);
glPushName(0);
glPolygonOffset(0.8, 1);
cells3D ? DrawCells3D(rnrCtx):DrawCells2D(rnrCtx);
glPopName();
glPopAttrib();
if (rnrCtx.Selection() == kFALSE && rnrCtx.Highlight() == kFALSE)
{
DrawHistBase(rnrCtx);
if (fM->fDrawHPlane)
{
glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glDisable(GL_CULL_FACE);
TGLUtil::ColorTransparency(fM->fPlaneColor, fM->fPlaneTransparency);
Float_t zhp = fM->fHPlaneVal*fDataMax;
glBegin(GL_POLYGON);
glVertex3f(fM->fEtaMin, fM->GetPhiMin(), zhp);
glVertex3f(fM->fEtaMax, fM->GetPhiMin(), zhp);
glVertex3f(fM->fEtaMax, fM->GetPhiMax(), zhp);
glVertex3f(fM->fEtaMin, fM->GetPhiMax(), zhp);
glEnd();
glPopAttrib();
}
}
glPopMatrix();
}
void TEveCaloLegoGL::ProcessSelection(TGLRnrCtx & , TGLSelectRecord & rec)
{
if (rec.GetN() < 2) return;
Int_t cellID = rec.GetItem(1);
TEveCaloData::CellData_t cellData;
fM->fData->GetCellData(fM->fCellList[cellID], cellData);
printf("Bin selected in slice %d \n", fM->fCellList[cellID].fSlice);
cellData.Dump();
}
Last change: Wed Jun 25 08:36:38 2008
Last generated: 2008-06-25 08:36
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.