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