propagate cluster error parametrization
[u/mrichter/AliRoot.git] / TRD / AliTRDtrapAlu.cxx
1 /**************************************************************************\r
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *\r
3 *                                                                        *\r
4 * Author: The ALICE Off-line Project.                                    *\r
5 * Contributors are mentioned in the code where appropriate.              *\r
6 *                                                                        *\r
7 * Permission to use, copy, modify and distribute this software and its   *\r
8 * documentation strictly for non-commercial purposes is hereby granted   *\r
9 * without fee, provided that the above copyright notice appears in all   *\r
10 * copies and that both the copyright notice and this permission notice   *\r
11 * appear in the supporting documentation. The authors make no claims     *\r
12 * about the suitability of this software for any purpose. It is          *\r
13 * provided "as is" without express or implied warranty.                  *\r
14 **************************************************************************/\r
15 \r
16 /* $Id: AliTRDtrapAlu.cxx 25891 2008-05-19 14:58:18Z fca $ */\r
17 \r
18 ///////////////////////////////////////////////////////////////////////////////\r
19 //                                                                           //\r
20 //  TRAP-ALU implementation                                                  //\r
21 //                                                                           //\r
22 //  Author:                                                                  //\r
23 //    Clemens Haltebourg <halteb@physi.uni-heidelberg.de>                    //\r
24 //                                                                           //\r
25 //  Usage of the class:                                                      //\r
26 //    Declaration of class instances: AliTRDtrapAlu a,b,c;                   //\r
27 //    Initialization:                 a.Init(2,11); b.Init(4,4); c.Init(5,4);//\r
28 //    Assigning values:               a.AssignDouble(5.7); b.AssignInt(3);   //\r
29 //    (you can also do b.AssignDouble(3) with same effect);                  //\r
30 //    Calculation:                     c = a*b;                              //\r
31 //    Test if c has right value:       c.WriteWord();                        //\r
32 //    Don't declare pointers; operators not overridden for pointer types;    //\r
33 //    You have to dereference yourself;                                      //\r
34 //    Use operators +,-,*,/ only with instances of the class; don't do       //\r
35 //    things like c=a*2 but rather b.AssignInt(2); c=a*b;                    //\r
36 //                                                                           //\r
37 ///////////////////////////////////////////////////////////////////////////////\r
38 \r
39 #include "AliTRDtrapAlu.h"\r
40 \r
41 ClassImp(AliTRDtrapAlu)\r
42 \r
43 //_____________________________________________________________________________  \r
44 AliTRDtrapAlu::AliTRDtrapAlu():TObject()\r
45 \r
46   ,fValue(0)\r
47   ,fPreCom(0)\r
48   ,fPostCom(0)\r
49   ,fuRestriction(0)\r
50   ,flRestriction(0)\r
51   ,fSigned(kFALSE)\r
52 \r
53 {\r
54   \r
55   // default constructor\r
56   \r
57 }\r
58 \r
59 //_____________________________________________________________________________  \r
60 AliTRDtrapAlu::~AliTRDtrapAlu(){\r
61   //destructor\r
62 }\r
63 \r
64 //_____________________________________________________________________________  \r
65 void AliTRDtrapAlu::Init(const Int_t& precom, const Int_t& postcom, const Int_t& lRestriction, const Int_t& uRestriction){\r
66    // initialization: characterizes the bit-word (nr of pre- and post-comma bits, boundaries)\r
67    fPostCom = postcom;\r
68    fPreCom  = precom;\r
69    fValue   = 0;       //currently, re-initialization kills the value\r
70    fSigned  = kFALSE;\r
71 \r
72    if (fPreCom + fPostCom > 32 || fPreCom > 31) {fPreCom = 1; fPostCom = 0;return;} // prevent pre-comma part exceeding 31 spaces\r
73    if (fPreCom  <= 0) {fPreCom  = 1;}\r
74    if (fPostCom <  0) {fPostCom = 0;}\r
75    \r
76    Int_t lut = LUT(fPreCom + fPostCom)-1;\r
77    if (uRestriction <= -1 || uRestriction > lut) {fuRestriction = lut;}\r
78    else {fuRestriction = uRestriction;}\r
79    if (lRestriction <= -1 || lRestriction > fuRestriction) {flRestriction = -lut;}\r
80    else {flRestriction = lRestriction;}\r
81    // up to now you can only choose a non-negative lower restriction (e.g. if you want your values to be >=0) ; can't deal with asymmetric borders; have to be implemented if needed\r
82 }\r
83 \r
84 //_____________________________________________________________________________  \r
85 Double_t AliTRDtrapAlu::GetValueWhole() const { \r
86    // get the actual value (respecting pre- and post-comma parts) in integer-description\r
87    Double_t valPre = (Double_t)(fValue>>fPostCom);\r
88    Double_t valPost = 0.0;\r
89    for(Int_t i = 0; i<=fPostCom-1; i++){\r
90      Double_t num = (fValue>>i)&1;\r
91      Double_t denom = LUT(fPostCom-i);\r
92      valPost = valPost + num/denom;\r
93    }\r
94    Double_t val = valPre + valPost;\r
95    return val;\r
96  }\r
97 \r
98 //_____________________________________________________________________________  \r
99 void AliTRDtrapAlu::WriteWord(){\r
100   // for debugging purposes\r
101   printf("bit-word: ");\r
102   if (fSigned == true) printf("-");\r
103   for(Int_t i = fPostCom + fPreCom - 1; i >= fPostCom; i--){  //read from behind in order to write the word from left to right\r
104     printf("%d",(fValue>>i) & 1);\r
105   }\r
106   printf(".");\r
107   for (Int_t j = fPostCom - 1; j >= 0; j--){\r
108     printf("%d",(fValue>>j) & 1);\r
109   }\r
110   printf("\n");\r
111          \r
112 }\r
113 \r
114 //_____________________________________________________________________________  \r
115 AliTRDtrapAlu& AliTRDtrapAlu::AssignInt(const Int_t& first){  \r
116   // assign an integer\r
117 \r
118   // parameter "first" is an integer for the pre-comma part (not UInt in order to match the error case first<0)\r
119   fSigned = kFALSE;\r
120   Int_t exponent = fPreCom + fPostCom;\r
121 \r
122     \r
123   if (first<0) {\r
124     fValue  = 0;                      //setting fValue to 0; first should not be negative\r
125     fValue  = fValue & 0;\r
126     return *this;\r
127   }\r
128 \r
129   if (CheckUSize(first<<fPostCom) == kFALSE){\r
130     \r
131     //setting fValue to maximum; first was to big\r
132     fValue  = fuRestriction;\r
133     fValue  = fValue & (LUT(exponent)-1);\r
134     return *this;\r
135   }\r
136 \r
137   if (CheckLSize(first<<fPostCom) == kFALSE){\r
138     \r
139     //setting fValue to minimum; first was to small\r
140     fValue  = flRestriction;\r
141     fValue  = fValue & (LUT(exponent)-1);\r
142     return *this;\r
143   }\r
144 \r
145   \r
146   fValue  = first;\r
147   fValue  = fValue<<fPostCom; \r
148   fValue  = fValue & (LUT(exponent)-1);\r
149  \r
150   return *this;\r
151     \r
152 }\r
153 \r
154 //_____________________________________________________________________________  \r
155 AliTRDtrapAlu& AliTRDtrapAlu::AssignDouble(const  Double_t& first){\r
156   // assign a double\r
157  \r
158   fSigned = kFALSE;\r
159   Int_t exponent           = fPreCom + fPostCom;\r
160   Int_t firstPre          = 0;  //integer part of first\r
161   Int_t firstPost         = 0;  //comma part of first (cut off with enough accuracy\r
162   Int_t c                  = 0;\r
163   Double_t firstPreFloat = 0;\r
164   \r
165   \r
166   Int_t power1 = LUT(exponent);\r
167   \r
168   firstPre       = (Int_t)first;\r
169   firstPreFloat = firstPre;\r
170   \r
171   if(firstPre < 0){\r
172     fValue  = 0;\r
173     fValue = fValue & 0;\r
174     return *this;\r
175   }\r
176   \r
177   if(CheckUSize((Int_t)(first*LUT(fPostCom))) == kFALSE){\r
178     \r
179     //fValue  = MakePower(2,fPreCom) - 1;\r
180     fValue  = fuRestriction;\r
181     fValue  = fValue & (power1 - 1);\r
182     return *this;\r
183   }\r
184   \r
185   if(CheckLSize((Int_t)(first*LUT(fPostCom))) == kFALSE){\r
186     \r
187     //fValue  = MakePower(2,fPreCom) - 1;\r
188     fValue  = flRestriction;\r
189     fValue  = fValue & (power1 - 1);\r
190     return *this;\r
191   }\r
192   \r
193 \r
194   fValue = firstPre;\r
195   \r
196   //get post comma part with adequate accuracy\r
197   firstPost = (Int_t)((first - firstPreFloat)*LUT(fPostCom));\r
198   for(Int_t i = 1; i <= fPostCom; i++) {\r
199     c = (firstPost>>(fPostCom - i)) & 1;\r
200     fValue  = fValue<<1;\r
201     fValue  = fValue | c;\r
202   }\r
203 \r
204   fValue = fValue & (power1 - 1);\r
205   return *this;\r
206 }\r
207 \r
208 //_____________________________________________________________________________  \r
209 AliTRDtrapAlu& AliTRDtrapAlu::operator=(const AliTRDtrapAlu& binary){\r
210   // assign an object of type AliTRDtrapAlu\r
211 \r
212   Int_t c    = 0;\r
213   //Int_t exponent = fPreCom + fPostCom;\r
214   \r
215   \r
216   Int_t power1 = LUT(fPreCom + fPostCom);\r
217 \r
218   fValue          = binary.GetValue();         // in case this==&binary : binary's values are overwritten\r
219   Int_t diffPost = binary.GetPost()-fPostCom;\r
220   Int_t check     = 0;\r
221   if(diffPost<0) check = fValue<<(-diffPost);\r
222   else check = fValue>>(diffPost);\r
223   if (CheckUSize(check)==kFALSE){    //checking size of pre-comma part\r
224     \r
225     //setting fValue to maximum\r
226       \r
227            \r
228     fValue  = fuRestriction;         // fuRestriction >= 0 \r
229     fValue  = fValue & (power1 - 1);\r
230     fSigned = kFALSE;\r
231     return *this;\r
232   }\r
233 \r
234   Int_t val = (binary.GetSign()==kFALSE) ? check : -check; \r
235   if (CheckLSize(val)==kFALSE){    //checking size of pre-comma part\r
236     \r
237     //setting fValue to minimum\r
238       \r
239            \r
240     if (flRestriction < 0) {\r
241       fValue  = -flRestriction;\r
242       fSigned = kTRUE;\r
243     }\r
244     else {\r
245       fValue  = flRestriction;\r
246       fSigned = kFALSE;\r
247     }\r
248     fValue  = fValue & (power1 - 1);\r
249     return *this;\r
250   }\r
251   \r
252   if (this == & binary) return *this;\r
253   \r
254   fSigned = kFALSE;\r
255   Int_t iValue = fValue;\r
256   fValue = fValue>>(binary.GetPost());           //only keep the valid pre-comma bits\r
257   \r
258   //append existing post-comma bits to fValue; cut off or add 0 if post-comma numbers don`t match\r
259   for(Int_t i = 1; i <= fPostCom; i++){\r
260     if(i <= (binary.GetPost())){\r
261       c = ((iValue)>>(binary.GetPost()-i)) & 1;\r
262     }\r
263     else{\r
264       c = 0;\r
265     }\r
266     fValue  = fValue<<1;\r
267     fValue  = fValue | c;\r
268   }\r
269   \r
270   fValue = fValue & (power1 - 1);\r
271   fSigned = binary.GetSign();\r
272   return *this;\r
273 }\r
274 \r
275 //_____________________________________________________________________________  \r
276 AliTRDtrapAlu AliTRDtrapAlu::operator+(const AliTRDtrapAlu& binary){ \r
277   // + operator\r
278 \r
279   //no const parameter because referenced object will be changed\r
280      \r
281     AliTRDtrapAlu alu;\r
282   \r
283   Int_t binPre     = binary.GetPre();\r
284   Int_t binPost    = binary.GetPost();\r
285   Int_t binVal     = binary.GetValue();\r
286   \r
287   Int_t min         = Min(binPost,fPostCom);\r
288   Int_t max         = Max(binPre,fPreCom);\r
289   \r
290   Int_t shift       = binPost - min;\r
291   Int_t add1        = (binVal)>>(shift);    //for addition: cut off at minimum accuracy\r
292   shift             = fPostCom - min;\r
293   Int_t add2        = fValue>>(shift);\r
294   if(binary.GetSign() == kTRUE) add1 = -add1;\r
295   if(fSigned == kTRUE) add2 = -add2;\r
296   Int_t add = add1 + add2;\r
297   \r
298   /*\r
299   //because the parameter "binary" could be a reference to the object to which Mem() is a reference, do not change Mem() until you have extracted all information from "binary"; otherwise you change the information you would like to read\r
300   Mem().Init(max + 1,min);      //buffer: enough space for pre-comma,post-comma according to accuracy\r
301   Mem().AssignFormatted(Max(add,-add));\r
302   Mem().SetSign(add);\r
303   \r
304 \r
305   //Mem().FastInit(max+1,min,add);\r
306   return Mem();*/\r
307  \r
308  alu.Init(max + 1,min);      //buffer: enough space for pre-comma,post-comma according to accuracy\r
309  alu.AssignFormatted(Max(add,-add));\r
310  alu.SetSign(add);\r
311  \r
312  return alu;\r
313 \r
314 }\r
315 \r
316 //_____________________________________________________________________________  \r
317 AliTRDtrapAlu AliTRDtrapAlu::operator-(const AliTRDtrapAlu& binary){\r
318   // - operator    \r
319 \r
320     AliTRDtrapAlu alu;\r
321 \r
322   Int_t binPre    = binary.GetPre();\r
323   Int_t binPost   = binary.GetPost();\r
324   Int_t binVal    = binary.GetValue();\r
325 \r
326 \r
327   Int_t min      = Min(binPost,fPostCom);\r
328   Int_t max      = Max(binPre,fPreCom);\r
329 \r
330   Int_t shift    = binPost - min;\r
331   Int_t sub1 = (binVal)>>(shift); //for addition: cut off at minimum accuracy\r
332   shift = fPostCom - min;\r
333   Int_t sub2 = fValue>>(shift);\r
334   if(binary.GetSign() == kTRUE) sub1 = -sub1;\r
335   if(fSigned  == kTRUE) sub2 = -sub2;\r
336   Int_t sub = sub2 - sub1;     // order of subtraction is important\r
337  \r
338 /*\r
339   Mem().Init(max + 1,min);      //buffer: enough space for pre-comma, post-comma according to accuracy\r
340   Mem().AssignFormatted(Max(sub,-sub)); \r
341   Mem().SetSign(sub);\r
342   //Mem().FastInit(max+1,min,sub);\r
343   return Mem();*/\r
344   \r
345   alu.Init(max + 1,min);\r
346   alu.AssignFormatted(Max(sub,-sub)); \r
347   alu.SetSign(sub);\r
348 \r
349   return alu;\r
350 \r
351\r
352 \r
353 //_____________________________________________________________________________  \r
354 AliTRDtrapAlu AliTRDtrapAlu::operator*(const AliTRDtrapAlu& binary){\r
355   // * operator\r
356   \r
357     AliTRDtrapAlu alu;\r
358 \r
359   Int_t binPre   = binary.GetPre();\r
360   Int_t binPost  = binary.GetPost();\r
361 \r
362 \r
363   Int_t min      = Min(binPost,fPostCom);\r
364   Int_t max      = Max(binPre,fPreCom);\r
365 \r
366   \r
367   Int_t mult1 = binary.GetValue();\r
368   Int_t mult2 = fValue;\r
369   Int_t shift  = (Int_t)(fPostCom + binPost - min);\r
370   Double_t fmult1 = (Double_t)mult1;\r
371   Double_t fmult2 = (Double_t)mult2;\r
372   (fmult1 > fmult2) ? fmult1 = fmult1/LUT(shift) : fmult2 = fmult2/LUT(shift);\r
373   \r
374     \r
375   if (binary.GetSign() == kTRUE) fmult1 = -fmult1;\r
376   if (fSigned  == kTRUE) fmult2 = -fmult2;\r
377   Double_t fmult  = fmult1*fmult2;\r
378   Int_t mult = (Int_t)fmult;\r
379   Int_t sign = 1;\r
380   if(mult<0) sign = -1;\r
381   mult = Max(mult,-mult);\r
382   //Int_t shift = fPostCom + binPost - min;\r
383   //mult = mult>>(shift);\r
384 \r
385 /*\r
386   Mem().Init(2 * max + 1, min); // +1 to consider the borrow from the past-comma part; accuracy of past-comma part is determined by the minimum; therefore, for the result not more accuracy is guaranteed\r
387   // be aware that this only works if 2*max+1+min <= 32!! adjusting the pre-comma place to the value would consume too much time\r
388 \r
389   Mem().AssignFormatted(mult);\r
390   Mem().SetSign(sign);\r
391   //mult = sign*mult;\r
392   //Mem().FastInit(2*max+1,min,mult);\r
393   return Mem();*/\r
394   \r
395   alu.Init(2 * max + 1, min); // +1 to consider the borrow from the past-comma part; accuracy of past-comma part is determined by the minimum; therefore, for the result not more accuracy is guaranteed\r
396 // be aware that this only works if 2*max+1+min <= 32!! adjusting the pre-comma place to the value would consume too much time\r
397 \r
398   alu.AssignFormatted(mult);\r
399   alu.SetSign(sign);\r
400   \r
401   return alu;\r
402 }\r
403   \r
404 //_____________________________________________________________________________  \r
405 AliTRDtrapAlu AliTRDtrapAlu::operator/(const AliTRDtrapAlu& binary){\r
406   // / operator\r
407  \r
408     AliTRDtrapAlu alu;\r
409 \r
410   Int_t binPre  = binary.GetPre();\r
411   Int_t binPost = binary.GetPost();\r
412   Int_t min              = Min(binPost,fPostCom);\r
413   Int_t max              = Max(binPre,fPreCom);\r
414   \r
415   Int_t div1             = binary.GetValue(); //value in integer format\r
416   Int_t div2             = fValue;\r
417   \r
418   // this approach does not always work because it can exceed the range of integers\r
419   //Int_t numerator     = div2 * LUT(min);\r
420   Int_t numerator     = div2;\r
421   if (fSigned == kTRUE) numerator = numerator*(-1);\r
422   Int_t denominator   = div1;\r
423   if (binary.GetSign() == kTRUE) denominator = denominator*(-1);\r
424   Double_t fdiv       = 0.0;\r
425   Double_t fLUT       = 0.0;\r
426   Int_t div           = 0;\r
427   \r
428 \r
429   if (div1 == 0){\r
430       /*Mem().Init(max + 1,min);\r
431     Mem().AssignFormatted(LUT(max+min+1)-1); // division by 0: set to max value\r
432     //Mem().FastInit(max+1,min,div1);\r
433     return Mem();*/\r
434       alu.Init(max + 1,min);\r
435       alu.AssignFormatted(LUT(max+min+1)-1); // division by 0: set to max value\r
436       return alu;\r
437   }\r
438       \r
439   fdiv = (Double_t)numerator/denominator;\r
440   \r
441   Int_t shift = fPostCom - binPost;\r
442   \r
443   if(shift>0){\r
444       //denominator = denominator * LUT(shift);\r
445       fLUT = (Double_t)LUT(min)/LUT(shift);\r
446   }\r
447   else {\r
448       if(shift<0) {\r
449           shift = -shift;\r
450           //numerator =  numerator * LUT(shift);\r
451           fLUT = (Double_t)LUT(min)*LUT(shift);\r
452       }\r
453       else {\r
454           fLUT = (Double_t)LUT(min);\r
455       }\r
456   }\r
457 \r
458   fdiv = fdiv*fLUT;\r
459   div = (Int_t)fdiv;\r
460   \r
461   Int_t sign = (div>=0) ? 1 : -1;\r
462   div = Max(div,-div);\r
463   \r
464   // chose min as past-comma part because from a division of integers you can't get only an integer\r
465   \r
466   /*Mem().Init(max + 1,min); // max+1+min must <= 32!!\r
467   Mem().SetSign(sign);\r
468   Mem().AssignFormatted(div);\r
469   \r
470   return Mem();*/\r
471 \r
472   alu.Init(max + 1,min); // max+1+min must <= 32!!\r
473   alu.SetSign(sign);\r
474   alu.AssignFormatted(div);\r
475   \r
476   return alu;\r
477 \r
478   \r
479 }\r
480 \r
481 //_____________________________________________________________________________  \r
482 Int_t AliTRDtrapAlu::MakePower(const Int_t& base,const  Int_t& exponent)const{\r
483 // calculate "base" to the power of "exponent"\r
484   Int_t result = 1;\r
485   \r
486     for(Int_t i = 1; i <= exponent; i++){\r
487     result = result * base;\r
488   }\r
489   return result;\r
490 }\r
491 \r
492 //_____________________________________________________________________________  \r
493 Int_t AliTRDtrapAlu::LUT(const Int_t& index){   \r
494   // simple look-up table for base=2\r
495   \r
496     AliTRDtrapAlu alu;\r
497 \r
498   static Bool_t fLUT = kFALSE;\r
499   static Int_t gLUT[30];\r
500   if (fLUT == kFALSE) {\r
501     gLUT[0] = 1;\r
502     for(Int_t i = 1; i<30; i++) {\r
503       gLUT[i] = gLUT[i-1] * 2;\r
504     }\r
505   fLUT = kTRUE;\r
506   } \r
507   if (index >=0 && index < 30){\r
508     return gLUT[index];\r
509   }\r
510   else {\r
511     \r
512       //return Mem().MakePower(2,index);\r
513       return alu.MakePower(2,index);\r
514   }\r
515 }\r