parity bit is introduced
[u/mrichter/AliRoot.git] / PMD / AliPMDRawStream.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 ///
20 /// This class provides access to PMD digits in raw data.
21 ///
22 /// It loops over all PMD digits in the raw data given by the AliRawReader.
23 /// The Next method goes to the next digit. If there are no digits left
24 /// it returns kFALSE.
25 /// Several getters provide information about the current digit.
26 ///
27 ///////////////////////////////////////////////////////////////////////////////
28
29 #include <Riostream.h>
30 #include <TObjArray.h>
31 #include <TString.h>
32 #include <TSystem.h>
33
34 #include "AliLog.h"
35 #include "AliPMDBlockHeader.h"
36 #include "AliPMDDspHeader.h"
37 #include "AliPMDPatchBusHeader.h"
38 #include "AliPMDddldata.h"
39 #include "AliPMDRawStream.h"
40 #include "AliRawReader.h"
41
42 ClassImp(AliPMDRawStream)
43
44
45 //_____________________________________________________________________________
46 AliPMDRawStream::AliPMDRawStream(AliRawReader* rawReader) :
47   fRawReader(rawReader)
48 {
49 // create an object to read PMD raw digits
50
51   fRawReader->Select("PMD");
52 }
53
54 //_____________________________________________________________________________
55 AliPMDRawStream::AliPMDRawStream(const AliPMDRawStream& stream) :
56   TObject(stream),
57   fRawReader(NULL)
58 {
59 // copy constructor
60
61   AliFatal("Copy constructor not implemented");
62 }
63
64 //_____________________________________________________________________________
65 AliPMDRawStream& AliPMDRawStream::operator = (const AliPMDRawStream& 
66                                               /* stream */)
67 {
68 // assignment operator
69
70   AliFatal("operator = assignment operator not implemented");
71   return *this;
72 }
73
74 //_____________________________________________________________________________
75 AliPMDRawStream::~AliPMDRawStream()
76 {
77 // destructor
78
79 }
80
81
82 //_____________________________________________________________________________
83
84 Bool_t AliPMDRawStream::DdlData(Int_t indexDDL, TObjArray *pmdddlcont)
85 {
86 // read the next raw digit
87 // returns kFALSE if there is no digit left
88
89   AliPMDddldata *pmdddldata;
90
91   if (!fRawReader->ReadHeader()) return kFALSE;
92   Int_t  iddl  = fRawReader->GetDDLID();
93   Int_t dataSize = fRawReader->GetDataSize();
94   Int_t totaldataword = dataSize/4;
95
96   if (dataSize <= 0) return kFALSE;
97   if (indexDDL != iddl)
98     {
99       AliError("Mismatch in the DDL index");
100       return kFALSE;
101     }
102
103   UInt_t *buffer;
104   buffer = new UInt_t[totaldataword];
105   UInt_t data;
106   for (Int_t i = 0; i < totaldataword; i++)
107     {
108       fRawReader->ReadNextInt(data);
109       buffer[i] = data;
110     }
111
112   // --- Open the mapping file
113
114   TString fileName(gSystem->Getenv("ALICE_ROOT"));
115   if(iddl == 0)
116     {
117       fileName += "/PMD/PMD_Mapping_ddl0.dat";
118     }
119   else if(iddl == 1)
120     {
121       fileName += "/PMD/PMD_Mapping_ddl1.dat";
122     }
123   else if(iddl == 2)
124     {
125       fileName += "/PMD/PMD_Mapping_ddl2.dat";
126     }
127   else if(iddl == 3)
128     {
129       fileName += "/PMD/PMD_Mapping_ddl3.dat";
130     }
131   else if(iddl == 4)
132     {
133       fileName += "/PMD/PMD_Mapping_ddl4.dat";
134     }
135   else if(iddl == 5)
136     {
137       fileName += "/PMD/PMD_Mapping_ddl5.dat";
138     }
139
140   ifstream infile;
141   infile.open(fileName.Data(), ios::in); // ascii file
142   if(!infile)
143     AliError(Form("Could not read the mapping file for DDL No = %d",iddl));
144   
145   Int_t modulePerDDL = 0;
146   if (iddl < 4)
147     {
148       modulePerDDL = 6;
149     }
150   else if (iddl == 4 || iddl == 5)
151     {
152       modulePerDDL = 12;
153     }
154
155   const Int_t kNPatchBus = 50;
156   
157   Int_t modno, totPatchBus, bPatchBus, ePatchBus;
158   Int_t ibus, totmcm, rows, rowe, cols, cole;
159   Int_t moduleNo[kNPatchBus], mcmperBus[kNPatchBus];
160   Int_t startRowBus[kNPatchBus], endRowBus[kNPatchBus];
161   Int_t startColBus[kNPatchBus], endColBus[kNPatchBus];
162
163
164   for (Int_t ibus = 0; ibus < kNPatchBus; ibus++)
165     {
166       mcmperBus[ibus]   = -1;
167       startRowBus[ibus] = -1;
168       endRowBus[ibus]   = -1;
169       startColBus[ibus] = -1;
170       endColBus[ibus]   = -1;
171     }
172
173
174   for (Int_t im = 0; im < modulePerDDL; im++)
175     {
176       infile >> modno;
177       infile >> totPatchBus >> bPatchBus >> ePatchBus;
178       
179       for(Int_t i=0; i<totPatchBus; i++)
180         {
181           infile >> ibus >> totmcm >> rows >> rowe >> cols >> cole;
182
183           moduleNo[ibus]     = modno;
184           mcmperBus[ibus]    = totmcm;
185           startRowBus[ibus]  = rows;
186           endRowBus[ibus]    = rowe;
187           startColBus[ibus]  = cols;
188           endColBus[ibus]    = cole;
189         }
190     }
191
192
193
194   infile.close();
195
196
197   AliPMDBlockHeader    blockHeader;
198   AliPMDDspHeader      dspHeader;
199   AliPMDPatchBusHeader pbusHeader;
200
201   const Int_t kblHLen   = blockHeader.GetHeaderLength();
202   const Int_t kdspHLen  = dspHeader.GetHeaderLength();
203   const Int_t kpbusHLen = pbusHeader.GetHeaderLength();
204   
205   Int_t parity;
206   Int_t idet, ismn;
207   Int_t irow = -1;
208   Int_t icol = -1;
209
210   Int_t blHeaderWord[8];
211   Int_t dspHeaderWord[10];
212   Int_t pbusHeaderWord[4];
213
214   Int_t ilowLimit = 0;
215   Int_t iuppLimit = 0;
216
217   Int_t blRawDataLength = 0;
218   Int_t iwordcount = 0;
219
220
221   for (Int_t iblock = 0; iblock < 2; iblock++)
222     {
223       ilowLimit = iuppLimit;
224       iuppLimit = ilowLimit + kblHLen;
225
226
227       for (Int_t i = ilowLimit; i < iuppLimit; i++)
228         {
229           blHeaderWord[i-ilowLimit] = (Int_t) buffer[i];
230         }
231
232       blockHeader.SetHeader(blHeaderWord);
233
234       blRawDataLength = blockHeader.GetRawDataLength();
235
236       for (Int_t idsp = 0; idsp < 5; idsp++)
237         {
238           ilowLimit = iuppLimit;
239           iuppLimit = ilowLimit + kdspHLen;
240
241           for (Int_t i = ilowLimit; i < iuppLimit; i++)
242             {
243               iwordcount++;
244               dspHeaderWord[i-ilowLimit] = (Int_t) buffer[i];
245             }
246           dspHeader.SetHeader(dspHeaderWord);
247
248           for (Int_t ibus = 0; ibus < 5; ibus++)
249             {
250
251               ilowLimit = iuppLimit;
252               iuppLimit = ilowLimit + kpbusHLen;
253
254               for (Int_t i = ilowLimit; i < iuppLimit; i++)
255                 {
256                   iwordcount++;
257                   pbusHeaderWord[i-ilowLimit] = (Int_t) buffer[i];
258                 }
259               pbusHeader.SetHeader(pbusHeaderWord);
260               Int_t rawdatalength = pbusHeader.GetRawDataLength();
261               Int_t pbusid = pbusHeader.GetPatchBusId();
262
263               ilowLimit = iuppLimit;
264               iuppLimit = ilowLimit + rawdatalength;
265
266               Int_t imodule = moduleNo[pbusid];
267
268
269               for (Int_t iword = ilowLimit; iword < iuppLimit; iword++)
270                 {
271                   iwordcount++;
272                   data = buffer[iword];
273
274                   Int_t isig =  data & 0x0FFF;
275                   Int_t ich  = (data >> 12) & 0x003F;
276                   Int_t imcm = (data >> 18) & 0x07FF;
277                   Int_t ibit = (data >> 31) & 0x0001;
278
279                   parity = ComputeParity(data);
280                   if (ibit != parity)
281                     {
282                       AliWarning("ComputeParity:: Parity Error");
283                     }
284                   GetRowCol(iddl, pbusid, imcm, ich, 
285                             startRowBus, endRowBus,
286                             startColBus, endColBus,
287                             irow, icol);
288
289                   ConvertDDL2SMN(iddl, imodule, ismn, idet);
290                   TransformH2S(ismn, irow, icol);
291
292                   pmdddldata = new AliPMDddldata();
293
294                   pmdddldata->SetDetector(idet);
295                   pmdddldata->SetSMN(ismn);
296                   pmdddldata->SetModule(imodule);
297                   pmdddldata->SetPatchBusId(pbusid);
298                   pmdddldata->SetMCM(imcm);
299                   pmdddldata->SetChannel(ich);
300                   pmdddldata->SetRow(irow);
301                   pmdddldata->SetColumn(icol);
302                   pmdddldata->SetSignal(isig);
303                   pmdddldata->SetParityBit(ibit);
304                   
305                   pmdddlcont->Add(pmdddldata);
306                   
307                 } // data word loop
308
309               if (iwordcount == blRawDataLength) break;
310
311             } // patch bus loop
312
313           if (dspHeader.GetPaddingWord() == 1) iuppLimit++;
314           if (iwordcount == blRawDataLength) break;
315
316         } // end of DSP
317       if (iwordcount == blRawDataLength) break;
318
319     } // end of BLOCK
320
321   
322   delete [] buffer;
323
324   return kTRUE;
325 }
326 //_____________________________________________________________________________
327 void AliPMDRawStream::GetRowCol(Int_t ddlno, Int_t pbusid,
328                                 UInt_t mcmno, UInt_t chno,
329                                 Int_t startRowBus[], Int_t endRowBus[],
330                                 Int_t startColBus[], Int_t endColBus[],
331                                 Int_t &row, Int_t &col) const
332 {
333 // decode: ddlno, patchbusid, mcmno, chno -> um, row, col
334
335
336   static const UInt_t kCh[64] = { 53, 58, 57, 54, 61, 62, 60, 63,
337                                   49, 59, 56, 55, 52, 50, 48, 51,
338                                   44, 47, 45, 43, 40, 39, 36, 46,
339                                   32, 35, 33, 34, 41, 38, 37, 42,
340                                   21, 26, 25, 22, 29, 30, 28, 31,
341                                   17, 27, 24, 23, 20, 18, 16, 19,
342                                   12, 15, 13, 11,  8,  7,  4, 14,
343                                   0,   3,  1,  2,  9,  6,  5, 10 };
344
345
346   Int_t rowcol  = kCh[chno];
347   Int_t irownew = rowcol/4;
348   Int_t icolnew = rowcol%4;
349
350   if (ddlno == 0)
351     {
352       if (pbusid  <= 2)
353         {
354           if (mcmno >= 12)
355             {
356               row = startRowBus[pbusid] + irownew;
357               col = startColBus[pbusid] + (mcmno-12)*4 + icolnew;
358             }
359           else
360             {
361               // Add 16 to skip the 1st 15 rows
362               row = startRowBus[pbusid] + irownew + 16;
363               col = startColBus[pbusid] + mcmno*4 + icolnew;
364             }
365         }
366       else if (pbusid > 2)
367         {
368           row = startRowBus[pbusid] + irownew;
369           col = startColBus[pbusid] + mcmno*4 + icolnew;
370           
371         }
372     }
373   else if (ddlno == 1)
374     {
375       if (pbusid  <= 2)
376         {
377           if (mcmno >= 12)
378             {
379               row = endRowBus[pbusid] - (15 - irownew);
380               col = startColBus[pbusid] + (mcmno-12)*4 + icolnew;
381             }
382           else
383             {
384               // Subtract 16 to skip the 1st 15 rows
385               row = endRowBus[pbusid] - 16 - (15 - irownew) ;
386               col = startColBus[pbusid] + mcmno*4 + icolnew;
387             }
388         }
389       else if (pbusid > 2)
390         {
391           row = endRowBus[pbusid] - (15 - irownew);
392           col = startColBus[pbusid] + mcmno*4 + icolnew;
393         }
394     }
395   else if (ddlno == 2)
396     {
397       row = startRowBus[pbusid] + irownew;
398       col = endColBus[pbusid] - mcmno*4 - (3 - icolnew);
399     }
400   else if (ddlno == 3)
401     {
402       row = endRowBus[pbusid] - (15 - irownew);
403       col = endColBus[pbusid] - mcmno*4 - (3 - icolnew);
404     }
405   else if (ddlno == 4)
406     {
407       if (pbusid  <= 16)
408         {
409           if (mcmno >= 12)
410             {
411               row = startRowBus[pbusid] + irownew;
412               col = startColBus[pbusid] + (mcmno-12)*4 + icolnew;
413             }
414           else
415             {
416               // Add 16 to skip the 1st 15 rows
417               row = startRowBus[pbusid] + irownew + 16;
418               col = startColBus[pbusid] + mcmno*4 + icolnew;
419             }
420         }
421       else if (pbusid > 16 && pbusid <= 20)
422         {
423           row = startRowBus[pbusid] + irownew;
424           col = startColBus[pbusid] + mcmno*4 + icolnew;
425           
426         }
427       else if(pbusid > 20)
428         {
429           row = endRowBus[pbusid] - (15 - irownew);
430           col = endColBus[pbusid] - mcmno*4 - (3 - icolnew);
431         }
432     }
433   else if (ddlno == 5)
434     {
435       if (pbusid  <= 16)
436         {
437           if (mcmno >= 12)
438             {
439               row = endRowBus[pbusid] - (15 - irownew);
440               col = startColBus[pbusid] + (mcmno-12)*4 + icolnew;
441             }
442           else
443             {
444               // Subtract 16 to skip the 1st 15 rows
445               row = endRowBus[pbusid] - 16 - (15 - irownew) ;
446               col = startColBus[pbusid] + mcmno*4 + icolnew;
447             }
448         }
449       else if (pbusid > 16 && pbusid <= 20)
450         {
451           row = endRowBus[pbusid] - (15 - irownew);
452           col = startColBus[pbusid] + mcmno*4 + icolnew;
453         }
454       else if (pbusid > 20)
455         {
456           row = startRowBus[pbusid] + irownew;
457           col = endColBus[pbusid] - mcmno*4 - (3 - icolnew);
458         }
459     }
460 }
461 //_____________________________________________________________________________
462 void AliPMDRawStream::ConvertDDL2SMN(Int_t iddl, Int_t imodule,
463                                      Int_t &smn, Int_t &detector) const
464 {
465   // This converts the DDL number (0 to 5), Module Number (0-47)
466   // to Serial module number in one detector (SMN : 0-23) and
467   // detector number (0:PRE plane, 1:CPV plane)
468   if (iddl < 4)
469     {
470       smn = imodule;
471       detector = 0;
472     }
473   else
474     {
475       smn = imodule - 24;
476       detector = 1;
477     }
478 }
479 //_____________________________________________________________________________
480 void AliPMDRawStream::TransformH2S(Int_t smn, Int_t &row, Int_t &col) const
481 {
482   // This does the transformation of the hardware coordinate to
483   // software 
484   // i.e., For SuperModule 0 &1, instead of 96x48(hardware),
485   // it is 48x96 (software)
486   // For Supermodule 3 & 4, 48x96
487
488   Int_t irownew  = 0;
489   Int_t icolnew  = 0;
490
491   if(smn < 12)
492     {
493       irownew = col;
494       icolnew = row;
495     }
496   else if(smn >= 12 && smn < 24)
497     {
498       irownew = row;
499       icolnew = col;
500     }
501
502   row = irownew;
503   col = icolnew;
504 }
505
506 //_____________________________________________________________________________
507
508 int AliPMDRawStream::ComputeParity(Int_t data)
509 {
510 // Calculate the parity bit
511
512   Int_t count = 0;
513   for(Int_t j = 0; j<29; j++)
514     {
515       if (data & 0x01 ) count++;
516       data >>= 1;
517     }
518   
519   Int_t parity = count%2;
520
521   return parity;
522 }
523
524 //_____________________________________________________________________________