00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "TAxis.h"
00013 #include "TH2.h"
00014 #include "THLimitsFinder.h"
00015
00016 #include "TGLViewer.h"
00017 #include "TGLIncludes.h"
00018 #include "TGLPhysicalShape.h"
00019 #include "TGLRnrCtx.h"
00020 #include "TGLSelectRecord.h"
00021 #include "TGLScene.h"
00022 #include "TGLCamera.h"
00023 #include "TGLUtil.h"
00024 #include "TColor.h"
00025 #include "TROOT.h"
00026
00027
00028 #include "TEveCaloLegoGL.h"
00029 #include "TEveCalo.h"
00030 #include "TEveManager.h"
00031 #include "TEveRGBAPalette.h"
00032
00033 #include <algorithm>
00034
00035
00036
00037
00038
00039 ClassImp(TEveCaloLegoGL);
00040
00041
00042 TEveCaloLegoGL::TEveCaloLegoGL() :
00043 TGLObject(),
00044
00045 fGridColor(-1),
00046 fFontColor(-1),
00047
00048 fEtaAxis(0),
00049 fPhiAxis(0),
00050 fZAxis(0),
00051 fM(0),
00052 fDLCacheOK(kFALSE),
00053 fMaxVal(0),
00054 fValToPixel(0),
00055 fCurrentPixelsPerBin(0),
00056 fCells3D(kTRUE),
00057 fBinStep(-1)
00058 {
00059
00060
00061 fDLCache = kFALSE;
00062
00063 fEtaAxis = new TAxis();
00064 fPhiAxis = new TAxis();
00065 fZAxis = new TAxis();
00066
00067 fAxisPainter.SetFontMode(TGLFont::kPixmap);
00068 }
00069
00070
00071 TEveCaloLegoGL::~TEveCaloLegoGL()
00072 {
00073
00074
00075 DLCachePurge();
00076
00077 delete fEtaAxis;
00078 delete fPhiAxis;
00079 delete fZAxis;
00080 }
00081
00082
00083 Bool_t TEveCaloLegoGL::SetModel(TObject* obj, const Option_t* )
00084 {
00085
00086
00087 fM = SetModelDynCast<TEveCaloLego>(obj);
00088 return kTRUE;
00089 }
00090
00091
00092 void TEveCaloLegoGL::SetBBox()
00093 {
00094
00095
00096 SetAxisAlignedBBox(((TEveCaloLego*)fExternalObj)->AssertBBox());
00097 }
00098
00099
00100 void TEveCaloLegoGL::DLCacheDrop()
00101 {
00102
00103
00104 fDLCacheOK = kFALSE;
00105 for (SliceDLMap_i i = fDLMap.begin(); i != fDLMap.end(); ++i)
00106 i->second = 0;
00107
00108 TGLObject::DLCacheDrop();
00109 }
00110
00111
00112 void TEveCaloLegoGL::DLCachePurge()
00113 {
00114
00115
00116
00117 fDLCacheOK = kFALSE;
00118 if (! fDLMap.empty()) {
00119 for (SliceDLMap_i i = fDLMap.begin(); i != fDLMap.end(); ++i) {
00120 if (i->second) {
00121 PurgeDLRange(i->second, 1);
00122 i->second = 0;
00123 }
00124 }
00125 }
00126 TGLObject::DLCachePurge();
00127 }
00128
00129
00130 void TEveCaloLegoGL::MakeQuad(Float_t x1, Float_t y1, Float_t z1,
00131 Float_t xw, Float_t yw, Float_t h) const
00132 {
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 Float_t x2 = x1 + xw;
00148 Float_t y2 = y1 + yw;
00149 Float_t z2 = z1 + h;
00150
00151 if (x1 < fM->GetEtaMin()) x1 = fM->GetEtaMin();
00152 if (x2 > fM->GetEtaMax()) x2 = fM->GetEtaMax();
00153
00154 if (y1 < fM->GetPhiMin()) y1 = fM->GetPhiMin();
00155 if (y2 > fM->GetPhiMax()) y2 = fM->GetPhiMax();
00156
00157 glBegin(GL_QUADS);
00158 {
00159
00160 glNormal3f(0, 0, -1);
00161 glVertex3f(x2, y2, z1);
00162 glVertex3f(x2, y1, z1);
00163 glVertex3f(x1, y1, z1);
00164 glVertex3f(x1, y2, z1);
00165
00166 glNormal3f(0, 0, 1);
00167 glVertex3f(x2, y2, z2);
00168 glVertex3f(x1, y2, z2);
00169 glVertex3f(x1, y1, z2);
00170 glVertex3f(x2, y1, z2);
00171
00172
00173 glNormal3f(1, 0, 0);
00174 glVertex3f(x2, y2, z1);
00175 glVertex3f(x2, y2, z2);
00176 glVertex3f(x2, y1, z2);
00177 glVertex3f(x2, y1, z1);
00178
00179 glNormal3f(-1, 0, 0);
00180 glVertex3f(x1, y2, z1);
00181 glVertex3f(x1, y1, z1);
00182 glVertex3f(x1, y1, z2);
00183 glVertex3f(x1, y2, z2);
00184
00185
00186 glNormal3f(0, 1, 0);
00187 glVertex3f(x2, y2, z1);
00188 glVertex3f(x1, y2, z1);
00189 glVertex3f(x1, y2, z2);
00190 glVertex3f(x2, y2, z2);
00191
00192 glNormal3f(0, -1, 0);
00193 glVertex3f(x2, y1, z1);
00194 glVertex3f(x2, y1, z2);
00195 glVertex3f(x1, y1, z2);
00196 glVertex3f(x1, y1, z1);
00197 }
00198 glEnd();
00199 }
00200
00201
00202 void TEveCaloLegoGL::Make3DDisplayList(TEveCaloData::vCellId_t& cellList, SliceDLMap_t& dlMap, Bool_t selection) const
00203 {
00204
00205
00206
00207 TEveCaloData::CellData_t cellData;
00208 Int_t prevTower = 0;
00209 Float_t offset = 0;
00210
00211
00212 Int_t nSlices = fM->fData->GetNSlices();
00213 for (Int_t s = 0; s < nSlices; ++s)
00214 {
00215 if (dlMap.empty() || dlMap[s] == 0)
00216 dlMap[s] = glGenLists(1);
00217
00218 glNewList(dlMap[s], GL_COMPILE);
00219
00220 for (UInt_t i = 0; i < cellList.size(); ++i)
00221 {
00222 if (cellList[i].fSlice > s) continue;
00223 if (cellList[i].fTower != prevTower) {
00224 offset = 0;
00225 prevTower = cellList[i].fTower;
00226 }
00227
00228 fM->fData->GetCellData(cellList[i], cellData);
00229 if (s == cellList[i].fSlice)
00230 {
00231 if (selection) glLoadName(i);
00232
00233 WrapTwoPi(cellData.fPhiMin, cellData.fPhiMax);
00234 MakeQuad(cellData.EtaMin(), cellData.PhiMin(), offset,
00235 cellData.EtaDelta(), cellData.PhiDelta(), cellData.Value(fM->fPlotEt));
00236 }
00237 offset += cellData.Value(fM->fPlotEt);
00238 }
00239 glEndList();
00240 }
00241 }
00242
00243
00244 void TEveCaloLegoGL::Make3DDisplayListRebin(TEveCaloData::RebinData_t& rebinData, SliceDLMap_t& dlMap, Bool_t selection) const
00245 {
00246
00247
00248
00249 Int_t nSlices = fM->fData->GetNSlices();
00250 Float_t *vals;
00251 Float_t offset;
00252 Float_t y0, y1;
00253
00254 for (Int_t s = 0; s < nSlices; ++s)
00255 {
00256 if (dlMap.empty() || dlMap[s] == 0)
00257 dlMap[s] = glGenLists(1);
00258
00259 glNewList(dlMap[s], GL_COMPILE);
00260
00261 for (Int_t i = 1; i <= fEtaAxis->GetNbins(); ++i)
00262 {
00263 for (Int_t j = 1; j <= fPhiAxis->GetNbins(); ++j)
00264 {
00265 const Int_t bin = (i)+(j)*(fEtaAxis->GetNbins()+2);
00266
00267 if (rebinData.fBinData[bin] !=-1)
00268 {
00269 vals = rebinData.GetSliceVals(bin);
00270 offset =0;
00271 for (Int_t t = 0; t < s; ++t)
00272 offset += vals[t];
00273
00274 y0 = fPhiAxis->GetBinLowEdge(j);
00275 y1 = fPhiAxis->GetBinUpEdge(j);
00276 WrapTwoPi(y0, y1);
00277
00278 if (selection) glLoadName(bin);
00279
00280 MakeQuad(fEtaAxis->GetBinLowEdge(i), y0, offset,
00281 fEtaAxis->GetBinWidth(i), y1-y0, vals[s]);
00282 }
00283 }
00284 }
00285 glEndList();
00286 }
00287 }
00288
00289
00290 void TEveCaloLegoGL::SetAxis3DTitlePos(TGLRnrCtx &rnrCtx, Float_t x0, Float_t x1, Float_t y0, Float_t y1) const
00291 {
00292 const GLdouble *pm = rnrCtx.RefCamera().RefLastNoPickProjM().CArr();
00293 GLdouble mm[16];
00294 GLint vp[4];
00295 glGetDoublev(GL_MODELVIEW_MATRIX, mm);
00296 glGetIntegerv(GL_VIEWPORT, vp);
00297 GLdouble projX[4], projY[4], projZ[4];
00298
00299 GLdouble cornerX[4];
00300 GLdouble cornerY[4];
00301 cornerX[0] = x0; cornerY[0] = y0;
00302 cornerX[1] = x1; cornerY[1] = y0;
00303 cornerX[2] = x1; cornerY[2] = y1;
00304 cornerX[3] = x0; cornerY[3] = y1;
00305
00306 gluProject(cornerX[0], cornerY[0], 0, mm, pm, vp, &projX[0], &projY[0], &projZ[0]);
00307 gluProject(cornerX[1], cornerY[1], 0, mm, pm, vp, &projX[1], &projY[1], &projZ[1]);
00308 gluProject(cornerX[2], cornerY[2], 0, mm, pm, vp, &projX[2], &projY[2], &projZ[2]);
00309 gluProject(cornerX[3], cornerY[3], 0, mm, pm, vp, &projX[3], &projY[3], &projZ[3]);
00310
00311
00312
00313
00314 Int_t idxLeft = 0;
00315 Float_t xt = projX[0];
00316 for (Int_t i = 1; i < 4; ++i) {
00317 if (projX[i] < xt) {
00318 xt = projX[i];
00319 idxLeft = i;
00320 }
00321 }
00322 fZAxisTitlePos.Set(cornerX[idxLeft], cornerY[idxLeft], 1.05 * fMaxVal);
00323
00324
00325
00326
00327 Float_t zt = 1.f;
00328 Float_t zMin = 0.f;
00329 Int_t idxFront = 0;
00330 for (Int_t i = 0; i < 4; ++i) {
00331 if (projZ[i] < zt) {
00332 zt = projZ[i];
00333 idxFront = i;
00334 }
00335 if (projZ[i] > zMin) zMin = projZ[i];
00336 }
00337
00338
00339 Int_t xyIdx = idxFront;
00340 if (zMin - zt < 1e-2) xyIdx = 0;
00341
00342
00343 switch (xyIdx) {
00344 case 0:
00345 fXAxisTitlePos.fX = x1;
00346 fXAxisTitlePos.fY = y0;
00347 fYAxisTitlePos.fX = x0;
00348 fYAxisTitlePos.fY = y1;
00349 break;
00350 case 1:
00351 fXAxisTitlePos.fX = x0;
00352 fXAxisTitlePos.fY = y0;
00353 fYAxisTitlePos.fX = x1;
00354 fYAxisTitlePos.fY = y1;
00355 break;
00356 case 2:
00357 fXAxisTitlePos.fX = x0;
00358 fXAxisTitlePos.fY = y1;
00359 fYAxisTitlePos.fX = x1;
00360 fYAxisTitlePos.fY = y0;
00361 break;
00362 case 3:
00363 fXAxisTitlePos.fX = x1;
00364 fXAxisTitlePos.fY = y1;
00365 fYAxisTitlePos.fX = x0;
00366 fYAxisTitlePos.fY = y0;
00367 break;
00368 }
00369
00370
00371 Float_t off = 0.05;
00372 Float_t tOffX = (x1-x0) * off; if (fYAxisTitlePos.fX > x0) tOffX = -tOffX;
00373 Float_t tOffY = (y1-y0) * off; if (fXAxisTitlePos.fY > y0) tOffY = -tOffY;
00374 fXAxisTitlePos.fX += tOffX;
00375 fYAxisTitlePos.fY += tOffY;
00376
00377
00378
00379
00380 if (fM->fBoxMode)
00381 {
00382
00383 Double_t zm = 1.f;
00384 Int_t idxDepthT = 0;
00385 for (Int_t i = 0; i < 4; ++i)
00386 {
00387 if (projZ[i] < zm && projZ[i] >= zt && i != idxFront )
00388 {
00389 zm = projZ[i];
00390 idxDepthT = i;
00391 }
00392 }
00393 if (idxFront == idxLeft) idxFront =idxDepthT;
00394
00395 switch (idxFront)
00396 {
00397 case 0:
00398 fBackPlaneXConst[0].Set(x1, y0, 0); fBackPlaneXConst[1].Set(x1, y1, 0);
00399 fBackPlaneYConst[0].Set(x0, y1, 0); fBackPlaneYConst[1].Set(x1, y1, 0);
00400 break;
00401 case 1:
00402 fBackPlaneXConst[0].Set(x0, y0, 0); fBackPlaneXConst[1].Set(x0, y1, 0);
00403 fBackPlaneYConst[0].Set(x0, y1, 0); fBackPlaneYConst[1].Set(x1, y1, 0);
00404 break;
00405 case 2:
00406 fBackPlaneXConst[0].Set(x0, y0, 0); fBackPlaneXConst[1].Set(x0, y1, 0);
00407 fBackPlaneYConst[0].Set(x0, y0, 0); fBackPlaneYConst[1].Set(x1, y0, 0);
00408 break;
00409 case 3:
00410 fBackPlaneXConst[0].Set(x1, y0, 0); fBackPlaneXConst[1].Set(x1, y1, 0);
00411 fBackPlaneYConst[0].Set(x0, y0, 0); fBackPlaneYConst[1].Set(x1, y0, 0);
00412 break;
00413 }
00414 }
00415 }
00416
00417
00418 void TEveCaloLegoGL::DrawAxis3D(TGLRnrCtx & rnrCtx) const
00419 {
00420
00421
00422
00423
00424
00425 TGLMatrix mm;
00426 GLdouble pm[16];
00427 GLint vp[4];
00428 glGetDoublev(GL_MODELVIEW_MATRIX, mm.Arr());
00429 glGetDoublev(GL_PROJECTION_MATRIX, pm);
00430 glGetIntegerv(GL_VIEWPORT, vp);
00431
00432 GLdouble dn[3];
00433 GLdouble up[3];
00434 gluProject(fZAxisTitlePos.fX, fZAxisTitlePos.fY, 0 , mm.Arr(), pm, vp, &dn[0], &dn[1], &dn[2]);
00435 gluProject(fZAxisTitlePos.fX, fZAxisTitlePos.fY, fZAxisTitlePos.fZ, mm.Arr(), pm, vp, &up[0], &up[1], &up[2]);
00436 Double_t len = TMath::Sqrt((up[0] - dn[0]) * (up[0] - dn[0])
00437 + (up[1] - dn[1]) * (up[1] - dn[1])
00438 + (up[2] - dn[2]) * (up[2] - dn[2]));
00439
00440 TGLVertex3 worldRef(fZAxisTitlePos.fX, fZAxisTitlePos.fY, fZAxisTitlePos.fZ);
00441
00442 fAxisPainter.RefTMOff(0) = rnrCtx.RefCamera().ViewportDeltaToWorld(worldRef, -len, 0, &mm);
00443 fAxisPainter.SetLabelPixelFontSize(TMath::Nint(len*fM->GetData()->GetEtaBins()->GetLabelSize()));
00444 fAxisPainter.SetTitlePixelFontSize(TMath::Nint(len*fM->GetData()->GetEtaBins()->GetTitleSize()));
00445
00446
00447
00448 if (fM->fData->Empty() == kFALSE)
00449 {
00450 fZAxis->SetAxisColor(fGridColor);
00451 fZAxis->SetLabelColor(fFontColor);
00452 fZAxis->SetTitleColor(fFontColor);
00453 fZAxis->SetNdivisions(fM->fNZSteps*100 + 10);
00454 fZAxis->SetLimits(0, fMaxVal);
00455 fZAxis->SetTitle(fM->GetPlotEt() ? "Et[GeV]" : "E[GeV]");
00456
00457 fAxisPainter.SetTMNDim(1);
00458 fAxisPainter.RefDir().Set(0., 0., 1.);
00459 fAxisPainter.SetLabelAlign(TGLFont::kRight, TGLFont::kCenterV);
00460 glPushMatrix();
00461 glTranslatef(fZAxisTitlePos.fX, fZAxisTitlePos.fY, 0);
00462
00463
00464 fAxisPainter.RefTitlePos().Set(fAxisPainter.RefTMOff(0).X()*0.05, fAxisPainter.RefTMOff(0).Y()*0.05, fZAxisTitlePos.fZ);
00465 fZAxis->SetLabelOffset(0.05);
00466 fZAxis->SetTickLength(0.05);
00467 fAxisPainter.PaintAxis(rnrCtx, fZAxis);
00468 glTranslated( fAxisPainter.RefTMOff(0).X(), fAxisPainter.RefTMOff(0).Y(), fAxisPainter.RefTMOff(0).Z());
00469 glPopMatrix();
00470
00471
00472
00473 if (fM->fBoxMode) {
00474
00475 glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT);
00476
00477
00478 TGLUtil::LineWidth(1);
00479 glBegin(GL_LINES);
00480 TGLUtil::Color(fGridColor);
00481
00482 glVertex3f(fBackPlaneXConst[0].fX ,fBackPlaneXConst[0].fY ,0);
00483 glVertex3f(fBackPlaneXConst[0].fX ,fBackPlaneXConst[0].fY ,fMaxVal);
00484 glVertex3f(fBackPlaneXConst[1].fX ,fBackPlaneXConst[1].fY ,0);
00485 glVertex3f(fBackPlaneXConst[1].fX ,fBackPlaneXConst[1].fY ,fMaxVal);
00486
00487
00488 glVertex3f(fBackPlaneYConst[0].fX ,fBackPlaneYConst[0].fY ,0);
00489 glVertex3f(fBackPlaneYConst[0].fX ,fBackPlaneYConst[0].fY ,fMaxVal);
00490 glVertex3f(fBackPlaneYConst[1].fX ,fBackPlaneYConst[1].fY ,0);
00491 glVertex3f(fBackPlaneYConst[1].fX ,fBackPlaneYConst[1].fY ,fMaxVal);
00492
00493
00494 glVertex3f(fBackPlaneXConst[0].fX ,fBackPlaneXConst[0].fY ,fMaxVal);
00495 glVertex3f(fBackPlaneXConst[1].fX ,fBackPlaneXConst[1].fY ,fMaxVal);
00496 glVertex3f(fBackPlaneYConst[0].fX ,fBackPlaneYConst[0].fY ,fMaxVal);
00497 glVertex3f(fBackPlaneYConst[1].fX ,fBackPlaneYConst[1].fY ,fMaxVal);
00498
00499 glEnd();
00500
00501
00502 glEnable(GL_LINE_STIPPLE);
00503 Int_t ondiv;
00504 Double_t omin, omax, bw1;
00505 THLimitsFinder::Optimize(0, fMaxVal, fM->fNZSteps, omin, omax, ondiv, bw1);
00506
00507 glLineStipple(1, 0x5555);
00508 glBegin(GL_LINES);
00509 Float_t hz = bw1;
00510 for (Int_t i = 1; i <= ondiv; ++i, hz += bw1) {
00511 glVertex3f(fBackPlaneXConst[0].fX ,fBackPlaneXConst[0].fY ,hz);
00512 glVertex3f(fBackPlaneXConst[1].fX ,fBackPlaneXConst[1].fY ,hz);
00513 glVertex3f(fBackPlaneYConst[0].fX ,fBackPlaneYConst[0].fY ,hz);
00514 glVertex3f(fBackPlaneYConst[1].fX ,fBackPlaneYConst[1].fY ,hz);
00515 }
00516 glEnd();
00517
00518 glPopAttrib();
00519 }
00520 }
00521
00522
00523
00524
00525 Float_t yOff = fM->GetPhiRng();
00526 if (fXAxisTitlePos.fY < fM->GetPhiMax()) yOff = -yOff;
00527
00528 Float_t xOff = fM->GetEtaRng();
00529 if (fYAxisTitlePos.fX < fM->GetEtaMax()) xOff = -xOff;
00530
00531 TAxis ax;
00532 ax.SetAxisColor(fGridColor);
00533 ax.SetLabelColor(fFontColor);
00534 ax.SetTitleColor(fFontColor);
00535 ax.SetTitleFont(fM->GetData()->GetEtaBins()->GetTitleFont());
00536 ax.SetLabelOffset(0.02);
00537 ax.SetTickLength(0.05);
00538 fAxisPainter.SetTMNDim(2);
00539 fAxisPainter.RefTMOff(1).Set(0, 0, -fMaxVal);
00540 fAxisPainter.SetLabelAlign(TGLFont::kCenterH, TGLFont::kBottom);
00541
00542
00543 glPushMatrix();
00544 fAxisPainter.RefDir().Set(1, 0, 0);
00545 fAxisPainter.RefTMOff(0).Set(0, yOff, 0);
00546 glTranslatef(0, fXAxisTitlePos.fY, 0);
00547 ax.SetNdivisions(710);
00548 ax.SetLimits(fM->GetEtaMin(), fM->GetEtaMax());
00549 ax.SetTitle(fM->GetData()->GetEtaBins()->GetTitle());
00550 fAxisPainter.RefTitlePos().Set(fXAxisTitlePos.fX, yOff*1.5*ax.GetTickLength(), -fMaxVal*ax.GetTickLength());
00551 fAxisPainter.PaintAxis(rnrCtx, &ax);
00552 glPopMatrix();
00553
00554
00555 fAxisPainter.RefDir().Set(0, 1, 0);
00556 fAxisPainter.RefTMOff(0).Set(xOff, 0, 0);
00557 ax.SetNdivisions(510);
00558 ax.SetLimits(fM->GetPhiMin(), fM->GetPhiMax());
00559 ax.SetTitle(fM->GetData()->GetPhiBins()->GetTitle());
00560 glPushMatrix();
00561 glTranslatef(fYAxisTitlePos.fX, 0, 0);
00562 fAxisPainter.RefTitlePos().Set( xOff*1.5*ax.GetTickLength(), fYAxisTitlePos.fY, -fMaxVal*ax.GetTickLength());
00563 fAxisPainter.PaintAxis(rnrCtx, &ax);
00564 glPopMatrix();
00565
00566 }
00567
00568
00569 void TEveCaloLegoGL::GetScaleForMatrix(Float_t& sx, Float_t& sy, Float_t& sz) const
00570 {
00571 Double_t em, eM, pm, pM;
00572 fM->fData->GetEtaLimits(em, eM);
00573 fM->fData->GetPhiLimits(pm, pM);
00574 Double_t unit = ((eM - em) < (pM - pm)) ? (eM - em) : (pM - pm);
00575 sx = (eM - em) / (fM->GetEtaRng() * unit);
00576 sy = (pM - pm) / (fM->GetPhiRng() * unit);
00577
00578 sz = 1;
00579 if (fM->fScaleAbs)
00580 {
00581 sz = fM->GetMaxTowerH() / fM->fMaxValAbs;
00582 }
00583 else if (!fM->fData->Empty())
00584 {
00585 sz = fM->GetMaxTowerH() / fMaxVal;
00586 }
00587 }
00588
00589
00590 void TEveCaloLegoGL::DrawAxis2D(TGLRnrCtx & rnrCtx) const
00591 {
00592
00593
00594 if (fM->GetData()->Empty())
00595 fAxisPainter.SetTMNDim(1);
00596
00597 TGLCamera& cam = rnrCtx.RefCamera();
00598
00599 TAxis ax;
00600 ax.SetAxisColor(fGridColor);
00601 ax.SetLabelColor(fFontColor);
00602 ax.SetTitleColor(fFontColor);
00603 ax.SetTitleFont(fM->GetData()->GetEtaBins()->GetTitleFont());
00604 ax.SetLabelOffset(0.01);
00605 ax.SetTickLength(0.05);
00606
00607
00608 fAxisPainter.SetAttAxis(&ax);
00609
00610
00611 TGLMatrix mm;
00612 GLdouble pm[16];
00613 GLint vp[4];
00614 glGetDoublev(GL_MODELVIEW_MATRIX, mm.Arr());
00615 glGetDoublev(GL_PROJECTION_MATRIX, pm);
00616 glGetIntegerv(GL_VIEWPORT, vp);
00617
00618 GLdouble dn[3];
00619 GLdouble up[3];
00620 gluProject(fM->GetEtaMin(), fM->GetPhiMin(), 0, mm.Arr(), pm, vp, &dn[0], &dn[1], &dn[2]);
00621 gluProject(fM->GetEtaMax(), fM->GetPhiMax(), 0, mm.Arr(), pm, vp, &up[0], &up[1], &up[2]);
00622 Double_t len = TMath::Sqrt((up[0] - dn[0]) * (up[0] - dn[0])
00623 + (up[1] - dn[1]) * (up[1] - dn[1])
00624 + (up[2] - dn[2]) * (up[2] - dn[2]));
00625
00626
00627 Double_t vpLimit = cam.RefViewport().Diagonal()*0.5/TMath::Sqrt2();
00628 len = TMath::Min(len, vpLimit);
00629
00630
00631 fAxisPainter.SetLabelPixelFontSize(TMath::Nint(len*fM->GetData()->GetEtaBins()->GetLabelSize()));
00632 fAxisPainter.SetTitlePixelFontSize(TMath::Nint(len*fM->GetData()->GetEtaBins()->GetTitleSize()));
00633 ax.SetNdivisions(710);
00634 ax.SetLimits(fM->GetEtaMin(), fM->GetEtaMax());
00635 ax.SetTitle(fM->GetData()->GetEtaBins()->GetTitle());
00636 fAxisPainter.RefTitlePos().Set(fM->GetEtaMax(), -fM->GetPhiRng()*(ax.GetTickLength()+ ax.GetLabelOffset()), 0 );
00637 fAxisPainter.RefDir().Set(1, 0, 0);
00638
00639 Float_t tmOffFrustX = cam.FrustumPlane(TGLCamera::kRight).D() + cam.FrustumPlane(TGLCamera::kLeft).D();
00640 fAxisPainter.RefTMOff(0).Set(0, -TMath::Min(fM->GetPhiRng(), tmOffFrustX), 0);
00641 fAxisPainter.SetLabelAlign(TGLFont::kCenterH, TGLFont::kBottom);
00642
00643 glPushMatrix();
00644 glTranslatef(0, fM->GetPhiMin(), 0);
00645 fAxisPainter.PaintAxis(rnrCtx, &ax);
00646 glPopMatrix();
00647
00648
00649 ax.SetNdivisions(510);
00650 ax.SetLimits(fM->GetPhiMin(), fM->GetPhiMax());
00651 ax.SetTitle(fM->GetData()->GetPhiBins()->GetTitle());
00652 fAxisPainter.RefTitlePos().Set(-fM->GetEtaRng()*(ax.GetTickLength()+ ax.GetLabelOffset()), fM->GetPhiMax(), 0);
00653 fAxisPainter.RefDir().Set(0, 1, 0);
00654 Float_t tmOffFrustY = cam.FrustumPlane(TGLCamera::kTop).D() + cam.FrustumPlane(TGLCamera::kBottom).D();
00655 fAxisPainter.RefTMOff(0).Set(-TMath::Min(fM->GetEtaRng(), tmOffFrustY), 0, 0);
00656 fAxisPainter.SetLabelAlign(TGLFont::kRight, TGLFont::kCenterV);
00657
00658 glPushMatrix();
00659 glTranslatef(fM->GetEtaMin(), 0, 0);
00660 fAxisPainter.PaintAxis(rnrCtx, &ax);
00661 glPopMatrix();
00662
00663 fAxisPainter.SetTMNDim(2);
00664 }
00665
00666
00667 Int_t TEveCaloLegoGL::GetGridStep(TGLRnrCtx &rnrCtx) const
00668 {
00669
00670
00671 TGLCamera &camera = rnrCtx.RefCamera();
00672 Float_t l = -camera.FrustumPlane(TGLCamera::kLeft).D();
00673 Float_t r = camera.FrustumPlane(TGLCamera::kRight).D();
00674 Float_t t = camera.FrustumPlane(TGLCamera::kTop).D();
00675 Float_t b = -camera.FrustumPlane(TGLCamera::kBottom).D();
00676 Float_t frustD = TMath::Hypot(r-l, t-b);
00677
00678 GLint vp[4]; glGetIntegerv(GL_VIEWPORT, vp);
00679 Float_t viewportD = TMath::Sqrt((vp[1] - vp[0]) * (vp[1] - vp[0]) + (vp[3] - vp[1]) * (vp[3] - vp[1]));
00680 Float_t deltaToViewport = viewportD/frustD;
00681
00682
00683 GLdouble em, eM, pm, pM;
00684 fM->GetData()->GetEtaLimits(pm, pM);
00685 fM->GetData()->GetPhiLimits(em, eM);
00686 Int_t i0 = fM->fData->GetEtaBins()->FindBin(fM->GetEtaMin());
00687 Int_t i1 = fM->fData->GetEtaBins()->FindBin(fM->GetEtaMax());
00688 Int_t j0 = fM->fData->GetPhiBins()->FindBin(fM->GetPhiMin());
00689 Int_t j1 = fM->fData->GetPhiBins()->FindBin(fM->GetPhiMax());
00690
00691 Float_t averageBinWidth = TMath::Hypot(eM - em, pM - pm)/TMath::Sqrt((i0 - i1) * (i0 - i1) + (j0 - j1) * (j0 - j1));
00692 Float_t ppb = deltaToViewport*averageBinWidth;
00693
00694 Int_t ngroup = 1;
00695 if (fM->fAutoRebin && fM->fPixelsPerBin > ppb)
00696 {
00697 ngroup = TMath::Nint(fM->fPixelsPerBin*0.5/ppb);
00698
00699 Int_t minN = TMath::Min(fM->fData->GetEtaBins()->GetNbins(), fM->fData->GetPhiBins()->GetNbins());
00700 if (ngroup * 4 > minN)
00701 ngroup = minN/4;
00702 }
00703 fCurrentPixelsPerBin = TMath::Nint(ppb);
00704
00705 return ngroup;
00706 }
00707
00708
00709 void TEveCaloLegoGL::RebinAxis(TAxis *orig, TAxis *curr) const
00710 {
00711
00712
00713 Double_t center = 0.5 * (orig->GetXmin() + orig->GetXmax());
00714 Int_t idx0 = orig->FindBin(center);
00715 Double_t bc = orig->GetBinCenter(idx0);
00716 if (bc > center) --idx0;
00717
00718 Int_t nbR = TMath::FloorNint(idx0/fBinStep) + TMath::FloorNint((orig->GetNbins() - idx0)/fBinStep);
00719 Int_t off = idx0 - TMath::FloorNint(idx0/fBinStep)*fBinStep;
00720 std::vector<Double_t> bins(nbR + 1);
00721 for (Int_t i = 0; i <= nbR; ++i)
00722 {
00723 bins[i] = orig->GetBinUpEdge(off + i*fBinStep);
00724 }
00725 curr->Set(nbR, &bins[0]);
00726 }
00727
00728
00729 void TEveCaloLegoGL::DrawHistBase(TGLRnrCtx &rnrCtx) const
00730 {
00731
00732
00733 Float_t eta0 = fM->fEtaMin;
00734 Float_t eta1 = fM->fEtaMax;
00735 Float_t phi0 = fM->GetPhiMin();
00736 Float_t phi1 = fM->GetPhiMax();
00737
00738
00739
00740 TGLUtil::Color(fGridColor);
00741 TGLUtil::LineWidth(1);
00742 glBegin(GL_LINES);
00743 glVertex2f(eta0, phi0);
00744 glVertex2f(eta0, phi1);
00745 glVertex2f(eta1, phi0);
00746 glVertex2f(eta1, phi1);
00747
00748 glVertex2f(eta0, phi0);
00749 glVertex2f(eta1, phi0);
00750 glVertex2f(eta0, phi1);
00751 glVertex2f(eta1, phi1);
00752
00753
00754 Float_t val;
00755 Int_t neb = fEtaAxis->GetNbins();
00756 for (Int_t i = 0; i<= neb; i++)
00757 {
00758 val = fEtaAxis->GetBinUpEdge(i);
00759 if (val > eta0 && val < eta1 )
00760 {
00761 glVertex2f(val, phi0);
00762 glVertex2f(val, phi1);
00763 }
00764 }
00765
00766
00767 Int_t npb = fPhiAxis->GetNbins();
00768 for (Int_t i = 1; i <= npb; i++) {
00769 val = fPhiAxis->GetBinUpEdge(i);
00770 if (val > phi0 && val < phi1)
00771 {
00772 glVertex2f(eta0, val);
00773 glVertex2f(eta1, val);
00774 }
00775 }
00776
00777 glEnd();
00778
00779
00780
00781 glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT | GL_POLYGON_BIT);
00782 TGLUtil::LineWidth(2);
00783 if (fCells3D)
00784 {
00785 SetAxis3DTitlePos(rnrCtx, eta0, eta1, phi0, phi1);
00786 DrawAxis3D(rnrCtx);
00787 }
00788 else
00789 {
00790 DrawAxis2D(rnrCtx);
00791 }
00792 glPopAttrib();
00793 }
00794
00795
00796 void TEveCaloLegoGL::DrawCells3D(TGLRnrCtx & rnrCtx) const
00797 {
00798
00799
00800
00801 {
00802 for (SliceDLMap_i i = fDLMap.begin(); i != fDLMap.end(); ++i) {
00803 TGLUtil::ColorTransparency(fM->GetDataSliceColor(i->first), fM->GetData()->GetSliceTransparency(i->first));
00804 glLoadName(i->first);
00805 glPushName(0);
00806 glCallList(i->second);
00807 glPopName();
00808 }
00809 }
00810
00811 {
00812 if (rnrCtx.SceneStyle() == TGLRnrCtx::kFill) {
00813 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00814 glDisable(GL_POLYGON_OFFSET_FILL);
00815 TGLUtil::Color(1);
00816 for (SliceDLMap_i i = fDLMap.begin(); i != fDLMap.end(); ++i)
00817 glCallList(i->second);
00818 }
00819 }
00820 }
00821
00822
00823 void TEveCaloLegoGL::PrepareCell2DData(TEveCaloData::vCellId_t& cellList, vCell2D_t& cells2D) const
00824 {
00825
00826
00827 Int_t max_energy_slice, cellID=0;
00828 Float_t sum, max_energy;
00829
00830 TEveCaloData::vCellId_t::iterator currentCell = cellList.begin();
00831 TEveCaloData::vCellId_t::iterator nextCell = currentCell;
00832 ++nextCell;
00833
00834 while (true)
00835 {
00836 TEveCaloData::CellData_t currentCellData;
00837 TEveCaloData::CellData_t nextCellData;
00838
00839 fM->fData->GetCellData(*currentCell, currentCellData);
00840 sum = max_energy = currentCellData.Value(fM->fPlotEt);
00841 max_energy_slice = currentCell->fSlice;
00842 while (nextCell != cellList.end() && currentCell->fTower == nextCell->fTower)
00843 {
00844 fM->fData->GetCellData(*nextCell, nextCellData);
00845 Float_t energy = nextCellData.Value(fM->fPlotEt);
00846 sum += energy;
00847 if (energy > max_energy)
00848 {
00849 max_energy = energy;
00850 max_energy_slice = nextCell->fSlice;
00851 }
00852 ++nextCell;
00853 ++cellID;
00854 }
00855
00856 WrapTwoPi(currentCellData.fPhiMin, currentCellData.fPhiMax);
00857 cells2D.push_back(Cell2D_t(cellID, sum, max_energy_slice));
00858 cells2D.back().SetGeom(currentCellData.fEtaMin, currentCellData.fEtaMax,
00859 currentCellData.fPhiMin, currentCellData.fPhiMax);
00860
00861 if (nextCell == cellList.end())
00862 break;
00863
00864 currentCell = nextCell;
00865 ++nextCell;
00866 ++cellID;
00867 }
00868 }
00869
00870
00871 void TEveCaloLegoGL::PrepareCell2DDataRebin(TEveCaloData::RebinData_t& rebinData, vCell2D_t& cells2D) const
00872 {
00873
00874
00875 const Int_t nEta = fEtaAxis->GetNbins();
00876 const Int_t nPhi = fPhiAxis->GetNbins();
00877 std::vector<Float_t> vec;
00878 vec.assign((nEta + 2)*(nPhi + 2), 0.f);
00879 std::vector<Float_t> max_e;
00880 std::vector<Int_t> max_e_slice;
00881 max_e.assign((nEta + 2) * (nPhi + 2), 0.f);
00882 max_e_slice.assign((nEta + 2) * (nPhi + 2), -1);
00883
00884 for (UInt_t bin = 0; bin < rebinData.fBinData.size(); ++bin) {
00885 Float_t ssum = 0;
00886 if (rebinData.fBinData[bin] != -1) {
00887 Float_t *val = rebinData.GetSliceVals(bin);
00888 for (Int_t s = 0; s < rebinData.fNSlices; ++s) {
00889 ssum += val[s];
00890 if (val[s] > max_e[bin]) {
00891 max_e[bin] = val[s];
00892 max_e_slice[bin] = s;
00893 }
00894 }
00895 }
00896 vec[bin] = ssum;
00897 }
00898
00899
00900 Float_t threshold = fM->GetDataSliceThreshold(0);
00901 for (Int_t s = 1; s < fM->fData->GetNSlices(); ++s) {
00902 if (threshold > fM->GetDataSliceThreshold(s))
00903 threshold = fM->GetDataSliceThreshold(s);
00904 }
00905
00906
00907 for (Int_t i = 1; i <= fEtaAxis->GetNbins(); ++i) {
00908 for (Int_t j = 1; j <= fPhiAxis->GetNbins(); ++j) {
00909 const Int_t bin = j * (nEta + 2) + i;
00910 if (vec[bin] > threshold && rebinData.fBinData[bin] != -1) {
00911 cells2D.push_back(Cell2D_t(bin, vec[bin], max_e_slice[bin]));
00912 cells2D.back().SetGeom(fEtaAxis->GetBinLowEdge(i), fEtaAxis->GetBinUpEdge(i),
00913 fPhiAxis->GetBinLowEdge(j), fPhiAxis->GetBinUpEdge(j));
00914 }
00915 }
00916 }
00917 }
00918
00919
00920 void TEveCaloLegoGL::DrawCells2D(TGLRnrCtx &rnrCtx, vCell2D_t& cells2D) const
00921 {
00922
00923
00924 Float_t bws = -1;
00925 Float_t logMax = -1;
00926
00927 Float_t baseOffset = fM->GetFixedHeightValIn2DMode()*fMaxVal;
00928
00929 if (fM->f2DMode == TEveCaloLego::kValColor)
00930 {
00931 fM->AssertPalette();
00932 UChar_t col[4];
00933
00934 for (vCell2D_i i = cells2D.begin(); i != cells2D.end(); ++i)
00935 {
00936 if (rnrCtx.SecSelection()) glLoadName(i->fId);
00937 glBegin(GL_POLYGON);
00938 fM->fPalette->ColorFromValue(TMath::FloorNint(i->fSumVal), col);
00939 col[3] = fM->GetData()->GetSliceTransparency(i->fMaxSlice);
00940 TGLUtil::Color4ubv(col);
00941 Float_t z = fM->GetHasFixedHeightIn2DMode() ? baseOffset : i->fSumVal;
00942 glVertex3f(i->fX0, i->fY0, z);
00943 glVertex3f(i->fX1, i->fY0, z);
00944 glVertex3f(i->fX1, i->fY1, z);
00945 glVertex3f(i->fX0, i->fY1, z);
00946 glEnd();
00947 }
00948 }
00949 else
00950 {
00951 Float_t x, y;
00952 if (!rnrCtx.HighlightOutline())
00953 {
00954 Float_t maxv = 0;
00955 bws = 1e5;
00956 for (vCell2D_i i = fCells2D.begin(); i != fCells2D.end(); ++i)
00957 {
00958 if (i->MinSize() < bws) bws = i->MinSize();
00959 if (i->fSumVal > maxv) maxv = i->fSumVal;
00960 }
00961 bws *= 0.5f;
00962 logMax = TMath::Log10(maxv + 1);
00963 fValToPixel = bws/logMax;
00964 }
00965
00966
00967 if (rnrCtx.SecSelection())
00968 {
00969 for (vCell2D_i i = cells2D.begin(); i != cells2D.end(); ++i)
00970 {
00971 glLoadName(i->fMaxSlice);
00972 glPushName(i->fId);
00973
00974 glBegin(GL_QUADS);
00975 Float_t z = fM->GetHasFixedHeightIn2DMode() ? baseOffset : i->fSumVal;
00976 glVertex3f(i->fX0, i->fY0, z);
00977 glVertex3f(i->fX1, i->fY0, z);
00978 glVertex3f(i->fX1, i->fY1, z);
00979 glVertex3f(i->fX0, i->fY1, z);
00980 glEnd();
00981
00982 glPopName();
00983 }
00984 }
00985 else
00986 {
00987 if (!rnrCtx.HighlightOutline())
00988 {
00989 glBegin(GL_POINTS);
00990 for (vCell2D_i i = cells2D.begin(); i != cells2D.end(); ++i)
00991 {
00992 TGLUtil::ColorTransparency(fM->fData->GetSliceColor(i->fMaxSlice), fM->fData->GetSliceTransparency(i->fMaxSlice));
00993 Float_t z = fM->GetHasFixedHeightIn2DMode() ? baseOffset : i->fSumVal;
00994 glVertex3f(i->X(), i->Y() , z);
00995 }
00996 glEnd();
00997 }
00998
00999 glBegin(GL_QUADS);
01000 for (vCell2D_i i = cells2D.begin(); i != cells2D.end(); ++i)
01001 {
01002 TGLUtil::ColorTransparency(fM->fData->GetSliceColor(i->fMaxSlice), fM->fData->GetSliceTransparency(i->fMaxSlice));
01003 Float_t bw = fValToPixel*TMath::Log10(i->fSumVal+1);
01004 x = i->X();
01005 y = i->Y();
01006 Float_t z = fM->GetHasFixedHeightIn2DMode() ? baseOffset : i->fSumVal;
01007 glVertex3f(x - bw, y - bw, z);
01008 glVertex3f(x + bw, y - bw, z);
01009 glVertex3f(x + bw, y + bw, z);
01010 glVertex3f(x - bw, y + bw, z);
01011 }
01012 glEnd();
01013
01014 if (fM->f2DMode == TEveCaloLego::kValSizeOutline)
01015 {
01016 glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT);
01017 Float_t z = 0;
01018 Float_t zOff = fMaxVal*0.001 ;
01019 glBegin(GL_QUADS);
01020 for ( vCell2D_i i = cells2D.begin(); i != cells2D.end(); ++i) {
01021 Char_t transp = TMath::Min(100, 80 + fM->fData->GetSliceTransparency(i->fMaxSlice) / 5);
01022 TGLUtil::ColorTransparency(fM->fData->GetSliceColor(i->fMaxSlice), transp);
01023 z = fM->GetHasFixedHeightIn2DMode() ? baseOffset : i->fSumVal;
01024 z -= zOff;
01025 glVertex3f(i->fX0, i->fY0, z);
01026 glVertex3f(i->fX1, i->fY0, z);
01027 glVertex3f(i->fX1, i->fY1, z);
01028 glVertex3f(i->fX0, i->fY1, z);
01029 }
01030 glEnd();
01031
01032 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
01033 glBegin(GL_QUADS);
01034 for ( vCell2D_i i = cells2D.begin(); i != cells2D.end(); ++i) {
01035 TGLUtil::ColorTransparency(fM->fData->GetSliceColor(i->fMaxSlice), 60);
01036 z = fM->GetHasFixedHeightIn2DMode() ? baseOffset : i->fSumVal;
01037 z += zOff;
01038 glVertex3f(i->fX0, i->fY0, z);
01039 glVertex3f(i->fX1, i->fY0, z);
01040 glVertex3f(i->fX1, i->fY1, z);
01041 glVertex3f(i->fX0, i->fY1, z);
01042 }
01043 glEnd();
01044 glPopAttrib();
01045 }
01046 }
01047 }
01048
01049
01050 if (fCurrentPixelsPerBin > fM->fDrawNumberCellPixels &&
01051 (rnrCtx.Selection() || rnrCtx.Highlight() || rnrCtx.HighlightOutline()) == kFALSE)
01052 {
01053 TGLUtil::Color(rnrCtx.ColorSet().Markup().GetColorIndex());
01054 TGLFont font;
01055 rnrCtx.RegisterFontNoScale(fM->fCellPixelFontSize, "arial", TGLFont::kPixmap, font);
01056 const char* txt;
01057 for (vCell2D_i i = cells2D.begin(); i != cells2D.end(); ++i) {
01058
01059 Float_t val = i->fSumVal;
01060 if (val > 10)
01061 txt = Form("%d", TMath::Nint(val));
01062 else if (val > 1 )
01063 txt = Form("%.1f", val);
01064 else if (val > 0.01 )
01065 txt = Form("%.2f", 0.01*TMath::Nint(val*100));
01066 else
01067 txt = Form("~1e%d", TMath::Nint(TMath::Log10(val)));
01068
01069 font.Render(txt, i->X(), i->Y(), val*1.2, TGLFont::kCenterH, TGLFont::kCenterV);
01070 }
01071 }
01072 }
01073
01074
01075 void TEveCaloLegoGL::DrawHighlight(TGLRnrCtx& rnrCtx, const TGLPhysicalShape* , Int_t ) const
01076 {
01077
01078
01079 if (fM->fData->GetCellsSelected().empty() && fM->fData->GetCellsHighlighted().empty())
01080 {
01081 return;
01082 }
01083
01084 glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT | GL_POLYGON_BIT );
01085
01086
01087 glPushMatrix();
01088 Float_t sx, sy, sz;
01089 GetScaleForMatrix(sx, sy, sz);
01090 glScalef(sx, sy, sz);
01091 glTranslatef(-fM->GetEta(), -fM->fPhi, 0);
01092
01093 glDisable(GL_LIGHTING);
01094 glDisable(GL_CULL_FACE);
01095 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
01096
01097 TGLUtil::LineWidth(2);
01098 TGLUtil::LockColor();
01099 if (!fM->fData->GetCellsHighlighted().empty())
01100 {
01101 glColor4ubv(rnrCtx.ColorSet().Selection(3).CArr());
01102 DrawSelectedCells(rnrCtx, fM->fData->GetCellsHighlighted());
01103 }
01104 if (!fM->fData->GetCellsSelected().empty())
01105 {
01106 Float_t dr[2];
01107 glGetFloatv(GL_DEPTH_RANGE,dr);
01108 glColor4ubv(rnrCtx.ColorSet().Selection(1).CArr());
01109 glDepthRange(dr[0], 0.8*dr[1]);
01110 DrawSelectedCells(rnrCtx, fM->fData->GetCellsSelected());
01111 glDepthRange(dr[0], dr[1]);
01112 }
01113
01114 TGLUtil::UnlockColor();
01115 glPopMatrix();
01116 glPopAttrib();
01117 }
01118
01119
01120
01121 void TEveCaloLegoGL::DrawSelectedCells(TGLRnrCtx & rnrCtx, TEveCaloData::vCellId_t cellsSelectedInput) const
01122 {
01123
01124
01125
01126 TEveCaloData::vCellId_t cellsSelected;
01127 TEveCaloData::CellData_t cellData;
01128 for (TEveCaloData::vCellId_i i = cellsSelectedInput.begin(); i != cellsSelectedInput.end(); ++i)
01129 {
01130 fM->fData->GetCellData((*i), cellData);
01131 if (fM->CellInEtaPhiRng(cellData))
01132 cellsSelected.push_back(*i);
01133 }
01134
01135
01136 TEveCaloData::RebinData_t rebinDataSelected;
01137 if (fBinStep > 1)
01138 {
01139 fM->fData->Rebin(fEtaAxis, fPhiAxis, cellsSelected, fM->fPlotEt, rebinDataSelected);
01140 if (fM->fNormalizeRebin) {
01141 Float_t scale = 1.f / (fBinStep * fBinStep);
01142 for (std::vector<Float_t>::iterator it = rebinDataSelected.fSliceData.begin(); it != rebinDataSelected.fSliceData.end(); it++)
01143 (*it) *= scale;
01144 }
01145 }
01146
01147 if (fCells3D)
01148 {
01149 Float_t offset = 0;
01150 if (fBinStep == 1)
01151 {
01152 for (TEveCaloData::vCellId_i j = cellsSelected.begin(); j != cellsSelected.end(); ++j)
01153 {
01154 offset = 0;
01155 {
01156 Int_t orig_slice = j->fSlice;
01157 for (Int_t s = 0; s < orig_slice; ++s)
01158 {
01159 j->fSlice = s;
01160 fM->fData->GetCellData(*j, cellData);
01161 offset += cellData.Value(fM->fPlotEt);
01162 }
01163 j->fSlice = orig_slice;
01164 }
01165 fM->fData->GetCellData(*j, cellData);
01166 WrapTwoPi(cellData.fPhiMin, cellData.fPhiMax);
01167 MakeQuad(cellData.EtaMin(), cellData.PhiMin(), offset,
01168 cellData.EtaDelta(), cellData.PhiDelta(), cellData.Value(fM->fPlotEt));
01169 }
01170 }
01171 else
01172 {
01173 Float_t *vals;
01174 Float_t *valsRef;
01175 Float_t y0, y1;
01176 Int_t nSlices = fM->fData->GetNSlices();
01177 for (Int_t i = 1; i <= fEtaAxis->GetNbins(); ++i)
01178 {
01179 for (Int_t j = 1; j <= fPhiAxis->GetNbins(); ++j)
01180 {
01181 const Int_t bin = (i)+(j)*(fEtaAxis->GetNbins()+2);
01182 if (rebinDataSelected.fBinData[bin] !=-1)
01183 {
01184 offset = 0;
01185 vals = rebinDataSelected.GetSliceVals(bin);
01186 valsRef = fRebinData.GetSliceVals(bin);
01187 for (Int_t s = 0; s < nSlices; ++s)
01188 {
01189 if (vals[s] > 0)
01190 {
01191 y0 = fPhiAxis->GetBinLowEdge(j);
01192 y1 = fPhiAxis->GetBinUpEdge(j);
01193 WrapTwoPi(y0, y1);
01194 MakeQuad(fEtaAxis->GetBinLowEdge(i), y0, offset,
01195 fEtaAxis->GetBinWidth(i), y1-y0, vals[s]);
01196 }
01197 offset += valsRef[s];
01198 }
01199 }
01200 }
01201 }
01202 }
01203 }
01204 else
01205 {
01206 vCell2D_t cells2DSelected;
01207 if (fBinStep == 1)
01208 {
01209
01210 TEveCaloData::vCellId_i j = cellsSelectedInput.begin();
01211 TEveCaloData::vCellId_i jEnd = cellsSelectedInput.end();
01212 std::set<Int_t> towers;
01213 while (j != jEnd)
01214 {
01215 towers.insert(j->fTower);
01216 ++j;
01217 }
01218 for (vCell2D_i i = fCells2D.begin(); i != fCells2D.end(); ++i)
01219 {
01220 TEveCaloData::CellId_t cell = fM->fCellList[i->fId];
01221 std::set<Int_t>::iterator ti = towers.find(cell.fTower);
01222 if (towers.find(cell.fTower) != towers.end())
01223 {
01224 cells2DSelected.push_back(*i);
01225 }
01226 }
01227 }
01228 else
01229 {
01230 PrepareCell2DDataRebin(rebinDataSelected, cells2DSelected);
01231 }
01232 DrawCells2D(rnrCtx, cells2DSelected);
01233 }
01234 }
01235
01236
01237 void TEveCaloLegoGL::DirectDraw(TGLRnrCtx & rnrCtx) const
01238 {
01239
01240
01241 if (! fM->fData || ! fM->fData->GetEtaBins() || ! fM->fData->GetPhiBins())
01242 return;
01243
01244
01245 if (fM->fProjection == TEveCaloLego::kAuto)
01246 fCells3D = (!(rnrCtx.RefCamera().IsOrthographic() && rnrCtx.RefCamera().GetCamBase().GetBaseVec(1).Z()));
01247 else if (fM->fProjection == TEveCaloLego::k2D)
01248 fCells3D = kFALSE;
01249 else if (fM->fProjection == TEveCaloLego::k3D)
01250 fCells3D = kTRUE;
01251
01252
01253 Int_t new_bin_step = GetGridStep(rnrCtx);
01254
01255
01256 if (fM->AssertCellIdCache() || fBinStep != new_bin_step)
01257 {
01258 fBinStep = new_bin_step;
01259 fDLCacheOK = kFALSE;
01260 fRebinData.Clear();
01261
01262 RebinAxis(fM->fData->GetEtaBins(), fEtaAxis);
01263 RebinAxis(fM->fData->GetPhiBins(), fPhiAxis);
01264
01265 if (fBinStep > 1)
01266 {
01267 fM->fData->Rebin(fEtaAxis, fPhiAxis, fM->fCellList, fM->fPlotEt, fRebinData);
01268
01269 fMaxVal = 0;
01270 for (UInt_t i = 0; i < fRebinData.fSliceData.size(); i += fRebinData.fNSlices)
01271 {
01272 Double_t sum = 0;
01273 for (Int_t s = 0; s < fRebinData.fNSlices; s++)
01274 {
01275 sum += fRebinData.fSliceData[i+s];
01276 }
01277 if (sum > fMaxVal) fMaxVal = sum;
01278 }
01279
01280 if (fM->fNormalizeRebin)
01281 {
01282 Float_t scale = 1.f / (fBinStep * fBinStep);
01283 for (std::vector<Float_t>::iterator it = fRebinData.fSliceData.begin(); it != fRebinData.fSliceData.end(); it++)
01284 {
01285 (*it) *= scale;
01286 }
01287 fMaxVal *= scale;
01288 }
01289 }
01290 else
01291 {
01292 fMaxVal = fM->GetMaxVal();
01293 }
01294 }
01295
01296
01297 glPushMatrix();
01298 Float_t sx, sy, sz;
01299 GetScaleForMatrix(sx, sy, sz);
01300 glScalef(sx, sy, sz);
01301 glTranslatef(-fM->GetEta(), -fM->fPhi, 0);
01302
01303 fFontColor = fM->fFontColor;
01304 fGridColor = fM->fGridColor;
01305 if (fGridColor < 0 || fFontColor < 0)
01306 {
01307 TColor* c1 = gROOT->GetColor(rnrCtx.ColorSet().Markup().GetColorIndex());
01308 TColor* c2 = gROOT->GetColor(rnrCtx.ColorSet().Background().GetColorIndex());
01309 Float_t f1, f2;
01310 if (fFontColor < 0) {
01311 f1 = 0.8; f2 = 0.2;
01312 fFontColor = TColor::GetColor(c1->GetRed() *f1 + c2->GetRed() *f2,
01313 c1->GetGreen()*f1 + c2->GetGreen()*f2,
01314 c1->GetBlue() *f1 + c2->GetBlue() *f2);
01315 }
01316 if (fGridColor < 0) {
01317 f1 = 0.3; f2 = 0.3;
01318 fGridColor = TColor::GetColor(c1->GetRed() *f1 + c2->GetRed() *f2,
01319 c1->GetGreen()*f1 + c2->GetGreen()*f2,
01320 c1->GetBlue() *f1 + c2->GetBlue() *f2);
01321 }
01322 }
01323
01324 glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT | GL_POLYGON_BIT);
01325 TGLUtil::LineWidth(1);
01326 glEnable(GL_BLEND);
01327 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
01328 if (!fM->fData->Empty())
01329 {
01330 glPushName(0);
01331 if (fCells3D)
01332 {
01333 if (fDLCacheOK == kFALSE)
01334 {
01335 if (fBinStep == 1)
01336 Make3DDisplayList(fM->fCellList, fDLMap, kTRUE);
01337 else
01338 Make3DDisplayListRebin(fRebinData, fDLMap, kTRUE);
01339 fDLCacheOK = kTRUE;
01340 }
01341 glEnable(GL_NORMALIZE);
01342 glEnable(GL_POLYGON_OFFSET_FILL);
01343 glPolygonOffset(0.8, 1);
01344
01345 DrawCells3D(rnrCtx);
01346 }
01347 else
01348 {
01349 glDisable(GL_LIGHTING);
01350
01351 fCells2D.clear();
01352 if (fBinStep == 1)
01353 PrepareCell2DData(fM->fCellList, fCells2D);
01354 else
01355 PrepareCell2DDataRebin(fRebinData, fCells2D);
01356
01357 DrawCells2D(rnrCtx, fCells2D);
01358 }
01359 glPopName();
01360 }
01361 glPopAttrib();
01362
01363
01364 if (rnrCtx.Selection() == kFALSE && rnrCtx.IsDrawPassFilled())
01365 {
01366 glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT | GL_POLYGON_BIT);
01367 glDisable(GL_LIGHTING);
01368 DrawHistBase(rnrCtx);
01369 if (fM->fDrawHPlane) {
01370 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
01371 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
01372 glDisable(GL_CULL_FACE);
01373 TGLUtil::ColorTransparency(fM->fPlaneColor, fM->fPlaneTransparency);
01374 Float_t zhp = fM->fHPlaneVal * fMaxVal;
01375 glBegin(GL_POLYGON);
01376 glVertex3f(fM->fEtaMin, fM->GetPhiMin(), zhp);
01377 glVertex3f(fM->fEtaMax, fM->GetPhiMin(), zhp);
01378 glVertex3f(fM->fEtaMax, fM->GetPhiMax(), zhp);
01379 glVertex3f(fM->fEtaMin, fM->GetPhiMax(), zhp);
01380 glEnd();
01381 }
01382 glPopAttrib();
01383 }
01384
01385 glPopMatrix();
01386 }
01387
01388
01389 void TEveCaloLegoGL::ProcessSelection(TGLRnrCtx & , TGLSelectRecord & rec)
01390 {
01391
01392
01393 TEveCaloData::vCellId_t sel;
01394 if (rec.GetN() > 2)
01395 {
01396 Int_t slice = rec.GetItem(1);
01397 Int_t cell = rec.GetItem(2);
01398
01399 if (fBinStep == 1)
01400 {
01401 Int_t tower = fM->fCellList[cell].fTower;
01402 while (cell > 0 && tower == fM->fCellList[cell].fTower)
01403 {
01404 sel.push_back(fM->fCellList[cell]);
01405 if (fCells3D) break;
01406 --cell;
01407 }
01408 }
01409 else
01410 {
01411 if (cell > 0)
01412 {
01413 Int_t nEta = fEtaAxis->GetNbins();
01414 Int_t phiBin = Int_t(cell/(nEta+2));
01415 Int_t etaBin = cell - phiBin*(nEta+2);
01416 TEveCaloData::vCellId_t sl;
01417 fM->fData->GetCellList(fEtaAxis->GetBinCenter(etaBin), fEtaAxis->GetBinWidth(etaBin),
01418 fPhiAxis->GetBinCenter(phiBin), fPhiAxis->GetBinWidth(phiBin),
01419 sl);
01420
01421 for (TEveCaloData::vCellId_i it = sl.begin(); it != sl.end(); ++it)
01422 {
01423 if (fCells3D) {
01424 if ((*it).fSlice == slice ) sel.push_back(*it);
01425 } else {
01426 if ((*it).fSlice <= slice ) sel.push_back(*it);
01427 }
01428 }
01429 }
01430 }
01431 }
01432 fM->fData->ProcessSelection(sel, rec);
01433 }