Implementation of VCalibParam to store double precision values (Laurent)
[u/mrichter/AliRoot.git] / MUON / AliMUONCalibParamND.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 "AliMUONCalibParamND.h"
19
20 #include "AliLog.h"
21
22 #include "Riostream.h"
23 #include "TMath.h"
24 #include "TString.h"
25
26 ///
27 /// \class AliMUONCalibParamND
28 ///
29 /// Handle the case of N floating point (double precision) parameters per channel.
30 ///
31 /// \author Laurent Aphecetche
32
33 /// \cond CLASSIMP
34 ClassImp(AliMUONCalibParamND)
35 /// \endcond
36
37 //_____________________________________________________________________________
38 AliMUONCalibParamND::AliMUONCalibParamND() 
39 : AliMUONVCalibParam(),
40   fDimension(0),
41   fSize(0),
42   fN(0),
43   fValues(0x0)
44 {
45 /// Default constructor.
46 }
47
48 //_____________________________________________________________________________
49 AliMUONCalibParamND::AliMUONCalibParamND(Int_t dimension, Int_t theSize, 
50                                          Int_t id0, Int_t id1,
51                                          Double_t fillWithValue) 
52 : AliMUONVCalibParam(id0,id1),
53   fDimension(dimension),
54   fSize(theSize),
55   fN(fSize*fDimension),
56   fValues(0x0)
57 {
58 /// Normal constructor, where theSize specifies the number of channels handled
59 /// by this object, and fillWithValue the default value assigned to each
60 /// channel.
61
62   if ( fN > 0 )
63   {
64     fValues = new Double_t[fN];
65     for ( Int_t i = 0; i < fN; ++i )
66     {
67       fValues[i] = fillWithValue;
68     }
69   }
70 }
71
72
73 //_____________________________________________________________________________
74 AliMUONCalibParamND::AliMUONCalibParamND(const AliMUONCalibParamND& other) 
75 : AliMUONVCalibParam(),
76 fDimension(0),
77 fSize(0),
78 fN(0),
79 fValues(0x0)
80 {
81 /// Copy constructor.
82
83   other.CopyTo(*this);
84 }
85
86 //_____________________________________________________________________________
87 AliMUONCalibParamND&
88 AliMUONCalibParamND::operator=(const AliMUONCalibParamND& other) 
89 {
90 /// Assignment operator
91
92   other.CopyTo(*this);
93   return *this;
94 }
95
96 //_____________________________________________________________________________
97 AliMUONCalibParamND::~AliMUONCalibParamND()
98 {
99 /// Destructor
100
101   delete[] fValues;
102 }
103
104 //_____________________________________________________________________________
105 void
106 AliMUONCalibParamND::CopyTo(AliMUONCalibParamND& destination) const
107 {
108 /// Copy *this to destination
109
110   delete[] destination.fValues;
111   destination.fN = fN;
112   destination.fSize = fSize;
113   destination.fDimension = fDimension;
114
115   if ( fN > 0 )
116   {
117     destination.fValues = new Double_t[fN];
118     for ( Int_t i = 0; i < fN; ++i )
119     {
120       destination.fValues[i] = fValues[i];
121     }
122   }
123 }
124
125 //_____________________________________________________________________________
126 Int_t
127 AliMUONCalibParamND::Index(Int_t i, Int_t j) const
128 {
129 /// Compute the 1D index of the internal storage from the pair (i,j)
130 /// Returns -1 if the (i,j) pair is invalid
131
132   if ( i >= 0 && i < Size() && j >= 0 && j < Dimension() )
133   {
134     return i + Size()*j;
135   }
136   return -1;
137 }
138
139 //_____________________________________________________________________________
140 void
141 AliMUONCalibParamND::Print(Option_t* opt) const
142 {
143 /// Output this object to stdout.
144 /// If opt=="full", then all channels are printed, 
145 /// if opt=="mean#", only the mean and sigma value are printed for j-th dimension
146 /// otherwise only the general characteristics are printed.
147
148   TString sopt(opt);
149   sopt.ToUpper();
150   cout << Form("AliMUONCalibParamND Id=(%d,%d) Size=%d Dimension=%d",ID0(),
151                ID1(),Size(),Dimension()) << endl;
152   if ( sopt.Contains("FULL") )
153   {
154     for ( Int_t i = 0; i < Size(); ++i )
155     {
156       cout << Form("CH %3d",i);
157       for ( Int_t j = 0; j < Dimension(); ++j )
158       {
159         cout << Form(" %g",ValueAsDouble(i,j));
160       }
161       cout << endl;
162     }
163   }  
164   if ( sopt.Contains("MEAN") )
165   {
166     Int_t j(0);
167     sscanf(sopt.Data(),"MEAN%d",&j);
168     
169     Double_t mean(0);
170     Double_t v2(0);
171     
172     Int_t n = Size();
173     
174     for ( Int_t i = 0; i < Size(); ++i )
175     {
176       Float_t v = ValueAsDouble(i,j);
177       mean += v;
178       v2 += v*v;
179     }
180     mean /= n;
181     float sigma = 0;
182     if ( n > 1 ) sigma = TMath::Sqrt( (v2-n*mean*mean)/(n-1) );
183     cout << Form(" Mean(j=%d)=%g Sigma(j=%d)=%g",j,mean,j,sigma) << endl;
184   }
185   
186 }
187
188 //_____________________________________________________________________________
189 void
190 AliMUONCalibParamND::SetValueAsDouble(Int_t i, Int_t j, Double_t value)
191 {
192   /// Set one value as a double, after checking that the indices are correct.
193   
194   Int_t ix = Index(i,j);
195   
196   if ( ix < 0 )
197   {
198     AliError(Form("Invalid (i,j)=(%d,%d) max allowed is (%d,%d)",
199                   i,j,Size()-1,Dimension()-1));
200   }
201   else
202   {
203     fValues[ix]=value;
204   }
205 }
206
207
208 //_____________________________________________________________________________
209 void
210 AliMUONCalibParamND::SetValueAsFloat(Int_t i, Int_t j, Float_t value)
211 {
212   /// Set one value as a float, after checking that the indices are correct.
213   SetValueAsDouble(i,j,static_cast<Double_t>(value));
214 }
215
216 //_____________________________________________________________________________
217 void
218 AliMUONCalibParamND::SetValueAsInt(Int_t i, Int_t j, Int_t value)
219 {
220 /// Set one value as an int.
221
222   SetValueAsFloat(i,j,static_cast<Float_t>(value));
223 }
224
225 //_____________________________________________________________________________
226 Double_t
227 AliMUONCalibParamND::ValueAsDouble(Int_t i, Int_t j) const
228 {
229   /// Return the value as a double (which it is), after checking indices.
230   
231   Int_t ix = Index(i,j);
232   
233   if ( ix < 0 )
234   {
235     AliError(Form("Invalid (i,j)=(%d,%d) max allowed is (%d,%d)",
236                   i,j,Size()-1,Dimension()-1));
237     return 0.0;
238   }
239   else
240   {
241     return fValues[ix];
242   }
243 }
244
245 //_____________________________________________________________________________
246 Float_t
247 AliMUONCalibParamND::ValueAsFloat(Int_t i, Int_t j) const
248 {
249 /// Return the value as a float 
250   return static_cast<Float_t>(ValueAsDouble(i,j));
251 }
252
253 //_____________________________________________________________________________
254 Int_t
255 AliMUONCalibParamND::ValueAsInt(Int_t i, Int_t j) const
256 {
257 /// Return the value as an int, by rounding the internal float value.
258
259   Float_t v = ValueAsFloat(i,j);
260   return TMath::Nint(v);
261 }