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());
Base class for advanced EGSnrc C++ applications.
Base geometry class. Every geometry class must be derived from EGS_BaseGeometry.
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.
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.
virtual void getLabelRegions(const string &str, vector< int > ®s)
Get the list of all regions labeled with str.
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 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.
vector< label > labels
Labels.
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.
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