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
89 AliPMDddldata *pmdddldata;
91 if (!fRawReader->ReadHeader()) return kFALSE;
92 Int_t iddl = fRawReader->GetDDLID();
93 Int_t dataSize = fRawReader->GetDataSize();
94 Int_t totaldataword = dataSize/4;
96 if (dataSize <= 0) return kFALSE;
99 AliError("Mismatch in the DDL index");
104 buffer = new UInt_t[totaldataword];
106 for (Int_t i = 0; i < totaldataword; i++)
108 fRawReader->ReadNextInt(data);
112 // --- Open the mapping file
114 TString fileName(gSystem->Getenv("ALICE_ROOT"));
117 fileName += "/PMD/PMD_Mapping_ddl0.dat";
121 fileName += "/PMD/PMD_Mapping_ddl1.dat";
125 fileName += "/PMD/PMD_Mapping_ddl2.dat";
129 fileName += "/PMD/PMD_Mapping_ddl3.dat";
133 fileName += "/PMD/PMD_Mapping_ddl4.dat";
137 fileName += "/PMD/PMD_Mapping_ddl5.dat";
141 infile.open(fileName.Data(), ios::in); // ascii file
143 AliError(Form("Could not read the mapping file for DDL No = %d",iddl));
145 Int_t modulePerDDL = 0;
150 else if (iddl == 4 || iddl == 5)
155 const Int_t kNPatchBus = 50;
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];
164 for (Int_t ibus = 0; ibus < kNPatchBus; ibus++)
166 mcmperBus[ibus] = -1;
167 startRowBus[ibus] = -1;
168 endRowBus[ibus] = -1;
169 startColBus[ibus] = -1;
170 endColBus[ibus] = -1;
174 for (Int_t im = 0; im < modulePerDDL; im++)
177 infile >> totPatchBus >> bPatchBus >> ePatchBus;
179 for(Int_t i=0; i<totPatchBus; i++)
181 infile >> ibus >> totmcm >> rows >> rowe >> cols >> cole;
183 moduleNo[ibus] = modno;
184 mcmperBus[ibus] = totmcm;
185 startRowBus[ibus] = rows;
186 endRowBus[ibus] = rowe;
187 startColBus[ibus] = cols;
188 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];
217 Int_t blRawDataLength = 0;
218 Int_t iwordcount = 0;
221 for (Int_t iblock = 0; iblock < 2; iblock++)
223 ilowLimit = iuppLimit;
224 iuppLimit = ilowLimit + kblHLen;
227 for (Int_t i = ilowLimit; i < iuppLimit; i++)
229 blHeaderWord[i-ilowLimit] = (Int_t) buffer[i];
232 blockHeader.SetHeader(blHeaderWord);
234 blRawDataLength = blockHeader.GetRawDataLength();
236 for (Int_t idsp = 0; idsp < 5; idsp++)
238 ilowLimit = iuppLimit;
239 iuppLimit = ilowLimit + kdspHLen;
241 for (Int_t i = ilowLimit; i < iuppLimit; i++)
244 dspHeaderWord[i-ilowLimit] = (Int_t) buffer[i];
246 dspHeader.SetHeader(dspHeaderWord);
248 for (Int_t ibus = 0; ibus < 5; ibus++)
251 ilowLimit = iuppLimit;
252 iuppLimit = ilowLimit + kpbusHLen;
254 for (Int_t i = ilowLimit; i < iuppLimit; i++)
257 pbusHeaderWord[i-ilowLimit] = (Int_t) buffer[i];
259 pbusHeader.SetHeader(pbusHeaderWord);
260 Int_t rawdatalength = pbusHeader.GetRawDataLength();
261 Int_t pbusid = pbusHeader.GetPatchBusId();
263 ilowLimit = iuppLimit;
264 iuppLimit = ilowLimit + rawdatalength;
266 Int_t imodule = moduleNo[pbusid];
269 for (Int_t iword = ilowLimit; iword < iuppLimit; iword++)
272 data = buffer[iword];
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;
279 parity = ComputeParity(data);
282 AliWarning("ComputeParity:: Parity Error");
284 GetRowCol(iddl, pbusid, imcm, ich,
285 startRowBus, endRowBus,
286 startColBus, endColBus,
289 ConvertDDL2SMN(iddl, imodule, ismn, idet);
290 TransformH2S(ismn, irow, icol);
292 pmdddldata = new AliPMDddldata();
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);
305 pmdddlcont->Add(pmdddldata);
309 if (iwordcount == blRawDataLength) break;
313 if (dspHeader.GetPaddingWord() == 1) iuppLimit++;
314 if (iwordcount == blRawDataLength) break;
317 if (iwordcount == blRawDataLength) break;
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
333 // decode: ddlno, patchbusid, mcmno, chno -> um, row, col
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 };
346 Int_t rowcol = kCh[chno];
347 Int_t irownew = rowcol/4;
348 Int_t icolnew = rowcol%4;
356 row = startRowBus[pbusid] + irownew;
357 col = startColBus[pbusid] + (mcmno-12)*4 + icolnew;
361 // Add 16 to skip the 1st 15 rows
362 row = startRowBus[pbusid] + irownew + 16;
363 col = startColBus[pbusid] + mcmno*4 + icolnew;
368 row = startRowBus[pbusid] + irownew;
369 col = startColBus[pbusid] + mcmno*4 + icolnew;
379 row = endRowBus[pbusid] - (15 - irownew);
380 col = startColBus[pbusid] + (mcmno-12)*4 + icolnew;
384 // Subtract 16 to skip the 1st 15 rows
385 row = endRowBus[pbusid] - 16 - (15 - irownew) ;
386 col = startColBus[pbusid] + mcmno*4 + icolnew;
391 row = endRowBus[pbusid] - (15 - irownew);
392 col = startColBus[pbusid] + mcmno*4 + icolnew;
397 row = startRowBus[pbusid] + irownew;
398 col = endColBus[pbusid] - mcmno*4 - (3 - icolnew);
402 row = endRowBus[pbusid] - (15 - irownew);
403 col = endColBus[pbusid] - mcmno*4 - (3 - icolnew);
411 row = startRowBus[pbusid] + irownew;
412 col = startColBus[pbusid] + (mcmno-12)*4 + icolnew;
416 // Add 16 to skip the 1st 15 rows
417 row = startRowBus[pbusid] + irownew + 16;
418 col = startColBus[pbusid] + mcmno*4 + icolnew;
421 else if (pbusid > 16 && pbusid <= 20)
423 row = startRowBus[pbusid] + irownew;
424 col = startColBus[pbusid] + mcmno*4 + icolnew;
429 row = endRowBus[pbusid] - (15 - irownew);
430 col = endColBus[pbusid] - mcmno*4 - (3 - icolnew);
439 row = endRowBus[pbusid] - (15 - irownew);
440 col = startColBus[pbusid] + (mcmno-12)*4 + icolnew;
444 // Subtract 16 to skip the 1st 15 rows
445 row = endRowBus[pbusid] - 16 - (15 - irownew) ;
446 col = startColBus[pbusid] + mcmno*4 + icolnew;
449 else if (pbusid > 16 && pbusid <= 20)
451 row = endRowBus[pbusid] - (15 - irownew);
452 col = startColBus[pbusid] + mcmno*4 + icolnew;
454 else if (pbusid > 20)
456 row = startRowBus[pbusid] + irownew;
457 col = endColBus[pbusid] - mcmno*4 - (3 - icolnew);
461 //_____________________________________________________________________________
462 void AliPMDRawStream::ConvertDDL2SMN(Int_t iddl, Int_t imodule,
463 Int_t &smn, Int_t &detector) const
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)
479 //_____________________________________________________________________________
480 void AliPMDRawStream::TransformH2S(Int_t smn, Int_t &row, Int_t &col) const
482 // This does the transformation of the hardware coordinate to
484 // i.e., For SuperModule 0 &1, instead of 96x48(hardware),
485 // it is 48x96 (software)
486 // For Supermodule 3 & 4, 48x96
496 else if(smn >= 12 && smn < 24)
506 //_____________________________________________________________________________
508 int AliPMDRawStream::ComputeParity(Int_t data)
510 // Calculate the parity bit
513 for(Int_t j = 0; j<29; j++)
515 if (data & 0x01 ) count++;
519 Int_t parity = count%2;
524 //_____________________________________________________________________________