In AddTaskPHOSPi0Flow.C set Cent. Bin past event buffers/lists,
[u/mrichter/AliRoot.git] / STEER / ESD / AliFMDMap.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 //____________________________________________________________________
19 //                                                                          
20 // Base class for caches of per-strip information.
21 // This is used to index a strip. 
22 // Data stored depends on derived class. 
23 // This class provides some common infra-structure.
24 // Derived classes sould define Reset, and operator(). 
25 //
26 #include "AliFMDMap.h"          // ALIFMDMAP_H
27 #include "AliLog.h"
28 //#include <TClass.h>
29 //#include <TBuffer.h>
30 #include <TFile.h>
31 #include <TList.h>
32 #include <TStreamerInfo.h>
33
34 //____________________________________________________________________
35 ClassImp(AliFMDMap)
36 #if 0
37   ; // This is here to keep Emacs for indenting the next line
38 #endif
39
40 //____________________________________________________________________
41 AliFMDMap::AliFMDMap(UShort_t maxDet, 
42                      UShort_t maxRing, 
43                      UShort_t maxSec, 
44                      UShort_t maxStr)
45   : fMaxDetectors(maxDet), 
46     fMaxRings(maxRing), 
47     fMaxSectors(maxSec), 
48     fMaxStrips(maxStr)
49 {
50   // Construct a map
51   //
52   // Parameters:
53   //     maxDet       Maximum # of detectors
54   //     maxRinf      Maximum # of rings
55   //     maxSec       Maximum # of sectors
56   //     maxStr       Maximum # of strips
57   SetBit(kNeedUShort, kFALSE);
58 }
59
60 //____________________________________________________________________
61 AliFMDMap::AliFMDMap(const AliFMDMap& other)
62   : TObject(other), 
63     fMaxDetectors(other.fMaxDetectors), 
64     fMaxRings(other.fMaxRings),
65     fMaxSectors(other.fMaxSectors),
66     fMaxStrips(other.fMaxStrips)
67 {
68   SetBit(kNeedUShort, other.TestBit(kNeedUShort));
69 }
70
71 //____________________________________________________________________
72 void
73 AliFMDMap::CheckNeedUShort(TFile* file) 
74 {
75   if (!file) return;
76   TObject* o = file->GetStreamerInfoList()->FindObject("AliFMDMap");
77   if (!o) return;
78   TStreamerInfo* info = static_cast<TStreamerInfo*>(o);
79   if (info->GetClassVersion() == 2) SetBit(kNeedUShort);
80 }
81 //____________________________________________________________________
82 void
83 AliFMDMap::Index2CoordsOld(Int_t     idx, 
84                            UShort_t& det, 
85                            Char_t&   ring, 
86                            UShort_t& sec, 
87                            UShort_t& str) const
88 {
89   UShort_t rng;
90   str  = idx % fMaxStrips;
91   sec  = (idx / fMaxStrips) % fMaxSectors;
92   rng  = (idx / fMaxStrips / fMaxSectors) % fMaxRings;
93   det  = (idx / fMaxStrips / fMaxSectors / fMaxRings) % fMaxDetectors + 1;
94   ring = (rng == 0 ? 'I' : 'O');
95 }
96
97 //____________________________________________________________________
98 void
99 AliFMDMap::Index2Coords(Int_t     idx, 
100                         UShort_t& det, 
101                         Char_t&   ring, 
102                         UShort_t& sec, 
103                         UShort_t& str) const
104 {
105   UShort_t nStr;
106   Int_t    i   = idx;
107   if      (i >= kFMD3Base)  { det  = 3;  i -= kFMD3Base; }
108   else if (i >= kFMD2Base)  { det  = 2;  i -= kFMD2Base; }
109   else                      { det  = 1;  i -= kFMD1Base; } 
110   if      (i >= kBaseOuter) { ring = 'O';i -= kBaseOuter; nStr = kNStripOuter; }
111   else                      { ring = 'I';                 nStr = kNStripInner; }
112   sec  = i / nStr;
113   str  = i % nStr;
114 }
115
116 //____________________________________________________________________
117 void
118 AliFMDMap::CalcCoords(Int_t     idx, 
119                       UShort_t& det, 
120                       Char_t&   ring, 
121                       UShort_t& sec, 
122                       UShort_t& str) const
123 {
124   if (fMaxDetectors == 0) {
125     Index2Coords(idx, det, ring, sec, str);
126   }
127   else {
128     Index2CoordsOld(idx, det, ring, sec, str);
129   }
130 }
131
132 //____________________________________________________________________
133 Int_t 
134 AliFMDMap::Coords2IndexOld(UShort_t det, Char_t ring, UShort_t sec, 
135                            UShort_t str) const
136 {
137   // Check that the index supplied is OK.   Returns true index, or -1
138   // on error. 
139   if (det < 1) return -1;
140   UShort_t ringi = (ring == 'I' ||  ring == 'i' ? 0 : 1);
141   Int_t idx = 
142     (str + fMaxStrips * (sec + fMaxSectors * (ringi + fMaxRings * (det-1))));
143   if (TestBit(kNeedUShort)) idx = UShort_t(idx);
144   if (idx < 0 || idx >= fMaxDetectors * fMaxRings * fMaxSectors * fMaxStrips) 
145     return -1;
146   return idx;
147 }
148
149 //____________________________________________________________________
150 Int_t 
151 AliFMDMap::Coords2Index(UShort_t det, Char_t ring, UShort_t sec, 
152                         UShort_t str) const
153 {
154   // Check that the index supplied is OK.   Returns true index, or -1
155   // on error. 
156   UShort_t irg  = (ring == 'I' || ring == 'i' ? kInner : 
157                    (ring == 'O' || ring == 'o' ? kOuter  : kOuter+1));
158   if (irg > kOuter) return -1;
159     
160   Int_t idx = 0;
161   switch (det) { 
162   case 1: idx = kFMD1Base;  if (irg > 0) return -1; break;
163   case 2: idx = kFMD2Base + irg * kBaseOuter; break;
164   case 3: idx = kFMD3Base + irg * kBaseOuter; break;
165   default: return -1;
166   }
167   UShort_t nSec = (irg == 0 ?  kNSectorInner :  kNSectorOuter);
168   if (sec >= nSec) return -1;
169   UShort_t nStr = (irg == 0 ? kNStripInner : kNStripOuter);
170   if (str >= nStr) return -1;
171   idx += nStr * sec + str;
172
173   return idx;
174 }
175
176 //____________________________________________________________________
177 Int_t 
178 AliFMDMap::CheckIndex(UShort_t det, Char_t ring, UShort_t sec, 
179                       UShort_t str) const
180 {
181   // Check that the index supplied is OK.   Returns true index, or -1
182   // on error. 
183   if (fMaxDetectors == 0)
184     return Coords2Index(det, ring, sec, str);
185   return Coords2IndexOld(det, ring, sec, str);
186 }
187
188
189     
190 //____________________________________________________________________
191 Int_t 
192 AliFMDMap::CalcIndex(UShort_t det, Char_t ring, UShort_t sec, UShort_t str) const
193 {
194   // Calculate index into storage from arguments. 
195   // 
196   // Parameters: 
197   //     det       Detector #
198   //     ring      Ring ID
199   //     sec       Sector # 
200   //     str       Strip # 
201   //
202   // Returns appropriate index into storage 
203   //
204   Int_t idx = CheckIndex(det, ring, sec, str);
205   if (idx < 0) {
206     UShort_t ringi = (ring == 'I' ||  ring == 'i' ? 0 : 
207                       (ring == 'O' || ring == 'o' ? 1 : 2));
208     AliFatal(Form("Index FMD%d%c[%2d,%3d] out of bounds, "
209                   "in particular the %s index ", 
210                   det, ring, sec, str, 
211                   (det > fMaxDetectors ? "Detector" : 
212                    (ringi >= fMaxRings ? "Ring" : 
213                     (sec >= fMaxSectors ? "Sector" : "Strip")))));
214     return 0;
215   }
216   return idx;
217 }
218
219 #define INCOMP_OP(self, other, OP) do {                                 \
220   AliWarning("Incompatible sized AliFMDMap");                           \
221   UShort_t maxDet = TMath::Min(self->MaxDetectors(), other.MaxDetectors()); \
222   UShort_t maxRng = TMath::Min(self->MaxRings(),     other.MaxRings()); \
223   UShort_t maxSec = TMath::Min(self->MaxSectors(),   other.MaxSectors()); \
224   UShort_t maxStr = TMath::Min(self->MaxStrips(),    other.MaxStrips()); \
225   for (UShort_t d = 1; d <= maxDet; d++) {                              \
226     UShort_t nRng = TMath::Min(UShort_t(d == 1 ? 1 : 2), maxRng);       \
227     for (UShort_t q = 0; q < nRng; q++) {                               \
228       Char_t   r    = (q == 0 ? 'I' : 'O');                             \
229       UShort_t nSec = TMath::Min(UShort_t(q == 0 ?  20 :  40), maxSec); \
230       UShort_t nStr = TMath::Min(UShort_t(q == 0 ? 512 : 256), maxStr); \
231       for (UShort_t s = 0; s < nSec; s++) {                             \
232         for (UShort_t t = 0; t < nStr; t++) {                           \
233           Int_t idx1 = self->CalcIndex(d, r, s, t);                     \
234           Int_t idx2 = other.CalcIndex(d, r, s, t);                     \
235           if (idx1 < 0 || idx2 < 0) {                                   \
236             AliWarning("Index out of bounds");                          \
237             continue;                                                   \
238           }                                                             \
239           if (self->IsFloat())                                          \
240             self->AtAsFloat(idx1) OP other.AtAsFloat(idx2);             \
241           else if (self->IsInt())                                       \
242             self->AtAsInt(idx1) OP other.AtAsInt(idx2);                 \
243           else if (self->IsUShort())                                    \
244             self->AtAsUShort(idx1) OP other.AtAsUShort(idx2);           \
245           else if (self->IsBool())                                      \
246             self->AtAsBool(idx1) OP other.AtAsBool(idx2);               \
247         }                                                               \
248       }                                                                 \
249     }                                                                   \
250   }                                                                     \
251   } while (false)
252
253 #define COMP_OP(self,other,OP) do {                                     \
254     for (Int_t i = 0; i < self->MaxIndex(); i++) {                      \
255       if (self->IsFloat())                                              \
256         self->AtAsFloat(i) OP other.AtAsFloat(i);                       \
257       else if (self->IsInt())                                           \
258         self->AtAsInt(i) OP other.AtAsInt(i);                           \
259       else if (self->IsUShort())                                        \
260         self->AtAsUShort(i) OP other.AtAsUShort(i);                     \
261       else if (self->IsBool())                                          \
262         self->AtAsBool(i) OP other.AtAsBool(i);                         \
263     } } while (false)
264
265 //__________________________________________________________
266 AliFMDMap&
267 AliFMDMap::operator*=(const AliFMDMap& other)
268 {
269   // Right multiplication assignment operator 
270   if(fMaxDetectors!= other.fMaxDetectors||
271      fMaxRings    != other.fMaxRings    ||
272      fMaxSectors  != other.fMaxSectors  ||
273      fMaxStrips   != other.fMaxStrips   ||
274      MaxIndex()   != other.MaxIndex()) {
275     INCOMP_OP(this, other, *=);
276     return *this;
277   }
278   COMP_OP(this, other, *=);
279   return *this;
280 }
281
282 //__________________________________________________________
283 AliFMDMap&
284 AliFMDMap::operator/=(const AliFMDMap& other)
285 {
286   // Right division assignment operator 
287   if(fMaxDetectors!= other.fMaxDetectors||
288      fMaxRings    != other.fMaxRings    ||
289      fMaxSectors  != other.fMaxSectors  ||
290      fMaxStrips   != other.fMaxStrips   ||
291      MaxIndex()   != other.MaxIndex()) {
292     INCOMP_OP(this, other, /=);
293     return *this;
294   }
295   COMP_OP(this, other, /=);
296   return *this;
297 }
298
299 //__________________________________________________________
300 AliFMDMap&
301 AliFMDMap::operator+=(const AliFMDMap& other)
302 {
303   // Right addition assignment operator 
304   if(fMaxDetectors!= other.fMaxDetectors||
305      fMaxRings    != other.fMaxRings    ||
306      fMaxSectors  != other.fMaxSectors  ||
307      fMaxStrips   != other.fMaxStrips   ||
308      MaxIndex()   != other.MaxIndex()) {
309     INCOMP_OP(this, other, +=);
310     return *this;
311   }
312   COMP_OP(this, other, +=);
313   return *this;
314 }
315
316 //__________________________________________________________
317 AliFMDMap&
318 AliFMDMap::operator-=(const AliFMDMap& other)
319 {
320   // Right subtraction assignment operator 
321   if(fMaxDetectors!= other.fMaxDetectors||
322      fMaxRings    != other.fMaxRings    ||
323      fMaxSectors  != other.fMaxSectors  ||
324      fMaxStrips   != other.fMaxStrips   ||
325      MaxIndex()   != other.MaxIndex()) {
326     INCOMP_OP(this, other, +=);
327     return *this;
328   }
329   COMP_OP(this, other, +=);
330   return *this;
331 }
332
333 //__________________________________________________________
334 Bool_t
335 AliFMDMap::ForEach(ForOne& algo) const
336 {
337   // Assignment operator 
338   Bool_t ret = kTRUE;
339   for (Int_t i = 0; i < this->MaxIndex(); i++) { 
340     UShort_t d, s, t;
341     Char_t r;
342     CalcCoords(i, d, r, s, t);
343     Bool_t rr = kTRUE;
344     if (IsFloat()) 
345       rr = algo.operator()(d, r, s, t, this->AtAsFloat(i));
346     else if (IsInt()) 
347       rr = algo.operator()(d, r, s, t, this->AtAsInt(i));
348     else if (IsUShort()) 
349       rr = algo.operator()(d, r, s, t, this->AtAsUShort(i));
350     else if (IsBool()) 
351       rr = algo.operator()(d, r, s, t, this->AtAsBool(i));
352     if (!rr) {
353       ret = kFALSE;
354       break;
355     }
356   }
357   return ret;
358 }
359
360 //__________________________________________________________
361 void
362 AliFMDMap::Print(Option_t* option) const
363 {
364   // Print contents of map
365   if (!option || option[0] == '\0') TObject::Print();
366   Printer p(option);
367   ForEach(p);
368   printf("\n");
369 }
370
371 //===================================================================
372 AliFMDMap::Printer::Printer(const char* format)
373   : fFormat(format), fOldD(0), fOldR('-'), fOldS(1024) 
374 {}
375
376 //___________________________________________________________________
377 AliFMDMap::Printer::Printer(const Printer& p) 
378   : AliFMDMap::ForOne(p),
379     fFormat(p.fFormat), 
380     fOldD(p.fOldD), 
381     fOldR(p.fOldR), 
382     fOldS(p.fOldS) 
383 {}
384 //___________________________________________________________________
385 void
386 AliFMDMap::Printer::PrintHeadings(UShort_t d, Char_t r, UShort_t s, UShort_t t) 
387 {
388   if (d != fOldD) { 
389     fOldD = d;
390     fOldR = '-';
391     if (d != 0) printf("\n");
392     printf("FMD%d", fOldD);
393   }
394   if (r != fOldR) {
395     fOldR = r;
396     fOldS = 1024;
397     printf("\n %s ring", (r == 'I' ? "Inner" : "Outer"));
398   }
399   if (s != fOldS) { 
400     fOldS = s;
401     printf("\n  Sector %2d", fOldS);
402   }
403   if (t % 4 == 0) printf("\n   %3d-%3d ", t, t+3);
404 }
405 //___________________________________________________________________
406 Bool_t
407 AliFMDMap::Printer::operator()(UShort_t d, Char_t r, UShort_t s, UShort_t t, 
408                                Float_t m)
409 {
410   PrintHeadings(d, r, s, t);
411   printf(fFormat, m);
412   return kTRUE;
413 }
414 //___________________________________________________________________
415 Bool_t
416 AliFMDMap::Printer::operator()(UShort_t d, Char_t r, UShort_t s, UShort_t t, 
417                                Int_t m)
418 {
419   PrintHeadings(d, r, s, t);
420   printf(fFormat, m);
421   return kTRUE;
422 }
423 //___________________________________________________________________
424 Bool_t
425 AliFMDMap::Printer::operator()(UShort_t d, Char_t r, UShort_t s, UShort_t t, 
426                                UShort_t m)
427 {
428   PrintHeadings(d, r, s, t);
429   printf(fFormat, m);
430   return kTRUE;
431 }
432 //___________________________________________________________________
433 Bool_t
434 AliFMDMap::Printer::operator()(UShort_t d, Char_t r, UShort_t s, UShort_t t, 
435                                Bool_t m)
436 {
437   PrintHeadings(d, r, s, t);
438   printf(fFormat, int(m));
439   return kTRUE;
440 }
441
442 #if 0
443 //___________________________________________________________________
444 void AliFMDMap::Streamer(TBuffer &R__b)
445 {
446   // Stream an object of class AliFMDMap.
447   // This is overridden so that we can know the version of the object
448   // that we are reading in.  In this way, we can fix problems that
449   // might occur in the class. 
450   if (R__b.IsReading()) {
451     // read the class version from the buffer
452     UInt_t R__s, R__c;
453     Version_t version = R__b.ReadVersion(&R__s, &R__c, this->Class());
454     TFile *file = (TFile*)R__b.GetParent();
455     if (file && file->GetVersion() < 30000) version = -1; 
456     AliFMDMap::Class()->ReadBuffer(R__b, this, version, R__s, R__c);
457     if (version == 2) SetBit(kNeedUShort);
458   } else {
459     AliFMDMap::Class()->WriteBuffer(R__b, this);
460   }
461 }
462 #endif
463
464 //___________________________________________________________________
465 //
466 // EOF
467 //