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