Import Geant4 11.4.0 source tree

This commit is contained in:
Gabriele Cosmo
2025-12-05 08:54:02 +01:00
parent a499fb82e9
commit b4a16de652
6484 changed files with 232674 additions and 221097 deletions
+66
View File
@@ -0,0 +1,66 @@
#----------------------------------------------------------------------------
# Setup the project
cmake_minimum_required(VERSION 3.16...3.27)
project(IAEAphsp)
#----------------------------------------------------------------------------
# Find Geant4 package, activating all available UI and Vis drivers by default
# You can set WITH_GEANT4_UIVIS to OFF via the command line or ccmake/cmake-gui
# to build a batch mode only executable
#
option(WITH_GEANT4_UIVIS "Build example with Geant4 UI and Vis drivers" ON)
if(WITH_GEANT4_UIVIS)
find_package(Geant4 REQUIRED ui_all vis_all)
else()
find_package(Geant4 REQUIRED)
endif()
#----------------------------------------------------------------------------
# Setup Geant4 include directories and compile definitions
#
include(${Geant4_USE_FILE})
#----------------------------------------------------------------------------
# Locate sources and headers for this project
#
include_directories(${PROJECT_SOURCE_DIR}/include
${PROJECT_SOURCE_DIR}/iaea_phsp
${Geant4_INCLUDE_DIR})
file(GLOB sources ${PROJECT_SOURCE_DIR}/src/*.cc)
file(GLOB headers ${PROJECT_SOURCE_DIR}/include/*.hh)
#----------------------------------------------------------------------------
# Build the iaea_phsp support library
add_subdirectory(iaea_phsp)
#----------------------------------------------------------------------------
# Add the executable, and link it to the Geant4 libraries
#
add_executable(IAEAphsp IAEAphsp.cc ${sources} ${headers})
target_link_libraries(IAEAphsp iaea_phsp ${Geant4_LIBRARIES})
#----------------------------------------------------------------------------
# Copy all scripts to the build directory, i.e. the directory in which we
# build IAEAphsp.
# This is so that we can run the executable directly because it
# relies on these scripts being in the current working directory.
#
set(IAEAphsp_SCRIPTS
test-reader.mac test-writer.mac test-rw.mac test-rw.out vis.mac
phsp/test.IAEAheader phsp/test.IAEAphsp
phsp/PSF_example.IAEAheader phsp/PSF_example.IAEAphsp
)
foreach(_script ${IAEAphsp_SCRIPTS})
configure_file(
${PROJECT_SOURCE_DIR}/${_script}
${PROJECT_BINARY_DIR}/${_script}
COPYONLY
)
endforeach()
#----------------------------------------------------------------------------
# Install the executable to 'bin' directory under CMAKE_INSTALL_PREFIX
#
install(TARGETS IAEAphsp DESTINATION bin)
+15
View File
@@ -0,0 +1,15 @@
# IAEAphsp advanced example History
See `CONTRIBUTING.rst` for details of **required** info/format for each entry,
which **must** added in reverse chronological order (newest at the top).
It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2025-11-17 Miguel A. Cortes-Giraldo (IAEAphsp-V11-03-01)
- Place all iaea_phsp external files into `iaea_phsp/` directory.
- Add copyright of `iaea_phsp` routines.
## 2025-10-19 Miguel A. Cortes-Giraldo (IAEAphsp-V11-03-00)
- Created.
+109
View File
@@ -0,0 +1,109 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// Example author: M.A. Cortes-Giraldo, Universidad de Sevilla
//
// Reference paper:
// M.A. Cortes-Giraldo et al., Int J Radiat Biol 88(1-2): 200-208 (2012)
// (doi: 10.3109/09553002.2011.627977)
//
// The iaea_phsp routines are available at the IAEAphsp project website:
// https://www-nds.iaea.org/phsp/phsp.htmlx
//
#include "globals.hh"
#include "Randomize.hh"
#ifdef G4MULTITHREADED
#include "G4MTRunManager.hh"
#else
#include "G4RunManager.hh"
#endif
#include "G4UImanager.hh"
#include "G4UIExecutive.hh"
#include "G4VisExecutive.hh"
#include "DetectorConstruction.hh"
#include "PhysicsList.hh"
#include "ActionInitialization.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
int main(int argc,char** argv) {
//detect interactive mode (if no arguments) and define UI session
G4UIExecutive* ui = nullptr;
if (argc == 1) ui = new G4UIExecutive(argc,argv);
//choose the Random engine
G4Random::setTheEngine(new CLHEP::RanecuEngine);
// Construct the default run manager
#ifdef G4MULTITHREADED
G4MTRunManager* runManager = new G4MTRunManager;
G4int nThreads = 3;
if (argc == 3)
nThreads = G4UIcommand::ConvertToInt(argv[2]);
runManager->SetNumberOfThreads(nThreads);
G4cout << "===== IAEAphsp started with "
<< runManager->GetNumberOfThreads() << " threads =====" << G4endl;
#else
G4RunManager* runManager = new G4RunManager();
#endif
//set mandatory initialization classes
runManager->SetUserInitialization(new DetectorConstruction());
runManager->SetUserInitialization(new PhysicsList());
// set user action classes
runManager->SetUserInitialization(new ActionInitialization());
//initialize visualization
G4VisManager* visManager = nullptr;
//get the pointer to the User Interface manager
G4UImanager* UImanager = G4UImanager::GetUIpointer();
if (ui) {
//interactive mode
visManager = new G4VisExecutive;
visManager->Initialize();
UImanager->ApplyCommand("/control/execute vis.mac");
ui->SessionStart();
delete ui;
}
else {
//batch mode
G4String command = "/control/execute ";
G4String fileName = argv[1];
UImanager->ApplyCommand(command+fileName);
}
//job termination
if (visManager) delete visManager;
delete runManager;
}
File diff suppressed because it is too large Load Diff
+273
View File
@@ -0,0 +1,273 @@
\page ExampleIAEAphsp Example IAEAphsp
# IAEAphsp — Geant4 Advanced Example
Author: M.A. Cortes-Giraldo et al.
Date: 14 Oct. 2025
Email: miancortes@us.es
IAEAphsp is an advanced Geant4 example that demonstrates **reading** and
**writing** IAEA phase-space (IAEAphsp) files (a binary `*.IAEAphsp` with
human-readable `*.IAEAheader`) within a minimal, configurable application.
The IAEAphsp format is defined by the IAEA Nuclear Data Section; this example
shows how to use IAEAphsp files as input source (i.e. as a primary generator)
and how to produce IAEAphsp outputs at given scoring planes.
**REFERENCE PAPER:** If you use this code, please cite:
M.A. Cortes-Giraldo et al., Int J Radiat Biol 88(1-2): 200-208 (2012)
[(doi: 10.3109/09553002.2011.627977)](https://doi.org/10.3109/09553002.2011.627977)
More information on the IAEAphsp format can be found at
[https://www-nds.iaea.org/phsp/phsp.htmlx](https://www-nds.iaea.org/phsp/phsp.htmlx)
---
## Contents
The most specific files of this example are:
- `phsp/` directory: Contains two IAEAphsp examples,
1. The "test" IAEAphsp file available from the IAEAphsp project website,
2. "PSF_example", an illustrative phsp file storing 200 particles (40 of
each kind) recorded during 1000 original histories.
- `iaea_phsp/` directory: Contains the files defining the IAEAphsp format
and routines.
- Three testing macro files:
- `test-reader.mac`: Case in which we only read an IAEAphsp file, no
IAEAphsp outputs.
- `test-writer.mac`: Regular particle gun is used, particles at specific
phsp planes (z const) are recorded in IAEAphsp output files.
- `test-rw.mac`: Performs both reading and writing operations with
IAEAphsp files.
- In addition, `vis.mac` macro is used for an interactive session.
---
## Geometry
Just a **box world volume** is created. You can configure world half-sizes at
runtime via the UI commands in `/my_geom/` directory:
```
/my_geom/worldXY <L> <unit> # world XY half-size
/my_geom/worldZ <L> <unit> # world Z half-size
```
The world material is `G4_Galactic`. No detector objects are required for the
IAEAphsp writer; the scoring planes are
**mathematical planes at constant Z positions** managed by the writer stack.
---
## Physics
This example **requires** the definition of a **reference physics list**
chosen at runtime via UI command **before initialization** (i.e., before
issuing the command `/run/initialize`). The required command is:
```
/my_phys/setList <name> # e.g. QGSP_BIC_HP_EMZ, QGSP_BERT_HP
```
Further, related verbosity can be controlled with:
```
/my_phys/verbose <0|1|2>
```
If no list is set before `/run/initialize`, the application will issue a
**fatal error**.
You can also configure production cuts in the macro, as usual, e.g.:
```
/run/setCut 0.1 mm
```
---
## Particle beam (used if no phsp reader is selected)
By default, 50 MeV are shot from the center, with momentum direction parallel
to the z-axis, pointing randomly towards positive or negative direction.
This is to illustrate the recording of the incremental history number variable
(also known as `n_stat`) within the output IAEAphsp files.
Besides regular commands at `/gun/` directory, the beam can be controlled with
the following UI commands:
```
/my_beam/kinE <E> <unit> # mean kinetic energy
/my_beam/DE <DE> <unit> # energy distribution half-width, flat distribution
/my_beam/X0 <X0> <unit> # mean x-position of the beam
/my_beam/Y0 <Y0> <unit> # mean y-position of the beam
/my_beam/Z0 <Z0> <unit> # mean z-position of the beam
/my_beam/DX <DX> <unit> # x-pos distribution half width, flat distribution
/my_beam/DY <DY> <unit> # y-pos distribution half width, flat distribution
/my_beam/DZ <DZ> <unit> # z-pos distribution half width, flat distribution
```
Its verbosity can be controlled with:
```
/my_beam/verbose <0|1|2>
```
---
## Specific commands for the IAEAphsp classes
### Activation of G4IAEAphspReader/Writer objects
The activation of IAEAphsp classes, either for reading or writing purpose,
is done via UI commands defined at a messenger class of the
ActionInitialization class, under the directory `/action/`.
This design comes from the need of passing the information safely to worker
threads and ensure MT-safe operations with the IAEAphsp routines.
```
/action/IAEAphspReader/fileName <name> # reads from <name>.IAEA* files
/action/IAEAphspWriter/namePrefix <name> # writes <name>[_runID].IAEA* files
/action/IAEAphspWriter/zphsp <z_phsp> <unit> # defines phsp plane at z-pos
```
The **G4IAEAphspReader** class only reads particle **from ONE file**.
In contrast, **more than one** zphsp values can be set to **G4IAEAphspWriter**.
### IAEAphsp Reader — controls & transforms
The G4IAEAphspReader object can be controlled with the following UI commands.
These commands are only available at `Idle` state.
Please see documentation within the class for further information.
Commands relevant for particle recycling:
```
/IAEAphspReader/recycling <n_rec> # Each particle is created n_rec+1 times
/IAEAphspReader/axialSymmetryX <true|false>
/IAEAphspReader/axialSymmetryY <true|false>
/IAEAphspReader/axialSymmetryZ <true|false>
```
Commands relevant for simulations run in parallel reading the same IAEAphsp:
```
/IAEAphspReader/numberOfParallelRuns <n_chunk> # No. chunks defined in file
/IAEAphspReader/parallelRun <chunk> # Defines the piece of phsp file to read
```
Commands to mimic rotations of a linac treatment head:
```
/IAEAphspReader/collimatorAngle <angle> <unit>
/IAEAphspReader/collimatorRotationAxis <u_coll> <v_coll> <w_coll>
/IAEAphspReader/gantryAngle <angle> <unit>
/IAEAphspReader/gantryRotationAxis <u_gantry> <v_gantry> <w_gantry>
/IAEAphspReader/isocenterPosition <x_ic> <y_ic> <z_ic> <unit>
```
Commands for custom spatial transformations of the phsp file:
```
/IAEAphspReader/rotateX <angle> <unit>
/IAEAphspReader/rotateY <angle> <unit>
/IAEAphspReader/rotateZ <angle> <unit>
/IAEAphspReader/rotationOrder <123|231|312|132|321|213>
/IAEAphspReader/translate <x> <y> <z> <unit>
```
Verbose command:
```
/IAEAphspReader/verbose <0|1|2>
```
---
## Build
```bash
# Configure your Geant4 path (or source your env script)
export Geant4_DIR=/path/to/geant4/lib/cmake/Geant4
# Configure & build
mkdir build && cd build
cmake -DGeant4_DIR="$Geant4_DIR" ..
cmake --build . --parallel
```
This produces the executable **`IAEAphsp`** and copies the example macros and
phsp files into the `build/` directory.
---
## Running
### Interactive UI
```bash
./IAEAphsp
```
Launches `an interactive session (Qt/terminal depending on your Geant4 build)
### Batch (macro)
Use the provided macros from the build directory:
```bash
./IAEAphsp test-reader.mac
./IAEAphsp test-writer.mac
./IAEAphsp test-rw.mac
./IAEAphsp vis.mac
```
This example accepts an **optional** thread-count as a second argument (MT
builds):
```bash
./IAEAphsp test-reader.mac 4
```
IAEAphsp outputs are written in the working directory.
---
## How it works (diagram)
```
+-------------------+
| Run Manager |
| (MT if enabled) |
+-------------------+
|
v
+----------------------------------------+
| User Initializations |
| - DetectorConstruction (via /my_geom/) |
| - PhysicsList (via /my_phys) |
| - ActionInitialization |
+----------------------------------------+
|
v
+--------------------------------------------------------------------+
| PrimaryGeneratorAction |
| - uses G4IAEAphspReader if /action/IAEAphspReader/fileName is set |
| - else particle gun (via /my_beam/*) |
+--------------------------------------------------------------------+
|
v
+-----------------------------------------------------------------------+
| SteppingAction |
| - sends eligible tracks to |
| G4IAEAphspWriterStack if /action/IAEAphspWriter/ commands are set |
+-----------------------------------------------------------------------+
|
v
+--------------------------+
| IAEAphspRun (per thread) |
| - merges at EndOfRun |
| - opens/writes via |
| G4IAEAphspWriter |
+--------------------------+
```
At end-of-run, the master consolidates thread-local stacks and the writer
produces `*.IAEAphsp`/`*.IAEAheader` files (name prefix set by
`/action/IAEAphspWriter/namePrefix`) - one pair per defined **Z plane**
(each set by `/action/IAEAphspWriter/zphsp`).
---
### Note on IAEASourceIdRegistry class
This example uses a thread-safe registry (`include/IAEASourceIdRegistry.hh`)
to coordinate the `source_ID` values passed to the IAEA routines. The goal is
to keep IDs **unique and stable** across threads and runs, avoiding surprises
from the C layers internal allocator.
- Readers reserve one ID per worker and reuse it on new runs; the ID is
released when the reader is destroyed (i.e. at the end of the entire job).
- Writers reserve one ID per output plane during `OpenIAEAphspOutFiles()` and
release them in `CloseIAEAphspOutFiles()`.
This mechanism is entirely internal; **no user commands are required**.
@@ -0,0 +1,2 @@
add_library(iaea_phsp STATIC iaea_header.cpp iaea_phsp.cpp iaea_record.cpp utilities.cpp)
target_include_directories(iaea_phsp PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
@@ -0,0 +1,51 @@
/*
* Copyright (C) 2006 International Atomic Energy Agency
* -----------------------------------------------------------------------------
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is furnished
* to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*-----------------------------------------------------------------------------
*
* AUTHORS:
*
* Roberto Capote Noy, PhD
* e-mail: R.CapoteNoy@iaea.org (rcapotenoy@yahoo.com)
* International Atomic Energy Agency
* Nuclear Data Section, P.O.Box 100
* Wagramerstrasse 5, Vienna A-1400, AUSTRIA
* Phone: +431-260021713; Fax: +431-26007
*
* Iwan Kawrakow, PhD
* e-mail iwan@irs.phy.nrc.ca
* Ionizing Radiation Standards
* Institute for National Measurement Standards
* National Research Council of Canada Ottawa, ON, K1A 0R6 Canada
* Phone: +1-613-993 2197, ext.241; Fax: +1-613-952 9865
*
**********************************************************************************
* For documentation
* see http://www-nds.iaea.org/reports-new/indc-reports/indc-nds/indc-nds-0484.pdf
**********************************************************************************/
//
// Sources files for the interfase (not tested with event generators):
// iaea_header.cpp (iaea_header.h)
// iaea_phsp.cpp (iaea_phsp.h)
// iaea_record.cpp (iaea_record.h)
// utilities.cpp (utilities.h)
//
@@ -0,0 +1,80 @@
// int * signed, signed int System dependent
// unsigned int * unsigned System dependent
//__int8 1 char, signed char -128 to 127
//__int16 2 short, short int, signed short int -32,768 to 32,767
//__int32 4 signed, signed int -2,147,483,648 to 2,147,483,647
//__int64 8 none -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
//char 1 signed char -128 to 127
//unsigned char 1 none 0 to 255
//short 2 short int, signed short int -32,768 to 32,767
//unsigned short 2 unsigned short int 0 to 65,535
//long 4 long int, signed long int -2,147,483,648 to 2,147,483,647
//unsigned long 4 unsigned long int 0 to 4,294,967,295
//enum * none Same as int
//float 4 none 3.4E +/- 38 (7 digits)
//double 8 none 1.7E +/- 308 (15 digits)
//long double 10 none 1.2E +/- 4932 (19 digits)
#ifndef IAEA_CONFIG
#define IAEA_CONFIG
#if (defined WIN32) || (defined WIN64)
#include <windows.h>
#endif
/* Without the above include file, gcc on Windows does not know about
__int64
*/
#ifdef DOUBLE
typedef double IAEA_Float;
#else
typedef float IAEA_Float;
#endif
typedef short IAEA_I16;
// typedef long IAEA_I32; // RCN changed int to long to allow storage of EGS LATCH, Dec. 2006
typedef int IAEA_I32; // Changed back on April 2011, following Daniel OBrien's comments
// It also corresponds to EGSnrc definition (see egs_config1.h file)
//typedef __int64 IAEA_I64;
#if (defined WIN32) || (defined WIN64)
typedef __int64 IAEA_I64;
#else
#if defined NO_LONG_LONG || defined LONG_IS_64
typedef long IAEA_I64;
#else
typedef long long IAEA_I64;
#endif
#endif
#ifdef __cplusplus
#define IAEA_EXTERN_C extern "C"
#else
#define IAEA_EXTERN_C extern
#endif
#if (defined WIN32) || (defined WIN64)
#ifdef BUILD_DLL
#define IAEA_EXPORT __declspec(dllexport)
#elif defined USE_DLL
#define IAEA_EXPORT __declspec(dllimport)
#else
#define IAEA_EXPORT
#endif
#define IAEA_LOCAL
#else
#ifdef HAVE_VISIBILITY
#define IAEA_EXPORT __attribute__ ((visibility ("default")))
#define IAEA_LOCAL __attribute__ ((visibility ("hidden")))
#else
#define IAEA_EXPORT
#define IAEA_LOCAL
#endif
#endif
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,160 @@
#ifndef IAEA_HEADER
#define IAEA_HEADER
/* *********************************************************************** */
#include "iaea_record.h"
// defines
#define SEGMENT_BEG_TOKEN '$'
#define SEGMENT_END_TOKEN ':'
#ifndef MAX_STR_LEN
#define MAX_STR_LEN 512 /* maximum length of a string */
#endif
#define MAX_NUMB_LINES 30 /* maximum number of lines in a block */
#define MAX_NUMB_EXTRALONG_TYPES 7 /* maximum number of extra long allowed */
// 0: User defined generic type
// 1: Incremental history number n_hist
// n_hist = 0 if previous primary particle scored
// n_hist > 0 indicates how many primary particle read before the current one
// 2: LATCH (EGS)
// 3: ILB5 (PENELOPE)
// 4: ILB4 (PENELOPE)
// 5: ILB3 (PENELOPE)
// 6: ILB2 (PENELOPE)
// 7: ILB1 (PENELOPE)
// more to be defined
#define MAX_NUMB_EXTRAFLOAT_TYPES 3 /* maximum number of extra float allowed */
// 0: User defined generic type
// 1: XLAST (x coord. of the last interaction)
// 2: YLAST (y coord. of the last interaction)
// 3: ZLAST (z coord. of the last interaction)
// more to be defined
struct iaea_header_type
{
FILE *fheader;
// ******************************************************************************
// 1. PHSP format
int file_type; // 0 = phsp file ; 1 = phsp generator
int byte_order; // as defined by get_byte_order routine
int record_contents[9]; // record_contents[i] = 1 or 0 (variable or constant)
// correspond to the following logical variables :
// ix,iy,iz,iu.iv,iw;
// iweight,iextrafloat,iextralong;
float record_constant[7]; // if record_contents[i<7] = 0
// then record_constant[i] contents the constant value
// extra floats and longs are always variable
// so no need to store them
// contains the keyword describing each stored extrafloat
int extrafloat_contents[NUM_EXTRA_FLOAT];
// contains the keyword describing each stored extralong
int extralong_contents[NUM_EXTRA_LONG];
int record_length;
// record_length = 1 + (particle)
// 4 + (energy)
// SUM(i=0;i<3) {record_contents[i]*4} (ix,iy,iz)
// SUM(i=3;i<6) {record_contents[i]*4} (iu,iv,iw)
// record_contents[6]*4 + (iweigth)
// record_contents[7]*4 + (iextrafloat)
// record_contents[8]*4 + (iextralong)
IAEA_I64 checksum;
// ******************************************************************************
// 2. Mandatory description of the phsp
char coordinate_system_description[MAX_STR_LEN*MAX_NUMB_LINES+1];
// Counters for phsp file
IAEA_I64 orig_histories;
IAEA_I64 nParticles;
IAEA_I64 particle_number[MAX_NUM_PARTICLES];
// Event generator input file
char input_file_for_event_generator[MAX_STR_LEN*MAX_NUMB_LINES+1];
// ******************************************************************************
// 3. Mandatory additional information
unsigned int iaea_index; // Agency ID
char title[MAX_STR_LEN*MAX_NUMB_LINES+1];
char machine_type[MAX_STR_LEN*MAX_NUMB_LINES+1];
char MC_code_and_version[MAX_STR_LEN*MAX_NUMB_LINES+1];
float global_photon_energy_cutoff;
float global_particle_energy_cutoff;
char transport_parameters[MAX_STR_LEN*MAX_NUMB_LINES+1];
// ******************************************************************************
// 4. Optional description
char beam_name[MAX_STR_LEN*MAX_NUMB_LINES+1];
char field_size[MAX_STR_LEN*MAX_NUMB_LINES+1];
char nominal_SSD[MAX_STR_LEN*MAX_NUMB_LINES+1];
char variance_reduction_techniques[MAX_STR_LEN*MAX_NUMB_LINES+1];
char initial_source_description[MAX_STR_LEN*MAX_NUMB_LINES+1];
// Documentation sub-section
char MC_input_filename[MAX_STR_LEN*MAX_NUMB_LINES+1];
// Assumed to be the preferred citation
char published_reference[MAX_STR_LEN*MAX_NUMB_LINES+1];
char authors[MAX_STR_LEN*MAX_NUMB_LINES+1];
char institution[MAX_STR_LEN*MAX_NUMB_LINES+1];
char link_validation[MAX_STR_LEN*MAX_NUMB_LINES+1];
char additional_notes[MAX_STR_LEN*MAX_NUMB_LINES+1];
// ******************************************************************************
// 5. Optional statistical information
double averageKineticEnergy[MAX_NUM_PARTICLES];
double sumParticleWeight[MAX_NUM_PARTICLES];
double maximumKineticEnergy[MAX_NUM_PARTICLES];
double minimumKineticEnergy[MAX_NUM_PARTICLES];
double minimumX, maximumX;
double minimumY, maximumY;
double minimumZ, maximumZ;
double minimumWeight[MAX_NUM_PARTICLES];
double maximumWeight[MAX_NUM_PARTICLES];
IAEA_I64 read_indep_histories;
// CLASS FUNCTIONS
public:
int read_header();
int write_header();
int print_header();
int set_record_contents(iaea_record_type *p_iaea_record);
int get_record_contents(iaea_record_type *p_iaea_record);
void initialize_counters();
void update_counters(iaea_record_type *p_iaea_record);
private:
int read_block(char *lineread, const char *blockname);
int get_block(char *lineread);
int get_blockname(char *line, const char *blockname);
int write_blockname(const char *blockname);
int check_byte_order();
void print_statistics();
};
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,414 @@
/*
* INTERFACE FOR IAEA PHSP ROUTINES (CONTAINS ONLY DECLARATIONS)
*
* Copyright (C) 2006 International Atomic Energy Agency
* -----------------------------------------------------------------------------
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is furnished
* to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*-----------------------------------------------------------------------------
*
* AUTHORS:
*
* Roberto Capote Noy, PhD
* e-mail: R.CapoteNoy@iaea.org (rcapotenoy@yahoo.com)
* International Atomic Energy Agency
* Nuclear Data Section, P.O.Box 100
* Wagramerstrasse 5, Vienna A-1400, AUSTRIA
* Phone: +431-260021713; Fax: +431-26007
*
* Iwan Kawrakow, PhD
* e-mail iwan@irs.phy.nrc.ca
* Ionizing Radiation Standards
* Institute for National Measurement Standards
* National Research Council of Canada Ottawa, ON, K1A 0R6 Canada
* Phone: +1-613-993 2197, ext.241; Fax: +1-613-952 9865
*
**********************************************************************************
* For documentation
* see http://www-nds.iaea.org/reports-new/indc-reports/indc-nds/indc-nds-0484.pdf
**********************************************************************************/
#ifndef IAEA_PHSP
#define IAEA_PHSP
#include "iaea_config.h"
/************************************************************************
* Initialization
*
* Given a file name header_file of length hf_length, initialize a
* new IAEA particle source, assign an unique source_ID to it and return
* this Id in result. Dont assume header_file is null-terminated as the
* function may be called from a Fortran program.
* The need for an Id arises from the fact that some applications may
* want to use several IAEA sources at once. The implementation must therefore
* maintain a list of already initialized sources.
* If an error occures (e.g. header file does not exist, there are errors
* in the header file, etc.), assign a negative number to result.
* (one may want to specify a list of error codes so that the application
* knows what went wrong). This function *must* be called before using
* any of the following functions for a given source id.
*
* access = 1 => opening read-only file
* access = 2 => opening file for writing
* access = 3 => opening file for appending/updating
*
***********************************************************************/
IAEA_EXTERN_C IAEA_EXPORT
void iaea_new_source(IAEA_I32 *source_ID, char *header_file,
const IAEA_I32 *access, IAEA_I32 *result,
int hf_length);
/************************************************************************
* Maximum number of particles
*
* Set n_particle to the maximum number of particle of type type the
* source with Id id can return. If type<0, set n_particle to the
* total number of all particles. For event generators, this function
* should set n_particle to the maximum integer that can be stored in a
* signed 64 bit integer. If the source with Id id does not exist,
* set n_particle to a negative number.
*************************************************************************/
IAEA_EXTERN_C IAEA_EXPORT
void iaea_get_max_particles(const IAEA_I32 *id, const IAEA_I32 *type,
IAEA_I64 *n_particle);
/************************************************************************
* Maximum energy
*
* Return the maximum energy of an initialized IAEA source with Id id
* in Emax. Set Emax to negative if a source with that Id does not exist.
************************************************************************/
IAEA_EXTERN_C IAEA_EXPORT
void iaea_get_maximum_energy(const IAEA_I32 *id, IAEA_Float *Emax);
/*************************************************************************
* Number of additional floats and integers returned by the source
*
* Return the number of additional floats in n_extra_float and the number
* of additional integers in n_extra_integer for the source with Id id.
* Set n_extra_integer and/or n_extra_float to be negative if such a
* source does not exist.
*************************************************************************/
IAEA_EXTERN_C IAEA_EXPORT
void iaea_get_extra_numbers(const IAEA_I32 *id, IAEA_I32 *n_extra_float,
IAEA_I32 *n_extra_int);
/*************************************************************************
* Number of additional floats and integers to be stored
*
* Set the number of additional floats in n_extra_float and the number
* of additional integers in n_extra_integer for the source with Id id
* to be stored in the corresponding file.
*************************************************************************/
IAEA_EXTERN_C IAEA_EXPORT
void iaea_set_extra_numbers(const IAEA_I32 *id, IAEA_I32 *n_extra_float,
IAEA_I32 *n_extra_int);
/*******************************************************************************
* Set a type type of the extra long variable corresponding to the "index" number
* for a corresponding header of the phsp "id". Index is running from zero.
*
* The current list of types for extra long variables is:
* 0: User defined generic type
* 1: Incremental history number (EGS,PENELOPE)
* = 0 indicates a nonprimary particle event
* > 0 indicates a primary particle. The value is equal to the number of
* primaries particles employed to get to this history after the last
* primary event was recorded.
* 2: LATCH (EGS)
* 3: ILB5 (PENELOPE)
* 4: ILB4 (PENELOPE)
* 5: ILB3 (PENELOPE)
* 6: ILB2 (PENELOPE)
* 7: ILB1 (PENELOPE)
* more to be defined
*
* Usually called before writing phsp header to set the type of extra long
* variables to be stored. It must be called once for every extralong variable.
*
* type = -1 means the source's header file does not exist
* or source was not properly initialized (call iaea_new_...)
* type = -2 means the index is out of range ( 0 <= index < NUM_EXTRA_LONG )
* type = -3 means the type to be set is out of range
* ( 1 <= type < MAX_NUMB_EXTRALONG_TYPES )
*******************************************************************************/
IAEA_EXTERN_C IAEA_EXPORT
void iaea_set_type_extralong_variable(const IAEA_I32 *id,
const IAEA_I32 *index,
IAEA_I32 *type);
/********************************************************************************
* Set a type type of the extra float variable corresponding to the "index" number
* for a corresponding header of the phsp "id". Index is running from zero.
*
* The current list of types for extra float variables is:
* 1: XLAST (x coord. of the last interaction)
* 2: YLAST (y coord. of the last interaction)
* 3: ZLAST (z coord. of the last interaction)
* more to be defined
*
* Usually called before writing phsp header to set the type of extra float
* variables to be stored. It must be called once for every extra float variable.
*
* type = -1 means the source's header file does not exist
* or source was not properly initialized (call iaea_new_...)
* type = -2 means the index is out of range ( 0 <= index < NUM_EXTRA_FLOAT )
* type = -3 means the type to be set is out of range
* ( 1 <= type < MAX_NUMB_EXTRAFLOAT_TYPES )
*******************************************************************************/
IAEA_EXTERN_C IAEA_EXPORT
void iaea_set_type_extrafloat_variable(const IAEA_I32 *id,
const IAEA_I32 *index,
IAEA_I32 *type);
/****************************************************************************
* Get a type type of all extra variables from a header of the phsp "id".
*
* extralong_types[] AND extrafloat_types[] must have a dimension bigger than
* MAX_NUMB_EXTRALONG_TYPES and MAX_NUMB_EXTRAFLOAT_TYPES correspondingly
*
* The current list of types for extra long variables is:
* 0: User defined generic type
* 1: Incremental history number (EGS,PENELOPE)
* = 0 indicates a nonprimary particle event
* > 0 indicates a primary particle. The value is equal to the number of
* primaries particles employed to get to this history after the last
* primary event was recorded.
* 2: LATCH (EGS)
* 3: ILB5 (PENELOPE)
* 4: ILB4 (PENELOPE)
* 5: ILB3 (PENELOPE)
* 6: ILB2 (PENELOPE)
* 7: ILB1 (PENELOPE)
* more to be defined
*
* The current list of types for extra float variables is:
* 1: XLAST (x coord. of the last interaction)
* 2: YLAST (y coord. of the last interaction)
* 3: ZLAST (z coord. of the last interaction)
* more to be defined
*
* Usually called before reading phsp header to know the type of extra long
* variables to be read. It must be called once for every extra float variable.
*
* result = -1 means the source's header file does not exist
* or source was not properly initialized (call iaea_new_...)
*******************************************************************************/
IAEA_EXTERN_C IAEA_EXPORT
void iaea_get_type_extra_variables(const IAEA_I32 *id, IAEA_I32 *result,
IAEA_I32 extralong_types[], IAEA_I32 extrafloat_types[]);
/*************************************************************************
* Set variable corresponding to the "index" number to a "constant" value
* for a corresponding header of the phsp "id". Index is running from zero.
*
* (Usually called as needed before MC loop started)
*
* index = 0 1 2 3 4 5 6
* corresponds to x,y,z,u,v,w,wt
*
* Usually called before writing phsp files to set those variables which
* are not going to be stored. It must be called once for every variable
*
* constant = -1 means the source's header file does not exist
* or source was not properly initialized (call iaea_new_...)
* constant = -2 means the index is out of range ( 0 <= index < 7 )
*************************************************************************/
IAEA_EXTERN_C IAEA_EXPORT
void iaea_set_constant_variable(const IAEA_I32 *id, const IAEA_I32 *index,
IAEA_Float *constant);
/*************************************************************************
* Get value of constant corresponding to the "index" number
* for a corresponding header of the phsp "id". Index is running from zero.
*
* index = 0 1 2 3 4 5 6
* corresponds to x,y,z,u,v,w,wt
*
* Usually called when reading phsp header info.
* It must be called once for every variable
*
* result = -1 means the source's header file does not exist
* or source was not properly initialized (call iaea_new_...)
* result = -2 means the index is out of range ( 0 <= index < 7 )
* result = -3 means that the parameter indicated by index is not a constant
*************************************************************************/
IAEA_EXTERN_C IAEA_EXPORT
void iaea_get_constant_variable(const IAEA_I32 *id, const IAEA_I32 *index,
IAEA_Float *constant, IAEA_I32 *result);
/*****************************************************************************
* Get n_indep_particles number of statistically independent particles read
* so far from the Source with Id id.
*
* Set n_indep_particles to negative if such source does not exist.
******************************************************************************/
IAEA_EXTERN_C IAEA_EXPORT
void iaea_get_used_original_particles(const IAEA_I32 *id,
IAEA_I64 *n_indep_particles);
/*****************************************************************************
* Get Total Number of Original Particles from the Source with Id id.
*
* For a typical linac it should be equal to the total number of electrons
* incident on the primary target.
*
* Set number_of_original_particles to negative if such source does not exist.
******************************************************************************/
IAEA_EXTERN_C IAEA_EXPORT
void iaea_get_total_original_particles(const IAEA_I32 *id,
IAEA_I64 *number_of_original_particles);
/*****************************************************************************
* Set Total Number of Original Particles for the Source with Id id.
*
* For a typical linac it should be equal to the total number of electrons
* incident on the primary target.
*
* Set number_of_original_particles to negative if such source does not exist.
******************************************************************************/
IAEA_EXTERN_C IAEA_EXPORT
void iaea_set_total_original_particles(const IAEA_I32 *id,
IAEA_I64 *number_of_original_particles);
/**************************************************************************
* Partitioning for parallel runs
*
* i_parallel is the job number, i_chunk the calculation chunk,
* n_chunk the total number of calculation chunks. This function
* should divide the available phase space of source with Id id
* into n_chunk equal portions and from now on deliver particles
* from the i_chunk-th portion. (i_chunk must be between 1 and n_chunk)
* The extra parameter i_parallel is needed
* for the cases where the source is an event generator and should
* be used to adjust the random number sequence.
* The variable is_ok should be set to 0 if everything went smoothly,
* or to some error code if it didnt.
**************************************************************************/
IAEA_EXTERN_C IAEA_EXPORT
void iaea_set_parallel(const IAEA_I32 *id, const IAEA_I32 *i_parallel,
const IAEA_I32 *i_chunk, const IAEA_I32 *n_chunk,
IAEA_I32 *is_ok);
/**************************************************************************
* setting the pointer to a user-specified record no. in the file
*
* record_num is the user-specified record number passed to the function.
* id is the phase space file identifier.
* The variable result should be set to 0 if everything went smoothly,
* or to some error code if it didnt.
**************************************************************************/
IAEA_EXTERN_C IAEA_EXPORT
void iaea_set_record(const IAEA_I32 *id, const IAEA_I64 *record_num,
IAEA_I32 *result);
/**************************************************************************
* check that the file size equals the value of checksum in the header
*
* id is the phase space file identifier. If the size of the phase space
* file is not equal to checksum, then result returns -1, otherwise result
* is set to 0.
**************************************************************************/
IAEA_EXTERN_C IAEA_EXPORT
void iaea_check_file_size_byte_order(const IAEA_I32 *id, IAEA_I32 *result);
/**************************************************************************
* Get a particle
*
* Return the next particle from the sequence of particles from source
* with Id id. Set n_stat to the number of statistically independent
* events since the last call to this function (i.e. n_stat = 0, if
* the particle resulted from the same incident electron, n_stat = 377
* if there were 377 statistically independent events sinc the last particle
* returned, etc.). If this information is not available,
* simply set n_stat to 1 if the particle belongs to a new statistically
* independent event. Set n_stat to -1, if a source with Id id does not
* exist. Set n_stat to -2, if end of file of the phase space source reached
**************************************************************************/
IAEA_EXTERN_C IAEA_EXPORT
void iaea_get_particle(const IAEA_I32 *id, IAEA_I32 *n_stat,
IAEA_I32 *type, /* particle type */
IAEA_Float *E, /* kinetic energy in MeV */
IAEA_Float *wt, /* statistical weight */
IAEA_Float *x,
IAEA_Float *y,
IAEA_Float *z, /* position in cartesian coordinates*/
IAEA_Float *u,
IAEA_Float *v,
IAEA_Float *w, /* direction in cartesian coordinates*/
IAEA_Float *extra_floats,
IAEA_I32 *extra_ints);
/**************************************************************************
* Write a particle
* n_stat = 0 for a secondary particle
* n_stat > 0 for an independent particle
*
* Write a particle to the source with Id id.
* Set n_stat to -1, if ERROR (source with Id id does not exist).
**************************************************************************/
IAEA_EXTERN_C IAEA_EXPORT
void iaea_write_particle(const IAEA_I32 *id, IAEA_I32 *n_stat,
const IAEA_I32 *type, /* particle type */
const IAEA_Float *E, /* kinetic energy in MeV */
const IAEA_Float *wt, /* statistical weight */
const IAEA_Float *x,
const IAEA_Float *y,
const IAEA_Float *z, /* position in cartesian coordinates*/
const IAEA_Float *u,
const IAEA_Float *v,
const IAEA_Float *w, /* direction in cartesian coordinates*/
const IAEA_Float *extra_floats,
const IAEA_I32 *extra_ints);
/***************************************************************************
* Destroy a source
*
* This function de-initializes the source with Id id, closing all open
* files, deallocating memory, etc. Nothing happens if a source with that
* id does not exist. Header is updated.
****************************************************************************/
IAEA_EXTERN_C IAEA_EXPORT
void iaea_destroy_source(const IAEA_I32 *source_ID, IAEA_I32 *result);
/***************************************************************************
* Print the current header associated to source id
*
* result is set to negative if phsp source does not exist.
****************************************************************************/
IAEA_EXTERN_C IAEA_EXPORT
void iaea_print_header(const IAEA_I32 *source_ID, IAEA_I32 *result);
/***************************************************************************
* Copy header of the source_id to the header of the destiny_id
****************************************************************************/
IAEA_EXTERN_C IAEA_EXPORT
void iaea_copy_header(const IAEA_I32 *source_ID, const IAEA_I32 *destiny_ID,
IAEA_I32 *result);
/***************************************************************************
* Update header of the source_id
****************************************************************************/
IAEA_EXTERN_C IAEA_EXPORT
void iaea_update_header(const IAEA_I32 *source_ID, IAEA_I32 *result);
#endif
@@ -0,0 +1,260 @@
/*
* Copyright (C) 2006 International Atomic Energy Agency
* -----------------------------------------------------------------------------
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is furnished
* to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*-----------------------------------------------------------------------------
*
* AUTHORS:
*
* Roberto Capote Noy, PhD
* e-mail: R.CapoteNoy@iaea.org (rcapotenoy@yahoo.com)
* International Atomic Energy Agency
* Nuclear Data Section, P.O.Box 100
* Wagramerstrasse 5, Vienna A-1400, AUSTRIA
* Phone: +431-260021713; Fax: +431-26007
*
* Iwan Kawrakow, PhD
* e-mail iwan@irs.phy.nrc.ca
* Ionizing Radiation Standards
* Institute for National Measurement Standards
* National Research Council of Canada Ottawa, ON, K1A 0R6 Canada
* Phone: +1-613-993 2197, ext.241; Fax: +1-613-952 9865
*
**********************************************************************************
* For documentation
* see http://www-nds.iaea.org/reports-new/indc-reports/indc-nds/indc-nds-0484.pdf
**********************************************************************************/
//#define DEBUG // Comment to avoid printing for every particle write or read
#if (defined WIN32) || (defined WIN64)
#include <iostream> // so that namespace std becomes defined
#endif
#include <math.h>
#include <cstdio>
#if !(defined WIN32) && !(defined WIN64)
using namespace std;
#endif
#include "iaea_record.h"
short iaea_record_type::initialize()
{
if(p_file == NULL) {
fprintf(stderr, "\n ERROR: Failed to open Phase Space file \n");
return (FAIL);
}
// Defines i/o logic and variable quantities to be stored
// If the value is zero, then corresponding quantity is fixed
ix = 1;
iy = 1;
iz = 1;
iu = 1;
iv = 1;
iw = 1;
iweight = 1;
// Defines a number of EXTRA long variables stored
// (EGS need 2 for incremental history number and LATCH)
iextralong = 1;
if( iextralong >= NUM_EXTRA_LONG)
{
fprintf(stderr, "\n ERROR: Increase NUM_EXTRA_LONG number in iaea_record.h\n");
return (FAIL);
}
// Defines a number of EXTRA float variables stored (EGS could need 1 for ZLAST)
iextrafloat = 0;
if( iextrafloat >= NUM_EXTRA_FLOAT)
{
fprintf(stderr, "\n ERROR: Increase NUM_EXTRA_FLOAT number in iaea_record.h\n");
return (FAIL);
}
return (OK);
}
short iaea_record_type::write_particle()
{
float floatArray[NUM_EXTRA_FLOAT+7];
IAEA_I32 longArray[NUM_EXTRA_LONG];
char ishort = (char) particle;
if(w < 0) ishort = -ishort; // Sign of w is stored in particle type
if( fwrite(&ishort, sizeof(char), 1, p_file) != 1)
{
fprintf(stderr, "\n ERROR: write_particle: Failed to write particle type\n");
return (FAIL);;
}
int reclength = sizeof(char);
if(IsNewHistory > 0) energy *= (-1); // New history is signaled by negative energy
floatArray[0] = energy;
int i = 0;
if(ix > 0) floatArray[++i] = x;
if(iy > 0) floatArray[++i] = y;
if(iz > 0) floatArray[++i] = z;
if(iu > 0) floatArray[++i] = u;
if(iv > 0) floatArray[++i] = v;
if(iweight > 0) floatArray[++i] = weight;
int j;
for(j=0;j<iextrafloat;j++) floatArray[++i] = extrafloat[j];
reclength += (i+1)*sizeof(float);
if( fwrite(floatArray, sizeof(float), (size_t)(i+1), p_file) != (size_t) (i+1))
{
fprintf(stderr, "\n ERROR: write_particle: Failed to write FLOAT phsp data\n");
return (FAIL);
}
if(iextralong > 0)
{
for(j=0;j<iextralong;j++) longArray[j] = extralong[j];
reclength += iextralong*sizeof(IAEA_I32);
if( fwrite(longArray, sizeof(IAEA_I32), (size_t)iextralong, p_file) != (size_t)iextralong)
{
fprintf(stderr, "\n ERROR: write_particle: Failed to write LONG phsp data\n");
return (FAIL);
}
}
if(reclength == 0) return(FAIL);
#ifdef DEBUG
// charge defined
int iaea_charge[MAX_NUM_PARTICLES]={0,-1,+1,0,+1};
int charge = iaea_charge[particle - 1];
printf("\n Wrote a particle with a record lenght %d",reclength);
printf("\n Q %d E %f X %f Y %f Z %f \n\t u %f v %f w %f W %f Part %d \n",
charge, energy, x, y, z, u, v, w, weight, particle);
if( iextrafloat > 0) printf(" EXTRA FLOATs:");
for(j=0;j<iextrafloat;j++) printf(" F%i %f",j+1,extrafloat[j]);
if( iextralong > 0) printf(" EXTRA LONGs:");
for(j=0;j<iextralong;j++) printf(" L%i %d", j+1,extralong[j]);
printf("\n");
#endif
return(OK);
}
short iaea_record_type::read_particle()
{
float floatArray[NUM_EXTRA_FLOAT+7];
IAEA_I32 longArray[NUM_EXTRA_LONG+7];
//(MACG) -Wshadow int i,j,is,reclength;
int i,j,l,is,reclength;
char ctmp;
// IAEA_I32 pos = ftell(p_file); // To check file position
if( fread(&ctmp, sizeof(char), 1, p_file) != 1) // particle type is always read
{
fprintf(stderr, "\n ERROR: read_particle: Failed to read particle type\n");
return (FAIL);;
}
particle = (short) ctmp;
is = 1; // getting sign of Z director cosine w
if(particle < 0) {is = -1; particle = -particle;}
reclength = sizeof(char); // particle type is always read
unsigned int rec_to_read = 1; // energy is always read
if(ix > 0) rec_to_read++;
if(iy > 0) rec_to_read++;
if(iz > 0) rec_to_read++;
if(iu > 0) rec_to_read++;
if(iv > 0) rec_to_read++;
if(iweight > 0) rec_to_read++;
if(iextrafloat>0) rec_to_read += iextrafloat;
if( fread(floatArray, sizeof(float), rec_to_read, p_file) != rec_to_read)
{
fprintf(stderr, "\n ERROR: read_particle: Failed to read FLOATs \n");
return (FAIL);;
}
reclength += rec_to_read*sizeof(float);
IsNewHistory = 0;
if(floatArray[0]<0) IsNewHistory = 1; // like egsnrc
energy = fabs(floatArray[0]);
i = 0;
if(ix > 0) x = floatArray[++i];
if(iy > 0) y = floatArray[++i];
if(iz > 0) z = floatArray[++i];
if(iu > 0) u = floatArray[++i];
if(iv > 0) v = floatArray[++i];
if(iweight > 0) weight = floatArray[++i];
for(j=0;j<iextrafloat;j++) extrafloat[j] = floatArray[++i];
if(iw > 0)
{
w = 0.f;
double aux = (u*u + v*v);
if (aux<=1.0) w = (float) (is * sqrt((float)(1.0 - aux)));
else
{
aux = sqrt((float)aux);
u /= (float)aux;
v /= (float)aux;
}
}
if(iextralong > 0)
{
if( fread(longArray, sizeof(IAEA_I32), (size_t)iextralong, p_file) != (size_t)iextralong)
{
fprintf(stderr, "\n ERROR: read_particle: Failed to read LONGS\n");
return (FAIL);
}
//(MACG) -Wshadow for(int l=0,j=0;j<iextralong;j++) extralong[j] = longArray[l++];
for(l=0,j=0;j<iextralong;j++) extralong[j] = longArray[l++];
reclength += (iextralong)*sizeof(IAEA_I32);
}
#ifdef DEBUG
// charge defined
int iaea_charge[MAX_NUM_PARTICLES]={0,-1,+1,0,+1};
int charge = iaea_charge[particle - 1];
printf("\n Read a particle with a record lenght %d (New History: %d)",
reclength,IsNewHistory);
printf("\n Q %d E %f X %f Y %f Z %f \n\t u %f v %f w %f W %f Part %d \n",
charge, energy, x, y, z, u, v, w, weight, particle);
if( iextrafloat > 0) printf(" EXTRA FLOATs:");
for(j=0;j<iextrafloat;j++) printf(" F%i %f",j+1,extrafloat[j]);
if( iextralong > 0) printf(" EXTRA LONGs:");
for(j=0;j<iextralong;j++) printf(" L%i %d",j+1,extralong[j]);
printf("\n");
#endif
return(reclength);
}
@@ -0,0 +1,66 @@
#include <cstdio>
#ifndef IAEA_RECORD
#define IAEA_RECORD
#include "utilities.h"
#include "iaea_config.h"
/* *********************************************************************** */
// defines
// To use additional float or integers
#ifndef NUM_EXTRA_FLOAT
#define NUM_EXTRA_FLOAT 10 // Maximum 10 extra float stored
#endif
#ifndef NUM_EXTRA_LONG
#define NUM_EXTRA_LONG 10 // Maximum 10 extra long stored
#endif
#define MAX_NUM_PARTICLES 5 // 1 photons
// 2 electrons
// 3 positrons
// 4 neutrons
// 5 protons
#define MAX_NUM_SOURCES 30
#define OK 0
#define FAIL -1
/* *********************************************************************** */
// structures
struct iaea_record_type
{
FILE *p_file; // phase space file pointer
short particle; // mandatory (photon:1 electron:2 positron:3 neutron:4 proton:5 ...)
float energy; // mandatory
IAEA_I32 IsNewHistory; // coded as sign of energy
// Type changed from short to IAEA_I32 to store EGS n_stat
float x; int ix;
float y; int iy;
float z; int iz;
float u; int iu;
float v; int iv;
float w; int iw; // sign of w coded as sign of code
float weight; int iweight;
short iextrafloat;
short iextralong;
float extrafloat[NUM_EXTRA_FLOAT]; // (default: no extra float stored)
IAEA_I32 extralong[NUM_EXTRA_LONG]; // (default: one extra long stored)
public:
short read_particle();
short write_particle();
short initialize();
};
#endif
@@ -0,0 +1,808 @@
/*
* Copyright 2000-2003 Virginia Commonwealth University
* -----------------------------------------------------------------------------
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is furnished
* to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*-----------------------------------------------------------------------------
*
* AUTHORS:
*
* Jeffrey Vincent Siebers
* e-mail: jsiebers@vcu.edu
* Virginia Commonwealth University
* 401 College Street, P.O.Box 980058
* Richmond, Viriginia 23298-0058
* Phone: +1-804-6287771
*
*
*/
/* General Utilities for CPP programs
File Created:
18-December-1995: Combined ok_check.cpp and some open_file
Modification History:
01-Feb-1996: JVS: filename used in open_file has extension only in openfile
09-Feb-1996: JVS: Add eprintf: outputs to screen and a buffer called pbuffer
pbuffer is a global whose memory must be allocated
this is useful for creating a "history" file
17-June-1996: JVS: change latex_string so will work with win95/bc5.0
cannot have for(int i=0,j=0; ). j will not increment.
05-Sept-1996: JVS: Add allocate_pbuffer and print_runtime_info
23-April-1997: JVS: Add interpolate
06-Jan-1998: JVS: Add array_read
11-June-1998: jvs: add eprintf and view_errors
22-Sept-1998: JVS: fix memory leak in eprintf
07-Dec-1998: JVS: Add clean_name
18-Feb-1999: JVS: eliminate atof in array_read because of failures
25-Feb-1999: JVS: array_read will now read numbers that start with .
26-Feb-1999: JVS: Add array_read for strings
02-March-1999: JVS: Add global eprint_mode so can quite eprintf statements
24-March-1999: JVS: Modify clean_name so names cannot have *'s in them
July 20, 1999: JVS: eprintf modified to use fprintf(stdout), rather than printf
Dec 3, 1999: JVS: Add check_byte_order
Jan 11, 2000: JVS: Modify clean_name so names cannot have / in them
Jun 16, 2000: JVS: Change open_file so will read in .extension properly when a . is in
the path name
April 25, 2001: JVS: Add cp(SourceFile,DestinationFile)
May 29, 2001: JVS: clean_name now removes & as well
May 31, 2002: add reverse_short_byte_order
Feb 18, 2004: JVS: Add writeBigEndianBinaryFile()
Feb 10, 2005: JVS: Add writeLittleEndianBinaryFile() and writeBinaryFile()
Feb 11, 2005: JVS: Add reverse_int_byte_order
April 21, 2005: JVS: Add readBinaryDataFromFile
*/
#if (defined WIN32) || (defined WIN64)
#include <iostream> // so that namespace std becomes defined
#endif
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
#include <ctime>
#if !(defined WIN32) && !(defined WIN64)
using namespace std;
#endif
#include "utilities.h"
/* ************************************************************************** */
int reverse_int_byte_order(int xold)
{
int xnew;
char *pn = (char *) &xnew;
char *po = (char *) &xold;
pn[0] = po[3];
pn[1] = po[2];
pn[2] = po[1];
pn[3] = po[0];
return(xnew);
}
/* *************************************************************************** */
float reverse_float_byte_order(float xold)
{
float xnew;
char *pn = (char *) &xnew;
char *po = (char *) &xold;
pn[0] = po[3];
pn[1] = po[2];
pn[2] = po[1];
pn[3] = po[0];
return(xnew);
}
/* **************************************************************************** */
short reverse_short_byte_order(short xold)
{
short xnew;
char *pn = (char *) &xnew;
char *po = (char *) &xold;
pn[0] = po[1];
pn[1] = po[0];
return(xnew);
}
/* **************************************************************************** */
int check_byte_order()
{
/* Determine the byte order on this machine */
float ftest=1.0f; /* assign a float to 1.0 */
char *pf = (char *) &ftest;
// printf("\n \t %x %x %x %x", pf[0],pf[1],pf[2],pf[3]);
if(pf[0] == 0 && pf[3] != 0)
{
// printf("\n\n Byte order: INTEL / ALPHA,LINUX -> LITLE_ENDIAN \n");
return(LITTLE_ENDIAN);
}else if(pf[0] != 0 && pf[3] == 0)
{
// printf("\n\n Byte order: OTHER (SGI,SUN-SOLARIS) -> BIG_ENDIAN \n ");
return(BIG_ENDIAN);
}
else
{
printf("\n\n ERROR: indeterminate byte order");
printf("\n \t %x %x %x %x", pf[0],pf[1],pf[2],pf[3]);
return(UNKNOWN_ENDIAN);
}
}
/* ************************************************** */
void print_runtime_info(int argc, char *argv[])
{ // print file header stuff
printf("\n Command Line: ");
for(int i=0; i<argc; i++) printf(" %s", argv[i]);
// printf("\n Program %s Revision %f", Prog_Name,Revision);
printf("\n \t Copyright XXXX MCV");
time_t t;
t = time(NULL);
printf("\n Run on %s\n", ctime(&t) );
}
/* ****************************************************************** */
void allocate_pbuffer()
{
pbuffer = (char *)malloc(MAX_BUFFER_SIZE * sizeof(char) +2);
if(pbuffer == NULL)
{
printf("\n Error Allocating Memory Buffer");
exit(EXIT_FAILURE);
}
}
/* ***************************************************************** */
/* *********************************************************************** */
int advance(char *istr, int *sval, int len)
{ /* advances past white-space in file */
while( !isspace(istr[*sval]) && (*sval < len) )
*sval+=1; /* advance to space */
while( isspace(istr[*sval]) && (*sval < len) )
*sval+=1; /* advance to next thing */
if(*sval > len) return(FAIL); /* return 0 when fails */
return (OK);
}
/* ********************************************************************** */
int my_isascii( int c )
{
return( !(c < 0 || c > 0177) );
}
/* ********************************************************************* */
int clean_name(char *name)
{
int len = strlen(name);
char *tname = (char *) calloc(len+1, sizeof(char));
if(tname == NULL)
{
eprintf("\n ERROR: memory allocation error");
return(FAIL);
}
strcpy(tname, name);
if(clean_name(tname, name)!= OK)
{
eprintf("\n ERROR: cleaning Name");
return(FAIL);
}
free(tname);
return(OK);
}
/* ********************************************************************* */
int clean_name(char *tmp_path, char *opath)
{
/* remove spaces, *'s, :'s &'s and commas from the name */
int len = strlen(tmp_path);
int o_index=0;
for(int i=0; i<len; i++)
{
if( isspace(tmp_path[i] ) )
{
if( o_index && // add a _ if not first char
opath[o_index-1] != '_' ) // and if previous char not a _
opath[o_index++] = '_';
}
else
if( my_isascii( tmp_path[i] ) &&
tmp_path[i] != '&' &&
tmp_path[i] != ',' &&
tmp_path[i] != '*' &&
tmp_path[i] != '/' &&
tmp_path[i] != ':' )
opath[o_index++] = tmp_path[i];
}
opath[o_index] = '\0'; /* terminate the string */
return(OK);
}
/* *********************************************************************** */
FILE *open_file(char *filename, const char*extension, const char *access)
{
char string[MAX_STR_LEN];
FILE *strm = NULL;
if(filename[0]=='\0')
{
printf("\n INPUT FILENAME (%s) > ",access);
//(MACG)-Wunused-result fgets(string,MAX_STR_LEN,stdin);
char* dummy = fgets(string, MAX_STR_LEN, stdin);
(void) dummy; //(MACG) no -Wunused-variable
sscanf(string,"%s",filename);
printf(" FILE %s opened \n", filename);
}
int len=strlen(filename);
if( len + strlen(extension) >= MAX_STR_LEN)
{
printf("\n ERROR: String Length of %s.%s Exceeds Maximum",
filename, extension);
return(NULL);
}
// char *filename1 = new(char[len+strlen(extension)+1]);
const int filenameLength = len+strlen(extension)+1;
//(MACG)-Wvla char *filename1 = new(char[filenameLength]);
char *filename1 = new char[filenameLength];
strcpy(filename1,filename); // temp filename for appending extension
/* check if file name has .extension */
/* if it does not, add .extension to it */
int i=len-1;
while(i > 0 && filename[i--] != '.');
// printf("\n Comparing %s to %s", extension, filename+i+1);
if(strcmp(extension, filename+i+1) )
strcat(filename1,extension);
if( (strm = fopen(filename1, access) ) == NULL )
{
printf("\n ERROR OPENING FILE %s (mode %s)", filename1,access);
}
//(MACG)-Wvla delete(filename1);
delete[] filename1;
return(strm);
}
/* *********************************************************************** */
int ok_check(void) /* GETS RESPONSE FROM USER */
{ /* IF OK TO DO SOMETHING */
char reply[MAX_STR_LEN]; /* RETURNS 1 ONLY IF REPLY Y */
/* OR y ELSE RETURNS 0 */
//(MACG)-Wunused-result fgets(reply,MAX_STR_LEN,stdin);
char* dummy = fgets(reply,MAX_STR_LEN,stdin);
(void) dummy; //(MACG) no -Wunused-variable
if( ( strncmp(reply,"Y",1)==0 )||
( strncmp(reply,"y",1)==0 ))
return(1);
return(0);
}
/* *********************************************************************** */
int ok_checks(char *string)
{
printf("\n %s", string);
return(ok_check());
}
/* ********************************************************************** */
#include <stdarg.h> // for va function
int pprintf(char *fmt, ... )
{
va_list argptr; /* Argument list pointer */
char str[MAX_STR_LEN]; /* Buffer to build sting into */
int cnt; /* Result of SPRINTF for return */
va_start( argptr, fmt ); /* Initialize va_ functions */
//(MACG) Apple SDK deprecated:
//cnt = vsprintf( str, fmt, argptr ); /* prints string to buffer */
cnt = vsnprintf(str, MAX_STR_LEN, fmt, argptr); /* prints string to buffer */
if(str[0] == '\0') return(0);
printf("%s", str); /* Send to screen */
if(pbuffer != NULL && strlen(pbuffer) + strlen(str) < MAX_BUFFER_SIZE)
strcat(pbuffer,str);
else
printf("\n ERROR: pbuffer is full");
va_end( argptr ); /* Close va_ functions */
return( cnt ); /* Return the conversion count */
}
/* *********************************************************************** */
/* eprintf: for buffering error reports, writes error messages to a buffer,
and, also can echo them to the screen (if set at compile time)
at first instance, allocates memory for the error buffer */
static char *ebuffer = NULL;
int eprintf(const char *fmt, ... )
{
va_list argptr; /* Argument list pointer */
char str[MAX_STR_LEN]; /* Buffer to build sting into */
int cnt; /* Result of SPRINTF for return */
va_start( argptr, fmt ); /* Initialize va_ functions */
//(MACG) Apple SDK deprecated:
//cnt = vsprintf( str, fmt, argptr ); /* prints string to buffer */
cnt = vsnprintf(str, MAX_STR_LEN, fmt, argptr); /* prints string to buffer */
if(str[0] == '\0') return(0);
if(eprintf_mode==ON)
fprintf(stdout,"%s", str); /* Send to screen */
// allocate memory for the error message
int ilen = 0;
if(ebuffer != NULL)
{
ilen+=strlen(ebuffer);
ebuffer = (char *) realloc(ebuffer, (ilen+strlen(str)+1)*sizeof(char));
}
else
ebuffer = (char *) calloc(ilen+strlen(str)+1,sizeof(char));
if(ebuffer == NULL)
{
printf("\n ERROR: ebuffer cannot be allocated in eprintf");
}
else
strcat(ebuffer,str);
va_end( argptr ); /* Close va_ functions */
return( cnt ); /* Return the conversion count */
}
int view_errors(void)
{
printf("\n%s\n",ebuffer);
return(OK);
}
/* ************************************************************************** */
int latex_string(char *string, char *nstring)
{
// adds \\ in front of % so % will show up in the comment when printed
// with LaTeX
// must change all %'s to \% for latex output
// also, must do the same for $, &, # _ { and }
int len = strlen(string);
int sval=0;
int j;
while(isspace(string[sval]) )sval++; // remove space from start of string
while(isspace(string[len-1]))len--; // remove space from end to string
j=0;
for(int i=sval;i<len;i++)
{
if(string[i]=='%' ||
string[i]=='$' ||
string[i]=='&' ||
string[i]=='#' ||
string[i]=='_' ||
string[i]=='{' ||
string[i]=='}' )
{
nstring[j++]='\\';
}
else
if(string[i]=='<' ||
string[i]=='>' )
{
nstring[j++]='$';
}
nstring[j++] = string[i];
if(string[i]=='<' ||
string[i]=='>' )
{
nstring[j++]='$';
}
}
nstring[j]='\0';
/* printf("\n string: %s", string);
printf("\n nstring: %d %s",j, nstring); */
return(OK);
}
/* ************************************************************************** */
float interpolate(float xh, float xl, float xm, float yh, float yl)
{
return(yh - (xh-xm)/(xh-xl)*(yh-yl));
}
/* *********************************************************************** */
// #define DEBUG_ARRAY
/* ********************************************************************** */
int array_read(char *in_string, float *array, int max_array)
{
char delimeter_string[MAX_STR_LEN];
//(MACG) Apple SDK deprecated:
// sprintf(delimeter_string," ,\t"); /* spaces, commas, and tabs */
int cnt =
snprintf(delimeter_string,MAX_STR_LEN," ,\t"); /* spaces, commas, and tabs */
(void) cnt; //(MACG) silent -Wunused-result and -Wunused-variable
char *p; /* pointer to string read in */
p = strtok(in_string,delimeter_string);
int i=0;
if(p!=NULL)
{
array[i++]=(float)atof(p); /* get the first value */
// if( sscanf(p,"%f",&array[i]) == 1) i++; // sscanf rounds values....
do{ /* get remaining values */
p = strtok(NULL,delimeter_string);
if(p!=NULL)
{
//array[i++] = atof(p);
if( sscanf(p,"%f",&array[i]) == 1) i++;
// printf("\n Got Value of %f", array[i-1]);
}
}while(p!=NULL && i < max_array);
}
#ifdef DEBUG_ARRAY
printf("\n atof %d", i);
for(int j=0; j<i; j++) {
// array[j] = 0.0001*round(1000.0*array[j]);
printf("\n i = %d, %f",j,array[j]);
}
#endif
return(i);
}
int array_read(FILE *istrm, float *array, int max_array)
{
// reads in an array of floats from a single line of istrm
// returns the number of elements read in
char in_string[MAX_STR_LEN];
if(fgets(in_string, MAX_STR_LEN, istrm) == NULL ) return(FAIL);
#ifdef DEBUG_ARRAY
printf("\nInput String\n %s", in_string);
#endif
int slen = strlen(in_string);
int k=0;
while(isspace(in_string[k]) && k < slen) k++;
if(slen==0 || !(isdigit(in_string[k])
|| in_string[k] == '.'
|| in_string[k] == '+'
|| in_string[k] == '-'))
{
return(0); // skip blank and non-numerical lines
}
int nread = array_read(in_string,array,max_array);
return(nread); // return the number of elements read
}
/* ********************************************************************** */
int copy(char *SourceFile, char *DestinationFile)
{
/* Copies sourceFile to destination file like unix cp command */
FILE *sStream = fopen(SourceFile, "rb");
if(sStream == NULL)
{
perror("\n ERROR: copy: ");
printf("\n ERROR: copy: Opening Source File %s",SourceFile);return(FAIL);
}
FILE *dStream = fopen(DestinationFile,"wb");
if(dStream == NULL)
{
perror("\n ERROR: copy:");
printf("\n ERROR: copy: Opening Destination File %s",DestinationFile);return(FAIL);
}
char buffer[1000];
int nRead;
do{
nRead = fread(buffer, sizeof(char), 1000, sStream);
if( nRead )
fwrite(buffer, sizeof(char), nRead, dStream);
}while( !feof(sStream) && !ferror(dStream) && !ferror(sStream) );
if(ferror(sStream) || ferror(dStream) )
{
perror("ERROR: Copy: ");
printf("\n ERROR: source %s, destination %s", SourceFile, DestinationFile);
return(FAIL);
}
fclose(sStream);
fclose(dStream);
return(OK);
}
/* ********************************************************************** */
/* ************************************************************************************ */
int readBinaryDataFromFile(FILE *iStream, int nItemsToRead, float **arrayToRead, int swab_flag)
{
// Reads binary data to stream, swab's if requested (1=swab, 0=don't swab)
// Swab if needed...Put swabbed results in different array so no need to "unswab" when done
// Allocate memory to read array into
float *inputArray;
inputArray = (float *) calloc(nItemsToRead,sizeof(float));
if(inputArray == NULL) {
printf("\n ERROR: Allocating memory for inputArray in readBinaryDataFromFile");
return(FAIL);
}
if(OK != readBinaryDataFromFile(iStream, nItemsToRead, inputArray, swab_flag)) {
printf("\n ERROR: Reading binary data from file"); return(FAIL);
}
*arrayToRead = inputArray;
return(OK);
}
/* ************************************************************************************ */
int readBinaryDataFromFile(FILE *iStream, int nItemsToRead, float *inputArray, int swab_flag)
{
// Reads binary data to stream, swab's if requested (1=swab, 0=don't swab)
// Swab if needed...Put swabbed results in different array so no need to "unswab" when done
// Allocate memory to read array into
// Read in the array....
int nRead=fread(inputArray,sizeof(float),nItemsToRead, iStream);
if(nRead != nItemsToRead) {
eprintf("\n ERROR: Wrong number read from file (%d %d)\n",
nRead, nItemsToRead); return(FAIL);
}
// Check if need to swab the data
if(swab_flag) // swab if swab_flag != 0
{
for(int index=0; index<nItemsToRead;index++)
{
inputArray[index] = reverse_float_byte_order( inputArray[index] );
}
}
return(OK);
}
/* ***************************************************************************************** */
int writeBinaryFile(char *binaryFileName, int nItemsToWrite, float *arrayToWrite, int swab_flag)
{
FILE *outputStream= fopen(binaryFileName,"wb");
if (outputStream == NULL) {
eprintf("\n ERROR: Cannot open file %s for writing\n",binaryFileName); return(FAIL);
}
if(OK != writeBinaryDataToFile(outputStream, nItemsToWrite, arrayToWrite, swab_flag) )
{
eprintf("\n ERROR: Writing Binary File"); return(FAIL);
}
fclose(outputStream);
return(OK);
}
/* ************************************************************************************ */
int writeBinaryDataToFile(FILE *outputStream, int nItemsToWrite, float *arrayToWrite, int swab_flag)
{
// Writes binary data to stream, swab's if requested (1=swab, 0=don't swab)
// Swab if needed...Put swabbed results in different array so no need to "unswab" when done
float *swabbedArray;
if(swab_flag) // swab if swab_flag != 0
{
//
swabbedArray = (float *) calloc(nItemsToWrite,sizeof(float));
if(swabbedArray == NULL) {
eprintf("\n ERROR: Allocating memory for swabbedArray in writeBinaryFile");
return(FAIL);
}
for(int index=0; index<nItemsToWrite;index++)
{
swabbedArray[index] = reverse_float_byte_order( arrayToWrite[index] );
}
} else {
swabbedArray = arrayToWrite;
}
// Check that writing positive number of items
if(nItemsToWrite < 0 )
{
eprintf("\n ERROR: writeBinaryDataToFile: nItemsToWrite= %d < 0", nItemsToWrite); return(FAIL);
}
// Write the dose distribution
int nWrite=fwrite(swabbedArray,sizeof(float),nItemsToWrite, outputStream);
if(nWrite != nItemsToWrite) {
eprintf("\n ERROR: Wrong number written to file (%d %d)\n",
nWrite, nItemsToWrite); return(FAIL);
}
// free swabbedArray if it was allocated here
if(swab_flag) {
free(swabbedArray);
}
return(OK);
}
/* ***************************************************************************************************** */
int writeBigEndianBinaryFile(char *binaryFileName, int nItemsToWrite, float *arrayToWrite)
{
// Pinnacle doses always written in BIG_ENDIAN format... Check if need to swab.....
int swab_flag = 0;
switch( (check_byte_order()) )
{
case BIG_ENDIAN:
break;
case LITTLE_ENDIAN:
swab_flag=1;
break;
default:
eprintf("\n ERROR: Indeterminate Byte Order\n");
return(FAIL);
}
if(OK != writeBinaryFile(binaryFileName, nItemsToWrite, arrayToWrite, swab_flag) )
{
printf("\n ERROR: Writing dose file %s", binaryFileName); return(FAIL);
}
return(OK);
}
/* ***************************************************************************************************** */
int writeLittleEndianBinaryFile(char *binaryFileName, int nItemsToWrite, float *arrayToWrite)
{
// Pinnacle doses always written in BIG_ENDIAN format... Check if need to swab.....
int swab_flag = 0;
switch( (check_byte_order()) )
{
case BIG_ENDIAN:
swab_flag=1;
break;
case LITTLE_ENDIAN:
break;
default:
eprintf("\n ERROR: Indeterminate Byte Order\n");
return(FAIL);
}
if(OK != writeBinaryFile(binaryFileName, nItemsToWrite, arrayToWrite, swab_flag) )
{
printf("\n ERROR: Writing dose file %s", binaryFileName); return(FAIL);
}
return(OK);
}
/* ***************************************************************************************************** */
char *strnset(char *s, int ch, size_t n)
{ /* mimic strnset command in dos/ os2/ win / ... */
for(int i=0; i< (int) n; i++)
{
if(s[i] == STR_NULL ) return(s); // return when find null
s[i] = ch;
}
return(s);
}
int get_string(FILE *fspec, char *string)
{
#ifdef DEBUG
int rvalue=fget_c_string(string, MAX_STR_LEN, fspec);
printf("\n fget_c_string returns %s", string);
return(rvalue);
#else
return(fget_c_string(string, MAX_STR_LEN, fspec));
#endif
}
#define REWIND_STREAM 100
/* ************************************************************************** */
int fget_c_string(char *string, int Max_Str_Len, FILE *fspec)
{
/* gets a string from the input and removes comments from it */
/* allows comments in standard "c" syntax,
starting with / *
ending with * / */
/* also allows c++ type comments, // causes rest of line to be skipped */
int check;
char comment_start[4]="/*"; /* signals start of comment */
char comment_stop[4]="*/"; /* signals end of comment */
int clen; /* length of string for start/stop*/
int ilen; /* length of input string */
char *istring; /* input string */
int olen; /* location on output string */
int icnt; /* location on string */
// int n_pass = 0; /* Number of passes through the file looking for a value */
olen = 0;
/* allocate memory for input string */
istring = (char *)calloc(Max_Str_Len,sizeof(char));
if(istring == NULL)
{
printf("\n ERROR: Allocating memory for input string if fget_c_string");
return(FAIL);
}
strnset(string,'\0',Max_Str_Len); /* null entire output string */
strnset(istring,'\0',Max_Str_Len); /* null entire input string */
#ifdef DEBUG
printf ("\n --------------fget_c_string");
#endif
clen = strlen(comment_start);
/* read in the line, verify that it exists */
do{
/* read in a line from the file */
while(fgets(istring, Max_Str_Len, fspec) == NULL) /* output warning if not a valid read */
{
#ifdef DEBUG
printf("\n istring: %s", istring);
#endif
#ifdef ALLOW_REWIND
if(n_pass) /* if already gone through file once looking for value, quit */
#endif
{
#ifdef DEBUG
// printf ("\n***End of Input File in get_string, closing");
#endif
// printf ("\nERROR: Reading File : End of File On Read ");
// fclose(fspec);
free(istring);
return(FAIL);
}
#ifdef ALLOW_REWIND
n_pass++; /* increment the number of times through the file */
rewind(fspec); /* rewind to the beginning of the file */
free(istring);
return(REWIND_STREAM);
#endif
}
#ifdef DEBUG
printf("\n istring: %s", istring);
#endif
ilen = strlen(istring); /* length of input string */
istring[ilen]='\0'; /* null terminate the string */
if(ilen < clen) /* not possible to have comment on the line */
{ /* so output the string as is */
strcpy(string,istring);
olen = strlen(string);
}
else
{
/* strip comments out of input string */
icnt=0;
do{
check = 1;
if(icnt < ilen - clen) /* make sure have enough characters for start of comment */
check = strncmp(istring+icnt,comment_start,clen); /* check if start of comment */
if(check == 0) /* comment found for standard c syntax */
{
/* find end of comment */
icnt+=clen; /* advance past comment delimeter */
clen=strlen(comment_stop); /* get length of end of comment delimiter */
/* look for end of comment till end of string */
do{
check = 1;
if(icnt < ilen - clen) /* make sure have enough characters for end of comment */
check = strncmp(istring+icnt, comment_stop,clen);
if(check != 0) /* if not end of comment */
{
icnt++; /* increment location on string */
if(icnt>ilen) /* if advance past end of string, get a new one */
{
if(fgets(istring, Max_Str_Len, fspec) == NULL) /* output warning if not a valid read */
{
printf ("\nERROR: Reading File, looking for end of comment %s",comment_stop);
// fclose(fspec);
free(istring);
return(FAIL);
}
ilen = strlen(istring); /* get length of this new string */
/* null terminate the string */
istring[ilen]='\0';
icnt = 0; /* reset the counter to the start of the string */
}
}
else
{
icnt+=clen; /* advance past comment delimiter */
}
}while(check != 0); /* end of comment found */
} /* end if */
else /* check if comment is in c++ format */
{
check = strncmp(istring+icnt, "//",2);
if(check == 0) /* c++ style comment found */
{ /* skip till end of string */
icnt = ilen;
string[olen++]='\n';
string[olen]='\0';
}
else /* is a valid character for the string */
{
string[olen++] = istring[icnt++]; /* append value to the string */
string[olen]='\0';
}
}
}while(icnt < ilen && /* do till end of string */
olen < Max_Str_Len); /* and output string not too long */
/* check for only carriage return (should have been caught above) */
if(olen == 1 && string[0] == '\n') olen = 0;
} /* end else */
}while(olen == 0); /* do till read in a string */
if(olen == Max_Str_Len)
{
printf ("\nERROR: Input line too long");
// fclose(fspec);
free(istring);
return(FAIL);
}
free(istring);
return(OK);
}
@@ -0,0 +1,140 @@
/*
Copyright 2000-2003 Virginia Commonwealth University
Advisory:
1. The authors make no claim of accuracy of the information in these files or the
results derived from use of these files.
2. You are not allowed to re-distribute these files or the information contained within.
3. This methods and information contained in these files was interpreted by the authors
from various sources. It is the users sole responsibility to verify the accuracy
of these files.
4. If you find a error within these files, we ask that you to contact the authors
and the distributor of these files.
5. We ask that you acknowledge the source of these files in publications that use results
derived from the input
Please contact us if you have any questions
*/
/* Header File for General Utilities for CPP programs
File Created:
18-December-1995: Combined ok_check.cpp and some open_file
Modification History:
09-feb-1996: JVS: add pprintf
07-Nov-1996: JVS: FAIL_SAFE definition changed, NULL=0
06-Jan-1998: JVS: Add array_read
07-May-1998: JVS: add myerrno
11-Sept-1998: JVS: add max, min definitions
// 28-Oct-1998: PJK: added MAX_NUM_FIELDS for output_path in case_info.h
03-Dec-1998: JVS: Add #ifndef UTILITIES_H_INCLUDED to ensure single inclusion of the file
All comments "c" compliant
02-Mar-1999: JVS: Add eprintf_mode
Dec 3, 1999: JVS: Add check_byte_order
April 24, 2001: JVS: Add cp
August 24, 2001: JVS: Change OK from 1 to 0...so exit(OK) is unix standard normal...
Feb 10, 2005: JVS:Add writeLittleEndianBinaryFile()
April 21, 2005: JVS: Add readBinaryDataFromFile()
*/
#ifndef UTILITIES_H_INCLUDED
#define UTILITIES_H_INCLUDED
#define OK 0
#define ERROR -1
#define FAIL -1
#define ON 1
#define OFF 0
#define FAIL_SAFE -999 /* used to be NULL**JVS 11/7/96** */
#define MAX_STR_LEN 512 /* maximum length of a string */
#define MAX_BUFFER_SIZE 16384 /* maximum number of characters in the output buffer */
#define STR_NULL ((char) 0)
/* #define MAX_NUM_FIELDS 100 */
#ifndef N_DATA
#define N_DATA 4096 /* maximum number of datapoints */
#endif
#ifdef MAIN
int myerrno = OK;
#else
extern int myerrno;
#endif
#ifdef MAIN
int eprintf_mode = ON;
#else
extern int eprintf_mode;
#endif
#ifndef MAIN
extern /* create global pbuffer */
#endif
char *pbuffer; /* pointer to buffer for output of run info for failures */
#ifndef ENDIAN_H_INCLUDED
#define ENDIAN_H_INCLUDED
/* Definitions for byte order, according to significance of bytes, from low
addresses to high addresses. The value is what you get by putting '4'
in the most significant byte, '3' in the second most significant byte,
'2' in the second least significant byte, and '1' in the least
significant byte. */
#define __LITTLE_ENDIAN 1234
#define __BIG_ENDIAN 4321
#define __PDP_ENDIAN 3412
//(MACG) endian macros defined in macOS 15, silent -Wmacro-redefined warning
#if !defined(LITTLE_ENDIAN) && defined(__LITTLE_ENDIAN)
#define LITTLE_ENDIAN __LITTLE_ENDIAN
#endif
#if !defined(BIG_ENDIAN) && defined(__BIG_ENDIAN)
#define BIG_ENDIAN __BIG_ENDIAN
#endif
#if !defined(PDP_ENDIAN) && defined(__PDP_ENDIAN)
#define PDP_ENDIAN __PDP_ENDIAN
#endif
//(MACG) --- end of changes
#define UNKNOWN_ENDIAN 0000
#endif /* endian.h */
/* #define max and min */
/* (MACG) using min and max functions through algorithm c++ library
#ifndef MINMAX_DEFINED
#define MINMAX_DEFINED
#define min(a,b) (((a) < (b)) ? (a) : (b))
#define max(a,b) (((a) > (b)) ? (a) : (b))
//#define __max max
//#define __min min
#endif (MACG)*/ /*MINMAX_DEFINED */
/* *************************************************************************** */
float reverse_float_byte_order(float xold);
short reverse_short_byte_order(short xold);
int reverse_int_byte_order(int xold);
int advance(char *istr, int *sval, int len);
int check_byte_order(void);
int clean_name(char *tmp_path, char *opath);
int clean_name(char *);
int copy(char *SourceFile, char *DestinationFile);
//(MACG) int eprintf(char *fmt, ... );
int eprintf(const char *fmt, ... );
int ok_check(void);
int ok_checks(char *string);
//(MACG) FILE *open_file(char *filename,char *extension, char *access);
FILE *open_file(char *filename,const char *extension,const char *access);
int pprintf(char *fmt, ... );
int latex_string(char *string, char *nstring);
void print_runtime_info(int argc, char *argv[]);
void allocate_pbuffer(void);
float interpolate(float xh, float xl, float xm, float yh, float yl);
int array_read(FILE *istrm, float *array, int max_array);
int array_read(char *in_string, float *array, int max_array);
int view_errors(void);
int writeBigEndianBinaryFile(char *doseFileName, int nDoseArray, float *doseArray);
int writeLittleEndianBinaryFile(char *doseFileName, int nDoseArray, float *doseArray);
int writeBinaryFile(char *doseFileName, int nDoseArray, float *doseArray, int swab_flag);
int writeBinaryDataToFile(FILE *outputStream, int nArray, float *array, int swab_flag);
int readBinaryDataFromFile(FILE *iStream, int nItemsToRead, float **arrayToRead, int swab_flag);
int readBinaryDataFromFile(FILE *iStream, int nItemsToRead, float *inputArray, int swab_flag);
// RCN added
int fget_c_string(char *string, int Max_Str_Len, FILE *fspec);
int get_string(FILE *fspec, char *string);
#endif
@@ -0,0 +1,73 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
#ifndef ActionInitialization_h
#define ActionInitialization_h 1
#include "G4VUserActionInitialization.hh"
#include "globals.hh"
#include "G4IAEAphspWriterStack.hh"
#include <vector>
class ActionInitializationMessenger;
//------------------------------------------------------------------------------
class ActionInitialization : public G4VUserActionInitialization
{
public:
ActionInitialization();
virtual ~ActionInitialization() override;
virtual void BuildForMaster() const override;
virtual void Build() const override;
// Set-Get methods
void SetIAEAphspReader(const G4String& name);
void SetIAEAphspWriterPrefix(const G4String& name);
void AddZphsp(const G4double val);
private:
// IAEAphsp-related data members
G4String fIAEAphspReaderName;
G4String fIAEAphspWriterNamePrefix;
std::vector<G4double>* fZphspVec;
G4int fNumberOfThreads;
// Messenger class needed for IAEAphsp commands
ActionInitializationMessenger* fMessenger;
};
#endif
@@ -0,0 +1,67 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
#ifndef ActionInitializationMessenger_h
#define ActionInitializationMessenger_h 1
//....oooOO0OOooo........oooOO00OOooo........oooOO00OOooo........oooOO0OOooo....
#include "globals.hh"
#include "G4UImessenger.hh"
class ActionInitialization;
class G4UIdirectory;
class G4UIcmdWithADoubleAndUnit;
class G4UIcmdWithAString;
//....oooOO0OOooo........oooOO00OOooo........oooOO00OOooo........oooOO0OOooo....
class ActionInitializationMessenger: public G4UImessenger
{
public:
ActionInitializationMessenger(ActionInitialization* );
virtual ~ActionInitializationMessenger() override;
void SetNewValue(G4UIcommand*, G4String) override;
private:
ActionInitialization* fAction;
G4UIdirectory* fActionDir;
G4UIdirectory* fIAEAphspReaderDir;
G4UIdirectory* fIAEAphspWriterDir;
G4UIcmdWithAString* fIAEAphspReaderFileCmd;
G4UIcmdWithAString* fIAEAphspWriterFileCmd;
G4UIcmdWithADoubleAndUnit* fIAEAphspWriterZphspCmd;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#endif
@@ -0,0 +1,66 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
#ifndef DetectorConstruction_h
#define DetectorConstruction_h 1
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "G4VUserDetectorConstruction.hh"
#include "globals.hh"
class G4LogicalVolume;
class G4Material;
class DetectorMessenger;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class DetectorConstruction : public G4VUserDetectorConstruction
{
public:
DetectorConstruction();
virtual ~DetectorConstruction() override;
G4VPhysicalVolume* Construct() override;
void DumpGeometryParameters();
inline void SetWorldXY(G4double val) { fWorldXY = val; }
inline void SetWorldZ(G4double val) { fWorldZ = val; }
private:
G4double fWorldXY, fWorldZ;
G4Material* fWorldMat;
DetectorMessenger* fMessenger;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif
@@ -0,0 +1,61 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
#ifndef DetectorMessenger_h
#define DetectorMessenger_h 1
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
#include "globals.hh"
#include "G4UImessenger.hh"
class G4UIdirectory;
class G4UIcommand;
class G4UIcmdWithADoubleAndUnit;
class DetectorConstruction;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
class DetectorMessenger: public G4UImessenger
{
public:
DetectorMessenger(DetectorConstruction* geom);
virtual ~DetectorMessenger() override;
void SetNewValue(G4UIcommand* command, G4String newValue) override;
private:
DetectorConstruction* fGeom;
G4UIdirectory* fGeomDir;
G4UIcmdWithADoubleAndUnit* fWorldXYCmd;
G4UIcmdWithADoubleAndUnit* fWorldZCmd;
};
#endif
@@ -0,0 +1,325 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// Author: M.A. Cortes-Giraldo, Universidad de Sevilla
//
// History changelog prior creation of this example:
// - 13/04/2009: Messenger class added.
// - 17/10/2009: version 1.0
// - 20/11/2009: version 1.1 before publishing:
// - Changed some names by more suitable ones
// - 02/08/2010: version 1.2-dev:
// - Added possbility of applying axial symmetries
// - 14/09/2023: version 2.0
// - Following Geant4 coding guidelines
// - 18/10/2025: version 3.0
// - Creation of IAEASourceIdRegistry for thread-safe source_id assignation
//
#ifndef G4IAEAphspReader_h
#define G4IAEAphspReader_h 1
#include "G4VPrimaryGenerator.hh"
#include <vector>
#include "globals.hh"
#include "G4ThreeVector.hh"
class G4Event;
class G4IAEAphspReaderMessenger;
class G4IAEAphspReader :public G4VPrimaryGenerator
{
public:
G4IAEAphspReader(const char* filename, const G4int threads = 1);
G4IAEAphspReader(const G4String filename, const G4int threads = 1);
// 'filename' must include the path if needed, but NOT the extension
~G4IAEAphspReader() override;
void GeneratePrimaryVertex(G4Event* evt) override; // Mandatory
inline void SetVerbose(const G4int verb)
{
fVerbose = verb;
if (fVerbose > 0)
G4cout << "G4IAEAphspReader::fVerbose = " << fVerbose << G4endl;
}
inline void SetTotalParallelRuns(const G4int nParallelRuns)
{
fTotalParallelRuns = nParallelRuns;
if (fVerbose > 0)
G4cout << "G4IAEAphspReader::fTotalParallelRuns = " << fTotalParallelRuns
<< G4endl;
}
void SetParallelRun(const G4int parallelRun);
inline void SetTotalThreads(const G4int threads) {fTotalThreads = threads;}
inline void SetTimesRecycled(const G4int ntimes) {fTimesRecycled = ntimes;}
inline void SetGlobalPhspTranslation(const G4ThreeVector & pos)
{fGlobalPhspTranslation = pos;}
inline void SetRotationOrder(const G4int ord) { fRotationOrder = ord; }
inline void SetRotationX(const G4double alpha) { fAlpha = alpha; }
inline void SetRotationY(const G4double beta) { fBeta = beta; }
inline void SetRotationZ(const G4double gamma) { fGamma = gamma; }
inline void SetIsocenterPosition(const G4ThreeVector & pos)
{fIsocenterPosition = pos;}
void SetCollimatorRotationAxis(const G4ThreeVector & axis);
void SetGantryRotationAxis(const G4ThreeVector & axis);
inline void SetCollimatorAngle(const G4double ang) {fCollimatorAngle = ang;}
inline void SetGantryAngle(const G4double ang) {fGantryAngle = ang;}
inline void SetAxialSymmetryX(const G4bool value)
{
fAxialSymmetryX = value;
if (value) {
fAxialSymmetryY = false;
fAxialSymmetryZ = false;
}
}
inline void SetAxialSymmetryY(const G4bool value)
{
fAxialSymmetryY = value;
if (value) {
fAxialSymmetryZ = false;
fAxialSymmetryX = false;
}
}
inline void SetAxialSymmetryZ(const G4bool value)
{
fAxialSymmetryZ = value;
if (value) {
fAxialSymmetryX = false;
fAxialSymmetryY = false;
}
}
inline G4String GetFileName() const {return fFileName;}
inline G4int GetSourceReadId() const {return fSourceReadId;}
inline G4long GetOrigHistories() const {return fOrigHistories;}
inline G4long GetUsedOrigHistories() const {return fUsedOrigHistories;}
inline G4long GetTotalParticles() const {return fTotalParticles;}
inline G4int GetNumberOfExtraFloats() const {return fNumberOfExtraFloats;}
inline G4int GetNumberOfExtraInts() const {return fNumberOfExtraInts;}
inline std::vector<G4int>* GetExtraFloatTypes() const
{return fExtraFloatTypes;}
inline std::vector<G4int>* GetExtraIntTypes() const
{return fExtraIntTypes;}
G4long GetTotalParticlesOfType(const G4String type) const;
G4double GetConstantVariable(const G4int index) const;
inline std::vector<G4int>* GetParticleTypeVec() const
{return fParticleTypeVec;}
inline std::vector<G4double>* GetKinEVec() const
{return fKinEVec;}
inline std::vector<G4ThreeVector>* GetPosVec() const
{return fPosVec;}
inline std::vector<G4ThreeVector>* GetMomDirVec() const
{return fMomDirVec;}
inline std::vector<G4double>* GetWeightVec() const
{return fWeightVec;}
inline std::vector< std::vector<G4double> >* GetExtraFloatVec() const
{return fExtraFloatVec;}
inline std::vector< std::vector<G4long> >* GetExtraIntVec() const
{return fExtraIntVec;}
inline G4int GetTotalParallelRuns() const {return fTotalParallelRuns;}
inline G4int GetParallelRun() const {return fParallelRun;}
inline G4int GetTotalThreads() const {return fTotalThreads;}
inline G4long GetFirstParticle() const {return fFirstParticle;}
inline G4long GetLastParticle() const {return fLastParticle;}
inline G4int GetTimesRecycled() const {return fTimesRecycled;}
inline G4ThreeVector GetGlobalPhspTranslation() const
{return fGlobalPhspTranslation;}
inline G4int GetRotationOrder() const {return fRotationOrder;}
inline G4double GetRotationX() const {return fAlpha;}
inline G4double GetRotationY() const {return fBeta;}
inline G4double GetRotationZ() const {return fGamma;}
inline G4ThreeVector GetIsocenterPosition() const
{return fIsocenterPosition;}
inline G4double GetCollimatorAngle() const {return fCollimatorAngle;}
inline G4double GetGantryAngle() const {return fGantryAngle;}
inline G4ThreeVector GetCollimatorRotationAxis() const
{return fCollimatorRotAxis;}
inline G4ThreeVector GetGantryRotationAxis() const {return fGantryRotAxis;}
inline G4bool GetAxialSymmetryX() const {return fAxialSymmetryX;}
inline G4bool GetAxialSymmetryY() const {return fAxialSymmetryY;}
inline G4bool GetAxialSymmetryZ() const {return fAxialSymmetryZ;}
private:
G4IAEAphspReader() = default;
void InitializeMembers();
void InitializeSource(const G4String filename);
void ComputeFirstLastParticle();
void ReadAndStoreFirstParticle();
void PrepareThisEvent();
void ReadThisEvent();
void GeneratePrimaryParticles(G4Event* evt);
void PerformRotations(G4ThreeVector& mom);
void PerformGlobalRotations(G4ThreeVector& mom);
void PerformHeadRotations(G4ThreeVector& mom);
void RestartSourceFile();
// ========== Data members ==========
private:
// ----------------------
// FILE GLOBAL PROPERTIES
// ----------------------
G4String fFileName;
// Must include the path, but NOT the IAEA extension
G4int fSourceReadId;
// The Id the file source has for the IAEA routines.
// This value is set by IAEA routines, but should correspond to thread Id.
// static const G4int fAccessRead = 1;
// A value needed to open the file in the IAEA codes
G4long fOrigHistories;
// Number of original histories which generated the phase space file
G4long fTotalParticles;
// Number of particles stored in the phase space file
G4int fNumberOfExtraFloats, fNumberOfExtraInts;
// Number of extra variables stored for each particle
std::vector<G4int>* fExtraFloatTypes;
std::vector<G4int>* fExtraIntTypes;
// Identification to classify the different extra variables
// ---------------------
// PARTICLE PROPERTIES
// ---------------------
std::vector<G4int>* fParticleTypeVec;
std::vector<G4double>* fKinEVec;
std::vector<G4ThreeVector>* fPosVec;
std::vector<G4ThreeVector>* fMomDirVec;
std::vector<G4double>* fWeightVec;
std::vector< std::vector<G4double> >* fExtraFloatVec;
std::vector< std::vector<G4long> >* fExtraIntVec;
// -------------------
// COUNTERS AND FLAGS
// -------------------
G4int fTotalParallelRuns;
// For independent parallel runs, number of fragments in which the
// PSF is divided.
G4int fParallelRun;
// Sets the fragment of PSF from which the particles must be read.
G4int fTotalThreads;
// Stores the total number of threads being used. Set via G4RunManager.
G4long fFirstParticle;
// First particle to read.
// Value given by the number of independent parallel runs and threads.
G4long fLastParticle;
// Last particle to read.
// Value given by the number of independent parallel runs and threads.
G4int fTimesRecycled;
// Set the number of times that each particle is recycled (not repeated)
G4int fNStat;
// Decides how many events should pass before throwing a new particle
G4long fUsedOrigHistories;
// Variable that stores the number of original histories read so far
G4long fCurrentParticle;
// Number to store the current particle position in PSF
G4bool fEndOfFile;
// Flag active when the file has reached the end
G4bool fLastGenerated;
// Flag active only when the last particle has been simulated
// ------------------------
// SPATIAL TRANSFORMATIONS
// ------------------------
G4ThreeVector fGlobalPhspTranslation;
// Global translation performed to particles
G4int fRotationOrder;
// Variable to decide first, second and third rotations
// For example, 132 means rotations using X, Z and Y global axis
G4double fAlpha, fBeta, fGamma;
// Angles of rotations around global axis
G4ThreeVector fIsocenterPosition;
// Position of the isocenter if needed
G4double fCollimatorAngle, fGantryAngle;
G4ThreeVector fCollimatorRotAxis, fGantryRotAxis;
// Angles and axis of isocentric rotations in the machine
// The collimator ALWAYS rotates first.
// --------------------
// ROTATIONAL SYMMETRY
// --------------------
// Boolean data members to apply rotational symmetry around XYZ axis
// Only one can be set to true.
G4bool fAxialSymmetryX;
G4bool fAxialSymmetryY;
G4bool fAxialSymmetryZ;
// ----------------
// MESSENGER CLASS
// ----------------
G4IAEAphspReaderMessenger* fMessenger;
// ----------
// VERBOSITY
// ----------
G4int fVerbose;
};
#endif
@@ -0,0 +1,126 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// Author: M.A. Cortes-Giraldo, Universidad de Sevilla
//
// History changelog prior creation of this example:
// - 17/10/2009: version 1.0
// - 20/11/2009: version 1.1 before publishing:
// - Changed some names by more suitable ones
// - 02/08/2010: version 1.2-dev:
// - Added possibility of applying axial symmetries
// - 14/09/2023: version 2.0
// - Following Geant4 coding guidelines
// - 18/10/2025: version 3.0
// - Creation of IAEASourceIdRegistry for thread-safe source_id assignation
//
#ifndef G4IAEAphspReaderMessenger_h
#define G4IAEAphspReaderMessenger_h 1
#include "globals.hh"
#include "G4UImessenger.hh"
class G4IAEAphspReader;
class G4UIcmdWith3Vector;
class G4UIcmdWith3VectorAndUnit;
class G4UIcmdWithABool;
class G4UIcmdWithADoubleAndUnit;
class G4UIcmdWithAnInteger;
class G4UIcommand;
class G4UIdirectory;
class G4IAEAphspReaderMessenger: public G4UImessenger
{
public:
G4IAEAphspReaderMessenger(G4IAEAphspReader* );
~G4IAEAphspReaderMessenger() override;
void SetNewValue(G4UIcommand*, G4String) override;
private:
G4IAEAphspReader* fIAEAphspReader;
// Pointer to the IAEA phase-space reader.
G4UIdirectory* fPhaseSpaceDir;
// Control of the phase space
G4UIcmdWithAnInteger* fVerboseCmd;
// UI command for verbosity level.
G4UIcmdWithAnInteger* fNofParallelRunsCmd;
// UI command to define the number of fragments defined in the file.
G4UIcmdWithAnInteger* fParallelRunCmd;
// UI command to choose the specific fragment where the particles are
// taken from.
G4UIcmdWithAnInteger* fTimesRecycledCmd;
// UI command to set the number of times each particle is recycled
// (not repeated).
G4UIcmdWith3VectorAndUnit* fPhspGlobalTranslationCmd;
// UI command to set the three-vector to move the phase-space plane globally.
G4UIcmdWithAnInteger* fPhspRotationOrderCmd;
// UI command to set the order in which the rotations are performed.
G4UIcmdWithADoubleAndUnit* fRotXCmd;
// UI command to set the rotation angle around X axis.
G4UIcmdWithADoubleAndUnit* fRotYCmd;
// UI command to set the rotation angle around Y axis.
G4UIcmdWithADoubleAndUnit* fRotZCmd;
// UI command to set the rotation angle around Z axis.
G4UIcmdWith3VectorAndUnit* fIsocenterPosCmd;
// UI command to set where the isocenter is.
G4UIcmdWith3Vector* fCollimatorRotAxisCmd;
// UI command to set the rotation axis of the collimator.
G4UIcmdWithADoubleAndUnit* fCollimatorAngleCmd;
// UI command to set the rotation angle of the treatment head.
G4UIcmdWith3Vector* fGantryRotAxisCmd;
// UI command to set the rotation axis of the gantry.
G4UIcmdWithADoubleAndUnit* fGantryAngleCmd;
// UI command to set the rotation angle of the gantry.
G4UIcmdWithABool* fAxialSymmetryXCmd;
// UI command to turn on/off the rotational symmetry around X.
G4UIcmdWithABool* fAxialSymmetryYCmd;
// UI command to turn on/off the rotational symmetry around Y.
G4UIcmdWithABool* fAxialSymmetryZCmd;
// UI command to turn on/off the rotational symmetry around Z.
};
#endif
@@ -0,0 +1,114 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// Author: M.A. Cortes-Giraldo, Universidad de Sevilla
//
// History changelog prior creation of this example:
// - 17/10/2009: inheritance removed (not needed)
// - 17/10/2009: version 1.0
// - 07/10/2024: version 2.0 for Geant4 example (MT compliant)
// - 18/10/2025: version 3.0
// - Creation of IAEASourceIdRegistry for thread-safe source_id assignation
//
#ifndef G4IAEAphspWriter_hh
#define G4IAEAphspWriter_hh 1
#include "G4ThreeVector.hh"
#include "globals.hh"
#include <map>
#include <vector>
class G4Run;
class G4Step;
class G4IAEAphspWriterStack;
//------------------------------------------------------------------------------
class G4IAEAphspWriter
{
public:
G4IAEAphspWriter(const G4String filename);
~G4IAEAphspWriter();
void OpenIAEAphspOutFiles(const G4Run*);
void WriteIAEAParticle(const size_t idx, const G4int nStat, const G4int pdg,
const G4double kinE, const G4double wt,
const G4ThreeVector pos, const G4ThreeVector momDir);
void CloseIAEAphspOutFiles();
void AddZphsp(const G4double zphsp);
void SetDataFromIAEAStack(const G4IAEAphspWriterStack* );
// void UpdateHeaders();
void SetFileName(const G4String name) { fFileName = name; }
void SetConstVariable(G4int idx, G4double value);
void SumOrigHistories(size_t idx, G4int value)
{ fOrigHistories->at(idx) += value; }
const G4String GetFileName() const { return fFileName; }
const std::vector<G4double>* GetZphspVec() const { return fZphspVec; }
const std::vector<G4int>* GetOrigHistoriesVec() const
{ return fOrigHistories; }
private:
G4IAEAphspWriter() = default;
void WriteIAEAParticle(const G4Step* aStep, const G4int zStopIdx);
// ------------
// DATA MEMBERS
// ------------
// FILE PROPERTIES
G4String fFileName;
// Must include the path but not any of the IAEA extensions.
std::vector<G4double>* fZphspVec = nullptr;
// Vector storing the z-value of the phsp planes.
std::map<G4int, G4double>* fConstVariables = nullptr;
// Map to store the value of the variables set as constant for the phsp's
// to save disk space.
// COUNTERS AND FLAGS
std::vector<G4int>* fOrigHistories = nullptr;
// Vector bookkeeping the number of original histories recorded for each phsp.
// For regular simulations, all the elements should have the same value.
G4int fIAEASourcesOpen;
// This is a counter to consider if there is another IAEA file already open,
// e.g. a source IAEAphsp file to generate particles.
};
#endif
@@ -0,0 +1,124 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// Author: M.A. Cortes-Giraldo
//
// 2025-08-27: Its objects work in local runs, their mission is to store the
// info of the particles to be written in the IAEAphsp output files at
// the end of the run. In other words, they constitute a stack for
// IAEAphsp particles until the run finishes, when the IAEAphsp file is
// actually written.
//
#ifndef G4IAEAphspWriterStack_hh
#define G4IAEAphspWriterStack_hh 1
#include "globals.hh"
#include "G4ThreeVector.hh"
#include <set>
#include <vector>
class G4IAEAphspWriter;
class G4Step;
class G4IAEAphspWriterStack
{
public:
G4IAEAphspWriterStack(const G4String filename);
~G4IAEAphspWriterStack();
void AddZphsp(const G4double zphsp);
void ClearZphspVec();
void SetDataFromWriter(const G4IAEAphspWriter* );
void PrepareRun();
void PrepareNextEvent();
void StoreParticleIfEligible(const G4Step*);
void ClearRunVectors();
void SetFileName(const G4String name) { fFileName = name; }
const G4String GetFileName() const {return fFileName;}
const std::vector<G4double>* GetZphspVec() const {return fZphspVec;}
std::vector<std::vector<G4int>* >* GetPDGMtrx() const {return fPDGMtrx;}
std::vector<std::vector<G4ThreeVector>* >* GetPosMtrx() const
{return fPosMtrx;}
std::vector<std::vector<G4ThreeVector>* >* GetMomMtrx() const
{return fMomMtrx;}
std::vector<std::vector<G4double>* >* GetEneMtrx() const {return fEneMtrx;}
std::vector<std::vector<G4double>* >* GetWtMtrx() const {return fWtMtrx;}
std::vector<std::vector<G4int>* >* GetNstatMtrx() const {return fNstatMtrx;}
private:
G4IAEAphspWriterStack() = default;
void StoreIAEAParticle(const G4Step* aStep, const G4int zStopIdx,
const G4int pdgCode);
// ------------
// DATA MEMBERS
// ------------
// FILE PROPERTIES
G4String fFileName;
// Must include the path but not any of the IAEA extensions.
// (This is set from G4IAEAphspWriter)
std::vector<G4double>* fZphspVec = nullptr;
// Vector storing the z-value of the phsp planes.
// COUNTERS & TAGS
std::vector<G4int>* fIncrNumberVec = nullptr;
// Book-keeping of the number of previous events without having particles
// crossing the phsp plane.
// (i.e., the current incremental history number, or n_stat, of each phsp)
std::vector< std::set<G4int>* >* fPassingTracksVec = nullptr;
// Each set is meant to store the track ID of every particle
// crossing one of the planes during an event.
// This is done to avoid registering multiple crosses in the phsp file.
// INFORMATION STORED DURING RUN
// First component is the phsp plane, according to registration ordering.
// Second components are the dynamic variables.
std::vector< std::vector<G4int>* >* fPDGMtrx = nullptr;
std::vector< std::vector<G4ThreeVector>* >* fPosMtrx = nullptr;
std::vector< std::vector<G4ThreeVector>* >* fMomMtrx = nullptr;
std::vector< std::vector<G4double>* >* fEneMtrx = nullptr;
std::vector< std::vector<G4double>* >* fWtMtrx = nullptr;
std::vector< std::vector<G4int>* >* fNstatMtrx = nullptr;
};
#endif
@@ -0,0 +1,83 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
#ifndef IAEASourceIdRegistry_hh
#define IAEASourceIdRegistry_hh 1
#include <bitset>
#include "G4AutoLock.hh"
#include "globals.hh"
constexpr G4int kIAEA_MaxSources = 30; // MAX_NUM_SOURCES
class IAEASourceIdRegistry {
public:
static IAEASourceIdRegistry& Instance() {
static IAEASourceIdRegistry inst;
return inst;
}
// Reserve the next free ID (lowest or highest; your choice)
G4int ReserveNextLowest() {
G4AutoLock lock(&fMutex);
for (G4int ii = 0; ii < kIAEA_MaxSources; ii++) {
if (!fUsed.test(ii)) {
fUsed.set(ii);
return ii;
}
}
return -1; // none free
}
// Reserve a specific ID (returns true if we could mark it)
bool ReserveExact(G4int id) {
if (id < 0 || id >= kIAEA_MaxSources) return false;
G4AutoLock lock(&fMutex);
if (fUsed.test(id)) return false;
fUsed.set(id);
return true;
}
void Release(G4int id) {
if (id < 0 || id >= kIAEA_MaxSources) return;
G4AutoLock lock(&fMutex);
fUsed.reset(id);
}
private:
IAEASourceIdRegistry() = default;
IAEASourceIdRegistry(const IAEASourceIdRegistry&) = delete;
IAEASourceIdRegistry& operator=(const IAEASourceIdRegistry&) = delete;
std::bitset<kIAEA_MaxSources> fUsed;
G4Mutex fMutex = G4MUTEX_INITIALIZER;
};
#endif
@@ -0,0 +1,74 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
#ifndef IAEAphspRun_h
#define IAEAphspRun_h 1
#include "G4Run.hh"
class G4Event;
class G4IAEAphspWriter;
class G4IAEAphspWriterStack;
class IAEAphspRun : public G4Run
{
public:
// constructor and destructor.
IAEAphspRun();
IAEAphspRun(G4IAEAphspWriterStack* iaeaStack);
virtual ~IAEAphspRun() override;
// virtual method from G4Run.
// The method is overriden in this class for scoring.
virtual void RecordEvent(const G4Event*) override;
// virtual method from G4Run.
// To merge local G4Run object into the global G4Run object.
virtual void Merge(const G4Run*) override;
// method to dump info into IAEAphsp output files
void DumpToIAEAphspFiles(const G4IAEAphspWriterStack*);
// Get/Set methods
G4IAEAphspWriter* GetIAEAphspWriter() const { return fIAEAphspWriter; }
G4IAEAphspWriterStack* GetIAEAphspWriterStack() const
{ return fIAEAphspWriterStack; }
private:
// DATA MEMBERS
G4IAEAphspWriter* fIAEAphspWriter = nullptr;
G4IAEAphspWriterStack* fIAEAphspWriterStack = nullptr;
};
#endif
@@ -0,0 +1,73 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//----------------------------------------------------------------------------//
// This physics list *must* be set with a *reference* physics list.
// These provide a full set of models (both electromagnetic and hadronic).
//
// The reference physics list must be set by issuing its command in a macro
// file (see messenger class). No other action is required.
// Examples of physics list names: QGSP_BIC_HP_EMZ or QGSP_BERT_HP
//----------------------------------------------------------------------------//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#ifndef PhysicsList_h
#define PhysicsList_h 1
#include "G4VModularPhysicsList.hh"
#include "globals.hh"
class PhysicsListMessenger;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class PhysicsList: public G4VModularPhysicsList
{
public:
PhysicsList();
virtual ~PhysicsList() override;
void ConstructParticle() override;
void ConstructProcess() override;
void SetPhysicsList(const G4String&);
inline void SetVerbose(G4int val) { fVerbose = val; }
private:
G4int fVerbose;
G4bool fPhysListIsSet; // Reference physics list
PhysicsListMessenger* fMessenger;
};
#endif
@@ -0,0 +1,62 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
#ifndef PhysicsListMessenger_h
#define PhysicsListMessenger_h 1
#include "globals.hh"
#include "G4UImessenger.hh"
class PhysicsList;
class G4UIdirectory;
class G4UIcmdWithAString;
class G4UIcmdWithAnInteger;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class PhysicsListMessenger: public G4UImessenger
{
public:
PhysicsListMessenger(PhysicsList* );
virtual ~PhysicsListMessenger() override;
void SetNewValue(G4UIcommand*, G4String) override;
private:
PhysicsList* fPL;
G4UIdirectory* fPhysDir;
G4UIcmdWithAnInteger* fVerbCmd;
G4UIcmdWithAString* fPhysListCmd;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif
@@ -0,0 +1,99 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
#ifndef PrimaryGeneratorAction_h
#define PrimaryGeneratorAction_h 1
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
#include "G4VUserPrimaryGeneratorAction.hh"
#include "globals.hh"
class G4Event;
class G4ParticleGun;
class G4IAEAphspReader;
class PrimaryGeneratorMessenger;
class DetectorConstruction;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
class PrimaryGeneratorAction : public G4VUserPrimaryGeneratorAction
{
public:
// The constructor defines a ParticleGun object, which allows
// shooting a beam of particles through the experimental set-up.
// It also needs a pointer to G4IAEAphspReader object in case we need to
// read particles from an IAEAphsp file
PrimaryGeneratorAction(const G4int threads);
//The destructor. It deletes the ParticleGun.
virtual ~PrimaryGeneratorAction() override;
//Generates the primary event via the ParticleGun method,
// and from the IAEA phase-space file.
void GeneratePrimaries(G4Event* anEvent) override;
//Get/Set methods
inline void SetKinE(const G4double val) { fKinE = val; };
inline void SetDE(const G4double val) { fDE = val; };
inline void SetX0(const G4double val) { fX0 = val;};
inline void SetY0(const G4double val) { fY0 = val;};
inline void SetZ0(const G4double val) { fZ0 = val;};
inline void SetDX(const G4double val) { fDX = val;};
inline void SetDY(const G4double val) { fDY = val;};
inline void SetDZ(const G4double val) { fDZ = val;};
inline void SetVerbose(const G4int val) { fVerbose = val;};
void SetIAEAphspReader(const G4String filename);
inline G4int GetVerbose() const { return fVerbose; }
inline G4IAEAphspReader* GetIAEAphspReader() const {return fIAEAphspReader;}
private:
// Phase space reader
G4IAEAphspReader* fIAEAphspReader = nullptr;
G4int fThreads;
G4String fIAEAphspReaderName;
G4int fVerbose;
PrimaryGeneratorMessenger* fMessenger;
G4ParticleGun* fParticleGun;
G4int fCounter;
G4double fKinE, fDE;
G4double fX0, fY0, fZ0;
G4double fDX, fDY, fDZ;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#endif
@@ -0,0 +1,71 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
#ifndef PrimaryGeneratorMessenger_h
#define PrimaryGeneratorMessenger_h 1
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
#include "globals.hh"
#include "G4UImessenger.hh"
class G4UIdirectory;
class G4UIcommand;
class G4UIcmdWithADoubleAndUnit;
class G4UIcmdWithAnInteger;
class PrimaryGeneratorAction;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
class PrimaryGeneratorMessenger: public G4UImessenger
{
public:
PrimaryGeneratorMessenger(PrimaryGeneratorAction* gen);
virtual ~PrimaryGeneratorMessenger() override;
void SetNewValue(G4UIcommand* command, G4String newValue) override;
private:
PrimaryGeneratorAction* fGen;
G4UIdirectory* fBeamDir;
G4UIcmdWithADoubleAndUnit* fKinECmd;
G4UIcmdWithADoubleAndUnit* fDECmd;
G4UIcmdWithADoubleAndUnit* fX0Cmd;
G4UIcmdWithADoubleAndUnit* fY0Cmd;
G4UIcmdWithADoubleAndUnit* fZ0Cmd;
G4UIcmdWithADoubleAndUnit* fDXCmd;
G4UIcmdWithADoubleAndUnit* fDYCmd;
G4UIcmdWithADoubleAndUnit* fDZCmd;
G4UIcmdWithAnInteger* fVerboseCmd;
};
#endif
@@ -0,0 +1,68 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
#ifndef RunAction_h
#define RunAction_h 1
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
#include "G4UserRunAction.hh"
#include "globals.hh"
class G4Run;
class G4IAEAphspWriterStack;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
class RunAction : public G4UserRunAction
{
public:
RunAction() = default;
virtual ~RunAction() override;
G4Run* GenerateRun() override;
// A derived G4Run is needed to store IAEAphsp particles during local run
// and to dump info into the IAEAphsp files using Run::Merge()
// void BeginOfRunAction(const G4Run*) override;
void EndOfRunAction(const G4Run*) override;
// Modifiers and setters
void SetIAEAphspWriterStack(const G4String& namePrefix);
void AddZphsp(const G4double val);
private:
// IAEAphsp stack object for the local run
G4IAEAphspWriterStack* fIAEAphspWriterStack = nullptr;
};
#endif
@@ -0,0 +1,46 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
#ifndef SteppingAction_h
#define SteppingAction_h 1
#include "G4UserSteppingAction.hh"
class G4Step;
class SteppingAction: public G4UserSteppingAction
{
public:
SteppingAction() = default;
virtual ~SteppingAction() override = default;
// To store eligible particles in the IAEAphspWriterstack
virtual void UserSteppingAction(const G4Step* step) override;
};
#endif
@@ -0,0 +1,104 @@
$IAEA_INDEX:
1000 // Test header
$TITLE:
PHASESPACE in IAEA format
$FILE_TYPE:
0
$CHECKSUM:
5000
$RECORD_CONTENTS:
1 // X is stored ?
1 // Y is stored ?
0 // Z is stored ?
1 // U is stored ?
1 // V is stored ?
1 // W is stored ?
0 // Weight is stored ?
0 // Extra floats stored ?
1 // Extra longs stored ?
1 // Incremental history number stored in the extralong array [ 0]
$RECORD_CONSTANT:
5.0000 // Constant Z
0.1000 // Constant Weight
$RECORD_LENGTH:
25
$BYTE_ORDER:
1234
$ORIG_HISTORIES:
1000
$PARTICLES:
200
$PHOTONS:
40
$ELECTRONS:
40
$POSITRONS:
40
$NEUTRONS:
40
$PROTONS:
40
$TRANSPORT_PARAMETERS:
$MACHINE_TYPE:
$MONTE_CARLO_CODE_VERSION:
$GLOBAL_PHOTON_ENERGY_CUTOFF:
0.00000
$GLOBAL_PARTICLE_ENERGY_CUTOFF:
0.00000
$COORDINATE_SYSTEM_DESCRIPTION:
// OPTIONAL INFORMATION
$BEAM_NAME:
$FIELD_SIZE:
$NOMINAL_SSD:
$MC_INPUT_FILENAME:
$VARIANCE_REDUCTION_TECHNIQUES:
$INITIAL_SOURCE_DESCRIPTION:
$PUBLISHED_REFERENCE:
$AUTHORS:
$INSTITUTION:
$LINK_VALIDATION:
$ADDITIONAL_NOTES:
This is IAEA header as defined in the technical
report IAEA(NDS)-0484, Vienna, 2006
$STATISTICAL_INFORMATION_PARTICLES:
// Weight Wmin Wmax <E> Emin Emax Particle
4 0.1 0.1 2.05 0.1 4 PHOTONS
4 0.1 0.1 6.05 4.1 8 ELECTRONS
4 0.1 0.1 10.05 8.1 12 POSITRONS
4 0.1 0.1 14.05 12.1 16 NEUTRONS
4 0.1 0.1 18.05 16.1 20 PROTONS
$STATISTICAL_INFORMATION_GEOMETRY:
-1 1
-1 1
Binary file not shown.
@@ -0,0 +1,95 @@
$IAEA_INDEX:
0 // Test header
$TITLE:
TEST PHASESPACE for IAEA format (random numbers)
$FILE_TYPE:
0
$CHECKSUM:
237597
$RECORD_CONTENTS:
1 // X is stored ?
1 // Y is stored ?
0 // Z is stored ?
1 // U is stored ?
1 // V is stored ?
1 // W is stored ?
1 // Weight is stored ?
0 // Extra floats stored ?
1 // Extra longs stored ?
2 // EGS LATCH
$RECORD_CONSTANT:
80.0000 // Constant Z
$RECORD_LENGTH:
29
$BYTE_ORDER:
1234
$ORIG_HISTORIES:
50000
$PARTICLES:
8193
$PHOTONS:
5958
$ELECTRONS:
2232
$POSITRONS:
3
$TRANSPORT_PARAMETERS:
$MACHINE_TYPE:
$MONTE_CARLO_CODE_VERSION:
$GLOBAL_PHOTON_ENERGY_CUTOFF:
0.001
$GLOBAL_PARTICLE_ENERGY_CUTOFF:
0.100
$COORDINATE_SYSTEM_DESCRIPTION:
// OPTIONAL INFORMATION
$BEAM_NAME:
$FIELD_SIZE:
$NOMINAL_SSD:
$MC_INPUT_FILENAME:
$VARIANCE_REDUCTION_TECHNIQUES:
$INITIAL_SOURCE_DESCRIPTION:
$PUBLISHED_REFERENCE:
$AUTHORS:
$INSTITUTION:
$LINK_VALIDATION:
$ADDITIONAL_NOTES:
This is IAEA header as defined in the technical
report IAEA(NDS)-0484, Vienna, 2006
$STATISTICAL_INFORMATION_PARTICLES:
// Weight Wmin Wmax <E> Emin Emax Particle
5958.00 1.00000 1.00 1.53 0.01368 11.53 PHOTONS
2232.00 1.00000 1.00 8.88 0.20873 10.96 ELECTRONS
3.00 1.00000 1.00 2.51 1.27093 3.24 POSITRONS
$STATISTICAL_INFORMATION_GEOMETRY:
-16.995096 16.969553
-16.990067 16.972181
Binary file not shown.
@@ -0,0 +1,188 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
#include "ActionInitialization.hh"
#include "ActionInitializationMessenger.hh"
#include "globals.hh"
#include "PrimaryGeneratorAction.hh"
#include "RunAction.hh"
#include "SteppingAction.hh"
#include "G4RunManager.hh"
#include "G4Threading.hh"
#include "G4IAEAphspReader.hh"
#include "G4IAEAphspWriterStack.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
ActionInitialization::ActionInitialization()
: G4VUserActionInitialization()
{
// Messenger
fMessenger = new ActionInitializationMessenger(this);
// IAEAphsp source file name (including path) for primary generator
fIAEAphspReaderName = "";
fNumberOfThreads = G4RunManager::GetRunManager()->GetNumberOfThreads();
// Name prefix, including path, of IAEAphsp output files (default, nothing).
fIAEAphspWriterNamePrefix = "";
// Vector to register phsp planes (Z=const)
fZphspVec = new std::vector<G4double>;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
ActionInitialization::~ActionInitialization()
{
if (fZphspVec) {
fZphspVec->clear();
delete fZphspVec;
}
if (fMessenger) delete fMessenger;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void ActionInitialization::BuildForMaster() const
{
// G4cout << "ActionInitialization::BuildForMaster() started" << G4endl;
SetUserAction(new RunAction());
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void ActionInitialization::Build() const
{
// G4cout << "ActionInitialization::Build() started" << G4endl;
G4cout << "IAEAphsp file to read is \"" << fIAEAphspReaderName << "\"."
<< G4endl;
PrimaryGeneratorAction* prim = new PrimaryGeneratorAction(fNumberOfThreads);
if ( !fIAEAphspReaderName.empty() ) // never true in sequential mode
prim->SetIAEAphspReader(fIAEAphspReaderName);
SetUserAction(prim);
RunAction* runAct = new RunAction();
if (fIAEAphspWriterNamePrefix != "") { // never true in sequential mode
// Set G4IAEAphspWriterStack object for the local thread
// and register zphsp values to it
runAct->SetIAEAphspWriterStack(fIAEAphspWriterNamePrefix);
if (fZphspVec->size() > 0) {
for (const auto& zphsp : (*fZphspVec))
runAct->AddZphsp(zphsp);
}
else {
G4ExceptionDescription msg;
msg << "IAEAphsp output file name provided, but no zphsp values "
<< "have been registered!" << G4endl;
G4Exception("ActionInitialization::Build()",
"ActionInit001", FatalException, msg);
}
}
SetUserAction(runAct);
SteppingAction *steppingAction = new SteppingAction();
SetUserAction(steppingAction);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void ActionInitialization::SetIAEAphspReader(const G4String& name)
{
fIAEAphspReaderName = name;
if ( !(G4Threading::IsMultithreadedApplication()) ) {
// In sequential mode, when this command is issued, Build() has been
// called already. Thus, we must set G4IAEAphspReader object here
const G4VUserPrimaryGeneratorAction* basePrim =
G4RunManager::GetRunManager()->GetUserPrimaryGeneratorAction();
if (!basePrim) return; // No PGA yet (very unlikely in sequential)
// 1) cast while preserving constness
const auto* myConstPrim =
dynamic_cast<const PrimaryGeneratorAction*>(basePrim);
if (!myConstPrim) return;
// 2) Drop constness to set G4IAEAphspReader object
auto* myPrim = const_cast<PrimaryGeneratorAction*>(myConstPrim);
myPrim->SetIAEAphspReader(name);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void ActionInitialization::SetIAEAphspWriterPrefix(const G4String& prefix)
{
fIAEAphspWriterNamePrefix = prefix;
if ( !(G4Threading::IsMultithreadedApplication()) ) {
// In sequential mode, when this command is issued, Build() has been
// called already. Thus, we must set G4IAEAphspWriterStack object here
const G4UserRunAction* baseRA =
G4RunManager::GetRunManager()->GetUserRunAction();
if (!baseRA) return; // No run action defined
// 1) cast while preserving constness
const auto* myConstRA = dynamic_cast<const RunAction*>(baseRA);
if (!myConstRA) return;
// 2) Drop constness to modify RunAction object status
auto* myRA = const_cast<RunAction*>(myConstRA);
myRA->SetIAEAphspWriterStack(prefix);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void ActionInitialization::AddZphsp(const G4double zphsp)
{
fZphspVec->push_back(zphsp);
if ( !(G4Threading::IsMultithreadedApplication()) ) {
// In sequential mode, when this command is issued, Build() has been
// called already. Thus, we must set G4IAEAphspWriterStack object here
const G4UserRunAction* baseRA =
G4RunManager::GetRunManager()->GetUserRunAction();
if (!baseRA) return; // No run action defined
// 1) cast while preserving constness
const auto* myConstRA = dynamic_cast<const RunAction*>(baseRA);
if (!myConstRA) return;
// 2) Drop constness to modify RunAction object status
auto* myRA = const_cast<RunAction*>(myConstRA);
myRA->AddZphsp(zphsp);
}
}
@@ -0,0 +1,112 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "ActionInitializationMessenger.hh"
#include "ActionInitialization.hh"
#include "G4UIdirectory.hh"
#include "G4UIcmdWithADoubleAndUnit.hh"
#include "G4UIcmdWithAString.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
ActionInitializationMessenger::
ActionInitializationMessenger(ActionInitialization* act)
:fAction(act)
{
fActionDir = new G4UIdirectory("/action/");
fActionDir->SetGuidance("Commands for action initialization status");
fIAEAphspReaderDir = new G4UIdirectory("/action/IAEAphspReader/");
fIAEAphspReaderDir->SetGuidance("Commands to set IAEAphsp reader object.");
fIAEAphspWriterDir = new G4UIdirectory("/action/IAEAphspWriter/");
fIAEAphspWriterDir->SetGuidance("Commands to set IAEAphsp writer object.");
fIAEAphspReaderFileCmd =
new G4UIcmdWithAString("/action/IAEAphspReader/fileName",this);
fIAEAphspReaderFileCmd
->SetGuidance("Set IAEAphsp source file name, including path if needed.");
fIAEAphspReaderFileCmd
->SetGuidance("(.IAEAphsp or .IAEAheader extension must not be written)");
fIAEAphspReaderFileCmd->SetParameterName("name",false);
fIAEAphspReaderFileCmd->AvailableForStates(G4State_PreInit);
fIAEAphspWriterFileCmd =
new G4UIcmdWithAString("/action/IAEAphspWriter/namePrefix",this);
fIAEAphspWriterFileCmd
->SetGuidance("Set the name prefix of IAEAphsp output files, ");
fIAEAphspWriterFileCmd
->SetGuidance("including path if needed.");
fIAEAphspWriterFileCmd
->SetGuidance("Name pattern: \"prefix_zphsp[_runID].IAEA[phsp|header]\".");
fIAEAphspWriterFileCmd->SetGuidance("NOTE:");
fIAEAphspWriterFileCmd
->SetGuidance("At least ONE zphsp value must be issued.");
fIAEAphspWriterFileCmd->SetParameterName("prefix",false);
fIAEAphspWriterFileCmd->AvailableForStates(G4State_PreInit);
fIAEAphspWriterZphspCmd =
new G4UIcmdWithADoubleAndUnit("/action/IAEAphspWriter/zphsp", this);
fIAEAphspWriterZphspCmd
->SetGuidance("Add z-coordinate of output phsp plane.");
fIAEAphspWriterZphspCmd
->SetGuidance("At least one value is NEEDED to get this writer working.");
fIAEAphspWriterZphspCmd->SetParameterName("zphsp",false);
fIAEAphspWriterZphspCmd->SetDefaultUnit("cm");
fIAEAphspWriterZphspCmd->SetUnitCandidates("cm mm m");
fIAEAphspWriterZphspCmd->AvailableForStates(G4State_PreInit);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
ActionInitializationMessenger::~ActionInitializationMessenger()
{
delete fActionDir;
delete fIAEAphspReaderDir;
delete fIAEAphspWriterDir;
delete fIAEAphspReaderFileCmd;
delete fIAEAphspWriterFileCmd;
delete fIAEAphspWriterZphspCmd;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void ActionInitializationMessenger::SetNewValue(G4UIcommand* command,
G4String newValue)
{
if ( command == fIAEAphspReaderFileCmd )
fAction->SetIAEAphspReader(newValue);
else if ( command == fIAEAphspWriterFileCmd )
fAction->SetIAEAphspWriterPrefix(newValue);
else if ( command == fIAEAphspWriterZphspCmd )
fAction->AddZphsp(fIAEAphspWriterZphspCmd->GetNewDoubleValue(newValue));
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -0,0 +1,117 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "DetectorConstruction.hh"
#include "DetectorMessenger.hh"
#include "globals.hh"
#include "G4SystemOfUnits.hh"
#include "G4Box.hh"
#include "G4LogicalVolume.hh"
#include "G4VPhysicalVolume.hh"
#include "G4PVPlacement.hh"
#include "G4Material.hh"
#include "G4NistManager.hh"
#include "G4GeometryManager.hh"
#include "G4PhysicalVolumeStore.hh"
#include "G4LogicalVolumeStore.hh"
#include "G4SolidStore.hh"
#include "G4VisAttributes.hh"
#include "G4Colour.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorConstruction::DetectorConstruction()
{
G4NistManager* man = G4NistManager::Instance();
//man->SetVerbose(1);
fMessenger = new DetectorMessenger(this);
fWorldMat = man->FindOrBuildMaterial("G4_Galactic");
fWorldXY = 50.*cm;
fWorldZ = 100.*cm;
G4cout << *(G4Material::GetMaterialTable()) << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorConstruction::~DetectorConstruction()
{
delete fMessenger;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4VPhysicalVolume* DetectorConstruction::Construct()
{
DumpGeometryParameters();
G4GeometryManager::GetInstance()->OpenGeometry();
G4PhysicalVolumeStore::GetInstance()->Clean();
G4LogicalVolumeStore::GetInstance()->Clean();
G4SolidStore::GetInstance()->Clean();
//
// World
//
G4Box* sWorld = new G4Box("World",
fWorldXY, fWorldXY, fWorldZ);
G4LogicalVolume* lWorld = new G4LogicalVolume(sWorld,
fWorldMat, "World");
G4VPhysicalVolume* phWorld = new G4PVPlacement(0, G4ThreeVector(),
"World", lWorld,
0, false, 0);
//
// Visualization attributes
//
auto visAtt = new G4VisAttributes(G4Colour(0.1,0.5,1.0));
visAtt->SetVisibility(true);
lWorld->SetVisAttributes(visAtt);
return phWorld;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::DumpGeometryParameters()
{
G4cout << "\n===================================================" << G4endl;
G4cout << "# IAEAphsp Geometry #" << G4endl;
G4cout << "===================================================" << G4endl;
G4cout << " WorldXY = " << fWorldXY/cm << " cm " << G4endl;
G4cout << " WorldZ = " << fWorldZ/cm << " cm " << G4endl;
G4cout << " WorldMat: " << fWorldMat->GetName() << G4endl;
G4cout << "===================================================\n" << G4endl;
}
@@ -0,0 +1,76 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
#include "G4UIdirectory.hh"
#include "G4UIcmdWithADoubleAndUnit.hh"
#include "DetectorMessenger.hh"
#include "DetectorConstruction.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
DetectorMessenger::DetectorMessenger(DetectorConstruction* geom)
: fGeom(geom)
{
fGeomDir = new G4UIdirectory("/my_geom/");
fGeomDir->SetGuidance("Commands to set the geometry");
fWorldXYCmd = new G4UIcmdWithADoubleAndUnit("/my_geom/worldXY",this);
fWorldXYCmd->SetGuidance("Set XY half-length of the world volume.");
fWorldXYCmd->SetParameterName("worldXY",true);
fWorldXYCmd->SetUnitCategory("Length");
fWorldXYCmd->AvailableForStates(G4State_PreInit, G4State_Idle);
fWorldZCmd = new G4UIcmdWithADoubleAndUnit("/my_geom/worldZ",this);
fWorldZCmd->SetGuidance("Set Z half-length of the world volume.");
fWorldZCmd->SetParameterName("worldZ",true);
fWorldZCmd->SetUnitCategory("Length");
fWorldZCmd->AvailableForStates(G4State_PreInit, G4State_Idle);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
DetectorMessenger::~DetectorMessenger()
{
delete fGeomDir;
delete fWorldXYCmd;
delete fWorldZCmd;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void DetectorMessenger::SetNewValue(G4UIcommand* command, G4String newValue)
{
if (command == fWorldXYCmd)
fGeom->SetWorldXY(fWorldXYCmd->GetNewDoubleValue(newValue));
else if (command == fWorldZCmd)
fGeom->SetWorldZ(fWorldZCmd->GetNewDoubleValue(newValue));
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,299 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// Author: M.A. Cortes-Giraldo, Universidad de Sevilla
//
// History changelog prior creation of this example:
// - 17/10/2009: version 1.0
// - 20/11/2009: version 1.1 before publishing:
// - Changed some names by more suitable ones
// - 02/08/2010: version 1.2-dev:
// - Added possibility of applying axial symmetries
// - 14/09/2023: version 2.0
// - Following Geant4 coding guidelines
// - 18/10/2025: version 3.0
// - Creation of IAEASourceIdRegistry for thread-safe source_id assignation
//
#include "G4IAEAphspReaderMessenger.hh"
#include "G4IAEAphspReader.hh"
#include "G4UIcmdWith3Vector.hh"
#include "G4UIcmdWith3VectorAndUnit.hh"
#include "G4UIcmdWithABool.hh"
#include "G4UIcmdWithADoubleAndUnit.hh"
#include "G4UIcmdWithAnInteger.hh"
#include "G4UIdirectory.hh"
G4IAEAphspReaderMessenger::G4IAEAphspReaderMessenger(G4IAEAphspReader* reader)
:fIAEAphspReader(reader)
{
fPhaseSpaceDir = new G4UIdirectory("/IAEAphspReader/");
fPhaseSpaceDir
->SetGuidance("Commands for the IAEA phase-space file management.");
fVerboseCmd = new G4UIcmdWithAnInteger("/IAEAphspReader/verbose", this);
fVerboseCmd->SetGuidance("Set verbose level of G4IAEAphspReader class");
fVerboseCmd->SetParameterName("value", false);
fVerboseCmd->SetRange("value >= 0");
fVerboseCmd->AvailableForStates(G4State_Idle);
fNofParallelRunsCmd =
new G4UIcmdWithAnInteger("/IAEAphspReader/numberOfParallelRuns", this);
fNofParallelRunsCmd
->SetGuidance("Select the number of fragments N in which the phase-space");
fNofParallelRunsCmd
->SetGuidance(" file is divided into.");
fNofParallelRunsCmd->SetParameterName("N", false);
fNofParallelRunsCmd->SetRange("N > 0");
fNofParallelRunsCmd->AvailableForStates(G4State_Idle);
fParallelRunCmd =
new G4UIcmdWithAnInteger("/IAEAphspReader/parallelRun", this);
fParallelRunCmd->
SetGuidance("Use the fragment F (of a total of N) from which particles");
fParallelRunCmd->SetGuidance(" are extracted. (1 <= F <= N).");
fParallelRunCmd->SetParameterName("frag", false);
fParallelRunCmd->SetRange("frag > 0");
fParallelRunCmd->AvailableForStates(G4State_Idle);
fTimesRecycledCmd =
new G4UIcmdWithAnInteger("/IAEAphspReader/recycling", this);
fTimesRecycledCmd
->SetGuidance("Select the number of times that each particle is reused.");
fTimesRecycledCmd
->SetGuidance("(Caution: 1 means that each particle is used twice.)");
fTimesRecycledCmd->SetParameterName("choice", false);
fTimesRecycledCmd->SetRange("choice >= 0");
fTimesRecycledCmd->AvailableForStates(G4State_Idle);
fPhspGlobalTranslationCmd =
new G4UIcmdWith3VectorAndUnit("/IAEAphspReader/translate", this);
fPhspGlobalTranslationCmd->SetGuidance("Set the translation components.");
fPhspGlobalTranslationCmd->SetParameterName("x0", "y0", "z0", false);
fPhspGlobalTranslationCmd->SetDefaultUnit("cm");
fPhspGlobalTranslationCmd->SetUnitCandidates("mm cm m");
fPhspGlobalTranslationCmd->AvailableForStates(G4State_Idle);
fPhspRotationOrderCmd =
new G4UIcmdWithAnInteger("/IAEAphspReader/rotationOrder", this);
fPhspRotationOrderCmd
->SetGuidance("Select the order in which the rotations are performed.");
fPhspRotationOrderCmd
->SetGuidance("1 means X axis, 2 means Y axis and 3 means Z axis.");
fPhspRotationOrderCmd
->SetGuidance("The argument must be a 3-digit integer without repetition.");
fPhspRotationOrderCmd->SetParameterName("choice", false);
fPhspRotationOrderCmd->AvailableForStates(G4State_Idle);
fRotXCmd = new G4UIcmdWithADoubleAndUnit("/IAEAphspReader/rotateX", this);
fRotXCmd->SetGuidance("Set the rotation angle around the global X axis.");
fRotXCmd->SetParameterName("angle", false);
fRotXCmd->SetDefaultUnit("deg");
fRotXCmd->SetUnitCandidates("deg rad");
fRotXCmd->AvailableForStates(G4State_Idle);
fRotYCmd = new G4UIcmdWithADoubleAndUnit("/IAEAphspReader/rotateY", this);
fRotYCmd->SetGuidance("Set the rotation angle around the global Y axis.");
fRotYCmd->SetParameterName("angle", false);
fRotYCmd->SetDefaultUnit("deg");
fRotYCmd->SetUnitCandidates("deg rad");
fRotYCmd->AvailableForStates(G4State_Idle);
fRotZCmd = new G4UIcmdWithADoubleAndUnit("/IAEAphspReader/rotateZ", this);
fRotZCmd->SetGuidance("Set the rotation angle around the global Z axis.");
fRotZCmd->SetParameterName("angle", false);
fRotZCmd->SetDefaultUnit("deg");
fRotZCmd->SetUnitCandidates("deg rad");
fRotZCmd->AvailableForStates(G4State_Idle);
fIsocenterPosCmd =
new G4UIcmdWith3VectorAndUnit("/IAEAphspReader/isocenterPosition", this);
fIsocenterPosCmd->SetGuidance("Set the isocenter position.");
fIsocenterPosCmd->SetParameterName("Xic", "Yic", "Zic", false);
fIsocenterPosCmd->SetDefaultUnit("cm");
fIsocenterPosCmd->SetUnitCandidates("mm cm m");
fIsocenterPosCmd->AvailableForStates(G4State_Idle);
fCollimatorRotAxisCmd =
new G4UIcmdWith3Vector("/IAEAphspReader/collimatorRotationAxis", this);
fCollimatorRotAxisCmd
->SetGuidance("Set the rotation axis of the collimator.");
fCollimatorRotAxisCmd->SetGuidance("It has to be a unit vector.");
fCollimatorRotAxisCmd->SetParameterName("Ucol", "Vcol", "Wcol", false);
fCollimatorRotAxisCmd->SetRange("Ucol != 0 || Vcol != 0 || Wcol != 0");
fCollimatorRotAxisCmd->AvailableForStates(G4State_Idle);
fCollimatorAngleCmd =
new G4UIcmdWithADoubleAndUnit("/IAEAphspReader/collimatorAngle", this);
fCollimatorAngleCmd
->SetGuidance("Set the rotation angle of the phase space plane around ");
fCollimatorAngleCmd
->SetGuidance("the rotation axis of the collimator.");
fCollimatorAngleCmd->SetParameterName("angle", false);
fCollimatorAngleCmd->SetDefaultUnit("deg");
fCollimatorAngleCmd->SetUnitCandidates("deg rad");
fCollimatorAngleCmd->AvailableForStates(G4State_Idle);
fGantryRotAxisCmd =
new G4UIcmdWith3Vector("/IAEAphspReader/gantryRotationAxis", this);
fGantryRotAxisCmd->SetGuidance("Set the rotation axis of the gantry.");
fGantryRotAxisCmd->SetGuidance("It has to be a unit vector.");
fGantryRotAxisCmd->SetParameterName("Ugan", "Vgan", "Wgan", false);
fGantryRotAxisCmd->SetRange("Ugan != 0 || Vgan != 0 || Wgan != 0");
fGantryRotAxisCmd->AvailableForStates(G4State_Idle);
fGantryAngleCmd =
new G4UIcmdWithADoubleAndUnit("/IAEAphspReader/gantryAngle", this);
fGantryAngleCmd
->SetGuidance("Set the rotation angle of the phase space plane around ");
fGantryAngleCmd
->SetGuidance("the gantry rotation axis.");
fGantryAngleCmd->SetParameterName("angle", false);
fGantryAngleCmd->SetDefaultUnit("deg");
fGantryAngleCmd->SetUnitCandidates("deg rad");
fGantryAngleCmd->AvailableForStates(G4State_Idle);
fAxialSymmetryXCmd =
new G4UIcmdWithABool("/IAEAphspReader/axialSymmetryX", this);
fAxialSymmetryXCmd
->SetGuidance("Command to take into account rotational symmetry around X");
fAxialSymmetryXCmd->SetParameterName("choice", true);
fAxialSymmetryXCmd->SetDefaultValue(true);
fAxialSymmetryXCmd->AvailableForStates(G4State_Idle);
fAxialSymmetryYCmd =
new G4UIcmdWithABool("/IAEAphspReader/axialSymmetryY", this);
fAxialSymmetryYCmd
->SetGuidance("Command to take into account rotational symmetry around Y");
fAxialSymmetryYCmd->SetParameterName("choice", true);
fAxialSymmetryYCmd->SetDefaultValue(true);
fAxialSymmetryYCmd->AvailableForStates(G4State_Idle);
fAxialSymmetryZCmd =
new G4UIcmdWithABool("/IAEAphspReader/axialSymmetryZ", this);
fAxialSymmetryZCmd
->SetGuidance("Command to take into account rotational symmetry around Z");
fAxialSymmetryZCmd->SetParameterName("choice", true);
fAxialSymmetryZCmd->SetDefaultValue(true);
fAxialSymmetryZCmd->AvailableForStates(G4State_Idle);
}
G4IAEAphspReaderMessenger::~G4IAEAphspReaderMessenger()
{
delete fPhaseSpaceDir;
delete fVerboseCmd;
delete fNofParallelRunsCmd;
delete fParallelRunCmd;
delete fTimesRecycledCmd;
delete fPhspGlobalTranslationCmd;
delete fPhspRotationOrderCmd;
delete fRotXCmd;
delete fRotYCmd;
delete fRotZCmd;
delete fIsocenterPosCmd;
delete fCollimatorRotAxisCmd;
delete fCollimatorAngleCmd;
delete fGantryRotAxisCmd;
delete fGantryAngleCmd;
delete fAxialSymmetryXCmd;
delete fAxialSymmetryYCmd;
delete fAxialSymmetryZCmd;
}
void G4IAEAphspReaderMessenger::SetNewValue(G4UIcommand* command,
G4String newValue)
{
if( command == fVerboseCmd )
fIAEAphspReader->SetVerbose(fVerboseCmd->GetNewIntValue(newValue));
else if( command == fNofParallelRunsCmd )
fIAEAphspReader
->SetTotalParallelRuns(fNofParallelRunsCmd->GetNewIntValue(newValue));
else if( command == fParallelRunCmd )
fIAEAphspReader->SetParallelRun(fParallelRunCmd->GetNewIntValue(newValue));
else if( command == fTimesRecycledCmd )
fIAEAphspReader
->SetTimesRecycled(fTimesRecycledCmd->GetNewIntValue(newValue) );
else if( command == fPhspGlobalTranslationCmd )
fIAEAphspReader
->SetGlobalPhspTranslation(fPhspGlobalTranslationCmd
->GetNew3VectorValue(newValue) );
else if( command == fPhspRotationOrderCmd )
fIAEAphspReader
->SetTimesRecycled(fPhspRotationOrderCmd->GetNewIntValue(newValue) );
else if( command == fRotXCmd )
fIAEAphspReader->SetRotationX( fRotXCmd->GetNewDoubleValue(newValue) );
else if( command == fRotYCmd )
fIAEAphspReader->SetRotationY( fRotYCmd->GetNewDoubleValue(newValue) );
else if( command == fRotZCmd )
fIAEAphspReader->SetRotationZ( fRotZCmd->GetNewDoubleValue(newValue) );
else if( command == fIsocenterPosCmd )
fIAEAphspReader
->SetIsocenterPosition(fIsocenterPosCmd->GetNew3VectorValue(newValue));
else if( command == fCollimatorRotAxisCmd )
fIAEAphspReader
->SetCollimatorRotationAxis(fCollimatorRotAxisCmd
->GetNew3VectorValue(newValue) );
else if( command == fCollimatorAngleCmd )
fIAEAphspReader
->SetCollimatorAngle(fCollimatorAngleCmd->GetNewDoubleValue(newValue));
else if( command == fGantryRotAxisCmd )
fIAEAphspReader
->SetGantryRotationAxis(fGantryRotAxisCmd->GetNew3VectorValue(newValue));
else if( command == fGantryAngleCmd )
fIAEAphspReader
->SetGantryAngle( fGantryAngleCmd->GetNewDoubleValue(newValue) );
else if( command == fAxialSymmetryXCmd )
fIAEAphspReader
->SetAxialSymmetryX( fAxialSymmetryXCmd->GetNewBoolValue(newValue));
else if( command == fAxialSymmetryYCmd )
fIAEAphspReader
->SetAxialSymmetryY( fAxialSymmetryYCmd->GetNewBoolValue(newValue) );
else if( command == fAxialSymmetryZCmd )
fIAEAphspReader
->SetAxialSymmetryZ( fAxialSymmetryZCmd->GetNewBoolValue(newValue) );
}
@@ -0,0 +1,435 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// Author: M.A. Cortes-Giraldo, Universidad de Sevilla
//
// History changelog prior creation of this example:
// - 17/10/2009: inheritance removed (not needed)
// - 17/10/2009: version 1.0
// - 07/10/2024: version 2.0 for Geant4 example (MT compliant)
// - 18/10/2025: version 3.0
// - Creation of IAEASourceIdRegistry for thread-safe source_id assignation
//
#include "G4IAEAphspWriter.hh"
#include "globals.hh"
#include "G4SystemOfUnits.hh"
#include "G4Run.hh"
#include "G4Step.hh"
#include "G4Track.hh"
#include "iaea_phsp.h"
#include "IAEASourceIdRegistry.hh"
#include "G4IAEAphspWriterStack.hh"
#include <map>
#include <sstream>
#include <vector>
//==============================================================================
G4IAEAphspWriter::G4IAEAphspWriter(const G4String filename)
{
fFileName = filename;
fZphspVec = new std::vector<G4double>;
fConstVariables = new std::map<G4int, G4double>;
fOrigHistories = new std::vector<G4int>;
fIAEASourcesOpen = 0;
G4cout << "G4IAEAphspWriter object constructed." << G4endl;
}
G4IAEAphspWriter::~G4IAEAphspWriter()
{
if (fZphspVec) delete fZphspVec;
if (fConstVariables) delete fConstVariables;
if (fOrigHistories) delete fOrigHistories;
}
//==============================================================================
void G4IAEAphspWriter::AddZphsp(const G4double zphsp)
{
fZphspVec->push_back(zphsp);
G4cout << "G4IAEAphspWriter: Registered phase-space plane at z = "
<< zphsp/cm << " cm." << G4endl;
// fOrigHistories must incorporate a new element (equal size as fZphspVec)
fOrigHistories->push_back(0);
}
//==============================================================================
void G4IAEAphspWriter::SetDataFromIAEAStack(const G4IAEAphspWriterStack* stack)
{
if (!stack) {
G4ExceptionDescription msg;
msg << "No G4IAEAphspWriterStack has been constructed!" << G4endl;
G4Exception("G4IAEAphspWriter::SetDataFromIAEAStack()",
"IAEAphspWriter001", FatalException, msg );
return;
}
else {
fFileName = stack->GetFileName();
if (stack->GetZphspVec()->size() > 0) {
(*fZphspVec) = *(stack->GetZphspVec()); // copy objects, not pointers
G4cout << "G4IAEAphspWriter::fFileName = " << fFileName << G4endl;
G4cout << "G4IAEAphspWriter::fZphspVec->size() = "
<< fZphspVec->size() << G4endl;
// fOrigHistories must have as many element as fZphspVec
fOrigHistories->assign(fZphspVec->size(), 0);
}
else {
G4ExceptionDescription msg;
msg << "No phsp plane z-coordinate has been defined!" << G4endl;
G4Exception("G4IAEAphspWriter::SetDataFromIAEAStack()",
"IAEAphspWriter002", FatalErrorInArgument, msg );
return;
}
}
}
//==============================================================================
void G4IAEAphspWriter::SetConstVariable(const G4int idx, const G4double val)
{
if (idx < 0 || idx > 6) {
G4cout << "No constant variable applies for index " << idx
<< ". Doing nothing." << G4endl;
return;
}
fConstVariables->insert( std::pair<G4int, G4double>(idx, val) );
switch (idx) {
case 0:
G4cout << "Variable 'x' set to constant value " << val << " cm" << G4endl;
break;
case 1:
G4cout << "Variable 'y' set to constant value " << val << " cm" << G4endl;
break;
case 2:
G4cout << "Variable 'z' set to constant value " << val << " cm" << G4endl;
break;
case 3:
G4cout << "Variable 'u' set to constant value " << val << G4endl;
break;
case 4:
G4cout << "Variable 'v' set to constant value " << val << G4endl;
break;
case 5:
G4cout << "Variable 'w' set to constant value " << val << G4endl;
break;
case 6:
G4cout << "Variable 'wt' set to constant value " << val << G4endl;
}
}
//==============================================================================
void G4IAEAphspWriter::WriteIAEAParticle(const size_t idx, const G4int incHist,
const G4int pdg, const G4double kinE,
const G4double wt,
const G4ThreeVector pos,
const G4ThreeVector momDir)
{
IAEA_I32 partType;
switch(pdg) {
case 22:
partType = 1; // gamma
break;
case 11:
partType = 2; // electron
break;
case -11:
partType = 3; // positron
break;
case 2112:
partType = 4; // neutron
break;
case 2212:
partType = 5; // proton
break;
default:
G4ExceptionDescription msg;
msg << "PDG " << pdg
<< " is not supported by IAEAphsp format and will not be recorded."
<< G4endl;
G4Exception("G4IAEAphspWriter::WriteIAEAParticle()",
"IAEAphspWriter003", JustWarning, msg);
return;
}
IAEA_I32 sourceID = static_cast<IAEA_I32>(idx+fIAEASourcesOpen);
IAEA_I32 nStat = static_cast<IAEA_I32>(incHist);
IAEA_Float energy = static_cast<IAEA_Float>(kinE/MeV);
IAEA_Float weight = static_cast<IAEA_Float>(wt);
IAEA_Float x = static_cast<IAEA_Float>( pos.x()/cm );
IAEA_Float y = static_cast<IAEA_Float>( pos.y()/cm );
IAEA_Float z = static_cast<IAEA_Float>( pos.z()/cm );
IAEA_Float u = static_cast<IAEA_Float>( momDir.x() );
IAEA_Float v = static_cast<IAEA_Float>( momDir.y() );
IAEA_Float w = static_cast<IAEA_Float>( momDir.z() );
// Extra variables
IAEA_Float extraFloat = -1; // no extra floats stored
IAEA_I32 extraInt = nStat;
// And finally store the particle following the IAEA routines
iaea_write_particle(&sourceID, &nStat, &partType,
&energy, &weight,
&x, &y, &z, &u, &v, &w, &extraFloat, &extraInt);
}
//==============================================================================
void G4IAEAphspWriter::WriteIAEAParticle(const G4Step* aStep,
const G4int zStopIdx)
{
IAEA_I32 sourceID =
static_cast<IAEA_I32>(zStopIdx+fIAEASourcesOpen); // beware
G4double zStop = (*fZphspVec)[zStopIdx];
// The particle type and kinetic energy
// -------------------------------------
const G4Track* aTrack = aStep->GetTrack();
G4int PDGCode = aTrack->GetDefinition()->GetPDGEncoding();
IAEA_I32 partType;
G4double postE = aStep->GetPostStepPoint()->GetKineticEnergy();
G4double preE = aStep->GetPreStepPoint()->GetKineticEnergy();
IAEA_Float kinEnergyMeV;
G4ThreeVector postR = aStep->GetPostStepPoint()->GetPosition();
G4ThreeVector preR = aStep->GetPreStepPoint()->GetPosition();
G4double postZ = postR.z();
G4double preZ = preR.z();
switch(PDGCode) {
case 22:
partType = 1; // gamma
kinEnergyMeV = static_cast<IAEA_Float>(preE/MeV);
break;
case 11:
partType = 2; // electron
kinEnergyMeV =
static_cast<IAEA_Float>( (preE+
(postE-preE)*(zStop-preZ)/(postZ-preZ))/MeV );
break;
case -11:
partType = 3; // positron
kinEnergyMeV =
static_cast<IAEA_Float>( (preE+
(postE-preE)*(zStop-preZ)/(postZ-preZ))/MeV );
break;
case 2112:
partType = 4; // neutron
kinEnergyMeV = static_cast<IAEA_Float>(preE/MeV);
break;
case 2212:
partType = 5; // proton
kinEnergyMeV =
static_cast<IAEA_Float>( (preE+
(postE-preE)*(zStop-preZ)/(postZ-preZ))/MeV );
break;
default:
G4String pname = aTrack->GetDefinition()->GetParticleName();
G4String errmsg = "'" + pname + "' is not supported by IAEAphsp format"
+ " and will not be recorded.";
G4Exception("G4IAEAphspWriter::WriteIAEAParticle()",
"IAEAphspWriter004", JustWarning, errmsg.c_str() );
return;
}
// Track weight
IAEA_Float wt = static_cast<IAEA_Float>(aTrack->GetWeight());
// Position
G4double postX = postR.x();
G4double preX = preR.x();
G4double postY = postR.y();
G4double preY = preR.y();
IAEA_Float x =
static_cast<IAEA_Float>( (preX+
(postX-preX)*(zStop-preZ)/(postZ-preZ))/cm );
IAEA_Float y =
static_cast<IAEA_Float>( (preY+
(postY-preY)*(zStop-preZ)/(postZ-preZ))/cm );
IAEA_Float z =
static_cast<IAEA_Float>( zStop/cm );
// Momentum direction
G4ThreeVector momDir = aStep->GetPreStepPoint()->GetMomentumDirection();
IAEA_Float u = static_cast<IAEA_Float>(momDir.x());
IAEA_Float v = static_cast<IAEA_Float>(momDir.y());
IAEA_Float w = static_cast<IAEA_Float>(momDir.z());
// Extra variables
IAEA_Float extraFloat = -1; // no extra floats stored
// IAEA_I32 extraInt = static_cast<IAEA_I32>((*fIncrNumberVector)[zStopIdx]);
// IAEA_I32 nStat = extraInt;
IAEA_I32 extraInt = -1;
IAEA_I32 nStat = 0; //MACG Admitted values, this MUST change
// And finally store the particle following the IAEA routines
iaea_write_particle(&sourceID, &nStat, &partType,
&kinEnergyMeV, &wt,
&x, &y, &z, &u, &v, &w, &extraFloat, &extraInt);
}
//==============================================================================
void G4IAEAphspWriter::OpenIAEAphspOutFiles(const G4Run* aRun)
{
// Open all the files intended to store
// the phase spaces following the IAEA format.
const IAEA_I32 accessWrite = 2; // 2 = Writing mode in IAEA routines
size_t nZphsps = fZphspVec->size();
for (size_t ii = 0; ii < nZphsps; ii++) {
// Set the source ID and file name in a unique way
std::stringstream sstr;
sstr << ((*fZphspVec)[ii]/cm);
G4String zphsp(sstr.str());
G4String fullName = fFileName + "_" + zphsp + "cm";
// This part is only added when running several runs
// during the simulation.
G4int runID = aRun->GetRunID();
if (runID > 0) {
std::stringstream sstr2;
sstr2 << runID;
G4String runIDStr(sstr2.str());
fullName += "_";
fullName += runIDStr;
}
// Create the file to store the IAEA phase space
// Reserve a global ID and request it explicitly
G4int reserved = IAEASourceIdRegistry::Instance().ReserveNextLowest();
if (reserved < 0) {
G4ExceptionDescription ed;
ed << "No free IAEA source IDs available for writer" << G4endl;
G4Exception("G4IAEAphspWriter::OpenIAEAphspOutFiles",
"IAEAphspWriter005",FatalException, ed);
}
IAEA_I32 sourceWrite = static_cast<IAEA_I32>(reserved);
char* filename = const_cast<char*>(fullName.data());
IAEA_I32 result = 0;
iaea_new_source( &sourceWrite, filename, &accessWrite,
&result, fullName.size()+1 );
if (result < 0 || sourceWrite < 0) {
IAEASourceIdRegistry::Instance().Release(reserved);
G4ExceptionDescription ed;
ed << "IAEAphsp output file opening operation failed!" << G4endl;
G4Exception("G4IAEAphspWriter::OpenIAEAphspOutFiles()",
"IAEAphspWriter006", FatalException, ed);
}
// This difference tells about the number of IAEA files already open.
fIAEASourcesOpen = sourceWrite - ii;
G4cout << "G4IAEAphspWriter::OpenOutputIAEAphspFiles() ==> "
<< "\"" << fullName << "\" IAEAphsp id = " << sourceWrite << "."
<< G4endl;
// Set the global information and options.
// Set constant variables
std::map<G4int, G4double>::iterator itmap;
for (itmap = fConstVariables->begin();
itmap != fConstVariables->end(); itmap++) {
IAEA_I32 varIdx = static_cast<IAEA_I32>( (*itmap).first );
IAEA_Float varValue = static_cast<IAEA_I32>( (*itmap).second );
iaea_set_constant_variable(&sourceWrite, &varIdx, &varValue);
}
//MACG
// Set constant Z
// IAEA_I32 varIdx = 2; // 0=x, 1=y, 2=z, 3=u, 4=v, 5=w, 6=wt
// IAEA_Float varValue = static_cast<IAEA_Float>((*fZphspVec)[ii]/cm);
// iaea_set_constant_variable(&sourceWrite, &varIdx, &varValue);
// Extra variables
IAEA_I32 extraFloats = 0;
IAEA_I32 extraInts = 1;
iaea_set_extra_numbers(&sourceWrite, &extraFloats, &extraInts);
// Extra variables types
IAEA_I32 longIdx = 0;
IAEA_I32 longType = 1; // incremental history number
iaea_set_type_extralong_variable(&sourceWrite, &longIdx, &longType);
}
}
//==============================================================================
void G4IAEAphspWriter::CloseIAEAphspOutFiles()
{
// Close the IAEA files
G4int nZphsps = fZphspVec->size();
for (G4int ii = 0; ii < nZphsps; ii++) {
const IAEA_I32 sourceID = static_cast<IAEA_I32>(ii+fIAEASourcesOpen);
IAEA_I64 nEvts = static_cast<IAEA_I64>( fOrigHistories->at(ii) );
iaea_set_total_original_particles(&sourceID, &nEvts);
IAEA_I32 result = 0;
iaea_print_header(&sourceID, &result);
if (result < 0) {
G4Exception("G4IAEAphspWriter::EndOfRunAction()",
"IAEAphspWriter007", JustWarning,
"IAEA phsp source not found");
}
iaea_destroy_source(&sourceID, &result);
if (result > 0) {
IAEASourceIdRegistry::Instance().Release(static_cast<G4int>(sourceID));
G4cout << "Phase-space file at z_phsp = " << (*fZphspVec)[ii]/cm
<< " cm (IAEA source id #" << sourceID << ") closed successfully!"
<< G4endl << G4endl;
}
else {
G4Exception("G4IAEAphspWriter::EndOfRunAction()",
"IAEAphspWriter008", JustWarning,
"IAEA file not closed properly");
}
}
}
@@ -0,0 +1,331 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// Author: M.A. Cortes-Giraldo
//
// 2025-08-27: Its objects work in local runs, their mission is to store the
// info of the particles to be written in the IAEAphsp output files at
// the end of the run. In other words, they constitute a stack for
// IAEAphsp particles until the run finishes, when the IAEAphsp file is
// actually written.
//
#include "G4IAEAphspWriterStack.hh"
#include "globals.hh"
#include "G4SystemOfUnits.hh"
#include "G4ThreeVector.hh"
#include "G4Step.hh"
#include "G4IAEAphspWriter.hh"
#include <set>
#include <vector>
//==============================================================================
G4IAEAphspWriterStack::G4IAEAphspWriterStack(const G4String filename)
{
fFileName = filename;
fZphspVec = new std::vector<G4double>;
fIncrNumberVec = new std::vector<G4int>;
fPassingTracksVec = new std::vector< std::set<G4int>* >;
fPDGMtrx = new std::vector< std::vector<G4int>* >;
fPosMtrx = new std::vector< std::vector<G4ThreeVector>* >;
fMomMtrx = new std::vector< std::vector<G4ThreeVector>* >;
fEneMtrx = new std::vector< std::vector<G4double>* >;
fWtMtrx = new std::vector< std::vector<G4double>* >;
fNstatMtrx = new std::vector< std::vector<G4int>* >;
G4cout << "G4IAEAphspWriterStack object constructed for files \""
<< fFileName << "_<zphsp>cm.IAEA*\"" << G4endl;
}
//==============================================================================
G4IAEAphspWriterStack::~G4IAEAphspWriterStack()
{
if (fZphspVec) delete fZphspVec;
if (fIncrNumberVec) delete fIncrNumberVec;
if (fPassingTracksVec) delete fPassingTracksVec;
if (fPDGMtrx) delete fPDGMtrx;
if (fPosMtrx) delete fPosMtrx;
if (fMomMtrx) delete fMomMtrx;
if (fEneMtrx) delete fEneMtrx;
if (fWtMtrx) delete fWtMtrx;
if (fNstatMtrx) delete fNstatMtrx;
}
//==============================================================================
void G4IAEAphspWriterStack::AddZphsp(const G4double zphsp)
{
fZphspVec->push_back(zphsp);
G4cout << "G4IAEAphspWriterStack: Registered phase-space plane at z = "
<< zphsp/cm << " cm." << G4endl;
}
//==============================================================================
void G4IAEAphspWriterStack::ClearZphspVec()
{
G4cout << "G4IAEAphspWriterStack: Removing all registered phase-space planes!"
<< G4endl;
fZphspVec->clear();
}
//==============================================================================
void G4IAEAphspWriterStack::SetDataFromWriter(const G4IAEAphspWriter* writer)
{
if (!writer) {
G4ExceptionDescription msg;
msg << "No G4IAEAphspWriter has been constructed!" << G4endl;
G4Exception("G4IAEAphspWriterStack::SetDataFromWriter()",
"IAEAphspWriterStack001", FatalException, msg );
return;
}
else {
fFileName = writer->GetFileName();
if (writer->GetZphspVec()->size() > 0) {
(*fZphspVec) = *(writer->GetZphspVec()); // copy objects, not pointers
G4cout << "G4IAEAphspWriterStack::fFileName = " << fFileName << G4endl;
G4cout << "G4IAEAphspWriterStack::fZphspVec->size() = "
<< fZphspVec->size() << G4endl;
}
else {
G4ExceptionDescription msg;
msg << "No phsp plane z-coordinate has been defined!" << G4endl;
G4Exception("G4IAEAphspWriterStack::SetDataFromWriter()",
"IAEAphspWriterStack002", FatalErrorInArgument, msg );
return;
}
}
}
//==============================================================================
void G4IAEAphspWriterStack::PrepareRun()
{
size_t nZphsps = fZphspVec->size();
fIncrNumberVec->reserve(nZphsps);
fPassingTracksVec->reserve(nZphsps);
fPDGMtrx->reserve(nZphsps);
fPosMtrx->reserve(nZphsps);
fMomMtrx->reserve(nZphsps);
fEneMtrx->reserve(nZphsps);
fWtMtrx->reserve(nZphsps);
fNstatMtrx->reserve(nZphsps);
for (size_t ii = 0; ii < nZphsps; ii++) {
fIncrNumberVec->push_back(0);
auto aSet = new std::set<G4int>;
fPassingTracksVec->push_back(aSet);
auto pdgVec = new std::vector<G4int>;
fPDGMtrx->push_back(pdgVec);
auto posVec = new std::vector<G4ThreeVector>;
fPosMtrx->push_back(posVec);
auto momVec = new std::vector<G4ThreeVector>;
fMomMtrx->push_back(momVec);
auto eneVec = new std::vector<G4double>;
fEneMtrx->push_back(eneVec);
auto wtVec = new std::vector<G4double>;
fWtMtrx->push_back(wtVec);
auto nstatVec = new std::vector<G4int>;
fNstatMtrx->push_back(nstatVec);
}
G4cout << "G4IAEAphspWriterStack::PrepareRun() done!" << G4endl;
}
//==============================================================================
void G4IAEAphspWriterStack::PrepareNextEvent()
{
// Update all the incremental history numbers.
for ( auto& ii : (*fIncrNumberVec) )
ii++;
// Remove the track ID's stored during this event.
for ( auto& trackIDs : (*fPassingTracksVec) )
trackIDs->clear();
// -- DEBUG!!
// G4cout << "G4IAEAphspWriterStack ready for the next event!" << G4endl;
}
//==============================================================================
void G4IAEAphspWriterStack::StoreParticleIfEligible(const G4Step* aStep)
{
const G4ThreeVector postR = aStep->GetPostStepPoint()->GetPosition();
const G4ThreeVector preR = aStep->GetPreStepPoint()->GetPosition();
const G4double postZ = postR.z();
const G4double preZ = preR.z();
// Check what phsp planes are being crossed
size_t phspIdx = 0;
for (const auto& phspZ : (*fZphspVec) ) {
if ( (postZ-phspZ)*(preZ-phspZ) < 0 ) {
// Get trackID and check if it is already in fPassingTracksVec[ii]
const G4int trackID = aStep->GetTrack()->GetTrackID();
std::set<G4int>::iterator is;
is = (*fPassingTracksVec)[phspIdx]->find(trackID);
if ( is == (*fPassingTracksVec)[phspIdx]->end() ) {
// This particle has not crossed this phsp plane before.
// Then, put it on the stack if it is of a type foreseen
// by the IAEAphsp format
const G4int pdgCode =
aStep->GetTrack()->GetDefinition()->GetPDGEncoding();
if (pdgCode == 22 || pdgCode == 11 || pdgCode == -11 ||
pdgCode == 2112 || pdgCode == 2212)
StoreIAEAParticle(aStep, phspIdx, pdgCode);
}
}
phspIdx++;
}
}
//==============================================================================
void G4IAEAphspWriterStack::StoreIAEAParticle(const G4Step* aStep,
const G4int phspIndex,
const G4int pdgCode)
{
const G4double zStop = (*fZphspVec)[phspIndex];
const G4Track* aTrack = aStep->GetTrack();
// Get step info
// --------------------------------
const G4ThreeVector postR = aStep->GetPostStepPoint()->GetPosition();
const G4ThreeVector preR = aStep->GetPreStepPoint()->GetPosition();
const G4double postZ = postR.z();
const G4double preZ = preR.z();
// Set kinetic energy
G4double kinEnergy;
if (pdgCode == 22 || pdgCode == 2112) { // gamma or neutron
kinEnergy = aStep->GetPreStepPoint()->GetKineticEnergy();
}
else if (pdgCode == 11 || pdgCode == -11 ||
pdgCode == 2212 ) { // electron, positron or proton
const G4double postE = aStep->GetPostStepPoint()->GetKineticEnergy();
const G4double preE = aStep->GetPreStepPoint()->GetKineticEnergy();
kinEnergy = preE + (postE-preE)*(zStop-preZ)/(postZ-preZ);
}
else { // not a particle for the IAEA format
G4ExceptionDescription ED;
ED << "\"" << aTrack->GetDefinition()->GetParticleName()
<< "\" is not supported by the IAEAphsp format; not recorded.";
G4Exception("G4IAEAphspWriterStack::StoreIAEAParticle()",
"IAEAphspWriterStack003", JustWarning, ED );
return;
}
// Position
const G4ThreeVector phspPos = preR + (postR-preR)*(zStop-preZ)/(postZ-preZ);
// Momentum direction
const G4ThreeVector phspMomDir =
aStep->GetPreStepPoint()->GetMomentumDirection();
// Track weight
const G4double wt = aTrack->GetWeight();
// n_stat value
const G4int nStat = (*fIncrNumberVec)[phspIndex];
// Store info in stacking vectors
// ------------------------------
((*fPDGMtrx)[phspIndex])->push_back(pdgCode);
((*fNstatMtrx)[phspIndex])->push_back(nStat);
((*fPosMtrx)[phspIndex])->push_back(phspPos);
((*fMomMtrx)[phspIndex])->push_back(phspMomDir);
((*fEneMtrx)[phspIndex])->push_back(kinEnergy);
((*fWtMtrx)[phspIndex])->push_back(wt);
// Once stored, reset the incremental history number (n_stat = 0)
(*fIncrNumberVec)[phspIndex] = 0;
// And now register this trackID to protect against multiple crossers
(*fPassingTracksVec)[phspIndex]->insert( aTrack->GetTrackID() );
// -- DEBUG!!
// G4cout << "G4IAEAphspWriterStack: Particle stored in phsp plane ["
// << phspIndex << "] at place #" << ((*fPDGMtrx)[phspIndex])->size()
// << " with the following values:" << G4endl;
// G4cout << "\tPDG = " << pdgCode << " nStat = " << nStat
// << " phspPos = " << phspPos << " phspMomDir = " << phspMomDir
// << " kinEnergy = " << kinEnergy << " weight = " << wt
// << G4endl;
}
//==============================================================================
void G4IAEAphspWriterStack::ClearRunVectors()
{
// Clear the run vectors at run termination
fIncrNumberVec->clear();
for (auto& trackIDs : (*fPassingTracksVec) ) delete trackIDs;
fPassingTracksVec->clear();
for (auto& pdgVec : (*fPDGMtrx) ) delete pdgVec;
fPDGMtrx->clear();
for (auto& posVec : (*fPosMtrx) ) delete posVec;
fPosMtrx->clear();
for (auto& momVec : (*fMomMtrx) ) delete momVec;
fMomMtrx->clear();
for (auto& eneVec : (*fEneMtrx) ) delete eneVec;
fEneMtrx->clear();
for (auto& wtVec : (*fWtMtrx) ) delete wtVec;
fWtMtrx->clear();
for (auto& nStatVec : (*fNstatMtrx) ) delete nStatVec;
fNstatMtrx->clear();
G4cout << "G4IAEAphspWriterStack run vectors cleaned!" << G4endl;
}
@@ -0,0 +1,210 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
#include "IAEAphspRun.hh"
#include "globals.hh"
#include "G4Event.hh"
#include "G4Run.hh"
#include <vector>
#include "G4IAEAphspWriter.hh"
#include "G4IAEAphspWriterStack.hh"
//==============================================================================
IAEAphspRun::IAEAphspRun()
:G4Run()
{
G4cout << "Creating default IAEAphspRun object" << G4endl;
}
//==============================================================================
IAEAphspRun::IAEAphspRun(G4IAEAphspWriterStack* iaeaStack)
:G4Run()
{
G4cout << "Creating IAEAphspRun object with IAEAphspWriterStack" << G4endl;
fIAEAphspWriterStack = iaeaStack;
fIAEAphspWriterStack->PrepareRun();
}
//==============================================================================
IAEAphspRun::~IAEAphspRun()
{
G4cout << "Destroying IAEAphspRun object" << G4endl;
if (fIAEAphspWriterStack)
fIAEAphspWriterStack->ClearRunVectors(); // deletion only in RunAction!
if (fIAEAphspWriter) delete fIAEAphspWriter;
}
//==============================================================================
// RecordEvent() is a method called at end of event after EndOfEventAction().
void IAEAphspRun::RecordEvent(const G4Event* aEvent)
{
G4Run::RecordEvent(aEvent); // Mandatory to increment 'numberOfEvent'
// G4cout << "IAEAphspRun: numberOfEvent = " << numberOfEvent << G4endl;
// G4cout << "Event ID = " << aEvent->GetEventID() << G4endl;
if (fIAEAphspWriterStack)
fIAEAphspWriterStack->PrepareNextEvent();
}
//==============================================================================
// Merge info from local IAEAphspRun object to the global IAEAphspRun object
void IAEAphspRun::Merge(const G4Run* aRun)
{
G4cout << "IAEAphspRun::Merge() started" << G4endl;
const IAEAphspRun* localRun = static_cast<const IAEAphspRun*>(aRun);
auto localPhspStack = localRun->GetIAEAphspWriterStack();
if (localPhspStack) { // only if we have IAEAphsp files
DumpToIAEAphspFiles(localPhspStack);
// Update the number of original histories to all files
const G4int histories = localRun->GetNumberOfEvent();
const size_t nPhsp = localPhspStack->GetZphspVec()->size();
for (size_t jj = 0; jj < nPhsp; jj++)
fIAEAphspWriter->SumOrigHistories(jj, histories);
}
G4Run::Merge(aRun);
}
//==============================================================================
// Dump info contained in local IAEAphspRun object into IAEAphsp files
void IAEAphspRun::DumpToIAEAphspFiles(const G4IAEAphspWriterStack* phspStack)
{
// Get info from vectors in G4IAEAphspWriterStack
if (phspStack) {
auto localPdgMtrx = phspStack->GetPDGMtrx();
auto localPosMtrx = phspStack->GetPosMtrx();
auto localMomMtrx = phspStack->GetMomMtrx();
auto localEneMtrx = phspStack->GetEneMtrx();
auto localWtMtrx = phspStack->GetWtMtrx();
auto localNstatMtrx = phspStack->GetNstatMtrx();
const size_t nPhsp = phspStack->GetZphspVec()->size();
// -- DEBUG!!
// G4cout << "IAEAphspRun: This run has " << nPhsp << " phsp planes stored."
// << G4endl;
if (nPhsp != localPdgMtrx->size() || nPhsp != localPosMtrx->size() ||
nPhsp != localMomMtrx->size() || nPhsp != localEneMtrx->size() ||
nPhsp != localWtMtrx->size() || nPhsp != localNstatMtrx->size() ) {
G4ExceptionDescription msg;
msg << "Number of zphsp stored != size of vectors storing phsp data."
<< " MERGING IGNORED!" << G4endl;
G4Exception("IAEAphspRun::DumpToIAEAphspFiles()",
"IAEAphspRun001", JustWarning, msg);
}
else {
size_t jj = 0; // phsp plane counter
for (const auto& phspPdgVec : *localPdgMtrx) {
size_t nPart = phspPdgVec->size(); // Get number of particles
// -- DEBUG!!
// G4cout << "\tPhsp #" << jj << " stores " << nPart << " particles"
// << G4endl;
if (nPart != (*localNstatMtrx)[jj]->size() ||
nPart != (*localPosMtrx)[jj]->size() ||
nPart != (*localMomMtrx)[jj]->size() ||
nPart != (*localEneMtrx)[jj]->size() ||
nPart != (*localWtMtrx)[jj]->size() ) {
G4ExceptionDescription msg;
msg << "Number of stored particles does not match in this "
<< "thread-local run for phps plane #" << jj
<< ". Merging ignored!" << G4endl;
G4Exception("IAEAphspRun::DumpToIAEAphspFiles()",
"IAEAphspRun002", JustWarning, msg);
}
else {
// Everything OK to dump particles into the IAEAphsp output files
// 1. If the G4IAEAphspWriter object was not created yet,
// create it, take data from G4IAEAphspWriterStack and open files
if (!fIAEAphspWriter) {
const G4String namePrefix = phspStack->GetFileName();
fIAEAphspWriter = new G4IAEAphspWriter(namePrefix);
fIAEAphspWriter->SetDataFromIAEAStack(phspStack);
fIAEAphspWriter->OpenIAEAphspOutFiles(this);
}
// 2. Loop over all vectors of this phsp to get the dynamic info
// and write it into the corresponding IAEAphsp file
size_t ii = 0;
for (const auto& pdg : *phspPdgVec) {
G4int nStat = (*(*localNstatMtrx)[jj])[ii];
G4double kinE = (*(*localEneMtrx)[jj])[ii];
G4double wt = (*(*localWtMtrx)[jj])[ii];
G4ThreeVector pos = (*(*localPosMtrx)[jj])[ii];
G4ThreeVector momDir = (*(*localMomMtrx)[jj])[ii];
fIAEAphspWriter->WriteIAEAParticle(jj, nStat, pdg, kinE, wt,
pos, momDir);
ii++;
// -- DEBUG!!
// G4cout << "\tPDG = " << pdg
// << " n_stat = " << (*(*localNstatMtrx)[jj])[ii]
// << " pos/cm = " << ((*(*localPosMtrx)[jj])[ii]) /cm
// << " momDir = " << (*(*localMomMtrx)[jj])[ii]
// << " kinE/MeV = " << ((*(*localEneMtrx)[jj])[ii]) /MeV
// << " wt = " << (*(*localWtMtrx)[jj])[ii] << G4endl;
}
}
jj++;
}
}
}
else {
G4ExceptionDescription msg;
msg << "This function is not meant to be called if no "
<< "G4IAEAphspWriterStack object has been defined."
<< G4endl;
G4Exception("IAEAphspRun::DumpToIAEAphspFiles()",
"IAEAphspRun003", FatalException, msg);
}
}
@@ -0,0 +1,156 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//----------------------------------------------------------------------------//
// This physics list *must* be set with a *reference* physics list.
// These provide a full set of models (both electromagnetic and hadronic).
//
// The reference physics list must be set by issuing its command in a macro
// file (see messenger class). No other action is required.
// Examples of physics list names: QGSP_BIC_HP_EMZ or QGSP_BERT_HP
//----------------------------------------------------------------------------//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "PhysicsList.hh"
#include "PhysicsListMessenger.hh"
#include "globals.hh"
#include "G4SystemOfUnits.hh"
#include "G4PhysListFactory.hh"
#include "G4VModularPhysicsList.hh"
#include "G4VPhysicsConstructor.hh"
#include "G4BosonConstructor.hh"
#include "G4LeptonConstructor.hh"
#include "G4MesonConstructor.hh"
#include "G4BaryonConstructor.hh"
#include "G4IonConstructor.hh"
#include "G4ShortLivedConstructor.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
PhysicsList::PhysicsList(): G4VModularPhysicsList()
{
SetDefaultCutValue(1.0*mm);
// This is to force setting the physics list with macro command
fPhysListIsSet = false;
fVerbose = 1;
fMessenger = new PhysicsListMessenger(this);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
PhysicsList::~PhysicsList()
{
delete fMessenger;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void PhysicsList::ConstructParticle()
{
if(fVerbose > 0) {
G4cout << "### PhysicsList Construct Particles" << G4endl;
}
// This method is invoked when the Geant4 application starts
// (do not mix with run initialization).
// (Taken from G4DecayPhysics)
G4BosonConstructor pBosonConstructor;
pBosonConstructor.ConstructParticle();
G4LeptonConstructor pLeptonConstructor;
pLeptonConstructor.ConstructParticle();
G4MesonConstructor pMesonConstructor;
pMesonConstructor.ConstructParticle();
G4BaryonConstructor pBaryonConstructor;
pBaryonConstructor.ConstructParticle();
G4IonConstructor pIonConstructor;
pIonConstructor.ConstructParticle();
G4ShortLivedConstructor pShortLivedConstructor;
pShortLivedConstructor.ConstructParticle();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void PhysicsList::ConstructProcess()
{
if(fVerbose > 0) {
G4cout << "### PhysicsList Construct Processes" << G4endl;
}
if (fPhysListIsSet)
G4VModularPhysicsList::ConstructProcess();
else
G4Exception("PhysicsList::ConstructProcess()", "PhysList001",
FatalException, "No PHYSICS LIST has been set!");
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void PhysicsList::SetPhysicsList(const G4String& name)
{
if(fVerbose > 0)
G4cout << "### PhysicsList set physics list <" << name
<< "> " << G4endl;
if (!fPhysListIsSet) {
G4PhysListFactory factory;
G4VModularPhysicsList* phys = factory.GetReferencePhysList(name);
size_t ii = 0;
const G4VPhysicsConstructor* elem = phys->GetPhysics(ii);
G4VPhysicsConstructor* tmp = const_cast<G4VPhysicsConstructor*> (elem);
while (elem) {
RegisterPhysics(tmp);
G4cout << "PhysicsList Type: " << elem->GetPhysicsType() << G4endl;
G4cout << "PhysicsList Name: " << elem->GetPhysicsName() << G4endl;
elem = phys->GetPhysics(++ii);
tmp = const_cast<G4VPhysicsConstructor*> (elem);
}
G4cout << name << " reference physics List has been ACTIVATED."
<< G4endl;
// Update the flag, the physics list is set
fPhysListIsSet = true;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -0,0 +1,76 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
#include "PhysicsListMessenger.hh"
#include "PhysicsList.hh"
#include "G4UIdirectory.hh"
#include "G4UIcmdWithAString.hh"
#include "G4UIcmdWithAnInteger.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
PhysicsListMessenger::PhysicsListMessenger(PhysicsList* pPhys)
:fPL(pPhys)
{
fPhysDir = new G4UIdirectory("/my_phys/");
fPhysDir->SetGuidance("Commands to set physics list");
fPhysListCmd = new G4UIcmdWithAString("/my_phys/setList", this);
fPhysListCmd->SetGuidance("Set a *reference* physics list.");
fPhysListCmd->SetParameterName("physList", false);
fPhysListCmd->AvailableForStates(G4State_PreInit);
fVerbCmd = new G4UIcmdWithAnInteger("/my_phys/verbose", this);
fVerbCmd->SetGuidance("Set verbose level for physics list");
fVerbCmd->SetParameterName("verb", false);
fVerbCmd->AvailableForStates(G4State_PreInit, G4State_Idle);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
PhysicsListMessenger::~PhysicsListMessenger()
{
delete fPhysListCmd;
delete fVerbCmd;
delete fPhysDir;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void PhysicsListMessenger::SetNewValue(G4UIcommand* command, G4String newValue)
{
if ( command == fPhysListCmd )
fPL->SetPhysicsList(newValue);
else if ( command == fVerbCmd )
fPL->SetVerbose(fVerbCmd->GetNewIntValue(newValue));
}
@@ -0,0 +1,155 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
#include "PrimaryGeneratorAction.hh"
#include "PrimaryGeneratorMessenger.hh"
#include "G4IAEAphspReader.hh"
#include "globals.hh"
#include "Randomize.hh"
#include "G4SystemOfUnits.hh"
#include "G4ParticleGun.hh"
#include "G4ParticleTable.hh"
#include "G4ParticleDefinition.hh"
#include "G4Gamma.hh"
#include "G4RunManager.hh"
#include <vector>
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
PrimaryGeneratorAction::PrimaryGeneratorAction(const G4int threads)
:fThreads(threads)
{
fIAEAphspReaderName = "";
fVerbose = 0;
fMessenger = new PrimaryGeneratorMessenger(this);
fParticleGun = new G4ParticleGun();
fParticleGun->SetParticleDefinition(G4Gamma::Definition());
fCounter = 0;
fKinE = 50.0*MeV;
fDE = 0.0;
fX0 = 0.0;
fY0 = 0.0;
fZ0 = 0.0;
fDX = 0.0;
fDY = 0.0;
fDZ = 0.0;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
PrimaryGeneratorAction::~PrimaryGeneratorAction()
{
if (fVerbose > 0) G4cout << "Destroying PrimaryGeneratorAction" << G4endl;
delete fParticleGun;
delete fMessenger;
if (fIAEAphspReader) delete fIAEAphspReader;
if (fVerbose > 0) G4cout << "PrimaryGeneratorAction destroyed" << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void PrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent)
{
if (fIAEAphspReader) {
fIAEAphspReader->GeneratePrimaryVertex(anEvent);
}
else {
fCounter++ ;
// Simulation of beam kinetic energy
G4double kinEnergy = fKinE;
if(fDE > 0.0)
kinEnergy = G4RandFlat::shoot(fKinE-fDE/2., fKinE+fDE/2.);
fParticleGun->SetParticleEnergy(kinEnergy);
// Simulation of beam position
G4double x = fX0;
G4double y = fY0;
G4double z = fZ0;
if (fDX > 0.0)
x = G4RandFlat::shoot(fX0-fDX/2., fX0+fDX/2.);
if (fDY > 0.0)
y = G4RandFlat::shoot(fY0-fDY/2., fY0+fDY/2.);
if (fDZ > 0.0)
z = G4RandFlat::shoot(fZ0-fDZ/2., fZ0+fDZ/2.);
fParticleGun->SetParticlePosition( G4ThreeVector(x,y,z) );
// Simulation of beam direction
G4double ux = 0.0;
G4double uy = 0.0;
G4double uz = 1.0;
// Beam particles are randomly going upwards or downwards
// This is done in order to let G4IAEAphspReader show how n_stat works
if(G4UniformRand() < 0.5)
uz = -uz;
fParticleGun->SetParticleMomentumDirection( G4ThreeVector(ux,uy,uz) );
if(fVerbose > 1) {
G4ParticleDefinition* particle = fParticleGun->GetParticleDefinition();
G4String particleName = particle->GetParticleName();
G4cout << G4endl
<< "Event # " << fCounter
<< " ParticleGun vertex: "
<< "ParticleName = " << particleName
<< " PDGcode = " << particle->GetPDGEncoding()
<< G4endl;
G4cout << std::setprecision(6)
<< "\t\t KinEnergy (MeV) = " << kinEnergy/MeV
<< " weight = " << fParticleGun->GetParticleWeight()
<< G4endl
<< "\t\t x (cm) = " << x/cm
<< " y (cm) = " << y/cm
<< " z (cm) = " << z/cm
<< " ux = " << ux << " uy = " << uy << " uz = " << uz
<< G4endl;
}
fParticleGun->GeneratePrimaryVertex(anEvent);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void PrimaryGeneratorAction::SetIAEAphspReader(const G4String filename)
{
fIAEAphspReaderName = filename;
fIAEAphspReader = new G4IAEAphspReader(filename, fThreads);
}
@@ -0,0 +1,142 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
#include "G4UIdirectory.hh"
#include "G4UIcmdWithADoubleAndUnit.hh"
#include "G4UIcmdWithAnInteger.hh"
#include "PrimaryGeneratorMessenger.hh"
#include "PrimaryGeneratorAction.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
PrimaryGeneratorMessenger::
PrimaryGeneratorMessenger(PrimaryGeneratorAction* gen)
: fGen(gen)
{
fBeamDir = new G4UIdirectory("/my_beam/");
fBeamDir->SetGuidance("Example-specific commands to set beam properties");
fKinECmd = new G4UIcmdWithADoubleAndUnit("/my_beam/kinE",this);
fKinECmd->SetGuidance("Set the beam kinetic energy");
fKinECmd->SetParameterName("kinE",false);
fKinECmd->SetUnitCategory("Energy");
fKinECmd->AvailableForStates(G4State_PreInit,G4State_Idle);
fDECmd = new G4UIcmdWithADoubleAndUnit("/my_beam/DE",this);
fDECmd->SetGuidance("Set the beam energy half-width, flat distribution");
fDECmd->SetParameterName("DE",false);
fDECmd->SetUnitCategory("Energy");
fDECmd->AvailableForStates(G4State_PreInit,G4State_Idle);
fX0Cmd = new G4UIcmdWithADoubleAndUnit("/my_beam/X0",this);
fX0Cmd->SetGuidance("Set X position of the center of the beam.");
fX0Cmd->SetParameterName("X0",false);
fX0Cmd->SetUnitCategory("Length");
fX0Cmd->AvailableForStates(G4State_PreInit,G4State_Idle);
fY0Cmd = new G4UIcmdWithADoubleAndUnit("/my_beam/Y0",this);
fY0Cmd->SetGuidance("Set Y position of the center of the beam.");
fY0Cmd->SetParameterName("Y0",false);
fY0Cmd->SetUnitCategory("Length");
fY0Cmd->AvailableForStates(G4State_PreInit,G4State_Idle);
fZ0Cmd = new G4UIcmdWithADoubleAndUnit("/my_beam/Z0",this);
fZ0Cmd->SetGuidance("Set Z position of the center of the beam.");
fZ0Cmd->SetParameterName("Z0",false);
fZ0Cmd->SetUnitCategory("Length");
fZ0Cmd->AvailableForStates(G4State_PreInit,G4State_Idle);
fDXCmd = new G4UIcmdWithADoubleAndUnit("/my_beam/DX",this);
fDXCmd->SetGuidance("Set the beam half-width for X, flat distribution");
fDXCmd->SetParameterName("DX",false);
fDXCmd->SetUnitCategory("Length");
fDXCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
fDYCmd = new G4UIcmdWithADoubleAndUnit("/my_beam/DY",this);
fDYCmd->SetGuidance("Set the beam half-width for Y, flat distribution");
fDYCmd->SetParameterName("DY",false);
fDYCmd->SetUnitCategory("Length");
fDYCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
fDZCmd = new G4UIcmdWithADoubleAndUnit("/my_beam/DZ",this);
fDZCmd->SetGuidance("Set the beam half-width for Z, flat distribution");
fDZCmd->SetParameterName("DZ",false);
fDZCmd->SetUnitCategory("Length");
fDZCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
fVerboseCmd = new G4UIcmdWithAnInteger("/my_beam/verbose", this);
fVerboseCmd->SetGuidance("Set primary generator verbose");
fVerboseCmd->SetParameterName("verb",false);
fVerboseCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
PrimaryGeneratorMessenger::~PrimaryGeneratorMessenger()
{
delete fBeamDir;
delete fKinECmd;
delete fDECmd;
delete fX0Cmd;
delete fY0Cmd;
delete fZ0Cmd;
delete fDXCmd;
delete fDYCmd;
delete fDZCmd;
delete fVerboseCmd;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void PrimaryGeneratorMessenger::SetNewValue(G4UIcommand* command,
G4String newValue)
{
if (command == fKinECmd)
fGen->SetKinE(fKinECmd->GetNewDoubleValue(newValue));
else if (command == fDECmd)
fGen->SetDE(fDECmd->GetNewDoubleValue(newValue));
else if (command == fX0Cmd)
fGen->SetX0(fX0Cmd->GetNewDoubleValue(newValue));
else if (command == fY0Cmd)
fGen->SetY0(fY0Cmd->GetNewDoubleValue(newValue));
else if (command == fZ0Cmd)
fGen->SetZ0(fZ0Cmd->GetNewDoubleValue(newValue));
else if (command == fDXCmd)
fGen->SetDX(fDXCmd->GetNewDoubleValue(newValue));
else if (command == fDYCmd)
fGen->SetDY(fDYCmd->GetNewDoubleValue(newValue));
else if (command == fDZCmd)
fGen->SetDZ(fDZCmd->GetNewDoubleValue(newValue));
else if (command == fVerboseCmd)
fGen->SetVerbose(fVerboseCmd->GetNewIntValue(newValue));
}
+148
View File
@@ -0,0 +1,148 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
#include "RunAction.hh"
#include "globals.hh"
#include "G4Threading.hh"
#include "G4IAEAphspWriter.hh"
#include "G4IAEAphspWriterStack.hh"
#include "IAEAphspRun.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
RunAction::~RunAction()
{
G4cout << "Destroying RunAction object" << G4endl;
if (fIAEAphspWriterStack) {
fIAEAphspWriterStack->ClearZphspVec();
delete fIAEAphspWriterStack;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4Run* RunAction::GenerateRun()
{
// Generate new RUN object, which is specially
// dedicated to store run-persistent data.
if ( G4Threading::IsMultithreadedApplication() ) {
if (!(IsMaster()) && fIAEAphspWriterStack ) {
G4cout << "Generating a worker IAEAphspRun with IAEAphspWriterStack!!"
<< G4endl;
return new IAEAphspRun(fIAEAphspWriterStack);
}
else {
if (IsMaster()) G4cout << "Generating a master IAEAphspRun!!" << G4endl;
else G4cout << "Generating a worker IAEAphspRun!!" << G4endl;
return new IAEAphspRun();
}
}
else { // sequential mode
if (fIAEAphspWriterStack)
return new IAEAphspRun(fIAEAphspWriterStack);
else
return new IAEAphspRun();
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void RunAction::EndOfRunAction(const G4Run* aRun)
{
G4cout << "RunAction::EndOfRunAction() " << G4endl;
if ( G4Threading::IsMultithreadedApplication() ) {
if (IsMaster()) {
auto masterRun = static_cast<const IAEAphspRun*>(aRun);
auto iaeaphspWriter = masterRun->GetIAEAphspWriter();
if (iaeaphspWriter) {
// The IAEAphsp files are open at first call of IAEAphspRun::Merge()
iaeaphspWriter->CloseIAEAphspOutFiles();
}
}
}
else { // sequential mode
const IAEAphspRun* constRun = dynamic_cast<const IAEAphspRun*>(aRun);
IAEAphspRun* iaeaRun = const_cast<IAEAphspRun*>(constRun);
auto phspStack = iaeaRun->GetIAEAphspWriterStack();
if (phspStack) { // We defined IAEAphsp stack
iaeaRun->DumpToIAEAphspFiles(phspStack);
// Update the number of original histories to all files and close
const G4int histories = iaeaRun->GetNumberOfEvent();
const size_t nPhsp = phspStack->GetZphspVec()->size();
auto iaeaphspWriter = iaeaRun->GetIAEAphspWriter();
if (iaeaphspWriter) {
for (size_t jj = 0; jj < nPhsp; jj++)
iaeaphspWriter->SumOrigHistories(jj, histories);
iaeaphspWriter->CloseIAEAphspOutFiles();
}
else {
G4ExceptionDescription msg;
msg << "Could not get G4IAEAphspWriter object after dumping info"
<< "from G4IAEAphspWriterStack."
<< G4endl;
G4Exception("RunAction::EndOfRunAction()",
"RunAction001", FatalException, msg);
}
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void RunAction::SetIAEAphspWriterStack(const G4String& namePrefix)
{
fIAEAphspWriterStack = new G4IAEAphspWriterStack(namePrefix);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void RunAction::AddZphsp(const G4double val)
{
if (fIAEAphspWriterStack) {
fIAEAphspWriterStack->AddZphsp(val);
}
else {
G4ExceptionDescription msg;
msg << "z_phsp value passed, but no IAEAphsp output file name provided!"
<< G4endl;
G4Exception("RunAction::AddZphsp()",
"RunAction002", FatalException, msg);
}
}
@@ -0,0 +1,44 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
#include "SteppingAction.hh"
#include "G4RunManager.hh"
#include "IAEAphspRun.hh"
#include "G4IAEAphspWriterStack.hh"
void SteppingAction::UserSteppingAction(const G4Step* aStep)
{
const IAEAphspRun* aRun =
static_cast<const IAEAphspRun*>( G4RunManager::GetRunManager()
->GetCurrentRun() );
auto phspWriterStack = aRun->GetIAEAphspWriterStack();
if (phspWriterStack)
phspWriterStack->StoreParticleIfEligible(aStep);
}
@@ -0,0 +1,26 @@
#================================================
# Macro file to test IAEAphsp reader
#================================================
/control/verbose 1
/run/verbose 1
/tracking/verbose 1
/event/verbose 0
#
/action/IAEAphspReader/fileName phsp/test
#
/my_geom/worldXY 25.0 cm
/my_geom/worldZ 100.0 cm
#
/my_phys/setList QGSP_BIC_HP_EMZ
#
/run/initialize
#
/run/setCut 0.1 mm
#
/IAEAphspReader/verbose 2
/IAEAphspReader/numberOfParallelRuns 4 # tot_parallel >= 1
/IAEAphspReader/parallelRun 2 # 1 <= value <= tot_parallel
#
#/run/printProgress 10
/run/beamOn 50
#
+31
View File
@@ -0,0 +1,31 @@
#=======================================================
# Macro file to test simultaneous r/w of IAEAphsp files
#=======================================================
/control/verbose 1
/run/verbose 1
/tracking/verbose 1
/event/verbose 0
#
/action/IAEAphspReader/fileName phsp/PSF_example
/action/IAEAphspWriter/namePrefix psf_z
/action/IAEAphspWriter/zphsp 12.0 cm
#
/my_geom/worldXY 25.0 cm
/my_geom/worldZ 30.0 cm
#
/my_phys/setList QGSP_BIC_HP_EMZ
#
/run/initialize
#
/run/setCut 0.1 mm
#
/IAEAphspReader/verbose 1
/IAEAphspReader/numberOfParallelRuns 1 # n_parallel >= 1
/IAEAphspReader/parallelRun 1 # in [1, n_parallel]
#
#/run/printProgress 100
/run/beamOn 200
#
/run/beamOn 100
#
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,34 @@
#================================================
# Macro file to test IAEAphsp writer
#================================================
/control/verbose 1
/run/verbose 1
/tracking/verbose 0
/event/verbose 0
#
/action/IAEAphspWriter/namePrefix psf_z
/action/IAEAphspWriter/zphsp 50.1 cm
/action/IAEAphspWriter/zphsp 60.5 cm
#
/my_geom/worldXY 25.0 cm
/my_geom/worldZ 100.0 cm
#
/my_phys/setList QGSP_BIC_HP_EMZ
#
/run/initialize
#
/run/setCut 0.1 mm
#
/gun/particle gamma
/my_beam/kinE 10.0 MeV
/my_beam/DE 5.0 MeV
/my_beam/X0 7.0 cm
/my_beam/DX 2.0 cm
/my_beam/Y0 -5.0 cm
/my_beam/DY 1.0 cm
/my_beam/Z0 0.0 cm
/my_beam/verbose 2
#
##/run/printProgress 10
/run/beamOn 50
#
+104
View File
@@ -0,0 +1,104 @@
#
# Macro file for visualisation
#
# Sets some default verbose
# and initializes the graphic.
#
/control/verbose 2
/run/verbose 2
/tracking/verbose 0
#
/action/IAEAphspReader/fileName phsp/test
/action/IAEAphspWriter/namePrefix psf_z
/action/IAEAphspWriter/zphsp 20. cm
#
/my_phys/setList QGSP_BIC_HP_EMZ
#
/run/initialize
#
/run/setCut 0.1 mm
#
/IAEAphspReader/translate 0 0 -70.0 cm
/IAEAphspReader/verbose 0
#
###/gun/particle e-
###/gun/energy 6.0 MeV
###/my_beam/DX 2.0 cm
###/my_beam/DY 2.0 cm
###/my_beam/verbose 1
#
# Use this open statement to create an OpenGL view:
/vis/open OGL 600x600-0+0
#
# Use this open statement to create a .prim file suitable for
# viewing in DAWN:
#/vis/open DAWNFILE
#
# Use this open statement to create a .heprep file suitable for
# viewing in HepRApp:
#/vis/open HepRepFile
#
# Use this open statement to create a .wrl file suitable for
# viewing in a VRML viewer:
#/vis/open VRML2FILE
#
# Disable auto refresh and quieten vis messages whilst scene and
# trajectories are established:
/vis/viewer/set/autoRefresh false
/vis/verbose errors
#
# Draw geometry:
/vis/drawVolume
#
# Specify view angle:
/vis/viewer/set/viewpointThetaPhi -90. 0.
#
# Specify zoom value:
/vis/viewer/zoom 1.4
#
# Specify style (surface or wireframe):
#/vis/viewer/set/style wireframe
#
# Draw coordinate axes:
#/vis/scene/add/axes 0 0 0 1 m
#
# Draw smooth trajectories at end of event, showing trajectory points
# as markers 2 pixels wide:
/vis/scene/add/trajectories smooth
/vis/modeling/trajectories/create/drawByCharge
/vis/modeling/trajectories/drawByCharge-0/default/setDrawStepPts true
/vis/modeling/trajectories/drawByCharge-0/default/setStepPtsSize 2
# (if too many tracks cause core dump => /tracking/storeTrajectory 0)
#
# Draw hits at end of event:
#/vis/scene/add/hits
#
# To draw only gammas:
#/vis/filtering/trajectories/create/particleFilter
#/vis/filtering/trajectories/particleFilter-0/add gamma
#
# To invert the above, drawing all particles except gammas,
# keep the above two lines but also add:
#/vis/filtering/trajectories/particleFilter-0/invert true
#
# Many other options are available with /vis/modeling and /vis/filtering.
# For example, to select colour by particle ID:
#/vis/modeling/trajectories/create/drawByParticleID
#/vis/modeling/trajectories/drawByParticleID-0/set e- blue
#
# To superimpose all of the events from a given run:
/vis/scene/endOfEventAction accumulate
#
# Re-establish auto refreshing and verbosity:
/vis/viewer/set/autoRefresh true
/vis/verbose warnings
#
# For file-based drivers, use this to create an empty detector view:
#/vis/viewer/flush
#
# ------------------------
# Launch a couple of runs to illustrate recording of IAEAphsp files
#
/run/beamOn 50
#
/run/beamOn 100