Defining/writing a histogram

I have a weird problem trying to fill a histogram. When the histogram is defined in BeginofRunAction via

G4double Xmax = 15.; G4double Ymax = 15.;
G4int Xbins = 30; G4int Ybins = 30;
analysisManager->CreateH2("gen_events","Generated Events", Xbins, -Xmax, +Xmax, Ybins, -Ymax, +Ymax);

all is fine. The histogram is written to the root file. But whenever I use variables from the code to define the histogram bounds, e.g.

G4double Xmax = MuDetector->GetWorld_sizeX()/2.;
G4double Ymax = MuDetector->GetWorld_sizeY()/2.;
G4int Xbins = int(2.*Xmax);
G4int Ybins = int(2.*Ymax);

there is no more histogram in the root file even though G4cout tells me the parameters I am passing to CreateH2 are the same in both cases.

I can also test the histogram contents in EndofRunAction, with
G4cout << " mean_x = " << G4BestUnit(analysisManager->GetH2(0)->mean_x(), “Length”)<<G4endl;

I get some statistics in the first case and a segfault in the second (histogram does not exist)

*** G4Exception : Analysis_W011
issued by : G4THnManager::GetH2
histogram 0 does not exist.

What am I doing wrong???

where do you print those parameters to check? are there any warnings printed?

Hey @tanbotto which type is your MuDetector and could you also let us see the output with /run/verbose/ 2 please.

This is how i call(?) MuDetectorConstruction in RunAction. The function GetWorld_sizeX() simply returns the value of a function that was set in MuDetectorConstruction.

MuRunAction::MuRunAction(G4String filename)
: G4UserRunAction(),
    out_filename = filename;
    /* Histogram bounds need to be adjusted to our geometry */ 
    MuDetector = static_cast<const MuDetectorConstruction*>
    G4double Xmax, Ymax;
    Xmax = MuDetector->GetWorld_sizeX()/2.;
    Ymax = MuDetector->GetWorld_sizeY()/2.;
    G4double Xbins = (2.*Xmax);
    G4double Ybins = (2.*Ymax);
    G4cout<<"$$$$ "<<Xbins<<" "<<Xmax<<" "<<Ybins<<" "<<Ymax<<G4endl;
//     G4double Xmax = 15.; G4double Ymax = 15.;
//     G4int Xbins = 30; G4int Ybins = 30;

    /* Create analysis manager */
    auto analysisManager = G4AnalysisManager::Instance();
    G4cout << "Using " << analysisManager->GetType() << G4endl;

    analysisManager->SetNtupleMerging(true); // does not work for csv files

    /* Create histograms */     
    analysisManager->CreateH2("gen_events","Generated Events", Xbins, -Xmax, +Xmax, Ybins, -Ymax, +Ymax);

So, it turns out MyRunAction is called twice. The first call occurs before MuDetectorConstruction and G4cout returns 0 for all variables. The second time the variables are correct but it’s too late.
/run/verbose/2 shows that I crash because of

Illegal value of number of bins: nbins <= 0

Should I instantiate (?) AnalysisManager in MuRunAction::BeginOfRunAction ??


Should I instantiate (?) AnalysisManager in MuRunAction::BeginOfRunAction ??

That actually worked… is this a good way to go??

btw, I would like to whine a bit in that it would have been much easier to catch this if somehow I could suppress
" HADRONIC PROCESSES SUMMARY (verbose level 1)" that loads my screen with stuff that, while I have been advised “It’s important and you want to pay attention to”, it’s maybe not so important that I have to look at it everytime as I am building my model…

Any idea how I could suppress this lengthy summary of hadronic process ? thx


It looks like you run in multi-threaded mode, that’s why you get your RunAction constructed more times. G4 analysis manager implicitly requires that the histograms (with the same id) created on master and workers are identical (as it performs their merging at the end of run), and as this was not the case when you extracted parameters from geometry, it failed with the message that you posted.

By moving creating histograms at BeginOfRun(), you get the geometry parameters correct also on master and this explains why this helped, and why this is a good way to go.

Best regards,

1 Like