Bug corrected.
[u/mrichter/AliRoot.git] / STEER / AliFMDMap.cxx
CommitLineData
9da38871 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"
c05d076f 28//#include <TClass.h>
29//#include <TBuffer.h>
30#include <TFile.h>
31#include <TList.h>
32#include <TStreamerInfo.h>
9da38871 33
34//____________________________________________________________________
35ClassImp(AliFMDMap)
36#if 0
37 ; // This is here to keep Emacs for indenting the next line
38#endif
39
40//____________________________________________________________________
9eeb02aa 41AliFMDMap::AliFMDMap(UShort_t maxDet,
42 UShort_t maxRing,
43 UShort_t maxSec,
44 UShort_t maxStr)
9da38871 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
c05d076f 57 SetBit(kNeedUShort, kFALSE);
9da38871 58}
59
60//____________________________________________________________________
021f1396 61AliFMDMap::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//____________________________________________________________________
c05d076f 72void
73AliFMDMap::CheckNeedUShort(TFile* file)
74{
75 if (!file) return;
e03121ec 76 TObject* o = file->GetStreamerInfoList()->FindObject("AliFMDMap");
c05d076f 77 if (!o) return;
78 TStreamerInfo* info = static_cast<TStreamerInfo*>(o);
79 if (info->GetClassVersion() == 2) SetBit(kNeedUShort);
80}
81//____________________________________________________________________
021f1396 82void
83AliFMDMap::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//____________________________________________________________________
98void
99AliFMDMap::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//____________________________________________________________________
117void
118AliFMDMap::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//____________________________________________________________________
9da38871 133Int_t
021f1396 134AliFMDMap::Coords2IndexOld(UShort_t det, Char_t ring, UShort_t sec,
135 UShort_t str) const
9da38871 136{
137 // Check that the index supplied is OK. Returns true index, or -1
138 // on error.
ac07a8f5 139 if (det < 1) return -1;
9eeb02aa 140 UShort_t ringi = (ring == 'I' || ring == 'i' ? 0 : 1);
c05d076f 141 Int_t idx =
9da38871 142 (str + fMaxStrips * (sec + fMaxSectors * (ringi + fMaxRings * (det-1))));
c05d076f 143 if (TestBit(kNeedUShort)) idx = UShort_t(idx);
144 if (idx < 0 || idx >= fMaxDetectors * fMaxRings * fMaxSectors * fMaxStrips)
145 return -1;
9da38871 146 return idx;
147}
148
021f1396 149//____________________________________________________________________
150Int_t
151AliFMDMap::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//____________________________________________________________________
177Int_t
178AliFMDMap::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
9da38871 189
190//____________________________________________________________________
5664d15a 191Int_t
9eeb02aa 192AliFMDMap::CalcIndex(UShort_t det, Char_t ring, UShort_t sec, UShort_t str) const
9da38871 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) {
021f1396 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, "
9da38871 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 }
5664d15a 216 return idx;
9da38871 217}
218
021f1396 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//__________________________________________________________
266AliFMDMap&
267AliFMDMap::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//__________________________________________________________
283AliFMDMap&
284AliFMDMap::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//__________________________________________________________
300AliFMDMap&
301AliFMDMap::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//__________________________________________________________
317AliFMDMap&
318AliFMDMap::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//__________________________________________________________
334Bool_t
335AliFMDMap::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
c05d076f 360#if 0
361//___________________________________________________________________
362void AliFMDMap::Streamer(TBuffer &R__b)
363{
364 // Stream an object of class AliFMDMap.
365 // This is overridden so that we can know the version of the object
366 // that we are reading in. In this way, we can fix problems that
367 // might occur in the class.
368 if (R__b.IsReading()) {
369 // read the class version from the buffer
370 UInt_t R__s, R__c;
371 Version_t version = R__b.ReadVersion(&R__s, &R__c, this->Class());
372 TFile *file = (TFile*)R__b.GetParent();
373 if (file && file->GetVersion() < 30000) version = -1;
374 AliFMDMap::Class()->ReadBuffer(R__b, this, version, R__s, R__c);
375 if (version == 2) SetBit(kNeedUShort);
376 } else {
377 AliFMDMap::Class()->WriteBuffer(R__b, this);
378 }
379}
380#endif
9da38871 381
382//___________________________________________________________________
383//
384// EOF
385//