////////////////////////////////////
//
-// MUON Raw Data generator in ALICE-MUON
-//
-// This class v-1:
-// * generates raw data for MUON tracker only (for the moment)
+// MUON Raw Data generator and reader in ALICE-MUON
+// This class version 1 (further details could be found in Alice-note)
+// Digits2Raw:
+// Generates raw data for MUON tracker and finally for trigger
// * a simple mapping is used (see below)
-// * the bus patch id is calculated but not stored properly in the raw data
-// this has to be changed
-// one DDL per 1/2 chamber is created for both cathode.
-//
+// * the bus patch id is calculated with an absolute number 0 - 999
+// * one DDL per 1/2 chamber is created for both cathode.
+// For trigger there is no mapping (mapping could be found in AliMUONTriggerCircuit)
+// Ch. Finck july 04
+// Raw2Digits:
+// Using still dummy mapping (inverse) for tracker
+// Indranil Das (Adapted for runloader: Ch. Finck) july 05
////////////////////////////////////
+#include <TClonesArray.h>
#include "AliMUONRawData.h"
#include "AliMUONDigit.h"
+
+#include "AliMUON.h"
+#include "AliMUONChamber.h"
#include "AliMUONConstants.h"
#include "AliMUONData.h"
-#include "AliMUONDDLTracker.h"
-#include "AliRun.h"
-#include "AliRunLoader.h"
#include "AliLoader.h"
#include "AliBitPacking.h"
+#include "AliRawReader.h"
+
+#include "AliMUONSubEventTrigger.h"
+#include "AliMUONDDLTracker.h"
+#include "AliMUONDDLTrigger.h"
+
+#include "AliMUONLocalTrigger.h"
+#include "AliMUONGlobalTrigger.h"
+
+#include "AliMUONGeometrySegmentation.h"
+#include "AliLog.h"
+#include "AliRun.h"
-const Int_t AliMUONRawData::fgkDefaultPrintLevel = 0;
-ClassImp(AliMUONRawData) // Class implementation in ROOT context
+ClassImp(AliMUONRawData) // Class implementation in ROOT context
//__________________________________________________________________________
-AliMUONRawData::AliMUONRawData(AliLoader* loader)
+ AliMUONRawData::AliMUONRawData(AliLoader* loader)
: TObject()
{
// Standard Constructor
- fDebug = 0;
- fNCh = 0;
- fNTrackingCh = 0;
- fNTriggerCh = 0;
- fMUONData = 0;
-
- fPrintLevel = fgkDefaultPrintLevel;
-
// initialize loader's
fLoader = loader;
// initialize container
fMUONData = new AliMUONData(fLoader,"MUON","MUON");
+
+ // initialize array
+ fSubEventArray[0] = new TClonesArray("AliMUONSubEventTracker",1000);
+ fSubEventArray[1] = new TClonesArray("AliMUONSubEventTracker",1000);
+
+
+ // ddl pointer
+ fDDLTracker = new AliMUONDDLTracker();
+ fDDLTrigger = new AliMUONDDLTrigger();
}
//__________________________________________________________________________
AliMUONRawData::AliMUONRawData()
: TObject(),
- fNCh(0),
- fNTrackingCh(0),
- fNTriggerCh(0),
fMUONData(0),
- fPrintLevel(fgkDefaultPrintLevel),
- fDebug(0),
- fLoader(0)
+ fLoader(0),
+ fFile1(0x0),
+ fFile2(0x0),
+ fDDLTracker(0),
+ fDDLTrigger(0)
+
{
// Default Constructor
}
{
// Protected copy constructor
- Fatal("AliMUONRawData", "Not implemented.");
+ AliFatal("Not implemented.");
}
//_______________________________________________________________________
if (this == &rhs) return *this;
- Fatal("operator=", "Not implemented.");
+ AliFatal("Not implemented.");
return *this;
}
{
if (fMUONData)
delete fMUONData;
+ if (fSubEventArray[0])
+ fSubEventArray[0]->Delete(); //using delete cos allocating memory in copy ctor.
+ if (fSubEventArray[1])
+ fSubEventArray[1]->Delete();
+
+ if (fDDLTracker)
+ delete fDDLTracker;
+ if (fDDLTrigger)
+ delete fDDLTrigger;
+
return;
}
//____________________________________________________________________
-Int_t AliMUONRawData::WriteRawData()
+Int_t AliMUONRawData::Digits2Raw()
{
// convert digits of the current event to raw data
-
- Int_t DDLId;
+ Int_t idDDL;
Char_t name[20];
fLoader->LoadDigits("READ");
- fMUONData->SetTreeAddress("D");
- // printf("je suis dans WriteRawData\n");
- for (Int_t ich = 0; ich < AliMUONConstants::NTrackingCh(); ich++) {
+ fMUONData->SetTreeAddress("D,GLT");
+
+ // tracking chambers
+
+ for (Int_t ich = 0; ich < AliMUONConstants::NTrackingCh(); ich++) {
+
// open files
- DDLId = ich * 2 + 1;
- sprintf(name, "MUON_%d.ddl",DDLId);
+ idDDL = ich * 2 + 0x900;
+ sprintf(name, "MUON_%d.ddl",idDDL);
fFile1 = fopen(name,"w");
- DDLId = (ich * 2 + 1) + 1;
- sprintf(name, "MUON_%d.ddl",DDLId);
+ idDDL = (ich * 2) + 1 + 0x900;
+ sprintf(name, "MUON_%d.ddl",idDDL);
fFile2 = fopen(name,"w");
- WriteDDL(ich);
+ WriteTrackerDDL(ich);
// reset and close
fclose(fFile1);
fclose(fFile2);
fMUONData->ResetDigits();
}
+
+ // trigger chambers
+
+ // open files
+ idDDL = 0xA00;
+ sprintf(name, "MUTR_%d.ddl",idDDL);
+ fFile1 = fopen(name,"w");
+
+ idDDL = 0xA00 + 1;
+ sprintf(name, "MUTR_%d.ddl",idDDL);
+ fFile2 = fopen(name,"w");
+
+ WriteTriggerDDL();
+
+ // reset and close
+ fclose(fFile1);
+ fclose(fFile2);
+ fMUONData->ResetTrigger();
+ fLoader->UnloadDigits();
+
return kTRUE;
}
//____________________________________________________________________
-Int_t AliMUONRawData::WriteDDL(Int_t iCh)
+Int_t AliMUONRawData::WriteTrackerDDL(Int_t iCh)
{
-
+ // resets
TClonesArray* muonDigits = 0;
+ fSubEventArray[0]->Clear();
+ fSubEventArray[1]->Clear();
+
+ //
+ TArrayI nbInBus[2];
+
+ nbInBus[0].Set(5000);
+ nbInBus[1].Set(5000);
+
+ nbInBus[0].Reset();
+ nbInBus[1].Reset();
+
+ // DDL header
+ AliRawDataHeader header = fDDLTracker->GetHeader();
+ Int_t headerSize = fDDLTracker->GetHeaderSize();
// DDL event one per half chamber
- AliMUONDDLTracker* eventDDL1;
- AliMUONDDLTracker* eventDDL2;
+ AliMUONSubEventTracker* subEvent;
// data format
Char_t parity = 0x4;
- UShort_t manuId;
- UChar_t channelId;
- UShort_t charge;
- Int_t busPatchId;
+ UShort_t manuId = 0;
+ UChar_t channelId = 0;
+ UShort_t charge = 0;
+ Int_t busPatchId = 0;
UInt_t word;
- Int_t nWord;
- Int_t dummy;
-
- Int_t offsetX = 0; // offet row
- Int_t offsetY = 0; // offset columns
- Int_t offsetCath = 0; //offset from one cathod to the other
- Int_t maxChannel = 0; // maximum nb of channel in 1/2 chamber
- Int_t id;
-
+ Int_t nEntries = 0;
+ Int_t* buffer = 0;
+ Int_t index;
+ Int_t indexDsp;
+ Int_t indexBlk;
+ Int_t padX;
+ Int_t padY;
+ Int_t cathode = 0;
+ Int_t detElemId;
Int_t nDigits;
- AliMUONDigit* digit;
+ const AliMUONDigit* digit;
+// AliMUON *pMUON;
+// AliMUONChamber* iChamber = 0x0;
+// AliMUONGeometrySegmentation* segmentation2[2];
- eventDDL1 = new AliMUONDDLTracker();
- eventDDL2 = new AliMUONDDLTracker();
+// pMUON = (AliMUON*) gAlice->GetModule("MUON");
+// iChamber = &(pMUON->Chamber(iCh));
- for (Int_t iCath = 0; iCath < 2; iCath++) {
+// segmentation2[0]=iChamber->SegmentationModel2(1); // cathode 0
+// segmentation2[1]=iChamber->SegmentationModel2(2); // cathode 1
- if (fPrintLevel)
- printf("WriteDDL chamber %d and cathode %d\n", iCh+1, iCath);
+ AliDebug(1, Form("WriteDDL chamber %d\n", iCh+1));
+
+ // for (Int_t iCath = 0; iCath < 2; iCath++) {
fMUONData->ResetDigits();
- fMUONData->GetCathode(iCath);
+ fMUONData->GetDigits();
muonDigits = fMUONData->Digits(iCh);
nDigits = muonDigits->GetEntriesFast();
- if (fPrintLevel)
- printf("ndigits = %d\n",nDigits);
+ AliDebug(2,Form("ndigits = %d\n",nDigits));
// open DDL file, on per 1/2 chamber
digit = (AliMUONDigit*) muonDigits->UncheckedAt(idig);
+ padX = digit->PadX();
+ padY = digit->PadY();
+ charge = digit->Signal();
+ charge &= 0xFFF;
+ cathode = digit->Cathode();
+ detElemId = digit->DetElemId();
+
+ // mapping
+// if (detElemId == 0) {
+// AliWarning("\ndetElemId = 0, old segmentation !\n");
+ GetDummyMapping(iCh, cathode, digit, busPatchId, manuId, channelId);
+// } else {
+// // mapping (not far from real one)
+// AliMUONSegmentManuIndex* connect = segmentation2[iCath]->GetMpConnection(detElemId, padX, padY);
+// if (connect != 0x0) {
+// busPatchId = connect->GetBusPatchId();
+// manuId = connect->GetManuId();
+// channelId = connect->GetManuChannelId();
+// AliDebug(3,Form("busPatchId %d, manuId: %d, channelId: %d\n", busPatchId, manuId, channelId));
+// } else {
+// busPatchId = 0;
+// manuId = 0;
+// channelId = 0;
+// }
+
+// }
+ //packing word
+ AliBitPacking::PackWord((UInt_t)parity,word,29,31);
+ AliBitPacking::PackWord((UInt_t)manuId,word,18,28);
+ AliBitPacking::PackWord((UInt_t)channelId,word,12,17);
+ AliBitPacking::PackWord((UInt_t)charge,word,0,11);
+
+ // set sub Event
+ subEvent = new AliMUONSubEventTracker();
+ subEvent->AddData(word);
+ subEvent->SetBusPatchId(busPatchId);
+ if (digit->PadX() > 0) {
+ nbInBus[0][busPatchId]++;
+ AddData1(subEvent);
+ } else {
+ nbInBus[1][busPatchId]++;
+ AddData2(subEvent);
+ }
+ delete subEvent;
+ }
+ // }
+ fSubEventArray[0]->Sort();
+ fSubEventArray[1]->Sort();
+
+ // gather datas from same bus patch
+ for (Int_t iDDL = 0; iDDL < 2; iDDL++) {
+ nEntries = fSubEventArray[iDDL]->GetEntriesFast();
+
+ for (Int_t i = 0; i < nEntries; i++) {
+ AliMUONSubEventTracker* temp = (AliMUONSubEventTracker*)fSubEventArray[iDDL]->At(i);
+ busPatchId = temp->GetBusPatchId();
+
+ // add bus patch header, length and total length managed by subevent class
+ temp->SetTriggerWord(0xdeadbeef);
+ for (Int_t j = 0; j < nbInBus[iDDL][busPatchId]-1; j++) {
+ AliMUONSubEventTracker* temp1 = (AliMUONSubEventTracker*)fSubEventArray[iDDL]->At(++i);
+ temp->AddData(temp1->GetData(0));
+ fSubEventArray[iDDL]->RemoveAt(i) ;
+ }
+ }
+ fSubEventArray[iDDL]->Compress();
+
+ if (AliLog::GetGlobalDebugLevel() == 3) {
+ nEntries = fSubEventArray[iDDL]->GetEntriesFast();
+ for (Int_t i = 0; i < nEntries; i++) {
+ AliMUONSubEventTracker* temp = (AliMUONSubEventTracker*)fSubEventArray[iDDL]->At(i);
+ printf("busPatchid back %d\n",temp->GetBusPatchId());
+ for (Int_t j = 0; j < temp->GetLength(); j++) {
+ printf("manuId back %d, ",temp->GetManuId(j));
+ printf("channelId back %d, ",temp->GetChannelId(j));
+ printf("charge back %d\n",temp->GetCharge(j));
+ }
+ }
+ printf("\n");
+ }
+
+ }
+
+ Int_t iBusPatch;
+ Int_t iEntries;
+ Int_t length;
+
+ for (Int_t iDDL = 0; iDDL < 2; iDDL++) {
+
+
+ // filling buffer
+ nEntries = fSubEventArray[iDDL]->GetEntriesFast();
+ buffer = new Int_t [(2048+24)*50]; // 24 words in average for one buspatch and 2048 manu info at most
+
+ indexBlk = 0;
+ indexDsp = 0;
+ index = 0;
+ iBusPatch = 0;
+ iEntries = 0;
+
+ for (Int_t iBlock = 0; iBlock < 2; iBlock++) {
+
+ // block header
+ // fDDLTracker->SetTotalBlkLength(0xFFFFFFFF);
+ length = fDDLTracker->GetBlkHeaderLength();
+ memcpy(&buffer[index],fDDLTracker->GetBlkHeader(),length*4);
+ indexBlk = index;
+ index += length;
+
+ for (Int_t iDsp = 0; iDsp < 5; iDsp++) {
+
+ // DSP header
+ // fDDLTracker->SetTotalDspLength(0xEEEEEEEE);
+ length = fDDLTracker->GetDspHeaderLength();
+ memcpy(&buffer[index],fDDLTracker->GetDspHeader(),length*4);
+ indexDsp = index;
+ index += length;
+
+ for (Int_t i = 0; i < 5; i++) {
+
+ iBusPatch = i + iBlock*25 + iDsp*5 + 50*(2*iCh + iDDL);
+
+ AliMUONSubEventTracker* temp = (AliMUONSubEventTracker*)fSubEventArray[iDDL]->At(iEntries);
+ if (nEntries > 0)
+ busPatchId = temp->GetBusPatchId();
+ else
+ busPatchId = -1;
+
+ if (busPatchId == iBusPatch) {
+ // add bus patch structure
+ length = temp->GetHeaderLength();
+ memcpy(&buffer[index],temp->GetAddress(),length*4);
+ index += length;
+ for (Int_t j = 0; j < temp->GetLength(); j++)
+ buffer[index++] = temp->GetData(j);
+ if (iEntries < nEntries-1)
+ iEntries++;
+ } else {
+ buffer[index++] = 4; // total length
+ buffer[index++] = 0; // raw data length
+ buffer[index++] = iBusPatch; // bus patch
+ buffer[index++] = 0xdeadbeef; // trigger word
+ }
+ } // bus patch
+ buffer[indexDsp] = index - indexDsp; // dsp length
+ buffer[indexDsp+1] = index - indexDsp - fDDLTracker->GetDspHeaderLength();
+ if ((index - indexDsp) % 2 == 0)
+ buffer[indexDsp+7] = 0;
+ else
+ buffer[indexDsp+7] = 1;
+ } // dsp
+ buffer[indexBlk] = index - indexBlk; // block length
+ buffer[indexBlk+1] = index - indexBlk - fDDLTracker->GetBlkHeaderLength();
+ }
+ if (iDDL == 0) {
+ // write DDL 1
+ header.fSize = (index + headerSize) * 4;// total length in bytes
+ fwrite((char*)(&header),headerSize*4,1,fFile1);
+ fwrite(buffer,sizeof(int),index,fFile1);
+ }
+ if (iDDL == 1) {
+ // write DDL 2
+ header.fSize = (index + headerSize) * 4;// total length in bytes
+ fwrite((char*)(&header),headerSize*4,1,fFile2);
+ fwrite(buffer,sizeof(int),index,fFile2);
+ }
+ delete[] buffer;
+ }
+
+ return kTRUE;
+}
+//____________________________________________________________________
+Int_t AliMUONRawData::WriteTriggerDDL()
+{
+
+ // DDL event one per half chamber
+ AliMUONSubEventTrigger* subEvent = 0x0;
+
+
+ // stored local id number
+ TArrayI isFired(256);
+ isFired.Reset();
+
+
+ // DDL header
+ AliRawDataHeader header = fDDLTrigger->GetHeader();
+ Int_t headerSize = fDDLTrigger->GetHeaderSize();
+ Int_t length;
+ TClonesArray* localTrigger;
+ TClonesArray* globalTrigger;
+ AliMUONGlobalTrigger* gloTrg;
+ AliMUONLocalTrigger* locTrg = 0x0;
+
+ fMUONData->GetTriggerD();
+
+ // global trigger for trigger pattern
+ globalTrigger = fMUONData->GlobalTrigger();
+ gloTrg = (AliMUONGlobalTrigger*)globalTrigger->UncheckedAt(0);
+ Int_t gloTrigPat = GetGlobalTriggerPattern(gloTrg);
+
+ // local trigger
+ localTrigger = fMUONData->LocalTrigger();
+
+ UInt_t word;
+ Int_t* buffer = 0;
+ Int_t index;
+ Int_t iEntries = 0;
+ Int_t iLocCard, locCard;
+ Char_t locDec, trigY, posY, devX, posX,regOut;
+ Int_t version = 1; // software version
+ Int_t eventType = 1; // trigger type: 1 for physics ?
+ Int_t serialNb = 0xF; // serial nb of card: all bits on for the moment
+ Int_t globalFlag = 1; // set to 2 if global info present in DDL else set to 1
+
+ Int_t nEntries = (Int_t) (localTrigger->GetEntries());// 234 local cards
+ // stored the local card id that's fired
+ for (Int_t i = 0; i < nEntries; i++) {
+ locTrg = (AliMUONLocalTrigger*)localTrigger->At(i);
+ isFired[locTrg->LoCircuit()] = 1;
+ }
+
+ if (!nEntries)
+ AliError("No Trigger information available");
+
+ buffer = new Int_t [672]; // [16(local)*5 words + 3 words]*8(reg) + 8 words = 672
+
+ for (Int_t iDDL = 0; iDDL < 2; iDDL++) {
+
+ index = 0;
+
+ // DDL enhanced header
+ word = 0;
+ AliBitPacking::PackWord((UInt_t)iDDL+1,word,28,31); //see AliMUONDDLTrigger.h for details
+ AliBitPacking::PackWord((UInt_t)serialNb,word,24,27);
+ AliBitPacking::PackWord((UInt_t)version,word,16,23);
+ AliBitPacking::PackWord((UInt_t)eventType,word,12,15);
+
+ if (iDDL == 0) // suppose global info in DDL one
+ globalFlag = 2;
+ else
+ globalFlag = 1;
+ AliBitPacking::PackWord((UInt_t)globalFlag,word,8,11);
+ fDDLTrigger->SetDDLWord(word);
+
+ if (iDDL == 0)
+ fDDLTrigger->SetGlobalOutput(gloTrigPat);// no global input for the moment....
+ else
+ fDDLTrigger->SetGlobalOutput(0);
+ length = fDDLTrigger->GetHeaderLength();
+ memcpy(&buffer[index],fDDLTrigger->GetEnhancedHeader(),length*4);
+ index += length;
+
+ for (Int_t iReg = 0; iReg < 8; iReg++) {
+
+ subEvent = new AliMUONSubEventTrigger();
+
+ // Regional card header
+ word = 0;
+ regOut = 0;
+ AliBitPacking::PackWord((UInt_t)serialNb,word,24,28); //see AliMUONSubEventTrigger.h for details
+ AliBitPacking::PackWord((UInt_t)version,word,16,23);
+ AliBitPacking::PackWord((UInt_t)iReg,word,12,15);
+ AliBitPacking::PackWord((UInt_t)regOut,word,0,7); // whenever regional output will be implemented
+
+ subEvent->SetRegWord(word);
+ memcpy(&buffer[index++],subEvent->GetAddress(),4);
+
+ buffer[index++] = 0;// 2 words of regional input
+ buffer[index++] = 0;
+
+ for (Int_t iLoc = 0; iLoc < 16; iLoc++) {
+
+ iLocCard = iLoc + iReg*16 + iDDL*128;
+
+ if (isFired[iLocCard]) {
+ locTrg = (AliMUONLocalTrigger*)localTrigger->At(iEntries);
+ locCard = locTrg->LoCircuit();
+ locDec = locTrg->GetLoDecision();
+ trigY = 0;
+ posY = locTrg->LoStripY();
+ posX = locTrg->LoStripX();
+ devX = locTrg->LoDev();
+ AliDebug(4,Form("loctrg %d, posX %d, posY %d, devX %d\n",
+ locTrg->LoCircuit(),locTrg->LoStripX(),locTrg->LoStripY(),locTrg->LoDev()));
+ } else { //no trigger (see PRR chpt 3.4)
+ locCard = -1;
+ locDec = 0;
+ trigY = 1;
+ posY = 15;
+ posX = 0;
+ devX = 0x8000;
+ }
+
+ //packing word
+ word = 0;
+ AliBitPacking::PackWord((UInt_t)(iLocCard % 16),word,19,22); //card id number in crate
+ AliBitPacking::PackWord((UInt_t)locDec,word,15,18);
+ AliBitPacking::PackWord((UInt_t)trigY,word,14,14);
+ AliBitPacking::PackWord((UInt_t)posY,word,10,13);
+ AliBitPacking::PackWord((UInt_t)devX,word,5,9);
+ AliBitPacking::PackWord((UInt_t)posX,word,0,4);
+
+ if (locCard == iLocCard) {
+ // add local cards structure
+ buffer[index++] = (locTrg->GetX1Pattern() | (locTrg->GetX2Pattern() << 16));
+ buffer[index++] = (locTrg->GetX3Pattern() | (locTrg->GetX4Pattern() << 16));
+ buffer[index++] = (locTrg->GetY1Pattern() | (locTrg->GetY2Pattern() << 16));
+ buffer[index++] = (locTrg->GetY3Pattern() | (locTrg->GetY4Pattern() << 16));
+ buffer[index++] = (Int_t)word; // data word
+ if (iEntries < nEntries-1)
+ iEntries++;
+ } else {
+ buffer[index++] = 0; // 4 words for x1, x2, y1, y2
+ buffer[index++] = 0;
+ buffer[index++] = 0;
+ buffer[index++] = 0;
+ buffer[index++] = (Int_t)word; // data word
+
+ }
+ } // local card
+
+ delete subEvent;
+
+ } // Regional card
+
+ buffer[index++] = fDDLTrigger->GetEoD(); // End of DDL word
+ buffer[index++] = fDDLTrigger->GetEoD(); // End of DDL word for 64 bits transfer purpose
+
+
+ if (iDDL == 0) {
+ // write DDL 1
+ header.fSize = (index + headerSize) * 4;// total length in bytes
+ fwrite((char*)(&header),headerSize*4,1,fFile1);
+ fwrite(buffer,sizeof(int),index,fFile1);
+ }
+ if (iDDL == 1) {
+ // write DDL 2
+ header.fSize = (index + headerSize) * 4;// total length in bytes
+ fwrite((char*)(&header),headerSize*4,1,fFile2);
+ fwrite(buffer,sizeof(int),index,fFile2);
+ }
+ }
+ delete[] buffer;
+
+ return kTRUE;
+}
+//____________________________________________________________________
+void AliMUONRawData::GetDummyMapping(Int_t iCh, Int_t iCath, const AliMUONDigit* digit,
+ Int_t &busPatchId, UShort_t &manuId, UChar_t &channelId)
+{
+// Dummy mapping for tracker
+
+ Int_t offsetX = 0; // offet row
+ Int_t offsetY = 0; // offset columns
+ Int_t offsetCath = 0; //offset from one cathod to the other
+ Int_t maxChannel = 0; // maximum nb of channel in 1/2 chamber
+ Int_t id;
switch (iCh+1) {
case 1:
case 2:
// dummy mapping
// manu Id directly from a matrix 8*8, same segmentation for B and NB
// 50 buspatches for 1/2 chamber
-
- id = (digit->PadX() * offsetX + digit->PadY() + offsetY +
- offsetCath*iCath);
- busPatchId = id/50;
-
- Int_t inBusId = (id - maxChannel/50 * busPatchId);// id channel in buspatch
- Int_t manuPerBus = (maxChannel/(50*64)); // number of manus per buspatch
+ id = (TMath::Abs(digit->PadX()) * offsetX + digit->PadY() + offsetY +
+ offsetCath * iCath);
+ Int_t chPerBus = maxChannel/50;
+ busPatchId = id/chPerBus; // start at zero
+ if (digit->PadX() > 0)
+ busPatchId += 50*iCh*2;
+ else
+ busPatchId += 50*(2*iCh+1);
// 64 manu cards for one buspatch
- manuId = inBusId/manuPerBus;
+ manuId = (id % chPerBus)/64; //start at zero
manuId &= 0x7FF; // 11 bits
// channel id
- channelId = (inBusId % manuPerBus);
+ channelId = (id % chPerBus) % 64; //start at zero
channelId &= 0x3F; // 6 bits
- // charge
- charge = digit->Signal();
- charge &= 0xFFF;
+
+ AliDebug(2,Form("id: %d, busPatchId %d, manuId: %d, channelId: %d, maxchannel: %d, chPerBus %d\n",
+ id, busPatchId, manuId, channelId, maxChannel, chPerBus));
- if (fPrintLevel)
- printf("id: %d, busPatchId %d, manuId: %d, channelId: %d, padx: %d pady %d, charge %d\n",
- id, busPatchId, manuId, channelId, digit->PadX(), digit->PadY(), digit->Signal());
- //packing word
- AliBitPacking::PackWord((UInt_t)parity,word,29,31);
- AliBitPacking::PackWord((UInt_t)manuId,word,18,28);
- AliBitPacking::PackWord((UInt_t)channelId,word,12,17);
- AliBitPacking::PackWord((UInt_t)charge,word,0,11);
+ AliDebug(2,Form("id: %d, busPatchId %d, manuId: %d, channelId: %d, padx: %d pady %d, charge %d\n",
+ id, busPatchId, manuId, channelId, digit->PadX(), digit->PadY(), digit->Signal()));
- // set DDL Event
- if (digit->PadX() > 0) {
- eventDDL1->SetRawData(word);
- eventDDL1->SetBusPatchId(busPatchId); // information not usable only last bus patch stored
- } else {
- eventDDL2->SetRawData(word);
- eventDDL2->SetBusPatchId(busPatchId);
- }
- if (fPrintLevel) {
- printf("word: 0x%x, ",word);
- printf("manuId back %d, ",eventDDL1->GetManuId(eventDDL1->GetLength()-1));
- printf("channelId back %d, ",eventDDL1->GetChannelId(eventDDL1->GetLength()-1));
- printf("charge back %d\n",eventDDL1->GetCharge(eventDDL1->GetLength()-1));
- }
- }
+}
+
+//____________________________________________________________________
+Int_t AliMUONRawData::GetGlobalTriggerPattern(const AliMUONGlobalTrigger* gloTrg)
+{
+ // global trigger pattern calculation
+
+ Int_t gloTrigPat = 0;
+
+ if (gloTrg->SinglePlusLpt()) gloTrigPat|= 0x1;
+ if (gloTrg->SinglePlusHpt()) gloTrigPat|= 0x2;
+ if (gloTrg->SinglePlusApt()) gloTrigPat|= 0x4;
+
+ if (gloTrg->SingleMinusLpt()) gloTrigPat|= 0x8;
+ if (gloTrg->SingleMinusHpt()) gloTrigPat|= 0x10;
+ if (gloTrg->SingleMinusApt()) gloTrigPat|= 0x20;
+
+ if (gloTrg->SingleUndefLpt()) gloTrigPat|= 0x40;
+ if (gloTrg->SingleUndefHpt()) gloTrigPat|= 0x80;
+ if (gloTrg->SingleUndefApt()) gloTrigPat|= 0x100;
+
+ if (gloTrg->PairUnlikeLpt()) gloTrigPat|= 0x200;
+ if (gloTrg->PairUnlikeHpt()) gloTrigPat|= 0x400;
+ if (gloTrg->PairUnlikeApt()) gloTrigPat|= 0x800;
+
+ if (gloTrg->PairLikeLpt()) gloTrigPat|= 0x1000;
+ if (gloTrg->PairLikeHpt()) gloTrigPat|= 0x2000;
+ if (gloTrg->PairLikeApt()) gloTrigPat|= 0x4000;
+
+ return gloTrigPat;
+}
+
+//____________________________________________________________________
+Int_t AliMUONRawData::Raw2Digits(AliRawReader* rawReader)
+{
+
+ // generate digits
+ ReadTrackerDDL(rawReader);
+
+ // generate trigger
+ ReadTriggerDDL(rawReader);
+
+ return kTRUE;
+
+}
+
+//____________________________________________________________________
+Int_t AliMUONRawData::ReadTrackerDDL(AliRawReader* rawReader)
+{
+
+ AliMUONSubEventTracker* subEventTracker = new AliMUONSubEventTracker();
+ AliMUONDigit* digit = new AliMUONDigit();
+
+
+ //Read Header Size of DDL,Block,DSP and BusPatch.
+
+ Int_t ddlHeaderSize = fDDLTracker->GetHeaderSize();
+ Int_t blockHeaderSize = fDDLTracker->GetBlkHeaderLength();
+ Int_t dspHeaderSize = fDDLTracker->GetDspHeaderLength();
+ Int_t buspatchHeaderSize = subEventTracker->GetHeaderLength();
+
+// Each DDL is made with 2 Blocks each of which consists of 5 DSP and each of DSP has at most 5 buspatches.
+// This information is used to calculate the size of headers (DDL,Block and DSP) which has no interesting data.
+
+ const Int_t blankDDLSize = ddlHeaderSize + 2*blockHeaderSize + 2*5*dspHeaderSize + 2*5*5*buspatchHeaderSize;
+ const Int_t blankBlockSize = blockHeaderSize + 5*dspHeaderSize + 5*5*buspatchHeaderSize;
+ const Int_t blankDspSize = dspHeaderSize + 5*buspatchHeaderSize;
+
+ Int_t totalDDLSize, totalBlockSize, totalDspSize , totalBusPatchSize, dataSize;
+
+
+ for(Int_t iCh = 0; iCh < AliMUONConstants::NTrackingCh(); iCh++){ // loops over tracking chambers
+
+ UShort_t charge;
+ Int_t padX, padY,iCath;
+
+ for(Int_t iDDL = 0; iDDL < 2; iDDL++){ // DDL loop
+
+ //rawReader = new AliRawReaderFile(iEvent);
+ rawReader->Select(0X9,(2*iCh)+iDDL,(2*iCh)+iDDL); //Select the DDL file to be read
+
+ rawReader->ReadHeader();
+
+ totalDDLSize = (rawReader->GetDataSize()+sizeof(AliRawDataHeader))/4; // 4 is multipiled to convert byte 2 word
+
+ if(totalDDLSize>blankDDLSize){ // Compare the DDL header with an empty DDL header size to read the file
+
+
+ Int_t totalDataWord = rawReader->GetDataSize()/4 ;
+ UInt_t *buffer = new UInt_t[totalDataWord];
+ for(Int_t i=0;i<totalDataWord;i++){
+ UInt_t& temp = buffer[i];
+ rawReader->ReadNextInt(temp); // takes the whole result into buffer variable for future analysis
+ }
+
+ Char_t parity;
+ Int_t buspatchId;
+ UChar_t channelId;
+ UShort_t manuId;//,charge;
+ Int_t id;//,padX, padY,iCath;
+ Int_t indexDsp, indexBusPatch, index = 0;
+
+
+ for(Int_t iBlock = 0; iBlock < 2 ;iBlock++){ // loop over 2 blocks
+ totalBlockSize = buffer[index];
+
+ if(totalBlockSize > blankBlockSize){ // compare block header
+ index += blockHeaderSize;
+
+ for(Int_t iDsp = 0; iDsp < 5 ;iDsp++){ //DSP loop
+ totalDspSize = buffer[index];
+ indexDsp = index;
+
+ if(totalDspSize > blankDspSize){ // Compare DSP Header
+ index += dspHeaderSize;
+
+ for(Int_t iBusPatch = 0; iBusPatch < 5 ; iBusPatch++){
+ totalBusPatchSize = buffer[index];
+ indexBusPatch = index;
+ buspatchId = buffer[index+2];
+
+ if(totalBusPatchSize > buspatchHeaderSize){ //Check Buspatch header
+ index += buspatchHeaderSize;
+ dataSize = totalBusPatchSize - buspatchHeaderSize;
+
+ if(dataSize>0) {
+
+ for(Int_t iData = 0; iData < dataSize ;iData++) {
+
+ subEventTracker->SetData(buffer[index++],iData); //Set to extract data
+ parity = subEventTracker->GetParity(iData);
+ manuId = subEventTracker->GetManuId(iData);
+ channelId = subEventTracker->GetChannelId(iData);
+ charge = subEventTracker->GetCharge(iData);
+ digit->AddSignal(charge); // set charge
+
+ GetInvDummyMapping(iCh,buspatchId,manuId,channelId,digit); // Get Back the hits at pads
+ padX = digit->PadX();
+ padY = digit->PadY();
+ iCath = digit->Cathode();
+ id = digit->DetElemId();
+
+ // fill digits
+ fMUONData->AddDigit(iCh, *digit);
+
+ } // data loop
+ } // dataSize test
+ } // testing buspatch
+
+ index = indexBusPatch + totalBusPatchSize;
+
+ } //buspatch loop
+
+
+ } // dsp test
+
+ index = indexDsp + totalDspSize;
+
+ } // dsp loop
+
+ } //block test
+
+ index = totalBlockSize;
+
+ } //block loop
+
+ delete []buffer;
+ } //loop checking the header size of DDL
+
+ //delete rawReader;
+ } // DDL loop
+
+ } // Chamber loop
+
+ delete subEventTracker;
+ delete digit;
+
+ return kTRUE;
+}
+
+//____________________________________________________________________
+void AliMUONRawData:: GetInvDummyMapping(Int_t iCh, Int_t buspatchId, UShort_t manuId,
+ UChar_t channelId, AliMUONDigit* digit )
+{
+ Int_t offsetX = 0; // offet row
+ Int_t offsetY = 0; // offset columns
+ Int_t offsetCath = 0; //offset from one cathod to the other
+ Int_t maxChannel = 0; // maximum nb of channel in 1/2 chamber
+ //Int_t id;
+ Bool_t flag;
+ switch (iCh+1) {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ offsetX = 512;
+ offsetY = 256;
+ offsetCath = 65536;
+ maxChannel = (offsetY * offsetX + 2* offsetY + offsetCath);
+ break;
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ offsetX = 1024;
+ offsetY = 0;
+ offsetCath = 65536;
+ maxChannel = (256 * offsetX + offsetX + offsetCath);
+ break;
}
- // write DDL event
- nWord = eventDDL1->GetLength();
- if (nWord > 0) { // not empty event
- fwrite(eventDDL1->GetAddress(),sizeof(int),nWord+2,fFile1);
- dummy = eventDDL1->GetEoD();
- fwrite(&dummy,sizeof(int),1,fFile1);// could be nicer !
+ // dummy mapping
+ // manu Id directly from a matrix 8*8, same segmentation for B and NB
+ // 50 buspatches for 1/2 chamber
+
+ if(buspatchId >= 50*(2*iCh + 1)){ // condn to find the sign of padX
+ buspatchId = buspatchId - 50*(2*iCh + 1);
+ flag = kTRUE;
}
- nWord = eventDDL2->GetLength();
- if (nWord > 0) {
- fwrite(eventDDL2->GetAddress(),sizeof(int),nWord+2,fFile2);
- dummy = eventDDL2->GetEoD();
- fwrite(&dummy,sizeof(int),1,fFile2);
+ else{
+ buspatchId = buspatchId - 50*2*iCh;
+ flag = kFALSE;
}
- delete eventDDL1;
- delete eventDDL2;
+
+ Int_t chPerBus = maxChannel/50;
+
+ Int_t id = buspatchId*chPerBus + 64*manuId + channelId;
+ Int_t iCath, padX,padY;
+ if(id >= (offsetY + offsetCath)) // find cathode plane
+ iCath = 1;
+ else
+ iCath = 0;
+
+ if(iCh<4)
+ padX = TMath::Nint((Float_t)(id - offsetY - offsetCath*iCath)/offsetX);
+ else
+ padX = (id - offsetY - offsetCath*iCath)/offsetX;
+
+ padY = id - (padX*offsetX + offsetY + offsetCath*iCath);
+
+ if(flag) //Detect the sign of padX
+ padX = -padX;
+ else
+ padX = padX;
+
+ digit->SetPadX(padX);
+ digit->SetPadY(padY);
+ digit->SetCathode(iCath);
+ digit->SetDetElemId(id);
+
+ return;
+}
+
+//____________________________________________________________________
+Int_t AliMUONRawData::ReadTriggerDDL(AliRawReader* rawReader)
+{
+ AliMUONSubEventTrigger* subEventTrigger = new AliMUONSubEventTrigger();
+ AliMUONGlobalTrigger* globalTrigger = 0x0;
+ AliMUONLocalTrigger* localTrigger = new AliMUONLocalTrigger();
+
+
+ //Int_t ddlHeaderSize = fDDLTrigger->GetHeaderSize(); // we dont need this, as size of ddl data is same for triger and no trigger
+
+ Int_t ddlEnhanceHeaderSize = fDDLTrigger->GetHeaderLength();
+ Int_t regHeaderLength = subEventTrigger->GetRegHeaderLength() ;
+
+ Int_t loCircuit, loStripX, loDev, loStripY, loLpt, loHpt;
+ Char_t loDecision;
+
+ UShort_t X1Pattern, X2Pattern, X3Pattern, X4Pattern;
+ UShort_t Y1Pattern, Y2Pattern, Y3Pattern, Y4Pattern;
+
+
+ for(Int_t iDDL = 0; iDDL < 2; iDDL++){ //DDL loop
+
+ rawReader->Select(0XA,iDDL,iDDL); //Select the DDL file to be read
+
+ rawReader->ReadHeader();
+
+ Int_t totalDataWord = rawReader->GetDataSize()/4 ;
+ UInt_t *buffer = new UInt_t[totalDataWord];
+ for(Int_t i=0;i<totalDataWord;i++){
+ UInt_t& temp = buffer[i];
+ rawReader->ReadNextInt(temp); // takes the whole result into buffer variable for future analysis
+ }
+
+ // rawReader->ReadNext((UChar_t*)buffer, totalDataWord); // method is protected ????
+
+ Int_t index = 0;
+
+ // fill DDL header informations
+ memcpy(fDDLTrigger->GetEnhancedHeader(), &buffer[index], ddlEnhanceHeaderSize*4);
+
+ // fill global trigger information
+ globalTrigger = GetGlobalTriggerPattern(fDDLTrigger->GetGlobalOuput());
+ fMUONData->AddGlobalTrigger(*globalTrigger);
+
+ index += ddlEnhanceHeaderSize;
+
+ for (Int_t iReg = 0; iReg < 8; iReg++) { //loop over regeonal card
+
+
+ subEventTrigger->SetRegWord(buffer[index]); //read regional data
+
+ index += regHeaderLength;
+
+ for (Int_t iLoc = 0; iLoc < 16; iLoc++) { //loop over local card
+
+ Int_t iLocIndex = index;
+
+ for(Int_t iData = 0; iData < 5 ;iData++ ){
+ subEventTrigger->SetLocalData(buffer[index++],5*iLoc+iData); //read local data
+ }
+
+ if(buffer[iLocIndex] > 0) {
+
+ loCircuit = (Int_t)subEventTrigger->GetLocalId(iLoc)+ 16*iReg + 128*iDDL;
+ loStripX = (Int_t)subEventTrigger->GetXPos(iLoc);
+ loStripY = (Int_t)subEventTrigger->GetYPos(iLoc);
+ loDev = (Int_t)subEventTrigger->GetXDev(iLoc);
+
+ // fill local trigger
+ localTrigger->SetLoCircuit(loCircuit);
+ localTrigger->SetLoStripX(loStripX );
+ localTrigger->SetLoStripY(loStripY);
+ localTrigger->SetLoDev(loDev);
+
+ loDecision = subEventTrigger->GetLocalDec(iLoc);
+ loLpt = loDecision & 0x3;
+ loHpt = (loDecision >> 2) & 0x3;
+
+ // fill local trigger
+ localTrigger->SetLoLpt(loLpt);
+ localTrigger->SetLoHpt(loHpt);
+
+
+ X1Pattern = subEventTrigger->GetX1(iLoc);
+ X2Pattern = subEventTrigger->GetX2(iLoc);
+ X3Pattern = subEventTrigger->GetX3(iLoc);
+ X4Pattern = subEventTrigger->GetX4(iLoc);
+
+ Y1Pattern = subEventTrigger->GetY1(iLoc);
+ Y2Pattern = subEventTrigger->GetY2(iLoc);
+ Y3Pattern = subEventTrigger->GetY3(iLoc);
+ Y4Pattern = subEventTrigger->GetY4(iLoc);
+
+ // fill local trigger
+ localTrigger->SetX1Pattern(X1Pattern);
+ localTrigger->SetX2Pattern(X2Pattern);
+ localTrigger->SetX3Pattern(X3Pattern);
+ localTrigger->SetX4Pattern(X4Pattern);
+
+ localTrigger->SetY1Pattern(Y1Pattern);
+ localTrigger->SetY2Pattern(Y2Pattern);
+ localTrigger->SetY3Pattern(Y3Pattern);
+ localTrigger->SetY4Pattern(Y4Pattern);
+ fMUONData->AddLocalTrigger(*localTrigger);
+
+ }
+
+ } // local card loop
+
+ } // regeinal card loop
+
+ delete [] buffer;
+ //delete rawReader;
+ } // DDL loop
+
+
+ delete subEventTrigger;
+ delete globalTrigger;
+ delete localTrigger;
+
return kTRUE;
+
+}
+//____________________________________________________________________
+AliMUONGlobalTrigger* AliMUONRawData::GetGlobalTriggerPattern(Int_t gloTrigPat)
+{
+ // global trigger pattern calculation
+
+ Int_t globalSinglePlus[3]; // tot num of single plus
+ Int_t globalSingleMinus[3]; // tot num of single minus
+ Int_t globalSingleUndef[3]; // tot num of single undefined
+ Int_t globalPairUnlike[3]; // tot num of unlike-sign pairs
+ Int_t globalPairLike[3]; // tot num of like-sign pairs
+
+
+ for (Int_t i = 0; i < 3; i++) {
+ globalSinglePlus[i] = gloTrigPat & (0x1 << i);
+ globalSingleMinus[i] = gloTrigPat & (0x1 << i+3);
+ globalSingleUndef[i] = gloTrigPat & (0x1 << i+6);
+ globalPairUnlike[i] = gloTrigPat & (0x1 << i+9);
+ globalPairLike[i] = gloTrigPat & (0x1 << i+12);
+ }
+
+ return (new AliMUONGlobalTrigger(globalSinglePlus, globalSingleMinus,
+ globalSingleUndef, globalPairUnlike,
+ globalPairLike));
+
}