1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 ///////////////////////////////////////////////////////////////////////////////
20 /// This class provides access to PMD digits in raw data.
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.
27 ///////////////////////////////////////////////////////////////////////////////
29 #include <Riostream.h>
30 #include <TObjArray.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"
42 ClassImp(AliPMDRawStream)
45 //_____________________________________________________________________________
46 AliPMDRawStream::AliPMDRawStream(AliRawReader* rawReader) :
47 fRawReader(rawReader),
51 // create an object to read PMD raw digits
54 fRawReader->Select("PMD");
57 //_____________________________________________________________________________
58 AliPMDRawStream::AliPMDRawStream(const AliPMDRawStream& stream) :
66 AliFatal("Copy constructor not implemented");
69 //_____________________________________________________________________________
70 AliPMDRawStream& AliPMDRawStream::operator = (const AliPMDRawStream&
73 // assignment operator
75 AliFatal("operator = assignment operator not implemented");
79 //_____________________________________________________________________________
80 AliPMDRawStream::~AliPMDRawStream()
87 //_____________________________________________________________________________
89 Int_t AliPMDRawStream::DdlData(TObjArray *pmdddlcont)
91 // read the next raw digit
92 // returns kFALSE if there is no digit left
98 AliPMDddldata *pmdddldata;
100 if (!fRawReader->ReadHeader()) return iddl;
102 iddl = fRawReader->GetDDLID();
103 Int_t dataSize = fRawReader->GetDataSize();
104 Int_t totaldataword = dataSize/4;
106 if (dataSize <= 0) return -1;
110 fRawReader->ReadNextData(fData);
114 // --- Open the mapping file
116 TString fileName(gSystem->Getenv("ALICE_ROOT"));
119 fileName += "/PMD/PMD_Mapping_ddl0.dat";
123 fileName += "/PMD/PMD_Mapping_ddl1.dat";
127 fileName += "/PMD/PMD_Mapping_ddl2.dat";
131 fileName += "/PMD/PMD_Mapping_ddl3.dat";
135 fileName += "/PMD/PMD_Mapping_ddl4.dat";
139 fileName += "/PMD/PMD_Mapping_ddl5.dat";
143 infile.open(fileName.Data(), ios::in); // ascii file
146 AliError(Form("Could not read the mapping file for DDL No = %d",iddl));
147 fRawReader->AddFatalErrorLog(kNoMappingFile,Form("ddl=%d",iddl));
150 Int_t modulePerDDL = 0;
155 else if (iddl == 4 || iddl == 5)
160 const Int_t kNPatchBus = 51;
162 Int_t modno, totPatchBus, bPatchBus, ePatchBus;
163 Int_t ibus, totmcm, rows, rowe, cols, cole;
164 Int_t moduleNo[kNPatchBus], mcmperBus[kNPatchBus];
165 Int_t startRowBus[kNPatchBus], endRowBus[kNPatchBus];
166 Int_t startColBus[kNPatchBus], endColBus[kNPatchBus];
168 for (ibus = 0; ibus < kNPatchBus; ibus++)
170 mcmperBus[ibus] = -1;
171 startRowBus[ibus] = -1;
172 endRowBus[ibus] = -1;
173 startColBus[ibus] = -1;
174 endColBus[ibus] = -1;
177 for (Int_t im = 0; im < modulePerDDL; im++)
180 infile >> totPatchBus >> bPatchBus >> ePatchBus;
182 for(Int_t i=0; i<totPatchBus; i++)
184 infile >> ibus >> totmcm >> rows >> rowe >> cols >> cole;
186 moduleNo[ibus] = modno;
187 mcmperBus[ibus] = totmcm;
188 startRowBus[ibus] = rows;
189 endRowBus[ibus] = rowe;
190 startColBus[ibus] = cols;
191 endColBus[ibus] = cole;
197 AliPMDBlockHeader blockHeader;
198 AliPMDDspHeader dspHeader;
199 AliPMDPatchBusHeader pbusHeader;
201 const Int_t kblHLen = blockHeader.GetHeaderLength();
202 const Int_t kdspHLen = dspHeader.GetHeaderLength();
203 const Int_t kpbusHLen = pbusHeader.GetHeaderLength();
210 Int_t blHeaderWord[8];
211 Int_t dspHeaderWord[10];
212 Int_t pbusHeaderWord[4];
216 Int_t blRawDataLength = 0;
217 Int_t dspRawDataLength = 0;
220 for (Int_t iblock = 0; iblock < 2; iblock++)
222 ilowLimit = iuppLimit;
223 iuppLimit = ilowLimit + kblHLen;
225 for (Int_t i = ilowLimit; i < iuppLimit; i++)
229 blHeaderWord[i-ilowLimit] = (Int_t) GetNextWord();
232 blockHeader.SetHeader(blHeaderWord);
233 blRawDataLength = blockHeader.GetRawDataLength();
235 if (iwordddl == totaldataword) continue;
239 for (Int_t idsp = 0; idsp < 5; idsp++)
243 ilowLimit = iuppLimit;
244 iuppLimit = ilowLimit + kdspHLen;
246 for (Int_t i = ilowLimit; i < iuppLimit; i++)
250 dspHeaderWord[i-ilowLimit] = (Int_t) GetNextWord();
252 dspHeader.SetHeader(dspHeaderWord);
253 dspRawDataLength = dspHeader.GetRawDataLength();
255 if (iwordddl == totaldataword) continue;
259 for (ibus = 0; ibus < 5; ibus++)
261 ilowLimit = iuppLimit;
262 iuppLimit = ilowLimit + kpbusHLen;
264 for (Int_t i = ilowLimit; i < iuppLimit; i++)
269 pbusHeaderWord[i-ilowLimit] = (Int_t) GetNextWord();
272 pbusHeader.SetHeader(pbusHeaderWord);
273 Int_t rawdatalength = pbusHeader.GetRawDataLength();
274 Int_t pbusid = pbusHeader.GetPatchBusId();
276 ilowLimit = iuppLimit;
277 iuppLimit = ilowLimit + rawdatalength;
279 Int_t imodule = moduleNo[pbusid];
281 if (iwordddl == totaldataword) continue;
283 for (Int_t iword = ilowLimit; iword < iuppLimit; iword++)
289 data = GetNextWord();
291 Int_t isig = data & 0x0FFF;
292 Int_t ich = (data >> 12) & 0x003F;
293 Int_t imcm = (data >> 18) & 0x07FF;
294 Int_t ibit = (data >> 31) & 0x0001;
295 parity = ComputeParity(data);
298 AliWarning("ComputeParity:: Parity Error");
299 fRawReader->AddMajorErrorLog(kParityError);
302 ConvertDDL2SMN(iddl, imodule, ismn, idet);
304 GetRowCol(iddl, ismn, pbusid, imcm, ich,
305 startRowBus, endRowBus,
306 startColBus, endColBus,
309 TransformH2S(ismn, irow, icol);
311 pmdddldata = new AliPMDddldata();
313 pmdddldata->SetDetector(idet);
314 pmdddldata->SetSMN(ismn);
315 pmdddldata->SetModule(imodule);
316 pmdddldata->SetPatchBusId(pbusid);
317 pmdddldata->SetMCM(imcm);
318 pmdddldata->SetChannel(ich);
319 pmdddldata->SetRow(irow);
320 pmdddldata->SetColumn(icol);
321 pmdddldata->SetSignal(isig);
322 pmdddldata->SetParityBit(ibit);
324 pmdddlcont->Add(pmdddldata);
328 if (iwordddl == totaldataword) break;
330 if (iworddsp == dspRawDataLength) break; // raw data
334 if (dspHeader.GetPaddingWord() == 1)
340 data = GetNextWord();
343 if (iwordblk == blRawDataLength) break; // for raw data
353 //_____________________________________________________________________________
354 void AliPMDRawStream::GetRowCol(Int_t ddlno, Int_t smn, Int_t pbusid,
355 UInt_t mcmno, UInt_t chno,
356 Int_t startRowBus[], Int_t endRowBus[],
357 Int_t startColBus[], Int_t endColBus[],
358 Int_t &row, Int_t &col) const
360 // decode: ddlno, patchbusid, mcmno, chno -> um, row, col
364 static const UInt_t kChDdl01[64] = { 9, 6, 5, 10, 1, 2, 0, 3,
365 13, 7, 4, 11, 8, 14, 12, 15,
366 16, 19, 17, 23, 20, 27, 24, 18,
367 28, 31, 29, 30, 21, 26, 25, 22,
368 41, 38, 37, 42, 33, 34, 32, 35,
369 45, 39, 36, 43, 40, 46, 44, 47,
370 48, 51, 49, 55, 52, 59, 56, 50,
371 60, 63, 61, 62, 53, 58, 57, 54 };
373 static const UInt_t kChDdl23[64] = { 54, 57, 58, 53, 62, 61, 63, 60,
374 50, 56, 59, 52, 55, 49, 51, 48,
375 47, 44, 46, 40, 43, 36, 39, 45,
376 35, 32, 34, 33, 42, 37, 38, 41,
377 22, 25, 26, 21, 30, 29, 31, 28,
378 18, 24, 27, 20, 23, 17, 19, 16,
379 15, 12, 14, 8, 11, 4, 7, 13,
380 3, 0, 2, 1, 10, 5, 6, 9 };
382 static const UInt_t kChDdl41[64] = { 53, 58, 57, 54, 61, 62, 60, 63,
383 49, 59, 56, 55, 52, 50, 48, 51,
384 44, 47, 45, 43, 40, 39, 36, 46,
385 32, 35, 33, 34, 41, 38, 37, 42,
386 21, 26, 25, 22, 29, 30, 28, 31,
387 17, 27, 24, 23, 20, 18, 16, 19,
388 12, 15, 13, 11, 8, 7, 4, 14,
389 0, 3, 1, 2, 9, 6, 5, 10 };
391 static const UInt_t kChDdl42[64] = { 10, 5, 6, 9, 2, 1, 3, 0,
392 14, 4, 7, 8, 11, 13, 15, 12,
393 19, 16, 18, 20, 23, 24, 27, 17,
394 31, 28, 30, 29, 22, 25, 26, 21,
395 42, 37, 38, 41, 34, 33, 35, 32,
396 46, 36, 39, 40, 43, 45, 47, 44,
397 51, 48, 50, 52, 55, 56, 59, 49,
398 63, 60, 62, 61, 54, 57, 58, 53 };
400 static const UInt_t kChDdl51[64] = { 10, 5, 6, 9, 2, 1, 3, 0,
401 14, 4, 7, 8, 11, 13, 15, 12,
402 19, 16, 18, 20, 23, 24, 27, 17,
403 31, 28, 30, 29, 22, 25, 26, 21,
404 42, 37, 38, 41, 34, 33, 35, 32,
405 46, 36, 39, 40, 43, 45, 47, 44,
406 51, 48, 50, 52, 55, 56, 59, 49,
407 63, 60, 62, 61, 54, 57, 58, 53 };
409 static const UInt_t kChDdl52[64] = { 53, 58, 57, 54, 61, 62, 60, 63,
410 49, 59, 56, 55, 52, 50, 48, 51,
411 44, 47, 45, 43, 40, 39, 36, 46,
412 32, 35, 33, 34, 41, 38, 37, 42,
413 21, 26, 25, 22, 29, 30, 28, 31,
414 17, 27, 24, 23, 20, 18, 16, 19,
415 12, 15, 13, 11, 8, 7, 4, 14,
416 0, 3, 1, 2, 9, 6, 5, 10 };
418 for (Int_t i = 0; i < 64; i++)
420 if (ddlno == 0 || ddlno == 1) iCh[i] = kChDdl01[i];
421 if (ddlno == 2 || ddlno == 3) iCh[i] = kChDdl23[i];
423 if (ddlno == 4 && smn < 6) iCh[i] = kChDdl41[i];
424 if (ddlno == 4 && (smn >= 18 && smn < 24))iCh[i] = kChDdl42[i];
425 if (ddlno == 5 && (smn >= 12 && smn < 18))iCh[i] = kChDdl51[i];
426 if (ddlno == 5 && (smn >= 6 && smn < 12))iCh[i] = kChDdl52[i];
430 Int_t rowcol = iCh[chno];
431 Int_t irownew = rowcol/4;
432 Int_t icolnew = rowcol%4;
436 row = startRowBus[pbusid] + irownew;
437 col = startColBus[pbusid] + (mcmno-1)*4 + icolnew;
441 row = endRowBus[pbusid] - (15 - irownew);
442 col = startColBus[pbusid] + (mcmno-1)*4 + icolnew;
445 else if (ddlno == 2 )
447 row = startRowBus[pbusid] + irownew;
448 col = endColBus[pbusid] - (mcmno-1)*4 - (3 - icolnew);
452 row = endRowBus[pbusid] - (15 - irownew);
453 col = endColBus[pbusid] - (mcmno-1)*4 - (3 - icolnew);
455 else if (ddlno == 4 )
461 // Add 16 to skip the 1st 15 rows
462 row = startRowBus[pbusid] + irownew + 16;
463 col = startColBus[pbusid] + (mcmno-1)*4 + icolnew;
467 row = startRowBus[pbusid] + irownew;
468 col = startColBus[pbusid] + (mcmno-12-1)*4 + icolnew;
475 col = endColBus[pbusid] - (mcmno-1)*4 - (3 - icolnew);
477 if(endRowBus[pbusid] - startRowBus[pbusid] > 16)
478 row = endRowBus[pbusid] - (15 - irownew) - 16 ;
480 row = endRowBus[pbusid] - (15 - irownew) ;
484 row = endRowBus[pbusid] - (15 - irownew) ;
485 col = endColBus[pbusid] - (mcmno - 12 - 1)*4 - (3 - icolnew);
495 // Subtract 16 to skip the 1st 15 rows
496 row = endRowBus[pbusid] - 16 -(15 - irownew);
497 col = startColBus[pbusid] + (mcmno-12 -1)*4 + icolnew;
501 row = endRowBus[pbusid] - (15 - irownew) ;
502 col = startColBus[pbusid] + (mcmno -1)*4 + icolnew;
507 else if (pbusid > 18)
511 // Add 16 to skip the 1st 15 rows
512 row = startRowBus[pbusid] + irownew + 16;
513 col = endColBus[pbusid] - (mcmno - 12 - 1)*4 - (3 - icolnew);
517 row = startRowBus[pbusid] + irownew ;
518 col = endColBus[pbusid] - (mcmno - 1)*4 - (3 - icolnew);
524 //_____________________________________________________________________________
525 void AliPMDRawStream::ConvertDDL2SMN(Int_t iddl, Int_t imodule,
526 Int_t &smn, Int_t &detector) const
528 // This converts the DDL number (0 to 5), Module Number (0-47)
529 // to Serial module number in one detector (SMN : 0-23) and
530 // detector number (0:PRE plane, 1:CPV plane)
542 //_____________________________________________________________________________
544 void AliPMDRawStream::TransformH2S(Int_t smn, Int_t &row, Int_t &col) const
546 // This does the transformation of the hardware coordinate to
548 // i.e., For SuperModule 0 &1, instead of 96x48(hardware),
549 // it is 48x96 (software)
550 // For Supermodule 3 & 4, 48x96
560 else if(smn >= 12 && smn < 24)
569 //_____________________________________________________________________________
570 Int_t AliPMDRawStream::ComputeParity(UInt_t data)
572 // Calculate the parity bit
575 for(Int_t j = 0; j<29; j++)
577 if (data & 0x01 ) count++;
581 Int_t parity = count%2;
586 //_____________________________________________________________________________
587 UInt_t AliPMDRawStream::GetNextWord()
589 // Returns the next 32 bit word
590 // inside the raw data payload.
592 if (!fData || fPosition < 0) AliFatal("Raw data payload buffer is not yet initialized !");
595 word |= fData[fPosition++];
596 word |= fData[fPosition++] << 8;
597 word |= fData[fPosition++] << 16;
598 word |= fData[fPosition++] << 24;