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