51 fPhantomMinusCorner(),
55 fUserVolumeCmd->
SetGuidance(
"Intersects a phantom with a user-defined volume and outputs the voxels that are totally inside the intersection as a new phantom file. It must have the parameters: POS_X POS_Y POS_Z ANG_X ANG_Y ANG_Z SOLID_TYPE SOLID_PARAM_1 (SOLID_PARAM_2 ...)");
60 fG4VolumeCmd->
SetGuidance(
"Intersects a phantom with a user-defined volume and outputs the voxels that are totally inside the intersection as a new phantom file. It must have the parameters: POS_X POS_Y POS_Z ANG_X ANG_Y ANG_Z SOLID_TYPE SOLID_PARAM_1 (SOLID_PARAM_2 ...)");
68 if (fUserVolumeCmd)
delete fUserVolumeCmd;
69 if (fG4VolumeCmd)
delete fG4VolumeCmd;
78 if (command == fUserVolumeCmd) {
80 std::vector<G4String> params = GetWordsInString( newValues );
81 if( params.size() < 8 ) {
83 " There must be at least 8 parameter: SOLID_TYPE POS_X POS_Y POS_Z ANG_X ANG_Y ANG_Z SOLID_PARAM_1 (SOLID_PARAM_2 ...)",
90 BuildUserSolid(params);
95 std::vector<double> angles;
101 }
else if (command == fG4VolumeCmd) {
102 std::vector<G4String> params = GetWordsInString( newValues );
103 if( params.size() !=1 )
G4Exception(
"DicomIntersectVolume::SetNewValue",
109 BuildG4Solid(params);
133 G4String thePhantomFileName =
"phantom.g4pdcm";
134 fout.open(thePhantomFileName);
135 std::vector<G4Material*> materials = thePhantomParam->
GetMaterials();
136 fout << materials.size() <<
G4endl;
137 for(
unsigned int ii = 0; ii < materials.size(); ii++ ) {
138 fout << ii <<
" " << materials[ii]->GetName() <<
G4endl;
146 fVoxelIsInside =
new G4bool[nx*ny*nz];
152 fout << nx <<
" " << ny <<
" " << nz <<
G4endl;
153 fout << -voxelHalfWidthX*nx+thePhantomTransform.NetTranslation().x() <<
" "
154 << voxelHalfWidthX*nx+thePhantomTransform.NetTranslation().x() <<
G4endl;
155 fout << -voxelHalfWidthY*ny+thePhantomTransform.NetTranslation().y() <<
" "
156 << voxelHalfWidthY*ny+thePhantomTransform.NetTranslation().y() <<
G4endl;
157 fout << -voxelHalfWidthZ*nz+thePhantomTransform.NetTranslation().z() <<
" "
158 << voxelHalfWidthZ*nz+thePhantomTransform.NetTranslation().z() <<
G4endl;
161 for(
G4int iy = 0; iy < ny; iy++) {
163 G4bool bPrevVoxelInside =
true;
164 G4bool b1VoxelFoundInside =
false;
165 G4int firstVoxel = -1;
166 G4int lastVoxel = -1;
167 for(
G4int ix = 0; ix < nx; ix++ ){
168 G4ThreeVector voxelCentre( (-nx+ix*2+1)*voxelHalfWidthX, (-ny+iy*2+1)*voxelHalfWidthY, (-nz+
iz*2+1)*voxelHalfWidthZ);
170 G4bool bVoxelIsInside =
true;
171 for(
G4int ivx = -1; ivx <= 1; ivx+=2 ) {
172 for(
G4int ivy = -1; ivy <= 1; ivy+=2 ){
173 for(
G4int ivz = -1; ivz <= 1; ivz+=2 ) {
174 G4ThreeVector voxelPoint = voxelCentre + ivx*voxelHalfWidthX*axisX + ivy*voxelHalfWidthY*axisY + ivz*voxelHalfWidthZ*axisZ;
176 bVoxelIsInside =
false;
181 if( !bVoxelIsInside )
break;
183 if( !bVoxelIsInside )
break;
186 G4int copyNo = ix + nx*iy + nxy*
iz;
187 if( bVoxelIsInside ) {
188 if( !bPrevVoxelInside ) {
192 "Volume cannot intersect phantom in discontiguous voxels, please use other voxel");
194 if( !b1VoxelFoundInside ) {
196 b1VoxelFoundInside =
true;
199 fVoxelIsInside[copyNo] =
true;
201 fVoxelIsInside[copyNo] =
false;
205 fout << firstVoxel <<
" " << lastVoxel <<
G4endl;
211 for(
G4int iy = 0; iy < ny; iy++) {
213 for(
G4int ix = 0; ix < nx; ix++ ){
214 size_t copyNo = ix + ny*iy + nxy*
iz;
216 if( fVoxelIsInside[copyNo] ) {
221 if(b1xFound ) fout <<
G4endl;
227 for(
G4int iy = 0; iy < ny; iy++) {
229 for(
G4int ix = 0; ix < nx; ix++ ){
230 size_t copyNo = ix + ny*iy + nxy*
iz;
231 if( fVoxelIsInside[copyNo] ) {
236 if(b1xFound ) fout <<
G4endl;
243 void DicomIntersectVolume::BuildUserSolid( std::vector<G4String> params )
245 for(
G4int ii = 0; ii < 6; ii++ ) params.erase( params.begin() );
246 params.insert( params.begin(),
":SOLID");
247 params.insert( params.begin(), params[1] );
255 void DicomIntersectVolume::BuildG4Solid( std::vector<G4String> params )
257 fSolid = GetLogicalVolumes( params[0], 1, 1)[0]->GetSolid();
267 std::vector<G4VPhysicalVolume*>::iterator cite;
268 for( cite = pvs->begin(); cite != pvs->end(); cite++ ) {
270 if( IsPhantomVolume( *cite ) ) {
280 if( !paramreg && bMustExist )
281 G4Exception(
"DicomIntersectVolume::GetPhantomParam",
284 " No G4PhantomParameterisation found ");
291 std::vector<G4VPhysicalVolume*> DicomIntersectVolume::GetPhysicalVolumes(
const G4String&
name,
bool exists,
G4int nVols )
293 std::vector<G4VPhysicalVolume*> vvolu;
294 std::string::size_type ial = name.rfind(
":");
297 if( ial != std::string::npos ) {
298 std::string::size_type ial2 = name.rfind(
":",ial-1);
299 if( ial2 != std::string::npos ) {
300 G4Exception(
"DicomIntersectVolume::GetPhysicalVolumes",
303 G4String(
"Name corresponds to a touchable " + name).c_str());
305 volname = name.substr( 0, ial );
314 std::vector<G4VPhysicalVolume*>::iterator citepv;
315 for( citepv = pvs->begin(); citepv != pvs->end(); citepv++ ) {
316 if( volname == (*citepv)->GetName()
317 && ( (*citepv)->GetCopyNo() == volcopy || -1 == volcopy ) ){
318 vvolu.push_back( *citepv );
323 if( vvolu.size() == 0 ) {
325 G4Exception(
" DicomIntersectVolume::GetPhysicalVolumes",
328 G4String(
"No physical volume found with name " + name).c_str());
330 G4cerr <<
"!!WARNING: DicomIntersectVolume::GetPhysicalVolumes: no physical volume found with name " << name <<
G4endl;
334 if( nVols != -1 &&
G4int(vvolu.size()) != nVols ) {
335 G4Exception(
"DicomIntersectVolume::GetLogicalVolumes:",
336 "Wrong number of physical volumes found",
362 std::vector<G4LogicalVolume*> DicomIntersectVolume::GetLogicalVolumes(
const G4String& name,
bool exists,
G4int nVols )
365 std::vector<G4LogicalVolume*> vvolu;
366 G4int ial = name.rfind(
":");
368 G4Exception(
"DicomIntersectVolume::GetLogicalVolumes",
371 G4String(
"Name corresponds to a touchable or physcal volume" + name).c_str());
375 std::vector<G4LogicalVolume*>::iterator citelv;
376 for( citelv = lvs->begin(); citelv != lvs->end(); citelv++ ) {
377 if( name == (*citelv)->GetName() ) {
378 vvolu.push_back( *citelv );
383 if( vvolu.size() == 0 ) {
387 G4Exception(
"DicomIntersectVolume::GetLogicalVolumes:",
"",
JustWarning,(
"no logical volume found with name " + name).c_str());
391 if( nVols != -1 &&
G4int(vvolu.size()) != nVols ) {
392 G4Exception(
"DicomIntersectVolume::GetLogicalVolumes:",
393 "Wrong number of logical volumes found",
403 std::vector<G4String> DicomIntersectVolume::GetWordsInString(
const G4String& stemp)
405 std::vector<G4String> wordlist;
410 const char* cstr = stemp.c_str();
411 int siz = stemp.length();
414 bool lastIsBlank =
false;
415 bool lastIsQuote =
false;
416 for( ii = 0; ii < siz; ii++ ){
417 if(cstr[ii] ==
'\"' ){
419 G4Exception(
"GmGenUtils:GetWordsFromString",
"",
FatalException, (
"There cannot be two quotes together " + stemp).c_str() );
421 if( nQuotes%2 == 1 ){
423 wordlist.push_back( stemp.substr(istart,ii-istart) );
431 }
else if(cstr[ii] ==
' ' ){
433 if( nQuotes%2 == 0 ){
434 if( !lastIsBlank && !lastIsQuote ) {
435 wordlist.push_back( stemp.substr(istart,ii-istart) );
445 wordlist.push_back( stemp.substr(istart,ii-istart+1) );
452 if( nQuotes%2 == 1 ) {