Passing an argument from mac file to EventAction

Hi,
I am working on a Geant4 project where I want to pass an argument from the mac file to the RunAction.
The project is based on ExampleB1 and is kept
here
.
This is what I am trying to do:

Step 1: I create a parameter store in B1RunConfig.hh

// B1RunConfig.hh
#ifndef B1_RUN_CONFIG_HH
#define B1_RUN_CONFIG_HH

class B1RunConfig
{
public:
    static B1RunConfig *Instance(); // singleton
    void SetRunID(int val) { runID = val; }
    int GetRunID() const { return runID; }

private:
    B1RunConfig() = default;
    int runID = 0;
};

#endif

and B1RunConfig.cc

// B1RunConfig.cc
#include "B1RunConfig.hh"

B1RunConfig *B1RunConfig::Instance()
{
    static B1RunConfig instance;
    return &instance;
}

Step 2: I made a messenger:
B1RunMessenger.hh

// B1RunMessenger.hh
#ifndef B1_RUN_MESSENGER_HH
#define B1_RUN_MESSENGER_HH

#include "G4UImessenger.hh"
#include "G4UIcmdWithAnInteger.hh"
#include "B1RunConfig.hh"

class B1RunMessenger : public G4UImessenger
{
public:
    B1RunMessenger();
    ~B1RunMessenger();

    void SetNewValue(G4UIcommand *command, G4String value) override;

private:
    G4UIcmdWithAnInteger *runIDCmd;
};

#endif

B1RunMessenger.cc

// B1RunMessenger.cc
#include "B1RunMessenger.hh"
#include "G4UIdirectory.hh"

B1RunMessenger::B1RunMessenger()
{
    auto dir = new G4UIdirectory("/myapp/");
    dir->SetGuidance("Custom app controls.");

    runIDCmd = new G4UIcmdWithAnInteger("/myapp/setRunID", this);
    runIDCmd->SetGuidance("Set custom run ID.");
    runIDCmd->SetParameterName("runID", false);
}

B1RunMessenger::~B1RunMessenger()
{
    delete runIDCmd;
}

void B1RunMessenger::SetNewValue(G4UIcommand *command, G4String value)
{
    if (command == runIDCmd)
    {
        B1RunConfig::Instance()->SetRunID(runIDCmd->GetNewIntValue(value));
    }
}

Step 3: I use B1RunConfig in B1RunAction:

G4int id = B1RunConfig::Instance()->GetRunID();
G4cout << "B1RunAction: Received run ID = " << id << G4endl;

Step 4: In my exampleB1.cc, I instantiate the messenger:

// Instantiate messenger
  static B1RunMessenger messenger; // static keeps it alive

Step 5: In the mac file, I pass the required argument:

/myapp/setRunID 42

While the setup is compiling fine, I see the argument is not passed from the mac file to the B1EventAction.
I see the required argument runID is always 0, which is the default value.

May I know what I am doing wrong here?
How should I pass an argument from the mac file to the RunAction?
Any help will be much appreciated.

Thank you,
Arka

Geant4 Version: 11.3.2
_Operating System:_x86_64-apple-darwin24.5.0
_Compiler/Version:_Apple clang version 17.0.0 (clang-1700.0.13.5)
_CMake Version:_4.0.3


Hello! I’m still pretty new at this, but I did write a few interactive commands for my simulation to do things like take an input to set a distance between a source and detector. I decided to just use the inbuilt G4GenericMessenger to create the commands in the same way as that in Example B5. It could be worth investigating that, as I think it’ll be easier, at least for something relatively simple like changing the run ID.

Also, in your github link, which branch are you currently working on? I’ve tried both the linked one (arka_dev) and the main branch, and neither compile off the bat, so I just wanted to check that it’s up to date before I start trying to play with it.

Dear Azhou,
Thanks for the hints.
I will look into the example B5.

As per the repository branches, the current working branch is arka_dev.
I am working on the project of B1_JUSL_Gaisser in this repo.
To build it, one needs to go inside B1_JUSL_Gaisser do the following:

mkdir build && cd build
cmake .. -DCMAKE_POLICY_VERSION_MINIMUM=3.5
make

To run it, one needs to use:

./exampleB1 run2.mac
from the build directory.

I hope this helps.

Best,
Arka

Got it to compile! So here’s what I think is going on. It looks like you’re successfully giving the value to the RunAction class based on the "B1RunAction: Received run ID = " print statement giving the input value, but you’re not actually setting the run ID anywhere. G4Run class has a function SetRunID built in, but I don’t see you using it. Instead you have a new SetRunID function in your B1RunConfig which, as far as I can tell, doesn’t talk to the current run anywhere.

I was able to fix this by, at BeginOfRunAction, telling the run manager to set the ID of the current run to whatever the value is in your RunConfig class. It does mean that you’ll have to update the run number between each run though. I might suggest you figure out how to incorporate G4RunManager::SetRunIDCounter() into your command instead.

Best,
Alistaer

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.