Formation GEANT4 - LPC
description
Transcript of Formation GEANT4 - LPC
Formation GEANT4 - LPC
Emmanuel Delage, Loïc Lestand, Yann Perrot, Bogdan Vulpescu
2
Programme de la formation
• Jeudi 15 novembre : introduction générale à Geant4• Vendredi 23 novembre : exploitation + visualisation• Jeudi 29 novembre : matériaux + géométrie• Jeudi 6 décembre : physique et particules• Jeudi 13 décembre : récupération des données
3
EXTRAIRE DES DONNÉES(tiré en partie des slides de M. Asai, Tutorial G4, SLAC 2012)
4
Extraire des données
• Une expérience GEANT4 incluant la géométrie, la physique, la génération des particules primaires ne produit AUCUNE sortie
• L’utilisateur DOIT donner du code pour enregistrer les données qu’il désire!
• La récupération de données est le scoring
5
Niveaux de simulation GEANT4
Nombre total particules primaires
Expérience
Fin expérience
Émission1 particule primaire
Énergie cinétique nulle
primaire + secondaires
Évènement
Interactions physiquesTransport des particules
Étape
6
Méthodes pour extraire des données
• Utilisation de scorers dans les volumes (primitive scorers)– Créer un score à chaque évènement– Créer sa propre classe Run/Event pour accumuler les scores
• Assigner un G4VSensitiveDetector à un volume pour générer des “hits”.– Implémenter des classes utilisateurs (G4UserEventAction,
G4UserRunAction) pour récupérer au niveau de l’évènement, de la simulation
• Utilisation des classes utilisateurs (G4UserTrackingAction, G4UserSteppingAction,…)
• Accès à toutes les informations• Il faut tout écrire soi même
7
Volume sensible
• Un volume sensible, représenté par un objet de la classe G4VSensitiveDetector (détecteur) peut être assigné à un volume logique G4LogicalVolume
• Le rôle principal d’un volume sensible est de construire des objets de type G4Hit à partir des informations obtenus au cours des étapes (steps) lors du suivi des particules.
• Dans le cas où un step a lieu dans un volume logique ayant été déclaré volume sensible, l’objet G4VSensitiveDetector est invoqué avec l’objet courant G4Step
• Vous pouvez implémenter vos propres classes définissant vos détecteurs (sensitive detector) ou bien utiliser les outils dédiés offerts par GEANT4 (primitive scorers)
8
Collection de Hits
• G4VHitsCollection est la classe abstraite des deux classes G4THitsCollection et G4THitsMap.
• G4THitsCollection est un vecteur de pointeurs vers des objets de type G4Hit
• G4THitsMap est un objet de type “map” qui enregistre des clés (numéro de copie du volume) associées à des pointeurs d’objets– Ces objets ne sont pas nécessairement des hits (G4double pour les
primitive scorers de Geant4)– G4THitsMap peut néanmoins être utilisé par le volume sensible pour
enregistrer des objets de type hit.
9
G4HCofThisEvent
• A la fin d’un évènement réussi, un objet G4Event contient un objet du
type G4HCofThisEvent.
• Un objet G4HCofThisEvent contient toutes les collections de hits
générées durant l’évènement:
– Pointeur(s) vers les collections NULL si aucune collection créée durant
l’évènement.
– Chaque collection est référencée par un index unique et inchangé durant une
simulation. L’index peut être obtenu de la façon suivante:
G4SDManager::GetCollectionID(“detName/colName”);
NB: la table des index est aussi enregistrée dans G4Run
10
Sensitive detector ou primitive scorer?Sensitive detector• Vous devez implémenter vos propres
classes gérant le détecteur et les hits.• Une classe définissant un hit peut
contenir plusieurs quantités. Un hit peut contenir chaque step individuellement ou accumuler des grandeurs.
• Une collection de hits est créée pour chaque détecteur.
Primitive scorer• Nombreux scorers fournis . Possibilité
d’ajouter les siens.• Chaque scorer accumule une grandeur
pour un évènement.
• G4MultiFunctionalDetector créé une collection par scorer.
En pratique: Primitive scorers
Si vous n’êtes pas intéressé par l’enregistrement de chaque step mais plutôt par l’accumulation de grandeurs pour un évènement ou une simulation et
Si vous n’avez pas besoin de trop de scorers. Sinon, penser à implémenter son propre sensitive detector.
11
PRIMITIVE SCORERS
12
Liste des Primitive Scorers
• Longueur du track– G4PSTrackLength, G4PSPassageTrackLength
• Énergie déposée– G4PSEnergyDeposit, G4PSDoseDeposit, G4PSChargeDeposit
• Courant/flux– G4PSFlatSurfaceCurrent, G4PSSphereSurfaceCurrent, G4PSPassageCurrent– G4PSFlatSurfaceFlux, G4PSCellFlux, G4PSPassageCellFlux
• Autres– G4PSMinKinEAtGeneration, G4PSNofSecondary, G4PSNofStep
13
Les filtres
• On peut être sélectifs quant aux informations récupérées via l’utilisation de filtres
– charged * Filtre particule chargée– neutral * Filtre particule de charge neutre– Particle * Filtre sur le nom de la particule– kineticEnergy * Filtre sur une gamme d’énergie cinétique– particleWithKineticEnergy * Filtre particule + énergie cinétique
14
Définir un Primitive ScorerEn pratique…
• Dans DetectorConstruction::Construct():
1. Créer un détecteur, il s’agit d’un objet G4MultiFunctionalDetector2. Attacher un volume logique à ce détecteur3. Créer un scorer4. Éventuellement, ajouter un filtre au scorer5. Enregistrer le scorer au détecteur
15
Exemple B4dG4LogicalVolume* absorberLV = new G4LogicalVolume(…);
// Scorers // declare Absorber as a MultiFunctionalDetector scorer
G4MultiFunctionalDetector* absDetector = new G4MultiFunctionalDetector("Absorber");
G4SDManager::GetSDMpointer()->AddNewDetector(absDetector); absorberLV->SetSensitiveDetector(absDetector);
G4VPrimitiveScorer* primitive; primitive = new G4PSEnergyDeposit("Edep"); absDetector->RegisterPrimitive(primitive);
primitive = new G4PSTrackLength("TrackLength");G4SDChargedFilter* charged = new G4SDChargedFilter("chargedFilter"); primitive ->SetFilter(charged); absDetector->RegisterPrimitive(primitive);
16
Accumulation des données
• Principe:1. Récupérer la collection de hits : G4HitsMap2. Sommer la grandeur
• Application:1. Dans un code utilisateur, quel est le moment le plus adapté pour
récupérer/accumuler les informations?2. Copier dans votre répertoire de travail l’exemple
/usr/local/geant4.9.5.p01/examples/basic/B4/B4d3. Dans B4d, éditer le code source de la classe qui gèrera la récupération des hits et
l’accumulation des données
17
Exemple B4dRécupération des hits
void B4dEventAction::EndOfEventAction(const G4Event* event){ // Get sum value from hits collections // G4double absoEdep = GetSum(GetHitsCollection("Absorber/Edep", event));}
Pour rappel dans B4dDetectorConstruction:
G4MultiFunctionalDetector* absDetector = new G4MultiFunctionalDetector("Absorber");
G4VPrimitiveScorer* primitive; primitive = new G4PSEnergyDeposit("Edep");
absDetector->RegisterPrimitive(primitive);
18
Exemple B4dRécupération des hits
G4THitsMap<G4double>* B4dEventAction::GetHitsCollection(const G4String& hcName, const G4Event* event) const{ G4int hcID = G4SDManager::GetSDMpointer()->GetCollectionID(hcName); G4THitsMap<G4double>* hitsCollection = static_cast<G4THitsMap<G4double>*>( event->GetHCofThisEvent()->GetHC(hcID));
// Gestion des erreurs if ( ! hitsCollection ) { G4cerr << "Cannot access hitsCollection " << hcName << G4endl; exit(1); }
return hitsCollection;}
GetHitsCollection("Absorber/Edep", event)
19
Exemple B4dSomme de l’énergie déposée
G4double B4dEventAction::GetSum(G4THitsMap<G4double>* hitsMap) const{ G4double sumValue = 0; std::map<G4int, G4double*>::iterator it; for ( it = hitsMap->GetMap()->begin();
it != hitsMap->GetMap()->end(); it++){
sumValue += *(it->second); } return sumValue; }
GetSum(GetHitsCollection("Absorber/Edep", event))
20
Exemple B4dExemple de fichier de sortie simple
FILE* myOutputFile;myOutputFile=fopen("output.txt", "a");fprintf(myOutputFile, "#Event %i -> %d \n",
event->GetEventID(),absoEdep);
fclose(myOutputFile);
G4double absoEdep= GetSum(GetHitsCollection("Absorber/Edep", event))
Tester avec la macro run2.mac où vous aurez modifié le nombre de particules à simuler
COMMENT AVOIR DES SORTIES PLUS ÉLABORÉES ??
21
ROOT
22
ROOT
• Outil d’analyse de données:– Lecture/écriture de fichiers;– Manipulation d’histogrammes, de structures de données;– Graphiques, fits;– Calculs analytiques ou numériques;– Et tant d’autres choses!
• http://root.cern.ch– Informations générales;– Téléchargement/installation;– Tutoriaux, guides utilisateur;– Forums.
23
ROOT et C++
• ROOT consiste en une collection de classes C++• Code ROOT = code C++ interprété par CINT• Exemples d’objets ROOT:
– Fichier ROOT: TFile– Histogramme 1D, 2D: TH1F, TH2F– Ntuple: TNtuple– Fonction 1D: TF1– Graphique: TGraph
• Pour utiliser ROOT:– De manière interactive– Par le biais de scripts (macro)
root[0] .X script.CHello World !4.79583root[1]
24
Exemple B4dLecture d’un fichier ROOT 1/4
• Dans un terminal,lancer root:root
• Lancer un explorateur:new TBrowser()
25
Exemple B4dLecture d’un fichier ROOT 2/4
• Ouvrir le fichier rootFile->Open
• Le fichier sélectionnéest ajouté
• Pour visualiser le contenu:double-click, ici histogrammeset n-tuples
26
Exemple B4dLecture d’un fichier ROOT 3/4
27
Exemple B4dLecture d’un fichier ROOT 4/4
28
ROOT et GEANT4
• Geant4 dispose d’un manager d’analyse: interface uniforme pour manipuler les données dans différents formats (ROOT, AIDA, XML, CSV et HBOOK)
• Idée : utiliser le manager pour créer, remplir et sauvegarder des histogrammes, des tables, …
• Exemple B4d : déclaration de l’utilisation de ROOT dans le fichier d’entête B4Analysis.hh
#include "g4analysis_defs.hh "using namespace G4Root;
29
1- Créer le fichier ROOT
// Create analysis manager// The choice of analysis technology is done via selectin of a namespace in B4Analysis.hh
G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();
// Open an output file G4String fileName = "B4"; analysisManager->OpenFile(fileName); analysisManager->SetFirstHistoId(1);
En début de simulation: B4RunAction::BeginOfRunAction
30
2- Créer la structure du fichier ROOT
// Creating histograms analysisManager->CreateH1("1","Edep in absorber", 100, 0., 800*MeV); analysisManager->CreateH1("2","Edep in gap", 100, 0., 100*MeV); analysisManager->CreateH1("3","trackL in absorber", 100, 0., 1*m); analysisManager->CreateH1("4","trackL in gap", 100, 0., 50*cm);
// Creating ntuple // analysisManager->CreateNtuple("B4", "Edep and TrackL"); analysisManager->CreateNtupleDColumn("Eabs"); analysisManager->CreateNtupleDColumn("Egap"); analysisManager->CreateNtupleDColumn("Labs"); analysisManager->CreateNtupleDColumn("Lgap"); analysisManager->FinishNtuple();
En début de simulation: B4RunAction::BeginOfRunAction
31
3- Remplir le fichier ROOT
A la fin de chaque évènement: B4dEventAction::EndOfEventAction
// fill histograms analysisManager->FillH1(1, absoEdep); analysisManager->FillH1(2, gapEdep); analysisManager->FillH1(3, absoTrackLength); analysisManager->FillH1(4, gapTrackLength); // fill ntuple analysisManager->FillNtupleDColumn(0, absoEdep); analysisManager->FillNtupleDColumn(1, gapEdep); analysisManager->FillNtupleDColumn(2, absoTrackLength); analysisManager->FillNtupleDColumn(3, gapTrackLength); analysisManager->AddNtupleRow();
32
4- Sauvegarder le fichier ROOT
A la fin de la simulation: B4RunAction::EndOfRunAction
G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();
// save histograms
analysisManager->Write();analysisManager->CloseFile();
33
EXERCICE D’APPLICATION
34
Dénombrer le nombre de particules secondairesA partir de l’example B4d, dénombrer le nombre de photons et d’électrons secondaires créés dans le volume Absorber en utilisant des primitive scorers et des filtres. Stocker les données dans deux Ntuples ROOT.
1- Modifier la classe B4dDetectorConstruction pour y inclure les scorers.
G4PSNofSecondary::G4PSNofSecondary(G4String name)
G4SDParticleFilter::G4SDParticleFilter(G4String name_filter, const G4String& particleName)
2- Modifier la classe B4dEventAction pour dénombrer le nombre d’électrons et de photons secondaires à chaque évènement.
3- Modifier la classe B4RunAction pour créer les deux Ntuples
4- Modifier la classe B4dEventAction pour enregistrer à chaque évènement le nombre d’électrons et de photons secondaires dans les Ntuples ROOT.
35
Dénombrer le nombre de particules secondairesUne solution
1- Modifier la classe B4dDetectorConstruction pour y inclure les scorers.
Déclarations
#include "PSNofSecondary.hh"#include "G4SDParticleFilter.hh"
Dans DefineVolumes()
primitive= new G4PSNofSecondary("SecElec"); G4SDParticleFilter* elecFilter = new
G4SDParticleFilter("elecFilter","e-");primitive->SetFilter(elecFilter);absDetector->RegisterPrimitive(primitive);
Idem avec G4PSNofSecondary("SecGamma"), et G4SDParticleFilter("elecGamma",”gamma");
36
Dénombrer le nombre de particules secondairesUne solution
2- Modifier la classe B4dEventAction pour dénombrer le nombre d’électrons et de photons secondaires à chaque évènement.
Dans EndOfEventAction:
G4int nSecElec = G4int( GetSum(
GetHitsCollection("Absorber/SecElec",event) )
);
G4int nSecElec = G4int( GetSum(
GetHitsCollection("Absorber/SecElec",event) )
);
37
Dénombrer le nombre de particules secondairesUne solution
3- Modifier la classe B4RunAction pour créer les deux Ntuples
Dans BeginOfRunAction:
//Creating ntuple……analysisManager->CreateNtupleDColumn("SecGamma");analysisManager->CreateNtupleDColumn("SecElec");analysisManager->FinishNtuple();
38
Dénombrer le nombre de particules secondairesUne solution
4- Modifier la classe B4dEventAction pour enregistrer à chaque évènement le nombre d’électrons et de photons secondaires dans les Ntuples ROOT.
Dans EndOfEventAction:
//fill ntuple……analysisManager->FillNtupleDColumn(4,nSecGamma);analysisManager->FillNtupleDColumn(5,nSecElec);analysisManager->AddNtupleRow();
39
UTILISATION AVANCÉESENSITIVE DETECTOR & HITS
40
Volume sensible et hits
• Chaque volume logique peut avoir un pointeur vers un détecteur
(sensitive detector)
– Ce volume devient alors sensible
• Hit est un état d’une trace dans un volume sensible
• Un volume sensible créé des hits à partir des informations
contenus dans une étape (objet G4Step). L’utilisateur doit
donner l’implémentation de la réponse du détecteur.
• Les hits, qui sont des objets définis par l’utilisateur, sont collectés
à la fin de chaque évènement dans un objet G4Event.
41
Les informations à partir de G4Step
• Un step ->2 points– Un point = 1 position
– 1 point = 1 volume physique, 1 volume logique, matériau, numéro de copie, etc…
– 1 point = 1 processus qui a limité le step
• Un step ->– Énergie déposée
– Longueur d’étape– …
• Un step -> Une trace– Moment– Énergie cinétique..– …
• Et bien d’autres informations, voir les méthodes d’accès:
http://geant4.web.cern.ch/geant4/UserDocumentation/UsersGuides/FAQ/html/ch01s04.html
42
La classe Hit• Un Hit est une classe utilisateur dérivée de G4VHit.• L’utilisateur stocke les données qu’il désire en implémentant sa propre classe
Hit. Par exemple:– Position et temps du step – Moment, énergie de la trace – Dépôt d’énergie du step – Information géométrique
• Les objets Hit doivent être stockés dans une collection dédiée dérivée de la la classe G4THitsCollection.
• La collection est associée à un évènement via G4HCofThisEvent.• La collection est accessible:
– Par G4Event à la fin de l’évènement– Par G4SDManager lors de l’analyse d’un évènement (filtre par exemple)
43
Implémentation Hit#include "G4VHit.hh"class MyHit : public G4VHit{ public: MyHit(some_arguments); virtual ~MyHit(); virtual void Draw(); virtual void Print(); private: // some data members public: // some set/get methods};
#include “G4THitsCollection.hh”typedef G4THitsCollection<MyHit> MyHitsCollection;
44
Implémentation Sensitive Detector
#include "G4VSensitiveDetector.hh"#include "MyHit.hh"class G4Step;class G4HCofThisEvent;class MyDetector : public G4VSensitiveDetector{ public: MyDetector(G4String name); virtual ~MyDetector(); virtual void Initialize(G4HCofThisEvent*HCE); virtual G4bool ProcessHits(G4Step*aStep, G4TouchableHistory*ROhist); virtual void EndOfEvent(G4HCofThisEvent*HCE); private: MyHitsCollection * hitsCollection; G4int collectionID;};
45
CLASSE UTILISATEURS
46
Que faire au début d’un
évènement?
Exécution
Fermeture
Début expérience
Début évènement
Étape
Fin expérience
Fin évènement
Que faire au début de l’expérience?
Que faire à la fin d’un
évènement?
Que faire à la finde l’expérience?
Que faire lors d’une interaction? RunAction::
G4UserRunAction
EventAction::G4UserEventAction
SteppingAction::G4UserSteppingAction
BeginOfRunActionEndOfRunAction
BeginOfEventActionEndOfEventAction
UserSteppingAction
Principe1- L’utilisateur doit créer si besoin ses propres classes pour décrire les différents niveaux.
2- Les informations sont recueillies au niveau de l’étape à partir d’un objet G4Step
3- Les niveaux de simulation ne communiquent pas les uns avec les autres, l’utilisateur doit inclure dans ses classes des moyens pour communiquer entre les différentes classes (pointeurs, méthodes lecture/écriture de données)
47
PrincipeExemple simple
EventAction.hh
public:
EventAction();
BeginOfEventAction();EndOfEventAction();
CollectInfo();
private:
G4double Info;
SteppingAction.hh
public:
SteppingAction(EventAction *);
UserSteppingAction();
private:
EventAction* fEventAction;
Au début de l’évènement BeginOfEventAction:Remettre à zéro la quantité
A chaque Step UserSteppingAction:Collecter l’information stockée grâce à la méthode d’accès implémentée dans EventActionfEventAction->CollectInfo();
48
L’exemple B4aEventAction.hh
class B4aEventAction : public G4UserEventAction{ public: … void AddAbs(G4double de, G4double dl); void AddGap(G4double de, G4double dl); private:… G4double fEnergyAbs; G4double fEnergyGap; G4double fTrackLAbs; G4double fTrackLGap;};
49
L’exemple B4aEventAction.cc
void B4aEventAction::BeginOfEventAction(const G4Event* evt){
…
// initialisation per event fEnergyAbs = 0.; fEnergyGap = 0.; fTrackLAbs = 0.; fTrackLGap = 0.;}
50
L’exemple B4aSteppingAction.hh
class B4aEventAction;
class B4aSteppingAction : public G4UserSteppingAction{public: B4aSteppingAction(const B4DetectorConstruction* detectorConstruction, B4aEventAction* eventAction); virtual ~B4aSteppingAction();
virtual void UserSteppingAction(const G4Step* step); private: const B4DetectorConstruction* fDetConstruction; B4aEventAction* fEventAction; };
51
L’exemple B4aSteppingAction.cc
#include "B4aEventAction.hh"
B4aSteppingAction::B4aSteppingAction( const B4DetectorConstruction* detectorConstruction, B4aEventAction* eventAction) : G4UserSteppingAction(), fDetConstruction(detectorConstruction), fEventAction(eventAction){}
52
L’exemple B4aSteppingAction.cc
void B4aSteppingAction::UserSteppingAction(const G4Step* step){G4VPhysicalVolume* volume = step->GetPreStepPoint()->GetTouchableHandle()->GetVolume();
G4double edep = step->GetTotalEnergyDeposit(); // step length G4double stepLength = 0.; if ( step->GetTrack()->GetDefinition()->GetPDGCharge() != 0. ) { stepLength = step->GetStepLength(); } if ( volume == fDetConstruction->GetAbsorberPV() ) { fEventAction->AddAbs(edep,stepLength); }}