X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=MUON%2FAliMUONDigitizer.cxx;h=d8d22793953cf40b3de123de9297b87afb6db072;hb=8c15d9f403dcdc84691f4faa9295bf03eca5bd6e;hp=0559174b7e41a6c6cca24bfceb004f18b68a9411;hpb=4b1670dcf59a6bdc98e9805e1049c85143099084;p=u%2Fmrichter%2FAliRoot.git diff --git a/MUON/AliMUONDigitizer.cxx b/MUON/AliMUONDigitizer.cxx index 0559174b7e4..d8d22793953 100644 --- a/MUON/AliMUONDigitizer.cxx +++ b/MUON/AliMUONDigitizer.cxx @@ -13,426 +13,605 @@ * provided "as is" without express or implied warranty. * **************************************************************************/ -/* -$Log$ -Revision 1.8 2002/02/13 09:03:24 jchudoba -Remove some deletes from dtor, those objects are deleted earlier in Exec() method (where they are created) - -Revision 1.7 2001/11/22 11:15:41 jchudoba -Proper deletion of arrays (thanks to Rene Brun) - -Revision 1.6 2001/11/02 12:55:45 jchudoba -cleanup of the code, add const to Get methods - -Revision 1.4 2001/10/18 14:44:09 jchudoba -Define constant MAXTRACKS for maximum number of tracks associated with 1 digit - -Revision 1.3 2001/10/04 20:01:54 jchudoba -changes for TTask implementation, some other small editing - -Revision 1.2 2001/07/28 10:46:04 hristov -AliRunDigitizer.h included; typos corrected - -Revision 1.1 2001/07/27 15:41:01 jchudoba -merging/digitization classes - -*/ -#include -#include -#include -#include -#include +/* $Id$ */ #include "AliMUONDigitizer.h" #include "AliMUONConstants.h" -#include "AliMUONChamber.h" +#include "AliMUONSegmentation.h" #include "AliMUONHitMapA1.h" #include "AliMUON.h" -#include "AliMUONHit.h" -#include "AliMUONPadHit.h" -#include "AliMUONDigit.h" +#include "AliMUONLoader.h" +#include "AliMUONConstants.h" #include "AliMUONTransientDigit.h" +#include "AliMUONTriggerDecision.h" +#include "AliLog.h" +#include "AliMUONGeometryTransformer.h" +#include "AliMUONGeometryModule.h" +#include "AliMUONGeometryStore.h" + #include "AliRun.h" -#include "AliPDG.h" #include "AliRunDigitizer.h" +#include "AliRunLoader.h" + +///////////////////////////////////////////////////////////////////////////////////// +// +// AliMUONDigitizer should be base abstract class of all digitisers in the MUON +// module. It implements the common functionality of looping over input streams +// filling the fTDList and writing the fTDList to the output stream. +// Inheriting digitizers need to override certain methods to choose and initialize +// the correct input and output trees, apply the correct detector response if any +// and implement how the transient digits are generated from the input stream. +// +///////////////////////////////////////////////////////////////////////////////////// ClassImp(AliMUONDigitizer) //___________________________________________ -AliMUONDigitizer::AliMUONDigitizer() :AliDigitizer() +AliMUONDigitizer::AliMUONDigitizer() : + AliDigitizer(), + fHitMap(0), + fTDList(0), + fTDCounter(0), + fMask(0), + fSignal(0) { -// Default ctor - don't use it - fHits = 0; - fPadHits = 0; - fHitMap = 0; - fTDList = 0; +/// Default constructor. +/// Initializes all pointers to NULL. + + fRunLoader = NULL; + fGime = NULL; + fMUON = NULL; + fMUONData = NULL; + fTrigDec = NULL; } //___________________________________________ -AliMUONDigitizer::AliMUONDigitizer(AliRunDigitizer* manager) - :AliDigitizer(manager) +AliMUONDigitizer::AliMUONDigitizer(AliRunDigitizer* manager) : + AliDigitizer(manager), + fHitMap(0), + fTDList(0), + fTDCounter(0), + fMask(0), + fSignal(0) { -// ctor which should be used - fHitMap = 0; - fTDList = 0; - fHits = 0; - fPadHits = 0; - fDebug = 0; - if (GetDebug()>2) - cerr<<"AliMUONDigitizer::AliMUONDigitizer" - <<"(AliRunDigitizer* manager) was processed"<TestHit(padhit->PadX(),padhit->PadY())); +/// Destructor + + if (fMUONData) + delete fMUONData; + + if (fTrigDec) + delete fTrigDec; } +//------------------------------------------------------------------- +AliMUONDigitizer& +AliMUONDigitizer::operator=(const AliMUONDigitizer& rhs) +{ +/// Protected assignement operator + + if (this == &rhs) return *this; + + AliFatal("Not implemented."); + + return *this; +} + //------------------------------------------------------------------------ -void AliMUONDigitizer::Update(AliMUONPadHit *padhit) +Bool_t AliMUONDigitizer::Init() { - AliMUONTransientDigit *pdigit = - static_cast( - 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); +/// Initialize - Does nothing. + + return kTRUE; } //------------------------------------------------------------------------ -void AliMUONDigitizer::CreateNew(AliMUONPadHit *padhit) +void AliMUONDigitizer::Exec(Option_t* /*option*/) { -// 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++; +/// The main work loop starts here. +/// The digitization process is broken up into two steps: +/// 1) Loop over input streams and create transient digits from the input. +/// Done in GenerateTransientDigits() +/// 2) Loop over the generated transient digits and write them to the output +/// stream. Done in CreateDigits() + + AliDebug(1, "Running digitiser."); + + if (fManager->GetNinputs() == 0) + { + AliWarning("No inputs set, nothing to do."); + return; + } + + if (!FetchLoaders(fManager->GetInputFolderName(0), fRunLoader, fGime) ) return; + if (! FetchGlobalPointers(fRunLoader) ) return; + if (! FetchTriggerPointer(fGime) ) return; + + InitArrays(); + + AliDebug(2, Form("Event Number is %d.", fManager->GetOutputEventNr())); + + // Loop over files to merge and to digitize + fSignal = kTRUE; + for (Int_t inputFile = 0; inputFile < fManager->GetNinputs(); inputFile++) + { + fMask = fManager->GetMask(inputFile); + AliDebug(2, Form("Digitising folder %d, with fMask = %d: %s", inputFile, fMask, + (const char*)fManager->GetInputFolderName(inputFile))); + + if (inputFile != 0) + // If this is the first file then we already have the loaders loaded. + if (! FetchLoaders(fManager->GetInputFolderName(inputFile), fRunLoader, fGime) ) + continue; + else + // If this is not the first file then it is assumed to be background. + fSignal = kFALSE; + + if (! InitInputData(fGime) ) continue; + GenerateTransientDigits(); + CleanupInputData(fGime); + } + + Bool_t ok = FetchLoaders(fManager->GetOutputFolderName(), fRunLoader, fGime); + if (ok) ok = InitOutputData(fGime); + if (ok) CreateDigits(); + if (ok) CreateTrigger(); + if (ok) CleanupOutputData(fGime); + + CleanupArrays(); + CleanupTriggerArrays(); } +//-------------------------------------------------------------------------- +void AliMUONDigitizer::AddOrUpdateTransientDigit(AliMUONTransientDigit* mTD) +{ +/// Checks to see if the transient digit exists in the corresponding fHitMap. +/// If it does then the digit is updated otherwise it is added. + + if (ExistTransientDigit(mTD)) + { + UpdateTransientDigit(mTD); + delete mTD; // The new digit can be deleted because it was not added. + } + else + AddTransientDigit(mTD); +} //------------------------------------------------------------------------ -Bool_t AliMUONDigitizer::Init() +void AliMUONDigitizer::UpdateTransientDigit(AliMUONTransientDigit* mTD) { -// Initialization - - fHits = new TClonesArray("AliMUONHit",1000); - fPadHits = new TClonesArray("AliMUONPadHit",1000); - return kTRUE; -} +/// Update the transient digit that is already in the fTDList by adding the new +/// transient digits charges and track lists to the existing one. + + AliDebug(4,Form( "Updating transient digit 0x%X", (void*)mTD)); + // Choosing the maping of the cathode plane of the chamber: + Int_t detElemId = mTD->DetElemId(); + + Int_t iNchCpl= fNDetElemId[detElemId] + (mTD->Cathode()-1) * AliMUONConstants::NDetElem(); + AliMUONTransientDigit *pdigit = + static_cast( fHitMap[iNchCpl]->GetHit(mTD->PadX(),mTD->PadY()) ); + + // update charge + pdigit->AddSignal( mTD->Signal() ); + pdigit->AddPhysicsSignal( mTD->Physics() ); + + // update list of tracks + Int_t ntracks = mTD->GetNTracks(); + if (ntracks > kMAXTRACKS) // Truncate the number of tracks to kMAXTRACKS if we have to. + { + AliDebug(1,Form( + "TransientDigit returned the number of tracks to be %d, which is bigger than kMAXTRACKS.", + ntracks)); + AliDebug(1,Form( "Reseting the number of tracks to be %d.", kMAXTRACKS)); + ntracks = kMAXTRACKS; + } + + for (Int_t i = 0; i < ntracks; i++) + { + pdigit->UpdateTrackList( mTD->GetTrack(i), mTD->GetCharge(i) ); + } +} //------------------------------------------------------------------------ -//void AliMUONDigitizer::Digitize() -void AliMUONDigitizer::Exec(Option_t* option) +void AliMUONDigitizer::AddTransientDigit(AliMUONTransientDigit* mTD) { +/// Adds the transient digit to the fTDList and sets the appropriate entry +/// in the fHitMap arrays. - TString optionString = option; - if (optionString.Data() == "deb") { - cout<<"AliMUONDigitizer::Exec: called with option deb "<2) cerr<<" AliMUONDigitizer::Digitize() starts"<GetModule("MUON"); - if (!pMUON) { - cerr<<"AliMUONDigitizer::Digitize Error:" - <<" module MUON not found in the input file"<MakeBranchInTreeD(fManager->GetTreeD()); - fHitMap= new AliMUONHitMapA1* [AliMUONConstants::NCh()]; + AliDebug(4,Form( "Adding transient digit 0x%X", (void*)mTD)); + // Choosing the maping of the cathode plane of the chamber: - // - // loop over cathodes - // + Int_t detElemId = mTD->DetElemId(); + Int_t iNchCpl= fNDetElemId[detElemId] + (mTD->Cathode()-1) * AliMUONConstants::NDetElem(); - 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); -// } - } + fTDList->AddAtAndExpand(mTD, fTDCounter); + if (iNchCpl>-1 && iNchCpl<2*AliMUONConstants::NDetElem()) { + fHitMap[iNchCpl]->SetHit( mTD->PadX(), mTD->PadY(), fTDCounter); + fTDCounter++; + } +} +//------------------------------------------------------------------------ +Bool_t AliMUONDigitizer::ExistTransientDigit(AliMUONTransientDigit* mTD) +{ +/// 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. -// Loop over files to digitize - fSignal = kTRUE; - for (Int_t inputFile=0; inputFileGetNinputs(); - inputFile++) { -// Connect MUON branches - - if (inputFile > 0 ) fSignal = kFALSE; - TBranch *branchHits = 0; - TBranch *branchPadHits = 0; - TTree *treeH = fManager->GetInputTreeH(inputFile); - if (GetDebug()>2) { - cerr<<" inputFile , cathode = "<GetBranch("MUON"); - if (branchHits) { - fHits->Clear(); - branchHits->SetAddress(&fHits); - } - else - Error("Exec","branch MUON was not found"); - } - if (GetDebug()>2) cerr<<" branchHits = "<GetBranch("MUONCluster"); - if (branchPadHits) - branchPadHits->SetAddress(&fPadHits); - else - Error("Exec","branch MUONCluster was not found"); - } - if (GetDebug()>2) cerr<<" branchPadHits = "<DetElemId(); -// -// Loop over tracks -// + Int_t iNchCpl= fNDetElemId[detElemId] + (mTD->Cathode()-1) *AliMUONConstants::NDetElem() ; - Int_t ntracks = (Int_t) treeH->GetEntries(); + // Int_t iNchCpl= mTD->Chamber() + (mTD->Cathode()-1) * AliMUONConstants::NCh(); + if (iNchCpl>-1 && iNchCpl<2*AliMUONConstants::NDetElem()) + return( fHitMap[iNchCpl]->TestHit(mTD->PadX(), mTD->PadY()) ); + else return kFALSE; +} - for (fTrack = 0; fTrack < ntracks; fTrack++) { - if (GetDebug()>2) cerr<<" fTrack = "<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(fHits->At(i)); - fNch = mHit->Chamber()-1; // chamber number - if (fNch > AliMUONConstants::NCh()-1) { - cerr<<"AliMUONDigitizer: ERROR: " - <<"fNch > AliMUONConstants::NCh()-1, fNch, NCh(): " - <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; - if (!(fHitMap[fNch]->ValidateHit(fDigits[0], fDigits[1]))) continue; - fDigits[2] = icat; - fDigits[3] = iqpad; - if (inputFile == 0) { - fDigits[4] = iqpad; - } else { - fDigits[4] = 0; +//----------------------------------------------------------------------- +void AliMUONDigitizer::CreateDigits() +{ +/// Loops over the fTDList for each cathode, gets the correct signal for the +/// digit and adds the new digit to the output stream. + + fTDList->Sort(); // sort by idDE + AliDebug(2, "Creating digits..."); + // for (Int_t icat = 0; icat < 2; icat++) { + + Int_t digitindex[14] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + // + // Filling Digit List + Int_t nentries = fTDList->GetEntriesFast(); + for (Int_t nent = 0; nent < nentries; nent++) { + + AliMUONTransientDigit* td = (AliMUONTransientDigit*)fTDList->At(nent); + if (td == NULL) continue; + + // Must be the same cathode, otherwise we will fill a mixture + // of digits from both cathodes. + //if (icat != td->Cathode() - 1) continue; + + AliDebug(3,Form( "Creating digit from transient digit 0x%X", (void*)td)); + + Int_t q = GetSignalFrom(td); + if (q > 0) { + Int_t chamber = td->Chamber(); + if (0 <= chamber && chamber <= 13 ) + AddDigit(td, q, digitindex[chamber]++); + else + AliError(Form("Invalid chamber %d\n",chamber)); } - 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"<GetEntriesFast(); + } + FillOutputData(); + // } + fTDCounter = 0; +} + +//------------------------------------------------------------------------ +void AliMUONDigitizer::AddDigit( + AliMUONTransientDigit* td, Int_t responseCharge, + Int_t digitindex + ) +{ +/// Prepares the digits, track and charge arrays in preparation for a call to +/// AddDigit(Int_t, Int_t[kMAXTRACKS], Int_t[kMAXTRACKS], Int_t[6]) +/// This method is called by CreateDigits() whenever a new digit needs to be added +/// to the output stream trees. +/// The responseCharge value is used as the Signal of the new digit. +/// The OnWriteTransientDigit method is also called just before the adding the +/// digit to allow inheriting digitizers to be able to do some specific processing +/// at this point. + + Int_t tracks[kMAXTRACKS]; + Int_t charges[kMAXTRACKS]; + Int_t digits[7]; + + digits[0] = td->PadX(); + digits[1] = td->PadY(); + digits[2] = td->Cathode() - 1; + digits[3] = responseCharge; + digits[4] = td->Physics(); + digits[5] = td->Hit(); + digits[6] = td->DetElemId(); + + Int_t nptracks = td->GetNTracks(); + if (nptracks > kMAXTRACKS) { + + AliDebug(1, Form( + "TransientDigit returned the number of tracks to be %d, which is bigger than kMAXTRACKS.", + nptracks)); + AliDebug(1, Form("Reseting the number of tracks to be %d.", kMAXTRACKS)); + nptracks = kMAXTRACKS; + } - for (Int_t 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); - - 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 "<GetTrack(i); + charges[i] = td->GetCharge(i); } - nptracks = kMAXTRACKS; - } - if (nptracks > 2 && GetDebug() >2) { - cerr<<"AliMUONDigitizer: nptracks > 2 "<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) { + + // Sort list of tracks according to charge SortTracks(tracks,charges,nptracks); - } - if (nptracks < kMAXTRACKS ) { - for (Int_t i = nptracks; i < kMAXTRACKS; i++) { - tracks[i] = 0; - charges[i] = 0; + + if (nptracks < kMAXTRACKS ) { + + for (Int_t i = nptracks; i < kMAXTRACKS; i++) { + tracks[i] = -1; + charges[i] = 0; + } } - } - - // fill digits - pMUON->AddDigits(ich,tracks,charges,fDigits); - } - fManager->GetTreeD()->Fill(); + AliDebug(4,Form( "Adding digit with charge %d.", responseCharge)); - pMUON->ResetDigits(); // - fTDList->Clear(); + OnWriteTransientDigit(td); + AddDigit(td->Chamber(), tracks, charges, digits); + AddDigitTrigger(td->Chamber(), tracks, charges, digits, digitindex); +} - - 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: " - <GetTreeD()->GetName()<GetTreeD()->Write(0,TObject::kOverwrite); - delete [] fHitMap; - delete fTDList; - - if (fHits) fHits->Delete(); - if (fPadHits) fPadHits->Delete(); +//------------------------------------------------------------------------ +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::OnWriteTransientDigit(AliMUONTransientDigit* /*digit*/) +{ +/// Does nothing. +/// +/// This is derived by Digitisers that want to trace which digits were made from +/// which hits. } +//------------------------------------------------------------------------ +Bool_t AliMUONDigitizer::FetchLoaders(const char* foldername, AliRunLoader*& runloader, AliMUONLoader*& muonloader) +{ +/// Fetches the run loader from the current folder, specified by 'foldername'. +/// The muon loader is then loaded from the fetched run loader. +/// kTRUE is returned if no error occurred otherwise kFALSE is returned. + + AliDebug(3, Form("Fetching run loader and muon loader from folder: %s", foldername)); + + runloader = AliRunLoader::GetRunLoader(foldername); + if (runloader == NULL) + { + AliError(Form("RunLoader not found in folder: %s", foldername)); + return kFALSE; + } + muonloader = (AliMUONLoader*) runloader->GetLoader("MUONLoader"); + if (muonloader == NULL) + { + AliError(Form("MUONLoader not found in folder: %s", foldername)); + return kFALSE; + } + return kTRUE; + +} //------------------------------------------------------------------------ -void AliMUONDigitizer::SortTracks(Int_t *tracks,Int_t *charges,Int_t ntr) +Bool_t AliMUONDigitizer::FetchGlobalPointers(AliRunLoader* runloader) { - // - // Sort the list of tracks contributing to a given digit - // Only the 3 most significant tracks are acctually sorted - // - - // - // Loop over signals, only 3 times - // - - Int_t qmax; - Int_t jmax; - Int_t idx[3] = {-2,-2,-2}; - Int_t jch[3] = {-2,-2,-2}; - Int_t jtr[3] = {-2,-2,-2}; - Int_t i,j,imax; +/// Fetches the AliRun object into the global gAlice pointer from the specified +/// run loader. The AliRun object is loaded into memory using the run loader if +/// not yet loaded. The MUON module object is then loaded from gAlice and +/// AliMUONData fetched from the MUON module. +/// kTRUE is returned if no error occurred otherwise kFALSE is returned. + + AliDebug(3, Form("Fetching gAlice, MUON module and AliMUONData from runloader 0x%X.", + (void*)runloader + )); + + if (runloader->GetAliRun() == NULL) runloader->LoadgAlice(); + gAlice = runloader->GetAliRun(); + if (gAlice == NULL) + { + AliError(Form("Could not find the AliRun object in runloader 0x%X.", (void*)runloader)); + return kFALSE; + } + fMUON = (AliMUON*) gAlice->GetDetector("MUON"); + if (fMUON == NULL) + { + AliError(Form("Could not find the MUON module in runloader 0x%X.", (void*)runloader)); + return kFALSE; + } + + AliMUONLoader *muonloader = (AliMUONLoader*) runloader->GetLoader("MUONLoader"); + if (muonloader == NULL) + { + AliError( "MUONLoader not found "); + return kFALSE; + } + + + if (fMUONData == NULL) fMUONData = new AliMUONData(muonloader,"MUON","MUON"); + if (fMUONData == NULL) + { + AliError(Form("Could not find AliMUONData object in runloader 0x%X.", (void*)runloader)); + return kFALSE; + } + + return kTRUE; +} +//----------------------------------------------------------------------- +Bool_t AliMUONDigitizer::FetchTriggerPointer(AliMUONLoader* loader) +{ +/// \todo add description + + if (fMUONData == NULL) { + AliError("MUONData not found"); + return kFALSE; + } + + if (fTrigDec == NULL) + fTrigDec = new AliMUONTriggerDecision(loader,0,fMUONData); - if (ntr<3) imax=ntr; - else imax=3; - for(i=0;i qmax) { - qmax = charges[j]; - jmax=j; - } - } - - if(qmax > 0) { - idx[i]=jmax; - jch[i]=charges[jmax]; - jtr[i]=tracks[jmax]; - } + return kTRUE; +} + +//------------------------------------------------------------------------ +void AliMUONDigitizer::InitArrays() +{ +/// Creates a new fTDList object. +/// Also creates an array of 2 * chamber_number AliMUONHitMapA1 objects +/// in the fHitMaps array. Each one is set to a chamber and cathode +/// specific segmentation model. +/// +/// Note: the fTDList and fHitMap arrays must be NULL before calling this method. + + AliDebug(2, "Initialising internal arrays."); + AliDebug(4, "Creating transient digits list."); + fTDList = new TObjArray; + + // Array of pointer of the AliMUONHitMapA1: + // two HitMaps per chamber, or one HitMap per cahtode plane + fHitMap = new AliMUONHitMapA1* [2*AliMUONConstants::NDetElem()]; + for (Int_t i=0; i<2*AliMUONConstants::NDetElem(); i++) fHitMap[i] = 0x0; + + Int_t k = 0; + Int_t idDE; + + for (Int_t i = 0; i < AliMUONConstants::NCh(); i++) { + + + AliDebug(4,Form( "Creating hit map for chamber %d, cathode 1.", i+1)); + AliMUONSegmentation* segmentation = fMUON->GetSegmentation(); + AliMUONGeometrySegmentation* c1Segmentation + = segmentation->GetModuleSegmentation(i, 0); // Cathode plane 1 + AliDebug(4,Form( "Creating hit map for chamber %d, cathode 2.", i+1)); + AliMUONGeometrySegmentation* c2Segmentation + = segmentation->GetModuleSegmentation(i, 1); // Cathode plane 2 + + const AliMUONGeometryTransformer* kGeometryTransformer + = fMUON->GetGeometryTransformer(); + + AliMUONGeometryStore* detElements + = kGeometryTransformer->GetModuleTransformer(i)->GetDetElementStore(); - } - - for(i=0;i<3;i++){ - if (jtr[i] == -2) { - charges[i]=0; - tracks[i]=0; - } else { - charges[i]=jch[i]; - tracks[i]=jtr[i]; + + // Loop over detection elements + for (Int_t j=0; jGetNofEntries(); j++) { + + idDE = detElements->GetEntry(j)->GetUniqueID(); + fNDetElemId[idDE] = k; + + Int_t npx1 = c1Segmentation->Npx(idDE)+1; + Int_t npy1 = c1Segmentation->Npy(idDE)+1; + fHitMap[k] = new AliMUONHitMapA1(npx1, npy1, fTDList); + + Int_t npx2 = c2Segmentation->Npx(idDE)+1; + Int_t npy2 = c2Segmentation->Npy(idDE)+1; + fHitMap[k+AliMUONConstants::NDetElem()] = new AliMUONHitMapA1(npx2, npy2, fTDList); + k++; + } } - } +} +//------------------------------------------------------------------------ +void AliMUONDigitizer::CleanupArrays() +{ +/// The arrays fTDList and fHitMap are deleted and the pointers set to NULL. + + AliDebug(2, "Deleting internal arrays."); + for(Int_t i = 0; i < 2*AliMUONConstants::NDetElem(); i++) { + delete fHitMap[i]; + } + delete [] fHitMap; + fHitMap = NULL; + + AliDebug(4, "Deleting transient digits list."); + fTDList->Delete(); + delete fTDList; + fTDList = NULL; + +} + +//------------------------------------------------------------------------ +void AliMUONDigitizer::SortTracks(Int_t *tracks, Int_t *charges, Int_t ntr) const +{ +/// Sort the list of tracks contributing to a given digit +/// Only the 3 most significant tracks are actually sorted + + if (ntr <= 1) return; + + // + // Loop over signals, only 3 times + // + + Int_t qmax; + Int_t jmax; + Int_t idx[3] = {-2,-2,-2}; + Int_t jch[3] = {-2,-2,-2}; + Int_t jtr[3] = {-2,-2,-2}; + Int_t i, j, imax; + + if (ntr < 3) imax = ntr; + else imax=3; + + for(i = 0; i < imax; i++) + { + qmax=0; + jmax=0; + + for(j = 0; j < ntr; j++) + { + if ( (i == 1 && j == idx[i-1]) || + (i == 2 && (j == idx[i-1] || j == idx[i-2])) + ) + continue; + + if(charges[j] > qmax) + { + qmax = charges[j]; + jmax = j; + } + } + + if(qmax > 0) + { + idx[i] = jmax; + jch[i] = charges[jmax]; + jtr[i] = tracks[jmax]; + } + + } + + for(i = 0; i < 3; i++) + { + if (jtr[i] == -2) + { + charges[i] = 0; + tracks[i] = 0; + } + else + { + charges[i] = jch[i]; + tracks[i] = jtr[i]; + } + } }