]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/BASE/AliHLTTTreeProcessor.cxx
- fix for setting the drawing option of the histograms in the configuration (Timur)
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTTTreeProcessor.cxx
CommitLineData
4731a36c 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//* *
9bed6a67 7//* Primary Authors: Timur Pocheptsov <Timur.Pocheptsov@cern.ch> *
8//* Matthias Richter <Matthias.Richter@cern.ch>
4731a36c 9//* for The ALICE HLT Project. *
10//* *
11//* Permission to use, copy, modify and distribute this software and its *
12//* documentation strictly for non-commercial purposes is hereby granted *
13//* without fee, provided that the above copyright notice appears in all *
14//* copies and that both the copyright notice and this permission notice *
15//* appear in the supporting documentation. The authors make no claims *
16//* about the suitability of this software for any purpose. It is *
17//* provided "as is" without express or implied warranty. *
18//**************************************************************************
19
20/// @file AliHLTTTreeProcessor.cxx
9bed6a67 21/// @author Timur Pocheptsov, Matthias Richter
4731a36c 22/// @date 05.07.2010
23/// @brief Generic component for data collection in a TTree
24
9bed6a67 25#include <cerrno>
26#include <memory>
27
4731a36c 28#include "AliHLTTTreeProcessor.h"
9bed6a67 29#include "TDirectory.h"
30#include "TDatime.h"
4731a36c 31#include "TString.h"
32#include "TTree.h"
33#include "TH1.h"
4731a36c 34
35/** ROOT macro for the implementation of ROOT specific class methods */
36ClassImp(AliHLTTTreeProcessor)
37
38AliHLTTTreeProcessor::AliHLTTTreeProcessor()
9bed6a67 39 : AliHLTProcessor(),
40 fDefinitions(),
41 fTree(0),
42 fMaxEntries(kMaxEntries),
43 fPublishInterval(kInterval),
44 fLastTime(0)
4731a36c 45{
46 // see header file for class documentation
47 // or
48 // refer to README to build package
49 // or
50 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
51}
52
53AliHLTTTreeProcessor::~AliHLTTTreeProcessor()
54{
55 // see header file for class documentation
56}
57
58AliHLTComponentDataType AliHLTTTreeProcessor::GetOutputDataType()
59{
60 // get the component output data type
61 return kAliHLTDataTypeHistogram;
62}
63
9bed6a67 64void AliHLTTTreeProcessor::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier)
4731a36c 65{
66 // get the output size estimator
67 //
9bed6a67 68 if (!fDefinitions.size()) {
69 HLTError("Can not calculate output data size, no histogram definitions were provided");
70 return;
71 }
72
73 constBase = 0;
74 for (list_const_iterator i = fDefinitions.begin(); i != fDefinitions.end(); ++i)
75 constBase += i->GetSize();
76
77 inputMultiplier = 1.;
4731a36c 78}
79
9bed6a67 80int AliHLTTTreeProcessor::DoInit(int argc, const char** argv)
4731a36c 81{
82 // init component
9bed6a67 83 // ask child to create the tree.
84 int iResult = 0;
4731a36c 85
9bed6a67 86 if (!fTree) {
87 std::auto_ptr<TTree> ptr(CreateTree(argc, argv));
88 if (ptr.get()) {
89 //Stage 1: default initialization.
90 ptr->SetDirectory(0);
91 //"Default" (for derived component) histograms.
92 FillHistogramDefinitions();
93 //Default values.
94 fMaxEntries = kMaxEntries;
95 fPublishInterval = kInterval;
96 fLastTime = 0;
97 //Stage 2: OCDB.
98 TString cdbPath("HLT/ConfigHLT/");
99 cdbPath += GetComponentID();
100 //
101 iResult = ConfigureFromCDBTObjString(cdbPath);
102 //
103 if (iResult < 0)
104 return iResult;
105 //Stage 3: command line arguments.
987a8120 106 if (argc && (iResult = ConfigureFromArgumentString(argc, argv)) < 0)
9bed6a67 107 return iResult;
108
109 ptr->SetCircular(fMaxEntries);
110 fTree = ptr.release();
111 } else //No way to process error correctly - error is unknown here.
112 return -EINVAL;
113 } else {
114 HLTError("fTree pointer must be null before DoInit call");
115 return -EINVAL;
4731a36c 116 }
9bed6a67 117
118 return iResult;
4731a36c 119}
120
121int AliHLTTTreeProcessor::DoDeinit()
122{
123 // cleanup component
124 delete fTree;
9bed6a67 125 fTree = 0;
126 fDefinitions.clear();
127 return 0;
4731a36c 128}
129
9bed6a67 130int AliHLTTTreeProcessor::DoEvent(const AliHLTComponentEventData& evtData, AliHLTComponentTriggerData& trigData)
4731a36c 131{
9bed6a67 132 //Process event and publish histograms.
987a8120 133 AliHLTUInt32_t eventType=0;
134 if (!IsDataEvent(&eventType) && eventType!=gkAliEventTypeEndOfRun) return 0;
135
9bed6a67 136 //I'm pretty sure, that if fTree == 0 (DoInit failed) DoEvent is not called.
137 //But interface itself does not force you to call DoInit before DoEvent, so,
138 //I make this check explicit.
139 if (!fTree) {
140 HLTError("fTree is a null pointer, try to call AliHLTTTreeProcessor::DoInit first.");
141 return -EINVAL;//-ENULLTREE? :)
142 }
143
4731a36c 144 // process input data blocks and fill the tree
987a8120 145 int iResult = 0;
146 if (eventType!=gkAliEventTypeEndOfRun) {
147 iResult=FillTree(fTree, evtData, trigData);
148 }
9bed6a67 149
150 if (iResult < 0)
151 return iResult;
152
153 const TDatime time;
154
987a8120 155 if (fLastTime - time.Get() > fPublishInterval ||
156 eventType==gkAliEventTypeEndOfRun) {
9bed6a67 157 for (list_const_iterator i = fDefinitions.begin(); i != fDefinitions.end(); ++i) {
158 if (TH1* h = CreateHistogram(*i)) {
159 //I do not care about errors here - since I'm not able
160 //to rollback changes.
987a8120 161 // TODO: in case of -ENOSPC et the size of the last object by calling
162 // GetLastObjectSize() and accumulate the necessary output buffer size
9bed6a67 163 PushBack(h, GetOriginDataType(), GetDataSpec());
164 }
165 }
166
167 fLastTime = time.Get();
4731a36c 168 }
9bed6a67 169
170 return iResult;
4731a36c 171}
172
173int AliHLTTTreeProcessor::ScanConfigurationArgument(int argc, const char** argv)
174{
175 // scan one argument and its parameters from the list
9bed6a67 176 // return number of processed entries.
177 // possible arguments:
178 // -maxentries number
179 // -interval number
180 // -histogram name -size number -expression expression [-cut expression ][-opt option]
181 // As soon as "-histogram" found, -size and -expression and -outtype are required,
182 // cut and option can be omitted.
183 if (argc <= 0)
184 return 0;
185
186 std::list<AliHLTHistogramDefinition> newDefs;
187 AliHLTHistogramDefinition def;
188
189 int i = 0;
190 int maxEntries = 0;
191
192 while (i < argc) {
193 const TString argument(argv[i]);
4731a36c 194
9bed6a67 195 if (argument.CompareTo("-maxentries") == 0) { //1. Max entries argument for TTree.
196 if (i + 1 == argc) {
197 HLTError("Numeric value for '-maxentries' is expected");
198 return -EPROTO;
199 }
200 //Next must be a number.
201 //TString returns 0 (number) even if string contains non-numeric symbols.
202 maxEntries = TString(argv[i + 1]).Atoi();
203 if (maxEntries <= 0) {
204 HLTError("Bad value for '-maxentries': %d", maxEntries);
205 return -EPROTO;
206 }
207
208 i += 2;
209 } else if (argument.CompareTo("-interval") == 0) { //2. Interval argument for publishing.
210 if (i + 1 == argc) {
211 HLTError("Numeric value for '-interval' is expected");
212 return -EPROTO;
213 }
4731a36c 214
9bed6a67 215 const Int_t interval = TString(argv[i + 1]).Atoi();
216 if (interval <= 0) {
217 HLTError("Bad value for '-interval' argument: %d", interval);
218 return -EPROTO;
219 }
220
221 fPublishInterval = interval;
222
223 i += 2;
224 } else if (argument.CompareTo("-histogram") == 0) { //3. Histogramm definition.
225 const int nParsed = ParseHistogramDefinition(argc, argv, i, def);
226 if (!nParsed)
227 return -EPROTO;
228
229 newDefs.push_back(def);
230
231 i += nParsed;
232 } else {
233 HLTError("Unknown argument %s", argument.Data());
234 return -EPROTO;
235 }
4731a36c 236 }
237
9bed6a67 238 if (maxEntries != fMaxEntries) {
239 fMaxEntries = maxEntries;
240 if (fTree) {
241 fTree->Reset();
242 fTree->SetCircular(fMaxEntries);
243 }
244 }
4731a36c 245
9bed6a67 246 if (newDefs.size())
247 fDefinitions.swap(newDefs);
248
249 return i;
4731a36c 250}
251
9bed6a67 252TH1* AliHLTTTreeProcessor::CreateHistogram(const AliHLTHistogramDefinition& d)
4731a36c 253{
953ad7b0 254
4731a36c 255 // create a histogram from the tree
9bed6a67 256 if (!fTree) {
257 HLTError("fTree is a null pointer, try to call AliHLTTTreeProcessor::DoInit first.");
258 return 0;
259 }
260
23ef7d2b 261 TString histName(d.GetName());
262 if (!histName.Contains("(")) {
263 //Without number of bins, the histogram will be "fixed"
264 //and most of values can go to underflow/overflow bins,
265 //since kCanRebin will be false.
266 histName += TString::Format("(%d)", Int_t(kDefaultNBins));
267 }
268
269 const Long64_t rez = fTree->Project(histName.Data(), d.GetExpression().Data(), d.GetCut().Data(), d.GetDrawOption().Data());
9bed6a67 270
271 if (rez == -1) {
272 HLTError("TTree::Project failed");
273 return 0;
274 }
275
953ad7b0 276 //Now, cut off the binning part of a name
277 histName = histName(0, histName.Index("("));
278 TH1 * hist = dynamic_cast<TH1*>(gDirectory->Get(histName.Data()));
279 if (!hist) {
953ad7b0 280 const TString msg(Form("Hist %s is a null pointer, selection was %s, strange name or hist's type\n", histName.Data(), d.GetExpression().Data()));
281 HLTError(msg.Data());
3c7e1276 282 }else if (d.GetDrawOption().Length()) {
283 hist->SetOption(d.GetDrawOption().Data());
953ad7b0 284 }
285
286 return hist;
9bed6a67 287}
288
289int AliHLTTTreeProcessor::ParseHistogramDefinition(int argc, const char** argv, int pos, AliHLTHistogramDefinition& dst)const
290{
291 //Histogram-definition:
292 // -histogram name -size number -expression expression [-cut expression][-opt option]
293
294 //at pos we have '-histogram', at pos + 1 must be the name.
295 if (pos + 1 == argc) {
296 HLTError("Bad histogram definition, histogram name is expected");
297 return 0;
298 }
299
300 dst.SetName(argv[pos + 1]);
301 pos += 2;
302
303 //At pos must be '-size', and number at pos + 1.
304 if (pos == argc || TString(argv[pos]).CompareTo("-size")) {
305 HLTError("Bad histogram definition, '-size' is expected");
306 return 0;
307 }
308
309 if (pos + 1 == argc) {
310 HLTError("Bad histogram definition, size is expected");
311 return 0;
312 }
313
314 dst.SetSize(TString(argv[pos + 1]).Atoi());
315 if (dst.GetSize() <= 0) {
316 HLTError("Bad histogram definition, positive size is required");
317 return 0;
318 }
319
320 pos += 2;
321 //At pos must be '-expression', and expression at pos + 1.
322 if (pos == argc || TString(argv[pos]).CompareTo("-expression")) {
323 HLTError("Bad histogram definition, '-expression' is expected");
324 return 0;
325 }
326
327 if (pos + 1 == argc) {
328 HLTError("Bad histogram definition, expression is expected");
329 return 0;
330 }
331
332 dst.SetExpression(argv[pos + 1]);
333 pos += 2;
334
335 int processed = 6;
336 dst.SetCut("");
337 dst.SetDrawOption("");
338
339 //remaining options can be the cut and Draw option.
340 //cut must be first.
341 if (pos + 1 >= argc)
342 return processed;
343
344 if (TString(argv[pos]).CompareTo("-cut") == 0) {
345 dst.SetCut(argv[pos + 1]);
346 pos += 2;
347 processed += 2;
348 }
349
350 if (pos + 1 >= argc)
351 return processed;
352
353 if (TString(argv[pos]).CompareTo("-opt") == 0) {
354 dst.SetDrawOption(argv[pos + 1]);
355 processed += 2;
356 }
357
358 return processed;
4731a36c 359}