1 /**************************************************************************
2 * Copyright(c) 1998-1999, 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 ///////////////////////////////////////////////////////////////////////////////
20 // Quality Assurance class //
21 // Provides standard histograms for every element of the detector //
23 ///////////////////////////////////////////////////////////////////////////////
30 #include <TDatabasePDG.h>
34 #include <TLorentzVector.h>
36 #include <TObjArray.h>
37 #include <TPaveLabel.h>
39 #include <TVirtualMC.h>
43 #include "AliModule.h"
48 //_______________________________________________________________________
62 // Default constructor
66 //_______________________________________________________________________
67 AliMCQA::AliMCQA(const AliMCQA &qa):
86 //_______________________________________________________________________
87 AliMCQA::AliMCQA(Int_t ndets):
89 fNvolumes(gMC->NofVolumes()),
90 fQAList(new TObjArray(ndets)),
92 fDetDone(new Int_t[ndets]),
93 fQAHist(new TObjArray(2)),
94 fVolNames(new TObjArray(fNvolumes)),
95 fModNames(new TObjArray(fNdets)),
100 // Constructor, creates the list of lists of histograms
106 TObjArray &hist = *fQAList;
110 TObjArray &mods = *(gAlice->Modules());
111 TList *dir = gDirectory->GetList();
112 for (i=0; i<ndets; i++) {
113 hist[i] = list = new TList();
114 AliModule *mod = dynamic_cast<AliModule*>(mods[i]);
117 sprintf(title,"Spectrum entering: %s ",mod->GetName());
118 list->Add(new TH1F("hEnIn",strcat(title,mod->GetTitle()),100,-4,2));
119 dir->Remove(dir->FindObject("hEnIn"));
121 sprintf(title,"Spectrum exiting: %s ",mod->GetName());
122 list->Add(new TH1F("hEnOut",strcat(title,mod->GetTitle()),100,-4,2));
123 dir->Remove(dir->FindObject("hEnOut"));
126 sprintf(title,"Z coordinate entering: %s ",mod->GetName());
127 list->Add(new TH1F("hZIn",strcat(title,mod->GetTitle()),100,
128 mod->ZMin(),mod->ZMax()));
129 dir->Remove(dir->FindObject("hZIn"));
131 sprintf(title,"Z coordinate exiting: %s ",mod->GetName());
132 list->Add(new TH1F("hZOut",strcat(title,mod->GetTitle()),100,
133 mod->ZMin(),mod->ZMax()));
134 dir->Remove(dir->FindObject("hZOut"));
137 gROOT->GetListOfBrowsables()->Add(this,"AliMCQA");
140 // Global QA histograms
143 fQAHist->Add(new TH1F("hMCVcalls","Monte Carlo calls per volume",
144 fNvolumes, 0.5, fNvolumes+0.5));
145 h = dynamic_cast<TH1F*>(dir->FindObject("hMCVcalls"));
146 h->GetListOfFunctions()->Add(new TExec("ex","gAlice->GetMCQA()->AddVolumeName()"));
147 dir->Remove(dir->FindObject("hMCVcalls"));
149 // Build list of volume names
151 AliMC * mc = gAlice->GetMCApp();
152 for(i=0;i<fNvolumes;++i) {
153 AliModule *mod = dynamic_cast<AliModule*>
154 ((*gAlice->Modules())[mc->DetFromMate(gMC->VolId2Mate(i+1))]);
155 (*fVolNames)[i]=new TNamed(gMC->VolName(i+1),mod->GetName());
158 fQAHist->Add(new TH1F("hMCMcalls","Monte Carlo calls per module",
159 fNdets, -0.5, fNdets-0.5));
160 h = dynamic_cast<TH1F*>(dir->FindObject("hMCMcalls"));
161 h->GetListOfFunctions()->Add(new TExec("ex","gAlice->GetMCQA()->AddModuleName()"));
163 dir->Remove(dir->FindObject("hMCMcalls"));
165 // Build list of module names
167 for(i=0;i<fNdets;++i)
169 new TNamed((dynamic_cast<AliModule*>((*gAlice->Modules())[i]))->GetName(),"");
172 //_______________________________________________________________________
173 void AliMCQA::Copy(TObject &) const
175 Fatal("Copy ctor","Not implemented!\n");
178 //_______________________________________________________________________
184 gROOT->GetListOfBrowsables()->Remove(this);
185 //if program crashes here - it probobly means that
186 //one of added browsables was deleted and not removed previously from that list
214 //_______________________________________________________________________
215 void AliMCQA::Browse(TBrowser *b)
218 // Called when the item "Run" is clicked on the left pane
219 // of the Root browser.
220 // It displays the Root Trees and all detectors.
224 // Global histos first
226 TIter global(fQAHist);
227 while((hist = dynamic_cast<TH1*>(global())))
228 b->Add(hist,hist->GetTitle());
230 // Module histograms now
234 while((histos = dynamic_cast<TList*>(next()))) {
236 while((hist = dynamic_cast<TH1*>(next1())))
237 b->Add(hist,hist->GetTitle());
241 //_______________________________________________________________________
242 void AliMCQA::PreTrack()
245 // Called before each track
248 for(Int_t i=0; i<fNdets; i++) fDetDone[i]=0;
251 //_______________________________________________________________________
252 void AliMCQA::StepManager(Int_t id)
255 // Called at each step
260 // Fill Global histograms first
264 static TH1F* mcvcalls = dynamic_cast<TH1F*>(fQAHist->FindObject("hMCVcalls"));
265 mcvcalls->Fill(gMC->CurrentVolID(copy));
266 static TH1F* mcmcalls = dynamic_cast<TH1F*>(fQAHist->FindObject("hMCMcalls"));
270 // Now the step manager histograms
273 static Double_t mpi0=0;
274 static Double_t mpip=0;
275 static Double_t mpim=0;
276 static Double_t mep=0;
277 static Double_t mem=0;
279 Int_t num = gMC->TrackPid();
283 if (mpi0==0) mpi0=gAlice->PDGDB()->GetParticle(num)->Mass();
287 if (mpip==0) mpip=gAlice->PDGDB()->GetParticle(num)->Mass();
291 if (mpim==0) mpim=gAlice->PDGDB()->GetParticle(num)->Mass();
295 if (mep==0) mep=gAlice->PDGDB()->GetParticle(num)->Mass();
299 if (mem==0) mem=gAlice->PDGDB()->GetParticle(num)->Mass();
303 if (gAlice->PDGDB()->GetParticle(num))
304 mass = gAlice->PDGDB()->GetParticle(num)->Mass();
308 static TLorentzVector p, x;
309 gMC->TrackMomentum(p);
310 gMC->TrackPosition(x);
311 Double_t energy = TMath::Max(p[3]-mass,1.e-12);
313 if(!fDetDone[fOldId] && !gMC->IsNewTrack()) {
314 TList *histold = dynamic_cast<TList*>((*fQAList)[fOldId]);
315 hist = dynamic_cast<TH1F*>(histold->FindObject("hEnOut"));
316 hist->Fill(TMath::Log10(energy));
317 hist = dynamic_cast<TH1F*>(histold->FindObject("hZOut"));
322 if(!fDetDone[id] && !gMC->IsNewTrack()) {
323 TList *histnew = dynamic_cast<TList*>((*fQAList)[id]);
324 hist = dynamic_cast<TH1F*>(histnew->FindObject("hEnIn"));
325 hist->Fill(TMath::Log10(energy));
326 hist = dynamic_cast<TH1F*>(histnew->FindObject("hZIn"));
333 //_______________________________________________________________________
334 void AliMCQA::AddModuleName()
337 // Add function DrawModuleName to the module frequency histogram pad
339 static TVirtualPad* oldpad=0;
341 gPad->GetCanvas()->FeedbackMode(kTRUE);
342 if(gPad) gPad->AddExec("ex","gAlice->GetMCQA()->DrawModuleName()");
343 DrawPaveLabel(fMPaveLabel);
348 //_______________________________________________________________________
349 void AliMCQA::AddVolumeName()
352 // Add function DrawVolumeName to the volume frequency histogram pad
354 static TVirtualPad* oldpad=0;
356 gPad->GetCanvas()->FeedbackMode(kTRUE);
357 if(gPad) gPad->AddExec("ex","gAlice->GetMCQA()->DrawVolumeName()");
358 DrawPaveLabel(fVPaveLabel);
363 //_______________________________________________________________________
364 void AliMCQA::DrawPaveLabel(TPaveLabel *&pv)
367 // Draws the PaveLabel with the meaning of the bin
369 float uxmin = gPad->GetUxmin();
370 float uxmax = gPad->GetUxmax();
371 float uymin = gPad->GetUymin();
372 float uymax = gPad->GetUymax();
373 float lx = uxmax-uxmin;
374 float ly = uymax-uymin;
378 = new TPaveLabel(uxmin+0.05*lx,uymax-(0.05+0.1)*ly,
379 uxmin+(0.05+0.2)*lx,uymax-0.05*ly,
384 //_______________________________________________________________________
385 Int_t AliMCQA::GetHBin(const char* hname)
388 // Get the bin where the cursor is
390 TList *dir = gDirectory->GetList();
391 TH1 *h=dynamic_cast<TH1*>(dir->FindObject(hname));
394 int px = gPad->GetEventX();
395 Float_t upx = gPad->AbsPixeltoX(px);
396 Float_t x = gPad->PadtoX(upx);
398 return h->GetXaxis()->FindBin(x);
401 //_______________________________________________________________________
402 void AliMCQA::DrawModuleName()
405 // Writes the name of the module of the bin where the cursor is
407 TObject *select = gPad->GetSelected();
410 Int_t binx = GetHBin("hMCMcalls");
411 if(0<binx && binx<=fNdets) {
413 strcpy(lab,dynamic_cast<TNamed*>((*fModNames)[binx-1])->GetName());
414 fMPaveLabel->SetLabel(lab);
421 //_______________________________________________________________________
422 void AliMCQA::DrawVolumeName()
425 // Writes the name of the volume:module of the bin where the cursor is
427 TObject *select = gPad->GetSelected();
430 Int_t binx = GetHBin("hMCVcalls");
431 if(0<binx && binx<=fNvolumes) {
433 sprintf(lab,"%s: %s",dynamic_cast<TNamed*>((*fVolNames)[binx-1])->GetName(),
434 dynamic_cast<TNamed*>((*fVolNames)[binx-1])->GetTitle());
435 fVPaveLabel->SetLabel(lab);