]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/sim/AliHLTOUTComponent.cxx
bugfix: dynamic_cast caused undefined symbol; sequence of writers written to raw...
[u/mrichter/AliRoot.git] / HLT / sim / AliHLTOUTComponent.cxx
CommitLineData
c4228ec4 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 AliHLTOUTComponent.cxx
20 @author Matthias Richter
21 @date
22 @brief The HLTOUT data sink component similar to HLTOUT nodes */
23
24// see header file for class documentation
25// or
26// refer to README to build package
27// or
28// visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
29
30#if __GNUC__>= 3
31using namespace std;
32#endif
33
4b113031 34#include <cassert>
a183f221 35#include <iostream>
c4228ec4 36#include "AliHLTOUTComponent.h"
4b113031 37#include "AliHLTOUT.h"
38#include "AliHLTHOMERWriter.h"
a183f221 39#include "AliDAQ.h" // equipment Ids
4b113031 40#include "AliRawDataHeader.h" // Common Data Header
41#include <TDatime.h> // seed for TRandom
42#include <TRandom.h> // random int generation for DDL no
c4228ec4 43
44/** ROOT macro for the implementation of ROOT specific class methods */
45ClassImp(AliHLTOUTComponent)
46
47AliHLTOUTComponent::AliHLTOUTComponent()
48 :
4b113031 49 AliHLTOfflineDataSink(),
50 fWriters(),
51 fNofDDLs(10),
52 fIdFirstDDL(4864), // 0x13<<8
53 fWriteDigits(kTRUE),
54 fWriteRaw(kTRUE),
a183f221 55 fBuffer(),
56 fpLibManager(NULL)
c4228ec4 57{
58 // see header file for class documentation
59 // or
60 // refer to README to build package
61 // or
62 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
4b113031 63
64 // I guess DDL definitions should never change any more
65 assert(fNofDDLs==AliDAQ::NumberOfDdls("HLT"));
66 fNofDDLs=AliDAQ::NumberOfDdls("HLT");
67 assert(fIdFirstDDL==AliDAQ::DdlIDOffset("HLT"));
68 fIdFirstDDL=AliDAQ::DdlIDOffset("HLT");
c4228ec4 69}
70
71AliHLTOUTComponent::~AliHLTOUTComponent()
72{
73 // see header file for class documentation
a183f221 74 if (fpLibManager) delete fpLibManager;
75 fpLibManager=NULL;
c4228ec4 76}
77
78const char* AliHLTOUTComponent::GetComponentID()
79{
80 // see header file for class documentation
81 return "HLTOUT";
82}
83
84void AliHLTOUTComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list)
85{
86 // see header file for class documentation
87 list.clear();
88 list.push_back(kAliHLTAnyDataType);
89}
90
91AliHLTComponent* AliHLTOUTComponent::Spawn()
92{
93 // see header file for class documentation
94 return new AliHLTOUTComponent;
95}
96
97int AliHLTOUTComponent::DoInit( int argc, const char** argv )
98{
99 // see header file for class documentation
100 int iResult=0;
101 TString argument="";
102 int bMissingParam=0;
103 for (int i=0; i<argc && iResult>=0; i++) {
104 argument=argv[i];
105 if (argument.IsNull()) continue;
106
107 {
108 HLTError("unknown argument %s", argument.Data());
109 break;
110 }
111 }
112 if (bMissingParam) {
113 HLTError("missing parameter for argument %s", argument.Data());
114 iResult=-EINVAL;
115 }
116 if (iResult>=0) {
117 }
118
a183f221 119 fpLibManager=new AliHLTHOMERLibManager;
120 if (fpLibManager) {
121 int writerNo=0;
122 for (writerNo=0; writerNo<fNofDDLs; writerNo++) {
123 AliHLTMonitoringWriter* pWriter=fpLibManager->OpenWriter();
124 if (pWriter) {
125 fWriters.push_back(pWriter);
126 } else {
127 iResult=-ENOMEM;
128 break;
129 }
4b113031 130 }
a183f221 131 } else {
132 iResult=-ENOMEM;
4b113031 133 }
134
c4228ec4 135 return iResult;
136}
137
138int AliHLTOUTComponent::DoDeinit()
139{
140 // see header file for class documentation
141 int iResult=0;
4b113031 142
a183f221 143 if (fpLibManager) {
144 AliHLTMonitoringWriterPVector::iterator element=fWriters.begin();
145 while (element!= fWriters.end()) {
146 assert(*element);
b9dd5a11 147 // wanted to have a dynamic_cast<AliHLTHOMERWriter*> here, but this results into
148 // undefined symbol when loading the library
149 if (*element!=NULL) fpLibManager->DeleteWriter((AliHLTHOMERWriter*)(*element));
a183f221 150 element=fWriters.erase(element);
151 }
4b113031 152 }
c4228ec4 153
154 return iResult;
155}
156
157int AliHLTOUTComponent::DumpEvent( const AliHLTComponentEventData& evtData,
158 const AliHLTComponentBlockData* blocks,
159 AliHLTComponentTriggerData& /*trigData*/ )
160{
161 // see header file for class documentation
162 int iResult=0;
163 HLTInfo("write %d output blocks", evtData.fBlockCnt);
4b113031 164 fWriters.clear();
165 if (iResult>=0) {
166 homer_uint64 homerHeader[kCount_64b_Words];
167 HOMERBlockDescriptor homerDescriptor(homerHeader);
168 for (int n=0; n<(int)evtData.fBlockCnt; n++ ) {
169 memset( homerHeader, 0, sizeof(homer_uint64)*kCount_64b_Words );
170 homerDescriptor.Initialize();
171 homerDescriptor.SetType(reinterpret_cast<homer_uint64>(blocks[n].fDataType.fID));
172 homerDescriptor.SetSubType1(reinterpret_cast<homer_uint64>(blocks[n].fDataType.fOrigin));
173 homerDescriptor.SetSubType2(static_cast<homer_uint64>(blocks[n].fSpecification));
174 int writerNo=ShuffleWriters(fWriters, blocks[n].fSize);
175 assert(writerNo>=0 && writerNo<fWriters.size());
176 fWriters[writerNo]->AddBlock(&homerDescriptor, blocks[n].fPtr);
177 }
178 }
179
180 return iResult;
181}
182
183int AliHLTOUTComponent::FillESD(int eventNo, AliRunLoader* runLoader, AliESDEvent* /*esd*/)
184{
185 // see header file for class documentation
186 int iResult=0;
187 if (fWriters.size()==0) return 0;
188
189 // search for the writer with the biggest data volume in order to allocate the
190 // output buffer of sufficient size
4b113031 191 vector<int> sorted;
192 for (int i=0; i<fWriters.size(); i++) {
193 assert(fWriters[i]);
194 if (fWriters[i]) {
195 if (sorted.size()>=0 && fWriters[i]->GetTotalMemorySize()>fWriters[sorted[0]]->GetTotalMemorySize()) {
196 sorted.insert(sorted.begin(), i);
197 } else {
198 sorted.push_back(i);
199 }
200 }
4b113031 201 }
202
203 vector<int>::iterator ddlno=sorted.begin();
204 while (ddlno!=sorted.end()) {
205 const AliHLTUInt8_t* pBuffer=NULL;
206 int bufferSize=0;
207
b9dd5a11 208 if ((bufferSize=FillOutputBuffer(eventNo, fWriters[*ddlno], pBuffer))>0) {
4b113031 209 if (fWriteDigits) WriteDigits(eventNo, runLoader, *ddlno, pBuffer, bufferSize);
210 if (fWriteRaw) WriteRawFile(eventNo, runLoader, *ddlno, pBuffer, bufferSize);
211 }
212 ddlno++;
213 }
214 return iResult;
215}
216
a183f221 217int AliHLTOUTComponent::ShuffleWriters(AliHLTMonitoringWriterPVector &list, AliHLTUInt32_t size)
4b113031 218{
219 // see header file for class documentation
220 int iResult=-ENOENT;
221 assert(list.size()>0);
222 if (list.size()==0) return iResult;
223 vector<int> writers;
224 int i=0;
225 for (i=0; i<list.size(); i++) {
226 if (list[i]->GetTotalMemorySize()==0)
227 writers.push_back(i);
228 else if (iResult<0 ||
229 list[i]->GetTotalMemorySize()<list[iResult]->GetTotalMemorySize())
230 iResult=i;
231
232 }
233 if (writers.size()>0) {
234 iResult=writers[0];
235 if (writers.size()>0) {
236 // shuffle among the empty writers
237 TDatime dt;
238 TRandom rand;
239 rand.SetSeed(dt.Get()*(iResult+1));
240 i=rand.Integer(writers.size()-1);
241 assert(i>0 && i<writers.size()-1);
242 iResult=writers[i];
243 }
244 } else {
245 // take the writer with the least data volume
246 assert(iResult>=0);
247 }
248 return iResult;
249}
250
a183f221 251int AliHLTOUTComponent::FillOutputBuffer(int eventNo, AliHLTMonitoringWriter* pWriter, const AliHLTUInt8_t* &pBuffer)
4b113031 252{
253 // see header file for class documentation
254 int iResult=0;
255 int bufferSize=0;
256
257 // space for common data header
258 bufferSize+=sizeof(AliRawDataHeader);
259 assert(sizeof(AliRawDataHeader)==24);
260
261 // space for HLT event header
262 bufferSize+=sizeof(AliHLTOUT::AliHLTOUTEventHeader);
263
264 // space for payload from the writer
265 if (pWriter) bufferSize+=pWriter->GetTotalMemorySize();
266
267 if (bufferSize>fBuffer.size())
268 fBuffer.resize(bufferSize);
269
270 if (bufferSize<=fBuffer.size()) {
271 AliRawDataHeader* pCDH=reinterpret_cast<AliRawDataHeader*>(&fBuffer[0]);
272 AliHLTOUT::AliHLTOUTEventHeader* pHLTH=reinterpret_cast<AliHLTOUT::AliHLTOUTEventHeader*>(&fBuffer[sizeof(AliRawDataHeader)]);
273 memset(pCDH, 0, sizeof(AliRawDataHeader));
274 memset(pHLTH, 0, sizeof(AliHLTOUT::AliHLTOUTEventHeader));
275 pHLTH->fVersion=1;
276 if (pWriter) {
277 // copy payload
278 pWriter->Copy(&fBuffer[sizeof(AliRawDataHeader)+sizeof(AliHLTOUT::AliHLTOUTEventHeader)], 0, 0, 0, 0);
279 pHLTH->fLength=pWriter->GetTotalMemorySize();
280 // set status bit to indicate HLT payload
281 pCDH->fStatusMiniEventID|=0x1<<(AliHLTOUT::fgkCDHStatusFlagsOffset+AliHLTOUT::fgkCDHFlagsHLTPayload);
282 }
283 pHLTH->fLength+=sizeof(AliHLTOUT::AliHLTOUTEventHeader);
284 pHLTH->fEventID=eventNo;
285
286 pCDH->fSize=sizeof(AliRawDataHeader)+pHLTH->fLength;
c4228ec4 287
4b113031 288 pBuffer=&fBuffer[0];
289 } else {
290 pBuffer=NULL;
291 iResult=-ENOMEM;
c4228ec4 292 }
293
294 return iResult;
295}
296
4b113031 297int AliHLTOUTComponent::WriteDigits(int eventNo, AliRunLoader* runLoader, int hltddl, const AliHLTUInt8_t* pBuffer, int bufferSize)
c4228ec4 298{
299 // see header file for class documentation
300 int iResult=0;
301 return iResult;
302}
4b113031 303
304int AliHLTOUTComponent::WriteRawFile(int eventNo, AliRunLoader* runLoader, int hltddl, const AliHLTUInt8_t* pBuffer, int bufferSize)
305{
306 // see header file for class documentation
307 int iResult=0;
308 const char* fileName=AliDAQ::DdlFileName("HLT", hltddl);
4b113031 309 assert(fileName!=NULL);
a183f221 310 TString filePath(fileName);
4b113031 311 if (fileName) {
312 ios::openmode filemode=(ios::openmode)0;
313 ofstream rawfile(filePath.Data(), filemode);
314 if (rawfile.good()) {
315 if (pBuffer && bufferSize>0) {
316 rawfile.write(reinterpret_cast<const char*>(pBuffer), bufferSize);
317 } else {
318 HLTWarning("writing zero length raw data file %s");
319 }
320 HLTDebug("wrote %d byte(s) to file %s", bufferSize, filePath.Data());
321 } else {
322 HLTError("can not open file %s for writing", filePath.Data());
323 iResult=-EBADF;
324 }
325 rawfile.close();
326 }
327 return iResult;
328}