]>
Commit | Line | Data |
---|---|---|
c1292031 | 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 AliHLTOUTPublisherComponent.cxx | |
20 | @author Matthias Richter | |
21 | @date 2008-06-11 | |
22 | @brief A data publisher for data block out of the HLTOUT data | |
23 | */ | |
24 | ||
25 | #include <cstdlib> | |
26 | #include "AliHLTOUTPublisherComponent.h" | |
27 | #include "AliHLTOUT.h" | |
28 | #include "TString.h" | |
29 | #include "AliRawReader.h" | |
30 | ||
31 | /** ROOT macro for the implementation of ROOT specific class methods */ | |
32 | ClassImp(AliHLTOUTPublisherComponent) | |
33 | ||
34 | AliHLTOUTPublisherComponent::AliHLTOUTPublisherComponent() | |
35 | : | |
36 | fFilterRules(), | |
37 | fMaxSize(0) | |
38 | { | |
39 | // see header file for class documentation | |
40 | // or | |
41 | // refer to README to build package | |
42 | // or | |
43 | // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt | |
44 | } | |
45 | ||
46 | AliHLTOUTPublisherComponent::~AliHLTOUTPublisherComponent() | |
47 | { | |
48 | // see header file for class documentation | |
49 | } | |
50 | ||
51 | const char* AliHLTOUTPublisherComponent::GetComponentID() | |
52 | { | |
53 | // see header file for class documentation | |
54 | return "AliHLTOUTPublisher"; | |
55 | } | |
56 | ||
57 | AliHLTComponentDataType AliHLTOUTPublisherComponent::GetOutputDataType() | |
58 | { | |
59 | // see header file for class documentation | |
60 | if (fFilterRules.size()==1) return fFilterRules[0].fDataType; | |
61 | if (fFilterRules.size()==0) return kAliHLTAnyDataType; | |
62 | return kAliHLTMultipleDataType; | |
63 | } | |
64 | ||
65 | int AliHLTOUTPublisherComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList) | |
66 | { | |
67 | // see header file for class documentation | |
68 | tgtList.clear(); | |
69 | AliHLTComponentBlockDataList::iterator desc=fFilterRules.begin(); | |
70 | while (desc!=fFilterRules.end()) { | |
71 | AliHLTComponentDataTypeList::iterator type=tgtList.begin(); | |
72 | while (type!=tgtList.end()) { | |
73 | if (*type==(*desc).fDataType) break; | |
74 | type++; | |
75 | } | |
76 | if (type==tgtList.end()) tgtList.push_back((*desc).fDataType); | |
77 | desc++; | |
78 | } | |
79 | return tgtList.size(); | |
80 | } | |
81 | ||
82 | void AliHLTOUTPublisherComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier ) | |
83 | { | |
84 | // see header file for class documentation | |
85 | constBase=fMaxSize; | |
86 | inputMultiplier=0.0; // there is no new data, just forwarded descriptors | |
87 | } | |
88 | ||
89 | AliHLTComponent* AliHLTOUTPublisherComponent::Spawn() | |
90 | { | |
91 | // see header file for class documentation | |
92 | return new AliHLTOUTPublisherComponent; | |
93 | } | |
94 | ||
95 | int AliHLTOUTPublisherComponent::DoInit( int argc, const char** argv ) | |
96 | { | |
97 | // see header file for class documentation | |
98 | int iResult=0; | |
99 | TString argument=""; | |
100 | int bMissingParam=0; | |
101 | AliHLTComponentBlockData rule; | |
102 | FillBlockData(rule); | |
103 | for (int i=0; i<argc && iResult>=0; i++) { | |
104 | argument=argv[i]; | |
105 | if (argument.IsNull()) continue; | |
106 | ||
107 | // -datatype | |
108 | if (argument.CompareTo("-datatype")==0) { | |
109 | if ((bMissingParam=(i+2>=argc))) break; | |
110 | ||
111 | if (!MatchExactly(rule.fDataType,kAliHLTAnyDataType)) { | |
112 | // the data type has already been set, add to list | |
113 | // and reset | |
114 | fFilterRules.push_back(rule); | |
115 | FillBlockData(rule); | |
116 | } | |
117 | ||
118 | SetDataType(rule.fDataType, argv[i+1], argv[i+2]); | |
119 | i+=2; | |
120 | ||
121 | // -origin | |
122 | } else if (argument.CompareTo("-origin")==0) { | |
123 | if ((bMissingParam=(i+1>=argc))) break; | |
124 | ||
125 | if (!MatchExactly(rule.fDataType,kAliHLTAnyDataType)) { | |
126 | // the data type has already been set, add to list | |
127 | // and reset | |
128 | fFilterRules.push_back(rule); | |
129 | FillBlockData(rule); | |
130 | } | |
131 | ||
132 | SetDataType(rule.fDataType, NULL, argv[i+1]); | |
133 | i+=1; | |
134 | ||
135 | // -typeid | |
136 | } else if (argument.CompareTo("-typeid")==0) { | |
137 | if ((bMissingParam=(i+1>=argc))) break; | |
138 | ||
139 | if (!MatchExactly(rule.fDataType,kAliHLTAnyDataType)) { | |
140 | // the data type has already been set, add to list | |
141 | // and reset | |
142 | fFilterRules.push_back(rule); | |
143 | FillBlockData(rule); | |
144 | } | |
145 | ||
146 | SetDataType(rule.fDataType, argv[i+1], NULL); | |
147 | i+=1; | |
148 | ||
149 | // -dataspec | |
150 | } else if (argument.CompareTo("-dataspec")==0) { | |
151 | if ((bMissingParam=(++i>=argc))) break; | |
152 | ||
153 | if (rule.fSpecification!=kAliHLTVoidDataSpec) { | |
154 | // the specification has already been set, add to list | |
155 | // and reset | |
156 | fFilterRules.push_back(rule); | |
157 | FillBlockData(rule); | |
158 | } | |
159 | ||
160 | TString parameter(argv[i]); | |
161 | parameter.Remove(TString::kLeading, ' '); // remove all blanks | |
162 | char* pRemnant=NULL; | |
163 | rule.fSpecification=strtoul(parameter.Data(), &pRemnant, 0); | |
164 | if (pRemnant!=NULL && pRemnant[0]!=0) { | |
165 | HLTError("invalid parameter/remnant (%s) for argument %s, number expected", pRemnant, argument.Data()); | |
166 | iResult=-EINVAL; | |
167 | } | |
168 | } else { | |
169 | HLTError("unknown argument %s", argument.Data()); | |
170 | iResult=-EINVAL; | |
171 | break; | |
172 | } | |
173 | } | |
174 | if (iResult>=0) { | |
175 | // add the pending rule or at least the empty default rule | |
176 | fFilterRules.push_back(rule); | |
177 | FillBlockData(rule); | |
178 | } | |
179 | return iResult; | |
180 | } | |
181 | ||
182 | int AliHLTOUTPublisherComponent::DoDeinit() | |
183 | { | |
184 | // see header file for class documentation | |
185 | int iResult=0; | |
186 | fFilterRules.clear(); | |
187 | return iResult; | |
188 | } | |
189 | ||
190 | int AliHLTOUTPublisherComponent::GetEvent( const AliHLTComponentEventData& /*evtData*/, | |
191 | AliHLTComponentTriggerData& /*trigData*/, | |
192 | AliHLTUInt8_t* outputPtr, | |
193 | AliHLTUInt32_t& size, | |
194 | AliHLTComponentBlockDataList& outputBlocks ) | |
195 | { | |
196 | // see header file for class documentation | |
197 | int iResult=0; | |
53f79557 | 198 | AliHLTUInt32_t capacity=size; |
199 | size=0; | |
587c9cf9 | 200 | |
201 | // process data events only | |
202 | if (!IsDataEvent()) return 0; | |
203 | ||
c1292031 | 204 | unsigned int offset=0; |
205 | AliHLTOUT* pHLTOUT=NULL; | |
206 | AliRawReader* pRawReader=GetRawReader(); | |
7131ea63 | 207 | if ((pHLTOUT=AliHLTOUT::GetGlobalInstance())!=NULL) { |
208 | // this is the HLTOUT instance set globally by the AliHLTOUT::AliHLTOUTGlobalInstanceGuard | |
209 | // used for data input from the HLTOUT to the publishers of a kChain handler | |
210 | } else | |
c1292031 | 211 | if (pRawReader) { |
212 | pRawReader->Reset(); | |
213 | pHLTOUT=AliHLTOUT::New(pRawReader); | |
7131ea63 | 214 | if (pHLTOUT) iResult=pHLTOUT->Init(); |
c1292031 | 215 | // } else { |
216 | // this is just a hack and work-around for the missing HLT AliLoader. | |
217 | // Because of that the AliRoot framework does not provide the digit tree. | |
218 | // The HLTDigits.root file is opened directly in the AliHLTOUTDigitReader. | |
219 | // Later, the TTree digit tree object must be fetched here and passed to | |
220 | // the HLTOUT instance. | |
221 | // Maybe it's obsolete anyhow: | |
222 | // 1. AliHLT reconstruction from digit data is not supported | |
223 | // 2. When integrated into HLTOUHandler of type kChain, most likely the | |
224 | // AliRawReaderMemory will be used. | |
225 | // The functionality is tested also with the AliHLTOUTDigitReader, for the | |
226 | // mentioned reasons I comment this branch. | |
227 | // pHLTOUT=AliHLTOUT::New(NULL, GetEventCount()); | |
228 | } else { | |
229 | if (GetEventCount()==0) { | |
230 | HLTFatal("can not get RunLoader or RawReader, event processing aborted for current and subsequent events"); | |
231 | } | |
232 | iResult=-ENODEV; | |
233 | } | |
234 | if (iResult>=0 && pHLTOUT) { | |
7131ea63 | 235 | if (true) { // condition was deprecated but keep for the sake of diff |
c1292031 | 236 | for (iResult=pHLTOUT->SelectFirstDataBlock(); |
237 | iResult>=0; | |
238 | iResult=pHLTOUT->SelectNextDataBlock()) { | |
239 | AliHLTComponentDataType dt=kAliHLTVoidDataType; | |
240 | AliHLTUInt32_t spec=kAliHLTVoidDataSpec; | |
241 | pHLTOUT->GetDataBlockDescription(dt, spec); | |
242 | if (fFilterRules.size()>0) { | |
243 | // check if the block is selected | |
244 | unsigned int rule=0; | |
245 | for (; rule<fFilterRules.size(); rule++) { | |
246 | if (fFilterRules[rule].fDataType!=dt) continue; | |
247 | if (fFilterRules[rule].fSpecification!=kAliHLTVoidDataSpec && | |
248 | fFilterRules[rule].fSpecification!=spec) continue; | |
249 | break; | |
250 | } | |
251 | // skip the block if none of the filter rules matches | |
252 | if (rule>=fFilterRules.size()) continue; | |
253 | } | |
254 | const AliHLTUInt8_t* pBuffer=NULL; | |
255 | AliHLTUInt32_t bufferSize=0; | |
256 | if ((iResult=pHLTOUT->GetDataBuffer(pBuffer, bufferSize))>=0) { | |
53f79557 | 257 | if (bufferSize+offset<=capacity) { |
c1292031 | 258 | memcpy(outputPtr+offset, pBuffer, bufferSize); |
259 | AliHLTComponentBlockData bd; | |
260 | FillBlockData( bd ); | |
261 | bd.fOffset = offset; | |
262 | bd.fSize = bufferSize; | |
263 | bd.fDataType = dt; | |
264 | bd.fSpecification = spec; | |
265 | outputBlocks.push_back( bd ); | |
266 | } else { | |
267 | // we keep the loop going in order to collect the full size | |
268 | fMaxSize=offset+bufferSize; | |
269 | } | |
270 | offset+=bufferSize; | |
271 | } | |
272 | } | |
273 | // -ENOENT is not an error but the return value for 'no more data block' | |
274 | if (iResult==-ENOENT) iResult=0; | |
275 | ||
276 | // indicate too little space in buffer for repeated processing | |
53f79557 | 277 | if (offset>capacity) { |
c1292031 | 278 | iResult=-ENOSPC; |
279 | } | |
280 | } else if (GetEventCount()<5) { | |
281 | const char* message=""; | |
282 | if (GetEventCount()==4) message=", suppressing further messages"; | |
283 | HLTError("failed initializing HLTOUT%s", message); | |
284 | } | |
285 | AliHLTOUT::Delete(pHLTOUT); | |
286 | pHLTOUT=NULL; | |
287 | } else { | |
288 | if (GetEventCount()==0) { | |
289 | HLTFatal("can not create HLTOUT instance, event processing aborted for current and most likely subsequent events"); | |
290 | } | |
291 | iResult=-ENODEV; | |
292 | } | |
293 | ||
294 | // finally set the output size | |
7131ea63 | 295 | if (iResult>=0) |
296 | size=offset; | |
c1292031 | 297 | |
298 | return iResult; | |
299 | } |