Rewritten using new VDigitStore, VDigit and VTriggerStore interfaces (Laurent)
authorhristov <hristov@f7af4fe6-9843-0410-8265-dc069ae4e863>
Sun, 17 Jun 2007 20:48:44 +0000 (20:48 +0000)
committerhristov <hristov@f7af4fe6-9843-0410-8265-dc069ae4e863>
Sun, 17 Jun 2007 20:48:44 +0000 (20:48 +0000)
MUON/AliMUONDigitMaker.cxx
MUON/AliMUONDigitMaker.h
MUON/AliMUONDigitizerV3.cxx
MUON/AliMUONDigitizerV3.h

index 97b2e9b..2779db9 100644 (file)
 /// \author Ch. Finck, oct 06 
 
 #include "AliMUONDigitMaker.h"
-#include "AliMUONDigit.h"
 
-#include "AliMUONConstants.h"
-#include "AliMUONData.h"
-
-#include "AliMUONRawStreamTracker.h"
-#include "AliMUONDDLTracker.h"
-#include "AliMUONDspHeader.h"
-#include "AliMUONBlockHeader.h"
-#include "AliMUONBusStruct.h"
-
-#include "AliMUONRawStreamTrigger.h"
+#include "AliLog.h"
 #include "AliMUONDDLTrigger.h"
 #include "AliMUONDarcHeader.h"
-#include "AliMUONRegHeader.h"
+#include "AliMUONVDigit.h"
+#include "AliMUONVDigitStore.h"
+#include "AliMUONGlobalTrigger.h"
 #include "AliMUONLocalStruct.h"
-
-#include "AliMUONTriggerCrateStore.h"
-#include "AliMUONTriggerCrate.h"
-#include "AliMUONLocalTriggerBoard.h"
 #include "AliMUONLocalTrigger.h"
-#include "AliMUONGlobalTrigger.h"
+#include "AliMUONLocalTriggerBoard.h"
+#include "AliMUONRawStreamTracker.h"
+#include "AliMUONRawStreamTrigger.h"
+#include "AliMUONRegHeader.h"
 #include "AliMUONTriggerCircuit.h"
-
+#include "AliMUONTriggerCrate.h"
+#include "AliMUONTriggerCrateStore.h"
+#include "AliMUONVTriggerStore.h"
+#include "AliMpCathodType.h"
+#include "AliMpDDLStore.h"
+#include "AliMpDEManager.h"
+#include "AliMpPad.h"
 #include "AliMpSegmentation.h"
 #include "AliMpVSegmentation.h"
-#include "AliMpPad.h"
-#include "AliMpDEManager.h"
-#include "AliMpDDLStore.h"
-#include "AliMpCathodType.h"
-
 #include "AliRawReader.h"
-#include "AliRawDataHeader.h"
-#include "AliLog.h"
-#include "AliRun.h"
-
-#include <TList.h>
 #include <TArrayS.h>
 
-
 /// \cond CLASSIMP
 ClassImp(AliMUONDigitMaker) // Class implementation in ROOT context
 /// \endcond
 
 //__________________________________________________________________________
-AliMUONDigitMaker::AliMUONDigitMaker(Bool_t flag)
+AliMUONDigitMaker::AliMUONDigitMaker()
   : TObject(),
-    fMUONData(0x0),
     fScalerEvent(kFALSE),
-    fDigitFlag(flag),
-    fTriggerFlag(kTRUE),
-    fDisplayFlag(kFALSE),
+    fMakeTriggerDigits(kFALSE),
     fRawStreamTracker(new AliMUONRawStreamTracker()),    
     fRawStreamTrigger(new AliMUONRawStreamTrigger()),    
-    fDigit(new AliMUONDigit()),
-    fLocalTrigger(new AliMUONLocalTrigger()),
-    fGlobalTrigger(new AliMUONGlobalTrigger()),
     fCrateManager(0x0),
     fTrackerTimer(),
     fTriggerTimer(),
-    fMappingTimer()
+    fMappingTimer(),
+    fDigitStore(0x0),
+    fTriggerStore(0x0)
 {
-  /// ctor with AliMUONData as argument
-  /// for reconstruction
+  /// ctor 
 
   AliDebug(1,"");
 
@@ -111,6 +92,8 @@ AliMUONDigitMaker::AliMUONDigitMaker(Bool_t flag)
   fTrackerTimer.Start(kTRUE); fTrackerTimer.Stop();
   fTriggerTimer.Start(kTRUE); fTriggerTimer.Stop();
   fMappingTimer.Start(kTRUE); fMappingTimer.Stop();
+  
+  SetMakeTriggerDigits();
 
 }
 
@@ -123,10 +106,6 @@ AliMUONDigitMaker::~AliMUONDigitMaker()
   delete fRawStreamTracker;
   delete fRawStreamTrigger;
 
