source: trunk/MagicSoft/Mars/mgui/MCamDisplay.cc@ 2153

Last change on this file since 2153 was 2153, checked in by tbretz, 23 years ago
*** empty log message ***
File size: 20.4 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of MARS, the MAGIC Analysis and Reconstruction
5! * Software. It is distributed to you in the hope that it can be a useful
6! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
7! * It is distributed WITHOUT ANY WARRANTY.
8! *
9! * Permission to use, copy, modify and distribute this software and its
10! * documentation for any purpose is hereby granted without fee,
11! * provided that the above copyright notice appear in all copies and
12! * that both that copyright notice and this permission notice appear
13! * in supporting documentation. It is provided "as is" without express
14! * or implied warranty.
15! *
16!
17!
18! Author(s): Thomas Bretz, 05/2002 <mailto:tbretz@astro.uni-wuerzburg.de>
19! Author(s): Harald Kornmayer, 1/2001
20!
21! Copyright: MAGIC Software Development, 2000-2003
22!
23!
24\* ======================================================================== */
25
26/////////////////////////////////////////////////////////////////////////////
27//
28// MCamDisplay
29//
30// Camera Display. The Pixels are displayed in
31// contents/area [somthing/mm^2]
32//
33// To change the scale to a logarithmic scale SetLogz() of the Pad.
34//
35//
36////////////////////////////////////////////////////////////////////////////
37#include "MCamDisplay.h"
38
39#include <fstream.h>
40#include <iostream.h>
41
42#include <TBox.h>
43#include <TArrow.h>
44#include <TLatex.h>
45#include <TStyle.h>
46#include <TMarker.h>
47#include <TCanvas.h>
48#include <TArrayF.h>
49#include <TClonesArray.h>
50
51#include "MH.h"
52#include "MHexagon.h"
53
54#include "MGeomCam.h"
55
56#include "MRflEvtData.h"
57
58#include "MCerPhotPix.h"
59#include "MCerPhotEvt.h"
60
61#include "MPedestalPix.h"
62#include "MPedestalCam.h"
63
64#include "MCurrents.h"
65
66#include "MImgCleanStd.h"
67
68#define kItemsLegend 50 // see SetPalette(1,0)
69
70ClassImp(MCamDisplay);
71
72// ------------------------------------------------------------------------
73//
74// Default Constructor. To be used by the root system ONLY.
75//
76MCamDisplay::MCamDisplay()
77 : fGeomCam(NULL), fAutoScale(kTRUE)
78{
79 fNumPixels = 0;
80 fRange = 0;
81
82 fPixels = NULL;
83 fLegend = NULL;
84 fLegText = NULL;
85 fArrowX = NULL;
86 fArrowY = NULL;
87 fLegRadius = NULL;
88 fLegDegree = NULL;
89
90 fMinimum = 0;
91 fMaximum = 1;
92
93 //fData.Set(0);
94}
95
96// ------------------------------------------------------------------------
97//
98// Constructor. Makes a clone of MGeomCam.
99//
100MCamDisplay::MCamDisplay(MGeomCam *geom)
101 : fGeomCam(NULL), fAutoScale(kTRUE), fData(geom->GetNumPixels()), fMinimum(0), fMaximum(1)
102{
103 fGeomCam = (MGeomCam*)geom->Clone();
104
105 //
106 // create the hexagons of the display
107 //
108 fNumPixels = fGeomCam->GetNumPixels();
109 fRange = fGeomCam->GetMaxRadius();
110
111 // root 3.02
112 // * base/inc/TObject.h:
113 // register BIT(8) as kNoContextMenu. If an object has this bit set it will
114 // not get an automatic context menu when clicked with the right mouse button.
115
116 fPhotons = new TClonesArray("TMarker", 0);
117
118 //
119 // Construct all hexagons. Use new-operator with placement
120 //
121 fPixels = new TClonesArray("MHexagon", fNumPixels);
122 for (UInt_t i=0; i<fNumPixels; i++)
123 {
124 MHexagon &pix = *new ((*fPixels)[i]) MHexagon((*fGeomCam)[i]);
125#if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06)
126 pix.SetBit(/*kNoContextMenu|*/kCannotPick);
127#endif
128 pix.SetFillColor(16);
129 pix.ResetBit(kIsUsed);
130 }
131
132 //
133 // set up the Legend
134 //
135 const Float_t H = 0.9*fRange;
136 const Float_t h = 2./kItemsLegend;
137
138 const Float_t w = fRange/sqrt(fNumPixels);
139
140 fLegend = new TClonesArray("TBox", kItemsLegend);
141 fLegText = new TClonesArray("TText", kItemsLegend);
142
143 for (Int_t i = 0; i<kItemsLegend; i++)
144 {
145 TBox &newbox = *new ((*fLegend)[i]) TBox;
146 TText &newtxt = *new ((*fLegText)[i]) TText;
147
148 newbox.SetX1(fRange);
149 newbox.SetX2(fRange+w);
150 newbox.SetY1(H*( i *h - 1.));
151 newbox.SetY2(H*((i+1)*h - 1.));
152 newbox.SetFillColor(16);
153#if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06)
154 newbox.SetBit(/*kNoContextMenu|*/kCannotPick);
155#endif
156
157 newtxt.SetTextSize(0.025);
158 newtxt.SetTextAlign(12);
159 newtxt.SetX(fRange+1.5*w);
160 newtxt.SetY(H*((i+0.5)*h - 1.));
161#if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06)
162 newtxt.SetBit(/*kNoContextMenu|*/kCannotPick);
163#endif
164 }
165
166 fArrowX = new TArrow(-fRange*.9, -fRange*.9, -fRange*.6, -fRange*.9, 0.025);
167 fArrowY = new TArrow(-fRange*.9, -fRange*.9, -fRange*.9, -fRange*.6, 0.025);
168
169 TString text;
170 text += (int)(fRange*.3);
171 text += "mm";
172
173 fLegRadius = new TText(-fRange*.85, -fRange*.85, text);
174 text = "";
175 text += (float)((int)(fRange*.3*fGeomCam->GetConvMm2Deg()*10))/10;
176 text += "\\circ";
177 text = text.Strip(TString::kLeading);
178 fLegDegree = new TLatex(-fRange*.85, -fRange*.75, text);
179 fLegRadius->SetTextSize(0.04);
180 fLegDegree->SetTextSize(0.04);
181
182#if ROOT_VERSION_CODE < ROOT_VERSION(3,01,06)
183 SetPalette(1, 0);
184#else
185 SetPalette(51, 0);
186#endif
187}
188
189// ------------------------------------------------------------------------
190//
191// Destructor. Deletes TClonesArrays for hexagons and legend elements.
192//
193MCamDisplay::~MCamDisplay()
194{
195 fPixels->Delete();
196 fLegend->Delete();
197 fLegText->Delete();
198 fPhotons->Delete();
199
200 delete fPixels;
201 delete fLegend;
202 delete fLegText;
203 delete fPhotons;
204
205 delete fArrowX;
206 delete fArrowY;
207
208 delete fLegRadius;
209 delete fLegDegree;
210
211 delete fGeomCam;
212}
213
214// ------------------------------------------------------------------------
215//
216// Call this function to draw the camera layout into your canvas.
217// Setup a drawing canvas. Add this object and all child objects
218// (hexagons, etc) to the current pad. If no pad exists a new one is
219// created.
220//
221void MCamDisplay::Draw(Option_t *option)
222{
223 // root 3.02:
224 // gPad->SetFixedAspectRatio()
225
226 TVirtualPad *pad = gPad ? gPad : MH::MakeDefCanvas("CamDisplay", "Mars Camera Display", 656, 600);
227 pad->SetBorderMode(0);
228 pad->SetFillColor(16);
229
230 AppendPad("");
231}
232
233
234void MCamDisplay::SetRange()
235{
236 //
237 // Maintain aspect ratio
238 //
239 const float ratio = 1.15;
240
241 const float w = gPad->GetWw();
242 const float h = gPad->GetWh()*ratio;
243
244 gPad->Range(-fRange, -fRange, (2*ratio-1)*fRange, fRange);
245
246 if (h<w)
247 gPad->SetPad((1.-h/w)/2, 0, (h/w+1)/2, 0.9999999);
248 else
249 gPad->SetPad(0, (1.-w/h)/2, 1, (w/h+1)/2);
250}
251
252void MCamDisplay::Update(Bool_t islog)
253{
254 // FIXME: Don't do this if nothing changed!
255 if (fAutoScale)
256 {
257 fMinimum = FLT_MAX;
258 fMaximum = -FLT_MAX;
259
260 for (UInt_t i=0; i<fNumPixels; i++)
261 {
262 if (!(*this)[i].TestBit(kIsUsed))
263 continue;
264
265 if (fData[i]<fMinimum)
266 fMinimum = fData[i];
267 if (fData[i]>fMaximum)
268 fMaximum = fData[i];
269 }
270 }
271
272 if (fMinimum==fMaximum)
273 fMaximum = fMinimum + 1;
274
275 UpdateLegend(fMinimum, fMaximum, islog);
276
277 for (UInt_t i=0; i<fNumPixels; i++)
278 {
279 if ((*this)[i].TestBit(kIsUsed))
280 (*this)[i].SetFillColor(GetColor(fData[i], fMinimum, fMaximum, islog));
281 else
282 (*this)[i].SetFillColor(10);
283
284 }
285}
286
287// ------------------------------------------------------------------------
288//
289// This is called at any time the canvas should get repainted.
290// Here we maintain an aspect ratio of 1.15. This makes sure,
291// that the camera image doesn't get distorted by resizing the canvas.
292//
293void MCamDisplay::Paint(Option_t *opt)
294{
295 if (!fPixels)
296 return;
297
298 // Maintain aspect ratio
299 SetRange();
300
301 // Maintain colors
302 SetPalette();
303
304 // Update Contents of the pixels
305 Update(gPad->GetLogz());
306
307 // Paint Legend
308 fArrowX->Paint(">");
309 fArrowY->Paint(">");
310
311 fLegRadius->Paint();
312 fLegDegree->Paint();
313
314 // Paint primitives (pixels, color legend, photons, ...)
315 { fPixels->ForEach(TObject, Paint)(); }
316 { fLegend->ForEach(TObject, Paint)(); }
317 { fLegText->ForEach(TObject, Paint)(); }
318 { fPhotons->ForEach(TObject, Paint)(); }
319}
320
321// ------------------------------------------------------------------------
322//
323// With this function you can change the color palette. For more
324// information see TStyle::SetPalette. Only palettes with 50 colors
325// are allowed.
326// In addition you can use SetPalette(52, 0) to create an inverse
327// deep blue sea palette
328//
329void MCamDisplay::SetPalette(Int_t ncolors, Int_t *colors)
330{
331 //
332 // If not enough colors are specified skip this.
333 //
334 if (ncolors>1 && ncolors<50)
335 {
336 cout << "MCamDisplay::SetPalette: Only default palettes with 50 colors are allowed... ignored." << endl;
337 return;
338 }
339
340 //
341 // If ncolors==52 create a reversed deep blue sea palette
342 //
343 if (ncolors==52)
344 {
345 gStyle->SetPalette(51, NULL);
346 Int_t c[50];
347 for (int i=0; i<50; i++)
348 c[49-i] = gStyle->GetColorPalette(i);
349 gStyle->SetPalette(50, c);
350 }
351 else
352 gStyle->SetPalette(ncolors, colors);
353
354 //
355 // Change the colors of the pixels
356 //
357 for (unsigned int i=0; i<fNumPixels; i++)
358 {
359 //
360 // Get the old color index and check whether it is
361 // background or transparent
362 //
363 Int_t col = (*this)[i].GetFillColor();
364 if (col==10 || col==16)
365 continue;
366
367 //
368 // Search for the color index (level) in the color table
369 //
370 int idx;
371 for (idx=0; idx<kItemsLegend; idx++)
372 if (col==fColors[idx])
373 break;
374
375 //
376 // Should not happen
377 //
378 if (idx==kItemsLegend)
379 {
380 cout << "MCamDisplay::SetPalette: Strange... FIXME!" << endl;
381 continue;
382 }
383
384 //
385 // Convert the old color index (level) into the new one
386 //
387 (*this)[i].SetFillColor(gStyle->GetColorPalette(idx));
388 }
389
390 //
391 // Store the color palette used for a leter reverse lookup
392 //
393 for (int i=0; i<kItemsLegend; i++)
394 {
395 fColors[i] = gStyle->GetColorPalette(i);
396 GetBox(i)->SetFillColor(fColors[i]);
397 }
398}
399
400void MCamDisplay::SetPrettyPalette()
401{
402 SetPalette(1, 0);
403}
404
405void MCamDisplay::SetDeepBlueSeaPalette()
406{
407 SetPalette(51, 0);
408}
409
410void MCamDisplay::SetInvDeepBlueSeaPalette()
411{
412 SetPalette(52, 0);
413}
414
415void MCamDisplay::SetPalette()
416{
417 for (int i=0; i<kItemsLegend; i++)
418 GetBox(i)->SetFillColor(fColors[i]);
419}
420
421void MCamDisplay::DrawPixelNumbers()
422{
423 for (int i=0; i<kItemsLegend; i++)
424 fColors[i] = 16;
425
426 if (!gPad)
427 Draw();
428
429 TText txt;
430 txt.SetTextFont(122);
431 txt.SetTextAlign(22); // centered/centered
432
433 for (UInt_t i=0; i<fNumPixels; i++)
434 {
435 TString num;
436 num += i;
437
438 const MHexagon &h = (*this)[i];
439 TText *nt = txt.DrawText(h.GetX(), h.GetY(), num);
440 nt->SetTextSize(0.3*h.GetD()/fGeomCam->GetMaxRadius());
441 }
442}
443
444// ------------------------------------------------------------------------
445//
446// Call this function to fill the number of photo electron into the
447// camera.
448//
449void MCamDisplay::FillPhotNum(const MCerPhotEvt &event)
450{
451 Reset();
452
453 const Int_t entries = event.GetNumPixels();
454
455 for (Int_t i=0; i<entries; i++)
456 {
457 const MCerPhotPix &pix = event[i];
458 if (!pix.IsPixelUsed())
459 continue;
460
461 const Int_t id = pix.GetPixId();
462
463 fData[id] = pix.GetNumPhotons()*fGeomCam->GetPixRatio(id);
464 (*this)[id].SetBit(kIsUsed);
465 }
466}
467
468// ------------------------------------------------------------------------
469//
470// Call this function to fill the number of photo electron into the
471// camera.
472//
473void MCamDisplay::FillPedestals(const MPedestalCam &event)
474{
475 Reset();
476
477 const Int_t entries = event.GetSize();
478 for (Int_t i=0; i<entries; i++)
479 {
480 fData[i] = event[i].GetMean()*fGeomCam->GetPixRatio(i);
481 (*this)[i].SetBit(kIsUsed);
482 }
483}
484
485// ------------------------------------------------------------------------
486//
487// Call this function to fill the error of number of photo electron
488// into the camera.
489//
490void MCamDisplay::FillErrorPhot(const MCerPhotEvt &event)
491{
492 Reset();
493
494 const Int_t entries = event.GetNumPixels();
495
496 for (Int_t i=0; i<entries; i++)
497 {
498 const MCerPhotPix &pix = event[i];
499 if (!pix.IsPixelUsed())
500 continue;
501
502 const Int_t id = pix.GetPixId();
503
504 fData[id] = pix.GetErrorPhot()*sqrt(fGeomCam->GetPixRatio(id));
505 (*this)[id].SetBit(kIsUsed);
506 }
507}
508
509// ------------------------------------------------------------------------
510//
511// Call this function to fill the ratio of the number of photons
512// divided by its error
513//
514void MCamDisplay::FillRatio(const MCerPhotEvt &event)
515{
516 Reset();
517
518 const Int_t entries = event.GetNumPixels();
519
520 for (Int_t i=0; i<entries; i++)
521 {
522 const MCerPhotPix &pix = event[i];
523
524 if (!pix.IsPixelUsed())
525 continue;
526
527 const Int_t id = pix.GetPixId();
528
529 const Float_t entry = pix.GetNumPhotons();
530 const Float_t noise = pix.GetErrorPhot();
531 const Double_t ratio = TMath::Sqrt(fGeomCam->GetPixRatio(id));
532
533 fData[id] = entry*ratio/noise;
534 (*this)[id].SetBit(kIsUsed);
535 }
536}
537
538// ------------------------------------------------------------------------
539//
540// Call this function to fill the currents
541//
542void MCamDisplay::FillCurrents(const MCurrents &event)
543{
544 Reset();
545
546 // FIXME: Security check missing!
547 for (UInt_t i=0; i<fNumPixels; i++)
548 {
549 if (event[i]<=0)
550 continue;
551
552 (*this)[i].SetBit(kIsUsed);
553 fData[i] = event[i];
554 }
555}
556
557// ------------------------------------------------------------------------
558//
559// Fill the colors in respect to the cleaning levels
560//
561void MCamDisplay::FillLevels(const MCerPhotEvt &event, Float_t lvl1, Float_t lvl2)
562{
563 FillRatio(event);
564
565 for (UInt_t i=0; i<fNumPixels; i++)
566 {
567 if (!(*this)[i].TestBit(kIsUsed))
568 continue;
569
570 if (fData[i]>lvl1)
571 fData[i] = 0;
572 else
573 if (fData[i]>lvl2)
574 fData[i] = 1;
575 else
576 fData[i] = 2;
577 }
578}
579
580// ------------------------------------------------------------------------
581//
582// Fill the colors in respect to the cleaning levels
583//
584void MCamDisplay::FillLevels(const MCerPhotEvt &event, const MImgCleanStd &clean)
585{
586 FillLevels(event, clean.GetCleanLvl1(), clean.GetCleanLvl2());
587}
588
589// ------------------------------------------------------------------------
590//
591// Show a reflector event. EMarkerStyle is defined in root/include/Gtypes.h
592// To remove the photons from the display call FillRflEvent(NULL)
593//
594void MCamDisplay::ShowRflEvent(const MRflEvtData *event, EMarkerStyle ms)
595{
596 const Int_t num = event ? event->GetNumPhotons() : 0;
597
598 fPhotons->ExpandCreate(num);
599 if (num < 1)
600 return;
601
602 Int_t i=num-1;
603 do
604 {
605 const MRflSinglePhoton &ph = event->GetPhoton(i);
606 TMarker &m = (TMarker&)*fPhotons->UncheckedAt(i);
607 m.SetX(ph.GetX());
608 m.SetY(ph.GetY());
609 m.SetMarkerStyle(ms);
610 } while (i--);
611}
612
613// ------------------------------------------------------------------------
614//
615// Fill a reflector event. Sums all pixels in each pixel as the
616// pixel contents.
617//
618// WARNING: Due to the estimation in DistanceToPrimitive and the
619// calculation in pixels instead of x, y this is only a
620// rough estimate.
621//
622void MCamDisplay::FillRflEvent(const MRflEvtData &event)
623{
624 //
625 // reset pixel colors to background color
626 //
627 Reset();
628
629 //
630 // sum the photons content in each pixel
631 //
632 const Int_t entries = event.GetNumPhotons();
633
634 for (Int_t i=0; i<entries; i++)
635 {
636 const MRflSinglePhoton &ph = event.GetPhoton(i);
637
638 UInt_t id;
639 for (id=0; id<fNumPixels; id++)
640 {
641 if ((*this)[id].DistanceToPrimitive(ph.GetX(), ph.GetY())<0)
642 break;
643 }
644 if (id==fNumPixels)
645 continue;
646
647 fData[id] += fGeomCam->GetPixRatio(id);
648 }
649
650 //
651 // Set color of pixels
652 //
653 for (UInt_t id=0; id<fNumPixels; id++)
654 if (fData[id]>0)
655 (*this)[id].SetBit(kIsUsed);
656}
657
658// ------------------------------------------------------------------------
659//
660// Reset the all pixel colors to a default value
661//
662void MCamDisplay::Reset()
663{
664 for (UInt_t i=0; i<fNumPixels; i++)
665 (*this)[i].ResetBit(kIsUsed);
666
667 if (fAutoScale)
668 {
669 fMinimum = 0;
670 fMaximum = 0;
671 }
672}
673
674// ------------------------------------------------------------------------
675//
676// Here we calculate the color index for the current value.
677// The color index is defined with the class TStyle and the
678// Color palette inside. We use the command gStyle->SetPalette(1,0)
679// for the display. So we have to convert the value "wert" into
680// a color index that fits the color palette.
681// The range of the color palette is defined by the values fMinPhe
682// and fMaxRange. Between this values we have 50 color index, starting
683// with 0 up to 49.
684//
685Int_t MCamDisplay::GetColor(Float_t val, Float_t min, Float_t max, Bool_t islog)
686{
687 //
688 // first treat the over- and under-flows
689 //
690 const Int_t maxcolidx = kItemsLegend-1;
691
692 if (val >= max)
693 return fColors[maxcolidx];
694
695 if (val <= min)
696 return fColors[0];
697
698 //
699 // calculate the color index
700 //
701 Float_t ratio;
702 if (islog && min>0)
703 ratio = log10(val/min) / log10(max/min);
704 else
705 ratio = (val-min) / (max-min);
706 const Int_t colidx = (Int_t)(ratio*maxcolidx + .5);
707 return fColors[colidx];
708}
709
710// ------------------------------------------------------------------------
711//
712// Change the text on the legend according to the range of the Display
713//
714void MCamDisplay::UpdateLegend(Float_t minphe, Float_t maxphe, Bool_t islog)
715{
716 for (Int_t i=0; i<kItemsLegend; i+=3)
717 {
718 const Float_t pos = (Float_t)i/kItemsLegend;
719
720 Float_t val;
721 if (islog && minphe>0)
722 val = pow(10, log10(maxphe/minphe)*pos) * minphe;
723 else
724 val = minphe + pos * (maxphe-minphe);
725
726 TText &txt = *GetText(i);
727 txt.SetText(txt.GetX(), txt.GetY(), Form(val<1e6?"%5.1f":"%5.1e", val));
728 }
729}
730
731// ------------------------------------------------------------------------
732//
733// Save primitive as a C++ statement(s) on output stream out
734//
735void MCamDisplay::SavePrimitive(ofstream &out, Option_t *opt)
736{
737 cout << "MCamDisplay::SavePrimitive: Must be rewritten!" << endl;
738 /*
739 if (!gROOT->ClassSaved(TCanvas::Class()))
740 fDrawingPad->SavePrimitive(out, opt);
741
742 out << " " << fDrawingPad->GetName() << "->SetWindowSize(";
743 out << fDrawingPad->GetWw() << "," << fDrawingPad->GetWh() << ");" << endl;
744 */
745}
746
747// ------------------------------------------------------------------------
748//
749// compute the distance of a point (px,py) to the Camera
750// this functions needed for graphical primitives, that
751// means without this function you are not able to interact
752// with the graphical primitive with the mouse!!!
753//
754// All calcutations are running in pixel coordinates
755//
756Int_t MCamDisplay::DistancetoPrimitive(Int_t px, Int_t py)
757{
758 Int_t dist = 999999;
759
760 for (UInt_t i=0; i<fNumPixels; i++)
761 {
762 Int_t d = (*fPixels)[i]->DistancetoPrimitive(px, py);
763
764 if (d<dist)
765 dist=d;
766 }
767 return dist==0?0:999999;
768}
769
770// ------------------------------------------------------------------------
771//
772// Execute a mouse event on the camera
773//
774/*
775 void MCamDisplay::ExecuteEvent(Int_t event, Int_t px, Int_t py)
776 {
777 cout << "Execute Event Camera " << event << " @ " << px << " " << py << endl;
778 }
779 */
780
781
782// ------------------------------------------------------------------------
783//
784// Function introduced (31-01-03) WILL BE REMOVED IN THE FUTURE! DON'T
785// USE IT!
786//
787void MCamDisplay::SetPix(const Int_t pixnum, const Int_t color, Float_t min, Float_t max)
788{
789 fData[pixnum] = color;
790 (*this)[pixnum].SetBit(kIsUsed);
791 (*this)[pixnum].SetFillColor(GetColor(color, min, max, 0));
792}
793
794// ------------------------------------------------------------------------
795//
796// Returns string containing info about the object at position (px,py).
797// Returned string will be re-used (lock in MT environment).
798//
799char *MCamDisplay::GetObjectInfo(Int_t px, Int_t py) const
800{
801 static char info[64];
802
803 UInt_t i;
804 for (i=0; i<fNumPixels; i++)
805 {
806 if ((*fPixels)[i]->DistancetoPrimitive(px, py)>0)
807 continue;
808
809 sprintf(info, "Pixel Id: %d", i);
810 return info;
811 }
812 return TObject::GetObjectInfo(px, py);
813}
Note: See TracBrowser for help on using the repository browser.