64 #include "egs_sobol.h"
130 int err = shape_inp->
getInput(
"shape volume", volume);
136 shape_inp->
getInput(
"type", shape_type);
138 if (shape_type ==
"cylinder") {
139 EGS_Float radius, height;
140 int err = shape_inp->
getInput(
"radius", radius);
142 egsFatal(
"getShapeVolume :: missing 'radius' input for shape\n");
145 err = shape_inp->
getInput(
"height", height);
147 egsFatal(
"getShapeVolume :: missing 'height' input for shape\n");
150 return M_PI*radius*radius*height;
153 else if (shape_type ==
"sphere") {
156 int err = shape_inp->
getInput(
"radius", radius);
158 egsFatal(
"getShapeVolume :: missing 'radius' input for shape\n");
161 return 4./3.*M_PI*radius*radius*radius;
164 else if (shape_type ==
"spherical shell" || shape_type ==
"egsSphericalShell") {
167 int err = shape_inp->
getInput(
"inner radius", ri);
169 egsFatal(
"getShapeVolume :: missing 'inner radius' input for shape\n");
172 err = shape_inp->
getInput(
"outer radius", ro);
174 egsFatal(
"getShapeVolume :: missing 'outer radius' input for shape\n");
177 err = shape_inp->
getInput(
"hemisphere", hemi);
181 EGS_Float vol = 4./3.*M_PI*(ro*ro*ro - ri*ri*ri);
189 else if (shape_type ==
"box") {
190 vector<EGS_Float> box_size;
191 int err = shape_inp->
getInput(
"box size", box_size);
193 egsFatal(
"getShapeVolume :: missing 'box size' input for shape\n");
195 if (box_size.size() == 3) {
196 return box_size[0]*box_size[1]*box_size[2];
199 return box_size[0]*box_size[0]*box_size[0];
203 if (shape_type ==
"") {
204 egsWarning(
"Either include a `type` or `shape volume` input key.");
208 "The volume (in cm^3) for shape type '%s' must be specified using a `shape volume` input key.",
246 const static unsigned long DEFAULT_RAND_POINT_DENSITY = 100000000;
250 rng(NULL), vc_file(
""), input(inp), bounds(NULL), sobolAllowed(false) {
317 vector<string> choices;
318 choices.push_back(
"discover");
319 choices.push_back(
"discover and zero volume");
320 choices.push_back(
"discover and correct volume");
327 int err = input->
getInput(
"volume correction file", vc_file);
338 egsWarning(
"VolCor::VCOptions::setBoundsShape - no `shape` input found.\n");
344 egsWarning(
"VolCor::VCOptions::setBoundsShape - unable to calculate volume.\n");
351 egsWarning(
"VolCor::VCOptions::setBoundsShape - `shape` input not valid.\n");
366 int err = input->
getInput(
"density of random points (cm^-3)",
density);
368 egsWarning(
"The volume correction 'density of random points (cm^-3)' input was not found\n");
369 density = (EGS_Float)DEFAULT_RAND_POINT_DENSITY;
382 int err = rng_input->
getInput(
"type", type);
383 if (!err && rng_input->
compare(type,
"sobol")) {
386 "Sobol QRNG are not allowed for non rectilinear shapes. "
387 "Using default Ranmar instead.\n"
393 rng =
new EGS_Sobol(rng_input);
395 egsWarning(
"Sobol RNG requested but not compiled with Sobol support\n");
404 egsFatal(
"VolCor::setRNG Invalid 'rng definition'.\n");
411 rng =
new EGS_Sobol();
469 vc_file = opts->vc_file;
478 egsInformation(
" --------- Volume Correction Results -----------\n");
489 egsInformation(
" Volume correction file = %s\n", vc_file.c_str());
492 egsInformation(
" -----------------------------------------------\n");
507 double npoints = opts->
npoints;
508 vector<EGS_Float> corrected_vols(uncorrected);
510 for (HitCounterT::iterator hi = hit_counter.begin(); hi != hit_counter.end(); hi++) {
512 int base_reg = hi->first;
517 int hits = hi->second;
518 EGS_Float corrected = uncorrected[base_reg] - bounds_vol*double(hits)/npoints;
519 corrected_vols[base_reg] = zero ? 0 : corrected;
522 return corrected_vols;
532 vector<EGS_Float> corrected_vols(uncorrected);
534 for (
size_t rvc=0; rvc < reg_volumes.size(); rvc++) {
535 int base_reg = reg_volumes[rvc].first;
536 EGS_Float vol = reg_volumes[rvc].second;
537 corrected_vols[base_reg] = zero ? 0 : vol;
540 return corrected_vols;
544 vector<EGS_Float> uncorrected;
545 for (
int ir=0; ir < base->
regions(); ir++) {
547 uncorrected.push_back(vol);
559 vector<EGS_BaseGeometry *> inscribed, vector<EGS_AffineTransform *> transforms) {
570 EGS_I64 n_in_inscribed = 0;
578 for (EGS_I64 i=0; i < opts->
npoints; i++) {
583 first_transform->
transform(inscribed_point);
585 if (!first_inscribed->
isInside(inscribed_point)) {
591 for (
size_t sidx = 0; sidx < transforms.size(); sidx++) {
594 transforms[sidx]->transform(transformed);
595 int base_reg = base->
isWhere(transformed);
596 bool in_base = base_reg >= 0;
600 hit_counter[base_reg] += 1;
624 bool isGZip(istream &vfile) {
625 return (vfile.get() == 0x1f && vfile.get() == 0x8b);
629 void readVolumes(istream &vfile, vector<RegVolume> ®_volumes,
RegionGeomSetT ®_with_inscribed, vector<EGS_BaseGeometry *> inscribed) {
632 for (
int rec = 0; rec < nrecords; rec++) {
635 vfile >> reg >> vol >> ninscribed;
636 egsInformation(
"loaded %d/%d %f %d\n", reg, nrecords, vol, ninscribed);
637 reg_volumes.push_back(
RegVolume(reg, vol));
638 for (
int i=0; i < ninscribed; i++) {
641 reg_with_inscribed[reg].insert(inscribed[gidx]);
647 int loadVolumes(
string fname, vector<RegVolume> ®_volumes,
RegionGeomSetT ®_with_inscribed, vector<EGS_BaseGeometry *> inscribed) {
648 ifstream vfile(fname.c_str(), ios::binary);
649 if (!vfile.is_open()) {
656 igzstream gzf(fname.c_str());
657 readVolumes(gzf, reg_volumes, reg_with_inscribed, inscribed);
660 egsWarning(
"Tried to load gzip volume correction file but not compiled with gzstream.\n");
666 ifstream vfile2(fname.c_str(), ios::in);
667 readVolumes(vfile2, reg_volumes, reg_with_inscribed, inscribed);
679 vector<EGS_BaseGeometry *> inscribed, vector<EGS_AffineTransform *> transforms) {
687 vector<RegVolume> reg_volumes;
692 "loadFileVolumeCorrections: failed to read "
693 "volumes from file '%s'\n", opts->vc_file.c_str()
Base geometry class. Every geometry class must be derived from EGS_BaseGeometry.
virtual EGS_Float getVolume(int ireg)
Calculates the volume of region ireg.
virtual bool isInside(const EGS_Vector &x)=0
Is the position x inside the geometry?
int regions() const
Returns the number of local regions in this geometry.
virtual int isWhere(const EGS_Vector &x)=0
In which region is poisition x?
Base shape class. All shapes in the EGSnrc C++ class library are derived from EGS_BaseShape.
static EGS_BaseShape * createShape(EGS_Input *inp)
Create a shape from the information pointed to by inp.
virtual EGS_Vector getRandomPoint(EGS_RandomGenerator *rndm)
Returns a random 3D vector.
const string & getObjectType() const
Get the object type.
Base random number generator class. All random number generators should be derived from this class.
static EGS_RandomGenerator * defaultRNG(int sequence=0)
Returns a pointer to the default egspp RNG.
static EGS_RandomGenerator * createRNG(EGS_Input *inp, int sequence=0)
Create a RNG object from the information pointed to by inp and return a pointer to it.
virtual void describeRNG() const
Describe this RNG.
A simple class for measuring CPU time.
EGS_Float time()
Returns the CPU time in seconds since start() was called.
void start()
Starts the time measurement.
A class representing 3D vectors.
Volume correction initialization helper class.
EGS_Vector getRandomPoint()
VCOptions(EGS_Input *inp)
EGS_BaseGeometry class header file.
Global egspp functions header file.
EGS_RandomGenerator class header file.
EGS_BaseShape and shape classes header file.
EGS_Timer 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.
EGS_InfoFunction EGS_EXPORT egsWarning
Always use this function for reporting warnings.
Region discovery/volume correction for auto envelope geometries.
VCResults findRegionsWithInscribed(VCOptions *opts, EGS_BaseGeometry *base, vector< EGS_BaseGeometry * > inscribed, vector< EGS_AffineTransform * > transforms)
Run the MC simulation.
VCResults loadFileResults(VCOptions *opts, EGS_BaseGeometry *base, vector< EGS_BaseGeometry * > inscribed, vector< EGS_AffineTransform * > transforms)
Load volume corrections from external file.
pair< int, EGS_Float > RegVolume
RegVolumeT is a pair of the form (RegionNumber, Volume)
std::map< int, EGS_I64 > HitCounterT
pair< EGS_BaseGeometry *, int > GeomRegPairT
vector< EGS_Float > applyFileVolumeCorrections(VCOptions *opts, vector< RegVolume > ®_volumes, vector< EGS_Float > uncorrected)
Apply file volume corrections to base regions.
vector< EGS_Float > applyVolumeCorrections(VCOptions *opts, HitCounterT hit_counter, vector< EGS_Float > uncorrected)
Apply volume corrections to base regions.
EGS_Float getShapeVolume(EGS_Input *shape_inp)
map< int, set< EGS_BaseGeometry * > > RegionGeomSetT
Struct used to collect and output results about a volume correction run.
RegionGeomSetT regions_with_inscribed
vector< EGS_Float > corrected_volumes
void outputResults() const
vector< EGS_Float > uncorrected_volumes