]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/BASE/util/AliHLTRawReaderPublisherComponent.cxx
consolidate zero-length arrays (aka struct hack)
[u/mrichter/AliRoot.git] / HLT / BASE / util / AliHLTRawReaderPublisherComponent.cxx
CommitLineData
3dff4b23 1// $Id$
6666bfe5 2
b6fc621c 3///**************************************************************************
2f7bb394 4///* This file is property of and copyright by the *
b6fc621c 5///* ALICE Experiment at CERN, All rights reserved. *
6///* *
7///* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
b6fc621c 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 AliHLTRawReaderPublisherComponent.cxx
19/// @author Matthias Richter
20/// @date
2f7bb394 21/// @brief Publisher component for raw data blocks through the AliRawReader
22/// of the offline environment
6666bfe5 23
24#include "AliHLTRawReaderPublisherComponent.h"
25#include "AliRawReader.h"
e39ae6fb 26#include "AliDAQ.h"
6666bfe5 27#include "AliLog.h"
16e6f752 28#include "AliHLTCDHWrapper.h"
6666bfe5 29#include <cerrno>
30#include <cassert>
bee77626 31#include <list>
6666bfe5 32
6666bfe5 33/** ROOT macro for the implementation of ROOT specific class methods */
34ClassImp(AliHLTRawReaderPublisherComponent)
35
36AliHLTRawReaderPublisherComponent::AliHLTRawReaderPublisherComponent()
37 :
0a51d3cf 38 fMaxSize(5000000),
6666bfe5 39 fDetector(),
40 fMinEquId(-1),
41 fMaxEquId(-1),
03df9065 42 fVerbosity(0),
0a51d3cf 43 fDataType(kAliHLTVoidDataType),
4eb069ae 44 fSpecification(kAliHLTVoidDataSpec),
45 fSkipEmpty(kFALSE)
6666bfe5 46{
4e8187d8 47 // constructor
6666bfe5 48}
49
50AliHLTRawReaderPublisherComponent::~AliHLTRawReaderPublisherComponent()
51{
2f7bb394 52 // destructor
6666bfe5 53}
54
55const char* AliHLTRawReaderPublisherComponent::GetComponentID()
56{
2f7bb394 57 /// inherited from AliHLTComponent: id of the component
6666bfe5 58 return "AliRawReaderPublisher";
59}
60
61AliHLTComponentDataType AliHLTRawReaderPublisherComponent::GetOutputDataType()
62{
2f7bb394 63 /// inherited from AliHLTComponent: output data type of the component.
6666bfe5 64 return fDataType;
65}
66
67void AliHLTRawReaderPublisherComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
68{
2f7bb394 69 /// inherited from AliHLTComponent: output data size estimator
6666bfe5 70 constBase=fMaxSize;
71 inputMultiplier=1;
72}
73
74AliHLTComponent* AliHLTRawReaderPublisherComponent::Spawn()
75{
2f7bb394 76 /// inherited from AliHLTComponent: spawn function.
6666bfe5 77 return new AliHLTRawReaderPublisherComponent;
78}
79
80int AliHLTRawReaderPublisherComponent::DoInit( int argc, const char** argv )
81{
2f7bb394 82 /// inherited from AliHLTComponent: component initialisation and argument scan.
6666bfe5 83 int iResult=0;
84
85 // scan arguments
2f7bb394 86 if (argc && (iResult = ConfigureFromArgumentString(argc, argv)) < 0)
87 return iResult;
88
89 if (!fDetector.IsNull()) {
90 int ddloffset=-1;
91 int ddlcount=-1;
92 if ((ddloffset=AliDAQ::DdlIDOffset(fDetector))<0 ||
93 (ddlcount=AliDAQ::NumberOfDdls(fDetector))<0) {
94 return -EINVAL;
95 }
96 if (fMinEquId<0) fMinEquId=ddloffset;
97 else fMinEquId+=ddloffset;
98
d78f01ff 99 if (fMaxEquId<0 || fMaxEquId>ddlcount) fMaxEquId=ddloffset+ddlcount-1;
2f7bb394 100 else fMaxEquId+=ddloffset;
101 }
102
103 if (fMinEquId>fMaxEquId) fMaxEquId=fMinEquId;
104
105 if (fMinEquId<0) {
106 AliErrorStream() << "equipment id required, use \'-equipmentid\' or \'-detector\' option" << endl;
107 return -EINVAL;
108 }
109
110 AliHLTUInt32_t dummy;
111 if (fMinEquId!=fMaxEquId && GetSpecificationFromEquipmentId(0, dummy)==-ENOSYS) {
112 AliWarningStream() << "publication of multiple equipment ids needs implementation of a child and function GetSpecificationFromEquipmentId to set correct specifications" << endl;
113 //return -EINVAL;
114 }
115
116 if (GetRawReader()!=NULL) {
117 } else {
118 AliErrorStream() << "RawReader instance needed" << endl;
119 return -EINVAL;
120 }
121
122 return iResult;
123}
124
125int AliHLTRawReaderPublisherComponent::DoDeinit()
126{
127 /// inherited from AliHLTComponent: component cleanup
128 int iResult=0;
129 return iResult;
130}
131
132int AliHLTRawReaderPublisherComponent::ScanConfigurationArgument(int argc, const char** argv)
133{
134 /// inherited from AliHLTComponent: argument scan
135 if (argc<1) return 0;
6666bfe5 136 int bMissingParam=0;
2f7bb394 137 int i=0;
138 TString argument=argv[i];
6666bfe5 139
2f7bb394 140 do {
6666bfe5 141 // -detector
142 if (argument.CompareTo("-detector")==0) {
143 if ((bMissingParam=(++i>=argc))) break;
144 fDetector=argv[i];
2f7bb394 145 return 2;
6666bfe5 146
147 // -equipmentid, -minid
148 } else if (argument.CompareTo("-equipmentid")==0 ||
149 argument.CompareTo("-minid")==0) {
150 if ((bMissingParam=(++i>=argc))) break;
151 TString parameter(argv[i]);
152 parameter.Remove(TString::kLeading, ' '); // remove all blanks
153 if (parameter.IsDigit()) {
154 fMinEquId=(AliHLTUInt32_t)parameter.Atoi();
2f7bb394 155 return 2;
6666bfe5 156 } else {
157 HLTError("wrong parameter for argument %s, number expected", argument.Data());
2f7bb394 158 return -EINVAL;
6666bfe5 159 }
160
161 // -maxid
162 } else if (argument.CompareTo("-maxid")==0) {
163 if ((bMissingParam=(++i>=argc))) break;
164 TString parameter(argv[i]);
165 parameter.Remove(TString::kLeading, ' '); // remove all blanks
166 if (parameter.IsDigit()) {
167 fMaxEquId=(AliHLTUInt32_t)parameter.Atoi();
2f7bb394 168 return 2;
6666bfe5 169 } else {
170 HLTError("wrong parameter for argument %s, number expected", argument.Data());
2f7bb394 171 return -EINVAL;
6666bfe5 172 }
173
174 // -verbose
175 } else if (argument.CompareTo("-verbose")==0) {
03df9065 176 fVerbosity++;
2f7bb394 177 return 1;
1c64b19a 178
179 // -silent
180 } else if (argument.CompareTo("-silent")==0) {
181 fVerbosity=0;
2f7bb394 182 return 1;
6666bfe5 183
4eb069ae 184 // -skipempty
185 } else if (argument.CompareTo("-skipempty")==0) {
186 fSkipEmpty=kTRUE;
2f7bb394 187 return 1;
4eb069ae 188
6666bfe5 189 // -datatype
190 } else if (argument.CompareTo("-datatype")==0) {
191 if ((bMissingParam=(++i>=argc))) break;
192 memcpy(&fDataType.fID, argv[i], TMath::Min(kAliHLTComponentDataTypefIDsize, (Int_t)strlen(argv[i])));
193 if ((bMissingParam=(++i>=argc))) break;
194 memcpy(&fDataType.fOrigin, argv[i], TMath::Min(kAliHLTComponentDataTypefOriginSize, (Int_t)strlen(argv[i])));
2f7bb394 195 return 3;
6666bfe5 196
197 // -dataspec
198 } else if (argument.CompareTo("-dataspec")==0) {
199 if ((bMissingParam=(++i>=argc))) break;
200 TString parameter(argv[i]);
201 parameter.Remove(TString::kLeading, ' '); // remove all blanks
202 if (parameter.IsDigit()) {
203 fSpecification=(AliHLTUInt32_t)parameter.Atoi();
204 } else if (parameter.BeginsWith("0x") &&
205 parameter.Replace(0,2,"",0).IsHex()) {
206 sscanf(parameter.Data(),"%x", &fSpecification);
207 } else {
208 HLTError("wrong parameter for argument %s, number expected", argument.Data());
2f7bb394 209 return -EINVAL;
6666bfe5 210 }
2f7bb394 211 return 2;
6666bfe5 212 }
2f7bb394 213 } while (0); // using do-while only to have break available
6666bfe5 214 if (bMissingParam) {
215 HLTError("missing parameter for argument %s", argument.Data());
6666bfe5 216 return -EINVAL;
217 }
218
2f7bb394 219 return -EPROTO;
6666bfe5 220}
221
d76bc02a 222int AliHLTRawReaderPublisherComponent::GetEvent(const AliHLTComponentEventData& /*evtData*/,
223 AliHLTComponentTriggerData& /*trigData*/,
6666bfe5 224 AliHLTUInt8_t* outputPtr,
225 AliHLTUInt32_t& size,
226 vector<AliHLTComponentBlockData>& outputBlocks)
227{
2f7bb394 228 /// inherited from AliHLTDataSource: get the event
6666bfe5 229 int iResult=0;
53f79557 230 AliHLTUInt32_t capacity=size;
231 size=0;
587c9cf9 232
233 // process data events only
234 if (!IsDataEvent()) return 0;
235
a1dbf058 236 unsigned int offset=0;
10ca703e 237 assert(outputPtr!=NULL || size==0);
6666bfe5 238 AliRawReader* pRawReader=GetRawReader();
239 if (pRawReader) {
0a51d3cf 240 pRawReader->Reset();
241 pRawReader->SelectEquipment(-1, fMinEquId, fMaxEquId);
1c64b19a 242 if (fVerbosity>1) {
4eb069ae 243 AliInfo(Form("get event from RawReader %p equipment id range [%d,%d]", pRawReader, fMinEquId, fMaxEquId));
244 } else {
245 AliDebug(0, Form("get event from RawReader %p equipment id range [%d,%d]", pRawReader, fMinEquId, fMaxEquId));
246 }
bee77626 247 list<int> processedIds;
21c623ef 248 UChar_t headerVersion=0;
6666bfe5 249 while (pRawReader->ReadHeader() && (iResult>=0 || iResult==-ENOSPC)) {
16e6f752 250 const AliRawDataHeader* pHeaderV2=pRawReader->GetDataHeader();
251 const AliRawDataHeaderV3* pHeaderV3=pRawReader->GetDataHeaderV3();
252 AliHLTCDHWrapper pHeader;
253 if(pHeaderV2) {
254 pHeader=pHeaderV2;
255 } else if (pHeaderV3) {
256 pHeader=pHeaderV3;
257 } else {
6daf06e2 258 HLTError("can not get data header from RawReader, skipping data block ...");
259 continue;
260 }
21c623ef 261 // store header version for empty blocks later on
262 // any found header will suffice
263 headerVersion=pHeader.GetVersion();
16e6f752 264 unsigned int headerSize=pHeader.GetHeaderSize();
265 unsigned int readSize=pRawReader->GetDataSize()+headerSize;
6666bfe5 266 int id=pRawReader->GetEquipmentId();
0a51d3cf 267 if (fMinEquId>id || fMaxEquId<id) {
6666bfe5 268 AliError(Form("id %d returned from RawReader is outside range [%d,%d]", id, fMinEquId, fMaxEquId));
269 continue;
270 }
bee77626 271 processedIds.push_back(id);
2f7bb394 272 bool isSelected=IsSelected(id);
273 if (fVerbosity>0) {
274 AliInfo(Form("got header for id %d, size %d, %s", id, readSize, isSelected?"selected":"discarded"));
275 } else {
276 AliDebug(0, Form("got header for id %d, size %d", id, readSize));
277 }
278 if (!isSelected) continue;
53f79557 279 if (readSize+offset<=capacity) {
16e6f752 280 memcpy(outputPtr+offset, pHeader.GetHeader(), headerSize);
281 if (readSize>headerSize) {
282 if (!pRawReader->ReadNext(outputPtr+offset+headerSize, readSize-headerSize)) {
283 AliError(Form("error reading %d bytes from RawReader %p", readSize-headerSize, pRawReader));
6666bfe5 284 iResult=-ENODATA;
285 break;
286 }
6666bfe5 287 }
6666bfe5 288 AliHLTComponentBlockData bd;
289 FillBlockData( bd );
290 bd.fOffset = offset;
291 bd.fSize = readSize;
292 bd.fDataType = fDataType;
0a51d3cf 293 if (fSpecification == kAliHLTVoidDataSpec) {
294 GetSpecificationFromEquipmentId(id, bd.fSpecification);
295 } else {
296 bd.fSpecification=fSpecification;
297 }
6666bfe5 298 outputBlocks.push_back( bd );
bee77626 299 } else {
300 // we keep the loop going in order to collect the full size
301 fMaxSize=offset+readSize;
302 iResult=-ENOSPC;
6666bfe5 303 }
304 offset+=readSize;
305 }
4eb069ae 306 if (!fSkipEmpty && processedIds.size()!=size_t(fMaxEquId-fMinEquId+1)) {
bee77626 307 // add further empty data blocks
16e6f752 308 AliHLTCDHWrapper header;
3f0d2be0 309 AliRawDataHeader headerV2;
310 AliRawDataHeaderV3 headerV3;
21c623ef 311 if(headerVersion==2){
16e6f752 312 headerV2.fSize=sizeof(AliRawDataHeader);
313 const UInt_t* triggermask=pRawReader->GetTriggerPattern();
314 if (triggermask) {
315 headerV2.fTriggerClassLow=triggermask[0];
316 headerV2.fROILowTriggerClassHigh=triggermask[1];
317 }
318 header=&headerV2;
21c623ef 319 } else { //assuming V3 even if no header at all was found above
16e6f752 320 headerV3.fSize=sizeof(AliRawDataHeaderV3);
321 const UInt_t* triggermask=pRawReader->GetTriggerPattern();
322 if (triggermask) {
323 headerV3.fTriggerClassLow=triggermask[0];
324 headerV3.fTriggerClassesMiddleLow=triggermask[1] & 0x3FFFF;
325 headerV3.fTriggerClassesMiddleHigh= (triggermask[1]>>18) | (triggermask[2]<<14);
326 headerV3.fROILowTriggerClassHigh=(triggermask[2]>>18) | (triggermask[3]<<14);
327 }
328 header=&headerV3;
3475fa39 329 }
16e6f752 330 unsigned int headerSize=header.GetHeaderSize();
bee77626 331 processedIds.sort();
332 list<int>::iterator curr=processedIds.begin();
333 for (int id=fMinEquId; id<=fMaxEquId; id++) {
334 if (curr!=processedIds.end() && *curr<=id) {
335 curr++;
336 } else {
16e6f752 337 if (headerSize<=capacity-offset) {
bee77626 338 HLTInfo("add empty data block for equipment id %d", id);
16e6f752 339 memcpy(outputPtr+offset, header.GetHeader(), headerSize);
bee77626 340 AliHLTComponentBlockData bd;
341 FillBlockData( bd );
342 bd.fOffset = offset;
16e6f752 343 bd.fSize = headerSize;
bee77626 344 bd.fDataType = fDataType;
345 if (fSpecification == kAliHLTVoidDataSpec) {
346 GetSpecificationFromEquipmentId(id, bd.fSpecification);
347 } else {
348 bd.fSpecification=fSpecification;
349 }
350 outputBlocks.push_back( bd );
351 } else {
352 // we keep the loop going in order to collect the full size
16e6f752 353 fMaxSize=offset+headerSize;
bee77626 354 iResult=-ENOSPC;
355 }
16e6f752 356 offset+=headerSize;
bee77626 357 }
358 }
359 }
53f79557 360 if (offset<=capacity) {
bee77626 361 size=offset;
362 } else {
bee77626 363 outputBlocks.clear();
364 }
6666bfe5 365 } else {
366 AliErrorStream() << "RawReader uninitialized" << endl;
367 iResult=-EFAULT;
368 }
369 return iResult;
370}
371
0a51d3cf 372int AliHLTRawReaderPublisherComponent::GetSpecificationFromEquipmentId(int id, AliHLTUInt32_t& specification) const {
2f7bb394 373 /// get the data specification from the equipment id
374 /// default method just returns the equipment id
0a51d3cf 375 return specification=id;
6666bfe5 376}