2 /**************************************************************************
3 * This file is property of and copyright by the ALICE HLT Project *
4 * ALICE Experiment at CERN, All rights reserved. *
6 * Primary Authors: Artur Szostak <artursz@iafrica.com> *
7 * for The ALICE HLT Project. *
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 **************************************************************************/
18 /// @file AliHLTGlobalTriggerDecision.cxx
19 /// @author Artur Szostak <artursz@iafrica.com>
21 /// @brief Implementation of the AliHLTGlobalTriggerDecision class.
23 /// The global trigger decision class stores the global HLT decision.
25 #include "AliHLTGlobalTriggerDecision.h"
26 #include "Riostream.h"
28 #include "AliHLTMisc.h"
29 #include "AliHLTLogging.h"
31 ClassImp(AliHLTGlobalTriggerDecision)
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.";
46 AliHLTGlobalTriggerDecision::AliHLTGlobalTriggerDecision() :
47 AliHLTTriggerDecision(0, "HLTGlobalTrigger"),
48 fContributingTriggers(AliHLTTriggerDecision::Class()),
52 // Default constructor.
54 // We set the ownership to false since the objects are deleted manually by this
55 // class in DeleteInputObjects().
56 fInputObjects.SetOwner(kFALSE);
60 AliHLTGlobalTriggerDecision::AliHLTGlobalTriggerDecision(
61 bool result, const AliHLTTriggerDomain& triggerDomain, const char* description
63 AliHLTTriggerDecision(result, "HLTGlobalTrigger", triggerDomain, description),
64 fContributingTriggers(AliHLTTriggerDecision::Class()),
68 // Constructor specifying multiple information fields.
71 // We set the ownership to false since the objects are deleted manually by this
72 // class in DeleteInputObjects().
73 fInputObjects.SetOwner(kFALSE);
77 AliHLTGlobalTriggerDecision::~AliHLTGlobalTriggerDecision()
79 // Default destructor.
85 void AliHLTGlobalTriggerDecision::Print(Option_t* option) const
87 // Prints the contents of the trigger decision.
90 if (opt.Contains("compact"))
93 AliHLTTriggerDecision::Print("");
95 else if (opt.Contains("short"))
98 AliHLTTriggerDecision::Print(option);
99 cout << "#################### Input trigger decisions ####################" << endl;
100 for (Int_t i = 0; i < NumberOfTriggerInputs(); i++)
102 if (TriggerInput(i) != NULL)
104 TriggerInput(i)->Print(option);
109 log.LoggingVarargs(kHLTLogError, this->ClassName(), FUNCTIONNAME(), __FILE__, __LINE__, kgNULLObjMessage);
112 if (NumberOfTriggerInputs() == 0)
114 cout << "(none)" << endl;
117 else if (opt.Contains("counters"))
119 cout << "Counter\tValue" << endl;
120 for (Int_t i = 0; i < fCounters.GetSize(); i++)
122 cout << i << "\t" << fCounters[i] << endl;
124 if (fCounters.GetSize() == 0)
126 cout << "(none)" << endl;
132 AliHLTTriggerDecision::Print(option);
133 cout << "#################### Input trigger decisions ####################" << endl;
134 for (Int_t i = 0; i < NumberOfTriggerInputs(); i++)
136 cout << "-------------------- Input trigger decision " << i << " --------------------" << endl;
137 if (TriggerInput(i) != NULL)
139 TriggerInput(i)->Print(option);
144 log.LoggingVarargs(kHLTLogError, this->ClassName(), FUNCTIONNAME(), __FILE__, __LINE__, kgNULLObjMessage);
147 if (NumberOfTriggerInputs() == 0)
149 cout << "(none)" << endl;
151 cout << "###################### Other input objects ######################" << endl;
152 for (Int_t i = 0; i < NumberOfInputObjects(); i++)
154 cout << "------------------------ Input object " << i << " ------------------------" << endl;
155 if (InputObject(i) != NULL)
157 InputObject(i)->Print(option);
162 log.LoggingVarargs(kHLTLogError, this->ClassName(), FUNCTIONNAME(), __FILE__, __LINE__, kgSplitModeMessage);
165 if (NumberOfInputObjects() == 0)
167 cout << "(none)" << endl;
169 cout << "#################### Event class counters ####################" << endl;
170 cout << "Counter\tValue" << endl;
171 for (Int_t i = 0; i < fCounters.GetSize(); i++)
173 cout << i << "\t" << fCounters[i] << endl;
175 if (fCounters.GetSize() == 0)
177 cout << "(none)" << endl;
182 void AliHLTGlobalTriggerDecision::Copy(TObject &object) const
184 // copy this to the specified object
186 if (object.IsA() == AliHLTMisc::Instance().IsAliESDHLTDecision()) {
187 AliHLTMisc::Instance().Copy(this, &object);
191 AliHLTGlobalTriggerDecision* pDecision=dynamic_cast<AliHLTGlobalTriggerDecision*>(&object);
194 // copy members if target is a AliHLTGlobalTriggerDecision
197 // copy the base class
198 AliHLTTriggerDecision::Copy(object);
201 TObject *AliHLTGlobalTriggerDecision::Clone(const char */*newname*/) const
203 // create a new clone, classname is ignored
205 return new AliHLTGlobalTriggerDecision(*this);
208 AliHLTGlobalTriggerDecision::AliHLTGlobalTriggerDecision(const AliHLTGlobalTriggerDecision& src) :
209 AliHLTTriggerDecision(src),
210 fContributingTriggers(AliHLTTriggerDecision::Class()),
214 // Copy constructor performs a deep copy.
216 // We set the ownership to false since the objects are deleted manually by this
217 // class in DeleteInputObjects().
218 fInputObjects.SetOwner(kFALSE);
223 AliHLTGlobalTriggerDecision& AliHLTGlobalTriggerDecision::operator=(const AliHLTGlobalTriggerDecision& src)
225 // assignment operator performs a deep copy.
227 fContributingTriggers.Delete();
228 for (int triggerInput=0; triggerInput<src.NumberOfTriggerInputs(); triggerInput++) {
229 const AliHLTTriggerDecision* pTriggerObject=src.TriggerInput(triggerInput);
230 if (pTriggerObject != NULL)
232 // the AddTriggerInput function uses the copy constructor and
233 // makes a new object from the reference
234 AddTriggerInput(*pTriggerObject);
239 log.LoggingVarargs(kHLTLogError, this->ClassName(), FUNCTIONNAME(), __FILE__, __LINE__, kgNULLObjMessage);
243 DeleteInputObjects();
244 for (int inputObject=0; inputObject<src.NumberOfInputObjects(); inputObject++) {
245 const TObject* pInputObject=src.InputObject(inputObject);
246 if (pInputObject != NULL)
248 // the AddInputObject function uses Clone() and
249 // makes a new object from the reference
250 AddInputObject(pInputObject);
255 log.LoggingVarargs(kHLTLogError, this->ClassName(), FUNCTIONNAME(), __FILE__, __LINE__, kgSplitModeMessage);
259 SetCounters(src.Counters());
265 void AliHLTGlobalTriggerDecision::AddInputObject(const TObject* object)
267 // Adds an object to the list of input objects considered in the global trigger.
269 if (object == NULL) return;
270 TObject* obj = object->Clone();
271 obj->SetBit(kCanDelete);
272 fInputObjects.Add(obj);
276 void AliHLTGlobalTriggerDecision::AddInputObjectRef(TObject* object, bool own)
278 // Adds an object to the list of input objects considered in the global trigger.
280 if (object == NULL) return;
283 object->SetBit(kCanDelete);
287 object->ResetBit(kCanDelete);
289 fInputObjects.Add(object);
293 void AliHLTGlobalTriggerDecision::SetCounters(const TArrayL64& counters, Long64_t eventCount)
295 // Sets the counter array.
296 // If the number of events is specified, an additional counter is added at the end.
297 fCounters = counters;
299 int size=fCounters.GetSize();
300 fCounters.Set(size+1);
301 fCounters[size]=eventCount;
306 void AliHLTGlobalTriggerDecision::Clear(Option_t* option)
308 // Clears the trigger domain and resets the decision result.
310 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 fContributingTriggers.Delete();
315 DeleteInputObjects();
320 TObject* AliHLTGlobalTriggerDecision::FindObject(const char* name) const
322 // Finds the first object in fContributingTriggers or fInputObjects that has the given name.
324 TObject* result = fContributingTriggers.FindObject(name);
325 if (result != NULL) return result;
326 return fInputObjects.FindObject(name);
330 TObject* AliHLTGlobalTriggerDecision::FindObject(const TObject* obj) const
332 // Finds the first object in fContributingTriggers or fInputObjects that matches
333 // based on a IsEqual() comparison.
335 TObject* result = fContributingTriggers.FindObject(obj);
336 if (result != NULL) return result;
337 return fInputObjects.FindObject(obj);
341 void AliHLTGlobalTriggerDecision::DeleteInputObjects()
343 // Deletes the objects marked with kCanDelete in fInputObjects and clears the array.
345 for (Int_t i = 0; i < NumberOfInputObjects(); i++)
347 TObject* obj = fInputObjects.UncheckedAt(i);
351 log.LoggingVarargs(kHLTLogError, this->ClassName(), FUNCTIONNAME(), __FILE__, __LINE__, kgSplitModeMessage);
354 if (obj->TestBit(kCanDelete)) delete obj;
356 fInputObjects.Clear();
360 void AliHLTGlobalTriggerDecision::MarkInputObjectsAsOwned()
362 // Marks all input objects as owned.
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 for (Int_t i = 0; i < fInputObjects.GetEntriesFast(); ++i)
369 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.
375 fInputObjects.RemoveAt(i);
376 if (not loggedWarning)
379 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."
384 loggedWarning = true; // Prevent multiple warnings, one is enough.
389 obj->SetBit(kCanDelete);
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 fInputObjects.Compress();
397 #if ROOT_VERSION_CODE < ROOT_VERSION(5,26,0)
398 void AliHLTGlobalTriggerDecision::Streamer(TBuffer &b)
400 // Stream an object of class AliHLTGlobalTriggerDecision.
404 b.ReadClassBuffer(AliHLTGlobalTriggerDecision::Class(), this);
405 MarkInputObjectsAsOwned();
409 b.WriteClassBuffer(AliHLTGlobalTriggerDecision::Class(), this);
412 #endif // ROOT version check.