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)),
104 fBGRejUnlike(kFALSE),
112 //_________________________________________________________________________________
113 AliAnalysisTaskMultiDielectronTG::AliAnalysisTaskMultiDielectronTG(const char *name) :
114 AliAnalysisTaskSE(name),
119 fSelectPhysics(kFALSE),
120 fTriggerMask(AliVEvent::kMB),
121 fExcludeTriggerMask(0),
122 fTriggerOnV0AND(kFALSE),
123 fRejectPileup(kFALSE),
125 fTriggerAnalysis(0x0),
131 fdEdXnSigmaElecvsPt(0x0),
133 fdEdXnSigmaElecvsPtTOF(0x0),
135 fTOFnSigmaElecvsPt(0x0),
136 fNCrossedRowsTPC(0x0),
138 fRatioCrossClusTPC(0x0),
143 fdconvphiv(acos(-1.0)),
147 fBGRejUnlike(kFALSE),
153 DefineInput(0,TChain::Class());
154 DefineOutput(1, TList::Class());
155 DefineOutput(2, TList::Class());
156 DefineOutput(3, TH1D::Class());
157 fListHistos.SetName("Dielectron_Histos_Multi");
158 fListCF.SetName("Dielectron_CF_Multi");
159 fListDielectron.SetOwner();
160 fListHistos.SetOwner();
164 for(int i=0;i<fgkNDIE; i++){
165 for(int j=0;j<fgkNZBIN;j++){
166 for(int k=0;k<fgkNCENT;k++){
167 for(int l=0; l<fgkNRPBIN; l++){
168 fibuf[i][j][k][l] = 0;
169 fpoolp[i][j][k][l].clear();
170 fpoolm[i][j][k][l].clear();
171 for(int ib=0;ib<fgkNBUF; ib++){
172 fvep[ib][i][j][k][l].clear();
173 fvem[ib][i][j][k][l].clear();
184 //_________________________________________________________________________________
185 AliAnalysisTaskMultiDielectronTG::~AliAnalysisTaskMultiDielectronTG()
191 //histograms and CF are owned by the dielectron framework.
192 //however they are streamed to file, so in the first place the
193 //lists need to be owner...
194 fListHistos.SetOwner(kFALSE);
195 fListCF.SetOwner(kFALSE);
197 for(int i=0;i<fgkNDIE; i++){
198 for(int j=0;j<fgkNZBIN;j++){
199 for(int k=0;k<fgkNCENT;k++){
200 for(int l=0; l<fgkNRPBIN; l++){
201 fibuf[i][j][k][l] = 0;
202 fpoolp[i][j][k][l].clear();
203 fpoolm[i][j][k][l].clear();
204 for(int ib=0;ib<fgkNBUF; ib++){
205 fvep[ib][i][j][k][l].clear();
206 fvem[ib][i][j][k][l].clear();
213 //_________________________________________________________________________________
214 void AliAnalysisTaskMultiDielectronTG::UserCreateOutputObjects()
217 // Add all histogram manager histogram lists to the output TList
220 if (!fListHistos.IsEmpty()||!fListCF.IsEmpty()) return; //already initialised
222 // AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();
223 // Bool_t isESD=man->GetInputEventHandler()->IsA()==AliESDInputHandler::Class();
224 // Bool_t isAOD=man->GetInputEventHandler()->IsA()==AliAODInputHandler::Class();
226 TIter nextDie(&fListDielectron);
227 AliDielectron *die=0;
228 while ( (die=static_cast<AliDielectron*>(nextDie())) ){
230 if (die->GetHistogramList()) fListHistos.Add(const_cast<THashList*>(die->GetHistogramList()));
231 if (die->GetCFManagerPair()) fListCF.Add(const_cast<AliCFContainer*>(die->GetCFManagerPair()->GetContainer()));
234 Int_t cuts=fListDielectron.GetEntries();
235 Int_t nbins=kNbinsEvent+2*cuts;
237 fEventStat=new TH1D("hEventStat","Event statistics",nbins,0,nbins);
238 fEventStat->GetXaxis()->SetBinLabel(1,"Before Phys. Sel.");
239 fEventStat->GetXaxis()->SetBinLabel(2,"After Phys. Sel.");
242 fEventStat->GetXaxis()->SetBinLabel(3,"Bin3 not used");
243 fEventStat->GetXaxis()->SetBinLabel(4,"Bin4 not used");
244 fEventStat->GetXaxis()->SetBinLabel(5,"Bin5 not used");
246 if(fTriggerOnV0AND) fEventStat->GetXaxis()->SetBinLabel(3,"V0and triggers");
247 if (fEventFilter) fEventStat->GetXaxis()->SetBinLabel(4,"After Event Filter");
248 if (fRejectPileup) fEventStat->GetXaxis()->SetBinLabel(5,"After Pileup rejection");
250 for (Int_t i=0; i<cuts; ++i){
251 fEventStat->GetXaxis()->SetBinLabel((kNbinsEvent+1)+2*i,Form("#splitline{1 candidate}{%s}",fListDielectron.At(i)->GetName()));
252 fEventStat->GetXaxis()->SetBinLabel((kNbinsEvent+2)+2*i,Form("#splitline{With >1 candidate}{%s}",fListDielectron.At(i)->GetName()));
256 if (!fTriggerAnalysis) fTriggerAnalysis=new AliTriggerAnalysis;
257 fTriggerAnalysis->EnableHistograms();
258 fTriggerAnalysis->SetAnalyzeMC(AliDielectronMC::Instance()->HasMC());
265 float binw = (TMath::Log(maxx)-TMath::Log(minx))/nbinx;
267 for(int ii=0;ii<nbinx+1;ii++){
268 xbin[ii] = TMath::Exp(TMath::Log(minx) + 0.5*binw+binw*ii);
272 fQAElectron = new TList();
273 fQAElectron->SetName("QAElectron");
274 fQAElectron->SetOwner();
277 fEvent = new TH1D("Event","centrality", 100,0,100);
278 fQAElectron->Add(fEvent);
279 fdEdXvsPt = new TH2D("dEdXvsPt","dE/dX vs. PT of TPC", nbinx, xbin, 2000,0,200);
280 fQAElectron->Add(fdEdXvsPt);
281 fdEdXnSigmaElecvsPt = new TH2D("fdEdXnSigmaElecvsPt"," dE/dX normalized to electron vs. pT of TPC",
282 nbinx, xbin, 2000, -10, 10);
283 fQAElectron->Add(fdEdXnSigmaElecvsPt);
285 fdEdXvsPtTOF = new TH2D("dEdXvsPtTOF","dE/dX vs. PT of TPC", nbinx, xbin, 2000,0,200);
286 fQAElectron->Add(fdEdXvsPtTOF);
287 fdEdXnSigmaElecvsPtTOF = new TH2D("fdEdXnSigmaElecvsPtTOF"," dE/dX normalized to electron vs. pT of TPC",
288 nbinx, xbin, 2000, -10, 10);
289 fQAElectron->Add(fdEdXnSigmaElecvsPtTOF);
293 fTOFbetavsPt = new TH2D("fTOFbetavsPt","TOF beta vs. p", 400, 0, 20, 1200, 0, 1.2);
294 fQAElectron->Add(fTOFbetavsPt);
295 fTOFnSigmaElecvsPt = new TH2D("fTOFnSigmaElecvsPt","TOF nsigma for electron", 400, 0, 20, 2000, -10, 10);
296 fQAElectron->Add(fTOFnSigmaElecvsPt);
298 fNCrossedRowsTPC = new TH2F("fNCrossedRowsTPC", "TPC nCrossed Rows vs. pT", 200, 0, 20, 200, 0, 200);
299 fQAElectron->Add(fNCrossedRowsTPC);
300 fChi2ClusTPC = new TH2F("fChi2ClusTPC", "hChi2ClusTPC vs. pT", 200, 0, 20, 200, 0, 10);
301 fQAElectron->Add(fChi2ClusTPC);
303 fRatioCrossClusTPC = new TH2F("fRatioCrossClusTPC", "hRatioCrossClusTPC vs. pT", 200, 0, 20, 200, 0, 10);
304 fQAElectron->Add(fRatioCrossClusTPC);
306 fListHistos.Add(fQAElectron);
308 fListHistos.SetOwner();
310 PostData(1, &fListHistos);
311 PostData(2, &fListCF);
312 PostData(3, fEventStat);
314 fCutsMother = new AliESDtrackCuts;
315 fCutsMother->SetDCAToVertex2D(kTRUE);
316 fCutsMother->SetMaxDCAToVertexZ(3.0);
317 fCutsMother->SetMaxDCAToVertexXY(1.0);
318 fCutsMother->SetPtRange( 0.05 , 200.0);
319 fCutsMother->SetEtaRange( -0.84 , 0.84 );
320 fCutsMother->SetAcceptKinkDaughters(kFALSE);
321 fCutsMother->SetRequireITSRefit(kTRUE);
322 fCutsMother->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kFirst);
323 fCutsMother->SetMinNClustersITS(3);
324 fCutsMother->SetRequireTPCRefit(kTRUE);
327 AliInfo(Form("PairCutType = %d %d %d %d %d",
332 fRejectPairFlag[4]));
336 //_________________________________________________________________________________
337 void AliAnalysisTaskMultiDielectronTG::UserExec(Option_t *)
340 // Main loop. Called for every event
343 if (fListHistos.IsEmpty()&&fListCF.IsEmpty()) return;
345 AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();
346 Bool_t isESD=man->GetInputEventHandler()->IsA()==AliESDInputHandler::Class();
347 Bool_t isAOD=man->GetInputEventHandler()->IsA()==AliAODInputHandler::Class();
349 AliInputEventHandler* inputHandler = (AliInputEventHandler*) (man->GetInputEventHandler());
350 if (!inputHandler) return;
352 // AliPIDResponse *pidRes=inputHandler->GetPIDResponse();
353 if ( inputHandler->GetPIDResponse() ){
354 // for the 2.76 pass2 MC private train. Together with a sigma shift of -0.169
355 // pidRes->GetTPCResponse().SetSigma(4.637e-3,2.41332105409873257e+04);
356 AliDielectronVarManager::SetPIDResponse( inputHandler->GetPIDResponse() );
358 AliFatal("This task needs the PID response attached to the input event handler!");
361 // Was event selected ?
362 ULong64_t isSelected = AliVEvent::kAny;
363 Bool_t isRejected = kFALSE;
364 if( fSelectPhysics && inputHandler){
365 if((isESD && inputHandler->GetEventSelection()) || isAOD){
366 isSelected = inputHandler->IsEventSelected();
367 if (fExcludeTriggerMask && (isSelected&fExcludeTriggerMask)) isRejected=kTRUE;
368 if (fTriggerLogic==kAny) isSelected&=fTriggerMask;
369 else if (fTriggerLogic==kExact) isSelected=((isSelected&fTriggerMask)==fTriggerMask);
374 //Before physics selection
375 fEventStat->Fill(kAllEvents);
376 if (isSelected==0||isRejected) {
377 PostData(3,fEventStat);
380 //after physics selection
381 fEventStat->Fill(kSelectedEvents);
385 if(isESD){if (!fTriggerAnalysis->IsOfflineTriggerFired(static_cast<AliESDEvent*>(InputEvent()), AliTriggerAnalysis::kV0AND))
387 if(isAOD){if(!((static_cast<AliAODEvent*>(InputEvent()))->GetVZEROData()->GetV0ADecision() == AliVVZERO::kV0BB &&
388 (static_cast<AliAODEvent*>(InputEvent()))->GetVZEROData()->GetV0CDecision() == AliVVZERO::kV0BB) )
393 fEventStat->Fill(kV0andEvents);
395 //Fill Event histograms before the event filter
396 TIter nextDie(&fListDielectron);
397 AliDielectron *die=0;
398 Double_t values[AliDielectronVarManager::kNMaxValues]={0};
399 Double_t valuesMC[AliDielectronVarManager::kNMaxValues]={0};
400 AliDielectronVarManager::SetEvent(InputEvent());
401 AliDielectronVarManager::Fill(InputEvent(),values);
402 AliDielectronVarManager::Fill(InputEvent(),valuesMC);
403 Bool_t hasMC=AliDielectronMC::Instance()->HasMC();
405 if (AliDielectronMC::Instance()->ConnectMCEvent())
406 AliDielectronVarManager::Fill(AliDielectronMC::Instance()->GetMCEvent(),valuesMC);
409 while ( (die=static_cast<AliDielectron*>(nextDie())) ){
410 AliDielectronHistos *h=die->GetHistoManager();
412 if (h->GetHistogramList()->FindObject("Event_noCuts"))
413 h->FillClass("Event_noCuts",AliDielectronVarManager::kNMaxValues,values);
414 if (hasMC && h->GetHistogramList()->FindObject("MCEvent_noCuts"))
415 h->FillClass("Event_noCuts",AliDielectronVarManager::kNMaxValues,valuesMC);
422 if (!fEventFilter->IsSelected(InputEvent())) return;
424 fEventStat->Fill(kFilteredEvents);
428 if (InputEvent()->IsPileupFromSPD(3,0.8,3.,2.,5.)) return;
430 fEventStat->Fill(kPileupEvents);
433 fbz = InputEvent()->GetMagneticField();
434 AliKFParticle::SetField( fbz );
435 AliDielectronPID::SetCorrVal((Double_t)InputEvent()->GetRunNumber());
437 //Process event in all AliDielectron instances
438 // TIter nextDie(&fListDielectron);
439 // AliDielectron *die=0;
441 while ( (die=static_cast<AliDielectron*>(nextDie())) ){
442 //AliInfo(Form(" **************** die->Process(InputEvent()) : %d **************************", idie));
443 die->SetDontClearArrays(kTRUE);
444 die->Process(InputEvent());
445 if (die->HasCandidates()){
446 Int_t ncandidates=die->GetPairArray(1)->GetEntriesFast();
447 if (ncandidates==1) fEventStat->Fill((kNbinsEvent)+2*idie);
448 else if (ncandidates>1) fEventStat->Fill((kNbinsEvent+1)+2*idie);
452 AliDielectronVarManager::Fill(InputEvent(), fgValues);
453 for (Int_t ii=0; ii<2; ++ii){
454 TObjArray *obj = (TObjArray*)die->GetTrackArray(ii);
455 Int_t ntracks=obj->GetEntriesFast();
456 //AliInfo(Form(" ************** # of tracks = %d", ntracks));
457 for (Int_t itrack=0; itrack<ntracks; ++itrack){
459 ////////////////////////////////////////////////////////////////////
460 AliDielectronVarManager::Fill(obj->UncheckedAt(itrack), fgValues);
461 ////////////////////////////////////////////////////////////////////
463 if(fgValues[AliDielectronVarManager::kCharge]>0){
464 fVeptmp.push_back(new AliDielectronSingleTG(1,
465 fgValues[AliDielectronVarManager::kCentrality],
466 fgValues[AliDielectronVarManager::kXv],
467 fgValues[AliDielectronVarManager::kYv],
468 fgValues[AliDielectronVarManager::kZv],
469 fgValues[AliDielectronVarManager::kPx],
470 fgValues[AliDielectronVarManager::kPy],
471 fgValues[AliDielectronVarManager::kPz],
472 fgValues[AliDielectronVarManager::kPt],
473 fgValues[AliDielectronVarManager::kEta],
474 fgValues[AliDielectronVarManager::kPhi],
475 fgValues[AliDielectronVarManager::kTheta],
476 1, 1, static_cast<AliVTrack*>(obj->UncheckedAt(itrack)))
478 }else if(fgValues[AliDielectronVarManager::kCharge]<0){
479 fVemtmp.push_back(new AliDielectronSingleTG(-1,
480 fgValues[AliDielectronVarManager::kCentrality],
481 fgValues[AliDielectronVarManager::kXv],
482 fgValues[AliDielectronVarManager::kYv],
483 fgValues[AliDielectronVarManager::kZv],
484 fgValues[AliDielectronVarManager::kPx],
485 fgValues[AliDielectronVarManager::kPy],
486 fgValues[AliDielectronVarManager::kPz],
487 fgValues[AliDielectronVarManager::kPt],
488 fgValues[AliDielectronVarManager::kEta],
489 fgValues[AliDielectronVarManager::kPhi],
490 fgValues[AliDielectronVarManager::kTheta],
491 1, 1, static_cast<AliVTrack*>(obj->UncheckedAt(itrack)))
496 //AliInfo(Form("size of e and p = %d %d", (int)fVeptmp.size(), (int)fVemtmp.size()));
499 CheckGhostPairs(fVeptmp);
500 CheckGhostPairs(fVemtmp);
501 if(fRejectPairFlag[idie]==1 || fRejectPairFlag[idie]==2){
502 RejectPairs(fVeptmp, fVemtmp, idie);
504 RandomizePool(fVeptmp, fVemtmp);
505 CalcPair(fVep, fVem, die, idie);
507 // AliInfo(Form("size of e and p (after) = %d %d", (int)fVep.size(), (int)fVem.size()));
509 double dwcent = 100.0/fgkNCENT;
510 double dwiz = 20.0/fgkNZBIN;
511 double dwrp = acos(-1.0)/fgkNRPBIN;
513 int icent = (int)(fgValues[AliDielectronVarManager::kCentrality]/dwcent);
514 int izbin = (int)((fgValues[AliDielectronVarManager::kZvPrim]+10)/dwiz);
515 int irp = (int)((fgValues[AliDielectronVarManager::kV0ACrpH2])/dwrp);
518 if(icent>=fgkNCENT) icent=fgkNCENT-1;
520 if(izbin>=fgkNZBIN) izbin=fgkNZBIN-1;
522 if(irp>=fgkNRPBIN) irp=fgkNRPBIN-1;
524 fvep[fibuf[idie][izbin][icent][irp]][idie][izbin][icent][irp].clear();
525 for(int iep = 0; iep<(int)fVep.size();iep++) {
526 fvep[fibuf[idie][izbin][icent][irp]][idie][izbin][icent][irp].push_back(fVep[iep]);
527 fpoolp[idie][izbin][icent][irp].push_back(fVep[iep]);
528 if(fpoolp[idie][izbin][icent][irp].size()>fgkMAXPOOL) {
529 fpoolp[idie][izbin][icent][irp].pop_front();
532 fvem[fibuf[idie][izbin][icent][irp]][idie][izbin][icent][irp].clear();
533 for(int iem = 0; iem<(int)fVem.size();iem++) {
534 fvem[fibuf[idie][izbin][icent][irp]][idie][izbin][icent][irp].push_back(fVem[iem]);
535 fpoolm[idie][izbin][icent][irp].push_back(fVem[iem]);
536 if(fpoolm[idie][izbin][icent][irp].size()>fgkMAXPOOL) {
537 fpoolm[idie][izbin][icent][irp].pop_front();
542 fibuf[idie][izbin][icent][irp]++;
543 if(fibuf[idie][izbin][icent][irp]>= fgkNBUF) fibuf[idie][izbin][icent][irp]=0;
556 AliESDEvent *fESD = dynamic_cast<AliESDEvent*>(InputEvent());
557 fEvent->Fill(values[AliDielectronVarManager::kCentrality]);
558 for (Int_t iTracks = 0; iTracks < fESD->GetNumberOfTracks(); iTracks++) {
559 AliESDtrack* track = fESD->GetTrack(iTracks);
561 Printf("ERROR: Could not receive track %d", iTracks);
564 if(!fCutsMother->AcceptTrack(track)) continue;
565 fdEdXvsPt->Fill(track->GetTPCmomentum(), track->GetTPCsignal());
566 fdEdXnSigmaElecvsPt->Fill(track->GetTPCmomentum(),
567 AliDielectronVarManager::GetPIDResponse()->NumberOfSigmasTPC(track,
569 -AliDielectronPID::GetCorrVal());
570 /// for beta caliculaton
571 Double_t l = track->GetIntegratedLength(); // cm
572 Double_t t = track->GetTOFsignal();
573 Double_t t0 = AliDielectronVarManager::GetPIDResponse()->GetTOFResponse().GetTimeZero(); // ps
575 if( (l < 360. || l > 800.) || (t <= 0.) || (t0 >999990.0) ) {
579 t -= t0; // subtract the T0
581 t *= 1e-12; //ps -> s
584 beta = v / TMath::C();
587 fTOFbetavsPt->Fill(track->GetTPCmomentum(), beta);
588 fTOFnSigmaElecvsPt->Fill(track->GetTPCmomentum(),
589 AliDielectronVarManager::GetPIDResponse()->NumberOfSigmasTOF(track,
591 ////rough PID is required
592 if( fabs(AliDielectronVarManager::GetPIDResponse()->NumberOfSigmasTOF(track, AliPID::kElectron))<3){
593 fdEdXvsPtTOF->Fill(track->GetTPCmomentum(), track->GetTPCsignal());
594 fdEdXnSigmaElecvsPtTOF->Fill(track->GetTPCmomentum(),
595 AliDielectronVarManager::GetPIDResponse()->NumberOfSigmasTPC(track,
597 -AliDielectronPID::GetCorrVal());
600 if(track->GetTPCsignal()>70 && track->GetTPCsignal()<90){
601 fNCrossedRowsTPC->Fill(track->GetTPCmomentum(), track->GetTPCCrossedRows());
602 //fChi2ClusTPC->Fill(track->GetTPCmomentum(), track->GetTPCchi2()/track->GetTPCNcls());
603 fChi2ClusTPC->Fill(track->GetTPCmomentum(), track->GetTPCchi2());
604 fRatioCrossClusTPC->Fill(track->GetTPCmomentum(), track->GetTPCCrossedRows()/track->GetTPCNclsF());
609 PostData(1, &fListHistos);
610 PostData(2, &fListCF);
611 PostData(3,fEventStat);
614 //_________________________________________________________________________________
615 void AliAnalysisTaskMultiDielectronTG::FinishTaskOutput()
620 TIter nextDie(&fListDielectron);
621 AliDielectron *die=0;
622 while ( (die=static_cast<AliDielectron*>(nextDie())) ){
623 die->SaveDebugTree();
624 AliDielectronMixingHandler *mix=die->GetMixingHandler();
625 // printf("\n\n\n===============\ncall mix in Terminate: %p (%p)\n=================\n\n",mix,die);
626 if (mix) mix->MixRemaining(die);
628 PostData(1, &fListHistos);
629 PostData(2, &fListCF);
632 //_________________________________________________________________________________
633 void AliAnalysisTaskMultiDielectronTG::CheckGhostPairs(vector<AliDielectronSingleTG*> e1)
635 ////// Check whether the pairs are in ghost pairs
636 ///// ghost means that one of the pairs is highly associated but reconstructed as a true particle
641 for(int i1=0; i1<(int)e1.size(); i1++){
643 for(int i2=i1+1; i2<(int)e1.size(); i2++){
644 if( fabs(e1[i1]->Phi() - e1[i2]->Phi())<0.01 &&
645 fabs(e1[i1]->Eta() - e1[i2]->Eta())<0.005
648 e1[i2]->SetGstFlag(0);
651 if(reject==true)e1[i1]->SetGstFlag(0);
656 //_________________________________________________________________________________
657 Bool_t AliAnalysisTaskMultiDielectronTG::CheckGhost(vector<AliDielectronSingleTG*> e1, vector<AliDielectronSingleTG*> e2)
659 ////// To be sure whether there are no ghost pairs in h event mixing
661 if(e1.size()>0 && e2.size()>0){
662 for(int i1=0; i1<(int)e1.size(); i1++){
663 for(int i2=0; i2<(int)e2.size(); i2++){
664 if( fabs(e1[i1]->Phi() - e2[i2]->Phi())<0.01 &&
665 fabs(e1[i1]->Eta() - e2[i2]->Eta())<0.005
675 //_________________________________________________________________________________
676 void AliAnalysisTaskMultiDielectronTG::RandomizePool(vector<AliDielectronSingleTG*> e1, vector<AliDielectronSingleTG*> e2)
679 ///// Randomize the pool constent to cancel the filling scheme of the single tracks
683 int size1 = e1.size();
685 for(int i=0;i<1000;i++){
688 for(int i=0;i<size1;i++){
692 for(int i=0;i<size1;i++){
693 int j = (int)(gRandom->Uniform(0,size1));
694 while(usedindex[j]==1){
695 j = (int)(gRandom->Uniform(0,size1));
697 if( (e1[j]->GetGstFlag()==1) &&
698 (e1[j]->GetConvFlag()==1)
700 fVep.push_back(e1[j]);
706 int size2 = e2.size();
707 for(int i=0;i<1000;i++){
710 for(int i=0;i<size2;i++){
714 for(int i=0;i<size2;i++){
715 int j = (int)(gRandom->Uniform(0,size2));
716 while(usedindex[j]==1){
717 j = (int)(gRandom->Uniform(0,size2));
719 if( (e2[j]->GetGstFlag()==1) &&
720 (e2[j]->GetConvFlag()==1)
722 fVem.push_back(e2[j]);
729 //_________________________________________________________________________________
730 void AliAnalysisTaskMultiDielectronTG::CalcPair(vector<AliDielectronSingleTG*> ve1,
731 vector<AliDielectronSingleTG*> ve2, AliDielectron *die, Int_t idie)
735 // main routine for the pair procesing
739 for(int i1=0; i1<(int)ve1.size(); i1++){
740 for(int i2=0; i2<(int)ve2.size(); i2++){
741 FillPair(ve1[i1], ve2[i2], 0, die, idie);
745 for(int i1=0; i1<(int)ve1.size(); i1++){
746 for(int i2=i1+1; i2<(int)ve1.size(); i2++){
747 FillPair(ve1[i1], ve1[i2], 1, die, idie);
751 for(int i1=0; i1<(int)ve2.size(); i1++){
752 for(int i2=i1+1; i2<(int)ve2.size(); i2++){
753 FillPair(ve2[i1], ve2[i2], 2, die, idie );
758 double dwcent = 100.0/fgkNCENT;
759 double dwiz = 20.0/fgkNZBIN;
760 double dwrp = acos(-1.0)/fgkNRPBIN;
762 int icent = (int)(fgValues[AliDielectronVarManager::kCentrality]/dwcent);
763 int izbin = (int)((fgValues[AliDielectronVarManager::kZvPrim]+10)/dwiz);
764 int irp = (int)((fgValues[AliDielectronVarManager::kV0ACrpH2])/dwrp);
767 if(icent>=fgkNCENT) icent=fgkNCENT-1;
769 if(izbin>=fgkNZBIN) izbin=fgkNZBIN-1;
771 if(irp>=fgkNRPBIN) irp=fgkNRPBIN-1;
776 // Now mixed event for +- pairs
779 for(int ibuf=0;(nmixed<fgkNMix);ibuf++) {
781 while((fBGRejUnlike && CheckGhost(ve1, fvem[ibuf][idie][izbin][icent][irp])) && ntry<fgkMAXTRY) {
782 ReshuffleBuffer(fvem[ibuf][idie][izbin][icent][irp],fpoolm[idie][izbin][icent][irp]);
785 for(int i1=0; i1<(int)ve1.size(); i1++){
786 for(int i2=0; i2<(int)fvem[ibuf][idie][izbin][icent][irp].size(); i2++){
787 FillPair(ve1[i1],fvem[ibuf][idie][izbin][icent][irp][i2], 3, die, idie);
795 // Now mixed event for -+ pairs
798 for(int ibuf=0;(nmixed<fgkNMix);ibuf++) {
800 while((fBGRejUnlike && CheckGhost(ve2, fvep[ibuf][idie][izbin][icent][irp])) && ntry<fgkMAXTRY) {
801 ReshuffleBuffer(fvep[ibuf][idie][izbin][icent][irp],fpoolp[idie][izbin][icent][irp]);
804 for(int i1=0; i1<(int)ve2.size(); i1++){
805 for(int i2=0; i2<(int)fvep[ibuf][idie][izbin][icent][irp].size(); i2++){
806 FillPair(fvep[ibuf][idie][izbin][icent][irp][i2],ve2[i1],4, die, idie);
815 // Now mixed event for ++ pairs
818 for(int ibuf=0;(nmixed<fgkNMix);ibuf++) {
820 while((fBGRejLike && CheckGhost(ve1, fvep[ibuf][idie][izbin][icent][irp])) && ntry<fgkMAXTRY) {
821 ReshuffleBuffer(fvep[ibuf][idie][izbin][icent][irp],fpoolp[idie][izbin][icent][irp]);
824 for(int i1=0; i1<(int)ve1.size(); i1++){
825 for(int i2=0;i2<(int)fvep[ibuf][idie][izbin][icent][irp].size(); i2++){
826 FillPair(ve1[i1],fvep[ibuf][idie][izbin][icent][irp][i2], 5, die, idie);
835 // Now mixed event for +- pairs
838 for(int ibuf=0;(nmixed<fgkNMix);ibuf++) {
840 while((fBGRejLike && CheckGhost(ve2, fvem[ibuf][idie][izbin][icent][irp])) && ntry<fgkMAXTRY) {
841 ReshuffleBuffer(fvem[ibuf][idie][izbin][icent][irp],fpoolm[idie][izbin][icent][irp]);
844 for(int i1=0; i1<(int)ve2.size(); i1++){
845 for(int i2=0; i2<(int)fvem[ibuf][idie][izbin][icent][irp].size(); i2++){
846 FillPair(ve2[i1],fvem[ibuf][idie][izbin][icent][irp][i2],6, die, idie);
856 //_________________________________________________________________________________
857 void AliAnalysisTaskMultiDielectronTG::FillPair(AliDielectronSingleTG *iep,
858 AliDielectronSingleTG *iem, int type, AliDielectron *die, Int_t idie)
862 // main routine for filling kinematics of pairs
867 double dmass, dphiv, dpxpair, dpypair, dpzpair;
868 double dptpair, depair, dphipair, detapair, dcos, dpsi;
870 CalcVars(iep, iem, dmass, dphiv, dpxpair, dpypair, dpzpair,
871 dptpair, depair, dphipair, detapair, dcos, dpsi);
874 double dopeningangle = -9999;
875 double dv0mass = -9999;
876 double dv0pxpair = -9999;
877 double dv0pypair = -9999;
878 double dv0pzpair = -9999;
879 double dv0ptpair = -9999;
880 double dv0epair = -9999;
881 double dv0xvpair = -9999;
882 double dv0yvpair = -9999;
883 double dv0zvpair = -9999;
884 double dv0phipair = -9999;
885 double dv0etapair = -9999;
886 double dv0rpair = -9999;
887 double dpsipair = -9999;
888 double dphivpair = -9999;
890 ////////////////////////////
891 ///// calculate v0 ////////
892 ///////////////////////////
894 /// for the moment, this doesn't work for MC
895 if(fdv0mixing == kFALSE && (type==3 || type==4 || type==5 || type==6)){
898 if(die->GetHasMC()==kTRUE && (type==3 || type==4 || type==5 || type==6)){
901 if(type==0 || type==1 || type==2){
907 AliVTrack* trackob1= iep->GetTrack();
908 AliVTrack* trackob2= iem->GetTrack();
910 if(!trackob1 || !trackob2){
914 AliDielectronPair candidate;
915 candidate.SetTracks(trackob1, (int)(11*iep->Charge()),
916 trackob2, (int)(11*iem->Charge()));
918 if(trackob1==trackob2){
919 AliInfo("Same Objects!!");
923 //const AliKFParticle &kfPairLeg1 = candidate.GetKFFirstDaughter();
924 //const AliKFParticle &kfPairLeg2 = candidate.GetKFSecondDaughter();
926 const AliKFParticle &kfPair = candidate.GetKFParticle();
929 dv0mass = candidate.M();
930 dv0pxpair = candidate.Px();
931 dv0pypair = candidate.Py();
932 dv0pzpair = candidate.Pz();
933 dv0ptpair = candidate.Pt();
934 dv0epair = candidate.E();
935 dv0xvpair = candidate.Xv();
936 dv0yvpair = candidate.Yv();
937 dv0zvpair = candidate.Zv();
938 dv0phipair = candidate.Phi();
939 dv0etapair = candidate.Eta();
941 dv0mass = kfPair.GetMass();
942 dv0pxpair = kfPair.GetPx();
943 dv0pypair = kfPair.GetPy();
944 dv0pzpair = kfPair.GetPz();
945 dv0ptpair = kfPair.GetPt();
946 dv0epair = kfPair.GetE();
947 dv0xvpair = kfPair.GetX();
948 dv0yvpair = kfPair.GetY();
949 dv0zvpair = kfPair.GetZ();
950 dv0phipair = kfPair.GetPhi();
951 dv0etapair = kfPair.GetEta();
952 dv0rpair = kfPair.GetR();
954 dopeningangle = candidate.OpeningAngle();
955 dpsipair = candidate.PsiPair(fbz);
956 dphivpair = candidate.PhivPair(fbz);
961 Double_t values[AliDielectronVarManager::kNMaxValues];
964 className1.Form("MyPair_%s",kPairClassNamesTG[type]);
965 className2.Form("MyPairV0_%s",kPairClassNamesTG[type]);
967 AliDielectronHistos *fHistos = die->GetHistoManager();
968 Bool_t pairClass1=fHistos->GetHistogramList()->FindObject(className1.Data())!=0x0;
969 Bool_t pairClass2=fHistos->GetHistogramList()->FindObject(className2.Data())!=0x0;
971 if (pairClass1 && PairTrackcut(dphiv, dcos, idie)==true){
972 ///import pair variables to values!!
973 values[AliDielectronVarManager::kPx] = dpxpair;
974 values[AliDielectronVarManager::kPy] = dpypair;
975 values[AliDielectronVarManager::kPz] = dpzpair;
976 values[AliDielectronVarManager::kPt] = dptpair;
977 values[AliDielectronVarManager::kXv] = dv0xvpair;
978 values[AliDielectronVarManager::kYv] = dv0yvpair;
979 values[AliDielectronVarManager::kZv] = dv0zvpair;
980 values[AliDielectronVarManager::kR] = dv0rpair;
981 values[AliDielectronVarManager::kE] = depair;
982 values[AliDielectronVarManager::kEta] = detapair;
983 values[AliDielectronVarManager::kM] = dmass;
984 values[AliDielectronVarManager::kPsiPair] = dphiv;
985 values[AliDielectronVarManager::kPhivPair] = dphiv;
986 values[AliDielectronVarManager::kPhi] = dphipair;
987 values[AliDielectronVarManager::kOpeningAngle] = dcos;
988 values[AliDielectronVarManager::kCosPointingAngle] = TMath::Abs(TMath::ATan2(TMath::Sin(iep->Phi()-iem->Phi()),TMath::Cos(iep->Phi()-iem->Phi())));
989 fHistos->FillClass(className1, AliDielectronVarManager::kNMaxValues, values);
993 if (pairClass2 && PairTrackcut(dphiv, dopeningangle, idie)==true){
994 values[AliDielectronVarManager::kPx] = dv0pxpair;
995 values[AliDielectronVarManager::kPy] = dv0pypair;
996 values[AliDielectronVarManager::kPz] = dv0pzpair;
997 values[AliDielectronVarManager::kPt] = dv0ptpair;
998 values[AliDielectronVarManager::kXv] = dv0xvpair;
999 values[AliDielectronVarManager::kYv] = dv0yvpair;
1000 values[AliDielectronVarManager::kZv] = dv0zvpair;
1001 values[AliDielectronVarManager::kR] = dv0rpair;
1002 values[AliDielectronVarManager::kE] = dv0epair;
1003 values[AliDielectronVarManager::kEta] = dv0etapair;
1004 values[AliDielectronVarManager::kM] = dv0mass;
1005 values[AliDielectronVarManager::kPsiPair] = dpsipair;
1006 values[AliDielectronVarManager::kPhivPair] = dphivpair;
1007 values[AliDielectronVarManager::kPhi] = dv0phipair;
1008 values[AliDielectronVarManager::kOpeningAngle] = dopeningangle;
1009 values[AliDielectronVarManager::kCosPointingAngle] = TMath::Abs(TMath::ATan2(TMath::Sin(iep->Phi()-iem->Phi()),TMath::Cos(iep->Phi()-iem->Phi())));
1010 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
1017 //_________________________________________________________________________________
1018 bool AliAnalysisTaskMultiDielectronTG::PairTrackcut(double phiv, double op, int idie)
1022 // pair-by-pair cuts
1028 if(fRejectPairFlag[idie] == 1 || fRejectPairFlag[idie] == 2 ||
1029 fRejectPairFlag[idie] == 3 || fRejectPairFlag[idie] == 4 ){
1030 if(fRejectPairFlag[idie] == 2 || fRejectPairFlag[idie] == 4 ){
1031 if(fbz>0 && phiv>fdconvphiv){
1033 }else if(fbz<0 && phiv<acos(-1.0)-fdconvphiv){
1036 }else if(fRejectPairFlag[idie] == 1 || fRejectPairFlag[idie] == 3){
1048 //_________________________________________________________________________________
1049 void AliAnalysisTaskMultiDielectronTG::CalcVars(AliDielectronSingleTG *iep, AliDielectronSingleTG *iem,
1050 double &mass, double &phiv, double &px, double &py, double&pz,
1051 double &pt, double &e, double &phi,
1052 double &eta, double &cos, double &psi)
1057 // standalone calculator for the pair variables
1060 px = iep->Px()+iem->Px();
1061 py = iep->Py()+iem->Py();
1062 pz = iep->Pz()+iem->Pz();
1063 pt = sqrt(px*px+py*py);
1064 double dppair = sqrt(pt*pt+pz*pz);
1065 static const double me=0.0005109989;
1066 e = sqrt(me*me+iep->Px()*iep->Px()+iep->Py()*iep->Py()+iep->Pz()*iep->Pz())
1067 + sqrt(me*me+iem->Px()*iem->Px()+iem->Py()*iem->Py()+iem->Pz()*iem->Pz());
1069 mass = e*e-px*px-py*py-pz*pz;
1077 phi = atan2(py, px);
1078 eta = -0.5*TMath::Log((dppair+pz)/(dppair-pz));
1079 double p1 = sqrt(pow(iep->Px(),2)+pow(iep->Py(),2)+pow(iep->Pz(),2));
1080 double p2 = sqrt(pow(iem->Px(),2)+pow(iem->Py(),2)+pow(iem->Pz(),2));
1081 cos = acos((iep->Px()*iem->Px()+iep->Py()*iem->Py()+iep->Pz()*iem->Pz())/(p1*p2));
1083 double dtheta = iep->Theta()-iem->Theta();
1084 psi = asin(dtheta/cos);
1087 //unit vector of (pep+pem)
1092 double ax = uy/sqrt(ux*ux+uy*uy);
1093 double ay = -ux/sqrt(ux*ux+uy*uy);
1095 //momentum of e+ and e- in (ax,ay,az) axis. Note that az=0 by
1097 //double ptep = iep->Px()*ax + iep->Py()*ay;
1098 //double ptem = iem->Px()*ax + iem->Py()*ay;
1100 double pxep = iep->Px();
1101 double pyep = iep->Py();
1102 double pzep = iep->Pz();
1103 double pxem = iem->Px();
1104 double pyem = iem->Py();
1105 double pzem = iem->Pz();
1108 //vector product of pep X pem
1109 double vpx = pyep*pzem - pzep*pyem;
1110 double vpy = pzep*pxem - pxep*pzem;
1111 double vpz = pxep*pyem - pyep*pxem;
1112 double vp = sqrt(vpx*vpx+vpy*vpy+vpz*vpz);
1113 //double thev = acos(vpz/vp);
1115 //unit vector of pep X pem
1120 //The third axis defined by vector product (ux,uy,uz)X(vx,vy,vz)
1121 double wx = uy*vz - uz*vy;
1122 double wy = uz*vx - ux*vz;
1123 double wz = ux*vy - uy*vx;
1124 double wl = sqrt(wx*wx+wy*wy+wz*wz);
1125 // by construction, (wx,wy,wz) must be a unit vector.
1126 if(fabs(wl - 1.0) > 0.00001) std::cout << "Calculation error in W vector"<<std::endl;
1127 // measure angle between (wx,wy,wz) and (ax,ay,0). The angle between them
1128 // should be small if the pair is conversion
1130 double cosPhiV = wx*ax + wy*ay;
1131 phiv = acos(cosPhiV);
1135 //_________________________________________________________________________________
1136 void AliAnalysisTaskMultiDielectronTG::ReshuffleBuffer(vector<AliDielectronSingleTG*> ve, deque<AliDielectronSingleTG*> pool)
1138 //If there is not enough electron in the pool, give up
1140 // ReshuffleBuffer for th event mixing
1143 unsigned int ne = ve.size();
1144 unsigned int poolsize = pool.size();
1145 int used[fgkMAXPOOL];
1146 for(int i=0;i<(int)fgkMAXPOOL;i++){
1151 std::cout <<" pool size="<<poolsize<<" ne"<<ne<<std::endl;
1154 for(unsigned int ie=0; ie < ne; ie++) {
1155 int j = rand()%poolsize;
1157 j = rand()%poolsize;
1165 //_________________________________________________________________________________
1166 void AliAnalysisTaskMultiDielectronTG::RejectPairs(vector<AliDielectronSingleTG*> e1, vector<AliDielectronSingleTG*> e2, Int_t idie){
1168 ////////////////////////////////////
1169 ///// to reject pairs from track arrays
1170 ///// conversions, ghost ..
1171 ///////////////////////////////////
1172 if(e1.size()>0 && e2.size()>0){
1173 for(int i1=0; i1<(int)e1.size(); i1++){
1174 for(int i2=0; i2<(int)e2.size(); i2++){
1175 if(fRejectPairFlag[idie]==1){
1176 Double_t cosine = GetOpeningAngle(e1[i1], e2[i2]);
1178 e1[i1]->SetConvFlag(0);
1179 e2[i2]->SetConvFlag(0);
1181 }else if(fRejectPairFlag[idie]==2){
1182 Double_t phiv = GetPhiv(e1[i1], e2[i2]);
1183 if(fbz>0 && phiv>fdconvphiv){
1184 e1[i1]->SetConvFlag(0);
1185 e2[i2]->SetConvFlag(0);
1186 }else if(fbz<0 && phiv<acos(-1.0)-fdconvphiv){
1187 e1[i1]->SetConvFlag(0);
1188 e2[i2]->SetConvFlag(0);
1194 /////// this is really necessary??????
1196 for(int i1=0; i1<(int)e1.size(); i1++){
1197 for(int i2=i1+1; i2<(int)e1.size(); i2++){
1198 if(fRejectPairFlag[idie]==1){
1199 Double_t cosine = GetOpeningAngle(e1[i1], e1[i2]);
1201 e1[i1]->SetConvFlag(0);
1202 e1[i2]->SetConvFlag(0);
1204 }else if(fRejectPairFlag[idie]==2){
1205 Double_t phiv = GetPhiv(e1[i1], e1[i2]);
1206 if(fbz>0 && phiv>fdconvphiv){
1207 e1[i1]->SetConvFlag(0);
1208 e1[i2]->SetConvFlag(0);
1209 }else if(fbz<0 && phiv<acos(-1.0)-fdconvphiv){
1210 e1[i1]->SetConvFlag(0);
1211 e1[i2]->SetConvFlag(0);
1219 for(int i1=0; i1<(int)e2.size(); i1++){
1220 for(int i2=i1+1; i2<(int)e2.size(); i2++){
1221 if(fRejectPairFlag[idie]==1){
1222 Double_t cosine = GetOpeningAngle(e2[i1], e2[i2]);
1224 e2[i1]->SetConvFlag(0);
1225 e2[i2]->SetConvFlag(0);
1227 }else if(fRejectPairFlag[idie]==2){
1228 Double_t phiv = GetPhiv(e2[i1], e2[i2]);
1229 if(fbz>0 && phiv>fdconvphiv){
1230 e2[i1]->SetConvFlag(0);
1231 e2[i2]->SetConvFlag(0);
1232 }else if(fbz<0 && phiv<acos(-1.0)-fdconvphiv){
1233 e2[i1]->SetConvFlag(0);
1234 e2[i2]->SetConvFlag(0);
1243 //_________________________________________________________________________________
1244 Double_t AliAnalysisTaskMultiDielectronTG::GetOpeningAngle(AliDielectronSingleTG* e1, AliDielectronSingleTG* e2){
1246 //////////////////////
1247 //////// calculate pairs and get opening angle
1248 //////////////////////
1250 double dmass, dphiv, dpxpair, dpypair, dpzpair;
1251 double dptpair, depair, dphipair, detapair, dcos, dpsi;
1253 CalcVars(e1, e2, dmass, dphiv, dpxpair, dpypair, dpzpair,
1254 dptpair, depair, dphipair, detapair, dcos, dpsi);
1259 //_________________________________________________________________________________
1260 Double_t AliAnalysisTaskMultiDielectronTG::GetPhiv(AliDielectronSingleTG* e1, AliDielectronSingleTG* e2){
1262 //////////////////////
1263 //////// calculate pairs and get opening angle
1264 //////////////////////
1266 double dmass, dphiv, dpxpair, dpypair, dpzpair;
1267 double dptpair, depair, dphipair, detapair, dcos, dpsi;
1269 CalcVars(e1, e2, dmass, dphiv, dpxpair, dpypair, dpzpair,
1270 dptpair, depair, dphipair, detapair, dcos, dpsi);