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