Apply corrections
[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//
decf6fd4 41// Usually the class selects the trigger scheme by itself depending on the run number.
42// Nevertheless, you can do that manually by calling AddCollisionTriggerClass() and AddBGTriggerClass()
43// Example:
44// To define the class CINT1B-ABCE-NOPF-ALL as collision trigger (those will be accepted as
45// collision candidates when they pass the selection):
46// AddCollisionTriggerClass("+CINT1B-ABCE-NOPF-ALL #769 #3119");
47// To select on bunch crossing IDs in addition, use:
48// AddCollisionTriggerClass("+CINT1B-ABCE-NOPF-ALL #769 #3119");
49// To define the class CINT1A-ABCE-NOPF-ALL as a background trigger (those will only be counted
50// for the control histograms):
51// AddBGTriggerClass("+CINT1A-ABCE-NOPF-ALL");
52// You can also specify more than one trigger class in a string or you can require that some are *not*
53// present. The following line would require CSMBA-ABCE-NOPF-ALL, but CSMBB-ABCE-NOPF-ALL is not allowed
54// to be present:
55// AddBGTriggerClass("+CSMBA-ABCE-NOPF-ALL -CSMBB-ABCE-NOPF-ALL");
56//
61899827 57// Origin: Jan Fiete Grosse-Oetringhaus, CERN
58//-------------------------------------------------------------------------
59
60#include <Riostream.h>
61#include <TH1F.h>
62#include <TH2F.h>
63#include <TList.h>
64#include <TIterator.h>
65#include <TDirectory.h>
296dd262 66#include <TObjArray.h>
61899827 67
68#include <AliPhysicsSelection.h>
69
70#include <AliTriggerAnalysis.h>
71#include <AliLog.h>
72
73#include <AliESDEvent.h>
74
75ClassImp(AliPhysicsSelection)
76
77AliPhysicsSelection::AliPhysicsSelection() :
296dd262 78 AliAnalysisCuts("AliPhysicsSelection", "AliPhysicsSelection"),
79 fCurrentRun(-1),
a2ce3799 80 fMC(kFALSE),
296dd262 81 fCollTrigClasses(),
82 fBGTrigClasses(),
83 fTriggerAnalysis(),
84 fBackgroundIdentification(0),
61899827 85 fHistStatistics(0),
91bea6e7 86 fHistBunchCrossing(0),
87 fSkipTriggerClassSelection(0),
88 fUsingCustomClasses(0)
61899827 89{
90 // constructor
91
296dd262 92 fCollTrigClasses.SetOwner(1);
93 fBGTrigClasses.SetOwner(1);
94 fTriggerAnalysis.SetOwner(1);
95
61899827 96 AliLog::SetClassDebugLevel("AliPhysicsSelection", AliLog::kWarning);
97}
98
99AliPhysicsSelection::~AliPhysicsSelection()
100{
101 // destructor
102
296dd262 103 fCollTrigClasses.Delete();
104 fBGTrigClasses.Delete();
105 fTriggerAnalysis.Delete();
61899827 106
107 if (fHistStatistics)
108 {
109 delete fHistStatistics;
110 fHistStatistics = 0;
111 }
112
113 if (fHistBunchCrossing)
114 {
115 delete fHistBunchCrossing;
116 fHistBunchCrossing = 0;
117 }
118}
296dd262 119
120Bool_t AliPhysicsSelection::CheckTriggerClass(const AliESDEvent* aEsd, const char* trigger) const
121{
122 // checks if the given trigger class(es) are found for the current event
123 // format of trigger: +TRIGGER1 -TRIGGER2
124 // requires TRIGGER1 and rejects TRIGGER2
125
decf6fd4 126 Bool_t foundBCRequirement = kFALSE;
127 Bool_t foundCorrectBC = kFALSE;
128
296dd262 129 TString str(trigger);
130 TObjArray* tokens = str.Tokenize(" ");
131
132 for (Int_t i=0; i < tokens->GetEntries(); i++)
133 {
134 TString str2(((TObjString*) tokens->At(i))->String());
135
decf6fd4 136 if (str2[0] == '+' || str2[0] == '-')
296dd262 137 {
decf6fd4 138 Bool_t flag = (str2[0] == '+');
139
140 str2.Remove(0, 1);
141
142 if (flag && !aEsd->IsTriggerClassFired(str2))
143 {
144 AliDebug(AliLog::kDebug, Form("Rejecting event because trigger class %s is not present", str2.Data()));
145 delete tokens;
146 return kFALSE;
147 }
148 if (!flag && aEsd->IsTriggerClassFired(str2))
149 {
150 AliDebug(AliLog::kDebug, Form("Rejecting event because trigger class %s is present", str2.Data()));
151 delete tokens;
152 return kFALSE;
153 }
296dd262 154 }
decf6fd4 155 else if (str2[0] == '#')
296dd262 156 {
decf6fd4 157 foundBCRequirement = kTRUE;
158
159 str2.Remove(0, 1);
160
161 Int_t bcNumber = str2.Atoi();
162 AliDebug(AliLog::kDebug, Form("Checking for bunch crossing number %d", bcNumber));
163
164 if (aEsd->GetBunchCrossNumber() == bcNumber)
165 {
166 foundCorrectBC = kTRUE;
167 AliDebug(AliLog::kDebug, Form("Found correct bunch crossing %d", bcNumber));
168 }
296dd262 169 }
decf6fd4 170 else
171 AliFatal(Form("Invalid trigger syntax: %s", trigger));
296dd262 172 }
173
174 delete tokens;
decf6fd4 175
176 if (foundBCRequirement && !foundCorrectBC)
177 return kFALSE;
178
296dd262 179 return kTRUE;
180}
61899827 181
182Bool_t AliPhysicsSelection::IsCollisionCandidate(const AliESDEvent* aEsd)
183{
184 // checks if the given event is a collision candidate
185
95e6f4ec 186 if (fCurrentRun != aEsd->GetRunNumber())
187 if (!Initialize(aEsd->GetRunNumber()))
188 AliFatal(Form("Could not initialize for run %d", aEsd->GetRunNumber()));
189
61899827 190 const AliESDHeader* esdHeader = aEsd->GetHeader();
191 if (!esdHeader)
192 {
193 AliError("ESD Header could not be retrieved");
194 return kFALSE;
195 }
196
a2ce3799 197 // check event type; should be PHYSICS = 7 for data and 0 for MC
198 if (!fMC)
199 {
200 if (esdHeader->GetEventType() != 7)
201 return kFALSE;
202 }
203 else
204 {
205 if (esdHeader->GetEventType() != 0)
206 AliFatal(Form("Invalid event type for MC: %d", esdHeader->GetEventType()));
207 }
758941d4 208
296dd262 209 Bool_t accept = kFALSE;
210
211 Int_t count = fCollTrigClasses.GetEntries() + fBGTrigClasses.GetEntries();
212 for (Int_t i=0; i < count; i++)
61899827 213 {
296dd262 214 const char* triggerClass = 0;
215 if (i < fCollTrigClasses.GetEntries())
216 triggerClass = ((TObjString*) fCollTrigClasses.At(i))->String();
217 else
218 triggerClass = ((TObjString*) fBGTrigClasses.At(i - fCollTrigClasses.GetEntries()))->String();
61899827 219
296dd262 220 AliDebug(AliLog::kDebug, Form("Processing trigger class %s", triggerClass));
61899827 221
296dd262 222 AliTriggerAnalysis* triggerAnalysis = static_cast<AliTriggerAnalysis*> (fTriggerAnalysis.At(i));
61899827 223
296dd262 224 triggerAnalysis->FillTriggerClasses(aEsd);
61899827 225
296dd262 226 if (CheckTriggerClass(aEsd, triggerClass))
227 {
228 triggerAnalysis->FillHistograms(aEsd);
229
230 fHistStatistics->Fill(1, i);
cc9d9320 231
232 // hardware trigger (should only remove events for MC)
233 // replay CINT1B hardware trigger
234 // TODO this has to depend on the actual hardware trigger (and that depends on the run...)
235 Int_t fastORHW = triggerAnalysis->SPDFiredChips(aEsd, 1); // SPD number of chips from trigger bits (!)
733f0542 236
237 AliTriggerAnalysis::V0Decision v0ADecision = triggerAnalysis->V0Trigger(aEsd, AliTriggerAnalysis::kASide);
238 AliTriggerAnalysis::V0Decision v0CDecision = triggerAnalysis->V0Trigger(aEsd, AliTriggerAnalysis::kCSide);
239
240 Bool_t v0A = (v0ADecision == AliTriggerAnalysis::kV0BB);
241 Bool_t v0C = (v0CDecision == AliTriggerAnalysis::kV0BB);
cc9d9320 242
243 if (fastORHW == 0 && !v0A && !v0C)
244 {
245 AliDebug(AliLog::kDebug, "Rejecting event because hardware trigger is not fired");
246 continue;
247 }
248
249 fHistStatistics->Fill(2, i);
250
251 // offline trigger
252 Int_t fastOROffline = triggerAnalysis->SPDFiredChips(aEsd, 0); // SPD number of chips from clusters (!)
733f0542 253 Bool_t v0ABG = (v0ADecision == AliTriggerAnalysis::kV0BG);
254 Bool_t v0CBG = (v0CDecision == AliTriggerAnalysis::kV0BG);
f4ca8f20 255 Bool_t v0BG = v0ABG || v0CBG;
61899827 256
cc9d9320 257 if (fastOROffline > 0)
296dd262 258 fHistStatistics->Fill(3, i);
cc9d9320 259 if (fastOROffline > 1)
260 fHistStatistics->Fill(4, i);
296dd262 261
262 if (v0A)
296dd262 263 fHistStatistics->Fill(5, i);
cc9d9320 264 if (v0C)
296dd262 265 fHistStatistics->Fill(6, i);
cc9d9320 266 if (v0ABG)
f4ca8f20 267 fHistStatistics->Fill(7, i);
cc9d9320 268 if (v0CBG)
f4ca8f20 269 fHistStatistics->Fill(8, i);
17ba346c 270
733f0542 271 if (v0ADecision == AliTriggerAnalysis::kV0Fake)
17ba346c 272 fHistStatistics->Fill(9, i);
733f0542 273 if (v0CDecision == AliTriggerAnalysis::kV0Fake)
274 fHistStatistics->Fill(10, i);
275
276 if (fastOROffline > 1 && !v0BG)
277 fHistStatistics->Fill(11, i);
cc9d9320 278
279 if ((fastOROffline > 0 || v0A || v0C) && !v0BG)
733f0542 280 fHistStatistics->Fill(12, i);
cc9d9320 281
282 if (fastOROffline > 0 && (v0A || v0C) && !v0BG)
733f0542 283 fHistStatistics->Fill(13, i);
296dd262 284
285 if (v0A && v0C && !v0BG)
733f0542 286 fHistStatistics->Fill(14, i);
287
cc9d9320 288 if (fastOROffline > 1 || (fastOROffline > 0 && (v0A || v0C)) || (v0A && v0C))
296dd262 289 {
290 if (!v0BG)
291 {
733f0542 292 fHistStatistics->Fill(15, i);
61899827 293
296dd262 294 if (fBackgroundIdentification && !fBackgroundIdentification->IsSelected(const_cast<AliESDEvent*> (aEsd)))
295 {
296 AliDebug(AliLog::kDebug, "Rejecting event because of background identification");
733f0542 297 fHistStatistics->Fill(16, i);
296dd262 298 }
299 else
300 {
301 AliDebug(AliLog::kDebug, "Accepted event for histograms");
302
733f0542 303 fHistStatistics->Fill(17, i);
296dd262 304 fHistBunchCrossing->Fill(aEsd->GetBunchCrossNumber(), i);
91bea6e7 305 if (i < fCollTrigClasses.GetEntries() || fSkipTriggerClassSelection)
296dd262 306 accept = kTRUE;
307 }
308 }
309 else
310 AliDebug(AliLog::kDebug, "Rejecting event because of V0 BG flag");
311 }
312 else
313 AliDebug(AliLog::kDebug, "Rejecting event because trigger condition is not fulfilled");
314 }
315 }
316
317 if (accept)
318 AliDebug(AliLog::kDebug, "Accepted event as collision candidate");
61899827 319
296dd262 320 return accept;
61899827 321}
a2ce3799 322
4b7e8f3b 323Int_t AliPhysicsSelection::GetTriggerScheme(UInt_t runNumber)
a2ce3799 324{
325 // returns the current trigger scheme (classes that are accepted/rejected)
326
327 if (fMC)
328 return 0;
329
330 // TODO dependent on run number
4b7e8f3b 331
332 switch (runNumber)
333 {
334 // CSMBB triggers
335 case 104044:
336 case 105054:
337 case 105057:
338 return 2;
339 }
340
341 // default: CINT1 suite
a2ce3799 342 return 1;
343}
61899827 344
345Bool_t AliPhysicsSelection::Initialize(UInt_t runNumber)
346{
347 // initializes the object for the given run
348 // 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
349
29e8486e 350 Bool_t oldStatus = TH1::AddDirectoryStatus();
351 TH1::AddDirectory(kFALSE);
352
a2ce3799 353 Int_t triggerScheme = GetTriggerScheme(runNumber);
354
91bea6e7 355 if (!fUsingCustomClasses && fCurrentRun != -1 && triggerScheme != GetTriggerScheme(fCurrentRun))
a2ce3799 356 AliFatal("Processing several runs with different trigger schemes is not supported");
296dd262 357
61899827 358 AliInfo(Form("Initializing for run %d", runNumber));
359
758941d4 360 // initialize first time?
a2ce3799 361 if (fCurrentRun == -1)
a2ce3799 362 {
91bea6e7 363 if (fUsingCustomClasses) {
364 AliInfo("Using user-provided trigger classes");
365 } else {
366 switch (triggerScheme)
367 {
a2ce3799 368 case 0:
369 fCollTrigClasses.Add(new TObjString(""));
370 break;
91bea6e7 371
a2ce3799 372 case 1:
373 fCollTrigClasses.Add(new TObjString("+CINT1B-ABCE-NOPF-ALL"));
374 fBGTrigClasses.Add(new TObjString("+CINT1A-ABCE-NOPF-ALL"));
375 fBGTrigClasses.Add(new TObjString("+CINT1C-ABCE-NOPF-ALL"));
376 fBGTrigClasses.Add(new TObjString("+CINT1-E-NOPF-ALL"));
377 break;
378
4b7e8f3b 379 case 2:
380 fCollTrigClasses.Add(new TObjString("+CSMBB-ABCE-NOPF-ALL"));
381 fBGTrigClasses.Add(new TObjString("+CSMBA-ABCE-NOPF-ALL -CSMBB-ABCE-NOPF-ALL"));
382 fBGTrigClasses.Add(new TObjString("+CSMBC-ABCE-NOPF-ALL -CSMBB-ABCE-NOPF-ALL"));
383 break;
91bea6e7 384
a2ce3799 385 default:
386 AliFatal(Form("Unsupported trigger scheme %d", triggerScheme));
91bea6e7 387 }
a2ce3799 388 }
91bea6e7 389
a2ce3799 390 Int_t count = fCollTrigClasses.GetEntries() + fBGTrigClasses.GetEntries();
391
392 for (Int_t i=0; i<count; i++)
393 {
394 AliTriggerAnalysis* triggerAnalysis = new AliTriggerAnalysis;
395 triggerAnalysis->SetAnalyzeMC(fMC);
396 triggerAnalysis->EnableHistograms();
397 triggerAnalysis->SetSPDGFOThreshhold(1);
398 fTriggerAnalysis.Add(triggerAnalysis);
399 }
400
401 if (fHistStatistics)
402 delete fHistStatistics;
296dd262 403
733f0542 404 fHistStatistics = new TH2F("fHistStatistics", "fHistStatistics;;", 17, 0.5, 17.5, count, -0.5, -0.5 + count);
a2ce3799 405
406 Int_t n = 1;
cc9d9320 407 fHistStatistics->GetXaxis()->SetBinLabel(n++, "Trigger class");
408 fHistStatistics->GetXaxis()->SetBinLabel(n++, "Hardware trigger");
a2ce3799 409 fHistStatistics->GetXaxis()->SetBinLabel(n++, "FO >= 1");
410 fHistStatistics->GetXaxis()->SetBinLabel(n++, "FO >= 2");
411 fHistStatistics->GetXaxis()->SetBinLabel(n++, "V0A");
412 fHistStatistics->GetXaxis()->SetBinLabel(n++, "V0C");
413 fHistStatistics->GetXaxis()->SetBinLabel(n++, "V0A BG");
414 fHistStatistics->GetXaxis()->SetBinLabel(n++, "V0C BG");
733f0542 415 fHistStatistics->GetXaxis()->SetBinLabel(n++, "V0A Fake");
416 fHistStatistics->GetXaxis()->SetBinLabel(n++, "V0C Fake");
a2ce3799 417 fHistStatistics->GetXaxis()->SetBinLabel(n++, "FO >= 2 &!V0 BG");
418 fHistStatistics->GetXaxis()->SetBinLabel(n++, "(FO >= 1 | V0A | V0C) & !V0 BG");
419 fHistStatistics->GetXaxis()->SetBinLabel(n++, "FO >= 1 & (V0A | V0C) & !V0 BG");
420 fHistStatistics->GetXaxis()->SetBinLabel(n++, "V0A & V0C & !V0 BG");
421 fHistStatistics->GetXaxis()->SetBinLabel(n++, "(FO >= 2 | (FO >= 1 & (V0A | V0C)) | (V0A & V0C)) & !V0 BG");
422 fHistStatistics->GetXaxis()->SetBinLabel(n++, "Background identification");
423 fHistStatistics->GetXaxis()->SetBinLabel(n++, "Accepted");
424
425 if (fHistBunchCrossing)
426 delete fHistBunchCrossing;
427
428 fHistBunchCrossing = new TH2F("fHistBunchCrossing", "fHistBunchCrossing;bunch crossing number;", 4000, -0.5, 3999.5, count, -0.5, -0.5 + count);
429
430 n = 1;
431 for (Int_t i=0; i < fCollTrigClasses.GetEntries(); i++)
432 {
433 fHistStatistics->GetYaxis()->SetBinLabel(n, ((TObjString*) fCollTrigClasses.At(i))->String());
434 fHistBunchCrossing->GetYaxis()->SetBinLabel(n, ((TObjString*) fCollTrigClasses.At(i))->String());
435 n++;
436 }
437 for (Int_t i=0; i < fBGTrigClasses.GetEntries(); i++)
438 {
439 fHistStatistics->GetYaxis()->SetBinLabel(n, ((TObjString*) fBGTrigClasses.At(i))->String());
440 fHistBunchCrossing->GetYaxis()->SetBinLabel(n, ((TObjString*) fBGTrigClasses.At(i))->String());
441 n++;
442 }
443 }
444
445 Int_t count = fCollTrigClasses.GetEntries() + fBGTrigClasses.GetEntries();
296dd262 446 for (Int_t i=0; i<count; i++)
61899827 447 {
a2ce3799 448 AliTriggerAnalysis* triggerAnalysis = static_cast<AliTriggerAnalysis*> (fTriggerAnalysis.At(i));
449
296dd262 450 switch (runNumber)
451 {
a2ce3799 452 case 104315:
296dd262 453 case 104316:
454 case 104320:
a2ce3799 455 case 104321:
296dd262 456 case 104439:
457 triggerAnalysis->SetV0TimeOffset(7.5);
458 break;
a2ce3799 459 default:
460 triggerAnalysis->SetV0TimeOffset(0);
296dd262 461 }
f4ca8f20 462 }
463
758941d4 464 fCurrentRun = runNumber;
465
29e8486e 466 TH1::AddDirectory(oldStatus);
467
61899827 468 return kTRUE;
469}
470
471void AliPhysicsSelection::Print(Option_t* /* option */) const
472{
473 // print the configuration
474
a2ce3799 475 Printf("Configuration initialized for run %d (MC: %d):", fCurrentRun, fMC);
61899827 476
296dd262 477 Printf("Collision trigger classes:");
478 for (Int_t i=0; i < fCollTrigClasses.GetEntries(); i++)
479 Printf("%s", ((TObjString*) fCollTrigClasses.At(i))->String().Data());
61899827 480
296dd262 481 Printf("Background trigger classes:");
482 for (Int_t i=0; i < fBGTrigClasses.GetEntries(); i++)
483 Printf("%s", ((TObjString*) fBGTrigClasses.At(i))->String().Data());
484
485 AliTriggerAnalysis* triggerAnalysis = dynamic_cast<AliTriggerAnalysis*> (fTriggerAnalysis.At(0));
61899827 486
296dd262 487 if (triggerAnalysis)
488 {
489 if (triggerAnalysis->GetV0TimeOffset() > 0)
490 Printf("V0 time offset active: %.2f ns", triggerAnalysis->GetV0TimeOffset());
61899827 491
296dd262 492 Printf("\nTotal available events:");
528640ed 493
296dd262 494 triggerAnalysis->PrintTriggerClasses();
495 }
528640ed 496
cc9d9320 497 if (fHistStatistics && fCollTrigClasses.GetEntries() > 0)
b43e01ed 498 {
cc9d9320 499 Printf("\nSelection statistics for first collision trigger (%s):", ((TObjString*) fCollTrigClasses.First())->String().Data());
b43e01ed 500
501 Printf("Total events with correct trigger class: %d", (Int_t) fHistStatistics->GetBinContent(1, 1));
17ba346c 502 Printf("Selected collision candidates: %d", (Int_t) fHistStatistics->GetBinContent(fHistStatistics->GetXaxis()->FindBin("Accepted"), 1));
503 }
504
505 if (fHistBunchCrossing)
506 {
507 Printf("\nBunch crossing statistics:");
508
509 for (Int_t i=1; i<=fHistBunchCrossing->GetNbinsY(); i++)
510 {
511 TString str;
512 str.Form("Trigger %s has accepted events in the bunch crossings: ", fHistBunchCrossing->GetYaxis()->GetBinLabel(i));
513
514 for (Int_t j=1; j<=fHistBunchCrossing->GetNbinsX(); j++)
515 if (fHistBunchCrossing->GetBinContent(j, i) > 0)
516 str += Form("%d, ", (Int_t) fHistBunchCrossing->GetXaxis()->GetBinCenter(j));
517
518 Printf("%s", str.Data());
519 }
520
521 for (Int_t j=1; j<=fHistBunchCrossing->GetNbinsX(); j++)
522 {
523 Int_t count = 0;
524 for (Int_t i=1; i<=fHistBunchCrossing->GetNbinsY(); i++)
525 {
526 if (fHistBunchCrossing->GetBinContent(j, i) > 0)
527 count++;
528 }
529 if (count > 1)
530 Printf("WARNING: Bunch crossing %d has more than one trigger class active. Check BPTX functioning for this run!", (Int_t) fHistBunchCrossing->GetXaxis()->GetBinCenter(j));
531 }
b43e01ed 532 }
91bea6e7 533
534 if (fUsingCustomClasses)
535 Printf("WARNING: Using custom trigger classes!");
536 if (fSkipTriggerClassSelection)
537 Printf("WARNING: Skipping trigger class selection!");
61899827 538}
539
540Long64_t AliPhysicsSelection::Merge(TCollection* list)
541{
542 // Merge a list of AliMultiplicityCorrection objects with this (needed for
543 // PROOF).
544 // Returns the number of merged objects (including this).
545
546 if (!list)
547 return 0;
548
549 if (list->IsEmpty())
550 return 1;
551
552 TIterator* iter = list->MakeIterator();
553 TObject* obj;
17ba346c 554
61899827 555 // collections of all histograms
556 const Int_t nHists = 9;
557 TList collections[nHists];
558
559 Int_t count = 0;
560 while ((obj = iter->Next())) {
561
562 AliPhysicsSelection* entry = dynamic_cast<AliPhysicsSelection*> (obj);
563 if (entry == 0)
564 continue;
17ba346c 565
566 collections[0].Add(&(entry->fTriggerAnalysis));
567 if (entry->fHistStatistics)
568 collections[1].Add(entry->fHistStatistics);
569 if (entry->fHistBunchCrossing)
570 collections[2].Add(entry->fHistBunchCrossing);
296dd262 571 if (entry->fBackgroundIdentification)
17ba346c 572 collections[3].Add(entry->fBackgroundIdentification);
61899827 573
574 count++;
575 }
576
17ba346c 577 fTriggerAnalysis.Merge(&collections[0]);
578 if (fHistStatistics)
579 fHistStatistics->Merge(&collections[1]);
580 if (fHistBunchCrossing)
581 fHistBunchCrossing->Merge(&collections[2]);
296dd262 582 if (fBackgroundIdentification)
17ba346c 583 fBackgroundIdentification->Merge(&collections[3]);
61899827 584
585 delete iter;
586
587 return count+1;
588}
589
590void AliPhysicsSelection::SaveHistograms(const char* folder) const
591{
592 // write histograms to current directory
593
594 if (!fHistStatistics)
595 return;
596
597 if (folder)
598 {
599 gDirectory->mkdir(folder);
600 gDirectory->cd(folder);
601 }
602
603 fHistStatistics->Write();
604 fHistBunchCrossing->Write();
605
296dd262 606 Int_t count = fCollTrigClasses.GetEntries() + fBGTrigClasses.GetEntries();
607 for (Int_t i=0; i < count; i++)
608 {
609 TString triggerClass = "trigger_histograms_";
610 if (i < fCollTrigClasses.GetEntries())
611 triggerClass += ((TObjString*) fCollTrigClasses.At(i))->String();
612 else
613 triggerClass += ((TObjString*) fBGTrigClasses.At(i - fCollTrigClasses.GetEntries()))->String();
61899827 614
296dd262 615 gDirectory->mkdir(triggerClass);
616 gDirectory->cd(triggerClass);
61899827 617
296dd262 618 static_cast<AliTriggerAnalysis*> (fTriggerAnalysis.At(i))->SaveHistograms();
619
620 gDirectory->cd("..");
621 }
622
623 if (fBackgroundIdentification)
624 {
625 gDirectory->mkdir("background_identification");
626 gDirectory->cd("background_identification");
627
628 fBackgroundIdentification->GetOutput()->Write();
629
630 gDirectory->cd("..");
631 }
61899827 632
633 if (folder)
634 gDirectory->cd("..");
635}