LCOV - code coverage report
Current view: top level - HLT/MUON/OfflineInterface - AliHLTMUONDigitPublisherComponent.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 16 605 2.6 %
Date: 2016-06-14 17:26:59 Functions: 7 21 33.3 %

          Line data    Source code
       1             : /**************************************************************************
       2             :  * This file is property of and copyright by the ALICE HLT Project        *
       3             :  * All rights reserved.                                                   *
       4             :  *                                                                        *
       5             :  * Primary Authors:                                                       *
       6             :  *   Artur Szostak <artursz@iafrica.com>                                  *
       7             :  *                                                                        *
       8             :  * Permission to use, copy, modify and distribute this software and its   *
       9             :  * documentation strictly for non-commercial purposes is hereby granted   *
      10             :  * without fee, provided that the above copyright notice appears in all   *
      11             :  * copies and that both the copyright notice and this permission notice   *
      12             :  * appear in the supporting documentation. The authors make no claims     *
      13             :  * about the suitability of this software for any purpose. It is          *
      14             :  * provided "as is" without express or implied warranty.                  *
      15             :  **************************************************************************/
      16             : 
      17             : // $Id: AliHLTMUONDigitPublisherComponent.cxx 26179 2008-05-29 22:27:27Z aszostak $
      18             : 
      19             : ///
      20             : /// @file   AliHLTMUONDigitPublisherComponent.cxx
      21             : /// @author Artur Szostak <artursz@iafrica.com>
      22             : /// @date   29 May 2008
      23             : /// @brief  Implementation of the dHLT digit publisher component.
      24             : ///
      25             : /// This component is used to publish simulated or reconstructed digits from
      26             : /// the digits trees as DDL raw data. The data is converted into DDL format
      27             : /// on the fly.
      28             : ///
      29             : 
      30             : #include "AliHLTMUONDigitPublisherComponent.h"
      31             : #include "AliHLTMUONConstants.h"
      32             : #include "AliHLTMUONUtils.h"
      33             : #include "AliHLTLogging.h"
      34             : #include "AliHLTSystem.h"
      35             : #include "AliHLTDefinitions.h"
      36             : #include "AliRawDataHeaderV3.h"
      37             : #include "AliMUONTrackerDDLDecoderEventHandler.h"
      38             : #include "AliMUONConstants.h"
      39             : #include "AliMUONMCDataInterface.h"
      40             : #include "AliMUONDataInterface.h"
      41             : #include "AliMUONVDigitStore.h"
      42             : #include "AliMUONVTriggerStore.h"
      43             : #include "AliMpExMap.h"
      44             : #include "AliMpCDB.h"
      45             : #include "AliMpDDL.h"
      46             : #include "AliMpDDLStore.h"
      47             : #include "AliMpDEManager.h"
      48             : #include "AliMpTriggerCrate.h"
      49             : #include "AliMpConstants.h"
      50             : #include "AliBitPacking.h"
      51             : #include "AliMUONBlockHeader.h"
      52             : #include "AliMUONBusStruct.h"
      53             : #include "AliMUONConstants.h"
      54             : #include "AliMUONDarcHeader.h"
      55             : #include "AliMUONVDigit.h"
      56             : #include "AliMUONDspHeader.h"
      57             : #include "AliMUONGlobalTrigger.h"
      58             : #include "AliMUONLocalStruct.h"
      59             : #include "AliMUONLocalTrigger.h"
      60             : #include "AliMUONLocalTriggerBoard.h"
      61             : #include "AliMUONRegionalTrigger.h"
      62             : #include "AliMUONRegHeader.h"
      63             : #include "AliRunLoader.h"
      64             : #include "AliCentralTrigger.h"
      65             : #include "AliLog.h"
      66             : #include <cstring>
      67             : #include <cstdlib>
      68             : #include <cmath>
      69             : #include <cerrno>
      70             : #include <cassert>
      71             : 
      72             : 
      73           6 : ClassImp(AliHLTMUONDigitPublisherComponent)
      74             : 
      75             : 
      76             : AliHLTMUONDigitPublisherComponent::AliHLTMUONDigitPublisherComponent() :
      77           3 :         AliHLTOfflineDataSource(),
      78           3 :         fDDL(-1),
      79           3 :         fCurrentEventIndex(0),
      80           3 :         fMakeScalars(false),
      81           3 :         fMCDataInterface(NULL),
      82           3 :         fDataInterface(NULL),
      83           3 :         fChamberExclusionList(0),
      84           3 :         fDetElemExclusionList(0)
      85          15 : {
      86             :         /// Default constructor.
      87           6 : }
      88             : 
      89             : 
      90           0 : AliHLTMUONDigitPublisherComponent::~AliHLTMUONDigitPublisherComponent()
      91          18 : {
      92             :         /// Default destructor.
      93             :         
      94           3 :         if (fMCDataInterface != NULL) delete fMCDataInterface;
      95           3 :         if (fDataInterface != NULL) delete fDataInterface;
      96           9 : }
      97             : 
      98             : const char* AliHLTMUONDigitPublisherComponent::GetComponentID()
      99             : {
     100             :         /// Inherited from AliHLTComponent. Returns the component ID.
     101             :         
     102         240 :         return AliHLTMUONConstants::DigitPublisherId();
     103             : }
     104             : 
     105             : 
     106             : AliHLTComponentDataType AliHLTMUONDigitPublisherComponent::GetOutputDataType()
     107             : {
     108             :         /// Inherited from AliHLTComponent. Returns the raw DDL data type.
     109             :         
     110           0 :         return AliHLTMUONConstants::DDLRawDataType();
     111             : }
     112             : 
     113             : 
     114             : void AliHLTMUONDigitPublisherComponent::GetOutputDataSize(
     115             :                 unsigned long& constBase, double& inputMultiplier
     116             :         )
     117             : {
     118             :         /// Inherited from AliHLTComponent.
     119             :         /// Returns an estimate of the expected output data size.
     120             :         
     121             :         // estimated as max number of channels * raw data word size + max headers size.
     122           0 :         constBase = sizeof(AliRawDataHeaderV3) + 65536*sizeof(UInt_t)
     123             :                 + sizeof(AliMUONBlockHeaderStruct)*2 + sizeof(AliMUONDSPHeaderStruct)*10
     124             :                 + sizeof(AliMUONBusPatchHeaderStruct) * 50;
     125           0 :         inputMultiplier = 0;
     126           0 : }
     127             : 
     128             : 
     129             : AliHLTComponent* AliHLTMUONDigitPublisherComponent::Spawn()
     130             : {
     131             :         /// Inherited from AliHLTComponent. Creates a new object instance.
     132             :         
     133           0 :         return new AliHLTMUONDigitPublisherComponent;
     134           0 : }
     135             : 
     136             : 
     137             : int AliHLTMUONDigitPublisherComponent::ParseChamberString(const char* str)
     138             : {
     139             :         /// Parses a string with the following format:
     140             :         ///   <number>|<number>-<number>[,<number>|<number>-<number>,...]
     141             :         /// For example: 1  1,2,3  1-2   1,2-4,5  etc...
     142             :         /// Chamber numbers must be in the range [1..10] for tracking chambers.
     143             :         /// All valid tracking chamber numbers will added to fChamberExclusionList.
     144             :         /// @param str  The string to parse.
     145             :         /// @return  Zero on success and EINVAL if there is a parse error.
     146             :         
     147           0 :         char* end = const_cast<char*>(str);
     148             :         long lastChamber = -1;
     149           0 :         do
     150             :         {
     151             :                 // Parse the next number.
     152           0 :                 char* current = end;
     153           0 :                 long chamber = strtol(current, &end, 0);
     154             :                 
     155             :                 // Check for parse errors of the number.
     156           0 :                 if (current == end)
     157             :                 {
     158           0 :                         HLTError("Expected a number in the range [1..%d] but got '%s'.",
     159             :                                 AliMUONConstants::NTrackingCh(), current
     160             :                         );
     161           0 :                         return -EINVAL;
     162             :                 }
     163           0 :                 if (chamber < 1 or AliMUONConstants::NTrackingCh() < chamber)
     164             :                 {
     165           0 :                         HLTError("Received the chamber number %d, which is outside the valid range of [1..%d].",
     166             :                                 chamber, AliMUONConstants::NTrackingCh()
     167             :                         );
     168           0 :                         return -EINVAL;
     169             :                 }
     170             :                 
     171             :                 // Skip any whitespace after the number
     172           0 :                 while (*end != '\0' and (*end == ' ' or *end == '\t' or *end == '\r' or *end == '\n')) end++;
     173             :                 
     174             :                 // Check if we are dealing with a list or range, or if we are at
     175             :                 // the end of the string.
     176           0 :                 if (*end == '-')
     177             :                 {
     178             :                         lastChamber = chamber;
     179           0 :                         end++;
     180           0 :                         continue;
     181             :                 }
     182           0 :                 else if (*end == ',')
     183             :                 {
     184           0 :                         assert( 1 <= chamber and chamber <= AliMUONConstants::NTrackingCh() );
     185           0 :                         Int_t size = fChamberExclusionList.GetSize();
     186           0 :                         fChamberExclusionList.Set(size+1);
     187           0 :                         fChamberExclusionList[size] = chamber-1;
     188           0 :                         end++;
     189           0 :                 }
     190           0 :                 else if (*end == '\0')
     191             :                 {
     192           0 :                         assert( 1 <= chamber and chamber <= AliMUONConstants::NTrackingCh() );
     193           0 :                         Int_t size = fChamberExclusionList.GetSize();
     194           0 :                         fChamberExclusionList.Set(size+1);
     195           0 :                         fChamberExclusionList[size] = chamber-1;
     196             :                 }
     197             :                 else
     198             :                 {
     199           0 :                         HLTError("Could not understand parameter list '%s'. Expected '-', ','"
     200             :                                   " or end of line, but received '%c' at character %d.",
     201             :                                 str, *end, (int)(end - str) +1
     202             :                         );
     203           0 :                         return -EINVAL;
     204             :                 }
     205             :                 
     206             :                 // Set the range of chambers to publish for.
     207           0 :                 if (lastChamber > 0)
     208             :                 {
     209             :                         Int_t min, max;
     210           0 :                         if (lastChamber < chamber)
     211             :                         {
     212           0 :                                 min = lastChamber;
     213           0 :                                 max = chamber;
     214           0 :                         }
     215             :                         else
     216             :                         {
     217           0 :                                 min = chamber;
     218           0 :                                 max = lastChamber;
     219             :                         }
     220           0 :                         assert( min >= 1 );
     221           0 :                         assert( max <= AliMUONConstants::NTrackingCh() );
     222           0 :                         for (Int_t i = min; i <= max; i++)
     223             :                         {
     224           0 :                                 Int_t size = fChamberExclusionList.GetSize();
     225           0 :                                 fChamberExclusionList.Set(size+1);
     226           0 :                                 fChamberExclusionList[size] = i-1;
     227             :                         }
     228           0 :                 }
     229             :                 lastChamber = -1;
     230           0 :         }
     231           0 :         while (*end != '\0');
     232           0 :         return 0;
     233           0 : }
     234             : 
     235             : 
     236             : int AliHLTMUONDigitPublisherComponent::ParseDetElemString(const char* str)
     237             : {
     238             :         /// Parses a string with the following format:
     239             :         ///   <number>|<number>-<number>[,<number>|<number>-<number>,...]
     240             :         /// For example: 100  100,201,208  100-104   105,202-204,503  etc...
     241             :         /// Detector element numbers must be in the range [100..1099] for tracking stations.
     242             :         /// All valid detector element numbers will added to fDetElemExclusionList.
     243             :         /// @param str  The string to parse.
     244             :         /// @return  Zero on success and EINVAL if there is a parse error.
     245             :         
     246           0 :         char* end = const_cast<char*>(str);
     247             :         long lastDetElem = -1;
     248           0 :         do
     249             :         {
     250             :                 // Parse the next number.
     251           0 :                 char* current = end;
     252           0 :                 long detElem = strtol(current, &end, 0);
     253             :                 
     254             :                 // Check for parse errors of the number.
     255           0 :                 if (current == end)
     256             :                 {
     257           0 :                         HLTError("Expected a number in the range [100..1099] but got '%s'.",
     258             :                                 current
     259             :                         );
     260           0 :                         return -EINVAL;
     261             :                 }
     262           0 :                 if (detElem < 100 or 1099 < detElem)
     263             :                 {
     264           0 :                         HLTError("Received the detector element ID number of %d,"
     265             :                                 " which is outside the valid range of [100..1099].",
     266             :                                 detElem
     267             :                         );
     268           0 :                         return -EINVAL;
     269             :                 }
     270             :                 
     271             :                 // Skip any whitespace after the number
     272           0 :                 while (*end != '\0' and (*end == ' ' or *end == '\t' or *end == '\r' or *end == '\n')) end++;
     273             :                 
     274             :                 // Check if we are dealing with a list or range, or if we are at
     275             :                 // the end of the string.
     276           0 :                 if (*end == '-')
     277             :                 {
     278             :                         lastDetElem = detElem;
     279           0 :                         end++;
     280           0 :                         continue;
     281             :                 }
     282           0 :                 else if (*end == ',')
     283             :                 {
     284           0 :                         assert( 100 <= detElem and detElem <= 1099 );
     285           0 :                         Int_t size = fDetElemExclusionList.GetSize();
     286           0 :                         fDetElemExclusionList.Set(size+1);
     287           0 :                         fDetElemExclusionList[size] = detElem-1;
     288           0 :                         end++;
     289           0 :                 }
     290           0 :                 else if (*end == '\0')
     291             :                 {
     292           0 :                         assert( 100 <= detElem and detElem <= 1099 );
     293           0 :                         Int_t size = fDetElemExclusionList.GetSize();
     294           0 :                         fDetElemExclusionList.Set(size+1);
     295           0 :                         fDetElemExclusionList[size] = detElem-1;
     296             :                 }
     297             :                 else
     298             :                 {
     299           0 :                         HLTError("Could not understand parameter list '%s'. Expected '-', ','"
     300             :                                   " or end of line, but received '%c' at character %d.",
     301             :                                 str, *end, (int)(end - str) +1
     302             :                         );
     303           0 :                         return -EINVAL;
     304             :                 }
     305             :                 
     306             :                 // Set the range of detector elements to publish for.
     307           0 :                 if (lastDetElem > 0)
     308             :                 {
     309             :                         Int_t min, max;
     310           0 :                         if (lastDetElem < detElem)
     311             :                         {
     312           0 :                                 min = lastDetElem;
     313           0 :                                 max = detElem;
     314           0 :                         }
     315             :                         else
     316             :                         {
     317           0 :                                 min = detElem;
     318           0 :                                 max = lastDetElem;
     319             :                         }
     320           0 :                         assert( min >= 100 );
     321           0 :                         assert( max <= 1099 );
     322           0 :                         for (Int_t i = min; i <= max; i++)
     323             :                         {
     324           0 :                                 Int_t size = fDetElemExclusionList.GetSize();
     325           0 :                                 fDetElemExclusionList.Set(size+1);
     326           0 :                                 fDetElemExclusionList[size] = i-1;
     327             :                         }
     328           0 :                 }
     329             :                 lastDetElem = -1;
     330           0 :         }
     331           0 :         while (*end != '\0');
     332           0 :         return 0;
     333           0 : }
     334             : 
     335             : 
     336             : int AliHLTMUONDigitPublisherComponent::DoInit(int argc, const char** argv)
     337             : {
     338             :         /// Inherited from AliHLTComponent.
     339             :         /// Parses the command line parameters and initialises the component.
     340             :         
     341           0 :         HLTInfo("Initialising dHLT digit publisher component.");
     342             : 
     343           0 :         if (fMCDataInterface != NULL)
     344             :         {
     345           0 :                 delete fMCDataInterface;
     346           0 :                 fMCDataInterface = NULL;
     347           0 :         }
     348           0 :         if (fDataInterface != NULL)
     349             :         {
     350           0 :                 delete fDataInterface;
     351           0 :                 fDataInterface = NULL;
     352           0 :         }
     353             :         
     354             :         // Initialise with default values.
     355           0 :         fDDL = -1;
     356           0 :         fCurrentEventIndex = 0;
     357           0 :         fMakeScalars = false;
     358           0 :         fChamberExclusionList.Set(0);
     359           0 :         fDetElemExclusionList.Set(0);
     360             :         bool simdata = false;
     361             :         bool recdata = false;
     362             :         bool firstEventSet = false;
     363             :         bool eventNumLitSet = false;
     364             : 
     365           0 :         for (int i = 0; i < argc; i++)
     366             :         {
     367           0 :                 if (strcmp(argv[i], "-makescalars") == 0)
     368             :                 {
     369           0 :                         fMakeScalars = true;
     370           0 :                         continue;
     371             :                 }
     372           0 :                 if (strcmp(argv[i], "-simdata") == 0)
     373             :                 {
     374             :                         simdata = true;
     375           0 :                         continue;
     376             :                 }
     377           0 :                 if (strcmp(argv[i], "-recdata") == 0)
     378             :                 {
     379             :                         recdata = true;
     380           0 :                         continue;
     381             :                 }
     382           0 :                 if (strcmp(argv[i], "-ddl") == 0)
     383             :                 {
     384           0 :                         if (argc <= i+1)
     385             :                         {
     386           0 :                                 HLTError("DDL number not specified. It must be in the range [1..22]" );
     387           0 :                                 return -EINVAL;
     388             :                         }
     389             :                 
     390           0 :                         char* cpErr = NULL;
     391           0 :                         unsigned long num = strtoul(argv[i+1], &cpErr, 0);
     392           0 :                         if (cpErr == NULL or *cpErr != '\0')
     393             :                         {
     394           0 :                                 HLTError("Cannot convert '%s' to a DDL number.", argv[i+1]);
     395           0 :                                 return -EINVAL;
     396             :                         }
     397           0 :                         if (num < 1 or 22 < num)
     398             :                         {
     399           0 :                                 HLTError("The DDL number must be in the range [1..22].");
     400           0 :                                 return -EINVAL;
     401             :                         }
     402           0 :                         fDDL = num - 1; // Convert to DDL number in the range 0..21
     403             :                         
     404             :                         i++;
     405           0 :                         continue;
     406           0 :                 }
     407           0 :                 if (strcmp(argv[i], "-ddlid") == 0)
     408             :                 {
     409           0 :                         if (argc <= i+1)
     410             :                         {
     411           0 :                                 HLTError("DDL equipment ID number not specified."
     412             :                                         " It must be in the range [2560..2579] or [2816..2817]."
     413             :                                 );
     414           0 :                                 return -EINVAL;
     415             :                         }
     416             :                 
     417           0 :                         char* cpErr = NULL;
     418           0 :                         unsigned long num = strtoul(argv[i+1], &cpErr, 0);
     419           0 :                         if (cpErr == NULL or *cpErr != '\0')
     420             :                         {
     421           0 :                                 HLTError("Cannot convert '%s' to a DDL equipment ID number.", argv[i+1]);
     422           0 :                                 return -EINVAL;
     423             :                         }
     424           0 :                         fDDL = AliHLTMUONUtils::EquipIdToDDLNumber(num); // Convert to DDL number in the range 0..21
     425           0 :                         if (fDDL < 0 or 21 < fDDL)
     426             :                         {
     427           0 :                                 HLTError("The DDL equipment ID number must be in the range"
     428             :                                         " [2560..2579] or [2816..2817]."
     429             :                                 );
     430           0 :                                 return -EINVAL;
     431             :                         }
     432             :                         
     433             :                         i++;
     434           0 :                         continue;
     435           0 :                 }
     436           0 :                 if (strcmp(argv[i], "-firstevent") == 0)
     437             :                 {
     438           0 :                         if (eventNumLitSet)
     439             :                         {
     440           0 :                                 HLTWarning("The -firstevent flag is overridden by a"
     441             :                                         " previous use of -event_number_literal."
     442             :                                 );
     443             :                         }
     444           0 :                         if (++i >= argc)
     445             :                         {
     446           0 :                                 HLTError("Expected a positive number after -firstevent.");
     447           0 :                                 return -EINVAL;
     448             :                         }
     449           0 :                         char* end = NULL;
     450           0 :                         long num = strtol(argv[i], &end, 0);
     451           0 :                         if ((end != NULL and *end != '\0') or num < 0) // Check if the conversion is OK.
     452             :                         {
     453           0 :                                 HLTError("Expected a positive number after -firstevent"
     454             :                                         " but got: %s", argv[i]
     455             :                                 );
     456           0 :                                 return -EINVAL;
     457             :                         }
     458           0 :                         fCurrentEventIndex = Int_t(num);
     459             :                         firstEventSet = true;
     460           0 :                         continue;
     461           0 :                 }
     462           0 :                 if (strcmp(argv[i], "-event_number_literal") == 0)
     463             :                 {
     464           0 :                         if (firstEventSet)
     465             :                         {
     466           0 :                                 HLTWarning("The -event_number_literal option will"
     467             :                                         " override -firstevent."
     468             :                                 );
     469             :                         }
     470           0 :                         fCurrentEventIndex = -1;
     471             :                         eventNumLitSet = true;
     472           0 :                         continue;
     473             :                 }
     474           0 :                 if (strcmp(argv[i], "-exclude_chamber") == 0)
     475             :                 {
     476           0 :                         if (argc <= i+1)
     477             :                         {
     478           0 :                                 HLTError("Expected a chamber number, a range eg. '1-10', or a list eg."
     479             :                                         " '1,2,3' after '-exclude_chamber'."
     480             :                                 );
     481           0 :                                 return -EINVAL;
     482             :                         }
     483             :                         
     484           0 :                         int result = ParseChamberString(argv[i+1]);
     485           0 :                         if (result != 0) return result;
     486             :                         i++;
     487           0 :                         continue;
     488             :                 }
     489           0 :                 if (strcmp(argv[i], "-exclude_detelem") == 0)
     490             :                 {
     491           0 :                         if (argc <= i+1)
     492             :                         {
     493           0 :                                 HLTError("Expected a detector element ID number, a range eg. '100-108',"
     494             :                                         " or a list eg. '100,102,301' after '-exclude_detelem'."
     495             :                                 );
     496           0 :                                 return -EINVAL;
     497             :                         }
     498             :                         
     499           0 :                         int result = ParseDetElemString(argv[i+1]);
     500           0 :                         if (result != 0) return result;
     501             :                         i++;
     502           0 :                         continue;
     503             :                 }
     504             :                 
     505           0 :                 HLTError("Unknown option '%s'.", argv[i]);
     506           0 :                 return -EINVAL;
     507             :         }
     508             :         
     509           0 :         if (fDDL == -1)
     510             :         {
     511           0 :                 HLTError("DDL number must be set with the -ddl option, but it was not.");
     512           0 :                 return -EINVAL;
     513             :         }
     514             :         
     515             :         // Must load the mapping data if it is not already loaded.
     516           0 :         if (AliMpDDLStore::Instance(false) == NULL)
     517             :         {
     518           0 :                 AliMpCDB::LoadDDLStore();
     519           0 :                 if (AliMpDDLStore::Instance(false) == NULL)
     520             :                 {
     521           0 :                         HLTError("Could not load the DDL mapping store from CDB.");
     522           0 :                         return -EFAULT;
     523             :                 }
     524             :         }
     525             :         
     526             :         // Now we can initialise the data interface objects and loaders.
     527           0 :         if (simdata)
     528             :         {
     529             :                 HLTDebug("Loading simulated digits with AliMUONMCDataInterface.");
     530             : 
     531             :                 try
     532             :                 {
     533           0 :                         fMCDataInterface = new AliMUONMCDataInterface("galice.root");
     534           0 :                 }
     535             :                 catch (const std::bad_alloc&)
     536             :                 {
     537           0 :                         HLTError("Not enough memory to allocate AliMUONMCDataInterface.");
     538             :                         return -ENOMEM;
     539           0 :                 }
     540           0 :         }
     541           0 :         else if (recdata)
     542             :         {
     543             :                 HLTDebug("Loading reconstructed digits with AliMUONDataInterface.");
     544             :                 
     545             :                 try
     546             :                 {
     547           0 :                         fDataInterface = new AliMUONDataInterface("galice.root");
     548           0 :                 }
     549             :                 catch (const std::bad_alloc&)
     550             :                 {
     551           0 :                         HLTError("Not enough memory to allocate AliMUONDataInterface.");
     552             :                         return -ENOMEM;
     553           0 :                 }
     554           0 :         }
     555             :         
     556             :         // Check that the fCurrentEventIndex number falls within the correct range.
     557             :         UInt_t maxevent = 0;
     558           0 :         if (fMCDataInterface != NULL)
     559           0 :                 maxevent = UInt_t(fMCDataInterface->NumberOfEvents());
     560           0 :         else if (fDataInterface != NULL)
     561           0 :                 maxevent = UInt_t(fDataInterface->NumberOfEvents());
     562           0 :         if (fCurrentEventIndex != -1 and UInt_t(fCurrentEventIndex) >= maxevent and maxevent != 0)
     563             :         {
     564           0 :                 fCurrentEventIndex = 0;
     565           0 :                 HLTWarning("The selected first event number (%d) was larger than"
     566             :                         " the available number of events (%d). Resetting the event"
     567             :                         " counter to zero.", fCurrentEventIndex, maxevent
     568             :                 );
     569             :         }
     570             : 
     571             :         return 0;
     572           0 : }
     573             : 
     574             : 
     575             : int AliHLTMUONDigitPublisherComponent::DoDeinit()
     576             : {
     577             :         /// Inherited from AliHLTComponent. Performs a cleanup of the component.
     578             :         
     579           0 :         HLTInfo("Deinitialising dHLT digit publisher component.");
     580             :         
     581           0 :         if (fMCDataInterface != NULL)
     582             :         {
     583           0 :                 delete fMCDataInterface;
     584           0 :                 fMCDataInterface = NULL;
     585           0 :         }
     586           0 :         if (fDataInterface != NULL)
     587             :         {
     588           0 :                 delete fDataInterface;
     589           0 :                 fDataInterface = NULL;
     590           0 :         }
     591           0 :         return 0;
     592             : }
     593             : 
     594             : 
     595             : int AliHLTMUONDigitPublisherComponent::GetEvent(
     596             :                 const AliHLTComponentEventData& evtData,
     597             :                 AliHLTComponentTriggerData& /*trigData*/,
     598             :                 AliHLTUInt8_t* outputPtr,
     599             :                 AliHLTUInt32_t& size,
     600             :                 AliHLTComponentBlockDataList& outputBlocks
     601             :         )
     602             : {
     603             :         /// Inherited from AliHLTOfflineDataSource.
     604             :         
     605           0 :         assert( fMCDataInterface != NULL or fDataInterface != NULL );
     606             :         
     607           0 :         if (not IsDataEvent()) return 0;  // ignore non data events.
     608             : 
     609             :         // Check the size of the event descriptor structure.
     610           0 :         if (evtData.fStructSize < sizeof(AliHLTComponentEventData))
     611             :         {
     612           0 :                 HLTError(kHLTLogError,
     613             :                         "The event descriptor (AliHLTComponentEventData) size is"
     614             :                           " smaller than expected. It claims to be %d bytes, but"
     615             :                           " we expect it to be %d bytes.",
     616             :                         evtData.fStructSize,
     617             :                         sizeof(AliHLTComponentEventData)
     618             :                 );
     619           0 :                 size = 0; // Important to tell framework that nothing was generated.
     620           0 :                 return -EINVAL;
     621             :         }
     622             :         
     623             :         // Use the fEventID as the event number to load if fCurrentEventIndex == -1,
     624             :         // check it and load that event with the runloader.
     625             :         // If fCurrentEventIndex is a positive number then use it instead and
     626             :         // increment it.
     627           0 :         UInt_t eventnumber = UInt_t(evtData.fEventID);
     628             :         UInt_t maxevent = 0;
     629           0 :         if (fMCDataInterface != NULL)
     630           0 :                 maxevent = UInt_t(fMCDataInterface->NumberOfEvents());
     631           0 :         else if (fDataInterface != NULL)
     632           0 :                 maxevent = UInt_t(fDataInterface->NumberOfEvents());
     633           0 :         if (fCurrentEventIndex != -1)
     634             :         {
     635             :                 eventnumber = UInt_t(fCurrentEventIndex);
     636           0 :                 fCurrentEventIndex++;
     637           0 :                 if (UInt_t(fCurrentEventIndex) >= maxevent)
     638           0 :                         fCurrentEventIndex = 0;
     639             :         }
     640           0 :         if ( eventnumber >= maxevent )
     641             :         {
     642           0 :                 HLTError("The event number (%d) is larger than the available number"
     643             :                           " of events on file (%d).",
     644             :                         eventnumber, maxevent
     645             :                 );
     646           0 :                 size = 0; // Important to tell framework that nothing was generated.
     647           0 :                 return -EINVAL;
     648             :         }
     649             :         
     650             :         const AliMUONVDigitStore* digitStore = NULL;
     651             :         const AliMUONVTriggerStore* triggerStore = NULL;
     652             :         
     653           0 :         if (fMCDataInterface != NULL)
     654             :         {
     655             :                 HLTDebug("Filling data block with simulated digits for event %d.", eventnumber);
     656             :                 
     657           0 :                 if (fDDL < 20)
     658             :                 {
     659           0 :                         digitStore = fMCDataInterface->DigitStore(eventnumber);
     660           0 :                 }
     661             :                 else
     662             :                 {
     663           0 :                         triggerStore = fMCDataInterface->TriggerStore(eventnumber);
     664             :                 }
     665             :         }
     666           0 :         else if (fDataInterface != NULL)
     667             :         {
     668             :                 HLTDebug("Filling data block with reconstructed digits for event %d.", eventnumber);
     669             :                 
     670           0 :                 if (fDDL < 20)
     671             :                 {
     672           0 :                         digitStore = fDataInterface->DigitStore(eventnumber);
     673           0 :                 }
     674             :                 else
     675             :                 {
     676           0 :                         triggerStore = fDataInterface->TriggerStore(eventnumber);
     677             :                 }
     678             :         }
     679             :         else
     680             :         {
     681           0 :                 HLTError("Neither AliMUONDataInterface nor AliMUONMCDataInterface were created.");
     682           0 :                 size = 0; // Important to tell framework that nothing was generated.
     683           0 :                 return -EFAULT;
     684             :         }
     685             :         
     686             :         // Make sure we have the correct CTP trigger loaded.
     687           0 :         AliRunLoader* runloader = AliRunLoader::Instance();
     688           0 :         if (runloader != NULL)
     689             :         {
     690           0 :                 if (runloader->GetTrigger() == NULL)
     691           0 :                         runloader->LoadTrigger();
     692           0 :                 runloader->GetEvent(eventnumber);
     693           0 :         }
     694             :         
     695           0 :         if (fDDL < 20 and digitStore != NULL)
     696             :         {
     697           0 :                 int result = WriteTrackerDDL(digitStore, fDDL, outputPtr, size);
     698           0 :                 if (result != 0)
     699             :                 {
     700           0 :                         size = 0; // Important to tell framework that nothing was generated.
     701           0 :                         return result;
     702             :                 }
     703           0 :         }
     704           0 :         else if (triggerStore != NULL)
     705             :         {
     706           0 :                 int result = WriteTriggerDDL(triggerStore, fDDL-20, outputPtr, size, fMakeScalars);
     707           0 :                 if (result != 0)
     708             :                 {
     709           0 :                         size = 0; // Important to tell framework that nothing was generated.
     710           0 :                         return result;
     711             :                 }
     712           0 :         }
     713             :         else
     714             :         {
     715           0 :                 size = 0; // Important to tell framework that nothing was generated.
     716           0 :                 return 0;
     717             :         }
     718             :         
     719           0 :         AliHLTComponentBlockData bd;
     720           0 :         FillBlockData(bd);
     721           0 :         bd.fPtr = outputPtr;
     722           0 :         bd.fOffset = 0;
     723           0 :         bd.fSize = size;
     724           0 :         bd.fDataType = AliHLTMUONConstants::DDLRawDataType();
     725           0 :         bd.fSpecification = AliHLTMUONUtils::DDLNumberToSpec(fDDL);
     726           0 :         outputBlocks.push_back(bd);
     727             :         
     728             :         return 0;
     729           0 : }
     730             : 
     731             : 
     732             : /////////////////////////////////////////////////////////////////////////////////////////
     733             : // Methods copied from AliMUONRawWriter.
     734             : //TODO: This is not ideal. We should have AliMUONRawWriter re-factored so that
     735             : // we can have raw data generated into a memory resident buffer, rather than
     736             : // always written to a file on disk, as it is now. But this will take some time
     737             : // since people need to be convinced of this fact.
     738             : 
     739             : //____________________________________________________________________
     740             : void  AliHLTMUONDigitPublisherComponent::LocalWordPacking(UInt_t& word, UInt_t locId, UInt_t locDec, 
     741             :                                          UInt_t trigY, UInt_t posY, UInt_t posX, 
     742             :                                          UInt_t sdevX, UInt_t devX)
     743             : {
     744             : /// pack local trigger word
     745             : 
     746           0 :     AliBitPacking::PackWord(locId,word,19,22); //card id number in crate
     747           0 :     AliBitPacking::PackWord(locDec,word,15,18);
     748           0 :     AliBitPacking::PackWord(trigY,word,14,14);
     749           0 :     AliBitPacking::PackWord(posY,word,10,13);
     750           0 :     AliBitPacking::PackWord(sdevX,word,9,9);
     751           0 :     AliBitPacking::PackWord(devX,word,5,8);
     752           0 :     AliBitPacking::PackWord(posX,word,0,4);
     753           0 : }
     754             : 
     755             : //______________________________________________________________________________
     756             : void 
     757             : AliHLTMUONDigitPublisherComponent::Digits2BusPatchMap(
     758             :                 const AliMUONVDigitStore& digitStore,
     759             :                 AliMpExMap& busPatchMap, Int_t iDDL
     760             :         )
     761             : {
     762             :   /// Create bus patch structures corresponding to digits in the store
     763             :   
     764           0 :   AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
     765           0 :   assert(ddlStore != NULL);
     766             :   
     767           0 :   AliMpDDL* ddl = ddlStore->GetDDL(iDDL);
     768           0 :   busPatchMap.SetSize(ddl->GetNofBusPatches());
     769             :   
     770           0 :   if (ddl->GetNofDEs() <= 0) return;
     771           0 :   Int_t minDetElem = ddl->GetDEId(0);
     772           0 :   Int_t maxDetElem = ddl->GetDEId(0);
     773           0 :   for (Int_t i = 1; i < ddl->GetNofDEs(); i++)
     774             :   {
     775           0 :     if (ddl->GetDEId(i) < minDetElem) minDetElem = ddl->GetDEId(i);
     776           0 :     if (ddl->GetDEId(i) > maxDetElem) maxDetElem = ddl->GetDEId(i);
     777             :   }
     778             :   
     779             :   static const Int_t kMAXADC = (1<<12)-1; // We code the charge on a 12 bits ADC.
     780             :     
     781             :   // DDL event one per half chamber
     782             :   
     783             :   // raw data
     784             :   Char_t parity = 0x4;
     785             :   UShort_t manuId = 0;
     786             :   UChar_t channelId = 0;
     787             :   UShort_t charge = 0;
     788             :   Int_t busPatchId = 0;
     789             :   Int_t currentBusPatchId = -1;
     790           0 :   UInt_t word;
     791             :   
     792             :   AliMUONBusStruct* busStruct(0x0);
     793             :   
     794           0 :   TIter next(digitStore.CreateIterator(minDetElem, maxDetElem));
     795             :   AliMUONVDigit* digit;
     796             :   
     797           0 :   while ( ( digit = static_cast<AliMUONVDigit*>(next()) ) )
     798             :   {
     799             :     // Check if we should exclude digits from a particular chamber or detector element.
     800             :     bool excludeDigit = false;
     801           0 :     for (Int_t i = 0; i < fDetElemExclusionList.GetSize(); i++)
     802             :     {
     803           0 :       if (digit->DetElemId() == fDetElemExclusionList[i])
     804             :       {
     805             :         excludeDigit = true;
     806           0 :         break;
     807             :       }
     808             :     }
     809           0 :     for (Int_t i = 0; i < fChamberExclusionList.GetSize(); i++)
     810             :     {
     811           0 :       if (AliMpDEManager::GetChamberId(digit->DetElemId()) == fChamberExclusionList[i])
     812             :       {
     813             :         excludeDigit = true;
     814           0 :         break;
     815             :       }
     816             :     }
     817           0 :     if (excludeDigit) continue;
     818             :   
     819           0 :     charge = digit->ADC();
     820           0 :     if ( charge > kMAXADC )
     821             :     {
     822             :       // This is most probably an error in the digitizer (which should insure
     823             :       // the adc is below kMAXADC), so make it a (non-fatal) error indeed.
     824           0 :       HLTError("ADC value %d above 0x%x for DE %d . Setting to 0x%x. Digit is:",
     825             :                     charge,kMAXADC,digit->DetElemId(),kMAXADC);
     826             :       charge = kMAXADC;
     827           0 :     }
     828             :     
     829             :     // inverse mapping
     830           0 :     busPatchId = ddlStore->GetBusPatchId(digit->DetElemId(), digit->ManuId());
     831             : 
     832           0 :     if (busPatchId<0) continue;
     833             :     
     834           0 :     if ( digit->ManuId() > 0x7FF ||
     835           0 :          digit->ManuChannel() > 0x3F )
     836             :     {
     837           0 :       HLTFatal("<%s>: ID %12u DE %4d Cath %d (Ix,Iy)=(%3d,%3d) (Manu,Channel)=(%4d,%2d)"
     838             :                ", Charge=%7.2f\nManuId,ManuChannel are invalid for this digit.",
     839             :                digit->ClassName(), digit->GetUniqueID(),
     840             :                digit->DetElemId(), digit->Cathode(), digit->PadX(), digit->PadY(),
     841             :                digit->ManuId(), digit->ManuChannel(), digit->Charge()
     842             :       );
     843             :     }
     844             :     
     845           0 :     manuId = ( digit->ManuId() & 0x7FF ); // 11 bits
     846           0 :     channelId = ( digit->ManuChannel() & 0x3F ); // 6 bits
     847             :     
     848             :     //packing word
     849           0 :     word = 0;
     850           0 :     AliBitPacking::PackWord((UInt_t)manuId,word,18,28);
     851           0 :     AliBitPacking::PackWord((UInt_t)channelId,word,12,17);
     852           0 :     AliBitPacking::PackWord((UInt_t)charge,word,0,11);
     853             :     
     854             :     // parity word
     855           0 :     parity = word & 0x1;
     856           0 :     for (Int_t i = 1; i <= 30; ++i) 
     857             :     {
     858           0 :       parity ^=  ((word >> i) & 0x1);
     859             :     }
     860           0 :     AliBitPacking::PackWord((UInt_t)parity,word,31,31);
     861             : 
     862           0 :     if ( currentBusPatchId != busPatchId ) 
     863             :     {
     864             :       busStruct = 
     865           0 :         static_cast<AliMUONBusStruct*>(busPatchMap.GetValue(busPatchId));
     866             :       currentBusPatchId = busPatchId;
     867           0 :     }
     868             :     
     869           0 :     if (!busStruct)
     870             :     {
     871           0 :       busStruct = new AliMUONBusStruct;
     872           0 :       busStruct->SetDataKey(busStruct->GetDefaultDataKey());
     873           0 :       busStruct->SetBusPatchId(busPatchId);
     874           0 :       busStruct->SetLength(0);
     875           0 :       busPatchMap.Add(busPatchId,busStruct);
     876             :     }
     877             :     
     878             :     // set sub Event
     879           0 :     busStruct->AddData(word);
     880           0 :   }
     881           0 : }
     882             : 
     883             : //______________________________________________________________________________
     884             : int AliHLTMUONDigitPublisherComponent::WriteTrackerDDL(
     885             :                 const AliMUONVDigitStore* digitStore, Int_t iDDL,
     886             :                 AliHLTUInt8_t* outBuffer, AliHLTUInt32_t& outBufferSize
     887             :         )
     888             : {
     889             :   /// Write DDL file for one tracker DDL
     890             :   
     891           0 :   assert(0 <= iDDL and iDDL <= 19);
     892             :   
     893           0 :   AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
     894           0 :   assert(ddlStore != NULL);
     895             :   
     896           0 :   if (ddlStore->GetDDL(iDDL) == NULL)
     897             :   {
     898           0 :         HLTError("Could not find DDL mapping for DDL %d.", iDDL+1);
     899           0 :         return -EFAULT;
     900             :   }
     901             :   
     902           0 :   AliMpExMap busPatchMap;
     903           0 :   Digits2BusPatchMap(*digitStore,busPatchMap,iDDL);
     904             :   
     905           0 :   AliMUONBlockHeader blockHeader;
     906           0 :   AliMUONDspHeader dspHeader;
     907           0 :   blockHeader.SetDataKey(blockHeader.GetDefaultDataKey());
     908           0 :   dspHeader.SetDataKey(dspHeader.GetDefaultDataKey());
     909             :   
     910           0 :   if (outBufferSize < sizeof(AliRawDataHeaderV3))
     911             :   {
     912           0 :         HLTError("The output buffer size is too small to write output."
     913             :                 " It is only %d bytes, but we need at least %d bytes.",
     914             :                 outBufferSize, sizeof(AliRawDataHeaderV3)
     915             :         );
     916           0 :         return -ENOBUFS;
     917             :   }
     918           0 :   AliRawDataHeaderV3* header = reinterpret_cast<AliRawDataHeaderV3*>(outBuffer);
     919             :   // Fill header with default values.
     920           0 :   *header = AliRawDataHeaderV3();
     921           0 :   AliRunLoader* runloader = AliRunLoader::Instance();
     922           0 :   if (runloader != NULL)
     923             :   {
     924           0 :     if (runloader->GetTrigger() != NULL)
     925             :     {
     926           0 :       AliCentralTrigger *aCTP = runloader->GetTrigger();
     927           0 :       ULong64_t mask = aCTP->GetClassMask();
     928           0 :       header->SetTriggerClass(mask);
     929           0 :       mask = aCTP->GetClassMaskNext50();
     930           0 :       header->SetTriggerClassNext50(mask);
     931           0 :     }
     932             :   }
     933             :   
     934           0 :   Int_t* buffer = reinterpret_cast<Int_t*>(header+1);
     935           0 :   Int_t endOfBuffer = (outBufferSize - sizeof(AliRawDataHeaderV3)) / sizeof(Int_t);
     936             :   
     937             :   // buffer size (max'ed out)
     938             :   // (((43 manus max per bus patch *64 channels + 4 bus patch words) * 5 bus patch 
     939             :   //   + 10 dsp words)*5 dsps + 8 block words)*2 blocks 
     940             :   
     941           0 :   AliMpDDL* ddl = ddlStore->GetDDL(iDDL);
     942           0 :   Int_t iDspMax = ddl->GetMaxDsp();
     943           0 :   Int_t iBusPerDSP[5]; //number of bus patches per DSP
     944           0 :   ddl->GetBusPerDsp(iBusPerDSP);
     945             :   Int_t busIter = 0;
     946             :   
     947             :   Int_t totalDDLLength = 0;
     948             :   
     949             :   Int_t index = 0;
     950             :   
     951             :   // two blocks A and B per DDL
     952           0 :   for (Int_t iBlock = 0; iBlock < 2; ++iBlock) 
     953             :   {
     954           0 :     Int_t length = blockHeader.GetHeaderLength();
     955           0 :     if (index + length >= endOfBuffer)
     956             :     {
     957           0 :       HLTError("The output buffer size is too small to write output."
     958             :                " It is only %d bytes, but we need at least %d bytes.",
     959             :                outBufferSize,
     960             :                sizeof(AliRawDataHeaderV3) + (index+length)*sizeof(UInt_t)
     961             :       );
     962           0 :       return -ENOBUFS;
     963             :     }
     964             :   
     965             :     // block header
     966           0 :     memcpy(&buffer[index],blockHeader.GetHeader(),length*4);
     967             :     Int_t indexBlk = index;
     968             :     index += length; 
     969             :     
     970             :     // 5 DSP's max per block
     971           0 :     for (Int_t iDsp = 0; iDsp < iDspMax; ++iDsp) 
     972             :     {
     973           0 :       Int_t dspHeaderLength = dspHeader.GetHeaderLength();
     974           0 :       if (index + dspHeaderLength >= endOfBuffer)
     975             :       {
     976           0 :         HLTError("The output buffer size is too small to write output."
     977             :                  " It is only %d bytes, but we need at least %d bytes.",
     978             :                  outBufferSize,
     979             :                  sizeof(AliRawDataHeaderV3) + (index+dspHeaderLength)*sizeof(UInt_t)
     980             :         );
     981           0 :         return -ENOBUFS;
     982             :       }
     983             :       
     984             :       // DSP header
     985           0 :       memcpy(&buffer[index],dspHeader.GetHeader(),dspHeaderLength*4);
     986             :       Int_t indexDsp = index;
     987             :       index += dspHeaderLength; 
     988             :       
     989             :       // 5 buspatches max per DSP
     990           0 :       for (Int_t i = 0; i < iBusPerDSP[iDsp]; ++i) 
     991             :       {
     992           0 :         Int_t iBusPatch = ddl->GetBusPatchId(busIter++);
     993             :         
     994             :         // iteration over bus patch in DDL
     995           0 :         if (iBusPatch == -1) 
     996             :         {
     997           0 :           AliWarning(Form("Error in bus itr in DDL %d\n", iDDL));
     998           0 :           continue;
     999             :         }
    1000             :         
    1001           0 :         AliMUONBusStruct* busStructPtr = static_cast<AliMUONBusStruct*>(busPatchMap.GetValue(iBusPatch));
    1002             :         
    1003           0 :         Int_t busHeaderLength = busStructPtr->GetHeaderLength();
    1004           0 :         if (index + busHeaderLength >= endOfBuffer)
    1005             :         {
    1006           0 :           HLTError("The output buffer size is too small to write output."
    1007             :                    " It is only %d bytes, but we need at least %d bytes.",
    1008             :                    outBufferSize,
    1009             :                    sizeof(AliRawDataHeaderV3) + (index+busHeaderLength)*sizeof(UInt_t)
    1010             :           );
    1011           0 :           return -ENOBUFS;
    1012             :         }
    1013             :       
    1014             :         // check if buspatchid has digit
    1015           0 :         if (busStructPtr) 
    1016             :         {
    1017             :           // add bus patch structure header
    1018           0 :           memcpy(&buffer[index],busStructPtr->GetHeader(),busHeaderLength*4);
    1019             :           index += busHeaderLength;
    1020             :           
    1021           0 :           Int_t busLength = busStructPtr->GetLength();
    1022           0 :           if (index + busLength >= endOfBuffer)
    1023             :           {
    1024           0 :             HLTError("The output buffer size is too small to write output."
    1025             :                      " It is only %d bytes, but we need at least %d bytes.",
    1026             :                      outBufferSize,
    1027             :                      sizeof(AliRawDataHeaderV3) + (index+busLength)*sizeof(UInt_t)
    1028             :             );
    1029           0 :             return -ENOBUFS;
    1030             :           }
    1031             :           
    1032             :           // add bus patch data
    1033           0 :           memcpy(&buffer[index],busStructPtr->GetData(),busLength*4);
    1034             :           index += busLength;
    1035           0 :         } 
    1036             :         else 
    1037             :         {
    1038             :           // writting anyhow buspatch structure (empty ones)
    1039           0 :           buffer[index++] = busStructPtr->GetDefaultDataKey(); // fill it also for empty data size
    1040           0 :           buffer[index++] = busStructPtr->GetHeaderLength(); // header length
    1041           0 :           buffer[index++] = 0; // raw data length
    1042           0 :           buffer[index++] = iBusPatch; // bus patch
    1043             :         }
    1044           0 :       } // bus patch
    1045             :       
    1046           0 :       if (index + 1 >= endOfBuffer)
    1047             :       {
    1048           0 :         HLTError("The output buffer size is too small to write output."
    1049             :                  " It is only %d bytes, but we need at least %d bytes.",
    1050             :                  outBufferSize,
    1051             :                  sizeof(AliRawDataHeaderV3) + (index+1)*sizeof(UInt_t)
    1052             :         );
    1053           0 :         return -ENOBUFS;
    1054             :       }
    1055             :       
    1056             :       // check if totalLength even
    1057             :       // set padding word in case
    1058             :       // Add one word 0xBEEFFACE at the end of DSP structure
    1059           0 :       Int_t totalDspLength  = index - indexDsp;
    1060           0 :       if ((totalDspLength % 2) == 1) 
    1061             :       { 
    1062           0 :         buffer[indexDsp + dspHeader.GetHeaderLength() - 2] = 1;
    1063           0 :         buffer[index++] = dspHeader.GetDefaultPaddingWord();
    1064           0 :         totalDspLength++;
    1065           0 :       }
    1066             :       
    1067           0 :       Int_t dspLength     = totalDspLength - dspHeader.GetHeaderLength();
    1068             :       
    1069           0 :       buffer[indexDsp+1] = totalDspLength; // dsp total length
    1070           0 :       buffer[indexDsp+2] = dspLength; // data length  
    1071             :       
    1072           0 :     } // dsp
    1073             :     
    1074           0 :     Int_t totalBlkLength  = index - indexBlk;
    1075           0 :     Int_t blkLength       = totalBlkLength - blockHeader.GetHeaderLength();
    1076           0 :     totalDDLLength       += totalBlkLength;
    1077             :     
    1078           0 :     buffer[indexBlk+1] = totalBlkLength; // total block length
    1079           0 :     buffer[indexBlk+2] = blkLength;
    1080             :         
    1081           0 :   } // block
    1082             :   
    1083           0 :   if (index + 2 >= endOfBuffer)
    1084             :   {
    1085           0 :     HLTError("The output buffer size is too small to write output."
    1086             :              " It is only %d bytes, but we need at least %d bytes.",
    1087             :              outBufferSize,
    1088             :              sizeof(AliRawDataHeaderV3) + (index+2)*sizeof(UInt_t)
    1089             :     );
    1090           0 :     return -ENOBUFS;
    1091             :   }
    1092             :   
    1093             :   // add twice the end of CRT structure data key
    1094             :   // hope it's good placed (ChF)
    1095           0 :   buffer[index++] = blockHeader.GetDdlDataKey();
    1096           0 :   buffer[index++] = blockHeader.GetDdlDataKey();
    1097           0 :   totalDDLLength  += 2;
    1098             :   
    1099           0 :   header->fSize = (totalDDLLength) * sizeof(Int_t) + sizeof(AliRawDataHeaderV3);
    1100           0 :   outBufferSize = header->fSize;
    1101             :   
    1102           0 :   return 0;
    1103           0 : }
    1104             : 
    1105             : //______________________________________________________________________________
    1106             : int AliHLTMUONDigitPublisherComponent::WriteTriggerDDL(
    1107             :                 const AliMUONVTriggerStore* triggerStore, Int_t iDDL,
    1108             :                 AliHLTUInt8_t* outBuffer, AliHLTUInt32_t& outBufferSize,
    1109             :                 bool scalarEvent
    1110             :         )
    1111             : {
    1112             :   /// Write trigger DDL
    1113             :   
    1114           0 :   assert(0 <= iDDL and iDDL <= 19);
    1115             :   
    1116           0 :   AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
    1117           0 :   assert(ddlStore != NULL);
    1118             :   
    1119           0 :   if (outBufferSize < sizeof(AliRawDataHeaderV3))
    1120             :   {
    1121           0 :         HLTError("The output buffer size is too small to write output."
    1122             :                 " It is only %d bytes, but we need at least %d bytes.",
    1123             :                 outBufferSize, sizeof(AliRawDataHeaderV3)
    1124             :         );
    1125           0 :         return -ENOBUFS;
    1126             :   }
    1127           0 :   AliRawDataHeaderV3* header = reinterpret_cast<AliRawDataHeaderV3*>(outBuffer);
    1128             :   // Fill header with default values.
    1129           0 :   *header = AliRawDataHeaderV3();
    1130           0 :   AliRunLoader* runloader = AliRunLoader::Instance();
    1131           0 :   if (runloader != NULL)
    1132             :   {
    1133           0 :     if (runloader->GetTrigger() != NULL)
    1134             :     {
    1135           0 :       AliCentralTrigger *aCTP = runloader->GetTrigger();
    1136           0 :       ULong64_t mask = aCTP->GetClassMask();
    1137           0 :       header->SetTriggerClass(mask);
    1138           0 :     }
    1139             :   }
    1140             : 
    1141             :   // global trigger for trigger pattern
    1142           0 :   AliMUONGlobalTrigger* gloTrg = triggerStore->Global();
    1143           0 :   if (!gloTrg) 
    1144             :   {
    1145           0 :     return 0;
    1146             :   }
    1147             :   
    1148           0 :   Int_t gloTrigResp = gloTrg->GetGlobalResponse();
    1149             : 
    1150           0 :   UInt_t word;
    1151           0 :   Int_t* buffer = reinterpret_cast<Int_t*>(header+1);
    1152             :   Int_t index;
    1153             :   //Int_t locCard;
    1154             :   UChar_t locDec, trigY, posY, posX, regOut;
    1155             :   UInt_t regInpLpt;
    1156             :   UInt_t regInpHpt;
    1157             : 
    1158             :   UInt_t devX;
    1159             :   UChar_t sdevX;
    1160             :   UInt_t version = 1; // software version
    1161             :   UInt_t eventPhys = 1; // trigger type: 1 for physics, 0 for software
    1162             :   UInt_t serialNb = 0xF; // serial nb of card: all bits on for the moment
    1163             :   Int_t globalFlag = 0; // set to 1 if global info present in DDL else set to 0
    1164             : 
    1165           0 :   AliMUONDarcHeader  darcHeader;
    1166           0 :   AliMUONRegHeader   regHeader;
    1167           0 :   AliMUONLocalStruct localStruct;
    1168             : 
    1169             :   // size of headers
    1170           0 :   static const Int_t kDarcHeaderLength   = darcHeader.GetDarcHeaderLength();
    1171           0 :   static const Int_t kGlobalHeaderLength = darcHeader.GetGlobalHeaderLength();
    1172           0 :   static const Int_t kDarcScalerLength   = darcHeader.GetDarcScalerLength();
    1173           0 :   static const Int_t kGlobalScalerLength = darcHeader.GetGlobalScalerLength();
    1174           0 :   static const Int_t kRegHeaderLength    = regHeader.GetHeaderLength();
    1175           0 :   static const Int_t kRegScalerLength    = regHeader.GetScalerLength();
    1176           0 :   static const Int_t kLocHeaderLength    = localStruct.GetLength();
    1177           0 :   static const Int_t kLocScalerLength    = localStruct.GetScalerLength();
    1178             : 
    1179             :   // [16(local)*6 words + 6 words]*8(reg) + 8 words = 824 
    1180           0 :   static const Int_t kBufferSize = (16 * (kLocHeaderLength+1) +  (kRegHeaderLength+1))* 8 
    1181           0 :       +  kDarcHeaderLength + kGlobalHeaderLength + 2;
    1182             : 
    1183             :   // [16(local)*51 words + 16 words]*8(reg) + 8 + 10 + 8 words scaler event 6682 words
    1184           0 :   static const Int_t kScalerBufferSize = (16 * (kLocHeaderLength +  kLocScalerLength +1) +  
    1185           0 :                                          (kRegHeaderLength + kRegScalerLength +1))* 8 +
    1186           0 :                                          (kDarcHeaderLength + kDarcScalerLength + 
    1187           0 :                                           kGlobalHeaderLength + kGlobalScalerLength + 2);
    1188           0 :   if(scalarEvent) {
    1189             :     eventPhys = 0; //set to generate scaler events
    1190           0 :     header->fWord2 |= (0x1 << 14); // set L1SwC bit on
    1191           0 :   }
    1192           0 :   if(scalarEvent)
    1193             :   {
    1194           0 :     if (outBufferSize < sizeof(AliRawDataHeaderV3) + kScalerBufferSize)
    1195             :     {
    1196           0 :       HLTError("The output buffer size is too small to write output."
    1197             :                " It is only %d bytes, but we need at least %d bytes.",
    1198             :                outBufferSize, sizeof(AliRawDataHeaderV3) + kScalerBufferSize
    1199             :       );
    1200           0 :       return -ENOBUFS;
    1201             :     }
    1202             :   }
    1203             :   else
    1204             :   {
    1205           0 :     if (outBufferSize < sizeof(AliRawDataHeaderV3) + kBufferSize)
    1206             :     {
    1207           0 :       HLTError("The output buffer size is too small to write output."
    1208             :                " It is only %d bytes, but we need at least %d bytes.",
    1209             :                outBufferSize, sizeof(AliRawDataHeaderV3) + kBufferSize
    1210             :       );
    1211           0 :       return -ENOBUFS;
    1212             :     }
    1213             :   }
    1214             : 
    1215             :     index = 0; 
    1216             : 
    1217           0 :     if (iDDL == 0) // suppose global info in DDL one
    1218           0 :       globalFlag = 1;
    1219             :     else 
    1220             :       globalFlag = 0;
    1221             : 
    1222           0 :     word = 0;
    1223             :     // set darc status word
    1224             :     // see AliMUONDarcHeader.h for details
    1225           0 :     AliBitPacking::PackWord((UInt_t)eventPhys,word,30,30);
    1226           0 :     AliBitPacking::PackWord((UInt_t)serialNb,word,20,23);
    1227           0 :     AliBitPacking::PackWord((UInt_t)globalFlag,word,10,10);
    1228           0 :     AliBitPacking::PackWord((UInt_t)version,word,12,19);
    1229           0 :     darcHeader.SetWord(word);
    1230             : 
    1231           0 :     memcpy(&buffer[index], darcHeader.GetHeader(), (kDarcHeaderLength)*4); 
    1232           0 :     index += kDarcHeaderLength;
    1233             : 
    1234             :     // no global input for the moment....
    1235           0 :     if (iDDL == 0)
    1236           0 :      darcHeader.SetGlobalOutput(gloTrigResp);
    1237             :     else 
    1238           0 :      darcHeader.SetGlobalOutput(0);
    1239             : 
    1240           0 :     if (scalarEvent) {
    1241             :       // 6 DARC scaler words
    1242           0 :       memcpy(&buffer[index], darcHeader.GetDarcScalers(),kDarcScalerLength*4);
    1243           0 :       index += kDarcScalerLength;
    1244           0 :     }
    1245             :     // end of darc word
    1246           0 :     buffer[index++] = darcHeader.GetEndOfDarc();
    1247             : 
    1248             :     // 4 words of global board input + Global board output
    1249           0 :     memcpy(&buffer[index], darcHeader.GetGlobalInput(), (kGlobalHeaderLength)*4); 
    1250           0 :     index += kGlobalHeaderLength; 
    1251             : 
    1252           0 :     if (scalarEvent) {
    1253             :       // 10 Global scaler words
    1254           0 :       memcpy(darcHeader.GetGlobalScalers(), &buffer[index], kGlobalScalerLength*4);
    1255           0 :       index += kGlobalScalerLength;
    1256           0 :     }
    1257             : 
    1258             :     // end of global word
    1259           0 :     buffer[index++] = darcHeader.GetEndOfGlobal();
    1260           0 :     const AliMpRegionalTrigger* reg = ddlStore->GetRegionalTrigger(); 
    1261             : 
    1262           0 :     Int_t nCrate = reg->GetNofTriggerCrates()/2;
    1263             :     // 8 regional cards per DDL
    1264           0 :     for (Int_t iReg = 0; iReg < nCrate; ++iReg) {
    1265             : 
    1266             :         // crate info
    1267           0 :       AliMpTriggerCrate* crate = ddlStore->GetTriggerCrate(iDDL, iReg);
    1268             : 
    1269           0 :       if (!crate)
    1270             :       {
    1271           0 :         AliWarning(Form("Missing crate number %d in DDL %d\n", iReg, iDDL));
    1272           0 :         continue;
    1273             :       }
    1274             :       
    1275             :       // regional info tree, make sure that no reg card missing
    1276           0 :       AliMUONRegionalTrigger* regTrg  = triggerStore->FindRegional(crate->GetId());
    1277           0 :       if (!regTrg)
    1278             :       {
    1279           0 :         AliError(Form("Missing regional board %d in trigger Store\n", crate->GetId()));
    1280           0 :         continue;
    1281             :       }
    1282             :       
    1283             :       // Regional card header
    1284           0 :       word = 0;
    1285             : 
    1286             :       // set darc status word
    1287           0 :       regHeader.SetDarcWord(word);
    1288             : 
    1289           0 :       regOut    = regTrg->GetOutput();
    1290           0 :       regInpHpt = regTrg->GetLocalOutput(0);
    1291           0 :       regInpLpt = regTrg->GetLocalOutput(1);
    1292             : 
    1293             :       // fill darc word, not darc status for the moment (empty)
    1294             :       //see  AliMUONRegHeader.h for details
    1295           0 :       AliBitPacking::PackWord((UInt_t)eventPhys,word,31,31); 
    1296           0 :       AliBitPacking::PackWord((UInt_t)serialNb,word,20,25); 
    1297           0 :       AliBitPacking::PackWord((UInt_t)version,word,8,15);
    1298           0 :       AliBitPacking::PackWord((UInt_t)crate->GetId(),word,16,19);
    1299           0 :       AliBitPacking::PackWord((UInt_t)regOut,word,0,7);
    1300           0 :       regHeader.SetWord(word);
    1301             : 
    1302             : 
    1303             :       // fill header later, need local response
    1304             :       Int_t indexReg = index;
    1305           0 :       index += kRegHeaderLength;
    1306             : 
    1307             :       // 11 regional scaler word
    1308           0 :       if (scalarEvent) {
    1309           0 :         memcpy(&buffer[index], regHeader.GetScalers(), kRegScalerLength*4);
    1310           0 :         index += kRegScalerLength;
    1311           0 :       }
    1312             : 
    1313             :       // end of regional word
    1314           0 :       buffer[index++] = regHeader.GetEndOfReg();
    1315             :       
    1316             :       // 16 local card per regional board
    1317             :       //      UShort_t localMask = 0x0;
    1318             :       
    1319           0 :       Int_t nLocalBoard = AliMpConstants::LocalBoardNofChannels();
    1320             : 
    1321           0 :       for (Int_t iLoc = 0; iLoc < nLocalBoard; iLoc++) {
    1322             :           
    1323             :         // slot zero for Regional card
    1324           0 :         Int_t localBoardId = crate->GetLocalBoardId(iLoc);
    1325             : 
    1326           0 :         if (localBoardId) { // if not empty slot
    1327           0 :           AliMpLocalBoard* localBoard = ddlStore->GetLocalBoard(localBoardId);
    1328             : 
    1329           0 :           if (localBoard->IsNotified()) {// if notified board 
    1330           0 :             AliMUONLocalTrigger* locTrg = triggerStore->FindLocal(localBoardId);
    1331             : 
    1332             :             //locCard = locTrg->LoCircuit();
    1333           0 :             locDec  = locTrg->GetLoDecision();
    1334           0 :             trigY   = locTrg->LoTrigY();
    1335           0 :             posY    = locTrg->LoStripY();
    1336           0 :             posX    = locTrg->LoStripX();
    1337           0 :             devX    = locTrg->LoDev();
    1338           0 :             sdevX   = locTrg->LoSdev();
    1339             :                   
    1340           0 :             AliDebug(4,Form("loctrg %d, posX %d, posY %d, devX %d\n", 
    1341             :                             locTrg->LoCircuit(),locTrg->LoStripX(),locTrg->LoStripY(),locTrg->LoDev()));  
    1342             :             //packing word
    1343           0 :             word = 0;
    1344           0 :             LocalWordPacking(word, (UInt_t)iLoc, (UInt_t)locDec, (UInt_t)trigY, (UInt_t)posY, 
    1345           0 :                              (UInt_t)posX, (UInt_t)sdevX, (UInt_t)devX);
    1346             : 
    1347           0 :             buffer[index++] = (locTrg->GetX1Pattern() | (locTrg->GetX2Pattern() << 16));
    1348           0 :             buffer[index++] = (locTrg->GetX3Pattern() | (locTrg->GetX4Pattern() << 16));
    1349           0 :             buffer[index++] = (locTrg->GetY1Pattern() | (locTrg->GetY2Pattern() << 16));
    1350           0 :             buffer[index++] = (locTrg->GetY3Pattern() | (locTrg->GetY4Pattern() << 16));
    1351           0 :             buffer[index++] = (Int_t)word; // data word
    1352             :                       
    1353             :                 
    1354           0 :           }
    1355             :           // fill copy card X-Y inputs from the notified cards 
    1356           0 :           if (localBoard->GetInputXfrom() && localBoard->GetInputYfrom()) 
    1357             :           {
    1358             :             // not triggered
    1359             :             locDec = 0; trigY = 1; posY = 15;    
    1360             :             posX   = 0; devX  = 0; sdevX = 1;
    1361           0 :             LocalWordPacking(word, (UInt_t)iLoc, (UInt_t)locDec, (UInt_t)trigY, (UInt_t)posY, 
    1362             :                              (UInt_t)posX, (UInt_t)sdevX, (UInt_t)devX);
    1363             : 
    1364           0 :             Int_t localFromId = localBoard->GetInputXfrom();
    1365           0 :             AliMUONLocalTrigger* locTrgfrom  = triggerStore->FindLocal(localFromId);
    1366             : 
    1367           0 :             buffer[index++] = 0; // copy only X3-4 & Y1-4
    1368           0 :             buffer[index++] = (locTrgfrom->GetX3Pattern() | (locTrgfrom->GetX4Pattern() << 16));
    1369           0 :             buffer[index++] = (locTrgfrom->GetY1Pattern() | (locTrgfrom->GetY2Pattern() << 16));
    1370           0 :             buffer[index++] = (locTrgfrom->GetY3Pattern() | (locTrgfrom->GetY4Pattern() << 16));
    1371           0 :             buffer[index++] = word;
    1372           0 :           }
    1373             : 
    1374           0 :         } else { 
    1375             :           // fill with 10CDEAD word for empty slots
    1376           0 :           for (Int_t i = 0; i < localStruct.GetLength(); i++)
    1377           0 :               buffer[index++] = localStruct.GetDisableWord(); 
    1378             :         }// condition localBoard
    1379             :           
    1380             :         // 45 regional scaler word
    1381           0 :         if (scalarEvent) {
    1382           0 :           memcpy(&buffer[index], localStruct.GetScalers(), kLocScalerLength*4);
    1383           0 :           index += kLocScalerLength;
    1384           0 :         }
    1385             :           
    1386             :         // end of local structure words
    1387           0 :         buffer[index++] = localStruct.GetEndOfLocal();
    1388             :           
    1389             :       } // local card 
    1390             :       // fill regional header with local output
    1391           0 :       regHeader.SetInput(regInpHpt, 0);
    1392           0 :       regHeader.SetInput(regInpLpt, 1);
    1393           0 :       memcpy(&buffer[indexReg],regHeader.GetHeader(),kRegHeaderLength*4);
    1394             :       
    1395           0 :     } // Regional card
    1396             : 
    1397           0 :   header->fSize = index * sizeof(Int_t) + sizeof(AliRawDataHeaderV3);
    1398           0 :   outBufferSize = header->fSize;
    1399             : 
    1400             :   return 0;
    1401           0 : }
    1402             : 
    1403             : 
    1404             : /////////////////////////////////////////////////////////////////////////////////////////

Generated by: LCOV version 1.11