1 // $Id: AliHLTTriggerCounterComponent.cxx 43071 2010-08-25 08:41:44Z richterm $
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 AliHLTTriggerCounterComponent.cxx
19 /// @author Artur Szostak <artursz@iafrica.com>
21 /// @brief Implementation of the AliHLTTriggerCounterComponent class.
23 /// The AliHLTTriggerCounterComponent is used to count HLT input and output
24 /// triggers based on the global trigger decisions coming from the global HLT
25 /// trigger component.
27 #include "AliHLTTriggerCounterComponent.h"
28 #include "AliHLTTriggerDecision.h"
29 #include "AliHLTGlobalTriggerDecision.h"
30 #include "AliHLTTriggerCounters.h"
31 #include "AliHLTCTPData.h"
32 #include "AliCDBManager.h"
33 #include "AliCDBStorage.h"
34 #include "AliCDBEntry.h"
35 #include "TObjString.h"
40 ClassImp(AliHLTTriggerCounterComponent)
42 const char* AliHLTTriggerCounterComponent::fgkConfigCDBPath = "HLT/ConfigHLT/HLTTriggerCounter";
43 TMap AliHLTTriggerCounterComponent::fgInitialCounterConfig(TCollection::kInitHashTableCapacity, 2);
46 AliHLTTriggerCounterComponent::AliHLTTriggerCounterComponent() :
51 fInputTimes(TCollection::kInitHashTableCapacity, 2),
52 fOutputTimes(TCollection::kInitHashTableCapacity, 2),
55 fDefaultMaxIntegrationTime(1.),
56 fCountFalseInputs(false),
57 fCountFalseOutputs(false)
59 // Default constructor.
61 fInputTimes.SetOwner(kTRUE);
62 fOutputTimes.SetOwner(kTRUE);
66 AliHLTTriggerCounterComponent::~AliHLTTriggerCounterComponent()
68 // Default destructor.
73 const char* AliHLTTriggerCounterComponent::GetComponentID()
75 // Returns the component ID.
76 return "HLTTriggerCounter";
80 void AliHLTTriggerCounterComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list)
82 // Returns the list of input data types that are handled.
83 list.push_back(kAliHLTDataTypeGlobalTrigger);
84 list.push_back(kAliHLTDataTypeTriggerDecision);
88 AliHLTComponentDataType AliHLTTriggerCounterComponent::GetOutputDataType()
90 // Returns kAliHLTMultipleDataType.
91 return kAliHLTMultipleDataType;
95 int AliHLTTriggerCounterComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& list)
97 // Returns the list of output data block types generated.
98 list.push_back(kAliHLTDataTypeInputTriggerCounters);
99 list.push_back(kAliHLTDataTypeOutputTriggerCounters);
100 return int(list.size());
104 void AliHLTTriggerCounterComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier)
106 // Returns the buffer size requirements.
108 inputMultiplier = fOutputMultiplier;
112 AliHLTComponent* AliHLTTriggerCounterComponent::Spawn()
114 // Creates a new instance of the component.
115 return new AliHLTTriggerCounterComponent;
119 Int_t AliHLTTriggerCounterComponent::DoInit(int argc, const char** argv)
121 // Initialises the data checker component from the command line.
123 HLTInfo("Starting HLT trigger counter component.");
125 const char* configFileName = NULL;
126 fInputCounters.Clear();
127 fOutputCounters.Clear();
129 fOutputTimes.Clear();
130 fLastPublishTime = -1;
132 fDefaultMaxIntegrationTime = -1;
133 fCountFalseInputs = false;
134 fCountFalseOutputs = false;
135 bool loadCDBObject = true;
137 for (int i = 0; i < argc; ++i)
139 if (strcmp(argv[i], "-config") == 0)
141 if (configFileName != NULL)
143 HLTWarning("The configuration macro was already specified."
144 " Will replace previous value given by -config."
149 HLTError("The configuration macro filename was not specified." );
152 configFileName = argv[i+1];
157 if (strcmp(argv[i], "-publishperiod") == 0)
159 if (fPublishPeriod != -1)
161 HLTWarning("The publish period was already specified."
162 " Will replace previous value given by -publishperiod."
167 HLTError("Publish period value was not specified for -publishperiod.");
172 double tmpnum = strtod(argv[i+1], &err);
173 if (err == NULL or *err != '\0')
175 HLTError("Cannot convert '%s' to a floating point value.", argv[i+1]);
180 HLTError("The specified value '%s' is out of range.", argv[i+1]);
183 fPublishPeriod = (tmpnum < 0 ? -1 : tmpnum);
188 if (strcmp(argv[i], "-skipcdb") == 0)
190 loadCDBObject = false;
194 if (strcmp(argv[i], "-countfalseinputs") == 0)
196 fCountFalseInputs = true;
200 if (strcmp(argv[i], "-countfalseoutputs") == 0)
202 fCountFalseOutputs = true;
206 if (strcmp(argv[i], "-integrationtime") == 0)
208 if (fDefaultMaxIntegrationTime != -1)
210 HLTWarning("The maximum integration time was already specified."
211 " Will replace previous value given by -integrationtime."
216 HLTError("A value for the maximum integration time was not specified for -integrationtime.");
221 double tmpnum = strtod(argv[i+1], &err);
222 if (err == NULL or *err != '\0')
224 HLTError("Cannot convert '%s' to a floating point value.", argv[i+1]);
229 HLTError("The specified value '%s' is out of range.", argv[i+1]);
234 HLTError("The specified value '%s' for the integration time must be positive.", argv[i+1]);
237 fDefaultMaxIntegrationTime = tmpnum;
242 HLTError("Unknown option '%s'.", argv[i]);
246 if (fDefaultMaxIntegrationTime == -1) fDefaultMaxIntegrationTime = 1.;
247 if (configFileName != NULL)
249 int result = LoadConfigFromFile(configFileName);
250 if (result != 0) return result;
252 else if (loadCDBObject)
254 int result = LoadConfigFromCDB(fgkConfigCDBPath);
255 if (result != 0) return result;
258 SetupCTPData(); // Setup the CTP accounting in AliHLTComponent.
264 Int_t AliHLTTriggerCounterComponent::DoDeinit()
266 // Cleans up the component.
268 HLTInfo("Stopping HLT trigger counter component.");
269 fInputCounters.Clear();
270 fOutputCounters.Clear();
272 fOutputTimes.Clear();
277 int AliHLTTriggerCounterComponent::DoEvent(const AliHLTComponentEventData& /*evtData*/, AliHLTComponentTriggerData& /*trigData*/)
279 // Finds the global trigger objects and adds the triggers to the counters.
281 fInputCounters.UpdateTimeStamp();
282 fOutputCounters.UpdateTimeStamp();
283 Double_t inputTime = fInputCounters.TimeStamp().AsDouble();
284 Double_t outputTime = fOutputCounters.TimeStamp().AsDouble();
286 // Add the CTP input triggers if available.
287 const AliHLTCTPData* ctp = CTPData();
290 const TArrayL64& counters = ctp->Counters();
291 for (Int_t i = 0; i < counters.GetSize(); ++i)
293 const char* ctpName = ctp->Name(i);
294 // Check if CTP counter is initialised and skip if not.
295 if (strcmp(ctpName, "AliHLTReadoutList") == 0 and counters[i] == 0) continue;
296 TObject* cntobj = fInputCounters.FindObject(ctpName);
299 HLTDebug("Updating existing CTP counter \"%s\".", cntobj->GetName());
300 AliHLTTriggerCounters::AliCounter* counter = static_cast<AliHLTTriggerCounters::AliCounter*>(cntobj);
301 if (counter->Counter() == ULong64_t(counters[i])) continue;
302 counter->Counter(ULong64_t(counters[i]));
303 counter->SetBit(BIT(14), true); // mark counter as incremented
306 static_cast<AliRingBuffer*>( fInputTimes.FindObject(ctpName) ),
312 HLTDebug("Adding new CTP counter \"%s\".", cntobj->GetName());
315 "New CTP trigger input counter found during the run.",
316 Double_t(counters[i]),
319 fInputCounters.GetCounterN(fInputCounters.NumberOfCounters()-1).SetBit(BIT(14), true); // mark counter as incremented
320 fInputTimes.Add(new AliRingBuffer(ctpName, inputTime));
326 const TObject* obj = GetFirstInputObject(kAliHLTDataTypeGlobalTrigger, "AliHLTGlobalTriggerDecision");
329 HLTDebug("Received trigger decision object of type AliHLTGlobalTriggerDecision.");
330 const AliHLTGlobalTriggerDecision* decision = dynamic_cast<const AliHLTGlobalTriggerDecision*>(obj);
331 if (decision != NULL)
333 if ((not fCountFalseOutputs and decision->Result()) or fCountFalseOutputs)
335 // Tokenise the global trigger description string which contains a
336 // list of the triggers that were fired and increment the corresponding
338 TString names = decision->Description();
341 while (names.Tokenize(token, from, ","))
343 TObject* cntobj = fOutputCounters.FindObject(token.Data());
346 HLTDebug("Updating existing output counter \"%s\".", cntobj->GetName());
347 AliHLTTriggerCounters::AliCounter* counter = static_cast<AliHLTTriggerCounters::AliCounter*>(cntobj);
348 counter->Increment();
349 counter->SetBit(BIT(14), true); // mark counter as incremented
352 static_cast<AliRingBuffer*>( fOutputTimes.FindObject(token.Data()) ),
358 HLTDebug("Adding new output counter \"%s\".", cntobj->GetName());
359 fOutputCounters.Add(token.Data(), "New trigger output counter found during the run.", 1, 1);
360 fOutputCounters.GetCounterN(fOutputCounters.NumberOfCounters()-1).SetBit(BIT(14), true); // mark counter as incremented
361 fOutputTimes.Add(new AliRingBuffer(token.Data(), outputTime));
366 // Add the list of input triggers.
367 for (Int_t i = 0; i < decision->NumberOfTriggerInputs(); ++i)
369 const AliHLTTriggerDecision* input = decision->TriggerInput(i);
370 if (input == NULL) continue;
371 if (not fCountFalseInputs and not input->Result()) continue;
372 TObject* cntobj = fInputCounters.FindObject(input->Name());
375 HLTDebug("Updating existing input counter \"%s\".", cntobj->GetName());
376 AliHLTTriggerCounters::AliCounter* counter = static_cast<AliHLTTriggerCounters::AliCounter*>(cntobj);
377 counter->Increment();
378 counter->SetBit(BIT(14), true); // mark counter as incremented
381 static_cast<AliRingBuffer*>( fInputTimes.FindObject(input->Name()) ),
387 HLTDebug("Adding new input counter \"%s\".", cntobj->GetName());
388 fInputCounters.Add(input->Name(), "New trigger input counter found during the run.", 1, 1);
389 fInputCounters.GetCounterN(fInputCounters.NumberOfCounters()-1).SetBit(BIT(14), true); // mark counter as incremented
390 fInputTimes.Add(new AliRingBuffer(input->Name(), inputTime));
394 obj = GetNextInputObject();
397 // Look for the individual trigger decision blocks to add if they are available.
398 obj = GetFirstInputObject(kAliHLTDataTypeTriggerDecision, "AliHLTTriggerDecision");
401 HLTDebug("Received trigger decision object of type AliHLTTriggerDecision.");
402 const AliHLTTriggerDecision* decision = dynamic_cast<const AliHLTTriggerDecision*>(obj);
403 if (decision != NULL and ((not fCountFalseInputs and decision->Result()) or fCountFalseInputs))
405 TObject* cntobj = fInputCounters.FindObject(decision->Name());
408 HLTDebug("Updating existing input counter \"%s\".", cntobj->GetName());
409 AliHLTTriggerCounters::AliCounter* counter = static_cast<AliHLTTriggerCounters::AliCounter*>(cntobj);
410 if (not counter->TestBit(BIT(14))) // Only update if marked as not updated.
412 counter->Increment();
413 counter->SetBit(BIT(14), true); // mark counter as incremented
416 static_cast<AliRingBuffer*>( fInputTimes.FindObject(decision->Name()) ),
423 HLTDebug("Adding new input counter \"%s\".", cntobj->GetName());
424 fInputCounters.Add(decision->Name(), "New trigger input counter found during the run.", 1, 1);
425 fInputCounters.GetCounterN(fInputCounters.NumberOfCounters()-1).SetBit(BIT(14), true); // mark counter as incremented
426 fInputTimes.Add(new AliRingBuffer(decision->Name(), inputTime));
429 obj = GetNextInputObject();
432 // Reset bit 14 which is used temporarily to mark incremented counters.
433 // Any counter which was not marked should have its rate updated.
434 for (UInt_t i = 0; i < fInputCounters.NumberOfCounters(); ++i)
436 AliHLTTriggerCounters::AliCounter* counter = &fInputCounters.GetCounterN(i);
437 if (not counter->TestBit(BIT(14)))
441 static_cast<AliRingBuffer*>( fInputTimes.FindObject(counter->Name()) ),
445 counter->SetBit(BIT(14), false);
447 for (UInt_t i = 0; i < fOutputCounters.NumberOfCounters(); ++i)
449 AliHLTTriggerCounters::AliCounter* counter = &fOutputCounters.GetCounterN(i);
450 if (not counter->TestBit(BIT(14)))
454 static_cast<AliRingBuffer*>( fOutputTimes.FindObject(counter->Name()) ),
458 counter->SetBit(BIT(14), false);
461 Double_t now = TTimeStamp();
462 if (fLastPublishTime == -1) fLastPublishTime = now;
463 if (now - fLastPublishTime > fPublishPeriod)
465 HLTDebug("Pushing back counter objects.");
466 fLastPublishTime = now;
467 bool inputCountersNotPushed = PushBack(&fInputCounters, kAliHLTDataTypeInputTriggerCounters) != 0;
468 bool outputCountersNotPushed = PushBack(&fOutputCounters, kAliHLTDataTypeOutputTriggerCounters) != 0;
469 if (inputCountersNotPushed or outputCountersNotPushed)
471 fOutputMultiplier = (fOutputMultiplier == 0 ? 1 : fOutputMultiplier*2);
479 void AliHLTTriggerCounterComponent::UpdateCounterRate(
480 AliHLTTriggerCounters::AliCounter* counter, AliRingBuffer* timeBuf, Double_t newTime
483 // Updates the counter's rate value.
485 assert(timeBuf != NULL);
486 Double_t dt = newTime - timeBuf->OldestTime();
487 Double_t rate = (dt != 0 ? (counter->Counter() - timeBuf->OldestCounter()) / dt : 0.);
489 timeBuf->Increment(counter->Counter(), newTime);
493 void AliHLTTriggerCounterComponent::UpdateCounterRate2(
494 AliHLTTriggerCounters::AliCounter* counter, AliRingBuffer* timeBuf, Double_t newTime
497 // Updates the counter's rate value when counter is not incremented.
499 assert(timeBuf != NULL);
500 Double_t dt = newTime - timeBuf->OldestTime();
501 Double_t rate = (dt != 0 ? (counter->Counter() - timeBuf->OldestCounter()) / dt : 0.);
503 timeBuf->Update(counter->Counter(), newTime);
507 int AliHLTTriggerCounterComponent::LoadConfigFromCDB(const char* cdbPath)
509 // Loads the initial configuration of counters from the given CDB path.
511 HLTDebug("Trying to load component configuration from '%s'.", cdbPath);
512 TObject* obj = LoadAndExtractOCDBObject(cdbPath);
515 HLTError("Configuration object for \"%s\" is missing.", cdbPath);
518 if (obj->IsA() != TMap::Class())
520 HLTError("Wrong type for configuration object in \"%s\". Found a %s but we expect a TMap.",
521 cdbPath, obj->ClassName()
525 TMap* counters = static_cast<TMap*>(obj);
526 SetInitialCounters(counters);
531 int AliHLTTriggerCounterComponent::LoadConfigFromFile(const char* configFile)
533 // Loads the initial configuration of counters from the given configuration file.
537 gROOT->ProcessLine(cmd);
538 SetInitialCounters(&fgInitialCounterConfig);
543 void AliHLTTriggerCounterComponent::SetInitialCounters(const TMap* counters)
545 // Sets the initial counter values from TMap objects containing name description pairs.
547 Double_t now = TTimeStamp();
548 TMapIter next(counters);
550 while ((key = next()) != NULL)
552 TObject* value = counters->GetValue(key);
553 if (value == NULL) continue;
554 Double_t maxIntegTime = fDefaultMaxIntegrationTime;
555 if (key->GetUniqueID() > 0) maxIntegTime = key->GetUniqueID() * 1e-6;
556 if (key->TestBit(BIT(14)))
558 fOutputCounters.Add(key->GetName(), value->GetName());
559 fOutputTimes.Add(new AliRingBuffer(key->GetName(), now, maxIntegTime));
563 fInputCounters.Add(key->GetName(), value->GetName());
564 fInputTimes.Add(new AliRingBuffer(key->GetName(), now, maxIntegTime));
570 void* AliHLTTriggerCounterComponent::AliRingBuffer::operator new (std::size_t size) throw (std::bad_alloc)
572 // New operator used to catch and log exceptions.
574 void* mem = malloc(size);
578 log.LoggingVarargs(kHLTLogFatal, Class_Name(), FUNCTIONNAME(), __FILE__, __LINE__,
579 "Could not allocate more space of %d bytes for the ring buffer.", size);
580 throw std::bad_alloc();
586 void AliHLTTriggerCounterComponent::AliRingBuffer::operator delete (void* mem) throw ()
588 // Symmetric delete operator to release memory.
594 void AliHLTTriggerCounterComponent::AliRingBuffer::Increment(ULong64_t newCounter, Double_t newTime)
596 // Inrements the buffer.
598 assert(fMaxIntegrationTime >= 0);
600 fCounterBuffer[fPos] = newCounter;
601 fTimeBuffer[fPos] = newTime;
602 fPos = (fPos+1) % kTimeStampEntries;
604 // We now need to replace all old values.
605 for (int i = 1; i < kTimeStampEntries; ++i)
607 if (newTime - fTimeBuffer[fPos] < fMaxIntegrationTime) break;
608 fCounterBuffer[fPos] = newCounter;
609 fTimeBuffer[fPos] = newTime;
610 fPos = (fPos+1) % kTimeStampEntries;
615 void AliHLTTriggerCounterComponent::AliRingBuffer::Update(ULong64_t currentCounter, Double_t newTime)
617 // Removes all old counter measurements.
619 assert(fMaxIntegrationTime >= 0);
620 for (int i = 0; i < kTimeStampEntries; ++i)
622 if (newTime - fTimeBuffer[fPos] < fMaxIntegrationTime) break;
623 fCounterBuffer[fPos] = currentCounter;
624 fTimeBuffer[fPos] = newTime;
625 fPos = (fPos+1) % kTimeStampEntries;