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