Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/examples/extended/medical/DICOM/src/DicomIntersectVolume.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /examples/extended/medical/DICOM/src/DicomIntersectVolume.cc (Version 11.3.0) and /examples/extended/medical/DICOM/src/DicomIntersectVolume.cc (Version 5.1)


  1 //                                                  1 
  2 // *******************************************    
  3 // * License and Disclaimer                       
  4 // *                                              
  5 // * The  Geant4 software  is  copyright of th    
  6 // * the Geant4 Collaboration.  It is provided    
  7 // * conditions of the Geant4 Software License    
  8 // * LICENSE and available at  http://cern.ch/    
  9 // * include a list of copyright holders.         
 10 // *                                              
 11 // * Neither the authors of this software syst    
 12 // * institutes,nor the agencies providing fin    
 13 // * work  make  any representation or  warran    
 14 // * regarding  this  software system or assum    
 15 // * use.  Please see the license in the file     
 16 // * for the full disclaimer and the limitatio    
 17 // *                                              
 18 // * This  code  implementation is the result     
 19 // * technical work of the GEANT4 collaboratio    
 20 // * By using,  copying,  modifying or  distri    
 21 // * any work based  on the software)  you  ag    
 22 // * use  in  resulting  scientific  publicati    
 23 // * acceptance of all terms of the Geant4 Sof    
 24 // *******************************************    
 25 //                                                
 26 //                                                
 27 /// \file medical/DICOM/src/DicomIntersectVolu    
 28 /// \brief Implementation of the DicomIntersec    
 29 //                                                
 30                                                   
 31 #include "DicomIntersectVolume.hh"                
 32                                                   
 33 #include "G4LogicalVolume.hh"                     
 34 #include "G4LogicalVolumeStore.hh"                
 35 #include "G4Material.hh"                          
 36 #include "G4PVParameterised.hh"                   
 37 #include "G4PhantomParameterisation.hh"           
 38 #include "G4PhysicalVolumeStore.hh"               
 39 #include "G4SystemOfUnits.hh"                     
 40 #include "G4UIcmdWithAString.hh"                  
 41 #include "G4UIcommand.hh"                         
 42 #include "G4VPhysicalVolume.hh"                   
 43 #include "G4VSolid.hh"                            
 44 #include "G4tgbVolume.hh"                         
 45 #include "G4tgrSolid.hh"                          
 46                                                   
 47 //....oooOO0OOooo........oooOO0OOooo........oo    
 48 DicomIntersectVolume::DicomIntersectVolume()      
 49   : G4UImessenger(), fG4VolumeCmd(0), fSolid(0    
 50 {                                                 
 51   fUserVolumeCmd = new G4UIcmdWithAString("/di    
 52   fUserVolumeCmd->SetGuidance(                    
 53     "Intersects a phantom with a user-defined     
 54     "and outputs the voxels that are totally i    
 55     " a new phantom file. It must have the par    
 56     "ANG_X ANG_Y ANG_Z SOLID_TYPE SOLID_PARAM_    
 57   fUserVolumeCmd->SetParameterName("choice", t    
 58   fUserVolumeCmd->AvailableForStates(G4State_I    
 59                                                   
 60   fG4VolumeCmd = new G4UIcmdWithAString("/dico    
 61   fG4VolumeCmd->SetGuidance(                      
 62     "Intersects a phantom with a user-defined     
 63     " and outputs the voxels that are totally     
 64     " a new phantom file. It must have the par    
 65     "ANG_X ANG_Y ANG_Z SOLID_TYPE SOLID_PARAM_    
 66   fG4VolumeCmd->SetParameterName("choice", tru    
 67   fG4VolumeCmd->AvailableForStates(G4State_Idl    
 68 }                                                 
 69                                                   
 70 //....oooOO0OOooo........oooOO0OOooo........oo    
 71 DicomIntersectVolume::~DicomIntersectVolume()     
 72 {                                                 
 73   if (fUserVolumeCmd) delete fUserVolumeCmd;      
 74   if (fG4VolumeCmd) delete fG4VolumeCmd;          
 75 }                                                 
 76                                                   
 77 //....oooOO0OOooo........oooOO0OOooo........oo    
 78 void DicomIntersectVolume::SetNewValue(G4UIcom    
 79 {                                                 
 80   G4AffineTransform theVolumeTransform;           
 81                                                   
 82   if (command == fUserVolumeCmd) {                
 83     std::vector<G4String> params = GetWordsInS    
 84     if (params.size() < 8) {                      
 85       G4Exception("DicomIntersectVolume::SetNe    
 86                   " There must be at least 8 p    
 87                   "ANG_X ANG_Y ANG_Z SOLID_PAR    
 88                   FatalErrorInArgument,           
 89                   G4String("Number of paramete    
 90                            + G4UIcommand::Conv    
 91                     .c_str());                    
 92     }                                             
 93                                                   
 94     //----- Build G4VSolid                        
 95     BuildUserSolid(params);                       
 96                                                   
 97     //----- Calculate volume inverse 3D transf    
 98     G4ThreeVector pos = G4ThreeVector(G4UIcomm    
 99                                       G4UIcomm    
100                                       G4UIcomm    
101     G4RotationMatrix* rotmat = new G4RotationM    
102     std::vector<G4double> angles;                 
103     rotmat->rotateX(G4UIcommand::ConvertToDoub    
104     rotmat->rotateY(G4UIcommand::ConvertToDoub    
105     rotmat->rotateY(G4UIcommand::ConvertToDoub    
106     theVolumeTransform = G4AffineTransform(rot    
107   }                                               
108   else if (command == fG4VolumeCmd) {             
109     std::vector<G4String> params = GetWordsInS    
110     if (params.size() != 1)                       
111       G4Exception("DicomIntersectVolume::SetNe    
112                   G4String("Command: " + comma    
113                            + " " + newValues +    
114                     .c_str());                    
115                                                   
116     //----- Build G4VSolid                        
117     BuildG4Solid(params);                         
118                                                   
119     //----- Calculate volume inverse 3D transf    
120     G4VPhysicalVolume* pv = GetPhysicalVolumes    
121                                                   
122     theVolumeTransform = G4AffineTransform(pv-    
123   }                                               
124                                                   
125   //----- Calculate relative phantom - volume     
126   G4PhantomParameterisation* thePhantomParam =    
127                                                   
128   G4RotationMatrix* rotph = new G4RotationMatr    
129   // assumes the phantom mother is not rotated    
130   G4AffineTransform thePhantomTransform(rotph,    
131   // assumes the phantom mother is not transla    
132                                                   
133   G4AffineTransform theTransform = theVolumeTr    
134                                                   
135   G4ThreeVector axisX(1., 0., 0.);                
136   G4ThreeVector axisY(0., 1., 0.);                
137   G4ThreeVector axisZ(0., 0., 1.);                
138   theTransform.ApplyAxisTransform(axisX);         
139   theTransform.ApplyAxisTransform(axisY);         
140   theTransform.ApplyAxisTransform(axisZ);         
141                                                   
142   //----- Write phantom header                    
143   G4String thePhantomFileName = "phantom.g4pdc    
144   fout.open(thePhantomFileName);                  
145   std::vector<G4Material*> materials = thePhan    
146   fout << materials.size() << G4endl;             
147   for (unsigned int ii = 0; ii < materials.siz    
148     fout << ii << " " << materials[ii]->GetNam    
149   }                                               
150                                                   
151   //----- Loop to pantom voxels                   
152   G4int nx = G4int(thePhantomParam->GetNoVoxel    
153   G4int ny = G4int(thePhantomParam->GetNoVoxel    
154   G4int nz = G4int(thePhantomParam->GetNoVoxel    
155   G4int nxy = nx * ny;                            
156   fVoxelIsInside = new G4bool[nx * ny * nz];      
157   G4double voxelHalfWidthX = thePhantomParam->    
158   G4double voxelHalfWidthY = thePhantomParam->    
159   G4double voxelHalfWidthZ = thePhantomParam->    
160                                                   
161   //----- Write phantom dimensions and limits     
162   fout << nx << " " << ny << " " << nz << G4en    
163   fout << -voxelHalfWidthX * nx + thePhantomTr    
164        << voxelHalfWidthX * nx + thePhantomTra    
165   fout << -voxelHalfWidthY * ny + thePhantomTr    
166        << voxelHalfWidthY * ny + thePhantomTra    
167   fout << -voxelHalfWidthZ * nz + thePhantomTr    
168        << voxelHalfWidthZ * nz + thePhantomTra    
169                                                   
170   for (G4int iz = 0; iz < nz; ++iz) {             
171     for (G4int iy = 0; iy < ny; ++iy) {           
172       G4bool bPrevVoxelInside = true;             
173       G4bool b1VoxelFoundInside = false;          
174       G4int firstVoxel = -1;                      
175       G4int lastVoxel = -1;                       
176       for (G4int ix = 0; ix < nx; ++ix) {         
177         G4ThreeVector voxelCentre((-nx + ix *     
178                                   (-ny + iy *     
179                                   (-nz + iz *     
180         theTransform.ApplyPointTransform(voxel    
181         G4bool bVoxelIsInside = true;             
182         for (G4int ivx = -1; ivx <= 1; ivx +=     
183           for (G4int ivy = -1; ivy <= 1; ivy +    
184             for (G4int ivz = -1; ivz <= 1; ivz    
185               G4ThreeVector voxelPoint = voxel    
186                                          + ivy    
187                                          + ivz    
188               if (fSolid->Inside(voxelPoint) =    
189                 bVoxelIsInside = false;           
190                 break;                            
191               }                                   
192               else {                              
193               }                                   
194             }                                     
195             if (!bVoxelIsInside) break;           
196           }                                       
197           if (!bVoxelIsInside) break;             
198         }                                         
199                                                   
200         G4int copyNo = ix + nx * iy + nxy * iz    
201         if (bVoxelIsInside) {                     
202           if (!bPrevVoxelInside) {                
203             G4Exception("DicomIntersectVolume:    
204                         "Volume cannot interse    
205                         "please use other voxe    
206           }                                       
207           if (!b1VoxelFoundInside) {              
208             firstVoxel = ix;                      
209             b1VoxelFoundInside = true;            
210           }                                       
211           lastVoxel = ix;                         
212           fVoxelIsInside[copyNo] = true;          
213         }                                         
214         else {                                    
215           fVoxelIsInside[copyNo] = false;         
216         }                                         
217       }                                           
218       fout << firstVoxel << " " << lastVoxel <    
219     }                                             
220   }                                               
221                                                   
222   //-----  Now write the materials                
223   for (G4int iz = 0; iz < nz; ++iz) {             
224     for (G4int iy = 0; iy < ny; ++iy) {           
225       G4bool b1xFound = false;                    
226       for (G4int ix = 0; ix < nx; ++ix) {         
227         size_t copyNo = ix + ny * iy + nxy * i    
228         if (fVoxelIsInside[copyNo]) {             
229           fout << thePhantomParam->GetMaterial    
230           b1xFound = true;                        
231         }                                         
232       }                                           
233       if (b1xFound) fout << G4endl;               
234     }                                             
235   }                                               
236                                                   
237   // Now write densities                          
238   for (G4int iz = 0; iz < nz; ++iz) {             
239     for (G4int iy = 0; iy < ny; ++iy) {           
240       G4bool b1xFound = false;                    
241       for (G4int ix = 0; ix < nx; ++ix) {         
242         size_t copyNo = ix + ny * iy + nxy * i    
243         if (fVoxelIsInside[copyNo]) {             
244           fout << thePhantomParam->GetMaterial    
245           b1xFound = true;                        
246         }                                         
247       }                                           
248       if (b1xFound) fout << G4endl;               
249     }                                             
250   }                                               
251 }                                                 
252                                                   
253 //....oooOO0OOooo........oooOO0OOooo........oo    
254 void DicomIntersectVolume::BuildUserSolid(std:    
255 {                                                 
256   for (G4int ii = 0; ii < 6; ++ii)                
257     params.erase(params.begin());                 
258   // take otu position and rotation angles        
259   params.insert(params.begin(), ":SOLID");        
260   params.insert(params.begin(), params[1]);       
261   G4tgrSolid* tgrSolid = new G4tgrSolid(params    
262   G4tgbVolume* tgbVolume = new G4tgbVolume();     
263   fSolid = tgbVolume->FindOrConstructG4Solid(t    
264 }                                                 
265                                                   
266 //....oooOO0OOooo........oooOO0OOooo........oo    
267 void DicomIntersectVolume::BuildG4Solid(std::v    
268 {                                                 
269   fSolid = GetLogicalVolumes(params[0], 1, 1)[    
270 }                                                 
271                                                   
272 //....oooOO0OOooo........oooOO0OOooo........oo    
273 G4PhantomParameterisation* DicomIntersectVolum    
274 {                                                 
275   G4PhantomParameterisation* paramreg = 0;        
276                                                   
277   G4PhysicalVolumeStore* pvs = G4PhysicalVolum    
278   for (auto cite = pvs->cbegin(); cite != pvs-    
279     if (IsPhantomVolume(*cite)) {                 
280       const G4PVParameterised* pvparam = stati    
281       G4VPVParameterisation* param = pvparam->    
282       //    if( static_cast<const G4PhantomPar    
283       //    if( static_cast<const G4PhantomPar    
284       //      G4cout << "G4PhantomParameterisa    
285       // << (*cite)->GetName() << G4endl;         
286       paramreg = static_cast<G4PhantomParamete    
287     }                                             
288   }                                               
289                                                   
290   if (!paramreg && bMustExist)                    
291     G4Exception("DicomIntersectVolume::GetPhan    
292                 " No G4PhantomParameterisation    
293                                                   
294   return paramreg;                                
295 }                                                 
296                                                   
297 //....oooOO0OOooo........oooOO0OOooo........oo    
298 std::vector<G4VPhysicalVolume*> DicomIntersect    
299                                                   
300 {                                                 
301   std::vector<G4VPhysicalVolume*> vvolu;          
302   std::string::size_type ial = name.rfind(":")    
303   G4String volname = "";                          
304   G4int volcopy = 0;                              
305   if (ial != std::string::npos) {                 
306     std::string::size_type ial2 = name.rfind("    
307     if (ial2 != std::string::npos) {              
308       G4Exception("DicomIntersectVolume::GetPh    
309                   G4String("Name corresponds t    
310     }                                             
311     else {                                        
312       volname = name.substr(0, ial);              
313       volcopy = G4UIcommand::ConvertToInt(name    
314     }                                             
315   }                                               
316   else {                                          
317     volname = name;                               
318     volcopy = -1;                                 
319   }                                               
320                                                   
321   G4PhysicalVolumeStore* pvs = G4PhysicalVolum    
322   for (auto citepv = pvs->cbegin(); citepv !=     
323     if (volname == (*citepv)->GetName() && ((*    
324       vvolu.push_back(*citepv);                   
325     }                                             
326   }                                               
327                                                   
328   //----- Check that at least one volume was f    
329   if (vvolu.size() == 0) {                        
330     if (exists) {                                 
331       G4Exception(" DicomIntersectVolume::GetP    
332                   G4String("No physical volume    
333     }                                             
334     else {                                        
335       G4cerr << "!!WARNING: DicomIntersectVolu    
336              << " no physical volume found wit    
337     }                                             
338   }                                               
339                                                   
340   if (nVols != -1 && G4int(vvolu.size()) != nV    
341     G4Exception("DicomIntersectVolume::GetLogi    
342                 "Wrong number of physical volu    
343                 ("Number of physical volumes "    
344                  + ", requesting " + G4UIcomma    
345                   .c_str());                      
346   }                                               
347                                                   
348   return vvolu;                                   
349 }                                                 
350                                                   
351 //....oooOO0OOooo........oooOO0OOooo........oo    
352 G4bool DicomIntersectVolume::IsPhantomVolume(G    
353 {                                                 
354   EAxis axis;                                     
355   G4int nReplicas;                                
356   G4double width, offset;                         
357   G4bool consuming;                               
358   pv->GetReplicationData(axis, nReplicas, widt    
359   EVolume type = (consuming) ? kReplica : kPar    
360   if (type == kParameterised && pv->GetRegular    
361     return TRUE;                                  
362   }                                               
363   else {                                          
364     return FALSE;                                 
365   }                                               
366 }                                                 
367                                                   
368 //....oooOO0OOooo........oooOO0OOooo........oo    
369 std::vector<G4LogicalVolume*> DicomIntersectVo    
370                                                   
371 {                                                 
372   //  G4cout << "GetLogicalVolumes " << name <    
373   std::vector<G4LogicalVolume*> vvolu;            
374   G4int ial = G4int(name.rfind(":"));             
375   if (ial != -1) {                                
376     G4Exception("DicomIntersectVolume::GetLogi    
377                 G4String("Name corresponds to     
378   }                                               
379                                                   
380   G4LogicalVolumeStore* lvs = G4LogicalVolumeS    
381   for (auto citelv = lvs->cbegin(); citelv !=     
382     if (name == (*citelv)->GetName()) {           
383       vvolu.push_back(*citelv);                   
384     }                                             
385   }                                               
386                                                   
387   //----- Check that at least one volume was f    
388   if (vvolu.size() == 0) {                        
389     if (exists) {                                 
390       G4Exception("DicomIntersectVolume::GetLo    
391                   ("no logical volume found wi    
392     }                                             
393     else {                                        
394       G4Exception("DicomIntersectVolume::GetLo    
395                   ("no  logical volume found w    
396     }                                             
397   }                                               
398                                                   
399   if (nVols != -1 && G4int(vvolu.size()) != nV    
400     G4Exception("DicomIntersectVolume::GetLogi    
401                 FatalErrorInArgument,             
402                 ("Number of logical volumes "     
403                  + ", requesting " + G4UIcomma    
404                   .c_str());                      
405   }                                               
406                                                   
407   return vvolu;                                   
408 }                                                 
409                                                   
410 //....oooOO0OOooo........oooOO0OOooo........oo    
411 std::vector<G4String> DicomIntersectVolume::Ge    
412 {                                                 
413   std::vector<G4String> wordlist;                 
414                                                   
415   //---------- Read a line of file:               
416   //----- Clear wordlist                          
417   G4int ii;                                       
418   const char* cstr = stemp.c_str();               
419   G4int siz = G4int(stemp.length());              
420   G4int istart = 0;                               
421   G4int nQuotes = 0;                              
422   G4bool lastIsBlank = false;                     
423   G4bool lastIsQuote = false;                     
424   for (ii = 0; ii < siz; ++ii) {                  
425     if (cstr[ii] == '\"') {                       
426       if (lastIsQuote) {                          
427         G4Exception("GmGenUtils:GetWordsFromSt    
428                     ("There cannot be two quot    
429       }                                           
430       if (nQuotes % 2 == 1) {                     
431         // close word                             
432         wordlist.push_back(stemp.substr(istart    
433         //        G4cout << "GetWordsInString     
434         //<< wordlist[wordlist.size()-1] << "     
435         //<< " ii " << ii << G4endl;              
436       }                                           
437       else {                                      
438         istart = ii + 1;                          
439       }                                           
440       ++nQuotes;                                  
441       lastIsQuote = true;                         
442       lastIsBlank = false;                        
443     }                                             
444     else if (cstr[ii] == ' ') {                   
445       //            G4cout << "GetWordsInStrin    
446       //<< nQuotes << " lastIsBlank " << lastI    
447       if (nQuotes % 2 == 0) {                     
448         if (!lastIsBlank && !lastIsQuote) {       
449           wordlist.push_back(stemp.substr(ista    
450           //          G4cout << "GetWordsInStr    
451           //<< wordlist[wordlist.size()-1] <<     
452           //<< lastIsBlank << G4endl;             
453         }                                         
454                                                   
455         istart = ii + 1;                          
456         lastIsQuote = false;                      
457         lastIsBlank = true;                       
458       }                                           
459     }                                             
460     else {                                        
461       if (ii == siz - 1) {                        
462         wordlist.push_back(stemp.substr(istart    
463         //                G4cout << "GetWordsI    
464         //<< wordlist[wordlist.size()-1] << "     
465       }                                           
466       lastIsQuote = false;                        
467       lastIsBlank = false;                        
468     }                                             
469   }                                               
470   if (nQuotes % 2 == 1) {                         
471     G4Exception("GmGenUtils:GetWordsFromString    
472                 ("unbalanced quotes in line "     
473   }                                               
474                                                   
475   return wordlist;                                
476 }                                                 
477