Skip to content

Commit

Permalink
Write celer-g4 input to output file or screen (#1034)
Browse files Browse the repository at this point in the history
* Add command-line options for dumping default celer-g4 JSON
* Output required celer-g4 JSON variables
* Improve output of 'unset' primary generator distributions
* Write run input to celer-g4 output file
* Fix defaults being in 1-element array
  • Loading branch information
sethrj committed Nov 28, 2023
1 parent c2ef342 commit 1dc8da2
Show file tree
Hide file tree
Showing 10 changed files with 140 additions and 66 deletions.
13 changes: 11 additions & 2 deletions app/celer-g4/GeantDiagnostics.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
# include "corecel/io/OutputInterfaceAdapter.hh"
# include "corecel/sys/EnvironmentIO.json.hh"
# include "corecel/sys/MemRegistryIO.json.hh"

# include "RunInputIO.json.hh"
#endif

namespace celeritas
Expand Down Expand Up @@ -51,11 +53,12 @@ GeantDiagnostics::GeantDiagnostics(SharedParams const& params)
timer_output_ = std::make_shared<TimerOutput>(num_threads);
output_reg->insert(timer_output_);

if (GlobalSetup::Instance()->StepDiagnostic())
auto& global_setup = *GlobalSetup::Instance();
if (global_setup.StepDiagnostic())
{
// Create the track step diagnostic and add to output registry
step_diagnostic_ = std::make_shared<GeantStepDiagnostic>(
GlobalSetup::Instance()->GetStepDiagnosticBins(), num_threads);
global_setup.GetStepDiagnosticBins(), num_threads);
output_reg->insert(step_diagnostic_);
}

Expand All @@ -76,6 +79,12 @@ GeantDiagnostics::GeantDiagnostics(SharedParams const& params)
output_reg->insert(std::make_shared<BuildOutput>());
}

#if CELERITAS_USE_JSON
// Save input options
output_reg->insert(OutputInterfaceAdapter<RunInput>::from_const_ref(
OutputInterface::Category::input, "*", global_setup.input()));
#endif

// Create shared exception handler
meh_ = std::make_shared<MultiExceptionHandler>();

