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 **************************************************************************/
16 ////////////////////////////////////
18 // MUON Raw Data reader in ALICE-MUON
19 // Class version 3 (further details could be found in Alice-note)
21 // Implemented non-constant buspatch numbers for tracking
22 // with correct DDL id (first guess)
23 // (Ch. Finck, dec 2005)
27 // Using real mapping for tracker
28 // Indranil Das (Adapted for runloader: Ch. Finck) july 05
29 // Add reader for scaler trigger events
30 // Use memcpy instead of assignment elt by elt
31 // (Ch. Finck, Jan 06)
33 ////////////////////////////////////
38 #include <TClonesArray.h>
40 #include "AliLoader.h"
41 #include "AliBitPacking.h"
42 #include "AliRawReader.h"
47 #include "AliMUONRawReader.h"
48 #include "AliMUONDigit.h"
50 #include "AliMUONConstants.h"
51 #include "AliMUONData.h"
53 #include "AliMUONSubEventTracker.h"
54 #include "AliMUONScalerEventTrigger.h"
55 #include "AliMUONSubEventTrigger.h"
56 #include "AliMUONDDLTracker.h"
57 #include "AliMUONDDLTrigger.h"
59 #include "AliMUONLocalTrigger.h"
60 #include "AliMUONGlobalTrigger.h"
62 #include "AliMUONGeometrySegmentation.h"
63 #include "AliMUONGeometryModule.h"
64 #include "AliMUONGeometryStore.h"
65 #include "AliMpSegFactory.h"
66 #include "AliMpPlaneType.h"
67 #include "AliMpVSegmentation.h"
68 #include "AliMpHelper.h"
72 ClassImp(AliMUONRawReader) // Class implementation in ROOT context
73 //__________________________________________________________________________
74 AliMUONRawReader::AliMUONRawReader(AliLoader* loader, AliMUONData* data)
78 // Standard Constructor
80 // initialize loader's
83 // initialize segmentation factory
84 fSegFactory = new AliMpSegFactory();
86 // initialize container
90 fDDLTracker = new AliMUONDDLTracker();
91 fDDLTrigger = new AliMUONDDLTrigger();
93 fBusPatchManager = new AliMpBusPatch();
94 fBusPatchManager->ReadBusPatchFile();
98 //__________________________________________________________________________
99 AliMUONRawReader::AliMUONRawReader()
109 // Default Constructor
113 //_______________________________________________________________________
114 AliMUONRawReader::AliMUONRawReader (const AliMUONRawReader& rhs)
117 // Protected copy constructor
119 AliFatal("Not implemented.");
122 //_______________________________________________________________________
124 AliMUONRawReader::operator=(const AliMUONRawReader& rhs)
126 // Protected assignement operator
128 if (this == &rhs) return *this;
130 AliFatal("Not implemented.");
135 //__________________________________________________________________________
136 AliMUONRawReader::~AliMUONRawReader(void)
139 fSegFactory->DeleteSegmentations();
147 fBusPatchManager->Delete();
152 //____________________________________________________________________
153 Int_t AliMUONRawReader::Raw2Digits(AliRawReader* rawReader)
157 ReadTrackerDDL(rawReader);
160 ReadTriggerDDL(rawReader);
166 //____________________________________________________________________
167 Int_t AliMUONRawReader::ReadTrackerDDL(AliRawReader* rawReader)
169 // reading tracker DDL
170 // filling the TClonesArray in MUONData
173 AliMUONSubEventTracker* subEventTracker = new AliMUONSubEventTracker();
174 AliMUONDigit* digit = new AliMUONDigit();
177 //Read Header Size of DDL,Block,DSP and BusPatch (put k before constant imb'cile)
179 Int_t kDDLHeaderSize = fDDLTracker->GetHeaderSize();
180 Int_t kBlockHeaderSize = fDDLTracker->GetBlkHeaderLength();
181 Int_t kDspHeaderSize = fDDLTracker->GetDspHeaderLength();
182 Int_t kBusPatchHeaderSize = subEventTracker->GetHeaderLength();
184 Int_t totalDDLSize, totalBlockSize, totalDspSize , totalBusPatchSize, dataSize;
187 Int_t iBusPerDSP[5];//number of bus patches per DSP
188 Int_t iDspMax; //number max of DSP per block
190 // minimum data size (only header's)
192 Int_t blankBlockSize;
195 for(Int_t iDDL = 0; iDDL < 20; iDDL++) { // DDL loop
197 AliDebug(3, Form("Chamber %d\n", iDDL/2 +1 ));
200 fBusPatchManager->GetDspInfo(iDDL/2, iDspMax, iBusPerDSP);
202 // Each DDL is made with 2 Blocks each of which consists of 5 DSP's at most and each of DSP has at most 5 buspatches.
203 // This information is used to calculate the size of headers (DDL,Block and DSP) which has no interesting data.
204 blankDDLSize = kDDLHeaderSize + 2*kBlockHeaderSize + 2*iDspMax*kDspHeaderSize;
205 blankBlockSize = kBlockHeaderSize + iDspMax*kDspHeaderSize;
207 for (Int_t i = 0; i < iDspMax; i++) {
208 blankDDLSize += 2*iBusPerDSP[i]*kBusPatchHeaderSize;
209 blankBlockSize += iBusPerDSP[i]*kBusPatchHeaderSize;
212 rawReader->Select(0X9, iDDL, iDDL); //Select the DDL file to be read
214 rawReader->ReadHeader();
216 totalDDLSize = (rawReader->GetDataSize() + sizeof(AliRawDataHeader))/4; // 4 is multiplied to convert byte 2 words
218 if(totalDDLSize > blankDDLSize) { // Compare the DDL header with an empty DDL header size to read the file
220 Int_t totalDataWord = rawReader->GetDataSize(); // in bytes
221 UInt_t *buffer = new UInt_t[totalDataWord/4];
223 rawReader->ReadNext((UChar_t*)buffer, totalDataWord);
237 for(Int_t iBlock = 0; iBlock < 2 ;iBlock++){ // loop over 2 blocks
238 totalBlockSize = buffer[index];
240 if(totalBlockSize > blankBlockSize) { // compare block header
241 index += kBlockHeaderSize;
243 for(Int_t iDsp = 0; iDsp < iDspMax ;iDsp++){ //DSP loop
245 totalDspSize = buffer[index];
248 blankDspSize = kDspHeaderSize + iBusPerDSP[iDsp]*kBusPatchHeaderSize; // no data just header
250 if(totalDspSize > blankDspSize) { // Compare DSP Header
251 index += kDspHeaderSize;
253 for(Int_t iBusPatch = 0; iBusPatch < iBusPerDSP[iDsp]; iBusPatch++) {
255 //copy buffer into header structure
256 memcpy(subEventTracker->GetBusPatchHeader(), &buffer[index], kBusPatchHeaderSize*4);
258 totalBusPatchSize = subEventTracker->GetTotalLength();
259 buspatchId = subEventTracker->GetBusPatchId();
260 indexBusPatch = index;
263 if(totalBusPatchSize > kBusPatchHeaderSize) { //Check Buspatch header, not empty events
265 index += kBusPatchHeaderSize;
266 dataSize = subEventTracker->GetLength();
268 if(dataSize>0) { // check data present
270 //copy buffer into data structure
271 memcpy(subEventTracker->GetData(), &buffer[index], dataSize*4);
274 for(Int_t iData = 0; iData < dataSize; iData++) {
277 parity = subEventTracker->GetParity(iData); // test later for parity
278 manuId = subEventTracker->GetManuId(iData);
279 channelId = subEventTracker->GetChannelId(iData);
280 charge = subEventTracker->GetCharge(iData);
282 digit->SetSignal(charge);
284 Int_t error = GetMapping(buspatchId,manuId,channelId,digit); // Get Back the hits at pads
288 if (AliLog::GetGlobalDebugLevel() == 3) {
289 Int_t padX = digit->PadX();
290 Int_t padY = digit->PadY();
291 Int_t iCath = digit->Cathode();
292 Int_t idDE = digit->DetElemId();
294 AliDebug(1,Form("output IdDE %d busPatchid %d PadX %d PadY %d iCath %d \n",
295 idDE, buspatchId, padX, padY, iCath));
297 AliDebug(3,Form("idDE %d Padx %d Pady %d, Cath %d, charge %d",idDE, padX, padY, iCath, charge));
301 fMUONData->AddDigit(iDDL/2, *digit);
305 } // testing buspatch
307 index = indexBusPatch + totalBusPatchSize;
313 index = indexDsp + totalDspSize;
319 index = totalBlockSize;
324 } //loop checking the header size of DDL
330 delete subEventTracker;
336 //____________________________________________________________________
337 Int_t AliMUONRawReader::GetMapping(Int_t busPatchId, UShort_t manuId,
338 UChar_t channelId, AliMUONDigit* digit )
341 // mapping for tracker
343 // getting DE from buspatch
344 Int_t idDE = fBusPatchManager->GetDEfromBus(busPatchId);
345 AliDebug(3,Form("idDE: %d busPatchId %d\n", idDE, busPatchId));
352 if (idDE < 500) { // should use GetDirection somehow (ChF)
353 if ( ((idDE % 100) % 2) != 0 ) {
359 iCath = (manuId > 1000) ? iCath2 : iCath1;
361 if (manuId > 1000) manuId -= 1000; // back to normal manuId
363 // Could the above logic be simplified ???
364 //AliMpVSegmentation* seg = AliMUONSegmentationManager::Segmentation(idDE, plane);
365 AliMpVSegmentation* seg = fSegFactory->CreateMpSegmentation(idDE, iCath);
366 AliMpPad pad = seg->PadByLocation(AliMpIntPair(manuId,(Int_t)channelId),kTRUE);
369 AliWarning(Form("No pad for idDE: %d, busPatchId %d, manuId: %d, channelId: %d\n",
370 idDE, busPatchId, manuId, channelId));
375 Int_t padX = pad.GetIndices().GetFirst();
378 Int_t padY = pad.GetIndices().GetSecond();
380 if (idDE >= 500) { // Since in AliMpSlat pads begin at (0,0)
381 padX++; // while in AliMUONSt345Seg. they begin at (1,1)
384 // storing into digits
385 digit->SetPadX(padX);
386 digit->SetPadY(padY);
387 digit->SetCathode(iCath);
388 digit->SetDetElemId(idDE);
390 AliDebug(3,Form("idDE: %d, busPatchId %d, manuId: %d, channelId: %d, padx: %d pady %d\n",
391 idDE, busPatchId, manuId, channelId, padX, padY));
395 //____________________________________________________________________
396 Int_t AliMUONRawReader::ReadTriggerDDL(AliRawReader* rawReader)
399 // reading DDL for trigger
401 AliMUONSubEventTrigger* subEventTrigger = new AliMUONSubEventTrigger();
402 AliMUONScalerEventTrigger* scalerEvent = 0x0;
404 AliMUONGlobalTrigger* globalTrigger = 0x0;
405 AliMUONLocalTrigger* localTrigger = new AliMUONLocalTrigger();
408 //Int_t kDDLHeaderSize = fDDLTrigger->GetHeaderSize();
409 // we dont need this, as size of ddl data is same for triger and no trigger
411 Int_t kDDLEnhanceHeaderSize = fDDLTrigger->GetHeaderLength();
412 Int_t kRegHeaderSize = subEventTrigger->GetRegHeaderLength() ;
414 Int_t loCircuit, loStripX, loDev, loStripY, loLpt, loHpt;
417 UShort_t x1Pattern, x2Pattern, x3Pattern, x4Pattern;
418 UShort_t y1Pattern, y2Pattern, y3Pattern, y4Pattern;
420 // loop over the two ddl's
421 for(Int_t iDDL = 0; iDDL < 2; iDDL++) { //DDL loop
423 rawReader->Select(0XA,iDDL,iDDL); //Select the DDL file to be read
425 rawReader->ReadHeader();
427 Int_t totalDataWord = rawReader->GetDataSize(); // in bytes
428 UInt_t *buffer = new UInt_t[totalDataWord/4];
430 rawReader->ReadNext((UChar_t*)buffer, totalDataWord);
433 fDDLTrigger->SetDDLWord(buffer[index++]);
435 if(fDDLTrigger->GetEventType() == 2) {
436 fScalerEvent = kTRUE;
437 scalerEvent = new AliMUONScalerEventTrigger();
439 fScalerEvent = kFALSE;
442 // 6 DARC scaler words
443 memcpy(scalerEvent->GetDarcScalers(), &buffer[index], scalerEvent->GetDarcScalerLength()*4);
444 index += scalerEvent->GetDarcScalerLength();
447 // 4 words of global board input + Global board output
448 memcpy(fDDLTrigger->GetGlobalInput(), &buffer[index], (kDDLEnhanceHeaderSize-1)*4);
449 index += kDDLEnhanceHeaderSize - 1; // kind tricky cos scaler info in-between Darc header
452 // 10 Global scaler words
453 memcpy(scalerEvent->GetGlobalScalers(), &buffer[index], scalerEvent->GetGlobalScalerLength()*4);
454 index += scalerEvent->GetGlobalScalerLength();
457 // fill global trigger information
458 globalTrigger = GetGlobalTriggerPattern(fDDLTrigger->GetGlobalOuput());
459 fMUONData->AddGlobalTrigger(*globalTrigger);
462 for (Int_t iReg = 0; iReg < 8; iReg++) { //loop over regeonal card
464 memcpy(subEventTrigger->GetRegHeader(), &buffer[index], kRegHeaderSize*4);
465 index += kRegHeaderSize;
467 // 11 regional scaler word
469 memcpy(scalerEvent->GetRegScalers(), &buffer[index], scalerEvent->GetRegScalerLength()*4);
470 index += scalerEvent->GetRegScalerLength();
473 // 16 local cards per regional board
474 for (Int_t iLoc = 0; iLoc < 16; iLoc++) { //loop over local card
476 Int_t iLocIndex = index;
478 // 5 word trigger information
479 for(Int_t iData = 0; iData < 5 ;iData++ ){
480 subEventTrigger->SetLocalData(buffer[index++],5*iLoc+iData); //read local data
483 if(buffer[iLocIndex] > 0) {
485 loCircuit = (Int_t)subEventTrigger->GetLocalId(iLoc)+ 16*iReg + 128*iDDL;
486 loStripX = (Int_t)subEventTrigger->GetXPos(iLoc);
487 loStripY = (Int_t)subEventTrigger->GetYPos(iLoc);
488 loDev = (Int_t)subEventTrigger->GetXDev(iLoc);
490 // fill local trigger
491 localTrigger->SetLoCircuit(loCircuit);
492 localTrigger->SetLoStripX(loStripX );
493 localTrigger->SetLoStripY(loStripY);
494 localTrigger->SetLoDev(loDev);
496 loDecision = subEventTrigger->GetLocalDec(iLoc);
497 loLpt = loDecision & 0x3;
498 loHpt = (loDecision >> 2) & 0x3;
500 // fill local trigger
501 localTrigger->SetLoLpt(loLpt);
502 localTrigger->SetLoHpt(loHpt);
504 //getting pattern from subvent
505 x1Pattern = subEventTrigger->GetX1(iLoc);
506 x2Pattern = subEventTrigger->GetX2(iLoc);
507 x3Pattern = subEventTrigger->GetX3(iLoc);
508 x4Pattern = subEventTrigger->GetX4(iLoc);
510 y1Pattern = subEventTrigger->GetY1(iLoc);
511 y2Pattern = subEventTrigger->GetY2(iLoc);
512 y3Pattern = subEventTrigger->GetY3(iLoc);
513 y4Pattern = subEventTrigger->GetY4(iLoc);
515 // fill local trigger
516 localTrigger->SetX1Pattern(x1Pattern);
517 localTrigger->SetX2Pattern(x2Pattern);
518 localTrigger->SetX3Pattern(x3Pattern);
519 localTrigger->SetX4Pattern(x4Pattern);
521 localTrigger->SetY1Pattern(y1Pattern);
522 localTrigger->SetY2Pattern(y2Pattern);
523 localTrigger->SetY3Pattern(y3Pattern);
524 localTrigger->SetY4Pattern(y4Pattern);
525 fMUONData->AddLocalTrigger(*localTrigger);
529 // 45 regional scaler word
531 memcpy(scalerEvent->GetLocalScalers(), &buffer[index], scalerEvent->GetLocalScalerLength()*4);
532 index += scalerEvent->GetLocalScalerLength();
537 } // regional card loop
542 delete subEventTrigger;
543 delete globalTrigger;
552 //____________________________________________________________________
553 AliMUONGlobalTrigger* AliMUONRawReader::GetGlobalTriggerPattern(Int_t gloTrigPat) const
555 // global trigger pattern calculation
557 Int_t globalSinglePlus[3]; // tot num of single plus
558 Int_t globalSingleMinus[3]; // tot num of single minus
559 Int_t globalSingleUndef[3]; // tot num of single undefined
560 Int_t globalPairUnlike[3]; // tot num of unlike-sign pairs
561 Int_t globalPairLike[3]; // tot num of like-sign pairs
564 for (Int_t i = 0; i < 3; i++) {
566 globalSinglePlus[i] = (gloTrigPat >> i) & 0x1;
567 globalSingleMinus[i] = (gloTrigPat >> (i+3)) & 0x1;
568 globalSingleUndef[i] = (gloTrigPat >> (i+6)) & 0x1;
569 globalPairUnlike[i] = (gloTrigPat >> (i+9)) & 0x1;
570 globalPairLike[i] = (gloTrigPat >> (i+12)) & 0x1;
573 return (new AliMUONGlobalTrigger(globalSinglePlus, globalSingleMinus,
574 globalSingleUndef, globalPairUnlike,