66 class EGS_LOCAL EGS_GeometryPrivate {
72 vector<EGS_Library *> glibs;
73 static string geom_delimeter;
75 static string create_key;
79 EGS_GeometryPrivate() : nnow(0), ntot(0), geoms(0), app(0) {
84 EGS_GeometryPrivate(
const EGS_GeometryPrivate &p) :
85 nnow(0), ntot(0), geoms(0), app(0) {
91 char *hhouse = getenv(
"HEN_HOUSE");
93 egsFatal(
"Environment variable HEN_HOUSE must be defined\n");
96 #if defined WIN32 && !defined CYGWIN
101 if (dso_path[dso_path.size()-1] != c) {
109 dso_path += CONFIG_NAME;
112 ~EGS_GeometryPrivate() {
122 for (
unsigned int j=0; j<glibs.size(); j++) {
128 void clearGeometries() {
133 int j = 0, iloop = 0;
135 if (geoms[j]->deref() == -1) {
136 removeGeometry(geoms[j]);
141 if (j >= nnow && nnow) {
145 for (
int i=0; i<nnow; ++i) {
146 if (!geoms[i]->deref()) {
147 removeGeometry(geoms[i]);
161 void grow(
int ngrow) {
164 for (
int j=0; j<nnow; j++) {
177 for (
int j=0; j<nnow; j++) {
178 if (geoms[j]->getName() == g->
getName()) {
194 for (
int j=0; j<nnow; j++) {
207 for (
int j=0; j<nnow; j++)
208 if (geoms[j]->getName() == name) {
214 int addMedium(
const string &Name) {
218 for (
unsigned int j=0; j<media.size(); j++)
219 if (media[j] == Name) {
222 media.push_back(Name);
223 return media.size()-1;
226 int getMediumIndex(
const string &Name) {
227 for (
unsigned int j=0; j<media.size(); j++)
228 if (media[j] == Name) {
238 const char *getMediumName(
int ind)
const {
239 if (ind < 0 || ind > media.size()-1) {
242 return media[ind].c_str();
245 void containsDynamic(
bool &hasdynamic) {
249 EGS_Float getMediumRho(
int ind)
const {
255 return app->getMediumRho(ind);
271 class EGS_LOCAL EGS_PrivateGeometryLists {
273 EGS_PrivateGeometryLists() : nnow(0), ntot(0) {
274 addList(
new EGS_GeometryPrivate);
276 ~EGS_PrivateGeometryLists() {
279 for (
int j=0; j<nnow; j++) {
289 EGS_GeometryPrivate &operator[](
int j) {
292 void addList(EGS_GeometryPrivate *l) {
297 EGS_GeometryPrivate **tmp =
new EGS_GeometryPrivate* [ntot+10];
298 for (
int j=0; j<nnow; j++) {
310 EGS_GeometryPrivate **lists;
313 string EGS_GeometryPrivate::geom_delimeter =
"geometry definition";
314 string EGS_GeometryPrivate::libkey =
"library";
315 string EGS_GeometryPrivate::create_key =
"createGeometry";
318 int EGS_BaseGeometry::active_glist = 0;
320 static char buf_unique[32];
328 egsWarning(
"createSingleGeometry: null input?\n");
331 int error = i->
getInput(EGS_GeometryPrivate::libkey,libname);
333 egsWarning(
"createSingleGeometry: input item %s does not define the"
334 " geometry library\n",i->
name());
338 for (
unsigned int j=0; j<glibs.size(); j++) {
339 if (libname == glibs[j]->libraryName()) {
345 lib =
new EGS_Library(libname.c_str(),dso_path.c_str());
348 egsWarning(
"createSingleGeometry: Failed to load library '%s' from"
349 " %s\n",libname.c_str(),dso_path.c_str());
352 glibs.push_back(lib);
354 EGS_GeometryCreationFunction gcreate = (EGS_GeometryCreationFunction)
355 lib->
resolve(EGS_GeometryPrivate::create_key.c_str());
357 egsWarning(
"createSingleGeometry: failed to resolve the %s function\n"
358 " in geometry library %s\n",
359 EGS_GeometryPrivate::create_key.c_str(),lib->
libraryName());
364 egsWarning(
"createSingleGeometry: got null geometry\n");
370 if (!addGeometry(g)) {
371 egsWarning(
"createSingleGeometry: failed to add the geometry %s\n"
372 " to the list of geometries. This implies that a geometry with"
373 " this name already exists\n",g->
getName().c_str());
383 static EGS_LOCAL EGS_PrivateGeometryLists egs_geometries;
392 for (EGS_I64 loopCount=0; loopCount<=
loopMax; ++loopCount) {
394 egsFatal(
"EGS_BaseGeometry::howfarToOutside: Too many iterations were required! Input may be invalid, or consider increasing loopMax.");
398 int inew = howfar(ireg,xx,u,t);
410 int n = egs_geometries.size();
413 for (
int j=n; j<=list; j++)
416 egs_geometries.addList(
new EGS_GeometryPrivate);
434 region_media(0), med(-1), has_rho_scaling(false), rhor(0),
435 has_B_scaling(false), has_Ref_rho(false), bfactor(0), rhoRef(1.0),
436 nref(0), debug(false), is_convex(true), bproperty(0), bp_array(0),
440 if (!egs_geometries.size()) {
441 egs_geometries.addList(
new EGS_GeometryPrivate);
446 if (egs_geometries[active_glist].addGeometry(
this) < 0)
447 egsFatal(
"EGS_BaseGeometry::EGS_BaseGeometry:\n"
448 " a geometry with name %s already exists\n",
name.c_str());
465 egs_geometries[active_glist].removeGeometry(
this);
469 egs_geometries[active_glist].clearGeometries();
473 return egs_geometries[active_glist].getGeometry(Name);
477 return egs_geometries[active_glist].geoms;
480 int EGS_BaseGeometry::getNGeometries() {
481 return egs_geometries[active_glist].nnow;
485 med = egs_geometries[active_glist].addMedium(Name);
487 for (
int j=0; j<
nreg; j++) {
493 return egs_geometries[active_glist].addMedium(medname);
497 return egs_geometries[active_glist].getMediumIndex(medname);
502 int imed = egs_geometries[active_glist].addMedium(Name);
522 for (
int j=0; j<
nreg; j++) {
526 for (
int j=istart; j<=iend; j+=delta) {
532 return egs_geometries[active_glist].nMedia();
536 return egs_geometries[active_glist].getMediumName(ind);
539 EGS_Float EGS_BaseGeometry::getMediumRho(
int ind)
const {
540 return egs_geometries[active_glist].getMediumRho(ind);
544 return egs_geometries[active_glist].setApplication(App);
548 return egs_geometries[active_glist].createSingleGeometry(input);
553 bool delete_it =
false;
554 if (!input->
isA(egs_geometries[active_glist].geom_delimeter)) {
555 ginput = input->
takeInputItem(egs_geometries[active_glist].geom_delimeter);
559 egsWarning(
"EGS_BaseGeometry::createGeometry: no geometry specification"
566 EGS_BaseGeometry *g = egs_geometries[active_glist].createSingleGeometry(ij);
573 for (
int j=0; j<egs_geometries[active_glist].nnow; j++) {
574 string gname = egs_geometries[active_glist].geoms[j]->getName();
575 for (
int k=0; k<egs_geometries[active_glist].nnow; k++) {
579 if (gname == egs_geometries[active_glist].geoms[k]->
getName()) {
580 egsFatal(
"\ncreateGeometry: Error: multiple geometries with"
581 " the same name exist: %s\n\n", gname.c_str());
587 egsFatal(
"EGS_BaseGeometry::createGeometry: errors during geometry"
592 int err = ginput->
getInput(
"simulation geometry",sim_geom);
594 egsWarning(
"EGS_BaseGeometry::createGeometry: missing/wrong keyword"
595 " 'simulation geometry'\n");
599 if (!g)
egsWarning(
"EGS_BaseGeometry::createGeometry: a geometry with "
600 "the name %s does not exist\n",sim_geom.c_str());
608 sprintf(buf_unique,
"geometry%d",egs_geometries[active_glist].nnow);
609 string result(buf_unique);
623 vector<EGS_Float> trans, trans_o;
624 vector<EGS_Float> rot_axis;
625 EGS_Float rot_angle, rot_angle_o;
626 int err1 = inp->getInput(
"type",typ);
627 int err2 = inp->getInput(
"number of copies",ncopy);
628 int err3 = inp->getInput(
"translation delta",trans);
629 int err4 = inp->getInput(
"first translation",trans_o);
630 int err5 = inp->getInput(
"rotation axis",rot_axis);
631 int err6 = inp->getInput(
"rotation delta",rot_angle);
632 int err7 = inp->getInput(
"first rotation",rot_angle_o);
636 if (err1)
egsWarning(
"geometry replication: 'type' not defined ->"
637 " ignoring input\n");
638 if (err2)
egsWarning(
"geometry replication: 'number of copies' "
639 "not defined -> ignoring input\n");
644 egsWarning(
"geometry replication: %d copies?\n",ncopy);
648 if (err3 || trans.size() != 3) {
649 egsWarning(
"geometry replication: got %d inputs for "
650 "'translation', need 3\n",trans.size());
655 trans_o.push_back(0);
656 trans_o.push_back(0);
657 trans_o.push_back(0);
662 else if (typ ==
"rotation") {
663 if (err5 || rot_axis.size() != 3) {
664 egsWarning(
"geometry replication: got %d inputs for "
665 "'rotation axis', need 3\n",rot_axis.size());
669 egsWarning(
"geometry replication: missing 'rotation delta'"
679 egsWarning(
"geometry replication: unknown replica type %s\n",
687 for (
int icopy=1; icopy<=ncopy; icopy++) {
690 content +=
" library = egs_gtransformed\n";
691 sprintf(buf,
" name = %s_rep%d_%d\n",
name.c_str(),irep,icopy);
693 sprintf(buf,
" my geometry = %s\n",
name.c_str());
695 content +=
" :start transformation:\n";
697 sprintf(buf,
" translation = %g %g %g\n",
698 trans_o[0]+trans[0]*icopy,
699 trans_o[1]+trans[1]*icopy,
700 trans_o[2]+trans[2]*icopy);
702 sprintf(buf,
" rotation = %g %g %g %g\n",
703 rot_axis[0],rot_axis[1],rot_axis[2],
704 rot_angle_o+rot_angle*icopy);
706 content +=
" :stop transformation:\n";
712 if (!g)
egsWarning(
"geometry replication: failed to create"
713 " replica %d of %s\n",icopy,
name.c_str());
724 egsWarning(
"EGS_BaseGeometry::setBoundaryTolerance(): error while reading 'boundary tolerance' input\n");
731 egsInformation(
"======================== geometry =====================\n");
742 for (
int j=0; j<egs_geometries[active_glist].nnow; j++) {
743 egs_geometries[active_glist].geoms[j]->printInfo();
749 bool delete_it =
false;
750 if (!input->
isA(
"media input")) {
751 input = inp->takeInputItem(
"media input");
759 vector<string> media_names;
760 int err = input->
getInput(
"media",media_names);
762 int nmed = media_names.size();
763 if (!err && nmed > 0) {
764 med_ind =
new int [nmed];
765 for (
int j=0; j<nmed; j++) {
766 med_ind[j] = egs_geometries[active_glist].addMedium(media_names[j]);
777 med_ind =
new int [nmed];
778 for (
int j=0; j<nmed; j++) {
796 int err = i->
getInput(
"set medium",inp);
800 if (inp.size() == 2) {
803 else if (inp.size() == 3) {
806 else if (inp.size() == 4) {
807 setMedium(inp[0],inp[1],mind[inp[2]],inp[3]);
809 else egsWarning(
"EGS_BaseGeometry::setMedia(): found %d inputs\n"
810 "in a 'set medium' input. 2 or 3 are allowed\n",inp.size());
812 else egsWarning(
"EGS_BaseGeometry::setMedia(): wrong 'set medium'"
828 for (j=0; j<
nreg; j++) {
832 for (j=start; j<=end; j++) {
842 vector<EGS_Float> tmp;
843 int err = i->
getInput(
"set relative density",tmp);
845 if (tmp.size() == 2) {
846 int start = (int)(tmp[0]+0.1);
850 else if (tmp.size() == 3) {
851 int start = (int)(tmp[0]+0.1);
852 int end = (int)(tmp[1]+0.1);
856 egsWarning(
"EGS_BaseGeometry::setRelativeRho(): found %d "
857 "inputs in a 'set relative density' input.\n",tmp.size());
858 egsWarning(
" 2 or 3 are allowed => input ignored\n");
876 for (j=0; j<
nreg; j++) {
880 for (j=start; j<=end; j++) {
891 vector<EGS_Float> tmp;
892 int err = i->
getInput(
"set B scaling",tmp);
894 if (tmp.size() == 2) {
895 int start = (int)(tmp[0]+0.1);
899 else if (tmp.size() == 3) {
900 int start = (int)(tmp[0]+0.1);
901 int end = (int)(tmp[1]+0.1);
905 egsWarning(
"EGS_BaseGeometry::setBScaling(): found %d "
906 "inputs in a 'set B scaling' input.\n", tmp.size());
907 egsWarning(
" 2 or 3 are allowed => input ignored\n");
914 int err0 = input->
getInput(
"B scaling reference density", refD);
928 EGS_Float t, ttot = 0;
933 ireg =
howfar(ireg,x,u,t,&imed);
938 isections[0].
rhof = 1;
939 isections[0].
ireg = -1;
940 isections[0].
imed = -1;
949 for (
int j=ifirst; j<n; j++) {
950 isections[j].
imed = imed;
952 isections[j].
ireg = ireg;
954 int inew =
howfar(ireg,x,u,t,&imed);
956 isections[j].
t = ttot;
957 if (inew < 0 || inew == ireg) {
964 return ireg >= 0 ? -1 : n;
977 if (bit < 0 || bit >= 8*
sizeof(EGS_BPType)) {
978 egsWarning(
"EGS_BaseGeometry::addBooleanProperty: attempt to set the "
979 "%d'th bith!\n",bit);
982 EGS_BPType prop = 1 << bit;
985 for (
int j=0; j<
nreg; j++) {
999 if (start == 0 && end ==
nreg-1 && step==1) {
1005 for (
int j=0; j<
nreg; j++) {
1009 for (
int j=start; j<=end; j+=step) {
1017 if (bit < 0 || bit >= 8*
sizeof(EGS_BPType)) {
1018 egsWarning(
"EGS_BaseGeometry::addBooleanProperty: attempt to set the "
1019 "%d'th bith!\n",bit);
1028 if (start == 0 && end ==
nreg-1 && step==1) {
1032 EGS_BPType prop = 1 << bit;
1035 for (
int j=0; j<
nreg; j++) {
1039 for (
int j=start; j<=end; j+=step) {
1069 for (
int i=0; i<tokens.size(); i++) {
1070 if (tokens[i].find_first_not_of(
"-0123456789") == std::string::npos) {
1071 regs.push_back(atoi(tokens[i].c_str()));
1083 size_t insert_pos = 0;
1087 for (
int j = 0; j < tokens.size(); j++) {
1089 for (
int i = 0; i <
labels.size(); i++) {
1090 if (
labels[i].
name.compare(tokens[j]) == 0) {
1093 regs.insert(regs.begin() + insert_pos,
labels[i].regions.begin(),
labels[i].regions.end());
1096 insert_pos +=
labels[i].regions.size();
1107 if (!foundLabel && regs.size() > 0) {
1108 if (insert_pos >= regs.size()) {
1109 egsFatal(
"EGS_BaseGeometry::getLabelRegions(): insert_pos out of bounds "
1110 "for geometry %s. Was getNumberRegions() called before "
1111 "getLabelRegions() for input \"%s\"?\n",
1112 getName().c_str(), str.c_str());
1122 sort(regs.begin(), regs.end());
1123 regs.erase(unique(regs.begin(), regs.end()), regs.end());
1134 int err = i->
getInput(
"set label", inp);
1139 egsWarning(
"EGS_BaseGeometry::setLabels(): error while reading 'set label' input\n");
1147 labelCount += nLabel;
1162 if (tokens.empty()) {
1163 egsWarning(
"EGS_BaseGeometry::setLabels(): no label specified\n");
1168 label.name = tokens[0];
1171 if (tokens.size() == 1) {
1172 label.regions.reserve(
nreg);
1173 for (
int i = 0; i <
nreg; i++) {
1174 label.regions.push_back(i);
1183 egsWarning(
"EGS_BaseGeometry::setLabels(): geometry %s, label %s, invalid regions\n",
getName().c_str(),
name.c_str());
1189 if (label.regions.size() == 0) {
1190 egsWarning(
"EGS_BaseGeometry::setLabels(): geometry %s, label \"%s\": no region specified\n",
getName().c_str(), label.name.c_str());
1204 if (reg < 0 || reg >=
nreg) {
1205 egsWarning(
"EGS_BaseGeometry::validateRegions(): geometry %s, region %d is out of bounds\n",
getName().c_str(), reg);
Base class for advanced EGSnrc C++ applications.
Base geometry class. Every geometry class must be derived from EGS_BaseGeometry.
virtual int getGlobalRegionOffset(const string geomName)
Get the global region number for the first region in the geometry.
virtual int computeIntersections(int ireg, int n, const EGS_Vector &x, const EGS_Vector &u, EGS_GeometryIntersections *isections)
Calculates intersection distances to region boundaries.
static int nMedia()
Get the number of media registered so far by all geometries.
bool validateRegions(const std::vector< int > ®ions)
Validate that all region numbers are within valid bounds.
EGS_BPType bproperty
A bit mask of boolean properties for the entire geometry.
virtual EGS_Float howfarToOutside(int ireg, const EGS_Vector &x, const EGS_Vector &u)
virtual void setBScaling(int start, int end, EGS_Float bf)
Set the B field scaling factor in regions.
void setMedia(EGS_Input *inp)
Set the media in the geometry from the input pointed to by inp.
static EGS_BaseGeometry * createSingleGeometry(EGS_Input *inp)
Create a single geometry from the input inp.
virtual const string & getType() const =0
Get the geometry type.
static void describeGeometries()
Describes all existing geometries.
int nreg
Number of local regions in this geometry.
virtual int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, EGS_Float &t, int *newmed=0, EGS_Vector *normal=0)=0
Calculate the distance to a boundary from x along the direction u.
bool has_B_scaling
Does this geometry has B field scaling factor?
bool has_rho_scaling
Does this geometry have relative mass density scvaling?
EGS_Float boundaryTolerance
Boundary tolerance for geometries that need it.
bool hasBScaling() const
Does this geometry object have a B field scaling feature?
short * region_media
Array of media indeces.
void setName(EGS_Input *inp)
Set the name of the geometry from the input inp.
static void setActiveGeometryList(int list)
Set the currently active geometry list.
void setMedium(const string &Name)
Set all regions to a medium with name Name.
static EGS_BaseGeometry * createGeometry(EGS_Input *)
Create a geometry (or geometries) from a given input.
const string & getName() const
Get the name of this geometry.
EGS_Float * rhor
Array with relative mass densities.
virtual EGS_Float getRelativeRho(int ireg) const
Get the relative mass density in region ireg.
EGS_Float * bfactor
Array with B field scaling factors.
virtual void setBooleanProperty(EGS_BPType prop)
Set the boolean properties of the entire geometry to prop.
static string getUniqueName()
Get a unique geometry name.
static void clearGeometries()
Clears (deletes) all geometries in the currently active geometry list.
virtual int medium(int ireg) const
Returns the medium index in region ireg.
static int error_flag
Set to non-zero status if a geometry problem is encountered.
string name
Name of this geometry.
int regions() const
Returns the number of local regions in this geometry.
int setLabels(EGS_Input *input)
Set the labels from an input block.
virtual void setRelativeRho(int start, int end, EGS_Float rho)
Set the relative mass density in regions.
virtual void printInfo() const
Print information about this geometry.
int ref()
Increase the reference count to this geometry.
static EGS_BaseGeometry * getGeometry(const string &Name)
Get a pointer to the geometry named Name.
virtual void addBooleanProperty(int bit)
Add a boolean property for the entire geometry by setting the bit'th bit.
static int addMedium(const string &medname)
Add a medium or get the index of an existing medium.
EGS_Float rhoRef
Reference density for B field scaling.
static int getMediumIndex(const string &medname)
Get the index of a medium named medname.
virtual ~EGS_BaseGeometry()
Destructor.
EGS_BaseGeometry(const string &Name)
Construct a geometry named Name.
static const char * getMediumName(int ind)
Get the name of medium with index ind.
void setBoundaryTolerance(EGS_Input *inp)
Set the value of the boundary tolerance from the input inp.
vector< EGS_Label > labels
Labels.
virtual void getLabelRegions(const string &str, vector< int > ®s, bool sanitize=true)
Get the list of all regions labeled with str.
EGS_BPType * bp_array
An array of boolean properties on a region by region basis.
virtual void getNumberRegions(const string &str, vector< int > ®s)
Get a list of all the regions labeled with a number.
A class for dynamically loading shared libraries.
const char * libraryName() const
Returns the name of the library object as given in the constructor.
bool isLoaded() const
Returns true if the library is loaded, false otherwise.
bool load()
Loads the library.
void * resolve(const char *func)
Returns the address of the exported symbol func.
A class representing 3D vectors.
EGS_Application class header file.
EGS_BaseGeometry class header file.
Global egspp functions header file.
EGS_Library class header file.
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.
const EGS_Float distanceEpsilon
The distanceEpsilon constant for physical distance comparisons.
const EGS_I64 loopMax
The maximum number of iterations for near-infinite loops.
EGS_InfoFunction EGS_EXPORT egsWarning
Always use this function for reporting warnings.
const EGS_Float veryFar
A very large float.
EGS_Float t
distance to next region boundary
EGS_Float rhof
relative mass density in that region