]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliMCQA.cxx
MC-dependent part of AliRun extracted in AliMC (F.Carminati)
[u/mrichter/AliRoot.git] / STEER / AliMCQA.cxx
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 ///////////////////////////////////////////////////////////////////////////////
19 //                                                                           //
20 // Quality Assurance class                                                   //
21 // Provides standard histograms for every element of the detector            //
22 //                                                                           //
23 ///////////////////////////////////////////////////////////////////////////////
24
25
26 #include <strings.h>
27
28 #include <TBrowser.h>
29 #include <TCanvas.h>
30 #include <TDatabasePDG.h>
31 #include <TExec.h>
32 #include <TH1.h>
33 #include <TList.h>
34 #include <TLorentzVector.h>
35 #include <TMath.h>
36 #include <TObjArray.h>
37 #include <TPad.h>
38 #include <TPaveLabel.h>
39 #include <TROOT.h>
40 #include <TVirtualMC.h>
41
42 #include "AliMCQA.h"
43 #include "AliModule.h"
44 #include "AliRun.h"
45 #include "AliMC.h"
46
47 ClassImp(AliMCQA)
48
49 //_______________________________________________________________________
50 AliMCQA::AliMCQA():
51   fNdets(0),
52   fNvolumes(0),
53   fQAList(0),
54   fOldId(0),
55   fDetDone(0),
56   fQAHist(0),
57   fVolNames(0),
58   fModNames(0),
59   fMPaveLabel(0),
60   fVPaveLabel(0)
61 {
62   //
63   // Default constructor
64   //
65 }
66
67 //_______________________________________________________________________
68 AliMCQA::AliMCQA(const AliMCQA &qa):
69   TObject(qa),
70   fNdets(0),
71   fNvolumes(0),
72   fQAList(0),
73   fOldId(0),
74   fDetDone(0),
75   fQAHist(0),
76   fVolNames(0),
77   fModNames(0),
78   fMPaveLabel(0),
79   fVPaveLabel(0)
80 {
81   //
82   // Copy constructor
83   //
84   qa.Copy(*this);
85 }
86
87 //_______________________________________________________________________
88 AliMCQA::AliMCQA(Int_t ndets):
89   fNdets(ndets),
90   fNvolumes(gMC->NofVolumes()),
91   fQAList(new TObjArray(ndets)),
92   fOldId(0),
93   fDetDone(new Int_t[ndets]),
94   fQAHist(new TObjArray(2)),
95   fVolNames(new TObjArray(fNvolumes)),
96   fModNames(new TObjArray(fNdets)),
97   fMPaveLabel(0),
98   fVPaveLabel(0)
99 {
100   //
101   // Constructor, creates the list of lists of histograms
102   //
103   TList *list;
104   TH1F* h;
105   Int_t i;
106   
107   TObjArray &hist = *fQAList;
108
109   char title[100];
110   //
111   TObjArray &mods = *(gAlice->Modules());
112   TList *dir = gDirectory->GetList();
113   for (i=0; i<ndets; i++) {
114     hist[i] = list = new TList();
115     AliModule *mod = dynamic_cast<AliModule*>(mods[i]);
116
117     // Energy Spectrum
118     sprintf(title,"Spectrum entering: %s ",mod->GetName());
119     list->Add(new TH1F("hEnIn",strcat(title,mod->GetTitle()),100,-4,2));
120     dir->Remove(dir->FindObject("hEnIn"));
121
122     sprintf(title,"Spectrum exiting: %s ",mod->GetName());
123     list->Add(new TH1F("hEnOut",strcat(title,mod->GetTitle()),100,-4,2));
124     dir->Remove(dir->FindObject("hEnOut"));
125
126     // Z position
127     sprintf(title,"Z coordinate entering: %s ",mod->GetName());
128     list->Add(new TH1F("hZIn",strcat(title,mod->GetTitle()),100,
129                        mod->ZMin(),mod->ZMax()));
130     dir->Remove(dir->FindObject("hZIn"));
131
132     sprintf(title,"Z coordinate exiting: %s ",mod->GetName());
133     list->Add(new TH1F("hZOut",strcat(title,mod->GetTitle()),100,
134                        mod->ZMin(),mod->ZMax()));
135     dir->Remove(dir->FindObject("hZOut"));
136   }
137   //
138   gROOT->GetListOfBrowsables()->Add(this,"AliMCQA");
139
140   //
141   // Global QA histograms
142   //
143   
144   fQAHist->Add(new TH1F("hMCVcalls","Monte Carlo calls per volume",
145                         fNvolumes, 0.5, fNvolumes+0.5));
146   h = dynamic_cast<TH1F*>(dir->FindObject("hMCVcalls"));
147   h->GetListOfFunctions()->Add(new TExec("ex","gAlice->GetMCQA()->AddVolumeName()"));
148   dir->Remove(dir->FindObject("hMCVcalls"));
149   //
150   // Build list of volume names
151   //
152   AliMC * mc = gAlice->GetMCApp();
153   for(i=0;i<fNvolumes;++i) {
154     AliModule *mod = dynamic_cast<AliModule*>
155       ((*gAlice->Modules())[mc->DetFromMate(gMC->VolId2Mate(i+1))]);
156     (*fVolNames)[i]=new TNamed(gMC->VolName(i+1),mod->GetName());
157   }
158
159   fQAHist->Add(new TH1F("hMCMcalls","Monte Carlo calls per module",
160                         fNdets, -0.5, fNdets-0.5));
161   h = dynamic_cast<TH1F*>(dir->FindObject("hMCMcalls"));
162    h->GetListOfFunctions()->Add(new TExec("ex","gAlice->GetMCQA()->AddModuleName()"));
163
164   dir->Remove(dir->FindObject("hMCMcalls"));
165   //
166   // Build list of module names
167   //
168   for(i=0;i<fNdets;++i) 
169     (*fModNames)[i]=
170       new TNamed((dynamic_cast<AliModule*>((*gAlice->Modules())[i]))->GetName(),"");
171 }
172
173 //_______________________________________________________________________
174 void AliMCQA::Copy(AliMCQA &) const
175 {
176   Fatal("Copy ctor","Not implemented!\n");
177 }
178
179 //_______________________________________________________________________
180 AliMCQA::~AliMCQA() 
181  {
182   //
183   // Destructor
184   //
185   gROOT->GetListOfBrowsables()->Remove(this);
186   //if program crashes here - it probobly means that 
187   //one of added browsables was deleted and not removed previously from that list
188   //skowron
189   
190   if (fQAList) {
191     fQAList->Delete();
192     delete fQAList;
193     fQAList = 0;
194   }
195   if (fQAHist) {
196     fQAHist->Delete();
197     delete fQAHist;
198     fQAHist = 0;
199   }
200   if (fVolNames) {
201     fVolNames->Delete();
202     delete fVolNames;
203     fVolNames = 0;
204   }
205   if (fModNames) {
206     fModNames->Delete();
207     delete fModNames;
208     fModNames = 0;
209   }
210   delete [] fDetDone;
211   delete fMPaveLabel;
212   delete fVPaveLabel;
213 }
214
215 //_______________________________________________________________________
216 void AliMCQA::Browse(TBrowser *b)
217 {
218   //
219   // Called when the item "Run" is clicked on the left pane
220   // of the Root browser.
221   // It displays the Root Trees and all detectors.
222   //
223   TH1 *hist;
224   //
225   // Global histos first
226   //
227   TIter global(fQAHist);
228   while((hist = dynamic_cast<TH1*>(global())))
229     b->Add(hist,hist->GetTitle());
230   //
231   // Module histograms now
232   //
233   TIter next(fQAList);
234   TList *histos;
235   while((histos = dynamic_cast<TList*>(next()))) {
236     TIter next1(histos);
237     while((hist = dynamic_cast<TH1*>(next1())))
238       b->Add(hist,hist->GetTitle());
239   }
240 }
241
242 //_______________________________________________________________________
243 void AliMCQA::PreTrack()
244 {
245   //
246   // Called before each track
247   //
248   fOldId=-1;
249   for(Int_t i=0; i<fNdets; i++) fDetDone[i]=0;
250 }
251
252 //_______________________________________________________________________
253 void AliMCQA::StepManager(Int_t id)
254 {
255   //
256   // Called at each step
257   //
258   TH1F *hist;
259   Int_t copy;
260   //
261   // Fill Global histograms first
262   //
263
264
265   static TH1F* mcvcalls = dynamic_cast<TH1F*>(fQAHist->FindObject("hMCVcalls"));
266   mcvcalls->Fill(gMC->CurrentVolID(copy));
267   static TH1F* mcmcalls = dynamic_cast<TH1F*>(fQAHist->FindObject("hMCMcalls"));
268   mcmcalls->Fill(id);
269
270   //
271   // Now the step manager histograms
272   //
273   if(fOldId != id) {
274     static  Double_t mpi0=0;
275     static  Double_t mpip=0;
276     static  Double_t mpim=0;
277     static  Double_t mep=0;
278     static  Double_t mem=0;
279     Double_t mass = 0;
280     Int_t num = gMC->TrackPid();
281
282     switch (num) {
283     case 111: 
284       if (mpi0==0) mpi0=gAlice->PDGDB()->GetParticle(num)->Mass(); 
285       mass=mpi0;
286       break;
287     case 211:
288       if (mpip==0) mpip=gAlice->PDGDB()->GetParticle(num)->Mass(); 
289       mass=mpip;
290       break;
291     case -211:
292       if (mpim==0) mpim=gAlice->PDGDB()->GetParticle(num)->Mass(); 
293       mass=mpim;
294       break;
295     case 11:
296       if (mep==0) mep=gAlice->PDGDB()->GetParticle(num)->Mass(); 
297       mass=mep;
298       break;
299     case -11:
300       if (mem==0) mem=gAlice->PDGDB()->GetParticle(num)->Mass(); 
301       mass=mem;
302       break;
303     default:
304         if (gAlice->PDGDB()->GetParticle(num))
305             mass = gAlice->PDGDB()->GetParticle(num)->Mass();
306       break; 
307     }
308
309     static TLorentzVector p, x;
310     gMC->TrackMomentum(p);
311     gMC->TrackPosition(x);
312     Double_t energy = TMath::Max(p[3]-mass,1.e-12);
313     if(fOldId > -1) {
314       if(!fDetDone[fOldId] && !gMC->IsNewTrack()) {
315         TList *histold = dynamic_cast<TList*>((*fQAList)[fOldId]);
316         hist = dynamic_cast<TH1F*>(histold->FindObject("hEnOut"));
317         hist->Fill(TMath::Log10(energy));
318         hist = dynamic_cast<TH1F*>(histold->FindObject("hZOut"));
319         hist->Fill(x[2]);
320         fDetDone[fOldId]=1;
321       }
322     }
323     if(!fDetDone[id] && !gMC->IsNewTrack()) {
324       TList *histnew = dynamic_cast<TList*>((*fQAList)[id]);
325       hist = dynamic_cast<TH1F*>(histnew->FindObject("hEnIn"));
326       hist->Fill(TMath::Log10(energy));
327       hist = dynamic_cast<TH1F*>(histnew->FindObject("hZIn"));
328       hist->Fill(x[2]);
329     }
330     fOldId=id;
331   }
332 }
333
334 //_______________________________________________________________________
335 void AliMCQA::AddModuleName()
336 {
337   //
338   // Add function DrawModuleName to the module frequency histogram pad
339   //
340   static TVirtualPad* oldpad=0;
341   if(oldpad!=gPad) {
342     gPad->GetCanvas()->FeedbackMode(kTRUE);
343     if(gPad) gPad->AddExec("ex","gAlice->GetMCQA()->DrawModuleName()");
344     DrawPaveLabel(fMPaveLabel);
345     oldpad=gPad;
346   }
347 }
348
349 //_______________________________________________________________________
350 void AliMCQA::AddVolumeName()
351 {
352   //
353   // Add function DrawVolumeName to the volume frequency histogram pad
354   //
355   static TVirtualPad* oldpad=0;
356   if(oldpad!=gPad) {
357     gPad->GetCanvas()->FeedbackMode(kTRUE);
358     if(gPad) gPad->AddExec("ex","gAlice->GetMCQA()->DrawVolumeName()");
359     DrawPaveLabel(fVPaveLabel);
360     oldpad=gPad;
361   }
362 }
363
364 //_______________________________________________________________________
365 void AliMCQA::DrawPaveLabel(TPaveLabel *&pv)
366 {
367   //
368   // Draws the PaveLabel with the meaning of the bin
369   //
370   float uxmin = gPad->GetUxmin();
371   float uxmax = gPad->GetUxmax();
372   float uymin = gPad->GetUymin();
373   float uymax = gPad->GetUymax();
374   float lx = uxmax-uxmin;
375   float ly = uymax-uymin;
376
377   if(pv) delete pv;
378   pv 
379     = new TPaveLabel(uxmin+0.05*lx,uymax-(0.05+0.1)*ly,
380                      uxmin+(0.05+0.2)*lx,uymax-0.05*ly,
381                      "");
382   pv->Draw();
383 }
384
385 //_______________________________________________________________________
386 Int_t AliMCQA::GetHBin(const char* hname)
387 {
388   //
389   // Get the bin where the cursor is
390   //
391   TList *dir = gDirectory->GetList();
392   TH1 *h=dynamic_cast<TH1*>(dir->FindObject(hname));
393   
394
395   int px = gPad->GetEventX();
396   Float_t upx = gPad->AbsPixeltoX(px);
397   Float_t x = gPad->PadtoX(upx);
398     
399   return h->GetXaxis()->FindBin(x);
400 }
401
402 //_______________________________________________________________________
403 void AliMCQA::DrawModuleName()
404 {
405   //
406   // Writes the name of the module of the bin where the cursor is
407   //
408   TObject *select = gPad->GetSelected();
409   if(!select) return;
410   
411   Int_t binx = GetHBin("hMCMcalls");
412   if(0<binx && binx<=fNdets) {
413     char lab[15];
414     strcpy(lab,dynamic_cast<TNamed*>((*fModNames)[binx-1])->GetName());
415     fMPaveLabel->SetLabel(lab);
416   
417     gPad->Modified();
418     gPad->Update();
419   }
420 }
421
422 //_______________________________________________________________________
423 void AliMCQA::DrawVolumeName()
424 {
425   //
426   // Writes the name of the volume:module of the bin where the cursor is
427   //
428   TObject *select = gPad->GetSelected();
429   if(!select) return;
430
431   Int_t binx = GetHBin("hMCVcalls");
432   if(0<binx && binx<=fNvolumes) {
433     char lab[20];
434     sprintf(lab,"%s: %s",dynamic_cast<TNamed*>((*fVolNames)[binx-1])->GetName(),
435             dynamic_cast<TNamed*>((*fVolNames)[binx-1])->GetTitle());
436     fVPaveLabel->SetLabel(lab);
437     
438     gPad->Modified();
439     gPad->Update();
440   }
441 }
442
443