1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 //-----------------------------------------------------------------------------
19 /// \class AliMUONPayloadTracker
20 /// Decodes rawdata from buffer and stores in TClonesArray.
21 /// First version implement for Tracker
23 /// \author Christian Finck
24 //-----------------------------------------------------------------------------
26 #include <TObjString.h>
28 #include "AliMUONPayloadTracker.h"
30 #include "AliMUONDspHeader.h"
31 #include "AliMUONBlockHeader.h"
32 #include "AliMUONBusStruct.h"
33 #include "AliMUONDDLTracker.h"
35 #include "AliMUONLogger.h"
39 ClassImp(AliMUONPayloadTracker)
42 AliMUONPayloadTracker::AliMUONPayloadTracker()
51 fDDLTracker(new AliMUONDDLTracker()),
52 fBusStruct(new AliMUONBusStruct()),
53 fBlockHeader(new AliMUONBlockHeader()),
54 fDspHeader(new AliMUONDspHeader()),
55 fLog(new AliMUONLogger(1000)),
62 /// create an object to decode MUON payload
67 //___________________________________
68 AliMUONPayloadTracker::~AliMUONPayloadTracker()
80 //______________________________________________________
81 Bool_t AliMUONPayloadTracker::Decode(UInt_t* buffer, Int_t totalDDLSize)
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 !)
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();
99 Int_t totalBusPatchSize;
111 while (buffer[index] == fBlockHeader->GetDefaultDataKey()) {
113 if (iBlock > fMaxBlock) break;
115 // copy within padding words
116 memcpy(fBlockHeader->GetHeader(),&buffer[index], (kBlockHeaderSize)*4);
118 totalBlockSize = fBlockHeader->GetTotalLength();
121 index += kBlockHeaderSize;
123 // copy in TClonesArray
124 fDDLTracker->AddBlkHeader(*fBlockHeader);
128 while (buffer[index] == fDspHeader->GetDefaultDataKey()) {
130 if (iDsp > fMaxDsp) break; // if ever...
132 memcpy(fDspHeader->GetHeader(),&buffer[index], kDspHeaderSize*4);
134 totalDspSize = fDspHeader->GetTotalLength();
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
144 Char_t* msg = Form("Glitch error detected in DSP %d, skipping event ", fBlockHeader->GetDspId());
146 if (fWarnings) AliWarning(msg);
147 AddErrorMessage(msg);
154 index += kDspHeaderSize;
156 // copy in TClonesArray
157 fDDLTracker->AddDspHeader(*fDspHeader, iBlock);
159 // buspatch structure
161 while (buffer[index] == fBusStruct->GetDefaultDataKey()) {
163 if (iBusPatch > fMaxBus) break; // if ever
165 //copy buffer into header structure
166 memcpy(fBusStruct->GetHeader(), &buffer[index], kBusPatchHeaderSize*4);
168 totalBusPatchSize = fBusStruct->GetTotalLength();
169 indexBusPatch = index;
171 //Check Buspatch header, not empty events
172 if(totalBusPatchSize > kBusPatchHeaderSize) {
174 index += kBusPatchHeaderSize;
175 dataSize = fBusStruct->GetLength();
176 bufSize = fBusStruct->GetBufSize();
178 if(dataSize > 0) { // check data present
179 if (dataSize > bufSize) // check buffer size
180 fBusStruct->SetAlloc(dataSize);
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);
188 if(!CheckDataParity()) {
193 // copy in TClonesArray
194 fDDLTracker->AddBusPatch(*fBusStruct, iBlock, iDsp);
198 } // testing buspatch
200 index = indexBusPatch + totalBusPatchSize;
201 if (index >= totalDDLSize) {// check the end of DDL
202 index = totalDDLSize - 1; // point to the last element of buffer
208 // skipping additionnal word if padding
209 if (fDspHeader->GetPaddingWord() == 1) {
210 if (buffer[index++] != fDspHeader->GetDefaultPaddingWord()) {
212 Char_t *msg = Form("Padding word error for iBlock %d, iDsp %d, iBus %d\n",
213 iBlock, iDsp, iBusPatch);
215 if (fWarnings) AliWarning(msg);
216 AddErrorMessage(msg);
221 index = indexDsp + totalDspSize;
222 if (index >= totalDDLSize) {
223 index = totalDDLSize - 1;
229 index = indexBlk + totalBlockSize;
230 if (index >= totalDDLSize) {
231 index = totalDDLSize - 1;
238 if (buffer[index++] != fBlockHeader->GetDdlDataKey() ||
239 buffer[index++] != fBlockHeader->GetDdlDataKey()) {
241 Char_t *msg = Form("Bad end of DDL data key\n");
243 if (fWarnings) AliWarning(msg);
244 AddErrorMessage(msg);
251 //______________________________________________________
252 void AliMUONPayloadTracker::ResetDDL()
254 /// reseting TClonesArray
257 fDDLTracker->GetBlkHeaderArray()->Delete();
264 //______________________________________________________
265 void AliMUONPayloadTracker::SetMaxBlock(Int_t blk)
267 /// set regional card number
268 if (blk > 2) blk = 2;
272 //______________________________________________________
273 Bool_t AliMUONPayloadTracker::CheckDataParity()
276 /// taken from MuTrkBusPatch.cxx (sotfware test for CROCUS)
282 Int_t dataSize = fBusStruct->GetLength();
283 for (int idata = 0; idata < dataSize; idata++) {
285 data = fBusStruct->GetData(idata);
287 // Compute the parity for each data word
289 for (Int_t i = 1; i <= 30; i++)
290 parity ^= ((data >> i) & 0x1);
293 if (parity != fBusStruct->GetParity(idata)) {
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());
299 if (fWarnings) AliWarning(msg);
300 AddErrorMessage(msg);
310 //______________________________________________________
311 void AliMUONPayloadTracker::AddErrorMessage(const Char_t* msg)
313 /// adding message to logger
317 Int_t pos = tmp.First("\n");
320 fLog->Log(tmp.Data());