]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
Filling out AliHLTMUONDigitPublisherComponent code to generate dimuon raw data on...
authoraszostak <aszostak@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 9 Jun 2008 13:56:36 +0000 (13:56 +0000)
committeraszostak <aszostak@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 9 Jun 2008 13:56:36 +0000 (13:56 +0000)
Fixing typos in AliHLTMUONRecHitsSource and AliHLTMUONTriggerRecordsSource, and adding some extra checking logic.

HLT/MUON/OfflineInterface/AliHLTMUONDigitPublisherComponent.cxx
HLT/MUON/OfflineInterface/AliHLTMUONDigitPublisherComponent.h
HLT/MUON/OfflineInterface/AliHLTMUONRecHitsSource.cxx
HLT/MUON/OfflineInterface/AliHLTMUONTriggerRecordsSource.cxx

index b43c425e5567629c90d371c4d26b73cb56b1632e..98d45e1461cdee9ef63660503845bec21de1d348 100644 (file)
 
 #include "AliHLTMUONDigitPublisherComponent.h"
 #include "AliHLTMUONConstants.h"
+#include "AliHLTMUONUtils.h"
 #include "AliHLTLogging.h"
 #include "AliHLTSystem.h"
 #include "AliHLTDefinitions.h"
 #include "AliRawDataHeader.h"
-#include "AliMUONConstants.h"
 #include "AliMUONTrackerDDLDecoderEventHandler.h"
+#include "AliMUONConstants.h"
+#include "AliMUONMCDataInterface.h"
+#include "AliMUONDataInterface.h"
+#include "AliMUONVDigitStore.h"
+#include "AliMUONVTriggerStore.h"
+#include "AliMpExMap.h"
+#include "AliMpCDB.h"
+#include "AliMpDDL.h"
+#include "AliMpDDLStore.h"
+#include "AliMpTriggerCrate.h"
+#include "AliMpConstants.h"
+#include "AliBitPacking.h"
+#include "AliMUONBlockHeader.h"
+#include "AliMUONBusStruct.h"
+#include "AliMUONConstants.h"
+#include "AliMUONDarcHeader.h"
+#include "AliMUONVDigit.h"
+#include "AliMUONDspHeader.h"
+#include "AliMUONGlobalTrigger.h"
+#include "AliMUONLocalStruct.h"
+#include "AliMUONLocalTrigger.h"
+#include "AliMUONLocalTriggerBoard.h"
+#include "AliMUONRegionalTrigger.h"
+#include "AliMUONRegHeader.h"
+#include "AliRunLoader.h"
+#include "AliCentralTrigger.h"
 #include <cstring>
 #include <cstdlib>
 #include <cmath>
@@ -48,7 +74,10 @@ ClassImp(AliHLTMUONDigitPublisherComponent)
 AliHLTMUONDigitPublisherComponent::AliHLTMUONDigitPublisherComponent() :
        AliHLTOfflineDataSource(),
        fDDL(-1),
-       fCurrentEventIndex(0)
+       fCurrentEventIndex(0),
+       fMakeScalars(false),
+       fMCDataInterface(NULL),
+       fDataInterface(NULL)
 {
        /// Default constructor.
 }
@@ -57,6 +86,9 @@ AliHLTMUONDigitPublisherComponent::AliHLTMUONDigitPublisherComponent() :
 AliHLTMUONDigitPublisherComponent::~AliHLTMUONDigitPublisherComponent()
 {
        /// Default destructor.
+       
+       if (fMCDataInterface != NULL) delete fMCDataInterface;
+       if (fDataInterface != NULL) delete fDataInterface;
 }
 
 const char* AliHLTMUONDigitPublisherComponent::GetComponentID()
@@ -105,9 +137,21 @@ int AliHLTMUONDigitPublisherComponent::DoInit(int argc, const char** argv)
        
        HLTInfo("Initialising dHLT digit publisher component.");
 
+       if (fMCDataInterface != NULL)
+       {
+               delete fMCDataInterface;
+               fMCDataInterface = NULL;
+       }
+       if (fDataInterface != NULL)
+       {
+               delete fDataInterface;
+               fDataInterface = NULL;
+       }
+       
        // Initialise with default values.
        fDDL = -1;
        fCurrentEventIndex = 0;
+       fMakeScalars = false;
        bool simdata = false;
        bool recdata = false;
        bool firstEventSet = false;
@@ -115,6 +159,11 @@ int AliHLTMUONDigitPublisherComponent::DoInit(int argc, const char** argv)
 
        for (int i = 0; i < argc; i++)
        {
+               if (strcmp(argv[i], "-makescalars") == 0)
+               {
+                       fMakeScalars = true;
+                       continue;
+               }
                if (strcmp(argv[i], "-simdata") == 0)
                {
                        simdata = true;
@@ -199,7 +248,61 @@ int AliHLTMUONDigitPublisherComponent::DoInit(int argc, const char** argv)
                return -EINVAL;
        }
        
-       //TODO initialise data source
+       // Must load the mapping data if it is not already loaded.
+       if (AliMpDDLStore::Instance(false) == NULL)
+       {
+               AliMpCDB::LoadDDLStore();
+               if (AliMpDDLStore::Instance(false) == NULL)
+               {
+                       HLTError("Could not load the DDL mapping store from CDB.");
+                       return -EFAULT;
+               }
+       }
+       
+       // Now we can initialise the data interface objects and loaders.
+       if (simdata)
+       {
+               HLTDebug("Loading simulated digits with AliMUONMCDataInterface.");
+
+               try
+               {
+                       fMCDataInterface = new AliMUONMCDataInterface("galice.root");
+               }
+               catch (const std::bad_alloc&)
+               {
+                       HLTError("Not enough memory to allocate AliMUONMCDataInterface.");
+                       return -ENOMEM;
+               }
+       }
+       else if (recdata)
+       {
+               HLTDebug("Loading reconstructed digits with AliMUONDataInterface.");
+               
+               try
+               {
+                       fDataInterface = new AliMUONDataInterface("galice.root");
+               }
+               catch (const std::bad_alloc&)
+               {
+                       HLTError("Not enough memory to allocate AliMUONDataInterface.");
+                       return -ENOMEM;
+               }
+       }
+       
+       // Check that the fCurrentEventIndex number falls within the correct range.
+       UInt_t maxevent = 0;
+       if (fMCDataInterface != NULL)
+               maxevent = UInt_t(fMCDataInterface->NumberOfEvents());
+       else if (fDataInterface != NULL)
+               maxevent = UInt_t(fDataInterface->NumberOfEvents());
+       if (fCurrentEventIndex != -1 and UInt_t(fCurrentEventIndex) >= maxevent and maxevent != 0)
+       {
+               fCurrentEventIndex = 0;
+               HLTWarning("The selected first event number (%d) was larger than"
+                       " the available number of events (%d). Resetting the event"
+                       " counter to zero.", fCurrentEventIndex, maxevent
+               );
+       }
 
        return 0;
 }
