]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONPayloadTracker.cxx
8ad6519155703584f1dd1132d3ee5e28f22f87c2
[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 {
52   ///
53   /// create an object to decode MUON payload
54   ///
55
56 }
57
58 //___________________________________
59 AliMUONPayloadTracker::~AliMUONPayloadTracker()
60 {
61   ///
62   /// clean up
63   ///
64   delete fDDLTracker;
65   delete fBusStruct;
66   delete fBlockHeader;
67   delete fDspHeader;
68 }
69
70 //______________________________________________________
71 Bool_t AliMUONPayloadTracker::Decode(UInt_t* buffer, Int_t totalDDLSize)
72 {
73
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 !)
79
80
81   //Read Header Size of DDL,Block,DSP and BusPatch
82   static Int_t kBlockHeaderSize    = fBlockHeader->GetHeaderLength();
83   static Int_t kDspHeaderSize      = fDspHeader->GetHeaderLength();
84   static Int_t kBusPatchHeaderSize = fBusStruct->GetHeaderLength();
85
86   // size structures
87   Int_t totalBlockSize;
88   Int_t totalDspSize;
89   Int_t totalBusPatchSize;
90   Int_t dataSize; 
91   Int_t bufSize;
92
93   // indexes
94   Int_t indexBlk;
95   Int_t indexDsp;
96   Int_t indexBusPatch;
97   Int_t index = 0;
98   Int_t iBlock = 0;
99
100   // CROCUS CRT
101   while (buffer[index] == fBlockHeader->GetDefaultDataKey()) {
102
103     if (iBlock > fMaxBlock) break;
104      
105     // copy within padding words
106     memcpy(fBlockHeader->GetHeader(),&buffer[index], (kBlockHeaderSize)*4);
107
108     totalBlockSize = fBlockHeader->GetTotalLength();
109
110     indexBlk = index;
111     index += kBlockHeaderSize;
112
113     // copy in TClonesArray
114     fDDLTracker->AddBlkHeader(*fBlockHeader);
115
116     // Crocus FRT
117     Int_t iDsp = 0;
118     while (buffer[index] == fDspHeader->GetDefaultDataKey()) {
119
120       if (iDsp > fMaxDsp) break; // if ever...
121                 
122       memcpy(fDspHeader->GetHeader(),&buffer[index], kDspHeaderSize*4);
123
124       totalDspSize = fDspHeader->GetTotalLength();
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       
140       indexDsp = index;
141       index += kDspHeaderSize;
142
143       // copy in TClonesArray
144       fDDLTracker->AddDspHeader(*fDspHeader, iBlock);
145
146       // buspatch structure
147       Int_t iBusPatch = 0;
148       while (buffer[index] == fBusStruct->GetDefaultDataKey()) {
149
150         if (iBusPatch > fMaxBus) break; // if ever
151         
152         //copy buffer into header structure
153         memcpy(fBusStruct->GetHeader(), &buffer[index], kBusPatchHeaderSize*4);
154
155         totalBusPatchSize = fBusStruct->GetTotalLength();
156         indexBusPatch     = index;
157                 
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
174             // check parity
175             if(!CheckDataParity())
176                 AddParityErrBus(fBusStruct->GetBusPatchId());
177
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
192
193       // skipping additionnal word if padding
194       if (fDspHeader->GetPaddingWord() == 1) {
195         if (buffer[index++] != fDspHeader->GetDefaultPaddingWord())
196
197             AliWarning(Form("Error in padding word for iBlock %d, iDsp %d, iBus %d\n", 
198                           iBlock, iDsp, iBusPatch));
199
200         fPaddingErrors++;
201       }
202
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
218
219   return kTRUE;
220 }
221
222 //______________________________________________________
223 void AliMUONPayloadTracker::ResetDDL()
224 {
225   /// reseting TClonesArray
226   /// after each DDL
227   ///
228   fDDLTracker->GetBlkHeaderArray()->Delete();
229   fGlitchErrors = 0;
230   fPaddingErrors = 0;
231   fParityErrBus.Reset();
232
233 }
234
235 //______________________________________________________
236 void AliMUONPayloadTracker::SetMaxBlock(Int_t blk) 
237 {
238   /// set regional card number
239   if (blk > 2) blk = 2;
240   fMaxBlock = blk;
241 }
242
243 //______________________________________________________
244 Bool_t AliMUONPayloadTracker::CheckDataParity()
245 {
246   /// parity check
247   /// taken from MuTrkBusPatch.cxx (sotfware test for CROCUS)
248   /// A. Baldisseri
249
250   Int_t  parity;
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);
257
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);
262
263     // Check
264     if (parity != fBusStruct->GetParity(idata)) {
265
266       AliWarning(Form("Parity error in word %d for manuId %d and channel %d\n", 
267                       idata, fBusStruct->GetManuId(idata), fBusStruct->GetChannelId(idata)));
268
269       return kFALSE;
270                      
271     }
272   }
273   return kTRUE;
274 }
275
276 //______________________________________________________
277 void AliMUONPayloadTracker::AddParityErrBus(Int_t buspatch)
278 {
279 /// adding bus with at least on parity error
280     fParityErrBus.Set(fParityErrBus.GetSize() + 1);
281     fParityErrBus.AddAt(buspatch, fParityErrBus.GetSize() - 1);
282 }