/* $Id$ */
-#include <Riostream.h>
-#include <TDirectory.h>
-#include <TPDGCode.h>
-
-#include "AliRunLoader.h"
-#include "AliLoader.h"
-#include <Riostream.h>
-
#include "AliMUONDigitizer.h"
#include "AliMUONConstants.h"
-#include "AliMUONChamber.h"
+#include "AliMUONSegmentation.h"
#include "AliMUONHitMapA1.h"
#include "AliMUON.h"
-#include "AliMUONChamber.h"
+#include "AliMUONLoader.h"
#include "AliMUONConstants.h"
-#include "AliMUONDigit.h"
-#include "AliMUONDigitizer.h"
-#include "AliMUONHit.h"
-#include "AliMUONHitMapA1.h"
-#include "AliMUONPadHit.h"
#include "AliMUONTransientDigit.h"
+#include "AliMUONTriggerDecision.h"
+#include "AliLog.h"
+#include "AliMUONGeometryTransformer.h"
+#include "AliMUONGeometryModule.h"
+#include "AliMUONGeometryStore.h"
+
#include "AliRun.h"
#include "AliRunDigitizer.h"
+#include "AliRunLoader.h"
+
+/////////////////////////////////////////////////////////////////////////////////////
+//
+// AliMUONDigitizer should be base abstract class of all digitisers in the MUON
+// module. It implements the common functionality of looping over input streams
+// filling the fTDList and writing the fTDList to the output stream.
+// Inheriting digitizers need to override certain methods to choose and initialize
+// the correct input and output trees, apply the correct detector response if any
+// and implement how the transient digits are generated from the input stream.
+//
+/////////////////////////////////////////////////////////////////////////////////////
ClassImp(AliMUONDigitizer)
//___________________________________________
-AliMUONDigitizer::AliMUONDigitizer() :AliDigitizer()
+AliMUONDigitizer::AliMUONDigitizer() :
+ AliDigitizer(),
+ fHitMap(0),
+ fTDList(0),
+ fTDCounter(0),
+ fMask(0),
+ fSignal(0)
{
-// Default ctor - don't use it
- fHits = 0;
- fPadHits = 0;
- fHitMap = 0;
- fTDList = 0;
+/// Default constructor.
+/// Initializes all pointers to NULL.
+
+ fRunLoader = NULL;
+ fGime = NULL;
+ fMUON = NULL;
+ fMUONData = NULL;
+ fTrigDec = NULL;
}
//___________________________________________
-AliMUONDigitizer::AliMUONDigitizer(AliRunDigitizer* manager)
- :AliDigitizer(manager)
+AliMUONDigitizer::AliMUONDigitizer(AliRunDigitizer* manager) :
+ AliDigitizer(manager),
+ fHitMap(0),
+ fTDList(0),
+ fTDCounter(0),
+ fMask(0),
+ fSignal(0)
{
-// ctor which should be used
- fHitMap = 0;
- fTDList = 0;
- fHits = 0;
- fPadHits = 0;
- fDebug = 0;
- if (GetDebug()>2)
- cerr<<"AliMUONDigitizer::AliMUONDigitizer"
- <<"(AliRunDigitizer* manager) was processed"<<endl;
+/// Constructor which should be used rather than the default constructor.
+/// Initializes all pointers to NULL.
+
+ fRunLoader = NULL;
+ fGime = NULL;
+ fMUON = NULL;
+ fMUONData = NULL;
+ fTrigDec = NULL;
}
-//------------------------------------------------------------------------
-AliMUONDigitizer::~AliMUONDigitizer()
+//___________________________________________
+AliMUONDigitizer::AliMUONDigitizer(const AliMUONDigitizer& rhs)
+ : AliDigitizer(rhs)
+{
+/// Protected copy constructor
+
+ AliFatal("Not implemented.");
+}
+
+//___________________________________________
+AliMUONDigitizer::~AliMUONDigitizer()
{
-// Destructor
- if (fHits) delete fHits;
- if (fPadHits) delete fPadHits;
+/// Destructor
+
+ if (fMUONData)
+ delete fMUONData;
+
+ if (fTrigDec)
+ delete fTrigDec;
}
+//-------------------------------------------------------------------
+AliMUONDigitizer&
+AliMUONDigitizer::operator=(const AliMUONDigitizer& rhs)
+{
+/// Protected assignement operator
+
+ if (this == &rhs) return *this;
+
+ AliFatal("Not implemented.");
+
+ return *this;
+}
+
//------------------------------------------------------------------------
-Bool_t AliMUONDigitizer::Exists(const AliMUONPadHit *padhit) const
+Bool_t AliMUONDigitizer::Init()
{
- return (fHitMap[fNch]->TestHit(padhit->PadX(),padhit->PadY()));
+/// Initialize - Does nothing.
+
+ return kTRUE;
}
//------------------------------------------------------------------------
-void AliMUONDigitizer::Update(AliMUONPadHit *padhit)
+void AliMUONDigitizer::Exec(Option_t* /*option*/)
{
- AliMUONTransientDigit *pdigit =
- static_cast<AliMUONTransientDigit*>(
- fHitMap[fNch]->GetHit(padhit->PadX(),padhit->PadY()));
-
- // update charge
- //
- Int_t iqpad = padhit->QPad(); // charge per pad
- pdigit->AddSignal(iqpad);
- pdigit->AddPhysicsSignal(iqpad);
-
- // update list of tracks
- //
- Int_t track, charge;
- track = fTrack+fMask;
- if (fSignal) {
- charge = iqpad;
- } else {
- charge = kBgTag;
- }
- pdigit->UpdateTrackList(track,charge);
+/// The main work loop starts here.
+/// The digitization process is broken up into two steps:
+/// 1) Loop over input streams and create transient digits from the input.
+/// Done in GenerateTransientDigits()
+/// 2) Loop over the generated transient digits and write them to the output
+/// stream. Done in CreateDigits()
+
+ AliDebug(1, "Running digitiser.");
+
+ if (fManager->GetNinputs() == 0)
+ {
+ AliWarning("No inputs set, nothing to do.");
+ return;
+ }
+
+ if (!FetchLoaders(fManager->GetInputFolderName(0), fRunLoader, fGime) ) return;
+ if (! FetchGlobalPointers(fRunLoader) ) return;
+ if (! FetchTriggerPointer(fGime) ) return;
+
+ InitArrays();
+
+ AliDebug(2, Form("Event Number is %d.", fManager->GetOutputEventNr()));
+
+ // Loop over files to merge and to digitize
+ fSignal = kTRUE;
+ for (Int_t inputFile = 0; inputFile < fManager->GetNinputs(); inputFile++)
+ {
+ fMask = fManager->GetMask(inputFile);
+ AliDebug(2, Form("Digitising folder %d, with fMask = %d: %s", inputFile, fMask,
+ (const char*)fManager->GetInputFolderName(inputFile)));
+
+ if (inputFile != 0)
+ // If this is the first file then we already have the loaders loaded.
+ if (! FetchLoaders(fManager->GetInputFolderName(inputFile), fRunLoader, fGime) )
+ continue;
+ else
+ // If this is not the first file then it is assumed to be background.
+ fSignal = kFALSE;
+
+ if (! InitInputData(fGime) ) continue;
+ GenerateTransientDigits();
+ CleanupInputData(fGime);
+ }
+
+ Bool_t ok = FetchLoaders(fManager->GetOutputFolderName(), fRunLoader, fGime);
+ if (ok) ok = InitOutputData(fGime);
+ if (ok) CreateDigits();
+ if (ok) CreateTrigger();
+ if (ok) CleanupOutputData(fGime);
+
+ CleanupArrays();
+ CleanupTriggerArrays();
+}
+
+//--------------------------------------------------------------------------
+void AliMUONDigitizer::AddOrUpdateTransientDigit(AliMUONTransientDigit* mTD)
+{
+/// Checks to see if the transient digit exists in the corresponding fHitMap.
+/// If it does then the digit is updated otherwise it is added.
+
+ if (ExistTransientDigit(mTD))
+ {
+ UpdateTransientDigit(mTD);
+ delete mTD; // The new digit can be deleted because it was not added.
+ }
+ else
+ AddTransientDigit(mTD);
}
//------------------------------------------------------------------------
-void AliMUONDigitizer::CreateNew(AliMUONPadHit *padhit)
+void AliMUONDigitizer::UpdateTransientDigit(AliMUONTransientDigit* mTD)
{
-// Create new AliMUONTransientDigit and add it to the fTDList
-
- fTDList->AddAtAndExpand(
- new AliMUONTransientDigit(fNch,fDigits),fCounter);
- fHitMap[fNch]->SetHit(padhit->PadX(),padhit->PadY(),fCounter);
- AliMUONTransientDigit* pdigit =
- (AliMUONTransientDigit*)fTDList->Last();
- // list of tracks
- Int_t track, charge;
- track = fTrack+fMask;
- if (fSignal) {
- charge = padhit->QPad();
- } else {
- charge = kBgTag;
- }
- pdigit->AddToTrackList(track,charge);
- fCounter++;
+/// Update the transient digit that is already in the fTDList by adding the new
+/// transient digits charges and track lists to the existing one.
+
+ AliDebug(4,Form( "Updating transient digit 0x%X", (void*)mTD));
+ // Choosing the maping of the cathode plane of the chamber:
+ Int_t detElemId = mTD->DetElemId();
+
+ Int_t iNchCpl= fNDetElemId[detElemId] + (mTD->Cathode()-1) * AliMUONConstants::NDetElem();
+
+ AliMUONTransientDigit *pdigit =
+ static_cast<AliMUONTransientDigit*>( fHitMap[iNchCpl]->GetHit(mTD->PadX(),mTD->PadY()) );
+
+ // update charge
+ pdigit->AddSignal( mTD->Signal() );
+ pdigit->AddPhysicsSignal( mTD->Physics() );
+
+ // update list of tracks
+ Int_t ntracks = mTD->GetNTracks();
+ if (ntracks > kMAXTRACKS) // Truncate the number of tracks to kMAXTRACKS if we have to.
+ {
+ AliDebug(1,Form(
+ "TransientDigit returned the number of tracks to be %d, which is bigger than kMAXTRACKS.",
+ ntracks));
+ AliDebug(1,Form( "Reseting the number of tracks to be %d.", kMAXTRACKS));
+ ntracks = kMAXTRACKS;
+ }
+
+ for (Int_t i = 0; i < ntracks; i++)
+ {
+ pdigit->UpdateTrackList( mTD->GetTrack(i), mTD->GetCharge(i) );
+ }
}
+//------------------------------------------------------------------------
+void AliMUONDigitizer::AddTransientDigit(AliMUONTransientDigit* mTD)
+{
+/// Adds the transient digit to the fTDList and sets the appropriate entry
+/// in the fHitMap arrays.
+
+ AliDebug(4,Form( "Adding transient digit 0x%X", (void*)mTD));
+ // Choosing the maping of the cathode plane of the chamber:
+
+ Int_t detElemId = mTD->DetElemId();
+ Int_t iNchCpl= fNDetElemId[detElemId] + (mTD->Cathode()-1) * AliMUONConstants::NDetElem();
+
+ fTDList->AddAtAndExpand(mTD, fTDCounter);
+ if (iNchCpl>-1 && iNchCpl<2*AliMUONConstants::NDetElem()) {
+ fHitMap[iNchCpl]->SetHit( mTD->PadX(), mTD->PadY(), fTDCounter);
+ fTDCounter++;
+ }
+}
//------------------------------------------------------------------------
-Bool_t AliMUONDigitizer::Init()
+Bool_t AliMUONDigitizer::ExistTransientDigit(AliMUONTransientDigit* mTD)
{
-// Initialization
- fHits = new TClonesArray("AliMUONHit",1000);
- fPadHits = new TClonesArray("AliMUONPadHit",1000);
- return kTRUE;
+/// Checks if the transient digit already exists on the corresponding fHitMap.
+/// i.e. is there a transient digit on the same chamber, cathode and pad position
+/// as mTD. If yes then kTRUE is returned else kFASLE is returned.
+
+ // Choosing the maping of the cathode plane of the chamber:
+ Int_t detElemId = mTD->DetElemId();
+
+ Int_t iNchCpl= fNDetElemId[detElemId] + (mTD->Cathode()-1) *AliMUONConstants::NDetElem() ;
+
+ // Int_t iNchCpl= mTD->Chamber() + (mTD->Cathode()-1) * AliMUONConstants::NCh();
+ if (iNchCpl>-1 && iNchCpl<2*AliMUONConstants::NDetElem())
+ return( fHitMap[iNchCpl]->TestHit(mTD->PadX(), mTD->PadY()) );
+ else return kFALSE;
}
+//-----------------------------------------------------------------------
+void AliMUONDigitizer::CreateDigits()
+{
+/// Loops over the fTDList for each cathode, gets the correct signal for the
+/// digit and adds the new digit to the output stream.
+
+ fTDList->Sort(); // sort by idDE
+ AliDebug(2, "Creating digits...");
+ // for (Int_t icat = 0; icat < 2; icat++) {
+
+ Int_t digitindex[14] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+ //
+ // Filling Digit List
+ Int_t nentries = fTDList->GetEntriesFast();
+ for (Int_t nent = 0; nent < nentries; nent++) {
+
+ AliMUONTransientDigit* td = (AliMUONTransientDigit*)fTDList->At(nent);
+ if (td == NULL) continue;
+
+ // Must be the same cathode, otherwise we will fill a mixture
+ // of digits from both cathodes.
+ //if (icat != td->Cathode() - 1) continue;
+
+ AliDebug(3,Form( "Creating digit from transient digit 0x%X", (void*)td));
+
+ Int_t q = GetSignalFrom(td);
+ if (q > 0) {
+ Int_t chamber = td->Chamber();
+ if (0 <= chamber && chamber <= 13 )
+ AddDigit(td, q, digitindex[chamber]++);
+ else
+ AliError(Form("Invalid chamber %d\n",chamber));
+ }
+ }
+ FillOutputData();
+ // }
+ fTDCounter = 0;
+}
//------------------------------------------------------------------------
-//void AliMUONDigitizer::Digitize()
-void AliMUONDigitizer::Exec(Option_t* /*option*/)
+void AliMUONDigitizer::AddDigit(
+ AliMUONTransientDigit* td, Int_t responseCharge,
+ Int_t digitindex
+ )
{
- // Obsolet sep 2003 Gines MARTINEZ
-
-// TString optionString = option;
-// if (optionString.Data() == "deb") {
-// cout<<"AliMUONDigitizer::Exec: called with option deb "<<endl;
-// fDebug = 3;
-// }
-// AliMUONChamber* iChamber;
-// AliSegmentation* segmentation;
-
-// if (GetDebug()>2) cerr<<" AliMUONDigitizer::Digitize() starts"<<endl;
-// fTDList = new TObjArray;
-
-// //Loaders (We assume input0 to be the output too)
-// AliRunLoader *rl, *orl;
-// AliLoader *gime, *ogime;
-// orl = AliRunLoader::GetRunLoader(fManager->GetOutputFolderName());
-// ogime = orl->GetLoader("MUONLoader");
-
-// runloader = AliRunLoader::GetRunLoader(fManager->GetInputFolderName(0));
-// if (runloader == 0x0) {
-// cerr<<"AliMUONDigitizerv1::Digitize() opening file "<<fManager->GetInputFileName(0,0)<<endl;
-// return; // RunDigitizer is not working.
-// }
-// gime = runloader->GetLoader("MUONLoader");
-// if (gime->TreeH()==0x0) {
-// Info("Digitize","TreeH is not loaded yet. Loading...");
-// gime->LoadHits("READ");
-// Info("Digitize","Now treeH is %#x. MUONLoader is %#x",gime->TreeH(),gime);
-// }
-
-// if (GetDebug()>2) cerr<<"AliMUONDigitizerv1::Digitize() loaders"<<endl;
-
-// if (runloader->GetAliRun() == 0x0) runloader->LoadgAlice();
-// gAlice = runloader->GetAliRun();
-
-// // Getting Module MUON
-// AliMUON *pMUON = (AliMUON *) gAlice->GetDetector("MUON");
-// if (!pMUON) {
-// cerr<<"AliMUONDigitizerv1::Digitize Error:"
-// <<" module MUON not found in the input file"<<endl;
-// return;
-// }
-// // Loading Event
-// Int_t currentevent = fManager->GetOutputEventNr();
-
-// if (GetDebug()>2) cerr<<"AliMUONDigitizerv1::Digitize() Event Number is "<<currentevent <<endl;
-// if ( (currentevent<10) ||
-// (Int_t(TMath::Log10(currentevent)) == TMath::Log10(currentevent) ) )
-// cout <<"ALiMUONDigitizerv1::Digitize() Event Number is "<< currentevent <<endl;
-
-// // Output file for digits
-// AliRunLoader * runloaderout = AliRunLoader::GetRunLoader(fManager->GetOutputFolderName());
-// AliLoader * gimeout = runloaderout->GetLoader("MUONLoader");
-// // New branch per chamber for MUON digit in the tree of digits
-// if (gimeout->TreeD() == 0x0) gimeout->MakeDigitsContainer();
-// TTree* treeD = gimeout->TreeD();
-// pMUON->GetMUONData()->SetLoader(gimeout);
-// pMUON->MakeBranch("D");
-
-// fHitMap= new AliMUONHitMapA1* [AliMUONConstants::NCh()];
-
-// //
-// // loop over cathodes
-// //
-
-// for (int icat = 0; icat < 2; icat++) {
-// fCounter = 0;
-// for (Int_t i = 0; i < AliMUONConstants::NCh(); i++) {
-// iChamber = &(pMUON->Chamber(i));
-// // if (!(iChamber->Nsec() == 1 && icat == 1)) {
-// segmentation = iChamber->SegmentationModel(icat+1);
-// fHitMap[i] = new AliMUONHitMapA1(segmentation, fTDList);
-// // }
-// }
-
-
-// // Loop over files to digitize
-// fSignal = kTRUE;
-// for (Int_t inputFile=0; inputFile<fManager->GetNinputs();
-// inputFile++) {
-// // Connect MUON branches
-
-// if (inputFile > 0 ) fSignal = kFALSE;
-// TBranch *branchHits = 0;
-// TBranch *branchPadHits = 0;
-
-// rl = AliRunLoader::GetRunLoader(fManager->GetInputFolderName(inputFile));
-// gime = rl->GetLoader("MUONLoader");
-
+/// Prepares the digits, track and charge arrays in preparation for a call to
+/// AddDigit(Int_t, Int_t[kMAXTRACKS], Int_t[kMAXTRACKS], Int_t[6])
+/// This method is called by CreateDigits() whenever a new digit needs to be added
+/// to the output stream trees.
+/// The responseCharge value is used as the Signal of the new digit.
+/// The OnWriteTransientDigit method is also called just before the adding the
+/// digit to allow inheriting digitizers to be able to do some specific processing
+/// at this point.
+
+ Int_t tracks[kMAXTRACKS];
+ Int_t charges[kMAXTRACKS];
+ Int_t digits[7];
-// TTree *treeH = gime->TreeH();
-// if (GetDebug()>2) {
-// cerr<<" inputFile , cathode = "<<inputFile<<" "
-// <<icat<<endl;
-// cerr<<" treeH, fHits "<<treeH<<" "<<fHits<<endl;
-// }
-// if (treeH && fHits) {
-// branchHits = treeH->GetBranch("MUON");
-// if (branchHits) {
-// fHits->Clear();
-// branchHits->SetAddress(&fHits);
-// }
-// else
-// Error("Exec","branch MUON was not found");
-// }
-// if (GetDebug()>2) cerr<<" branchHits = "<<branchHits<<endl;
-
-// if (treeH && fPadHits) {
-// branchPadHits = treeH->GetBranch("MUONCluster");
-// if (branchPadHits)
-// branchPadHits->SetAddress(&fPadHits);
-// else
-// Error("Exec","branch MUONCluster was not found");
-// }
-// if (GetDebug()>2) cerr<<" branchPadHits = "<<branchPadHits<<endl;
-
-// //
-// // Loop over tracks
-// //
-
-// Int_t ntracks = (Int_t) treeH->GetEntries();
-
-// for (fTrack = 0; fTrack < ntracks; fTrack++) {
-// if (GetDebug()>2) cerr<<" fTrack = "<<fTrack<<endl;
-// fHits->Clear();
-// fPadHits->Clear();
-// branchHits->GetEntry(fTrack);
-// branchPadHits->GetEntry(fTrack);
-
-// //
-// // Loop over hits
-
-// AliMUONHit* mHit;
-// for(Int_t i = 0; i < fHits->GetEntriesFast(); ++i) {
-// mHit = static_cast<AliMUONHit*>(fHits->At(i));
-// fNch = mHit->Chamber()-1; // chamber number
-// if (fNch > AliMUONConstants::NCh()-1) {
-// cerr<<"AliMUONDigitizer: ERROR: "
-// <<"fNch > AliMUONConstants::NCh()-1, fNch, NCh(): "
-// <<fNch<<", "<< AliMUONConstants::NCh()<<endl;
-// return;
-// }
-// iChamber = &(pMUON->Chamber(fNch));
-// //
-// // Loop over pad hits
-// for (AliMUONPadHit* mPad =
-// (AliMUONPadHit*)pMUON->FirstPad(mHit,fPadHits);
-// mPad;
-// mPad = (AliMUONPadHit*)pMUON->NextPad(fPadHits))
-// {
-// Int_t cathode = mPad->Cathode(); // cathode number
-// Int_t ipx = mPad->PadX(); // pad number on X
-// Int_t ipy = mPad->PadY(); // pad number on Y
-// Int_t iqpad = Int_t(mPad->QPad()); // charge per pad
-// if (cathode != (icat+1)) continue;
-
-// fMask = fManager->GetMask(inputFile);
-// fDigits[0] = ipx;
-// fDigits[1] = ipy;
-// fDigits[2] = icat;
-// fDigits[3] = iqpad;
-// if (inputFile == 0) {
-// fDigits[4] = iqpad;
-// } else {
-// fDigits[4] = 0;
-// }
-// if (mHit->Particle() == kMuonPlus ||
-// mHit->Particle() == kMuonMinus) {
-// fDigits[5] = (mPad->HitNumber()) + fMask;
-// } else fDigits[5] = -1;
-
-// // build the list of fired pads and update the info,
-// // fDigits is input for Update(mPad)
-
-// if (!Exists(mPad)) {
-// CreateNew(mPad);
-// } else {
-// Update(mPad);
-// } // end if Exists(mPad)
-// } //end loop over clusters
-// } // hit loop
-// } // track loop
-// } // end file loop
-// if (GetDebug()>2) cerr<<"END OF FILE LOOP"<<endl;
-
-// Int_t tracks[kMAXTRACKS];
-// Int_t charges[kMAXTRACKS];
-// Int_t nentries = fTDList->GetEntriesFast();
-
-// for (Int_t nent = 0; nent < nentries; nent++) {
-// AliMUONTransientDigit *address = (AliMUONTransientDigit*)fTDList->At(nent);
-// if (address == 0) continue;
-// Int_t ich = address->Chamber();
-// Int_t q = address->Signal();
-// iChamber = &(pMUON->Chamber(ich));
-// //
-// // Digit Response (noise, threshold, saturation, ...)
-// AliMUONResponse * response = iChamber->ResponseModel();
-// q = response->DigitResponse(q,address);
-
-// if (!q) continue;
-
-// fDigits[0] = address->PadX();
-// fDigits[1] = address->PadY();
-// fDigits[2] = address->Cathode();
-// fDigits[3] = q;
-// fDigits[4] = address->Physics();
-// fDigits[5] = address->Hit();
-
-// Int_t nptracks = address->GetNTracks();
-
-// if (nptracks > kMAXTRACKS) {
-// if (GetDebug() >0) {
-// cerr<<"AliMUONDigitizer: nptracks > 10 "<<nptracks;
-// cerr<<"reset to max value "<<kMAXTRACKS<<endl;
-// }
-// nptracks = kMAXTRACKS;
-// }
-// if (nptracks > 2 && GetDebug() >2) {
-// cerr<<"AliMUONDigitizer: nptracks > 2 "<<nptracks<<endl;
-// printf("cat,ich,ix,iy,q %d %d %d %d %d \n",icat,ich,fDigits[0],fDigits[1],q);
-// }
-// for (Int_t tr = 0; tr < nptracks; tr++) {
-// tracks[tr] = address->GetTrack(tr);
-// charges[tr] = address->GetCharge(tr);
-// } //end loop over list of tracks for one pad
-// // Sort list of tracks according to charge
-// if (nptracks > 1) {
-// SortTracks(tracks,charges,nptracks);
-// }
-// if (nptracks < kMAXTRACKS ) {
-// for (Int_t i = nptracks; i < kMAXTRACKS; i++) {
-// tracks[i] = 0;
-// charges[i] = 0;
-// }
-// }
-
-// // fill digits
-// pMUON->AddDigits(ich,tracks,charges,fDigits);
-// }
-
-// // fManager->GetTreeD()->Fill();
-// ogime->TreeD()->Fill();
-
+ digits[0] = td->PadX();
+ digits[1] = td->PadY();
+ digits[2] = td->Cathode() - 1;
+ digits[3] = responseCharge;
+ digits[4] = td->Physics();
+ digits[5] = td->Hit();
+ digits[6] = td->DetElemId();
+
+ Int_t nptracks = td->GetNTracks();
+ if (nptracks > kMAXTRACKS) {
+
+ AliDebug(1, Form(
+ "TransientDigit returned the number of tracks to be %d, which is bigger than kMAXTRACKS.",
+ nptracks));
+ AliDebug(1, Form("Reseting the number of tracks to be %d.", kMAXTRACKS));
+ nptracks = kMAXTRACKS;
+ }
+
+ for (Int_t i = 0; i < nptracks; i++) {
+
+ tracks[i] = td->GetTrack(i);
+ charges[i] = td->GetCharge(i);
+ }
+
+ // Sort list of tracks according to charge
+ SortTracks(tracks,charges,nptracks);
+
+ if (nptracks < kMAXTRACKS ) {
+
+ for (Int_t i = nptracks; i < kMAXTRACKS; i++) {
+ tracks[i] = -1;
+ charges[i] = 0;
+ }
+ }
+
+ AliDebug(4,Form( "Adding digit with charge %d.", responseCharge));
+
+ OnWriteTransientDigit(td);
+ AddDigit(td->Chamber(), tracks, charges, digits);
+ AddDigitTrigger(td->Chamber(), tracks, charges, digits, digitindex);
+}
-// pMUON->ResetDigits(); //
-// fTDList->Clear();
+//------------------------------------------------------------------------
+void AliMUONDigitizer::OnCreateTransientDigit(AliMUONTransientDigit* /*digit*/, TObject* /*source_object*/)
+{
+/// Does nothing.
+///
+/// This is derived by Digitisers that want to trace which digits were made from
+/// which hits.
+}
-
-// for(Int_t ii = 0; ii < AliMUONConstants::NCh(); ++ii) {
-// if (fHitMap[ii]) {
-// delete fHitMap[ii];
-// fHitMap[ii] = 0;
-// }
-// }
-// } //end loop over cathodes
-// if (GetDebug()>2)
-// cerr<<"AliMUONDigitizer::Exec: writing the TreeD: "
-// << ogime->TreeD()->GetName()<<endl;
-
-// ogime->WriteDigits("OVERWRITE");
-
-// delete [] fHitMap;
-// delete fTDList;
-
-// if (fHits) fHits->Delete();
-// if (fPadHits) fPadHits->Delete();
+//------------------------------------------------------------------------
+void AliMUONDigitizer::OnWriteTransientDigit(AliMUONTransientDigit* /*digit*/)
+{
+/// Does nothing.
+///
+/// This is derived by Digitisers that want to trace which digits were made from
+/// which hits.
}
+//------------------------------------------------------------------------
+Bool_t AliMUONDigitizer::FetchLoaders(const char* foldername, AliRunLoader*& runloader, AliMUONLoader*& muonloader)
+{
+/// Fetches the run loader from the current folder, specified by 'foldername'.
+/// The muon loader is then loaded from the fetched run loader.
+/// kTRUE is returned if no error occurred otherwise kFALSE is returned.
+
+ AliDebug(3, Form("Fetching run loader and muon loader from folder: %s", foldername));
+
+ runloader = AliRunLoader::GetRunLoader(foldername);
+ if (runloader == NULL)
+ {
+ AliError(Form("RunLoader not found in folder: %s", foldername));
+ return kFALSE;
+ }
+ muonloader = (AliMUONLoader*) runloader->GetLoader("MUONLoader");
+ if (muonloader == NULL)
+ {
+ AliError(Form("MUONLoader not found in folder: %s", foldername));
+ return kFALSE;
+ }
+ return kTRUE;
+
+}
//------------------------------------------------------------------------
-void AliMUONDigitizer::SortTracks(Int_t *tracks,Int_t *charges,Int_t ntr)
+Bool_t AliMUONDigitizer::FetchGlobalPointers(AliRunLoader* runloader)
{
- //
- // Sort the list of tracks contributing to a given digit
- // Only the 3 most significant tracks are acctually sorted
- //
-
- //
- // Loop over signals, only 3 times
- //
-
- Int_t qmax;
- Int_t jmax;
- Int_t idx[3] = {-2,-2,-2};
- Int_t jch[3] = {-2,-2,-2};
- Int_t jtr[3] = {-2,-2,-2};
- Int_t i,j,imax;
+/// Fetches the AliRun object into the global gAlice pointer from the specified
+/// run loader. The AliRun object is loaded into memory using the run loader if
+/// not yet loaded. The MUON module object is then loaded from gAlice and
+/// AliMUONData fetched from the MUON module.
+/// kTRUE is returned if no error occurred otherwise kFALSE is returned.
+
+ AliDebug(3, Form("Fetching gAlice, MUON module and AliMUONData from runloader 0x%X.",
+ (void*)runloader
+ ));
+
+ if (runloader->GetAliRun() == NULL) runloader->LoadgAlice();
+ gAlice = runloader->GetAliRun();
+ if (gAlice == NULL)
+ {
+ AliError(Form("Could not find the AliRun object in runloader 0x%X.", (void*)runloader));
+ return kFALSE;
+ }
+ fMUON = (AliMUON*) gAlice->GetDetector("MUON");
+ if (fMUON == NULL)
+ {
+ AliError(Form("Could not find the MUON module in runloader 0x%X.", (void*)runloader));
+ return kFALSE;
+ }
+
+ AliMUONLoader *muonloader = (AliMUONLoader*) runloader->GetLoader("MUONLoader");
+ if (muonloader == NULL)
+ {
+ AliError( "MUONLoader not found ");
+ return kFALSE;
+ }
+
+
+ if (fMUONData == NULL) fMUONData = new AliMUONData(muonloader,"MUON","MUON");
+ if (fMUONData == NULL)
+ {
+ AliError(Form("Could not find AliMUONData object in runloader 0x%X.", (void*)runloader));
+ return kFALSE;
+ }
+
+ return kTRUE;
+}
+//-----------------------------------------------------------------------
+Bool_t AliMUONDigitizer::FetchTriggerPointer(AliMUONLoader* loader)
+{
+/// \todo add description
+
+ if (fMUONData == NULL) {
+ AliError("MUONData not found");
+ return kFALSE;
+ }
+
+ if (fTrigDec == NULL)
+ fTrigDec = new AliMUONTriggerDecision(loader,0,fMUONData);
- if (ntr<3) imax=ntr;
- else imax=3;
- for(i=0;i<imax;i++){
- qmax=0;
- jmax=0;
-
- for(j=0;j<ntr;j++){
-
- if((i == 1 && j == idx[i-1])
- ||(i == 2 && (j == idx[i-1] || j == idx[i-2]))) continue;
-
- if(charges[j] > qmax) {
- qmax = charges[j];
- jmax=j;
- }
- }
-
- if(qmax > 0) {
- idx[i]=jmax;
- jch[i]=charges[jmax];
- jtr[i]=tracks[jmax];
- }
+ return kTRUE;
+}
+
+//------------------------------------------------------------------------
+void AliMUONDigitizer::InitArrays()
+{
+/// Creates a new fTDList object.
+/// Also creates an array of 2 * chamber_number AliMUONHitMapA1 objects
+/// in the fHitMaps array. Each one is set to a chamber and cathode
+/// specific segmentation model.
+///
+/// Note: the fTDList and fHitMap arrays must be NULL before calling this method.
+
+ AliDebug(2, "Initialising internal arrays.");
+ AliDebug(4, "Creating transient digits list.");
+ fTDList = new TObjArray;
+
+ // Array of pointer of the AliMUONHitMapA1:
+ // two HitMaps per chamber, or one HitMap per cahtode plane
+ fHitMap = new AliMUONHitMapA1* [2*AliMUONConstants::NDetElem()];
+ for (Int_t i=0; i<2*AliMUONConstants::NDetElem(); i++) fHitMap[i] = 0x0;
+
+ Int_t k = 0;
+ Int_t idDE;
+
+ for (Int_t i = 0; i < AliMUONConstants::NCh(); i++) {
+
+
+ AliDebug(4,Form( "Creating hit map for chamber %d, cathode 1.", i+1));
+ AliMUONSegmentation* segmentation = fMUON->GetSegmentation();
+ AliMUONGeometrySegmentation* c1Segmentation
+ = segmentation->GetModuleSegmentation(i, 0); // Cathode plane 1
+ AliDebug(4,Form( "Creating hit map for chamber %d, cathode 2.", i+1));
+ AliMUONGeometrySegmentation* c2Segmentation
+ = segmentation->GetModuleSegmentation(i, 1); // Cathode plane 2
+
+ const AliMUONGeometryTransformer* kGeometryTransformer
+ = fMUON->GetGeometryTransformer();
+
+ AliMUONGeometryStore* detElements
+ = kGeometryTransformer->GetModuleTransformer(i)->GetDetElementStore();
- }
-
- for(i=0;i<3;i++){
- if (jtr[i] == -2) {
- charges[i]=0;
- tracks[i]=0;
- } else {
- charges[i]=jch[i];
- tracks[i]=jtr[i];
+
+ // Loop over detection elements
+ for (Int_t j=0; j<detElements->GetNofEntries(); j++) {
+
+ idDE = detElements->GetEntry(j)->GetUniqueID();
+ fNDetElemId[idDE] = k;
+
+ Int_t npx1 = c1Segmentation->Npx(idDE)+1;
+ Int_t npy1 = c1Segmentation->Npy(idDE)+1;
+ fHitMap[k] = new AliMUONHitMapA1(npx1, npy1, fTDList);
+
+ Int_t npx2 = c2Segmentation->Npx(idDE)+1;
+ Int_t npy2 = c2Segmentation->Npy(idDE)+1;
+ fHitMap[k+AliMUONConstants::NDetElem()] = new AliMUONHitMapA1(npx2, npy2, fTDList);
+ k++;
+ }
}
- }
+}
+//------------------------------------------------------------------------
+void AliMUONDigitizer::CleanupArrays()
+{
+/// The arrays fTDList and fHitMap are deleted and the pointers set to NULL.
+
+ AliDebug(2, "Deleting internal arrays.");
+ for(Int_t i = 0; i < 2*AliMUONConstants::NDetElem(); i++) {
+ delete fHitMap[i];
+ }
+ delete [] fHitMap;
+ fHitMap = NULL;
+
+ AliDebug(4, "Deleting transient digits list.");
+ fTDList->Delete();
+ delete fTDList;
+ fTDList = NULL;
+
+}
+
+//------------------------------------------------------------------------
+void AliMUONDigitizer::SortTracks(Int_t *tracks, Int_t *charges, Int_t ntr) const
+{
+/// Sort the list of tracks contributing to a given digit
+/// Only the 3 most significant tracks are actually sorted
+
+ if (ntr <= 1) return;
+
+ //
+ // Loop over signals, only 3 times
+ //
+
+ Int_t qmax;
+ Int_t jmax;
+ Int_t idx[3] = {-2,-2,-2};
+ Int_t jch[3] = {-2,-2,-2};
+ Int_t jtr[3] = {-2,-2,-2};
+ Int_t i, j, imax;
+
+ if (ntr < 3) imax = ntr;
+ else imax=3;
+
+ for(i = 0; i < imax; i++)
+ {
+ qmax=0;
+ jmax=0;
+
+ for(j = 0; j < ntr; j++)
+ {
+ if ( (i == 1 && j == idx[i-1]) ||
+ (i == 2 && (j == idx[i-1] || j == idx[i-2]))
+ )
+ continue;
+
+ if(charges[j] > qmax)
+ {
+ qmax = charges[j];
+ jmax = j;
+ }
+ }
+
+ if(qmax > 0)
+ {
+ idx[i] = jmax;
+ jch[i] = charges[jmax];
+ jtr[i] = tracks[jmax];
+ }
+
+ }
+
+ for(i = 0; i < 3; i++)
+ {
+ if (jtr[i] == -2)
+ {
+ charges[i] = 0;
+ tracks[i] = 0;
+ }
+ else
+ {
+ charges[i] = jch[i];
+ tracks[i] = jtr[i];
+ }
+ }
}