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 Revision 1.8 2002/10/29 14:26:49 hristov
19 Code clean-up (F.Carminati)
21 Revision 1.7 2002/10/14 14:57:32 hristov
22 Merging the VirtualMC branch to the main development branch (HEAD)
24 Revision 1.6.6.1 2002/10/12 21:41:00 hristov
25 Remove the object from the list of browsables
27 Revision 1.6 2001/12/05 08:31:25 hristov
28 Destructor corrected, thanks to R.Brun
30 Revision 1.5 2001/01/26 19:58:48 hristov
31 Major upgrade of AliRoot code
33 Revision 1.4 2001/01/17 10:50:50 hristov
34 Corrections to destructors
36 Revision 1.3 2000/12/18 14:16:31 alibrary
39 Revision 1.2 2000/12/18 11:33:48 alibrary
40 New call frequence histograms per module and volume
42 Revision 1.1 2000/11/30 07:12:48 alibrary
43 Introducing new Rndm and QA classes
47 ///////////////////////////////////////////////////////////////////////////////
50 ///////////////////////////////////////////////////////////////////////////////
55 #include "TObjArray.h"
61 #include "TLorentzVector.h"
62 #include "TDatabasePDG.h"
66 #include "TPaveLabel.h"
71 #include "AliModule.h"
75 //_______________________________________________________________________
89 // Default constructor
93 //_______________________________________________________________________
94 AliMCQA::AliMCQA(const AliMCQA &qa):
113 //_______________________________________________________________________
114 AliMCQA::AliMCQA(Int_t ndets):
116 fNvolumes(gMC->NofVolumes()),
117 fQAList(new TObjArray(ndets)),
119 fDetDone(new Int_t[ndets]),
120 fQAHist(new TObjArray(2)),
121 fVolNames(new TObjArray(fNvolumes)),
122 fModNames(new TObjArray(fNdets)),
127 // Constructor, creates the list of lists of histograms
133 TObjArray &hist = *fQAList;
137 TObjArray &mods = *(gAlice->Modules());
138 TList *dir = gDirectory->GetList();
139 for (i=0; i<ndets; i++) {
140 hist[i] = list = new TList();
141 AliModule *mod = dynamic_cast<AliModule*>(mods[i]);
144 sprintf(title,"Spectrum entering: %s ",mod->GetName());
145 list->Add(new TH1F("hEnIn",strcat(title,mod->GetTitle()),100,-4,2));
146 dir->Remove(dir->FindObject("hEnIn"));
148 sprintf(title,"Spectrum exiting: %s ",mod->GetName());
149 list->Add(new TH1F("hEnOut",strcat(title,mod->GetTitle()),100,-4,2));
150 dir->Remove(dir->FindObject("hEnOut"));
153 sprintf(title,"Z coordinate entering: %s ",mod->GetName());
154 list->Add(new TH1F("hZIn",strcat(title,mod->GetTitle()),100,
155 mod->ZMin(),mod->ZMax()));
156 dir->Remove(dir->FindObject("hZIn"));
158 sprintf(title,"Z coordinate exiting: %s ",mod->GetName());
159 list->Add(new TH1F("hZOut",strcat(title,mod->GetTitle()),100,
160 mod->ZMin(),mod->ZMax()));
161 dir->Remove(dir->FindObject("hZOut"));
164 gROOT->GetListOfBrowsables()->Add(this,"AliMCQA");
167 // Global QA histograms
170 fQAHist->Add(new TH1F("hMCVcalls","Monte Carlo calls per volume",
171 fNvolumes, 0.5, fNvolumes+0.5));
172 h = dynamic_cast<TH1F*>(dir->FindObject("hMCVcalls"));
173 h->GetListOfFunctions()->Add(new TExec("ex","gAlice->GetMCQA()->AddVolumeName()"));
174 dir->Remove(dir->FindObject("hMCVcalls"));
176 // Build list of volume names
178 for(i=0;i<fNvolumes;++i) {
179 AliModule *mod = dynamic_cast<AliModule*>
180 ((*gAlice->Modules())[gAlice->DetFromMate(gMC->VolId2Mate(i+1))]);
181 (*fVolNames)[i]=new TNamed(gMC->VolName(i+1),mod->GetName());
184 fQAHist->Add(new TH1F("hMCMcalls","Monte Carlo calls per module",
185 fNdets, -0.5, fNdets-0.5));
186 h = dynamic_cast<TH1F*>(dir->FindObject("hMCMcalls"));
187 h->GetListOfFunctions()->Add(new TExec("ex","gAlice->GetMCQA()->AddModuleName()"));
189 dir->Remove(dir->FindObject("hMCMcalls"));
191 // Build list of module names
193 for(i=0;i<fNdets;++i)
195 new TNamed((dynamic_cast<AliModule*>((*gAlice->Modules())[i]))->GetName(),"");
198 //_______________________________________________________________________
199 void AliMCQA::Copy(AliMCQA &) const
201 Fatal("Copy ctor","Not implemented!\n");
204 //_______________________________________________________________________
205 AliMCQA::~AliMCQA() {
206 gROOT->GetListOfBrowsables()->Remove(this);
232 //_______________________________________________________________________
233 void AliMCQA::Browse(TBrowser *b)
236 // Called when the item "Run" is clicked on the left pane
237 // of the Root browser.
238 // It displays the Root Trees and all detectors.
242 // Global histos first
244 TIter global(fQAHist);
245 while((hist = dynamic_cast<TH1*>(global())))
246 b->Add(hist,hist->GetTitle());
248 // Module histograms now
252 while((histos = dynamic_cast<TList*>(next()))) {
254 while((hist = dynamic_cast<TH1*>(next1())))
255 b->Add(hist,hist->GetTitle());
259 //_______________________________________________________________________
260 void AliMCQA::PreTrack()
263 // Called before each track
266 for(Int_t i=0; i<fNdets; i++) fDetDone[i]=0;
269 //_______________________________________________________________________
270 void AliMCQA::StepManager(Int_t id)
273 // Called at each step
278 // Fill Global histograms first
282 static TH1F* mcvcalls = dynamic_cast<TH1F*>(fQAHist->FindObject("hMCVcalls"));
283 mcvcalls->Fill(gMC->CurrentVolID(copy));
284 static TH1F* mcmcalls = dynamic_cast<TH1F*>(fQAHist->FindObject("hMCMcalls"));
288 // Now the step manager histograms
291 static Double_t mpi0=0;
292 static Double_t mpip=0;
293 static Double_t mpim=0;
294 static Double_t mep=0;
295 static Double_t mem=0;
297 Int_t num = gMC->TrackPid();
301 if (mpi0==0) mpi0=gAlice->PDGDB()->GetParticle(num)->Mass();
305 if (mpip==0) mpip=gAlice->PDGDB()->GetParticle(num)->Mass();
309 if (mpim==0) mpim=gAlice->PDGDB()->GetParticle(num)->Mass();
313 if (mep==0) mep=gAlice->PDGDB()->GetParticle(num)->Mass();
317 if (mem==0) mem=gAlice->PDGDB()->GetParticle(num)->Mass();
321 mass =gAlice->PDGDB()->GetParticle(num)->Mass();
325 static TLorentzVector p, x;
326 gMC->TrackMomentum(p);
327 gMC->TrackPosition(x);
328 Double_t energy = TMath::Max(p[3]-mass,1.e-12);
330 if(!fDetDone[fOldId] && !gMC->IsNewTrack()) {
331 TList *histold = dynamic_cast<TList*>((*fQAList)[fOldId]);
332 hist = dynamic_cast<TH1F*>(histold->FindObject("hEnOut"));
333 hist->Fill(TMath::Log10(energy));
334 hist = dynamic_cast<TH1F*>(histold->FindObject("hZOut"));
339 if(!fDetDone[id] && !gMC->IsNewTrack()) {
340 TList *histnew = dynamic_cast<TList*>((*fQAList)[id]);
341 hist = dynamic_cast<TH1F*>(histnew->FindObject("hEnIn"));
342 hist->Fill(TMath::Log10(energy));
343 hist = dynamic_cast<TH1F*>(histnew->FindObject("hZIn"));
350 //_______________________________________________________________________
351 void AliMCQA::AddModuleName()
354 // Add function DrawModuleName to the module frequency histogram pad
356 static TVirtualPad* oldpad=0;
358 gPad->GetCanvas()->FeedbackMode(kTRUE);
359 if(gPad) gPad->AddExec("ex","gAlice->GetMCQA()->DrawModuleName()");
360 DrawPaveLabel(fMPaveLabel);
365 //_______________________________________________________________________
366 void AliMCQA::AddVolumeName()
369 // Add function DrawVolumeName to the volume frequency histogram pad
371 static TVirtualPad* oldpad=0;
373 gPad->GetCanvas()->FeedbackMode(kTRUE);
374 if(gPad) gPad->AddExec("ex","gAlice->GetMCQA()->DrawVolumeName()");
375 DrawPaveLabel(fVPaveLabel);
380 //_______________________________________________________________________
381 void AliMCQA::DrawPaveLabel(TPaveLabel *&pv)
384 // Draws the PaveLabel with the meaning of the bin
386 float uxmin = gPad->GetUxmin();
387 float uxmax = gPad->GetUxmax();
388 float uymin = gPad->GetUymin();
389 float uymax = gPad->GetUymax();
390 float lx = uxmax-uxmin;
391 float ly = uymax-uymin;
395 = new TPaveLabel(uxmin+0.05*lx,uymax-(0.05+0.1)*ly,
396 uxmin+(0.05+0.2)*lx,uymax-0.05*ly,
401 //_______________________________________________________________________
402 Int_t AliMCQA::GetHBin(const char* hname)
405 // Get the bin where the cursor is
407 TList *dir = gDirectory->GetList();
408 TH1 *h=dynamic_cast<TH1*>(dir->FindObject(hname));
411 int px = gPad->GetEventX();
412 Float_t upx = gPad->AbsPixeltoX(px);
413 Float_t x = gPad->PadtoX(upx);
415 return h->GetXaxis()->FindBin(x);
418 //_______________________________________________________________________
419 void AliMCQA::DrawModuleName()
422 // Writes the name of the module of the bin where the cursor is
424 TObject *select = gPad->GetSelected();
427 Int_t binx = GetHBin("hMCMcalls");
428 if(0<binx && binx<=fNdets) {
430 strcpy(lab,dynamic_cast<TNamed*>((*fModNames)[binx-1])->GetName());
431 fMPaveLabel->SetLabel(lab);
438 //_______________________________________________________________________
439 void AliMCQA::DrawVolumeName()
442 // Writes the name of the volume:module of the bin where the cursor is
444 TObject *select = gPad->GetSelected();
447 Int_t binx = GetHBin("hMCVcalls");
448 if(0<binx && binx<=fNvolumes) {
450 sprintf(lab,"%s: %s",dynamic_cast<TNamed*>((*fVolNames)[binx-1])->GetName(),
451 dynamic_cast<TNamed*>((*fVolNames)[binx-1])->GetTitle());
452 fVPaveLabel->SetLabel(lab);