]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/AliMUONVPainter.cxx
Coding conventions
[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
6e97fbb8 569
570 AliMpArea area(Area().GetPositionX(),
571 Area().GetPositionY(),
572 Area().GetDimensionX()*fBorderFactor,
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 {
757 fContour->PaintArea(2);
758 fContour->PaintOutline(1,1);
759 }
0145e89a 760}
761
762//_____________________________________________________________________________
763TString
764AliMUONVPainter::Describe(const AliMUONVTrackerData&, Int_t, Double_t, Double_t)
765{
766 /// Default implementation (must be overriden)
767 AliError(Form("%s : implement me",GetName()));
768 return "";
769}
770
771//_____________________________________________________________________________
772void
773AliMUONVPainter::PaintArea(const AliMUONVTrackerData&, Int_t, Double_t, Double_t)
774{
775 /// Default implementation (must be overriden)
776 AliError(Form("%s : implement me",GetName()));
1ffbeb9d 777 return;
0145e89a 778}
779
780//_____________________________________________________________________________
781void
782AliMUONVPainter::PaintOutline(Int_t color, Int_t width, Double_t /*x*/, Double_t /*y*/)
783{
784 /// Default implementation is simply a drawing of the contour lines,
785 /// not using the optional (x,y)
786 Int_t c = color >= 0 ? color : GetLineColor();
787 Int_t w = width >= 0 ? width : GetLineWidth();
788
789 fContour->PaintOutline(c,w);
790}
791
792//_____________________________________________________________________________
793void
794AliMUONVPainter::PixelToPad(Int_t px, Int_t py, Double_t& x, Double_t& y)
795{
796 /// convert (px,py) into pad position (x,y)
797
798 x = gPad->PadtoX(gPad->AbsPixeltoX(px));
799 y = gPad->PadtoY(gPad->AbsPixeltoY(py));
800}
801
802//_____________________________________________________________________________
803void
804AliMUONVPainter::Print(Option_t* opt) const
805{
806 /// Printout
807 for ( Int_t i = 0; i < Depth()*4; ++i )
808 {
809 cout << " ";
810 }
811
812 if ( !IsValid() ) cout << "!!!INVALID!!!" << endl;
813
814 cout << Form("%p Name %s Depth %d ContourName %s ID=(%d,%d)",
815 this,GetName(),Depth(),ContourName().Data(),ID0(),ID1());
816
817 if ( fResponderGroup )
818 {
819 cout << Form(" Responder group %p %s",fResponderGroup,fResponderGroup->Type());
820 }
821 if ( fPlotterGroup )
822 {
823 cout << Form(" Plotter group %p %s",fPlotterGroup,fPlotterGroup->Type());
824 }
825 if ( Mother() )
826 {
827 cout << Form(" Mother %p %s",Mother(),Mother()->GetName());
828 }
829 if ( MotherGroup() )
830 {
831 cout << Form(" Group %p %s ",MotherGroup(),MotherGroup()->Type());
832 }
833
834 if ( fChildren )
835 {
836 cout << Form(" %d children",fChildren->GetLast()+1);
837 }
838
839 cout << endl;
840
841 TString sopt(opt);
842 sopt.ToUpper();
843
844 if ( fChildren && ( sopt == "FULL" || sopt == "CHILD" ) )
845 {
846 TIter next(fChildren);
847 AliMUONVPainter* painter;
848 while ( ( painter = static_cast<AliMUONVPainter*>(next()) ) )
849 {
850 painter->Print(opt);
851 }
852 }
853
854 if ( fPainterGroups && ( sopt == "FULL" || sopt == "GROUP" ) )
855 {
856 TIter next(fPainterGroups);
857 TObjString* groupName;
858 while ( ( groupName = static_cast<TObjString*>(next()) ) )
859 {
860 AliMUONPainterGroup* group = Group(groupName->String().Data());
861 group->Print(opt);
862 }
863 }
864}
865
866//_____________________________________________________________________________
867void
868AliMUONVPainter::SetAttributes(const AliMUONAttPainter& attributes)
869{
870 /// Set our attributes
871 fAttributes = attributes;
872}
873
874//_____________________________________________________________________________
875void
876AliMUONVPainter::SetContour(AliMUONPainterContour* contour)
877{
878 /// Set out contour
879 if (!contour)
880 {
881 AliError(Form("Setting a null contour for painter %s : bad idea !",PathName().Data()));
882 }
883 fContour = contour;
884}
885
886//_____________________________________________________________________________
887void
888AliMUONVPainter::SetData(const char* pattern, AliMUONVTrackerData* data,
889 Int_t dataIndex)
890{
891 /// Tell all painters which type matches pattern that they should
892 /// monitor a given data source
893
894 if ( !fPainterGroups )
895 {
896 CreateGroups();
897 }
898
49419555 899 if ( data )
900 {
901 data->Connect("Destroyed()",ClassName(),this,Form("SetData(=\"%s\",0x0,-1)",pattern));
902 }
903
0145e89a 904 TIter next(fPainterGroups);
905 TObjString* str;
906
907 fPlotterGroup = 0x0;
908
909 while ( ( str = static_cast<TObjString*>(next()) ) )
910 {
911 AliMUONPainterGroup* group = static_cast<AliMUONPainterGroup*>(fPainterGroups->GetValue(str));
10eb3d17 912
0145e89a 913 if ( group->Matches(pattern) )
914 {
915 group->SetData(data,dataIndex);
916 if ( data )
917 {
918 fPlotterGroup = group;
919 }
920 }
921 else
922 {
923 group->SetData(0x0,-1);
924 }
925 }
10eb3d17 926
927 // Update context menus
928 TList list;
929 FlatList(list);
930
931 TIter pnext(&list);
932 AliMUONVPainter* p;
933
934 AliMUONPainterGroup* group = Master()->PlotterGroup();
935
936 while ( ( p = static_cast<AliMUONVPainter*>(pnext()) ) )
937 {
938 TList* l = p->IsA()->GetMenuList();
939
49419555 940 l->Delete();
10eb3d17 941
1ffbeb9d 942 TClassMenuItem* n(0x0);
943
944 l->Add(new TClassMenuItem(TClassMenuItem::kPopupUserFunction,p->IsA(),
945 "Include","Include",p,"",-1,kTRUE));
946 l->Add(new TClassMenuItem(TClassMenuItem::kPopupUserFunction,p->IsA(),
947 "Exclude","Exclude",p,"",-1,kTRUE));
948
949 if ( group )
10eb3d17 950 {
0edb62c4 951 if ( data && data->IsHistogrammed(0) )
952 {
953 // Add histo drawing to the popup menu
954 TString name("Draw histogram of ");
49419555 955
0edb62c4 956 name += data->ExternalDimensionName(0);
957
958 n = new TClassMenuItem(TClassMenuItem::kPopupUserFunction,p->IsA(),
959 name.Data(),"DrawHistogram0",p,"",-1,kTRUE);
960 l->Add(n);
961
962 name += " clone";
963
964 n = new TClassMenuItem(TClassMenuItem::kPopupUserFunction,p->IsA(),
965 name.Data(),"DrawHistogramClone0",p,"",-1,kTRUE);
966 l->Add(n);
10eb3d17 967 }
49419555 968
1ffbeb9d 969 Int_t nd = data->IsSingleEvent() ? data->ExternalDimension() : data->ExternalDimension()*2;
970
971 for ( Int_t i = 0; i < nd; ++i )
49419555 972 {
1ffbeb9d 973 n = new TClassMenuItem(TClassMenuItem::kPopupUserFunction,p->IsA(),
974 Form("Draw %s clone",data->DimensionName(i).Data()),
975 Form("DrawInternalHistogramClone%d",i),p,"",-1,kTRUE);
49419555 976 l->Add(n);
977 }
10eb3d17 978 }
979 }
980}
981
982//_____________________________________________________________________________
983void
49419555 984AliMUONVPainter::DrawInternalHistogram(Int_t dim) const
985{
986 /// Draw histogram (and delete the previous one)
987
988 delete fHistogram;
989 fHistogram = 0x0;
990
991 DrawInternalHistogramClone(dim);
992}
993
994//_____________________________________________________________________________
995void
996AliMUONVPainter::DrawInternalHistogramClone(Int_t dim) const
997{
998 /// Draw histogram
999
1000 fHistogram = AliMUONTrackerDataHistogrammer::CreateHisto(*this,-1,dim);
1001
1002 if (fHistogram)
1003 {
1004 new TCanvas();
1005 fHistogram->Draw();
1006 }
1007}
1008
1009//_____________________________________________________________________________
1010void
1011AliMUONVPainter::DrawHistogram(Double_t* values) const
10eb3d17 1012{
1013 /// Draw histogram (and delete the previous one)
1014
1015 delete fHistogram;
1016 fHistogram = 0x0;
1017
49419555 1018 DrawHistogramClone(values);
10eb3d17 1019}
1020
1021//_____________________________________________________________________________
1022void
49419555 1023AliMUONVPainter::DrawHistogramClone(Double_t*) const
10eb3d17 1024{
1025 /// Draw histogram
1026
49419555 1027 fHistogram = AliMUONTrackerDataHistogrammer::CreateHisto(*this,0,-1);
10eb3d17 1028
1029 if (fHistogram)
1030 {
1031 new TCanvas();
1032 fHistogram->Draw();
1033 }
1034}
1035
1036//_____________________________________________________________________________
1037void
1038AliMUONVPainter::FillManuList(TObjArray& manuList) const
1039{
1040 /// Append to manulist
1041 /// This is the default implementation, which just calls the FillManuList
1042 /// of all our children.
1043 /// Some derived class might need to override this in order to exclude
1044 /// some children from the fill.
1045
1046 TIter next(Children());
1047
1048 AliMUONVPainter* p;
1049
1050 while ( ( p = static_cast<AliMUONVPainter*>(next()) ) )
1051 {
1052 p->FillManuList(manuList);
1053 }
0145e89a 1054}
1055
1056//_____________________________________________________________________________
1057void
1058AliMUONVPainter::SetLine(Int_t depth, Int_t lineColor, Int_t lineWidth)
1059{
1060 /// Set the line attributes of painters at a given depth
1061 AliMUONPainterGroup* group = Group(depth);
1062 if ( group )
1063 {
1064 group->SetLine(lineColor,lineWidth);
1065 }
1066}
1067
1068//_____________________________________________________________________________
1069void
1070AliMUONVPainter::SetMother(AliMUONVPainter* painter)
1071{
1072 /// Set our mother
1073 fMother = painter;
1074}
1075
1076//_____________________________________________________________________________
1077void
1078AliMUONVPainter::SetOutlined(const char* pattern, Bool_t flag)
1079{
1080 /// Decide whether or not painters which type matches pattern
1081 /// should be outlined
1082
1083 AliDebug(1,Form("pattern=%s flag=%d",pattern,flag));
1084
1085 if (!fPainterGroups)
1086 {
1087 CreateGroups();
1088 }
1089
1090 TIter next(fPainterGroups);
1091 TObjString* str;
1092
1093 while ( ( str = static_cast<TObjString*>(next()) ) )
1094 {
1095 AliMUONPainterGroup* group = static_cast<AliMUONPainterGroup*>(fPainterGroups->GetValue(str));
1096 if ( group->Matches(pattern) )
1097 {
1098 group->SetOutlined(flag);
1099 }
1100 }
1101}
1102
1103//_____________________________________________________________________________
1104void
1105AliMUONVPainter::SetResponder(const char* pattern)
1106{
1107 /// Set the painters matching pattern to be the responder
1108
1109 AliDebug(1,Form("pattern=%s",pattern));
1110
1111 if (!fPainterGroups)
1112 {
1113 CreateGroups();
1114 }
1115
1116 TIter next(fPainterGroups);
1117 TObjString* str;
1118
1119 fResponderGroup = 0x0;
1120
1121 while ( ( str = static_cast<TObjString*>(next()) ) )
1122 {
1123 AliMUONPainterGroup* group = static_cast<AliMUONPainterGroup*>(fPainterGroups->GetValue(str));
1124 if ( group->Matches(pattern) )
1125 {
1126 AliDebug(1,Form("group %s is matching pattern %s : setting to responder",
1127 group->Type(),pattern));
1128 group->SetResponder(kTRUE);
1129 fResponderGroup = group;
1130 }
1131 else
1132 {
1133 group->SetResponder(kFALSE);
1134 }
1135 }
1136}
1137
1138//_____________________________________________________________________________
1139void
1140AliMUONVPainter::SetResponder(Int_t depth)
1141{
1142 /// Select as responder the *first* group that has a given depth
1143
1144 AliDebug(1,Form("depth=%d",depth));
1145
1146 if (!fPainterGroups)
1147 {
1148 CreateGroups();
1149 }
1150
1151 TIter next(fPainterGroups);
1152 TObjString* str;
1153
1154 fResponderGroup = 0x0;
1155
1156 while ( ( str = static_cast<TObjString*>(next()) ) )
1157 {
1158 AliMUONPainterGroup* group = static_cast<AliMUONPainterGroup*>(fPainterGroups->GetValue(str));
1159 if ( group->Depth() == depth )
1160 {
1161 AliDebug(1,Form("group %s has correct depth = %d, using as responder",
1162 group->Type(),depth));
1163 group->SetResponder(kTRUE);
1164 fResponderGroup = group;
1165 break;
1166 }
1167 else
1168 {
1169 group->SetResponder(kFALSE);
1170 }
1171 }
1172}
1173
1174//_____________________________________________________________________________
1175void
1176AliMUONVPainter::SetVisible(const char* pattern, Bool_t flag)
1177{
1178 /// Decide whether the painters matching pattern should be visible or not
1179 AliDebug(1,Form("pattern=%s flag=%d",pattern,flag));
1180
1181 if (!fPainterGroups)
1182 {
1183 CreateGroups();
1184 }
1185
1186 TIter next(fPainterGroups);
1187 TObjString* str;
1188
1189 while ( ( str = static_cast<TObjString*>(next()) ) )
1190 {
1191 AliMUONPainterGroup* group = static_cast<AliMUONPainterGroup*>(fPainterGroups->GetValue(str));
1192 if ( group->Matches(pattern) )
1193 {
1194 group->SetVisible(flag);
1195 }
1196 }
1197}
1198
1199//_____________________________________________________________________________
1200void
1201AliMUONVPainter::UpdateGroupsFrom(const AliMUONVPainter& painter)
1202{
1203 /// (re)Create groups
1204 delete fPainterGroups;
1205 fPainterGroups = 0x0;
1206
1207 CreateGroups();
1208
1209 // and copy the status of responder, plotter and visible
1210 if ( painter.ResponderGroup() )
1211 {
1212 SetResponder(painter.ResponderGroup()->Type());
1213 }
1214
1215 if ( painter.PlotterGroup() )
1216 {
1217 SetData(painter.PlotterGroup()->Type(),
1218 painter.PlotterGroup()->Data(),
1219 painter.PlotterGroup()->DataIndex());
1220 PlotterGroup()->SetDataRange(painter.PlotterGroup()->DataMin(),
1221 painter.PlotterGroup()->DataMax());
1222 }
1223
1224 TObjArray types;
1225 painter.GetTypes(types);
1226 TIter next(&types);
1227 TObjString* groupName;
1228
1229 while ( ( groupName = static_cast<TObjString*>(next()) ) )
1230 {
1231 AliMUONPainterGroup* group = painter.Group(groupName->String().Data());
1232 if ( group->IsVisible() )
1233 {
1234 SetVisible(group->Type(),kTRUE);
1235 }
1236 else
1237 {
1238 SetVisible(group->Type(),kFALSE);
1239 }
1240
1241 if ( group->IsOutlined() )
1242 {
1243 SetOutlined(group->Type(),kTRUE);
1244 }
1245 else
1246 {
1247 SetOutlined(group->Type(),kFALSE);
1248 }
1249
1250 SetLine(group->Depth(),group->GetLineColor(),group->GetLineWidth());
1251 }
1ffbeb9d 1252
1253}
1254
1255//_____________________________________________________________________________
1256void
1257AliMUONVPainter::Include()
1258{
1259 /// Include this painter
1260 AliInfo(GetName());
1261
1262 /// Update the global interactive read out configuration
1263 WriteIROC(1);
1264}
1265
1266//_____________________________________________________________________________
1267void
1268AliMUONVPainter::GetIROCManuList(TObjArray& manuList)
1269{
1270 /// Get the list of manus spanned by this painter AND by its dual
1271
1272 FillManuList(manuList);
1273
1274 // get our dual
1275 AliMUONAttPainter att(Attributes());
1276
1277 att.Invert();
1278
1279 att.SetCathodeAndPlaneDisabled(kTRUE);
1280
1281 AliMUONVPainter* p = AliMUONVPainter::CreatePainter(ClassName(),att,ID0(),ID1());
1282
1283 if (p)
1284 {
1285 p->FillManuList(manuList);
1286 }
1287
1288 delete p;
1289}
1290
1291//_____________________________________________________________________________
1292void
1293AliMUONVPainter::WriteIROC(Double_t value)
1294{
1295 /// Update the interactive readout configuration
1296
1297 TObjArray manuList;
1298 GetIROCManuList(manuList);
1299
1300 AliMpManuUID* muid;
1301 TIter nextm(&manuList);
1302 AliMUON2DMap store(true);
1303
1304 while ((muid=static_cast<AliMpManuUID*>(nextm())))
1305 {
1306 AliMUONVCalibParam* param = new AliMUONCalibParamND(1,64,
1307 muid->DetElemId(),
1308 muid->ManuId(),value);
1309 store.Add(param);
1310 }
1311
1312 InteractiveReadOutConfig()->Replace(store);
1313}
1314
1315//_____________________________________________________________________________
1316void
1317AliMUONVPainter::Exclude()
1318{
1319 /// Exclude this painter
1320 AliInfo(GetName());
1321
1322 /// Update the global interactive read out configuration
1323 WriteIROC(0.0);
1324}
1325
1326//_____________________________________________________________________________
1327AliMUONVTrackerData*
1328AliMUONVPainter::InteractiveReadOutConfig() const
1329{
1330 /// get the interactive readout config object
1331 return AliMUONPainterRegistry::Instance()->InteractiveReadOutConfig();
0145e89a 1332}
1333
1334//_____________________________________________________________________________
1335AliMUONVPainter*
1336AliMUONVPainter::CreatePainter(const char* className,
1337 const AliMUONAttPainter& att,
1338 Int_t id1, Int_t id2)
1339{
1340 /// Create a painter (factory method)
1341
1342 TClass* c = TClass::GetClass(className);
1343
1344 if (!c)
1345 {
1346 AliErrorClass(Form("Cannot get class %s",className));
1347 return 0x0;
1348 }
1349
1350 Int_t n(0);
1351
1352 TMethodCall call;
1353
1354 call.InitWithPrototype(c,className,"AliMUONAttPainter&,Int_t");
1355
1356 if (call.IsValid()) n = 1;
1357 else
1358 {
1359 call.InitWithPrototype(c,className,"AliMUONAttPainter&,Int_t,Int_t");
1360
1361 if ( call.IsValid() ) n = 2;
1362 }
1363
1364 Long_t returnLong(0x0);
1365
1366 if ( n ==1 )
1367 {
1368 Long_t params[] = { (Long_t)(&att), (Long_t)(id1) };
1369 call.SetParamPtrs((void*)(params));
1370 call.Execute((void*)(0x0),returnLong);
1371 }
1372 else if ( n == 2 )
1373 {
1374 Long_t params[] = { (Long_t)(&att), (Long_t)(id1), (Long_t)(id2) };
1375 call.SetParamPtrs((void*)(params));
1376 call.Execute((void*)(0x0),returnLong);
1377 }
1378
1379 if (!returnLong)
1380 {
1381 AliErrorClass(Form("Cannot create a painter of class %s",className));
1382 }
1383
1384 AliMUONVPainter* rv = reinterpret_cast<AliMUONVPainter*> (returnLong);
1385
1386 if (!rv->IsValid())
1387 {
1388 AliErrorClass(Form("Painter of class %s is not valid",className));
1389 delete rv;
1390 rv = 0x0;
1391 }
1392 return rv;
1393}
1394