]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - MUON/AliMUONDigitMaker.cxx
First big commit of the mchview program and its accompanying library,
[u/mrichter/AliRoot.git] / MUON / AliMUONDigitMaker.cxx
index 6dab242c598a6110f645607bdcbc55f54f749163..a218fd3fb62a4990c7acf27d6e5a06d2e71f2950 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 "AliCodeTimer.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 "AliMUONTriggerCircuitNew.h"
-#include "AliMpSegFactory.h"
-#include "AliMpVSegmentation.h"
-#include "AliMpPad.h"
+#include "AliMUONLogger.h"
+#include "AliMUONRawStreamTracker.h"
+#include "AliMUONRawStreamTrackerHP.h"
+#include "AliMUONRawStreamTrigger.h"
+#include "AliMUONRegHeader.h"
+#include "AliMUONTriggerCircuit.h"
+#include "AliMpTriggerCrate.h"
+#include "AliMpLocalBoard.h"
+#include "AliMUONVTriggerStore.h"
+#include "AliMpCathodType.h"
+#include "AliMpDDLStore.h"
 #include "AliMpDEManager.h"
+#include "AliMpPad.h"
+#include "AliMpSegmentation.h"
+#include "AliMpVSegmentation.h"
+#include "AliRawReader.h"
+#include <TArrayS.h>
 
+/// \cond CLASSIMP
 ClassImp(AliMUONDigitMaker) // Class implementation in ROOT context
+/// \endcond
+
 //__________________________________________________________________________
-AliMUONDigitMaker::AliMUONDigitMaker(Bool_t flag)
+AliMUONDigitMaker::AliMUONDigitMaker(Bool_t enableErrorLogger, Bool_t useFastDecoder)
   : TObject(),
-    fMUONData(0x0),
-    fSegFactory(0x0),
-    fBusPatchManager(new AliMpBusPatch()),
     fScalerEvent(kFALSE),
-    fDigitFlag(flag),
-    fRawStreamTracker(new AliMUONRawStreamTracker()),    
+    fMakeTriggerDigits(kFALSE),
+    fRawStreamTracker(NULL),
     fRawStreamTrigger(new AliMUONRawStreamTrigger()),    
-    fDigit(new AliMUONDigit()),
-    fLocalTrigger(new AliMUONLocalTrigger()),
-    fGlobalTrigger(new AliMUONGlobalTrigger()),
-    fCrateManager(0x0),
-    fTrackerTimer(),
-    fTriggerTimer(),
-    fMappingTimer()
+    fDigitStore(0x0),
+    fTriggerStore(0x0),
+  fLogger(new AliMUONLogger(10000))
 {
-  //
-  // ctor with AliMUONData as argument
-  // for reconstruction
-  //
+  /// ctor 
 
   AliDebug(1,"");
+  
+  CreateRawStreamTracker(useFastDecoder);
 
   // Standard Constructor
+  if (enableErrorLogger) {
+    fRawStreamTracker->EnabbleErrorLogger();
+    fRawStreamTrigger->EnabbleErrorLogger();
+  }
 
-  // bus patch 
-  fBusPatchManager->ReadBusPatchFile();
-
-  fTrackerTimer.Start(kTRUE); fTrackerTimer.Stop();
-  fTriggerTimer.Start(kTRUE); fTriggerTimer.Stop();
-  fMappingTimer.Start(kTRUE); fMappingTimer.Stop();
+  SetMakeTriggerDigits();
 
 }
 
 //__________________________________________________________________________
 AliMUONDigitMaker::~AliMUONDigitMaker()
 {
-  //
-  // clean up
-  // and time processing measure
-  //
+  /// clean up
+  /// and time processing measure
+
   delete fRawStreamTracker;
   delete fRawStreamTrigger;
 
-  delete fDigit;
-  delete fLocalTrigger;
-  delete fGlobalTrigger;
-
-  delete fBusPatchManager;
-
-  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) "
-               ": R:%.2fs C:%.2fs",
-               fMappingTimer.RealTime(),fMappingTimer.CpuTime()));
-  AliDebug(1, 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::CreateRawStreamTracker(Bool_t useFastDecoder)
 {
-  // Main method to creates digit
-  // for tracker 
-  // and trigger
+/// Create raw stream tracker according to the passed option
 
-  // generate digits
-  ReadTrackerDDL(rawReader);
+  if (useFastDecoder)
+  {
+    AliInfo("Using fast decoder.");
+    fRawStreamTracker = new AliMUONRawStreamTrackerHP();
+  }
+  else
+    fRawStreamTracker = new AliMUONRawStreamTracker();
+}    
 
-  // generate trigger
-  ReadTriggerDDL(rawReader);
+//____________________________________________________________________
+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 kFALSE;
+  }
+  
+  if ( fDigitStore ) 
+  {
+    fDigitStore->Clear(); // insure we start with an empty container
+    ReadTrackerDDL(rawReader);
+  }
+  
+  if ( fTriggerStore || fMakeTriggerDigits ) 
+  {
+    if ( fTriggerStore ) fTriggerStore->Clear();
+    if ( fMakeTriggerDigits && !fDigitStore ) 
+    {
+      fLogger->Log("Asking for trigger digits but digitStore is null");
+    }
+    else
+    {
+      ReadTriggerDDL(rawReader);
+    }
+  }
+  
   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
-  //
-  fTrackerTimer.Start(kFALSE);
+  AliDebug(1,"");
+  
+  AliCodeTimerAuto("");
 
   // 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);
