]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/trigger/AliHLTGlobalTriggerComponent.cxx
Finished code for global HLT trigger and the trigger menu implementation.
[u/mrichter/AliRoot.git] / HLT / trigger / AliHLTGlobalTriggerComponent.cxx
CommitLineData
1b9a175e 1/**************************************************************************
2 * This file is property of and copyright by the ALICE HLT Project *
3 * ALICE Experiment at CERN, All rights reserved. *
4 * *
5 * Primary Authors: Artur Szostak <artursz@iafrica.com> *
6 * for The ALICE HLT Project. *
7 * *
8 * Permission to use, copy, modify and distribute this software and its *
9 * documentation strictly for non-commercial purposes is hereby granted *
10 * without fee, provided that the above copyright notice appears in all *
11 * copies and that both the copyright notice and this permission notice *
12 * appear in the supporting documentation. The authors make no claims *
13 * about the suitability of this software for any purpose. It is *
14 * provided "as is" without express or implied warranty. *
15 **************************************************************************/
16
17/// @file AliHLTGlobalTriggerComponent.cxx
18/// @author Artur Szostak <artursz@iafrica.com>
19/// @date 26 Nov 2008
20/// @brief Implementation of the AliHLTGlobalTriggerComponent component class.
21///
22/// The AliHLTGlobalTriggerComponentComponent class applies the global HLT trigger to all
23/// trigger information produced by components deriving from AliHLTTrigger.
24
25#include "AliHLTGlobalTriggerComponent.h"
e2bb8ddd 26#include "AliHLTGlobalTriggerDecision.h"
27#include "AliHLTGlobalTrigger.h"
52f67e50 28#include "AliHLTGlobalTriggerConfig.h"
29#include "AliHLTTriggerMenu.h"
e2bb8ddd 30#include "TUUID.h"
31#include "TROOT.h"
52f67e50 32#include "TRegexp.h"
33#include "TClonesArray.h"
34#include "TObjString.h"
e2bb8ddd 35#include "TSystem.h"
52f67e50 36#include "TInterpreter.h"
e2bb8ddd 37#include <fstream>
38#include <cerrno>
1b9a175e 39
40ClassImp(AliHLTGlobalTriggerComponent)
41
42
43AliHLTGlobalTriggerComponent::AliHLTGlobalTriggerComponent() :
e2bb8ddd 44 AliHLTTrigger(),
52f67e50 45 fTrigger(NULL),
46 fDebugMode(false)
1b9a175e 47{
48 // Default constructor.
49}
50
51
52AliHLTGlobalTriggerComponent::~AliHLTGlobalTriggerComponent()
53{
54 // Default destructor.
e2bb8ddd 55
56 if (fTrigger != NULL) delete fTrigger;
1b9a175e 57}
58
59
60void AliHLTGlobalTriggerComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier)
61{
62 // Returns the output data size estimate.
63
e2bb8ddd 64 constBase = sizeof(AliHLTGlobalTriggerDecision);
1b9a175e 65 inputMultiplier = 1;
66}
67
68
52f67e50 69Int_t AliHLTGlobalTriggerComponent::DoInit(int argc, const char** argv)
1b9a175e 70{
e2bb8ddd 71 // Initialises the global trigger component.
72
52f67e50 73 fDebugMode = false;
74 const char* configFileName = NULL;
75 const char* codeFileName = NULL;
e2bb8ddd 76 TString classname;
52f67e50 77 TClonesArray includePaths(TObjString::Class());
78 TClonesArray includeFiles(TObjString::Class());
79
80 for (int i = 0; i < argc; i++)
81 {
82 if (strcmp(argv[i], "-config") == 0)
83 {
84 if (configFileName != NULL)
85 {
86 HLTWarning("Trigger configuration macro was already specified."
87 " Will replace previous value given by -config."
88 );
89 }
90 if (argc <= i+1)
91 {
92 HLTError("The trigger configuration macro filename was not specified." );
93 return -EINVAL;
94 }
95 configFileName = argv[i+1];
96 i++;
97 continue;
98 }
99
100 if (strcmp(argv[i], "-includepath") == 0)
101 {
102 if (argc <= i+1)
103 {
104 HLTError("The include path was not specified." );
105 return -EINVAL;
106 }
107 new (includePaths[includePaths.GetEntriesFast()]) TObjString(argv[i+1]);
108 i++;
109 continue;
110 }
111
112 if (strcmp(argv[i], "-include") == 0)
113 {
114 if (argc <= i+1)
115 {
116 HLTError("The include file name was not specified." );
117 return -EINVAL;
118 }
119 new (includeFiles[includeFiles.GetEntriesFast()]) TObjString(argv[i+1]);
120 i++;
121 continue;
122 }
123
124 if (strcmp(argv[i], "-debug") == 0)
125 {
126 if (fDebugMode == true)
127 {
128 HLTWarning("The debug flag was already specified. Ignoring this instance.");
129 }
130 fDebugMode = true;
131 i++;
132 continue;
133 }
134
135 if (strcmp(argv[i], "-usecode") == 0)
136 {
137 if (codeFileName != NULL)
138 {
139 HLTWarning("Custom trigger code file was already specified."
140 " Will replace previous value given by -usecode."
141 );
142 }
143 if (argc <= i+1)
144 {
145 HLTError("The custom trigger code filename was not specified." );
146 return -EINVAL;
147 }
148 codeFileName = argv[i+1];
149 if (argc <= i+2)
150 {
151 HLTError("The custom trigger class name was not specified." );
152 return -EINVAL;
153 }
154 classname = argv[i+2];
155 i += 2;
156 continue;
157 }
158
159 HLTError("Unknown option '%s'.", argv[i]);
160 return -EINVAL;
161 } // for loop
162
163 const AliHLTTriggerMenu* menu = NULL;
164 if (configFileName != NULL)
165 {
166 TString cmd = ".x ";
167 cmd += configFileName;
168 gROOT->ProcessLine(cmd);
169 menu = AliHLTGlobalTriggerConfig::Menu();
170 }
171
172 if (menu == NULL)
173 {
174 HLTError("No trigger menu configuration found or specified.");
175 return -ENOENT;
176 }
177
178 int result = 0;
179 if (codeFileName == NULL)
180 {
181 HLTDebug("Generating custom HLT trigger class.");
182 result = GenerateTrigger(menu, classname, includePaths, includeFiles);
183 }
184 else
185 {
186 HLTDebug("Loading HLT trigger class from file '%s'.", codeFileName);
187 result = LoadTriggerClass(codeFileName, includePaths);
188 }
e2bb8ddd 189 if (result != 0) return result;
190
191 fTrigger = AliHLTGlobalTrigger::CreateNew(classname.Data());
192 if (fTrigger == NULL)
193 {
194 HLTError("Could not create a new instance of '%s'.", classname.Data());
195 return -EIO;
196 }
197
52f67e50 198 fTrigger->FillFromMenu(*menu);
199 fTrigger->ResetCounters(menu->NumberOfItems());
200
e2bb8ddd 201 return 0;
202}
203
1b9a175e 204
e2bb8ddd 205Int_t AliHLTGlobalTriggerComponent::DoDeinit()
206{
207 // Cleans up the global trigger component.
208
209 if (fTrigger != NULL)
210 {
211 delete fTrigger;
212 fTrigger = NULL;
213 }
214
1b9a175e 215 return 0;
216}
4f1d6b68 217
218
219AliHLTComponent* AliHLTGlobalTriggerComponent::Spawn()
220{
221 // Creates a new object instance.
222
223 return new AliHLTGlobalTriggerComponent;
224}
225
e2bb8ddd 226
227int AliHLTGlobalTriggerComponent::DoTrigger()
228{
229 // This method will apply the global trigger decision.
230
231 if (fTrigger == NULL)
232 {
233 HLTFatal("Global trigger implementation object is NULL!");
234 return -EIO;
235 }
236
237 fTrigger->NewEvent();
238
239 // Fill in the input data.
240 const TObject* obj = GetFirstInputObject();
241 while (obj != NULL)
52f67e50 242 {
243 fTrigger->Add(obj, GetDataType(), GetSpecification());
244 obj = GetNextInputObject();
245 }
246
247 // Calculate the global trigger result and trigger domain, then create and push
248 // back the new global trigger decision object.
249 TString description;
250 GetTriggerDomain().Clear();
251 bool triggerResult = fTrigger->CalculateTriggerDecision(GetTriggerDomain(), description);
252 SetDescription(description.Data());
253
254 AliHLTGlobalTriggerDecision decision(triggerResult, GetTriggerDomain(), GetDescription());
255 decision.SetCounters(fTrigger->Counters());
256
257 // Add the input objects used to the global decision.
258 obj = GetFirstInputObject();
259 while (obj != NULL)
e2bb8ddd 260 {
261 if (obj->IsA() == AliHLTTriggerDecision::Class())
262 {
52f67e50 263 decision.AddTriggerInput( *static_cast<const AliHLTTriggerDecision*>(obj) );
e2bb8ddd 264 }
265 else
266 {
52f67e50 267 decision.AddInputObject(obj);
e2bb8ddd 268 }
269 obj = GetNextInputObject();
270 }
52f67e50 271
272 TriggerEvent(&decision);
e2bb8ddd 273 return 0;
274}
275
276
52f67e50 277int AliHLTGlobalTriggerComponent::GenerateTrigger(
278 const AliHLTTriggerMenu* menu, TString& name,
279 const TClonesArray& includePaths, const TClonesArray& includeFiles
280 )
e2bb8ddd 281{
282 // Generates the global trigger class that will implement the specified trigger menu.
52f67e50 283 // See header for more details.
e2bb8ddd 284
285 // Create a new UUID and replace the '-' characters with '_' to make it a valid
286 // C++ symbol name.
287 TUUID uuid;
288 TString uuidstr = uuid.AsString();
289 for (Int_t i = 0; i < uuidstr.Length(); i++)
290 {
291 if (uuidstr[i] == '-') uuidstr[i] = '_';
292 }
293
294 // Create the name of the new class.
295 name = "AliHLTGlobalTriggerImpl_";
296 name += uuidstr;
297 TString filename = name + ".cxx";
298
52f67e50 299 // Open a text file to write the code and generate the new class.
e2bb8ddd 300 fstream code(filename.Data(), ios_base::out | ios_base::trunc);
301 if (not code.good())
302 {
303 HLTError("Could not open file '%s' for writing.", filename.Data());
304 return -EIO;
305 }
306
52f67e50 307 TClonesArray symbols(AliHLTTriggerMenuSymbol::Class());
308 int result = BuildSymbolList(menu, symbols);
309 if (result != 0) return result;
310
311 code << "#include <cstring>" << endl;
312 code << "#include \"TString.h\"" << endl;
313 code << "#include \"TClonesArray.h\"" << endl;
e2bb8ddd 314 code << "#include \"AliHLTGlobalTrigger.h\"" << endl;
315 code << "#include \"AliHLTGlobalTriggerDecision.h\"" << endl;
52f67e50 316 code << "#include \"AliHLTDomainEntry.h\"" << endl;
317 code << "#include \"AliHLTTriggerDomain.h\"" << endl;
318 code << "#include \"AliHLTReadoutList.h\"" << endl;
319 code << "#include \"AliHLTTriggerMenu.h\"" << endl;
320 code << "#include \"AliHLTTriggerMenuItem.h\"" << endl;
321 code << "#include \"AliHLTTriggerMenuSymbol.h\"" << endl;
322
323 // Add any include files that were specified on the command line.
324 for (Int_t i = 0; i < includeFiles.GetEntriesFast(); i++)
325 {
326 TString file = static_cast<const TObjString*>(includeFiles.UncheckedAt(i))->String();
327 code << "#include \"" << file.Data() << "\"" << endl;
328 }
329
e2bb8ddd 330 code << "class " << name << " : public AliHLTGlobalTrigger" << endl;
331 code << "{" << endl;
332 code << "public:" << endl;
52f67e50 333
334 code << " " << name << "() : AliHLTGlobalTrigger()";
335 // Write the symbols in the trigger menu in the initialisation list.
336 for (Int_t i = 0; i < symbols.GetEntriesFast(); i++)
337 {
338 code << "," << endl;
339 AliHLTTriggerMenuSymbol* symbol = static_cast<AliHLTTriggerMenuSymbol*>( symbols.UncheckedAt(i) );
340 code << " " << symbol->Name() << "()," << endl;
341 if (strcmp(symbol->ObjectClass(), "AliHLTTriggerDecision") == 0)
342 {
343 code << " " << symbol->Name() << "TriggerDomain()," << endl;
344 }
345 code << " " << symbol->Name() << "DomainEntry(kAliHLTAnyDataType)";
346 }
347 for (UInt_t i = 0; i < menu->NumberOfItems(); i++)
348 {
349 code << "," << endl << " fMenuItemDescription" << i << "()";
350 }
351 code << endl << " {" << endl;
352 if (fDebugMode)
353 {
354 code << " SetLocalLoggingLevel(kHLTLogAll);" << endl;
355 code << " HLTInfo(\"Creating new instance at %p.\", this);" << endl;
356 }
e2bb8ddd 357 code << " }" << endl;
52f67e50 358
e2bb8ddd 359 code << " virtual ~" << name << "() {" << endl;
52f67e50 360 if (fDebugMode)
361 {
362 code << " HLTInfo(\"Deleting instance at %p.\", this);" << endl;
363 }
e2bb8ddd 364 code << " }" << endl;
52f67e50 365
366 // Generate the FillFromMenu method.
367 code << " virtual void FillFromMenu(const AliHLTTriggerMenu& menu) {" << endl;
368 if (fDebugMode)
369 {
370 code << " HLTDebug(\"Filling description entries from trigger menu for global trigger %p.\", this);" << endl;
371 }
372 for (UInt_t i = 0; i < menu->NumberOfItems(); i++)
373 {
374 code << " fMenuItemDescription" << i << " = (menu.Item(" << i
375 << ") != NULL) ? menu.Item(" << i << ")->Description() : \"\";" << endl;
376 }
377 if (fDebugMode)
378 {
379 code << " HLTDebug(\"Finished filling description entries from trigger menu.\");" << endl;
380 code << " HLTDebug(\"Filling domain entries from trigger menu symbols for global trigger %p.\", this);" << endl;
381 }
382 code << " for (Int_t i = 0; i < menu.SymbolArray().GetEntriesFast(); i++) {" << endl;
383 code << " const AliHLTTriggerMenuSymbol* symbol = dynamic_cast<const"
384 " AliHLTTriggerMenuSymbol*>(menu.SymbolArray().UncheckedAt(i));" << endl;
385 code << " if (symbol == NULL) continue;" << endl;
386 for (Int_t i = 0; i < symbols.GetEntriesFast(); i++)
387 {
388 AliHLTTriggerMenuSymbol* symbol = static_cast<AliHLTTriggerMenuSymbol*>( symbols.UncheckedAt(i) );
389 code << " if (strcmp(symbol->Name(), \"" << symbol->Name() << "\") == 0) {" << endl;
390 if (fDebugMode)
391 {
392 code << " HLTDebug(\"Assinging domain entry value to match for symbol '%s' to '%s'.\","
393 " symbol->Name(), symbol->BlockType().AsString().Data());" << endl;
394 }
395 code << " " << symbol->Name() << "DomainEntry = symbol->BlockType();" << endl;
396 code << " continue;" << endl;
397 code << " }" << endl;
398 }
399 code << " }" << endl;
400 if (fDebugMode)
401 {
402 code << " HLTDebug(\"Finished filling domain entries from trigger menu symbols.\");" << endl;
403 }
e2bb8ddd 404 code << " }" << endl;
52f67e50 405
406 // Generate the NewEvent method.
407 code << " virtual void NewEvent() {" << endl;
408 if (fDebugMode)
409 {
410 code << " HLTDebug(\"New event for global trigger object %p, initialising variables to default values.\", this);" << endl;
411 }
412 // Write code to initialise the symbols in the trigger menu to their default values.
413 for (Int_t i = 0; i < symbols.GetEntriesFast(); i++)
414 {
415 AliHLTTriggerMenuSymbol* symbol = static_cast<AliHLTTriggerMenuSymbol*>( symbols.UncheckedAt(i) );
416 code << " " << symbol->Name() << " = " << symbol->DefaultValue() << ";" << endl;
417 if (strcmp(symbol->ObjectClass(), "AliHLTTriggerDecision") == 0)
418 {
419 code << " " << symbol->Name() << "TriggerDomain.Clear();" << endl;
420 }
421 }
422 if (fDebugMode)
423 {
424 code << " HLTDebug(\"Finished initialising variables.\");" << endl;
425 }
e2bb8ddd 426 code << " }" << endl;
52f67e50 427
428 // Generate the Add method.
429 code << " virtual void Add(const TObject* _object_, const AliHLTComponentDataType& _type_, AliHLTUInt32_t _spec_) {" << endl;
430 code << " AliHLTDomainEntry _type_spec_(_type_, _spec_);" << endl;
431 if (fDebugMode)
432 {
433 code << " HLTDebug(\"Adding TObject %p, with class name '%s' from data block"
434 " '%s', to global trigger object %p\", _object_, _object_->ClassName(),"
435 " _type_spec_.AsString().Data(), this);" << endl;
436 code << " _object_->Print();" << endl;
437 code << " bool _object_assigned_ = false;" << endl;
438 }
439 for (Int_t i = 0; i < symbols.GetEntriesFast(); i++)
440 {
441 // Write code to check if the block type, specification and class name is correct.
442 // Then write code to assign the variable from the input object.
443 AliHLTTriggerMenuSymbol* symbol = static_cast<AliHLTTriggerMenuSymbol*>( symbols.UncheckedAt(i) );
444 TString expr = symbol->AssignExpression();
445 if (expr == "") continue; // Skip entries that have no assignment expression.
446 bool isTrigDecision = strcmp(symbol->ObjectClass(), "AliHLTTriggerDecision") == 0;
447 if (fDebugMode)
448 {
449 if (isTrigDecision)
450 {
451 code << " HLTDebug(\"Trying to match input object to class '"
452 << symbol->ObjectClass() << "', trigger name '" << symbol->Name()
453 << "' and block type '%s'\", " << symbol->Name()
454 << "DomainEntry.AsString().Data());" << endl;
455 }
456 else
457 {
458 code << " HLTDebug(\"Trying to match input object to class '"
459 << symbol->ObjectClass() << "' and block type '%s'\", "
460 << symbol->Name() << "DomainEntry.AsString().Data());" << endl;
461 }
462 }
463 code << " const " << symbol->ObjectClass() << "* " << symbol->Name()
464 << "_object_ = dynamic_cast<const " << symbol->ObjectClass()
465 << "*>(_object_);" << endl;
466 code << " if (" << symbol->Name() << "_object_ != NULL and ";
467 if (isTrigDecision)
468 {
469 code << "strcmp(" << symbol->Name() << "_object_->Name(), \""
470 << symbol->Name() << "\") == 0 and ";
471 }
472 code << symbol->Name() << "DomainEntry == _type_spec_) {" << endl;
473 TString fullname = symbol->Name();
474 fullname += "_object_";
475 expr.ReplaceAll("this", fullname);
476 code << " this->" << symbol->Name() << " = " << expr.Data() << ";" << endl;
477 if (isTrigDecision)
478 {
479 code << " this->" << symbol->Name() << "TriggerDomain = "
480 << fullname.Data() << "->TriggerDomain();" << endl;
481 }
482 if (fDebugMode)
483 {
484 code << " HLTDebug(\"Added TObject %p with class name '%s' to variable "
485 << symbol->Name() << "\", _object_, _object_->ClassName());" << endl;
486 code << " _object_assigned_ = true;" << endl;
487 }
488 code << " }" << endl;
489 }
490 if (fDebugMode)
491 {
492 code << " if (not _object_assigned_) HLTDebug(\"Did not assign TObject %p"
493 " with class name '%s' to any variable.\", _object_, _object_->ClassName());"
494 << endl;
495 }
e2bb8ddd 496 code << " }" << endl;
52f67e50 497
498 // Generate the CalculateTriggerDecision method.
499 code << " virtual bool CalculateTriggerDecision(AliHLTTriggerDomain& _domain_, TString& _description_) {" << endl;
500 if (fDebugMode)
501 {
502 code << " HLTDebug(\"Calculating global HLT trigger result with trigger object at %p.\", this);" << endl;
503 }
504 for (UInt_t i = 0; i < menu->NumberOfItems(); i++)
505 {
506 const AliHLTTriggerMenuItem* item = menu->Item(i);
507 TString mergeExpr = item->MergeExpression();
508 for (Int_t j = 0; j < symbols.GetEntriesFast(); j++)
509 {
510 AliHLTTriggerMenuSymbol* symbol = static_cast<AliHLTTriggerMenuSymbol*>( symbols.UncheckedAt(j) );
511 if (strcmp(symbol->ObjectClass(), "AliHLTTriggerDecision") != 0) continue;
512 TString newname = symbol->Name();
513 newname += "TriggerDomain";
514 mergeExpr.ReplaceAll(symbol->Name(), newname);
515 }
516 if (fDebugMode)
517 {
518 code << " HLTDebug(\"Trying trigger condition " << i
519 << " (Description = '%s').\", fMenuItemDescription" << i << ".Data());"
520 << endl;
521 }
522 code << " if (" << item->TriggerCondision() << ") {" << endl;
523 code << " IncrementCounter(" << i << ");" << endl;
524 const char* indentation = "";
525 if (item->PreScalar() != 0)
526 {
527 indentation = " ";
528 code << " if ((GetCounter(" << i << ") % " << item->PreScalar() << ") == 1) {" << endl;
529 }
530 code << indentation << " _domain_ = " << mergeExpr.Data() << ";" << endl;
531 code << indentation << " _description_ = fMenuItemDescription" << i << ";" << endl;
532 if (fDebugMode)
533 {
534 code << indentation << " HLTDebug(\"Matched trigger condition " << i
535 << " (Description = '%s').\", fMenuItemDescription" << i << ".Data());" << endl;
536 }
537 code << indentation << " return true;" << endl;
538 if (item->PreScalar() != 0)
539 {
540 code << " }" << endl;
541 }
542 code << " }" << endl;
543 }
544 code << " return false;" << endl;
e2bb8ddd 545 code << " }" << endl;
52f67e50 546
547 // Generate the custom Factory class.
e2bb8ddd 548 code << " class FactoryImpl : public AliHLTGlobalTrigger::Factory" << endl;
549 code << " {" << endl;
550 code << " public:" << endl;
551 code << " virtual const char* ClassName() const {" << endl;
552 code << " return \"" << name << "\";" << endl;
553 code << " }" << endl;
554 code << " virtual AliHLTGlobalTrigger* New() const {" << endl;
555 code << " return new " << name << "();" << endl;
556 code << " }" << endl;
e2bb8ddd 557 code << " };" << endl;
52f67e50 558
e2bb8ddd 559 code << "private:" << endl;
52f67e50 560 // Add the symbols in the trigger menu to the list of private variables.
561 for (Int_t i = 0; i < symbols.GetEntriesFast(); i++)
562 {
563 AliHLTTriggerMenuSymbol* symbol = static_cast<AliHLTTriggerMenuSymbol*>( symbols.UncheckedAt(i) );
564 code << " " << symbol->Type() << " " << symbol->Name() << ";" << endl;
565 if (strcmp(symbol->ObjectClass(), "AliHLTTriggerDecision") == 0)
566 {
567 code << " AliHLTTriggerDomain " << symbol->Name() << "TriggerDomain;" << endl;
568 }
569 code << " AliHLTDomainEntry " << symbol->Name() << "DomainEntry;" << endl;
570 }
571 for (UInt_t i = 0; i < menu->NumberOfItems(); i++)
572 {
573 code << " TString fMenuItemDescription" << i << ";" << endl;
574 }
e2bb8ddd 575 code << "};" << endl;
e2bb8ddd 576
52f67e50 577 // Write a global object for the Factory class for automatic registration.
578 code << "namespace {" << endl;
579 code << " const " << name << "::FactoryImpl gkFactoryImpl;" << endl;
580 code << "};" << endl;
e2bb8ddd 581
582 code.close();
583
52f67e50 584 // Now we need to compile and load the new class.
585 result = LoadTriggerClass(filename, includePaths);
586 return result;
587}
588
589
590int AliHLTGlobalTriggerComponent::LoadTriggerClass(
591 const char* filename, const TClonesArray& includePaths
592 )
593{
594 // Loads the code for a custom global trigger class implementation on the fly.
595
596 TString compiler = gSystem->GetBuildCompilerVersion();
597 if (compiler.Contains("gcc") or compiler.Contains("icc"))
598 {
599 TString includePath = "-I${ALICE_ROOT}/include -I${ALICE_ROOT}/HLT/BASE -I${ALICE_ROOT}/HLT/trigger";
600 // Add any include paths that were specified on the command line.
601 for (Int_t i = 0; i < includePaths.GetEntriesFast(); i++)
602 {
603 TString path = static_cast<const TObjString*>(includePaths.UncheckedAt(i))->String();
604 includePath += " ";
605 includePath += path;
606 }
607 gSystem->SetIncludePath(includePath);
608 gSystem->SetFlagsOpt("-O3 -DNDEBUG");
609 gSystem->SetFlagsDebug("-g3 -DDEBUG -D__DEBUG");
610
611 int result = kTRUE;
612 if (fDebugMode)
613 {
614 result = gSystem->CompileMacro(filename, "g");
615 }
616 else
617 {
618 result = gSystem->CompileMacro(filename, "O");
619 }
620 if (result != kTRUE)
621 {
622 HLTFatal("Could not compile and load global trigger menu implementation.");
623 return -ENOENT;
624 }
625 }
626 else
627 {
628 // If we do not support the compiler then try interpret the class instead.
629 TString cmd = ".L ";
630 cmd += filename;
631 Int_t errorcode = TInterpreter::kNoError;
632 gROOT->ProcessLine(cmd, &errorcode);
633 if (errorcode != TInterpreter::kNoError)
634 {
635 HLTFatal("Could not load interpreted global trigger menu implementation"
636 " (Interpreter error code = %d).",
637 errorcode
638 );
639 return -ENOENT;
640 }
641 }
642
643 return 0;
644}
645
646
647int AliHLTGlobalTriggerComponent::FindSymbol(const char* name, const TClonesArray& list)
648{
649 // Searches for the named symbol in the given list.
650 // See header for more details.
651
652 for (int i = 0; i < list.GetEntriesFast(); i++)
653 {
654 const AliHLTTriggerMenuSymbol* symbol = dynamic_cast<const AliHLTTriggerMenuSymbol*>( list.UncheckedAt(i) );
655 if (symbol == NULL) continue;
656 if (strcmp(symbol->Name(), name) == 0) return i;
657 }
658 return -1;
659}
660
661
662int AliHLTGlobalTriggerComponent::BuildSymbolList(const AliHLTTriggerMenu* menu, TClonesArray& list)
663{
664 // Builds the list of symbols to use in the custom global trigger menu
665 // implementation class.
666 // See header for more details.
667
668 for (UInt_t i = 0; i < menu->NumberOfSymbols(); i++)
669 {
670 const AliHLTTriggerMenuSymbol* symbol = menu->Symbol(i);
671 if (FindSymbol(symbol->Name(), list) != -1)
672 {
673 HLTError("Multiple symbols with the name '%s' defined in the trigger menu.", symbol->Name());
674 return -EIO;
675 }
676 new (list[list.GetEntriesFast()]) AliHLTTriggerMenuSymbol(*symbol);
677 }
678
679 TRegexp exp("[_a-zA-Z][_a-zA-Z0-9]*");
680 for (UInt_t i = 0; i < menu->NumberOfItems(); i++)
681 {
682 const AliHLTTriggerMenuItem* item = menu->Item(i);
683 TString str = item->TriggerCondision();
684 Ssiz_t start = 0;
685 do
686 {
687 Ssiz_t length = 0;
688 Ssiz_t pos = exp.Index(str, &length, start);
689 if (pos == kNPOS) break;
690 TString s = str(pos, length);
691 start = pos+length;
692
693 if (s == "and" or s == "and_eq" or s == "bitand" or s == "bitor" or
694 s == "compl" or s == "not" or s == "not_eq" or s == "or" or
695 s == "or_eq" or s == "xor" or s == "xor_eq" or s == "true" or
696 s == "false"
697 )
698 {
699 // Ignore iso646.h and other keywords.
700 continue;
701 }
702
703 if (FindSymbol(s.Data(), list) == -1)
704 {
705 AliHLTTriggerMenuSymbol newSymbol;
706 newSymbol.Name(s.Data());
707 newSymbol.Type("bool");
708 newSymbol.ObjectClass("AliHLTTriggerDecision");
709 newSymbol.AssignExpression("this->Result()");
710 newSymbol.DefaultValue("false");
711 new (list[list.GetEntriesFast()]) AliHLTTriggerMenuSymbol(newSymbol);
712 }
713 }
714 while (start < str.Length());
715 }
716
e2bb8ddd 717 return 0;
718}
719