Line data Source code
1 : /**************************************************************************
2 : * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 : * *
4 : * Author: The ALICE Off-line Project. *
5 : * Contributors are mentioned in the code where appropriate. *
6 : * *
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 : **************************************************************************/
15 :
16 : // $Id$
17 :
18 : #include "AliMUONTriggerEfficiencyCells.h"
19 : #include "AliMpConstants.h"
20 :
21 : // Classes for display
22 : #include "AliMUONTriggerDisplay.h"
23 : #include "AliCDBManager.h"
24 : #include "AliMpDDLStore.h"
25 :
26 : #include "AliLog.h"
27 :
28 : #include "TRandom.h"
29 : #include "Riostream.h"
30 : #include "TH1F.h"
31 : #include "TObjArray.h"
32 : #include "TGraphAsymmErrors.h"
33 :
34 : #include "TH2F.h"
35 : #include "TCanvas.h"
36 : #include "TROOT.h"
37 :
38 : #include "AliMUONTriggerChamberEfficiency.h"
39 :
40 : //-----------------------------------------------------------------------------
41 : /// \class AliMUONTriggerChamberEfficiency
42 : /// A class to store and give access to the trigger chamber efficiency.
43 : ///
44 : /// Efficiency is stored per cathode on local boards
45 : ///
46 : /// The main method of this class is IsTriggered().
47 : ///
48 : /// \author Diego Stocco; INFN Torino
49 : //-----------------------------------------------------------------------------
50 :
51 : /// \cond CLASSIMP
52 18 : ClassImp(AliMUONTriggerChamberEfficiency)
53 : /// \endcond
54 :
55 : //__________________________________________________________________________
56 : AliMUONTriggerChamberEfficiency::AliMUONTriggerChamberEfficiency(AliMUONTriggerEfficiencyCells* effCells)
57 : :
58 1 : TObject(),
59 1 : fIsOwner(kFALSE),
60 1 : fEfficiencyMap(effCells),
61 1 : fEfficiencyObjects(0x0),
62 1 : fDisplayList(0x0)
63 5 : {
64 : /// Default constructor.
65 1 : FillFromList();
66 2 : }
67 :
68 : //__________________________________________________________________________
69 : AliMUONTriggerChamberEfficiency::AliMUONTriggerChamberEfficiency(const Char_t* filename, const Char_t* listname)
70 : :
71 0 : TObject(),
72 0 : fIsOwner(kTRUE),
73 0 : fEfficiencyMap(0x0),
74 0 : fEfficiencyObjects(0x0),
75 0 : fDisplayList(0x0)
76 0 : {
77 : /// Constructor using an ASCII file.
78 0 : fEfficiencyMap = new AliMUONTriggerEfficiencyCells(filename, listname);
79 0 : FillFromList();
80 0 : }
81 :
82 :
83 : //_____________________________________________________________________________
84 : AliMUONTriggerChamberEfficiency::AliMUONTriggerChamberEfficiency(const AliMUONTriggerChamberEfficiency& other)
85 : :
86 0 : TObject(other),
87 0 : fIsOwner(other.fIsOwner),
88 0 : fEfficiencyMap(other.fEfficiencyMap),
89 0 : fEfficiencyObjects(other.fEfficiencyObjects),
90 0 : fDisplayList(other.fDisplayList)
91 0 : {
92 : /// Copy constructor
93 0 : }
94 :
95 : //_____________________________________________________________________________
96 : AliMUONTriggerChamberEfficiency& AliMUONTriggerChamberEfficiency::operator=(const AliMUONTriggerChamberEfficiency& other)
97 : {
98 : /// Asignment operator
99 : // check assignement to self
100 0 : if (this == &other)
101 0 : return *this;
102 :
103 0 : fIsOwner = other.fIsOwner;
104 0 : fEfficiencyMap = other.fEfficiencyMap;
105 0 : fEfficiencyObjects = other.fEfficiencyObjects;
106 0 : fDisplayList = other.fDisplayList;
107 :
108 0 : return *this;
109 0 : }
110 :
111 : //__________________________________________________________________________
112 : AliMUONTriggerChamberEfficiency::~AliMUONTriggerChamberEfficiency()
113 0 : {
114 : /// Destructor.
115 0 : if ( fIsOwner )
116 0 : delete fEfficiencyMap;
117 0 : delete fEfficiencyObjects;
118 0 : delete fDisplayList;
119 0 : }
120 :
121 :
122 : //__________________________________________________________________________
123 : Float_t AliMUONTriggerChamberEfficiency::GetCellEfficiency(Int_t detElemId, Int_t localBoard, Int_t hType) const
124 : {
125 : /// Get the efficiencies of the 2 cathodes at a given local board
126 :
127 258 : Int_t chamber = FindChamberIndex(detElemId);
128 129 : Int_t index = GetIndex(kHboardEff, hType, chamber);
129 129 : TGraphAsymmErrors* effGraph = ((TGraphAsymmErrors*)fEfficiencyObjects->At(index));
130 :
131 : // Some graphs are not available in the old implementation
132 129 : if ( ! effGraph ) return -1.;
133 :
134 129 : Double_t xpt, ypt;
135 129 : effGraph->GetPoint(localBoard-1, xpt, ypt);
136 129 : return ypt;
137 258 : }
138 :
139 :
140 : //__________________________________________________________________________
141 : Float_t AliMUONTriggerChamberEfficiency::GetCellEfficiencyError(Int_t detElemId, Int_t localBoard, Int_t hType, Int_t errType) const
142 : {
143 : /// Get the efficiencie errors of the 2 cathodes at a given local board
144 : /// errype 0 -> low error
145 : /// errype 1 -> high error
146 :
147 0 : Int_t chamber = FindChamberIndex(detElemId);
148 0 : Int_t index = GetIndex(kHboardEff, hType, chamber);
149 0 : TGraphAsymmErrors* effGraph = ((TGraphAsymmErrors*)fEfficiencyObjects->At(index));
150 :
151 : // Some graphs are not available in the old implementation
152 0 : if ( ! effGraph ) return -1.;
153 :
154 : Float_t err = -1.;
155 0 : if ( errType == 0 ) { // low error
156 0 : err = effGraph->GetErrorYlow(localBoard-1);
157 0 : }
158 0 : else if ( errType == 1 ) { // up error
159 0 : err = effGraph->GetErrorYhigh(localBoard-1);
160 0 : }
161 :
162 : return err;
163 0 : }
164 :
165 :
166 : //__________________________________________________________________________
167 : void
168 : AliMUONTriggerChamberEfficiency::IsTriggered(Int_t detElemId, Int_t localBoard, Bool_t &trigBend, Bool_t &trigNonBend) const
169 : {
170 : /// Whether or not a given local board has a chance to trig, on each cathode.
171 :
172 : // P(B) : probability to fire bending plane
173 86 : Float_t effBend = GetCellEfficiency(detElemId, localBoard, AliMUONTriggerEfficiencyCells::kBendingEff);
174 :
175 : // P(BN) : probability to fire bending and non-bending plane
176 43 : Float_t effBoth = GetCellEfficiency(detElemId, localBoard, AliMUONTriggerEfficiencyCells::kBothPlanesEff);
177 :
178 43 : trigBend = ( gRandom->Rndm() > effBend ) ? kFALSE : kTRUE;
179 :
180 : // P(N) : probability to fire non-bending plane
181 43 : Float_t effNonBend = GetCellEfficiency(detElemId, localBoard, AliMUONTriggerEfficiencyCells::kNonBendingEff);
182 :
183 43 : if ( effBoth > 0 ) {
184 129 : effNonBend = ( trigBend ) ?
185 43 : effBoth / effBend : // P(N|B) = P(BN) / P(B)
186 0 : ( effNonBend - effBoth ) / ( 1. - effBend ); // P(N|!B) = ( P(N) - P(BN) ) / ( 1 - P(B) )
187 43 : }
188 :
189 43 : trigNonBend = ( gRandom->Rndm() > effNonBend ) ? kFALSE : kTRUE;
190 :
191 129 : AliDebug(2,Form("Ch %i board %i resp (%i, %i) prob (%.2f, %.2f) effNB %.2f effBoth %.2f\n", detElemId/100, localBoard, trigBend, trigNonBend, effBend, effNonBend, GetCellEfficiency(detElemId, localBoard, AliMUONTriggerEfficiencyCells::kNonBendingEff), effBoth));
192 :
193 :
194 43 : }
195 :
196 :
197 : //__________________________________________________________________________
198 : Int_t AliMUONTriggerChamberEfficiency::FindChamberIndex(Int_t detElemId) const
199 : {
200 : /// From detElemId to chamber number
201 :
202 : // Int_t iChamber = AliMpDEManager::GetChamberId(detElemId);
203 258 : Int_t iChamber = detElemId/100 - 1;
204 129 : return iChamber-AliMpConstants::NofTrackingChambers();
205 : }
206 :
207 :
208 : //__________________________________________________________________________
209 : void
210 : AliMUONTriggerChamberEfficiency::FillFromList(Bool_t useMeanValues)
211 : {
212 : /// Fills internal histos from list.
213 :
214 1 : if ( fEfficiencyObjects )
215 0 : delete fEfficiencyObjects;
216 :
217 : const Int_t kNeffHistos =
218 1 : 2 * ( AliMUONTriggerEfficiencyCells::kNcounts - 1 ) * AliMpConstants::NofTriggerChambers();
219 :
220 2 : fEfficiencyObjects = new TObjArray(kNeffHistos);
221 1 : fEfficiencyObjects->SetOwner();
222 :
223 : TH1F *histoNum = 0x0, *histoDen=0x0;
224 1 : TString histoName = "";
225 1 : Int_t deType[2] = {AliMUONTriggerEfficiencyCells::kHboardCount,
226 : AliMUONTriggerEfficiencyCells::kHslatCount};
227 1 : Int_t deTypeEff[2] = {kHboardEff, kHslatEff};
228 : Int_t index = -1;
229 :
230 : Bool_t rebuildEfficiency = kTRUE;
231 :
232 6 : for ( Int_t ide=0; ide<2; ide++){
233 2 : Int_t currDe = deType[ide];
234 :
235 2 : if ( useMeanValues && currDe == AliMUONTriggerEfficiencyCells::kHboardCount )
236 0 : continue;
237 :
238 30 : for(Int_t ich=0; ich<AliMpConstants::NofTriggerChambers(); ich++){
239 16 : histoName = fEfficiencyMap->GetHistoName(currDe, AliMUONTriggerEfficiencyCells::kAllTracks, ich);
240 8 : if ( fEfficiencyMap->GetHistoList() ) {
241 24 : histoDen = (TH1F*)fEfficiencyMap->GetHistoList()->FindObject(histoName.Data());
242 8 : if ( !histoDen ) {
243 0 : AliWarning(Form("Histogram %s not found. Efficiency won't be re-build", histoName.Data()));
244 : rebuildEfficiency = kFALSE;
245 0 : }
246 : }
247 : else {
248 0 : AliWarning("Histogram list not present: efficiency won't be re-build");
249 : rebuildEfficiency = kFALSE;
250 : }
251 :
252 8 : Int_t nTypes = ( rebuildEfficiency ) ? AliMUONTriggerEfficiencyCells::kNcounts-1 : 2;
253 64 : for(Int_t hType=0; hType<nTypes; hType++){
254 48 : histoName = fEfficiencyMap->GetHistoName(currDe, hType, ich);
255 :
256 72 : histoNum = ( rebuildEfficiency ) ?
257 96 : (TH1F*)fEfficiencyMap->GetHistoList()->FindObject(histoName.Data()) :
258 0 : fEfficiencyMap->GetOldEffHisto(currDe, ich, hType);
259 :
260 24 : if ( !histoNum ) {
261 0 : AliWarning(Form("Histogram %s not found. Skip to next", histoName.Data()));
262 : continue;
263 : }
264 :
265 24 : index = GetIndex(deTypeEff[ide], hType, ich);
266 24 : TGraphAsymmErrors* effGraph = GetEfficiencyGraph(histoNum,histoDen);
267 24 : fEfficiencyObjects->AddAt(effGraph, index);
268 :
269 72 : TString debugString = Form("Adding object %s",effGraph->GetName());
270 120 : if ( histoDen ) debugString += Form(" (%s/%s)",histoNum->GetName(),histoDen->GetName());
271 48 : debugString += Form(" index %i",index);
272 120 : AliDebug(5,debugString.Data());
273 :
274 24 : if ( useMeanValues && rebuildEfficiency ){
275 0 : Int_t currChamber = ich + AliMpConstants::NofTrackingChambers();
276 0 : histoName = fEfficiencyMap->GetHistoName(AliMUONTriggerEfficiencyCells::kHboardCount, hType, ich);
277 0 : TH1F* auxHistoNum = (TH1F*)fEfficiencyMap->GetHistoList()->FindObject(histoName.Data())->Clone("tempHistoNum");
278 0 : TH1F* auxHistoDen = (TH1F*)fEfficiencyMap->GetHistoList()->FindObject(histoName.Data())->Clone("tempHistoDen");
279 0 : for ( Int_t iBinBoard = 1; iBinBoard<=AliMpConstants::NofLocalBoards(); iBinBoard++){
280 0 : Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromLocalBoard(iBinBoard, currChamber);
281 0 : Int_t iBin = histoNum->FindBin(detElemId%100);
282 :
283 0 : auxHistoNum->SetBinContent(iBinBoard, histoNum->GetBinContent(iBin));
284 0 : auxHistoDen->SetBinContent(iBinBoard, histoDen->GetBinContent(iBin));
285 : }
286 0 : index = GetIndex(kHboardEff, hType, ich);
287 0 : effGraph = GetEfficiencyGraph(auxHistoNum,auxHistoDen);
288 0 : fEfficiencyObjects->AddAt(effGraph, index);
289 0 : AliDebug(5,Form("Adding object %s (%s/%s) at index %i",effGraph->GetName(),histoNum->GetName(),histoDen->GetName(),index));
290 0 : delete auxHistoNum;
291 0 : delete auxHistoDen;
292 0 : } // if (useMeanValues)
293 24 : } // loop on count type
294 : } // loop on chamber
295 2 : } // loop on detection element histogram
296 1 : }
297 :
298 :
299 : //_____________________________________________________________________________
300 : void AliMUONTriggerChamberEfficiency::DisplayEfficiency(Bool_t perSlat, Bool_t show2Dhisto)
301 : {
302 : //
303 : /// Display calculated efficiency.
304 : //
305 :
306 0 : if ( !AliCDBManager::Instance()->GetDefaultStorage() ){
307 0 : AliWarning("Please set default CDB storage (needed for mapping).");
308 0 : return;
309 : }
310 0 : if ( AliCDBManager::Instance()->GetRun() < 0 ){
311 0 : AliWarning("Please set CDB run number (needed for mapping).");
312 0 : return;
313 : }
314 :
315 0 : TString baseCanName = "MTRtrigChEffCan";
316 0 : TString histoName;
317 :
318 : // Remove previously created canvases
319 : TCanvas* can = 0x0;
320 0 : TIter next(gROOT->GetListOfCanvases());
321 0 : while ((can = (TCanvas *)next())) {
322 0 : histoName = can->GetName();
323 0 : if ( histoName.Contains(baseCanName.Data()))
324 0 : delete can;
325 : }
326 :
327 0 : delete fDisplayList;
328 0 : fDisplayList = new TList();
329 0 : fDisplayList->SetOwner();
330 :
331 : TH2F* displayHisto = 0x0;
332 :
333 0 : AliMUONTriggerDisplay triggerDisplay;
334 :
335 0 : Int_t deType = ( perSlat ) ? kHslatEff : kHboardEff;
336 0 : AliMUONTriggerDisplay::EDisplayType displayType = ( perSlat ) ?
337 : AliMUONTriggerDisplay::kDisplaySlats : AliMUONTriggerDisplay::kDisplayBoards;
338 : Int_t index = -1;
339 :
340 : TGraph* graph = 0x0;
341 :
342 : // Book histos
343 0 : for(Int_t ich=0; ich<AliMpConstants::NofTriggerChambers(); ich++){
344 0 : Int_t currCh = 11 + ich;
345 0 : for(Int_t hType=0; hType<AliMUONTriggerEfficiencyCells::kNcounts - 1; hType++){
346 0 : index = GetIndex(deType, hType, ich);
347 0 : graph = (TGraph*)fEfficiencyObjects->At(index);
348 0 : if ( ! graph ) continue;
349 0 : histoName = graph->GetName();
350 0 : histoName += baseCanName;
351 0 : Int_t shift = 10*(index%((AliMUONTriggerEfficiencyCells::kNcounts - 1)*
352 0 : AliMpConstants::NofTriggerChambers()));
353 0 : can = new TCanvas(histoName.Data(), histoName.Data(), 100+shift, shift, 700, 700);
354 0 : can->SetRightMargin(0.14);
355 0 : can->SetLeftMargin(0.12);
356 0 : histoName.ReplaceAll(baseCanName.Data(), "Display");
357 0 : if ( show2Dhisto ) {
358 0 : displayHisto =
359 0 : (TH2F*)triggerDisplay.GetDisplayHistogram(graph, histoName,
360 : displayType,
361 0 : hType,currCh,histoName,
362 : AliMUONTriggerDisplay::kShowZeroes);
363 0 : displayHisto->SetDirectory(0);
364 : }
365 :
366 0 : if ( show2Dhisto ){
367 0 : displayHisto->GetZaxis()->SetRangeUser(0.,1.);
368 0 : displayHisto->GetYaxis()->SetTitleOffset(1.4);
369 0 : displayHisto->SetStats(kFALSE);
370 0 : displayHisto->DrawCopy("COLZ");
371 0 : delete displayHisto;
372 :
373 0 : if ( deType == kHboardEff ){
374 0 : histoName = Form("labels%iChamber%i", hType, currCh);
375 0 : displayHisto =
376 0 : (TH2F*)triggerDisplay.GetBoardNumberHisto(histoName,currCh);
377 0 : displayHisto->SetDirectory(0);
378 0 : displayHisto->DrawCopy("textsame");
379 0 : delete displayHisto;
380 : }
381 : }
382 : else {
383 0 : TGraphAsymmErrors* drawGraph = (TGraphAsymmErrors*)graph->Clone(histoName.Data());
384 0 : drawGraph->SetMarkerStyle(20);
385 0 : drawGraph->SetMarkerSize(0.7);
386 0 : drawGraph->SetMarkerColor(kRed);
387 0 : fDisplayList->Add(drawGraph);
388 0 : drawGraph->Draw("ap");
389 : } // loop on chamber
390 0 : } // loop on count type
391 : } // loop on chamber
392 0 : }
393 :
394 :
395 : //__________________________________________________________________________
396 : Bool_t AliMUONTriggerChamberEfficiency::LowStatisticsSettings(Bool_t useMeanValues)
397 : {
398 : //
399 : /// In case of low statistics, fill the local board efficiency with
400 : /// the average value of the RPC
401 : //
402 :
403 0 : if ( useMeanValues )
404 0 : AliInfo("Boards filled with the average efficiency of the RPC");
405 :
406 0 : FillFromList(useMeanValues);
407 :
408 0 : return kTRUE;
409 : }
410 :
411 :
412 : //__________________________________________________________________________
413 : Int_t
414 : AliMUONTriggerChamberEfficiency::GetIndex(Int_t histoType, Int_t countType,
415 : Int_t chamber) const
416 : {
417 : //
418 : /// Return the index of the object in the array
419 : //
420 :
421 : const Int_t kNtypes = AliMUONTriggerEfficiencyCells::kNcounts - 1;
422 306 : const Int_t kNchambers = AliMpConstants::NofTriggerChambers();
423 153 : return
424 306 : histoType * kNtypes * kNchambers +
425 306 : chamber * kNtypes +
426 : countType;
427 : //countType * kNchambers +
428 : //chamber;
429 : }
430 :
431 :
432 : //_____________________________________________________________________________
433 : TObject* AliMUONTriggerChamberEfficiency::GetEffObject(Int_t histoType, Int_t countType,
434 : Int_t chamber)
435 : {
436 : //
437 : /// Get efficiency object
438 : //
439 0 : Int_t index = GetIndex(histoType, countType, chamber);
440 0 : return fEfficiencyObjects->At(index);
441 : }
442 :
443 :
444 : //_____________________________________________________________________________
445 : TGraphAsymmErrors* AliMUONTriggerChamberEfficiency::GetEfficiencyGraph(TH1* histoNum, TH1* histoDen)
446 : {
447 : //
448 : /// Create the graph of efficiency from the numerator and denominator
449 : /// histogram in such a way to have a point set also for
450 : /// detection elements with efficiency = 0 or non calculated
451 : //
452 :
453 : TGraphAsymmErrors* auxGraph = 0x0;
454 96 : if ( histoDen ) auxGraph = new TGraphAsymmErrors(histoNum,histoDen,"cp");
455 0 : else auxGraph = new TGraphAsymmErrors(histoNum);
456 :
457 24 : Int_t npoints = histoNum->GetNbinsX();
458 24 : TGraphAsymmErrors* effGraph = new TGraphAsymmErrors(npoints);
459 24 : TString histoName = histoNum->GetName();
460 24 : histoName.ReplaceAll("Count","Eff");
461 48 : effGraph->SetName(histoName.Data());
462 48 : effGraph->SetTitle(histoName.Data());
463 24 : Double_t oldX, oldY;
464 6096 : for ( Int_t ibin=0; ibin<npoints; ibin++ ) {
465 : Int_t foundPoint = -1;
466 663984 : for (Int_t ipt=0; ipt<auxGraph->GetN(); ipt++) {
467 331992 : auxGraph->GetPoint(ipt, oldX, oldY);
468 667008 : if ( oldX > histoNum->GetBinLowEdge(ibin+1) &&
469 6048 : oldX < histoNum->GetBinLowEdge(ibin+2) ) {
470 : foundPoint = ipt;
471 3024 : break;
472 : }
473 : }
474 9072 : Double_t currX = ( foundPoint < 0 ) ? histoNum->GetBinCenter(ibin+1) : oldX;
475 3024 : Double_t currY = ( foundPoint < 0 ) ? 0. : oldY;
476 9072 : Double_t eyl = ( foundPoint < 0 ) ? 0. : auxGraph->GetErrorYlow(foundPoint);
477 9072 : Double_t eyh = ( foundPoint < 0 ) ? 0. : auxGraph->GetErrorYhigh(foundPoint);
478 3024 : effGraph->SetPoint(ibin, currX, currY);
479 3024 : effGraph->SetPointError(ibin, 0., 0., eyl, eyh);
480 : }
481 :
482 48 : delete auxGraph;
483 :
484 : return effGraph;
485 24 : }
|