ALIROOT-5600 - skip non-participating detector modules
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTGlobalTriggerDecision.cxx
CommitLineData
4a035340 1// $Id$
1b9a175e 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"
95ea76b5 27#include "TClass.h"
28#include "AliHLTMisc.h"
f1cac1f9 29#include "AliHLTLogging.h"
1b9a175e 30
31ClassImp(AliHLTGlobalTriggerDecision)
32
33
f1cac1f9 34namespace {
a0806f9b 35const char* kgNULLObjMessage =
36 "The global decision object contains NULL pointers in the fContributingTriggers array."
37 " This is unexpected and probably indicates a serious problem.";
f1cac1f9 38const 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
1b9a175e 46AliHLTGlobalTriggerDecision::AliHLTGlobalTriggerDecision() :
2f251ae6 47AliHLTTriggerDecision(0, "HLTGlobalTrigger"),
1b9a175e 48 fContributingTriggers(AliHLTTriggerDecision::Class()),
52f67e50 49 fInputObjects(),
1b9a175e 50 fCounters()
51{
52 // Default constructor.
34dec501 53
2f251ae6 54 // We set the ownership to false since the objects are deleted manually by this
55 // class in DeleteInputObjects().
56 fInputObjects.SetOwner(kFALSE);
1b9a175e 57}
58
59
60AliHLTGlobalTriggerDecision::AliHLTGlobalTriggerDecision(
52f67e50 61 bool result, const AliHLTTriggerDomain& triggerDomain, const char* description
1b9a175e 62 ) :
52f67e50 63 AliHLTTriggerDecision(result, "HLTGlobalTrigger", triggerDomain, description),
1b9a175e 64 fContributingTriggers(AliHLTTriggerDecision::Class()),
52f67e50 65 fInputObjects(),
1b9a175e 66 fCounters()
67{
68 // Constructor specifying multiple information fields.
69
70 Result(result);
2f251ae6 71 // We set the ownership to false since the objects are deleted manually by this
72 // class in DeleteInputObjects().
73 fInputObjects.SetOwner(kFALSE);
1b9a175e 74}
75
76
77AliHLTGlobalTriggerDecision::~AliHLTGlobalTriggerDecision()
78{
79 // Default destructor.
2f251ae6 80
81 DeleteInputObjects();
1b9a175e 82}
83
84
85void AliHLTGlobalTriggerDecision::Print(Option_t* option) const
86{
87 // Prints the contents of the trigger decision.
88
89 TString opt(option);
52f67e50 90 if (opt.Contains("compact"))
91 {
92 cout << "Global ";
93 AliHLTTriggerDecision::Print("");
94 }
95 else if (opt.Contains("short"))
1b9a175e 96 {
97 cout << "Global ";
98 AliHLTTriggerDecision::Print(option);
52f67e50 99 cout << "#################### Input trigger decisions ####################" << endl;
1b9a175e 100 for (Int_t i = 0; i < NumberOfTriggerInputs(); i++)
101 {
f1cac1f9 102 if (TriggerInput(i) != NULL)
103 {
104 TriggerInput(i)->Print(option);
105 }
106 else
107 {
108 AliHLTLogging log;
a0806f9b 109 log.LoggingVarargs(kHLTLogError, this->ClassName(), FUNCTIONNAME(), __FILE__, __LINE__, kgNULLObjMessage);
f1cac1f9 110 }
1b9a175e 111 }
52f67e50 112 if (NumberOfTriggerInputs() == 0)
113 {
114 cout << "(none)" << endl;
115 }
116 }
117 else if (opt.Contains("counters"))
118 {
119 cout << "Counter\tValue" << endl;
120 for (Int_t i = 0; i < fCounters.GetSize(); i++)
121 {
122 cout << i << "\t" << fCounters[i] << endl;
123 }
124 if (fCounters.GetSize() == 0)
125 {
126 cout << "(none)" << endl;
127 }
1b9a175e 128 }
129 else
130 {
131 cout << "Global ";
132 AliHLTTriggerDecision::Print(option);
52f67e50 133 cout << "#################### Input trigger decisions ####################" << endl;
1b9a175e 134 for (Int_t i = 0; i < NumberOfTriggerInputs(); i++)
135 {
52f67e50 136 cout << "-------------------- Input trigger decision " << i << " --------------------" << endl;
f1cac1f9 137 if (TriggerInput(i) != NULL)
138 {
139 TriggerInput(i)->Print(option);
140 }
141 else
142 {
143 AliHLTLogging log;
a0806f9b 144 log.LoggingVarargs(kHLTLogError, this->ClassName(), FUNCTIONNAME(), __FILE__, __LINE__, kgNULLObjMessage);
f1cac1f9 145 }
1b9a175e 146 }
52f67e50 147 if (NumberOfTriggerInputs() == 0)
148 {
149 cout << "(none)" << endl;
150 }
151 cout << "###################### Other input objects ######################" << endl;
152 for (Int_t i = 0; i < NumberOfInputObjects(); i++)
153 {
154 cout << "------------------------ Input object " << i << " ------------------------" << endl;
f1cac1f9 155 if (InputObject(i) != NULL)
156 {
157 InputObject(i)->Print(option);
158 }
159 else
160 {
161 AliHLTLogging log;
162 log.LoggingVarargs(kHLTLogError, this->ClassName(), FUNCTIONNAME(), __FILE__, __LINE__, kgSplitModeMessage);
163 }
52f67e50 164 }
165 if (NumberOfInputObjects() == 0)
166 {
167 cout << "(none)" << endl;
168 }
169 cout << "#################### Event class counters ####################" << endl;
1b9a175e 170 cout << "Counter\tValue" << endl;
171 for (Int_t i = 0; i < fCounters.GetSize(); i++)
172 {
173 cout << i << "\t" << fCounters[i] << endl;
174 }
52f67e50 175 if (fCounters.GetSize() == 0)
176 {
177 cout << "(none)" << endl;
178 }
1b9a175e 179 }
180}
181
4a035340 182void AliHLTGlobalTriggerDecision::Copy(TObject &object) const
183{
184 // copy this to the specified object
185
95ea76b5 186 if (object.IsA() == AliHLTMisc::Instance().IsAliESDHLTDecision()) {
187 AliHLTMisc::Instance().Copy(this, &object);
188 return;
189 }
190
4a035340 191 AliHLTGlobalTriggerDecision* pDecision=dynamic_cast<AliHLTGlobalTriggerDecision*>(&object);
192 if (pDecision)
193 {
194 // copy members if target is a AliHLTGlobalTriggerDecision
195 *pDecision=*this;
196 }
4a035340 197 // copy the base class
198 AliHLTTriggerDecision::Copy(object);
199}
200
201TObject *AliHLTGlobalTriggerDecision::Clone(const char */*newname*/) const
202{
203 // create a new clone, classname is ignored
204
205 return new AliHLTGlobalTriggerDecision(*this);
206}
30d84601 207
208AliHLTGlobalTriggerDecision::AliHLTGlobalTriggerDecision(const AliHLTGlobalTriggerDecision& src) :
209 AliHLTTriggerDecision(src),
210 fContributingTriggers(AliHLTTriggerDecision::Class()),
211 fInputObjects(),
212 fCounters()
213{
2f251ae6 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 fInputObjects.SetOwner(kFALSE);
219
30d84601 220 *this=src;
221}
222
223AliHLTGlobalTriggerDecision& AliHLTGlobalTriggerDecision::operator=(const AliHLTGlobalTriggerDecision& src)
224{
2f251ae6 225 // assignment operator performs a deep copy.
30d84601 226
227 fContributingTriggers.Delete();
228 for (int triggerInput=0; triggerInput<src.NumberOfTriggerInputs(); triggerInput++) {
229 const AliHLTTriggerDecision* pTriggerObject=src.TriggerInput(triggerInput);
f1cac1f9 230 if (pTriggerObject != NULL)
231 {
232 // the AddTriggerInput function uses the copy constructor and
233 // makes a new object from the reference
234 AddTriggerInput(*pTriggerObject);
235 }
236 else
237 {
238 AliHLTLogging log;
a0806f9b 239 log.LoggingVarargs(kHLTLogError, this->ClassName(), FUNCTIONNAME(), __FILE__, __LINE__, kgNULLObjMessage);
f1cac1f9 240 }
30d84601 241 }
242
2f251ae6 243 DeleteInputObjects();
a0806f9b 244 for (int inputObject=0; inputObject<src.NumberOfInputObjects(); inputObject++) {
30d84601 245 const TObject* pInputObject=src.InputObject(inputObject);
f1cac1f9 246 if (pInputObject != NULL)
247 {
248 // the AddInputObject function uses Clone() and
249 // makes a new object from the reference
250 AddInputObject(pInputObject);
251 }
252 else
253 {
254 AliHLTLogging log;
255 log.LoggingVarargs(kHLTLogError, this->ClassName(), FUNCTIONNAME(), __FILE__, __LINE__, kgSplitModeMessage);
256 }
30d84601 257 }
258
259 SetCounters(src.Counters());
260
261 return *this;
262}
d4ed5215 263
2f251ae6 264
265void AliHLTGlobalTriggerDecision::AddInputObject(const TObject* object)
266{
267 // Adds an object to the list of input objects considered in the global trigger.
268
269 if (object == NULL) return;
270 TObject* obj = object->Clone();
271 obj->SetBit(kCanDelete);
272 fInputObjects.Add(obj);
273}
274
275
276void AliHLTGlobalTriggerDecision::AddInputObjectRef(TObject* object, bool own)
277{
278 // Adds an object to the list of input objects considered in the global trigger.
279
280 if (object == NULL) return;
281 if (own)
282 {
283 object->SetBit(kCanDelete);
284 }
285 else
286 {
287 object->ResetBit(kCanDelete);
288 }
289 fInputObjects.Add(object);
290}
291
292
d4ed5215 293void 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 fCounters = counters;
81d62bb4 298 if (eventCount>=0) {
d4ed5215 299 int size=fCounters.GetSize();
300 fCounters.Set(size+1);
301 fCounters[size]=eventCount;
302 }
303}
2f251ae6 304
305
306void AliHLTGlobalTriggerDecision::Clear(Option_t* option)
307{
308 // Clears the trigger domain and resets the decision result.
309
310 AliHLTTriggerDecision::Clear(option);
a9d2ffa7 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();
2f251ae6 315 DeleteInputObjects();
316 fCounters.Set(0);
317}
318
319
4685d513 320TObject* AliHLTGlobalTriggerDecision::FindObject(const char* name) const
321{
322 // Finds the first object in fContributingTriggers or fInputObjects that has the given name.
323
324 TObject* result = fContributingTriggers.FindObject(name);
325 if (result != NULL) return result;
326 return fInputObjects.FindObject(name);
327}
328
329
330TObject* 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 TObject* result = fContributingTriggers.FindObject(obj);
336 if (result != NULL) return result;
337 return fInputObjects.FindObject(obj);
338}
339
340
2f251ae6 341void AliHLTGlobalTriggerDecision::DeleteInputObjects()
342{
343 // Deletes the objects marked with kCanDelete in fInputObjects and clears the array.
344
345 for (Int_t i = 0; i < NumberOfInputObjects(); i++)
346 {
347 TObject* obj = fInputObjects.UncheckedAt(i);
f1cac1f9 348 if (obj == NULL)
349 {
350 AliHLTLogging log;
351 log.LoggingVarargs(kHLTLogError, this->ClassName(), FUNCTIONNAME(), __FILE__, __LINE__, kgSplitModeMessage);
352 continue;
353 }
2f251ae6 354 if (obj->TestBit(kCanDelete)) delete obj;
355 }
356 fInputObjects.Clear();
357}
358
359
afa10123 360void 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 for (Int_t i = 0; i < fInputObjects.GetEntriesFast(); ++i)
368 {
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.
373 if (obj == NULL)
374 {
375 fInputObjects.RemoveAt(i);
376 if (not loggedWarning)
377 {
378 AliHLTLogging log;
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."
383 );
384 loggedWarning = true; // Prevent multiple warnings, one is enough.
385 }
386 }
387 else
388 {
389 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 fInputObjects.Compress();
395}
396
397#if ROOT_VERSION_CODE < ROOT_VERSION(5,26,0)
2f251ae6 398void AliHLTGlobalTriggerDecision::Streamer(TBuffer &b)
399{
400 // Stream an object of class AliHLTGlobalTriggerDecision.
401
402 if (b.IsReading())
403 {
404 b.ReadClassBuffer(AliHLTGlobalTriggerDecision::Class(), this);
afa10123 405 MarkInputObjectsAsOwned();
2f251ae6 406 }
407 else
408 {
409 b.WriteClassBuffer(AliHLTGlobalTriggerDecision::Class(), this);
410 }
411}
afa10123 412#endif // ROOT version check.