Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expand environment variable in file names for C++ apps #600

Merged
merged 3 commits into from
Aug 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions HEN_HOUSE/egs++/egs_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,79 @@ string egsJoinPath(const string &first, const string &second) {
return result;
}

/* Expand first environment variable found anywhere in string aname

- Checks for Unix or Windows style environment variable
- Expands environment variable in aname appending folder
separator if missing
- Replaces backslashes with slashes
- Checks for duplicate slashes in aname
*/
string egsExpandPath(const string &aname) {
string str = aname;
string c = "%$";
// Check for FIRST environment variable anywhere in aname
size_t p1= str.npos;
int i = 0;
while (i < c.size()) {
p1= str.find_first_of(c[i++]);
if (p1 != str.npos) {
break;
}
}
string fs = "%/\\";
i = 0;
size_t p2 = str.npos;
while (p1 != str.npos && i < fs.size()) {
p2 = str.find_first_of(fs[i++],p1+1);
if (p2 != str.npos) {
break;
}
}
// Did we find an environment variable?
if (p1 != str.npos && p2 != str.npos) {
string envvar = str.substr(p1+1, p2-(p1+1));
char *envval = getenv(envvar.c_str());
// Check that env var is defined
string envloc = envval ? string(envval) : string();
if (!envloc.empty()) {
// Append missing separator
size_t last = envloc.find_last_of("/\\");
if (last != envloc.size()-1) {
if (envloc[last] == __egs_fs) {
envloc.append("\\");
}
else {
envloc.append("/");
}
}
str.replace(p1, p2-p1+1,envloc);
}
else {
if (str[p1] == '$') {
egsWarning("\n\n *** egs++ egsExpandPath: Undefined environment variable $%s \n\n", envvar.c_str());
}
else {
egsWarning("\n\n *** egs++ egsExpandPath: Undefined environment variable %%%s%% \n\n", envvar.c_str());
}
}
}
// Replace back slashes with slashes
size_t found = str.find("\\");
while (found != str.npos) {
str.replace(found,1,"/");
found = str.find("\\");
}
// Remove duplicated slashes
found = str.find("//");
while (found != str.npos) {
str.replace(found,2,"/");
found = str.find("//");
}

return str;
}

