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