2 //**************************************************************************
3 //* This file is property of and copyright by the ALICE HLT Project *
4 //* ALICE Experiment at CERN, All rights reserved. *
6 //* Primary Authors: Zhongbao Yin <zbyin@mail.ccnu.edu.cn>, *
7 //* Kalliopi Kanaki <Kalliopi.Kanaki@ift.uib.no> *
8 //* for The ALICE HLT Project. *
10 //* Permission to use, copy, modify and distribute this software and its *
11 //* documentation strictly for non-commercial purposes is hereby granted *
12 //* without fee, provided that the above copyright notice appears in all *
13 //* copies and that both the copyright notice and this permission notice *
14 //* appear in the supporting documentation. The authors make no claims *
15 //* about the suitability of this software for any purpose. It is *
16 //* provided "as is" without express or implied warranty. *
17 //**************************************************************************
19 /** @file AliAnalysisTaskHLT.cxx
20 @author Kalliopi Kanaki, Hege Erdal
22 @brief An analysis task containing
23 loops over HLT and offline ESD trees for comparing
24 AliESDtrack properties.
29 class AliAnalysisTask;
30 class AliAnalysisManager;
32 #include "AliAnalysisTaskHLT.h"
33 #include "AliHLTGlobalTriggerDecision.h"
37 #include "AliESDEvent.h"
38 #include "AliESDtrackCuts.h"
39 #include "AliESDInputHandler.h"
40 #include "AliTracker.h"
41 #include "AliCentrality.h"
44 #include "TTimeStamp.h"
48 ClassImp(AliAnalysisTaskHLT)
50 //===============================================================//
52 AliAnalysisTaskHLT::AliAnalysisTaskHLT()
55 ,fUseHLTTrigger(kFALSE)
56 //,fESDOfftrackCuts(0)
57 //,fESDHLTtrackCuts(0)
92 ,fNITSclusterHLTcut(0)
117 // Define input and output slots here
118 // Input slot #0 works with a TChain
119 // DefineInput(0, TChain::Class());
120 // Output slot #0 writes into a TH1 container
123 AliAnalysisTaskHLT::AliAnalysisTaskHLT(const char *name, float eta, float pt, float DCAr, float DCAz, float vertexZ)
125 AliAnalysisTaskSE(name)
126 ,fUseHLTTrigger(kFALSE)
127 //,fESDOfftrackCuts(0)
128 //,fESDHLTtrackCuts(0)
159 ,fNITSclusterHLTcut(0)
182 // Define input and output slots here
183 // Input slot #0 works with a TChain
184 // DefineInput(0, TChain::Class());
185 // Output slot #0 writes into a TH1 container
186 DefineOutput(1, TList::Class());
189 //------------------------------------------------------------------------//
191 void AliAnalysisTaskHLT::UserCreateOutputObjects(){
195 fOutputList = new TList();
196 fOutputList->SetOwner();
197 fOutputList->SetName(GetName());
200 //0 mistriggered, 1 Good triggered, 2, triggered, 3 fake trigger,
201 //4 events with offline track, 5 total events processed,
202 //6 offline track thru CE, 7 online track to CE
203 fHistTrigger = new TH1F("fHistTrigger", "Trigger Status", 8, -0.5, 7.5);
204 fHistTrigger->GetXaxis()->SetTitle("");
205 fHistTrigger->GetYaxis()->SetTitle("Events");
206 fHistTrigger->SetMarkerStyle(kFullCircle);
207 fHistTrigger->SetStats(0);
208 fHistTrigger->SetFillColor(2);
209 //fHistTrigger->SetDrawOption("B TEXT60");
212 (fHistTrigger->GetXaxis())->SetBinLabel(1,"missed");
213 (fHistTrigger->GetXaxis())->SetBinLabel(2,"triggerWofflTrk");
214 (fHistTrigger->GetXaxis())->SetBinLabel(3,"triggered");
215 (fHistTrigger->GetXaxis())->SetBinLabel(4,"triggerWOofflTrk");
216 (fHistTrigger->GetXaxis())->SetBinLabel(5,"NevWofflTrk");
217 (fHistTrigger->GetXaxis())->SetBinLabel(6,"Nevt");
218 (fHistTrigger->GetXaxis())->SetBinLabel(7,"offlTrkThruCE");
219 (fHistTrigger->GetXaxis())->SetBinLabel(8,"onlTrkThruCE");
222 //fHistTrigger = new TH1F("fHistTrigger", "CTP trigger counter", 24, 0, 24);
223 //fHistTrigger->GetXaxis()->SetTitle("");
224 //fHistTrigger->GetYaxis()->SetTitle("#Events");
226 //=========== event properties =================//
228 if(fBeamType.Contains("Pb")){
229 fMultOff = new TH1F("fMult_off", "",200,0,2000);
230 fMultHLT = new TH1F("fMult_hlt", "TPC track multiplicity",200,0,2000); fMultHLT->SetXTitle("TPC track multiplicity");
231 fNcontOff = new TH1F("fNcont_off","",200,0,2000);
232 fNcontHLT = new TH1F("fNcont_hlt","# of contributors",200,0,2000); fNcontHLT->SetXTitle("# of contributors");
233 fV0cent = new TH1F("fV0cent", "V0 centrality", 100,0, 100); fV0cent->SetXTitle("V0 centrality");
236 fMultOff = new TH1F("fMult_off","",200,0,200);
237 fMultHLT = new TH1F("fMult_hlt","TPC track multiplicity",200,0,200); fMultHLT->SetXTitle("TPC track multiplicity");
238 fNcontOff = new TH1F("fNcont_off","",200,0,200);
239 fNcontHLT = new TH1F("fNcont_hlt","# of contributors",200,0,200); fNcontHLT->SetXTitle("# of contributors");
242 fXvertexOff = new TH1F("fXvertex_off","",200,-0.5,0.5);
243 fXvertexHLT = new TH1F("fXvertex_hlt","X primary vertex",200,-0.5,0.5); fXvertexHLT->SetXTitle("x (cm)");
245 fYvertexOff = new TH1F("fYvertex_off","",200,-0.5,0.5);
246 fYvertexHLT = new TH1F("fYvertex_hlt","Y primary vertex",200,-0.5,0.5); fYvertexHLT->SetXTitle("y (cm)");
248 fZvertexOff = new TH1F("fZvertex_off","",100,-20,20);
249 fZvertexHLT = new TH1F("fZvertex_hlt","Z primary vertex",100,-20,20); fZvertexHLT->SetXTitle("z (cm)");
251 fSPDXvertexOff = new TH1F("fSPDXvertex_off","",200,-0.5,0.5);
252 fSPDXvertexHLT = new TH1F("fSPDXvertex_hlt","X SPD primary vertex",200,-0.5,0.5); fSPDXvertexHLT->SetXTitle("x (cm)");
254 fSPDYvertexOff = new TH1F("fSPDYvertex_off","",200,-0.5,0.5);
255 fSPDYvertexHLT = new TH1F("fSPDYvertex_hlt","Y SPD primary vertex",200,-0.5,0.5); fSPDYvertexHLT->SetXTitle("y (cm)");
257 fSPDZvertexOff = new TH1F("fSPDZvertex_off","",100,-20,20);
258 fSPDZvertexHLT = new TH1F("fSPDZvertex_hlt","Z SPD primary vertex",100,-20,20); fSPDZvertexHLT->SetXTitle("z (cm)");
260 fEventSpecieOff = new TH1F("fEventSpecie_off","",18, 0, 18);
261 fEventSpecieHLT = new TH1F("fEventSpecie_hlt","event species",18, 0, 18);
263 //============== track properties =================//
265 fChargeOff = new TH1F("fCharge_off", "", 3, -1.5, 1.5);
266 fChargeHLT = new TH1F("fCharge_hlt", "charge distribution", 3, -1.5, 1.5); fChargeHLT->SetXTitle("polarity");
268 fMomentumOff = new TH1F("fMomentum_off", "", 100, 0, 10);
269 fMomentumHLT = new TH1F("fMomentum_hlt", "transverse momentum", 100, 0, 10); fMomentumHLT->SetXTitle("p_{T} (GeV/c)");
271 fDCArOff = new TH1F("fDCAr_off", "", 200, -15, 15);
272 fDCArHLT = new TH1F("fDCAr_hlt", "DCAr", 200, -15, 15); fDCArHLT->SetXTitle("DCAr (cm)");
274 fDCAzOff = new TH1F("fDCAz_off", "", 200, -15, 15);
275 fDCAzHLT = new TH1F("fDCAz_hlt", "DCAz", 200, -15, 15); fDCAzHLT->SetXTitle("DCAz (cm)");
277 fNclusterOff = new TH1F("fNcluster_off","", 200, 0, 200);
278 fNclusterHLT = new TH1F("fNcluster_hlt","TPC clusters/track", 200, 0, 200); fNclusterHLT->SetXTitle("TPC clusters/track");
280 fNITSclusterOff = new TH1F("fNITScluster_off","", 10, 0, 10);
281 fNITSclusterHLT = new TH1F("fNITScluster_hlt","ITS clusters/track", 10, 0, 10); fNITSclusterHLT->SetXTitle("ITS clusters/track");
283 fPhiOff = new TH1F("fPhi_off","",90,0,360);
284 fPhiHLT = new TH1F("fPhi_hlt","azimuthal angle",90,0,360); fPhiHLT->SetXTitle("#phi (deg)");
286 fEtaOff = new TH1F("fEta_off","",100,-2,2);
287 fEtaHLT = new TH1F("fEta_hlt","pseudorapidity",100,-2,2); fEtaHLT->SetXTitle("#eta");
289 fChargeHLTcut = new TH1F("fCharge_hltcut", "", 3, -1.5, 1.5); fChargeHLTcut->SetXTitle("polarity");
290 fMomentumHLTcut = new TH1F("fMomentum_hltcut", "",100, 0, 10); fMomentumHLTcut ->SetXTitle("p_{T} (GeV/c)");
291 fDCArHLTcut = new TH1F("fDCAr_hltcut", "",200, -15, 15); fDCArHLTcut->SetXTitle("DCAr (cm)");
292 fDCAzHLTcut = new TH1F("fDCAz_hltcut", "",200, -15, 15); fDCAzHLTcut->SetXTitle("DCAz (cm)");
293 fNclusterHLTcut = new TH1F("fNcluster_hltcut", "",200, 0, 200); fNclusterHLTcut->SetXTitle("TPC clusters/track");
294 fNITSclusterHLTcut = new TH1F("fNITScluster_hltcut","", 10, 0, 10); fNITSclusterHLTcut->SetXTitle("ITS clusters/track");
295 fPhiHLTcut = new TH1F("fPhi_hltcut", "", 90, 0, 360); fPhiHLTcut->SetXTitle("#phi (deg)");
296 fEtaHLTcut = new TH1F("fEta_hltcut", "",100, -2, 2); fEtaHLTcut->SetXTitle("#eta");
298 //--------------------------------------------------//
300 fTextBox = new TText();
302 fCuts->SetName("cuts");
303 TString s = Form("|#eta|<%2g, p_{T}>%2g, |DCAr|<%2g, |DCAz|<%2g, |vertexZ|<%2g", TMath::Abs(fEta), TMath::Abs(fPt), TMath::Abs(fDCAr), TMath::Abs(fDCAz),TMath::Abs(fVertexZ));
306 //fOutputList->Add(fHistTrigger);
307 fOutputList->Add(fChargeOff); fOutputList->Add(fChargeHLT); fOutputList->Add(fChargeHLTcut);
308 fOutputList->Add(fMomentumOff); fOutputList->Add(fMomentumHLT); fOutputList->Add(fMomentumHLTcut);
309 fOutputList->Add(fDCArOff); fOutputList->Add(fDCArHLT); fOutputList->Add(fDCArHLTcut);
310 fOutputList->Add(fDCAzOff); fOutputList->Add(fDCAzHLT); fOutputList->Add(fDCAzHLTcut);
311 fOutputList->Add(fNclusterOff); fOutputList->Add(fNclusterHLT); fOutputList->Add(fNclusterHLTcut);
312 fOutputList->Add(fNITSclusterOff); fOutputList->Add(fNITSclusterHLT); fOutputList->Add(fNITSclusterHLTcut);
313 fOutputList->Add(fPhiOff); fOutputList->Add(fPhiHLT); fOutputList->Add(fPhiHLTcut);
314 fOutputList->Add(fEtaOff); fOutputList->Add(fEtaHLT); fOutputList->Add(fEtaHLTcut);
316 fOutputList->Add(fMultOff); fOutputList->Add(fMultHLT);
317 fOutputList->Add(fXvertexOff); fOutputList->Add(fXvertexHLT);
318 fOutputList->Add(fYvertexOff); fOutputList->Add(fYvertexHLT);
319 fOutputList->Add(fZvertexOff); fOutputList->Add(fZvertexHLT);
320 fOutputList->Add(fSPDXvertexOff); fOutputList->Add(fSPDXvertexHLT);
321 fOutputList->Add(fSPDYvertexOff); fOutputList->Add(fSPDYvertexHLT);
322 fOutputList->Add(fSPDZvertexOff); fOutputList->Add(fSPDZvertexHLT);
323 fOutputList->Add(fEventSpecieOff); fOutputList->Add(fEventSpecieHLT);
324 fOutputList->Add(fNcontOff); fOutputList->Add(fNcontHLT);
326 fOutputList->Add(fTextBox);
327 fOutputList->Add(fCuts);
328 if(fBeamType.Contains("Pb")) fOutputList->Add(fV0cent);
330 //SetupESDtrackCuts();
331 PostData(1, fOutputList);
334 void AliAnalysisTaskHLT::UserExec(Option_t *){
335 // see header file of AliAnalysisTask for documentation
337 AliESDEvent *esdOFF = dynamic_cast<AliESDEvent*>(InputEvent());
339 printf("Error:UserExec OFF esd not available\n");
343 if(esdOFF->GetEventSpecie()==16) return; // skip calibration events, HLT doesn't set this flag yet
345 AliESDInputHandler *esdH = dynamic_cast<AliESDInputHandler*>(fInputHandler);
347 printf("The ESD input handler is empty\n");
351 AliESDEvent *esdHLT = NULL;
352 if(esdH) esdHLT = esdH->GetHLTEvent();
354 printf("Error:UserExec HLT esd not available\n");
359 TTimeStamp *timestamp = new TTimeStamp(esdHLT->GetTimeStamp());
360 fTextBox->SetName("text");
361 TString s = Form("Run %d, Date %d", esdHLT->GetRunNumber(), timestamp->GetDate());
362 printf("You are analyzing run %d from date %d\n\n", esdHLT->GetRunNumber(), timestamp->GetDate());
363 fTextBox->SetTitle(s);
367 //Double_t bfield = esdOFF->GetMagneticField();
369 // UInt_t Statusnames[12]={AliESDtrack::kTPCin,
370 // AliESDtrack::kITSin,
371 // AliESDtrack::kTPCout,
372 // AliESDtrack::kITSout,
373 // AliESDtrack::kITSrefit,
374 // AliESDtrack::kTPCrefit,
375 // AliESDtrack::kTRDin,
376 // AliESDtrack::kTRDout,
377 // AliESDtrack::kTRDrefit,
378 // AliESDtrack::kTOFin,
379 // AliESDtrack::kTOFout,
380 // AliESDtrack::kTOFrefit};
384 //---------------- HLT ESD tree -----------------------//
386 Int_t nr_tracksHLT = 0;
387 const AliESDVertex *vertHLT = esdHLT->GetPrimaryVertexTracks();
389 if(vertHLT->GetStatus()==kTRUE){
390 fXvertexHLT->Fill( vertHLT->GetX() );
391 fYvertexHLT->Fill( vertHLT->GetY() );
392 fZvertexHLT->Fill( vertHLT->GetZ() );
394 fSPDXvertexHLT->Fill(esdHLT->GetPrimaryVertexSPD()->GetX());
395 fSPDYvertexHLT->Fill(esdHLT->GetPrimaryVertexSPD()->GetY());
396 fSPDZvertexHLT->Fill(esdHLT->GetPrimaryVertexSPD()->GetZ());
398 fNcontHLT->Fill(vertHLT->GetNContributors());
401 fEventSpecieHLT->Fill(esdHLT->GetEventSpecie());
403 for(Int_t i=0; i<esdHLT->GetNumberOfTracks(); i++){
405 AliESDtrack *esdtrackHLT = esdHLT->GetTrack(i);
406 if(!esdtrackHLT) continue;
408 //Fill which status flags that are set for an event
409 //for(int jjj=0;jjj<12;jjj++){
410 // if(esdtrackHLT->GetStatus()&Statusnames[jjj]) fStatusHLT->Fill(jjj);
413 if(!(esdtrackHLT->GetStatus()&AliESDtrack::kTPCin)) continue; // only interested in tracks with kTPCin flag
414 if(esdtrackHLT->GetTPCNcls()<=0) continue;
418 esdtrackHLT->GetXYZ(x);
420 AliTracker::GetBxByBz(x,b);
421 Bool_t isOK = esdtrackHLT->RelateToVertexTPCBxByBz(vertHLT, b, kVeryBig);
423 Float_t dca[2]={0,0}; Float_t cov[3]={0,0,0}; // dca_xy, dca_z, sigma_xy, sigma_xy_z, sigma_z
425 const AliExternalTrackParam *track = esdtrackHLT->GetTPCInnerParam();
427 esdtrackHLT->GetImpactParametersTPC(dca,cov);
428 fDCArHLT->Fill(dca[0]);
429 fDCAzHLT->Fill(dca[1]);
433 // if(vertHLT->GetStatus()==kTRUE){
434 // esdtrackHLT->GetDZ(esdHLT->GetPrimaryVertex()->GetX(), esdHLT->GetPrimaryVertex()->GetY(), esdHLT->GetPrimaryVertex()->GetZ(), bfield, dca);
435 // fDCArHLT->Fill(dca[0]);
436 // fDCAzHLT->Fill(dca[1]);
439 fChargeHLT->Fill(esdtrackHLT->Charge());
440 fNclusterHLT->Fill(esdtrackHLT->GetTPCNcls());
441 fNITSclusterHLT->Fill(esdtrackHLT->GetNcls(0));
442 fEtaHLT->Fill(esdtrackHLT->Eta());
443 fPhiHLT->Fill(esdtrackHLT->Phi()*TMath::RadToDeg());
444 fMomentumHLT->Fill(TMath::Abs(esdtrackHLT->Pt()));
446 if( TMath::Abs(esdtrackHLT->Eta())<TMath::Abs(fEta) &&
447 TMath::Abs(esdtrackHLT->Pt())>TMath::Abs(fPt) &&
448 TMath::Abs(dca[0])<TMath::Abs(fDCAr) &&
449 TMath::Abs(dca[1])<TMath::Abs(fDCAz) &&
450 TMath::Abs(vertHLT->GetZ())<TMath::Abs(fVertexZ) )
452 fChargeHLTcut->Fill(esdtrackHLT->Charge());
453 fNclusterHLTcut->Fill(esdtrackHLT->GetTPCNcls());
454 fDCArHLTcut->Fill(dca[0]);
455 fDCAzHLTcut->Fill(dca[1]);
456 fNITSclusterHLTcut->Fill(esdtrackHLT->GetNcls(0));
457 fEtaHLTcut->Fill(esdtrackHLT->Eta());
458 fPhiHLTcut->Fill(esdtrackHLT->Phi()*TMath::RadToDeg());
459 fMomentumHLTcut->Fill(TMath::Abs(esdtrackHLT->Pt()));
461 } // end of loop over hlt tracks
463 if(nr_tracksHLT>0) fMultHLT->Fill(nr_tracksHLT);
465 //----------------- OFFLINE ESD tree ----------------//
467 Int_t nr_tracksOff = 0;
468 const AliESDVertex *vertOFF = esdOFF->GetPrimaryVertexTracks();
470 if(fBeamType.Contains("Pb")){
471 fCentrality = esdOFF->GetCentrality();
472 // this information is only available from the offline ESD for 2010 PbPb data, the V0 info was not stored in the HLTesd (17.04.11, Kelly)
474 printf("Centrality pointer is empty\n");
477 else fV0cent->Fill(fCentrality->GetCentralityPercentile("V0M"));
480 if(vertOFF->GetStatus()==kTRUE){
481 fXvertexOff->Fill( vertOFF->GetX() );
482 fYvertexOff->Fill( vertOFF->GetY() );
483 fZvertexOff->Fill( vertOFF->GetZ() );
485 fSPDXvertexOff->Fill(esdOFF->GetPrimaryVertexSPD()->GetX());
486 fSPDYvertexOff->Fill(esdOFF->GetPrimaryVertexSPD()->GetY());
487 fSPDZvertexOff->Fill(esdOFF->GetPrimaryVertexSPD()->GetZ());
489 fNcontOff->Fill(vertOFF->GetNContributors());
492 fEventSpecieOff->Fill(esdOFF->GetEventSpecie());
494 for(Int_t i=0; i<esdOFF->GetNumberOfTracks(); i++){
496 AliESDtrack *esdtrackOFF = esdOFF->GetTrack(i);
497 if (!esdtrackOFF) continue;
499 if(!(esdtrackOFF->GetStatus()&AliESDtrack::kTPCin)) continue;
500 if(esdtrackOFF->GetTPCNcls()<=0) continue;
504 esdtrackOFF->GetXYZ(x);
506 AliTracker::GetBxByBz(x,b);
507 Bool_t isOK = esdtrackOFF->RelateToVertexTPCBxByBz(vertOFF, b, kVeryBig);
509 const AliExternalTrackParam *track = esdtrackOFF->GetTPCInnerParam();
511 Float_t dca[2]={0,0}; Float_t cov[3]={0,0,0}; // dca_xy, dca_z, sigma_xy, sigma_xy_z, sigma_z
512 esdtrackOFF->GetImpactParametersTPC(dca,cov);
513 fDCArOff->Fill(dca[0]);
514 fDCAzOff->Fill(dca[1]);
516 // // calculate the offline DCAs the same way like for HLT. The above way is calculating the DCA for the TPC inner barrel surface (Kelly, 17.04.11)
518 // if(vertOFF->GetStatus()==kTRUE){
519 // esdtrackOFF->GetDZ(esdOFF->GetPrimaryVertex()->GetX(), esdOFF->GetPrimaryVertex()->GetY(), esdOFF->GetPrimaryVertex()->GetZ(), bfield, dca);
522 fChargeOff->Fill(esdtrackOFF->Charge());
523 fNclusterOff->Fill(esdtrackOFF->GetTPCNcls());
524 fNITSclusterOff->Fill(esdtrackOFF->GetNcls(0));
525 fEtaOff->Fill(esdtrackOFF->Eta());
526 fPhiOff->Fill(esdtrackOFF->Phi()*TMath::RadToDeg());
527 fMomentumOff->Fill( TMath::Abs(esdtrackOFF->Pt()) );
529 } // end of loop over offline tracks
531 if(nr_tracksOff>0) fMultOff->Fill(nr_tracksOff);
533 PostData(1, fOutputList);
536 void AliAnalysisTaskHLT::Terminate(Option_t *){
537 // see header file of AliAnalysisTask for documentation
540 // void AliAnalysisTaskHLT::SetupESDtrackCuts(){ // not called
542 // // NB! Work in progress!
544 // Bool_t selPrimaries = kTRUE;
546 // fESDOfftrackCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2009(selPrimaries);
547 // //To make Offline cuts = HLT cuts
548 // fESDOfftrackCuts->SetRequireITSRefit(kFALSE);
549 // fESDOfftrackCuts->SetEtaRange(-0.9,+0.9);
553 // //NB! Need to understand this a bit more! Which cuts should we keep?
554 // fESDHLTtrackCuts = new AliESDtrackCuts;
557 // fESDHLTtrackCuts->SetRequireTPCStandAlone(kTRUE); // to get chi2 and ncls of kTPCin
558 // fESDHLTtrackCuts->SetMinNClustersTPC(70);
559 // fESDHLTtrackCuts->SetMaxChi2PerClusterTPC(4);
560 // fESDHLTtrackCuts->SetAcceptKinkDaughters(kFALSE);
562 // fESDHLTtrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,
563 // AliESDtrackCuts::kAny);
565 // if(selPrimaries) { // 7*(0.0050+0.0060/pt^0.9)
566 // fESDHLTtrackCuts->SetMaxDCAToVertexXYPtDep("0.0350+0.0420/pt^0.9");
569 // fESDHLTtrackCuts->SetMaxDCAToVertexZ(1.e6);
570 // fESDHLTtrackCuts->SetDCAToVertex2D(kFALSE);
571 // fESDHLTtrackCuts->SetRequireSigmaToVertex(kFALSE);
572 // fESDHLTtrackCuts->SetEtaRange(-0.9,+0.9);