Line data Source code
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 18 : ClassImp(AliMUONSparseHisto)
39 : /// \endcond
40 :
41 : //______________________________________________________________________________
42 : AliMUONSparseHisto::AliMUONSparseHisto(Double_t xmin, Double_t xmax)
43 0 : : TObject(),
44 0 : fNbins(0),
45 0 : fArray(0x0),
46 0 : fXmin(xmin),
47 0 : fXmax(xmax),
48 0 : fFactor((1<<Nbits())/(xmax-xmin))
49 0 : {
50 : /// ctor
51 0 : SetBit(kOverflow,0);
52 0 : SetBit(kUnderflow,0);
53 0 : }
54 :
55 : //______________________________________________________________________________
56 : AliMUONSparseHisto::AliMUONSparseHisto(const AliMUONSparseHisto& rhs)
57 0 : : TObject(rhs),
58 0 : fNbins(0),
59 0 : fArray(0x0),
60 0 : fXmin(0.0),
61 0 : fXmax(0.0),
62 0 : fFactor(0.0)
63 0 : {
64 : /// copy ctor
65 0 : rhs.Copy(*this);
66 0 : }
67 :
68 : //______________________________________________________________________________
69 : AliMUONSparseHisto&
70 : AliMUONSparseHisto::operator=(const AliMUONSparseHisto& rhs)
71 : {
72 : /// assignment operator
73 0 : if ( this != &rhs )
74 : {
75 0 : rhs.Copy(*this);
76 0 : }
77 0 : return *this;
78 : }
79 :
80 : //______________________________________________________________________________
81 : AliMUONSparseHisto::~AliMUONSparseHisto()
82 0 : {
83 : /// dtor
84 0 : delete[] fArray;
85 0 : }
86 :
87 : //______________________________________________________________________________
88 : Bool_t
89 : AliMUONSparseHisto::Add(const AliMUONSparseHisto& h)
90 : {
91 : /// Add h to this
92 :
93 0 : if ( fXmin != h.Xmin() || fXmax != h.Xmax() )
94 : {
95 0 : AliError("Cannot add sparse histograms with different limits !");
96 0 : return kFALSE;
97 : }
98 :
99 0 : for ( Int_t i = 0; i < h.GetNbins(); ++i )
100 : {
101 0 : Fill(h.GetBinContent(i));
102 : }
103 :
104 0 : return kTRUE;
105 0 : }
106 :
107 : //______________________________________________________________________________
108 : void
109 : AliMUONSparseHisto::Clear(Option_t*)
110 : {
111 : /// Reset the content
112 0 : delete[] fArray;
113 0 : fArray = 0x0;
114 0 : fNbins = 0;
115 0 : }
116 :
117 : //______________________________________________________________________________
118 : void
119 : AliMUONSparseHisto::Copy(TObject& object) const
120 : {
121 : /// Copy this to *object
122 0 : TObject::Copy(object);
123 0 : AliMUONSparseHisto& h = static_cast<AliMUONSparseHisto&>(object);
124 0 : delete[] h.fArray;
125 0 : h.fArray = 0x0;
126 0 : h.fNbins = GetNbins();
127 0 : h.fXmin = Xmin();
128 0 : h.fXmax = Xmax();
129 0 : h.fFactor = Factor();
130 :
131 0 : if ( GetNbins() > 0 )
132 : {
133 0 : h.fArray = new UInt_t[GetNbins()];
134 0 : for ( Int_t i = 0; i < GetNbins(); ++i )
135 : {
136 0 : h.fArray[i] = GetBin(i);
137 : }
138 0 : }
139 0 : }
140 :
141 : //______________________________________________________________________________
142 : Double_t
143 : AliMUONSparseHisto::DecodeValue(Int_t value) const
144 : {
145 : /// From internal integer to "original" double
146 0 : 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 0 : 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 0 : 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 0 : 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 0 : return ( ( binCenter & 0xFFF ) ) << 20 | ( ( binContent & 0xFFFFF ) );
182 : }
183 :
184 : //______________________________________________________________________________
185 : void
186 : AliMUONSparseHisto::Expand()
187 : {
188 : /// Make fArray of size n
189 0 : if (!fArray || !fNbins)
190 : {
191 0 : delete[] fArray;
192 0 : fArray = new UInt_t[1];
193 0 : fNbins = 1;
194 0 : }
195 : else
196 : {
197 0 : UInt_t* tmp = new UInt_t[fNbins+1];
198 0 : for ( Int_t i = 0; i < fNbins; ++i )
199 : {
200 0 : tmp[i] = fArray[i];
201 : }
202 0 : delete[] fArray;
203 0 : fArray = tmp;
204 0 : ++fNbins;
205 : }
206 0 : }
207 :
208 : //______________________________________________________________________________
209 : Int_t
210 : AliMUONSparseHisto::Fill(Double_t value)
211 : {
212 : /// Fill
213 :
214 0 : if ( value < Xmin() )
215 : {
216 0 : SetBit(kUnderflow,1);
217 0 : return -1;
218 : }
219 :
220 0 : if ( value > Xmax() )
221 : {
222 0 : SetBit(kOverflow,1);
223 0 : return -1;
224 : }
225 :
226 0 : Int_t ivalue = EncodeValue(value);
227 :
228 0 : Int_t i = Find(ivalue);
229 :
230 0 : if ( i < 0 )
231 : {
232 0 : Int_t n = fNbins;
233 0 : Expand();
234 0 : fArray[n] = Encode(ivalue,1);
235 : i = n;
236 0 : }
237 : else
238 : {
239 0 : Int_t bc = GetBinContent(i);
240 0 : if ( bc < 0xFFFFF )
241 : {
242 0 : fArray[i] = Encode(ivalue,bc+1);
243 0 : }
244 : }
245 :
246 : return i;
247 0 : }
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 0 : for ( Int_t i = 0; i < GetNbins(); ++i )
256 : {
257 0 : if ( binCenter == GetBinCenter(i) ) return i;
258 : }
259 0 : return -1;
260 0 : }
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 0 : return fArray[bin];
269 : }
270 :
271 : //______________________________________________________________________________
272 : Double_t
273 : AliMUONSparseHisto::GetBinCenter(Int_t bin) const
274 : {
275 : /// Get bin center
276 0 : if ( bin < 0 ) return -FLT_MAX;
277 0 : if ( bin >= GetNbins() ) return FLT_MAX;
278 :
279 0 : UInt_t i = GetBin(bin);
280 :
281 0 : return DecodeValue(BinCenter(i));
282 0 : }
283 :
284 : //______________________________________________________________________________
285 : Int_t
286 : AliMUONSparseHisto::GetBinContent(Int_t bin) const
287 : {
288 : /// Get bin content
289 :
290 0 : if ( bin < 0 || bin >= GetNbins() ) return 0xFFFFFFFF;
291 :
292 0 : UInt_t i = GetBin(bin);
293 :
294 0 : return BinContent(i);
295 0 : }
296 :
297 : //______________________________________________________________________________
298 : void
299 : AliMUONSparseHisto::Print(Option_t* opt) const
300 : {
301 : /// Printout
302 0 : Int_t id1 = ( GetUniqueID() & 0xFFFF0000 ) >> 16;
303 0 : Int_t id2 = GetUniqueID() & 0xFFFF;
304 :
305 0 : cout << "ID=(" << id1 << "," << id2 << ") n bins = " << GetNbins();
306 0 : if ( HasUnderflow() ) cout << " has underflow(s)";
307 0 : if ( HasOverflow() ) cout << " has overflow(s)";
308 0 : cout << endl;
309 :
310 0 : TString sopt(opt);
311 0 : sopt.ToUpper();
312 :
313 0 : if ( sopt.Contains("FULL") )
314 : {
315 0 : for ( Int_t i = 0; i < GetNbins(); ++i )
316 : {
317 0 : cout << Form("Bin (%10u) %e = %6d",GetBin(i),GetBinCenter(i),GetBinContent(i)) << endl;
318 : }
319 0 : }
320 0 : }
|