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