58 #include <sys/types.h>
70 #define EGS_ACCESS ::_access
74 #define EGS_ACCESS ::access
75 #include <sys/statvfs.h>
78 #define MAXIMUM_JOB_NUMBER 8192
81 static char __egs_app_msg1[] =
"EGS_Application::EGS_Application(int,char**):";
82 static char __egs_app_msg2[] =
"EGS_Application::initSimulation():";
83 static char __egs_app_msg3[] =
"EGS_Application::runSimulation():";
85 static EGS_LOCAL
bool __egs_find_pegsfile(
const vector<string> &paths,
86 const string &pegs_file,
string &abs_pegs_file) {
87 string pfile = pegs_file;
88 if (pfile.find(
".pegs4dat") == string::npos) {
91 for (
unsigned int j=0; j<paths.size(); j++) {
92 string this_pegs =!paths[j].empty() ?
egsJoinPath(paths[j],pfile) : pfile;
93 if (!EGS_ACCESS(this_pegs.c_str(),R_OK)) {
94 abs_pegs_file = this_pegs;
103 int EGS_Application::n_apps = 0;
105 unique_ptr<EGS_InputStruct> EGS_Application::inputStructure = unique_ptr<EGS_InputStruct>();
108 return active_egs_application;
112 active_egs_application = a;
117 int early_return = 0;
118 for (
int j=0; j<a_objects[iarg].size(); ++j) {
121 res = a_objects[iarg][j]->processEvent((
AusgabCall)iarg, ir);
124 res = a_objects[iarg][j]->processEvent((
AusgabCall)iarg);
133 if (early_return > 0) {
146 const char *n1,
const char *n2,
const char *env,
string &var) {
147 char *aux = getenv(env);
154 getArgument(argc,argv,n1,n2,var);
155 if (!var.size())
egsFatal(
"%s\n the environment variable %s is not set"
156 " and it was not passed as argument\n",__egs_app_msg1,env);
157 int n = var.size()-1;
158 if (var[n] !=
'/' && var[n] != fs) {
171 EGS_Float Twant, EGS_Float T) : x(X), u(U), twant(Twant), t(T),
172 ireg(Ireg), inew(Inew) {};
174 egsWarning(
"old region=%d, position=(%g,%g,%g), "
175 "direction=(%g,%g,%g) intended step=%g, new region=%d, "
176 "step=%g\n",ireg,x.
x,x.
y,x.
z,u.
x,u.
y,u.
z,twant,inew,t);
185 void addStep(
int ireg,
int inew,
const EGS_Vector &x,
186 const EGS_Vector &u, EGS_Float twant, EGS_Float t) {
187 steps[ns++] = Step(ireg,inew,x,u,twant,t);
193 void reportHistory()
const {
194 int nhave = wrap ? nsize : ns;
195 egsWarning(
"\n************** Last %d geometry steps:\n",nhave);
197 for (
int j=ns; j<nsize; j++) {
201 for (
int j=0; j<ns; j++) {
212 void EGS_Application::reportGeometryError() {
213 ghistory->reportHistory();
216 run->geomErrorCount++;
217 if (run->geomErrorCount > run->geomErrorMax) {
218 egsFatal(
"\n\n******** Encountered %d geometry errors (maximum allowed is %d). \n \
219 You can change this limit with the 'geometry error limit' run control input key. \n \
220 Quitting now.\n", run->geomErrorCount, run->geomErrorMax);
224 void EGS_Application::storeGeometryStep(
int ireg,
int inew,
226 ghistory->addStep(ireg,inew,x,u,twant,t);
230 source(0), rndm(0), run(0), simple_run(false), uniform_run(false), current_case(0),
231 last_case(0), data_out(0), data_in(0), a_objects(0),
236 if (!active_egs_application) {
237 active_egs_application =
this;
257 size_t exePos =
app_name.rfind(
".exe");
258 if (exePos != string::npos) {
263 "name from %s or command line arguments\n",__egs_app_msg1,argv[0]);
288 if (ext != std::string::npos) {
314 vector<string> pegs_paths;
315 pegs_paths.push_back(
"");
319 egsFatal(
"%s\n the pegs file %s does not exist or is not "
320 "readable\n",__egs_app_msg1,
pegs_file.c_str());
329 if (ifile.find(
".egsinp") == string::npos) {
332 if (EGS_ACCESS(ifile.c_str(),R_OK))
333 egsFatal(
"%s\n the input file %s does not exist or is not "
334 "readable\n",__egs_app_msg1,ifile.c_str());
350 for (
int j=1; j<argc; j++) {
351 string tmp = argv[j];
352 if (tmp ==
"-b" || tmp ==
"--batch") {
362 string npar, ipar, ifirst;
365 bool have_np =
getArgument(argc,argv,
"-P",
"--parallel",npar);
366 bool have_ip =
getArgument(argc,argv,
"-j",
"--job",ipar);
367 bool have_first =
getArgument(argc,argv,
"-f",
"--first-job",ifirst);
368 if (have_np && have_ip) {
374 egsWarning(
"%s\n invalid -f argument %d\n",__egs_app_msg1,
381 egsWarning(
"%s\n invalid -P argument %d\n",__egs_app_msg1,
386 egsWarning(
"%s\n invalid -j argument %d\n",__egs_app_msg1,
392 egsWarning(
"%s\n job number (%d) can not be larger than number"
393 " of parallel jobs(%d). Turning off parallel option\n",
399 else if (have_np && !have_ip) {
408 else if (!have_np && have_ip) {
409 egsWarning(
"\n%s\n to specify a parallel run you need both,"
410 " the -P and -j command line options\n\n",__egs_app_msg1);
416 for (
int j=1; j<argc; j++) {
417 string tmp = argv[j];
418 if (tmp ==
"-s" || tmp ==
"--simple-run") {
430 for (
int j=1; j<argc; j++) {
431 string tmp = argv[j];
432 if (tmp ==
"-u" || tmp ==
"--urc") {
451 if (ifile.size() > 0) {
453 egsFatal(
"%s\n error while reading input file %s\n",
454 __egs_app_msg1,ifile.c_str());
460 const char *name1,
const char *name2,
string &arg) {
461 string n1(name1), n2(name2);
462 for (
int j=1; j<argc-1; j++) {
463 if (n1 == argv[j] || n2 == argv[j]) {
474 bool with_run_dir)
const {
494 data_out =
new ofstream(ofile.c_str());
496 egsWarning(
"EGS_Application::outputData: failed to open %s "
497 "for writing\n",ofile.c_str());
530 data_in =
new ifstream(ifile.c_str());
532 egsWarning(
"EGS_Application::readData: failed to open %s "
533 "for reading\n",ifile.c_str());
561 rndm->resetCounter();
570 if (!
run->addState(data)) {
579 if (!
rndm->addState(data)) {
592 bool fileExists(
const string &name) {
594 return (stat(name.c_str(), &buffer) == 0);
605 if (fileExists(dfile)) {
627 "\n Suming the following .egsdat files:\n"
628 "=======================================================================\n");
631 EGS_Float last_cpu = 0;
632 EGS_I64 last_ncase = 0;
646 ifstream data(dfile.c_str());
651 EGS_I64 ncase =
run->getNdone();
652 EGS_Float cpu =
run->getCPUTime();
654 ndat,buf,ncase-last_ncase,cpu-last_cpu);
660 egsWarning(
"%2d %-30s error %d\n",ndat,buf,err);
666 "=======================================================================\n");
667 egsInformation(
"%40s%-14lld cpu=%-11.2f\n\n",
"Total ncase=",last_ncase,
724 run = EGS_RunControl::getRunControlObject(
this);
744 egsWarning(
"EGS_Application::initRNG(): using default RNG\n");
748 egsWarning(
"EGS_Application::initRNG(): got null RNG?\n");
761 egsWarning(
"\n\n%s geometry initialization failed\n",__egs_app_msg2);
766 egsWarning(
"\n\n%s source initialization failed\n",__egs_app_msg2);
771 egsWarning(
"\n\n%s RNG initialization failed\n",__egs_app_msg2);
776 egsWarning(
"\n\n%s run control initialization failed\n",__egs_app_msg2);
784 egsWarning(
"\n\n%s back-end initialization failed\n",__egs_app_msg2);
790 egsWarning(
"\n\n%s cross section initialization failed\n",__egs_app_msg2);
795 egsWarning(
"\n\n%s scoring initialization failed with status %d\n",
820 "\n========================================="
831 egsInformation(
"The following ausgab objects are included in the simulation\n");
832 egsInformation(
"===========================================================\n\n");
843 egsWarning(
"%s no geometry\n",__egs_app_msg3);
855 egsWarning(
"%s no run control object\n",__egs_app_msg3);
864 if (start_status < 0) {
865 egsWarning(
"\n%s failed to start the simulation\n\n",__egs_app_msg3);
871 bool next_chunk =
true;
877 if (
run->getCombinedResult(f,df)) {
880 " runs: %lg +/- %7.3lf%c\n\n",f,df,c);
886 EGS_I64 ncase_per_batch = ncase/nbatch;
887 if (!ncase_per_batch) {
891 for (
int ibatch=0; ibatch<nbatch; ibatch++) {
897 for (EGS_I64 icase=0; icase<ncase_per_batch; icase++) {
900 "loop termination\n");
927 egsWarning(
"EGS_Application::simulateSingleShower(): no particle"
928 " from the source has entered the geometry after 100000"
985 active_egs_application =
this;
988 active_egs_application = app;
1005 if (active_egs_application ==
this) {
1006 active_egs_application = 0;
1019 egsFatal(
"error: only one ausgab object of type "
1020 "'EGS_TrackScoring' is allowed\n");
1098 fstat(fileno(stream), &tmp);
1101 if (S_ISREG(tmp.st_mode)) {
1102 struct statvfs fstats;
1103 fstatvfs(fileno(stdout), &fstats);
1104 if (fstats.f_bavail*fstats.f_bsize < 1048576) {
1105 egsFatal(
"\n\n******** Space left on file system is below 1 MB. Quitting now.\n");
1114 fprintf(stdout,
"%s",msg);
1122 fprintf(stderr,
"%s",msg);
1130 fprintf(stderr,
"%s",msg);
Base class for advanced EGSnrc C++ applications.
static bool getArgument(int &argc, char **argv, const char *name1, const char *name2, string &arg)
Finds a command line argument.
string app_dir
The user code directory.
virtual EGS_I64 randomNumbersUsed() const
Returns the number of random numbers used.
static EGS_Application * activeApplication()
Get the active application.
bool uniform_run
Use a uniform run control object for parallel runs.
string run_dir
The working directory during the run.
bool simple_run
Use a simple run control object for parallel runs.
EGS_RandomGenerator * rndm
the random number generator
bool is_pegsless
set to true if a pegsless run
int n_parallel
Number of parallel jobs.
virtual void resetCounter()
Reset the application to a 'pristine' state.
virtual int startNewShower()
Called just before the shower() function.
EGS_Application(int argc, char **argv)
Construct an EGSnrc application.
EGS_SimpleContainer< EGS_AusgabObject * > a_objects_list
The ausgab objects.
string input_file
The input file name.
string output_file
The output file name (no extension)
virtual void setAusgabCall(AusgabCall call, bool on_or_off)
Turns on or off a call to the user scoring function ausgab.
virtual void describeSimulation()
Describe the simulation.
EGS_I64 last_case
The last case simulated.
virtual int addState(istream &data)
Add data from a parallel job.
virtual int finishSimulation()
Analyze and output the results.
static void setActiveApplication(EGS_Application *)
Set the active EGS_Application class.
virtual int initRunControl()
Construct the run control object.
virtual void appFatal(const char *)
Write a warning message and exit.
string pegs_file
The pegs file name.
virtual int outputData()
Output intermediate results.
virtual int initScoring()
Initialize the scoring of quantities of interest.
virtual int initSimulation()
Initializes the EGSnrc application.
EGS_Input * input
the input to this simulation.
string app_name
The application name.
virtual void outputResults()
Output the simulation results.
virtual ~EGS_Application()
Destruct the EGSnrc application.
void initAusgabObjects()
Initialize ausgab objects.
string final_output_file
The final output file name.
void addAusgabObject(EGS_AusgabObject *o)
Adds an ausgab object to the list of ausgab objects.
EGS_BaseGeometry * geometry
the geometry of this simulation
AusgabCall
Possible calls to the user scoring function ausgab().
@ BeforeTransport
before the step
@ UnknownCall
last element in the enumeration
@ AfterTransport
after the step
bool ausgab_flag[UnknownCall]
on/off flags for ausgab calls
EGS_I64 current_case
The current case as returned from the source.
virtual int initGeometry()
Initialize the simulation geometry.
virtual int initRNG()
Initialize the random number generator.
bool batch_run
Interactive or batch run.
int i_parallel
Job index in parallel runs.
istream * data_in
data input stream
string egs_home
The EGS_HOME directory.
int first_parallel
first parallel job number
int app_index
the index of this application.
virtual int initCrossSections()
Initialize the EGSnrc cross sections and cross section/transport options.
int howManyJobsDone()
Counts how many *.egsdat files in app folder.
virtual void appInformation(const char *)
Write an information message.
virtual void setSimulationChunk(EGS_I64 nstart, EGS_I64 nrun, int npar, int nchunk)
Set the simulation chunk.
virtual void describeUserCode() const
Describe the user code.
string abs_pegs_file
The pegs file name including absolute path.
virtual int finishShower()
Called just after the shower() function.
int userScoring(int iarg, int ir=-1)
User scoring function for accumulation of results and VRT implementation.
virtual int simulateSingleShower()
Simulates a single particle shower.
ostream * data_out
data output stream
virtual void appWarning(const char *)
Write a warning message.
virtual int initSource()
Initialize the particle source.
EGS_RunControl * run
the run control object.
EGS_SimpleContainer< EGS_AusgabObject * > * a_objects
The ausgab objects for the various ausgab calls.
virtual int combineResults()
Combine results from parallel runs.
static void checkEnvironmentVar(int &argc, char **argv, const char *env, const char *n1, const char *n2, string &var)
Finds a command line argument.
string constructIOFileName(const char *extension, bool with_run_dir) const
Constructs and returns the name of an input/output file.
virtual void fillRandomArray(int n, EGS_Float *rns)
Fill an array with random numbers using the application's RNG.
string hen_house
The HEN_HOUSE directory.
virtual int runSimulation()
Runs an EGSnrc simulation.
virtual int initEGSnrcBackEnd()
Initialize the EGSnrc backend.
void checkDeviceFull(FILE *)
Check if a device holding a given stream is full.
void setTimeIndex(EGS_Float temp_time)
EGS_BaseSource * source
the particle source
virtual int combinePartialResults()
Combine intermediate results from parallel runs.
virtual int shower()
Simulate a single shower.
virtual int readData()
Read intermediate results.
virtual void setApplication(EGS_Application *App)
Set the application this object belongs to.
static EGS_AusgabObject * getObject(size_t j)
Returns the j'th ausgab object in the internal list.
static void createAusgabObjects(EGS_Input *)
Create ausgab objects from the information pointed to by input.
static int nObjects()
Returns the number of ausgab objects in the internal list.
virtual bool needsCall(EGS_Application::AusgabCall iarg) const
Is the ausgab call iarg relevant for this object?
int deref()
Decrease the reference count to this geometry.
virtual int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, EGS_Float &t, int *newmed=0, EGS_Vector *normal=0)=0
Calculate the distance to a boundary from x along the direction u.
static void setActiveGeometryList(int list)
Set the currently active geometry list.
static EGS_BaseGeometry * createGeometry(EGS_Input *)
Create a geometry (or geometries) from a given input.
virtual void printInfo() const
Print information about this geometry.
int ref()
Increase the reference count to this geometry.
virtual int isWhere(const EGS_Vector &x)=0
In which region is poisition x?
virtual bool addState(istream &data_in)
Add data from the stream data_in to the source state.
const char * getSourceDescription() const
Get a short description of this source.
virtual void resetCounter()
Reset the source state.
virtual EGS_I64 getNextParticle(EGS_RandomGenerator *rndm, int &q, int &latch, EGS_Float &E, EGS_Float &wt, EGS_Vector &x, EGS_Vector &u)=0
Sample the next source particle from the source probability distribution.
static EGS_BaseSource * createSource(EGS_Input *)
Create sources from the information pointed to by input.
virtual bool setState(istream &data_in)
Set the source state based on data from the stream data_in.
virtual void setSimulationChunk(EGS_I64 nstart, EGS_I64 nrun, int npar, int nchunk)
Set the next simulation chunk to start at nstart and to consist of nrun particles.
virtual bool storeState(ostream &data_out) const
Store the source state into the stream data_out.
int ref()
Increase the reference count to this object.
static void deleteObject(EGS_Object *o)
Delete an object.
const string & getObjectType() const
Get the object type.
virtual void fillArray(int n, EGS_Float *array)=0
Fill the array of n elements pointed to by array with random numbers.
static EGS_RandomGenerator * defaultRNG(int sequence=0)
Returns a pointer to the default egspp RNG.
static EGS_RandomGenerator * createRNG(EGS_Input *inp, int sequence=0)
Create a RNG object from the information pointed to by inp and return a pointer to it.
bool storeState(ostream &data)
Functions for storing, seting and reseting the state of a RNG object.
virtual void describeRNG() const
Describe this RNG.
EGS_I64 numbersUsed() const
Returns the number of random numbers used so far.
A simple run control object for advanced EGSnrc C++ applications.
virtual EGS_I64 getNextChunk()
Returns the number of histories to run in the next simulation chunk.
int getNbatch() const
Returns the number of batches per simulation chunk.
virtual int startSimulation()
Starts the simulation.
virtual bool startBatch(int, EGS_I64)
Start a new batch.
virtual bool finishBatch()
Finish a batch.
virtual int finishSimulation()
Finish the simulation.
A class representing 3D vectors.
EGS_Application class header file.
EGS_AusgabObject interface class header file.
EGS_BaseGeometry class header file.
EGS_BaseSource class header file.
Global egspp functions header file.
#define EGS_EXPORT
Export symbols from the egspp library.
EGS_RandomGenerator class header file.
EGS_SimpleContainer template class.
bool EGS_EXPORT egsStoreI64(ostream &data, EGS_I64 n)
Writes the 64 bit integer n to the output stream data and returns true on success,...
string egsHostName()
Get the name of the host the program is running on.
int egsGetPid()
Get the process id.
EGS_InfoFunction EGS_EXPORT egsInformation
Always use this function for reporting the progress of a simulation and any other type of information...
EGS_InfoFunction EGS_EXPORT egsFatal
Always use this function for reporting fatal errors.
bool EGS_EXPORT egsGetI64(istream &data, EGS_I64 &n)
Reads a 64 bit integer from the stream data and assigns it to n. Returns true on success,...
string egsJoinPath(const string &first, const string &second)
Join two path variables (or a path and a file name) using the platform specific directory separator a...
EGS_InfoFunction EGS_EXPORT egsWarning
Always use this function for reporting warnings.
const EGS_Float veryFar
A very large float.
string egsStripPath(const string &aname)
Strip the path from a file name and return the result.
EGS_Float E
particle energy in MeV
int ir
particle region index
int latch
latch variable (useful as a flag on many occasions)
EGS_Float wt
statistical weight