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