-
-  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++) {
-
-           // 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);
-
-           // 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)
-             fMUONData->AddDigit(iChamber, *fDigit);
-           else
-             fMUONData->AddSDigit(iChamber, *fDigit);
-
-
-         } // iData
-       } // iBusPatch
-      } // iDsp
-    } // iBlock
-  } // NextDDL
-
-  fTrackerTimer.Stop();
-
-  return kTRUE;
-}
-//____________________________________________________________________
-Int_t AliMUONDigitMaker::GetMapping(Int_t busPatchId, UShort_t manuId, 
-                                        UChar_t channelId, AliMUONDigit* digit )
-{
-  //
-  // mapping  for tracker
-  //
-  fMappingTimer.Start(kFALSE);
+  fRawStreamTracker->First();
   
-  // getting DE from buspatch
-  Int_t detElemId = fBusPatchManager->GetDEfromBus(busPatchId);
-  AliDebug(3,Form("detElemId: %d busPatchId %d\n", detElemId, busPatchId));
+  while ( fRawStreamTracker->Next(buspatchId,manuId,channelId,charge) )
+  {    
+    // getting DE from buspatch
+    Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(buspatchId);
+
+    const AliMpVSegmentation* seg 
+      = AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(detElemId, 
+                                                                      manuId);  
+
+    if (!seg)
+    {
+      fLogger->Log(Form("(DE,MANUID)=(%04d,%04d) is not valid",detElemId,manuId));
+      continue;
+    }
+    
+    AliMp::CathodType cathodeType = AliMpDEManager::GetCathod(detElemId, 
+                                                              seg->PlaneType());
 
-  AliMpVSegmentation* seg = fSegFactory->CreateMpSegmentationByElectronics(detElemId, manuId);  
-  AliMpPad pad = seg->PadByLocation(AliMpIntPair(manuId,channelId),kTRUE);
+    AliMpPad pad = seg->PadByLocation(AliMpIntPair(manuId,channelId),kFALSE);
+    
+    if (!pad.IsValid())
+    {
+      fLogger->Log(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)
+    {
+      fLogger->Log(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);
 
-  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
-  //
+  /// reading tracker DDL
+  /// 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);
+  AliCodeTimerAuto("");
 
   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()) {
-       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
-
-      // crate info
-      if (!fCrateManager) AliFatal("Crate Store not defined");
-      AliMUONTriggerCrate* crate = fCrateManager->Crate(fRawStreamTrigger->GetDDL(), iReg);
-  
+    
+    for(Int_t iReg = 0; iReg < nReg ;iReg++)
+    {   //reg loop
+      
+
+      // crate info  
+      AliMpTriggerCrate* crate = AliMpDDLStore::Instance()->
+                                GetTriggerCrate(fRawStreamTrigger->GetDDL(), iReg);
+      
       if (!crate) 
-       AliWarning(Form("Missing crate number %d in DDL %d\n", iReg, fRawStreamTrigger->GetDDL()));
-
-      TObjArray *boards  = crate->Boards();
-
-
+        fLogger->Log(Form("Missing crate number %d in DDL %d\n", iReg, fRawStreamTrigger->GetDDL()));
+     
+      
       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 = AliMpDEManager::GetChamberId(digit->DetElemId());
-               fMUONData->AddSDigit(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) {
+          
+         loCircuit = crate->GetLocalBoardId(localStruct->GetId());
+
+         if ( !loCircuit ) continue; // empty slot
+
+         AliMpLocalBoard* localBoard = AliMpDDLStore::Instance()->GetLocalBoard(loCircuit, false);
+
+         // 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;
 
 }
-//____________________________________________________________________
-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, 
+                                       TArrayS* xyPattern,
+                                       AliMUONVDigitStore& digitStore) const
 {
-  //
-  // make (S)Digit for trigger
+  /// make digits for trigger from pattern, and add them to digitStore
 
-  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++) {
-
-    // get chamber, cathode and associated trigger response pattern
-    GetTriggerChamber(localStruct, xyPattern, iChamber, iCath, icase);
+  AliCodeTimerAuto("");
   
-    if (!xyPattern) continue;
-
-    // get detElemId
-    AliMUONTriggerCircuitNew triggerCircuit;
-    detElemId = triggerCircuit.DetElemId(iChamber, localBoard->GetName());
-    nBoard    = localBoard->GetNumber();
+  Int_t detElemId;
 
-    AliMpVSegmentation* seg = fSegFactory->CreateMpSegmentation(detElemId, iCath);  
+  AliMpLocalBoard* localBoard = AliMpDDLStore::Instance()->GetLocalBoard(nBoard);
 
-    // 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(6)) offset = -8;
+            
+            AliMpPad pad = seg->PadByLocation(AliMpIntPair(nBoard,ibitxy+offset),kTRUE);
+                        
+            if (!pad.IsValid()) 
+            {
+              fLogger->Log(Form("No pad for detElemId: %d, nboard %d, ibitxy: %d\n",
+                              detElemId, nBoard, ibitxy));
+              continue;
+            }
+
+            n = pad.GetLocation(0).GetFirst(); // always take first location so that digits are not inserted several times
+           b = pad.GetLocation(0).GetSecond();
+
+           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.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)
+void  AliMUONDigitMaker::SetFastDecoder(Bool_t useFastDecoder)
 {
-  // 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;
-      }
+/// Set fast raw data decoder
+
+  delete fRawStreamTracker;
+  CreateRawStreamTracker(useFastDecoder);
+}  
+  
+    
 
-      // crate Right for first DDL
-      if (iDDL == 0)
-       strcat(name, "R");
-      else 
-       strcat(name, "L"); 
-}