Version where the process for HLT and vdrift on DAQ are off(Raphaelle)
[u/mrichter/AliRoot.git] / TRD / AliTRDfeeParam.cxx
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
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 //                                                                        //
33 //  many things now configured by AliTRDtrapConfig reflecting             //
34 //  the real memory structure of the TRAP (Jochen)                        //
35 //                                                                        //
36 ////////////////////////////////////////////////////////////////////////////
37
38 //#include <TMath.h>
39
40 #include "AliLog.h"
41
42 #include "AliTRDfeeParam.h"
43 //#include "AliTRDgeometry.h"
44 #include "AliTRDCommonParam.h"
45
46 ClassImp(AliTRDfeeParam)
47
48 AliTRDfeeParam *AliTRDfeeParam::fgInstance   = 0;
49 Bool_t          AliTRDfeeParam::fgTerminated = kFALSE;
50 Bool_t          AliTRDfeeParam::fgTracklet = kTRUE;
51
52 //_____________________________________________________________________________
53 AliTRDfeeParam* AliTRDfeeParam::Instance()
54 {
55   //
56   // Instance constructor
57   //
58
59   if (fgTerminated != kFALSE) {
60     return 0;
61   }
62
63   if (fgInstance == 0) {
64     fgInstance = new AliTRDfeeParam();
65   }  
66
67   return fgInstance;
68
69 }
70
71 //_____________________________________________________________________________
72 void 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   }
84
85 }
86
87 //_____________________________________________________________________________
88 AliTRDfeeParam::AliTRDfeeParam()
89   :TObject()
90   ,fCP(0)
91   ,fRAWversion(3)
92 {
93   //
94   // Default constructor
95   //
96   
97   fCP  = AliTRDCommonParam::Instance();
98 }
99
100 //_____________________________________________________________________________
101 AliTRDfeeParam::AliTRDfeeParam(TRootIoCtor *)
102   :TObject()
103   ,fCP(0)
104   ,fRAWversion(0)
105 {
106   //
107   // IO constructor
108   //
109
110 }
111
112 //_____________________________________________________________________________
113 AliTRDfeeParam::AliTRDfeeParam(const AliTRDfeeParam &p)
114   :TObject(p)
115   ,fCP(p.fCP)
116   ,fRAWversion(p.fRAWversion)
117 {
118   //
119   // AliTRDfeeParam copy constructor
120   //
121
122 }
123
124 //_____________________________________________________________________________
125 AliTRDfeeParam::~AliTRDfeeParam()
126 {
127   //
128   // AliTRDfeeParam destructor
129   //
130
131 }
132
133 //_____________________________________________________________________________
134 AliTRDfeeParam &AliTRDfeeParam::operator=(const AliTRDfeeParam &p)
135 {
136   //
137   // Assignment operator
138   //
139
140   if (this != &p) {
141     ((AliTRDfeeParam &) p).Copy(*this);
142   }
143
144   return *this;
145
146 }
147
148 //_____________________________________________________________________________
149 void AliTRDfeeParam::Copy(TObject &p) const
150 {
151   //
152   // Copy function
153   //
154
155   ((AliTRDfeeParam &) p).fCP          = fCP;
156   ((AliTRDfeeParam &) p).fRAWversion  = fRAWversion;
157   
158   TObject::Copy(p);
159
160 }
161
162 //_____________________________________________________________________________
163 Int_t AliTRDfeeParam::GetPadRowFromMCM(Int_t irob, Int_t imcm) const
164 {
165   //
166   // Return on which pad row this mcm sits
167   //
168   
169   return fgkNmcmRobInRow*(irob/2) + imcm/fgkNmcmRobInCol;
170
171 }
172
173 //_____________________________________________________________________________
174 Int_t AliTRDfeeParam::GetPadColFromADC(Int_t irob, Int_t imcm, Int_t iadc) const
175 {
176   //
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   //
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
187   //
188
189   if (iadc < 0 || iadc > fgkNadcMcm ) return -100;
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;
192   if( padcol < 0 || padcol >= fgkNcol ) return -1;   // this is commented because of reason above OK
193
194   return padcol;
195
196 }
197
198 //_____________________________________________________________________________
199 Int_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]
209   Int_t padcol = mcmcol*fgkNadcMcm + fgkNcolMcm + 2 - iadc;
210
211   return padcol;
212
213 }
214
215 //_____________________________________________________________________________
216 Int_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);
226
227 }
228
229 //_____________________________________________________________________________
230 Int_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 //_____________________________________________________________________________
252 Int_t AliTRDfeeParam::GetROBfromPad(Int_t irow, Int_t icol) const
253 {
254   //
255   // Return on which rob this pad is
256   //
257
258   return (irow/fgkNmcmRobInRow)*2 + GetColSide(icol);
259
260 }
261
262 //_____________________________________________________________________________
263 Int_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 //_____________________________________________________________________________
275 Int_t AliTRDfeeParam::GetRobSide(Int_t irob) const
276 {
277   //
278   // Return on which side this rob sits (A side = 0, B side = 1)
279   //
280
281   if ( irob < 0 || irob >= fgkNrobC1 ) return -1;
282
283   return irob%2;
284
285 }
286
287 //_____________________________________________________________________________
288 Int_t AliTRDfeeParam::GetColSide(Int_t icol) const
289 {
290   //
291   // Return on which side this column sits (A side = 0, B side = 1)
292   //
293
294   if ( icol < 0 || icol >= fgkNcol ) return -1;
295
296   return icol/(fgkNcol/2);
297
298 }
299
300
301
302 UInt_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
311 Int_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
373 Short_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
398 Short_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;
404   for( i = 0 ; i < 18 ; i++ ) {  // 18: number of MCMs on a ROB
405      if( (cmA & (1 << i)) != 0 && nmcm<listSize) {
406         mcmList[nmcm] = ((linkpair*2) << 7) | i;
407         ++nmcm;
408     }
409     if( (cmB & (1 << i)) != 0  && nmcm<listSize) {
410        mcmList[nmcm] = ((linkpair*2+1) << 7) | i;
411        ++nmcm;
412     }
413   }
414
415   mcmList[nmcm]=-1;
416   return nmcm;
417 }
418
419
420 //_____________________________________________________________________________
421 void AliTRDfeeParam::SetRAWversion( Int_t rawver )
422 {
423   //
424   // Set raw data version (major number only)
425   // Maximum available number is preset in fgkMaxRAWversion
426   //
427
428   if( rawver >= 0 && rawver <= fgkMaxRAWversion ) {
429     fRAWversion = rawver;
430   } 
431   else {
432     AliError(Form("Raw version is out of range: %d",rawver));
433   }
434
435 }