@@ -210,23 +313,798 @@ int AliHLTMUONDigitPublisherComponent::DoDeinit()
        /// Inherited from AliHLTComponent. Performs a cleanup of the component.
        
        HLTInfo("Deinitialising dHLT digit publisher component.");
+       
+       if (fMCDataInterface != NULL)
+       {
+               delete fMCDataInterface;
+               fMCDataInterface = NULL;
+       }
+       if (fDataInterface != NULL)
+       {
+               delete fDataInterface;
+               fDataInterface = NULL;
+       }
        return 0;
 }
 
 
 int AliHLTMUONDigitPublisherComponent::GetEvent(
-               const AliHLTComponentEventData& /*evtData*/,
+               const AliHLTComponentEventData& evtData,
                AliHLTComponentTriggerData& /*trigData*/,
-               AliHLTUInt8_t* /*outputPtr*/,
+               AliHLTUInt8_t* outputPtr,
                AliHLTUInt32_t& size,
-               vector<AliHLTComponentBlockData>& /*outputBlocks*/
+               vector<AliHLTComponentBlockData>& outputBlocks
        )
 {
        /// Inherited from AliHLTOfflineDataSource.
        
-       //TODO
+       assert( fMCDataInterface != NULL or fDataInterface != NULL );
+
+       // Check the size of the event descriptor structure.
+       if (evtData.fStructSize < sizeof(AliHLTComponentEventData))
+       {
+               HLTError(kHLTLogError,
+                       "The event descriptor (AliHLTComponentEventData) size is"
+                         " smaller than expected. It claims to be %d bytes, but"
+                         " we expect it to be %d bytes.",
+                       evtData.fStructSize,
+                       sizeof(AliHLTComponentEventData)
+               );
+               size = 0; // Important to tell framework that nothing was generated.
+               return -EINVAL;
+       }
+       
+       // Use the fEventID as the event number to load if fCurrentEventIndex == -1,
+       // check it and load that event with the runloader.
+       // If fCurrentEventIndex is a positive number then use it instead and
+       // increment it.
+       UInt_t eventnumber = UInt_t(evtData.fEventID);
+       UInt_t maxevent = 0;
+       if (fMCDataInterface != NULL)
+               maxevent = UInt_t(fMCDataInterface->NumberOfEvents());
+       else if (fDataInterface != NULL)
+               maxevent = UInt_t(fDataInterface->NumberOfEvents());
+       if (fCurrentEventIndex != -1)
+       {
+               eventnumber = UInt_t(fCurrentEventIndex);
+               fCurrentEventIndex++;
+               if (UInt_t(fCurrentEventIndex) >= maxevent)
+                       fCurrentEventIndex = 0;
+       }
+       if ( eventnumber >= maxevent )
+       {
+               HLTError("The event number (%d) is larger than the available number"
+                         " of events on file (%d).",
+                       eventnumber, maxevent
+               );
+               size = 0; // Important to tell framework that nothing was generated.
+               return -EINVAL;
+       }
+       
+       const AliMUONVDigitStore* digitStore = NULL;
+       const AliMUONVTriggerStore* triggerStore = NULL;
+       
+       if (fMCDataInterface != NULL)
+       {
+               HLTDebug("Filling data block with simulated digits for event %d.", eventnumber);
+               
+               if (fDDL < 20)
+               {
+                       digitStore = fMCDataInterface->DigitStore(eventnumber);
+               }
+               else
+               {
+                       triggerStore = fMCDataInterface->TriggerStore(eventnumber);
+               }
+       }
+       else if (fDataInterface != NULL)
+       {
+               HLTDebug("Filling data block with reconstructed digits for event %d.", eventnumber);
+               
+               if (fDDL < 20)
+               {
+                       digitStore = fDataInterface->DigitStore(eventnumber);
+               }
+               else
+               {
+                       triggerStore = fDataInterface->TriggerStore(eventnumber);
+               }
+       }
+       else
+       {
+               HLTError("Neither AliMUONDataInterface nor AliMUONMCDataInterface were created.");
+               size = 0; // Important to tell framework that nothing was generated.
+               return -EFAULT;
+       }
+       
+       // Make sure we have the correct CTP trigger loaded.
+       AliRunLoader* runloader = AliRunLoader::GetRunLoader();
+       if (runloader != NULL)
+       {
+               if (runloader->GetTrigger() == NULL)
+                       runloader->LoadTrigger();
+               runloader->GetEvent(eventnumber);
+       }
+       
+       if (fDDL < 20 and digitStore != NULL)
+       {
+               int result = WriteTrackerDDL(digitStore, fDDL, outputPtr, size);
+               if (result != 0)
+               {
+                       size = 0; // Important to tell framework that nothing was generated.
+                       return result;
+               }
+       }
+       else if (triggerStore != NULL)
+       {
+               int result = WriteTriggerDDL(triggerStore, fDDL-20, outputPtr, size, fMakeScalars);
+               if (result != 0)
+               {
+                       size = 0; // Important to tell framework that nothing was generated.
+                       return result;
+               }
+       }
+       else
+       {
+               size = 0; // Important to tell framework that nothing was generated.
+               return 0;
+       }
+       
+       AliHLTComponentBlockData bd;
+       FillBlockData(bd);
+       bd.fPtr = outputPtr;
+       bd.fOffset = 0;
+       bd.fSize = size;
+       bd.fDataType = AliHLTMUONConstants::DDLRawDataType();
+       bd.fSpecification = AliHLTMUONUtils::DDLNumberToSpec(fDDL);
+       outputBlocks.push_back(bd);
        
-       size = 0;
        return 0;
 }
 
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Methods copied from AliMUONRawWriter.
+//TODO: This is not ideal. We should have AliMUONRawWriter re-factored so that
+// we can have raw data generated into a memory resident buffer, rather than
+// always written to a file on disk, as it is now. But this will take some time
+// since people need to be convinced of this fact.
+
+//____________________________________________________________________
+void  AliHLTMUONDigitPublisherComponent::LocalWordPacking(UInt_t& word, UInt_t locId, UInt_t locDec, 
+                                        UInt_t trigY, UInt_t posY, UInt_t posX, 
+                                        UInt_t sdevX, UInt_t devX)
+{
+/// pack local trigger word
+
+    AliBitPacking::PackWord(locId,word,19,22); //card id number in crate
+    AliBitPacking::PackWord(locDec,word,15,18);
+    AliBitPacking::PackWord(trigY,word,14,14);
+    AliBitPacking::PackWord(posY,word,10,13);
+    AliBitPacking::PackWord(sdevX,word,9,9);
+    AliBitPacking::PackWord(devX,word,5,8);
+    AliBitPacking::PackWord(posX,word,0,4);
+}
+
+//______________________________________________________________________________
+void 
+AliHLTMUONDigitPublisherComponent::Digits2BusPatchMap(
+               const AliMUONVDigitStore& digitStore,
+               AliMpExMap& busPatchMap, Int_t iDDL
+       )
+{
+  /// Create bus patch structures corresponding to digits in the store
+  
+  AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
+  assert(ddlStore != NULL);
+  
+  AliMpDDL* ddl = ddlStore->GetDDL(iDDL);
+  busPatchMap.SetSize(ddl->GetNofBusPatches());
+  
+  if (ddl->GetNofDEs() <= 0) return;
+  Int_t minDetElem = ddl->GetDEId(0);
+  Int_t maxDetElem = ddl->GetDEId(0);
+  for (Int_t i = 1; i < ddl->GetNofDEs(); i++)
+  {
+    if (ddl->GetDEId(i) < minDetElem) minDetElem = ddl->GetDEId(i);
+    if (ddl->GetDEId(i) > maxDetElem) maxDetElem = ddl->GetDEId(i);
+  }
+  
+  static const Int_t kMAXADC = (1<<12)-1; // We code the charge on a 12 bits ADC.
+    
+  // DDL event one per half chamber
+  
+  // raw data
+  Char_t parity = 0x4;
+  UShort_t manuId = 0;
+  UChar_t channelId = 0;
+  UShort_t charge = 0;
+  Int_t busPatchId = 0;
+  Int_t currentBusPatchId = -1;
+  UInt_t word;
+  
+  AliMUONBusStruct* busStruct(0x0);
+  
+  TIter next(digitStore.CreateIterator(minDetElem, maxDetElem));
+  AliMUONVDigit* digit;
+  
+  while ( ( digit = static_cast<AliMUONVDigit*>(next()) ) )
+  {
+    charge = digit->ADC();
+    if ( charge > kMAXADC )
+    {
+      // This is most probably an error in the digitizer (which should insure
+      // the adc is below kMAXADC), so make it a (non-fatal) error indeed.
+      HLTError("ADC value %d above 0x%x for DE %d . Setting to 0x%x. Digit is:",
+                    charge,kMAXADC,digit->DetElemId(),kMAXADC);
+      charge = kMAXADC;
+    }
+    
+    // inverse mapping
+    busPatchId = ddlStore->GetBusPatchId(digit->DetElemId(), digit->ManuId());
+
+    if (busPatchId<0) continue;
+    
+    if ( digit->ManuId() > 0x7FF ||
+         digit->ManuChannel() > 0x3F )
+    {
+      HLTFatal("<%s>: ID %12u DE %4d Cath %d (Ix,Iy)=(%3d,%3d) (Manu,Channel)=(%4d,%2d)"
+               ", Charge=%7.2f\nManuId,ManuChannel are invalid for this digit.",
+               digit->ClassName(), digit->GetUniqueID(),
+               digit->DetElemId(), digit->Cathode(), digit->PadX(), digit->PadY(),
+               digit->ManuId(), digit->ManuChannel(), digit->Charge()
+      );
+    }
+    
+    manuId = ( digit->ManuId() & 0x7FF ); // 11 bits
+    channelId = ( digit->ManuChannel() & 0x3F ); // 6 bits
+    
+    //packing word
+    word = 0;
+    AliBitPacking::PackWord((UInt_t)manuId,word,18,28);
+    AliBitPacking::PackWord((UInt_t)channelId,word,12,17);
+    AliBitPacking::PackWord((UInt_t)charge,word,0,11);
+    
+    // parity word
+    parity = word & 0x1;
+    for (Int_t i = 1; i <= 30; ++i) 
+    {
+      parity ^=  ((word >> i) & 0x1);
+    }
+    AliBitPacking::PackWord((UInt_t)parity,word,31,31);
+
+    if ( currentBusPatchId != busPatchId ) 
+    {
+      busStruct = 
+        static_cast<AliMUONBusStruct*>(busPatchMap.GetValue(busPatchId));
+      currentBusPatchId = busPatchId;
+    }
+    
+    if (!busStruct)
+    {
+      busStruct = new AliMUONBusStruct;
+      busStruct->SetDataKey(busStruct->GetDefaultDataKey());
+      busStruct->SetBusPatchId(busPatchId);
+      busStruct->SetLength(0);
+      busPatchMap.Add(busPatchId,busStruct);
+    }
+    
+    // set sub Event
+    busStruct->AddData(word);
+  }
+}
+
+//______________________________________________________________________________
+int AliHLTMUONDigitPublisherComponent::WriteTrackerDDL(
+               const AliMUONVDigitStore* digitStore, Int_t iDDL,
+               AliHLTUInt8_t* outBuffer, AliHLTUInt32_t& outBufferSize
+       )
+{
+  /// Write DDL file for one tracker DDL
+  
+  assert(0 <= iDDL and iDDL <= 19);
+  
+  AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
+  assert(ddlStore != NULL);
+  
+  if (ddlStore->GetDDL(iDDL) == NULL)
+  {
+       HLTError("Could not find DDL mapping for DDL %d.", iDDL+1);
+       return -EFAULT;
+  }
+  
+  AliMpExMap busPatchMap;
+  Digits2BusPatchMap(*digitStore,busPatchMap,iDDL);
+  
+  AliMUONBlockHeader blockHeader;
+  AliMUONDspHeader dspHeader;
+  blockHeader.SetDataKey(blockHeader.GetDefaultDataKey());
+  dspHeader.SetDataKey(dspHeader.GetDefaultDataKey());
+  
+  if (outBufferSize < sizeof(AliRawDataHeader))
+  {
+       HLTError("The output buffer size is too small to write output."
+               " It is only %d bytes, but we need at least %d bytes.",
+               outBufferSize, sizeof(AliRawDataHeader)
+       );
+       return -ENOBUFS;
+  }
+  AliRawDataHeader* header = reinterpret_cast<AliRawDataHeader*>(outBuffer);
+  // Fill header with default values.
+  *header = AliRawDataHeader();
+  AliRunLoader* runloader = AliRunLoader::GetRunLoader();
+  if (runloader != NULL)
+  {
+    if (runloader->GetTrigger() != NULL)
+    {
+      AliCentralTrigger *aCTP = runloader->GetTrigger();
+      ULong64_t mask = aCTP->GetClassMask();
+      header->SetTriggerClass(mask);
+    }
+  }
+  
+  Int_t* buffer = reinterpret_cast<Int_t*>(header+1);
+  Int_t endOfBuffer = (outBufferSize - sizeof(AliRawDataHeader)) / sizeof(Int_t);
+  
+  // buffer size (max'ed out)
+  // (((43 manus max per bus patch *64 channels + 4 bus patch words) * 5 bus patch 
+  //   + 10 dsp words)*5 dsps + 8 block words)*2 blocks 
+  
+  AliMpDDL* ddl = ddlStore->GetDDL(iDDL);
+  Int_t iDspMax = ddl->GetMaxDsp();
+  Int_t iBusPerDSP[5]; //number of bus patches per DSP
+  ddl->GetBusPerDsp(iBusPerDSP);
+  Int_t busIter = 0;
+  
+  Int_t totalDDLLength = 0;
+  
+  Int_t index = 0;
+  
+  // two blocks A and B per DDL
+  for (Int_t iBlock = 0; iBlock < 2; ++iBlock) 
+  {
+    Int_t length = blockHeader.GetHeaderLength();
+    if (index + length >= endOfBuffer)
+    {
+      HLTError("The output buffer size is too small to write output."
+               " It is only %d bytes, but we need at least %d bytes.",
+               outBufferSize,
+               sizeof(AliRawDataHeader) + (index+length)*sizeof(UInt_t)
+      );
+      return -ENOBUFS;
+    }
+  
+    // block header
+    memcpy(&buffer[index],blockHeader.GetHeader(),length*4);
+    Int_t indexBlk = index;
+    index += length; 
+    
+    // 5 DSP's max per block
+    for (Int_t iDsp = 0; iDsp < iDspMax; ++iDsp) 
+    {
+      Int_t dspHeaderLength = dspHeader.GetHeaderLength();
+      if (index + dspHeaderLength >= endOfBuffer)
+      {
+        HLTError("The output buffer size is too small to write output."
+                 " It is only %d bytes, but we need at least %d bytes.",
+                 outBufferSize,
+                 sizeof(AliRawDataHeader) + (index+dspHeaderLength)*sizeof(UInt_t)
+        );
+        return -ENOBUFS;
+      }
+      
+      // DSP header
+      memcpy(&buffer[index],dspHeader.GetHeader(),dspHeaderLength*4);
+      Int_t indexDsp = index;
+      index += dspHeaderLength; 
+      
+      // 5 buspatches max per DSP
+      for (Int_t i = 0; i < iBusPerDSP[iDsp]; ++i) 
+      {
+        Int_t iBusPatch = ddl->GetBusPatchId(busIter++);
+        
+        // iteration over bus patch in DDL
+        if (iBusPatch == -1) 
+        {
+          AliWarning(Form("Error in bus itr in DDL %d\n", iDDL));
+          continue;
+        }
+        
+        AliMUONBusStruct* busStructPtr = static_cast<AliMUONBusStruct*>(busPatchMap.GetValue(iBusPatch));
+        
+        Int_t busHeaderLength = busStructPtr->GetHeaderLength();
+        if (index + busHeaderLength >= endOfBuffer)
+        {
+          HLTError("The output buffer size is too small to write output."
+                   " It is only %d bytes, but we need at least %d bytes.",
+                   outBufferSize,
+                   sizeof(AliRawDataHeader) + (index+busHeaderLength)*sizeof(UInt_t)
+          );
+          return -ENOBUFS;
+        }
+      
+        // check if buspatchid has digit
+        if (busStructPtr) 
+        {
+          // add bus patch structure header
+          memcpy(&buffer[index],busStructPtr->GetHeader(),busHeaderLength*4);
+          index += busHeaderLength;
+          
+          Int_t busLength = busStructPtr->GetLength();
+          if (index + busLength >= endOfBuffer)
+          {
+            HLTError("The output buffer size is too small to write output."
+                     " It is only %d bytes, but we need at least %d bytes.",
+                     outBufferSize,
+                     sizeof(AliRawDataHeader) + (index+busLength)*sizeof(UInt_t)
+            );
+            return -ENOBUFS;
+          }
+          
+          // add bus patch data
+          memcpy(&buffer[index],busStructPtr->GetData(),busLength*4);
+          index += busLength;
+        } 
+        else 
+        {
+          // writting anyhow buspatch structure (empty ones)
+          buffer[index++] = busStructPtr->GetDefaultDataKey(); // fill it also for empty data size
+          buffer[index++] = busStructPtr->GetHeaderLength(); // header length
+          buffer[index++] = 0; // raw data length
+          buffer[index++] = iBusPatch; // bus patch
+        }
+      } // bus patch
+      
+      if (index + 1 >= endOfBuffer)
+      {
+        HLTError("The output buffer size is too small to write output."
+                 " It is only %d bytes, but we need at least %d bytes.",
+                 outBufferSize,
+                 sizeof(AliRawDataHeader) + (index+1)*sizeof(UInt_t)
+        );
+        return -ENOBUFS;
+      }
+      
+      // check if totalLength even
+      // set padding word in case
+      // Add one word 0xBEEFFACE at the end of DSP structure
+      Int_t totalDspLength  = index - indexDsp;
+      if ((totalDspLength % 2) == 1) 
+      { 
+        buffer[indexDsp + dspHeader.GetHeaderLength() - 2] = 1;
+        buffer[index++] = dspHeader.GetDefaultPaddingWord();
+        totalDspLength++;
+      }
+      
+      Int_t dspLength     = totalDspLength - dspHeader.GetHeaderLength();
+      
+      buffer[indexDsp+1] = totalDspLength; // dsp total length
+      buffer[indexDsp+2] = dspLength; // data length  
+      
+    } // dsp
+    
+    Int_t totalBlkLength  = index - indexBlk;
+    Int_t blkLength       = totalBlkLength - blockHeader.GetHeaderLength();
+    totalDDLLength       += totalBlkLength;
+    
+    buffer[indexBlk+1] = totalBlkLength; // total block length
+    buffer[indexBlk+2] = blkLength;
+        
+  } // block
+  
+  if (index + 2 >= endOfBuffer)
+  {
+    HLTError("The output buffer size is too small to write output."
+             " It is only %d bytes, but we need at least %d bytes.",
+             outBufferSize,
+             sizeof(AliRawDataHeader) + (index+2)*sizeof(UInt_t)
+    );
+    return -ENOBUFS;
+  }
+  
+  // add twice the end of CRT structure data key
+  // hope it's good placed (ChF)
+  buffer[index++] = blockHeader.GetDdlDataKey();
+  buffer[index++] = blockHeader.GetDdlDataKey();
+  totalDDLLength  += 2;
+  
+  header->fSize = (totalDDLLength) * sizeof(Int_t) + sizeof(AliRawDataHeader);
+  outBufferSize = header->fSize;
+  
+  return 0;
+}
+
+//______________________________________________________________________________
+int AliHLTMUONDigitPublisherComponent::WriteTriggerDDL(
+               const AliMUONVTriggerStore* triggerStore, Int_t iDDL,
+               AliHLTUInt8_t* outBuffer, AliHLTUInt32_t& outBufferSize,
+               bool scalarEvent
+       )
+{
+  /// Write trigger DDL
+  
+  assert(0 <= iDDL and iDDL <= 19);
+  
+  AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
+  assert(ddlStore != NULL);
+  
+  if (outBufferSize < sizeof(AliRawDataHeader))
+  {
+       HLTError("The output buffer size is too small to write output."
+               " It is only %d bytes, but we need at least %d bytes.",
+               outBufferSize, sizeof(AliRawDataHeader)
+       );
+       return -ENOBUFS;
+  }
+  AliRawDataHeader* header = reinterpret_cast<AliRawDataHeader*>(outBuffer);
+  // Fill header with default values.
+  *header = AliRawDataHeader();
+  AliRunLoader* runloader = AliRunLoader::GetRunLoader();
+  if (runloader != NULL)
+  {
+    if (runloader->GetTrigger() != NULL)
+    {
+      AliCentralTrigger *aCTP = runloader->GetTrigger();
+      ULong64_t mask = aCTP->GetClassMask();
+      header->SetTriggerClass(mask);
+    }
+  }
+
+  // global trigger for trigger pattern
+  AliMUONGlobalTrigger* gloTrg = triggerStore->Global();
+  if (!gloTrg) 
+  {
+    return 0;
+  }
+  
+  Int_t gloTrigResp = gloTrg->GetGlobalResponse();
+
+  UInt_t word;
+  Int_t* buffer = reinterpret_cast<Int_t*>(header+1);
+  Int_t index;
+  Int_t locCard;
+  UChar_t locDec, trigY, posY, posX, regOut;
+  UInt_t regInpLpt;
+  UInt_t regInpHpt;
+
+  UInt_t devX;
+  UChar_t sdevX;
+  UInt_t version = 1; // software version
+  UInt_t eventPhys = 1; // trigger type: 1 for physics, 0 for software
+  UInt_t serialNb = 0xF; // serial nb of card: all bits on for the moment
+  Int_t globalFlag = 0; // set to 1 if global info present in DDL else set to 0
+
+  AliMUONDarcHeader  darcHeader;
+  AliMUONRegHeader   regHeader;
+  AliMUONLocalStruct localStruct;
+
+  // size of headers
+  static const Int_t kDarcHeaderLength   = darcHeader.GetDarcHeaderLength();
+  static const Int_t kGlobalHeaderLength = darcHeader.GetGlobalHeaderLength();
+  static const Int_t kDarcScalerLength   = darcHeader.GetDarcScalerLength();
+  static const Int_t kGlobalScalerLength = darcHeader.GetGlobalScalerLength();
+  static const Int_t kRegHeaderLength    = regHeader.GetHeaderLength();
+  static const Int_t kRegScalerLength    = regHeader.GetScalerLength();
+  static const Int_t kLocHeaderLength    = localStruct.GetLength();
+  static const Int_t kLocScalerLength    = localStruct.GetScalerLength();
+
+  // [16(local)*6 words + 6 words]*8(reg) + 8 words = 824 
+  static const Int_t kBufferSize = (16 * (kLocHeaderLength+1) +  (kRegHeaderLength+1))* 8 
+      +  kDarcHeaderLength + kGlobalHeaderLength + 2;
+
+  // [16(local)*51 words + 16 words]*8(reg) + 8 + 10 + 8 words scaler event 6682 words
+  static const Int_t kScalerBufferSize = (16 * (kLocHeaderLength +  kLocScalerLength +1) +  
+                                        (kRegHeaderLength + kRegScalerLength +1))* 8 +
+                                         (kDarcHeaderLength + kDarcScalerLength + 
+                                         kGlobalHeaderLength + kGlobalScalerLength + 2);
+  if(scalarEvent) {
+    eventPhys = 0; //set to generate scaler events
+    header->fWord2 |= (0x1 << 14); // set L1SwC bit on
+  }
+  if(scalarEvent)
+  {
+    if (outBufferSize < sizeof(AliRawDataHeader) + kScalerBufferSize)
+    {
+      HLTError("The output buffer size is too small to write output."
+               " It is only %d bytes, but we need at least %d bytes.",
+               outBufferSize, sizeof(AliRawDataHeader) + kScalerBufferSize
+      );
+      return -ENOBUFS;
+    }
+  }
+  else
+  {
+    if (outBufferSize < sizeof(AliRawDataHeader) + kBufferSize)
+    {
+      HLTError("The output buffer size is too small to write output."
+               " It is only %d bytes, but we need at least %d bytes.",
+               outBufferSize, sizeof(AliRawDataHeader) + kBufferSize
+      );
+      return -ENOBUFS;
+    }
+  }
+
+    index = 0; 
+
+    if (iDDL == 0) // suppose global info in DDL one
+      globalFlag = 1;
+    else 
+      globalFlag = 0;
+
+    word = 0;
+    // set darc status word
+    // see AliMUONDarcHeader.h for details
+    AliBitPacking::PackWord((UInt_t)eventPhys,word,30,30);
+    AliBitPacking::PackWord((UInt_t)serialNb,word,20,23);
+    AliBitPacking::PackWord((UInt_t)globalFlag,word,10,10);
+    AliBitPacking::PackWord((UInt_t)version,word,12,19);
+    darcHeader.SetWord(word);
+
+    memcpy(&buffer[index], darcHeader.GetHeader(), (kDarcHeaderLength)*4); 
+    index += kDarcHeaderLength;
+
+    // no global input for the moment....
+    if (iDDL == 0)
+     darcHeader.SetGlobalOutput(gloTrigResp);
+    else 
+     darcHeader.SetGlobalOutput(0);
+
+    if (scalarEvent) {
+      // 6 DARC scaler words
+      memcpy(&buffer[index], darcHeader.GetDarcScalers(),kDarcScalerLength*4);
+      index += kDarcScalerLength;
+    }
+    // end of darc word
+    buffer[index++] = darcHeader.GetEndOfDarc();
+
+    // 4 words of global board input + Global board output
+    memcpy(&buffer[index], darcHeader.GetGlobalInput(), (kGlobalHeaderLength)*4); 
+    index += kGlobalHeaderLength; 
+
+    if (scalarEvent) {
+      // 10 Global scaler words
+      memcpy(darcHeader.GetGlobalScalers(), &buffer[index], kGlobalScalerLength*4);
+      index += kGlobalScalerLength;
+    }
+
+    // end of global word
+    buffer[index++] = darcHeader.GetEndOfGlobal();
+    const AliMpRegionalTrigger* reg = ddlStore->GetRegionalTrigger(); 
+
+    Int_t nCrate = reg->GetNofTriggerCrates()/2;
+    // 8 regional cards per DDL
+    for (Int_t iReg = 0; iReg < nCrate; ++iReg) {
+
+        // crate info
+      AliMpTriggerCrate* crate = ddlStore->GetTriggerCrate(iDDL, iReg);
+
+      if (!crate) 
+       AliWarning(Form("Missing crate number %d in DDL %d\n", iReg, iDDL));
+
+      // regional info tree, make sure that no reg card missing
+      AliMUONRegionalTrigger* regTrg  = triggerStore->FindRegional(crate->GetId());
+      if (!regTrg) 
+        AliError(Form("Missing regional board %d in trigger Store\n", crate->GetId()));
+    
+      // Regional card header
+      word = 0;
+
+      // set darc status word
+      regHeader.SetDarcWord(word);
+
+      regOut    = regTrg->GetOutput();
+      regInpHpt = regTrg->GetLocalOutput(0);
+      regInpLpt = regTrg->GetLocalOutput(1);
+
+      // fill darc word, not darc status for the moment (empty)
+      //see  AliMUONRegHeader.h for details
+      AliBitPacking::PackWord((UInt_t)eventPhys,word,31,31); 
+      AliBitPacking::PackWord((UInt_t)serialNb,word,19,24); 
+      AliBitPacking::PackWord((UInt_t)version,word,7,14);
+      AliBitPacking::PackWord((UInt_t)iReg,word,15,18);
+      AliBitPacking::PackWord((UInt_t)regOut,word,0,7); 
+      regHeader.SetWord(word);
+
+
+      // fill header later, need local response
+      Int_t indexReg = index;
+      index += kRegHeaderLength;
+
+      // 11 regional scaler word
+      if (scalarEvent) {
+       memcpy(&buffer[index], regHeader.GetScalers(), kRegScalerLength*4);
+       index += kRegScalerLength;
+      }
+
+      // end of regional word
+      buffer[index++] = regHeader.GetEndOfReg();
+      
+      // 16 local card per regional board
+      //      UShort_t localMask = 0x0;
+      
+      Int_t nLocalBoard = AliMpConstants::LocalBoardNofChannels();
+
+      for (Int_t iLoc = 0; iLoc < nLocalBoard; iLoc++) {
+         
+       // slot zero for Regional card
+       Int_t localBoardId = crate->GetLocalBoardId(iLoc);
+
+       if (localBoardId) { // if not empty slot
+         AliMpLocalBoard* localBoard = ddlStore->GetLocalBoard(localBoardId);
+
+         if (localBoard->IsNotified()) {// if notified board 
+           AliMUONLocalTrigger* locTrg = triggerStore->FindLocal(localBoardId);
+
+           locCard = locTrg->LoCircuit();
+           locDec  = locTrg->GetLoDecision();
+           trigY   = locTrg->LoTrigY();
+           posY    = locTrg->LoStripY();
+           posX    = locTrg->LoStripX();
+           devX    = locTrg->LoDev();
+           sdevX   = locTrg->LoSdev();
+                 
+           AliDebug(4,Form("loctrg %d, posX %d, posY %d, devX %d\n", 
+                           locTrg->LoCircuit(),locTrg->LoStripX(),locTrg->LoStripY(),locTrg->LoDev()));  
+           //packing word
+           word = 0;
+           LocalWordPacking(word, (UInt_t)iLoc, (UInt_t)locDec, (UInt_t)trigY, (UInt_t)posY, 
+                            (UInt_t)posX, (UInt_t)sdevX, (UInt_t)devX);
+
+           buffer[index++] = (locTrg->GetX1Pattern() | (locTrg->GetX2Pattern() << 16));
+           buffer[index++] = (locTrg->GetX3Pattern() | (locTrg->GetX4Pattern() << 16));
+           buffer[index++] = (locTrg->GetY1Pattern() | (locTrg->GetY2Pattern() << 16));
+           buffer[index++] = (locTrg->GetY3Pattern() | (locTrg->GetY4Pattern() << 16));
+           buffer[index++] = (Int_t)word; // data word
+                     
+               
+         }
+         // fill copy card X-Y inputs from the notified cards 
+         if (localBoard->GetInputXfrom() && localBoard->GetInputYfrom()) 
+         {
+           // not triggered
+           locDec = 0; trigY = 1; posY = 15;    
+           posX   = 0; devX  = 0; sdevX = 1;
+           LocalWordPacking(word, (UInt_t)iLoc, (UInt_t)locDec, (UInt_t)trigY, (UInt_t)posY, 
+                            (UInt_t)posX, (UInt_t)sdevX, (UInt_t)devX);
+
+           Int_t localFromId = localBoard->GetInputXfrom();
+           AliMUONLocalTrigger* locTrgfrom  = triggerStore->FindLocal(localFromId);
+
+           buffer[index++] = 0; // copy only X3-4 & Y1-4
+           buffer[index++] = (locTrgfrom->GetX3Pattern() | (locTrgfrom->GetX4Pattern() << 16));
+           buffer[index++] = (locTrgfrom->GetY1Pattern() | (locTrgfrom->GetY2Pattern() << 16));
+           buffer[index++] = (locTrgfrom->GetY3Pattern() | (locTrgfrom->GetY4Pattern() << 16));
+           buffer[index++] = word;
+         }
+
+       } else { 
+         // fill with 10CDEAD word for empty slots
+         for (Int_t i = 0; i < localStruct.GetLength(); i++)
+             buffer[index++] = localStruct.GetDisableWord(); 
+       }// condition localBoard
+         
+       // 45 regional scaler word
+       if (scalarEvent) {
+         memcpy(&buffer[index], localStruct.GetScalers(), kLocScalerLength*4);
+         index += kLocScalerLength;
+       }
+         
+       // end of local structure words
+       buffer[index++] = localStruct.GetEndOfLocal();
+         
+      } // local card 
+      // fill regional header with local output
+      regHeader.SetInput(regInpHpt, 0);
+      regHeader.SetInput(regInpHpt, 1);
+      memcpy(&buffer[indexReg],regHeader.GetHeader(),kRegHeaderLength*4);
+      
+    } // Regional card
+
+  header->fSize = index * sizeof(Int_t) + sizeof(AliRawDataHeader);
+  outBufferSize = header->fSize;
+
+  return 0;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////////////////
index efd5760e472ae31351091fe3d3f7e0141f982c95..1ca547db52c3edbc567cbc41243ac854c032dddb 100644 (file)
 #define std
 #endif
 
+class AliMUONVDigitStore;
+class AliMUONVTriggerStore;
+class AliMpExMap;
+class AliMUONMCDataInterface;
+class AliMUONDataInterface;
+
 /**
  * @class AliHLTMUONDigitPublisherComponent
  * The component is used to convert simulated or reconstructed digits into DDL
@@ -37,6 +43,9 @@
  *       dimuon trigger.<br>
  *
  * Optional arguments:<br>
+ * \li -makescalars <br>
+ *       If set then the scalar events will be generated for the trigger DDLs.
+ *       (default is not to generate the scalars)<br>
  * \li -simdata <br>
  *       Indicates that the simulated digits should be used. (default option)<br>
  * \li -recdata <br>
@@ -93,12 +102,45 @@ private:
        AliHLTMUONDigitPublisherComponent(const AliHLTMUONDigitPublisherComponent& /*obj*/);
        AliHLTMUONDigitPublisherComponent& operator = (const AliHLTMUONDigitPublisherComponent& /*obj*/);
        