string egsStripPath(const string &aname) {
int j;
for (j=aname.size()-1; j>=0; j--) {
Expand Down
10 changes: 10 additions & 0 deletions HEN_HOUSE/egs++/egs_functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,16 @@ string EGS_EXPORT egsJoinPath(const string &first, const string &second);
*/
string EGS_EXPORT egsStripPath(const string &fname);

/*! \brief Expands first environment variable found in a file name.
*
* Looks for first Unix or Windows environment variable and expands
* it into its value. Missing folder separator is added, duplicated
* separators are removed. Final file name uses slashes as separators.
*
* \ingroup egspp_main
*/
string EGS_EXPORT egsExpandPath(const string &fname);

/*! \brief Get the name of the host the program is running on.
*
* \ingroup egspp_main
Expand Down
2 changes: 2 additions & 0 deletions HEN_HOUSE/egs++/egs_spectra.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1873,6 +1873,8 @@ EGS_BaseSpectrum *EGS_BaseSpectrum::createSpectrum(EGS_Input *input) {
else if (inp->compare(stype,"tabulated spectrum")) {
string spec_file;
err = inp->getInput("spectrum file",spec_file);
// Expands FIRST environment variable found in spec_file
spec_file = egsExpandPath(spec_file);
if (!err) {
ifstream sdata(spec_file.c_str());
if (!sdata) egsWarning("%s failed to open spectrum file %s\n",
Expand Down
1 change: 1 addition & 0 deletions HEN_HOUSE/user_codes/cavity/cavity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2822,6 +2822,7 @@ int Cavity_Application::initScoring() {
if( err3 ) egsFatal(
"\n\n*** Wrong/missing 'muen file' input for a "
"HVL calculation\n This is a fatal error\n\n");
muen_file = egsExpandPath(muen_file);
ifstream muen_data(muen_file.c_str());
if( !muen_data ){
egsFatal(
Expand Down
12 changes: 8 additions & 4 deletions HEN_HOUSE/user_codes/egs_cbct/egs_cbct.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1145,15 +1145,19 @@ int EGS_CBCT::initScoring() {
if( err3 ) egsFatal(
"\n\n*** Wrong/missing 'muen file' input for a "
"kerma calculation\n This is a fatal error\n\n");
muen_file = egsExpandPath(muen_file);
ifstream muen_data(muen_file.c_str());
if( !muen_data.is_open() ){
egsFatal(
"\n\n*** Failed to open muen file %s\n"
" This is a fatal error\n",muen_file.c_str());
}
else{
egsInformation("\nUsing E*muen file %s for air-kerma calculation\n",
muen_file.c_str());
egsInformation(
"\n\n=============== Kerma Scoring ===============\n"
"E*muen/rho file: %s\n"
"=============================================\n",
muen_file.c_str());
}
int ndat; muen_data >> ndat;
if( ndat < 2 || muen_data.fail() ) egsFatal(
Expand Down Expand Up @@ -1403,7 +1407,7 @@ void EGS_CBCT::initOutput() {
scan_type = blank;
}
else{
blank_scan = b_scan;
blank_scan = egsExpandPath(b_scan);
}
/*
If no scan file name entry, a warning is issued.
Expand All @@ -1417,7 +1421,7 @@ void EGS_CBCT::initOutput() {
" This is not a proper CBCT calculation.\n\n");
}
else{
real_scan = the_scan;
real_scan = egsExpandPath(the_scan);
}
/* check what scans are requested by the user
real => real scan simulation
Expand Down
24 changes: 12 additions & 12 deletions HEN_HOUSE/user_codes/egs_cbct/example_w5br.egsinp
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
#
# Projections at other angles can be obtained by modifying input block
# :cbct setup: below. One can define the projection angle and angular
# :interval. Negative values of the latter indicate rotation is done
# :counter-clockwise around the indicated axis.
# interval. Negative values of the latter indicate rotation is done
# counter-clockwise around the indicated axis.
#
# BEWARE:
#
Expand All @@ -43,8 +43,6 @@
# - media information in PEGS4 data file 521icru.pegs4dat distributed
# with EGSnrc.
#
# - Replace $EGS_HOME string below with the actual value!!!
#
# - If the detector resolution is changed, one must recalculate the blank
# scan
#
Expand Down Expand Up @@ -183,7 +181,7 @@
rotation = 0 1.570796326794896619 0
:stop transformation:
# Uses file provided in the distribution
muen file = /home/mainegra/egsnrc_mp/egs_fac/muen_air.data
muen file = $HEN_HOUSE/user_codes/egs_fac/examples/muen_air.data
:stop planar scoring:

:stop scoring options:
Expand All @@ -197,13 +195,13 @@
###############################################
# Use the 2 lines below to produce a blank scan
###############################################
#scan file = /home/mainegra/egsnrc_mp/egs_cbct/blank_coll_64.scan
#scan file = $EGS_HOME/egs_cbct/blank_coll_64.scan
#scan type = blank
###############################################
# Use the 3 lines below to produce real scans
###############################################
scan file = /home/mainegra/egsnrc_mp/egs_cbct/scan_w5br_coll_64.scan
blank scan = /home/mainegra/egsnrc_mp/egs_cbct/blank_coll_64.scan
scan file = $EGS_HOME/egs_cbct/scan_w5br_coll_64.scan
blank scan = $EGS_HOME/egs_cbct/blank_coll_64.scan
scan type = scatter
###############################################
:stop scan output:
Expand Down Expand Up @@ -286,18 +284,20 @@


########
# For fast computation one can use KN for Compton scattering. However,
# in realistic phantoms this may cause a 3% discrepancy.
# For fast computation one can assume scattering from free electrons.
# However, in realistic phantoms this may cause a 3% discrepancy.
########
:start MC transport parameter:

Global ECUT = 1

Photon cross sections = xcom # epdl (or xcom)
Photon cross sections = xcom # epdl (or xcom)

Bound Compton scattering = off

Rayleigh scattering = off

Rayleigh scattering= on
Atomic relaxations = off

:stop MC transport parameter:

Expand Down
8 changes: 8 additions & 0 deletions HEN_HOUSE/user_codes/egs_fac/egs_fac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -955,9 +955,17 @@ int EGS_FACApplication::initScoring() {
int err3 = options->getInput("muen file",muen_file);
if( err3 ) egsFatal("\n\n*** Wrong/missing 'muen file' input\n"
" This is a fatal error\n\n");
muen_file = egsExpandPath(muen_file);
ifstream muen_data(muen_file.c_str());
if( !muen_data ) egsFatal("\n\n*** Failed to open muen file %s\n"
" This is a fatal error\n",muen_file.c_str());
else{
egsInformation(
"\n\n=============== Kerma Scoring ===============\n"
"E*muen/rho file: %s\n"
"=============================================\n\n",
muen_file.c_str());
}
int ndat; muen_data >> ndat;
if( ndat < 2 || muen_data.fail() ) egsFatal(
"\n\n*** Failed to read muen dfata file\n");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@
#
# An example input file for egs_fac.
#
# NOTE: Substitute every instance of $HEN_HOUSE for its actual value in this
# file! It is essential to use 'Bound Compton Scattering = norej'. See the MC
# NOTE: It is essential to use 'Bound Compton Scattering = norej'. See the MC
# transport parameter input section for more info. See comments accompanying
# the various inputs for more details.
#
Expand Down Expand Up @@ -803,7 +802,7 @@
# ignores them (except for the first and last energy, which define the
# energy interval).
#
muen file = $HEN_HOUSE/user_codes/egs_fac/muen_air.data
muen file = $HEN_HOUSE/user_codes/egs_fac/examples/muen_air.data

:stop scoring options:

Expand Down Expand Up @@ -852,4 +851,4 @@
Bound Compton Scattering = norej
Photon cross sections = xcom # (could also be epdl or si)

:stop MC transport parameter:
:stop MC transport parameter:
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,16 @@ AIRICRU512

:Stop MC Transport Parameter:
#########################
#
# User-defined entries
#
#########################
:Start user inputs:

# phsp output directory = /home/mainegra/egsnrc_mp/phsp/
# Enter here a custom location for phase-space file output
# For instance users might want to direct the output to a
# device with enough disk space!
# phsp output directory = enter_user_defined_location

:Stop user inputs:
#########################
Expand Down
21 changes: 4 additions & 17 deletions HEN_HOUSE/user_codes/egs_kerma/egs_kerma.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1312,36 +1312,23 @@ int EGS_KermaApplication::initScoring() {
}

string emuen_file;
int errKmuen = options->getInput("emuen file",emuen_file);
int errKmuen = options->getInput("emuen file", emuen_file);
if (errKmuen) {
// Handle legacy option
errKmuen = options->getInput("muen file",emuen_file);
errKmuen = options->getInput("muen file", emuen_file);
if (errKmuen)
egsFatal(
"\n\n*** Wrong/missing 'emuen file' input for a "
"Kerma calculation\n This is a fatal error\n\n");
}
//Check for environment variable at beginning of file name
std::size_t p1= emuen_file.find_first_of("$");
if (p1 != emuen_file.npos) {
string str = emuen_file;
std::size_t p2 = str.find_first_of("/");
string envvar = str.substr(p1+1,p2-1);
//egsInformation(" Found env var: %s\n",envvar.c_str());
char *envloc = getenv(envvar.c_str());
//egsInformation(" %s points to: %s\n",envvar.c_str(),envloc);
emuen_file.replace(p1,p2+1,envloc);
//egsInformation("\n-> Kerma calculated using E*muen/rho file : %s\n\n",emuen_file.c_str());

}

//emuen_file = egsExpandPath(emuen_file);
emuen_file = egsExpandPath(emuen_file);

ifstream muen_data(emuen_file.c_str());
if (!muen_data) {
egsFatal(
"\n\n*** Failed to open emuen file %s\n"
" This is a fatal error\n",emuen_file.c_str());
" This is a fatal error\n", emuen_file.c_str());
}
else {
egsInformation(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,10 +218,8 @@
:stop fluence scoring:

### E*muen file (could also be E*mutr): absolute or relative file path
#emuen file = emuen_icru90_1.5MeV.data
### Use absolute path when submitting parallel jobs!!!
### $EGS_HOME replaced with its value now
emuen file = $EGS_HOME/egs_kerma/emuen_rho_air_1keV-1.5MeV.data
emuen file = $EGS_HOME/egs_kerma/emuen_icru90_1.5MeV.data

### geometry for forced-detection (if omitted, score ONLY when reaching scoring region)
Default FD geometry = sphere
Expand Down