3 //**************************************************************************
4 //* This file is property of and copyright by the *
5 //* ALICE Experiment at CERN, All rights reserved. *
7 //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
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 //**************************************************************************
18 /// @file AliHLTOUTHomerCollection.cxx
19 /// @author Matthias Richter
21 /// @brief General collection for HLTOUT data in DDL format.
24 #include "AliHLTOUTHomerCollection.h"
25 #include "AliHLTHOMERLibManager.h"
26 #include "AliHLTHOMERReader.h"
27 #include "AliRawDataHeader.h"
28 #include "AliHLTEsdManager.h"
31 /** ROOT macro for the implementation of ROOT specific class methods */
32 ClassImp(AliHLTOUTHomerCollection)
34 AliHLTOUTHomerCollection::AliHLTOUTHomerCollection(int event, AliHLTEsdManager* pEsdManager)
36 AliHLTOUTHomerBuffer(NULL, 0),
39 fpEsdManager(pEsdManager)
43 // General collection for HLTOUT data in DDL format
45 // see header file for class documentation
48 const int AliHLTOUTHomerCollection::fgkIdShift=16;
50 AliHLTOUTHomerCollection::~AliHLTOUTHomerCollection()
54 if (fpCurrent) fpManager->DeleteReader(fpCurrent);
59 int AliHLTOUTHomerCollection::GenerateIndex()
61 // Overloaded from AliHLTOUT
62 // step through all HLT ddls, create HOMER readers and
67 int firstLink=AliDAQ::DdlIDOffset("HLT");
68 int nofDDLs=AliDAQ::NumberOfDdls("HLT");
69 SelectEquipment(-1,firstLink, firstLink+nofDDLs);
71 while (ReadNextData(pSrc) && pSrc!=NULL && iResult>=0) {
72 AliHLTUInt32_t id=(GetEquipmentId());
73 unsigned int size=GetDataSize();
75 AliHLTHOMERReader* pReader=OpenReader(pSrc, size);
77 // we use the equipment id to identify the different homer blocks
80 iResult=ScanReader(pReader, id);
81 fpManager->DeleteReader(pReader);
90 int AliHLTOUTHomerCollection::GetDataBuffer(AliHLTUInt32_t index, const AliHLTUInt8_t* &pBuffer,
93 // Overloaded from AliHLTOUT: get data buffer at specified index
98 Int_t id = Int_t(index>>fgkIdShift);
99 AliHLTUInt32_t blockNo=index&((0x1<<fgkIdShift)-1);
101 // block from the same ddl requested?
102 if (fpCurrent && GetEquipmentId()!=id) {
103 fpManager->DeleteReader(fpCurrent);
107 // open ddl for equipment id and create HOMER reader
110 SelectEquipment(-1, id, id);
112 if (ReadNextData(pSrc) && pSrc!=NULL) {
113 int srcSize=GetDataSize();
114 fpCurrent=OpenReader(pSrc, srcSize);
115 if (fpCurrent && fpCurrent->ReadNextEvent()!=0) {
125 AliHLTMonitoringReader* pReader=fpCurrent;
126 if ((pBuffer=static_cast<const AliHLTUInt8_t*>(pReader->GetBlockData(blockNo)))!=NULL) {
127 size=pReader->GetBlockDataLength(blockNo);
138 AliHLTHOMERReader* AliHLTOUTHomerCollection::OpenReader(UChar_t* pSrc, unsigned int size)
140 // open HOMER reader for buffer
141 unsigned int offset=sizeof(AliHLTOUTEventHeader);
142 const AliRawDataHeader* pCDH=GetDataHeader();
143 AliHLTUInt32_t id=(GetEquipmentId());
144 AliHLTUInt32_t statusFlags=pCDH->GetStatus();
145 AliHLTOUTEventHeader* pHLTHeader=reinterpret_cast<AliHLTOUTEventHeader*>(pSrc);
147 // consistency check for the block size
148 if (pHLTHeader->fLength>size) {
149 HLTError("can not treat HLT data block %d: size mismatch, header %d, but buffer is %d", id, pHLTHeader->fLength, size);
151 } else if (pHLTHeader->fLength<size-3) {
152 // data payload is aligned to 32bit, so there can be a difference by at most 3 bytes
153 HLTWarning("size mismatch in HLT data block %d: header %d, but buffer is %d", id, pHLTHeader->fLength, size);
156 // determine the offset of the homer block
157 // the HLT header is mandatory, HLT decision and HLT
158 // payload are optional. HLT decision is always before HLT
159 // payload if existent.
160 if (statusFlags&(0x1<<kCDHFlagsHLTDecision)) {
161 // the block contains HLT decision data, this is just
163 AliHLTUInt32_t* pDecisionLen=reinterpret_cast<AliHLTUInt32_t*>(pSrc+offset);
164 if ((*pDecisionLen)*sizeof(AliHLTUInt32_t)+offset<size) {
165 // the first 32bit word specifies the number of 32bit words in the
166 // decision block -> +1 for this length word
167 offset+=((*pDecisionLen)+1)*sizeof(AliHLTUInt32_t);
169 HLTWarning("size mismatch: HLT decision block bigger than total block length, skipping ...");
174 // check if there is payload
175 if (!(statusFlags&(0x1<<kCDHFlagsHLTPayload))) return NULL;
177 // continue if there is no data left in the buffer
178 if (offset>=pHLTHeader->fLength) {
179 HLTWarning("no HLT payload available, but bit is set, skipping ...");
183 // check for the HOME descriptor type id
184 AliHLTUInt64_t* pHomerDesc=reinterpret_cast<AliHLTUInt64_t*>(pSrc+offset);
185 if (*(pHomerDesc+kID_64b_Offset) != HOMER_BLOCK_DESCRIPTOR_TYPEID &&
186 ByteSwap64(*(pHomerDesc+kID_64b_Offset)) != HOMER_BLOCK_DESCRIPTOR_TYPEID) {
187 HLTWarning("format error: can not find HOMER block descriptor typid, skipping this data block");
191 AliHLTUInt64_t eventId=pHLTHeader->fEventIDHigh;
192 eventId = eventId<<32;
193 eventId|=pHLTHeader->fEventIDLow;
195 return fpManager->OpenReaderBuffer(pSrc+offset, pHLTHeader->fLength-offset);
198 int AliHLTOUTHomerCollection::WriteESD(const AliHLTUInt8_t* pBuffer, AliHLTUInt32_t size, AliHLTComponentDataType dt, AliESDEvent* tgtesd) const
201 if (!pBuffer && size<=0) return -EINVAL;
204 fpEsdManager->WriteESD(pBuffer, size, dt, tgtesd, GetCurrentEventNo());