new functionality and new class added
[u/mrichter/AliRoot.git] / MUON / AliMUONTrackerDataHistogrammer.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 "AliMUONTrackerDataHistogrammer.h"
19
20 #include "AliLog.h"
21 #include "AliMUONPainterGroup.h"
22 #include "AliMUONSparseHisto.h"
23 #include "AliMUONVPainter.h"
24 #include "AliMUONVTrackerData.h"
25 #include "AliMpBusPatch.h"
26 #include "AliMpConstants.h"
27 #include "AliMpDDLStore.h"
28 #include "AliMpDEIterator.h"
29 #include "AliMpDetElement.h"
30 #include "AliMpManuUID.h"
31 #include <TClass.h>
32 #include <TH1.h>
33 #include <TObjArray.h>
34 #include <TROOT.h>
35 #include <TMath.h>
36
37 ///\class AliMUONTrackerDataHistogrammer
38 ///
39 /// Class to generate histograms from AliMUONVTrackerData 
40 /// (and AliMUONVPainter) objects
41 ///
42 /// \author Laurent Aphecetche, Subatech
43 ///
44
45 ///\cond CLASSIMP
46 ClassImp(AliMUONTrackerDataHistogrammer)
47 ///\endcond CLASSIMP
48
49 //_____________________________________________________________________________
50 AliMUONTrackerDataHistogrammer::AliMUONTrackerDataHistogrammer(const AliMUONVTrackerData& data,
51                                                                Int_t externalDim,
52                                                                Int_t internalDim)
53 : TObject(),
54 fkData(data),
55 fExternalDim(externalDim),
56 fInternalDim(internalDim)
57 {
58   /// ctor
59 }
60
61 //_____________________________________________________________________________
62 AliMUONTrackerDataHistogrammer::~AliMUONTrackerDataHistogrammer()
63 {
64   /// dtor
65 }
66
67 //_____________________________________________________________________________
68 void
69 AliMUONTrackerDataHistogrammer::Add(TH1& h, const AliMUONSparseHisto& sh) const
70 {
71   /// Add sparse histo content to histogram.
72   
73   Double_t entries(h.GetEntries());
74   
75   for ( Int_t i = 0; i < sh.GetNbins(); ++i ) 
76   {
77     Int_t count = sh.GetBinContent(i);
78     
79     h.Fill(sh.GetBinCenter(i),count);
80     
81     entries += count;
82   }
83   
84   h.SetEntries(entries);
85   
86   if (sh.HasUnderflow()) h.SetBinContent(0,1);
87   if (sh.HasOverflow()) h.SetBinContent(h.GetNbinsX()+1,1);
88 }
89
90 //_____________________________________________________________________________
91 void
92 AliMUONTrackerDataHistogrammer::AddBusPatchHisto(TH1& h, Int_t busPatchId) const
93 {
94   /// Add data from one bus patch to the histogram
95   
96   if ( fkData.HasBusPatch(busPatchId ) )
97   {
98     AliMpBusPatch* busPatch = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
99     for ( Int_t i = 0; i < busPatch->GetNofManus(); ++i ) 
100     {
101       Int_t manuId = busPatch->GetManuId(i);
102       AddManuHisto(h,busPatch->GetDEId(),manuId);
103     }
104   }
105 }
106 //_____________________________________________________________________________
107 void
108 AliMUONTrackerDataHistogrammer::AddDEHisto(TH1& h, Int_t detElemId) const
109 {
110   /// Add data from one detection element to the histogram
111   
112   if ( fkData.HasDetectionElement(detElemId) )
113   {
114     AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
115     for ( Int_t i = 0; i < de->GetNofBusPatches(); ++ i ) 
116     {
117       Int_t busPatchId = de->GetBusPatchId(i);
118       AddBusPatchHisto(h,busPatchId);
119     }
120   }
121 }
122
123 //_____________________________________________________________________________
124 void
125 AliMUONTrackerDataHistogrammer::AddManuHisto(TH1& h, Int_t detElemId, Int_t manuId) const
126 {
127   /// Add data from a given manu to histogram
128   
129   if ( fkData.HasManu(detElemId,manuId) )
130   {
131     if ( fkData.IsChannelLevelEnabled() )
132     {
133       for ( Int_t i = 0; i < AliMpConstants::ManuNofChannels(); ++i ) 
134       {
135         if ( fkData.HasChannel(detElemId,manuId,i) )
136         {
137           if ( IsInternalMode() ) 
138           {
139             h.Fill(fkData.Channel(detElemId,manuId,i,fInternalDim));
140           }
141           else
142           {
143             AliMUONSparseHisto* sh = fkData.GetChannelSparseHisto(detElemId,manuId,i,fExternalDim);
144             
145             if ( sh ) 
146             {       
147               Add(h,*sh);
148             }
149           }
150         }
151       }
152     }
153     else
154     {
155       if ( IsInternalMode() ) 
156       {
157         h.Fill(fkData.Manu(detElemId,manuId,fInternalDim));
158       }
159       else
160       {
161         AliMUONSparseHisto* sh = fkData.GetManuSparseHisto(detElemId,manuId,fExternalDim);
162         if (sh)
163         {
164           Add(h,*sh);
165         }
166       }
167     }
168   }
169 }
170
171 //_____________________________________________________________________________
172 TH1*
173 AliMUONTrackerDataHistogrammer::CreateChannelHisto(Int_t detElemId, 
174                                                    Int_t manuId, 
175                                                    Int_t manuChannel) const
176 {
177   /// Create histogram of a given channel. Note that in order
178   /// to keep memory footprint as low as possible, you should delete
179   /// the returned pointer as soon as possible...
180   
181   if ( fkData.HasChannel(detElemId, manuId, manuChannel) && fkData.IsHistogrammed(fExternalDim) )
182   {
183     AliMUONSparseHisto* sh = fkData.GetChannelSparseHisto(detElemId,manuId,manuChannel);
184     
185     if ( sh ) 
186     {
187       Int_t nbins((1<<sh->Nbits()));
188       Double_t xmin,xmax;
189       fkData.HistogramRange(xmin,xmax);
190       
191       TH1* h = CreateHisto(Form("DE%04dMANU%04dCH%02d",detElemId,manuId,manuChannel),
192                            nbins,xmin,xmax);
193       if (h ) 
194       {
195         Add(*h,*sh);
196       }
197       return h;
198     }
199   }
200   return 0x0;
201 }
202
203 //_____________________________________________________________________________
204 TH1*
205 AliMUONTrackerDataHistogrammer::CreateHisto(const char* name,
206                                             Int_t nbins,
207                                             Double_t xmin,
208                                             Double_t xmax) const
209 {
210   /// Create a single histogram
211   
212   TH1* h(0);
213   
214   if ( xmin < xmax ) 
215   {
216     h = new TH1F(name,name,nbins,xmin,xmax);
217     h->SetDirectory(gROOT);
218   }
219         else
220         {
221                 AliError(Form("Cannot create histo for name=%s nbins=%d xmin=%e xmax=%e",name,nbins,xmin,xmax));
222         }
223   return h;
224 }
225
226 //_____________________________________________________________________________
227 TH1* 
228 AliMUONTrackerDataHistogrammer::CreateHisto(const AliMUONVPainter& painter, 
229                                                                                                                                                                                 Int_t externalDim,
230                                                                                                                                                                                 Int_t internalDim)
231 {
232   /// Create an histogram, from given dim of given data, 
233   /// for all the channels handled by painter
234
235   AliMUONPainterGroup* group = painter.Master()->PlotterGroup();
236   
237   if ( !group ) return 0x0; // no data to histogram in this painter
238   
239   AliMUONVTrackerData* data = group->Data();
240   
241   if ( externalDim >= data->ExternalDimension() )
242   {
243     AliErrorClass(Form("externalDim %d is out of bounds",externalDim));
244     return 0x0;
245   }
246
247   if ( internalDim >= data->NumberOfDimensions() )
248   {
249     AliErrorClass(Form("internalDim %d is out of bounds",internalDim));
250     return 0x0;
251   }
252   
253   if ( internalDim < 0 && externalDim < 0 ) 
254   {
255     AliErrorClass("Both internal and external dim are < 0 !!!");
256     return 0x0;
257   }
258   
259   AliMUONTrackerDataHistogrammer tdh(*data,externalDim,internalDim);
260
261   TObjArray manuArray;
262   
263   painter.FillManuList(manuArray);
264
265   AliMpManuUID* mid;
266   TIter next(&manuArray);
267
268   TString basename(Form("%s-%s",painter.PathName().Data(),painter.Attributes().GetName()));
269   TString ext;
270   Int_t nbins((1<<12));
271   Double_t xmin(0.0);
272   Double_t xmax(0.0);
273   
274   if ( !tdh.IsInternalMode() ) 
275   {
276     data->HistogramRange(xmin,xmax);
277     
278     xmin -= 0.5;
279     xmax -= 0.5;
280     
281     ext = data->ExternalDimensionName(externalDim).Data();
282   }
283   else
284   {
285     tdh.GetDataRange(manuArray,xmin,xmax);
286     ext = data->DimensionName(internalDim).Data();
287     nbins = 100;
288   }
289   
290   TString name(Form("%s-%s",basename.Data(),ext.Data()));
291
292   TH1* histo = tdh.CreateHisto(name.Data(),nbins,xmin,xmax);
293
294   if ( histo ) 
295   {
296     while ( ( mid = static_cast<AliMpManuUID*>(next()) ) )
297     {
298       TH1* h = tdh.CreateManuHisto(mid->DetElemId(),mid->ManuId(),nbins,xmin,xmax);
299       if ( h ) 
300       {
301         histo->Add(h);
302       }
303       delete h;
304     }
305   }
306   else
307   {
308     AliErrorClass(Form("Could not create histo for painter %s (%p) data %s (%p) external dim %d internal dim %d",
309                        painter.PathName().Data(),&painter,
310                        data->GetName(),data,externalDim,internalDim));
311   }
312   
313   if (histo) histo->SetDirectory(gROOT);
314   
315   return histo;
316 }
317
318 //_____________________________________________________________________________
319 TH1*
320 AliMUONTrackerDataHistogrammer::CreateManuHisto(Int_t detElemId, Int_t manuId,
321                                                 Int_t nbins,
322                                                 Double_t xmin,
323                                                 Double_t xmax) const
324 {
325   /// Create histogram of a given manu. Note that in order
326   /// to keep memory footprint as low as possible, you should delete
327   /// the returned pointer as soon as possible...
328   
329   TH1* h(0x0);
330   
331   if ( !fkData.HasManu(detElemId,manuId) ) return 0x0;
332   
333   if ( ( fExternalDim >= 0 && fkData.IsHistogrammed(fExternalDim) ) ||
334        ( fInternalDim >= 0 && fInternalDim < fkData.NumberOfDimensions() ) )
335   {
336     h = CreateHisto(Form("DE%04dMANU%04d",detElemId,manuId),
337                     nbins,xmin,xmax);
338     if ( h ) AddManuHisto(*h,detElemId,manuId);
339   }
340   
341   return h;
342 }
343
344 //_____________________________________________________________________________
345 void
346 AliMUONTrackerDataHistogrammer::GetDataRange(const TObjArray& manuArray, 
347                                              Double_t& xmin, Double_t& xmax) const
348 {
349   /// Get data range (in case of InternalMode() only) spanned by the manus in
350   /// manuArray
351   
352   xmin = FLT_MAX;
353   xmax = -FLT_MAX;
354   
355   if (!IsInternalMode())
356   {
357     AliError("Cannot use this method for external mode !");
358   }
359
360   AliMpManuUID* mid;
361   TIter next(&manuArray);
362   
363   while ( ( mid = static_cast<AliMpManuUID*>(next()) ) )
364   {
365     Int_t detElemId = mid->DetElemId();
366     Int_t manuId = mid->ManuId();
367     
368     for ( Int_t i = 0; i < AliMpConstants::ManuNofChannels(); ++i ) 
369     {
370       if ( fkData.HasChannel(detElemId,manuId,i) ) 
371       {
372         Double_t value = fkData.Channel(detElemId,manuId,i,fInternalDim);
373                                 
374                                 if ( ! TMath::Finite(value) )
375                                 {
376                                         AliError(Form("Got a NaN for DE %d manu %d ch %d",detElemId,manuId,i));
377                                 }
378                                 else
379                                 {
380                                         xmin = TMath::Min(xmin,value);
381                                         xmax = TMath::Max(xmax,value);
382                                 }
383       }
384     }
385   }
386
387 }
388