]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWG/muon/AliMuonEventCuts.cxx
Split the TaskMuMu into more manageable sub-analysis (Laurent)
[u/mrichter/AliRoot.git] / PWG / muon / AliMuonEventCuts.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 #include "AliMuonEventCuts.h"
17
18 #include "TMath.h"
19 #include "TFormula.h"
20 #include "THashList.h"
21 #include "TObjArray.h"
22 #include "TObjString.h"
23 #include "TFile.h"
24 #include "TParameter.h"
25 #include "TKey.h"
26 #include "TSystem.h"
27 #include "TAxis.h"
28 #include "TArrayI.h"
29 #include "TRegexp.h"
30 #include "TPRegexp.h"
31
32 #include "AliLog.h"
33 #include "AliInputEventHandler.h"
34 #include "AliVEvent.h"
35 #include "AliESDEvent.h"
36 #include "AliAODEvent.h"
37 #include "AliVVertex.h"
38 #include "AliCentrality.h"
39
40 #include "AliAnalysisMuonUtility.h"
41
42 /// \cond CLASSIMP
43 ClassImp(AliMuonEventCuts) // Class implementation in ROOT context
44 /// \endcond
45
46
47 //________________________________________________________________________
48 AliMuonEventCuts::AliMuonEventCuts() :
49   AliAnalysisCuts(),
50   fPhysicsSelectionMask(0),
51   fVertexMinNContributors(0),
52   fVertexVzMin(0.),
53   fVertexVzMax(0.),
54   fDefaultTrigClassPatterns(""),
55   fSelectedTrigPattern(0x0),
56   fRejectedTrigPattern(0x0),
57   fSelectedTrigLevel(0x0),
58   fSelectedTrigCombination(0x0),
59   fTrigInputsMap(0x0),
60   fAllSelectedTrigClasses(0x0),
61   fCentralityClasses(0x0),
62   fEventTriggerMask(0),
63   fSelectedTrigClassesInEvent(0x0)
64 {
65   /// Default ctor.
66 }
67
68 //________________________________________________________________________
69 AliMuonEventCuts::AliMuonEventCuts(const char* name, const char* title ) :
70 AliAnalysisCuts(name, title),
71   fPhysicsSelectionMask(0),
72   fVertexMinNContributors(0),
73   fVertexVzMin(0.),
74   fVertexVzMax(0.),
75   fDefaultTrigClassPatterns(""),
76   fSelectedTrigPattern(new TObjArray()),
77   fRejectedTrigPattern(new TObjArray()),
78   fSelectedTrigLevel(new TObjArray()),
79   fSelectedTrigCombination(new TObjArray()),
80   fTrigInputsMap(new THashList()),
81   fAllSelectedTrigClasses(new THashList()),
82   fCentralityClasses(0x0),
83   fEventTriggerMask(0),
84   fSelectedTrigClassesInEvent(new TObjArray())
85 {
86   /// Constructor
87   SetDefaultParameters();
88   SetDefaultFilterMask();
89   SetDefaultTrigClassPatterns();
90   SetTrigClassLevels();
91   SetDefaultTrigInputsMap();
92   SetCentralityClasses();
93   fAllSelectedTrigClasses->SetOwner();
94   fSelectedTrigClassesInEvent->SetOwner();
95 }
96
97 //________________________________________________________________________
98 AliMuonEventCuts::AliMuonEventCuts(const AliMuonEventCuts& obj) :
99   AliAnalysisCuts(obj),
100   fPhysicsSelectionMask(obj.fPhysicsSelectionMask),
101   fVertexMinNContributors(obj.fVertexMinNContributors),
102   fVertexVzMin(obj.fVertexVzMin),
103   fVertexVzMax(obj.fVertexVzMax),
104   fDefaultTrigClassPatterns(obj.fDefaultTrigClassPatterns),
105   fSelectedTrigPattern(obj.fSelectedTrigPattern),
106   fRejectedTrigPattern(obj.fRejectedTrigPattern),
107   fSelectedTrigLevel(obj.fSelectedTrigLevel),
108   fSelectedTrigCombination(obj.fSelectedTrigCombination),
109   fTrigInputsMap(obj.fTrigInputsMap),
110   fAllSelectedTrigClasses(obj.fAllSelectedTrigClasses),
111   fCentralityClasses(obj.fCentralityClasses),
112   fEventTriggerMask(obj.fEventTriggerMask),
113   fSelectedTrigClassesInEvent(obj.fSelectedTrigClassesInEvent)
114 {
115   /// Copy constructor
116 }
117
118
119 //________________________________________________________________________
120 AliMuonEventCuts& AliMuonEventCuts::operator=(const AliMuonEventCuts& obj)
121 {
122   /// Assignment operator
123   if ( this != &obj ) { 
124     AliAnalysisCuts::operator=(obj);
125     fPhysicsSelectionMask = obj.fPhysicsSelectionMask;
126     fVertexMinNContributors = obj.fVertexMinNContributors,
127     fVertexVzMin = obj.fVertexVzMin;
128     fVertexVzMax = obj.fVertexVzMax;
129     fDefaultTrigClassPatterns = obj.fDefaultTrigClassPatterns;
130     fSelectedTrigPattern = obj.fSelectedTrigPattern;
131     fRejectedTrigPattern = obj.fRejectedTrigPattern;
132     fSelectedTrigLevel = obj.fSelectedTrigLevel;
133     fSelectedTrigCombination = obj.fSelectedTrigCombination;
134     fTrigInputsMap = obj.fTrigInputsMap;
135     fAllSelectedTrigClasses = obj.fAllSelectedTrigClasses;
136     fCentralityClasses = obj.fCentralityClasses;
137     fEventTriggerMask = obj.fEventTriggerMask;
138     fSelectedTrigClassesInEvent = obj.fSelectedTrigClassesInEvent;
139   }
140   return *this;
141 }
142
143
144 //________________________________________________________________________
145 AliMuonEventCuts::~AliMuonEventCuts()
146 {
147   /// Destructor
148   delete fSelectedTrigPattern;
149   delete fRejectedTrigPattern;
150   delete fSelectedTrigLevel;
151   delete fSelectedTrigCombination;
152   delete fTrigInputsMap;
153   delete fAllSelectedTrigClasses;
154   delete fSelectedTrigClassesInEvent;
155   delete fCentralityClasses;
156 }
157
158 //________________________________________________________________________
159 Bool_t AliMuonEventCuts::IsSelected( TObject* obj )
160 {
161   /// Track is selected
162   UInt_t filterMask = GetFilterMask();
163   UInt_t selectionMask = GetSelectionMask(obj);
164   
165   AliDebug(1, Form("Is event selected %i  mask 0x%x", ( selectionMask & filterMask ) == filterMask, selectionMask ));
166   
167   return ( ( selectionMask & filterMask ) == filterMask );
168 }
169
170
171 //________________________________________________________________________
172 UInt_t AliMuonEventCuts::GetSelectionMask( const TObject* obj )
173 {
174   /// Get selection mask
175   
176   UInt_t selectionMask = 0;
177   
178   const AliInputEventHandler* inputHandler = static_cast<const AliInputEventHandler*> ( obj );
179   
180   if ( const_cast<AliInputEventHandler*>(inputHandler)->IsEventSelected() & fPhysicsSelectionMask ) selectionMask |= kPhysicsSelected;
181   
182   const AliVEvent* event = inputHandler->GetEvent();
183   
184   Double_t centrality = GetCentrality(event);
185   if ( centrality >= fCentralityClasses->GetXmin() && centrality <= fCentralityClasses->GetXmax() ) selectionMask |= kSelectedCentrality;
186   
187   UpdateEvent(event);
188   
189   if ( fSelectedTrigClassesInEvent->GetEntries() > 0 ) selectionMask |= kSelectedTrig;
190   
191   AliVVertex* vertex = AliAnalysisMuonUtility::GetVertexSPD(event);
192   if ( vertex->GetNContributors() >= GetVertexMinNContributors() && 
193       vertex->GetZ() >= GetVertexVzMin() && vertex->GetZ() <= GetVertexVzMax() ) selectionMask |= kGoodVertex;
194   
195   AliDebug(1, Form("Selection mask 0x%x\n", selectionMask));
196
197   return selectionMask;
198 }
199
200
201 //________________________________________________________________________
202 Bool_t AliMuonEventCuts::IsSelected( TList* /* list */)
203 {
204   /// Not implemented
205   AliError("Function not implemented: Use IsSelected(TObject*)");
206   return kFALSE;
207 }
208
209 //________________________________________________________________________
210 Bool_t AliMuonEventCuts::UpdateEvent ( const AliVEvent* event )
211 {
212   /// Update the transient data member per event
213   
214   if ( fSelectedTrigClassesInEvent && ( fEventTriggerMask == event->GetTriggerMask() ) ) return kFALSE;
215   
216   BuildTriggerClasses(AliAnalysisMuonUtility::GetFiredTriggerClasses(event), AliAnalysisMuonUtility::GetL0TriggerInputs(event), AliAnalysisMuonUtility::GetL1TriggerInputs(event), AliAnalysisMuonUtility::GetL2TriggerInputs(event));
217   
218   fEventTriggerMask = event->GetTriggerMask();
219   
220   return kTRUE;
221 }
222
223 //________________________________________________________________________
224 void AliMuonEventCuts::SetDefaultTrigClassPatterns ()
225 {
226   /// Set the default patterns
227   /// (done in such a way to get all muon triggers)
228   fDefaultTrigClassPatterns = "CM*,C0M*,CINT*,CPBI*,CCENT*,CV*,!*ABCE*,!*-ACE-*,!*-AC-*,!*-E-*,!*WU*,!*EGA*,!*EJE*,!*PHS*";
229   SetTrigClassPatterns(fDefaultTrigClassPatterns);
230 }
231
232
233 //________________________________________________________________________
234 void AliMuonEventCuts::SetTrigClassPatterns ( const TString trigPattern )
235 {
236   /// Set trigger classes
237   ///
238   /// 1) specify trigger class pattern and reject pattern (wildcard * accepted)
239   /// Classes will be filled dynamycally according to the pattern
240   /// - if name contains ! (without spaces): reject it
241   /// - otherwise keep it
242   /// e.g. CMBAC*,!*ALLNOTRD*
243   /// keeps classes beginning with CMBAC, and not containing ALLNOTRD.
244   ///
245   /// CAVEATs:
246   ///   a ) if a wildcard is not specified, exact match is required
247   ///   b ) if you use an fCFContainer and you want an axis to contain the trigger classes,
248   ///       please be sure that each pattern matches only 1 trigger class, or triggers will be mixed up
249   ///       when merging different chuncks.
250   ///
251   ///
252   /// 2) specify a combination of triggers
253   /// combined through a logical AND "&" or a logical OR "|" (wildcard * NOT accepted)
254   /// It is also possible to ask for a trigger class containing a specific trigger input:
255   /// e.g. CMSL7-B-NOPF-MUON&0MSH,CMSL7-B-NOPF-MUON,CMSL7-B-NOPF-MUON|CMSL8-B-NOPF-MUON
256   /// will give the events with:
257   /// - the single low trigger class fired and containing a single high trigger input
258   /// - the single low trigger class fired
259   /// - the single low trigger class 7 or 8 fired
260   /// By default, when specific trigger combinations are provided, the most general case
261   /// based on trigger pattern is disabled...but it can be activated with the disableTrigPattern flag
262   ///
263   /// example:
264   /// SetTrigClassPatterns("CINT7*,!*-ACE-*,CMSL7-B-NOPF-MUON,CMSL7-B-NOPF-MUON&0MSH")
265   
266   
267   fSelectedTrigCombination->SetOwner();
268   if ( fSelectedTrigCombination->GetEntries() > 0 ) fSelectedTrigCombination->Delete();
269   fSelectedTrigPattern->SetOwner();
270   if ( fSelectedTrigPattern->GetEntries() > 0 ) fSelectedTrigPattern->Delete();
271   fRejectedTrigPattern->SetOwner();
272   if ( fRejectedTrigPattern->GetEntries() > 0 ) fRejectedTrigPattern->Delete();
273   
274   TString badSyntax = "", duplicated = "";
275   TString listName[4] = {"L0","L1","L2","trigClass"};
276   
277   TString pattern(trigPattern);
278   pattern.ReplaceAll(" ","");
279   TObjArray* fullList = pattern.Tokenize(",");
280   TIter next(fullList);
281   TObjString* objString = 0x0;
282   
283   TObjArray combinationList;
284   // First search for patterns
285   while ( ( objString = static_cast<TObjString*>(next()) ) ) {
286     TString currPattern = objString->String();
287     Bool_t isCombination = ( currPattern.Contains("&") || currPattern.Contains("|") );
288     Bool_t isSingleTrigger = ( ! isCombination && ! currPattern.BeginsWith("0") && ! currPattern.BeginsWith("1") && ! currPattern.BeginsWith("2") );
289     Bool_t isMatchPattern = ( currPattern.Contains("*") || isSingleTrigger );
290     Bool_t isRejectPattern = kFALSE;
291     if ( currPattern.Contains("!") ) {
292       currPattern.ReplaceAll("!","");
293       isRejectPattern = kTRUE;
294     }
295     if ( isCombination && ( isMatchPattern || isRejectPattern ) ) {
296       badSyntax += Form(" %s;", currPattern.Data());
297       continue;
298     }
299     if ( isRejectPattern ) {
300       fRejectedTrigPattern->AddLast(new TObjString(currPattern));
301       AliDebug(1,Form("Adding %s to reject pattern",currPattern.Data()));
302     }
303     else if ( isMatchPattern ) {
304       fSelectedTrigPattern->AddLast(new TObjString(currPattern));
305       AliDebug(1,Form("Adding %s to match pattern",currPattern.Data()));
306     }
307     else combinationList.Add(objString);
308   }
309   
310   // Then check for combinations
311   TIter nextCombo(&combinationList);
312   while ( ( objString = static_cast<TObjString*>(nextCombo()) ) ) {
313     TString currPattern = objString->String();
314     
315     TString tn (currPattern);
316     Bool_t hasAND = kFALSE, hasOR = kFALSE;
317     if ( tn.Contains("&") ) {
318       tn.ReplaceAll("&",":");
319       hasAND = kTRUE;
320     }
321     if ( tn.Contains("|") ) {
322       tn.ReplaceAll("|",":");
323       hasOR = kTRUE;
324     }
325     if ( tn.Contains("(") || tn.Contains(")") ) {
326       tn.ReplaceAll("(","");
327       tn.ReplaceAll(")","");
328     }
329     
330     if ( ! hasAND && ! hasOR ) {
331       if ( CheckTriggerClassPattern(currPattern) ) {
332         duplicated += Form("%s ", currPattern.Data());
333         continue;
334       }
335     }
336     
337     TObjArray* trigCombo = new TObjArray();
338     trigCombo->SetOwner();
339     trigCombo->SetName(currPattern.Data());
340     
341     UInt_t uniqueID = kComboSimple;
342     if ( hasAND && hasOR ) uniqueID = kComboFormula;
343     else if ( hasAND ) uniqueID = kComboAND;
344     else if ( hasOR ) uniqueID = kComboOR;
345     
346     trigCombo->SetUniqueID(uniqueID);
347     
348     TObjArray* arr = tn.Tokenize(":");
349     
350     TIter nextA(arr);
351     TObjString* an = 0x0;
352     while ( ( an = static_cast<TObjString*>(nextA()) ) )
353     {
354       Int_t listIdx = 3;
355       if ( an->String().BeginsWith("0") ) listIdx = 0;
356       else if ( an->String().BeginsWith("1") ) listIdx = 1;
357       else if ( an->String().BeginsWith("2") ) listIdx = 2;
358       
359       TObjArray* currList = static_cast<TObjArray*>(trigCombo->FindObject(listName[listIdx].Data()));
360       if ( ! currList ) {
361         currList = new TObjArray();
362         currList->SetOwner();
363         currList->SetName(listName[listIdx].Data());
364         currList->SetUniqueID(listIdx);
365         trigCombo->AddAt(currList,listIdx);
366       }
367       TObjString* currStr = new TObjString(an->String());
368       
369       if ( listIdx < 3 ) {
370         // that's an input
371         TObject* trigInput = fTrigInputsMap->FindObject(an->String().Data());
372         if ( trigInput ) currStr->SetUniqueID(trigInput->GetUniqueID());
373         else {
374           AliError(Form("Uknown input %s in formula %s", an->String().Data(), currPattern.Data()));
375           delete trigCombo;
376           trigCombo = 0x0;
377           break;
378         }
379       }
380       currList->AddLast(currStr);
381     }
382     delete arr;
383     if ( trigCombo) {
384       fSelectedTrigCombination->AddLast(trigCombo);
385       AliDebug(1,Form("Adding %s to trigger combination (type %u)",currPattern.Data(),trigCombo->GetUniqueID()));
386     }
387   }
388   delete fullList;
389   
390   if ( ! duplicated.IsNull() )
391     AliWarning(Form("Triggers %s already accounted in patterns",duplicated.Data()));
392   if ( ! badSyntax.IsNull() )
393     AliWarning(Form("%s : illegal expressions. Must be in the form:\n   pattern* => keep class if it contains pattern\n   !pattern* => reject class if it contains pattern\n   class&input = keep class if it satisfies the expression (exact matching required)",badSyntax.Data()));
394 }
395
396
397 //________________________________________________________________________
398 void AliMuonEventCuts::SetTrigClassLevels ( TString pattern )
399 {
400   /// Set trigger cut level associated to the trigger class
401   ///
402   /// example:
403   /// SetTrigClassLevels("MSL:Lpt,MSH:Hpt,MUL:LptLpt")
404   ///
405   /// For the trigger classes defined in SetTrigClassPatterns
406   /// it check if they contains the keywords MSL or MSH
407   /// Hence, in the analysis, the function
408   /// TrackPtCutMatchTrigClass(track, "CPBIMSL") returns true if track match Lpt
409   /// TrackPtCutMatchTrigClass(track, "CPBIMSH") returns true if track match Hpt
410   /// TrackPtCutMatchTrigClass(track, "CMBAC") always returns true
411   
412   fSelectedTrigLevel->SetOwner();
413   if ( fSelectedTrigLevel->GetEntries() > 0 ) fSelectedTrigLevel->Delete();
414   
415   pattern.ReplaceAll(" ","");
416   
417   TObjArray* fullList = pattern.Tokenize(",");
418   UInt_t offset = 2;
419   for ( Int_t ipat=0; ipat<fullList->GetEntries(); ++ipat ) {
420     TString currPattern = fullList->At(ipat)->GetName();
421     TObjArray* arr = currPattern.Tokenize(":");
422     TObjString* trigClassPattern = new TObjString(arr->At(0)->GetName());
423     TString selTrigLevel = arr->At(1)->GetName();
424     selTrigLevel.ToUpper();
425     UInt_t trigLevel = 0;
426     if ( selTrigLevel.Contains("LPT") ) {
427       trigLevel = 2;
428       if ( selTrigLevel.Contains("LPTLPT") ) trigLevel += 2<<offset;
429     }
430     else if ( selTrigLevel.Contains("HPT") ) {
431       trigLevel = 3;
432       if ( selTrigLevel.Contains("HPTHPT") ) trigLevel += 3<<offset;
433     }
434     trigClassPattern->SetUniqueID(trigLevel);
435     fSelectedTrigLevel->AddLast(trigClassPattern);
436     delete arr;
437   }
438   
439   delete fullList;
440 }
441
442 //________________________________________________________________________
443 UInt_t AliMuonEventCuts::GetTriggerInputBitMaskFromInputName(const char* inputName) const
444 {
445   // Get trigger input bit from its name
446   
447   if (!fTrigInputsMap)
448   {
449     AliError("No Inputs Map available");
450     return TMath::Limits<UInt_t>::Max();
451   }
452   
453   TObjString* s = static_cast<TObjString*>(fTrigInputsMap->FindObject(inputName));
454   if (!s)
455   {
456     AliError(Form("Did not find input %s",inputName));
457     return TMath::Limits<UInt_t>::Max();    
458   }
459   return s->GetUniqueID();
460 }
461
462 //________________________________________________________________________
463 TArrayI AliMuonEventCuts::GetTrigClassPtCutLevel ( const TString trigClassName ) const
464 {
465   /// Get trigger class pt cut level for tracking/trigger matching
466   ///
467   /// CAVEAT: this functionality fully works with trigger class names,
468   ///   but it can have a problem to extract the correct information in
469   ///   combinations of trigger classes/inputs. In this case it provides:
470   ///   - the highest pt level among classes/inputs combined through a logical AND "&"
471   ///   - the lowest pt level among classes/inputs combined through a logical OR "|"
472   ///   The first should be fine, but the second could not be the proper matching.
473   TObject* obj = fAllSelectedTrigClasses->FindObject(trigClassName.Data());
474   if ( ! obj ) {
475     AliWarning(Form("Class %s not in the list!", trigClassName.Data()));
476     return -1;
477   }
478   
479   TArrayI ptCutLevel(2);
480   ptCutLevel.Reset();
481   ptCutLevel[0] = obj->GetUniqueID() & 0x3;
482   ptCutLevel[1] = ( obj->GetUniqueID() >> 2 ) & 0x3;
483   
484   AliDebug(3,Form("Class %s ptCutLevel %i %i",trigClassName.Data(),ptCutLevel[0],ptCutLevel[1]));
485   
486   return ptCutLevel;
487 }
488
489
490 //________________________________________________________________________
491 void AliMuonEventCuts::SetTrigInputsMap ( TString trigInputsMap )
492 {
493   /// Set trigger input mask
494   /// The inputs must be in the form:
495   /// input1:ID1,input2:ID2,...
496   /// CAVEAT: the input ID is ID_aliceLogbook - 1
497   /// since this is the ID in the OCDB
498   
499   fTrigInputsMap->SetOwner();
500   if ( fTrigInputsMap->GetEntries() > 0 ) fTrigInputsMap->Delete();
501   
502   trigInputsMap.ReplaceAll(" ","");
503   
504   TObjArray* fullList = trigInputsMap.Tokenize(",");
505   for ( Int_t ipat=0; ipat<fullList->GetEntries(); ++ipat ) {
506     TString currPattern = fullList->At(ipat)->GetName();
507     TObjArray* arr = currPattern.Tokenize(":");
508     TObjString* trigInput = new TObjString(arr->At(0)->GetName());
509     UInt_t trigID = (UInt_t)static_cast<TObjString*>(arr->At(1))->GetString().Atoi();
510     trigInput->SetUniqueID(1<<trigID);
511     fTrigInputsMap->Add(trigInput);
512     delete arr;
513   }
514   delete fullList;
515 }
516
517 //________________________________________________________________________
518 void AliMuonEventCuts::SetDefaultTrigInputsMap ()
519 {
520   /// Set default trigger input mask
521   
522   TString trigInputsMap = "0VBA:0,";
523   trigInputsMap += "0VBC:1,";
524   trigInputsMap += "0SMB:2,";
525   trigInputsMap += "0TVX:3,";
526   trigInputsMap += "0VGC:4,";
527   trigInputsMap += "0VGA:5,";
528   trigInputsMap += "0SH1:6,";
529   trigInputsMap += "0SH2:7,";
530   trigInputsMap += "0HPT:8,";
531   trigInputsMap += "0AMU:9,";
532   trigInputsMap += "0OB0:10,";
533   trigInputsMap += "0ASL:11,";
534   trigInputsMap += "0MSL:12,";
535   trigInputsMap += "0MSH:13,";
536   trigInputsMap += "0MUL:14,";
537   trigInputsMap += "0MLL:15,";
538   trigInputsMap += "0EMC:16,";
539   trigInputsMap += "0PH0:17,";
540   trigInputsMap += "0HWU:18,";
541   trigInputsMap += "0LSR:19,";
542   trigInputsMap += "0T0A:20,";
543   trigInputsMap += "0BPA:21,";
544   trigInputsMap += "0BPC:22,";
545   trigInputsMap += "0T0C:23,";
546   
547   trigInputsMap += "1EJE:0,";
548   trigInputsMap += "1EGA:1,";
549   trigInputsMap += "1EJ2:2,";
550   trigInputsMap += "1EG2:3,";
551   trigInputsMap += "1PHL:4,";
552   trigInputsMap += "1PHM:5,";
553   trigInputsMap += "1PHH:6,";
554   trigInputsMap += "1HCO:8,";
555   trigInputsMap += "1HJT:9,";
556   trigInputsMap += "1HSE:10,";
557   trigInputsMap += "1DUM:11,";
558   trigInputsMap += "1HQU:12,";
559   trigInputsMap += "1H14:13,";
560   trigInputsMap += "1ZMD:14,";
561   trigInputsMap += "1ZMB:16,";
562   trigInputsMap += "1ZED:17,";
563   trigInputsMap += "1ZAC:18,";
564   trigInputsMap += "1EJE:19";
565   
566   SetTrigInputsMap(trigInputsMap);
567 }
568
569 //________________________________________________________________________
570 const TObjArray*
571 AliMuonEventCuts::GetSelectedTrigClassesInEvent(const TString& firedTriggerClasses,
572                                                 UInt_t l0Inputs, UInt_t l1Inputs,
573                                                 UInt_t l2Inputs)
574 {
575   /// Return the selected trigger classes in the fired trigger classes
576   /// give also the L0,L1,L2 input bit masks
577   
578   BuildTriggerClasses(firedTriggerClasses,l0Inputs,l1Inputs,l2Inputs);
579
580   return fSelectedTrigClassesInEvent;
581 }
582
583 //________________________________________________________________________
584 const TObjArray* AliMuonEventCuts::GetSelectedTrigClassesInEvent( const AliVEvent* event )
585 {
586   /// Return the selected trigger classes in the current event
587   UpdateEvent(event);
588   return fSelectedTrigClassesInEvent;
589 }
590
591
592 //________________________________________________________________________
593 void AliMuonEventCuts::BuildTriggerClasses ( const TString firedTrigClasses,
594                                              UInt_t l0Inputs, UInt_t l1Inputs, UInt_t l2Inputs )
595 {
596   //
597   /// Return the list of trigger classes to be considered
598   /// for current event. Update the global list if necessary
599   //
600   
601   AliDebug(2,Form("Fired classes: %s  Inputs 0x%x 0x%x 0x%x",firedTrigClasses.Data(),l0Inputs,l1Inputs,l2Inputs));
602   
603   if ( fSelectedTrigClassesInEvent) fSelectedTrigClassesInEvent->Delete();
604   else {
605     fSelectedTrigClassesInEvent = new TObjArray(0);
606     fSelectedTrigClassesInEvent->SetOwner();
607   }
608   
609
610   TString firedTrigClassesAny = "ANY " + firedTrigClasses;
611   
612   if ( fSelectedTrigPattern->GetEntries() > 0 ) {
613     TObjArray* firedTrigClassesList = firedTrigClassesAny.Tokenize(" ");
614   
615     for ( Int_t itrig=0; itrig<firedTrigClassesList->GetEntries(); ++itrig ) {
616       TString trigName = ((TObjString*)firedTrigClassesList->At(itrig))->GetString();
617
618       TObjString* foundTrig = static_cast<TObjString*>(fAllSelectedTrigClasses->FindObject(trigName.Data()));
619       if ( ! foundTrig ) {
620         if ( ! CheckTriggerClassPattern(trigName) ) continue;
621       }
622       
623       AddToEventSelectedClass ( trigName, foundTrig );
624     } // loop on trigger classes
625   
626     delete firedTrigClassesList;
627   }
628   
629   for ( Int_t icomb=0; icomb<fSelectedTrigCombination->GetEntries(); icomb++ ) {
630     TObjArray* currComb = static_cast<TObjArray*>(fSelectedTrigCombination->At(icomb));
631     if ( CheckTriggerClassCombination(currComb, firedTrigClassesAny, l0Inputs, l1Inputs, l2Inputs) ) {
632       TObjString* foundTrig = static_cast<TObjString*>(fAllSelectedTrigClasses->FindObject(currComb->GetName()));
633       AddToEventSelectedClass ( currComb->GetName(), foundTrig, currComb->GetUniqueID() );
634     }
635   }
636 }
637
638 //_____________________________________________________________________________
639 Bool_t
640 AliMuonEventCuts::CheckTriggerClassPattern ( const TString& toCheck ) const
641 {
642   // Check if the "toCheck" class matches the user pattern
643   
644   for ( Int_t ipat=0; ipat<fRejectedTrigPattern->GetEntries(); ++ipat ) {
645     if ( toCheck.Contains(TRegexp(fRejectedTrigPattern->At(ipat)->GetName(),kTRUE) ) ) return kFALSE;
646   } // loop on reject pattern
647
648   for ( Int_t ipat=0; ipat<fSelectedTrigPattern->GetEntries(); ++ipat ) {
649     if ( toCheck.Contains(TRegexp(fSelectedTrigPattern->At(ipat)->GetName(),kTRUE) ) ) return kTRUE;
650   } // loop on keep pattern
651   
652   return kFALSE;
653 }
654
655
656 //_____________________________________________________________________________
657 Bool_t
658 AliMuonEventCuts::CheckTriggerClassCombination ( const TObjArray* combo,
659                                                  const TString& firedTriggerClasses,
660                                                  UInt_t l0Inputs, UInt_t l1Inputs, UInt_t l2Inputs ) const
661 {
662   // Check if the "toCheck" class (or logical combination of classes and L0 inputs)
663   // are within the "firedTriggerClasses"
664   
665   Bool_t ok(kFALSE);
666   
667   TString comp(combo->GetName());
668   UInt_t trigInputs[3] = {l0Inputs, l1Inputs, l2Inputs};
669   
670   Bool_t exitLoop = kFALSE;
671   
672   TIter nextObj(combo);
673   TObjArray* currList = 0x0;
674   while ( ( currList = static_cast<TObjArray*>(nextObj()) ) ) {
675     Int_t listIdx = currList->GetUniqueID();
676     TIter nextA(currList);
677     TObjString* an = 0x0;
678     while ( ( an = static_cast<TObjString*>(nextA()) ) )
679     {
680       if ( listIdx < 3 ) {
681         UInt_t bit = an->GetUniqueID();
682         ok = ( (trigInputs[listIdx] & bit) == bit );
683       }
684       else {
685         TPRegexp re(Form("(^|[ ])%s([ ]|$)",an->String().Data()));
686         ok = firedTriggerClasses.Contains(re);
687       }
688       if ( combo->GetUniqueID() == kComboFormula ) comp.ReplaceAll(an->String().Data(),Form("%d",ok));
689       else if ( ( combo->GetUniqueID() == kComboAND && ! ok ) || ( combo->GetUniqueID() == kComboOR && ok ) ) {
690         exitLoop = kTRUE;
691         break;
692       }
693     }
694     if ( exitLoop ) break;
695   }
696   
697   if ( combo->GetUniqueID() == kComboFormula ) {
698     TFormula formula("TriggerClassFormulaCheck", comp.Data());
699     if ( formula.Compile() > 0 ) {
700       AliError(Form("Could not evaluate formula %s",comp.Data()));
701       ok = kFALSE;
702     }
703     else ok = formula.Eval(0);
704   }
705   
706   AliDebug(2,Form("tname %s => %d comp=%s  inputs 0x%x 0x%x 0x%x",combo->GetName(),ok,comp.Data(),l0Inputs, l1Inputs, l2Inputs));
707   
708   return ok;
709 }
710
711 //_____________________________________________________________________________
712 void
713 AliMuonEventCuts::AddToEventSelectedClass ( const TString& toCheck, const TObjString* foundTrig, const UInt_t comboType )
714 {
715   /// Add current trigger to the selected class for the event
716   
717   // Compute the trigger pt cut level of the current class
718   UInt_t trigLevel = 0;
719   if ( foundTrig ) trigLevel = foundTrig->GetUniqueID();
720   else {
721     // The assigned trigger pt cut level is:
722     // - the correct one if "toCheck" is a single trigger class
723     // - the highest pt cut among the matching ones in case "toCheck" is a trigger class/input
724     //   combined through (at least one) logical AND "&"
725     // - the lowest pt cut among the macthing ones in case "toCheck" is a trigger class/input
726     //   combined through (only) logical OR "|"
727     // This may lead to errors in case of complex combinations of trigger/inputs
728     Bool_t isFirst = kTRUE;
729     for ( Int_t ipat=0; ipat<fSelectedTrigLevel->GetEntries(); ++ipat ) {
730       if ( toCheck.Contains(fSelectedTrigLevel->At(ipat)->GetName() ) ) {
731         UInt_t currLevel = fSelectedTrigLevel->At(ipat)->GetUniqueID();
732         if ( comboType == kComboAND ) trigLevel = TMath::Max(trigLevel, currLevel);
733         else if ( comboType == kComboOR || comboType == kComboFormula ) {
734           if ( isFirst ) {
735             trigLevel = currLevel;
736             isFirst = kFALSE;
737           }
738           else trigLevel = TMath::Min(trigLevel, currLevel);
739         }
740         else {
741           trigLevel = currLevel;
742           break;
743         }
744       }
745     } // loop on trig level patterns
746   }
747   
748   TObjString* currTrig = new TObjString(toCheck);
749   currTrig->SetUniqueID(trigLevel);
750   fSelectedTrigClassesInEvent->AddLast(currTrig);
751   
752   if ( foundTrig ) return;
753   TObjString* addTrig = new TObjString(toCheck);
754   addTrig->SetUniqueID(trigLevel);
755   fAllSelectedTrigClasses->Add(addTrig);
756   TString trigLevelInfo = Form("trig level %i ", trigLevel & 0x3);
757   trigLevelInfo += ( trigLevel > 3 ) ? "di-muon" : "single-muon";
758   AliInfo(Form("Adding %s (%s) to considered trigger classes",toCheck.Data(),trigLevelInfo.Data()));
759 }
760
761 //________________________________________________________________________
762 void AliMuonEventCuts::SetCentralityClasses(Int_t nCentralityBins, Double_t* centralityBins)
763 {
764   //
765   /// Set centrality classes
766   //
767   Double_t* bins = centralityBins;
768   Int_t nbins = nCentralityBins;
769   
770   Double_t defaultCentralityBins[] = {-5., 0., 5., 10., 20., 30., 40., 50., 60., 70., 80., 90., 100., 105.};
771   if ( ! centralityBins ) {
772     bins = defaultCentralityBins;
773     nbins = sizeof(defaultCentralityBins)/sizeof(defaultCentralityBins[0])-1;
774   }
775   
776   TString centralityEstimator = "V0M";
777   if ( fCentralityClasses ) {
778     centralityEstimator = GetCentralityEstimator();
779     delete fCentralityClasses;
780   }
781   fCentralityClasses = new TAxis(nbins, bins);
782   TString currClass = "";
783   for ( Int_t ibin=1; ibin<=fCentralityClasses->GetNbins(); ++ibin ){
784     currClass = Form("%.0f_%.0f",fCentralityClasses->GetBinLowEdge(ibin),fCentralityClasses->GetBinUpEdge(ibin));
785     fCentralityClasses->SetBinLabel(ibin, currClass.Data());
786   }
787   
788   SetCentralityEstimator(centralityEstimator);
789 }
790
791 //________________________________________________________________________
792 void AliMuonEventCuts::SetCentralityEstimator ( const TString centralityEstimator )
793 {
794   /// Set centrality estimator
795   fCentralityClasses->SetName(centralityEstimator.Data());
796 }
797
798
799 //________________________________________________________________________
800 TString AliMuonEventCuts::GetCentralityEstimator () const
801 {
802   /// Get centrality estimator
803   return fCentralityClasses->GetName();
804 }
805
806 //________________________________________________________________________
807 Double_t AliMuonEventCuts::GetCentrality ( const AliVEvent* event ) const
808 {
809   /// Get centrality
810   AliVEvent* evt = const_cast<AliVEvent*>(event);
811   return evt->GetCentrality()->GetCentralityPercentile(GetCentralityEstimator());
812 }
813
814 //________________________________________________________________________
815 void AliMuonEventCuts::SetDefaultParameters ()
816 {
817   /// Standard parameters for muon event
818   SetPhysicsSelectionMask(AliVEvent::kAny);
819   SetVertexMinNContributors(1);
820   SetVertexVzLimits();
821 }
822
823
824 //________________________________________________________________________
825 void AliMuonEventCuts::SetDefaultFilterMask ()
826 {
827   /// Standard cuts for muon event
828   SetFilterMask ( kPhysicsSelected | kSelectedTrig | kGoodVertex );
829 }
830
831 //________________________________________________________________________
832 void AliMuonEventCuts::Print(Option_t* option) const
833 {
834   //
835   /// Print info
836   //
837   TString sopt(option);
838   sopt.ToLower();
839   if ( sopt.IsNull() || sopt.Contains("*") || sopt.Contains("all") ) sopt = "mask param";
840   UInt_t filterMask = GetFilterMask();
841   if ( sopt.Contains("mask") ) {
842     printf(" *** Muon event filter mask: *** \n");
843     printf("  0x%x\n", filterMask);
844     if ( filterMask & kPhysicsSelected ) printf("  Pass physics selection 0x%x\n", fPhysicsSelectionMask);
845     if ( filterMask & kSelectedCentrality ) printf(  "%g < centrality < %g\n", fCentralityClasses->GetXmin(), fCentralityClasses->GetXmax() );
846     if ( filterMask & kSelectedTrig )    printf("  Has selected trigger classes\n");
847     if ( filterMask & kGoodVertex )      printf("  SPD vertex with %i contributors && %g < Vz < %g\n", GetVertexMinNContributors(), GetVertexVzMin(), GetVertexVzMax());
848     printf(" ******************** \n");
849   }
850 }