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