]>
Commit | Line | Data |
---|---|---|
742ae1c4 | 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. * | |
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 AliHLTTriggerCounterComponent.cxx | |
19 | /// @author Artur Szostak <artursz@iafrica.com> | |
20 | /// @date 3 Nov 2010 | |
21 | /// @brief Implementation of the AliHLTTriggerCounterComponent class. | |
22 | /// | |
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. | |
26 | ||
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" | |
36 | #include "TROOT.h" | |
37 | #include <cstring> | |
38 | #include <cassert> | |
39 | ||
40 | ClassImp(AliHLTTriggerCounterComponent) | |
41 | ||
42 | const char* AliHLTTriggerCounterComponent::fgkConfigCDBPath = "HLT/ConfigHLT/HLTTriggerCounter"; | |
43 | TMap AliHLTTriggerCounterComponent::fgInitialCounterConfig(TCollection::kInitHashTableCapacity, 2); | |
44 | ||
45 | ||
46 | AliHLTTriggerCounterComponent::AliHLTTriggerCounterComponent() : | |
47 | AliHLTProcessor(), | |
48 | fOutputMultiplier(0), | |
49 | fInputCounters(), | |
50 | fOutputCounters(), | |
51 | fInputTimes(TCollection::kInitHashTableCapacity, 2), | |
52 | fOutputTimes(TCollection::kInitHashTableCapacity, 2), | |
53 | fLastPublishTime(-1), | |
247b2cad | 54 | fPublishPeriod(-1), |
55 | fCountFalseInputs(false), | |
56 | fCountFalseOutputs(false) | |
742ae1c4 | 57 | { |
58 | // Default constructor. | |
59 | ||
60 | fInputTimes.SetOwner(kTRUE); | |
61 | fOutputTimes.SetOwner(kTRUE); | |
62 | } | |
63 | ||
64 | ||
65 | AliHLTTriggerCounterComponent::~AliHLTTriggerCounterComponent() | |
66 | { | |
67 | // Default destructor. | |
68 | ||
69 | } | |
70 | ||
71 | ||
72 | const char* AliHLTTriggerCounterComponent::GetComponentID() | |
73 | { | |
74 | // Returns the component ID. | |
75 | return "HLTTriggerCounter"; | |
76 | } | |
77 | ||
78 | ||
79 | void AliHLTTriggerCounterComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list) | |
80 | { | |
81 | // Returns the list of input data types that are handled. | |
82 | list.push_back(kAliHLTDataTypeGlobalTrigger); | |
83 | list.push_back(kAliHLTDataTypeTriggerDecision); | |
84 | } | |
85 | ||
86 | ||
87 | AliHLTComponentDataType AliHLTTriggerCounterComponent::GetOutputDataType() | |
88 | { | |
89 | // Returns kAliHLTMultipleDataType. | |
90 | return kAliHLTMultipleDataType; | |
91 | } | |
92 | ||
93 | ||
94 | int AliHLTTriggerCounterComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& list) | |
95 | { | |
96 | // Returns the list of output data block types generated. | |
97 | list.push_back(kAliHLTDataTypeInputTriggerCounters); | |
98 | list.push_back(kAliHLTDataTypeOutputTriggerCounters); | |
99 | return int(list.size()); | |
100 | } | |
101 | ||
102 | ||
103 | void AliHLTTriggerCounterComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier) | |
104 | { | |
105 | // Returns the buffer size requirements. | |
106 | constBase = 1024*16; | |
107 | inputMultiplier = fOutputMultiplier; | |
108 | } | |
109 | ||
110 | ||
111 | AliHLTComponent* AliHLTTriggerCounterComponent::Spawn() | |
112 | { | |
113 | // Creates a new instance of the component. | |
114 | return new AliHLTTriggerCounterComponent; | |
115 | } | |
116 | ||
117 | ||
118 | Int_t AliHLTTriggerCounterComponent::DoInit(int argc, const char** argv) | |
119 | { | |
120 | // Initialises the data checker component from the command line. | |
121 | ||
122 | HLTInfo("Starting HLT trigger counter component."); | |
123 | ||
124 | const char* configFileName = NULL; | |
125 | fInputCounters.Clear(); | |
126 | fOutputCounters.Clear(); | |
127 | fInputTimes.Clear(); | |
128 | fOutputTimes.Clear(); | |
129 | fLastPublishTime = -1; | |
130 | fPublishPeriod = -1; | |
247b2cad | 131 | fCountFalseInputs = false; |
132 | fCountFalseOutputs = false; | |
742ae1c4 | 133 | bool loadCDBObject = true; |
134 | ||
135 | for (int i = 0; i < argc; ++i) | |
136 | { | |
137 | if (strcmp(argv[i], "-config") == 0) | |
138 | { | |
139 | if (configFileName != NULL) | |
140 | { | |
141 | HLTWarning("The configuration macro was already specified." | |
142 | " Will replace previous value given by -config." | |
143 | ); | |
144 | } | |
145 | if (argc <= i+1) | |
146 | { | |
147 | HLTError("The configuration macro filename was not specified." ); | |
148 | return -EINVAL; | |
149 | } | |
150 | configFileName = argv[i+1]; | |
151 | i++; | |
152 | continue; | |
153 | } | |
154 | ||
155 | if (strcmp(argv[i], "-publishperiod") == 0) | |
156 | { | |
157 | if (fPublishPeriod != -1) | |
158 | { | |
159 | HLTWarning("The publish period was already specified." | |
160 | " Will replace previous value given by -publishperiod." | |
161 | ); | |
162 | } | |
163 | if (argc <= i+1) | |
164 | { | |
165 | HLTError("Publish period value was not specified for -publishperiod."); | |
166 | return -EINVAL; | |
167 | } | |
168 | char* err = NULL; | |
169 | errno = 0; | |
170 | double tmpnum = strtod(argv[i+1], &err); | |
171 | if (err == NULL or *err != '\0') | |
172 | { | |
173 | HLTError("Cannot convert '%s' to a floating point value.", argv[i+1]); | |
174 | return false; | |
175 | } | |
176 | if (errno == ERANGE) | |
177 | { | |
178 | HLTError("The specified value '%s' is out of range.", argv[i+1]); | |
179 | return false; | |
180 | } | |
181 | fPublishPeriod = (tmpnum < 0 ? -1 : tmpnum); | |
182 | i++; | |
183 | continue; | |
184 | } | |
185 | ||
186 | if (strcmp(argv[i], "-skipcdb") == 0) | |
187 | { | |
188 | loadCDBObject = false; | |
189 | continue; | |
190 | } | |
191 | ||
247b2cad | 192 | if (strcmp(argv[i], "-countfalseinputs") == 0) |
193 | { | |
194 | fCountFalseInputs = true; | |
195 | continue; | |
196 | } | |
197 | ||
198 | if (strcmp(argv[i], "-countfalseoutputs") == 0) | |
199 | { | |
200 | fCountFalseOutputs = true; | |
201 | continue; | |
202 | } | |
203 | ||
742ae1c4 | 204 | HLTError("Unknown option '%s'.", argv[i]); |
205 | return -EINVAL; | |
206 | } // for loop | |
207 | ||
208 | if (configFileName != NULL) | |
209 | { | |
210 | int result = LoadConfigFromFile(configFileName); | |
211 | if (result != 0) return result; | |
212 | } | |
213 | else if (loadCDBObject) | |
214 | { | |
215 | int result = LoadConfigFromCDB(fgkConfigCDBPath); | |
216 | if (result != 0) return result; | |
217 | } | |
218 | ||
219 | return 0; | |
220 | } | |
221 | ||
222 | ||
223 | Int_t AliHLTTriggerCounterComponent::DoDeinit() | |
224 | { | |
225 | // Cleans up the component. | |
226 | ||
227 | HLTInfo("Stopping HLT trigger counter component."); | |
228 | fInputCounters.Clear(); | |
229 | fOutputCounters.Clear(); | |
230 | fInputTimes.Clear(); | |
231 | fOutputTimes.Clear(); | |
232 | return 0; | |
233 | } | |
234 | ||
235 | ||
236 | int AliHLTTriggerCounterComponent::DoEvent(const AliHLTComponentEventData& /*evtData*/, AliHLTComponentTriggerData& /*trigData*/) | |
237 | { | |
238 | // Finds the global trigger objects and adds the triggers to the counters. | |
239 | ||
240 | fInputCounters.UpdateTimeStamp(); | |
241 | fOutputCounters.UpdateTimeStamp(); | |
242 | Double_t inputTime = fInputCounters.TimeStamp().AsDouble(); | |
243 | Double_t outputTime = fOutputCounters.TimeStamp().AsDouble(); | |
244 | ||
245 | const TObject* obj = GetFirstInputObject(kAliHLTDataTypeGlobalTrigger, "AliHLTGlobalTriggerDecision"); | |
246 | while (obj != NULL) | |
247 | { | |
247b2cad | 248 | HLTDebug("Received trigger decision object of type AliHLTGlobalTriggerDecision."); |
742ae1c4 | 249 | const AliHLTGlobalTriggerDecision* decision = dynamic_cast<const AliHLTGlobalTriggerDecision*>(obj); |
250 | if (decision != NULL) | |
251 | { | |
247b2cad | 252 | if ((not fCountFalseOutputs and decision->Result()) or fCountFalseOutputs) |
742ae1c4 | 253 | { |
247b2cad | 254 | // Tokenise the global trigger description string which contains a |
255 | // list of the triggers that were fired and increment the corresponding | |
256 | // counters. | |
257 | TString names = decision->Description(); | |
258 | Ssiz_t from = 0; | |
259 | TString token; | |
260 | while (names.Tokenize(token, from, ",")) | |
742ae1c4 | 261 | { |
247b2cad | 262 | TObject* cntobj = fOutputCounters.FindObject(token.Data()); |
263 | if (cntobj != NULL) | |
264 | { | |
265 | HLTDebug("Updating existing output counter \"%s\".", cntobj->GetName()); | |
266 | AliHLTTriggerCounters::AliCounter* counter = static_cast<AliHLTTriggerCounters::AliCounter*>(cntobj); | |
267 | counter->Increment(); | |
268 | UpdateCounterRate( | |
269 | counter, | |
270 | static_cast<AliRingBuffer*>( fOutputTimes.FindObject(token.Data()) ), | |
271 | outputTime | |
272 | ); | |
273 | } | |
274 | else | |
275 | { | |
276 | HLTDebug("Adding new output counter \"%s\".", cntobj->GetName()); | |
277 | fOutputCounters.Add(token.Data(), "New trigger output counter found during the run.", 1, 1); | |
278 | fOutputTimes.Add(new AliRingBuffer(token.Data(), outputTime)); | |
279 | } | |
742ae1c4 | 280 | } |
281 | } | |
282 | ||
283 | // Now add the CTP triggers. | |
284 | const AliHLTCTPData* ctp = dynamic_cast<const AliHLTCTPData*>( decision->InputObjects().FindObject("AliHLTCTPData") ); | |
285 | if (ctp != NULL) | |
286 | { | |
287 | const TArrayL64& counters = ctp->Counters(); | |
288 | for (Int_t i = 0; i < counters.GetSize(); ++i) | |
289 | { | |
290 | const char* ctpName = ctp->Name(i); | |
291 | // Check if CTP counter is initialised and skip if not. | |
292 | if (strcmp(ctpName, "AliHLTReadoutList") == 0 and counters[i] == 0) continue; | |
293 | TObject* cntobj = fInputCounters.FindObject(ctpName); | |
294 | if (cntobj != NULL) | |
295 | { | |
247b2cad | 296 | HLTDebug("Updating existing CTP counter \"%s\".", cntobj->GetName()); |
742ae1c4 | 297 | AliHLTTriggerCounters::AliCounter* counter = static_cast<AliHLTTriggerCounters::AliCounter*>(cntobj); |
298 | counter->Counter(counters[i]); | |
299 | UpdateCounterRate( | |
300 | counter, | |
301 | static_cast<AliRingBuffer*>( fInputTimes.FindObject(ctpName) ), | |
302 | inputTime | |
303 | ); | |
304 | } | |
305 | else | |
306 | { | |
247b2cad | 307 | HLTDebug("Adding new CTP counter \"%s\".", cntobj->GetName()); |
742ae1c4 | 308 | fInputCounters.Add( |
309 | ctpName, | |
310 | "New CTP trigger input counter found during the run.", | |
311 | Double_t(counters[i]), | |
312 | counters[i] | |
313 | ); | |
314 | fInputTimes.Add(new AliRingBuffer(ctpName, inputTime)); | |
315 | } | |
316 | } | |
317 | } | |
318 | ||
319 | // Add the list of input triggers. | |
320 | for (Int_t i = 0; i < decision->NumberOfTriggerInputs(); ++i) | |
321 | { | |
322 | const AliHLTTriggerDecision* input = decision->TriggerInput(i); | |
247b2cad | 323 | if (input == NULL) continue; |
324 | if (not fCountFalseInputs and not input->Result()) continue; | |
742ae1c4 | 325 | TObject* cntobj = fInputCounters.FindObject(input->Name()); |
326 | if (cntobj != NULL) | |
327 | { | |
247b2cad | 328 | HLTDebug("Updating existing input counter \"%s\".", cntobj->GetName()); |
742ae1c4 | 329 | AliHLTTriggerCounters::AliCounter* counter = static_cast<AliHLTTriggerCounters::AliCounter*>(cntobj); |
330 | counter->Increment(); | |
331 | counter->SetBit(BIT(14), true); // mark counter as updated | |
332 | UpdateCounterRate( | |
333 | counter, | |
334 | static_cast<AliRingBuffer*>( fInputTimes.FindObject(input->Name()) ), | |
335 | inputTime | |
336 | ); | |
337 | } | |
338 | else | |
339 | { | |
247b2cad | 340 | HLTDebug("Adding new input counter \"%s\".", cntobj->GetName()); |
742ae1c4 | 341 | fInputCounters.Add(input->Name(), "New trigger input counter found during the run.", 1, 1); |
342 | fInputCounters.GetCounterN(fInputCounters.NumberOfCounters()-1).SetBit(BIT(14), true); // mark counter as updated | |
343 | fInputTimes.Add(new AliRingBuffer(input->Name(), inputTime)); | |
344 | } | |
345 | } | |
346 | } | |
347 | obj = GetNextInputObject(); | |
348 | } | |
349 | ||
350 | // Look for the individual trigger decision blocks to add if they are available. | |
351 | obj = GetFirstInputObject(kAliHLTDataTypeTriggerDecision, "AliHLTTriggerDecision"); | |
352 | while (obj != NULL) | |
353 | { | |
247b2cad | 354 | HLTDebug("Received trigger decision object of type AliHLTTriggerDecision."); |
742ae1c4 | 355 | const AliHLTTriggerDecision* decision = dynamic_cast<const AliHLTTriggerDecision*>(obj); |
247b2cad | 356 | if (decision != NULL and ((not fCountFalseInputs and decision->Result()) or fCountFalseInputs)) |
742ae1c4 | 357 | { |
742ae1c4 | 358 | TObject* cntobj = fInputCounters.FindObject(decision->Name()); |
359 | if (cntobj != NULL) | |
360 | { | |
247b2cad | 361 | HLTDebug("Updating existing input counter \"%s\".", cntobj->GetName()); |
742ae1c4 | 362 | AliHLTTriggerCounters::AliCounter* counter = static_cast<AliHLTTriggerCounters::AliCounter*>(cntobj); |
363 | if (not counter->TestBit(BIT(14))) // Only update if marked as not updated. | |
364 | { | |
365 | counter->Increment(); | |
366 | UpdateCounterRate( | |
367 | counter, | |
368 | static_cast<AliRingBuffer*>( fInputTimes.FindObject(decision->Name()) ), | |
369 | inputTime | |
370 | ); | |
371 | } | |
372 | } | |
373 | else | |
374 | { | |
247b2cad | 375 | HLTDebug("Adding new input counter \"%s\".", cntobj->GetName()); |
742ae1c4 | 376 | fInputCounters.Add(decision->Name(), "New trigger input counter found during the run.", 1, 1); |
377 | fInputTimes.Add(new AliRingBuffer(decision->Name(), inputTime)); | |
378 | } | |
379 | } | |
380 | obj = GetNextInputObject(); | |
381 | } | |
382 | // Reset bit 14 which is used temporarily to mark updated counters. | |
383 | for (UInt_t i = 0; i < fInputCounters.NumberOfCounters(); ++i) | |
384 | { | |
385 | fInputCounters.GetCounterN(i).SetBit(BIT(14), false); | |
386 | } | |
387 | ||
388 | Double_t now = TTimeStamp(); | |
389 | if (fLastPublishTime == -1) fLastPublishTime = now; | |
390 | if (now - fLastPublishTime > fPublishPeriod) | |
391 | { | |
247b2cad | 392 | HLTDebug("Pushing back counter objects."); |
742ae1c4 | 393 | fLastPublishTime = now; |
394 | bool inputCountersNotPushed = PushBack(&fInputCounters, kAliHLTDataTypeInputTriggerCounters) != 0; | |
395 | bool outputCountersNotPushed = PushBack(&fOutputCounters, kAliHLTDataTypeOutputTriggerCounters) != 0; | |
396 | if (inputCountersNotPushed or outputCountersNotPushed) | |
397 | { | |
398 | fOutputMultiplier = (fOutputMultiplier == 0 ? 1 : fOutputMultiplier*2); | |
399 | return -ENOSPC; | |
400 | } | |
401 | } | |
402 | return 0; | |
403 | } | |
404 | ||
405 | ||
406 | void AliHLTTriggerCounterComponent::UpdateCounterRate( | |
407 | AliHLTTriggerCounters::AliCounter* counter, AliRingBuffer* timeBuf, Double_t newTime | |
408 | ) | |
409 | { | |
410 | // Updates the counter's rate value. | |
411 | ||
412 | assert(timeBuf != NULL); | |
413 | Double_t dt = newTime - timeBuf->OldestTime(); | |
414 | Double_t rate = (dt != 0 ? (counter->Counter() - timeBuf->OldestCounter()) / dt : 0.); | |
415 | counter->Rate(rate); | |
416 | timeBuf->Increment(counter->Counter(), newTime); | |
417 | } | |
418 | ||
419 | ||
420 | int AliHLTTriggerCounterComponent::LoadConfigFromCDB(const char* cdbPath) | |
421 | { | |
422 | // Loads the initial configuration of counters from the given CDB path. | |
423 | ||
424 | HLTDebug("Trying to load trigger menu from '%s'.", cdbPath); | |
425 | ||
426 | if (AliCDBManager::Instance() == NULL) | |
427 | { | |
428 | HLTError("CDB manager object not found."); | |
429 | return -EIO; | |
430 | } | |
431 | AliCDBStorage* store = AliCDBManager::Instance()->GetDefaultStorage(); | |
432 | if (store == NULL) | |
433 | { | |
434 | HLTError("Could not get the the default storage for the CDB."); | |
435 | return -EIO; | |
436 | } | |
437 | Int_t version = store->GetLatestVersion(cdbPath, GetRunNo()); | |
438 | if (version < 0) | |
439 | { | |
440 | HLTError("Could not find an entry in the CDB for \"%s\".", cdbPath); | |
441 | return -EIO; | |
442 | } | |
443 | Int_t subVersion = store->GetLatestSubVersion(cdbPath, GetRunNo(), version); | |
444 | AliCDBEntry* entry = AliCDBManager::Instance()->Get(cdbPath, GetRunNo(), version, subVersion); | |
445 | if (entry == NULL) | |
446 | { | |
447 | HLTError("Could not get the CDB entry for \"%s\".", cdbPath); | |
448 | return -EIO; | |
449 | } | |
450 | TObject* obj = entry->GetObject(); | |
451 | if (obj == NULL) | |
452 | { | |
453 | HLTError("Configuration object for \"%s\" is missing.", cdbPath); | |
454 | return -ENOENT; | |
455 | } | |
456 | if (obj->IsA() != TMap::Class()) | |
457 | { | |
458 | HLTError("Wrong type for configuration object in \"%s\". Found a %s but we expect a TMap.", | |
459 | cdbPath, obj->ClassName() | |
460 | ); | |
461 | return -EPROTO; | |
462 | } | |
463 | TMap* counters = static_cast<TMap*>(obj); | |
464 | SetInitialCounters(counters); | |
465 | return 0; | |
466 | } | |
467 | ||
468 | ||
469 | int AliHLTTriggerCounterComponent::LoadConfigFromFile(const char* configFile) | |
470 | { | |
471 | // Loads the initial configuration of counters from the given configuration file. | |
472 | ||
473 | TString cmd = ".x "; | |
474 | cmd += configFile; | |
475 | gROOT->ProcessLine(cmd); | |
476 | SetInitialCounters(&fgInitialCounterConfig); | |
477 | return 0; | |
478 | } | |
479 | ||
480 | ||
481 | void AliHLTTriggerCounterComponent::SetInitialCounters(const TMap* counters) | |
482 | { | |
483 | // Sets the initial counter values from TMap objects containing name description pairs. | |
484 | ||
485 | Double_t now = TTimeStamp(); | |
486 | TMapIter next(counters); | |
487 | TObject* key = NULL; | |
488 | while ((key = next()) != NULL) | |
489 | { | |
490 | TObject* value = counters->GetValue(key); | |
491 | if (value == NULL) continue; | |
492 | if (key->TestBit(BIT(14))) | |
493 | { | |
494 | fOutputCounters.Add(key->GetName(), value->GetName()); | |
495 | fOutputTimes.Add(new AliRingBuffer(key->GetName(), now)); | |
496 | } | |
497 | else | |
498 | { | |
499 | fInputCounters.Add(key->GetName(), value->GetName()); | |
500 | fInputTimes.Add(new AliRingBuffer(key->GetName(), now)); | |
501 | } | |
502 | } | |
503 | } |