]>
Commit | Line | Data |
---|---|---|
0fa651e5 | 1 | /************************************************************************** |
2 | * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * | |
3 | * * | |
4 | * Author: The ALICE Off-line Project. * | |
5 | * Contributors are mentioned in the code where appropriate. * | |
6 | * * | |
7 | * Permission to use, copy, modify and distribute this software and its * | |
8 | * documentation strictly for non-commercial purposes is hereby granted * | |
9 | * without fee, provided that the above copyright notice appears in all * | |
10 | * copies and that both the copyright notice and this permission notice * | |
11 | * appear in the supporting documentation. The authors make no claims * | |
12 | * about the suitability of this software for any purpose. It is * | |
13 | * provided "as is" without express or implied warranty. * | |
14 | **************************************************************************/ | |
15 | ||
27de2dfb | 16 | /* $Id$ */ |
17 | ||
0fa651e5 | 18 | //------------------------------------------------------------------------- |
19 | // Implementation of class AliAnalysisTaskPileup | |
20 | // | |
21 | // The class re-weights the number of analysed events with the correction | |
22 | // factor to account for the event pileup. | |
23 | // | |
24 | // The final idea will be to include all of the methods for the pileup | |
25 | // calculation. | |
26 | // | |
27 | // For the moment, the implemented method is based on a work | |
28 | // by L. Aphecetche. | |
29 | // The probability of having at least 1 collision is given by: | |
30 | // MB L0 trigger / max collision rate | |
31 | // The max collision rate is given by: | |
32 | // number of bunches X revolution frequency ~ CBEAMB L0 trigger | |
33 | // Assuming a poissonian distribution of the collision, with: | |
34 | // mu = mean number of collisions | |
35 | // the probability of having 0 collisions is: | |
36 | // exp{-mu} = 1 - L0b_MB / max collision rate | |
37 | // Since the MB trigger is measuring the probability of having at least | |
38 | // 1 collisions, the number should be corrected by the factor: | |
39 | // CF = mu / ( 1 - exp{-mu} ) | |
40 | // The class weights the number of events with this correction factor | |
41 | // | |
42 | // CAVEATS: | |
43 | // - so far the class needs to access the OCDB | |
44 | // (hopefully it will be changed in the future) | |
45 | // Hence the following libraries need to be included (in addition to | |
46 | // the standard analysis ones): | |
47 | // libRAWDatabase.so libCDB.so libSTEER.so libPWG3base.so | |
48 | //------------------------------------------------------------------------- | |
49 | ||
50 | #include <Riostream.h> | |
51 | ||
52 | // ROOT includes | |
53 | #include "TH1.h" | |
54 | #include "TH2.h" | |
55 | #include "TCanvas.h" | |
56 | #include "TROOT.h" | |
57 | #include "TString.h" | |
58 | #include "TObjArray.h" | |
59 | #include "TObjString.h" | |
60 | #include "TMath.h" | |
61 | ||
62 | // STEER includes | |
63 | #include "AliESDEvent.h" | |
64 | #include "AliESDInputHandler.h" | |
65 | #include "AliAODEvent.h" | |
66 | #include "AliAODInputHandler.h" | |
67 | #include "AliTriggerScalersESD.h" | |
b78b61c2 | 68 | #include "AliCentrality.h" |
0fa651e5 | 69 | |
70 | // ANALYSIS includes | |
71 | #include "AliAnalysisTaskSE.h" | |
72 | #include "AliAnalysisManager.h" | |
73 | #include "AliAnalysisDataSlot.h" | |
74 | #include "AliAnalysisDataContainer.h" | |
75 | ||
76 | #include "AliCounterCollection.h" | |
77 | ||
78 | #include "AliAnalysisTaskPileup.h" | |
79 | ||
80 | #if defined(READOCDB) | |
81 | #include "AliTriggerRunScalers.h" | |
82 | #include "AliTriggerConfiguration.h" | |
83 | #include "AliTriggerClass.h" | |
84 | #include "AliCDBManager.h" | |
85 | #include "AliCDBEntry.h" | |
86 | #include "AliCDBPath.h" | |
87 | #endif | |
88 | ||
89 | ||
90 | ClassImp(AliAnalysisTaskPileup) | |
91 | ||
92 | ||
b78b61c2 | 93 | //________________________________________________________________________ |
94 | AliAnalysisTaskPileup::AliAnalysisTaskPileup() : | |
95 | AliAnalysisTaskSE(), | |
96 | fEventCounters(0x0), | |
97 | fHistoEventsList(0x0), | |
98 | fTriggerClasses(0x0), | |
99 | fTriggerClassIndex(0x0), | |
100 | fIsInitCDB(0), | |
101 | fCentralityClasses(0x0) | |
102 | #if defined(READOCDB) | |
103 | , fTriggerRunScalers(0x0), | |
104 | fStorageList(0x0) | |
105 | #endif | |
106 | ||
107 | { | |
108 | /// Default Constructor | |
109 | } | |
110 | ||
111 | ||
0fa651e5 | 112 | //________________________________________________________________________ |
113 | AliAnalysisTaskPileup::AliAnalysisTaskPileup(const char *name) : | |
114 | AliAnalysisTaskSE(name), | |
115 | fEventCounters(0x0), | |
116 | fHistoEventsList(0x0), | |
117 | fTriggerClasses(0x0), | |
b78b61c2 | 118 | fTriggerClassIndex(0x0), |
119 | fIsInitCDB(0), | |
120 | fCentralityClasses(0x0) | |
0fa651e5 | 121 | #if defined(READOCDB) |
122 | , fTriggerRunScalers(0x0), | |
b78b61c2 | 123 | fStorageList(0x0) |
0fa651e5 | 124 | #endif |
125 | ||
126 | { | |
127 | /// Constructor | |
128 | ||
129 | DefineOutput(1,AliCounterCollection::Class()); | |
130 | DefineOutput(2,TObjArray::Class()); | |
131 | } | |
132 | ||
133 | //________________________________________________________________________ | |
134 | AliAnalysisTaskPileup::~AliAnalysisTaskPileup() | |
135 | { | |
136 | /// Destructor | |
c705eb52 | 137 | |
138 | // For proof: do not delete output containers | |
139 | if ( ! AliAnalysisManager::GetAnalysisManager()->IsProofMode() ) { | |
140 | delete fEventCounters; | |
141 | } | |
142 | ||
0fa651e5 | 143 | delete fHistoEventsList; |
144 | delete fTriggerClasses; | |
145 | delete fTriggerClassIndex; | |
146 | ||
147 | #if defined(READOCDB) | |
91ff2fb3 | 148 | //delete fTriggerRunScalers; // Not owner -> Owned by OCDB |
b78b61c2 | 149 | delete fStorageList; |
0fa651e5 | 150 | #endif |
151 | ||
152 | } | |
153 | ||
154 | ||
155 | //___________________________________________________________________________ | |
156 | void AliAnalysisTaskPileup::NotifyRun() | |
157 | { | |
158 | /// Notify run | |
159 | ||
160 | #if defined(READOCDB) | |
b78b61c2 | 161 | fStorageList->Compress(); |
0fa651e5 | 162 | if ( ! AliCDBManager::Instance()->GetDefaultStorage() ) { |
b78b61c2 | 163 | for ( Int_t ientry=0; ientry<fStorageList->GetEntries(); ientry++ ) { |
164 | TObjString* calibStr = (TObjString*)fStorageList->At(ientry); | |
165 | ientry++; | |
166 | TObjString* dbStr = (TObjString*)fStorageList->At(ientry); | |
167 | TString calibName = calibStr->GetString(); | |
168 | if ( ! calibName.CompareTo("default") ) { | |
169 | AliCDBManager::Instance()->SetDefaultStorage(dbStr->GetName()); | |
170 | } | |
171 | else { | |
172 | AliCDBManager::Instance()->SetSpecificStorage(calibStr->GetName(), dbStr->GetName()); | |
173 | } | |
174 | } | |
0fa651e5 | 175 | } |
176 | ||
b78b61c2 | 177 | // Default storage was not correclty set: nothing done |
178 | if ( ! AliCDBManager::Instance()->GetDefaultStorage() ) return; | |
179 | ||
0fa651e5 | 180 | AliCDBManager::Instance()->SetRun(InputEvent()->GetRunNumber()); |
181 | ||
182 | AliCDBEntry *entry = 0x0; | |
183 | entry = AliCDBManager::Instance()->Get("GRP/CTP/Config"); | |
b78b61c2 | 184 | if ( ! entry ) return; |
185 | AliTriggerConfiguration* trigConf = (AliTriggerConfiguration*)entry->GetObject(); | |
186 | const TObjArray& classesArray = trigConf->GetClasses(); | |
187 | Int_t nclasses = classesArray.GetEntriesFast(); | |
188 | ||
189 | if ( fTriggerClasses ) delete fTriggerClasses; | |
190 | ||
191 | fTriggerClasses = new TObjArray(nclasses); | |
192 | fTriggerClasses->SetOwner(); | |
193 | ||
194 | Int_t currActive = -1; | |
195 | for( Int_t iclass=0; iclass < nclasses; iclass++ ) { | |
196 | AliTriggerClass* trclass = (AliTriggerClass*)classesArray.At(iclass); | |
197 | if (trclass && trclass->GetMask()>0) { | |
198 | currActive++; | |
199 | Int_t currPos = currActive; | |
200 | ||
201 | // Store the CBEAMB class at the first position | |
202 | TString trigName = trclass->GetName(); | |
203 | if ( ( trigName.Contains("CBEAMB") || trigName.Contains("CTRUE") ) && ! trigName.Contains("WU") ) | |
204 | currPos = 0; | |
205 | else if ( ! fTriggerClasses->At(0) ) | |
206 | currPos++; | |
207 | ||
208 | Int_t trindex = TMath::Nint(TMath::Log2(trclass->GetMask())); | |
209 | TObjString* objString = new TObjString(trigName.Data()); | |
210 | fTriggerClasses->AddAtAndExpand(objString, currPos); | |
211 | (*fTriggerClassIndex)[currPos] = trindex; | |
212 | if ( fDebug >= 3 ) printf("AliAnalysisTaskPileup: Current class %s index %i position %i\n", trigName.Data(), trindex, currPos); | |
213 | } // is class active | |
214 | } // loop on trigger classes | |
0fa651e5 | 215 | |
b78b61c2 | 216 | entry = AliCDBManager::Instance()->Get("GRP/CTP/Scalers"); |
217 | if ( ! entry ) return; | |
218 | AliInfo("Found an AliTriggerRunScalers in GRP/CTP/Scalers, reading it"); | |
91ff2fb3 | 219 | fTriggerRunScalers = static_cast<AliTriggerRunScalers*> (entry->GetObject()); |
b78b61c2 | 220 | if (fTriggerRunScalers->CorrectScalersOverflow() == 0) AliInfo("32bit Trigger counters corrected for overflow"); |
0fa651e5 | 221 | |
b78b61c2 | 222 | fIsInitCDB = kTRUE; |
0fa651e5 | 223 | |
0fa651e5 | 224 | #endif |
225 | ||
226 | } | |
227 | ||
228 | ||
229 | //___________________________________________________________________________ | |
230 | void AliAnalysisTaskPileup::UserCreateOutputObjects() | |
231 | { | |
232 | /// Create histograms and counters | |
b78b61c2 | 233 | |
234 | fTriggerClassIndex = new TArrayI(50); | |
235 | fTriggerClassIndex->Reset(-1); | |
236 | ||
237 | fCentralityClasses = new TAxis(20, 0., 100.); | |
238 | ||
239 | TString centralityClassesStr = "", currClass = ""; | |
240 | for ( Int_t ibin=1; ibin<=fCentralityClasses->GetNbins(); ibin++ ){ | |
241 | if ( ! centralityClassesStr.IsNull() ) | |
242 | centralityClassesStr.Append("/"); | |
243 | currClass = Form("%.0f-%.0f",fCentralityClasses->GetBinLowEdge(ibin),fCentralityClasses->GetBinUpEdge(ibin)); | |
244 | centralityClassesStr += currClass; | |
245 | fCentralityClasses->SetBinLabel(ibin, currClass.Data()); | |
246 | } | |
0fa651e5 | 247 | |
248 | // The framework has problems if the name of the object | |
249 | // and the one of container differ | |
250 | // To be complaint, get the name from container and set it | |
251 | TString containerName = GetOutputSlot(1)->GetContainer()->GetName(); | |
252 | ||
253 | // initialize event counters | |
254 | fEventCounters = new AliCounterCollection(containerName.Data()); | |
255 | fEventCounters->AddRubric("event", "any/correctedL0"); | |
256 | fEventCounters->AddRubric("trigger", 1000000); | |
c705eb52 | 257 | fEventCounters->AddRubric("vtxSelection", "any/hasVtxContrib/nonPileupSPD"); |
258 | fEventCounters->AddRubric("selected", "yes/no"); | |
b78b61c2 | 259 | fEventCounters->AddRubric("centrality", centralityClassesStr.Data()); |
0fa651e5 | 260 | fEventCounters->Init(kTRUE); |
261 | ||
262 | // Post data at least once per task to ensure data synchronisation (required for merging) | |
263 | PostData(1, fEventCounters); | |
264 | } | |
265 | ||
266 | //________________________________________________________________________ | |
267 | void AliAnalysisTaskPileup::UserExec(Option_t *) | |
268 | { | |
269 | /// Called for each event | |
270 | ||
271 | AliAODEvent* aodEvent = 0x0; | |
272 | ||
273 | AliESDEvent* esdEvent = dynamic_cast<AliESDEvent*> (InputEvent()); | |
274 | if ( ! esdEvent ) { | |
275 | aodEvent = dynamic_cast<AliAODEvent*> (InputEvent()); | |
276 | } | |
277 | ||
278 | if ( ! aodEvent && ! esdEvent ) { | |
279 | AliError ("AOD or ESD event not found. Nothing done!"); | |
280 | return; | |
281 | } | |
282 | ||
283 | // check physics selection | |
c705eb52 | 284 | Bool_t isPhysicsSelected = (fInputHandler && fInputHandler->IsEventSelected()); |
285 | TString selected = ( isPhysicsSelected ) ? "yes" : "no"; | |
0fa651e5 | 286 | |
0fa651e5 | 287 | TString firedTrigClasses = ( esdEvent ) ? esdEvent->GetFiredTriggerClasses() : aodEvent->GetFiredTriggerClasses(); |
288 | ||
b78b61c2 | 289 | if ( ! fIsInitCDB ) { |
290 | delete fTriggerClasses; | |
291 | fTriggerClasses = firedTrigClasses.Tokenize(" "); | |
292 | fTriggerClasses->SetOwner(); | |
293 | } | |
294 | ||
295 | #if defined(READOCDB) | |
0fa651e5 | 296 | |
b78b61c2 | 297 | //if ( firedTrigClasses.IsNull() ) return; // Reject non-physics events |
0fa651e5 | 298 | |
b78b61c2 | 299 | if ( fDebug >= 2 ) printf("\nAliAnalysisTaskPileup: Event %lli\n", Entry()); |
300 | ||
301 | // If scalers is not correctly loaded, the task becomes a mere event counter | |
302 | Int_t nPoints = ( fTriggerRunScalers ) ? fTriggerRunScalers->GetScalersRecordsESD()->GetEntriesFast() : 0; | |
0fa651e5 | 303 | |
c705eb52 | 304 | AliTriggerScalersRecordESD* trigScalerRecords1 = 0x0; |
0fa651e5 | 305 | AliTriggerScalersRecordESD* trigScalerRecords2 = 0x0; |
c705eb52 | 306 | if ( nPoints > 1 ) { |
b78b61c2 | 307 | // Add protection for MC (no scalers there!) |
c705eb52 | 308 | |
309 | AliTimeStamp timeStamp(InputEvent()->GetOrbitNumber(), InputEvent()->GetPeriodNumber(), InputEvent()->GetBunchCrossNumber()); | |
310 | Int_t position = fTriggerRunScalers->FindNearestScalersRecord(&timeStamp); | |
311 | if ( position < 0 ) { | |
312 | AliWarning("Position out of range: put to 1"); | |
313 | position = 1; | |
314 | } | |
315 | if ( position == 0 ) position++; // Don't trust the first one | |
316 | else if ( position + 1 >= nPoints ) position--; | |
b78b61c2 | 317 | if ( fDebug >= 2 ) printf("AliAnalysisTaskPileup: position %i\n", position); |
c705eb52 | 318 | trigScalerRecords1 = (AliTriggerScalersRecordESD*)fTriggerRunScalers->GetScalersRecordsESD()->At(position); |
319 | ||
320 | // Sometimes scalers are filled very close to each others | |
321 | // in this case skip to the next entry | |
322 | for ( Int_t ipos=position+1; ipos<nPoints; ipos++ ) { | |
323 | trigScalerRecords2 = (AliTriggerScalersRecordESD*)fTriggerRunScalers->GetScalersRecordsESD()->At(ipos); | |
324 | Double_t deltaTime = (Double_t)( trigScalerRecords2->GetTimeStamp()->GetSeconds() - trigScalerRecords1->GetTimeStamp()->GetSeconds() ); | |
b78b61c2 | 325 | if ( fDebug >= 2 ) printf("AliAnalysisTaskPileup: Pos %i TimeStamp %u - %u = %.0f\n", ipos, trigScalerRecords2->GetTimeStamp()->GetSeconds(), trigScalerRecords1->GetTimeStamp()->GetSeconds(), deltaTime); |
c705eb52 | 326 | |
327 | if ( deltaTime > 1 ) | |
328 | break; | |
329 | } // loop on position | |
330 | } // nPoins > 0 | |
0fa651e5 | 331 | |
332 | #endif | |
333 | ||
334 | ULong64_t trigMask = 0; | |
335 | Double_t correctFactor = 1.; | |
336 | ||
337 | Int_t nVtxContrib = ( esdEvent ) ? esdEvent->GetPrimaryVertex()->GetNContributors() : aodEvent->GetPrimaryVertex()->GetNContributors(); | |
338 | Bool_t isPileupSPD = ( esdEvent ) ? esdEvent->IsPileupFromSPD(3,0.8) : aodEvent->IsPileupFromSPD(3,0.8); | |
339 | ||
b78b61c2 | 340 | Double_t centralityClass = InputEvent()->GetCentrality()->GetCentralityPercentile("V0M"); |
341 | // If percentile is exactly 100. the bin chosen is in overflow | |
342 | // fix it by setting 99.999 instead of 100. | |
343 | if ( centralityClass >= 100. ) centralityClass = 99.999; | |
344 | Int_t centralityBin = fCentralityClasses->FindBin(centralityClass); | |
345 | ||
c705eb52 | 346 | TString vtxSelKey[3] = {"any","hasVtxContrib","nonPileupSPD"}; |
0fa651e5 | 347 | Bool_t fillSel[3] = {kTRUE, ( nVtxContrib > 0 ), ( ( nVtxContrib > 0 ) && ( ! isPileupSPD ) )}; |
348 | ||
349 | //const AliTriggerScalersRecordESD* trigScalerRecords = esdEvent->GetHeader()->GetTriggerScalersRecord(); // REMEMBER TO CUT | |
350 | ||
351 | TString trigName = ""; | |
352 | TString eventType = ""; | |
353 | ||
b78b61c2 | 354 | // Get entries counts the number of entries != 0 |
355 | // However the position 0 can be empty in MC (it is reserved to CBEAMB) | |
356 | // In this case with GetEntries the last entry is lost | |
357 | // Use GetEntriesFast instead | |
358 | Int_t nTriggerClasses = fTriggerClasses->GetEntriesFast(); | |
0fa651e5 | 359 | Int_t classIndex = -1; |
b78b61c2 | 360 | #if defined(READOCDB) |
0fa651e5 | 361 | Double_t deltaScalersBeam = 0., deltaScalers = 0.; |
b78b61c2 | 362 | #endif |
91ff2fb3 | 363 | //Bool_t isFiredOnce = kFALSE; |
0fa651e5 | 364 | for (Int_t itrig=0; itrig<nTriggerClasses+1; itrig++) { |
365 | ||
366 | Double_t correctFactorL0 = 1.; | |
367 | ||
368 | Bool_t isClassFired = kFALSE; | |
369 | ||
370 | if ( itrig < nTriggerClasses ) { | |
371 | ||
b78b61c2 | 372 | if ( fIsInitCDB ) { |
373 | // Check if current mask contains trigger | |
374 | classIndex = (*fTriggerClassIndex)[itrig]; | |
375 | if ( classIndex < 0 ) continue; // Protection for MC (where BEAMB not present | |
376 | trigMask = ( 1ull << classIndex ); | |
377 | isClassFired = ( trigMask & InputEvent()->GetTriggerMask() ); | |
378 | } | |
379 | else | |
380 | isClassFired = kTRUE; | |
381 | ||
c705eb52 | 382 | trigName = ((TObjString*)fTriggerClasses->At(itrig))->GetString(); |
0fa651e5 | 383 | |
c705eb52 | 384 | #if defined(READOCDB) |
385 | if ( trigScalerRecords2 && ( isClassFired || itrig == 0 ) ) { | |
0fa651e5 | 386 | // Get scalers |
387 | const AliTriggerScalersESD* scaler1 = trigScalerRecords1->GetTriggerScalersForClass(classIndex+1); | |
388 | const AliTriggerScalersESD* scaler2 = trigScalerRecords2->GetTriggerScalersForClass(classIndex+1); | |
389 | deltaScalers = scaler2->GetLOCB() - scaler1->GetLOCB(); | |
c705eb52 | 390 | |
0fa651e5 | 391 | if ( itrig == 0 ) |
392 | deltaScalersBeam = deltaScalers; | |
393 | else if ( isClassFired ) { | |
394 | correctFactorL0 = GetL0Correction(deltaScalers, deltaScalersBeam); | |
b78b61c2 | 395 | if ( fDebug >= 2 ) printf("AliAnalysisTaskPileup: Scalers: %s %.0f %s %.0f -> CF %f\n", fTriggerClasses->At(itrig)->GetName(), deltaScalers, fTriggerClasses->At(0)->GetName(), deltaScalersBeam, correctFactorL0); |
0fa651e5 | 396 | } |
397 | } | |
c705eb52 | 398 | #endif |
399 | } // if ( itrig < nTriggerClasses ) | |
0fa651e5 | 400 | else { |
0fa651e5 | 401 | classIndex = -1; |
c705eb52 | 402 | trigName = "any"; |
91ff2fb3 | 403 | isClassFired = kTRUE; // isFiredOnce; |
0fa651e5 | 404 | } |
405 | ||
406 | if ( ! isClassFired ) continue; | |
91ff2fb3 | 407 | //isFiredOnce = kTRUE; |
0fa651e5 | 408 | |
409 | //const AliTriggerScalersESD* trigScaler = trigScalerRecords->GetTriggerScalersForClass(classIndex+1); // REMEMBER TO CUT | |
410 | //if ( classIndex > 1 ) printf("Index: trigger %i scaler %i\n", classIndex+1, trigScaler->GetClassIndex()); // REMEMBER TO CUT | |
411 | ||
b78b61c2 | 412 | if ( fDebug >= 2 ) printf("AliAnalysisTaskPileup: Fired trig %s\n", trigName.Data()); |
0fa651e5 | 413 | |
414 | for ( Int_t ievType=0; ievType<2; ievType++ ){ | |
415 | switch ( ievType ) { | |
0fa651e5 | 416 | case kHeventsCorrectL0: |
417 | correctFactor = correctFactorL0; | |
418 | eventType = "correctedL0"; | |
419 | break; | |
0fa651e5 | 420 | default: |
421 | correctFactor = 1.; | |
422 | eventType = "any"; | |
b78b61c2 | 423 | break; |
0fa651e5 | 424 | } |
425 | ||
426 | for ( Int_t isel=0; isel<3; isel++ ) { | |
427 | if ( ! fillSel[isel] ) continue; | |
b78b61c2 | 428 | fEventCounters->Count(Form("event:%s/trigger:%s/vtxSelection:%s/selected:%s/centrality:%s",eventType.Data(),trigName.Data(), vtxSelKey[isel].Data(), selected.Data(),fCentralityClasses->GetBinLabel(centralityBin)),correctFactor); |
0fa651e5 | 429 | } // loop on vertex selection |
430 | } // loop on event type | |
431 | } // loop on trigger classes | |
432 | ||
433 | // Post final data. It will be written to a file with option "RECREATE" | |
434 | PostData(1, fEventCounters); | |
435 | } | |
436 | ||
437 | ||
438 | //________________________________________________________________________ | |
439 | void AliAnalysisTaskPileup::Terminate(Option_t *) | |
440 | { | |
441 | // | |
442 | /// Save final histograms | |
443 | /// and draw result to the screen | |
444 | // | |
445 | ||
c705eb52 | 446 | // Fill the container only at the very last step |
447 | // i.e. in local, when done interactively | |
448 | if ( gROOT->IsBatch() ) | |
449 | return; | |
450 | ||
0fa651e5 | 451 | fEventCounters = dynamic_cast<AliCounterCollection*>(GetOutputData(1)); |
452 | if ( ! fEventCounters ) return; | |
453 | ||
c705eb52 | 454 | if ( ! fHistoEventsList ) fHistoEventsList = new TObjArray(0); |
0fa651e5 | 455 | fHistoEventsList->SetOwner(); |
456 | ||
457 | TH2D* histo = 0x0; | |
c705eb52 | 458 | const Int_t kNevtTypes = 2; |
459 | TString evtSel[kNevtTypes] = {"event:any", "event:correctedL0"}; | |
460 | TString evtName[kNevtTypes] = {"", "CorrectL0"}; | |
461 | TString evtTitle[kNevtTypes] = {"Events", "L0 corrected events"}; | |
462 | const Int_t kNphysSel = 2; | |
463 | TString physSel[kNphysSel] = {"selected:any","selected:yes"}; | |
464 | TString physName[kNphysSel] = {"", "PhysSel"}; | |
465 | TString physTitle[kNphysSel] = {"", "w/ physics selection"}; | |
466 | ||
b78b61c2 | 467 | TString typeName[2] = {"", "Centrality"}; |
468 | ||
c705eb52 | 469 | Int_t currHisto = -1; |
470 | TString currName = ""; | |
b78b61c2 | 471 | for ( Int_t itype=0; itype<2; itype++ ) { |
472 | for ( Int_t isel=0; isel<kNphysSel; isel++ ) { | |
473 | for ( Int_t iev=0; iev<kNevtTypes; iev++ ) { | |
474 | currName = Form("%s/%s", evtSel[iev].Data(), physSel[isel].Data()); | |
475 | if ( itype == 0 ) | |
476 | histo = fEventCounters->Get("trigger","vtxSelection",currName.Data()); | |
477 | else { | |
478 | currName.Append("/vtxSelection:any"); | |
479 | histo = fEventCounters->Get("trigger","centrality",currName.Data()); | |
480 | } | |
481 | if ( ! histo ) continue; | |
482 | currHisto++; | |
483 | currName = Form("hEvents%s%s%s", typeName[itype].Data(), evtName[iev].Data(), physName[isel].Data()); | |
484 | histo->SetName(currName.Data()); | |
485 | currName = Form("%s %s", evtTitle[iev].Data(), physTitle[isel].Data()); | |
486 | histo->SetTitle(currName.Data()); | |
487 | fHistoEventsList->AddAtAndExpand(histo, currHisto); | |
488 | } // loop on event type | |
489 | TH2D* num = (TH2D*)fHistoEventsList->At(currHisto); | |
490 | TH2D* den = (TH2D*)fHistoEventsList->At(currHisto-1); | |
491 | if ( ! num || ! den ) continue; | |
492 | currName = Form("hPileupL0%s%s_%s", typeName[itype].Data(), physName[isel].Data(), GetName()); | |
493 | TH2D* histoPileupL0 = (TH2D*)num->Clone(currName.Data()); | |
494 | histoPileupL0->Divide(den); | |
495 | currName.ReplaceAll("hPileupL0","canPileupL0"); | |
496 | TCanvas *can = new TCanvas(currName.Data(),"Pileup",10,10,310,310); | |
497 | can->SetFillColor(10); can->SetHighLightColor(10); | |
498 | can->SetLeftMargin(0.15); can->SetBottomMargin(0.15); | |
499 | histoPileupL0->DrawCopy("text"); | |
500 | delete histoPileupL0; | |
501 | } // loop on physics selection | |
502 | } // loop on histo type | |
0fa651e5 | 503 | |
504 | PostData(2, fHistoEventsList); | |
0fa651e5 | 505 | } |
506 | ||
507 | ||
508 | //________________________________________________________________________ | |
509 | Double_t AliAnalysisTaskPileup::GetL0Correction(Double_t nCINT1B, Double_t nCBEAMB) | |
510 | { | |
511 | /// Get the correction factor for L0 calculation | |
512 | ||
513 | if ( nCBEAMB == 0. ) | |
514 | return 1.; | |
515 | ||
516 | Double_t ratio = nCINT1B / nCBEAMB; | |
517 | ||
518 | if ( ratio >= 1. || ratio == 0. ) | |
519 | return 1.; | |
520 | ||
521 | Double_t mu = -TMath::Log(1-ratio); | |
522 | ||
523 | return mu / ( 1. - TMath::Exp(-mu) ); | |
524 | ||
525 | } | |
b78b61c2 | 526 | |
527 | //________________________________________________________________________ | |
528 | void AliAnalysisTaskPileup::SetDefaultStorage(TString dbString) | |
529 | { | |
530 | /// Set default storage | |
531 | SetSpecificStorage("default", dbString); | |
532 | } | |
533 | ||
534 | ||
535 | //________________________________________________________________________ | |
536 | void AliAnalysisTaskPileup::SetSpecificStorage(TString calibType, TString dbString) | |
537 | { | |
538 | /// Set specific storage | |
539 | #if defined(READOCDB) | |
540 | if ( ! fStorageList ) { | |
541 | fStorageList = new TObjArray(5); | |
542 | fStorageList->SetOwner(); | |
543 | } | |
544 | fStorageList->AddLast(new TObjString(calibType)); | |
545 | fStorageList->AddLast(new TObjString(dbString)); | |
546 | #else | |
547 | calibType = ""; | |
548 | dbString = ""; | |
549 | AliWarning(Form("Class was not compiled to run on OCDB. Command will not have effect")); | |
550 | #endif | |
551 | } | |
552 |