61 #define S_STREAM std::istringstream
64 #define S_STREAM std::istrstream
71 EGS_VoxelInfo *EGS_VoxelGeometry::v = 0;
72 int EGS_VoxelGeometry::nv = 0;
74 VHP_OrganData::VHP_OrganData(
const char *fname,
int slice_min,
int slice_max)
75 : nslice(0), ok(false) {
76 ifstream data(fname,ios::binary);
78 egsWarning(
"VHP_OrganData: failed to open file %s for reading\n",
83 data.read(&endian,
sizeof(endian));
85 if (endian != my_endian) {
86 egsWarning(
"VHP_OrganData: wrong endianess. \n"
87 "This machine has endianess %d, data was written on %d\n"
88 "This requires byte swaping, which has not been implemented yet\n",
89 (
int)my_endian,(
int)endian);
92 data.read((
char *)&dx,
sizeof(dx));
93 data.read((
char *)&dy,
sizeof(dy));
94 data.read((
char *)&dz,
sizeof(dz));
95 data.read((
char *)&nslice,
sizeof(nslice));
99 if (slice_max > nslice) {
102 int nwant = slice_max - slice_min;
103 slices =
new VHP_SliceInfo [nwant];
106 for (
int islice=0; islice<nslice; ++islice) {
107 if (islice >= slice_min) {
108 slices[is].readData(data);
110 slices[is++].getSliceDimensions(ni,nj);
122 if (islice == slice_max - 1) {
127 nslice = slice_max - slice_min;
129 egsWarning(
"VHP_OrganData: I/O error while reading data\n");
136 VHP_OrganData::~VHP_OrganData() {
142 void VHP_RowInfo::readData(istream &in) {
144 in.read((
char *)&n,
sizeof(n));
157 pix =
new unsigned short [nbin+1];
158 org =
new unsigned char [nbin];
160 in.read((
char *)pix,(nbin+1)*
sizeof(
unsigned short));
161 in.read((
char *)org,nbin*
sizeof(
unsigned char));
164 void VHP_SliceInfo::readData(istream &in) {
169 in.read((
char *)&firstr,
sizeof(firstr));
170 in.read((
char *)&lastr,
sizeof(lastr));
171 int nrow = lastr-firstr+1;
173 rinfo =
new VHP_RowInfo [nrow];
174 for (
int j=0; j<nrow; ++j) {
175 rinfo[j].readData(in);
181 EGS_VHPGeometry::EGS_VHPGeometry(
const char *phantom_file,
182 const char *media_file,
int slice_min,
int slice_max,
183 const string &Name) :
185 organs =
new VHP_OrganData(phantom_file,slice_min,slice_max);
186 if (!organs->isOK()) {
187 egsWarning(
"EGS_VHPGeometry: failed to construct organ data\n");
192 ifstream med_data(media_file);
194 egsWarning(
"EGS_VHPGeometry: failed to open media data file %s\n",
203 egsWarning(
"EGS_VHPGeometry: %d organs in media data file %s?\n",
210 for (j=0; j<256; ++j) {
212 organ_names[j] =
"Undefined";
216 med_data.getline(buf,1023);
217 for (j=0; j<norg; ++j) {
220 med_data >> iorg >> imed >> c;
221 med_data.getline(buf,1023);
222 if (iorg < 0 || iorg > 255)
223 egsWarning(
"EGS_VHPGeometry: bad organ number %d on line %d\n",
226 organ_media[iorg] = imed;
228 organ_names[iorg] = c;
229 organ_names[iorg] += buf;
233 med_data.getline(buf,1023);
234 vector<string> media_names;
235 vector<int> media_indeces;
236 for (j=0; j<nmed; ++j) {
237 med_data.getline(buf,1023);
239 media_names.push_back(med);
243 for (j=0; j<nmed; ++j) {
245 media_names[j].c_str(),media_indeces[j]);
247 for (j=0; j<256; ++j) {
248 if (organ_media[j] >= 0) {
249 if (organ_media[j] >= nmed) {
250 egsWarning(
"EGS_VHPGeometry: invalid medium index %d\n",
254 organ_media[j] = media_indeces[organ_media[j]];
258 EGS_Float dx, dy, dz;
260 organs->getVoxelSizes(dx,dy,dz);
261 organs->getPhantomDimensions(nx,ny,nz);
262 vg =
new EGS_VoxelGeometry(nx,ny,nz,dx,dy,dz);
265 egsInformation(
"Phantom size in voxels: x=%d y=%d z=%d\n",nx,ny,nz);
269 void EGS_VHPGeometry::setMicros(
EGS_Input *input) {
270 if (!vg || !organs) {
271 egsWarning(
"EGS_VHPGeometry::setMicros: called for an invalid "
276 egsWarning(
"EGS_VHPGeometry::setMicros: no micro matrix definitions\n");
279 vector<EGS_MicroMatrixCluster *> mv;
281 input->
getInput(
"micro matrix folder",dir);
284 const static char *err_msg =
285 "EGS_VHPGeometry::setMicros: wrong/missing '%s' input\n";
286 int err = input->
getInput(
"BSC thickness",t_bsc);
287 if (err || t_bsc < 0) {
291 string tb_medium, bm_medium;
292 err = input->
getInput(
"TB medium",tb_medium);
297 err = input->
getInput(
"BM medium",bm_medium);
303 egsWarning(
"EGS_VHPGeometry::setMicros: wrong/missing inputs found\n"
304 " => no micro matrices set for use\n");
308 vector<string> minput;
309 while (!input->
getInput(
"micro matrix",minput)) {
311 if (minput.size() < 2) {
312 egsWarning(
"EGS_VHPGeometry::setMicros: 'micro matrix' input"
313 " requires at least two inputs => ignored\n");
316 string fname = dir.size() ?
egsJoinPath(dir,minput[0]) : minput[0];
317 EGS_MicroMatrixCluster *mcluster =
new EGS_MicroMatrixCluster(
318 vg->dx,vg->dy,vg->dz,t_bsc,tb_med,bm_med,fname.c_str());
319 if (!mcluster->isValid()) {
320 egsWarning(
"failed to construct micro cluster from %s\n",
327 for (
int i=1; i<minput.size(); ++i) {
328 S_STREAM s(minput[i].c_str());
332 egsWarning(
"EGS_VHPGeometry::setMicros: invalid input %s "
333 "for micro matrix %s\n",minput[i].c_str(),
338 if (org < 0 || org > 255) {
339 egsWarning(
"EGS_VHPGeometry::setMicros: invalid input"
340 " %d for micro matrix %s\n",org,minput[0].c_str());
349 mv.push_back(mcluster);
351 " organs:",fname.c_str());
352 for (
int i=0; i<orgs.size(); ++i) {
354 organ_micro[orgs[i]] = mv.size()-1;
365 for (
int i=0; i<nmicro; ++i) {
371 micros =
new EGS_MicroMatrixCluster* [nmicro];
373 for (
int i=0; i<nmicro; ++i) {
375 int nr = micros[i]->nxy*micros[i]->nz;
376 int nm = micros[i]->mxy*micros[i]->mz;
381 nmacro = vg->nxy*vg->nz;
385 if (ntot > 2147483647)
egsFatal(
"EGS_VHPGeometry::setMicros: "
386 "too many micro regions\n");
387 nreg = nmacro + nmax*nmicro;
390 egsInformation(
"Using regions %d...%d to identify micro voxels\n",
395 EGS_VHPGeometry::~EGS_VHPGeometry() {
403 for (
int j=0; j<nmicro; ++j) {
411 void EGS_VHPGeometry::setMedia(
EGS_Input *,
int,
const int *) {
412 egsWarning(
"EGS_VHPGeometry::setMedia: don't use this method.\n"
413 " Media are fixed by the organ data defining an VHP geometry\n");
416 void EGS_VHPGeometry::printInfo()
const {
427 string EGS_VHPGeometry::type =
"EGS_VHPGeometry";
430 VHPBox EGS_MicroMatrixCluster::bm_boxes[64];
431 bool EGS_MicroMatrixCluster::bm_boxes_initialized =
false;
433 EGS_MicroMatrixCluster::EGS_MicroMatrixCluster(
434 EGS_Float Dx, EGS_Float Dy, EGS_Float Dz, EGS_Float bsc_thickness,
435 int tb_med,
int bm_med,
const char *micro_file) : med_tb(tb_med), med_bm(bm_med),
440 ifstream in(micro_file,ios::binary);
442 egsWarning(
"EGS_MicroMatrixCluster: failed to open file %s\n",
450 unsigned char Mx, My, Mz;
451 in.read((
char *)&Mx,
sizeof(Mx));
452 in.read((
char *)&My,
sizeof(My));
453 in.read((
char *)&Mz,
sizeof(Mz));
459 micros =
new unsigned char *[nmic];
460 in.read((
char *)&Mx,
sizeof(Mx));
461 in.read((
char *)&My,
sizeof(My));
462 in.read((
char *)&Mz,
sizeof(Mz));
467 int nxyz = nxy*nz, j;
470 for (
int j=0; j<nmic; ++j) {
471 micros[j] =
new unsigned char [nxyz];
472 in.read((
char *)micros[j],nxyz*
sizeof(
unsigned char));
474 egsWarning(
"EGS_MicroMatrixCluster: I/O error while reading "
475 "%d'th micto-matrix from file %s\n",j+1,micro_file);
476 for (
int i=0; i<=j; ++i) {
495 EGS_Float ddx = Dx/nx, ddy = Dy/ny, ddz = Dz/nz;
504 vg =
new EGS_VoxelGeometry(nx,ny,nz,ddx,ddy,ddz);
510 if (!bm_boxes_initialized) {
511 bm_boxes_initialized =
true;
512 for (
int ixm=0; ixm<2; ++ixm) {
513 EGS_Float xmin = bsc_thickness*ixm;
514 for (
int ixp=0; ixp<2; ++ixp) {
515 EGS_Float xmax = ddx - bsc_thickness*ixp;
516 for (
int iym=0; iym<2; ++iym) {
517 EGS_Float ymin = bsc_thickness*iym;
518 for (
int iyp=0; iyp<2; ++iyp) {
519 EGS_Float ymax = ddy - bsc_thickness*iyp;
520 for (
int izm=0; izm<2; ++izm) {
521 EGS_Float zmin = bsc_thickness*izm;
522 for (
int izp=0; izp<2; ++izp) {
523 EGS_Float zmax = ddz - bsc_thickness*izp;
524 int ibox = ixm+2*ixp+4*iym+8*iyp+16*izm+32*izp;
525 bm_boxes[ibox].xmin = xmin;
526 bm_boxes[ibox].xmax = xmax;
527 bm_boxes[ibox].ymin = ymin;
528 bm_boxes[ibox].ymax = ymax;
529 bm_boxes[ibox].zmin = zmin;
530 bm_boxes[ibox].zmax = zmax;
548 v_tb =
new EGS_Float [nmic];
549 v_bm =
new EGS_Float [nmic];
550 v_bsc =
new EGS_Float [nmic];
551 double tot_tb = 0, tot_bm = 0, tot_bsc = 0;
552 for (j=0; j<nmic; ++j) {
554 int iy = (j-iz*mxy)/mx;
555 int ix = j-iz*mxy-iy*mx;
580 EGS_Float bsc_vol = 0, bm_vol = 0, tb_vol = 0;
581 for (
int jx=0; jx<nx; ++jx) {
582 for (
int jy=0; jy<ny; ++jy) {
583 for (
int jz=0; jz<nz; ++jz) {
584 int ireg = jx + jy*nx + jz*nxy;
585 if (micros[j][ireg]) {
586 int micxm = !(jx > 0 ? micros[j][ireg-1] :
587 micros[ixm+iy*mx+iz*mxy][nx-1+jy*nx+jz*nxy]);
588 int micxp = !(jx < nx-1 ? micros[j][ireg+1] :
589 micros[ixp+iy*mx+iz*mxy][jy*nx+jz*nxy]);
590 int micym = !(jy > 0 ? micros[j][ireg-nx] :
591 micros[ix+iym*mx+iz*mxy][jx+(ny-1)*nx+jz*nxy]);
592 int micyp = !(jy < ny-1 ? micros[j][ireg+nx] :
593 micros[ix+iyp*mx+iz*mxy][jx+jz*nxy]);
594 int miczm = !(jz > 0 ? micros[j][ireg-nxy] :
595 micros[ix+iy*mx+izm*mxy][jx+jy*nx+(nz-1)*nxy]);
596 int miczp = !(jz < nz-1 ? micros[j][ireg+nxy] :
597 micros[ix+iy*mx+izp*mxy][jx+jy*nx]);
598 if ((micxm && micxp && 2*bsc_thickness>ddx) ||
599 (micym && micyp && 2*bsc_thickness>ddy) ||
600 (miczm && miczp && 2*bsc_thickness>ddz)) {
605 int ibox=micxm+2*micxp+4*micym+8*micyp+
607 micros[j][ireg] = ibox + 2;
613 (bm_boxes[ibox].xmax-bm_boxes[ibox].xmin)*
614 (bm_boxes[ibox].ymax-bm_boxes[ibox].ymin)*
615 (bm_boxes[ibox].zmax-bm_boxes[ibox].zmin);
633 v_tb[j] = tb_vol*ddx*ddy*ddz;
634 v_bm[j] = bm_vol*ddx*ddy*ddz;
635 v_bsc[j] = bsc_vol*ddx*ddy*ddz;
646 EGS_MicroMatrixCluster::~EGS_MicroMatrixCluster() {
650 EGS_TestMicro::EGS_TestMicro(EGS_Float Dx, EGS_Float Dy, EGS_Float Dz,
651 EGS_Float bsc_t,
int tb_med,
int bm_med,
const char *micro_file,
653 micro =
new EGS_MicroMatrixCluster(Dx,Dy,Dz,bsc_t,tb_med,bm_med,micro_file);
654 vg =
new EGS_VoxelGeometry(micro->mx,micro->my,micro->mz,Dx,Dy,Dz);
655 nr = micro->nx*micro->ny*micro->nz;
656 nreg = nr*micro->mx*micro->my*micro->mz;
659 void EGS_TestMicro::setMedia(
EGS_Input *,
int,
const int *) {
660 egsFatal(
"EGS_TestMicro::setMedia(EGS_Input*,int,const int *):\n"
661 " Don't use this method. Media are only set via the micro matrix"
665 EGS_TestMicro::~EGS_TestMicro() {
668 string EGS_TestMicro::type =
"EGS_TestMicro";
670 const static EGS_VHP_LOCAL
char *vhp_error_msg1 =
671 "createGeometry(VHP): wrong/missing %s input for micro_test geometry\n";
677 int err = input->
getInput(
"type",type);
678 if (!err && type ==
"micro_test") {
680 vector<EGS_Float> vs;
681 err = input->
getInput(
"voxel sizes",vs);
682 if (err || vs.size() != 3) {
687 err = input->
getInput(
"BSC thickness",bsc_t);
692 string tb_medium, bm_medium;
693 int err1 = input->
getInput(
"TB medium",tb_medium);
694 int err2 = input->
getInput(
"BM medium",bm_medium);
705 err = input->
getInput(
"micro data file",micro_data);
707 egsWarning(vhp_error_msg1,
"'micro data file'");
716 tb_med,bm_med,micro_data.c_str());
722 string phantom, media;
723 int err1 = input->
getInput(
"phantom data",phantom);
724 int err2 = input->
getInput(
"media data",media);
725 if (err1)
egsWarning(
"createGeometry(EGS_VHPGeometry): "
726 "missing 'phantom data' input\n");
727 if (err2)
egsWarning(
"createGeometry(EGS_VHPGeometry): "
728 "missing 'media data' input\n");
733 err1 = input->
getInput(
"slice range",srange);
735 if (!err1 && srange.size() == 2 && srange[1] > srange[0]) result =
736 new EGS_VHPGeometry(phantom.c_str(),media.c_str(),srange[0],srange[1]);
740 if (!result->isOK()) {
741 egsWarning(
"createGeometry(EGS_VHPGeometry): failed to construct "
748 result->setMicros(input);
Base geometry class. Every geometry class must be derived from EGS_BaseGeometry.
int nreg
Number of local regions in this geometry.
void setName(EGS_Input *inp)
Set the name of the geometry from the input inp.
int setLabels(EGS_Input *input)
Set the labels from an input block.
virtual void printInfo() const
Print information about this geometry.
static int addMedium(const string &medname)
Add a medium or get the index of an existing medium.
void setBoundaryTolerance(EGS_Input *inp)
Set the value of the boundary tolerance from the input inp.
A Voxelized Human Phantom (VHP) geometry.
Global egspp functions header file.
EGS_GLIB_EXPORT EGS_BaseGeometry * createGeometry(EGS_Input *input)
Voxelized Human Phantom (VHP) geometry: header.
int egsGetEndian()
Get the endianess of the machine.
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.
string egsJoinPath(const string &first, const string &second)
Join two path variables (or a path and a file name) using the platform specific directory separator a...
EGS_InfoFunction EGS_EXPORT egsWarning
Always use this function for reporting warnings.