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 **************************************************************************/
17 /// \class AliMUONPayloadTracker
18 /// Decodes rawdata from buffer and stores in TClonesArray.
19 /// First version implement for Tracker
21 /// \author Christian Finck
23 #include "AliMUONPayloadTracker.h"
25 #include "AliMUONDspHeader.h"
26 #include "AliMUONBlockHeader.h"
27 #include "AliMUONBusStruct.h"
28 #include "AliMUONDDLTracker.h"
33 ClassImp(AliMUONPayloadTracker)
36 AliMUONPayloadTracker::AliMUONPayloadTracker()
45 fDDLTracker(new AliMUONDDLTracker()),
46 fBusStruct(new AliMUONBusStruct()),
47 fBlockHeader(new AliMUONBlockHeader()),
48 fDspHeader(new AliMUONDspHeader()),
54 /// create an object to decode MUON payload
59 //___________________________________
60 AliMUONPayloadTracker::~AliMUONPayloadTracker()
71 //______________________________________________________
72 Bool_t AliMUONPayloadTracker::Decode(UInt_t* buffer, Int_t totalDDLSize)
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 !)
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();
90 Int_t totalBusPatchSize;
102 while (buffer[index] == fBlockHeader->GetDefaultDataKey()) {
104 if (iBlock > fMaxBlock) break;
106 // copy within padding words
107 memcpy(fBlockHeader->GetHeader(),&buffer[index], (kBlockHeaderSize)*4);
109 totalBlockSize = fBlockHeader->GetTotalLength();
112 index += kBlockHeaderSize;
114 // copy in TClonesArray
115 fDDLTracker->AddBlkHeader(*fBlockHeader);
119 while (buffer[index] == fDspHeader->GetDefaultDataKey()) {
121 if (iDsp > fMaxDsp) break; // if ever...
123 memcpy(fDspHeader->GetHeader(),&buffer[index], kDspHeaderSize*4);
125 totalDspSize = fDspHeader->GetTotalLength();
127 if (fDspHeader->GetErrorWord()) {
128 fDspHeader->Print("");
129 if ( fDspHeader->GetErrorWord() == (0x000000B1 | fBlockHeader->GetDspId())
130 || fDspHeader->GetErrorWord() == (0x00000091 | fBlockHeader->GetDspId()) ){
131 // an event with a glitch in the readout has been detected
132 // it means that somewhere a 1 byte word has been randomly inserted
133 // all the readout sequence is shifted untill the next event
135 AliWarning(Form("Glitch in data detected, skipping event "));
143 index += kDspHeaderSize;
145 // copy in TClonesArray
146 fDDLTracker->AddDspHeader(*fDspHeader, iBlock);
148 // buspatch structure
150 while (buffer[index] == fBusStruct->GetDefaultDataKey()) {
152 if (iBusPatch > fMaxBus) break; // if ever
154 //copy buffer into header structure
155 memcpy(fBusStruct->GetHeader(), &buffer[index], kBusPatchHeaderSize*4);
157 totalBusPatchSize = fBusStruct->GetTotalLength();
158 indexBusPatch = index;
160 //Check Buspatch header, not empty events
161 if(totalBusPatchSize > kBusPatchHeaderSize) {
163 index += kBusPatchHeaderSize;
164 dataSize = fBusStruct->GetLength();
165 bufSize = fBusStruct->GetBufSize();
167 if(dataSize > 0) { // check data present
168 if (dataSize > bufSize) // check buffer size
169 fBusStruct->SetAlloc(dataSize);
171 //copy buffer into data structure
172 memcpy(fBusStruct->GetData(), &buffer[index], dataSize*4);
173 fBusStruct->SetBlockId(iBlock); // could be usefull in future applications ?
174 fBusStruct->SetDspId(iDsp);
177 if(!CheckDataParity())
178 AddParityErrBus(fBusStruct->GetBusPatchId());
180 // copy in TClonesArray
181 fDDLTracker->AddBusPatch(*fBusStruct, iBlock, iDsp);
185 } // testing buspatch
187 index = indexBusPatch + totalBusPatchSize;
188 if (index >= totalDDLSize) {// check the end of DDL
189 index = totalDDLSize - 1; // point to the last element of buffer
195 // skipping additionnal word if padding
196 if (fDspHeader->GetPaddingWord() == 1) {
197 if (buffer[index++] != fDspHeader->GetDefaultPaddingWord())
199 AliWarning(Form("Error in padding word for iBlock %d, iDsp %d, iBus %d\n",
200 iBlock, iDsp, iBusPatch));
205 index = indexDsp + totalDspSize;
206 if (index >= totalDDLSize) {
207 index = totalDDLSize - 1;
213 index = indexBlk + totalBlockSize;
214 if (index >= totalDDLSize) {
215 index = totalDDLSize - 1;
224 //______________________________________________________
225 void AliMUONPayloadTracker::ResetDDL()
227 /// reseting TClonesArray
230 fDDLTracker->GetBlkHeaderArray()->Delete();
233 fParityErrBus.Reset();
237 //______________________________________________________
238 void AliMUONPayloadTracker::SetMaxBlock(Int_t blk)
240 /// set regional card number
241 if (blk > 2) blk = 2;
245 //______________________________________________________
246 Bool_t AliMUONPayloadTracker::CheckDataParity()
249 /// taken from MuTrkBusPatch.cxx (sotfware test for CROCUS)
255 Int_t dataSize = fBusStruct->GetLength();
256 for (int idata = 0; idata < dataSize; idata++) {
258 data = fBusStruct->GetData(idata);
260 // Compute the parity for each data word
262 for (Int_t i = 1; i <= 30; i++)
263 parity ^= ((data >> i) & 0x1);
266 if (parity != fBusStruct->GetParity(idata)) {
268 AliWarning(Form("Parity error in word %d for manuId %d and channel %d\n",
269 idata, fBusStruct->GetManuId(idata), fBusStruct->GetChannelId(idata)));
278 //______________________________________________________
279 void AliMUONPayloadTracker::AddParityErrBus(Int_t buspatch)
281 /// adding bus with at least on parity error
282 fParityErrBus.Set(fParityErrBus.GetSize() + 1);
283 fParityErrBus.AddAt(buspatch, fParityErrBus.GetSize() - 1);