Protection against non-default geometry name. The name shouldn't change i nthe future...
[u/mrichter/AliRoot.git] / HLT / trigger / AliHLTGlobalTriggerComponent.cxx
CommitLineData
3da1c6d7 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 AliHLTGlobalTriggerComponent.cxx
19/// @author Artur Szostak <artursz@iafrica.com>
20/// @date 26 Nov 2008
21/// @brief Implementation of the AliHLTGlobalTriggerComponent component class.
22///
23/// The AliHLTGlobalTriggerComponentComponent class applies the global HLT trigger to all
24/// trigger information produced by components deriving from AliHLTTrigger.
25
26#include "AliHLTGlobalTriggerComponent.h"
e2bb8ddd 27#include "AliHLTGlobalTriggerDecision.h"
28#include "AliHLTGlobalTrigger.h"
52f67e50 29#include "AliHLTGlobalTriggerConfig.h"
30#include "AliHLTTriggerMenu.h"
474952b2 31#include "AliHLTCTPData.h"
3da1c6d7 32#include "AliCDBManager.h"
33#include "AliCDBStorage.h"
34#include "AliCDBEntry.h"
e2bb8ddd 35#include "TUUID.h"
36#include "TROOT.h"
72bc5ab0 37#include "TSystem.h"
52f67e50 38#include "TRegexp.h"
39#include "TClonesArray.h"
40#include "TObjString.h"
e2bb8ddd 41#include "TSystem.h"
52f67e50 42#include "TInterpreter.h"
d4ed5215 43#include "TDatime.h"
e2bb8ddd 44#include <fstream>
45#include <cerrno>
1b9a175e 46
47ClassImp(AliHLTGlobalTriggerComponent)
48
3da1c6d7 49const char* AliHLTGlobalTriggerComponent::fgkTriggerMenuCDBPath = "HLT/ConfigHLT/HLTGlobalTrigger";
50
1b9a175e 51
52AliHLTGlobalTriggerComponent::AliHLTGlobalTriggerComponent() :
e2bb8ddd 53 AliHLTTrigger(),
52f67e50 54 fTrigger(NULL),
72bc5ab0 55 fDebugMode(false),
56 fCodeFileName()
1b9a175e 57{
58 // Default constructor.
acc7214e 59
60 ClearInfoForNewEvent(false);
1b9a175e 61}
62
63
64AliHLTGlobalTriggerComponent::~AliHLTGlobalTriggerComponent()
65{
66 // Default destructor.
e2bb8ddd 67
68 if (fTrigger != NULL) delete fTrigger;
1b9a175e 69}
70
71
72void AliHLTGlobalTriggerComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier)
73{
74 // Returns the output data size estimate.
75
e2bb8ddd 76 constBase = sizeof(AliHLTGlobalTriggerDecision);
1b9a175e 77 inputMultiplier = 1;
78}
79
80
52f67e50 81Int_t AliHLTGlobalTriggerComponent::DoInit(int argc, const char** argv)
1b9a175e 82{
e2bb8ddd 83 // Initialises the global trigger component.
84
52f67e50 85 fDebugMode = false;
474952b2 86 bool bSkipCTPCounters=false;
52f67e50 87 const char* configFileName = NULL;
88 const char* codeFileName = NULL;
e2bb8ddd 89 TString classname;
52f67e50 90 TClonesArray includePaths(TObjString::Class());
91 TClonesArray includeFiles(TObjString::Class());
92
93 for (int i = 0; i < argc; i++)
94 {
95 if (strcmp(argv[i], "-config") == 0)
96 {
97 if (configFileName != NULL)
98 {
99 HLTWarning("Trigger configuration macro was already specified."
100 " Will replace previous value given by -config."
101 );
102 }
103 if (argc <= i+1)
104 {
105 HLTError("The trigger configuration macro filename was not specified." );
106 return -EINVAL;
107 }
108 configFileName = argv[i+1];
109 i++;
110 continue;
111 }
112
113 if (strcmp(argv[i], "-includepath") == 0)
114 {
115 if (argc <= i+1)
116 {
117 HLTError("The include path was not specified." );
118 return -EINVAL;
119 }
120 new (includePaths[includePaths.GetEntriesFast()]) TObjString(argv[i+1]);
121 i++;
122 continue;
123 }
124
125 if (strcmp(argv[i], "-include") == 0)
126 {
127 if (argc <= i+1)
128 {
129 HLTError("The include file name was not specified." );
130 return -EINVAL;
131 }
132 new (includeFiles[includeFiles.GetEntriesFast()]) TObjString(argv[i+1]);
133 i++;
134 continue;
135 }
136
137 if (strcmp(argv[i], "-debug") == 0)
138 {
139 if (fDebugMode == true)
140 {
141 HLTWarning("The debug flag was already specified. Ignoring this instance.");
142 }
143 fDebugMode = true;
144 i++;
145 continue;
146 }
147
148 if (strcmp(argv[i], "-usecode") == 0)
149 {
150 if (codeFileName != NULL)
151 {
152 HLTWarning("Custom trigger code file was already specified."
153 " Will replace previous value given by -usecode."
154 );
155 }
156 if (argc <= i+1)
157 {
158 HLTError("The custom trigger code filename was not specified." );
159 return -EINVAL;
160 }
161 codeFileName = argv[i+1];
162 if (argc <= i+2)
163 {
164 HLTError("The custom trigger class name was not specified." );
165 return -EINVAL;
166 }
167 classname = argv[i+2];
168 i += 2;
169 continue;
170 }
474952b2 171
172 if (strcmp(argv[i], "-skipctp") == 0)
173 {
174 HLTInfo("Skipping CTP counters in trigger decision");
175 bSkipCTPCounters=true;
176 continue;
177 }
178
52f67e50 179 HLTError("Unknown option '%s'.", argv[i]);
180 return -EINVAL;
181 } // for loop
182
183 const AliHLTTriggerMenu* menu = NULL;
184 if (configFileName != NULL)
185 {
186 TString cmd = ".x ";
187 cmd += configFileName;
188 gROOT->ProcessLine(cmd);
189 menu = AliHLTGlobalTriggerConfig::Menu();
190 }
191
3da1c6d7 192 // Try load the trigger menu from the CDB if it is not loaded yet with the
193 // -config option
194 if (menu == NULL and AliCDBManager::Instance() != NULL)
195 {
196 AliCDBStorage* store = AliCDBManager::Instance()->GetDefaultStorage();
197 if (store == NULL)
198 {
199 HLTError("Could not get the the default storage for the CDB.");
200 return -EIO;
201 }
202 Int_t version = store->GetLatestVersion(fgkTriggerMenuCDBPath, GetRunNo());
203 Int_t subVersion = store->GetLatestSubVersion(fgkTriggerMenuCDBPath, GetRunNo(), version);
204 AliCDBEntry* entry = AliCDBManager::Instance()->Get(fgkTriggerMenuCDBPath, GetRunNo(), version, subVersion);
205 if (entry == NULL)
206 {
207 HLTError("Could not get the CDB entry for \"%s\".", fgkTriggerMenuCDBPath);
208 return -EIO;
209 }
210 TObject* obj = entry->GetObject();
211 if (obj == NULL)
212 {
213 HLTError("Configuration object for \"%s\" is missing.", fgkTriggerMenuCDBPath);
214 return -ENOENT;
215 }
216 if (obj->IsA() != AliHLTTriggerMenu::Class())
217 {
218 HLTError("Wrong type for configuration object in \"%s\". Found a %s but we expect a AliHLTTriggerMenu.",
219 fgkTriggerMenuCDBPath, obj->ClassName()
220 );
221 return -EPROTO;
222 }
223 menu = dynamic_cast<AliHLTTriggerMenu*>(obj);
224 }
225
52f67e50 226 if (menu == NULL)
227 {
228 HLTError("No trigger menu configuration found or specified.");
229 return -ENOENT;
230 }
231
232 int result = 0;
233 if (codeFileName == NULL)
234 {
235 HLTDebug("Generating custom HLT trigger class.");
236 result = GenerateTrigger(menu, classname, includePaths, includeFiles);
237 }
238 else
239 {
240 HLTDebug("Loading HLT trigger class from file '%s'.", codeFileName);
241 result = LoadTriggerClass(codeFileName, includePaths);
242 }
e2bb8ddd 243 if (result != 0) return result;
244
245 fTrigger = AliHLTGlobalTrigger::CreateNew(classname.Data());
246 if (fTrigger == NULL)
247 {
248 HLTError("Could not create a new instance of '%s'.", classname.Data());
249 return -EIO;
250 }
251
52f67e50 252 fTrigger->FillFromMenu(*menu);
253 fTrigger->ResetCounters(menu->NumberOfItems());
474952b2 254
255 // setup the CTP accounting in AliHLTComponent
256 if (!bSkipCTPCounters) SetupCTPData();
257
acc7214e 258 // Set the default values from the trigger menu.
259 SetDescription(menu->DefaultDescription());
260 SetTriggerDomain(menu->DefaultTriggerDomain());
261
e2bb8ddd 262 return 0;
263}
264
1b9a175e 265
e2bb8ddd 266Int_t AliHLTGlobalTriggerComponent::DoDeinit()
267{
268 // Cleans up the global trigger component.
269
270 if (fTrigger != NULL)
271 {
272 delete fTrigger;
273 fTrigger = NULL;
274 }
72bc5ab0 275
d4ed5215 276 if (!fCodeFileName.IsNull() && gSystem->AccessPathName(fCodeFileName)==0 && !fDebugMode) {
277 fCodeFileName.ReplaceAll(".cxx", "*");
72bc5ab0 278 TString command="rm "; command+=fCodeFileName;
279 gSystem->Exec(command);
280 }
d4ed5215 281 fCodeFileName="";
e2bb8ddd 282
1b9a175e 283 return 0;
284}
4f1d6b68 285
286
287AliHLTComponent* AliHLTGlobalTriggerComponent::Spawn()
288{
289 // Creates a new object instance.
290
291 return new AliHLTGlobalTriggerComponent;
292}
293
e2bb8ddd 294
295int AliHLTGlobalTriggerComponent::DoTrigger()
296{
297 // This method will apply the global trigger decision.
298
299 if (fTrigger == NULL)
300 {
301 HLTFatal("Global trigger implementation object is NULL!");
302 return -EIO;
303 }
2974f8dc 304
305 AliHLTUInt32_t eventType=0;
306 if (!IsDataEvent(&eventType)) {
307 if (eventType==gkAliEventTypeEndOfRun) PrintStatistics(fTrigger, kHLTLogImportant, 0);
308 return 0;
309 }
310
e2bb8ddd 311 fTrigger->NewEvent();
312
313 // Fill in the input data.
314 const TObject* obj = GetFirstInputObject();
315 while (obj != NULL)
52f67e50 316 {
317 fTrigger->Add(obj, GetDataType(), GetSpecification());
318 obj = GetNextInputObject();
319 }
320
a489a8dd 321 // add trigger decisions for every CTP class
322 const AliHLTCTPData* pCTPData=CTPData();
323 if (pCTPData) {
324 fTrigger->AddCTPDecisions(pCTPData, GetTriggerData());
325 }
326
52f67e50 327 // Calculate the global trigger result and trigger domain, then create and push
328 // back the new global trigger decision object.
329 TString description;
acc7214e 330 AliHLTTriggerDomain triggerDomain;
331 bool triggerResult = fTrigger->CalculateTriggerDecision(triggerDomain, description);
52f67e50 332
acc7214e 333 AliHLTGlobalTriggerDecision decision(
334 triggerResult,
335 // The following will cause the decision to be generated with default values
336 // (set in fTriggerDomain and fDescription) if the trigger result is false.
337 (triggerResult == true) ? triggerDomain : GetTriggerDomain(),
338 (triggerResult == true) ? description.Data() : GetDescription()
339 );
48d98db9 340
341 // mask the readout list according to the CTP trigger
342 // if the classes have been initialized (mask non-zero)
48d98db9 343 if (pCTPData && pCTPData->Mask()) {
344 AliHLTEventDDL eventDDL=pCTPData->ReadoutList(*GetTriggerData());
345 AliHLTReadoutList ctpreadout(eventDDL);
45398383 346 ctpreadout.Enable(AliHLTReadoutList::kHLT);
347 AliHLTReadoutList maskedList=decision.ReadoutList();
348 maskedList.AndEq(ctpreadout);
349 decision.ReadoutList(maskedList);
48d98db9 350 }
351
68099920 352 const TArrayL64* counters=fTrigger->Counters();
353 if (counters) {
354 decision.SetCounters(*counters, GetEventCount()+1);
355 }
d4ed5215 356 static UInt_t lastTime=0;
357 TDatime time;
358 if (time.Get()-lastTime>5) {
359 lastTime=time.Get();
2974f8dc 360 PrintStatistics(fTrigger);
d4ed5215 361 }
52f67e50 362
363 // Add the input objects used to the global decision.
364 obj = GetFirstInputObject();
365 while (obj != NULL)
e2bb8ddd 366 {
367 if (obj->IsA() == AliHLTTriggerDecision::Class())
368 {
52f67e50 369 decision.AddTriggerInput( *static_cast<const AliHLTTriggerDecision*>(obj) );
e2bb8ddd 370 }
371 else
372 {
52f67e50 373 decision.AddInputObject(obj);
e2bb8ddd 374 }
375 obj = GetNextInputObject();
376 }
2974f8dc 377
474952b2 378 if (CTPData()) decision.AddInputObject(CTPData());
379
2974f8dc 380 CreateEventDoneReadoutFilter(decision.TriggerDomain(), 3);
381 CreateEventDoneReadoutFilter(decision.TriggerDomain(), 4);
52f67e50 382 TriggerEvent(&decision);
e2bb8ddd 383 return 0;
384}
385
386
52f67e50 387int AliHLTGlobalTriggerComponent::GenerateTrigger(
388 const AliHLTTriggerMenu* menu, TString& name,
389 const TClonesArray& includePaths, const TClonesArray& includeFiles
390 )
e2bb8ddd 391{
392 // Generates the global trigger class that will implement the specified trigger menu.
52f67e50 393 // See header for more details.
e2bb8ddd 394
395 // Create a new UUID and replace the '-' characters with '_' to make it a valid
396 // C++ symbol name.
397 TUUID uuid;
398 TString uuidstr = uuid.AsString();
399 for (Int_t i = 0; i < uuidstr.Length(); i++)
400 {
401 if (uuidstr[i] == '-') uuidstr[i] = '_';
402 }
403
404 // Create the name of the new class.
405 name = "AliHLTGlobalTriggerImpl_";
406 name += uuidstr;
72bc5ab0 407 fCodeFileName = name + ".cxx";
e2bb8ddd 408
52f67e50 409 // Open a text file to write the code and generate the new class.
72bc5ab0 410 fstream code(fCodeFileName.Data(), ios_base::out | ios_base::trunc);
e2bb8ddd 411 if (not code.good())
412 {
72bc5ab0 413 HLTError("Could not open file '%s' for writing.", fCodeFileName.Data());
e2bb8ddd 414 return -EIO;
415 }
416
52f67e50 417 TClonesArray symbols(AliHLTTriggerMenuSymbol::Class());
418 int result = BuildSymbolList(menu, symbols);
419 if (result != 0) return result;
420
421 code << "#include <cstring>" << endl;
422 code << "#include \"TString.h\"" << endl;
423 code << "#include \"TClonesArray.h\"" << endl;
e2bb8ddd 424 code << "#include \"AliHLTGlobalTrigger.h\"" << endl;
425 code << "#include \"AliHLTGlobalTriggerDecision.h\"" << endl;
52f67e50 426 code << "#include \"AliHLTDomainEntry.h\"" << endl;
427 code << "#include \"AliHLTTriggerDomain.h\"" << endl;
428 code << "#include \"AliHLTReadoutList.h\"" << endl;
429 code << "#include \"AliHLTTriggerMenu.h\"" << endl;
430 code << "#include \"AliHLTTriggerMenuItem.h\"" << endl;
431 code << "#include \"AliHLTTriggerMenuSymbol.h\"" << endl;
432
433 // Add any include files that were specified on the command line.
434 for (Int_t i = 0; i < includeFiles.GetEntriesFast(); i++)
435 {
7da191b6 436 TString file = static_cast<TObjString*>(includeFiles.UncheckedAt(i))->String();
52f67e50 437 code << "#include \"" << file.Data() << "\"" << endl;
438 }
439
e2bb8ddd 440 code << "class " << name << " : public AliHLTGlobalTrigger" << endl;
441 code << "{" << endl;
442 code << "public:" << endl;
52f67e50 443
444 code << " " << name << "() : AliHLTGlobalTrigger()";
445 // Write the symbols in the trigger menu in the initialisation list.
446 for (Int_t i = 0; i < symbols.GetEntriesFast(); i++)
447 {
448 code << "," << endl;
449 AliHLTTriggerMenuSymbol* symbol = static_cast<AliHLTTriggerMenuSymbol*>( symbols.UncheckedAt(i) );
450 code << " " << symbol->Name() << "()," << endl;
451 if (strcmp(symbol->ObjectClass(), "AliHLTTriggerDecision") == 0)
452 {
453 code << " " << symbol->Name() << "TriggerDomain()," << endl;
454 }
455 code << " " << symbol->Name() << "DomainEntry(kAliHLTAnyDataType)";
456 }
457 for (UInt_t i = 0; i < menu->NumberOfItems(); i++)
458 {
459 code << "," << endl << " fMenuItemDescription" << i << "()";
460 }
461 code << endl << " {" << endl;
462 if (fDebugMode)
463 {
464 code << " SetLocalLoggingLevel(kHLTLogAll);" << endl;
465 code << " HLTInfo(\"Creating new instance at %p.\", this);" << endl;
466 }
e2bb8ddd 467 code << " }" << endl;
52f67e50 468
e2bb8ddd 469 code << " virtual ~" << name << "() {" << endl;
52f67e50 470 if (fDebugMode)
471 {
472 code << " HLTInfo(\"Deleting instance at %p.\", this);" << endl;
473 }
e2bb8ddd 474 code << " }" << endl;
52f67e50 475
476 // Generate the FillFromMenu method.
477 code << " virtual void FillFromMenu(const AliHLTTriggerMenu& menu) {" << endl;
478 if (fDebugMode)
479 {
480 code << " HLTDebug(\"Filling description entries from trigger menu for global trigger %p.\", this);" << endl;
481 }
482 for (UInt_t i = 0; i < menu->NumberOfItems(); i++)
483 {
484 code << " fMenuItemDescription" << i << " = (menu.Item(" << i
485 << ") != NULL) ? menu.Item(" << i << ")->Description() : \"\";" << endl;
486 }
487 if (fDebugMode)
488 {
489 code << " HLTDebug(\"Finished filling description entries from trigger menu.\");" << endl;
490 code << " HLTDebug(\"Filling domain entries from trigger menu symbols for global trigger %p.\", this);" << endl;
491 }
492 code << " for (Int_t i = 0; i < menu.SymbolArray().GetEntriesFast(); i++) {" << endl;
493 code << " const AliHLTTriggerMenuSymbol* symbol = dynamic_cast<const"
494 " AliHLTTriggerMenuSymbol*>(menu.SymbolArray().UncheckedAt(i));" << endl;
495 code << " if (symbol == NULL) continue;" << endl;
496 for (Int_t i = 0; i < symbols.GetEntriesFast(); i++)
497 {
498 AliHLTTriggerMenuSymbol* symbol = static_cast<AliHLTTriggerMenuSymbol*>( symbols.UncheckedAt(i) );
499 code << " if (strcmp(symbol->Name(), \"" << symbol->Name() << "\") == 0) {" << endl;
500 if (fDebugMode)
501 {
502 code << " HLTDebug(\"Assinging domain entry value to match for symbol '%s' to '%s'.\","
503 " symbol->Name(), symbol->BlockType().AsString().Data());" << endl;
504 }
505 code << " " << symbol->Name() << "DomainEntry = symbol->BlockType();" << endl;
506 code << " continue;" << endl;
507 code << " }" << endl;
508 }
509 code << " }" << endl;
510 if (fDebugMode)
511 {
512 code << " HLTDebug(\"Finished filling domain entries from trigger menu symbols.\");" << endl;
513 }
e2bb8ddd 514 code << " }" << endl;
52f67e50 515
516 // Generate the NewEvent method.
517 code << " virtual void NewEvent() {" << endl;
518 if (fDebugMode)
519 {
520 code << " HLTDebug(\"New event for global trigger object %p, initialising variables to default values.\", this);" << endl;
521 }
522 // Write code to initialise the symbols in the trigger menu to their default values.
523 for (Int_t i = 0; i < symbols.GetEntriesFast(); i++)
524 {
525 AliHLTTriggerMenuSymbol* symbol = static_cast<AliHLTTriggerMenuSymbol*>( symbols.UncheckedAt(i) );
526 code << " " << symbol->Name() << " = " << symbol->DefaultValue() << ";" << endl;
527 if (strcmp(symbol->ObjectClass(), "AliHLTTriggerDecision") == 0)
528 {
529 code << " " << symbol->Name() << "TriggerDomain.Clear();" << endl;
530 }
531 }
532 if (fDebugMode)
533 {
534 code << " HLTDebug(\"Finished initialising variables.\");" << endl;
535 }
e2bb8ddd 536 code << " }" << endl;
52f67e50 537
538 // Generate the Add method.
539 code << " virtual void Add(const TObject* _object_, const AliHLTComponentDataType& _type_, AliHLTUInt32_t _spec_) {" << endl;
540 code << " AliHLTDomainEntry _type_spec_(_type_, _spec_);" << endl;
541 if (fDebugMode)
542 {
543 code << " HLTDebug(\"Adding TObject %p, with class name '%s' from data block"
544 " '%s', to global trigger object %p\", _object_, _object_->ClassName(),"
545 " _type_spec_.AsString().Data(), this);" << endl;
546 code << " _object_->Print();" << endl;
547 code << " bool _object_assigned_ = false;" << endl;
548 }
549 for (Int_t i = 0; i < symbols.GetEntriesFast(); i++)
550 {
551 // Write code to check if the block type, specification and class name is correct.
552 // Then write code to assign the variable from the input object.
553 AliHLTTriggerMenuSymbol* symbol = static_cast<AliHLTTriggerMenuSymbol*>( symbols.UncheckedAt(i) );
554 TString expr = symbol->AssignExpression();
555 if (expr == "") continue; // Skip entries that have no assignment expression.
556 bool isTrigDecision = strcmp(symbol->ObjectClass(), "AliHLTTriggerDecision") == 0;
557 if (fDebugMode)
558 {
559 if (isTrigDecision)
560 {
561 code << " HLTDebug(\"Trying to match input object to class '"
562 << symbol->ObjectClass() << "', trigger name '" << symbol->Name()
563 << "' and block type '%s'\", " << symbol->Name()
564 << "DomainEntry.AsString().Data());" << endl;
565 }
566 else
567 {
568 code << " HLTDebug(\"Trying to match input object to class '"
569 << symbol->ObjectClass() << "' and block type '%s'\", "
570 << symbol->Name() << "DomainEntry.AsString().Data());" << endl;
571 }
572 }
573 code << " const " << symbol->ObjectClass() << "* " << symbol->Name()
574 << "_object_ = dynamic_cast<const " << symbol->ObjectClass()
575 << "*>(_object_);" << endl;
576 code << " if (" << symbol->Name() << "_object_ != NULL and ";
577 if (isTrigDecision)
578 {
579 code << "strcmp(" << symbol->Name() << "_object_->Name(), \""
580 << symbol->Name() << "\") == 0 and ";
581 }
582 code << symbol->Name() << "DomainEntry == _type_spec_) {" << endl;
583 TString fullname = symbol->Name();
584 fullname += "_object_";
585 expr.ReplaceAll("this", fullname);
586 code << " this->" << symbol->Name() << " = " << expr.Data() << ";" << endl;
587 if (isTrigDecision)
588 {
589 code << " this->" << symbol->Name() << "TriggerDomain = "
590 << fullname.Data() << "->TriggerDomain();" << endl;
591 }
592 if (fDebugMode)
593 {
594 code << " HLTDebug(\"Added TObject %p with class name '%s' to variable "
595 << symbol->Name() << "\", _object_, _object_->ClassName());" << endl;
596 code << " _object_assigned_ = true;" << endl;
597 }
598 code << " }" << endl;
599 }
600 if (fDebugMode)
601 {
602 code << " if (not _object_assigned_) HLTDebug(\"Did not assign TObject %p"
603 " with class name '%s' to any variable.\", _object_, _object_->ClassName());"
604 << endl;
605 }
e2bb8ddd 606 code << " }" << endl;
52f67e50 607
608 // Generate the CalculateTriggerDecision method.
609 code << " virtual bool CalculateTriggerDecision(AliHLTTriggerDomain& _domain_, TString& _description_) {" << endl;
610 if (fDebugMode)
611 {
612 code << " HLTDebug(\"Calculating global HLT trigger result with trigger object at %p.\", this);" << endl;
613 }
614 for (UInt_t i = 0; i < menu->NumberOfItems(); i++)
615 {
616 const AliHLTTriggerMenuItem* item = menu->Item(i);
617 TString mergeExpr = item->MergeExpression();
618 for (Int_t j = 0; j < symbols.GetEntriesFast(); j++)
619 {
620 AliHLTTriggerMenuSymbol* symbol = static_cast<AliHLTTriggerMenuSymbol*>( symbols.UncheckedAt(j) );
621 if (strcmp(symbol->ObjectClass(), "AliHLTTriggerDecision") != 0) continue;
622 TString newname = symbol->Name();
623 newname += "TriggerDomain";
624 mergeExpr.ReplaceAll(symbol->Name(), newname);
625 }
626 if (fDebugMode)
627 {
628 code << " HLTDebug(\"Trying trigger condition " << i
629 << " (Description = '%s').\", fMenuItemDescription" << i << ".Data());"
630 << endl;
631 }
632 code << " if (" << item->TriggerCondision() << ") {" << endl;
633 code << " IncrementCounter(" << i << ");" << endl;
634 const char* indentation = "";
635 if (item->PreScalar() != 0)
636 {
637 indentation = " ";
638 code << " if ((GetCounter(" << i << ") % " << item->PreScalar() << ") == 1) {" << endl;
639 }
640 code << indentation << " _domain_ = " << mergeExpr.Data() << ";" << endl;
641 code << indentation << " _description_ = fMenuItemDescription" << i << ";" << endl;
642 if (fDebugMode)
643 {
644 code << indentation << " HLTDebug(\"Matched trigger condition " << i
645 << " (Description = '%s').\", fMenuItemDescription" << i << ".Data());" << endl;
646 }
647 code << indentation << " return true;" << endl;
648 if (item->PreScalar() != 0)
649 {
650 code << " }" << endl;
651 }
652 code << " }" << endl;
653 }
654 code << " return false;" << endl;
e2bb8ddd 655 code << " }" << endl;
52f67e50 656
657 // Generate the custom Factory class.
e2bb8ddd 658 code << " class FactoryImpl : public AliHLTGlobalTrigger::Factory" << endl;
659 code << " {" << endl;
660 code << " public:" << endl;
661 code << " virtual const char* ClassName() const {" << endl;
662 code << " return \"" << name << "\";" << endl;
663 code << " }" << endl;
664 code << " virtual AliHLTGlobalTrigger* New() const {" << endl;
665 code << " return new " << name << "();" << endl;
666 code << " }" << endl;
e2bb8ddd 667 code << " };" << endl;
52f67e50 668
e2bb8ddd 669 code << "private:" << endl;
52f67e50 670 // Add the symbols in the trigger menu to the list of private variables.
671 for (Int_t i = 0; i < symbols.GetEntriesFast(); i++)
672 {
673 AliHLTTriggerMenuSymbol* symbol = static_cast<AliHLTTriggerMenuSymbol*>( symbols.UncheckedAt(i) );
674 code << " " << symbol->Type() << " " << symbol->Name() << ";" << endl;
675 if (strcmp(symbol->ObjectClass(), "AliHLTTriggerDecision") == 0)
676 {
677 code << " AliHLTTriggerDomain " << symbol->Name() << "TriggerDomain;" << endl;
678 }
679 code << " AliHLTDomainEntry " << symbol->Name() << "DomainEntry;" << endl;
680 }
681 for (UInt_t i = 0; i < menu->NumberOfItems(); i++)
682 {
683 code << " TString fMenuItemDescription" << i << ";" << endl;
684 }
e2bb8ddd 685 code << "};" << endl;
e2bb8ddd 686
52f67e50 687 // Write a global object for the Factory class for automatic registration.
688 code << "namespace {" << endl;
689 code << " const " << name << "::FactoryImpl gkFactoryImpl;" << endl;
690 code << "};" << endl;
e2bb8ddd 691
692 code.close();
693
52f67e50 694 // Now we need to compile and load the new class.
72bc5ab0 695 result = LoadTriggerClass(fCodeFileName, includePaths);
52f67e50 696 return result;
697}
698
699
700int AliHLTGlobalTriggerComponent::LoadTriggerClass(
701 const char* filename, const TClonesArray& includePaths
702 )
703{
704 // Loads the code for a custom global trigger class implementation on the fly.
705
706 TString compiler = gSystem->GetBuildCompilerVersion();
707 if (compiler.Contains("gcc") or compiler.Contains("icc"))
708 {
bfe15056 709 TString includePath = "-I${ALIHLT_TOPDIR}/BASE -I${ALIHLT_TOPDIR}/trigger -I${ALICE_ROOT}/include -I${ALICE_ROOT}/HLT/BASE -I${ALICE_ROOT}/HLT/trigger";
52f67e50 710 // Add any include paths that were specified on the command line.
711 for (Int_t i = 0; i < includePaths.GetEntriesFast(); i++)
712 {
7da191b6 713 TString path = static_cast<TObjString*>(includePaths.UncheckedAt(i))->String();
52f67e50 714 includePath += " ";
715 includePath += path;
716 }
717 gSystem->SetIncludePath(includePath);
718 gSystem->SetFlagsOpt("-O3 -DNDEBUG");
719 gSystem->SetFlagsDebug("-g3 -DDEBUG -D__DEBUG");
720
721 int result = kTRUE;
722 if (fDebugMode)
723 {
724 result = gSystem->CompileMacro(filename, "g");
725 }
726 else
727 {
728 result = gSystem->CompileMacro(filename, "O");
729 }
730 if (result != kTRUE)
731 {
732 HLTFatal("Could not compile and load global trigger menu implementation.");
733 return -ENOENT;
734 }
735 }
736 else
737 {
738 // If we do not support the compiler then try interpret the class instead.
739 TString cmd = ".L ";
740 cmd += filename;
741 Int_t errorcode = TInterpreter::kNoError;
742 gROOT->ProcessLine(cmd, &errorcode);
743 if (errorcode != TInterpreter::kNoError)
744 {
745 HLTFatal("Could not load interpreted global trigger menu implementation"
746 " (Interpreter error code = %d).",
747 errorcode
748 );
749 return -ENOENT;
750 }
751 }
752
753 return 0;
754}
755
756
757int AliHLTGlobalTriggerComponent::FindSymbol(const char* name, const TClonesArray& list)
758{
759 // Searches for the named symbol in the given list.
760 // See header for more details.
761
762 for (int i = 0; i < list.GetEntriesFast(); i++)
763 {
764 const AliHLTTriggerMenuSymbol* symbol = dynamic_cast<const AliHLTTriggerMenuSymbol*>( list.UncheckedAt(i) );
765 if (symbol == NULL) continue;
766 if (strcmp(symbol->Name(), name) == 0) return i;
767 }
768 return -1;
769}
770
771
772int AliHLTGlobalTriggerComponent::BuildSymbolList(const AliHLTTriggerMenu* menu, TClonesArray& list)
773{
774 // Builds the list of symbols to use in the custom global trigger menu
775 // implementation class.
776 // See header for more details.
777
778 for (UInt_t i = 0; i < menu->NumberOfSymbols(); i++)
779 {
780 const AliHLTTriggerMenuSymbol* symbol = menu->Symbol(i);
781 if (FindSymbol(symbol->Name(), list) != -1)
782 {
783 HLTError("Multiple symbols with the name '%s' defined in the trigger menu.", symbol->Name());
784 return -EIO;
785 }
786 new (list[list.GetEntriesFast()]) AliHLTTriggerMenuSymbol(*symbol);
787 }
788
789 TRegexp exp("[_a-zA-Z][_a-zA-Z0-9]*");
3da1c6d7 790 TRegexp hexexp("x[a-fA-F0-9]+");
52f67e50 791 for (UInt_t i = 0; i < menu->NumberOfItems(); i++)
792 {
793 const AliHLTTriggerMenuItem* item = menu->Item(i);
794 TString str = item->TriggerCondision();
795 Ssiz_t start = 0;
796 do
797 {
798 Ssiz_t length = 0;
799 Ssiz_t pos = exp.Index(str, &length, start);
800 if (pos == kNPOS) break;
52f67e50 801 start = pos+length;
802
3da1c6d7 803 // Check if there is a numerical character before the found
804 // regular expression. If so, then the symbol is not a valid one
805 // and should be skipped.
806 if (pos > 0)
807 {
808 bool notValid = false;
809 switch (str[pos-1])
810 {
811 case '0': case '1': case '2': case '3': case '4':
812 case '5': case '6': case '7': case '8': case '9':
813 notValid = true;
814 break;
815 default:
816 notValid = false;
817 break;
818 }
819 if (notValid) continue;
820 }
821 TString s = str(pos, length);
822
52f67e50 823 if (s == "and" or s == "and_eq" or s == "bitand" or s == "bitor" or
824 s == "compl" or s == "not" or s == "not_eq" or s == "or" or
825 s == "or_eq" or s == "xor" or s == "xor_eq" or s == "true" or
826 s == "false"
827 )
828 {
829 // Ignore iso646.h and other keywords.
830 continue;
831 }
3da1c6d7 832
52f67e50 833 if (FindSymbol(s.Data(), list) == -1)
834 {
835 AliHLTTriggerMenuSymbol newSymbol;
836 newSymbol.Name(s.Data());
837 newSymbol.Type("bool");
838 newSymbol.ObjectClass("AliHLTTriggerDecision");
839 newSymbol.AssignExpression("this->Result()");
840 newSymbol.DefaultValue("false");
841 new (list[list.GetEntriesFast()]) AliHLTTriggerMenuSymbol(newSymbol);
842 }
843 }
844 while (start < str.Length());
845 }
846
e2bb8ddd 847 return 0;
848}
849
2974f8dc 850int AliHLTGlobalTriggerComponent::PrintStatistics(const AliHLTGlobalTrigger* pTrigger, AliHLTComponentLogSeverity level, int offset) const
851{
852 // print some statistics
853 ULong64_t count=0;
68099920 854 const TArrayL64* counters=pTrigger->Counters();
855 for (int i=0; counters!=NULL && i<counters->GetSize(); i++) {
856 count+=(*counters)[i];
2974f8dc 857 }
858 int totalEvents=GetEventCount()+offset;
859 float ratio=0;
860 if (totalEvents>0) ratio=100*(float)count/totalEvents;
861 HLTLog(level, "total events: %d - triggered events: %llu (%.1f%%)", totalEvents, count, ratio);
862 return 0;
863}