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 EGS_Float getMediumRho(
int ind)
const {
251 return app->getMediumRho(ind);
267 class EGS_LOCAL EGS_PrivateGeometryLists {
269 EGS_PrivateGeometryLists() : nnow(0), ntot(0) {
270 addList(
new EGS_GeometryPrivate);
272 ~EGS_PrivateGeometryLists() {
275 for (
int j=0; j<nnow; j++) {
285 EGS_GeometryPrivate &operator[](
int j) {
288 void addList(EGS_GeometryPrivate *l) {
293 EGS_GeometryPrivate **tmp =
new EGS_GeometryPrivate* [ntot+10];
294 for (
int j=0; j<nnow; j++) {
306 EGS_GeometryPrivate **lists;
309 string EGS_GeometryPrivate::geom_delimeter =
"geometry definition";
310 string EGS_GeometryPrivate::libkey =
"library";
311 string EGS_GeometryPrivate::create_key =
"createGeometry";
314 int EGS_BaseGeometry::active_glist = 0;
316 static char buf_unique[32];
324 egsWarning(
"createSingleGeometry: null input?\n");
327 int error = i->
getInput(EGS_GeometryPrivate::libkey,libname);
329 egsWarning(
"createSingleGeometry: input item %s does not define the"
330 " geometry library\n",i->
name());
334 for (
unsigned int j=0; j<glibs.size(); j++) {
335 if (libname == glibs[j]->libraryName()) {
341 lib =
new EGS_Library(libname.c_str(),dso_path.c_str());
344 egsWarning(
"createSingleGeometry: Failed to load library '%s' from"
345 " %s\n",libname.c_str(),dso_path.c_str());
348 glibs.push_back(lib);
350 EGS_GeometryCreationFunction gcreate = (EGS_GeometryCreationFunction)
351 lib->
resolve(EGS_GeometryPrivate::create_key.c_str());
353 egsWarning(
"createSingleGeometry: failed to resolve the %s function\n"
354 " in geometry library %s\n",
355 EGS_GeometryPrivate::create_key.c_str(),lib->
libraryName());
360 egsWarning(
"createSingleGeometry: got null geometry\n");
366 if (!addGeometry(g)) {
367 egsWarning(
"createSingleGeometry: failed to add the geometry %s\n"
368 " to the list of geometries. This implies that a geometry with"
369 " this name already exists\n",g->
getName().c_str());
379 static EGS_LOCAL EGS_PrivateGeometryLists egs_geometries;
388 for (EGS_I64 loopCount=0; loopCount<=
loopMax; ++loopCount) {
390 egsFatal(
"EGS_BaseGeometry::howfarToOutside: Too many iterations were required! Input may be invalid, or consider increasing loopMax.");
394 int inew = howfar(ireg,xx,u,t);
406 int n = egs_geometries.size();
409 for (
int j=n; j<=list; j++)
412 egs_geometries.addList(
new EGS_GeometryPrivate);
430 region_media(0), med(-1), has_rho_scaling(false), rhor(0),
431 has_B_scaling(false), has_Ref_rho(false), bfactor(0), rhoRef(1.0),
432 nref(0), debug(false), is_convex(true), bproperty(0), bp_array(0),
436 if (!egs_geometries.size()) {
437 egs_geometries.addList(
new EGS_GeometryPrivate);
442 if (egs_geometries[active_glist].addGeometry(
this) < 0)
443 egsFatal(
"EGS_BaseGeometry::EGS_BaseGeometry:\n"
444 " a geometry with name %s already exists\n",name.c_str());
461 egs_geometries[active_glist].removeGeometry(
this);
465 egs_geometries[active_glist].clearGeometries();
469 return egs_geometries[active_glist].getGeometry(Name);
473 return egs_geometries[active_glist].geoms;
476 int EGS_BaseGeometry::getNGeometries() {
477 return egs_geometries[active_glist].nnow;
481 med = egs_geometries[active_glist].addMedium(Name);
483 for (
int j=0; j<
nreg; j++) {
489 return egs_geometries[active_glist].addMedium(medname);
493 return egs_geometries[active_glist].getMediumIndex(medname);
498 int imed = egs_geometries[active_glist].addMedium(Name);
518 for (
int j=0; j<
nreg; j++) {
522 for (
int j=istart; j<=iend; j+=delta) {
528 return egs_geometries[active_glist].nMedia();
532 return egs_geometries[active_glist].getMediumName(ind);
535 EGS_Float EGS_BaseGeometry::getMediumRho(
int ind)
const {
536 return egs_geometries[active_glist].getMediumRho(ind);
540 return egs_geometries[active_glist].setApplication(App);
544 return egs_geometries[active_glist].createSingleGeometry(input);
549 bool delete_it =
false;
550 if (!input->
isA(egs_geometries[active_glist].geom_delimeter)) {
551 ginput = input->
takeInputItem(egs_geometries[active_glist].geom_delimeter);
555 egsWarning(
"EGS_BaseGeometry::createGeometry: no geometry specification"
562 EGS_BaseGeometry *g = egs_geometries[active_glist].createSingleGeometry(ij);
569 for (
int j=0; j<egs_geometries[active_glist].nnow; j++) {
570 string gname = egs_geometries[active_glist].geoms[j]->getName();
571 for (
int k=0; k<egs_geometries[active_glist].nnow; k++) {
575 if (gname == egs_geometries[active_glist].geoms[k]->
getName()) {
576 egsFatal(
"\ncreateGeometry: Error: multiple geometries with"
577 " the same name exist: %s\n\n", gname.c_str());
583 egsFatal(
"EGS_BaseGeometry::createGeometry: errors during geometry"
588 int err = ginput->
getInput(
"simulation geometry",sim_geom);
590 egsWarning(
"EGS_BaseGeometry::createGeometry: missing/wrong keyword"
591 " 'simulation geometry'\n");
595 if (!g)
egsWarning(
"EGS_BaseGeometry::createGeometry: a geometry with "
596 "the name %s does not exist\n",sim_geom.c_str());
604 sprintf(buf_unique,
"geometry%d",egs_geometries[active_glist].nnow);
605 string result(buf_unique);
619 vector<EGS_Float> trans, trans_o;
620 vector<EGS_Float> rot_axis;
621 EGS_Float rot_angle, rot_angle_o;
622 int err1 = inp->
getInput(
"type",typ);
623 int err2 = inp->
getInput(
"number of copies",ncopy);
624 int err3 = inp->
getInput(
"translation delta",trans);
625 int err4 = inp->
getInput(
"first translation",trans_o);
626 int err5 = inp->
getInput(
"rotation axis",rot_axis);
627 int err6 = inp->
getInput(
"rotation delta",rot_angle);
628 int err7 = inp->
getInput(
"first rotation",rot_angle_o);
632 if (err1)
egsWarning(
"geometry replication: 'type' not defined ->"
633 " ignoring input\n");
634 if (err2)
egsWarning(
"geometry replication: 'number of copies' "
635 "not defined -> ignoring input\n");
640 egsWarning(
"geometry replication: %d copies?\n",ncopy);
644 if (err3 || trans.size() != 3) {
645 egsWarning(
"geometry replication: got %d inputs for "
646 "'translation', need 3\n",trans.size());
651 trans_o.push_back(0);
652 trans_o.push_back(0);
653 trans_o.push_back(0);
658 else if (typ ==
"rotation") {
659 if (err5 || rot_axis.size() != 3) {
660 egsWarning(
"geometry replication: got %d inputs for "
661 "'rotation axis', need 3\n",rot_axis.size());
665 egsWarning(
"geometry replication: missing 'rotation delta'"
675 egsWarning(
"geometry replication: unknown replica type %s\n",
683 for (
int icopy=1; icopy<=ncopy; icopy++) {
686 content +=
" library = egs_gtransformed\n";
687 sprintf(buf,
" name = %s_rep%d_%d\n",name.c_str(),irep,icopy);
689 sprintf(buf,
" my geometry = %s\n",name.c_str());
691 content +=
" :start transformation:\n";
693 sprintf(buf,
" translation = %g %g %g\n",
694 trans_o[0]+trans[0]*icopy,
695 trans_o[1]+trans[1]*icopy,
696 trans_o[2]+trans[2]*icopy);
698 sprintf(buf,
" rotation = %g %g %g %g\n",
699 rot_axis[0],rot_axis[1],rot_axis[2],
700 rot_angle_o+rot_angle*icopy);
702 content +=
" :stop transformation:\n";
708 if (!g)
egsWarning(
"geometry replication: failed to create"
709 " replica %d of %s\n",icopy,name.c_str());
720 egsWarning(
"EGS_BaseGeometry::setBoundaryTolerance(): error while reading 'boundary tolerance' input\n");
727 egsInformation(
"======================== geometry =====================\n");
738 for (
int j=0; j<egs_geometries[active_glist].nnow; j++) {
739 egs_geometries[active_glist].geoms[j]->printInfo();
745 bool delete_it =
false;
746 if (!input->
isA(
"media input")) {
755 vector<string> media_names;
756 int err = input->
getInput(
"media",media_names);
758 int nmed = media_names.size();
759 if (!err && nmed > 0) {
760 med_ind =
new int [nmed];
761 for (
int j=0; j<nmed; j++) {
762 med_ind[j] = egs_geometries[active_glist].addMedium(media_names[j]);
773 med_ind =
new int [nmed];
774 for (
int j=0; j<nmed; j++) {
792 int err = i->
getInput(
"set medium",inp);
796 if (inp.size() == 2) {
799 else if (inp.size() == 3) {
802 else if (inp.size() == 4) {
803 setMedium(inp[0],inp[1],mind[inp[2]],inp[3]);
805 else egsWarning(
"EGS_BaseGeometry::setMedia(): found %d inputs\n"
806 "in a 'set medium' input. 2 or 3 are allowed\n",inp.size());
808 else egsWarning(
"EGS_BaseGeometry::setMedia(): wrong 'set medium'"
824 for (j=0; j<
nreg; j++) {
828 for (j=start; j<=end; j++) {
838 vector<EGS_Float> tmp;
839 int err = i->
getInput(
"set relative density",tmp);
841 if (tmp.size() == 2) {
842 int start = (int)(tmp[0]+0.1);
846 else if (tmp.size() == 3) {
847 int start = (int)(tmp[0]+0.1);
848 int end = (int)(tmp[1]+0.1);
852 egsWarning(
"EGS_BaseGeometry::setRelativeRho(): found %d "
853 "inputs in a 'set relative density' input.\n",tmp.size());
854 egsWarning(
" 2 or 3 are allowed => input ignored\n");
872 for (j=0; j<
nreg; j++) {
876 for (j=start; j<=end; j++) {
887 vector<EGS_Float> tmp;
888 int err = i->
getInput(
"set B scaling",tmp);
890 if (tmp.size() == 2) {
891 int start = (int)(tmp[0]+0.1);
895 else if (tmp.size() == 3) {
896 int start = (int)(tmp[0]+0.1);
897 int end = (int)(tmp[1]+0.1);
901 egsWarning(
"EGS_BaseGeometry::setBScaling(): found %d "
902 "inputs in a 'set B scaling' input.\n", tmp.size());
903 egsWarning(
" 2 or 3 are allowed => input ignored\n");
910 int err0 = input->
getInput(
"B scaling reference density", refD);
924 EGS_Float t, ttot = 0;
929 ireg =
howfar(ireg,x,u,t,&imed);
934 isections[0].
rhof = 1;
935 isections[0].
ireg = -1;
936 isections[0].
imed = -1;
945 for (
int j=ifirst; j<n; j++) {
946 isections[j].
imed = imed;
948 isections[j].
ireg = ireg;
950 int inew =
howfar(ireg,x,u,t,&imed);
952 isections[j].
t = ttot;
953 if (inew < 0 || inew == ireg) {
960 return ireg >= 0 ? -1 : n;
973 if (bit < 0 || bit >= 8*
sizeof(EGS_BPType)) {
974 egsWarning(
"EGS_BaseGeometry::addBooleanProperty: attempt to set the "
975 "%d'th bith!\n",bit);
978 EGS_BPType prop = 1 << bit;
981 for (
int j=0; j<
nreg; j++) {
995 if (start == 0 && end ==
nreg-1 && step==1) {
1001 for (
int j=0; j<
nreg; j++) {
1005 for (
int j=start; j<=end; j+=step) {
1013 if (bit < 0 || bit >= 8*
sizeof(EGS_BPType)) {
1014 egsWarning(
"EGS_BaseGeometry::addBooleanProperty: attempt to set the "
1015 "%d'th bith!\n",bit);
1024 if (start == 0 && end ==
nreg-1 && step==1) {
1028 EGS_BPType prop = 1 << bit;
1031 for (
int j=0; j<
nreg; j++) {
1035 for (
int j=start; j<=end; j+=step) {
1048 vector<string> tokens;
1049 const char *ptr = str.c_str();
1051 const char *begin = ptr;
1052 while (*ptr !=
' ' && *ptr) {
1055 tokens.push_back(
string(begin, ptr));
1057 while (*ptr++ !=
'\0');
1059 for (
int i=0; i<tokens.size(); i++) {
1062 if (tokens[i].find_first_not_of(
" -0123456789") == std::string::npos) {
1063 regs.push_back(atoi(tokens[i].c_str()));
1072 vector<string> tokens;
1073 const char *ptr = str.c_str();
1075 const char *begin = ptr;
1076 while (*ptr !=
' ' && *ptr) {
1079 tokens.push_back(
string(begin, ptr));
1081 while (*ptr++ !=
'\0');
1084 for (
int j=0; j<tokens.size(); j++) {
1085 for (
int i=0; i<
labels.size(); i++) {
1086 if (
labels[i].name.compare(tokens[j]) == 0) {
1087 regs.insert(regs.end(),
labels[i].regions.begin(),
labels[i].regions.end());
1093 sort(regs.begin(), regs.end());
1094 regs.erase(unique(regs.begin(), regs.end()), regs.end());
1105 int err = i->
getInput(
"set label",inp);
1110 egsWarning(
"EGS_BaseGeometry::setLabels(): error while reading 'set label' input\n");
1118 labelCount += nLabel;
1128 vector<string> tokens;
1129 const char *ptr = inp.c_str();
1131 const char *begin = ptr;
1132 while (*ptr !=
' ' && *ptr) {
1135 tokens.push_back(
string(begin, ptr));
1137 while (*ptr++ !=
'\0');
1140 if (tokens.size() < 1) {
1141 egsWarning(
"EGS_BaseGeometry::setLabels(): no label name\n");
1147 lab.name = tokens[0];
1148 for (
int i=1; i<tokens.size(); i++) {
1149 int reg = atoi(tokens[i].c_str());
1150 if (reg < nreg && reg >= 0) {
1151 lab.regions.push_back(reg);
1154 egsWarning(
"EGS_BaseGeometry::setLabels(): label \"%s\": region %d is beyond the number " \
1155 "of regions in this geometry\n", lab.name.c_str(), reg);
1160 if (lab.regions.size() <= 0) {
1165 sort(lab.regions.begin(), lab.regions.end());
1166 lab.regions.erase(unique(lab.regions.begin(), lab.regions.end()), lab.regions.end());
virtual const string & getType() const =0
Get the geometry type.
const EGS_I64 loopMax
The maximum number of iterations for near-infinite loops.
A class for dynamically loading shared libraries.
virtual int medium(int ireg) const
Returns the medium index in region ireg.
virtual void printInfo() const
Print information about this geometry.
EGS_Float t
distance to next region boundary
EGS_Float * bfactor
Array with B field scaling factors.
virtual EGS_Float howfarToOutside(int ireg, const EGS_Vector &x, const EGS_Vector &u)
virtual void getNumberRegions(const string &str, vector< int > ®s)
Get a list of all the regions labeled with a number.
EGS_Float rhoRef
Reference density for B field scaling.
const char * libraryName() const
Returns the name of the library object as given in the constructor.
EGS_Float rhof
relative mass density in that region
const EGS_Float distanceEpsilon
The distanceEpsilon constant for physical distance comparisons.
EGS_BPType bproperty
A bit mask of boolean properties for the entire geometry.
EGS_BPType * bp_array
An array of boolean properties on a region by region basis.
EGS_BaseGeometry(const string &Name)
Construct a geometry named Name.
A class representing 3D vectors.
int setLabels(EGS_Input *input)
Set the labels from an input block.
Global egspp functions header file.
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.
const EGS_Float veryFar
A very large float.
vector< label > labels
Labels.
Base geometry class. Every geometry class must be derived from EGS_BaseGeometry.
virtual void setRelativeRho(int start, int end, EGS_Float rho)
Set the relative mass density in regions.
void setBoundaryTolerance(EGS_Input *inp)
Set the value of the boundary tolerance from the input inp.
static void setActiveGeometryList(int list)
Set the currently active geometry list.
virtual void setBScaling(int start, int end, EGS_Float bf)
Set the B field scaling factor in regions.
static EGS_BaseGeometry * getGeometry(const string &Name)
Get a pointer to the geometry named Name.
EGS_InfoFunction EGS_EXPORT egsFatal
Always use this function for reporting fatal errors.
static int nMedia()
Get the number of media registered so far by all geometries.
virtual void getLabelRegions(const string &str, vector< int > ®s)
Get the list of all regions labeled with str.
static string getUniqueName()
Get a unique geometry name.
void setMedia(EGS_Input *inp)
Set the media in the geometry from the input pointed to by inp.
static int addMedium(const string &medname)
Add a medium or get the index of an existing medium.
static void clearGeometries()
Clears (deletes) all geometries in the currently active geometry list.
EGS_InfoFunction EGS_EXPORT egsInformation
Always use this function for reporting the progress of a simulation and any other type of information...
EGS_Library class header file.
virtual int computeIntersections(int ireg, int n, const EGS_Vector &x, const EGS_Vector &u, EGS_GeometryIntersections *isections)
Calculates intersection distances to region boundaries.
bool hasBScaling() const
Does this geometry object have a B field scaling feature?
void setMedium(const string &Name)
Set all regions to a medium with name Name.
void setName(EGS_Input *inp)
Set the name of the geometry from the input inp.
static void describeGeometries()
Describes all existing geometries.
virtual EGS_Float getRelativeRho(int ireg) const
Get the relative mass density in region ireg.
EGS_Float boundaryTolerance
Boundary tolerance for geometries that need it.
static int getMediumIndex(const string &medname)
Get the index of a medium named medname.
short * region_media
Array of media indeces.
virtual ~EGS_BaseGeometry()
Destructor.
bool has_rho_scaling
Does this geometry have relative mass density scvaling?
static EGS_BaseGeometry * createGeometry(EGS_Input *)
Create a geometry (or geometries) from a given input.
static int error_flag
Set to non-zero status if a geometry problem is encountered.
bool load()
Loads the library.
static EGS_BaseGeometry * createSingleGeometry(EGS_Input *inp)
Create a single geometry from the input inp.
static const char * getMediumName(int ind)
Get the name of medium with index ind.
const string & getName() const
Get the name of this geometry.
EGS_BaseGeometry class header file.
int nreg
Number of local regions in this geometry.
void * resolve(const char *func)
Returns the address of the exported symbol func.
EGS_Application class header file.
EGS_Float * rhor
Array with relative mass densities.
Base class for advanced EGSnrc C++ applications.
virtual void addBooleanProperty(int bit)
Add a boolean property for the entire geometry by setting the bit'th bit.
bool has_B_scaling
Does this geometry has B field scaling factor?
virtual void setBooleanProperty(EGS_BPType prop)
Set the boolean properties of the entire geometry to prop.
EGS_InfoFunction EGS_EXPORT egsWarning
Always use this function for reporting warnings.
bool isLoaded() const
Returns true if the library is loaded, false otherwise.