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 generator and reader in ALICE-MUON
19 // This 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)
26 // Generates raw data for MUON tracker and finally for trigger
27 // Using real mapping (inverse) for tracker
28 // For trigger there is no mapping (mapping could be found in AliMUONTriggerCircuit)
32 // Using real mapping for tracker
33 // Indranil Das (Adapted for runloader: Ch. Finck) july 05
35 ////////////////////////////////////
40 #include <TClonesArray.h>
42 #include "AliLoader.h"
43 #include "AliBitPacking.h"
44 #include "AliRawReader.h"
49 #include "AliMUONRawReader.h"
50 #include "AliMUONDigit.h"
52 #include "AliMUONConstants.h"
53 #include "AliMUONData.h"
55 #include "AliMUONSubEventTracker.h"
56 #include "AliMUONSubEventTrigger.h"
57 #include "AliMUONDDLTracker.h"
58 #include "AliMUONDDLTrigger.h"
60 #include "AliMUONLocalTrigger.h"
61 #include "AliMUONGlobalTrigger.h"
63 #include "AliMUONGeometrySegmentation.h"
64 #include "AliMUONGeometryModule.h"
65 #include "AliMUONGeometryStore.h"
66 #include "AliMpSegFactory.h"
67 #include "AliMpPlaneType.h"
68 #include "AliMpVSegmentation.h"
69 #include "AliMpHelper.h"
73 ClassImp(AliMUONRawReader) // Class implementation in ROOT context
74 //__________________________________________________________________________
75 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()
107 // Default Constructor
111 //_______________________________________________________________________
112 AliMUONRawReader::AliMUONRawReader (const AliMUONRawReader& rhs)
115 // Protected copy constructor
117 AliFatal("Not implemented.");
120 //_______________________________________________________________________
122 AliMUONRawReader::operator=(const AliMUONRawReader& rhs)
124 // Protected assignement operator
126 if (this == &rhs) return *this;
128 AliFatal("Not implemented.");
133 //__________________________________________________________________________
134 AliMUONRawReader::~AliMUONRawReader(void)
137 fSegFactory->DeleteSegmentations();
145 fBusPatchManager->Delete();
150 //____________________________________________________________________
151 Int_t AliMUONRawReader::Raw2Digits(AliRawReader* rawReader)
155 ReadTrackerDDL(rawReader);
158 ReadTriggerDDL(rawReader);
164 //____________________________________________________________________
165 Int_t AliMUONRawReader::ReadTrackerDDL(AliRawReader* rawReader)
167 // reading tracker DDL
168 // filling the TClonesArray in MUONData
171 AliMUONSubEventTracker* subEventTracker = new AliMUONSubEventTracker();
172 AliMUONDigit* digit = new AliMUONDigit();
175 //Read Header Size of DDL,Block,DSP and BusPatch.
177 Int_t ddlHeaderSize = fDDLTracker->GetHeaderSize();
178 Int_t blockHeaderSize = fDDLTracker->GetBlkHeaderLength();
179 Int_t dspHeaderSize = fDDLTracker->GetDspHeaderLength();
180 Int_t buspatchHeaderSize = subEventTracker->GetHeaderLength();
182 Int_t totalDDLSize, totalBlockSize, totalDspSize , totalBusPatchSize, dataSize;
185 Int_t iBusPerDSP[5];//number of bus patches per DSP
186 Int_t iDspMax; //number max of DSP per block
188 // minimum data size (only header's)
190 Int_t blankBlockSize;
193 for(Int_t iDDL = 0; iDDL < 20; iDDL++) { // DDL loop
195 AliDebug(3, Form("Chamber %d\n", iDDL/2 +1 ));
198 fBusPatchManager->GetDspInfo(iDDL/2, iDspMax, iBusPerDSP);
200 // 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.
201 // This information is used to calculate the size of headers (DDL,Block and DSP) which has no interesting data.
202 blankDDLSize = ddlHeaderSize + 2*blockHeaderSize + 2*iDspMax*dspHeaderSize;
203 blankBlockSize = blockHeaderSize + iDspMax*dspHeaderSize;
205 for (Int_t i = 0; i < iDspMax; i++) {
206 blankDDLSize += 2*iBusPerDSP[i]*buspatchHeaderSize;
207 blankBlockSize += iBusPerDSP[i]*buspatchHeaderSize;
210 rawReader->Select(0X9, iDDL, iDDL); //Select the DDL file to be read
212 rawReader->ReadHeader();
214 totalDDLSize = (rawReader->GetDataSize() + sizeof(AliRawDataHeader))/4; // 4 is multiplied to convert byte 2 words
216 if(totalDDLSize > blankDDLSize) { // Compare the DDL header with an empty DDL header size to read the file
218 Int_t totalDataWord = rawReader->GetDataSize()/4 ;
219 UInt_t *buffer = new UInt_t[totalDataWord];
220 for(Int_t i = 0; i < totalDataWord; i++) {
221 UInt_t& temp = buffer[i];
222 rawReader->ReadNextInt(temp); // takes the whole result into buffer variable for future analysis
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 += blockHeaderSize;
243 for(Int_t iDsp = 0; iDsp < iDspMax ;iDsp++){ //DSP loop
245 totalDspSize = buffer[index];
248 blankDspSize = dspHeaderSize + iBusPerDSP[iDsp]*buspatchHeaderSize; // no data just header
250 if(totalDspSize > blankDspSize) { // Compare DSP Header
251 index += dspHeaderSize;
253 for(Int_t iBusPatch = 0; iBusPatch < iBusPerDSP[iDsp]; iBusPatch++) {
255 totalBusPatchSize = buffer[index];
256 buspatchId = buffer[index+2];
257 indexBusPatch = index;
259 if(totalBusPatchSize > buspatchHeaderSize) { //Check Buspatch header
261 index += buspatchHeaderSize;
262 dataSize = totalBusPatchSize - buspatchHeaderSize;
264 if(dataSize>0) { // check data present
266 for(Int_t iData = 0; iData < dataSize; iData++) {
268 subEventTracker->SetData(buffer[index++],iData); //Set to extract data
270 parity = subEventTracker->GetParity(iData); // test later for parity
271 manuId = subEventTracker->GetManuId(iData);
272 channelId = subEventTracker->GetChannelId(iData);
273 charge = subEventTracker->GetCharge(iData);
275 digit->SetSignal(charge);
277 Int_t error = GetMapping(buspatchId,manuId,channelId,digit); // Get Back the hits at pads
281 if (AliLog::GetGlobalDebugLevel() == 3) {
282 Int_t padX = digit->PadX();
283 Int_t padY = digit->PadY();
284 Int_t iCath = digit->Cathode();
285 Int_t idDE = digit->DetElemId();
287 AliDebug(1,Form("output IdDE %d busPatchid %d PadX %d PadY %d iCath %d \n",
288 idDE, buspatchId, padX, padY, iCath));
290 AliDebug(3,Form("idDE %d Padx %d Pady %d, Cath %d, charge %d",idDE, padX, padY, iCath, charge));
294 fMUONData->AddDigit(iDDL/2, *digit);
298 } // testing buspatch
300 index = indexBusPatch + totalBusPatchSize;
306 index = indexDsp + totalDspSize;
312 index = totalBlockSize;
317 } //loop checking the header size of DDL
323 delete subEventTracker;
329 //____________________________________________________________________
330 Int_t AliMUONRawReader::GetMapping(Int_t busPatchId, UShort_t manuId,
331 UChar_t channelId, AliMUONDigit* digit )
334 // mapping for tracker
336 // getting DE from buspatch
337 Int_t idDE = fBusPatchManager->GetDEfromBus(busPatchId);
338 AliDebug(3,Form("idDE: %d busPatchId %d\n", idDE, busPatchId));
346 AliMpPlaneType plane;
348 if (manuId > 1000) { // again tmp solution (ChF) (+1000 for Non-Bending plane
349 plane = kNonBendingPlane;
351 plane = kBendingPlane;
355 if (idDE < 500) { // should use GetDirection somehow (ChF)
356 if ( ((idDE % 100) % 2) != 0 ) {
362 iCath = (manuId > 1000) ? iCath2 : iCath1;
364 if (manuId > 1000) manuId -= 1000; // back to normal manuId
366 // Could the above logic be simplified ???
367 //AliMpVSegmentation* seg = AliMUONSegmentationManager::Segmentation(idDE, plane);
368 AliMpVSegmentation* seg = fSegFactory->CreateMpSegmentation(idDE, iCath);
369 AliMpPad pad = seg->PadByLocation(AliMpIntPair(manuId,(Int_t)channelId),kTRUE);
372 AliWarning(Form("No pad for idDE: %d, busPatchId %d, manuId: %d, channelId: %d\n",
373 idDE, busPatchId, manuId, channelId));
378 Int_t padX = pad.GetIndices().GetFirst();
381 Int_t padY = pad.GetIndices().GetSecond();
383 if (idDE >= 500) { // Since in AliMpSlat pads begin at (0,0)
384 padX++; // while in AliMUONSt345Seg. they begin at (1,1)
387 // storing into digits
388 digit->SetPadX(padX);
389 digit->SetPadY(padY);
390 digit->SetCathode(iCath);
391 digit->SetDetElemId(idDE);
393 AliDebug(3,Form("idDE: %d, busPatchId %d, manuId: %d, channelId: %d, padx: %d pady %d\n",
394 idDE, busPatchId, manuId, channelId, padX, padY));
398 //____________________________________________________________________
399 Int_t AliMUONRawReader::ReadTriggerDDL(AliRawReader* rawReader)
402 // reading DDL for trigger
404 AliMUONSubEventTrigger* subEventTrigger = new AliMUONSubEventTrigger();
405 AliMUONGlobalTrigger* globalTrigger = 0x0;
406 AliMUONLocalTrigger* localTrigger = new AliMUONLocalTrigger();
409 //Int_t ddlHeaderSize = fDDLTrigger->GetHeaderSize();
410 // we dont need this, as size of ddl data is same for triger and no trigger
412 Int_t ddlEnhanceHeaderSize = fDDLTrigger->GetHeaderLength();
413 Int_t regHeaderLength = subEventTrigger->GetRegHeaderLength() ;
415 Int_t loCircuit, loStripX, loDev, loStripY, loLpt, loHpt;
418 UShort_t x1Pattern, x2Pattern, x3Pattern, x4Pattern;
419 UShort_t y1Pattern, y2Pattern, y3Pattern, y4Pattern;
422 // loop over the two ddl's
423 for(Int_t iDDL = 0; iDDL < 2; iDDL++) { //DDL loop
425 rawReader->Select(0XA,iDDL,iDDL); //Select the DDL file to be read
427 rawReader->ReadHeader();
429 Int_t totalDataWord = rawReader->GetDataSize()/4 ;
430 UInt_t *buffer = new UInt_t[totalDataWord];
431 for(Int_t i=0;i<totalDataWord;i++){
432 UInt_t& temp = buffer[i];
433 rawReader->ReadNextInt(temp); // takes the whole result into buffer variable for future analysis
436 // rawReader->ReadNext((UChar_t*)buffer, totalDataWord); // method is protected ????
440 // fill DDL header informations
441 memcpy(fDDLTrigger->GetEnhancedHeader(), &buffer[index], ddlEnhanceHeaderSize*4);
443 // fill global trigger information
444 globalTrigger = GetGlobalTriggerPattern(fDDLTrigger->GetGlobalOuput());
445 fMUONData->AddGlobalTrigger(*globalTrigger);
447 index += ddlEnhanceHeaderSize;
450 for (Int_t iReg = 0; iReg < 8; iReg++) { //loop over regeonal card
453 subEventTrigger->SetRegWord(buffer[index]); //read regional data
455 index += regHeaderLength;
457 // 16 local cards per regional board
458 for (Int_t iLoc = 0; iLoc < 16; iLoc++) { //loop over local card
460 Int_t iLocIndex = index;
462 // 5 word trigger information
463 for(Int_t iData = 0; iData < 5 ;iData++ ){
464 subEventTrigger->SetLocalData(buffer[index++],5*iLoc+iData); //read local data
467 if(buffer[iLocIndex] > 0) {
469 loCircuit = (Int_t)subEventTrigger->GetLocalId(iLoc)+ 16*iReg + 128*iDDL;
470 loStripX = (Int_t)subEventTrigger->GetXPos(iLoc);
471 loStripY = (Int_t)subEventTrigger->GetYPos(iLoc);
472 loDev = (Int_t)subEventTrigger->GetXDev(iLoc);
474 // fill local trigger
475 localTrigger->SetLoCircuit(loCircuit);
476 localTrigger->SetLoStripX(loStripX );
477 localTrigger->SetLoStripY(loStripY);
478 localTrigger->SetLoDev(loDev);
480 loDecision = subEventTrigger->GetLocalDec(iLoc);
481 loLpt = loDecision & 0x3;
482 loHpt = (loDecision >> 2) & 0x3;
484 // fill local trigger
485 localTrigger->SetLoLpt(loLpt);
486 localTrigger->SetLoHpt(loHpt);
488 //getting pattern from subvent
489 x1Pattern = subEventTrigger->GetX1(iLoc);
490 x2Pattern = subEventTrigger->GetX2(iLoc);
491 x3Pattern = subEventTrigger->GetX3(iLoc);
492 x4Pattern = subEventTrigger->GetX4(iLoc);
494 y1Pattern = subEventTrigger->GetY1(iLoc);
495 y2Pattern = subEventTrigger->GetY2(iLoc);
496 y3Pattern = subEventTrigger->GetY3(iLoc);
497 y4Pattern = subEventTrigger->GetY4(iLoc);
499 // fill local trigger
500 localTrigger->SetX1Pattern(x1Pattern);
501 localTrigger->SetX2Pattern(x2Pattern);
502 localTrigger->SetX3Pattern(x3Pattern);
503 localTrigger->SetX4Pattern(x4Pattern);
505 localTrigger->SetY1Pattern(y1Pattern);
506 localTrigger->SetY2Pattern(y2Pattern);
507 localTrigger->SetY3Pattern(y3Pattern);
508 localTrigger->SetY4Pattern(y4Pattern);
509 fMUONData->AddLocalTrigger(*localTrigger);
515 } // regional card loop
520 delete subEventTrigger;
521 delete globalTrigger;
527 //____________________________________________________________________
528 AliMUONGlobalTrigger* AliMUONRawReader::GetGlobalTriggerPattern(Int_t gloTrigPat) const
530 // global trigger pattern calculation
532 Int_t globalSinglePlus[3]; // tot num of single plus
533 Int_t globalSingleMinus[3]; // tot num of single minus
534 Int_t globalSingleUndef[3]; // tot num of single undefined
535 Int_t globalPairUnlike[3]; // tot num of unlike-sign pairs
536 Int_t globalPairLike[3]; // tot num of like-sign pairs
539 for (Int_t i = 0; i < 3; i++) {
540 globalSinglePlus[i] = gloTrigPat & (0x1 << i);
541 globalSingleMinus[i] = gloTrigPat & (0x1 << i+3);
542 globalSingleUndef[i] = gloTrigPat & (0x1 << i+6);
543 globalPairUnlike[i] = gloTrigPat & (0x1 << i+9);
544 globalPairLike[i] = gloTrigPat & (0x1 << i+12);
547 return (new AliMUONGlobalTrigger(globalSinglePlus, globalSingleMinus,
548 globalSingleUndef, globalPairUnlike,