55 return (vfile.get() == 0x1f && vfile.get() == 0x8b);
84 int err = shape_inp->getInput(
"shape volume", volume);
90 shape_inp->getInput(
"type", shape_type);
92 if (shape_type ==
"cylinder") {
93 EGS_Float radius, height;
94 shape_inp->getInput(
"radius", radius);
95 shape_inp->getInput(
"height", height);
96 return M_PI*radius*radius*height;
97 }
else if (shape_type ==
"sphere") {
98 EGS_Float radius, height;
99 shape_inp->getInput(
"radius", radius);
100 shape_inp->getInput(
"height", height);
101 return 4./3.*M_PI*radius*radius*radius;
102 }
else if (shape_type ==
"spherical shell" || shape_type ==
"egsSphericalShell") {
105 int err = shape_inp->getInput(
"inner radius", ri);
107 egsFatal(
"getShapeVolume :: missing 'inner radius' input for shape\n");
110 err = shape_inp->getInput(
"outer radius", ro);
112 egsFatal(
"getShapeVolume :: missing 'outer radius' input for shape\n");
115 err = shape_inp->getInput(
"hemisphere", hemi);
119 EGS_Float vol = 4./3.*M_PI*(ro*ro*ro - ri*ri*ri);
126 }
else if (shape_type ==
"box") {
127 vector<EGS_Float> box_size;
128 shape_inp->getInput(
"box size", box_size);
129 if (box_size.size() == 3) {
130 return box_size[0]*box_size[1]*box_size[2];
132 return box_size[0]*box_size[0]*box_size[0];
135 if (shape_type ==
"") {
136 egsWarning(
"Either include a `type` or `shape volume` input key.");
139 "The volume (in cm^3) for shape type '%s' must be specified using a `shape volume` input key.",
150 vector<string> choices;
151 choices.push_back(
"none");
152 choices.push_back(
"zero dose");
153 choices.push_back(
"correct");
164 EGS_Input *shape_inp =
input->takeInputItem(
"shape");
166 egsWarning(
"VolCor::Options::setBoundsShape - no `shape` input found.\n");
172 egsWarning(
"VolCor::Options::setBoundsShape - unable to calculate volume.\n");
177 bounds = EGS_BaseShape::createShape(shape_inp);
179 egsWarning(
"VolCor::Options::setBoundsShape - `shape` input not valid.\n");
194 int err =
input->getInput(
"density of random points (cm^-3)",
density);
196 egsWarning(
"The volume correction 'density of random points (cm^-3)' input was not found\n");
206 EGS_Input *rng_input =
input->getInputItem(
"rng definition");
210 int err = rng_input->getInput(
"type", type);
211 if (!err && rng_input->compare(type,
"sobol")) {
214 "Sobol QRNG are not allowed for non rectilinear shapes. "
215 "Using default Ranmar instead.\n"
221 rng = EGS_RandomGenerator::createRNG(rng_input);
229 rng = EGS_RandomGenerator::defaultRNG();
240 egsWarning(
"The input 'total coverage threshold %%' input was not found. Using 99.9%\n");
256 EGS_Input *source_cor_inp =
input->takeInputItem(
"source volume correction");
258 if (source_cor_inp) {
259 delete source_cor_inp;
263 EGS_Input *gen_cor_inp =
input->takeInputItem(
"extra volume correction");
269 EGS_Input *file_cor_inp =
input->takeInputItem(
"volume correction from file");
274 while ((ij = file_cor_inp->takeInputItem(
"phantom file"))) {
276 string phantom, filename;
277 vector<string> phant_file;
278 ij->getInput(
"phantom file", phant_file);
279 if (phant_file.size() != 2) {
280 egsWarning(
"VolumeCorrector::setupOptions ignoring 'phantom file' input number %d\n", input_num);
302 int global_reg =
base_geom->isWhere(point);
304 for (
size_t pidx=0; pidx <
phantoms.size(); pidx++) {
305 bool phant_is_covered = !
phantoms[pidx]->globalRegIsInPhant(global_reg);
306 if (!phant_is_covered) {
310 int phant_reg =
phantoms[pidx]->geometry->isWhere(point);
312 PhantRegT phant_and_reg(pidx, phant_reg);
313 hit_counter[phant_and_reg] += 1;
340 EGS_I64 n_in_source = 0;
354 for (
size_t sidx = 0; sidx <
transforms.size(); sidx++) {
356 EGS_Vector transformed(point);
359 for (
size_t phant= 0; phant<
phantoms.size(); phant++) {
360 int reg =
phantoms[phant]->geometry->isWhere(transformed);
361 bool in_phant = reg >= 0;
365 hit_counter[phant_reg] += 1;
382 double npoints = opts->
npoints;
384 for (HitCounterT::iterator hi = hit_counter.begin(); hi != hit_counter.end(); hi++) {
386 int phant_idx = hi->first.first;
387 int phant_reg = hi->first.second;
391 int hits = hi->second;
392 double reg_vol =
phantoms[phant_idx]->getUncorrectedVolume(phant_reg);
393 double corrected_vol = reg_vol - bounds_vol*double(hits)/npoints;
398 if (!(voxel_covered || zero_dose)){
399 unc = bounds_vol/corrected_vol*sqrt(hits*(npoints-hits)/(npoints*npoints*npoints));
404 phantoms[phant_idx]->setCorrectedVolume(phant_reg, corrected_vol, unc);
412 for (
size_t rec = 0; rec < nrecords; rec++) {
414 EGS_Float vol, vol_unc;
415 vfile >> reg >> vol >> vol_unc;
417 reg_volumes.push_back(rvol);
422 ifstream vfile(fname.c_str());
423 if (!vfile.is_open()) {
442 map<string, int> nreg_read_for_phant;
444 for (
size_t phant_idx=0; phant_idx <
phantoms.size(); phant_idx++) {
446 string phant_name =
phantoms[phant_idx]->geometry->getName();
452 vector<RegVolume> volumes;
456 "VolumeCorrector::loadFileVolumeCorrections: failed to read "
457 "volumes for '%s' from file '%s'\n", phant_name.c_str(), fname.c_str()
461 nreg_read_for_phant[phant_name] = volumes.size();
463 for (
size_t rv=0; rv < volumes.size(); rv++) {
465 phantoms[phant_idx]->setCorrectedVolume(reg_vol.
ir, reg_vol.
vol, reg_vol.
unc);
470 return nreg_read_for_phant;
EGS_RandomGenerator wrapper for Sobol library.
Volume correction initialization helper class.
static const unsigned long DEFAULT_RAND_POINT_DENSITY
EGS_Float covered_threshold
int setBoundsShape()
create bounding shape from the shape input and calculate its volume
void setCoveredThreshold()
EGS_Vector getRandomPoint()
void setMode()
read mode from input
EGS_RandomGenerator * rng
map< string, int > loadFileVolumeCorrections()
EGS_BaseGeometry * base_geom
vector< EGS_AffineTransform * > transforms
void applyVolumeCorrections(Options *options, HitCounterT hit_counter)
EGS_AffineTransform * base_transform_inv
double correctPhantomVolumesForSources()
vector< EB_Phantom * > phantoms
EGS_AffineTransform * base_transform
double correctGeneralVolumes()
map< string, string > phantom_files
Volume correction routines for egs_brachy.
pair< int, int > PhantRegT
PhantRegT is a pair of the form (PhantomNumber, PhantomRegion) e.g. a pair of (2, 12) would represent...
std::map< PhantRegT, EGS_I64 > HitCounterT
HitCounterT is used for counting how many random points land in a given phantoms region.
int loadVolumes(string fname, vector< RegVolume > ®_volumes)
void readVolumes(istream &vfile, vector< RegVolume > ®_volumes)
EGS_Float getShapeVolume(EGS_Input *shape_inp)
get shape volume from a shape input item
bool isGZip(istream &vfile)
RegVolumeT sruct with members (ir=RegionNumber, vol=Volume, unc=Unc)