DQM configure file
[u/mrichter/AliRoot.git] / MUON / AliMUONSparseHisto.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 "AliMUONSparseHisto.h"
19
20 #include "AliLog.h"
21 #include <Riostream.h>
22 #include <TH1.h>
23 #include <TMath.h>
24 #include <TString.h>
25
26 /// \class AliMUONSparseHisto
27 ///
28 /// Tiny histogram-like class to hold some distributions of tracker data.
29 /// Only intent of this class is to minimize memory consumption, in
30 /// order to fit a maximum number of channel histograms into memory.
31 /// The rest is not supported ;-)
32 ///
33 /// \author Laurent Aphecetche, Subatech
34
35 using std::cout;
36 using std::endl;
37 /// \cond CLASSIMP
38 ClassImp(AliMUONSparseHisto)
39 /// \endcond
40
41 //______________________________________________________________________________
42 AliMUONSparseHisto::AliMUONSparseHisto(Double_t xmin, Double_t xmax)
43 : TObject(),
44 fNbins(0),
45 fArray(0x0),
46 fXmin(xmin),
47 fXmax(xmax),
48 fFactor((1<<Nbits())/(xmax-xmin))
49 {
50   /// ctor
51   SetBit(kOverflow,0);
52   SetBit(kUnderflow,0);
53 }
54
55 //______________________________________________________________________________
56 AliMUONSparseHisto::AliMUONSparseHisto(const AliMUONSparseHisto& rhs)
57 : TObject(rhs),
58 fNbins(0),
59 fArray(0x0),
60 fXmin(0.0),
61 fXmax(0.0),
62 fFactor(0.0)
63 {
64   /// copy ctor
65   rhs.Copy(*this);
66 }
67
68 //______________________________________________________________________________
69 AliMUONSparseHisto&
70 AliMUONSparseHisto::operator=(const AliMUONSparseHisto& rhs)
71 {
72   /// assignment operator
73   if ( this != &rhs )
74   {
75     rhs.Copy(*this);
76   }
77   return *this;
78 }
79
80 //______________________________________________________________________________
81 AliMUONSparseHisto::~AliMUONSparseHisto()
82 {
83   /// dtor
84   delete[] fArray;
85 }
86
87 //______________________________________________________________________________
88 Bool_t 
89 AliMUONSparseHisto::Add(const AliMUONSparseHisto& h)
90 {
91   /// Add h to this
92
93   if ( fXmin != h.Xmin() || fXmax != h.Xmax() ) 
94   {
95     AliError("Cannot add sparse histograms with different limits !");
96     return kFALSE;
97   }
98   
99   for ( Int_t i = 0; i < h.GetNbins(); ++i ) 
100   {
101     Fill(h.GetBinContent(i));
102   }  
103   
104   return kTRUE;
105 }
106
107 //______________________________________________________________________________
108 void 
109 AliMUONSparseHisto::Clear(Option_t*)
110 {
111   /// Reset the content
112   delete[] fArray;
113   fArray = 0x0;
114   fNbins = 0;
115 }  
116
117 //______________________________________________________________________________
118 void 
119 AliMUONSparseHisto::Copy(TObject& object) const
120 {
121   /// Copy this to *object
122   TObject::Copy(object);
123   AliMUONSparseHisto& h = static_cast<AliMUONSparseHisto&>(object);
124   delete[] h.fArray;
125   h.fArray = 0x0;
126   h.fNbins = GetNbins();
127   h.fXmin = Xmin();
128   h.fXmax = Xmax();
129   h.fFactor = Factor();
130   
131   if ( GetNbins() > 0 )
132   {
133     h.fArray = new UInt_t[GetNbins()];
134     for ( Int_t i = 0; i < GetNbins(); ++i ) 
135     {
136       h.fArray[i] = GetBin(i);
137     }
138   }
139 }
140
141 //______________________________________________________________________________
142 Double_t 
143 AliMUONSparseHisto::DecodeValue(Int_t value) const
144 {
145   /// From internal integer to "original" double
146   return value/Factor() + Xmin();
147 }
148
149 //______________________________________________________________________________
150 Int_t 
151 AliMUONSparseHisto::EncodeValue(Double_t value) const
152 {
153   /// From original double value to internal integer
154   return TMath::Nint(Factor()*(value-Xmin()));
155 }
156
157 //______________________________________________________________________________
158 Int_t
159 AliMUONSparseHisto::BinCenter(UInt_t x) const
160 {
161   /// Extract binCenter part from x
162   
163   return ( x & 0xFFF00000 ) >> 20;
164 }
165
166 //______________________________________________________________________________
167 Int_t
168 AliMUONSparseHisto::BinContent(UInt_t x) const
169 {
170   /// Extract binContent part from x
171   
172   return (x & 0xFFFFF);
173 }
174
175 //______________________________________________________________________________
176 UInt_t 
177 AliMUONSparseHisto::Encode(Int_t binCenter, Int_t binContent) const
178 {
179   /// Convert (binCenter,binContent) into a single value
180   
181   return ( ( binCenter & 0xFFF ) ) << 20 | ( ( binContent & 0xFFFFF ) );
182 }
183
184 //______________________________________________________________________________
185 void 
186 AliMUONSparseHisto::Expand()
187 {
188   /// Make fArray of size n
189   if (!fArray || !fNbins) 
190   {
191     delete[] fArray;
192     fArray = new UInt_t[1];
193     fNbins = 1;
194   }
195   else
196   {
197     UInt_t* tmp = new UInt_t[fNbins+1];
198     for ( Int_t i = 0; i < fNbins; ++i ) 
199     {
200       tmp[i] = fArray[i];
201     }
202     delete[] fArray;
203     fArray = tmp;
204     ++fNbins;
205   }
206 }
207
208 //______________________________________________________________________________
209 Int_t 
210 AliMUONSparseHisto::Fill(Double_t value)
211 {
212   /// Fill
213   
214   if ( value < Xmin() ) 
215   {
216     SetBit(kUnderflow,1);
217     return -1;
218   }
219   
220   if ( value > Xmax() ) 
221   {
222     SetBit(kOverflow,1);
223     return -1;
224   }
225   
226   Int_t ivalue = EncodeValue(value);
227   
228   Int_t i = Find(ivalue);
229   
230   if ( i < 0 ) 
231   {
232     Int_t n = fNbins;
233     Expand();
234     fArray[n] = Encode(ivalue,1);
235     i = n;
236   }
237   else
238   {
239     Int_t bc = GetBinContent(i);
240     if ( bc < 0xFFFFF ) 
241     {
242       fArray[i] = Encode(ivalue,bc+1);
243     }
244   }
245     
246   return i;
247 }
248
249 //______________________________________________________________________________
250 Int_t 
251 AliMUONSparseHisto::Find(Int_t binCenter) const
252 {
253   /// Return the index in fArray of value, or -1 if not found
254   
255   for ( Int_t i = 0; i < GetNbins(); ++i ) 
256   {
257     if ( binCenter == GetBinCenter(i) ) return i;
258   }
259   return -1;
260 }
261
262 //______________________________________________________________________________
263 UInt_t 
264 AliMUONSparseHisto::GetBin(Int_t bin) const
265 {
266   /// Get bin, which is a compacted form of two integers : (binCenter,binContent)
267   /// where binCenter itself might be an integer-fied double value.
268   return fArray[bin];
269 }
270
271 //______________________________________________________________________________
272 Double_t 
273 AliMUONSparseHisto::GetBinCenter(Int_t bin) const
274 {
275   /// Get bin center
276   if ( bin < 0 ) return -FLT_MAX;
277   if ( bin >= GetNbins() ) return FLT_MAX;
278   
279   UInt_t i = GetBin(bin);
280   
281   return DecodeValue(BinCenter(i));
282 }
283
284 //______________________________________________________________________________
285 Int_t 
286 AliMUONSparseHisto::GetBinContent(Int_t bin) const
287 {
288   /// Get bin content
289   
290   if ( bin < 0 || bin >= GetNbins() ) return 0xFFFFFFFF;
291
292   UInt_t i = GetBin(bin);
293
294   return BinContent(i);
295 }
296
297 //______________________________________________________________________________
298 void 
299 AliMUONSparseHisto::Print(Option_t* opt) const
300 {
301   /// Printout
302   Int_t id1 = ( GetUniqueID() & 0xFFFF0000 ) >> 16;
303   Int_t id2 = GetUniqueID() & 0xFFFF;
304   
305   cout << "ID=(" << id1 << "," << id2 << ") n bins = " << GetNbins();
306   if ( HasUnderflow() ) cout << " has underflow(s)";
307   if ( HasOverflow() ) cout << " has overflow(s)";
308   cout << endl;
309   
310   TString sopt(opt);
311   sopt.ToUpper();
312   
313   if ( sopt.Contains("FULL") )
314   {
315     for ( Int_t i = 0; i < GetNbins(); ++i ) 
316     {
317       cout << Form("Bin (%10u) %e = %6d",GetBin(i),GetBinCenter(i),GetBinContent(i)) << endl;
318     }
319   }
320 }