]>
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; |
6666bfe5 | 248 | while (pRawReader->ReadHeader() && (iResult>=0 || iResult==-ENOSPC)) { |
16e6f752 | 249 | const AliRawDataHeader* pHeaderV2=pRawReader->GetDataHeader(); |
250 | const AliRawDataHeaderV3* pHeaderV3=pRawReader->GetDataHeaderV3(); | |
251 | AliHLTCDHWrapper pHeader; | |
252 | if(pHeaderV2) { | |
253 | pHeader=pHeaderV2; | |
254 | } else if (pHeaderV3) { | |
255 | pHeader=pHeaderV3; | |
256 | } else { | |
6daf06e2 | 257 | HLTError("can not get data header from RawReader, skipping data block ..."); |
258 | continue; | |
259 | } | |
16e6f752 | 260 | unsigned int headerSize=pHeader.GetHeaderSize(); |
261 | unsigned int readSize=pRawReader->GetDataSize()+headerSize; | |
6666bfe5 | 262 | int id=pRawReader->GetEquipmentId(); |
0a51d3cf | 263 | if (fMinEquId>id || fMaxEquId<id) { |
6666bfe5 | 264 | AliError(Form("id %d returned from RawReader is outside range [%d,%d]", id, fMinEquId, fMaxEquId)); |
265 | continue; | |
266 | } | |
bee77626 | 267 | processedIds.push_back(id); |
2f7bb394 | 268 | bool isSelected=IsSelected(id); |
269 | if (fVerbosity>0) { | |
270 | AliInfo(Form("got header for id %d, size %d, %s", id, readSize, isSelected?"selected":"discarded")); | |
271 | } else { | |
272 | AliDebug(0, Form("got header for id %d, size %d", id, readSize)); | |
273 | } | |
274 | if (!isSelected) continue; | |
53f79557 | 275 | if (readSize+offset<=capacity) { |
16e6f752 | 276 | memcpy(outputPtr+offset, pHeader.GetHeader(), headerSize); |
277 | if (readSize>headerSize) { | |
278 | if (!pRawReader->ReadNext(outputPtr+offset+headerSize, readSize-headerSize)) { | |
279 | AliError(Form("error reading %d bytes from RawReader %p", readSize-headerSize, pRawReader)); | |
6666bfe5 | 280 | iResult=-ENODATA; |
281 | break; | |
282 | } | |
6666bfe5 | 283 | } |
6666bfe5 | 284 | AliHLTComponentBlockData bd; |
285 | FillBlockData( bd ); | |
286 | bd.fOffset = offset; | |
287 | bd.fSize = readSize; | |
288 | bd.fDataType = fDataType; | |
0a51d3cf | 289 | if (fSpecification == kAliHLTVoidDataSpec) { |
290 | GetSpecificationFromEquipmentId(id, bd.fSpecification); | |
291 | } else { | |
292 | bd.fSpecification=fSpecification; | |
293 | } | |
6666bfe5 | 294 | outputBlocks.push_back( bd ); |
bee77626 | 295 | } else { |
296 | // we keep the loop going in order to collect the full size | |
297 | fMaxSize=offset+readSize; | |
298 | iResult=-ENOSPC; | |
6666bfe5 | 299 | } |
300 | offset+=readSize; | |
301 | } | |
4eb069ae | 302 | if (!fSkipEmpty && processedIds.size()!=size_t(fMaxEquId-fMinEquId+1)) { |
bee77626 | 303 | // add further empty data blocks |
16e6f752 | 304 | AliHLTCDHWrapper header; |
3f0d2be0 | 305 | AliRawDataHeader headerV2; |
306 | AliRawDataHeaderV3 headerV3; | |
16e6f752 | 307 | if(pRawReader->GetVersion()==2){ |
16e6f752 | 308 | headerV2.fSize=sizeof(AliRawDataHeader); |
309 | const UInt_t* triggermask=pRawReader->GetTriggerPattern(); | |
310 | if (triggermask) { | |
311 | headerV2.fTriggerClassLow=triggermask[0]; | |
312 | headerV2.fROILowTriggerClassHigh=triggermask[1]; | |
313 | } | |
314 | header=&headerV2; | |
315 | } else if (pRawReader->GetVersion()==3){ | |
16e6f752 | 316 | headerV3.fSize=sizeof(AliRawDataHeaderV3); |
317 | const UInt_t* triggermask=pRawReader->GetTriggerPattern(); | |
318 | if (triggermask) { | |
319 | headerV3.fTriggerClassLow=triggermask[0]; | |
320 | headerV3.fTriggerClassesMiddleLow=triggermask[1] & 0x3FFFF; | |
321 | headerV3.fTriggerClassesMiddleHigh= (triggermask[1]>>18) | (triggermask[2]<<14); | |
322 | headerV3.fROILowTriggerClassHigh=(triggermask[2]>>18) | (triggermask[3]<<14); | |
323 | } | |
324 | header=&headerV3; | |
3475fa39 | 325 | } |
16e6f752 | 326 | unsigned int headerSize=header.GetHeaderSize(); |
bee77626 | 327 | processedIds.sort(); |
328 | list<int>::iterator curr=processedIds.begin(); | |
329 | for (int id=fMinEquId; id<=fMaxEquId; id++) { | |
330 | if (curr!=processedIds.end() && *curr<=id) { | |
331 | curr++; | |
332 | } else { | |
16e6f752 | 333 | if (headerSize<=capacity-offset) { |
bee77626 | 334 | HLTInfo("add empty data block for equipment id %d", id); |
16e6f752 | 335 | memcpy(outputPtr+offset, header.GetHeader(), headerSize); |
bee77626 | 336 | AliHLTComponentBlockData bd; |
337 | FillBlockData( bd ); | |
338 | bd.fOffset = offset; | |
16e6f752 | 339 | bd.fSize = headerSize; |
bee77626 | 340 | bd.fDataType = fDataType; |
341 | if (fSpecification == kAliHLTVoidDataSpec) { | |
342 | GetSpecificationFromEquipmentId(id, bd.fSpecification); | |
343 | } else { | |
344 | bd.fSpecification=fSpecification; | |
345 | } | |
346 | outputBlocks.push_back( bd ); | |
347 | } else { | |
348 | // we keep the loop going in order to collect the full size | |
16e6f752 | 349 | fMaxSize=offset+headerSize; |
bee77626 | 350 | iResult=-ENOSPC; |
351 | } | |
16e6f752 | 352 | offset+=headerSize; |
bee77626 | 353 | } |
354 | } | |
355 | } | |
53f79557 | 356 | if (offset<=capacity) { |
bee77626 | 357 | size=offset; |
358 | } else { | |
bee77626 | 359 | outputBlocks.clear(); |
360 | } | |
6666bfe5 | 361 | } else { |
362 | AliErrorStream() << "RawReader uninitialized" << endl; | |
363 | iResult=-EFAULT; | |
364 | } | |
365 | return iResult; | |
366 | } | |
367 | ||
0a51d3cf | 368 | int AliHLTRawReaderPublisherComponent::GetSpecificationFromEquipmentId(int id, AliHLTUInt32_t& specification) const { |
2f7bb394 | 369 | /// get the data specification from the equipment id |
370 | /// default method just returns the equipment id | |
0a51d3cf | 371 | return specification=id; |
6666bfe5 | 372 | } |