]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONPayloadTracker.cxx
More robust raw-reader for HLT
[u/mrichter/AliRoot.git] / MUON / AliMUONPayloadTracker.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 /// \class AliMUONPayloadTracker
18 /// Decodes rawdata from buffer and stores in TClonesArray.
19 /// First version implement for Tracker
20 ///
21 /// \author Christian Finck
22
23 #include "AliMUONPayloadTracker.h"
24
25 #include "AliMUONDspHeader.h"
26 #include "AliMUONBlockHeader.h"
27 #include "AliMUONBusStruct.h"
28 #include "AliMUONDDLTracker.h"
29
30 #include "AliLog.h"
31
32 /// \cond CLASSIMP
33 ClassImp(AliMUONPayloadTracker)
34 /// \endcond
35
36 AliMUONPayloadTracker::AliMUONPayloadTracker()
37   : TObject(),
38     fBusPatchId(0),
39     fDspId(0),
40     fBlkId(0),
41     fMaxDDL(20),
42     fMaxBlock(2),
43     fMaxDsp(5),
44     fMaxBus(5),
45     fDDLTracker(new AliMUONDDLTracker()),
46     fBusStruct(new AliMUONBusStruct()),
47     fBlockHeader(new AliMUONBlockHeader()),
48     fDspHeader(new AliMUONDspHeader()),
49     fParityErrBus(),
50     fGlitchErrors(0),
51     fPaddingErrors(0)
52 {
53   ///
54   /// create an object to decode MUON payload
55   ///
56
57 }
58
59 //___________________________________
60 AliMUONPayloadTracker::~AliMUONPayloadTracker()
61 {
62   ///
63   /// clean up
64   ///
65   delete fDDLTracker;
66   delete fBusStruct;
67   delete fBlockHeader;
68   delete fDspHeader;
69 }
70
71 //______________________________________________________
72 Bool_t AliMUONPayloadTracker::Decode(UInt_t* buffer, Int_t totalDDLSize)
73 {
74
75   /// Each DDL is made with 2 Blocks each of which consists of 5 DSP's at most 
76   /// and each of DSP has at most 5 buspatches.
77   /// The different structures, Block (CRT), DSP (FRT) and Buspatch,
78   /// are identified by a key word 0xFC0000FC, 0xF000000F and 0xB000000B respectively.
79   /// (fBusPatchManager no more needed !)
80
81
82   //Read Header Size of DDL,Block,DSP and BusPatch
83   static Int_t kBlockHeaderSize    = fBlockHeader->GetHeaderLength();
84   static Int_t kDspHeaderSize      = fDspHeader->GetHeaderLength();
85   static Int_t kBusPatchHeaderSize = fBusStruct->GetHeaderLength();
86
87   // size structures
88   Int_t totalBlockSize;
89   Int_t totalDspSize;
90   Int_t totalBusPatchSize;
91   Int_t dataSize; 
92   Int_t bufSize;
93
94   // indexes
95   Int_t indexBlk;
96   Int_t indexDsp;
97   Int_t indexBusPatch;
98   Int_t index = 0;
99   Int_t iBlock = 0;
100
101   // CROCUS CRT
102   while (buffer[index] == fBlockHeader->GetDefaultDataKey()) {
103
104     if (iBlock > fMaxBlock) break;
105      
106     // copy within padding words
107     memcpy(fBlockHeader->GetHeader(),&buffer[index], (kBlockHeaderSize)*4);
108
109     totalBlockSize = fBlockHeader->GetTotalLength();
110
111     indexBlk = index;
112     index += kBlockHeaderSize;
113
114     // copy in TClonesArray
115     fDDLTracker->AddBlkHeader(*fBlockHeader);
116
117     // Crocus FRT
118     Int_t iDsp = 0;
119     while (buffer[index] == fDspHeader->GetDefaultDataKey()) {
120
121       if (iDsp > fMaxDsp) break; // if ever...
122                 
123       memcpy(fDspHeader->GetHeader(),&buffer[index], kDspHeaderSize*4);
124
125       totalDspSize = fDspHeader->GetTotalLength();
126
127       if (fDspHeader->GetErrorWord()) {
128         fDspHeader->Print("");
129         if (fDspHeader->GetErrorWord() == (0x000000B1 |  fBlockHeader->GetDspId())){
130           // an event with a glitch in the readout  has been detected
131           // it means that somewhere a 1 byte word has been randomly inserted
132           // all the readout sequence is shifted  untill the next event 
133
134           AliWarning(Form("Glitch in data detected, skipping event ")); 
135
136           fGlitchErrors++;
137           return kFALSE ; 
138         }       
139       }
140       
141       indexDsp = index;
142       index += kDspHeaderSize;
143
144       // copy in TClonesArray
145       fDDLTracker->AddDspHeader(*fDspHeader, iBlock);
146
147       // buspatch structure
148       Int_t iBusPatch = 0;
149       while (buffer[index] == fBusStruct->GetDefaultDataKey()) {
150
151         if (iBusPatch > fMaxBus) break; // if ever
152         
153         //copy buffer into header structure
154         memcpy(fBusStruct->GetHeader(), &buffer[index], kBusPatchHeaderSize*4);
155
156         totalBusPatchSize = fBusStruct->GetTotalLength();
157         indexBusPatch     = index;
158                 
159         //Check Buspatch header, not empty events
160         if(totalBusPatchSize > kBusPatchHeaderSize) {    
161
162           index   += kBusPatchHeaderSize;
163           dataSize = fBusStruct->GetLength();
164           bufSize  = fBusStruct->GetBufSize();
165
166           if(dataSize > 0) { // check data present
167             if (dataSize > bufSize) // check buffer size
168               fBusStruct->SetAlloc(dataSize);
169          
170             //copy buffer into data structure
171             memcpy(fBusStruct->GetData(), &buffer[index], dataSize*4);
172             fBusStruct->SetBlockId(iBlock); // could be usefull in future applications ?
173             fBusStruct->SetDspId(iDsp);
174
175             // check parity
176             if(!CheckDataParity())
177                 AddParityErrBus(fBusStruct->GetBusPatchId());
178
179             // copy in TClonesArray
180             fDDLTracker->AddBusPatch(*fBusStruct, iBlock, iDsp);
181
182           } // dataSize test
183
184         } // testing buspatch
185
186         index = indexBusPatch + totalBusPatchSize;
187         if (index >= totalDDLSize) {// check the end of DDL
188           index = totalDDLSize - 1; // point to the last element of buffer
189           break;
190         }
191         iBusPatch++;
192       }  // buspatch loop
193
194       // skipping additionnal word if padding
195       if (fDspHeader->GetPaddingWord() == 1) {
196         if (buffer[index++] != fDspHeader->GetDefaultPaddingWord())
197
198             AliWarning(Form("Error in padding word for iBlock %d, iDsp %d, iBus %d\n", 
199                           iBlock, iDsp, iBusPatch));
200
201         fPaddingErrors++;
202       }
203
204       index = indexDsp + totalDspSize;
205       if (index >= totalDDLSize) {
206         index = totalDDLSize - 1;
207         break;
208       }
209       iDsp++;
210     }  // dsp loop
211
212     index = indexBlk + totalBlockSize;
213     if (index >= totalDDLSize) {
214       index = totalDDLSize - 1;
215       break;
216     }
217     iBlock++;
218   }  // block loop
219
220   return kTRUE;
221 }
222
223 //______________________________________________________
224 void AliMUONPayloadTracker::ResetDDL()
225 {
226   /// reseting TClonesArray
227   /// after each DDL
228   ///
229   fDDLTracker->GetBlkHeaderArray()->Delete();
230   fGlitchErrors = 0;
231   fPaddingErrors = 0;
232   fParityErrBus.Reset();
233
234 }
235
236 //______________________________________________________
237 void AliMUONPayloadTracker::SetMaxBlock(Int_t blk) 
238 {
239   /// set regional card number
240   if (blk > 2) blk = 2;
241   fMaxBlock = blk;
242 }
243
244 //______________________________________________________
245 Bool_t AliMUONPayloadTracker::CheckDataParity()
246 {
247   /// parity check
248   /// taken from MuTrkBusPatch.cxx (sotfware test for CROCUS)
249   /// A. Baldisseri
250
251   Int_t  parity;
252   UInt_t data;
253   
254   Int_t dataSize = fBusStruct->GetLength();
255   for (int idata = 0; idata < dataSize; idata++) {
256
257     data  = fBusStruct->GetData(idata);
258
259     // Compute the parity for each data word
260     parity  = data & 0x1;
261     for (Int_t i = 1; i <= 30; i++) 
262       parity ^= ((data >> i) & 0x1);
263
264     // Check
265     if (parity != fBusStruct->GetParity(idata)) {
266
267       AliWarning(Form("Parity error in word %d for manuId %d and channel %d\n", 
268                       idata, fBusStruct->GetManuId(idata), fBusStruct->GetChannelId(idata)));
269
270       return kFALSE;
271                      
272     }
273   }
274   return kTRUE;
275 }
276
277 //______________________________________________________
278 void AliMUONPayloadTracker::AddParityErrBus(Int_t buspatch)
279 {
280 /// adding bus with at least on parity error
281     fParityErrBus.Set(fParityErrBus.GetSize() + 1);
282     fParityErrBus.AddAt(buspatch, fParityErrBus.GetSize() - 1);
283 }