EGSnrc C++ class library  Report PIRS-898 (2021)
Iwan Kawrakow, Ernesto Mainegra-Hing, Frederic Tessier, Reid Townson and Blake Walters
egs_source_collection.cpp
Go to the documentation of this file.
1 /*
2 ###############################################################################
3 #
4 # EGSnrc egs++ source 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 # Blake Walters
28 # Hannah Gallop
29 #
30 ###############################################################################
31 */
32 
33 
39 #include "egs_source_collection.h"
40 #include "egs_input.h"
41 
42 static bool EGS_SOURCE_COLLECTION_LOCAL inputSet = false;
43 
45  EGS_ObjectFactory *f) : EGS_BaseSource(input,f), nsource(0), count(0) {
46  vector<EGS_BaseSource *> s;
47  egsInformation("EGS_SourceCollection::EGS_BaseSource: input is:\n");
48  input->print(0,cout);
49  EGS_Input *isource;
50  while ((isource = input->takeInputItem("source",false))) {
51  egsInformation("EGS_SourceCollection: got input\n");
52  EGS_BaseSource *this_source = EGS_BaseSource::createSource(isource);
53  if (!this_source) {
54  egsWarning("EGS_SourceCollection: got null source\n");
55  }
56  else {
57  s.push_back(this_source);
58  }
59  delete isource;
60  }
61  vector<string> snames;
62  int err = input->getInput("source names",snames);
63  if (!err) {
64  for (unsigned int j=0; j<snames.size(); j++) {
65  EGS_BaseSource *this_source = EGS_BaseSource::getSource(snames[j]);
66  if (!this_source) {
67  egsWarning("EGS_SourceCollection: got null source\n");
68  }
69  else {
70  s.push_back(this_source);
71  }
72  }
73  }
74  if (s.size() < 1) {
75  egsWarning("EGS_SourceCollection: no sources\n");
76  return;
77  }
78  vector<EGS_Float> prob;
79  err = input->getInput("weights",prob);
80  if (err) {
81  egsWarning("EGS_SourceCollection: missing 'weights' input\n");
82  return;
83  }
84  if (prob.size() != s.size()) {
85  egsWarning("EGS_SourceCollection: the number of sources (%d) is not"
86  " the same as the number of input probabilities (%d)\n",
87  s.size(),prob.size());
88  return;
89  }
90  setUp(s,prob);
91 }
92 
93 void EGS_SourceCollection::setUp(const vector<EGS_BaseSource *> &S,
94  const vector<EGS_Float> &prob) {
95  otype = "EGS_SourceCollection";
96  nsource = S.size();
97  if (prob.size() < nsource) {
98  nsource = prob.size();
99  }
100  description = "Invalid source collection";
101  if (isValid()) {
102  p = new EGS_Float [nsource];
103  last_flu = new EGS_Float [nsource];
104  p_group = new vector<EGS_I64> [nsource];
105  sources = new EGS_BaseSource* [nsource];
106  Emax = 0;
107  for (int j=0; j<nsource; j++) {
108  p[j] = prob[j];
109  sources[j] = S[j];
110  if (p[j] < 0 || !sources[j]) {
111  if (p[j] < 0) egsWarning("EGS_SourceCollection: input "
112  "probability p[%d]=%g is less than zero.\n",j,p[j]);
113  else {
114  egsWarning("EGS_SourceCollection: source %d is null\n",j);
115  }
116  delete [] p;
117  for (int i=0; i<j; j++) {
119  }
120  delete [] sources;
121  nsource = 0;
122  return;
123  }
124  sources[j]->ref();
125  EGS_Float e = sources[j]->getEmax();
126  if (e > Emax) {
127  Emax = e;
128  }
129  }
130  table = new EGS_SimpleAliasTable(nsource,p);
131  description = "Source collection";
132  last_cases = new EGS_I64 [ nsource ];
133  for (int i=0; i<nsource; i++) {
134  last_cases[i] = 0;
135  last_flu[i]=0.;
136  }
137  i_add = false;
138  }
139 }
140 
147  hasdynamic = false;
148  for (int j=0; j<nsource; j++) {
149  bool sourceContainsDynamic = false;
150  sources[j]->containsDynamic(sourceContainsDynamic);
151  if (sourceContainsDynamic) {
152  hasdynamic = true;
153  return;
154  }
155  }
156 }
157 
158 extern "C" {
159 
160  static void setInputs() {
161  inputSet = true;
162 
163  setBaseSourceInputs(false, false);
164 
165  srcBlockInput->getSingleInput("library")->setValues({"egs_source_collection"});
166 
167  // Format: name, isRequired, description, vector string of allowed values
168  srcBlockInput->addSingleInput("source names", true, "A list of names of previously defined sources.");
169  srcBlockInput->addSingleInput("weights", true, "A list of weights for the sources, used as the relative sampling probabilities.");
170  }
171 
172  EGS_SOURCE_COLLECTION_EXPORT string getExample() {
173  string example;
174  example = {
175  R"(
176  # Example of egs_source_collection
177  :start source:
178  library = egs_source_collection
179  name = my_source
180  source name = p1 p2
181  # create sources called p1 and p2
182  weights = 0.1 0.9
183  :stop source:
184 )"};
185  return example;
186  }
187 
188  EGS_SOURCE_COLLECTION_EXPORT shared_ptr<EGS_BlockInput> getInputs() {
189  if(!inputSet) {
190  setInputs();
191  }
192  return srcBlockInput;
193  }
194 
195  EGS_SOURCE_COLLECTION_EXPORT EGS_BaseSource *createSource(EGS_Input *input,
196  EGS_ObjectFactory *f) {
197  return
198  createSourceTemplate<EGS_SourceCollection>(input,f,"source collection");
199  }
200 
201 }
Base source class. All particle sources must be derived from this class.
static EGS_BaseSource * getSource(const string &Name)
Get a pointer to the source named Name.
virtual EGS_Float getEmax() const =0
Return the maximum energy of this source.
string description
A short source description.
static EGS_BaseSource * createSource(EGS_Input *)
Create sources from the information pointed to by input.
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
void print(int nind, ostream &)
Used for debugging purposes.
Definition: egs_input.cpp:1177
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.
int ref()
Increase the reference count to this object.
static void deleteObject(EGS_Object *o)
Delete an object.
string otype
The object type.
A class for sampling random bins from a given probability distribution using the alias table techniqu...
EGS_Float * last_flu
Saved value of source_flu.
EGS_SimpleAliasTable * table
Alias table for randomly picking a source.
EGS_SourceCollection(const vector< EGS_BaseSource * > &S, const vector< EGS_Float > &prob, const string &Name="", EGS_ObjectFactory *f=0)
Constructor.
bool i_add
Set to true if parallel results have been combined.
EGS_Float Emax
Maximum energy (max of s[j]->getEmax()).
vector< EGS_I64 > * p_group
Vector of sources using the same base source.
EGS_BaseSource ** sources
The sources in the collection.
EGS_Float * p
The probabilities.
void containsDynamic(bool &hasdynamic)
Check if the simulation source contains time indices.
EGS_I64 * last_cases
Last case returned from each source.
EGS_Input class header file.
A source 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 egsWarning
Always use this function for reporting warnings.