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"
52 const char* kPairClassNamesTG[7] = {
63 ClassImp(AliDielectronSingleTG)
64 ClassImp(AliAnalysisTaskMultiDielectronTG)
66 //_________________________________________________________________________________
67 AliAnalysisTaskMultiDielectronTG::AliAnalysisTaskMultiDielectronTG() :
73 fSelectPhysics(kFALSE),
74 fTriggerMask(AliVEvent::kMB),
75 fExcludeTriggerMask(0),
76 fTriggerOnV0AND(kFALSE),
77 fRejectPileup(kFALSE),
79 fTriggerAnalysis(0x0),
85 fdEdXnSigmaElecvsPt(0x0),
87 fdEdXnSigmaElecvsPtTOF(0x0),
89 fTOFnSigmaElecvsPt(0x0),
90 fNCrossedRowsTPC(0x0),
92 fRatioCrossClusTPC(0x0),
97 fdconvphiv(acos(-1.0)),
102 fBGRejUnlike(kFALSE),
110 //_________________________________________________________________________________
111 AliAnalysisTaskMultiDielectronTG::AliAnalysisTaskMultiDielectronTG(const char *name) :
112 AliAnalysisTaskSE(name),
117 fSelectPhysics(kFALSE),
118 fTriggerMask(AliVEvent::kMB),
119 fExcludeTriggerMask(0),
120 fTriggerOnV0AND(kFALSE),
121 fRejectPileup(kFALSE),
123 fTriggerAnalysis(0x0),
129 fdEdXnSigmaElecvsPt(0x0),
131 fdEdXnSigmaElecvsPtTOF(0x0),
133 fTOFnSigmaElecvsPt(0x0),
134 fNCrossedRowsTPC(0x0),
136 fRatioCrossClusTPC(0x0),
141 fdconvphiv(acos(-1.0)),
146 fBGRejUnlike(kFALSE),
152 DefineInput(0,TChain::Class());
153 DefineOutput(1, TList::Class());
154 DefineOutput(2, TList::Class());
155 DefineOutput(3, TH1D::Class());
156 fListHistos.SetName("Dielectron_Histos_Multi");
157 fListCF.SetName("Dielectron_CF_Multi");
158 fListDielectron.SetOwner();
159 fListHistos.SetOwner();
163 for(int i=0;i<fgkNDIE; i++){
164 for(int j=0;j<fgkNZBIN;j++){
165 for(int k=0;k<fgkNCENT;k++){
166 for(int l=0; l<fgkNRPBIN; l++){
167 fibuf[i][j][k][l] = 0;
168 fpoolp[i][j][k][l].clear();
169 fpoolm[i][j][k][l].clear();
170 for(int ib=0;ib<fgkNBUF; ib++){
171 fvep[ib][i][j][k][l].clear();
172 fvem[ib][i][j][k][l].clear();
183 //_________________________________________________________________________________
184 AliAnalysisTaskMultiDielectronTG::~AliAnalysisTaskMultiDielectronTG()
190 //histograms and CF are owned by the dielectron framework.
191 //however they are streamed to file, so in the first place the
192 //lists need to be owner...
193 fListHistos.SetOwner(kFALSE);
194 fListCF.SetOwner(kFALSE);
196 for(int i=0;i<fgkNDIE; i++){
197 for(int j=0;j<fgkNZBIN;j++){
198 for(int k=0;k<fgkNCENT;k++){
199 for(int l=0; l<fgkNRPBIN; l++){
200 fibuf[i][j][k][l] = 0;
201 fpoolp[i][j][k][l].clear();
202 fpoolm[i][j][k][l].clear();
203 for(int ib=0;ib<fgkNBUF; ib++){
204 fvep[ib][i][j][k][l].clear();
205 fvem[ib][i][j][k][l].clear();
212 //_________________________________________________________________________________
213 void AliAnalysisTaskMultiDielectronTG::UserCreateOutputObjects()
216 // Add all histogram manager histogram lists to the output TList
219 if (!fListHistos.IsEmpty()||!fListCF.IsEmpty()) return; //already initialised
221 // AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();
222 // Bool_t isESD=man->GetInputEventHandler()->IsA()==AliESDInputHandler::Class();
223 // Bool_t isAOD=man->GetInputEventHandler()->IsA()==AliAODInputHandler::Class();
225 TIter nextDie(&fListDielectron);
226 AliDielectron *die=0;
227 while ( (die=static_cast<AliDielectron*>(nextDie())) ){
229 if (die->GetHistogramList()) fListHistos.Add(const_cast<THashList*>(die->GetHistogramList()));
230 if (die->GetCFManagerPair()) fListCF.Add(const_cast<AliCFContainer*>(die->GetCFManagerPair()->GetContainer()));
233 Int_t cuts=fListDielectron.GetEntries();
234 Int_t nbins=kNbinsEvent+2*cuts;
236 fEventStat=new TH1D("hEventStat","Event statistics",nbins,0,nbins);
237 fEventStat->GetXaxis()->SetBinLabel(1,"Before Phys. Sel.");
238 fEventStat->GetXaxis()->SetBinLabel(2,"After Phys. Sel.");
241 fEventStat->GetXaxis()->SetBinLabel(3,"Bin3 not used");
242 fEventStat->GetXaxis()->SetBinLabel(4,"Bin4 not used");
243 fEventStat->GetXaxis()->SetBinLabel(5,"Bin5 not used");
245 if(fTriggerOnV0AND) fEventStat->GetXaxis()->SetBinLabel(3,"V0and triggers");
246 if (fEventFilter) fEventStat->GetXaxis()->SetBinLabel(4,"After Event Filter");
247 if (fRejectPileup) fEventStat->GetXaxis()->SetBinLabel(5,"After Pileup rejection");
249 for (Int_t i=0; i<cuts; ++i){
250 fEventStat->GetXaxis()->SetBinLabel((kNbinsEvent+1)+2*i,Form("#splitline{1 candidate}{%s}",fListDielectron.At(i)->GetName()));
251 fEventStat->GetXaxis()->SetBinLabel((kNbinsEvent+2)+2*i,Form("#splitline{With >1 candidate}{%s}",fListDielectron.At(i)->GetName()));
255 if (!fTriggerAnalysis) fTriggerAnalysis=new AliTriggerAnalysis;
256 fTriggerAnalysis->EnableHistograms();
257 fTriggerAnalysis->SetAnalyzeMC(AliDielectronMC::Instance()->HasMC());
264 float binw = (TMath::Log(maxx)-TMath::Log(minx))/nbinx;
266 for(int ii=0;ii<nbinx+1;ii++){
267 xbin[ii] = TMath::Exp(TMath::Log(minx) + 0.5*binw+binw*ii);
271 fQAElectron = new TList();
272 fQAElectron->SetName("QAElectron");
273 fQAElectron->SetOwner();
276 fEvent = new TH1D("Event","centrality", 100,0,100);
277 fQAElectron->Add(fEvent);
278 fdEdXvsPt = new TH2D("dEdXvsPt","dE/dX vs. PT of TPC", nbinx, xbin, 2000,0,200);
279 fQAElectron->Add(fdEdXvsPt);
280 fdEdXnSigmaElecvsPt = new TH2D("fdEdXnSigmaElecvsPt"," dE/dX normalized to electron vs. pT of TPC",
281 nbinx, xbin, 2000, -10, 10);
282 fQAElectron->Add(fdEdXnSigmaElecvsPt);
284 fdEdXvsPtTOF = new TH2D("dEdXvsPtTOF","dE/dX vs. PT of TPC", nbinx, xbin, 2000,0,200);
285 fQAElectron->Add(fdEdXvsPtTOF);
286 fdEdXnSigmaElecvsPtTOF = new TH2D("fdEdXnSigmaElecvsPtTOF"," dE/dX normalized to electron vs. pT of TPC",
287 nbinx, xbin, 2000, -10, 10);
288 fQAElectron->Add(fdEdXnSigmaElecvsPtTOF);
292 fTOFbetavsPt = new TH2D("fTOFbetavsPt","TOF beta vs. p", 400, 0, 20, 1200, 0, 1.2);
293 fQAElectron->Add(fTOFbetavsPt);
294 fTOFnSigmaElecvsPt = new TH2D("fTOFnSigmaElecvsPt","TOF nsigma for electron", 400, 0, 20, 2000, -10, 10);
295 fQAElectron->Add(fTOFnSigmaElecvsPt);
297 fNCrossedRowsTPC = new TH2F("fNCrossedRowsTPC", "TPC nCrossed Rows vs. pT", 200, 0, 20, 200, 0, 200);
298 fQAElectron->Add(fNCrossedRowsTPC);
299 fChi2ClusTPC = new TH2F("fChi2ClusTPC", "hChi2ClusTPC vs. pT", 200, 0, 20, 200, 0, 10);
300 fQAElectron->Add(fChi2ClusTPC);
302 fRatioCrossClusTPC = new TH2F("fRatioCrossClusTPC", "hRatioCrossClusTPC vs. pT", 200, 0, 20, 200, 0, 10);
303 fQAElectron->Add(fRatioCrossClusTPC);
305 fListHistos.Add(fQAElectron);
307 fListHistos.SetOwner();
309 PostData(1, &fListHistos);
310 PostData(2, &fListCF);
311 PostData(3, fEventStat);
313 fCutsMother = new AliESDtrackCuts;
314 fCutsMother->SetDCAToVertex2D(kTRUE);
315 fCutsMother->SetMaxDCAToVertexZ(3.0);
316 fCutsMother->SetMaxDCAToVertexXY(1.0);
317 fCutsMother->SetPtRange( 0.05 , 200.0);
318 fCutsMother->SetEtaRange( -0.84 , 0.84 );
319 fCutsMother->SetAcceptKinkDaughters(kFALSE);
320 fCutsMother->SetRequireITSRefit(kTRUE);
321 fCutsMother->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kFirst);
322 fCutsMother->SetMinNClustersITS(3);
323 fCutsMother->SetRequireTPCRefit(kTRUE);
326 AliInfo(Form("PairCutType = %d %d %d %d %d",
331 fRejectPairFlag[4]));
335 //_________________________________________________________________________________
336 void AliAnalysisTaskMultiDielectronTG::UserExec(Option_t *)
339 // Main loop. Called for every event
342 if (fListHistos.IsEmpty()&&fListCF.IsEmpty()) return;
344 AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();
345 Bool_t isESD=man->GetInputEventHandler()->IsA()==AliESDInputHandler::Class();
346 Bool_t isAOD=man->GetInputEventHandler()->IsA()==AliAODInputHandler::Class();
348 AliInputEventHandler* inputHandler = (AliInputEventHandler*) (man->GetInputEventHandler());
349 if (!inputHandler) return;
351 // AliPIDResponse *pidRes=inputHandler->GetPIDResponse();
352 if ( inputHandler->GetPIDResponse() ){
353 // for the 2.76 pass2 MC private train. Together with a sigma shift of -0.169
354 // pidRes->GetTPCResponse().SetSigma(4.637e-3,2.41332105409873257e+04);
355 AliDielectronVarManager::SetPIDResponse( inputHandler->GetPIDResponse() );
357 AliFatal("This task needs the PID response attached to the input event handler!");
360 // Was event selected ?
361 ULong64_t isSelected = AliVEvent::kAny;
362 Bool_t isRejected = kFALSE;
363 if( fSelectPhysics && inputHandler){
364 if((isESD && inputHandler->GetEventSelection()) || isAOD){
365 isSelected = inputHandler->IsEventSelected();
366 if (fExcludeTriggerMask && (isSelected&fExcludeTriggerMask)) isRejected=kTRUE;
367 if (fTriggerLogic==kAny) isSelected&=fTriggerMask;
368 else if (fTriggerLogic==kExact) isSelected=((isSelected&fTriggerMask)==fTriggerMask);
373 //Before physics selection
374 fEventStat->Fill(kAllEvents);
375 if (isSelected==0||isRejected) {
376 PostData(3,fEventStat);
379 //after physics selection
380 fEventStat->Fill(kSelectedEvents);
384 if(isESD){if (!fTriggerAnalysis->IsOfflineTriggerFired(static_cast<AliESDEvent*>(InputEvent()), AliTriggerAnalysis::kV0AND))
386 if(isAOD){if(!((static_cast<AliAODEvent*>(InputEvent()))->GetVZEROData()->GetV0ADecision() == AliVVZERO::kV0BB &&
387 (static_cast<AliAODEvent*>(InputEvent()))->GetVZEROData()->GetV0CDecision() == AliVVZERO::kV0BB) )
392 fEventStat->Fill(kV0andEvents);
394 //Fill Event histograms before the event filter
395 TIter nextDie(&fListDielectron);
396 AliDielectron *die=0;
397 Double_t values[AliDielectronVarManager::kNMaxValues]={0};
398 Double_t valuesMC[AliDielectronVarManager::kNMaxValues]={0};
399 AliDielectronVarManager::SetEvent(InputEvent());
400 AliDielectronVarManager::Fill(InputEvent(),values);
401 AliDielectronVarManager::Fill(InputEvent(),valuesMC);
402 Bool_t hasMC=AliDielectronMC::Instance()->HasMC();
404 if (AliDielectronMC::Instance()->ConnectMCEvent())
405 AliDielectronVarManager::Fill(AliDielectronMC::Instance()->GetMCEvent(),valuesMC);
408 while ( (die=static_cast<AliDielectron*>(nextDie())) ){
409 AliDielectronHistos *h=die->GetHistoManager();
411 if (h->GetHistogramList()->FindObject("Event_noCuts"))
412 h->FillClass("Event_noCuts",AliDielectronVarManager::kNMaxValues,values);
413 if (hasMC && h->GetHistogramList()->FindObject("MCEvent_noCuts"))
414 h->FillClass("Event_noCuts",AliDielectronVarManager::kNMaxValues,valuesMC);
421 if (!fEventFilter->IsSelected(InputEvent())) return;
423 fEventStat->Fill(kFilteredEvents);
427 if (InputEvent()->IsPileupFromSPD(3,0.8,3.,2.,5.)) return;
429 fEventStat->Fill(kPileupEvents);
432 fbz = InputEvent()->GetMagneticField();
433 AliKFParticle::SetField( fbz );
434 AliDielectronPID::SetCorrVal((Double_t)InputEvent()->GetRunNumber());
436 //Process event in all AliDielectron instances
437 // TIter nextDie(&fListDielectron);
438 // AliDielectron *die=0;
440 while ( (die=static_cast<AliDielectron*>(nextDie())) ){
441 //AliInfo(Form(" **************** die->Process(InputEvent()) : %d **************************", idie));
442 die->SetDontClearArrays(kTRUE);
443 die->Process(InputEvent());
444 if (die->HasCandidates()){
445 Int_t ncandidates=die->GetPairArray(1)->GetEntriesFast();
446 if (ncandidates==1) fEventStat->Fill((kNbinsEvent)+2*idie);
447 else if (ncandidates>1) fEventStat->Fill((kNbinsEvent+1)+2*idie);
451 AliDielectronVarManager::Fill(InputEvent(), fgValues);
452 for (Int_t ii=0; ii<2; ++ii){
453 TObjArray *obj = (TObjArray*)die->GetTrackArray(ii);
454 Int_t ntracks=obj->GetEntriesFast();
455 //AliInfo(Form(" ************** # of tracks = %d", ntracks));
456 for (Int_t itrack=0; itrack<ntracks; ++itrack){
458 ////////////////////////////////////////////////////////////////////
459 AliDielectronVarManager::Fill(obj->UncheckedAt(itrack), fgValues);
460 ////////////////////////////////////////////////////////////////////
462 if(fgValues[AliDielectronVarManager::kCharge]>0){
463 fVeptmp.push_back(new AliDielectronSingleTG(1,
464 fgValues[AliDielectronVarManager::kCentrality],
465 fgValues[AliDielectronVarManager::kXv],
466 fgValues[AliDielectronVarManager::kYv],
467 fgValues[AliDielectronVarManager::kZv],
468 fgValues[AliDielectronVarManager::kPx],
469 fgValues[AliDielectronVarManager::kPy],
470 fgValues[AliDielectronVarManager::kPz],
471 fgValues[AliDielectronVarManager::kPt],
472 fgValues[AliDielectronVarManager::kEta],
473 fgValues[AliDielectronVarManager::kPhi],
474 fgValues[AliDielectronVarManager::kTheta],
475 1, 1, static_cast<AliVTrack*>(obj->UncheckedAt(itrack)))
477 }else if(fgValues[AliDielectronVarManager::kCharge]<0){
478 fVemtmp.push_back(new AliDielectronSingleTG(-1,
479 fgValues[AliDielectronVarManager::kCentrality],
480 fgValues[AliDielectronVarManager::kXv],
481 fgValues[AliDielectronVarManager::kYv],
482 fgValues[AliDielectronVarManager::kZv],
483 fgValues[AliDielectronVarManager::kPx],
484 fgValues[AliDielectronVarManager::kPy],
485 fgValues[AliDielectronVarManager::kPz],
486 fgValues[AliDielectronVarManager::kPt],
487 fgValues[AliDielectronVarManager::kEta],
488 fgValues[AliDielectronVarManager::kPhi],
489 fgValues[AliDielectronVarManager::kTheta],
490 1, 1, static_cast<AliVTrack*>(obj->UncheckedAt(itrack)))
495 //AliInfo(Form("size of e and p = %d %d", (int)fVeptmp.size(), (int)fVemtmp.size()));
498 CheckGhostPairs(fVeptmp);
499 CheckGhostPairs(fVemtmp);
500 if(fRejectPairFlag[idie]==1 || fRejectPairFlag[idie]==2){
501 RejectPairs(fVeptmp, fVemtmp, idie);
503 RandomizePool(fVeptmp, fVemtmp);
504 CalcPair(fVep, fVem, die, idie);
506 // AliInfo(Form("size of e and p (after) = %d %d", (int)fVep.size(), (int)fVem.size()));
508 double dwcent = 100.0/fgkNCENT;
509 double dwiz = 20.0/fgkNZBIN;
510 double dwrp = acos(-1.0)/fgkNRPBIN;
512 int icent = (int)(fgValues[AliDielectronVarManager::kCentrality]/dwcent);
513 int izbin = (int)((fgValues[AliDielectronVarManager::kZvPrim]+10)/dwiz);
514 int irp = (int)((fgValues[AliDielectronVarManager::kV0ACrpH2])/dwrp);
517 if(icent>=fgkNCENT) icent=fgkNCENT-1;
519 if(izbin>=fgkNZBIN) izbin=fgkNZBIN-1;
521 if(irp>=fgkNRPBIN) irp=fgkNRPBIN-1;
523 fvep[fibuf[idie][izbin][icent][irp]][idie][izbin][icent][irp].clear();
524 for(int iep = 0; iep<(int)fVep.size();iep++) {
525 fvep[fibuf[idie][izbin][icent][irp]][idie][izbin][icent][irp].push_back(fVep[iep]);
526 fpoolp[idie][izbin][icent][irp].push_back(fVep[iep]);
527 if(fpoolp[idie][izbin][icent][irp].size()>fgkMAXPOOL) {
528 fpoolp[idie][izbin][icent][irp].pop_front();
531 fvem[fibuf[idie][izbin][icent][irp]][idie][izbin][icent][irp].clear();
532 for(int iem = 0; iem<(int)fVem.size();iem++) {
533 fvem[fibuf[idie][izbin][icent][irp]][idie][izbin][icent][irp].push_back(fVem[iem]);
534 fpoolm[idie][izbin][icent][irp].push_back(fVem[iem]);
535 if(fpoolm[idie][izbin][icent][irp].size()>fgkMAXPOOL) {
536 fpoolm[idie][izbin][icent][irp].pop_front();
541 fibuf[idie][izbin][icent][irp]++;
542 if(fibuf[idie][izbin][icent][irp]>= fgkNBUF) fibuf[idie][izbin][icent][irp]=0;
555 AliESDEvent *fESD = dynamic_cast<AliESDEvent*>(InputEvent());
556 fEvent->Fill(values[AliDielectronVarManager::kCentrality]);
557 for (Int_t iTracks = 0; iTracks < fESD->GetNumberOfTracks(); iTracks++) {
558 AliESDtrack* track = fESD->GetTrack(iTracks);
560 Printf("ERROR: Could not receive track %d", iTracks);
563 if(!fCutsMother->AcceptTrack(track)) continue;
564 fdEdXvsPt->Fill(track->GetTPCmomentum(), track->GetTPCsignal());
565 fdEdXnSigmaElecvsPt->Fill(track->GetTPCmomentum(),
566 AliDielectronVarManager::GetPIDResponse()->NumberOfSigmasTPC(track,
568 -AliDielectronPID::GetCorrVal());
569 /// for beta caliculaton
570 Double_t l = track->GetIntegratedLength(); // cm
571 Double_t t = track->GetTOFsignal();
572 Double_t t0 = AliDielectronVarManager::GetPIDResponse()->GetTOFResponse().GetTimeZero(); // ps
574 if( (l < 360. || l > 800.) || (t <= 0.) || (t0 >999990.0) ) {
578 t -= t0; // subtract the T0
580 t *= 1e-12; //ps -> s
583 beta = v / TMath::C();
586 fTOFbetavsPt->Fill(track->GetTPCmomentum(), beta);
587 fTOFnSigmaElecvsPt->Fill(track->GetTPCmomentum(),
588 AliDielectronVarManager::GetPIDResponse()->NumberOfSigmasTOF(track,
590 ////rough PID is required
591 if( fabs(AliDielectronVarManager::GetPIDResponse()->NumberOfSigmasTOF(track, AliPID::kElectron))<3){
592 fdEdXvsPtTOF->Fill(track->GetTPCmomentum(), track->GetTPCsignal());
593 fdEdXnSigmaElecvsPtTOF->Fill(track->GetTPCmomentum(),
594 AliDielectronVarManager::GetPIDResponse()->NumberOfSigmasTPC(track,
596 -AliDielectronPID::GetCorrVal());
599 if(track->GetTPCsignal()>70 && track->GetTPCsignal()<90){
600 fNCrossedRowsTPC->Fill(track->GetTPCmomentum(), track->GetTPCCrossedRows());
601 //fChi2ClusTPC->Fill(track->GetTPCmomentum(), track->GetTPCchi2()/track->GetTPCNcls());
602 fChi2ClusTPC->Fill(track->GetTPCmomentum(), track->GetTPCchi2());
603 fRatioCrossClusTPC->Fill(track->GetTPCmomentum(), track->GetTPCCrossedRows()/track->GetTPCNclsF());
608 PostData(1, &fListHistos);
609 PostData(2, &fListCF);
610 PostData(3,fEventStat);
613 //_________________________________________________________________________________
614 void AliAnalysisTaskMultiDielectronTG::FinishTaskOutput()
619 TIter nextDie(&fListDielectron);
620 AliDielectron *die=0;
621 while ( (die=static_cast<AliDielectron*>(nextDie())) ){
622 die->SaveDebugTree();
623 AliDielectronMixingHandler *mix=die->GetMixingHandler();
624 // printf("\n\n\n===============\ncall mix in Terminate: %p (%p)\n=================\n\n",mix,die);
625 if (mix) mix->MixRemaining(die);
627 PostData(1, &fListHistos);
628 PostData(2, &fListCF);
631 //_________________________________________________________________________________
632 void AliAnalysisTaskMultiDielectronTG::CheckGhostPairs(vector<AliDielectronSingleTG*> e1)
634 ////// Check whether the pairs are in ghost pairs
635 ///// ghost means that one of the pairs is highly associated but reconstructed as a true particle
640 for(int i1=0; i1<(int)e1.size(); i1++){
642 for(int i2=i1+1; i2<(int)e1.size(); i2++){
643 if( fabs(e1[i1]->Phi() - e1[i2]->Phi())<0.01 &&
644 fabs(e1[i1]->Eta() - e1[i2]->Eta())<0.005
647 e1[i2]->SetGstFlag(0);
650 if(reject==true)e1[i1]->SetGstFlag(0);
655 //_________________________________________________________________________________
656 Bool_t AliAnalysisTaskMultiDielectronTG::CheckGhost(vector<AliDielectronSingleTG*> e1, vector<AliDielectronSingleTG*> e2)
658 ////// To be sure whether there are no ghost pairs in h event mixing
660 if(e1.size()>0 && e2.size()>0){
661 for(int i1=0; i1<(int)e1.size(); i1++){
662 for(int i2=0; i2<(int)e2.size(); i2++){
663 if( fabs(e1[i1]->Phi() - e2[i2]->Phi())<0.01 &&
664 fabs(e1[i1]->Eta() - e2[i2]->Eta())<0.005
674 //_________________________________________________________________________________
675 void AliAnalysisTaskMultiDielectronTG::RandomizePool(vector<AliDielectronSingleTG*> e1, vector<AliDielectronSingleTG*> e2)
678 ///// Randomize the pool constent to cancel the filling scheme of the single tracks
682 int size1 = e1.size();
684 for(int i=0;i<1000;i++){
687 for(int i=0;i<size1;i++){
691 for(int i=0;i<size1;i++){
692 int j = (int)(gRandom->Uniform(0,size1));
693 while(usedindex[j]==1){
694 j = (int)(gRandom->Uniform(0,size1));
696 if( (e1[j]->GetGstFlag()==1) &&
697 (e1[j]->GetConvFlag()==1)
699 fVep.push_back(e1[j]);
705 int size2 = e2.size();
706 for(int i=0;i<1000;i++){
709 for(int i=0;i<size2;i++){
713 for(int i=0;i<size2;i++){
714 int j = (int)(gRandom->Uniform(0,size2));
715 while(usedindex[j]==1){
716 j = (int)(gRandom->Uniform(0,size2));
718 if( (e2[j]->GetGstFlag()==1) &&
719 (e2[j]->GetConvFlag()==1)
721 fVem.push_back(e2[j]);
728 //_________________________________________________________________________________
729 void AliAnalysisTaskMultiDielectronTG::CalcPair(vector<AliDielectronSingleTG*> ve1,
730 vector<AliDielectronSingleTG*> ve2, AliDielectron *die, Int_t idie)
734 // main routine for the pair procesing
738 for(int i1=0; i1<(int)ve1.size(); i1++){
739 for(int i2=0; i2<(int)ve2.size(); i2++){
740 FillPair(ve1[i1], ve2[i2], 0, die, idie);
744 for(int i1=0; i1<(int)ve1.size(); i1++){
745 for(int i2=i1+1; i2<(int)ve1.size(); i2++){
746 FillPair(ve1[i1], ve1[i2], 1, die, idie);
750 for(int i1=0; i1<(int)ve2.size(); i1++){
751 for(int i2=i1+1; i2<(int)ve2.size(); i2++){
752 FillPair(ve2[i1], ve2[i2], 2, die, idie );
757 double dwcent = 100.0/fgkNCENT;
758 double dwiz = 20.0/fgkNZBIN;
759 double dwrp = acos(-1.0)/fgkNRPBIN;
761 int icent = (int)(fgValues[AliDielectronVarManager::kCentrality]/dwcent);
762 int izbin = (int)((fgValues[AliDielectronVarManager::kZvPrim]+10)/dwiz);
763 int irp = (int)((fgValues[AliDielectronVarManager::kV0ACrpH2])/dwrp);
766 if(icent>=fgkNCENT) icent=fgkNCENT-1;
768 if(izbin>=fgkNZBIN) izbin=fgkNZBIN-1;
770 if(irp>=fgkNRPBIN) irp=fgkNRPBIN-1;
775 // Now mixed event for +- pairs
778 for(int ibuf=0;(nmixed<fgkNMix);ibuf++) {
780 while((fBGRejUnlike && CheckGhost(ve1, fvem[ibuf][idie][izbin][icent][irp])) && ntry<fgkMAXTRY) {
781 ReshuffleBuffer(fvem[ibuf][idie][izbin][icent][irp],fpoolm[idie][izbin][icent][irp]);
784 for(int i1=0; i1<(int)ve1.size(); i1++){
785 for(int i2=0; i2<(int)fvem[ibuf][idie][izbin][icent][irp].size(); i2++){
786 FillPair(ve1[i1],fvem[ibuf][idie][izbin][icent][irp][i2], 3, die, idie);
794 // Now mixed event for -+ pairs
797 for(int ibuf=0;(nmixed<fgkNMix);ibuf++) {
799 while((fBGRejUnlike && CheckGhost(ve2, fvep[ibuf][idie][izbin][icent][irp])) && ntry<fgkMAXTRY) {
800 ReshuffleBuffer(fvep[ibuf][idie][izbin][icent][irp],fpoolp[idie][izbin][icent][irp]);
803 for(int i1=0; i1<(int)ve2.size(); i1++){
804 for(int i2=0; i2<(int)fvep[ibuf][idie][izbin][icent][irp].size(); i2++){
805 FillPair(fvep[ibuf][idie][izbin][icent][irp][i2],ve2[i1],4, die, idie);
814 // Now mixed event for ++ pairs
817 for(int ibuf=0;(nmixed<fgkNMix);ibuf++) {
819 while((fBGRejLike && CheckGhost(ve1, fvep[ibuf][idie][izbin][icent][irp])) && ntry<fgkMAXTRY) {
820 ReshuffleBuffer(fvep[ibuf][idie][izbin][icent][irp],fpoolp[idie][izbin][icent][irp]);
823 for(int i1=0; i1<(int)ve1.size(); i1++){
824 for(int i2=0;i2<(int)fvep[ibuf][idie][izbin][icent][irp].size(); i2++){
825 FillPair(ve1[i1],fvep[ibuf][idie][izbin][icent][irp][i2], 5, die, idie);
834 // Now mixed event for +- pairs
837 for(int ibuf=0;(nmixed<fgkNMix);ibuf++) {
839 while((fBGRejLike && CheckGhost(ve2, fvem[ibuf][idie][izbin][icent][irp])) && ntry<fgkMAXTRY) {
840 ReshuffleBuffer(fvem[ibuf][idie][izbin][icent][irp],fpoolm[idie][izbin][icent][irp]);
843 for(int i1=0; i1<(int)ve2.size(); i1++){
844 for(int i2=0; i2<(int)fvem[ibuf][idie][izbin][icent][irp].size(); i2++){
845 FillPair(ve2[i1],fvem[ibuf][idie][izbin][icent][irp][i2],6, die, idie);
855 //_________________________________________________________________________________
856 void AliAnalysisTaskMultiDielectronTG::FillPair(AliDielectronSingleTG *iep,
857 AliDielectronSingleTG *iem, int type, AliDielectron *die, Int_t idie)
861 // main routine for filling kinematics of pairs
866 double dmass, dphiv, dpxpair, dpypair, dpzpair;
867 double dptpair, depair, dphipair, detapair, dcos, dpsi;
869 CalcVars(iep, iem, dmass, dphiv, dpxpair, dpypair, dpzpair,
870 dptpair, depair, dphipair, detapair, dcos, dpsi);
873 double dopeningangle = -9999;
874 double dv0mass = -9999;
875 double dv0pxpair = -9999;
876 double dv0pypair = -9999;
877 double dv0pzpair = -9999;
878 double dv0ptpair = -9999;
879 double dv0epair = -9999;
880 double dv0xvpair = -9999;
881 double dv0yvpair = -9999;
882 double dv0zvpair = -9999;
883 double dv0phipair = -9999;
884 double dv0etapair = -9999;
885 double dv0rpair = -9999;
886 double dpsipair = -9999;
887 double dphivpair = -9999;
889 ////////////////////////////
890 ///// calculate v0 ////////
891 ///////////////////////////
893 /// for the moment, this doesn't work for MC
894 if(fdv0mixing == kFALSE && (type==3 || type==4 || type==5 || type==6)){
897 if(die->GetHasMC()==kTRUE && (type==3 || type==4 || type==5 || type==6)){
900 if(type==0 || type==1 || type==2){
906 AliVTrack* trackob1= iep->GetTrack();
907 AliVTrack* trackob2= iem->GetTrack();
909 if(!trackob1 || !trackob2){
913 AliDielectronPair candidate;
914 candidate.SetTracks(trackob1, (int)(11*iep->Charge()),
915 trackob2, (int)(11*iem->Charge()));
917 if(trackob1==trackob2){
918 AliInfo("Same Objects!!");
922 //const AliKFParticle &kfPairLeg1 = candidate.GetKFFirstDaughter();
923 //const AliKFParticle &kfPairLeg2 = candidate.GetKFSecondDaughter();
925 const AliKFParticle &kfPair = candidate.GetKFParticle();
928 dv0mass = candidate.M();
929 dv0pxpair = candidate.Px();
930 dv0pypair = candidate.Py();
931 dv0pzpair = candidate.Pz();
932 dv0ptpair = candidate.Pt();
933 dv0epair = candidate.E();
934 dv0xvpair = candidate.Xv();
935 dv0yvpair = candidate.Yv();
936 dv0zvpair = candidate.Zv();
937 dv0phipair = candidate.Phi();
938 dv0etapair = candidate.Eta();
940 dv0mass = kfPair.GetMass();
941 dv0pxpair = kfPair.GetPx();
942 dv0pypair = kfPair.GetPy();
943 dv0pzpair = kfPair.GetPz();
944 dv0ptpair = kfPair.GetPt();
945 dv0epair = kfPair.GetE();
946 dv0xvpair = kfPair.GetX();
947 dv0yvpair = kfPair.GetY();
948 dv0zvpair = kfPair.GetZ();
949 dv0phipair = kfPair.GetPhi();
950 dv0etapair = kfPair.GetEta();
951 dv0rpair = kfPair.GetR();
953 dopeningangle = candidate.OpeningAngle();
954 dpsipair = candidate.PsiPair(fbz);
955 dphivpair = candidate.PhivPair(fbz);
960 Double_t values[AliDielectronVarManager::kNMaxValues];
963 className1.Form("MyPair_%s",kPairClassNamesTG[type]);
964 className2.Form("MyPairV0_%s",kPairClassNamesTG[type]);
966 AliDielectronHistos *fHistos = die->GetHistoManager();
967 Bool_t pairClass1=fHistos->GetHistogramList()->FindObject(className1.Data())!=0x0;
968 Bool_t pairClass2=fHistos->GetHistogramList()->FindObject(className2.Data())!=0x0;
970 if (pairClass1 && PairTrackcut(dphiv, dcos, dmass, idie)==true){
971 ///import pair variables to values!!
972 values[AliDielectronVarManager::kPx] = dpxpair;
973 values[AliDielectronVarManager::kPy] = dpypair;
974 values[AliDielectronVarManager::kPz] = dpzpair;
975 values[AliDielectronVarManager::kPt] = dptpair;
976 values[AliDielectronVarManager::kXv] = dv0xvpair;
977 values[AliDielectronVarManager::kYv] = dv0yvpair;
978 values[AliDielectronVarManager::kZv] = dv0zvpair;
979 values[AliDielectronVarManager::kR] = dv0rpair;
980 values[AliDielectronVarManager::kE] = depair;
981 values[AliDielectronVarManager::kEta] = detapair;
982 values[AliDielectronVarManager::kM] = dmass;
983 values[AliDielectronVarManager::kPsiPair] = dphiv;
984 values[AliDielectronVarManager::kPhivPair] = dphiv;
985 values[AliDielectronVarManager::kPhi] = dphipair;
986 values[AliDielectronVarManager::kOpeningAngle] = dcos;
987 values[AliDielectronVarManager::kCosPointingAngle] = TMath::Abs(TMath::ATan2(TMath::Sin(iep->Phi()-iem->Phi()),TMath::Cos(iep->Phi()-iem->Phi())));
988 fHistos->FillClass(className1, AliDielectronVarManager::kNMaxValues, values);
992 if (pairClass2 && PairTrackcut(dphiv, dopeningangle, dv0mass, idie)==true){
993 values[AliDielectronVarManager::kPx] = dv0pxpair;
994 values[AliDielectronVarManager::kPy] = dv0pypair;
995 values[AliDielectronVarManager::kPz] = dv0pzpair;
996 values[AliDielectronVarManager::kPt] = dv0ptpair;
997 values[AliDielectronVarManager::kXv] = dv0xvpair;
998 values[AliDielectronVarManager::kYv] = dv0yvpair;
999 values[AliDielectronVarManager::kZv] = dv0zvpair;
1000 values[AliDielectronVarManager::kR] = dv0rpair;
1001 values[AliDielectronVarManager::kE] = dv0epair;
1002 values[AliDielectronVarManager::kEta] = dv0etapair;
1003 values[AliDielectronVarManager::kM] = dv0mass;
1004 values[AliDielectronVarManager::kPsiPair] = dpsipair;
1005 values[AliDielectronVarManager::kPhivPair] = dphivpair;
1006 values[AliDielectronVarManager::kPhi] = dv0phipair;
1007 values[AliDielectronVarManager::kOpeningAngle] = dopeningangle;
1008 values[AliDielectronVarManager::kCosPointingAngle] = TMath::Abs(TMath::ATan2(TMath::Sin(iep->Phi()-iem->Phi()),TMath::Cos(iep->Phi()-iem->Phi())));
1009 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
1016 //_________________________________________________________________________________
1017 bool AliAnalysisTaskMultiDielectronTG::PairTrackcut(double phiv, double op, double mass, int idie)
1021 // pair-by-pair cuts
1027 if(fRejectPairFlag[idie] == 1 || fRejectPairFlag[idie] == 2 ||
1028 fRejectPairFlag[idie] == 3 || fRejectPairFlag[idie] == 4 ){
1029 if(fRejectPairFlag[idie] == 2 || fRejectPairFlag[idie] == 4 ){
1030 if(fbz>0 && (phiv>fdconvphiv && mass < fdconvMee) ){
1032 }else if(fbz<0 && phiv<acos(-1.0)-fdconvphiv && mass < fdconvMee){
1035 }else if(fRejectPairFlag[idie] == 1 || fRejectPairFlag[idie] == 3){
1047 //_________________________________________________________________________________
1048 void AliAnalysisTaskMultiDielectronTG::CalcVars(AliDielectronSingleTG *iep, AliDielectronSingleTG *iem,
1049 double &mass, double &phiv, double &px, double &py, double&pz,
1050 double &pt, double &e, double &phi,
1051 double &eta, double &cos, double &psi)
1056 // standalone calculator for the pair variables
1059 px = iep->Px()+iem->Px();
1060 py = iep->Py()+iem->Py();
1061 pz = iep->Pz()+iem->Pz();
1062 pt = sqrt(px*px+py*py);
1063 double dppair = sqrt(pt*pt+pz*pz);
1064 static const double me=0.0005109989;
1065 e = sqrt(me*me+iep->Px()*iep->Px()+iep->Py()*iep->Py()+iep->Pz()*iep->Pz())
1066 + sqrt(me*me+iem->Px()*iem->Px()+iem->Py()*iem->Py()+iem->Pz()*iem->Pz());
1068 mass = e*e-px*px-py*py-pz*pz;
1074 phi = atan2(py, px);
1075 eta = -0.5*TMath::Log((dppair+pz)/(dppair-pz));
1076 double p1 = sqrt(pow(iep->Px(),2)+pow(iep->Py(),2)+pow(iep->Pz(),2));
1077 double p2 = sqrt(pow(iem->Px(),2)+pow(iem->Py(),2)+pow(iem->Pz(),2));
1078 cos = acos((iep->Px()*iem->Px()+iep->Py()*iem->Py()+iep->Pz()*iem->Pz())/(p1*p2));
1080 double dtheta = iep->Theta()-iem->Theta();
1081 psi = asin(dtheta/cos);
1084 //unit vector of (pep+pem)
1089 double ax = uy/sqrt(ux*ux+uy*uy);
1090 double ay = -ux/sqrt(ux*ux+uy*uy);
1092 //momentum of e+ and e- in (ax,ay,az) axis. Note that az=0 by
1094 //double ptep = iep->Px()*ax + iep->Py()*ay;
1095 //double ptem = iem->Px()*ax + iem->Py()*ay;
1097 double pxep = iep->Px();
1098 double pyep = iep->Py();
1099 double pzep = iep->Pz();
1100 double pxem = iem->Px();
1101 double pyem = iem->Py();
1102 double pzem = iem->Pz();
1105 //vector product of pep X pem
1106 double vpx = pyep*pzem - pzep*pyem;
1107 double vpy = pzep*pxem - pxep*pzem;
1108 double vpz = pxep*pyem - pyep*pxem;
1109 double vp = sqrt(vpx*vpx+vpy*vpy+vpz*vpz);
1110 //double thev = acos(vpz/vp);
1112 //unit vector of pep X pem
1117 //The third axis defined by vector product (ux,uy,uz)X(vx,vy,vz)
1118 double wx = uy*vz - uz*vy;
1119 double wy = uz*vx - ux*vz;
1120 double wz = ux*vy - uy*vx;
1121 double wl = sqrt(wx*wx+wy*wy+wz*wz);
1122 // by construction, (wx,wy,wz) must be a unit vector.
1123 if(fabs(wl - 1.0) > 0.00001) std::cout << "Calculation error in W vector"<<std::endl;
1124 // measure angle between (wx,wy,wz) and (ax,ay,0). The angle between them
1125 // should be small if the pair is conversion
1127 double cosPhiV = wx*ax + wy*ay;
1128 phiv = acos(cosPhiV);
1132 //_________________________________________________________________________________
1133 void AliAnalysisTaskMultiDielectronTG::ReshuffleBuffer(vector<AliDielectronSingleTG*> ve, deque<AliDielectronSingleTG*> pool)
1135 //If there is not enough electron in the pool, give up
1137 // ReshuffleBuffer for th event mixing
1140 unsigned int ne = ve.size();
1141 unsigned int poolsize = pool.size();
1142 int used[fgkMAXPOOL];
1143 for(int i=0;i<(int)fgkMAXPOOL;i++){
1148 std::cout <<" pool size="<<poolsize<<" ne"<<ne<<std::endl;
1151 for(unsigned int ie=0; ie < ne; ie++) {
1152 int j = rand()%poolsize;
1154 j = rand()%poolsize;
1162 //_________________________________________________________________________________
1163 void AliAnalysisTaskMultiDielectronTG::RejectPairs(vector<AliDielectronSingleTG*> e1, vector<AliDielectronSingleTG*> e2, Int_t idie){
1165 ////////////////////////////////////
1166 ///// to reject pairs from track arrays
1167 ///// conversions, ghost ..
1168 ///////////////////////////////////
1169 if(e1.size()>0 && e2.size()>0){
1170 for(int i1=0; i1<(int)e1.size(); i1++){
1171 for(int i2=0; i2<(int)e2.size(); i2++){
1172 if(fRejectPairFlag[idie]==1){
1173 Double_t cosine = GetOpeningAngle(e1[i1], e2[i2]);
1175 e1[i1]->SetConvFlag(0);
1176 e2[i2]->SetConvFlag(0);
1178 }else if(fRejectPairFlag[idie]==2){
1179 Double_t phiv = GetPhiv(e1[i1], e2[i2]);
1180 Double_t mee = GetMass(e1[i1], e2[i2]);
1181 if(fbz>0 && ( phiv>fdconvphiv && mee < fdconvMee) ){
1182 e1[i1]->SetConvFlag(0);
1183 e2[i2]->SetConvFlag(0);
1184 }else if(fbz<0 && phiv<acos(-1.0)-fdconvphiv && mee < fdconvMee){
1185 e1[i1]->SetConvFlag(0);
1186 e2[i2]->SetConvFlag(0);
1193 for(int i1=0; i1<(int)e1.size(); i1++){
1194 for(int i2=i1+1; i2<(int)e1.size(); i2++){
1195 if(fRejectPairFlag[idie]==1){
1196 Double_t cosine = GetOpeningAngle(e1[i1], e1[i2]);
1198 e1[i1]->SetConvFlag(0);
1199 e1[i2]->SetConvFlag(0);
1201 }else if(fRejectPairFlag[idie]==2){
1202 Double_t phiv = GetPhiv(e1[i1], e1[i2]);
1203 Double_t mee = GetMass(e1[i1], e1[i2]);
1204 if(fbz>0 && phiv>fdconvphiv && mee < fdconvMee){
1205 e1[i1]->SetConvFlag(0);
1206 e1[i2]->SetConvFlag(0);
1207 }else if(fbz<0 && phiv<acos(-1.0)-fdconvphiv && mee < fdconvMee){
1208 e1[i1]->SetConvFlag(0);
1209 e1[i2]->SetConvFlag(0);
1217 for(int i1=0; i1<(int)e2.size(); i1++){
1218 for(int i2=i1+1; i2<(int)e2.size(); i2++){
1219 if(fRejectPairFlag[idie]==1){
1220 Double_t cosine = GetOpeningAngle(e2[i1], e2[i2]);
1222 e2[i1]->SetConvFlag(0);
1223 e2[i2]->SetConvFlag(0);
1225 }else if(fRejectPairFlag[idie]==2){
1226 Double_t phiv = GetPhiv(e2[i1], e2[i2]);
1227 Double_t mee = GetMass(e2[i1], e2[i2]);
1228 if(fbz>0 && phiv>fdconvphiv && mee < fdconvMee){
1229 e2[i1]->SetConvFlag(0);
1230 e2[i2]->SetConvFlag(0);
1231 }else if(fbz<0 && phiv<acos(-1.0)-fdconvphiv && mee < fdconvMee){
1232 e2[i1]->SetConvFlag(0);
1233 e2[i2]->SetConvFlag(0);
1242 //_________________________________________________________________________________
1243 Double_t AliAnalysisTaskMultiDielectronTG::GetOpeningAngle(AliDielectronSingleTG* e1, AliDielectronSingleTG* e2){
1245 //////////////////////
1246 //////// calculate pairs and get opening angle
1247 //////////////////////
1249 double dmass, dphiv, dpxpair, dpypair, dpzpair;
1250 double dptpair, depair, dphipair, detapair, dcos, dpsi;
1252 CalcVars(e1, e2, dmass, dphiv, dpxpair, dpypair, dpzpair,
1253 dptpair, depair, dphipair, detapair, dcos, dpsi);
1258 //_________________________________________________________________________________
1259 Double_t AliAnalysisTaskMultiDielectronTG::GetPhiv(AliDielectronSingleTG* e1, AliDielectronSingleTG* e2){
1261 //////////////////////
1262 //////// calculate pairs and get phiv
1263 //////////////////////
1265 double dmass, dphiv, dpxpair, dpypair, dpzpair;
1266 double dptpair, depair, dphipair, detapair, dcos, dpsi;
1268 CalcVars(e1, e2, dmass, dphiv, dpxpair, dpypair, dpzpair,
1269 dptpair, depair, dphipair, detapair, dcos, dpsi);
1274 //_________________________________________________________________________________
1275 Double_t AliAnalysisTaskMultiDielectronTG::GetMass(AliDielectronSingleTG* e1, AliDielectronSingleTG* e2){
1277 //////////////////////
1278 //////// calculate pairs and get mass
1279 //////////////////////
1281 double dmass, dphiv, dpxpair, dpypair, dpzpair;
1282 double dptpair, depair, dphipair, detapair, dcos, dpsi;
1284 CalcVars(e1, e2, dmass, dphiv, dpxpair, dpypair, dpzpair,
1285 dptpair, depair, dphipair, detapair, dcos, dpsi);