]> git.uio.no Git - u/mrichter/AliRoot.git/blame - ANALYSIS/AliPhysicsSelection.cxx
Adding C0SCO-D-NOPF-FAST.
[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"
61899827 115
116ClassImp(AliPhysicsSelection)
117
118AliPhysicsSelection::AliPhysicsSelection() :
296dd262 119 AliAnalysisCuts("AliPhysicsSelection", "AliPhysicsSelection"),
120 fCurrentRun(-1),
a2ce3799 121 fMC(kFALSE),
296dd262 122 fCollTrigClasses(),
123 fBGTrigClasses(),
124 fTriggerAnalysis(),
125 fBackgroundIdentification(0),
91bea6e7 126 fHistBunchCrossing(0),
73cc8654 127 fHistTriggerPattern(0),
91bea6e7 128 fSkipTriggerClassSelection(0),
85c71ba7 129 fUsingCustomClasses(0),
130 fSkipV0(0),
131 fBIFactorA(1),
132 fBIFactorC(1),
85c71ba7 133 fComputeBG(0),
73cc8654 134 fUseBXNumbers(1),
135 fUseMuonTriggers(0),
85c71ba7 136 fFillingScheme(""),
ff097e3f 137 fBin0CallBack(""),
138 fBin0CallBackPointer(0)
61899827 139{
140 // constructor
141
296dd262 142 fCollTrigClasses.SetOwner(1);
143 fBGTrigClasses.SetOwner(1);
144 fTriggerAnalysis.SetOwner(1);
85c71ba7 145 fHistStatistics[0] = 0;
146 fHistStatistics[1] = 0;
296dd262 147
61899827 148 AliLog::SetClassDebugLevel("AliPhysicsSelection", AliLog::kWarning);
149}
150
151AliPhysicsSelection::~AliPhysicsSelection()
152{
153 // destructor
85c71ba7 154
296dd262 155 fCollTrigClasses.Delete();
156 fBGTrigClasses.Delete();
157 fTriggerAnalysis.Delete();
61899827 158
85c71ba7 159 if (fHistStatistics[0])
160 {
161 delete fHistStatistics[0];
162 fHistStatistics[0] = 0;
163 }
164 if (fHistStatistics[1])
61899827 165 {
85c71ba7 166 delete fHistStatistics[1];
167 fHistStatistics[1] = 0;
61899827 168 }
169
170 if (fHistBunchCrossing)
171 {
172 delete fHistBunchCrossing;
173 fHistBunchCrossing = 0;
174 }
73cc8654 175 if (fHistTriggerPattern)
176 {
177 delete fHistTriggerPattern;
178 fHistTriggerPattern = 0;
179 }
85c71ba7 180
61899827 181}
296dd262 182
183Bool_t AliPhysicsSelection::CheckTriggerClass(const AliESDEvent* aEsd, const char* trigger) const
184{
185 // checks if the given trigger class(es) are found for the current event
186 // format of trigger: +TRIGGER1 -TRIGGER2
187 // requires TRIGGER1 and rejects TRIGGER2
188
decf6fd4 189 Bool_t foundBCRequirement = kFALSE;
190 Bool_t foundCorrectBC = kFALSE;
191
296dd262 192 TString str(trigger);
193 TObjArray* tokens = str.Tokenize(" ");
194
195 for (Int_t i=0; i < tokens->GetEntries(); i++)
196 {
197 TString str2(((TObjString*) tokens->At(i))->String());
198
decf6fd4 199 if (str2[0] == '+' || str2[0] == '-')
296dd262 200 {
decf6fd4 201 Bool_t flag = (str2[0] == '+');
202
203 str2.Remove(0, 1);
204
205 if (flag && !aEsd->IsTriggerClassFired(str2))
206 {
207 AliDebug(AliLog::kDebug, Form("Rejecting event because trigger class %s is not present", str2.Data()));
208 delete tokens;
209 return kFALSE;
210 }
211 if (!flag && aEsd->IsTriggerClassFired(str2))
212 {
213 AliDebug(AliLog::kDebug, Form("Rejecting event because trigger class %s is present", str2.Data()));
214 delete tokens;
215 return kFALSE;
216 }
296dd262 217 }
decf6fd4 218 else if (str2[0] == '#')
296dd262 219 {
decf6fd4 220 foundBCRequirement = kTRUE;
221
222 str2.Remove(0, 1);
223
224 Int_t bcNumber = str2.Atoi();
225 AliDebug(AliLog::kDebug, Form("Checking for bunch crossing number %d", bcNumber));
226
227 if (aEsd->GetBunchCrossNumber() == bcNumber)
228 {
229 foundCorrectBC = kTRUE;
230 AliDebug(AliLog::kDebug, Form("Found correct bunch crossing %d", bcNumber));
231 }
296dd262 232 }
decf6fd4 233 else
234 AliFatal(Form("Invalid trigger syntax: %s", trigger));
296dd262 235 }
236
237 delete tokens;
decf6fd4 238
239 if (foundBCRequirement && !foundCorrectBC)
240 return kFALSE;
241
296dd262 242 return kTRUE;
243}
61899827 244
245Bool_t AliPhysicsSelection::IsCollisionCandidate(const AliESDEvent* aEsd)
246{
247 // checks if the given event is a collision candidate
248
95e6f4ec 249 if (fCurrentRun != aEsd->GetRunNumber())
250 if (!Initialize(aEsd->GetRunNumber()))
251 AliFatal(Form("Could not initialize for run %d", aEsd->GetRunNumber()));
252
61899827 253 const AliESDHeader* esdHeader = aEsd->GetHeader();
254 if (!esdHeader)
255 {
256 AliError("ESD Header could not be retrieved");
257 return kFALSE;
258 }
259
a2ce3799 260 // check event type; should be PHYSICS = 7 for data and 0 for MC
261 if (!fMC)
262 {
263 if (esdHeader->GetEventType() != 7)
264 return kFALSE;
265 }
266 else
267 {
268 if (esdHeader->GetEventType() != 0)
269 AliFatal(Form("Invalid event type for MC: %d", esdHeader->GetEventType()));
270 }
758941d4 271
296dd262 272 Bool_t accept = kFALSE;
273
274 Int_t count = fCollTrigClasses.GetEntries() + fBGTrigClasses.GetEntries();
275 for (Int_t i=0; i < count; i++)
61899827 276 {
296dd262 277 const char* triggerClass = 0;
278 if (i < fCollTrigClasses.GetEntries())
279 triggerClass = ((TObjString*) fCollTrigClasses.At(i))->String();
280 else
281 triggerClass = ((TObjString*) fBGTrigClasses.At(i - fCollTrigClasses.GetEntries()))->String();
61899827 282
296dd262 283 AliDebug(AliLog::kDebug, Form("Processing trigger class %s", triggerClass));
61899827 284
296dd262 285 AliTriggerAnalysis* triggerAnalysis = static_cast<AliTriggerAnalysis*> (fTriggerAnalysis.At(i));
61899827 286
296dd262 287 triggerAnalysis->FillTriggerClasses(aEsd);
61899827 288
296dd262 289 if (CheckTriggerClass(aEsd, triggerClass))
290 {
291 triggerAnalysis->FillHistograms(aEsd);
292
85c71ba7 293 Bool_t isBin0 = kFALSE;
294 if (fBin0CallBack != "") {
295 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
296 if (!mgr) {
297 AliError("Cannot get the analysis manager");
298 }
299 else {
300 isBin0 = ((AliAnalysisTaskSE*)mgr->GetTask(fBin0CallBack.Data()))->IsEventInBinZero();
301 }
ff097e3f 302 } else if (fBin0CallBackPointer) {
303 isBin0 = (*fBin0CallBackPointer)(aEsd);
304
85c71ba7 305 }
ff097e3f 306
85c71ba7 307
cc9d9320 308
309 // hardware trigger (should only remove events for MC)
310 // replay CINT1B hardware trigger
311 // TODO this has to depend on the actual hardware trigger (and that depends on the run...)
312 Int_t fastORHW = triggerAnalysis->SPDFiredChips(aEsd, 1); // SPD number of chips from trigger bits (!)
85c71ba7 313 Bool_t v0A = fSkipV0 ? 0 :triggerAnalysis->IsOfflineTriggerFired(aEsd, AliTriggerAnalysis::kV0A);
314 Bool_t v0C = fSkipV0 ? 0 :triggerAnalysis->IsOfflineTriggerFired(aEsd, AliTriggerAnalysis::kV0C);
315 Bool_t v0AHW = fSkipV0 ? 0 :(triggerAnalysis->V0Trigger(aEsd, AliTriggerAnalysis::kASide, kTRUE) == AliTriggerAnalysis::kV0BB);// should replay hw trigger
316 Bool_t v0CHW = fSkipV0 ? 0 :(triggerAnalysis->V0Trigger(aEsd, AliTriggerAnalysis::kCSide, kTRUE) == AliTriggerAnalysis::kV0BB);// should replay hw trigger
cc9d9320 317 // offline trigger
318 Int_t fastOROffline = triggerAnalysis->SPDFiredChips(aEsd, 0); // SPD number of chips from clusters (!)
85c71ba7 319 Bool_t v0ABG = fSkipV0 ? 0 :triggerAnalysis->IsOfflineTriggerFired(aEsd, AliTriggerAnalysis::kV0ABG);
320 Bool_t v0CBG = fSkipV0 ? 0 :triggerAnalysis->IsOfflineTriggerFired(aEsd, AliTriggerAnalysis::kV0CBG);
f4ca8f20 321 Bool_t v0BG = v0ABG || v0CBG;
85c71ba7 322
323 // fmd
324 Bool_t fmdA = triggerAnalysis->IsOfflineTriggerFired(aEsd, AliTriggerAnalysis::kFMDA);
325 Bool_t fmdC = triggerAnalysis->IsOfflineTriggerFired(aEsd, AliTriggerAnalysis::kFMDC);
326 Bool_t fmd = fmdA || fmdC;
61899827 327
85c71ba7 328 // SSD
329 Int_t ssdClusters = triggerAnalysis->SSDClusters(aEsd);
330
331 // Some "macros"
332 Bool_t mb1 = (fastOROffline > 0 || v0A || v0C) && (!v0BG);
333 Bool_t mb1prime = (fastOROffline > 1 || (fastOROffline > 0 && (v0A || v0C)) || (v0A && v0C) ) && (!v0BG);
334
335 // Background rejection
336 Bool_t bgID = ! fBackgroundIdentification->IsSelected(const_cast<AliESDEvent*> (aEsd));
337
338 Int_t ntrig = fastOROffline; // any 2 hits
339 if(v0A) ntrig += 1;
340 if(v0C) ntrig += 1; //v0C alone is enough
341 if(fmd) ntrig += 1;
342 if(ssdClusters>1) ntrig += 1;
343
344
345 Bool_t hwTrig = fastORHW > 0 || v0AHW || v0CHW;
346
73cc8654 347 // Fill trigger pattern histo
348 Int_t tpatt = 0;
349 if (fastORHW>0) tpatt+=1;
350 if (v0AHW) tpatt+=2;
351 if (v0CHW) tpatt+=4;
352 fHistTriggerPattern->Fill( tpatt );
353
85c71ba7 354 // fill statistics and return decision
355 const Int_t nHistStat = 2;
356 for(Int_t iHistStat = 0; iHistStat < nHistStat; iHistStat++){
357 if (iHistStat == kStatIdxBin0 && !isBin0) continue; // skip the filling of bin0 stats if the event is not in the bin0
358
359 fHistStatistics[iHistStat]->Fill(kStatTriggerClass, i);
360
361
362
363 // We fill the rest only if hw trigger is ok
364 if (!hwTrig)
365 {
366 AliDebug(AliLog::kDebug, "Rejecting event because hardware trigger is not fired");
367 continue;
368 } else {
369 fHistStatistics[iHistStat]->Fill(kStatHWTrig, i);
370 }
733f0542 371
85c71ba7 372
373 // v0 BG stats
374 if (v0ABG)
375 fHistStatistics[iHistStat]->Fill(kStatV0ABG, i);
376 if (v0CBG)
377 fHistStatistics[iHistStat]->Fill(kStatV0CBG, i);
378
379 // We fill the rest only if mb1 && ! v0BG
380 if (mb1)
381 fHistStatistics[iHistStat]->Fill(kStatMB1, i);
382 else continue;
383
384 if (mb1prime)
385 fHistStatistics[iHistStat]->Fill(kStatMB1Prime, i);
386
387 if (fmd)
388 fHistStatistics[iHistStat]->Fill(kStatFMD, i);
389
390 if(ssdClusters>1)
391 fHistStatistics[iHistStat]->Fill(kStatSSD1, i);
392
393 if(ntrig >= 2 && !v0BG)
394 fHistStatistics[iHistStat]->Fill(kStatAny2Hits, i);
395
396 if (fastOROffline > 0)
397 fHistStatistics[iHistStat]->Fill(kStatFO1, i);
398 if (fastOROffline > 1)
399 fHistStatistics[iHistStat]->Fill(kStatFO2, i);
cc9d9320 400
85c71ba7 401 if (v0A)
402 fHistStatistics[iHistStat]->Fill(kStatV0A, i);
403 if (v0C)
404 fHistStatistics[iHistStat]->Fill(kStatV0C, i);
405
406 // if (fastOROffline > 1 && !v0BG)
407 // fHistStatistics[iHistStat]->Fill(kStatFO2NoBG, i);
408
409 if (fastOROffline > 0 && (v0A || v0C) && !v0BG)
410 fHistStatistics[iHistStat]->Fill(kStatFO1AndV0, i);
296dd262 411
85c71ba7 412 if (v0A && v0C && !v0BG && !bgID)
413 fHistStatistics[iHistStat]->Fill(kStatV0, i);
414
415
416 if ( mb1 )
417
418 {
419 if (!v0BG || fSkipV0)
420 {
421 if (!v0BG) fHistStatistics[iHistStat]->Fill(kStatOffline, i);
61899827 422
85c71ba7 423 if (fBackgroundIdentification && bgID)
424 {
425 AliDebug(AliLog::kDebug, "Rejecting event because of background identification");
426 fHistStatistics[iHistStat]->Fill(kStatBG, i);
427 }
428 else
429 {
430 AliDebug(AliLog::kDebug, "Accepted event for histograms");
296dd262 431
85c71ba7 432 fHistStatistics[iHistStat]->Fill(kStatAccepted, i);
433 if(iHistStat == kStatIdxAll) fHistBunchCrossing->Fill(aEsd->GetBunchCrossNumber(), i); // Fill only for all (avoid double counting)
434 if((i < fCollTrigClasses.GetEntries() || fSkipTriggerClassSelection) && (iHistStat==kStatIdxAll))
435 accept = kTRUE; // only set for "all" (should not really matter)
436 }
437 }
438 else
439 AliDebug(AliLog::kDebug, "Rejecting event because of V0 BG flag");
440 }
441 else
442 AliDebug(AliLog::kDebug, "Rejecting event because trigger condition is not fulfilled");
296dd262 443 }
296dd262 444 }
445 }
446
447 if (accept)
448 AliDebug(AliLog::kDebug, "Accepted event as collision candidate");
61899827 449
296dd262 450 return accept;
61899827 451}
a2ce3799 452
85c71ba7 453Int_t AliPhysicsSelection::GetTriggerScheme(UInt_t runNumber) const
a2ce3799 454{
455 // returns the current trigger scheme (classes that are accepted/rejected)
456
457 if (fMC)
458 return 0;
459
460 // TODO dependent on run number
4b7e8f3b 461
462 switch (runNumber)
463 {
464 // CSMBB triggers
465 case 104044:
466 case 105054:
467 case 105057:
468 return 2;
469 }
470
471 // default: CINT1 suite
a2ce3799 472 return 1;
473}
85c71ba7 474
475const char * AliPhysicsSelection::GetFillingScheme(UInt_t runNumber) {
476
477 if(fMC) return "MC";
478
479 if (runNumber >= 104065 && runNumber <= 104160) {
480 return "4x4a";
481 }
482 else if (runNumber >= 104315 && runNumber <= 104321) {
483 return "4x4a*";
484 }
485 else if (runNumber >= 104792 && runNumber <= 104803) {
486 return "4x4b";
487 }
488 else if (runNumber >= 104824 && runNumber <= 104892) {
489 return "4x4c";
490 }
491 else if (runNumber == 105143 || runNumber == 105160) {
492 return "16x16a";
493 }
494 else if (runNumber >= 105256 && runNumber <= 105268) {
495 return "4x4c";
5f337f3d 496 }
497 else if (runNumber >= 114786 && runNumber <= 116684) {
ca234d7a 498 return "Single_2b_1_1_1";
85c71ba7 499 }
5f337f3d 500 else if (runNumber >= 117048 && runNumber <= 117120) {
501 return "Single_3b_2_2_2";
502 }
503 else if (runNumber >= 117220 && runNumber <= 119163) {
504 return "Single_2b_1_1_1";
505 }
506 else if (runNumber >= 119837 && runNumber <= 119862) {
507 return "Single_4b_2_2_2";
508 }
509 else if (runNumber >= 119902 && runNumber <= 120691) {
510 return "Single_6b_3_3_3";
511 }
512 else if (runNumber >= 120741 && runNumber <= 122375) {
513 return "Single_13b_8_8_8";
514 }
85c71ba7 515 else {
516 AliError(Form("Unknown filling scheme (run %d)", runNumber));
517 }
518
519 return "Unknown";
520}
521
85c71ba7 522const char * AliPhysicsSelection::GetBXIDs(UInt_t runNumber, const char * trigger) {
523
524 if (!fUseBXNumbers || fMC) return "";
525
526 if (runNumber >= 104065 && runNumber <= 104160) {
527 if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #2128 #3019";
528 else if(!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #346 #3465";
529 else if(!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #1234 #1680";
530 else if(!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #790";
531 else AliError(Form("Unknown trigger: %s", trigger));
532 }
533 else if (runNumber >= 104315 && runNumber <= 104321) {
534 if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #2000 #2891";
535 else if(!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #218 #3337";
536 else if(!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #1106 #1552";
537 else if(!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #790";
538 else AliError(Form("Unknown trigger: %s", trigger));
539 }
540 else if (runNumber >= 104792 && runNumber <= 104803) {
541 if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #2228 #3119";
542 else if(!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #2554 #446";
543 else if(!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #1334 #769";
544 else if(!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #790";
545 else AliError(Form("Unknown trigger: %s", trigger));
546 }
547 else if (runNumber >= 104824 && runNumber <= 104892) {
548 if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #3119 #769";
549 else if(!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #2554 #446";
550 else if(!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #1334 #2228";
551 else if(!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #790";
552 else AliError(Form("Unknown trigger: %s", trigger));
553 }
554 else if (runNumber == 105143 || runNumber == 105160) {
85c71ba7 555 if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #1337 #1418 #2228 #2309 #3119 #3200 #446 #527";
556 else if(!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #1580 #1742 #1904 #2066 #2630 #2792 #2954 #3362";
557 else if(!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #845 #1007 #1169 #1577 #3359 #3521 #119 #281 ";
558 else if(!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #790";
559 else AliError(Form("Unknown trigger: %s", trigger));
560 }
561 else if (runNumber >= 105256 && runNumber <= 105268) {
562 if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #3019 #669";
563 else if(!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #2454 #346";
564 else if(!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #1234 #2128";
565 else if(!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #790";
566 else AliError(Form("Unknown trigger: %s", trigger));
73cc8654 567 } else if (runNumber >= 114786 && runNumber <= 116684) { // 7 TeV 2010, assume always the same filling scheme
ca234d7a 568 if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #346";
569 else if(!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #2131";
570 else if(!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #3019";
571 else if(!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #1238";
572 else AliError(Form("Unknown trigger: %s", trigger));
85c71ba7 573 }
5f337f3d 574 else if (runNumber >= 117048 && runNumber <= 117120) {
575 // return "Single_3b_2_2_2";
576 if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #346 #1240 ";
577 else if (!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #2131 ";
578 else if (!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #3019 ";
579 else if (!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #1238";
580 else AliError(Form("Unknown trigger: %s", trigger));
581
582 }
583 else if (runNumber >= 117220 && runNumber <= 119163) {
584 // return "Single_2b_1_1_1";
585 if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #346 ";
586 else if (!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #2131 ";
587 else if (!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #3019 ";
588 else if (!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #1238 ";
589 else AliError(Form("Unknown trigger: %s", trigger));
590 }
591 else if (runNumber >= 119837 && runNumber <= 119862) {
592 // return "Single_4b_2_2_2";
593 if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #669 #3019 ";
594 else if (!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #346 #2454 ";
595 else if (!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #1234 #2128 ";
596 else if (!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #1681 #3463";
597 else AliError(Form("Unknown trigger: %s", trigger));
598
599 }
600 else if (runNumber >= 119902 && runNumber <= 120691) {
601 // return "Single_6b_3_3_3";
602 if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #346 #546 #746 ";
603 else if (!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #2131 #2331 #2531 ";
604 else if (!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #3019 #3219 #3419 ";
605 else if (!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #1296 #1670";
606 else AliError(Form("Unknown trigger: %s", trigger));
607 }
608 else if (runNumber >= 120741 && runNumber <= 122375) {
609 // return "Single_13b_8_8_8";
610 if (!strcmp("CINT1B-ABCE-NOPF-ALL",trigger)) return " #346 #446 #546 #646 #1240 #1340 #1440 #1540 ";
611 else if (!strcmp("CINT1A-ABCE-NOPF-ALL",trigger)) return " #946 #2131 #2231 #2331 #2431 ";
612 else if (!strcmp("CINT1C-ABCE-NOPF-ALL",trigger)) return " #3019 #3119 #3219 #3319 #3519 ";
613 else if (!strcmp("CINT1-E-NOPF-ALL",trigger)) return " #1835 #2726";
614 else AliError(Form("Unknown trigger: %s", trigger));
615
616 }
617
85c71ba7 618 else {
619 AliError(Form("Unknown run %d, using all BXs!",runNumber));
620 }
621
622 return "";
623}
61899827 624
85c71ba7 625Bool_t AliPhysicsSelection::Initialize(Int_t runNumber)
61899827 626{
627 // initializes the object for the given run
628 // 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
629
29e8486e 630 Bool_t oldStatus = TH1::AddDirectoryStatus();
631 TH1::AddDirectory(kFALSE);
632
85c71ba7 633 if(!fBin0CallBack)
634 AliError("Bin0 Callback not set: will not fill the statistics for the bin 0");
635
636 if (fMC) {
637 // ovverride BX and bg options in case of MC
638 fComputeBG = kFALSE;
639 fUseBXNumbers = kFALSE;
640 }
641
a2ce3799 642 Int_t triggerScheme = GetTriggerScheme(runNumber);
91bea6e7 643 if (!fUsingCustomClasses && fCurrentRun != -1 && triggerScheme != GetTriggerScheme(fCurrentRun))
a2ce3799 644 AliFatal("Processing several runs with different trigger schemes is not supported");
296dd262 645
85c71ba7 646 if(fComputeBG && fCurrentRun != -1 && fCurrentRun != runNumber)
647 AliFatal("Cannot process several runs because BG computation is requested");
648
649 if(fComputeBG && !fUseBXNumbers)
650 AliFatal("Cannot compute BG id BX numbers are not used");
651
652 if(fUseBXNumbers && fFillingScheme != "" && fFillingScheme != GetFillingScheme(runNumber))
653 AliFatal("Cannot process runs with different filling scheme if usage of BX numbers is requested");
654
85c71ba7 655 fFillingScheme = GetFillingScheme(runNumber);
656
657 if(fComputeBG) SetBIFactors(runNumber);
658
61899827 659 AliInfo(Form("Initializing for run %d", runNumber));
660
758941d4 661 // initialize first time?
a2ce3799 662 if (fCurrentRun == -1)
a2ce3799 663 {
91bea6e7 664 if (fUsingCustomClasses) {
665 AliInfo("Using user-provided trigger classes");
666 } else {
667 switch (triggerScheme)
668 {
a2ce3799 669 case 0:
670 fCollTrigClasses.Add(new TObjString(""));
671 break;
91bea6e7 672
a2ce3799 673 case 1:
85c71ba7 674 { // need a new scope to avoid cross-initialization errors
73cc8654 675
676 if (fUseMuonTriggers) {
677 // Muon trigger have the same BXIDs of the corresponding CINT triggers
678 fCollTrigClasses.Add(new TObjString(Form("%s%s ","+CMUS1B-ABCE-NOPF-MUON", GetBXIDs(runNumber,"CINT1B-ABCE-NOPF-ALL"))));
679 fBGTrigClasses.Add (new TObjString(Form("%s%s ","+CMUS1A-ABCE-NOPF-MUON", GetBXIDs(runNumber,"CINT1A-ABCE-NOPF-ALL"))));
680 fBGTrigClasses.Add (new TObjString(Form("%s%s ","+CMUS1C-ABCE-NOPF-MUON", GetBXIDs(runNumber,"CINT1C-ABCE-NOPF-ALL"))));
681 fBGTrigClasses.Add (new TObjString(Form("%s%s ","+CMUS1-E-NOPF-MUON" , GetBXIDs(runNumber,"CINT1-E-NOPF-ALL"))));
682 }
85c71ba7 683 TObjString * cint1b = new TObjString(Form("%s%s","+CINT1B-ABCE-NOPF-ALL", GetBXIDs(runNumber,"CINT1B-ABCE-NOPF-ALL")));
684 TObjString * cint1a = new TObjString(Form("%s%s","+CINT1A-ABCE-NOPF-ALL", GetBXIDs(runNumber,"CINT1A-ABCE-NOPF-ALL")));
685 TObjString * cint1c = new TObjString(Form("%s%s","+CINT1C-ABCE-NOPF-ALL", GetBXIDs(runNumber,"CINT1C-ABCE-NOPF-ALL")));
686 TObjString * cint1e = new TObjString(Form("%s%s","+CINT1-E-NOPF-ALL", GetBXIDs(runNumber,"CINT1-E-NOPF-ALL")) );
687 //
688 fCollTrigClasses.Add(cint1b);
689 fBGTrigClasses.Add(cint1a);
690 fBGTrigClasses.Add(cint1c);
691 fBGTrigClasses.Add(cint1e);
73cc8654 692
85c71ba7 693 }
a2ce3799 694 break;
695
4b7e8f3b 696 case 2:
697 fCollTrigClasses.Add(new TObjString("+CSMBB-ABCE-NOPF-ALL"));
698 fBGTrigClasses.Add(new TObjString("+CSMBA-ABCE-NOPF-ALL -CSMBB-ABCE-NOPF-ALL"));
699 fBGTrigClasses.Add(new TObjString("+CSMBC-ABCE-NOPF-ALL -CSMBB-ABCE-NOPF-ALL"));
700 break;
91bea6e7 701
a2ce3799 702 default:
703 AliFatal(Form("Unsupported trigger scheme %d", triggerScheme));
91bea6e7 704 }
a2ce3799 705 }
91bea6e7 706
a2ce3799 707 Int_t count = fCollTrigClasses.GetEntries() + fBGTrigClasses.GetEntries();
708
709 for (Int_t i=0; i<count; i++)
710 {
711 AliTriggerAnalysis* triggerAnalysis = new AliTriggerAnalysis;
712 triggerAnalysis->SetAnalyzeMC(fMC);
713 triggerAnalysis->EnableHistograms();
714 triggerAnalysis->SetSPDGFOThreshhold(1);
715 fTriggerAnalysis.Add(triggerAnalysis);
716 }
717
85c71ba7 718 // TODO: shall I really delete this?
719 if (fHistStatistics[0])
720 delete fHistStatistics[0];
721 if (fHistStatistics[1])
722 delete fHistStatistics[1];
296dd262 723
85c71ba7 724 fHistStatistics[kStatIdxBin0] = BookHistStatistics("_Bin0");
725 fHistStatistics[kStatIdxAll] = BookHistStatistics("");
a2ce3799 726
727 if (fHistBunchCrossing)
728 delete fHistBunchCrossing;
729
730 fHistBunchCrossing = new TH2F("fHistBunchCrossing", "fHistBunchCrossing;bunch crossing number;", 4000, -0.5, 3999.5, count, -0.5, -0.5 + count);
73cc8654 731
732 if (fHistTriggerPattern)
733 delete fHistTriggerPattern;
734
735 const int ntrig=3;
85c71ba7 736 Int_t n = 1;
73cc8654 737 const Int_t nbinTrig = TMath::Nint(TMath::Power(2,ntrig));
738
739 fHistTriggerPattern = new TH1F("fHistTriggerPattern", "Trigger pattern: FO + 2*v0A + 4*v0C",
740 nbinTrig, -0.5, nbinTrig-0.5);
741 fHistTriggerPattern->GetXaxis()->SetBinLabel(1,"NO TRIG");
742 fHistTriggerPattern->GetXaxis()->SetBinLabel(2,"FO");
743 fHistTriggerPattern->GetXaxis()->SetBinLabel(3,"v0A");
744 fHistTriggerPattern->GetXaxis()->SetBinLabel(4,"FO & v0A");
745 fHistTriggerPattern->GetXaxis()->SetBinLabel(5,"v0C");
746 fHistTriggerPattern->GetXaxis()->SetBinLabel(6,"FO & v0C");
747 fHistTriggerPattern->GetXaxis()->SetBinLabel(7,"v0A & v0C");
748 fHistTriggerPattern->GetXaxis()->SetBinLabel(8,"FO & v0A & v0C");
749
750
751 n = 1;
a2ce3799 752 for (Int_t i=0; i < fCollTrigClasses.GetEntries(); i++)
753 {
a2ce3799 754 fHistBunchCrossing->GetYaxis()->SetBinLabel(n, ((TObjString*) fCollTrigClasses.At(i))->String());
755 n++;
756 }
757 for (Int_t i=0; i < fBGTrigClasses.GetEntries(); i++)
758 {
a2ce3799 759 fHistBunchCrossing->GetYaxis()->SetBinLabel(n, ((TObjString*) fBGTrigClasses.At(i))->String());
760 n++;
761 }
85c71ba7 762
763
764
a2ce3799 765 }
766
767 Int_t count = fCollTrigClasses.GetEntries() + fBGTrigClasses.GetEntries();
296dd262 768 for (Int_t i=0; i<count; i++)
61899827 769 {
a2ce3799 770 AliTriggerAnalysis* triggerAnalysis = static_cast<AliTriggerAnalysis*> (fTriggerAnalysis.At(i));
771
296dd262 772 switch (runNumber)
773 {
a2ce3799 774 case 104315:
296dd262 775 case 104316:
776 case 104320:
a2ce3799 777 case 104321:
296dd262 778 case 104439:
779 triggerAnalysis->SetV0TimeOffset(7.5);
780 break;
a2ce3799 781 default:
782 triggerAnalysis->SetV0TimeOffset(0);
296dd262 783 }
f4ca8f20 784 }
785
758941d4 786 fCurrentRun = runNumber;
787
29e8486e 788 TH1::AddDirectory(oldStatus);
789
61899827 790 return kTRUE;
791}
792
85c71ba7 793TH2F * AliPhysicsSelection::BookHistStatistics(const char * tag) {
794
795 // add 6 rows to count for the estimate of good, accidentals and
796 // BG and the ratio of BG and accidentals to total +ratio goot to
797 // first col + 2 for error on good.
798
799 Int_t count = fCollTrigClasses.GetEntries() + fBGTrigClasses.GetEntries();
800#ifdef VERBOSE_STAT
801 Int_t extrarows = fComputeBG ? 8 : 0;
802#else
803 Int_t extrarows = fComputeBG ? 3 : 0;
804#endif
805 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);
806
807 h->GetXaxis()->SetBinLabel(kStatTriggerClass, "Trigger class");
808 h->GetXaxis()->SetBinLabel(kStatHWTrig, "Hardware trigger");
809 h->GetXaxis()->SetBinLabel(kStatFO1, "FO >= 1");
810 h->GetXaxis()->SetBinLabel(kStatFO2, "FO >= 2");
811 h->GetXaxis()->SetBinLabel(kStatV0A, "V0A");
812 h->GetXaxis()->SetBinLabel(kStatV0C, "V0C");
813 h->GetXaxis()->SetBinLabel(kStatFMD, "FMD");
814 h->GetXaxis()->SetBinLabel(kStatSSD1, "SSD >= 2");
815 h->GetXaxis()->SetBinLabel(kStatV0ABG, "V0A BG");
816 h->GetXaxis()->SetBinLabel(kStatV0CBG, "V0C BG");
817 h->GetXaxis()->SetBinLabel(kStatMB1, "(FO >= 1 | V0A | V0C) & !V0 BG");
818 h->GetXaxis()->SetBinLabel(kStatMB1Prime, "(FO >= 2 | (FO >= 1 & (V0A | V0C)) | (V0A &v0C) ) & !V0 BG");
819 h->GetXaxis()->SetBinLabel(kStatFO1AndV0, "FO >= 1 & (V0A | V0C) & !V0 BG");
820 h->GetXaxis()->SetBinLabel(kStatV0, "V0A & V0C & !V0 BG & !BG ID");
821 h->GetXaxis()->SetBinLabel(kStatOffline, "Offline Trigger");
822 h->GetXaxis()->SetBinLabel(kStatAny2Hits, "2 Hits & !V0 BG");
823 h->GetXaxis()->SetBinLabel(kStatBG, "Background identification");
824 h->GetXaxis()->SetBinLabel(kStatAccepted, "Accepted");
825
826 Int_t n = 1;
827 for (Int_t i=0; i < fCollTrigClasses.GetEntries(); i++)
828 {
829 h->GetYaxis()->SetBinLabel(n, ((TObjString*) fCollTrigClasses.At(i))->String());
830 n++;
831 }
832 for (Int_t i=0; i < fBGTrigClasses.GetEntries(); i++)
833 {
834 h->GetYaxis()->SetBinLabel(n, ((TObjString*) fBGTrigClasses.At(i))->String());
835 n++;
836 }
837
838 if(fComputeBG) {
839 h->GetYaxis()->SetBinLabel(n++, "BG (A+C)");
840 h->GetYaxis()->SetBinLabel(n++, "ACC");
841#ifdef VERBOSE_STAT
842 h->GetYaxis()->SetBinLabel(n++, "BG (A+C) % (rel. to CINT1B)");
843 h->GetYaxis()->SetBinLabel(n++, "ACC % (rel. to CINT1B)");
844 h->GetYaxis()->SetBinLabel(n++, "ERR GOOD %");
845 h->GetYaxis()->SetBinLabel(n++, "GOOD % (rel. to 1st col)");
846 h->GetYaxis()->SetBinLabel(n++, "ERR GOOD");
847#endif
848 h->GetYaxis()->SetBinLabel(n++, "GOOD");
849 }
850
851 return h;
852}
853
61899827 854void AliPhysicsSelection::Print(Option_t* /* option */) const
855{
856 // print the configuration
857
a2ce3799 858 Printf("Configuration initialized for run %d (MC: %d):", fCurrentRun, fMC);
61899827 859
296dd262 860 Printf("Collision trigger classes:");
861 for (Int_t i=0; i < fCollTrigClasses.GetEntries(); i++)
862 Printf("%s", ((TObjString*) fCollTrigClasses.At(i))->String().Data());
61899827 863
296dd262 864 Printf("Background trigger classes:");
865 for (Int_t i=0; i < fBGTrigClasses.GetEntries(); i++)
866 Printf("%s", ((TObjString*) fBGTrigClasses.At(i))->String().Data());
867
868 AliTriggerAnalysis* triggerAnalysis = dynamic_cast<AliTriggerAnalysis*> (fTriggerAnalysis.At(0));
61899827 869
296dd262 870 if (triggerAnalysis)
871 {
872 if (triggerAnalysis->GetV0TimeOffset() > 0)
873 Printf("V0 time offset active: %.2f ns", triggerAnalysis->GetV0TimeOffset());
61899827 874
296dd262 875 Printf("\nTotal available events:");
528640ed 876
296dd262 877 triggerAnalysis->PrintTriggerClasses();
878 }
528640ed 879
85c71ba7 880 if (fHistStatistics[kStatIdxAll] && fCollTrigClasses.GetEntries() > 0)
b43e01ed 881 {
cc9d9320 882 Printf("\nSelection statistics for first collision trigger (%s):", ((TObjString*) fCollTrigClasses.First())->String().Data());
b43e01ed 883
85c71ba7 884 Printf("Total events with correct trigger class: %d", (Int_t) fHistStatistics[kStatIdxAll]->GetBinContent(1, 1));
885 Printf("Selected collision candidates: %d", (Int_t) fHistStatistics[kStatIdxAll]->GetBinContent(fHistStatistics[kStatIdxAll]->GetXaxis()->FindBin("Accepted"), 1));
17ba346c 886 }
887
888 if (fHistBunchCrossing)
889 {
890 Printf("\nBunch crossing statistics:");
891
892 for (Int_t i=1; i<=fHistBunchCrossing->GetNbinsY(); i++)
893 {
894 TString str;
895 str.Form("Trigger %s has accepted events in the bunch crossings: ", fHistBunchCrossing->GetYaxis()->GetBinLabel(i));
896
897 for (Int_t j=1; j<=fHistBunchCrossing->GetNbinsX(); j++)
898 if (fHistBunchCrossing->GetBinContent(j, i) > 0)
899 str += Form("%d, ", (Int_t) fHistBunchCrossing->GetXaxis()->GetBinCenter(j));
900
901 Printf("%s", str.Data());
902 }
903
904 for (Int_t j=1; j<=fHistBunchCrossing->GetNbinsX(); j++)
905 {
906 Int_t count = 0;
907 for (Int_t i=1; i<=fHistBunchCrossing->GetNbinsY(); i++)
908 {
909 if (fHistBunchCrossing->GetBinContent(j, i) > 0)
910 count++;
911 }
912 if (count > 1)
913 Printf("WARNING: Bunch crossing %d has more than one trigger class active. Check BPTX functioning for this run!", (Int_t) fHistBunchCrossing->GetXaxis()->GetBinCenter(j));
914 }
b43e01ed 915 }
91bea6e7 916
917 if (fUsingCustomClasses)
918 Printf("WARNING: Using custom trigger classes!");
919 if (fSkipTriggerClassSelection)
920 Printf("WARNING: Skipping trigger class selection!");
85c71ba7 921 if (fSkipV0)
922 Printf("WARNING: Ignoring V0 information in selection");
923 if(!fBin0CallBack)
924 Printf("WARNING: Callback not set: will not fill the statistics for the bin 0");
925
61899827 926}
927
928Long64_t AliPhysicsSelection::Merge(TCollection* list)
929{
930 // Merge a list of AliMultiplicityCorrection objects with this (needed for
931 // PROOF).
932 // Returns the number of merged objects (including this).
933
934 if (!list)
935 return 0;
936
937 if (list->IsEmpty())
938 return 1;
939
940 TIterator* iter = list->MakeIterator();
941 TObject* obj;
17ba346c 942
61899827 943 // collections of all histograms
944 const Int_t nHists = 9;
945 TList collections[nHists];
946
947 Int_t count = 0;
948 while ((obj = iter->Next())) {
949
950 AliPhysicsSelection* entry = dynamic_cast<AliPhysicsSelection*> (obj);
951 if (entry == 0)
952 continue;
17ba346c 953
954 collections[0].Add(&(entry->fTriggerAnalysis));
85c71ba7 955 if (entry->fHistStatistics[0])
956 collections[1].Add(entry->fHistStatistics[0]);
957 if (entry->fHistStatistics[1])
958 collections[2].Add(entry->fHistStatistics[1]);
17ba346c 959 if (entry->fHistBunchCrossing)
85c71ba7 960 collections[3].Add(entry->fHistBunchCrossing);
73cc8654 961 if (entry->fHistTriggerPattern)
962 collections[4].Add(entry->fHistTriggerPattern);
296dd262 963 if (entry->fBackgroundIdentification)
73cc8654 964 collections[5].Add(entry->fBackgroundIdentification);
61899827 965
966 count++;
967 }
968
17ba346c 969 fTriggerAnalysis.Merge(&collections[0]);
85c71ba7 970 if (fHistStatistics[0])
971 fHistStatistics[0]->Merge(&collections[1]);
972 if (fHistStatistics[1])
973 fHistStatistics[1]->Merge(&collections[2]);
17ba346c 974 if (fHistBunchCrossing)
85c71ba7 975 fHistBunchCrossing->Merge(&collections[3]);
73cc8654 976 if (fHistTriggerPattern)
977 fHistTriggerPattern->Merge(&collections[4]);
296dd262 978 if (fBackgroundIdentification)
73cc8654 979 fBackgroundIdentification->Merge(&collections[5]);
61899827 980
981 delete iter;
982
983 return count+1;
984}
985
986void AliPhysicsSelection::SaveHistograms(const char* folder) const
987{
988 // write histograms to current directory
989
85c71ba7 990 if (!fHistStatistics[0] || !fHistStatistics[1])
61899827 991 return;
992
993 if (folder)
994 {
995 gDirectory->mkdir(folder);
996 gDirectory->cd(folder);
997 }
998
85c71ba7 999
1000 // Fill the last rows of fHistStatistics before saving
1001 if (fComputeBG) {
1002 Int_t triggerScheme = GetTriggerScheme(UInt_t(fCurrentRun));
1003 if(triggerScheme != 1){
1004 AliWarning("BG estimate only supported for trigger scheme \"1\" (CINT1 suite)");
73cc8654 1005 } else if (fUseMuonTriggers) {
1006 AliWarning("BG estimate with muon triggers to be implemented");
85c71ba7 1007 } else {
5f337f3d 1008 // 0. Determine the ratios of triggers E/B, A/B, C/B from the stat histogram
1009 // Those are used to rescale the different classes to the same number of bx ids
1010 Float_t nB = 0;
1011 Float_t nC = 0;
1012 Float_t nA = 0;
1013 Float_t nE = 0;
1014 for (Int_t j=1; j<=fHistBunchCrossing->GetNbinsX(); j++) {
1015 if (fHistBunchCrossing->GetBinContent(j, 1) > 0) nB++;
1016 if (fHistBunchCrossing->GetBinContent(j, 2) > 0) nA++;
1017 if (fHistBunchCrossing->GetBinContent(j, 3) > 0) nC++;
1018 if (fHistBunchCrossing->GetBinContent(j, 4) > 0) nE++;
1019 }
1020 Float_t ratioBE = nB/nE;
1021 Float_t ratioBA = nB/nA;
1022 Float_t ratioBC = nB/nC;
1023 Printf("Ratio between the BX ids in the different trigger classes:");
1024 Printf(" B/E = %f",ratioBE);
1025 Printf(" B/A = %f",ratioBA);
1026 Printf(" B/C = %f",ratioBC);
85c71ba7 1027 Int_t nHistStat = 2;
1028 // TODO: get number of rows in a more flexible way
1029 // 1. loop over all cols
1030
1031 for(Int_t iHistStat = 0; iHistStat < nHistStat; iHistStat++){
1032
1033 Int_t ncol = fHistStatistics[iHistStat]->GetNbinsX();
1034 Float_t good1 = 0;
1035 for(Int_t icol = 1; icol <= ncol; icol++) {
1036 Int_t cint1B = (Int_t) fHistStatistics[iHistStat]->GetBinContent(icol,1);
1037 Int_t cint1A = (Int_t) fHistStatistics[iHistStat]->GetBinContent(icol,2);
1038 Int_t cint1C = (Int_t) fHistStatistics[iHistStat]->GetBinContent(icol,3);
1039 Int_t cint1E = (Int_t) fHistStatistics[iHistStat]->GetBinContent(icol,4);
1040
1041 if (cint1B>0) {
5f337f3d 1042 Int_t acc = ratioBE*cint1E;
1043 Double_t acc_err = TMath::Sqrt(ratioBE*ratioBE*cint1E);
85c71ba7 1044 // Int_t bg = cint1A + cint1C - 2*acc;
5f337f3d 1045 Float_t bg = fBIFactorA*(ratioBA*cint1A-acc) + fBIFactorC*(ratioBC*cint1C-acc) ;
85c71ba7 1046 Float_t good = Float_t(cint1B) - bg - acc;
1047 if (icol ==1) good1 = good;
1048 // Float_t errGood = TMath::Sqrt(2*(cint1A+cint1C+cint1E));// Error on the number of goods assuming only bg fluctuates
1049 // DeltaG^2 = B + FA^2 A + FC^2 C + Ratio^2 (FA+FC-1)^2 E.
1050 Float_t errGood = TMath::Sqrt( cint1B +
5f337f3d 1051 fBIFactorA*fBIFactorA*ratioBA*ratioBA*cint1A +
1052 fBIFactorC*fBIFactorC*ratioBC*ratioBC*cint1C +
1053 ratioBE * ratioBE *
85c71ba7 1054 (fBIFactorA + fBIFactorC - 1)*(fBIFactorA + fBIFactorC - 1)*cint1E);
5f337f3d 1055 Float_t errBG = TMath::Sqrt(fBIFactorA*fBIFactorA*ratioBA*ratioBA*cint1A+
1056 fBIFactorC*fBIFactorC*ratioBC*ratioBC*cint1C+
1057 ratioBE*ratioBE*(fBIFactorA+fBIFactorC)*(fBIFactorA+fBIFactorC)*cint1E);
85c71ba7 1058
1059
1060 fHistStatistics[iHistStat]->SetBinContent(icol,kStatRowBG,bg);
1061 fHistStatistics[iHistStat]->SetBinError (icol,kStatRowBG,errBG);
1062 fHistStatistics[iHistStat]->SetBinContent(icol,kStatRowAcc,acc);
ca234d7a 1063 fHistStatistics[iHistStat]->SetBinError (icol,kStatRowAcc,acc_err);
85c71ba7 1064 fHistStatistics[iHistStat]->SetBinContent(icol,kStatRowGood,good);
1065 fHistStatistics[iHistStat]->SetBinError (icol,kStatRowGood,errGood);
1066
1067#ifdef VERBOSE_STAT
ca234d7a 1068 //kStatRowBG=5,kStatRowAcc,kStatRowBGFrac,kStatRowAccFrac,kStatRowErrGoodFrac,kStatRowGoodFrac,kStatRowGood,kStatRowErrGood
85c71ba7 1069 Float_t accFrac = Float_t(acc) / cint1B *100;
ca234d7a 1070 Float_t errAccFrac= Float_t(acc_err) / cint1B *100;
85c71ba7 1071 Float_t bgFrac = Float_t(bg) / cint1B *100;
1072 Float_t goodFrac = Float_t(good) / good1 *100;
1073 Float_t errGoodFrac = errGood/good1 * 100;
73cc8654 1074 Float_t errFracBG = bg > 0 ? TMath::Sqrt((errBG/bg)*(errBG/bg) + 1/cint1B)*bgFrac : 0;
85c71ba7 1075 fHistStatistics[iHistStat]->SetBinContent(icol,kStatRowBGFrac,bgFrac);
1076 fHistStatistics[iHistStat]->SetBinError (icol,kStatRowBGFrac,errFracBG);
1077 fHistStatistics[iHistStat]->SetBinContent(icol,kStatRowAccFrac,accFrac);
ca234d7a 1078 fHistStatistics[iHistStat]->SetBinError (icol,kStatRowAccFrac,errAccFrac);
85c71ba7 1079 fHistStatistics[iHistStat]->SetBinContent(icol,kStatRowGoodFrac,goodFrac);
ca234d7a 1080 fHistStatistics[iHistStat]->SetBinContent(icol,kStatRowErrGoodFrac,errGoodFrac);
85c71ba7 1081 fHistStatistics[iHistStat]->SetBinContent(icol,kStatRowErrGood,errGood);
1082#endif
1083 }
1084 }
1085 }
1086 }
1087 }
1088
1089 fHistStatistics[0]->Write();
1090 fHistStatistics[1]->Write();
8e58a7b9 1091 if(fHistBunchCrossing ) fHistBunchCrossing ->Write();
1092 if(fHistTriggerPattern) fHistTriggerPattern->Write();
61899827 1093
296dd262 1094 Int_t count = fCollTrigClasses.GetEntries() + fBGTrigClasses.GetEntries();
1095 for (Int_t i=0; i < count; i++)
1096 {
1097 TString triggerClass = "trigger_histograms_";
1098 if (i < fCollTrigClasses.GetEntries())
1099 triggerClass += ((TObjString*) fCollTrigClasses.At(i))->String();
1100 else
1101 triggerClass += ((TObjString*) fBGTrigClasses.At(i - fCollTrigClasses.GetEntries()))->String();
61899827 1102
296dd262 1103 gDirectory->mkdir(triggerClass);
1104 gDirectory->cd(triggerClass);
61899827 1105
296dd262 1106 static_cast<AliTriggerAnalysis*> (fTriggerAnalysis.At(i))->SaveHistograms();
1107
1108 gDirectory->cd("..");
1109 }
1110
1111 if (fBackgroundIdentification)
1112 {
1113 gDirectory->mkdir("background_identification");
1114 gDirectory->cd("background_identification");
1115
1116 fBackgroundIdentification->GetOutput()->Write();
1117
1118 gDirectory->cd("..");
1119 }
61899827 1120
1121 if (folder)
1122 gDirectory->cd("..");
1123}
85c71ba7 1124
1125void AliPhysicsSelection::SetBIFactors(Int_t run) {
1126
1127 switch(run) {
1128 case 104155:
1129 fBIFactorA = 0.961912722908;
1130 fBIFactorC = 1.04992336081;
1131 break;
1132 case 104157:
1133 fBIFactorA = 0.947312854998;
1134 fBIFactorC = 1.01599706417;
1135 break;
1136 case 104159:
1137 fBIFactorA = 0.93659320151;
1138 fBIFactorC = 0.98580804207;
1139 break;
1140 case 104160:
1141 fBIFactorA = 0.929664189926;
1142 fBIFactorC = 0.963467679851;
1143 break;
1144 case 104315:
1145 fBIFactorA = 1.08939104979;
1146 fBIFactorC = 0.931113921925;
1147 break;
1148 case 104316:
1149 fBIFactorA = 1.08351880974;
1150 fBIFactorC = 0.916068345845;
1151 break;
1152 case 104320:
1153 fBIFactorA = 1.07669281245;
1154 fBIFactorC = 0.876818744763;
1155 break;
1156 case 104321:
1157 fBIFactorA = 1.00971079602;
1158 fBIFactorC = 0.773781299076;
1159 break;
1160 case 104792:
1161 fBIFactorA = 0.787215863962;
1162 fBIFactorC = 0.778253173071;
1163 break;
1164 case 104793:
1165 fBIFactorA = 0.692211363661;
1166 fBIFactorC = 0.733152456667;
1167 break;
1168 case 104799:
1169 fBIFactorA = 1.04027825161;
1170 fBIFactorC = 1.00530825942;
1171 break;
1172 case 104800:
1173 fBIFactorA = 1.05309910671;
1174 fBIFactorC = 1.00376801855;
1175 break;
1176 case 104801:
1177 fBIFactorA = 1.0531231922;
1178 fBIFactorC = 0.992439666758;
1179 break;
1180 case 104802:
1181 fBIFactorA = 1.04191478134;
1182 fBIFactorC = 0.979368585208;
1183 break;
1184 case 104803:
1185 fBIFactorA = 1.03121314094;
1186 fBIFactorC = 0.973379962609;
1187 break;
1188 case 104824:
1189 fBIFactorA = 0.969945926722;
1190 fBIFactorC = 0.39549745806;
1191 break;
1192 case 104825:
1193 fBIFactorA = 0.968627213937;
1194 fBIFactorC = 0.310100412205;
1195 break;
1196 case 104841:
1197 fBIFactorA = 0.991601393212;
1198 fBIFactorC = 0.83762204722;
1199 break;
1200 case 104845:
1201 fBIFactorA = 0.98040863886;
1202 fBIFactorC = 0.694824205793;
1203 break;
1204 case 104867:
1205 fBIFactorA = 1.10646173412;
1206 fBIFactorC = 0.841407246916;
1207 break;
1208 case 104876:
1209 fBIFactorA = 1.12063452421;
1210 fBIFactorC = 0.78726542895;
1211 break;
1212 case 104890:
1213 fBIFactorA = 1.02346137453;
1214 fBIFactorC = 1.03355663595;
1215 break;
1216 case 104892:
1217 fBIFactorA = 1.05406025913;
1218 fBIFactorC = 1.00029166135;
1219 break;
1220 case 105143:
1221 fBIFactorA = 0.947343384349;
1222 fBIFactorC = 0.972637444408;
1223 break;
1224 case 105160:
1225 fBIFactorA = 0.908854622177;
1226 fBIFactorC = 0.958851103977;
1227 break;
1228 case 105256:
1229 fBIFactorA = 0.810076150206;
1230 fBIFactorC = 0.884663561883;
1231 break;
1232 case 105257:
1233 fBIFactorA = 0.80974912303;
1234 fBIFactorC = 0.878859123479;
1235 break;
1236 case 105268:
1237 fBIFactorA = 0.809052110679;
1238 fBIFactorC = 0.87233890989;
1239 break;
1240 default:
1241 fBIFactorA = 1;
1242 fBIFactorC = 1;
1243 }
1244
1245
1246}