]>
Commit | Line | Data |
---|---|---|
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 | ||
20 | #include "AliMUONObjectPair.h" | |
21 | #include "AliMUONPainterContour.h" | |
22 | #include "AliMUONPainterGroup.h" | |
23 | #include "AliMUONPainterHelper.h" | |
24 | #include "AliMUONVTrackerData.h" | |
25 | #include "AliCodeTimer.h" | |
26 | #include "AliLog.h" | |
27 | #include <Riostream.h> | |
28 | #include <TCanvas.h> | |
29 | #include <TClass.h> | |
30 | #include <TClass.h> | |
31 | #include <TList.h> | |
32 | #include <TMap.h> | |
33 | #include <TMath.h> | |
34 | #include <TMethodCall.h> | |
35 | #include <TObjArray.h> | |
36 | #include <TObjString.h> | |
37 | #include <TROOT.h> | |
38 | #include <TVirtualPad.h> | |
39 | #include <cassert> | |
40 | #include <float.h> | |
41 | ||
42 | ||
43 | /// \class AliMUONVPainter | |
44 | /// | |
45 | /// Base class for a graphical object representing some part of the | |
46 | /// MUON tracking system. | |
47 | /// | |
48 | /// A painter is a graphical representation of some part (e.g. detection element, | |
49 | /// full chamber, one manu, etc...) of the MUON tracking system. | |
50 | /// | |
51 | /// A painter is a double fold hierarchical structure. | |
52 | /// | |
53 | /// First, a painter is part of a tree (mother->childrens), that describe | |
54 | /// the natural organization of the spectrometer. For instance, a chamber | |
55 | /// painter has children that are the detection element, the detection elements | |
56 | /// themselves contain manus, which in turn contain channels. | |
57 | /// | |
58 | /// Second, a painter contains a number of "painter groups" (see AliMUONPainterGroup). | |
59 | /// A group gather all the painters of the same type, | |
60 | /// where the type is a string identifying which part of system we're dealing | |
61 | /// with (chamber, DE, manu, etc...) | |
62 | /// | |
63 | /// The groups are there to ease the manipulation of similar painters, e.g. if | |
64 | /// we want to hide all detection elements, we hide the "detection element group" | |
65 | /// Some special groups are the responder and the plotter groups. The responder | |
66 | /// group is the group which is currently responding to mouse events. | |
67 | /// The plotter group is the group which is supposed to represent some data. | |
68 | /// | |
69 | /// There are two ways to represent the painter on screen. In any case, we can | |
70 | /// outline the painter (i.e. draw its borders) (see AliMUONVPainter::PaintOutline). | |
71 | /// In the cases where the painter is attached to some data source (i.e. it is | |
72 | /// used to represent some data about its type, e.g. the mean charge on some manu), | |
73 | /// we can draw the full area of the contour, using some color (see | |
74 | /// AliMUONVPainter::PaintArea). | |
75 | /// | |
76 | /// Note that you can outline several types of painters (aka groups) at the same | |
77 | /// time, but you cannot plot several groups at the same time. | |
78 | /// | |
79 | /// Painters are TQObject so they can emit signals. | |
80 | /// | |
81 | /// Currently emitted signal are : | |
82 | /// | |
83 | /// void Clicked(AliMUONVPainter* painter, Double_t*); | |
84 | /// DoubleClicked(AliMUONVPainter* painter, Double_t*); | |
85 | /// | |
86 | /// to know which and where a painter was (double-) clicked. | |
87 | /// | |
88 | /// \author Laurent Aphecetche, Subatech | |
89 | ||
90 | ///\cond CLASSIMP | |
91 | ClassImp(AliMUONVPainter) | |
92 | ///\endcond | |
93 | ||
94 | //_____________________________________________________________________________ | |
95 | AliMUONVPainter::AliMUONVPainter(const char* type) | |
96 | : TObject(), | |
97 | fName(""), | |
98 | fPathName(""), | |
99 | fType(type), | |
100 | fMother(0x0), | |
101 | fGroup(0x0), | |
102 | fContour(0x0), | |
103 | fPainterGroups(0x0), | |
104 | fChildren(0x0), | |
105 | fResponderGroup(0x0), | |
106 | fPlotterGroup(0x0), | |
107 | fBorderFactor(1.1), | |
108 | fPad(0x0), | |
109 | fAttributes(), | |
110 | fLineColor(1), | |
111 | fLineWidth(1), | |
112 | fIsValid(kTRUE) | |
113 | { | |
114 | /// ctor | |
115 | SetID(-1,-1); | |
116 | } | |
117 | ||
118 | //_____________________________________________________________________________ | |
119 | AliMUONVPainter::AliMUONVPainter(const AliMUONVPainter& rhs) | |
120 | : TObject(rhs), | |
121 | fName(""), | |
122 | fPathName(""), | |
123 | fType(""), | |
124 | fMother(0x0), | |
125 | fGroup(0x0), | |
126 | fContour(0x0), | |
127 | fPainterGroups(0x0), | |
128 | fChildren(0x0), | |
129 | fResponderGroup(0x0), | |
130 | fPlotterGroup(0x0), | |
131 | fBorderFactor(1.0), | |
132 | fPad(0x0), | |
133 | fAttributes(), | |
134 | fLineColor(-1), | |
135 | fLineWidth(-1), | |
136 | fIsValid(kTRUE) | |
137 | { | |
138 | /// copy ctor | |
139 | rhs.Copy(*this); | |
140 | } | |
141 | ||
142 | //_____________________________________________________________________________ | |
143 | AliMUONVPainter& | |
144 | AliMUONVPainter::operator=(const AliMUONVPainter& rhs) | |
145 | { | |
146 | /// assignment operator | |
147 | if ( this != &rhs ) | |
148 | { | |
149 | rhs.Copy(*this); | |
150 | } | |
151 | return *this; | |
152 | } | |
153 | ||
154 | //_____________________________________________________________________________ | |
155 | AliMUONVPainter::~AliMUONVPainter() | |
156 | { | |
157 | /// dtor | |
158 | delete fChildren; | |
159 | } | |
160 | ||
161 | //_____________________________________________________________________________ | |
162 | AliMpArea | |
163 | AliMUONVPainter::Area() const | |
164 | { | |
165 | /// Return the area covered by this painter | |
166 | if ( fContour ) | |
167 | { | |
168 | return fContour->Area(); | |
169 | } | |
170 | else | |
171 | { | |
172 | AliWarning("Returning an invalid area, as contour is not defined"); | |
173 | return AliMpArea(); | |
174 | } | |
175 | } | |
176 | ||
177 | //_____________________________________________________________________________ | |
178 | void | |
179 | AliMUONVPainter::Add(AliMUONVPainter* painter) | |
180 | { | |
181 | /// Add a child painter | |
182 | if (!fChildren) fChildren = new TObjArray; | |
183 | assert(painter->Mother()==0x0); | |
184 | fChildren->Add(painter); | |
185 | painter->SetMother(this); | |
186 | } | |
187 | ||
188 | //_____________________________________________________________________________ | |
189 | TCollection* | |
190 | AliMUONVPainter::Children() const | |
191 | { | |
192 | /// Return the list of childrens | |
193 | return fChildren; | |
194 | } | |
195 | ||
196 | //_____________________________________________________________________________ | |
197 | void | |
198 | AliMUONVPainter::Clicked(AliMUONVPainter* painter, Double_t* values) | |
199 | { | |
9016a84e | 200 | /// Let our mother emit the signal as clients are probably connected to |
201 | /// our (grand)mother, not to us | |
0145e89a | 202 | |
203 | if ( Mother() ) | |
204 | { | |
205 | Mother()->Clicked(painter,values); | |
206 | } | |
207 | else | |
208 | { | |
209 | Long_t param[] = { (Long_t)painter,(Long_t)values }; | |
210 | ||
211 | Emit("Clicked(AliMUONVPainter*,Double_t*)",param); | |
212 | } | |
213 | } | |
214 | ||
215 | //_____________________________________________________________________________ | |
216 | void | |
217 | AliMUONVPainter::ShiftClicked(AliMUONVPainter* painter, Double_t* values) | |
218 | { | |
9016a84e | 219 | /// Let our mother emit the signal as clients are probably connected to |
220 | /// our (grand)mother, not to us | |
0145e89a | 221 | |
222 | if ( Mother() ) | |
223 | { | |
224 | Mother()->ShiftClicked(painter,values); | |
225 | } | |
226 | else | |
227 | { | |
228 | Long_t param[] = { (Long_t)painter,(Long_t)values }; | |
229 | ||
230 | Emit("ShiftClicked(AliMUONVPainter*,Double_t*)",param); | |
231 | } | |
232 | } | |
233 | ||
234 | //_____________________________________________________________________________ | |
235 | void | |
236 | AliMUONVPainter::ComputeDataRange(const AliMUONVTrackerData&, Int_t, | |
237 | Double_t&, Double_t&) const | |
238 | { | |
239 | /// Should compute the min and max of a given data source | |
240 | AliError("Not implemented. Please fixe me"); | |
241 | } | |
242 | ||
243 | //_____________________________________________________________________________ | |
244 | TString | |
245 | AliMUONVPainter::ContourName() const | |
246 | { | |
247 | /// Default implementation of the contour name. | |
248 | ||
249 | TString name(PathName()); | |
250 | ||
251 | name += "-"; | |
252 | name += fAttributes.Name(); | |
253 | ||
254 | return name; | |
255 | } | |
256 | ||
257 | //_____________________________________________________________________________ | |
258 | void | |
259 | AliMUONVPainter::Copy(TObject& object) const | |
260 | { | |
261 | /// Copy this to object. | |
262 | ||
263 | TObject::Copy(object); | |
264 | ||
265 | AliMUONVPainter& painter = static_cast<AliMUONVPainter&>(object); | |
266 | ||
267 | painter.fType = fType; | |
268 | painter.fName = fName; | |
269 | painter.fPathName = fPathName; | |
270 | ||
271 | painter.fMother = 0x0; | |
272 | painter.fContour = fContour; | |
273 | ||
274 | painter.fGroup = 0x0; | |
275 | painter.fResponderGroup = 0x0; | |
276 | painter.fPlotterGroup = 0x0; | |
277 | ||
278 | painter.fBorderFactor = fBorderFactor; | |
279 | ||
280 | painter.fAttributes = fAttributes; | |
281 | ||
282 | painter.fAttributes.SetCathodeAndPlaneDisabled(kFALSE); | |
283 | ||
284 | painter.fPad = fPad; | |
285 | ||
286 | painter.fLineColor = fLineColor; | |
287 | painter.fLineWidth = fLineWidth; | |
288 | ||
289 | painter.fIsValid = fIsValid; | |
290 | ||
291 | delete painter.fChildren; | |
292 | painter.fChildren = 0x0; | |
293 | ||
294 | painter.fID[0] = fID[0]; | |
295 | painter.fID[1] = fID[1]; | |
296 | ||
297 | TIter next(fChildren); | |
298 | AliMUONVPainter* p; | |
299 | ||
300 | while ( ( p = static_cast<AliMUONVPainter*>(next()) ) ) | |
301 | { | |
302 | painter.Add(static_cast<AliMUONVPainter*>(p->Clone())); | |
303 | } | |
304 | ||
305 | painter.UpdateGroupsFrom(*this); | |
306 | ||
307 | object.ResetBit(kCanDelete); | |
308 | } | |
309 | ||
310 | //_____________________________________________________________________________ | |
311 | AliMUONPainterGroup* | |
312 | AliMUONVPainter::CreateGroup(const char* type, Int_t depth) | |
313 | { | |
314 | /// Create a painter group at a given depth | |
315 | ||
316 | if (!fPainterGroups) fPainterGroups = new TMap; | |
317 | TObject* o = fPainterGroups->GetValue(type); | |
318 | if (o) | |
319 | { | |
320 | AliError(Form("Group %s is already there ! Check this",type)); | |
321 | return 0x0; | |
322 | } | |
323 | AliMUONPainterGroup* group = new AliMUONPainterGroup(type,depth); | |
324 | fPainterGroups->Add(new TObjString(type),group); | |
325 | return group; | |
326 | } | |
327 | ||
328 | //_____________________________________________________________________________ | |
329 | void | |
330 | AliMUONVPainter::CreateGroups() | |
331 | { | |
332 | /// Groups our children into groups | |
333 | ||
334 | if ( Mother() ) | |
335 | { | |
336 | AliFatal("Not supposed to create groups for a children"); | |
337 | } | |
338 | ||
339 | TList list; | |
340 | FlatList(list); | |
341 | ||
342 | TIter next(&list); | |
343 | AliMUONVPainter* painter; | |
344 | ||
345 | while ( ( painter = static_cast<AliMUONVPainter*>(next()) ) ) | |
346 | { | |
347 | AliMUONPainterGroup* group = Group(painter->Type()); | |
348 | if (!group) | |
349 | { | |
350 | group = CreateGroup(painter->Type(),painter->Depth()); | |
351 | } | |
352 | group->Add(painter); | |
353 | } | |
354 | } | |
355 | ||
356 | //_____________________________________________________________________________ | |
357 | AliMUONVPainter* | |
358 | AliMUONVPainter::Detach() const | |
359 | { | |
360 | /// Make this a new top painter (i.e. a master) | |
361 | ||
362 | AliDebug(1,Form("Detaching %s",GetName())); | |
363 | ||
364 | AliMUONVPainter* p = static_cast<AliMUONVPainter*>(Clone()); | |
365 | ||
366 | AliMUONVPainter* master = Master(); | |
367 | ||
368 | if ( master ) | |
369 | { | |
370 | AliDebug(1,Form("UpdatingGroups of the detached painter %s from its master %s", | |
371 | p->GetName(),master->GetName())); | |
372 | p->UpdateGroupsFrom(*master); | |
373 | } | |
374 | ||
375 | return p; | |
376 | } | |
377 | ||
378 | //_____________________________________________________________________________ | |
379 | Int_t | |
380 | AliMUONVPainter::Depth() const | |
381 | { | |
382 | /// Return our depth in the hierarchy | |
383 | ||
384 | if ( Mother() ) | |
385 | { | |
386 | return Mother()->Depth() + 1; | |
387 | } | |
388 | else | |
389 | { | |
390 | return 0; | |
391 | } | |
392 | } | |
393 | ||
394 | //_____________________________________________________________________________ | |
395 | Int_t | |
396 | AliMUONVPainter::DistancetoPrimitive(Int_t px, Int_t py) | |
397 | { | |
398 | /// See TObject::DistancetoPrimitive | |
399 | ||
400 | static const Int_t kBigValue = 999999; | |
401 | ||
402 | if (!gPad) return kBigValue; | |
403 | ||
404 | Double_t x,y; | |
405 | ||
406 | AliMUONVPainter* painter = GetPainter(px,py,x,y); | |
407 | ||
408 | x=y=0.0; // to avoid compiler warning | |
409 | ||
410 | if ( painter == this) return 0; | |
411 | ||
412 | return kBigValue; | |
413 | } | |
414 | ||
415 | //_____________________________________________________________________________ | |
416 | void | |
417 | AliMUONVPainter::DoubleClicked(AliMUONVPainter*, Double_t*) | |
418 | { | |
419 | /// Should emit the DoubleClicked signal (if I knew how to detect those events...) | |
420 | ||
421 | AliWarning("Please implement me !"); | |
422 | ||
423 | // if ( fMother ) | |
424 | // { | |
425 | // // let our top mother emit the signal as clients are probably connected to | |
426 | // // our mother, not to us | |
427 | // Top()->DoubleClicked(painter,values); | |
428 | // } | |
429 | // else | |
430 | // { | |
431 | // Long_t param[] = { (Long_t)painter,(Long_t)values }; | |
432 | // | |
433 | // Emit("DoubleClicked(AliMUONVPainter*,Double_t*)",param); | |
434 | // } | |
435 | } | |
436 | ||
437 | //_____________________________________________________________________________ | |
438 | void | |
439 | AliMUONVPainter::Draw(Option_t* opt) | |
440 | { | |
441 | /// Append ourselves to the current pad | |
442 | ||
443 | if (!gPad) | |
444 | { | |
445 | gROOT->MakeDefCanvas(); | |
446 | } | |
447 | ||
448 | Bool_t kMustSetRange(kFALSE); | |
449 | ||
450 | TString sopt(opt); | |
451 | sopt.ToUpper(); | |
452 | ||
453 | if (sopt.Contains("R") ) kMustSetRange=kTRUE; | |
454 | ||
455 | if (kMustSetRange) | |
456 | { | |
457 | Double_t x1,y1,x2,y2; | |
458 | GetBoundingBox(x1,y1,x2,y2); | |
459 | if ( gPad) gPad->Range(x1,y1,x2,y2); | |
460 | } | |
461 | ||
462 | if ( !fMother && !fPainterGroups ) | |
463 | { | |
464 | CreateGroups(); | |
465 | } | |
466 | ||
467 | TIter next(fChildren); | |
468 | AliMUONVPainter* painter; | |
469 | while ( ( painter = static_cast<AliMUONVPainter*>(next()) ) ) | |
470 | { | |
471 | painter->Draw(); | |
472 | } | |
473 | ||
474 | AppendPad(opt); | |
475 | ||
476 | fPad = gPad; | |
477 | } | |
478 | ||
479 | //_____________________________________________________________________________ | |
480 | void | |
481 | AliMUONVPainter::ExecuteEvent(Int_t event, Int_t px, Int_t py) | |
482 | { | |
483 | /// Handle graphics events | |
484 | ||
485 | Double_t x,y; | |
486 | ||
487 | AliMUONVPainter* painter = GetPainter(px,py,x,y); | |
488 | ||
489 | if ( painter == this ) | |
490 | { | |
491 | Double_t values[] = { x,y }; | |
492 | ||
493 | switch (event) | |
494 | { | |
495 | case kButton2Up: | |
496 | ShiftClicked(this,values); | |
497 | break; | |
498 | case kButton1Up: | |
499 | Clicked(this,values); | |
500 | break; | |
501 | case kButton1Double: | |
502 | //the following statement is required against other loop executions before returning (depending on the time between the clicks) | |
503 | gPad->GetCanvas()->HandleInput((EEventType)-1,0,0); | |
504 | DoubleClicked(this,values); | |
505 | break; | |
506 | } | |
507 | } | |
508 | } | |
509 | ||
510 | //_____________________________________________________________________________ | |
511 | void | |
512 | AliMUONVPainter::FlatList(TList& list) | |
513 | { | |
514 | /// Make a flat list of our children | |
515 | ||
516 | TIter next(fChildren); | |
517 | AliMUONVPainter* painter; | |
518 | while ( ( painter = static_cast<AliMUONVPainter*>(next()))) | |
519 | { | |
520 | painter->FlatList(list); | |
521 | } | |
522 | ||
523 | list.Add(this); | |
524 | } | |
525 | ||
526 | //_____________________________________________________________________________ | |
527 | void | |
528 | AliMUONVPainter::GetBoundingBox(Double_t& x1, Double_t& y1, | |
529 | Double_t& x2, Double_t& y2) const | |
530 | { | |
531 | /// Get the bounding box = our area | |
532 | AliMpArea area(Area().Position(),Area().Dimensions()*fBorderFactor); | |
533 | ||
534 | x1 = area.LeftBorder(); | |
535 | y1 = area.DownBorder(); | |
536 | x2 = area.RightBorder(); | |
537 | y2 = area.UpBorder(); | |
538 | } | |
539 | ||
540 | //_____________________________________________________________________________ | |
541 | char* | |
542 | AliMUONVPainter::GetObjectInfo(Int_t, Int_t) const | |
543 | { | |
544 | /// See TObject::GetObjectInfo | |
545 | return const_cast<char*>(GetName()); | |
546 | } | |
547 | ||
548 | //_____________________________________________________________________________ | |
549 | AliMUONVPainter* | |
550 | AliMUONVPainter::GetPainter(Int_t px, Int_t py, Double_t& x, Double_t& y) const | |
551 | { | |
552 | /// Get the responder painter at integer position (px,py), and get back its | |
553 | /// absolute position (x,y) | |
554 | ||
555 | PixelToPad(px,py,x,y); | |
556 | ||
557 | if ( !IsInside(x,y) ) return 0x0; | |
558 | ||
559 | if ( fGroup->IsResponder() ) return const_cast<AliMUONVPainter*>(this); | |
560 | ||
561 | if (fChildren) | |
562 | { | |
563 | TIter next(fChildren); | |
564 | AliMUONVPainter* painter; | |
565 | ||
566 | while ( ( painter = static_cast<AliMUONVPainter*>(next()) ) ) | |
567 | { | |
568 | AliMUONVPainter* p = painter->GetPainter(px,py,x,y); | |
569 | if (p) return p; | |
570 | } | |
571 | } | |
572 | ||
573 | return 0x0; | |
574 | } | |
575 | ||
576 | //_____________________________________________________________________________ | |
577 | void | |
578 | AliMUONVPainter::GetTypes(TObjArray& types) const | |
579 | { | |
580 | /// Get the list of types (as a TObjArray of TObjString) | |
581 | /// of our hierarchy, sorted alphabetically | |
582 | ||
583 | types.SetOwner(kTRUE); | |
584 | types.Clear(); | |
585 | ||
586 | TObjArray tmp; | |
587 | tmp.SetOwner(kFALSE); | |
588 | ||
589 | TIter next(fPainterGroups); | |
590 | ||
591 | TObjString* str; | |
592 | while ( ( str = static_cast<TObjString*>(next()) ) ) | |
593 | { | |
594 | AliMUONPainterGroup* group = Group(str->String().Data()); | |
595 | tmp.AddLast(group); | |
596 | } | |
597 | ||
598 | tmp.Sort(); | |
599 | ||
600 | Int_t n = tmp.GetLast()+1; | |
601 | ||
602 | Int_t* index = new Int_t[n]; | |
603 | ||
604 | Int_t* a = new Int_t[n]; | |
605 | ||
606 | for ( Int_t i = 0; i < n; ++i ) | |
607 | { | |
608 | AliMUONPainterGroup* group = static_cast<AliMUONPainterGroup*>(tmp.At(i)); | |
609 | a[i] = group->Depth(); | |
610 | } | |
611 | ||
612 | TMath::Sort(n,a,index,kFALSE); | |
613 | ||
614 | for ( Int_t i = 0; i < n; ++i ) | |
615 | { | |
616 | AliMUONPainterGroup* group = static_cast<AliMUONPainterGroup*>(tmp.At(index[i])); | |
617 | types.AddLast(new TObjString(group->Type())); | |
618 | } | |
619 | ||
620 | delete[] index; | |
621 | delete[] a; | |
622 | } | |
623 | ||
624 | //_____________________________________________________________________________ | |
625 | AliMUONPainterGroup* | |
626 | AliMUONVPainter::Group(const char* type) const | |
627 | { | |
628 | /// Returns a group of a given type | |
629 | if (!fPainterGroups) return 0x0; | |
630 | return static_cast<AliMUONPainterGroup*>(fPainterGroups->GetValue(type)); | |
631 | } | |
632 | ||
633 | //_____________________________________________________________________________ | |
634 | AliMUONPainterGroup* | |
635 | AliMUONVPainter::Group(Int_t depth) const | |
636 | { | |
637 | /// Returns a group of a given depth | |
638 | if (!fPainterGroups) return 0x0; | |
639 | TIter next(fPainterGroups); | |
640 | TObjString* groupName; | |
641 | while ( ( groupName = static_cast<TObjString*>(next()) ) ) | |
642 | { | |
643 | AliMUONPainterGroup* group = static_cast<AliMUONPainterGroup*> | |
644 | (fPainterGroups->GetValue(groupName->String().Data())); | |
645 | if ( group->Depth() == depth ) | |
646 | { | |
647 | return group; | |
648 | } | |
649 | } | |
650 | return 0x0; | |
651 | } | |
652 | ||
653 | //_____________________________________________________________________________ | |
654 | Bool_t | |
655 | AliMUONVPainter::IsInside(Double_t x, Double_t y) const | |
656 | { | |
657 | /// Whether point (x,y) is inside our contour | |
658 | if (!fContour) return kFALSE; | |
659 | return fContour->IsInside(x,y); | |
660 | } | |
661 | ||
662 | //_____________________________________________________________________________ | |
663 | Bool_t | |
664 | AliMUONVPainter::IsResponder() const | |
665 | { | |
666 | /// Whether we're responding to mouse events | |
667 | return MotherGroup()->IsResponder(); | |
668 | } | |
669 | ||
670 | //_____________________________________________________________________________ | |
671 | AliMUONVPainter* | |
672 | AliMUONVPainter::Master() const | |
673 | { | |
674 | /// Return the top of the hierarchy | |
675 | ||
676 | /// if we get no mother, we are the master | |
677 | ||
678 | if ( Mother() == 0x0 ) return const_cast<AliMUONVPainter*>(this); | |
679 | ||
680 | AliMUONVPainter* p = Mother(); | |
681 | ||
682 | while ( p->Mother() ) | |
683 | { | |
684 | p = p->Mother(); | |
685 | } | |
686 | ||
687 | return p; | |
688 | } | |
689 | ||
690 | //_____________________________________________________________________________ | |
691 | void | |
692 | AliMUONVPainter::Paint(Option_t*) | |
693 | { | |
694 | /// Paint ourselves of screen | |
695 | /// If we have some data (i.e. we're belonging to the plotter group) | |
696 | /// we use PaintArea. | |
697 | /// And if must be outlined, then we do that too. | |
698 | ||
699 | if ( !MotherGroup()->IsVisible() ) return; | |
700 | ||
701 | if ( MotherGroup()->IsPlotter() ) | |
702 | { | |
703 | PaintArea(*(MotherGroup()->Data()), | |
704 | MotherGroup()->DataIndex(), | |
705 | MotherGroup()->DataMin(), | |
706 | MotherGroup()->DataMax()); | |
707 | } | |
708 | ||
709 | if ( MotherGroup()->IsOutlined() ) | |
710 | { | |
711 | PaintOutline(); | |
712 | } | |
713 | } | |
714 | ||
715 | //_____________________________________________________________________________ | |
716 | TString | |
717 | AliMUONVPainter::Describe(const AliMUONVTrackerData&, Int_t, Double_t, Double_t) | |
718 | { | |
719 | /// Default implementation (must be overriden) | |
720 | AliError(Form("%s : implement me",GetName())); | |
721 | return ""; | |
722 | } | |
723 | ||
724 | //_____________________________________________________________________________ | |
725 | void | |
726 | AliMUONVPainter::PaintArea(const AliMUONVTrackerData&, Int_t, Double_t, Double_t) | |
727 | { | |
728 | /// Default implementation (must be overriden) | |
729 | AliError(Form("%s : implement me",GetName())); | |
730 | } | |
731 | ||
732 | //_____________________________________________________________________________ | |
733 | void | |
734 | AliMUONVPainter::PaintOutline(Int_t color, Int_t width, Double_t /*x*/, Double_t /*y*/) | |
735 | { | |
736 | /// Default implementation is simply a drawing of the contour lines, | |
737 | /// not using the optional (x,y) | |
738 | Int_t c = color >= 0 ? color : GetLineColor(); | |
739 | Int_t w = width >= 0 ? width : GetLineWidth(); | |
740 | ||
741 | fContour->PaintOutline(c,w); | |
742 | } | |
743 | ||
744 | //_____________________________________________________________________________ | |
745 | void | |
746 | AliMUONVPainter::PixelToPad(Int_t px, Int_t py, Double_t& x, Double_t& y) | |
747 | { | |
748 | /// convert (px,py) into pad position (x,y) | |
749 | ||
750 | x = gPad->PadtoX(gPad->AbsPixeltoX(px)); | |
751 | y = gPad->PadtoY(gPad->AbsPixeltoY(py)); | |
752 | } | |
753 | ||
754 | //_____________________________________________________________________________ | |
755 | void | |
756 | AliMUONVPainter::Print(Option_t* opt) const | |
757 | { | |
758 | /// Printout | |
759 | for ( Int_t i = 0; i < Depth()*4; ++i ) | |
760 | { | |
761 | cout << " "; | |
762 | } | |
763 | ||
764 | if ( !IsValid() ) cout << "!!!INVALID!!!" << endl; | |
765 | ||
766 | cout << Form("%p Name %s Depth %d ContourName %s ID=(%d,%d)", | |
767 | this,GetName(),Depth(),ContourName().Data(),ID0(),ID1()); | |
768 | ||
769 | if ( fResponderGroup ) | |
770 | { | |
771 | cout << Form(" Responder group %p %s",fResponderGroup,fResponderGroup->Type()); | |
772 | } | |
773 | if ( fPlotterGroup ) | |
774 | { | |
775 | cout << Form(" Plotter group %p %s",fPlotterGroup,fPlotterGroup->Type()); | |
776 | } | |
777 | if ( Mother() ) | |
778 | { | |
779 | cout << Form(" Mother %p %s",Mother(),Mother()->GetName()); | |
780 | } | |
781 | if ( MotherGroup() ) | |
782 | { | |
783 | cout << Form(" Group %p %s ",MotherGroup(),MotherGroup()->Type()); | |
784 | } | |
785 | ||
786 | if ( fChildren ) | |
787 | { | |
788 | cout << Form(" %d children",fChildren->GetLast()+1); | |
789 | } | |
790 | ||
791 | cout << endl; | |
792 | ||
793 | TString sopt(opt); | |
794 | sopt.ToUpper(); | |
795 | ||
796 | if ( fChildren && ( sopt == "FULL" || sopt == "CHILD" ) ) | |
797 | { | |
798 | TIter next(fChildren); | |
799 | AliMUONVPainter* painter; | |
800 | while ( ( painter = static_cast<AliMUONVPainter*>(next()) ) ) | |
801 | { | |
802 | painter->Print(opt); | |
803 | } | |
804 | } | |
805 | ||
806 | if ( fPainterGroups && ( sopt == "FULL" || sopt == "GROUP" ) ) | |
807 | { | |
808 | TIter next(fPainterGroups); | |
809 | TObjString* groupName; | |
810 | while ( ( groupName = static_cast<TObjString*>(next()) ) ) | |
811 | { | |
812 | AliMUONPainterGroup* group = Group(groupName->String().Data()); | |
813 | group->Print(opt); | |
814 | } | |
815 | } | |
816 | } | |
817 | ||
818 | //_____________________________________________________________________________ | |
819 | void | |
820 | AliMUONVPainter::SetAttributes(const AliMUONAttPainter& attributes) | |
821 | { | |
822 | /// Set our attributes | |
823 | fAttributes = attributes; | |
824 | } | |
825 | ||
826 | //_____________________________________________________________________________ | |
827 | void | |
828 | AliMUONVPainter::SetContour(AliMUONPainterContour* contour) | |
829 | { | |
830 | /// Set out contour | |
831 | if (!contour) | |
832 | { | |
833 | AliError(Form("Setting a null contour for painter %s : bad idea !",PathName().Data())); | |
834 | } | |
835 | fContour = contour; | |
836 | } | |
837 | ||
838 | //_____________________________________________________________________________ | |
839 | void | |
840 | AliMUONVPainter::SetData(const char* pattern, AliMUONVTrackerData* data, | |
841 | Int_t dataIndex) | |
842 | { | |
843 | /// Tell all painters which type matches pattern that they should | |
844 | /// monitor a given data source | |
845 | ||
846 | if ( !fPainterGroups ) | |
847 | { | |
848 | CreateGroups(); | |
849 | } | |
850 | ||
851 | TIter next(fPainterGroups); | |
852 | TObjString* str; | |
853 | ||
854 | fPlotterGroup = 0x0; | |
855 | ||
856 | while ( ( str = static_cast<TObjString*>(next()) ) ) | |
857 | { | |
858 | AliMUONPainterGroup* group = static_cast<AliMUONPainterGroup*>(fPainterGroups->GetValue(str)); | |
859 | if ( group->Matches(pattern) ) | |
860 | { | |
861 | group->SetData(data,dataIndex); | |
862 | if ( data ) | |
863 | { | |
864 | fPlotterGroup = group; | |
865 | } | |
866 | } | |
867 | else | |
868 | { | |
869 | group->SetData(0x0,-1); | |
870 | } | |
871 | } | |
872 | } | |
873 | ||
874 | //_____________________________________________________________________________ | |
875 | void | |
876 | AliMUONVPainter::SetLine(Int_t depth, Int_t lineColor, Int_t lineWidth) | |
877 | { | |
878 | /// Set the line attributes of painters at a given depth | |
879 | AliMUONPainterGroup* group = Group(depth); | |
880 | if ( group ) | |
881 | { | |
882 | group->SetLine(lineColor,lineWidth); | |
883 | } | |
884 | } | |
885 | ||
886 | //_____________________________________________________________________________ | |
887 | void | |
888 | AliMUONVPainter::SetMother(AliMUONVPainter* painter) | |
889 | { | |
890 | /// Set our mother | |
891 | fMother = painter; | |
892 | } | |
893 | ||
894 | //_____________________________________________________________________________ | |
895 | void | |
896 | AliMUONVPainter::SetOutlined(const char* pattern, Bool_t flag) | |
897 | { | |
898 | /// Decide whether or not painters which type matches pattern | |
899 | /// should be outlined | |
900 | ||
901 | AliDebug(1,Form("pattern=%s flag=%d",pattern,flag)); | |
902 | ||
903 | if (!fPainterGroups) | |
904 | { | |
905 | CreateGroups(); | |
906 | } | |
907 | ||
908 | TIter next(fPainterGroups); | |
909 | TObjString* str; | |
910 | ||
911 | while ( ( str = static_cast<TObjString*>(next()) ) ) | |
912 | { | |
913 | AliMUONPainterGroup* group = static_cast<AliMUONPainterGroup*>(fPainterGroups->GetValue(str)); | |
914 | if ( group->Matches(pattern) ) | |
915 | { | |
916 | group->SetOutlined(flag); | |
917 | } | |
918 | } | |
919 | } | |
920 | ||
921 | //_____________________________________________________________________________ | |
922 | void | |
923 | AliMUONVPainter::SetResponder(const char* pattern) | |
924 | { | |
925 | /// Set the painters matching pattern to be the responder | |
926 | ||
927 | AliDebug(1,Form("pattern=%s",pattern)); | |
928 | ||
929 | if (!fPainterGroups) | |
930 | { | |
931 | CreateGroups(); | |
932 | } | |
933 | ||
934 | TIter next(fPainterGroups); | |
935 | TObjString* str; | |
936 | ||
937 | fResponderGroup = 0x0; | |
938 | ||
939 | while ( ( str = static_cast<TObjString*>(next()) ) ) | |
940 | { | |
941 | AliMUONPainterGroup* group = static_cast<AliMUONPainterGroup*>(fPainterGroups->GetValue(str)); | |
942 | if ( group->Matches(pattern) ) | |
943 | { | |
944 | AliDebug(1,Form("group %s is matching pattern %s : setting to responder", | |
945 | group->Type(),pattern)); | |
946 | group->SetResponder(kTRUE); | |
947 | fResponderGroup = group; | |
948 | } | |
949 | else | |
950 | { | |
951 | group->SetResponder(kFALSE); | |
952 | } | |
953 | } | |
954 | } | |
955 | ||
956 | //_____________________________________________________________________________ | |
957 | void | |
958 | AliMUONVPainter::SetResponder(Int_t depth) | |
959 | { | |
960 | /// Select as responder the *first* group that has a given depth | |
961 | ||
962 | AliDebug(1,Form("depth=%d",depth)); | |
963 | ||
964 | if (!fPainterGroups) | |
965 | { | |
966 | CreateGroups(); | |
967 | } | |
968 | ||
969 | TIter next(fPainterGroups); | |
970 | TObjString* str; | |
971 | ||
972 | fResponderGroup = 0x0; | |
973 | ||
974 | while ( ( str = static_cast<TObjString*>(next()) ) ) | |
975 | { | |
976 | AliMUONPainterGroup* group = static_cast<AliMUONPainterGroup*>(fPainterGroups->GetValue(str)); | |
977 | if ( group->Depth() == depth ) | |
978 | { | |
979 | AliDebug(1,Form("group %s has correct depth = %d, using as responder", | |
980 | group->Type(),depth)); | |
981 | group->SetResponder(kTRUE); | |
982 | fResponderGroup = group; | |
983 | break; | |
984 | } | |
985 | else | |
986 | { | |
987 | group->SetResponder(kFALSE); | |
988 | } | |
989 | } | |
990 | } | |
991 | ||
992 | //_____________________________________________________________________________ | |
993 | void | |
994 | AliMUONVPainter::SetVisible(const char* pattern, Bool_t flag) | |
995 | { | |
996 | /// Decide whether the painters matching pattern should be visible or not | |
997 | AliDebug(1,Form("pattern=%s flag=%d",pattern,flag)); | |
998 | ||
999 | if (!fPainterGroups) | |
1000 | { | |
1001 | CreateGroups(); | |
1002 | } | |
1003 | ||
1004 | TIter next(fPainterGroups); | |
1005 | TObjString* str; | |
1006 | ||
1007 | while ( ( str = static_cast<TObjString*>(next()) ) ) | |
1008 | { | |
1009 | AliMUONPainterGroup* group = static_cast<AliMUONPainterGroup*>(fPainterGroups->GetValue(str)); | |
1010 | if ( group->Matches(pattern) ) | |
1011 | { | |
1012 | group->SetVisible(flag); | |
1013 | } | |
1014 | } | |
1015 | } | |
1016 | ||
1017 | //_____________________________________________________________________________ | |
1018 | void | |
1019 | AliMUONVPainter::UpdateGroupsFrom(const AliMUONVPainter& painter) | |
1020 | { | |
1021 | /// (re)Create groups | |
1022 | delete fPainterGroups; | |
1023 | fPainterGroups = 0x0; | |
1024 | ||
1025 | CreateGroups(); | |
1026 | ||
1027 | // and copy the status of responder, plotter and visible | |
1028 | if ( painter.ResponderGroup() ) | |
1029 | { | |
1030 | SetResponder(painter.ResponderGroup()->Type()); | |
1031 | } | |
1032 | ||
1033 | if ( painter.PlotterGroup() ) | |
1034 | { | |
1035 | SetData(painter.PlotterGroup()->Type(), | |
1036 | painter.PlotterGroup()->Data(), | |
1037 | painter.PlotterGroup()->DataIndex()); | |
1038 | PlotterGroup()->SetDataRange(painter.PlotterGroup()->DataMin(), | |
1039 | painter.PlotterGroup()->DataMax()); | |
1040 | } | |
1041 | ||
1042 | TObjArray types; | |
1043 | painter.GetTypes(types); | |
1044 | TIter next(&types); | |
1045 | TObjString* groupName; | |
1046 | ||
1047 | while ( ( groupName = static_cast<TObjString*>(next()) ) ) | |
1048 | { | |
1049 | AliMUONPainterGroup* group = painter.Group(groupName->String().Data()); | |
1050 | if ( group->IsVisible() ) | |
1051 | { | |
1052 | SetVisible(group->Type(),kTRUE); | |
1053 | } | |
1054 | else | |
1055 | { | |
1056 | SetVisible(group->Type(),kFALSE); | |
1057 | } | |
1058 | ||
1059 | if ( group->IsOutlined() ) | |
1060 | { | |
1061 | SetOutlined(group->Type(),kTRUE); | |
1062 | } | |
1063 | else | |
1064 | { | |
1065 | SetOutlined(group->Type(),kFALSE); | |
1066 | } | |
1067 | ||
1068 | SetLine(group->Depth(),group->GetLineColor(),group->GetLineWidth()); | |
1069 | } | |
1070 | } | |
1071 | ||
1072 | //_____________________________________________________________________________ | |
1073 | AliMUONVPainter* | |
1074 | AliMUONVPainter::CreatePainter(const char* className, | |
1075 | const AliMUONAttPainter& att, | |
1076 | Int_t id1, Int_t id2) | |
1077 | { | |
1078 | /// Create a painter (factory method) | |
1079 | ||
1080 | TClass* c = TClass::GetClass(className); | |
1081 | ||
1082 | if (!c) | |
1083 | { | |
1084 | AliErrorClass(Form("Cannot get class %s",className)); | |
1085 | return 0x0; | |
1086 | } | |
1087 | ||
1088 | Int_t n(0); | |
1089 | ||
1090 | TMethodCall call; | |
1091 | ||
1092 | call.InitWithPrototype(c,className,"AliMUONAttPainter&,Int_t"); | |
1093 | ||
1094 | if (call.IsValid()) n = 1; | |
1095 | else | |
1096 | { | |
1097 | call.InitWithPrototype(c,className,"AliMUONAttPainter&,Int_t,Int_t"); | |
1098 | ||
1099 | if ( call.IsValid() ) n = 2; | |
1100 | } | |
1101 | ||
1102 | Long_t returnLong(0x0); | |
1103 | ||
1104 | if ( n ==1 ) | |
1105 | { | |
1106 | Long_t params[] = { (Long_t)(&att), (Long_t)(id1) }; | |
1107 | call.SetParamPtrs((void*)(params)); | |
1108 | call.Execute((void*)(0x0),returnLong); | |
1109 | } | |
1110 | else if ( n == 2 ) | |
1111 | { | |
1112 | Long_t params[] = { (Long_t)(&att), (Long_t)(id1), (Long_t)(id2) }; | |
1113 | call.SetParamPtrs((void*)(params)); | |
1114 | call.Execute((void*)(0x0),returnLong); | |
1115 | } | |
1116 | ||
1117 | if (!returnLong) | |
1118 | { | |
1119 | AliErrorClass(Form("Cannot create a painter of class %s",className)); | |
1120 | } | |
1121 | ||
1122 | AliMUONVPainter* rv = reinterpret_cast<AliMUONVPainter*> (returnLong); | |
1123 | ||
1124 | if (!rv->IsValid()) | |
1125 | { | |
1126 | AliErrorClass(Form("Painter of class %s is not valid",className)); | |
1127 | delete rv; | |
1128 | rv = 0x0; | |
1129 | } | |
1130 | return rv; | |
1131 | } | |
1132 |