63 #include "egs_sobol.h"
129 int err = shape_inp->
getInput(
"shape volume", volume);
135 shape_inp->
getInput(
"type", shape_type);
137 if (shape_type ==
"cylinder") {
138 EGS_Float radius, height;
139 int err = shape_inp->
getInput(
"radius", radius);
141 egsFatal(
"getShapeVolume :: missing 'radius' input for shape\n");
144 err = shape_inp->
getInput(
"height", height);
146 egsFatal(
"getShapeVolume :: missing 'height' input for shape\n");
149 return M_PI*radius*radius*height;
152 else if (shape_type ==
"sphere") {
155 int err = shape_inp->
getInput(
"radius", radius);
157 egsFatal(
"getShapeVolume :: missing 'radius' input for shape\n");
160 return 4./3.*M_PI*radius*radius*radius;
163 else if (shape_type ==
"spherical shell" || shape_type ==
"egsSphericalShell") {
166 int err = shape_inp->
getInput(
"inner radius", ri);
168 egsFatal(
"getShapeVolume :: missing 'inner radius' input for shape\n");
171 err = shape_inp->
getInput(
"outer radius", ro);
173 egsFatal(
"getShapeVolume :: missing 'outer radius' input for shape\n");
176 err = shape_inp->
getInput(
"hemisphere", hemi);
180 EGS_Float vol = 4./3.*M_PI*(ro*ro*ro - ri*ri*ri);
188 else if (shape_type ==
"box") {
189 vector<EGS_Float> box_size;
190 int err = shape_inp->
getInput(
"box size", box_size);
192 egsFatal(
"getShapeVolume :: missing 'box size' input for shape\n");
194 if (box_size.size() == 3) {
195 return box_size[0]*box_size[1]*box_size[2];
198 return box_size[0]*box_size[0]*box_size[0];
202 if (shape_type ==
"") {
203 egsWarning(
"Either include a `type` or `shape volume` input key.");
207 "The volume (in cm^3) for shape type '%s' must be specified using a `shape volume` input key.",
245 const static unsigned long DEFAULT_RAND_POINT_DENSITY = 100000000;
249 rng(NULL), vc_file(
""), input(inp), bounds(NULL), sobolAllowed(false) {
316 vector<string> choices;
317 choices.push_back(
"discover");
318 choices.push_back(
"discover and zero volume");
319 choices.push_back(
"discover and correct volume");
326 int err = input->
getInput(
"volume correction file", vc_file);
337 egsWarning(
"VolCor::VCOptions::setBoundsShape - no `shape` input found.\n");
343 egsWarning(
"VolCor::VCOptions::setBoundsShape - unable to calculate volume.\n");
350 egsWarning(
"VolCor::VCOptions::setBoundsShape - `shape` input not valid.\n");
365 int err = input->
getInput(
"density of random points (cm^-3)",
density);
367 egsWarning(
"The volume correction 'density of random points (cm^-3)' input was not found\n");
368 density = (EGS_Float)DEFAULT_RAND_POINT_DENSITY;
381 int err = rng_input->
getInput(
"type", type);
382 if (!err && rng_input->
compare(type,
"sobol")) {
385 "Sobol QRNG are not allowed for non rectilinear shapes. "
386 "Using default Ranmar instead.\n"
392 rng =
new EGS_Sobol(rng_input);
394 egsWarning(
"Sobol RNG requested but not compiled with Sobol support\n");
403 egsFatal(
"VolCor::setRNG Invalid 'rng definition'.\n");
410 rng =
new EGS_Sobol();
468 vc_file = opts->vc_file;
477 egsInformation(
" --------- Volume Correction Results -----------\n");
488 egsInformation(
" Volume correction file = %s\n", vc_file.c_str());
491 egsInformation(
" -----------------------------------------------\n");
506 double npoints = opts->
npoints;
507 vector<EGS_Float> corrected_vols(uncorrected);
509 for (HitCounterT::iterator hi = hit_counter.begin(); hi != hit_counter.end(); hi++) {
511 int base_reg = hi->first;
516 int hits = hi->second;
517 EGS_Float corrected = uncorrected[base_reg] - bounds_vol*double(hits)/npoints;
518 corrected_vols[base_reg] = zero ? 0 : corrected;
521 return corrected_vols;
531 vector<EGS_Float> corrected_vols(uncorrected);
533 for (
size_t rvc=0; rvc < reg_volumes.size(); rvc++) {
534 int base_reg = reg_volumes[rvc].first;
535 EGS_Float vol = reg_volumes[rvc].second;
536 corrected_vols[base_reg] = zero ? 0 : vol;
539 return corrected_vols;
543 vector<EGS_Float> uncorrected;
544 for (
int ir=0; ir < base->
regions(); ir++) {
546 uncorrected.push_back(vol);
558 vector<EGS_BaseGeometry *> inscribed, vector<EGS_AffineTransform *> transforms) {
569 EGS_I64 n_in_inscribed = 0;
577 for (EGS_I64 i=0; i < opts->
npoints; i++) {
582 first_transform->
transform(inscribed_point);
584 if (!first_inscribed->
isInside(inscribed_point)) {
590 for (
size_t sidx = 0; sidx < transforms.size(); sidx++) {
593 transforms[sidx]->transform(transformed);
594 int base_reg = base->
isWhere(transformed);
595 bool in_base = base_reg >= 0;
599 hit_counter[base_reg] += 1;
623 bool isGZip(istream &vfile) {
624 return (vfile.get() == 0x1f && vfile.get() == 0x8b);
628 void readVolumes(istream &vfile, vector<RegVolume> ®_volumes,
RegionGeomSetT ®_with_inscribed, vector<EGS_BaseGeometry *> inscribed) {
631 for (
int rec = 0; rec < nrecords; rec++) {
634 vfile >> reg >> vol >> ninscribed;
635 egsInformation(
"loaded %d/%d %f %d\n", reg, nrecords, vol, ninscribed);
636 reg_volumes.push_back(
RegVolume(reg, vol));
637 for (
int i=0; i < ninscribed; i++) {
640 reg_with_inscribed[reg].insert(inscribed[gidx]);
646 int loadVolumes(
string fname, vector<RegVolume> ®_volumes,
RegionGeomSetT ®_with_inscribed, vector<EGS_BaseGeometry *> inscribed) {
647 ifstream vfile(fname.c_str(), ios::binary);
648 if (!vfile.is_open()) {
655 igzstream gzf(fname.c_str());
656 readVolumes(gzf, reg_volumes, reg_with_inscribed, inscribed);
659 egsWarning(
"Tried to load gzip volume correction file but not compiled with gzstream.\n");
665 ifstream vfile2(fname.c_str(), ios::in);
666 readVolumes(vfile2, reg_volumes, reg_with_inscribed, inscribed);
678 vector<EGS_BaseGeometry *> inscribed, vector<EGS_AffineTransform *> transforms) {
686 vector<RegVolume> reg_volumes;
691 "loadFileVolumeCorrections: failed to read "
692 "volumes from file '%s'\n", opts->vc_file.c_str()
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.
EGS_Float time()
Returns the CPU time in seconds since start() was called.
void outputResults() const
virtual EGS_Vector getRandomPoint(EGS_RandomGenerator *rndm)
Returns a random 3D vector.
std::map< int, EGS_I64 > HitCounterT
EGS_Vector getRandomPoint()
static EGS_BaseShape * createShape(EGS_Input *inp)
Create a shape from the information pointed to by inp.
RegionGeomSetT regions_with_inscribed
A class representing 3D vectors.
pair< EGS_BaseGeometry *, int > GeomRegPairT
virtual EGS_Float getVolume(int ireg)
Calculates the volume of region ireg.
Global egspp functions header file.
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.
Base geometry class. Every geometry class must be derived from EGS_BaseGeometry.
VCResults findRegionsWithInscribed(VCOptions *opts, EGS_BaseGeometry *base, vector< EGS_BaseGeometry * > inscribed, vector< EGS_AffineTransform * > transforms)
Run the MC simulation.
Base random number generator class. All random number generators should be derived from this class...
vector< EGS_Float > uncorrected_volumes
vector< EGS_Float > applyVolumeCorrections(VCOptions *opts, HitCounterT hit_counter, vector< EGS_Float > uncorrected)
Apply volume corrections to base regions.
VCResults loadFileResults(VCOptions *opts, EGS_BaseGeometry *base, vector< EGS_BaseGeometry * > inscribed, vector< EGS_AffineTransform * > transforms)
Load volume corrections from external file.
EGS_InfoFunction EGS_EXPORT egsFatal
Always use this function for reporting fatal errors.
EGS_RandomGenerator class header file.
map< int, set< EGS_BaseGeometry * > > RegionGeomSetT
EGS_InfoFunction EGS_EXPORT egsInformation
Always use this function for reporting the progress of a simulation and any other type of information...
EGS_BaseShape and shape classes header file.
EGS_Float getShapeVolume(EGS_Input *shape_inp)
vector< EGS_Float > corrected_volumes
A simple class for measuring CPU time.
Struct used to collect and output results about a volume correction run.
virtual void describeRNG() const
Describe this RNG.
pair< int, EGS_Float > RegVolume
RegVolumeT is a pair of the form (RegionNumber, Volume)
const string & getObjectType() const
Get the object type.
void start()
Starts the time measurement.
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...
VCOptions(EGS_Input *inp)
Volume correction initialization helper class.
static EGS_RandomGenerator * defaultRNG(int sequence=0)
Returns a pointer to the default egspp RNG.
EGS_BaseGeometry class header file.
EGS_Timer class header file.
vector< EGS_Float > applyFileVolumeCorrections(VCOptions *opts, vector< RegVolume > ®_volumes, vector< EGS_Float > uncorrected)
Apply file volume corrections to base regions.
EGS_InfoFunction EGS_EXPORT egsWarning
Always use this function for reporting warnings.