source: trunk/MagicSoft/Mars/mhist/MHCamera.cc@ 2222

Last change on this file since 2222 was 2222, checked in by tbretz, 21 years ago
*** empty log message ***
File size: 26.7 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// MHCamera
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 "MHCamera.h"
38
39#include <fstream>
40#include <iostream>
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 <TRandom.h>
50#include <TPaveText.h>
51#include <TClonesArray.h>
52
53#include "MH.h"
54#include "MHexagon.h"
55
56#include "MGeomPix.h"
57#include "MGeomCam.h"
58
59#include "MRflEvtData.h"
60#include "MRflSinglePhoton.h"
61
62#include "MCerPhotPix.h"
63#include "MCerPhotEvt.h"
64
65#include "MPedestalPix.h"
66#include "MPedestalCam.h"
67
68#include "MCurrents.h"
69#include "MCamEvent.h"
70
71#include "MImgCleanStd.h"
72
73#define kItemsLegend 48 // see SetPalette(1,0)
74
75ClassImp(MHCamera);
76
77using namespace std;
78
79// ------------------------------------------------------------------------
80//
81// Default Constructor. To be used by the root system ONLY.
82//
83MHCamera::MHCamera() : TH1D(), fGeomCam(NULL), fColors(kItemsLegend)
84{
85 SetDirectory(NULL);
86
87 fPhotons = NULL;
88 fNotify = NULL;
89
90#if ROOT_VERSION_CODE < ROOT_VERSION(3,01,06)
91 SetPalette(1, 0);
92#else
93 SetPalette(51, 0);
94#endif
95}
96
97// ------------------------------------------------------------------------
98//
99// Constructor. Makes a clone of MGeomCam.
100//
101MHCamera::MHCamera(const MGeomCam &geom, const char *name, const char *title)
102: TH1D(name, title, geom.GetNumPixels(), -0.5, geom.GetNumPixels()-0.5),
103fUsed(geom.GetNumPixels()), fColors(kItemsLegend)
104{
105 fGeomCam = (MGeomCam*)geom.Clone();
106
107 SetDirectory(NULL);
108 Sumw2();
109
110 SetLineColor(kGreen);
111 SetMarkerStyle(kFullDotMedium);
112 SetXTitle("Pixel Index");
113
114 fNotify = new TList;
115
116 //
117 // create the hexagons of the display
118 //
119 // root 3.02
120 // * base/inc/TObject.h:
121 // register BIT(8) as kNoContextMenu. If an object has this bit set it will
122 // not get an automatic context menu when clicked with the right mouse button.
123
124 fPhotons = new TClonesArray("TMarker", 0);
125
126 //
127 // Construct all hexagons. Use new-operator with placement
128 //
129 for (Int_t i=0; i<fNcells-2; i++)
130 ResetUsed(i);
131
132#if ROOT_VERSION_CODE < ROOT_VERSION(3,01,06)
133 SetPalette(1, 0);
134#else
135 SetPalette(51, 0);
136#endif
137}
138
139// ------------------------------------------------------------------------
140//
141// Destructor. Deletes TClonesArrays for hexagons and legend elements.
142//
143MHCamera::~MHCamera()
144{
145 if (fPhotons)
146 {
147 fPhotons->Delete();
148 delete fPhotons;
149 }
150 if (fGeomCam)
151 delete fGeomCam;
152 if (fNotify)
153 delete fNotify;
154}
155
156Int_t MHCamera::Fill(Axis_t x)
157{
158// -*-*-*-*-*-*-*-*Increment bin with abscissa X by 1*-*-*-*-*-*-*-*-*-*-*
159// ==================================
160//
161// if x is less than the low-edge of the first bin, the Underflow bin is incremented
162// if x is greater than the upper edge of last bin, the Overflow bin is incremented
163//
164// If the storage of the sum of squares of weights has been triggered,
165// via the function Sumw2, then the sum of the squares of weights is incremented
166// by 1 in the bin corresponding to x.
167//
168// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
169
170#if ROOT_VERSION_CODE > ROOT_VERSION(3,05,00)
171 if (fBuffer) return BufferFill(x,1);
172#endif
173 const Int_t bin = (Int_t)x+1;
174 AddBinContent(bin);
175 if (fSumw2.fN)
176 fSumw2.fArray[bin]++;
177
178 if (bin<=0 || bin>fNcells-2)
179 return -1;
180
181 fTsumw++;
182 fTsumw2++;
183 fTsumwx += x;
184 fTsumwx2 += x*x;
185 return bin;
186}
187
188//______________________________________________________________________________
189Int_t MHCamera::Fill(Axis_t x, Stat_t w)
190{
191// -*-*-*-*-*-*Increment bin with abscissa X with a weight w*-*-*-*-*-*-*-*
192// =============================================
193//
194// if x is less than the low-edge of the first bin, the Underflow bin is incremented
195// if x is greater than the upper edge of last bin, the Overflow bin is incremented
196//
197// If the storage of the sum of squares of weights has been triggered,
198// via the function Sumw2, then the sum of the squares of weights is incremented
199// by w^2 in the bin corresponding to x.
200//
201// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
202
203#if ROOT_VERSION_CODE > ROOT_VERSION(3,05,00)
204 if (fBuffer) return BufferFill(x,w);
205#endif
206 const Int_t bin = (Int_t)x+1;
207 AddBinContent(bin, w);
208 if (fSumw2.fN)
209 fSumw2.fArray[bin] += w*w;
210
211 if (bin<=0 || bin>fNcells-2)
212 return -1;
213
214 const Stat_t z = (w > 0 ? w : -w);
215 fTsumw += z;
216 fTsumw2 += z*z;
217 fTsumwx += z*x;
218 fTsumwx2 += z*x*x;
219 return bin;
220}
221
222// ------------------------------------------------------------------------
223//
224// Return the minimum contents of all pixels (if all is set, otherwise
225// only of all 'used' pixels), fMinimum if fMinimum set
226//
227Double_t MHCamera::GetMinimum(Bool_t all) const
228{
229 if (fMinimum != -1111)
230 return fMinimum;
231
232 Double_t minimum=FLT_MAX;
233
234 if (all)
235 {
236 for (Int_t idx=0; idx<fNcells-2; idx++)
237 if (fArray[idx+1] < minimum)
238 minimum = fArray[idx+1];
239 }
240 else
241 {
242 for (Int_t idx=0; idx<fNcells-2; idx++)
243 if (IsUsed(idx) && fArray[idx+1] < minimum)
244 minimum = fArray[idx+1];
245 }
246 return minimum;
247}
248
249// ------------------------------------------------------------------------
250//
251// Return the maximum contents of all pixels (if all is set, otherwise
252// only of all 'used' pixels), fMaximum if fMaximum set
253//
254Double_t MHCamera::GetMaximum(Bool_t all) const
255{
256 if (fMaximum != -1111)
257 return fMaximum;
258
259 Double_t maximum=-FLT_MAX;
260 if (all)
261 {
262 for (Int_t idx=0; idx<fNcells-2; idx++)
263 if (fArray[idx+1] > maximum)
264 maximum = fArray[idx+1];
265 }
266 else
267 {
268 for (Int_t idx=0; idx<fNcells-2; idx++)
269 if (IsUsed(idx) && fArray[idx+1] > maximum)
270 maximum = fArray[idx+1];
271 }
272 return maximum;
273}
274
275// ------------------------------------------------------------------------
276//
277// Call this function to draw the camera layout into your canvas.
278// Setup a drawing canvas. Add this object and all child objects
279// (hexagons, etc) to the current pad. If no pad exists a new one is
280// created.
281//
282// To draw a camera into its own pad do something like:
283//
284// TCanvas *c = new TCanvas;
285// c->Divide(2,1);
286// MGeomCamMagic m;
287// MHCamera *d=new MHCamera(&m);
288// d->FillRandom();
289// c->cd(1);
290// gPad->SetBorderMode(0);
291// gPad->Divide(1,1);
292// gPad->cd(1);
293// d->Draw();
294// d->SetBit(kCanDelete);
295//
296void MHCamera::Draw(Option_t *option)
297{
298 // root 3.02:
299 // gPad->SetFixedAspectRatio()
300 Int_t col = 16;
301
302 if (gPad)
303 col = gPad->GetFillColor();
304
305 TVirtualPad *pad = gPad ? gPad : MH::MakeDefCanvas("CamDisplay", "Mars Camera Display", 656, 600);
306 pad->SetBorderMode(0);
307 pad->SetFillColor(col);
308
309 AppendPad(option);
310}
311
312
313void MHCamera::SetRange()
314{
315 const Float_t range = fGeomCam->GetMaxRadius();
316
317 //
318 // Maintain aspect ratio
319 //
320 const float ratio = 1.15;
321
322 //
323 // Calculate width and height of the current pad in pixels
324 //
325 Float_t w = gPad->GetWw();
326 Float_t h = gPad->GetWh()*ratio;
327
328 //
329 // This prevents the pad from resizing itself wrongly
330 //
331 if (gPad->GetMother() != gPad)
332 {
333 w *= gPad->GetMother()->GetAbsWNDC();
334 h *= gPad->GetMother()->GetAbsHNDC();
335 }
336
337 //
338 // Set Range (coordinate system) of pad
339 //
340 gPad->Range(-range, -range, (2*ratio-1)*range, range);
341
342 //
343 // Resize Pad to given ratio
344 //
345 if (h<w)
346 gPad->SetPad((1.-h/w)/2, 0, (h/w+1.)/2, 1);
347 else
348 gPad->SetPad(0, (1.-w/h)/2, 1, (w/h+1.)/2);
349}
350
351void MHCamera::Update(Bool_t islog, Bool_t isbox, Bool_t iscol)
352{
353 Double_t min = GetMinimum(kFALSE);
354 Double_t max = GetMaximum(kFALSE);
355 if (min==FLT_MAX)
356 {
357 min = 0;
358 max = 1;
359 }
360
361 UpdateLegend(min, max, islog);
362
363 MHexagon hex;
364 for (Int_t i=0; i<fNcells-2; i++)
365 {
366 if (IsUsed(i) && iscol)
367 hex.SetFillColor(GetColor(fArray[i+1], min, max, islog));
368 else
369 hex.SetFillColor(10);
370
371 MGeomPix &pix = (*fGeomCam)[i];
372 if (!isbox)
373 hex.PaintHexagon(pix.GetX(), pix.GetY(), pix.GetD());
374 else
375 if (IsUsed(i))
376 {
377 Float_t size = pix.GetD()*(fArray[i+1]-min)/(max-min);
378 if (size>pix.GetD())
379 size=pix.GetD();
380 hex.PaintHexagon(pix.GetX(), pix.GetY(), size);
381 }
382 }
383}
384
385void MHCamera::Print(Option_t *) const
386{
387 cout << "Minimum: " << GetMinimum();
388 if (fMinimum==-1111)
389 cout << " <autoscaled>";
390 cout << endl;
391 cout << "Maximum: " << GetMaximum();
392 if (fMaximum==-1111)
393 cout << " <autoscaled>";
394 cout << endl;
395}
396
397void MHCamera::PaintAxisTitle()
398{
399 Float_t fRange = fGeomCam->GetMaxRadius();
400
401 TLatex *ptitle = new TLatex(1.2*fRange, .97*fRange, GetYaxis()->GetTitle());
402
403 ptitle->SetTextSize(0.03);
404 ptitle->SetTextAlign(33);
405
406 // box with the histogram title
407 ptitle->SetTextColor(gStyle->GetTitleTextColor());
408#if ROOT_VERSION_CODE > ROOT_VERSION(3,05,00)
409 ptitle->SetTextFont(gStyle->GetTitleFont(""));
410#endif
411 ptitle->Paint();
412}
413
414void MHCamera::PaintTitle()
415{
416// *-*-*-*-*-*-*-*-*-*Draw the histogram title*-*-*-*-*-*-*-*-*-*-*-*-*
417// ========================
418 //if (Hoption.Same) return;
419#if ROOT_VERSION_CODE > ROOT_VERSION(3,05,00)
420 if (TestBit(kNoTitle))
421 return;
422#endif
423
424 const Int_t nt = strlen(GetTitle());
425
426 TPaveText *title = (TPaveText*)gPad->FindObject("title");
427 if (nt == 0 || gStyle->GetOptTitle() <= 0)
428 {
429 if (title)
430 delete title;
431 return;
432 }
433
434 Double_t ht = gStyle->GetTitleH();
435 Double_t wt = gStyle->GetTitleW();
436
437 if (ht <= 0)
438 ht = 0.05;
439 if (wt <= 0)
440 {
441 TLatex l;
442 l.SetTextSize(ht);
443 l.SetTitle(GetTitle());
444 Double_t wndc = l.GetXsize()/(gPad->GetX2() - gPad->GetX1());
445 wt = TMath::Min(0.7, 0.02+wndc);
446 }
447 if (title)
448 {
449 TText *t0 = (TText*)title->GetLine(0);
450 if (t0)
451 {
452 if (!strcmp(t0->GetTitle(), GetTitle()))
453 return;
454
455 t0->SetTitle(GetTitle());
456 if (wt > 0)
457 title->SetX2NDC(title->GetX1NDC()+wt);
458 }
459 return;
460 }
461
462 TPaveText *ptitle = new TPaveText(
463 gStyle->GetTitleX(),
464 gStyle->GetTitleY()-ht,
465 gStyle->GetTitleX()+wt,
466 gStyle->GetTitleY(),"blNDC");
467
468 // box with the histogram title
469#if ROOT_VERSION_CODE > ROOT_VERSION(3,05,00)
470 ptitle->SetFillColor(gStyle->GetTitleFillColor());
471 ptitle->SetTextFont(gStyle->GetTitleFont(""));
472 if (gStyle->GetTitleFont("")%10 > 2)
473 ptitle->SetTextSize(gStyle->GetTitleFontSize());
474#endif
475 ptitle->SetFillStyle(gStyle->GetTitleStyle());
476 ptitle->SetName("title");
477 ptitle->SetBorderSize(gStyle->GetTitleBorderSize());
478 ptitle->SetTextColor(gStyle->GetTitleTextColor());
479 ptitle->AddText(GetTitle());
480 ptitle->SetBit(kCanDelete);
481 ptitle->Draw();
482 ptitle->Paint();
483}
484
485// ------------------------------------------------------------------------
486//
487// This is called at any time the canvas should get repainted.
488// Here we maintain an aspect ratio of 1.15. This makes sure,
489// that the camera image doesn't get distorted by resizing the canvas.
490//
491void MHCamera::Paint(Option_t *o)
492{
493 const TString opt(o);
494
495 if (opt.Contains("hist", TString::kIgnoreCase))
496 {
497 Int_t mode = gStyle->GetOptStat();
498 TVirtualPad *save = gPad;
499 gPad=NULL;
500 gStyle->SetOptStat(1000011);
501 gPad=save;
502 TH1D::Paint(o);
503 gPad=NULL;
504 gStyle->SetOptStat(mode);
505 gPad=save;
506 return;
507 }
508
509 // Maintain aspect ratio
510 SetRange();
511
512 Bool_t isbox = opt.Contains("box", TString::kIgnoreCase);
513 Bool_t iscol = isbox ? !opt.Contains("nocol", TString::kIgnoreCase) : 1;
514
515 // Update Contents of the pixels and paint legend
516 Update(gPad->GetLogy(), isbox, iscol);
517
518 // Paint primitives (pixels, color legend, photons, ...)
519 { fPhotons->ForEach(TObject, Paint)(); }
520
521 PaintTitle();
522 PaintAxisTitle();
523}
524
525// ------------------------------------------------------------------------
526//
527// With this function you can change the color palette. For more
528// information see TStyle::SetPalette. Only palettes with 50 colors
529// are allowed.
530// In addition you can use SetPalette(52, 0) to create an inverse
531// deep blue sea palette
532//
533void MHCamera::SetPalette(Int_t ncolors, Int_t *colors)
534{
535 //
536 // If not enough colors are specified skip this.
537 //
538 if (ncolors>1 && ncolors<50)
539 {
540 cout << "MHCamera::SetPalette: Only default palettes with 50 colors are allowed... ignored." << endl;
541 return;
542 }
543
544 //
545 // If ncolors==52 create a reversed deep blue sea palette
546 //
547 if (ncolors==52)
548 {
549 gStyle->SetPalette(51, NULL);
550 TArrayI c(kItemsLegend);
551 for (int i=0; i<kItemsLegend; i++)
552 c[kItemsLegend-i-1] = gStyle->GetColorPalette(i);
553 gStyle->SetPalette(kItemsLegend, c.GetArray());
554 }
555 else
556 gStyle->SetPalette(ncolors, colors);
557
558 fColors.Set(kItemsLegend);
559 for (int i=0; i<kItemsLegend; i++)
560 fColors[i] = gStyle->GetColorPalette(i);
561}
562
563
564void MHCamera::SetPrettyPalette()
565{
566 if (!TString(GetDrawOption()).Contains("hist", TString::kIgnoreCase))
567 SetPalette(1, 0);
568}
569
570void MHCamera::SetDeepBlueSeaPalette()
571{
572 if (!TString(GetDrawOption()).Contains("hist", TString::kIgnoreCase))
573 SetPalette(51, 0);
574}
575
576void MHCamera::SetInvDeepBlueSeaPalette()
577{
578 if (!TString(GetDrawOption()).Contains("hist", TString::kIgnoreCase))
579 SetPalette(52, 0);
580}
581
582void MHCamera::DrawPixelNumbers()
583{
584 for (int i=0; i<kItemsLegend; i++)
585 fColors[i] = 16;
586
587 if (!gPad)
588 Draw();
589
590 TText txt;
591 txt.SetTextFont(122);
592 txt.SetTextAlign(22); // centered/centered
593
594 for (Int_t i=0; i<fNcells-2; i++)
595 {
596 TString num;
597 num += i;
598
599 const MGeomPix &h = (*fGeomCam)[i];
600 TText *nt = txt.DrawText(h.GetX(), h.GetY(), num);
601 nt->SetTextSize(0.3*h.GetD()/fGeomCam->GetMaxRadius());
602 }
603}
604
605// ------------------------------------------------------------------------
606//
607// Call this function to fill the currents
608//
609void MHCamera::AddCamContent(const MCamEvent &event, Int_t type)
610{
611 // FIXME: Security check missing!
612 for (Int_t idx=0; idx<fNcells-2; idx++)
613 {
614 Double_t val=0;
615 if (event.GetPixelContent(val, idx, *fGeomCam, type) && !IsUsed(idx))
616 SetUsed(idx);
617
618 Fill(idx, val); // FIXME: Slow!
619 //fArray[idx+1]+=val;
620 }
621 fEntries++;
622}
623
624// ------------------------------------------------------------------------
625//
626// Call this function to fill the currents
627//
628void MHCamera::AddCamContent(const MHCamera &d, Int_t type)
629{
630 if (fNcells!=d.fNcells)
631 return;
632
633 // FIXME: Security check missing!
634 for (Int_t idx=0; idx<fNcells-2; idx++)
635 if (d.IsUsed(idx))
636 SetUsed(idx);
637
638 switch (type)
639 {
640 case 1:
641 for (Int_t idx=0; idx<fNcells-2; idx++)
642 Fill(idx, d.GetBinError(idx+1));
643 break;
644 case 2:
645 for (Int_t idx=0; idx<fNcells-2; idx++)
646 if (d.GetBinContent(idx+1)!=0)
647 Fill(idx, fabs(d.GetBinError(idx+1)/d.GetBinContent(idx+1)));
648 break;
649 default:
650 for (Int_t idx=0; idx<fNcells-2; idx++)
651 Fill(idx, d.GetBinContent(idx+1));
652 break;
653 }
654 fEntries++;
655}
656
657// ------------------------------------------------------------------------
658//
659// Call this function to fill the currents
660//
661void MHCamera::AddCamContent(const TArrayD &event, Bool_t ispos)
662{
663 for (Int_t idx=0; idx<fNcells-2; idx++)
664 {
665 Fill(idx, const_cast<TArrayD&>(event)[idx]); // FIXME: Slow!
666 //fArray[idx+1]+=val;
667
668 if (!ispos || fArray[idx+1]>0)
669 SetUsed(idx);
670 }
671 fEntries++;
672}
673
674// ------------------------------------------------------------------------
675//
676// Call this function to fill the currents
677//
678void MHCamera::CntCamContent(const MCamEvent &event, Double_t threshold, Int_t type)
679{
680 // FIXME: Security check missing!
681 for (Int_t idx=0; idx<fNcells-2; idx++)
682 {
683 Double_t val=0;
684 if (event.GetPixelContent(val, idx, *fGeomCam, type) && !IsUsed(idx))
685 SetUsed(idx);
686
687 if (val>threshold)
688 Fill(idx);
689 }
690 fEntries++;
691}
692
693// ------------------------------------------------------------------------
694//
695// Call this function to fill the currents
696//
697void MHCamera::CntCamContent(const TArrayD &event, Double_t threshold, Bool_t ispos)
698{
699 for (Int_t idx=0; idx<fNcells-2; idx++)
700 {
701 if (const_cast<TArrayD&>(event)[idx]>threshold)
702 Fill(idx);
703
704 if (!ispos || fArray[idx+1]>0)
705 SetUsed(idx);
706 }
707 fEntries++;
708}
709
710void MHCamera::FillRandom()
711{
712 Reset();
713
714 // FIXME: Security check missing!
715 for (Int_t idx=0; idx<fNcells-2; idx++)
716 {
717 Fill(idx, gRandom->Uniform()*fGeomCam->GetPixRatio(idx));
718 SetUsed(idx);
719 }
720 fEntries=1;
721}
722
723
724// ------------------------------------------------------------------------
725//
726// Fill the colors in respect to the cleaning levels
727//
728void MHCamera::FillLevels(const MCerPhotEvt &event, Float_t lvl1, Float_t lvl2)
729{
730 SetCamContent(event, 2);
731
732 for (Int_t i=0; i<fNcells-2; i++)
733 {
734 if (!IsUsed(i))
735 continue;
736
737 if (fArray[i+1]>lvl1)
738 fArray[i+1] = 0;
739 else
740 if (fArray[i+1]>lvl2)
741 fArray[i+1] = 1;
742 else
743 fArray[i+1] = 2;
744 }
745}
746
747// ------------------------------------------------------------------------
748//
749// Fill the colors in respect to the cleaning levels
750//
751void MHCamera::FillLevels(const MCerPhotEvt &event, const MImgCleanStd &clean)
752{
753 FillLevels(event, clean.GetCleanLvl1(), clean.GetCleanLvl2());
754}
755
756// ------------------------------------------------------------------------
757//
758// Show a reflector event. EMarkerStyle is defined in root/include/Gtypes.h
759// To remove the photons from the display call FillRflEvent(NULL)
760//
761void MHCamera::ShowRflEvent(const MRflEvtData *event, EMarkerStyle ms)
762{
763 const Int_t num = event ? event->GetNumPhotons() : 0;
764
765 fPhotons->ExpandCreate(num);
766 if (num < 1)
767 return;
768
769 Int_t i=num-1;
770 do
771 {
772 const MRflSinglePhoton &ph = event->GetPhoton(i);
773 TMarker &m = *static_cast<TMarker*>(fPhotons->UncheckedAt(i));
774 m.SetX(ph.GetX());
775 m.SetY(ph.GetY());
776 m.SetMarkerStyle(ms);
777 } while (i--);
778}
779
780// ------------------------------------------------------------------------
781//
782// Reset the all pixel colors to a default value
783//
784void MHCamera::Reset(Option_t *opt)
785{
786 TH1::Reset(opt);
787
788 for (Int_t i=0; i<fNcells-2; i++)
789 {
790 fArray[i+1]=0;
791 ResetUsed(i);
792 }
793 fArray[0] = 0;
794 fArray[fNcells-1] = 0;
795}
796
797// ------------------------------------------------------------------------
798//
799// Here we calculate the color index for the current value.
800// The color index is defined with the class TStyle and the
801// Color palette inside. We use the command gStyle->SetPalette(1,0)
802// for the display. So we have to convert the value "wert" into
803// a color index that fits the color palette.
804// The range of the color palette is defined by the values fMinPhe
805// and fMaxRange. Between this values we have 50 color index, starting
806// with 0 up to 49.
807//
808Int_t MHCamera::GetColor(Float_t val, Float_t min, Float_t max, Bool_t islog)
809{
810 //
811 // first treat the over- and under-flows
812 //
813 const Int_t maxcolidx = kItemsLegend-1;
814
815 if (val >= max)
816 return fColors[maxcolidx];
817
818 if (val <= min)
819 return fColors[0];
820
821 //
822 // calculate the color index
823 //
824 Float_t ratio;
825 if (islog && min>0)
826 ratio = log10(val/min) / log10(max/min);
827 else
828 ratio = (val-min) / (max-min);
829 const Int_t colidx = (Int_t)(ratio*maxcolidx + .5);
830 return fColors[colidx];
831}
832
833// ------------------------------------------------------------------------
834//
835// Change the text on the legend according to the range of the Display
836//
837void MHCamera::UpdateLegend(Float_t minphe, Float_t maxphe, Bool_t islog)
838{
839 const Float_t range = fGeomCam->GetMaxRadius();
840
841 const Float_t H = 0.9*range;
842 const Float_t h = 2./kItemsLegend;
843 const Float_t offset = 0.04*range;
844
845 const Float_t w = range/sqrt((float)(fNcells-2));
846
847 TBox newbox;
848 TText newtxt;
849 newtxt.SetTextSize(0.025);
850 newtxt.SetTextAlign(12);
851#if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06)
852 newtxt.SetBit(/*kNoContextMenu|*/kCannotPick);
853 newbox.SetBit(/*kNoContextMenu|*/kCannotPick);
854#endif
855
856 for (Int_t i=0; i<kItemsLegend+1; i+=3)
857 {
858 const Float_t pos = (Float_t)i/kItemsLegend;
859
860 Float_t val;
861 if (islog && minphe>0)
862 val = pow(10, log10(maxphe/minphe)*pos) * minphe;
863 else
864 val = minphe + pos * (maxphe-minphe);
865
866 newtxt.PaintText(range+1.5*w, H*(i*h-1)-offset, Form(val<1e6?"%5.1f":"%5.1e", val));
867 }
868
869 for (Int_t i=0; i<kItemsLegend; i++)
870 {
871 newbox.SetFillColor(fColors[i]);
872 newbox.PaintBox(range, H*(i*h-1)-offset, range+w, H*((i+1)*h-1)-offset);
873 }
874
875 TArrow arr;
876 arr.PaintArrow(-range*.9, -range*.9, -range*.6, -range*.9, 0.025);
877 arr.PaintArrow(-range*.9, -range*.9, -range*.9, -range*.6, 0.025);
878
879 TString text;
880 text += (int)(range*.3);
881 text += "mm";
882
883 TText newtxt2;
884 newtxt2.SetTextSize(0.04);
885 newtxt2.PaintText(-range*.85, -range*.85, text);
886
887 text = "";
888 text += (float)((int)(range*.3*fGeomCam->GetConvMm2Deg()*10))/10;
889 text += "\\circ";
890 text = text.Strip(TString::kLeading);
891
892 TLatex latex;
893 latex.PaintLatex(-range*.85, -range*.75, 0, 0.04, text);
894}
895
896// ------------------------------------------------------------------------
897//
898// Save primitive as a C++ statement(s) on output stream out
899//
900void MHCamera::SavePrimitive(ofstream &out, Option_t *opt)
901{
902 cout << "MHCamera::SavePrimitive: Must be rewritten!" << endl;
903 /*
904 if (!gROOT->ClassSaved(TCanvas::Class()))
905 fDrawingPad->SavePrimitive(out, opt);
906
907 out << " " << fDrawingPad->GetName() << "->SetWindowSize(";
908 out << fDrawingPad->GetWw() << "," << fDrawingPad->GetWh() << ");" << endl;
909 */
910}
911
912// ------------------------------------------------------------------------
913//
914// compute the distance of a point (px,py) to the Camera
915// this functions needed for graphical primitives, that
916// means without this function you are not able to interact
917// with the graphical primitive with the mouse!!!
918//
919// All calcutations are running in pixel coordinates
920//
921Int_t MHCamera::DistancetoPrimitive(Int_t px, Int_t py)
922{
923 if (TString(GetDrawOption()).Contains("hist", TString::kIgnoreCase))
924 return TH1D::DistancetoPrimitive(px, py);
925
926 Int_t dist = 999999;
927
928 for (Int_t i=0; i<fNcells-2; i++)
929 {
930 MHexagon hex((*fGeomCam)[i]);
931 Int_t d = hex.DistancetoPrimitive(px, py);
932
933 if (d<dist)
934 dist=d;
935 }
936 return dist==0?0:999999;
937}
938
939// ------------------------------------------------------------------------
940//
941// Execute a mouse event on the camera
942//
943/*
944 void MHCamera::ExecuteEvent(Int_t event, Int_t px, Int_t py)
945 {
946 cout << "Execute Event Camera " << event << " @ " << px << " " << py << endl;
947 }
948 */
949
950
951// ------------------------------------------------------------------------
952//
953// Function introduced (31-01-03) WILL BE REMOVED IN THE FUTURE! DON'T
954// USE IT!
955//
956void MHCamera::SetPix(const Int_t idx, const Int_t color, Float_t min, Float_t max)
957{
958 fArray[idx+1] = color;
959 SetUsed(idx);
960}
961
962Int_t MHCamera::GetPixelIndex(Int_t px, Int_t py) const
963{
964 Int_t i;
965 for (i=0; i<fNcells-2; i++)
966 {
967 MHexagon hex((*fGeomCam)[i]);
968 if (hex.DistancetoPrimitive(px, py)>0)
969 continue;
970
971 return i;
972 }
973 return -1;
974}
975
976// ------------------------------------------------------------------------
977//
978// Returns string containing info about the object at position (px,py).
979// Returned string will be re-used (lock in MT environment).
980//
981char *MHCamera::GetObjectInfo(Int_t px, Int_t py) const
982{
983 if (TString(GetDrawOption()).Contains("hist", TString::kIgnoreCase))
984 return TH1D::GetObjectInfo(px, py);
985
986 static char info[128];
987
988 const Int_t idx=GetPixelIndex(px, py);
989
990 if (idx<0)
991 return TObject::GetObjectInfo(px, py);
992
993 sprintf(info, "Software Pixel Index: %d (Hardware Id=%d)", idx, idx+1);
994 return info;
995}
996
997// ------------------------------------------------------------------------
998//
999// Execute a mouse event on the camera
1000//
1001void MHCamera::ExecuteEvent(Int_t event, Int_t px, Int_t py)
1002{
1003 if (TString(GetDrawOption()).Contains("hist", TString::kIgnoreCase))
1004 {
1005 TH1D::ExecuteEvent(event, px, py);
1006 return;
1007 }
1008 //if (event==kMouseMotion && fStatusBar)
1009 // fStatusBar->SetText(GetObjectInfo(px, py), 0);
1010 if (event!=kButton1Down)
1011 return;
1012
1013 const Int_t idx = GetPixelIndex(px, py);
1014 if (idx<0)
1015 return;
1016
1017 cout << "Software Pixel Index: " << idx << endl;
1018 cout << "Hardware Pixel Id: " << idx+1 << endl;
1019 cout << "Contents: " << fArray[idx+1] << " <";
1020 cout << (IsUsed(idx)?"on":"off");
1021 cout << ">" << endl << endl;
1022
1023 if (fNotify && fNotify->GetSize()>0)
1024 new TCanvas;
1025 fNotify->ForEach(MCamEvent, DrawPixelContent)(idx);
1026}
Note: See TracBrowser for help on using the repository browser.