EGSnrc C++ class library  Report PIRS-898 (2021)
Iwan Kawrakow, Ernesto Mainegra-Hing, Frederic Tessier, Reid Townson and Blake Walters
egs_lattice.cpp
Go to the documentation of this file.
1 /*
2 ###############################################################################
3 #
4 # EGSnrc egs++ lattice geometry
5 # Copyright (C) 2019 Rowan Thomson and Martin Martinov
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: Martin Martinov, 2019
25 #
26 # Contributors:
27 #
28 ###############################################################################
29 #
30 # When egs_lattice is used for publications, please cite the following paper:
31 #
32 # Martinov, Martin P., and Rowan M. Thomson. Taking EGSnrc to new lows:
33 # Development of egs++ lattice geometry and testing with microscopic
34 # geometries. Medical Physics 47, 3225-3232 (2020).
35 #
36 ###############################################################################
37 */
38 
39 
44 #include "egs_lattice.h"
45 #include "egs_input.h"
46 #include "egs_functions.h"
47 
48 using namespace std;
49 
50 void EGS_Lattice::setMedia(EGS_Input *,int,const int *) {
51  egsWarning("EGS_Lattice::setMedia: don't use this method. Use the\n"
52  " setMedia() methods of the geometry objects that make up this geometry\n");
53 }
54 
55 void EGS_Lattice::setRelativeRho(int start, int end, EGS_Float rho) {
56  setRelativeRho(0);
57 }
58 
59 void EGS_Lattice::setRelativeRho(EGS_Input *) {
60  egsWarning("EGS_Lattice::setRelativeRho(): don't use this method."
61  " Use the\n setRelativeRho methods of the geometry objects that make up"
62  " this geometry\n");
63 }
64 
65 void EGS_Lattice::setBScaling(int start, int end, EGS_Float bf) {
66  setBScaling(0);
67 }
68 
69 void EGS_Lattice::setBScaling(EGS_Input *) {
70  egsWarning("EGS_Lattice::setBScaling(): don't use this method. "
71  "Use the\n setBScaling() methods of the geometry objects that make "
72  "up this geometry\n");
73 }
74 
75 EGS_Lattice::EGS_Lattice(EGS_BaseGeometry *B, EGS_BaseGeometry *S, int i, EGS_Float x,
76  EGS_Float y, EGS_Float z, const string &Name)
77  : EGS_BaseGeometry(Name), base(B),
78  sub(new EGS_TransformedGeometry(S,EGS_Vector(0,0,0))),
79  ind(i), a(x), b(y), c(z) {
80  type = base->getType();
81  type += " with a lattice of ";
82  type += sub->getType();
83  nreg = base->regions() + sub->regions();
84  has_rho_scaling = base->hasRhoScaling();
85  maxStep = base->regions()+1000000*sub->regions(); // Arbitrary step-length because I can't
86 }; // think of an elegant way to do this
87 
88 EGS_Lattice::~EGS_Lattice() {
89  if (!sub->deref()) {
90  delete sub;
91  }
92  if (!base->deref()) {
93  delete base;
94  }
95 };
96 
97 void EGS_Lattice::printInfo() const {
99  egsInformation(" base geometry = %s (type %s)\n",base->getName().c_str(),
100  base->getType().c_str());
101  egsInformation(" lattice subgeometry = %s (type %s)\n",sub->getName().c_str(),
102  sub->getType().c_str());
103  egsInformation(" lattice region %d with an (x,y,z) spacing of (%d,%d,%d)",
104  ind,a,b,c);
105  egsInformation("=======================================================\n");
106 }
107 
108 void EGS_Hexagonal_Lattice::setMedia(EGS_Input *,int,const int *) {
109  egsWarning("EGS_Hexagonal_Lattice::setMedia: don't use this method. Use the\n"
110  " setMedia() methods of the geometry objects that make up this geometry\n");
111 }
112 
113 void EGS_Hexagonal_Lattice::setRelativeRho(int start, int end, EGS_Float rho) {
114  setRelativeRho(0);
115 }
116 
117 void EGS_Hexagonal_Lattice::setRelativeRho(EGS_Input *) {
118  egsWarning("EGS_Hexagonal_Lattice::setRelativeRho(): don't use this method."
119  " Use the\n setRelativeRho methods of the geometry objects that make up"
120  " this geometry\n");
121 }
122 
123 void EGS_Hexagonal_Lattice::setBScaling(int start, int end, EGS_Float bf) {
124  setBScaling(0);
125 }
126 
127 void EGS_Hexagonal_Lattice::setBScaling(EGS_Input *) {
128  egsWarning("EGS_Hexagonal_Lattice::setBScaling(): don't use this method. "
129  "Use the\n setBScaling() methods of the geometry objects that make "
130  "up this geometry\n");
131 }
132 
133 EGS_Hexagonal_Lattice::EGS_Hexagonal_Lattice(EGS_BaseGeometry *B, EGS_BaseGeometry *S, int i, EGS_Float x,
134  const string &Name)
135  : EGS_BaseGeometry(Name), base(B),
136  sub(new EGS_TransformedGeometry(S,EGS_Vector(0,0,0))),
137  ind(i), a(x), d(4,0.0) {
138  type = base->getType();
139  type += " with a hexagonal lattice of ";
140  type += sub->getType();
141  gap = a*sqrt(3.0)/2.0;
142  nreg = base->regions() + sub->regions();
143  has_rho_scaling = base->hasRhoScaling();
144  maxStep = base->regions()+1000000*sub->regions(); // Arbitrary step-length because I can't
145 }; // think of an elegant way to do this
146 
147 EGS_Hexagonal_Lattice::~EGS_Hexagonal_Lattice() {
148  if (!sub->deref()) {
149  delete sub;
150  }
151  if (!base->deref()) {
152  delete base;
153  }
154 };
155 
156 void EGS_Hexagonal_Lattice::printInfo() const {
158  egsInformation(" base geometry = %s (type %s)\n",base->getName().c_str(),
159  base->getType().c_str());
160  egsInformation(" hexagonal lattice subgeometry = %s (type %s)\n",sub->getName().c_str(),
161  sub->getType().c_str());
162  egsInformation(" hexagonal lattice region %d with a spacing of %d",ind,a);
163  egsInformation("=======================================================\n");
164 }
165 extern "C" {
166 
167  EGS_LATTICE_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) {
168  int err = 0;
169 
170  // Get base geometry
171  EGS_Input *i = input->getInputItem("base geometry");
172  if (!i) {
173  egsWarning("createGeometry(lattice): base geometry must be defined\n"
174  " using 'base geometry = some_geom'?\n");
175  return 0;
176  }
177  EGS_Input *ig = i->getInputItem("geometry");
178  EGS_BaseGeometry *b;
179  if (ig) {
181  delete ig;
182  if (!b) {
183  egsWarning("createGeometry(lattice): incorrect base geometry definition\n");
184  delete i;
185  return 0;
186  }
187  }
188  else {
189  string bgname;
190  err = i->getInput("base geometry",bgname);
191  delete i;
192  if (err) {
193  egsWarning("createGeometry(lattice): missing/incorrect 'base geometry' input\n");
194  return 0;
195  }
196  b = EGS_BaseGeometry::getGeometry(bgname);
197  if (!b) {
198  egsWarning("createGeometry(lattice): no geometry with name %s defined\n",
199  bgname.c_str());
200  return 0;
201  }
202  }
203 
204  // Get subgeometry
205  i = input->getInputItem("subgeometry");
206  if (!i) {
207  egsWarning("createGeometry(lattice): subgeometry must be defined\n"
208  " using 'subgeometry = some_geom'?\n");
209  return 0;
210  }
211  ig = i->getInputItem("geometry");
212  EGS_BaseGeometry *s;
213  if (ig) {
215  delete ig;
216  if (!s) {
217  egsWarning("createGeometry(lattice): incorrect subgeometry definition\n");
218  delete i;
219  return 0;
220  }
221  }
222  else {
223  string bgname;
224  err = i->getInput("subgeometry",bgname);
225  delete i;
226  if (err) {
227  egsWarning("createGeometry(lattice): missing/incorrect 'subgeometry' input\n");
228  return 0;
229  }
230  s = EGS_BaseGeometry::getGeometry(bgname);
231  if (!s) {
232  egsWarning("createGeometry(lattice): no geometry with name %s defined\n",
233  bgname.c_str());
234  return 0;
235  }
236  }
237 
238  // Get base region in which to place subgeometries
239  int ind = -1;
240  i = input->getInputItem("subgeometry index");
241  if (!i) {
242  egsWarning("createGeometry(lattice): subgeometry index must be defined\n"
243  " using 'subgeometry index = some_index'\n");
244  return 0;
245  }
246  else {
247  err = i->getInput("subgeometry index",ind);
248  delete i;
249  if (err) {
250  egsWarning("createGeometry(lattice): missing/incorrect 'subgeometry index' input\n");
251  return 0;
252  }
253  else if (ind < 0 || ind >= b->regions()) { // Not a real index
254  egsWarning("createGeometry(lattice): subgeometry index %d"
255  " is not valid, must be a region in base geometry\n",ind);
256  return 0;
257  }
258  }
259 
260  // Get one subgeometry spacing (hexagonal or cubic) or three (Bravais)
261  vector<EGS_Float> space;
262  err = input->getInput("spacing",space);
263  if (!err) {
264  for (int i=0; i < space.size(); i++) {
265  if (space[i] <= 0) {
266  egsWarning("createGeometry(lattice): spacing"
267  " is not valid, spacings must be greater than zero\n");
268  return 0;
269  }
270  }
271  if (space.size() != 1 && space.size() != 3) {
272  egsWarning("createGeometry(lattice): spacing"
273  " is not valid, input either one or three"
274  "x, y, and z spacings\n");
275  return 0;
276  }
277  }
278 
279  // Check for hexagonal lattice
280  string type;
281  input->getInput("type",type);
282 
283  // Final build
284  EGS_BaseGeometry *result;
285  if (space.size() == 3) {
286  result = new EGS_Lattice(b, s, ind, space[0], space[1], space[2]);
287  }
288  else if (input->compare("hexagonal",type)) {
289  result = new EGS_Hexagonal_Lattice(b, s, ind, space[0]);
290  }
291  else {
292  result = new EGS_Lattice(b, s, ind, space[0], space[0], space[0]);
293  }
294  result->setName(input);
295  return result;
296  }
297 
298  void EGS_Lattice::getLabelRegions(const string &str, vector<int> &regs) {
299  // labels defined in base geometry (matching indices)
300  base->getLabelRegions(str, regs);
301  int index = regs.size();
302 
303  // labels defined in sub geometries (shifting by base nreg)
305  for (; index<regs.size(); index++) {
306  regs[index] += base->regions();
307  }
308  }
309 
310  void EGS_Hexagonal_Lattice::getLabelRegions(const string &str, vector<int> &regs) {
311  // labels defined in base geometry (matching indices)
312  base->getLabelRegions(str, regs);
313  int index = regs.size();
314 
315  // labels defined in sub geometries (shifting by base nreg)
317  for (; index<regs.size(); index++) {
318  regs[index] += base->regions();
319  }
320  }
321 }
Base geometry class. Every geometry class must be derived from EGS_BaseGeometry.
int deref()
Decrease the reference count to this geometry.
static EGS_BaseGeometry * createSingleGeometry(EGS_Input *inp)
Create a single geometry from the input inp.
virtual const string & getType() const =0
Get the geometry type.
virtual void getLabelRegions(const string &str, vector< int > &regs)
Get the list of all regions labeled with str.
void setName(EGS_Input *inp)
Set the name of the geometry from the input inp.
const string & getName() const
Get the name of this geometry.
int regions() const
Returns the number of local regions in this geometry.
virtual void printInfo() const
Print information about this geometry.
static EGS_BaseGeometry * getGeometry(const string &Name)
Get a pointer to the geometry named Name.
EGS_Float a
The center-to-center distance to the nearest 12 neighbours.
Definition: egs_lattice.h:516
EGS_BaseGeometry * base
The geometry within which the sub geometry appears.
Definition: egs_lattice.h:512
EGS_TransformedGeometry * sub
The sub geometry that could appear within base.
Definition: egs_lattice.h:513
int ind
The region in base geom where we could encounter sub geom.
Definition: egs_lattice.h:514
A class for storing information in a tree-like structure of key-value pairs. This class is used throu...
Definition: egs_input.h:182
static bool compare(const string &s1, const string &s2)
Definition: egs_input.cpp:1170
EGS_Input * getInputItem(const string &key) const
Same as the previous function but now ownership remains with the EGS_Input object.
Definition: egs_input.cpp:245
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
A Bravais, cubic, and hexagonal lattice geometry.
Definition: egs_lattice.h:146
EGS_TransformedGeometry * sub
The sub geometry that could appear within base.
Definition: egs_lattice.h:150
EGS_BaseGeometry * base
The geometry within which the sub geometry appears.
Definition: egs_lattice.h:149
EGS_Float c
The center-to-center distance along x, y, and z.
Definition: egs_lattice.h:153
int ind
The region in base geom where we could encounter sub geom.
Definition: egs_lattice.h:151
A transformed geometry.
A class representing 3D vectors.
Definition: egs_vector.h:57
Global egspp functions header file.
EGS_GLIB_EXPORT EGS_BaseGeometry * createGeometry(EGS_Input *input)
Definition: egs_glib.cpp:57
EGS_Input class header file.
Lattice geometries: header.
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 egsWarning
Always use this function for reporting warnings.