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