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