+       /////////////////////////////////////////////////////////////////////////////////////////
+       // Methods copied from AliMUONRawWriter.
+       //TODO: This is not ideal. We should have AliMUONRawWriter re-factored so that
+       // we can have raw data generated into a memory resident buffer, rather than
+       // always written to a file on disk, as it is now. But this will take some time
+       // since people need to be convinced of this fact.
+       void Digits2BusPatchMap(
+                       const AliMUONVDigitStore& digitStore,
+                       AliMpExMap& busPatchMap, Int_t iDDL
+               );
+       
+       int WriteTrackerDDL(
+                       const AliMUONVDigitStore* digitStore, Int_t iDDL,
+                       AliHLTUInt8_t* outBuffer, AliHLTUInt32_t& outBufferSize
+               );
+       
+       int WriteTriggerDDL(
+                       const AliMUONVTriggerStore* triggerStore, Int_t iDDL,
+                       AliHLTUInt8_t* outBuffer, AliHLTUInt32_t& outBufferSize,
+                       bool scalarEvent = false
+               );
+       
+       static void LocalWordPacking(UInt_t &word, UInt_t locId, UInt_t locDec,
+                               UInt_t trigY, UInt_t posY, UInt_t posX,
+                               UInt_t sdevX, UInt_t devX);
+       
+       /////////////////////////////////////////////////////////////////////////////////////////
+       
        AliHLTInt32_t fDDL;  ///< DDL number in the range [0..21]. Set to -1 for invalid/unspecified value.
        
        Int_t fCurrentEventIndex;  ///< The current event index that is to be loaded.
                                   //  -1 indicates that we should rather use the event
                                   // numbers as given by the system.
        
