45 #include "iaea_phsp.h"
47 EGS_PhspScoring::EGS_PhspScoring(
const string &Name,
50 count(0), countg(0), emin(1.e30), emax(-1.e30), first_flush(true), is_restart(false) {
51 otype =
"EGS_PhspScoring";
54 EGS_PhspScoring::~EGS_PhspScoring() {
66 p_stack =
new Particle[store_max];
68 description =
"\n*******************************************\n";
72 description +=
"*******************************************\n";
74 description +=
"\n Will output phase space for particles crossing surfaces of geometry:\n";
78 description +=
"entering and exiting phase space geometry";
80 else if (scoredir == 1) {
83 else if (scoredir == 2) {
87 else if (score_type==1) {
88 description +=
"\n Will output phase space for the following exit/entry region pairs:\n";
90 for (
int i=0; i<fromreg.size(); i++) {
91 sprintf(buf,
"%d ",fromreg[i]);
95 for (
int i=0; i<fromreg.size(); i++) {
96 sprintf(buf,
"%d ",toreg[i]);
101 int nreg =
app->getnRegions();
102 for (
int ir=0; ir<nreg; ir++) {
104 for (
int i=0; i<fromreg.size(); i++) {
105 if (fromreg[i]==ir) {
106 tolist.push_back(toreg[i]);
109 from_to.push_back(tolist);
114 if (phspoutdir ==
"") {
118 description +=
"\n Data will be output in EGSnrc format.\n";
129 else if (oformat==1) {
130 description +=
"\n Data will be output in IAEA format.\n";
140 len = phsp_fname.length();
141 phsp_fname_char =
new char[len+1];
142 phsp_fname.copy(phsp_fname_char,len,0);
143 phsp_fname_char[len]=
'\0';
157 iaea_n_extra_float=1;
162 iaea_n_extra_float=0;
166 description +=
" Header file: " + phsp_fname +
".IAEAheader\n";
167 description +=
" Data file: " + phsp_fname +
".IAEAphsp";
168 string xyzname[3] = {
"X",
"Y",
"Z"};
169 for (
int i=0; i<3; i++) {
170 if (xyz_is_const[i]) {
173 description +=
"\n Data scored at constant " + xyzname[i] +
" = " + xyz.str() +
" cm";
181 else if (ocharge == 1) {
184 else if (ocharge == 2) {
187 if (oformat ==1 && score_time) {
188 description +=
"\n time index will be scored (if available)";
190 if (oformat ==0 && score_mc) {
191 description +=
"\n will score multiple crossers (and descendents)";
198 void EGS_PhspScoring::reportResults() {
202 iaea_destroy_source(&iaea_id,&iaea_iostat);
204 egsFatal(
"\n EGS_PhspScoring: Error closing phase space file.\n");
207 else if (oformat == 0) {
210 egsInformation(
"\n======================================================\n");
212 egsInformation(
"======================================================\n");
215 egsInformation(
" Header file: %s.IAEAheader\n",phsp_fname.c_str());
218 else if (oformat == 0) {
223 if (count == countg) {
233 egsInformation(
"=> min. k.e. of charged particles = %g MeV\n",emintmp);
234 egsInformation(
"=> no. of primary histories represented = %lld\n",last_case);
235 egsInformation(
"\n======================================================\n");
242 void EGS_PhspScoring::storeParticle(EGS_I64 ncase) {
246 egsWarning(
"\nEGS_PhspScoring: User requested time index scoring, but time is inavailable with this source.\n");
247 egsWarning(
"Turning off time index scoring.\n");
252 EGS_Float prm =
app->getRM();
270 else if (oformat == 1) {
275 if (ncase != last_case) {
281 p_stack[phsp_index].E = E;
295 if (phsp_index > store_max - 1) {
302 void EGS_PhspScoring::openPhspFile()
const {
306 phsp_file.open(phsp_fname.c_str(),ios::binary|ios::out|ios::in);
308 egsFatal(
"\nEGS_PhspScoring: Failed to open phase space file %s for appending.\n",
312 phsp_file.seekg(5,ios::beg);
313 phsp_file.read((
char *) &count4,
sizeof(
unsigned int));
314 if (count4 != countprev) {
315 egsFatal(
"\nEGS_PhspScoring: Particle no. mismatch between %s and .egsdat file.\n",phsp_fname.c_str());
318 phsp_file.seekp(0,ios::end);
319 if (phsp_file.tellp() != 28 + countprev*
sizeof(egs_phsp_write_struct)) {
320 egsFatal(
"\nEGS_PhspScoring: File size mismatch in %s and .egsdat file.\n",phsp_fname.c_str());
324 phsp_file.open(phsp_fname.c_str(),ios::binary|ios::out);
326 egsFatal(
"\nEGS_PhspScoring: Failed to open phase space file %s for writing.\n",
329 phsp_file.write(
"MODE0",5);
331 phsp_file.seekp(28,ios::beg);
334 else if (oformat == 1) {
340 iaea_new_source(&iaea_id,phsp_fname_char,&rwmode,&iaea_iostat,len);
341 if (iaea_iostat < 0) {
342 egsFatal(
"\nEGS_PhspScoring: Failed to open phase space file %s.IAEAphsp for appending.\n",phsp_fname.c_str());
348 iaea_get_max_particles(&iaea_id,&type,&nparticle);
349 if (nparticle != countprev) {
350 egsFatal(
"\nEGS_PhspScoring: Particle no. mismatch between %s.IAEAphsp and .egsdat file.\n",phsp_fname.c_str());
352 iaea_check_file_size_byte_order(&iaea_id,&iaea_iostat);
353 if (iaea_iostat != 0) {
354 egsFatal(
"\nEGS_PhspScoring: Byte order/file size mismatch in %s.IAEAphsp.\n",phsp_fname.c_str());
359 iaea_new_source(&iaea_id,phsp_fname_char,&rwmode,&iaea_iostat,len);
360 if (iaea_iostat < 0) {
361 egsFatal(
"\nEGS_PhspScoring: Failed to open phase space file %s.IAEAphsp for writing.\n",phsp_fname.c_str());
367 for (
int i=0; i<3; i++) {
368 if (xyz_is_const[i]) {
370 float constval = xyzscore[i];
371 iaea_set_constant_variable(&iaea_id,&index,&constval);
376 int latch_ind_tmp = latch_ind;
377 int iaea_n_extra_long_tmp=iaea_n_extra_long;
378 int iaea_i_latch_tmp=iaea_i_latch;
379 int time_ind_tmp = time_ind;
380 int iaea_i_time_tmp = iaea_i_time;
381 int iaea_n_extra_float_tmp=iaea_n_extra_float;
383 iaea_set_extra_numbers(&iaea_id,&iaea_n_extra_float_tmp,&iaea_n_extra_long_tmp);
384 iaea_set_type_extralong_variable(&iaea_id,&iaea_i_latch_tmp,&latch_ind_tmp);
386 iaea_set_type_extrafloat_variable(&iaea_id,&iaea_i_time_tmp,&time_ind_tmp);
393 int EGS_PhspScoring::flushBuffer()
const {
403 for (
int j=0; j<phsp_index; j++) {
406 int n_stat = p_stack[j].E < 0 ? 1 : 0;
407 float E = abs(p_stack[j].E);
409 int type = iaea_q_type[p_stack[j].q+1];
412 EGS_I32 *iaea_extra_long =
new EGS_I32[iaea_n_extra_long];
413 iaea_extra_long[iaea_i_latch]=p_stack[j].latch;
414 float *iaea_extra_float =
new float[iaea_n_extra_float];
416 iaea_extra_float[iaea_i_time] = p_stack[j].time;
420 float wt = p_stack[j].wt;
421 float x = p_stack[j].x;
422 float y = p_stack[j].y;
423 float z = p_stack[j].z;
424 float u = p_stack[j].u;
425 float v = p_stack[j].v;
426 float w = p_stack[j].w;
429 iaea_write_particle(&iaea_id,&n_stat,&type,&E,&wt,&x,&y,&z,&u,&v,&w,iaea_extra_float,iaea_extra_long);
431 egsFatal(
"\nEGS_PhspScoring: Failed to write particle data to phase space file.");
435 EGS_I64 last_case_tmp = last_case;
436 iaea_set_total_original_particles(&iaea_id,&last_case_tmp);
439 iaea_update_header(&iaea_id,&iaea_iostat);
441 egsFatal(
"\nEGS_PhspScoring: Failed to update phase space header file.");
444 else if (oformat == 0) {
446 egsFatal(
"\nEGS_PhspScoring: phase space file is not open for writing.");
449 for (
int j=0; j<phsp_index; j++) {
450 egs_phsp_write_struct ws(p_stack[j]);
451 phsp_file.write((
char *) &ws,
sizeof(ws));
454 iostream::off_type pos = (count+1)*
sizeof(egs_phsp_write_struct);
456 phsp_file.seekp(5,ios::beg);
457 unsigned int count4 = count, countg4 = countg;
458 float pinc = last_case;
460 if (countg4==count4) {
466 phsp_file.write((
char *) &count4,
sizeof(
unsigned int));
467 phsp_file.write((
char *) &countg4,
sizeof(
unsigned int));
468 phsp_file.write((
char *) &emax,
sizeof(float));
469 phsp_file.write((
char *) &emintmp,
sizeof(float));
470 phsp_file.write((
char *) &pinc,
sizeof(float));
471 phsp_file.seekp(pos,ios::beg);
479 bool EGS_PhspScoring::storeState(ostream &data)
const {
491 bool EGS_PhspScoring::setState(istream &data) {
503 bool EGS_PhspScoring::addState(istream &data) {
525 const static char *func =
"createAusgabObject(phsp_scoring)";
533 vector <int> from_reg, to_reg;
540 bool xyzisconst[3] = {
false,
false,
false};
543 int err01 = input->
getInput(
"phase space geometry",gname);
550 egsWarning(
"\nEGS_PhspScoring: %s does not name an existing geometry.\n"
551 "Will assume you want to use exit/entry region pairs.\n",gname.c_str());
555 if (input->
getInput(
"score particles on", str) < 0) {
556 egsInformation(
"EGS_PhspScoring: No input for scoring direction.\n");
557 egsInformation(
"Will score on entry and exit from phase space geometry.\n");
562 vector<string> allowed_sdir;
563 allowed_sdir.push_back(
"entry and exit");
564 allowed_sdir.push_back(
"entry");
565 allowed_sdir.push_back(
"exit");
566 sdir = input->
getInput(
"score particles on",allowed_sdir,-1);
568 egsFatal(
"\nEGS_PhspScoring: Invalid scoring direction.\n");
575 int err05 = input->
getInput(
"from regions",from_reg);
576 int err06 = input->
getInput(
"to regions",to_reg);
577 if (err05 || err06) {
578 egsFatal(
"\nEGS_PhspScoring: Missing/incorrect input for scoring method\n"
579 "(scoring geometry or pairs of exit/entry regions)\n");
583 vector<int>::iterator p,p1;
584 if (from_reg.size() > to_reg.size()) {
585 p = from_reg.begin();
586 egsWarning(
"\nEGS_PhspScoring: Mismatch in no. of exit/entry regions.\n"
587 "Will only score for matched pairs.\n");
589 from_reg.erase(p,p+from_reg.size()-to_reg.size());
591 else if (to_reg.size() > from_reg.size()) {
593 egsWarning(
"\nEGS_PhspScoring: Mismatch in no. of exit/entry regions.\n"
594 "Will only score for matched pairs.\n");
595 p += from_reg.size();
596 to_reg.erase(p,p+to_reg.size()-from_reg.size());
600 while (i<from_reg.size()) {
601 if (from_reg[i]==to_reg[i]) {
602 egsInformation(
"\nEGS_PhspScoring: Cannot have entry region = exit region (reg no. %d)\n",from_reg[i]);
604 p=from_reg.begin()+i;
605 p1 =to_reg.begin()+i;
617 if (input->
getInput(
"output format", str) < 0) {
618 egsInformation(
"EGS_PhspScoring: No input for output format type. Will default to EGSnrc.\n");
622 vector<string> allowed_oformat;
623 allowed_oformat.push_back(
"EGSnrc");
624 allowed_oformat.push_back(
"IAEA");
625 phspouttype = input->
getInput(
"output format", allowed_oformat, -1);
626 if (phspouttype < 0) {
627 egsFatal(
"\nEGS_PhspScoring: Invalid output format.\n");
630 if (phspouttype == 1) {
631 int err02 = input->
getInput(
"constant X",xyzconst[0]);
632 int err03 = input->
getInput(
"constant Y",xyzconst[1]);
633 int err04 = input->
getInput(
"constant Z",xyzconst[2]);
635 xyzisconst[0] =
true;
638 xyzisconst[1] =
true;
641 xyzisconst[2] =
true;
646 if (!input->
getInput(
"score mu", str)) {
647 vector<string> allowed_timescore;
648 allowed_timescore.push_back(
"no");
649 allowed_timescore.push_back(
"yes");
650 itimescore = input->
getInput(
"score mu",allowed_timescore,-1);
651 if (itimescore < 0) {
652 egsWarning(
"\nEGS_PhspScoring: Invalid input for time index scoring. Will not score time.\n");
657 if (!input->
getInput(
"score time index", str)) {
658 vector<string> allowed_timescore;
659 allowed_timescore.push_back(
"no");
660 allowed_timescore.push_back(
"yes");
661 itimescore = input->
getInput(
"score time index",allowed_timescore,-1);
662 if (itimescore < 0) {
663 egsWarning(
"\nEGS_PhspScoring: Invalid input for time index scoring. Will not score time.\n");
669 if (phspouttype == 0) {
671 if (!input->
getInput(
"score multiple crossers", str)) {
672 vector<string> allowed_scoremc;
673 allowed_scoremc.push_back(
"no");
674 allowed_scoremc.push_back(
"yes");
675 iscoremc = input->
getInput(
"score multiple crossers",allowed_scoremc,-1);
677 egsWarning(
"\nEGS_PhspScoring: Invalid input for score multiple crossers. Will not score.\n");
682 if (input->
getInput(
"output directory",outdir) < 0) {
685 if (input->
getInput(
"particle type", str) < 0) {
686 egsInformation(
"EGS_PhspScoring: No input for particle type. Will score all.\n");
691 vector<string> allowed_ptype;
692 allowed_ptype.push_back(
"all");
693 allowed_ptype.push_back(
"photons");
694 allowed_ptype.push_back(
"charged");
695 ptype = input->
getInput(
"particle type",allowed_ptype,-1);
697 egsFatal(
"\nEGS_PhspScoring: Invalid particle type.\n");
707 result->setGeom(phspgeom);
710 result->setEntryExitReg(from_reg,to_reg);
712 result->setOType(phspouttype);
713 result->setXYZconst(xyzisconst,xyzconst);
714 result->setOutDir(outdir);
715 result->setParticleType(ptype);
716 result->setScoreDir(sdir);
717 result->setTimeScore(itimescore);
718 result->setScoreMC(iscoremc);
Base class for advanced EGSnrc C++ applications.
int getNparallel() const
Returns the number of parallel jobs executing.
EGS_Float getTimeIndex()
Returns the value of the time synchronization parameter.
const string & getAppDir() const
Returns the absolute path to the user code directory.
int getIparallel() const
Returns the job number in a parallel run.
EGS_Particle top_p
The top particle on the stack (i.e., the particle being transported)
virtual void setApplication(EGS_Application *App)
Set the application this object belongs to.
string description
A short ausgab object description.
EGS_Application * app
The application this object belongs to.
Base geometry class. Every geometry class must be derived from EGS_BaseGeometry.
const string & getName() const
Get the name of this geometry.
static EGS_BaseGeometry * getGeometry(const string &Name)
Get a pointer to the geometry named Name.
void setName(EGS_Input *inp)
Set the name of the object from the information provided by inp.
const string & getObjectName() const
Get the object name.
string name
The object name.
A phase space scoring object: header.
Global egspp functions header file.
A phase space scoring ausgab object.
EGS_RADIATIVE_SPLITTING_EXPORT EGS_AusgabObject * createAusgabObject(EGS_Input *input, EGS_ObjectFactory *f)
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,...
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.
EGS_Float E
particle energy in MeV
int latch
latch variable (useful as a flag on many occasions)
EGS_Float wt
statistical weight