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