]>
Commit | Line | Data |
---|---|---|
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 */ |
34 | ClassImp(AliHLTRawReaderPublisherComponent) | |
35 | ||
36 | AliHLTRawReaderPublisherComponent::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 | ||
50 | AliHLTRawReaderPublisherComponent::~AliHLTRawReaderPublisherComponent() | |
51 | { | |
2f7bb394 | 52 | // destructor |
6666bfe5 | 53 | } |
54 | ||
55 | const char* AliHLTRawReaderPublisherComponent::GetComponentID() | |
56 | { | |
2f7bb394 | 57 | /// inherited from AliHLTComponent: id of the component |
6666bfe5 | 58 | return "AliRawReaderPublisher"; |
59 | } | |
60 | ||
61 | AliHLTComponentDataType AliHLTRawReaderPublisherComponent::GetOutputDataType() | |
62 | { | |
2f7bb394 | 63 | /// inherited from AliHLTComponent: output data type of the component. |
6666bfe5 | 64 | return fDataType; |
65 | } | |
66 | ||
67 | void 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 | ||
74 | AliHLTComponent* AliHLTRawReaderPublisherComponent::Spawn() | |
75 | { | |
2f7bb394 | 76 | /// inherited from AliHLTComponent: spawn function. |
6666bfe5 | 77 | return new AliHLTRawReaderPublisherComponent; |
78 | } | |
79 | ||
80 | int 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 | ||
125 | int AliHLTRawReaderPublisherComponent::DoDeinit() | |
126 | { | |
127 | /// inherited from AliHLTComponent: component cleanup | |
128 | int iResult=0; | |
129 | return iResult; | |
130 | } | |
131 | ||
132 | int 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 | 222 | int 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 |
00286347 | 320 | if(! headerVersion){ |
321 | AliWarning("No data header found! Creating dummy header for empty blocks assuming CDH v3."); | |
322 | } | |
16e6f752 | 323 | headerV3.fSize=sizeof(AliRawDataHeaderV3); |
324 | const UInt_t* triggermask=pRawReader->GetTriggerPattern(); | |
325 | if (triggermask) { | |
326 | headerV3.fTriggerClassLow=triggermask[0]; | |
327 | headerV3.fTriggerClassesMiddleLow=triggermask[1] & 0x3FFFF; | |
328 | headerV3.fTriggerClassesMiddleHigh= (triggermask[1]>>18) | (triggermask[2]<<14); | |
329 | headerV3.fROILowTriggerClassHigh=(triggermask[2]>>18) | (triggermask[3]<<14); | |
330 | } | |
331 | header=&headerV3; | |
3475fa39 | 332 | } |
16e6f752 | 333 | unsigned int headerSize=header.GetHeaderSize(); |
bee77626 | 334 | processedIds.sort(); |
335 | list<int>::iterator curr=processedIds.begin(); | |
336 | for (int id=fMinEquId; id<=fMaxEquId; id++) { | |
337 | if (curr!=processedIds.end() && *curr<=id) { | |
338 | curr++; | |
339 | } else { | |
16e6f752 | 340 | if (headerSize<=capacity-offset) { |
bee77626 | 341 | HLTInfo("add empty data block for equipment id %d", id); |
16e6f752 | 342 | memcpy(outputPtr+offset, header.GetHeader(), headerSize); |
bee77626 | 343 | AliHLTComponentBlockData bd; |
344 | FillBlockData( bd ); | |
345 | bd.fOffset = offset; | |
16e6f752 | 346 | bd.fSize = headerSize; |
bee77626 | 347 | bd.fDataType = fDataType; |
348 | if (fSpecification == kAliHLTVoidDataSpec) { | |
349 | GetSpecificationFromEquipmentId(id, bd.fSpecification); | |
350 | } else { | |
351 | bd.fSpecification=fSpecification; | |
352 | } | |
353 | outputBlocks.push_back( bd ); | |
354 | } else { | |
355 | // we keep the loop going in order to collect the full size | |
16e6f752 | 356 | fMaxSize=offset+headerSize; |
bee77626 | 357 | iResult=-ENOSPC; |
358 | } | |
16e6f752 | 359 | offset+=headerSize; |
bee77626 | 360 | } |
361 | } | |
362 | } | |
53f79557 | 363 | if (offset<=capacity) { |
bee77626 | 364 | size=offset; |
365 | } else { | |
bee77626 | 366 | outputBlocks.clear(); |
367 | } | |
6666bfe5 | 368 | } else { |
369 | AliErrorStream() << "RawReader uninitialized" << endl; | |
370 | iResult=-EFAULT; | |
371 | } | |
372 | return iResult; | |
373 | } | |
374 | ||
0a51d3cf | 375 | int AliHLTRawReaderPublisherComponent::GetSpecificationFromEquipmentId(int id, AliHLTUInt32_t& specification) const { |
2f7bb394 | 376 | /// get the data specification from the equipment id |
377 | /// default method just returns the equipment id | |
0a51d3cf | 378 | return specification=id; |
6666bfe5 | 379 | } |