]> git.uio.no Git - u/mrichter/AliRoot.git/blame - STEER/AliRun.cxx
ITS sensitive Si medium cuts values added
[u/mrichter/AliRoot.git] / STEER / AliRun.cxx
CommitLineData
99d554c8 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/*
17$Log$
d2ecd553 18Revision 1.34 2000/05/18 10:45:38 fca
19Delete Particle Factory properly
20
c222d2b0 21Revision 1.33 2000/05/16 13:10:40 fca
22New method IsNewTrack and fix for a problem in Father-Daughter relations
23
a01a8b12 24Revision 1.32 2000/04/27 10:38:21 fca
25Correct termination of Lego Run and introduce Lego getter in AliRun
26
838edcaf 27Revision 1.31 2000/04/26 10:17:32 fca
28Changes in Lego for G4 compatibility
29
dffd31ef 30Revision 1.30 2000/04/18 19:11:40 fca
31Introduce variable Config.C function signature
32
45189757 33Revision 1.29 2000/04/07 11:12:34 fca
34G4 compatibility changes
35
875c717b 36Revision 1.28 2000/04/05 06:51:06 fca
37Workaround for an HP compiler problem
38
5eb58812 39Revision 1.27 2000/03/22 18:08:07 fca
40Rationalisation of the virtual MC interfaces
41
80762cb1 42Revision 1.26 2000/03/22 13:42:26 fca
43SetGenerator does not replace an existing generator, ResetGenerator does
44
ee1dd322 45Revision 1.25 2000/02/23 16:25:22 fca
46AliVMC and AliGeant3 classes introduced
47ReadEuclid moved from AliRun to AliModule
48
b13db077 49Revision 1.24 2000/01/19 17:17:20 fca
50Introducing a list of lists of hits -- more hits allowed for detector now
51
1cedd08a 52Revision 1.23 1999/12/03 11:14:31 fca
53Fixing previous wrong checking
54
00719c1b 55Revision 1.21 1999/11/25 10:40:08 fca
56Fixing daughters information also in primary tracks
57
ae23d366 58Revision 1.20 1999/10/04 18:08:49 fca
59Adding protection against inconsistent Euclid files
60
3fcc96a1 61Revision 1.19 1999/09/29 07:50:40 fca
62Introduction of the Copyright and cvs Log
63
99d554c8 64*/
65
fe4da5cc 66///////////////////////////////////////////////////////////////////////////////
67// //
68// Control class for Alice C++ //
69// Only one single instance of this class exists. //
70// The object is created in main program aliroot //
71// and is pointed by the global gAlice. //
72// //
8494b010 73// -Supports the list of all Alice Detectors (fModules). //
fe4da5cc 74// -Supports the list of particles (fParticles). //
75// -Supports the Trees. //
76// -Supports the geometry. //
77// -Supports the event display. //
78//Begin_Html
79/*
1439f98e 80<img src="picts/AliRunClass.gif">
fe4da5cc 81*/
82//End_Html
83//Begin_Html
84/*
1439f98e 85<img src="picts/alirun.gif">
fe4da5cc 86*/
87//End_Html
88// //
89///////////////////////////////////////////////////////////////////////////////
90
91#include <TFile.h>
92#include <TRandom.h>
93#include <TBRIK.h>
94#include <TNode.h>
fe4da5cc 95#include <TCint.h>
96#include <TSystem.h>
a8f1fb7c 97#include <TObjectTable.h>
fe4da5cc 98
1578254f 99#include "TParticle.h"
fe4da5cc 100#include "AliRun.h"
fe4da5cc 101#include "AliDisplay.h"
875c717b 102#include "AliMC.h"
dffd31ef 103#include "AliLego.h"
fe4da5cc 104
fe4da5cc 105#include <stdlib.h>
106#include <stdio.h>
107#include <string.h>
108
109AliRun *gAlice;
110
111static AliHeader *header;
112
fe4da5cc 113ClassImp(AliRun)
114
115//_____________________________________________________________________________
116AliRun::AliRun()
117{
118 //
119 // Default constructor for AliRun
120 //
121 header=&fHeader;
122 fRun = 0;
123 fEvent = 0;
124 fCurrent = -1;
8494b010 125 fModules = 0;
fe4da5cc 126 fGenerator = 0;
127 fTreeD = 0;
128 fTreeK = 0;
129 fTreeH = 0;
130 fTreeE = 0;
131 fTreeR = 0;
132 fParticles = 0;
133 fGeometry = 0;
134 fDisplay = 0;
135 fField = 0;
875c717b 136 fMC = 0;
fe4da5cc 137 fNdets = 0;
138 fImedia = 0;
139 fTrRmax = 1.e10;
140 fTrZmax = 1.e10;
fe4da5cc 141 fInitDone = kFALSE;
142 fLego = 0;
1578254f 143 fPDGDB = 0; //Particle factory object!
1cedd08a 144 fHitLists = 0;
45189757 145 fConfigFunction = "\0";
fe4da5cc 146}
147
148//_____________________________________________________________________________
149AliRun::AliRun(const char *name, const char *title)
150 : TNamed(name,title)
151{
152 //
153 // Constructor for the main processor.
154 // Creates the geometry
155 // Creates the list of Detectors.
156 // Creates the list of particles.
157 //
158 Int_t i;
159
160 gAlice = this;
161 fTreeD = 0;
162 fTreeK = 0;
163 fTreeH = 0;
164 fTreeE = 0;
165 fTreeR = 0;
166 fTrRmax = 1.e10;
167 fTrZmax = 1.e10;
1141f8e4 168 fGenerator = 0;
fe4da5cc 169 fInitDone = kFALSE;
170 fLego = 0;
171 fField = 0;
45189757 172 fConfigFunction = "Config();";
fe4da5cc 173
174 gROOT->GetListOfBrowsables()->Add(this,name);
175 //
176 // create the support list for the various Detectors
8494b010 177 fModules = new TObjArray(77);
fe4da5cc 178 //
179 // Create the TNode geometry for the event display
180
181 BuildSimpleGeometry();
182
183
184 fNtrack=0;
185 fHgwmk=0;
186 fCurrent=-1;
187 header=&fHeader;
188 fRun = 0;
189 fEvent = 0;
190 //
191 // Create the particle stack
1578254f 192 fParticles = new TClonesArray("TParticle",100);
fe4da5cc 193
194 fDisplay = 0;
195 //
196 // Create default mag field
197 SetField();
198 //
875c717b 199 fMC = gMC;
fe4da5cc 200 //
201 // Prepare the tracking medium lists
202 fImedia = new TArrayI(1000);
203 for(i=0;i<1000;i++) (*fImedia)[i]=-99;
1578254f 204 //
205 // Make particles
206 fPDGDB = TDatabasePDG::Instance(); //Particle factory object!
1cedd08a 207 //
208 // Create HitLists list
209 fHitLists = new TList();
fe4da5cc 210}
211
212//_____________________________________________________________________________
213AliRun::~AliRun()
214{
215 //
216 // Defaullt AliRun destructor
217 //
fe4da5cc 218 delete fImedia;
219 delete fField;
875c717b 220 delete fMC;
fe4da5cc 221 delete fGeometry;
222 delete fDisplay;
223 delete fGenerator;
224 delete fLego;
225 delete fTreeD;
226 delete fTreeK;
227 delete fTreeH;
228 delete fTreeE;
229 delete fTreeR;
8494b010 230 if (fModules) {
231 fModules->Delete();
232 delete fModules;
fe4da5cc 233 }
234 if (fParticles) {
235 fParticles->Delete();
236 delete fParticles;
237 }
1cedd08a 238 delete fHitLists;
c222d2b0 239 delete fPDGDB;
fe4da5cc 240}
241
242//_____________________________________________________________________________
243void AliRun::AddHit(Int_t id, Int_t track, Int_t *vol, Float_t *hits) const
244{
245 //
246 // Add a hit to detector id
247 //
8494b010 248 TObjArray &dets = *fModules;
249 if(dets[id]) ((AliModule*) dets[id])->AddHit(track,vol,hits);
fe4da5cc 250}
251
252//_____________________________________________________________________________
253void AliRun::AddDigit(Int_t id, Int_t *tracks, Int_t *digits) const
254{
255 //
256 // Add digit to detector id
257 //
8494b010 258 TObjArray &dets = *fModules;
259 if(dets[id]) ((AliModule*) dets[id])->AddDigit(tracks,digits);
fe4da5cc 260}
261
262//_____________________________________________________________________________
263void AliRun::Browse(TBrowser *b)
264{
265 //
266 // Called when the item "Run" is clicked on the left pane
267 // of the Root browser.
268 // It displays the Root Trees and all detectors.
269 //
270 if (fTreeK) b->Add(fTreeK,fTreeK->GetName());
271 if (fTreeH) b->Add(fTreeH,fTreeH->GetName());
272 if (fTreeD) b->Add(fTreeD,fTreeD->GetName());
273 if (fTreeE) b->Add(fTreeE,fTreeE->GetName());
274 if (fTreeR) b->Add(fTreeR,fTreeR->GetName());
275
8494b010 276 TIter next(fModules);
277 AliModule *detector;
278 while((detector = (AliModule*)next())) {
fe4da5cc 279 b->Add(detector,detector->GetName());
280 }
281}
282
283//_____________________________________________________________________________
284void AliRun::Build()
285{
286 //
287 // Initialize Alice geometry
288 // Dummy routine
289 //
290}
291
292//_____________________________________________________________________________
293void AliRun::BuildSimpleGeometry()
294{
295 //
296 // Create a simple TNode geometry used by Root display engine
297 //
298 // Initialise geometry
299 //
300 fGeometry = new TGeometry("AliceGeom","Galice Geometry for Hits");
301 new TMaterial("void","Vacuum",0,0,0); //Everything is void
302 TBRIK *brik = new TBRIK("S_alice","alice volume","void",2000,2000,3000);
303 brik->SetVisibility(0);
304 new TNode("alice","alice","S_alice");
305}
306
307//_____________________________________________________________________________
308void AliRun::CleanDetectors()
309{
310 //
311 // Clean Detectors at the end of event
312 //
8494b010 313 TIter next(fModules);
314 AliModule *detector;
315 while((detector = (AliModule*)next())) {
fe4da5cc 316 detector->FinishEvent();
317 }
318}
319
320//_____________________________________________________________________________
321void AliRun::CleanParents()
322{
323 //
324 // Clean Particles stack.
1578254f 325 // Set parent/daughter relations
fe4da5cc 326 //
327 TClonesArray &particles = *(gAlice->Particles());
1578254f 328 TParticle *part;
fe4da5cc 329 int i;
330 for(i=0; i<fNtrack; i++) {
1578254f 331 part = (TParticle *)particles.UncheckedAt(i);
332 if(!part->TestBit(Daughters_Bit)) {
333 part->SetFirstDaughter(-1);
334 part->SetLastDaughter(-1);
fe4da5cc 335 }
336 }
337}
338
339//_____________________________________________________________________________
340Int_t AliRun::DistancetoPrimitive(Int_t, Int_t)
341{
342 //
343 // Return the distance from the mouse to the AliRun object
344 // Dummy routine
345 //
346 return 9999;
347}
348
349//_____________________________________________________________________________
350void AliRun::DumpPart (Int_t i)
351{
352 //
353 // Dumps particle i in the stack
354 //
355 TClonesArray &particles = *fParticles;
1578254f 356 ((TParticle*) particles[i])->Print();
fe4da5cc 357}
358
359//_____________________________________________________________________________
360void AliRun::DumpPStack ()
361{
362 //
363 // Dumps the particle stack
364 //
365 TClonesArray &particles = *fParticles;
366 printf(
367 "\n\n=======================================================================\n");
368 for (Int_t i=0;i<fNtrack;i++)
369 {
1578254f 370 printf("-> %d ",i); ((TParticle*) particles[i])->Print();
fe4da5cc 371 printf("--------------------------------------------------------------\n");
372 }
373 printf(
374 "\n=======================================================================\n\n");
375}
376
377//_____________________________________________________________________________
378void AliRun::SetField(Int_t type, Int_t version, Float_t scale,
379 Float_t maxField, char* filename)
380{
381 //
382 // Set magnetic field parameters
383 // type Magnetic field transport flag 0=no field, 2=helix, 3=Runge Kutta
384 // version Magnetic field map version (only 1 active now)
385 // scale Scale factor for the magnetic field
386 // maxField Maximum value for the magnetic field
387
388 //
389 // --- Sanity check on mag field flags
390 if(type<0 || type > 2) {
23370b7a 391 Warning("SetField",
392 "Invalid magnetic field flag: %5d; Helix tracking chosen instead\n"
fe4da5cc 393 ,type);
394 type=2;
395 }
396 if(fField) delete fField;
397 if(version==1) {
398 fField = new AliMagFC("Map1"," ",type,version,scale,maxField);
399 } else if(version<=3) {
400 fField = new AliMagFCM("Map2-3",filename,type,version,scale,maxField);
401 fField->ReadField();
402 } else {
23370b7a 403 Warning("SetField","Invalid map %d\n",version);
fe4da5cc 404 }
405}
406
407//_____________________________________________________________________________
408void AliRun::FillTree()
409{
410 //
411 // Fills all AliRun TTrees
412 //
413 if (fTreeK) fTreeK->Fill();
414 if (fTreeH) fTreeH->Fill();
415 if (fTreeD) fTreeD->Fill();
416 if (fTreeR) fTreeR->Fill();
417}
418
419//_____________________________________________________________________________
420void AliRun::FinishPrimary()
421{
422 //
423 // Called at the end of each primary track
424 //
425
6c9704e6 426 // static Int_t count=0;
427 // const Int_t times=10;
fe4da5cc 428 // This primary is finished, purify stack
80762cb1 429 PurifyKine();
fe4da5cc 430
431 // Write out hits if any
432 if (gAlice->TreeH()) {
433 gAlice->TreeH()->Fill();
434 }
435
436 // Reset Hits info
437 gAlice->ResetHits();
a8f1fb7c 438
439 //
440 // if(++count%times==1) gObjectTable->Print();
fe4da5cc 441}
442
443//_____________________________________________________________________________
444void AliRun::FinishEvent()
445{
446 //
447 // Called at the end of the event.
448 //
7fb01480 449
dffd31ef 450 //
451 if(fLego) fLego->FinishEvent();
452
fe4da5cc 453 //Update the energy deposit tables
454 Int_t i;
875c717b 455 for(i=0;i<fEventEnergy.GetSize();i++) {
456 fSummEnergy[i]+=fEventEnergy[i];
457 fSum2Energy[i]+=fEventEnergy[i]*fEventEnergy[i];
fe4da5cc 458 }
875c717b 459 fEventEnergy.Reset();
fe4da5cc 460
461 // Clean detector information
462 CleanDetectors();
463
464 // Write out the kinematics
465 if (fTreeK) {
466 CleanParents();
467 fTreeK->Fill();
468 }
469
470 // Write out the digits
471 if (fTreeD) {
472 fTreeD->Fill();
473 ResetDigits();
474 }
475
476 // Write out reconstructed clusters
477 if (fTreeR) {
478 fTreeR->Fill();
479 }
480
481 // Write out the event Header information
482 if (fTreeE) fTreeE->Fill();
483
484 // Reset stack info
485 ResetStack();
486
487 // Write Tree headers
59fe9bd2 488 // Int_t ievent = fHeader.GetEvent();
489 // char hname[30];
490 // sprintf(hname,"TreeK%d",ievent);
491 if (fTreeK) fTreeK->Write();
492 // sprintf(hname,"TreeH%d",ievent);
493 if (fTreeH) fTreeH->Write();
494 // sprintf(hname,"TreeD%d",ievent);
495 if (fTreeD) fTreeD->Write();
496 // sprintf(hname,"TreeR%d",ievent);
497 if (fTreeR) fTreeR->Write();
875c717b 498
499 ++fEvent;
fe4da5cc 500}
501
502//_____________________________________________________________________________
503void AliRun::FinishRun()
504{
505 //
506 // Called at the end of the run.
507 //
508
dffd31ef 509 //
510 if(fLego) fLego->FinishRun();
511
fe4da5cc 512 // Clean detector information
8494b010 513 TIter next(fModules);
514 AliModule *detector;
515 while((detector = (AliModule*)next())) {
fe4da5cc 516 detector->FinishRun();
517 }
518
519 //Output energy summary tables
520 EnergySummary();
521
522 // file is retrieved from whatever tree
523 TFile *File = 0;
524 if (fTreeK) File = fTreeK->GetCurrentFile();
525 if ((!File) && (fTreeH)) File = fTreeH->GetCurrentFile();
526 if ((!File) && (fTreeD)) File = fTreeD->GetCurrentFile();
527 if ((!File) && (fTreeE)) File = fTreeE->GetCurrentFile();
528 if( NULL==File ) {
529 Error("FinishRun","There isn't root file!");
530 exit(1);
531 }
532 File->cd();
533 fTreeE->Write();
534
535 // Clean tree information
d2ecd553 536 if (fTreeK) {
537 delete fTreeK; fTreeK = 0;
538 }
539 if (fTreeH) {
540 delete fTreeH; fTreeH = 0;
541 }
542 if (fTreeD) {
543 delete fTreeD; fTreeD = 0;
544 }
545 if (fTreeR) {
546 delete fTreeR; fTreeR = 0;
547 }
548 if (fTreeE) {
549 delete fTreeE; fTreeE = 0;
550 }
fe4da5cc 551
552 // Write AliRun info and all detectors parameters
553 Write();
554
555 // Close output file
556 File->Write();
fe4da5cc 557}
558
559//_____________________________________________________________________________
560void AliRun::FlagTrack(Int_t track)
561{
562 //
563 // Flags a track and all its family tree to be kept
564 //
565 int curr;
1578254f 566 TParticle *particle;
fe4da5cc 567
568 curr=track;
569 while(1) {
1578254f 570 particle=(TParticle*)fParticles->UncheckedAt(curr);
fe4da5cc 571
572 // If the particle is flagged the three from here upward is saved already
573 if(particle->TestBit(Keep_Bit)) return;
574
575 // Save this particle
576 particle->SetBit(Keep_Bit);
577
578 // Move to father if any
1578254f 579 if((curr=particle->GetFirstMother())==-1) return;
fe4da5cc 580 }
581}
582
583//_____________________________________________________________________________
584void AliRun::EnergySummary()
585{
586 //
587 // Print summary of deposited energy
588 //
589
fe4da5cc 590 Int_t ndep=0;
591 Float_t edtot=0;
592 Float_t ed, ed2;
593 Int_t kn, i, left, j, id;
594 const Float_t zero=0;
595 Int_t ievent=fHeader.GetEvent()+1;
596 //
597 // Energy loss information
598 if(ievent) {
599 printf("***************** Energy Loss Information per event (GEV) *****************\n");
875c717b 600 for(kn=1;kn<fEventEnergy.GetSize();kn++) {
601 ed=fSummEnergy[kn];
fe4da5cc 602 if(ed>0) {
875c717b 603 fEventEnergy[ndep]=kn;
fe4da5cc 604 if(ievent>1) {
605 ed=ed/ievent;
875c717b 606 ed2=fSum2Energy[kn];
fe4da5cc 607 ed2=ed2/ievent;
608 ed2=100*TMath::Sqrt(TMath::Max(ed2-ed*ed,zero))/ed;
609 } else
610 ed2=99;
875c717b 611 fSummEnergy[ndep]=ed;
612 fSum2Energy[ndep]=TMath::Min((Float_t) 99.,TMath::Max(ed2,zero));
fe4da5cc 613 edtot+=ed;
614 ndep++;
615 }
616 }
617 for(kn=0;kn<(ndep-1)/3+1;kn++) {
618 left=ndep-kn*3;
619 for(i=0;i<(3<left?3:left);i++) {
620 j=kn*3+i;
875c717b 621 id=Int_t (fEventEnergy[j]+0.1);
622 printf(" %s %10.3f +- %10.3f%%;",gMC->VolName(id),fSummEnergy[j],fSum2Energy[j]);
fe4da5cc 623 }
624 printf("\n");
625 }
626 //
627 // Relative energy loss in different detectors
628 printf("******************** Relative Energy Loss per event ********************\n");
629 printf("Total energy loss per event %10.3f GeV\n",edtot);
630 for(kn=0;kn<(ndep-1)/5+1;kn++) {
631 left=ndep-kn*5;
632 for(i=0;i<(5<left?5:left);i++) {
633 j=kn*5+i;
875c717b 634 id=Int_t (fEventEnergy[j]+0.1);
635 printf(" %s %10.3f%%;",gMC->VolName(id),100*fSummEnergy[j]/edtot);
fe4da5cc 636 }
637 printf("\n");
638 }
639 for(kn=0;kn<75;kn++) printf("*");
640 printf("\n");
641 }
642 //
643 // Reset the TArray's
875c717b 644 // fEventEnergy.Set(0);
645 // fSummEnergy.Set(0);
646 // fSum2Energy.Set(0);
fe4da5cc 647}
648
649//_____________________________________________________________________________
8494b010 650AliModule *AliRun::GetModule(const char *name)
fe4da5cc 651{
652 //
653 // Return pointer to detector from name
654 //
8494b010 655 return (AliModule*)fModules->FindObject(name);
fe4da5cc 656}
657
a68348e9 658//_____________________________________________________________________________
659AliDetector *AliRun::GetDetector(const char *name)
660{
661 //
662 // Return pointer to detector from name
663 //
664 return (AliDetector*)fModules->FindObject(name);
665}
666
fe4da5cc 667//_____________________________________________________________________________
8494b010 668Int_t AliRun::GetModuleID(const char *name)
fe4da5cc 669{
670 //
671 // Return galice internal detector identifier from name
672 //
23370b7a 673 Int_t i=-1;
674 TObject *mod=fModules->FindObject(name);
675 if(mod) i=fModules->IndexOf(mod);
676 return i;
fe4da5cc 677}
678
679//_____________________________________________________________________________
680Int_t AliRun::GetEvent(Int_t event)
681{
682 //
683 // Connect the Trees Kinematics and Hits for event # event
684 // Set branch addresses
685 //
fe4da5cc 686
687 // Reset existing structures
688 ResetStack();
689 ResetHits();
690 ResetDigits();
691
692 // Delete Trees already connected
693 if (fTreeK) delete fTreeK;
694 if (fTreeH) delete fTreeH;
695 if (fTreeD) delete fTreeD;
696 if (fTreeR) delete fTreeR;
59fe9bd2 697
698 // Get header from file
699 if(fTreeE) fTreeE->GetEntry(event);
700 else Error("GetEvent","Cannot file Header Tree\n");
fe4da5cc 701
702 // Get Kine Tree from file
703 char treeName[20];
704 sprintf(treeName,"TreeK%d",event);
705 fTreeK = (TTree*)gDirectory->Get(treeName);
706 if (fTreeK) fTreeK->SetBranchAddress("Particles", &fParticles);
23370b7a 707 else Error("GetEvent","cannot find Kine Tree for event:%d\n",event);
fe4da5cc 708
709 // Get Hits Tree header from file
710 sprintf(treeName,"TreeH%d",event);
711 fTreeH = (TTree*)gDirectory->Get(treeName);
712 if (!fTreeH) {
23370b7a 713 Error("GetEvent","cannot find Hits Tree for event:%d\n",event);
fe4da5cc 714 }
715
716 // Get Digits Tree header from file
717 sprintf(treeName,"TreeD%d",event);
718 fTreeD = (TTree*)gDirectory->Get(treeName);
719 if (!fTreeD) {
07a68c1d 720 Warning("GetEvent","cannot find Digits Tree for event:%d\n",event);
fe4da5cc 721 }
722
723
724 // Get Reconstruct Tree header from file
725 sprintf(treeName,"TreeR%d",event);
726 fTreeR = (TTree*)gDirectory->Get(treeName);
727 if (!fTreeR) {
728 // printf("WARNING: cannot find Reconstructed Tree for event:%d\n",event);
729 }
730
731 // Set Trees branch addresses
8494b010 732 TIter next(fModules);
733 AliModule *detector;
734 while((detector = (AliModule*)next())) {
fe4da5cc 735 detector->SetTreeAddress();
736 }
737
738 if (fTreeK) fTreeK->GetEvent(0);
739 fNtrack = Int_t (fParticles->GetEntries());
740 return fNtrack;
741}
742
743//_____________________________________________________________________________
744TGeometry *AliRun::GetGeometry()
745{
746 //
747 // Import Alice geometry from current file
748 // Return pointer to geometry object
749 //
750 if (!fGeometry) fGeometry = (TGeometry*)gDirectory->Get("AliceGeom");
751 //
752 // Unlink and relink nodes in detectors
753 // This is bad and there must be a better way...
754 //
fe4da5cc 755
8494b010 756 TIter next(fModules);
757 AliModule *detector;
758 while((detector = (AliModule*)next())) {
fe4da5cc 759 detector->SetTreeAddress();
760 TList *dnodes=detector->Nodes();
761 Int_t j;
762 TNode *node, *node1;
763 for ( j=0; j<dnodes->GetSize(); j++) {
764 node = (TNode*) dnodes->At(j);
52d0ab00 765 node1 = fGeometry->GetNode(node->GetName());
fe4da5cc 766 dnodes->Remove(node);
767 dnodes->AddAt(node1,j);
768 }
769 }
770 return fGeometry;
771}
772
773//_____________________________________________________________________________
774void AliRun::GetNextTrack(Int_t &mtrack, Int_t &ipart, Float_t *pmom,
775 Float_t &e, Float_t *vpos, Float_t *polar,
776 Float_t &tof)
777{
778 //
779 // Return next track from stack of particles
780 //
a8f1fb7c 781 TVector3 pol;
fe4da5cc 782 fCurrent=-1;
1578254f 783 TParticle *track;
fe4da5cc 784 for(Int_t i=fNtrack-1; i>=0; i--) {
1578254f 785 track=(TParticle*) fParticles->UncheckedAt(i);
fe4da5cc 786 if(!track->TestBit(Done_Bit)) {
787 //
788 // The track has not yet been processed
789 fCurrent=i;
1578254f 790 ipart=track->GetPdgCode();
791 pmom[0]=track->Px();
792 pmom[1]=track->Py();
793 pmom[2]=track->Pz();
794 e =track->Energy();
795 vpos[0]=track->Vx();
796 vpos[1]=track->Vy();
797 vpos[2]=track->Vz();
a8f1fb7c 798 track->GetPolarisation(pol);
799 polar[0]=pol.X();
800 polar[1]=pol.Y();
801 polar[2]=pol.Z();
1578254f 802 tof=track->T();
fe4da5cc 803 track->SetBit(Done_Bit);
804 break;
805 }
806 }
807 mtrack=fCurrent;
808 //
809 // stop and start timer when we start a primary track
810 Int_t nprimaries = fHeader.GetNprimary();
811 if (fCurrent >= nprimaries) return;
812 if (fCurrent < nprimaries-1) {
813 fTimer.Stop();
1578254f 814 track=(TParticle*) fParticles->UncheckedAt(fCurrent+1);
815 // track->SetProcessTime(fTimer.CpuTime());
fe4da5cc 816 }
817 fTimer.Start();
818}
819
820//_____________________________________________________________________________
821Int_t AliRun::GetPrimary(Int_t track)
822{
823 //
824 // return number of primary that has generated track
825 //
826 int current, parent;
1578254f 827 TParticle *part;
fe4da5cc 828 //
829 parent=track;
830 while (1) {
831 current=parent;
1578254f 832 part = (TParticle *)fParticles->UncheckedAt(current);
833 parent=part->GetFirstMother();
fe4da5cc 834 if(parent<0) return current;
835 }
836}
837
838//_____________________________________________________________________________
875c717b 839void AliRun::InitMC(const char *setup)
fe4da5cc 840{
841 //
842 // Initialize the Alice setup
843 //
844
845 gROOT->LoadMacro(setup);
45189757 846 gInterpreter->ProcessLine(fConfigFunction.Data());
fe4da5cc 847
cfce8870 848 gMC->DefineParticles(); //Create standard MC particles
fe4da5cc 849
850 TObject *objfirst, *objlast;
851
23370b7a 852 fNdets = fModules->GetLast()+1;
853
fe4da5cc 854 //
875c717b 855 //=================Create Materials and geometry
856 gMC->Init();
857
8494b010 858 TIter next(fModules);
859 AliModule *detector;
860 while((detector = (AliModule*)next())) {
fe4da5cc 861 detector->SetTreeAddress();
862 objlast = gDirectory->GetList()->Last();
863
fe4da5cc 864 // Add Detector histograms in Detector list of histograms
865 if (objlast) objfirst = gDirectory->GetList()->After(objlast);
866 else objfirst = gDirectory->GetList()->First();
867 while (objfirst) {
868 detector->Histograms()->Add(objfirst);
869 objfirst = gDirectory->GetList()->After(objfirst);
870 }
871 }
872 SetTransPar(); //Read the cuts for all materials
873
874 MediaTable(); //Build the special IMEDIA table
875
fe4da5cc 876 //Initialise geometry deposition table
875c717b 877 fEventEnergy.Set(gMC->NofVolumes()+1);
878 fSummEnergy.Set(gMC->NofVolumes()+1);
879 fSum2Energy.Set(gMC->NofVolumes()+1);
fe4da5cc 880
fe4da5cc 881 //Compute cross-sections
875c717b 882 gMC->BuildPhysics();
fe4da5cc 883
884 //Write Geometry object to current file.
885 fGeometry->Write();
886
887 fInitDone = kTRUE;
888}
889
890//_____________________________________________________________________________
891void AliRun::MediaTable()
892{
893 //
894 // Built media table to get from the media number to
895 // the detector id
896 //
ad51aeb0 897 Int_t kz, nz, idt, lz, i, k, ind;
898 // Int_t ibeg;
fe4da5cc 899 TObjArray &dets = *gAlice->Detectors();
8494b010 900 AliModule *det;
fe4da5cc 901 //
902 // For all detectors
903 for (kz=0;kz<fNdets;kz++) {
904 // If detector is defined
8494b010 905 if((det=(AliModule*) dets[kz])) {
ad51aeb0 906 TArrayI &idtmed = *(det->GetIdtmed());
907 for(nz=0;nz<100;nz++) {
fe4da5cc 908 // Find max and min material number
ad51aeb0 909 if((idt=idtmed[nz])) {
fe4da5cc 910 det->LoMedium() = det->LoMedium() < idt ? det->LoMedium() : idt;
911 det->HiMedium() = det->HiMedium() > idt ? det->HiMedium() : idt;
912 }
913 }
914 if(det->LoMedium() > det->HiMedium()) {
915 det->LoMedium() = 0;
916 det->HiMedium() = 0;
917 } else {
918 if(det->HiMedium() > fImedia->GetSize()) {
ad51aeb0 919 Error("MediaTable","Increase fImedia from %d to %d",
920 fImedia->GetSize(),det->HiMedium());
fe4da5cc 921 return;
922 }
923 // Tag all materials in rage as belonging to detector kz
924 for(lz=det->LoMedium(); lz<= det->HiMedium(); lz++) {
925 (*fImedia)[lz]=kz;
926 }
927 }
928 }
929 }
930 //
931 // Print summary table
932 printf(" Traking media ranges:\n");
933 for(i=0;i<(fNdets-1)/6+1;i++) {
934 for(k=0;k< (6<fNdets-i*6?6:fNdets-i*6);k++) {
935 ind=i*6+k;
8494b010 936 det=(AliModule*)dets[ind];
fe4da5cc 937 if(det)
938 printf(" %6s: %3d -> %3d;",det->GetName(),det->LoMedium(),
939 det->HiMedium());
940 else
941 printf(" %6s: %3d -> %3d;","NULL",0,0);
942 }
943 printf("\n");
944 }
945}
946
947//____________________________________________________________________________
948void AliRun::SetGenerator(AliGenerator *generator)
ee1dd322 949{
950 //
951 // Load the event generator
952 //
953 if(!fGenerator) fGenerator = generator;
954}
955
956//____________________________________________________________________________
957void AliRun::ResetGenerator(AliGenerator *generator)
fe4da5cc 958{
959 //
960 // Load the event generator
961 //
b13db077 962 if(fGenerator)
838edcaf 963 if(generator)
964 Warning("ResetGenerator","Replacing generator %s with %s\n",
965 fGenerator->GetName(),generator->GetName());
966 else
967 Warning("ResetGenerator","Replacing generator %s with NULL\n",
968 fGenerator->GetName());
b13db077 969 fGenerator = generator;
fe4da5cc 970}
971
972//____________________________________________________________________________
973void AliRun::SetTransPar(char* filename)
974{
975 //
976 // Read filename to set the transport parameters
977 //
978
fe4da5cc 979
980 const Int_t ncuts=10;
981 const Int_t nflags=11;
982 const Int_t npars=ncuts+nflags;
983 const char pars[npars][7] = {"CUTGAM" ,"CUTELE","CUTNEU","CUTHAD","CUTMUO",
984 "BCUTE","BCUTM","DCUTE","DCUTM","PPCUTM","ANNI",
985 "BREM","COMP","DCAY","DRAY","HADR","LOSS",
986 "MULS","PAIR","PHOT","RAYL"};
987 char line[256];
ad51aeb0 988 char detName[7];
fe4da5cc 989 char* filtmp;
990 Float_t cut[ncuts];
991 Int_t flag[nflags];
992 Int_t i, itmed, iret, ktmed, kz;
993 FILE *lun;
994 //
995 // See whether the file is there
996 filtmp=gSystem->ExpandPathName(filename);
997 lun=fopen(filtmp,"r");
998 delete [] filtmp;
999 if(!lun) {
ad51aeb0 1000 Warning("SetTransPar","File %s does not exist!\n",filename);
fe4da5cc 1001 return;
1002 }
1003 //
1004 printf(" "); for(i=0;i<60;i++) printf("*"); printf("\n");
1005 printf(" *%59s\n","*");
1006 printf(" * Please check carefully what you are doing!%10s\n","*");
1007 printf(" *%59s\n","*");
1008 //
1009 while(1) {
1010 // Initialise cuts and flags
1011 for(i=0;i<ncuts;i++) cut[i]=-99;
1012 for(i=0;i<nflags;i++) flag[i]=-99;
1013 itmed=0;
1014 for(i=0;i<256;i++) line[i]='\0';
1015 // Read up to the end of line excluded
1016 iret=fscanf(lun,"%[^\n]",line);
1017 if(iret<0) {
1018 //End of file
1019 fclose(lun);
1020 printf(" *%59s\n","*");
1021 printf(" "); for(i=0;i<60;i++) printf("*"); printf("\n");
1022 return;
1023 }
1024 // Read the end of line
1025 fscanf(lun,"%*c");
1026 if(!iret) continue;
1027 if(line[0]=='*') continue;
1028 // Read the numbers
ad51aeb0 1029 iret=sscanf(line,"%s %d %f %f %f %f %f %f %f %f %f %f %d %d %d %d %d %d %d %d %d %d %d",
1030 detName,&itmed,&cut[0],&cut[1],&cut[2],&cut[3],&cut[4],&cut[5],&cut[6],&cut[7],&cut[8],
1031 &cut[9],&flag[0],&flag[1],&flag[2],&flag[3],&flag[4],&flag[5],&flag[6],&flag[7],
1032 &flag[8],&flag[9],&flag[10]);
fe4da5cc 1033 if(!iret) continue;
1034 if(iret<0) {
1035 //reading error
ad51aeb0 1036 Warning("SetTransPar","Error reading file %s\n",filename);
fe4da5cc 1037 continue;
1038 }
ad51aeb0 1039 // Check that the module exist
1040 AliModule *mod = GetModule(detName);
1041 if(mod) {
1042 // Get the array of media numbers
1043 TArrayI &idtmed = *mod->GetIdtmed();
1044 // Check that the tracking medium code is valid
1045 if(0<=itmed && itmed < 100) {
1046 ktmed=idtmed[itmed];
1047 if(!ktmed) {
1048 Warning("SetTransPar","Invalid tracking medium code %d for %s\n",itmed,mod->GetName());
1049 continue;
fe4da5cc 1050 }
ad51aeb0 1051 // Set energy thresholds
1052 for(kz=0;kz<ncuts;kz++) {
1053 if(cut[kz]>=0) {
23370b7a 1054 printf(" * %-6s set to %10.3E for tracking medium code %4d for %s\n",
ad51aeb0 1055 pars[kz],cut[kz],itmed,mod->GetName());
cfce8870 1056 gMC->Gstpar(ktmed,pars[kz],cut[kz]);
ad51aeb0 1057 }
fe4da5cc 1058 }
ad51aeb0 1059 // Set transport mechanisms
1060 for(kz=0;kz<nflags;kz++) {
1061 if(flag[kz]>=0) {
1062 printf(" * %-6s set to %10d for tracking medium code %4d for %s\n",
1063 pars[ncuts+kz],flag[kz],itmed,mod->GetName());
cfce8870 1064 gMC->Gstpar(ktmed,pars[ncuts+kz],Float_t(flag[kz]));
ad51aeb0 1065 }
1066 }
1067 } else {
1068 Warning("SetTransPar","Invalid medium code %d *\n",itmed);
1069 continue;
fe4da5cc 1070 }
1071 } else {
ad51aeb0 1072 Warning("SetTransPar","Module %s not present\n",detName);
fe4da5cc 1073 continue;
1074 }
1075 }
1076}
1077
1078//_____________________________________________________________________________
1079void AliRun::MakeTree(Option_t *option)
1080{
1081 //
1082 // Create the ROOT trees
1083 // Loop on all detectors to create the Root branch (if any)
1084 //
1085
b13db077 1086 char hname[30];
fe4da5cc 1087 //
1088 // Analyse options
1089 char *K = strstr(option,"K");
1090 char *H = strstr(option,"H");
1091 char *E = strstr(option,"E");
1092 char *D = strstr(option,"D");
1093 char *R = strstr(option,"R");
1094 //
b13db077 1095 if (K && !fTreeK) {
1096 sprintf(hname,"TreeK%d",fEvent);
1097 fTreeK = new TTree(hname,"Kinematics");
1098 // Create a branch for particles
1099 fTreeK->Branch("Particles",&fParticles,4000);
1100 }
1101 if (H && !fTreeH) {
1102 sprintf(hname,"TreeH%d",fEvent);
1103 fTreeH = new TTree(hname,"Hits");
1104 fTreeH->SetAutoSave(1000000000); //no autosave
1105 }
1106 if (D && !fTreeD) {
1107 sprintf(hname,"TreeD%d",fEvent);
1108 fTreeD = new TTree(hname,"Digits");
1109 }
1110 if (R && !fTreeR) {
1111 sprintf(hname,"TreeR%d",fEvent);
1112 fTreeR = new TTree(hname,"Reconstruction");
1113 }
1114 if (E && !fTreeE) {
1115 fTreeE = new TTree("TE","Header");
1116 // Create a branch for Header
1117 fTreeE->Branch("Header","AliHeader",&header,4000);
1118 }
fe4da5cc 1119 //
1120 // Create a branch for hits/digits for each detector
1121 // Each branch is a TClonesArray. Each data member of the Hits classes
1122 // will be in turn a subbranch of the detector master branch
8494b010 1123 TIter next(fModules);
1124 AliModule *detector;
1125 while((detector = (AliModule*)next())) {
fe4da5cc 1126 if (H || D || R) detector->MakeBranch(option);
1127 }
fe4da5cc 1128}
1129
1130//_____________________________________________________________________________
1131Int_t AliRun::PurifyKine(Int_t lastSavedTrack, Int_t nofTracks)
1132{
1133 //
1134 // PurifyKine with external parameters
1135 //
1136 fHgwmk = lastSavedTrack;
1137 fNtrack = nofTracks;
1138 PurifyKine();
1139 return fHgwmk;
1140}
1141
1142//_____________________________________________________________________________
1143void AliRun::PurifyKine()
1144{
1145 //
1146 // Compress kinematic tree keeping only flagged particles
1147 // and renaming the particle id's in all the hits
1148 //
1149 TClonesArray &particles = *fParticles;
1150 int nkeep=fHgwmk+1, parent, i;
1578254f 1151 TParticle *part, *partnew, *father;
fe4da5cc 1152 int *map = new int[particles.GetEntries()];
1153
1154 // Save in Header total number of tracks before compression
1155 fHeader.SetNtrack(fHeader.GetNtrack()+fNtrack-fHgwmk);
1156
a01a8b12 1157 // First pass, invalid Daughter information
fe4da5cc 1158 for(i=0; i<fNtrack; i++) {
a01a8b12 1159 // Preset map, to be removed later
1160 if(i<=fHgwmk) map[i]=i ; else map[i] = -99;
1161 ((TParticle *)particles.UncheckedAt(i))->ResetBit(Daughters_Bit);
1162 }
fe4da5cc 1163 // Second pass, build map between old and new numbering
1164 for(i=fHgwmk+1; i<fNtrack; i++) {
1578254f 1165 part = (TParticle *)particles.UncheckedAt(i);
fe4da5cc 1166 if(part->TestBit(Keep_Bit)) {
1167
1168 // This particle has to be kept
1169 map[i]=nkeep;
1170 if(i!=nkeep) {
1171
1172 // Old and new are different, have to copy
1578254f 1173 partnew = (TParticle *)particles.UncheckedAt(nkeep);
5eb58812 1174 // Change due to a bug in the HP compiler
1175 // *partnew = *part;
1176 memcpy(partnew,part,sizeof(TParticle));
fe4da5cc 1177 } else partnew = part;
1178
1179 // as the parent is always *before*, it must be already
1180 // in place. This is what we are checking anyway!
1578254f 1181 if((parent=partnew->GetFirstMother())>fHgwmk) {
fe4da5cc 1182 if(map[parent]==-99) printf("map[%d] = -99!\n",parent);
1578254f 1183 partnew->SetFirstMother(map[parent]);
fe4da5cc 1184 }
1185 nkeep++;
1186 }
1187 }
1188 fNtrack=nkeep;
1189
1578254f 1190 // Fix daughters information
ae23d366 1191 for (i=0; i<fNtrack; i++) {
1578254f 1192 part = (TParticle *)particles.UncheckedAt(i);
1193 parent = part->GetFirstMother();
ae23d366 1194 if(parent>=0) {
1195 father = (TParticle *)particles.UncheckedAt(parent);
1196 if(father->TestBit(Daughters_Bit)) {
fe4da5cc 1197
ae23d366 1198 if(i<father->GetFirstDaughter()) father->SetFirstDaughter(i);
1199 if(i>father->GetLastDaughter()) father->SetLastDaughter(i);
1200 } else {
1201 // Iitialise daughters info for first pass
1202 father->SetFirstDaughter(i);
1203 father->SetLastDaughter(i);
1204 father->SetBit(Daughters_Bit);
1205 }
fe4da5cc 1206 }
1207 }
1208
1cedd08a 1209#ifdef old
fe4da5cc 1210 // Now loop on all detectors and reset the hits
b13db077 1211 AliHit *OneHit;
8494b010 1212 TIter next(fModules);
1213 AliModule *detector;
1214 while((detector = (AliModule*)next())) {
fe4da5cc 1215 if (!detector->Hits()) continue;
1216 TClonesArray &vHits=*(detector->Hits());
1217 if(vHits.GetEntries() != detector->GetNhits())
1218 printf("vHits.GetEntries()!=detector->GetNhits(): %d != %d\n",
1219 vHits.GetEntries(),detector->GetNhits());
1220 for (i=0; i<detector->GetNhits(); i++) {
1221 OneHit = (AliHit *)vHits.UncheckedAt(i);
1222 OneHit->SetTrack(map[OneHit->GetTrack()]);
1223 }
1224 }
1cedd08a 1225#else
1226
1227 // Now loop on all registered hit lists
1228 TIter next(fHitLists);
1229 TCollection *hitList;
1230 while((hitList = (TCollection*)next())) {
1231 TIter nexthit(hitList);
1232 AliHit *hit;
1233 while((hit = (AliHit*)nexthit())) {
1234 hit->SetTrack(map[hit->GetTrack()]);
1235 }
1236 }
1237#endif
fe4da5cc 1238
1239 fHgwmk=nkeep-1;
1240 particles.SetLast(fHgwmk);
1241 delete [] map;
1242}
1243
1244//_____________________________________________________________________________
dffd31ef 1245void AliRun::BeginEvent()
fe4da5cc 1246{
1247 //
1248 // Reset all Detectors & kinematics & trees
1249 //
59fe9bd2 1250 char hname[30];
dffd31ef 1251 //
1252
1253 //
1254 if(fLego) {
1255 fLego->BeginEvent();
1256 return;
1257 }
1258
59fe9bd2 1259 //
fe4da5cc 1260 ResetStack();
1261 ResetHits();
1262 ResetDigits();
1263
1264 // Initialise event header
875c717b 1265 fHeader.Reset(fRun,fEvent);
fe4da5cc 1266
59fe9bd2 1267 if(fTreeK) {
1268 fTreeK->Reset();
875c717b 1269 sprintf(hname,"TreeK%d",fEvent);
59fe9bd2 1270 fTreeK->SetName(hname);
1271 }
1272 if(fTreeH) {
1273 fTreeH->Reset();
875c717b 1274 sprintf(hname,"TreeH%d",fEvent);
59fe9bd2 1275 fTreeH->SetName(hname);
1276 }
1277 if(fTreeD) {
1278 fTreeD->Reset();
875c717b 1279 sprintf(hname,"TreeD%d",fEvent);
59fe9bd2 1280 fTreeD->SetName(hname);
1281 }
1282 if(fTreeR) {
1283 fTreeR->Reset();
875c717b 1284 sprintf(hname,"TreeR%d",fEvent);
59fe9bd2 1285 fTreeR->SetName(hname);
1286 }
fe4da5cc 1287}
1288
1289//_____________________________________________________________________________
1290void AliRun::ResetDigits()
1291{
1292 //
1293 // Reset all Detectors digits
1294 //
8494b010 1295 TIter next(fModules);
1296 AliModule *detector;
1297 while((detector = (AliModule*)next())) {
fe4da5cc 1298 detector->ResetDigits();
1299 }
1300}
1301
1302//_____________________________________________________________________________
1303void AliRun::ResetHits()
1304{
1305 //
1306 // Reset all Detectors hits
1307 //
8494b010 1308 TIter next(fModules);
1309 AliModule *detector;
1310 while((detector = (AliModule*)next())) {
fe4da5cc 1311 detector->ResetHits();
1312 }
1313}
1314
1315//_____________________________________________________________________________
1316void AliRun::ResetPoints()
1317{
1318 //
1319 // Reset all Detectors points
1320 //
8494b010 1321 TIter next(fModules);
1322 AliModule *detector;
1323 while((detector = (AliModule*)next())) {
fe4da5cc 1324 detector->ResetPoints();
1325 }
1326}
1327
1328//_____________________________________________________________________________
875c717b 1329void AliRun::RunMC(Int_t nevent, const char *setup)
fe4da5cc 1330{
1331 //
1332 // Main function to be called to process a galice run
1333 // example
1334 // Root > gAlice.Run();
1335 // a positive number of events will cause the finish routine
1336 // to be called
1337 //
1338
fe4da5cc 1339 // check if initialisation has been done
875c717b 1340 if (!fInitDone) InitMC(setup);
fe4da5cc 1341
fe4da5cc 1342 // Create the Root Tree with one branch per detector
80762cb1 1343 MakeTree("KHDER");
fe4da5cc 1344
875c717b 1345 gMC->ProcessRun(nevent);
1346
fe4da5cc 1347 // End of this run, close files
80762cb1 1348 if(nevent>0) FinishRun();
fe4da5cc 1349}
1350
1351//_____________________________________________________________________________
1352void AliRun::RunLego(const char *setup,Int_t ntheta,Float_t themin,
1353 Float_t themax,Int_t nphi,Float_t phimin,Float_t phimax,
1354 Float_t rmin,Float_t rmax,Float_t zmax)
1355{
1356 //
1357 // Generates lego plots of:
1358 // - radiation length map phi vs theta
1359 // - radiation length map phi vs eta
1360 // - interaction length map
1361 // - g/cm2 length map
1362 //
1363 // ntheta bins in theta, eta
1364 // themin minimum angle in theta (degrees)
1365 // themax maximum angle in theta (degrees)
1366 // nphi bins in phi
1367 // phimin minimum angle in phi (degrees)
1368 // phimax maximum angle in phi (degrees)
1369 // rmin minimum radius
1370 // rmax maximum radius
1371 //
1372 //
1373 // The number of events generated = ntheta*nphi
1374 // run input parameters in macro setup (default="Config.C")
1375 //
1376 // Use macro "lego.C" to visualize the 3 lego plots in spherical coordinates
1377 //Begin_Html
1378 /*
1439f98e 1379 <img src="picts/AliRunLego1.gif">
fe4da5cc 1380 */
1381 //End_Html
1382 //Begin_Html
1383 /*
1439f98e 1384 <img src="picts/AliRunLego2.gif">
fe4da5cc 1385 */
1386 //End_Html
1387 //Begin_Html
1388 /*
1439f98e 1389 <img src="picts/AliRunLego3.gif">
fe4da5cc 1390 */
1391 //End_Html
1392 //
1393
1394 // check if initialisation has been done
875c717b 1395 if (!fInitDone) InitMC(setup);
b13db077 1396
838edcaf 1397 //Save current generator
1398 AliGenerator *gen=Generator();
1399
b13db077 1400 //Create Lego object
1401 fLego = new AliLego("lego",ntheta,themin,themax,nphi,phimin,phimax,rmin,rmax,zmax);
1402
dffd31ef 1403 //Prepare MC for Lego Run
1404 gMC->InitLego();
1405
b13db077 1406 //Run Lego Object
dffd31ef 1407 gMC->ProcessRun(ntheta*nphi+1);
fe4da5cc 1408
1409 // Create only the Root event Tree
80762cb1 1410 MakeTree("E");
fe4da5cc 1411
1412 // End of this run, close files
80762cb1 1413 FinishRun();
838edcaf 1414
1415 // Delete Lego Object
1416 delete fLego; fLego=0;
1417
1418 // Restore current generator
1419 SetGenerator(gen);
fe4da5cc 1420}
1421
1422//_____________________________________________________________________________
1423void AliRun::SetCurrentTrack(Int_t track)
1424{
1425 //
1426 // Set current track number
1427 //
1428 fCurrent = track;
1429}
1430
1431//_____________________________________________________________________________
1578254f 1432void AliRun::SetTrack(Int_t done, Int_t parent, Int_t pdg, Float_t *pmom,
fe4da5cc 1433 Float_t *vpos, Float_t *polar, Float_t tof,
d2ecd553 1434 const char *mecha, Int_t &ntr, Float_t weight=1)
fe4da5cc 1435{
1436 //
1437 // Load a track on the stack
1438 //
1439 // done 0 if the track has to be transported
1440 // 1 if not
1441 // parent identifier of the parent track. -1 for a primary
1578254f 1442 // pdg particle code
fe4da5cc 1443 // pmom momentum GeV/c
1444 // vpos position
1445 // polar polarisation
1446 // tof time of flight in seconds
1447 // mecha production mechanism
1448 // ntr on output the number of the track stored
1449 //
1450 TClonesArray &particles = *fParticles;
1578254f 1451 TParticle *particle;
fe4da5cc 1452 Float_t mass;
1578254f 1453 const Int_t firstdaughter=-1;
1454 const Int_t lastdaughter=-1;
fe4da5cc 1455 const Int_t KS=0;
1578254f 1456 // const Float_t tlife=0;
fe4da5cc 1457
1578254f 1458 //
1459 // Here we get the static mass
1460 // For MC is ok, but a more sophisticated method could be necessary
1461 // if the calculated mass is required
1462 // also, this method is potentially dangerous if the mass
1463 // used in the MC is not the same of the PDG database
1464 //
1465 mass = TDatabasePDG::Instance()->GetParticle(pdg)->Mass();
fe4da5cc 1466 Float_t e=TMath::Sqrt(mass*mass+pmom[0]*pmom[0]+
1467 pmom[1]*pmom[1]+pmom[2]*pmom[2]);
1468
1469 //printf("Loading particle %s mass %f ene %f No %d ip %d pos %f %f %f mom %f %f %f KS %d m %s\n",
1578254f 1470 //pname,mass,e,fNtrack,pdg,vpos[0],vpos[1],vpos[2],pmom[0],pmom[1],pmom[2],KS,mecha);
fe4da5cc 1471
1578254f 1472 particle=new(particles[fNtrack]) TParticle(pdg,KS,parent,-1,firstdaughter,
1473 lastdaughter,pmom[0],pmom[1],pmom[2],
1474 e,vpos[0],vpos[1],vpos[2],tof);
1475 // polar[0],polar[1],polar[2],tof,
1476 // mecha,weight);
1477 ((TParticle*)particles[fNtrack])->SetPolarisation(TVector3(polar[0],polar[1],polar[2]));
1478 ((TParticle*)particles[fNtrack])->SetWeight(weight);
fe4da5cc 1479 if(!done) particle->SetBit(Done_Bit);
a01a8b12 1480 //Declare that the daughter information is valid
1481 ((TParticle*)particles[fNtrack])->SetBit(Daughters_Bit);
fe4da5cc 1482
1483 if(parent>=0) {
1578254f 1484 particle=(TParticle*) fParticles->UncheckedAt(parent);
1485 particle->SetLastDaughter(fNtrack);
1486 if(particle->GetFirstDaughter()<0) particle->SetFirstDaughter(fNtrack);
fe4da5cc 1487 } else {
1488 //
1489 // This is a primary track. Set high water mark for this event
1490 fHgwmk=fNtrack;
1491 //
1492 // Set also number if primary tracks
1493 fHeader.SetNprimary(fHgwmk+1);
1494 fHeader.SetNtrack(fHgwmk+1);
1495 }
1496 ntr = fNtrack++;
1497}
1498
1499//_____________________________________________________________________________
1500void AliRun::KeepTrack(const Int_t track)
1501{
1502 //
1503 // flags a track to be kept
1504 //
1505 TClonesArray &particles = *fParticles;
1578254f 1506 ((TParticle*)particles[track])->SetBit(Keep_Bit);
fe4da5cc 1507}
1508
1509//_____________________________________________________________________________
875c717b 1510void AliRun::StepManager(Int_t id)
fe4da5cc 1511{
1512 //
1513 // Called at every step during transport
1514 //
1515
fe4da5cc 1516 //
1517 // --- If lego option, do it and leave
b13db077 1518 if (fLego)
fe4da5cc 1519 fLego->StepManager();
b13db077 1520 else {
1521 Int_t copy;
1522 //Update energy deposition tables
875c717b 1523 AddEnergyDeposit(gMC->CurrentVolID(copy),gMC->Edep());
fe4da5cc 1524
b13db077 1525 //Call the appropriate stepping routine;
1526 AliModule *det = (AliModule*)fModules->At(id);
1527 if(det) det->StepManager();
fe4da5cc 1528 }
fe4da5cc 1529}
1530
fe4da5cc 1531//_____________________________________________________________________________
1532void AliRun::Streamer(TBuffer &R__b)
1533{
1534 //
1535 // Stream an object of class AliRun.
1536 //
1537 if (R__b.IsReading()) {
1538 Version_t R__v = R__b.ReadVersion(); if (R__v) { }
1539 TNamed::Streamer(R__b);
1540 if (!gAlice) gAlice = this;
1541 gROOT->GetListOfBrowsables()->Add(this,"Run");
59fe9bd2 1542 fTreeE = (TTree*)gDirectory->Get("TE");
1543 if (fTreeE) fTreeE->SetBranchAddress("Header", &header);
1544 else Error("Streamer","cannot find Header Tree\n");
fe4da5cc 1545 R__b >> fNtrack;
1546 R__b >> fHgwmk;
1547 R__b >> fDebug;
1548 fHeader.Streamer(R__b);
8494b010 1549 R__b >> fModules;
fe4da5cc 1550 R__b >> fParticles;
1551 R__b >> fField;
875c717b 1552 // R__b >> fMC;
fe4da5cc 1553 R__b >> fNdets;
1554 R__b >> fTrRmax;
1555 R__b >> fTrZmax;
1556 R__b >> fGenerator;
59fe9bd2 1557 if(R__v>1) {
1558 R__b >> fPDGDB; //Particle factory object!
1559 fTreeE->GetEntry(0);
1560 } else {
1561 fHeader.SetEvent(0);
1562 fPDGDB = TDatabasePDG::Instance(); //Particle factory object!
1563 }
45189757 1564 if(R__v>2) {
1565 fConfigFunction.Streamer(R__b);
1566 } else {
1567 fConfigFunction="Config();";
1568 }
fe4da5cc 1569 } else {
1570 R__b.WriteVersion(AliRun::IsA());
1571 TNamed::Streamer(R__b);
1572 R__b << fNtrack;
1573 R__b << fHgwmk;
1574 R__b << fDebug;
1575 fHeader.Streamer(R__b);
8494b010 1576 R__b << fModules;
fe4da5cc 1577 R__b << fParticles;
1578 R__b << fField;
875c717b 1579 // R__b << fMC;
fe4da5cc 1580 R__b << fNdets;
1581 R__b << fTrRmax;
1582 R__b << fTrZmax;
1583 R__b << fGenerator;
1578254f 1584 R__b << fPDGDB; //Particle factory object!
45189757 1585 fConfigFunction.Streamer(R__b);
fe4da5cc 1586 }
1587}