Renaming AliHLTReconstructorBase to AliHLTPluginBase to reflect the
[u/mrichter/AliRoot.git] / HLT / rec / AliHLTOUTHomerCollection.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   AliHLTOUTHomerCollection.cxx
20     @author Matthias Richter
21     @date   
22     @brief  General collection for HLTOUT data in DDL format.
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 */
32 ClassImp(AliHLTOUTHomerCollection)
33
34 AliHLTOUTHomerCollection::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
48 const int AliHLTOUTHomerCollection::fgkIdShift=16;
49
50 AliHLTOUTHomerCollection::~AliHLTOUTHomerCollection()
51 {
52   // see header file for class documentation
53   if (fpManager) {
54     if (fpCurrent) fpManager->DeleteReader(fpCurrent);
55     fpCurrent=NULL;
56   }
57 }
58
59 int 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");
72     SelectEquipment(-1,7680, 7689);
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
93 int 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
141 AliHLTHOMERReader* 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
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);
153     return NULL;
154   } else if (pHLTHeader->fLength<size) {
155     HLTWarning("size mismatch in HLT data block %d: header %d, but buffer is %d", id, pHLTHeader->fLength, size);
156   }
157
158   // determine the offset of the homer block
159   // the HLT header is mandatory, HLT decision and HLT
160   // payload are optional. HLT decision is always before HLT
161   // payload if existent.
162   if (statusFlags&(0x1<<kCDHFlagsHLTDecision)) {
163     // the block contains HLT decision data, this is just
164     // skipped here
165     AliHLTUInt32_t* pDecisionLen=reinterpret_cast<AliHLTUInt32_t*>(pSrc+offset);
166     if ((*pDecisionLen)*sizeof(AliHLTUInt32_t)+offset<size) {
167       // the first 32bit word specifies the number of 32bit words in the
168       // decision block -> +1 for this length word
169       offset+=((*pDecisionLen)+1)*sizeof(AliHLTUInt32_t);
170     } else {
171       HLTWarning("size mismatch: HLT decision block bigger than total block length, skipping ...");
172       return NULL;
173     }
174   }
175
176   // check if there is payload
177   if (!(statusFlags&(0x1<<kCDHFlagsHLTPayload))) return NULL;
178
179   // continue if there is no data left in the buffer
180   if (offset>=size) {
181     HLTWarning("no HLT payload available, but bit is set, skipping ...");
182     return NULL;
183   }
184
185   // check for the HOME descriptor type id
186   AliHLTUInt64_t* pHomerDesc=reinterpret_cast<AliHLTUInt64_t*>(pSrc+offset);
187   if (*(pHomerDesc+kID_64b_Offset) != HOMER_BLOCK_DESCRIPTOR_TYPEID && 
188       ByteSwap64(*(pHomerDesc+kID_64b_Offset)) != HOMER_BLOCK_DESCRIPTOR_TYPEID) {
189     HLTWarning("format error: can not find HOMER block descriptor typid, skipping this data block");
190     return NULL;
191   }
192
193   return fpManager->OpenReaderBuffer(pSrc+offset, size-offset);
194 }
195
196 int AliHLTOUTHomerCollection::WriteESD(const AliHLTUInt8_t* pBuffer, AliHLTUInt32_t size, AliHLTComponentDataType dt, AliESDEvent* tgtesd) const
197 {
198   // see header file for class documentation
199   if (!pBuffer && size<=0) return -EINVAL;
200   int iResult=0;
201   if (fpEsdManager) {
202     fpEsdManager->WriteESD(pBuffer, size, dt, tgtesd, GetCurrentEventNo());
203   }
204   return iResult;
205 }