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 "AliPMDMappingData.h"
41 #include "AliRawReader.h"
42 #include "AliCDBManager.h"
43 #include "AliCDBStorage.h"
44 #include "AliCDBEntry.h"
46 ClassImp(AliPMDRawStream)
49 //_____________________________________________________________________________
50 AliPMDRawStream::AliPMDRawStream(AliRawReader* rawReader) :
51 fRawReader(rawReader),
54 fMapData(GetMappingData())
56 // create an object to read PMD raw digits
59 fRawReader->Select("PMD");
62 //_____________________________________________________________________________
63 AliPMDRawStream::AliPMDRawStream(const AliPMDRawStream& stream) :
68 fMapData(GetMappingData())
72 AliFatal("Copy constructor not implemented");
75 //_____________________________________________________________________________
76 AliPMDRawStream& AliPMDRawStream::operator = (const AliPMDRawStream&
79 // assignment operator
81 AliFatal("operator = assignment operator not implemented");
85 //_____________________________________________________________________________
86 AliPMDRawStream::~AliPMDRawStream()
93 //_____________________________________________________________________________
95 Int_t AliPMDRawStream::DdlData(TObjArray *pmdddlcont)
97 // read the next raw digit
98 // returns kFALSE if there is no digit left
102 AliPMDddldata *pmdddldata;
104 if (!fRawReader->ReadHeader()) return -1;
106 iddl = fRawReader->GetDDLID();
107 Int_t dataSize = fRawReader->GetDataSize();
108 Int_t totaldataword = dataSize/4;
111 if (dataSize <= 0) return -1;
115 fRawReader->ReadNextData(fData);
122 const Int_t kNPatchBus = 51;
124 Int_t moduleNo[kNPatchBus], mcmperBus[kNPatchBus];
125 Int_t startRowBus[kNPatchBus], endRowBus[kNPatchBus];
126 Int_t startColBus[kNPatchBus], endColBus[kNPatchBus];
128 for (ibus = 0; ibus < kNPatchBus; ibus++)
131 mcmperBus[ibus] = -1;
132 startRowBus[ibus] = -1;
133 endRowBus[ibus] = -1;
134 startColBus[ibus] = -1;
135 endColBus[ibus] = -1;
140 Ddl0Mapping(moduleNo, mcmperBus, startRowBus,
141 endRowBus, startColBus, endColBus);
146 Ddl1Mapping(moduleNo, mcmperBus, startRowBus,
147 endRowBus, startColBus, endColBus);
152 Ddl2Mapping(moduleNo, mcmperBus, startRowBus,
153 endRowBus, startColBus, endColBus);
157 Ddl3Mapping(moduleNo, mcmperBus, startRowBus,
158 endRowBus, startColBus, endColBus);
162 Ddl4Mapping(moduleNo, mcmperBus, startRowBus,
163 endRowBus, startColBus, endColBus);
167 Ddl5Mapping(moduleNo, mcmperBus, startRowBus,
168 endRowBus, startColBus, endColBus);
172 AliPMDBlockHeader blockHeader;
173 AliPMDDspHeader dspHeader;
174 AliPMDPatchBusHeader pbusHeader;
176 const Int_t kblHLen = blockHeader.GetHeaderLength();
177 const Int_t kdspHLen = dspHeader.GetHeaderLength();
178 const Int_t kpbusHLen = pbusHeader.GetHeaderLength();
185 Int_t blHeaderWord[8];
186 Int_t dspHeaderWord[10];
187 Int_t pbusHeaderWord[4];
189 Int_t blRawDataLength = 0;
190 Int_t dspRawDataLength = 0;
195 for (Int_t iblock = 0; iblock < 2; iblock++)
197 for (Int_t i = 0; i < kblHLen; i++)
201 blHeaderWord[i] = (Int_t) GetNextWord();
204 blockHeader.SetHeader(blHeaderWord);
205 blRawDataLength = blockHeader.GetRawDataLength();
207 if (iwordddl == totaldataword) break;
211 for (Int_t idsp = 0; idsp < 5; idsp++)
213 for (Int_t i = 0; i < kdspHLen; i++)
217 dspHeaderWord[i] = (Int_t) GetNextWord();
219 dspHeader.SetHeader(dspHeaderWord);
220 dspRawDataLength = dspHeader.GetRawDataLength();
222 if (iwordddl == totaldataword) break;
226 for (ibus = 0; ibus < 5; ibus++)
228 for (Int_t i = 0; i < kpbusHLen; i++)
233 pbusHeaderWord[i] = (Int_t) GetNextWord();
236 pbusHeader.SetHeader(pbusHeaderWord);
237 Int_t rawdatalength = pbusHeader.GetRawDataLength();
238 Int_t pbusid = pbusHeader.GetPatchBusId();
240 if (pbusid < 0 || pbusid > 50) return -1;
242 Int_t imodule = moduleNo[pbusid];
244 if (iwordddl == totaldataword) break;
246 for (Int_t iword = 0; iword < rawdatalength; iword++)
252 data = GetNextWord();
254 Int_t isig = data & 0x0FFF;
255 Int_t ich = (data >> 12) & 0x003F;
256 Int_t imcm = (data >> 18) & 0x07FF;
257 Int_t ibit = (data >> 31) & 0x0001;
261 AliWarning(Form("FEE address WRONG:: Module %d Patch Bus %d MCM %d",imodule,pbusid,imcm));
265 parity = ComputeParity(data);
269 AliWarning(Form("Parity Error:: Patch Bus %d Module %d",pbusid,imodule));
270 fRawReader->AddMajorErrorLog(kParityError);
274 ConvertDDL2SMN(iddl, imodule, ismn, idet);
276 GetRowCol(imodule, pbusid, imcm, ich,
277 startRowBus, endRowBus,
278 startColBus, endColBus,
282 TransformH2S(ismn, irow, icol);
284 pmdddldata = new AliPMDddldata();
286 pmdddldata->SetDetector(idet);
287 pmdddldata->SetSMN(ismn);
288 pmdddldata->SetModule(imodule);
289 pmdddldata->SetPatchBusId(pbusid);
290 pmdddldata->SetMCM(imcm);
291 pmdddldata->SetChannel(ich);
292 pmdddldata->SetRow(irow);
293 pmdddldata->SetColumn(icol);
294 pmdddldata->SetSignal(isig);
295 pmdddldata->SetParityBit(ibit);
297 pmdddlcont->Add(pmdddldata);
302 if (iwordddl == totaldataword) break;
304 if (dspHeader.GetPaddingWord() == 1)
306 if (iworddsp == dspRawDataLength-1) break; // raw data
310 if (iworddsp == dspRawDataLength) break; // raw data
317 if (dspHeader.GetPaddingWord() == 1)
322 data = GetNextWord();
324 if (iwordddl == totaldataword) break;
326 if (iwordblk == blRawDataLength) break; // for raw data
335 //_____________________________________________________________________________
336 void AliPMDRawStream::GetRowCol(Int_t imodule, Int_t pbusid,
337 UInt_t mcmno, UInt_t chno,
338 Int_t startRowBus[], Int_t endRowBus[],
339 Int_t startColBus[], Int_t endColBus[],
340 Int_t &row, Int_t &col) const
342 // decode: ddlno, patchbusid, mcmno, chno -> um, row, col
346 static const UInt_t kChDdl01[64] = { 9, 6, 5, 10, 1, 2, 0, 3,
347 13, 7, 4, 11, 8, 14, 12, 15,
348 16, 19, 17, 23, 20, 27, 24, 18,
349 28, 31, 29, 30, 21, 26, 25, 22,
350 41, 38, 37, 42, 33, 34, 32, 35,
351 45, 39, 36, 43, 40, 46, 44, 47,
352 48, 51, 49, 55, 52, 59, 56, 50,
353 60, 63, 61, 62, 53, 58, 57, 54 };
355 static const UInt_t kChDdl23[64] = { 54, 57, 58, 53, 62, 61, 63, 60,
356 50, 56, 59, 52, 55, 49, 51, 48,
357 47, 44, 46, 40, 43, 36, 39, 45,
358 35, 32, 34, 33, 42, 37, 38, 41,
359 22, 25, 26, 21, 30, 29, 31, 28,
360 18, 24, 27, 20, 23, 17, 19, 16,
361 15, 12, 14, 8, 11, 4, 7, 13,
362 3, 0, 2, 1, 10, 5, 6, 9 };
364 static const UInt_t kChDdl41[64] = { 53, 58, 57, 54, 61, 62, 60, 63,
365 49, 59, 56, 55, 52, 50, 48, 51,
366 44, 47, 45, 43, 40, 39, 36, 46,
367 32, 35, 33, 34, 41, 38, 37, 42,
368 21, 26, 25, 22, 29, 30, 28, 31,
369 17, 27, 24, 23, 20, 18, 16, 19,
370 12, 15, 13, 11, 8, 7, 4, 14,
371 0, 3, 1, 2, 9, 6, 5, 10 };
373 static const UInt_t kChDdl42[64] = { 10, 5, 6, 9, 2, 1, 3, 0,
374 14, 4, 7, 8, 11, 13, 15, 12,
375 19, 16, 18, 20, 23, 24, 27, 17,
376 31, 28, 30, 29, 22, 25, 26, 21,
377 42, 37, 38, 41, 34, 33, 35, 32,
378 46, 36, 39, 40, 43, 45, 47, 44,
379 51, 48, 50, 52, 55, 56, 59, 49,
380 63, 60, 62, 61, 54, 57, 58, 53 };
382 static const UInt_t kChDdl51[64] = { 10, 5, 6, 9, 2, 1, 3, 0,
383 14, 4, 7, 8, 11, 13, 15, 12,
384 19, 16, 18, 20, 23, 24, 27, 17,
385 31, 28, 30, 29, 22, 25, 26, 21,
386 42, 37, 38, 41, 34, 33, 35, 32,
387 46, 36, 39, 40, 43, 45, 47, 44,
388 51, 48, 50, 52, 55, 56, 59, 49,
389 63, 60, 62, 61, 54, 57, 58, 53 };
391 static const UInt_t kChDdl52[64] = { 53, 58, 57, 54, 61, 62, 60, 63,
392 49, 59, 56, 55, 52, 50, 48, 51,
393 44, 47, 45, 43, 40, 39, 36, 46,
394 32, 35, 33, 34, 41, 38, 37, 42,
395 21, 26, 25, 22, 29, 30, 28, 31,
396 17, 27, 24, 23, 20, 18, 16, 19,
397 12, 15, 13, 11, 8, 7, 4, 14,
398 0, 3, 1, 2, 9, 6, 5, 10 };
400 for (Int_t i = 0; i < 64; i++)
402 if(imodule < 6) iCh[i] = kChDdl01[i];
403 if(imodule >= 6 && imodule <= 11) iCh[i] = kChDdl01[i];
404 if(imodule >= 12 && imodule <= 17) iCh[i] = kChDdl23[i];
405 if(imodule >= 18 && imodule <= 23) iCh[i] = kChDdl23[i];
406 if(imodule >= 24 && imodule <= 29) iCh[i] = kChDdl41[i];
407 if(imodule >= 42 && imodule <= 47) iCh[i] = kChDdl42[i];
408 if(imodule >= 36 && imodule <= 41) iCh[i] = kChDdl51[i];
409 if(imodule >= 30 && imodule <= 35) iCh[i] = kChDdl52[i];
413 Int_t rowcol = iCh[chno];
414 Int_t irownew = rowcol/4;
415 Int_t icolnew = rowcol%4;
420 row = startRowBus[pbusid] + irownew;
421 col = startColBus[pbusid] + (mcmno-1)*4 + icolnew;
423 else if (imodule >= 6 && imodule < 12)
425 row = endRowBus[pbusid] - (15 - irownew);
426 col = startColBus[pbusid] + (mcmno-1)*4 + icolnew;
429 else if (imodule >= 12 && imodule < 18 )
431 row = startRowBus[pbusid] + irownew;
432 col = endColBus[pbusid] - (mcmno-1)*4 - (3 - icolnew);
434 else if (imodule >= 18 && imodule < 24)
436 row = endRowBus[pbusid] - (15 - irownew);
437 col = endColBus[pbusid] - (mcmno-1)*4 - (3 - icolnew);
439 else if (imodule >= 24 && imodule < 30)
441 Int_t rowdiff = endRowBus[pbusid] - startRowBus[pbusid];
446 // Add 16 to skip the 1st 15 rows
447 row = startRowBus[pbusid] + irownew + 16;
448 col = startColBus[pbusid] + (mcmno-1)*4 + icolnew;
452 row = startRowBus[pbusid] + irownew;
453 col = startColBus[pbusid] + (mcmno-12-1)*4 + icolnew;
456 else if (rowdiff < 16)
458 row = startRowBus[pbusid] + irownew;
459 col = startColBus[pbusid] + (mcmno-1)*4 + icolnew;
462 else if (imodule >= 42 && imodule < 48)
464 Int_t rowdiff = endRowBus[pbusid] - startRowBus[pbusid];
468 col = endColBus[pbusid] - (mcmno-1)*4 - (3 - icolnew);
471 row = endRowBus[pbusid] - (15 - irownew) - 16 ;
473 row = endRowBus[pbusid] - (15 - irownew) ;
477 row = endRowBus[pbusid] - (15 - irownew) ;
478 col = endColBus[pbusid] - (mcmno - 12 - 1)*4 - (3 - icolnew);
484 else if (imodule >= 30 && imodule < 36)
488 // Subtract 16 to skip the 1st 15 rows
489 row = endRowBus[pbusid] - 16 -(15 - irownew);
490 col = startColBus[pbusid] + (mcmno-12 -1)*4 + icolnew;
494 row = endRowBus[pbusid] - (15 - irownew) ;
495 col = startColBus[pbusid] + (mcmno -1)*4 + icolnew;
500 else if (imodule >= 36 && imodule < 42)
504 // Add 16 to skip the 1st 15 rows
505 row = startRowBus[pbusid] + irownew + 16;
506 col = endColBus[pbusid] - (mcmno - 12 - 1)*4 - (3 - icolnew);
510 row = startRowBus[pbusid] + irownew ;
511 col = endColBus[pbusid] - (mcmno - 1)*4 - (3 - icolnew);
517 //_____________________________________________________________________________
518 void AliPMDRawStream::ConvertDDL2SMN(Int_t iddl, Int_t imodule,
519 Int_t &smn, Int_t &detector) const
521 // This converts the DDL number (0 to 5), Module Number (0-47)
522 // to Serial module number in one detector (SMN : 0-23) and
523 // detector number (0:PRE plane, 1:CPV plane)
535 //_____________________________________________________________________________
537 void AliPMDRawStream::TransformH2S(Int_t smn, Int_t &row, Int_t &col) const
539 // This does the transformation of the hardware coordinate to
541 // i.e., For SuperModule 0 &1, instead of 96x48(hardware),
542 // it is 48x96 (software)
543 // For Supermodule 3 & 4, 48x96
553 else if(smn >= 12 && smn < 24)
562 //_____________________________________________________________________________
563 Int_t AliPMDRawStream::ComputeParity(UInt_t data)
565 // Calculate the parity bit
568 for(Int_t j = 0; j<29; j++)
570 if (data & 0x01 ) count++;
574 Int_t parity = count%2;
579 //_____________________________________________________________________________
580 UInt_t AliPMDRawStream::GetNextWord()
582 // Returns the next 32 bit word
583 // inside the raw data payload.
585 if (!fData || fPosition < 0) AliFatal("Raw data payload buffer is not yet initialized !");
588 word |= fData[fPosition++];
589 word |= fData[fPosition++] << 8;
590 word |= fData[fPosition++] << 16;
591 word |= fData[fPosition++] << 24;
596 //_____________________________________________________________________________
597 void AliPMDRawStream::Ddl0Mapping(Int_t moduleNo[], Int_t mcmperBus[],
598 Int_t startRowBus[], Int_t endRowBus[],
599 Int_t startColBus[], Int_t endColBus[])
605 for(Int_t ibus = 1; ibus < 51; ibus++)
607 moduleNo[ibus] = fMapData->GetModuleNo(iddl,ibus);
608 mcmperBus[ibus] = fMapData->GetMcmperBus(iddl,ibus);
609 startRowBus[ibus] = fMapData->GetStartRowBus(iddl,ibus);
610 startColBus[ibus] = fMapData->GetStartColBus(iddl,ibus);
611 endRowBus[ibus] = fMapData->GetEndRowBus(iddl,ibus);
612 endColBus[ibus] = fMapData->GetEndColBus(iddl,ibus);
617 //_____________________________________________________________________________
618 void AliPMDRawStream::Ddl1Mapping(Int_t moduleNo[], Int_t mcmperBus[],
619 Int_t startRowBus[], Int_t endRowBus[],
620 Int_t startColBus[], Int_t endColBus[])
626 for(Int_t ibus = 1; ibus < 51; ibus++)
628 moduleNo[ibus] = fMapData->GetModuleNo(iddl,ibus);
629 mcmperBus[ibus] = fMapData->GetMcmperBus(iddl,ibus);
630 startRowBus[ibus] = fMapData->GetStartRowBus(iddl,ibus);
631 startColBus[ibus] = fMapData->GetStartColBus(iddl,ibus);
632 endRowBus[ibus] = fMapData->GetEndRowBus(iddl,ibus);
633 endColBus[ibus] = fMapData->GetEndColBus(iddl,ibus);
640 //_____________________________________________________________________________
641 void AliPMDRawStream::Ddl2Mapping(Int_t moduleNo[], Int_t mcmperBus[],
642 Int_t startRowBus[], Int_t endRowBus[],
643 Int_t startColBus[], Int_t endColBus[])
649 for(Int_t ibus = 1; ibus < 51; ibus++)
651 moduleNo[ibus] = fMapData->GetModuleNo(iddl,ibus);
652 mcmperBus[ibus] = fMapData->GetMcmperBus(iddl,ibus);
653 startRowBus[ibus] = fMapData->GetStartRowBus(iddl,ibus);
654 startColBus[ibus] = fMapData->GetStartColBus(iddl,ibus);
655 endRowBus[ibus] = fMapData->GetEndRowBus(iddl,ibus);
656 endColBus[ibus] = fMapData->GetEndColBus(iddl,ibus);
662 //_____________________________________________________________________________
663 void AliPMDRawStream::Ddl3Mapping(Int_t moduleNo[], Int_t mcmperBus[],
664 Int_t startRowBus[], Int_t endRowBus[],
665 Int_t startColBus[], Int_t endColBus[])
671 for(Int_t ibus = 1; ibus < 51; ibus++)
673 moduleNo[ibus] = fMapData->GetModuleNo(iddl,ibus);
674 mcmperBus[ibus] = fMapData->GetMcmperBus(iddl,ibus);
675 startRowBus[ibus] = fMapData->GetStartRowBus(iddl,ibus);
676 startColBus[ibus] = fMapData->GetStartColBus(iddl,ibus);
677 endRowBus[ibus] = fMapData->GetEndRowBus(iddl,ibus);
678 endColBus[ibus] = fMapData->GetEndColBus(iddl,ibus);
684 //_____________________________________________________________________________
685 void AliPMDRawStream::Ddl4Mapping(Int_t moduleNo[], Int_t mcmperBus[],
686 Int_t startRowBus[], Int_t endRowBus[],
687 Int_t startColBus[], Int_t endColBus[])
693 for(Int_t ibus = 1; ibus < 51; ibus++)
695 moduleNo[ibus] = fMapData->GetModuleNo(iddl,ibus);
696 mcmperBus[ibus] = fMapData->GetMcmperBus(iddl,ibus);
697 startRowBus[ibus] = fMapData->GetStartRowBus(iddl,ibus);
698 startColBus[ibus] = fMapData->GetStartColBus(iddl,ibus);
699 endRowBus[ibus] = fMapData->GetEndRowBus(iddl,ibus);
700 endColBus[ibus] = fMapData->GetEndColBus(iddl,ibus);
707 //_____________________________________________________________________________
708 void AliPMDRawStream::Ddl5Mapping(Int_t moduleNo[], Int_t mcmperBus[],
709 Int_t startRowBus[], Int_t endRowBus[],
710 Int_t startColBus[], Int_t endColBus[])
716 for(Int_t ibus = 1; ibus < 51; ibus++)
718 moduleNo[ibus] = fMapData->GetModuleNo(iddl,ibus);
719 mcmperBus[ibus] = fMapData->GetMcmperBus(iddl,ibus);
720 startRowBus[ibus] = fMapData->GetStartRowBus(iddl,ibus);
721 startColBus[ibus] = fMapData->GetStartColBus(iddl,ibus);
722 endRowBus[ibus] = fMapData->GetEndRowBus(iddl,ibus);
723 endColBus[ibus] = fMapData->GetEndColBus(iddl,ibus);
728 //_____________________________________________________________________________
730 AliPMDMappingData* AliPMDRawStream::GetMappingData() const
732 // Fetching the mapping data from CDB
734 AliCDBEntry *entry = AliCDBManager::Instance()->Get("PMD/Calib/Mapping");
736 if(!entry) AliFatal("Mapping object retrieval failed!");
738 AliPMDMappingData *mapdata=0;
739 if (entry) mapdata = (AliPMDMappingData*) entry->GetObject();
741 if (!mapdata) AliFatal("No Mapping data from CDB !");
748 //_____________________________________________________________________________