Merge branch 'master' into TPCdev
[u/mrichter/AliRoot.git] / STEER / STEER / AliCTPRawStream.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 ///////////////////////////////////////////////////////////////////////////////
17 ///
18 /// This class provides access to CTP DDL raw data.
19 ///
20 /// The raw data format is taken form the trigger TDR.
21 /// The meaning of the trigger class and cluster masks
22 /// are given in the trigger description file (in /data)
23 /// and in the AliCentralTrigger class.
24 ///
25 ///////////////////////////////////////////////////////////////////////////////
26
27 #include "AliCTPRawStream.h"
28 #include "AliRawReader.h"
29 #include "AliLog.h"
30 #include "AliDAQ.h"
31 #include "AliTriggerIR.h"
32
33 ClassImp(AliCTPRawStream)
34
35 //_____________________________________________________________________________
36 AliCTPRawStream::AliCTPRawStream(AliRawReader* rawReader) :
37   fIRArray("AliTriggerIR",3),
38   fOrbit(0),
39   fBC(0),
40   fL0TriggerInputs(0),
41   fL1TriggerInputs(0),
42   fL2TriggerInputs(0),
43   fClassMask(0),
44   fClassMaskNext50(0),
45   fClusterMask(0),
46   fRawReader(rawReader)
47 {
48   // create an object to read CTP raw data
49   //
50   // select the raw data corresponding to
51   // the CTP detector id
52   fRawReader->Reset();
53   AliDebug(1,Form("Selecting raw data for detector %d",AliDAQ::DetectorID("TRG")));
54   fRawReader->Select("TRG");
55 }
56
57 //_____________________________________________________________________________
58 AliCTPRawStream::AliCTPRawStream(const AliCTPRawStream& stream) :
59   TObject(stream),
60   fIRArray("AliTriggerIR",3),
61   fOrbit(0),
62   fBC(0),
63   fL0TriggerInputs(0),
64   fL1TriggerInputs(0),
65   fL2TriggerInputs(0),
66   fClassMask(0),
67   fClassMaskNext50(0),
68   fClusterMask(0),
69   fRawReader(NULL)
70 {
71   // Copy constructor
72   AliFatal("Copy constructor not implemented");
73 }
74
75 //_____________________________________________________________________________
76 AliCTPRawStream& AliCTPRawStream::operator = (const AliCTPRawStream& 
77                                               /* stream */)
78 {
79   AliFatal("Assignment operator not implemented");
80   return *this;
81 }
82
83 //_____________________________________________________________________________
84 AliCTPRawStream::~AliCTPRawStream()
85 {
86   // destructor
87   fIRArray.Delete();
88 }
89
90 //_____________________________________________________________________________
91 void AliCTPRawStream::Reset()
92 {
93   // reset raw stream params
94   fIRArray.Clear();
95
96   fClassMask = fClusterMask = 0;
97   fClassMaskNext50 = 0;
98
99   if (fRawReader) fRawReader->Reset();
100 }
101
102 //_____________________________________________________________________________
103 Bool_t AliCTPRawStream::Next()
104 {
105   // read the whole CTP raw data stream
106   // return kFALSE in case of error
107
108   UChar_t *data = NULL;
109
110   // CTP raw data does not contain CDH
111   fRawReader->RequireHeader(kFALSE);
112
113   if (!fRawReader->ReadNextData(data)) {
114     fRawReader->RequireHeader(kTRUE);
115     return kFALSE;
116   }
117
118   if ((fRawReader->GetDataSize()) < 32 ||
119       ((fRawReader->GetDataSize() % 4) != 0)) {
120     AliError(Form("Wrong CTP raw data size: %d",fRawReader->GetDataSize()));
121     fRawReader->RequireHeader(kTRUE);
122     return kFALSE;
123   }
124
125   fBC = data[0];
126   fBC |= (data[1] & 0xF) << 8;
127
128   fOrbit = data[4] << 12;
129   fOrbit |= (data[5] & 0xF) << 20;
130   fOrbit |= data[8];
131   fOrbit |= (data[9] & 0xF) << 8;
132
133   // 4th word bit 12= version, check here.
134   UInt_t version=data[13] & 0x10;
135
136   if(version == 0){
137    return GetPayloadRun1(data);
138   } 
139   else{
140    return GetPayloadRun2(data);
141   } 
142
143 Bool_t AliCTPRawStream::GetPayloadRun2(UChar_t *data)
144 {
145   fClusterMask = data[12]&0xef;
146
147   fClassMaskNext50 =  ((ULong64_t)data[16] & 0xf) << 46;   // 100..97
148
149   fClassMaskNext50 |= ((ULong64_t)data[21] & 0xF) << 42;   // 96..93
150   fClassMaskNext50 |= (ULong64_t)data[20] << 34;           // 92..85
151
152   fClassMaskNext50 |= ((ULong64_t)data[25] & 0xF) << 30;   //84..81
153   fClassMaskNext50 |= (ULong64_t)data[24] << 22;           //80..73
154
155   fClassMaskNext50 |= ((ULong64_t)data[29] & 0xF) << 18;   //72..69
156   fClassMaskNext50 |= (ULong64_t)data[28] << 10;           //68..61   
157
158   fClassMaskNext50 |= ((ULong64_t)data[33] & 0xf ) << 6;   //60..57
159   fClassMaskNext50 |= ((ULong64_t)data[32] & 0xfc )>> 2;   //56..51
160   fClassMask        = ((ULong64_t)data[32] & 0x3 ) << 48;  //50..49
161
162   fClassMask |= ((ULong64_t)data[37] & 0xf) << 44;         //48..45
163   fClassMask |= (ULong64_t)data[36]  << 36;                //44..37
164
165   fClassMask |= ((ULong64_t)data[41] & 0xf) << 32;         //36..33
166   fClassMask |= (ULong64_t)data[40]  << 24;                //32..25
167
168   fClassMask |= ((ULong64_t)data[45] & 0xf) << 20;         //24..21
169   fClassMask |= (ULong64_t)data[44]  << 12;                //20..13
170
171   fClassMask |= ((ULong64_t)data[49] & 0xf) << 8;         //12..9
172   fClassMask |= (ULong64_t)data[48]  << 0;                //8..1
173
174   if (fRawReader->GetDataSize() == 52) {
175     AliDebug(1,"No trigger input and interaction records found");
176     fRawReader->RequireHeader(kTRUE);
177     return kTRUE;
178   }
179
180   // Read detector trigger inputs
181   if (fRawReader->GetDataSize() < 72) {
182     AliError(Form("Wrong CTP raw data size: %d",fRawReader->GetDataSize()));
183     fRawReader->RequireHeader(kTRUE);
184     return kFALSE;
185   }
186
187   fL0TriggerInputs = data[52] << 12;
188   fL0TriggerInputs |= (data[53] & 0xF) << 20;
189   fL0TriggerInputs |= data[56];
190   fL0TriggerInputs |= (data[57] & 0xF) << 8;
191
192   fL1TriggerInputs = data[60] << 12;
193   fL1TriggerInputs |= (data[61] & 0xF) << 20;
194   fL1TriggerInputs |= data[64];
195   fL1TriggerInputs |= (data[65] & 0xF) << 8;
196
197   fL2TriggerInputs = data[68] << 12;
198   fL2TriggerInputs |= (data[69] & 0xF) << 20;
199
200   if (fRawReader->GetDataSize() == 72) {
201     AliDebug(1,"No interaction records found");
202     fRawReader->RequireHeader(kTRUE);
203     return kTRUE;
204   }
205
206   // Read IRs
207   Int_t iword = 52;
208   UChar_t level = 0;
209   UInt_t *irdata = NULL;
210   UInt_t irsize = 0;
211   UInt_t orbit = 0;
212   Bool_t incomplete = kFALSE, transerr = kFALSE;
213   while (iword < fRawReader->GetDataSize()) {
214     if (data[iword+1] & 0x80) {
215       UChar_t flag = ((data[iword+1] >> 4) & 0x3);
216       if (flag == 0) {
217         if (irdata) {
218           new (fIRArray[fIRArray.GetEntriesFast()])
219             AliTriggerIR(orbit,irsize,irdata,incomplete,transerr);
220           irdata = NULL; irsize = 0;
221         }
222         level = 1;
223         orbit = data[iword] << 12;
224         orbit |= (data[iword+1] & 0xF) << 20;
225         transerr = ((data[iword+1] >> 6) & 0x1);
226         iword += 4;
227         continue;
228       }
229       else if (flag == 3) {
230         if (level == 1) {
231           level = 2;
232           orbit |= data[iword];
233           orbit |= ((data[iword+1] & 0xF) << 8);
234           iword += 4;
235           AliDebug(1,Form("Orbit=0x%x\n",orbit));
236           continue;
237         }
238       }
239       UShort_t bc = data[iword];
240       bc |= ((data[iword+1] & 0xF) << 8);
241       AliDebug(1,Form("BC=0x%x\n",bc));
242       if (bc == 0xFFF) {
243         incomplete = kTRUE;
244       }
245       else {
246         if (level == 2) {
247           level = 3;
248           irdata = (UInt_t *)&data[iword];
249           irsize = 0;
250         }
251         if (level == 3) {
252           irsize++;
253         }
254       }
255     }
256     else
257       AliWarning(Form("Invalid interaction record (%d %d)",iword,fRawReader->GetDataSize()));
258
259     iword += 4;
260   }
261
262   if (irdata) {
263     new (fIRArray[fIRArray.GetEntriesFast()])
264       AliTriggerIR(orbit,irsize,irdata,incomplete,transerr);
265     irdata = NULL; irsize = 0;
266   }
267
268   // Restore the raw-reader state!!
269   fRawReader->RequireHeader(kTRUE);
270  return kTRUE;
271 }
272 Bool_t AliCTPRawStream::GetPayloadRun1(UChar_t *data)
273 {
274   fClusterMask = data[12] >> 2;
275
276   fClassMask =  ((ULong64_t)data[12] & 0x3) << 48;
277
278   fClassMask |= (ULong64_t)data[16] << 36;
279   fClassMask |= ((ULong64_t)data[17] & 0xF) << 44;
280
281   fClassMask |= (ULong64_t)data[20] << 24;
282   fClassMask |= ((ULong64_t)data[21] & 0xF) << 32;
283
284   fClassMask |= (ULong64_t)data[24] << 12;
285   fClassMask |= ((ULong64_t)data[25] & 0xF) << 20;
286
287   fClassMask |= (ULong64_t)data[28];
288   fClassMask |= ((ULong64_t)data[29] & 0xF) << 8;
289
290   if (fRawReader->GetDataSize() == 32) {
291     AliDebug(1,"No trigger input and interaction records found");
292     fRawReader->RequireHeader(kTRUE);
293     return kTRUE;
294   }
295
296   // Read detector trigger inputs
297   if (fRawReader->GetDataSize() < 52) {
298     AliError(Form("Wrong CTP raw data size: %d",fRawReader->GetDataSize()));
299     fRawReader->RequireHeader(kTRUE);
300     return kFALSE;
301   }
302
303   fL0TriggerInputs = data[32] << 12;
304   fL0TriggerInputs |= (data[33] & 0xF) << 20;
305   fL0TriggerInputs |= data[36];
306   fL0TriggerInputs |= (data[37] & 0xF) << 8;
307
308   fL1TriggerInputs = data[40] << 12;
309   fL1TriggerInputs |= (data[41] & 0xF) << 20;
310   fL1TriggerInputs |= data[44];
311   fL1TriggerInputs |= (data[45] & 0xF) << 8;
312
313   fL2TriggerInputs = data[48] << 12;
314   fL2TriggerInputs |= (data[49] & 0xF) << 20;
315
316   if (fRawReader->GetDataSize() == 52) {
317     AliDebug(1,"No interaction records found");
318     fRawReader->RequireHeader(kTRUE);
319     return kTRUE;
320   }
321
322   // Read IRs
323   Int_t iword = 52;
324   UChar_t level = 0;
325   UInt_t *irdata = NULL;
326   UInt_t irsize = 0;
327   UInt_t orbit = 0;
328   Bool_t incomplete = kFALSE, transerr = kFALSE;
329   while (iword < fRawReader->GetDataSize()) {
330     if (data[iword+1] & 0x80) {
331       UChar_t flag = ((data[iword+1] >> 4) & 0x3);
332       if (flag == 0) {
333         if (irdata) {
334           new (fIRArray[fIRArray.GetEntriesFast()])
335             AliTriggerIR(orbit,irsize,irdata,incomplete,transerr);
336           irdata = NULL; irsize = 0;
337         }
338         level = 1;
339         orbit = data[iword] << 12;
340         orbit |= (data[iword+1] & 0xF) << 20;
341         transerr = ((data[iword+1] >> 6) & 0x1);
342         iword += 4;
343         continue;
344       }
345       else if (flag == 3) {
346         if (level == 1) {
347           level = 2;
348           orbit |= data[iword];
349           orbit |= ((data[iword+1] & 0xF) << 8);
350           iword += 4;
351           AliDebug(1,Form("Orbit=0x%x\n",orbit));
352           continue;
353         }
354       }
355       UShort_t bc = data[iword];
356       bc |= ((data[iword+1] & 0xF) << 8);
357       AliDebug(1,Form("BC=0x%x\n",bc));
358       if (bc == 0xFFF) {
359         incomplete = kTRUE;
360       }
361       else {
362         if (level == 2) {
363           level = 3;
364           irdata = (UInt_t *)&data[iword];
365           irsize = 0;
366         }
367         if (level == 3) {
368           irsize++;
369         }
370       }
371     }
372     else
373       AliWarning(Form("Invalid interaction record (%d %d)",iword,fRawReader->GetDataSize()));
374
375     iword += 4;
376   }
377
378   if (irdata) {
379     new (fIRArray[fIRArray.GetEntriesFast()])
380       AliTriggerIR(orbit,irsize,irdata,incomplete,transerr);
381     irdata = NULL; irsize = 0;
382   }
383
384   // Restore the raw-reader state!!
385   fRawReader->RequireHeader(kTRUE);
386
387   return kTRUE;
388 }
389