3 //**************************************************************************
4 //* This file is property of and copyright by the ALICE HLT Project *
5 //* ALICE Experiment at CERN, All rights reserved. *
7 //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8 //* for The ALICE HLT Project. *
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 //**************************************************************************
19 /** @file AliHLTOUTHomerCollection.cxx
20 @author Matthias Richter
22 @brief General collection for HLTOUT data in DDL format.
25 #include "AliHLTOUTHomerCollection.h"
26 #include "AliHLTHOMERLibManager.h"
27 #include "AliHLTHOMERReader.h"
28 #include "AliRawDataHeader.h"
29 #include "AliHLTEsdManager.h"
32 /** ROOT macro for the implementation of ROOT specific class methods */
33 ClassImp(AliHLTOUTHomerCollection)
35 AliHLTOUTHomerCollection::AliHLTOUTHomerCollection(int event, AliHLTEsdManager* pEsdManager)
37 AliHLTOUTHomerBuffer(NULL, 0),
40 fpEsdManager(pEsdManager)
42 // see header file for class documentation
44 // refer to README to build package
46 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
49 const int AliHLTOUTHomerCollection::fgkIdShift=16;
51 AliHLTOUTHomerCollection::~AliHLTOUTHomerCollection()
53 // see header file for class documentation
55 if (fpCurrent) fpManager->DeleteReader(fpCurrent);
60 int AliHLTOUTHomerCollection::GenerateIndex()
62 // see header file for class documentation
63 // step through all HLT ddls, create HOMER readers and
68 int firstLink=AliDAQ::DdlIDOffset("HLT");
69 int nofDDLs=AliDAQ::NumberOfDdls("HLT");
70 SelectEquipment(-1,firstLink, firstLink+nofDDLs);
72 while (ReadNextData(pSrc) && pSrc!=NULL && iResult>=0) {
73 AliHLTUInt32_t id=(GetEquipmentId());
74 unsigned int size=GetDataSize();
76 AliHLTHOMERReader* pReader=OpenReader(pSrc, size);
78 // we use the equipment id to identify the different homer blocks
81 iResult=ScanReader(pReader, id);
82 fpManager->DeleteReader(pReader);
91 int AliHLTOUTHomerCollection::GetDataBuffer(AliHLTUInt32_t index, const AliHLTUInt8_t* &pBuffer,
94 // see header file for class documentation
99 Int_t id = Int_t(index>>fgkIdShift);
100 AliHLTUInt32_t blockNo=index&((0x1<<fgkIdShift)-1);
102 // block from the same ddl requested?
103 if (fpCurrent && GetEquipmentId()!=id) {
104 fpManager->DeleteReader(fpCurrent);
108 // open ddl for equipment id and create HOMER reader
111 SelectEquipment(-1, id, id);
113 if (ReadNextData(pSrc) && pSrc!=NULL) {
114 int srcSize=GetDataSize();
115 fpCurrent=OpenReader(pSrc, srcSize);
116 if (fpCurrent && fpCurrent->ReadNextEvent()!=0) {
126 AliHLTMonitoringReader* pReader=fpCurrent;
127 if ((pBuffer=static_cast<const AliHLTUInt8_t*>(pReader->GetBlockData(blockNo)))!=NULL) {
128 size=pReader->GetBlockDataLength(blockNo);
139 AliHLTHOMERReader* AliHLTOUTHomerCollection::OpenReader(UChar_t* pSrc, unsigned int size)
141 // see header file for class documentation
142 unsigned int offset=sizeof(AliHLTOUTEventHeader);
143 const AliRawDataHeader* pCDH=GetDataHeader();
144 AliHLTUInt32_t id=(GetEquipmentId());
145 AliHLTUInt32_t statusFlags=pCDH->GetStatus();
146 AliHLTOUTEventHeader* pHLTHeader=reinterpret_cast<AliHLTOUTEventHeader*>(pSrc);
148 // consistency check for the block size
149 if (pHLTHeader->fLength>size) {
150 HLTError("can not treat HLT data block %d: size mismatch, header %d, but buffer is %d", id, pHLTHeader->fLength, size);
152 } else if (pHLTHeader->fLength<size-3) {
153 // data payload is aligned to 32bit, so there can be a difference by at most 3 bytes
154 HLTWarning("size mismatch in HLT data block %d: header %d, but buffer is %d", id, pHLTHeader->fLength, size);
157 // determine the offset of the homer block
158 // the HLT header is mandatory, HLT decision and HLT
159 // payload are optional. HLT decision is always before HLT
160 // payload if existent.
161 if (statusFlags&(0x1<<kCDHFlagsHLTDecision)) {
162 // the block contains HLT decision data, this is just
164 AliHLTUInt32_t* pDecisionLen=reinterpret_cast<AliHLTUInt32_t*>(pSrc+offset);
165 if ((*pDecisionLen)*sizeof(AliHLTUInt32_t)+offset<size) {
166 // the first 32bit word specifies the number of 32bit words in the
167 // decision block -> +1 for this length word
168 offset+=((*pDecisionLen)+1)*sizeof(AliHLTUInt32_t);
170 HLTWarning("size mismatch: HLT decision block bigger than total block length, skipping ...");
175 // check if there is payload
176 if (!(statusFlags&(0x1<<kCDHFlagsHLTPayload))) return NULL;
178 // continue if there is no data left in the buffer
179 if (offset>=pHLTHeader->fLength) {
180 HLTWarning("no HLT payload available, but bit is set, skipping ...");
184 // check for the HOME descriptor type id
185 AliHLTUInt64_t* pHomerDesc=reinterpret_cast<AliHLTUInt64_t*>(pSrc+offset);
186 if (*(pHomerDesc+kID_64b_Offset) != HOMER_BLOCK_DESCRIPTOR_TYPEID &&
187 ByteSwap64(*(pHomerDesc+kID_64b_Offset)) != HOMER_BLOCK_DESCRIPTOR_TYPEID) {
188 HLTWarning("format error: can not find HOMER block descriptor typid, skipping this data block");
192 AliHLTUInt64_t eventId=pHLTHeader->fEventIDHigh;
193 eventId = eventId<<32;
194 eventId|=pHLTHeader->fEventIDLow;
196 return fpManager->OpenReaderBuffer(pSrc+offset, pHLTHeader->fLength-offset);
199 int AliHLTOUTHomerCollection::WriteESD(const AliHLTUInt8_t* pBuffer, AliHLTUInt32_t size, AliHLTComponentDataType dt, AliESDEvent* tgtesd) const
201 // see header file for class documentation
202 if (!pBuffer && size<=0) return -EINVAL;
205 fpEsdManager->WriteESD(pBuffer, size, dt, tgtesd, GetCurrentEventNo());