]>
Commit | Line | Data |
---|---|---|
3dff4b23 | 1 | // $Id$ |
6666bfe5 | 2 | |
b6fc621c | 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 | /// | |
6666bfe5 | 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), | |
03df9065 | 48 | fVerbosity(0), |
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) { | |
03df9065 | 134 | fVerbosity++; |
1c64b19a | 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 | ||
b6fc621c | 204 | if (GetRawReader()!=NULL) { |
6666bfe5 | 205 | } else { |
206 | AliErrorStream() << "RawReader instance needed" << endl; | |
207 | return -EINVAL; | |
208 | } | |
209 | ||
210 | return iResult; | |
211 | } | |
212 | ||
213 | int AliHLTRawReaderPublisherComponent::DoDeinit() | |
214 | { | |
215 | // see header file for class documentation | |
216 | int iResult=0; | |
217 | return iResult; | |
218 | } | |
219 | ||
d76bc02a | 220 | int AliHLTRawReaderPublisherComponent::GetEvent(const AliHLTComponentEventData& /*evtData*/, |
221 | AliHLTComponentTriggerData& /*trigData*/, | |
6666bfe5 | 222 | AliHLTUInt8_t* outputPtr, |
223 | AliHLTUInt32_t& size, | |
224 | vector<AliHLTComponentBlockData>& outputBlocks) | |
225 | { | |
226 | // see header file for class documentation | |
227 | int iResult=0; | |
53f79557 | 228 | AliHLTUInt32_t capacity=size; |
229 | size=0; | |
587c9cf9 | 230 | |
231 | // process data events only | |
232 | if (!IsDataEvent()) return 0; | |
233 | ||
a1dbf058 | 234 | unsigned int offset=0; |
10ca703e | 235 | assert(outputPtr!=NULL || size==0); |
6666bfe5 | 236 | AliRawReader* pRawReader=GetRawReader(); |
237 | if (pRawReader) { | |
0a51d3cf | 238 | pRawReader->Reset(); |
239 | pRawReader->SelectEquipment(-1, fMinEquId, fMaxEquId); | |
1c64b19a | 240 | if (fVerbosity>1) { |
4eb069ae | 241 | AliInfo(Form("get event from RawReader %p equipment id range [%d,%d]", pRawReader, fMinEquId, fMaxEquId)); |
242 | } else { | |
243 | AliDebug(0, Form("get event from RawReader %p equipment id range [%d,%d]", pRawReader, fMinEquId, fMaxEquId)); | |
244 | } | |
bee77626 | 245 | list<int> processedIds; |
6666bfe5 | 246 | while (pRawReader->ReadHeader() && (iResult>=0 || iResult==-ENOSPC)) { |
0a51d3cf | 247 | const AliRawDataHeader* pHeader=pRawReader->GetDataHeader(); |
6daf06e2 | 248 | if (pHeader==NULL) { |
249 | HLTError("can not get data header from RawReader, skipping data block ..."); | |
250 | continue; | |
251 | } | |
a1dbf058 | 252 | unsigned int readSize=pRawReader->GetDataSize()+sizeof(AliRawDataHeader); |
6666bfe5 | 253 | int id=pRawReader->GetEquipmentId(); |
1c64b19a | 254 | if (fVerbosity>0) { |
255 | AliInfo(Form("got header for id %d, size %d", id, readSize)); | |
256 | } else { | |
257 | AliDebug(0, Form("got header for id %d, size %d", id, readSize)); | |
258 | } | |
0a51d3cf | 259 | if (fMinEquId>id || fMaxEquId<id) { |
6666bfe5 | 260 | AliError(Form("id %d returned from RawReader is outside range [%d,%d]", id, fMinEquId, fMaxEquId)); |
261 | continue; | |
262 | } | |
bee77626 | 263 | processedIds.push_back(id); |
d04c836e | 264 | if (!IsSelected(id)) continue; |
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))) { | |
3dff4b23 | 269 | AliError(Form("error reading %ld 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); | |
3475fa39 | 296 | const UInt_t* triggermask=pRawReader->GetTriggerPattern(); |
297 | if (triggermask) { | |
298 | header.fTriggerClassLow=triggermask[0]; | |
299 | header.fROILowTriggerClassHigh=triggermask[1]; | |
300 | } | |
bee77626 | 301 | processedIds.sort(); |
302 | list<int>::iterator curr=processedIds.begin(); | |
303 | for (int id=fMinEquId; id<=fMaxEquId; id++) { | |
304 | if (curr!=processedIds.end() && *curr<=id) { | |
305 | curr++; | |
306 | } else { | |
53f79557 | 307 | if (sizeof(AliRawDataHeader)<=capacity-offset) { |
bee77626 | 308 | HLTInfo("add empty data block for equipment id %d", id); |
309 | memcpy(outputPtr+offset, &header, sizeof(AliRawDataHeader)); | |
310 | AliHLTComponentBlockData bd; | |
311 | FillBlockData( bd ); | |
312 | bd.fOffset = offset; | |
313 | bd.fSize = sizeof(AliRawDataHeader); | |
314 | bd.fDataType = fDataType; | |
315 | if (fSpecification == kAliHLTVoidDataSpec) { | |
316 | GetSpecificationFromEquipmentId(id, bd.fSpecification); | |
317 | } else { | |
318 | bd.fSpecification=fSpecification; | |
319 | } | |
320 | outputBlocks.push_back( bd ); | |
321 | } else { | |
322 | // we keep the loop going in order to collect the full size | |
323 | fMaxSize=offset+sizeof(AliRawDataHeader); | |
324 | iResult=-ENOSPC; | |
325 | } | |
326 | offset+=sizeof(AliRawDataHeader); | |
327 | } | |
328 | } | |
329 | } | |
53f79557 | 330 | if (offset<=capacity) { |
bee77626 | 331 | size=offset; |
332 | } else { | |
bee77626 | 333 | outputBlocks.clear(); |
334 | } | |
6666bfe5 | 335 | } else { |
336 | AliErrorStream() << "RawReader uninitialized" << endl; | |
337 | iResult=-EFAULT; | |
338 | } | |
339 | return iResult; | |
340 | } | |
341 | ||
0a51d3cf | 342 | int AliHLTRawReaderPublisherComponent::GetSpecificationFromEquipmentId(int id, AliHLTUInt32_t& specification) const { |
f3506ea2 | 343 | // see header file for class documentation |
0a51d3cf | 344 | return specification=id; |
6666bfe5 | 345 | } |