1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | #define APP_NAME"hdds-root" "hdds-root" |
19 | |
20 | #include <xercesc/util/PlatformUtils.hpp> |
21 | #include <xercesc/util/XMLString.hpp> |
22 | #include <xercesc/util/XMLStringTokenizer.hpp> |
23 | #include <xercesc/sax/SAXParseException.hpp> |
24 | #include <xercesc/parsers/XercesDOMParser.hpp> |
25 | #include <xercesc/framework/LocalFileFormatTarget.hpp> |
26 | #include <xercesc/dom/DOM.hpp> |
27 | #include <xercesc/util/XercesDefs.hpp> |
28 | #include <xercesc/sax/ErrorHandler.hpp> |
29 | |
30 | using namespace xercesc; |
31 | |
32 | #include "XString.hpp" |
33 | #include "XParsers.hpp" |
34 | #include "hddsCommon.hpp" |
35 | |
36 | #include <assert.h> |
37 | #include <stdlib.h> |
38 | #include <ctype.h> |
39 | #include <stdio.h> |
40 | #include <math.h> |
41 | |
42 | #include <iostream> |
43 | #include <fstream> |
44 | #include <sstream> |
45 | #include <string> |
46 | #include <iomanip> |
47 | #include <vector> |
48 | #include <list> |
49 | |
50 | #define X(str)XString(str).unicode_str() XString(str).unicode_str() |
51 | #define S(str)str.c_str() str.c_str() |
52 | |
53 | int first_volume_placement = 0; |
54 | |
55 | void usage() |
56 | { |
57 | std::cerr |
58 | << "Usage: " << APP_NAME"hdds-root" << " [-v] {HDDS file}" |
59 | << std::endl << "Options:" << std::endl |
60 | << " -v validate only" << std::endl; |
61 | } |
62 | |
63 | class RootMacroWriter : public CodeWriter |
64 | { |
65 | public: |
66 | RootMacroWriter() {}; |
67 | void createHeader(); |
68 | void createTrailer(); |
69 | int createMaterial(DOMElement* el); |
70 | int createSolid(DOMElement* el, |
71 | Refsys& ref); |
72 | int createRotation(Refsys& ref); |
73 | int createVolume(DOMElement* el, |
74 | Refsys& ref); |
75 | int createDivision(XString& divStr, |
76 | Refsys& ref); |
77 | void createUtilityFunctions(DOMElement* el, |
78 | const XString& ident); |
79 | }; |
80 | |
81 | |
82 | int main(int argC, char* argV[]) |
83 | { |
84 | try |
85 | { |
86 | XMLPlatformUtils::Initialize(); |
87 | } |
88 | catch (const XMLException& toCatch) |
89 | { |
90 | XString message(toCatch.getMessage()); |
91 | std::cerr |
92 | << APP_NAME"hdds-root" << " - error during initialization!" |
93 | << std::endl << S(message)message.c_str() << std::endl; |
94 | return 1; |
95 | } |
96 | |
97 | if (argC < 2) |
98 | { |
99 | usage(); |
100 | return 1; |
101 | } |
102 | else if ((argC == 2) && (strcmp(argV[1], "-?") == 0)) |
103 | { |
104 | usage(); |
105 | return 2; |
106 | } |
107 | |
108 | XString xmlFile; |
109 | bool rootMacroOutput = true; |
110 | int argInd; |
111 | for (argInd = 1; argInd < argC; argInd++) |
112 | { |
113 | if (argV[argInd][0] != '-') |
114 | break; |
115 | |
116 | if (strcmp(argV[argInd], "-v") == 0) |
117 | rootMacroOutput = false; |
118 | else |
119 | std::cerr |
120 | << "Unknown option \'" << argV[argInd] |
121 | << "\', ignoring it\n" << std::endl; |
122 | } |
123 | |
124 | if (argInd != argC - 1) |
125 | { |
126 | usage(); |
127 | return 1; |
128 | } |
129 | xmlFile = argV[argInd]; |
130 | |
131 | #if defined OLD_STYLE_XERCES_PARSER |
132 | DOMDocument* document = parseInputDocument(xmlFile,false); |
133 | #else |
134 | DOMDocument* document = buildDOMDocument(xmlFile,false); |
135 | #endif |
136 | if (document == 0) |
137 | { |
138 | std::cerr |
139 | << APP_NAME"hdds-root" << " - error parsing HDDS document, " |
140 | << "cannot continue" << std::endl; |
141 | return 1; |
142 | } |
143 | |
144 | |
145 | try { |
146 | document->getDocumentElement(); |
147 | } |
148 | catch (DOMException& e) { |
149 | std::cerr << "Woops " << e.msg << std::endl; |
150 | return 1; |
151 | } |
152 | |
153 | DOMElement* rootEl = document->getElementById(X("everything")XString("everything").unicode_str()); |
154 | if (rootEl == 0) |
155 | { |
156 | std::cerr |
157 | << APP_NAME"hdds-root" << " - error scanning HDDS document, " << std::endl |
158 | << " no element named \"everything\" found" << std::endl; |
159 | return 1; |
160 | } |
161 | |
162 | if (rootMacroOutput) |
163 | { |
164 | RootMacroWriter fout; |
165 | fout.translate(rootEl); |
166 | } |
167 | |
168 | XMLPlatformUtils::Terminate(); |
169 | return 0; |
170 | } |
171 | |
172 | struct goo |
173 | { |
174 | double weight; |
175 | Substance* sub; |
176 | }; |
177 | |
178 | int RootMacroWriter::createMaterial(DOMElement* el) |
179 | { |
180 | int imate = CodeWriter::createMaterial(el); |
181 | |
182 | double a = fSubst.getAtomicWeight(); |
183 | double z = fSubst.getAtomicNumber(); |
184 | double dens = fSubst.getDensity(); |
185 | double radl = fSubst.getRadLength(); |
186 | |
187 | double coll = fSubst.getColLength(); |
188 | |
189 | XString matS = fSubst.getName(); |
190 | |
191 | if (fSubst.fBrewList.size() == 0) |
192 | { |
193 | std::cout |
194 | << "TGeoMaterial *mat" << imate |
195 | << "= new TGeoMaterial(\"" << S(matS)matS.c_str() |
196 | << "\"," << a << "," << z << "," << dens << ");" |
197 | << std::endl |
198 | << "mat" << imate << "->SetUniqueID(" << imate << ");" |
199 | << std::endl; |
200 | if (dens > 0 && radl > 0) |
201 | { |
202 | std::cout |
203 | << "mat" << imate |
204 | << "->SetRadLen(" << radl << "," << coll << ");" |
205 | << std::endl; |
206 | } |
207 | } |
208 | else |
209 | { |
210 | std::stringstream sout; |
211 | struct goo gunk; |
212 | gunk.weight = 1; |
213 | gunk.sub = &fSubst; |
214 | std::list<struct goo> gooStack; |
215 | gooStack.push_back(gunk); |
216 | int nelem = 0; |
217 | while (gooStack.size() > 0) |
218 | { |
219 | gunk = gooStack.front(); |
220 | gooStack.pop_front(); |
221 | if (gunk.sub->fBrewList.size() == 0) |
222 | { |
223 | sout << "mat" << imate |
224 | << "->DefineElement(" << nelem++ << "," |
225 | << gunk.sub->getAtomicWeight() << "," |
226 | << gunk.sub->getAtomicNumber() << "," |
227 | << gunk.weight << ");" << std::endl; |
228 | } |
229 | else |
230 | { |
231 | std::list<Substance::Brew>::iterator iter; |
232 | for (iter = gunk.sub->fBrewList.begin(); |
233 | iter != gunk.sub->fBrewList.end(); |
234 | ++iter) |
235 | { |
236 | struct goo slime; |
237 | slime.weight = gunk.weight * iter->wfact; |
238 | slime.sub = iter->sub; |
239 | gooStack.push_back(slime); |
240 | } |
241 | } |
242 | } |
243 | std::cout |
244 | << "TGeoMixture *mat" << imate |
245 | << "= new TGeoMixture(\"" << S(matS)matS.c_str() |
246 | << "\"," << nelem << "," << dens << ");" |
247 | << std::endl |
248 | << "mat" << imate << "->SetUniqueID(" << imate << ");" |
249 | << std::endl |
250 | << sout.str(); |
251 | } |
252 | return imate; |
253 | } |
254 | |
255 | int RootMacroWriter::createSolid(DOMElement* el, Refsys& ref) |
256 | { |
257 | int ivolu = CodeWriter::createSolid(el,ref); |
258 | int imate = fSubst.fUniqueID; |
259 | |
260 | |
261 | int ifield = 0; |
262 | double fieldm = 0; |
263 | double tmaxfd = 0; |
264 | double stemax = -1; |
265 | double deemax = -1; |
266 | XString epsil = "0.001"; |
267 | double stmin = -1; |
268 | if (ref.fRegion) |
269 | { |
270 | DOMNodeList* noBfieldL = ref.fRegion->getElementsByTagName(X("noBfield")XString("noBfield").unicode_str()); |
271 | DOMNodeList* uniBfieldL = ref.fRegion->getElementsByTagName(X("uniformBfield")XString("uniformBfield").unicode_str()); |
272 | DOMNodeList* mapBfieldL = ref.fRegion->getElementsByTagName(X("mappedBfield")XString("mappedBfield").unicode_str()); |
273 | DOMNodeList* swimL = ref.fRegion->getElementsByTagName(X("swim")XString("swim").unicode_str()); |
274 | if (noBfieldL->getLength() > 0) |
275 | { |
276 | ifield = 0; |
277 | fieldm = 0; |
278 | } |
279 | else if (uniBfieldL->getLength() > 0) |
280 | { |
281 | DOMElement* uniBfieldEl = (DOMElement*)uniBfieldL->item(0); |
282 | XString bvecS(uniBfieldEl->getAttribute(X("Bx_By_Bz")XString("Bx_By_Bz").unicode_str())); |
283 | std::stringstream str(S(bvecS)bvecS.c_str()); |
284 | double B[3]; |
285 | str >> B[0] >> B[1] >> B[2]; |
286 | fieldm = sqrt(B[0]*B[0] + B[1]*B[1] + B[2]*B[2]); |
287 | ifield = 2; |
288 | tmaxfd = 1; |
289 | } |
290 | else if (mapBfieldL->getLength() > 0) |
291 | { |
292 | DOMElement* mapBfieldEl = (DOMElement*)mapBfieldL->item(0); |
293 | XString bmaxS(mapBfieldEl->getAttribute(X("maxBfield")XString("maxBfield").unicode_str())); |
294 | fieldm = atof(S(bmaxS)bmaxS.c_str()); |
295 | ifield = 2; |
296 | tmaxfd = 1; |
297 | if (swimL->getLength() > 0) |
298 | { |
299 | DOMElement* swimEl = (DOMElement*)swimL->item(0); |
300 | XString methodS(swimEl->getAttribute(X("method")XString("method").unicode_str())); |
301 | ifield = (methodS == "RungeKutta")? 1 : 2; |
302 | } |
303 | } |
304 | } |
305 | |
306 | static int itmedCount = 0; |
307 | int itmed = ++itmedCount; |
308 | XString nameS(el->getAttribute(X("name")XString("name").unicode_str())); |
309 | XString matS(el->getAttribute(X("material")XString("material").unicode_str())); |
310 | XString sensiS(el->getAttribute(X("sensitive")XString("sensitive").unicode_str())); |
311 | std::cout |
312 | << "TGeoMedium *med" << itmed |
313 | << " = new TGeoMedium(\"" << S(nameS)nameS.c_str() |
314 | << " " << S(matS)matS.c_str() << "\"," << itmed << "," << imate << "," |
315 | << (sensiS == "true" ? 1 : 0) << "," |
316 | << ifield << "," << fieldm << "," << tmaxfd << "," |
317 | << stemax << "," << deemax << "," << epsil << "," << stmin << ");" |
318 | << std::endl; |
319 | |
320 | Units unit; |
321 | unit.getConversions(el); |
322 | |
323 | double par[99]; |
324 | int npar = 0; |
325 | XString shapeS(el->getTagName()); |
326 | if (shapeS == "box") |
327 | { |
328 | shapeS = "BOX "; |
329 | double xl, yl, zl; |
330 | XString xyzS(el->getAttribute(X("X_Y_Z")XString("X_Y_Z").unicode_str())); |
331 | std::stringstream listr(xyzS); |
332 | listr >> xl >> yl >> zl; |
333 | |
334 | npar = 3; |
335 | par[0] = xl/2 /unit.cm; |
336 | par[1] = yl/2 /unit.cm; |
337 | par[2] = zl/2 /unit.cm; |
338 | |
339 | std::cout |
340 | << "TGeoVolume *" << S(nameS)nameS.c_str() |
341 | << "= gGeoManager->MakeBox(\"" << S(nameS)nameS.c_str() << "\",med" |
342 | << itmed << "," << par[0] << "," << par[1] << "," |
343 | << par[2] << ");" << std::endl; |
344 | } |
345 | else if (shapeS == "eltu") |
346 | { |
347 | shapeS = "ELTU"; |
348 | double rx, ry, zl; |
349 | |
350 | XString rxyzS(el->getAttribute(X("Rxy_Z")XString("Rxy_Z").unicode_str())); |
351 | std::stringstream listr(rxyzS); |
352 | listr >> rx >> ry >> zl; |
353 | |
354 | npar = 3; |
| Value stored to 'npar' is never read |
355 | par[0] = rx /unit.cm; |
356 | par[1] = ry /unit.cm; |
357 | par[2] = zl/2 /unit.cm; |
358 | |
359 | std::cout |
360 | << "TGeoVolume *" << S(nameS)nameS.c_str() << "= gGeoManager->MakeEltu(\"" |
361 | << S(nameS)nameS.c_str() << "\",med" << itmed << "," |
362 | << par[0] << "," << par[1] << "," << par[2] << ");" |
363 | << std::endl; |
364 | |
365 | } |
366 | else if (shapeS == "tubs") |
367 | { |
368 | shapeS = "TUBS"; |
369 | double ri, ro, zl, phi0, dphi; |
370 | XString riozS(el->getAttribute(X("Rio_Z")XString("Rio_Z").unicode_str())); |
371 | std::stringstream listr(riozS); |
372 | listr >> ri >> ro >> zl; |
373 | XString profS(el->getAttribute(X("profile")XString("profile").unicode_str())); |
374 | listr.clear(), listr.str(profS); |
375 | listr >> phi0 >> dphi; |
376 | |
377 | npar = 5; |
378 | par[0] = ri /unit.cm; |
379 | par[1] = ro /unit.cm; |
380 | par[2] = zl/2 /unit.cm; |
381 | par[3] = phi0 /unit.deg; |
382 | par[4] = (phi0 + dphi) /unit.deg; |
383 | if (dphi == 360*unit.deg) |
384 | { |
385 | shapeS = "TUBE"; |
386 | npar = 3; |
387 | |
388 | std::cout |
389 | << "TGeoVolume *" << S(nameS)nameS.c_str() << "= gGeoManager->MakeTube(\"" |
390 | << S(nameS)nameS.c_str() << "\",med" << itmed << "," |
391 | << par[0] << "," << par[1] << "," << par[2] << ");" |
392 | << std::endl; |
393 | } |
394 | else |
395 | { |
396 | std::cout |
397 | << "TGeoVolume *" << S(nameS)nameS.c_str() << "= gGeoManager->MakeTubs(\"" |
398 | << S(nameS)nameS.c_str() << "\",med" << itmed << "," << par[0] << "," |
399 | << par[1] << "," << par[2] << "," << par[3] << "," << par[4] |
400 | << ");" << std::endl; |
401 | } |
402 | } |
403 | else if (shapeS == "trd") |
404 | { |
405 | shapeS = "TRAP"; |
406 | double xm, ym, xp, yp, zl; |
407 | XString xyzS(el->getAttribute(X("Xmp_Ymp_Z")XString("Xmp_Ymp_Z").unicode_str())); |
408 | std::stringstream listr(xyzS); |
409 | listr >> xm >> xp >> ym >> yp >> zl; |
410 | double alph_xz, alph_yz; |
411 | XString incS(el->getAttribute(X("inclination")XString("inclination").unicode_str())); |
412 | listr.clear(), listr.str(incS); |
413 | listr >> alph_xz >> alph_yz; |
414 | |
415 | npar = 11; |
416 | double x = tan(alph_xz/unit.rad); |
417 | double y = tan(alph_yz/unit.rad); |
418 | double r = sqrt(x*x + y*y); |
419 | par[0] = zl/2 /unit.cm; |
420 | par[1] = atan2(r,1)*unit.rad /unit.deg; |
421 | par[2] = atan2(y,x)*unit.rad /unit.deg; |
422 | par[3] = ym/2 /unit.cm; |
423 | par[4] = xm/2 /unit.cm; |
424 | par[5] = xm/2 /unit.cm; |
425 | par[6] = 0; |
426 | par[7] = yp/2 /unit.cm; |
427 | par[8] = xp/2 /unit.cm; |
428 | par[9] = xp/2 /unit.cm; |
429 | par[10] = 0; |
430 | |
431 | std::cout |
432 | << "TGeoVolume *" << S(nameS)nameS.c_str() << "= gGeoManager->MakeTrap(\"" |
433 | << S(nameS)nameS.c_str() << "\",med" << itmed << "," << par[0] << "," |
434 | << par[1] << "," << par[2] << "," << par[3] << "," << par[4] |
435 | << "," << par[5] << "," << par[6] << "," << par[7] << "," |
436 | << par[8] << "," << par[9] << "," << par[10] << ");" |
437 | << std::endl; |
438 | } |
439 | else if (shapeS == "pcon") |
440 | { |
441 | shapeS = "PCON"; |
442 | double phi0, dphi; |
443 | XString profS(el->getAttribute(X("profile")XString("profile").unicode_str())); |
444 | std::stringstream listr(profS); |
445 | listr >> phi0 >> dphi; |
446 | DOMNodeList* planeList = el->getElementsByTagName(X("polyplane")XString("polyplane").unicode_str()); |
447 | |
448 | npar = 3; |
449 | par[0] = phi0 /unit.deg; |
450 | par[1] = dphi /unit.deg; |
451 | par[2] = planeList->getLength(); |
452 | for (unsigned int p = 0; p < planeList->getLength(); p++) |
453 | { |
454 | double ri, ro, zl; |
455 | DOMNode* node = planeList->item(p); |
456 | DOMElement* elem = (DOMElement*) node; |
457 | XString riozS(elem->getAttribute(X("Rio_Z")XString("Rio_Z").unicode_str())); |
458 | std::stringstream listr1(riozS); |
459 | listr1 >> ri >> ro >> zl; |
460 | par[npar++] = zl /unit.cm; |
461 | par[npar++] = ri /unit.cm; |
462 | par[npar++] = ro /unit.cm; |
463 | } |
464 | |
465 | std::cout |
466 | << "TGeoVolume *" << S(nameS)nameS.c_str() << "= gGeoManager->MakePcon(\"" |
467 | << S(nameS)nameS.c_str() << "\",med" << itmed << "," << par[0] << "," |
468 | << par[1] << "," << par[2] << ");" << std::endl; |
469 | for (int mycounter=0; mycounter < par[2]; mycounter++) |
470 | { |
471 | std::cout |
472 | << " ((TGeoPcon*)" << S(nameS)nameS.c_str() |
473 | << "->GetShape())->DefineSection(" << mycounter |
474 | << "," << par[3+3*mycounter] << "," << par[4+3*mycounter] |
475 | << "," << par[5+3*mycounter] << ");" << std::endl; |
476 | } |
477 | } |
478 | else if (shapeS == "pgon") |
479 | { |
480 | shapeS = "PGON"; |
481 | int segments; |
482 | XString segS(el->getAttribute(X("segments")XString("segments").unicode_str())); |
483 | segments = atoi(S(segS)segS.c_str()); |
484 | double phi0, dphi; |
485 | XString profS(el->getAttribute(X("profile")XString("profile").unicode_str())); |
486 | std::stringstream listr(profS); |
487 | listr >> phi0 >> dphi; |
488 | DOMNodeList* planeList = el->getElementsByTagName(X("polyplane")XString("polyplane").unicode_str()); |
489 | |
490 | npar = 4; |
491 | par[0] = phi0 /unit.deg; |
492 | par[1] = dphi /unit.deg; |
493 | par[2] = segments; |
494 | par[3] = planeList->getLength(); |
495 | for (unsigned int p = 0; p < planeList->getLength(); p++) |
496 | { |
497 | double ri, ro, zl; |
498 | DOMNode* node = planeList->item(p); |
499 | DOMElement* elem = (DOMElement*) node; |
500 | XString riozS(elem->getAttribute(X("Rio_Z")XString("Rio_Z").unicode_str())); |
501 | std::stringstream listr1(riozS); |
502 | listr1 >> ri >> ro >> zl; |
503 | par[npar++] = zl /unit.cm; |
504 | par[npar++] = ri /unit.cm; |
505 | par[npar++] = ro /unit.cm; |
506 | } |
507 | |
508 | std::cout |
509 | << "TGeoVolume *" << S(nameS)nameS.c_str() << "= gGeoManager->MakePgon(\"" |
510 | << S(nameS)nameS.c_str() << "\",med" << itmed << "," << par[0] << "," |
511 | << par[1] << "," << par[2] << "," << par[3] << ");" << std::endl; |
512 | for (int mycounter=0; mycounter < par[3]; mycounter++) |
513 | { |
514 | std::cout |
515 | << " ((TGeoPgon*)" << S(nameS)nameS.c_str() |
516 | << "->GetShape())->DefineSection(" << mycounter |
517 | << "," << par[4+3*mycounter] << "," << par[5+3*mycounter] |
518 | << "," << par[6+3*mycounter] << ");" << std::endl; |
519 | } |
520 | } |
521 | else if (shapeS == "cons") |
522 | { |
523 | shapeS = "CONS"; |
524 | double rim, rip, rom, rop, zl; |
525 | XString riozS(el->getAttribute(X("Rio1_Rio2_Z")XString("Rio1_Rio2_Z").unicode_str())); |
526 | std::stringstream listr(riozS); |
527 | listr >> rim >> rom >> rip >> rop >> zl; |
528 | double phi0, dphi; |
529 | XString profS(el->getAttribute(X("profile")XString("profile").unicode_str())); |
530 | listr.clear(), listr.str(profS); |
531 | listr >> phi0 >> dphi; |
532 | |
533 | npar = 7; |
534 | par[0] = zl/2 /unit.cm; |
535 | par[1] = rim /unit.cm; |
536 | par[2] = rom /unit.cm; |
537 | par[3] = rip /unit.cm; |
538 | par[4] = rop /unit.cm; |
539 | par[5] = phi0 /unit.deg; |
540 | par[6] = (phi0 + dphi) /unit.deg; |
541 | if (dphi == 360*unit.deg) |
542 | { |
543 | shapeS = "CONE"; |
544 | npar = 5; |
545 | |
546 | std::cout |
547 | << "TGeoVolume *" << S(nameS)nameS.c_str() << "= gGeoManager->MakeCone(\"" |
548 | << S(nameS)nameS.c_str() << "\",med" << itmed << "," |
549 | << par[0] << "," << par[1] << "," << par[2] |
550 | << par[3] << "," << par[4] << ");" << std::endl; |
551 | } |
552 | else |
553 | { |
554 | std::cout |
555 | << "TGeoVolume *" << S(nameS)nameS.c_str() |
556 | << "= gGeoManager->MakeCons(\"" << S(nameS)nameS.c_str() |
557 | << "\",med" << itmed << "," << par[0] << "," << par[1] |
558 | << "," << par[2] << "," << par[3] << "," << par[4] << "," |
559 | << par[5] << "," << par[6] << ");" << std::endl; |
560 | } |
561 | } |
562 | else if (shapeS == "sphere") |
563 | { |
564 | shapeS = "SPHE"; |
565 | double ri, ro; |
566 | XString rioS(el->getAttribute(X("Rio")XString("Rio").unicode_str())); |
567 | std::stringstream listr(rioS); |
568 | listr >> ri >> ro; |
569 | double theta0, theta1; |
570 | XString polarS(el->getAttribute(X("polar_bounds")XString("polar_bounds").unicode_str())); |
571 | listr.clear(), listr.str(polarS); |
572 | listr >> theta0 >> theta1; |
573 | double phi0, dphi; |
574 | XString profS(el->getAttribute(X("profile")XString("profile").unicode_str())); |
575 | listr.clear(), listr.str(profS); |
576 | listr >> phi0 >> dphi; |
577 | |
578 | npar = 6; |
579 | par[0] = ri /unit.cm; |
580 | par[1] = ro /unit.cm; |
581 | par[2] = theta0 /unit.deg; |
582 | par[3] = theta1 /unit.deg; |
583 | par[4] = phi0 /unit.deg; |
584 | par[5] = (phi0 + dphi) /unit.deg; |
585 | std::cout |
586 | << "TGeoVolume *" << S(nameS)nameS.c_str() |
587 | << "= gGeoManager->MakeSphere(\"" << S(nameS)nameS.c_str() |
588 | << "\",med" << itmed << "," << par[0] << "," << par[1] |
589 | << "," << par[2] << "," << par[3] << "," << par[4] << "," |
590 | << par[5] << ");" << std::endl; |
591 | } |
592 | else |
593 | { |
594 | std::cerr |
595 | << APP_NAME"hdds-root" << " error: volume " << S(nameS)nameS.c_str() |
596 | << " should be one of the valid shapes, not " << S(shapeS)shapeS.c_str() |
597 | << std::endl; |
598 | exit(1); |
599 | } |
600 | |
601 | if (nameS.size() > 4) |
602 | { |
603 | std::cerr |
604 | << APP_NAME"hdds-root" << " error: volume name " << S(nameS)nameS.c_str() |
605 | << " should be no more than 4 characters long." << std::endl; |
606 | exit(1); |
607 | } |
608 | |
609 | return ivolu; |
610 | } |
611 | |
612 | int RootMacroWriter::createRotation(Refsys& ref) |
613 | { |
614 | int irot = CodeWriter::createRotation(ref); |
615 | |
616 | if (irot > 0) |
617 | { |
618 | double theta[3], phi[3]; |
619 | for (int i = 0; i < 3; i++) |
620 | { |
621 | double r = sqrt(ref.fRmatrix[0][i] * ref.fRmatrix[0][i] |
622 | + ref.fRmatrix[1][i] * ref.fRmatrix[1][i]); |
623 | theta[i] = atan2(r, ref.fRmatrix[2][i]) * 180/M_PI3.14159265358979323846; |
624 | phi[i] = atan2(ref.fRmatrix[1][i], ref.fRmatrix[0][i]) * 180/M_PI3.14159265358979323846; |
625 | } |
626 | |
627 | std::cout |
628 | << "TGeoRotation *rot" << irot |
629 | <<" = new TGeoRotation(\"rot" << irot << "\"," |
630 | << theta[0] << "," << phi[0] << "," << theta[1] << "," |
631 | << phi[1] << "," << theta[2] << "," << phi[2] << ");" |
632 | << std::endl; |
633 | } |
634 | return irot; |
635 | } |
636 | |
637 | int RootMacroWriter::createDivision(XString& divStr, Refsys& ref) |
638 | { |
639 | int ndiv = CodeWriter::createDivision(divStr,ref); |
640 | |
641 | int iaxis; |
642 | if (ref.fPartition.axis == "x") |
643 | { |
644 | iaxis = 1; |
645 | } |
646 | else if (ref.fPartition.axis == "y") |
647 | { |
648 | iaxis = 2; |
649 | } |
650 | else if (ref.fPartition.axis == "z") |
651 | { |
652 | iaxis = 3; |
653 | } |
654 | else if (ref.fPartition.axis == "rho") |
655 | { |
656 | iaxis = 1; |
657 | } |
658 | else if (ref.fPartition.axis == "phi") |
659 | { |
660 | iaxis = 2; |
661 | } |
662 | else |
663 | { |
664 | XString motherS(ref.fMother->getAttribute(X("name")XString("name").unicode_str())); |
665 | std::cerr |
666 | << APP_NAME"hdds-root" << " error: volume " << S(motherS)motherS.c_str() |
667 | << " is divided along unsupported axis " |
668 | << "\"" << ref.fPartition.axis << "\"" |
669 | << std::endl; |
670 | exit(1); |
671 | } |
672 | |
673 | XString motherS(ref.fMother->getAttribute(X("name")XString("name").unicode_str())); |
674 | std::cout |
675 | << "TGeoVolume *" << divStr << "= " |
676 | << S(motherS)motherS.c_str() << "->Divide(\"" << divStr << "\"," |
677 | << iaxis << "," << ref.fPartition.ncopy << "," |
678 | << ref.fPartition.start << "," << ref.fPartition.step << ");" |
679 | << std::endl; |
680 | |
681 | return ndiv; |
682 | } |
683 | |
684 | int RootMacroWriter::createVolume(DOMElement* el, Refsys& ref) |
685 | { |
686 | int icopy = CodeWriter::createVolume(el,ref); |
687 | |
688 | if (fPending) |
689 | { |
690 | XString nameS(el->getAttribute(X("name")XString("name").unicode_str())); |
691 | XString motherS(fRef.fMother->getAttribute(X("name")XString("name").unicode_str())); |
692 | int irot = fRef.fRotation; |
693 | if (first_volume_placement == 0) |
694 | { |
695 | std::cout |
696 | << "gGeoManager->SetTopVolume(" << S(motherS)motherS.c_str() << ");" |
697 | << std::endl; |
698 | first_volume_placement = 1; |
699 | } |
700 | if (irot == 0) |
701 | { |
702 | if ( (fRef.fOrigin[0] == 0) && |
703 | (fRef.fOrigin[1] == 0) && |
704 | (fRef.fOrigin[2] == 0)) |
705 | { |
706 | std::cout |
707 | << S(motherS)motherS.c_str() << "->AddNode(" |
708 | << S(nameS)nameS.c_str() << "," << icopy << ",gGeoIdentity);" |
709 | << std::endl; |
710 | } |
711 | else |
712 | { |
713 | std::cout |
714 | << S(motherS)motherS.c_str() <<"->AddNode(" << S(nameS)nameS.c_str() << "," |
715 | << icopy << ",new TGeoTranslation(" |
716 | << fRef.fOrigin[0] << "," |
717 | << fRef.fOrigin[1] << "," |
718 | << fRef.fOrigin[2] << "));" << std::endl; |
719 | } |
720 | } |
721 | else |
722 | { |
723 | std::cout |
724 | << S(motherS)motherS.c_str() <<"->AddNode(" << S(nameS)nameS.c_str()<< "," |
725 | << icopy << ",new TGeoCombiTrans(" |
726 | << fRef.fOrigin[0] << "," |
727 | << fRef.fOrigin[1] << "," |
728 | << fRef.fOrigin[2] << "," << "rot" << irot |
729 | <<"));" << std::endl; |
730 | } |
731 | fPending = false; |
732 | } |
733 | return icopy; |
734 | } |
735 | |
736 | void RootMacroWriter::createHeader() |
737 | { |
738 | CodeWriter::createHeader(); |
739 | |
740 | std::cout |
741 | << "TGeoManager * hddsroot()" << std::endl |
742 | << "{" << std::endl |
743 | << "//" << std::endl |
744 | << "// This file has been generated automatically via the " << std::endl |
745 | << "// utility hdds-root_h directly from main_HDDS.xml " << std::endl |
746 | << "// (see ROOT class TGeoManager for an example of use) " << std::endl |
747 | << "//" << std::endl |
748 | << " " << std::endl |
749 | << "//-----------List of Materials and Mixtures--------------" << std::endl |
750 | << " " << std::endl; |
751 | } |
752 | |
753 | void RootMacroWriter::createTrailer() |
754 | { |
755 | CodeWriter::createTrailer(); |
756 | std::cout |
757 | << "gGeoManager->CloseGeometry();" << std::endl |
758 | << "gGeoManager->SetTopVolume(SITE);" << std::endl |
759 | << "return gGeoManager;" << std::endl |
760 | << "}" << std::endl; |
761 | } |
762 | |
763 | void RootMacroWriter::createUtilityFunctions(DOMElement* el, const XString& ident) |
764 | { |
765 | |
766 | |
767 | std::cout |
768 | << std::endl |
769 | << "const char* md5geom(void){ return \""<< last_md5_checksum <<"\";}" << std::endl; |
770 | } |
771 | |