- Disentangle masks effect from trigger chamber efficiency estimation.
[u/mrichter/AliRoot.git] / MUON / AliMUONPainterMatrix.cxx
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 "AliMUONPainterMatrix.h"
19
20 #include "AliLog.h"
21 #include "AliMUONPainterGroup.h"
22 #include "AliMUONPainterHelper.h"
23 #include "AliMUONVPainter.h"
24 #include "AliMUONVTrackerData.h"
25 #include "TCanvas.h"
26 #include "TGClient.h"
27 #include "TPaveLabel.h"
28 #include <Riostream.h>
29 #include <TBox.h>
30 #include <TMath.h>
31 #include <TObjArray.h>
32 #include <TObjString.h>
33 #include <TROOT.h>
34 #include <TVirtualPad.h>
35 #include <float.h>
36
37 ///\class AliMUONPainterMatrix
38 ///
39 /// Matrix of AliMUONVPainter
40 ///
41 ///\author Laurent Aphecetche, Subatech
42
43 ///\cond CLASSIMP 
44 ClassImp(AliMUONPainterMatrix)
45 ///\endcond
46
47 //_____________________________________________________________________________
48 AliMUONPainterMatrix::AliMUONPainterMatrix(const char* name, Int_t nx, Int_t ny)
49 : TObject(),
50   fBasename(name),
51   fWhatname(""),
52   fNx(nx),
53   fNy(ny),
54   fPainters(new TObjArray(fNx*fNy)),
55   fAttributes()
56 {
57   /// ctor
58   
59   fPainters->SetOwner(kTRUE);
60   if ( fNx*fNy > 1 ) 
61   {
62     fAttributes.SetSingle(kFALSE);
63   }
64 }
65
66 //_____________________________________________________________________________
67 AliMUONPainterMatrix::~AliMUONPainterMatrix()
68 {
69   /// dtor
70   delete fPainters;
71 }
72
73 //_____________________________________________________________________________
74 void 
75 AliMUONPainterMatrix::Adopt(AliMUONVPainter* painter)
76 {
77   /// Adopt a given painter
78   fPainters->AddLast(painter);
79   UpdateAttributes();
80 }
81
82 //_____________________________________________________________________________
83 void
84 AliMUONPainterMatrix::UpdateAttributes()
85 {
86   /// Update our attributes (using our painters' attributes)
87   
88   Bool_t cathode0(kFALSE);
89   Bool_t cathode1(kFALSE);
90   Bool_t bending(kFALSE);
91   Bool_t nonbending(kFALSE);
92   Bool_t front(kFALSE);
93   Bool_t back(kFALSE);
94   Bool_t cathplaneexclusive(kFALSE);
95   Bool_t cathplanedisabled(kFALSE);
96   
97   for ( Int_t i = 0; i < Size(); ++i )
98   {
99     AliMUONAttPainter att = Painter(i)->Attributes();
100     
101     if ( att.IsCathodeDefined() ) 
102     {
103       if ( att.IsCathode0() ) cathode0 = kTRUE;
104       if ( att.IsCathode1() ) cathode1 = kTRUE;
105     }
106
107     if ( att.IsPlaneDefined() ) 
108     {
109       if ( att.IsBendingPlane() ) bending = kTRUE;
110       if ( att.IsNonBendingPlane() ) nonbending = kTRUE;
111     }
112     
113     if ( att.IsFrontView() ) front = kTRUE;
114     if ( att.IsBackView() ) back = kTRUE;
115     
116     if ( att.IsCathodeAndPlaneMutuallyExclusive() ) cathplaneexclusive = kTRUE;
117     
118     if ( att.IsCathodeAndPlaneDisabled() ) cathplanedisabled = kTRUE;
119   }
120   
121   fAttributes.SetCathode(cathode0,cathode1);
122   fAttributes.SetPlane(bending,nonbending);
123   fAttributes.SetViewPoint(front,back);
124   fAttributes.SetCathodeAndPlaneMutuallyExclusive(cathplaneexclusive);
125   fAttributes.SetCathodeAndPlaneDisabled(cathplanedisabled);
126 }
127
128 //_____________________________________________________________________________
129 const char*
130 AliMUONPainterMatrix::Name() const
131 {
132   /// Build our name
133   
134   return NameIt(fWhatname.Data(),fBasename.Data(),fAttributes).Data();
135 }
136
137 //_____________________________________________________________________________
138 TString
139 AliMUONPainterMatrix::NameIt(const char* whatname, const char* basename, const AliMUONAttPainter& att)
140 {
141   /// Build a name 
142   if ( strlen(whatname) > 0 ) 
143   {
144     return Form("%s-%s-%s",whatname,basename,att.Name().Data());
145   }
146   else
147   {
148     return Form("noda-%s-%s",basename,att.Name().Data());
149   }
150 }
151
152 //_____________________________________________________________________________
153 void 
154 AliMUONPainterMatrix::ComputeDataRange()
155 {
156   /// Compute the data range spanned by the painters in this matrix
157   
158   Double_t dataMin(FLT_MAX);
159   Double_t dataMax(-FLT_MAX);
160   Bool_t atLeastOnePlotter(kFALSE);
161   
162   for ( Int_t i = 0; i < Size(); ++i ) 
163   {
164     AliMUONVPainter* p = Painter(i);
165     AliMUONPainterGroup* g = p->PlotterGroup();
166
167     Double_t min(FLT_MAX);
168     Double_t max(-FLT_MAX);
169
170     if ( g ) 
171     {
172       atLeastOnePlotter = kTRUE;
173       g->ComputeDataRange(min,max);
174       if ( min <= max ) 
175       {
176         dataMin = TMath::Min(min,dataMin);
177         dataMax = TMath::Max(max,dataMax);
178       }
179     }
180
181     AliDebug(1,Form("painter %s group %s min %e max %e dataMin,Max=%7.3f,%7.3f",
182                     p->GetName(),
183                     g ? g->Type() : "none",
184                     min,max,
185                     dataMin,dataMax));
186   }
187
188   if ( dataMin > dataMax && atLeastOnePlotter ) 
189   {
190     AliError(Form("data min %e > max %e : setting both to 0.0",
191                     dataMin,dataMax));
192     dataMin = dataMax = 0.0;
193   }
194   
195   AliDebug(1,Form("Final dataMin,Max=%7.3f,%7.3f",dataMin,dataMax));
196   
197   SetDataRange(dataMin,dataMax);
198 }
199
200 //_____________________________________________________________________________
201 void 
202 AliMUONPainterMatrix::Connect(const char* sourceMethod, const char* destClassName, 
203                               void* destObject, const char* destMethod)
204 {
205   /// Connect our painters
206   
207   for ( Int_t i = 0; i < Size(); ++i )
208   {
209     Painter(i)->Connect(sourceMethod,destClassName,destObject,destMethod);
210   }
211 }
212
213 //_____________________________________________________________________________
214 TCanvas*
215 AliMUONPainterMatrix::CreateCanvas(Int_t x, Int_t y, Int_t w, Int_t h)
216 {
217   /// Generate a canvas to show the painter matrix.
218   ///
219   /// Layout is the following :
220   ///
221   /// ----------------------------------------------------
222   /// |    title describing what is plotted              |
223   /// ----------------------------------------------------
224   /// |                                        |         |
225   /// |                                        |         |
226   /// |                                        |         |
227   /// |                                        |         |
228   /// |                                        |         |
229   /// |             painter themselves         | color   |
230   /// |                                        | range   |
231   /// |                                        |         |
232   /// |                                        |         |
233   /// ----------------------------------------------------
234   ///
235   
236   Int_t mw = ( w <= 0 ? TMath::Nint(gClient->GetDisplayWidth()*0.9) : w );
237   Int_t mh = ( h <= 0 ? TMath::Nint(gClient->GetDisplayHeight()*0.9) : h );
238   
239   TString name(Name());
240   
241   TCanvas* d = new TCanvas(name.Data(),name.Data(),x,y,mw,mh);
242
243   TVirtualPad* pTitle = new TPad(Form("%s-title",name.Data()),Form("%s-title",name.Data()),0,0.9,1.0,0.99);
244   
245   pTitle->Draw();
246   
247   pTitle->cd();
248   
249   TPaveLabel* text = new TPaveLabel(0,0,1,1,"");
250   text->SetFillStyle(0);
251   text->SetFillColor(0);
252   text->SetTextColor(4);
253   text->SetBorderSize(0);
254   
255   text->SetLabel(name.Data());
256   
257   text->Draw();
258   
259   d->cd();
260   
261   TVirtualPad* pMatrix = new TPad(Form("%s-matrix",name.Data()),Form("%s-matrix",name.Data()),0,0,0.9,0.89);
262   
263   pMatrix->Draw();
264   pMatrix->cd();
265   
266   Draw();
267   
268   d->cd();
269   
270   TVirtualPad* pColor = new TPad(Form("%s-color",name.Data()),Form("%s-color",name.Data()),0.91,0.01,0.99,0.89);
271     
272   pColor->Range(0,0,1,1);
273
274   pColor->Draw();
275   
276   pColor->cd();
277   
278   Int_t ndivisions(20);
279   
280   Double_t rangeXmin(0.1);
281   Double_t rangeXmax(0.9);
282   
283   Double_t ymin, ymax;
284   
285   GetDataRange(ymin,ymax);
286     
287   Double_t min(0.0);
288   Double_t max(1.0);
289   
290   Double_t step = (max-min)/ndivisions;
291
292   Double_t hsize = 1.0/(ndivisions+2);
293
294   Double_t ypos = 1.0;
295   
296   for ( Int_t i = -1; i < ndivisions+1; ++i ) 
297   {
298     Double_t value = max - (min + step*i);
299     
300     Int_t color = AliMUONPainterHelper::Instance()->ColorFromValue(value,min,max);
301     
302     Bool_t limit(kFALSE);
303     
304     TString label;
305     TString sign;
306     
307     Double_t yvalue(0.0);
308     
309     if ( i == -1 )
310     {
311       yvalue = ymax;
312       limit = kTRUE;
313       sign = ">";
314     }
315     else if ( i == ndivisions )
316     {
317       yvalue = ymin;
318       limit = kTRUE;
319       sign = "<=";
320     }
321     
322     if (limit)
323     {
324       if ( TMath::Abs(yvalue) < 1E5 ) 
325       {
326         label = Form("%s %7.2f",sign.Data(),yvalue);    
327       }
328       else
329       {
330         label = Form("%s %e",sign.Data(),yvalue);
331       }
332     }
333
334     TPaveLabel* box = new TPaveLabel(rangeXmin,TMath::Max(0.001,ypos-hsize),rangeXmax,ypos,label.Data(),"");    
335     
336     ypos -= hsize;
337     
338     box->SetFillColor(color);
339     box->SetTextColor( i == -1 ? 0 : 1 );
340     box->SetBorderSize(1);
341     box->SetLineColor(1);
342     box->Draw();
343   }  
344   
345   d->SetEditable(kFALSE);
346   
347   return d;
348 }
349
350 //_____________________________________________________________________________
351 void
352 AliMUONPainterMatrix::GetDataRange(Double_t& dataMin, Double_t& dataMax) const
353 {
354   /// Get the data range spanned by the painters in this matrix
355   
356   dataMin=FLT_MAX;
357   dataMax=-FLT_MAX;
358   
359   for ( Int_t i = 0; i < Size(); ++i ) 
360   {
361     AliMUONVPainter* p = Painter(i);
362     if ( p )
363     {
364       AliMUONPainterGroup* g = p->PlotterGroup();
365       if ( g ) 
366       {
367         dataMin = TMath::Min(dataMin,g->DataMin());
368         dataMax = TMath::Max(dataMax,g->DataMax());
369       }
370     }
371   }
372 }
373
374 //_____________________________________________________________________________
375 void 
376 AliMUONPainterMatrix::GetTypes(TObjArray& types) const
377 {
378   /// Get the types of the painters in this matrix
379   
380   types.SetOwner(kTRUE);
381   types.Clear();
382   
383   for ( Int_t i = 0; i < Size(); ++i ) 
384   {
385     AliMUONVPainter* p = Painter(i);
386     TObjArray ptypes;
387     p->GetTypes(ptypes);
388     TIter next(&ptypes);
389     TObject* o;
390     while ( ( o = next() ) )
391     {
392       if ( ! types.FindObject(o) )
393       {
394         types.AddLast(o->Clone());
395       }
396     }
397   }  
398 }
399
400
401 //_____________________________________________________________________________
402 void
403 AliMUONPainterMatrix::Draw(Option_t*)
404 {
405   /// Append our painters to the current pad
406
407   if (!gPad) 
408   {
409     gROOT->MakeDefCanvas();
410   }
411   
412   TVirtualPad* pad = gPad;
413
414   gPad->Divide(Nx(),Ny());
415   
416   for ( Int_t i = 0; i < Size(); ++i ) 
417   {
418     AliMUONVPainter* painter = Painter(i);
419     pad->cd(i+1);
420     painter->Draw("R");
421   }  
422   
423   AppendPad("");
424 }
425
426 //_____________________________________________________________________________
427 AliMUONVPainter* 
428 AliMUONPainterMatrix::Painter(Int_t index) const
429 {
430   /// Get a given painter
431   
432   if ( index <= fPainters->GetLast() ) 
433   {
434     return static_cast<AliMUONVPainter*>(fPainters->At(index));
435   }
436   return 0x0;
437 }
438
439 //_____________________________________________________________________________
440 AliMUONVTrackerData* 
441 AliMUONPainterMatrix::Data() const
442 {
443   /// Return our data
444   AliMUONPainterGroup* group = Painter(0)->PlotterGroup();
445   return ( group ? group->Data() : 0x0 );
446 }
447
448 //_____________________________________________________________________________
449 TString 
450 AliMUONPainterMatrix::DataPattern() const
451 {
452   /// Return our data pattern
453   AliMUONPainterGroup* group = Painter(0)->PlotterGroup();
454   return ( group ? group->Type() : "" );
455 }
456
457 //_____________________________________________________________________________
458 Int_t 
459 AliMUONPainterMatrix::DataIndex() const
460 {
461   /// Return our data index
462   AliMUONPainterGroup* group = Painter(0)->PlotterGroup();
463   return ( group ? group->DataIndex() : -1 );
464 }
465
466 //_____________________________________________________________________________
467 void
468 AliMUONPainterMatrix::SetData(const char* pattern, AliMUONVTrackerData* d,
469                               Int_t indexInData)
470 {
471   /// Set the data to be plotted
472   
473   for ( Int_t i = 0; i < Size(); ++i )
474   {
475     AliMUONVPainter* painter = Painter(i);
476     painter->SetData(pattern,d,indexInData);
477   }
478   
479   if ( d ) 
480   {
481     fWhatname = Form("%s-%s",d->GetName(),d->DimensionName(indexInData).Data());
482   }
483   else
484   {
485     fWhatname = "";
486   }
487 }
488
489 //_____________________________________________________________________________
490 void
491 AliMUONPainterMatrix::SetDataRange(Double_t dataMin, Double_t dataMax)
492 {
493   /// Set the data range
494   
495   for ( Int_t i = 0; i < Size(); ++i ) 
496   {
497     AliMUONVPainter* p = Painter(i);
498     AliMUONPainterGroup* g = p->PlotterGroup();
499     if ( g ) 
500     {
501       g->SetDataRange(dataMin,dataMax);
502     }
503   }       
504 }
505
506 //_____________________________________________________________________________
507 Int_t 
508 AliMUONPainterMatrix::Size() const
509 {
510   /// Return the number of painters we actually handle
511   return fPainters->GetLast()+1;
512 }
513
514 //_____________________________________________________________________________
515 void
516 AliMUONPainterMatrix::Print(Option_t*) const
517 {
518   /// Printout
519   cout << "Whatname=" << fWhatname.Data() << "Basename=" << fBasename.Data() 
520   << " Nx=" << fNx << " Ny=" << fNy << " Att=" << fAttributes.GetName() << endl;
521 }
522
523 //_____________________________________________________________________________
524 //void 
525 //AliMUONPainterMatrix::ChangeAttributes(const AliMUONAttPainter& attributes)
526 //{
527 //  /// Change painters' attributes
528 //  
529 //  AliWarning("Implement me !");
530 //  
531 //  //  for ( Int_t i = 0; i < Size(); ++i ) 
532 //  //  {
533 //  //    Painter(i)->SetAttributes(attributes);
534 //  //  }
535 //}
536
537 //_____________________________________________________________________________
538 AliMUONPainterMatrix*
539 AliMUONPainterMatrix::Clone(const AliMUONAttPainter& attributes) const
540 {
541   /// Clone with given attributes
542   
543   AliMUONPainterMatrix* clone = new AliMUONPainterMatrix(Basename(),Nx(),Ny());
544
545   for ( Int_t i = 0; i < Size(); ++i ) 
546   {
547     AliMUONVPainter* oldPainter = Painter(i);
548     
549     AliMUONVPainter* newPainter(0x0);
550     
551     newPainter = AliMUONVPainter::CreatePainter(oldPainter->ClassName(),
552                                                 attributes,
553                                                 oldPainter->ID0(),
554                                                 oldPainter->ID1());
555     
556     if (newPainter)
557     {
558       newPainter->UpdateGroupsFrom(*(oldPainter->Master()));
559       clone->Adopt(newPainter);
560     }
561     else
562     {
563       AliError(Form("Failed to create painter of class %s ID0 %d ID1 %d",
564                     oldPainter->ClassName(),
565                     oldPainter->ID0(),
566                     oldPainter->ID1()));
567     }
568   }
569   
570   return clone;
571 }
572
573 //_____________________________________________________________________________
574 void
575 AliMUONPainterMatrix::SetOutlined(const char* pattern, Bool_t value)
576 {
577   /// Calls SetOutlined for all our painters
578
579   for ( Int_t i = 0; i < Size(); ++i ) 
580   {
581     Painter(i)->SetOutlined(pattern,value);
582   }
583 }
584
585 //_____________________________________________________________________________
586 void
587 AliMUONPainterMatrix::SetResponder(const char* pattern)
588 {
589   /// Calls SetResponder for all our painters
590   for ( Int_t i = 0; i < Size(); ++i ) 
591   {
592     Painter(i)->SetResponder(pattern);
593   }
594 }
595
596 //_____________________________________________________________________________
597 AliMUONAttPainter
598 AliMUONPainterMatrix::Validate(const AliMUONAttPainter& att) const
599 {
600   /// Normalize attributes
601
602   AliMUONAttPainter a;
603   
604   for ( Int_t i = 0; i < Size() && a.IsValid(); ++i ) 
605   {
606     a = Painter(i)->Validate(att);
607   }
608   return a;
609 }