C++ for Geant4 users A collection of most useful and/or common features used in and to use Geant4 Marc Verderi LLR – Ecole polytechnique 14/11/2018 Marc Verderi - LLR Ecole polytechnique
Marc Verderi - LLR Ecole polytechnique Introduction Geant4 user’s interfaces do not involve “expert” C++ features. The most advanced features exposed to the user: Inheritance The feature that makes a programming language “Object Oriented” And which makes Geant4 versatile and extendable Singletons Which is the technique used for the many “managers” in Geant4 A little of templates The so-called “generic programming” Hope here is to make novice users a bit more comfortable with the above: Assuming basic syntax is known (int, double, i++, for(…){..}, etc…) Speak about Class constructor/destructor, methods & arguments, const, initialization and operator overloading Singleton 14/11/2018 Marc Verderi - LLR Ecole polytechnique
Marc Verderi - LLR Ecole polytechnique Class 14/11/2018 Marc Verderi - LLR Ecole polytechnique
Class : constructor/destructor Class declaration: class AClass { public: // default constructor: AClass(); // copy constructor: AClass(const AClass &); // other constructor: AClass([arguments]); // destructor ~AClass(); … }; At use: #include “AClass.hh” … [some main, method…]{ AClass objA; AClass objB(objA); AClass objC([arg. values]); AClass *p_obj = new AClass; } // here, destructor called // for objA, objB, objC, // but not for *p_obj that // requires delete p_obj; Used when object passed by value. Heavily used by STL: eg std::vector<T>, when increasing vector capacity 14/11/2018 Marc Verderi - LLR Ecole polytechnique
Class : method & arguments Class declaration: class AClass { … public: int fun1(int i); // default argument: double fun2(int n=0); // argument type: double fun2(double); // !! Ambiguity here !! double fun2(double w=3.14); // !! not allowed !! int fun2(double); }; At use: #include “AClass.hh” … [some main, method…]{ AClass objA; int i = objA.fun1(5); double x = objA.fun2(); double z = objA.fun2(3.14); // is it n=0 or w=3.14 ? double v = objA.fun2(); 14/11/2018 Marc Verderi - LLR Ecole polytechnique
Class : “publicity” levels Class declaration: class AClass { … public: // access to everyone: int publicFun(); protected: // access to derived classes: double protectFun(); private: // access to this class only // (and “friend” classes) void privateFun(); int someNumber; }; At use: #include “AClass.hh” … [some main, method…]{ AClass objA; int i = objA.publicFun(); // valid only in derived // classes code (see later): double a = objA.protectFun(); // valid only in AClass code: objA.privateFun(); int m = objA.someNumber; 14/11/2018 Marc Verderi - LLR Ecole polytechnique
Marc Verderi - LLR Ecole polytechnique Class : keyword const Class declaration: class AClass { … public: // pointing to constant int const int* add(int i) {someNumber += i; return &someNumber;} // object itself unaffected: int number() const {return someNumber;} // !! Wrong !! void increment() const {someNumber++;} private: int someNumber; }; At use: #include “AClass.hh” … [some main, method…]{ AClass objA; const int* j = objA.add(5); // !! Wrong !! int *n = objA.add(5); int k = objA.number(); 14/11/2018 Marc Verderi - LLR Ecole polytechnique
Class : initialization Class declaration: class AClass { … public: AClass(int); AClass(double); AClass(int, int); private: int number; const double pi; }; Class implementation: #include “AClass.hh” // could be: AClass::AClass(int i) { number = i; } // or : number(i) {;} // here no choice, as const: AClass::AClass(double p) : pi(p) 14/11/2018 Marc Verderi - LLR Ecole polytechnique
Class : initialization Class declaration: class AClass { … public: AClass(int); AClass(double); AClass(int, int); private: int number; const double pi; BClass b; }; With only constructor of BClass being with two int as arguments. Class implementation: #include “AClass.hh” // must construct b in all // cases: AClass::AClass(int i) : number(i), b(0,0) {;} // here as well: AClass::AClass(double p) : pi(p), b(0,0) AClass::AClass(int i, int j) : b(i,j) Instructions are executed following the ordering passed after the “:” Note that all members are not initialized properly here ! ;-) 14/11/2018 Marc Verderi - LLR Ecole polytechnique
Class : operator overloading Class declaration: Syntax for operator overloading cryptic class AClass { … public: // operator “=”: AClass& operator = (const AClass& toCopy); // remember that all operators // can be overloaded, even the // “new” and “delete” ones. }; Not operator overloading: // Global functions: AClass operator + (const AClass&, const AClass&); At use: #include “AClass.hh” … [some main, method…]{ AClass toCopy, objA; objA = toCopy; AClass objI, objJ, objK; objI = objJ + objK; 14/11/2018 Marc Verderi - LLR Ecole polytechnique
The main feature that makes a language object oriented Inheritance The main feature that makes a language object oriented 14/11/2018 Marc Verderi - LLR Ecole polytechnique
the actual behavior is the one of the derived class Inheritance You define a base class (base class, interface, abstract interface, etc…) Specifying what this class should be able to do and from there derived classes Which are of the type of the base class But which specializes it : ie the actual behavior is the one of the derived class Animal: - locomotion() - feeding() Too complicated operations to be described by only a few parameters common to all Animal categories ! HumanBeing:Animal - locomotion() : walk - feeding() : everything Fish:Animal - locomotion() : swim - feeding() : fish,insects Bird:Animal - locomotion() : fly - feeding() : insects 14/11/2018 Marc Verderi - LLR Ecole polytechnique
Marc Verderi - LLR Ecole polytechnique Inheritance in Geant4 ? Used in many places (as it must !) For example: Geometry: G4VSolid: Abstract interface to describe all geometrical shapes G4Box, G4Tubs, etc… are derived from G4VSolid (actually G4VCSGSolid, itself derived from G4VSolid) Physics: G4VProcess: Abstract interface common to all physical processes: Gamma conversion, multiple scattering, photo-fission, etc… Sensitivity: G4VSensitiveDetector, G4VHit, etc… User interfaces: Detector construction: G4VUserDetectorConstruction User actions: G4UserTrackingAction, G4UserSteppingAction,… … 14/11/2018 Marc Verderi - LLR Ecole polytechnique
Marc Verderi - LLR Ecole polytechnique Inheritance in Geant4 ? Used in many places (as it must !) For example: Geometry: G4VSolid: Abstract interface to describe all geometrical shapes G4Box, G4Tubs, etc… are derived from G4VSolid (actually G4VCSGSolid, itself derived from G4VSolid) Physics: G4VProcess: Abstract interface common to all physical processes: Gamma conversion, multiple scattering, photo-fission, etc… Sensitivity: G4VSensitiveDetector, G4VHit, etc… User interfaces: Detector construction: G4VUserDetectorConstruction User actions: G4UserTrackingAction, G4UserSteppingAction,… … Navigation in Geant4 never asks: distanceToBox if solid is a box distanceToTubs if solid is a tub … But only: distanceTo the solid C++ compiler does the rest: Use method for box if solid is a box, Use method for tub, if solid is a tub, Makes the navigation generic If a new solid shape is created, it will be accommodated for free, as inheriting from G4VSolid class. X X X X 14/11/2018 Marc Verderi - LLR Ecole polytechnique
Marc Verderi - LLR Ecole polytechnique Inheritance in Geant4 ? Used in many places (as it must !) For example: Geometry: G4VSolid: Abstract interface to describe all geometrical shapes G4Box, G4Tubs, etc… are derived from G4VSolid (actually G4VCSGSolid, itself derived from G4VSolid) Physics: G4VProcess: Abstract interface common to all physical processes: Gamma conversion, multiple scattering, photo-fission, etc… Sensitivity: G4VSensitiveDetector, G4VHit, etc… User interfaces: Detector construction: G4VUserDetectorConstruction User actions: G4UserTrackingAction, G4UserSteppingAction,… … 14/11/2018 Marc Verderi - LLR Ecole polytechnique
Inheritance : the keyword virtual A class is a « base class/abstract class/… » if at least one of its methods is declared « virtual » Makes the compiler aware that the code to call is that of the daughter classes Example in G4UserSteppingAction: virtual void UserSteppingAction(const G4Step*) {;} In this case, it has a default implementation… Which does nothing (but in general, can be more than that) The class is an « interface » You can create an object of this type in memory: G4UserSteppingAction dummySteppingAction; Example in G4VUserDetectorConstruction: virtual G4VPhysicalVolume* Construct() = 0; It is a so-called « pure virtual method »: It does not propose a default implementation The class is an « abstract interface » Creating such an object in memory is not possible Only pointers on it can be declared: G4VUserDetectorConstruction* detector; 14/11/2018 Marc Verderi - LLR Ecole polytechnique
Syntax for inheritance Example of detector construction, in example N03 In header file G4VUserDetectorConstruction.hh : class G4VUserDetectorConstruction { … public: virtual G4VPhysicalVolume* Construct() = 0; }; In header file ExN03DectectorConstruction.hh : class ExN03DectectorConstruction : public G4VUserDetectorConstruction G4VPhysicalVolume* Construct(); 14/11/2018 Marc Verderi - LLR Ecole polytechnique
Inheritance: a few more things Remember about publicity keywords: “public:” fields are accessible to all “protected:” These fields are accessible to daughter classes “private:”: fields accessible to the class only (and to “friend” classes) Destructor of a base class is declared virtual In general, to allow your stuff to be deleted when the destructor of the base class is called Initialization: Base class constructor to be called as case “BClass” before At execution time: A construction of a daughter class proceeds as follows: First the constructor of base class is called Then the constructor of daughter class is called Automatically 14/11/2018 Marc Verderi - LLR Ecole polytechnique
One word about the technique used for the various “managers” in Geant4 Singleton One word about the technique used for the various “managers” in Geant4 14/11/2018 Marc Verderi - LLR Ecole polytechnique
Marc Verderi - LLR Ecole polytechnique Singleton A singleton is a class for which only one instance can be created in memory By construction ie: no choice ! Technique very useful to gather informations: Keep track of all volumes created Of all particles types declared in the simulation Etc… Provide a unique entity to which you can ask What exist as volumes, or particles, etc… But also, ask to add or remove a volume, a particle,… Technique makes use of the keyword static If in a class declaration a data member is declared static, all objects in memory of that class will share the same data member 14/11/2018 Marc Verderi - LLR Ecole polytechnique
G4SDManager* manager = G4SDManager::GetSDMpointer(); Singleton: an example In G4SDManager.hh: class G4SDManager { public: static G4SDManager* GetSDMpointer(); … private: G4SDManager(); static G4SDManager* fSDManager; }; In G4SDManager.cc: G4SDManager* G4SDManager::fSDManager = 0; G4SDManager* G4SDManager::GetSDMpointer() { if (!fSDManager) fSDManager = new G4SDManager(); } return fSDManager; Since constructor is private, only the class can create a G4SDManager Indeed, I lie: in the code it is actually protected, but this is to make things simplier The static pointer (and thus unique) is initialized to zero. Then, upon first call to GetSDMpointer(), the unique instance is created: G4SDManager* manager = G4SDManager::GetSDMpointer(); 14/11/2018 Marc Verderi - LLR Ecole polytechnique
Marc Verderi - LLR Ecole polytechnique That’s all… 14/11/2018 Marc Verderi - LLR Ecole polytechnique