1 /**************************************************************************
2 * Copyright(c) 1998-2007, 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 **************************************************************************/
18 //-----------------------------------------------------------------------------
19 /// \class AliAnalysisTaskSingleMu
20 /// Analysis task for single muons in the spectrometer.
21 /// The output is a list of histograms.
22 /// The macro class can run on AOD or ESDs.
23 /// If Monte Carlo information is present, some basics checks are performed.
25 /// \author Diego Stocco
26 //-----------------------------------------------------------------------------
28 //----------------------------------------------------------------------------
29 // Implementation of the class for trigger chamber efficiency determinaltion
30 //----------------------------------------------------------------------------
33 #define AliAnalysisTaskTrigChEff_cxx
42 #include "TGraphAsymmErrors.h"
46 #include "AliESDEvent.h"
47 #include "AliESDMuonTrack.h"
48 #include "AliAnalysisManager.h"
51 #include "AliAnalysisTaskSE.h"
53 #include "AliAnalysisTaskTrigChEff.h"
55 ClassImp(AliAnalysisTaskTrigChEff)
57 //________________________________________________________________________
58 AliAnalysisTaskTrigChEff::AliAnalysisTaskTrigChEff() :
64 /// Default constructor
68 //________________________________________________________________________
69 AliAnalysisTaskTrigChEff::AliAnalysisTaskTrigChEff(const char *name) :
70 AliAnalysisTaskSE(name),
78 DefineOutput(1, TList::Class());
81 //________________________________________________________________________
82 AliAnalysisTaskTrigChEff::~AliAnalysisTaskTrigChEff()
84 if ( ! AliAnalysisManager::GetAnalysisManager()->IsProofMode() )
88 //_________________________________________________________________________
89 void AliAnalysisTaskTrigChEff::UserCreateOutputObjects() {
95 TString countTypeName[kNcounts] = {"bendPlane", "nonBendPlane","bothPlanes", "allTracks"};
97 const Char_t* yAxisTitle = "counts";
99 const Int_t kNboards = 234; //AliMpConstants::NofLocalBoards();
100 const Int_t kFirstTrigCh = 11;//AliMpConstants::NofTrackingChambers()+1;
102 Int_t chamberBins = kNchambers;
103 Float_t chamberLow = kFirstTrigCh-0.5, chamberHigh = kFirstTrigCh+kNchambers-0.5;
104 const Char_t* chamberName = "chamber";
106 Int_t slatBins = kNslats;
107 Float_t slatLow = 0-0.5, slatHigh = kNslats-0.5;
108 const Char_t* slatName = "slat";
110 Int_t boardBins = kNboards;
111 Float_t boardLow = 1-0.5, boardHigh = kNboards+1.-0.5;
112 const Char_t* boardName = "board";
114 TString baseName, histoName, histoTitle;
121 Int_t histoIndex = -1;
123 for(Int_t icount=0; icount<kNcounts; icount++){
124 histoName = Form("%sCountChamber", countTypeName[icount].Data());
125 histo = new TH1F(histoName, histoName,
126 chamberBins, chamberLow, chamberHigh);
127 histo->GetXaxis()->SetTitle(chamberName);
128 histo->GetYaxis()->SetTitle(yAxisTitle);
129 histoIndex = GetHistoIndex(kHchamberEff, icount);
130 fList->AddAt(histo, histoIndex);
133 for(Int_t icount=0; icount<kNcounts; icount++){
134 for(Int_t ch=0; ch<kNchambers; ch++){
135 histoName = Form("%sCountSlatCh%i", countTypeName[icount].Data(), kFirstTrigCh+ch);
136 histo = new TH1F(histoName, histoName,
137 slatBins, slatLow, slatHigh);
138 histo->GetXaxis()->SetTitle(slatName);
139 histo->GetYaxis()->SetTitle(yAxisTitle);
140 histoIndex = GetHistoIndex(kHslatEff, icount, ch);
141 fList->AddAt(histo, histoIndex);
145 for(Int_t icount=0; icount<kNcounts; icount++){
146 for(Int_t ch=0; ch<kNchambers; ch++){
147 histoName = Form("%sCountBoardCh%i", countTypeName[icount].Data(), kFirstTrigCh+ch);
148 histo = new TH1F(histoName, histoName,
149 boardBins, boardLow, boardHigh);
150 histo->GetXaxis()->SetTitle(boardName);
151 histo->GetYaxis()->SetTitle(yAxisTitle);
152 histoIndex = GetHistoIndex(kHboardEff, icount, ch);
153 fList->AddAt(histo, histoIndex);
157 histo2D = new TH2F("checkRejectedBoard", "Rejected tracks motivation",
158 4, 20.5, 24.5, boardBins, boardLow, boardHigh);
159 histo2D->GetXaxis()->SetBinLabel(1,"Many pads");
160 histo2D->GetXaxis()->SetBinLabel(2,"Few pads");
161 histo2D->GetXaxis()->SetBinLabel(3,"Outside geom");
162 histo2D->GetXaxis()->SetBinLabel(4,"Tracker track");
163 histo2D->GetYaxis()->SetTitle(boardName);
164 histoIndex = GetHistoIndex(kHcheckBoard);
165 fList->AddAt(histo2D, histoIndex);
170 //________________________________________________________________________
171 void AliAnalysisTaskTrigChEff::UserExec(Option_t *) {
174 /// Called for each event
176 AliESDEvent* esdEvent = dynamic_cast<AliESDEvent*> (InputEvent());
179 Printf("ERROR: esdEvent not available\n");
183 Int_t slat = 0, board = 0;
184 UShort_t pattern = 0;
185 AliESDMuonTrack *esdTrack = 0x0;
187 Int_t nTracks = esdEvent->GetNumberOfMuonTracks();
189 const Int_t kFirstTrigCh = 11; //AliMpConstants::NofTrackingChambers()+1;
191 TArrayI othersEfficient(kNchambers);
192 Int_t histoIndex = -1;
194 for (Int_t itrack = 0; itrack < nTracks; itrack++) {
195 esdTrack = esdEvent->GetMuonTrack(itrack);
197 if ( ! esdTrack->ContainTrackerData() && ! fUseGhosts ) continue;
199 pattern = esdTrack->GetHitsPatternInTrigCh();
200 Int_t effFlag = AliESDMuonTrack::GetEffFlag(pattern);
202 board = esdTrack->LoCircuit();
204 if(effFlag < AliESDMuonTrack::kChEff) {
205 histoIndex = GetHistoIndex(kHcheckBoard);
206 ((TH2F*)fList->At(histoIndex))->Fill(AliESDMuonTrack::GetSlatOrInfo(pattern), board);
207 continue; // Track not good for efficiency calculation
210 othersEfficient.Reset(1);
211 for(Int_t cath=0; cath<kNcathodes; cath++){
212 for(Int_t ich=0; ich<kNchambers; ich++){
213 if( ! AliESDMuonTrack::IsChamberHit(pattern, cath, ich)){
214 for(Int_t jch=0; jch<kNchambers; jch++){
216 othersEfficient[jch] = 0;
218 } // loop on other chambers
220 } // if chamber not efficient
221 } // loop on chambers
222 } // loop on cathodes
224 Bool_t rejectTrack = kTRUE;
225 for (Int_t ich=0; ich<kNchambers; ich++){
226 if ( othersEfficient[ich] > 0 ){
227 rejectTrack = kFALSE;
232 if ( rejectTrack ) continue;
234 slat = AliESDMuonTrack::GetSlatOrInfo(pattern);
236 for(Int_t ch=0; ch<kNchambers; ch++){
237 if ( ! othersEfficient[ch] )
238 continue; // Reject track if the info of the chamber under study
239 // is necessary to create the track itself
241 Int_t iChamber = kFirstTrigCh + ch;
243 Bool_t hitsBend = AliESDMuonTrack::IsChamberHit(pattern, 0, ch);
244 Bool_t hitsNonBend = AliESDMuonTrack::IsChamberHit(pattern, 1, ch);
246 Bool_t fillHisto[kNcounts] = {
249 ( hitsBend && hitsNonBend ),
253 for (Int_t icount=0; icount<kNcounts; icount++){
254 if ( ! fillHisto[icount] ) continue;
256 histoIndex = GetHistoIndex(kHchamberEff, icount);
257 ((TH1F*)fList->At(histoIndex))->Fill(iChamber);
259 if(effFlag < AliESDMuonTrack::kSlatEff) continue; // Track crossed different slats
260 histoIndex = GetHistoIndex(kHslatEff, icount, ch);
261 ((TH1F*)fList->At(histoIndex))->Fill(slat);
263 if(effFlag < AliESDMuonTrack::kBoardEff) continue; // Track crossed different boards
264 histoIndex = GetHistoIndex(kHboardEff, icount, ch);
265 ((TH1F*)fList->At(histoIndex))->Fill(board);
266 } // loop on chambers
267 } // loop on count types
270 // Post final data. It will be written to a file with option "RECREATE"
274 //________________________________________________________________________
275 void AliAnalysisTaskTrigChEff::Terminate(Option_t *) {
277 /// Draw result to the screen
278 /// Called once at the end of the query.
280 if ( gROOT->IsBatch() ) return;
281 fList = dynamic_cast<TList*> (GetOutputData(1));
288 TGraphAsymmErrors* effGraph = 0x0;
289 TString baseName[3] = {"Chamber", "RPC", "Board"};
290 Int_t baseIndex[3] = {kHchamberEff, kHslatEff, kHboardEff};
291 TString effName[kNcounts-1] = {"BendPlane", "NonBendPlane", "BothPlanes"};
292 Int_t histoIndexNum = -1, histoIndexDen = -1;
293 for (Int_t itype=0; itype<3; itype++) {
294 for(Int_t icount=0; icount<kNcounts-1; icount++){
295 TString canName = Form("efficiencyPer%s_%s",baseName[itype].Data(),effName[icount].Data());
296 can = new TCanvas(canName.Data(),canName.Data(),10*(1+kNcounts*itype+icount),10*(1+kNcounts*itype+icount),310,310);
297 can->SetFillColor(10); can->SetHighLightColor(10);
298 can->SetLeftMargin(0.15); can->SetBottomMargin(0.15);
302 for(Int_t ch=0; ch<kNchambers; ch++){
303 histoIndexNum = GetHistoIndex(baseIndex[itype], icount, ch);
304 histoIndexDen = GetHistoIndex(baseIndex[itype], kAllTracks, ch);
305 num = (TH1F*)(fList->At(histoIndexNum));
306 den = (TH1F*)(fList->At(histoIndexDen));
307 effGraph = new TGraphAsymmErrors(num, den);
308 effGraph->GetYaxis()->SetRangeUser(0., 1.1);
309 effGraph->GetYaxis()->SetTitle("Efficiency");
310 effGraph->GetXaxis()->SetTitle(baseName[itype].Data());
312 effGraph->Draw("AP");
313 if ( itype == 0 ) break;
315 } // loop on count types
319 //________________________________________________________________________
321 AliAnalysisTaskTrigChEff::GetHistoIndex(Int_t histoType, Int_t countType,
325 /// Return the index of the histogram in the list
327 switch ( histoType ) {
329 return 0 + countType;
331 return 4 + kNchambers*countType + chamber;
333 return 20 + kNchambers*countType + chamber;
339 const Int_t kNhistosPlaneCorr = 38;
341 switch ( histoType ){
343 return 0 + planeCorrelation*kNhistosPlaneCorr;
344 case kHtracksInBoard:
345 return 1 + planeCorrelation*kNhistosPlaneCorr;
347 return 2 + kNcathodes*countType + cathode
348 + planeCorrelation*kNhistosPlaneCorr;
350 return 6 + kNchambers*kNcathodes*countType
351 + kNchambers*cathode + chamber
352 + planeCorrelation*kNhistosPlaneCorr;
354 return 22 + kNchambers*kNcathodes*countType
355 + kNchambers*cathode + chamber
356 + planeCorrelation*kNhistosPlaneCorr;
358 return 0 + 2*kNhistosPlaneCorr;