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 }
virtual const string & getType() const =0
Get the geometry type.
int regions() const
Returns the number of local regions in this geometry.
int deref()
Decrease the reference count to this geometry.
virtual void printInfo() const
Print information about this geometry.
EGS_Float c
The center-to-center distance along x, y, and z.
Definition: egs_lattice.h:152
Lattice geometries: header.
EGS_Input class header file.
EGS_TransformedGeometry * sub
The sub geometry that could appear within base.
Definition: egs_lattice.h:149
A class representing 3D vectors.
Definition: egs_vector.h:56
Global egspp functions header file.
EGS_GLIB_EXPORT EGS_BaseGeometry * createGeometry(EGS_Input *input)
Definition: egs_glib.cpp:57
Base geometry class. Every geometry class must be derived from EGS_BaseGeometry.
A Bravais, cubic, and hexagonal lattice geometryA geometry which embeds a lattice of one geometry (na...
Definition: egs_lattice.h:145
EGS_BaseGeometry * base
The geometry within which the sub geometry appears.
Definition: egs_lattice.h:148
A transformed geometry.
static EGS_BaseGeometry * getGeometry(const string &Name)
Get a pointer to the geometry named Name.
virtual void getLabelRegions(const string &str, vector< int > &regs)
Get the list of all regions labeled with str.
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
EGS_InfoFunction EGS_EXPORT egsInformation
Always use this function for reporting the progress of a simulation and any other type of information...
EGS_Float a
The center-to-center distance to the nearest 12 neighbours.
Definition: egs_lattice.h:515
void setName(EGS_Input *inp)
Set the name of the geometry from the input inp.
int ind
The region in base geom where we could encounter sub geom.
Definition: egs_lattice.h:513
bool has_rho_scaling
Does this geometry have relative mass density scvaling?
int ind
The region in base geom where we could encounter sub geom.
Definition: egs_lattice.h:150
static EGS_BaseGeometry * createSingleGeometry(EGS_Input *inp)
Create a single geometry from the input inp.
A class for storing information in a tree-like structure of key-value pairs. This class is used throu...
Definition: egs_input.h:182
const string & getName() const
Get the name of this geometry.
EGS_TransformedGeometry * sub
The sub geometry that could appear within base.
Definition: egs_lattice.h:512
static bool compare(const string &s1, const string &s2)
Definition: egs_input.cpp:1170
int nreg
Number of local regions in this geometry.
EGS_BaseGeometry * base
The geometry within which the sub geometry appears.
Definition: egs_lattice.h:511
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.