Updating Pb-Pb triggers to include downscaled central and semicentral triggers
[u/mrichter/AliRoot.git] / OADB / AliOADBPhysicsSelection.cxx
1 #include "AliOADBPhysicsSelection.h"
2 #include "TList.h"
3 #include "TString.h"
4 #include "TObjString.h"
5 #include "AliLog.h"
6 #include "TBrowser.h"
7 #include "TFolder.h"
8 #include "TIterator.h"
9 #include <iostream>
10
11 using namespace std;
12
13 ClassImp(AliOADBPhysicsSelection)
14
15
16 AliOADBPhysicsSelection::AliOADBPhysicsSelection() : 
17 TNamed("AliOADBPhysicsSelection", "OADB object for the physics selection"), fNtriggerBits(NTRIGGERBITS), fNtriggerLogics(NTRIGGERLOGICS),fCollTrigClasses(0),fBGTrigClasses(0),fHardwareTrigger(0),fOfflineTrigger(0),fBeamSide(0)
18 {
19   // default ctor
20   
21 }
22 AliOADBPhysicsSelection::AliOADBPhysicsSelection(const char* name) : 
23   TNamed(name, "OADB object for the physics selection"), fNtriggerBits(NTRIGGERBITS), fNtriggerLogics(NTRIGGERLOGICS),fCollTrigClasses(0),fBGTrigClasses(0),fHardwareTrigger(0),fOfflineTrigger(0),fBeamSide(0)
24 {
25   // ctor, better use this one
26   Init();
27 }
28
29 void AliOADBPhysicsSelection::Init() {
30   //Initialization of pointers
31
32   if(fCollTrigClasses) {
33     AliInfo("Already initialized");
34     return;
35   }
36
37   fNtriggerBits = NTRIGGERBITS;
38   fCollTrigClasses = new TList*[fNtriggerBits];
39   fBGTrigClasses   = new TList*[fNtriggerBits];
40   fHardwareTrigger = new TObjString[fNtriggerLogics];
41   fOfflineTrigger  = new TObjString[fNtriggerLogics];  
42   fBeamSide = new TMap;
43   for(UInt_t ibit = 0; ibit < fNtriggerBits; ibit++){
44     fCollTrigClasses[ibit] = new TList;
45     fBGTrigClasses  [ibit] = new TList;
46   }
47   for(UInt_t ilogic = 0; ilogic < fNtriggerLogics; ilogic++){
48     fHardwareTrigger[ilogic] = "";
49     fOfflineTrigger [ilogic] = "";
50   }
51   
52
53 }
54
55 AliOADBPhysicsSelection::~AliOADBPhysicsSelection(){
56   // dtor
57
58   if(fHardwareTrigger) delete [] fHardwareTrigger;
59   if(fOfflineTrigger)  delete [] fOfflineTrigger ;
60   
61   for(Int_t ibit = 0; ibit < NTRIGGERBITS; ibit++){
62     
63     if(fCollTrigClasses)
64       if(fCollTrigClasses[ibit]) delete fCollTrigClasses[ibit];
65     if(fBGTrigClasses)
66       if(fBGTrigClasses  [ibit]) delete fBGTrigClasses  [ibit];
67   }
68
69 }
70
71 AliOADBPhysicsSelection::AliOADBPhysicsSelection(const AliOADBPhysicsSelection& cont) :TNamed("AliOADBPhysicsSelection", "OADB object for the physics selection"), fNtriggerBits(NTRIGGERBITS), fNtriggerLogics(NTRIGGERLOGICS),fCollTrigClasses(0),fBGTrigClasses(0),fHardwareTrigger(0),fOfflineTrigger(0),fBeamSide(0) {
72   // Copy ctor
73   fCollTrigClasses = cont.fCollTrigClasses;
74   fBGTrigClasses = cont.fBGTrigClasses;
75   fHardwareTrigger = cont.fHardwareTrigger;
76   fOfflineTrigger = cont.fOfflineTrigger;
77   fBeamSide = cont.fBeamSide;
78   
79 }
80
81 AliOADBPhysicsSelection& AliOADBPhysicsSelection::operator=(const AliOADBPhysicsSelection& other)  {
82   //Assignment operator
83   TNamed::operator=(other);
84
85   fCollTrigClasses = other.fCollTrigClasses;
86   fBGTrigClasses = other.fBGTrigClasses;
87   fHardwareTrigger = other.fHardwareTrigger;
88   fOfflineTrigger = other.fOfflineTrigger;
89   fBeamSide = other.fBeamSide;
90   
91
92   return *this;
93 }
94  
95 void AliOADBPhysicsSelection::AddCollisionTriggerClass(AliVEvent::EOfflineTriggerTypes triggerMask, const char* className,const char * beamSide, UInt_t triggerLogic) {
96   // add collision trigger class
97   TObjString * tclass = new TObjString(Form("%s &%u *%u",ExpandTriggerString(className),triggerMask, triggerLogic));
98   fCollTrigClasses[GetActiveBit(triggerMask)]->Add(tclass); 
99   SetBeamSide(tclass->String().Data(),beamSide);
100 }
101 void AliOADBPhysicsSelection::AddBGTriggerClass       (AliVEvent::EOfflineTriggerTypes triggerMask, const char* className,const char * beamSide, UInt_t triggerLogic) 
102
103   // add bg trigger class
104   TObjString * tclass = new TObjString(Form("%s &%u *%u",ExpandTriggerString(className),triggerMask, triggerLogic));
105   fBGTrigClasses  [GetActiveBit(triggerMask)]->Add(tclass);
106   SetBeamSide(tclass->String().Data(),beamSide);
107 }
108
109 const TString AliOADBPhysicsSelection::GetBeamSide (const char * trigger)  {
110   // Associate beam side to trigger class name
111   TObjString * cname = new TObjString(trigger);
112   CleanKey(cname->String());  
113   static TString retValue="";
114   retValue = ((TObjString*)fBeamSide->GetValue(cname->String().Data())) ?  
115     ((TObjString*)fBeamSide->GetValue(cname->String().Data()))->String() : "" ;
116   delete cname;
117   return retValue;
118 }
119 void AliOADBPhysicsSelection::SetBeamSide (const char * className, const char * side)
120
121   // return beam side
122   TObjString * cname = new TObjString(className);
123   CleanKey(cname->String());
124   fBeamSide->Add(new TObjString(cname->String().Data()), new TObjString(side));
125   delete cname;
126 }
127
128 void AliOADBPhysicsSelection::CleanKey(TString & str) {
129
130   //  Remove all wite spaces and "goodies" of the trigger class string (bx ids, trigger logic...)
131   if(str.Index("*")>0)
132     str.Remove(str.Index("*")); // keep only the class name (no bx, offline trigger...)   
133   if(str.Index("#")>0)
134     str.Remove(str.Index("#")); // keep only the class name (no bx, offline trigger...)   
135   if(str.Index("&")>0)
136     str.Remove(str.Index("&")); // keep only the class name (no bx, offline trigger...)   
137   str.ReplaceAll(" ","");
138
139 }
140  
141 // Getters
142
143 // FIXME: decide about these getters
144 // TList * AliOADBPhysicsSelection::GetCollTrigClass(AliVEvent::EOfflineTriggerTypes trig) const { 
145 //   // Returns list of collision trigger classes for the requested bits
146 //   return GetTrigClass(trig,fCollTrigClasses);
147 // }
148
149 // TList * AliOADBPhysicsSelection::GetBGTrigClass(AliVEvent::EOfflineTriggerTypes trig) const { 
150 //   // Returns list of background trigger classes for the requested bits
151 //   return GetTrigClass(trig,fBGTrigClasses);
152 // }
153
154 // TList * AliOADBPhysicsSelection::GetTrigClass(AliVEvent::EOfflineTriggerTypes trig, TList ** listClasses) const { 
155 //   // Returns list of trigger classes for the requested bits
156
157 //   TList * list= new TList;  
158 //   // Check which bits are on and build the final list
159 //   for(UInt_t ibit = 0; ibit < fNtriggerBits; ibit++){
160 //     if ((trig&(0x1<<ibit))) {
161 //       if(listClasses[ibit]) list->AddAll(listClasses[ibit]);
162 //       else AliError(Form("List %d not initialized?",ibit));
163 //     }
164 //   }
165   
166 //   return list;
167 // }
168
169 void AliOADBPhysicsSelection::Print(Option_t* option) const {
170
171   for(UInt_t ibit = 0; ibit < fNtriggerBits; ibit++){
172     cout << "Bit " << ibit << endl;
173     
174     fCollTrigClasses[ibit]->Print(option);
175     fBGTrigClasses[ibit]->Print(option);
176     cout << "HW trig " << fHardwareTrigger[ibit].String().Data() << endl;
177     cout << "Offline trig " << fHardwareTrigger[ibit].String().Data() << endl;
178     
179   }
180   cout << "Beams: " << endl;
181   fBeamSide->Print();
182
183 }
184
185
186 void AliOADBPhysicsSelection::Browse(TBrowser *b)
187 {
188    // Browse this object.
189    // If b=0, there is no Browse call TObject::Browse(0) instead.
190    //         This means TObject::Inspect() will be invoked indirectly
191   static TFolder  ** bitFolders = 0;
192   if(!bitFolders) {
193     bitFolders = new TFolder*[fNtriggerBits];
194     for(UInt_t ibit = 0; ibit < fNtriggerBits; ibit++){
195       bitFolders[ibit] = 0;
196     }
197     
198   }
199
200   if (b) {
201     for(UInt_t ibit = 0; ibit < fNtriggerBits; ibit++){
202       if(bitFolders[ibit]) delete bitFolders[ibit];
203       bitFolders[ibit] = new TFolder (Form("Bit %2.2d", ibit), "Trigger bit folder");
204       bitFolders[ibit]->SetOwner(); // Delete also the TObjString when deleting the folder
205       for(UInt_t ilogic = 0; ilogic < fNtriggerLogics; ilogic++){
206         if(GetHardwareTrigger(ilogic) != "" ||  GetOfflineTrigger(ilogic) != "")  {
207           bitFolders[ibit]->Add(new TObjString(Form("Hardware Trig    [*%d][%s]",ilogic,GetHardwareTrigger(ilogic).Data())));
208           bitFolders[ibit]->Add(new TObjString(Form("Offline  Trig    [*%d][%s]",ilogic,GetOfflineTrigger(ilogic).Data())));      
209         }
210       }
211       
212       TIterator *itColl = fCollTrigClasses[ibit]->MakeIterator();
213       TObjString * coll = 0;
214
215       while ((coll = (TObjString*)itColl->Next())) {
216         bitFolders[ibit]->Add(new TObjString(Form("Collision Class  [%s] [%s]", coll->String().Data(), 
217                                                   GetBeamSide(coll->String().Data()).Data())));
218       }
219       delete itColl;
220
221       TIterator *itBG = fBGTrigClasses[ibit]->MakeIterator();
222       TObjString * bg = 0;
223       while ((bg = (TObjString*)itBG->Next())) {
224         bitFolders[ibit]->Add(new TObjString(Form("Background Class [%s] [%s]", bg->String().Data(), 
225                                                   GetBeamSide(bg->String().Data()).Data())));
226       }
227       delete itBG;
228
229       b->Add(bitFolders[ibit]);
230
231     }    
232   }     
233    else
234       TObject::Browse(b);
235 }
236
237 UInt_t AliOADBPhysicsSelection::GetActiveBit(UInt_t mask) {
238   // Returns the active bit index in the mask
239   // Assumes only one bit is on.
240   // If more than one bit is lit, prints an error and returns the first.
241   // If no bit is on, prints an error and returns 0
242
243   const Int_t kNBitsToCheck = 28;
244
245   //  Int_t nbit = sizeof(mask)*8;
246   Int_t nbit = kNBitsToCheck;
247   Int_t activeBit = -1;
248   for(Int_t ibit = 0; ibit < nbit; ibit++){
249     if ( mask & (0x1 << ibit) ) {
250       if (activeBit == -1) activeBit = ibit;
251       else Printf("ERROR (AliTriggerAnalysis::GetActiveBit): More than one bit is on in this mask 0x%x", mask);
252     }
253   }
254   if (activeBit == -1) {
255     Printf("ERROR (AliTriggerAnalysis::GetActiveBit): No bit is on");
256     activeBit=0;
257   }
258
259   return activeBit;
260
261 }
262
263 const char* AliOADBPhysicsSelection::ExpandTriggerString(const char* className)
264 {
265   // expands [] syntax
266   // E.g. +CVHN-B-[NOPF|PF]-[ALL|CENT]NOTRD goes to +CVHN-B-NOPF-ALLNOTRD,CVHN-B-NOPF-CENTNOTRD,CVHN-B-PF-ALLNOTRD,CVHN-B-PF-CENTNOTRD
267   
268   static TString str;
269   str = className;
270   TObjArray* triggers = str.Tokenize(" ");
271   for (Int_t j=0; j<triggers->GetEntries(); j++)
272   {
273     str = triggers->At(j)->GetName();
274     str = str(1, str.Length());
275     
276     TList list;
277     list.SetOwner();
278
279     TObjArray* triggers2 = str.Tokenize(",");
280     for (Int_t k=0; k<triggers2->GetEntries(); k++)
281       list.Add(new TObjString(triggers2->At(k)->GetName()));
282     delete triggers2;
283     
284 //     list.Print();
285     
286     while (1)
287     {
288       Int_t i=0;
289       for (i=0; i<list.GetEntries(); i++)
290       {
291         str = list.At(i)->GetName();
292       
293         Int_t begin = str.Index("[");
294         Int_t end = str.Index("]");
295         if (begin >= 0 && end >= 0)
296         {
297           TString before = str(0, begin);
298           TString after = str(end+1, str.Length());
299           TString tokens = str(begin+1, end-begin-1);
300   //    Printf("%s %s %s", before.Data(), tokens.Data(), after.Data());
301           Int_t pos = 0;
302           while (tokens.Index("|", pos) >= 0)
303           {
304             list.Add(new TObjString(before + tokens(pos, tokens.Index("|", pos) - pos) + after));
305             pos = tokens.Index("|", pos) + 1;
306           }
307           list.Add(new TObjString(before + tokens(pos, tokens.Length()) + after));
308           delete list.RemoveAt(i);
309           
310   //    list.Print();
311           i=-1;
312         }
313       }
314
315       str = "";
316       for (i=0; i<list.GetEntries(); i++)
317       {
318         str += list.At(i)->GetName();
319         str += ",";
320       }
321       str = str(0, str.Length() - 1);
322       break;
323     }
324       
325     TString& target = ((TObjString*) triggers->At(j))->String();
326     target.Form("%c%s", target[0], str.Data());
327   }
328   
329   str = "";
330   for (Int_t j=0; j<triggers->GetEntries(); j++)
331   {
332     str += triggers->At(j)->GetName();
333     str += " ";
334   }
335   str = str(0, str.Length() - 1);
336
337   delete triggers;
338   if (strcmp(className, str.Data()))
339     Printf("AliOADBPhysicsSelection::ExpandTriggerString: In: <%s> Out: <%s>", className, str.Data());
340   return str;
341 }