40 ClassImp(TEveCaloLegoGL);
45 TEveCaloLegoGL::TEveCaloLegoGL() :
58 fCurrentPixelsPerBin(0),
64 fEtaAxis =
new TAxis();
65 fPhiAxis =
new TAxis();
68 fAxisPainter.SetFontMode(TGLFont::kPixmap);
74 TEveCaloLegoGL::~TEveCaloLegoGL()
86 Bool_t TEveCaloLegoGL::SetModel(TObject* obj,
const Option_t* )
88 fM = SetModelDynCast<TEveCaloLego>(obj);
95 void TEveCaloLegoGL::SetBBox()
97 SetAxisAlignedBBox(((TEveCaloLego*)fExternalObj)->AssertBBox());
103 void TEveCaloLegoGL::DLCacheDrop()
106 for (SliceDLMap_i i = fDLMap.begin(); i != fDLMap.end(); ++i)
109 TGLObject::DLCacheDrop();
115 void TEveCaloLegoGL::DLCachePurge()
119 if (! fDLMap.empty()) {
120 for (SliceDLMap_i i = fDLMap.begin(); i != fDLMap.end(); ++i) {
122 PurgeDLRange(i->second, 1);
127 TGLObject::DLCachePurge();
145 void TEveCaloLegoGL::MakeQuad(Float_t x1, Float_t y1, Float_t z1,
146 Float_t xw, Float_t yw, Float_t h)
const
148 Float_t x2 = x1 + xw;
149 Float_t y2 = y1 + yw;
152 if (x1 < fM->GetEtaMin()) x1 = fM->GetEtaMin();
153 if (x2 > fM->GetEtaMax()) x2 = fM->GetEtaMax();
155 if (y1 < fM->GetPhiMin()) y1 = fM->GetPhiMin();
156 if (y2 > fM->GetPhiMax()) y2 = fM->GetPhiMax();
161 glNormal3f(0, 0, -1);
162 glVertex3f(x2, y2, z1);
163 glVertex3f(x2, y1, z1);
164 glVertex3f(x1, y1, z1);
165 glVertex3f(x1, y2, z1);
168 glVertex3f(x2, y2, z2);
169 glVertex3f(x1, y2, z2);
170 glVertex3f(x1, y1, z2);
171 glVertex3f(x2, y1, z2);
175 glVertex3f(x2, y2, z1);
176 glVertex3f(x2, y2, z2);
177 glVertex3f(x2, y1, z2);
178 glVertex3f(x2, y1, z1);
180 glNormal3f(-1, 0, 0);
181 glVertex3f(x1, y2, z1);
182 glVertex3f(x1, y1, z1);
183 glVertex3f(x1, y1, z2);
184 glVertex3f(x1, y2, z2);
188 glVertex3f(x2, y2, z1);
189 glVertex3f(x1, y2, z1);
190 glVertex3f(x1, y2, z2);
191 glVertex3f(x2, y2, z2);
193 glNormal3f(0, -1, 0);
194 glVertex3f(x2, y1, z1);
195 glVertex3f(x2, y1, z2);
196 glVertex3f(x1, y1, z2);
197 glVertex3f(x1, y1, z1);
206 void TEveCaloLegoGL::Make3DDisplayList(TEveCaloData::vCellId_t& cellList, SliceDLMap_t& dlMap, Bool_t selection)
const
208 TEveCaloData::CellData_t cellData;
213 Int_t nSlices = fM->fData->GetNSlices();
214 for (Int_t s = 0; s < nSlices; ++s)
216 if (dlMap.empty() || dlMap[s] == 0)
217 dlMap[s] = glGenLists(1);
219 glNewList(dlMap[s], GL_COMPILE);
221 for (UInt_t i = 0; i < cellList.size(); ++i)
223 if (cellList[i].fSlice > s)
continue;
224 if (cellList[i].fTower != prevTower) {
226 prevTower = cellList[i].fTower;
229 fM->fData->GetCellData(cellList[i], cellData);
230 if (s == cellList[i].fSlice)
232 if (selection) glLoadName(i);
234 WrapTwoPi(cellData.fPhiMin, cellData.fPhiMax);
235 MakeQuad(cellData.EtaMin(), cellData.PhiMin(), offset,
236 cellData.EtaDelta(), cellData.PhiDelta(), cellData.Value(fM->fPlotEt));
238 offset += cellData.Value(fM->fPlotEt);
248 void TEveCaloLegoGL::Make3DDisplayListRebin(TEveCaloData::RebinData_t& rebinData, SliceDLMap_t& dlMap, Bool_t selection)
const
250 Int_t nSlices = fM->fData->GetNSlices();
255 for (Int_t s = 0; s < nSlices; ++s)
257 if (dlMap.empty() || dlMap[s] == 0)
258 dlMap[s] = glGenLists(1);
260 glNewList(dlMap[s], GL_COMPILE);
262 for (Int_t i = 1; i <= fEtaAxis->GetNbins(); ++i)
264 for (Int_t j = 1; j <= fPhiAxis->GetNbins(); ++j)
266 const Int_t bin = (i)+(j)*(fEtaAxis->GetNbins()+2);
268 if (rebinData.fBinData[bin] !=-1)
270 vals = rebinData.GetSliceVals(bin);
272 for (Int_t t = 0; t < s; ++t)
275 y0 = fPhiAxis->GetBinLowEdge(j);
276 y1 = fPhiAxis->GetBinUpEdge(j);
279 if (selection) glLoadName(bin);
281 MakeQuad(fEtaAxis->GetBinLowEdge(i), y0, offset,
282 fEtaAxis->GetBinWidth(i), y1-y0, vals[s]);
293 void TEveCaloLegoGL::SetAxis3DTitlePos(TGLRnrCtx &rnrCtx, Float_t x0, Float_t x1, Float_t y0, Float_t y1)
const
295 const GLdouble *pm = rnrCtx.RefCamera().RefLastNoPickProjM().CArr();
298 glGetDoublev(GL_MODELVIEW_MATRIX, mm);
299 glGetIntegerv(GL_VIEWPORT, vp);
300 GLdouble projX[4], projY[4], projZ[4];
304 cornerX[0] = x0; cornerY[0] = y0;
305 cornerX[1] = x1; cornerY[1] = y0;
306 cornerX[2] = x1; cornerY[2] = y1;
307 cornerX[3] = x0; cornerY[3] = y1;
309 gluProject(cornerX[0], cornerY[0], 0, mm, pm, vp, &projX[0], &projY[0], &projZ[0]);
310 gluProject(cornerX[1], cornerY[1], 0, mm, pm, vp, &projX[1], &projY[1], &projZ[1]);
311 gluProject(cornerX[2], cornerY[2], 0, mm, pm, vp, &projX[2], &projY[2], &projZ[2]);
312 gluProject(cornerX[3], cornerY[3], 0, mm, pm, vp, &projX[3], &projY[3], &projZ[3]);
318 Float_t xt = projX[0];
319 for (Int_t i = 1; i < 4; ++i) {
325 fZAxisTitlePos.Set(cornerX[idxLeft], cornerY[idxLeft], 1.05 * fMaxVal);
333 for (Int_t i = 0; i < 4; ++i) {
338 if (projZ[i] > zMin) zMin = projZ[i];
342 Int_t xyIdx = idxFront;
343 if (zMin - zt < 1e-2) xyIdx = 0;
348 fXAxisTitlePos.fX = x1;
349 fXAxisTitlePos.fY = y0;
350 fYAxisTitlePos.fX = x0;
351 fYAxisTitlePos.fY = y1;
354 fXAxisTitlePos.fX = x0;
355 fXAxisTitlePos.fY = y0;
356 fYAxisTitlePos.fX = x1;
357 fYAxisTitlePos.fY = y1;
360 fXAxisTitlePos.fX = x0;
361 fXAxisTitlePos.fY = y1;
362 fYAxisTitlePos.fX = x1;
363 fYAxisTitlePos.fY = y0;
366 fXAxisTitlePos.fX = x1;
367 fXAxisTitlePos.fY = y1;
368 fYAxisTitlePos.fX = x0;
369 fYAxisTitlePos.fY = y0;
375 Float_t tOffX = (x1-x0) * off;
if (fYAxisTitlePos.fX > x0) tOffX = -tOffX;
376 Float_t tOffY = (y1-y0) * off;
if (fXAxisTitlePos.fY > y0) tOffY = -tOffY;
377 fXAxisTitlePos.fX += tOffX;
378 fYAxisTitlePos.fY += tOffY;
388 for (Int_t i = 0; i < 4; ++i)
390 if (projZ[i] < zm && projZ[i] >= zt && i != idxFront )
396 if (idxFront == idxLeft) idxFront =idxDepthT;
401 fBackPlaneXConst[0].Set(x1, y0, 0); fBackPlaneXConst[1].Set(x1, y1, 0);
402 fBackPlaneYConst[0].Set(x0, y1, 0); fBackPlaneYConst[1].Set(x1, y1, 0);
405 fBackPlaneXConst[0].Set(x0, y0, 0); fBackPlaneXConst[1].Set(x0, y1, 0);
406 fBackPlaneYConst[0].Set(x0, y1, 0); fBackPlaneYConst[1].Set(x1, y1, 0);
409 fBackPlaneXConst[0].Set(x0, y0, 0); fBackPlaneXConst[1].Set(x0, y1, 0);
410 fBackPlaneYConst[0].Set(x0, y0, 0); fBackPlaneYConst[1].Set(x1, y0, 0);
413 fBackPlaneXConst[0].Set(x1, y0, 0); fBackPlaneXConst[1].Set(x1, y1, 0);
414 fBackPlaneYConst[0].Set(x0, y0, 0); fBackPlaneYConst[1].Set(x1, y0, 0);
424 void TEveCaloLegoGL::DrawAxis3D(TGLRnrCtx & rnrCtx)
const
430 glGetDoublev(GL_MODELVIEW_MATRIX, mm.Arr());
431 glGetDoublev(GL_PROJECTION_MATRIX, pm);
432 Int_t* vp = rnrCtx.RefCamera().RefViewport().CArr();
435 gluProject(fXAxisTitlePos.fX, fXAxisTitlePos.fY, fXAxisTitlePos.fZ, mm.Arr(), pm, vp, &up[0], &up[1], &up[2]);
436 gluProject(fYAxisTitlePos.fX, fYAxisTitlePos.fY, fYAxisTitlePos.fZ, mm.Arr(), pm, vp, &dn[0], &dn[1], &dn[2]);
437 Float_t len = TMath::Sqrt((up[0] - dn[0]) * (up[0] - dn[0])
438 + (up[1] - dn[1]) * (up[1] - dn[1])
439 + (up[2] - dn[2]) * (up[2] - dn[2]));
440 len = TMath::Min(len, rnrCtx.RefCamera().RefViewport().Diagonal()*0.7f);
441 len /= TMath::Sqrt2();
443 TGLVertex3 worldRef(fZAxisTitlePos.fX, fZAxisTitlePos.fY, fZAxisTitlePos.fZ);
444 fAxisPainter.RefTMOff(0) = rnrCtx.RefCamera().ViewportDeltaToWorld(worldRef, -len, 0, &mm);
445 fAxisPainter.SetLabelPixelFontSize(TMath::Nint(TMath::Max(len*fM->GetData()->GetEtaBins()->GetLabelSize(), 0.02f)));
446 fAxisPainter.SetTitlePixelFontSize(TMath::Nint(TMath::Max(len*fM->GetData()->GetEtaBins()->GetLabelSize(), 0.02f)));
448 Float_t tickLength = TMath::Max(fM->GetData()->GetEtaBins()->GetTickLength(), 0.02f);
449 Float_t labelOffset = TMath::Max(fM->GetData()->GetEtaBins()->GetLabelOffset(), 0.02f);
453 if (fM->fData->Empty() == kFALSE)
456 Double_t omin=0, omax=0, bw1;
457 THLimitsFinder::Optimize(0, fMaxVal, fM->fNZSteps, omin, omax, ondiv, bw1);
458 worldRef.Set(fZAxisTitlePos.fX, fZAxisTitlePos.fY, fZAxisTitlePos.fZ);
459 TGLVector3 zto = rnrCtx.RefCamera().ViewportDeltaToWorld(worldRef, 0, fAxisPainter.GetLabelPixelFontSize(), &mm);
461 if ( fZAxisTitlePos.fZ - omax < fAxisPainter.GetLabelPixelFontSize())
462 fZAxisTitlePos.fZ = omax + zto.Z();
465 fZAxis->SetAxisColor(fGridColor);
466 fZAxis->SetLabelColor(fFontColor);
467 fZAxis->SetTitleColor(fFontColor);
468 fZAxis->SetNdivisions(fM->fNZSteps*100 + 10);
469 fZAxis->SetLimits(0, fMaxVal);
470 fZAxis->SetTitle(fM->GetPlotEt() ?
"Et[GeV]" :
"E[GeV]");
472 fAxisPainter.SetTMNDim(1);
473 fAxisPainter.RefDir().Set(0., 0., 1.);
474 fAxisPainter.SetLabelAlign(TGLFont::kRight, TGLFont::kCenterV);
476 glTranslatef(fZAxisTitlePos.fX, fZAxisTitlePos.fY, 0);
479 fAxisPainter.RefTitlePos().Set(fAxisPainter.RefTMOff(0).X()*0.05, fAxisPainter.RefTMOff(0).Y()*0.05, fZAxisTitlePos.fZ);
480 fZAxis->SetLabelOffset(labelOffset);
481 fZAxis->SetTickLength(tickLength);
482 fAxisPainter.PaintAxis(rnrCtx, fZAxis);
489 glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT);
492 TGLUtil::LineWidth(1);
494 TGLUtil::Color(fGridColor);
496 glVertex3f(fBackPlaneXConst[0].fX ,fBackPlaneXConst[0].fY ,0);
497 glVertex3f(fBackPlaneXConst[0].fX ,fBackPlaneXConst[0].fY ,fMaxVal);
498 glVertex3f(fBackPlaneXConst[1].fX ,fBackPlaneXConst[1].fY ,0);
499 glVertex3f(fBackPlaneXConst[1].fX ,fBackPlaneXConst[1].fY ,fMaxVal);
502 glVertex3f(fBackPlaneYConst[0].fX ,fBackPlaneYConst[0].fY ,0);
503 glVertex3f(fBackPlaneYConst[0].fX ,fBackPlaneYConst[0].fY ,fMaxVal);
504 glVertex3f(fBackPlaneYConst[1].fX ,fBackPlaneYConst[1].fY ,0);
505 glVertex3f(fBackPlaneYConst[1].fX ,fBackPlaneYConst[1].fY ,fMaxVal);
508 glVertex3f(fBackPlaneXConst[0].fX ,fBackPlaneXConst[0].fY ,fMaxVal);
509 glVertex3f(fBackPlaneXConst[1].fX ,fBackPlaneXConst[1].fY ,fMaxVal);
510 glVertex3f(fBackPlaneYConst[0].fX ,fBackPlaneYConst[0].fY ,fMaxVal);
511 glVertex3f(fBackPlaneYConst[1].fX ,fBackPlaneYConst[1].fY ,fMaxVal);
516 glEnable(GL_LINE_STIPPLE);
517 glLineStipple(1, 0x5555);
520 for (Int_t i = 1; i <= ondiv; ++i, hz += bw1) {
521 glVertex3f(fBackPlaneXConst[0].fX ,fBackPlaneXConst[0].fY ,hz);
522 glVertex3f(fBackPlaneXConst[1].fX ,fBackPlaneXConst[1].fY ,hz);
523 glVertex3f(fBackPlaneYConst[0].fX ,fBackPlaneYConst[0].fY ,hz);
524 glVertex3f(fBackPlaneYConst[1].fX ,fBackPlaneYConst[1].fY ,hz);
535 Float_t yOff = fM->GetPhiRng();
536 if (fXAxisTitlePos.fY < fM->GetPhiMax()) yOff = -yOff;
538 Float_t xOff = fM->GetEtaRng();
539 if (fYAxisTitlePos.fX < fM->GetEtaMax()) xOff = -xOff;
542 ax.SetAxisColor(fGridColor);
543 ax.SetLabelColor(fFontColor);
544 ax.SetTitleColor(fFontColor);
545 ax.SetTitleFont(fM->GetData()->GetEtaBins()->GetTitleFont());
546 ax.SetLabelOffset(labelOffset);
547 ax.SetTickLength(tickLength);
548 fAxisPainter.SetTMNDim(2);
549 fAxisPainter.RefTMOff(1).Set(0, 0, -fMaxVal);
550 fAxisPainter.SetLabelAlign(TGLFont::kCenterH, TGLFont::kBottom);
554 fAxisPainter.RefDir().Set(1, 0, 0);
555 fAxisPainter.RefTMOff(0).Set(0, yOff, 0);
556 glTranslatef(0, fXAxisTitlePos.fY, 0);
558 ax.SetNdivisions(fM->GetData()->GetEtaBins()->GetNdivisions());
559 ax.SetLimits(fM->GetEtaMin(), fM->GetEtaMax());
560 ax.SetTitle(fM->GetData()->GetEtaBins()->GetTitle());
561 fAxisPainter.RefTitlePos().Set(fXAxisTitlePos.fX, yOff*1.5*ax.GetTickLength(), -fMaxVal*ax.GetTickLength());
562 fAxisPainter.PaintAxis(rnrCtx, &ax);
566 fAxisPainter.RefDir().Set(0, 1, 0);
567 fAxisPainter.RefTMOff(0).Set(xOff, 0, 0);
568 ax.SetNdivisions(fM->GetData()->GetPhiBins()->GetNdivisions());
569 ax.SetLimits(fM->GetPhiMin(), fM->GetPhiMax());
570 ax.SetTitle(fM->GetData()->GetPhiBins()->GetTitle());
572 glTranslatef(fYAxisTitlePos.fX, 0, 0);
573 fAxisPainter.RefTitlePos().Set( xOff*1.5*ax.GetTickLength(), fYAxisTitlePos.fY, -fMaxVal*ax.GetTickLength());
574 fAxisPainter.PaintAxis(rnrCtx, &ax);
582 void TEveCaloLegoGL::GetScaleForMatrix(Float_t& sx, Float_t& sy, Float_t& sz)
const
584 Double_t em, eM, pm, pM;
585 fM->fData->GetEtaLimits(em, eM);
586 fM->fData->GetPhiLimits(pm, pM);
587 Double_t unit = ((eM - em) < (pM - pm)) ? (eM - em) : (pM - pm);
588 sx = (eM - em) / (fM->GetEtaRng() * unit);
589 sy = (pM - pm) / (fM->GetPhiRng() * unit);
594 sz = fM->GetMaxTowerH() / fM->fMaxValAbs;
596 else if (!fM->fData->Empty())
598 sz = fM->GetMaxTowerH() / fMaxVal;
605 void TEveCaloLegoGL::DrawAxis2D(TGLRnrCtx & rnrCtx)
const
607 if (fM->GetData()->Empty())
608 fAxisPainter.SetTMNDim(1);
610 TGLCamera& cam = rnrCtx.RefCamera();
613 ax.SetAxisColor(fGridColor);
614 ax.SetLabelColor(fFontColor);
615 ax.SetTitleColor(fFontColor);
616 ax.SetTitleFont(fM->GetData()->GetEtaBins()->GetTitleFont());
617 ax.SetTitleSize(TMath::Max(fM->GetData()->GetEtaBins()->GetTitleSize(), 0.02f));
618 ax.SetLabelOffset(TMath::Max(fM->GetData()->GetEtaBins()->GetLabelOffset(), 0.02f));
619 ax.SetTickLength(TMath::Max(fM->GetData()->GetEtaBins()->GetTickLength(), 0.05f));
622 fAxisPainter.SetAttAxis(&ax);
628 glGetDoublev(GL_MODELVIEW_MATRIX, mm.Arr());
629 glGetDoublev(GL_PROJECTION_MATRIX, pm);
630 glGetIntegerv(GL_VIEWPORT, vp);
634 gluProject(fM->GetEtaMin(), fM->GetPhiMin(), 0, mm.Arr(), pm, vp, &dn[0], &dn[1], &dn[2]);
635 gluProject(fM->GetEtaMax(), fM->GetPhiMax(), 0, mm.Arr(), pm, vp, &up[0], &up[1], &up[2]);
636 Double_t len = TMath::Sqrt((up[0] - dn[0]) * (up[0] - dn[0])
637 + (up[1] - dn[1]) * (up[1] - dn[1])
638 + (up[2] - dn[2]) * (up[2] - dn[2]));
641 Double_t vpLimit = cam.RefViewport().Diagonal()*0.5/TMath::Sqrt2();
642 len = TMath::Min(len, vpLimit);
645 fAxisPainter.SetLabelPixelFontSize(TMath::Nint(len*fM->GetData()->GetEtaBins()->GetLabelSize()));
646 fAxisPainter.SetTitlePixelFontSize(TMath::Nint(len*fM->GetData()->GetEtaBins()->GetTitleSize()));
647 ax.SetNdivisions(fM->GetData()->GetEtaBins()->GetNdivisions());
648 ax.SetLimits(fM->GetEtaMin(), fM->GetEtaMax());
649 ax.SetTitle(fM->GetData()->GetEtaBins()->GetTitle());
650 fAxisPainter.RefTitlePos().Set(fM->GetEtaMax(), -fM->GetPhiRng()*(ax.GetTickLength()+ ax.GetLabelOffset()), 0 );
651 fAxisPainter.RefDir().Set(1, 0, 0);
653 Float_t tmOffFrustX = cam.FrustumPlane(TGLCamera::kRight).D() + cam.FrustumPlane(TGLCamera::kLeft).D();
654 fAxisPainter.RefTMOff(0).Set(0, -TMath::Min(fM->GetPhiRng(), tmOffFrustX), 0);
655 fAxisPainter.SetLabelAlign(TGLFont::kCenterH, TGLFont::kBottom);
658 glTranslatef(0, fM->GetPhiMin(), 0);
659 fAxisPainter.PaintAxis(rnrCtx, &ax);
663 ax.SetNdivisions(fM->GetData()->GetPhiBins()->GetNdivisions());
664 ax.SetLimits(fM->GetPhiMin(), fM->GetPhiMax());
665 ax.SetTitle(fM->GetData()->GetPhiBins()->GetTitle());
666 fAxisPainter.RefTitlePos().Set(-fM->GetEtaRng()*(ax.GetTickLength()+ ax.GetLabelOffset()), fM->GetPhiMax(), 0);
667 fAxisPainter.RefDir().Set(0, 1, 0);
668 Float_t tmOffFrustY = cam.FrustumPlane(TGLCamera::kTop).D() + cam.FrustumPlane(TGLCamera::kBottom).D();
669 fAxisPainter.RefTMOff(0).Set(-TMath::Min(fM->GetEtaRng(), tmOffFrustY), 0, 0);
670 fAxisPainter.SetLabelAlign(TGLFont::kRight, TGLFont::kCenterV);
673 glTranslatef(fM->GetEtaMin(), 0, 0);
674 fAxisPainter.PaintAxis(rnrCtx, &ax);
677 fAxisPainter.SetTMNDim(2);
683 Int_t TEveCaloLegoGL::GetGridStep(TGLRnrCtx &rnrCtx)
const
685 TGLCamera &camera = rnrCtx.RefCamera();
686 Float_t l = -camera.FrustumPlane(TGLCamera::kLeft).D();
687 Float_t r = camera.FrustumPlane(TGLCamera::kRight).D();
688 Float_t t = camera.FrustumPlane(TGLCamera::kTop).D();
689 Float_t b = -camera.FrustumPlane(TGLCamera::kBottom).D();
690 Float_t frustD = TMath::Hypot(r-l, t-b);
692 GLint vp[4]; glGetIntegerv(GL_VIEWPORT, vp);
693 Float_t viewportD = TMath::Sqrt((vp[1] - vp[0]) * (vp[1] - vp[0]) + (vp[3] - vp[1]) * (vp[3] - vp[1]));
694 Float_t deltaToViewport = viewportD/frustD;
697 GLdouble em, eM, pm, pM;
698 fM->GetData()->GetEtaLimits(pm, pM);
699 fM->GetData()->GetPhiLimits(em, eM);
700 Int_t i0 = fM->fData->GetEtaBins()->FindBin(fM->GetEtaMin());
701 Int_t i1 = fM->fData->GetEtaBins()->FindBin(fM->GetEtaMax());
702 Int_t j0 = fM->fData->GetPhiBins()->FindBin(fM->GetPhiMin());
703 Int_t j1 = fM->fData->GetPhiBins()->FindBin(fM->GetPhiMax());
705 Float_t averageBinWidth = TMath::Hypot(eM - em, pM - pm)/TMath::Sqrt((i0 - i1) * (i0 - i1) + (j0 - j1) * (j0 - j1));
706 Float_t ppb = deltaToViewport*averageBinWidth;
709 if (fM->fAutoRebin && fM->fPixelsPerBin > ppb)
712 Int_t maxGroup = TMath::Min(fM->fData->GetEtaBins()->GetNbins(), fM->fData->GetPhiBins()->GetNbins())/4;
714 ngroup = TMath::Nint(fM->fPixelsPerBin*0.5/ppb);
715 if (ngroup > maxGroup) ngroup = maxGroup;
718 fCurrentPixelsPerBin = TMath::Nint(ppb);
726 void TEveCaloLegoGL::RebinAxis(TAxis *orig, TAxis *curr)
const
728 Double_t center = 0.5 * (orig->GetXmin() + orig->GetXmax());
729 Int_t idx0 = orig->FindBin(center);
730 Double_t bc = orig->GetBinCenter(idx0);
731 if (bc > center) --idx0;
733 Int_t nbR = TMath::FloorNint(idx0/fBinStep) + TMath::FloorNint((orig->GetNbins() - idx0)/fBinStep);
734 Int_t off = idx0 - TMath::FloorNint(idx0/fBinStep)*fBinStep;
735 std::vector<Double_t> bins(nbR + 1);
736 for (Int_t i = 0; i <= nbR; ++i)
738 bins[i] = orig->GetBinUpEdge(off + i*fBinStep);
740 curr->Set(nbR, &bins[0]);
746 void TEveCaloLegoGL::DrawHistBase(TGLRnrCtx &rnrCtx)
const
748 Float_t eta0 = fM->fEtaMin;
749 Float_t eta1 = fM->fEtaMax;
750 Float_t phi0 = fM->GetPhiMin();
751 Float_t phi1 = fM->GetPhiMax();
755 TGLUtil::Color(fGridColor);
756 TGLUtil::LineWidth(1);
758 glVertex2f(eta0, phi0);
759 glVertex2f(eta0, phi1);
760 glVertex2f(eta1, phi0);
761 glVertex2f(eta1, phi1);
763 glVertex2f(eta0, phi0);
764 glVertex2f(eta1, phi0);
765 glVertex2f(eta0, phi1);
766 glVertex2f(eta1, phi1);
770 Int_t neb = fEtaAxis->GetNbins();
771 for (Int_t i = 0; i<= neb; i++)
773 val = fEtaAxis->GetBinUpEdge(i);
774 if (val > eta0 && val < eta1 )
776 glVertex2f(val, phi0);
777 glVertex2f(val, phi1);
782 Int_t npb = fPhiAxis->GetNbins();
783 for (Int_t i = 1; i <= npb; i++) {
784 val = fPhiAxis->GetBinUpEdge(i);
785 if (val > phi0 && val < phi1)
787 glVertex2f(eta0, val);
788 glVertex2f(eta1, val);
796 glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT | GL_POLYGON_BIT);
797 TGLUtil::LineWidth(2);
800 SetAxis3DTitlePos(rnrCtx, eta0, eta1, phi0, phi1);
813 void TEveCaloLegoGL::DrawCells3D(TGLRnrCtx & rnrCtx)
const
817 for (SliceDLMap_i i = fDLMap.begin(); i != fDLMap.end(); ++i) {
818 TGLUtil::ColorTransparency(fM->GetDataSliceColor(i->first), fM->GetData()->GetSliceTransparency(i->first));
819 glLoadName(i->first);
821 glCallList(i->second);
827 if (rnrCtx.SceneStyle() == TGLRnrCtx::kFill) {
828 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
829 glDisable(GL_POLYGON_OFFSET_FILL);
831 for (SliceDLMap_i i = fDLMap.begin(); i != fDLMap.end(); ++i)
832 glCallList(i->second);
840 void TEveCaloLegoGL::PrepareCell2DData(TEveCaloData::vCellId_t& cellList, vCell2D_t& cells2D)
const
842 Int_t max_energy_slice, cellID=0;
843 Float_t sum, max_energy;
845 TEveCaloData::vCellId_t::iterator currentCell = cellList.begin();
846 TEveCaloData::vCellId_t::iterator nextCell = currentCell;
851 TEveCaloData::CellData_t currentCellData;
852 TEveCaloData::CellData_t nextCellData;
854 fM->fData->GetCellData(*currentCell, currentCellData);
855 sum = max_energy = currentCellData.Value(fM->fPlotEt);
856 max_energy_slice = currentCell->fSlice;
857 while (nextCell != cellList.end() && currentCell->fTower == nextCell->fTower)
859 fM->fData->GetCellData(*nextCell, nextCellData);
860 Float_t energy = nextCellData.Value(fM->fPlotEt);
862 if (energy > max_energy)
865 max_energy_slice = nextCell->fSlice;
871 WrapTwoPi(currentCellData.fPhiMin, currentCellData.fPhiMax);
872 cells2D.push_back(Cell2D_t(cellID, sum, max_energy_slice));
873 cells2D.back().SetGeom(currentCellData.fEtaMin, currentCellData.fEtaMax,
874 currentCellData.fPhiMin, currentCellData.fPhiMax);
876 if (nextCell == cellList.end())
879 currentCell = nextCell;
888 void TEveCaloLegoGL::PrepareCell2DDataRebin(TEveCaloData::RebinData_t& rebinData, vCell2D_t& cells2D)
const
890 const Int_t nEta = fEtaAxis->GetNbins();
891 const Int_t nPhi = fPhiAxis->GetNbins();
892 std::vector<Float_t> vec;
893 vec.assign((nEta + 2)*(nPhi + 2), 0.f);
894 std::vector<Float_t> max_e;
895 std::vector<Int_t> max_e_slice;
896 max_e.assign((nEta + 2) * (nPhi + 2), 0.f);
897 max_e_slice.assign((nEta + 2) * (nPhi + 2), -1);
899 for (UInt_t bin = 0; bin < rebinData.fBinData.size(); ++bin) {
901 if (rebinData.fBinData[bin] != -1) {
902 Float_t *val = rebinData.GetSliceVals(bin);
903 for (Int_t s = 0; s < rebinData.fNSlices; ++s) {
905 if (val[s] > max_e[bin]) {
907 max_e_slice[bin] = s;
915 Float_t threshold = fM->GetDataSliceThreshold(0);
916 for (Int_t s = 1; s < fM->fData->GetNSlices(); ++s) {
917 if (threshold > fM->GetDataSliceThreshold(s))
918 threshold = fM->GetDataSliceThreshold(s);
922 for (Int_t i = 1; i <= fEtaAxis->GetNbins(); ++i) {
923 for (Int_t j = 1; j <= fPhiAxis->GetNbins(); ++j) {
924 const Int_t bin = j * (nEta + 2) + i;
925 if (vec[bin] > threshold && rebinData.fBinData[bin] != -1) {
926 cells2D.push_back(Cell2D_t(bin, vec[bin], max_e_slice[bin]));
927 cells2D.back().SetGeom(fEtaAxis->GetBinLowEdge(i), fEtaAxis->GetBinUpEdge(i),
928 fPhiAxis->GetBinLowEdge(j), fPhiAxis->GetBinUpEdge(j));
937 void TEveCaloLegoGL::DrawCells2D(TGLRnrCtx &rnrCtx, vCell2D_t& cells2D)
const
942 Float_t baseOffset = fM->GetFixedHeightValIn2DMode()*fMaxVal;
944 if (fM->f2DMode == TEveCaloLego::kValColor)
949 for (vCell2D_i i = cells2D.begin(); i != cells2D.end(); ++i)
951 if (rnrCtx.SecSelection()) glLoadName(i->fId);
953 fM->fPalette->ColorFromValue(TMath::FloorNint(i->fSumVal), col);
954 col[3] = fM->GetData()->GetSliceTransparency(i->fMaxSlice);
955 TGLUtil::Color4ubv(col);
956 Float_t z = fM->GetHasFixedHeightIn2DMode() ? baseOffset : i->fSumVal;
957 glVertex3f(i->fX0, i->fY0, z);
958 glVertex3f(i->fX1, i->fY0, z);
959 glVertex3f(i->fX1, i->fY1, z);
960 glVertex3f(i->fX0, i->fY1, z);
968 for (vCell2D_i i = fCells2D.begin(); i != fCells2D.end(); ++i)
970 if (i->MinSize() < bws) bws = i->MinSize();
971 if (i->fSumVal > maxv) maxv = i->fSumVal;
974 logMax = TMath::Log10(maxv + 1);
975 fValToPixel = bws / logMax;
977 if (rnrCtx.SecSelection())
981 for (vCell2D_i i = cells2D.begin(); i != cells2D.end(); ++i)
983 glLoadName(i->fMaxSlice);
987 Float_t z = fM->GetHasFixedHeightIn2DMode() ? baseOffset : i->fSumVal;
988 glVertex3f(i->fX0, i->fY0, z);
989 glVertex3f(i->fX1, i->fY0, z);
990 glVertex3f(i->fX1, i->fY1, z);
991 glVertex3f(i->fX0, i->fY1, z);
1001 if ( ! rnrCtx.Highlight())
1004 for (vCell2D_i i = cells2D.begin(); i != cells2D.end(); ++i)
1006 TGLUtil::ColorTransparency(fM->fData->GetSliceColor(i->fMaxSlice), fM->fData->GetSliceTransparency(i->fMaxSlice));
1007 Float_t z = fM->GetHasFixedHeightIn2DMode() ? baseOffset : i->fSumVal;
1008 glVertex3f(i->X(), i->Y() , z);
1014 for (vCell2D_i i = cells2D.begin(); i != cells2D.end(); ++i)
1016 TGLUtil::ColorTransparency(fM->fData->GetSliceColor(i->fMaxSlice), fM->fData->GetSliceTransparency(i->fMaxSlice));
1017 Float_t bw = fValToPixel*TMath::Log10(i->fSumVal+1);
1020 Float_t z = fM->GetHasFixedHeightIn2DMode() ? baseOffset : i->fSumVal;
1021 glVertex3f(x - bw, y - bw, z);
1022 glVertex3f(x + bw, y - bw, z);
1023 glVertex3f(x + bw, y + bw, z);
1024 glVertex3f(x - bw, y + bw, z);
1028 if (fM->f2DMode == TEveCaloLego::kValSizeOutline)
1030 glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT);
1032 Float_t zOff = fMaxVal*0.001 ;
1034 for ( vCell2D_i i = cells2D.begin(); i != cells2D.end(); ++i) {
1035 Char_t transp = TMath::Min(100, 80 + fM->fData->GetSliceTransparency(i->fMaxSlice) / 5);
1036 TGLUtil::ColorTransparency(fM->fData->GetSliceColor(i->fMaxSlice), transp);
1037 z = fM->GetHasFixedHeightIn2DMode() ? baseOffset : i->fSumVal;
1039 glVertex3f(i->fX0, i->fY0, z);
1040 glVertex3f(i->fX1, i->fY0, z);
1041 glVertex3f(i->fX1, i->fY1, z);
1042 glVertex3f(i->fX0, i->fY1, z);
1046 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1048 for ( vCell2D_i i = cells2D.begin(); i != cells2D.end(); ++i) {
1049 TGLUtil::ColorTransparency(fM->fData->GetSliceColor(i->fMaxSlice), 60);
1050 z = fM->GetHasFixedHeightIn2DMode() ? baseOffset : i->fSumVal;
1052 glVertex3f(i->fX0, i->fY0, z);
1053 glVertex3f(i->fX1, i->fY0, z);
1054 glVertex3f(i->fX1, i->fY1, z);
1055 glVertex3f(i->fX0, i->fY1, z);
1064 if (fCurrentPixelsPerBin > fM->fDrawNumberCellPixels &&
1065 ! rnrCtx.Selection() && ! rnrCtx.Highlight())
1067 TGLUtil::Color(rnrCtx.ColorSet().Markup().GetColorIndex());
1069 rnrCtx.RegisterFontNoScale(fM->fCellPixelFontSize,
"arial", TGLFont::kPixmap, font);
1071 for (vCell2D_i i = cells2D.begin(); i != cells2D.end(); ++i) {
1073 Float_t val = i->fSumVal;
1075 txt = Form(
"%d", TMath::Nint(val));
1077 txt = Form(
"%.1f", val);
1078 else if (val > 0.01 )
1079 txt = Form(
"%.2f", 0.01*TMath::Nint(val*100));
1081 txt = Form(
"~1e%d", TMath::Nint(TMath::Log10(val)));
1083 font.Render(txt, i->X(), i->Y(), val*1.2, TGLFont::kCenterH, TGLFont::kCenterV);
1091 void TEveCaloLegoGL::DrawHighlight(TGLRnrCtx& rnrCtx,
const TGLPhysicalShape* , Int_t )
const
1093 if (fM->fData->GetCellsSelected().empty() && fM->fData->GetCellsHighlighted().empty())
1101 GetScaleForMatrix(sx, sy, sz);
1102 glScalef(sx, sy, sz);
1103 glTranslatef(-fM->GetEta(), -fM->fPhi, 0);
1107 glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT | GL_POLYGON_BIT);
1108 glDisable(GL_LIGHTING);
1109 glDisable(GL_CULL_FACE);
1110 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1111 TGLUtil::LineWidth(2);
1114 TGLUtil::LockColor();
1115 if (!fM->fData->GetCellsHighlighted().empty())
1117 glColor4ubv(rnrCtx.ColorSet().Selection(3).CArr());
1118 DrawSelectedCells(rnrCtx, fM->fData->GetCellsHighlighted());
1120 if (!fM->fData->GetCellsSelected().empty())
1122 glColor4ubv(rnrCtx.ColorSet().Selection(1).CArr());
1123 DrawSelectedCells(rnrCtx, fM->fData->GetCellsSelected());
1125 TGLUtil::UnlockColor();
1139 void TEveCaloLegoGL::DrawSelectedCells(TGLRnrCtx & rnrCtx, TEveCaloData::vCellId_t cellsSelectedInput)
const
1142 TEveCaloData::vCellId_t cellsSelected;
1143 TEveCaloData::CellData_t cellData;
1144 for (TEveCaloData::vCellId_i i = cellsSelectedInput.begin(); i != cellsSelectedInput.end(); ++i)
1146 fM->fData->GetCellData((*i), cellData);
1147 if (fM->CellInEtaPhiRng(cellData))
1148 cellsSelected.push_back(*i);
1152 TEveCaloData::RebinData_t rebinDataSelected;
1155 fM->fData->Rebin(fEtaAxis, fPhiAxis, cellsSelected, fM->fPlotEt, rebinDataSelected);
1156 if (fM->fNormalizeRebin) {
1157 Float_t scale = 1.f / (fBinStep * fBinStep);
1158 for (std::vector<Float_t>::iterator it = rebinDataSelected.fSliceData.begin();
1159 it != rebinDataSelected.fSliceData.end(); ++it)
1169 for (TEveCaloData::vCellId_i j = cellsSelected.begin(); j != cellsSelected.end(); ++j)
1173 Int_t orig_slice = j->fSlice;
1174 for (Int_t s = 0; s < orig_slice; ++s)
1177 fM->fData->GetCellData(*j, cellData);
1178 offset += cellData.Value(fM->fPlotEt);
1180 j->fSlice = orig_slice;
1182 fM->fData->GetCellData(*j, cellData);
1183 WrapTwoPi(cellData.fPhiMin, cellData.fPhiMax);
1184 MakeQuad(cellData.EtaMin(), cellData.PhiMin(), offset,
1185 cellData.EtaDelta(), cellData.PhiDelta(), cellData.Value(fM->fPlotEt));
1193 Int_t nSlices = fM->fData->GetNSlices();
1194 for (Int_t i = 1; i <= fEtaAxis->GetNbins(); ++i)
1196 for (Int_t j = 1; j <= fPhiAxis->GetNbins(); ++j)
1198 const Int_t bin = (i)+(j)*(fEtaAxis->GetNbins()+2);
1199 if (rebinDataSelected.fBinData[bin] !=-1)
1202 vals = rebinDataSelected.GetSliceVals(bin);
1203 valsRef = fRebinData.GetSliceVals(bin);
1204 for (Int_t s = 0; s < nSlices; ++s)
1208 y0 = fPhiAxis->GetBinLowEdge(j);
1209 y1 = fPhiAxis->GetBinUpEdge(j);
1211 MakeQuad(fEtaAxis->GetBinLowEdge(i), y0, offset,
1212 fEtaAxis->GetBinWidth(i), y1-y0, vals[s]);
1214 offset += valsRef[s];
1223 vCell2D_t cells2DSelected;
1227 TEveCaloData::vCellId_i j = cellsSelectedInput.begin();
1228 TEveCaloData::vCellId_i jEnd = cellsSelectedInput.end();
1229 std::set<Int_t> towers;
1232 towers.insert(j->fTower);
1235 for (vCell2D_i i = fCells2D.begin(); i != fCells2D.end(); ++i)
1237 TEveCaloData::CellId_t cell = fM->fCellList[i->fId];
1239 if (towers.find(cell.fTower) != towers.end())
1241 cells2DSelected.push_back(*i);
1247 PrepareCell2DDataRebin(rebinDataSelected, cells2DSelected);
1249 DrawCells2D(rnrCtx, cells2DSelected);
1256 void TEveCaloLegoGL::DirectDraw(TGLRnrCtx & rnrCtx)
const
1258 if (! fM->fData || ! fM->fData->GetEtaBins() || ! fM->fData->GetPhiBins())
1262 if (fM->fProjection == TEveCaloLego::kAuto)
1263 fCells3D = (!(rnrCtx.RefCamera().IsOrthographic() && rnrCtx.RefCamera().GetCamBase().GetBaseVec(1).Z()));
1264 else if (fM->fProjection == TEveCaloLego::k2D)
1266 else if (fM->fProjection == TEveCaloLego::k3D)
1270 Int_t new_bin_step = GetGridStep(rnrCtx);
1273 if (fM->AssertCellIdCache() || fBinStep != new_bin_step)
1275 fBinStep = new_bin_step;
1276 fDLCacheOK = kFALSE;
1279 RebinAxis(fM->fData->GetEtaBins(), fEtaAxis);
1280 RebinAxis(fM->fData->GetPhiBins(), fPhiAxis);
1284 fM->fData->Rebin(fEtaAxis, fPhiAxis, fM->fCellList, fM->fPlotEt, fRebinData);
1287 for (UInt_t i = 0; i < fRebinData.fSliceData.size(); i += fRebinData.fNSlices)
1290 for (Int_t s = 0; s < fRebinData.fNSlices; s++)
1292 sum += fRebinData.fSliceData[i+s];
1294 if (sum > fMaxVal) fMaxVal = sum;
1297 if (fM->fNormalizeRebin)
1299 Float_t scale = 1.f / (fBinStep * fBinStep);
1300 for (std::vector<Float_t>::iterator it = fRebinData.fSliceData.begin(); it != fRebinData.fSliceData.end();
1309 fMaxVal = fM->GetMaxVal();
1316 GetScaleForMatrix(sx, sy, sz);
1317 glScalef(sx, sy, sz);
1318 glTranslatef(-fM->GetEta(), -fM->fPhi, 0);
1320 fFontColor = fM->fFontColor;
1321 fGridColor = fM->fGridColor;
1322 if (fGridColor < 0 || fFontColor < 0)
1324 TColor* c1 = gROOT->GetColor(rnrCtx.ColorSet().Markup().GetColorIndex());
1325 TColor* c2 = gROOT->GetColor(rnrCtx.ColorSet().Background().GetColorIndex());
1327 if (fFontColor < 0) {
1329 fFontColor = TColor::GetColor(c1->GetRed() *f1 + c2->GetRed() *f2,
1330 c1->GetGreen()*f1 + c2->GetGreen()*f2,
1331 c1->GetBlue() *f1 + c2->GetBlue() *f2);
1333 if (fGridColor < 0) {
1335 fGridColor = TColor::GetColor(c1->GetRed() *f1 + c2->GetRed() *f2,
1336 c1->GetGreen()*f1 + c2->GetGreen()*f2,
1337 c1->GetBlue() *f1 + c2->GetBlue() *f2);
1341 glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT | GL_POLYGON_BIT);
1342 TGLUtil::LineWidth(1);
1344 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1345 if (!fM->fData->Empty())
1350 if (fDLCacheOK == kFALSE)
1353 Make3DDisplayList(fM->fCellList, fDLMap, kTRUE);
1355 Make3DDisplayListRebin(fRebinData, fDLMap, kTRUE);
1358 glEnable(GL_NORMALIZE);
1359 glEnable(GL_POLYGON_OFFSET_FILL);
1360 glPolygonOffset(0.8, 1);
1362 DrawCells3D(rnrCtx);
1366 glDisable(GL_LIGHTING);
1370 PrepareCell2DData(fM->fCellList, fCells2D);
1372 PrepareCell2DDataRebin(fRebinData, fCells2D);
1374 DrawCells2D(rnrCtx, fCells2D);
1381 if (rnrCtx.Selection() == kFALSE && rnrCtx.IsDrawPassFilled())
1383 glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT | GL_POLYGON_BIT);
1384 glDisable(GL_LIGHTING);
1385 DrawHistBase(rnrCtx);
1386 if (fM->fDrawHPlane) {
1387 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1388 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1389 glDisable(GL_CULL_FACE);
1390 TGLUtil::ColorTransparency(fM->fPlaneColor, fM->fPlaneTransparency);
1391 Float_t zhp = fM->fHPlaneVal * fMaxVal;
1392 glBegin(GL_POLYGON);
1393 glVertex3f(fM->fEtaMin, fM->GetPhiMin(), zhp);
1394 glVertex3f(fM->fEtaMax, fM->GetPhiMin(), zhp);
1395 glVertex3f(fM->fEtaMax, fM->GetPhiMax(), zhp);
1396 glVertex3f(fM->fEtaMin, fM->GetPhiMax(), zhp);
1408 void TEveCaloLegoGL::ProcessSelection(TGLRnrCtx & , TGLSelectRecord & rec)
1410 TEveCaloData::vCellId_t sel;
1413 Int_t slice = rec.GetItem(1);
1414 Int_t cell = rec.GetItem(2);
1418 Int_t tower = fM->fCellList[cell].fTower;
1419 while (cell > 0 && tower == fM->fCellList[cell].fTower)
1421 sel.push_back(fM->fCellList[cell]);
1422 if (fCells3D)
break;
1430 Int_t nEta = fEtaAxis->GetNbins();
1431 Int_t phiBin = Int_t(cell/(nEta+2));
1432 Int_t etaBin = cell - phiBin*(nEta+2);
1433 TEveCaloData::vCellId_t sl;
1434 fM->fData->GetCellList(fEtaAxis->GetBinCenter(etaBin), fEtaAxis->GetBinWidth(etaBin),
1435 fPhiAxis->GetBinCenter(phiBin), fPhiAxis->GetBinWidth(phiBin),
1438 for (TEveCaloData::vCellId_i it = sl.begin(); it != sl.end(); ++it)
1441 if ((*it).fSlice == slice ) sel.push_back(*it);
1443 if ((*it).fSlice <= slice ) sel.push_back(*it);
1449 fM->fData->ProcessSelection(sel, rec);