EGS Brachy
An egs++ user code for rapid brachytherapy calculations
Loading...
Searching...
No Matches
/Users/marc/Developer/EGSnrc/HEN_HOUSE/user_codes/egs_brachy/egs_brachy/phsp.cpp
Go to the documentation of this file.
1/*
2################################################################################
3#
4# egs_brachy phsp.cpp
5# Copyright (C) 2016 Rowan Thomson, Dave Rogers, Randle Taylor, and Marc
6# Chamberland
7#
8# This file is part of egs_brachy
9#
10# egs_brachy is free software: you can redistribute it and/or modify it
11# under the terms of the GNU Affero General Public License as published
12# by the Free Software Foundation, either version 3 of the License, or
13# (at your option) any later version.
14#
15# egs_brachy is distributed in the hope that it will be useful, but
16# WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18# Affero General Public License for more details:
19# <http://www.gnu.org/licenses/>.
20#
21################################################################################
22#
23# When egs_brachy is used for publications, please cite our paper:
24# M. J. P. Chamberland, R. E. P. Taylor, D. W. O. Rogers, and R. M. Thomson,
25# egs brachy: a versatile and fast Monte Carlo code for brachytherapy,
26# Phys. Med. Biol. 61, 8214-8231 (2016).
27#
28################################################################################
29#
30# Author: Randle Taylor, 2016
31#
32# Contributors: Marc Chamberland
33# Dave Rogers
34# Rowan Thomson
35#
36################################################################################
37*/
38
44#include "phsp.h"
45#include <sys/types.h>
46#include <sys/stat.h>
47#include "egs_interface2.h"
48#include "iaea_header.h"
49
51bool dirExists(string path) {
52
53 struct stat info;
54 int res = stat(path.c_str(), &info);
55 return res == 0 && (info.st_mode & S_IFDIR);
56}
57
58
59PHSPControl::PHSPControl(EGS_Input *inp, EGS_AffineTransform *trans, EGS_AdvancedApplication *app, Publisher *pub):
60 num_written(0), transform(trans), boundary_step(1E-4) {
61
62 id = 1;
63
64 string dir;
65 int err = inp->getInput("phsp output directory", dir);
66 if (err) {
67 dir = egsJoinPath(app->getAppDir(), app->getWorkDir());
68 }
69
70 if (!dirExists(dir)) {
71 egsFatal("PHSPControl:: unable to access directory %s\n", dir.c_str());
72 }
73
74 fname = egsJoinPath(dir, app->getOutputFile())+".phsp";
75
76 vector<string> yn_choices;
77 yn_choices.push_back("no");
78 yn_choices.push_back("yes");
79 kill_after_scoring = (bool)inp->getInput("kill after scoring", yn_choices, 0);
80 print_header = (bool)inp->getInput("print header", yn_choices, 0);
81
82 err = inp->getInput("boundary step", boundary_step);
83
84
85 vector<string> access_choices;
86 access_choices.push_back("append");
87 access_choices.push_back("write");
88 int imode = inp->getInput("access mode", access_choices, 0);
89 if (imode == 0) {
90 mode = APPEND;
91 } else if (imode == 1) {
92 mode = WRITE;
93 } else {
94 egsFatal("PHSPControl:: unknown access mode\n");
95 }
96
97 initSource();
98
100}
101
102
103short PHSPControl::getIAEAParticleType(const EGS_Particle *p) {
104
105 if (p->q == 0) {
106 return PHOTON;
107 } else if (p->q == -1) {
108 return ELECTRON;
109 } else if (p->q == 1) {
110 return POSITRON;
111 }
112
113 egsFatal("PHSPControl::Tried to write unknown particle type\n");
114 return -1;
115}
116
117void PHSPControl::writeParticle(EGS_Particle *p) {
118
119
120 // first move back to non transformed location
121 EGS_Vector new_loc(p->x);
122 EGS_Vector new_dir(p->u);
123 EGS_Vector new_dir_norm(p->u);
124
125 new_dir_norm.normalize();
126 transform->transform(new_loc);
127 transform->rotate(new_dir);
128
129 // take very small step so we are ensured to be outside source geom
130 new_loc += boundary_step*new_dir_norm;
131
132
133 // if particles haven't been split by brem splitting they
134 // should be statistically independent when leaving source
135 IAEA_I32 n_stat = p->wt < 1. ? 0 : 1;
136
137 const IAEA_I32 type = getIAEAParticleType(p);
138 const IAEA_Float E = (IAEA_Float)p->E,
139 wt = (IAEA_Float)p->wt,
140 x = (IAEA_Float)new_loc.x,
141 y = (IAEA_Float)new_loc.y,
142 z = (IAEA_Float)new_loc.z,
143 u = (IAEA_Float)new_dir.x,
144 v = (IAEA_Float)new_dir.y,
145 w = (IAEA_Float)new_dir.z;
146
147 const IAEA_Float extra_float = 0.;
148 const IAEA_I32 extra_int = 0;
149
150 iaea_write_particle(&id, &n_stat, &type, &E, &wt, &x, &y, &z, &u, &v, &w, &extra_float, &extra_int);
151
152 num_written++;
153
154 if (kill_after_scoring) {
155 p->wt = 0.;
156 int np = the_stack->np - 1;
157 the_stack->wt[np] = 0;
158 }
159
160}
161
162
164
165 char *hname = new char[fname.size()+1];
166 copy(fname.begin(), fname.end(), hname);
167 hname[fname.size()] = '\0';
168
169 IAEA_I32 iaea_idx;
170 iaea_new_source(&id, hname, &mode, &iaea_idx, fname.size());
171
172 // we're not currently writing any extra parameters
173 IAEA_I32 n_extra_float=0, n_extra_int=0;
174 iaea_set_extra_numbers(&id, &n_extra_float, &n_extra_int);
175
176 if (iaea_idx < 0) {
177 egsFatal("PHSPControl:: failed to initialize source with IAEA error %d\n", iaea_idx);
178 }
179
180 delete[] hname;
181
182}
183
184
185void PHSPControl::update(EB_Message message, void *particle) {
186 if (message == PARTICLE_ESCAPED_SOURCE) {
187 EGS_Particle *p = static_cast<EGS_Particle *>(particle);
188 writeParticle(p);
189 }
190}
191
192
193void PHSPControl::finish(EGS_I64 n_orig_particles) {
194 IAEA_I64 n_orig = n_orig_particles;
195 iaea_set_total_original_particles(&id, &n_orig);
196}
197
198
200
201 string sep(80, '=');
202
203 IAEA_I64 n_particles;
204 IAEA_I32 particle_type = ALL_TYPES;
205
206 IAEA_I32 result;
207
208 iaea_get_max_particles(&id, &particle_type, &n_particles);
209
210 egsInformation("\n\nPHSP File Scoring\n%s\n", sep.c_str());
211 egsInformation("\nOutput file : %s", (fname+".*").c_str());
212 egsInformation("\nNew Particles written : %d", num_written);
213 egsInformation("\nTotal Particles : %d", n_particles);
214 egsInformation("\nBoundary Step (cm) : %.2G", boundary_step);
215 if (print_header) {
216 iaea_print_header(&id, &result);
217 }
218
219}
220
222 IAEA_I32 result;
223 iaea_destroy_source(&id, &result);
224}
225
bool kill_after_scoring
Set wt = 0 for particle after scoring if true.
Definition phsp.h:82
void initSource()
create/open new source and set extra numbers
Definition phsp.cpp:163
@ APPEND
IAEA Append mode.
Definition phsp.h:56
@ WRITE
IAEA Write mode.
Definition phsp.h:55
EGS_AffineTransform * transform
Definition phsp.h:75
void outputResults()
output file name and number of particles written
Definition phsp.cpp:199
void finish(EGS_I64 n_orig_particles)
set final number of particles written and destroy source
Definition phsp.cpp:193
void update(EB_Message message, void *particle)
receive PARTICLE_ESCAPED_SOURCE message
Definition phsp.cpp:185
void writeParticle(EGS_Particle *p)
write a single particle to the phsp
Definition phsp.cpp:117
IAEA_I32 mode
Access mode.
Definition phsp.h:68
bool print_header
User has requested the phsp header gets printed after run.
Definition phsp.h:84
short getIAEAParticleType(const EGS_Particle *p)
convert a particle to its IAEA Particle type
Definition phsp.cpp:103
@ ALL_TYPES
Definition phsp.h:60
@ PHOTON
Definition phsp.h:61
@ ELECTRON
Definition phsp.h:62
@ POSITRON
Definition phsp.h:63
void destroySource()
destroy the source
Definition phsp.cpp:221
string fname
root name of phsp header
Definition phsp.h:69
IAEA_I64 num_written
Number of particles written to phsp file.
Definition phsp.h:72
EGS_Float boundary_step
Definition phsp.h:78
PHSPControl(EGS_Input *inp, EGS_AffineTransform *trans, EGS_AdvancedApplication *app, Publisher *pub)
PHSP Control constructor.
Definition phsp.cpp:59
void subscribe(Subscriber *s, EB_Message message)
Definition pubsub.h:83
bool dirExists(string path)
return true if input path is an existing directory
Definition phsp.cpp:51
Definition of the PHSPControl object.
EB_Message
Definition pubsub.h:54
@ PARTICLE_ESCAPED_SOURCE
Definition pubsub.h:61