]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EVE/Alieve/TPCSector2DGL.cxx
Use new naming conventions from QuadSet; increase x-width of SDD digits.
[u/mrichter/AliRoot.git] / EVE / Alieve / TPCSector2DGL.cxx
1 // $Header$
2
3 #include "TPCSector2DGL.h"
4
5 #include <Alieve/TPCData.h>
6
7 #include <TH1S.h>
8 #include <TH2S.h>
9 #include <TVirtualPad.h>
10 #include <TStopwatch.h>
11
12 #include <TGLDrawFlags.h>
13 #include <GL/gl.h>
14
15 using namespace Reve;
16 using namespace Alieve;
17 using namespace std;
18
19 //______________________________________________________________________
20 // TPCSector2DGL
21 //
22
23 ClassImp(TPCSector2DGL)
24
25 // This can be optimized to non-pow-2 values once everybody has GL 1.4.
26
27 const Int_t TPCSector2DGL::fgkTextureWidth    = 256;
28 const Int_t TPCSector2DGL::fgkTextureHeight   = 128;
29 const Int_t TPCSector2DGL::fgkTextureByteSize = 4*256*128;
30
31 /**************************************************************************/
32
33 TPCSector2DGL::TPCSector2DGL() :
34   TGLObject(),
35   
36   fSector     (0),
37   fSectorData (0),
38
39   fImage   (0),
40   fTexture (0),
41   fRTS     (0)
42 {}
43
44 TPCSector2DGL::~TPCSector2DGL()
45 {
46   if(fImage)   delete fImage;
47   if(fTexture) glDeleteTextures(1, &fTexture);
48 }
49
50 /**************************************************************************/
51
52 Bool_t TPCSector2DGL::SetModel(TObject* obj)
53 {
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")) {
58 #else
59   if(SetModelCheckClass(obj, Alieve::TPCSector2D::Class())) {
60 #endif
61     fSector = (TPCSector2D*) fExternalObj;
62     return kTRUE;
63   }
64   return kFALSE;
65 }
66
67 void TPCSector2DGL::SetBBox()
68 {
69 #if ROOT_VERSION_CODE <= ROOT_VERSION(5,11,2)
70   set_axis_aligned_bbox(((TPCSector2D*)fExternalObj)->AssertBBox());
71 #else
72   SetAxisAlignedBBox(((TPCSector2D*)fExternalObj)->AssertBBox());
73 #endif
74 }
75
76 /**************************************************************************/
77
78 void TPCSector2DGL::ProcessSelection(UInt_t* ptr, TGLViewer*, TGLScene*)
79 {
80   if (ptr[0] != 3) return;
81   ptr += 3; // skip n, zmin, zmax
82   Int_t row = ptr[1];
83   Int_t pad = ptr[2];
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()) {
90     sseg += 18;
91     srow -= TPCSectorData::GetInnSeg().GetNRows();
92   }
93   switch (fSector->fPickMode)
94     {
95     case 0: {
96       printf("TPCSector2DGL::ProcessSelection segment=%d, row=%d, pad=%d\n",
97              sseg, srow, pad);
98       break;
99     }
100     case 1: {
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");
108       h->SetYTitle("ADC");
109       TPCSectorData::PadIterator i = fSectorData->MakePadIterator(row, pad);
110       while (i.Next())
111         h->Fill(i.Time(), i.Signal());
112       h->Draw();
113       gPad->Modified();
114       gPad->Update();
115       break;
116     }
117     case 2: {
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,
125                          npad, 0, npad - 1);
126       h->SetXTitle("Time");
127       h->SetYTitle("Pad");
128       h->SetZTitle("ADC");
129       TPCSectorData::RowIterator i = fSectorData->MakeRowIterator(row);
130       while (i.NextPad())
131         while (i.Next())
132           h->Fill(i.Time(), i.Pad(), i.Signal());
133       h->Draw();
134       gPad->Modified();
135       gPad->Update();
136       break;
137     }
138     } // switch
139 }
140
141 /**************************************************************************/
142
143 void TPCSector2DGL::DirectDraw(const TGLDrawFlags& flags) const
144 {
145   // Actual GL drawing.
146
147   // printf("TPCSector2DGL::DirectDraw \n");
148
149   fSectorData = fSector->GetSectorData();
150
151   if(fRTS < fSector->fRTS && fSectorData != 0) {
152     CreateTexture();
153     fRTS = fSector->fRTS;
154   }
155
156   glPushAttrib(GL_CURRENT_BIT      | GL_DEPTH_BUFFER_BIT |
157                GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT       | GL_POLYGON_BIT);
158
159   glDisable(GL_LIGHTING);
160   glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
161   glEnable(GL_COLOR_MATERIAL);
162   glDisable(GL_CULL_FACE);
163
164   // Display digits
165   if(fSectorData != 0) {
166
167     const TPCSectorData::SegmentInfo&  iSeg = TPCSectorData::GetInnSeg();
168     const TPCSectorData::SegmentInfo& o1Seg = TPCSectorData::GetOut1Seg();
169     const TPCSectorData::SegmentInfo& o2Seg = TPCSectorData::GetOut2Seg();
170
171     if(flags.SecSelection()) {
172
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());
176
177     } else {
178
179       if(fSector->fUseTexture) {
180         //texture
181         glEnable(GL_BLEND);
182         glDepthMask(GL_FALSE);
183         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
184
185         glPolygonOffset(2,2);
186         glEnable(GL_POLYGON_OFFSET_FILL);
187
188         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
189         glBindTexture(GL_TEXTURE_2D, fTexture);
190         glEnable(GL_TEXTURE_2D);
191
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());
195
196         glDisable(GL_TEXTURE_2D);
197       } else {
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());
201       }
202       glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
203       DisplayFrame();
204     }
205
206   }
207
208   glPopAttrib();
209 }
210
211 /**************************************************************************/
212 // Data import
213 /**************************************************************************/
214
215 void TPCSector2DGL::LoadPadrow(TPCSectorData::RowIterator& iter,
216                                Int_t row, Int_t col_off) const
217 {
218   Int_t    padVal;
219   Int_t    time, val;   
220
221   Int_t    minTime = fSector->fMinTime;
222   Int_t    maxTime = fSector->fMaxTime;
223   Bool_t   halfBorderTime = ((maxTime - minTime) % 2 == 0);
224
225   UChar_t* img_pos = GetRowCol(row, col_off);
226   while (iter.NextPad()) {
227     padVal = 0; 
228
229     while (iter.Next()) {
230       time = iter.Time();
231       val  = iter.Signal();
232
233       if(time < minTime || time > maxTime)
234         continue;
235
236       if(fSector->fShowMax) {
237         if(val > padVal) {
238           padVal = val;
239         }
240       } else {
241         if(halfBorderTime && (time == minTime || time == maxTime))
242           padVal += val/2;
243         else
244           padVal += val;
245       }
246     }
247
248     if(fSector->fShowMax == kFALSE && fSector->fAverage) {
249       padVal = (Int_t)((Float_t)padVal / (maxTime - minTime));
250     }
251     padVal = TMath::Min(padVal, fSector->fMaxVal);
252     if(padVal > fSector->fThreshold)
253       fSector->ColorFromArray(padVal, img_pos);
254     img_pos += 4;
255   }
256 }
257
258 /**************************************************************************/
259
260 void TPCSector2DGL::CreateTexture() const
261 {
262   if (fImage == 0 ) {
263     fImage = new UChar_t[fgkTextureByteSize];
264     glGenTextures(1, &fTexture);
265   }
266   memset(fImage, 0, fgkTextureByteSize);
267
268   Int_t rowOff[3], colOff[3];
269   Bool_t isOn[3];
270   rowOff[0] = 0;
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;
277
278   fSector->SetupColorArray();
279
280   // Loop over 3 main segments
281   for (Int_t sId = 0; sId <= 2; ++sId) {
282     if(isOn[sId] == kFALSE)
283       continue;
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]);
289     }
290   }
291
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);
300
301 }
302
303 /**************************************************************************/
304 // Data display
305 /**************************************************************************/
306
307 void TPCSector2DGL::DisplayTexture(const TPCSectorData::SegmentInfo& seg,
308                                    Int_t startCol, Int_t startRow) const
309 {
310   Float_t w  = seg.GetNMaxPads()*seg.GetPadWidth()/2;
311   Float_t y1 = seg.GetRLow();
312   Float_t y2 = y1 + seg.GetNRows()*seg.GetPadHeight();
313
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;
318
319   glBegin(GL_QUADS);  
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);
324   glEnd();
325 }
326
327 /**************************************************************************/
328
329 void TPCSector2DGL::DisplayQuads(const TPCSectorData::SegmentInfo& seg,
330                                  Int_t startCol, Int_t startRow) const
331 {
332   Float_t y_d, y_u;
333   Float_t x_off, x;
334   Float_t padW = seg.GetPadWidth();
335   Float_t padH = seg.GetPadHeight();
336
337   glBegin(GL_QUADS);
338   for (Int_t row=0; row<seg.GetNRows(); row++) {
339     y_d = seg.GetRLow() + row*padH;
340     y_u = y_d + 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;
348       if (pix[3] != 0) {
349         glColor4ubv(pix);
350         glVertex2f(x+padW, y_d);
351         glVertex2f(x,      y_d);
352         glVertex2f(x,      y_u);
353         glVertex2f(x+padW, y_u);
354       }
355     }
356   }
357   glEnd();
358 }
359
360 void TPCSector2DGL::DisplayNamedQuads(const TPCSectorData::SegmentInfo& seg,
361                                       Int_t startCol, Int_t startRow) const
362 {
363   Float_t y_d, y_u;
364   Float_t x_off, x;
365   Float_t padW = seg.GetPadWidth();
366   Float_t padH = seg.GetPadHeight();
367
368   glPushName(0);
369   for (Int_t row=0; row<seg.GetNRows(); row++) {
370     y_d = seg.GetRLow() + row*padH;
371     y_u = y_d + padH;
372     x_off = -seg.GetNMaxPads()*padW/2;
373     Int_t tpcRow = row + seg.GetFirstRow();
374     glLoadName(tpcRow);
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);
378     glPushName(0);
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);
383         glBegin(GL_QUADS);
384         glVertex2f(x+padW, y_d);
385         glVertex2f(x,      y_d);
386         glVertex2f(x,      y_u);
387         glVertex2f(x+padW, y_u);
388         glEnd();
389       }
390     }
391     glPopName();
392   }
393   glPopName();
394 }
395
396 /**************************************************************************/
397 // Frame drawing
398 /**************************************************************************/
399
400 void TPCSector2DGL::TraceStepsUp(const TPCSectorData::SegmentInfo& s)
401 {
402   Float_t x = -(s.GetNMaxPads()*1.0/2 - s.GetNYSteps())*s.GetPadWidth();
403   Float_t y  = s.GetRLow();
404   glVertex2f(x, y);
405   for (Int_t i=0; i<s.GetNYSteps(); ++i) {
406     y = s.GetYStep(i);
407     glVertex2f(x, y);
408     x -= s.GetPadWidth();
409     glVertex2f(x, y);
410   }
411   y =  s.GetRLow() + s.GetNRows()*s.GetPadHeight();
412   glVertex2f(-s.GetNMaxPads()*s.GetPadWidth()/2, y);
413 }
414
415 void TPCSector2DGL::TraceStepsDown(const TPCSectorData::SegmentInfo& s) 
416 {
417   Float_t x = s.GetNMaxPads()*s.GetPadWidth()/2;
418   Float_t y = s.GetRLow() + s.GetNRows()*s.GetPadHeight();
419   glVertex2f(x, y);
420   for (Int_t i=s.GetNYSteps() - 1; i>=0; --i) {
421     y =  s.GetYStep(i);
422     glVertex2f(x, y);
423     x -= s.GetPadWidth();
424     glVertex2f(x, y);
425   }
426   y = s.GetRLow();
427   glVertex2f((0.5*s.GetNMaxPads() - s.GetNYSteps())*s.GetPadWidth(), y);
428 }
429
430 void TPCSector2DGL::DisplayFrame() const
431 {
432   UChar_t col[4];
433   ColorFromIdx(fSector->fFrameColor, col);
434   glColor4ubv(col);
435
436   if(fSector->fRnrInn) {
437     glBegin(GL_POLYGON);
438     TraceStepsUp  (TPCSectorData::GetInnSeg());
439     TraceStepsDown(TPCSectorData::GetInnSeg());
440     glEnd();
441   }
442   if(fSector->fRnrOut1) {
443     glBegin(GL_POLYGON);
444     TraceStepsUp  (TPCSectorData::GetOut1Seg());
445     TraceStepsDown(TPCSectorData::GetOut1Seg());
446     glEnd();
447   }
448   if(fSector->fRnrOut2) {
449     glBegin(GL_POLYGON);
450     TraceStepsUp  (TPCSectorData::GetOut2Seg());
451     TraceStepsDown(TPCSectorData::GetOut2Seg());
452     glEnd();
453   }
454 }