]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - MUON/AliMUONDigitMaker.cxx
Fixed memory leak
[u/mrichter/AliRoot.git] / MUON / AliMUONDigitMaker.cxx
index 75e6301466305e42b458cb951fa3f535c84ae227..3463933c7784c5c92cefefc97d0de6947f16554b 100644 (file)
  * provided "as is" without express or implied warranty.                  *
  **************************************************************************/
 
-////////////////////////////////////
-///
+// $Id$
+
+//-----------------------------------------------------------------------------
+/// \class AliMUONDigitMaker
 /// MUON Digit maker from rawdata.
 ///
 /// Raw2Digits:
 ///
 /// Add (S)Digit maker tracker (for free)
 /// and for trigger. Create trigger inverse mapping.
-/// (Ch. Finck, oct 06) 
-////////////////////////////////////
-
-#include <fstream>
-#include <string>
-
-#include <TClonesArray.h>
-#include <TList.h>
-
-#include "AliRawReader.h"
-#include "AliRawDataHeader.h"
-#include "AliLog.h"
-#include "AliRun.h"
+///
+/// \author Ch. Finck, oct 06 
+//-----------------------------------------------------------------------------
 
-#include "AliMpBusPatch.h"
-#include "AliMUON.h"
 #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 "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 "AliMUONTriggerCircuitNew.h"
-#include "AliMpSegFactory.h"
-#include "AliMpVSegmentation.h"
-#include "AliMpPad.h"
+#include "AliMUONLogger.h"
+#include "AliMUONRawStreamTrackerHP.h"
+#include "AliMUONRawStreamTriggerHP.h"
+#include "AliMUONRegHeader.h"
+#include "AliMUONVTriggerStore.h"
+#include "AliMpCDB.h"
+#include "AliMpDetElement.h"
+#include "AliMpTriggerCrate.h"
+#include "AliMpLocalBoard.h"
+#include "AliMpCathodType.h"
+#include "AliMpDDLStore.h"
 #include "AliMpDEManager.h"
+#include "AliMpPad.h"
+#include "AliMpSegmentation.h"
+#include "AliMpVSegmentation.h"
+#include "AliCodeTimer.h"
+#include "AliLog.h"
+#include "AliRawReader.h"
+#include <TArrayS.h>
 
+using std::endl;
+using std::cout;
+/// \cond CLASSIMP
 ClassImp(AliMUONDigitMaker) // Class implementation in ROOT context
+/// \endcond
+
+//__________________________________________________________________________
+AliMUONDigitMaker::AliMUONDigitMaker(Bool_t enableErrorLogger, Bool_t a, Bool_t b) :
+TObject(),
+fScalerEvent(kFALSE),
+fMakeTriggerDigits(kFALSE),
+fRawStreamTracker(new AliMUONRawStreamTrackerHP),
+fRawStreamTrigger(new AliMUONRawStreamTriggerHP),
+fDigitStore(0x0),
+fTriggerStore(0x0),
+fLogger(new AliMUONLogger(10000)){
+  /// ctor 
+  
+  if  ( !a || !b ) AliFatal("no longer supported");
+  
+  AliDebug(1,"");
+  
+  // Standard Constructor
+  if (enableErrorLogger) 
+  {
+    fRawStreamTracker->EnabbleErrorLogger();
+    fRawStreamTrigger->EnabbleErrorLogger();
+  }
+  else
+  {
+    fRawStreamTracker->DisableWarnings();
+  }
+  
+  SetMakeTriggerDigits();
+  
+  // Load mapping
+  if ( ! AliMpCDB::LoadDDLStore() ) {
+    AliFatal("Could not access mapping from OCDB !");
+  }
+}
+
 //__________________________________________________________________________
-AliMUONDigitMaker::AliMUONDigitMaker(Bool_t flag)
-  : TObject(),
-    fMUONData(0x0),
-    fSegFactory(new AliMpSegFactory()),
-    fBusPatchManager(new AliMpBusPatch()),
+AliMUONDigitMaker::AliMUONDigitMaker(Bool_t enableErrorLogger) :
+TObject(),
     fScalerEvent(kFALSE),
