ALIROOT-5433 Transition to CDHv3 in HLT
[u/mrichter/AliRoot.git] / HLT / rec / AliHLTOUTHomerCollection.cxx
1 // $Id$
2
3 //**************************************************************************
4 //* This file is property of and copyright by the                          * 
5 //* ALICE Experiment at CERN, All rights reserved.                         *
6 //*                                                                        *
7 //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
8 //*                                                                        *
9 //* Permission to use, copy, modify and distribute this software and its   *
10 //* documentation strictly for non-commercial purposes is hereby granted   *
11 //* without fee, provided that the above copyright notice appears in all   *
12 //* copies and that both the copyright notice and this permission notice   *
13 //* appear in the supporting documentation. The authors make no claims     *
14 //* about the suitability of this software for any purpose. It is          *
15 //* provided "as is" without express or implied warranty.                  *
16 //**************************************************************************
17
18 /// @file   AliHLTOUTHomerCollection.cxx
19 /// @author Matthias Richter
20 /// @date   
21 /// @brief  General collection for HLTOUT data in DDL format.
22 ///
23
24 #include "AliHLTOUTHomerCollection.h"
25 #include "AliHLTHOMERLibManager.h"
26 #include "AliHLTHOMERReader.h"
27 #include "AliHLTEsdManager.h"
28 #include "AliDAQ.h"
29
30 /** ROOT macro for the implementation of ROOT specific class methods */
31 ClassImp(AliHLTOUTHomerCollection)
32
33 AliHLTOUTHomerCollection::AliHLTOUTHomerCollection(int event, AliHLTEsdManager* pEsdManager)
34   :
35   AliHLTOUTHomerBuffer(NULL, 0),
36   fEvent(event),
37   fpCurrent(NULL),
38   fpEsdManager(pEsdManager)
39 {
40   // constructor
41   //
42   // General collection for HLTOUT data in DDL format
43   // 
44   // see header file for class documentation
45 }
46
47 const int AliHLTOUTHomerCollection::fgkIdShift=16;
48
49 AliHLTOUTHomerCollection::~AliHLTOUTHomerCollection()
50 {
51   // destructor
52   if (fpManager) {
53     if (fpCurrent) fpManager->DeleteReader(fpCurrent);
54     fpCurrent=NULL;
55   }
56 }
57
58 int AliHLTOUTHomerCollection::GenerateIndex()
59 {
60   // Overloaded from AliHLTOUT
61   // step through all HLT ddls, create HOMER readers and
62   // scan data block
63   int iResult=0;
64   if (fpManager) {
65     Reset();
66     int firstLink=AliDAQ::DdlIDOffset("HLT");
67     int nofDDLs=AliDAQ::NumberOfDdls("HLT");
68     SelectEquipment(-1,firstLink, firstLink+nofDDLs);
69     UChar_t* pSrc=NULL;
70     while (ReadNextData(pSrc) && pSrc!=NULL && iResult>=0) {
71       AliHLTUInt32_t id=(GetEquipmentId());
72       unsigned int size=GetDataSize();
73
74       AliHLTHOMERReader* pReader=OpenReader(pSrc, size);
75
76       // we use the equipment id to identify the different homer blocks 
77       id<<=fgkIdShift;
78       if (pReader) {
79         iResult=ScanReader(pReader, id);
80         fpManager->DeleteReader(pReader);
81       }
82     }
83   } else {
84     iResult=-ENODEV;
85   }
86   return iResult;
87 }
88
89 int AliHLTOUTHomerCollection::GetDataBuffer(AliHLTUInt32_t index, const AliHLTUInt8_t* &pBuffer, 
90                                       AliHLTUInt32_t& size)
91 {
92   // Overloaded from AliHLTOUT: get data buffer at specified index
93   int iResult=0;
94   pBuffer=NULL;
95   size=0;
96   if (fpManager) {
97     Int_t id = Int_t(index>>fgkIdShift);
98     AliHLTUInt32_t blockNo=index&((0x1<<fgkIdShift)-1);
99
100     // block from the same ddl requested?
101     if (fpCurrent && GetEquipmentId()!=id) {
102       fpManager->DeleteReader(fpCurrent);
103       fpCurrent=NULL;
104     }
105
106     // open ddl for equipment id and create HOMER reader
107     if (!fpCurrent) {
108       Reset();
109       SelectEquipment(-1, id, id);
110       UChar_t* pSrc=NULL;
111       if (ReadNextData(pSrc) && pSrc!=NULL) {
112         int srcSize=GetDataSize();
113         fpCurrent=OpenReader(pSrc, srcSize);
114         if (fpCurrent && fpCurrent->ReadNextEvent()!=0) {
115           iResult=-ENODATA;
116         }
117       } else {
118         iResult=-ENOSYS;
119       }
120     }
121
122     // get data
123     if (fpCurrent) {
124       AliHLTMonitoringReader* pReader=fpCurrent;
125       if ((pBuffer=static_cast<const AliHLTUInt8_t*>(pReader->GetBlockData(blockNo)))!=NULL) {
126         size=pReader->GetBlockDataLength(blockNo);
127       } else {
128         iResult=-ENOENT;
129       }
130     }
131   } else {
132     iResult=-ENODEV;
133   }
134   return iResult;
135 }
136
137 AliHLTHOMERReader* AliHLTOUTHomerCollection::OpenReader(UChar_t* pSrc, unsigned int size)
138 {
139   // open HOMER reader for buffer
140   unsigned int offset=sizeof(AliHLTOUTEventHeader);
141   AliHLTCDHWrapper pCDH=GetDataHeader();
142   AliHLTUInt32_t id=(GetEquipmentId());
143   AliHLTUInt32_t statusFlags=pCDH.GetStatus();
144   AliHLTOUTEventHeader* pHLTHeader=reinterpret_cast<AliHLTOUTEventHeader*>(pSrc);
145
146   // consistency check for the block size
147   if (pHLTHeader->fLength>size) {
148     HLTError("can not treat HLT data block %d: size mismatch, header %d, but buffer is %d", id, pHLTHeader->fLength, size);
149     return NULL;
150   } else if (pHLTHeader->fLength<size-3) {
151     // data payload is aligned to 32bit, so there can be a difference by at most 3 bytes
152     HLTWarning("size mismatch in HLT data block %d: header %d, but buffer is %d", id, pHLTHeader->fLength, size);
153   }
154
155   // determine the offset of the homer block
156   // the HLT header is mandatory, HLT decision and HLT
157   // payload are optional. HLT decision is always before HLT
158   // payload if existent.
159   if (statusFlags&(0x1<<kCDHFlagsHLTDecision)) {
160     // the block contains HLT decision data, this is just
161     // skipped here
162     AliHLTUInt32_t* pDecisionLen=reinterpret_cast<AliHLTUInt32_t*>(pSrc+offset);
163     if ((*pDecisionLen)*sizeof(AliHLTUInt32_t)+offset<size) {
164       // the first 32bit word specifies the number of 32bit words in the
165       // decision block -> +1 for this length word
166       offset+=((*pDecisionLen)+1)*sizeof(AliHLTUInt32_t);
167     } else {
168       HLTWarning("size mismatch: HLT decision block bigger than total block length, skipping ...");
169       return NULL;
170     }
171   }
172
173   // check if there is payload
174   if (!(statusFlags&(0x1<<kCDHFlagsHLTPayload))) return NULL;
175
176   // continue if there is no data left in the buffer
177   if (offset>=pHLTHeader->fLength) {
178     HLTWarning("no HLT payload available, but bit is set, skipping ...");
179     return NULL;
180   }
181
182   // check for the HOME descriptor type id
183   AliHLTUInt64_t* pHomerDesc=reinterpret_cast<AliHLTUInt64_t*>(pSrc+offset);
184   if (*(pHomerDesc+kID_64b_Offset) != HOMER_BLOCK_DESCRIPTOR_TYPEID && 
185       ByteSwap64(*(pHomerDesc+kID_64b_Offset)) != HOMER_BLOCK_DESCRIPTOR_TYPEID) {
186     HLTWarning("format error: can not find HOMER block descriptor typid, skipping this data block");
187     return NULL;
188   }
189
190   AliHLTUInt64_t eventId=pHLTHeader->fEventIDHigh;
191   eventId = eventId<<32;
192   eventId|=pHLTHeader->fEventIDLow;
193   SetEventId(eventId);
194   return fpManager->OpenReaderBuffer(pSrc+offset, pHLTHeader->fLength-offset);
195 }
196
197 int AliHLTOUTHomerCollection::WriteESD(const AliHLTUInt8_t* pBuffer, AliHLTUInt32_t size, AliHLTComponentDataType dt, AliESDEvent* tgtesd) const
198 {
199   // write ESD
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 }