]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/AliMUONVPainter.cxx
Memory leaks
[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
49419555 860 if ( data )
861 {
862 data->Connect("Destroyed()",ClassName(),this,Form("SetData(=\"%s\",0x0,-1)",pattern));
863 }
864
0145e89a 865 TIter next(fPainterGroups);
866 TObjString* str;
867
868 fPlotterGroup = 0x0;
869
870 while ( ( str = static_cast<TObjString*>(next()) ) )
871 {
872 AliMUONPainterGroup* group = static_cast<AliMUONPainterGroup*>(fPainterGroups->GetValue(str));
10eb3d17 873
0145e89a 874 if ( group->Matches(pattern) )
875 {
876 group->SetData(data,dataIndex);
877 if ( data )
878 {
879 fPlotterGroup = group;
880 }
881 }
882 else
883 {
884 group->SetData(0x0,-1);
885 }
886 }
10eb3d17 887
888 // Update context menus
889 TList list;
890 FlatList(list);
891
892 TIter pnext(&list);
893 AliMUONVPainter* p;
894
895 AliMUONPainterGroup* group = Master()->PlotterGroup();
896
897 while ( ( p = static_cast<AliMUONVPainter*>(pnext()) ) )
898 {
899 TList* l = p->IsA()->GetMenuList();
900
49419555 901// l->Clear();
902 l->Delete();
10eb3d17 903
904 if ( group )
905 {
906 Int_t dim = group->Data()->InternalToExternal(group->DataIndex());
907 if ( dim < group->Data()->ExternalDimension() )
908 {
909 if ( data && data->IsHistogrammed(dim) )
910 {
911 // Add histo drawing to the popup menu
912 TClassMenuItem* n = new TClassMenuItem(TClassMenuItem::kPopupUserFunction,p->IsA(),
49419555 913 "Draw histogram","DrawHistogram0",p,"",-1,kTRUE);
914 l->Add(n);
10eb3d17 915
916 n = new TClassMenuItem(TClassMenuItem::kPopupUserFunction,p->IsA(),
49419555 917 "Draw histogram clone","DrawHistogramClone0",p,"",-1,kTRUE);
918 l->Add(n);
10eb3d17 919 }
49419555 920
10eb3d17 921 }
49419555 922
923 for ( Int_t i = 0; i < data->ExternalDimension()*2; ++i )
924 {
925 TClassMenuItem* n = new TClassMenuItem(TClassMenuItem::kPopupUserFunction,p->IsA(),
926 Form("Draw %s clone",data->DimensionName(i).Data()),
927 Form("DrawInternalHistogramClone%d",i),p,"",-1,kTRUE);
928 l->Add(n);
929 }
10eb3d17 930 }
931 }
932}
933
934//_____________________________________________________________________________
935void
49419555 936AliMUONVPainter::DrawInternalHistogram(Int_t dim) const
937{
938 /// Draw histogram (and delete the previous one)
939
940 delete fHistogram;
941 fHistogram = 0x0;
942
943 DrawInternalHistogramClone(dim);
944}
945
946//_____________________________________________________________________________
947void
948AliMUONVPainter::DrawInternalHistogramClone(Int_t dim) const
949{
950 /// Draw histogram
951
952 fHistogram = AliMUONTrackerDataHistogrammer::CreateHisto(*this,-1,dim);
953
954 if (fHistogram)
955 {
956 new TCanvas();
957 fHistogram->Draw();
958 }
959}
960
961//_____________________________________________________________________________
962void
963AliMUONVPainter::DrawHistogram(Double_t* values) const
10eb3d17 964{
965 /// Draw histogram (and delete the previous one)
966
967 delete fHistogram;
968 fHistogram = 0x0;
969
49419555 970 DrawHistogramClone(values);
10eb3d17 971}
972
973//_____________________________________________________________________________
974void
49419555 975AliMUONVPainter::DrawHistogramClone(Double_t*) const
10eb3d17 976{
977 /// Draw histogram
978
49419555 979 fHistogram = AliMUONTrackerDataHistogrammer::CreateHisto(*this,0,-1);
10eb3d17 980
981 if (fHistogram)
982 {
983 new TCanvas();
984 fHistogram->Draw();
985 }
986}
987
988//_____________________________________________________________________________
989void
990AliMUONVPainter::FillManuList(TObjArray& manuList) const
991{
992 /// Append to manulist
993 /// This is the default implementation, which just calls the FillManuList
994 /// of all our children.
995 /// Some derived class might need to override this in order to exclude
996 /// some children from the fill.
997
998 TIter next(Children());
999
1000 AliMUONVPainter* p;
1001
1002 while ( ( p = static_cast<AliMUONVPainter*>(next()) ) )
1003 {
1004 p->FillManuList(manuList);
1005 }
0145e89a 1006}
1007
1008//_____________________________________________________________________________
1009void
1010AliMUONVPainter::SetLine(Int_t depth, Int_t lineColor, Int_t lineWidth)
1011{
1012 /// Set the line attributes of painters at a given depth
1013 AliMUONPainterGroup* group = Group(depth);
1014 if ( group )
1015 {
1016 group->SetLine(lineColor,lineWidth);
1017 }
1018}
1019
1020//_____________________________________________________________________________
1021void
1022AliMUONVPainter::SetMother(AliMUONVPainter* painter)
1023{
1024 /// Set our mother
1025 fMother = painter;
1026}
1027
1028//_____________________________________________________________________________
1029void
1030AliMUONVPainter::SetOutlined(const char* pattern, Bool_t flag)
1031{
1032 /// Decide whether or not painters which type matches pattern
1033 /// should be outlined
1034
1035 AliDebug(1,Form("pattern=%s flag=%d",pattern,flag));
1036
1037 if (!fPainterGroups)
1038 {
1039 CreateGroups();
1040 }
1041
1042 TIter next(fPainterGroups);
1043 TObjString* str;
1044
1045 while ( ( str = static_cast<TObjString*>(next()) ) )
1046 {
1047 AliMUONPainterGroup* group = static_cast<AliMUONPainterGroup*>(fPainterGroups->GetValue(str));
1048 if ( group->Matches(pattern) )
1049 {
1050 group->SetOutlined(flag);
1051 }
1052 }
1053}
1054
1055//_____________________________________________________________________________
1056void
1057AliMUONVPainter::SetResponder(const char* pattern)
1058{
1059 /// Set the painters matching pattern to be the responder
1060
1061 AliDebug(1,Form("pattern=%s",pattern));
1062
1063 if (!fPainterGroups)
1064 {
1065 CreateGroups();
1066 }
1067
1068 TIter next(fPainterGroups);
1069 TObjString* str;
1070
1071 fResponderGroup = 0x0;
1072
1073 while ( ( str = static_cast<TObjString*>(next()) ) )
1074 {
1075 AliMUONPainterGroup* group = static_cast<AliMUONPainterGroup*>(fPainterGroups->GetValue(str));
1076 if ( group->Matches(pattern) )
1077 {
1078 AliDebug(1,Form("group %s is matching pattern %s : setting to responder",
1079 group->Type(),pattern));
1080 group->SetResponder(kTRUE);
1081 fResponderGroup = group;
1082 }
1083 else
1084 {
1085 group->SetResponder(kFALSE);
1086 }
1087 }
1088}
1089
1090//_____________________________________________________________________________
1091void
1092AliMUONVPainter::SetResponder(Int_t depth)
1093{
1094 /// Select as responder the *first* group that has a given depth
1095
1096 AliDebug(1,Form("depth=%d",depth));
1097
1098 if (!fPainterGroups)
1099 {
1100 CreateGroups();
1101 }
1102
1103 TIter next(fPainterGroups);
1104 TObjString* str;
1105
1106 fResponderGroup = 0x0;
1107
1108 while ( ( str = static_cast<TObjString*>(next()) ) )
1109 {
1110 AliMUONPainterGroup* group = static_cast<AliMUONPainterGroup*>(fPainterGroups->GetValue(str));
1111 if ( group->Depth() == depth )
1112 {
1113 AliDebug(1,Form("group %s has correct depth = %d, using as responder",
1114 group->Type(),depth));
1115 group->SetResponder(kTRUE);
1116 fResponderGroup = group;
1117 break;
1118 }
1119 else
1120 {
1121 group->SetResponder(kFALSE);
1122 }
1123 }
1124}
1125
1126//_____________________________________________________________________________
1127void
1128AliMUONVPainter::SetVisible(const char* pattern, Bool_t flag)
1129{
1130 /// Decide whether the painters matching pattern should be visible or not
1131 AliDebug(1,Form("pattern=%s flag=%d",pattern,flag));
1132
1133 if (!fPainterGroups)
1134 {
1135 CreateGroups();
1136 }
1137
1138 TIter next(fPainterGroups);
1139 TObjString* str;
1140
1141 while ( ( str = static_cast<TObjString*>(next()) ) )
1142 {
1143 AliMUONPainterGroup* group = static_cast<AliMUONPainterGroup*>(fPainterGroups->GetValue(str));
1144 if ( group->Matches(pattern) )
1145 {
1146 group->SetVisible(flag);
1147 }
1148 }
1149}
1150
1151//_____________________________________________________________________________
1152void
1153AliMUONVPainter::UpdateGroupsFrom(const AliMUONVPainter& painter)
1154{
1155 /// (re)Create groups
1156 delete fPainterGroups;
1157 fPainterGroups = 0x0;
1158
1159 CreateGroups();
1160
1161 // and copy the status of responder, plotter and visible
1162 if ( painter.ResponderGroup() )
1163 {
1164 SetResponder(painter.ResponderGroup()->Type());
1165 }
1166
1167 if ( painter.PlotterGroup() )
1168 {
1169 SetData(painter.PlotterGroup()->Type(),
1170 painter.PlotterGroup()->Data(),
1171 painter.PlotterGroup()->DataIndex());
1172 PlotterGroup()->SetDataRange(painter.PlotterGroup()->DataMin(),
1173 painter.PlotterGroup()->DataMax());
1174 }
1175
1176 TObjArray types;
1177 painter.GetTypes(types);
1178 TIter next(&types);
1179 TObjString* groupName;
1180
1181 while ( ( groupName = static_cast<TObjString*>(next()) ) )
1182 {
1183 AliMUONPainterGroup* group = painter.Group(groupName->String().Data());
1184 if ( group->IsVisible() )
1185 {
1186 SetVisible(group->Type(),kTRUE);
1187 }
1188 else
1189 {
1190 SetVisible(group->Type(),kFALSE);
1191 }
1192
1193 if ( group->IsOutlined() )
1194 {
1195 SetOutlined(group->Type(),kTRUE);
1196 }
1197 else
1198 {
1199 SetOutlined(group->Type(),kFALSE);
1200 }
1201
1202 SetLine(group->Depth(),group->GetLineColor(),group->GetLineWidth());
1203 }
1204}
1205
1206//_____________________________________________________________________________
1207AliMUONVPainter*
1208AliMUONVPainter::CreatePainter(const char* className,
1209 const AliMUONAttPainter& att,
1210 Int_t id1, Int_t id2)
1211{
1212 /// Create a painter (factory method)
1213
1214 TClass* c = TClass::GetClass(className);
1215
1216 if (!c)
1217 {
1218 AliErrorClass(Form("Cannot get class %s",className));
1219 return 0x0;
1220 }
1221
1222 Int_t n(0);
1223
1224 TMethodCall call;
1225
1226 call.InitWithPrototype(c,className,"AliMUONAttPainter&,Int_t");
1227
1228 if (call.IsValid()) n = 1;
1229 else
1230 {
1231 call.InitWithPrototype(c,className,"AliMUONAttPainter&,Int_t,Int_t");
1232
1233 if ( call.IsValid() ) n = 2;
1234 }
1235
1236 Long_t returnLong(0x0);
1237
1238 if ( n ==1 )
1239 {
1240 Long_t params[] = { (Long_t)(&att), (Long_t)(id1) };
1241 call.SetParamPtrs((void*)(params));
1242 call.Execute((void*)(0x0),returnLong);
1243 }
1244 else if ( n == 2 )
1245 {
1246 Long_t params[] = { (Long_t)(&att), (Long_t)(id1), (Long_t)(id2) };
1247 call.SetParamPtrs((void*)(params));
1248 call.Execute((void*)(0x0),returnLong);
1249 }
1250
1251 if (!returnLong)
1252 {
1253 AliErrorClass(Form("Cannot create a painter of class %s",className));
1254 }
1255
1256 AliMUONVPainter* rv = reinterpret_cast<AliMUONVPainter*> (returnLong);
1257
1258 if (!rv->IsValid())
1259 {
1260 AliErrorClass(Form("Painter of class %s is not valid",className));
1261 delete rv;
1262 rv = 0x0;
1263 }
1264 return rv;
1265}
1266