Expand Down
32 changes: 15 additions & 17 deletions app/celer-g4/GlobalSetup.cc
Original file line number Diff line number Diff line change
Expand Up @@ -111,15 +111,7 @@ void GlobalSetup::SetIgnoreProcesses(SetupOptions::VecString ignored)
*/
void GlobalSetup::ReadInput(std::string const& filename)
{
if (ends_with(filename, ".mac"))
{
CELER_LOG(status) << "Executing macro commands from '" << filename
<< "'";
G4UImanager* ui = G4UImanager::GetUIpointer();
CELER_ASSERT(ui);
ui->ApplyCommand(std::string("/control/execute ") + filename);
}
else
if (ends_with(filename, ".json"))
{
#if CELERITAS_USE_JSON
using std::to_string;
Expand Down Expand Up @@ -153,18 +145,24 @@ void GlobalSetup::ReadInput(std::string const& filename)
options_->cuda_heap_size = input_.cuda_heap_size;
options_->sync = input_.sync;
options_->default_stream = input_.default_stream;

// Execute macro for Geant4 commands (e.g. to set verbosity)
if (!input_.macro_file.empty())
{
G4UImanager* ui = G4UImanager::GetUIpointer();
CELER_ASSERT(ui);
ui->ApplyCommand("/control/execute " + input_.macro_file);
}
#else
CELER_NOT_CONFIGURED("nlohmann_json");
#endif
}
else if (ends_with(filename, ".mac"))
{
input_.macro_file = filename;
}

// Execute macro for Geant4 commands (e.g. to set verbosity)
if (!input_.macro_file.empty())
{
CELER_LOG(status) << "Executing macro commands from '" << filename
<< "'";
G4UImanager* ui = G4UImanager::GetUIpointer();
CELER_ASSERT(ui);
ui->ApplyCommand("/control/execute " + input_.macro_file);
}

// Set the filename for JSON output
if (CELERITAS_USE_JSON && input_.output_file.empty())
Expand Down
2 changes: 2 additions & 0 deletions app/celer-g4/RunInput.hh
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ enum class SensitiveDetectorType
//---------------------------------------------------------------------------//
/*!
* Input for a single run.
*
* TODO: field type should be std::variant
*/
struct RunInput
{
Expand Down
51 changes: 29 additions & 22 deletions app/celer-g4/RunInputIO.json.cc
Original file line number Diff line number Diff line change
Expand Up @@ -146,49 +146,56 @@ void to_json(nlohmann::json& j, RunInput const& v)
if (!(v.NAME == default_args.NAME)) \
j[#NAME] = v.NAME; \
} while (0)
#define RI_SAVE_REQUIRED(NAME) j[#NAME] = v.NAME
#define RI_SAVE(NAME) j[#NAME] = v.NAME

RI_SAVE_REQUIRED(geometry_file);
RI_SAVE(geometry_file);
RI_SAVE_OPTION(event_file);

if (v.event_file.empty())
{
RI_SAVE_REQUIRED(primary_options);
RI_SAVE(primary_options);
}

RI_SAVE_OPTION(num_track_slots);
RI_SAVE_OPTION(max_events);
RI_SAVE(num_track_slots);
RI_SAVE(max_events);
RI_SAVE_OPTION(max_steps);
RI_SAVE_OPTION(initializer_capacity);
RI_SAVE_OPTION(secondary_stack_factor);
RI_SAVE(initializer_capacity);
RI_SAVE(secondary_stack_factor);
RI_SAVE_OPTION(cuda_stack_size);
RI_SAVE_OPTION(cuda_heap_size);
RI_SAVE_OPTION(sync);
RI_SAVE_OPTION(default_stream);
RI_SAVE(sync);
RI_SAVE(default_stream);

RI_SAVE_OPTION(physics_list);
RI_SAVE(physics_list);
if (v.physics_list == PhysicsListSelection::geant_physics_list)
{
RI_SAVE_OPTION(physics_options);
RI_SAVE(physics_options);
}

RI_SAVE_OPTION(field_type);
RI_SAVE_OPTION(field_file);
RI_SAVE_OPTION(field);
RI_SAVE_OPTION(field_options);
RI_SAVE(field_type);
if (v.field_type == "rzmap")
{
RI_SAVE(field_file);
RI_SAVE(field_options);
}
else if (v.field != RunInput::no_field())
{
RI_SAVE(field);
RI_SAVE(field_options);
}

RI_SAVE_OPTION(sd_type);
RI_SAVE(sd_type);

RI_SAVE_OPTION(output_file);
RI_SAVE_OPTION(physics_output_file);
RI_SAVE_OPTION(offload_output_file);
RI_SAVE_OPTION(macro_file);
RI_SAVE(output_file);
RI_SAVE(physics_output_file);
RI_SAVE(offload_output_file);
RI_SAVE(macro_file);

RI_SAVE_OPTION(step_diagnostic);
RI_SAVE(step_diagnostic);
RI_SAVE_OPTION(step_diagnostic_bins);

#undef RI_SAVE_OPTION
#undef RI_SAVE_REQUIRED
#undef RI_SAVE
}

//---------------------------------------------------------------------------//
Expand Down
84 changes: 62 additions & 22 deletions app/celer-g4/celer-g4.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,15 @@
#include <iostream>
#include <memory>
#include <string>
#include <string_view>
#include <vector>
#include <CLHEP/Random/Random.h>
#include <FTFP_BERT.hh>
#include <G4ParticleTable.hh>
#include <G4RunManager.hh>
#include <G4UIExecutive.hh>
#include <G4Version.hh>

#include "accel/SharedParams.hh"

#include "GlobalSetup.hh"

#if G4VERSION_NUMBER >= 1100
# include <G4RunManagerFactory.hh>
#else
Expand All @@ -31,8 +29,14 @@
# include <G4GlobalConfig.hh>
#endif

#include <FTFP_BERT.hh>
#include "celeritas_config.h"
#if CELERITAS_USE_JSON
# include <nlohmann/json.hpp>

# include "RunInputIO.json.hh"
#endif

#include "celeritas_version.h"
#include "corecel/Assert.hh"
#include "corecel/Macros.hh"
#include "corecel/io/ExceptionOutput.hh"
Expand All @@ -52,6 +56,7 @@
#include "celeritas/ext/ScopedGeantLogger.hh"
#include "celeritas/ext/ScopedRootErrorHandler.hh"
#include "celeritas/ext/detail/GeantPhysicsList.hh"
#include "accel/SharedParams.hh"

#include "ActionInitialization.hh"
#include "DetectorConstruction.hh"
Expand All @@ -66,6 +71,28 @@ namespace app
{
namespace
{
//---------------------------------------------------------------------------//
void print_usage(std::string_view exec_name)
{
// clang-format off
std::cerr << "usage: " << exec_name << " {input}.json\n"
" " << exec_name << " {commands}.mac\n"
" " << exec_name << " --interactive\n"
" " << exec_name << " [--help|-h]\n"
" " << exec_name << " --version\n"
" " << exec_name << " --dump-default\n"
"Environment variables:\n"
" G4FORCE_RUN_MANAGER_TYPE: MT or Serial\n"
" G4FORCENUMBEROFTHREADS: set CPU worker thread count\n"
" CELER_DISABLE: nonempty disables offloading\n"
" CELER_DISABLE_DEVICE: nonempty disables CUDA\n"
" CELER_DISABLE_ROOT: nonempty disables ROOT I/O\n"
" CELER_LOG: global logging level\n"
" CELER_LOG_LOCAL: thread-local logging level\n"
<< std::endl;
// clang-format on
}

//---------------------------------------------------------------------------//
void run(int argc, char** argv, std::shared_ptr<SharedParams> params)
{
Expand Down Expand Up @@ -202,23 +229,6 @@ void run(int argc, char** argv, std::shared_ptr<SharedParams> params)
*/
int main(int argc, char* argv[])
{
if (argc != 2 || argv[1] == "--help"sv || argv[1] == "-h"sv)
{
std::cerr << "usage: " << argv[0] << " {input}.json\n"
<< " " << argv[0] << " {commands}.mac\n"
<< " " << argv[0] << " --interactive\n"
<< "Environment variables:\n"
<< " G4FORCE_RUN_MANAGER_TYPE: MT or Serial\n"
<< " G4FORCENUMBEROFTHREADS: set CPU worker thread count\n"
<< " CELER_DISABLE: nonempty disables offloading\n"
<< " CELER_DISABLE_DEVICE: nonempty disables CUDA\n"
<< " CELER_DISABLE_ROOT: nonempty disables ROOT I/O\n"
<< " CELER_LOG: global logging level\n"
<< " CELER_LOG_LOCAL: thread-local logging level\n"
<< std::endl;
return EXIT_FAILURE;
}

using celeritas::MpiCommunicator;
using celeritas::ScopedMpiInit;

Expand All @@ -236,6 +246,36 @@ int main(int argc, char* argv[])
return EXIT_FAILURE;
}

// Process input arguments
if (argc != 2)
{
celeritas::app::print_usage(argv[0]);
return EXIT_FAILURE;
}
std::string_view filename{argv[1]};
if (filename == "--help"sv || filename == "-h"sv)
{
celeritas::app::print_usage(argv[0]);
return EXIT_SUCCESS;
}
if (filename == "--version"sv || filename == "-v"sv)
{
std::cout << celeritas_version << std::endl;
return EXIT_SUCCESS;
}
if (filename == "--dump-default"sv)
{
#if CELERITAS_USE_JSON
std::cout << nlohmann::json(celeritas::app::RunInput{}).dump(1)
<< std::endl;
return EXIT_SUCCESS;
#else
CELER_LOG(critical) << "JSON is not enabled in this build of "
"Celeritas";
return EXIT_FAILURE;
#endif
}

// Create params, which need to be shared with detectors as well as
// initialization, and can be written for output
auto params = std::make_shared<celeritas::SharedParams>();
Expand Down
1 change: 1 addition & 0 deletions app/celer-g4/celer-g4.nogeant.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//! \file celer-g4/celer-g4.nogeant.cc
//---------------------------------------------------------------------------//
#include <iostream>
#include <cstdlib>

//---------------------------------------------------------------------------//
/*!
Expand Down
6 changes: 6 additions & 0 deletions app/celer-g4/test-harness.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,9 @@ def strtobool(text):
result = json.load(f)

pprint(result["result"])

# Rewrite with indentation
with open(out_file, 'w') as f:
json.dump(result, f, indent=1)


6 changes: 3 additions & 3 deletions app/celer-sim/celer-sim.cc
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ void run(std::istream* is, std::shared_ptr<OutputRegistry> output)
#if CELERITAS_USE_JSON
nlohmann::json::parse(*is).get_to(*run_input);
#else
CELER_NOT_CONFIGURED("nlohmann_json");
CELER_ASSERT_UNREACHABLE();
#endif
output->insert(std::make_shared<OutputInterfaceAdapter<RunnerInput>>(
OutputInterface::Category::input, "*", run_input));
Expand Down Expand Up @@ -150,7 +150,7 @@ void run(std::istream* is, std::shared_ptr<OutputRegistry> output)
}

//---------------------------------------------------------------------------//
void print_usage(char const* exec_name)
void print_usage(std::string_view exec_name)
{
// clang-format off
std::cerr << "usage: " << exec_name << " {input}.json\n"
Expand Down Expand Up @@ -227,7 +227,7 @@ int main(int argc, char* argv[])
if (filename == "--dump-default"sv)
{
#if CELERITAS_USE_JSON
std::cout << nlohmann::json{celeritas::app::RunnerInput{}}.dump(1)
std::cout << nlohmann::json(celeritas::app::RunnerInput{}).dump(1)
<< std::endl;
#endif
return EXIT_SUCCESS;
Expand Down
6 changes: 6 additions & 0 deletions src/celeritas/phys/PrimaryGeneratorOptions.hh
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ struct DistributionOptions
/*!
* Primary generator options.
*
* TODO: distributions should be std::variant (see ORANGE input)
*
* - \c seed: RNG seed
* - \c pdg: PDG numbers of the primaries. An equal number of primaries of each
* type will be generated
Expand Down Expand Up @@ -78,6 +80,8 @@ struct PrimaryGeneratorOptions
}
};

// TODO: move to PrimaryGenerator.hh

using PrimaryGeneratorEngine = std::mt19937;

//---------------------------------------------------------------------------//
Expand All @@ -87,6 +91,8 @@ using PrimaryGeneratorEngine = std::mt19937;
// Get a distribution name
char const* to_cstring(DistributionSelection value);

// TODO: move these to PrimaryGenerator.hh

// Return a distribution for sampling the energy
std::function<real_type(PrimaryGeneratorEngine&)>
make_energy_sampler(DistributionOptions options);
Expand Down
5 changes: 5 additions & 0 deletions src/celeritas/phys/PrimaryGeneratorOptionsIO.json.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ void from_json(nlohmann::json const& j, DistributionOptions& opts)

void to_json(nlohmann::json& j, DistributionOptions const& opts)
{
if (!opts)
{
j = nlohmann::json::object();
return;
}
j = nlohmann::json{{"distribution", opts.distribution},
{"params", opts.params}};
}
Expand Down

0 comments on commit 1dc8da2

Please sign in to comment.