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 // PMD raw data does not contain CDH
117 if (!fRawReader->ReadNextData(fData))
127 const Int_t kNPatchBus = 51;
129 Int_t moduleNo[kNPatchBus], mcmperBus[kNPatchBus];
130 Int_t startRowBus[kNPatchBus], endRowBus[kNPatchBus];
131 Int_t startColBus[kNPatchBus], endColBus[kNPatchBus];
133 for (ibus = 0; ibus < kNPatchBus; ibus++)
136 mcmperBus[ibus] = -1;
137 startRowBus[ibus] = -1;
138 endRowBus[ibus] = -1;
139 startColBus[ibus] = -1;
140 endColBus[ibus] = -1;
145 Ddl0Mapping(moduleNo, mcmperBus, startRowBus,
146 endRowBus, startColBus, endColBus);
151 Ddl1Mapping(moduleNo, mcmperBus, startRowBus,
152 endRowBus, startColBus, endColBus);
157 Ddl2Mapping(moduleNo, mcmperBus, startRowBus,
158 endRowBus, startColBus, endColBus);
162 Ddl3Mapping(moduleNo, mcmperBus, startRowBus,
163 endRowBus, startColBus, endColBus);
167 Ddl4Mapping(moduleNo, mcmperBus, startRowBus,
168 endRowBus, startColBus, endColBus);
172 Ddl5Mapping(moduleNo, mcmperBus, startRowBus,
173 endRowBus, startColBus, endColBus);
177 AliPMDBlockHeader blockHeader;
178 AliPMDDspHeader dspHeader;
179 AliPMDPatchBusHeader pbusHeader;
181 const Int_t kblHLen = blockHeader.GetHeaderLength();
182 const Int_t kdspHLen = dspHeader.GetHeaderLength();
183 const Int_t kpbusHLen = pbusHeader.GetHeaderLength();
186 Int_t idet = 0, ismn = 0;
190 Int_t blHeaderWord[8]={0};
191 Int_t dspHeaderWord[10]={0};
192 Int_t pbusHeaderWord[4]={0};
194 Int_t blRawDataLength = 0;
195 Int_t dspRawDataLength = 0;
200 for (Int_t iblock = 0; iblock < 2; iblock++)
202 for (Int_t i = 0; i < kblHLen; i++)
206 blHeaderWord[i] = (Int_t) GetNextWord();
209 blockHeader.SetHeader(blHeaderWord);
210 blRawDataLength = blockHeader.GetRawDataLength();
212 if (iwordddl == totaldataword) break;
216 for (Int_t idsp = 0; idsp < 5; idsp++)
218 for (Int_t i = 0; i < kdspHLen; i++)
222 dspHeaderWord[i] = (Int_t) GetNextWord();
224 dspHeader.SetHeader(dspHeaderWord);
225 dspRawDataLength = dspHeader.GetRawDataLength();
227 if (iwordddl == totaldataword) break;
231 for (ibus = 0; ibus < 5; ibus++)
233 for (Int_t i = 0; i < kpbusHLen; i++)
238 pbusHeaderWord[i] = (Int_t) GetNextWord();
241 pbusHeader.SetHeader(pbusHeaderWord);
242 Int_t rawdatalength = pbusHeader.GetRawDataLength();
243 Int_t pbusid = pbusHeader.GetPatchBusId();
245 if (pbusid < 0 || pbusid > 50) return -1;
247 Int_t imodule = moduleNo[pbusid];
249 if (iwordddl == totaldataword) break;
251 for (Int_t iword = 0; iword < rawdatalength; iword++)
257 data = GetNextWord();
259 Int_t isig = data & 0x0FFF;
260 Int_t ich = (data >> 12) & 0x003F;
261 Int_t imcm = (data >> 18) & 0x07FF;
262 Int_t ibit = (data >> 31) & 0x0001;
266 AliWarning(Form("FEE address WRONG:: Module %d Patch Bus %d MCM %d",imodule,pbusid,imcm));
270 parity = ComputeParity(data);
274 AliWarning(Form("Parity Error:: Patch Bus %d Module %d",pbusid,imodule));
275 fRawReader->AddMajorErrorLog(kParityError);
279 ConvertDDL2SMN(iddl, imodule, ismn, idet);
281 GetRowCol(imodule, pbusid, imcm, ich,
282 startRowBus, endRowBus,
283 startColBus, endColBus,
287 TransformH2S(ismn, irow, icol);
289 pmdddldata = new AliPMDddldata();
291 pmdddldata->SetDetector(idet);
292 pmdddldata->SetSMN(ismn);
293 pmdddldata->SetModule(imodule);
294 pmdddldata->SetPatchBusId(pbusid);
295 pmdddldata->SetMCM(imcm);
296 pmdddldata->SetChannel(ich);
297 pmdddldata->SetRow(irow);
298 pmdddldata->SetColumn(icol);
299 pmdddldata->SetSignal(isig);
300 pmdddldata->SetParityBit(ibit);
302 pmdddlcont->Add(pmdddldata);
307 if (iwordddl == totaldataword) break;
309 if (dspHeader.GetPaddingWord() == 1)
311 if (iworddsp == dspRawDataLength-1) break; // raw data
315 if (iworddsp == dspRawDataLength) break; // raw data
322 if (dspHeader.GetPaddingWord() == 1)
327 data = GetNextWord();
329 if (iwordddl == totaldataword) break;
331 if (iwordblk == blRawDataLength) break; // for raw data
340 //_____________________________________________________________________________
341 void AliPMDRawStream::GetRowCol(Int_t imodule, Int_t pbusid,
342 UInt_t mcmno, UInt_t chno,
343 Int_t startRowBus[], Int_t endRowBus[],
344 Int_t startColBus[], Int_t endColBus[],
345 Int_t &row, Int_t &col) const
347 // decode: ddlno, patchbusid, mcmno, chno -> um, row, col
351 static const UInt_t kChDdl01[64] = { 9, 6, 5, 10, 1, 2, 0, 3,
352 13, 7, 4, 11, 8, 14, 12, 15,
353 16, 19, 17, 23, 20, 27, 24, 18,
354 28, 31, 29, 30, 21, 26, 25, 22,
355 41, 38, 37, 42, 33, 34, 32, 35,
356 45, 39, 36, 43, 40, 46, 44, 47,
357 48, 51, 49, 55, 52, 59, 56, 50,
358 60, 63, 61, 62, 53, 58, 57, 54 };
360 static const UInt_t kChDdl23[64] = { 54, 57, 58, 53, 62, 61, 63, 60,
361 50, 56, 59, 52, 55, 49, 51, 48,
362 47, 44, 46, 40, 43, 36, 39, 45,
363 35, 32, 34, 33, 42, 37, 38, 41,
364 22, 25, 26, 21, 30, 29, 31, 28,
365 18, 24, 27, 20, 23, 17, 19, 16,
366 15, 12, 14, 8, 11, 4, 7, 13,
367 3, 0, 2, 1, 10, 5, 6, 9 };
369 static const UInt_t kChDdl41[64] = { 53, 58, 57, 54, 61, 62, 60, 63,
370 49, 59, 56, 55, 52, 50, 48, 51,
371 44, 47, 45, 43, 40, 39, 36, 46,
372 32, 35, 33, 34, 41, 38, 37, 42,
373 21, 26, 25, 22, 29, 30, 28, 31,
374 17, 27, 24, 23, 20, 18, 16, 19,
375 12, 15, 13, 11, 8, 7, 4, 14,
376 0, 3, 1, 2, 9, 6, 5, 10 };
378 static const UInt_t kChDdl42[64] = { 10, 5, 6, 9, 2, 1, 3, 0,
379 14, 4, 7, 8, 11, 13, 15, 12,
380 19, 16, 18, 20, 23, 24, 27, 17,
381 31, 28, 30, 29, 22, 25, 26, 21,
382 42, 37, 38, 41, 34, 33, 35, 32,
383 46, 36, 39, 40, 43, 45, 47, 44,
384 51, 48, 50, 52, 55, 56, 59, 49,
385 63, 60, 62, 61, 54, 57, 58, 53 };
387 static const UInt_t kChDdl51[64] = { 10, 5, 6, 9, 2, 1, 3, 0,
388 14, 4, 7, 8, 11, 13, 15, 12,
389 19, 16, 18, 20, 23, 24, 27, 17,
390 31, 28, 30, 29, 22, 25, 26, 21,
391 42, 37, 38, 41, 34, 33, 35, 32,
392 46, 36, 39, 40, 43, 45, 47, 44,
393 51, 48, 50, 52, 55, 56, 59, 49,
394 63, 60, 62, 61, 54, 57, 58, 53 };
396 static const UInt_t kChDdl52[64] = { 53, 58, 57, 54, 61, 62, 60, 63,
397 49, 59, 56, 55, 52, 50, 48, 51,
398 44, 47, 45, 43, 40, 39, 36, 46,
399 32, 35, 33, 34, 41, 38, 37, 42,
400 21, 26, 25, 22, 29, 30, 28, 31,
401 17, 27, 24, 23, 20, 18, 16, 19,
402 12, 15, 13, 11, 8, 7, 4, 14,
403 0, 3, 1, 2, 9, 6, 5, 10 };
405 for (Int_t i = 0; i < 64; i++)
407 if(imodule < 6) iCh[i] = kChDdl01[i];
408 if(imodule >= 6 && imodule <= 11) iCh[i] = kChDdl01[i];
409 if(imodule >= 12 && imodule <= 17) iCh[i] = kChDdl23[i];
410 if(imodule >= 18 && imodule <= 23) iCh[i] = kChDdl23[i];
411 if(imodule >= 24 && imodule <= 29) iCh[i] = kChDdl41[i];
412 if(imodule >= 42 && imodule <= 47) iCh[i] = kChDdl42[i];
413 if(imodule >= 36 && imodule <= 41) iCh[i] = kChDdl51[i];
414 if(imodule >= 30 && imodule <= 35) iCh[i] = kChDdl52[i];
418 Int_t rowcol = iCh[chno];
419 Int_t irownew = rowcol/4;
420 Int_t icolnew = rowcol%4;
425 row = startRowBus[pbusid] + irownew;
426 col = startColBus[pbusid] + (mcmno-1)*4 + icolnew;
428 else if (imodule >= 6 && imodule < 12)
430 row = endRowBus[pbusid] - (15 - irownew);
431 col = startColBus[pbusid] + (mcmno-1)*4 + icolnew;
434 else if (imodule >= 12 && imodule < 18 )
436 row = startRowBus[pbusid] + irownew;
437 col = endColBus[pbusid] - (mcmno-1)*4 - (3 - icolnew);
439 else if (imodule >= 18 && imodule < 24)
441 row = endRowBus[pbusid] - (15 - irownew);
442 col = endColBus[pbusid] - (mcmno-1)*4 - (3 - icolnew);
444 else if (imodule >= 24 && imodule < 30)
446 Int_t rowdiff = endRowBus[pbusid] - startRowBus[pbusid];
451 // Add 16 to skip the 1st 15 rows
452 row = startRowBus[pbusid] + irownew + 16;
453 col = startColBus[pbusid] + (mcmno-1)*4 + icolnew;
457 row = startRowBus[pbusid] + irownew;
458 col = startColBus[pbusid] + (mcmno-12-1)*4 + icolnew;
461 else if (rowdiff < 16)
463 row = startRowBus[pbusid] + irownew;
464 col = startColBus[pbusid] + (mcmno-1)*4 + icolnew;
467 else if (imodule >= 42 && imodule < 48)
469 Int_t rowdiff = endRowBus[pbusid] - startRowBus[pbusid];
473 col = endColBus[pbusid] - (mcmno-1)*4 - (3 - icolnew);
476 row = endRowBus[pbusid] - (15 - irownew) - 16 ;
478 row = endRowBus[pbusid] - (15 - irownew) ;
482 row = endRowBus[pbusid] - (15 - irownew) ;
483 col = endColBus[pbusid] - (mcmno - 12 - 1)*4 - (3 - icolnew);
489 else if (imodule >= 30 && imodule < 36)
493 // Subtract 16 to skip the 1st 15 rows
494 row = endRowBus[pbusid] - 16 -(15 - irownew);
495 col = startColBus[pbusid] + (mcmno-12 -1)*4 + icolnew;
499 row = endRowBus[pbusid] - (15 - irownew) ;
500 col = startColBus[pbusid] + (mcmno -1)*4 + icolnew;
505 else if (imodule >= 36 && imodule < 42)
509 // Add 16 to skip the 1st 15 rows
510 row = startRowBus[pbusid] + irownew + 16;
511 col = endColBus[pbusid] - (mcmno - 12 - 1)*4 - (3 - icolnew);
515 row = startRowBus[pbusid] + irownew ;
516 col = endColBus[pbusid] - (mcmno - 1)*4 - (3 - icolnew);
522 //_____________________________________________________________________________
523 void AliPMDRawStream::ConvertDDL2SMN(Int_t iddl, Int_t imodule,
524 Int_t &smn, Int_t &detector) const
526 // This converts the DDL number (0 to 5), Module Number (0-47)
527 // to Serial module number in one detector (SMN : 0-23) and
528 // detector number (0:PRE plane, 1:CPV plane)
540 //_____________________________________________________________________________
542 void AliPMDRawStream::TransformH2S(Int_t smn, Int_t &row, Int_t &col) const
544 // This does the transformation of the hardware coordinate to
546 // i.e., For SuperModule 0 &1, instead of 96x48(hardware),
547 // it is 48x96 (software)
548 // For Supermodule 3 & 4, 48x96
558 else if(smn >= 12 && smn < 24)
567 //_____________________________________________________________________________
568 Int_t AliPMDRawStream::ComputeParity(UInt_t data)
570 // Calculate the parity bit
573 for(Int_t j = 0; j<29; j++)
575 if (data & 0x01 ) count++;
579 Int_t parity = count%2;
584 //_____________________________________________________________________________
585 UInt_t AliPMDRawStream::GetNextWord()
587 // Returns the next 32 bit word
588 // inside the raw data payload.
590 if (!fData || fPosition < 0) AliFatal("Raw data payload buffer is not yet initialized !");
593 word |= fData[fPosition++];
594 word |= fData[fPosition++] << 8;
595 word |= fData[fPosition++] << 16;
596 word |= fData[fPosition++] << 24;
601 //_____________________________________________________________________________
602 void AliPMDRawStream::Ddl0Mapping(Int_t moduleNo[], Int_t mcmperBus[],
603 Int_t startRowBus[], Int_t endRowBus[],
604 Int_t startColBus[], Int_t endColBus[])
610 for(Int_t ibus = 1; ibus < 51; ibus++)
612 moduleNo[ibus] = fMapData->GetModuleNo(iddl,ibus);
613 mcmperBus[ibus] = fMapData->GetMcmperBus(iddl,ibus);
614 startRowBus[ibus] = fMapData->GetStartRowBus(iddl,ibus);
615 startColBus[ibus] = fMapData->GetStartColBus(iddl,ibus);
616 endRowBus[ibus] = fMapData->GetEndRowBus(iddl,ibus);
617 endColBus[ibus] = fMapData->GetEndColBus(iddl,ibus);
622 //_____________________________________________________________________________
623 void AliPMDRawStream::Ddl1Mapping(Int_t moduleNo[], Int_t mcmperBus[],
624 Int_t startRowBus[], Int_t endRowBus[],
625 Int_t startColBus[], Int_t endColBus[])
631 for(Int_t ibus = 1; ibus < 51; ibus++)
633 moduleNo[ibus] = fMapData->GetModuleNo(iddl,ibus);
634 mcmperBus[ibus] = fMapData->GetMcmperBus(iddl,ibus);
635 startRowBus[ibus] = fMapData->GetStartRowBus(iddl,ibus);
636 startColBus[ibus] = fMapData->GetStartColBus(iddl,ibus);
637 endRowBus[ibus] = fMapData->GetEndRowBus(iddl,ibus);
638 endColBus[ibus] = fMapData->GetEndColBus(iddl,ibus);
645 //_____________________________________________________________________________
646 void AliPMDRawStream::Ddl2Mapping(Int_t moduleNo[], Int_t mcmperBus[],
647 Int_t startRowBus[], Int_t endRowBus[],
648 Int_t startColBus[], Int_t endColBus[])
654 for(Int_t ibus = 1; ibus < 51; ibus++)
656 moduleNo[ibus] = fMapData->GetModuleNo(iddl,ibus);
657 mcmperBus[ibus] = fMapData->GetMcmperBus(iddl,ibus);
658 startRowBus[ibus] = fMapData->GetStartRowBus(iddl,ibus);
659 startColBus[ibus] = fMapData->GetStartColBus(iddl,ibus);
660 endRowBus[ibus] = fMapData->GetEndRowBus(iddl,ibus);
661 endColBus[ibus] = fMapData->GetEndColBus(iddl,ibus);
667 //_____________________________________________________________________________
668 void AliPMDRawStream::Ddl3Mapping(Int_t moduleNo[], Int_t mcmperBus[],
669 Int_t startRowBus[], Int_t endRowBus[],
670 Int_t startColBus[], Int_t endColBus[])
676 for(Int_t ibus = 1; ibus < 51; ibus++)
678 moduleNo[ibus] = fMapData->GetModuleNo(iddl,ibus);
679 mcmperBus[ibus] = fMapData->GetMcmperBus(iddl,ibus);
680 startRowBus[ibus] = fMapData->GetStartRowBus(iddl,ibus);
681 startColBus[ibus] = fMapData->GetStartColBus(iddl,ibus);
682 endRowBus[ibus] = fMapData->GetEndRowBus(iddl,ibus);
683 endColBus[ibus] = fMapData->GetEndColBus(iddl,ibus);
689 //_____________________________________________________________________________
690 void AliPMDRawStream::Ddl4Mapping(Int_t moduleNo[], Int_t mcmperBus[],
691 Int_t startRowBus[], Int_t endRowBus[],
692 Int_t startColBus[], Int_t endColBus[])
698 for(Int_t ibus = 1; ibus < 51; ibus++)
700 moduleNo[ibus] = fMapData->GetModuleNo(iddl,ibus);
701 mcmperBus[ibus] = fMapData->GetMcmperBus(iddl,ibus);
702 startRowBus[ibus] = fMapData->GetStartRowBus(iddl,ibus);
703 startColBus[ibus] = fMapData->GetStartColBus(iddl,ibus);
704 endRowBus[ibus] = fMapData->GetEndRowBus(iddl,ibus);
705 endColBus[ibus] = fMapData->GetEndColBus(iddl,ibus);
712 //_____________________________________________________________________________
713 void AliPMDRawStream::Ddl5Mapping(Int_t moduleNo[], Int_t mcmperBus[],
714 Int_t startRowBus[], Int_t endRowBus[],
715 Int_t startColBus[], Int_t endColBus[])
721 for(Int_t ibus = 1; ibus < 51; ibus++)
723 moduleNo[ibus] = fMapData->GetModuleNo(iddl,ibus);
724 mcmperBus[ibus] = fMapData->GetMcmperBus(iddl,ibus);
725 startRowBus[ibus] = fMapData->GetStartRowBus(iddl,ibus);
726 startColBus[ibus] = fMapData->GetStartColBus(iddl,ibus);
727 endRowBus[ibus] = fMapData->GetEndRowBus(iddl,ibus);
728 endColBus[ibus] = fMapData->GetEndColBus(iddl,ibus);
733 //_____________________________________________________________________________
735 AliPMDMappingData* AliPMDRawStream::GetMappingData() const
737 // Fetching the mapping data from CDB
739 AliCDBEntry *entry = AliCDBManager::Instance()->Get("PMD/Calib/Mapping");
741 if(!entry) AliFatal("Mapping object retrieval failed!");
743 AliPMDMappingData *mapdata=0;
744 if (entry) mapdata = (AliPMDMappingData*) entry->GetObject();
746 if (!mapdata) AliFatal("No Mapping data from CDB !");
753 //_____________________________________________________________________________