605bcf6c4fbe3e89cc9d05cd6f4379895fd0d5ce
[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
62 #include <TCint.h>
63 #include <TFile.h>
64 #include <TKey.h>
65 #include <TObjArray.h>
66 #include <TObjString.h>
67 #include <TObject.h>
68 #include <TROOT.h>
69 #include <TString.h>
70 #include <TSystem.h>
71
72 #include "AliCDBManager.h"
73 #include "AliLog.h"
74 #include "AliMC.h"
75 #include "AliModule.h"
76 #include "AliPDG.h"
77 #include "AliRun.h"
78 #include "AliRunLoader.h"
79 #include "AliTriggerBCMask.h"
80 #include "AliTriggerClass.h"
81 #include "AliTriggerCluster.h"
82 #include "AliTriggerConfiguration.h"
83 #include "AliTriggerDescriptor.h"
84 #include "AliTriggerInput.h"
85 #include "AliTriggerInteraction.h"
86 #include "AliTriggerPFProtection.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   fVersion(0)
104 {
105   // Default constructor
106 }
107
108 //_____________________________________________________________________________
109 AliTriggerConfiguration::AliTriggerConfiguration( TString & name, TString & description ):
110   TNamed( name, description ),
111   fInputs(),
112   fInteractions(),
113   fFunctions(),
114   fPFProtections(),
115   fMasks(),
116   fDescriptors(),
117   fClusters(),
118   fClasses(),
119   fVersion(0)
120 {
121   // Constructor
122 }
123
124 //_____________________________________________________________________________
125 AliTriggerConfiguration::~AliTriggerConfiguration() 
126
127   // Destructor
128   fInputs.SetOwner();
129   fInputs.Delete();
130   fInteractions.SetOwner();
131   fInteractions.Delete();
132   fFunctions.SetOwner();
133   fFunctions.Delete();
134   fPFProtections.SetOwner();
135   fPFProtections.Delete();
136   fMasks.SetOwner();
137   fMasks.Delete();
138   fDescriptors.SetOwner();
139   fDescriptors.Delete();
140   fClusters.SetOwner(); 
141   fClusters.Delete(); 
142   fClasses.SetOwner(); 
143   fClasses.Delete(); 
144 }
145
146 //_____________________________________________________________________________
147 Bool_t AliTriggerConfiguration::AddInput( AliTriggerInput* input )
148 {
149   // Add a trigger input to
150   // the list of the trigger inputs
151   if (fInputs.GetEntries() < kNMaxInputs) {
152     fInputs.AddLast( input );
153     return kTRUE;
154   }
155   else {
156     AliError("CTP can handle up to 60 inputs ! Impossible to add the required input !");
157     return kFALSE;
158   }
159 }
160
161 //_____________________________________________________________________________
162 AliTriggerInput* AliTriggerConfiguration::AddInput( TString &name, TString &det,
163                                                     UChar_t level, UInt_t signature,
164                                                     UChar_t number )
165 {
166   // Add a trigger input to
167   // the list of the trigger inputs
168   AliTriggerInput *input = new AliTriggerInput(name,det,level,signature,number);
169   if (!AddInput(input)) {
170     delete input;
171     return NULL;
172   }
173   else
174     return input;
175 }
176
177 //_____________________________________________________________________________
178 AliTriggerInteraction* AliTriggerConfiguration::AddInteraction(TString &name, TString &logic)
179 {
180   // Add a trigger interaction object to
181   // the list of the trigger interactions
182   AliTriggerInteraction *interact = new AliTriggerInteraction(name,logic);
183   if (!AddInteraction(interact)) {
184     delete interact;
185     return NULL;
186   }
187   else
188     return interact;
189 }
190
191 //_____________________________________________________________________________
192 Bool_t  AliTriggerConfiguration::AddInteraction(AliTriggerInteraction *interact)
193 {
194   // Add a trigger interaction object to
195   // the list of the trigger interactions
196   if (fInteractions.GetEntries() < kNMaxInteractions) {
197     if (interact->CheckInputs(fInputs)) {
198       fInteractions.AddLast( interact );
199       return kTRUE;
200     }
201     else
202       AliError("Invalid interaction ! Impossible to add it !");
203   }
204   else
205     AliError("CTP can handle up to 2 interactions ! Impossible to add the required interaction !");
206
207   return kFALSE;
208 }
209
210 //_____________________________________________________________________________
211 AliTriggerInteraction* AliTriggerConfiguration::AddFunction(TString &name, TString &logic)
212 {
213   // Add a trigger function object to
214   // the list of the trigger functions
215   AliTriggerInteraction *func = new AliTriggerInteraction(name,logic);
216   if (!AddFunction(func)) {
217     delete func;
218     return NULL;
219   }
220   else
221     return func;
222 }
223
224 //_____________________________________________________________________________
225 Bool_t  AliTriggerConfiguration::AddFunction(AliTriggerInteraction *func)
226 {
227   // Add a trigger function object to
228   // the list of the trigger functions
229   if (fFunctions.GetEntries() < kNMaxFunctions) {
230     if (func->CheckInputs(fInputs)) {
231       fFunctions.AddLast( func );
232       return kTRUE;
233     }
234     else
235       AliError("Invalid logical function ! Impossible to add it !");
236   }
237   else
238     AliError("CTP can handle up to 2 logical functions ! Impossible to add the required interaction !");
239
240   return kFALSE;
241 }
242
243 //_____________________________________________________________________________
244 Bool_t AliTriggerConfiguration::AddPFProtection( AliTriggerPFProtection* pfp )
245 {
246   // Add a trigger past-future protection object to
247   // the list of the trigger past-future protections
248   if (fPFProtections.GetEntries() < kNMaxPFProtections) {
249     if (pfp->CheckInteractions(fInteractions)) {
250       fPFProtections.AddLast( pfp );
251       return kTRUE;
252     }
253     else
254       AliError("Invalid past-future protection ! Impossible to add it !");
255   }
256   else
257     AliError("CTP can handle up to 4 past-future protections ! Impossible to add the required protection !");
258
259   return kFALSE;
260 }
261
262 //_____________________________________________________________________________
263 AliTriggerBCMask* AliTriggerConfiguration::AddMask( TString &name, TString &mask )
264 {
265   // Add a trigger bunch-crossing mask object to
266   // the list of the trigger bunch-crossing masks
267   AliTriggerBCMask *bcmask = new AliTriggerBCMask(name,mask);
268   if (!AddMask(bcmask)) {
269     delete bcmask;
270     return NULL;
271   }
272   else
273     return bcmask;
274 }
275
276 //_____________________________________________________________________________
277 Bool_t AliTriggerConfiguration::AddMask( AliTriggerBCMask* mask )
278 {
279   // Add a trigger bunch-crossing mask object to
280   // the list of the trigger bunch-crossing masks
281   if (fMasks.GetEntries() < (kNMaxMasks+1)) {  //+1 to account for NONE
282       fMasks.AddLast( mask );
283       return kTRUE;
284   }
285   else
286     AliError("CTP can handle up to 4 bunch-crossing masks ! Impossible to add the required mask !");
287
288   return kFALSE;
289 }
290
291 //_____________________________________________________________________________
292 AliTriggerCluster* AliTriggerConfiguration::AddCluster( TString &name, UChar_t index, TString &detectors)
293 {
294   // Add a trigger detector readout cluster to
295   // the list of the trigger clusters
296   AliTriggerCluster *clust = new AliTriggerCluster(name,index,detectors);
297   if (!AddCluster(clust)) {
298     delete clust;
299     return NULL;
300   }
301   else
302     return clust;
303
304 }
305
306 //_____________________________________________________________________________
307 Bool_t AliTriggerConfiguration::AddCluster( AliTriggerCluster* cluster )
308 {
309   // Add a trigger detector readout cluster to
310   // the list of the trigger clusters
311   if (fClusters.GetEntries() < kNMaxClusters) {
312     TString dets(cluster->GetDetectorsInCluster());
313     if (!(dets.IsNull())) {
314       fClusters.AddLast( cluster );
315       return kTRUE;
316     }
317     else
318       AliError("Empty trigger cluster ! Impossible to add it !");
319   }
320   else
321     AliError("CTP can handle up to 6 different detector clusters ! Impossible to add the required cluster !");
322
323   return kFALSE;
324 }
325
326 //_____________________________________________________________________________
327 TString AliTriggerConfiguration::GetActiveDetectors() const
328 {
329   // Return an string with all active detector
330   // from each cluster
331
332    TString activeDet = "";
333
334    Int_t nclus = fClusters.GetEntriesFast();
335    if( !nclus ) return activeDet;
336    
337    for( Int_t j=0; j<nclus; ++j ) {
338       TString detStr = ((AliTriggerCluster*)fClusters.At(j))->GetDetectorsInCluster();
339       TObjArray* det = detStr.Tokenize(" ");
340       Int_t ndet = det->GetEntriesFast();
341       for( Int_t k=0; k<ndet; ++k ) {
342          if( activeDet.Contains( ((TObjString*)det->At(k))->String() ) )continue;
343          activeDet.Append( " " );
344          activeDet.Append( ((TObjString*)det->At(k))->String() );
345       }
346    }
347    return activeDet;
348 }
349
350 //_____________________________________________________________________________
351 TString AliTriggerConfiguration::GetTriggeringDetectors() const
352 {
353   // Return an string with all detectors
354   // used for triggering
355
356    TString trDet = "";
357
358    Int_t ninputs = fInputs.GetEntriesFast();
359    if( !ninputs ) return trDet;
360    
361    for( Int_t j=0; j<ninputs; j++ ) {
362       TString detStr = ((AliTriggerInput*)fInputs.At(j))->GetDetector();
363       if( trDet.Contains( detStr ) ) continue;
364       trDet.Append( " " );
365       trDet.Append( detStr );
366    }
367    return trDet;
368 }
369
370 //_____________________________________________________________________________
371 TString AliTriggerConfiguration::GetTriggeringModules() const
372 {
373    // Return an string with all detectors (modules in the AliRoot
374   // simulation sense) used for triggering
375
376    TString trDet = "";
377
378    Int_t ninputs = fInputs.GetEntriesFast();
379    if( !ninputs ) return trDet;
380    
381    for( Int_t j=0; j<ninputs; j++ ) {
382       TString detStr = ((AliTriggerInput*)fInputs.At(j))->GetModule();
383       if( trDet.Contains( detStr ) ) continue;
384       trDet.Append( " " );
385       trDet.Append( detStr );
386    }
387    return trDet;
388 }
389
390 //_____________________________________________________________________________
391 AliTriggerDescriptor* AliTriggerConfiguration::AddDescriptor( TString &name, TString &cond )
392 {
393   // Add a trigger descriptor to
394   // the list of the trigger descriptors
395   AliTriggerDescriptor *desc = new AliTriggerDescriptor(name,cond);
396   if (!AddDescriptor(desc)) {
397     delete desc;
398     return NULL;
399   }
400   else
401     return desc;
402 }
403
404 //_____________________________________________________________________________
405 Bool_t AliTriggerConfiguration::AddDescriptor( AliTriggerDescriptor *desc )
406 {
407   // Add a trigger descriptor to
408   // the list of the trigger descriptors
409   if (fDescriptors.GetEntries() < kNMaxClasses) {
410     if (desc->CheckInputsAndFunctions(fInputs,fFunctions)) {
411       fDescriptors.AddLast( desc );
412       return kTRUE;
413     }
414     else
415       AliError("Invalid trigger desciptor ! Impossible to add it !");
416   }
417   else
418     AliError("CTP can handle up to 50 different descriptors ! Impossible to add the required descriptor !");
419
420   return kFALSE;
421 }
422
423 //_____________________________________________________________________________
424 Bool_t AliTriggerConfiguration::AddClass( AliTriggerClass *trclass )
425 {
426   // Add a trigger class to
427   // the list of the trigger classes
428   if (fClasses.GetEntries() < kNMaxClasses) {
429     if (trclass->CheckClass(this)) {
430       fClasses.AddLast( trclass );
431       return kTRUE;
432     }
433     else
434       AliError("Invalid trigger class ! Impossible to add it !");
435   }
436   else
437     AliError("CTP can handle up to 50 different classes ! Impossible to add the required class !");
438
439   return kFALSE;
440 }
441
442 //_____________________________________________________________________________
443 AliTriggerClass *AliTriggerConfiguration::AddClass( TString &name, UChar_t index,
444                                                     AliTriggerDescriptor *desc, AliTriggerCluster *clus,
445                                                     AliTriggerPFProtection *pfp, AliTriggerBCMask *mask,
446                                                     UInt_t prescaler, Bool_t allrare)
447 {
448   // Add a trigger class to
449   // the list of the trigger classes
450   if (!fDescriptors.FindObject(desc)) {
451     AliError("Invalid descriptor ! Impossible to add the class !");
452     return NULL;
453   }
454   if (!fClusters.FindObject(clus)) {
455     AliError("Invalid cluster ! Impossible to add the class !");
456     return NULL;
457   }
458   if (!fPFProtections.FindObject(pfp)) {
459     AliError("Invalid past-future protection ! Impossible to add the class !");
460     return NULL;
461   }
462   if (!fMasks.FindObject(mask)) {
463     AliError("Invalid bunch-crossing mask ! Impossible to add the class !");
464     return NULL;
465   }
466   AliTriggerClass* trclass = new AliTriggerClass( name,index,desc,clus,pfp,mask,prescaler,allrare );
467   if (!AddClass(trclass)) {
468     delete trclass;
469     return NULL;
470   }
471   else
472     return trclass;
473 }
474
475 //_____________________________________________________________________________
476 AliTriggerClass *AliTriggerConfiguration::AddClass( TString &name, UChar_t index,
477                                                     TString &desc, TString &clus,
478                                                     TString &pfp, TString &mask,
479                                                     UInt_t prescaler, Bool_t allrare)
480 {
481    // Add a new trigger class
482   if (!fDescriptors.FindObject(desc)) {
483     AliError("Invalid descriptor ! Impossible to add the class !");
484     return NULL;
485   }
486   if (!fClusters.FindObject(clus)) {
487     AliError("Invalid cluster ! Impossible to add the class !");
488     return NULL;
489   }
490   if (!fPFProtections.FindObject(pfp)) {
491     AliError("Invalid past-future protection ! Impossible to add the class !");
492     return NULL;
493   }
494   if (!fMasks.FindObject(mask)) {
495     AliError("Invalid bunch-crossing mask ! Impossible to add the class !");
496     return NULL;
497   }
498   AliTriggerClass* trclass = new AliTriggerClass( this, name,index,desc,clus,pfp,mask,prescaler,allrare );
499   if (!AddClass(trclass)) {
500     delete trclass;
501     return NULL;
502   }
503   else
504     return trclass;
505 }
506
507 //_____________________________________________________________________________
508 Bool_t AliTriggerConfiguration::ProcessConfigurationLine(const char* line, Int_t& level)
509 {
510     // processes one line of configuration
511
512      TString strLine(line);
513
514      if (strLine.BeginsWith("#")) return kTRUE;
515      if (strLine.BeginsWith("PARTITION:")) {
516        strLine.ReplaceAll("PARTITION:","");
517        SetName(strLine.Data());
518        return kTRUE;
519      }
520      if (strLine.BeginsWith("VERSION:")) {
521        strLine.ReplaceAll("VERSION:","");
522        fVersion = strLine.Atoi();
523        return kTRUE;
524      }
525      if (strLine.BeginsWith("INPUTS:")) {
526        level = 1;
527        return kTRUE;
528      }
529      if (strLine.BeginsWith("INTERACTIONS:")) {
530        level = 2;
531        return kTRUE;
532      }
533      if (strLine.BeginsWith("DESCRIPTORS:")) {
534        level = 3;
535        return kTRUE;
536      }
537      if (strLine.BeginsWith("CLUSTERS:")) {
538        level = 4;
539        return kTRUE;
540      }
541      if (strLine.BeginsWith("PFS:")) {
542        level = 5;
543        return kTRUE;
544      }
545      if (strLine.BeginsWith("BCMASKS:")) {
546        level = 6;
547        return kTRUE;
548      }
549      if (strLine.BeginsWith("CLASSES:")) {
550        level = 7;
551        return kTRUE;
552      }
553
554      strLine.ReplaceAll("*",'!');
555      strLine.ReplaceAll("~",'!');
556      TObjArray *tokens = strLine.Tokenize(" \t");
557      Int_t ntokens = tokens->GetEntriesFast();
558      if (ntokens == 0)
559      {
560        delete tokens;
561        return kTRUE;
562      }
563      switch (level) {
564      case 1:
565        // Read inputs
566        if (ntokens != 5) {
567          AliError(Form("Invalid trigger input syntax (%s)!",strLine.Data()));
568          return kFALSE;
569        }
570        AddInput(((TObjString*)tokens->At(0))->String(),
571                      ((TObjString*)tokens->At(1))->String(),
572                      ((TObjString*)tokens->At(2))->String().Atoi(),
573                      ((TObjString*)tokens->At(3))->String().Atoi(),
574                      ((TObjString*)tokens->At(4))->String().Atoi());
575        break;
576      case 2:
577        // Read interaction
578        if (ntokens != 2) {
579          AliError(Form("Invalid trigger interaction syntax (%s)!",strLine.Data()));
580          return kFALSE;
581        }
582        AddInteraction(((TObjString*)tokens->At(0))->String(),
583                            ((TObjString*)tokens->At(1))->String());
584        break;
585      case 3:
586        // Read logical functions and descriptors
587        if (ntokens < 2) {
588          if ((((TObjString*)tokens->At(0))->String().CompareTo("EMPTY") == 0) ||
589              (((TObjString*)tokens->At(0))->String().CompareTo("DTRUE") == 0) ||
590              (((TObjString*)tokens->At(0))->String().CompareTo("DEMPTY") == 0)) {
591            AddDescriptor(((TObjString*)tokens->At(0))->String(),
592                          strLine.ReplaceAll(((TObjString*)tokens->At(0))->String(),""));
593            break;
594          }
595          else {
596            AliError(Form("Invalid trigger descriptor syntax (%s)!",strLine.Data()));
597            return kFALSE;
598          }
599        }
600        if (((TObjString*)tokens->At(0))->String().BeginsWith("l0f")) {
601          // function
602          AddFunction(((TObjString*)tokens->At(0))->String(),
603                           strLine.ReplaceAll(((TObjString*)tokens->At(0))->String(),""));
604        }
605        else {
606          AddDescriptor(((TObjString*)tokens->At(0))->String(),
607                             strLine.ReplaceAll(((TObjString*)tokens->At(0))->String(),""));
608        }
609        break;
610      case 4:
611        {
612          if (ntokens < 2) {
613            AliError(Form("Invalid trigger cluster syntax (%s)!",strLine.Data()));
614            return kFALSE;
615          }
616          if (((TObjString*)tokens->At(1))->String().Atoi() <= 0) {
617            AliError(Form("Invalid trigger cluster syntax (%s)!",strLine.Data()));
618            return kFALSE;
619          }
620          TString strTemp;
621          for(Int_t i = 2; i < ntokens; i++) {
622            strTemp += ((TObjString*)tokens->At(i))->String();
623            strTemp += " ";
624          }
625          AddCluster(((TObjString*)tokens->At(0))->String(),
626                          ((TObjString*)tokens->At(1))->String().Atoi(),
627                          strTemp);
628        }
629        break;
630      case 5:
631        {
632          AliTriggerPFProtection *pfp = NULL;
633          if ((((TObjString*)tokens->At(0))->String().CompareTo("NONE") == 0) ||
634              (((TObjString*)tokens->At(0))->String().CompareTo("NOPF") == 0)) {
635            pfp = new AliTriggerPFProtection(((TObjString*)tokens->At(0))->String());
636          }
637          else {
638            if (ntokens != 10) {
639              AliError(Form("Invalid trigger pfs syntax (%s)!",strLine.Data()));
640              return kFALSE;
641            }
642            pfp = new AliTriggerPFProtection(((TObjString*)tokens->At(0))->String(),
643                                             ((TObjString*)tokens->At(1))->String(),
644                                             ((TObjString*)tokens->At(2))->String(),
645                                             ((TObjString*)tokens->At(3))->String());
646            pfp->SetNa1(((TObjString*)tokens->At(4))->String().Atoi());
647            pfp->SetNa2(((TObjString*)tokens->At(5))->String().Atoi());
648            pfp->SetNb1(((TObjString*)tokens->At(6))->String().Atoi());
649            pfp->SetNb2(((TObjString*)tokens->At(7))->String().Atoi());
650            pfp->SetTa(((TObjString*)tokens->At(8))->String().Atoi());
651            pfp->SetTb(((TObjString*)tokens->At(9))->String().Atoi());
652          }
653          AddPFProtection(pfp);
654        }
655        break;
656      case 6:
657          if (ntokens > 2) {
658            AliError(Form("Invalid trigger bcmasks syntax (%s)!",strLine.Data()));
659            return kFALSE;
660          }
661        if (((TObjString*)tokens->At(0))->String().CompareTo("NONE") == 0)
662        {         
663          AddMask(new AliTriggerBCMask(((TObjString*)tokens->At(0))->String()));
664        }
665        else {
666          AddMask(((TObjString*)tokens->At(0))->String(),
667                       ((TObjString*)tokens->At(1))->String());
668        }
669        break;
670      case 7:
671        {
672          if ((ntokens < 8) || (ntokens >10)) {
673            AliError(Form("Invalid trigger class syntax (%s)!",strLine.Data()));
674            return kFALSE;
675          }
676          AliTriggerClass *trclass = new AliTriggerClass(this,
677                                                         ((TObjString*)tokens->At(0))->String(),((TObjString*)tokens->At(1))->String().Atoi(),
678                                                         ((TObjString*)tokens->At(2))->String(),((TObjString*)tokens->At(3))->String(),
679                                                         ((TObjString*)tokens->At(4))->String(),((TObjString*)tokens->At(5))->String(),
680                                                         ((TObjString*)tokens->At(6))->String().Atoi(),(Bool_t)(((TObjString*)tokens->At(7))->String().Atoi()));
681          AddClass(trclass);
682        }
683      default:
684        break;
685      }
686      delete tokens;
687
688      return kTRUE;
689 }
690
691 //_____________________________________________________________________________
692 AliTriggerConfiguration* AliTriggerConfiguration::LoadConfiguration(TString & configuration)
693 {
694    // Load one pre-created Configurations from database/file that match
695    // with the input string 'configuration'
696    // Ej: "Pb-Pb" or "p-p-DIMUON CALIBRATION-CENTRAL-BARREL"
697   // By default the files are stored in GRP/CTP folder.
698   // The filename is constructed as: GRP/CTP/<configuration>.cfg
699
700    // Load the selected configuration
701   TString filename;
702   if (configuration.EndsWith(".cfg") ||
703       configuration.EndsWith(".shuttle")) {
704     filename = configuration;
705   }
706   else {
707     filename = gSystem->Getenv("ALICE_ROOT");
708     filename += "/GRP/CTP/";
709     filename += configuration;
710     filename += ".cfg";
711   }
712
713    if( gSystem->AccessPathName( filename.Data() ) ) {
714       AliErrorClass( Form( "file (%s) not found", filename.Data() ) );
715       return NULL;
716    }
717
718
719    ifstream *file = new ifstream ( filename.Data() );
720    if (!*file) {
721      AliErrorClass(Form("Error opening file (%s) !",filename.Data()));
722      file->close();
723      delete file;
724      return NULL;
725    }
726
727    AliTriggerConfiguration *cfg = new AliTriggerConfiguration();
728
729    Int_t level = 0;
730
731    TString strLine;
732    while (strLine.ReadLine(*file)) {
733      if (cfg->ProcessConfigurationLine(strLine, level) == kFALSE)
734      {
735         delete cfg;
736         cfg = 0;
737         break;
738      }
739    }
740
741    file->close();
742    delete file;
743
744    return cfg;
745 }
746
747 //_____________________________________________________________________________
748 AliTriggerConfiguration* AliTriggerConfiguration::LoadConfigurationFromString(const char* configuration)
749 {
750    // Loads configuration given as parameter <configuration>
751
752    if (!configuration)
753      return 0;
754
755    AliTriggerConfiguration *cfg = new AliTriggerConfiguration();
756
757    Int_t level = 0;
758
759    TObjArray* tokens = TString(configuration).Tokenize("\n");
760    for (Int_t i=0; i<tokens->GetEntries(); i++)
761    {
762      TObjString* str = dynamic_cast<TObjString*>(tokens->At(i));
763      if (!str)
764        continue;
765
766      if (cfg->ProcessConfigurationLine(str->String(), level) == kFALSE)
767      {
768         delete cfg;
769         cfg = 0;
770         break;
771      }
772    }
773
774    delete tokens;
775
776    return cfg;
777 }
778
779 //_____________________________________________________________________________
780 TObjArray* AliTriggerConfiguration::GetAvailableConfigurations( const char* filename )
781 {
782    // Return an array of configuration in the file
783
784    TString path;
785    if( !filename[0] ) {
786       path += gSystem->Getenv( "ALICE_ROOT" );
787       path += fgkConfigurationFileName;
788    }
789    else
790       path += filename;
791
792    if( gSystem->AccessPathName( path.Data() ) ) {
793       AliErrorGeneral( "AliTriggerConfiguration", Form( "file (%s) not found", path.Data() ) );
794       return NULL;
795    }
796
797    TObjArray* desArray = new TObjArray();
798
799    TFile file( path.Data(), "READ" );
800    if( file.IsZombie() ) {
801       AliErrorGeneral( "AliTriggerConfiguration", Form( "Error opening file (%s)", path.Data() ) );
802       return NULL;
803    }
804
805    file.ReadAll();
806
807    TKey* key;
808    TIter next( file.GetListOfKeys() );
809    while( (key = (TKey*)next()) ) {
810       TObject* obj = key->ReadObj();
811       if( obj->InheritsFrom( "AliTriggerConfiguration" ) ) {
812          desArray->AddLast( obj );
813       }
814    }
815    file.Close();
816
817    return desArray;
818 }
819
820 //_____________________________________________________________________________
821 void AliTriggerConfiguration::WriteConfiguration( const char* filename )
822 {
823    // Write the configuration
824    TString path;
825    if( !filename[0] ) {
826       path += gSystem->Getenv("ALICE_ROOT");
827       path += fgkConfigurationFileName;
828    }
829    else
830       path += filename;
831
832    TFile file( path.Data(), "UPDATE" );
833    if( file.IsZombie() ) {
834       AliErrorGeneral( "AliTriggerConfiguration", 
835                         Form( "Can't open file (%s)", path.Data() ) );
836       return;
837    }
838
839    Bool_t result = (Write( GetName(), TObject::kOverwrite ) != 0);
840    if( !result )
841       AliErrorGeneral( "AliTriggerConfiguration",
842                         Form( "Can't write entry to file <%s>!", path.Data() ) );
843    file.Close();
844 }
845
846 //_____________________________________________________________________________
847 Bool_t AliTriggerConfiguration::CheckConfiguration( TString& configfile )
848 {
849    // To be used on the pre-creation of Configurations to check if the
850    // conditions have valid inputs names.
851    //
852    // Initiate detectors modules from a Config file
853    // Ask to each active module present in the fDetectorCluster
854    // to create a Trigger detector and retrive the inputs from it
855    // to create a list of inputs.
856    // Each condition in the configuration is then checked agains 
857    // the list of inputs
858
859
860    if (!gAlice) {
861       AliError( "no gAlice object. Restart aliroot and try again." );
862       return kFALSE;
863    }
864    if (gAlice->Modules()->GetEntries() > 0) {
865       AliError( "gAlice was already run. Restart aliroot and try again." );
866       return kFALSE;
867    }
868
869    AliInfo( Form( "initializing gAlice with config file %s",
870             configfile.Data() ) );
871 //_______________________________________________________________________
872    gAlice->Announce();
873    
874    gROOT->LoadMacro(configfile.Data());
875    gInterpreter->ProcessLine(gAlice->GetConfigFunction());
876    
877    if(AliCDBManager::Instance()->GetRun() >= 0) { 
878      AliRunLoader::Instance()->SetRunNumber(AliCDBManager::Instance()->GetRun());
879    } else {
880      AliWarning("Run number not initialized!!");
881    }
882   
883    AliRunLoader::Instance()->CdGAFile();
884     
885    AliPDG::AddParticlesToPdgDataBase();  
886
887    gAlice->GetMCApp()->Init();
888    
889    //Must be here because some MCs (G4) adds detectors here and not in Config.C
890    gAlice->InitLoaders();
891    AliRunLoader::Instance()->MakeTree("E");
892    AliRunLoader::Instance()->LoadKinematics("RECREATE");
893    AliRunLoader::Instance()->LoadTrackRefs("RECREATE");
894    AliRunLoader::Instance()->LoadHits("all","RECREATE");
895    //
896    // Save stuff at the beginning of the file to avoid file corruption
897    AliRunLoader::Instance()->CdGAFile();
898    gAlice->Write();
899
900    AliRunLoader* runLoader = AliRunLoader::Instance();
901    if( !runLoader ) {
902       AliError( Form( "gAlice has no run loader object. "
903                       "Check your config file: %s", configfile.Data() ) );
904       return kFALSE;
905    }
906
907    // get the possible inputs to check the condition
908    TObjArray inputs;
909    TObjArray* detArray = runLoader->GetAliRun()->Detectors();
910
911    TString detStr = GetTriggeringModules();
912
913    for( Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++ ) {
914       AliModule* det = (AliModule*) detArray->At(iDet);
915       if( !det || !det->IsActive() ) continue;
916       if( IsSelected( det->GetName(), detStr ) ) {
917          AliInfo( Form( "Creating inputs for %s", det->GetName() ) );
918          AliTriggerDetector* dtrg = det->CreateTriggerDetector();
919          dtrg->AssignInputs(GetInputs());
920          TObjArray* detInp = dtrg->GetInputs();
921          for( Int_t i=0; i<detInp->GetEntriesFast(); i++ ) {
922             AliInfo( Form( "Adding input %s", ((AliTriggerInput*)detInp->At(i))->GetName() ) );
923             inputs.AddLast( detInp->At(i) );
924          }
925       }
926    }
927
928    // check if the condition is compatible with the triggers inputs
929    Int_t ndesc = fClasses.GetEntriesFast();
930    Bool_t check = kTRUE;
931    ULong64_t mask = 0L;
932    for( Int_t j=0; j<ndesc; j++ ) {
933      AliTriggerClass *trclass = (AliTriggerClass*)fClasses.At( j );
934      if( !(trclass->CheckClass( this )) ) check = kFALSE;
935      else {
936        if (trclass->IsActive(this->GetInputs(),this->GetFunctions())) {
937          AliInfo( Form( "Trigger Class (%s) OK, class mask (0x%Lx)",
938                         trclass->GetName(), trclass->GetMask( ) ) );
939        }
940        else {
941          AliWarning( Form( "Trigger Class (%s) is NOT active, class mask (0x%Lx)",
942                            trclass->GetName(), trclass->GetMask( ) ) );
943        }
944      }
945      // check if condition mask is duplicated
946      if( mask & trclass->GetMask() ) {
947        AliError( Form("Class (%s). The class mask (0x%Lx) is ambiguous. It was already defined",
948                       trclass->GetName(), trclass->GetMask()  ) );
949        check = kFALSE;
950      }
951      mask |= trclass->GetMask();
952    }
953
954    return check;
955 }
956 //_____________________________________________________________________________
957 Int_t AliTriggerConfiguration::GetClassIndexFromName(const char* className) const
958 {
959    //const TObjArray& classes = cfg->GetClasses();
960    Int_t nclasses = (Int_t)fClasses.GetEntriesFast();
961    for (Int_t i=0;i<nclasses;i++) {
962        AliTriggerClass* trgclass = (AliTriggerClass*)fClasses.At(i);
963        if (TString(trgclass->GetName()).CompareTo(className) == 0) { 
964           ULong64_t classmask = (ULong64_t)trgclass->GetMask();
965           return TMath::Nint(TMath::Log2(classmask))+1;
966        }
967    }
968    return -1;
969 }
970 //_____________________________________________________________________________
971 const char* AliTriggerConfiguration::GetClassNameFromIndex(Int_t classIndex) const
972 {
973    Int_t nclasses = (Int_t)fClasses.GetEntriesFast();
974    for (Int_t i=0;i<nclasses;i++) {
975        AliTriggerClass* trgclass = (AliTriggerClass*)fClasses.At(i);
976        ULong64_t classmask = (ULong64_t)trgclass->GetMask();
977        if (TMath::Nint(TMath::Log2(classmask))+1 == classIndex) return trgclass->GetName();
978    }
979    return 0;
980 }
981 //_____________________________________________________________________________
982 AliTriggerClass* AliTriggerConfiguration::GetTriggerClass(Int_t classIndex) const
983 {
984    Int_t nclasses = (Int_t)fClasses.GetEntriesFast();
985    for (Int_t i=0;i<nclasses;i++) {
986        AliTriggerClass* trgclass = (AliTriggerClass*)fClasses.At(i);
987        ULong64_t classmask = (ULong64_t)trgclass->GetMask();
988        if (TMath::Nint(TMath::Log2(classmask))+1 == classIndex) return trgclass;
989    }
990    return 0;
991 }
992 //_____________________________________________________________________________
993 void AliTriggerConfiguration::Reset()
994 {
995    for( Int_t j=0; j<fInputs.GetEntriesFast(); j++ )
996      ((AliTriggerInput*)fInputs.At(j))->Reset();
997
998    for( Int_t j=0; j<fClasses.GetEntriesFast(); j++ )
999      ((AliTriggerClass*)fClasses.At(j))->Reset();
1000 }
1001
1002 //_____________________________________________________________________________
1003 void AliTriggerConfiguration::Print( const Option_t*  ) const
1004 {
1005    // Print
1006   cout << "#################################################" << endl;
1007    cout << "Trigger Configuration:"  << endl;
1008    cout << "  Name:              " << GetName() << endl; 
1009    cout << "  Description:       " << GetTitle() << endl;
1010    cout << "  Version:           " << GetVersion() << endl;
1011    cout << "  Active Detectors:  " << GetActiveDetectors() << endl;
1012    cout << "  Trigger Detectors: " << GetTriggeringDetectors() << endl;
1013
1014    cout << "#################################################" << endl;
1015    fInputs.Print();
1016    cout << "#################################################" << endl;
1017    fInteractions.Print();
1018    cout << "#################################################" << endl;
1019    fFunctions.Print();
1020    cout << "#################################################" << endl;
1021    fDescriptors.Print();
1022    cout << "#################################################" << endl;
1023    fClusters.Print();
1024    cout << "#################################################" << endl;
1025    fPFProtections.Print();
1026    cout << "#################################################" << endl;
1027    fMasks.Print();
1028    cout << "#################################################" << endl;
1029    fClasses.Print();
1030    cout << "#################################################" << endl;
1031
1032    cout << endl;
1033 }
1034
1035
1036 //////////////////////////////////////////////////////////////////////////////
1037 // Helper method
1038
1039 //_____________________________________________________________________________
1040 Bool_t AliTriggerConfiguration::IsSelected( TString detName, TString& detectors ) const
1041 {
1042    // check whether detName is contained in detectors
1043    // if yes, it is removed from detectors
1044
1045    // check if all detectors are selected
1046    if( (detectors.CompareTo("ALL") == 0 ) ||
1047         detectors.BeginsWith("ALL ") ||
1048         detectors.EndsWith(" ALL") ||
1049         detectors.Contains(" ALL ") ) {
1050       detectors = "ALL";
1051       return kTRUE;
1052    }
1053
1054    // search for the given detector
1055    Bool_t result = kFALSE;
1056    if( (detectors.CompareTo( detName ) == 0) ||
1057         detectors.BeginsWith( detName+" " ) ||
1058         detectors.EndsWith( " "+detName ) ||
1059         detectors.Contains( " "+detName+" " ) ) {
1060       detectors.ReplaceAll( detName, "" );
1061       result = kTRUE;
1062    }
1063
1064    // clean up the detectors string
1065    while( detectors.Contains("  ") )  detectors.ReplaceAll( "  ", " " );
1066    while( detectors.BeginsWith(" ") ) detectors.Remove( 0, 1 );
1067    while( detectors.EndsWith(" ") )   detectors.Remove( detectors.Length()-1, 1 );
1068
1069    return result;
1070 }