/// \class AliMUONRawWriter
/// MUON Raw Data generaton in ALICE-MUON
-/// This class version 3 (further details could be found in Alice-note)
+/// Raw data structure could be found in Alice-note.
///
/// Implemented non-constant buspatch numbers for tracking
/// with correct DDL id (first guess)
/// Using informations from AliMUONTriggerCrateStore for
/// empty slots and non-notified cards in trigger crates.
/// Ch. Finck, August 06.
+/// Using AliMpDDLStore::GetBusPatchId.
+///
+/// \author Ch. Finck, Feb. 07.
+
#include "AliMUONRawWriter.h"
#include "AliMUONLocalStruct.h"
#include "AliMUONLocalTrigger.h"
#include "AliMUONLocalTriggerBoard.h"
+#include "AliMUONRegionalTrigger.h"
#include "AliMUONRegHeader.h"
#include "AliMUONTriggerCrate.h"
#include "AliMUONTriggerCrateStore.h"
-#include "AliMpBusPatch.h"
+#include "AliMpDDLStore.h"
+#include "AliMpDDL.h"
+#include "AliMpDetElement.h"
#include "AliMpDEManager.h"
#include "AliMpExMap.h"
#include "AliMpConstants.h"
#include "TList.h"
#include "TObjArray.h"
#include "TStopwatch.h"
+#include <Riostream.h>
/// \cond CLASSIMP
ClassImp(AliMUONRawWriter) // Class implementation in ROOT context
/// \endcond
-Int_t AliMUONRawWriter::fgManuPerBusSwp1B[12] = {1, 27, 53, 79, 105, 131, 157, 183, 201, 214, 224, 232};
-Int_t AliMUONRawWriter::fgManuPerBusSwp1NB[12] = {1, 27, 53, 79, 105, 131, 157, 183, 201, 214, 225, 233};
-
-Int_t AliMUONRawWriter::fgManuPerBusSwp2B[12] = {1, 27, 53, 79, 105, 131, 157, 183, 201, 214, 226, 246};
-Int_t AliMUONRawWriter::fgManuPerBusSwp2NB[12] = {1, 27, 53, 79, 105, 131, 157, 183, 201, 214, 227, 245};
-
namespace
{
enum ETimer { kWriteTracker, kWriteTrigger, kDigitLoop, kGetBusPatch, kTest, kLast };
fDarcHeader(new AliMUONDarcHeader()),
fRegHeader(new AliMUONRegHeader()),
fLocalStruct(new AliMUONLocalStruct()),
- fBusPatchManager(new AliMpBusPatch()),
+ fDDLStore(AliMpDDLStore::Instance()),
fCrateManager(new AliMUONTriggerCrateStore()),
fScalerEvent(kFALSE),
fHeader(),
fBlockHeader->SetDataKey(fBlockHeader->GetDefaultDataKey());
fDspHeader->SetDataKey(fDspHeader->GetDefaultDataKey());
- // bus patch managers
- fBusPatchManager->ReadBusPatchFile();
-
// Crate manager
fCrateManager->ReadFromFile();
fDarcHeader(0),
fRegHeader(0),
fLocalStruct(0),
- fBusPatchManager(0),
+ fDDLStore(0),
fCrateManager(0x0),
fScalerEvent(kFALSE),
fHeader(),
delete fRegHeader;
delete fLocalStruct;
- delete fBusPatchManager;
delete fCrateManager;
for ( Int_t i = 0; i < kLast; ++i )
delete[] fTimers;
}
-//______________________________________________________________________________
-//void
-//AliMUONRawWriter::CheckDigits()
-//{
-// std::map<int,std::map<int,int> > m;
-//
-// for (Int_t iSt = 0; iSt < AliMUONConstants::NTrackingCh()/2; ++iSt)
-// {
-// for (Int_t iCh = iSt*2; iCh <= iSt*2 + 1; ++iCh)
-// {
-// TClonesArray* muonDigits = fMUONData->Digits(iCh);
-// for (Int_t idig = 0; idig < muonDigits->GetEntriesFast(); idig++)
-// {
-// AliMUONDigit* digit = (AliMUONDigit*) muonDigits->UncheckedAt(idig);
-// Int_t busPatchId = GetBusPatch(*digit);
-// m[busPatchId][digit->ManuId()]++;
-// }
-// }
-// }
-//
-// std::map<int,std::map<int,int> >::const_iterator it;
-//
-// Int_t nManuMax(0);
-//
-// for ( it = m.begin(); it != m.end(); ++it )
-// {
-// AliDebug(1,Form("BusPatch %3d has %3d manus",it->first,it->second.size()));
-// nManuMax = std::max((Int_t)it->second.size(),nManuMax);
-// std::map<int,int>::const_iterator it2;
-// for ( it2 = it->second.begin(); it2 != it->second.end(); ++it2 )
-// {
-// AliDebug(1,Form(" BusPatch %3d Manu %4d Nch %3d",it->first,it2->first,it2->second));
-// }
-// }
-// AliDebug(1,Form("Max manus per busPatch : %3d",nManuMax));
-//}
-
//____________________________________________________________________
Int_t AliMUONRawWriter::Digits2Raw()
{
strcpy(name,AliDAQ::DdlFileName("MUONTRG",idDDL));
fFile[1] = fopen(name,"w");
- WriteTriggerDDL();
+ WriteTriggerDDL();
// reset and close
fclose(fFile[0]);
fTimers[kGetBusPatch].Stop();
if (busPatchId<0) continue;
- fTimers[kTest].Start(kFALSE);
- busPatchId = GetBusPatch(*digit);
- fTimers[kTest].Stop();
-
if ( digit->ManuId() > 0x7FF || digit->ManuId() < 0 ||
digit->ManuChannel() > 0x3F || digit->ManuChannel() < 0 )
{
// open DDL files, 4 per station
for (Int_t iDDL = iSt*4; iDDL < 4 + iSt*4; ++iDDL) {
- fBusPatchManager->ResetBusItr(iDDL);
- fBusPatchManager->GetDspInfo(iDDL, iDspMax, iBusPerDSP);
+ AliMpDDL* ddl = fDDLStore->GetDDL(iDDL);
+ iDspMax = ddl->GetMaxDsp();
+ ddl->GetBusPerDsp(iBusPerDSP);
+ Int_t busIter = 0;
Int_t buffer[kBufferSize];
// 5 buspatches max per DSP
for (Int_t i = 0; i < iBusPerDSP[iDsp]; i++) {
- iBusPatch = fBusPatchManager->NextBusInDDL(iDDL);
+ iBusPatch = ddl->GetBusPatchId(busIter++);
// iteration over bus patch in DDL
if (iBusPatch == -1) {
return kTRUE;
}
-//____________________________________________________________________
-Int_t AliMUONRawWriter::GetBusPatch(Int_t detElemId, Int_t manuId) const
-{
- /// Determine the BusPatch this digit belongs to.
-
- Int_t* ptr = 0;
-
- AliMpPlaneType plane =
- (manuId & AliMpConstants::ManuMask(kNonBendingPlane)) ?
- kNonBendingPlane : kBendingPlane;
-
- AliMpStationType stationType = AliMpDEManager::GetStationType(detElemId);
-
- if ( stationType == kStation1 || stationType == kStation2 )
- {
- if (plane == kBendingPlane)
- {
- ptr = &fgManuPerBusSwp1B[0];
- }
- else
- {
- ptr = &fgManuPerBusSwp1NB[0];
- }
- }
- else
- {
- if (plane == kBendingPlane)
- {
- ptr = &fgManuPerBusSwp2B[0];
- }
- else
- {
- ptr = &fgManuPerBusSwp2NB[0];
- }
- }
-
- // Getting buspatch id
- TArrayI* vec = fBusPatchManager->GetBusfromDE(detElemId);
- Int_t pos = 0;
-
- Int_t m = ( manuId & 0x3FF ); // remove bit 10
- //FIXME : how can we remove that condition
- // on the 10-th bit ? All the rest need not any knowledge about it,
- // can't we find a way to get manu<->buspatch transparent to this too ?
-
- if ( stationType == kStation1 || stationType == kStation2 )
- {
- for (pos = 11; pos >=0 ; --pos)
- {
- if (m >= ptr[pos]) break;
- }
- }
- else
- {
- // offset of 100 in manuId for following bus patch
- pos = m/100;
- }
-
-
- if (pos >(Int_t) vec->GetSize())
- {
- AliError(Form("pos greater %d than size %d manuId %d detElemId %d \n",
- pos, (Int_t)vec->GetSize(), manuId, detElemId));
- AliError(Form("Chamber %s Plane %s manuId %d m %d",
- StationTypeName(stationType).Data(),
- PlaneTypeName(plane).Data(),
- manuId,
- m));
- return -1;
- }
-
- Int_t busPatchId = vec->At(pos);
-
- if ( ( stationType == kStation1 || stationType == kStation2 ) &&
- ( plane == kNonBendingPlane ) )
- {
- busPatchId += 12;
- }
-
- return busPatchId;
-}
-
//____________________________________________________________________
Int_t AliMUONRawWriter::GetBusPatch(const AliMUONDigit& digit) const
{
/// Determine the BusPatch this digit belongs to.
- return GetBusPatch(digit.DetElemId(),digit.ManuId());
+ return fDDLStore->GetBusPatchId(digit.DetElemId(),digit.ManuId());
}
//____________________________________________________________________
// DDL event one per half chamber
- // stored local id number
- TArrayI isFired(256);
- isFired.Reset();
-
-
// DDL header size
Int_t headerSize = sizeof(AliRawDataHeader)/4;
TClonesArray* localTrigger;
TClonesArray* globalTrigger;
+ TClonesArray* regionalTrigger;
+
AliMUONGlobalTrigger* gloTrg;
AliMUONLocalTrigger* locTrg = 0x0;
+ AliMUONRegionalTrigger* regTrg = 0x0;
// global trigger for trigger pattern
globalTrigger = fMUONData->GlobalTrigger();
Int_t gloTrigResp = gloTrg->GetGlobalResponse();
// local trigger
- localTrigger = fMUONData->LocalTrigger();
+ localTrigger = fMUONData->LocalTrigger();
+
+
+ // regional trigger
+ regionalTrigger = fMUONData->RegionalTrigger();
+
UInt_t word;
Int_t* buffer = 0;
Int_t index;
Int_t iEntries = 0;
Int_t iLocCard, locCard;
- Char_t locDec, trigY, posY, posX, regOut;
+ UChar_t locDec, trigY, posY, posX, regOut;
UInt_t regInpLpt;
UInt_t regInpHpt;
- Int_t devX;
- Int_t version = 1; // software version
- Int_t eventPhys = 1; // trigger type: 1 for physics, 0 for software
- Int_t serialNb = 0xF; // serial nb of card: all bits on for the moment
+ UInt_t devX;
+ UChar_t sdevX;
+ UInt_t version = 1; // software version
+ UInt_t eventPhys = 1; // trigger type: 1 for physics, 0 for software
+ UInt_t serialNb = 0xF; // serial nb of card: all bits on for the moment
Int_t globalFlag = 0; // set to 1 if global info present in DDL else set to 0
// size of headers
eventPhys = 0; //set to generate scaler events
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; // storing local boards with informations
- }
if (!nEntries)
AliDebug(1, "No Trigger information available");
if (!crate)
AliWarning(Form("Missing crate number %d in DDL %d\n", iReg, iDDL));
+ // regional info tree, make sure that no reg card missing
+ for (Int_t i = 0; i < 16; ++i) {
+ regTrg = (AliMUONRegionalTrigger*)regionalTrigger->At(i);
+ if (regTrg)
+ if (regTrg->GetId() == (iReg + iDDL*8)) break;
+ }
+
// Regional card header
word = 0;
// set darc status word
fRegHeader->SetDarcWord(word);
- regOut = 0;
- regInpHpt = regInpLpt = 0;
+ regOut = regTrg->GetOutput();
+ regInpHpt = regTrg->GetLocalOutput(0);
+ regInpLpt = regTrg->GetLocalOutput(1);
+
// fill darc word, not darc status for the moment (empty)
//see AliMUONRegHeader.h for details
AliBitPacking::PackWord((UInt_t)eventPhys,word,31,31);
AliBitPacking::PackWord((UInt_t)serialNb,word,19,24);
AliBitPacking::PackWord((UInt_t)version,word,16,23);
AliBitPacking::PackWord((UInt_t)iReg,word,15,18);
- AliBitPacking::PackWord((UInt_t)regOut,word,0,7); // waiting realistic output of AliMUONGlobalTrigger (oct 06 ?)
+ AliBitPacking::PackWord((UInt_t)regOut,word,0,7);
fRegHeader->SetWord(word);
// 16 local card per regional board
- UShort_t localMask = 0x0;
-
+ // UShort_t localMask = 0x0;
+
for (Int_t iLoc = 0; iLoc < 16; iLoc++) {
-
- // slot zero for Regional card
- AliMUONLocalTriggerBoard* localBoard = (AliMUONLocalTriggerBoard*)boards->At(iLoc+1);
-
- if (localBoard) { // if not empty slot
-
- if ((iLocCard = localBoard->GetNumber()) != 0) {// if notified board
-
- localMask |= (0x1 << iLoc); // local mask
- if (isFired[iLocCard]) { // if card has triggered
- 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)
- locDec = 0;
- trigY = 1;
- posY = 15;
- posX = 0;
- devX = 0x8;
- // set local card id to -1
- locCard = -1;
- }
- // calculate regional input High and low Pt
- UInt_t tmp1 = (locDec >> 2) & 0x3;
- UInt_t tmp2 = locDec & 0x3;
-
- regInpHpt |= tmp1 << (30 - iLoc*2);
- regInpLpt |= tmp2 << (30 - iLoc*2);
-
- //packing word
- word = 0;
- AliBitPacking::PackWord((UInt_t)iLoc,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
-
- }
- } else {// number!=0
- // fill with 10CDEAD word for 'non-notified' slots
- for (Int_t i = 0; i < fLocalStruct->GetLength(); i++)
- buffer[index++] = fLocalStruct->GetDisableWord();
+
+ // slot zero for Regional card
+ AliMUONLocalTriggerBoard* localBoard = (AliMUONLocalTriggerBoard*)boards->At(iLoc+1);
+
+ if (localBoard) { // if not empty slot
+
+ if ((iLocCard = localBoard->GetNumber()) != 0) {// if notified board
+
+ locTrg = (AliMUONLocalTrigger*)localTrigger->At(iEntries++);
+ locCard = locTrg->LoCircuit();
+ locDec = locTrg->GetLoDecision();
+ trigY = locTrg->LoTrigY();
+ posY = locTrg->LoStripY();
+ posX = locTrg->LoStripX();
+ devX = locTrg->LoDev();
+ sdevX = locTrg->LoSdev();
+
+ AliDebug(4,Form("loctrg %d, posX %d, posY %d, devX %d\n",
+ locTrg->LoCircuit(),locTrg->LoStripX(),locTrg->LoStripY(),locTrg->LoDev()));
+ //packing word
+ word = 0;
+ AliBitPacking::PackWord((UInt_t)iLoc,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)sdevX,word,9,9);
+ AliBitPacking::PackWord((UInt_t)devX,word,5,8);
+ AliBitPacking::PackWord((UInt_t)posX,word,0,4);
+
+ 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
+
+ } else {// number!=0
+ // fill with 10CDEAD word for 'non-notified' slots
+ for (Int_t i = 0; i < fLocalStruct->GetLength(); i++)
+ buffer[index++] = fLocalStruct->GetDisableWord();
+ }
+ } else {
+ // fill with 10CDEAD word for empty slots
+ for (Int_t i = 0; i < fLocalStruct->GetLength(); i++)
+ buffer[index++] = fLocalStruct->GetDisableWord();
+ }// condition localBoard
+
+ // 45 regional scaler word
+ if (fScalerEvent) {
+ memcpy(&buffer[index], fLocalStruct->GetScalers(), kLocScalerLength*4);
+ index += kLocScalerLength;
}
- } else {
- // fill with 10CDEAD word for empty slots
- for (Int_t i = 0; i < fLocalStruct->GetLength(); i++)
- buffer[index++] = fLocalStruct->GetDisableWord();
- }// condition localBoard
-
- // 45 regional scaler word
- if (fScalerEvent) {
- memcpy(&buffer[index], fLocalStruct->GetScalers(), kLocScalerLength*4);
- index += kLocScalerLength;
- }
-
- // end of local structure words
- buffer[index++] = fLocalStruct->GetEndOfLocal();
-
+
+ // end of local structure words
+ buffer[index++] = fLocalStruct->GetEndOfLocal();
+
} // local card
// fill regional header with local output
- fRegHeader->SetInput(regInpLpt, 0);
+ fRegHeader->SetInput(regInpHpt, 0);
fRegHeader->SetInput(regInpHpt, 1);
- fRegHeader->SetMask(localMask);
memcpy(&buffer[indexReg],fRegHeader->GetHeader(),kRegHeaderLength*4);
-
+
} // Regional card