]>
Commit | Line | Data |
---|---|---|
6666bfe5 | 1 | // @(#) $Id$ |
2 | ||
3 | /************************************************************************** | |
4 | * This file is property of and copyright by the ALICE HLT Project * | |
5 | * ALICE Experiment at CERN, All rights reserved. * | |
6 | * * | |
7 | * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> * | |
8 | * for The ALICE HLT Project. * | |
9 | * * | |
10 | * Permission to use, copy, modify and distribute this software and its * | |
11 | * documentation strictly for non-commercial purposes is hereby granted * | |
12 | * without fee, provided that the above copyright notice appears in all * | |
13 | * copies and that both the copyright notice and this permission notice * | |
14 | * appear in the supporting documentation. The authors make no claims * | |
15 | * about the suitability of this software for any purpose. It is * | |
16 | * provided "as is" without express or implied warranty. * | |
17 | **************************************************************************/ | |
18 | ||
19 | /** @file AliHLTRawReaderPublisherComponent.cxx | |
20 | @author Matthias Richter | |
21 | @date | |
22 | @brief A general tree publisher component for the AliRawReader. | |
23 | */ | |
24 | ||
25 | // see header file for class documentation | |
26 | // or | |
27 | // refer to README to build package | |
28 | // or | |
29 | // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt | |
30 | ||
31 | #include "AliHLTRawReaderPublisherComponent.h" | |
32 | #include "AliRawReader.h" | |
e39ae6fb | 33 | #include "AliDAQ.h" |
6666bfe5 | 34 | #include "AliLog.h" |
35 | #include <cerrno> | |
36 | #include <cassert> | |
bee77626 | 37 | #include <list> |
6666bfe5 | 38 | |
6666bfe5 | 39 | /** ROOT macro for the implementation of ROOT specific class methods */ |
40 | ClassImp(AliHLTRawReaderPublisherComponent) | |
41 | ||
42 | AliHLTRawReaderPublisherComponent::AliHLTRawReaderPublisherComponent() | |
43 | : | |
0a51d3cf | 44 | fMaxSize(5000000), |
6666bfe5 | 45 | fDetector(), |
46 | fMinEquId(-1), | |
47 | fMaxEquId(-1), | |
1c64b19a | 48 | fVerbosity(1), |
0a51d3cf | 49 | fDataType(kAliHLTVoidDataType), |
4eb069ae | 50 | fSpecification(kAliHLTVoidDataSpec), |
51 | fSkipEmpty(kFALSE) | |
6666bfe5 | 52 | { |
53 | // see header file for class documentation | |
54 | // or | |
55 | // refer to README to build package | |
56 | // or | |
57 | // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt | |
58 | } | |
59 | ||
60 | AliHLTRawReaderPublisherComponent::~AliHLTRawReaderPublisherComponent() | |
61 | { | |
62 | // see header file for class documentation | |
63 | } | |
64 | ||
65 | const char* AliHLTRawReaderPublisherComponent::GetComponentID() | |
66 | { | |
67 | // see header file for class documentation | |
68 | return "AliRawReaderPublisher"; | |
69 | } | |
70 | ||
71 | AliHLTComponentDataType AliHLTRawReaderPublisherComponent::GetOutputDataType() | |
72 | { | |
f3506ea2 | 73 | // see header file for class documentation |
6666bfe5 | 74 | return fDataType; |
75 | } | |
76 | ||
77 | void AliHLTRawReaderPublisherComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier ) | |
78 | { | |
f3506ea2 | 79 | // see header file for class documentation |
6666bfe5 | 80 | constBase=fMaxSize; |
81 | inputMultiplier=1; | |
82 | } | |
83 | ||
84 | AliHLTComponent* AliHLTRawReaderPublisherComponent::Spawn() | |
85 | { | |
86 | // see header file for class documentation | |
87 | return new AliHLTRawReaderPublisherComponent; | |
88 | } | |
89 | ||
90 | int AliHLTRawReaderPublisherComponent::DoInit( int argc, const char** argv ) | |
91 | { | |
92 | // see header file for class documentation | |
93 | int iResult=0; | |
94 | ||
95 | // scan arguments | |
96 | TString argument=""; | |
97 | int bMissingParam=0; | |
98 | for (int i=0; i<argc && iResult>=0; i++) { | |
99 | argument=argv[i]; | |
100 | if (argument.IsNull()) continue; | |
101 | ||
102 | // -detector | |
103 | if (argument.CompareTo("-detector")==0) { | |
104 | if ((bMissingParam=(++i>=argc))) break; | |
105 | fDetector=argv[i]; | |
106 | ||
107 | // -equipmentid, -minid | |
108 | } else if (argument.CompareTo("-equipmentid")==0 || | |
109 | argument.CompareTo("-minid")==0) { | |
110 | if ((bMissingParam=(++i>=argc))) break; | |
111 | TString parameter(argv[i]); | |
112 | parameter.Remove(TString::kLeading, ' '); // remove all blanks | |
113 | if (parameter.IsDigit()) { | |
114 | fMinEquId=(AliHLTUInt32_t)parameter.Atoi(); | |
115 | } else { | |
116 | HLTError("wrong parameter for argument %s, number expected", argument.Data()); | |
117 | iResult=-EINVAL; | |
118 | } | |
119 | ||
120 | // -maxid | |
121 | } else if (argument.CompareTo("-maxid")==0) { | |
122 | if ((bMissingParam=(++i>=argc))) break; | |
123 | TString parameter(argv[i]); | |
124 | parameter.Remove(TString::kLeading, ' '); // remove all blanks | |
125 | if (parameter.IsDigit()) { | |
126 | fMaxEquId=(AliHLTUInt32_t)parameter.Atoi(); | |
127 | } else { | |
128 | HLTError("wrong parameter for argument %s, number expected", argument.Data()); | |
129 | iResult=-EINVAL; | |
130 | } | |
131 | ||
132 | // -verbose | |
133 | } else if (argument.CompareTo("-verbose")==0) { | |
1c64b19a | 134 | fVerbosity=2; |
135 | ||
136 | // -silent | |
137 | } else if (argument.CompareTo("-silent")==0) { | |
138 | fVerbosity=0; | |
6666bfe5 | 139 | |
4eb069ae | 140 | // -skipempty |
141 | } else if (argument.CompareTo("-skipempty")==0) { | |
142 | fSkipEmpty=kTRUE; | |
143 | ||
6666bfe5 | 144 | // -datatype |
145 | } else if (argument.CompareTo("-datatype")==0) { | |
146 | if ((bMissingParam=(++i>=argc))) break; | |
147 | memcpy(&fDataType.fID, argv[i], TMath::Min(kAliHLTComponentDataTypefIDsize, (Int_t)strlen(argv[i]))); | |
148 | if ((bMissingParam=(++i>=argc))) break; | |
149 | memcpy(&fDataType.fOrigin, argv[i], TMath::Min(kAliHLTComponentDataTypefOriginSize, (Int_t)strlen(argv[i]))); | |
150 | ||
151 | // -dataspec | |
152 | } else if (argument.CompareTo("-dataspec")==0) { | |
153 | if ((bMissingParam=(++i>=argc))) break; | |
154 | TString parameter(argv[i]); | |
155 | parameter.Remove(TString::kLeading, ' '); // remove all blanks | |
156 | if (parameter.IsDigit()) { | |
157 | fSpecification=(AliHLTUInt32_t)parameter.Atoi(); | |
158 | } else if (parameter.BeginsWith("0x") && | |
159 | parameter.Replace(0,2,"",0).IsHex()) { | |
160 | sscanf(parameter.Data(),"%x", &fSpecification); | |
161 | } else { | |
162 | HLTError("wrong parameter for argument %s, number expected", argument.Data()); | |
163 | iResult=-EINVAL; | |
164 | } | |
165 | } else { | |
166 | HLTError("unknown argument %s", argument.Data()); | |
167 | iResult=-EINVAL; | |
168 | } | |
169 | } | |
170 | if (bMissingParam) { | |
171 | HLTError("missing parameter for argument %s", argument.Data()); | |
172 | iResult=-EINVAL; | |
173 | } | |
174 | ||
175 | if (iResult<0) return iResult; | |
176 | ||
e39ae6fb | 177 | if (!fDetector.IsNull()) { |
178 | int ddloffset=-1; | |
179 | int ddlcount=-1; | |
180 | if ((ddloffset=AliDAQ::DdlIDOffset(fDetector))<0 || | |
181 | (ddlcount=AliDAQ::NumberOfDdls(fDetector))<0) { | |
182 | return -EINVAL; | |
183 | } | |
184 | if (fMinEquId<0) fMinEquId=ddloffset; | |
185 | else fMinEquId+=ddloffset; | |
186 | ||
187 | if (fMaxEquId<0 || fMaxEquId>ddlcount) fMaxEquId=ddloffset+ddlcount; | |
188 | else fMaxEquId+=ddloffset; | |
189 | } | |
190 | ||
6666bfe5 | 191 | if (fMinEquId>fMaxEquId) fMaxEquId=fMinEquId; |
192 | ||
193 | if (fMinEquId<0) { | |
e39ae6fb | 194 | AliErrorStream() << "equipment id required, use \'-equipmentid\' or \'-detector\' option" << endl; |
6666bfe5 | 195 | return -EINVAL; |
196 | } | |
197 | ||
198 | AliHLTUInt32_t dummy; | |
199 | if (fMinEquId!=fMaxEquId && GetSpecificationFromEquipmentId(0, dummy)==-ENOSYS) { | |
200 | AliWarningStream() << "publication of multiple equipment ids needs implementation of a child and function GetSpecificationFromEquipmentId to set correct specifications" << endl; | |
201 | //return -EINVAL; | |
202 | } | |
203 | ||
204 | AliRawReader* pRawReader=GetRawReader(); | |
205 | if ((pRawReader=GetRawReader())!=NULL) { | |
6666bfe5 | 206 | } else { |
207 | AliErrorStream() << "RawReader instance needed" << endl; | |
208 | return -EINVAL; | |
209 | } | |
210 | ||
211 | return iResult; | |
212 | } | |
213 | ||
214 | int AliHLTRawReaderPublisherComponent::DoDeinit() | |
215 | { | |
216 | // see header file for class documentation | |
217 | int iResult=0; | |
218 | return iResult; | |
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 | { | |
227 | // see header file for class documentation | |
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(); |
1c64b19a | 255 | if (fVerbosity>0) { |
256 | AliInfo(Form("got header for id %d, size %d", id, readSize)); | |
257 | } else { | |
258 | AliDebug(0, Form("got header for id %d, size %d", id, readSize)); | |
259 | } | |
0a51d3cf | 260 | if (fMinEquId>id || fMaxEquId<id) { |
6666bfe5 | 261 | AliError(Form("id %d returned from RawReader is outside range [%d,%d]", id, fMinEquId, fMaxEquId)); |
262 | continue; | |
263 | } | |
bee77626 | 264 | processedIds.push_back(id); |
53f79557 | 265 | if (readSize+offset<=capacity) { |
bee77626 | 266 | memcpy(outputPtr+offset, pHeader, sizeof(AliRawDataHeader)); |
267 | if (readSize>sizeof(AliRawDataHeader)) { | |
268 | if (!pRawReader->ReadNext(outputPtr+offset+sizeof(AliRawDataHeader), readSize-sizeof(AliRawDataHeader))) { | |
0a51d3cf | 269 | AliError(Form("error reading %d bytes from RawReader %p", readSize-sizeof(AliRawDataHeader), pRawReader)); |
6666bfe5 | 270 | iResult=-ENODATA; |
271 | break; | |
272 | } | |
6666bfe5 | 273 | } |
6666bfe5 | 274 | AliHLTComponentBlockData bd; |
275 | FillBlockData( bd ); | |
276 | bd.fOffset = offset; | |
277 | bd.fSize = readSize; | |
278 | bd.fDataType = fDataType; | |
0a51d3cf | 279 | if (fSpecification == kAliHLTVoidDataSpec) { |
280 | GetSpecificationFromEquipmentId(id, bd.fSpecification); | |
281 | } else { | |
282 | bd.fSpecification=fSpecification; | |
283 | } | |
6666bfe5 | 284 | outputBlocks.push_back( bd ); |
bee77626 | 285 | } else { |
286 | // we keep the loop going in order to collect the full size | |
287 | fMaxSize=offset+readSize; | |
288 | iResult=-ENOSPC; | |
6666bfe5 | 289 | } |
290 | offset+=readSize; | |
291 | } | |
4eb069ae | 292 | if (!fSkipEmpty && processedIds.size()!=size_t(fMaxEquId-fMinEquId+1)) { |
bee77626 | 293 | // add further empty data blocks |
294 | AliRawDataHeader header; | |
295 | header.fSize=sizeof(AliRawDataHeader); | |
296 | processedIds.sort(); | |
297 | list<int>::iterator curr=processedIds.begin(); | |
298 | for (int id=fMinEquId; id<=fMaxEquId; id++) { | |
299 | if (curr!=processedIds.end() && *curr<=id) { | |
300 | curr++; | |
301 | } else { | |
53f79557 | 302 | if (sizeof(AliRawDataHeader)<=capacity-offset) { |
bee77626 | 303 | HLTInfo("add empty data block for equipment id %d", id); |
304 | memcpy(outputPtr+offset, &header, sizeof(AliRawDataHeader)); | |
305 | AliHLTComponentBlockData bd; | |
306 | FillBlockData( bd ); | |
307 | bd.fOffset = offset; | |
308 | bd.fSize = sizeof(AliRawDataHeader); | |
309 | bd.fDataType = fDataType; | |
310 | if (fSpecification == kAliHLTVoidDataSpec) { | |
311 | GetSpecificationFromEquipmentId(id, bd.fSpecification); | |
312 | } else { | |
313 | bd.fSpecification=fSpecification; | |
314 | } | |
315 | outputBlocks.push_back( bd ); | |
316 | } else { | |
317 | // we keep the loop going in order to collect the full size | |
318 | fMaxSize=offset+sizeof(AliRawDataHeader); | |
319 | iResult=-ENOSPC; | |
320 | } | |
321 | offset+=sizeof(AliRawDataHeader); | |
322 | } | |
323 | } | |
324 | } | |
53f79557 | 325 | if (offset<=capacity) { |
bee77626 | 326 | size=offset; |
327 | } else { | |
bee77626 | 328 | outputBlocks.clear(); |
329 | } | |
6666bfe5 | 330 | } else { |
331 | AliErrorStream() << "RawReader uninitialized" << endl; | |
332 | iResult=-EFAULT; | |
333 | } | |
334 | return iResult; | |
335 | } | |
336 | ||
0a51d3cf | 337 | int AliHLTRawReaderPublisherComponent::GetSpecificationFromEquipmentId(int id, AliHLTUInt32_t& specification) const { |
f3506ea2 | 338 | // see header file for class documentation |
0a51d3cf | 339 | return specification=id; |
6666bfe5 | 340 | } |