]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/AliMUONVPainter.cxx
Fix compiler warnings and new raw stream options
[u/mrichter/AliRoot.git] / MUON / AliMUONVPainter.cxx
CommitLineData
0145e89a 1/**************************************************************************
2* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3* *
4* Author: The ALICE Off-line Project. *
5* Contributors are mentioned in the code where appropriate. *
6* *
7* Permission to use, copy, modify and distribute this software and its *
8* documentation strictly for non-commercial purposes is hereby granted *
9* without fee, provided that the above copyright notice appears in all *
10* copies and that both the copyright notice and this permission notice *
11* appear in the supporting documentation. The authors make no claims *
12* about the suitability of this software for any purpose. It is *
13* provided "as is" without express or implied warranty. *
14**************************************************************************/
15
16// $Id$
17
18#include "AliMUONVPainter.h"
19
10eb3d17 20#include "AliCodeTimer.h"
21#include "AliLog.h"
0145e89a 22#include "AliMUONObjectPair.h"
23#include "AliMUONPainterContour.h"
24#include "AliMUONPainterGroup.h"
25#include "AliMUONPainterHelper.h"
10eb3d17 26#include "AliMUONTrackerDataHistogrammer.h"
0145e89a 27#include "AliMUONVTrackerData.h"
0145e89a 28#include <Riostream.h>
29#include <TCanvas.h>
30#include <TClass.h>
10eb3d17 31#include <TClassMenuItem.h>
32#include <TH1.h>
0145e89a 33#include <TList.h>
34#include <TMap.h>
35#include <TMath.h>
36#include <TMethodCall.h>
37#include <TObjArray.h>
38#include <TObjString.h>
39#include <TROOT.h>
40#include <TVirtualPad.h>
41#include <cassert>
42#include <float.h>
43
0145e89a 44/// \class AliMUONVPainter
45///
46/// Base class for a graphical object representing some part of the
47/// MUON tracking system.
48///
49/// A painter is a graphical representation of some part (e.g. detection element,
50/// full chamber, one manu, etc...) of the MUON tracking system.
51///
52/// A painter is a double fold hierarchical structure.
53///
54/// First, a painter is part of a tree (mother->childrens), that describe
55/// the natural organization of the spectrometer. For instance, a chamber
56/// painter has children that are the detection element, the detection elements
57/// themselves contain manus, which in turn contain channels.
58///
59/// Second, a painter contains a number of "painter groups" (see AliMUONPainterGroup).
60/// A group gather all the painters of the same type,
61/// where the type is a string identifying which part of system we're dealing
62/// with (chamber, DE, manu, etc...)
63///
64/// The groups are there to ease the manipulation of similar painters, e.g. if
65/// we want to hide all detection elements, we hide the "detection element group"
66/// Some special groups are the responder and the plotter groups. The responder
67/// group is the group which is currently responding to mouse events.
68/// The plotter group is the group which is supposed to represent some data.
69///
70/// There are two ways to represent the painter on screen. In any case, we can
71/// outline the painter (i.e. draw its borders) (see AliMUONVPainter::PaintOutline).
72/// In the cases where the painter is attached to some data source (i.e. it is
73/// used to represent some data about its type, e.g. the mean charge on some manu),
74/// we can draw the full area of the contour, using some color (see
75/// AliMUONVPainter::PaintArea).
76///
77/// Note that you can outline several types of painters (aka groups) at the same
78/// time, but you cannot plot several groups at the same time.
79///
80/// Painters are TQObject so they can emit signals.
81///
82/// Currently emitted signal are :
83///
84/// void Clicked(AliMUONVPainter* painter, Double_t*);
85/// DoubleClicked(AliMUONVPainter* painter, Double_t*);
86///
87/// to know which and where a painter was (double-) clicked.
88///
89/// \author Laurent Aphecetche, Subatech
90
91///\cond CLASSIMP
92ClassImp(AliMUONVPainter)
93///\endcond
94
95//_____________________________________________________________________________
96AliMUONVPainter::AliMUONVPainter(const char* type)
97: TObject(),
98 fName(""),
99 fPathName(""),
100 fType(type),
101 fMother(0x0),
102 fGroup(0x0),
103 fContour(0x0),
104 fPainterGroups(0x0),
105 fChildren(0x0),
106 fResponderGroup(0x0),
107 fPlotterGroup(0x0),
108 fBorderFactor(1.1),
109 fPad(0x0),
110 fAttributes(),
111 fLineColor(1),
112 fLineWidth(1),
10eb3d17 113 fIsValid(kTRUE),
114 fHistogram(0x0)
0145e89a 115{
116 /// ctor
117 SetID(-1,-1);
118}
119
120//_____________________________________________________________________________
121AliMUONVPainter::AliMUONVPainter(const AliMUONVPainter& rhs)
122: TObject(rhs),
123fName(""),
124fPathName(""),
125fType(""),
126fMother(0x0),
127fGroup(0x0),
128fContour(0x0),
129fPainterGroups(0x0),
130fChildren(0x0),
131fResponderGroup(0x0),
132fPlotterGroup(0x0),
133fBorderFactor(1.0),
134fPad(0x0),
135fAttributes(),
136fLineColor(-1),
137fLineWidth(-1),
10eb3d17 138fIsValid(kTRUE),
139fHistogram(0x0)
0145e89a 140{
141 /// copy ctor
142 rhs.Copy(*this);
143}
144
145//_____________________________________________________________________________
146AliMUONVPainter&
147AliMUONVPainter::operator=(const AliMUONVPainter& rhs)
148{
149 /// assignment operator
150 if ( this != &rhs )
151 {
152 rhs.Copy(*this);
153 }
154 return *this;
155}
156
157//_____________________________________________________________________________
158AliMUONVPainter::~AliMUONVPainter()
159{
160 /// dtor
161 delete fChildren;
10eb3d17 162 delete fHistogram;
0145e89a 163}
164
165//_____________________________________________________________________________
166AliMpArea
167AliMUONVPainter::Area() const
168{
169 /// Return the area covered by this painter
170 if ( fContour )
171 {
172 return fContour->Area();
173 }
174 else
175 {
176 AliWarning("Returning an invalid area, as contour is not defined");
177 return AliMpArea();
178 }
179}
180
181//_____________________________________________________________________________
182void
183AliMUONVPainter::Add(AliMUONVPainter* painter)
184{
185 /// Add a child painter
186 if (!fChildren) fChildren = new TObjArray;
187 assert(painter->Mother()==0x0);
188 fChildren->Add(painter);
189 painter->SetMother(this);
190}
191
192//_____________________________________________________________________________
193TCollection*
194AliMUONVPainter::Children() const
195{
196 /// Return the list of childrens
197 return fChildren;
198}
199
200//_____________________________________________________________________________
201void
202AliMUONVPainter::Clicked(AliMUONVPainter* painter, Double_t* values)
203{
9016a84e 204 /// Let our mother emit the signal as clients are probably connected to
205 /// our (grand)mother, not to us
0145e89a 206
207 if ( Mother() )
208 {
209 Mother()->Clicked(painter,values);
210 }
211 else
212 {
213 Long_t param[] = { (Long_t)painter,(Long_t)values };
214
215 Emit("Clicked(AliMUONVPainter*,Double_t*)",param);
216 }
217}
218
219//_____________________________________________________________________________
220void
221AliMUONVPainter::ShiftClicked(AliMUONVPainter* painter, Double_t* values)
222{
9016a84e 223 /// Let our mother emit the signal as clients are probably connected to
224 /// our (grand)mother, not to us
0145e89a 225
226 if ( Mother() )
227 {
228 Mother()->ShiftClicked(painter,values);
229 }
230 else
231 {
232 Long_t param[] = { (Long_t)painter,(Long_t)values };
233
234 Emit("ShiftClicked(AliMUONVPainter*,Double_t*)",param);
235 }
236}
237
238//_____________________________________________________________________________
239void
240AliMUONVPainter::ComputeDataRange(const AliMUONVTrackerData&, Int_t,
241 Double_t&, Double_t&) const
242{
243 /// Should compute the min and max of a given data source
244 AliError("Not implemented. Please fixe me");
245}
246
247//_____________________________________________________________________________
248TString
249AliMUONVPainter::ContourName() const
250{
251 /// Default implementation of the contour name.
252
253 TString name(PathName());
254
255 name += "-";
256 name += fAttributes.Name();
257
258 return name;
259}
260
261//_____________________________________________________________________________
262void
263AliMUONVPainter::Copy(TObject& object) const
264{
265 /// Copy this to object.
266
267 TObject::Copy(object);
268
269 AliMUONVPainter& painter = static_cast<AliMUONVPainter&>(object);
270
271 painter.fType = fType;
272 painter.fName = fName;
273 painter.fPathName = fPathName;
274
275 painter.fMother = 0x0;
276 painter.fContour = fContour;
277
278 painter.fGroup = 0x0;
279 painter.fResponderGroup = 0x0;
280 painter.fPlotterGroup = 0x0;
281
282 painter.fBorderFactor = fBorderFactor;
283
284 painter.fAttributes = fAttributes;
285
286 painter.fAttributes.SetCathodeAndPlaneDisabled(kFALSE);
287
288 painter.fPad = fPad;
289
290 painter.fLineColor = fLineColor;
291 painter.fLineWidth = fLineWidth;
292
293 painter.fIsValid = fIsValid;
294
295 delete painter.fChildren;
296 painter.fChildren = 0x0;
297
298 painter.fID[0] = fID[0];
299 painter.fID[1] = fID[1];
300
10eb3d17 301 delete painter.fHistogram;
302 painter.fHistogram = 0x0;
303
0145e89a 304 TIter next(fChildren);
305 AliMUONVPainter* p;
306
307 while ( ( p = static_cast<AliMUONVPainter*>(next()) ) )
308 {
309 painter.Add(static_cast<AliMUONVPainter*>(p->Clone()));
310 }
311
312 painter.UpdateGroupsFrom(*this);
313
314 object.ResetBit(kCanDelete);
315}
316
317//_____________________________________________________________________________
318AliMUONPainterGroup*
319AliMUONVPainter::CreateGroup(const char* type, Int_t depth)
320{
321 /// Create a painter group at a given depth
322
323 if (!fPainterGroups) fPainterGroups = new TMap;
324 TObject* o = fPainterGroups->GetValue(type);
325 if (o)
326 {
327 AliError(Form("Group %s is already there ! Check this",type));
328 return 0x0;
329 }
330 AliMUONPainterGroup* group = new AliMUONPainterGroup(type,depth);
331 fPainterGroups->Add(new TObjString(type),group);
332 return group;
333}
334
335//_____________________________________________________________________________
336void
337AliMUONVPainter::CreateGroups()
338{
339 /// Groups our children into groups
340
341 if ( Mother() )
342 {
343 AliFatal("Not supposed to create groups for a children");
344 }
345
346 TList list;
347 FlatList(list);
348
349 TIter next(&list);
350 AliMUONVPainter* painter;
351
352 while ( ( painter = static_cast<AliMUONVPainter*>(next()) ) )
353 {
354 AliMUONPainterGroup* group = Group(painter->Type());
355 if (!group)
356 {
357 group = CreateGroup(painter->Type(),painter->Depth());
358 }
359 group->Add(painter);
360 }
361}
362
363//_____________________________________________________________________________
364AliMUONVPainter*
365AliMUONVPainter::Detach() const
366{
367 /// Make this a new top painter (i.e. a master)
368
369 AliDebug(1,Form("Detaching %s",GetName()));
370
371 AliMUONVPainter* p = static_cast<AliMUONVPainter*>(Clone());
372
373 AliMUONVPainter* master = Master();
374
375 if ( master )
376 {
377 AliDebug(1,Form("UpdatingGroups of the detached painter %s from its master %s",
378 p->GetName(),master->GetName()));
379 p->UpdateGroupsFrom(*master);
380 }
381
382 return p;
383}
384
385//_____________________________________________________________________________
386Int_t
387AliMUONVPainter::Depth() const
388{
389 /// Return our depth in the hierarchy
390
391 if ( Mother() )
392 {
393 return Mother()->Depth() + 1;
394 }
395 else
396 {
397 return 0;
398 }
399}
400
401//_____________________________________________________________________________
402Int_t
403AliMUONVPainter::DistancetoPrimitive(Int_t px, Int_t py)
404{
405 /// See TObject::DistancetoPrimitive
406
407 static const Int_t kBigValue = 999999;
408
409 if (!gPad) return kBigValue;
410
411 Double_t x,y;
412
413 AliMUONVPainter* painter = GetPainter(px,py,x,y);
414
415 x=y=0.0; // to avoid compiler warning
416
417 if ( painter == this) return 0;
418
419 return kBigValue;
420}
421
422//_____________________________________________________________________________
423void
424AliMUONVPainter::DoubleClicked(AliMUONVPainter*, Double_t*)
425{
426 /// Should emit the DoubleClicked signal (if I knew how to detect those events...)
427
428 AliWarning("Please implement me !");
429
430 // if ( fMother )
431// {
432// // let our top mother emit the signal as clients are probably connected to
433// // our mother, not to us
434// Top()->DoubleClicked(painter,values);
435// }
436// else
437// {
438// Long_t param[] = { (Long_t)painter,(Long_t)values };
439//
440// Emit("DoubleClicked(AliMUONVPainter*,Double_t*)",param);
441// }
442}
443
444//_____________________________________________________________________________
445void
446AliMUONVPainter::Draw(Option_t* opt)
447{
448 /// Append ourselves to the current pad
449
450 if (!gPad)
451 {
452 gROOT->MakeDefCanvas();
453 }
454
455 Bool_t kMustSetRange(kFALSE);
456
457 TString sopt(opt);
458 sopt.ToUpper();
459
460 if (sopt.Contains("R") ) kMustSetRange=kTRUE;
461
462 if (kMustSetRange)
463 {
464 Double_t x1,y1,x2,y2;
465 GetBoundingBox(x1,y1,x2,y2);
466 if ( gPad) gPad->Range(x1,y1,x2,y2);
467 }
468
469 if ( !fMother && !fPainterGroups )
470 {
471 CreateGroups();
472 }
473
474 TIter next(fChildren);
475 AliMUONVPainter* painter;
476 while ( ( painter = static_cast<AliMUONVPainter*>(next()) ) )
477 {
478 painter->Draw();
479 }
480
481 AppendPad(opt);
482
483 fPad = gPad;
484}
485
486//_____________________________________________________________________________
487void
488AliMUONVPainter::ExecuteEvent(Int_t event, Int_t px, Int_t py)
489{
490 /// Handle graphics events
491
492 Double_t x,y;
493
494 AliMUONVPainter* painter = GetPainter(px,py,x,y);
495
496 if ( painter == this )
497 {
498 Double_t values[] = { x,y };
499
500 switch (event)
501 {
502 case kButton2Up:
503 ShiftClicked(this,values);
504 break;
505 case kButton1Up:
506 Clicked(this,values);
507 break;
508 case kButton1Double:
509 //the following statement is required against other loop executions before returning (depending on the time between the clicks)
510 gPad->GetCanvas()->HandleInput((EEventType)-1,0,0);
511 DoubleClicked(this,values);
512 break;
513 }
514 }
515}
516
517//_____________________________________________________________________________
518void
519AliMUONVPainter::FlatList(TList& list)
520{
10eb3d17 521 /// Make a flat list of our children (and ourselves)
0145e89a 522
523 TIter next(fChildren);
524 AliMUONVPainter* painter;
525 while ( ( painter = static_cast<AliMUONVPainter*>(next())))
526 {
527 painter->FlatList(list);
528 }
529
530 list.Add(this);
531}
532
533//_____________________________________________________________________________
534void
535AliMUONVPainter::GetBoundingBox(Double_t& x1, Double_t& y1,
536 Double_t& x2, Double_t& y2) const
537{
538 /// Get the bounding box = our area
539 AliMpArea area(Area().Position(),Area().Dimensions()*fBorderFactor);
540
541 x1 = area.LeftBorder();
542 y1 = area.DownBorder();
543 x2 = area.RightBorder();
544 y2 = area.UpBorder();
545}
546
547//_____________________________________________________________________________
548char*
549AliMUONVPainter::GetObjectInfo(Int_t, Int_t) const
550{
551 /// See TObject::GetObjectInfo
552 return const_cast<char*>(GetName());
553}
554
555//_____________________________________________________________________________
556AliMUONVPainter*
557AliMUONVPainter::GetPainter(Int_t px, Int_t py, Double_t& x, Double_t& y) const
558{
559 /// Get the responder painter at integer position (px,py), and get back its
560 /// absolute position (x,y)
561
562 PixelToPad(px,py,x,y);
563
564 if ( !IsInside(x,y) ) return 0x0;
565
566 if ( fGroup->IsResponder() ) return const_cast<AliMUONVPainter*>(this);
567
568 if (fChildren)
569 {
570 TIter next(fChildren);
571 AliMUONVPainter* painter;
572
573 while ( ( painter = static_cast<AliMUONVPainter*>(next()) ) )
574 {
575 AliMUONVPainter* p = painter->GetPainter(px,py,x,y);
576 if (p) return p;
577 }
578 }
579
580 return 0x0;
581}
582
583//_____________________________________________________________________________
584void
585AliMUONVPainter::GetTypes(TObjArray& types) const
586{
587 /// Get the list of types (as a TObjArray of TObjString)
588 /// of our hierarchy, sorted alphabetically
589
590 types.SetOwner(kTRUE);
591 types.Clear();
592
593 TObjArray tmp;
594 tmp.SetOwner(kFALSE);
595
596 TIter next(fPainterGroups);
597
598 TObjString* str;
599 while ( ( str = static_cast<TObjString*>(next()) ) )
600 {
601 AliMUONPainterGroup* group = Group(str->String().Data());
602 tmp.AddLast(group);
603 }
604
605 tmp.Sort();
606
607 Int_t n = tmp.GetLast()+1;
608
609 Int_t* index = new Int_t[n];
610
611 Int_t* a = new Int_t[n];
612
613 for ( Int_t i = 0; i < n; ++i )
614 {
615 AliMUONPainterGroup* group = static_cast<AliMUONPainterGroup*>(tmp.At(i));
616 a[i] = group->Depth();
617 }
618
619 TMath::Sort(n,a,index,kFALSE);
620
621 for ( Int_t i = 0; i < n; ++i )
622 {
623 AliMUONPainterGroup* group = static_cast<AliMUONPainterGroup*>(tmp.At(index[i]));
624 types.AddLast(new TObjString(group->Type()));
625 }
626
627 delete[] index;
628 delete[] a;
629}
630
631//_____________________________________________________________________________
632AliMUONPainterGroup*
633AliMUONVPainter::Group(const char* type) const
634{
635 /// Returns a group of a given type
636 if (!fPainterGroups) return 0x0;
637 return static_cast<AliMUONPainterGroup*>(fPainterGroups->GetValue(type));
638}
639
640//_____________________________________________________________________________
641AliMUONPainterGroup*
642AliMUONVPainter::Group(Int_t depth) const
643{
644 /// Returns a group of a given depth
645 if (!fPainterGroups) return 0x0;
646 TIter next(fPainterGroups);
647 TObjString* groupName;
648 while ( ( groupName = static_cast<TObjString*>(next()) ) )
649 {
650 AliMUONPainterGroup* group = static_cast<AliMUONPainterGroup*>
651 (fPainterGroups->GetValue(groupName->String().Data()));
652 if ( group->Depth() == depth )
653 {
654 return group;
655 }
656 }
657 return 0x0;
658}
659
660//_____________________________________________________________________________
661Bool_t
662AliMUONVPainter::IsInside(Double_t x, Double_t y) const
663{
664 /// Whether point (x,y) is inside our contour
665 if (!fContour) return kFALSE;
666 return fContour->IsInside(x,y);
667}
668
669//_____________________________________________________________________________
670Bool_t
671AliMUONVPainter::IsResponder() const
672{
673 /// Whether we're responding to mouse events
674 return MotherGroup()->IsResponder();
675}
676
677//_____________________________________________________________________________
678AliMUONVPainter*
679AliMUONVPainter::Master() const
680{
681 /// Return the top of the hierarchy
682
683 /// if we get no mother, we are the master
684
685 if ( Mother() == 0x0 ) return const_cast<AliMUONVPainter*>(this);
686
687 AliMUONVPainter* p = Mother();
688
689 while ( p->Mother() )
690 {
691 p = p->Mother();
692 }
693
694 return p;
695}
696
697//_____________________________________________________________________________
698void
699AliMUONVPainter::Paint(Option_t*)
700{
701 /// Paint ourselves of screen
702 /// If we have some data (i.e. we're belonging to the plotter group)
703 /// we use PaintArea.
704 /// And if must be outlined, then we do that too.
705
706 if ( !MotherGroup()->IsVisible() ) return;
707
708 if ( MotherGroup()->IsPlotter() )
709 {
710 PaintArea(*(MotherGroup()->Data()),
711 MotherGroup()->DataIndex(),
712 MotherGroup()->DataMin(),
713 MotherGroup()->DataMax());
714 }
715
716 if ( MotherGroup()->IsOutlined() )
717 {
718 PaintOutline();
719 }
720}
721
722//_____________________________________________________________________________
723TString
724AliMUONVPainter::Describe(const AliMUONVTrackerData&, Int_t, Double_t, Double_t)
725{
726 /// Default implementation (must be overriden)
727 AliError(Form("%s : implement me",GetName()));
728 return "";
729}
730
731//_____________________________________________________________________________
732void
733AliMUONVPainter::PaintArea(const AliMUONVTrackerData&, Int_t, Double_t, Double_t)
734{
735 /// Default implementation (must be overriden)
736 AliError(Form("%s : implement me",GetName()));
737}
738
739//_____________________________________________________________________________
740void
741AliMUONVPainter::PaintOutline(Int_t color, Int_t width, Double_t /*x*/, Double_t /*y*/)
742{
743 /// Default implementation is simply a drawing of the contour lines,
744 /// not using the optional (x,y)
745 Int_t c = color >= 0 ? color : GetLineColor();
746 Int_t w = width >= 0 ? width : GetLineWidth();
747
748 fContour->PaintOutline(c,w);
749}
750
751//_____________________________________________________________________________
752void
753AliMUONVPainter::PixelToPad(Int_t px, Int_t py, Double_t& x, Double_t& y)
754{
755 /// convert (px,py) into pad position (x,y)
756
757 x = gPad->PadtoX(gPad->AbsPixeltoX(px));
758 y = gPad->PadtoY(gPad->AbsPixeltoY(py));
759}
760
761//_____________________________________________________________________________
762void
763AliMUONVPainter::Print(Option_t* opt) const
764{
765 /// Printout
766 for ( Int_t i = 0; i < Depth()*4; ++i )
767 {
768 cout << " ";
769 }
770
771 if ( !IsValid() ) cout << "!!!INVALID!!!" << endl;
772
773 cout << Form("%p Name %s Depth %d ContourName %s ID=(%d,%d)",
774 this,GetName(),Depth(),ContourName().Data(),ID0(),ID1());
775
776 if ( fResponderGroup )
777 {
778 cout << Form(" Responder group %p %s",fResponderGroup,fResponderGroup->Type());
779 }
780 if ( fPlotterGroup )
781 {
782 cout << Form(" Plotter group %p %s",fPlotterGroup,fPlotterGroup->Type());
783 }
784 if ( Mother() )
785 {
786 cout << Form(" Mother %p %s",Mother(),Mother()->GetName());
787 }
788 if ( MotherGroup() )
789 {
790 cout << Form(" Group %p %s ",MotherGroup(),MotherGroup()->Type());
791 }
792
793 if ( fChildren )
794 {
795 cout << Form(" %d children",fChildren->GetLast()+1);
796 }
797
798 cout << endl;
799
800 TString sopt(opt);
801 sopt.ToUpper();
802
803 if ( fChildren && ( sopt == "FULL" || sopt == "CHILD" ) )
804 {
805 TIter next(fChildren);
806 AliMUONVPainter* painter;
807 while ( ( painter = static_cast<AliMUONVPainter*>(next()) ) )
808 {
809 painter->Print(opt);
810 }
811 }
812
813 if ( fPainterGroups && ( sopt == "FULL" || sopt == "GROUP" ) )
814 {
815 TIter next(fPainterGroups);
816 TObjString* groupName;
817 while ( ( groupName = static_cast<TObjString*>(next()) ) )
818 {
819 AliMUONPainterGroup* group = Group(groupName->String().Data());
820 group->Print(opt);
821 }
822 }
823}
824
825//_____________________________________________________________________________
826void
827AliMUONVPainter::SetAttributes(const AliMUONAttPainter& attributes)
828{
829 /// Set our attributes
830 fAttributes = attributes;
831}
832
833//_____________________________________________________________________________
834void
835AliMUONVPainter::SetContour(AliMUONPainterContour* contour)
836{
837 /// Set out contour
838 if (!contour)
839 {
840 AliError(Form("Setting a null contour for painter %s : bad idea !",PathName().Data()));
841 }
842 fContour = contour;
843}
844
845//_____________________________________________________________________________
846void
847AliMUONVPainter::SetData(const char* pattern, AliMUONVTrackerData* data,
848 Int_t dataIndex)
849{
850 /// Tell all painters which type matches pattern that they should
851 /// monitor a given data source
852
853 if ( !fPainterGroups )
854 {
855 CreateGroups();
856 }
857
858 TIter next(fPainterGroups);
859 TObjString* str;
860
861 fPlotterGroup = 0x0;
862
863 while ( ( str = static_cast<TObjString*>(next()) ) )
864 {
865 AliMUONPainterGroup* group = static_cast<AliMUONPainterGroup*>(fPainterGroups->GetValue(str));
10eb3d17 866
0145e89a 867 if ( group->Matches(pattern) )
868 {
869 group->SetData(data,dataIndex);
870 if ( data )
871 {
872 fPlotterGroup = group;
873 }
874 }
875 else
876 {
877 group->SetData(0x0,-1);
878 }
879 }
10eb3d17 880
881 // Update context menus
882 TList list;
883 FlatList(list);
884
885 TIter pnext(&list);
886 AliMUONVPainter* p;
887
888 AliMUONPainterGroup* group = Master()->PlotterGroup();
889
890 while ( ( p = static_cast<AliMUONVPainter*>(pnext()) ) )
891 {
892 TList* l = p->IsA()->GetMenuList();
893
894 l->Clear();
895
896 if ( group )
897 {
898 Int_t dim = group->Data()->InternalToExternal(group->DataIndex());
899 if ( dim < group->Data()->ExternalDimension() )
900 {
901 if ( data && data->IsHistogrammed(dim) )
902 {
903 // Add histo drawing to the popup menu
904 TClassMenuItem* n = new TClassMenuItem(TClassMenuItem::kPopupUserFunction,p->IsA(),
905 "Draw histogram","DrawHistogram",p,"",-1,kTRUE);
906 l->AddFirst(n);
907
908 n = new TClassMenuItem(TClassMenuItem::kPopupUserFunction,p->IsA(),
909 "Draw histogram clone","DrawHistogramClone",p,"",-1,kTRUE);
910 l->AddFirst(n);
911
912
913 }
914 }
915 }
916 }
917}
918
919//_____________________________________________________________________________
920void
921AliMUONVPainter::DrawHistogram() const
922{
923 /// Draw histogram (and delete the previous one)
924
925 delete fHistogram;
926 fHistogram = 0x0;
927
928 DrawHistogramClone();
929}
930
931//_____________________________________________________________________________
932void
933AliMUONVPainter::DrawHistogramClone() const
934{
935 /// Draw histogram
936
937 fHistogram = AliMUONTrackerDataHistogrammer::CreateHisto(*this);
938
939 if (fHistogram)
940 {
941 new TCanvas();
942 fHistogram->Draw();
943 }
944}
945
946//_____________________________________________________________________________
947void
948AliMUONVPainter::FillManuList(TObjArray& manuList) const
949{
950 /// Append to manulist
951 /// This is the default implementation, which just calls the FillManuList
952 /// of all our children.
953 /// Some derived class might need to override this in order to exclude
954 /// some children from the fill.
955
956 TIter next(Children());
957
958 AliMUONVPainter* p;
959
960 while ( ( p = static_cast<AliMUONVPainter*>(next()) ) )
961 {
962 p->FillManuList(manuList);
963 }
0145e89a 964}
965
966//_____________________________________________________________________________
967void
968AliMUONVPainter::SetLine(Int_t depth, Int_t lineColor, Int_t lineWidth)
969{
970 /// Set the line attributes of painters at a given depth
971 AliMUONPainterGroup* group = Group(depth);
972 if ( group )
973 {
974 group->SetLine(lineColor,lineWidth);
975 }
976}
977
978//_____________________________________________________________________________
979void
980AliMUONVPainter::SetMother(AliMUONVPainter* painter)
981{
982 /// Set our mother
983 fMother = painter;
984}
985
986//_____________________________________________________________________________
987void
988AliMUONVPainter::SetOutlined(const char* pattern, Bool_t flag)
989{
990 /// Decide whether or not painters which type matches pattern
991 /// should be outlined
992
993 AliDebug(1,Form("pattern=%s flag=%d",pattern,flag));
994
995 if (!fPainterGroups)
996 {
997 CreateGroups();
998 }
999
1000 TIter next(fPainterGroups);
1001 TObjString* str;
1002
1003 while ( ( str = static_cast<TObjString*>(next()) ) )
1004 {
1005 AliMUONPainterGroup* group = static_cast<AliMUONPainterGroup*>(fPainterGroups->GetValue(str));
1006 if ( group->Matches(pattern) )
1007 {
1008 group->SetOutlined(flag);
1009 }
1010 }
1011}
1012
1013//_____________________________________________________________________________
1014void
1015AliMUONVPainter::SetResponder(const char* pattern)
1016{
1017 /// Set the painters matching pattern to be the responder
1018
1019 AliDebug(1,Form("pattern=%s",pattern));
1020
1021 if (!fPainterGroups)
1022 {
1023 CreateGroups();
1024 }
1025
1026 TIter next(fPainterGroups);
1027 TObjString* str;
1028
1029 fResponderGroup = 0x0;
1030
1031 while ( ( str = static_cast<TObjString*>(next()) ) )
1032 {
1033 AliMUONPainterGroup* group = static_cast<AliMUONPainterGroup*>(fPainterGroups->GetValue(str));
1034 if ( group->Matches(pattern) )
1035 {
1036 AliDebug(1,Form("group %s is matching pattern %s : setting to responder",
1037 group->Type(),pattern));
1038 group->SetResponder(kTRUE);
1039 fResponderGroup = group;
1040 }
1041 else
1042 {
1043 group->SetResponder(kFALSE);
1044 }
1045 }
1046}
1047
1048//_____________________________________________________________________________
1049void
1050AliMUONVPainter::SetResponder(Int_t depth)
1051{
1052 /// Select as responder the *first* group that has a given depth
1053
1054 AliDebug(1,Form("depth=%d",depth));
1055
1056 if (!fPainterGroups)
1057 {
1058 CreateGroups();
1059 }
1060
1061 TIter next(fPainterGroups);
1062 TObjString* str;
1063
1064 fResponderGroup = 0x0;
1065
1066 while ( ( str = static_cast<TObjString*>(next()) ) )
1067 {
1068 AliMUONPainterGroup* group = static_cast<AliMUONPainterGroup*>(fPainterGroups->GetValue(str));
1069 if ( group->Depth() == depth )
1070 {
1071 AliDebug(1,Form("group %s has correct depth = %d, using as responder",
1072 group->Type(),depth));
1073 group->SetResponder(kTRUE);
1074 fResponderGroup = group;
1075 break;
1076 }
1077 else
1078 {
1079 group->SetResponder(kFALSE);
1080 }
1081 }
1082}
1083
1084//_____________________________________________________________________________
1085void
1086AliMUONVPainter::SetVisible(const char* pattern, Bool_t flag)
1087{
1088 /// Decide whether the painters matching pattern should be visible or not
1089 AliDebug(1,Form("pattern=%s flag=%d",pattern,flag));
1090
1091 if (!fPainterGroups)
1092 {
1093 CreateGroups();
1094 }
1095
1096 TIter next(fPainterGroups);
1097 TObjString* str;
1098
1099 while ( ( str = static_cast<TObjString*>(next()) ) )
1100 {
1101 AliMUONPainterGroup* group = static_cast<AliMUONPainterGroup*>(fPainterGroups->GetValue(str));
1102 if ( group->Matches(pattern) )
1103 {
1104 group->SetVisible(flag);
1105 }
1106 }
1107}
1108
1109//_____________________________________________________________________________
1110void
1111AliMUONVPainter::UpdateGroupsFrom(const AliMUONVPainter& painter)
1112{
1113 /// (re)Create groups
1114 delete fPainterGroups;
1115 fPainterGroups = 0x0;
1116
1117 CreateGroups();
1118
1119 // and copy the status of responder, plotter and visible
1120 if ( painter.ResponderGroup() )
1121 {
1122 SetResponder(painter.ResponderGroup()->Type());
1123 }
1124
1125 if ( painter.PlotterGroup() )
1126 {
1127 SetData(painter.PlotterGroup()->Type(),
1128 painter.PlotterGroup()->Data(),
1129 painter.PlotterGroup()->DataIndex());
1130 PlotterGroup()->SetDataRange(painter.PlotterGroup()->DataMin(),
1131 painter.PlotterGroup()->DataMax());
1132 }
1133
1134 TObjArray types;
1135 painter.GetTypes(types);
1136 TIter next(&types);
1137 TObjString* groupName;
1138
1139 while ( ( groupName = static_cast<TObjString*>(next()) ) )
1140 {
1141 AliMUONPainterGroup* group = painter.Group(groupName->String().Data());
1142 if ( group->IsVisible() )
1143 {
1144 SetVisible(group->Type(),kTRUE);
1145 }
1146 else
1147 {
1148 SetVisible(group->Type(),kFALSE);
1149 }
1150
1151 if ( group->IsOutlined() )
1152 {
1153 SetOutlined(group->Type(),kTRUE);
1154 }
1155 else
1156 {
1157 SetOutlined(group->Type(),kFALSE);
1158 }
1159
1160 SetLine(group->Depth(),group->GetLineColor(),group->GetLineWidth());
1161 }
1162}
1163
1164//_____________________________________________________________________________
1165AliMUONVPainter*
1166AliMUONVPainter::CreatePainter(const char* className,
1167 const AliMUONAttPainter& att,
1168 Int_t id1, Int_t id2)
1169{
1170 /// Create a painter (factory method)
1171
1172 TClass* c = TClass::GetClass(className);
1173
1174 if (!c)
1175 {
1176 AliErrorClass(Form("Cannot get class %s",className));
1177 return 0x0;
1178 }
1179
1180 Int_t n(0);
1181
1182 TMethodCall call;
1183
1184 call.InitWithPrototype(c,className,"AliMUONAttPainter&,Int_t");
1185
1186 if (call.IsValid()) n = 1;
1187 else
1188 {
1189 call.InitWithPrototype(c,className,"AliMUONAttPainter&,Int_t,Int_t");
1190
1191 if ( call.IsValid() ) n = 2;
1192 }
1193
1194 Long_t returnLong(0x0);
1195
1196 if ( n ==1 )
1197 {
1198 Long_t params[] = { (Long_t)(&att), (Long_t)(id1) };
1199 call.SetParamPtrs((void*)(params));
1200 call.Execute((void*)(0x0),returnLong);
1201 }
1202 else if ( n == 2 )
1203 {
1204 Long_t params[] = { (Long_t)(&att), (Long_t)(id1), (Long_t)(id2) };
1205 call.SetParamPtrs((void*)(params));
1206 call.Execute((void*)(0x0),returnLong);
1207 }
1208
1209 if (!returnLong)
1210 {
1211 AliErrorClass(Form("Cannot create a painter of class %s",className));
1212 }
1213
1214 AliMUONVPainter* rv = reinterpret_cast<AliMUONVPainter*> (returnLong);
1215
1216 if (!rv->IsValid())
1217 {
1218 AliErrorClass(Form("Painter of class %s is not valid",className));
1219 delete rv;
1220 rv = 0x0;
1221 }
1222 return rv;
1223}
1224