00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <fstream>
00035
00036 #include "G4STRead.hh"
00037
00038 #include "G4Material.hh"
00039 #include "G4Box.hh"
00040 #include "G4QuadrangularFacet.hh"
00041 #include "G4TriangularFacet.hh"
00042 #include "G4TessellatedSolid.hh"
00043 #include "G4LogicalVolume.hh"
00044 #include "G4PVPlacement.hh"
00045 #include "G4AffineTransform.hh"
00046 #include "G4VoxelLimits.hh"
00047
00048 void G4STRead::TessellatedRead(const std::string& line)
00049 {
00050 if (tessellatedList.size()>0)
00051 {
00052 tessellatedList.back()->SetSolidClosed(true);
00053
00054 }
00055
00056 std::istringstream stream(line.substr(2));
00057
00058 G4String name;
00059 stream >> name;
00060
00061 G4TessellatedSolid* tessellated = new G4TessellatedSolid(name);
00062 volumeMap[tessellated] =
00063 new G4LogicalVolume(tessellated, solid_material, name+"_LV" , 0, 0, 0);
00064 tessellatedList.push_back(tessellated);
00065
00066 G4cout << "G4STRead: Reading solid: " << name << G4endl;
00067 }
00068
00069 void G4STRead::FacetRead(const std::string& line)
00070 {
00071 if (tessellatedList.size()==0)
00072 {
00073 G4Exception("G4STRead::FacetRead()", "ReadError", FatalException,
00074 "A solid must be defined before defining a facet!");
00075 }
00076
00077 if (line[2]=='3')
00078 {
00079 G4double x1,y1,z1;
00080 G4double x2,y2,z2;
00081 G4double x3,y3,z3;
00082
00083 std::istringstream stream(line.substr(4));
00084 stream >> x1 >> y1 >> z1 >> x2 >> y2 >> z2 >> x3 >> y3 >> z3;
00085 tessellatedList.back()->
00086 AddFacet(new G4TriangularFacet(G4ThreeVector(x1,y1,z1),
00087 G4ThreeVector(x2,y2,z2),
00088 G4ThreeVector(x3,y3,z3), ABSOLUTE));
00089 }
00090 else if (line[2]=='4')
00091 {
00092 G4double x1,y1,z1;
00093 G4double x2,y2,z2;
00094 G4double x3,y3,z3;
00095 G4double x4,y4,z4;
00096
00097 std::istringstream stream(line.substr(4));
00098 stream >> x1 >> y1 >> z1 >> x2 >> y2 >> z2
00099 >> x3 >> y3 >> z3 >> x4 >> y4 >> z4;
00100 tessellatedList.back()->
00101 AddFacet(new G4QuadrangularFacet(G4ThreeVector(x1,y1,z1),
00102 G4ThreeVector(x2,y2,z2),
00103 G4ThreeVector(x3,y3,z3),
00104 G4ThreeVector(x4,y4,z4), ABSOLUTE));
00105 }
00106 else
00107 {
00108 G4Exception("G4STRead::FacetRead()", "ReadError", FatalException,
00109 "Number of vertices per facet should be either 3 or 4!");
00110 }
00111 }
00112
00113 void G4STRead::PhysvolRead(const std::string& line)
00114 {
00115 G4int level;
00116 G4String name;
00117 G4double r1,r2,r3;
00118 G4double r4,r5,r6;
00119 G4double r7,r8,r9;
00120 G4double pX,pY,pZ;
00121 G4double n1,n2,n3,n4,n5;
00122
00123 std::istringstream stream(line.substr(2));
00124 stream >> level >> name >> r1 >> r2 >> r3 >> n1 >> r4 >> r5 >> r6
00125 >> n2 >> r7 >> r8 >> r9 >> n3 >> pX >> pY >> pZ >> n4 >> n5;
00126 std::string::size_type idx = name.rfind("_");
00127 if (idx!=std::string::npos)
00128 {
00129 name.resize(idx);
00130 }
00131 else
00132 {
00133 G4Exception("G4STRead::PhysvolRead()", "ReadError",
00134 FatalException, "Invalid input stream!");
00135 return;
00136 }
00137
00138 G4cout << "G4STRead: Placing tessellated solid: " << name << G4endl;
00139
00140 G4TessellatedSolid* tessellated = 0;
00141
00142 for (size_t i=0; i<tessellatedList.size(); i++)
00143 {
00144 if (tessellatedList[i]->GetName() == G4String(name))
00145 {
00146 tessellated = tessellatedList[i];
00147 break;
00148 }
00149 }
00150
00151 if (tessellated == 0)
00152 {
00153 G4String error_msg = "Referenced solid '" + name + "' not found!";
00154 G4Exception("G4STRead::PhysvolRead()", "ReadError",
00155 FatalException, error_msg);
00156 }
00157 if (volumeMap.find(tessellated) == volumeMap.end())
00158 {
00159 G4String error_msg = "Referenced solid '" + name
00160 + "' is not associated with a logical volume!";
00161 G4Exception("G4STRead::PhysvolRead()", "InvalidSetup",
00162 FatalException, error_msg);
00163 }
00164 const G4RotationMatrix rot(G4ThreeVector(r1,r2,r3),
00165 G4ThreeVector(r4,r5,r6),
00166 G4ThreeVector(r7,r8,r9));
00167 const G4ThreeVector pos(pX,pY,pZ);
00168
00169 new G4PVPlacement(G4Transform3D(rot.inverse(),pos),
00170 volumeMap[tessellated], name+"_PV", world_volume, 0, 0);
00171
00172
00173 G4double minx,miny,minz;
00174 G4double maxx,maxy,maxz;
00175 const G4VoxelLimits limits;
00176
00177 tessellated->CalculateExtent(kXAxis,limits,
00178 G4AffineTransform(rot,pos),minx,maxx);
00179 tessellated->CalculateExtent(kYAxis,limits,
00180 G4AffineTransform(rot,pos),miny,maxy);
00181 tessellated->CalculateExtent(kZAxis,limits,
00182 G4AffineTransform(rot,pos),minz,maxz);
00183
00184 if (world_extent.x() < std::fabs(minx))
00185 { world_extent.setX(std::fabs(minx)); }
00186 if (world_extent.y() < std::fabs(miny))
00187 { world_extent.setY(std::fabs(miny)); }
00188 if (world_extent.z() < std::fabs(minz))
00189 { world_extent.setZ(std::fabs(minz)); }
00190 if (world_extent.x() < std::fabs(maxx))
00191 { world_extent.setX(std::fabs(maxx)); }
00192 if (world_extent.y() < std::fabs(maxy))
00193 { world_extent.setY(std::fabs(maxy)); }
00194 if (world_extent.z() < std::fabs(maxz))
00195 { world_extent.setZ(std::fabs(maxz)); }
00196 }
00197
00198 void G4STRead::ReadGeom(const G4String& name)
00199 {
00200 G4cout << "G4STRead: Reading '" << name << "'..." << G4endl;
00201
00202 std::ifstream GeomFile(name);
00203
00204 if (!GeomFile)
00205 {
00206 G4String error_msg = "Cannot open file: " + name;
00207 G4Exception("G4STRead::ReadGeom()", "ReadError",
00208 FatalException, error_msg);
00209 }
00210
00211 tessellatedList.clear();
00212 volumeMap.clear();
00213 std::string line;
00214
00215 while (getline(GeomFile,line))
00216 {
00217 if (line[0] == 'f') { TessellatedRead(line); } else
00218 if (line[0] == 'p') { FacetRead(line); }
00219 }
00220
00221 if (tessellatedList.size()>0)
00222 {
00223 tessellatedList.back()->SetSolidClosed(true);
00224 }
00225
00226 G4cout << "G4STRead: Reading '" << name << "' done." << G4endl;
00227 }
00228
00229 void G4STRead::ReadTree(const G4String& name)
00230 {
00231 G4cout << "G4STRead: Reading '" << name << "'..." << G4endl;
00232
00233 std::ifstream TreeFile(name);
00234
00235 if (!TreeFile)
00236 {
00237 G4String error_msg = "Cannot open file: " + name;
00238 G4Exception("G4STRead::ReadTree()", "ReadError",
00239 FatalException, error_msg);
00240 }
00241
00242 std::string line;
00243
00244 while (getline(TreeFile,line))
00245 {
00246 if (line[0] == 'g') { PhysvolRead(line); }
00247 }
00248
00249 G4cout << "G4STRead: Reading '" << name << "' done." << G4endl;
00250 }
00251
00252 G4LogicalVolume*
00253 G4STRead::Read(const G4String& name, G4Material* mediumMaterial,
00254 G4Material* solidMaterial)
00255 {
00256 if (mediumMaterial == 0)
00257 {
00258 G4Exception("G4STRead::Read()", "InvalidSetup", FatalException,
00259 "Pointer to medium material is not valid!");
00260 }
00261 if (solidMaterial == 0)
00262 {
00263 G4Exception("G4STRead::Read()", "InvalidSetup", FatalException,
00264 "Pointer to solid material is not valid!");
00265 }
00266
00267 solid_material = solidMaterial;
00268
00269 world_box = new G4Box("TessellatedWorldBox",kInfinity,kInfinity,kInfinity);
00270
00271 world_volume = new G4LogicalVolume(world_box, mediumMaterial,
00272 "TessellatedWorldLV", 0, 0, 0);
00273 world_extent = G4ThreeVector(0,0,0);
00274
00275 ReadGeom(name+".geom");
00276 ReadTree(name+".tree");
00277
00278
00279
00280 if (world_box->GetXHalfLength() > world_extent.x())
00281 { world_box->SetXHalfLength(world_extent.x()); }
00282 if (world_box->GetYHalfLength() > world_extent.y())
00283 { world_box->SetYHalfLength(world_extent.y()); }
00284 if (world_box->GetZHalfLength() > world_extent.z())
00285 { world_box->SetZHalfLength(world_extent.z()); }
00286
00287 return world_volume;
00288 }