Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 // G4STRead implementation << 26 // $Id: G4STRead.cc 69813 2013-05-15 15:44:33Z gcosmo $ 27 // 27 // 28 // Author: Zoltan Torzsok, November 2007 << 28 // class G4STRead Implementation 29 // ------------------------------------------- << 29 // >> 30 // History: >> 31 // - Created. Zoltan Torzsok, November 2007 >> 32 // ------------------------------------------------------------------------- 30 33 31 #include <fstream> 34 #include <fstream> 32 35 33 #include "G4STRead.hh" 36 #include "G4STRead.hh" 34 37 35 #include "G4Material.hh" 38 #include "G4Material.hh" 36 #include "G4Box.hh" 39 #include "G4Box.hh" 37 #include "G4QuadrangularFacet.hh" 40 #include "G4QuadrangularFacet.hh" 38 #include "G4TriangularFacet.hh" 41 #include "G4TriangularFacet.hh" 39 #include "G4TessellatedSolid.hh" 42 #include "G4TessellatedSolid.hh" 40 #include "G4LogicalVolume.hh" 43 #include "G4LogicalVolume.hh" 41 #include "G4PVPlacement.hh" 44 #include "G4PVPlacement.hh" 42 #include "G4AffineTransform.hh" 45 #include "G4AffineTransform.hh" 43 #include "G4VoxelLimits.hh" 46 #include "G4VoxelLimits.hh" 44 47 45 // ------------------------------------------- << 46 void G4STRead::TessellatedRead(const std::stri 48 void G4STRead::TessellatedRead(const std::string& line) 47 { 49 { 48 if(tessellatedList.size() > 0) << 50 if (tessellatedList.size()>0) 49 { << 51 { 50 tessellatedList.back()->SetSolidClosed(tru << 52 tessellatedList.back()->SetSolidClosed(true); 51 // Finish the previous solid at first! << 53 // Finish the previous solid at first! 52 } << 54 } 53 << 55 54 std::istringstream stream(line.substr(2)); << 56 std::istringstream stream(line.substr(2)); 55 << 57 56 G4String name; << 58 G4String name; 57 stream >> name; << 59 stream >> name; 58 << 60 59 G4TessellatedSolid* tessellated = new G4Tess << 61 G4TessellatedSolid* tessellated = new G4TessellatedSolid(name); 60 volumeMap[tessellated] = << 62 volumeMap[tessellated] = 61 new G4LogicalVolume(tessellated, solid_mat << 63 new G4LogicalVolume(tessellated, solid_material, name+"_LV" , 0, 0, 0); 62 tessellatedList.push_back(tessellated); << 64 tessellatedList.push_back(tessellated); 63 << 65 64 #ifdef G4VERBOSE << 66 G4cout << "G4STRead: Reading solid: " << name << G4endl; 65 G4cout << "G4STRead: Reading solid: " << nam << 66 #endif << 67 } 67 } 68 68 69 // ------------------------------------------- << 70 void G4STRead::FacetRead(const std::string& li 69 void G4STRead::FacetRead(const std::string& line) 71 { 70 { 72 if(tessellatedList.size() == 0) << 71 if (tessellatedList.size()==0) 73 { << 72 { 74 G4Exception("G4STRead::FacetRead()", "Read << 73 G4Exception("G4STRead::FacetRead()", "ReadError", FatalException, 75 "A solid must be defined befor << 74 "A solid must be defined before defining a facet!"); 76 } << 75 } 77 << 76 78 if(line[2] == '3') // Triangular facet << 77 if (line[2]=='3') // Triangular facet 79 { << 78 { 80 G4double x1, y1, z1; << 79 G4double x1,y1,z1; 81 G4double x2, y2, z2; << 80 G4double x2,y2,z2; 82 G4double x3, y3, z3; << 81 G4double x3,y3,z3; 83 << 82 84 std::istringstream stream(line.substr(4)); << 83 std::istringstream stream(line.substr(4)); 85 stream >> x1 >> y1 >> z1 >> x2 >> y2 >> z2 << 84 stream >> x1 >> y1 >> z1 >> x2 >> y2 >> z2 >> x3 >> y3 >> z3; 86 tessellatedList.back()->AddFacet(new G4Tri << 85 tessellatedList.back()-> 87 G4ThreeVector(x1, y1, z1), G4ThreeVector << 86 AddFacet(new G4TriangularFacet(G4ThreeVector(x1,y1,z1), 88 G4ThreeVector(x3, y3, z3), ABSOLUTE)); << 87 G4ThreeVector(x2,y2,z2), 89 } << 88 G4ThreeVector(x3,y3,z3), ABSOLUTE)); 90 else if(line[2] == '4') // Quadrangular fac << 89 } 91 { << 90 else if (line[2]=='4') // Quadrangular facet 92 G4double x1, y1, z1; << 91 { 93 G4double x2, y2, z2; << 92 G4double x1,y1,z1; 94 G4double x3, y3, z3; << 93 G4double x2,y2,z2; 95 G4double x4, y4, z4; << 94 G4double x3,y3,z3; 96 << 95 G4double x4,y4,z4; 97 std::istringstream stream(line.substr(4)); << 96 98 stream >> x1 >> y1 >> z1 >> x2 >> y2 >> z2 << 97 std::istringstream stream(line.substr(4)); 99 z4; << 98 stream >> x1 >> y1 >> z1 >> x2 >> y2 >> z2 100 tessellatedList.back()->AddFacet(new G4Qua << 99 >> x3 >> y3 >> z3 >> x4 >> y4 >> z4; 101 G4ThreeVector(x1, y1, z1), G4ThreeVector << 100 tessellatedList.back()-> 102 G4ThreeVector(x3, y3, z3), G4ThreeVector << 101 AddFacet(new G4QuadrangularFacet(G4ThreeVector(x1,y1,z1), 103 } << 102 G4ThreeVector(x2,y2,z2), 104 else << 103 G4ThreeVector(x3,y3,z3), 105 { << 104 G4ThreeVector(x4,y4,z4), ABSOLUTE)); 106 G4Exception("G4STRead::FacetRead()", "Read << 105 } 107 "Number of vertices per facet << 106 else 108 } << 107 { >> 108 G4Exception("G4STRead::FacetRead()", "ReadError", FatalException, >> 109 "Number of vertices per facet should be either 3 or 4!"); >> 110 } 109 } 111 } 110 112 111 // ------------------------------------------- << 112 void G4STRead::PhysvolRead(const std::string& 113 void G4STRead::PhysvolRead(const std::string& line) 113 { 114 { 114 G4int level; << 115 G4int level; 115 G4String name; << 116 G4String name; 116 G4double r1, r2, r3; << 117 G4double r1,r2,r3; 117 G4double r4, r5, r6; << 118 G4double r4,r5,r6; 118 G4double r7, r8, r9; << 119 G4double r7,r8,r9; 119 G4double pX, pY, pZ; << 120 G4double pX,pY,pZ; 120 G4double n1, n2, n3, n4, n5; << 121 G4double n1,n2,n3,n4,n5; 121 << 122 122 std::istringstream stream(line.substr(2)); << 123 std::istringstream stream(line.substr(2)); 123 stream >> level >> name >> r1 >> r2 >> r3 >> << 124 stream >> level >> name >> r1 >> r2 >> r3 >> n1 >> r4 >> r5 >> r6 124 r7 >> r8 >> r9 >> n3 >> pX >> pY >> pZ >> << 125 >> n2 >> r7 >> r8 >> r9 >> n3 >> pX >> pY >> pZ >> n4 >> n5; 125 std::string::size_type idx = name.rfind("_") << 126 std::string::size_type idx = name.rfind("_"); 126 if(idx != std::string::npos) << 127 if (idx!=std::string::npos) 127 { << 128 { 128 name.resize(idx); << 129 name.resize(idx); 129 } << 130 } 130 else << 131 else 131 { << 132 { 132 G4Exception("G4STRead::PhysvolRead()", "Re << 133 G4Exception("G4STRead::PhysvolRead()", "ReadError", 133 "Invalid input stream!"); << 134 FatalException, "Invalid input stream!"); 134 return; << 135 return; 135 } << 136 } 136 << 137 137 G4cout << "G4STRead: Placing tessellated sol << 138 G4cout << "G4STRead: Placing tessellated solid: " << name << G4endl; 138 << 139 139 G4TessellatedSolid* tessellated = nullptr; << 140 G4TessellatedSolid* tessellated = 0; 140 << 141 141 for(std::size_t i = 0; i < tessellatedList.s << 142 for (size_t i=0; i<tessellatedList.size(); i++) 142 { // Find the volume for this physvol! << 143 { // Find the volume for this physvol! 143 if(tessellatedList[i]->GetName() == G4Stri << 144 if (tessellatedList[i]->GetName() == G4String(name)) 144 { << 145 { 145 tessellated = tessellatedList[i]; << 146 tessellated = tessellatedList[i]; 146 break; << 147 break; 147 } << 148 } 148 } << 149 } 149 << 150 150 if(tessellated == nullptr) << 151 if (tessellated == 0) 151 { << 152 { 152 G4String error_msg = "Referenced solid '" << 153 G4String error_msg = "Referenced solid '" + name + "' not found!"; 153 G4Exception("G4STRead::PhysvolRead()", "Re << 154 G4Exception("G4STRead::PhysvolRead()", "ReadError", 154 error_msg); << 155 FatalException, error_msg); 155 } << 156 } 156 if(volumeMap.find(tessellated) == volumeMap. << 157 if (volumeMap.find(tessellated) == volumeMap.end()) 157 { << 158 { 158 G4String error_msg = "Referenced solid '" << 159 G4String error_msg = "Referenced solid '" + name 159 "' is not associated << 160 + "' is not associated with a logical volume!"; 160 G4Exception("G4STRead::PhysvolRead()", "In << 161 G4Exception("G4STRead::PhysvolRead()", "InvalidSetup", 161 error_msg); << 162 FatalException, error_msg); 162 } << 163 } 163 const G4RotationMatrix rot(G4ThreeVector(r1, << 164 const G4RotationMatrix rot(G4ThreeVector(r1,r2,r3), 164 G4ThreeVector(r4, << 165 G4ThreeVector(r4,r5,r6), 165 G4ThreeVector(r7, << 166 G4ThreeVector(r7,r8,r9)); 166 const G4ThreeVector pos(pX, pY, pZ); << 167 const G4ThreeVector pos(pX,pY,pZ); 167 << 168 168 new G4PVPlacement(G4Transform3D(rot.inverse( << 169 new G4PVPlacement(G4Transform3D(rot.inverse(),pos), 169 name + "_PV", world_volume << 170 volumeMap[tessellated], name+"_PV", world_volume, 0, 0); 170 // Note: INVERSE of rotation is needed!!! << 171 // Note: INVERSE of rotation is needed!!! 171 << 172 172 G4double minx, miny, minz; << 173 G4double minx,miny,minz; 173 G4double maxx, maxy, maxz; << 174 G4double maxx,maxy,maxz; 174 const G4VoxelLimits limits; << 175 const G4VoxelLimits limits; 175 << 176 176 tessellated->CalculateExtent(kXAxis, limits, << 177 tessellated->CalculateExtent(kXAxis,limits, 177 minx, maxx); << 178 G4AffineTransform(rot,pos),minx,maxx); 178 tessellated->CalculateExtent(kYAxis, limits, << 179 tessellated->CalculateExtent(kYAxis,limits, 179 miny, maxy); << 180 G4AffineTransform(rot,pos),miny,maxy); 180 tessellated->CalculateExtent(kZAxis, limits, << 181 tessellated->CalculateExtent(kZAxis,limits, 181 minz, maxz); << 182 G4AffineTransform(rot,pos),minz,maxz); 182 << 183 183 if(world_extent.x() < std::fabs(minx)) << 184 if (world_extent.x() < std::fabs(minx)) 184 { << 185 { world_extent.setX(std::fabs(minx)); } 185 world_extent.setX(std::fabs(minx)); << 186 if (world_extent.y() < std::fabs(miny)) 186 } << 187 { world_extent.setY(std::fabs(miny)); } 187 if(world_extent.y() < std::fabs(miny)) << 188 if (world_extent.z() < std::fabs(minz)) 188 { << 189 { world_extent.setZ(std::fabs(minz)); } 189 world_extent.setY(std::fabs(miny)); << 190 if (world_extent.x() < std::fabs(maxx)) 190 } << 191 { world_extent.setX(std::fabs(maxx)); } 191 if(world_extent.z() < std::fabs(minz)) << 192 if (world_extent.y() < std::fabs(maxy)) 192 { << 193 { world_extent.setY(std::fabs(maxy)); } 193 world_extent.setZ(std::fabs(minz)); << 194 if (world_extent.z() < std::fabs(maxz)) 194 } << 195 { world_extent.setZ(std::fabs(maxz)); } 195 if(world_extent.x() < std::fabs(maxx)) << 196 { << 197 world_extent.setX(std::fabs(maxx)); << 198 } << 199 if(world_extent.y() < std::fabs(maxy)) << 200 { << 201 world_extent.setY(std::fabs(maxy)); << 202 } << 203 if(world_extent.z() < std::fabs(maxz)) << 204 { << 205 world_extent.setZ(std::fabs(maxz)); << 206 } << 207 } 196 } 208 197 209 // ------------------------------------------- << 210 void G4STRead::ReadGeom(const G4String& name) 198 void G4STRead::ReadGeom(const G4String& name) 211 { 199 { 212 #ifdef G4VERBOSE << 200 G4cout << "G4STRead: Reading '" << name << "'..." << G4endl; 213 G4cout << "G4STRead: Reading '" << name << " << 201 214 #endif << 202 std::ifstream GeomFile(name); 215 std::ifstream GeomFile(name); << 203 216 << 204 if (!GeomFile) 217 if(!GeomFile) << 205 { 218 { << 206 G4String error_msg = "Cannot open file: " + name; 219 G4String error_msg = "Cannot open file: " << 207 G4Exception("G4STRead::ReadGeom()", "ReadError", 220 G4Exception("G4STRead::ReadGeom()", "ReadE << 208 FatalException, error_msg); 221 } << 209 } 222 << 210 223 tessellatedList.clear(); << 211 tessellatedList.clear(); 224 volumeMap.clear(); << 212 volumeMap.clear(); 225 std::string line; << 213 std::string line; 226 << 214 227 while(getline(GeomFile, line)) << 215 while (getline(GeomFile,line)) 228 { << 216 { 229 if(line[0] == 'f') << 217 if (line[0] == 'f') { TessellatedRead(line); } else 230 { << 218 if (line[0] == 'p') { FacetRead(line); } 231 TessellatedRead(line); << 219 } 232 } << 220 233 else if(line[0] == 'p') << 221 if (tessellatedList.size()>0) // Finish the last solid! 234 { << 222 { 235 FacetRead(line); << 223 tessellatedList.back()->SetSolidClosed(true); 236 } << 224 } 237 } << 238 << 239 if(tessellatedList.size() > 0) // Finish th << 240 { << 241 tessellatedList.back()->SetSolidClosed(tru << 242 } << 243 225 244 G4cout << "G4STRead: Reading '" << name << " << 226 G4cout << "G4STRead: Reading '" << name << "' done." << G4endl; 245 } 227 } 246 228 247 // ------------------------------------------- << 248 void G4STRead::ReadTree(const G4String& name) 229 void G4STRead::ReadTree(const G4String& name) 249 { 230 { 250 #ifdef G4VERBOSE << 231 G4cout << "G4STRead: Reading '" << name << "'..." << G4endl; 251 G4cout << "G4STRead: Reading '" << name << " << 232 252 #endif << 233 std::ifstream TreeFile(name); 253 std::ifstream TreeFile(name); << 234 254 << 235 if (!TreeFile) 255 if(!TreeFile) << 236 { 256 { << 237 G4String error_msg = "Cannot open file: " + name; 257 G4String error_msg = "Cannot open file: " << 238 G4Exception("G4STRead::ReadTree()", "ReadError", 258 G4Exception("G4STRead::ReadTree()", "ReadE << 239 FatalException, error_msg); 259 } << 240 } 260 << 241 261 std::string line; << 242 std::string line; 262 << 243 263 while(getline(TreeFile, line)) << 244 while (getline(TreeFile,line)) 264 { << 245 { 265 if(line[0] == 'g') << 246 if (line[0] == 'g') { PhysvolRead(line); } 266 { << 247 } 267 PhysvolRead(line); << 268 } << 269 } << 270 248 271 G4cout << "G4STRead: Reading '" << name << " << 249 G4cout << "G4STRead: Reading '" << name << "' done." << G4endl; 272 } 250 } 273 251 274 // ------------------------------------------- << 252 G4LogicalVolume* 275 G4LogicalVolume* G4STRead::Read(const G4String << 253 G4STRead::Read(const G4String& name, G4Material* mediumMaterial, 276 G4Material* me << 254 G4Material* solidMaterial) 277 G4Material* so << 278 { 255 { 279 if(mediumMaterial == nullptr) << 256 if (mediumMaterial == 0) 280 { << 257 { 281 G4Exception("G4STRead::Read()", "InvalidSe << 258 G4Exception("G4STRead::Read()", "InvalidSetup", FatalException, 282 "Pointer to medium material is << 259 "Pointer to medium material is not valid!"); 283 } << 260 } 284 if(solidMaterial == nullptr) << 261 if (solidMaterial == 0) 285 { << 262 { 286 G4Exception("G4STRead::Read()", "InvalidSe << 263 G4Exception("G4STRead::Read()", "InvalidSetup", FatalException, 287 "Pointer to solid material is << 264 "Pointer to solid material is not valid!"); 288 } << 265 } 289 << 266 290 solid_material = solidMaterial; << 267 solid_material = solidMaterial; 291 << 268 292 world_box = new G4Box("TessellatedWorldBox", << 269 world_box = new G4Box("TessellatedWorldBox",kInfinity,kInfinity,kInfinity); 293 // We don't know the extent of the world yet << 270 // We don't know the extent of the world yet! 294 world_volume = new G4LogicalVolume(world_box << 271 world_volume = new G4LogicalVolume(world_box, mediumMaterial, 295 "Tessella << 272 "TessellatedWorldLV", 0, 0, 0); 296 world_extent = G4ThreeVector(0, 0, 0); << 273 world_extent = G4ThreeVector(0,0,0); 297 << 274 298 ReadGeom(name + ".geom"); << 275 ReadGeom(name+".geom"); 299 ReadTree(name + ".tree"); << 276 ReadTree(name+".tree"); 300 << 277 301 // Now setting the world extent ... << 278 // Now setting the world extent ... 302 // << 279 // 303 if(world_box->GetXHalfLength() > world_exten << 280 if (world_box->GetXHalfLength() > world_extent.x()) 304 { << 281 { world_box->SetXHalfLength(world_extent.x()); } 305 world_box->SetXHalfLength(world_extent.x() << 282 if (world_box->GetYHalfLength() > world_extent.y()) 306 } << 283 { world_box->SetYHalfLength(world_extent.y()); } 307 if(world_box->GetYHalfLength() > world_exten << 284 if (world_box->GetZHalfLength() > world_extent.z()) 308 { << 285 { world_box->SetZHalfLength(world_extent.z()); } 309 world_box->SetYHalfLength(world_extent.y() << 310 } << 311 if(world_box->GetZHalfLength() > world_exten << 312 { << 313 world_box->SetZHalfLength(world_extent.z() << 314 } << 315 286 316 return world_volume; << 287 return world_volume; 317 } 288 } 318 289