]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONPayloadTracker.cxx
Fixing bug in the position of the central slats of station 4 and 5 (Javier, Alberto)
[u/mrichter/AliRoot.git] / MUON / AliMUONPayloadTracker.cxx
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 ///
17 /// \class AliMUONPayloadTracker
18 /// Decodes rawdata from buffer and stores in TClonesArray.
19 /// First version implement for Tracker
20 ///
21 /// \author Christian Finck
22
23 #include "AliMUONPayloadTracker.h"
24
25 #include "AliMUONDspHeader.h"
26 #include "AliMUONBlockHeader.h"
27 #include "AliMUONBusStruct.h"
28 #include "AliMUONDDLTracker.h"
29
30 #include "AliLog.h"
31
32 /// \cond CLASSIMP
33 ClassImp(AliMUONPayloadTracker)
34 /// \endcond
35
36 AliMUONPayloadTracker::AliMUONPayloadTracker()
37   : TObject(),
38     fBusPatchId(0),
39     fDspId(0),
40     fBlkId(0),
41     fMaxDDL(20),
42     fMaxBlock(2),
43     fMaxDsp(5),
44     fMaxBus(5),
45     fDDLTracker(new AliMUONDDLTracker()),
46     fBusStruct(new AliMUONBusStruct()),
47     fBlockHeader(new AliMUONBlockHeader()),
48     fDspHeader(new AliMUONDspHeader()),
49     fParityErrBus(),
50     fGlitchErrors(0),
51     fPaddingErrors(0)
52 {
53   ///
54   /// create an object to decode MUON payload
55   ///
56
57 }
58
59 //___________________________________
60 AliMUONPayloadTracker::~AliMUONPayloadTracker()
61 {
62   ///
63   /// clean up
64   ///
65   delete fDDLTracker;
66   delete fBusStruct;
67   delete fBlockHeader;
68   delete fDspHeader;
69 }
70
71 //______________________________________________________
72 Bool_t AliMUONPayloadTracker::Decode(UInt_t* buffer, Int_t totalDDLSize)
73 {
74
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 !)
80
81
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();
86
87   // size structures
88   Int_t totalBlockSize;
89   Int_t totalDspSize;
90   Int_t totalBusPatchSize;
91   Int_t dataSize; 
92   Int_t bufSize;
93
94   // indexes
95   Int_t indexBlk;
96   Int_t indexDsp;
97   Int_t indexBusPatch;
98   Int_t index = 0;
99   Int_t iBlock = 0;
100
101   // CROCUS CRT
102   while (buffer[index] == fBlockHeader->GetDefaultDataKey()) {
103
104     if (iBlock > fMaxBlock) break;
105      
106     // copy within padding words
107     memcpy(fBlockHeader->GetHeader(),&buffer[index], (kBlockHeaderSize)*4);
108
109     totalBlockSize = fBlockHeader->GetTotalLength();
110
111     indexBlk = index;
112     index += kBlockHeaderSize;
113
114     // copy in TClonesArray
115     fDDLTracker->AddBlkHeader(*fBlockHeader);
116
117     // Crocus FRT
118     Int_t iDsp = 0;
119     while (buffer[index] == fDspHeader->GetDefaultDataKey()) {
120
121       if (iDsp > fMaxDsp) break; // if ever...
122                 
123       memcpy(fDspHeader->GetHeader(),&buffer[index], kDspHeaderSize*4);
124
125       totalDspSize = fDspHeader->GetTotalLength();
126
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 
134
135           AliWarning(Form("Glitch in data detected, skipping event ")); 
136
137           fGlitchErrors++;
138           return kFALSE ; 
139         }       
140       }
141       
142       indexDsp = index;
143       index += kDspHeaderSize;
144
145       // copy in TClonesArray
146       fDDLTracker->AddDspHeader(*fDspHeader, iBlock);
147
148       // buspatch structure
149       Int_t iBusPatch = 0;
150       while (buffer[index] == fBusStruct->GetDefaultDataKey()) {
151
152         if (iBusPatch > fMaxBus) break; // if ever
153         
154         //copy buffer into header structure
155         memcpy(fBusStruct->GetHeader(), &buffer[index], kBusPatchHeaderSize*4);
156
157         totalBusPatchSize = fBusStruct->GetTotalLength();
158         indexBusPatch     = index;
159                 
160         //Check Buspatch header, not empty events
161         if(totalBusPatchSize > kBusPatchHeaderSize) {    
162
163           index   += kBusPatchHeaderSize;
164           dataSize = fBusStruct->GetLength();
165           bufSize  = fBusStruct->GetBufSize();
166
167           if(dataSize > 0) { // check data present
168             if (dataSize > bufSize) // check buffer size
169               fBusStruct->SetAlloc(dataSize);
170          
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);
175
176             // check parity
177             if(!CheckDataParity())
178                 AddParityErrBus(fBusStruct->GetBusPatchId());
179
180             // copy in TClonesArray
181             fDDLTracker->AddBusPatch(*fBusStruct, iBlock, iDsp);
182
183           } // dataSize test
184
185         } // testing buspatch
186
187         index = indexBusPatch + totalBusPatchSize;
188         if (index >= totalDDLSize) {// check the end of DDL
189           index = totalDDLSize - 1; // point to the last element of buffer
190           break;
191         }
192         iBusPatch++;
193       }  // buspatch loop
194
195       // skipping additionnal word if padding
196       if (fDspHeader->GetPaddingWord() == 1) {
197         if (buffer[index++] != fDspHeader->GetDefaultPaddingWord())
198
199             AliWarning(Form("Error in padding word for iBlock %d, iDsp %d, iBus %d\n", 
200                           iBlock, iDsp, iBusPatch));
201
202         fPaddingErrors++;
203       }
204
205       index = indexDsp + totalDspSize;
206       if (index >= totalDDLSize) {
207         index = totalDDLSize - 1;
208         break;
209       }
210       iDsp++;
211     }  // dsp loop
212
213     index = indexBlk + totalBlockSize;
214     if (index >= totalDDLSize) {
215       index = totalDDLSize - 1;
216       break;
217     }
218     iBlock++;
219   }  // block loop
220
221   return kTRUE;
222 }
223
224 //______________________________________________________
225 void AliMUONPayloadTracker::ResetDDL()
226 {
227   /// reseting TClonesArray
228   /// after each DDL
229   ///
230   fDDLTracker->GetBlkHeaderArray()->Delete();
231   fGlitchErrors = 0;
232   fPaddingErrors = 0;
233   fParityErrBus.Reset();
234
235 }
236
237 //______________________________________________________
238 void AliMUONPayloadTracker::SetMaxBlock(Int_t blk) 
239 {
240   /// set regional card number
241   if (blk > 2) blk = 2;
242   fMaxBlock = blk;
243 }
244
245 //______________________________________________________
246 Bool_t AliMUONPayloadTracker::CheckDataParity()
247 {
248   /// parity check
249   /// taken from MuTrkBusPatch.cxx (sotfware test for CROCUS)
250   /// A. Baldisseri
251
252   Int_t  parity;
253   UInt_t data;
254   
255   Int_t dataSize = fBusStruct->GetLength();
256   for (int idata = 0; idata < dataSize; idata++) {
257
258     data  = fBusStruct->GetData(idata);
259
260     // Compute the parity for each data word
261     parity  = data & 0x1;
262     for (Int_t i = 1; i <= 30; i++) 
263       parity ^= ((data >> i) & 0x1);
264
265     // Check
266     if (parity != fBusStruct->GetParity(idata)) {
267
268       AliWarning(Form("Parity error in word %d for manuId %d and channel %d\n", 
269                       idata, fBusStruct->GetManuId(idata), fBusStruct->GetChannelId(idata)));
270
271       return kFALSE;
272                      
273     }
274   }
275   return kTRUE;
276 }
277
278 //______________________________________________________
279 void AliMUONPayloadTracker::AddParityErrBus(Int_t buspatch)
280 {
281 /// adding bus with at least on parity error
282     fParityErrBus.Set(fParityErrBus.GetSize() + 1);
283     fParityErrBus.AddAt(buspatch, fParityErrBus.GetSize() - 1);
284 }