]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONPayloadTracker.cxx
Add Config/HighVoltage directory and entry
[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
194             // copy in TClonesArray
195             fDDLTracker->AddBusPatch(*fBusStruct, iBlock, iDsp);
196
197           } // dataSize test
198
199         } // testing buspatch
200
201         index = indexBusPatch + totalBusPatchSize;
202         if (index >= totalDDLSize) {// check the end of DDL
203           index = totalDDLSize - 1; // point to the last element of buffer
204           break;
205         }
206         iBusPatch++;
207       }  // buspatch loop
208
209       // skipping additionnal word if padding
210       if (fDspHeader->GetPaddingWord() == 1) {
211         if (buffer[index++] != fDspHeader->GetDefaultPaddingWord()) {
212
213           Char_t *msg = Form("Padding word error for iBlock %d, iDsp %d, iBus %d\n", 
214                       iBlock, iDsp, iBusPatch);
215         
216           if (fWarnings) AliWarning(msg);
217           AddErrorMessage(msg);
218           fPaddingErrors++;
219         }
220       }
221
222       index = indexDsp + totalDspSize;
223       if (index >= totalDDLSize) {
224         index = totalDDLSize - 1;
225         break;
226       }
227       iDsp++;
228     }  // dsp loop
229
230     index = indexBlk + totalBlockSize;
231     if (index >= totalDDLSize) {
232       index = totalDDLSize - 1;
233       break;
234     }
235     iBlock++;
236   }  // block loop
237
238   return kTRUE;
239 }
240
241 //______________________________________________________
242 void AliMUONPayloadTracker::ResetDDL()
243 {
244   /// reseting TClonesArray
245   /// after each DDL
246   ///
247   fDDLTracker->GetBlkHeaderArray()->Delete();
248   fGlitchErrors  = 0;
249   fPaddingErrors = 0;
250   fParityErrors  = 0;
251
252 }
253
254 //______________________________________________________
255 void AliMUONPayloadTracker::SetMaxBlock(Int_t blk) 
256 {
257   /// set regional card number
258   if (blk > 2) blk = 2;
259   fMaxBlock = blk;
260 }
261
262 //______________________________________________________
263 Bool_t AliMUONPayloadTracker::CheckDataParity()
264 {
265   /// parity check
266   /// taken from MuTrkBusPatch.cxx (sotfware test for CROCUS)
267   /// A. Baldisseri
268
269   Int_t  parity;
270   UInt_t data;
271   
272   Int_t dataSize = fBusStruct->GetLength();
273   for (int idata = 0; idata < dataSize; idata++) {
274
275     data  = fBusStruct->GetData(idata);
276
277     // Compute the parity for each data word
278     parity  = data & 0x1;
279     for (Int_t i = 1; i <= 30; i++) 
280       parity ^= ((data >> i) & 0x1);
281
282     // Check
283     if (parity != fBusStruct->GetParity(idata)) {
284
285       Char_t* msg = Form("Parity error in word %d for manuId %d and channel %d in buspatch %d\n", 
286                           idata, fBusStruct->GetManuId(idata), fBusStruct->GetChannelId(idata),
287                           fBusStruct->GetBusPatchId());
288       
289       if (fWarnings) AliWarning(msg);
290       AddErrorMessage(msg);
291       fParityErrors++;
292       
293       return kFALSE;
294                      
295     }
296   }
297   return kTRUE;
298 }
299
300 //______________________________________________________
301 void AliMUONPayloadTracker::AddErrorMessage(const Char_t* msg)
302 {
303 /// adding message to logger
304  
305     TString tmp(msg);
306   
307     Int_t pos = tmp.First("\n");
308     tmp[pos] = 0;
309     
310     fLog->Log(tmp.Data());
311 }
312
313