]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONPayloadTracker.cxx
376ddfca8ad275ff8e1f5bfc8364231a0f4005fc
[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 ///////////////////////////////////////////////////////////////////////////////
18 ///
19 /// Class Payload
20 ///
21 /// Decodes rawdata from buffer and stores in TClonesArray.
22 /// 
23 /// First version implement for Tracker
24 ///
25 ///////////////////////////////////////////////////////////////////////////////
26
27 #include "AliMUONPayloadTracker.h"
28
29 #include "AliRawReader.h"
30 #include "AliRawDataHeader.h"
31 #include "AliLog.h"
32
33 #include "AliMUONDspHeader.h"
34 #include "AliMUONBlockHeader.h"
35 #include "AliMUONBusStruct.h"
36 #include "AliMUONDDLTracker.h"
37
38 ClassImp(AliMUONPayloadTracker)
39
40 AliMUONPayloadTracker::AliMUONPayloadTracker()
41   : TObject(),
42     fBusPatchId(0),
43     fDspId(0),
44     fBlkId(0),
45     fMaxDDL(20),
46     fMaxBlock(2),
47     fMaxDsp(5),
48     fMaxBus(5),
49     fDDLTracker(new AliMUONDDLTracker()),
50     fBusStruct(new AliMUONBusStruct()),
51     fBlockHeader(new AliMUONBlockHeader()),
52     fDspHeader(new AliMUONDspHeader())
53 {
54   //
55   // create an object to decode MUON payload
56   //
57
58 }
59
60 //___________________________________
61 AliMUONPayloadTracker::~AliMUONPayloadTracker()
62 {
63   //
64   // clean up
65   //
66   delete fDDLTracker;
67   delete fBusStruct;
68   delete fBlockHeader;
69   delete fDspHeader;
70 }
71
72 //______________________________________________________
73 Bool_t AliMUONPayloadTracker::Decode(UInt_t* buffer, Int_t totalDDLSize)
74 {
75
76   // Each DDL is made with 2 Blocks each of which consists of 5 DSP's at most 
77   // and each of DSP has at most 5 buspatches.
78   // The different structures, Block (CRT), DSP (FRT) and Buspatch,
79   // are identified by a key word 0xFC0000FC, 0xF000000F and 0xB000000B respectively.
80   // (fBusPatchManager no more needed !)
81
82
83   //Read Header Size of DDL,Block,DSP and BusPatch
84   static Int_t kBlockHeaderSize    = fBlockHeader->GetHeaderLength();
85   static Int_t kDspHeaderSize      = fDspHeader->GetHeaderLength();
86   static Int_t kBusPatchHeaderSize = fBusStruct->GetHeaderLength();
87
88   // size structures
89   Int_t totalBlockSize;
90   Int_t totalDspSize;
91   Int_t totalBusPatchSize;
92   Int_t dataSize; 
93   Int_t bufSize;
94
95   // indexes
96   Int_t indexBlk;
97   Int_t indexDsp;
98   Int_t indexBusPatch;
99   Int_t index = 0;
100   Int_t iBlock = 0;
101
102   // CROCUS CRT
103   while (buffer[index] == fBlockHeader->GetDefaultDataKey()) {
104
105     if (iBlock > fMaxBlock) break;
106      
107     // copy within padding words
108     memcpy(fBlockHeader->GetHeader(),&buffer[index], (kBlockHeaderSize)*4);
109
110     totalBlockSize = fBlockHeader->GetTotalLength();
111
112     indexBlk = index;
113     index += kBlockHeaderSize;
114
115     // copy in TClonesArray
116     fDDLTracker->AddBlkHeader(*fBlockHeader);
117
118     // Crocus FRT
119     Int_t iDsp = 0;
120     while (buffer[index] == fDspHeader->GetDefaultDataKey()) {
121
122       if (iDsp > fMaxDsp) break; // if ever...
123                 
124       memcpy(fDspHeader->GetHeader(),&buffer[index], kDspHeaderSize*4);
125
126       totalDspSize = fDspHeader->GetTotalLength();
127       indexDsp = index;
128       index += kDspHeaderSize;
129
130 //       if (fDspHeader->GetPaddingWord() != fDspHeader->GetDefaultPaddingWord()) {
131 //      // copy the field of Padding word into ErrorWord field
132 //      fDspHeader->SetErrorWord(fDspHeader->GetPaddingWord());
133 //      index--;
134 //       }
135
136       // copy in TClonesArray
137       fDDLTracker->AddDspHeader(*fDspHeader, iBlock);
138
139       // buspatch structure
140       Int_t iBusPatch = 0;
141       while (buffer[index] == fBusStruct->GetDefaultDataKey()) {
142
143         if (iBusPatch > fMaxBus) break; // if ever
144         
145         //copy buffer into header structure
146         memcpy(fBusStruct->GetHeader(), &buffer[index], kBusPatchHeaderSize*4);
147
148         totalBusPatchSize = fBusStruct->GetTotalLength();
149         indexBusPatch     = index;
150                 
151         //Check Buspatch header, not empty events
152         if(totalBusPatchSize > kBusPatchHeaderSize) {    
153
154           index   += kBusPatchHeaderSize;
155           dataSize = fBusStruct->GetLength();
156           bufSize  = fBusStruct->GetBufSize();
157
158           if(dataSize > 0) { // check data present
159             if (dataSize > bufSize) // check buffer size
160               fBusStruct->SetAlloc(dataSize);
161          
162             //copy buffer into data structure
163             memcpy(fBusStruct->GetData(), &buffer[index], dataSize*4);
164             fBusStruct->SetBlockId(iBlock); // could be usefull in future applications ?
165             fBusStruct->SetDspId(iDsp);
166
167             // check parity
168             CheckDataParity();
169
170             // copy in TClonesArray
171             fDDLTracker->AddBusPatch(*fBusStruct, iBlock, iDsp);
172
173           } // dataSize test
174
175         } // testing buspatch
176
177         index = indexBusPatch + totalBusPatchSize;
178         if (index >= totalDDLSize) {// check the end of DDL
179           index = totalDDLSize - 1; // point to the last element of buffer
180           break;
181         }
182         iBusPatch++;
183       }  // buspatch loop
184
185       // skipping additionnal word if padding
186       if (fDspHeader->GetPaddingWord() == 1) {
187         if (buffer[index++] != fDspHeader->GetDefaultPaddingWord())
188           AliWarning(Form("Error in padding word for iBlock %d, iDsp %d, iBus %d\n", 
189                           iBlock, iDsp, iBusPatch));
190       }
191
192       index = indexDsp + totalDspSize;
193       if (index >= totalDDLSize) {
194         index = totalDDLSize - 1;
195         break;
196       }
197       iDsp++;
198     }  // dsp loop
199
200     index = indexBlk + totalBlockSize;
201     if (index >= totalDDLSize) {
202       index = totalDDLSize - 1;
203       break;
204     }
205     iBlock++;
206   }  // block loop
207
208   return kTRUE;
209 }
210
211 //______________________________________________________
212 void AliMUONPayloadTracker::ResetDDL()
213 {
214   // reseting TClonesArray
215   // after each DDL
216   //
217   fDDLTracker->GetBlkHeaderArray()->Delete();
218 }
219
220 //______________________________________________________
221 void AliMUONPayloadTracker::SetMaxBlock(Int_t blk) 
222 {
223   // set regional card number
224   if (blk > 2) blk = 2;
225   fMaxBlock = blk;
226 }
227
228 //______________________________________________________
229 Bool_t AliMUONPayloadTracker::CheckDataParity()
230 {
231   // parity check
232   // taken from MuTrkBusPatch.cxx (sotfware test for CROCUS)
233   // A. Baldisseri
234
235   Int_t  parity;
236   UInt_t data;
237   
238   Int_t dataSize = fBusStruct->GetLength();
239   for (int idata = 0; idata < dataSize; idata++) {
240
241     data  = fBusStruct->GetData(idata);
242
243     // Compute the parity for each data word
244     parity  = data & 0x1;
245     for (Int_t i = 1; i <= 30; i++) 
246       parity ^= ((data >> i) & 0x1);
247
248     // Check
249     if (parity != fBusStruct->GetParity(idata)) {
250       AliWarning(Form("Parity error in word %d for manuId %d and channel %d\n", 
251                       idata, fBusStruct->GetManuId(idata), fBusStruct->GetChannelId(idata)));
252       return kFALSE;
253                      
254     }
255   }
256   return kTRUE;
257 }