Ntuple does not exist

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.

The problem is in your loop over fCurrentNtupleId. Can you change it using an independent iterator variable like what you do for your histogram?

  for (G4int i = 0; i<volumeReps; ++i) {
  {
    fCurrentNtupleId = analysisManager->CreateNtuple("Secondary Generation", "Secondary Coordinates");
    ...
}

Hi Ivana, I tried it and it makes no difference. it still complains once that the ntuple hasnt been created but it subsequently fills it

-------- WWWW ------- G4Exception-START -------- WWWW -------
*** G4Exception : Analysis_W001
      issued by : G4RootPNtupleManager::GetActivation
ntuple description id= 2 does not exist.
*** This is just a warning message. ***
-------- WWWW -------- G4Exception-END --------- WWWW -------

G4WT1 > Skipping FillNtupleIColumn for 2
G4WT1 > 
-------- WWWW ------- G4Exception-START -------- WWWW -------
*** G4Exception : Analysis_W001
      issued by : G4RootPNtupleManager::GetActivation
ntuple description id= 2 does not exist.
*** This is just a warning message. ***
-------- WWWW -------- G4Exception-END --------- WWWW -------


Can you add printing just after creating an ntuple and then check in the output, if the ntuple was created before calling Fill:

  for (G4int i = 0; i<volumeReps; ++i) {
  {
    fCurrentNtupleId = analysisManager->CreateNtuple("Secondary Generation", "Secondary Coordinates");
    G4cout << "Constructed ntuple id = " <<  fCurrentNtupleId << G4cout;
    ...
}

Also I suggest to remove all set/get Activation calls, as these are useful only if you want to have a possibility to define more analysis objects at the application start and then use only some of them.This should eliminate possible (harmless) warning from the case I described above.

its this section here. the for loop seems to work:

G4WT1 > ### Run 0 starts on worker thread 1.
G4WT1 > /run/geometryModified
G4WT1 > volumeReps in histomanager is 2
G4WT1 > the number of volumeReps for ntuple is 2
G4WT1 > fCurrentNtupleId = 1
G4WT1 > fCurrentNtupleId = 2
G4WT1 > the number of volumeReps for 3d histogram is 2
G4WT1 > ... set ntuple merging row mode : row-wise - done
G4WT1 > the copy number 2 is 2
G4WT1 > the copy name is AbsorberInSamplePV
G4WT1 > fSampleRepetitions 2
G4WT1 > 
-------- WWWW ------- G4Exception-START -------- WWWW -------
*** G4Exception : Analysis_W001
      issued by : G4RootPNtupleManager::GetActivation
ntuple description id= 2 does not exist.
*** This is just a warning message. ***
-------- WWWW -------- G4Exception-END --------- WWWW -------

G4WT1 > Skipping FillNtupleIColumn for 2
G4WT1 > 
-------- WWWW ------- G4Exception-START -------- WWWW -------
*** G4Exception : Analysis_W001
      issued by : G4RootPNtupleManager::GetActivation
ntuple description id= 2 does not exist.
*** This is just a warning message. ***
-------- WWWW -------- G4Exception-END --------- WWWW -------

G4WT1 > Skipping FillNtupleIColumn for 2
G4WT1 > the copy number 2 is 2



Same number of entries as the 3d histo though :confused:
It would be nice if we could also get this data merged as a csv though I could probably come up with a bash script.

This is expected number of entries ?

I cannot reproduce your warning, even if I reorganize the AnaEx01 example to fit your use case.

Can you do following:

  1. set analysis manager verbose level to 4
  2. add this setting in your run macro:
    /control/cout/setCoutFile output
  3. run your application with:
    ./myapp >& out
  4. create a tar file from the outputs:
    tar czvf outputs.tar.gz out *output

and send me outputs.tar.gz by e-mail to ivana.hrivnacova@cern.ch ?

Sure. thanks for the help.

Yes