Cleaning-up code (Artur)
authormartinez <martinez@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 12 Mar 2004 12:10:35 +0000 (12:10 +0000)
committermartinez <martinez@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 12 Mar 2004 12:10:35 +0000 (12:10 +0000)
MUON/AliMUONDigitizer.cxx
MUON/AliMUONDigitizer.h
MUON/AliMUONDigitizerv1.cxx
MUON/AliMUONDigitizerv1.h
MUON/AliMUONDigitizerv2.cxx
MUON/AliMUONDigitizerv2.h
MUON/AliMUONSDigitizerv1.cxx
MUON/AliMUONSDigitizerv1.h

index ad9ac4cfa53d104335bfc63c04d5078aeb8ec0bc..a16126ef91c1aff2390648f96cc7a345506a7301 100644 (file)
 #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];
+               }
+       }
+};
index e10f7b0413d79001d62b4cc6e12abd8f6178faa4..706531afa1c9bf704eae76c5b1e76a7487240ced 100644 (file)
 
 /* $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
-
index 317d97ccbc9b11d2931db854a0bdd77a5dac10a1..6dcd5f99e80feaed4c996ecde98db9bd9cbc7322 100644 (file)
@@ -1,5 +1,4 @@
 
-
 #include <Riostream.h>
 #include <TDirectory.h>
 #include <TFile.h>
@@ -8,6 +7,11 @@
 #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();
+};
+
index 18dc6ee6022bbe2cb4997edbeaefc7cbd7cab461..848c2317b350b3523711a0435422599a66460dfd 100644 (file)
 // 
 // 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
 
index 4775e343dbb2a278bddca72dbf5428c931c35ca4..e8eb27438a25201e93f1e6b4f191c8c239049d37 100644 (file)
 #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();
+};
index 4a2ebfb9883b83c2721a5b6e4fe9ecaa6ae7741c..f89092e2fd8f44da81ff3bad33f265e7a90fec70 100644 (file)
@@ -3,49 +3,26 @@
 /* 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
 
index 1a504eadbf0bce093930d49346a1292222e57970..b64bc87d68deb4f67c240f485f5a948b3ec0121a 100644 (file)
@@ -1,5 +1,4 @@
 
-
 #include <Riostream.h>
 #include <TDirectory.h>
 #include <TFile.h>
@@ -8,6 +7,10 @@
 #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();
+};
index e4584759bc2cd1014634db1587136accb959426d..e088c36b4669ddaf0ad0de86e432c63041947ca0 100644 (file)
@@ -5,46 +5,24 @@
 // 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