+       bool fMakeScalars;  ///< Flag indicating if the scalars should be generated for the trigger DDLs.
+       
+       AliMUONMCDataInterface* fMCDataInterface; ///< Access to MUON MC-related data.
+       AliMUONDataInterface* fDataInterface; ///< Access to MUON data.
+       
        ClassDef(AliHLTMUONDigitPublisherComponent, 0)  // dHLT component for publishing DDL streams from digits on the fly.
 };
 
index 96d8e3a022c23b2cfcfa4a886674129446e65ce2..594cfd4a6db5d4c4da95192a5860833a389aa779 100644 (file)
@@ -68,8 +68,8 @@ AliHLTMUONRecHitsSource::~AliHLTMUONRecHitsSource()
        /// Default destructor.
        ///
        
-       assert( fMCDataInterface == NULL );
-       assert( fDataInterface == NULL );
+       if (fMCDataInterface != NULL) delete fMCDataInterface;
+       if (fDataInterface != NULL) delete fDataInterface;
 }
 
 
@@ -79,9 +79,19 @@ int AliHLTMUONRecHitsSource::DoInit(int argc, const char** argv)
        /// Inherited from AliHLTComponent.
        /// Parses the command line parameters and initialises the component.
        ///
+       
+       HLTInfo("Initialising dHLT reconstructed hit source component.");
 
