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