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 AliWarning("Mismatch in the DDL index");
100 fRawReader->AddFatalErrorLog(kDDLIndexMismatch);
105 buffer = new UInt_t[totaldataword];
107 for (Int_t i = 0; i < totaldataword; i++)
109 fRawReader->ReadNextInt(data);
113 // --- Open the mapping file
115 TString fileName(gSystem->Getenv("ALICE_ROOT"));
118 fileName += "/PMD/PMD_Mapping_ddl0.dat";
122 fileName += "/PMD/PMD_Mapping_ddl1.dat";
126 fileName += "/PMD/PMD_Mapping_ddl2.dat";
130 fileName += "/PMD/PMD_Mapping_ddl3.dat";
134 fileName += "/PMD/PMD_Mapping_ddl4.dat";
138 fileName += "/PMD/PMD_Mapping_ddl5.dat";
142 infile.open(fileName.Data(), ios::in); // ascii file
144 AliError(Form("Could not read the mapping file for DDL No = %d",iddl));
145 fRawReader->AddFatalErrorLog(kNoMappingFile,Form("ddl=%d",iddl));
148 Int_t modulePerDDL = 0;
153 else if (iddl == 4 || iddl == 5)
158 const Int_t kNPatchBus = 50;
160 Int_t modno, totPatchBus, bPatchBus, ePatchBus;
161 Int_t ibus, totmcm, rows, rowe, cols, cole;
162 Int_t moduleNo[kNPatchBus], mcmperBus[kNPatchBus];
163 Int_t startRowBus[kNPatchBus], endRowBus[kNPatchBus];
164 Int_t startColBus[kNPatchBus], endColBus[kNPatchBus];
166 for (Int_t ibus = 0; ibus < kNPatchBus; ibus++)
168 mcmperBus[ibus] = -1;
169 startRowBus[ibus] = -1;
170 endRowBus[ibus] = -1;
171 startColBus[ibus] = -1;
172 endColBus[ibus] = -1;
175 for (Int_t im = 0; im < modulePerDDL; im++)
178 infile >> totPatchBus >> bPatchBus >> ePatchBus;
180 for(Int_t i=0; i<totPatchBus; i++)
182 infile >> ibus >> totmcm >> rows >> rowe >> cols >> cole;
184 moduleNo[ibus] = modno;
185 mcmperBus[ibus] = totmcm;
186 startRowBus[ibus] = rows;
187 endRowBus[ibus] = rowe;
188 startColBus[ibus] = cols;
189 endColBus[ibus] = cole;
195 AliPMDBlockHeader blockHeader;
196 AliPMDDspHeader dspHeader;
197 AliPMDPatchBusHeader pbusHeader;
199 const Int_t kblHLen = blockHeader.GetHeaderLength();
200 const Int_t kdspHLen = dspHeader.GetHeaderLength();
201 const Int_t kpbusHLen = pbusHeader.GetHeaderLength();
208 Int_t blHeaderWord[8];
209 Int_t dspHeaderWord[10];
210 Int_t pbusHeaderWord[4];
214 Int_t blRawDataLength = 0;
215 Int_t iwordcount = 0;
218 for (Int_t iblock = 0; iblock < 2; iblock++)
220 ilowLimit = iuppLimit;
221 iuppLimit = ilowLimit + kblHLen;
223 for (Int_t i = ilowLimit; i < iuppLimit; i++)
225 blHeaderWord[i-ilowLimit] = (Int_t) buffer[i];
228 blockHeader.SetHeader(blHeaderWord);
230 blRawDataLength = blockHeader.GetRawDataLength();
232 for (Int_t idsp = 0; idsp < 5; idsp++)
234 ilowLimit = iuppLimit;
235 iuppLimit = ilowLimit + kdspHLen;
237 for (Int_t i = ilowLimit; i < iuppLimit; i++)
240 dspHeaderWord[i-ilowLimit] = (Int_t) buffer[i];
242 dspHeader.SetHeader(dspHeaderWord);
244 for (Int_t ibus = 0; ibus < 5; ibus++)
246 ilowLimit = iuppLimit;
247 iuppLimit = ilowLimit + kpbusHLen;
249 for (Int_t i = ilowLimit; i < iuppLimit; i++)
252 pbusHeaderWord[i-ilowLimit] = (Int_t) buffer[i];
254 pbusHeader.SetHeader(pbusHeaderWord);
255 Int_t rawdatalength = pbusHeader.GetRawDataLength();
256 Int_t pbusid = pbusHeader.GetPatchBusId();
258 ilowLimit = iuppLimit;
259 iuppLimit = ilowLimit + rawdatalength;
261 Int_t imodule = moduleNo[pbusid];
264 for (Int_t iword = ilowLimit; iword < iuppLimit; iword++)
267 data = buffer[iword];
269 Int_t isig = data & 0x0FFF;
270 Int_t ich = (data >> 12) & 0x003F;
271 Int_t imcm = (data >> 18) & 0x07FF;
272 Int_t ibit = (data >> 31) & 0x0001;
273 parity = ComputeParity(data);
276 AliWarning("ComputeParity:: Parity Error");
277 fRawReader->AddMajorErrorLog(kParityError);
279 GetRowCol(iddl, pbusid, imcm, ich,
280 startRowBus, endRowBus,
281 startColBus, endColBus,
284 ConvertDDL2SMN(iddl, imodule, ismn, idet);
285 TransformH2S(ismn, irow, icol);
287 pmdddldata = new AliPMDddldata();
289 pmdddldata->SetDetector(idet);
290 pmdddldata->SetSMN(ismn);
291 pmdddldata->SetModule(imodule);
292 pmdddldata->SetPatchBusId(pbusid);
293 pmdddldata->SetMCM(imcm);
294 pmdddldata->SetChannel(ich);
295 pmdddldata->SetRow(irow);
296 pmdddldata->SetColumn(icol);
297 pmdddldata->SetSignal(isig);
298 pmdddldata->SetParityBit(ibit);
300 pmdddlcont->Add(pmdddldata);
304 if (iwordcount == blRawDataLength) break;
308 if (dspHeader.GetPaddingWord() == 1) iuppLimit++;
309 if (iwordcount == blRawDataLength) break;
312 if (iwordcount == blRawDataLength) break;
320 //_____________________________________________________________________________
321 void AliPMDRawStream::GetRowCol(Int_t ddlno, Int_t pbusid,
322 UInt_t mcmno, UInt_t chno,
323 Int_t startRowBus[], Int_t endRowBus[],
324 Int_t startColBus[], Int_t endColBus[],
325 Int_t &row, Int_t &col) const
327 // decode: ddlno, patchbusid, mcmno, chno -> um, row, col
330 static const UInt_t kCh[64] = { 53, 58, 57, 54, 61, 62, 60, 63,
331 49, 59, 56, 55, 52, 50, 48, 51,
332 44, 47, 45, 43, 40, 39, 36, 46,
333 32, 35, 33, 34, 41, 38, 37, 42,
334 21, 26, 25, 22, 29, 30, 28, 31,
335 17, 27, 24, 23, 20, 18, 16, 19,
336 12, 15, 13, 11, 8, 7, 4, 14,
337 0, 3, 1, 2, 9, 6, 5, 10 };
340 Int_t rowcol = kCh[chno];
341 Int_t irownew = rowcol/4;
342 Int_t icolnew = rowcol%4;
346 row = startRowBus[pbusid] + irownew;
347 col = startColBus[pbusid] + mcmno*4 + icolnew;
351 row = endRowBus[pbusid] - (15 - irownew);
352 col = startColBus[pbusid] + mcmno*4 + icolnew;
355 else if (ddlno == 2 )
357 row = startRowBus[pbusid] + irownew;
358 col = endColBus[pbusid] - mcmno*4 - (3 - icolnew);
362 row = endRowBus[pbusid] - (15 - irownew);
363 col = endColBus[pbusid] - mcmno*4 - (3 - icolnew);
365 else if (ddlno == 4 )
371 // Add 16 to skip the 1st 15 rows
372 row = startRowBus[pbusid] + irownew + 16;
373 col = startColBus[pbusid] + (mcmno)*4 + icolnew;
377 row = startRowBus[pbusid] + irownew;
378 col = startColBus[pbusid] + (mcmno-12)*4 + icolnew;
385 col = endColBus[pbusid] - mcmno*4 - (3 - icolnew);
387 if(endRowBus[pbusid] - startRowBus[pbusid] > 16)
388 row = endRowBus[pbusid] - (15 - irownew) - 16 ;
390 row = endRowBus[pbusid] - (15 - irownew) ;
396 row = endRowBus[pbusid] - (15 - irownew) ;
397 col = endColBus[pbusid] - (mcmno - 12)*4 - (3 - icolnew);
407 // Subtract 16 to skip the 1st 15 rows
408 row = endRowBus[pbusid] - 16 -(15 - irownew);
409 col = startColBus[pbusid] + (mcmno-12)*4 + icolnew;
413 row = endRowBus[pbusid] - (15 - irownew) ;
414 col = startColBus[pbusid] + mcmno*4 + icolnew;
418 else if (pbusid > 17)
422 // Add 16 to skip the 1st 15 rows
423 row = startRowBus[pbusid] + irownew + 16;
424 col = endColBus[pbusid] - (mcmno - 12)*4 - (3 - icolnew);
428 row = startRowBus[pbusid] + irownew ;
429 col = endColBus[pbusid] - mcmno*4 - (3 - icolnew);
435 //_____________________________________________________________________________
436 void AliPMDRawStream::ConvertDDL2SMN(Int_t iddl, Int_t imodule,
437 Int_t &smn, Int_t &detector) const
439 // This converts the DDL number (0 to 5), Module Number (0-47)
440 // to Serial module number in one detector (SMN : 0-23) and
441 // detector number (0:PRE plane, 1:CPV plane)
453 //_____________________________________________________________________________
454 void AliPMDRawStream::TransformH2S(Int_t smn, Int_t &row, Int_t &col) const
456 // This does the transformation of the hardware coordinate to
458 // i.e., For SuperModule 0 &1, instead of 96x48(hardware),
459 // it is 48x96 (software)
460 // For Supermodule 3 & 4, 48x96
470 else if(smn >= 12 && smn < 24)
479 //_____________________________________________________________________________
480 Int_t AliPMDRawStream::ComputeParity(Int_t data)
482 // Calculate the parity bit
485 for(Int_t j = 0; j<29; j++)
487 if (data & 0x01 ) count++;
491 Int_t parity = count%2;
496 //_____________________________________________________________________________