-       assert( fMCDataInterface == NULL );
-       assert( fDataInterface == NULL );
+       if (fMCDataInterface != NULL)
+       {
+               delete fMCDataInterface;
+               fMCDataInterface = NULL;
+       }
+       if (fDataInterface != NULL)
+       {
+               delete fDataInterface;
+               fDataInterface = NULL;
+       }
        
        // Parse the command line arguments:
        bool simdata = false;
@@ -305,6 +315,8 @@ int AliHLTMUONRecHitsSource::DoDeinit()
        /// Inherited from AliHLTComponent. Performs a cleanup of the component.
        ///
        
+       HLTInfo("Deinitialising dHLT reconstructed hit source component.");
+       
        if (fMCDataInterface != NULL)
        {
                delete fMCDataInterface;
@@ -395,12 +407,14 @@ int AliHLTMUONRecHitsSource::GetEvent(
        
        // Use the fEventID as the event number to load if fCurrentEventIndex == -1,
        // check it and load that event with the runloader.
-       // If fCurrentEventIndex is a positive number then us it instead and
+       // If fCurrentEventIndex is a positive number then use it instead and
        // increment it.
        UInt_t eventnumber = UInt_t(evtData.fEventID);
-       UInt_t maxevent = fMCDataInterface != NULL ?
-               UInt_t(fMCDataInterface->NumberOfEvents())
-               : UInt_t(fDataInterface->NumberOfEvents());
+       UInt_t maxevent = 0;
+       if (fMCDataInterface != NULL)
+               maxevent = UInt_t(fMCDataInterface->NumberOfEvents());
+       else if (fDataInterface != NULL)
+               maxevent = UInt_t(fDataInterface->NumberOfEvents());
        if (fCurrentEventIndex != -1)
        {
                eventnumber = UInt_t(fCurrentEventIndex);
index 56e6feb5bde3eae4154433e89d8c9245042e5ad7..8fe8f3af0e221c363eb4bc794e4fbbe24929e6e3 100644 (file)
@@ -105,8 +105,8 @@ AliHLTMUONTriggerRecordsSource::~AliHLTMUONTriggerRecordsSource()
        /// Default destructor.
        ///
        
-       assert( fMCDataInterface == NULL );
-       assert( fDataInterface == NULL );
+       if (fMCDataInterface != NULL) delete fMCDataInterface;
+       if (fDataInterface != NULL) delete fDataInterface;
 }
 
 
@@ -117,8 +117,18 @@ int AliHLTMUONTriggerRecordsSource::DoInit(int argc, const char** argv)
        /// Parses the command line parameters and initialises the component.
        ///
        
-       assert( fMCDataInterface == NULL );
-       assert( fDataInterface == NULL );
+       HLTInfo("Initialising dHLT trigger record source component.");
+       
+       if (fMCDataInterface != NULL)
+       {
+               delete fMCDataInterface;
+               fMCDataInterface = NULL;
+       }
+       if (fDataInterface != NULL)
+       {
+               delete fDataInterface;
+               fDataInterface = NULL;
+       }
        
        // Parse the command line arguments:
        bool hitdata = false;
@@ -317,6 +327,8 @@ int AliHLTMUONTriggerRecordsSource::DoDeinit()
        /// Inherited from AliHLTComponent. Performs a cleanup of the component.
        ///
        
+       HLTInfo("Deinitialising dHLT trigger record source component.");
+       
        if (fMCDataInterface != NULL)
        {
                delete fMCDataInterface;
@@ -409,12 +421,14 @@ int AliHLTMUONTriggerRecordsSource::GetEvent(
        
        // Use the fEventID as the event number to load if fCurrentEventIndex == -1,
        // check it and load that event with the runloader.
-       // If fCurrentEventIndex is a positive number then us it instead and
+       // If fCurrentEventIndex is a positive number then use it instead and
        // increment it.
        UInt_t eventnumber = UInt_t(evtData.fEventID);
-       UInt_t maxevent = fMCDataInterface != NULL ?
-               UInt_t(fMCDataInterface->NumberOfEvents())
-               : UInt_t(fDataInterface->NumberOfEvents());
+       UInt_t maxevent = 0;
+       if (fMCDataInterface != NULL)
+               maxevent = UInt_t(fMCDataInterface->NumberOfEvents());
+       else if (fDataInterface != NULL)
+               maxevent = UInt_t(fDataInterface->NumberOfEvents());
        if (fCurrentEventIndex != -1)
        {
                eventnumber = UInt_t(fCurrentEventIndex);