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