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 | |
75 | ClassImp(AliPhysicsSelection) |
76 | |
77 | AliPhysicsSelection::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 | |
99 | AliPhysicsSelection::~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 | |
120 | Bool_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 | |
182 | Bool_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 (!) |
296dd262 |
236 | Bool_t v0A = triggerAnalysis->IsOfflineTriggerFired(aEsd, AliTriggerAnalysis::kV0A); |
237 | Bool_t v0C = triggerAnalysis->IsOfflineTriggerFired(aEsd, AliTriggerAnalysis::kV0C); |
cc9d9320 |
238 | |
239 | if (fastORHW == 0 && !v0A && !v0C) |
240 | { |
241 | AliDebug(AliLog::kDebug, "Rejecting event because hardware trigger is not fired"); |
242 | continue; |
243 | } |
244 | |
245 | fHistStatistics->Fill(2, i); |
246 | |
247 | // offline trigger |
248 | Int_t fastOROffline = triggerAnalysis->SPDFiredChips(aEsd, 0); // SPD number of chips from clusters (!) |
f4ca8f20 |
249 | Bool_t v0ABG = triggerAnalysis->IsOfflineTriggerFired(aEsd, AliTriggerAnalysis::kV0ABG); |
250 | Bool_t v0CBG = triggerAnalysis->IsOfflineTriggerFired(aEsd, AliTriggerAnalysis::kV0CBG); |
251 | Bool_t v0BG = v0ABG || v0CBG; |
61899827 |
252 | |
cc9d9320 |
253 | if (fastOROffline > 0) |
296dd262 |
254 | fHistStatistics->Fill(3, i); |
cc9d9320 |
255 | if (fastOROffline > 1) |
256 | fHistStatistics->Fill(4, i); |
296dd262 |
257 | |
258 | if (v0A) |
296dd262 |
259 | fHistStatistics->Fill(5, i); |
cc9d9320 |
260 | if (v0C) |
296dd262 |
261 | fHistStatistics->Fill(6, i); |
cc9d9320 |
262 | if (v0ABG) |
f4ca8f20 |
263 | fHistStatistics->Fill(7, i); |
cc9d9320 |
264 | if (v0CBG) |
f4ca8f20 |
265 | fHistStatistics->Fill(8, i); |
17ba346c |
266 | |
cc9d9320 |
267 | if (fastOROffline > 1 && !v0BG) |
17ba346c |
268 | fHistStatistics->Fill(9, i); |
cc9d9320 |
269 | |
270 | if ((fastOROffline > 0 || v0A || v0C) && !v0BG) |
17ba346c |
271 | fHistStatistics->Fill(10, i); |
cc9d9320 |
272 | |
273 | if (fastOROffline > 0 && (v0A || v0C) && !v0BG) |
274 | fHistStatistics->Fill(11, i); |
296dd262 |
275 | |
276 | if (v0A && v0C && !v0BG) |
cc9d9320 |
277 | fHistStatistics->Fill(12, i); |
296dd262 |
278 | |
cc9d9320 |
279 | if (fastOROffline > 1 || (fastOROffline > 0 && (v0A || v0C)) || (v0A && v0C)) |
296dd262 |
280 | { |
281 | if (!v0BG) |
282 | { |
cc9d9320 |
283 | fHistStatistics->Fill(13, i); |
61899827 |
284 | |
296dd262 |
285 | if (fBackgroundIdentification && !fBackgroundIdentification->IsSelected(const_cast<AliESDEvent*> (aEsd))) |
286 | { |
287 | AliDebug(AliLog::kDebug, "Rejecting event because of background identification"); |
cc9d9320 |
288 | fHistStatistics->Fill(14, i); |
296dd262 |
289 | } |
290 | else |
291 | { |
292 | AliDebug(AliLog::kDebug, "Accepted event for histograms"); |
293 | |
cc9d9320 |
294 | fHistStatistics->Fill(15, i); |
296dd262 |
295 | fHistBunchCrossing->Fill(aEsd->GetBunchCrossNumber(), i); |
91bea6e7 |
296 | if (i < fCollTrigClasses.GetEntries() || fSkipTriggerClassSelection) |
296dd262 |
297 | accept = kTRUE; |
298 | } |
299 | } |
300 | else |
301 | AliDebug(AliLog::kDebug, "Rejecting event because of V0 BG flag"); |
302 | } |
303 | else |
304 | AliDebug(AliLog::kDebug, "Rejecting event because trigger condition is not fulfilled"); |
305 | } |
306 | } |
307 | |
308 | if (accept) |
309 | AliDebug(AliLog::kDebug, "Accepted event as collision candidate"); |
61899827 |
310 | |
296dd262 |
311 | return accept; |
61899827 |
312 | } |
a2ce3799 |
313 | |
4b7e8f3b |
314 | Int_t AliPhysicsSelection::GetTriggerScheme(UInt_t runNumber) |
a2ce3799 |
315 | { |
316 | // returns the current trigger scheme (classes that are accepted/rejected) |
317 | |
318 | if (fMC) |
319 | return 0; |
320 | |
321 | // TODO dependent on run number |
4b7e8f3b |
322 | |
323 | switch (runNumber) |
324 | { |
325 | // CSMBB triggers |
326 | case 104044: |
327 | case 105054: |
328 | case 105057: |
329 | return 2; |
330 | } |
331 | |
332 | // default: CINT1 suite |
a2ce3799 |
333 | return 1; |
334 | } |
61899827 |
335 | |
336 | Bool_t AliPhysicsSelection::Initialize(UInt_t runNumber) |
337 | { |
338 | // initializes the object for the given run |
339 | // 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 |
340 | |
29e8486e |
341 | Bool_t oldStatus = TH1::AddDirectoryStatus(); |
342 | TH1::AddDirectory(kFALSE); |
343 | |
a2ce3799 |
344 | Int_t triggerScheme = GetTriggerScheme(runNumber); |
345 | |
91bea6e7 |
346 | if (!fUsingCustomClasses && fCurrentRun != -1 && triggerScheme != GetTriggerScheme(fCurrentRun)) |
a2ce3799 |
347 | AliFatal("Processing several runs with different trigger schemes is not supported"); |
296dd262 |
348 | |
61899827 |
349 | AliInfo(Form("Initializing for run %d", runNumber)); |
350 | |
758941d4 |
351 | // initialize first time? |
a2ce3799 |
352 | if (fCurrentRun == -1) |
a2ce3799 |
353 | { |
91bea6e7 |
354 | if (fUsingCustomClasses) { |
355 | AliInfo("Using user-provided trigger classes"); |
356 | } else { |
357 | switch (triggerScheme) |
358 | { |
a2ce3799 |
359 | case 0: |
360 | fCollTrigClasses.Add(new TObjString("")); |
361 | break; |
91bea6e7 |
362 | |
a2ce3799 |
363 | case 1: |
364 | fCollTrigClasses.Add(new TObjString("+CINT1B-ABCE-NOPF-ALL")); |
365 | fBGTrigClasses.Add(new TObjString("+CINT1A-ABCE-NOPF-ALL")); |
366 | fBGTrigClasses.Add(new TObjString("+CINT1C-ABCE-NOPF-ALL")); |
367 | fBGTrigClasses.Add(new TObjString("+CINT1-E-NOPF-ALL")); |
368 | break; |
369 | |
4b7e8f3b |
370 | case 2: |
371 | fCollTrigClasses.Add(new TObjString("+CSMBB-ABCE-NOPF-ALL")); |
372 | fBGTrigClasses.Add(new TObjString("+CSMBA-ABCE-NOPF-ALL -CSMBB-ABCE-NOPF-ALL")); |
373 | fBGTrigClasses.Add(new TObjString("+CSMBC-ABCE-NOPF-ALL -CSMBB-ABCE-NOPF-ALL")); |
374 | break; |
91bea6e7 |
375 | |
a2ce3799 |
376 | default: |
377 | AliFatal(Form("Unsupported trigger scheme %d", triggerScheme)); |
91bea6e7 |
378 | } |
a2ce3799 |
379 | } |
91bea6e7 |
380 | |
a2ce3799 |
381 | Int_t count = fCollTrigClasses.GetEntries() + fBGTrigClasses.GetEntries(); |
382 | |
383 | for (Int_t i=0; i<count; i++) |
384 | { |
385 | AliTriggerAnalysis* triggerAnalysis = new AliTriggerAnalysis; |
386 | triggerAnalysis->SetAnalyzeMC(fMC); |
387 | triggerAnalysis->EnableHistograms(); |
388 | triggerAnalysis->SetSPDGFOThreshhold(1); |
389 | fTriggerAnalysis.Add(triggerAnalysis); |
390 | } |
391 | |
392 | if (fHistStatistics) |
393 | delete fHistStatistics; |
296dd262 |
394 | |
cc9d9320 |
395 | fHistStatistics = new TH2F("fHistStatistics", "fHistStatistics;;", 15, 0.5, 15.5, count, -0.5, -0.5 + count); |
a2ce3799 |
396 | |
397 | Int_t n = 1; |
cc9d9320 |
398 | fHistStatistics->GetXaxis()->SetBinLabel(n++, "Trigger class"); |
399 | fHistStatistics->GetXaxis()->SetBinLabel(n++, "Hardware trigger"); |
a2ce3799 |
400 | fHistStatistics->GetXaxis()->SetBinLabel(n++, "FO >= 1"); |
401 | fHistStatistics->GetXaxis()->SetBinLabel(n++, "FO >= 2"); |
402 | fHistStatistics->GetXaxis()->SetBinLabel(n++, "V0A"); |
403 | fHistStatistics->GetXaxis()->SetBinLabel(n++, "V0C"); |
404 | fHistStatistics->GetXaxis()->SetBinLabel(n++, "V0A BG"); |
405 | fHistStatistics->GetXaxis()->SetBinLabel(n++, "V0C BG"); |
406 | fHistStatistics->GetXaxis()->SetBinLabel(n++, "FO >= 2 &!V0 BG"); |
407 | fHistStatistics->GetXaxis()->SetBinLabel(n++, "(FO >= 1 | V0A | V0C) & !V0 BG"); |
408 | fHistStatistics->GetXaxis()->SetBinLabel(n++, "FO >= 1 & (V0A | V0C) & !V0 BG"); |
409 | fHistStatistics->GetXaxis()->SetBinLabel(n++, "V0A & V0C & !V0 BG"); |
410 | fHistStatistics->GetXaxis()->SetBinLabel(n++, "(FO >= 2 | (FO >= 1 & (V0A | V0C)) | (V0A & V0C)) & !V0 BG"); |
411 | fHistStatistics->GetXaxis()->SetBinLabel(n++, "Background identification"); |
412 | fHistStatistics->GetXaxis()->SetBinLabel(n++, "Accepted"); |
413 | |
414 | if (fHistBunchCrossing) |
415 | delete fHistBunchCrossing; |
416 | |
417 | fHistBunchCrossing = new TH2F("fHistBunchCrossing", "fHistBunchCrossing;bunch crossing number;", 4000, -0.5, 3999.5, count, -0.5, -0.5 + count); |
418 | |
419 | n = 1; |
420 | for (Int_t i=0; i < fCollTrigClasses.GetEntries(); i++) |
421 | { |
422 | fHistStatistics->GetYaxis()->SetBinLabel(n, ((TObjString*) fCollTrigClasses.At(i))->String()); |
423 | fHistBunchCrossing->GetYaxis()->SetBinLabel(n, ((TObjString*) fCollTrigClasses.At(i))->String()); |
424 | n++; |
425 | } |
426 | for (Int_t i=0; i < fBGTrigClasses.GetEntries(); i++) |
427 | { |
428 | fHistStatistics->GetYaxis()->SetBinLabel(n, ((TObjString*) fBGTrigClasses.At(i))->String()); |
429 | fHistBunchCrossing->GetYaxis()->SetBinLabel(n, ((TObjString*) fBGTrigClasses.At(i))->String()); |
430 | n++; |
431 | } |
432 | } |
433 | |
434 | Int_t count = fCollTrigClasses.GetEntries() + fBGTrigClasses.GetEntries(); |
296dd262 |
435 | for (Int_t i=0; i<count; i++) |
61899827 |
436 | { |
a2ce3799 |
437 | AliTriggerAnalysis* triggerAnalysis = static_cast<AliTriggerAnalysis*> (fTriggerAnalysis.At(i)); |
438 | |
296dd262 |
439 | switch (runNumber) |
440 | { |
a2ce3799 |
441 | case 104315: |
296dd262 |
442 | case 104316: |
443 | case 104320: |
a2ce3799 |
444 | case 104321: |
296dd262 |
445 | case 104439: |
446 | triggerAnalysis->SetV0TimeOffset(7.5); |
447 | break; |
a2ce3799 |
448 | default: |
449 | triggerAnalysis->SetV0TimeOffset(0); |
296dd262 |
450 | } |
f4ca8f20 |
451 | } |
452 | |
758941d4 |
453 | fCurrentRun = runNumber; |
454 | |
29e8486e |
455 | TH1::AddDirectory(oldStatus); |
456 | |
61899827 |
457 | return kTRUE; |
458 | } |
459 | |
460 | void AliPhysicsSelection::Print(Option_t* /* option */) const |
461 | { |
462 | // print the configuration |
463 | |
a2ce3799 |
464 | Printf("Configuration initialized for run %d (MC: %d):", fCurrentRun, fMC); |
61899827 |
465 | |
296dd262 |
466 | Printf("Collision trigger classes:"); |
467 | for (Int_t i=0; i < fCollTrigClasses.GetEntries(); i++) |
468 | Printf("%s", ((TObjString*) fCollTrigClasses.At(i))->String().Data()); |
61899827 |
469 | |
296dd262 |
470 | Printf("Background trigger classes:"); |
471 | for (Int_t i=0; i < fBGTrigClasses.GetEntries(); i++) |
472 | Printf("%s", ((TObjString*) fBGTrigClasses.At(i))->String().Data()); |
473 | |
474 | AliTriggerAnalysis* triggerAnalysis = dynamic_cast<AliTriggerAnalysis*> (fTriggerAnalysis.At(0)); |
61899827 |
475 | |
296dd262 |
476 | if (triggerAnalysis) |
477 | { |
478 | if (triggerAnalysis->GetV0TimeOffset() > 0) |
479 | Printf("V0 time offset active: %.2f ns", triggerAnalysis->GetV0TimeOffset()); |
61899827 |
480 | |
296dd262 |
481 | Printf("\nTotal available events:"); |
528640ed |
482 | |
296dd262 |
483 | triggerAnalysis->PrintTriggerClasses(); |
484 | } |
528640ed |
485 | |
cc9d9320 |
486 | if (fHistStatistics && fCollTrigClasses.GetEntries() > 0) |
b43e01ed |
487 | { |
cc9d9320 |
488 | Printf("\nSelection statistics for first collision trigger (%s):", ((TObjString*) fCollTrigClasses.First())->String().Data()); |
b43e01ed |
489 | |
490 | Printf("Total events with correct trigger class: %d", (Int_t) fHistStatistics->GetBinContent(1, 1)); |
17ba346c |
491 | Printf("Selected collision candidates: %d", (Int_t) fHistStatistics->GetBinContent(fHistStatistics->GetXaxis()->FindBin("Accepted"), 1)); |
492 | } |
493 | |
494 | if (fHistBunchCrossing) |
495 | { |
496 | Printf("\nBunch crossing statistics:"); |
497 | |
498 | for (Int_t i=1; i<=fHistBunchCrossing->GetNbinsY(); i++) |
499 | { |
500 | TString str; |
501 | str.Form("Trigger %s has accepted events in the bunch crossings: ", fHistBunchCrossing->GetYaxis()->GetBinLabel(i)); |
502 | |
503 | for (Int_t j=1; j<=fHistBunchCrossing->GetNbinsX(); j++) |
504 | if (fHistBunchCrossing->GetBinContent(j, i) > 0) |
505 | str += Form("%d, ", (Int_t) fHistBunchCrossing->GetXaxis()->GetBinCenter(j)); |
506 | |
507 | Printf("%s", str.Data()); |
508 | } |
509 | |
510 | for (Int_t j=1; j<=fHistBunchCrossing->GetNbinsX(); j++) |
511 | { |
512 | Int_t count = 0; |
513 | for (Int_t i=1; i<=fHistBunchCrossing->GetNbinsY(); i++) |
514 | { |
515 | if (fHistBunchCrossing->GetBinContent(j, i) > 0) |
516 | count++; |
517 | } |
518 | if (count > 1) |
519 | Printf("WARNING: Bunch crossing %d has more than one trigger class active. Check BPTX functioning for this run!", (Int_t) fHistBunchCrossing->GetXaxis()->GetBinCenter(j)); |
520 | } |
b43e01ed |
521 | } |
91bea6e7 |
522 | |
523 | if (fUsingCustomClasses) |
524 | Printf("WARNING: Using custom trigger classes!"); |
525 | if (fSkipTriggerClassSelection) |
526 | Printf("WARNING: Skipping trigger class selection!"); |
61899827 |
527 | } |
528 | |
529 | Long64_t AliPhysicsSelection::Merge(TCollection* list) |
530 | { |
531 | // Merge a list of AliMultiplicityCorrection objects with this (needed for |
532 | // PROOF). |
533 | // Returns the number of merged objects (including this). |
534 | |
535 | if (!list) |
536 | return 0; |
537 | |
538 | if (list->IsEmpty()) |
539 | return 1; |
540 | |
541 | TIterator* iter = list->MakeIterator(); |
542 | TObject* obj; |
17ba346c |
543 | |
61899827 |
544 | // collections of all histograms |
545 | const Int_t nHists = 9; |
546 | TList collections[nHists]; |
547 | |
548 | Int_t count = 0; |
549 | while ((obj = iter->Next())) { |
550 | |
551 | AliPhysicsSelection* entry = dynamic_cast<AliPhysicsSelection*> (obj); |
552 | if (entry == 0) |
553 | continue; |
17ba346c |
554 | |
555 | collections[0].Add(&(entry->fTriggerAnalysis)); |
556 | if (entry->fHistStatistics) |
557 | collections[1].Add(entry->fHistStatistics); |
558 | if (entry->fHistBunchCrossing) |
559 | collections[2].Add(entry->fHistBunchCrossing); |
296dd262 |
560 | if (entry->fBackgroundIdentification) |
17ba346c |
561 | collections[3].Add(entry->fBackgroundIdentification); |
61899827 |
562 | |
563 | count++; |
564 | } |
565 | |
17ba346c |
566 | fTriggerAnalysis.Merge(&collections[0]); |
567 | if (fHistStatistics) |
568 | fHistStatistics->Merge(&collections[1]); |
569 | if (fHistBunchCrossing) |
570 | fHistBunchCrossing->Merge(&collections[2]); |
296dd262 |
571 | if (fBackgroundIdentification) |
17ba346c |
572 | fBackgroundIdentification->Merge(&collections[3]); |
61899827 |
573 | |
574 | delete iter; |
575 | |
576 | return count+1; |
577 | } |
578 | |
579 | void AliPhysicsSelection::SaveHistograms(const char* folder) const |
580 | { |
581 | // write histograms to current directory |
582 | |
583 | if (!fHistStatistics) |
584 | return; |
585 | |
586 | if (folder) |
587 | { |
588 | gDirectory->mkdir(folder); |
589 | gDirectory->cd(folder); |
590 | } |
591 | |
592 | fHistStatistics->Write(); |
593 | fHistBunchCrossing->Write(); |
594 | |
296dd262 |
595 | Int_t count = fCollTrigClasses.GetEntries() + fBGTrigClasses.GetEntries(); |
596 | for (Int_t i=0; i < count; i++) |
597 | { |
598 | TString triggerClass = "trigger_histograms_"; |
599 | if (i < fCollTrigClasses.GetEntries()) |
600 | triggerClass += ((TObjString*) fCollTrigClasses.At(i))->String(); |
601 | else |
602 | triggerClass += ((TObjString*) fBGTrigClasses.At(i - fCollTrigClasses.GetEntries()))->String(); |
61899827 |
603 | |
296dd262 |
604 | gDirectory->mkdir(triggerClass); |
605 | gDirectory->cd(triggerClass); |
61899827 |
606 | |
296dd262 |
607 | static_cast<AliTriggerAnalysis*> (fTriggerAnalysis.At(i))->SaveHistograms(); |
608 | |
609 | gDirectory->cd(".."); |
610 | } |
611 | |
612 | if (fBackgroundIdentification) |
613 | { |
614 | gDirectory->mkdir("background_identification"); |
615 | gDirectory->cd("background_identification"); |
616 | |
617 | fBackgroundIdentification->GetOutput()->Write(); |
618 | |
619 | gDirectory->cd(".."); |
620 | } |
61899827 |
621 | |
622 | if (folder) |
623 | gDirectory->cd(".."); |
624 | } |