Line data Source code
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 6 : ClassImp(AliHLTOUTHomerCollection)
32 :
33 : AliHLTOUTHomerCollection::AliHLTOUTHomerCollection(int event, AliHLTEsdManager* pEsdManager)
34 : :
35 4 : AliHLTOUTHomerBuffer(NULL, 0),
36 4 : fEvent(event),
37 4 : fpCurrent(NULL),
38 4 : fpEsdManager(pEsdManager)
39 12 : {
40 : // constructor
41 : //
42 : // General collection for HLTOUT data in DDL format
43 : //
44 : // see header file for class documentation
45 4 : }
46 :
47 : const int AliHLTOUTHomerCollection::fgkIdShift=16;
48 :
49 0 : AliHLTOUTHomerCollection::~AliHLTOUTHomerCollection()
50 8 : {
51 : // destructor
52 4 : if (fpManager) {
53 4 : if (fpCurrent) fpManager->DeleteReader(fpCurrent);
54 4 : fpCurrent=NULL;
55 4 : }
56 4 : }
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 8 : if (fpManager) {
65 4 : Reset();
66 4 : int firstLink=AliDAQ::DdlIDOffset("HLT");
67 4 : int nofDDLs=AliDAQ::NumberOfDdls("HLT");
68 4 : SelectEquipment(-1,firstLink, firstLink+nofDDLs);
69 4 : UChar_t* pSrc=NULL;
70 8 : while (ReadNextData(pSrc) && pSrc!=NULL && iResult>=0) {
71 0 : AliHLTUInt32_t id=(GetEquipmentId());
72 0 : unsigned int size=GetDataSize();
73 :
74 0 : AliHLTHOMERReader* pReader=OpenReader(pSrc, size);
75 :
76 : // we use the equipment id to identify the different homer blocks
77 0 : id<<=fgkIdShift;
78 0 : if (pReader) {
79 0 : iResult=ScanReader(pReader, id);
80 0 : fpManager->DeleteReader(pReader);
81 0 : }
82 : }
83 4 : } else {
84 : iResult=-ENODEV;
85 : }
86 4 : 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 0 : pBuffer=NULL;
95 0 : size=0;
96 0 : if (fpManager) {
97 0 : Int_t id = Int_t(index>>fgkIdShift);
98 0 : AliHLTUInt32_t blockNo=index&((0x1<<fgkIdShift)-1);
99 :
100 : // block from the same ddl requested?
101 0 : if (fpCurrent && GetEquipmentId()!=id) {
102 0 : fpManager->DeleteReader(fpCurrent);
103 0 : fpCurrent=NULL;
104 0 : }
105 :
106 : // open ddl for equipment id and create HOMER reader
107 0 : if (!fpCurrent) {
108 0 : Reset();
109 0 : SelectEquipment(-1, id, id);
110 0 : UChar_t* pSrc=NULL;
111 0 : if (ReadNextData(pSrc) && pSrc!=NULL) {
112 0 : int srcSize=GetDataSize();
113 0 : fpCurrent=OpenReader(pSrc, srcSize);
114 0 : if (fpCurrent && fpCurrent->ReadNextEvent()!=0) {
115 : iResult=-ENODATA;
116 0 : }
117 0 : } else {
118 : iResult=-ENOSYS;
119 : }
120 0 : }
121 :
122 : // get data
123 0 : if (fpCurrent) {
124 0 : AliHLTMonitoringReader* pReader=fpCurrent;
125 0 : if ((pBuffer=static_cast<const AliHLTUInt8_t*>(pReader->GetBlockData(blockNo)))!=NULL) {
126 0 : size=pReader->GetBlockDataLength(blockNo);
127 0 : } else {
128 : iResult=-ENOENT;
129 : }
130 0 : }
131 0 : } else {
132 : iResult=-ENODEV;
133 : }
134 0 : 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 0 : AliHLTCDHWrapper pCDH=GetDataHeader();
142 0 : if(pCDH.GetHeader()==NULL){
143 0 : HLTError("Couldn't find data header.");
144 0 : return NULL;
145 : }
146 0 : AliHLTUInt32_t id=(GetEquipmentId());
147 0 : AliHLTUInt32_t statusFlags=pCDH.GetStatus();
148 0 : AliHLTOUTEventHeader* pHLTHeader=reinterpret_cast<AliHLTOUTEventHeader*>(pSrc);
149 :
150 : // consistency check for the block size
151 0 : if (pHLTHeader->fLength>size) {
152 0 : HLTError("can not treat HLT data block %d: size mismatch, header %d, but buffer is %d", id, pHLTHeader->fLength, size);
153 0 : return NULL;
154 0 : } else if (pHLTHeader->fLength<size-3) {
155 : // data payload is aligned to 32bit, so there can be a difference by at most 3 bytes
156 0 : HLTWarning("size mismatch in HLT data block %d: header %d, but buffer is %d", id, pHLTHeader->fLength, size);
157 : }
158 :
159 : // determine the offset of the homer block
160 : // the HLT header is mandatory, HLT decision and HLT
161 : // payload are optional. HLT decision is always before HLT
162 : // payload if existent.
163 0 : if (statusFlags&(0x1<<kCDHFlagsHLTDecision)) {
164 : // the block contains HLT decision data, this is just
165 : // skipped here
166 0 : AliHLTUInt32_t* pDecisionLen=reinterpret_cast<AliHLTUInt32_t*>(pSrc+offset);
167 0 : if ((*pDecisionLen)*sizeof(AliHLTUInt32_t)+offset<size) {
168 : // the first 32bit word specifies the number of 32bit words in the
169 : // decision block -> +1 for this length word
170 0 : offset+=((*pDecisionLen)+1)*sizeof(AliHLTUInt32_t);
171 : } else {
172 0 : HLTWarning("size mismatch: HLT decision block bigger than total block length, skipping ...");
173 0 : return NULL;
174 : }
175 0 : }
176 :
177 : // check if there is payload
178 0 : if (!(statusFlags&(0x1<<kCDHFlagsHLTPayload))) return NULL;
179 :
180 : // continue if there is no data left in the buffer
181 0 : if (offset>=pHLTHeader->fLength) {
182 0 : HLTWarning("no HLT payload available, but bit is set, skipping ...");
183 0 : return NULL;
184 : }
185 :
186 : // check for the HOME descriptor type id
187 0 : AliHLTUInt64_t* pHomerDesc=reinterpret_cast<AliHLTUInt64_t*>(pSrc+offset);
188 0 : if (*(pHomerDesc+kID_64b_Offset) != HOMER_BLOCK_DESCRIPTOR_TYPEID &&
189 0 : ByteSwap64(*(pHomerDesc+kID_64b_Offset)) != HOMER_BLOCK_DESCRIPTOR_TYPEID) {
190 0 : HLTWarning("format error: can not find HOMER block descriptor typid, skipping this data block");
191 0 : return NULL;
192 : }
193 :
194 0 : AliHLTUInt64_t eventId=pHLTHeader->fEventIDHigh;
195 0 : eventId = eventId<<32;
196 0 : eventId|=pHLTHeader->fEventIDLow;
197 0 : SetEventId(eventId);
198 0 : return fpManager->OpenReaderBuffer(pSrc+offset, pHLTHeader->fLength-offset);
199 0 : }
200 :
201 : int AliHLTOUTHomerCollection::WriteESD(const AliHLTUInt8_t* pBuffer, AliHLTUInt32_t size, AliHLTComponentDataType dt, AliESDEvent* tgtesd) const
202 : {
203 : // write ESD
204 0 : if (!pBuffer && size<=0) return -EINVAL;
205 : int iResult=0;
206 0 : if (fpEsdManager) {
207 0 : fpEsdManager->WriteESD(pBuffer, size, dt, tgtesd, GetCurrentEventNo());
208 0 : }
209 : return iResult;
210 0 : }
|