1 /*************************************************************************
2 * Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
16 ///////////////////////////////////////////////////////////////////////////
18 // Basic Analysis Task //
20 ///////////////////////////////////////////////////////////////////////////
25 #include <AliCFContainer.h>
26 #include <AliInputEventHandler.h>
27 #include <AliESDInputHandler.h>
28 #include <AliAODInputHandler.h>
29 #include <AliAnalysisManager.h>
30 #include <AliVEvent.h>
31 #include <AliTriggerAnalysis.h>
32 #include <AliPIDResponse.h>
33 #include <AliTPCPIDResponse.h>
35 #include "AliDielectron.h"
36 #include "AliDielectronHistos.h"
37 #include "AliDielectronCF.h"
38 #include "AliDielectronMC.h"
39 #include "AliDielectronMixingHandler.h"
40 #include "AliAnalysisTaskMultiDielectronTG.h"
42 #include "AliESDtrack.h"
43 #include "AliESDtrackCuts.h"
55 const char* kPairClassNamesTG[7] = {
66 ClassImp(AliDielectronSingleTG)
67 ClassImp(AliAnalysisTaskMultiDielectronTG)
69 //_________________________________________________________________________________
70 AliAnalysisTaskMultiDielectronTG::AliAnalysisTaskMultiDielectronTG() :
76 fSelectPhysics(kFALSE),
77 fTriggerMask(AliVEvent::kMB),
78 fExcludeTriggerMask(0),
79 fTriggerOnV0AND(kFALSE),
80 fRejectPileup(kFALSE),
82 fTriggerAnalysis(0x0),
88 fdEdXnSigmaElecvsPt(0x0),
90 fdEdXnSigmaElecvsPtTOF(0x0),
92 fTOFnSigmaElecvsPt(0x0),
93 fNCrossedRowsTPC(0x0),
95 fRatioCrossClusTPC(0x0),
100 fdconvphiv(acos(-1.0)),
105 fBGRejUnlike(kFALSE),
113 //_________________________________________________________________________________
114 AliAnalysisTaskMultiDielectronTG::AliAnalysisTaskMultiDielectronTG(const char *name) :
115 AliAnalysisTaskSE(name),
120 fSelectPhysics(kFALSE),
121 fTriggerMask(AliVEvent::kMB),
122 fExcludeTriggerMask(0),
123 fTriggerOnV0AND(kFALSE),
124 fRejectPileup(kFALSE),
126 fTriggerAnalysis(0x0),
132 fdEdXnSigmaElecvsPt(0x0),
134 fdEdXnSigmaElecvsPtTOF(0x0),
136 fTOFnSigmaElecvsPt(0x0),
137 fNCrossedRowsTPC(0x0),
139 fRatioCrossClusTPC(0x0),
144 fdconvphiv(acos(-1.0)),
149 fBGRejUnlike(kFALSE),
155 DefineInput(0,TChain::Class());
156 DefineOutput(1, TList::Class());
157 DefineOutput(2, TList::Class());
158 DefineOutput(3, TH1D::Class());
159 fListHistos.SetName("Dielectron_Histos_Multi");
160 fListCF.SetName("Dielectron_CF_Multi");
161 fListDielectron.SetOwner();
162 fListHistos.SetOwner();
166 for(int i=0;i<fgkNDIE; i++){
167 for(int j=0;j<fgkNZBIN;j++){
168 for(int k=0;k<fgkNCENT;k++){
169 for(int l=0; l<fgkNRPBIN; l++){
170 fibuf[i][j][k][l] = 0;
171 fpoolp[i][j][k][l].clear();
172 fpoolm[i][j][k][l].clear();
173 for(int ib=0;ib<fgkNBUF; ib++){
174 fvep[ib][i][j][k][l].clear();
175 fvem[ib][i][j][k][l].clear();
186 //_________________________________________________________________________________
187 AliAnalysisTaskMultiDielectronTG::~AliAnalysisTaskMultiDielectronTG()
193 //histograms and CF are owned by the dielectron framework.
194 //however they are streamed to file, so in the first place the
195 //lists need to be owner...
196 fListHistos.SetOwner(kFALSE);
197 fListCF.SetOwner(kFALSE);
199 for(int i=0;i<fgkNDIE; i++){
200 for(int j=0;j<fgkNZBIN;j++){
201 for(int k=0;k<fgkNCENT;k++){
202 for(int l=0; l<fgkNRPBIN; l++){
203 fibuf[i][j][k][l] = 0;
204 fpoolp[i][j][k][l].clear();
205 fpoolm[i][j][k][l].clear();
206 for(int ib=0;ib<fgkNBUF; ib++){
207 fvep[ib][i][j][k][l].clear();
208 fvem[ib][i][j][k][l].clear();
215 //_________________________________________________________________________________
216 void AliAnalysisTaskMultiDielectronTG::UserCreateOutputObjects()
219 // Add all histogram manager histogram lists to the output TList
222 if (!fListHistos.IsEmpty()||!fListCF.IsEmpty()) return; //already initialised
224 // AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();
225 // Bool_t isESD=man->GetInputEventHandler()->IsA()==AliESDInputHandler::Class();
226 // Bool_t isAOD=man->GetInputEventHandler()->IsA()==AliAODInputHandler::Class();
228 TIter nextDie(&fListDielectron);
229 AliDielectron *die=0;
230 while ( (die=static_cast<AliDielectron*>(nextDie())) ){
232 if (die->GetHistogramList()) fListHistos.Add(const_cast<THashList*>(die->GetHistogramList()));
233 if (die->GetCFManagerPair()) fListCF.Add(const_cast<AliCFContainer*>(die->GetCFManagerPair()->GetContainer()));
236 Int_t cuts=fListDielectron.GetEntries();
237 Int_t nbins=kNbinsEvent+2*cuts;
239 fEventStat=new TH1D("hEventStat","Event statistics",nbins,0,nbins);
240 fEventStat->GetXaxis()->SetBinLabel(1,"Before Phys. Sel.");
241 fEventStat->GetXaxis()->SetBinLabel(2,"After Phys. Sel.");
244 fEventStat->GetXaxis()->SetBinLabel(3,"Bin3 not used");
245 fEventStat->GetXaxis()->SetBinLabel(4,"Bin4 not used");
246 fEventStat->GetXaxis()->SetBinLabel(5,"Bin5 not used");
248 if(fTriggerOnV0AND) fEventStat->GetXaxis()->SetBinLabel(3,"V0and triggers");
249 if (fEventFilter) fEventStat->GetXaxis()->SetBinLabel(4,"After Event Filter");
250 if (fRejectPileup) fEventStat->GetXaxis()->SetBinLabel(5,"After Pileup rejection");
252 for (Int_t i=0; i<cuts; ++i){
253 fEventStat->GetXaxis()->SetBinLabel((kNbinsEvent+1)+2*i,Form("#splitline{1 candidate}{%s}",fListDielectron.At(i)->GetName()));
254 fEventStat->GetXaxis()->SetBinLabel((kNbinsEvent+2)+2*i,Form("#splitline{With >1 candidate}{%s}",fListDielectron.At(i)->GetName()));
258 if (!fTriggerAnalysis) fTriggerAnalysis=new AliTriggerAnalysis;
259 fTriggerAnalysis->EnableHistograms();
260 fTriggerAnalysis->SetAnalyzeMC(AliDielectronMC::Instance()->HasMC());
267 float binw = (TMath::Log(maxx)-TMath::Log(minx))/nbinx;
269 for(int ii=0;ii<nbinx+1;ii++){
270 xbin[ii] = TMath::Exp(TMath::Log(minx) + 0.5*binw+binw*ii);
274 fQAElectron = new TList();
275 fQAElectron->SetName("QAElectron");
276 fQAElectron->SetOwner();
279 fEvent = new TH1D("Event","centrality", 100,0,100);
280 fQAElectron->Add(fEvent);
281 fdEdXvsPt = new TH2D("dEdXvsPt","dE/dX vs. PT of TPC", nbinx, xbin, 2000,0,200);
282 fQAElectron->Add(fdEdXvsPt);
283 fdEdXnSigmaElecvsPt = new TH2D("fdEdXnSigmaElecvsPt"," dE/dX normalized to electron vs. pT of TPC",
284 nbinx, xbin, 2000, -10, 10);
285 fQAElectron->Add(fdEdXnSigmaElecvsPt);
287 fdEdXvsPtTOF = new TH2D("dEdXvsPtTOF","dE/dX vs. PT of TPC", nbinx, xbin, 2000,0,200);
288 fQAElectron->Add(fdEdXvsPtTOF);
289 fdEdXnSigmaElecvsPtTOF = new TH2D("fdEdXnSigmaElecvsPtTOF"," dE/dX normalized to electron vs. pT of TPC",
290 nbinx, xbin, 2000, -10, 10);
291 fQAElectron->Add(fdEdXnSigmaElecvsPtTOF);
295 fTOFbetavsPt = new TH2D("fTOFbetavsPt","TOF beta vs. p", 400, 0, 20, 1200, 0, 1.2);
296 fQAElectron->Add(fTOFbetavsPt);
297 fTOFnSigmaElecvsPt = new TH2D("fTOFnSigmaElecvsPt","TOF nsigma for electron", 400, 0, 20, 2000, -10, 10);
298 fQAElectron->Add(fTOFnSigmaElecvsPt);
300 fNCrossedRowsTPC = new TH2F("fNCrossedRowsTPC", "TPC nCrossed Rows vs. pT", 200, 0, 20, 200, 0, 200);
301 fQAElectron->Add(fNCrossedRowsTPC);
302 fChi2ClusTPC = new TH2F("fChi2ClusTPC", "hChi2ClusTPC vs. pT", 200, 0, 20, 200, 0, 10);
303 fQAElectron->Add(fChi2ClusTPC);
305 fRatioCrossClusTPC = new TH2F("fRatioCrossClusTPC", "hRatioCrossClusTPC vs. pT", 200, 0, 20, 200, 0, 10);
306 fQAElectron->Add(fRatioCrossClusTPC);
308 fListHistos.Add(fQAElectron);
310 fListHistos.SetOwner();
312 PostData(1, &fListHistos);
313 PostData(2, &fListCF);
314 PostData(3, fEventStat);
316 fCutsMother = new AliESDtrackCuts;
317 fCutsMother->SetDCAToVertex2D(kTRUE);
318 fCutsMother->SetMaxDCAToVertexZ(3.0);
319 fCutsMother->SetMaxDCAToVertexXY(1.0);
320 fCutsMother->SetPtRange( 0.05 , 200.0);
321 fCutsMother->SetEtaRange( -0.84 , 0.84 );
322 fCutsMother->SetAcceptKinkDaughters(kFALSE);
323 fCutsMother->SetRequireITSRefit(kTRUE);
324 fCutsMother->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kFirst);
325 fCutsMother->SetMinNClustersITS(3);
326 fCutsMother->SetRequireTPCRefit(kTRUE);
329 AliInfo(Form("PairCutType = %d %d %d %d %d",
334 fRejectPairFlag[4]));
338 //_________________________________________________________________________________
339 void AliAnalysisTaskMultiDielectronTG::UserExec(Option_t *)
342 // Main loop. Called for every event
345 if (fListHistos.IsEmpty()&&fListCF.IsEmpty()) return;
347 AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();
348 Bool_t isESD=man->GetInputEventHandler()->IsA()==AliESDInputHandler::Class();
349 Bool_t isAOD=man->GetInputEventHandler()->IsA()==AliAODInputHandler::Class();
351 AliInputEventHandler* inputHandler = (AliInputEventHandler*) (man->GetInputEventHandler());
352 if (!inputHandler) return;
354 // AliPIDResponse *pidRes=inputHandler->GetPIDResponse();
355 if ( inputHandler->GetPIDResponse() ){
356 // for the 2.76 pass2 MC private train. Together with a sigma shift of -0.169
357 // pidRes->GetTPCResponse().SetSigma(4.637e-3,2.41332105409873257e+04);
358 AliDielectronVarManager::SetPIDResponse( inputHandler->GetPIDResponse() );
360 AliFatal("This task needs the PID response attached to the input event handler!");
363 // Was event selected ?
364 ULong64_t isSelected = AliVEvent::kAny;
365 Bool_t isRejected = kFALSE;
366 if( fSelectPhysics && inputHandler){
367 if((isESD && inputHandler->GetEventSelection()) || isAOD){
368 isSelected = inputHandler->IsEventSelected();
369 if (fExcludeTriggerMask && (isSelected&fExcludeTriggerMask)) isRejected=kTRUE;
370 if (fTriggerLogic==kAny) isSelected&=fTriggerMask;
371 else if (fTriggerLogic==kExact) isSelected=((isSelected&fTriggerMask)==fTriggerMask);
376 //Before physics selection
377 fEventStat->Fill(kAllEvents);
378 if (isSelected==0||isRejected) {
379 PostData(3,fEventStat);
382 //after physics selection
383 fEventStat->Fill(kSelectedEvents);
387 if(isESD){if (!fTriggerAnalysis->IsOfflineTriggerFired(static_cast<AliESDEvent*>(InputEvent()), AliTriggerAnalysis::kV0AND))
389 if(isAOD){if(!((static_cast<AliAODEvent*>(InputEvent()))->GetVZEROData()->GetV0ADecision() == AliVVZERO::kV0BB &&
390 (static_cast<AliAODEvent*>(InputEvent()))->GetVZEROData()->GetV0CDecision() == AliVVZERO::kV0BB) )
395 fEventStat->Fill(kV0andEvents);
397 //Fill Event histograms before the event filter
398 TIter nextDie(&fListDielectron);
399 AliDielectron *die=0;
400 Double_t values[AliDielectronVarManager::kNMaxValues]={0};
401 Double_t valuesMC[AliDielectronVarManager::kNMaxValues]={0};
402 AliDielectronVarManager::SetEvent(InputEvent());
403 AliDielectronVarManager::Fill(InputEvent(),values);
404 AliDielectronVarManager::Fill(InputEvent(),valuesMC);
405 Bool_t hasMC=AliDielectronMC::Instance()->HasMC();
407 if (AliDielectronMC::Instance()->ConnectMCEvent())
408 AliDielectronVarManager::Fill(AliDielectronMC::Instance()->GetMCEvent(),valuesMC);
411 while ( (die=static_cast<AliDielectron*>(nextDie())) ){
412 AliDielectronHistos *h=die->GetHistoManager();
414 if (h->GetHistogramList()->FindObject("Event_noCuts"))
415 h->FillClass("Event_noCuts",AliDielectronVarManager::kNMaxValues,values);
416 if (hasMC && h->GetHistogramList()->FindObject("MCEvent_noCuts"))
417 h->FillClass("Event_noCuts",AliDielectronVarManager::kNMaxValues,valuesMC);
424 if (!fEventFilter->IsSelected(InputEvent())) return;
426 fEventStat->Fill(kFilteredEvents);
430 if (InputEvent()->IsPileupFromSPD(3,0.8,3.,2.,5.)) return;
432 fEventStat->Fill(kPileupEvents);
435 fbz = InputEvent()->GetMagneticField();
436 AliKFParticle::SetField( fbz );
437 AliDielectronPID::SetCorrVal((Double_t)InputEvent()->GetRunNumber());
439 //Process event in all AliDielectron instances
440 // TIter nextDie(&fListDielectron);
441 // AliDielectron *die=0;
443 while ( (die=static_cast<AliDielectron*>(nextDie())) ){
444 //AliInfo(Form(" **************** die->Process(InputEvent()) : %d **************************", idie));
445 die->SetDontClearArrays(kTRUE);
446 die->Process(InputEvent());
447 if (die->HasCandidates()){
448 Int_t ncandidates=die->GetPairArray(1)->GetEntriesFast();
449 if (ncandidates==1) fEventStat->Fill((kNbinsEvent)+2*idie);
450 else if (ncandidates>1) fEventStat->Fill((kNbinsEvent+1)+2*idie);
454 AliDielectronVarManager::Fill(InputEvent(), fgValues);
455 for (Int_t ii=0; ii<2; ++ii){
456 TObjArray *obj = (TObjArray*)die->GetTrackArray(ii);
457 Int_t ntracks=obj->GetEntriesFast();
458 //AliInfo(Form(" ************** # of tracks = %d", ntracks));
459 for (Int_t itrack=0; itrack<ntracks; ++itrack){
461 ////////////////////////////////////////////////////////////////////
462 AliDielectronVarManager::Fill(obj->UncheckedAt(itrack), fgValues);
463 ////////////////////////////////////////////////////////////////////
465 if(fgValues[AliDielectronVarManager::kCharge]>0){
466 fVeptmp.push_back(new AliDielectronSingleTG(1,
467 fgValues[AliDielectronVarManager::kCentrality],
468 fgValues[AliDielectronVarManager::kXv],
469 fgValues[AliDielectronVarManager::kYv],
470 fgValues[AliDielectronVarManager::kZv],
471 fgValues[AliDielectronVarManager::kPx],
472 fgValues[AliDielectronVarManager::kPy],
473 fgValues[AliDielectronVarManager::kPz],
474 fgValues[AliDielectronVarManager::kPt],
475 fgValues[AliDielectronVarManager::kEta],
476 fgValues[AliDielectronVarManager::kPhi],
477 fgValues[AliDielectronVarManager::kTheta],
478 1, 1, static_cast<AliVTrack*>(obj->UncheckedAt(itrack)))
480 }else if(fgValues[AliDielectronVarManager::kCharge]<0){
481 fVemtmp.push_back(new AliDielectronSingleTG(-1,
482 fgValues[AliDielectronVarManager::kCentrality],
483 fgValues[AliDielectronVarManager::kXv],
484 fgValues[AliDielectronVarManager::kYv],
485 fgValues[AliDielectronVarManager::kZv],
486 fgValues[AliDielectronVarManager::kPx],
487 fgValues[AliDielectronVarManager::kPy],
488 fgValues[AliDielectronVarManager::kPz],
489 fgValues[AliDielectronVarManager::kPt],
490 fgValues[AliDielectronVarManager::kEta],
491 fgValues[AliDielectronVarManager::kPhi],
492 fgValues[AliDielectronVarManager::kTheta],
493 1, 1, static_cast<AliVTrack*>(obj->UncheckedAt(itrack)))
498 //AliInfo(Form("size of e and p = %d %d", (int)fVeptmp.size(), (int)fVemtmp.size()));
501 CheckGhostPairs(fVeptmp);
502 CheckGhostPairs(fVemtmp);
503 if(fRejectPairFlag[idie]==1 || fRejectPairFlag[idie]==2){
504 RejectPairs(fVeptmp, fVemtmp, idie);
506 RandomizePool(fVeptmp, fVemtmp);
507 CalcPair(fVep, fVem, die, idie);
509 // AliInfo(Form("size of e and p (after) = %d %d", (int)fVep.size(), (int)fVem.size()));
511 double dwcent = 100.0/fgkNCENT;
512 double dwiz = 20.0/fgkNZBIN;
513 double dwrp = acos(-1.0)/fgkNRPBIN;
515 int icent = (int)(fgValues[AliDielectronVarManager::kCentrality]/dwcent);
516 int izbin = (int)((fgValues[AliDielectronVarManager::kZvPrim]+10)/dwiz);
517 int irp = (int)((fgValues[AliDielectronVarManager::kV0ACrpH2])/dwrp);
520 if(icent>=fgkNCENT) icent=fgkNCENT-1;
522 if(izbin>=fgkNZBIN) izbin=fgkNZBIN-1;
524 if(irp>=fgkNRPBIN) irp=fgkNRPBIN-1;
526 fvep[fibuf[idie][izbin][icent][irp]][idie][izbin][icent][irp].clear();
527 for(int iep = 0; iep<(int)fVep.size();iep++) {
528 fvep[fibuf[idie][izbin][icent][irp]][idie][izbin][icent][irp].push_back(fVep[iep]);
529 fpoolp[idie][izbin][icent][irp].push_back(fVep[iep]);
530 if(fpoolp[idie][izbin][icent][irp].size()>fgkMAXPOOL) {
531 fpoolp[idie][izbin][icent][irp].pop_front();
534 fvem[fibuf[idie][izbin][icent][irp]][idie][izbin][icent][irp].clear();
535 for(int iem = 0; iem<(int)fVem.size();iem++) {
536 fvem[fibuf[idie][izbin][icent][irp]][idie][izbin][icent][irp].push_back(fVem[iem]);
537 fpoolm[idie][izbin][icent][irp].push_back(fVem[iem]);
538 if(fpoolm[idie][izbin][icent][irp].size()>fgkMAXPOOL) {
539 fpoolm[idie][izbin][icent][irp].pop_front();
544 fibuf[idie][izbin][icent][irp]++;
545 if(fibuf[idie][izbin][icent][irp]>= fgkNBUF) fibuf[idie][izbin][icent][irp]=0;
558 AliESDEvent *fESD = dynamic_cast<AliESDEvent*>(InputEvent());
559 fEvent->Fill(values[AliDielectronVarManager::kCentrality]);
560 for (Int_t iTracks = 0; iTracks < fESD->GetNumberOfTracks(); iTracks++) {
561 AliESDtrack* track = fESD->GetTrack(iTracks);
563 Printf("ERROR: Could not receive track %d", iTracks);
566 if(!fCutsMother->AcceptTrack(track)) continue;
567 fdEdXvsPt->Fill(track->GetTPCmomentum(), track->GetTPCsignal());
568 fdEdXnSigmaElecvsPt->Fill(track->GetTPCmomentum(),
569 AliDielectronVarManager::GetPIDResponse()->NumberOfSigmasTPC(track,
571 -AliDielectronPID::GetCorrVal());
572 /// for beta caliculaton
573 Double_t l = track->GetIntegratedLength(); // cm
574 Double_t t = track->GetTOFsignal();
575 Double_t t0 = AliDielectronVarManager::GetPIDResponse()->GetTOFResponse().GetTimeZero(); // ps
577 if( (l < 360. || l > 800.) || (t <= 0.) || (t0 >999990.0) ) {
581 t -= t0; // subtract the T0
583 t *= 1e-12; //ps -> s
586 beta = v / TMath::C();
589 fTOFbetavsPt->Fill(track->GetTPCmomentum(), beta);
590 fTOFnSigmaElecvsPt->Fill(track->GetTPCmomentum(),
591 AliDielectronVarManager::GetPIDResponse()->NumberOfSigmasTOF(track,
593 ////rough PID is required
594 if( fabs(AliDielectronVarManager::GetPIDResponse()->NumberOfSigmasTOF(track, AliPID::kElectron))<3){
595 fdEdXvsPtTOF->Fill(track->GetTPCmomentum(), track->GetTPCsignal());
596 fdEdXnSigmaElecvsPtTOF->Fill(track->GetTPCmomentum(),
597 AliDielectronVarManager::GetPIDResponse()->NumberOfSigmasTPC(track,
599 -AliDielectronPID::GetCorrVal());
602 if(track->GetTPCsignal()>70 && track->GetTPCsignal()<90){
603 fNCrossedRowsTPC->Fill(track->GetTPCmomentum(), track->GetTPCCrossedRows());
604 //fChi2ClusTPC->Fill(track->GetTPCmomentum(), track->GetTPCchi2()/track->GetTPCNcls());
605 fChi2ClusTPC->Fill(track->GetTPCmomentum(), track->GetTPCchi2());
606 fRatioCrossClusTPC->Fill(track->GetTPCmomentum(), track->GetTPCCrossedRows()/track->GetTPCNclsF());
611 PostData(1, &fListHistos);
612 PostData(2, &fListCF);
613 PostData(3,fEventStat);
616 //_________________________________________________________________________________
617 void AliAnalysisTaskMultiDielectronTG::FinishTaskOutput()
622 TIter nextDie(&fListDielectron);
623 AliDielectron *die=0;
624 while ( (die=static_cast<AliDielectron*>(nextDie())) ){
625 die->SaveDebugTree();
626 AliDielectronMixingHandler *mix=die->GetMixingHandler();
627 // printf("\n\n\n===============\ncall mix in Terminate: %p (%p)\n=================\n\n",mix,die);
628 if (mix) mix->MixRemaining(die);
630 PostData(1, &fListHistos);
631 PostData(2, &fListCF);
634 //_________________________________________________________________________________
635 void AliAnalysisTaskMultiDielectronTG::CheckGhostPairs(vector<AliDielectronSingleTG*> e1)
637 ////// Check whether the pairs are in ghost pairs
638 ///// ghost means that one of the pairs is highly associated but reconstructed as a true particle
643 for(int i1=0; i1<(int)e1.size(); i1++){
645 for(int i2=i1+1; i2<(int)e1.size(); i2++){
646 if( fabs(e1[i1]->Phi() - e1[i2]->Phi())<0.01 &&
647 fabs(e1[i1]->Eta() - e1[i2]->Eta())<0.005
650 e1[i2]->SetGstFlag(0);
653 if(reject==true)e1[i1]->SetGstFlag(0);
658 //_________________________________________________________________________________
659 Bool_t AliAnalysisTaskMultiDielectronTG::CheckGhost(vector<AliDielectronSingleTG*> e1, vector<AliDielectronSingleTG*> e2)
661 ////// To be sure whether there are no ghost pairs in h event mixing
663 if(e1.size()>0 && e2.size()>0){
664 for(int i1=0; i1<(int)e1.size(); i1++){
665 for(int i2=0; i2<(int)e2.size(); i2++){
666 if( fabs(e1[i1]->Phi() - e2[i2]->Phi())<0.01 &&
667 fabs(e1[i1]->Eta() - e2[i2]->Eta())<0.005
677 //_________________________________________________________________________________
678 void AliAnalysisTaskMultiDielectronTG::RandomizePool(vector<AliDielectronSingleTG*> e1, vector<AliDielectronSingleTG*> e2)
681 ///// Randomize the pool constent to cancel the filling scheme of the single tracks
685 int size1 = e1.size();
687 for(int i=0;i<1000;i++){
690 for(int i=0;i<size1;i++){
694 for(int i=0;i<size1;i++){
695 int j = (int)(gRandom->Uniform(0,size1));
696 while(usedindex[j]==1){
697 j = (int)(gRandom->Uniform(0,size1));
699 if( (e1[j]->GetGstFlag()==1) &&
700 (e1[j]->GetConvFlag()==1)
702 fVep.push_back(e1[j]);
708 int size2 = e2.size();
709 for(int i=0;i<1000;i++){
712 for(int i=0;i<size2;i++){
716 for(int i=0;i<size2;i++){
717 int j = (int)(gRandom->Uniform(0,size2));
718 while(usedindex[j]==1){
719 j = (int)(gRandom->Uniform(0,size2));
721 if( (e2[j]->GetGstFlag()==1) &&
722 (e2[j]->GetConvFlag()==1)
724 fVem.push_back(e2[j]);
731 //_________________________________________________________________________________
732 void AliAnalysisTaskMultiDielectronTG::CalcPair(vector<AliDielectronSingleTG*> ve1,
733 vector<AliDielectronSingleTG*> ve2, AliDielectron *die, Int_t idie)
737 // main routine for the pair procesing
741 for(int i1=0; i1<(int)ve1.size(); i1++){
742 for(int i2=0; i2<(int)ve2.size(); i2++){
743 FillPair(ve1[i1], ve2[i2], 0, die, idie);
747 for(int i1=0; i1<(int)ve1.size(); i1++){
748 for(int i2=i1+1; i2<(int)ve1.size(); i2++){
749 FillPair(ve1[i1], ve1[i2], 1, die, idie);
753 for(int i1=0; i1<(int)ve2.size(); i1++){
754 for(int i2=i1+1; i2<(int)ve2.size(); i2++){
755 FillPair(ve2[i1], ve2[i2], 2, die, idie );
760 double dwcent = 100.0/fgkNCENT;
761 double dwiz = 20.0/fgkNZBIN;
762 double dwrp = acos(-1.0)/fgkNRPBIN;
764 int icent = (int)(fgValues[AliDielectronVarManager::kCentrality]/dwcent);
765 int izbin = (int)((fgValues[AliDielectronVarManager::kZvPrim]+10)/dwiz);
766 int irp = (int)((fgValues[AliDielectronVarManager::kV0ACrpH2])/dwrp);
769 if(icent>=fgkNCENT) icent=fgkNCENT-1;
771 if(izbin>=fgkNZBIN) izbin=fgkNZBIN-1;
773 if(irp>=fgkNRPBIN) irp=fgkNRPBIN-1;
778 // Now mixed event for +- pairs
781 for(int ibuf=0;(nmixed<fgkNMix);ibuf++) {
783 while((fBGRejUnlike && CheckGhost(ve1, fvem[ibuf][idie][izbin][icent][irp])) && ntry<fgkMAXTRY) {
784 ReshuffleBuffer(fvem[ibuf][idie][izbin][icent][irp],fpoolm[idie][izbin][icent][irp]);
787 for(int i1=0; i1<(int)ve1.size(); i1++){
788 for(int i2=0; i2<(int)fvem[ibuf][idie][izbin][icent][irp].size(); i2++){
789 FillPair(ve1[i1],fvem[ibuf][idie][izbin][icent][irp][i2], 3, die, idie);
797 // Now mixed event for -+ pairs
800 for(int ibuf=0;(nmixed<fgkNMix);ibuf++) {
802 while((fBGRejUnlike && CheckGhost(ve2, fvep[ibuf][idie][izbin][icent][irp])) && ntry<fgkMAXTRY) {
803 ReshuffleBuffer(fvep[ibuf][idie][izbin][icent][irp],fpoolp[idie][izbin][icent][irp]);
806 for(int i1=0; i1<(int)ve2.size(); i1++){
807 for(int i2=0; i2<(int)fvep[ibuf][idie][izbin][icent][irp].size(); i2++){
808 FillPair(fvep[ibuf][idie][izbin][icent][irp][i2],ve2[i1],4, die, idie);
817 // Now mixed event for ++ pairs
820 for(int ibuf=0;(nmixed<fgkNMix);ibuf++) {
822 while((fBGRejLike && CheckGhost(ve1, fvep[ibuf][idie][izbin][icent][irp])) && ntry<fgkMAXTRY) {
823 ReshuffleBuffer(fvep[ibuf][idie][izbin][icent][irp],fpoolp[idie][izbin][icent][irp]);
826 for(int i1=0; i1<(int)ve1.size(); i1++){
827 for(int i2=0;i2<(int)fvep[ibuf][idie][izbin][icent][irp].size(); i2++){
828 FillPair(ve1[i1],fvep[ibuf][idie][izbin][icent][irp][i2], 5, die, idie);
837 // Now mixed event for +- pairs
840 for(int ibuf=0;(nmixed<fgkNMix);ibuf++) {
842 while((fBGRejLike && CheckGhost(ve2, fvem[ibuf][idie][izbin][icent][irp])) && ntry<fgkMAXTRY) {
843 ReshuffleBuffer(fvem[ibuf][idie][izbin][icent][irp],fpoolm[idie][izbin][icent][irp]);
846 for(int i1=0; i1<(int)ve2.size(); i1++){
847 for(int i2=0; i2<(int)fvem[ibuf][idie][izbin][icent][irp].size(); i2++){
848 FillPair(ve2[i1],fvem[ibuf][idie][izbin][icent][irp][i2],6, die, idie);
858 //_________________________________________________________________________________
859 void AliAnalysisTaskMultiDielectronTG::FillPair(AliDielectronSingleTG *iep,
860 AliDielectronSingleTG *iem, int type, AliDielectron *die, Int_t idie)
864 // main routine for filling kinematics of pairs
869 double dmass, dphiv, dpxpair, dpypair, dpzpair;
870 double dptpair, depair, dphipair, detapair, dcos, dpsi;
872 CalcVars(iep, iem, dmass, dphiv, dpxpair, dpypair, dpzpair,
873 dptpair, depair, dphipair, detapair, dcos, dpsi);
876 double dopeningangle = -9999;
877 double dv0mass = -9999;
878 double dv0pxpair = -9999;
879 double dv0pypair = -9999;
880 double dv0pzpair = -9999;
881 double dv0ptpair = -9999;
882 double dv0epair = -9999;
883 double dv0xvpair = -9999;
884 double dv0yvpair = -9999;
885 double dv0zvpair = -9999;
886 double dv0phipair = -9999;
887 double dv0etapair = -9999;
888 double dv0rpair = -9999;
889 double dpsipair = -9999;
890 double dphivpair = -9999;
892 ////////////////////////////
893 ///// calculate v0 ////////
894 ///////////////////////////
896 /// for the moment, this doesn't work for MC
897 if(fdv0mixing == kFALSE && (type==3 || type==4 || type==5 || type==6)){
900 if(die->GetHasMC()==kTRUE && (type==3 || type==4 || type==5 || type==6)){
903 if(type==0 || type==1 || type==2){
909 AliVTrack* trackob1= iep->GetTrack();
910 AliVTrack* trackob2= iem->GetTrack();
912 if(!trackob1 || !trackob2){
916 AliDielectronPair candidate;
917 candidate.SetTracks(trackob1, (int)(11*iep->Charge()),
918 trackob2, (int)(11*iem->Charge()));
920 if(trackob1==trackob2){
921 AliInfo("Same Objects!!");
925 //const AliKFParticle &kfPairLeg1 = candidate.GetKFFirstDaughter();
926 //const AliKFParticle &kfPairLeg2 = candidate.GetKFSecondDaughter();
928 const AliKFParticle &kfPair = candidate.GetKFParticle();
931 dv0mass = candidate.M();
932 dv0pxpair = candidate.Px();
933 dv0pypair = candidate.Py();
934 dv0pzpair = candidate.Pz();
935 dv0ptpair = candidate.Pt();
936 dv0epair = candidate.E();
937 dv0xvpair = candidate.Xv();
938 dv0yvpair = candidate.Yv();
939 dv0zvpair = candidate.Zv();
940 dv0phipair = candidate.Phi();
941 dv0etapair = candidate.Eta();
943 dv0mass = kfPair.GetMass();
944 dv0pxpair = kfPair.GetPx();
945 dv0pypair = kfPair.GetPy();
946 dv0pzpair = kfPair.GetPz();
947 dv0ptpair = kfPair.GetPt();
948 dv0epair = kfPair.GetE();
949 dv0xvpair = kfPair.GetX();
950 dv0yvpair = kfPair.GetY();
951 dv0zvpair = kfPair.GetZ();
952 dv0phipair = kfPair.GetPhi();
953 dv0etapair = kfPair.GetEta();
954 dv0rpair = kfPair.GetR();
956 dopeningangle = candidate.OpeningAngle();
957 dpsipair = candidate.PsiPair(fbz);
958 dphivpair = candidate.PhivPair(fbz);
963 Double_t values[AliDielectronVarManager::kNMaxValues];
966 className1.Form("MyPair_%s",kPairClassNamesTG[type]);
967 className2.Form("MyPairV0_%s",kPairClassNamesTG[type]);
969 AliDielectronHistos *fHistos = die->GetHistoManager();
970 Bool_t pairClass1=fHistos->GetHistogramList()->FindObject(className1.Data())!=0x0;
971 Bool_t pairClass2=fHistos->GetHistogramList()->FindObject(className2.Data())!=0x0;
973 if (pairClass1 && PairTrackcut(dphiv, dcos, dmass, idie)==true){
974 ///import pair variables to values!!
975 values[AliDielectronVarManager::kPx] = dpxpair;
976 values[AliDielectronVarManager::kPy] = dpypair;
977 values[AliDielectronVarManager::kPz] = dpzpair;
978 values[AliDielectronVarManager::kPt] = dptpair;
979 values[AliDielectronVarManager::kXv] = dv0xvpair;
980 values[AliDielectronVarManager::kYv] = dv0yvpair;
981 values[AliDielectronVarManager::kZv] = dv0zvpair;
982 values[AliDielectronVarManager::kR] = dv0rpair;
983 values[AliDielectronVarManager::kE] = depair;
984 values[AliDielectronVarManager::kEta] = detapair;
985 values[AliDielectronVarManager::kM] = dmass;
986 values[AliDielectronVarManager::kPsiPair] = dphiv;
987 values[AliDielectronVarManager::kPhivPair] = dphiv;
988 values[AliDielectronVarManager::kPhi] = dphipair;
989 values[AliDielectronVarManager::kOpeningAngle] = dcos;
990 values[AliDielectronVarManager::kCosPointingAngle] = TMath::Abs(TMath::ATan2(TMath::Sin(iep->Phi()-iem->Phi()),TMath::Cos(iep->Phi()-iem->Phi())));
991 fHistos->FillClass(className1, AliDielectronVarManager::kNMaxValues, values);
995 if (pairClass2 && PairTrackcut(dphiv, dopeningangle, dv0mass, idie)==true){
996 values[AliDielectronVarManager::kPx] = dv0pxpair;
997 values[AliDielectronVarManager::kPy] = dv0pypair;
998 values[AliDielectronVarManager::kPz] = dv0pzpair;
999 values[AliDielectronVarManager::kPt] = dv0ptpair;
1000 values[AliDielectronVarManager::kXv] = dv0xvpair;
1001 values[AliDielectronVarManager::kYv] = dv0yvpair;
1002 values[AliDielectronVarManager::kZv] = dv0zvpair;
1003 values[AliDielectronVarManager::kR] = dv0rpair;
1004 values[AliDielectronVarManager::kE] = dv0epair;
1005 values[AliDielectronVarManager::kEta] = dv0etapair;
1006 values[AliDielectronVarManager::kM] = dv0mass;
1007 values[AliDielectronVarManager::kPsiPair] = dpsipair;
1008 values[AliDielectronVarManager::kPhivPair] = dphivpair;
1009 values[AliDielectronVarManager::kPhi] = dv0phipair;
1010 values[AliDielectronVarManager::kOpeningAngle] = dopeningangle;
1011 values[AliDielectronVarManager::kCosPointingAngle] = TMath::Abs(TMath::ATan2(TMath::Sin(iep->Phi()-iem->Phi()),TMath::Cos(iep->Phi()-iem->Phi())));
1012 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
1019 //_________________________________________________________________________________
1020 bool AliAnalysisTaskMultiDielectronTG::PairTrackcut(double phiv, double op, double mass, int idie)
1024 // pair-by-pair cuts
1030 if(fRejectPairFlag[idie] == 1 || fRejectPairFlag[idie] == 2 ||
1031 fRejectPairFlag[idie] == 3 || fRejectPairFlag[idie] == 4 ){
1032 if(fRejectPairFlag[idie] == 2 || fRejectPairFlag[idie] == 4 ){
1033 if(fbz>0 && (phiv>fdconvphiv && mass < fdconvMee) ){
1035 }else if(fbz<0 && phiv<acos(-1.0)-fdconvphiv && mass < fdconvMee){
1038 }else if(fRejectPairFlag[idie] == 1 || fRejectPairFlag[idie] == 3){
1050 //_________________________________________________________________________________
1051 void AliAnalysisTaskMultiDielectronTG::CalcVars(AliDielectronSingleTG *iep, AliDielectronSingleTG *iem,
1052 double &mass, double &phiv, double &px, double &py, double&pz,
1053 double &pt, double &e, double &phi,
1054 double &eta, double &cos, double &psi)
1059 // standalone calculator for the pair variables
1062 px = iep->Px()+iem->Px();
1063 py = iep->Py()+iem->Py();
1064 pz = iep->Pz()+iem->Pz();
1065 pt = sqrt(px*px+py*py);
1066 double dppair = sqrt(pt*pt+pz*pz);
1067 static const double me=0.0005109989;
1068 e = sqrt(me*me+iep->Px()*iep->Px()+iep->Py()*iep->Py()+iep->Pz()*iep->Pz())
1069 + sqrt(me*me+iem->Px()*iem->Px()+iem->Py()*iem->Py()+iem->Pz()*iem->Pz());
1071 mass = e*e-px*px-py*py-pz*pz;
1079 phi = atan2(py, px);
1080 eta = -0.5*TMath::Log((dppair+pz)/(dppair-pz));
1081 double p1 = sqrt(pow(iep->Px(),2)+pow(iep->Py(),2)+pow(iep->Pz(),2));
1082 double p2 = sqrt(pow(iem->Px(),2)+pow(iem->Py(),2)+pow(iem->Pz(),2));
1083 cos = acos((iep->Px()*iem->Px()+iep->Py()*iem->Py()+iep->Pz()*iem->Pz())/(p1*p2));
1085 double dtheta = iep->Theta()-iem->Theta();
1086 psi = asin(dtheta/cos);
1089 //unit vector of (pep+pem)
1094 double ax = uy/sqrt(ux*ux+uy*uy);
1095 double ay = -ux/sqrt(ux*ux+uy*uy);
1097 //momentum of e+ and e- in (ax,ay,az) axis. Note that az=0 by
1099 //double ptep = iep->Px()*ax + iep->Py()*ay;
1100 //double ptem = iem->Px()*ax + iem->Py()*ay;
1102 double pxep = iep->Px();
1103 double pyep = iep->Py();
1104 double pzep = iep->Pz();
1105 double pxem = iem->Px();
1106 double pyem = iem->Py();
1107 double pzem = iem->Pz();
1110 //vector product of pep X pem
1111 double vpx = pyep*pzem - pzep*pyem;
1112 double vpy = pzep*pxem - pxep*pzem;
1113 double vpz = pxep*pyem - pyep*pxem;
1114 double vp = sqrt(vpx*vpx+vpy*vpy+vpz*vpz);
1115 //double thev = acos(vpz/vp);
1117 //unit vector of pep X pem
1122 //The third axis defined by vector product (ux,uy,uz)X(vx,vy,vz)
1123 double wx = uy*vz - uz*vy;
1124 double wy = uz*vx - ux*vz;
1125 double wz = ux*vy - uy*vx;
1126 double wl = sqrt(wx*wx+wy*wy+wz*wz);
1127 // by construction, (wx,wy,wz) must be a unit vector.
1128 if(fabs(wl - 1.0) > 0.00001) std::cout << "Calculation error in W vector"<<std::endl;
1129 // measure angle between (wx,wy,wz) and (ax,ay,0). The angle between them
1130 // should be small if the pair is conversion
1132 double cosPhiV = wx*ax + wy*ay;
1133 phiv = acos(cosPhiV);
1137 //_________________________________________________________________________________
1138 void AliAnalysisTaskMultiDielectronTG::ReshuffleBuffer(vector<AliDielectronSingleTG*> ve, deque<AliDielectronSingleTG*> pool)
1140 //If there is not enough electron in the pool, give up
1142 // ReshuffleBuffer for th event mixing
1145 unsigned int ne = ve.size();
1146 unsigned int poolsize = pool.size();
1147 int used[fgkMAXPOOL];
1148 for(int i=0;i<(int)fgkMAXPOOL;i++){
1153 std::cout <<" pool size="<<poolsize<<" ne"<<ne<<std::endl;
1156 for(unsigned int ie=0; ie < ne; ie++) {
1157 int j = rand()%poolsize;
1159 j = rand()%poolsize;
1167 //_________________________________________________________________________________
1168 void AliAnalysisTaskMultiDielectronTG::RejectPairs(vector<AliDielectronSingleTG*> e1, vector<AliDielectronSingleTG*> e2, Int_t idie){
1170 ////////////////////////////////////
1171 ///// to reject pairs from track arrays
1172 ///// conversions, ghost ..
1173 ///////////////////////////////////
1174 if(e1.size()>0 && e2.size()>0){
1175 for(int i1=0; i1<(int)e1.size(); i1++){
1176 for(int i2=0; i2<(int)e2.size(); i2++){
1177 if(fRejectPairFlag[idie]==1){
1178 Double_t cosine = GetOpeningAngle(e1[i1], e2[i2]);
1180 e1[i1]->SetConvFlag(0);
1181 e2[i2]->SetConvFlag(0);
1183 }else if(fRejectPairFlag[idie]==2){
1184 Double_t phiv = GetPhiv(e1[i1], e2[i2]);
1185 Double_t mee = GetMass(e1[i1], e2[i2]);
1186 if(fbz>0 && ( phiv>fdconvphiv && mee < fdconvMee) ){
1187 e1[i1]->SetConvFlag(0);
1188 e2[i2]->SetConvFlag(0);
1189 }else if(fbz<0 && phiv<acos(-1.0)-fdconvphiv && mee < fdconvMee){
1190 e1[i1]->SetConvFlag(0);
1191 e2[i2]->SetConvFlag(0);
1198 for(int i1=0; i1<(int)e1.size(); i1++){
1199 for(int i2=i1+1; i2<(int)e1.size(); i2++){
1200 if(fRejectPairFlag[idie]==1){
1201 Double_t cosine = GetOpeningAngle(e1[i1], e1[i2]);
1203 e1[i1]->SetConvFlag(0);
1204 e1[i2]->SetConvFlag(0);
1206 }else if(fRejectPairFlag[idie]==2){
1207 Double_t phiv = GetPhiv(e1[i1], e1[i2]);
1208 Double_t mee = GetMass(e1[i1], e1[i2]);
1209 if(fbz>0 && phiv>fdconvphiv && mee < fdconvMee){
1210 e1[i1]->SetConvFlag(0);
1211 e1[i2]->SetConvFlag(0);
1212 }else if(fbz<0 && phiv<acos(-1.0)-fdconvphiv && mee < fdconvMee){
1213 e1[i1]->SetConvFlag(0);
1214 e1[i2]->SetConvFlag(0);
1222 for(int i1=0; i1<(int)e2.size(); i1++){
1223 for(int i2=i1+1; i2<(int)e2.size(); i2++){
1224 if(fRejectPairFlag[idie]==1){
1225 Double_t cosine = GetOpeningAngle(e2[i1], e2[i2]);
1227 e2[i1]->SetConvFlag(0);
1228 e2[i2]->SetConvFlag(0);
1230 }else if(fRejectPairFlag[idie]==2){
1231 Double_t phiv = GetPhiv(e2[i1], e2[i2]);
1232 Double_t mee = GetMass(e2[i1], e2[i2]);
1233 if(fbz>0 && phiv>fdconvphiv && mee < fdconvMee){
1234 e2[i1]->SetConvFlag(0);
1235 e2[i2]->SetConvFlag(0);
1236 }else if(fbz<0 && phiv<acos(-1.0)-fdconvphiv && mee < fdconvMee){
1237 e2[i1]->SetConvFlag(0);
1238 e2[i2]->SetConvFlag(0);
1247 //_________________________________________________________________________________
1248 Double_t AliAnalysisTaskMultiDielectronTG::GetOpeningAngle(AliDielectronSingleTG* e1, AliDielectronSingleTG* e2){
1250 //////////////////////
1251 //////// calculate pairs and get opening angle
1252 //////////////////////
1254 double dmass, dphiv, dpxpair, dpypair, dpzpair;
1255 double dptpair, depair, dphipair, detapair, dcos, dpsi;
1257 CalcVars(e1, e2, dmass, dphiv, dpxpair, dpypair, dpzpair,
1258 dptpair, depair, dphipair, detapair, dcos, dpsi);
1263 //_________________________________________________________________________________
1264 Double_t AliAnalysisTaskMultiDielectronTG::GetPhiv(AliDielectronSingleTG* e1, AliDielectronSingleTG* e2){
1266 //////////////////////
1267 //////// calculate pairs and get phiv
1268 //////////////////////
1270 double dmass, dphiv, dpxpair, dpypair, dpzpair;
1271 double dptpair, depair, dphipair, detapair, dcos, dpsi;
1273 CalcVars(e1, e2, dmass, dphiv, dpxpair, dpypair, dpzpair,
1274 dptpair, depair, dphipair, detapair, dcos, dpsi);
1279 //_________________________________________________________________________________
1280 Double_t AliAnalysisTaskMultiDielectronTG::GetMass(AliDielectronSingleTG* e1, AliDielectronSingleTG* e2){
1282 //////////////////////
1283 //////// calculate pairs and get mass
1284 //////////////////////
1286 double dmass, dphiv, dpxpair, dpypair, dpzpair;
1287 double dptpair, depair, dphipair, detapair, dcos, dpsi;
1289 CalcVars(e1, e2, dmass, dphiv, dpxpair, dpypair, dpzpair,
1290 dptpair, depair, dphipair, detapair, dcos, dpsi);