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