1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 #include "AliMUONSparseHisto.h"
21 #include <Riostream.h>
26 /// \class AliMUONSparseHisto
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 ;-)
33 /// \author Laurent Aphecetche, Subatech
36 ClassImp(AliMUONSparseHisto)
39 //______________________________________________________________________________
40 AliMUONSparseHisto::AliMUONSparseHisto(Double_t xmin, Double_t xmax)
46 fFactor((1<<Nbits())/(xmax-xmin))
53 //______________________________________________________________________________
54 AliMUONSparseHisto::AliMUONSparseHisto(const AliMUONSparseHisto& rhs)
66 //______________________________________________________________________________
68 AliMUONSparseHisto::operator=(const AliMUONSparseHisto& rhs)
70 /// assignment operator
78 //______________________________________________________________________________
79 AliMUONSparseHisto::~AliMUONSparseHisto()
85 //______________________________________________________________________________
87 AliMUONSparseHisto::Add(const AliMUONSparseHisto& h)
91 if ( fXmin != h.Xmin() || fXmax != h.Xmax() )
93 AliError("Cannot add sparse histograms with different limits !");
97 for ( Int_t i = 0; i < h.GetNbins(); ++i )
99 Fill(h.GetBinContent(i));
105 //______________________________________________________________________________
107 AliMUONSparseHisto::Clear(Option_t*)
109 /// Reset the content
115 //______________________________________________________________________________
117 AliMUONSparseHisto::Copy(TObject& object) const
119 /// Copy this to *object
120 TObject::Copy(object);
121 AliMUONSparseHisto& h = static_cast<AliMUONSparseHisto&>(object);
124 h.fNbins = GetNbins();
127 h.fFactor = Factor();
129 if ( GetNbins() > 0 )
131 h.fArray = new UInt_t[GetNbins()];
132 for ( Int_t i = 0; i < GetNbins(); ++i )
134 h.fArray[i] = GetBin(i);
139 //______________________________________________________________________________
141 AliMUONSparseHisto::DecodeValue(Int_t value) const
143 /// From internal integer to "original" double
144 return value/Factor() + Xmin();
147 //______________________________________________________________________________
149 AliMUONSparseHisto::EncodeValue(Double_t value) const
151 /// From original double value to internal integer
152 return TMath::Nint(Factor()*(value-Xmin()));
155 //______________________________________________________________________________
157 AliMUONSparseHisto::BinCenter(UInt_t x) const
159 /// Extract binCenter part from x
161 return ( x & 0xFFF00000 ) >> 20;
164 //______________________________________________________________________________
166 AliMUONSparseHisto::BinContent(UInt_t x) const
168 /// Extract binContent part from x
170 return (x & 0xFFFFF);
173 //______________________________________________________________________________
175 AliMUONSparseHisto::Encode(Int_t binCenter, Int_t binContent) const
177 /// Convert (binCenter,binContent) into a single value
179 return ( ( binCenter & 0xFFF ) ) << 20 | ( ( binContent & 0xFFFFF ) );
182 //______________________________________________________________________________
184 AliMUONSparseHisto::Expand()
186 /// Make fArray of size n
187 if (!fArray || !fNbins)
190 fArray = new UInt_t[1];
195 UInt_t* tmp = new UInt_t[fNbins+1];
196 for ( Int_t i = 0; i < fNbins; ++i )
206 //______________________________________________________________________________
208 AliMUONSparseHisto::Fill(Double_t value)
212 if ( value < Xmin() )
214 SetBit(kUnderflow,1);
218 if ( value > Xmax() )
224 Int_t ivalue = EncodeValue(value);
226 Int_t i = Find(ivalue);
232 fArray[n] = Encode(ivalue,1);
237 Int_t bc = GetBinContent(i);
240 fArray[i] = Encode(ivalue,bc+1);
247 //______________________________________________________________________________
249 AliMUONSparseHisto::Find(Int_t binCenter) const
251 /// Return the index in fArray of value, or -1 if not found
253 for ( Int_t i = 0; i < GetNbins(); ++i )
255 if ( binCenter == GetBinCenter(i) ) return i;
260 //______________________________________________________________________________
262 AliMUONSparseHisto::GetBin(Int_t bin) const
264 /// Get bin, which is a compacted form of two integers : (binCenter,binContent)
265 /// where binCenter itself might be an integer-fied double value.
269 //______________________________________________________________________________
271 AliMUONSparseHisto::GetBinCenter(Int_t bin) const
274 if ( bin < 0 ) return -FLT_MAX;
275 if ( bin >= GetNbins() ) return FLT_MAX;
277 UInt_t i = GetBin(bin);
279 return DecodeValue(BinCenter(i));
282 //______________________________________________________________________________
284 AliMUONSparseHisto::GetBinContent(Int_t bin) const
288 if ( bin < 0 || bin >= GetNbins() ) return 0xFFFFFFFF;
290 UInt_t i = GetBin(bin);
292 return BinContent(i);
295 //______________________________________________________________________________
297 AliMUONSparseHisto::Print(Option_t* opt) const
300 Int_t id1 = ( GetUniqueID() & 0xFFFF0000 ) >> 16;
301 Int_t id2 = GetUniqueID() & 0xFFFF;
303 cout << "ID=(" << id1 << "," << id2 << ") n bins = " << GetNbins();
304 if ( HasUnderflow() ) cout << " has underflow(s)";
305 if ( HasOverflow() ) cout << " has overflow(s)";
311 if ( sopt.Contains("FULL") )
313 for ( Int_t i = 0; i < GetNbins(); ++i )
315 cout << Form("Bin (%10u) %e = %6d",GetBin(i),GetBinCenter(i),GetBinContent(i)) << endl;