]> git.uio.no Git - u/mrichter/AliRoot.git/blame - ANALYSIS/AliPhysicsSelection.cxx
update for transporting event info along the TRD train
[u/mrichter/AliRoot.git] / ANALYSIS / AliPhysicsSelection.cxx
CommitLineData
61899827 1/* $Id: AliPhysicsSelection.cxx 35782 2009-10-22 11:54:31Z jgrosseo $ */
2
3/**************************************************************************
4 * Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
5 * *
6 * Author: The ALICE Off-line Project. *
7 * Contributors are mentioned in the code where appropriate. *
8 * *
9 * Permission to use, copy, modify and distribute this software and its *
10 * documentation strictly for non-commercial purposes is hereby granted *
11 * without fee, provided that the above copyright notice appears in all *
12 * copies and that both the copyright notice and this permission notice *
13 * appear in the supporting documentation. The authors make no claims *
14 * about the suitability of this software for any purpose. It is *
15 * provided "as is" without express or implied warranty. *
16 **************************************************************************/
17
18//-------------------------------------------------------------------------
19// Implementation of Class AliPhysicsSelection
528640ed 20// This class selects collision candidates from data runs, applying selection cuts on triggers
21// and background rejection based on the content of the ESD
22//
23// Usage:
24//
a2ce3799 25// Create the object:
528640ed 26// fPhysicsSelection = new AliPhysicsSelection;
a2ce3799 27//
28// For MC data, call
29// fPhysicsSelection->SetAnalyzeMC()
528640ed 30//
31// To check if an event is a collision candidate, use:
32// fPhysicsSelection->IsCollisionCandidate(fESD)
33//
34// After processing save the resulting histograms to a file with (a folder physics_selection
35// will be created that contains the histograms):
36// fPhysicsSelection->SaveHistograms("physics_selection")
37//
38// To print statistics after processing use:
39// fPhysicsSelection->Print();
40//
73cc8654 41// The BX ids corresponding to real bunches crossings p2 are
42// automatically selected. You cannot process runs with different
43// filling schemes if this option is set. If you want to disable this,
44// use:
45// fPhysicsSelection->SetUseBXNumbers(0);
46//
47//
48// If you are analizing muons and you want to keep the muon triggers
49// besides the CINT1B you can set:
50// fPhysicsSelection->SetUseMuonTriggers();
51//
85c71ba7 52//
53// To compute the Background automatically using the control triggers
54// use:
55// fPhysicsSelection->SetComputeBG();
56// this will show the value of the Beam Gas, accidentals and good
57// events as additional rows in the statistic tables, but it will NOT
58// subtract the background automatically.
59// This option will only work for runs taken with the CINT1
60// suite. This options enables automatically also the usage of BX
61// numbers. You can only process one run at a time if you require this
62// options, because it uses the bunch intensity estimated run by run.
63//
64// The BG will usually be more important in the so-called "bin 0": the
65// class can also compute the statistics table for events in this
66// bin. Since the definition of bin 0 may in general change from
67// analysis to analysis, the user needs to provide a callback
68// implementing the definition of bin zero. The callback should be
69// implemented as a method in the analysis task and should override
70// the IsEventInBinZero method of AliAnalysisTaskSE, and should thus
71// have the the following prototype:
72// Bool_t IsEventInBinZero();
73// It should return true if the event is in the bin 0 and it is set by
74// passing to the physics selection the NAME of the task where the
75// callback is implemented:
76// fPhysicsSelection->SetBin0Callback("MyTask").
77//
78//
decf6fd4 79// Usually the class selects the trigger scheme by itself depending on the run number.
80// Nevertheless, you can do that manually by calling AddCollisionTriggerClass() and AddBGTriggerClass()
81// Example:
82// To define the class CINT1B-ABCE-NOPF-ALL as collision trigger (those will be accepted as
83// collision candidates when they pass the selection):
84// AddCollisionTriggerClass("+CINT1B-ABCE-NOPF-ALL #769 #3119");
85// To select on bunch crossing IDs in addition, use:
86// AddCollisionTriggerClass("+CINT1B-ABCE-NOPF-ALL #769 #3119");
87// To define the class CINT1A-ABCE-NOPF-ALL as a background trigger (those will only be counted
88// for the control histograms):
89// AddBGTriggerClass("+CINT1A-ABCE-NOPF-ALL");
90// You can also specify more than one trigger class in a string or you can require that some are *not*
91// present. The following line would require CSMBA-ABCE-NOPF-ALL, but CSMBB-ABCE-NOPF-ALL is not allowed
92// to be present:
93// AddBGTriggerClass("+CSMBA-ABCE-NOPF-ALL -CSMBB-ABCE-NOPF-ALL");
94//
85c71ba7 95// Origin: Jan Fiete Grosse-Oetringhaus, CERN
96// Michele Floris, CERN
61899827 97//-------------------------------------------------------------------------
98
99#include <Riostream.h>
100#include <TH1F.h>
101#include <TH2F.h>
102#include <TList.h>
103#include <TIterator.h>
104#include <TDirectory.h>
296dd262 105#include <TObjArray.h>
61899827 106
107#include <AliPhysicsSelection.h>
108
109#include <AliTriggerAnalysis.h>
110#include <AliLog.h>
111
112#include <AliESDEvent.h>
85c71ba7 113#include <AliAnalysisTaskSE.h>
114#include "AliAnalysisManager.h"
141265a2 115#include "TPRegexp.h"
61899827 116
117ClassImp(AliPhysicsSelection)
118
119AliPhysicsSelection::AliPhysicsSelection() :
296dd262 120 AliAnalysisCuts("AliPhysicsSelection", "AliPhysicsSelection"),
121 fCurrentRun(-1),
a2ce3799 122 fMC(kFALSE),
296dd262 123 fCollTrigClasses(),
124 fBGTrigClasses(),
125 fTriggerAnalysis(),
126 fBackgroundIdentification(0),
91bea6e7 127 fHistBunchCrossing(0),
73cc8654 128 fHistTriggerPattern(0),
91bea6e7 129 fSkipTriggerClassSelection(0),
85c71ba7 130 fUsingCustomClasses(0),
131 fSkipV0(0),
132 fBIFactorA(1),
133 fBIFactorC(1),
141265a2 134 fBIFactorAC(1),
85c71ba7 135 fComputeBG(0),
141265a2 136 fBGStatOffset(0),
73cc8654 137 fUseBXNumbers(1),
138 fUseMuonTriggers(0),
85c71ba7 139 fFillingScheme(""),
ff097e3f 140 fBin0CallBack(""),
141 fBin0CallBackPointer(0)
61899827 142{
143 // constructor
144
296dd262 145 fCollTrigClasses.SetOwner(1);
146 fBGTrigClasses.SetOwner(1);
147 fTriggerAnalysis.SetOwner(1);
85c71ba7 148 fHistStatistics[0] = 0;
149 fHistStatistics[1] = 0;
296dd262 150
61899827 151 AliLog::SetClassDebugLevel("AliPhysicsSelection", AliLog::kWarning);
152}
153
154AliPhysicsSelection::~AliPhysicsSelection()
155{
156 // destructor
85c71ba7 157
296dd262 158 fCollTrigClasses.Delete();
159 fBGTrigClasses.Delete();
160 fTriggerAnalysis.Delete();
61899827 161
85c71ba7 162 if (fHistStatistics[0])
163 {
164 delete fHistStatistics[0];
165 fHistStatistics[0] = 0;
166 }
167 if (fHistStatistics[1])
61899827 168 {
85c71ba7 169 delete fHistStatistics[1];
170 fHistStatistics[1] = 0;
61899827 171 }
172
173 if (fHistBunchCrossing)
174 {
175 delete fHistBunchCrossing;
176 fHistBunchCrossing = 0;
177 }
73cc8654 178 if (fHistTriggerPattern)
179 {
180 delete fHistTriggerPattern;
181 fHistTriggerPattern = 0;
182 }
716f045f 183 if (fBackgroundIdentification)
184 {
185 delete fBackgroundIdentification;
186 fBackgroundIdentification = 0;
187 }
61899827 188}
296dd262 189
c2ba5a61 190UInt_t AliPhysicsSelection::CheckTriggerClass(const AliESDEvent* aEsd, const char* trigger, Int_t& triggerLogic) const
296dd262 191{
192 // checks if the given trigger class(es) are found for the current event
c2ba5a61 193 // format of trigger: +TRIGGER1 -TRIGGER2 [#XXX] [&YY] [*ZZ]
296dd262 194 // requires TRIGGER1 and rejects TRIGGER2
0c6c629b 195 // in bunch crossing XXX
1209509c 196 // if successful, YY is returned (for association between entry in fCollTrigClasses and AliVEvent::EOfflineTriggerTypes)
c2ba5a61 197 // triggerLogic is filled with ZZ, defaults to kCINT1
296dd262 198
decf6fd4 199 Bool_t foundBCRequirement = kFALSE;
200 Bool_t foundCorrectBC = kFALSE;
201
0c6c629b 202 UInt_t returnCode = AliVEvent::kUserDefined;
c2ba5a61 203 triggerLogic = kCINT1;
0c6c629b 204
296dd262 205 TString str(trigger);
206 TObjArray* tokens = str.Tokenize(" ");
207
208 for (Int_t i=0; i < tokens->GetEntries(); i++)
209 {
210 TString str2(((TObjString*) tokens->At(i))->String());
211
decf6fd4 212 if (str2[0] == '+' || str2[0] == '-')
296dd262 213 {
decf6fd4 214 Bool_t flag = (str2[0] == '+');
215
216 str2.Remove(0, 1);
217
218 if (flag && !aEsd->IsTriggerClassFired(str2))
219 {
220 AliDebug(AliLog::kDebug, Form("Rejecting event because trigger class %s is not present", str2.Data()));
221 delete tokens;
222 return kFALSE;
223 }
224 if (!flag && aEsd->IsTriggerClassFired(str2))
225 {
226 AliDebug(AliLog::kDebug, Form("Rejecting event because trigger class %s is present", str2.Data()));
227 delete tokens;
228 return kFALSE;
229 }
296dd262 230 }
decf6fd4 231 else if (str2[0] == '#')
296dd262 232 {
decf6fd4 233 foundBCRequirement = kTRUE;
234
235 str2.Remove(0, 1);
236
237 Int_t bcNumber = str2.Atoi();
238 AliDebug(AliLog::kDebug, Form("Checking for bunch crossing number %d", bcNumber));
239
240 if (aEsd->GetBunchCrossNumber() == bcNumber)
241 {
242 foundCorrectBC = kTRUE;
243 AliDebug(AliLog::kDebug, Form("Found correct bunch crossing %d", bcNumber));
244 }
296dd262 245 }
0c6c629b 246 else if (str2[0] == '&' && !fUsingCustomClasses)
247 {
248 str2.Remove(0, 1);
249
1209509c 250 returnCode = str2.Atoll();
0c6c629b 251 }
c2ba5a61 252 else if (str2[0] == '*')
253 {
254 str2.Remove(0, 1);
255
256 triggerLogic = str2.Atoi();
257 }
decf6fd4 258 else
259 AliFatal(Form("Invalid trigger syntax: %s", trigger));
296dd262 260 }
261
262 delete tokens;
decf6fd4 263
264 if (foundBCRequirement && !foundCorrectBC)
265 return kFALSE;
266
0c6c629b 267 return returnCode;
296dd262 268}
2d45a1a7 269
270//______________________________________________________________________________
271TObject *AliPhysicsSelection::GetStatistics(Option_t *option) const
272{
273// Get the statistics histograms ("ALL" and "BIN0")
274 TString opt(option);
275 opt.ToUpper();
276 Int_t ihist = 0;
277 if (opt == "ALL") ihist = kStatIdxAll;
278 if (opt == "BIN0") ihist = kStatIdxBin0;
279 return fHistStatistics[ihist];
280}
281
282//______________________________________________________________________________
0c6c629b 283UInt_t AliPhysicsSelection::IsCollisionCandidate(const AliESDEvent* aEsd)
61899827 284{
285 // checks if the given event is a collision candidate
0c6c629b 286 //
287 // returns a bit word describing the fired offline triggers (see AliVEvent::EOfflineTriggerTypes)
61899827 288
141265a2 289 if (fCurrentRun != aEsd->GetRunNumber()) {
1107e2ce 290 if (!Initialize(aEsd))
95e6f4ec 291 AliFatal(Form("Could not initialize for run %d", aEsd->GetRunNumber()));
141265a2 292 if(fComputeBG) SetBIFactors(aEsd); // is this safe here?
293 }
61899827 294 const AliESDHeader* esdHeader = aEsd->GetHeader();
295 if (!esdHeader)
296 {
297 AliError("ESD Header could not be retrieved");
298 return kFALSE;
299 }
300
a2ce3799 301 // check event type; should be PHYSICS = 7 for data and 0 for MC
302 if (!fMC)
303 {
304 if (esdHeader->GetEventType() != 7)
305 return kFALSE;
306 }
307 else
308 {
309 if (esdHeader->GetEventType() != 0)
310 AliFatal(Form("Invalid event type for MC: %d", esdHeader->GetEventType()));
311 }
758941d4 312
0c6c629b 313 UInt_t accept = 0;
296dd262 314
315 Int_t count = fCollTrigClasses.GetEntries() + fBGTrigClasses.GetEntries();
316 for (Int_t i=0; i < count; i++)
61899827 317 {
296dd262 318 const char* triggerClass = 0;
319 if (i < fCollTrigClasses.GetEntries())
320 triggerClass = ((TObjString*) fCollTrigClasses.At(i))->String();
321 else
322 triggerClass = ((TObjString*) fBGTrigClasses.At(i - fCollTrigClasses.GetEntries()))->String();
61899827 323
296dd262 324 AliDebug(AliLog::kDebug, Form("Processing trigger class %s", triggerClass));
61899827 325
296dd262 326 AliTriggerAnalysis* triggerAnalysis = static_cast<AliTriggerAnalysis*> (fTriggerAnalysis.At(i));
61899827 327
296dd262 328 triggerAnalysis->FillTriggerClasses(aEsd);
61899827 329
c2ba5a61 330 Int_t triggerLogic = 0;
331 UInt_t singleTriggerResult = CheckTriggerClass(aEsd, triggerClass, triggerLogic);
332
0c6c629b 333 if (singleTriggerResult)
296dd262 334 {
335 triggerAnalysis->FillHistograms(aEsd);
336
85c71ba7 337 Bool_t isBin0 = kFALSE;
338 if (fBin0CallBack != "") {
339 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
340 if (!mgr) {
341 AliError("Cannot get the analysis manager");
342 }
343 else {
344 isBin0 = ((AliAnalysisTaskSE*)mgr->GetTask(fBin0CallBack.Data()))->IsEventInBinZero();
345 }
ff097e3f 346 } else if (fBin0CallBackPointer) {
347 isBin0 = (*fBin0CallBackPointer)(aEsd);
85c71ba7 348 }
ff097e3f 349
c2ba5a61 350 // hardware trigger
cc9d9320 351 Int_t fastORHW = triggerAnalysis->SPDFiredChips(aEsd, 1); // SPD number of chips from trigger bits (!)
c2ba5a61 352 Int_t fastORHWL1 = triggerAnalysis->SPDFiredChips(aEsd, 1, kFALSE, 2); // SPD number of chips from trigger bits in second layer (!)
85c71ba7 353 Bool_t v0AHW = fSkipV0 ? 0 :(triggerAnalysis->V0Trigger(aEsd, AliTriggerAnalysis::kASide, kTRUE) == AliTriggerAnalysis::kV0BB);// should replay hw trigger
354 Bool_t v0CHW = fSkipV0 ? 0 :(triggerAnalysis->V0Trigger(aEsd, AliTriggerAnalysis::kCSide, kTRUE) == AliTriggerAnalysis::kV0BB);// should replay hw trigger
c2ba5a61 355
cc9d9320 356 // offline trigger
357 Int_t fastOROffline = triggerAnalysis->SPDFiredChips(aEsd, 0); // SPD number of chips from clusters (!)
c2ba5a61 358 Int_t fastOROfflineL1 = triggerAnalysis->SPDFiredChips(aEsd, 0, kFALSE, 2); // SPD number of chips from clusters in second layer (!)
359 Bool_t v0A = fSkipV0 ? 0 :triggerAnalysis->IsOfflineTriggerFired(aEsd, AliTriggerAnalysis::kV0A);
360 Bool_t v0C = fSkipV0 ? 0 :triggerAnalysis->IsOfflineTriggerFired(aEsd, AliTriggerAnalysis::kV0C);
85c71ba7 361 Bool_t v0ABG = fSkipV0 ? 0 :triggerAnalysis->IsOfflineTriggerFired(aEsd, AliTriggerAnalysis::kV0ABG);
362 Bool_t v0CBG = fSkipV0 ? 0 :triggerAnalysis->IsOfflineTriggerFired(aEsd, AliTriggerAnalysis::kV0CBG);
f4ca8f20 363 Bool_t v0BG = v0ABG || v0CBG;
85c71ba7 364
365 // fmd
366 Bool_t fmdA = triggerAnalysis->IsOfflineTriggerFired(aEsd, AliTriggerAnalysis::kFMDA);
367 Bool_t fmdC = triggerAnalysis->IsOfflineTriggerFired(aEsd, AliTriggerAnalysis::kFMDC);
368 Bool_t fmd = fmdA || fmdC;
61899827 369
85c71ba7 370 // SSD
1107e2ce 371 //Int_t ssdClusters = triggerAnalysis->SSDClusters(aEsd);
c2ba5a61 372
373 // ZDC
ce08cb1f 374 // Bool_t zdcA = triggerAnalysis->IsOfflineTriggerFired(aEsd, AliTriggerAnalysis::kZDCA);
375 // Bool_t zdcC = triggerAnalysis->IsOfflineTriggerFired(aEsd, AliTriggerAnalysis::kZDCC);
376 Bool_t zdcA = triggerAnalysis->ZDCTDCTrigger(aEsd, AliTriggerAnalysis::kASide);
377 Bool_t zdcC = triggerAnalysis->ZDCTDCTrigger(aEsd, AliTriggerAnalysis::kCSide);
c2ba5a61 378
85c71ba7 379
380 // Some "macros"
381 Bool_t mb1 = (fastOROffline > 0 || v0A || v0C) && (!v0BG);
382 Bool_t mb1prime = (fastOROffline > 1 || (fastOROffline > 0 && (v0A || v0C)) || (v0A && v0C) ) && (!v0BG);
383
384 // Background rejection
8663e267 385 Bool_t bgID = kFALSE;
386 if (fBackgroundIdentification)
387 bgID = ! fBackgroundIdentification->IsSelected(const_cast<AliESDEvent*> (aEsd));
388
c2ba5a61 389 /*Int_t ntrig = fastOROffline; // any 2 hits
85c71ba7 390 if(v0A) ntrig += 1;
391 if(v0C) ntrig += 1; //v0C alone is enough
392 if(fmd) ntrig += 1;
c2ba5a61 393 if(ssdClusters>1) ntrig += 1;*/
85c71ba7 394
c2ba5a61 395 // replay hardware trigger (should only remove events for MC)
396
397 Bool_t hwTrig = kFALSE;
398 switch (triggerLogic)
399 {
400 case kCINT1: hwTrig = fastORHW > 0 || v0AHW || v0CHW; break;
401 case kCMBS2A: hwTrig = fastORHWL1 > 1 && v0AHW; break;
402 case kCMBS2C: hwTrig = fastORHWL1 > 1 && v0CHW; break;
403 case kCMBAC: hwTrig = v0AHW && v0CHW; break;
404 default: AliFatal(Form("Undefined trigger logic %d", triggerLogic)); break;
405 }
85c71ba7 406
73cc8654 407 // Fill trigger pattern histo
408 Int_t tpatt = 0;
409 if (fastORHW>0) tpatt+=1;
410 if (v0AHW) tpatt+=2;
411 if (v0CHW) tpatt+=4;
412 fHistTriggerPattern->Fill( tpatt );
413
85c71ba7 414 // fill statistics and return decision
415 const Int_t nHistStat = 2;
416 for(Int_t iHistStat = 0; iHistStat < nHistStat; iHistStat++){
417 if (iHistStat == kStatIdxBin0 && !isBin0) continue; // skip the filling of bin0 stats if the event is not in the bin0
418
419 fHistStatistics[iHistStat]->Fill(kStatTriggerClass, i);
420
85c71ba7 421 // We fill the rest only if hw trigger is ok
422 if (!hwTrig)
423 {
424 AliDebug(AliLog::kDebug, "Rejecting event because hardware trigger is not fired");
425 continue;
426 } else {
427 fHistStatistics[iHistStat]->Fill(kStatHWTrig, i);
428 }
733f0542 429
85c71ba7 430
431 // v0 BG stats
432 if (v0ABG)
433 fHistStatistics[iHistStat]->Fill(kStatV0ABG, i);
434 if (v0CBG)
435 fHistStatistics[iHistStat]->Fill(kStatV0CBG, i);
436
437 // We fill the rest only if mb1 && ! v0BG
438 if (mb1)
439 fHistStatistics[iHistStat]->Fill(kStatMB1, i);
440 else continue;
441
442 if (mb1prime)
443 fHistStatistics[iHistStat]->Fill(kStatMB1Prime, i);
444
445 if (fmd)
446 fHistStatistics[iHistStat]->Fill(kStatFMD, i);
447
c2ba5a61 448 //if(ntrig >= 2 && !v0BG)
449 // fHistStatistics[iHistStat]->Fill(kStatAny2Hits, i);
85c71ba7 450
451 if (fastOROffline > 0)
452 fHistStatistics[iHistStat]->Fill(kStatFO1, i);
453 if (fastOROffline > 1)
454 fHistStatistics[iHistStat]->Fill(kStatFO2, i);
c2ba5a61 455 if (fastOROfflineL1 > 1)
456 fHistStatistics[iHistStat]->Fill(kStatFO2L1, i);
cc9d9320 457
85c71ba7 458 if (v0A)
459 fHistStatistics[iHistStat]->Fill(kStatV0A, i);
460 if (v0C)
461 fHistStatistics[iHistStat]->Fill(kStatV0C, i);
c2ba5a61 462
463 if (zdcA)
464 fHistStatistics[iHistStat]->Fill(kStatZDCA, i);
465 if (zdcC)
466 fHistStatistics[iHistStat]->Fill(kStatZDCC, i);
467 if (zdcA && zdcC)
468 fHistStatistics[iHistStat]->Fill(kStatZDCAC, i);
85c71ba7 469
470 // if (fastOROffline > 1 && !v0BG)
471 // fHistStatistics[iHistStat]->Fill(kStatFO2NoBG, i);
472
c2ba5a61 473 //if (fastOROffline > 0 && (v0A || v0C) && !v0BG)
474 // fHistStatistics[iHistStat]->Fill(kStatFO1AndV0, i);
296dd262 475
85c71ba7 476 if (v0A && v0C && !v0BG && !bgID)
477 fHistStatistics[iHistStat]->Fill(kStatV0, i);
478
c2ba5a61 479 Bool_t offlineAccepted = kFALSE;
480
481 switch (triggerLogic)
482 {
483 case kCINT1: offlineAccepted = mb1; break;
484 case kCMBS2A: offlineAccepted = fastOROfflineL1 > 1 && v0A; break;
485 case kCMBS2C: offlineAccepted = fastOROfflineL1 > 1 && v0C; break;
486 case kCMBAC: offlineAccepted = v0A && v0C; break;
487 default: AliFatal(Form("Undefined trigger logic %d", triggerLogic)); break;
488 }
85c71ba7 489
c2ba5a61 490 if ( offlineAccepted )
85c71ba7 491 {
492 if (!v0BG || fSkipV0)
493 {
494 if (!v0BG) fHistStatistics[iHistStat]->Fill(kStatOffline, i);
61899827 495
85c71ba7 496 if (fBackgroundIdentification && bgID)
497 {
498 AliDebug(AliLog::kDebug, "Rejecting event because of background identification");
499 fHistStatistics[iHistStat]->Fill(kStatBG, i);
500 }
501 else
502 {
c2ba5a61 503 AliDebug(AliLog::kDebug, Form("Accepted event for histograms with trigger logic %d", triggerLogic));
296dd262 504
85c71ba7 505 fHistStatistics[iHistStat]->Fill(kStatAccepted, i);
506 if(iHistStat == kStatIdxAll) fHistBunchCrossing->Fill(aEsd->GetBunchCrossNumber(), i); // Fill only for all (avoid double counting)
507 if((i < fCollTrigClasses.GetEntries() || fSkipTriggerClassSelection) && (iHistStat==kStatIdxAll))
0c6c629b 508 accept |= singleTriggerResult; // only set for "all" (should not really matter)
85c71ba7 509 }
510 }
511 else
512 AliDebug(AliLog::kDebug, "Rejecting event because of V0 BG flag");
513 }
514 else
c2ba5a61 515 AliDebug(AliLog::kDebug, Form("Rejecting event because trigger logic %d is not fulfilled", triggerLogic));
296dd262 516 }
296dd262 517 }
518 }
519
520 if (accept)
0c6c629b 521 AliDebug(AliLog::kDebug, Form("Accepted event as collision candidate with bit mask %d", accept));
61899827 522
296dd262 523 return accept;
61899827 524}
a2ce3799 525
85c71ba7 526Int_t AliPhysicsSelection::GetTriggerScheme(UInt_t runNumber) const
a2ce3799 527{
528 // returns the current trigger scheme (classes that are accepted/rejected)
529
530 if (fMC)
1107e2ce 531 return 0;
a2ce3799 532
533 // TODO dependent on run number
4b7e8f3b 534
535 switch (runNumber)
536 {
537 // CSMBB triggers
538 case 104044:
539 case 105054:
540 case 105057:
541 return 2;
542 }
543
c2ba5a61 544 // defaults
1107e2ce 545 return 1;
a2ce3799 546}
85c71ba7 547
548const char * AliPhysicsSelection::GetFillingScheme(UInt_t runNumber) {
549
550 if(fMC) return "MC";
551
552 if (runNumber >= 104065 && runNumber <= 104160) {
553 return "4x4a";
554 }
555 else if (runNumber >= 104315 && runNumber <= 104321) {
556 return "4x4a*";
557 }
558 else if (runNumber >= 104792 && runNumber <= 104803) {
559 return "4x4b";
560 }
561 else if (runNumber >= 104824 && runNumber <= 104892) {
562 return "4x4c";
563 }
564 else if (runNumber == 105143 || runNumber == 105160) {
565 return "16x16a";
566 }
567 else if (runNumber >= 105256 && runNumber <= 105268) {
568 return "4x4c";
5f337f3d 569 }
570 else if (runNumber >= 114786 && runNumber <= 116684) {
ca234d7a 571 return "Single_2b_1_1_1";
85c71ba7 572 }
5f337f3d 573 else if (runNumber >= 117048 && runNumber <= 117120) {
574 return "Single_3b_2_2_2";
575 }
576 else if (runNumber >= 117220 && runNumber <= 119163) {
577 return "Single_2b_1_1_1";
578 }
579 else if (runNumber >= 119837 && runNumber <= 119862) {
580 return "Single_4b_2_2_2";
581 }
582 else if (runNumber >= 119902 && runNumber <= 120691) {
583 return "Single_6b_3_3_3";
584 }
585 else if (runNumber >= 120741 && runNumber <= 122375) {
586 return "Single_13b_8_8_8";
587 }
141265a2 588 else if (runNumber >= 130148 && runNumber <= 130375) {
589 return "125n_48b_36_16_36";
590 }
8fc17e87 591 else if (runNumber >= 130601 && runNumber <= 130640) {
592 return "1000ns_50b_35_14_35";
593 }
85c71ba7 594 else {
595 AliError(Form("Unknown filling scheme (run %d)", runNumber));
596 }
597
598 return "Unknown";
599}
600
85c71ba7 601const char * AliPhysicsSelection::GetBXIDs(UInt_t runNumber, const char * trigger) {
602
603 if (!fUseBXNumbers || fMC) return "";
604
605 if (runNumber >= 104065 && runNumber <= 104160) {
606 if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #2128 #3019";
607 else if(!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #346 #3465";
608 else if(!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #1234 #1680";
609 else if(!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #790";
e0bf2892 610 // else AliError(Form("Unknown trigger: %s", trigger));
85c71ba7 611 }
612 else if (runNumber >= 104315 && runNumber <= 104321) {
613 if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #2000 #2891";
614 else if(!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #218 #3337";
615 else if(!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #1106 #1552";
616 else if(!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #790";
e0bf2892 617 // else AliError(Form("Unknown trigger: %s", trigger));
85c71ba7 618 }
619 else if (runNumber >= 104792 && runNumber <= 104803) {
620 if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #2228 #3119";
621 else if(!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #2554 #446";
622 else if(!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #1334 #769";
623 else if(!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #790";
e0bf2892 624 // else AliError(Form("Unknown trigger: %s", trigger));
85c71ba7 625 }
626 else if (runNumber >= 104824 && runNumber <= 104892) {
627 if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #3119 #769";
628 else if(!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #2554 #446";
629 else if(!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #1334 #2228";
630 else if(!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #790";
e0bf2892 631 // else AliError(Form("Unknown trigger: %s", trigger));
85c71ba7 632 }
633 else if (runNumber == 105143 || runNumber == 105160) {
85c71ba7 634 if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #1337 #1418 #2228 #2309 #3119 #3200 #446 #527";
635 else if(!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #1580 #1742 #1904 #2066 #2630 #2792 #2954 #3362";
636 else if(!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #845 #1007 #1169 #1577 #3359 #3521 #119 #281 ";
637 else if(!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #790";
e0bf2892 638 // else AliError(Form("Unknown trigger: %s", trigger));
85c71ba7 639 }
640 else if (runNumber >= 105256 && runNumber <= 105268) {
641 if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #3019 #669";
642 else if(!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #2454 #346";
643 else if(!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #1234 #2128";
644 else if(!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #790";
e0bf2892 645 // else AliError(Form("Unknown trigger: %s", trigger));
73cc8654 646 } else if (runNumber >= 114786 && runNumber <= 116684) { // 7 TeV 2010, assume always the same filling scheme
ca234d7a 647 if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #346";
648 else if(!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #2131";
649 else if(!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #3019";
650 else if(!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #1238";
e0bf2892 651 // else AliError(Form("Unknown trigger: %s", trigger));
85c71ba7 652 }
5f337f3d 653 else if (runNumber >= 117048 && runNumber <= 117120) {
654 // return "Single_3b_2_2_2";
655 if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #346 #1240 ";
656 else if (!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #2131 ";
657 else if (!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #3019 ";
658 else if (!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #1238";
e0bf2892 659 // else AliError(Form("Unknown trigger: %s", trigger));
5f337f3d 660
661 }
c2ba5a61 662 else if ((runNumber >= 117220 && runNumber <= 118555) || (runNumber >= 118784 && runNumber <= 119163))
663 {
5f337f3d 664 // return "Single_2b_1_1_1";
665 if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #346 ";
666 else if (!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #2131 ";
667 else if (!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #3019 ";
668 else if (!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #1238 ";
e0bf2892 669 // else AliError(Form("Unknown trigger: %s", trigger));
5f337f3d 670 }
c2ba5a61 671 else if (runNumber >= 118556 && runNumber <= 118783) {
672 // return "Single_2b_1_1_1";
673 // same as previous but was misaligned by 1 BX in fill 1069
674 if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #345 ";
675 else if (!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #2130 ";
676 else if (!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #3018 ";
677 else if (!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #1238 ";
678 // else AliError(Form("Unknown trigger: %s", trigger));
679 }
5f337f3d 680 else if (runNumber >= 119837 && runNumber <= 119862) {
681 // return "Single_4b_2_2_2";
682 if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #669 #3019 ";
683 else if (!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #346 #2454 ";
684 else if (!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #1234 #2128 ";
685 else if (!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #1681 #3463";
e0bf2892 686 // else AliError(Form("Unknown trigger: %s", trigger));
5f337f3d 687
688 }
689 else if (runNumber >= 119902 && runNumber <= 120691) {
690 // return "Single_6b_3_3_3";
691 if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #346 #546 #746 ";
692 else if (!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #2131 #2331 #2531 ";
693 else if (!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #3019 #3219 #3419 ";
694 else if (!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #1296 #1670";
e0bf2892 695 // else AliError(Form("Unknown trigger: %s", trigger));
5f337f3d 696 }
697 else if (runNumber >= 120741 && runNumber <= 122375) {
698 // return "Single_13b_8_8_8";
699 if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #346 #446 #546 #646 #1240 #1340 #1440 #1540 ";
700 else if (!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #946 #2131 #2231 #2331 #2431 ";
701 else if (!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #3019 #3119 #3219 #3319 #3519 ";
702 else if (!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #1835 #2726";
e0bf2892 703 // else AliError(Form("Unknown trigger: %s", trigger));
5f337f3d 704
bc18a83e 705 }
706 else if (runNumber >= 130148 && runNumber <= 130375) {
707 TString triggerString = trigger;
708 static TString returnString = " ";
709 returnString = "";
710 if (triggerString.Contains("B")) returnString += " #346 #396 #446 #496 #546 #596 #646 #696 #1240 #1290 #1340 #1390 #1440 #1490 #1540 #1590 ";
711 if (triggerString.Contains("A")) returnString += " #755 #805 #855 #905 #955 #1005 #1799 #1849 #1899 #2131 #2181 #2231 #2281 #2331 #2381 #2431 #2481 #2531 #2581 #2631 #2846 #3016 #3066 #3116 #3166 #3216 #3266 #3316 #3366 #3425 #3475 #3525 ";
712 if (triggerString.Contains("C")) returnString += " #3019 #3069 #3119 #3169 #3219 #3269 #3319 #3369 #14 #64 #114 #746 #796 #846 #908 #958 #1008 #1640 #1690 #1740 #2055 #2125 #2175 #2225 #2275 #2325 #2375 #2425 #2475 #2534 #2584 #2634 ";
713 // Printf("0x%x",returnString.Data());
714 // Printf("%s",returnString.Data());
715 return returnString.Data();
8fc17e87 716 }
717 else if (runNumber >= 130601 && runNumber <= 130640) {
718 TString triggerString = trigger;
719 static TString returnString = " ";
720 returnString = "";
721 if (triggerString.Contains("B")) returnString += " #346 #386 #426 #466 #506 #546 #586 #1240 #1280 #1320 #1360 #1400 #1440 #1480 ";
722 if (triggerString.Contains("A")) returnString += " #626 #666 #706 #746 #786 #826 #866 #1520 #1560 #1600 #1640 #1680 #1720 #1760 #2076 #2131 #2171 #2211 #2251 #2291 #2331 #2371 #2414 #2454 #2494 #2534 #2574 #2614 #2654 #2694 #2734 #2774 #2814 "; //#2854 #2894 #2934 not present in this run
723 if (triggerString.Contains("C")) returnString += " #3019 #3059 #3099 #3139 #3179 #3219 #3259 #3299 #3339 #3379 #3419 #3459 #3499 #3539 #115 #629 #669 #709 #749 #789 #829 #869 #909 #949 #989 #1029 #1069 #1109 #1149 #1523 #1563 #1603 #1643 "; //#1683 #1723 #1763 not present in this run
724 return returnString.Data();
5f337f3d 725 }
726
85c71ba7 727 else {
8fc17e87 728 AliWarning(Form("Unknown run %d, using all BXs!",runNumber));
85c71ba7 729 }
730
731 return "";
732}
1107e2ce 733
734Bool_t AliPhysicsSelection::Initialize(const AliESDEvent* aEsd)
735{
736 // initializes the object for the given ESD
737
c8aeecab 738 AliInfo(Form("Initializing for beam type: %s", aEsd->GetESDRun()->GetBeamType()));
1107e2ce 739 Bool_t pp = kTRUE;
740 if (strcmp(aEsd->GetESDRun()->GetBeamType(), "Pb-Pb") == 0)
741 pp = kFALSE;
742
743 return Initialize(aEsd->GetRunNumber(), pp);
744}
745
746Bool_t AliPhysicsSelection::Initialize(Int_t runNumber, Bool_t pp)
61899827 747{
748 // initializes the object for the given run
749 // TODO having the run number here and parameters hardcoded is clearly temporary, a way needs to be found to have a CDB-like configuration also for analysis
750
29e8486e 751 Bool_t oldStatus = TH1::AddDirectoryStatus();
752 TH1::AddDirectory(kFALSE);
753
85c71ba7 754 if(!fBin0CallBack)
755 AliError("Bin0 Callback not set: will not fill the statistics for the bin 0");
756
757 if (fMC) {
0c6c629b 758 // override BX and bg options in case of MC
85c71ba7 759 fComputeBG = kFALSE;
760 fUseBXNumbers = kFALSE;
761 }
762
a2ce3799 763 Int_t triggerScheme = GetTriggerScheme(runNumber);
91bea6e7 764 if (!fUsingCustomClasses && fCurrentRun != -1 && triggerScheme != GetTriggerScheme(fCurrentRun))
a2ce3799 765 AliFatal("Processing several runs with different trigger schemes is not supported");
296dd262 766
85c71ba7 767 if(fComputeBG && fCurrentRun != -1 && fCurrentRun != runNumber)
768 AliFatal("Cannot process several runs because BG computation is requested");
769
770 if(fComputeBG && !fUseBXNumbers)
e0bf2892 771 AliFatal("Cannot compute BG if BX numbers are not used");
85c71ba7 772
773 if(fUseBXNumbers && fFillingScheme != "" && fFillingScheme != GetFillingScheme(runNumber))
774 AliFatal("Cannot process runs with different filling scheme if usage of BX numbers is requested");
775
85c71ba7 776 fFillingScheme = GetFillingScheme(runNumber);
777
61899827 778 AliInfo(Form("Initializing for run %d", runNumber));
779
758941d4 780 // initialize first time?
a2ce3799 781 if (fCurrentRun == -1)
a2ce3799 782 {
91bea6e7 783 if (fUsingCustomClasses) {
784 AliInfo("Using user-provided trigger classes");
785 } else {
1107e2ce 786 if (pp)
91bea6e7 787 {
1107e2ce 788 switch (triggerScheme)
789 {
790 case 0:
791 // MC Proton-Proton
792
793 fCollTrigClasses.Add(new TObjString(Form("&%u *%d", (UInt_t) AliVEvent::kMB, (Int_t) kCINT1)));
794 break;
795
796 case 1:
797 // Proton-Proton
798
799 // trigger classes used before August 2010
800 fCollTrigClasses.Add(new TObjString(Form("%s%s &%u","+CINT1B-ABCE-NOPF-ALL", GetBXIDs(runNumber,"CINT1B-ABCE-NOPF-ALL"), (UInt_t) AliVEvent::kMB)));
801 fBGTrigClasses.Add (new TObjString(Form("%s%s &%u","+CINT1A-ABCE-NOPF-ALL", GetBXIDs(runNumber,"CINT1A-ABCE-NOPF-ALL"), (UInt_t) AliVEvent::kMB)));
802 fBGTrigClasses.Add (new TObjString(Form("%s%s &%u","+CINT1C-ABCE-NOPF-ALL", GetBXIDs(runNumber,"CINT1C-ABCE-NOPF-ALL"), (UInt_t) AliVEvent::kMB)));
803 fBGTrigClasses.Add (new TObjString(Form("%s%s &%u","+CINT1-E-NOPF-ALL", GetBXIDs(runNumber,"CINT1-E-NOPF-ALL"), (UInt_t) AliVEvent::kMB)));
804
805 // Muon trigger have the same BXIDs of the corresponding CINT triggers
806 fCollTrigClasses.Add(new TObjString(Form("%s%s &%u","+CMUS1B-ABCE-NOPF-MUON", GetBXIDs(runNumber,"CINT1B-ABCE-NOPF-ALL"), (UInt_t) AliVEvent::kMUON)));
807 fBGTrigClasses.Add (new TObjString(Form("%s%s &%u","+CMUS1A-ABCE-NOPF-MUON", GetBXIDs(runNumber,"CINT1A-ABCE-NOPF-ALL"), (UInt_t) AliVEvent::kMUON)));
808 fBGTrigClasses.Add (new TObjString(Form("%s%s &%u","+CMUS1C-ABCE-NOPF-MUON", GetBXIDs(runNumber,"CINT1C-ABCE-NOPF-ALL"), (UInt_t) AliVEvent::kMUON)));
809 fBGTrigClasses.Add (new TObjString(Form("%s%s &%u","+CMUS1-E-NOPF-MUON" , GetBXIDs(runNumber,"CINT1-E-NOPF-ALL"), (UInt_t) AliVEvent::kMUON)));
810
811 // triggers classes used from August 2010
812 // MB
813 fCollTrigClasses.Add(new TObjString(Form("%s%s &%u", "+CINT1-B-NOPF-ALLNOTRD" , GetBXIDs(runNumber, "B"), (UInt_t) AliVEvent::kMB)));
814 fBGTrigClasses.Add (new TObjString(Form("%s%s &%u", "+CINT1-AC-NOPF-ALLNOTRD", GetBXIDs(runNumber, "AC"), (UInt_t) AliVEvent::kMB)));
815 fBGTrigClasses.Add (new TObjString(Form("%s%s &%u", "+CINT1-E-NOPF-ALLNOTRD" , GetBXIDs(runNumber, "E"), (UInt_t) AliVEvent::kMB)));
816
817 // MUON
818 fCollTrigClasses.Add(new TObjString(Form("%s%s &%u", "+CMUS1-B-NOPF-ALLNOTRD" , GetBXIDs(runNumber, "B"), (UInt_t) AliVEvent::kMUON)));
819 fBGTrigClasses.Add (new TObjString(Form("%s%s &%u", "+CMUS1-AC-NOPF-ALLNOTRD", GetBXIDs(runNumber, "AC"), (UInt_t) AliVEvent::kMUON)));
820 fBGTrigClasses.Add (new TObjString(Form("%s%s &%u", "+CMUS1-E-NOPF-ALLNOTRD" , GetBXIDs(runNumber, "E"), (UInt_t) AliVEvent::kMUON)));
821
822 // High Multiplicity
823 fCollTrigClasses.Add(new TObjString(Form("%s%s &%u", "+CSH1-B-NOPF-ALLNOTRD" , GetBXIDs(runNumber, "B"), (UInt_t) AliVEvent::kHighMult)));
824 fBGTrigClasses.Add (new TObjString(Form("%s%s &%u", "+CSH1-AC-NOPF-ALLNOTRD" , GetBXIDs(runNumber, "AC"), (UInt_t) AliVEvent::kHighMult)));
825 fBGTrigClasses.Add (new TObjString(Form("%s%s &%u", "+CSH1-E-NOPF-ALLNOTRD" , GetBXIDs(runNumber, "E"), (UInt_t) AliVEvent::kHighMult)));
826
827 // WARNING: IF YOU ADD MORE TRIGGER CLASSES, PLEASE CHECK THAT THE REGULAR EXPRESSION IN GetStatRow IS STILL VALID
828
829 break;
830
831 case 2:
832 // Proton-Proton
833
834 fCollTrigClasses.Add(new TObjString(Form("+CSMBB-ABCE-NOPF-ALL &%u", (UInt_t) AliVEvent::kMB)));
835 fBGTrigClasses.Add(new TObjString(Form("+CSMBA-ABCE-NOPF-ALL -CSMBB-ABCE-NOPF-ALL &%u", (UInt_t) AliVEvent::kMB)));
836 fBGTrigClasses.Add(new TObjString(Form("+CSMBC-ABCE-NOPF-ALL -CSMBB-ABCE-NOPF-ALL &%u", (UInt_t) AliVEvent::kMB)));
837 break;
838
839 default:
840 AliFatal(Form("Unsupported trigger scheme %d", triggerScheme));
841 }
842 }
843 else
844 {
845 switch (triggerScheme)
846 {
847 case 0:
848 // MC Heavy-Ion
849
850 fCollTrigClasses.Add(new TObjString(Form("&%u *%d", (UInt_t) AliVEvent::kMB, (Int_t) kCMBS2A)));
851 fCollTrigClasses.Add(new TObjString(Form("&%u *%d", (UInt_t) AliVEvent::kMB, (Int_t) kCMBS2C)));
852 fCollTrigClasses.Add(new TObjString(Form("&%u *%d", (UInt_t) AliVEvent::kMB, (Int_t) kCMBAC)));
853 break;
c2ba5a61 854
1107e2ce 855 case 1:
856 // Data Heavy-ion
857
858 fCollTrigClasses.Add(new TObjString(Form("+CMBS2A-B-NOPF-ALL &%u *%d", (UInt_t) AliVEvent::kMB, (Int_t) kCMBS2A)));
859 fBGTrigClasses.Add (new TObjString(Form("+CMBS2A-A-NOPF-ALL &%u *%d", (UInt_t) AliVEvent::kMB, (Int_t) kCMBS2A)));
860 fBGTrigClasses.Add (new TObjString(Form("+CMBS2A-C-NOPF-ALL &%u *%d", (UInt_t) AliVEvent::kMB, (Int_t) kCMBS2A)));
861 fBGTrigClasses.Add (new TObjString(Form("+CMBS2A-E-NOPF-ALL &%u *%d", (UInt_t) AliVEvent::kMB, (Int_t) kCMBS2A)));
862
863 fCollTrigClasses.Add(new TObjString(Form("+CMBS2C-B-NOPF-ALL &%u *%d", (UInt_t) AliVEvent::kMB, (Int_t) kCMBS2C)));
864 fBGTrigClasses.Add (new TObjString(Form("+CMBS2C-A-NOPF-ALL &%u *%d", (UInt_t) AliVEvent::kMB, (Int_t) kCMBS2C)));
865 fBGTrigClasses.Add (new TObjString(Form("+CMBS2C-C-NOPF-ALL &%u *%d", (UInt_t) AliVEvent::kMB, (Int_t) kCMBS2C)));
866 fBGTrigClasses.Add (new TObjString(Form("+CMBS2C-E-NOPF-ALL &%u *%d", (UInt_t) AliVEvent::kMB, (Int_t) kCMBS2C)));
867
868 fCollTrigClasses.Add(new TObjString(Form("+CMBAC-B-NOPF-ALL &%u *%d", (UInt_t) AliVEvent::kMB, (Int_t) kCMBAC)));
869 fBGTrigClasses.Add (new TObjString(Form("+CMBAC-A-NOPF-ALL &%u *%d", (UInt_t) AliVEvent::kMB, (Int_t) kCMBAC)));
870 fBGTrigClasses.Add (new TObjString(Form("+CMBAC-C-NOPF-ALL &%u *%d", (UInt_t) AliVEvent::kMB, (Int_t) kCMBAC)));
871 fBGTrigClasses.Add (new TObjString(Form("+CMBAC-E-NOPF-ALL &%u *%d", (UInt_t) AliVEvent::kMB, (Int_t) kCMBAC)));
872
873 break;
91bea6e7 874
1107e2ce 875 default:
876 AliFatal(Form("Unsupported trigger scheme %d", triggerScheme));
877 }
91bea6e7 878 }
a2ce3799 879 }
91bea6e7 880
a2ce3799 881 Int_t count = fCollTrigClasses.GetEntries() + fBGTrigClasses.GetEntries();
882
883 for (Int_t i=0; i<count; i++)
884 {
885 AliTriggerAnalysis* triggerAnalysis = new AliTriggerAnalysis;
886 triggerAnalysis->SetAnalyzeMC(fMC);
887 triggerAnalysis->EnableHistograms();
888 triggerAnalysis->SetSPDGFOThreshhold(1);
4011b280 889 triggerAnalysis->SetDoFMD(kFALSE);
a2ce3799 890 fTriggerAnalysis.Add(triggerAnalysis);
891 }
892
85c71ba7 893 // TODO: shall I really delete this?
894 if (fHistStatistics[0])
895 delete fHistStatistics[0];
896 if (fHistStatistics[1])
897 delete fHistStatistics[1];
296dd262 898
85c71ba7 899 fHistStatistics[kStatIdxBin0] = BookHistStatistics("_Bin0");
900 fHistStatistics[kStatIdxAll] = BookHistStatistics("");
a2ce3799 901
902 if (fHistBunchCrossing)
903 delete fHistBunchCrossing;
904
905 fHistBunchCrossing = new TH2F("fHistBunchCrossing", "fHistBunchCrossing;bunch crossing number;", 4000, -0.5, 3999.5, count, -0.5, -0.5 + count);
73cc8654 906
907 if (fHistTriggerPattern)
908 delete fHistTriggerPattern;
909
910 const int ntrig=3;
85c71ba7 911 Int_t n = 1;
73cc8654 912 const Int_t nbinTrig = TMath::Nint(TMath::Power(2,ntrig));
913
914 fHistTriggerPattern = new TH1F("fHistTriggerPattern", "Trigger pattern: FO + 2*v0A + 4*v0C",
915 nbinTrig, -0.5, nbinTrig-0.5);
916 fHistTriggerPattern->GetXaxis()->SetBinLabel(1,"NO TRIG");
917 fHistTriggerPattern->GetXaxis()->SetBinLabel(2,"FO");
918 fHistTriggerPattern->GetXaxis()->SetBinLabel(3,"v0A");
919 fHistTriggerPattern->GetXaxis()->SetBinLabel(4,"FO & v0A");
920 fHistTriggerPattern->GetXaxis()->SetBinLabel(5,"v0C");
921 fHistTriggerPattern->GetXaxis()->SetBinLabel(6,"FO & v0C");
922 fHistTriggerPattern->GetXaxis()->SetBinLabel(7,"v0A & v0C");
923 fHistTriggerPattern->GetXaxis()->SetBinLabel(8,"FO & v0A & v0C");
924
925
926 n = 1;
a2ce3799 927 for (Int_t i=0; i < fCollTrigClasses.GetEntries(); i++)
928 {
a2ce3799 929 fHistBunchCrossing->GetYaxis()->SetBinLabel(n, ((TObjString*) fCollTrigClasses.At(i))->String());
930 n++;
931 }
932 for (Int_t i=0; i < fBGTrigClasses.GetEntries(); i++)
933 {
a2ce3799 934 fHistBunchCrossing->GetYaxis()->SetBinLabel(n, ((TObjString*) fBGTrigClasses.At(i))->String());
935 n++;
936 }
85c71ba7 937
938
939
a2ce3799 940 }
941
942 Int_t count = fCollTrigClasses.GetEntries() + fBGTrigClasses.GetEntries();
296dd262 943 for (Int_t i=0; i<count; i++)
61899827 944 {
a2ce3799 945 AliTriggerAnalysis* triggerAnalysis = static_cast<AliTriggerAnalysis*> (fTriggerAnalysis.At(i));
946
296dd262 947 switch (runNumber)
948 {
a2ce3799 949 case 104315:
296dd262 950 case 104316:
951 case 104320:
a2ce3799 952 case 104321:
296dd262 953 case 104439:
954 triggerAnalysis->SetV0TimeOffset(7.5);
955 break;
a2ce3799 956 default:
957 triggerAnalysis->SetV0TimeOffset(0);
296dd262 958 }
f4ca8f20 959 }
960
758941d4 961 fCurrentRun = runNumber;
962
29e8486e 963 TH1::AddDirectory(oldStatus);
964
61899827 965 return kTRUE;
966}
967
85c71ba7 968TH2F * AliPhysicsSelection::BookHistStatistics(const char * tag) {
bc18a83e 969 // add 6 rows to count for the estimate of good, accidentals and
970 // BG and the ratio of BG and accidentals to total +ratio goot to
971 // first col + 2 for error on good.
972 // TODO: Remember the the indexes of rows for the BG selection. Add new member fBGRows[] and use kStat as indexes
85c71ba7 973
974 Int_t count = fCollTrigClasses.GetEntries() + fBGTrigClasses.GetEntries();
975#ifdef VERBOSE_STAT
141265a2 976 Int_t extrarows = fComputeBG != 0 ? 8 : 0;
85c71ba7 977#else
141265a2 978 Int_t extrarows = fComputeBG != 0 ? 3 : 0;
85c71ba7 979#endif
980 TH2F * h = new TH2F(Form("fHistStatistics%s",tag), Form("fHistStatistics - %s ;;",tag), kStatAccepted, 0.5, kStatAccepted+0.5, count+extrarows, -0.5, -0.5 + count+extrarows);
981
982 h->GetXaxis()->SetBinLabel(kStatTriggerClass, "Trigger class");
983 h->GetXaxis()->SetBinLabel(kStatHWTrig, "Hardware trigger");
984 h->GetXaxis()->SetBinLabel(kStatFO1, "FO >= 1");
985 h->GetXaxis()->SetBinLabel(kStatFO2, "FO >= 2");
c2ba5a61 986 h->GetXaxis()->SetBinLabel(kStatFO2L1, "FO (L1) >= 2");
85c71ba7 987 h->GetXaxis()->SetBinLabel(kStatV0A, "V0A");
988 h->GetXaxis()->SetBinLabel(kStatV0C, "V0C");
989 h->GetXaxis()->SetBinLabel(kStatFMD, "FMD");
85c71ba7 990 h->GetXaxis()->SetBinLabel(kStatV0ABG, "V0A BG");
991 h->GetXaxis()->SetBinLabel(kStatV0CBG, "V0C BG");
c2ba5a61 992 h->GetXaxis()->SetBinLabel(kStatZDCA, "ZDCA");
993 h->GetXaxis()->SetBinLabel(kStatZDCC, "ZDCC");
994 h->GetXaxis()->SetBinLabel(kStatZDCAC, "ZDCA & ZDCC");
85c71ba7 995 h->GetXaxis()->SetBinLabel(kStatMB1, "(FO >= 1 | V0A | V0C) & !V0 BG");
996 h->GetXaxis()->SetBinLabel(kStatMB1Prime, "(FO >= 2 | (FO >= 1 & (V0A | V0C)) | (V0A &v0C) ) & !V0 BG");
c2ba5a61 997 //h->GetXaxis()->SetBinLabel(kStatFO1AndV0, "FO >= 1 & (V0A | V0C) & !V0 BG");
85c71ba7 998 h->GetXaxis()->SetBinLabel(kStatV0, "V0A & V0C & !V0 BG & !BG ID");
999 h->GetXaxis()->SetBinLabel(kStatOffline, "Offline Trigger");
c2ba5a61 1000 //h->GetXaxis()->SetBinLabel(kStatAny2Hits, "2 Hits & !V0 BG");
85c71ba7 1001 h->GetXaxis()->SetBinLabel(kStatBG, "Background identification");
1002 h->GetXaxis()->SetBinLabel(kStatAccepted, "Accepted");
1003
1004 Int_t n = 1;
1005 for (Int_t i=0; i < fCollTrigClasses.GetEntries(); i++)
1006 {
1007 h->GetYaxis()->SetBinLabel(n, ((TObjString*) fCollTrigClasses.At(i))->String());
1008 n++;
1009 }
1010 for (Int_t i=0; i < fBGTrigClasses.GetEntries(); i++)
1011 {
1012 h->GetYaxis()->SetBinLabel(n, ((TObjString*) fBGTrigClasses.At(i))->String());
1013 n++;
1014 }
1015
1016 if(fComputeBG) {
141265a2 1017 fBGStatOffset = n;
1018 h->GetYaxis()->SetBinLabel(n++, Form("BG (A+C) (Mask [0x%x])", fComputeBG));
85c71ba7 1019 h->GetYaxis()->SetBinLabel(n++, "ACC");
1020#ifdef VERBOSE_STAT
1021 h->GetYaxis()->SetBinLabel(n++, "BG (A+C) % (rel. to CINT1B)");
1022 h->GetYaxis()->SetBinLabel(n++, "ACC % (rel. to CINT1B)");
1023 h->GetYaxis()->SetBinLabel(n++, "ERR GOOD %");
1024 h->GetYaxis()->SetBinLabel(n++, "GOOD % (rel. to 1st col)");
1025 h->GetYaxis()->SetBinLabel(n++, "ERR GOOD");
1026#endif
1027 h->GetYaxis()->SetBinLabel(n++, "GOOD");
1028 }
1029
1030 return h;
1031}
1032
e9247450 1033void AliPhysicsSelection::Print(Option_t *option) const
61899827 1034{
1035 // print the configuration
e9247450 1036 TString msg;
a2ce3799 1037 Printf("Configuration initialized for run %d (MC: %d):", fCurrentRun, fMC);
e9247450 1038 msg += Form("Configuration initialized for run %d (MC: %d):\n", fCurrentRun, fMC);
61899827 1039
296dd262 1040 Printf("Collision trigger classes:");
1041 for (Int_t i=0; i < fCollTrigClasses.GetEntries(); i++)
1042 Printf("%s", ((TObjString*) fCollTrigClasses.At(i))->String().Data());
61899827 1043
296dd262 1044 Printf("Background trigger classes:");
1045 for (Int_t i=0; i < fBGTrigClasses.GetEntries(); i++)
1046 Printf("%s", ((TObjString*) fBGTrigClasses.At(i))->String().Data());
1047
1048 AliTriggerAnalysis* triggerAnalysis = dynamic_cast<AliTriggerAnalysis*> (fTriggerAnalysis.At(0));
61899827 1049
296dd262 1050 if (triggerAnalysis)
1051 {
1052 if (triggerAnalysis->GetV0TimeOffset() > 0)
1053 Printf("V0 time offset active: %.2f ns", triggerAnalysis->GetV0TimeOffset());
61899827 1054
296dd262 1055 Printf("\nTotal available events:");
528640ed 1056
296dd262 1057 triggerAnalysis->PrintTriggerClasses();
1058 }
528640ed 1059
0c6c629b 1060 if (fHistStatistics[kStatIdxAll])
b43e01ed 1061 {
0c6c629b 1062 for (Int_t i=0; i<fCollTrigClasses.GetEntries(); i++)
1063 {
1064 Printf("\nSelection statistics for collision trigger %s:", ((TObjString*) fCollTrigClasses.At(i))->String().Data());
e9247450 1065 msg += Form("\nSelection statistics for collision trigger %s:\n", ((TObjString*) fCollTrigClasses.At(i))->String().Data());
0c6c629b 1066
1067 Printf("Total events with correct trigger class: %d", (Int_t) fHistStatistics[kStatIdxAll]->GetBinContent(1, i+1));
e9247450 1068 msg += Form("Total events with correct trigger class: %d\n", (Int_t) fHistStatistics[kStatIdxAll]->GetBinContent(1, i+1));
0c6c629b 1069 Printf("Selected collision candidates: %d", (Int_t) fHistStatistics[kStatIdxAll]->GetBinContent(fHistStatistics[kStatIdxAll]->GetXaxis()->FindBin("Accepted"), i+1));
e9247450 1070 msg += Form("Selected collision candidates: %d\n", (Int_t) fHistStatistics[kStatIdxAll]->GetBinContent(fHistStatistics[kStatIdxAll]->GetXaxis()->FindBin("Accepted"), i+1));
0c6c629b 1071 }
17ba346c 1072 }
1073
1074 if (fHistBunchCrossing)
1075 {
1076 Printf("\nBunch crossing statistics:");
e9247450 1077 msg += "\nBunch crossing statistics:\n";
17ba346c 1078
1079 for (Int_t i=1; i<=fHistBunchCrossing->GetNbinsY(); i++)
1080 {
1081 TString str;
1082 str.Form("Trigger %s has accepted events in the bunch crossings: ", fHistBunchCrossing->GetYaxis()->GetBinLabel(i));
1083
1084 for (Int_t j=1; j<=fHistBunchCrossing->GetNbinsX(); j++)
1085 if (fHistBunchCrossing->GetBinContent(j, i) > 0)
1086 str += Form("%d, ", (Int_t) fHistBunchCrossing->GetXaxis()->GetBinCenter(j));
e9247450 1087
17ba346c 1088 Printf("%s", str.Data());
e9247450 1089 msg += str;
1090 msg += "\n";
17ba346c 1091 }
1092
1093 for (Int_t j=1; j<=fHistBunchCrossing->GetNbinsX(); j++)
1094 {
0c6c629b 1095 Int_t countColl = 0;
1096 Int_t countBG = 0;
17ba346c 1097 for (Int_t i=1; i<=fHistBunchCrossing->GetNbinsY(); i++)
1098 {
1099 if (fHistBunchCrossing->GetBinContent(j, i) > 0)
0c6c629b 1100 {
1101 if (fCollTrigClasses.FindObject(fHistBunchCrossing->GetYaxis()->GetBinLabel(i)))
1102 countColl++;
1103 if (fBGTrigClasses.FindObject(fHistBunchCrossing->GetYaxis()->GetBinLabel(i)))
1104 countBG++;
1105 }
17ba346c 1106 }
0c6c629b 1107 if (countColl > 0 && countBG > 0)
1108 Printf("WARNING: Bunch crossing %d has collision and BG trigger classes active. Check BPTX functioning for this run!", (Int_t) fHistBunchCrossing->GetXaxis()->GetBinCenter(j));
17ba346c 1109 }
b43e01ed 1110 }
91bea6e7 1111
1112 if (fUsingCustomClasses)
1113 Printf("WARNING: Using custom trigger classes!");
1114 if (fSkipTriggerClassSelection)
1115 Printf("WARNING: Skipping trigger class selection!");
85c71ba7 1116 if (fSkipV0)
1117 Printf("WARNING: Ignoring V0 information in selection");
1118 if(!fBin0CallBack)
1119 Printf("WARNING: Callback not set: will not fill the statistics for the bin 0");
e9247450 1120 TString opt(option);
1121 opt.ToUpper();
1122 if (opt == "STAT") {
1123 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1124 if (mgr) mgr->AddStatisticsMsg(msg);
1125 }
61899827 1126}
1127
1128Long64_t AliPhysicsSelection::Merge(TCollection* list)
1129{
1130 // Merge a list of AliMultiplicityCorrection objects with this (needed for
1131 // PROOF).
1132 // Returns the number of merged objects (including this).
1133
1134 if (!list)
1135 return 0;
1136
1137 if (list->IsEmpty())
1138 return 1;
1139
1140 TIterator* iter = list->MakeIterator();
1141 TObject* obj;
17ba346c 1142
61899827 1143 // collections of all histograms
1144 const Int_t nHists = 9;
1145 TList collections[nHists];
1146
1147 Int_t count = 0;
1148 while ((obj = iter->Next())) {
1149
1150 AliPhysicsSelection* entry = dynamic_cast<AliPhysicsSelection*> (obj);
1151 if (entry == 0)
1152 continue;
518b6d59 1153 // Update run number. If this one is not initialized (-1) take the one from
1154 // the next physics selection to be merged with. In case of 2 different run
1155 // numbers issue a warning (should physics selections from different runs be
1156 // merged together) A.G.
1157 Int_t currentRun = entry->GetCurrentRun();
1158 // Nothing to merge with since run number was not initialized.
1159 if (currentRun < 0) continue;
c2ba5a61 1160 if (fCurrentRun < 0)
1161 {
1162 fCurrentRun = currentRun;
1163 fMC = entry->fMC;
1164 for (Int_t i=0; i<entry->fCollTrigClasses.GetEntries(); i++)
1165 fCollTrigClasses.Add(entry->fCollTrigClasses.At(i)->Clone());
1166 for (Int_t i=0; i<entry->fBGTrigClasses.GetEntries(); i++)
1167 fBGTrigClasses.Add(entry->fBGTrigClasses.At(i)->Clone());
1168 }
518b6d59 1169 if (fCurrentRun != currentRun)
1170 AliWarning(Form("Current run %d not matching the one to be merged with %d", fCurrentRun, currentRun));
1171
c2ba5a61 1172 if (entry->fTriggerAnalysis.GetEntries() > 0)
1173 collections[0].Add(&(entry->fTriggerAnalysis));
85c71ba7 1174 if (entry->fHistStatistics[0])
1175 collections[1].Add(entry->fHistStatistics[0]);
1176 if (entry->fHistStatistics[1])
1177 collections[2].Add(entry->fHistStatistics[1]);
17ba346c 1178 if (entry->fHistBunchCrossing)
85c71ba7 1179 collections[3].Add(entry->fHistBunchCrossing);
73cc8654 1180 if (entry->fHistTriggerPattern)
1181 collections[4].Add(entry->fHistTriggerPattern);
296dd262 1182 if (entry->fBackgroundIdentification)
73cc8654 1183 collections[5].Add(entry->fBackgroundIdentification);
61899827 1184
1185 count++;
1186 }
1187
c2ba5a61 1188 if (fTriggerAnalysis.GetEntries() == 0 && collections[0].GetEntries() > 0)
1189 {
1190 TList* firstList = (TList*) collections[0].First();
1191 for (Int_t i=0; i<firstList->GetEntries(); i++)
1192 fTriggerAnalysis.Add(firstList->At(i)->Clone());
1193
1194 collections[0].RemoveAt(0);
1195 }
17ba346c 1196 fTriggerAnalysis.Merge(&collections[0]);
c2ba5a61 1197
1198 // if this instance is empty (not initialized) nothing would be merged here --> copy first entry
1199 if (!fHistStatistics[0] && collections[1].GetEntries() > 0)
1200 {
1201 fHistStatistics[0] = (TH2F*) collections[1].First()->Clone();
1202 collections[1].RemoveAt(0);
1203 }
85c71ba7 1204 if (fHistStatistics[0])
1205 fHistStatistics[0]->Merge(&collections[1]);
c2ba5a61 1206
1207 if (!fHistStatistics[1] && collections[2].GetEntries() > 0)
1208 {
1209 fHistStatistics[1] = (TH2F*) collections[2].First()->Clone();
1210 collections[2].RemoveAt(0);
1211 }
85c71ba7 1212 if (fHistStatistics[1])
1213 fHistStatistics[1]->Merge(&collections[2]);
c2ba5a61 1214
1215 if (!fHistBunchCrossing && collections[3].GetEntries() > 0)
1216 {
1217 fHistBunchCrossing = (TH2F*) collections[3].First()->Clone();
1218 collections[3].RemoveAt(0);
1219 }
17ba346c 1220 if (fHistBunchCrossing)
85c71ba7 1221 fHistBunchCrossing->Merge(&collections[3]);
c2ba5a61 1222
1223 if (!fHistTriggerPattern && collections[4].GetEntries() > 0)
1224 {
1225 fHistTriggerPattern = (TH1F*) collections[4].First()->Clone();
1226 collections[4].RemoveAt(0);
1227 }
73cc8654 1228 if (fHistTriggerPattern)
1229 fHistTriggerPattern->Merge(&collections[4]);
c2ba5a61 1230
1231 if (!fBackgroundIdentification && collections[5].GetEntries() > 0)
1232 {
1233 fBackgroundIdentification = (AliAnalysisCuts*) collections[5].First()->Clone();
1234 collections[5].RemoveAt(0);
1235 }
296dd262 1236 if (fBackgroundIdentification)
73cc8654 1237 fBackgroundIdentification->Merge(&collections[5]);
61899827 1238
1239 delete iter;
1240
1241 return count+1;
1242}
1243
1244void AliPhysicsSelection::SaveHistograms(const char* folder) const
1245{
1246 // write histograms to current directory
1247
85c71ba7 1248 if (!fHistStatistics[0] || !fHistStatistics[1])
61899827 1249 return;
1250
1251 if (folder)
1252 {
1253 gDirectory->mkdir(folder);
1254 gDirectory->cd(folder);
1255 }
1256
85c71ba7 1257
1258 // Fill the last rows of fHistStatistics before saving
1259 if (fComputeBG) {
1260 Int_t triggerScheme = GetTriggerScheme(UInt_t(fCurrentRun));
1261 if(triggerScheme != 1){
1262 AliWarning("BG estimate only supported for trigger scheme \"1\" (CINT1 suite)");
73cc8654 1263 } else if (fUseMuonTriggers) {
1264 AliWarning("BG estimate with muon triggers to be implemented");
141265a2 1265 } else {
1266 AliInfo("BG estimate assumes that for a given run you only have A and C triggers separately or"
1267 " toghether as a AC class! Make sure this assumption holds in your case");
1268
1269 // use an anum for the different trigger classes, to make loops easier to read
1270 enum {kClassB =0 , kClassA, kClassC, kClassAC, kClassE, kNClasses};
1271 const char * classFlags[] = {"B", "A", "C", "AC", "E"}; // labels
1272
1273 UInt_t * rows[kNClasses] = {0}; // Array of matching rows
1274 Int_t nrows[kNClasses] = {0};
1275 // Get rows matching the requested trigger bits for all trigger classes
1276 for(Int_t iTrigClass = 0; iTrigClass < kNClasses; iTrigClass++){
1277 nrows[iTrigClass] = GetStatRow(classFlags[iTrigClass],fComputeBG,&rows[iTrigClass]);
1278 }
1279
5f337f3d 1280 // 0. Determine the ratios of triggers E/B, A/B, C/B from the stat histogram
1281 // Those are used to rescale the different classes to the same number of bx ids
141265a2 1282 // TODO: pass names of the rows for B, CA and E and look names of the rows. How do I handle the case in which both AC are in the same row?
1283 Int_t nBXIds[kNClasses] = {0};
1284 cout <<"Computing BG:" << endl;
1285
1286 for(Int_t iTrigClass = 0; iTrigClass < kNClasses; iTrigClass++){
1287 for(Int_t irow = 0; irow < nrows[iTrigClass]; irow++) {
1288 if(irow==0) cout << "- Class " << classFlags[iTrigClass] << endl;
1289 for (Int_t j=1; j<=fHistBunchCrossing->GetNbinsX(); j++) {
1290 if (fHistBunchCrossing->GetBinContent(j, rows[iTrigClass][irow]) > 0) {
1291 nBXIds[iTrigClass]++;
1292 }
1293 }
1294 if(nBXIds[iTrigClass]>0) cout << " Using row " << rows[iTrigClass][irow] << ": "
1295 << fHistBunchCrossing->GetYaxis()->GetBinLabel(rows[iTrigClass][irow])
1296 << " (nBXID "<< nBXIds[iTrigClass] << ")"<< endl;
1297
1298 }
1299
5f337f3d 1300 }
141265a2 1301
1302 Float_t ratioToB[kNClasses];
1303 ratioToB[kClassE] = nBXIds[kClassE] >0 ? Float_t(nBXIds[kClassB])/nBXIds[kClassE] : 0;
1304 ratioToB[kClassA] = nBXIds[kClassA] >0 ? Float_t(nBXIds[kClassB])/nBXIds[kClassA] : 0;
1305 ratioToB[kClassC] = nBXIds[kClassC] >0 ? Float_t(nBXIds[kClassB])/nBXIds[kClassC] : 0;
1306 ratioToB[kClassAC] = nBXIds[kClassAC] >0 ? Float_t(nBXIds[kClassB])/nBXIds[kClassAC] : 0;
5f337f3d 1307 Printf("Ratio between the BX ids in the different trigger classes:");
141265a2 1308 Printf(" B/E = %d/%d = %f", nBXIds[kClassB],nBXIds[kClassE], ratioToB[kClassE] );
1309 Printf(" B/A = %d/%d = %f", nBXIds[kClassB],nBXIds[kClassA], ratioToB[kClassA] );
1310 Printf(" B/C = %d/%d = %f", nBXIds[kClassB],nBXIds[kClassC], ratioToB[kClassC] );
1311 Printf(" B/AC = %d/%d = %f", nBXIds[kClassB],nBXIds[kClassAC],ratioToB[kClassAC]);
85c71ba7 1312 Int_t nHistStat = 2;
85c71ba7 1313
141265a2 1314 // 1. loop over all cols
85c71ba7 1315 for(Int_t iHistStat = 0; iHistStat < nHistStat; iHistStat++){
85c71ba7 1316 Int_t ncol = fHistStatistics[iHistStat]->GetNbinsX();
141265a2 1317 Float_t good1 = 0;
85c71ba7 1318 for(Int_t icol = 1; icol <= ncol; icol++) {
141265a2 1319 Int_t nEvents[kNClasses] = {0}; // number of events should be reset at every column
1320 // For all trigger classes, add up over row matching trigger mask (as selected before)
1321 for(Int_t iTrigClass = 0; iTrigClass < kNClasses; iTrigClass++){
1322 for(Int_t irow = 0; irow < nrows[iTrigClass]; irow++) {
1323 nEvents[iTrigClass] += (Int_t) fHistStatistics[iHistStat]->GetBinContent(icol,rows[iTrigClass][irow]);
1324 }
1325 // cout << "Events " << classFlags[iTrigClass] << " ("<<icol<<") " << nEvents[iTrigClass] << endl;
1326 }
1327 if (nEvents[kClassB]>0) {
a67fbdc0 1328 Float_t acc = ratioToB[kClassE]*nEvents[kClassE];
141265a2 1329 Double_t acc_err = TMath::Sqrt(ratioToB[kClassE]*ratioToB[kClassE]*nEvents[kClassE]);
85c71ba7 1330 // Int_t bg = cint1A + cint1C - 2*acc;
141265a2 1331
1332 // Assuming that for a given class the triggers are either recorded as A+C or AC
1333 Float_t bg = nEvents[kClassAC] > 0 ?
1334 fBIFactorAC*(ratioToB[kClassAC]*nEvents[kClassAC] - 2*acc):
1335 fBIFactorA* (ratioToB[kClassA]*nEvents[kClassA]-acc) +
1336 fBIFactorC* (ratioToB[kClassC]*nEvents[kClassC]-acc) ;
1337
8fc17e87 1338 // cout << "-----------------------" << endl;
1339 // cout << "Factors: " << fBIFactorA << " " << fBIFactorC << " " << fBIFactorAC << endl;
1340 // cout << "Ratios: " << ratioToB[kClassA] << " " << ratioToB[kClassC] << " " << ratioToB[kClassAC] << endl;
1341 // cout << "Evts: " << nEvents[kClassA] << " " << nEvents[kClassC] << " " << nEvents[kClassAC] << " " << nEvents[kClassB] << endl;
1342 // cout << "Acc: " << acc << endl;
141265a2 1343 // cout << "BG: " << bg << endl;
1344 // cout << " " << fBIFactorA* (ratioToB[kClassA]*nEvents[kClassA]-acc) <<endl;
1345 // cout << " " << fBIFactorC* (ratioToB[kClassC]*nEvents[kClassC]-acc) <<endl;
1346 // cout << " " << fBIFactorAC*(ratioToB[kClassAC]*nEvents[kClassAC] - 2*acc) << endl;
1347 // cout << "-----------------------" << endl;
1348
1349 Float_t good = Float_t(nEvents[kClassB]) - bg - acc;
85c71ba7 1350 if (icol ==1) good1 = good;
141265a2 1351 // Float_t errGood = TMath::Sqrt(2*(nEvents[kClassA]+nEvents[kClassC]+nEvents[kClassE]));// Error on the number of goods assuming only bg fluctuates
85c71ba7 1352 // DeltaG^2 = B + FA^2 A + FC^2 C + Ratio^2 (FA+FC-1)^2 E.
141265a2 1353 Float_t errGood = nEvents[kClassAC] > 0 ?
1354 TMath::Sqrt( nEvents[kClassB] +
1355 fBIFactorAC*fBIFactorAC*ratioToB[kClassAC]*ratioToB[kClassAC]*nEvents[kClassAC] +
1356 ratioToB[kClassE] * ratioToB[kClassE] *
1357 (fBIFactorAC - 1)*(fBIFactorAC - 1)*nEvents[kClassE]) :
1358 TMath::Sqrt( nEvents[kClassB] +
1359 fBIFactorA*fBIFactorA*ratioToB[kClassA]*ratioToB[kClassA]*nEvents[kClassA] +
1360 fBIFactorC*fBIFactorC*ratioToB[kClassC]*ratioToB[kClassC]*nEvents[kClassC] +
1361 ratioToB[kClassE] * ratioToB[kClassE] *
1362 (fBIFactorA + fBIFactorC - 1)*(fBIFactorA + fBIFactorC - 1)*nEvents[kClassE]);
1363
1364 Float_t errBG = nEvents[kClassAC] > 0 ?
1365 TMath::Sqrt(fBIFactorAC*fBIFactorAC*ratioToB[kClassAC]*ratioToB[kClassAC]*nEvents[kClassAC]+
1366 4*ratioToB[kClassE]*ratioToB[kClassE]*(fBIFactorAC*fBIFactorAC)*nEvents[kClassE]) :
1367 TMath::Sqrt(fBIFactorA*fBIFactorA*ratioToB[kClassA]*ratioToB[kClassA]*nEvents[kClassA]+
1368 fBIFactorC*fBIFactorC*ratioToB[kClassC]*ratioToB[kClassC]*nEvents[kClassC]+
1369 ratioToB[kClassE]*ratioToB[kClassE]*(fBIFactorA+fBIFactorC)*(fBIFactorA+fBIFactorC)*nEvents[kClassE]);
85c71ba7 1370
1371
141265a2 1372 fHistStatistics[iHistStat]->SetBinContent(icol,fBGStatOffset+kStatRowBG,bg);
1373 fHistStatistics[iHistStat]->SetBinError (icol,fBGStatOffset+kStatRowBG,errBG);
1374 fHistStatistics[iHistStat]->SetBinContent(icol,fBGStatOffset+kStatRowAcc,acc);
1375 fHistStatistics[iHistStat]->SetBinError (icol,fBGStatOffset+kStatRowAcc,acc_err);
1376 fHistStatistics[iHistStat]->SetBinContent(icol,fBGStatOffset+kStatRowGood,good);
1377 fHistStatistics[iHistStat]->SetBinError (icol,fBGStatOffset+kStatRowGood,errGood);
85c71ba7 1378
1379#ifdef VERBOSE_STAT
141265a2 1380 //kStatRowBG=0,kStatRowAcc,kStatRowBGFrac,kStatRowAccFrac,kStatRowErrGoodFrac,kStatRowGoodFrac,kStatRowGood,kStatRowErrGood
1381 Float_t accFrac = Float_t(acc) / nEvents[kClassB] *100;
1382 Float_t errAccFrac= Float_t(acc_err) / nEvents[kClassB] *100;
1383 Float_t bgFrac = Float_t(bg) / nEvents[kClassB] *100;
85c71ba7 1384 Float_t goodFrac = Float_t(good) / good1 *100;
1385 Float_t errGoodFrac = errGood/good1 * 100;
141265a2 1386 Float_t errFracBG = bg > 0 ? TMath::Sqrt((errBG/bg)*(errBG/bg) + 1/nEvents[kClassB])*bgFrac : 0;
1387 fHistStatistics[iHistStat]->SetBinContent(icol,fBGStatOffset+kStatRowBGFrac,bgFrac);
1388 fHistStatistics[iHistStat]->SetBinError (icol,fBGStatOffset+kStatRowBGFrac,errFracBG);
1389 fHistStatistics[iHistStat]->SetBinContent(icol,fBGStatOffset+kStatRowAccFrac,accFrac);
1390 fHistStatistics[iHistStat]->SetBinError (icol,fBGStatOffset+kStatRowAccFrac,errAccFrac);
1391 fHistStatistics[iHistStat]->SetBinContent(icol,fBGStatOffset+kStatRowGoodFrac,goodFrac);
1392 fHistStatistics[iHistStat]->SetBinContent(icol,fBGStatOffset+kStatRowErrGoodFrac,errGoodFrac);
1393 fHistStatistics[iHistStat]->SetBinContent(icol,fBGStatOffset+kStatRowErrGood,errGood);
85c71ba7 1394#endif
1395 }
1396 }
1397 }
ed185ba9 1398 for (Int_t iTrigClass = 0; iTrigClass < kNClasses; iTrigClass++){
1399 delete [] rows[iTrigClass];
1400 }
85c71ba7 1401 }
1402 }
1403
1404 fHistStatistics[0]->Write();
1405 fHistStatistics[1]->Write();
8e58a7b9 1406 if(fHistBunchCrossing ) fHistBunchCrossing ->Write();
1407 if(fHistTriggerPattern) fHistTriggerPattern->Write();
61899827 1408
296dd262 1409 Int_t count = fCollTrigClasses.GetEntries() + fBGTrigClasses.GetEntries();
1410 for (Int_t i=0; i < count; i++)
1411 {
1412 TString triggerClass = "trigger_histograms_";
1413 if (i < fCollTrigClasses.GetEntries())
1414 triggerClass += ((TObjString*) fCollTrigClasses.At(i))->String();
1415 else
1416 triggerClass += ((TObjString*) fBGTrigClasses.At(i - fCollTrigClasses.GetEntries()))->String();
61899827 1417
296dd262 1418 gDirectory->mkdir(triggerClass);
1419 gDirectory->cd(triggerClass);
61899827 1420
296dd262 1421 static_cast<AliTriggerAnalysis*> (fTriggerAnalysis.At(i))->SaveHistograms();
1422
1423 gDirectory->cd("..");
1424 }
1425
1426 if (fBackgroundIdentification)
1427 {
1428 gDirectory->mkdir("background_identification");
1429 gDirectory->cd("background_identification");
1430
1431 fBackgroundIdentification->GetOutput()->Write();
1432
1433 gDirectory->cd("..");
1434 }
61899827 1435
1436 if (folder)
1437 gDirectory->cd("..");
1438}
85c71ba7 1439
141265a2 1440Int_t AliPhysicsSelection::GetStatRow(const char * triggerBXClass, UInt_t offlineTriggerType, UInt_t ** rowIDs) const {
1441 // Puts inside the array rowIDs the row number for a given offline
1442 // trigger in a given bx class. Returns the total number of lines
1443 // matching the selection
1444 // triggerBXClass can be either "A", "AC", "B" or "E"
1445 // offlineTriggerType is one of the types defined in AliVEvent
1446 // User should delete rowIDs if no longer needed
1447
1448 if(!fHistStatistics[0]) {
1449 AliWarning("Not initialized, returning 0");
1450 return 0;
1451 }
1452 const Int_t nrows = fHistStatistics[0]->GetNbinsY();
1453
1454 // allocate memory for at maximum nrows
1455 Int_t nMatches = 0;
1456 (*rowIDs) = new UInt_t[nrows];
1457
1458 // Build regular expression. look for a +, followed by the beginning
1459 // of a word. Within the word, look for the class id after any
1460 // number of any char, but at most one dash ("[^-]*-?"), followed by
1461 // a - and then any char (".*") and at the class id ("\\&(\\d)")
1462 // The class id is stored.
1463 // WARNING: please check this if the trigger classes change
1464 TPRegexp re(Form("\\+\\b[^-]*-?%s-.*\\&(\\d)",triggerBXClass));
1465 // Loop over rows and find matching ones:
1466 for(Int_t irow = 1; irow <= nrows; irow++){
1467 TObjArray * matches = re.MatchS(fHistStatistics[0]->GetYaxis()->GetBinLabel(irow));
1468 if (matches->GetEntries()) {
1469 TString s = ((TObjString*)matches->At(1))->GetString();
1470 if(UInt_t(s.Atoi()) & offlineTriggerType) { // bitwise comparison with the requested mask
1471 // cout << "Marching " << s.Data() << " " << offlineTriggerType << " " << fHistStatistics[0]->GetYaxis()->GetBinLabel(irow) << endl;
1472 (*rowIDs)[nMatches] = irow;
1473 nMatches++;
1474 }
1475 }
1476 delete matches;
85c71ba7 1477 }
141265a2 1478
1479 return nMatches;
1480}
85c71ba7 1481
141265a2 1482void AliPhysicsSelection::SetBIFactors(const AliESDEvent * aESD) {
1483 // Set factors for realtive bunch intesities
1484 if(!aESD) {
1485 AliFatal("ESD not given");
1486 }
1487 Int_t run = aESD->GetRunNumber();
1488 if (run > 105268) {
1489 // intensities stored in the ESDs
1490 const AliESDRun* esdRun = aESD->GetESDRun();
1491 Double_t intAB = esdRun->GetMeanIntensityIntecting(0);
1492 Double_t intCB = esdRun->GetMeanIntensityIntecting(1);
1493 Double_t intAA = esdRun->GetMeanIntensityNonIntecting(0);
1494 Double_t intCC = esdRun->GetMeanIntensityNonIntecting(1);
1495
1496 // cout << "INT " <<intAB <<endl;
1497 // cout << "INT " <<intCB <<endl;
1498 // cout << "INT " <<intAA <<endl;
1499 // cout << "INT " <<intCC <<endl;
1500
1501 if (intAB > -1 && intAA > -1) {
1502 fBIFactorA = intAB/intAA;
1503 } else {
1504 AliWarning("Cannot set fBIFactorA, assuming 1");
1505 }
1506
1507 if (intCB > -1 && intCC > -1) {
1508 fBIFactorC = intCB/intCC;
1509 } else {
1510 AliWarning("Cannot set fBIFactorC, assuming 1");
1511 }
1512
1513 if (intAB > -1 && intAA > -1 &&
1514 intCB > -1 && intCC > -1) {
1515 fBIFactorAC = (intAB+intCB)/(intAA+intCC);
1516 } else {
1517 AliWarning("Cannot set fBIFactorAC, assuming 1");
1518 }
1519
1520 }
1521 else {
1522 // First runs. Intensities hardcoded
1523 switch(run) {
1524 case 104155:
1525 fBIFactorA = 0.961912722908;
1526 fBIFactorC = 1.04992336081;
1527 break;
1528 case 104157:
1529 fBIFactorA = 0.947312854998;
1530 fBIFactorC = 1.01599706417;
1531 break;
1532 case 104159:
1533 fBIFactorA = 0.93659320151;
1534 fBIFactorC = 0.98580804207;
1535 break;
1536 case 104160:
1537 fBIFactorA = 0.929664189926;
1538 fBIFactorC = 0.963467679851;
1539 break;
1540 case 104315:
1541 fBIFactorA = 1.08939104979;
1542 fBIFactorC = 0.931113921925;
1543 break;
1544 case 104316:
1545 fBIFactorA = 1.08351880974;
1546 fBIFactorC = 0.916068345845;
1547 break;
1548 case 104320:
1549 fBIFactorA = 1.07669281245;
1550 fBIFactorC = 0.876818744763;
1551 break;
1552 case 104321:
1553 fBIFactorA = 1.00971079602;
1554 fBIFactorC = 0.773781299076;
1555 break;
1556 case 104792:
1557 fBIFactorA = 0.787215863962;
1558 fBIFactorC = 0.778253173071;
1559 break;
1560 case 104793:
1561 fBIFactorA = 0.692211363661;
1562 fBIFactorC = 0.733152456667;
1563 break;
1564 case 104799:
1565 fBIFactorA = 1.04027825161;
1566 fBIFactorC = 1.00530825942;
1567 break;
1568 case 104800:
1569 fBIFactorA = 1.05309910671;
1570 fBIFactorC = 1.00376801855;
1571 break;
1572 case 104801:
1573 fBIFactorA = 1.0531231922;
1574 fBIFactorC = 0.992439666758;
1575 break;
1576 case 104802:
1577 fBIFactorA = 1.04191478134;
1578 fBIFactorC = 0.979368585208;
1579 break;
1580 case 104803:
1581 fBIFactorA = 1.03121314094;
1582 fBIFactorC = 0.973379962609;
1583 break;
1584 case 104824:
1585 fBIFactorA = 0.969945926722;
1586 fBIFactorC = 0.39549745806;
1587 break;
1588 case 104825:
1589 fBIFactorA = 0.968627213937;
1590 fBIFactorC = 0.310100412205;
1591 break;
1592 case 104841:
1593 fBIFactorA = 0.991601393212;
1594 fBIFactorC = 0.83762204722;
1595 break;
1596 case 104845:
1597 fBIFactorA = 0.98040863886;
1598 fBIFactorC = 0.694824205793;
1599 break;
1600 case 104867:
1601 fBIFactorA = 1.10646173412;
1602 fBIFactorC = 0.841407246916;
1603 break;
1604 case 104876:
1605 fBIFactorA = 1.12063452421;
1606 fBIFactorC = 0.78726542895;
1607 break;
1608 case 104890:
1609 fBIFactorA = 1.02346137453;
1610 fBIFactorC = 1.03355663595;
1611 break;
1612 case 104892:
1613 fBIFactorA = 1.05406025913;
1614 fBIFactorC = 1.00029166135;
1615 break;
1616 case 105143:
1617 fBIFactorA = 0.947343384349;
1618 fBIFactorC = 0.972637444408;
1619 break;
1620 case 105160:
1621 fBIFactorA = 0.908854622177;
1622 fBIFactorC = 0.958851103977;
1623 break;
1624 case 105256:
1625 fBIFactorA = 0.810076150206;
1626 fBIFactorC = 0.884663561883;
1627 break;
1628 case 105257:
1629 fBIFactorA = 0.80974912303;
1630 fBIFactorC = 0.878859123479;
1631 break;
1632 case 105268:
1633 fBIFactorA = 0.809052110679;
1634 fBIFactorC = 0.87233890989;
1635 break;
1636 default:
1637 fBIFactorA = 1;
1638 fBIFactorC = 1;
1639 }
1640 }
85c71ba7 1641
1642}