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