]> git.uio.no Git - u/mrichter/AliRoot.git/blame - ANALYSIS/AliPhysicsSelection.cxx
Changes for #93916 EMCAL commit attached patch and port to the release
[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//
869f9767 95// The class also supports the triggers used in heavy ion runs
96//
85c71ba7 97// Origin: Jan Fiete Grosse-Oetringhaus, CERN
98// Michele Floris, CERN
61899827 99//-------------------------------------------------------------------------
100
101#include <Riostream.h>
102#include <TH1F.h>
103#include <TH2F.h>
104#include <TList.h>
105#include <TIterator.h>
106#include <TDirectory.h>
296dd262 107#include <TObjArray.h>
7c55ebd9 108#include <TPRegexp.h>
109#include <TFormula.h>
110#include <TParameter.h>
111#include <TInterpreter.h>
61899827 112
113#include <AliPhysicsSelection.h>
114
115#include <AliTriggerAnalysis.h>
116#include <AliLog.h>
117
118#include <AliESDEvent.h>
85c71ba7 119#include <AliAnalysisTaskSE.h>
120#include "AliAnalysisManager.h"
141265a2 121#include "TPRegexp.h"
7c55ebd9 122#include "TFile.h"
123#include <AliOADBContainer.h>
124#include "AliOADBPhysicsSelection.h"
125#include "AliOADBFillingScheme.h"
eeaab745 126#include "AliOADBTriggerAnalysis.h"
61899827 127
128ClassImp(AliPhysicsSelection)
129
130AliPhysicsSelection::AliPhysicsSelection() :
296dd262 131 AliAnalysisCuts("AliPhysicsSelection", "AliPhysicsSelection"),
132 fCurrentRun(-1),
a2ce3799 133 fMC(kFALSE),
296dd262 134 fCollTrigClasses(),
135 fBGTrigClasses(),
136 fTriggerAnalysis(),
7c55ebd9 137// fHistStatisticsTokens(0),
91bea6e7 138 fHistBunchCrossing(0),
73cc8654 139 fHistTriggerPattern(0),
91bea6e7 140 fSkipTriggerClassSelection(0),
85c71ba7 141 fUsingCustomClasses(0),
142 fSkipV0(0),
8dec6e35 143 fBIFactorA(-1),
144 fBIFactorC(-1),
145 fBIFactorAC(-1),
85c71ba7 146 fComputeBG(0),
7c55ebd9 147 fBGStatOffset(-1),
73cc8654 148 fUseBXNumbers(1),
149 fUseMuonTriggers(0),
85c71ba7 150 fFillingScheme(""),
ff097e3f 151 fBin0CallBack(""),
869f9767 152 fBin0CallBackPointer(0),
7c55ebd9 153 fIsPP(kFALSE),
154 fPSOADB(0),
155 fFillOADB(0),
eeaab745 156 fTriggerOADB(0),
7c55ebd9 157 fRegexp(0),
158 fCashedTokens(0)
159
61899827 160{
161 // constructor
162
296dd262 163 fCollTrigClasses.SetOwner(1);
164 fBGTrigClasses.SetOwner(1);
165 fTriggerAnalysis.SetOwner(1);
85c71ba7 166 fHistStatistics[0] = 0;
167 fHistStatistics[1] = 0;
296dd262 168
7c55ebd9 169 fRegexp = new TPRegexp("([[:alpha:]]\\w*)");
170 fCashedTokens = new TList;
171 fCashedTokens->SetOwner();
172
61899827 173 AliLog::SetClassDebugLevel("AliPhysicsSelection", AliLog::kWarning);
174}
175
176AliPhysicsSelection::~AliPhysicsSelection()
177{
178 // destructor
85c71ba7 179
296dd262 180 fCollTrigClasses.Delete();
181 fBGTrigClasses.Delete();
182 fTriggerAnalysis.Delete();
61899827 183
85c71ba7 184 if (fHistStatistics[0])
185 {
186 delete fHistStatistics[0];
187 fHistStatistics[0] = 0;
188 }
189 if (fHistStatistics[1])
61899827 190 {
85c71ba7 191 delete fHistStatistics[1];
192 fHistStatistics[1] = 0;
61899827 193 }
7c55ebd9 194 // if (fHistStatisticsTokens) {
195 // delete fHistStatisticsTokens;
196 // fHistStatisticsTokens = 0;
197 // }
61899827 198 if (fHistBunchCrossing)
199 {
200 delete fHistBunchCrossing;
201 fHistBunchCrossing = 0;
202 }
73cc8654 203 if (fHistTriggerPattern)
204 {
205 delete fHistTriggerPattern;
206 fHistTriggerPattern = 0;
207 }
7c55ebd9 208
209 if (fPSOADB)
210 {
211 delete fPSOADB;
eeaab745 212 fPSOADB = 0;
7c55ebd9 213 }
214 if (fFillOADB)
215 {
216 delete fFillOADB;
217 fFillOADB = 0;
218 }
eeaab745 219 if (fTriggerOADB)
220 {
221 delete fTriggerOADB;
222 fTriggerOADB = 0;
223 }
7c55ebd9 224
225 if (fRegexp)
226 {
227 delete fRegexp;
228 fRegexp = 0;
229 }
230
231 if (fCashedTokens)
232 {
233 delete fCashedTokens;
234 fCashedTokens = 0;
235 }
236
237
61899827 238}
296dd262 239
c2ba5a61 240UInt_t AliPhysicsSelection::CheckTriggerClass(const AliESDEvent* aEsd, const char* trigger, Int_t& triggerLogic) const
296dd262 241{
242 // checks if the given trigger class(es) are found for the current event
05e1da5d 243 // format of trigger: +TRIGGER1,TRIGGER1b,TRIGGER1c -TRIGGER2 [#XXX] [&YY] [*ZZ]
244 // requires one out of TRIGGER1,TRIGGER1b,TRIGGER1c and rejects TRIGGER2
0c6c629b 245 // in bunch crossing XXX
1209509c 246 // if successful, YY is returned (for association between entry in fCollTrigClasses and AliVEvent::EOfflineTriggerTypes)
c2ba5a61 247 // triggerLogic is filled with ZZ, defaults to kCINT1
296dd262 248
decf6fd4 249 Bool_t foundBCRequirement = kFALSE;
250 Bool_t foundCorrectBC = kFALSE;
251
0c6c629b 252 UInt_t returnCode = AliVEvent::kUserDefined;
c2ba5a61 253 triggerLogic = kCINT1;
0c6c629b 254
6340be16 255 AliDebug(AliLog::kDebug+1, Form("Processing event with triggers %s", aEsd->GetFiredTriggerClasses().Data()));
256
296dd262 257 TString str(trigger);
258 TObjArray* tokens = str.Tokenize(" ");
259
260 for (Int_t i=0; i < tokens->GetEntries(); i++)
261 {
262 TString str2(((TObjString*) tokens->At(i))->String());
263
decf6fd4 264 if (str2[0] == '+' || str2[0] == '-')
296dd262 265 {
decf6fd4 266 Bool_t flag = (str2[0] == '+');
267
268 str2.Remove(0, 1);
269
05e1da5d 270 TObjArray* tokens2 = str2.Tokenize(",");
271
272 Bool_t foundTriggerClass = kFALSE;
273 for (Int_t j=0; j < tokens2->GetEntries(); j++)
decf6fd4 274 {
05e1da5d 275 TString str3(((TObjString*) tokens2->At(j))->String());
276
277 if (flag && aEsd->IsTriggerClassFired(str3))
278 foundTriggerClass = kTRUE;
279 if (!flag && aEsd->IsTriggerClassFired(str3))
280 {
7c55ebd9 281 AliDebug(AliLog::kDebug+1, Form("Rejecting event because trigger class %s is present", str3.Data()));
05e1da5d 282 delete tokens2;
283 delete tokens;
284 return kFALSE;
285 }
decf6fd4 286 }
05e1da5d 287
288 delete tokens2;
289
6340be16 290 if (flag && !foundTriggerClass)
decf6fd4 291 {
7c55ebd9 292 AliDebug(AliLog::kDebug+1, Form("Rejecting event because (none of the) trigger class(es) %s is present", str2.Data()));
decf6fd4 293 delete tokens;
294 return kFALSE;
295 }
296dd262 296 }
decf6fd4 297 else if (str2[0] == '#')
296dd262 298 {
decf6fd4 299 foundBCRequirement = kTRUE;
300
301 str2.Remove(0, 1);
302
303 Int_t bcNumber = str2.Atoi();
7c55ebd9 304 AliDebug(AliLog::kDebug+1, Form("Checking for bunch crossing number %d", bcNumber));
decf6fd4 305
306 if (aEsd->GetBunchCrossNumber() == bcNumber)
307 {
308 foundCorrectBC = kTRUE;
7c55ebd9 309 AliDebug(AliLog::kDebug+1, Form("Found correct bunch crossing %d", bcNumber));
decf6fd4 310 }
296dd262 311 }
7c55ebd9 312 else if (str2[0] == '&')
0c6c629b 313 {
314 str2.Remove(0, 1);
315
1209509c 316 returnCode = str2.Atoll();
0c6c629b 317 }
c2ba5a61 318 else if (str2[0] == '*')
319 {
320 str2.Remove(0, 1);
321
322 triggerLogic = str2.Atoi();
323 }
decf6fd4 324 else
325 AliFatal(Form("Invalid trigger syntax: %s", trigger));
296dd262 326 }
327
328 delete tokens;
decf6fd4 329
330 if (foundBCRequirement && !foundCorrectBC)
331 return kFALSE;
332
0c6c629b 333 return returnCode;
296dd262 334}
2d45a1a7 335
336//______________________________________________________________________________
7c55ebd9 337TObject *AliPhysicsSelection::GetStatistics(const Option_t *option) const
2d45a1a7 338{
7c55ebd9 339// Get the statistics histograms ("ALL" and "BIN0" and "TOK")
2d45a1a7 340 TString opt(option);
341 opt.ToUpper();
342 Int_t ihist = 0;
343 if (opt == "ALL") ihist = kStatIdxAll;
344 if (opt == "BIN0") ihist = kStatIdxBin0;
7c55ebd9 345 // if (opt == "TOK") return fHistStatisticsTokens;
2d45a1a7 346 return fHistStatistics[ihist];
347}
348
7c55ebd9 349//______________________________________________________________________________
350Bool_t AliPhysicsSelection::EvaluateTriggerLogic(const AliESDEvent* aEsd, AliTriggerAnalysis* triggerAnalysis, const char* triggerLogic, Bool_t offline)
351{
352 // evaluates trigger logic. If called with no ESD pointer/triggerAnalysis pointer, it just caches the tokens
353 // Fills the statistics histogram, if booked at row i
354 TString trigger(triggerLogic);
355
356 // add space after each token (to use ReplaceAll later)
357 fRegexp->Substitute(trigger, "$1 ", "g");
358
359 while (1)
360 {
361 AliDebug(AliLog::kDebug, trigger.Data());
362
363 TArrayI pos;
364 Int_t nMatches = fRegexp->Match(trigger, "", 0, 2, &pos);
365
366 if (nMatches <= 0)
367 break;
368
369 TString token(trigger(pos[0], pos[1]-pos[0]+1));
370
371 TParameter<Int_t>* param = (TParameter<Int_t>*) fCashedTokens->FindObject(token);
372 if (!param)
373 {
374 TInterpreter::EErrorCode error;
375 Int_t bit = gInterpreter->ProcessLine(Form("AliTriggerAnalysis::k%s;", token.Data()), &error);
376
377 if (error > 0)
378 AliFatal(Form("Trigger token %s unknown", token.Data()));
379
380 param = new TParameter<Int_t>(token, bit);
381 fCashedTokens->Add(param);
382 AliDebug(AliLog::kDebug, "Added token");
383 }
384
385 Long64_t bit = param->GetVal();
386
387 AliDebug(AliLog::kDebug, Form("Tok %d %d %s %lld", pos[0], pos[1], token.Data(), bit));
388
389 if (offline)
390 bit |= AliTriggerAnalysis::kOfflineFlag;
391
392 if(aEsd && triggerAnalysis) {
393 trigger.ReplaceAll(token, Form("%d", triggerAnalysis->EvaluateTrigger(aEsd, (AliTriggerAnalysis::Trigger) bit)));
394 // if(fHistStatisticsTokens)
395 }
396 }
7a4eb25e 397
7c55ebd9 398 TFormula formula("formula", trigger);
7a4eb25e 399 if (formula.Compile() > 0)
400 AliFatal(Form("Could not evaluate trigger logic %s (evaluated to %s)", triggerLogic, trigger.Data()));
7c55ebd9 401 Bool_t result = formula.Eval(0);
402
403 AliDebug(AliLog::kDebug, Form("%s --> %d", trigger.Data(), result));
404
405 return result;
406}
407
2d45a1a7 408//______________________________________________________________________________
0c6c629b 409UInt_t AliPhysicsSelection::IsCollisionCandidate(const AliESDEvent* aEsd)
61899827 410{
411 // checks if the given event is a collision candidate
0c6c629b 412 //
413 // returns a bit word describing the fired offline triggers (see AliVEvent::EOfflineTriggerTypes)
7acc5b9d 414 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
415 if (!mgr) {
416 AliError("Cannot get the analysis manager");
417 return 0;
418 }
419 mgr->LoadBranch("AliESDHeader.");
420 mgr->LoadBranch("AliESDRun.");
1ea7a921 421
141265a2 422 if (fCurrentRun != aEsd->GetRunNumber()) {
1107e2ce 423 if (!Initialize(aEsd))
95e6f4ec 424 AliFatal(Form("Could not initialize for run %d", aEsd->GetRunNumber()));
141265a2 425 if(fComputeBG) SetBIFactors(aEsd); // is this safe here?
426 }
61899827 427 const AliESDHeader* esdHeader = aEsd->GetHeader();
428 if (!esdHeader)
429 {
430 AliError("ESD Header could not be retrieved");
431 return kFALSE;
432 }
433
a2ce3799 434 // check event type; should be PHYSICS = 7 for data and 0 for MC
435 if (!fMC)
436 {
437 if (esdHeader->GetEventType() != 7)
438 return kFALSE;
439 }
440 else
441 {
442 if (esdHeader->GetEventType() != 0)
443 AliFatal(Form("Invalid event type for MC: %d", esdHeader->GetEventType()));
444 }
758941d4 445
1ea7a921 446 mgr->LoadBranch("AliMultiplicity.");
447//mgr->LoadBranch("AliESDFMD.");
448 mgr->LoadBranch("AliESDVZERO.");
449 mgr->LoadBranch("AliESDZDC.");
450 mgr->LoadBranch("SPDVertex.");
451 mgr->LoadBranch("PrimaryVertex.");
452 mgr->LoadBranch("TPCVertex.");
453 mgr->LoadBranch("Tracks");
454 mgr->LoadBranch("SPDPileupVertices");
455
0c6c629b 456 UInt_t accept = 0;
296dd262 457
458 Int_t count = fCollTrigClasses.GetEntries() + fBGTrigClasses.GetEntries();
459 for (Int_t i=0; i < count; i++)
61899827 460 {
296dd262 461 const char* triggerClass = 0;
462 if (i < fCollTrigClasses.GetEntries())
463 triggerClass = ((TObjString*) fCollTrigClasses.At(i))->String();
464 else
465 triggerClass = ((TObjString*) fBGTrigClasses.At(i - fCollTrigClasses.GetEntries()))->String();
61899827 466
7c55ebd9 467 AliDebug(AliLog::kDebug+1, Form("Processing trigger class %s", triggerClass));
61899827 468
296dd262 469 AliTriggerAnalysis* triggerAnalysis = static_cast<AliTriggerAnalysis*> (fTriggerAnalysis.At(i));
61899827 470
296dd262 471 triggerAnalysis->FillTriggerClasses(aEsd);
61899827 472
c2ba5a61 473 Int_t triggerLogic = 0;
474 UInt_t singleTriggerResult = CheckTriggerClass(aEsd, triggerClass, triggerLogic);
475
0c6c629b 476 if (singleTriggerResult)
296dd262 477 {
478 triggerAnalysis->FillHistograms(aEsd);
479
85c71ba7 480 Bool_t isBin0 = kFALSE;
481 if (fBin0CallBack != "") {
85c71ba7 482 isBin0 = ((AliAnalysisTaskSE*)mgr->GetTask(fBin0CallBack.Data()))->IsEventInBinZero();
ff097e3f 483 } else if (fBin0CallBackPointer) {
484 isBin0 = (*fBin0CallBackPointer)(aEsd);
85c71ba7 485 }
ff097e3f 486
7c55ebd9 487 // ---->
488 // FIXME: this stuff is still used to fill the stat
489 // tables. Decide wethere we are switching to a new stat table
490 // (with all AliTriggerAnalysis tokens? Only we the tokens
491 // actually used in the selection?) and clean up
492
c2ba5a61 493 // hardware trigger
7c55ebd9 494 Int_t fastORHW = triggerAnalysis->EvaluateTrigger(aEsd, AliTriggerAnalysis::kSPDGFO); // SPD number of chips from trigger bits (!)
495 // Int_t fastORHWL1 = triggerAnalysis->EvaluateTrigger(aEsd, AliTriggerAnalysis::kSPDGFOL1); // SPD number of chips from trigger bits in second layer (!)
496 Bool_t v0AHW = fSkipV0 ? 0 : triggerAnalysis->EvaluateTrigger(aEsd, AliTriggerAnalysis::kV0A);// should replay hw trigger
497 Bool_t v0CHW = fSkipV0 ? 0 : triggerAnalysis->EvaluateTrigger(aEsd, AliTriggerAnalysis::kV0C);// should replay hw trigger
c2ba5a61 498
cc9d9320 499 // offline trigger
7c55ebd9 500 Int_t fastOROffline = triggerAnalysis->EvaluateTrigger(aEsd, (AliTriggerAnalysis::Trigger) (AliTriggerAnalysis::kOfflineFlag | AliTriggerAnalysis::kSPDGFO)); // SPD number of chips from clusters (!)
501 Int_t fastOROfflineL1 = triggerAnalysis->EvaluateTrigger(aEsd, (AliTriggerAnalysis::Trigger) (AliTriggerAnalysis::kOfflineFlag | AliTriggerAnalysis::kSPDGFOL1)); // SPD number of chips from clusters in second layer (!)
502 Bool_t v0A = fSkipV0 ? 0 : triggerAnalysis->EvaluateTrigger(aEsd, (AliTriggerAnalysis::Trigger) (AliTriggerAnalysis::kOfflineFlag | AliTriggerAnalysis::kV0A));
503 Bool_t v0C = fSkipV0 ? 0 : triggerAnalysis->EvaluateTrigger(aEsd, (AliTriggerAnalysis::Trigger) (AliTriggerAnalysis::kOfflineFlag | AliTriggerAnalysis::kV0C));
504 Bool_t v0ABG = fSkipV0 ? 0 : triggerAnalysis->EvaluateTrigger(aEsd, (AliTriggerAnalysis::Trigger) (AliTriggerAnalysis::kOfflineFlag | AliTriggerAnalysis::kV0ABG));
505 Bool_t v0CBG = fSkipV0 ? 0 : triggerAnalysis->EvaluateTrigger(aEsd, (AliTriggerAnalysis::Trigger) (AliTriggerAnalysis::kOfflineFlag | AliTriggerAnalysis::kV0CBG));
f4ca8f20 506 Bool_t v0BG = v0ABG || v0CBG;
559b5ed7 507 Bool_t t0 = triggerAnalysis->EvaluateTrigger(aEsd, (AliTriggerAnalysis::Trigger) (AliTriggerAnalysis::kOfflineFlag | AliTriggerAnalysis::kT0 ));
508 Bool_t t0BG = triggerAnalysis->EvaluateTrigger(aEsd, (AliTriggerAnalysis::Trigger) (AliTriggerAnalysis::kOfflineFlag | AliTriggerAnalysis::kT0BG ));
509 Bool_t t0PileUp = triggerAnalysis->EvaluateTrigger(aEsd, (AliTriggerAnalysis::Trigger) (AliTriggerAnalysis::kOfflineFlag | AliTriggerAnalysis::kT0Pileup));
85c71ba7 510
511 // fmd
396981c2 512 // Bool_t fmdA = triggerAnalysis->EvaluateTrigger(aEsd, (AliTriggerAnalysis::Trigger) (AliTriggerAnalysis::kOfflineFlag | AliTriggerAnalysis::kFMDA));
513 // Bool_t fmdC = triggerAnalysis->EvaluateTrigger(aEsd, (AliTriggerAnalysis::Trigger) (AliTriggerAnalysis::kOfflineFlag | AliTriggerAnalysis::kFMDC));
514 // Bool_t fmd = fmdA || fmdC;
61899827 515
85c71ba7 516 // SSD
1107e2ce 517 //Int_t ssdClusters = triggerAnalysis->SSDClusters(aEsd);
c2ba5a61 518
519 // ZDC
ce08cb1f 520 // Bool_t zdcA = triggerAnalysis->IsOfflineTriggerFired(aEsd, AliTriggerAnalysis::kZDCA);
521 // Bool_t zdcC = triggerAnalysis->IsOfflineTriggerFired(aEsd, AliTriggerAnalysis::kZDCC);
7c55ebd9 522 Bool_t zdcA = triggerAnalysis->EvaluateTrigger(aEsd, (AliTriggerAnalysis::Trigger) (AliTriggerAnalysis::kOfflineFlag | AliTriggerAnalysis::kZDCTDCA));
523 Bool_t zdcC = triggerAnalysis->EvaluateTrigger(aEsd, (AliTriggerAnalysis::Trigger) (AliTriggerAnalysis::kOfflineFlag | AliTriggerAnalysis::kZDCTDCC));
524 Bool_t zdcTime = triggerAnalysis->EvaluateTrigger(aEsd, (AliTriggerAnalysis::Trigger) (AliTriggerAnalysis::kOfflineFlag | AliTriggerAnalysis::kZDCTime));
85c71ba7 525
396981c2 526 Bool_t laserCut = triggerAnalysis->EvaluateTrigger(aEsd, (AliTriggerAnalysis::Trigger) (AliTriggerAnalysis::kOfflineFlag | AliTriggerAnalysis::kTPCLaserWarmUp));
527
85c71ba7 528 // Some "macros"
529 Bool_t mb1 = (fastOROffline > 0 || v0A || v0C) && (!v0BG);
530 Bool_t mb1prime = (fastOROffline > 1 || (fastOROffline > 0 && (v0A || v0C)) || (v0A && v0C) ) && (!v0BG);
531
532 // Background rejection
8663e267 533 Bool_t bgID = kFALSE;
1ea7a921 534 bgID = triggerAnalysis->EvaluateTrigger(aEsd, (AliTriggerAnalysis::Trigger) (AliTriggerAnalysis::kSPDClsVsTrkBG | AliTriggerAnalysis::kOfflineFlag)); // FIXME: temporarily, we keep both ways to validate the new one. if the external BG id is not set, it will use the new one
8663e267 535
c2ba5a61 536 /*Int_t ntrig = fastOROffline; // any 2 hits
85c71ba7 537 if(v0A) ntrig += 1;
538 if(v0C) ntrig += 1; //v0C alone is enough
539 if(fmd) ntrig += 1;
c2ba5a61 540 if(ssdClusters>1) ntrig += 1;*/
85c71ba7 541
7c55ebd9 542
543 // <---
544
545 TString triggerLogicOnline = fPSOADB->GetHardwareTrigger(triggerLogic);
546 TString triggerLogicOffline = fPSOADB->GetOfflineTrigger(triggerLogic);
547
010e7ad7 548 AliDebug(AliLog::kDebug, Form("Triggers from OADB [0x%x][%d][%s][%s]",singleTriggerResult,AliOADBPhysicsSelection::GetActiveBit(singleTriggerResult),triggerLogicOffline.Data(),triggerLogicOnline.Data()));
7c55ebd9 549
c2ba5a61 550 // replay hardware trigger (should only remove events for MC)
7c55ebd9 551 Bool_t onlineTrigger = EvaluateTriggerLogic(aEsd, triggerAnalysis, triggerLogicOnline, kFALSE);
552 // offline selection
553 Bool_t offlineTrigger = EvaluateTriggerLogic(aEsd, triggerAnalysis, triggerLogicOffline, kTRUE);
c2ba5a61 554
7c55ebd9 555 // Printf("%s %s", triggerLogicOnline.Data(), triggerLogicOffline.Data());
556 // Printf("%d %d", onlineTrigger, offlineTrigger);
557
85c71ba7 558
73cc8654 559 // Fill trigger pattern histo
560 Int_t tpatt = 0;
561 if (fastORHW>0) tpatt+=1;
562 if (v0AHW) tpatt+=2;
563 if (v0CHW) tpatt+=4;
564 fHistTriggerPattern->Fill( tpatt );
565
85c71ba7 566 // fill statistics and return decision
567 const Int_t nHistStat = 2;
568 for(Int_t iHistStat = 0; iHistStat < nHistStat; iHistStat++){
569 if (iHistStat == kStatIdxBin0 && !isBin0) continue; // skip the filling of bin0 stats if the event is not in the bin0
570
571 fHistStatistics[iHistStat]->Fill(kStatTriggerClass, i);
8dec6e35 572 if(iHistStat == kStatIdxAll) fHistBunchCrossing->Fill(aEsd->GetBunchCrossNumber(), i); // Fill only for all (avoid double counting)
85c71ba7 573
85c71ba7 574 // We fill the rest only if hw trigger is ok
7c55ebd9 575 if (!onlineTrigger)
85c71ba7 576 {
577 AliDebug(AliLog::kDebug, "Rejecting event because hardware trigger is not fired");
578 continue;
579 } else {
580 fHistStatistics[iHistStat]->Fill(kStatHWTrig, i);
581 }
733f0542 582
85c71ba7 583
584 // v0 BG stats
585 if (v0ABG)
586 fHistStatistics[iHistStat]->Fill(kStatV0ABG, i);
587 if (v0CBG)
588 fHistStatistics[iHistStat]->Fill(kStatV0CBG, i);
589
559b5ed7 590 // T0 stats
591 if(t0)
592 fHistStatistics[iHistStat]->Fill(kStatT0BB, i);
593 if(t0BG)
594 fHistStatistics[iHistStat]->Fill(kStatT0BG, i);
595 if(t0PileUp)
596 fHistStatistics[iHistStat]->Fill(kStatT0PileUp, i);
597
7c55ebd9 598 // mb 1
85c71ba7 599 if (mb1)
600 fHistStatistics[iHistStat]->Fill(kStatMB1, i);
85c71ba7 601
602 if (mb1prime)
603 fHistStatistics[iHistStat]->Fill(kStatMB1Prime, i);
604
396981c2 605 if (laserCut)
606 fHistStatistics[iHistStat]->Fill(kStatLaserCut, i);
85c71ba7 607
c2ba5a61 608 //if(ntrig >= 2 && !v0BG)
609 // fHistStatistics[iHistStat]->Fill(kStatAny2Hits, i);
85c71ba7 610
611 if (fastOROffline > 0)
612 fHistStatistics[iHistStat]->Fill(kStatFO1, i);
613 if (fastOROffline > 1)
614 fHistStatistics[iHistStat]->Fill(kStatFO2, i);
c2ba5a61 615 if (fastOROfflineL1 > 1)
616 fHistStatistics[iHistStat]->Fill(kStatFO2L1, i);
cc9d9320 617
85c71ba7 618 if (v0A)
619 fHistStatistics[iHistStat]->Fill(kStatV0A, i);
620 if (v0C)
621 fHistStatistics[iHistStat]->Fill(kStatV0C, i);
c2ba5a61 622
623 if (zdcA)
624 fHistStatistics[iHistStat]->Fill(kStatZDCA, i);
625 if (zdcC)
626 fHistStatistics[iHistStat]->Fill(kStatZDCC, i);
627 if (zdcA && zdcC)
628 fHistStatistics[iHistStat]->Fill(kStatZDCAC, i);
7c55ebd9 629
869f9767 630 if (zdcTime)
631 fHistStatistics[iHistStat]->Fill(kStatZDCTime, i);
296dd262 632
869f9767 633 if (v0A && v0C && !v0BG && (!bgID && fIsPP))
85c71ba7 634 fHistStatistics[iHistStat]->Fill(kStatV0, i);
635
1ea7a921 636 if (bgID && !v0BG)
637 fHistStatistics[iHistStat]->Fill(kStatBG, i);
7c55ebd9 638
639 // FIXME: check lines below
640 if ( offlineTrigger )
85c71ba7 641 {
642 if (!v0BG || fSkipV0)
643 {
644 if (!v0BG) fHistStatistics[iHistStat]->Fill(kStatOffline, i);
1ea7a921 645 AliDebug(AliLog::kDebug, Form("Accepted event for histograms with trigger logic %d", triggerLogic));
296dd262 646
1ea7a921 647 fHistStatistics[iHistStat]->Fill(kStatAccepted, i);
648
649 if (aEsd->IsPileupFromSPD())
650 fHistStatistics[iHistStat]->Fill(kStatAcceptedPileUp, i);
651
8dec6e35 652 // if(iHistStat == kStatIdxAll) fHistBunchCrossing->Fill(aEsd->GetBunchCrossNumber(), i); // Fill only for all (avoid double counting)
1ea7a921 653 if((i < fCollTrigClasses.GetEntries() || fSkipTriggerClassSelection) && (iHistStat==kStatIdxAll))
654 accept |= singleTriggerResult; // only set for "all" (should not really matter)
85c71ba7 655 }
656 else
657 AliDebug(AliLog::kDebug, "Rejecting event because of V0 BG flag");
658 }
659 else
c2ba5a61 660 AliDebug(AliLog::kDebug, Form("Rejecting event because trigger logic %d is not fulfilled", triggerLogic));
296dd262 661 }
296dd262 662 }
663 }
664
665 if (accept)
0c6c629b 666 AliDebug(AliLog::kDebug, Form("Accepted event as collision candidate with bit mask %d", accept));
61899827 667
296dd262 668 return accept;
61899827 669}
a2ce3799 670
5f337f3d 671
7c55ebd9 672// const char * AliPhysicsSelection::GetFillingScheme(UInt_t runNumber) {
673
674// if(fMC) return "MC";
675
676// if (runNumber >= 104065 && runNumber <= 104160) {
677// return "4x4a";
678// }
679// else if (runNumber >= 104315 && runNumber <= 104321) {
680// return "4x4a*";
681// }
682// else if (runNumber >= 104792 && runNumber <= 104803) {
683// return "4x4b";
684// }
685// else if (runNumber >= 104824 && runNumber <= 104892) {
686// return "4x4c";
687// }
688// else if (runNumber == 105143 || runNumber == 105160) {
689// return "16x16a";
690// }
691// else if (runNumber >= 105256 && runNumber <= 105268) {
692// return "4x4c";
693// }
694// else if (runNumber >= 114786 && runNumber <= 116684) {
695// return "Single_2b_1_1_1";
696// }
697// else if (runNumber >= 117048 && runNumber <= 117120) {
698// return "Single_3b_2_2_2";
699// }
700// else if (runNumber >= 117220 && runNumber <= 119163) {
701// return "Single_2b_1_1_1";
702// }
703// else if (runNumber >= 119837 && runNumber <= 119862) {
704// return "Single_4b_2_2_2";
705// }
706// else if (runNumber >= 119902 && runNumber <= 120691) {
707// return "Single_6b_3_3_3";
708// }
709// else if (runNumber >= 120741 && runNumber <= 122375) {
710// return "Single_13b_8_8_8";
711// }
712// else if (runNumber >= 130148 && runNumber <= 130375) {
713// return "125n_48b_36_16_36";
714// }
715// else if (runNumber >= 130601 && runNumber <= 130640) {
716// return "1000ns_50b_35_14_35";
717// }
718// else {
719// AliError(Form("Unknown filling scheme (run %d)", runNumber));
720// }
721
722// return "Unknown";
723// }
724
725// const char * AliPhysicsSelection::GetBXIDs(UInt_t runNumber, const char * trigger) {
726
727// if (!fUseBXNumbers || fMC) return "";
728
729// if (runNumber >= 104065 && runNumber <= 104160) {
730// if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #2128 #3019";
731// else if(!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #346 #3465";
732// else if(!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #1234 #1680";
733// else if(!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #790";
734// // else AliError(Form("Unknown trigger: %s", trigger));
735// }
736// else if (runNumber >= 104315 && runNumber <= 104321) {
737// if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #2000 #2891";
738// else if(!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #218 #3337";
739// else if(!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #1106 #1552";
740// else if(!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #790";
741// // else AliError(Form("Unknown trigger: %s", trigger));
742// }
743// else if (runNumber >= 104792 && runNumber <= 104803) {
744// if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #2228 #3119";
745// else if(!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #2554 #446";
746// else if(!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #1334 #769";
747// else if(!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #790";
748// // else AliError(Form("Unknown trigger: %s", trigger));
749// }
750// else if (runNumber >= 104824 && runNumber <= 104892) {
751// if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #3119 #769";
752// else if(!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #2554 #446";
753// else if(!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #1334 #2228";
754// else if(!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #790";
755// // else AliError(Form("Unknown trigger: %s", trigger));
756// }
757// else if (runNumber == 105143 || runNumber == 105160) {
758// if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #1337 #1418 #2228 #2309 #3119 #3200 #446 #527";
759// else if(!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #1580 #1742 #1904 #2066 #2630 #2792 #2954 #3362";
760// else if(!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #845 #1007 #1169 #1577 #3359 #3521 #119 #281 ";
761// else if(!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #790";
762// // else AliError(Form("Unknown trigger: %s", trigger));
763// }
764// else if (runNumber >= 105256 && runNumber <= 105268) {
765// if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #3019 #669";
766// else if(!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #2454 #346";
767// else if(!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #1234 #2128";
768// else if(!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #790";
769// // else AliError(Form("Unknown trigger: %s", trigger));
770// } else if (runNumber >= 114786 && runNumber <= 116684) { // 7 TeV 2010, assume always the same filling scheme
771// if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #346";
772// else if(!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #2131";
773// else if(!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #3019";
774// else if(!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #1238";
775// // else AliError(Form("Unknown trigger: %s", trigger));
776// }
777// else if (runNumber >= 117048 && runNumber <= 117120) {
778// // return "Single_3b_2_2_2";
779// if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #346 #1240 ";
780// else if (!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #2131 ";
781// else if (!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #3019 ";
782// else if (!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #1238";
783// // else AliError(Form("Unknown trigger: %s", trigger));
784
785// }
786// else if ((runNumber >= 117220 && runNumber <= 118555) || (runNumber >= 118784 && runNumber <= 119163))
787// {
788// // return "Single_2b_1_1_1";
789// if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #346 ";
790// else if (!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #2131 ";
791// else if (!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #3019 ";
792// else if (!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #1238 ";
793// // else AliError(Form("Unknown trigger: %s", trigger));
794// }
795// else if (runNumber >= 118556 && runNumber <= 118783) {
796// // return "Single_2b_1_1_1";
797// // same as previous but was misaligned by 1 BX in fill 1069
798// if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #345 ";
799// else if (!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #2130 ";
800// else if (!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #3018 ";
801// else if (!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #1238 ";
802// // else AliError(Form("Unknown trigger: %s", trigger));
803// }
804// else if (runNumber >= 119837 && runNumber <= 119862) {
805// // return "Single_4b_2_2_2";
806// if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #669 #3019 ";
807// else if (!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #346 #2454 ";
808// else if (!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #1234 #2128 ";
809// else if (!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #1681 #3463";
810// // else AliError(Form("Unknown trigger: %s", trigger));
811
812// }
813// else if (runNumber >= 119902 && runNumber <= 120691) {
814// // return "Single_6b_3_3_3";
815// if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #346 #546 #746 ";
816// else if (!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #2131 #2331 #2531 ";
817// else if (!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #3019 #3219 #3419 ";
818// else if (!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #1296 #1670";
819// // else AliError(Form("Unknown trigger: %s", trigger));
820// }
821// else if (runNumber >= 120741 && runNumber <= 122375) {
822// // return "Single_13b_8_8_8";
823// if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #346 #446 #546 #646 #1240 #1340 #1440 #1540 ";
824// else if (!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #946 #2131 #2231 #2331 #2431 ";
825// else if (!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #3019 #3119 #3219 #3319 #3519 ";
826// else if (!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #1835 #2726";
827// // else AliError(Form("Unknown trigger: %s", trigger));
5f337f3d 828
7c55ebd9 829// }
830// else if (runNumber >= 130148 && runNumber <= 130375) {
831// TString triggerString = trigger;
832// static TString returnString = " ";
833// returnString = "";
834// if (triggerString.Contains("B")) returnString += " #346 #396 #446 #496 #546 #596 #646 #696 #1240 #1290 #1340 #1390 #1440 #1490 #1540 #1590 ";
835// 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 ";
836// 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 ";
837// // Printf("0x%x",returnString.Data());
838// // Printf("%s",returnString.Data());
839// return returnString.Data();
840// }
841// else if (runNumber >= 130601 && runNumber <= 130640) {
842// TString triggerString = trigger;
843// static TString returnString = " ";
844// returnString = "";
845// if (triggerString.Contains("B")) returnString += " #346 #386 #426 #466 #506 #546 #586 #1240 #1280 #1320 #1360 #1400 #1440 #1480 ";
846// 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
847// 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
848// return returnString.Data();
849// }
850
851// else {
852// AliWarning(Form("Unknown run %d, using all BXs!",runNumber));
853// }
854
855// return "";
856// }
1107e2ce 857
858Bool_t AliPhysicsSelection::Initialize(const AliESDEvent* aEsd)
859{
860 // initializes the object for the given ESD
861
c8aeecab 862 AliInfo(Form("Initializing for beam type: %s", aEsd->GetESDRun()->GetBeamType()));
869f9767 863 fIsPP = kTRUE;
c915635b 864 if (strcmp(aEsd->GetESDRun()->GetBeamType(), "A-A") == 0)
869f9767 865 fIsPP = kFALSE;
866
7c55ebd9 867 return Initialize(aEsd->GetRunNumber());
1107e2ce 868}
869
7c55ebd9 870Bool_t AliPhysicsSelection::Initialize(Int_t runNumber)
61899827 871{
7c55ebd9 872 // initializes the object for the given run
873
874
29e8486e 875 Bool_t oldStatus = TH1::AddDirectoryStatus();
876 TH1::AddDirectory(kFALSE);
7c55ebd9 877
878 /// Open OADB file and fetch OADB objects
879 TString oadbfilename = AliPhysicsSelection::GetOADBFileName();
880
28cbc692 881 TFile * foadb = TFile::Open(oadbfilename);
7c55ebd9 882 if(!foadb->IsOpen()) AliFatal(Form("Cannot open OADB file %s", oadbfilename.Data()));
883
884
885 if(!fPSOADB || !fUsingCustomClasses) { // if it's already set and custom class is required, we use the one provided by the user
886 AliInfo("Using Standard OADB");
887 AliOADBContainer * psContainer = (AliOADBContainer*) foadb->Get("physSel");
6340be16 888 if (!psContainer) AliFatal("Cannot fetch OADB container for Physics selection");
889 fPSOADB = (AliOADBPhysicsSelection*) psContainer->GetObject(runNumber, fIsPP ? "oadbDefaultPP" : "oadbDefaultPbPb");
7c55ebd9 890 if (!fPSOADB) AliFatal(Form("Cannot find physics selection object for run %d", runNumber));
891 } else {
892 AliInfo("Using Custom OADB");
893 }
894 if(!fFillOADB || !fUsingCustomClasses) { // if it's already set and custom class is required, we use the one provided by the user
895 AliOADBContainer * fillContainer = (AliOADBContainer*) foadb->Get("fillScheme");
6340be16 896 if (!fillContainer) AliFatal("Cannot fetch OADB container for filling scheme");
7c55ebd9 897 fFillOADB = (AliOADBFillingScheme*) fillContainer->GetObject(runNumber, "Default");
898 if (!fFillOADB) AliFatal(Form("Cannot find filling scheme object for run %d", runNumber));
899 }
eeaab745 900 if(!fTriggerOADB || !fUsingCustomClasses) { // if it's already set and custom class is required, we use the one provided by the user
901 AliOADBContainer * triggerContainer = (AliOADBContainer*) foadb->Get("trigAnalysis");
902 if (!triggerContainer) AliFatal("Cannot fetch OADB container for trigger analysis");
903 fTriggerOADB = (AliOADBTriggerAnalysis*) triggerContainer->GetObject(runNumber, "Default");
904 fTriggerOADB->Print();
905 if (!fTriggerOADB) AliFatal(Form("Cannot find trigger analysis object for run %d", runNumber));
906 }
7c55ebd9 907
29e8486e 908
85c71ba7 909 if(!fBin0CallBack)
910 AliError("Bin0 Callback not set: will not fill the statistics for the bin 0");
911
912 if (fMC) {
0c6c629b 913 // override BX and bg options in case of MC
85c71ba7 914 fComputeBG = kFALSE;
915 fUseBXNumbers = kFALSE;
916 }
917
7c55ebd9 918 // FIXME: think how to implement this check with the OADB, trigger scheme is not a int number here
919 // Int_t triggerScheme = GetTriggerScheme(runNumber);
920 // if (!fUsingCustomClasses && fCurrentRun != -1 && triggerScheme != GetTriggerScheme(fCurrentRun))
921 // AliFatal("Processing several runs with different trigger schemes is not supported");
296dd262 922
85c71ba7 923 if(fComputeBG && fCurrentRun != -1 && fCurrentRun != runNumber)
924 AliFatal("Cannot process several runs because BG computation is requested");
925
926 if(fComputeBG && !fUseBXNumbers)
e0bf2892 927 AliFatal("Cannot compute BG if BX numbers are not used");
85c71ba7 928
7c55ebd9 929 if(fUseBXNumbers && fFillingScheme != "" && fFillingScheme != fFillOADB->GetFillingSchemeName())
85c71ba7 930 AliFatal("Cannot process runs with different filling scheme if usage of BX numbers is requested");
931
7c55ebd9 932 fFillingScheme = fFillOADB->GetFillingSchemeName();
85c71ba7 933
61899827 934 AliInfo(Form("Initializing for run %d", runNumber));
935
758941d4 936 // initialize first time?
a2ce3799 937 if (fCurrentRun == -1)
a2ce3799 938 {
7c55ebd9 939 const UInt_t ntriggerBits = fPSOADB->GetNTriggerBits(); // FIXME!
940 for(UInt_t ibit = 0; ibit < ntriggerBits; ibit++){
941
942 TIterator * collIter = fPSOADB->GetCollTrigClass(ibit)->MakeIterator();
943 TIterator * bgIter = fPSOADB->GetBGTrigClass(ibit)->MakeIterator();
944 TObjString * obj = 0;
945 while((obj = (TObjString*) collIter->Next())){
946 if (obj->String() != "") {
947 fCollTrigClasses.Add(new TObjString(GetTriggerString(obj)));
948 }
1107e2ce 949 }
7c55ebd9 950 // BG classes only make sense for real data
951 if(!fMC) {
952 obj = 0 ;
953 while((obj = (TObjString*) bgIter->Next())){
954 if (obj->String() != "") {
955 fBGTrigClasses.Add(new TObjString(GetTriggerString(obj)));
956 }
957 }
91bea6e7 958 }
7c55ebd9 959
a2ce3799 960 }
7c55ebd9 961 // not sure how to handle this in the case of > x cuts
962 // // Book the token histo with the tokens actually used here!
963 // // 1. Cache the tokens
964 // for(UInt_t ibit = 0; ibit < ntriggerBits; ibit++){
965 // EvaluateTriggerLogic(0,0, fPSOADB->GetHardwareTrigger(ibit), 0);
966 // EvaluateTriggerLogic(0,0, fPSOADB->GetOfflineTrigger(ibit), 1);
967 // }
968 // // 2. Book the histogram
969 // if (!fHistStatisticsTokens) {
970 // Int_t ntokens = fCashedTokens->GetEntries();
971 // Int_t count = fCollTrigClasses->GetEntries() + fBGTrigClasses->GetEntries();
972 // fHistStatisticsTokens = new TH2F("fHistStatisticsTokens", "fHistStatisticsTokens", ntokens + 2, 0.5, ntokens+2+0.5, count, -0.5, -0.5 + count);
973
974 // Int_t nrow = 0;
975 // fHistStatisticsTokens->GetXaxis()->SetBinLabel(nrow++, "Trigger class");
976 // for(Int_t itoken = 0; itoken < ntoken; itoken++){
977 // TParameter<Int_t> * param = fCashedTokens->At(itoken);
978 // fHistStatisticsTokens->GetXaxis()->SetBinLabel(nrow++, param->GetName());
979 // }
980
981 // fHistStatisticsTokens->GetXaxis()->SetBinLabel(nrow++, "Accepted");
982
983 // }
984
985
91bea6e7 986
7c55ebd9 987 // TODO:
988 // Add a new statistics histo containing only the tokens actually used in the selection
989
a2ce3799 990 Int_t count = fCollTrigClasses.GetEntries() + fBGTrigClasses.GetEntries();
991
992 for (Int_t i=0; i<count; i++)
993 {
7c55ebd9 994
a2ce3799 995 AliTriggerAnalysis* triggerAnalysis = new AliTriggerAnalysis;
996 triggerAnalysis->SetAnalyzeMC(fMC);
997 triggerAnalysis->EnableHistograms();
998 triggerAnalysis->SetSPDGFOThreshhold(1);
4011b280 999 triggerAnalysis->SetDoFMD(kFALSE);
eeaab745 1000 triggerAnalysis->SetCorrZDCCutParams(fTriggerOADB->GetZDCCutRefSumCorr(),
1001 fTriggerOADB->GetZDCCutRefDeltaCorr(),
1002 fTriggerOADB->GetZDCCutSigmaSumCorr(),
1003 fTriggerOADB->GetZDCCutSigmaDeltaCorr());
a2ce3799 1004 fTriggerAnalysis.Add(triggerAnalysis);
1005 }
7c55ebd9 1006
1007
85c71ba7 1008 // TODO: shall I really delete this?
1009 if (fHistStatistics[0])
1010 delete fHistStatistics[0];
1011 if (fHistStatistics[1])
1012 delete fHistStatistics[1];
296dd262 1013
85c71ba7 1014 fHistStatistics[kStatIdxBin0] = BookHistStatistics("_Bin0");
1015 fHistStatistics[kStatIdxAll] = BookHistStatistics("");
a2ce3799 1016
7c55ebd9 1017
a2ce3799 1018 if (fHistBunchCrossing)
1019 delete fHistBunchCrossing;
1020
1021 fHistBunchCrossing = new TH2F("fHistBunchCrossing", "fHistBunchCrossing;bunch crossing number;", 4000, -0.5, 3999.5, count, -0.5, -0.5 + count);
73cc8654 1022
7c55ebd9 1023 // TODO: remove fHistTriggerPattern
73cc8654 1024 if (fHistTriggerPattern)
1025 delete fHistTriggerPattern;
1026
1027 const int ntrig=3;
85c71ba7 1028 Int_t n = 1;
73cc8654 1029 const Int_t nbinTrig = TMath::Nint(TMath::Power(2,ntrig));
1030
1031 fHistTriggerPattern = new TH1F("fHistTriggerPattern", "Trigger pattern: FO + 2*v0A + 4*v0C",
1032 nbinTrig, -0.5, nbinTrig-0.5);
1033 fHistTriggerPattern->GetXaxis()->SetBinLabel(1,"NO TRIG");
1034 fHistTriggerPattern->GetXaxis()->SetBinLabel(2,"FO");
1035 fHistTriggerPattern->GetXaxis()->SetBinLabel(3,"v0A");
1036 fHistTriggerPattern->GetXaxis()->SetBinLabel(4,"FO & v0A");
1037 fHistTriggerPattern->GetXaxis()->SetBinLabel(5,"v0C");
1038 fHistTriggerPattern->GetXaxis()->SetBinLabel(6,"FO & v0C");
1039 fHistTriggerPattern->GetXaxis()->SetBinLabel(7,"v0A & v0C");
1040 fHistTriggerPattern->GetXaxis()->SetBinLabel(8,"FO & v0A & v0C");
1041
1042
1043 n = 1;
a2ce3799 1044 for (Int_t i=0; i < fCollTrigClasses.GetEntries(); i++)
1045 {
7c55ebd9 1046
a2ce3799 1047 fHistBunchCrossing->GetYaxis()->SetBinLabel(n, ((TObjString*) fCollTrigClasses.At(i))->String());
1048 n++;
1049 }
1050 for (Int_t i=0; i < fBGTrigClasses.GetEntries(); i++)
1051 {
7c55ebd9 1052
a2ce3799 1053 fHistBunchCrossing->GetYaxis()->SetBinLabel(n, ((TObjString*) fBGTrigClasses.At(i))->String());
1054 n++;
1055 }
85c71ba7 1056
1057
1058
a2ce3799 1059 }
1060
1061 Int_t count = fCollTrigClasses.GetEntries() + fBGTrigClasses.GetEntries();
296dd262 1062 for (Int_t i=0; i<count; i++)
61899827 1063 {
7c55ebd9 1064
a2ce3799 1065 AliTriggerAnalysis* triggerAnalysis = static_cast<AliTriggerAnalysis*> (fTriggerAnalysis.At(i));
1066
296dd262 1067 switch (runNumber)
1068 {
a2ce3799 1069 case 104315:
296dd262 1070 case 104316:
1071 case 104320:
a2ce3799 1072 case 104321:
296dd262 1073 case 104439:
1074 triggerAnalysis->SetV0TimeOffset(7.5);
1075 break;
a2ce3799 1076 default:
1077 triggerAnalysis->SetV0TimeOffset(0);
296dd262 1078 }
f4ca8f20 1079 }
1080
758941d4 1081 fCurrentRun = runNumber;
1082
29e8486e 1083 TH1::AddDirectory(oldStatus);
1084
7c55ebd9 1085
61899827 1086 return kTRUE;
1087}
1088
85c71ba7 1089TH2F * AliPhysicsSelection::BookHistStatistics(const char * tag) {
bc18a83e 1090 // add 6 rows to count for the estimate of good, accidentals and
1091 // BG and the ratio of BG and accidentals to total +ratio goot to
1092 // first col + 2 for error on good.
1093 // TODO: Remember the the indexes of rows for the BG selection. Add new member fBGRows[] and use kStat as indexes
85c71ba7 1094
1095 Int_t count = fCollTrigClasses.GetEntries() + fBGTrigClasses.GetEntries();
1096#ifdef VERBOSE_STAT
8dec6e35 1097 Int_t extrarows = fComputeBG != 0 ? 11 : 0;
85c71ba7 1098#else
8dec6e35 1099 Int_t extrarows = fComputeBG != 0 ? 6 : 0;
85c71ba7 1100#endif
559b5ed7 1101 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);
85c71ba7 1102
1103 h->GetXaxis()->SetBinLabel(kStatTriggerClass, "Trigger class");
1104 h->GetXaxis()->SetBinLabel(kStatHWTrig, "Hardware trigger");
1105 h->GetXaxis()->SetBinLabel(kStatFO1, "FO >= 1");
1106 h->GetXaxis()->SetBinLabel(kStatFO2, "FO >= 2");
c2ba5a61 1107 h->GetXaxis()->SetBinLabel(kStatFO2L1, "FO (L1) >= 2");
85c71ba7 1108 h->GetXaxis()->SetBinLabel(kStatV0A, "V0A");
1109 h->GetXaxis()->SetBinLabel(kStatV0C, "V0C");
559b5ed7 1110 h->GetXaxis()->SetBinLabel(kStatT0BB, "T0");
1111 h->GetXaxis()->SetBinLabel(kStatT0BG, "T0BG");
1112 h->GetXaxis()->SetBinLabel(kStatT0PileUp, "T0 PileUp");
396981c2 1113 h->GetXaxis()->SetBinLabel(kStatLaserCut, "TPC Laser Wup Cut");
85c71ba7 1114 h->GetXaxis()->SetBinLabel(kStatV0ABG, "V0A BG");
1115 h->GetXaxis()->SetBinLabel(kStatV0CBG, "V0C BG");
c2ba5a61 1116 h->GetXaxis()->SetBinLabel(kStatZDCA, "ZDCA");
1117 h->GetXaxis()->SetBinLabel(kStatZDCC, "ZDCC");
1118 h->GetXaxis()->SetBinLabel(kStatZDCAC, "ZDCA & ZDCC");
869f9767 1119 h->GetXaxis()->SetBinLabel(kStatZDCTime, "ZDC Time Cut");
85c71ba7 1120 h->GetXaxis()->SetBinLabel(kStatMB1, "(FO >= 1 | V0A | V0C) & !V0 BG");
1121 h->GetXaxis()->SetBinLabel(kStatMB1Prime, "(FO >= 2 | (FO >= 1 & (V0A | V0C)) | (V0A &v0C) ) & !V0 BG");
c2ba5a61 1122 //h->GetXaxis()->SetBinLabel(kStatFO1AndV0, "FO >= 1 & (V0A | V0C) & !V0 BG");
85c71ba7 1123 h->GetXaxis()->SetBinLabel(kStatV0, "V0A & V0C & !V0 BG & !BG ID");
1124 h->GetXaxis()->SetBinLabel(kStatOffline, "Offline Trigger");
c2ba5a61 1125 //h->GetXaxis()->SetBinLabel(kStatAny2Hits, "2 Hits & !V0 BG");
85c71ba7 1126 h->GetXaxis()->SetBinLabel(kStatBG, "Background identification");
e219c292 1127 h->GetXaxis()->SetBinLabel(kStatAcceptedPileUp, "Pile up (in accepted)");
559b5ed7 1128 h->GetXaxis()->SetBinLabel(kStatAccepted, "Accepted");
e219c292 1129
85c71ba7 1130
1131 Int_t n = 1;
1132 for (Int_t i=0; i < fCollTrigClasses.GetEntries(); i++)
1133 {
1134 h->GetYaxis()->SetBinLabel(n, ((TObjString*) fCollTrigClasses.At(i))->String());
1135 n++;
1136 }
1137 for (Int_t i=0; i < fBGTrigClasses.GetEntries(); i++)
1138 {
1139 h->GetYaxis()->SetBinLabel(n, ((TObjString*) fBGTrigClasses.At(i))->String());
1140 n++;
1141 }
1142
1143 if(fComputeBG) {
141265a2 1144 fBGStatOffset = n;
8dec6e35 1145 h->GetYaxis()->SetBinLabel(n++, "All B");
1146 h->GetYaxis()->SetBinLabel(n++, "All A+C");
1147 h->GetYaxis()->SetBinLabel(n++, "All E");
141265a2 1148 h->GetYaxis()->SetBinLabel(n++, Form("BG (A+C) (Mask [0x%x])", fComputeBG));
85c71ba7 1149 h->GetYaxis()->SetBinLabel(n++, "ACC");
1150#ifdef VERBOSE_STAT
1151 h->GetYaxis()->SetBinLabel(n++, "BG (A+C) % (rel. to CINT1B)");
1152 h->GetYaxis()->SetBinLabel(n++, "ACC % (rel. to CINT1B)");
1153 h->GetYaxis()->SetBinLabel(n++, "ERR GOOD %");
1154 h->GetYaxis()->SetBinLabel(n++, "GOOD % (rel. to 1st col)");
1155 h->GetYaxis()->SetBinLabel(n++, "ERR GOOD");
1156#endif
1157 h->GetYaxis()->SetBinLabel(n++, "GOOD");
1158 }
1159
1160 return h;
1161}
1162
7c55ebd9 1163void AliPhysicsSelection::Print(const Option_t *option) const
61899827 1164{
1165 // print the configuration
e9247450 1166 TString msg;
a2ce3799 1167 Printf("Configuration initialized for run %d (MC: %d):", fCurrentRun, fMC);
e9247450 1168 msg += Form("Configuration initialized for run %d (MC: %d):\n", fCurrentRun, fMC);
61899827 1169
296dd262 1170 Printf("Collision trigger classes:");
1171 for (Int_t i=0; i < fCollTrigClasses.GetEntries(); i++)
1172 Printf("%s", ((TObjString*) fCollTrigClasses.At(i))->String().Data());
61899827 1173
296dd262 1174 Printf("Background trigger classes:");
1175 for (Int_t i=0; i < fBGTrigClasses.GetEntries(); i++)
1176 Printf("%s", ((TObjString*) fBGTrigClasses.At(i))->String().Data());
1177
1178 AliTriggerAnalysis* triggerAnalysis = dynamic_cast<AliTriggerAnalysis*> (fTriggerAnalysis.At(0));
61899827 1179
296dd262 1180 if (triggerAnalysis)
1181 {
1182 if (triggerAnalysis->GetV0TimeOffset() > 0)
1183 Printf("V0 time offset active: %.2f ns", triggerAnalysis->GetV0TimeOffset());
61899827 1184
296dd262 1185 Printf("\nTotal available events:");
528640ed 1186
296dd262 1187 triggerAnalysis->PrintTriggerClasses();
7e7fadb8 1188 // Check if all triggers with counts are known to the physics selection. If not, print a WARNING (only for MC)
1189 if(!fMC) {
1190 TMap * triggers = triggerAnalysis->GetTriggerClasses();
1191 TIterator* iter = triggers->MakeIterator();
1192 TObjString* obj = 0;
1193 static TString alreadyFoundTriggers;
1194 while ((obj = dynamic_cast<TObjString*> (iter->Next())))
1195 {
1196 TString strTrigger = obj->GetString();
1197 TParameter<Long64_t>* param = static_cast<TParameter<Long64_t>*> (triggers->GetValue(obj));
1198 Long_t counts = (Long_t)param->GetVal();
1199 TObjArray* tokens = obj->String().Tokenize(" ");
1200 for (Int_t i=0; i<tokens->GetEntries(); i++)
1201 {
1202 TString singleTrigStr = ((TObjString*) tokens->At(i))->String();
1203 singleTrigStr.Strip(TString::kBoth, ' ' );
1204 const char * singleTrig = singleTrigStr.Data();
1205 // Printf("%s", singleTrig);
1206 TString singleTrigStrFull;
1207 Bool_t found = kFALSE;
1208 Int_t nCollTriggers = fCollTrigClasses.GetEntries();
1209 for(Int_t iCollTriggers = 0; iCollTriggers < nCollTriggers; iCollTriggers++){
1210 singleTrigStrFull = ((TObjString*)fCollTrigClasses.At(iCollTriggers))->String();
1211 if(singleTrigStrFull.Contains(singleTrigStr)) {
1212 found = kTRUE;
1213 break;
1214 }
1215 singleTrigStrFull = singleTrigStr;
b885484d 1216 }
7e7fadb8 1217 Int_t nBGTriggers = fBGTrigClasses.GetEntries();
1218 for(Int_t iBGTriggers = 0; iBGTriggers < nBGTriggers; iBGTriggers++){
1219 singleTrigStrFull = ((TObjString*)fBGTrigClasses.At(iBGTriggers))->String();
1220 if(singleTrigStrFull.Contains(singleTrigStr)) {
1221 found = kTRUE;
1222 break;
1223 }
1224 singleTrigStrFull = singleTrigStr;
b885484d 1225 }
7e7fadb8 1226
6aca0ab9 1227 TString blacklist = "CEMC7WU-B-NOPF-ALL, CEMC7WU-AC-NOPF-ALL CEMC7WU-E-NOPF-ALL C0LSR-ABCE-NOPF-TPC CBEAMB-B-NOPF-ALLNOTRD"; // We know we dont support those, so we print no warning
7e7fadb8 1228 if(counts>0 && !found && !blacklist.Contains(singleTrig) && !singleTrigStr.Contains("WU") && !alreadyFoundTriggers.Contains(singleTrig)) {
1229 Printf("WARNING: Found unknown trigger [%s] with %ld counts in the ESD!", singleTrig, counts);
1230 alreadyFoundTriggers += singleTrig; // Avoid printing warning twice for the same trigger
1231 }
1232 }
1233 delete tokens;
1234 }
1235 delete iter;
1236 }
296dd262 1237 }
528640ed 1238
0c6c629b 1239 if (fHistStatistics[kStatIdxAll])
b43e01ed 1240 {
7e7fadb8 1241 static TString alreadyFoundTriggers; // avoids printing twice the same warning
1242
0c6c629b 1243 for (Int_t i=0; i<fCollTrigClasses.GetEntries(); i++)
1244 {
1245 Printf("\nSelection statistics for collision trigger %s:", ((TObjString*) fCollTrigClasses.At(i))->String().Data());
e9247450 1246 msg += Form("\nSelection statistics for collision trigger %s:\n", ((TObjString*) fCollTrigClasses.At(i))->String().Data());
0c6c629b 1247
b885484d 1248 Float_t allEvents = fHistStatistics[kStatIdxAll]->GetBinContent(1, i+1);
1249 Float_t triggeredEvents = fHistStatistics[kStatIdxAll]->GetBinContent(fHistStatistics[kStatIdxAll]->GetXaxis()->FindBin("Accepted"), i+1);
1250
0c6c629b 1251 Printf("Total events with correct trigger class: %d", (Int_t) fHistStatistics[kStatIdxAll]->GetBinContent(1, i+1));
e9247450 1252 msg += Form("Total events with correct trigger class: %d\n", (Int_t) fHistStatistics[kStatIdxAll]->GetBinContent(1, i+1));
0c6c629b 1253 Printf("Selected collision candidates: %d", (Int_t) fHistStatistics[kStatIdxAll]->GetBinContent(fHistStatistics[kStatIdxAll]->GetXaxis()->FindBin("Accepted"), i+1));
e9247450 1254 msg += Form("Selected collision candidates: %d\n", (Int_t) fHistStatistics[kStatIdxAll]->GetBinContent(fHistStatistics[kStatIdxAll]->GetXaxis()->FindBin("Accepted"), i+1));
b885484d 1255
1256 // If the fraction of accepted events is too low, print a warning.
1257 Float_t eff = allEvents > 0 ? triggeredEvents/allEvents : 0;
7e7fadb8 1258 if(allEvents > 0 && (eff < 0.5) && // FIXME: make threshold programmable in OADB
1259 !alreadyFoundTriggers.Contains(((TObjString*) fCollTrigClasses.At(i))->String().Data())) {
b885484d 1260 Printf("WARNING: Trigger class %s has a very low efficiency (%d/%d=%.2f)",((TObjString*) fCollTrigClasses.At(i))->String().Data(), (Int_t) triggeredEvents, (Int_t) allEvents, eff);
7e7fadb8 1261 alreadyFoundTriggers += ((TObjString*) fCollTrigClasses.At(i))->String().Data();
e219c292 1262 Printf("%s", alreadyFoundTriggers.Data());
b885484d 1263 }
1264
0c6c629b 1265 }
17ba346c 1266 }
1267
1268 if (fHistBunchCrossing)
1269 {
1270 Printf("\nBunch crossing statistics:");
e9247450 1271 msg += "\nBunch crossing statistics:\n";
17ba346c 1272
1273 for (Int_t i=1; i<=fHistBunchCrossing->GetNbinsY(); i++)
1274 {
1275 TString str;
8dec6e35 1276 str.Form("Trigger %s has events in the bunch crossings: ", fHistBunchCrossing->GetYaxis()->GetBinLabel(i));
17ba346c 1277
1278 for (Int_t j=1; j<=fHistBunchCrossing->GetNbinsX(); j++)
1279 if (fHistBunchCrossing->GetBinContent(j, i) > 0)
1280 str += Form("%d, ", (Int_t) fHistBunchCrossing->GetXaxis()->GetBinCenter(j));
e9247450 1281
17ba346c 1282 Printf("%s", str.Data());
e9247450 1283 msg += str;
1284 msg += "\n";
17ba346c 1285 }
1286
1287 for (Int_t j=1; j<=fHistBunchCrossing->GetNbinsX(); j++)
1288 {
0c6c629b 1289 Int_t countColl = 0;
1290 Int_t countBG = 0;
17ba346c 1291 for (Int_t i=1; i<=fHistBunchCrossing->GetNbinsY(); i++)
1292 {
1293 if (fHistBunchCrossing->GetBinContent(j, i) > 0)
0c6c629b 1294 {
1295 if (fCollTrigClasses.FindObject(fHistBunchCrossing->GetYaxis()->GetBinLabel(i)))
1296 countColl++;
1297 if (fBGTrigClasses.FindObject(fHistBunchCrossing->GetYaxis()->GetBinLabel(i)))
1298 countBG++;
1299 }
17ba346c 1300 }
0c6c629b 1301 if (countColl > 0 && countBG > 0)
1302 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 1303 }
b43e01ed 1304 }
91bea6e7 1305
1306 if (fUsingCustomClasses)
1307 Printf("WARNING: Using custom trigger classes!");
1308 if (fSkipTriggerClassSelection)
1309 Printf("WARNING: Skipping trigger class selection!");
85c71ba7 1310 if (fSkipV0)
1311 Printf("WARNING: Ignoring V0 information in selection");
1312 if(!fBin0CallBack)
1313 Printf("WARNING: Callback not set: will not fill the statistics for the bin 0");
e9247450 1314 TString opt(option);
1315 opt.ToUpper();
1316 if (opt == "STAT") {
1317 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1318 if (mgr) mgr->AddStatisticsMsg(msg);
1319 }
61899827 1320}
1321
1322Long64_t AliPhysicsSelection::Merge(TCollection* list)
1323{
1324 // Merge a list of AliMultiplicityCorrection objects with this (needed for
1325 // PROOF).
1326 // Returns the number of merged objects (including this).
1327
1328 if (!list)
1329 return 0;
1330
1331 if (list->IsEmpty())
1332 return 1;
1333
1334 TIterator* iter = list->MakeIterator();
1335 TObject* obj;
17ba346c 1336
61899827 1337 // collections of all histograms
1ea7a921 1338 const Int_t nHists = 8;
61899827 1339 TList collections[nHists];
1340
1341 Int_t count = 0;
1342 while ((obj = iter->Next())) {
1343
1344 AliPhysicsSelection* entry = dynamic_cast<AliPhysicsSelection*> (obj);
1345 if (entry == 0)
1346 continue;
518b6d59 1347 // Update run number. If this one is not initialized (-1) take the one from
1348 // the next physics selection to be merged with. In case of 2 different run
1349 // numbers issue a warning (should physics selections from different runs be
1350 // merged together) A.G.
1351 Int_t currentRun = entry->GetCurrentRun();
1352 // Nothing to merge with since run number was not initialized.
1353 if (currentRun < 0) continue;
c2ba5a61 1354 if (fCurrentRun < 0)
1355 {
1356 fCurrentRun = currentRun;
1357 fMC = entry->fMC;
1358 for (Int_t i=0; i<entry->fCollTrigClasses.GetEntries(); i++)
1359 fCollTrigClasses.Add(entry->fCollTrigClasses.At(i)->Clone());
1360 for (Int_t i=0; i<entry->fBGTrigClasses.GetEntries(); i++)
1361 fBGTrigClasses.Add(entry->fBGTrigClasses.At(i)->Clone());
1362 }
518b6d59 1363 if (fCurrentRun != currentRun)
1364 AliWarning(Form("Current run %d not matching the one to be merged with %d", fCurrentRun, currentRun));
7c55ebd9 1365
1366 // With the same strategy update fBGStatOffset
1367 Int_t bgstatoffset = entry->GetBGStatOffset();
1368
504e41a3 1369 // Nothing to merge with since BG was not initialized.
1370 if (!(bgstatoffset < 0)){
1371 if (fBGStatOffset < 0)
1372 {
1373 fBGStatOffset = bgstatoffset;
1374 }
7c55ebd9 1375 }
1376 if (fBGStatOffset != bgstatoffset)
504e41a3 1377 AliWarning(Form("Current run %d not matching the one to be merged with %d", fBGStatOffset, bgstatoffset));
518b6d59 1378
7c55ebd9 1379
1380
1381 // Merge the OADBs (Take just the first instance you find
28cbc692 1382 if (!fPSOADB && entry->GetOADBPhysicsSelection()) {
7c55ebd9 1383 fPSOADB = (AliOADBPhysicsSelection*) entry->GetOADBPhysicsSelection()->Clone();
1384 }
28cbc692 1385 if (!fFillOADB && entry->GetOADBFillingScheme()){
7c55ebd9 1386 fFillOADB = (AliOADBFillingScheme*) entry->GetOADBFillingScheme()->Clone();
1387 }
1388
c2ba5a61 1389 if (entry->fTriggerAnalysis.GetEntries() > 0)
1390 collections[0].Add(&(entry->fTriggerAnalysis));
85c71ba7 1391 if (entry->fHistStatistics[0])
1392 collections[1].Add(entry->fHistStatistics[0]);
1393 if (entry->fHistStatistics[1])
1394 collections[2].Add(entry->fHistStatistics[1]);
7c55ebd9 1395 // if (entry->fHistStatisticsTokens)
1396 // collections[3].Add(entry->fHistStatisticsTokens);
17ba346c 1397 if (entry->fHistBunchCrossing)
85c71ba7 1398 collections[3].Add(entry->fHistBunchCrossing);
73cc8654 1399 if (entry->fHistTriggerPattern)
1400 collections[4].Add(entry->fHistTriggerPattern);
61899827 1401
1402 count++;
1403 }
1404
c2ba5a61 1405 if (fTriggerAnalysis.GetEntries() == 0 && collections[0].GetEntries() > 0)
1406 {
1407 TList* firstList = (TList*) collections[0].First();
1408 for (Int_t i=0; i<firstList->GetEntries(); i++)
1409 fTriggerAnalysis.Add(firstList->At(i)->Clone());
1410
1411 collections[0].RemoveAt(0);
1412 }
17ba346c 1413 fTriggerAnalysis.Merge(&collections[0]);
c2ba5a61 1414
1415 // if this instance is empty (not initialized) nothing would be merged here --> copy first entry
1416 if (!fHistStatistics[0] && collections[1].GetEntries() > 0)
1417 {
1418 fHistStatistics[0] = (TH2F*) collections[1].First()->Clone();
1419 collections[1].RemoveAt(0);
1420 }
85c71ba7 1421 if (fHistStatistics[0])
1422 fHistStatistics[0]->Merge(&collections[1]);
c2ba5a61 1423
1424 if (!fHistStatistics[1] && collections[2].GetEntries() > 0)
1425 {
1426 fHistStatistics[1] = (TH2F*) collections[2].First()->Clone();
1427 collections[2].RemoveAt(0);
1428 }
85c71ba7 1429 if (fHistStatistics[1])
1430 fHistStatistics[1]->Merge(&collections[2]);
c2ba5a61 1431
1432 if (!fHistBunchCrossing && collections[3].GetEntries() > 0)
1433 {
1434 fHistBunchCrossing = (TH2F*) collections[3].First()->Clone();
1435 collections[3].RemoveAt(0);
1436 }
17ba346c 1437 if (fHistBunchCrossing)
85c71ba7 1438 fHistBunchCrossing->Merge(&collections[3]);
c2ba5a61 1439
1440 if (!fHistTriggerPattern && collections[4].GetEntries() > 0)
1441 {
1442 fHistTriggerPattern = (TH1F*) collections[4].First()->Clone();
1443 collections[4].RemoveAt(0);
1444 }
73cc8654 1445 if (fHistTriggerPattern)
1446 fHistTriggerPattern->Merge(&collections[4]);
1ea7a921 1447
61899827 1448 delete iter;
1449
1450 return count+1;
1451}
1452
8dec6e35 1453void AliPhysicsSelection::SaveHistograms(const char* folder)
61899827 1454{
1455 // write histograms to current directory
1456
85c71ba7 1457 if (!fHistStatistics[0] || !fHistStatistics[1])
61899827 1458 return;
1459
1460 if (folder)
1461 {
1462 gDirectory->mkdir(folder);
1463 gDirectory->cd(folder);
1464 }
1465
85c71ba7 1466
1467 // Fill the last rows of fHistStatistics before saving
8dec6e35 1468 if (fComputeBG) {
1469 AliInfo("BG estimate assumes that for a given run you only have A and C triggers separately or"
1470 " toghether as a AC class! Make sure this assumption holds in your case");
1471
1472 // use an anum for the different trigger classes, to make loops easier to read
1473 enum {kClassB =0 , kClassA, kClassC, kClassAC, kClassE, kNClasses};
1474 const char * classFlags[] = {"B", "A", "C", "AC", "E"}; // labels
1475
1476 UInt_t * rows[kNClasses] = {0}; // Array of matching rows
1477 Int_t nrows[kNClasses] = {0};
1478 // Get rows matching the requested trigger bits for all trigger classes
1479 for(Int_t iTrigClass = 0; iTrigClass < kNClasses; iTrigClass++){
1480 nrows[iTrigClass] = GetStatRow(classFlags[iTrigClass],fComputeBG,&rows[iTrigClass]);
1481 }
1482
1483 // 0. Determine the ratios of triggers E/B, A/B, C/B from the stat histogram
1484 // Those are used to rescale the different classes to the same number of bx ids
1485 // 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?
1486 Int_t nBXIds[kNClasses] = {0};
1487 // cout <<"Computing BG:" << endl;
1488
1489 for(Int_t iTrigClass = 0; iTrigClass < kNClasses; iTrigClass++){
1490 for(Int_t irow = 0; irow < nrows[iTrigClass]; irow++) {
1491 if(irow==0) cout << "- Class " << classFlags[iTrigClass] << endl;
1492 for (Int_t j=1; j<=fHistBunchCrossing->GetNbinsX(); j++) {
1493 if (fHistBunchCrossing->GetBinContent(j, rows[iTrigClass][irow]) > 0) {
1494 nBXIds[iTrigClass]++;
141265a2 1495 }
141265a2 1496 }
8dec6e35 1497 if(nBXIds[iTrigClass]>0) cout << " Using row " << rows[iTrigClass][irow] << ": "
1498 << fHistBunchCrossing->GetYaxis()->GetBinLabel(rows[iTrigClass][irow])
1499 << " (nBXID "<< nBXIds[iTrigClass] << ")"<< endl;
141265a2 1500
5f337f3d 1501 }
141265a2 1502
8dec6e35 1503 }
1504
1505 Float_t ratioToB[kNClasses];
1506 ratioToB[kClassE] = nBXIds[kClassE] >0 ? Float_t(nBXIds[kClassB])/nBXIds[kClassE] : 0;
1507 ratioToB[kClassA] = nBXIds[kClassA] >0 ? Float_t(nBXIds[kClassB])/nBXIds[kClassA] : 0;
1508 ratioToB[kClassC] = nBXIds[kClassC] >0 ? Float_t(nBXIds[kClassB])/nBXIds[kClassC] : 0;
1509 ratioToB[kClassAC] = nBXIds[kClassAC] >0 ? Float_t(nBXIds[kClassB])/nBXIds[kClassAC] : 0;
1510 Printf("Ratio between the BX ids in the different trigger classes:");
1511 Printf(" B/E = %d/%d = %f", nBXIds[kClassB],nBXIds[kClassE], ratioToB[kClassE] );
1512 Printf(" B/A = %d/%d = %f", nBXIds[kClassB],nBXIds[kClassA], ratioToB[kClassA] );
1513 Printf(" B/C = %d/%d = %f", nBXIds[kClassB],nBXIds[kClassC], ratioToB[kClassC] );
1514 Printf(" B/AC = %d/%d = %f", nBXIds[kClassB],nBXIds[kClassAC],ratioToB[kClassAC]);
1515 Int_t nHistStat = 2;
1516
1517 // 1. loop over all cols
1518 for(Int_t iHistStat = 0; iHistStat < nHistStat; iHistStat++){
1519 Int_t ncol = fHistStatistics[iHistStat]->GetNbinsX();
1520 Float_t good1 = 0;
1521 for(Int_t icol = 1; icol <= ncol; icol++) {
1522 Int_t nEvents[kNClasses] = {0}; // number of events should be reset at every column
1523 // For all trigger classes, add up over row matching trigger mask (as selected before)
1524 for(Int_t iTrigClass = 0; iTrigClass < kNClasses; iTrigClass++){
1525 for(Int_t irow = 0; irow < nrows[iTrigClass]; irow++) {
1526 nEvents[iTrigClass] += (Int_t) fHistStatistics[iHistStat]->GetBinContent(icol,rows[iTrigClass][irow]);
141265a2 1527 }
8dec6e35 1528 // cout << "Events " << classFlags[iTrigClass] << " ("<<icol<<") " << nEvents[iTrigClass] << endl;
1529 }
1530 if (nEvents[kClassB]>0) {
1531 Float_t acc = ratioToB[kClassE]*nEvents[kClassE];
7c55ebd9 1532 Double_t accErr = TMath::Sqrt(ratioToB[kClassE]*ratioToB[kClassE]*nEvents[kClassE]);
8dec6e35 1533 // Int_t bg = cint1A + cint1C - 2*acc;
141265a2 1534
8dec6e35 1535 // If intensity measurements are available, they already
1536 // contain the scaling for BX ratios, so we reset the
1537 // ratioToB entries
1779d797 1538 if(icol == 1) {
1539 if(fBIFactorAC > 0 || fBIFactorA > 0 || fBIFactorC > 0) {
7c55ebd9 1540 if (fBIFactorAC <= 0 && (fBIFactorA <= 0 || fBIFactorC <= 0)) {
1779d797 1541 AliError("Not all intensities set!, assuming equal intensities");
1542 fBIFactorA = 1;
1543 fBIFactorC = 1;
1544 fBIFactorAC = 1;
1545 } else {
1546 AliInfo("Using ratio of number of bunch crossing embedded in the intensity measurements");
1547 ratioToB[kClassA] = ratioToB[kClassA] >0 ? 1 : 0;
1548 ratioToB[kClassC] = ratioToB[kClassC] >0 ? 1 : 0;
1549 ratioToB[kClassAC] = ratioToB[kClassAC] >0 ? 1 : 0;
1550 AliInfo(Form(" - BI Factor A: %f", fBIFactorA ));
1551 AliInfo(Form(" - BI Factor C: %f", fBIFactorC ));
1552 AliInfo(Form(" - BI Factor AC: %f", fBIFactorAC ));
1553
1554 }
1555 } else {
1556 AliWarning("Intensities not set!, assuming equal intensities");
8dec6e35 1557 fBIFactorA = 1;
1558 fBIFactorC = 1;
1559 fBIFactorAC = 1;
8dec6e35 1560 }
8dec6e35 1561 }
8dec6e35 1562 // Assuming that for a given class the triggers are either recorded as A+C or AC
1563 Float_t bg = nEvents[kClassAC] > 0 ?
1564 fBIFactorAC*(ratioToB[kClassAC]*nEvents[kClassAC] - 2*acc):
1565 fBIFactorA* (ratioToB[kClassA]*nEvents[kClassA]-acc) +
1566 fBIFactorC* (ratioToB[kClassC]*nEvents[kClassC]-acc) ;
1567
1568 // cout << "-----------------------" << endl;
1569 // cout << "Factors: " << fBIFactorA << " " << fBIFactorC << " " << fBIFactorAC << endl;
1570 // cout << "Ratios: " << ratioToB[kClassA] << " " << ratioToB[kClassC] << " " << ratioToB[kClassAC] << endl;
1571 // cout << "Evts: " << nEvents[kClassA] << " " << nEvents[kClassC] << " " << nEvents[kClassAC] << " " << nEvents[kClassB] << endl;
1572 // cout << "Acc: " << acc << endl;
1573 // cout << "BG: " << bg << endl;
1574 // cout << " " << fBIFactorA* (ratioToB[kClassA]*nEvents[kClassA]-acc) <<endl;
1575 // cout << " " << fBIFactorC* (ratioToB[kClassC]*nEvents[kClassC]-acc) <<endl;
1576 // cout << " " << fBIFactorAC*(ratioToB[kClassAC]*nEvents[kClassAC] - 2*acc) << endl;
1577 // cout << "-----------------------" << endl;
1578
1579 Float_t good = Float_t(nEvents[kClassB]) - bg - acc;
1580 if (icol ==1) good1 = good;
1581 // Float_t errGood = TMath::Sqrt(2*(nEvents[kClassA]+nEvents[kClassC]+nEvents[kClassE]));// Error on the number of goods assuming only bg fluctuates
1582 // DeltaG^2 = B + FA^2 A + FC^2 C + Ratio^2 (FA+FC-1)^2 E.
1583 Float_t errGood = nEvents[kClassAC] > 0 ?
1584 TMath::Sqrt( nEvents[kClassB] +
1585 fBIFactorAC*fBIFactorAC*ratioToB[kClassAC]*ratioToB[kClassAC]*nEvents[kClassAC] +
1586 ratioToB[kClassE] * ratioToB[kClassE] *
1587 (fBIFactorAC - 1)*(fBIFactorAC - 1)*nEvents[kClassE]) :
1588 TMath::Sqrt( nEvents[kClassB] +
1589 fBIFactorA*fBIFactorA*ratioToB[kClassA]*ratioToB[kClassA]*nEvents[kClassA] +
1590 fBIFactorC*fBIFactorC*ratioToB[kClassC]*ratioToB[kClassC]*nEvents[kClassC] +
1591 ratioToB[kClassE] * ratioToB[kClassE] *
1592 (fBIFactorA + fBIFactorC - 1)*(fBIFactorA + fBIFactorC - 1)*nEvents[kClassE]);
1593
1594 Float_t errBG = nEvents[kClassAC] > 0 ?
1595 TMath::Sqrt(fBIFactorAC*fBIFactorAC*ratioToB[kClassAC]*ratioToB[kClassAC]*nEvents[kClassAC]+
1596 4*ratioToB[kClassE]*ratioToB[kClassE]*(fBIFactorAC*fBIFactorAC)*nEvents[kClassE]) :
1597 TMath::Sqrt(fBIFactorA*fBIFactorA*ratioToB[kClassA]*ratioToB[kClassA]*nEvents[kClassA]+
1598 fBIFactorC*fBIFactorC*ratioToB[kClassC]*ratioToB[kClassC]*nEvents[kClassC]+
1599 ratioToB[kClassE]*ratioToB[kClassE]*(fBIFactorA+fBIFactorC)*(fBIFactorA+fBIFactorC)*nEvents[kClassE]);
85c71ba7 1600
1601
8dec6e35 1602 fHistStatistics[iHistStat]->SetBinContent(icol,fBGStatOffset+kStatRowAllB, nEvents[kClassB]);
1603 fHistStatistics[iHistStat]->SetBinContent(icol,fBGStatOffset+kStatRowAllAC,nEvents[kClassA]+nEvents[kClassC]+nEvents[kClassAC]);
1604 fHistStatistics[iHistStat]->SetBinContent(icol,fBGStatOffset+kStatRowAllE, nEvents[kClassE]);
1605
1606 fHistStatistics[iHistStat]->SetBinContent(icol,fBGStatOffset+kStatRowBG,bg);
1607 fHistStatistics[iHistStat]->SetBinError (icol,fBGStatOffset+kStatRowBG,errBG);
1608 fHistStatistics[iHistStat]->SetBinContent(icol,fBGStatOffset+kStatRowAcc,acc);
7c55ebd9 1609 fHistStatistics[iHistStat]->SetBinError (icol,fBGStatOffset+kStatRowAcc,accErr);
8dec6e35 1610 fHistStatistics[iHistStat]->SetBinContent(icol,fBGStatOffset+kStatRowGood,good);
1611 fHistStatistics[iHistStat]->SetBinError (icol,fBGStatOffset+kStatRowGood,errGood);
85c71ba7 1612
1613#ifdef VERBOSE_STAT
8dec6e35 1614 //kStatRowBG=0,kStatRowAcc,kStatRowBGFrac,kStatRowAccFrac,kStatRowErrGoodFrac,kStatRowGoodFrac,kStatRowGood,kStatRowErrGood
1615 Float_t accFrac = Float_t(acc) / nEvents[kClassB] *100;
7c55ebd9 1616 Float_t errAccFrac= Float_t(accErr) / nEvents[kClassB] *100;
8dec6e35 1617 Float_t bgFrac = Float_t(bg) / nEvents[kClassB] *100;
1618 Float_t goodFrac = Float_t(good) / good1 *100;
1619 Float_t errGoodFrac = errGood/good1 * 100;
1620 Float_t errFracBG = bg > 0 ? TMath::Sqrt((errBG/bg)*(errBG/bg) + 1/nEvents[kClassB])*bgFrac : 0;
1621 fHistStatistics[iHistStat]->SetBinContent(icol,fBGStatOffset+kStatRowBGFrac,bgFrac);
1622 fHistStatistics[iHistStat]->SetBinError (icol,fBGStatOffset+kStatRowBGFrac,errFracBG);
1623 fHistStatistics[iHistStat]->SetBinContent(icol,fBGStatOffset+kStatRowAccFrac,accFrac);
1624 fHistStatistics[iHistStat]->SetBinError (icol,fBGStatOffset+kStatRowAccFrac,errAccFrac);
1625 fHistStatistics[iHistStat]->SetBinContent(icol,fBGStatOffset+kStatRowGoodFrac,goodFrac);
1626 fHistStatistics[iHistStat]->SetBinContent(icol,fBGStatOffset+kStatRowErrGoodFrac,errGoodFrac);
1627 fHistStatistics[iHistStat]->SetBinContent(icol,fBGStatOffset+kStatRowErrGood,errGood);
85c71ba7 1628#endif
85c71ba7 1629 }
1630 }
8dec6e35 1631 }
1632 for (Int_t iTrigClass = 0; iTrigClass < kNClasses; iTrigClass++){
1633 delete [] rows[iTrigClass];
85c71ba7 1634 }
8dec6e35 1635 }
85c71ba7 1636
1637 fHistStatistics[0]->Write();
1638 fHistStatistics[1]->Write();
8e58a7b9 1639 if(fHistBunchCrossing ) fHistBunchCrossing ->Write();
1640 if(fHistTriggerPattern) fHistTriggerPattern->Write();
61899827 1641
296dd262 1642 Int_t count = fCollTrigClasses.GetEntries() + fBGTrigClasses.GetEntries();
1643 for (Int_t i=0; i < count; i++)
8dec6e35 1644 {
1645 TString triggerClass = "trigger_histograms_";
1646 if (i < fCollTrigClasses.GetEntries())
1647 triggerClass += ((TObjString*) fCollTrigClasses.At(i))->String();
1648 else
1649 triggerClass += ((TObjString*) fBGTrigClasses.At(i - fCollTrigClasses.GetEntries()))->String();
1650
1651 gDirectory->mkdir(triggerClass);
1652 gDirectory->cd(triggerClass);
1653
1654 static_cast<AliTriggerAnalysis*> (fTriggerAnalysis.At(i))->SaveHistograms();
1655
1656 gDirectory->cd("..");
1657 }
1ea7a921 1658
61899827 1659 if (folder)
1660 gDirectory->cd("..");
7c55ebd9 1661
61899827 1662}
85c71ba7 1663
141265a2 1664Int_t AliPhysicsSelection::GetStatRow(const char * triggerBXClass, UInt_t offlineTriggerType, UInt_t ** rowIDs) const {
1665 // Puts inside the array rowIDs the row number for a given offline
1666 // trigger in a given bx class. Returns the total number of lines
1667 // matching the selection
1668 // triggerBXClass can be either "A", "AC", "B" or "E"
1669 // offlineTriggerType is one of the types defined in AliVEvent
1670 // User should delete rowIDs if no longer needed
1671
1672 if(!fHistStatistics[0]) {
1673 AliWarning("Not initialized, returning 0");
1674 return 0;
1675 }
1676 const Int_t nrows = fHistStatistics[0]->GetNbinsY();
1677
1678 // allocate memory for at maximum nrows
1679 Int_t nMatches = 0;
1680 (*rowIDs) = new UInt_t[nrows];
1681
7c55ebd9 1682
1683 // Loop over rows and find matching ones, using the PS OADB
1684 // FIXME: check BG estimates
141265a2 1685 for(Int_t irow = 1; irow <= nrows; irow++){
8dec6e35 1686 TString triggerClassCurrent = fHistStatistics[0]->GetYaxis()->GetBinLabel(irow);
7c55ebd9 1687 TPRegexp trigType (".*\\&(\\d+).*");
1688 TObjArray * arr = trigType.MatchS(triggerClassCurrent.Data());
1689 if(arr->GetEntries() > 1){
1690 UInt_t tType = ((TObjString*)arr->At(1))->GetString().Atoi();
1691
1692 if (tType == offlineTriggerType && fPSOADB->GetBeamSide(triggerClassCurrent.Data()) == triggerBXClass) {
1693 (*rowIDs)[nMatches] = irow;
1694 nMatches++;
141265a2 1695 }
7c55ebd9 1696
141265a2 1697 }
7c55ebd9 1698 delete arr;
1699
85c71ba7 1700 }
141265a2 1701
1702 return nMatches;
1703}
85c71ba7 1704
141265a2 1705void AliPhysicsSelection::SetBIFactors(const AliESDEvent * aESD) {
1706 // Set factors for realtive bunch intesities
1707 if(!aESD) {
1708 AliFatal("ESD not given");
1709 }
1710 Int_t run = aESD->GetRunNumber();
1711 if (run > 105268) {
1712 // intensities stored in the ESDs
1713 const AliESDRun* esdRun = aESD->GetESDRun();
1714 Double_t intAB = esdRun->GetMeanIntensityIntecting(0);
1715 Double_t intCB = esdRun->GetMeanIntensityIntecting(1);
1716 Double_t intAA = esdRun->GetMeanIntensityNonIntecting(0);
1717 Double_t intCC = esdRun->GetMeanIntensityNonIntecting(1);
1718
1719 // cout << "INT " <<intAB <<endl;
1720 // cout << "INT " <<intCB <<endl;
1721 // cout << "INT " <<intAA <<endl;
1722 // cout << "INT " <<intCC <<endl;
1723
d0b66831 1724 if (intAB > 0 && intAA > 0) {
141265a2 1725 fBIFactorA = intAB/intAA;
1726 } else {
8dec6e35 1727 AliWarning("Cannot set fBIFactorA");
141265a2 1728 }
1729
d0b66831 1730 if (intCB > 0 && intCC > 0) {
141265a2 1731 fBIFactorC = intCB/intCC;
1732 } else {
8dec6e35 1733 AliWarning("Cannot set fBIFactorC");
141265a2 1734 }
1735
d0b66831 1736 if (intAB > 0 && intAA > 0 &&
1737 intCB > 0 && intCC > 0) {
141265a2 1738 fBIFactorAC = (intAB+intCB)/(intAA+intCC);
1739 } else {
8dec6e35 1740 AliWarning("Cannot set fBIFactorAC");
141265a2 1741 }
1742
1743 }
1744 else {
1745 // First runs. Intensities hardcoded
1746 switch(run) {
1747 case 104155:
1748 fBIFactorA = 0.961912722908;
1749 fBIFactorC = 1.04992336081;
1750 break;
1751 case 104157:
1752 fBIFactorA = 0.947312854998;
1753 fBIFactorC = 1.01599706417;
1754 break;
1755 case 104159:
1756 fBIFactorA = 0.93659320151;
1757 fBIFactorC = 0.98580804207;
1758 break;
1759 case 104160:
1760 fBIFactorA = 0.929664189926;
1761 fBIFactorC = 0.963467679851;
1762 break;
1763 case 104315:
1764 fBIFactorA = 1.08939104979;
1765 fBIFactorC = 0.931113921925;
1766 break;
1767 case 104316:
1768 fBIFactorA = 1.08351880974;
1769 fBIFactorC = 0.916068345845;
1770 break;
1771 case 104320:
1772 fBIFactorA = 1.07669281245;
1773 fBIFactorC = 0.876818744763;
1774 break;
1775 case 104321:
1776 fBIFactorA = 1.00971079602;
1777 fBIFactorC = 0.773781299076;
1778 break;
1779 case 104792:
1780 fBIFactorA = 0.787215863962;
1781 fBIFactorC = 0.778253173071;
1782 break;
1783 case 104793:
1784 fBIFactorA = 0.692211363661;
1785 fBIFactorC = 0.733152456667;
1786 break;
1787 case 104799:
1788 fBIFactorA = 1.04027825161;
1789 fBIFactorC = 1.00530825942;
1790 break;
1791 case 104800:
1792 fBIFactorA = 1.05309910671;
1793 fBIFactorC = 1.00376801855;
1794 break;
1795 case 104801:
1796 fBIFactorA = 1.0531231922;
1797 fBIFactorC = 0.992439666758;
1798 break;
1799 case 104802:
1800 fBIFactorA = 1.04191478134;
1801 fBIFactorC = 0.979368585208;
1802 break;
1803 case 104803:
1804 fBIFactorA = 1.03121314094;
1805 fBIFactorC = 0.973379962609;
1806 break;
1807 case 104824:
1808 fBIFactorA = 0.969945926722;
1809 fBIFactorC = 0.39549745806;
1810 break;
1811 case 104825:
1812 fBIFactorA = 0.968627213937;
1813 fBIFactorC = 0.310100412205;
1814 break;
1815 case 104841:
1816 fBIFactorA = 0.991601393212;
1817 fBIFactorC = 0.83762204722;
1818 break;
1819 case 104845:
1820 fBIFactorA = 0.98040863886;
1821 fBIFactorC = 0.694824205793;
1822 break;
1823 case 104867:
1824 fBIFactorA = 1.10646173412;
1825 fBIFactorC = 0.841407246916;
1826 break;
1827 case 104876:
1828 fBIFactorA = 1.12063452421;
1829 fBIFactorC = 0.78726542895;
1830 break;
1831 case 104890:
1832 fBIFactorA = 1.02346137453;
1833 fBIFactorC = 1.03355663595;
1834 break;
1835 case 104892:
1836 fBIFactorA = 1.05406025913;
1837 fBIFactorC = 1.00029166135;
1838 break;
1839 case 105143:
1840 fBIFactorA = 0.947343384349;
1841 fBIFactorC = 0.972637444408;
1842 break;
1843 case 105160:
1844 fBIFactorA = 0.908854622177;
1845 fBIFactorC = 0.958851103977;
1846 break;
1847 case 105256:
1848 fBIFactorA = 0.810076150206;
1849 fBIFactorC = 0.884663561883;
1850 break;
1851 case 105257:
1852 fBIFactorA = 0.80974912303;
1853 fBIFactorC = 0.878859123479;
1854 break;
1855 case 105268:
1856 fBIFactorA = 0.809052110679;
1857 fBIFactorC = 0.87233890989;
1858 break;
1859 default:
1860 fBIFactorA = 1;
1861 fBIFactorC = 1;
1862 }
1863 }
85c71ba7 1864
1865}
7c55ebd9 1866
1867const char * AliPhysicsSelection::GetTriggerString(TObjString * obj) {
1868 // Returns a formed objstring
1869 static TString retString;
1870
1871 retString.Form("%s%s",
1872 obj->String().Data(),
1873 fUseBXNumbers ? fFillOADB->GetBXIDs(fPSOADB->GetBeamSide(obj->String().Data())) : ""
1874 );
1875
1876 if (fMC) {
1877 TPRegexp stripClasses("\\+\\S* ");
1878 stripClasses.Substitute(retString,"","g");
1879 stripClasses=TPRegexp("\\-\\S* ");
1880 stripClasses.Substitute(retString,"","g");
1881 }
1882
1883 return retString.Data();
1884}
1885
1886void AliPhysicsSelection::AddCollisionTriggerClass(const char* className){
1887 AliError("This method is deprecated! Will be removed soon! Please use SetCustomOADBObjects() instead!");
1888 if(!fPSOADB) {
1889 fPSOADB = new AliOADBPhysicsSelection("CustomPS");
1890 fPSOADB->SetHardwareTrigger ( 0,"SPDGFO >= 1 || V0A || V0C");
1891 fPSOADB->SetOfflineTrigger ( 0,"(SPDGFO >= 1 || V0A || V0C) && !V0ABG && !V0CBG");
1892 }
1893
1894 // Strip all which is not needed, if BX ids are provided, they are still used here
1895 // offline trigger and logics are appended automagically, so we strip-em out if they are provided
1896 TString classNameStripped = className;
1897 if(classNameStripped.Index("*")>0)
1898 classNameStripped.Remove(classNameStripped.Index("*")); // keep only the class name (no bx, offline trigger...)
1899 if(classNameStripped.Index("&")>0)
1900 classNameStripped.Remove(classNameStripped.Index("&")); // keep only the class name (no bx, offline trigger...)
1901
1902 fPSOADB->AddCollisionTriggerClass ( AliVEvent::kUserDefined,classNameStripped.Data(),"B",0);
1903
1904 fUsingCustomClasses = kTRUE;
1905
1906
1907}
1908
1909void AliPhysicsSelection::AddBGTriggerClass(const char* className){
1910 // Add custom BG trigger class
1911
1912 AliError("This method is deprecated! Will be removed soon! Please use SetCustomOADBObjects() instead!");
1913 if(!fPSOADB) {
1914 fPSOADB = new AliOADBPhysicsSelection("CustomPS");
1915 fPSOADB->SetHardwareTrigger ( 0,"SPDGFO >= 1 || V0A || V0C");
1916 fPSOADB->SetOfflineTrigger ( 0,"(SPDGFO >= 1 || V0A || V0C) && !V0ABG && !V0CBG");
1917 }
1918
1919 // Strip all which is not needed, if BX ids are provided, they are still used here
1920 // offline trigger and logics are appended automagically, so we strip-em out if they are provided
1921 TString classNameStripped = className;
1922 if(classNameStripped.Index("*")>0)
1923 classNameStripped.Remove(classNameStripped.Index("*")); // keep only the class name (no bx, offline trigger...)
1924 if(classNameStripped.Index("&")>0)
1925 classNameStripped.Remove(classNameStripped.Index("&")); // keep only the class name (no bx, offline trigger...)
1926
1927 fPSOADB->AddBGTriggerClass ( AliVEvent::kUserDefined,classNameStripped.Data(),"AC",0);
1928
1929 fUsingCustomClasses = kTRUE;
1930
1931}