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