Patch for the bug described in Savannah report 54788 (P. Hristov)
[u/mrichter/AliRoot.git] / HLT / rec / AliHLTOUTHomerCollection.cxx
CommitLineData
c5123824 1// $Id$
2
3//**************************************************************************
4//* This file is property of and copyright by the ALICE HLT Project *
5//* ALICE Experiment at CERN, All rights reserved. *
6//* *
7//* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8//* for The ALICE HLT Project. *
9//* *
10//* Permission to use, copy, modify and distribute this software and its *
11//* documentation strictly for non-commercial purposes is hereby granted *
12//* without fee, provided that the above copyright notice appears in all *
13//* copies and that both the copyright notice and this permission notice *
14//* appear in the supporting documentation. The authors make no claims *
15//* about the suitability of this software for any purpose. It is *
16//* provided "as is" without express or implied warranty. *
17//**************************************************************************
18
19/** @file AliHLTOUTHomerCollection.cxx
20 @author Matthias Richter
21 @date
7ec2b0ab 22 @brief General collection for HLTOUT data in DDL format.
c5123824 23*/
24
25#include "AliHLTOUTHomerCollection.h"
26#include "AliHLTHOMERLibManager.h"
27#include "AliHLTHOMERReader.h"
28#include "AliRawDataHeader.h"
29#include "AliHLTEsdManager.h"
30
31/** ROOT macro for the implementation of ROOT specific class methods */
32ClassImp(AliHLTOUTHomerCollection)
33
34AliHLTOUTHomerCollection::AliHLTOUTHomerCollection(int event, AliHLTEsdManager* pEsdManager)
35 :
36 AliHLTOUTHomerBuffer(NULL, 0),
37 fpCurrent(NULL),
38 fEvent(event),
39 fpEsdManager(pEsdManager)
40{
41 // see header file for class documentation
42 // or
43 // refer to README to build package
44 // or
45 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
46}
47
48const int AliHLTOUTHomerCollection::fgkIdShift=16;
49
50AliHLTOUTHomerCollection::~AliHLTOUTHomerCollection()
51{
52 // see header file for class documentation
53 if (fpManager) {
54 if (fpCurrent) fpManager->DeleteReader(fpCurrent);
55 fpCurrent=NULL;
56 }
57}
58
59int AliHLTOUTHomerCollection::GenerateIndex()
60{
61 // see header file for class documentation
62 // step through all HLT ddls, create HOMER readers and
63 // scan data block
64 int iResult=0;
65 if (fpManager) {
66 Reset();
67 // there was a bug in AliDAQ returning the wrong equipment id
68 // for the HLT links. It has been fixed in the trunk on Feb 5th 2008
69 // and from v4-10-Release (Rev-02). For the moment we select directly
70 // to support older AliRoot versions
71 //Select("HLT");
173c6353 72 SelectEquipment(-1,7680, 7689);
c5123824 73 UChar_t* pSrc=NULL;
74 while (ReadNextData(pSrc) && pSrc!=NULL && iResult>=0) {
75 AliHLTUInt32_t id=(GetEquipmentId());
76 unsigned int size=GetDataSize();
77
78 AliHLTHOMERReader* pReader=OpenReader(pSrc, size);
79
80 // we use the equipment id to identify the different homer blocks
81 id<<=fgkIdShift;
82 if (pReader) {
83 iResult=ScanReader(pReader, id);
84 fpManager->DeleteReader(pReader);
85 }
86 }
87 } else {
88 iResult=-ENODEV;
89 }
90 return iResult;
91}
92
93int AliHLTOUTHomerCollection::GetDataBuffer(AliHLTUInt32_t index, const AliHLTUInt8_t* &pBuffer,
94 AliHLTUInt32_t& size)
95{
96 // see header file for class documentation
97 int iResult=0;
98 pBuffer=NULL;
99 size=0;
100 if (fpManager) {
101 Int_t id = Int_t(index>>fgkIdShift);
102 AliHLTUInt32_t blockNo=index&((0x1<<fgkIdShift)-1);
103
104 // block from the same ddl requested?
105 if (fpCurrent && GetEquipmentId()!=id) {
106 fpManager->DeleteReader(fpCurrent);
107 fpCurrent=NULL;
108 }
109
110 // open ddl for equipment id and create HOMER reader
111 if (!fpCurrent) {
112 Reset();
113 SelectEquipment(-1, id, id);
114 UChar_t* pSrc=NULL;
115 if (ReadNextData(pSrc) && pSrc!=NULL) {
116 int srcSize=GetDataSize();
117 fpCurrent=OpenReader(pSrc, srcSize);
118 if (fpCurrent && fpCurrent->ReadNextEvent()!=0) {
119 iResult=-ENODATA;
120 }
121 } else {
122 iResult=-ENOSYS;
123 }
124 }
125
126 // get data
127 if (fpCurrent) {
128 AliHLTMonitoringReader* pReader=fpCurrent;
129 if ((pBuffer=static_cast<const AliHLTUInt8_t*>(pReader->GetBlockData(blockNo)))!=NULL) {
130 size=pReader->GetBlockDataLength(blockNo);
131 } else {
132 iResult=-ENOENT;
133 }
134 }
135 } else {
136 iResult=-ENODEV;
137 }
138 return iResult;
139}
140
141AliHLTHOMERReader* AliHLTOUTHomerCollection::OpenReader(UChar_t* pSrc, unsigned int size)
142{
143 // see header file for class documentation
144 unsigned int offset=sizeof(AliHLTOUTEventHeader);
145 const AliRawDataHeader* pCDH=GetDataHeader();
146 AliHLTUInt32_t id=(GetEquipmentId());
147 AliHLTUInt32_t statusFlags=pCDH->GetStatus();
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
737bab1f 194 return fpManager->OpenReaderBuffer(pSrc+offset, pHLTHeader->fLength-offset);
c5123824 195}
196
197int AliHLTOUTHomerCollection::WriteESD(const AliHLTUInt8_t* pBuffer, AliHLTUInt32_t size, AliHLTComponentDataType dt, AliESDEvent* tgtesd) const
198{
199 // see header file for class documentation
200 if (!pBuffer && size<=0) return -EINVAL;
201 int iResult=0;
202 if (fpEsdManager) {
203 fpEsdManager->WriteESD(pBuffer, size, dt, tgtesd, GetCurrentEventNo());
204 }
205 return iResult;
206}