Only in begin of run action as below
void RunAction::BeginOfRunAction(const G4Run*)
{
// show Rndm status
if (isMaster) G4Random::showEngineStatus();
// keep run condition
if (fPrimary) {
G4ParticleDefinition* particle
= fPrimary->GetParticleGun()->GetParticleDefinition();
G4double energy = fPrimary->GetParticleGun()->GetParticleEnergy();
fRun->SetPrimary(particle, energy);
}
G4RunManager::GetRunManager()->GeometryHasBeenModified();
// Histograms
G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();
fHistoManager->SecondaryGenerationPositionNtuple();
fHistoManager->ThreeDHisto();
if ( analysisManager->IsActive() ) {
analysisManager->OpenFile();
}
}
the 3d histos work fine. I call the functions there because detectorconstruction has been run thus giving us the number of samples that where created from macro input. That variable is sent to histomanager as a static g4int, so it exist within the scope of the class and when the functions SecondaryPositionNtuple and ThreeDHisto are called a simple for loop creates them with the static int as the upper limit. here is the ntuple loop again.
void HistoManager::SecondaryGenerationPositionNtuple()
{
G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();
// Create ntuples.
// Ntuples ids are generated automatically starting from 0
// The start value can be changed by:
analysisManager->SetFirstNtupleId(1);
//analysisManager->SetNtupleActivation(false);
// create an ntuple of secondary Tritium
G4cout << "volumeReps in histomanager is " << volumeReps <<G4endl;
for (fCurrentNtupleId = 0; fCurrentNtupleId < volumeReps; fCurrentNtupleId++)
{
fCurrentNtupleId = analysisManager->CreateNtuple("Secondary Generation", "Secondary Coordinates");
analysisManager->CreateNtupleSColumn(fCurrentNtupleId,"ParticleName");//column id 0
analysisManager->CreateNtupleSColumn(fCurrentNtupleId,"ProcessGen"); //column id 1
analysisManager->CreateNtupleDColumn(fCurrentNtupleId,"PosX"); //column id 2
analysisManager->CreateNtupleDColumn(fCurrentNtupleId,"PosY"); //column id 3
analysisManager->CreateNtupleDColumn(fCurrentNtupleId,"PosZ"); //column id 4
analysisManager->FinishNtuple(fCurrentNtupleId);
//analysisManager->SetNtupleActivation(fCurrentNtupleId,true);
G4cout << "fCurrentNtupleId = " << fCurrentNtupleId << G4endl;
G4cout << "ntuple activation of ntuple " <<analysisManager->GetNofNtuples() <<
" is " << analysisManager->GetNtupleActivation(fCurrentNtupleId) << G4endl;
G4cout << "ntuple number " << analysisManager->GetNofNtuples() << G4endl;
}
//analysisManager->SetNtupleFileName(0,"TritiumLocation");
analysisManager->SetNtupleMerging(true);
//G4cout << "Booking ntuple 0 activation " << analysisManager->GetNtupleActivation(0) << G4endl;
//G4cout << "The 1st Ntuple id is " << analysisManager->GetFirstNtupleId() << G4endl;
}
Apologies for all this bad code. In this instance the second ntuple isnt being generated. Not sure why not. two 3d histograms are generated with pretty much the same code.
Perhaps I should share the ThreeDHistogram function. The only difference being the iterator variable type. In the ntuple case its threadlocal.
void HistoManager::ThreeDHisto()
{
G4int nbins = 100;
G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();
analysisManager->SetFirstH3Id(1);
G4cout << "the number of volumeReps for 3d histogram is " << volumeReps << G4endl;
for (G4int ThreeD=0; ThreeD<volumeReps; ThreeD++)
{
// 3D Histogram of interaction sites in Sample
analysisManager->CreateH3("Triton XYZ", "XYZ", //3D histogram title
nbins, -15.0, 15.0, //x number of bins and range
nbins, -15.0, 15.0, //y number of bins and range
nbins, -15.0, 15.0, //z number of bins and range
"mm", "mm", "mm", //xyz units
"none", "none", "none", //xyz function ?
"linear", "linear", "linear"); //axis function
}
}
This works in the way I expect.