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