Added static AliEMCALRecoUtils::ExtrapolateTrackToEMCalSurface function that operates...
[u/mrichter/AliRoot.git] / EMCAL / AliEMCALTriggerSTURawStream.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 /*
18
19
20
21 This class provides access to STU DDL raw data.
22 Author: R. GUERNANE LPSC Grenoble CNRS/IN2P3
23 */
24
25 #include "AliEMCALTriggerSTURawStream.h"
26 #include "AliRawReader.h"
27 #include "AliLog.h"
28
29 #include "Riostream.h"
30 #include "TBits.h"
31
32 #include <cstdlib>
33
34 namespace
35 {
36         const Int_t kPayLoadSizeV0     = 236;
37         const Int_t kPayLoadSizeV1     = 245;        
38         const Int_t kPayLoadSizeV2     = 390;        
39 }
40
41 using std::cout;
42 using std::setw;
43 using std::endl;
44 ClassImp(AliEMCALTriggerSTURawStream)
45
46 //_____________________________________________________________________________
47 AliEMCALTriggerSTURawStream::AliEMCALTriggerSTURawStream() : TObject(),
48 fRawReader(0x0),
49 fL1JetThreshold(),
50 fL1GammaThreshold(),
51 fL0GammaPatchIndex(),
52 fL1GammaPatchIndex(),
53 fL1JetPatchIndex(),
54 fNL0GammaPatch(0),
55 fNL1JetPatch(),
56 fNL1GammaPatch(),
57 fGetRawData(0),
58 fV0A(0),
59 fV0C(0),
60 fG(),
61 fJ(),
62 fRegionEnable(0),
63 fFrameReceived(0),
64 fFwVersion(0)
65 {
66         //
67         for (int i = 0; i < 2; i++) {
68                 //
69                 fL1JetThreshold[i] = fL1GammaThreshold[i] = 0;
70                 
71                 fNL1JetPatch[i] = fNL1GammaPatch[i] = 0;
72         }
73         
74         for (int i = 0; i < 3; i++) {
75                 for (int j = 0; j < 2; j++) {
76                         //
77                         fG[i][j] = fJ[i][j] = 0;
78                 }
79         }
80         
81         for (int i = 0; i < 3100; i++) {
82                 //
83                 fL0GammaPatchIndex[i] = 0;
84                 
85                 for (int j = 0; j < 2; j++) {
86                         
87                         fL1GammaPatchIndex[i][j] = 0;
88                 }
89         }
90         
91         for (int i = 0; i < 200; i++) {
92                 for (int j = 0; j < 2; j++) {
93                         
94                         fL1JetPatchIndex[i][j] = 0;
95                 }
96         }
97 }
98
99 //_____________________________________________________________________________
100 AliEMCALTriggerSTURawStream::AliEMCALTriggerSTURawStream(AliRawReader* rawReader) : TObject(),
101 fRawReader(rawReader),
102 fL1JetThreshold(),
103 fL1GammaThreshold(),
104 fL0GammaPatchIndex(),
105 fL1GammaPatchIndex(),
106 fL1JetPatchIndex(),
107 fNL0GammaPatch(0),
108 fNL1JetPatch(),
109 fNL1GammaPatch(),
110 fGetRawData(0),
111 fV0A(0),
112 fV0C(0),
113 fG(),
114 fJ(),
115 fRegionEnable(0),
116 fFrameReceived(0),
117 fFwVersion(0)
118 {
119         //
120         fRawReader->Reset();
121         fRawReader->Select("EMCAL",44);
122         //
123         for (int i = 0; i < 2; i++) {
124                 //
125                 fL1JetThreshold[i] = fL1GammaThreshold[i] = 0;
126                 
127                 fNL1JetPatch[i] = fNL1GammaPatch[i] = 0;
128         }
129         
130         for (int i = 0; i < 3; i++) {
131                 for (int j = 0; j < 2; j++) {
132                         //
133                         fG[i][j] = fJ[i][j] = 0;
134                 }
135         }
136         
137         for (int i = 0; i < 3100; i++) {
138                 //
139                 fL0GammaPatchIndex[i] = 0;
140                 
141                 for (int j = 0; j < 2; j++) {
142                         
143                         fL1GammaPatchIndex[i][j] = 0;
144                 }
145         }
146         
147         for (int i = 0; i < 200; i++) {
148                 for (int j = 0; j < 2; j++) {
149                         
150                         fL1JetPatchIndex[i][j] = 0;
151                 }
152         }
153 }
154
155 //_____________________________________________________________________________
156 AliEMCALTriggerSTURawStream::~AliEMCALTriggerSTURawStream()
157 {
158         // destructor
159 }
160
161 //_____________________________________________________________________________
162 void AliEMCALTriggerSTURawStream::Reset()
163 {
164         // Reset
165         
166         if (fRawReader) fRawReader->Reset();
167         
168         fNL0GammaPatch = 0;
169         fNL1GammaPatch[0] = fNL1GammaPatch[1] = 0;
170         fNL1JetPatch[0] = fNL1JetPatch[1] = 0;
171 }
172
173 //_____________________________________________________________________________
174 Bool_t AliEMCALTriggerSTURawStream::ReadPayLoad()
175 {
176         // STU data decoder from Olivier Bourrion LPSC CNRS-IN2P3
177         // bourrion_at_lpsc_dot_in2p3_dot_fr
178         
179         UInt_t word32[kPayLoadSizeV2 + 1536]; // 32b words
180         for (Int_t i = 0;i < kPayLoadSizeV2 + 1536; i++) word32[i] = 0;
181         
182         Int_t iword = 0;
183         
184         fNL0GammaPatch = 0;
185         fNL1GammaPatch[0] = fNL1GammaPatch[1] = 0;
186         fNL1JetPatch[0] = fNL1JetPatch[1] = 0;
187         
188         Int_t eqId = -1, eqSize = 0;
189         
190         UInt_t w32;
191         
192         while (fRawReader->ReadNextInt(w32)) 
193         {
194                 if (!iword)
195                 {
196                         eqId   = fRawReader->GetEquipmentId();
197                         eqSize = fRawReader->GetEquipmentSize();
198                 }
199                 
200                 word32[iword++] = w32;
201         }
202  
203         if (iword != kPayLoadSizeV0 && iword != kPayLoadSizeV1 && iword != kPayLoadSizeV2 
204                 && 
205                 iword != (kPayLoadSizeV0 + 1536) && iword != (kPayLoadSizeV1 + 1536) && iword != (kPayLoadSizeV2 + 1536))
206         {
207                 AliError(Form("STU payload (eqId: %d, eqSize: %d) doesn't match expected size! %d word32",
208                                           eqId, eqSize, iword));
209                 return kFALSE;
210         }
211         
212         AliDebug(1, Form("STU (eqId: %d, eqSize: %d) payload size: %d word32",
213                                          eqId, eqSize, iword));
214         
215         int offset = 1;//, jetSize = 2;
216         
217         int nthres = 1;
218         
219         switch (iword) 
220         {
221                 case kPayLoadSizeV0:
222                 case kPayLoadSizeV0 + 1536:
223                 {
224                         fL1JetThreshold[0]   = ((word32[0]>>16) & 0xFFFF);
225                         fL1GammaThreshold[0] =  (word32[0]      & 0xFFFF);
226                         
227                         break;
228                 }
229                 case kPayLoadSizeV1:
230                 case kPayLoadSizeV1 + 1536:
231                 {
232                         fV0A = ((word32[0]>>16) & 0xFFFF);
233                         fV0C =  (word32[0]      & 0xFFFF);
234                         
235                         fG[0][0]       = word32[1];
236                         fG[1][0]       = word32[2];
237                         fG[2][0]       = word32[3];
238                         fJ[0][0]       = word32[4];
239                         fJ[1][0]       = word32[5];
240                         fJ[2][0]       = word32[6];             
241                         fRegionEnable  = word32[7];
242                         fFrameReceived = word32[8];
243                         fFwVersion     = word32[9];
244                         
245                         fL1JetThreshold[0]   = GetThreshold(fJ[0][0], fJ[1][0], fJ[2][0], fV0A, fV0C);
246                         fL1GammaThreshold[0] = GetThreshold(fG[0][0], fG[1][0], fG[2][0], fV0A, fV0C); 
247                         
248                         offset = 10;
249                         
250                         break;
251                 }
252                 case kPayLoadSizeV2:
253                 case kPayLoadSizeV2 + 1536:
254                 {
255                         fV0A = ((word32[0]>>16) & 0xFFFF);
256                         fV0C =  (word32[0]      & 0xFFFF);
257                         
258                         fG[0][0]       = word32[1];
259                         fG[1][0]       = word32[2];
260                         fG[2][0]       = word32[3];
261                         fJ[0][0]       = word32[4];
262                         fJ[1][0]       = word32[5];
263                         fJ[2][0]       = word32[6];             
264                         
265                         fG[0][1]       = word32[7];
266                         fG[1][1]       = word32[8];
267                         fG[2][1]       = word32[9];
268                         fJ[0][1]       = word32[10];
269                         fJ[1][1]       = word32[11];
270                         fJ[2][1]       = word32[12];            
271                         
272                         fRegionEnable  = word32[13];
273                         fFrameReceived = word32[14];
274                         fFwVersion     = word32[15];
275                         
276                         for (int i = 0; i < 2; i++) {
277                                 //
278                                 fL1JetThreshold[i]   = GetThreshold(fJ[0][i], fJ[1][i], fJ[2][i], fV0A, fV0C);
279                                 fL1GammaThreshold[i] = GetThreshold(fG[0][i], fG[1][i], fG[2][i], fV0A, fV0C); 
280                         }
281                         
282                         offset = 16;                    
283                         
284                         nthres = 2;
285                         
286                         break;
287                 }
288         }
289         
290 //      jetSize += (fFwVersion >> 16);
291         
292         ///////////
293         // START DECODING
294         //////////
295
296         for (int i = 0; i < nthres; i++) {
297                 DecodeL1JetPatchIndexes(i, word32, offset);
298                 
299                 offset += 11;
300         }
301         
302         DecodeL0GammaPatchIndexes(word32, offset);
303         
304         offset += 96;
305         
306         for (int i = 0; i < nthres; i++) {
307                 DecodeL1GammaPatchIndexes(i, word32, offset);   
308                 
309                 offset += 128;
310         }
311         
312         if (iword == kPayLoadSizeV0 || iword == kPayLoadSizeV1 || iword == kPayLoadSizeV2) {
313                 fGetRawData = 0;
314                 return kTRUE;
315         }
316         
317         fGetRawData = 1;
318         
319         DecodeTRUADC(word32, offset);
320         
321         return kTRUE;
322 }
323
324 //_____________________________________________________________________________
325 void AliEMCALTriggerSTURawStream::DecodeL0GammaPatchIndexes(UInt_t *word32, const int offset)
326 {
327         //////////////////////////////////////////////////////////
328         // index des L0                                         //
329         //////////////////////////////////////////////////////////
330         // FIXME: sounds like not valid data
331         
332         unsigned short truL0indexes[32][6];
333         
334         // extraction from stream
335         for (Int_t index=0;index<6;index++)
336         {
337                 for (Int_t tru_num=0;tru_num<16;tru_num++)
338                 {
339                         truL0indexes[2*tru_num  ][index] = ( word32[offset + index * 16 + tru_num]        & 0xFFFF);
340                         truL0indexes[2*tru_num+1][index] = ((word32[offset + index * 16 + tru_num] >> 16) & 0xFFFF);
341                 }
342         }
343         
344         for (Int_t tru_num=0;tru_num<32;tru_num++) 
345         {
346                 for (Int_t index=0;index<6;index++) 
347                 {
348                         for (Int_t bit_num=0;bit_num<12;bit_num++)
349                         {
350                                 if ((truL0indexes[tru_num][index] & (1 << bit_num)))
351                                 {
352                                         Int_t idx = 12 * index + bit_num;
353                                         
354                                         fNL0GammaPatch++;
355                                         
356                                         fL0GammaPatchIndex[fNL0GammaPatch-1] = (((idx << 5) & 0x7E0) | (tru_num & 0x1F));
357                                 }
358                         }
359                 }
360         }
361 }
362
363 //_____________________________________________________________________________
364 void AliEMCALTriggerSTURawStream::DecodeL1JetPatchIndexes(const int i, UInt_t *word32, const int offset)
365 {
366         //////////////////////////////////////////////////////////
367         // index des L1 jet                                     //
368         //////////////////////////////////////////////////////////
369         
370         int jetSize = 2 + (fFwVersion >> 16);
371         
372         for (Int_t jet_row = 0; jet_row < 12 - (jetSize - 1); jet_row++)
373         {
374                 UInt_t currentrow = word32[offset + jet_row];
375                 
376                 for (Int_t jet_col = 0; jet_col < 15; jet_col++)
377                 {
378                         if (currentrow & (1 << jet_col))
379                         {
380                                 fNL1JetPatch[i] = fNL1JetPatch[i] + 1;
381                                 
382                                 fL1JetPatchIndex[fNL1JetPatch[i] - 1][i] = ((jet_row << 8) & 0xFF00) | (jet_col & 0xFF);
383                         }
384                 }
385         }
386 }
387
388 //_____________________________________________________________________________
389 void AliEMCALTriggerSTURawStream::DecodeL1GammaPatchIndexes(const int i, UInt_t *word32, const int offset)
390 {
391         //////////////////////////////////////////////////////////
392         // index des L1 gamma                                   //
393         //////////////////////////////////////////////////////////
394         
395         unsigned short truL1indexes[32][8];
396         
397         // extraction from stream
398         for (Int_t index=0;index<8;index++)
399         {
400                 for (Int_t tru_num=0;tru_num<16;tru_num++)
401                 {
402                         truL1indexes[2*tru_num  ][index] = ( word32[offset + index * 16 + tru_num]        & 0xFFFF);
403                         truL1indexes[2*tru_num+1][index] = ((word32[offset + index * 16 + tru_num] >> 16) & 0xFFFF);
404                 }
405         }       
406         
407         // interpretation
408         int gammacolnum;
409         short indexcopy;
410         
411         for (Int_t tru_num=0;tru_num<32;tru_num++)
412         {
413                 for (Int_t index=0;index<8;index++)
414                 {
415                         for (Int_t bit_num=0; bit_num<12; bit_num++)
416                         {
417                                 if ((truL1indexes[tru_num][index] & (1<<bit_num)) != 0)
418                                 {
419                                         if (index<4) // Even
420                                         {
421                                                 gammacolnum = (2*bit_num  );
422                                                 indexcopy   = index;
423                                         }
424                                         else         // Odd
425                                         {
426                                                 gammacolnum = (2*bit_num+1);
427                                                 indexcopy   = index-4;
428                                         }                                               
429                                         
430                                         fNL1GammaPatch[i] = fNL1GammaPatch[i] + 1;
431                                         
432                                         fL1GammaPatchIndex[fNL1GammaPatch[i] - 1][i] = (((indexcopy << 10) & 0xC00) | ((gammacolnum << 5) & 0x3E0) | (tru_num & 0x1F));
433                                 }
434                         }
435                 }
436         }       
437 }
438
439 //_____________________________________________________________________________
440 void AliEMCALTriggerSTURawStream::DecodeTRUADC(UInt_t *word32, const int offset)
441 {
442         // extraction from stream
443         for (Int_t index=0;index<96;index++)
444         {
445                 for (Int_t tru_num=0;tru_num<16;tru_num++)
446                 {
447                         fADC[2*tru_num  ][index] = ( word32[offset + index * 16 + tru_num]        & 0xFFFF);
448                         fADC[2*tru_num+1][index] = ((word32[offset + index * 16 + tru_num] >> 16) & 0xFFFF);
449                 }
450         }       
451         
452         for (Int_t tru_num=16;tru_num<32;tru_num++) // A side
453         {
454                 Int_t v[96];
455                 for (Int_t index=0;index<96;index++) v[index] = fADC[tru_num][95-index];
456                 
457                 for (Int_t index=0;index<96;index++) fADC[tru_num][index] = v[index];
458         }
459 }
460
461
462 //_____________________________________________________________________________
463 Bool_t AliEMCALTriggerSTURawStream::GetL0GammaPatch(const Int_t i, Int_t& tru, Int_t& idx) const
464 {
465         // L0 gamma patches sent to STU (original access to L0 patch indexes)
466         
467         if (i > fNL0GammaPatch) return kFALSE;
468         
469         tru =  fL0GammaPatchIndex[i] & 0x1F;
470         idx = (fL0GammaPatchIndex[i] & 0x7E0) >> 5;
471         
472         return kTRUE;
473 }
474
475 //_____________________________________________________________________________
476 Bool_t AliEMCALTriggerSTURawStream::GetL1GammaPatch(const Int_t i, const Int_t j, Int_t& tru, Int_t& col, Int_t& row) const
477 {
478         // L1 gamma patch indexes
479         
480         if (j >= 2 || i > fNL1GammaPatch[j]) return kFALSE;
481         
482         tru =  fL1GammaPatchIndex[i][j] & 0x1F;
483         col = (fL1GammaPatchIndex[i][j] & 0x3E0) >> 5;
484         row = (fL1GammaPatchIndex[i][j] & 0xC00) >> 10;
485         
486         return kTRUE;
487 }
488
489 //_____________________________________________________________________________
490 Bool_t AliEMCALTriggerSTURawStream::GetL1JetPatch(const Int_t i, const Int_t j, Int_t& col, Int_t& row) const
491 {
492         // L1 jet patch indexes
493         
494         if (j >= 2 || i > fNL1JetPatch[j]) return kFALSE;
495         
496         col =  fL1JetPatchIndex[i][j] & 0xFF;
497         row = (fL1JetPatchIndex[i][j] & 0xFF00) >> 8;
498         
499         return kTRUE;
500 }
501
502 //_____________________________________________________________________________
503 void AliEMCALTriggerSTURawStream::GetADC(Int_t iTRU, UInt_t ADC[])
504 {
505         // Time sums
506         
507         for (Int_t i=0; i<96; i++) ADC[i] = fADC[iTRU][i];
508 }
509
510 //_____________________________________________________________________________
511 void AliEMCALTriggerSTURawStream::DumpPayLoad(const Option_t *option) const
512 {
513         // Dump STU payload
514         
515         TString op = option;
516         
517         printf("V0A:             %d\n", fV0A);
518         printf("V0C:             %d\n", fV0C);
519
520         printf("RawData:         %d\n", fGetRawData);
521         printf("RegionEnable:    %8x\n", fRegionEnable); 
522         printf("FrameReceived:   %8x\n", fFrameReceived);
523         printf("FwVersion:       %x\n", fFwVersion);
524         printf("Number of L0:    %d\n", fNL0GammaPatch);
525
526         for (int i = 0; i < 2; i++) {
527                 for (int j = 0; j < 3; j++) {
528                         printf("G[%d][%d]: %d\n", j, i, fG[j][i]);
529                         printf("J[%d][%d]: %d\n", j, i, fJ[j][i]);
530                 }
531                 
532                 printf("Gamma threshold[%d]: %d\n", i, fL1GammaThreshold[i]);
533                 printf("Jet Threshold[%d]:   %d\n", i, fL1JetThreshold[i]);
534
535                 printf("Number of L1-g[%d]: %d\n", i, fNL1GammaPatch[i]);
536                 printf("Number of L1-j[%d]: %d\n", i, fNL1JetPatch[i]);
537         }
538         
539         Int_t itru, col, row;
540         
541         if (op.Contains("L0") || op.Contains("ALL"))
542         {
543                 for (Int_t i = 0;i < fNL0GammaPatch; i++) {
544                         if (GetL0GammaPatch(i,itru,col)) 
545                                 cout << "> Found L0 gamma in TRU #" << setw(2) << itru <<  " at idx: " << setw(2) << col << endl;
546                 }
547         }
548         
549         if (op.Contains("L1") || op.Contains("ALL")) {
550                 for (int j = 0; j < 2; j++) {
551                         for (Int_t i = 0; i < fNL1GammaPatch[j]; i++) {
552                                 if (GetL1GammaPatch(i, j, itru, col, row)) 
553                                         cout << "> Found L1 gamma " << j << " in TRU #" << setw(2) << itru <<  " at: ( col: " << setw(2) << col << " , row: " << setw(2) << row << " )" << endl;
554                         }
555                         
556                         for (Int_t i = 0; i < fNL1JetPatch[j]; i++) {
557                                 if (GetL1JetPatch(i, j, col, row)) cout << "> Found L1 jet " << j << " at: ( col: " << setw(2) << col << " , row: " << setw(2) << row << " )" << endl;
558                         }
559                 }
560         }
561         
562         if ((op.Contains("ADC") || op.Contains("ALL")) && fGetRawData) {
563                 for (Int_t i = 0; i < 32; i++) {
564                         cout << "--------\n";
565                         cout << "TRU #" << setw(2) << i << ":";
566                         for (Int_t j = 0;j < 96; j++) { 
567                                 //TBits xadc(12); xadc.Set(12,&fADC[i][j]); 
568                                 if ((j % 4) == 0) cout << endl;
569                                 //cout << setw(2) << j << ": " << xadc << " ";
570                                 printf("%2d: %3x / ",j,fADC[i][j]); 
571                         }
572                         cout << "\n";
573                 }
574         }
575 }
576
577 //_____________________________________________________________________________
578 UShort_t AliEMCALTriggerSTURawStream::GetThreshold(Short_t A, Short_t B, Short_t C, UShort_t V0A, UShort_t V0C) const
579 {
580         // Get threshold 
581   ULong64_t v0sum = V0A + V0C;
582   
583   ULong64_t sqrV0 = v0sum * v0sum;                                      
584                                         
585   sqrV0 *= A;
586                                         
587   sqrV0 >>= 32;
588                                 
589   v0sum *= B;
590                                         
591   v0sum >>= 16;
592                                         
593   return (UShort_t)(sqrV0 + v0sum + C);
594 }