-    fDigitFlag(flag),
-    fRawStreamTracker(new AliMUONRawStreamTracker()),    
-    fRawStreamTrigger(new AliMUONRawStreamTrigger()),    
-    fDigit(new AliMUONDigit()),
-    fLocalTrigger(new AliMUONLocalTrigger()),
-    fGlobalTrigger(new AliMUONGlobalTrigger()),
-    fCrateManager(new AliMUONTriggerCrateStore()),
-    fTrackerTimer(),
-    fTriggerTimer(),
-    fMappingTimer()
+    fMakeTriggerDigits(kFALSE),
+    fRawStreamTracker(new AliMUONRawStreamTrackerHP),
+    fRawStreamTrigger(new AliMUONRawStreamTriggerHP),
+    fDigitStore(0x0),
+    fTriggerStore(0x0),
+  fLogger(new AliMUONLogger(10000))
 {
-  //
-  // ctor with AliMUONData as argument
-  // for reconstruction
-  //
+  /// ctor 
 
   AliDebug(1,"");
-
+  
   // Standard Constructor
+  if (enableErrorLogger) 
+  {
+    fRawStreamTracker->EnabbleErrorLogger();
+    fRawStreamTrigger->EnabbleErrorLogger();
+  }
+  else
+  {
+    fRawStreamTracker->DisableWarnings();
+  }
 
-  // bus patch 
-  fBusPatchManager->ReadBusPatchFile();
-
-  // Crate manager
-  fCrateManager->ReadFromFile();
-
-  fTrackerTimer.Start(kTRUE); fTrackerTimer.Stop();
-  fTriggerTimer.Start(kTRUE); fTriggerTimer.Stop();
-  fMappingTimer.Start(kTRUE); fMappingTimer.Stop();
+  SetMakeTriggerDigits();
 
+  // Load mapping
+  if ( ! AliMpCDB::LoadDDLStore() ) {
+    AliFatal("Could not access mapping from OCDB !");
+  }
 }
 
 //__________________________________________________________________________
 AliMUONDigitMaker::~AliMUONDigitMaker()
 {
-  //
-  // clean up
-  // and time processing measure
-  //
-  delete fSegFactory;  
+  /// clean up
+  /// and time processing measure
 
   delete fRawStreamTracker;
   delete fRawStreamTrigger;
-
-  delete fDigit;
-  delete fLocalTrigger;
-  delete fGlobalTrigger;
-
-  delete fCrateManager;
-
-  delete fBusPatchManager;
-
-  AliInfo(Form("Execution time for MUON tracker : R:%.2fs C:%.2fs",
-               fTrackerTimer.RealTime(),fTrackerTimer.CpuTime()));
-  AliInfo(Form("   Execution time for MUON tracker (mapping calls part) "
-               ": R:%.2fs C:%.2fs",
-               fMappingTimer.RealTime(),fMappingTimer.CpuTime()));
-  AliInfo(Form("Execution time for MUON trigger : R:%.2fs C:%.2fs",
-               fTriggerTimer.RealTime(),fTriggerTimer.CpuTime()));
-
-  return;
+  delete fLogger;
 }
 
 //____________________________________________________________________
-Int_t AliMUONDigitMaker::Raw2Digits(AliRawReader* rawReader)
+void
+AliMUONDigitMaker::Print(Option_t*) const
 {
-  // Main method to creates digit
-  // for tracker 
-  // and trigger
+  /// Printout
 
-  // generate digits
-  ReadTrackerDDL(rawReader);
+  cout << "RawStreamerTracker class=" << fRawStreamTracker->ClassName()
+       << " MakeTriggerDigits=" << fMakeTriggerDigits
+       << " ScalerEvent=" << fScalerEvent
+       << " DigitStore=" << fDigitStore
+       << " TriggerStore=" << fTriggerStore << endl;
 
-  // generate trigger
-  ReadTriggerDDL(rawReader);
+  if ( fLogger ) fLogger->Print();
+}
 
