#include <TDirectory.h>
#include <TPDGCode.h>
+#include "AliRun.h"
+#include "AliRunDigitizer.h"
#include "AliRunLoader.h"
#include "AliLoader.h"
-#include <Riostream.h>
#include "AliMUONDigitizer.h"
#include "AliMUONConstants.h"
#include "AliMUONHitMapA1.h"
#include "AliMUONPadHit.h"
#include "AliMUONTransientDigit.h"
-#include "AliRun.h"
-#include "AliRunDigitizer.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),
+ fDebug(0)
{
-// Default ctor - don't use it
- fHits = 0;
- fPadHits = 0;
- fHitMap = 0;
- fTDList = 0;
-}
+// Default constructor.
+// Initializes all pointers to NULL.
+
+ runloader = NULL;
+ gime = NULL;
+ pMUON = NULL;
+ muondata = NULL;
+};
//___________________________________________
-AliMUONDigitizer::AliMUONDigitizer(AliRunDigitizer* manager)
- :AliDigitizer(manager)
+AliMUONDigitizer::AliMUONDigitizer(AliRunDigitizer* manager) :
+ AliDigitizer(manager),
+ fHitMap(0),
+ fTDList(0),
+ fTDCounter(0),
+ fMask(0),
+ fSignal(0),
+ fDebug(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.
+
+ runloader = NULL;
+ gime = NULL;
+ pMUON = NULL;
+ muondata = NULL;
+};
//------------------------------------------------------------------------
-AliMUONDigitizer::~AliMUONDigitizer()
+Bool_t AliMUONDigitizer::Init()
{
-// Destructor
- if (fHits) delete fHits;
- if (fPadHits) delete fPadHits;
+// Does nothing.
+ return kTRUE;
}
//------------------------------------------------------------------------
-Bool_t AliMUONDigitizer::Exists(const AliMUONPadHit *padhit) const
+void AliMUONDigitizer::Exec(Option_t* option)
{
- return (fHitMap[fNch]->TestHit(padhit->PadX(),padhit->PadY()));
-}
+// 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()
+
+ if (GetDebug() > 0) Info("Exec", "Running digitiser.");
+ ParseOptions(option);
+
+ if (fManager->GetNinputs() == 0)
+ {
+ Warning("Exec", "No inputs set, nothing to do.");
+ return;
+ };
+
+ if (! FetchLoaders(fManager->GetInputFolderName(0), runloader, gime) ) return;
+ if (! FetchGlobalPointers(runloader) ) return;
+
+ InitArrays();
+
+ if (GetDebug() > 1) Info("Exec", "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);
+ if (GetDebug() > 1)
+ Info("Exec", "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), runloader, gime) )
+ continue;
+ else
+ // If this is not the first file then it is assumed to be background.
+ fSignal = kFALSE;
+
+ if (! InitInputData(gime) ) continue;
+ GenerateTransientDigits();
+ CleanupInputData(gime);
+ };
+
+ Bool_t ok = FetchLoaders(fManager->GetOutputFolderName(), runloader, gime);
+ if (ok) ok = InitOutputData(gime);
+ if (ok) CreateDigits();
+ if (ok) CleanupOutputData(gime);
+
+ CleanupArrays();
+};
+
+//--------------------------------------------------------------------------
+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::Update(AliMUONPadHit *padhit)
+void AliMUONDigitizer::UpdateTransientDigit(AliMUONTransientDigit* mTD)
{
- 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);
-}
+// Update the transient digit that is already in the fTDList by adding the new
+// transient digits charges and track lists to the existing one.
+
+ if (GetDebug() > 3)
+ Info("UpdateTransientDigit", "Updating transient digit 0x%X", (void*)mTD);
+ // Choosing the maping of the cathode plane of the chamber:
+ Int_t iNchCpl= mTD->Chamber() + (mTD->Cathode()-1) * AliMUONConstants::NCh();
+ 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.
+ {
+ if (GetDebug() > 0)
+ {
+ Warning("UpdateTransientDigit",
+ "TransientDigit returned the number of tracks to be %d, which is bigger than kMAXTRACKS.",
+ ntracks);
+ Warning("UpdateTransientDigit", "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::CreateNew(AliMUONPadHit *padhit)
+void AliMUONDigitizer::AddTransientDigit(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++;
-}
-
+// Adds the transient digit to the fTDList and sets the appropriate entry
+// in the fHitMap arrays.
+
+ if (GetDebug() > 3)
+ Info("AddTransientDigit", "Adding transient digit 0x%X", (void*)mTD);
+ // Choosing the maping of the cathode plane of the chamber:
+ Int_t iNchCpl= mTD->Chamber() + (mTD->Cathode()-1) * AliMUONConstants::NCh();
+ fTDList->AddAtAndExpand(mTD, fTDCounter);
+ 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 iNchCpl= mTD->Chamber() + (mTD->Cathode()-1) * AliMUONConstants::NCh();
+ return( fHitMap[iNchCpl]->TestHit(mTD->PadX(), mTD->PadY()) );
+};
+//-----------------------------------------------------------------------
+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.
+
+ if (GetDebug() > 1) Info("CreateDigits", "Creating digits...");
+ for (Int_t icat = 0; icat < 2; icat++)
+ {
+ //
+ // 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;
+
+ if (GetDebug() > 2)
+ Info("CreateDigits", "Creating digit from transient digit 0x%X", (void*)td);
+
+ Int_t q = GetSignalFrom(td);
+ if (q > 0) AddDigit(td, q);
+ };
+ FillOutputData();
+ };
+};
//------------------------------------------------------------------------
-//void AliMUONDigitizer::Digitize()
-void AliMUONDigitizer::Exec(Option_t* /*option*/)
+void AliMUONDigitizer::AddDigit(AliMUONTransientDigit* td, Int_t response_charge)
{
- // 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;
+// 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 response_charge 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[6];
-// rl = AliRunLoader::GetRunLoader(fManager->GetInputFolderName(inputFile));
-// gime = rl->GetLoader("MUONLoader");
-
-
-// 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();
-
-
-// pMUON->ResetDigits(); //
-// fTDList->Clear();
-
-
-// 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();
-}
+ digits[0] = td->PadX();
+ digits[1] = td->PadY();
+ digits[2] = td->Cathode() - 1;
+ digits[3] = response_charge;
+ digits[4] = td->Physics();
+ digits[5] = td->Hit();
+
+ Int_t nptracks = td->GetNTracks();
+ if (nptracks > kMAXTRACKS)
+ {
+ if (GetDebug() > 0)
+ {
+ Warning("AddDigit",
+ "TransientDigit returned the number of tracks to be %d, which is bigger than kMAXTRACKS.",
+ nptracks);
+ Warning("AddDigit", "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;
+ };
+ };
+
+ if (GetDebug() > 3) Info("AddDigit", "Adding digit with charge %d.", response_charge);
+
+ OnWriteTransientDigit(td);
+ AddDigit(td->Chamber(), tracks, charges, digits);
+};
+//------------------------------------------------------------------------
+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.
+};
//------------------------------------------------------------------------
-void AliMUONDigitizer::SortTracks(Int_t *tracks,Int_t *charges,Int_t ntr)
+void AliMUONDigitizer::OnWriteTransientDigit(AliMUONTransientDigit* /*digit*/)
{
- //
- // 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;
-
- 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];
- }
- }
+ // 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.
+
+ if (GetDebug() > 2)
+ Info("FetchLoaders", "Fetching run loader and muon loader from folder: %s", foldername);
+
+ runloader = AliRunLoader::GetRunLoader(foldername);
+ if (runloader == NULL)
+ {
+ Error("FetchLoaders", "RunLoader not found in folder: %s", foldername);
+ return kFALSE;
+ }
+ muonloader = (AliMUONLoader*) runloader->GetLoader("MUONLoader");
+ if (muonloader == NULL)
+ {
+ Error("FetchLoaders", "MUONLoader not found in folder: %s", foldername);
+ return kFALSE;
+ }
+ return kTRUE;
+};
+
+//------------------------------------------------------------------------
+Bool_t AliMUONDigitizer::FetchGlobalPointers(AliRunLoader* runloader)
+{
+// 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.
+
+ if (GetDebug() > 2)
+ Info("FetchGlobalPointers", "Fetching gAlice, MUON module and AliMUONData from runloader 0x%X.",
+ (void*)runloader
+ );
+
+ if (runloader->GetAliRun() == NULL) runloader->LoadgAlice();
+ gAlice = runloader->GetAliRun();
+ if (gAlice == NULL)
+ {
+ Error("FetchGlobalPointers", "Could not find the AliRun object in runloader 0x%X.", (void*)runloader);
+ return kFALSE;
+ };
+ pMUON = (AliMUON*) gAlice->GetDetector("MUON");
+ if (pMUON == NULL)
+ {
+ Error("FetchGlobalPointers", "Could not find the MUON module in runloader 0x%X.", (void*)runloader);
+ return kFALSE;
+ };
+ muondata = pMUON->GetMUONData();
+ if (muondata == NULL)
+ {
+ Error("FetchGlobalPointers", "Could not find AliMUONData object in runloader 0x%X.", (void*)runloader);
+ return kFALSE;
+ };
+ return kTRUE;
}
+
+//------------------------------------------------------------------------
+void AliMUONDigitizer::ParseOptions(Option_t* options)
+{
+// Called by the Exec method. ParseOptions should parse the option string given to the Exec method.
+//
+// The following options are defined:
+// "debug" - Sets the debug level to 99, which will show all debug messages.
+// "deb" - Same as "debug", implemented for backward comparability.
+//
+// If an invalid option is specified it is simply ignored.
+
+ TString optionString = options;
+ if (optionString.Data() == "debug" ||
+ optionString.Data() == "deb" // maintained for compatability.
+ )
+ {
+ Info("ParseOptions", "Called with option \"debug\".");
+ SetDebug(99);
+ };
+};
+
+//------------------------------------------------------------------------
+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.
+
+ if (GetDebug() > 1) Info("InitArrays", "Initialising internal arrays.");
+ if (GetDebug() > 3) Info("InitArrays", "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::NCh()];
+
+ // Loop over chambers for the definition AliMUONHitMap
+ for (Int_t i = 0; i < AliMUONConstants::NCh(); i++)
+ {
+ if (GetDebug() > 3) Info("InitArrays", "Creating hit map for chamber %d, cathode 1.", i+1);
+ AliMUONChamber* chamber = &(pMUON->Chamber(i));
+ AliSegmentation* c1Segmentation = chamber->SegmentationModel(1); // Cathode plane 1
+ fHitMap[i] = new AliMUONHitMapA1(c1Segmentation, fTDList);
+ if (GetDebug() > 3) Info("InitArrays", "Creating hit map for chamber %d, cathode 2.", i+1);
+ AliSegmentation* c2Segmentation = chamber->SegmentationModel(2); // Cathode plane 2
+ fHitMap[i+AliMUONConstants::NCh()] = new AliMUONHitMapA1(c2Segmentation, fTDList);
+ };
+};
+
+//------------------------------------------------------------------------
+void AliMUONDigitizer::CleanupArrays()
+{
+// The arrays fTDList and fHitMap are deleted and the pointers set to NULL.
+
+ if (GetDebug() > 1) Info("CleanupArrays", "Deleting internal arrays.");
+ for(Int_t i = 0; i < 2*AliMUONConstants::NCh(); i++)
+ {
+ if (GetDebug() > 3) Info("CleanupArrays", "Deleting hit map for chamber %d, cathode %d.",
+ i%AliMUONConstants::NCh()+1, i/AliMUONConstants::NCh()+1);
+ delete fHitMap[i];
+ };
+ delete [] fHitMap;
+ fHitMap = NULL;
+
+ if (GetDebug() > 3) Info("CleanupArrays", "Deleting transient digits list.");
+ fTDList->Delete();
+ delete fTDList;
+ fTDList = NULL;
+};
+
+//------------------------------------------------------------------------
+void AliMUONDigitizer::SortTracks(Int_t *tracks, Int_t *charges, Int_t ntr)
+{
+//
+// 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];
+ }
+ }
+};
/* $Id$ */
#include "AliDigitizer.h"
+#include "AliRunLoader.h"
+#include "AliMUONLoader.h"
+#include "AliMUONTransientDigit.h"
+#include "AliMUON.h"
+#include "AliMUONData.h"
class AliRunDigitizer;
-class AliMUONPadHit;
class AliMUONHitMapA1;
-class AliMUONDigitizer : public AliDigitizer {
- public:
-
- AliMUONDigitizer();
- AliMUONDigitizer(AliRunDigitizer * manager);
- virtual ~AliMUONDigitizer();
-
- // Compare pad hits
- virtual Bool_t Exists(const AliMUONPadHit * sdigit) const;
- // Update a pad hit
- virtual void Update(AliMUONPadHit *sdigit);
- // Create a new hit
- virtual void CreateNew(AliMUONPadHit *sdigit);
-
- // Initialize merging and digitization
- virtual Bool_t Init();
-
- // Do the main work
- virtual void Exec(Option_t* option=0);
-
- Int_t GetDebug() const {return fDebug;} // get debug level
- void SetDebug(Int_t level){fDebug = level;} // set debug level
- enum {kBgTag = -1};
-
- private:
- void SortTracks(Int_t *tracks,Int_t *charges,Int_t ntr);
-
- private:
- TClonesArray* fHits;
- TClonesArray* fPadHits;
- AliMUONHitMapA1 **fHitMap; //! pointer to array of pointers to hitmaps
- Int_t fNch; //! chamber nr (loop variable)
- Int_t fTrack; //! track nr (loop variable)
- TObjArray *fTDList; //! list of AliMUONTransientDigits
- Int_t fCounter; //! nr. of AliMUONTransientDigit
- Bool_t fSignal; //! kTRUE if signal file is processed
- Int_t fMask; //! mask dependent on input file
- Int_t fDigits[6]; //! array with digits
- Int_t fDebug; //! debug level
-
- ClassDef(AliMUONDigitizer,1) // MUON merging/digitization
+
+class AliMUONDigitizer : public AliDigitizer
+{
+public:
+
+ /* Default constructor initializes all the internal pointers to NULL.
+ */
+ AliMUONDigitizer();
+
+ /* Constructor initialises all the internal pointers to NULL and
+ sets this digitizers manager to the one specified.
+ */
+ AliMUONDigitizer(AliRunDigitizer * manager);
+
+ // The Init method does nothing.
+ // All initialization happens in Exec at the moment.
+ virtual Bool_t Init();
+
+ // Override the TTask Exec method.
+ virtual void Exec(Option_t* option = 0);
+
+ Int_t GetDebug() const {return fDebug;} // Get debug level.
+ void SetDebug(Int_t level){fDebug = level;} // Set debug level.
+
+protected:
+
+ // Parses the option string given to the Exec method.
+ virtual void ParseOptions(Option_t* options);
+
+ /* Digitizers inheriting from AliMUONDigitizer should implement this abstract method
+ so that TransientDigit objects are generated and put onto the fTDList.
+ The method would be implemented as some loop over the input stream. The data can be
+ fetched from the muondata pointer. To add to the fTDList once should use code similar
+ to the following:
+
+ TObject* source_object; // Assume the object from which the transient digit
+ // is created is already initialized at this point.
+ AliMUONTransientDigit* td = new AliMUONTransientDigit();
+ // Initialize the transient digit.
+ // ...
+
+ // The following line of code is required to have working digitisers that want
+ // to store information about which digits were created from which hits.
+ OnCreateTransientDigit(td, source_object);
+
+ AddOrUpdateTransientDigit(td); // Adds to the fTDList preventing duplicates.
+ */
+ virtual void GenerateTransientDigits() = 0;
+
+ // Loops over the fTDList of transient digits to write them to the output stream.
+ virtual void CreateDigits();
+
+ /* Inheriting digitizers should implement this method to prepare the muondata
+ object before GenerateTransientDigits() is called.
+ If the initialization was successful then kTRUE should be returned otherwise
+ kFALSE should be returned.
+ */
+ virtual Bool_t InitInputData(AliMUONLoader* muonloader) = 0;
+
+ /* This method should be overridden to undo/cleanup what was done in the
+ InitInputData method call.
+ */
+ virtual void CleanupInputData(AliMUONLoader* muonloader) = 0;
+
+ /* Inheriting digitizers should implement this method to prepare the muondata
+ object before CreateDigits() is called.
+ If the initialization was successful then kTRUE should be returned otherwise
+ kFALSE should be returned.
+ */
+ virtual Bool_t InitOutputData(AliMUONLoader* muonloader) = 0;
+
+ /* When all the data is added to the muondata object and the trees need to be
+ filled then this method is called by CreateDigits().
+ Thus code like
+ muondata->Fill("D")
+ should go into this method.
+ */
+ virtual void FillOutputData() = 0;
+
+ /* This method should be overridden to undo/cleanup what was done in the
+ InitOutputData method call.
+ */
+ virtual void CleanupOutputData(AliMUONLoader* muonloader) = 0;
+
+ /* This is called by CreateDigits when it wants the Signal value that will be written
+ to the output stream. Inheriting digitizers can override this to apply some kind
+ of detector response.
+ */
+ virtual Int_t GetSignalFrom(AliMUONTransientDigit* td) = 0;
+
+ /* Should be overridden by inheriting digitizers such that this method adds the digits
+ to the correct tree.
+ */
+ virtual void AddDigit(Int_t chamber, Int_t tracks[kMAXTRACKS], Int_t charges[kMAXTRACKS], Int_t digits[6]) = 0;
+
+ /* Should be called by GenerateTransientDigits() when a new transient digit is generated
+ form a source object from the input stream. The source object could be an AliMUONHit
+ or AliMUONSDigit for example.
+ */
+ virtual void OnCreateTransientDigit(AliMUONTransientDigit* /*digit*/, TObject* /*source_object*/);
+
+ /* Called by AddDigit(AliMUONTransientDigit*, Int_t) when transient digit is added to the
+ muondata object ready for writing to the data trees.
+ */
+ virtual void OnWriteTransientDigit(AliMUONTransientDigit* digit);
+
+ // Wrapper method for AddDigit(Int_t, Int_t[kMAXTRACKS], Int_t[kMAXTRACKS], Int_t[6])
+ void AddDigit(AliMUONTransientDigit* td, Int_t response_charge);
+
+ // Creates a new fTDList object, and creates and fills the fHitMap arrays.
+ // Note: this method assumes the array pointers are NULL when calling this method.
+ void InitArrays();
+
+ // Frees the memory allocated for fTDList and the fHitMap arrays.
+ void CleanupArrays();
+
+ /* Gets the run loader and muon loader pointers from the given folder name. If an error
+ occurred then kFALSE is returned else kTRUE on success.
+ */
+ Bool_t FetchLoaders(const char* foldername, AliRunLoader*& runloader, AliMUONLoader*& muonloader);
+
+ /* Gets the gAlice, and MUON module pointers from the specified run loader. If an error
+ occurred then kFALSE is returned else kTRUE on success.
+ */
+ Bool_t FetchGlobalPointers(AliRunLoader* runloader);
+
+ // Adds the transient digit uniquely to the fTDList.
+ void AddOrUpdateTransientDigit(AliMUONTransientDigit* mTD);
+
+ // Updates a TransientDigit in fTDList
+ void UpdateTransientDigit(AliMUONTransientDigit * mTD);
+
+ // Adds the new TransientDigit to fTDList
+ void AddTransientDigit(AliMUONTransientDigit * mTD);
+
+ // Verify that a TransientDigit already exists.
+ Bool_t ExistTransientDigit(AliMUONTransientDigit * mTD);
+
+ // Sorts the 3 most significant tracks.
+ void SortTracks(Int_t *tracks, Int_t *charges, Int_t ntr);
+
+
+ AliRunLoader* runloader; //! Global run loader.
+ AliMUONLoader* gime; //! MUON specific loader.
+ AliMUON* pMUON; //! Pointer to MUON module.
+ AliMUONData* muondata; //! muon data interface
+
+ AliMUONHitMapA1 **fHitMap; //! pointer to array of pointers to hitmaps
+ TObjArray *fTDList; //! list of AliMUONTransientDigits
+ Int_t fTDCounter; //! nr. of AliMUONTransientDigit
+ Int_t fMask; //! mask dependent on input file
+ Bool_t fSignal; //! kTRUE if signal file is processed
+
+private:
+
+ Int_t fDebug; //! Debug level.
+
+ ClassDef(AliMUONDigitizer, 1) // MUON merging/digitization
};
#endif
-
-
#include <Riostream.h>
#include <TDirectory.h>
#include <TFile.h>
#include <TTree.h>
#include <TMath.h>
+#include "AliRun.h"
+#include "AliRunDigitizer.h"
+#include "AliRunLoader.h"
+#include "AliLoader.h"
+
#include "AliMUON.h"
#include "AliMUONChamber.h"
#include "AliMUONConstants.h"
#include "AliMUONHitMapA1.h"
#include "AliMUONPadHit.h"
#include "AliMUONTransientDigit.h"
-#include "AliRun.h"
-#include "AliRunDigitizer.h"
-#include "AliRunLoader.h"
-#include "AliLoader.h"
+
+/////////////////////////////////////////////////////////////////////////////////
+//
+// AliMUONDigitizerv1 implements a full digitizer to digitize digits directly
+// from hits. It also performs merging over several input streams.
+// The first input stream is assumed to be the signal and all other input
+// streams are assumed to be background. SDigits are never generated by this
+// digitizer and one should use the AliMUONSDigitizerv1 for that task.
+//
+// NOTE: This digitizer will become depricated in the future in favour of
+// AliMUONSDigitizerv1 and AliMUONDigitizerv2.
+//
+/////////////////////////////////////////////////////////////////////////////////
ClassImp(AliMUONDigitizerv1)
//___________________________________________
-AliMUONDigitizerv1::AliMUONDigitizerv1() :
- AliDigitizer(),
- fHitMap(0),
- fTDList(0),
- fTDCounter(0),
- fDebug(0),
- fMask(0),
- fSignal(0)
+AliMUONDigitizerv1::AliMUONDigitizerv1() : AliMUONDigitizer()
{
-// Default ctor - don't use it
- if (GetDebug()>2)
- cerr<<"AliMUONDigitizerv1::AliMUONDigitizerv1"
- <<"(AliRunDigitizer* manager) was processed"<<endl;
+ // Default ctor - don't use it
}
//___________________________________________
-AliMUONDigitizerv1::AliMUONDigitizerv1(AliRunDigitizer* manager):
- AliDigitizer(manager),
- fHitMap(0),
- fTDList(0),
- fTDCounter(0),
- fDebug(0),
- fMask(0),
- fSignal(0)
+AliMUONDigitizerv1::AliMUONDigitizerv1(AliRunDigitizer* manager) : AliMUONDigitizer(manager)
{
-// ctor which should be used
- if (GetDebug()>2)
- cerr<<"AliMUONDigitizerv1::AliMUONDigitizerv1"
- <<"(AliRunDigitizer* manager) was processed"<<endl;
+ // ctor which should be used
}
+//-----------------------------------------------------------------------
+void AliMUONDigitizerv1::GenerateTransientDigits()
+{
+// Loops over all tracks and hits in the current selected event and calls
+// MakeTransientDigitsFromHit for each hit.
+// Note: Charge correlation is applied to the tracking chambers.
+
+ TTree* treeH = gime->TreeH();
+ if (GetDebug() > 1)
+ Info("GenerateTransientDigits", "Generating transient digits using treeH = 0x%X"
+ , (void*)treeH);
+ //
+ // Loop over tracks
+ Int_t ntracks = (Int_t) treeH->GetEntries();
+ for (Int_t itrack = 0; itrack < ntracks; itrack++)
+ {
+ if (GetDebug() > 2) Info("GenerateTransientDigits", "Processing track %d...", itrack);
+ muondata->ResetHits();
+ treeH->GetEvent(itrack);
+ //
+ // Loop over hits
+ TClonesArray* hits = muondata->Hits();
+ for (Int_t ihit = 0; ihit < hits->GetEntriesFast(); ihit++)
+ {
+ AliMUONHit* mHit = static_cast<AliMUONHit*>( hits->At(ihit) );
+ Int_t ichamber = mHit->Chamber()-1; // chamber number
+ if (ichamber > AliMUONConstants::NCh()-1)
+ {
+ Error("GenerateTransientDigits",
+ "Hit 0x%X has a invalid chamber number: %d", ichamber);
+ continue;
+ }
+ //
+ //Dumping Hit content:
+ if (GetDebug() > 2)
+ {
+ Info("GenerateTransientDigits",
+ "Hit %d: chamber = %d\tX = %f\tY = %f\tZ = %f\teloss = %f",
+ ihit, mHit->Chamber(), mHit->X(), mHit->Y(), mHit->Z(), mHit->Eloss()
+ );
+ }
+ //
+ // Inititializing Correlation
+ AliMUONChamber& chamber = pMUON->Chamber(ichamber);
+ chamber.ChargeCorrelationInit();
+ if (ichamber < AliMUONConstants::NTrackingCh())
+ {
+ // Tracking Chamber
+ // Initialize hit position (cursor) in the segmentation model
+ chamber.SigGenInit(mHit->X(), mHit->Y(), mHit->Z());
+ }; // else do nothing for Trigger Chambers
+
+ MakeTransientDigitsFromHit(itrack, ihit, mHit);
+ } // hit loop
+ } // track loop
+};
+
+//--------------------------------------------------------------------------
+void AliMUONDigitizerv1::MakeTransientDigitsFromHit(Int_t track, Int_t iHit, AliMUONHit * mHit)
+{
+// This method is called for every hit in an event to generate AliMUONTransientDigits
+// from the hit and add these to fTDList.
+// The AliMUONChamber::DisIntegration method us used to figure out which pads are
+// fired for a given hit. We then loop over the fired pads and add an AliMUONTransientDigit
+// for each pad.
+
+ if (GetDebug() > 3)
+ Info("MakeTransientDigitsFromHit", "Making transient digit for hit number %d.", iHit);
+
+ //
+ // Calls the charge disintegration method of the current chamber
+ if (GetDebug() > 4)
+ Info("MakeTransientDigitsFromHit", "Calling AliMUONChamber::DisIngtegration...");
+
+ Float_t newdigit[6][500]; // Pad information
+ Int_t nnew=0; // Number of touched Pads per hit
+ Int_t ichamber = mHit->Chamber()-1;
+ AliMUONChamber& chamber = pMUON->Chamber(ichamber);
+ chamber.DisIntegration(mHit->Eloss(), mHit->Age(), mHit->X(), mHit->Y(), mHit->Z(), nnew, newdigit);
+
+ // Creating new TransientDigits from hit
+ for(Int_t iTD = 0; iTD < nnew; iTD++)
+ {
+ Int_t charge;
+ Int_t digits[6];
+
+ digits[0] = Int_t(newdigit[1][iTD]); // Padx of the Digit
+ digits[1] = Int_t(newdigit[2][iTD]); // Pady of the Digit
+ digits[2] = Int_t(newdigit[5][iTD]); // Cathode plane
+ digits[3] = Int_t(newdigit[3][iTD]); // Induced charge in the Pad
+ if (fSignal)
+ {
+ charge = digits[3];
+ digits[4] = Int_t(newdigit[3][iTD]); // Signal due to physics
+ }
+ else
+ {
+ charge = digits[3] + fMask;
+ digits[4] = 0; // No signal due to physics since this is now background.
+ };
+ digits[5] = iHit+fMask; // Hit number in the list
+
+ if (GetDebug() > 4)
+ Info("MakeTransientDigitsFromHit",
+ "DisIntegration result %d: PadX %d\tPadY %d\tPlane %d\tCharge %d\tHit %d",
+ iTD, digits[0], digits[1], digits[2], digits[3], digits[5]);
+
+ AliMUONTransientDigit* mTD = new AliMUONTransientDigit(ichamber, digits);
+ mTD->AddToTrackList(track + fMask, charge);
+
+ OnCreateTransientDigit(mTD, mHit);
+ AddOrUpdateTransientDigit(mTD);
+ };
+};
+
//------------------------------------------------------------------------
-AliMUONDigitizerv1::~AliMUONDigitizerv1()
+void AliMUONDigitizerv1::AddDigit(Int_t chamber, Int_t tracks[kMAXTRACKS], Int_t charges[kMAXTRACKS], Int_t digits[6])
{
-// Destructor
-}
+// Derived to add digits to TreeD.
+ muondata->AddDigit(chamber, tracks, charges, digits);
+};
//------------------------------------------------------------------------
-void AliMUONDigitizerv1::AddTransientDigit(AliMUONTransientDigit * mTD)
+Int_t AliMUONDigitizerv1::GetSignalFrom(AliMUONTransientDigit* td)
{
- // Choosing the maping of the cathode plane of the chamber:
- Int_t iNchCpl= mTD->Chamber() + (mTD->Cathode()-1) * AliMUONConstants::NCh();
- fTDList->AddAtAndExpand(mTD, fTDCounter);
- fHitMap[iNchCpl]->SetHit( mTD->PadX(), mTD->PadY(), fTDCounter);
- fTDCounter++;
-}
+// Derived to apply the chamber response model to the digit.
+// Using AliMUONChamber::ResponseModel() for this.
+
+ if (GetDebug() > 3)
+ Info("GetSignalFrom", "Applying response of chamber to TransientDigit signal.");
+ //
+ // Digit Response (noise, threshold, saturation, ...)
+ Int_t q = td->Signal();
+ AliMUONChamber& chamber = pMUON->Chamber(td->Chamber());
+ AliMUONResponse* response = chamber.ResponseModel();
+ q = response->DigitResponse(q, td);
+ return q;
+};
//------------------------------------------------------------------------
-Bool_t AliMUONDigitizerv1::ExistTransientDigit(AliMUONTransientDigit * mTD)
+Bool_t AliMUONDigitizerv1::InitOutputData(AliMUONLoader* muonloader)
{
- // Choosing the maping of the cathode plane of the chamber:
- Int_t iNchCpl= mTD->Chamber() + (mTD->Cathode()-1) * AliMUONConstants::NCh();
- return( fHitMap[iNchCpl]->TestHit(mTD->PadX(), mTD->PadY()) );
-}
+// Derived to initialize the output digits tree TreeD, create it if necessary
+// and sets the muondata tree address to treeD.
+
+ if (GetDebug() > 2)
+ Info("InitOutputData", "Creating digits branch and setting the tree address.");
+
+ muondata->SetLoader(muonloader);
+
+ // New branch per chamber for MUON digit in the tree of digits
+ if (muonloader->TreeD() == NULL)
+ {
+ muonloader->MakeDigitsContainer();
+ if (muonloader->TreeD() == NULL)
+ {
+ Error("InitOutputData", "Could not create TreeD.");
+ return kFALSE;
+ };
+ };
+
+ muondata->MakeBranch("D");
+ muondata->SetTreeAddress("D");
+
+ return kTRUE;
+};
//------------------------------------------------------------------------
-Bool_t AliMUONDigitizerv1::Init()
+void AliMUONDigitizerv1::FillOutputData()
{
+// Derived to fill TreeD and resets the digit array in muondata.
-// Initialization
- if (GetDebug()>2) Info("Init","AliMUONDigitizerv1::Init() starts");
-
- //Loaders (We assume input0 to be the output too)
- AliRunLoader * runloader; // Input loader
- AliLoader * gime;
-
- // Getting runloader
- runloader = AliRunLoader::GetRunLoader(fManager->GetInputFolderName(0));
- if (runloader == 0x0) {
- Error("Init","RunLoader is not in input file 0");
- return kFALSE; // RunDigitizer is not working.
- }
- // Getting MUONloader
- gime = runloader->GetLoader("MUONLoader");
- gime->LoadHits("READ");
- gime->LoadDigits("RECREATE");
-
- return kTRUE;
-}
+ if (GetDebug() > 2) Info("FillOutputData", "Filling trees with digits.");
+ muondata->Fill("D");
+ muondata->ResetDigits();
+};
//------------------------------------------------------------------------
-void AliMUONDigitizerv1::UpdateTransientDigit(Int_t track, AliMUONTransientDigit * mTD)
+void AliMUONDigitizerv1::CleanupOutputData(AliMUONLoader* muonloader)
{
- // Choosing the maping of the cathode plane of the chamber:
- Int_t iNchCpl= mTD->Chamber() + (mTD->Cathode()-1) * AliMUONConstants::NCh();
- AliMUONTransientDigit *pdigit =
- static_cast<AliMUONTransientDigit*>(fHitMap[iNchCpl]->GetHit(mTD->PadX(),mTD->PadY()));
- // update charge
- //
- Int_t iqpad = mTD->Signal(); // charge per pad
- pdigit->AddSignal(iqpad);
- pdigit->AddPhysicsSignal(iqpad);
- // update list of tracks
- //
- Int_t charge;
- track=+ fMask;
- if (fSignal) charge = iqpad;
- //else charge = kBgTag;
- else charge = iqpad + fMask;
-
- pdigit->UpdateTrackList(track,charge);
-}
+// Derived to write the digits tree and then unload the digits tree once written.
+ if (GetDebug() > 2) Info("CleanupOutputData", "Writing digits and releasing pointers.");
+ muonloader->WriteDigits("OVERWRITE");
+ muonloader->UnloadDigits();
+};
-//--------------------------------------------------------------------------
-void AliMUONDigitizerv1::MakeTransientDigit(Int_t track, Int_t iHit, AliMUONHit * mHit)
-{
- AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
- if (!pMUON) {
- cerr<<"AliMUONDigitizerv1::Digitize Error:"
- <<" module MUON not found in the input file"<<endl;
- }
- if (GetDebug()>2) cerr<<"AliMUONDigitizerv1::MakeTransientDigit starts"<<endl;
- Int_t ichamber = mHit->Chamber()-1;
- AliMUONChamber & chamber = pMUON->Chamber(ichamber);
- Float_t xhit = mHit->X();
- Float_t yhit = mHit->Y();
- Float_t zhit = mHit->Z();
- Float_t eloss= mHit->Eloss();
- Float_t tof = mHit->Age();
- // Variables for chamber response from AliMUONChamber::DisIntegration
- Float_t newdigit[6][500]; // Pad information
- Int_t nnew=0; // Number of touched Pads per hit
- Int_t digits[6];
-
- //
- // Calls the charge disintegration method of the current chamber
- if (GetDebug()>2) cerr<<"AliMUONDigitizerv1::MakeTransientDigit calling AliMUONChamber::DisIngtegration starts"<<endl;
- chamber.DisIntegration(eloss, tof, xhit, yhit, zhit, nnew, newdigit);
- // Creating a new TransientDigits from hit
- for(Int_t iTD=0; iTD<nnew; iTD++) {
- digits[0] = Int_t(newdigit[1][iTD]); // Padx of the Digit
- digits[1] = Int_t(newdigit[2][iTD]); // Pady of the Digit
- digits[2] = Int_t(newdigit[5][iTD]); // Cathode plane
- digits[3] = Int_t(newdigit[3][iTD]); // Induced charge in the Pad
- if (fSignal) digits[4] = Int_t(newdigit[3][iTD]);
- else digits[4] = 0;
- digits[5] = iHit+fMask; // Hit number in the list
- if (GetDebug()>2) cerr<<"AliMUONDigitizerv1::MakeTransientDigit " <<
- "PadX "<< digits[0] << " " <<
- "PadY "<< digits[1] << " " <<
- "Plane " << digits[2] << " " <<
- "Charge " << digits[3] <<" " <<
- "Hit " << digits[5] << endl;
- // list of tracks
- Int_t charge;
- track += fMask;
- if (fSignal) charge = digits[3];
- //else charge = kBgTag;
- else charge = digits[3] + fMask;
-
- if (GetDebug()>2) cerr<<"AliMUONDigitizerv1::MakeTransientDigit Creating AliMUONTransientDigit"<<endl;
- AliMUONTransientDigit * mTD = new AliMUONTransientDigit(ichamber, digits);
- mTD->AddToTrackList(track,charge);
- if (!ExistTransientDigit(mTD)) {
- AddTransientDigit(mTD);
- if (GetDebug()>2) cerr<<"AliMUONDigitizerv1::MakeTransientDigit Adding TransientDigit"<<endl;
- }
- else {
- if (GetDebug()>2) cerr<<"AliMUONDigitizerv1::MakeTransientDigit updating TransientDigit"<<endl;
- UpdateTransientDigit(track, mTD);
- delete mTD;
- }
- }
-}
-//-----------------------------------------------------------------------
-void AliMUONDigitizerv1::Exec(Option_t* option)
+
+//------------------------------------------------------------------------
+Bool_t AliMUONDigitizerv1::InitInputData(AliMUONLoader* muonloader)
{
- TString optionString = option;
- if (optionString.Data() == "deb") {
- Info("Digitize","Called with option deb ");
- fDebug = 3;
- }
-
- AliMUONChamber* chamber;
- AliSegmentation* c1Segmentation; //Cathode plane c1 of the chamber
- AliSegmentation* c2Segmentation; //Cathode place c2 of the chamber
-
- if (GetDebug()>2) Info("Digitize","AliMUONDigitizerv1::Digitize() starts");
- fTDList = new TObjArray;
-
- //Loaders (We assume input0 to be the output too)
- AliRunLoader * runloader; // Input loader
- AliLoader * gime;
-
- // Getting runloader
- runloader = AliRunLoader::GetRunLoader(fManager->GetInputFolderName(0));
- if (runloader == 0x0) {
- Error("Digitize","RunLoader is not in input file 0");
- return; // RunDigitizer is not working.
- }
- // Getting MUONloader
- gime = runloader->GetLoader("MUONLoader");
- if (gime->TreeH()==0x0) {
- if (GetDebug()>2) Info("Digitize","TreeH is not loaded yet. Loading...");
- gime->LoadHits("READ");
- if (GetDebug()>2) Info("Digitize","Now treeH is %#x. MUONLoader is %#x",gime->TreeH(),gime);
- }
-
- if (GetDebug()>2) Info("Digitize","Loaders ready");
-
- if (runloader->GetAliRun() == 0x0) runloader->LoadgAlice();
- gAlice = runloader->GetAliRun();
-
- // Getting Module MUON
- AliMUON *pMUON = (AliMUON *) gAlice->GetDetector("MUON");
- if (!pMUON) {
- Error("Digitize","Module MUON not found in the input file");
- return;
- }
- // Getting Muon data
- AliMUONData * muondata = pMUON->GetMUONData();
- muondata->SetLoader(gime);
- muondata->SetTreeAddress("H");
-
- // 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 same as hits
- // AliRunLoader * runloaderout = AliRunLoader::GetRunLoader(fManager->GetOutputFolderName());
- //AliLoader * gimeout = runloaderout->GetLoader("MUONLoader");
- // New branch per chamber for MUON digit in the tree of digits
- if (gime->TreeD() == 0x0) {
- gime->MakeDigitsContainer();
- }
- TTree* treeD = gime->TreeD();
- muondata->MakeBranch("D");
- muondata->SetTreeAddress("D");
-
- // Array of pointer of the AliMUONHitMapA1:
- // two HitMaps per chamber, or one HitMap per cahtode plane
- fHitMap= new AliMUONHitMapA1* [2*AliMUONConstants::NCh()];
-
- //Loop over chambers for the definition AliMUONHitMap
- for (Int_t i=0; i<AliMUONConstants::NCh(); i++) {
- chamber = &(pMUON->Chamber(i));
- c1Segmentation = chamber->SegmentationModel(1); // Cathode plane 1
- fHitMap[i] = new AliMUONHitMapA1(c1Segmentation, fTDList);
- c2Segmentation = chamber->SegmentationModel(2); // Cathode plane 2
- fHitMap[i+AliMUONConstants::NCh()] = new AliMUONHitMapA1(c2Segmentation, fTDList);
- }
-
-// Loop over files to merge and to digitize
- fSignal = kTRUE;
- for (Int_t inputFile=0; inputFile<fManager->GetNinputs(); inputFile++) {
- if (GetDebug()>2) cerr<<"AliMUONDigitizerv1::Digitize() Input File is "<<inputFile<<endl;
-
-
- // Connect MUON Hit branch
- if (inputFile > 0 ) {
- fSignal = kFALSE;
- runloader = AliRunLoader::GetRunLoader(fManager->GetInputFolderName(inputFile));
- if (runloader == 0x0) {
- cerr<<"AliMUONDigitizerv1::Digitize() RunLoader for inputFile "<<inputFile<< " not found !!! "<<endl;
- }
- gime = runloader->GetLoader("MUONLoader");
- if (gime->TreeH() == 0x0) gime->LoadHits("READ");
- muondata->SetLoader(gime);
- muondata->SetTreeAddress("H");
- }
-
- // Setting the address
- TTree *treeH = gime->TreeH();
- if (treeH == 0x0) {
- Error("Digitize","Can not get TreeH from input %d",inputFile);
- Info("Digitize","Now treeH is %#x. MUONLoader is %#x",gime->TreeH(),gime);
- return;
- }
- if (GetDebug()>2) {
- cerr<<"AliMUONDigitizerv1::Exec inputFile is "<<inputFile<<" "<<endl;
- cerr<<"AliMUONDigitizerv1::Exec treeH" << treeH <<endl;
- }
-
- if (GetDebug()>2) cerr<<"AliMUONDigitizerv1::Exec Setting tree addresses"<<endl;
-
- fMask = fManager->GetMask(inputFile);
- //
- // Loop over tracks
- Int_t itrack;
- Int_t ntracks = (Int_t) treeH->GetEntries();
- for (itrack = 0; itrack < ntracks; itrack++) {
- if (GetDebug()>2) cerr<<"AliMUONDigitizerv1::Exec itrack = "<<itrack<<endl;
- muondata->ResetHits();
- treeH->GetEvent(itrack);
- //
- // Loop over hits
- Int_t ihit, ichamber;
- AliMUONHit* mHit;
- TClonesArray* hits = muondata->Hits();
- for(ihit = 0; ihit < hits->GetEntriesFast(); ihit++) {
- mHit = static_cast<AliMUONHit*>(hits->At(ihit));
- ichamber = mHit->Chamber()-1; // chamber number
- if (ichamber > AliMUONConstants::NCh()-1) {
- cerr<<"AliMUONDigitizer: ERROR: "
- <<"fNch > AliMUONConstants::NCh()-1, fNch, NCh(): "
- <<ichamber<<", "<< AliMUONConstants::NCh()<<endl;
- return;
- }
- chamber = &(pMUON->Chamber(ichamber));
- //
- //Dumping Hit content:
- if (GetDebug()>2) {
- cerr<<"AliMuonDigitizerv1::Exec ihit, ichamber, x, y, z, eloss " <<
- ihit << " " <<
- mHit->Chamber() << " " <<
- mHit->X() << " " <<
- mHit->Y() << " " <<
- mHit->Z() << " " <<
- mHit->Eloss() << " " << endl;
- }
- //
- // Inititializing Correlation
- chamber->ChargeCorrelationInit();
- if (ichamber < AliMUONConstants::NTrackingCh()) {
- // Tracking Chamber
- // Initialize hit position (cursor) in the segmentation model
- chamber->SigGenInit(mHit->X(), mHit->Y(), mHit->Z());
- } else {
- // Trigger Chamber
- }
- MakeTransientDigit(itrack, ihit, mHit);
- } // hit loop
- } // track loop
- } // end file loop
- if (GetDebug()>2) cerr<<"AliMUONDigitizer::Exec End of hits, track and file loops"<<endl;
-
- runloader = AliRunLoader::GetRunLoader(fManager->GetOutputFolderName());
- gime = runloader->GetLoader("MUONLoader");
- muondata->SetLoader(gime);
-
- // Loop on cathodes
- Int_t icat;
- for(icat=0; icat<2; icat++) {
- //
- // Filling Digit List
- Int_t tracks[kMAXTRACKS];
- Int_t charges[kMAXTRACKS];
- Int_t nentries = fTDList->GetEntriesFast();
- Int_t digits[6];
- 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();
- chamber = &(pMUON->Chamber(ich));
- //
- // Digit Response (noise, threshold, saturation, ...)
- AliMUONResponse * response = chamber->ResponseModel();
- q = response->DigitResponse(q,address);
-
- if (!q) continue;
-
- digits[0] = address->PadX();
- digits[1] = address->PadY();
- digits[2] = address->Cathode()-1;
- digits[3] = q;
- digits[4] = address->Physics();
- digits[5] = address->Hit();
-
- Int_t nptracks = address->GetNTracks();
-
- if (nptracks > kMAXTRACKS) {
- if (GetDebug() >0) {
- cerr<<"AliMUONDigitizer:Exec nptracks > 10 "<<nptracks;
- cerr<<"reset to max value "<<kMAXTRACKS<<endl;
- }
- nptracks = kMAXTRACKS;
- }
- if (nptracks > 2 && GetDebug() >2) {
- cerr<<"AliMUONDigitizer::Exec nptracks > 2 "<<nptracks<<endl;
- // printf("cat,ich,ix,iy,q %d %d %d %d %d \n",icat,ich,digits[0],digits[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] = -1;
- charges[i] = 0;
- }
- }
-
- // Add digits
- if (GetDebug()>3) cerr<<"AliMUONDigitzerv1::Exex TransientDigit to Digit"<<endl;
- if ( digits[2] == icat ) muondata->AddDigit(ich,tracks,charges,digits);
-// printf("test rm ich %d padX %d padY %d \n",ich, digits[0], digits[1]);
- }
- // Filling list of digits per chamber for a given cathode.
- muondata->Fill("D");
- muondata->ResetDigits();
- } // end loop cathode
- fTDList->Delete();
-
- for(Int_t ii = 0; ii < 2*AliMUONConstants::NCh(); ++ii) {
- if (fHitMap[ii]) {
- delete fHitMap[ii];
- fHitMap[ii] = 0;
- }
- }
-
- if (GetDebug()>2)
- cerr<<"AliMUONDigitizer::Exec: writing the TreeD: "
- <<treeD->GetName()<<endl;
-
- runloader = AliRunLoader::GetRunLoader(fManager->GetOutputFolderName());
- gime = runloader->GetLoader("MUONLoader");
- gime->WriteDigits("OVERWRITE");
- delete [] fHitMap;
- delete fTDList;
- muondata->ResetHits();
- gime->UnloadHits();
- gime->UnloadDigits();
-}
+// Derived to initialise the input to read from TreeH the hits tree.
+// If the hits are not loaded then we load the hits using the muon loader.
+
+ if (GetDebug() > 2)
+ Info("InitInputData", "Loading hits in READ mode and setting the tree address.");
+
+ muondata->SetLoader(muonloader);
+
+ if (muonloader->TreeH() == NULL)
+ {
+ muonloader->LoadHits("READ");
+ if (muonloader->TreeH() == NULL)
+ {
+ Error("InitInputData", "Can not load the hits tree.");
+ return kFALSE;
+ };
+ };
+
+ muondata->SetTreeAddress("H");
+ return kTRUE;
+};
+
//------------------------------------------------------------------------
-void AliMUONDigitizerv1::SortTracks(Int_t *tracks,Int_t *charges,Int_t ntr)
+void AliMUONDigitizerv1::CleanupInputData(AliMUONLoader* muonloader)
{
- //
- // 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;
-
- 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];
- }
- }
-}
+// Derived to release the loaded hits and unload them.
+
+ if (GetDebug() > 2) Info("CleanupInputData", "Releasing loaded hits.");
+ muondata->ResetHits();
+ muonloader->UnloadHits();
+};
+
//
// Gines MARTINEZ Subatech Feb 2003
-#include "AliDigitizer.h"
-class AliRunDigitizer;
-class AliMUONPadHit;
-class AliMUONHitMapA1;
-
-class AliMUONDigitizerv1 : public AliDigitizer {
-
- public:
- AliMUONDigitizerv1();
- AliMUONDigitizerv1(AliRunDigitizer * manager);
- virtual ~AliMUONDigitizerv1();
-
- // Create a new TransientDigit
- virtual void AddTransientDigit(AliMUONTransientDigit * mTD);
- // Do the main work
- virtual void Exec(Option_t* option=0);
- // Verifying a TransientDigit
- virtual Bool_t ExistTransientDigit(AliMUONTransientDigit * mTD);
- // Getting debug level
- Int_t GetDebug() const {return fDebug;} // get debug level
- // Initialize merging and digitization
- virtual Bool_t Init();
- // Generation of a TransientDigit : Response function of the chamber
- virtual void MakeTransientDigit(Int_t itrack, Int_t ihit, AliMUONHit * mHit);
- // Setting debug level
- void SetDebug(Int_t level){fDebug = level;} // set debug level
- enum {kBgTag = -1};
- // Updating a TransientDigit
- virtual void UpdateTransientDigit(Int_t itrack, AliMUONTransientDigit * mTD);
+#include "AliMUONDigitizer.h"
+
+class AliMUONDigitizerv1 : public AliMUONDigitizer
+{
+public:
+ AliMUONDigitizerv1();
+
+ // Preferred constructor which assigns the manager object.
+ AliMUONDigitizerv1(AliRunDigitizer * manager);
- private:
- void SortTracks(Int_t *tracks,Int_t *charges,Int_t ntr);
-
- private:
- AliMUONHitMapA1 **fHitMap; //! pointer to array of pointers to hitmaps
- TObjArray *fTDList; //! list of AliMUONTransientDigits
- Int_t fTDCounter; //! nr. of AliMUONTransientDigits
- Int_t fDebug; //! debug level
- Int_t fMask; //! mask dependent on input file
- Bool_t fSignal; //! kTRUE if signal file is processed
-
-
- ClassDef(AliMUONDigitizerv1,1)
+protected:
+ // Generation of a TransientDigits from a hit object.
+ void MakeTransientDigitsFromHit(Int_t itrack, Int_t ihit, AliMUONHit * mHit);
+
+ // The following methods are all derived from AliMUONDigitizer
+ virtual void GenerateTransientDigits();
+ virtual void AddDigit(Int_t chamber, Int_t tracks[kMAXTRACKS], Int_t charges[kMAXTRACKS], Int_t digits[6]);
+ virtual Int_t GetSignalFrom(AliMUONTransientDigit* td);
+ virtual Bool_t InitOutputData(AliMUONLoader* muonloader);
+ virtual void FillOutputData();
+ virtual void CleanupOutputData(AliMUONLoader* muonloader);
+ virtual Bool_t InitInputData(AliMUONLoader* muonloader);
+ virtual void CleanupInputData(AliMUONLoader* muonloader);
+
+ ClassDef(AliMUONDigitizerv1, 1)
};
#endif
#include "AliRunLoader.h"
#include "AliLoader.h"
+/////////////////////////////////////////////////////////////////////////////////
+//
+// AliMUONDigitizerv2 digitizes digits from s-digits.
+// Merging is allowed from multiple input streams. The first input stream is
+// assumed to be the signal and all other input streams as assumed to be
+// background.
+// Chamber response is applied to the digits identically to AliMUONDigitizerv1.
+//
+/////////////////////////////////////////////////////////////////////////////////
+
ClassImp(AliMUONDigitizerv2)
//___________________________________________
-AliMUONDigitizerv2::AliMUONDigitizerv2() :
- AliDigitizer(),
- fHitMap(0),
- fTDList(0),
- fTDCounter(0),
- fDebug(0),
- fMask(0),
- fSignal(0)
+AliMUONDigitizerv2::AliMUONDigitizerv2() : AliMUONDigitizerv1()
{
-// Default ctor - don't use it
- if (GetDebug()>2)
- cerr<<"AliMUONDigitizerv2::AliMUONDigitizerv2"
- <<"(AliRunDigitizer* manager) was processed"<<endl;
+ // Default ctor - don't use it
}
//___________________________________________
-AliMUONDigitizerv2::AliMUONDigitizerv2(AliRunDigitizer* manager):
- AliDigitizer(manager),
- fHitMap(0),
- fTDList(0),
- fTDCounter(0),
- fDebug(0),
- fMask(0),
- fSignal(0)
+AliMUONDigitizerv2::AliMUONDigitizerv2(AliRunDigitizer* manager) : AliMUONDigitizerv1(manager)
{
-// ctor which should be used
- if (GetDebug()>2)
- cerr<<"AliMUONDigitizerv2::AliMUONDigitizerv2"
- <<"(AliRunDigitizer* manager) was processed"<<endl;
+ // ctor which should be used
}
-//------------------------------------------------------------------------
-AliMUONDigitizerv2::~AliMUONDigitizerv2()
+//-----------------------------------------------------------------------
+void AliMUONDigitizerv2::GenerateTransientDigits()
{
-// Destructor
-}
+// Loop over all chambers and s-digits in the input stream and create
+// AliMUONTransientDigit objects from them. These are then added to fTDList.
-//------------------------------------------------------------------------
-void AliMUONDigitizerv2::AddTransientDigit(AliMUONTransientDigit * mTD)
-{
- // Choosing the maping of the cathode plane of the chamber:
- Int_t iNchCpl= mTD->Chamber() + (mTD->Cathode()-1) * AliMUONConstants::NCh();
- fTDList->AddAtAndExpand(mTD, fTDCounter);
- fHitMap[iNchCpl]->SetHit( mTD->PadX(), mTD->PadY(), fTDCounter);
- fTDCounter++;
-}
+ if (GetDebug() > 1)
+ Info("GenerateTransientDigits", "Generating transient digits using treeH = 0x%X");
-//------------------------------------------------------------------------
-Bool_t AliMUONDigitizerv2::ExistTransientDigit(AliMUONTransientDigit * mTD)
-{
- // Choosing the maping of the cathode plane of the chamber:
- Int_t iNchCpl= mTD->Chamber() + (mTD->Cathode()-1) * AliMUONConstants::NCh();
- return( fHitMap[iNchCpl]->TestHit(mTD->PadX(), mTD->PadY()) );
-}
+ //
+ // Loop over SDigits
+ Int_t ndig, k;
+ AliMUONDigit* sDigit;
+ TClonesArray* muonSDigits;
+ for (Int_t ich = 0; ich < AliMUONConstants::NCh(); ich++) // loop over chamber
+ {
+ muondata->ResetSDigits();
+ muondata->GetCathodeS(0);
+ muonSDigits = muondata->SDigits(ich);
+ ndig = muonSDigits->GetEntriesFast();
+ for (k = 0; k < ndig; k++)
+ {
+ sDigit = (AliMUONDigit*) muonSDigits->UncheckedAt(k);
+ MakeTransientDigitFromSDigit(ich,sDigit);
+ }
+ muondata->ResetSDigits();
+ muondata->GetCathodeS(1);
+ muonSDigits = muondata->SDigits(ich);
+ ndig=muonSDigits->GetEntriesFast();
+ for (k = 0; k < ndig; k++)
+ {
+ sDigit = (AliMUONDigit*) muonSDigits->UncheckedAt(k);
+ MakeTransientDigitFromSDigit(ich,sDigit);
+ };
+ } // SDigits loop, end loop over chamber
+};
//------------------------------------------------------------------------
-Bool_t AliMUONDigitizerv2::Init()
+void AliMUONDigitizerv2::MakeTransientDigitFromSDigit(Int_t iChamber, AliMUONDigit* sDigit)
{
+// Makes a transient digit from the specified s-digit from the specified chamber.
+// Once the digit is created it is added to the fTDList.
-// Initialization
- if (GetDebug()>2) Info("Init","AliMUONDigitizerv2::Init() starts");
-
- //Loaders (We assume input0 to be the output too)
- AliRunLoader * runloader; // Input loader
- AliLoader * gime;
-
- // Getting runloader
- runloader = AliRunLoader::GetRunLoader(fManager->GetInputFolderName(0));
- if (runloader == 0x0) {
- Error("Init","RunLoader is not in input file 0");
- return kFALSE; // RunDigitizer is not working.
- }
- // Getting MUONloader
- gime = runloader->GetLoader("MUONLoader");
- gime->LoadSDigits("READ");
- gime->LoadDigits("RECREATE");
-
- return kTRUE;
-}
+ if (GetDebug() > 3)
+ Info("MakeTransientDigitFromSDigit",
+ "Making transient digit from s-digit for chamber %d.", iChamber);
+
+ Int_t digits[6];
+ //
+ // Creating a new TransientDigits from SDigit
+ digits[0] = sDigit->PadX(); // Padx of the Digit
+ digits[1] = sDigit->PadY(); // Pady of the Digit
+ digits[2] = sDigit->Cathode()+1; // Cathode plane
+ digits[3] = sDigit->Signal(); // Induced charge in the Pad
+ if (fSignal)
+ digits[4] = sDigit->Signal();
+ else
+ digits[4] = 0;
+
+ digits[5] = sDigit->Hit(); // Hit number in the list
+
+ if (GetDebug() > 4)
+ Info("MakeTransientDigitFromSDigit",
+ "Made digit from sDigit 0x%X: PadX %d\tPadY %d\tPlane %d\tCharge %d\tHit %d",
+ (void*)sDigit, digits[0], digits[1], digits[2], digits[3], digits[5]);
+
+ AliMUONTransientDigit* mTD = new AliMUONTransientDigit(iChamber, digits);
+ // Copy list of tracks and trackcharge
+ for(Int_t itrack = 0; itrack < kMAXTRACKS; itrack++)
+ {
+ Int_t track = sDigit->Track(itrack);
+ if (track < 0) break; // Check if we reached the end of the track list.
+ mTD->AddToTrackList( track + fMask, sDigit->TrackCharge(itrack) );
+ };
+
+ OnCreateTransientDigit(mTD, sDigit);
+ AddOrUpdateTransientDigit(mTD);
+};
//------------------------------------------------------------------------
-void AliMUONDigitizerv2::UpdateTransientDigit(Int_t /*track*/, AliMUONTransientDigit * mTD)
-{
- // Choosing the maping of the cathode plane of the chamber:
- Int_t iNchCpl= mTD->Chamber() + (mTD->Cathode()-1) * AliMUONConstants::NCh();
- AliMUONTransientDigit *pdigit =
- static_cast<AliMUONTransientDigit*>(fHitMap[iNchCpl]->GetHit(mTD->PadX(),mTD->PadY()));
- // update charge
- //
- Int_t iqpad = mTD->Signal(); // charge per pad
- pdigit->AddSignal(iqpad);
- pdigit->AddPhysicsSignal(iqpad);
- // update list of tracks
- //
- // List of tracks and trackcharge
- Int_t itrack;
- for(itrack=0;itrack<kMAXTRACKS;itrack++) {
- pdigit->UpdateTrackList(mTD->Track(itrack), mTD->TrackCharge(itrack));
- }
-}
-
-//--------------------------------------------------------------------------
-void AliMUONDigitizerv2::MakeTransientDigitFromSDigit(Int_t iChamber, AliMUONDigit * sDigit)
+void AliMUONDigitizerv2::AddDigit(Int_t chamber, Int_t tracks[kMAXTRACKS], Int_t charges[kMAXTRACKS], Int_t digits[6])
{
- Int_t digits[6];
-
-
- //
- // Creating a new TransientDigits from SDigit
- digits[0] = sDigit->PadX(); // Padx of the Digit
- digits[1] = sDigit->PadY(); // Pady of the Digit
- digits[2] = sDigit->Cathode()+1; // Cathode plane
- digits[3] = sDigit->Signal(); // Induced charge in the Pad
- if (fSignal) digits[4] = sDigit->Signal();
- else digits[4] = 0;
- digits[5] = sDigit->Hit(); // Hit number in the list
- if (GetDebug()>2) cerr<<"AliMUONDigitizerv2::MakeTransientDigitFromSDigit " <<
- "PadX "<< digits[0] << " " <<
- "PadY "<< digits[1] << " " <<
- "Plane " << digits[2] << " " <<
- "Charge " << digits[3] <<" " <<
- "Hit " << digits[5] << endl;
-
- if (GetDebug()>2) cerr<<"AliMUONDigitizerv2::MakeTransientDigitFromSDigit Creating AliMUONTransientDigit"<<endl;
- AliMUONTransientDigit * mTD = new AliMUONTransientDigit(iChamber, digits);
-
- // List of tracks and trackcharge
- Int_t itrack;
- for(itrack=0;itrack<kMAXTRACKS;itrack++) {
- mTD->AddToTrackList(fMask+sDigit->Track(itrack), sDigit->TrackCharge(itrack));
- }
+// Override to add new digits to the digits tree TreeD.
+ muondata->AddDigit(chamber, tracks, charges, digits);
+};
- if (!ExistTransientDigit(mTD)) {
- AddTransientDigit(mTD);
- if (GetDebug()>2) cerr<<"AliMUONDigitizerv2::MakeTransientDigitFromSDigit Adding TransientDigit"<<endl;
- }
- else {
- if (GetDebug()>2) cerr<<"AliMUONDigitizerv2::MakeTransientDigitFromSDigit updating TransientDigit"<<endl;
- UpdateTransientDigit(0, mTD);
- delete mTD;
- }
-}
-
-//-----------------------------------------------------------------------
-void AliMUONDigitizerv2::Exec(Option_t* option)
+//------------------------------------------------------------------------
+Bool_t AliMUONDigitizerv2::InitInputData(AliMUONLoader* muonloader)
{
- TString optionString = option;
- if (optionString.Data() == "deb") {
- Info("Digitize","Called with option deb ");
- fDebug = 3;
- }
-
- AliRun *aliRun;
- AliMUONChamber* chamber;
- AliSegmentation* c1Segmentation; //Cathode plane c1 of the chamber
- AliSegmentation* c2Segmentation; //Cathode place c2 of the chamber
-
- if (GetDebug()>2) Info("Exec","AliMUONDigitizerv2::Exec() starts");
- fTDList = new TObjArray;
-
- //Loaders (We assume input0 to be the output too)
- AliRunLoader *runloader, *runloaderOut; // Input / Output loaders
- AliLoader *gime, *gimeOut;
-
- // Getting runloader
- runloader = AliRunLoader::GetRunLoader(fManager->GetInputFolderName(0));
- if (runloader == 0x0) {
- Error("Exec","RunLoader is not in input file 0");
- return; // RunDigitizer is not working.
- }
- // Getting MUONloader
- gime = runloader->GetLoader("MUONLoader");
- if (gime->TreeS()==0x0) {
- if (GetDebug()>2) Info("Exec","TreeS is not loaded yet. Loading...");
- gime->LoadSDigits("READ");
- if (GetDebug()>2) Info("Exec","Now treeS is %#x. MUONLoader is %#x",gime->TreeS(),gime);
- }
-
- if (GetDebug()>2) Info("Exec","Loaders ready");
-
- if (runloader->GetAliRun() == 0x0) runloader->LoadgAlice();
- aliRun = runloader->GetAliRun();
+// Overridden to initialize muondata to read from the s-digits tree TreeS.
+// If the s-digits are not loaded then the muon loader is used to load the
+// s-digits into memory.
- // Getting Module MUON
- AliMUON *pMUON = (AliMUON *) aliRun->GetDetector("MUON");
- if (!pMUON) {
- Error("Digitize","Module MUON not found in the input file");
- return;
- }
- // Getting Muon data
- AliMUONData * muondata = pMUON->GetMUONData();
+ if (GetDebug() > 2)
+ Info("InitInputData", "Loading s-digits in READ mode and setting the tree address.");
- // Loading Event
- Int_t currentevent = fManager->GetOutputEventNr();
-
- if (GetDebug()>2) cerr<<"AliMUONDigitizerv2::Exec() Event Number is "<<currentevent <<endl;
- if ( (currentevent<10) ||
- (Int_t(TMath::Log10(currentevent)) == TMath::Log10(currentevent) ) )
- cout <<"ALiMUONDigitizerv2::Exec() Event Number is "<< currentevent <<endl;
+ muondata->SetLoader(muonloader);
- // Output runloader
- runloaderOut = AliRunLoader::GetRunLoader(fManager->GetOutputFolderName());
- gimeOut = runloaderOut->GetLoader("MUONLoader");
-
+ if (muonloader->TreeS() == NULL)
+ {
+ muonloader->LoadSDigits("READ");
+ if (muonloader->TreeS() == NULL)
+ {
+ Error("InitInputData", "Can not load the s-digits tree.");
+ return kFALSE;
+ };
+ };
- if (gimeOut->TreeD() == 0x0) {
- gimeOut->MakeDigitsContainer();
- }
- TTree* treeD = gimeOut->TreeD();
- muondata->SetLoader(gimeOut);
- muondata->MakeBranch("D");
- muondata->SetTreeAddress("D");
-
- // Array of pointer of the AliMUONHitMapA1:
- // two HitMaps per chamber, or one HitMap per cahtode plane
- fHitMap= new AliMUONHitMapA1* [2*AliMUONConstants::NCh()];
-
- //Loop over chambers for the definition AliMUONHitMap
- for (Int_t i=0; i<AliMUONConstants::NCh(); i++) {
- chamber = &(pMUON->Chamber(i));
- c1Segmentation = chamber->SegmentationModel(1); // Cathode plane 1
- fHitMap[i] = new AliMUONHitMapA1(c1Segmentation, fTDList);
- c2Segmentation = chamber->SegmentationModel(2); // Cathode plane 2
- fHitMap[i+AliMUONConstants::NCh()] = new AliMUONHitMapA1(c2Segmentation, fTDList);
- }
-
-// Loop over files to merge and to digitize
- fSignal = kTRUE;
- for (Int_t inputFile=0; inputFile<fManager->GetNinputs(); inputFile++) {
- if (GetDebug()>2) cerr<<"AliMUONDigitizerv2::Exec() Input File is "<<inputFile<<endl;
- if (inputFile == 0) {
- muondata->SetLoader(gime);
- muondata->SetTreeAddress("S");
- } else {
- // Connect MUON Hit branch
- fSignal = kFALSE;
- runloader = AliRunLoader::GetRunLoader(fManager->GetInputFolderName(inputFile));
- if (runloader == 0x0) {
- cerr<<"AliMUONDigitizerv2::Digitize() RunLoader for inputFile "<<inputFile<< " not found !!! "<<endl;
- }
- gime = runloader->GetLoader("MUONLoader");
- if (gime->TreeS() == 0x0) gime->LoadSDigits("READ");
- muondata->SetLoader(gime);
muondata->SetTreeAddress("S");
- }
-
- // Setting the address
- TTree *treeS = gime->TreeS();
- if (treeS == 0x0) {
- Error("Digitize","Can not get TreeS from input %d",inputFile);
- Info("Digitize","Now treeS is %#x. MUONLoader is %#x",gime->TreeS(),gime);
- return;
- }
- if (GetDebug()>2) {
- cerr<<"AliMUONDigitizerv2::Exec inputFile is "<<inputFile<<" "<<endl;
- cerr<<"AliMUONDigitizerv2::Exec treeS" << treeS <<endl;
- }
-
- if (GetDebug()>2) cerr<<"AliMUONDigitizerv2::Exec Setting tree addresses"<<endl;
-
- fMask = fManager->GetMask(inputFile);
- //
- // Loop over SDigits
- Int_t ndig,k;
- AliMUONDigit *sDigit;
- TClonesArray * muonSDigits;
- for (Int_t ich = 0; ich < AliMUONConstants::NCh(); ich++) { // loop over chamber
- muondata->ResetSDigits();
- muondata->GetCathodeS(0);
- //TClonesArray *
- muonSDigits = muondata->SDigits(ich);
- ndig = muonSDigits->GetEntriesFast();
- // printf("\n 1 Found %d Sdigits in %p chamber %d", ndig, muonSDigits,ich);
- Int_t n = 0;
- for (k = 0; k < ndig; k++) {
- sDigit = (AliMUONDigit*) muonSDigits->UncheckedAt(k);
- MakeTransientDigitFromSDigit(ich,sDigit);
- }
- muondata->ResetSDigits();
- muondata->GetCathodeS(1);
- //TClonesArray *
- muonSDigits = muondata->SDigits(ich);
- ndig=muonSDigits->GetEntriesFast();
- // printf("\n 2 Found %d Sdigits in %p chamber %d", ndig, muonSDigits,ich);
- n = 0;
- for (k = 0; k < ndig; k++) {
- sDigit = (AliMUONDigit*) muonSDigits->UncheckedAt(k);
- MakeTransientDigitFromSDigit(ich,sDigit);
- }
-
- } // SDigits loop end loop over chamber
- } // end file loop
- if (GetDebug()>2) cerr<<"AliMUONDigitizerv2::Exec End of Sdigits, file loops"<<endl;
-
- // Loop on cathodes
- Int_t icat;
- for(icat=0; icat<2; icat++) {
- //
- // Filling Digit List
- Int_t tracks[kMAXTRACKS];
- Int_t charges[kMAXTRACKS];
- Int_t nentries = fTDList->GetEntriesFast();
- Int_t digits[6];
- 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();
- chamber = &(pMUON->Chamber(ich));
- //
- // Digit Response (noise, threshold, saturation, ...)
- AliMUONResponse * response = chamber->ResponseModel();
- q = response->DigitResponse(q,address);
-
- if (!q) continue;
-
- digits[0] = address->PadX();
- digits[1] = address->PadY();
- digits[2] = address->Cathode()-1;
- digits[3] = q;
- digits[4] = address->Physics();
- digits[5] = address->Hit();
-
- Int_t nptracks = address->GetNTracks();
-
- if (nptracks > kMAXTRACKS) {
- if (GetDebug() >0) {
- cerr<<"AliMUONDigitizer:Exec nptracks > 10 "<<nptracks;
- cerr<<"reset to max value "<<kMAXTRACKS<<endl;
- }
- nptracks = kMAXTRACKS;
- }
- if (nptracks > 2 && GetDebug() >2) {
- cerr<<"AliMUONDigitizer::Exec nptracks > 2 "<<nptracks<<endl;
- // printf("cat,ich,ix,iy,q %d %d %d %d %d \n",icat,ich,digits[0],digits[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] = -1;
- charges[i] = 0;
- }
- }
-
- // Add digits
- if (GetDebug()>3) cerr<<"AliMUONDigitzerv2::Exec TransientDigit to Digit"<<endl;
- if ( digits[2] == icat ) muondata->AddDigit(ich,tracks,charges,digits);
-// printf("test rm ich %d padX %d padY %d \n",ich, digits[0], digits[1]);
- }
- muondata->SetLoader(gimeOut);
- muondata->Fill("D");
- muondata->ResetDigits();
- } // end loop cathode
- fTDList->Delete();
-
- for(Int_t ii = 0; ii < 2*AliMUONConstants::NCh(); ++ii) {
- if (fHitMap[ii]) {
- delete fHitMap[ii];
- fHitMap[ii] = 0;
- }
- }
-
- if (GetDebug()>2)
- cerr<<"AliMUONDigitizer::Exec: writing the TreeD: "
- <<treeD->GetName()<<endl;
-
- gimeOut->WriteDigits("OVERWRITE");
- delete [] fHitMap;
- delete fTDList;
- muondata->ResetSDigits();
- gime->UnloadSDigits();
- gimeOut->UnloadDigits();
-}
+ return kTRUE;
+};
+
//------------------------------------------------------------------------
-void AliMUONDigitizerv2::SortTracks(Int_t *tracks,Int_t *charges,Int_t ntr)
+void AliMUONDigitizerv2::CleanupInputData(AliMUONLoader* muonloader)
{
- //
- // 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;
-
- 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];
- }
- }
-}
+// Overridden to release and unload s-digits from memory.
+
+ if (GetDebug() > 2) Info("CleanupInputData", "Releasing loaded s-digits.");
+ muondata->ResetSDigits();
+ muonloader->UnloadSDigits();
+};
/* Copyright(c) 1998-2001, ALICE Experiment at CERN, All rights reserved. *
* See cxx source for full Copyright notice */
-#include "AliDigitizer.h"
-class AliRunDigitizer;
-class AliMUONPadHit;
-class AliMUONHitMapA1;
+#include "AliMUONDigitizerv1.h"
-class AliMUONDigitizerv2 : public AliDigitizer {
+class AliMUONDigitizerv2 : public AliMUONDigitizerv1
+{
+public:
+ AliMUONDigitizerv2();
+
+ // Preferred constructor which assigns the manager object.
+ AliMUONDigitizerv2(AliRunDigitizer * manager);
- public:
- AliMUONDigitizerv2();
- AliMUONDigitizerv2(AliRunDigitizer * manager);
- virtual ~AliMUONDigitizerv2();
+ // Makes a transient digit from the specified s-digit from the specified chamber.
+ void MakeTransientDigitFromSDigit(Int_t iChamber, AliMUONDigit* sDigit);
- // Create a new TransientDigit
- virtual void AddTransientDigit(AliMUONTransientDigit * mTD);
- // Do the main work
- virtual void Exec(Option_t* option=0);
- // Verifying a TransientDigit
- virtual Bool_t ExistTransientDigit(AliMUONTransientDigit * mTD);
- // Getting debug level
- Int_t GetDebug() const {return fDebug;} // get debug level
- // Initialize merging and digitization
- virtual Bool_t Init();
- // Generation of a TransientDigit from SDigit
- virtual void MakeTransientDigitFromSDigit(Int_t iChamber, AliMUONDigit * sDigit);
- // Setting debug level
- void SetDebug(Int_t level){fDebug = level;} // set debug level
- enum {kBgTag = -1};
- // Updating a TransientDigit
- virtual void UpdateTransientDigit(Int_t /*itrack*/, AliMUONTransientDigit * mTD);
-
- private:
- void SortTracks(Int_t *tracks,Int_t *charges,Int_t ntr);
-
- private:
- AliMUONHitMapA1 **fHitMap; //! pointer to array of pointers to hitmaps
- TObjArray *fTDList; //! list of AliMUONTransientDigits
- Int_t fTDCounter; //! nr. of AliMUONTransientDigits
- Int_t fDebug; //! debug level
- Int_t fMask; //! mask dependent on input file
- Bool_t fSignal; //! kTRUE if signal file is processed
+ // The following methods are inherited from AliMUONDigitizerv1 and overridden.
+ virtual void GenerateTransientDigits();
+ virtual void AddDigit(Int_t chamber, Int_t tracks[kMAXTRACKS], Int_t charges[kMAXTRACKS], Int_t digits[6]);
+ virtual Bool_t InitInputData(AliMUONLoader* muonloader);
+ virtual void CleanupInputData(AliMUONLoader* muonloader);
-
- ClassDef(AliMUONDigitizerv2,0)
+ ClassDef(AliMUONDigitizerv2, 0)
};
#endif
-
#include <Riostream.h>
#include <TDirectory.h>
#include <TFile.h>
#include <TTree.h>
#include <TMath.h>
+#include "AliRun.h"
+#include "AliRunLoader.h"
+#include "AliLoader.h"
+
#include "AliMUON.h"
#include "AliMUONChamber.h"
#include "AliMUONConstants.h"
#include "AliMUONHitMapA1.h"
#include "AliMUONPadHit.h"
#include "AliMUONTransientDigit.h"
-#include "AliRun.h"
-#include "AliRunLoader.h"
-#include "AliLoader.h"
+
+/////////////////////////////////////////////////////////////////////////////////
+//
+// AliMUONSDigitizerv1 digitizes hits from the input stream into s-digits.
+// The s-digits are written to the s-digit tree TreeS.
+// The same algorithm is implemented as for AliMUONDigitizerv1 however the
+// chamber response is not applied to the s-digits and we write to TreeS and
+// not TreeD.
+//
+/////////////////////////////////////////////////////////////////////////////////
ClassImp(AliMUONSDigitizerv1)
//___________________________________________
-AliMUONSDigitizerv1::AliMUONSDigitizerv1() :
- fHitMap(0),
- fTDList(0),
- fTDCounter(0),
- fDebug(0),
- fMask(0),
- fSignal(0)
+AliMUONSDigitizerv1::AliMUONSDigitizerv1() : AliMUONDigitizerv1()
{
-// Default ctor - don't use it
- if (GetDebug()>2)
- cerr<<"AliMUONSDigitizerv1::AliMUONSDigitizerv1"
- <<"(AliRunDigitizer* manager) was processed"<<endl;
+ // Default ctor - don't use it
}
-
-//------------------------------------------------------------------------
-AliMUONSDigitizerv1::~AliMUONSDigitizerv1()
+//___________________________________________
+AliMUONSDigitizerv1::AliMUONSDigitizerv1(AliRunDigitizer* manager) : AliMUONDigitizerv1(manager)
{
-// Destructor
+ // ctor which should be used
}
//------------------------------------------------------------------------
-void AliMUONSDigitizerv1::AddTransientDigit(AliMUONTransientDigit * mTD)
+void AliMUONSDigitizerv1::AddDigit(Int_t chamber, Int_t tracks[kMAXTRACKS], Int_t charges[kMAXTRACKS], Int_t digits[6])
{
- // Choosing the maping of the cathode plane of the chamber:
- Int_t iNchCpl= mTD->Chamber() + (mTD->Cathode()-1) * AliMUONConstants::NCh();
- fTDList->AddAtAndExpand(mTD, fTDCounter);
- fHitMap[iNchCpl]->SetHit( mTD->PadX(), mTD->PadY(), fTDCounter);
- fTDCounter++;
-}
+// Derived to write to the s-digit tree TreeS.
-//------------------------------------------------------------------------
-Bool_t AliMUONSDigitizerv1::ExistTransientDigit(AliMUONTransientDigit * mTD)
-{
- // Choosing the maping of the cathode plane of the chamber:
- Int_t iNchCpl= mTD->Chamber() + (mTD->Cathode()-1) * AliMUONConstants::NCh();
- return( fHitMap[iNchCpl]->TestHit(mTD->PadX(), mTD->PadY()) );
-}
+ muondata->AddSDigit(chamber, tracks, charges, digits);
+};
//------------------------------------------------------------------------
-Bool_t AliMUONSDigitizerv1::Init()
+Int_t AliMUONSDigitizerv1::GetSignalFrom(AliMUONTransientDigit* td)
{
+// Returns the transient digit signal as is without applying the chamber response.
-// Initialization
- if (GetDebug()>2) Info("Init","AliMUONSDigitizerv1::Init() starts");
-
- //Loaders (We assume input0 to be the output too)
- AliRunLoader * runloader; // Input loader
- AliLoader * gime;
-
- // Getting runloader
- runloader = AliRunLoader::GetRunLoader();
- if (runloader == 0x0) {
- Error("Init","RunLoader is not in input file 0");
- return kFALSE; // RunDigitizer is not working.
- }
- // Getting MUONloader
- gime = runloader->GetLoader("MUONLoader");
- gime->LoadHits("READ");
- gime->LoadSDigits("RECREATE");
-
- return kTRUE;
-}
+ if (GetDebug() > 3) Info("GetSignalFrom", "Returning TransientDigit signal.");
+ return td->Signal();
+};
//------------------------------------------------------------------------
-void AliMUONSDigitizerv1::UpdateTransientDigit(Int_t track, AliMUONTransientDigit * mTD)
+Bool_t AliMUONSDigitizerv1::InitOutputData(AliMUONLoader* muonloader)
{
- // Choosing the maping of the cathode plane of the chamber:
- Int_t iNchCpl= mTD->Chamber() + (mTD->Cathode()-1) * AliMUONConstants::NCh();
- AliMUONTransientDigit *pdigit =
- static_cast<AliMUONTransientDigit*>(fHitMap[iNchCpl]->GetHit(mTD->PadX(),mTD->PadY()));
- // update charge
- //
- Int_t iqpad = mTD->Signal(); // charge per pad
- pdigit->AddSignal(iqpad);
- pdigit->AddPhysicsSignal(iqpad);
- // update list of tracks
- //
- Int_t charge;
- track=+ fMask;
- if (fSignal) charge = iqpad;
- //else charge = kBgTag;
- else charge = iqpad + fMask;
-
- pdigit->UpdateTrackList(track,charge);
-}
-
-
-//--------------------------------------------------------------------------
-void AliMUONSDigitizerv1::MakeTransientDigit(Int_t track, Int_t iHit, AliMUONHit * mHit)
-{
- AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
- if (!pMUON) {
- cerr<<"AliMUONSDigitizerv1::MakeTransientDigit Error:"
- <<" module MUON not found in the input file"<<endl;
- }
- if (GetDebug()>2) cerr<<"AliMUONSDigitizerv1::MakeTransientDigit starts"<<endl;
- Int_t ichamber = mHit->Chamber()-1;
- AliMUONChamber & chamber = pMUON->Chamber(ichamber);
- Float_t xhit = mHit->X();
- Float_t yhit = mHit->Y();
- Float_t zhit = mHit->Z();
- Float_t eloss= mHit->Eloss();
- Float_t tof = mHit->Age();
- // Variables for chamber response from AliMUONChamber::DisIntegration
- Float_t newdigit[6][500]; // Pad information
- Int_t nnew=0; // Number of touched Pads per hit
- Int_t digits[6];
-
- //
- // Calls the charge disintegration method of the current chamber
- if (GetDebug()>2) cerr<<"AliMUONSDigitizerv1::MakeTransientDigit calling AliMUONChamber::DisIngtegration starts"<<endl;
- chamber.DisIntegration(eloss, tof, xhit, yhit, zhit, nnew, newdigit);
- // Creating a new TransientDigits from hit
- for(Int_t iTD=0; iTD<nnew; iTD++) {
- digits[0] = Int_t(newdigit[1][iTD]); // Padx of the Digit
- digits[1] = Int_t(newdigit[2][iTD]); // Pady of the Digit
- digits[2] = Int_t(newdigit[5][iTD]); // Cathode plane
- digits[3] = Int_t(newdigit[3][iTD]); // Induced charge in the Pad !!!! Int_t not correct
- if (fSignal) digits[4] = Int_t(newdigit[3][iTD]);
- else digits[4] = 0;
- digits[5] = iHit+fMask; // Hit number in the list
- if (GetDebug()>2) cerr<<"AliMUONSDigitizerv1::MakeTransientDigit " <<
- cerr<<"AliMUONSDigitizerv1::MakeTransientDigit " <<
- "PadX "<< digits[0] << " " <<
- "PadY "<< digits[1] << " " <<
- "Plane " << digits[2] << " " <<
- "Charge " << digits[3] <<" " <<
- "newdigit " << newdigit[3][iTD] <<" " <<
- "Hit " << digits[5] << endl;
- // list of tracks
- Int_t charge;
- track += fMask;
- if (fSignal) charge = digits[3];
- //else charge = kBgTag;
- else charge = digits[3] + fMask;
-
- if (GetDebug()>2) cerr<<"AliMUONSDigitizerv1::MakeTransientDigit Creating AliMUONTransientDigit"<<endl;
- AliMUONTransientDigit * mTD = new AliMUONTransientDigit(ichamber, digits);
- mTD->AddToTrackList(track,charge);
- if (!ExistTransientDigit(mTD)) {
- AddTransientDigit(mTD);
- if (GetDebug()>2) cerr<<"AliMUONSDigitizerv1::MakeTransientDigit Adding TransientDigit"<<endl;
- }
- else {
- if (GetDebug()>2) cerr<<"AliMUONSDigitizerv1::MakeTransientDigit updating TransientDigit"<<endl;
- UpdateTransientDigit(track, mTD);
- delete mTD;
- }
- }
-}
-//-----------------------------------------------------------------------
-void AliMUONSDigitizerv1::Exec(Option_t* option)
-{
- TString optionString = option;
- if (optionString.Data() == "deb") {
- Info("SDigitize","Called with option deb ");
- fDebug = 3;
- }
-
- AliMUONChamber* chamber;
- AliSegmentation* c1Segmentation; //Cathode plane c1 of the chamber
- AliSegmentation* c2Segmentation; //Cathode place c2 of the chamber
-
- if (GetDebug()>2) Info("SDigitize","AliMUONSDigitizerv1::Exec starts");
- fTDList = new TObjArray;
-
- //Loaders (We assume input0 to be the output too)
- AliRunLoader * runloader; // Input loader
- AliLoader * gime;
-
- // Getting runloader
- runloader = AliRunLoader::GetRunLoader();
- if (runloader == 0x0) {
- Error("SDigitize","RunLoader is not in input file 0");
- return; // RunDigitizer is not working.
- }
- // Getting MUONloader
- gime = runloader->GetLoader("MUONLoader");
- if (gime->TreeH()==0x0) {
- if (GetDebug()>2) Info("SDigitize","TreeH is not loaded yet. Loading...");
- gime->LoadHits("READ");
- if (GetDebug()>2) Info("SDigitize","Now treeH is %#x. MUONLoader is %#x",gime->TreeH(),gime);
- }
-
- if (GetDebug()>2) Info("SDigitize","Loaders ready");
-
- if (runloader->GetAliRun() == 0x0) runloader->LoadgAlice();
- gAlice = runloader->GetAliRun();
-
- // Getting Module MUON
- AliMUON *pMUON = (AliMUON *) gAlice->GetDetector("MUON");
- if (!pMUON) {
- Error("SDigitize","Module MUON not found in the input file");
- return;
- }
- // Getting Muon data
- AliMUONData * muondata = pMUON->GetMUONData();
- muondata->SetLoader(gime);
- muondata->SetTreeAddress("H");
-
- Int_t currentevent = runloader->GetEventNumber();
-
- if (GetDebug()>2) cerr<<"AliMUONSDigitizerv1::Exec Event Number is "<<currentevent <<endl;
- if ( (currentevent<10) ||
- (Int_t(TMath::Log10(currentevent)) == TMath::Log10(currentevent) ) )
- cout <<"AliMUONSDigitizerv1::Exec Event Number is "<< currentevent <<endl;
-
- // New branch per chamber for MUON digit in the tree of digits
- if (gime->TreeS() == 0x0) {
- gime->MakeSDigitsContainer();
- }
- TTree* treeS = gime->TreeS();
- muondata->MakeBranch("S");
- muondata->SetTreeAddress("S");
-
- // Array of pointer of the AliMUONHitMapA1:
- // two HitMaps per chamber, or one HitMap per cahtode plane
- fHitMap= new AliMUONHitMapA1* [2*AliMUONConstants::NCh()];
-
- //Loop over chambers for the definition AliMUONHitMap
- for (Int_t i=0; i<AliMUONConstants::NCh(); i++) {
- chamber = &(pMUON->Chamber(i));
- c1Segmentation = chamber->SegmentationModel(1); // Cathode plane 1
- fHitMap[i] = new AliMUONHitMapA1(c1Segmentation, fTDList);
- c2Segmentation = chamber->SegmentationModel(2); // Cathode plane 2
- fHitMap[i+AliMUONConstants::NCh()] = new AliMUONHitMapA1(c2Segmentation, fTDList);
- }
-
-// Loop to Sdigitize
- fSignal = kTRUE;
-
- // Setting the address
- TTree *treeH = gime->TreeH();
- if (treeH == 0x0) {
- Error("SDigitize","Can not get TreeH from input ");
- Info("SDigitize","Now treeH is %#x. MUONLoader is %#x",gime->TreeH(),gime);
- return;
- }
- if (GetDebug()>2) {
- cerr<<"AliMUONSDigitizerv1::Exec treeH" << treeH <<endl;
- }
+// Overridden to initialise the output tree to be TreeS rather than TreeD.
+
+ if (GetDebug() > 2)
+ Info("InitOutputData", "Creating s-digits branch and setting the tree address.");
+
+ muondata->SetLoader(muonloader);
+
+ // New branch per chamber for MUON digit in the tree of digits
+ if (muonloader->TreeS() == NULL)
+ {
+ muonloader->MakeSDigitsContainer();
+ if (muonloader->TreeS() == NULL)
+ {
+ Error("InitOutputData", "Could not create TreeS.");
+ return kFALSE;
+ };
+ };
+
+ muondata->MakeBranch("S");
+ muondata->SetTreeAddress("S");
- if (GetDebug()>2) cerr<<"AliMUONSDigitizerv1::Exec Setting tree addresses"<<endl;
+ return kTRUE;
+};
- //
- // Loop over tracks
- Int_t itrack;
- Int_t ntracks = (Int_t) treeH->GetEntries();
- for (itrack = 0; itrack < ntracks; itrack++) {
- if (GetDebug()>2) cerr<<"AliMUONSDigitizerv1::Exec itrack = "<<itrack<<endl;
- muondata->ResetHits();
- treeH->GetEvent(itrack);
- //
- // Loop over hits
- Int_t ihit, ichamber;
- AliMUONHit* mHit;
- TClonesArray* hits = muondata->Hits();
- for(ihit = 0; ihit < hits->GetEntriesFast(); ihit++) {
- mHit = static_cast<AliMUONHit*>(hits->At(ihit));
- ichamber = mHit->Chamber()-1; // chamber number
- if (ichamber > AliMUONConstants::NCh()-1) {
- cerr<<"AliMUONSDigitizer: ERROR: "
- <<"fNch > AliMUONConstants::NCh()-1, fNch, NCh(): "
- <<ichamber<<", "<< AliMUONConstants::NCh()<<endl;
- return;
- }
- chamber = &(pMUON->Chamber(ichamber));
- //
- //Dumping Hit content:
- if (GetDebug()>2) {
- cerr<<"AliMuonDigitizerv1::Exec ihit, ichamber, x, y, z, eloss " <<
- ihit << " " <<
- mHit->Chamber() << " " <<
- mHit->X() << " " <<
- mHit->Y() << " " <<
- mHit->Z() << " " <<
- mHit->Eloss() << " " << endl;
- }
- //
- // Inititializing Correlation
- chamber->ChargeCorrelationInit();
- if (ichamber < AliMUONConstants::NTrackingCh()) {
- // Tracking Chamber
- // Initialize hit position (cursor) in the segmentation model
- chamber->SigGenInit(mHit->X(), mHit->Y(), mHit->Z());
- } else {
- // Trigger Chamber
- }
- MakeTransientDigit(itrack, ihit, mHit);
- } // hit loop
- } // track loop
- if (GetDebug()>2) cerr<<"AliMUONSDigitizer::Exec End of hits, track and file loops"<<endl;
+//------------------------------------------------------------------------
+void AliMUONSDigitizerv1::FillOutputData()
+{
+// Overridden to fill TreeS rather than TreeD.
- // Loop on cathodes
- Int_t icat;
- for(icat=0; icat<2; icat++) {
- //
- // Filling SDigit List
- Int_t tracks[kMAXTRACKS];
- Int_t charges[kMAXTRACKS];
- Int_t nentries = fTDList->GetEntriesFast();
- Int_t digits[6];
- 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();
-
- if (!q) continue; // not mandatory ?
-
- digits[0] = address->PadX();
- digits[1] = address->PadY();
- digits[2] = address->Cathode()-1;
- digits[3] = q;
- digits[4] = address->Physics();
- digits[5] = address->Hit();
-
- Int_t nptracks = address->GetNTracks();
-
- if (nptracks > kMAXTRACKS) {
- if (GetDebug() >0) {
- cerr<<"AliMUONSDigitizer:Exec nptracks > 10 "<<nptracks;
- cerr<<"reset to max value "<<kMAXTRACKS<<endl;
- }
- nptracks = kMAXTRACKS;
- }
- if (nptracks > 2 && GetDebug() >2) {
- cerr<<"AliMUONSDigitizer::Exec nptracks > 2 "<<nptracks<<endl;
- // printf("cat,ich,ix,iy,q %d %d %d %d %d \n",icat,ich,digits[0],digits[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] = -1;
- charges[i] = 0;
- }
- }
-
- // Add Sdigits
- if (GetDebug()>3) cerr<<"AliMUONSDigitzerv1::Exec TransientDigit to SDigit"<<endl;
- if ( digits[2] == icat ) muondata->AddSDigit(ich,tracks,charges,digits);
-// printf("test rm ich %d padX %d padY %d \n",ich, digits[0], digits[1]);
- }
- // Filling list of Sdigits per chamber for a given cathode.
- muondata->Fill("S");
- muondata->ResetSDigits();
- } // end loop cathode
- fTDList->Delete();
-
- for(Int_t ii = 0; ii < 2*AliMUONConstants::NCh(); ++ii) {
- if (fHitMap[ii]) {
- delete fHitMap[ii];
- fHitMap[ii] = 0;
- }
- }
-
- if (GetDebug()>2)
- cerr<<"AliMUONSDigitizer::Exec: writing the TreeS: "
- <<treeS->GetName()<<endl;
+ if (GetDebug() > 2) Info("FillOutputData", "Filling trees with s-digits.");
+ muondata->Fill("S");
+ muondata->ResetSDigits();
+};
- runloader = AliRunLoader::GetRunLoader();
- gime = runloader->GetLoader("MUONLoader");
- gime->WriteSDigits("OVERWRITE");
- delete [] fHitMap;
- delete fTDList;
- muondata->ResetHits();
- gime->UnloadHits();
- gime->UnloadSDigits();
-}
//------------------------------------------------------------------------
-void AliMUONSDigitizerv1::SortTracks(Int_t *tracks,Int_t *charges,Int_t ntr)
+void AliMUONSDigitizerv1::CleanupOutputData(AliMUONLoader* muonloader)
{
- //
- // Sort the list of tracks contributing to a given Sdigit
- // 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;
-
- 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];
- }
- }
-}
+// Overridden to write and then cleanup TreeS that was initialised in InitOutputData.
+
+ if (GetDebug() > 2) Info("CleanupOutputData", "Writing s-digits and releasing pointers.");
+ muonloader->WriteSDigits("OVERWRITE");
+ muondata->ResetSDigits();
+ muonloader->UnloadSDigits();
+};
// SDigits from Hits
// J.P Cussonneau Subatech Feb 2004
-class AliMUONPadHit;
-class AliMUONHitMapA1;
-
-class AliMUONSDigitizerv1 {
-
- public:
- AliMUONSDigitizerv1();
- virtual ~AliMUONSDigitizerv1();
-
- // Create a new TransientDigit
- virtual void AddTransientDigit(AliMUONTransientDigit * mTD);
- // Do the main work
- virtual void Exec(Option_t* option=0);
- // Verifying a TransientDigit
- virtual Bool_t ExistTransientDigit(AliMUONTransientDigit * mTD);
- // Getting debug level
- Int_t GetDebug() const {return fDebug;} // get debug level
- // Initialize merging and digitization
- virtual Bool_t Init();
- // Generation of a TransientDigit : Response function of the chamber
- virtual void MakeTransientDigit(Int_t itrack, Int_t ihit, AliMUONHit * mHit);
- // Setting debug level
- void SetDebug(Int_t level){fDebug = level;} // set debug level
- enum {kBgTag = -1};
- // Updating a TransientDigit
- virtual void UpdateTransientDigit(Int_t itrack, AliMUONTransientDigit * mTD);
-
- private:
- void SortTracks(Int_t *tracks,Int_t *charges,Int_t ntr);
-
- private:
- AliMUONHitMapA1 **fHitMap; //! pointer to array of pointers to hitmaps
- TObjArray *fTDList; //! list of AliMUONTransientDigits
- Int_t fTDCounter; //! nr. of AliMUONTransientDigits
- Int_t fDebug; //! debug level
- Int_t fMask; //! mask dependent on input file
- Bool_t fSignal; //! kTRUE if signal file is processed
-
-
- ClassDef(AliMUONSDigitizerv1,0)
+#include "AliMUONDigitizerv1.h"
+
+class AliMUONSDigitizerv1 : public AliMUONDigitizerv1
+{
+public:
+ AliMUONSDigitizerv1();
+
+ // Preferred constructor to call which sets the manager.
+ AliMUONSDigitizerv1(AliRunDigitizer * manager);
+
+ // The following methods are inherited from AliMUONDigitizerv1
+ virtual void AddDigit(Int_t chamber, Int_t tracks[kMAXTRACKS], Int_t charges[kMAXTRACKS], Int_t digits[6]);
+ virtual Int_t GetSignalFrom(AliMUONTransientDigit* td);
+ virtual Bool_t InitOutputData(AliMUONLoader* muonloader);
+ virtual void FillOutputData();
+ virtual void CleanupOutputData(AliMUONLoader* muonloader);
+
+ ClassDef(AliMUONSDigitizerv1, 0)
};
#endif