]>
Commit | Line | Data |
---|---|---|
939ae4b2 | 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 | ||
3d1463c8 | 16 | // $Id$ |
17 | ||
18 | //----------------------------------------------------------------------------- | |
00e86732 | 19 | /// \class AliMUONPayloadTracker |
939ae4b2 | 20 | /// Decodes rawdata from buffer and stores in TClonesArray. |
939ae4b2 | 21 | /// First version implement for Tracker |
22 | /// | |
00e86732 | 23 | /// \author Christian Finck |
3d1463c8 | 24 | //----------------------------------------------------------------------------- |
939ae4b2 | 25 | |
3fe5a267 | 26 | #include <TObjString.h> |
27 | ||
939ae4b2 | 28 | #include "AliMUONPayloadTracker.h" |
29 | ||
939ae4b2 | 30 | #include "AliMUONDspHeader.h" |
31 | #include "AliMUONBlockHeader.h" | |
32 | #include "AliMUONBusStruct.h" | |
33 | #include "AliMUONDDLTracker.h" | |
34 | ||
3fe5a267 | 35 | #include "AliMUONLogger.h" |
1ed3c5c2 | 36 | #include "AliLog.h" |
37 | ||
00e86732 | 38 | /// \cond CLASSIMP |
939ae4b2 | 39 | ClassImp(AliMUONPayloadTracker) |
00e86732 | 40 | /// \endcond |
939ae4b2 | 41 | |
42 | AliMUONPayloadTracker::AliMUONPayloadTracker() | |
43 | : TObject(), | |
9f5dcca3 | 44 | fBusPatchId(0), |
45 | fDspId(0), | |
46 | fBlkId(0), | |
47 | fMaxDDL(20), | |
939ae4b2 | 48 | fMaxBlock(2), |
49 | fMaxDsp(5), | |
9f5dcca3 | 50 | fMaxBus(5), |
51 | fDDLTracker(new AliMUONDDLTracker()), | |
52 | fBusStruct(new AliMUONBusStruct()), | |
53 | fBlockHeader(new AliMUONBlockHeader()), | |
1ed3c5c2 | 54 | fDspHeader(new AliMUONDspHeader()), |
3fe5a267 | 55 | fLog(new AliMUONLogger(1000)), |
56 | fParityErrors(0), | |
b48fc831 | 57 | fGlitchErrors(0), |
3fe5a267 | 58 | fPaddingErrors(0), |
59 | fWarnings(kTRUE) | |
939ae4b2 | 60 | { |
71a2d3aa | 61 | /// |
62 | /// create an object to decode MUON payload | |
63 | /// | |
939ae4b2 | 64 | |
939ae4b2 | 65 | } |
66 | ||
939ae4b2 | 67 | //___________________________________ |
68 | AliMUONPayloadTracker::~AliMUONPayloadTracker() | |
69 | { | |
71a2d3aa | 70 | /// |
71 | /// clean up | |
72 | /// | |
939ae4b2 | 73 | delete fDDLTracker; |
74 | delete fBusStruct; | |
75 | delete fBlockHeader; | |
76 | delete fDspHeader; | |
3fe5a267 | 77 | delete fLog; |
939ae4b2 | 78 | } |
79 | ||
80 | //______________________________________________________ | |
84ceeb06 | 81 | Bool_t AliMUONPayloadTracker::Decode(UInt_t* buffer, Int_t totalDDLSize) |
939ae4b2 | 82 | { |
84ceeb06 | 83 | |
71a2d3aa | 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 !) | |
939ae4b2 | 89 | |
90 | ||
91 | //Read Header Size of DDL,Block,DSP and BusPatch | |
8ecc5cf0 | 92 | static Int_t kBlockHeaderSize = fBlockHeader->GetHeaderLength(); |
93 | static Int_t kDspHeaderSize = fDspHeader->GetHeaderLength(); | |
94 | static Int_t kBusPatchHeaderSize = fBusStruct->GetHeaderLength(); | |
939ae4b2 | 95 | |
84ceeb06 | 96 | // size structures |
939ae4b2 | 97 | Int_t totalBlockSize; |
98 | Int_t totalDspSize; | |
99 | Int_t totalBusPatchSize; | |
100 | Int_t dataSize; | |
84ceeb06 | 101 | Int_t bufSize; |
939ae4b2 | 102 | |
84ceeb06 | 103 | // indexes |
104 | Int_t indexBlk; | |
105 | Int_t indexDsp; | |
106 | Int_t indexBusPatch; | |
107 | Int_t index = 0; | |
108 | Int_t iBlock = 0; | |
939ae4b2 | 109 | |
84ceeb06 | 110 | // CROCUS CRT |
111 | while (buffer[index] == fBlockHeader->GetDefaultDataKey()) { | |
1c66abf3 | 112 | |
84ceeb06 | 113 | if (iBlock > fMaxBlock) break; |
1c66abf3 | 114 | |
84ceeb06 | 115 | // copy within padding words |
116 | memcpy(fBlockHeader->GetHeader(),&buffer[index], (kBlockHeaderSize)*4); | |
1c66abf3 | 117 | |
84ceeb06 | 118 | totalBlockSize = fBlockHeader->GetTotalLength(); |
1c66abf3 | 119 | |
84ceeb06 | 120 | indexBlk = index; |
121 | index += kBlockHeaderSize; | |
1c66abf3 | 122 | |
84ceeb06 | 123 | // copy in TClonesArray |
124 | fDDLTracker->AddBlkHeader(*fBlockHeader); | |
1c66abf3 | 125 | |
84ceeb06 | 126 | // Crocus FRT |
127 | Int_t iDsp = 0; | |
128 | while (buffer[index] == fDspHeader->GetDefaultDataKey()) { | |
1c66abf3 | 129 | |
84ceeb06 | 130 | if (iDsp > fMaxDsp) break; // if ever... |
1c66abf3 | 131 | |
84ceeb06 | 132 | memcpy(fDspHeader->GetHeader(),&buffer[index], kDspHeaderSize*4); |
1c66abf3 | 133 | |
84ceeb06 | 134 | totalDspSize = fDspHeader->GetTotalLength(); |
1c66abf3 | 135 | |
1ed3c5c2 | 136 | if (fDspHeader->GetErrorWord()) { |
1c66abf3 | 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 | ||
3fe5a267 | 144 | Char_t* msg = Form("Glitch error detected in DSP %d, skipping event ", fBlockHeader->GetDspId()); |
145 | ||
146 | if (fWarnings) AliWarning(msg); | |
147 | AddErrorMessage(msg); | |
1c66abf3 | 148 | fGlitchErrors++; |
149 | return kFALSE ; | |
150 | } | |
1ed3c5c2 | 151 | } |
152 | ||
84ceeb06 | 153 | indexDsp = index; |
154 | index += kDspHeaderSize; | |
1c66abf3 | 155 | |
84ceeb06 | 156 | // copy in TClonesArray |
157 | fDDLTracker->AddDspHeader(*fDspHeader, iBlock); | |
1c66abf3 | 158 | |
84ceeb06 | 159 | // buspatch structure |
160 | Int_t iBusPatch = 0; | |
161 | while (buffer[index] == fBusStruct->GetDefaultDataKey()) { | |
1c66abf3 | 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 | |
3fe5a267 | 188 | if(!CheckDataParity()) { |
1c66abf3 | 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++; | |
84ceeb06 | 206 | } // buspatch loop |
1c66abf3 | 207 | |
86400e61 | 208 | // skipping additionnal word if padding |
209 | if (fDspHeader->GetPaddingWord() == 1) { | |
1c66abf3 | 210 | if (buffer[index++] != fDspHeader->GetDefaultPaddingWord()) { |
211 | ||
3fe5a267 | 212 | Char_t *msg = Form("Padding word error for iBlock %d, iDsp %d, iBus %d\n", |
1c66abf3 | 213 | iBlock, iDsp, iBusPatch); |
214 | ||
3fe5a267 | 215 | if (fWarnings) AliWarning(msg); |
216 | AddErrorMessage(msg); | |
217 | fPaddingErrors++; | |
1c66abf3 | 218 | } |
86400e61 | 219 | } |
1c66abf3 | 220 | |
84ceeb06 | 221 | index = indexDsp + totalDspSize; |
222 | if (index >= totalDDLSize) { | |
1c66abf3 | 223 | index = totalDDLSize - 1; |
224 | break; | |
84ceeb06 | 225 | } |
226 | iDsp++; | |
227 | } // dsp loop | |
1c66abf3 | 228 | |
84ceeb06 | 229 | index = indexBlk + totalBlockSize; |
230 | if (index >= totalDDLSize) { | |
231 | index = totalDDLSize - 1; | |
232 | break; | |
233 | } | |
1c66abf3 | 234 | |
84ceeb06 | 235 | iBlock++; |
236 | } // block loop | |
1c66abf3 | 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 | ||
939ae4b2 | 248 | return kTRUE; |
249 | } | |
250 | ||
251 | //______________________________________________________ | |
252 | void AliMUONPayloadTracker::ResetDDL() | |
253 | { | |
71a2d3aa | 254 | /// reseting TClonesArray |
255 | /// after each DDL | |
256 | /// | |
939ae4b2 | 257 | fDDLTracker->GetBlkHeaderArray()->Delete(); |
3fe5a267 | 258 | fGlitchErrors = 0; |
ea59383d | 259 | fPaddingErrors = 0; |
3fe5a267 | 260 | fParityErrors = 0; |
1ed3c5c2 | 261 | |
939ae4b2 | 262 | } |
263 | ||
264 | //______________________________________________________ | |
265 | void AliMUONPayloadTracker::SetMaxBlock(Int_t blk) | |
266 | { | |
71a2d3aa | 267 | /// set regional card number |
939ae4b2 | 268 | if (blk > 2) blk = 2; |
269 | fMaxBlock = blk; | |
270 | } | |
607fb67b | 271 | |
6dee95a7 | 272 | //______________________________________________________ |
607fb67b | 273 | Bool_t AliMUONPayloadTracker::CheckDataParity() |
274 | { | |
71a2d3aa | 275 | /// parity check |
276 | /// taken from MuTrkBusPatch.cxx (sotfware test for CROCUS) | |
277 | /// A. Baldisseri | |
607fb67b | 278 | |
6dee95a7 | 279 | Int_t parity; |
607fb67b | 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); | |
607fb67b | 286 | |
6dee95a7 | 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); | |
607fb67b | 291 | |
292 | // Check | |
293 | if (parity != fBusStruct->GetParity(idata)) { | |
1ed3c5c2 | 294 | |
3fe5a267 | 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 | ||
607fb67b | 303 | return kFALSE; |
304 | ||
305 | } | |
306 | } | |
307 | return kTRUE; | |
308 | } | |
1ed3c5c2 | 309 | |
310 | //______________________________________________________ | |
3fe5a267 | 311 | void AliMUONPayloadTracker::AddErrorMessage(const Char_t* msg) |
1ed3c5c2 | 312 | { |
3fe5a267 | 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()); | |
1ed3c5c2 | 321 | } |
3fe5a267 | 322 | |
323 |