]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONPayloadTracker.cxx
Better selection between menus
[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             AliError(Form("Error in padding word for iBlock %d, iDsp %d, iBus %d\n", 
198                           iBlock, iDsp, iBusPatch));
199
200       }
201
202       index = indexDsp + totalDspSize;
203       if (index >= totalDDLSize) {
204         index = totalDDLSize - 1;
205         break;
206       }
207       iDsp++;
208     }  // dsp loop
209
210     index = indexBlk + totalBlockSize;
211     if (index >= totalDDLSize) {
212       index = totalDDLSize - 1;
213       break;
214     }
215     iBlock++;
216   }  // block loop
217
218   return kTRUE;
219 }
220
221 //______________________________________________________
222 void AliMUONPayloadTracker::ResetDDL()
223 {
224   /// reseting TClonesArray
225   /// after each DDL
226   ///
227   fDDLTracker->GetBlkHeaderArray()->Delete();
228   fGlitchErrors = 0;
229   fParityErrBus.Reset();
230
231 }
232
233 //______________________________________________________
234 void AliMUONPayloadTracker::SetMaxBlock(Int_t blk) 
235 {
236   /// set regional card number
237   if (blk > 2) blk = 2;
238   fMaxBlock = blk;
239 }
240
241 //______________________________________________________
242 Bool_t AliMUONPayloadTracker::CheckDataParity()
243 {
244   /// parity check
245   /// taken from MuTrkBusPatch.cxx (sotfware test for CROCUS)
246   /// A. Baldisseri
247
248   Int_t  parity;
249   UInt_t data;
250   
251   Int_t dataSize = fBusStruct->GetLength();
252   for (int idata = 0; idata < dataSize; idata++) {
253
254     data  = fBusStruct->GetData(idata);
255
256     // Compute the parity for each data word
257     parity  = data & 0x1;
258     for (Int_t i = 1; i <= 30; i++) 
259       parity ^= ((data >> i) & 0x1);
260
261     // Check
262     if (parity != fBusStruct->GetParity(idata)) {
263
264       AliWarning(Form("Parity error in word %d for manuId %d and channel %d\n", 
265                       idata, fBusStruct->GetManuId(idata), fBusStruct->GetChannelId(idata)));
266
267       return kFALSE;
268                      
269     }
270   }
271   return kTRUE;
272 }
273
274 //______________________________________________________
275 void AliMUONPayloadTracker::AddParityErrBus(Int_t buspatch)
276 {
277 /// adding bus with at least on parity error
278     fParityErrBus.Set(fParityErrBus.GetSize() + 1);
279     fParityErrBus.AddAt(buspatch, fParityErrBus.GetSize() - 1);
280 }