EGSnrc C++ class library  Report PIRS-898 (2021)
Iwan Kawrakow, Ernesto Mainegra-Hing, Frederic Tessier, Reid Townson and Blake Walters
egs_cd_geometry.cpp
Go to the documentation of this file.
1 /*
2 ###############################################################################
3 #
4 # EGSnrc egs++ cd geometry
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: Iwan Kawrakow, 2005
25 #
26 # Contributors: Frederic Tessier
27 # Ernesto Mainegra-Hing
28 # Marc Chamberland
29 #
30 ###############################################################################
31 */
32 
33 
39 #include "egs_cd_geometry.h"
40 #include "egs_input.h"
41 
42 #ifdef NO_SSTREAM
43  #include <strstream>
44  #define S_STREAM std::istrstream
45 #else
46  #include <sstream>
47  #define S_STREAM std::istringstream
48 #endif
49 
50 string EGS_CDGeometry::type = "EGS_CDGeometry";
51 
52 void EGS_CDGeometry::setMedia(EGS_Input *,int,const int *) {
53  egsWarning("EGS_CDGeometry::setMedia: don't use this method. Use the\n"
54  " setMedia() methods of the geometry objects that make up this geometry\n");
55 }
56 
57 void EGS_CDGeometry::setRelativeRho(int start, int end, EGS_Float rho) {
58  egsWarning("EGS_CDGeometry::setRelativeRho(): don't use this method\n"
59  " Use the setRelativeRho() methods of the geometry objects that make"
60  " up this geometry\n");
61 }
62 
63 void EGS_CDGeometry::setRelativeRho(EGS_Input *) {
64  egsWarning("EGS_CDGeometry::setRelativeRho(): don't use this method\n"
65  " Use the setRelativeRho() methods of the geometry objects that make"
66  " up this geometry\n");
67 }
68 
69 void EGS_CDGeometry::setBScaling(int start, int end, EGS_Float bf) {
70  egsWarning("EGS_CDGeometry::setBScaling(): don't use this method\n"
71  " Use the setBScaling() methods of the geometry objects that make"
72  " up this geometry\n");
73 }
74 
75 void EGS_CDGeometry::setBScaling(EGS_Input *) {
76  egsWarning("EGS_CDGeometry::setBScaling(): don't use this method\n"
77  " Use the setBScaling() methods of the geometry objects that make"
78  " up this geometry\n");
79 }
80 
81 void EGS_CDGeometry::setUpIndexing() {
82  int nr = 0;
83  int j;
84  for (j=0; j<nbase; j++) {
85  if (g[j]) {
86  nr += g[j]->regions();
87  }
88  else {
89  ++nr;
90  }
91  }
92  reg_to_base = new int [nr];
93  local_start = new int [nbase];
94  int ir=0;
95  for (j=0; j<nbase; j++) {
96  local_start[j] = ir;
97  if (g[j]) {
98  int n = g[j]->regions();
99  for (int i=0; i<n; i++) {
100  reg_to_base[ir++] = j;
101  }
102  }
103  else {
104  reg_to_base[ir++] = j;
105  }
106  }
107  new_indexing = true;
108  nreg = nr;
109 }
110 
111 
112 extern "C" {
113 
114  EGS_CDGEOMETRY_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) {
115  if (!input) {
116  egsWarning("createGeometry(CD_Geometry): null input?\n");
117  return 0;
118  }
119  EGS_Input *ij;
120  while ((ij = input->takeInputItem("geometry",false)) != 0) {
122  delete ij;
123  }
124  string bg_name;
125  int err = input->getInput("base geometry",bg_name);
126  if (err) {
127  egsWarning("createGeometry(CD_Geometry): no 'base geometry' input\n");
128  return 0;
129  }
131  if (!g) {
132  egsWarning("createGeometry(CD_Geometry): no geometry named %s is"
133  " defined\n",bg_name.c_str());
134  return 0;
135  }
136  int nreg = g->regions();
137  if (nreg < 1) {
138  egsWarning("createGeometry(CD_Geometry): the base geometry has %d"
139  " regions?\n",nreg);
140  return 0;
141  }
142  EGS_BaseGeometry **G = new EGS_BaseGeometry* [nreg];
143  int j;
144  for (j=0; j<nreg; j++) {
145  G[j] = 0;
146  }
147  int ng = 0;
148  string aux;
149  err = 0;
150  while ((ij = input->takeInputItem("set geometry")) != 0) {
151  vector<string> aux;
152  ij->getInput("set geometry",aux);
153  int istart, iend;
154  string name;
155  bool is_ok = true;
156  if (aux.size() == 2) {
157  string auxx = aux[0];
158  auxx += ' ';
159  auxx += aux[1];
160  auxx += ' ';
161  S_STREAM in(auxx.c_str());
162  in >> istart >> name;
163  if (in.fail() || !in.good()) {
164  egsWarning("createGeometry(CD_Geometry): parse error in\n"
165  " set geometry = %s\n",auxx.c_str());
166  err++;
167  is_ok = false;
168  }
169  else {
170  if (istart < 0 || istart > nreg-1) {
171  istart = -1;
172  iend = -2;
173  }
174  else {
175  iend = istart+1;
176  }
177  }
178  }
179  else if (aux.size() == 3) {
180  string auxx = aux[0];
181  auxx += ' ';
182  auxx += aux[1];
183  auxx += ' ';
184  auxx += aux[2];
185  auxx += ' ';
186  S_STREAM in(auxx.c_str());
187  in >> istart >> iend >> name;
188  if (in.fail() || !in.good()) {
189  egsWarning("createGeometry(CD_Geometry): parse error in\n"
190  " set geometry = %s\n",auxx.c_str());
191  err++;
192  is_ok = false;
193  }
194  else {
195  if (istart < 0) {
196  istart = 0;
197  }
198  if (iend > nreg) {
199  iend = nreg;
200  }
201  }
202  }
203  else {
204  err++;
205  is_ok = false;
206  }
207  if (is_ok) {
209  if (!gj) {
210  egsWarning("createGeometry(CD_Geometry): no geometry named %s"
211  " is defined\n",name.c_str());
212  err++;
213  }
214  else {
215  for (int j=istart; j<iend; j++) {
216  if (G[j] && G[j] != gj) {
217  G[j]->deref();
218  }
219  /*
220  if( !G[j] ) gj->ref();
221  else {
222  if( G[j] != gj ) G[j]->deref();
223  }
224  */
225  G[j] = gj;
226  gj->ref();
227  ng++;
228  }
229  }
230  }
231  delete ij;
232  }
233  if (err) {
234  egsWarning("createGeometry(CD_Geometry): %d errors\n",err);
235  for (j=0; j<nreg; j++) {
236  if (G[j]) {
237  if (!G[j]->deref()) {
238  delete G[j];
239  }
240  }
241  }
242  delete [] G[j];
243  return 0;
244  }
245  if (!ng)
246  egsWarning("createGeometry(CD_Geometry): no geometries in addition to"
247  " the base geometry defined?\n"
248  " Hope you know what you are doing\n");
249  g->ref();
250  int indexing = 0;
251  input->getInput("new indexing style",indexing);
252  EGS_BaseGeometry *result = new EGS_CDGeometry(g,G,"",indexing);
253  delete [] G;
254  result->setName(input);
255  result->setBoundaryTolerance(input);
256  result->setLabels(input);
257  return result;
258 
259  }
260 
261 
262  void EGS_CDGeometry::getLabelRegions(const string &str, vector<int> &regs) {
263 
264  // label defined in the base geometry
265  vector<int> bgregs;
266  bg->getLabelRegions(str, bgregs);
267 
268  // expand base regions to global region lists
269  int rstart = 0;
270  int rend = 0;
271  for (int i=0; i<bgregs.size(); i++) {
272  if (new_indexing) {
273  rstart = local_start[bgregs[i]];
274  if (bgregs[i] < nbase-1) {
275  rend = local_start[bgregs[i]+1];
276  }
277  else {
278  rend = nreg;
279  }
280  }
281  else {
282  rstart = bgregs[i]*nmax;
283  rend = (bgregs[i]+1)*nmax;
284  }
285  for (int j=rstart; j<rend; j++) {
286  regs.push_back(j);
287  }
288  }
289 
290  // label defined in the set geometries
291  vector<int> gregs;
292  int shift=0;
293  for (int i=0; i<nbase; i++) {
294 
295  // add regions from set geometries
296  gregs.clear();
297  if (g[i]) {
298  g[i]->getLabelRegions(str, gregs);
299  }
300 
301  // shift region numbers according to indexing style
302  if (new_indexing) {
303  shift = local_start[i];
304  }
305  else {
306  shift = i*nmax;
307  }
308  for (int j=0; j<gregs.size(); j++) {
309  gregs[j] += shift;
310  }
311 
312  // add regions to the list
313  regs.insert(regs.end(), gregs.begin(), gregs.end());
314 
315  }
316 
317  // label defined in self (cd input block)
319 
320  }
321 
322 }
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 void getLabelRegions(const string &str, vector< int > &regs)
Get the list of all regions labeled with str.
int nreg
Number of local regions in this geometry.
void setName(EGS_Input *inp)
Set the name of the geometry from the input inp.
int regions() const
Returns the number of local regions in this geometry.
int setLabels(EGS_Input *input)
Set the labels from an input block.
int ref()
Increase the reference count to this geometry.
static EGS_BaseGeometry * getGeometry(const string &Name)
Get a pointer to the geometry named Name.
void setBoundaryTolerance(EGS_Input *inp)
Set the value of the boundary tolerance from the input inp.
A "combinatorial dimension" geometry.
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_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
A CD-geometry: header.
EGS_GLIB_EXPORT EGS_BaseGeometry * createGeometry(EGS_Input *input)
Definition: egs_glib.cpp:57
EGS_Input class header file.
EGS_InfoFunction EGS_EXPORT egsWarning
Always use this function for reporting warnings.