Line data Source code
1 : // $Id$
2 : /**************************************************************************
3 : * This file is property of and copyright by the ALICE HLT Project *
4 : * ALICE Experiment at CERN, All rights reserved. *
5 : * *
6 : * Primary Authors: Artur Szostak <artursz@iafrica.com> *
7 : * for The ALICE HLT Project. *
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 AliHLTGlobalTriggerDecision.cxx
19 : /// @author Artur Szostak <artursz@iafrica.com>
20 : /// @date 26 Nov 2008
21 : /// @brief Implementation of the AliHLTGlobalTriggerDecision class.
22 : ///
23 : /// The global trigger decision class stores the global HLT decision.
24 :
25 : #include "AliHLTGlobalTriggerDecision.h"
26 : #include "Riostream.h"
27 : #include "TClass.h"
28 : #include "AliHLTMisc.h"
29 : #include "AliHLTLogging.h"
30 :
31 126 : ClassImp(AliHLTGlobalTriggerDecision)
32 :
33 :
34 : namespace {
35 : const char* kgNULLObjMessage =
36 : "The global decision object contains NULL pointers in the fContributingTriggers array."
37 : " This is unexpected and probably indicates a serious problem.";
38 : const char* kgSplitModeMessage =
39 : "The global decision object contains NULL pointers in the fInputObjects array."
40 : " This means that it was written to a TTree branch with the split-mode > 0."
41 : " This causes the custom streamer to be skipped and prevents the"
42 : " fInputObjects array to be setup properly. In addition this can cause memory leaks.";
43 : };
44 :
45 :
46 : AliHLTGlobalTriggerDecision::AliHLTGlobalTriggerDecision() :
47 8 : AliHLTTriggerDecision(0, "HLTGlobalTrigger"),
48 16 : fContributingTriggers(AliHLTTriggerDecision::Class()),
49 8 : fInputObjects(),
50 8 : fCounters()
51 40 : {
52 : // Default constructor.
53 :
54 : // We set the ownership to false since the objects are deleted manually by this
55 : // class in DeleteInputObjects().
56 8 : fInputObjects.SetOwner(kFALSE);
57 16 : }
58 :
59 :
60 : AliHLTGlobalTriggerDecision::AliHLTGlobalTriggerDecision(
61 : bool result, const AliHLTTriggerDomain& triggerDomain, const char* description
62 : ) :
63 0 : AliHLTTriggerDecision(result, "HLTGlobalTrigger", triggerDomain, description),
64 0 : fContributingTriggers(AliHLTTriggerDecision::Class()),
65 0 : fInputObjects(),
66 0 : fCounters()
67 0 : {
68 : // Constructor specifying multiple information fields.
69 :
70 0 : Result(result);
71 : // We set the ownership to false since the objects are deleted manually by this
72 : // class in DeleteInputObjects().
73 0 : fInputObjects.SetOwner(kFALSE);
74 0 : }
75 :
76 :
77 : AliHLTGlobalTriggerDecision::~AliHLTGlobalTriggerDecision()
78 12 : {
79 : // Default destructor.
80 :
81 2 : DeleteInputObjects();
82 6 : }
83 :
84 :
85 : void AliHLTGlobalTriggerDecision::Print(Option_t* option) const
86 : {
87 : // Prints the contents of the trigger decision.
88 :
89 0 : TString opt(option);
90 0 : if (opt.Contains("compact"))
91 : {
92 0 : cout << "Global ";
93 0 : AliHLTTriggerDecision::Print("");
94 : }
95 0 : else if (opt.Contains("short"))
96 : {
97 0 : cout << "Global ";
98 0 : AliHLTTriggerDecision::Print(option);
99 0 : cout << "#################### Input trigger decisions ####################" << endl;
100 0 : for (Int_t i = 0; i < NumberOfTriggerInputs(); i++)
101 : {
102 0 : if (TriggerInput(i) != NULL)
103 : {
104 0 : TriggerInput(i)->Print(option);
105 : }
106 : else
107 : {
108 0 : AliHLTLogging log;
109 0 : log.LoggingVarargs(kHLTLogError, this->ClassName(), FUNCTIONNAME(), __FILE__, __LINE__, kgNULLObjMessage);
110 0 : }
111 : }
112 0 : if (NumberOfTriggerInputs() == 0)
113 : {
114 0 : cout << "(none)" << endl;
115 : }
116 : }
117 0 : else if (opt.Contains("counters"))
118 : {
119 0 : cout << "Counter\tValue" << endl;
120 0 : for (Int_t i = 0; i < fCounters.GetSize(); i++)
121 : {
122 0 : cout << i << "\t" << fCounters[i] << endl;
123 : }
124 0 : if (fCounters.GetSize() == 0)
125 : {
126 0 : cout << "(none)" << endl;
127 : }
128 : }
129 : else
130 : {
131 0 : cout << "Global ";
132 0 : AliHLTTriggerDecision::Print(option);
133 0 : cout << "#################### Input trigger decisions ####################" << endl;
134 0 : for (Int_t i = 0; i < NumberOfTriggerInputs(); i++)
135 : {
136 0 : cout << "-------------------- Input trigger decision " << i << " --------------------" << endl;
137 0 : if (TriggerInput(i) != NULL)
138 : {
139 0 : TriggerInput(i)->Print(option);
140 : }
141 : else
142 : {
143 0 : AliHLTLogging log;
144 0 : log.LoggingVarargs(kHLTLogError, this->ClassName(), FUNCTIONNAME(), __FILE__, __LINE__, kgNULLObjMessage);
145 0 : }
146 : }
147 0 : if (NumberOfTriggerInputs() == 0)
148 : {
149 0 : cout << "(none)" << endl;
150 : }
151 0 : cout << "###################### Other input objects ######################" << endl;
152 0 : for (Int_t i = 0; i < NumberOfInputObjects(); i++)
153 : {
154 0 : cout << "------------------------ Input object " << i << " ------------------------" << endl;
155 0 : if (InputObject(i) != NULL)
156 : {
157 0 : InputObject(i)->Print(option);
158 : }
159 : else
160 : {
161 0 : AliHLTLogging log;
162 0 : log.LoggingVarargs(kHLTLogError, this->ClassName(), FUNCTIONNAME(), __FILE__, __LINE__, kgSplitModeMessage);
163 0 : }
164 : }
165 0 : if (NumberOfInputObjects() == 0)
166 : {
167 0 : cout << "(none)" << endl;
168 : }
169 0 : cout << "#################### Event class counters ####################" << endl;
170 0 : cout << "Counter\tValue" << endl;
171 0 : for (Int_t i = 0; i < fCounters.GetSize(); i++)
172 : {
173 0 : cout << i << "\t" << fCounters[i] << endl;
174 : }
175 0 : if (fCounters.GetSize() == 0)
176 : {
177 0 : cout << "(none)" << endl;
178 : }
179 : }
180 0 : }
181 :
182 : void AliHLTGlobalTriggerDecision::Copy(TObject &object) const
183 : {
184 : // copy this to the specified object
185 :
186 20 : if (object.IsA() == AliHLTMisc::Instance().IsAliESDHLTDecision()) {
187 8 : AliHLTMisc::Instance().Copy(this, &object);
188 8 : return;
189 : }
190 :
191 6 : AliHLTGlobalTriggerDecision* pDecision=dynamic_cast<AliHLTGlobalTriggerDecision*>(&object);
192 2 : if (pDecision)
193 : {
194 : // copy members if target is a AliHLTGlobalTriggerDecision
195 2 : *pDecision=*this;
196 2 : }
197 : // copy the base class
198 2 : AliHLTTriggerDecision::Copy(object);
199 12 : }
200 :
201 : TObject *AliHLTGlobalTriggerDecision::Clone(const char */*newname*/) const
202 : {
203 : // create a new clone, classname is ignored
204 :
205 0 : return new AliHLTGlobalTriggerDecision(*this);
206 0 : }
207 :
208 : AliHLTGlobalTriggerDecision::AliHLTGlobalTriggerDecision(const AliHLTGlobalTriggerDecision& src) :
209 0 : AliHLTTriggerDecision(src),
210 0 : fContributingTriggers(AliHLTTriggerDecision::Class()),
211 0 : fInputObjects(),
212 0 : fCounters()
213 0 : {
214 : // Copy constructor performs a deep copy.
215 :
216 : // We set the ownership to false since the objects are deleted manually by this
217 : // class in DeleteInputObjects().
218 0 : fInputObjects.SetOwner(kFALSE);
219 :
220 0 : *this=src;
221 0 : }
222 :
223 : AliHLTGlobalTriggerDecision& AliHLTGlobalTriggerDecision::operator=(const AliHLTGlobalTriggerDecision& src)
224 : {
225 : // assignment operator performs a deep copy.
226 :
227 4 : fContributingTriggers.Delete();
228 4 : for (int triggerInput=0; triggerInput<src.NumberOfTriggerInputs(); triggerInput++) {
229 0 : const AliHLTTriggerDecision* pTriggerObject=src.TriggerInput(triggerInput);
230 0 : if (pTriggerObject != NULL)
231 : {
232 : // the AddTriggerInput function uses the copy constructor and
233 : // makes a new object from the reference
234 0 : AddTriggerInput(*pTriggerObject);
235 0 : }
236 : else
237 : {
238 0 : AliHLTLogging log;
239 0 : log.LoggingVarargs(kHLTLogError, this->ClassName(), FUNCTIONNAME(), __FILE__, __LINE__, kgNULLObjMessage);
240 0 : }
241 : }
242 :
243 2 : DeleteInputObjects();
244 4 : for (int inputObject=0; inputObject<src.NumberOfInputObjects(); inputObject++) {
245 0 : const TObject* pInputObject=src.InputObject(inputObject);
246 0 : if (pInputObject != NULL)
247 : {
248 : // the AddInputObject function uses Clone() and
249 : // makes a new object from the reference
250 0 : AddInputObject(pInputObject);
251 0 : }
252 : else
253 : {
254 0 : AliHLTLogging log;
255 0 : log.LoggingVarargs(kHLTLogError, this->ClassName(), FUNCTIONNAME(), __FILE__, __LINE__, kgSplitModeMessage);
256 0 : }
257 : }
258 :
259 2 : SetCounters(src.Counters());
260 :
261 2 : return *this;
262 0 : }
263 :
264 :
265 : void AliHLTGlobalTriggerDecision::AddInputObject(const TObject* object)
266 : {
267 : // Adds an object to the list of input objects considered in the global trigger.
268 :
269 0 : if (object == NULL) return;
270 0 : TObject* obj = object->Clone();
271 0 : obj->SetBit(kCanDelete);
272 0 : fInputObjects.Add(obj);
273 0 : }
274 :
275 :
276 : void AliHLTGlobalTriggerDecision::AddInputObjectRef(TObject* object, bool own)
277 : {
278 : // Adds an object to the list of input objects considered in the global trigger.
279 :
280 0 : if (object == NULL) return;
281 0 : if (own)
282 : {
283 0 : object->SetBit(kCanDelete);
284 0 : }
285 : else
286 : {
287 0 : object->ResetBit(kCanDelete);
288 : }
289 0 : fInputObjects.Add(object);
290 0 : }
291 :
292 :
293 : void AliHLTGlobalTriggerDecision::SetCounters(const TArrayL64& counters, Long64_t eventCount)
294 : {
295 : // Sets the counter array.
296 : // If the number of events is specified, an additional counter is added at the end.
297 4 : fCounters = counters;
298 2 : if (eventCount>=0) {
299 0 : int size=fCounters.GetSize();
300 0 : fCounters.Set(size+1);
301 0 : fCounters[size]=eventCount;
302 0 : }
303 2 : }
304 :
305 :
306 : void AliHLTGlobalTriggerDecision::Clear(Option_t* option)
307 : {
308 : // Clears the trigger domain and resets the decision result.
309 :
310 34 : AliHLTTriggerDecision::Clear(option);
311 : // because of TClonesArray members in AliHLTTriggerDecision it is not
312 : // enough to call Clear. Delete will also invoke the destructor of the
313 : // elements which is necessary to do the proper internal cleanup
314 17 : fContributingTriggers.Delete();
315 17 : DeleteInputObjects();
316 17 : fCounters.Set(0);
317 17 : }
318 :
319 :
320 : TObject* AliHLTGlobalTriggerDecision::FindObject(const char* name) const
321 : {
322 : // Finds the first object in fContributingTriggers or fInputObjects that has the given name.
323 :
324 0 : TObject* result = fContributingTriggers.FindObject(name);
325 0 : if (result != NULL) return result;
326 0 : return fInputObjects.FindObject(name);
327 0 : }
328 :
329 :
330 : TObject* AliHLTGlobalTriggerDecision::FindObject(const TObject* obj) const
331 : {
332 : // Finds the first object in fContributingTriggers or fInputObjects that matches
333 : // based on a IsEqual() comparison.
334 :
335 0 : TObject* result = fContributingTriggers.FindObject(obj);
336 0 : if (result != NULL) return result;
337 0 : return fInputObjects.FindObject(obj);
338 0 : }
339 :
340 :
341 : void AliHLTGlobalTriggerDecision::DeleteInputObjects()
342 : {
343 : // Deletes the objects marked with kCanDelete in fInputObjects and clears the array.
344 :
345 63 : for (Int_t i = 0; i < NumberOfInputObjects(); i++)
346 : {
347 0 : TObject* obj = fInputObjects.UncheckedAt(i);
348 0 : if (obj == NULL)
349 : {
350 0 : AliHLTLogging log;
351 0 : log.LoggingVarargs(kHLTLogError, this->ClassName(), FUNCTIONNAME(), __FILE__, __LINE__, kgSplitModeMessage);
352 : continue;
353 0 : }
354 0 : if (obj->TestBit(kCanDelete)) delete obj;
355 0 : }
356 21 : fInputObjects.Clear();
357 21 : }
358 :
359 :
360 : void AliHLTGlobalTriggerDecision::MarkInputObjectsAsOwned()
361 : {
362 : // Marks all input objects as owned.
363 :
364 : // We must mark all the objects that were read into fInputObjects as owned.
365 : // Otherwise we will have a memory leak in DeleteInputObjects.
366 : bool loggedWarning = false;
367 18 : for (Int_t i = 0; i < fInputObjects.GetEntriesFast(); ++i)
368 : {
369 0 : TObject* obj = fInputObjects.UncheckedAt(i);
370 : // We must check if the object pointer is NULL. This could happen because the
371 : // class dictionary has not been loaded, so the ReadClassBuffer streamer just
372 : // silently skips the object but fills the fInputObjects array with a NULL pointer.
373 0 : if (obj == NULL)
374 : {
375 0 : fInputObjects.RemoveAt(i);
376 0 : if (not loggedWarning)
377 : {
378 0 : AliHLTLogging log;
379 0 : log.LoggingVarargs(kHLTLogWarning, this->ClassName(), FUNCTIONNAME(), __FILE__, __LINE__,
380 : "The global trigger decision contains NULL pointers in the input object array."
381 : " This is probably due to the fact that some class dictionaries have not been loaded."
382 : " Will just remove the NULL pointer and continue."
383 : );
384 : loggedWarning = true; // Prevent multiple warnings, one is enough.
385 0 : }
386 : }
387 : else
388 : {
389 0 : obj->SetBit(kCanDelete);
390 : }
391 : }
392 : // Compress the input object array to prevent any seg-faults due to access of
393 : // NULL pointers if the objects were not loaded due to missing dictionaries.
394 6 : fInputObjects.Compress();
395 6 : }
396 :
397 : #if ROOT_VERSION_CODE < ROOT_VERSION(5,26,0)
398 : void AliHLTGlobalTriggerDecision::Streamer(TBuffer &b)
399 : {
400 : // Stream an object of class AliHLTGlobalTriggerDecision.
401 :
402 : if (b.IsReading())
403 : {
404 : b.ReadClassBuffer(AliHLTGlobalTriggerDecision::Class(), this);
405 : MarkInputObjectsAsOwned();
406 : }
407 : else
408 : {
409 : b.WriteClassBuffer(AliHLTGlobalTriggerDecision::Class(), this);
410 : }
411 : }
412 : #endif // ROOT version check.
|