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;
110 if (dataSize <= 0) return -1;
114 // PMD raw data does not contain CDH
116 if (!fRawReader->ReadNextData(fData))
126 const Int_t kNPatchBus = 51;
128 Int_t moduleNo[kNPatchBus], mcmperBus[kNPatchBus];
129 Int_t startRowBus[kNPatchBus], endRowBus[kNPatchBus];
130 Int_t startColBus[kNPatchBus], endColBus[kNPatchBus];
132 for (ibus = 0; ibus < kNPatchBus; ibus++)
135 mcmperBus[ibus] = -1;
136 startRowBus[ibus] = -1;
137 endRowBus[ibus] = -1;
138 startColBus[ibus] = -1;
139 endColBus[ibus] = -1;
144 Ddl0Mapping(moduleNo, mcmperBus, startRowBus,
145 endRowBus, startColBus, endColBus);
150 Ddl1Mapping(moduleNo, mcmperBus, startRowBus,
151 endRowBus, startColBus, endColBus);
156 Ddl2Mapping(moduleNo, mcmperBus, startRowBus,
157 endRowBus, startColBus, endColBus);
161 Ddl3Mapping(moduleNo, mcmperBus, startRowBus,
162 endRowBus, startColBus, endColBus);
166 Ddl4Mapping(moduleNo, mcmperBus, startRowBus,
167 endRowBus, startColBus, endColBus);
171 Ddl5Mapping(moduleNo, mcmperBus, startRowBus,
172 endRowBus, startColBus, endColBus);
176 AliPMDBlockHeader blockHeader;
177 AliPMDDspHeader dspHeader;
178 AliPMDPatchBusHeader pbusHeader;
180 const Int_t kblHLen = blockHeader.GetHeaderLength();
181 const Int_t kdspHLen = dspHeader.GetHeaderLength();
182 const Int_t kpbusHLen = pbusHeader.GetHeaderLength();
185 Int_t idet = 0, ismn = 0;
189 Int_t blHeaderWord[8]={0};
190 Int_t dspHeaderWord[10]={0};
191 Int_t pbusHeaderWord[4]={0};
193 Int_t blRawDataLength = 0;
194 Int_t dspRawDataLength = 0;
199 for (Int_t iblock = 0; iblock < 2; iblock++)
201 for (Int_t i = 0; i < kblHLen; i++)
204 blHeaderWord[i] = (Int_t) GetNextWord();
207 blockHeader.SetHeader(blHeaderWord);
208 blRawDataLength = blockHeader.GetRawDataLength();
210 if (iwordddl == totaldataword) break;
214 for (Int_t idsp = 0; idsp < 5; idsp++)
216 for (Int_t i = 0; i < kdspHLen; i++)
220 dspHeaderWord[i] = (Int_t) GetNextWord();
222 dspHeader.SetHeader(dspHeaderWord);
223 dspRawDataLength = dspHeader.GetRawDataLength();
225 if (iwordddl == totaldataword) break;
229 for (ibus = 0; ibus < 5; ibus++)
231 for (Int_t i = 0; i < kpbusHLen; i++)
236 pbusHeaderWord[i] = (Int_t) GetNextWord();
239 pbusHeader.SetHeader(pbusHeaderWord);
240 Int_t rawdatalength = pbusHeader.GetRawDataLength();
241 Int_t pbusid = pbusHeader.GetPatchBusId();
243 if (pbusid < 0 || pbusid > 50) return -1;
245 Int_t imodule = moduleNo[pbusid];
247 if (iwordddl == totaldataword) break;
249 for (Int_t iword = 0; iword < rawdatalength; iword++)
255 data = GetNextWord();
257 Int_t isig = data & 0x0FFF;
258 Int_t ich = (data >> 12) & 0x003F;
259 Int_t imcm = (data >> 18) & 0x07FF;
260 Int_t ibit = (data >> 31) & 0x0001;
263 AliWarning(Form("FEE address WRONG:: Module %d Patch Bus %d MCM %d",imodule,pbusid,imcm));
267 parity = ComputeParity(data);
271 AliWarning(Form("Parity Error:: Patch Bus %d Module %d",pbusid,imodule));
272 fRawReader->AddMajorErrorLog(kParityError);
276 ConvertDDL2SMN(iddl, imodule, ismn, idet);
278 GetRowCol(imodule, pbusid, imcm, ich,
279 startRowBus, endRowBus,
280 startColBus, endColBus,
284 TransformH2S(ismn, irow, icol);
286 pmdddldata = new AliPMDddldata();
288 pmdddldata->SetDetector(idet);
289 pmdddldata->SetSMN(ismn);
290 pmdddldata->SetModule(imodule);
291 pmdddldata->SetPatchBusId(pbusid);
292 pmdddldata->SetMCM(imcm);
293 pmdddldata->SetChannel(ich);
294 pmdddldata->SetRow(irow);
295 pmdddldata->SetColumn(icol);
296 pmdddldata->SetSignal(isig);
297 pmdddldata->SetParityBit(ibit);
299 pmdddlcont->Add(pmdddldata);
304 if (iwordddl == totaldataword) break;
306 if (dspHeader.GetPaddingWord() == 1)
308 if (iworddsp == dspRawDataLength-1) break; // raw data
312 if (iworddsp == dspRawDataLength) break; // raw data
318 //SKP added break next line (Reqd. if only one patch Bus)
319 if (iwordddl == totaldataword) break;
321 if (dspHeader.GetPaddingWord() == 1)
326 data = GetNextWord();
328 if (iwordddl == totaldataword) break;
330 if (iwordblk == blRawDataLength) break; // for raw data
334 //SKP added break next line (Reqd. if only one patch Bus)
335 if (iwordddl == totaldataword) break;
341 //_____________________________________________________________________________
342 void AliPMDRawStream::GetRowCol(Int_t imodule, Int_t pbusid,
343 UInt_t mcmno, UInt_t chno,
344 Int_t startRowBus[], Int_t endRowBus[],
345 Int_t startColBus[], Int_t endColBus[],
346 Int_t &row, Int_t &col) const
348 // decode: ddlno, patchbusid, mcmno, chno -> um, row, col
352 static const UInt_t kChDdl01[64] = { 9, 6, 5, 10, 1, 2, 0, 3,
353 13, 7, 4, 11, 8, 14, 12, 15,
354 16, 19, 17, 23, 20, 27, 24, 18,
355 28, 31, 29, 30, 21, 26, 25, 22,
356 41, 38, 37, 42, 33, 34, 32, 35,
357 45, 39, 36, 43, 40, 46, 44, 47,
358 48, 51, 49, 55, 52, 59, 56, 50,
359 60, 63, 61, 62, 53, 58, 57, 54 };
361 static const UInt_t kChDdl23[64] = { 54, 57, 58, 53, 62, 61, 63, 60,
362 50, 56, 59, 52, 55, 49, 51, 48,
363 47, 44, 46, 40, 43, 36, 39, 45,
364 35, 32, 34, 33, 42, 37, 38, 41,
365 22, 25, 26, 21, 30, 29, 31, 28,
366 18, 24, 27, 20, 23, 17, 19, 16,
367 15, 12, 14, 8, 11, 4, 7, 13,
368 3, 0, 2, 1, 10, 5, 6, 9 };
370 static const UInt_t kChDdl41[64] = { 53, 58, 57, 54, 61, 62, 60, 63,
371 49, 59, 56, 55, 52, 50, 48, 51,
372 44, 47, 45, 43, 40, 39, 36, 46,
373 32, 35, 33, 34, 41, 38, 37, 42,
374 21, 26, 25, 22, 29, 30, 28, 31,
375 17, 27, 24, 23, 20, 18, 16, 19,
376 12, 15, 13, 11, 8, 7, 4, 14,
377 0, 3, 1, 2, 9, 6, 5, 10 };
379 static const UInt_t kChDdl42[64] = { 10, 5, 6, 9, 2, 1, 3, 0,
380 14, 4, 7, 8, 11, 13, 15, 12,
381 19, 16, 18, 20, 23, 24, 27, 17,
382 31, 28, 30, 29, 22, 25, 26, 21,
383 42, 37, 38, 41, 34, 33, 35, 32,
384 46, 36, 39, 40, 43, 45, 47, 44,
385 51, 48, 50, 52, 55, 56, 59, 49,
386 63, 60, 62, 61, 54, 57, 58, 53 };
388 static const UInt_t kChDdl51[64] = { 10, 5, 6, 9, 2, 1, 3, 0,
389 14, 4, 7, 8, 11, 13, 15, 12,
390 19, 16, 18, 20, 23, 24, 27, 17,
391 31, 28, 30, 29, 22, 25, 26, 21,
392 42, 37, 38, 41, 34, 33, 35, 32,
393 46, 36, 39, 40, 43, 45, 47, 44,
394 51, 48, 50, 52, 55, 56, 59, 49,
395 63, 60, 62, 61, 54, 57, 58, 53 };
397 static const UInt_t kChDdl52[64] = { 53, 58, 57, 54, 61, 62, 60, 63,
398 49, 59, 56, 55, 52, 50, 48, 51,
399 44, 47, 45, 43, 40, 39, 36, 46,
400 32, 35, 33, 34, 41, 38, 37, 42,
401 21, 26, 25, 22, 29, 30, 28, 31,
402 17, 27, 24, 23, 20, 18, 16, 19,
403 12, 15, 13, 11, 8, 7, 4, 14,
404 0, 3, 1, 2, 9, 6, 5, 10 };
406 for (Int_t i = 0; i < 64; i++)
408 if(imodule < 6) iCh[i] = kChDdl01[i];
409 if(imodule >= 6 && imodule <= 11) iCh[i] = kChDdl01[i];
410 if(imodule >= 12 && imodule <= 17) iCh[i] = kChDdl23[i];
411 if(imodule >= 18 && imodule <= 23) iCh[i] = kChDdl23[i];
412 if(imodule >= 24 && imodule <= 29) iCh[i] = kChDdl41[i];
413 if(imodule >= 42 && imodule <= 47) iCh[i] = kChDdl42[i];
414 if(imodule >= 36 && imodule <= 41) iCh[i] = kChDdl51[i];
415 if(imodule >= 30 && imodule <= 35) iCh[i] = kChDdl52[i];
419 Int_t rowcol = iCh[chno];
420 Int_t irownew = rowcol/4;
421 Int_t icolnew = rowcol%4;
426 row = startRowBus[pbusid] + irownew;
427 col = startColBus[pbusid] + (mcmno-1)*4 + icolnew;
429 else if (imodule >= 6 && imodule < 12)
431 row = endRowBus[pbusid] - (15 - irownew);
432 col = startColBus[pbusid] + (mcmno-1)*4 + icolnew;
435 else if (imodule >= 12 && imodule < 18 )
437 row = startRowBus[pbusid] + irownew;
438 col = endColBus[pbusid] - (mcmno-1)*4 - (3 - icolnew);
440 else if (imodule >= 18 && imodule < 24)
442 row = endRowBus[pbusid] - (15 - irownew);
443 col = endColBus[pbusid] - (mcmno-1)*4 - (3 - icolnew);
445 else if (imodule >= 24 && imodule < 30)
447 Int_t rowdiff = endRowBus[pbusid] - startRowBus[pbusid];
452 // Add 16 to skip the 1st 15 rows
453 row = startRowBus[pbusid] + irownew + 16;
454 col = startColBus[pbusid] + (mcmno-1)*4 + icolnew;
458 row = startRowBus[pbusid] + irownew;
459 col = startColBus[pbusid] + (mcmno-12-1)*4 + icolnew;
462 else if (rowdiff < 16)
464 row = startRowBus[pbusid] + irownew;
465 col = startColBus[pbusid] + (mcmno-1)*4 + icolnew;
468 else if (imodule >= 42 && imodule < 48)
470 Int_t rowdiff = endRowBus[pbusid] - startRowBus[pbusid];
474 col = endColBus[pbusid] - (mcmno-1)*4 - (3 - icolnew);
477 row = endRowBus[pbusid] - (15 - irownew) - 16 ;
479 row = endRowBus[pbusid] - (15 - irownew) ;
483 row = endRowBus[pbusid] - (15 - irownew) ;
484 col = endColBus[pbusid] - (mcmno - 12 - 1)*4 - (3 - icolnew);
490 else if (imodule >= 30 && imodule < 36)
494 // Subtract 16 to skip the 1st 15 rows
495 row = endRowBus[pbusid] - 16 -(15 - irownew);
496 col = startColBus[pbusid] + (mcmno-12 -1)*4 + icolnew;
500 row = endRowBus[pbusid] - (15 - irownew) ;
501 col = startColBus[pbusid] + (mcmno -1)*4 + icolnew;
506 else if (imodule >= 36 && imodule < 42)
510 // Add 16 to skip the 1st 15 rows
511 row = startRowBus[pbusid] + irownew + 16;
512 col = endColBus[pbusid] - (mcmno - 12 - 1)*4 - (3 - icolnew);
516 row = startRowBus[pbusid] + irownew ;
517 col = endColBus[pbusid] - (mcmno - 1)*4 - (3 - icolnew);
523 //_____________________________________________________________________________
524 void AliPMDRawStream::ConvertDDL2SMN(Int_t iddl, Int_t imodule,
525 Int_t &smn, Int_t &detector) const
527 // This converts the DDL number (0 to 5), Module Number (0-47)
528 // to Serial module number in one detector (SMN : 0-23) and
529 // detector number (0:PRE plane, 1:CPV plane)
541 //_____________________________________________________________________________
543 void AliPMDRawStream::TransformH2S(Int_t smn, Int_t &row, Int_t &col) const
545 // This does the transformation of the hardware coordinate to
547 // i.e., For SuperModule 0 &1, instead of 96x48(hardware),
548 // it is 48x96 (software)
549 // For Supermodule 3 & 4, 48x96
559 else if(smn >= 12 && smn < 24)
568 //_____________________________________________________________________________
569 Int_t AliPMDRawStream::ComputeParity(UInt_t data)
571 // Calculate the parity bit
574 for(Int_t j = 0; j<29; j++)
576 if (data & 0x01 ) count++;
580 Int_t parity = count%2;
585 //_____________________________________________________________________________
586 UInt_t AliPMDRawStream::GetNextWord()
588 // Returns the next 32 bit word
589 // inside the raw data payload.
591 if (!fData || fPosition < 0) AliFatal("Raw data payload buffer is not yet initialized !");
594 word |= fData[fPosition++];
595 word |= fData[fPosition++] << 8;
596 word |= fData[fPosition++] << 16;
597 word |= fData[fPosition++] << 24;
602 //_____________________________________________________________________________
603 void AliPMDRawStream::Ddl0Mapping(Int_t moduleNo[], Int_t mcmperBus[],
604 Int_t startRowBus[], Int_t endRowBus[],
605 Int_t startColBus[], Int_t endColBus[])
611 for(Int_t ibus = 1; ibus < 51; ibus++)
613 moduleNo[ibus] = fMapData->GetModuleNo(iddl,ibus);
614 mcmperBus[ibus] = fMapData->GetMcmperBus(iddl,ibus);
615 startRowBus[ibus] = fMapData->GetStartRowBus(iddl,ibus);
616 startColBus[ibus] = fMapData->GetStartColBus(iddl,ibus);
617 endRowBus[ibus] = fMapData->GetEndRowBus(iddl,ibus);
618 endColBus[ibus] = fMapData->GetEndColBus(iddl,ibus);
623 //_____________________________________________________________________________
624 void AliPMDRawStream::Ddl1Mapping(Int_t moduleNo[], Int_t mcmperBus[],
625 Int_t startRowBus[], Int_t endRowBus[],
626 Int_t startColBus[], Int_t endColBus[])
632 for(Int_t ibus = 1; ibus < 51; ibus++)
634 moduleNo[ibus] = fMapData->GetModuleNo(iddl,ibus);
635 mcmperBus[ibus] = fMapData->GetMcmperBus(iddl,ibus);
636 startRowBus[ibus] = fMapData->GetStartRowBus(iddl,ibus);
637 startColBus[ibus] = fMapData->GetStartColBus(iddl,ibus);
638 endRowBus[ibus] = fMapData->GetEndRowBus(iddl,ibus);
639 endColBus[ibus] = fMapData->GetEndColBus(iddl,ibus);
646 //_____________________________________________________________________________
647 void AliPMDRawStream::Ddl2Mapping(Int_t moduleNo[], Int_t mcmperBus[],
648 Int_t startRowBus[], Int_t endRowBus[],
649 Int_t startColBus[], Int_t endColBus[])
655 for(Int_t ibus = 1; ibus < 51; ibus++)
657 moduleNo[ibus] = fMapData->GetModuleNo(iddl,ibus);
658 mcmperBus[ibus] = fMapData->GetMcmperBus(iddl,ibus);
659 startRowBus[ibus] = fMapData->GetStartRowBus(iddl,ibus);
660 startColBus[ibus] = fMapData->GetStartColBus(iddl,ibus);
661 endRowBus[ibus] = fMapData->GetEndRowBus(iddl,ibus);
662 endColBus[ibus] = fMapData->GetEndColBus(iddl,ibus);
668 //_____________________________________________________________________________
669 void AliPMDRawStream::Ddl3Mapping(Int_t moduleNo[], Int_t mcmperBus[],
670 Int_t startRowBus[], Int_t endRowBus[],
671 Int_t startColBus[], Int_t endColBus[])
677 for(Int_t ibus = 1; ibus < 51; ibus++)
679 moduleNo[ibus] = fMapData->GetModuleNo(iddl,ibus);
680 mcmperBus[ibus] = fMapData->GetMcmperBus(iddl,ibus);
681 startRowBus[ibus] = fMapData->GetStartRowBus(iddl,ibus);
682 startColBus[ibus] = fMapData->GetStartColBus(iddl,ibus);
683 endRowBus[ibus] = fMapData->GetEndRowBus(iddl,ibus);
684 endColBus[ibus] = fMapData->GetEndColBus(iddl,ibus);
690 //_____________________________________________________________________________
691 void AliPMDRawStream::Ddl4Mapping(Int_t moduleNo[], Int_t mcmperBus[],
692 Int_t startRowBus[], Int_t endRowBus[],
693 Int_t startColBus[], Int_t endColBus[])
699 for(Int_t ibus = 1; ibus < 51; ibus++)
701 moduleNo[ibus] = fMapData->GetModuleNo(iddl,ibus);
702 mcmperBus[ibus] = fMapData->GetMcmperBus(iddl,ibus);
703 startRowBus[ibus] = fMapData->GetStartRowBus(iddl,ibus);
704 startColBus[ibus] = fMapData->GetStartColBus(iddl,ibus);
705 endRowBus[ibus] = fMapData->GetEndRowBus(iddl,ibus);
706 endColBus[ibus] = fMapData->GetEndColBus(iddl,ibus);
713 //_____________________________________________________________________________
714 void AliPMDRawStream::Ddl5Mapping(Int_t moduleNo[], Int_t mcmperBus[],
715 Int_t startRowBus[], Int_t endRowBus[],
716 Int_t startColBus[], Int_t endColBus[])
722 for(Int_t ibus = 1; ibus < 51; ibus++)
724 moduleNo[ibus] = fMapData->GetModuleNo(iddl,ibus);
725 mcmperBus[ibus] = fMapData->GetMcmperBus(iddl,ibus);
726 startRowBus[ibus] = fMapData->GetStartRowBus(iddl,ibus);
727 startColBus[ibus] = fMapData->GetStartColBus(iddl,ibus);
728 endRowBus[ibus] = fMapData->GetEndRowBus(iddl,ibus);
729 endColBus[ibus] = fMapData->GetEndColBus(iddl,ibus);
734 //_____________________________________________________________________________
736 AliPMDMappingData* AliPMDRawStream::GetMappingData() const
738 // Fetching the mapping data from CDB
740 AliCDBEntry *entry = AliCDBManager::Instance()->Get("PMD/Calib/Mapping");
742 if(!entry) AliFatal("Mapping object retrieval failed!");
744 AliPMDMappingData *mapdata=0;
745 if (entry) mapdata = (AliPMDMappingData*) entry->GetObject();
747 if (!mapdata) AliFatal("No Mapping data from CDB !");
754 //_____________________________________________________________________________