Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4STRead.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26// G4STRead implementation
27//
28// Author: Zoltan Torzsok, November 2007
29// --------------------------------------------------------------------
30
31#include <fstream>
32
33#include "G4STRead.hh"
34
35#include "G4Material.hh"
36#include "G4Box.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// --------------------------------------------------------------------
46void G4STRead::TessellatedRead(const std::string& line)
47{
48 if(tessellatedList.size() > 0)
49 {
50 tessellatedList.back()->SetSolidClosed(true);
51 // Finish the previous solid at first!
52 }
53
54 std::istringstream stream(line.substr(2));
55
57 stream >> name;
58
59 G4TessellatedSolid* tessellated = new G4TessellatedSolid(name);
60 volumeMap[tessellated] =
61 new G4LogicalVolume(tessellated, solid_material, name + "_LV", 0, 0, 0);
62 tessellatedList.push_back(tessellated);
63
64#ifdef G4VERBOSE
65 G4cout << "G4STRead: Reading solid: " << name << G4endl;
66#endif
67}
68
69// --------------------------------------------------------------------
70void G4STRead::FacetRead(const std::string& line)
71{
72 if(tessellatedList.size() == 0)
73 {
74 G4Exception("G4STRead::FacetRead()", "ReadError", FatalException,
75 "A solid must be defined before defining a facet!");
76 }
77
78 if(line[2] == '3') // Triangular facet
79 {
80 G4double x1, y1, z1;
81 G4double x2, y2, z2;
82 G4double x3, y3, z3;
83
84 std::istringstream stream(line.substr(4));
85 stream >> x1 >> y1 >> z1 >> x2 >> y2 >> z2 >> x3 >> y3 >> z3;
86 tessellatedList.back()->AddFacet(new G4TriangularFacet(
87 G4ThreeVector(x1, y1, z1), G4ThreeVector(x2, y2, z2),
88 G4ThreeVector(x3, y3, z3), ABSOLUTE));
89 }
90 else if(line[2] == '4') // Quadrangular facet
91 {
92 G4double x1, y1, z1;
93 G4double x2, y2, z2;
94 G4double x3, y3, z3;
95 G4double x4, y4, z4;
96
97 std::istringstream stream(line.substr(4));
98 stream >> x1 >> y1 >> z1 >> x2 >> y2 >> z2 >> x3 >> y3 >> z3 >> x4 >> y4 >>
99 z4;
100 tessellatedList.back()->AddFacet(new G4QuadrangularFacet(
101 G4ThreeVector(x1, y1, z1), G4ThreeVector(x2, y2, z2),
102 G4ThreeVector(x3, y3, z3), G4ThreeVector(x4, y4, z4), ABSOLUTE));
103 }
104 else
105 {
106 G4Exception("G4STRead::FacetRead()", "ReadError", FatalException,
107 "Number of vertices per facet should be either 3 or 4!");
108 }
109}
110
111// --------------------------------------------------------------------
112void G4STRead::PhysvolRead(const std::string& line)
113{
114 G4int level;
116 G4double r1, r2, r3;
117 G4double r4, r5, r6;
118 G4double r7, r8, r9;
119 G4double pX, pY, pZ;
120 G4double n1, n2, n3, n4, n5;
121
122 std::istringstream stream(line.substr(2));
123 stream >> level >> name >> r1 >> r2 >> r3 >> n1 >> r4 >> r5 >> r6 >> n2 >>
124 r7 >> r8 >> r9 >> n3 >> pX >> pY >> pZ >> n4 >> n5;
125 std::string::size_type idx = name.rfind("_");
126 if(idx != std::string::npos)
127 {
128 name.resize(idx);
129 }
130 else
131 {
132 G4Exception("G4STRead::PhysvolRead()", "ReadError", FatalException,
133 "Invalid input stream!");
134 return;
135 }
136
137 G4cout << "G4STRead: Placing tessellated solid: " << name << G4endl;
138
139 G4TessellatedSolid* tessellated = nullptr;
140
141 for(std::size_t i = 0; i < tessellatedList.size(); ++i)
142 { // Find the volume for this physvol!
143 if(tessellatedList[i]->GetName() == G4String(name))
144 {
145 tessellated = tessellatedList[i];
146 break;
147 }
148 }
149
150 if(tessellated == nullptr)
151 {
152 G4String error_msg = "Referenced solid '" + name + "' not found!";
153 G4Exception("G4STRead::PhysvolRead()", "ReadError", FatalException,
154 error_msg);
155 }
156 if(volumeMap.find(tessellated) == volumeMap.cend())
157 {
158 G4String error_msg = "Referenced solid '" + name +
159 "' is not associated with a logical volume!";
160 G4Exception("G4STRead::PhysvolRead()", "InvalidSetup", FatalException,
161 error_msg);
162 }
163 const G4RotationMatrix rot(G4ThreeVector(r1, r2, r3),
164 G4ThreeVector(r4, r5, r6),
165 G4ThreeVector(r7, r8, r9));
166 const G4ThreeVector pos(pX, pY, pZ);
167
168 new G4PVPlacement(G4Transform3D(rot.inverse(), pos), volumeMap[tessellated],
169 name + "_PV", world_volume, 0, 0);
170 // Note: INVERSE of rotation is needed!!!
171
172 G4double minx, miny, minz;
173 G4double maxx, maxy, maxz;
174 const G4VoxelLimits limits;
175
176 tessellated->CalculateExtent(kXAxis, limits, G4AffineTransform(rot, pos),
177 minx, maxx);
178 tessellated->CalculateExtent(kYAxis, limits, G4AffineTransform(rot, pos),
179 miny, maxy);
180 tessellated->CalculateExtent(kZAxis, limits, G4AffineTransform(rot, pos),
181 minz, maxz);
182
183 if(world_extent.x() < std::fabs(minx))
184 {
185 world_extent.setX(std::fabs(minx));
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}
208
209// --------------------------------------------------------------------
210void G4STRead::ReadGeom(const G4String& name)
211{
212#ifdef G4VERBOSE
213 G4cout << "G4STRead: Reading '" << name << "'..." << G4endl;
214#endif
215 std::ifstream GeomFile(name);
216
217 if(!GeomFile)
218 {
219 G4String error_msg = "Cannot open file: " + name;
220 G4Exception("G4STRead::ReadGeom()", "ReadError", FatalException, error_msg);
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 the last solid!
240 {
241 tessellatedList.back()->SetSolidClosed(true);
242 }
243
244 G4cout << "G4STRead: Reading '" << name << "' done." << G4endl;
245}
246
247// --------------------------------------------------------------------
248void G4STRead::ReadTree(const G4String& name)
249{
250#ifdef G4VERBOSE
251 G4cout << "G4STRead: Reading '" << name << "'..." << G4endl;
252#endif
253 std::ifstream TreeFile(name);
254
255 if(!TreeFile)
256 {
257 G4String error_msg = "Cannot open file: " + name;
258 G4Exception("G4STRead::ReadTree()", "ReadError", FatalException, error_msg);
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
271 G4cout << "G4STRead: Reading '" << name << "' done." << G4endl;
272}
273
274// --------------------------------------------------------------------
276 G4Material* mediumMaterial,
277 G4Material* solidMaterial)
278{
279 if(mediumMaterial == nullptr)
280 {
281 G4Exception("G4STRead::Read()", "InvalidSetup", FatalException,
282 "Pointer to medium material is not valid!");
283 }
284 if(solidMaterial == nullptr)
285 {
286 G4Exception("G4STRead::Read()", "InvalidSetup", FatalException,
287 "Pointer to solid material is not valid!");
288 }
289
290 solid_material = solidMaterial;
291
292 world_box = new G4Box("TessellatedWorldBox", kInfinity, kInfinity, kInfinity);
293 // We don't know the extent of the world yet!
294 world_volume = new G4LogicalVolume(world_box, mediumMaterial,
295 "TessellatedWorldLV", 0, 0, 0);
296 world_extent = G4ThreeVector(0, 0, 0);
297
298 ReadGeom(name + ".geom");
299 ReadTree(name + ".tree");
300
301 // Now setting the world extent ...
302 //
303 if(world_box->GetXHalfLength() > world_extent.x())
304 {
305 world_box->SetXHalfLength(world_extent.x());
306 }
307 if(world_box->GetYHalfLength() > world_extent.y())
308 {
309 world_box->SetYHalfLength(world_extent.y());
310 }
311 if(world_box->GetZHalfLength() > world_extent.z())
312 {
313 world_box->SetZHalfLength(world_extent.z());
314 }
315
316 return world_volume;
317}
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:59
CLHEP::Hep3Vector G4ThreeVector
HepGeom::Transform3D G4Transform3D
double G4double
Definition: G4Types.hh:83
int G4int
Definition: G4Types.hh:85
@ ABSOLUTE
Definition: G4VFacet.hh:48
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
double z() const
double x() const
void setY(double)
double y() const
void setZ(double)
void setX(double)
Definition: G4Box.hh:56
G4double GetYHalfLength() const
G4double GetZHalfLength() const
void SetZHalfLength(G4double dz)
Definition: G4Box.cc:172
G4double GetXHalfLength() const
void SetYHalfLength(G4double dy)
Definition: G4Box.cc:149
void SetXHalfLength(G4double dx)
Definition: G4Box.cc:125
G4LogicalVolume * Read(const G4String &, G4Material *mediumMaterial, G4Material *solidMaterial)
Definition: G4STRead.cc:275
virtual G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const
@ kYAxis
Definition: geomdefs.hh:56
@ kXAxis
Definition: geomdefs.hh:55
@ kZAxis
Definition: geomdefs.hh:57
const char * name(G4int ptype)