-  return kTRUE;
+//____________________________________________________________________
+Int_t
+AliMUONDigitMaker::Raw2Digits(AliRawReader* rawReader, 
+                                        AliMUONVDigitStore* digitStore,
+                                        AliMUONVTriggerStore* triggerStore)
+{
+  /// Main method to creates digit
+  /// for tracker 
+  /// and trigger
 
+  AliDebug(1,Form("rawReader=%p digitStore=%p triggerStore=%p",
+                  rawReader,digitStore,triggerStore));
+  
+  fDigitStore = digitStore;
+  fTriggerStore = triggerStore;
+  
+  if (!fDigitStore && !fTriggerStore)
+  {
+    fLogger->Log("No digit or trigger store given. Nothing to do...");
+    return kTriggerBAD & kTrackerBAD;
+  }
+  
+  Int_t tracker(kOK);
+  Int_t trigger(kOK);
+  
+  if ( fDigitStore ) 
+  {
+    fDigitStore->Clear(); // insure we start with an empty container
+    tracker = ReadTrackerDDL(rawReader);
+  }
+  
+  if ( fTriggerStore || fMakeTriggerDigits ) 
+  {
+    if ( fTriggerStore ) fTriggerStore->Clear();
+    if ( fMakeTriggerDigits && !fDigitStore ) 
+    {
+      fLogger->Log("Asking for trigger digits but digitStore is null");
+    }
+    else
+    {
+      trigger = ReadTriggerDDL(rawReader);
+    }
+  }
+  
+  return tracker | trigger;
 }
 
 //____________________________________________________________________
-Int_t AliMUONDigitMaker::ReadTrackerDDL(AliRawReader* rawReader)
+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
-  //
-  fTrackerTimer.Start(kFALSE);
+  AliDebug(1,"");
+  
+  AliCodeTimerAuto("",0);
 
   // elex info
   Int_t    buspatchId;
   UChar_t  channelId;
   UShort_t manuId;
-  Char_t   parity;
   UShort_t charge; 
-  Int_t    dataSize;
-
-  Int_t iChamber;
-
-  AliMUONDDLTracker*   ddlTracker = 0x0;
-  AliMUONBlockHeader*  blkHeader  = 0x0;
-  AliMUONDspHeader*    dspHeader  = 0x0;
-  AliMUONBusStruct*    busStruct  = 0x0;
-
 
   fRawStreamTracker->SetReader(rawReader);
