Bug fix: AliHLTOUTRawReader
[u/mrichter/AliRoot.git] / HLT / rec / AliHLTOUTHomerCollection.cxx
CommitLineData
c5123824 1// $Id$
2
3//**************************************************************************
8bc2b457 4//* This file is property of and copyright by the *
c5123824 5//* ALICE Experiment at CERN, All rights reserved. *
6//* *
7//* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
c5123824 8//* *
9//* Permission to use, copy, modify and distribute this software and its *
10//* documentation strictly for non-commercial purposes is hereby granted *
11//* without fee, provided that the above copyright notice appears in all *
12//* copies and that both the copyright notice and this permission notice *
13//* appear in the supporting documentation. The authors make no claims *
14//* about the suitability of this software for any purpose. It is *
15//* provided "as is" without express or implied warranty. *
16//**************************************************************************
17
8bc2b457 18/// @file AliHLTOUTHomerCollection.cxx
19/// @author Matthias Richter
20/// @date
21/// @brief General collection for HLTOUT data in DDL format.
22///
c5123824 23
24#include "AliHLTOUTHomerCollection.h"
25#include "AliHLTHOMERLibManager.h"
26#include "AliHLTHOMERReader.h"
c5123824 27#include "AliHLTEsdManager.h"
4c2d4fb9 28#include "AliDAQ.h"
c5123824 29
30/** ROOT macro for the implementation of ROOT specific class methods */
31ClassImp(AliHLTOUTHomerCollection)
32
33AliHLTOUTHomerCollection::AliHLTOUTHomerCollection(int event, AliHLTEsdManager* pEsdManager)
34 :
35 AliHLTOUTHomerBuffer(NULL, 0),
c5123824 36 fEvent(event),
8bc2b457 37 fpCurrent(NULL),
c5123824 38 fpEsdManager(pEsdManager)
39{
8bc2b457 40 // constructor
41 //
42 // General collection for HLTOUT data in DDL format
43 //
c5123824 44 // see header file for class documentation
c5123824 45}
46
47const int AliHLTOUTHomerCollection::fgkIdShift=16;
48
49AliHLTOUTHomerCollection::~AliHLTOUTHomerCollection()
50{
8bc2b457 51 // destructor
c5123824 52 if (fpManager) {
53 if (fpCurrent) fpManager->DeleteReader(fpCurrent);
54 fpCurrent=NULL;
55 }
56}
57
58int AliHLTOUTHomerCollection::GenerateIndex()
59{
8bc2b457 60 // Overloaded from AliHLTOUT
c5123824 61 // step through all HLT ddls, create HOMER readers and
62 // scan data block
63 int iResult=0;
64 if (fpManager) {
65 Reset();
4c2d4fb9 66 int firstLink=AliDAQ::DdlIDOffset("HLT");
67 int nofDDLs=AliDAQ::NumberOfDdls("HLT");
68 SelectEquipment(-1,firstLink, firstLink+nofDDLs);
c5123824 69 UChar_t* pSrc=NULL;
70 while (ReadNextData(pSrc) && pSrc!=NULL && iResult>=0) {
71 AliHLTUInt32_t id=(GetEquipmentId());
72 unsigned int size=GetDataSize();
73
74 AliHLTHOMERReader* pReader=OpenReader(pSrc, size);
75
76 // we use the equipment id to identify the different homer blocks
77 id<<=fgkIdShift;
78 if (pReader) {
79 iResult=ScanReader(pReader, id);
80 fpManager->DeleteReader(pReader);
81 }
82 }
83 } else {
84 iResult=-ENODEV;
85 }
86 return iResult;
87}
88
89int AliHLTOUTHomerCollection::GetDataBuffer(AliHLTUInt32_t index, const AliHLTUInt8_t* &pBuffer,
90 AliHLTUInt32_t& size)
91{
8bc2b457 92 // Overloaded from AliHLTOUT: get data buffer at specified index
c5123824 93 int iResult=0;
94 pBuffer=NULL;
95 size=0;
96 if (fpManager) {
97 Int_t id = Int_t(index>>fgkIdShift);
98 AliHLTUInt32_t blockNo=index&((0x1<<fgkIdShift)-1);
99
100 // block from the same ddl requested?
101 if (fpCurrent && GetEquipmentId()!=id) {
102 fpManager->DeleteReader(fpCurrent);
103 fpCurrent=NULL;
104 }
105
106 // open ddl for equipment id and create HOMER reader
107 if (!fpCurrent) {
108 Reset();
109 SelectEquipment(-1, id, id);
110 UChar_t* pSrc=NULL;
111 if (ReadNextData(pSrc) && pSrc!=NULL) {
112 int srcSize=GetDataSize();
113 fpCurrent=OpenReader(pSrc, srcSize);
114 if (fpCurrent && fpCurrent->ReadNextEvent()!=0) {
115 iResult=-ENODATA;
116 }
117 } else {
118 iResult=-ENOSYS;
119 }
120 }
121
122 // get data
123 if (fpCurrent) {
124 AliHLTMonitoringReader* pReader=fpCurrent;
125 if ((pBuffer=static_cast<const AliHLTUInt8_t*>(pReader->GetBlockData(blockNo)))!=NULL) {
126 size=pReader->GetBlockDataLength(blockNo);
127 } else {
128 iResult=-ENOENT;
129 }
130 }
131 } else {
132 iResult=-ENODEV;
133 }
134 return iResult;
135}
136
137AliHLTHOMERReader* AliHLTOUTHomerCollection::OpenReader(UChar_t* pSrc, unsigned int size)
138{
8bc2b457 139 // open HOMER reader for buffer
c5123824 140 unsigned int offset=sizeof(AliHLTOUTEventHeader);
16e6f752 141 AliHLTCDHWrapper pCDH=GetDataHeader();
c89f0daf 142 if(pCDH.GetHeader()==NULL){
143 HLTError("Couldn't find data header.");
144 return NULL;
145 }
c5123824 146 AliHLTUInt32_t id=(GetEquipmentId());
16e6f752 147 AliHLTUInt32_t statusFlags=pCDH.GetStatus();
c5123824 148 AliHLTOUTEventHeader* pHLTHeader=reinterpret_cast<AliHLTOUTEventHeader*>(pSrc);
149
150 // consistency check for the block size
e3995366 151 if (pHLTHeader->fLength>size) {
152 HLTError("can not treat HLT data block %d: size mismatch, header %d, but buffer is %d", id, pHLTHeader->fLength, size);
c5123824 153 return NULL;
737bab1f 154 } else if (pHLTHeader->fLength<size-3) {
155 // data payload is aligned to 32bit, so there can be a difference by at most 3 bytes
e3995366 156 HLTWarning("size mismatch in HLT data block %d: header %d, but buffer is %d", id, pHLTHeader->fLength, size);
c5123824 157 }
158
159 // determine the offset of the homer block
160 // the HLT header is mandatory, HLT decision and HLT
161 // payload are optional. HLT decision is always before HLT
162 // payload if existent.
163 if (statusFlags&(0x1<<kCDHFlagsHLTDecision)) {
164 // the block contains HLT decision data, this is just
165 // skipped here
166 AliHLTUInt32_t* pDecisionLen=reinterpret_cast<AliHLTUInt32_t*>(pSrc+offset);
167 if ((*pDecisionLen)*sizeof(AliHLTUInt32_t)+offset<size) {
168 // the first 32bit word specifies the number of 32bit words in the
169 // decision block -> +1 for this length word
170 offset+=((*pDecisionLen)+1)*sizeof(AliHLTUInt32_t);
171 } else {
172 HLTWarning("size mismatch: HLT decision block bigger than total block length, skipping ...");
173 return NULL;
174 }
175 }
176
177 // check if there is payload
178 if (!(statusFlags&(0x1<<kCDHFlagsHLTPayload))) return NULL;
179
180 // continue if there is no data left in the buffer
737bab1f 181 if (offset>=pHLTHeader->fLength) {
c5123824 182 HLTWarning("no HLT payload available, but bit is set, skipping ...");
183 return NULL;
184 }
185
186 // check for the HOME descriptor type id
187 AliHLTUInt64_t* pHomerDesc=reinterpret_cast<AliHLTUInt64_t*>(pSrc+offset);
188 if (*(pHomerDesc+kID_64b_Offset) != HOMER_BLOCK_DESCRIPTOR_TYPEID &&
189 ByteSwap64(*(pHomerDesc+kID_64b_Offset)) != HOMER_BLOCK_DESCRIPTOR_TYPEID) {
190 HLTWarning("format error: can not find HOMER block descriptor typid, skipping this data block");
191 return NULL;
192 }
193
c63e8be4 194 AliHLTUInt64_t eventId=pHLTHeader->fEventIDHigh;
195 eventId = eventId<<32;
196 eventId|=pHLTHeader->fEventIDLow;
197 SetEventId(eventId);
737bab1f 198 return fpManager->OpenReaderBuffer(pSrc+offset, pHLTHeader->fLength-offset);
c5123824 199}
200
201int AliHLTOUTHomerCollection::WriteESD(const AliHLTUInt8_t* pBuffer, AliHLTUInt32_t size, AliHLTComponentDataType dt, AliESDEvent* tgtesd) const
202{
8bc2b457 203 // write ESD
c5123824 204 if (!pBuffer && size<=0) return -EINVAL;
205 int iResult=0;
206 if (fpEsdManager) {
207 fpEsdManager->WriteESD(pBuffer, size, dt, tgtesd, GetCurrentEventNo());
208 }
209 return iResult;
210}