1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
16 #include "AliMuonEventCuts.h"
20 #include "THashList.h"
21 #include "TObjArray.h"
22 #include "TObjString.h"
24 #include "TParameter.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 #include "AliAnalysisUtils.h"
41 #include "AliAnalysisMuonUtility.h"
44 ClassImp(AliMuonEventCuts) // Class implementation in ROOT context
48 //________________________________________________________________________
49 AliMuonEventCuts::AliMuonEventCuts() :
51 fPhysicsSelectionMask(0),
52 fVertexMinNContributors(0),
56 fSelectedTrigPattern(0x0),
57 fRejectedTrigPattern(0x0),
58 fSelectedTrigLevel(0x0),
59 fSelectedTrigCombination(0x0),
61 fAllSelectedTrigClasses(0x0),
62 fCentralityClasses(0x0),
65 fSelectedTrigClassesInEvent(0x0)
70 //________________________________________________________________________
71 AliMuonEventCuts::AliMuonEventCuts(const char* name, const char* title ) :
72 AliAnalysisCuts(name, title),
73 fPhysicsSelectionMask(0),
74 fVertexMinNContributors(0),
78 fSelectedTrigPattern(new TObjArray()),
79 fRejectedTrigPattern(new TObjArray()),
80 fSelectedTrigLevel(new TObjArray()),
81 fSelectedTrigCombination(new TObjArray()),
82 fTrigInputsMap(new THashList()),
83 fAllSelectedTrigClasses(new THashList()),
84 fCentralityClasses(0x0),
87 fSelectedTrigClassesInEvent(new TObjArray())
90 SetDefaultParameters();
91 SetDefaultFilterMask();
92 SetDefaultTrigClassPatterns();
94 SetCentralityClasses();
95 fAnalysisUtils = new AliAnalysisUtils();
96 fAllSelectedTrigClasses->SetOwner();
97 fSelectedTrigClassesInEvent->SetOwner();
100 //________________________________________________________________________
101 AliMuonEventCuts::AliMuonEventCuts(const AliMuonEventCuts& obj) :
102 AliAnalysisCuts(obj),
103 fPhysicsSelectionMask(obj.fPhysicsSelectionMask),
104 fVertexMinNContributors(obj.fVertexMinNContributors),
105 fVertexVzMin(obj.fVertexVzMin),
106 fVertexVzMax(obj.fVertexVzMax),
107 fCheckMask(obj.fCheckMask),
108 fSelectedTrigPattern(obj.fSelectedTrigPattern),
109 fRejectedTrigPattern(obj.fRejectedTrigPattern),
110 fSelectedTrigLevel(obj.fSelectedTrigLevel),
111 fSelectedTrigCombination(obj.fSelectedTrigCombination),
112 fTrigInputsMap(obj.fTrigInputsMap),
113 fAllSelectedTrigClasses(obj.fAllSelectedTrigClasses),
114 fCentralityClasses(obj.fCentralityClasses),
115 fAnalysisUtils(obj.fAnalysisUtils),
116 fEventTriggerMask(obj.fEventTriggerMask),
117 fSelectedTrigClassesInEvent(obj.fSelectedTrigClassesInEvent)
123 //________________________________________________________________________
124 AliMuonEventCuts& AliMuonEventCuts::operator=(const AliMuonEventCuts& obj)
126 /// Assignment operator
127 if ( this != &obj ) {
128 AliAnalysisCuts::operator=(obj);
129 fPhysicsSelectionMask = obj.fPhysicsSelectionMask;
130 fVertexMinNContributors = obj.fVertexMinNContributors,
131 fVertexVzMin = obj.fVertexVzMin;
132 fVertexVzMax = obj.fVertexVzMax;
133 fCheckMask = obj.fCheckMask;
134 delete fSelectedTrigPattern;
135 fSelectedTrigPattern = ( obj.fSelectedTrigPattern ) ? static_cast<TObjArray*>(obj.fSelectedTrigPattern->Clone() ) : 0x0;
136 delete fRejectedTrigPattern;
137 fRejectedTrigPattern = ( obj.fRejectedTrigPattern ) ? static_cast<TObjArray*>(obj.fRejectedTrigPattern->Clone() ) : 0x0;
138 delete fSelectedTrigLevel;
139 fSelectedTrigLevel = ( obj.fSelectedTrigLevel ) ? static_cast<TObjArray*>(obj.fSelectedTrigLevel->Clone() ) : 0x0;
140 delete fSelectedTrigCombination;
141 fSelectedTrigCombination = ( obj.fSelectedTrigCombination ) ? static_cast<TObjArray*>(obj.fSelectedTrigCombination->Clone() ) : 0x0;
142 delete fTrigInputsMap;
143 fTrigInputsMap = ( obj.fTrigInputsMap ) ? static_cast<TList*>(obj.fTrigInputsMap->Clone() ) : 0x0;
144 delete fAllSelectedTrigClasses;
145 fAllSelectedTrigClasses = ( obj.fAllSelectedTrigClasses ) ? static_cast<TList*>(obj.fAllSelectedTrigClasses->Clone() ) : 0x0;
146 delete fCentralityClasses;
147 fCentralityClasses = ( obj.fCentralityClasses ) ? static_cast<TAxis*>(obj.fCentralityClasses->Clone() ) : 0x0;
148 delete fAnalysisUtils;
149 fAnalysisUtils = ( obj.fAnalysisUtils ) ? static_cast<AliAnalysisUtils*>(obj.fAnalysisUtils->Clone() ) : 0x0;
150 fEventTriggerMask = obj.fEventTriggerMask;
151 delete fSelectedTrigClassesInEvent;
152 fSelectedTrigClassesInEvent = ( obj.fSelectedTrigClassesInEvent ) ? static_cast<TObjArray*>(obj.fSelectedTrigClassesInEvent->Clone() ) : 0x0;
158 //________________________________________________________________________
159 AliMuonEventCuts::~AliMuonEventCuts()
162 delete fSelectedTrigPattern;
163 delete fRejectedTrigPattern;
164 delete fSelectedTrigLevel;
165 delete fSelectedTrigCombination;
166 delete fTrigInputsMap;
167 delete fAllSelectedTrigClasses;
168 delete fSelectedTrigClassesInEvent;
169 delete fCentralityClasses;
170 delete fAnalysisUtils;
173 //________________________________________________________________________
174 Bool_t AliMuonEventCuts::IsSelected( TObject* obj )
176 /// Track is selected
177 UInt_t filterMask = GetFilterMask();
178 UInt_t selectionMask = GetSelectionMask(obj);
180 AliDebug(1, Form("Is event selected %i mask 0x%x", ( selectionMask & filterMask ) == filterMask, selectionMask ));
182 return ( ( selectionMask & filterMask ) == filterMask );
186 //________________________________________________________________________
187 UInt_t AliMuonEventCuts::GetSelectionMask( const TObject* obj )
189 /// Get selection mask
191 UInt_t selectionMask = 0;
193 UInt_t checkMask = fCheckMask | GetFilterMask();
195 const AliInputEventHandler* inputHandler = static_cast<const AliInputEventHandler*> ( obj );
197 if ( checkMask & kPhysicsSelected ) {
198 if ( const_cast<AliInputEventHandler*>(inputHandler)->IsEventSelected() & fPhysicsSelectionMask ) selectionMask |= kPhysicsSelected;
201 const AliVEvent* event = inputHandler->GetEvent();
203 Double_t centrality = GetCentrality(event);
204 if ( centrality >= fCentralityClasses->GetXmin() && centrality <= fCentralityClasses->GetXmax() ) selectionMask |= kSelectedCentrality;
208 if ( fSelectedTrigClassesInEvent->GetEntries() > 0 ) selectionMask |= kSelectedTrig;
210 if ( checkMask & kGoodVertex ) {
211 AliVVertex* vertex = AliAnalysisMuonUtility::GetVertexSPD(event);
212 if ( vertex->GetNContributors() >= GetVertexMinNContributors() &&
213 vertex->GetZ() >= GetVertexVzMin() && vertex->GetZ() <= GetVertexVzMax() ) selectionMask |= kGoodVertex;
216 if ( checkMask & kNoPileup ) {
217 if ( ! fAnalysisUtils->IsPileUpEvent(const_cast<AliVEvent*>(event)) ) selectionMask |= kNoPileup;
218 // // Uncomment to use settings for pPb
219 // if ( fRejectPileup ) {
220 // Int_t nTracklets = ( event.IsA() == AliESDEvent::Class() ) ? static_cast<AliESDEvent*>(event)->GetMultiplicity()->GetNumberOfTracklets() : static_cast<AliAODEvent*>(event)->GetTracklets()->GetNumberOfTracklets();
221 // Int_t nContrib = ( nTracklets < 40 ) ? 3 : 5;
222 // Double_t dist = 0.8;
223 // Bool_t isPielup = ( event.IsA() == AliESDEvent::Class() ) ? static_cast<AliESDEvent*>(event)->IsPileupFromSPD(nContrib,dist) : static_cast<AliAODEvent*>(event)->IsPileupFromSPD(nContrib,dist);
224 // if ( isPielup ) return;
228 AliDebug(1, Form("Selection mask 0x%x\n", selectionMask));
229 return selectionMask;
233 //________________________________________________________________________
234 Bool_t AliMuonEventCuts::IsSelected( TList* /* list */)
237 AliError("Function not implemented: Use IsSelected(TObject*)");
241 //________________________________________________________________________
242 Bool_t AliMuonEventCuts::UpdateEvent ( const AliVEvent* event )
244 /// Update the transient data member per event
246 if ( fSelectedTrigClassesInEvent && ( fEventTriggerMask == event->GetTriggerMask() ) ) return kFALSE;
248 BuildTriggerClasses(AliAnalysisMuonUtility::GetFiredTriggerClasses(event), AliAnalysisMuonUtility::GetL0TriggerInputs(event), AliAnalysisMuonUtility::GetL1TriggerInputs(event), AliAnalysisMuonUtility::GetL2TriggerInputs(event));
250 fEventTriggerMask = event->GetTriggerMask();
255 //________________________________________________________________________
256 TString AliMuonEventCuts::GetDefaultTrigClassPatterns () const
258 /// Get the default patterns
259 /// (done in such a way to get all muon triggers)
260 return "CM*,C0M*,CINT*,CPBI*,CCENT*,CV*,!*ABCE*,!*-ACE-*,!*-AC-*,!*-E-*,!*WU*,!*EGA*,!*EJE*,!*PHS*";
263 //________________________________________________________________________
264 TString AliMuonEventCuts::GetDefaultTrigInputsMap () const
266 /// Get the default trigger inputs
269 TString trigInputsMap = "0VBA:0,";
270 trigInputsMap += "0VBC:1,";
271 trigInputsMap += "0SMB:2,";
272 trigInputsMap += "0TVX:3,";
273 trigInputsMap += "0VGC:4,";
274 trigInputsMap += "0VGA:5,";
275 trigInputsMap += "0SH1:6,";
276 trigInputsMap += "0SH2:7,";
277 trigInputsMap += "0HPT:8,";
278 trigInputsMap += "0AMU:9,";
279 trigInputsMap += "0OB0:10,";
280 trigInputsMap += "0ASL:11,";
281 trigInputsMap += "0MSL:12,";
282 trigInputsMap += "0MSH:13,";
283 trigInputsMap += "0MUL:14,";
284 trigInputsMap += "0MLL:15,";
285 trigInputsMap += "0EMC:16,";
286 trigInputsMap += "0PH0:17,";
287 trigInputsMap += "0HWU:18,";
288 trigInputsMap += "0LSR:19,";
289 trigInputsMap += "0T0A:20,";
290 trigInputsMap += "0BPA:21,";
291 trigInputsMap += "0BPC:22,";
292 trigInputsMap += "0T0C:23,";
294 trigInputsMap += "1EJE:0,";
295 trigInputsMap += "1EGA:1,";
296 trigInputsMap += "1EJ2:2,";
297 trigInputsMap += "1EG2:3,";
298 trigInputsMap += "1PHL:4,";
299 trigInputsMap += "1PHM:5,";
300 trigInputsMap += "1PHH:6,";
301 trigInputsMap += "1HCO:8,";
302 trigInputsMap += "1HJT:9,";
303 trigInputsMap += "1HSE:10,";
304 trigInputsMap += "1DUM:11,";
305 trigInputsMap += "1HQU:12,";
306 trigInputsMap += "1H14:13,";
307 trigInputsMap += "1ZMD:14,";
308 trigInputsMap += "1ZMB:16,";
309 trigInputsMap += "1ZED:17,";
310 trigInputsMap += "1ZAC:18,";
311 trigInputsMap += "1EJE:19";
313 return trigInputsMap;
316 //________________________________________________________________________
317 void AliMuonEventCuts::SetDefaultTrigClassPatterns ()
319 /// Set the default patterns
320 /// (done in such a way to get all muon triggers)
321 SetTrigClassPatterns(GetDefaultTrigClassPatterns(),GetDefaultTrigInputsMap());
325 //________________________________________________________________________
326 void AliMuonEventCuts::SetTrigClassPatterns ( TString trigPattern, TString trigInputsMap )
328 /// Set trigger classes
330 /// 1) specify trigger class pattern and reject pattern (wildcard * accepted)
331 /// Classes will be filled dynamycally according to the pattern
332 /// - if name contains ! (without spaces): reject it
333 /// - otherwise keep it
334 /// e.g. CMBAC*,!*ALLNOTRD*
335 /// keeps classes beginning with CMBAC, and not containing ALLNOTRD.
338 /// a ) if a wildcard is not specified, exact match is required
339 /// b ) if you use an fCFContainer and you want an axis to contain the trigger classes,
340 /// please be sure that each pattern matches only 1 trigger class, or triggers will be mixed up
341 /// when merging different chuncks.
344 /// 2) specify a combination of triggers
345 /// combined through a logical AND "&" or a logical OR "|" (wildcard * NOT accepted)
346 /// It is also possible to ask for a trigger class containing a specific trigger input:
347 /// e.g. CMSL7-B-NOPF-MUON&0MSH,CMSL7-B-NOPF-MUON,CMSL7-B-NOPF-MUON|CMSL8-B-NOPF-MUON
348 /// will give the events with:
349 /// - the single low trigger class fired and containing a single high trigger input
350 /// - the single low trigger class fired
351 /// - the single low trigger class 7 or 8 fired
352 /// By default, when specific trigger combinations are provided, the most general case
353 /// based on trigger pattern is disabled...but it can be activated with the disableTrigPattern flag
356 /// SetTrigClassPatterns("CINT7*,!*-ACE-*,CMSL7-B-NOPF-MUON,CMSL7-B-NOPF-MUON&0MSH")
359 fSelectedTrigCombination->SetOwner();
360 if ( fSelectedTrigCombination->GetEntries() > 0 ) fSelectedTrigCombination->Delete();
361 fSelectedTrigPattern->SetOwner();
362 if ( fSelectedTrigPattern->GetEntries() > 0 ) fSelectedTrigPattern->Delete();
363 fRejectedTrigPattern->SetOwner();
364 if ( fRejectedTrigPattern->GetEntries() > 0 ) fRejectedTrigPattern->Delete();
366 SetTrigInputsMap(trigInputsMap);
368 TString badSyntax = "", duplicated = "";
369 TString listName[4] = {"L0","L1","L2","trigClass"};
371 TString pattern(trigPattern);
372 pattern.ReplaceAll(" ","");
373 TObjArray* fullList = pattern.Tokenize(",");
374 TIter next(fullList);
375 TObjString* objString = 0x0;
377 TObjArray combinationList;
378 // First search for patterns
379 while ( ( objString = static_cast<TObjString*>(next()) ) ) {
380 TString currPattern = objString->String();
381 Bool_t isCombination = ( currPattern.Contains("&") || currPattern.Contains("|") );
382 Bool_t isSingleTrigger = ( ! isCombination && ! currPattern.BeginsWith("0") && ! currPattern.BeginsWith("1") && ! currPattern.BeginsWith("2") );
383 Bool_t isMatchPattern = ( currPattern.Contains("*") || isSingleTrigger );
384 Bool_t isRejectPattern = kFALSE;
385 if ( isMatchPattern && currPattern.Contains("!") ) {
386 currPattern.ReplaceAll("!","");
387 isRejectPattern = kTRUE;
389 if ( isCombination && ( isMatchPattern || isRejectPattern ) ) {
390 badSyntax += Form(" %s;", currPattern.Data());
393 if ( isRejectPattern ) {
394 fRejectedTrigPattern->AddLast(new TObjString(currPattern));
395 AliDebug(1,Form("Adding %s to reject pattern",currPattern.Data()));
397 else if ( isMatchPattern ) {
398 fSelectedTrigPattern->AddLast(new TObjString(currPattern));
399 AliDebug(1,Form("Adding %s to match pattern",currPattern.Data()));
401 else combinationList.Add(objString);
404 // Then check for combinations
405 TIter nextCombo(&combinationList);
406 while ( ( objString = static_cast<TObjString*>(nextCombo()) ) ) {
407 TString currPattern = objString->String();
409 TString tn (currPattern);
410 Bool_t hasAND = kFALSE, hasOR = kFALSE, hasNOT = kFALSE;
411 if ( tn.Contains("&") ) {
412 tn.ReplaceAll("&",":");
415 if ( tn.Contains("|") ) {
416 tn.ReplaceAll("|",":");
419 if ( tn.Contains("!") ) {
420 tn.ReplaceAll("!","");
423 if ( tn.Contains("(") || tn.Contains(")") ) {
424 tn.ReplaceAll("(","");
425 tn.ReplaceAll(")","");
428 if ( ! hasAND && ! hasOR && ! hasNOT ) {
429 if ( CheckTriggerClassPattern(currPattern) ) {
430 duplicated += Form("%s ", currPattern.Data());
435 TObjArray* trigCombo = new TObjArray();
436 trigCombo->SetOwner();
437 trigCombo->SetName(currPattern.Data());
439 UInt_t uniqueID = kComboSimple;
440 if ( ( hasAND && hasOR ) || hasNOT ) uniqueID = kComboFormula;
441 else if ( hasAND ) uniqueID = kComboAND;
442 else if ( hasOR ) uniqueID = kComboOR;
444 trigCombo->SetUniqueID(uniqueID);
446 TObjArray* arr = tn.Tokenize(":");
449 TObjString* an = 0x0;
450 while ( ( an = static_cast<TObjString*>(nextA()) ) )
453 if ( an->String().BeginsWith("0") ) listIdx = 0;
454 else if ( an->String().BeginsWith("1") ) listIdx = 1;
455 else if ( an->String().BeginsWith("2") ) listIdx = 2;
457 TObjArray* currList = static_cast<TObjArray*>(trigCombo->FindObject(listName[listIdx].Data()));
459 currList = new TObjArray();
460 currList->SetOwner();
461 currList->SetName(listName[listIdx].Data());
462 currList->SetUniqueID(listIdx);
463 trigCombo->AddAt(currList,listIdx);
465 TObjString* currStr = new TObjString(an->String());
469 TObject* trigInput = fTrigInputsMap->FindObject(an->String().Data());
470 if ( trigInput ) currStr->SetUniqueID(trigInput->GetUniqueID());
472 AliError(Form("Uknown input %s in formula %s", an->String().Data(), currPattern.Data()));
478 currList->AddLast(currStr);
482 fSelectedTrigCombination->AddLast(trigCombo);
483 AliDebug(1,Form("Adding %s to trigger combination (type %u)",currPattern.Data(),trigCombo->GetUniqueID()));
488 if ( ! duplicated.IsNull() )
489 AliWarning(Form("Triggers %s already accounted in patterns",duplicated.Data()));
490 if ( ! badSyntax.IsNull() )
491 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()));
495 //________________________________________________________________________
496 void AliMuonEventCuts::SetTrigClassLevels ( TString pattern )
498 /// Set trigger cut level associated to the trigger class
501 /// SetTrigClassLevels("MSL:Lpt,MSH:Hpt,MUL:LptLpt")
503 /// For the trigger classes defined in SetTrigClassPatterns
504 /// it check if they contains the keywords MSL or MSH
505 /// Hence, in the analysis, the function
506 /// TrackPtCutMatchTrigClass(track, "CPBIMSL") returns true if track match Lpt
507 /// TrackPtCutMatchTrigClass(track, "CPBIMSH") returns true if track match Hpt
508 /// TrackPtCutMatchTrigClass(track, "CMBAC") always returns true
510 fSelectedTrigLevel->SetOwner();
511 if ( fSelectedTrigLevel->GetEntries() > 0 ) fSelectedTrigLevel->Delete();
513 pattern.ReplaceAll(" ","");
515 TObjArray* fullList = pattern.Tokenize(",");
517 for ( Int_t ipat=0; ipat<fullList->GetEntries(); ++ipat ) {
518 TString currPattern = fullList->At(ipat)->GetName();
519 TObjArray* arr = currPattern.Tokenize(":");
520 TObjString* trigClassPattern = new TObjString(arr->At(0)->GetName());
521 TString selTrigLevel = arr->At(1)->GetName();
522 selTrigLevel.ToUpper();
523 UInt_t trigLevel = 0;
524 if ( selTrigLevel.Contains("LPT") ) {
526 if ( selTrigLevel.Contains("LPTLPT") ) trigLevel += 2<<offset;
528 else if ( selTrigLevel.Contains("HPT") ) {
530 if ( selTrigLevel.Contains("HPTHPT") ) trigLevel += 3<<offset;
532 trigClassPattern->SetUniqueID(trigLevel);
533 fSelectedTrigLevel->AddLast(trigClassPattern);
540 //________________________________________________________________________
541 UInt_t AliMuonEventCuts::GetTriggerInputBitMaskFromInputName(const char* inputName) const
543 // Get trigger input bit from its name
547 AliError("No Inputs Map available");
548 return TMath::Limits<UInt_t>::Max();
551 TObjString* s = static_cast<TObjString*>(fTrigInputsMap->FindObject(inputName));
554 AliError(Form("Did not find input %s",inputName));
555 return TMath::Limits<UInt_t>::Max();
557 return s->GetUniqueID();
560 //________________________________________________________________________
561 TArrayI AliMuonEventCuts::GetTrigClassPtCutLevel ( TString trigClassName ) const
563 /// Get trigger class pt cut level for tracking/trigger matching
565 /// CAVEAT: this functionality fully works with trigger class names,
566 /// but it can have a problem to extract the correct information in
567 /// combinations of trigger classes/inputs. In this case it provides:
568 /// - the highest pt level among classes/inputs combined through a logical AND "&"
569 /// - the lowest pt level among classes/inputs combined through a logical OR "|"
570 /// The first should be fine, but the second could not be the proper matching.
571 TObject* obj = fAllSelectedTrigClasses->FindObject(trigClassName.Data());
573 AliWarning(Form("Class %s not in the list!", trigClassName.Data()));
577 TArrayI ptCutLevel(2);
579 ptCutLevel[0] = obj->GetUniqueID() & 0x3;
580 ptCutLevel[1] = ( obj->GetUniqueID() >> 2 ) & 0x3;
582 AliDebug(3,Form("Class %s ptCutLevel %i %i",trigClassName.Data(),ptCutLevel[0],ptCutLevel[1]));
588 //________________________________________________________________________
589 void AliMuonEventCuts::SetTrigInputsMap ( TString trigInputsMap )
591 /// Set trigger input mask
592 /// The inputs must be in the form:
593 /// input1:ID1,input2:ID2,...
594 /// CAVEAT: the input ID is ID_aliceLogbook - 1
595 /// since this is the ID in the OCDB
597 fTrigInputsMap->SetOwner();
598 if ( fTrigInputsMap->GetEntries() > 0 ) fTrigInputsMap->Delete();
600 if ( trigInputsMap.IsNull() ) {
601 AliWarning("Trigger input map not specified: using default");
602 trigInputsMap = GetDefaultTrigInputsMap();
605 trigInputsMap.ReplaceAll(" ","");
607 TObjArray* fullList = trigInputsMap.Tokenize(",");
608 for ( Int_t ipat=0; ipat<fullList->GetEntries(); ++ipat ) {
609 TString currPattern = fullList->At(ipat)->GetName();
610 TObjArray* arr = currPattern.Tokenize(":");
611 TObjString* trigInput = new TObjString(arr->At(0)->GetName());
612 UInt_t trigID = (UInt_t)static_cast<TObjString*>(arr->At(1))->GetString().Atoi();
613 trigInput->SetUniqueID(1<<trigID);
614 fTrigInputsMap->Add(trigInput);
620 //________________________________________________________________________
622 AliMuonEventCuts::GetSelectedTrigClassesInEvent(const TString& firedTriggerClasses,
623 UInt_t l0Inputs, UInt_t l1Inputs,
626 /// Return the selected trigger classes in the fired trigger classes
627 /// give also the L0,L1,L2 input bit masks
629 BuildTriggerClasses(firedTriggerClasses,l0Inputs,l1Inputs,l2Inputs);
631 return fSelectedTrigClassesInEvent;
634 //________________________________________________________________________
635 const TObjArray* AliMuonEventCuts::GetSelectedTrigClassesInEvent( const AliVEvent* event )
637 /// Return the selected trigger classes in the current event
639 return fSelectedTrigClassesInEvent;
643 //________________________________________________________________________
644 void AliMuonEventCuts::BuildTriggerClasses ( TString firedTrigClasses,
645 UInt_t l0Inputs, UInt_t l1Inputs, UInt_t l2Inputs )
648 /// Return the list of trigger classes to be considered
649 /// for current event. Update the global list if necessary
652 AliDebug(2,Form("Fired classes: %s Inputs 0x%x 0x%x 0x%x",firedTrigClasses.Data(),l0Inputs,l1Inputs,l2Inputs));
654 if ( fSelectedTrigClassesInEvent) fSelectedTrigClassesInEvent->Delete();
656 fSelectedTrigClassesInEvent = new TObjArray(0);
657 fSelectedTrigClassesInEvent->SetOwner();
661 TString firedTrigClassesAny = "ANY " + firedTrigClasses;
663 if ( fSelectedTrigPattern->GetEntries() > 0 ) {
664 TObjArray* firedTrigClassesList = firedTrigClassesAny.Tokenize(" ");
666 for ( Int_t itrig=0; itrig<firedTrigClassesList->GetEntries(); ++itrig ) {
667 TString trigName = ((TObjString*)firedTrigClassesList->At(itrig))->GetString();
669 TObjString* foundTrig = static_cast<TObjString*>(fAllSelectedTrigClasses->FindObject(trigName.Data()));
671 if ( ! CheckTriggerClassPattern(trigName) ) continue;
674 AddToEventSelectedClass ( trigName, foundTrig );
675 } // loop on trigger classes
677 delete firedTrigClassesList;
680 for ( Int_t icomb=0; icomb<fSelectedTrigCombination->GetEntries(); icomb++ ) {
681 TObjArray* currComb = static_cast<TObjArray*>(fSelectedTrigCombination->At(icomb));
682 if ( CheckTriggerClassCombination(currComb, firedTrigClassesAny, l0Inputs, l1Inputs, l2Inputs) ) {
683 TObjString* foundTrig = static_cast<TObjString*>(fAllSelectedTrigClasses->FindObject(currComb->GetName()));
684 AddToEventSelectedClass ( currComb->GetName(), foundTrig, currComb->GetUniqueID() );
689 //_____________________________________________________________________________
691 AliMuonEventCuts::CheckTriggerClassPattern ( const TString& toCheck ) const
693 // Check if the "toCheck" class matches the user pattern
695 for ( Int_t ipat=0; ipat<fRejectedTrigPattern->GetEntries(); ++ipat ) {
696 if ( toCheck.Contains(TRegexp(fRejectedTrigPattern->At(ipat)->GetName(),kTRUE) ) ) return kFALSE;
697 } // loop on reject pattern
699 for ( Int_t ipat=0; ipat<fSelectedTrigPattern->GetEntries(); ++ipat ) {
700 if ( toCheck.Contains(TRegexp(fSelectedTrigPattern->At(ipat)->GetName(),kTRUE) ) ) return kTRUE;
701 } // loop on keep pattern
707 //_____________________________________________________________________________
709 AliMuonEventCuts::CheckTriggerClassCombination ( const TObjArray* combo,
710 const TString& firedTriggerClasses,
711 UInt_t l0Inputs, UInt_t l1Inputs, UInt_t l2Inputs ) const
713 // Check if the "toCheck" class (or logical combination of classes and L0 inputs)
714 // are within the "firedTriggerClasses"
718 TString comp(combo->GetName());
719 UInt_t trigInputs[3] = {l0Inputs, l1Inputs, l2Inputs};
721 Bool_t exitLoop = kFALSE;
723 TIter nextObj(combo);
724 TObjArray* currList = 0x0;
725 while ( ( currList = static_cast<TObjArray*>(nextObj()) ) ) {
726 Int_t listIdx = currList->GetUniqueID();
727 TIter nextA(currList);
728 TObjString* an = 0x0;
729 while ( ( an = static_cast<TObjString*>(nextA()) ) )
732 UInt_t bit = an->GetUniqueID();
733 ok = ( (trigInputs[listIdx] & bit) == bit );
736 TPRegexp re(Form("(^|[ ])%s([ ]|$)",an->String().Data()));
737 ok = firedTriggerClasses.Contains(re);
739 if ( combo->GetUniqueID() == kComboFormula ) comp.ReplaceAll(an->String().Data(),Form("%d",ok));
740 else if ( ( combo->GetUniqueID() == kComboAND && ! ok ) || ( combo->GetUniqueID() == kComboOR && ok ) ) {
745 if ( exitLoop ) break;
748 if ( combo->GetUniqueID() == kComboFormula ) {
749 TFormula formula("TriggerClassFormulaCheck", comp.Data());
750 if ( formula.Compile() > 0 ) {
751 AliError(Form("Could not evaluate formula %s",comp.Data()));
754 else ok = formula.Eval(0);
757 AliDebug(2,Form("tname %s => %d comp=%s inputs 0x%x 0x%x 0x%x",combo->GetName(),ok,comp.Data(),l0Inputs, l1Inputs, l2Inputs));
762 //_____________________________________________________________________________
764 AliMuonEventCuts::AddToEventSelectedClass ( const TString& toCheck, const TObjString* foundTrig, UInt_t comboType )
766 /// Add current trigger to the selected class for the event
768 // Compute the trigger pt cut level of the current class
769 UInt_t trigLevel = 0;
770 if ( foundTrig ) trigLevel = foundTrig->GetUniqueID();
772 // The assigned trigger pt cut level is:
773 // - the correct one if "toCheck" is a single trigger class
774 // - the highest pt cut among the matching ones in case "toCheck" is a trigger class/input
775 // combined through (at least one) logical AND "&"
776 // - the lowest pt cut among the macthing ones in case "toCheck" is a trigger class/input
777 // combined through (only) logical OR "|"
778 // This may lead to errors in case of complex combinations of trigger/inputs
780 // First eliminate trigger classes which are negated in combinations
781 TString checkStr(toCheck);
782 while ( checkStr.Contains("!") ) {
783 Int_t startNot = checkStr.Index("!");
784 Int_t endNot = startNot;
786 for ( endNot = startNot; endNot<checkStr.Length(); endNot++ ) {
787 if ( checkStr[endNot] == '(' ) npars++;
788 else if ( checkStr[endNot] == ')' ) npars--;
791 if ( checkStr[endNot] == '&' || checkStr[endNot] == '|' ) break;
794 checkStr.Remove(startNot,endNot-startNot);
797 // Then check if they match the Lpt or Hpt
798 Bool_t isFirst = kTRUE;
799 for ( Int_t ipat=0; ipat<fSelectedTrigLevel->GetEntries(); ++ipat ) {
800 if ( checkStr.Contains(fSelectedTrigLevel->At(ipat)->GetName() ) ) {
801 UInt_t currLevel = fSelectedTrigLevel->At(ipat)->GetUniqueID();
802 if ( comboType == kComboAND ) trigLevel = TMath::Max(trigLevel, currLevel);
803 else if ( comboType == kComboOR || comboType == kComboFormula ) {
805 trigLevel = currLevel;
808 else trigLevel = TMath::Min(trigLevel, currLevel);
811 trigLevel = currLevel;
815 } // loop on trig level patterns
818 TObjString* currTrig = new TObjString(toCheck);
819 currTrig->SetUniqueID(trigLevel);
820 fSelectedTrigClassesInEvent->AddLast(currTrig);
822 if ( foundTrig ) return;
823 TObjString* addTrig = new TObjString(toCheck);
824 addTrig->SetUniqueID(trigLevel);
825 fAllSelectedTrigClasses->Add(addTrig);
826 TString trigLevelInfo = Form("trig level %i ", trigLevel & 0x3);
827 trigLevelInfo += ( trigLevel > 3 ) ? "di-muon" : "single-muon";
828 AliInfo(Form("Adding %s (%s) to considered trigger classes",toCheck.Data(),trigLevelInfo.Data()));
831 //________________________________________________________________________
832 void AliMuonEventCuts::SetCentralityClasses(Int_t nCentralityBins, Double_t* centralityBins)
835 /// Set centrality classes
837 Double_t* bins = centralityBins;
838 Int_t nbins = nCentralityBins;
840 Double_t defaultCentralityBins[] = {-5., 0., 5., 10., 20., 30., 40., 50., 60., 70., 80., 90., 100., 105.};
841 if ( ! centralityBins ) {
842 bins = defaultCentralityBins;
843 nbins = sizeof(defaultCentralityBins)/sizeof(defaultCentralityBins[0])-1;
846 TString centralityEstimator = "V0M";
847 if ( fCentralityClasses ) {
848 centralityEstimator = GetCentralityEstimator();
849 delete fCentralityClasses;
851 fCentralityClasses = new TAxis(nbins, bins);
852 TString currClass = "";
853 for ( Int_t ibin=1; ibin<=fCentralityClasses->GetNbins(); ++ibin ){
854 currClass = Form("%.0f_%.0f",fCentralityClasses->GetBinLowEdge(ibin),fCentralityClasses->GetBinUpEdge(ibin));
855 fCentralityClasses->SetBinLabel(ibin, currClass.Data());
858 SetCentralityEstimator(centralityEstimator);
861 //________________________________________________________________________
862 void AliMuonEventCuts::SetCentralityEstimator ( TString centralityEstimator )
864 /// Set centrality estimator
865 fCentralityClasses->SetName(centralityEstimator.Data());
869 //________________________________________________________________________
870 TString AliMuonEventCuts::GetCentralityEstimator () const
872 /// Get centrality estimator
873 return fCentralityClasses->GetName();
876 //________________________________________________________________________
877 Double_t AliMuonEventCuts::GetCentrality ( const AliVEvent* event ) const
880 AliVEvent* evt = const_cast<AliVEvent*>(event);
881 return evt->GetCentrality()->GetCentralityPercentile(GetCentralityEstimator());
884 //________________________________________________________________________
885 void AliMuonEventCuts::SetDefaultParameters ()
887 /// Standard parameters for muon event
888 SetPhysicsSelectionMask(AliVEvent::kAny);
889 SetVertexMinNContributors(1);
894 //________________________________________________________________________
895 void AliMuonEventCuts::SetDefaultFilterMask ()
897 /// Standard cuts for muon event
898 SetFilterMask ( kPhysicsSelected | kSelectedTrig | kGoodVertex );
901 //________________________________________________________________________
902 void AliMuonEventCuts::Print(Option_t* option) const
907 TString sopt(option);
909 if ( sopt.IsNull() || sopt.Contains("*") || sopt.Contains("all") ) sopt = "mask param";
910 UInt_t filterMask = GetFilterMask();
911 if ( sopt.Contains("mask") ) {
912 printf(" *** Muon event filter mask: *** \n");
913 printf(" 0x%x\n", filterMask);
914 if ( filterMask & kPhysicsSelected ) printf(" Pass physics selection 0x%x\n", fPhysicsSelectionMask);
915 if ( filterMask & kSelectedCentrality ) printf( "%g < centrality (%s) < %g\n", fCentralityClasses->GetXmin(), GetCentralityEstimator().Data(), fCentralityClasses->GetXmax() );
916 if ( filterMask & kSelectedTrig ) printf(" Has selected trigger classes\n");
917 if ( filterMask & kGoodVertex ) printf(" SPD vertex with %i contributors && %g < Vz < %g\n", GetVertexMinNContributors(), GetVertexVzMin(), GetVertexVzMax());
918 if ( filterMask & kNoPileup ) printf(" Reject pileup with SPD\n");
919 printf(" ******************** \n");
921 if ( sopt.Contains("param") ) {
922 printf(" *** Muon event parameters: *** \n");
923 printf(" Centrality estimator: %s\n", GetCentralityEstimator().Data());
924 printf(" ******************** \n");