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