+  fRawStreamTracker->First();
+  
+  while ( fRawStreamTracker->Next(buspatchId,manuId,channelId,charge,kTRUE) )
+  {    
+    // getting DE from buspatch
+    Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(buspatchId);
 
-  while(fRawStreamTracker->NextDDL()) {
-
-    ddlTracker =  fRawStreamTracker->GetDDLTracker();
-
-    Int_t nBlock = ddlTracker->GetBlkHeaderEntries();
-    for(Int_t iBlock = 0; iBlock < nBlock ;iBlock++){
-
-      blkHeader = ddlTracker->GetBlkHeaderEntry(iBlock);
-      Int_t nDsp = blkHeader->GetDspHeaderEntries();
-
-      for(Int_t iDsp = 0; iDsp < nDsp ;iDsp++){   //DSP loop
-
-       dspHeader =  blkHeader->GetDspHeaderEntry(iDsp);
-
-       Int_t nBusPatch = dspHeader->GetBusPatchEntries();
-
-       for(Int_t iBusPatch = 0; iBusPatch < nBusPatch; iBusPatch++) {  
-
-         busStruct = dspHeader->GetBusPatchEntry(iBusPatch);
-
-         dataSize   = busStruct->GetLength();
-         buspatchId = busStruct->GetBusPatchId();
-
-         for (Int_t iData = 0; iData < dataSize; iData++) {
+    AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
 
-           // digits info
-           parity    = busStruct->GetParity(iData); // test later for parity
-           manuId    = busStruct->GetManuId(iData);
-           channelId = busStruct->GetChannelId(iData);
-           charge    = busStruct->GetCharge(iData);
-           // set charge
-           fDigit->SetSignal(charge);
-           fDigit->SetPhysicsSignal(charge);
-           fDigit->SetADC(charge);
+    if (!de)
+      {
+       fLogger->Log(Form("DE %04d does not exist !", detElemId));
+       continue;
+      }
 
-           // 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();
+    if (!de->IsConnectedChannel(manuId,channelId))
+      {
+       // non connected pad, do nothing (this is not an error !)
+       continue;
+      }
 
-             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));
-           }
+    const AliMpVSegmentation* seg 
+      = AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(detElemId, 
+                                                                      manuId);  
 
-           // fill digits
-           iChamber = fDigit->DetElemId()/100 - 1;
+    if (!seg)
+    {
+      fLogger->Log(Form("(DE,MANUID)=(%04d,%04d) is not valid",detElemId,manuId));
+      continue;
+    }
+    
+    AliMp::CathodType cathodeType = de->GetCathodType(seg->PlaneType());
 
-           if (fDigitFlag)
-             fMUONData->AddDigit(iChamber, *fDigit);
-           else
-             fMUONData->AddSDigit(iChamber, *fDigit);
+    AliMpPad pad = seg->PadByLocation(manuId,channelId,kFALSE);
 
+    if (!pad.IsValid())
+    {
+      fLogger->Log(Form("No pad for detElemId: %d, manuId: %d, channelId: %d",
+                    detElemId, manuId, channelId));
+      continue;
+    } 
 
-         } // iData
-       } // iBusPatch
-      } // iDsp
-    } // iBlock
-  } // NextDDL
+    AliMUONVDigit* digit = fDigitStore->Add(detElemId,manuId,channelId,cathodeType,
+                                            AliMUONVDigitStore::kDeny);
 
-  fTrackerTimer.Stop();
+    if (!digit)
+    {
+      fLogger->Log(Form("Digit DE %04d Manu %04d Channel %02d could not be added",
+                    detElemId, manuId, channelId));
+      continue;
+    }
+    
+    digit->SetPadXY(pad.GetIx(),pad.GetIy());
+    
+    digit->SetADC(charge);
 
-  return kTRUE;
-}
-//____________________________________________________________________
-Int_t AliMUONDigitMaker::GetMapping(Int_t busPatchId, UShort_t manuId, 
-                                        UChar_t channelId, AliMUONDigit* digit )
-{
-  //
-  // mapping  for tracker
-  //
-  fMappingTimer.Start(kFALSE);
+  }
   
-  // getting DE from buspatch
-  Int_t detElemId = fBusPatchManager->GetDEfromBus(busPatchId);
-  AliDebug(3,Form("detElemId: %d busPatchId %d\n", detElemId, busPatchId));
-
-  AliMpVSegmentation* seg = fSegFactory->CreateMpSegmentationByElectronics(detElemId, manuId);  
-  AliMpPad pad = seg->PadByLocation(AliMpIntPair(manuId,channelId),kTRUE);
-
-  if (!pad.IsValid())
+  if ( fRawStreamTracker->IsErrorMessage() ) 
   {
-    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(););
+    return kTrackerBAD;
+  }
   
-  fMappingTimer.Stop();
-  return kFALSE;
+  return kOK;
 }
 
 //____________________________________________________________________
