EGSnrc C++ class library  Report PIRS-898 (2021)
Iwan Kawrakow, Ernesto Mainegra-Hing, Frederic Tessier, Reid Townson and Blake Walters
egs_planes.cpp
Go to the documentation of this file.
1 /*
2 ###############################################################################
3 #
4 # EGSnrc egs++ planes 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 # Marc Chamberland
28 # Reid Townson
29 # Hannah Gallop
30 #
31 ###############################################################################
32 */
33 
34 
41 #include "egs_planes.h"
42 #include "egs_input.h"
43 
44 //string XProjector::type = "EGS_Xplanes";
45 //string YProjector::type = "EGS_Yplanes";
46 //string ZProjector::type = "EGS_Zplanes";
47 //string Projector::type = "EGS_Planes";
48 const string EGS_PLANES_LOCAL xproj_type("EGS_Xplanes");
49 const string EGS_PLANES_LOCAL yproj_type("EGS_Yplanes");
50 const string EGS_PLANES_LOCAL zproj_type("EGS_Zplanes");
51 const string EGS_PLANES_LOCAL proj_type("EGS_Planes");
52 
53 static bool EGS_PLANES_LOCAL inputSet = false;
54 
55 string EGS_PlaneCollection::type = "EGS_PlaneCollection";
56 
57 EGS_PlaneCollection::EGS_PlaneCollection(int Np, const EGS_Float *pos,
58  const EGS_Vector *norm, const string &Name) : EGS_BaseGeometry(Name) {
59  if (Np < 2) egsFatal("EGS_PlaneCollection::EGS_PlaneCollection: "
60  " you nead at least 2 planes\n");
61  np = Np;
62  nreg=np-1;
63  planes = new EGS_Planes* [np];
64  for (int j=0; j<np; j++) {
65  planes[j] = new EGS_Planes(1,&pos[j],"",
66  EGS_Projector(norm[j],proj_type));
67  planes[j]->ref();
68  }
69 }
70 
71 EGS_PlaneCollection::~EGS_PlaneCollection() {
72  //egsWarning("Deleting ~EGS_PlaneCollection at 0x%x\n",this);
73  for (int j=0; j<np; j++) if (!planes[j]->deref()) {
74  delete planes[j];
75  }
76  delete [] planes;
77 }
78 
79 void EGS_PlaneCollection::printInfo() const {
81  int j;
82  egsInformation(" plane positions: ");
83  for (j=0; j<np; j++) {
84  egsInformation(" %g ",planes[j]->position(0));
85  }
86  egsInformation(" \nplane normals: ");
87  for (j=0; j<np; j++) {
88  EGS_Vector a = planes[j]->normal();
89  egsInformation(" (%g,%g,%g) ",a.x,a.y,a.z);
90  }
91  egsInformation("\n=====================================================\n");
92 }
93 
94 extern "C" {
95  static void setInputs() {
96  inputSet = true;
97 
98  setBaseGeometryInputs();
99 
100  geomBlockInput->getSingleInput("library")->setValues({"egs_planes"});
101 
102  // Format: name, isRequired, description, vector string of allowed values
103  auto typePtr = geomBlockInput->addSingleInput("type", true, "The type of plane.", {"EGS_XPlanes", "EGS_YPlanes", "EGS_ZPlanes", "EGS_Planes", "EGS_PlaneCollection"});
104 
105  auto posPtr = geomBlockInput->addSingleInput("positions", false, "A list of plane co-ordinates");
106 
107  // EGS_Planes
108  auto norPtr = geomBlockInput->addSingleInput("normal", true, "The plane normal (x, y, z)");
109  norPtr->addDependency(typePtr, "EGS_Planes");
110 
111  // EGS_PlaneCollection
112  auto normsPtr = geomBlockInput->addSingleInput("normals", true, "3 numbers defining a unit vector as the normal for each plane");
113  normsPtr->addDependency(typePtr, "EGS_PlaneCollection");
114 
115  // Alternative definition of the plane position
116  auto fpPtr = geomBlockInput->addSingleInput("first plane", false, "The position of the first plane.");
117  auto slabPtr = geomBlockInput->addSingleInput("slab thickness", false, "A list of the thickness between each set of planes");
118  auto numPtr = geomBlockInput->addSingleInput("number of slabs", false, "A list of the number of slabs");
119 
120  // Either positions or the alternatives must be used, not both
121  fpPtr->addDependency(posPtr, "", true);
122  slabPtr->addDependency(posPtr, "", true);
123  numPtr->addDependency(posPtr, "", true);
124  posPtr->addDependency(fpPtr, "", true);
125  posPtr->addDependency(slabPtr, "", true);
126  posPtr->addDependency(numPtr, "", true);
127  }
128 
129  EGS_PLANES_EXPORT string getExample() {
130  string example;
131  example = {
132  R"(
133  # Examples of the egs_planes
134 
135  # EGS_Plane example
136  #:start geometry:
137  library = egs_planes
138  type = EGS_Planes
139  name = my_plane
140  positions = 2 2 2
141  normal = 0
142  :stop geometry:
143 
144  # EGS_PlaneCollection example
145  #:start geometry:
146  library = egs_planes
147  type = EGS_PlaneCollection
148  name = my_plane_collection
149  normals = 0 0 1 0.1 -0.1 1 -0.1 -0.3 1 0 0 1
150  positions = -5 -2 2 12
151  :start media input:
152  media = air water air
153  set medium = 1 1
154  set medium = 2 2
155  :stop media input:
156  :stop geometry:
157 )"};
158  return example;
159  }
160 
161  EGS_PLANES_EXPORT shared_ptr<EGS_BlockInput> getInputs() {
162  if(!inputSet) {
163  setInputs();
164  }
165  return geomBlockInput;
166  }
167 
168  EGS_PLANES_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) {
169  string type;
170  int err = input->getInput("type",type);
171  if (err) {
172  egsWarning("createGeometry(planes): missing type key\n");
173  return 0;
174  }
175  EGS_Float first;
176  vector<EGS_Float> thick;
177  vector<int> nthick;
178  vector<EGS_Float> pos;
179  int err_first = input->getInput("first plane",first);
180  int err_thick = input->getInput("slab thickness",thick);
181  int err_nthick = input->getInput("number of slabs",nthick);
182  if (!err_first && !err_thick && !err_nthick) {
183  if (thick.size() != nthick.size() || !thick.size()) {
184  egsWarning("createGeometry(planes): number of 'slab thickness' and"
185  "\n 'number of slabs' inputs must be the same and not zero\n");
186  egsWarning(" got %d and %d inputs --> input ignored\n",
187  thick.size(),nthick.size());
188  }
189  else {
190  pos.push_back(first);
191  int j=0;
192  for (int i=0; i<thick.size(); i++) {
193  for (int l=0; l<nthick[i]; ++l) {
194  pos.push_back(pos[j++]+thick[i]);
195  }
196  }
197  }
198  }
199  if (!pos.size()) {
200  err = input->getInput("positions",pos);
201  if (err) {
202  egsWarning("createGeometry(planes): missing/wrong 'positions' "
203  "input and missing/wrong multiple plane input\n");
204  return 0;
205  }
206  }
207  EGS_BaseGeometry *g;
208  if (type == "EGS_Xplanes") g = new EGS_PlanesX(pos,"",
209  EGS_XProjector(xproj_type));
210  else if (type == "EGS_Yplanes") g = new EGS_PlanesY(pos,"",
211  EGS_YProjector(yproj_type));
212  else if (type == "EGS_Zplanes") g = new EGS_PlanesZ(pos,"",
213  EGS_ZProjector(zproj_type));
214  else if (type == "EGS_Planes") {
215  vector<EGS_Float> a;
216  err = input->getInput("normal",a);
217  if (err || a.size() != 3) {
218  egsWarning("createGeometry(planes): missing/wrong normal input\n");
219  return 0;
220  }
221  g = new EGS_Planes(pos,"",EGS_Projector(EGS_Vector(a[0],a[1],a[2]),
222  proj_type));
223  }
224  else if (type == "EGS_PlaneCollection") {
225  vector<EGS_Float> a;
226  err = input->getInput("normals",a);
227  if (err || a.size() < 6) {
228  egsWarning("createGeometry(planes): missing/wrong normal input\n");
229  return 0;
230  }
231  int np = a.size()/3;
232  if (np != pos.size()) {
233  egsWarning("createGeometry(planes): number of plane normals (%d)\n"
234  " is not the same as number of plane positions (%d) for a"
235  " plane collection\n",np,pos.size());
236  return 0;
237  }
238  EGS_Float *p = new EGS_Float [np];
239  EGS_Vector *normal = new EGS_Vector [np];
240  for (int j=0; j<np; j++) {
241  p[j] = pos[j];
242  normal[j] = EGS_Vector(a[3*j],a[3*j+1],a[3*j+2]);
243  }
244  g = new EGS_PlaneCollection(np,p,normal);
245  }
246  else {
247  egsWarning("createGeometry(planes): unknown type %s\n",type.c_str());
248  return 0;
249  }
250  g->setName(input);
251  g->setBoundaryTolerance(input);
252  g->setMedia(input);
253  g->setLabels(input);
254  return g;
255  }
256 
257 }
Base geometry class. Every geometry class must be derived from EGS_BaseGeometry.
int deref()
Decrease the reference count to this geometry.
void setMedia(EGS_Input *inp)
Set the media in the geometry from the input pointed to by inp.
void setName(EGS_Input *inp)
Set the name of the geometry from the input inp.
int setLabels(EGS_Input *input)
Set the labels from an input block.
virtual void printInfo() const
Print information about this geometry.
void setBoundaryTolerance(EGS_Input *inp)
Set the value of the boundary tolerance 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
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:341
A collection of non-parallel planes.
Definition: egs_planes.h:575
A set of parallel planes.
Definition: egs_planes.h:167
A projector into any plane.
A class representing 3D vectors.
Definition: egs_vector.h:57
EGS_Float y
y-component
Definition: egs_vector.h:62
EGS_Float z
z-component
Definition: egs_vector.h:63
EGS_Float x
x-component
Definition: egs_vector.h:61
A projector into the x-plane.
A projector into the y-plane.
A projector into the z-plane.
EGS_GLIB_EXPORT EGS_BaseGeometry * createGeometry(EGS_Input *input)
Definition: egs_glib.cpp:84
EGS_Input class header file.
Sets of parallel planes and a plane collection.
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 egsFatal
Always use this function for reporting fatal errors.
EGS_InfoFunction EGS_EXPORT egsWarning
Always use this function for reporting warnings.