EGSnrc C++ class library  Report PIRS-898 (2021)
Iwan Kawrakow, Ernesto Mainegra-Hing, Frederic Tessier, Reid Townson and Blake Walters
egs_phsp_scoring.h
Go to the documentation of this file.
1 /*
2 ###############################################################################
3 #
4 # EGSnrc egs++ phase space scoring object headers
5 # Copyright (C) 2015 National Research Council Canada
6 #
7 # This file is part of EGSnrc.
8 #
9 # EGSnrc is free software: you can redistribute it and/or modify it under
10 # the terms of the GNU Affero General Public License as published by the
11 # Free Software Foundation, either version 3 of the License, or (at your
12 # option) any later version.
13 #
14 # EGSnrc is distributed in the hope that it will be useful, but WITHOUT ANY
15 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
17 # more details.
18 #
19 # You should have received a copy of the GNU Affero General Public License
20 # along with EGSnrc. If not, see <http://www.gnu.org/licenses/>.
21 #
22 ###############################################################################
23 #
24 # Author: Blake Walters, 2018
25 #
26 # Contributors:
27 #
28 ###############################################################################
29 */
30 
31 
37 #ifndef EGS_PHSP_SCORING_
38 #define EGS_PHSP_SCORING_
39 
40 #include "egs_ausgab_object.h"
41 #include "egs_application.h"
42 #include "egs_scoring.h"
43 #include "egs_base_geometry.h"
44 
45 #ifdef WIN32
46 
47  #ifdef BUILD_PHSP_SCORING_DLL
48  #define EGS_PHSP_SCORING_EXPORT __declspec(dllexport)
49  #else
50  #define EGS_PHSP_SCORING_EXPORT __declspec(dllimport)
51  #endif
52  #define EGS_PHSP_SCORING_LOCAL
53 
54 #else
55 
56  #ifdef HAVE_VISIBILITY
57  #define EGS_PHSP_SCORING_EXPORT __attribute__ ((visibility ("default")))
58  #define EGS_PHSP_SCORING_LOCAL __attribute__ ((visibility ("hidden")))
59  #else
60  #define EGS_PHSP_SCORING_EXPORT
61  #define EGS_PHSP_SCORING_LOCAL
62  #endif
63 
64 #endif
65 
250 class EGS_PHSP_SCORING_EXPORT EGS_PhspScoring : public EGS_AusgabObject {
251 
252 public:
253 
254  EGS_PhspScoring(const string &Name="", EGS_ObjectFactory *f = 0);
255 
256  ~EGS_PhspScoring();
257 
259  //only score if particle has correct charge
260  if (ocharge==0 || 1+abs(app->top_p.q)==ocharge) {
261  EGS_Vector x = app->top_p.x;
262  int ir = app->top_p.ir;
263  int latch = app->top_p.latch;
264  //only score if: 1) it has not been scored before or
265  //2) we are scoring multiple crossers (EGSnrc format only)
266  if (!(latch & bsmc()) || (oformat==0 && score_mc)) {
267  if (score_type==0) { //using scoring geometry
268  if (iarg == 0) {
269  phsp_before = phsp_geom->isInside(x);
270  }
271 
272  if (iarg == 5) {
273  phsp_after = phsp_geom->isInside(x);
274  if (phsp_after != phsp_before) {
275  if (scoredir == 0 || (scoredir == 1 && phsp_after) ||
276  (scoredir == 2 && phsp_before)) {
277  storeParticle(current_case);
278  }
279  //set bit 31 to flag this as having been scored
280  latch = (latch | bsmc());
281  app->setLatch(latch);
282  return 0;
283  }
284  }
285  }
286  else if (score_type==1) { //pairs of exit/entry regions
287  if (iarg == 0) {
288  ir_before = ir;
289  }
290 
291  if (iarg == 5) {
292  ir_after = ir;
293  if (from_to[ir_before].size()>0 && ir_before != ir_after) {
294  for (int i=0; i< from_to[ir_before].size(); i++) {
295  if (ir_after == from_to[ir_before][i]) {
296  storeParticle(current_case);
297  latch = (latch | bsmc());
298  app->setLatch(latch);
299  return 0;
300  }
301  }
302  }
303  }
304  }
305  }
306  }
307  return 0;
308  };
309 
310  int processEvent(EGS_Application::AusgabCall iarg, int ir) {
311  //same as above, we don't need the region no.
312  if (ocharge==0 || 1+abs(app->top_p.q)==ocharge) {
313  EGS_Vector x = app->top_p.x;
314  int latch = app->top_p.latch;
315  //only score if: 1) it has not been scored before or
316  //2) we are scoring multiple crossers (EGSnrc format only)
317  if (!(latch & bsmc()) || (oformat==0 && score_mc)) {
318  if (score_type==0) { //using scoring geometry
319  if (iarg == 0) {
320  phsp_before = phsp_geom->isInside(x);
321  }
322 
323  if (iarg == 5) {
324  phsp_after = phsp_geom->isInside(x);
325  if (phsp_after != phsp_before) {
326  if (scoredir == 0 || (scoredir == 1 && phsp_after) ||
327  (scoredir == 2 && phsp_before)) {
328  storeParticle(current_case);
329  }
330  //set bit 31 to flag this as having been scored
331  latch = (latch | bsmc());
332  app->setLatch(latch);
333  return 0;
334  }
335  }
336  }
337  else if (score_type==1) { //pairs of exit/entry regions
338  if (iarg == 0) {
339  ir_before = ir;
340  }
341 
342  if (iarg == 5) {
343  ir_after = ir;
344  if (from_to[ir_before].size()>0 && ir_before != ir_after) {
345  for (int i=0; i< from_to[ir_before].size(); i++) {
346  if (ir_after == from_to[ir_before][i]) {
347  storeParticle(current_case);
348  latch = (latch | bsmc());
349  app->setLatch(latch);
350  return 0;
351  }
352  }
353  }
354  }
355  }
356  }
357  }
358  return 0;
359  };
360 
361  bool needsCall(EGS_Application::AusgabCall iarg) const {
362  if (iarg == 0 || iarg == 5) {
363  return true;
364  }
365  else {
366  return false;
367  }
368  };
369 
370  //below gets called from startNewShower if current_case != last_case
371  //don't update last_case yet
372  void setCurrentCase(EGS_I64 ncase) {
373  current_case=ncase;
374  };
375 
376  void setGeom(EGS_BaseGeometry *phspgeom) {
377  score_type=0;
378  phsp_geom = phspgeom;
379  }
380 
381  void setEntryExitReg(const vector <int> from_reg, const vector <int> to_reg) {
382  score_type=1;
383  fromreg=from_reg;
384  toreg=to_reg;
385  }
386 
387  void setOType(const int phspouttype) {
388  oformat = phspouttype;
389  }
390 
391  //set output directory
392  void setOutDir(const string outdir) {
393  phspoutdir = outdir;
394  }
395 
396  void setParticleType(const int ptype) {
397  ocharge = ptype;
398  }
399 
400  void setScoreDir(const int sdir) {
401  scoredir = sdir;
402  }
403 
404  void setMuScore(const int imuscore) {
405  if (imuscore == 1) {
406  score_mu = true;
407  }
408  else {
409  score_mu = false;
410  }
411  }
412 
413  void setScoreMC(const int iscoremc) {
414  if (iscoremc==1) {
415  score_mc = true;
416  }
417  else {
418  score_mc = false;
419  }
420  }
421 
422  //method below pertains only to IAEA format
423  //set array element 0/1/2 of xyz_is_constant equal to true
424  //if scoring at a constant X/Y/Z value and store the
425  //constant value in element 0/1/2 of array xyzscore
426  void setXYZconst(bool xyzisconst[3], float xyzconst[3]) {
427  for (int i=0; i<3; i++) {
428  xyz_is_const[i] = xyzisconst[i];
429  xyzscore[i]=xyzconst[i];
430  }
431  }
432 
433  void storeParticle(EGS_I64 ncase);
434 
435  int flushBuffer() const;
436 
437  void openPhspFile() const;
438 
439  void setApplication(EGS_Application *App);
440 
441  void reportResults();
442 
443  bool storeState(ostream &data) const;
444  bool setState(istream &data);
445  bool addState(istream &data);
446 
447 protected:
448 
449  struct Particle {
450  int q, latch;
451  EGS_Float E, x, y, z, u, v, w, wt, mu;
452  };
453 
454  //functions, struct and variables used to write EGSnrc format phsp files
455  static unsigned int bclr() {
456  return ~((1 << 30) | (1 << 29));
457  }
458  static unsigned int bsqe() {
459  return (1 << 30);
460  }
461  static unsigned int bsqp() {
462  return (1 << 29);
463  }
465  int latch;
466  float E;
467  float x,y;
468  float u,v;
469  float wt;
471  egs_phsp_write_struct(const Particle &p) {
472  latch = (p.latch & bclr());
473  if (p.q == -1) {
474  latch = (latch | bsqe());
475  }
476  else if (p.q == 1) {
477  latch = (latch | bsqp());
478  }
479  E = p.E;
480  x = p.x;
481  y = p.y;
482  u = p.u;
483  v = p.v;
484  wt = p.w >= 0 ? p.wt : -p.wt;
485  };
486  };
487 
488  bool score_mc; //set to true to score multiple crossers and their descendents
489 
490  //variables specific to IAEA format
491  mutable int iaea_id; //file id--mutable so we can write to it during storeState
492  int latch_ind; //IAEA id for latch variable (set to 2)
493  int mu_ind; //IAEA id for mu--no ID for now so set to generic float (0)
494  int iaea_n_extra_float, iaea_n_extra_long; //no. of extra floats, ints
495  int iaea_i_latch, iaea_i_mu; //indices of indicated variables in arrays
496  int iaea_q_type[3]; //easy conversion from q to iaea type
497  bool xyz_is_const[3]; //set to true if scoring at constant X/Y/Z
498  float xyzscore[3]; //constant X/Y/Z scoring values
499  int len; //length of name
500  char *phsp_fname_char; //need file name in char format
501  bool score_mu; //set to true if scoring mu
502  float pmu; //mu value associated with particle
503 
504  //back to variables common to EGSnrc and IAEA formats
505 
506  Particle *p_stack; //the stored particle stack
507 
508  //below used to set bit 31 to denote the particle has been scored
509  static unsigned int bsmc() {
510  return (1 << 31);
511  }
512 
513  mutable int phsp_index; //index in p_stack array -- mutable so we can change it in storeState
514  int store_max; //max. no. of particles to store in p_stack
515  mutable fstream phsp_file; //output file -- mutable so we can write to it during storeState
516  EGS_I64 count; //total no. of particles in file
517  EGS_I64 countg; //no. of photons in file
518  float emin; //min. k.e. of charged particles in file
519  float emax; //max. k.e. of particles in phsp file
520  mutable bool first_flush; //first time writing to file in this run -- mutable so we can change it in storeState
521 
522  bool is_restart; //true if this is a restart
523  EGS_I64 countprev; //no. of particles written to file before restart
524 
525  EGS_I64 last_case; //last primary history scored
526  EGS_I64 current_case; //current primary history
527 
528  int oformat; //0 for EGSnrc format, 1 for IAEA format
529 
530  int ocharge; //particle type for output: 0--all; 1--photons; 2--charged particles
531 
532  string phsp_fname; //name of phase space file
533 
534  string phspoutdir; //output directory
535 
536  int score_type; //0 if scoring on exiting/entering a phase space geometry
537  //1 if using pairs of exit/entry regions
538 
539  //for method 1: scoring using predefined geometry
540  EGS_BaseGeometry *phsp_geom; //geometry on entrance to/exit from which phase space data is scored
541  int scoredir; //scoring direction: 0--on entry and exit; 1--on entry; 2--on exit
542  bool phsp_before; //true if inside scoring geometry before step
543  bool phsp_after; //true if inside scoring geometry after step
544 
545  //for method 2: scoring using exit/entry region pairs
546  vector <int> fromreg; //array of exit regions
547  vector <int> toreg; //array of entry regions
548  vector <vector <int> > from_to; //from a given global exit region, an array of possible entry regions
549  int ir_before, ir_after; //reg. no. before and after step
550 };
551 
552 #endif
A phase space scoring object: header.
EGS_AusgabObject interface class header file.
virtual int processEvent(EGS_Application::AusgabCall iarg)=0
Process an ausgab call for event iarg.
virtual bool storeState(ostream &data_out) const
Store the source state into the stream data_out.
AusgabCall
Possible calls to the user scoring function ausgab().
A class representing 3D vectors.
Definition: egs_vector.h:56
Base geometry class. Every geometry class must be derived from EGS_BaseGeometry.
virtual bool needsCall(EGS_Application::AusgabCall iarg) const
Is the ausgab call iarg relevant for this object?
virtual bool setState(istream &data_in)
Set the ausgab object state based on data from the stream data_in.
virtual void reportResults()
Report results.
An object factory.
EGS_Float x
x-component
Definition: egs_vector.h:60
virtual bool addState(istream &data_in)
Add data from the stream data_in to the ausgab object state.
EGS_ScoringSingle and EGS_ScoringArray class header file.
EGS_BaseGeometry class header file.
virtual void setCurrentCase(EGS_I64 ncase)
Set the current event.
virtual void setApplication(EGS_Application *App)
Set the application this object belongs to.
EGS_Application class header file.
Base class for advanced EGSnrc C++ applications.