]>
Commit | Line | Data |
---|---|---|
240601e9 | 1 | // $Id$ |
2 | // Category: geometry | |
3 | // | |
4 | // See the class description in the header file. | |
5 | ||
6 | #include "TG4XMLConvertor.h" | |
7 | #include "TG3Units.h" | |
8 | ||
9 | #include <G4LogicalVolume.hh> | |
10 | #include <G4Material.hh> | |
11 | #include <G4VSolid.hh> | |
12 | #include <G4Box.hh> | |
13 | #include <G4Tubs.hh> | |
14 | #include <G4Trd.hh> | |
15 | #include <globals.hh> | |
16 | ||
17 | #include <g4std/iostream> | |
18 | #include <g4std/iomanip> | |
19 | ||
20 | const G4int TG4XMLConvertor::fgkMaxVolumeNameLength = 10; | |
21 | const G4int TG4XMLConvertor::fgkMaxMaterialNameLength = 20; | |
22 | ||
23 | TG4XMLConvertor::TG4XMLConvertor(G4std::ofstream& outFile) | |
24 | : fOutFile(outFile), | |
3716fae8 | 25 | fBasicIndention(" "), |
26 | fIndention(fBasicIndention) | |
240601e9 | 27 | { |
28 | // | |
29 | } | |
30 | ||
31 | TG4XMLConvertor::~TG4XMLConvertor() { | |
32 | // | |
33 | } | |
34 | ||
35 | // private methods | |
36 | ||
37 | void TG4XMLConvertor::CutName(G4String& name) const | |
38 | { | |
39 | // Removes spaces after the name if present. | |
40 | // --- | |
41 | ||
42 | G4int i = name.length(); | |
43 | while (name(--i) == ' ') name = name(0,i); | |
44 | } | |
45 | ||
46 | void TG4XMLConvertor::CutName(G4String& name, G4int size) const | |
47 | { | |
48 | // Cuts name to given size. | |
49 | // --- | |
50 | ||
51 | if (name.length() > size) name = name(0, size); | |
52 | } | |
53 | ||
54 | void TG4XMLConvertor::PutName(G4String& element, G4String name, | |
55 | G4String templ) const | |
56 | { | |
57 | // Replaces given template in string element with a give name. | |
58 | // --- | |
59 | ||
60 | CutName(name); | |
61 | // make better | |
62 | if (templ == "#") | |
63 | CutName(name, fgkMaxVolumeNameLength); | |
64 | else if (templ == "!") | |
65 | CutName(name, fgkMaxMaterialNameLength); | |
66 | ||
67 | element.replace(element.find(templ), name.size(), name); | |
68 | element.replace(element.find(templ), 1, "\""); | |
69 | while (element.contains(templ)) element.replace(element.find(templ), 1 , " "); | |
70 | } | |
71 | ||
72 | void TG4XMLConvertor::WriteBox(const G4Box* box, G4String materialName) | |
73 | { | |
74 | // Writes G4box solid. | |
75 | // --- | |
76 | ||
77 | // get parameters | |
78 | G4String solidName = box->GetName(); | |
79 | G4double x = box->GetXHalfLength()/TG3Units::Length(); | |
80 | G4double y = box->GetYHalfLength()/TG3Units::Length(); | |
81 | G4double z = box->GetZHalfLength()/TG3Units::Length(); | |
82 | ||
83 | // compose element string template | |
84 | G4String element1 | |
85 | = "<box name=\"########### material=\"!!!!!!!!!!!!!!!!!!!!! X_Y_Z=\""; | |
86 | G4String element2 = "\" />"; | |
87 | ||
88 | // put solid and material names | |
89 | PutName(element1, solidName, "#"); | |
90 | PutName(element1, materialName, "!"); | |
91 | ||
92 | // write element | |
3716fae8 | 93 | fOutFile << fBasicIndention |
94 | << element1 | |
240601e9 | 95 | << G4std::setw(7) << G4std::setprecision(2) << x << " " |
96 | << G4std::setw(7) << G4std::setprecision(2) << y << " " | |
97 | << G4std::setw(7) << G4std::setprecision(2) << z | |
98 | << element2 | |
99 | << G4endl; | |
100 | } | |
101 | ||
102 | void TG4XMLConvertor::WriteTubs(const G4Tubs* tubs, G4String materialName) | |
103 | { | |
104 | // Writes G4tubs solid. | |
105 | // --- | |
106 | ||
107 | // get parameters | |
108 | G4String solidName = tubs->GetName(); | |
109 | G4double rmin = tubs->GetInnerRadius()/TG3Units::Length(); | |
110 | G4double rmax = tubs->GetOuterRadius()/TG3Units::Length(); | |
111 | G4double hz = tubs->GetZHalfLength()/TG3Units::Length(); | |
112 | G4double sphi = tubs->GetStartPhiAngle()/TG3Units::Angle(); | |
113 | G4double dphi = tubs->GetDeltaPhiAngle()/TG3Units::Angle(); | |
114 | ||
115 | // compose element string template | |
116 | G4String element1 | |
117 | = "<tubs name=\"########### material=\"!!!!!!!!!!!!!!!!!!!!! Rio_Z=\""; | |
118 | G4String element2 = "\" profile=\""; | |
119 | G4String element3 = "\" />"; | |
120 | ||
121 | // put solid and material names | |
122 | PutName(element1, solidName, "#"); | |
123 | PutName(element1, materialName, "!"); | |
124 | ||
125 | // write element | |
3716fae8 | 126 | fOutFile << fBasicIndention |
127 | << element1 | |
240601e9 | 128 | << G4std::setw(7) << G4std::setprecision(2) << rmin << " " |
129 | << G4std::setw(7) << G4std::setprecision(2) << rmax << " " | |
130 | << G4std::setw(7) << G4std::setprecision(2) << hz | |
131 | << element2 | |
132 | << G4std::setw(7) << G4std::setprecision(2) << sphi << " " | |
133 | << G4std::setw(7) << G4std::setprecision(2) << dphi | |
134 | << element3 | |
135 | << G4endl; | |
136 | } | |
137 | ||
138 | ||
139 | void TG4XMLConvertor::WriteTrd(const G4Trd* trd, G4String materialName) | |
140 | { | |
141 | // Writes G4Trd solid. | |
142 | // --- | |
143 | ||
144 | // get parameters | |
145 | G4String solidName = trd->GetName(); | |
146 | G4double x1 = trd->GetXHalfLength1()/TG3Units::Length(); | |
147 | G4double x2 = trd->GetXHalfLength2()/TG3Units::Length(); | |
148 | G4double y1 = trd->GetYHalfLength1()/TG3Units::Length(); | |
149 | G4double y2 = trd->GetYHalfLength2()/TG3Units::Length(); | |
150 | G4double hz = trd->GetZHalfLength()/TG3Units::Length(); | |
151 | ||
152 | // compose element string template | |
153 | G4String element1 | |
154 | = "<trd name=\"########### material=\"!!!!!!!!!!!!!!!!!!!!! Xmp_Ymp_Z=\""; | |
155 | G4String element2 = "\" />"; | |
156 | ||
157 | // put solid and material names | |
158 | // put solid and material names | |
159 | PutName(element1, solidName, "#"); | |
160 | PutName(element1, materialName, "!"); | |
161 | ||
162 | // write element | |
3716fae8 | 163 | fOutFile << fBasicIndention |
164 | << element1 | |
240601e9 | 165 | << G4std::setw(7) << G4std::setprecision(2) << x1 << " " |
166 | << G4std::setw(7) << G4std::setprecision(2) << x2 << " " | |
167 | << G4std::setw(7) << G4std::setprecision(2) << y1 << " " | |
168 | << G4std::setw(7) << G4std::setprecision(2) << y2 << " " | |
169 | << G4std::setw(7) << G4std::setprecision(2) << hz | |
170 | << element2 | |
171 | << G4endl; | |
172 | } | |
173 | ||
174 | ||
175 | // public methods | |
176 | ||
3716fae8 | 177 | void TG4XMLConvertor::OpenMaterials(const G4String& version, |
178 | const G4String& date, const G4String& author, | |
179 | const G4String dtdVersion) | |
180 | { | |
181 | // Writes section opening. | |
182 | // --- | |
183 | ||
184 | G4String element1 = "<materials version = \""; | |
185 | G4String element2 = " date = \""; | |
186 | G4String element3 = " author = \""; | |
187 | G4String element4 = " DTD_version=\""; | |
188 | G4String element5 = " >"; | |
189 | G4String quota = "\""; | |
190 | ||
191 | // write element | |
192 | fOutFile << element1 << version << quota << G4endl | |
193 | << element2 << date << quota << G4endl | |
194 | << element3 << author << quota << G4endl | |
195 | << element4 << dtdVersion << quota | |
196 | << element5 << G4endl; | |
197 | } | |
198 | ||
240601e9 | 199 | void TG4XMLConvertor::OpenSection(const G4String& name, const G4String& version, |
200 | const G4String& date, const G4String& author, | |
201 | const G4String& topVolume) | |
202 | { | |
203 | // Writes section opening. | |
204 | // --- | |
205 | ||
206 | G4String element1 = "<section name = \""; | |
207 | G4String element2 = " version = \""; | |
208 | G4String element3 = " date = \""; | |
209 | G4String element4 = " author = \""; | |
210 | G4String element5 = " topVolume = \""; | |
211 | G4String element6 = " >"; | |
212 | G4String quota = "\""; | |
213 | ||
214 | // write element | |
215 | fOutFile << element1 << name << quota << G4endl | |
216 | << element2 << version << quota << G4endl | |
217 | << element3 << date << quota << G4endl | |
218 | << element4 << author << quota << G4endl | |
219 | << element5 << topVolume << quota | |
220 | << element6 << G4endl; | |
221 | } | |
222 | ||
223 | void TG4XMLConvertor::OpenComposition(const G4String& name) | |
224 | { | |
225 | // Writes composition opening. | |
226 | // --- | |
227 | ||
228 | G4String element = "<composition name=\""; | |
229 | element.append(name); | |
230 | element.append(">"); | |
231 | ||
232 | // write element | |
233 | fOutFile << fIndention | |
234 | << element | |
235 | << G4endl; | |
236 | ||
237 | // increase indention | |
3716fae8 | 238 | IncreaseIndention(); |
239 | } | |
240 | ||
241 | void TG4XMLConvertor::CloseMaterials() | |
242 | { | |
243 | // Writes materials closing. | |
244 | // --- | |
245 | ||
246 | // define element | |
247 | G4String element = "</materials>"; | |
248 | ||
249 | // write element | |
250 | fOutFile << element | |
251 | << G4endl; | |
240601e9 | 252 | } |
253 | ||
254 | void TG4XMLConvertor::CloseSection() | |
255 | { | |
256 | // Writes section closing. | |
257 | // --- | |
258 | ||
259 | // define element | |
260 | G4String element = "</section>"; | |
261 | ||
262 | // write element | |
263 | fOutFile << element | |
264 | << G4endl; | |
265 | } | |
266 | ||
267 | void TG4XMLConvertor::CloseComposition() | |
268 | { | |
269 | // Writes composition closing. | |
270 | // --- | |
271 | ||
272 | // decrease indention | |
3716fae8 | 273 | DecreaseIndention(); |
240601e9 | 274 | |
275 | // define element | |
276 | G4String element = "</composition>"; | |
277 | ||
278 | // write element | |
279 | fOutFile << fIndention | |
280 | << element | |
281 | << G4endl; | |
282 | } | |
283 | ||
284 | void TG4XMLConvertor::WriteMaterial(const G4Material* material) | |
285 | { | |
286 | // Writes G4Material. | |
287 | // Not yet implemented, only XML comment element is written. | |
288 | // --- | |
289 | ||
290 | G4String name = material->GetName(); | |
291 | CutName(name); | |
292 | ||
293 | // return if material of this name was already written | |
294 | if (fMaterialNames.find(name) != fMaterialNames.end()) return; | |
295 | ||
296 | fMaterialNames.insert(fMaterialNames.begin(), name); | |
297 | ||
298 | // only comment line | |
299 | G4String element1 = "<!-- material = \""; | |
300 | G4String element2 = "\" -->"; | |
301 | ||
302 | // write element | |
3716fae8 | 303 | fOutFile << fBasicIndention |
304 | << element1 << name | |
240601e9 | 305 | << element2 |
306 | << G4endl; | |
307 | } | |
308 | ||
309 | void TG4XMLConvertor::WriteSolid(const G4VSolid* solid, G4String materialName) | |
310 | { | |
311 | // Finds G4Solid concrete type and calls writing function. | |
312 | // For not yet implemented solids, only XML comment element is written. | |
313 | // --- | |
314 | ||
315 | G4String name = solid->GetName(); | |
316 | ||
317 | // return if solid of this name was already written | |
318 | if (fSolidNames.find(name) != fSolidNames.end()) return; | |
319 | ||
320 | fSolidNames.insert(fSolidNames.begin(), name); | |
321 | ||
322 | // find concrete solid type and write it | |
323 | ||
324 | const G4Box* box = dynamic_cast<const G4Box*>(solid); | |
325 | if (box) { | |
326 | WriteBox(box, materialName); | |
327 | return; | |
328 | } | |
329 | ||
330 | const G4Tubs* tubs = dynamic_cast<const G4Tubs*>(solid); | |
331 | if (tubs) { | |
332 | WriteTubs(tubs, materialName); | |
333 | return; | |
334 | } | |
335 | ||
336 | const G4Trd* trd = dynamic_cast<const G4Trd*>(solid); | |
337 | if (trd) { | |
338 | WriteTrd(trd, materialName); | |
339 | return; | |
340 | } | |
341 | ||
342 | // write comment line in case of unsupported | |
343 | // shape | |
344 | ||
345 | // only comment line | |
346 | G4String element1 = "<!-- unsupported shape name= \""; | |
347 | G4String element2 = "\" -->"; | |
348 | ||
349 | // write element | |
3716fae8 | 350 | fOutFile << fBasicIndention |
351 | << element1 << name | |
240601e9 | 352 | << element2 |
353 | << G4endl; | |
354 | } | |
355 | ||
356 | void TG4XMLConvertor::WriteRotation(const G4RotationMatrix* rotation) | |
357 | { | |
358 | // Writes G4RotationMatrix. | |
359 | // Not yet implemented, only XML comment element is written. | |
360 | // --- | |
361 | ||
3716fae8 | 362 | // return if this rotation was already written |
363 | G4int nofRotations = fRotations.size(); | |
364 | if (nofRotations>0) | |
365 | for (G4int i=0; i<nofRotations; i++) | |
366 | if (fRotations[i] == rotation) return; | |
367 | ||
368 | fRotations.push_back(rotation); | |
369 | ||
370 | // get parameters | |
371 | G4double xx = rotation->xx(); | |
372 | G4double xy = rotation->xy(); | |
373 | G4double xz = rotation->xz(); | |
374 | G4double yx = rotation->yx(); | |
375 | G4double yy = rotation->yy(); | |
376 | G4double yz = rotation->yz(); | |
377 | G4double zx = rotation->zx(); | |
378 | G4double zy = rotation->zy(); | |
379 | G4double zz = rotation->zz(); | |
380 | G4String id = "RM"; | |
381 | TG4Globals::AppendNumberToString(id, nofRotations); | |
382 | ||
383 | // compose element string template | |
384 | G4String quota = "\"\n"; | |
385 | G4String element1 = "<rot_matrix id=\"####### XX_XY_XZ=\""; | |
386 | G4String element2 = " YX_YY_YZ=\""; | |
387 | G4String element3 = " ZX_ZY_ZZ=\""; | |
388 | G4String element4 = "\" />"; | |
240601e9 | 389 | |
3716fae8 | 390 | // put identifier |
391 | PutName(element1, id, "#"); | |
392 | ||
240601e9 | 393 | // write element |
3716fae8 | 394 | fOutFile << fBasicIndention |
395 | << element1 | |
396 | << G4std::setw(8) << G4std::setprecision(5) << xx << " " | |
397 | << G4std::setw(8) << G4std::setprecision(5) << xy << " " | |
398 | << G4std::setw(8) << G4std::setprecision(5) << xz << quota | |
399 | << fBasicIndention | |
400 | << element2 | |
401 | << G4std::setw(8) << G4std::setprecision(5) << yx << " " | |
402 | << G4std::setw(8) << G4std::setprecision(5) << yy << " " | |
403 | << G4std::setw(8) << G4std::setprecision(5) << yz << quota | |
404 | << fBasicIndention | |
405 | << element3 | |
406 | << G4std::setw(8) << G4std::setprecision(5) << zx << " " | |
407 | << G4std::setw(8) << G4std::setprecision(5) << zy << " " | |
408 | << G4std::setw(8) << G4std::setprecision(5) << zz | |
409 | << element4 | |
240601e9 | 410 | << G4endl; |
411 | } | |
412 | ||
413 | void TG4XMLConvertor::WritePosition(G4String solidName, G4ThreeVector position) | |
414 | { | |
415 | // Writes position without rotation with a given solid name. | |
416 | // --- | |
417 | ||
418 | // get parameters | |
419 | G4double x = position.x()/TG3Units::Length(); | |
420 | G4double y = position.y()/TG3Units::Length(); | |
421 | G4double z = position.z()/TG3Units::Length(); | |
422 | ||
423 | // compose element string template | |
3716fae8 | 424 | G4String element1 = "<posXYZ volume=\"########### X_Y_Z=\""; |
240601e9 | 425 | G4String element2 = "\" />"; |
426 | ||
427 | // put solid name | |
428 | PutName(element1, solidName, "#"); | |
429 | ||
430 | // write element | |
431 | fOutFile << fIndention | |
432 | << element1 | |
3716fae8 | 433 | << G4std::setw(8) << G4std::setprecision(2) << x << " " |
434 | << G4std::setw(8) << G4std::setprecision(2) << y << " " | |
435 | << G4std::setw(8) << G4std::setprecision(2) << z | |
240601e9 | 436 | << element2 |
437 | << G4endl; | |
438 | } | |
439 | ||
440 | void TG4XMLConvertor::WritePositionWithRotation( | |
441 | G4String solidName, G4ThreeVector position, | |
442 | const G4RotationMatrix* rotation) | |
443 | { | |
444 | // Writes position with rotation with a given solid name. | |
445 | // Not yet implemented, only XML comment element is written. | |
446 | // --- | |
447 | ||
3716fae8 | 448 | // get parameters |
449 | G4double x = position.x()/TG3Units::Length(); | |
450 | G4double y = position.y()/TG3Units::Length(); | |
451 | G4double z = position.z()/TG3Units::Length(); | |
452 | ||
453 | // find rotation | |
454 | G4int i=0; | |
455 | while (i<fRotations.size() && fRotations[i] != rotation) i++; | |
456 | if (i==fRotations.size()) { | |
457 | G4String text = "TG4XMLConvertor::WritePositionWithRotation: "; | |
458 | text = text + " Unknown rotation - fatal error."; | |
459 | TG4Globals::Exception(text); | |
460 | } | |
461 | G4String id = "RM"; | |
462 | TG4Globals::AppendNumberToString(id, i); | |
463 | ||
464 | // compose element string template | |
465 | G4String element1 = "<posXYZRot volume=\"########### X_Y_Z=\""; | |
466 | G4String element2 = "\" rot=\""; | |
467 | G4String element3 = "\" />"; | |
468 | ||
469 | // put solid name | |
470 | PutName(element1, solidName, "#"); | |
240601e9 | 471 | |
472 | // write element | |
473 | fOutFile << fIndention | |
3716fae8 | 474 | << element1 |
475 | << G4std::setw(8) << G4std::setprecision(2) << x << " " | |
476 | << G4std::setw(8) << G4std::setprecision(2) << y << " " | |
477 | << G4std::setw(8) << G4std::setprecision(2) << z | |
478 | << element2 | |
479 | << id | |
480 | << element3 | |
481 | << G4endl; | |
240601e9 | 482 | } |
483 | ||
484 | void TG4XMLConvertor::WriteEmptyLine() | |
485 | { | |
486 | // Writes empty line. | |
487 | // --- | |
488 | ||
489 | fOutFile << G4endl; | |
490 | } | |
491 | ||
3716fae8 | 492 | void TG4XMLConvertor::IncreaseIndention() |
493 | { | |
494 | // increase indention | |
495 | fIndention.append(fBasicIndention); | |
496 | } | |
240601e9 | 497 | |
3716fae8 | 498 | void TG4XMLConvertor::DecreaseIndention() |
499 | { | |
500 | // decrease indention | |
501 | fIndention.replace(fIndention.find(fBasicIndention), 3 , ""); | |
502 | } |