-  delete fDigit;
-  delete fLocalTrigger;
-  delete fGlobalTrigger;
-
   AliDebug(1, Form("Execution time for MUON tracker : R:%.2fs C:%.2fs",
                fTrackerTimer.RealTime(),fTrackerTimer.CpuTime()));
   AliDebug(1, Form("   Execution time for MUON tracker (mapping calls part) "
@@ -135,36 +114,59 @@ AliMUONDigitMaker::~AliMUONDigitMaker()
   AliDebug(1, Form("Execution time for MUON trigger : R:%.2fs C:%.2fs",
                fTriggerTimer.RealTime(),fTriggerTimer.CpuTime()));
 
-  return;
 }
 
 //____________________________________________________________________
-Int_t AliMUONDigitMaker::Raw2Digits(AliRawReader* rawReader)
+Int_t AliMUONDigitMaker::Raw2Digits(AliRawReader* rawReader, 
+                                    AliMUONVDigitStore* digitStore,
+                                    AliMUONVTriggerStore* triggerStore)
 {
   /// Main method to creates digit
   /// for tracker 
   /// and trigger
 
-  // generate digits
-  ReadTrackerDDL(rawReader);
-
-  // generate trigger
-  if( fTriggerFlag)
+  AliDebug(1,Form("rawReader=%p digitStore=%p triggerStore=%p",
+                  rawReader,digitStore,triggerStore));
+  
+  fDigitStore = digitStore;
+  fTriggerStore = triggerStore;
+  
+  if (!fDigitStore && !fTriggerStore)
+  {
+    AliError("No digit or trigger store given. Nothing to do...");
+    return kFALSE;
+  }
+  
+  if ( fDigitStore ) 
+  {
+    fDigitStore->Clear(); // insure we start with an empty container
+    ReadTrackerDDL(rawReader);
+  }
+  
+  if ( fTriggerStore || fMakeTriggerDigits ) 
+  {
+    if ( fTriggerStore ) fTriggerStore->Clear();
+    if ( fMakeTriggerDigits && !fDigitStore ) 
+    {
+      AliError("Asking for trigger digits but digitStore is null");
+    }
+    else
+    {
       ReadTriggerDDL(rawReader);
-  else
-      AliInfo("Reading trigger rawdata disable");
-
+    }
+  }
+  
   return kTRUE;
-
 }
 
 //____________________________________________________________________
 Int_t AliMUONDigitMaker::ReadTrackerDDL(AliRawReader* rawReader)
 {
+  /// Reading tracker DDL
+  /// filling the fDigitStore container, which must not be null
 
-  /// reading tracker DDL
-  /// filling the TClonesArray in MUONData
-
+  AliDebug(1,"");
+  
   fTrackerTimer.Start(kFALSE);
 
   // elex info
@@ -173,213 +175,150 @@ Int_t AliMUONDigitMaker::ReadTrackerDDL(AliRawReader* rawReader)
   UShort_t manuId;
   UShort_t charge; 
 
-  Int_t iChamber;
-
   fRawStreamTracker->SetReader(rawReader);
   fRawStreamTracker->First();
   
   while ( fRawStreamTracker->Next(buspatchId,manuId,channelId,charge) )
   {    
-           fDigit->SetSignal(charge);
-           fDigit->SetPhysicsSignal(charge);
-           fDigit->SetADC(charge);
+    // getting DE from buspatch
+    Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(buspatchId);
 
-           // Get Back the hits at pads
-           Int_t error = GetMapping(buspatchId,manuId,channelId,fDigit); 
-           if (error) 
-      {
-             AliWarning("Mapping Error\n");
-             continue;
-           }
-           
-      // debugging 
-           if (AliLog::GetGlobalDebugLevel() == 3) 
-      {
-             Int_t padX  = fDigit->PadX();
-             Int_t padY  = fDigit->PadY();
-             Int_t iCath = fDigit->Cathode();  
-             Int_t idDE  = fDigit->DetElemId();
-
-             AliDebug(1,Form("output  IdDE %d busPatchid %d PadX %d PadY %d iCath %d \n", 
-                             idDE, buspatchId, padX, padY, iCath));
-               
-             AliDebug(3,Form("idDE %d Padx %d Pady %d, Cath %d, charge %d",
-                             idDE, padX, padY, iCath, charge));
-           }
-
-           // fill digits
-           iChamber = AliMpDEManager::GetChamberId(fDigit->DetElemId());
-
-           if (fDigitFlag || fDisplayFlag)
-      {
-        fMUONData->AddDigit(iChamber, *fDigit);
-      }
-           else
-      {
-        fMUONData->AddSDigit(iChamber, *fDigit);
-      }
-  }
-  
-  fTrackerTimer.Stop();
+    const AliMpVSegmentation* seg 
+      = AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(detElemId, 
+                                                                      manuId);  
 
-  return kTRUE;
-}
+    AliMp::CathodType cathodeType = AliMpDEManager::GetCathod(detElemId, 
+                                                              seg->PlaneType());
 
-//____________________________________________________________________
-Int_t AliMUONDigitMaker::GetMapping(Int_t busPatchId, UShort_t manuId, 
-                                        UChar_t channelId, AliMUONDigit* digit )
-{
-  /// mapping  for tracker
+    AliMpPad pad = seg->PadByLocation(AliMpIntPair(manuId,channelId),kFALSE);
+    
+    if (!pad.IsValid())
+    {
+      AliError(Form("No pad for detElemId: %d, manuId: %d, channelId: %d",
+                    detElemId, manuId, channelId));
+      continue;
+    } 
+    
+    AliMUONVDigit* digit = fDigitStore->Add(detElemId,manuId,channelId,cathodeType,
+                                            AliMUONVDigitStore::kDeny);
+    if (!digit)
+    {
+      AliError(Form("Digit DE %04d Manu %04d Channel %02d could not be added",
+                    detElemId, manuId, channelId));
+      continue;
+    }
+    
+    digit->SetPadXY(pad.GetIndices().GetFirst(),
+                   pad.GetIndices().GetSecond());
+    
+         digit->SetADC(charge);
 
-  fMappingTimer.Start(kFALSE);
+  }
   
-  // getting DE from buspatch
-  Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(busPatchId);
-  AliDebug(3,Form("detElemId: %d busPatchId %d\n", detElemId, busPatchId));
-
-  const AliMpVSegmentation* seg 
-    = AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(detElemId, manuId);  
-  AliMpPad pad = seg->PadByLocation(AliMpIntPair(manuId,channelId),kTRUE);
+  fTrackerTimer.Stop();
 
-  if (!pad.IsValid())
-  {
-    AliWarning(Form("No pad for detElemId: %d, busPatchId %d, manuId: %d, channelId: %d\n",
-                 detElemId, busPatchId, manuId, channelId));
-    fMappingTimer.Stop();
-    return kTRUE;
-  } // return error
-
-  // Getting padX, padY and cathode number.
-  Int_t padX = pad.GetIndices().GetFirst();
-  Int_t padY = pad.GetIndices().GetSecond();
-  Int_t iCath = AliMpDEManager::GetCathod(detElemId,seg->PlaneType());
-
-  // storing into digits
-  digit->SetPadX(padX);
-  digit->SetPadY(padY);
-  digit->SetCathode(iCath);
-  digit->SetDetElemId(detElemId);
-  digit->SetElectronics(manuId,channelId);
-  
-  AliDebug(3,Form("detElemId: %d, busPatchId %d, manuId: %d, channelId: %d, padx: %d pady %d\n",
-                 detElemId, busPatchId, manuId, channelId, padX, padY));
-//  StdoutToAliDebug(3,digit->Print(););
-  
-  fMappingTimer.Stop();
-  return kFALSE;
+  return kTRUE;
 }
 
 //____________________________________________________________________
 Int_t AliMUONDigitMaker::ReadTriggerDDL(AliRawReader* rawReader)
 {
   /// reading tracker DDL
-  /// filling the TClonesArray in MUONData
+  /// filling the fTriggerStore container, which must not be null
 
+  AliDebug(1,"");
+  
   AliMUONDDLTrigger*       ddlTrigger      = 0x0;
   AliMUONDarcHeader*       darcHeader      = 0x0;
   AliMUONRegHeader*        regHeader       = 0x0;
   AliMUONLocalStruct*      localStruct     = 0x0;
 
   Int_t loCircuit;
-  TList digitList;
 
   fTriggerTimer.Start(kFALSE);
 
   fRawStreamTrigger->SetReader(rawReader);
 
-  while(fRawStreamTrigger->NextDDL()) {
-    
+  while (fRawStreamTrigger->NextDDL()) 
+  {
     ddlTrigger = fRawStreamTrigger->GetDDLTrigger();
     darcHeader = ddlTrigger->GetDarcHeader();
-
-    // fill global trigger information in Digit Tree
-    if (fDigitFlag) {
-      if (darcHeader->GetGlobalFlag()) {
-       if (!fDisplayFlag) {
-         fGlobalTrigger->SetFromGlobalResponse(darcHeader->GetGlobalOutput());
-         fMUONData->AddGlobalTrigger(*fGlobalTrigger);
-       }
+    
+    // fill global trigger information
+    if (fTriggerStore) 
+    {
+      if (darcHeader->GetGlobalFlag()) 
+      {
+          AliMUONGlobalTrigger globalTrigger;
+          globalTrigger.SetFromGlobalResponse(darcHeader->GetGlobalOutput());
+          fTriggerStore->SetGlobal(globalTrigger);
       }
     }
-
+    
     Int_t nReg = darcHeader->GetRegHeaderEntries();
-
-    for(Int_t iReg = 0; iReg < nReg ;iReg++){   //reg loop
-
+    
+    for(Int_t iReg = 0; iReg < nReg ;iReg++)
+    {   //reg loop
+      
       // crate info
       if (!fCrateManager) AliFatal("Crate Store not defined");
       AliMUONTriggerCrate* crate = fCrateManager->Crate(fRawStreamTrigger->GetDDL(), iReg);
-  
+      
       if (!crate) 
-       AliWarning(Form("Missing crate number %d in DDL %d\n", iReg, fRawStreamTrigger->GetDDL()));
-
+        AliWarning(Form("Missing crate number %d in DDL %d\n", iReg, fRawStreamTrigger->GetDDL()));
+      
       TObjArray *boards  = crate->Boards();
-
+      
       regHeader =  darcHeader->GetRegHeaderEntry(iReg);
-
+      
       Int_t nLocal = regHeader->GetLocalEntries();
-      for(Int_t iLocal = 0; iLocal < nLocal; iLocal++) {  
-       
-       localStruct = regHeader->GetLocalEntry(iLocal);
-
-       // if card exist
-       if (localStruct) {
-
-         AliMUONLocalTriggerBoard* localBoard = 
-           (AliMUONLocalTriggerBoard*)boards->At(localStruct->GetId()+1);
-
-         // skip copy cards
-         if( !(loCircuit = localBoard->GetNumber()) )
-            continue;
-
-         if (fDigitFlag) {
-           // fill local trigger
-             fLocalTrigger->SetLocalStruct(loCircuit, *localStruct);
-             fMUONData->AddLocalTrigger(*fLocalTrigger);
-             
-         } else {
-           // Make SDigit
-
-           digitList.Clear();
-           //FIXEME should find something better than a TArray
-           TArrayS xyPattern[2];
-           xyPattern[0].Set(4);
-           xyPattern[1].Set(4);
-
-           xyPattern[0].AddAt(localStruct->GetX1(),0);
-           xyPattern[0].AddAt(localStruct->GetX2(),1);
-           xyPattern[0].AddAt(localStruct->GetX3(),2);
-           xyPattern[0].AddAt(localStruct->GetX4(),3);
-
-           xyPattern[1].AddAt(localStruct->GetY1(),0);
-           xyPattern[1].AddAt(localStruct->GetY2(),1);
-           xyPattern[1].AddAt(localStruct->GetY3(),2);
-           xyPattern[1].AddAt(localStruct->GetY4(),3);
-
-           if( TriggerDigits(loCircuit, xyPattern, digitList) ) {
-
-             for (Int_t iEntry = 0; iEntry < digitList.GetEntries(); iEntry++) {
-
-               AliMUONDigit* digit = (AliMUONDigit*)digitList.At(iEntry);
-               
-               // filling S container
-               Int_t iChamber = AliMpDEManager::GetChamberId(digit->DetElemId());
-               if (!fDisplayFlag) {
-                 fMUONData->AddSDigit(iChamber, *digit);
-               } else {
-                 fMUONData->AddDigit(iChamber, *digit);
-               }
-
-             }
-
-           } // trigger digits
-         } // S flag
-
-       } // if triggerY
+      for(Int_t iLocal = 0; iLocal < nLocal; iLocal++) 
+      {  
+        
+        localStruct = regHeader->GetLocalEntry(iLocal);
+        
+        // if card exist
+        if (localStruct) {
+          
+          AliMUONLocalTriggerBoard* localBoard = 
+          (AliMUONLocalTriggerBoard*)boards->At(localStruct->GetId()+1);
+          
+          // skip copy cards
+          if( !(loCircuit = localBoard->GetNumber()) )
+            continue;
+          
+          if (fTriggerStore) 
+          {
+            // fill local trigger
+            AliMUONLocalTrigger localTrigger;
+            localTrigger.SetLocalStruct(loCircuit, *localStruct);
+            fTriggerStore->Add(localTrigger);
+          } 
+          
+          if ( fMakeTriggerDigits )
+          {
+            //FIXEME should find something better than a TArray
+            TArrayS xyPattern[2];
+            xyPattern[0].Set(4);
+            xyPattern[1].Set(4);
+            
+            xyPattern[0].AddAt(localStruct->GetX1(),0);
+            xyPattern[0].AddAt(localStruct->GetX2(),1);
+            xyPattern[0].AddAt(localStruct->GetX3(),2);
+            xyPattern[0].AddAt(localStruct->GetX4(),3);
+            
+            xyPattern[1].AddAt(localStruct->GetY1(),0);
+            xyPattern[1].AddAt(localStruct->GetY2(),1);
+            xyPattern[1].AddAt(localStruct->GetY3(),2);
+            xyPattern[1].AddAt(localStruct->GetY4(),3);
+            
+            TriggerDigits(loCircuit, xyPattern, *fDigitStore);
+          }          
+        } // if triggerY
       } // iLocal
     } // iReg
   } // NextDDL
-
+  
   fTriggerTimer.Stop();
 
   return kTRUE;
@@ -388,84 +327,71 @@ Int_t AliMUONDigitMaker::ReadTriggerDDL(AliRawReader* rawReader)
 
 //____________________________________________________________________
 Int_t AliMUONDigitMaker::TriggerDigits(Int_t nBoard, 
-                                      TArrayS* xyPattern,
-                                      TList& digitList)
+                                       TArrayS* xyPattern,
+                                       AliMUONVDigitStore& digitStore) const
 {
-  /// make (S)Digit for trigger
-
-  Int_t detElemId;
-  Int_t previousDetElemId[4] = {0};
-  Int_t previousBoard[4] = {0};
+  /// make digits for trigger from pattern, and add them to digitStore
 
   // loop over x1-4 and y1-4
-  for(Int_t iChamber = 0; iChamber < 4; ++iChamber){
-    for(Int_t iCath = 0; iCath < 2; ++iCath){
-  
+  for (Int_t iChamber = 0; iChamber < 4; ++iChamber)
+  {
+    for (Int_t iCath = 0; iCath < 2; ++iCath)
+    {
       Int_t pattern = (Int_t)xyPattern[iCath].At(iChamber); 
       if (!pattern) continue;
-
+      
       // get detElemId
       AliMUONTriggerCircuit triggerCircuit;
       AliMUONLocalTriggerBoard* localBoard = fCrateManager->LocalBoard(nBoard);
-      detElemId = triggerCircuit.DetElemId(iChamber+10, localBoard->GetName());//FIXME +/-10 (should be ok with new mapping)
-
-
-      if(iCath == 1){ // FIXME should find a more elegant way
-       // Don't save twice the same digit
-       // (since strips in non bending plane can cross several boards)
-       Int_t prevDetElemId = previousDetElemId[iChamber];
-       Int_t prevBoard = previousBoard[iChamber];
-       previousDetElemId[iChamber] = detElemId;
-       previousBoard[iChamber] = nBoard;
-
-       if(detElemId == prevDetElemId){
-         if(nBoard-prevBoard==1) continue;
-       }
-      }
-
-      const AliMpVSegmentation* seg 
-         = AliMpSegmentation::Instance()
-         ->GetMpSegmentation(detElemId, AliMp::GetCathodType(iCath));  
-
-      // loop over the 16 bits of pattern
-      for (Int_t ibitxy = 0; ibitxy < 16; ++ibitxy) {
-    
-       if ((pattern >> ibitxy) & 0x1) {
-
-         // not quite sure about this
-         Int_t offset = 0;
-         if (iCath && localBoard->GetSwitch(6)) offset = -8;
-
-         AliMpPad pad = seg->PadByLocation(AliMpIntPair(nBoard,ibitxy+offset),kTRUE);
-
-         AliMUONDigit* digit = new  AliMUONDigit();
-         if (!pad.IsValid()) {
-           AliWarning(Form("No pad for detElemId: %d, nboard %d, ibitxy: %d\n",
-                           detElemId, nBoard, ibitxy));
-           continue;
-         } // 
-
-         Int_t padX = pad.GetIndices().GetFirst();
-         Int_t padY = pad.GetIndices().GetSecond();
-
-         // file digit
-         digit->SetPadX(padX);
-         digit->SetPadY(padY);
-         digit->SetSignal(1.);
-         digit->SetCathode(iCath);
-         digit->SetDetElemId(detElemId);
-         digit->SetElectronics(nBoard, ibitxy);
-         digitList.Add(digit);
-       
-       }// xyPattern
-      }// ibitxy
+      Int_t detElemId = triggerCircuit.DetElemId(iChamber+10, localBoard->GetName());//FIXME +/-10 (should be ok with new mapping)
+        
+        const AliMpVSegmentation* seg 
+          = AliMpSegmentation::Instance()
+          ->GetMpSegmentation(detElemId, AliMp::GetCathodType(iCath));  
+        
+        // loop over the 16 bits of pattern
+        for (Int_t ibitxy = 0; ibitxy < 16; ++ibitxy) 
+        {
+          if ((pattern >> ibitxy) & 0x1) 
+          {            
+            // not quite sure about this
+            Int_t offset = 0;
+            if (iCath && localBoard->GetSwitch(6)) offset = -8;
+            
+            AliMpPad pad = seg->PadByLocation(AliMpIntPair(nBoard,ibitxy+offset),kTRUE);
+                        
+            if (!pad.IsValid()) 
+            {
+              AliWarning(Form("No pad for detElemId: %d, nboard %d, ibitxy: %d\n",
+                              detElemId, nBoard, ibitxy));
+              continue;
+            }
+            
+            AliMUONVDigit* digit = digitStore.Add(detElemId,nBoard,ibitxy,iCath,AliMUONVDigitStore::kDeny);
+            
+            if (!digit)
+            {
+              AliError(Form("Could not add digit DE %04d LocalBoard %03d ibitxy %02d cath %d",
+                            detElemId,nBoard,ibitxy,iCath));
+              continue;
+            }
+            
+            Int_t padX = pad.GetIndices().GetFirst();
+            Int_t padY = pad.GetIndices().GetSecond();
+            
+            // fill digit
+            digit->SetPadXY(padX,padY);
+            digit->SetCharge(1.);
+          }// xyPattern
+        }// ibitxy
     }// cath
   } // ichamber
-
+  
   return kTRUE;
 } 
 //____________________________________________________________________
-void  AliMUONDigitMaker::GetCrateName(Char_t* name, Int_t iDDL, Int_t iReg) const
+void  
+AliMUONDigitMaker::GetCrateName(Char_t* name, Int_t iDDL, Int_t iReg) const
 {
   /// set crate name from DDL & reg number
   /// method same as in RawWriter, not so nice
index d46ef4d..7a20f30 100644 (file)
 #include <TObject.h>
 #include "TStopwatch.h"
 
-class TList;
 class TArrayS;
 
 class AliRawReader;
-class AliMUONData;
-class AliMUONDigit;
-class AliMUONGlobalTrigger;
-class AliMUONLocalTrigger;
 class AliMUONTriggerCrateStore;
 class AliMUONLocalStruct;
 
 class AliMUONRawStreamTracker;
 class AliMUONRawStreamTrigger;
 
+class AliMUONVDigitStore;
+class AliMUONVTriggerStore;
+
 class AliMUONDigitMaker : public TObject 
 {
  public:
-  AliMUONDigitMaker(Bool_t digit = kTRUE); // Constructor
+  AliMUONDigitMaker(); // Constructor
   virtual ~AliMUONDigitMaker(void); // Destructor
     
   // write raw data
-  Int_t  Raw2Digits(AliRawReader* rawReader);
+  Int_t  Raw2Digits(AliRawReader* rawReader, 
+                    AliMUONVDigitStore* digitContainer=0,
+                    AliMUONVTriggerStore* triggerStore=0);
 
   Int_t  ReadTrackerDDL(AliRawReader* rawReader);
   Int_t  ReadTriggerDDL(AliRawReader* rawReader);
-         /// Return MUON data
-  AliMUONData*   GetMUONData() const {return fMUONData;}
-        /// Set MUON data
-  void SetMUONData(AliMUONData* data) {fMUONData = data;}
-  Int_t GetMapping(Int_t buspatchId, UShort_t manuId, 
-                         UChar_t channelId, AliMUONDigit* digit );
-
-  Int_t TriggerDigits(Int_t nBoard, TArrayS* xyPattern, TList& digitList );
+  
+  Int_t TriggerDigits(Int_t nBoard, TArrayS* xyPattern, 
+                      AliMUONVDigitStore& digitStore) const;
 
         /// Set flag to generates scaler event
-  void  SetScalerEvent() {fScalerEvent = kTRUE;}
-
-      /// Disable trigger rawdata reading
-  void  DisableTrigger() {fTriggerFlag = kFALSE;}
+  void  SetScalerEvent() { fScalerEvent = kTRUE; }
 
         /// Set Crate array
-  void  SetCrateManager(AliMUONTriggerCrateStore* crateManager) {fCrateManager =  crateManager;}
+  void  SetCrateManager(AliMUONTriggerCrateStore* crateManager) { fCrateManager =  crateManager; }
 
-       /// enable only list of digits for the display
-  void SetDisplayFlag() { fDisplayFlag = kTRUE;  fDigitFlag = kFALSE;}
+        /// Set flag whether or not we should generate digits for the trigger
+  void  SetMakeTriggerDigits(Bool_t flag = kFALSE) { fMakeTriggerDigits = flag; }
 
-
- private:
+private:
+    
   /// Not implemented
   AliMUONDigitMaker (const AliMUONDigitMaker& rhs); // copy constructor
   /// Not implemented
@@ -71,31 +61,24 @@ class AliMUONDigitMaker : public TObject
 
   void GetCrateName(Char_t* name, Int_t iDDL, Int_t iReg) const;
 
-  AliMUONData*     fMUONData;          //!< Data container for MUON subsystem 
-  
-  Bool_t           fScalerEvent;       //!< flag to generates scaler event
-
-  Bool_t           fDigitFlag;         //!< true for Digit, false for SDigit
-
-  Bool_t           fTriggerFlag;       //!< true for reading also trigger rawdata
-
-  Bool_t           fDisplayFlag;       //!< true for returning digits list to the display
+private:
 
+  Bool_t           fScalerEvent;       //!< flag to generates scaler event
+  Bool_t fMakeTriggerDigits; //!< whether or not we should generate digits for the trigger
+  
   AliMUONRawStreamTracker* fRawStreamTracker;  //!< pointer of raw stream for tracker
   AliMUONRawStreamTrigger* fRawStreamTrigger;  //!< pointer of raw stream for trigger
 
-  AliMUONDigit*        fDigit;                 //!< pointer to digits
-
-  AliMUONLocalTrigger*  fLocalTrigger;         //!< pointer to local trigger
-  AliMUONGlobalTrigger* fGlobalTrigger;        //!< pointer to local trigger
-
   AliMUONTriggerCrateStore* fCrateManager;     //!< Crate array
 
   TStopwatch fTrackerTimer;                    //!< time watcher for tracker part
   TStopwatch fTriggerTimer;                    //!< time watcher for trigger part
   TStopwatch fMappingTimer;                    //!< time watcher for mapping-tracker part
 
-  ClassDef(AliMUONDigitMaker,1) // MUON digit maker from rawdata
+  AliMUONVDigitStore* fDigitStore; //!< not owner
+  AliMUONVTriggerStore* fTriggerStore; //!< not owner
+  
+  ClassDef(AliMUONDigitMaker,4) // MUON digit maker from rawdata
 };
        
 #endif
index 6df5a2d..0f576e5 100644 (file)
 
 #include "AliMUONDigitizerV3.h"
 
+#include "AliCDBManager.h"
+#include "AliLog.h"
 #include "AliMUON.h"
 #include "AliMUONCalibrationData.h"
-#include "AliCDBManager.h"
 #include "AliMUONConstants.h"
-#include "AliMUONSimData.h"
-#include "AliMUONDataIterator.h"
 #include "AliMUONDigit.h"
 #include "AliMUONLogger.h"
-#include "AliMUONSegmentation.h"
 #include "AliMUONTriggerEfficiencyCells.h"
 #include "AliMUONTriggerElectronics.h"
+#include "AliMUONTriggerStoreV1.h"
 #include "AliMUONVCalibParam.h"
-
+#include "AliMUONVDigitStore.h"
+#include "AliMpCathodType.h"
+#include "AliMpConstants.h"
 #include "AliMpDEIterator.h"
 #include "AliMpDEManager.h"
+#include "AliMpDEManager.h"
 #include "AliMpIntPair.h"
 #include "AliMpPad.h"
-#include "AliMpStationType.h"
 #include "AliMpSegmentation.h"
+#include "AliMpStationType.h"
 #include "AliMpVSegmentation.h"
-#include "AliMpDEManager.h"
-#include "AliMpCathodType.h"
-
 #include "AliRun.h"
 #include "AliRunDigitizer.h"
 #include "AliRunLoader.h"
-#include "AliLog.h"
-
 #include <Riostream.h>
 #include <TF1.h>
+#include <TFile.h>
 #include <TMath.h>
 #include <TRandom.h>
 #include <TString.h>
+#include <TSystem.h>
+
 ///
 /// \class AliMUONDigitizerV3
 /// The digitizer is performing the transformation to go from SDigits (digits
@@ -86,23 +86,23 @@ AliMUONDigitizerV3::AliMUONDigitizerV3(AliRunDigitizer* manager,
                                        Bool_t generateNoisyDigits)
 : AliDigitizer(manager),
 fIsInitialized(kFALSE),
-fOutputData(0x0),
 fCalibrationData(0x0),
 fTriggerProcessor(0x0),
 fTriggerEfficiency(0x0),
-fFindDigitIndexTimer(),
 fGenerateNoisyDigitsTimer(),
 fExecTimer(),
 fNoiseFunction(0x0),
   fGenerateNoisyDigits(generateNoisyDigits),
-  fLogger(new AliMUONLogger(1000))
+  fLogger(new AliMUONLogger(1000)),
+fTriggerStore(new AliMUONTriggerStoreV1),
+fDigitStore(0x0),
+fOutputDigitStore(0x0)
 {
   /// Ctor.
 
   AliDebug(1,Form("AliRunDigitizer=%p",fManager));
   fGenerateNoisyDigitsTimer.Start(kTRUE); fGenerateNoisyDigitsTimer.Stop();
   fExecTimer.Start(kTRUE); fExecTimer.Stop();
-  fFindDigitIndexTimer.Start(kTRUE); fFindDigitIndexTimer.Stop();
 }
 
 //_____________________________________________________________________________
@@ -112,13 +112,13 @@ AliMUONDigitizerV3::~AliMUONDigitizerV3()
 
   AliDebug(1,"dtor");
 
-  delete fOutputData;
   delete fCalibrationData;
   delete fTriggerProcessor;
   delete fNoiseFunction;
+  delete fTriggerStore;
+  delete fDigitStore;
+  delete fOutputDigitStore;
   
-  AliDebug(1, Form("Execution time for FindDigitIndex() : R:%.2fs C:%.2fs",
-               fFindDigitIndexTimer.RealTime(),fFindDigitIndexTimer.CpuTime()));
   if ( fGenerateNoisyDigits )
   {
     AliDebug(1, Form("Execution time for GenerateNoisyDigits() : R:%.2fs C:%.2fs",
@@ -136,7 +136,7 @@ AliMUONDigitizerV3::~AliMUONDigitizerV3()
 
 //_____________________________________________________________________________
 void 
-AliMUONDigitizerV3::ApplyResponseToTrackerDigit(AliMUONDigit& digit, Bool_t addNoise)
+AliMUONDigitizerV3::ApplyResponseToTrackerDigit(AliMUONVDigit& digit, Bool_t addNoise)
 {
   /// For tracking digits, starting from an ideal digit's charge, we :
   ///
@@ -147,11 +147,11 @@ AliMUONDigitizerV3::ApplyResponseToTrackerDigit(AliMUONDigit& digit, Bool_t addN
 
   static const Int_t kMaxADC = (1<<12)-1; // We code the charge on a 12 bits ADC.
   
-  Float_t signal = digit.Signal();
+  Float_t signal = digit.Charge();
   
   if ( !addNoise )
   {
-    digit.SetADC(TMath::Nint(signal));
+    digit.SetADC(TMath::Min(kMaxADC,TMath::Nint(signal)));
     return;
   }
   
@@ -166,8 +166,7 @@ AliMUONDigitizerV3::ApplyResponseToTrackerDigit(AliMUONDigit& digit, Bool_t addN
     fLogger->Log(Form("%s:%d:Could not get pedestal for DE=%4d manuId=%4d. Disabling.",
                       __FILE__,__LINE__,
                       detElemId,manuId));
-    digit.SetPhysicsSignal(0);
-    digit.SetSignal(0);
+    digit.SetCharge(0);
     digit.SetADC(0);
     return;    
   }
@@ -180,8 +179,7 @@ AliMUONDigitizerV3::ApplyResponseToTrackerDigit(AliMUONDigit& digit, Bool_t addN
     fLogger->Log(Form("%s:%d:Could not get gain for DE=%4d manuId=%4d. Disabling.",
                       __FILE__,__LINE__,
                       detElemId,manuId));
-    digit.SetPhysicsSignal(0);
-    digit.SetSignal(0);
+    digit.SetCharge(0);
     digit.SetADC(0);
     return;        
   }    
@@ -214,14 +212,14 @@ AliMUONDigitizerV3::ApplyResponseToTrackerDigit(AliMUONDigit& digit, Bool_t addN
     adc = kMaxADC;
   }
   
-  digit.SetPhysicsSignal(TMath::Nint(signal));
-  digit.SetSignal(adc);
+  digit.SetCharge(adc);
   digit.SetADC(adc);
 }
 
 //_____________________________________________________________________________
 void 
-AliMUONDigitizerV3::ApplyResponseToTriggerDigit(AliMUONDigit& digit)
+AliMUONDigitizerV3::ApplyResponseToTriggerDigit(const AliMUONVDigitStore& digitStore,
+                                                AliMUONVDigit& digit)
 {
   /// \todo add comment
 
@@ -229,7 +227,7 @@ AliMUONDigitizerV3::ApplyResponseToTriggerDigit(AliMUONDigit& digit)
 
   if (digit.IsEfficiencyApplied()) return;
 
-  AliMUONDigit* correspondingDigit = FindCorrespondingDigit(digit);
+  AliMUONVDigit* correspondingDigit = FindCorrespondingDigit(digitStore,digit);
 
   if (!correspondingDigit) return; //reject bad correspondences
 
@@ -263,111 +261,51 @@ AliMUONDigitizerV3::ApplyResponseToTriggerDigit(AliMUONDigit& digit)
 
   if (!isTrig[digit.Cathode()])
   {
-         digit.SetSignal(0);
+         digit.SetCharge(0);
   }
   
   if ( &digit != correspondingDigit )
   {
          if (!isTrig[correspondingDigit->Cathode()])
     {
-      correspondingDigit->SetSignal(0);
+      correspondingDigit->SetCharge(0);
          }
   }
 }
 
 //_____________________________________________________________________________
 void
-AliMUONDigitizerV3::ApplyResponse()
+AliMUONDigitizerV3::ApplyResponse(const AliMUONVDigitStore& store,
+                                  AliMUONVDigitStore& filteredStore)
 {
   /// Loop over all chamber digits, and apply the response to them
   /// Note that this method may remove digits.
 
+  filteredStore.Clear();
+  
   const Bool_t kAddNoise = kTRUE;
   
-  for ( Int_t ich = 0; ich < AliMUONConstants::NCh(); ++ich )
+  TIter next(store.CreateIterator());
+  AliMUONVDigit* digit;
+  
+  while ( ( digit = static_cast<AliMUONVDigit*>(next()) ) )
   {
-    TClonesArray* digits = fOutputData->Digits(ich);
-    Int_t n = digits->GetEntriesFast();
-    Bool_t trackingChamber = ( ich < AliMUONConstants::NTrackingCh() );
-    for ( Int_t i = 0; i < n; ++i )
+    AliMp::StationType stationType = AliMpDEManager::GetStationType(digit->DetElemId());
+    
+    if ( stationType != AliMp::kStationTrigger )
     {
-      AliMUONDigit* d = static_cast<AliMUONDigit*>(digits->UncheckedAt(i));
-      if ( !d ) continue; // that digit might have been removed
-      if ( trackingChamber )
-      {
-        ApplyResponseToTrackerDigit(*d,kAddNoise);
-      }
-      else
-      {
-        ApplyResponseToTriggerDigit(*d);
-      }
-      if ( d->Signal() <= 0 )
-      {
-        digits->RemoveAt(i);
-      }
+      ApplyResponseToTrackerDigit(*digit,kAddNoise);
     }
-    digits->Compress(); // only do the compress at the end in order not to
-    // change the n = digits->GetEntriesFast()
-  }    
-  
-// The version below, using iterator, does not yet work (as the iterator
-// assumes it is reading digits from the tree, while in this case it's
-// writing...)
-//
-//  AliMUONDigit* digit(0x0);
-//
-//  // First loop on tracker digits
-//  AliMUONDataIterator tracker(fOutputData,"D",AliMUONDataIterator::kTrackingChambers);
-//  
-//  while ( ( digit = static_cast<AliMUONDigit*>(tracker.Next()) ) )
-//  {
-//    ApplyResponseToTrackerDigit(*digit);
-//    if ( digit->Signal() <= 0 )
-//    {
-//      tracker.Remove();
-//    }    
-//    
-//  }
-//
-//  // Then loop on trigger digits
-//  AliMUONDataIterator trigger(fOutputData,"D",AliMUONDataIterator::kTriggerChambers);
-//  
-//  while ( ( digit = static_cast<AliMUONDigit*>(trigger.Next()) ) )
-//  {
-//    ApplyResponseToTriggerDigit(*digit,fOutputData);
-//    if ( digit->Signal() <= 0 )
-//    {
-//      trigger.Remove();
-//    }    
-//  }
-}
-
-//_____________________________________________________________________________
-void
-AliMUONDigitizerV3::AddOrUpdateDigit(TClonesArray& array, 
-                                     const AliMUONDigit& digit)
-{
-  /// Add or update a digit, depending on whether there's already a digit
-  /// for the corresponding channel.
-
-  Int_t ix = FindDigitIndex(array,digit);
-  
-  if (ix>=0)
-  {
-    AliMUONDigit* d = static_cast<AliMUONDigit*>(array.UncheckedAt(ix));
-    Bool_t ok = MergeDigits(digit,*d);
-    if (!ok)
+    else
     {
-      AliError("Digits are not mergeable !");
+      ApplyResponseToTriggerDigit(store,*digit);
+    }
+    if ( digit->Charge() > 0  )
+    {
+      filteredStore.Add(*digit,AliMUONVDigitStore::kIgnore);
     }
   }
-  else
-  {
-    ix = array.GetLast() + 1;
-    new(array[ix]) AliMUONDigit(digit);
-  }
-  
-}
+}    
 
 //_____________________________________________________________________________
 void
@@ -397,33 +335,42 @@ AliMUONDigitizerV3::Exec(Option_t*)
 
   Int_t nInputFiles = fManager->GetNinputs();
   
-  if ( fOutputData->TreeD() == 0x0 )
+  AliLoader* outputLoader = GetLoader(fManager->GetOutputFolderName());
+  
+  outputLoader->MakeDigitsContainer();
+  
+  TTree* oTreeD = outputLoader->TreeD();
+  
+  if (!oTreeD) 
   {
-    AliDebug(2,"Calling MakeDigitsContainer");
-    fOutputData->GetLoader()->MakeDigitsContainer();
+    AliFatal("Cannot create output TreeD");
   }
-  fOutputData->MakeBranch("D,GLT");
-  fOutputData->SetTreeAddress("D,GLT");
-  
+
   // Loop over all the input files, and merge the sdigits found in those
   // files.
+  
   for ( Int_t iFile = 0; iFile < nInputFiles; ++iFile )
   {    
-    AliMUONSimData* inputData = GetDataAccess(fManager->GetInputFolderName(iFile));
-    if (!inputData)
+    AliLoader* inputLoader = GetLoader(fManager->GetInputFolderName(iFile));
+
+    inputLoader->LoadSDigits("READ");
+
+    TTree* iTreeS = inputLoader->TreeS();
+    if (!iTreeS)
     {
       AliFatal(Form("Could not get access to input file #%d",iFile));
     }
+    
+    AliMUONVDigitStore* inputStore = AliMUONVDigitStore::Create(*iTreeS);
+    inputStore->Connect(*iTreeS);
+    
+    iTreeS->GetEvent(0);
+    
+    MergeWithSDigits(fDigitStore,*inputStore,fManager->GetMask(iFile));
 
-    inputData->GetLoader()->LoadSDigits("READ");
-    inputData->SetTreeAddress("S");
-    inputData->GetSDigits();
-
-    MergeWithSDigits(*fOutputData,*inputData,fManager->GetMask(iFile));
+    inputLoader->UnloadSDigits();
     
-    inputData->ResetSDigits();
-    inputData->GetLoader()->UnloadSDigits();
-    delete inputData;
+    delete inputStore;
   }
   
   // At this point, we do have digit arrays (one per chamber) which contains 
@@ -431,109 +378,76 @@ AliMUONDigitizerV3::Exec(Option_t*)
   // We now massage them to apply the detector response, i.e. this
   // is here that we do the "digitization" work.
   
-  ApplyResponse();
+  if (!fOutputDigitStore)
+  {
+    fOutputDigitStore = fDigitStore->Create();
+  }
+  
+  ApplyResponse(*fDigitStore,*fOutputDigitStore);
   
   if ( fGenerateNoisyDigits )
   {
     // Generate noise-only digits for tracker.
-    GenerateNoisyDigits();
+    GenerateNoisyDigits(*fOutputDigitStore);
   }
   
   // We generate the global and local trigger decisions.
-  fTriggerProcessor->ExecuteTask();
+  fTriggerProcessor->Digits2Trigger(*fOutputDigitStore,*fTriggerStore);
+
+  // Prepare output tree
+  Bool_t okD = fOutputDigitStore->Connect(*oTreeD,kFALSE);
+  Bool_t okT = fTriggerStore->Connect(*oTreeD,kFALSE);
+  if (!okD || !okT)
+  {
+    AliError(Form("Could not make branch : Digit %d Trigger %d",okD,okT));
+    return;
+  }
   
   // Fill the output treeD
-  fOutputData->Fill("D,GLT");
+  oTreeD->Fill();
   
   // Write to the output tree(D).
   // Please note that as GlobalTrigger, LocalTrigger and Digits are in the same
   // tree (=TreeD) in different branches, this WriteDigits in fact writes all of 
   // the 3 branches.
-  fOutputData->GetLoader()->WriteDigits("OVERWRITE");
+  outputLoader->WriteDigits("OVERWRITE");  
   
-  // Finally, we clean up after ourselves.
-  fOutputData->ResetDigits();
-  fOutputData->ResetTrigger();
-  fOutputData->GetLoader()->UnloadDigits();
+  outputLoader->UnloadDigits();
   
+  // Finally, we clean up after ourselves.
+  fTriggerStore->Clear();
+  fDigitStore->Clear();
+  fOutputDigitStore->Clear();
   fExecTimer.Stop();
 }
 
 //_____________________________________________________________________________
-AliMUONDigit* 
-AliMUONDigitizerV3::FindCorrespondingDigit(AliMUONDigit& digit) const
+AliMUONVDigit* 
+AliMUONDigitizerV3::FindCorrespondingDigit(const AliMUONVDigitStore& digitStore,
+                                           AliMUONVDigit& digit) const
 {                                                
   /// Find, if it exists, the digit corresponding to digit.Hit(), in the 
   /// other cathode
 
-// Iterator does not yet work when writing digits (only works when reading,
-// which is not the case here)
-//
-//  AliMUONDataIterator it(data,"D",AliMUONDataIterator::kTriggerChambers);
-//  AliMUONDigit* cd;
-//
-//  while ( ( cd = static_cast<AliMUONDigit*>(it.Next()) ) )
-//  {
-//    if ( cd->DetElemId() == digit.DetElemId() &&
-//         cd->Hit() == digit.Hit() &&
-//         cd->Cathode() != digit.Cathode() )
-//    {
-//      break;
-//    }
-//  }
-  
-  Int_t ich = AliMpDEManager::GetChamberId(digit.DetElemId());  
-  TClonesArray* digits = fOutputData->Digits(ich);
-  Int_t n = digits->GetEntriesFast();
-  for ( Int_t i = 0; i < n; ++i )
+  TIter next(digitStore.CreateIterator());
+  AliMUONVDigit* d;
+  
+  while ( ( d = static_cast<AliMUONVDigit*>(next()) ) )
   {
-    AliMUONDigit* d = static_cast<AliMUONDigit*>(digits->UncheckedAt(i));
-    if ( d &&
-         d->DetElemId() == digit.DetElemId() &&
+    if ( d->DetElemId() == digit.DetElemId() &&
          d->Hit() == digit.Hit() &&
          d->Cathode() != digit.Cathode() )
     {
       return d;
     }      
   }    
-
   return 0x0;
 }
 
 
 //_____________________________________________________________________________
-Int_t
-AliMUONDigitizerV3::FindDigitIndex(TClonesArray& array, 
-                                   const AliMUONDigit& digit) const
-{
-  /// Return the index of digit within array, if that digit is there, 
-  /// otherwise returns -1
-  ///
-  /// \todo FIXME: this is of course not the best implementation you can think of.
-  /// Reconsider the use of hit/digit map... ? (but be sure it's needed!)
-  
-  fFindDigitIndexTimer.Start(kFALSE);
-  
-  Int_t n = array.GetEntriesFast();
-  for ( Int_t i = 0; i < n; ++i )
-  {
-    AliMUONDigit* d = static_cast<AliMUONDigit*>(array.UncheckedAt(i));
-    if ( d->DetElemId() == digit.DetElemId() &&
-         d->PadX() == digit.PadX() &&
-         d->PadY() == digit.PadY() && 
-         d->Cathode() == digit.Cathode() )
-    {
-      fFindDigitIndexTimer.Stop();
-      return i;
-    }
-  }
-  fFindDigitIndexTimer.Stop();
-  return -1;
-}
-
-//_____________________________________________________________________________
 void
-AliMUONDigitizerV3::GenerateNoisyDigits()
+AliMUONDigitizerV3::GenerateNoisyDigits(AliMUONVDigitStore& digitStore)
 {
   /// According to a given probability, generate digits that
   /// have a signal above the noise cut (ped+n*sigma_ped), i.e. digits
@@ -559,7 +473,7 @@ AliMUONDigitizerV3::GenerateNoisyDigits()
     {
       for ( Int_t cathode = 0; cathode < 2; ++cathode )
       {
-        GenerateNoisyDigitsForOneCathode(it.CurrentDEId(),cathode);
+        GenerateNoisyDigitsForOneCathode(digitStore,it.CurrentDEId(),cathode);
       }
       it.Next();
     }
@@ -570,14 +484,12 @@ AliMUONDigitizerV3::GenerateNoisyDigits()
  
 //_____________________________________________________________________________
 void
-AliMUONDigitizerV3::GenerateNoisyDigitsForOneCathode(Int_t detElemId, Int_t cathode)
+AliMUONDigitizerV3::GenerateNoisyDigitsForOneCathode(AliMUONVDigitStore& digitStore,
+                                                     Int_t detElemId, Int_t cathode)
 {
   /// Generate noise-only digits for one cathode of one detection element.
   /// Called by GenerateNoisyDigits()
   
-  Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
-  TClonesArray* digits = fOutputData->Digits(chamberId);
-  
   const AliMpVSegmentation* seg 
     = AliMpSegmentation::Instance()->GetMpSegmentation(detElemId,AliMp::GetCathodType(cathode));
   Int_t nofPads = seg->NofPads();
@@ -596,86 +508,79 @@ AliMUONDigitizerV3::GenerateNoisyDigitsForOneCathode(Int_t detElemId, Int_t cath
   
   AliDebug(3,Form("DE %d cath %d nofNoisyPads %d",detElemId,cathode,nofNoisyPads));
   
-  for ( Int_t i = 0; i < nofNoisyPads; ++i )
+  for ( Int_t i = 0; i < nofNoisyPads; ++i ) 
   {
     Int_t ix(-1);
     Int_t iy(-1);
+    AliMpPad pad;
+    
     do {
       ix = gRandom->Integer(maxIx+1);
       iy = gRandom->Integer(maxIy+1);
-    } while ( !seg->HasPad(AliMpIntPair(ix,iy)) );
-    AliMUONDigit d;
-    d.SetDetElemId(detElemId);
-    d.SetCathode(cathode);
-    d.SetPadX(ix);
-    d.SetPadY(iy);
-    if ( FindDigitIndex(*digits,d) >= 0 )
-    {
-      // this digit is already there, and not noise-only, we simply skip it
-      continue;
-    }
-    AliMpPad pad = seg->PadByIndices(AliMpIntPair(ix,iy));
+      pad = seg->PadByIndices(AliMpIntPair(ix,iy),kFALSE);
+    } while ( !pad.IsValid() );
+
     Int_t manuId = pad.GetLocation().GetFirst();
-    Int_t manuChannel = pad.GetLocation().GetSecond();
-    
-    d.SetElectronics(manuId,manuChannel);
-    
+    Int_t manuChannel = pad.GetLocation().GetSecond();    
+
     AliMUONVCalibParam* pedestals = fCalibrationData->Pedestals(detElemId,manuId);
     
     if (!pedestals) 
     {
       // no pedestal available for this channel, simply give up
-      return;
+      continue;
     }
     
+    AliMUONVDigit* d = digitStore.CreateDigit(detElemId,manuId,manuChannel,cathode);
+    
+    d->SetPadXY(ix,iy);
+    
     Float_t pedestalMean = pedestals->ValueAsFloat(manuChannel,0);
     Float_t pedestalSigma = pedestals->ValueAsFloat(manuChannel,1);
     
     Double_t ped = fNoiseFunction->GetRandom()*pedestalSigma;
 
-    d.SetSignal(TMath::Nint(ped+pedestalMean+0.5));
-    d.SetPhysicsSignal(0);
-    d.NoiseOnly(kTRUE);
-    AliDebug(3,Form("Adding a pure noise digit :"));
-//    StdoutToAliDebug(3,cout << "Before Response: " << endl; 
-//                     d.Print(););
-    ApplyResponseToTrackerDigit(d,kFALSE);
-    if ( d.Signal() > 0 )
+    d->SetCharge(TMath::Nint(ped+pedestalMean+0.5));
+    d->NoiseOnly(kTRUE);
+    ApplyResponseToTrackerDigit(*d,kFALSE);
+    if ( d->Charge() > 0 )
     {
-      AddOrUpdateDigit(*digits,d);
+      Bool_t ok = digitStore.Add(*d,AliMUONVDigitStore::kDeny);
+      // this can happen (that we randomly chose a digit that is
+      // already there). We simply ignore this, but log the occurence
+      // to cross-check that it's not too frequent.
+      if (!ok)
+      {
+        fLogger->Log("Collision while adding noiseOnly digit");
+      }
+      else
+      {
+        fLogger->Log("Added noiseOnly digit");
+      }
     }
     else
     {
       AliError("Pure noise below threshold. This should not happen. Not adding "
                "this digit.");
     }
-//    StdoutToAliDebug(3,cout << "After Response: " << endl; 
-//                     d.Print(););
+    delete d;
   }
 }
 
 //_____________________________________________________________________________
-AliMUONSimData* 
-AliMUONDigitizerV3::GetDataAccess(const TString& folderName)
+AliLoader*
+AliMUONDigitizerV3::GetLoader(const TString& folderName)
 {
-  /// Create an AliMUONSimData to deal with data found in folderName.
+  /// Get a MUON loader
 
   AliDebug(2,Form("Getting access to folder %s",folderName.Data()));
-  AliRunLoader* runLoader = AliRunLoader::GetRunLoader(folderName);
-  if (!runLoader)
-  {
-    AliError(Form("Could not get RunLoader from folder %s",folderName.Data()));
-    return 0x0;
-  }
-  AliLoader* loader = static_cast<AliLoader*>(runLoader->GetLoader("MUONLoader"));
+  AliLoader* loader = AliRunLoader::GetDetectorLoader("MUON",folderName.Data());
   if (!loader)
   {
     AliError(Form("Could not get MuonLoader from folder %s",folderName.Data()));
     return 0x0;
   }
-  AliMUONSimData* data = new AliMUONSimData(loader,"MUON","MUONDataForDigitOutput");
-  AliDebug(2,Form("AliMUONSimData=%p loader=%p",data,loader));
-  return data;
+  return loader;
 }
 
 //_____________________________________________________________________________
@@ -683,9 +588,8 @@ Bool_t
 AliMUONDigitizerV3::Init()
 {
   /// Initialization of the TTask :
-  /// a) set the outputData pointer
-  /// b) create the calibrationData, according to run number
-  /// c) create the trigger processing task
+  /// a) create the calibrationData, according to run number
+  /// b) create the trigger processing task
 
   AliDebug(2,"");
   
@@ -701,14 +605,6 @@ AliMUONDigitizerV3::Init()
     return kFALSE;
   }
   
-  fOutputData = GetDataAccess(fManager->GetOutputFolderName());
-  if (!fOutputData)
-  {
-    AliError("Can not perform digitization. I'm sorry");
-    return kFALSE;
-  }
-  AliDebug(2,Form("fOutputData=%p",fOutputData));
-  
   Int_t runnumber = AliCDBManager::Instance()->GetRun();
   
   fCalibrationData = new AliMUONCalibrationData(runnumber);
@@ -720,7 +616,7 @@ AliMUONDigitizerV3::Init()
   {
     AliFatal("Could not access gains from OCDB !");
   }
-  fTriggerProcessor = new AliMUONTriggerElectronics(fOutputData,fCalibrationData);
+  fTriggerProcessor = new AliMUONTriggerElectronics(fCalibrationData);
   
   if ( muon()->GetTriggerEffCells() )
   {
@@ -744,70 +640,29 @@ AliMUONDigitizerV3::Init()
 }
 
 //_____________________________________________________________________________
-Bool_t
-AliMUONDigitizerV3::MergeDigits(const AliMUONDigit& src, 
-                                AliMUONDigit& srcAndDest)
-{
-  /// Merge 2 digits (src and srcAndDest) into srcAndDest.
-
-  AliDebug(2,"Merging the following digits:");
-//  StdoutToAliDebug(2,src.Print("tracks"););
-//  StdoutToAliDebug(2,srcAndDest.Print("tracks"););
-  
-  Bool_t check = ( src.DetElemId() == srcAndDest.DetElemId() &&
-                   src.PadX() == srcAndDest.PadX() &&
-                   src.PadY() == srcAndDest.PadY() &&
-                   src.Cathode() == srcAndDest.Cathode() );
-  if (!check)
-  {
-    return kFALSE;
-  }
-  
-  srcAndDest.AddSignal(src.Signal());
-  srcAndDest.AddPhysicsSignal(src.Physics());
-  for ( Int_t i = 0; i < src.Ntracks(); ++i )
-  {
-    srcAndDest.AddTrack(src.Track(i),src.TrackCharge(i));
-  }
-//  StdoutToAliDebug(2,cout << "result:"; srcAndDest.Print("tracks"););
-  return kTRUE;
-}
-
-//_____________________________________________________________________________
 void 
-AliMUONDigitizerV3::MergeWithSDigits(AliMUONSimData& outputData, 
-                                     const AliMUONSimData& inputData, Int_t mask)
+AliMUONDigitizerV3::MergeWithSDigits(AliMUONVDigitStore*& outputStore,
+                                     const AliMUONVDigitStore& input,
+                                     Int_t mask)
 {
   /// Merge the sdigits in inputData with the digits already present in outputData
-
-  AliDebug(2,"");
   
-       for ( Int_t ich = 0; ich < AliMUONConstants::NCh(); ++ich )
-       {
-    TClonesArray* iDigits = inputData.SDigits(ich); 
-    TClonesArray* oDigits = outputData.Digits(ich);
-    if (!iDigits)
+  if ( !outputStore ) outputStore = input.Create();
+  
+  TIter next(input.CreateIterator());
+  AliMUONVDigit* sdigit;
+  
+  while ( ( sdigit = static_cast<AliMUONVDigit*>(next()) ) )
+  {
+    // Update the track references using the mask.
+    // FIXME: this is dirty, for backward compatibility only.
+    // Should re-design all this way of keeping track of MC information...
+    if ( mask ) sdigit->PatchTracks(mask);
+    // Then add or update the digit to the output.
+    AliMUONVDigit* added = outputStore->Add(*sdigit,AliMUONVDigitStore::kMerge);
+    if (!added)
     {
-      AliError(Form("Could not get sdigits for ich=%d",ich));
-      return;
+      AliError("Could not add digit in merge mode");
     }
-    Int_t nSDigits = iDigits->GetEntriesFast();
-    for ( Int_t k = 0; k < nSDigits; ++k )
-               {
-                       AliMUONDigit* sdigit = static_cast<AliMUONDigit*>(iDigits->UncheckedAt(k));
-      if (!sdigit)
-      {
-        AliError(Form("Could not get sdigit for ich=%d and k=%d",ich,k));
-      }
-      else
-      {
-        // Update the track references using the mask.
-        // FIXME: this is dirty, for backward compatibility only.
-        // Should re-design all this way of keeping track of MC information...
-        if ( mask ) sdigit->PatchTracks(mask);
-        // Then add or update the digit to the output.
-        AddOrUpdateDigit(*oDigits,*sdigit);
-      }
-    }   
   }
 }
index aad00e7..68f4de9 100644 (file)
 #endif
 
 class AliMUONCalibrationData;
-class AliMUONSimData;
-class AliMUONDigit;
+class AliMUONVDigit;
 class AliMUONLogger;
 class AliMUONTriggerEfficiencyCells;
 class TClonesArray;
 class TF1;
 class TString;
+class AliMUONVDigitStore;
+class AliLoader;
+class AliMUONVTriggerStore;
+class AliMUONTriggerElectronics;
 
 class AliMUONDigitizerV3 : public AliDigitizer
 {
@@ -45,37 +48,32 @@ private:
   AliMUONDigitizerV3(const AliMUONDigitizerV3& other);
   /// Not implemented
   AliMUONDigitizerV3& operator=(const AliMUONDigitizerV3& other);
-  
-  void AddOrUpdateDigit(TClonesArray& array, 
-                        const AliMUONDigit& digit);
     
-  void ApplyResponse();
+  void ApplyResponse(const AliMUONVDigitStore& store, AliMUONVDigitStore& filteredStore);
 
-  void ApplyResponseToTrackerDigit(AliMUONDigit& digit, Bool_t addNoise);
-  void ApplyResponseToTriggerDigit(AliMUONDigit& digit);
+  void ApplyResponseToTrackerDigit(AliMUONVDigit& digit, Bool_t addNoise);
+  void ApplyResponseToTriggerDigit(const AliMUONVDigitStore& digitStore, AliMUONVDigit& digit);
 
-private:  
-  AliMUONDigit* FindCorrespondingDigit(AliMUONDigit& digit) const;
+  AliLoader* GetLoader(const TString& foldername);
   
-  Int_t FindDigitIndex(TClonesArray& array, const AliMUONDigit& digit) const;
-
-  void GenerateNoisyDigits();
-  void GenerateNoisyDigitsForOneCathode(Int_t detElemId, Int_t cathode);
+private:  
 
-  AliMUONSimData* GetDataAccess(const TString& folderName);
+  AliMUONVDigit* FindCorrespondingDigit(const AliMUONVDigitStore& digitStore,
+                                       AliMUONVDigit& digit) const;
 
-  Bool_t MergeDigits(const AliMUONDigit& src, AliMUONDigit& srcAndDest);
+  void GenerateNoisyDigits(AliMUONVDigitStore& digitStore);
+  void GenerateNoisyDigitsForOneCathode(AliMUONVDigitStore& digitStore, 
+                                        Int_t detElemId, Int_t cathode);
 
-  void MergeWithSDigits(AliMUONSimData& outputData, const AliMUONSimData& inputData, 
+  void MergeWithSDigits(AliMUONVDigitStore*& digitStore,
+                        const AliMUONVDigitStore& input,
                         Int_t mask);
   
 private:
   Bool_t fIsInitialized; ///< are we initialized ?
-  AliMUONSimData* fOutputData; //!< pointer to access digits
   AliMUONCalibrationData* fCalibrationData; //!< pointer to access calib parameters
-  TTask* fTriggerProcessor; ///< pointer to the trigger part of the job
+  AliMUONTriggerElectronics* fTriggerProcessor; ///< pointer to the trigger part of the job
   AliMUONTriggerEfficiencyCells* fTriggerEfficiency; ///< trigger efficiency map  
-  mutable TStopwatch fFindDigitIndexTimer; //!< counting time spent in FindDigitIndex
   TStopwatch fGenerateNoisyDigitsTimer; //!< counting time spent in GenerateNoisyDigits()
   TStopwatch fExecTimer; //!< couting time spent in Exec()  
   TF1* fNoiseFunction; //!< function to randomly get signal above n*sigma_ped
@@ -83,8 +81,11 @@ private:
   static const Double_t fgkNSigmas; ///< \brief number of sigmas above ped to use 
   /// for noise-only digit generation and zero-suppression
   AliMUONLogger* fLogger; //!< to keep track of messages
+  AliMUONVTriggerStore* fTriggerStore; //!< trigger objects
+  AliMUONVDigitStore* fDigitStore; //!< temporary digits
+  AliMUONVDigitStore* fOutputDigitStore; //!< digits we'll output to disk
   
-  ClassDef(AliMUONDigitizerV3,4) // MUON Digitizer V3-3
+  ClassDef(AliMUONDigitizerV3,5) // MUON Digitizer V3-5
 };
 
 #endif