3 #include "TPCSector2DGL.h"
5 #include <Alieve/TPCData.h>
9 #include <TVirtualPad.h>
10 #include <TStopwatch.h>
12 #include <TGLDrawFlags.h>
16 using namespace Alieve;
19 //______________________________________________________________________
23 ClassImp(TPCSector2DGL)
25 // This can be optimized to non-pow-2 values once everybody has GL 1.4.
27 const Int_t TPCSector2DGL::fgkTextureWidth = 256;
28 const Int_t TPCSector2DGL::fgkTextureHeight = 128;
29 const Int_t TPCSector2DGL::fgkTextureByteSize = 4*256*128;
31 /**************************************************************************/
33 TPCSector2DGL::TPCSector2DGL() :
44 TPCSector2DGL::~TPCSector2DGL()
46 if(fImage) delete fImage;
47 if(fTexture) glDeleteTextures(1, &fTexture);
50 /**************************************************************************/
52 Bool_t TPCSector2DGL::SetModel(TObject* obj)
54 #if ROOT_VERSION_CODE <= ROOT_VERSION(5,11,2)
55 if(set_model(obj, "Alieve::TPCSector2D")) {
56 #elif ROOT_VERSION_CODE <= ROOT_VERSION(5,13,0)
57 if(SetModelCheckClass(obj, "Alieve::TPCSector2D")) {
59 if(SetModelCheckClass(obj, Alieve::TPCSector2D::Class())) {
61 fSector = (TPCSector2D*) fExternalObj;
67 void TPCSector2DGL::SetBBox()
69 #if ROOT_VERSION_CODE <= ROOT_VERSION(5,11,2)
70 set_axis_aligned_bbox(((TPCSector2D*)fExternalObj)->AssertBBox());
72 SetAxisAlignedBBox(((TPCSector2D*)fExternalObj)->AssertBBox());
76 /**************************************************************************/
78 void TPCSector2DGL::ProcessSelection(UInt_t* ptr, TGLViewer*, TGLScene*)
80 if (ptr[0] != 3) return;
81 ptr += 3; // skip n, zmin, zmax
84 Int_t seg = fSector->fSectorID;
85 if (row < 0 || row >= TPCSectorData::GetNAllRows()) return;
86 if (pad < 0 || pad >= TPCSectorData::GetNPadsInRow(row)) return;
87 // EVE -> Std convention
88 Int_t sseg = seg, srow = row;
89 if (row >= TPCSectorData::GetInnSeg().GetNRows()) {
91 srow -= TPCSectorData::GetInnSeg().GetNRows();
93 switch (fSector->fPickMode)
96 printf("TPCSector2DGL::ProcessSelection segment=%d, row=%d, pad=%d\n",
101 if (fSectorData == 0) return;
102 Int_t mint = fSector->GetMinTime();
103 Int_t maxt = fSector->GetMaxTime();
104 TH1S* h = new TH1S(Form("Seg%d_Row%d_Pad%d", sseg, srow, pad),
105 Form("Segment %d, Row %d, Pad %d", sseg, srow, pad),
106 maxt - mint +1 , mint, maxt);
107 h->SetXTitle("Time");
109 TPCSectorData::PadIterator i = fSectorData->MakePadIterator(row, pad);
111 h->Fill(i.Time(), i.Signal());
118 if (fSectorData == 0) return;
119 Int_t mint = fSector->GetMinTime();
120 Int_t maxt = fSector->GetMaxTime();
121 Int_t npad = TPCSectorData::GetNPadsInRow(row);
122 TH2S* h = new TH2S(Form("Seg%d_Row%d", sseg, srow),
123 Form("Segment %d, Row %d", sseg, srow),
124 maxt - mint +1 , mint, maxt,
126 h->SetXTitle("Time");
129 TPCSectorData::RowIterator i = fSectorData->MakeRowIterator(row);
132 h->Fill(i.Time(), i.Pad(), i.Signal());
141 /**************************************************************************/
143 void TPCSector2DGL::DirectDraw(const TGLDrawFlags& flags) const
145 // Actual GL drawing.
147 // printf("TPCSector2DGL::DirectDraw \n");
149 fSectorData = fSector->GetSectorData();
151 if(fRTS < fSector->fRTS && fSectorData != 0) {
153 fRTS = fSector->fRTS;
156 glPushAttrib(GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT |
157 GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT | GL_POLYGON_BIT);
159 glDisable(GL_LIGHTING);
160 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
161 glEnable(GL_COLOR_MATERIAL);
162 glDisable(GL_CULL_FACE);
165 if(fSectorData != 0) {
167 const TPCSectorData::SegmentInfo& iSeg = TPCSectorData::GetInnSeg();
168 const TPCSectorData::SegmentInfo& o1Seg = TPCSectorData::GetOut1Seg();
169 const TPCSectorData::SegmentInfo& o2Seg = TPCSectorData::GetOut2Seg();
171 if(flags.SecSelection()) {
173 if(fSector->fRnrInn) DisplayNamedQuads(iSeg, 0, 0);
174 if(fSector->fRnrOut1) DisplayNamedQuads(o1Seg, iSeg.GetNMaxPads(), 0);
175 if(fSector->fRnrOut2) DisplayNamedQuads(o2Seg, 0, o1Seg.GetNRows());
179 if(fSector->fUseTexture) {
182 glDepthMask(GL_FALSE);
183 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
185 glPolygonOffset(2,2);
186 glEnable(GL_POLYGON_OFFSET_FILL);
188 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
189 glBindTexture(GL_TEXTURE_2D, fTexture);
190 glEnable(GL_TEXTURE_2D);
192 if(fSector->fRnrInn) DisplayTexture(iSeg, 0, 0);
193 if(fSector->fRnrOut1) DisplayTexture(o1Seg, iSeg.GetNMaxPads(), 0);
194 if(fSector->fRnrOut2) DisplayTexture(o2Seg, 0, o1Seg.GetNRows());
196 glDisable(GL_TEXTURE_2D);
198 if(fSector->fRnrInn) DisplayQuads(iSeg, 0, 0);
199 if(fSector->fRnrOut1) DisplayQuads(o1Seg, iSeg.GetNMaxPads(), 0);
200 if(fSector->fRnrOut2) DisplayQuads(o2Seg, 0, o1Seg.GetNRows());
202 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
211 /**************************************************************************/
213 /**************************************************************************/
215 void TPCSector2DGL::LoadPadrow(TPCSectorData::RowIterator& iter,
216 Int_t row, Int_t col_off) const
221 Int_t minTime = fSector->fMinTime;
222 Int_t maxTime = fSector->fMaxTime;
223 Bool_t halfBorderTime = ((maxTime - minTime) % 2 == 0);
225 UChar_t* img_pos = GetRowCol(row, col_off);
226 while (iter.NextPad()) {
229 while (iter.Next()) {
233 if(time < minTime || time > maxTime)
236 if(fSector->fShowMax) {
241 if(halfBorderTime && (time == minTime || time == maxTime))
248 if(fSector->fShowMax == kFALSE && fSector->fAverage) {
249 padVal = (Int_t)((Float_t)padVal / (maxTime - minTime));
251 padVal = TMath::Min(padVal, fSector->fMaxVal);
252 if(padVal > fSector->fThreshold)
253 fSector->ColorFromArray(padVal, img_pos);
258 /**************************************************************************/
260 void TPCSector2DGL::CreateTexture() const
263 fImage = new UChar_t[fgkTextureByteSize];
264 glGenTextures(1, &fTexture);
266 memset(fImage, 0, fgkTextureByteSize);
268 Int_t rowOff[3], colOff[3];
271 rowOff[1] = rowOff[2] = -TPCSectorData::GetSeg(1).GetFirstRow();
272 colOff[0] = colOff[2] = 0;
273 colOff[1] = TPCSectorData::GetSeg(0).GetNMaxPads();
274 isOn[0] = fSector->fRnrInn;
275 isOn[1] = fSector->fRnrOut1;
276 isOn[2] = fSector->fRnrOut2;
278 fSector->SetupColorArray();
280 // Loop over 3 main segments
281 for (Int_t sId = 0; sId <= 2; ++sId) {
282 if(isOn[sId] == kFALSE)
284 const TPCSectorData::SegmentInfo& sInfo = TPCSectorData::GetSeg(sId);
285 for (Int_t row=sInfo.GetFirstRow(); row<=sInfo.GetLastRow(); ++row) {
286 TPCSectorData::RowIterator i = fSectorData->MakeRowIterator(row);
287 Int_t offset = (sInfo.GetNMaxPads() - TPCSectorData::GetNPadsInRow(row))/2;
288 LoadPadrow(i, row + rowOff[sId], offset + colOff[sId]);
292 glBindTexture (GL_TEXTURE_2D, fTexture);
293 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_REPEAT);
294 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_REPEAT);
295 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
296 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
297 glTexEnvf (GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE, GL_REPLACE);
298 glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, fgkTextureWidth, fgkTextureHeight,
299 0, GL_RGBA, GL_UNSIGNED_BYTE, fImage);
303 /**************************************************************************/
305 /**************************************************************************/
307 void TPCSector2DGL::DisplayTexture(const TPCSectorData::SegmentInfo& seg,
308 Int_t startCol, Int_t startRow) const
310 Float_t w = seg.GetNMaxPads()*seg.GetPadWidth()/2;
311 Float_t y1 = seg.GetRLow();
312 Float_t y2 = y1 + seg.GetNRows()*seg.GetPadHeight();
314 Float_t u1 = (Float_t) startCol / fgkTextureWidth;
315 Float_t v1 = (Float_t) startRow / fgkTextureHeight;
316 Float_t u2 = u1 + (Float_t) seg.GetNMaxPads() / fgkTextureWidth;
317 Float_t v2 = v1 + (Float_t) seg.GetNRows() / fgkTextureHeight;
320 glTexCoord2f(u1, v1); glVertex2f(-w, y1);
321 glTexCoord2f(u1, v2); glVertex2f(-w, y2);
322 glTexCoord2f(u2, v2); glVertex2f( w, y2);
323 glTexCoord2f(u2, v1); glVertex2f( w, y1);
327 /**************************************************************************/
329 void TPCSector2DGL::DisplayQuads(const TPCSectorData::SegmentInfo& seg,
330 Int_t startCol, Int_t startRow) const
334 Float_t padW = seg.GetPadWidth();
335 Float_t padH = seg.GetPadHeight();
338 for (Int_t row=0; row<seg.GetNRows(); row++) {
339 y_d = seg.GetRLow() + row*padH;
341 x_off = -seg.GetNMaxPads()*padW/2;
342 Int_t tpcRow = row + seg.GetFirstRow();
343 Int_t deltaPad = (seg.GetNMaxPads() - TPCSectorData::GetNPadsInRow(tpcRow))/2;
344 Int_t maxPad = seg.GetNMaxPads() - deltaPad;
345 UChar_t *pix = GetRowCol(row + startRow, startCol + deltaPad);
346 for (Int_t pad=deltaPad; pad<maxPad; pad++, pix+=4) {
347 x = x_off + pad*padW;
350 glVertex2f(x+padW, y_d);
353 glVertex2f(x+padW, y_u);
360 void TPCSector2DGL::DisplayNamedQuads(const TPCSectorData::SegmentInfo& seg,
361 Int_t startCol, Int_t startRow) const
365 Float_t padW = seg.GetPadWidth();
366 Float_t padH = seg.GetPadHeight();
369 for (Int_t row=0; row<seg.GetNRows(); row++) {
370 y_d = seg.GetRLow() + row*padH;
372 x_off = -seg.GetNMaxPads()*padW/2;
373 Int_t tpcRow = row + seg.GetFirstRow();
375 Int_t deltaPad = (seg.GetNMaxPads() - TPCSectorData::GetNPadsInRow(tpcRow))/2;
376 Int_t maxPad = seg.GetNMaxPads() - deltaPad;
377 UChar_t *pix = GetRowCol(row + startRow, startCol + deltaPad);
379 for (Int_t pad=deltaPad; pad<maxPad; pad++, pix+=4) {
380 x = x_off + pad*padW;
381 if (pix[3] != 0 || fSector->fPickEmpty) {
382 glLoadName(pad - deltaPad);
384 glVertex2f(x+padW, y_d);
387 glVertex2f(x+padW, y_u);
396 /**************************************************************************/
398 /**************************************************************************/
400 void TPCSector2DGL::TraceStepsUp(const TPCSectorData::SegmentInfo& s)
402 Float_t x = -(s.GetNMaxPads()*1.0/2 - s.GetNYSteps())*s.GetPadWidth();
403 Float_t y = s.GetRLow();
405 for (Int_t i=0; i<s.GetNYSteps(); ++i) {
408 x -= s.GetPadWidth();
411 y = s.GetRLow() + s.GetNRows()*s.GetPadHeight();
412 glVertex2f(-s.GetNMaxPads()*s.GetPadWidth()/2, y);
415 void TPCSector2DGL::TraceStepsDown(const TPCSectorData::SegmentInfo& s)
417 Float_t x = s.GetNMaxPads()*s.GetPadWidth()/2;
418 Float_t y = s.GetRLow() + s.GetNRows()*s.GetPadHeight();
420 for (Int_t i=s.GetNYSteps() - 1; i>=0; --i) {
423 x -= s.GetPadWidth();
427 glVertex2f((0.5*s.GetNMaxPads() - s.GetNYSteps())*s.GetPadWidth(), y);
430 void TPCSector2DGL::DisplayFrame() const
433 ColorFromIdx(fSector->fFrameColor, col);
436 if(fSector->fRnrInn) {
438 TraceStepsUp (TPCSectorData::GetInnSeg());
439 TraceStepsDown(TPCSectorData::GetInnSeg());
442 if(fSector->fRnrOut1) {
444 TraceStepsUp (TPCSectorData::GetOut1Seg());
445 TraceStepsDown(TPCSectorData::GetOut1Seg());
448 if(fSector->fRnrOut2) {
450 TraceStepsUp (TPCSectorData::GetOut2Seg());
451 TraceStepsDown(TPCSectorData::GetOut2Seg());