bug fixed
[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 "AliLog.h"
1ffbeb9d 21#include "AliMUON2DMap.h"
22#include "AliMUONCalibParamND.h"
8f0acce4 23#include "AliMUONContour.h"
24#include "AliMUONContourPainter.h"
0145e89a 25#include "AliMUONObjectPair.h"
0145e89a 26#include "AliMUONPainterGroup.h"
27#include "AliMUONPainterHelper.h"
8f0acce4 28#include "AliMUONPainterDataRegistry.h"
10eb3d17 29#include "AliMUONTrackerDataHistogrammer.h"
0145e89a 30#include "AliMUONVTrackerData.h"
8f0acce4 31#include "AliMpManuUID.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
99//_____________________________________________________________________________
1ffbeb9d 100AliMUONVPainter::AliMUONVPainter(TRootIOCtor*) : TObject(),
101TQObject(),
102fHistogram(0x0),
05398ff1 103fPainterGroups(0x0),
104fResponderGroup(0x0),
1ffbeb9d 105fName(""),
106fPathName(""),
107fType(""),
108fMother(0x0),
109fGroup(0x0),
110fContour(0x0),
1ffbeb9d 111fChildren(0x0),
1ffbeb9d 112fPlotterGroup(0x0),
113fBorderFactor(1.1),
114fPad(0x0),
115fAttributes(),
116fLineColor(1),
117fLineWidth(1),
118fIsValid(kTRUE)
119{
120 /// streamer ctor
121}
122
123//_____________________________________________________________________________
0145e89a 124AliMUONVPainter::AliMUONVPainter(const char* type)
125: TObject(),
4a3224ff 126 TQObject(),
b89ac3d6 127 fHistogram(0x0),
05398ff1 128 fPainterGroups(0x0),
129 fResponderGroup(0x0),
0145e89a 130 fName(""),
131 fPathName(""),
132 fType(type),
133 fMother(0x0),
134 fGroup(0x0),
135 fContour(0x0),
0145e89a 136 fChildren(0x0),
0145e89a 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),
05398ff1 154fPainterGroups(0x0),
155fResponderGroup(0x0),
0145e89a 156fName(""),
157fPathName(""),
158fType(""),
159fMother(0x0),
160fGroup(0x0),
161fContour(0x0),
0145e89a 162fChildren(0x0),
0145e89a 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
8f0acce4 569 AliMpArea area(Area().GetPositionX(),
6e97fbb8 570 Area().GetPositionY(),
8f0acce4 571 Area().GetDimensionX()*fBorderFactor,
6e97fbb8 572 Area().GetDimensionY()*fBorderFactor);
0145e89a 573
574 x1 = area.LeftBorder();
575 y1 = area.DownBorder();
576 x2 = area.RightBorder();
577 y2 = area.UpBorder();
578}
579
580//_____________________________________________________________________________
581char*
582AliMUONVPainter::GetObjectInfo(Int_t, Int_t) const
583{
584 /// See TObject::GetObjectInfo
585 return const_cast<char*>(GetName());
586}
587
588//_____________________________________________________________________________
589AliMUONVPainter*
590AliMUONVPainter::GetPainter(Int_t px, Int_t py, Double_t& x, Double_t& y) const
591{
592 /// Get the responder painter at integer position (px,py), and get back its
593 /// absolute position (x,y)
594
595 PixelToPad(px,py,x,y);
596
597 if ( !IsInside(x,y) ) return 0x0;
598
599 if ( fGroup->IsResponder() ) return const_cast<AliMUONVPainter*>(this);
600
601 if (fChildren)
602 {
603 TIter next(fChildren);
604 AliMUONVPainter* painter;
605
606 while ( ( painter = static_cast<AliMUONVPainter*>(next()) ) )
607 {
608 AliMUONVPainter* p = painter->GetPainter(px,py,x,y);
609 if (p) return p;
610 }
611 }
612
613 return 0x0;
614}
615
616//_____________________________________________________________________________
617void
618AliMUONVPainter::GetTypes(TObjArray& types) const
619{
620 /// Get the list of types (as a TObjArray of TObjString)
621 /// of our hierarchy, sorted alphabetically
622
623 types.SetOwner(kTRUE);
624 types.Clear();
625
626 TObjArray tmp;
627 tmp.SetOwner(kFALSE);
628
629 TIter next(fPainterGroups);
630
631 TObjString* str;
632 while ( ( str = static_cast<TObjString*>(next()) ) )
633 {
634 AliMUONPainterGroup* group = Group(str->String().Data());
635 tmp.AddLast(group);
636 }
637
638 tmp.Sort();
639
640 Int_t n = tmp.GetLast()+1;
641
642 Int_t* index = new Int_t[n];
643
644 Int_t* a = new Int_t[n];
645
646 for ( Int_t i = 0; i < n; ++i )
647 {
648 AliMUONPainterGroup* group = static_cast<AliMUONPainterGroup*>(tmp.At(i));
649 a[i] = group->Depth();
650 }
651
652 TMath::Sort(n,a,index,kFALSE);
653
654 for ( Int_t i = 0; i < n; ++i )
655 {
656 AliMUONPainterGroup* group = static_cast<AliMUONPainterGroup*>(tmp.At(index[i]));
657 types.AddLast(new TObjString(group->Type()));
658 }
659
660 delete[] index;
661 delete[] a;
662}
663
664//_____________________________________________________________________________
665AliMUONPainterGroup*
666AliMUONVPainter::Group(const char* type) const
667{
668 /// Returns a group of a given type
669 if (!fPainterGroups) return 0x0;
670 return static_cast<AliMUONPainterGroup*>(fPainterGroups->GetValue(type));
671}
672
673//_____________________________________________________________________________
674AliMUONPainterGroup*
675AliMUONVPainter::Group(Int_t depth) const
676{
677 /// Returns a group of a given depth
678 if (!fPainterGroups) return 0x0;
679 TIter next(fPainterGroups);
680 TObjString* groupName;
681 while ( ( groupName = static_cast<TObjString*>(next()) ) )
682 {
683 AliMUONPainterGroup* group = static_cast<AliMUONPainterGroup*>
684 (fPainterGroups->GetValue(groupName->String().Data()));
685 if ( group->Depth() == depth )
686 {
687 return group;
688 }
689 }
690 return 0x0;
691}
692
693//_____________________________________________________________________________
694Bool_t
695AliMUONVPainter::IsInside(Double_t x, Double_t y) const
696{
697 /// Whether point (x,y) is inside our contour
698 if (!fContour) return kFALSE;
699 return fContour->IsInside(x,y);
700}
701
702//_____________________________________________________________________________
703Bool_t
704AliMUONVPainter::IsResponder() const
705{
706 /// Whether we're responding to mouse events
707 return MotherGroup()->IsResponder();
708}
709
710//_____________________________________________________________________________
711AliMUONVPainter*
712AliMUONVPainter::Master() const
713{
714 /// Return the top of the hierarchy
715
716 /// if we get no mother, we are the master
717
718 if ( Mother() == 0x0 ) return const_cast<AliMUONVPainter*>(this);
719
720 AliMUONVPainter* p = Mother();
721
722 while ( p->Mother() )
723 {
724 p = p->Mother();
725 }
726
727 return p;
728}
729
730//_____________________________________________________________________________
731void
732AliMUONVPainter::Paint(Option_t*)
733{
734 /// Paint ourselves of screen
735 /// If we have some data (i.e. we're belonging to the plotter group)
736 /// we use PaintArea.
737 /// And if must be outlined, then we do that too.
738
739 if ( !MotherGroup()->IsVisible() ) return;
740
741 if ( MotherGroup()->IsPlotter() )
742 {
743 PaintArea(*(MotherGroup()->Data()),
744 MotherGroup()->DataIndex(),
745 MotherGroup()->DataMin(),
746 MotherGroup()->DataMax());
747 }
748
749 if ( MotherGroup()->IsOutlined() )
750 {
751 PaintOutline();
752 }
1ffbeb9d 753
754 if ( IsExcluded() )
755 {
8f0acce4 756 AliMUONContourPainter::Paint(*fContour,1,1,2); // red fill with black thin outline
1ffbeb9d 757 }
0145e89a 758}
759
760//_____________________________________________________________________________
761TString
762AliMUONVPainter::Describe(const AliMUONVTrackerData&, Int_t, Double_t, Double_t)
763{
764 /// Default implementation (must be overriden)
765 AliError(Form("%s : implement me",GetName()));
766 return "";
767}
768
769//_____________________________________________________________________________
770void
771AliMUONVPainter::PaintArea(const AliMUONVTrackerData&, Int_t, Double_t, Double_t)
772{
773 /// Default implementation (must be overriden)
774 AliError(Form("%s : implement me",GetName()));
1ffbeb9d 775 return;
0145e89a 776}
777
778//_____________________________________________________________________________
779void
780AliMUONVPainter::PaintOutline(Int_t color, Int_t width, Double_t /*x*/, Double_t /*y*/)
781{
782 /// Default implementation is simply a drawing of the contour lines,
783 /// not using the optional (x,y)
784 Int_t c = color >= 0 ? color : GetLineColor();
785 Int_t w = width >= 0 ? width : GetLineWidth();
786
8f0acce4 787 AliMUONContourPainter::Paint(*fContour,c,w);
0145e89a 788}
789
790//_____________________________________________________________________________
791void
792AliMUONVPainter::PixelToPad(Int_t px, Int_t py, Double_t& x, Double_t& y)
793{
794 /// convert (px,py) into pad position (x,y)
795
796 x = gPad->PadtoX(gPad->AbsPixeltoX(px));
797 y = gPad->PadtoY(gPad->AbsPixeltoY(py));
798}
799
800//_____________________________________________________________________________
801void
802AliMUONVPainter::Print(Option_t* opt) const
803{
804 /// Printout
805 for ( Int_t i = 0; i < Depth()*4; ++i )
806 {
807 cout << " ";
808 }
809
810 if ( !IsValid() ) cout << "!!!INVALID!!!" << endl;
811
812 cout << Form("%p Name %s Depth %d ContourName %s ID=(%d,%d)",
813 this,GetName(),Depth(),ContourName().Data(),ID0(),ID1());
814
815 if ( fResponderGroup )
816 {
817 cout << Form(" Responder group %p %s",fResponderGroup,fResponderGroup->Type());
818 }
819 if ( fPlotterGroup )
820 {
821 cout << Form(" Plotter group %p %s",fPlotterGroup,fPlotterGroup->Type());
822 }
823 if ( Mother() )
824 {
825 cout << Form(" Mother %p %s",Mother(),Mother()->GetName());
826 }
827 if ( MotherGroup() )
828 {
829 cout << Form(" Group %p %s ",MotherGroup(),MotherGroup()->Type());
830 }
831
832 if ( fChildren )
833 {
834 cout << Form(" %d children",fChildren->GetLast()+1);
835 }
836
837 cout << endl;
838
839 TString sopt(opt);
840 sopt.ToUpper();
841
842 if ( fChildren && ( sopt == "FULL" || sopt == "CHILD" ) )
843 {
844 TIter next(fChildren);
845 AliMUONVPainter* painter;
846 while ( ( painter = static_cast<AliMUONVPainter*>(next()) ) )
847 {
848 painter->Print(opt);
849 }
850 }
851
852 if ( fPainterGroups && ( sopt == "FULL" || sopt == "GROUP" ) )
853 {
854 TIter next(fPainterGroups);
855 TObjString* groupName;
856 while ( ( groupName = static_cast<TObjString*>(next()) ) )
857 {
858 AliMUONPainterGroup* group = Group(groupName->String().Data());
859 group->Print(opt);
860 }
861 }
862}
863
864//_____________________________________________________________________________
865void
866AliMUONVPainter::SetAttributes(const AliMUONAttPainter& attributes)
867{
868 /// Set our attributes
869 fAttributes = attributes;
870}
871
872//_____________________________________________________________________________
873void
8f0acce4 874AliMUONVPainter::SetContour(AliMUONContour* contour)
0145e89a 875{
876 /// Set out contour
877 if (!contour)
878 {
879 AliError(Form("Setting a null contour for painter %s : bad idea !",PathName().Data()));
880 }
881 fContour = contour;
882}
883
884//_____________________________________________________________________________
885void
886AliMUONVPainter::SetData(const char* pattern, AliMUONVTrackerData* data,
887 Int_t dataIndex)
888{
889 /// Tell all painters which type matches pattern that they should
890 /// monitor a given data source
891
892 if ( !fPainterGroups )
893 {
894 CreateGroups();
895 }
896
49419555 897 if ( data )
898 {
899 data->Connect("Destroyed()",ClassName(),this,Form("SetData(=\"%s\",0x0,-1)",pattern));
900 }
901
0145e89a 902 TIter next(fPainterGroups);
903 TObjString* str;
904
905 fPlotterGroup = 0x0;
906
907 while ( ( str = static_cast<TObjString*>(next()) ) )
908 {
909 AliMUONPainterGroup* group = static_cast<AliMUONPainterGroup*>(fPainterGroups->GetValue(str));
10eb3d17 910
0145e89a 911 if ( group->Matches(pattern) )
912 {
913 group->SetData(data,dataIndex);
914 if ( data )
915 {
916 fPlotterGroup = group;
917 }
918 }
919 else
920 {
921 group->SetData(0x0,-1);
922 }
923 }
10eb3d17 924
925 // Update context menus
926 TList list;
927 FlatList(list);
928
929 TIter pnext(&list);
930 AliMUONVPainter* p;
931
932 AliMUONPainterGroup* group = Master()->PlotterGroup();
933
934 while ( ( p = static_cast<AliMUONVPainter*>(pnext()) ) )
935 {
936 TList* l = p->IsA()->GetMenuList();
937
49419555 938 l->Delete();
10eb3d17 939
1ffbeb9d 940 TClassMenuItem* n(0x0);
941
942 l->Add(new TClassMenuItem(TClassMenuItem::kPopupUserFunction,p->IsA(),
943 "Include","Include",p,"",-1,kTRUE));
944 l->Add(new TClassMenuItem(TClassMenuItem::kPopupUserFunction,p->IsA(),
945 "Exclude","Exclude",p,"",-1,kTRUE));
946
947 if ( group )
10eb3d17 948 {
0edb62c4 949 if ( data && data->IsHistogrammed(0) )
950 {
951 // Add histo drawing to the popup menu
952 TString name("Draw histogram of ");
49419555 953
0edb62c4 954 name += data->ExternalDimensionName(0);
955
956 n = new TClassMenuItem(TClassMenuItem::kPopupUserFunction,p->IsA(),
957 name.Data(),"DrawHistogram0",p,"",-1,kTRUE);
958 l->Add(n);
959
960 name += " clone";
961
962 n = new TClassMenuItem(TClassMenuItem::kPopupUserFunction,p->IsA(),
963 name.Data(),"DrawHistogramClone0",p,"",-1,kTRUE);
964 l->Add(n);
10eb3d17 965 }
49419555 966
1ffbeb9d 967 Int_t nd = data->IsSingleEvent() ? data->ExternalDimension() : data->ExternalDimension()*2;
968
969 for ( Int_t i = 0; i < nd; ++i )
49419555 970 {
1ffbeb9d 971 n = new TClassMenuItem(TClassMenuItem::kPopupUserFunction,p->IsA(),
972 Form("Draw %s clone",data->DimensionName(i).Data()),
973 Form("DrawInternalHistogramClone%d",i),p,"",-1,kTRUE);
49419555 974 l->Add(n);
975 }
10eb3d17 976 }
977 }
978}
979
980//_____________________________________________________________________________
981void
49419555 982AliMUONVPainter::DrawInternalHistogram(Int_t dim) const
983{
984 /// Draw histogram (and delete the previous one)
985
986 delete fHistogram;
987 fHistogram = 0x0;
988
989 DrawInternalHistogramClone(dim);
990}
991
992//_____________________________________________________________________________
993void
994AliMUONVPainter::DrawInternalHistogramClone(Int_t dim) const
995{
996 /// Draw histogram
997
998 fHistogram = AliMUONTrackerDataHistogrammer::CreateHisto(*this,-1,dim);
999
1000 if (fHistogram)
1001 {
1002 new TCanvas();
1003 fHistogram->Draw();
1004 }
1005}
1006
1007//_____________________________________________________________________________
1008void
1009AliMUONVPainter::DrawHistogram(Double_t* values) const
10eb3d17 1010{
1011 /// Draw histogram (and delete the previous one)
1012
1013 delete fHistogram;
1014 fHistogram = 0x0;
1015
49419555 1016 DrawHistogramClone(values);
10eb3d17 1017}
1018
1019//_____________________________________________________________________________
1020void
49419555 1021AliMUONVPainter::DrawHistogramClone(Double_t*) const
10eb3d17 1022{
1023 /// Draw histogram
1024
49419555 1025 fHistogram = AliMUONTrackerDataHistogrammer::CreateHisto(*this,0,-1);
10eb3d17 1026
1027 if (fHistogram)
1028 {
1029 new TCanvas();
1030 fHistogram->Draw();
1031 }
1032}
1033
1034//_____________________________________________________________________________
1035void
1036AliMUONVPainter::FillManuList(TObjArray& manuList) const
1037{
1038 /// Append to manulist
1039 /// This is the default implementation, which just calls the FillManuList
1040 /// of all our children.
1041 /// Some derived class might need to override this in order to exclude
1042 /// some children from the fill.
1043
1044 TIter next(Children());
1045
1046 AliMUONVPainter* p;
1047
1048 while ( ( p = static_cast<AliMUONVPainter*>(next()) ) )
1049 {
1050 p->FillManuList(manuList);
1051 }
0145e89a 1052}
1053
1054//_____________________________________________________________________________
1055void
1056AliMUONVPainter::SetLine(Int_t depth, Int_t lineColor, Int_t lineWidth)
1057{
1058 /// Set the line attributes of painters at a given depth
1059 AliMUONPainterGroup* group = Group(depth);
1060 if ( group )
1061 {
1062 group->SetLine(lineColor,lineWidth);
1063 }
1064}
1065
1066//_____________________________________________________________________________
1067void
1068AliMUONVPainter::SetMother(AliMUONVPainter* painter)
1069{
1070 /// Set our mother
1071 fMother = painter;
1072}
1073
1074//_____________________________________________________________________________
1075void
1076AliMUONVPainter::SetOutlined(const char* pattern, Bool_t flag)
1077{
1078 /// Decide whether or not painters which type matches pattern
1079 /// should be outlined
1080
1081 AliDebug(1,Form("pattern=%s flag=%d",pattern,flag));
1082
1083 if (!fPainterGroups)
1084 {
1085 CreateGroups();
1086 }
1087
1088 TIter next(fPainterGroups);
1089 TObjString* str;
1090
1091 while ( ( str = static_cast<TObjString*>(next()) ) )
1092 {
1093 AliMUONPainterGroup* group = static_cast<AliMUONPainterGroup*>(fPainterGroups->GetValue(str));
1094 if ( group->Matches(pattern) )
1095 {
1096 group->SetOutlined(flag);
1097 }
1098 }
1099}
1100
1101//_____________________________________________________________________________
1102void
1103AliMUONVPainter::SetResponder(const char* pattern)
1104{
1105 /// Set the painters matching pattern to be the responder
1106
1107 AliDebug(1,Form("pattern=%s",pattern));
1108
1109 if (!fPainterGroups)
1110 {
1111 CreateGroups();
1112 }
1113
1114 TIter next(fPainterGroups);
1115 TObjString* str;
1116
1117 fResponderGroup = 0x0;
1118
1119 while ( ( str = static_cast<TObjString*>(next()) ) )
1120 {
1121 AliMUONPainterGroup* group = static_cast<AliMUONPainterGroup*>(fPainterGroups->GetValue(str));
1122 if ( group->Matches(pattern) )
1123 {
1124 AliDebug(1,Form("group %s is matching pattern %s : setting to responder",
1125 group->Type(),pattern));
1126 group->SetResponder(kTRUE);
1127 fResponderGroup = group;
1128 }
1129 else
1130 {
1131 group->SetResponder(kFALSE);
1132 }
1133 }
1134}
1135
1136//_____________________________________________________________________________
1137void
1138AliMUONVPainter::SetResponder(Int_t depth)
1139{
1140 /// Select as responder the *first* group that has a given depth
1141
1142 AliDebug(1,Form("depth=%d",depth));
1143
1144 if (!fPainterGroups)
1145 {
1146 CreateGroups();
1147 }
1148
1149 TIter next(fPainterGroups);
1150 TObjString* str;
1151
1152 fResponderGroup = 0x0;
1153
1154 while ( ( str = static_cast<TObjString*>(next()) ) )
1155 {
1156 AliMUONPainterGroup* group = static_cast<AliMUONPainterGroup*>(fPainterGroups->GetValue(str));
1157 if ( group->Depth() == depth )
1158 {
1159 AliDebug(1,Form("group %s has correct depth = %d, using as responder",
1160 group->Type(),depth));
1161 group->SetResponder(kTRUE);
1162 fResponderGroup = group;
1163 break;
1164 }
1165 else
1166 {
1167 group->SetResponder(kFALSE);
1168 }
1169 }
1170}
1171
1172//_____________________________________________________________________________
1173void
1174AliMUONVPainter::SetVisible(const char* pattern, Bool_t flag)
1175{
1176 /// Decide whether the painters matching pattern should be visible or not
1177 AliDebug(1,Form("pattern=%s flag=%d",pattern,flag));
1178
1179 if (!fPainterGroups)
1180 {
1181 CreateGroups();
1182 }
1183
1184 TIter next(fPainterGroups);
1185 TObjString* str;
1186
1187 while ( ( str = static_cast<TObjString*>(next()) ) )
1188 {
1189 AliMUONPainterGroup* group = static_cast<AliMUONPainterGroup*>(fPainterGroups->GetValue(str));
1190 if ( group->Matches(pattern) )
1191 {
1192 group->SetVisible(flag);
1193 }
1194 }
1195}
1196
1197//_____________________________________________________________________________
1198void
1199AliMUONVPainter::UpdateGroupsFrom(const AliMUONVPainter& painter)
1200{
1201 /// (re)Create groups
1202 delete fPainterGroups;
1203 fPainterGroups = 0x0;
1204
1205 CreateGroups();
1206
1207 // and copy the status of responder, plotter and visible
1208 if ( painter.ResponderGroup() )
1209 {
1210 SetResponder(painter.ResponderGroup()->Type());
1211 }
1212
1213 if ( painter.PlotterGroup() )
1214 {
1215 SetData(painter.PlotterGroup()->Type(),
1216 painter.PlotterGroup()->Data(),
1217 painter.PlotterGroup()->DataIndex());
1218 PlotterGroup()->SetDataRange(painter.PlotterGroup()->DataMin(),
1219 painter.PlotterGroup()->DataMax());
1220 }
1221
1222 TObjArray types;
1223 painter.GetTypes(types);
1224 TIter next(&types);
1225 TObjString* groupName;
1226
1227 while ( ( groupName = static_cast<TObjString*>(next()) ) )
1228 {
1229 AliMUONPainterGroup* group = painter.Group(groupName->String().Data());
1230 if ( group->IsVisible() )
1231 {
1232 SetVisible(group->Type(),kTRUE);
1233 }
1234 else
1235 {
1236 SetVisible(group->Type(),kFALSE);
1237 }
1238
1239 if ( group->IsOutlined() )
1240 {
1241 SetOutlined(group->Type(),kTRUE);
1242 }
1243 else
1244 {
1245 SetOutlined(group->Type(),kFALSE);
1246 }
1247
1248 SetLine(group->Depth(),group->GetLineColor(),group->GetLineWidth());
1249 }
1ffbeb9d 1250
1251}
1252
1253//_____________________________________________________________________________
1254void
1255AliMUONVPainter::Include()
1256{
1257 /// Include this painter
1258 AliInfo(GetName());
1259
1260 /// Update the global interactive read out configuration
1261 WriteIROC(1);
1262}
1263
1264//_____________________________________________________________________________
1265void
1266AliMUONVPainter::GetIROCManuList(TObjArray& manuList)
1267{
1268 /// Get the list of manus spanned by this painter AND by its dual
1269
1270 FillManuList(manuList);
1271
1272 // get our dual
1273 AliMUONAttPainter att(Attributes());
1274
1275 att.Invert();
1276
1277 att.SetCathodeAndPlaneDisabled(kTRUE);
1278
1279 AliMUONVPainter* p = AliMUONVPainter::CreatePainter(ClassName(),att,ID0(),ID1());
1280
1281 if (p)
1282 {
1283 p->FillManuList(manuList);
1284 }
1285
1286 delete p;
1287}
1288
1289//_____________________________________________________________________________
1290void
1291AliMUONVPainter::WriteIROC(Double_t value)
1292{
1293 /// Update the interactive readout configuration
1294
1295 TObjArray manuList;
1296 GetIROCManuList(manuList);
1297
1298 AliMpManuUID* muid;
1299 TIter nextm(&manuList);
1300 AliMUON2DMap store(true);
1301
1302 while ((muid=static_cast<AliMpManuUID*>(nextm())))
1303 {
1304 AliMUONVCalibParam* param = new AliMUONCalibParamND(1,64,
1305 muid->DetElemId(),
1306 muid->ManuId(),value);
1307 store.Add(param);
1308 }
1309
1310 InteractiveReadOutConfig()->Replace(store);
1311}
1312
1313//_____________________________________________________________________________
1314void
1315AliMUONVPainter::Exclude()
1316{
1317 /// Exclude this painter
1318 AliInfo(GetName());
1319
1320 /// Update the global interactive read out configuration
1321 WriteIROC(0.0);
1322}
1323
1324//_____________________________________________________________________________
1325AliMUONVTrackerData*
1326AliMUONVPainter::InteractiveReadOutConfig() const
1327{
1328 /// get the interactive readout config object
8f0acce4 1329 return AliMUONPainterDataRegistry::Instance()->InteractiveReadOutConfig();
0145e89a 1330}
1331
1332//_____________________________________________________________________________
1333AliMUONVPainter*
1334AliMUONVPainter::CreatePainter(const char* className,
1335 const AliMUONAttPainter& att,
1336 Int_t id1, Int_t id2)
1337{
1338 /// Create a painter (factory method)
1339
1340 TClass* c = TClass::GetClass(className);
1341
1342 if (!c)
1343 {
1344 AliErrorClass(Form("Cannot get class %s",className));
1345 return 0x0;
1346 }
1347
1348 Int_t n(0);
1349
1350 TMethodCall call;
1351
1352 call.InitWithPrototype(c,className,"AliMUONAttPainter&,Int_t");
1353
1354 if (call.IsValid()) n = 1;
1355 else
1356 {
1357 call.InitWithPrototype(c,className,"AliMUONAttPainter&,Int_t,Int_t");
1358
1359 if ( call.IsValid() ) n = 2;
1360 }
1361
1362 Long_t returnLong(0x0);
1363
1364 if ( n ==1 )
1365 {
1366 Long_t params[] = { (Long_t)(&att), (Long_t)(id1) };
1367 call.SetParamPtrs((void*)(params));
1368 call.Execute((void*)(0x0),returnLong);
1369 }
1370 else if ( n == 2 )
1371 {
1372 Long_t params[] = { (Long_t)(&att), (Long_t)(id1), (Long_t)(id2) };
1373 call.SetParamPtrs((void*)(params));
1374 call.Execute((void*)(0x0),returnLong);
1375 }
1376
1377 if (!returnLong)
1378 {
1379 AliErrorClass(Form("Cannot create a painter of class %s",className));
1380 }
1381
1382 AliMUONVPainter* rv = reinterpret_cast<AliMUONVPainter*> (returnLong);
1383
1384 if (!rv->IsValid())
1385 {
1386 AliErrorClass(Form("Painter of class %s is not valid",className));
1387 delete rv;
1388 rv = 0x0;
1389 }
1390 return rv;
1391}
1392
8f0acce4 1393//_____________________________________________________________________________
1394void
1395AliMUONVPainter::PaintArea(Int_t fillColor)
1396{
ca04ed6c 1397 /// Draw a filled area
8f0acce4 1398 AliMUONContourPainter::Paint(*(Contour()),-1,-1,fillColor);
1399}