]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PMD/AliPMDDDLRawData.cxx
added some more summed histograms in the HistogramHandlerComponent; cleanup in the...
[u/mrichter/AliRoot.git] / PMD / AliPMDDDLRawData.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 #include <Riostream.h>
17 #include <TClonesArray.h>
18 #include <TTree.h>
19 #include <TBranch.h>
20 #include <TMath.h>
21 #include <TString.h>
22 #include <TSystem.h>
23
24 #include "AliLog.h"
25 #include "AliRawDataHeaderSim.h"
26 #include "AliBitPacking.h"
27 #include "AliPMDdigit.h"
28 #include "AliPMDBlockHeader.h"
29 #include "AliPMDDspHeader.h"
30 #include "AliPMDPatchBusHeader.h"
31 #include "AliPMDRawStream.h"
32 #include "AliPMDDDLRawData.h"
33 #include "AliDAQ.h"
34 #include "AliFstream.h"
35
36 ClassImp(AliPMDDDLRawData)
37
38 AliPMDDDLRawData::AliPMDDDLRawData():
39   fDigits(new TClonesArray("AliPMDdigit", 1000))
40 {
41   // Default Constructor
42   //
43
44 }
45 //____________________________________________________________________________
46 AliPMDDDLRawData::AliPMDDDLRawData(const AliPMDDDLRawData& ddlraw):
47   TObject(ddlraw),
48   fDigits(ddlraw.fDigits)
49 {
50   //Copy Constructor 
51 }
52 //____________________________________________________________________________
53 AliPMDDDLRawData & AliPMDDDLRawData::operator=(const AliPMDDDLRawData& ddlraw)
54 {
55   //Assignment operator 
56   if(this != &ddlraw)
57     {
58       fDigits = ddlraw.fDigits;
59     }
60   return *this;
61 }
62 //____________________________________________________________________________
63
64 AliPMDDDLRawData::~AliPMDDDLRawData()
65 {
66   // Default Destructor
67   //
68
69 }
70
71 //____________________________________________________________________________
72 void AliPMDDDLRawData::WritePMDRawData(TTree *treeD)
73 {
74   // write digits into raw data format
75
76   AliFstream *outfile;
77
78   TBranch *branch = treeD->GetBranch("PMDDigit");
79   if (!branch)
80     {
81       AliError("PMD Digit branch not found");
82       return;
83     }
84   branch->SetAddress(&fDigits);  
85   
86   Int_t   nmodules = (Int_t) treeD->GetEntries();
87   AliDebug(1,Form("Number of modules inside treeD = %d",nmodules));
88
89   const Int_t kDDL          = AliDAQ::NumberOfDdls("PMD");
90   Int_t modulePerDDL        = 0;
91
92
93   AliRawDataHeaderSim header;
94   UInt_t sizeRawData = 0;
95   
96   const Int_t kbusSize = 51;
97   const Int_t kSize = 1536;
98   UInt_t buffer[kSize];
99
100   UInt_t busPatch[kbusSize][1536];
101
102   Int_t contentsBus[kbusSize];
103
104   Char_t filename[80];
105
106
107   Int_t mmodule = 0;
108   for(Int_t iddl = 0; iddl < kDDL; iddl++)
109     {
110       strcpy(filename,AliDAQ::DdlFileName("PMD",iddl));
111       
112       outfile = new AliFstream(filename);
113       
114       if (iddl < 4)
115         {
116           modulePerDDL = 6;
117           mmodule = 6*iddl;
118         }
119       else if (iddl == 4)
120         {
121           modulePerDDL = 12;
122           mmodule = 24;
123         }
124       else if (iddl == 5)
125         {
126           modulePerDDL = 12;
127           mmodule = 30;
128         }
129
130
131
132       // Write the Dummy Data Header into the file
133       Int_t bHPosition = outfile->Tellp();
134       outfile->WriteBuffer((char*)(&header),sizeof(header));
135
136       for (Int_t ibus = 0; ibus < kbusSize; ibus++)
137         {
138           contentsBus[ibus] = 0;
139           for (Int_t ich = 0; ich < kSize; ich++)
140             {
141               busPatch[ibus][ich] = 0;
142             }
143         }
144
145       for(Int_t ium = 0; ium < modulePerDDL; ium++)
146         {
147           if (iddl == 4 && ium == 6) mmodule = 42;
148
149           // Extract energy deposition per cell and pack it
150           // in a 32-bit word and returns all the total words
151           // per one unit-module
152           
153           GetUMDigitsData(treeD, mmodule, iddl, contentsBus, busPatch);
154           mmodule++;
155         }
156
157       
158
159       Int_t ij = 0;
160       Int_t dsp[10];
161       Int_t dspBus[10];
162       for (Int_t i = 0; i < 10; i++)
163         {
164           dsp[i] = 0;
165           dspBus[i] = 0;
166           for (Int_t ibus=0; ibus < 5; ibus++)
167             {
168               ij++;
169               if (contentsBus[ij] > 0)
170                 {
171                   dsp[i] += contentsBus[ij];
172                 }
173               dspBus[i]++;
174             }
175           // Add the patch Bus header to the DSP contents
176           dsp[i] += 4*dspBus[i];
177         }
178
179       Int_t dspBlockARDL    = 0;
180       Int_t dspBlockBRDL    = 0;
181       Int_t remainder       = 0;
182
183
184       for (Int_t i = 0; i < 5; i++)
185         {
186           Int_t ieven = 2*i;
187           Int_t iodd  = 2*i + 1;
188           if (dsp[ieven] > 0)
189             {
190               dspBlockARDL += dsp[ieven];
191               remainder = dsp[ieven]%2;
192               if (remainder == 1)
193                 {
194                   dspBlockARDL++;
195                 }
196             }
197           if (dsp[iodd] > 0)
198             {
199               dspBlockBRDL += dsp[iodd];
200               remainder = dsp[iodd]%2;
201               if (remainder == 1)
202                 {
203                   dspBlockBRDL++;
204                 }
205             }
206         }
207
208       dspBlockARDL += 50;
209       dspBlockBRDL += 50;
210
211       // Start writing the DDL file
212
213       AliPMDBlockHeader blHeader;
214       AliPMDDspHeader   dspHeader;
215       AliPMDPatchBusHeader pbusHeader;
216
217       const Int_t kblHLen   = blHeader.GetHeaderLength();
218       const Int_t kdspHLen  = dspHeader.GetHeaderLength();
219       const Int_t kpbusHLen = pbusHeader.GetHeaderLength();
220
221       UInt_t dspRDL = 0;
222       UInt_t dspBlockHeaderWord[8];
223       UInt_t dspHeaderWord[10];
224       UInt_t patchBusHeaderWord[4];
225       Int_t  iskip[5];
226       UInt_t ddlEndWord[2] = {0xDEADFACE, 0xDEADFACE};
227
228       Int_t bknJunk = 0;
229
230
231       for (Int_t iblock = 0; iblock < 2; iblock++)
232         {
233           // DSP Block Header
234           
235           for (Int_t i=0; i<kblHLen; i++)
236             {
237               dspBlockHeaderWord[i] = 0;
238             }
239           if (iblock == 0)
240             {
241               dspBlockHeaderWord[1] = (UInt_t) (dspBlockARDL + kblHLen);
242               dspBlockHeaderWord[2] = (UInt_t) dspBlockARDL;
243             }
244           else if (iblock == 1)
245             {
246               dspBlockHeaderWord[1] = (UInt_t) (dspBlockBRDL + kblHLen);
247               dspBlockHeaderWord[2] = (UInt_t) dspBlockBRDL;
248             }
249
250           outfile->WriteBuffer((char*)dspBlockHeaderWord,kblHLen*sizeof(UInt_t));
251
252           if (iblock == 0)
253             {
254               iskip[0] = 0;
255               iskip[1] = 10;
256               iskip[2] = 20;
257               iskip[3] = 30;
258               iskip[4] = 40;
259             }
260           else if (iblock == 1)
261             {
262               iskip[0] = 5;
263               iskip[1] = 15;
264               iskip[2] = 25;
265               iskip[3] = 35;
266               iskip[4] = 45;
267             }
268
269           for (Int_t idsp = 0; idsp < 5; idsp++)
270             {
271               // DSP Header
272               Int_t dspno = 0;
273               if (iblock == 0)
274                 {
275                   dspno = 2*idsp;
276                   dspRDL = (UInt_t) dsp[dspno];
277                 }
278               else if (iblock == 1)
279                 {
280                   dspno = 2*idsp + 1;
281                   dspRDL = (UInt_t) dsp[dspno];
282                 }
283
284               for (Int_t i=0; i<kdspHLen; i++)
285                 {
286                   dspHeaderWord[i] = 0;
287                 }
288               remainder = dspRDL%2;
289               if (remainder == 1) dspRDL++;
290
291               dspHeaderWord[1] = dspRDL + kdspHLen;
292               dspHeaderWord[2] = dspRDL;
293               dspHeaderWord[3] = dspno;
294               if (remainder == 1) dspHeaderWord[8] = 1; // setting the padding word
295
296
297               outfile->WriteBuffer((char*)dspHeaderWord,kdspHLen*sizeof(UInt_t));
298
299               for (Int_t ibus = 0; ibus < 5; ibus++)
300                 {
301                   // Patch Bus Header
302
303                   Int_t busno = iskip[idsp] + ibus + 1;
304                   Int_t patchbusRDL = contentsBus[busno];
305
306                   if (patchbusRDL > 0)
307                     {
308                       patchBusHeaderWord[0] = 0;
309                       patchBusHeaderWord[1] = (UInt_t) (patchbusRDL + kpbusHLen);
310                       patchBusHeaderWord[2] = (UInt_t) patchbusRDL;
311                       patchBusHeaderWord[3] = (UInt_t) busno;
312                     }
313                   else if (patchbusRDL == 0)
314                     {
315                       patchBusHeaderWord[0] = 0;
316                       patchBusHeaderWord[1] = (UInt_t) kpbusHLen;
317                       patchBusHeaderWord[2] = (UInt_t) 0;
318                       patchBusHeaderWord[3] = (UInt_t) busno;
319                     }
320
321
322                   outfile->WriteBuffer((char*)patchBusHeaderWord,4*sizeof(UInt_t));
323
324                   bknJunk += patchbusRDL;
325
326                   for (Int_t iword = 0; iword < patchbusRDL; iword++)
327                     {
328                       buffer[iword] = busPatch[busno][iword];
329                     }
330                   
331                   outfile->WriteBuffer((char*)buffer,patchbusRDL*sizeof(UInt_t));
332
333                 } // End of patch bus loop
334
335
336               // Adding a padding word if the total words odd
337               if (remainder == 1)
338                 {
339                   UInt_t paddingWord = dspHeader.GetDefaultPaddingWord();
340                   outfile->WriteBuffer((char*)(&paddingWord),sizeof(UInt_t));
341                 }
342             }
343         }
344
345       // Write two extra word at the end of each DDL file
346       outfile->WriteBuffer((char*)ddlEndWord,2*sizeof(UInt_t));
347
348       // Write real data header
349       // take the pointer to the beginning of the data header
350       // write the total number of words per ddl and bring the
351       // pointer to the current file position and close it
352       UInt_t cFPosition = outfile->Tellp();
353       sizeRawData = cFPosition - bHPosition - sizeof(header);
354
355       header.fSize = cFPosition - bHPosition;
356       header.SetAttribute(0);  // valid data
357       outfile->Seekp(bHPosition);
358       outfile->WriteBuffer((char*)(&header),sizeof(header));
359       outfile->Seekp(cFPosition);
360
361       delete outfile;
362     } // DDL Loop over
363
364
365 }
366 //____________________________________________________________________________
367 void AliPMDDDLRawData::GetUMDigitsData(TTree *treeD, Int_t imodule,
368                                        Int_t ddlno, Int_t *contentsBus,
369                                        UInt_t busPatch[][1536])
370 {
371   // Retrives digits data UnitModule by UnitModule
372
373   UInt_t baseword;
374   UInt_t mcmno, chno;
375   UInt_t adc;
376   Int_t  det, smn, irow, icol;
377   Int_t  parity;
378   
379   const Int_t kMaxBus = 51;   // BKN
380   Int_t totPatchBus, bPatchBus, ePatchBus;
381   Int_t ibus, totmcm, rows, cols, rowe, cole;
382   Int_t moduleno;
383   Int_t busno = 0;
384   Int_t patchBusNo[kMaxBus], mcmperBus[kMaxBus];
385   Int_t startRowBus[kMaxBus], startColBus[kMaxBus];
386   Int_t endRowBus[kMaxBus], endColBus[kMaxBus];
387
388   Int_t beginPatchBus = -1;
389   Int_t endPatchBus   = -1;
390   for(Int_t i = 0; i < kMaxBus; i++)
391     {
392       patchBusNo[i]  = -1;
393       mcmperBus[i]   = -1;
394       startRowBus[i] = -1;
395       startColBus[i] = -1;
396       endRowBus[i]   = -1;
397       endColBus[i]   = -1;
398     }
399   Int_t modulePerDDL = 0;
400   if (ddlno < 4)
401     {
402       modulePerDDL = 6;
403     }
404   else if (ddlno == 4 || ddlno == 5)
405     {
406       modulePerDDL = 12;
407     }
408
409   TString fileName(gSystem->Getenv("ALICE_ROOT"));
410
411   if(ddlno == 0)
412     {
413       fileName += "/PMD/PMD_Mapping_ddl0.dat";
414     }
415   else if(ddlno == 1)
416     {
417       fileName += "/PMD/PMD_Mapping_ddl1.dat";
418     }
419   else if(ddlno == 2)
420     {
421       fileName += "/PMD/PMD_Mapping_ddl2.dat";
422     }
423   else if(ddlno == 3)
424     {
425       fileName += "/PMD/PMD_Mapping_ddl3.dat";
426     }
427   else if(ddlno == 4)
428     {
429       fileName += "/PMD/PMD_Mapping_ddl4.dat";
430     }
431   else if(ddlno == 5)
432     {
433       fileName += "/PMD/PMD_Mapping_ddl5.dat";
434     }
435
436   ifstream infile;
437   infile.open(fileName.Data(), ios::in); // ascii file
438   if(!infile)
439     AliError(Form("Could not read the mapping file for DDL No = %d",ddlno));
440
441   for (Int_t im = 0; im < modulePerDDL; im++)
442     {
443       infile >> moduleno;
444       infile >> totPatchBus >> bPatchBus >> ePatchBus;
445
446       if (moduleno == imodule)
447         {
448           beginPatchBus = bPatchBus;
449           endPatchBus   = ePatchBus;
450         }
451       
452       for(Int_t i=0; i<totPatchBus; i++)
453         {
454           infile >> ibus >> totmcm >> rows >> rowe >> cols >> cole;
455
456           if (moduleno == imodule)
457             {
458               patchBusNo[ibus]   = ibus;
459               mcmperBus[ibus]    = totmcm;
460               startRowBus[ibus]  = rows;
461               startColBus[ibus]  = cols;
462               endRowBus[ibus]    = rowe;
463               endColBus[ibus]    = cole;
464             }
465         }
466
467     }
468
469   infile.close();
470
471   treeD->GetEntry(imodule); 
472   Int_t nentries = fDigits->GetLast();
473   Int_t totword = nentries+1;
474
475   AliPMDdigit *pmddigit;
476
477   for (Int_t ient = 0; ient < totword; ient++)
478     {
479       pmddigit = (AliPMDdigit*)fDigits->UncheckedAt(ient);
480       
481       det    = pmddigit->GetDetector();
482       smn    = pmddigit->GetSMNumber();
483       irow   = pmddigit->GetRow();
484       icol   = pmddigit->GetColumn();
485       adc    = (UInt_t) pmddigit->GetADC();
486
487       TransformS2H(smn,irow,icol);
488
489       GetMCMCh(ddlno, smn, irow, icol, beginPatchBus, endPatchBus,
490                mcmperBus, startRowBus, startColBus,
491                endRowBus, endColBus, busno, mcmno, chno);
492
493       baseword = 0;
494       AliBitPacking::PackWord(adc,baseword,0,11);
495       AliBitPacking::PackWord(chno,baseword,12,17);
496       AliBitPacking::PackWord(mcmno,baseword,18,28);
497       AliBitPacking::PackWord(0,baseword,29,30);
498       parity = ComputeParity(baseword);      // generate the parity bit
499       AliBitPacking::PackWord(parity,baseword,31,31);
500
501       Int_t jj = contentsBus[busno];
502       busPatch[busno][jj] = baseword;
503
504       contentsBus[busno]++;
505     }
506
507 }
508
509 //____________________________________________________________________________
510 void AliPMDDDLRawData::TransformS2H(Int_t smn, Int_t &irow, Int_t &icol)
511 {
512   // Does the Software to Hardware coordinate transformation
513   //
514
515   Int_t  irownew = 0;
516   Int_t  icolnew = 0;
517
518   // First in digits we have all dimension 48x96
519   // Transform into the realistic one, i.e, For SM 0&1 96(row)x48(col)
520   // and for SM 2&3 48(row)x96(col)
521   // 
522   if(smn < 12)
523     {
524       irownew = icol;
525       icolnew = irow;
526     }
527   else if( smn >= 12 && smn < 24)
528     {
529       irownew = irow;
530       icolnew = icol;
531     }
532
533   irow = irownew;
534   icol = icolnew;
535
536 }
537
538
539 //____________________________________________________________________________
540
541 void AliPMDDDLRawData::GetMCMCh(Int_t ddlno, Int_t smn, Int_t row, Int_t col,
542                                 Int_t beginPatchBus, Int_t endPatchBus,
543                                 Int_t *mcmperBus,
544                                 Int_t *startRowBus, Int_t *startColBus,
545                                 Int_t *endRowBus, Int_t *endColBus,
546                                 Int_t & busno, UInt_t &mcmno, UInt_t &chno)
547 {
548   // This converts row col to hardware channel number
549   // This is the final version of mapping supplied by Mriganka
550
551     UInt_t iCh[16][4];
552
553     static const UInt_t kChDdl01[16][4] = { {6, 4, 5, 7},
554                                            {10, 2, 1, 9},
555                                            {12, 0, 3, 11},
556                                            {14, 8, 13, 15},
557                                            {16, 18, 23, 17},
558                                            {20, 28, 31, 19},
559                                            {22, 30, 29, 21},
560                                            {24, 26, 27, 25},
561                                            {38, 36, 37, 39},
562                                            {42, 34, 33, 41},
563                                            {44, 32, 35, 43},
564                                            {46, 40, 45, 47},
565                                            {48, 50, 55, 49},
566                                            {52, 60, 63, 51},
567                                            {54, 62, 61, 53},
568                                            {56, 58, 59, 57} };
569
570
571     static const UInt_t kChDdl23[16][4] = { {57, 59, 58, 56},
572                                             {53, 61, 62, 54},
573                                             {51, 63, 60, 52},
574                                             {49, 55, 50, 48},
575                                             {47, 45, 40, 46},
576                                             {43, 35, 32, 44},
577                                             {41, 33, 34, 42},
578                                             {39, 37, 36, 38},
579                                             {25, 27, 26, 24},
580                                             {21, 29, 30, 22},
581                                             {19, 31, 28, 20},
582                                             {17, 23, 18, 16},
583                                             {15, 13, 8, 14},
584                                             {11, 3, 0, 12},
585                                             {9, 1, 2, 10},
586                                             {7, 5, 4, 6} };
587     
588     
589     static const UInt_t kChDdl41[16][4] = { {56, 58, 59, 57},
590                                            {54, 62, 61, 53},
591                                            {52, 60, 63, 51},
592                                            {48, 50, 55, 49},
593                                            {46, 40, 45, 47},
594                                            {44, 32, 35, 43},
595                                            {42, 34, 33, 41},
596                                            {38, 36, 37, 39},
597                                            {24, 26, 27, 25},
598                                            {22, 30, 29, 21},
599                                            {20, 28, 31, 19},
600                                            {16, 18, 23, 17},
601                                            {14, 8, 13, 15},
602                                            {12, 0, 3, 11},
603                                            {10, 2, 1, 9},
604                                            {6, 4, 5, 7} };
605
606
607     static const UInt_t kChDdl42[16][4] = { {7, 5, 4, 6},
608                                             {9, 1, 2, 10},
609                                             {11, 3, 0, 12},
610                                             {15, 13, 8, 14},
611                                             {17, 23, 18, 16},
612                                             {19, 31, 28, 20},
613                                             {21, 29, 30, 22},
614                                             {25, 27, 26, 24},
615                                             {39, 37, 36, 38},
616                                             {41, 33, 34, 42},
617                                             {43, 35, 32, 44},
618                                             {47, 45, 40, 46},
619                                             {49, 55, 50, 48},
620                                             {51, 63, 60, 52},
621                                             {53, 61, 62, 54},
622                                             {57, 59, 58, 56} };
623
624
625     static const UInt_t kChDdl51[16][4] = { {7, 5, 4, 6},
626                                             {9, 1, 2, 10},
627                                             {11, 3, 0, 12},
628                                             {15, 13, 8, 14},
629                                             {17, 23, 18, 16},
630                                             {19, 31, 28, 20},
631                                             {21, 29, 30, 22},
632                                             {25, 27, 26, 24},
633                                             {39, 37, 36, 38},
634                                             {41, 33, 34, 42},
635                                             {43, 35, 32, 44},
636                                             {47, 45, 40, 46},
637                                             {49, 55, 50, 48},
638                                             {51, 63, 60, 52},
639                                             {53, 61, 62, 54},
640                                             {57, 59, 58, 56} };
641     
642
643
644     static const UInt_t kChDdl52[16][4] = { {56, 58, 59, 57},
645                                             {54, 62, 61, 53},
646                                             {52, 60, 63, 51},
647                                             {48, 50, 55, 49},
648                                             {46, 40, 45, 47},
649                                             {44, 32, 35, 43},
650                                             {42, 34, 33, 41},
651                                             {38, 36, 37, 39},
652                                             {24, 26, 27, 25},
653                                             {22, 30, 29, 21},
654                                             {20, 28, 31, 19},
655                                             {16, 18, 23, 17},
656                                             {14, 8, 13, 15},
657                                             {12, 0, 3, 11},
658                                             {10, 2, 1, 9},
659                                             {6, 4, 5, 7} };
660     
661     
662     for (Int_t i = 0; i < 16; i++)
663     {
664         for (Int_t j = 0; j < 4; j++)
665         {
666             if (ddlno == 0 || ddlno == 1) iCh[i][j] = kChDdl01[i][j];
667             if (ddlno == 2 || ddlno == 3) iCh[i][j] = kChDdl23[i][j];
668             
669             if (ddlno == 4 && smn < 6)                iCh[i][j] = kChDdl41[i][j];
670             if (ddlno == 4 && (smn >= 18 && smn < 24))iCh[i][j] = kChDdl42[i][j];
671             if (ddlno == 5 && (smn >= 12 && smn < 18))iCh[i][j] = kChDdl51[i][j];
672             if (ddlno == 5 && (smn >=  6 && smn < 12))iCh[i][j] = kChDdl52[i][j];
673         }
674     }
675
676
677   Int_t irownew = row%16;
678   Int_t icolnew = col%4;
679   
680   chno  = iCh[irownew][icolnew];
681   
682   
683   for (Int_t ibus = beginPatchBus; ibus <= endPatchBus; ibus++)
684     {
685       Int_t srow = startRowBus[ibus];
686       Int_t erow = endRowBus[ibus];
687       Int_t scol = startColBus[ibus];
688       Int_t ecol = endColBus[ibus];
689       Int_t tmcm = mcmperBus[ibus];
690       if ((row >= srow && row <= erow) && (col >= scol && col <= ecol))
691         {
692           busno = ibus;
693           
694           // Find out the MCM Number
695           //
696           
697           if (ddlno == 0 || ddlno == 1)
698             {
699               // PRE plane, SU Mod = 0, 1
700               mcmno = (col-scol)/4 + 1;
701               
702             }
703           else if (ddlno == 2 || ddlno == 3)
704             {
705               // PRE plane,  SU Mod = 2, 3
706               icolnew = (col - scol)/4;
707               mcmno = tmcm - icolnew;
708             }
709           else if (ddlno == 4 )
710             {
711               // CPV plane,  SU Mod = 0, 3 : ddl = 4
712               
713               if(ibus <= 18)
714                 {
715                   Int_t midrow = srow + 16;
716                   if(row >= srow && row < midrow)
717                     {
718                       mcmno = 12 + (col-scol)/4 + 1;
719                     }
720                   else if(row >= midrow && row <= erow)
721                   
722                     {
723                       mcmno = (col-scol)/4 + 1;
724                     }
725                 }
726               
727               else if (ibus > 18)
728                 {
729                   Int_t rowdiff = endRowBus[ibus] - startRowBus[ibus];
730                   if(rowdiff > 16)
731                     {
732                       Int_t midrow = srow + 16;
733                       if (row >= midrow && row <= erow)
734                         {
735                           mcmno = 12 + (ecol -col)/4 + 1;
736                         }
737                       else if (row >= srow && row < midrow)
738                         {
739                           mcmno = (ecol - col)/4 + 1;
740                         }
741                     }
742                   else if (rowdiff < 16)
743                     {
744                       mcmno = (ecol - col)/4 + 1;
745                     }
746                 }
747             }
748           else if ( ddlno == 5)
749             {
750               // CPV plane,  SU Mod = 1, 2 : ddl = 5
751               
752               if(ibus <= 18)
753                 {
754                   Int_t midrow = srow + 16;
755                   if(row >= srow && row < midrow)
756                     {
757                       mcmno = 12 + (col-scol)/4 + 1;
758                     }
759                   else if(row >= midrow && row <= erow)
760                     {
761                       mcmno = (col-scol)/4 + 1;
762                     }
763                 }
764               
765               else if (ibus > 18)
766                 {
767                   Int_t rowdiff = endRowBus[ibus] - startRowBus[ibus];
768                   if(rowdiff > 16)
769                     {
770                       Int_t midrow = srow + 16;
771                       if (row >= midrow && row <= erow)
772                         {
773                           mcmno = 12 + (ecol - col)/4 + 1;
774                         }
775                       else if (row >= srow && row < midrow)
776                         {
777                           mcmno = (ecol - col)/4 + 1;
778                         }
779                     }
780                   else if (rowdiff < 16)
781                     {
782                       mcmno = (ecol - col)/4 + 1;
783                     }
784                 }
785             }
786         }
787     }
788
789
790 //____________________________________________________________________________
791
792 Int_t AliPMDDDLRawData::ComputeParity(UInt_t baseword)
793 {
794   // Generate the parity bit
795
796   Int_t count = 0;
797   for(Int_t j=0; j<29; j++)
798     {
799       if (baseword & 0x01 ) count++;
800       baseword >>= 1;
801     }
802   Int_t parity = count%2;
803   return parity;
804 }
805
806 //____________________________________________________________________________