48 #define M_PI 3.14159265358979323846
51 string EGS_SimpleCone::type =
"EGS_SimpleCone";
52 string EGS_ParallelCones::type =
"EGS_ParallelCones";
53 string EGS_ConeSet::type =
"EGS_ConeSet";
54 string EGS_ConeStack::type =
"EGS_ConeStack";
56 static bool EGS_CONES_LOCAL inputSet =
false;
58 void EGS_ConeStack::clear(
bool all) {
61 for (
int j=0; j<nl; j++) {
62 for (
int i=0; i<nr[j]; i++)
63 if (!cones[j][i]->
deref()) {
79 void EGS_ConeStack::resize() {
80 int nnew = nltot + N_CS_GROW;
81 int *new_nr =
new int [nnew], *new_flag =
new int [nnew];
82 EGS_Float *new_pos =
new EGS_Float [nnew+1];
84 for (
int j=0; j<nl; j++) {
86 new_flag[j] = flag[j];
88 new_cones[j] = cones[j];
91 new_pos[nl] = pos[nl];
101 void EGS_ConeStack::addLayer(EGS_Float thick,
const vector<EGS_Float> &rtop,
102 const vector<EGS_Float> &rbottom,
103 const vector<string> &med_names) {
104 int this_nr = rbottom.size();
106 egsWarning(
"EGS_ConeStack::addLayer: no bottom radii?\n");
110 if ((
int)med_names.size() != this_nr) {
111 egsWarning(
"EGS_ConeStack::addLayer: number of cone radii (%d) is"
112 " different from number of media (%d)\n",this_nr,med_names.size());
116 bool same_radii =
false;
117 if (rtop.size() != rbottom.size()) {
120 egsWarning(
"EGS_ConeStack::addLayer: zero top radii does not"
121 " work for the first layer\n");
128 egsWarning(
"EGS_ConeStack::addLayer: number of bottom radii (%d)"
129 " is different from number of top radii (%d)\n",this_nr,
140 Rout = rbottom[this_nr-1];
150 pos[nl+1] = pos[nl] + thick;
153 for (
int ir=0; ir<this_nr; ir++) {
154 EGS_Float Rtop = same_radii ? cones[nl-1][ir]->getRadius(x) : rtop[ir];
157 cones[nl][ir]->
ref();
158 if (ir == this_nr-1) {
176 if (this_nr > nmax) {
186 void EGS_ConeStack::printInfo()
const {
189 for (
int il=0; il<nl; il++) {
195 for (i=0; i<nr[il]; i++) {
199 x = xo + a*(pos[il+1]-pos[0]);
200 for (i=0; i<nr[il]; i++) {
204 for (i=0; i<nr[il]; i++) {
209 egsInformation(
"=====================================================\n");
212 void EGS_SimpleCone::printInfo()
const {
216 egsInformation(
" opening angle = %g degrees\n",180*atan(gamma)/M_PI);
223 egsInformation(
"=====================================================\n");
226 void EGS_ParallelCones::printInfo()
const {
229 egsInformation(
" opening angle = %g degrees\n",180*atan(gamma)/M_PI);
232 for (
int j=0; j<nc; j++) {
235 egsInformation(
"\n=====================================================\n");
238 void EGS_ConeSet::printInfo()
const {
244 for (
int j=0; j<nc; j++) {
247 egsInformation(
"\n=====================================================\n");
253 static void setInputs() {
256 setBaseGeometryInputs(
false);
258 geomBlockInput->getSingleInput(
"library")->setValues({
"egs_cones"});
261 auto typePtr = geomBlockInput->addSingleInput(
"type",
true,
"The type of cone.", {
"EGS_ConeStack",
"EGS_SimpleCone",
"EGS_ParallelCones",
"EGS_ConeSet"});
263 geomBlockInput->addSingleInput(
"axis",
false,
"The unit vector defining the axis along the length of the cones. Layers or cones are added sequentially in the vector direction.");
265 auto inpPtr = geomBlockInput->addSingleInput(
"apex",
false,
"The position of the cone apex (x, y, z). For EGS_ParallelCones, this is the position of the first cone apex.");
266 inpPtr->addDependency(typePtr,
"EGS_SimpleCone");
267 inpPtr->addDependency(typePtr,
"EGS_ParallelCones");
268 inpPtr->addDependency(typePtr,
"EGS_ConeSet");
269 inpPtr->addDependency(typePtr,
"EGS_ConeStack",
true);
272 auto blockPtr = geomBlockInput->addBlockInput(
"layer");
273 blockPtr->addDependency(typePtr,
"EGS_ConeStack");
274 blockPtr->addSingleInput(
"thickness",
true,
"The thickness of the layer.");
275 blockPtr->addSingleInput(
"top radii",
false,
"A list of the top cone radii. If omitted, the top radii are assumed to be the same as a bottom radii from the previous layer. This improves the algorithm efficiency.");
276 blockPtr->addSingleInput(
"bottom radii",
true,
"A list of the bottom cone radii.");
277 blockPtr->addSingleInput(
"media",
true,
"A list of media names, one for each region.");
280 auto anglesPtr = geomBlockInput->addSingleInput(
"opening angles",
false,
"A list of angles in degrees.");
281 anglesPtr->addDependency(typePtr,
"EGS_ConeSet");
282 auto anglesRadPtr = geomBlockInput->addSingleInput(
"opening angles in radian",
false,
"A list of angles in radians.");
283 anglesRadPtr->addDependency(typePtr,
"EGS_ConeSet");
285 anglesRadPtr->addDependency(anglesPtr,
"",
true);
286 anglesPtr->addDependency(anglesRadPtr,
"",
true);
287 geomBlockInput->addSingleInput(
"flag",
false,
"0 or 1 or 2. This input affects the region numbering algorithm; see the documentation for details.")->addDependency(typePtr,
"EGS_ConeSet");
288 auto mediaPtr = geomBlockInput->addBlockInput(
"media input");
289 mediaPtr->addDependency(typePtr,
"EGS_ConeSet");
290 mediaPtr->addSingleInput(
"media",
true,
"");
291 mediaPtr->addSingleInput(
"set medium",
false,
"");
294 auto anglePtr = geomBlockInput->addSingleInput(
"opening angle",
false,
"The opening angle of the cone in degrees.");
295 anglePtr->addDependency(typePtr,
"EGS_SimpleCone");
296 anglePtr->addDependency(typePtr,
"EGS_ParallelCones");
297 auto heightPtr = geomBlockInput->addSingleInput(
"height",
false,
"The height of the cone.");
298 heightPtr->addDependency(typePtr,
"EGS_SimpleCone");
299 auto mediaPtr2 = geomBlockInput->addBlockInput(
"media input");
300 mediaPtr2->addDependency(typePtr,
"EGS_SimpleCone");
301 mediaPtr2->addDependency(typePtr,
"EGS_ParallelCones");
302 mediaPtr2->addSingleInput(
"media",
true,
"");
303 mediaPtr2->addSingleInput(
"set medium",
false,
"");
306 auto apexPtr = geomBlockInput->addSingleInput(
"apex distances",
false,
"A list of distances from the first apex.");
307 apexPtr->addDependency(typePtr,
"EGS_ParallelCones");
310 EGS_CONES_EXPORT
string getExample() {
314 # Examples of each of the egs_cones types follow
315 # Simply uncomment the :start line for the example that you
318 # EGS_ConeStack example
323 axis = 1.2417 0 0 -1 0 0
327 bottom radii = 0.0858
332 top radii = 0. 0.0858
333 bottom radii = 0.3125 0.35
338 bottom radii = 0.3125 0.35
343 top radii = 0.050 0.3125 0.35
344 bottom radii = 0.050 0.3125 0.35
345 media = water air water
349 # EGS_SimpleCone example
352 type = EGS_SimpleCone
353 name = my_simple_cone
357 opening angle = 30 # deg
363 # EGS_ParallelCones example
366 type = EGS_ParallelCones
367 name = my_parallel_cones
370 apex distances = 1 2 3
371 opening angle = 30 # deg
374 # EGS_ConeSet example
381 opening angles = 10 20 30
383 media = water air water
392 EGS_CONES_EXPORT shared_ptr<EGS_BlockInput> getInputs() {
396 return geomBlockInput;
402 egsWarning(
"createGeometry(cones): null input?\n");
406 int err = input->
getInput(
"type",type);
408 egsWarning(
"createGeometry(cones): object type not specified\n");
411 if (type ==
"EGS_ConeStack") {
412 vector<EGS_Float> axis;
415 egsWarning(
"createGeometry(EGS_ConeStack): no axis input\n");
418 if (axis.size() != 6) {
419 egsWarning(
"createGeometry(EGS_ConeStack): wrong axis input"
420 " (expecting 6 instead of %d inputs)\n",axis.size());
428 vector<int> layerLabels;
430 vector<EGS_Float> rtop, rbottom;
431 vector<string> media;
433 err = layer->
getInput(
"thickness",thickness);
435 egsWarning(
"createGeometry(EGS_ConeStack): missing 'thickness'"
436 " input for layer %d\n --> layer ignored\n",nl);
438 err = layer->
getInput(
"top radii",rtop);
439 err = layer->
getInput(
"bottom radii",rbottom);
440 if (err)
egsWarning(
"createGeometry(EGS_ConeStack): missing "
441 "'bottom radii' input for layer %d\n",nl);
442 int err1 = layer->
getInput(
"media",media);
443 if (err1)
egsWarning(
"createGeometry(EGS_ConeStack): missing "
444 "'media' input for layer %d\n",nl);
449 g->addLayer(thickness,rtop,rbottom,media);
452 layerLabels.push_back(g->
setLabels(layer));
457 egsWarning(
"createGeometry(EGS_ConeStack): zero layers\n");
464 for (
size_t i=0; i<layerLabels.size(); i++) {
465 for (
int j=0; j<layerLabels[i]; j++) {
466 g->shiftLabelRegions(count,i);
479 vector<EGS_Float> tmp;
482 if (err || tmp.size() != 3)
483 egsWarning(
"createGeometry(cones): no 'apex' input, "
484 "assuming (0,0,0)\n");
495 if (err || tmp.size() != 3)
496 egsWarning(
"createGeometry(cones): no 'axis' input, assuming "
505 if (input->
compare(type,
"EGS_ConeSet")) {
506 vector<EGS_Float> angles;
507 err = input->
getInput(
"opening angles",angles);
508 bool is_radian =
false;
511 err = input->
getInput(
"opening angles in radian",angles);
513 egsWarning(
"createGeometry(cones): no 'opening angles' or "
514 "'opening angles in radian' input\n");
521 int nc = angles.size();
522 EGS_Float *gamma =
new EGS_Float [nc];
523 for (
int j=0; j<nc; j++) {
524 if (angles[j] <= 0) {
525 egsWarning(
"createGeometry(cones): opening angles must be"
530 EGS_Float a = angles[j];
535 egsWarning(
"createGeometry(cones): opening angles can not be"
536 " greater than Pi/2\n");
541 if (angles[j] <= angles[j-1]) {
542 egsWarning(
"createGeometry(cones): opening angles must be"
543 " in increasing order\n");
557 err = input->
getInput(
"opening angle",angle);
559 err = input->
getInput(
"opening angle in radian",angle);
561 egsWarning(
"createGeometry(cones): no 'opening angle' or "
562 "'opening angle in radian' input\n");
569 if (angle >= M_PI/2) {
570 egsWarning(
"createGeometry(cones): it is not allowed to have"
571 " an opening angle greater than Pi/2, your input was %g\n",angle);
574 EGS_Float gamma = tan(angle);
575 if (input->
compare(type,
"EGS_SimpleCone")) {
578 err = input->
getInput(
"height",height);
581 egsWarning(
"createGeometry(cones): the cone height"
582 " must be greater than zero, your input was %g\n",height);
589 else if (input->
compare(type,
"EGS_ParallelCones")) {
591 err = input->
getInput(
"apex distances",d);
594 if (!err && d.size() > 0) {
595 dist =
new EGS_Float [d.size()];
596 for (
size_t j=0; j<d.size(); j++) {
607 egsWarning(
"createGeometry(cones): unknown object type %s\n",
Base geometry class. Every geometry class must be derived from EGS_BaseGeometry.
int deref()
Decrease the reference count to this geometry.
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.
int nreg
Number of local regions in this geometry.
bool is_convex
Is this geometry convex?
EGS_Float boundaryTolerance
Boundary tolerance for geometries that need it.
void setName(EGS_Input *inp)
Set the name of the geometry from the input inp.
void setMedium(const string &Name)
Set all regions to a medium with name Name.
int setLabels(EGS_Input *input)
Set the labels from an input block.
virtual void printInfo() const
Print information about this geometry.
int ref()
Increase the reference count to this geometry.
void setBoundaryTolerance(EGS_Input *inp)
Set the value of the boundary tolerance from the input inp.
A set of cones with different opening angles but the same axis and apexes.
A set of "parallel cones" (i.e. cones with the same axis and opening angles but different apexes)
A single cone that may be open (i.e. extends to infinity or closed by a plane perpendicular to the co...
A class representing 3D vectors.
Various cone geometries: header.
EGS_GLIB_EXPORT EGS_BaseGeometry * createGeometry(EGS_Input *input)
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.