EGSnrc C++ class library  Report PIRS-898 (2021)
Iwan Kawrakow, Ernesto Mainegra-Hing, Frederic Tessier, Reid Townson and Blake Walters
egs_conical_shell.cpp
Go to the documentation of this file.
1 /*
2 ###############################################################################
3 #
4 # EGSnrc egs++ conical shell shape
5 # Copyright (C) 2016 Randle E. P. Taylor, Rowan M. Thomson,
6 # Marc J. P. Chamberland, D. W. O. Rogers
7 #
8 # This file is part of EGSnrc.
9 #
10 # EGSnrc is free software: you can redistribute it and/or modify it under
11 # the terms of the GNU Affero General Public License as published by the
12 # Free Software Foundation, either version 3 of the License, or (at your
13 # option) any later version.
14 #
15 # EGSnrc is distributed in the hope that it will be useful, but WITHOUT ANY
16 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
18 # more details.
19 #
20 # You should have received a copy of the GNU Affero General Public License
21 # along with EGSnrc. If not, see <http://www.gnu.org/licenses/>.
22 #
23 ###############################################################################
24 #
25 # Author: Randle Taylor, 2016
26 #
27 # Contributors: Marc Chamberland
28 # Rowan Thomson
29 # Dave Rogers
30 #
31 ###############################################################################
32 #
33 # egs_conical_shell was developed for the Carleton Laboratory for
34 # Radiotherapy Physics.
35 #
36 ###############################################################################
37 */
38 
39 
45 #include "egs_conical_shell.h"
46 #include "egs_input.h"
47 #include "egs_functions.h"
48 #include <iostream>
49 #include <fstream>
50 
51 
52 CSSSLayer::CSSSLayer(EGS_Float t, EGS_Float rit, EGS_Float rot, EGS_Float rib, EGS_Float rob, EGS_Float z):
53  thick(t), ri_top(rit), ro_top(rot), ri_bot(rib), ro_bot(rob), zo(z) {
54 
55  ro_max = max(ro_top, ro_bot);
56  ro_min = min(ro_top, ro_bot);
57 
58  ri_max = max(ri_top, ri_bot);
59  ri_min = min(ri_top, ri_bot);
60 
61  o_slope = (ro_bot - ro_top)/thick;
62  i_slope = (ri_bot - ri_top)/thick;
63 
64  const_width = ((ro_bot - ri_bot) - (ro_top - ri_top)) < 1E-5;
65 
66  vout = M_PI/3.*(3*ro_max+thick*fabs(o_slope))*thick*thick*fabs(o_slope);
67  vout += M_PI*ro_min*ro_min*thick;
68 
69  vin = M_PI/3.*(3*ri_max+thick*fabs(i_slope))*thick*thick*fabs(i_slope);
70  vin += M_PI*ri_min*ri_min*thick;
71 
72  volume = vout - vin;
73 
74 }
75 
76 EGS_Vector CSSSLayer::getPoint(EGS_RandomGenerator *rndm) {
77 
78  EGS_Float r, z;
79 
80  if (const_width) {
81  getRZEqualWidth(rndm, r, z);
82  }
83  else {
84  getRZRejection(rndm, r, z);
85 
86  }
87 
88  EGS_Vector point = getPointInCircleAtZ(rndm, r, z);
89  point.z += zo;
90  return point;
91 }
92 
93 void CSSSLayer::getRZEqualWidth(EGS_RandomGenerator *rndm, EGS_Float &r, EGS_Float &z) {
94 
95  z = thick*(rndm->getUniform());
96  EGS_Float ri = getRiAtZ(z);
97  EGS_Float ro = getRoAtZ(z);
98  r = ri+(ro-ri)*sqrt(rndm->getUniform());
99 }
100 
101 void CSSSLayer::getRZRejection(EGS_RandomGenerator *rndm, EGS_Float &r, EGS_Float &z) {
102 
103  int count = 0;
104 
105  while (1) {
106  z = thick*(rndm->getUniform());
107  r = ri_min+(ro_max-ri_min)*rndm->getUniform();
108 
109  if (r <= getRoAtZ(z) && r >= getRiAtZ(z)) {
110  EGS_Vector point = getPointInCircleAtZ(rndm, r, z);
111  point.z += zo;
112  return;
113  }
114 
115  if (count++ > 1000) {
116  egsWarning("egs_conical_shell: Less than .1%% of random points are being accepted");
117  }
118 
119  }
120 
121 }
122 
123 
124 EGS_Vector CSSSLayer::getPointInCircleAtZ(EGS_RandomGenerator *rndm, EGS_Float r, EGS_Float z) {
125 
126  EGS_Float cphi, sphi;
127  rndm->getAzimuth(cphi,sphi);
128  return EGS_Vector(r*cphi, r*sphi, z);
129 
130 };
131 
132 EGS_Float CSSSLayer::getRoAtZ(EGS_Float z) {
133  return o_slope*z+ro_top;
134 }
135 
136 EGS_Float CSSSLayer::getRiAtZ(EGS_Float z) {
137  return i_slope*z+ri_top;
138 }
139 
140 
141 
144  EGS_BaseShape(Name, f), layer_sampler(0), xo(Xo) {
145  otype = "conicalShellStack";
146  total_thick = 0;
147 };
148 
151 
152  int lyr= layer_sampler->sample(rndm) ;
153  CSSSLayer *layer = layers[lyr];
154  EGS_Vector point = layer->getPoint(rndm);
155  return xo + point;
156 
157 };
158 
159 void EGS_ConicalShellStackShape::addLayer(EGS_Float thick,
160  EGS_Float ri_top, EGS_Float ro_top, EGS_Float ri_bot,EGS_Float ro_bot) {
161 
162  CSSSLayer *layer = new CSSSLayer(thick, ri_top, ro_top, ri_bot, ro_bot, total_thick);
163  layers.push_back(layer);
164  total_thick += thick;
165 
166  volumes.push_back(layer->volume);
167 
168  setLayerSampler();
169 
170 }
171 
172 
173 void EGS_ConicalShellStackShape::addLayer(EGS_Float thick, EGS_Float ri_bot,EGS_Float ro_bot) {
174 
175  EGS_Float ri_top = layers[layers.size()-1]->ri_bot;
176  EGS_Float ro_top = layers[layers.size()-1]->ro_bot;
177 
178  addLayer(thick, ri_top, ro_top, ri_bot, ro_bot);
179 
180 }
181 
182 void EGS_ConicalShellStackShape::setLayerSampler() {
183 
184  if (layer_sampler) {
185  delete layer_sampler;
186  }
187 
188  layer_sampler = new EGS_SimpleAliasTable(volumes.size(), &volumes[0]);
189 }
190 
191 
192 extern "C" {
193 
194  EGS_CONICAL_SHELL_EXPORT EGS_BaseShape *createShape(EGS_Input *input, EGS_ObjectFactory *f) {
195 
196  if (!input) {
197  egsWarning("createShape(conicalShell): null input?\n");
198  return 0;
199  }
200 
201 
202  vector<EGS_Float> xo;
203  int err = input->getInput("midpoint", xo);
204  if (err || xo.size() != 3) {
205  xo.clear();
206  xo.push_back(0);
207  xo.push_back(0);
208  xo.push_back(0);
209  }
210 
211  EGS_ConicalShellStackShape *result = new EGS_ConicalShellStackShape(EGS_Vector(xo[0],xo[1],xo[2]));
212  result->setName(input);
213 
214  EGS_Input *layer;
215  int nl = 0;
216  while ((layer = input->takeInputItem("layer"))) {
217  vector<EGS_Float> rtop, rbot;
218  EGS_Float thick;
219  err = layer->getInput("thickness", thick);
220  if (err) {
221  egsWarning(
222  "createShape(EGS_ConicalShellStackShape): missing 'thickness'"
223  " input for layer %d\n --> layer ignored\n", nl
224  );
225  }
226  else {
227 
228  err = layer->getInput("top radii",rtop);
229  if (err && nl==0) {
230  egsWarning("createGeometry(EGS_ConeStack): missing 'top radii' input for 1st layer\n");
231  }
232  else {
233  err=0;
234  }
235 
236  int err1 = layer->getInput("bottom radii",rbot);
237  if (err1) {
238  egsWarning("createGeometry(EGS_ConeStack): missing 'bottom radii' input for layer %d\n",nl);
239  }
240  if (err || err1) {
241  egsWarning(" --> layer ignored\n");
242  }
243  else {
244 
245  EGS_Float rit, rot, rib, rob;
246  if (rbot.size() < 2) {
247  rib = 0;
248  rob = rbot[0];
249  }
250  else {
251  rib = rbot[0];
252  rob = rbot[1];
253  }
254 
255  if (rtop.size() == 0) {
256  result->addLayer(thick, rib, rob);
257  }
258  else if (rtop.size() < 2) {
259  rit = 0;
260  rot = rtop[0];
261  result->addLayer(thick, rit, rot, rib, rob);
262  }
263  else {
264  rit = rtop[0];
265  rot = rtop[1];
266  result->addLayer(thick, rit, rot, rib, rob);
267  }
268  }
269  }
270  delete layer;
271  ++nl;
272  }
273 
274  return result;
275  }
276 
277 }
a conical stack shell shape
EGS_Input class header file.
A class representing 3D vectors.
Definition: egs_vector.h:56
void getAzimuth(EGS_Float &cphi, EGS_Float &sphi)
Sets cphi and sphi to the cosine and sine of a random angle uniformely distributed between 0 and ...
Definition: egs_rndm.h:138
Global egspp functions header file.
int sample(EGS_RandomGenerator *rndm) const
Sample a random bin.
Base shape class. All shapes in the EGSnrc C++ class library are derived from EGS_BaseShape.
Definition: egs_shapes.h:112
A conical shell shape.
Base random number generator class. All random number generators should be derived from this class...
Definition: egs_rndm.h:67
EGS_Float z
z-component
Definition: egs_vector.h:62
A class for sampling random bins from a given probability distribution using the alias table techniqu...
An object factory.
void setName(EGS_Input *inp)
Set the name of the object from the information provided by inp.
EGS_Float getUniform()
Returns a random number uniformly distributed between zero (inclusive) and 1 (exclusive).
Definition: egs_rndm.h:103
EGS_ConicalShellStackShape(const EGS_Vector &Xo, const string &Name="", EGS_ObjectFactory *f=0)
Construct a sphere of radius r with midpoint Xo.
A class for storing information in a tree-like structure of key-value pairs. This class is used throu...
Definition: egs_input.h:182
EGS_Vector getPoint(EGS_RandomGenerator *rndm)
Returns a random point within the conical shell.
string otype
The object type.
EGS_Input * takeInputItem(const string &key, bool self=true)
Get the property named key.
Definition: egs_input.cpp:226
int getInput(const string &key, vector< string > &values) const
Assign values to an array of strings from an input identified by key.
Definition: egs_input.cpp:338
EGS_InfoFunction EGS_EXPORT egsWarning
Always use this function for reporting warnings.