53 fPhantomMinusCorner(),
57 fUserVolumeCmd->
SetGuidance(
"Intersects a phantom with a user-defined volume "
58 "and outputs the voxels that are totally inside the intersection as"
59 " a new phantom file. It must have the parameters: POS_X POS_Y POS_Z "
60 "ANG_X ANG_Y ANG_Z SOLID_TYPE SOLID_PARAM_1 (SOLID_PARAM_2 ...)");
65 fG4VolumeCmd->
SetGuidance(
"Intersects a phantom with a user-defined volume"
66 " and outputs the voxels that are totally inside the intersection as "
67 " a new phantom file. It must have the parameters: POS_X POS_Y POS_Z "
68 "ANG_X ANG_Y ANG_Z SOLID_TYPE SOLID_PARAM_1 (SOLID_PARAM_2 ...)");
76 if (fUserVolumeCmd)
delete fUserVolumeCmd;
77 if (fG4VolumeCmd)
delete fG4VolumeCmd;
86 if (command == fUserVolumeCmd) {
88 std::vector<G4String> params = GetWordsInString( newValues );
89 if( params.size() < 8 ) {
91 " There must be at least 8 parameter: SOLID_TYPE POS_X POS_Y POS_Z "
92 "ANG_X ANG_Y ANG_Z SOLID_PARAM_1 (SOLID_PARAM_2 ...)",
94 G4String(
"Number of parameters given = " +
100 BuildUserSolid(params);
107 std::vector<double> angles;
113 }
else if (command == fG4VolumeCmd) {
114 std::vector<G4String> params = GetWordsInString( newValues );
115 if( params.size() !=1 )
122 " needs 1 argument: VOLUME_NAME").c_str());
125 BuildG4Solid(params);
152 G4String thePhantomFileName =
"phantom.g4pdcm";
153 fout.open(thePhantomFileName);
154 std::vector<G4Material*> materials = thePhantomParam->
GetMaterials();
155 fout << materials.size() <<
G4endl;
156 for(
unsigned int ii = 0; ii < materials.size(); ii++ ) {
157 fout << ii <<
" " << materials[ii]->GetName() <<
G4endl;
165 fVoxelIsInside =
new G4bool[nx*ny*nz];
171 fout << nx <<
" " << ny <<
" " << nz <<
G4endl;
172 fout << -voxelHalfWidthX*nx+thePhantomTransform.NetTranslation().x() <<
" "
173 << voxelHalfWidthX*nx+thePhantomTransform.NetTranslation().x() <<
G4endl;
174 fout << -voxelHalfWidthY*ny+thePhantomTransform.NetTranslation().y() <<
" "
175 << voxelHalfWidthY*ny+thePhantomTransform.NetTranslation().y() <<
G4endl;
176 fout << -voxelHalfWidthZ*nz+thePhantomTransform.NetTranslation().z() <<
" "
177 << voxelHalfWidthZ*nz+thePhantomTransform.NetTranslation().z() <<
G4endl;
179 for(
G4int iz = 0; iz < nz; iz++ ){
180 for(
G4int iy = 0; iy < ny; iy++) {
182 G4bool bPrevVoxelInside =
true;
183 G4bool b1VoxelFoundInside =
false;
184 G4int firstVoxel = -1;
185 G4int lastVoxel = -1;
186 for(
G4int ix = 0; ix < nx; ix++ ){
188 (-ny+iy*2+1)*voxelHalfWidthY, (-nz+iz*2+1)*voxelHalfWidthZ);
190 G4bool bVoxelIsInside =
true;
191 for(
G4int ivx = -1; ivx <= 1; ivx+=2 ) {
192 for(
G4int ivy = -1; ivy <= 1; ivy+=2 ){
193 for(
G4int ivz = -1; ivz <= 1; ivz+=2 ) {
195 + ivx*voxelHalfWidthX*axisX +
196 ivy*voxelHalfWidthY*axisY + ivz*voxelHalfWidthZ*axisZ;
198 bVoxelIsInside =
false;
203 if( !bVoxelIsInside )
break;
205 if( !bVoxelIsInside )
break;
208 G4int copyNo = ix + nx*iy + nxy*iz;
209 if( bVoxelIsInside ) {
210 if( !bPrevVoxelInside ) {
214 "Volume cannot intersect phantom in discontiguous voxels, "
215 "please use other voxel");
217 if( !b1VoxelFoundInside ) {
219 b1VoxelFoundInside =
true;
222 fVoxelIsInside[copyNo] =
true;
224 fVoxelIsInside[copyNo] =
false;
228 fout << firstVoxel <<
" " << lastVoxel <<
G4endl;
233 for(
G4int iz = 0; iz < nz; iz++ ){
234 for(
G4int iy = 0; iy < ny; iy++) {
236 for(
G4int ix = 0; ix < nx; ix++ ){
237 size_t copyNo = ix + ny*iy + nxy*iz;
239 if( fVoxelIsInside[copyNo] ) {
244 if(b1xFound ) fout <<
G4endl;
249 for(
G4int iz = 0; iz < nz; iz++ ){
250 for(
G4int iy = 0; iy < ny; iy++) {
252 for(
G4int ix = 0; ix < nx; ix++ ){
253 size_t copyNo = ix + ny*iy + nxy*iz;
254 if( fVoxelIsInside[copyNo] ) {
259 if(b1xFound ) fout <<
G4endl;
266 void DicomIntersectVolume::BuildUserSolid( std::vector<G4String> params )
268 for(
G4int ii = 0; ii < 6; ii++ ) params.erase( params.begin() );
270 params.insert( params.begin(),
":SOLID");
271 params.insert( params.begin(), params[1] );
279 void DicomIntersectVolume::BuildG4Solid( std::vector<G4String> params )
281 fSolid = GetLogicalVolumes( params[0], 1, 1)[0]->GetSolid();
291 std::vector<G4VPhysicalVolume*>::iterator cite;
292 for( cite = pvs->begin(); cite != pvs->end(); cite++ ) {
294 if( IsPhantomVolume( *cite ) ) {
306 if( !paramreg && bMustExist )
307 G4Exception(
"DicomIntersectVolume::GetPhantomParam",
310 " No G4PhantomParameterisation found ");
317 std::vector<G4VPhysicalVolume*> DicomIntersectVolume::GetPhysicalVolumes(
320 std::vector<G4VPhysicalVolume*> vvolu;
321 std::string::size_type ial = name.rfind(
":");
324 if( ial != std::string::npos ) {
325 std::string::size_type ial2 = name.rfind(
":",ial-1);
326 if( ial2 != std::string::npos ) {
327 G4Exception(
"DicomIntersectVolume::GetPhysicalVolumes",
330 G4String(
"Name corresponds to a touchable " + name).c_str());
332 volname = name.substr( 0, ial );
341 std::vector<G4VPhysicalVolume*>::iterator citepv;
342 for( citepv = pvs->begin(); citepv != pvs->end(); citepv++ ) {
343 if( volname == (*citepv)->GetName()
344 && ( (*citepv)->GetCopyNo() == volcopy || -1 == volcopy ) ){
345 vvolu.push_back( *citepv );
350 if( vvolu.size() == 0 ) {
352 G4Exception(
" DicomIntersectVolume::GetPhysicalVolumes",
355 G4String(
"No physical volume found with name " + name).c_str());
357 G4cerr <<
"!!WARNING: DicomIntersectVolume::GetPhysicalVolumes: "<<
358 " no physical volume found with name " << name <<
G4endl;
362 if( nVols != -1 &&
G4int(vvolu.size()) != nVols ) {
363 G4Exception(
"DicomIntersectVolume::GetLogicalVolumes:",
364 "Wrong number of physical volumes found",
366 (
"Number of physical volumes " +
392 std::vector<G4LogicalVolume*> DicomIntersectVolume::GetLogicalVolumes(
396 std::vector<G4LogicalVolume*> vvolu;
397 G4int ial = name.rfind(
":");
399 G4Exception(
"DicomIntersectVolume::GetLogicalVolumes",
402 G4String(
"Name corresponds to a touchable or physcal volume"
407 std::vector<G4LogicalVolume*>::iterator citelv;
408 for( citelv = lvs->begin(); citelv != lvs->end(); citelv++ ) {
409 if( name == (*citelv)->GetName() ) {
410 vvolu.push_back( *citelv );
415 if( vvolu.size() == 0 ) {
417 G4Exception(
"DicomIntersectVolume::GetLogicalVolumes:",
"",
421 G4Exception(
"DicomIntersectVolume::GetLogicalVolumes:",
"",
422 JustWarning,(
"no logical volume found with name " + name).c_str());
426 if( nVols != -1 &&
G4int(vvolu.size()) != nVols ) {
427 G4Exception(
"DicomIntersectVolume::GetLogicalVolumes:",
428 "Wrong number of logical volumes found",
430 (
"Number of logical volumes " +
440 std::vector<G4String> DicomIntersectVolume::GetWordsInString(
443 std::vector<G4String> wordlist;
448 const char* cstr = stemp.c_str();
449 int siz = stemp.length();
452 bool lastIsBlank =
false;
453 bool lastIsQuote =
false;
454 for( ii = 0; ii < siz; ii++ ){
455 if(cstr[ii] ==
'\"' ){
458 (
"There cannot be two quotes together " + stemp).c_str() );
460 if( nQuotes%2 == 1 ){
462 wordlist.push_back( stemp.substr(istart,ii-istart) );
472 }
else if(cstr[ii] ==
' ' ){
475 if( nQuotes%2 == 0 ){
476 if( !lastIsBlank && !lastIsQuote ) {
477 wordlist.push_back( stemp.substr(istart,ii-istart) );
489 wordlist.push_back( stemp.substr(istart,ii-istart+1) );
497 if( nQuotes%2 == 1 ) {
499 (
"unbalanced quotes in line " + stemp).c_str() );
void SetParameterName(const char *theName, G4bool omittable, G4bool currentAsDefault=false)
G4ThreeVector GetFrameTranslation() const
G4VSolid * FindOrConstructG4Solid(const G4tgrSolid *vol)
CLHEP::Hep3Vector G4ThreeVector
HepRotation & rotateX(double delta)
CLHEP::HepRotation G4RotationMatrix
G4double GetDensity() const
static G4String ConvertToString(G4bool boolVal)
HepRotation & rotateY(double delta)
size_t GetMaterialIndex(size_t nx, size_t ny, size_t nz) const
size_t GetNoVoxelZ() const
static G4PhysicalVolumeStore * GetInstance()
G4VPVParameterisation * GetParameterisation() const
virtual EInside Inside(const G4ThreeVector &p) const =0
virtual G4int GetRegularStructureId() const =0
void SetGuidance(const char *aGuidance)
std::vector< G4Material * > GetMaterials() const
static G4double ConvertToDouble(const char *st)
static G4LogicalVolumeStore * GetInstance()
const G4String & GetCommandPath() const
void AvailableForStates(G4ApplicationState s1)
G4double GetVoxelHalfY() const
static constexpr double cm3
static G4int ConvertToInt(const char *st)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
virtual void SetNewValue(G4UIcommand *command, G4String newValues)
G4Material * GetMaterial(size_t nx, size_t ny, size_t nz) const
const G4RotationMatrix * GetFrameRotation() const
const G4String & GetCommandName() const
size_t GetNoVoxelY() const
G4double GetVoxelHalfX() const
Definition of the DicomIntersectVolume class.
virtual void GetReplicationData(EAxis &axis, G4int &nReplicas, G4double &width, G4double &offset, G4bool &consuming) const =0
G4double GetVoxelHalfZ() const
size_t GetNoVoxelX() const
static const G4double pos
G4GLOB_DLL std::ostream G4cerr