EGSnrc C++ class library  Report PIRS-898 (2021)
Iwan Kawrakow, Ernesto Mainegra-Hing, Frederic Tessier, Reid Townson and Blake Walters
egs_shape_collection.cpp
Go to the documentation of this file.
1 /*
2 ###############################################################################
3 #
4 # EGSnrc egs++ shape collection
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: Marc Chamberland
27 # Randle Taylor
28 # Hannah Gallop
29 #
30 ###############################################################################
31 */
32 
33 
39 #include "egs_shape_collection.h"
40 #include "egs_input.h"
41 #include "egs_functions.h"
42 
43 static bool EGS_SHAPE_COLLECTION_LOCAL inputSet = false;
44 static shared_ptr<EGS_BlockInput> EGS_SHAPE_COLLECTION_LOCAL shapeBlockInput = make_shared<EGS_BlockInput>("shape");
45 
46 EGS_ShapeCollection::EGS_ShapeCollection(const vector<EGS_BaseShape *> &Shapes,
47  const vector<EGS_Float> &Probs, const string &Name, EGS_ObjectFactory *f) :
48  EGS_BaseShape(Name,f), nshape(0) {
49  int n1 = Shapes.size(), n2 = Probs.size();
50  if (n1 < 2 || n2 < 2 || n1 != n2) {
51  egsWarning("EGS_ShapeCollection::EGS_ShapeCollection: invalid input\n");
52  return;
53  }
54  nshape = n1;
55  shapes = new EGS_BaseShape* [nshape];
56  EGS_Float *p = new EGS_Float [nshape];
57  for (int j=0; j<nshape; j++) {
58  shapes[j] = Shapes[j];
59  shapes[j]->ref();
60  p[j] = Probs[j];
61  }
62  table = new EGS_SimpleAliasTable(nshape,p);
63  delete [] p;
64 }
65 
66 extern "C" {
67 
68  static void setInputs() {
69  inputSet = true;
70  shapeBlockInput->addSingleInput("library", true, "The type of shape, loaded by shared library in egs++/dso.", {"egs_shape_collection"});
71  shapeBlockInput->addSingleInput("probabilities", true, "A list of the relative sampling weight for each of the shapes: p1 p2 ... pn");
72 
73  auto shapePtr = shapeBlockInput->addBlockInput("shape");
74  setShapeInputs(shapePtr);
75  }
76 
77  EGS_SHAPE_COLLECTION_EXPORT string getExample() {
78  string example;
79  example = {
80  R"(
81  # Example of egs_shape_collection
82  #:start shape:
83  library = egs_shape_collection
84  :start shape:
85  definition of the first shape in the collection:
86  :stop shape:
87  :start shape:
88  definition of the second shape in the collection
89  :stop shape:
90  ...
91  :start shape:
92  definition of the last shape in the collection
93  :stop shape:
94  probablities = p1 p2 ... pn
95  :stop shape:
96 )"};
97  return example;
98  }
99 
100  EGS_SHAPE_COLLECTION_EXPORT shared_ptr<EGS_BlockInput> getInputs() {
101  if(!inputSet) {
102  setInputs();
103  }
104  return shapeBlockInput;
105  }
106 
107  EGS_SHAPE_COLLECTION_EXPORT EGS_BaseShape *createShape(EGS_Input *input,
108  EGS_ObjectFactory *f) {
109  if (!input) {
110  egsWarning("createShape(shape collection): null input?\n");
111  return 0;
112  }
113  vector<EGS_BaseShape *> shapes;
114  vector<EGS_Float> probs;
115  EGS_Input *ishape;
116  while ((ishape = input->takeInputItem("shape",false))) {
117  EGS_BaseShape *shape = EGS_BaseShape::createShape(ishape);
118  if (!shape) {
119  egsWarning("createShape(shape collection): got null shape\n");
120  }
121  else {
122  shapes.push_back(shape);
123  }
124  delete ishape;
125  }
126  vector<string> snames;
127  int err = input->getInput("shape names",snames);
128  if (!err && snames.size() > 0) {
129  for (unsigned int j=0; j<snames.size(); j++) {
130  EGS_BaseShape *shape = EGS_BaseShape::getShape(snames[j]);
131  if (!shape) egsWarning("createShape(shape collection): no shape "
132  "named %s exists\n",snames[j].c_str());
133  else {
134  shapes.push_back(shape);
135  }
136  }
137  }
138  err = input->getInput("probabilities",probs);
139  bool ok = true;
140  if (err) {
141  egsWarning("createShape(shape collection): no 'probabilities' input\n");
142  ok = false;
143  }
144  if (shapes.size() < 2) {
145  egsWarning("createShape(shape collection): at least 2 shapes are "
146  "needed for a shape collection, you defined %d\n",shapes.size());
147  ok = false;
148  }
149  if (shapes.size() != probs.size()) {
150  egsWarning("createShape(shape collection): the number of shapes (%d)"
151  " is not the same as the number of input probabilities (%d)\n");
152  ok = false;
153  }
154  for (unsigned int i=0; i<probs.size(); i++) {
155  if (probs[i] < 0) {
156  egsWarning("createShape(shape collection): probabilities must not"
157  " be negative, but your input probability %d is %g\n",
158  i,probs[i]);
159  ok = false;
160  }
161  }
162  if (!ok) {
163  for (unsigned int j=0; j<shapes.size(); j++) {
164  EGS_Object::deleteObject(shapes[j]);
165  }
166  return 0;
167  }
168  EGS_ShapeCollection *s = new EGS_ShapeCollection(shapes,probs,"",f);
169  s->setName(input);
170  s->setTransformation(input);
171  return s;
172  }
173 
174 }
Base shape class. All shapes in the EGSnrc C++ class library are derived from EGS_BaseShape.
Definition: egs_shapes.h:145
static EGS_BaseShape * getShape(const string &Name)
Get a pointer to the shape named Name.
Definition: egs_shapes.cpp:64
static EGS_BaseShape * createShape(EGS_Input *inp)
Create a shape from the information pointed to by inp.
Definition: egs_shapes.cpp:51
void setTransformation(EGS_Input *inp)
Set the transformation attached to this shape.
Definition: egs_shapes.cpp:69
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:229
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
An object factory.
void setName(EGS_Input *inp)
Set the name of the object from the information provided by inp.
int ref()
Increase the reference count to this object.
static void deleteObject(EGS_Object *o)
Delete an object.
A shape collection.
A class for sampling random bins from a given probability distribution using the alias table techniqu...
Global egspp functions header file.
EGS_Input class header file.
A shape collection.
EGS_InfoFunction EGS_EXPORT egsWarning
Always use this function for reporting warnings.