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