]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliTriggerConfiguration.cxx
- Modified the class AliMUONRecoParam to inherit from the new bass
[u/mrichter/AliRoot.git] / STEER / AliTriggerConfiguration.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 ///////////////////////////////////////////////////////////////////////////////
17 //
18 // This class which defines defines the Trigger Configuration 
19 //
20 // Trigger Configuration defines the trigger setup for a particular run
21 // We have default configurations for each running mode (Pb-Pb, p-p, p-A, Calibration, etc).
22 // It keep:
23 //   All the information conained in the CTP configuration file used
24 //   online during the data taking
25 //
26 // Configurations could be created and stored in local file.
27 // By default the configuration is loaded from the corresponding GRP entry
28 // inside the OCDB. There one can have one and only one configuration per run.
29 //
30 //   Example how to create a Trigger Configuration:
31 //
32 //   AliTriggerConfiguration config( "TEST", "Test Configuration" );
33 //
34 //   // Define a Cluster Detector
35 //   config.AddDetectorCluster( "VZERO ZDC MUON" );
36 //
37 //   // Define the trigger conditions (see AliTriggerCondition.cxx)
38 //   config.AddCondition( "VZERO_TEST1_L0 & MUON_SPlus_LPt_L0 & ZDC_TEST2_L0", // condition
39 //                         "VO1_M1_ZDC2",      // short name
40 //                         "Dummy",            // short description
41 //                          0x0100 );          // class mask (set one bit)
42 //
43 //   config.AddCondition( "VZERO_TEST2_L0 & MUON_SMinus_HPt_L0 & ZDC_TEST1_L0",
44 //                         "VO2_M3_ZDC1",
45 //                         "Dummy",
46 //                          0x0200 );
47 //
48 //   config.AddCondition( "VZERO_TEST3_L0 | MUON_Unlike_LPt_L0 | ZDC_TEST3_L0",
49 //                         "VO3_M1_ZDC3",
50 //                         "Dummy",
51 //                          0x0400 );
52 //   config.CheckInputsConditions("Config.C");
53 //   config.Print();
54 //
55 //   // save the configuration to file 
56 //   // (default file name $ALICE_ROOT/data/triggerConfigurations.root)
57 //   config.WriteConfiguration(); or config.WriteConfiguration( filename );
58 //
59 ///////////////////////////////////////////////////////////////////////////////
60 #include <Riostream.h>
61 #include <cstdlib>
62
63 #include <TObject.h>
64 #include <TString.h>
65 #include <TObjString.h>
66 #include <TObjArray.h>
67 #include <TSystem.h>
68 #include <TKey.h>
69 #include <TList.h>
70 #include <TMap.h>
71 #include <TFile.h>
72
73 #include "AliLog.h"
74 #include "AliRun.h"
75 #include "AliRunLoader.h"
76 #include "AliModule.h"
77
78 #include "AliTriggerInput.h"
79 //#include "AliTriggerDetector.h"
80 #include "AliTriggerInteraction.h"
81 #include "AliTriggerBCMask.h"
82 #include "AliTriggerCluster.h"
83 #include "AliTriggerPFProtection.h"
84 #include "AliTriggerDescriptor.h"
85 #include "AliTriggerClass.h"
86 #include "AliTriggerConfiguration.h"
87
88 ClassImp(AliTriggerConfiguration)
89
90 const TString AliTriggerConfiguration::fgkConfigurationFileName("/data/triggerConfigurations.root");
91
92 //_____________________________________________________________________________
93 AliTriggerConfiguration::AliTriggerConfiguration():
94   TNamed(),
95   fInputs(),
96   fInteractions(),
97   fFunctions(),
98   fPFProtections(),
99   fMasks(),
100   fDescriptors(),
101   fClusters(),
102   fClasses()
103 {
104   // Default constructor
105 }
106
107 //_____________________________________________________________________________
108 AliTriggerConfiguration::AliTriggerConfiguration( TString & name, TString & description ):
109   TNamed( name, description ),
110   fInputs(),
111   fInteractions(),
112   fFunctions(),
113   fPFProtections(),
114   fMasks(),
115   fDescriptors(),
116   fClusters(),
117   fClasses()
118 {
119   // Constructor
120 }
121
122 //_____________________________________________________________________________
123 AliTriggerConfiguration::~AliTriggerConfiguration() 
124
125   fInputs.SetOwner();
126   fInputs.Delete();
127   fInteractions.SetOwner();
128   fInteractions.Delete();
129   fFunctions.SetOwner();
130   fFunctions.Delete();
131   fPFProtections.SetOwner();
132   fPFProtections.Delete();
133   fMasks.SetOwner();
134   fMasks.Delete();
135   fDescriptors.SetOwner();
136   fDescriptors.Delete();
137   fClusters.SetOwner(); 
138   fClusters.Delete(); 
139   fClasses.SetOwner(); 
140   fClasses.Delete(); 
141 }
142
143 //_____________________________________________________________________________
144 Bool_t AliTriggerConfiguration::AddInput( AliTriggerInput* input )
145 {
146   if (fInputs.GetEntries() < kNMaxInputs) {
147     fInputs.AddLast( input );
148     return kTRUE;
149   }
150   else {
151     AliError("CTP can handle up to 50 inputs ! Impossible to add the required input !");
152     return kFALSE;
153   }
154 }
155
156 //_____________________________________________________________________________
157 AliTriggerInput* AliTriggerConfiguration::AddInput( TString &name, TString &det,
158                                                     UChar_t level, UInt_t signature,
159                                                     UChar_t number )
160 {
161   AliTriggerInput *input = new AliTriggerInput(name,det,level,signature,number);
162   if (!AddInput(input)) {
163     delete input;
164     return NULL;
165   }
166   else
167     return input;
168 }
169
170 //_____________________________________________________________________________
171 AliTriggerInteraction* AliTriggerConfiguration::AddInteraction(TString &name, TString &logic)
172 {
173   AliTriggerInteraction *interact = new AliTriggerInteraction(name,logic);
174   if (!AddInteraction(interact)) {
175     delete interact;
176     return NULL;
177   }
178   else
179     return interact;
180 }
181
182 //_____________________________________________________________________________
183 Bool_t  AliTriggerConfiguration::AddInteraction(AliTriggerInteraction *interact)
184 {
185   if (fInteractions.GetEntries() < kNMaxInteractions) {
186     if (interact->CheckInputs(fInputs)) {
187       fInteractions.AddLast( interact );
188       return kTRUE;
189     }
190     else
191       AliError("Invalid interaction ! Impossible to add it !");
192   }
193   else
194     AliError("CTP can handle up to 2 interactions ! Impossible to add the required interaction !");
195
196   return kFALSE;
197 }
198
199 //_____________________________________________________________________________
200 AliTriggerInteraction* AliTriggerConfiguration::AddFunction(TString &name, TString &logic)
201 {
202   AliTriggerInteraction *func = new AliTriggerInteraction(name,logic);
203   if (!AddFunction(func)) {
204     delete func;
205     return NULL;
206   }
207   else
208     return func;
209 }
210
211 //_____________________________________________________________________________
212 Bool_t  AliTriggerConfiguration::AddFunction(AliTriggerInteraction *func)
213 {
214   if (fFunctions.GetEntries() < kNMaxFunctions) {
215     if (func->CheckInputs(fInputs)) {
216       fFunctions.AddLast( func );
217       return kTRUE;
218     }
219     else
220       AliError("Invalid logical function ! Impossible to add it !");
221   }
222   else
223     AliError("CTP can handle up to 2 logical functions ! Impossible to add the required interaction !");
224
225   return kFALSE;
226 }
227
228 //_____________________________________________________________________________
229 Bool_t AliTriggerConfiguration::AddPFProtection( AliTriggerPFProtection* pfp )
230 {
231   if (fPFProtections.GetEntries() < kNMaxPFProtections) {
232     if (pfp->CheckInteractions(fInteractions)) {
233       fPFProtections.AddLast( pfp );
234       return kTRUE;
235     }
236     else
237       AliError("Invalid past-future protection ! Impossible to add it !");
238   }
239   else
240     AliError("CTP can handle up to 4 past-future protections ! Impossible to add the required protection !");
241
242   return kFALSE;
243 }
244
245 //_____________________________________________________________________________
246 AliTriggerBCMask* AliTriggerConfiguration::AddMask( TString &name, TString &mask )
247 {
248   AliTriggerBCMask *bcmask = new AliTriggerBCMask(name,mask);
249   if (!AddMask(bcmask)) {
250     delete bcmask;
251     return NULL;
252   }
253   else
254     return bcmask;
255 }
256
257 //_____________________________________________________________________________
258 Bool_t AliTriggerConfiguration::AddMask( AliTriggerBCMask* mask )
259 {
260   if (fMasks.GetEntries() < kNMaxMasks) {
261       fMasks.AddLast( mask );
262       return kTRUE;
263   }
264   else
265     AliError("CTP can handle up to 4 bunch-crossing masks ! Impossible to add the required mask !");
266
267   return kFALSE;
268 }
269
270 //_____________________________________________________________________________
271 AliTriggerCluster* AliTriggerConfiguration::AddCluster( TString &name, UChar_t index, TString &detectors)
272 {
273   AliTriggerCluster *clust = new AliTriggerCluster(name,index,detectors);
274   if (!AddCluster(clust)) {
275     delete clust;
276     return NULL;
277   }
278   else
279     return clust;
280
281 }
282
283 //_____________________________________________________________________________
284 Bool_t AliTriggerConfiguration::AddCluster( AliTriggerCluster* cluster )
285 {
286   if (fClusters.GetEntries() < kNMaxClusters) {
287     TString dets(cluster->GetDetectorsInCluster());
288     if (!(dets.IsNull())) {
289       fClusters.AddLast( cluster );
290       return kTRUE;
291     }
292     else
293       AliError("Empty trigger cluster ! Impossible to add it !");
294   }
295   else
296     AliError("CTP can handle up to 6 different detector clusters ! Impossible to add the required cluster !");
297
298   return kFALSE;
299 }
300
301 //_____________________________________________________________________________
302 TString AliTriggerConfiguration::GetActiveDetectors() const
303 {
304    // Return an string with all active detector from each cluster
305
306    TString activeDet = "";
307
308    Int_t nclus = fClusters.GetEntriesFast();
309    if( !nclus ) return activeDet;
310    
311    for( Int_t j=0; j<nclus; j++ ) {
312       TString detStr = ((AliTriggerCluster*)fClusters.At(j))->GetDetectorsInCluster();
313       TObjArray* det = detStr.Tokenize(" ");
314       Int_t ndet = det->GetEntriesFast();
315       for( Int_t j=0; j<ndet; j++ ) {
316          if( activeDet.Contains( ((TObjString*)det->At(j))->String() ) )continue;
317          activeDet.Append( " " );
318          activeDet.Append( ((TObjString*)det->At(j))->String() );
319       }
320    }
321    return activeDet;
322 }
323
324 //_____________________________________________________________________________
325 TString AliTriggerConfiguration::GetTriggeringDetectors() const
326 {
327    // Return an string with all detectors used for triggering
328
329    TString trDet = "";
330
331    Int_t ninputs = fInputs.GetEntriesFast();
332    if( !ninputs ) return trDet;
333    
334    for( Int_t j=0; j<ninputs; j++ ) {
335       TString detStr = ((AliTriggerInput*)fInputs.At(j))->GetDetector();
336       if( trDet.Contains( detStr ) ) continue;
337       trDet.Append( " " );
338       trDet.Append( detStr );
339    }
340    return trDet;
341 }
342
343 //_____________________________________________________________________________
344 TString AliTriggerConfiguration::GetTriggeringModules() const
345 {
346    // Return an string with all detectors (modules in the AliRoot
347   // simulation sense) used for triggering
348
349    TString trDet = "";
350
351    Int_t ninputs = fInputs.GetEntriesFast();
352    if( !ninputs ) return trDet;
353    
354    for( Int_t j=0; j<ninputs; j++ ) {
355       TString detStr = ((AliTriggerInput*)fInputs.At(j))->GetModule();
356       if( trDet.Contains( detStr ) ) continue;
357       trDet.Append( " " );
358       trDet.Append( detStr );
359    }
360    return trDet;
361 }
362
363 //_____________________________________________________________________________
364 AliTriggerDescriptor* AliTriggerConfiguration::AddDescriptor( TString &name, TString &cond )
365 {
366   AliTriggerDescriptor *desc = new AliTriggerDescriptor(name,cond);
367   if (!AddDescriptor(desc)) {
368     delete desc;
369     return NULL;
370   }
371   else
372     return desc;
373 }
374
375 //_____________________________________________________________________________
376 Bool_t AliTriggerConfiguration::AddDescriptor( AliTriggerDescriptor *desc )
377 {
378   if (fDescriptors.GetEntries() < kNMaxClasses) {
379     if (desc->CheckInputsAndFunctions(fInputs,fFunctions)) {
380       fDescriptors.AddLast( desc );
381       return kTRUE;
382     }
383     else
384       AliError("Invalid trigger desciptor ! Impossible to add it !");
385   }
386   else
387     AliError("CTP can handle up to 50 different descriptors ! Impossible to add the required descriptor !");
388
389   return kFALSE;
390 }
391
392 //_____________________________________________________________________________
393 Bool_t AliTriggerConfiguration::AddClass( AliTriggerClass *trclass )
394 {
395   if (fClasses.GetEntries() < kNMaxClasses) {
396     if (trclass->CheckClass(this)) {
397       fClasses.AddLast( trclass );
398       return kTRUE;
399     }
400     else
401       AliError("Invalid trigger class ! Impossible to add it !");
402   }
403   else
404     AliError("CTP can handle up to 50 different classes ! Impossible to add the required class !");
405
406   return kFALSE;
407 }
408
409 //_____________________________________________________________________________
410 AliTriggerClass *AliTriggerConfiguration::AddClass( TString &name, UChar_t index,
411                                                     AliTriggerDescriptor *desc, AliTriggerCluster *clus,
412                                                     AliTriggerPFProtection *pfp, AliTriggerBCMask *mask,
413                                                     UInt_t prescaler, Bool_t allrare)
414 {
415   // Add a new trigger class
416   if (!fDescriptors.FindObject(desc)) {
417     AliError("Invalid descriptor ! Impossible to add the class !");
418     return NULL;
419   }
420   if (!fClusters.FindObject(clus)) {
421     AliError("Invalid cluster ! Impossible to add the class !");
422     return NULL;
423   }
424   if (!fPFProtections.FindObject(pfp)) {
425     AliError("Invalid past-future protection ! Impossible to add the class !");
426     return NULL;
427   }
428   if (!fMasks.FindObject(mask)) {
429     AliError("Invalid bunch-crossing mask ! Impossible to add the class !");
430     return NULL;
431   }
432   AliTriggerClass* trclass = new AliTriggerClass( name,index,desc,clus,pfp,mask,prescaler,allrare );
433   if (!AddClass(trclass)) {
434     delete trclass;
435     return NULL;
436   }
437   else
438     return trclass;
439 }
440
441 //_____________________________________________________________________________
442 AliTriggerClass *AliTriggerConfiguration::AddClass( TString &name, UChar_t index,
443                                                     TString &desc, TString &clus,
444                                                     TString &pfp, TString &mask,
445                                                     UInt_t prescaler, Bool_t allrare)
446 {
447    // Add a new trigger class
448   if (!fDescriptors.FindObject(desc)) {
449     AliError("Invalid descriptor ! Impossible to add the class !");
450     return NULL;
451   }
452   if (!fClusters.FindObject(clus)) {
453     AliError("Invalid cluster ! Impossible to add the class !");
454     return NULL;
455   }
456   if (!fPFProtections.FindObject(pfp)) {
457     AliError("Invalid past-future protection ! Impossible to add the class !");
458     return NULL;
459   }
460   if (!fMasks.FindObject(mask)) {
461     AliError("Invalid bunch-crossing mask ! Impossible to add the class !");
462     return NULL;
463   }
464   AliTriggerClass* trclass = new AliTriggerClass( this, name,index,desc,clus,pfp,mask,prescaler,allrare );
465   if (!AddClass(trclass)) {
466     delete trclass;
467     return NULL;
468   }
469   else
470     return trclass;
471 }
472
473 //_____________________________________________________________________________
474 AliTriggerConfiguration* AliTriggerConfiguration::LoadConfiguration( TString & configuration)
475 {
476    // Load one pre-created Configurations from database/file that match
477    // with the input string 'configuration'
478    // Ej: "Pb-Pb" or "p-p-DIMUON CALIBRATION-CENTRAL-BARREL"
479   // By default the files are stored in GRP/CTP folder.
480   // The filename is constructed as: GRP/CTP/<configuration>.cfg
481
482    // Load the selected configuration
483    TString filename = gSystem->Getenv("ALICE_ROOT");
484    filename += "/GRP/CTP/";
485    filename += configuration;
486    filename += ".cfg";
487
488    if( gSystem->AccessPathName( filename.Data() ) ) {
489       AliErrorClass( Form( "file (%s) not found", filename.Data() ) );
490       return NULL;
491    }
492
493
494    ifstream *file = new ifstream ( filename.Data() );
495    if (!*file) {
496      AliErrorClass(Form("Error opening file (%s) !",filename.Data()));
497      file->close();
498      delete file;
499      return NULL;
500    }
501
502    AliTriggerConfiguration *cfg = new AliTriggerConfiguration();
503
504    Int_t level = 0;
505    TString strLine;
506    while (strLine.ReadLine(*file)) {
507      if (strLine.BeginsWith("#")) continue;
508      if (strLine.BeginsWith("INPUTS:")) {
509        level = 1;
510        continue;
511      }
512      if (strLine.BeginsWith("INTERACTIONS:")) {
513        level = 2;
514        continue;
515      }
516      if (strLine.BeginsWith("DESCRIPTORS:")) {
517        level = 3;
518        continue;
519      }
520      if (strLine.BeginsWith("CLUSTERS:")) {
521        level = 4;
522        continue;
523      }
524      if (strLine.BeginsWith("PFS:")) {
525        level = 5;
526        continue;
527      }
528      if (strLine.BeginsWith("BCMASKS:")) {
529        level = 6;
530        continue;
531      }
532      if (strLine.BeginsWith("CLASSES:")) {
533        level = 7;
534        continue;
535      }
536      strLine.ReplaceAll("*",'!');
537      TObjArray *tokens = strLine.Tokenize(" \t");
538      Int_t ntokens = tokens->GetEntriesFast();
539      switch (level) {
540      case 1:
541        // Read inputs
542        if (ntokens != 5) {
543          AliErrorClass(Form("Invalid trigger input syntax (%s)!",strLine.Data()));
544          file->close();
545          delete file;
546          return NULL;
547        }
548        cfg->AddInput(((TObjString*)tokens->At(0))->String(),
549                      ((TObjString*)tokens->At(1))->String(),
550                      ((TObjString*)tokens->At(2))->String().Atoi(),
551                      ((TObjString*)tokens->At(3))->String().Atoi(),
552                      ((TObjString*)tokens->At(4))->String().Atoi());
553        break;
554      case 2:
555        // Read intreractions
556        cfg->AddInteraction(((TObjString*)tokens->At(0))->String(),
557                            ((TObjString*)tokens->At(1))->String());
558        break;
559      case 3:
560        // Read logical functions and descriptors
561        if (((TObjString*)tokens->At(0))->String().BeginsWith("l0f")) {
562          // function
563          cfg->AddFunction(((TObjString*)tokens->At(0))->String(),
564                           strLine.ReplaceAll(((TObjString*)tokens->At(0))->String(),""));
565        }
566        else {
567          cfg->AddDescriptor(((TObjString*)tokens->At(0))->String(),
568                             strLine.ReplaceAll(((TObjString*)tokens->At(0))->String(),""));
569        }
570        break;
571      case 4:
572        {
573          TString strTemp;
574          for(Int_t i = 2; i < ntokens; i++) {
575            strTemp += ((TObjString*)tokens->At(i))->String();
576            strTemp += " ";
577          }
578          cfg->AddCluster(((TObjString*)tokens->At(0))->String(),
579                          ((TObjString*)tokens->At(1))->String().Atoi(),
580                          strTemp);
581        }
582        break;
583      case 5:
584        {
585          AliTriggerPFProtection *pfp = NULL;
586          if (((TObjString*)tokens->At(0))->String().CompareTo("NONE") == 0) {
587            pfp = new AliTriggerPFProtection(((TObjString*)tokens->At(0))->String());
588          }
589          else {
590            pfp = new AliTriggerPFProtection(((TObjString*)tokens->At(0))->String(),
591                                             ((TObjString*)tokens->At(1))->String(),
592                                             ((TObjString*)tokens->At(2))->String(),
593                                             ((TObjString*)tokens->At(3))->String());
594            pfp->SetNa1(((TObjString*)tokens->At(4))->String().Atoi());
595            pfp->SetNa2(((TObjString*)tokens->At(5))->String().Atoi());
596            pfp->SetNb1(((TObjString*)tokens->At(6))->String().Atoi());
597            pfp->SetNb2(((TObjString*)tokens->At(7))->String().Atoi());
598            pfp->SetTa(((TObjString*)tokens->At(8))->String().Atoi());
599            pfp->SetTb(((TObjString*)tokens->At(9))->String().Atoi());
600          }
601          cfg->AddPFProtection(pfp);
602        }
603        break;
604      case 6:
605        if (((TObjString*)tokens->At(0))->String().CompareTo("NONE") == 0)
606          cfg->AddMask(new AliTriggerBCMask(((TObjString*)tokens->At(0))->String()));
607        else {
608          cfg->AddMask(((TObjString*)tokens->At(0))->String(),
609                       ((TObjString*)tokens->At(1))->String());
610        }
611        break;
612      case 7:
613        {
614          AliTriggerClass *trclass = new AliTriggerClass(cfg,
615                                                         ((TObjString*)tokens->At(0))->String(),((TObjString*)tokens->At(1))->String().Atoi(),
616                                                         ((TObjString*)tokens->At(2))->String(),((TObjString*)tokens->At(3))->String(),
617                                                         ((TObjString*)tokens->At(4))->String(),((TObjString*)tokens->At(5))->String(),
618                                                         ((TObjString*)tokens->At(6))->String().Atoi(),(Bool_t)(((TObjString*)tokens->At(0))->String().Atoi()));
619          cfg->AddClass(trclass);
620        }
621      default:
622        break;
623      }
624      delete tokens;
625    }
626
627    file->close();
628    delete file;
629
630    return cfg;
631
632 }
633
634 //_____________________________________________________________________________
635 TObjArray* AliTriggerConfiguration::GetAvailableConfigurations( const char* filename )
636 {
637    // Return an array of configuration in the file
638
639    TString path;
640    if( !filename[0] ) {
641       path += gSystem->Getenv( "ALICE_ROOT" );
642       path += fgkConfigurationFileName;
643    }
644    else
645       path += filename;
646
647    if( gSystem->AccessPathName( path.Data() ) ) {
648       AliErrorGeneral( "AliTriggerConfiguration", Form( "file (%s) not found", path.Data() ) );
649       return NULL;
650    }
651
652    TObjArray* desArray = new TObjArray();
653
654    TFile file( path.Data(), "READ" );
655    if( file.IsZombie() ) {
656       AliErrorGeneral( "AliTriggerConfiguration", Form( "Error opening file (%s)", path.Data() ) );
657       return NULL;
658    }
659
660    file.ReadAll();
661
662    TKey* key;
663    TIter next( file.GetListOfKeys() );
664    while( (key = (TKey*)next()) ) {
665       TObject* obj = key->ReadObj();
666       if( obj->InheritsFrom( "AliTriggerConfiguration" ) ) {
667          desArray->AddLast( obj );
668       }
669    }
670    file.Close();
671
672    return desArray;
673 }
674
675 //_____________________________________________________________________________
676 void AliTriggerConfiguration::WriteConfiguration( const char* filename )
677 {
678    // Write the configuration
679    TString path;
680    if( !filename[0] ) {
681       path += gSystem->Getenv("ALICE_ROOT");
682       path += fgkConfigurationFileName;
683    }
684    else
685       path += filename;
686
687    TFile file( path.Data(), "UPDATE" );
688    if( file.IsZombie() ) {
689       AliErrorGeneral( "AliTriggerConfiguration", 
690                         Form( "Can't open file (%s)", path.Data() ) );
691       return;
692    }
693
694    Bool_t result = (Write( GetName(), TObject::kOverwrite ) != 0);
695    if( !result )
696       AliErrorGeneral( "AliTriggerConfiguration",
697                         Form( "Can't write entry to file <%s>!", path.Data() ) );
698    file.Close();
699 }
700
701 //_____________________________________________________________________________
702 Bool_t AliTriggerConfiguration::CheckConfiguration( TString& configfile )
703 {
704    // To be used on the pre-creation of Configurations to check if the
705    // conditions have valid inputs names.
706    //
707    // Initiate detectors modules from a Config file
708    // Ask to each active module present in the fDetectorCluster
709    // to create a Trigger detector and retrive the inputs from it
710    // to create a list of inputs.
711    // Each condition in the configuration is then checked agains 
712    // the list of inputs
713
714
715    if (!gAlice) {
716       AliError( "no gAlice object. Restart aliroot and try again." );
717       return kFALSE;
718    }
719    if (gAlice->Modules()->GetEntries() > 0) {
720       AliError( "gAlice was already run. Restart aliroot and try again." );
721       return kFALSE;
722    }
723
724    AliInfo( Form( "initializing gAlice with config file %s",
725             configfile.Data() ) );
726    StdoutToAliInfo( StderrToAliError(
727       gAlice->Init( configfile.Data() );
728    ););
729
730    AliRunLoader* runLoader = gAlice->GetRunLoader();
731    if( !runLoader ) {
732       AliError( Form( "gAlice has no run loader object. "
733                       "Check your config file: %s", configfile.Data() ) );
734       return kFALSE;
735    }
736
737    // get the possible inputs to check the condition
738    TObjArray inputs;
739    TObjArray* detArray = runLoader->GetAliRun()->Detectors();
740
741    TString detStr = GetTriggeringModules();
742
743    for( Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++ ) {
744       AliModule* det = (AliModule*) detArray->At(iDet);
745       if( !det || !det->IsActive() ) continue;
746       if( IsSelected( det->GetName(), detStr ) ) {
747          AliInfo( Form( "Creating inputs for %s", det->GetName() ) );
748          AliTriggerDetector* dtrg = det->CreateTriggerDetector();
749          dtrg->CreateInputs(GetInputs());
750          TObjArray* detInp = dtrg->GetInputs();
751          for( Int_t i=0; i<detInp->GetEntriesFast(); i++ ) {
752             AliInfo( Form( "Adding input %s", ((AliTriggerInput*)detInp->At(i))->GetName() ) );
753             inputs.AddLast( detInp->At(i) );
754          }
755       }
756    }
757
758    // check if the condition is compatible with the triggers inputs
759    Int_t ndesc = fClasses.GetEntriesFast();
760    Bool_t check = kTRUE;
761    ULong64_t mask = 0L;
762    for( Int_t j=0; j<ndesc; j++ ) {
763      AliTriggerClass *trclass = (AliTriggerClass*)fClasses.At( j );
764      if( !(trclass->CheckClass( this )) ) check = kFALSE;
765      else {
766        if (trclass->IsActive(this->GetInputs(),this->GetFunctions())) {
767          AliInfo( Form( "Trigger Class (%s) OK, class mask (0x%Lx)",
768                         trclass->GetName(), trclass->GetMask( ) ) );
769        }
770        else {
771          AliWarning( Form( "Trigger Class (%s) is NOT active, class mask (0x%Lx)",
772                            trclass->GetName(), trclass->GetMask( ) ) );
773        }
774      }
775      // check if condition mask is duplicated
776      if( mask & trclass->GetMask() ) {
777        AliError( Form("Class (%s). The class mask (0x%Lx) is ambiguous. It was already defined",
778                       trclass->GetName(), trclass->GetMask()  ) );
779        check = kFALSE;
780      }
781      mask |= trclass->GetMask();
782    }
783
784    return check;
785 }
786
787
788 //_____________________________________________________________________________
789 void AliTriggerConfiguration::Print( const Option_t*  ) const
790 {
791    // Print
792   cout << "#################################################" << endl;
793    cout << "Trigger Configuration:"  << endl;
794    cout << "  Name:              " << GetName() << endl; 
795    cout << "  Description:       " << GetTitle() << endl;
796    cout << "  Active Detectors:  " << GetActiveDetectors() << endl;
797    cout << "  Trigger Detectors: " << GetTriggeringDetectors() << endl;
798
799    cout << "#################################################" << endl;
800    fInputs.Print();
801    cout << "#################################################" << endl;
802    fInteractions.Print();
803    cout << "#################################################" << endl;
804    fFunctions.Print();
805    cout << "#################################################" << endl;
806    fDescriptors.Print();
807    cout << "#################################################" << endl;
808    fClusters.Print();
809    cout << "#################################################" << endl;
810    fPFProtections.Print();
811    cout << "#################################################" << endl;
812    fMasks.Print();
813    cout << "#################################################" << endl;
814    fClasses.Print();
815    cout << "#################################################" << endl;
816
817    cout << endl;
818 }
819
820
821 //////////////////////////////////////////////////////////////////////////////
822 // Helper method
823
824 //_____________________________________________________________________________
825 Bool_t AliTriggerConfiguration::IsSelected( TString detName, TString& detectors ) const
826 {
827    // check whether detName is contained in detectors
828    // if yes, it is removed from detectors
829
830    // check if all detectors are selected
831    if( (detectors.CompareTo("ALL") == 0 ) ||
832         detectors.BeginsWith("ALL ") ||
833         detectors.EndsWith(" ALL") ||
834         detectors.Contains(" ALL ") ) {
835       detectors = "ALL";
836       return kTRUE;
837    }
838
839    // search for the given detector
840    Bool_t result = kFALSE;
841    if( (detectors.CompareTo( detName ) == 0) ||
842         detectors.BeginsWith( detName+" " ) ||
843         detectors.EndsWith( " "+detName ) ||
844         detectors.Contains( " "+detName+" " ) ) {
845       detectors.ReplaceAll( detName, "" );
846       result = kTRUE;
847    }
848
849    // clean up the detectors string
850    while( detectors.Contains("  ") )  detectors.ReplaceAll( "  ", " " );
851    while( detectors.BeginsWith(" ") ) detectors.Remove( 0, 1 );
852    while( detectors.EndsWith(" ") )   detectors.Remove( detectors.Length()-1, 1 );
853
854    return result;
855 }