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