Coverity fix
[u/mrichter/AliRoot.git] / TRD / TRDbase / AliTRDfeeParam.cxx
CommitLineData
022e76c3 1
2/**************************************************************************
3 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * *
5 * Author: The ALICE Off-line Project. *
6 * Contributors are mentioned in the code where appropriate. *
7 * *
8 * Permission to use, copy, modify and distribute this software and its *
9 * documentation strictly for non-commercial purposes is hereby granted *
10 * without fee, provided that the above copyright notice appears in all *
11 * copies and that both the copyright notice and this permission notice *
12 * appear in the supporting documentation. The authors make no claims *
13 * about the suitability of this software for any purpose. It is *
14 * provided "as is" without express or implied warranty. *
15 **************************************************************************/
16
17/* $Id$ */
18
acc49af9 19////////////////////////////////////////////////////////////////////////////
20// //
21// TRD front end electronics parameters class //
22// Contains all FEE (MCM, TRAP, PASA) related //
23// parameters, constants, and mapping. //
24// //
25// New release on 2007/08/17: //
26// The default raw data version (now fRAWversion ) is set to 3 //
27// in the constructor because version 3 raw data read and write //
28// are fully debugged. //
29// //
30// Author: //
31// Ken Oyama (oyama@physi.uni-heidelberg.de) //
32// //
3b4b024f 33// many things now configured by AliTRDtrapConfig reflecting //
34// the real memory structure of the TRAP (Jochen) //
35// //
acc49af9 36////////////////////////////////////////////////////////////////////////////
022e76c3 37
7cb613c0 38//#include <TMath.h>
022e76c3 39
ecf39416 40#include "AliLog.h"
ba84a3e3 41
022e76c3 42#include "AliTRDfeeParam.h"
7cb613c0 43//#include "AliTRDgeometry.h"
022e76c3 44#include "AliTRDCommonParam.h"
45
46ClassImp(AliTRDfeeParam)
47
48AliTRDfeeParam *AliTRDfeeParam::fgInstance = 0;
49Bool_t AliTRDfeeParam::fgTerminated = kFALSE;
1b1afdd3 50Bool_t AliTRDfeeParam::fgTracklet = kTRUE;
022e76c3 51
52//_____________________________________________________________________________
53AliTRDfeeParam* AliTRDfeeParam::Instance()
54{
acc49af9 55 //
022e76c3 56 // Instance constructor
acc49af9 57 //
58
022e76c3 59 if (fgTerminated != kFALSE) {
60 return 0;
61 }
62
63 if (fgInstance == 0) {
64 fgInstance = new AliTRDfeeParam();
65 }
66
67 return fgInstance;
acc49af9 68
022e76c3 69}
70
71//_____________________________________________________________________________
72void AliTRDfeeParam::Terminate()
73{
74 //
75 // Terminate the class and release memory
76 //
77
78 fgTerminated = kTRUE;
79
80 if (fgInstance != 0) {
81 delete fgInstance;
82 fgInstance = 0;
83 }
acc49af9 84
022e76c3 85}
86
87//_____________________________________________________________________________
88AliTRDfeeParam::AliTRDfeeParam()
89 :TObject()
022e76c3 90 ,fCP(0)
ecf39416 91 ,fRAWversion(3)
022e76c3 92{
93 //
94 // Default constructor
95 //
96
022e76c3 97 fCP = AliTRDCommonParam::Instance();
022e76c3 98}
99
100//_____________________________________________________________________________
ba84a3e3 101AliTRDfeeParam::AliTRDfeeParam(TRootIoCtor *)
102 :TObject()
103 ,fCP(0)
ba84a3e3 104 ,fRAWversion(0)
ba84a3e3 105{
106 //
107 // IO constructor
108 //
109
110}
111
112//_____________________________________________________________________________
022e76c3 113AliTRDfeeParam::AliTRDfeeParam(const AliTRDfeeParam &p)
114 :TObject(p)
022e76c3 115 ,fCP(p.fCP)
ecf39416 116 ,fRAWversion(p.fRAWversion)
022e76c3 117{
118 //
119 // AliTRDfeeParam copy constructor
120 //
acc49af9 121
022e76c3 122}
123
124//_____________________________________________________________________________
125AliTRDfeeParam::~AliTRDfeeParam()
126{
127 //
128 // AliTRDfeeParam destructor
129 //
acc49af9 130
022e76c3 131}
132
133//_____________________________________________________________________________
134AliTRDfeeParam &AliTRDfeeParam::operator=(const AliTRDfeeParam &p)
135{
136 //
137 // Assignment operator
138 //
139
140 if (this != &p) {
141 ((AliTRDfeeParam &) p).Copy(*this);
142 }
acc49af9 143
022e76c3 144 return *this;
acc49af9 145
022e76c3 146}
147
148//_____________________________________________________________________________
149void AliTRDfeeParam::Copy(TObject &p) const
150{
151 //
152 // Copy function
153 //
154
ecf39416 155 ((AliTRDfeeParam &) p).fCP = fCP;
ecf39416 156 ((AliTRDfeeParam &) p).fRAWversion = fRAWversion;
022e76c3 157
158 TObject::Copy(p);
acc49af9 159
022e76c3 160}
161
162//_____________________________________________________________________________
163Int_t AliTRDfeeParam::GetPadRowFromMCM(Int_t irob, Int_t imcm) const
164{
165 //
acc49af9 166 // Return on which pad row this mcm sits
022e76c3 167 //
168
169 return fgkNmcmRobInRow*(irob/2) + imcm/fgkNmcmRobInCol;
acc49af9 170
022e76c3 171}
172
173//_____________________________________________________________________________
174Int_t AliTRDfeeParam::GetPadColFromADC(Int_t irob, Int_t imcm, Int_t iadc) const
175{
176 //
ecf39416 177 // Return which pad is connected to this adc channel.
178 //
179 // Return virtual pad number even if ADC is outside chamber
180 // to keep compatibility of data processing at the edge MCM.
181 // User has to check that this is in the chamber if it is essential.
182 // Return -100 if iadc is invalid.
183 //
022e76c3 184 // Caution: ADC ordering in the online data is opposite to the pad column ordering.
185 // And it is not one-by-one correspondence. Precise drawing can be found in:
186 // http://wiki.kip.uni-heidelberg.de/ti/TRD/index.php/Image:ROB_MCM_numbering.pdf
acc49af9 187 //
022e76c3 188
a6d08b7f 189 if (iadc < 0 || iadc > fgkNadcMcm ) return -100;
022e76c3 190 Int_t mcmcol = imcm%fgkNmcmRobInCol + GetRobSide(irob)*fgkNmcmRobInCol; // MCM column number on ROC [0..7]
191 Int_t padcol = mcmcol*fgkNcolMcm + fgkNcolMcm + 1 - iadc;
38cb2aa7 192 if( padcol < 0 || padcol >= fgkNcol ) return -1; // this is commented because of reason above OK
860f3a82 193
194 return padcol;
195
196}
197
198//_____________________________________________________________________________
199Int_t AliTRDfeeParam::GetExtendedPadColFromADC(Int_t irob, Int_t imcm, Int_t iadc) const
200{
201 //
202 // Return which pad coresponds to the extended digit container pad numbering
203 // Extended digit container is designed to store all pad data including shared pad,
204 // so we have to introduce new virtual pad numbering scheme for this purpose.
205 //
206
207 if (iadc < 0 || iadc > fgkNadcMcm ) return -100;
208 Int_t mcmcol = imcm%fgkNmcmRobInCol + GetRobSide(irob)*fgkNmcmRobInCol; // MCM column number on ROC [0..7]
af0d9e9e 209 Int_t padcol = mcmcol*fgkNadcMcm + fgkNcolMcm + 2 - iadc;
acc49af9 210
022e76c3 211 return padcol;
acc49af9 212
022e76c3 213}
214
215//_____________________________________________________________________________
216Int_t AliTRDfeeParam::GetMCMfromPad(Int_t irow, Int_t icol) const
217{
218 //
219 // Return on which MCM this pad is directry connected.
220 // Return -1 for error.
221 //
222
223 if ( irow < 0 || icol < 0 || irow > fgkNrowC1 || icol > fgkNcol ) return -1;
224
225 return (icol%(fgkNcol/2))/fgkNcolMcm + fgkNmcmRobInCol*(irow%fgkNmcmRobInRow);
acc49af9 226
022e76c3 227}
228
229//_____________________________________________________________________________
1785640c 230Int_t AliTRDfeeParam::GetMCMfromSharedPad(Int_t irow, Int_t icol) const
231{
232 //
233 // Return on which MCM this pad is directry connected.
234 // Return -1 for error.
235 //
236
237 if ( irow < 0 || icol < 0 || irow > fgkNrowC1 || icol > fgkNcol+8*3 ) return -1;
238
239 Int_t adc = 20 - (icol%18) -1;
240 switch(adc) {
241 case 2: icol += 5; break;
242 case 18: icol -= 5; break;
243 case 19: icol -= 5; break;
244 default: icol += 0; break;
245 }
246
247 return (icol%(fgkNcol/2))/fgkNcolMcm + fgkNmcmRobInCol*(irow%fgkNmcmRobInRow);
248
249}
250
251//_____________________________________________________________________________
022e76c3 252Int_t AliTRDfeeParam::GetROBfromPad(Int_t irow, Int_t icol) const
253{
254 //
acc49af9 255 // Return on which rob this pad is
022e76c3 256 //
257
258 return (irow/fgkNmcmRobInRow)*2 + GetColSide(icol);
acc49af9 259
022e76c3 260}
261
262//_____________________________________________________________________________
1785640c 263Int_t AliTRDfeeParam::GetROBfromSharedPad(Int_t irow, Int_t icol) const
264{
265 //
266 // Return on which rob this pad is for shared pads
267 //
268
269 if(icol<72) return (irow/fgkNmcmRobInRow)*2 + GetColSide(icol+5);
270 else return (irow/fgkNmcmRobInRow)*2 + GetColSide(icol-5);
271
272}
273
274//_____________________________________________________________________________
022e76c3 275Int_t AliTRDfeeParam::GetRobSide(Int_t irob) const
276{
277 //
acc49af9 278 // Return on which side this rob sits (A side = 0, B side = 1)
022e76c3 279 //
280
281 if ( irob < 0 || irob >= fgkNrobC1 ) return -1;
acc49af9 282
022e76c3 283 return irob%2;
acc49af9 284
022e76c3 285}
286
287//_____________________________________________________________________________
288Int_t AliTRDfeeParam::GetColSide(Int_t icol) const
289{
290 //
acc49af9 291 // Return on which side this column sits (A side = 0, B side = 1)
022e76c3 292 //
293
294 if ( icol < 0 || icol >= fgkNcol ) return -1;
acc49af9 295
022e76c3 296 return icol/(fgkNcol/2);
acc49af9 297
022e76c3 298}
299
8ea391e3 300
301
302UInt_t AliTRDfeeParam::AliToExtAli(Int_t rob, Int_t aliid)
303{
304 if(aliid!= 127)
305 return ( (1 << 10) | (rob << 7) | aliid);
306
307 return 127;
308}
309
310
311Int_t AliTRDfeeParam::ExtAliToAli(UInt_t dest, UShort_t linkpair, UShort_t rocType, Int_t *mcmList, Int_t listSize)
312{
313 // Converts an extended ALICE ID which identifies a single MCM or a group of MCMs to
314 // the corresponding list of MCMs. Only broadcasts (127) are encoded as 127
315 // The return value is the number of MCMs in the list
316
317 mcmList[0]=-1;
318
319 Short_t nmcm = 0;
320 UInt_t mcm, rob, robAB;
321 UInt_t cmA = 0, cmB = 0; // Chipmask for each A and B side
322
323 // Default chipmask for 4 linkpairs (each bit correponds each alice-mcm)
324 static const UInt_t gkChipmaskDefLp[4] = { 0x1FFFF, 0x1FFFF, 0x3FFFF, 0x1FFFF };
325
326 rob = dest >> 7; // Extract ROB pattern from dest.
327 mcm = dest & 0x07F; // Extract MCM pattern from dest.
328 robAB = GetRobAB( rob, linkpair ); // Get which ROB sides are selected.
329
330 // Abort if no ROB is selected
331 if( robAB == 0 ) {
332 return 0;
333 }
334
335 // Special case
336 if( mcm == 127 ) {
337 if( robAB == 3 ) { // This is very special 127 can stay only if two ROBs are selected
338 mcmList[0]=127; // broadcase to ALL
339 mcmList[1]=-1;
340 return 1;
341 }
342 cmA = cmB = 0x3FFFF;
343 } else if( (mcm & 0x40) != 0 ) { // If top bit is 1 but not 127, this is chip group.
344 if( (mcm & 0x01) != 0 ) { cmA |= 0x04444; cmB |= 0x04444; } // chip_cmrg
345 if( (mcm & 0x02) != 0 ) { cmA |= 0x10000; cmB |= 0x10000; } // chip_bmrg
346 if( (mcm & 0x04) != 0 && rocType == 0 ) { cmA |= 0x20000; cmB |= 0x20000; } // chip_hm3
347 if( (mcm & 0x08) != 0 && rocType == 1 ) { cmA |= 0x20000; cmB |= 0x20000; } // chip_hm4
348 if( (mcm & 0x10) != 0 ) { cmA |= 0x01111; cmB |= 0x08888; } // chip_edge
349 if( (mcm & 0x20) != 0 ) { cmA |= 0x0aaaa; cmB |= 0x03333; } // chip_norm
350 } else { // Otherwise, this is normal chip ID, turn on only one chip.
351 cmA = 1 << mcm;
352 cmB = 1 << mcm;
353 }
354
355 // Mask non-existing MCMs
356 cmA &= gkChipmaskDefLp[linkpair];
357 cmB &= gkChipmaskDefLp[linkpair];
358 // Remove if only one side is selected
359 if( robAB == 1 )
360 cmB = 0;
361 if( robAB == 2 )
362 cmA = 0;
363 if( robAB == 4 && linkpair != 2 )
364 cmA = cmB = 0; // Restrict to only T3A and T3B
365
366 // Finally convert chipmask to list of slaves
367 nmcm = ChipmaskToMCMlist( cmA, cmB, linkpair, mcmList, listSize);
368
369 return nmcm;
370}
371
372
373Short_t AliTRDfeeParam::GetRobAB( UShort_t robsel, UShort_t linkpair )
374{
375 // Converts the ROB part of the extended ALICE ID to robs
376
377 if( (robsel & 0x8) != 0 ) { // 1000 .. direct ROB selection. Only one of the 8 ROBs are used.
378 robsel = robsel & 7;
379 if( (robsel % 2) == 0 && (robsel / 2) == linkpair )
380 return 1; // Even means A side (position 0,2,4,6)
381 if( (robsel % 2) == 1 && (robsel / 2) == linkpair )
382 return 2; // Odd means B side (position 1,3,5,7)
383 return 0;
384 }
385
386 // ROB group
387 if( robsel == 0 ) { return 3; } // Both ROB
388 if( robsel == 1 ) { return 1; } // A-side ROB
389 if( robsel == 2 ) { return 2; } // B-side ROB
390 if( robsel == 3 ) { return 3; } // Both ROB
391 if( robsel == 4 ) { return 4; } // Only T3A and T3B
392 // Other number 5 to 7 are ignored (not defined)
393
394 return 0;
395}
396
397
398Short_t AliTRDfeeParam::ChipmaskToMCMlist( UInt_t cmA, UInt_t cmB, UShort_t linkpair, Int_t *mcmList, Int_t listSize )
399{
400 // Converts the chipmask to a list of MCMs
401
402 Short_t nmcm = 0;
403 Short_t i;
5ac2e3b1 404 for( i = 0 ; i < 18 ; i++ ) { // 18: number of MCMs on a ROB
405 if( (cmA & (1 << i)) != 0 && nmcm<listSize) {
8ea391e3 406 mcmList[nmcm] = ((linkpair*2) << 7) | i;
407 ++nmcm;
408 }
5ac2e3b1 409 if( (cmB & (1 << i)) != 0 && nmcm<listSize) {
8ea391e3 410 mcmList[nmcm] = ((linkpair*2+1) << 7) | i;
411 ++nmcm;
412 }
413 }
414
415 mcmList[nmcm]=-1;
416 return nmcm;
417}
418
419
ecf39416 420//_____________________________________________________________________________
acc49af9 421void AliTRDfeeParam::SetRAWversion( Int_t rawver )
ecf39416 422{
acc49af9 423 //
ecf39416 424 // Set raw data version (major number only)
425 // Maximum available number is preset in fgkMaxRAWversion
acc49af9 426 //
ecf39416 427
428 if( rawver >= 0 && rawver <= fgkMaxRAWversion ) {
acc49af9 429 fRAWversion = rawver;
430 }
431 else {
ecf39416 432 AliError(Form("Raw version is out of range: %d",rawver));
433 }
ecf39416 434
ecf39416 435}