]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTOUT.cxx
Ignoring temporary files
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTOUT.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   AliHLTOUT.cxx
20     @author Matthias Richter
21     @date   
22     @brief  The control class for HLTOUT data.                            */
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 #include <cerrno>
31 #include <cassert>
32 #include "AliHLTOUT.h"
33
34 /** ROOT macro for the implementation of ROOT specific class methods */
35 ClassImp(AliHLTOUT)
36
37 AliHLTOUT::AliHLTOUT()
38   :
39   fSearchDataType(kAliHLTVoidDataType),
40   fSearchSpecification(kAliHLTVoidDataSpec),
41   fSearchHandlerType(AliHLTModuleAgent::kUnknownOutput),
42   fFlags(0),
43   fBlockDescList(),
44   fCurrent(fBlockDescList.begin()),
45   fpBuffer(NULL),
46   fDataHandlers(),
47   fbVerbose(true)
48 {
49   // see header file for class documentation
50   // or
51   // refer to README to build package
52   // or
53   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
54 }
55
56 AliHLTOUT::~AliHLTOUT()
57 {
58   // see header file for class documentation
59 }
60
61 int AliHLTOUT::Init()
62 {
63   // see header file for class documentation
64   int iResult=0;
65   SetStatusFlag(kCollecting);
66   if ((iResult=GenerateIndex())>=0) {
67     if ((iResult=InitHandlers())>=0) {
68     }
69   }
70   ClearStatusFlag(kCollecting);
71   return iResult;
72 }
73
74 int AliHLTOUT::GetNofDataBlocks()
75 {
76   // see header file for class documentation
77   return fBlockDescList.size();
78 }
79
80 int AliHLTOUT::SelectFirstDataBlock(AliHLTComponentDataType dt, AliHLTUInt32_t spec,
81                                     AliHLTModuleAgent::AliHLTOUTHandlerType handlerType)
82 {
83   // see header file for class documentation
84   if (CheckStatusFlag(kLocked)) return -EPERM;
85   fCurrent=fBlockDescList.begin();
86   fSearchDataType=dt;
87   fSearchSpecification=spec;
88   fSearchHandlerType=handlerType;
89   return FindAndSelectDataBlock();
90 }
91
92 int AliHLTOUT::SelectNextDataBlock()
93 {
94   // see header file for class documentation
95   if (CheckStatusFlag(kLocked)) return -EPERM;
96   if (fCurrent==fBlockDescList.end()) return -ENOENT;
97   fCurrent++;
98   return FindAndSelectDataBlock();
99 }
100
101 int AliHLTOUT::FindAndSelectDataBlock()
102 {
103   // see header file for class documentation
104   if (CheckStatusFlag(kLocked)) return -EPERM;
105   int iResult=-ENOENT;
106   while (fCurrent!=fBlockDescList.end() && iResult==-ENOENT) {
107     if ((*fCurrent)==fSearchDataType &&
108         (fSearchSpecification==kAliHLTVoidDataSpec || (*fCurrent)==fSearchSpecification) &&
109         (fSearchHandlerType==AliHLTModuleAgent::kUnknownOutput || FindHandlerDesc(fCurrent->GetIndex())==fSearchHandlerType)) {
110       iResult=fCurrent->GetIndex();
111       // TODO: check the byte order on the current system and the byte order of the
112       // data block, print warning when mismatch and user did not check
113       //AliHLTOUTByteOrder blockBO=CheckByteOrder();
114       CheckByteOrder();
115       /*
116         if (blockBO!=fByteOrder) {
117         SetStatusFlag(kByteOrderWarning);
118
119         }
120        */
121       ClearStatusFlag(kByteOrderChecked);
122
123       // TODO: check the alignment on the current system and the alignment of the
124       // data block, print warning when mismatch and user did not check
125       ClearStatusFlag(kAlignmentChecked);
126
127       break;
128     }
129     fCurrent++;
130   }
131   return iResult;
132 }
133
134 int AliHLTOUT::GetDataBlockDescription(AliHLTComponentDataType& dt, AliHLTUInt32_t& spec)
135 {
136   // see header file for class documentation
137   int iResult=-ENOENT;
138   if (fCurrent!=fBlockDescList.end()) {
139     iResult=0;
140     dt=(*fCurrent);
141     spec=(*fCurrent);
142   }
143   return iResult;
144 }
145
146 const AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::GetDataBlockHandlerDesc()
147 {
148   // see header file for class documentation
149   return FindHandlerDesc(GetDataBlockIndex());
150 }
151
152 AliHLTModuleAgent::AliHLTOUTHandlerType AliHLTOUT::GetDataBlockHandlerType()
153 {
154   // see header file for class documentation
155   AliHLTModuleAgent::AliHLTOUTHandlerDesc desc=FindHandlerDesc(GetDataBlockIndex());
156   AliHLTModuleAgent::AliHLTOUTHandlerType type=desc;
157   return type;
158 }
159
160 AliHLTUInt32_t AliHLTOUT::GetDataBlockIndex()
161 {
162   // see header file for class documentation
163   if (fCurrent==fBlockDescList.end()) return AliHLTOUTInvalidIndex;
164   return fCurrent->GetIndex();
165 }
166
167 int AliHLTOUT::GetDataBuffer(const AliHLTUInt8_t* &pBuffer, AliHLTUInt32_t& size)
168 {
169   // see header file for class documentation
170   int iResult=-ENOENT;
171   pBuffer=NULL;
172   size=0;
173   if (fCurrent!=fBlockDescList.end()) {
174     if ((iResult=GetDataBuffer(fCurrent->GetIndex(), pBuffer, size))>=0) {
175       fpBuffer=pBuffer;
176     }
177   }
178   return iResult;  
179 }
180
181 int AliHLTOUT::ReleaseDataBuffer(const AliHLTUInt8_t* pBuffer)
182 {
183   // see header file for class documentation
184   int iResult=0;
185   if (pBuffer==fpBuffer) {
186     fpBuffer=NULL;
187   } else {
188     HLTWarning("buffer %p does not match the provided one %p", pBuffer, fpBuffer);
189   }
190   return iResult;  
191 }
192
193 AliHLTModuleAgent* AliHLTOUT::GetAgent()
194 {
195   // see header file for class documentation
196   AliHLTModuleAgent* pAgent=NULL;
197   pAgent=FindHandlerDesc(GetDataBlockIndex());
198   return pAgent;
199 }
200
201 AliHLTOUTHandler* AliHLTOUT::GetHandler()
202 {
203   // see header file for class documentation
204   AliHLTOUTHandler* pHandler=NULL;
205   pHandler=FindHandlerDesc(GetDataBlockIndex());
206   return pHandler;
207 }
208
209 int AliHLTOUT::WriteESD(const AliHLTUInt8_t* /*pBuffer*/, AliHLTUInt32_t /*size*/, AliHLTComponentDataType /*dt*/, AliESDEvent* /*tgtesd*/) const
210 {
211   // see header file for class documentation
212   HLTWarning("method not implemented in base class");
213   return -ENOSYS;
214 }
215
216 int AliHLTOUT::AddBlockDescriptor(const AliHLTOUTBlockDescriptor desc)
217 {
218   // see header file for class documentation
219   if (!CheckStatusFlag(kCollecting)) return -EPERM;
220   int iResult=0;
221   fBlockDescList.push_back(desc);
222   return iResult;  
223 }
224
225 AliHLTOUT::AliHLTOUTByteOrder AliHLTOUT::CheckByteOrder()
226 {
227   // see header file for class documentation
228   if (fCurrent!=fBlockDescList.end()) {
229     SetStatusFlag(kByteOrderChecked);
230     AliHLTOUT::AliHLTOUTByteOrder order=CheckBlockByteOrder((*fCurrent).GetIndex());
231     return order;
232   }
233   return kInvalidByteOrder;
234 }
235
236 int AliHLTOUT::CheckAlignment(AliHLTOUT::AliHLTOUTDataType type)
237 {
238   // see header file for class documentation
239   if (fCurrent!=fBlockDescList.end()) {
240     SetStatusFlag(kAlignmentChecked);
241     int alignment=CheckBlockAlignment((*fCurrent).GetIndex(), type);
242     return alignment;
243   }
244   return -ENOENT;
245 }
246
247 int AliHLTOUT::InitHandlers()
248 {
249   // see header file for class documentation
250   int iResult=0;
251   AliHLTOUTIndexList remnants;
252   int iCount=0;
253   for (int havedata=SelectFirstDataBlock(kAliHLTAnyDataType, kAliHLTVoidDataSpec); havedata>=0; havedata=SelectNextDataBlock()) {
254     iCount++;
255     remnants.push_back(GetDataBlockIndex());
256     AliHLTComponentDataType dt=kAliHLTVoidDataType;
257     AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
258     if (GetDataBlockDescription(dt, spec)<0) break;
259     bool bHaveHandler=false;
260     for (AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent(); pAgent && iResult>=0; pAgent=AliHLTModuleAgent::GetNextAgent()) {
261       AliHLTModuleAgent::AliHLTOUTHandlerDesc handlerDesc;
262       if (pAgent->GetHandlerDescription(dt, spec, handlerDesc)>0) {
263         AliHLTOUTHandlerListEntry entry(pAgent->GetOutputHandler(dt, spec), handlerDesc, pAgent, GetDataBlockIndex());
264         InsertHandler(fDataHandlers, entry);
265         remnants.pop_back();
266         bHaveHandler=true;
267         break;
268       }
269     }
270     if (!bHaveHandler && (dt==kAliHLTDataTypeESDObject || dt==kAliHLTDataTypeESDTree)) {
271       // ESDs are handled by the framework
272       remnants.pop_back();
273     }
274   }
275
276   // warning if some of the data blocks are not selected by the kAliHLTAnyDataType
277   // criterion
278   if (GetNofDataBlocks()>iCount) {
279     HLTWarning("incomplete data type in %d out of %d data block(s)", GetNofDataBlocks()-iCount, iCount);
280   }
281
282   // warning if handler not found
283   if (remnants.size()>0) {
284     HLTWarning("no handlers found for %d data blocks out of %d", remnants.size(), iCount);
285     AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
286     for (AliHLTOUTIndexList::iterator element=remnants.begin(); element!=remnants.end(); element++) {
287       for (int trials=0; trials<2; trials++) {
288         do {
289           // we start searching the index from the current position in the block list
290           if ((*block).GetIndex()==*element) break;
291         } while ((++block)!=fBlockDescList.end());
292         if (block==fBlockDescList.end()) {
293           // rewind and try again
294           block=fBlockDescList.begin();
295         }
296       }
297       assert(block!=fBlockDescList.end());
298       if (block!=fBlockDescList.end()) {
299         HLTDebug("   %s", AliHLTComponent::DataType2Text((AliHLTComponentDataType)*block).c_str());
300       }
301     }
302   }
303   return iResult;
304 }
305
306 int AliHLTOUT::InsertHandler(AliHLTOUTHandlerListEntryVector& list, const AliHLTOUTHandlerListEntry &entry)
307 {
308   // see header file for class documentation
309   int iResult=0;
310   AliHLTOUTHandlerListEntryVector::iterator element=list.begin();
311   while (element!=list.end()) {
312     if (entry==(*element)) break;
313     element++;
314   }
315   if (element==list.end()) {
316     list.push_back(entry);
317   } else {
318     element->AddIndex(const_cast<AliHLTOUTHandlerListEntry&>(entry));
319   }
320   return iResult;
321 }
322
323 const AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::FindHandlerDesc(AliHLTUInt32_t blockIndex)
324 {
325   // see header file for class documentation
326   AliHLTOUTHandlerListEntryVector::iterator element=fDataHandlers.begin();
327   while (element!=fDataHandlers.end()) {
328     if (element->HasIndex(blockIndex)) {
329       return *element;
330     }
331     element++;
332   }
333   return const_cast<AliHLTOUT::AliHLTOUTHandlerListEntry&>(AliHLTOUT::AliHLTOUTHandlerListEntry::fgkVoidHandlerListEntry);
334 }
335
336 AliHLTOUT::AliHLTOUTHandlerListEntry::AliHLTOUTHandlerListEntry()
337   :
338   fpHandler(NULL),
339   fpHandlerDesc(NULL),
340   fpAgent(NULL),
341   fBlocks()
342 {
343   // see header file for class documentation
344 }
345
346 AliHLTOUT::AliHLTOUTHandlerListEntry::AliHLTOUTHandlerListEntry(AliHLTOUTHandler* pHandler, 
347                                                                 AliHLTModuleAgent::AliHLTOUTHandlerDesc& handlerDesc,
348                                                                 AliHLTModuleAgent* pAgent,
349                                                                 AliHLTUInt32_t index)
350   :
351   fpHandler(pHandler),
352   fpHandlerDesc(new AliHLTModuleAgent::AliHLTOUTHandlerDesc),
353   fpAgent(pAgent),
354   fBlocks()
355 {
356   // see header file for class documentation
357   *fpHandlerDesc=handlerDesc;
358   fBlocks.push_back(index);
359 }
360
361 AliHLTOUT::AliHLTOUTHandlerListEntry::AliHLTOUTHandlerListEntry(const AliHLTOUTHandlerListEntry& src)
362   :
363   fpHandler(src.fpHandler),
364   fpHandlerDesc(new AliHLTModuleAgent::AliHLTOUTHandlerDesc),
365   fpAgent(src.fpAgent),
366   fBlocks()
367 {
368   // see header file for class documentation
369   *fpHandlerDesc=*src.fpHandlerDesc;
370   fBlocks.assign(src.fBlocks.begin(), src.fBlocks.end());
371 }
372
373 AliHLTOUT::AliHLTOUTHandlerListEntry::~AliHLTOUTHandlerListEntry()
374 {
375   // see header file for class documentation
376   if (fpHandlerDesc) delete fpHandlerDesc;
377   fpHandlerDesc=NULL;
378 }
379
380 AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::AliHLTOUTHandlerListEntry::operator=(const AliHLTOUTHandlerListEntry& src)
381 {
382   // see header file for class documentation
383   fpHandler=src.fpHandler;
384   if (src.fpHandlerDesc)
385     *fpHandlerDesc=*src.fpHandlerDesc;
386   fpAgent=src.fpAgent;
387   fBlocks.assign(src.fBlocks.begin(), src.fBlocks.end());
388   return *this;
389 }
390
391 AliHLTUInt32_t AliHLTOUT::AliHLTOUTHandlerListEntry::operator[](int i) const
392 {
393   // see header file for class documentation
394   return (int)fBlocks.size()>i?fBlocks[i]:AliHLTOUTInvalidIndex;
395 }
396
397 bool AliHLTOUT::AliHLTOUTHandlerListEntry::operator==(const AliHLTOUTHandlerListEntry& entry) const
398 {
399   // see header file for class documentation
400   if (entry.fpHandler!=fpHandler || fpHandler==NULL) return false;
401   assert(entry.fpAgent==fpAgent);
402   if (entry.fpAgent!=fpAgent) return false;
403   return true;
404 }
405
406 bool AliHLTOUT::AliHLTOUTHandlerListEntry::operator==(const AliHLTModuleAgent::AliHLTOUTHandlerType handlerType) const
407 {
408   // see header file for class documentation
409   if (!fpHandlerDesc) return false;
410   return *fpHandlerDesc==handlerType;
411 }
412
413 void AliHLTOUT::AliHLTOUTHandlerListEntry::AddIndex(AliHLTOUT::AliHLTOUTHandlerListEntry &desc)
414 {
415   // see header file for class documentation
416   AliHLTOUTIndexList::iterator element;
417   for (element=desc.fBlocks.begin(); element!=desc.fBlocks.end(); element++) {
418     AddIndex(*element);
419   }  
420 }
421
422 void AliHLTOUT::AliHLTOUTHandlerListEntry::AddIndex(AliHLTUInt32_t index)
423 {
424   // see header file for class documentation
425   fBlocks.push_back(index);
426 }
427
428 bool AliHLTOUT::AliHLTOUTHandlerListEntry::HasIndex(AliHLTUInt32_t index)
429 {
430   // see header file for class documentation
431   AliHLTOUTIndexList::iterator element;
432   for (element=fBlocks.begin(); element!=fBlocks.end(); element++) {
433     if (*element==index) return true;
434   }
435   return false;
436 }
437
438 const AliHLTOUT::AliHLTOUTHandlerListEntry AliHLTOUT::AliHLTOUTHandlerListEntry::fgkVoidHandlerListEntry;
439
440 AliHLTUInt64_t AliHLTOUT::ByteSwap64(AliHLTUInt64_t src)
441 {
442   // see header file for class documentation
443   return ((src & 0xFFULL) << 56) | 
444     ((src & 0xFF00ULL) << 40) | 
445     ((src & 0xFF0000ULL) << 24) | 
446     ((src & 0xFF000000ULL) << 8) | 
447     ((src & 0xFF00000000ULL) >> 8) | 
448     ((src & 0xFF0000000000ULL) >> 24) | 
449     ((src & 0xFF000000000000ULL) >>  40) | 
450     ((src & 0xFF00000000000000ULL) >> 56);
451 }
452
453 AliHLTUInt32_t AliHLTOUT::ByteSwap32(AliHLTUInt32_t src)
454 {
455   // see header file for class documentation
456   return ((src & 0xFFULL) << 24) | 
457     ((src & 0xFF00ULL) << 8) | 
458     ((src & 0xFF0000ULL) >> 8) | 
459     ((src & 0xFF000000ULL) >> 24);
460 }