-Int_t AliMUONDigitMaker::ReadTriggerDDL(AliRawReader* rawReader)
+Int_t
+AliMUONDigitMaker::ReadTriggerDDL(AliRawReader* rawReader)
 {
-  // reading tracker DDL
-  // filling the TClonesArray in MUONData
-  //
+  /// reading tracker DDL like ReadTriggerDDL but with fast decoder interface.
+  /// filling the fTriggerStore container, which must not be null
 
-  AliMUONDDLTrigger*       ddlTrigger      = 0x0;
-  AliMUONDarcHeader*       darcHeader      = 0x0;
-  AliMUONRegHeader*        regHeader       = 0x0;
-  AliMUONLocalStruct*      localStruct     = 0x0;
+  const AliMUONRawStreamTriggerHP::AliHeader*          darcHeader  = 0x0;
+  const AliMUONRawStreamTriggerHP::AliRegionalHeader*  regHeader   = 0x0;
+  const AliMUONRawStreamTriggerHP::AliLocalStruct*     localStruct = 0x0;
 
   Int_t loCircuit;
-  TList digitList;
-
-
-  fTriggerTimer.Start(kFALSE);
 
   fRawStreamTrigger->SetReader(rawReader);
 
-  while(fRawStreamTrigger->NextDDL()) {
-
-    ddlTrigger = fRawStreamTrigger->GetDDLTrigger();
-    darcHeader = ddlTrigger->GetDarcHeader();
-
-    // fill global trigger information in Digit Tree
-    if (fDigitFlag) {
-      if (darcHeader->GetGlobalFlag()) {
-       fGlobalTrigger->SetFromGlobalResponse(darcHeader->GetGlobalOutput());
-       fMUONData->AddGlobalTrigger(*fGlobalTrigger);
+  while (fRawStreamTrigger->NextDDL())
+  {
+    darcHeader = fRawStreamTrigger->GetHeaders();
+    
+    // fill global trigger information
+    if (fTriggerStore) 
+    {
+      if (darcHeader->GetGlobalFlag()) 
+      {
+          AliMUONGlobalTrigger globalTrigger;
+          globalTrigger.SetFromGlobalResponse(darcHeader->GetGlobalOutput());
+          globalTrigger.SetFromGlobalInput(darcHeader->GetGlobalHeader()->fInput);
+          fTriggerStore->SetGlobal(globalTrigger);
       }
     }
-
-    Int_t nReg = darcHeader->GetRegHeaderEntries();
-
-    for(Int_t iReg = 0; iReg < nReg ;iReg++){   //reg loop
-
-     // crate info
-      AliMUONTriggerCrate* crate = fCrateManager->Crate(fRawStreamTrigger->GetDDL(), iReg);
-  
-      if (!crate) 
-       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 has triggered
-       if (localStruct->GetTriggerY() == 0) {
-
-
-         AliMUONLocalTriggerBoard* localBoard = 
-           (AliMUONLocalTriggerBoard*)boards->At(localStruct->GetId()+1);
-
-         loCircuit = localBoard->GetNumber();
-
-         if (fDigitFlag) {
-           // fill local trigger
-           fLocalTrigger->SetLocalStruct(loCircuit, *localStruct);
-
-           fMUONData->AddLocalTrigger(*fLocalTrigger);
-
-         } else {
-           // Make SDigit
-
-           digitList.Clear();
-           
-           if( TriggerDigits(localBoard, localStruct, digitList) ) {
-
-             for (Int_t iEntry = 0; iEntry < digitList.GetEntries(); iEntry++) {
-
-               AliMUONDigit* digit = (AliMUONDigit*)digitList.At(iEntry);
-               
-               // filling S container
-               Int_t iChamber = digit->DetElemId()/100 - 1;
-               fMUONData->AddSDigit(iChamber, *digit);
-
-             }
-
-           } // trigger digits
-         } // S flag
-
-       } // if triggerY
+    
+    Int_t nReg = fRawStreamTrigger->GetRegionalHeaderCount();
+    
+    for(Int_t iReg = 0; iReg < nReg ;iReg++)
+    {   //reg loop
+      
+
+      // crate info  
+      AliMpTriggerCrate* crate = AliMpDDLStore::Instance()->
+                                GetTriggerCrate(fRawStreamTrigger->GetDDL(), iReg);
+      
+      if (!crate) {
+        fLogger->Log(Form("Missing crate number %d in DDL %d\n", iReg, fRawStreamTrigger->GetDDL()));
+        continue;
+      }
+      
+      regHeader =  fRawStreamTrigger->GetRegionalHeader(iReg);
+      
+      Int_t nLocal = regHeader->GetLocalStructCount();
+      for(Int_t iLocal = 0; iLocal < nLocal; iLocal++) 
+      {
+        
+        localStruct = regHeader->GetLocalStruct(iLocal);
+        
+        // if card exist
+        if (localStruct) {
+          
+         loCircuit = crate->GetLocalBoardId(localStruct->GetId());
+
+         if ( !loCircuit ) continue; // empty slot
+
+         AliMpLocalBoard* localBoard = AliMpDDLStore::Instance()->GetLocalBoard(loCircuit, kTRUE);
+
+         // skip copy cards
+         if( !localBoard->IsNotified()) 
+            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];
+            
+           localStruct->GetXPattern(xyPattern[0]);
+           localStruct->GetYPattern(xyPattern[1]);
+            
+            TriggerDigits(loCircuit, xyPattern, *fDigitStore);
+          }
+        } // if triggerY
       } // iLocal
     } // iReg
   } // NextDDL
-
-  fTriggerTimer.Stop();
-
-  return kTRUE;
-
+  
+  return kOK;
 }
-//____________________________________________________________________
-void AliMUONDigitMaker::GetTriggerChamber(AliMUONLocalStruct* localStruct, Int_t& xyPattern, 
-                                         Int_t& iChamber, Int_t& iCath, Int_t icase)
-{
 
-  // get chamber & cathode number, (chamber starts at 0 !)
-    switch(icase) {
-    case 0: 
-      xyPattern =  localStruct->GetX1();
-      iCath = 0;
-      iChamber = 10;
-      break;
-    case 1: 
-      xyPattern =  localStruct->GetX2();
-      iCath = 0;
-      iChamber = 11;
-      break;
-    case 2: 
-      xyPattern =  localStruct->GetX3();
-      iCath = 0;
-      iChamber = 12;
-      break;
-    case 3: 
-      xyPattern =  localStruct->GetX4();
-      iCath = 0;
-      iChamber = 13;
-      break;
-    case 4: 
-      xyPattern =  localStruct->GetY1();
-      iCath = 1;
-      iChamber = 10;
-      break;
-    case 5: 
-      xyPattern =  localStruct->GetY2();
-      iCath = 1;
-      iChamber = 11;
-      break;
-    case 6: 
-      xyPattern =  localStruct->GetY3();
-      iCath = 1;
-      iChamber = 12;
-      break;
-    case 7: 
-      xyPattern =  localStruct->GetY4();
-      iCath = 1;
-      iChamber = 13;
-      break;
-    }
-}
 //____________________________________________________________________
-Int_t AliMUONDigitMaker::TriggerDigits(AliMUONLocalTriggerBoard* localBoard, 
-                                      AliMUONLocalStruct* localStruct,
-                                      TList& digitList)
+Int_t AliMUONDigitMaker::TriggerDigits(Int_t nBoard, 
+                                       const TArrayS* xyPattern,
+                                       AliMUONVDigitStore& digitStore, Bool_t warn) const
 {
-  //
-  // make (S)Digit for trigger
-
-  Int_t detElemId;
-  Int_t nBoard;
-  Int_t iCath = -1;
-  Int_t iChamber = 0;
-  Int_t xyPattern = 0;
-
-  // loop over x1-4 and y1-4
-  for (Int_t icase = 0; icase < 8; icase++) {
+  /// make digits for trigger from pattern, and add them to digitStore
 
-    // get chamber, cathode and associated trigger response pattern
-    GetTriggerChamber(localStruct, xyPattern, iChamber, iCath, icase);
+  AliCodeTimerAuto("",0);
   
-    if (!xyPattern) continue;
+  Int_t detElemId;
 
-    // get detElemId
-    AliMUONTriggerCircuitNew triggerCircuit;
-    detElemId = triggerCircuit.DetElemId(iChamber, localBoard->GetName());
-    nBoard    = localBoard->GetNumber();
+  AliMpLocalBoard* localBoard = AliMpDDLStore::Instance()->GetLocalBoard(nBoard);
 
-    AliMpVSegmentation* seg = fSegFactory->CreateMpSegmentation(detElemId, iCath);  
-
-    // loop over the 16 bits of pattern
-    for (Int_t ibitxy = 0; ibitxy < 16; ibitxy++) {
-    
-      if ((xyPattern >> 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->SetCathode(iCath);
-       digit->SetDetElemId(detElemId);
-       digit->SetElectronics(nBoard, ibitxy);
-       digitList.Add(digit);
-       
-      }// xyPattern
-    }// ibitxy
-  }// case
+  Int_t n,b;
 
+  // loop over x1-4 and y1-4
+  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
+      detElemId = AliMpDDLStore::Instance()->GetDEfromLocalBoard(nBoard, iChamber);
+        
+        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(AliMpLocalBoard::kZeroAllYLSB)) offset = -8;
+            
+            AliMpPad pad = seg->PadByLocation(nBoard,ibitxy+offset,warn);
+                        
+            if (!pad.IsValid()) 
+            {
+              fLogger->Log(Form("No pad for detElemId: %d, nboard %d, ibitxy: %d\n",
+                              detElemId, nBoard, ibitxy));
+              continue;
+            }
+
+            n = pad.GetLocalBoardId(0); // always take first location so that digits are not inserted several times
+           b = pad.GetLocalBoardChannel(0);
+
+           AliDebug(1,Form("Using localBoard %d ixy %d instead of %d,%d",
+                           n,b,nBoard,ibitxy));
+
+           AliMUONVDigit* digit = digitStore.Add(detElemId,n,b,iCath,AliMUONVDigitStore::kDeny);
+            
+            if (!digit)
+            {
+               AliDebug(1, Form("Digit DE %04d LocalBoard %03d ibitxy %02d cath %d already in store",
+                                detElemId,nBoard,ibitxy,iCath));
+               continue;
+            }
+            
+            Int_t padX = pad.GetIx();
+            Int_t padY = pad.GetIy();
+            
+            // 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)
+}
+
+//______________________________________________________________________________
+Bool_t 
+AliMUONDigitMaker::TriggerToDigitsStore(const AliMUONVTriggerStore& triggerStore,
+                                       AliMUONVDigitStore& digitStore) const
 {
-  // set crate name from DDL & reg number
-  // method same as in RawWriter, not so nice
-  // should be put in AliMUONTriggerCrateStore
-
-      switch(iReg) {
-      case 0:
-      case 1:
-       sprintf(name,"%d", iReg+1);
-       break;
-      case 2:
-       strcpy(name, "2-3");
-       break;
-      case 3:
-      case 4:
-      case 5:
-      case 6:
-      case 7:
-       sprintf(name,"%d", iReg);
-       break;
-      }
+  //
+  /// make (S)Digit for trigger
+  //
+  
+  digitStore.Clear();
+  
+  AliMUONLocalTrigger* locTrg;
+  TIter next(triggerStore.CreateLocalIterator());
+  
+  while ( ( locTrg = static_cast<AliMUONLocalTrigger*>(next()) ) ) 
+  {
+    if (locTrg->IsNull()) continue;
+   
+    TArrayS xyPattern[2];
+    locTrg->GetXPattern(xyPattern[0]);
+    locTrg->GetYPattern(xyPattern[1]);
+
+    Int_t nBoard = locTrg->LoCircuit();
+    TriggerDigits(nBoard, xyPattern, digitStore);
+  }
+  return kTRUE;
+}
 
-      // crate Right for first DDL
-      if (iDDL == 0)
-       strcat(name, "R");
-      else 
-       strcat(name, "L"); 
+//______________________________________________________________________________
+void 
+AliMUONDigitMaker::SetTryRecover(Bool_t flag) 
+{
+  /// Instruct the decoder to try to recover corrupted raw data.
+  /// Only use for specific cases for which you know it will work...
+  fRawStreamTracker->TryRecover(flag);
 }