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) :
49 // create an object to read PMD raw digits
51 fRawReader->Select("PMD");
54 //_____________________________________________________________________________
55 AliPMDRawStream::AliPMDRawStream(const AliPMDRawStream& stream) :
61 AliFatal("Copy constructor not implemented");
64 //_____________________________________________________________________________
65 AliPMDRawStream& AliPMDRawStream::operator = (const AliPMDRawStream&
68 // assignment operator
70 AliFatal("operator = assignment operator not implemented");
74 //_____________________________________________________________________________
75 AliPMDRawStream::~AliPMDRawStream()
82 //_____________________________________________________________________________
84 Bool_t AliPMDRawStream::DdlData(Int_t indexDDL, TObjArray *pmdddlcont)
86 // read the next raw digit
87 // returns kFALSE if there is no digit left
90 AliPMDddldata *pmdddldata;
92 if (!fRawReader->ReadHeader()) return kFALSE;
93 Int_t iddl = fRawReader->GetDDLID();
94 Int_t dataSize = fRawReader->GetDataSize();
95 Int_t totaldataword = dataSize/4;
97 if (dataSize <= 0) return kFALSE;
100 AliWarning("Mismatch in the DDL index");
101 fRawReader->AddFatalErrorLog(kDDLIndexMismatch);
106 buffer = new UInt_t[totaldataword];
108 for (Int_t i = 0; i < totaldataword; i++)
110 fRawReader->ReadNextInt(data);
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
145 AliError(Form("Could not read the mapping file for DDL No = %d",iddl));
146 fRawReader->AddFatalErrorLog(kNoMappingFile,Form("ddl=%d",iddl));
149 Int_t modulePerDDL = 0;
154 else if (iddl == 4 || iddl == 5)
159 const Int_t kNPatchBus = 51;
161 Int_t modno, totPatchBus, bPatchBus, ePatchBus;
162 Int_t ibus, totmcm, rows, rowe, cols, cole;
163 Int_t moduleNo[kNPatchBus], mcmperBus[kNPatchBus];
164 Int_t startRowBus[kNPatchBus], endRowBus[kNPatchBus];
165 Int_t startColBus[kNPatchBus], endColBus[kNPatchBus];
167 for (Int_t ibus = 0; ibus < kNPatchBus; ibus++)
169 mcmperBus[ibus] = -1;
170 startRowBus[ibus] = -1;
171 endRowBus[ibus] = -1;
172 startColBus[ibus] = -1;
173 endColBus[ibus] = -1;
176 for (Int_t im = 0; im < modulePerDDL; im++)
179 infile >> totPatchBus >> bPatchBus >> ePatchBus;
181 for(Int_t i=0; i<totPatchBus; i++)
183 infile >> ibus >> totmcm >> rows >> rowe >> cols >> cole;
185 moduleNo[ibus] = modno;
186 mcmperBus[ibus] = totmcm;
187 startRowBus[ibus] = rows;
188 endRowBus[ibus] = rowe;
189 startColBus[ibus] = cols;
190 endColBus[ibus] = cole;
196 AliPMDBlockHeader blockHeader;
197 AliPMDDspHeader dspHeader;
198 AliPMDPatchBusHeader pbusHeader;
200 const Int_t kblHLen = blockHeader.GetHeaderLength();
201 const Int_t kdspHLen = dspHeader.GetHeaderLength();
202 const Int_t kpbusHLen = pbusHeader.GetHeaderLength();
209 Int_t blHeaderWord[8];
210 Int_t dspHeaderWord[10];
211 Int_t pbusHeaderWord[4];
215 Int_t blRawDataLength = 0;
216 Int_t iwordcount = 0;
219 for (Int_t iblock = 0; iblock < 2; iblock++)
221 ilowLimit = iuppLimit;
222 iuppLimit = ilowLimit + kblHLen;
224 for (Int_t i = ilowLimit; i < iuppLimit; i++)
226 blHeaderWord[i-ilowLimit] = (Int_t) buffer[i];
229 blockHeader.SetHeader(blHeaderWord);
231 blRawDataLength = blockHeader.GetRawDataLength();
233 for (Int_t idsp = 0; idsp < 5; idsp++)
235 ilowLimit = iuppLimit;
236 iuppLimit = ilowLimit + kdspHLen;
238 for (Int_t i = ilowLimit; i < iuppLimit; i++)
241 dspHeaderWord[i-ilowLimit] = (Int_t) buffer[i];
243 dspHeader.SetHeader(dspHeaderWord);
245 for (Int_t ibus = 0; ibus < 5; ibus++)
247 ilowLimit = iuppLimit;
248 iuppLimit = ilowLimit + kpbusHLen;
250 for (Int_t i = ilowLimit; i < iuppLimit; i++)
253 pbusHeaderWord[i-ilowLimit] = (Int_t) buffer[i];
255 pbusHeader.SetHeader(pbusHeaderWord);
256 Int_t rawdatalength = pbusHeader.GetRawDataLength();
257 Int_t pbusid = pbusHeader.GetPatchBusId();
259 ilowLimit = iuppLimit;
260 iuppLimit = ilowLimit + rawdatalength;
262 Int_t imodule = moduleNo[pbusid];
265 for (Int_t iword = ilowLimit; iword < iuppLimit; iword++)
268 data = buffer[iword];
270 Int_t isig = data & 0x0FFF;
271 Int_t ich = (data >> 12) & 0x003F;
272 Int_t imcm = (data >> 18) & 0x07FF;
273 Int_t ibit = (data >> 31) & 0x0001;
274 parity = ComputeParity(data);
277 AliWarning("ComputeParity:: Parity Error");
278 fRawReader->AddMajorErrorLog(kParityError);
281 ConvertDDL2SMN(iddl, imodule, ismn, idet);
283 GetRowCol(iddl, ismn, pbusid, imcm, ich,
284 startRowBus, endRowBus,
285 startColBus, endColBus,
288 TransformH2S(ismn, irow, icol);
290 pmdddldata = new AliPMDddldata();
292 pmdddldata->SetDetector(idet);
293 pmdddldata->SetSMN(ismn);
294 pmdddldata->SetModule(imodule);
295 pmdddldata->SetPatchBusId(pbusid);
296 pmdddldata->SetMCM(imcm);
297 pmdddldata->SetChannel(ich);
298 pmdddldata->SetRow(irow);
299 pmdddldata->SetColumn(icol);
300 pmdddldata->SetSignal(isig);
301 pmdddldata->SetParityBit(ibit);
303 pmdddlcont->Add(pmdddldata);
307 if (iwordcount == blRawDataLength) break;
311 if (dspHeader.GetPaddingWord() == 1) iuppLimit++;
312 if (iwordcount == blRawDataLength) break;
315 if (iwordcount == blRawDataLength) break;
323 //_____________________________________________________________________________
324 void AliPMDRawStream::GetRowCol(Int_t ddlno, Int_t smn, Int_t pbusid,
325 UInt_t mcmno, UInt_t chno,
326 Int_t startRowBus[], Int_t endRowBus[],
327 Int_t startColBus[], Int_t endColBus[],
328 Int_t &row, Int_t &col) const
330 // decode: ddlno, patchbusid, mcmno, chno -> um, row, col
336 static const UInt_t kChDdl01[64] = { 9, 6, 5, 10, 1, 2, 0, 3,
337 13, 7, 4, 11, 8, 14, 12, 15,
338 16, 19, 17, 23, 20, 27, 24, 18,
339 28, 31, 29, 30, 21, 26, 25, 22,
340 41, 38, 37, 42, 33, 34, 32, 35,
341 45, 39, 36, 43, 40, 46, 44, 47,
342 48, 51, 49, 55, 52, 59, 56, 50,
343 60, 63, 61, 62, 53, 58, 57, 54 };
345 static const UInt_t kChDdl23[64] = { 54, 57, 58, 53, 62, 61, 63, 60,
346 50, 56, 59, 52, 55, 49, 51, 48,
347 47, 44, 46, 40, 43, 36, 39, 45,
348 35, 32, 34, 33, 42, 37, 38, 41,
349 22, 25, 26, 21, 30, 29, 31, 28,
350 18, 24, 27, 20, 23, 17, 19, 16,
351 15, 12, 14, 8, 11, 4, 7, 13,
352 3, 0, 2, 1, 10, 5, 6, 9 };
354 static const UInt_t kChDdl41[64] = { 53, 58, 57, 54, 61, 62, 60, 63,
355 49, 59, 56, 55, 52, 50, 48, 51,
356 44, 47, 45, 43, 40, 39, 36, 46,
357 32, 35, 33, 34, 41, 38, 37, 42,
358 21, 26, 25, 22, 29, 30, 28, 31,
359 17, 27, 24, 23, 20, 18, 16, 19,
360 12, 15, 13, 11, 8, 7, 4, 14,
361 0, 3, 1, 2, 9, 6, 5, 10 };
363 static const UInt_t kChDdl42[64] = { 10, 5, 6, 9, 2, 1, 3, 0,
364 14, 4, 7, 8, 11, 13, 15, 12,
365 19, 16, 18, 20, 23, 24, 27, 17,
366 31, 28, 30, 29, 22, 25, 26, 21,
367 42, 37, 38, 41, 34, 33, 35, 32,
368 46, 36, 39, 40, 43, 45, 47, 44,
369 51, 48, 50, 52, 55, 56, 59, 49,
370 63, 60, 62, 61, 54, 57, 58, 53 };
372 static const UInt_t kChDdl51[64] = { 10, 5, 6, 9, 2, 1, 3, 0,
373 14, 4, 7, 8, 11, 13, 15, 12,
374 19, 16, 18, 20, 23, 24, 27, 17,
375 31, 28, 30, 29, 22, 25, 26, 21,
376 42, 37, 38, 41, 34, 33, 35, 32,
377 46, 36, 39, 40, 43, 45, 47, 44,
378 51, 48, 50, 52, 55, 56, 59, 49,
379 63, 60, 62, 61, 54, 57, 58, 53 };
381 static const UInt_t kChDdl52[64] = { 53, 58, 57, 54, 61, 62, 60, 63,
382 49, 59, 56, 55, 52, 50, 48, 51,
383 44, 47, 45, 43, 40, 39, 36, 46,
384 32, 35, 33, 34, 41, 38, 37, 42,
385 21, 26, 25, 22, 29, 30, 28, 31,
386 17, 27, 24, 23, 20, 18, 16, 19,
387 12, 15, 13, 11, 8, 7, 4, 14,
388 0, 3, 1, 2, 9, 6, 5, 10 };
390 for (Int_t i = 0; i < 64; i++)
392 if (ddlno == 0 || ddlno == 1) iCh[i] = kChDdl01[i];
393 if (ddlno == 2 || ddlno == 3) iCh[i] = kChDdl23[i];
395 if (ddlno == 4 && smn < 6) iCh[i] = kChDdl41[i];
396 if (ddlno == 4 && (smn >= 18 && smn < 24))iCh[i] = kChDdl42[i];
397 if (ddlno == 5 && (smn >= 12 && smn < 18))iCh[i] = kChDdl51[i];
398 if (ddlno == 5 && (smn >= 6 && smn < 12))iCh[i] = kChDdl52[i];
402 Int_t rowcol = iCh[chno];
403 Int_t irownew = rowcol/4;
404 Int_t icolnew = rowcol%4;
408 row = startRowBus[pbusid] + irownew;
409 col = startColBus[pbusid] + (mcmno-1)*4 + icolnew;
413 row = endRowBus[pbusid] - (15 - irownew);
414 col = startColBus[pbusid] + (mcmno-1)*4 + icolnew;
417 else if (ddlno == 2 )
419 row = startRowBus[pbusid] + irownew;
420 col = endColBus[pbusid] - (mcmno-1)*4 - (3 - icolnew);
424 row = endRowBus[pbusid] - (15 - irownew);
425 col = endColBus[pbusid] - (mcmno-1)*4 - (3 - icolnew);
427 else if (ddlno == 4 )
433 // Add 16 to skip the 1st 15 rows
434 row = startRowBus[pbusid] + irownew + 16;
435 col = startColBus[pbusid] + (mcmno-1)*4 + icolnew;
439 row = startRowBus[pbusid] + irownew;
440 col = startColBus[pbusid] + (mcmno-12-1)*4 + icolnew;
447 col = endColBus[pbusid] - (mcmno-1)*4 - (3 - icolnew);
449 if(endRowBus[pbusid] - startRowBus[pbusid] > 16)
450 row = endRowBus[pbusid] - (15 - irownew) - 16 ;
452 row = endRowBus[pbusid] - (15 - irownew) ;
456 row = endRowBus[pbusid] - (15 - irownew) ;
457 col = endColBus[pbusid] - (mcmno - 12 - 1)*4 - (3 - icolnew);
467 // Subtract 16 to skip the 1st 15 rows
468 row = endRowBus[pbusid] - 16 -(15 - irownew);
469 col = startColBus[pbusid] + (mcmno-12 -1)*4 + icolnew;
473 row = endRowBus[pbusid] - (15 - irownew) ;
474 col = startColBus[pbusid] + (mcmno -1)*4 + icolnew;
479 else if (pbusid > 18)
483 // Add 16 to skip the 1st 15 rows
484 row = startRowBus[pbusid] + irownew + 16;
485 col = endColBus[pbusid] - (mcmno - 12 - 1)*4 - (3 - icolnew);
489 row = startRowBus[pbusid] + irownew ;
490 col = endColBus[pbusid] - (mcmno - 1)*4 - (3 - icolnew);
496 //_____________________________________________________________________________
497 void AliPMDRawStream::ConvertDDL2SMN(Int_t iddl, Int_t imodule,
498 Int_t &smn, Int_t &detector) const
500 // This converts the DDL number (0 to 5), Module Number (0-47)
501 // to Serial module number in one detector (SMN : 0-23) and
502 // detector number (0:PRE plane, 1:CPV plane)
514 //_____________________________________________________________________________
516 void AliPMDRawStream::TransformH2S(Int_t smn, Int_t &row, Int_t &col) const
518 // This does the transformation of the hardware coordinate to
520 // i.e., For SuperModule 0 &1, instead of 96x48(hardware),
521 // it is 48x96 (software)
522 // For Supermodule 3 & 4, 48x96
532 else if(smn >= 12 && smn < 24)
541 //_____________________________________________________________________________
542 Int_t AliPMDRawStream::ComputeParity(Int_t data)
544 // Calculate the parity bit
547 for(Int_t j = 0; j<29; j++)
549 if (data & 0x01 ) count++;
553 Int_t parity = count%2;
558 //_____________________________________________________________________________