From 65227b06c384c22d847a4f2097494bbfc33e3534 Mon Sep 17 00:00:00 2001 From: Rene Brun <Rene.Brun@cern.ch> Date: Sat, 22 Apr 2006 09:23:01 +0000 Subject: [PATCH] Implement new methods in TGenerator (suggested by Christian Holm) virtual void GenerateEvent(); virtual Double_t GetParameter(const char* /*name*/) const { return 0.; } virtual void SetParameter(const char* /*name*/,Double_t /*val*/){} git-svn-id: http://root.cern.ch/svn/root/trunk@14797 27541ba8-7e3a-0410-8455-c3a389f83636 --- eg/inc/TGenerator.h | 125 +++++++++++++++++++++++++++++--- eg/src/TGenerator.cxx | 161 +++++++++++++++++++++++++++++++++++------- 2 files changed, 254 insertions(+), 32 deletions(-) diff --git a/eg/inc/TGenerator.h b/eg/inc/TGenerator.h index 2b508d71dd3..1cc461b14ef 100644 --- a/eg/inc/TGenerator.h +++ b/eg/inc/TGenerator.h @@ -1,4 +1,5 @@ -// @(#)root/eg:$Name: $:$Id: TGenerator.h,v 1.3 2000/12/13 15:13:46 brun Exp $ +// @(#)root/eg:$Name: $:$Id: TGenerator.h,v 1.4 2003/01/20 10:25:57 brun Exp $ +// -*- mode: C++ -*- // Author: Ola Nordmann 21/09/95 /************************************************************************* @@ -14,15 +15,120 @@ // // // TGenerator // // // -// Is an abstact base class, that defines the interface of ROOT and the // -// various event generators. Every event generator should inherit from // +// Is an base class, that defines the interface of ROOT to various // +// event generators. Every event generator should inherit from // // TGenerator or its subclasses. // // // -// Every class inherited from TGenerator knows already the interface to // -// the /HEPEVT/ common block. So in the event creation of the various // -// generators, the /HEPEVT/ common block should be filled // -// The ImportParticles method then parses the result from the event // -// generators into a TClonesArray of TParticle objects. // +// Derived class can overload the member function GenerateEvent // +// to do the actual event generation (e.g., call PYEVNT or similar). // +// // +// The derived class should overload the member function // +// ImportParticles (both types) to read the internal storage of the // +// generated event into either the internal TObjArray or the passed // +// TClonesArray of TParticles. // +// // +// If the generator code stores event data in the /HEPEVT/ common block // +// Then the default implementation of ImportParticles should suffice. // +// The common block /HEPEVT/ is structed like // +// // +// /* C */ // +// typedef struct { // +// Int_t nevhep; // +// Int_t nhep; // +// Int_t isthep[4000]; // +// Int_t idhep[4000]; // +// Int_t jmohep[4000][2]; // +// Int_t jdahep[4000][2]; // +// Double_t phep[4000][5]; // +// Double_t vhep[4000][4]; // +// } HEPEVT_DEF; // +// // +// // +// C Fortran // +// COMMON/HEPEVT/NEVHEP,NHEP,ISTHEP(4000),IDHEP(4000), // +// + JMOHEP(2,4000),JDAHEP(2,4000),PHEP(5,4000),VHEP(4,4000) // +// INTEGER NEVHEP,NHEP,ISTHEP,IDHEP,JMOHEP,JDAHEP // +// DOUBLE PRECISION PHEP,VHEP // +// // +// The generic member functions SetParameter and GetParameter can be // +// overloaded to set and get parameters of the event generator. // +// // +// Note, if the derived class interfaces a (set of) Fortran common // +// blocks (like TPythia, TVenus does), one better make the derived // +// class a singleton. That is, something like // +// // +// class MyGenerator : public TGenerator // +// { // +// public: // +// static MyGenerator* Instance() // +// { // +// if (!fgInstance) fgInstance = new MyGenerator; // +// return fgInstance; // +// } // +// void GenerateEvent() { ... } // +// void ImportParticles(TClonesArray* a, Option_t opt="") {...} // +// Int_t ImportParticles(Option_t opt="") { ... } // +// Int_t SetParameter(const char* name, Double_t val) { ... } // +// Double_t GetParameter(const char* name) { ... } // +// virtual ~MyGenerator() { ... } // +// protected: // +// MyGenerator() { ... } // +// MyGenerator(const MyGenerator& o) { ... } // +// MyGenerator& operator=(const MyGenerator& o) { ... } // +// static MyGenerator* fgInstance; // +// ClassDef(MyGenerator,0); // +// }; // +// // +// Having multiple objects accessing the same common blocks is not // +// safe. // +// // +// concrete TGenerator classes can be loaded in scripts and subseqent- // +// ly used in compiled code: // +// // +// // MyRun.h // +// class MyRun : public TObject // +// { // +// public: // +// static MyRun* Instance() { ... } // +// void SetGenerator(TGenerator* g) { fGenerator = g; } // +// void Run(Int_t n, Option_t* option="") // +// { // +// TFile* file = TFile::Open("file.root","RECREATE"); // +// TTree* tree = new TTree("T","T"); // +// TClonesArray* p = new TClonesArray("TParticles"); // +// tree->Branch("particles", &p); // +// for (Int_t event = 0; event < n; event++) { // +// fGenerator->GenerateEvent(); // +// fGenerator->ImportParticles(p,option); // +// tree->Fill(); // +// } // +// file->Write(); // +// file->Close(); // +// } // +// ... // +// protected: // +// TGenerator* fGenerator; // +// ClassDef(MyRun,0); // +// }; // +// // +// // Config.C // +// void Config() // +// { // +// MyRun* run = MyRun::Instance(); // +// run->SetGenerator(MyGenerator::Instance()); // +// } // +// // +// // main.cxx // +// int // +// main(int argc, char** argv) // +// { // +// TApplication app("", 0, 0); // +// gSystem->ProcessLine(".x Config.C"); // +// MyRun::Instance()->Run(10); // +// return 0; // +// } // +// // +// This is especially useful for example with TVirtualMC or similar. // // // ////////////////////////////////////////////////////////////////////////// @@ -53,6 +159,8 @@ class TGenerator : public TNamed { virtual Int_t DistancetoPrimitive(Int_t px, Int_t py); virtual void Draw(Option_t *option=""); virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py); + virtual void GenerateEvent(); + virtual Double_t GetParameter(const char* /*name*/) const { return 0.; } virtual Int_t ImportParticles(TClonesArray *particles, Option_t *option=""); virtual TObjArray *ImportParticles(Option_t *option=""); virtual TParticle *GetParticle(Int_t i) const; @@ -61,6 +169,7 @@ class TGenerator : public TNamed { virtual TObjArray *GetPrimaries(Option_t *option="") {return ImportParticles(option);} Float_t GetPtCut() const {return fPtCut;} virtual void Paint(Option_t *option=""); + virtual void SetParameter(const char* /*name*/,Double_t /*val*/){} virtual void SetPtCut(Float_t ptcut=0); // *MENU* virtual void SetViewRadius(Float_t rbox = 1000); // *MENU* virtual void SetViewRange(Float_t xmin=-10000,Float_t ymin=-10000,Float_t zmin=-10000 diff --git a/eg/src/TGenerator.cxx b/eg/src/TGenerator.cxx index 3cf7037968e..3a86b5b745b 100644 --- a/eg/src/TGenerator.cxx +++ b/eg/src/TGenerator.cxx @@ -1,4 +1,4 @@ -// @(#)root/eg:$Name: $:$Id: TGenerator.cxx,v 1.7 2002/01/24 11:39:27 rdm Exp $ +// @(#)root/eg:$Name: $:$Id: TGenerator.cxx,v 1.8 2005/08/30 06:39:31 brun Exp $ // Author: Ola Nordmann 21/09/95 /************************************************************************* @@ -11,17 +11,122 @@ ////////////////////////////////////////////////////////////////////////// // // -// TGenerator // +// TGenerator // // // -// Is an abstact base class, that defines the interface of ROOT and the // -// various event generators. Every event generator should inherit from // -// TGenerator or its subclasses. // +// Is an base class, that defines the interface of ROOT to various // +// event generators. Every event generator should inherit from // +// TGenerator or its subclasses. // // // -// Every class inherited from TGenerator knows already the interface to // -// the /HEPEVT/ common block. So in the event creation of the various // -// generators, the /HEPEVT/ common block should be filled // -// The ImportParticles method then parses the result from the event // -// generators into a TClonesArray of TParticle objects. // +// Derived class can overload the member function GenerateEvent // +// to do the actual event generation (e.g., call PYEVNT or similar). // +// // +// The derived class should overload the member function // +// ImportParticles (both types) to read the internal storage of the // +// generated event into either the internal TObjArray or the passed // +// TClonesArray of TParticles. // +// // +// If the generator code stores event data in the /HEPEVT/ common block // +// Then the default implementation of ImportParticles should suffice. // +// The common block /HEPEVT/ is structed like // +// // +// /* C */ // +// typedef struct { // +// Int_t nevhep; // Event number // +// Int_t nhep; // # of particles // +// Int_t isthep[4000]; // Status flag of i'th particle // +// Int_t idhep[4000]; // PDG # of particle // +// Int_t jmohep[4000][2]; // 1st & 2nd mother particle # // +// Int_t jdahep[4000][2]; // 1st & 2nd daughter particle # // +// Double_t phep[4000][5]; // 4-momentum and 1 word // +// Double_t vhep[4000][4]; // 4-position of production // +// } HEPEVT_DEF; // +// // +// // +// C Fortran // +// COMMON/HEPEVT/NEVHEP,NHEP,ISTHEP(4000),IDHEP(4000), // +// + JMOHEP(2,4000),JDAHEP(2,4000),PHEP(5,4000),VHEP(4,4000) // +// INTEGER NEVHEP,NHEP,ISTHEP,IDHEP,JMOHEP,JDAHEP // +// DOUBLE PRECISION PHEP,VHEP // +// // +// The generic member functions SetParameter and GetParameter can be // +// overloaded to set and get parameters of the event generator. // +// // +// Note, if the derived class interfaces a (set of) Fortran common // +// blocks (like TPythia, TVenus does), one better make the derived // +// class a singleton. That is, something like // +// // +// class MyGenerator : public TGenerator // +// { // +// public: // +// static MyGenerator* Instance() // +// { // +// if (!fgInstance) fgInstance = new MyGenerator; // +// return fgInstance; // +// } // +// void GenerateEvent() { ... } // +// void ImportParticles(TClonesArray* a, Option_t opt="") {...} // +// Int_t ImportParticles(Option_t opt="") { ... } // +// Int_t SetParameter(const char* name, Double_t val) { ... } // +// Double_t GetParameter(const char* name) { ... } // +// virtual ~MyGenerator() { ... } // +// protected: // +// MyGenerator() { ... } // +// MyGenerator(const MyGenerator& o) { ... } // +// MyGenerator& operator=(const MyGenerator& o) { ... } // +// static MyGenerator* fgInstance; // +// ClassDef(MyGenerator,0); // +// }; // +// // +// Having multiple objects accessing the same common blocks is not // +// safe. // +// // +// concrete TGenerator classes can be loaded in scripts and subseqent- // +// ly used in compiled code: // +// // +// // MyRun.h // +// class MyRun : public TObject // +// { // +// public: // +// static MyRun* Instance() { ... } // +// void SetGenerator(TGenerator* g) { fGenerator = g; } // +// void Run(Int_t n, Option_t* option="") // +// { // +// TFile* file = TFile::Open("file.root","RECREATE"); // +// TTree* tree = new TTree("T","T"); // +// TClonesArray* p = new TClonesArray("TParticles"); // +// tree->Branch("particles", &p); // +// for (Int_t event = 0; event < n; event++) { // +// fGenerator->GenerateEvent(); // +// fGenerator->ImportParticles(p,option); // +// tree->Fill(); // +// } // +// file->Write(); // +// file->Close(); // +// } // +// ... // +// protected: // +// TGenerator* fGenerator; // +// ClassDef(MyRun,0); // +// }; // +// // +// // Config.C // +// void Config() // +// { // +// MyRun* run = MyRun::Instance(); // +// run->SetGenerator(MyGenerator::Instance()); // +// } // +// // +// // main.cxx // +// int // +// main(int argc, char** argv) // +// { // +// TApplication app("", 0, 0); // +// gSystem->ProcessLine(".x Config.C"); // +// MyRun::Instance()->Run(10); // +// return 0; // +// } // +// // +// This is especially useful for example with TVirtualMC or similar. // // // ////////////////////////////////////////////////////////////////////////// @@ -75,16 +180,23 @@ TGenerator::~TGenerator() } } +//______________________________________________________________________________ +void TGenerator::GenerateEvent() +{ + // must be implemented in concrete class (see eg TPythia6) +} + //______________________________________________________________________________ TObjArray* TGenerator::ImportParticles(Option_t *option) { // -// Default primary creation method. It reads the /HEPEVT/ common block which -// has been filled by the GenerateEvent method. If the event generator does -// not use the HEPEVT common block, This routine has to be overloaded by -// the subclasses. -// The default action is to store only the stable particles (ISTHEP = 1) -// This can be demanded explicitly by setting the option = "Final" +// It reads the /HEPEVT/ common block which has been filled by the +// GenerateEvent method. If the event generator does not use the +// HEPEVT common block, This routine has to be overloaded by the +// subclasses. +// +// The default action is to store only the stable particles (ISTHEP = +// 1) This can be demanded explicitly by setting the option = "Final" // If the option = "All", all the particles are stored. // fParticles->Clear(); @@ -143,15 +255,16 @@ TObjArray* TGenerator::ImportParticles(Option_t *option) Int_t TGenerator::ImportParticles(TClonesArray *particles, Option_t *option) { // -// Default primary creation method. It reads the /HEPEVT/ common block which -// has been filled by the GenerateEvent method. If the event generator does -// not use the HEPEVT common block, This routine has to be overloaded by -// the subclasses. +// It reads the /HEPEVT/ common block which has been filled by the +// GenerateEvent method. If the event generator does not use the +// HEPEVT common block, This routine has to be overloaded by the +// subclasses. +// // The function loops on the generated particles and store them in -// the TClonesArray pointed by the argument particles. -// The default action is to store only the stable particles (ISTHEP = 1) -// This can be demanded explicitly by setting the option = "Final" -// If the option = "All", all the particles are stored. +// the TClonesArray pointed by the argument particles. The default +// action is to store only the stable particles (ISTHEP = 1) This can +// be demanded explicitly by setting the option = "Final" If the +// option = "All", all the particles are stored. // if (particles == 0) return 0; TClonesArray &clonesParticles = *particles; -- GitLab