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