Bug Summary

File:/group/halld/Software/builds/Linux_RHEL7-x86_64-gcc4.8.5/hdds/hdds-4.14.0^root62404/hddsCommon.cpp
Location:line 1686, column 19
Description:Value stored to 'rMax' is never read

Annotated Source Code

1/* HDDS Common Classes
2 *
3 * Author: richard.t.jones@uconn.edu
4 *
5 * Original version - Richard Jones, January 6, 2006.
6 * Revision 1.1 - Richard Jones, September 10, 2013.
7 *
8 * Revision 1.1 Notes:
9 * -------------------
10 * 1. Updated to HDDS-1.1 which adds support for geometry layers, using
11 * the geometry_layer="int" attribute of the object placement tags.
12 *
13 * Original Notes:
14 * ---------------
15 * 1. The HDDS specification is an xml document in the standard W3C
16 * schema namespace http://www.gluex.org/hdds, as described by the
17 * HDDS-1_0.xsd schema document.
18 * 2. Access to the xml source is through the industry-standard DOM interface.
19 * 3. The code has been tested with the xerces-c DOM implementation from
20 * Apache, and is intended to be used with the xerces-c library.
21 * 4. The common classes were created originally as tools for the hdds-geant
22 * converter to write Fortran geometry definition code for the Geant3
23 * simulation. Later they were reused for other simulation packages,
24 * but occasionally the original purpose is still visible in comments
25 * and some of the implementation details.
26 *
27 * Implementation:
28 * ---------------
29 * Most of the translation was straight-forward, but there were a couple
30 * of tricky cases where decisions had to be made. I think that these
31 * choices should work out in most cases. If not, further tuning of the
32 * algorithm will be necessary. Here are the tricky cases.
33 *
34 * 1. When to use divisions instead of placing multiple copies.
35 *
36 * Most of the time when a <mpos...> command appears it can be translated
37 * into a division of the mother volume in Geant. This is good to do
38 * because it makes both more compact description and is more efficient
39 * at tracking time. The difficulty here is that there is no easy way
40 * to check if the contents fit entirely inside the division. This is
41 * not a problem in the HDDS geometry description because the <mpos...>
42 * command is only for positioning, and makes no statement about what
43 * slice of the mother it occupies. But it is a problem for Geant because
44 * contents of divisions have to fit inside the division. This can
45 * happen at any time, but it most frequently happens when the object
46 * is being rotated before placement, as in the case of stereo layers
47 * in a drift chamber. My solution is to make a strict set of rules
48 * that are required before hdds-geant will create a division in response
49 * to a <mpos...> command, and do individual placement by default.
50 * The rules for creation of divisions are as follows:
51 * (a) the <composition> command must have a solid container, either
52 * via the envelope="..." attribute or by itself being a division.
53 * (b) the <mpos...> command must be alone inside its <composition>
54 * (c) the kind of shape of the container must be compatible with the
55 * <mpos...> type, eg. <mposPhi> would work if its container is
56 * a "tubs" (or division theroef) but not if it is a "box".
57 * (d) for <mposPhi> the impliedRot attribute must be "true".
58 * (e) the rot="..." attribute must be zeros or missing.
59 * The last condition is not logically necessary for it to work, but it
60 * avoids the problems that often occur with rotated placements failing
61 * to fit inside the division. To bypass this limitation and place
62 * rotated volumes inside divisions, one can simply create a new volume
63 * as a <composition> into which the content is placed with rotation,
64 * and then place the new volume with the <mpos...> command without rot.
65 *
66 * 2. How to recognize which media contain magnetic fields.
67 *
68 * There is was originally no provision in the AGDD geometry model for
69 * magnetic field information. This information was introduced in HDDS
70 * through a new concept called a "region" and a new tag "apply" which
71 * associates a volume in the geometry definition with a region. For more
72 * information about the meaning of regions in HDDS and the methods for
73 * specifying a region's magnetic field, see the documentation in the
74 * HDDS schema file. Geant needs to distinguish between 4 cases:
75 * ifield=0 : no magnetic field
76 * ifield=1 : general case of inhomogenous field (Runge-Kutta)
77 * ifield=2 : quasi-homogenous field with map (helical segments)
78 * ifield=3 : uniform field (helices along local z-axis)
79 * For detector regions with no magnetic field, the volume is created with
80 * ifield=0. If a field map is provided for the region, it is assigned
81 * ifield=1 and the field interpolator is written as a part of the output
82 * code. If the field is uniform then it is assigned ifield=2 unless it
83 * is along the z-axis, in which case it is assigned ifield=3.
84 *
85 * 3. What to do about stackX/stackY/stackZ tags
86 *
87 * In the case of Boolean tags (union/intersection/subtraction) the choice
88 * was easy: no support in Geant3 for these cases. For the stacks it is
89 * possible to construct such structures in Geant3 but it is complicated
90 * by the fact that the stacks do not give information about the kind or
91 * size of volume that should be used for the mother. Since stacks can
92 * be implemented easily using compositions anyway, I decided not to include
93 * support for them in hdds-geant.
94 */
95
96#include <xercesc/util/PlatformUtils.hpp>
97#include <xercesc/util/XMLString.hpp>
98#include <xercesc/util/XMLStringTokenizer.hpp>
99#include <xercesc/sax/SAXParseException.hpp>
100#include <xercesc/parsers/XercesDOMParser.hpp>
101#include <xercesc/framework/LocalFileFormatTarget.hpp>
102#include <xercesc/dom/DOM.hpp>
103#include <xercesc/util/XercesDefs.hpp>
104#include <xercesc/sax/ErrorHandler.hpp>
105
106using namespace xercesc;
107
108#include "XString.hpp"
109#include "XParsers.hpp"
110#include "hddsCommon.hpp"
111
112#include <assert.h>
113#include <stdlib.h>
114#include <ctype.h>
115#include <stdio.h>
116#include <math.h>
117
118#include <iostream>
119#include <fstream>
120#include <sstream>
121#include <string>
122#include <iomanip>
123#include <vector>
124#include <list>
125
126#define APP_NAME"hddsCommon" "hddsCommon"
127
128#define X(str)XString(str).unicode_str() XString(str).unicode_str()
129#define S(str)str.c_str() str.c_str()
130
131#define NOT_USED(x)((void)(x)) ((void)(x))
132
133/* Refsys class:
134 * Stores persistent information about coordinate
135 * reference systems which are used to orient and place
136 * volumes in the simulation geometry.
137 */
138
139int Refsys::fVolumes = 0;
140int Refsys::fRegions = 0;
141int Refsys::fRotations = 0;
142std::map<std::string,Refsys::VolIdent> Refsys::fIdentifiers;
143std::vector<std::map<std::string,std::vector<int> > > Refsys::fIdentifierTable;
144
145Refsys::Refsys() // empty constructor
146 : fMother(0),
147 fRegion(0),
148 fPhiOffset(0),
149 fRegionID(0),
150 fGeometryLayer(0),
151 fRelativeLayer(0),
152 fIdentifier()
153{
154 fMOrigin[0] = fMOrigin[1] = fMOrigin[2] = 0;
155 fMRmatrix[0][0] = fMRmatrix[1][1] = fMRmatrix[2][2] = 1;
156 fMRmatrix[0][1] = fMRmatrix[1][0] = fMRmatrix[1][2] =
157 fMRmatrix[0][2] = fMRmatrix[2][0] = fMRmatrix[2][1] = 0;
158 reset();
159}
160
161Refsys::Refsys(const Refsys& src) // copy constructor
162 : fMother(src.fMother),
163 fRegion(src.fRegion),
164 fPhiOffset(src.fPhiOffset),
165 fRegionID(src.fRegionID),
166 fGeometryLayer(src.fGeometryLayer),
167 fRelativeLayer(src.fRelativeLayer),
168 fIdentifier(src.fIdentifier),
169 fPartition(src.fPartition)
170{
171 for (int i=0; i<3; i++)
172 {
173 fMOrigin[i] = src.fMOrigin[i];
174 fMRmatrix[i][0] = src.fMRmatrix[i][0];
175 fMRmatrix[i][1] = src.fMRmatrix[i][1];
176 fMRmatrix[i][2] = src.fMRmatrix[i][2];
177 }
178 std::map<std::string,double>::const_iterator iter;
179 for (iter = src.fPar.begin(); iter != src.fPar.end(); ++iter)
180 {
181 fPar[iter->first] = iter->second;
182 }
183 reset(src);
184}
185
186Refsys& Refsys::operator=(const Refsys& src) // copy operator (deep sematics)
187{
188 fIdentifier = src.fIdentifier;
189 fMother = src.fMother;
190 fRegion = src.fRegion;
191 fRegionID = src.fRegionID;
192 fGeometryLayer = src.fGeometryLayer;
193 fRelativeLayer = src.fRelativeLayer;
194 fPhiOffset = src.fPhiOffset;
195 fPartition = src.fPartition;
196 for (int i=0; i<3; i++)
197 {
198 fMOrigin[i] = src.fMOrigin[i];
199 fMRmatrix[i][0] = src.fMRmatrix[i][0];
200 fMRmatrix[i][1] = src.fMRmatrix[i][1];
201 fMRmatrix[i][2] = src.fMRmatrix[i][2];
202 }
203 std::map<std::string,double>::const_iterator iter;
204 for (iter = src.fPar.begin(); iter != src.fPar.end(); ++iter)
205 {
206 fPar[iter->first] = iter->second;
207 }
208 reset(src);
209 return *this;
210}
211
212Refsys& Refsys::reset() // reset origin, Rmatrix to null
213{
214 fOrigin[0] = fOrigin[1] = fOrigin[2] = 0;
215 fRmatrix[0][0] = fRmatrix[1][1] = fRmatrix[2][2] = 1;
216 fRmatrix[0][1] = fRmatrix[1][0] = fRmatrix[1][2] =
217 fRmatrix[0][2] = fRmatrix[2][0] = fRmatrix[2][1] = 0;
218 fRotation = 0;
219 return *this;
220}
221
222Refsys& Refsys::reset(const Refsys& ref) // reset origin, Rmatrix to ref
223{
224 for (int i = 0; i < 3; i++)
225 {
226 fOrigin[i] = ref.fOrigin[i];
227 fRmatrix[i][0] = ref.fRmatrix[i][0];
228 fRmatrix[i][1] = ref.fRmatrix[i][1];
229 fRmatrix[i][2] = ref.fRmatrix[i][2];
230 }
231 fRotation = ref.fRotation;
232 return *this;
233}
234
235Refsys& Refsys::shift(const double vector[3]) // translate origin
236{
237 for (int i = 0; i < 3; i++)
238 {
239 fOrigin[i] += fRmatrix[i][0] * vector[0] +
240 fRmatrix[i][1] * vector[1] +
241 fRmatrix[i][2] * vector[2];
242 fMOrigin[i] += fMRmatrix[i][0] * vector[0] +
243 fMRmatrix[i][1] * vector[1] +
244 fMRmatrix[i][2] * vector[2];
245 }
246 return *this;
247}
248
249Refsys& Refsys::shift(const Refsys& ref) // copy origin from ref
250{
251 fOrigin[0] = ref.fOrigin[0];
252 fOrigin[1] = ref.fOrigin[1];
253 fOrigin[2] = ref.fOrigin[2];
254 fMOrigin[0] = ref.fMOrigin[0];
255 fMOrigin[1] = ref.fMOrigin[1];
256 fMOrigin[2] = ref.fMOrigin[2];
257 return *this;
258}
259
260Refsys& Refsys::shift(const Refsys& ref,
261 const double vector[3]) // translate origin in ref frame
262{
263 Refsys myRef(ref);
264 myRef.shift(vector);
265 return shift(myRef);
266}
267
268Refsys& Refsys::rotate(const double omega[3]) // rotate by vector omega (rad)
269{
270 if ( (omega[0] != 0) || (omega[1] != 0) || (omega[2] != 0) )
271 {
272 double cosx = cos(omega[0]);
273 double sinx = sin(omega[0]);
274 double cosy = cos(omega[1]);
275 double siny = sin(omega[1]);
276 double cosz = cos(omega[2]);
277 double sinz = sin(omega[2]);
278
279 for (int i = 0; i < 3; i++)
280 {
281 double x[3];
282 double xx[3];
283
284 x[0] = fRmatrix[i][0] * cosz + fRmatrix[i][1] * sinz;
285 x[1] = fRmatrix[i][1] * cosz - fRmatrix[i][0] * sinz;
286 x[2] = fRmatrix[i][2];
287 xx[0] = x[0] * cosy - x[2] * siny;
288 xx[1] = x[1];
289 xx[2] = x[2] * cosy + x[0] * siny;
290 fRmatrix[i][0] = xx[0];
291 fRmatrix[i][1] = xx[1] * cosx + xx[2] * sinx;
292 fRmatrix[i][2] = xx[2] * cosx - xx[1] * sinx;
293
294 x[0] = fMRmatrix[i][0] * cosz + fMRmatrix[i][1] * sinz;
295 x[1] = fMRmatrix[i][1] * cosz - fMRmatrix[i][0] * sinz;
296 x[2] = fMRmatrix[i][2];
297 xx[0] = x[0] * cosy - x[2] * siny;
298 xx[1] = x[1];
299 xx[2] = x[2] * cosy + x[0] * siny;
300 fMRmatrix[i][0] = xx[0];
301 fMRmatrix[i][1] = xx[1] * cosx + xx[2] * sinx;
302 fMRmatrix[i][2] = xx[2] * cosx - xx[1] * sinx;
303 }
304
305 fRotation = -1;
306 }
307
308 return *this;
309}
310
311Refsys& Refsys::rotate(const Refsys& ref) // copy Rmatrix from ref
312{
313 for (int i = 0; i < 3; i++)
314 {
315 fRmatrix[i][0] = ref.fRmatrix[i][0];
316 fRmatrix[i][1] = ref.fRmatrix[i][1];
317 fRmatrix[i][2] = ref.fRmatrix[i][2];
318 fMRmatrix[i][0] = ref.fMRmatrix[i][0];
319 fMRmatrix[i][1] = ref.fMRmatrix[i][1];
320 fMRmatrix[i][2] = ref.fMRmatrix[i][2];
321 }
322 fRotation = ref.fRotation;
323 return *this;
324}
325
326Refsys& Refsys::rotate(const Refsys& ref,
327 const double omega[3]) // rotate by omega in ref frame
328{
329 Refsys myRef(ref);
330 myRef.rotate(omega);
331 return rotate(myRef);
332}
333
334std::vector<double>& Refsys::getRotation() const
335{
336 std::vector<double> *angles = new std::vector<double>(3);
337 if (fRmatrix[2][1] == 0 && fRmatrix[2][2] == 0) {
338 if (fRmatrix[2][0] < 0) {
339 (*angles)[0] = atan2(fRmatrix[0][1],fRmatrix[1][1]);
340 (*angles)[1] = M_PI3.14159265358979323846/2.;
341 (*angles)[2] = 0;
342 }
343 else {
344 (*angles)[0] = atan2(-fRmatrix[0][1],fRmatrix[1][1]);
345 (*angles)[1] = -M_PI3.14159265358979323846/2.;
346 (*angles)[2] = 0;
347 }
348 }
349 else {
350 (*angles)[0] = atan2(fRmatrix[2][1],fRmatrix[2][2]);
351 (*angles)[1] = atan2(-fRmatrix[2][0],
352 fRmatrix[2][2]/(cos((*angles)[0])+1e-100));
353 (*angles)[2] = atan2(fRmatrix[1][0],fRmatrix[0][0]);
354 }
355 return *angles;
356}
357
358std::vector<double>& Refsys::getMRotation() const
359{
360 std::vector<double> *angles = new std::vector<double>(3);
361 if (fMRmatrix[2][1] == 0 && fMRmatrix[2][2] == 0) {
362 if (fMRmatrix[2][0] < 0) {
363 (*angles)[0] = atan2(fMRmatrix[0][1],fMRmatrix[1][1]);
364 (*angles)[1] = M_PI3.14159265358979323846/2.;
365 (*angles)[2] = 0;
366 }
367 else {
368 (*angles)[0] = atan2(-fMRmatrix[0][1],fMRmatrix[1][1]);
369 (*angles)[1] = -M_PI3.14159265358979323846/2.;
370 (*angles)[2] = 0;
371 }
372 }
373 else {
374 (*angles)[0] = atan2(fMRmatrix[2][1],fMRmatrix[2][2]);
375 (*angles)[1] = atan2(-fMRmatrix[2][0],
376 fMRmatrix[2][2]/(cos((*angles)[0])+1e-100));
377 (*angles)[2] = atan2(fMRmatrix[1][0],fMRmatrix[0][0]);
378 }
379 return *angles;
380}
381
382void Refsys::clearIdentifiers()
383{
384 fIdentifier.clear();
385}
386
387void Refsys::incrementIdentifiers()
388{
389 std::map<std::string,Refsys::VolIdent>::iterator iter;
390 for (iter = fIdentifier.begin(); iter != fIdentifier.end(); ++iter)
391 {
392 iter->second.value += iter->second.step;
393 }
394}
395
396void Refsys::addIdentifier(XString ident, int value, int step)
397{
398 VolIdent id;
399 id.value = value;
400 id.step = step;
401 fIdentifier[ident] = id;
402 fIdentifiers[ident] = id;
403}
404
405int Refsys::nextRotationID()
406{
407 return ++fRotations;
408}
409
410int Refsys::nextVolumeID()
411{
412 unsigned int ivolu = ++fVolumes;
413 while (fIdentifierTable.size() <= ivolu)
414 {
415 std::map<std::string,std::vector<int> > unmarked;
416 fIdentifierTable.push_back(unmarked);
417 }
418 return ivolu;
419}
420
421int Refsys::nextRegionID()
422{
423 return ++fRegions;
424}
425
426/* Substance class:
427 * Computes and saves properties of materials that are used
428 * in the detector description, sometimes using directly the
429 * values in the hdds file and other times computing them
430 * based on the hdds information.
431 */
432
433Substance::Substance()
434 : fUniqueID(0),
435 fBrewList(0),
436 fMaterialEl(0),
437 fAtomicWeight(0),
438 fAtomicNumber(0),
439 fDensity(-1),
440 fRadLen(0),
441 fAbsLen(0),
442 fColLen(0),
443 fMIdEdx(0)
444{}
445
446Substance::Substance(const Substance& src)
447 : fUniqueID(src.fUniqueID),
448 fMaterialEl(src.fMaterialEl),
449 fAtomicWeight(src.fAtomicWeight),
450 fAtomicNumber(src.fAtomicNumber),
451 fDensity(src.fDensity),
452 fRadLen(src.fRadLen),
453 fAbsLen(src.fAbsLen),
454 fColLen(src.fColLen),
455 fMIdEdx(src.fMIdEdx)
456{
457 std::list<Brew>::const_iterator iter;
458 for (iter = src.fBrewList.begin();
459 iter != src.fBrewList.end();
460 ++iter)
461 {
462 Brew formula = *iter;
463 formula.sub = new Substance(*iter->sub);
464 fBrewList.push_back(formula);
465 }
466}
467
468Substance::Substance(DOMElement* elem)
469 : fUniqueID(0),
470 fBrewList(0),
471 fMaterialEl(elem),
472 fAtomicWeight(0),
473 fAtomicNumber(0),
474 fDensity(-1),
475 fRadLen(0),
476 fAbsLen(0),
477 fColLen(0),
478 fMIdEdx(0)
479{
480 XString aS(fMaterialEl->getAttribute(X("a")XString("a").unicode_str()));
481 fAtomicWeight = atof(S(aS)aS.c_str());
482 XString zS(fMaterialEl->getAttribute(X("z")XString("z").unicode_str()));
483 fAtomicNumber = atof(S(zS)zS.c_str());
484
485 double wfactSum = 0;
486
487 DOMNode* cont;
488 for (cont = fMaterialEl->getFirstChild(); cont != 0;
489 cont = cont->getNextSibling())
490 {
491 if (cont->getNodeType() == DOMNode::ELEMENT_NODE)
492 {
493 DOMElement* contEl = (DOMElement*)cont;
494 XString tagS(contEl->getTagName());
495 if (tagS == "real")
496 {
497 Units unit;
498 unit.getConversions(contEl);
499 XString nameS(contEl->getAttribute(X("name")XString("name").unicode_str()));
500 XString valueS(contEl->getAttribute(X("value")XString("value").unicode_str()));
501 if (nameS == "density")
502 {
503 fDensity = atof(S(valueS)valueS.c_str()) /(unit.g/unit.cm3);
504 }
505 else if (nameS == "radlen")
506 {
507 fRadLen = atof(S(valueS)valueS.c_str()) /unit.cm;
508 }
509 else if (nameS == "abslen")
510 {
511 fAbsLen = atof(S(valueS)valueS.c_str()) /unit.cm;
512 }
513 else if (nameS == "collen")
514 {
515 fColLen = atof(S(valueS)valueS.c_str()) /unit.cm;
516 }
517 else if (nameS == "dedx")
518 {
519 fMIdEdx = atof(S(valueS)valueS.c_str()) /(unit.MeV/unit.cm);
520 }
521 }
522 else if (tagS == "addmaterial")
523 {
524 XString matS(contEl->getAttribute(X("material")XString("material").unicode_str()));
525 DOMDocument* document = fMaterialEl->getOwnerDocument();
526 DOMElement* targEl = document->getElementById(X(matS)XString(matS).unicode_str());
527 XString typeS(targEl->getTagName());
528 Substance::Brew formula;
529 formula.sub = new Substance(targEl);
530 formula.natoms = 0;
531 formula.wfact = 0;
532 DOMNode* mix;
533 for (mix = contEl->getFirstChild(); mix != 0;
534 mix = mix->getNextSibling())
535 {
536 if (mix->getNodeType() == DOMNode::ELEMENT_NODE)
537 {
538 DOMElement* mixEl = (DOMElement*)mix;
539 XString mixS(mixEl->getTagName());
540 if (mixS == "natoms")
541 {
542 if (typeS != "element")
543 {
544 std::cerr << APP_NAME"hddsCommon"
545 << " - error processing composite "
546 << S(matS)matS.c_str() << std::endl
547 << "natoms can only be specified for elements."
548 << std::endl;
549 exit(1);
550 }
551 XString nS(mixEl->getAttribute(X("n")XString("n").unicode_str()));
552 formula.natoms = atoi(S(nS)nS.c_str());
553 formula.wfact = formula.natoms * formula.sub->getAtomicWeight();
554 }
555 else if (mixS == "fractionmass")
556 {
557 XString fS(mixEl->getAttribute(X("fraction")XString("fraction").unicode_str()));
558 formula.wfact = atof(S(fS)fS.c_str());
559 }
560 }
561 }
562 fBrewList.push_back(formula);
563 wfactSum += formula.wfact;
564 }
565 }
566 }
567
568 double aSum=0; double aNorm=0;
569 double zSum=0; double zNorm=0;
570 double densitySum=0; double densityNorm=0;
571 double radlenSum=0; double radlenNorm=0;
572 double abslenSum=0; double abslenNorm=0;
573 double collenSum=0; double collenNorm=0;
574 double dedxSum=0; double dedxNorm=0;
575
576 std::list<Substance::Brew>::iterator iter;
577 for (iter = fBrewList.begin(); iter != fBrewList.end(); ++iter)
578 {
579 iter->wfact /= wfactSum;
580 double weight = (iter->natoms > 0)?
581 iter->natoms * iter->sub->fAtomicWeight : iter->wfact;
582 aSum += weight*iter->sub->fAtomicWeight;
583 aNorm += weight;
584 zSum += weight*iter->sub->fAtomicNumber;
585 zNorm += weight;
586 densitySum += weight/iter->sub->fDensity;
587 densityNorm += weight;
588 weight /= iter->sub->fDensity;
589 radlenSum += weight/(iter->sub->fRadLen + 1e-99);
590 radlenNorm += weight;
591 abslenSum += weight/(iter->sub->fAbsLen + 1e-99);
592 abslenNorm += weight;
593 collenSum += weight/(iter->sub->fColLen + 1e-99);
594 collenNorm += weight;
595 dedxSum += weight*iter->sub->fMIdEdx;
596 dedxNorm += weight;
597 }
598
599 if (fAtomicWeight == 0 && aNorm > 0)
600 {
601 fAtomicWeight = aSum/aNorm;
602 }
603
604 if (fAtomicNumber == 0 && zNorm > 0)
605 {
606 fAtomicNumber = zSum/zNorm;
607 }
608
609 if (fDensity <= 0 && densitySum > 0)
610 {
611 fDensity = densityNorm/densitySum;
612 }
613
614 if (fRadLen == 0 && radlenSum > 0)
615 {
616 fRadLen = radlenNorm/radlenSum;
617 }
618
619 if (fAbsLen == 0 && abslenSum > 0)
620 {
621 fAbsLen = abslenNorm/abslenSum;
622 }
623
624 if (fColLen == 0 && collenSum > 0)
625 {
626 fColLen = collenNorm/collenSum;
627 }
628
629 if (fMIdEdx == 0 && dedxNorm > 0)
630 {
631 fMIdEdx = dedxSum/dedxNorm;
632 }
633
634 if (fDensity < 0)
635 {
636 XString tagS(fMaterialEl->getTagName());
637 XString nameS(fMaterialEl->getAttribute(X("name")XString("name").unicode_str()));
638 std::cerr
639 << APP_NAME"hddsCommon" << " error: " << S(tagS)tagS.c_str() << " " << S(nameS)nameS.c_str()
640 << ", atomic number " << fAtomicNumber
641 << ", atomic weight " << fAtomicWeight
642 << " is missing a density specification." << std::endl;
643 exit(1);
644 }
645}
646
647Substance::~Substance()
648{
649 std::list<Brew>::iterator iter;
650 for (iter = fBrewList.begin(); iter != fBrewList.end(); ++iter)
651 {
652 delete iter->sub;
653 }
654}
655
656Substance& Substance::operator=(const Substance& src)
657{
658 fMaterialEl = src.fMaterialEl;
659 fAtomicWeight = src.fAtomicWeight;
660 fAtomicNumber = src.fAtomicNumber;
661 fDensity = src.fDensity;
662 fRadLen = src.fRadLen;
663 fAbsLen = src.fAbsLen;
664 fColLen = src.fColLen;
665 fMIdEdx = src.fMIdEdx;
666 fUniqueID = src.fUniqueID;
667 fBrewList = src.fBrewList;
668 std::list<Brew>::iterator iter;
669 for (iter = fBrewList.begin();
670 iter != fBrewList.end();
671 ++iter)
672 {
673 iter->sub = new Substance(*iter->sub);
674 }
675 return *this;
676}
677
678double Substance::getAtomicWeight()
679{
680 return fAtomicWeight;
681}
682
683double Substance::getAtomicNumber()
684{
685 return fAtomicNumber;
686}
687
688double Substance::getDensity()
689{
690 return fDensity;
691}
692
693double Substance::getRadLength()
694{
695 return fRadLen;
696}
697
698double Substance::getAbsLength()
699{
700 return fAbsLen;
701}
702
703double Substance::getColLength()
704{
705 return fColLen;
706}
707
708double Substance::getMIdEdx()
709{
710 return fMIdEdx;
711}
712
713XString Substance::getName()
714{
715 return XString(fMaterialEl->getAttribute(X("name")XString("name").unicode_str()));
716}
717
718XString Substance::getSymbol()
719{
720 return XString(fMaterialEl->getAttribute(X("symbol")XString("symbol").unicode_str()));
721}
722
723DOMElement* Substance::getDOMElement()
724{
725 return fMaterialEl;
726}
727
728
729/* Units class:
730 * Provides conversion constants for convenient extraction of
731 * dimensioned parameters in the hdds file.
732 */
733
734Units::Units()
735{
736 set_1s(1.);
737 set_1cm(1.);
738 set_1rad(1.);
739 set_1MeV(1.);
740 set_1g(1.);
741 set_1cm2(1.);
742 set_1cm3(1.);
743 set_1G(1.);
744 percent = 0.01;
745}
746
747Units::Units(const Units& u)
748{
749 set_1s(u.s);
750 set_1cm(u.cm);
751 set_1rad(u.rad);
752 set_1MeV(u.MeV);
753 set_1g(u.g);
754 set_1cm2(u.cm2);
755 set_1cm3(u.cm3);
756 set_1G(u.G);
757 percent = 0.01;
758}
759
760void Units::set_1s(double tu)
761{
762 s=tu;
763 ns=s*1e-9; ms=s*1e-3;
764 min=s/60; hr=min/60; days=hr/24; weeks=days/7;
765}
766
767void Units::set_1cm(double lu)
768{
769 cm=lu;
770 m=cm*1e2; mm=m*1e-3; um=m*1e-6; nm=m*1e-9; km=m*1e3;
771 in=cm*2.54; ft=in*12; miles=ft*5280; mils=in*1e-3;
772}
773
774void Units::set_1rad(double au)
775{
776 rad=au;
777 mrad=rad*1e-3; urad=rad*1e-6;
778 deg=rad*M_PI3.14159265358979323846/180; arcmin=deg/60; arcsec=arcmin/60;
779}
780
781void Units::set_1deg(double au)
782{
783 deg=au;
784 arcmin=deg/60; arcsec=arcmin/60;
785 rad=deg*180/M_PI3.14159265358979323846; mrad=rad*1e-3; urad=rad*1e-6;
786}
787
788void Units::set_1MeV(double eu)
789{
790 MeV=eu;
791 eV=MeV*1e-6; KeV=eV*1e3; GeV=eV*1e9; TeV=eV*1e12;
792}
793
794void Units::set_1g(double mu)
795{
796 g=mu;
797 kg=g*1e3; mg=g*1e-3;
798}
799
800void Units::set_1cm2(double l2u)
801{
802 cm2=l2u;
803 m2=cm2*1e4; mm2=cm2*1e-2;
804 b=cm2*1e-24; mb=b*1e-3; ub=b*1e-6; nb=b*1e-9; pb=b*1e-12;
805}
806
807void Units::set_1cm3(double l3u)
808{
809 cm3=l3u;
810 ml=cm3; l=ml*1e3;
811}
812
813void Units::set_1G(double bfu)
814{
815 G=bfu;
816 kG=G*1e3; Tesla=kG*10;
817}
818
819void Units::getConversions(DOMElement* el)
820{
821 XString unitlS(el->getAttribute(X("unit_length")XString("unit_length").unicode_str()));
822 if (unitlS.size() == 0)
823 {
824 ;
825 }
826 else if (unitlS == "mm")
827 {
828 set_1cm(10);
829 }
830 else if (unitlS == "cm")
831 {
832 set_1cm(1);
833 }
834 else if (unitlS == "m")
835 {
836 set_1cm(0.01);
837 }
838 else if (unitlS == "km")
839 {
840 set_1cm(1e-5);
841 }
842 else if (unitlS == "um")
843 {
844 set_1cm(1e6);
845 }
846 else if (unitlS == "nm")
847 {
848 set_1cm(1e9);
849 }
850 else if (unitlS == "in")
851 {
852 set_1cm(1/2.54);
853 }
854 else if (unitlS == "ft")
855 {
856 set_1cm(1/(12*2.54));
857 }
858 else if (unitlS == "mil")
859 {
860 set_1cm(1000/2.54);
861 }
862 else
863 {
864 XString tagS(el->getTagName());
865 std::cerr
866 << APP_NAME"hddsCommon" << " error: unknown length unit " << S(unitlS)unitlS.c_str()
867 << " on tag " << S(tagS)tagS.c_str() << std::endl;
868 exit(1);
869 }
870
871 XString unitaS = el->getAttribute(X("unit_angle")XString("unit_angle").unicode_str());
872 if (unitaS.size() == 0)
873 {
874 ;
875 }
876 else if (unitaS == "deg")
877 {
878 set_1deg(1);
879 }
880 else if (unitaS == "rad")
881 {
882 set_1rad(1);
883 }
884 else if (unitaS == "mrad")
885 {
886 set_1rad(1e3);
887 }
888 else
889 {
890 XString tagS(el->getTagName());
891 std::cerr
892 << APP_NAME"hddsCommon" << " error: unknown angle unit " << S(unitaS)unitaS.c_str()
893 << " on volume " << S(tagS)tagS.c_str() << std::endl;
894 exit(1);
895 }
896
897 XString unitS = el->getAttribute(X("unit")XString("unit").unicode_str());
898 if (unitS.size() == 0)
899 {
900 ;
901 }
902 else if (unitS == "mm")
903 {
904 set_1cm(10);
905 }
906 else if (unitS == "cm")
907 {
908 set_1cm(1);
909 }
910 else if (unitS == "m")
911 {
912 set_1cm(0.01);
913 }
914 else if (unitlS == "km")
915 {
916 set_1cm(1e-5);
917 }
918 else if (unitlS == "um")
919 {
920 set_1cm(1e6);
921 }
922 else if (unitlS == "nm")
923 {
924 set_1cm(1e9);
925 }
926 else if (unitlS == "in")
927 {
928 set_1cm(1/2.54);
929 }
930 else if (unitlS == "ft")
931 {
932 set_1cm(1/(12*2.54));
933 }
934 else if (unitlS == "mil")
935 {
936 set_1cm(1000/2.54);
937 }
938 else if (unitaS == "deg")
939 {
940 set_1deg(1);
941 }
942 else if (unitaS == "rad")
943 {
944 set_1rad(1);
945 }
946 else if (unitaS == "mrad")
947 {
948 set_1rad(1e3);
949 }
950 else if (unitS == "eV")
951 {
952 set_1MeV(1e6);
953 }
954 else if (unitS == "KeV")
955 {
956 set_1MeV(1e3);
957 }
958 else if (unitS == "MeV")
959 {
960 set_1MeV(1);
961 }
962 else if (unitS == "GeV")
963 {
964 set_1MeV(1e-3);
965 }
966 else if (unitS == "g/cm^2")
967 {
968 set_1g(1);
969 set_1cm2(1);
970 }
971 else if (unitS == "g/cm^3")
972 {
973 set_1g(1);
974 set_1cm3(1);
975 }
976 else if (unitS == "MeV/g/cm^2")
977 {
978 set_1MeV(1);
979 set_1g(1);
980 set_1cm2(1);
981 }
982 else if (unitS == "Tesla" || unitS == "T")
983 {
984 set_1G(1e-4);
985 }
986 else if (unitS == "kG" || unitS == "kGs")
987 {
988 set_1G(1e-3);
989 }
990 else if (unitS == "G" || unitS == "Gs")
991 {
992 set_1G(1);
993 }
994 else if (unitS == "percent")
995 {
996 ;
997 }
998 else if (unitS == "none")
999 {
1000 ;
1001 }
1002 else
1003 {
1004 XString tagS(el->getTagName());
1005 std::cerr
1006 << APP_NAME"hddsCommon" << " error: unknown unit " << S(unitS)unitS.c_str()
1007 << " on volume " << S(tagS)tagS.c_str() << std::endl;
1008 exit(1);
1009 }
1010}
1011
1012#ifdef LINUX_CPUTIME_PROFILING
1013CPUtimer::CPUtimer()
1014{
1015 getRusage();
1016 gettimeofday(&fClock0,&fTZ);
1017 fClockRef = fClock0;
1018 fRef = fLast;
1019}
1020
1021double CPUtimer::getUserTime()
1022{
1023 if (getRusage() == 0)
1024 {
1025 return fLast.ru_utime.tv_sec + fLast.ru_utime.tv_usec/1e6;
1026 }
1027 else
1028 {
1029 return -1;
1030 }
1031}
1032
1033double CPUtimer::getSystemTime()
1034{
1035 if (getRusage() == 0)
1036 {
1037 return fLast.ru_stime.tv_sec + fLast.ru_stime.tv_usec/1e6;
1038 }
1039 else
1040 {
1041 return -1;
1042 }
1043}
1044
1045double CPUtimer::getRealTime()
1046{
1047 if (getRusage() == 0)
1048 {
1049 return (fClock.tv_sec - fClock0.tv_sec)
1050 +(fClock.tv_usec - fClock0.tv_usec)/1e6;
1051 }
1052 else
1053 {
1054 return -1;
1055 }
1056}
1057
1058double CPUtimer::getUserDelta()
1059{
1060 if (getRusage() == 0)
1061 {
1062 return fLast.ru_utime.tv_sec + fLast.ru_utime.tv_usec/1e6
1063 -(fRef.ru_utime.tv_sec + fRef.ru_utime.tv_usec/1e6);
1064 }
1065 else
1066 {
1067 return -1;
1068 }
1069}
1070
1071double CPUtimer::getSystemDelta()
1072{
1073 if (getRusage() == 0)
1074 {
1075 return fLast.ru_stime.tv_sec + fLast.ru_stime.tv_usec/1e6
1076 -(fRef.ru_stime.tv_sec + fRef.ru_stime.tv_usec/1e6);
1077 }
1078 else
1079 {
1080 return -1;
1081 }
1082}
1083
1084double CPUtimer::getRealDelta()
1085{
1086 if (getRusage() == 0)
1087 {
1088 return (fClock.tv_sec - fClockRef.tv_sec)
1089 +(fClock.tv_usec - fClockRef.tv_usec)/1e6;
1090 }
1091 else
1092 {
1093 return -1;
1094 }
1095}
1096
1097void CPUtimer::resetClocks()
1098{
1099 getRusage();
1100 fRef = fLast;
1101 fClockRef = fClock;
1102}
1103
1104int CPUtimer::getRusage()
1105{
1106 return getrusage(RUSAGE_SELF,&fLast) + gettimeofday(&fClock,&fTZ);
1107}
1108
1109CPUtimer timer;
1110#endif
1111
1112int CodeWriter::createMaterial(DOMElement* el)
1113{
1114 static int imateCount = 0;
1115 int imate = ++imateCount;
1116 std::stringstream imateStr;
1117 imateStr << imate;
1118 el->setAttribute(X("HDDSmate")XString("HDDSmate").unicode_str(),X(imateStr.str())XString(imateStr.str()).unicode_str());
1119
1120 Substance subst(el);
1121 std::list<Substance::Brew>::iterator iter;
1122 for (iter = subst.fBrewList.begin();
1123 iter != subst.fBrewList.end(); ++iter)
1124 {
1125 DOMElement* subEl = iter->sub->getDOMElement();
1126 XString subS(subEl->getAttribute(X("HDDSmate")XString("HDDSmate").unicode_str()));
1127 iter->sub->fUniqueID = atoi(S(subS)subS.c_str());
1128 if (iter->sub->fUniqueID == 0)
1129 {
1130 iter->sub->fUniqueID = createMaterial(subEl);
1131 }
1132 }
1133 fSubst = subst;
1134 return imate;
1135}
1136
1137int CodeWriter::createSolid(DOMElement* el, Refsys& ref)
1138{
1139 XString nameS(el->getAttribute(X("name")XString("name").unicode_str()));
1140 XString matS(el->getAttribute(X("material")XString("material").unicode_str()));
1141
1142 DOMDocument* document = el->getOwnerDocument();
1143 DOMElement* matEl = document->getElementById(X(matS)XString(matS).unicode_str());
1144 if (matEl == 0)
1145 {
1146 std::cerr << APP_NAME"hddsCommon" << " error: material " << S(matS)matS.c_str()
1147 << " is referenced but not defined." << std::endl;
1148 exit(1);
1149 }
1150 XString imateS(matEl->getAttribute(X("HDDSmate")XString("HDDSmate").unicode_str()));
1151 if (imateS.size() != 0)
1152 {
1153 fSubst.fUniqueID = atoi(S(imateS)imateS.c_str());
1154 }
1155 else
1156 {
1157 fSubst.fUniqueID = createMaterial(matEl);
1158 }
1159
1160 int ivolu = ref.nextVolumeID();
1161 std::stringstream ivoluStr;
1162 ivoluStr << ivolu;
1163 el->setAttribute(X("HDDSvolu")XString("HDDSvolu").unicode_str(),X(ivoluStr.str())XString(ivoluStr.str()).unicode_str());
1164 el->setAttribute(X("HDDScopy")XString("HDDScopy").unicode_str(),X("0")XString("0").unicode_str());
1165
1166 return ivolu;
1167}
1168
1169int CodeWriter::createRotation(Refsys& ref)
1170{
1171 if (ref.fRotation < 0)
1172 {
1173 ref.fRotation = ref.nextRotationID();
1174 }
1175 return ref.fRotation;
1176}
1177
1178int CodeWriter::createRegion(DOMElement* el, Refsys& ref)
1179{
1180 int iregion = ref.nextRegionID();
1181
1182 XString regionS(el->getAttribute(X("region")XString("region").unicode_str()));
1183 DOMDocument* document = el->getOwnerDocument();
1184 ref.fRegion = document->getElementById(X(regionS)XString(regionS).unicode_str());
1185 ref.fRegionID = iregion;
1186
1187 double origin[3], angle[3];
1188 XString rotS(el->getAttribute(X("rot")XString("rot").unicode_str()));
1189 std::stringstream listr(rotS);
1190 listr >> angle[0] >> angle[1] >> angle[2];
1191 Units unit;
1192 unit.getConversions(el);
1193 angle[0] /= unit.rad;
1194 angle[1] /= unit.rad;
1195 angle[2] /= unit.rad;
1196 XString xyzS(el->getAttribute(X("origin")XString("origin").unicode_str()));
1197 listr.clear(), listr.str(xyzS);
1198 listr >> origin[0] >> origin[1] >> origin[2];
1199 origin[0] /= unit.cm;
1200 origin[1] /= unit.cm;
1201 origin[2] /= unit.cm;
1202 ref.shift(origin);
1203 ref.rotate(angle);
1204
1205 std::stringstream attStr;
1206 attStr << iregion;
1207 el->setAttribute(X("HDDSregion")XString("HDDSregion").unicode_str(),X(attStr.str())XString(attStr.str()).unicode_str());
1208 DOMElement* regEl = document->createElement(X("HDDSregion")XString("HDDSregion").unicode_str());
1209 regEl->setAttribute(X("id")XString("id").unicode_str(),X(attStr.str())XString(attStr.str()).unicode_str());
1210
1211 attStr.clear(), attStr.str("");
1212 attStr << ref.fMOrigin[0] << " "
1213 << ref.fMOrigin[1] << " "
1214 << ref.fMOrigin[2];
1215 regEl->setAttribute(X("origin")XString("origin").unicode_str(),X(attStr.str())XString(attStr.str()).unicode_str());
1216 attStr.clear(), attStr.str("");
1217 attStr << ref.fMRmatrix[0][0] << " "
1218 << ref.fMRmatrix[0][1] << " "
1219 << ref.fMRmatrix[0][2] << " "
1220 << ref.fMRmatrix[1][0] << " "
1221 << ref.fMRmatrix[1][1] << " "
1222 << ref.fMRmatrix[1][2] << " "
1223 << ref.fMRmatrix[2][0] << " "
1224 << ref.fMRmatrix[2][1] << " "
1225 << ref.fMRmatrix[2][2];
1226 regEl->setAttribute(X("Rmatrix")XString("Rmatrix").unicode_str(),X(attStr.str())XString(attStr.str()).unicode_str());
1227 ref.fRegion->appendChild(regEl);
1228
1229 for (DOMNode* cont = ref.fRegion->getFirstChild();
1230 cont != 0;
1231 cont = cont->getNextSibling())
1232 {
1233 if (cont->getNodeType() == DOMNode::ELEMENT_NODE)
1234 {
1235 XString tagS(((DOMElement*)cont)->getTagName());
1236 if (tagS.find("Bfield") != XString::npos)
1237 {
1238 ref.addIdentifier(XString("map"),iregion,0);
1239 break;
1240 }
1241 }
1242 }
1243 return iregion;
1244}
1245
1246int CodeWriter::createDivision(XString& divStr, Refsys& ref)
1247{
1248 int ncopy = ref.fPartition.ncopy;
1249 int ivolu = ref.nextVolumeID();
1250
1251 assert (ref.fMother != 0)((ref.fMother != 0) ? static_cast<void> (0) : __assert_fail
("ref.fMother != 0", "/group/halld/Software/builds/Linux_RHEL7-x86_64-gcc4.8.5/hdds/hdds-4.14.0^root62404/hddsCommon.cpp"
, 1251, __PRETTY_FUNCTION__))
;
1252
1253 std::stringstream attStr;
1254 DOMDocument* document = ref.fMother->getOwnerDocument();
1255 DOMElement* divEl = document->createElement(X("HDDSdivision")XString("HDDSdivision").unicode_str());
1256 divEl->setAttribute(X("name")XString("name").unicode_str(),X(divStr)XString(divStr).unicode_str());
1257 XString motherS(ref.fMother->getAttribute(X("name")XString("name").unicode_str()));
1258 divEl->setAttribute(X("volume")XString("volume").unicode_str(),X(motherS)XString(motherS).unicode_str());
1259 attStr << ivolu;
1260 divEl->setAttribute(X("HDDSvolu")XString("HDDSvolu").unicode_str(),X(attStr.str())XString(attStr.str()).unicode_str());
1261 std::stringstream copyStr;
1262 copyStr << ncopy;
1263 divEl->setAttribute(X("HDDScopy")XString("HDDScopy").unicode_str(),X(copyStr.str())XString(copyStr.str()).unicode_str());
1264 ref.fMother->appendChild(divEl);
1265 ref.fPartition.divEl = divEl;
1266
1267 std::map<std::string,Refsys::VolIdent>::iterator iter;
1268 for (iter = ref.fIdentifier.begin();
1269 iter != ref.fIdentifier.end();
1270 ++iter)
1271 {
1272 int value = iter->second.value;
1273 int step = iter->second.step;
1274 XString fieldS(iter->first);
1275 std::vector<int>* idlist = &Refsys::fIdentifierTable[ivolu][fieldS];
1276 for (int ic = 0; ic < ncopy; ic++)
1277 {
1278 idlist->push_back(value);
1279 value += step;
1280 }
1281 }
1282 Refsys::fIdentifierTable[ivolu]["copy counter"].push_back(ncopy);
1283 ref.clearIdentifiers();
1284 return ncopy;
1285}
1286
1287int CodeWriter::createVolume(DOMElement* el, Refsys& ref)
1288{
1289 fPending = false;
1290 int icopy = 0;
1291
1292 XString tagS(el->getTagName());
1293 XString nameS(el->getAttribute(X("name")XString("name").unicode_str()));
1294
1295 Refsys myRef(ref);
1296 DOMElement* env = 0;
1297 DOMDocument* document = el->getOwnerDocument();
1298 XString envS(el->getAttribute(X("envelope")XString("envelope").unicode_str()));
1299 if (envS.size() != 0)
1300 {
1301 env = document->getElementById(X(envS)XString(envS).unicode_str());
1302 XString containS(env->getAttribute(X("contains")XString("contains").unicode_str()));
1303 if (containS == nameS)
1304 {
1305 return createVolume(env,myRef);
1306 }
1307 else if (containS.size() != 0)
1308 {
1309 std::cerr
1310 << APP_NAME"hddsCommon" << " error: re-use of shape " << S(envS)envS.c_str()
1311 << " is not allowed by " << APP_NAME"hddsCommon" << std::endl;
1312 exit(1);
1313 }
1314
1315 DOMNode* cont;
1316 for (cont = env->getFirstChild();
1317 cont != 0;
1318 cont = cont->getNextSibling())
1319 {
1320 if (cont->getNodeType() != DOMNode::ELEMENT_NODE)
1321 {
1322 continue;
1323 }
1324 DOMElement* contEl = (DOMElement*) cont;
1325 XString comdS(contEl->getTagName());
1326 if (comdS == "apply")
1327 {
1328 Refsys drs(myRef);
1329 myRef.fRegionID = createRegion(contEl,drs);
1330 myRef.fIdentifier["map"] = drs.fIdentifier["map"];
1331 myRef.fRegion = drs.fRegion;
1332 myRef.fPar = drs.fPar;
1333 }
1334 }
1335
1336 env->setAttribute(X("contains")XString("contains").unicode_str(),X(nameS)XString(nameS).unicode_str());
1337 icopy = createVolume(env,myRef);
1338 myRef.clearIdentifiers();
1339 myRef.fMother = env;
1340 myRef.reset();
1341 }
1342
1343 if (tagS == "intersection" ||
1344 tagS == "subtraction" ||
1345 tagS == "union")
1346 {
1347 std::cerr
1348 << APP_NAME"hddsCommon" << " error: boolean " << S(tagS)tagS.c_str()
1349 << " operator is not supported by "<< APP_NAME"hddsCommon" << std::endl;
1350 exit(1);
1351 }
1352 else if (tagS == "composition")
1353 {
1354 DOMNode* cont;
1355 int nSiblings = 0;
1356 for (cont = el->getFirstChild();
1357 cont != 0;
1358 cont = cont->getNextSibling())
1359 {
1360 if (cont->getNodeType() == DOMNode::ELEMENT_NODE)
1361 {
1362 ++nSiblings;
1363 }
1364 }
1365
1366 for (cont = el->getFirstChild();
1367 cont != 0;
1368 cont = cont->getNextSibling())
1369 {
1370 if (cont->getNodeType() != DOMNode::ELEMENT_NODE)
1371 {
1372 continue;
1373 }
1374 DOMElement* contEl = (DOMElement*) cont;
1375 XString comdS(contEl->getTagName());
1376 XString targS(contEl->getAttribute(X("volume")XString("volume").unicode_str()));
1377 DOMElement* targEl = document->getElementById(X(targS)XString(targS).unicode_str());
1378
1379 Refsys drs(myRef);
1380 double origin[3], angle[3];
1381 XString rotS(contEl->getAttribute(X("rot")XString("rot").unicode_str()));
1382 std::stringstream listr1(rotS);
1383 listr1 >> angle[0] >> angle[1] >> angle[2];
1384 Units unit;
1385 unit.getConversions(contEl);
1386 angle[0] /= unit.rad;
1387 angle[1] /= unit.rad;
1388 angle[2] /= unit.rad;
1389 bool noRotation = (angle[0] == 0) &&
1390 (angle[1] == 0) &&
1391 (angle[2] == 0) ;
1392
1393 DOMNode* ident;
1394 for (ident = cont->getFirstChild();
1395 ident != 0;
1396 ident = ident->getNextSibling())
1397 {
1398 if (ident->getNodeType() != DOMNode::ELEMENT_NODE)
1399 {
1400 continue;
1401 }
1402 DOMElement* identEl = (DOMElement*) ident;
1403 XString fieldS(identEl->getAttribute(X("field")XString("field").unicode_str()));
1404 XString valueS(identEl->getAttribute(X("value")XString("value").unicode_str()));
1405 XString stepS(identEl->getAttribute(X("step")XString("step").unicode_str()));
1406 drs.addIdentifier(fieldS,atoi(S(valueS)valueS.c_str()),atoi(S(stepS)stepS.c_str()));
1407 }
1408
1409 XString geolayerS(contEl->getAttribute(X("geometry_layer")XString("geometry_layer").unicode_str()));
1410 if (geolayerS.size() != 0)
1411 {
1412 std::stringstream geolayerStr(geolayerS);
1413 geolayerStr >> drs.fRelativeLayer;
1414 }
1415 else
1416 {
1417 drs.fRelativeLayer = 0;
1418 }
1419 drs.fGeometryLayer += drs.fRelativeLayer;
1420
1421 if (comdS == "posXYZ")
1422 {
1423 XString xyzS(contEl->getAttribute(X("X_Y_Z")XString("X_Y_Z").unicode_str()));
1424 std::stringstream listr(xyzS);
1425 listr >> origin[0] >> origin[1] >> origin[2];
1426 origin[0] /= unit.cm;
1427 origin[1] /= unit.cm;
1428 origin[2] /= unit.cm;
1429 drs.shift(origin);
1430 drs.rotate(angle);
1431 createVolume(targEl,drs);
1432 }
1433 else if (comdS == "posRPhiZ")
1434 {
1435 double r, phi, z;
1436 XString rphizS(contEl->getAttribute(X("R_Phi_Z")XString("R_Phi_Z").unicode_str()));
1437 std::stringstream listr(rphizS);
1438 listr >> r >> phi >> z;
1439 double s;
1440 XString sS(contEl->getAttribute(X("S")XString("S").unicode_str()));
1441 s = atof(S(sS)sS.c_str());
1442 phi /= unit.rad;
1443 r /= unit.cm;
1444 z /= unit.cm;
1445 s /= unit.cm;
1446 origin[0] = r * cos(phi) - s * sin(phi);
1447 origin[1] = r * sin(phi) + s * cos(phi);
1448 origin[2] = z;
1449 XString implrotS(contEl->getAttribute(X("impliedRot")XString("impliedRot").unicode_str()));
1450 if (implrotS == "true" && (phi != 0))
1451 {
1452 angle[2] += phi;
1453 }
1454 drs.shift(origin);
1455 drs.rotate(angle);
1456 createVolume(targEl,drs);
1457 }
1458 else if (comdS == "mposPhi")
1459 {
1460 XString ncopyS(contEl->getAttribute(X("ncopy")XString("ncopy").unicode_str()));
1461 int ncopy = atoi(S(ncopyS)ncopyS.c_str());
1462 if (ncopy <= 0)
1463 {
1464 std::cerr
1465 << APP_NAME"hddsCommon" << " error: volume " << S(nameS)nameS.c_str()
1466 << " is positioned with " << ncopy << " copies!"
1467 << std::endl;
1468 exit(1);
1469 }
1470
1471 double phi0, dphi;
1472 XString phi0S(contEl->getAttribute(X("Phi0")XString("Phi0").unicode_str()));
1473 phi0 = atof(S(phi0S)phi0S.c_str()) /unit.rad;
1474 XString dphiS(contEl->getAttribute(X("dPhi")XString("dPhi").unicode_str()));
1475 if (dphiS.size() != 0)
1476 {
1477 dphi = atof(S(dphiS)dphiS.c_str()) /unit.rad;
1478 }
1479 else
1480 {
1481 dphi = 2 * M_PI3.14159265358979323846 / ncopy;
1482 }
1483
1484 double r, s, z;
1485 XString rzS(contEl->getAttribute(X("R_Z")XString("R_Z").unicode_str()));
1486 std::stringstream listr(rzS);
1487 listr >> r >> z;
1488 XString sS(contEl->getAttribute(X("S")XString("S").unicode_str()));
1489 s = atof(S(sS)sS.c_str());
1490 r /= unit.cm;
1491 z /= unit.cm;
1492 s /= unit.cm;
1493
1494 XString containerS;
1495 XString containerTypeS;
1496 if (env != 0)
1497 {
1498 containerS = env->getAttribute(X("name")XString("name").unicode_str());
1499 containerTypeS = env->getTagName();
1500 }
1501 else
1502 {
1503 containerS = el->getAttribute(X("container_name")XString("container_name").unicode_str());
1504 containerTypeS = el->getAttribute(X("container_type")XString("container_type").unicode_str());
1505 env = document->getElementById(X(containerS)XString(containerS).unicode_str());
1506 }
1507 XString implrotS(contEl->getAttribute(X("impliedRot")XString("impliedRot").unicode_str()));
1508 XString targTagS(targEl->getTagName());
1509 XString targEnvS(targEl->getAttribute(X("envelope")XString("envelope").unicode_str()));
1510 DOMElement* targEnv;
1511 if (targEnvS.size() != 0)
1512 {
1513 targEnv = document->getElementById(X(targEnvS)XString(targEnvS).unicode_str());
1514 }
1515 else
1516 {
1517 targEnv = targEl;
1518 }
1519 if (noRotation && (nSiblings == 1) &&
1520 (containerTypeS == "pcon" ||
1521 containerTypeS == "cons" ||
1522 containerTypeS == "tubs") &&
1523 (implrotS == "true"))
1524 {
1525 double phiMax, phiMin, dphiM;
1526 XString envProfS(env->getAttribute(X("profile")XString("profile").unicode_str()));
1527 if (envProfS.size() > 0)
1528 {
1529 std::stringstream profstr(envProfS);
1530 profstr >> phiMin >> dphiM;
1531 Units munit;
1532 munit.getConversions(env);
1533 phiMin /= munit.deg;
1534 dphiM /= munit.deg;
1535 phiMax = phiMin + dphiM;
1536 }
1537 else {
1538 phiMin = 0;
1539 phiMax = 360;
1540 }
1541 phi0 *= unit.rad /unit.deg;
1542 dphi *= unit.rad /unit.deg;
1543 double phigap = phi0-phiMin;
1544 double phipull = dphi/2;
1545 if (phiMax < phiMin + 360)
1546 {
1547 phipull = (phipull > phigap)? phigap : phipull;
1548 }
1549 if (phi0 - phipull + ncopy*dphi > phiMax)
1550 {
1551 std::cerr
1552 << APP_NAME"hddsCommon" << " error: volume " << S(nameS)nameS.c_str()
1553 << " overflows " << phiMax
1554 << " degrees when positioned with "
1555 << ncopy << " copies starting at "
1556 << phi0 << " degrees and spaced "
1557 << dphi << " degrees apart."
1558 << std::endl;
1559 exit(1);
1560 }
1561 double phi1=0, dphi1=0;
1562 XString targProfS(targEnv->getAttribute(X("profile")XString("profile").unicode_str()));
1563 if (r == 0 && s == 0 && targProfS.size() > 0)
1564 {
1565 std::stringstream profstr(targProfS);
1566 profstr >> phi1 >> dphi1;
1567 Units tunit;
1568 tunit.getConversions(targEnv);
1569 phi1 /= tunit.deg;
1570 dphi1 /= tunit.deg;
1571 }
1572 if (phipull+phi1 < -0.001 || phipull+phi1+dphi1 > dphi+0.001)
1573 {
1574 std::cerr
1575 << APP_NAME"hddsCommon" << " error: volume " << S(targS)targS.c_str()
1576 << " overflows its sector division of size "
1577 << dphi << " degrees."
1578 << std::endl;
1579 exit(1);
1580 }
1581 static int phiDivisions = 0xd00;
1582 std::stringstream divStr;
1583 divStr << "s" << std::setfill('0') << std::setw(3) << std::hex
1584 << ++phiDivisions;
1585 drs.fPartition.ncopy = ncopy;
1586 drs.fPartition.axis = "phi";
1587 drs.fPartition.start = phi0 - phipull - myRef.fPhiOffset;
1588 drs.fPartition.offset = drs.fPartition.start - phiMin;
1589 drs.fPartition.step = dphi;
1590 XString divS(divStr.str());
1591 createDivision(divS, drs);
1592 drs.fMother = drs.fPartition.divEl;
1593 targEl->setAttribute(X("container_name")XString("container_name").unicode_str(),X(containerS)XString(containerS).unicode_str());
1594 targEl->setAttribute(X("container_type")XString("container_type").unicode_str(),X(containerTypeS)XString(containerTypeS).unicode_str());
1595 drs.reset();
1596
1597 double phioffset = dphi/2 - phipull;
1598 if (fabs(phioffset) > 0.001)
1599 {
1600 angle[0] = 0;
1601 angle[1] = 0;
1602 angle[2] = -phioffset*unit.deg /unit.rad;
1603 drs.rotate(angle);
1604 }
1605 origin[0] = r;
1606 origin[1] = s;
1607 origin[2] = z;
1608 drs.shift(origin);
1609 createVolume(targEl,drs);
1610 }
1611 else
1612 {
1613 Refsys drs0(drs);
1614 drs.rotate(angle);
1615 for (int inst = 0; inst < ncopy; inst++)
1616 {
1617 double phi = phi0 + inst * dphi;
1618 origin[0] = r * cos(phi) - s * sin(phi);
1619 origin[1] = r * sin(phi) + s * cos(phi);
1620 origin[2] = z;
1621 drs.shift(drs0, origin);
1622 if (implrotS == "true")
1623 {
1624 angle[2] += ((inst == 0) ? phi0 : dphi);
1625 drs.rotate(drs0, angle);
1626 }
1627 createVolume(targEl,drs);
1628 drs.incrementIdentifiers();
1629 }
1630 }
1631 }
1632 else if (comdS == "mposR")
1633 {
1634 XString ncopyS(contEl->getAttribute(X("ncopy")XString("ncopy").unicode_str()));
1635 int ncopy = atoi(S(ncopyS)ncopyS.c_str());
1636 if (ncopy <= 0)
1637 {
1638 std::cerr
1639 << APP_NAME"hddsCommon" << " error: volume " << S(nameS)nameS.c_str()
1640 << " is positioned with " << ncopy << " copies!"
1641 << std::endl;
1642 exit(1);
1643 }
1644
1645 double r0, dr;
1646 XString r0S(contEl->getAttribute(X("R0")XString("R0").unicode_str()));
1647 r0 = atof(S(r0S)r0S.c_str()) /unit.cm;
1648 XString drS(contEl->getAttribute(X("dR")XString("dR").unicode_str()));
1649 dr = atof(S(drS)drS.c_str()) /unit.cm;
1650
1651 double phi, z, s;
1652 XString zphiS(contEl->getAttribute(X("Z_Phi")XString("Z_Phi").unicode_str()));
1653 std::stringstream listr(zphiS);
1654 listr >> z >> phi;
1655 XString sS(contEl->getAttribute(X("S")XString("S").unicode_str()));
1656 s = atof(S(sS)sS.c_str());
1657 phi /= unit.rad;
1658 z /= unit.cm;
1659 s /= unit.cm;
1660
1661 XString containerS;
1662 XString containerTypeS;
1663 if (env != 0)
1664 {
1665 containerS = env->getAttribute(X("name")XString("name").unicode_str());
1666 containerTypeS = env->getTagName();
1667 }
1668 else
1669 {
1670 containerS = el->getAttribute(X("container_name")XString("container_name").unicode_str());
1671 containerTypeS = el->getAttribute(X("container_type")XString("container_type").unicode_str());
1672 env = document->getElementById(X(containerS)XString(containerS).unicode_str());
1673 }
1674 if (noRotation && (nSiblings == 1) &&
1675 (containerTypeS == "tubs" ))
1676 {
1677 double rMax, rMin;
1678 XString envRioZS(env->getAttribute(X("Rio_Z")XString("Rio_Z").unicode_str()));
1679 if (envRioZS.size() > 0)
1680 {
1681 std::stringstream riozstr(envRioZS);
1682 riozstr >> rMin >> rMax;
1683 Units munit;
1684 munit.getConversions(env);
1685 rMin /= munit.deg;
1686 rMax /= munit.deg;
Value stored to 'rMax' is never read
1687 // drM = rMax-rMin; commented out to avoid compiler warnings 4/26/2015 DL
1688 }
1689 else
1690 {
1691 std::cerr
1692 << APP_NAME"hddsCommon" << " error: volume " << S(targS)targS.c_str()
1693 << " is missing a Rio_Z attribute."
1694 << std::endl;
1695 exit(1);
1696 }
1697 static int rDivisions = 0xd00;
1698 std::stringstream divStr;
1699 divStr << "r" << std::setfill('0') << std::setw(3) << std::hex
1700 << ++rDivisions;
1701 drs.fPartition.ncopy = ncopy;
1702 drs.fPartition.axis = "rho";
1703 drs.fPartition.start = r0 - dr/2;
1704 drs.fPartition.offset = drs.fPartition.start - rMin;
1705 drs.fPartition.step = dr;
1706 XString divS(divStr.str());
1707 createDivision(divS, drs);
1708 drs.fMother = drs.fPartition.divEl;
1709 targEl->setAttribute(X("container_name")XString("container_name").unicode_str(),X(containerS)XString(containerS).unicode_str());
1710 targEl->setAttribute(X("container_type")XString("container_type").unicode_str(),X(containerTypeS)XString(containerTypeS).unicode_str());
1711 origin[0] = r0 * cos(phi) - s * sin(phi);
1712 origin[1] = r0 * sin(phi) + s * cos(phi);
1713 origin[2] = z;
1714 drs.reset();
1715 drs.shift(origin);
1716 drs.rotate(angle);
1717 createVolume(targEl,drs);
1718 }
1719 else
1720 {
1721 Refsys drs0(drs);
1722 drs.rotate(angle);
1723 for (int inst = 0; inst < ncopy; inst++)
1724 {
1725 double r = r0 + inst * dr;
1726 origin[0] = r * cos(phi) - s * sin(phi);
1727 origin[1] = r * sin(phi) + s * cos(phi);
1728 origin[2] = z;
1729 drs.shift(drs0, origin);
1730 createVolume(targEl,drs);
1731 drs.incrementIdentifiers();
1732 }
1733 }
1734 }
1735 else if (comdS == "mposX")
1736 {
1737 XString ncopyS(contEl->getAttribute(X("ncopy")XString("ncopy").unicode_str()));
1738 int ncopy = atoi(S(ncopyS)ncopyS.c_str());
1739 if (ncopy <= 0)
1740 {
1741 std::cerr
1742 << APP_NAME"hddsCommon" << " error: volume " << S(nameS)nameS.c_str()
1743 << " is positioned with " << ncopy << " copies!"
1744 << std::endl;
1745 exit(1);
1746 }
1747
1748 double x0, dx;
1749 XString x0S(contEl->getAttribute(X("X0")XString("X0").unicode_str()));
1750 x0 = atof(S(x0S)x0S.c_str()) /unit.cm;
1751 XString dxS(contEl->getAttribute(X("dX")XString("dX").unicode_str()));
1752 dx = atof(S(dxS)dxS.c_str()) /unit.cm;
1753
1754 double y, z, s;
1755 XString yzS(contEl->getAttribute(X("Y_Z")XString("Y_Z").unicode_str()));
1756 std::stringstream listr(yzS);
1757 listr >> y >> z;
1758 XString sS(contEl->getAttribute(X("S")XString("S").unicode_str()));
1759 s = atof(S(sS)sS.c_str());
1760 y /= unit.cm;
1761 z /= unit.cm;
1762 s /= unit.cm;
1763
1764 XString containerS;
1765 XString containerTypeS;
1766 if (env != 0)
1767 {
1768 containerS = env->getAttribute(X("name")XString("name").unicode_str());
1769 containerTypeS = env->getTagName();
1770 }
1771 else
1772 {
1773 containerS = el->getAttribute(X("container_name")XString("container_name").unicode_str());
1774 containerTypeS = el->getAttribute(X("container_type")XString("container_type").unicode_str());
1775 env = document->getElementById(X(containerS)XString(containerS).unicode_str());
1776 }
1777 if (noRotation && (nSiblings == 1) &&
1778 containerTypeS == "box")
1779 {
1780 double xMax, xMin;
1781 XString envXYZS(env->getAttribute(X("X_Y_Z")XString("X_Y_Z").unicode_str()));
1782 if (envXYZS.size() > 0)
1783 {
1784 std::stringstream xyzstr(envXYZS);
1785 double hx, hy, hz;
1786 xyzstr >> hx >> hy >> hz;
1787 Units munit;
1788 munit.getConversions(env);
1789 xMax = hx/2 /munit.cm;
1790 xMin = -xMax;
1791 // dxM = hx; commented out to avoid compiler warnings 4/26/2015 DL
1792 }
1793 else
1794 {
1795 std::cerr
1796 << APP_NAME"hddsCommon" << " error: volume " << S(targS)targS.c_str()
1797 << " is missing a X_Y_Z attribute."
1798 << std::endl;
1799 exit(1);
1800 }
1801 static int xDivisions = 0xd00;
1802 std::stringstream divStr;
1803 divStr << "x" << std::setfill('0') << std::setw(3) << std::hex
1804 << ++xDivisions;
1805 drs.fPartition.ncopy = ncopy;
1806 drs.fPartition.axis = "x";
1807 drs.fPartition.start = x0 - dx/2;
1808 drs.fPartition.offset = drs.fPartition.start - xMin;
1809 drs.fPartition.step = dx;
1810 XString divS(divStr.str());
1811 createDivision(divS, drs);
1812 drs.fMother = drs.fPartition.divEl;
1813 targEl->setAttribute(X("container_name")XString("container_name").unicode_str(),X(containerS)XString(containerS).unicode_str());
1814 targEl->setAttribute(X("container_type")XString("container_type").unicode_str(),X(containerTypeS)XString(containerTypeS).unicode_str());
1815 origin[0] = 0;
1816 origin[1] = y + s;
1817 origin[2] = z;
1818 drs.reset();
1819 drs.shift(origin);
1820 drs.rotate(angle);
1821 createVolume(targEl,drs);
1822 }
1823 else
1824 {
1825 Refsys drs0(drs);
1826 drs.rotate(angle);
1827 for (int inst = 0; inst < ncopy; inst++)
1828 {
1829 double x = x0 + inst * dx;
1830 origin[0] = x;
1831 origin[1] = y + s;
1832 origin[2] = z;
1833 drs.shift(drs0, origin);
1834 createVolume(targEl,drs);
1835 drs.incrementIdentifiers();
1836 }
1837 }
1838 }
1839 else if (comdS == "mposY")
1840 {
1841 XString ncopyS(contEl->getAttribute(X("ncopy")XString("ncopy").unicode_str()));
1842 int ncopy = atoi(S(ncopyS)ncopyS.c_str());
1843 if (ncopy <= 0)
1844 {
1845 std::cerr
1846 << APP_NAME"hddsCommon" << " error: volume " << S(nameS)nameS.c_str()
1847 << " is positioned with " << ncopy << " copies!"
1848 << std::endl;
1849 exit(1);
1850 }
1851
1852 double y0, dy;
1853 XString y0S(contEl->getAttribute(X("Y0")XString("Y0").unicode_str()));
1854 y0 = atof(S(y0S)y0S.c_str()) /unit.cm;
1855 XString dyS(contEl->getAttribute(X("dY")XString("dY").unicode_str()));
1856 dy = atof(S(dyS)dyS.c_str()) /unit.cm;
1857
1858 double x, z, s;
1859 XString zxS(contEl->getAttribute(X("Z_X")XString("Z_X").unicode_str()));
1860 std::stringstream listr(zxS);
1861 listr >> z >> x;
1862 XString sS(contEl->getAttribute(X("S")XString("S").unicode_str()));
1863 s = atof(S(sS)sS.c_str());
1864 x /= unit.cm;
1865 z /= unit.cm;
1866 s /= unit.cm;
1867
1868 XString containerS;
1869 XString containerTypeS;
1870 if (env != 0)
1871 {
1872 containerS = env->getAttribute(X("name")XString("name").unicode_str());
1873 containerTypeS = env->getTagName();
1874 }
1875 else
1876 {
1877 containerS = el->getAttribute(X("container_name")XString("container_name").unicode_str());
1878 containerTypeS = el->getAttribute(X("container_type")XString("container_type").unicode_str());
1879 env = document->getElementById(X(containerS)XString(containerS).unicode_str());
1880 }
1881 if (noRotation && (nSiblings == 1) &&
1882 containerTypeS == "box")
1883 {
1884 double yMax, yMin;
1885 XString envXYZS(env->getAttribute(X("X_Y_Z")XString("X_Y_Z").unicode_str()));
1886 if (envXYZS.size() > 0)
1887 {
1888 std::stringstream xyzstr(envXYZS);
1889 double hx, hy, hz;
1890 xyzstr >> hx >> hy >> hz;
1891 Units munit;
1892 munit.getConversions(env);
1893 yMax = hy/2 /munit.cm;
1894 yMin = -yMax;
1895 // dyM = hy; commented out to avoid compiler warnings 4/26/2015 DL
1896 }
1897 else
1898 {
1899 std::cerr
1900 << APP_NAME"hddsCommon" << " error: volume " << S(targS)targS.c_str()
1901 << " is missing a X_Y_Z attribute."
1902 << std::endl;
1903 exit(1);
1904 }
1905 static int yDivisions = 0xd00;
1906 std::stringstream divStr;
1907 divStr << "y" << std::setfill('0') << std::setw(3) << std::hex
1908 << ++yDivisions;
1909 drs.fPartition.ncopy = ncopy;
1910 drs.fPartition.axis = "y";
1911 drs.fPartition.start = y0 - dy/2;
1912 drs.fPartition.offset = drs.fPartition.start - yMin;
1913 drs.fPartition.step = dy;
1914 XString divS(divStr.str());
1915 createDivision(divS, drs);
1916 drs.fMother = drs.fPartition.divEl;
1917 targEl->setAttribute(X("container_name")XString("container_name").unicode_str(),X(containerS)XString(containerS).unicode_str());
1918 targEl->setAttribute(X("container_type")XString("container_type").unicode_str(),X(containerTypeS)XString(containerTypeS).unicode_str());
1919 origin[0] = x + s;
1920 origin[1] = 0;
1921 origin[2] = z;
1922 drs.reset();
1923 drs.shift(origin);
1924 drs.rotate(angle);
1925 createVolume(targEl,drs);
1926 }
1927 else
1928 {
1929 Refsys drs0(drs);
1930 drs.rotate(angle);
1931 for (int inst = 0; inst < ncopy; inst++)
1932 {
1933 double y = y0 + inst * dy;
1934 // double phi = atan2(y,x);
1935 origin[0] = x;
1936 origin[1] = y;
1937 origin[2] = z;
1938 drs.shift(drs0, origin);
1939 createVolume(targEl,drs);
1940 drs.incrementIdentifiers();
1941 }
1942 }
1943 }
1944 else if (comdS == "mposZ")
1945 {
1946 XString ncopyS(contEl->getAttribute(X("ncopy")XString("ncopy").unicode_str()));
1947 int ncopy = atoi(S(ncopyS)ncopyS.c_str());
1948 if (ncopy <= 0)
1949 {
1950 std::cerr
1951 << APP_NAME"hddsCommon" << " error: volume " << S(nameS)nameS.c_str()
1952 << " is positioned with " << ncopy << " copies!"
1953 << std::endl;
1954 exit(1);
1955 }
1956
1957 double z0, dz;
1958 XString z0S(contEl->getAttribute(X("Z0")XString("Z0").unicode_str()));
1959 z0 = atof(S(z0S)z0S.c_str()) /unit.cm;
1960 XString dzS(contEl->getAttribute(X("dZ")XString("dZ").unicode_str()));
1961 dz = atof(S(dzS)dzS.c_str()) /unit.cm;
1962
1963 double x, y, s;
1964 XString xyS(contEl->getAttribute(X("X_Y")XString("X_Y").unicode_str()));
1965 if (xyS.size() > 0)
1966 {
1967 std::stringstream listr(xyS);
1968 listr >> x >> y;
1969 }
1970 else
1971 {
1972 double r, phi;
1973 XString rphiS(contEl->getAttribute(X("R_Phi")XString("R_Phi").unicode_str()));
1974 std::stringstream listr(rphiS);
1975 listr >> r >> phi;
1976 phi /= unit.rad;
1977 x = r * cos(phi);
1978 y = r * sin(phi);
1979 }
1980 XString sS(contEl->getAttribute(X("S")XString("S").unicode_str()));
1981 s = atof(S(sS)sS.c_str());
1982 x /= unit.cm;
1983 y /= unit.cm;
1984 s /= unit.cm;
1985
1986 XString containerS;
1987 XString containerTypeS;
1988 if (env != 0)
1989 {
1990 containerS = env->getAttribute(X("name")XString("name").unicode_str());
1991 containerTypeS = env->getTagName();
1992 }
1993 else
1994 {
1995 containerS = el->getAttribute(X("container_name")XString("container_name").unicode_str());
1996 containerTypeS = el->getAttribute(X("container_type")XString("container_type").unicode_str());
1997 env = document->getElementById(X(containerS)XString(containerS).unicode_str());
1998 }
1999 if (noRotation && (nSiblings == 1) &&
2000 (containerTypeS == "tubs" ||
2001 containerTypeS == "cons" ||
2002 containerTypeS == "pcon" ||
2003 containerTypeS == "pgon" ||
2004 containerTypeS == "box") &&
2005 (containerS.size() != 0))
2006 {
2007 double zMax, zMin;
2008 XString envXYZS(env->getAttribute(X("X_Y_Z")XString("X_Y_Z").unicode_str()));
2009 XString envRioZS(el->getAttribute(X("Rio_Z")XString("Rio_Z").unicode_str()));
2010 XString envRxyZS(el->getAttribute(X("Rxy_Z")XString("Rxy_Z").unicode_str()));
2011 XString envXmpYmpZS(el->getAttribute(X("Xmp_Ymp_Z")XString("Xmp_Ymp_Z").unicode_str()));
2012 if (envXYZS.size() > 0)
2013 {
2014 std::stringstream xyzstr(envXYZS);
2015 double hx, hy, hz;
2016 xyzstr >> hx >> hy >> hz;
2017 Units munit;
2018 munit.getConversions(env);
2019 zMax = hz/2 /munit.cm;
2020 zMin = -zMax;
2021 // dzM = hz; commented out to avoid compiler warnings 4/26/2015 DL
2022 }
2023 else if (envRioZS.size() > 0)
2024 {
2025 std::stringstream riozstr(envRioZS);
2026 double ri, ro, hz;
2027 riozstr >> ri >> ro >> hz;
2028 Units munit;
2029 munit.getConversions(env);
2030 zMax = hz/2 /munit.cm;
2031 zMin = -zMax;
2032 // dzM = hz; commented out to avoid compiler warnings 4/26/2015 DL
2033 }
2034 else if (envRxyZS.size() > 0)
2035 {
2036 std::stringstream xyzstr(envRxyZS);
2037 double rx, ry, hz;
2038 xyzstr >> rx >> ry >> hz;
2039 Units munit;
2040 munit.getConversions(env);
2041 zMax = hz/2 /munit.cm;
2042 zMin = -zMax;
2043 // dzM = hz; commented out to avoid compiler warnings 4/26/2015 DL
2044 }
2045 else if (envXmpYmpZS.size() > 0)
2046 {
2047 std::stringstream xyzstr(envXmpYmpZS);
2048 double xm, xp, ym, yp, hz;
2049 xyzstr >> xm >> xp >> ym >> yp >> hz;
2050 Units munit;
2051 munit.getConversions(env);
2052 zMax = hz/2 /munit.cm;
2053 zMin = -zMax;
2054 // dzM = hz; commented out to avoid compiler warnings 4/26/2015 DL
2055 }
2056 else
2057 {
2058 std::cerr
2059 << APP_NAME"hddsCommon" << " error: volume " << S(targS)targS.c_str()
2060 << " is missing a *_Z attribute."
2061 << std::endl;
2062 exit(1);
2063 }
2064 static int zDivisions = 0xd00;
2065 std::stringstream divStr;
2066 divStr << "z" << std::setfill('0') << std::setw(3) << std::hex
2067 << ++zDivisions;
2068 drs.fPartition.ncopy = ncopy;
2069 drs.fPartition.axis = "z";
2070 drs.fPartition.start = z0 - dz/2;
2071 drs.fPartition.offset = drs.fPartition.start - zMin;
2072 drs.fPartition.step = dz;
2073 XString divS(divStr.str());
2074 createDivision(divS, drs);
2075 drs.fMother = drs.fPartition.divEl;
2076 targEl->setAttribute(X("container_name")XString("container_name").unicode_str(),X(containerS)XString(containerS).unicode_str());
2077 targEl->setAttribute(X("container_type")XString("container_type").unicode_str(),X(containerTypeS)XString(containerTypeS).unicode_str());
2078 double phi = atan2(y,x);
2079 origin[0] = x - s * sin(phi);
2080 origin[1] = y + s * cos(phi);
2081 origin[2] = 0;
2082 drs.reset();
2083 drs.shift(origin);
2084 drs.rotate(angle);
2085 createVolume(targEl,drs);
2086 }
2087 else
2088 {
2089 Refsys drs0(drs);
2090 drs.rotate(angle);
2091 double phi = atan2(y,x);
2092 origin[0] = x - s * sin(phi);
2093 origin[1] = y + s * cos(phi);
2094 for (int inst = 0; inst < ncopy; inst++)
2095 {
2096 double z = z0 + inst * dz;
2097 origin[2] = z;
2098 drs.shift(drs0, origin);
2099 createVolume(targEl,drs);
2100 drs.incrementIdentifiers();
2101 }
2102 }
2103 }
2104 else if (comdS == "apply")
2105 {
2106 myRef.fRegionID = createRegion(contEl,drs);
2107 myRef.fIdentifier["map"] = drs.fIdentifier["map"];
2108 myRef.fRegion = drs.fRegion;
2109 myRef.fPar = drs.fPar;
2110 }
2111 else
2112 {
2113 std::cerr
2114 << APP_NAME"hddsCommon" << " error: composition of volume " << S(nameS)nameS.c_str()
2115 << " contains unknown tag " << S(comdS)comdS.c_str() << std::endl;
2116 exit(1);
2117 }
2118 }
2119 }
2120 else if (tagS == "stackX" ||
2121 tagS == "stackY" ||
2122 tagS == "stackZ")
2123 {
2124 std::cerr
2125 << APP_NAME"hddsCommon" << " error: stacks are not supported by " << APP_NAME"hddsCommon"
2126 << std::endl
2127 << "Use compositions instead." << std::endl;
2128 exit(1);
2129 }
2130 else
2131 {
2132 XString icopyS(el->getAttribute(X("HDDScopy")XString("HDDScopy").unicode_str()));
2133 if (icopyS.size() != 0)
2134 {
2135 icopy = atoi(S(icopyS)icopyS.c_str());
2136 }
2137 else
2138 {
2139 XString profS(el->getAttribute(X("profile")XString("profile").unicode_str()));
2140 if (profS.size() != 0)
2141 {
2142 double phi0, dphi;
2143 std::stringstream listr(profS);
2144 listr >> phi0 >> dphi;
2145 Units punit;
2146 punit.getConversions(el);
2147 phi0 /= punit.deg;
2148 dphi /= punit.deg;
2149 if ( (myRef.fOrigin[0] == 0) && (myRef.fOrigin[1] == 0) )
2150 {
2151 phi0 -= myRef.fPhiOffset;
2152 }
2153 std::stringstream pStr;
2154 pStr << phi0 << " " << dphi;
2155 el->setAttribute(X("profile")XString("profile").unicode_str(),X(pStr.str())XString(pStr.str()).unicode_str());
2156 }
2157 createSolid(el,myRef);
2158 icopy = 0;
2159 }
2160
2161 if (myRef.fMother != 0)
2162 {
2163 createRotation(myRef);
2164 fPending = true;
2165 fRef = myRef;
2166 ++icopy;
2167 }
2168
2169 std::stringstream icopyStr;
2170 icopyStr << icopy;
2171 el->setAttribute(X("HDDScopy")XString("HDDScopy").unicode_str(),X(icopyStr.str())XString(icopyStr.str()).unicode_str());
2172 XString voluS(el->getAttribute(X("HDDSvolu")XString("HDDSvolu").unicode_str()));
2173 int ivolu = atoi(S(voluS)voluS.c_str());
2174 std::map<std::string,Refsys::VolIdent>::iterator iter;
2175 for (iter = myRef.fIdentifier.begin();
2176 iter != myRef.fIdentifier.end();
2177 ++iter)
2178 {
2179 XString fieldS(iter->first);
2180 std::vector<int>* idlist = &Refsys::fIdentifierTable[ivolu][fieldS];
2181 while (idlist->size() < (unsigned int)icopy-1)
2182 {
2183 idlist->push_back(0);
2184 }
2185 idlist->push_back(iter->second.value);
2186 }
2187 Refsys::fIdentifierTable[ivolu]["copy counter"].push_back(icopy);
2188 }
2189 return icopy;
2190}
2191
2192void CodeWriter::createHeader()
2193{
2194}
2195
2196void CodeWriter::createTrailer()
2197{
2198}
2199
2200void CodeWriter::createSetFunctions(DOMElement* el, const XString& ident)
2201{
2202 NOT_USED(el)((void)(el));
2203 NOT_USED(ident)((void)(ident));
2204}
2205
2206void CodeWriter::createGetFunctions(DOMElement* el, const XString& ident)
2207{
2208 NOT_USED(el)((void)(el));
2209 NOT_USED(ident)((void)(ident));
2210}
2211
2212void CodeWriter::createMapFunctions(DOMElement* el, const XString& ident)
2213{
2214 NOT_USED(el)((void)(el));
2215 NOT_USED(ident)((void)(ident));
2216}
2217
2218void CodeWriter::createUtilityFunctions(DOMElement* el, const XString& ident)
2219{
2220 NOT_USED(el)((void)(el));
2221 NOT_USED(ident)((void)(ident));
2222}
2223
2224void CodeWriter::translate(DOMElement* topel)
2225{
2226 Refsys mrs;
2227 createHeader();
2228 createVolume(topel,mrs);
2229 createTrailer();
2230
2231 DOMNodeList* propL = topel->getOwnerDocument()
2232 ->getElementsByTagName(X("optical_properties")XString("optical_properties").unicode_str());
2233 for (unsigned int iprop=0; iprop < propL->getLength(); ++iprop)
2234 {
2235 DOMElement* propEl = (DOMElement*)propL->item(iprop);
2236 DOMElement* matEl = (DOMElement*)propEl->getParentNode();
2237 XString imateS(matEl->getAttribute(X("HDDSmate")XString("HDDSmate").unicode_str()));
2238 if (imateS.size() > 0)
2239 {
2240 createSetFunctions(propEl,imateS);
2241 }
2242 }
2243
2244 std::map<std::string,Refsys::VolIdent>::iterator iter;
2245 for (iter = mrs.fIdentifiers.begin();
2246 iter != mrs.fIdentifiers.end(); ++iter)
2247 {
2248 createGetFunctions(topel, iter->first);
2249 }
2250
2251 DOMNodeList* regionsL = topel->getOwnerDocument()
2252 ->getElementsByTagName(X("regions")XString("regions").unicode_str());
2253 createMapFunctions((DOMElement*)regionsL->item(0),XString("map"));
2254
2255 createUtilityFunctions(topel,XString("user"));
2256}
2257
2258void CodeWriter::dump(DOMElement* el, int level=0) // useful debug function
2259{
2260 XString tagS(el->getTagName());
2261 for (int i=0; i<level; i++)
2262 {
2263 std::cerr << " ";
2264 }
2265 std::cerr << "<" << tagS;
2266 DOMNamedNodeMap* attribL = el->getAttributes();
2267 for (unsigned int i=0; i < attribL->getLength(); i++)
2268 {
2269 XString nameS(attribL->item(i)->getNodeName());
2270 XString valueS(attribL->item(i)->getNodeValue());
2271 std::cerr << " " << nameS << "=\"" << valueS << "\"";
2272 }
2273 int n=0;
2274 for (DOMNode* cont = el->getFirstChild();
2275 cont != 0;
2276 cont = cont->getNextSibling())
2277 {
2278 if (cont->getNodeType() == DOMNode::ELEMENT_NODE)
2279 {
2280 ++n;
2281 }
2282 }
2283 if (n > 0)
2284 {
2285 std::cerr << ">" << std::endl;
2286 for (DOMNode* cont = el->getFirstChild();
2287 cont != 0;
2288 cont = cont->getNextSibling())
2289 {
2290 if (cont->getNodeType() == DOMNode::ELEMENT_NODE)
2291 {
2292 dump((DOMElement*)cont,level+1);
2293 }
2294 }
2295 for (int i=0; i<level; i++)
2296 {
2297 std::cerr << " ";
2298 }
2299 std::cerr << "</" << tagS << ">" << std::endl;
2300 }
2301 else
2302 {
2303 std::cerr << "/>" << std::endl;
2304 }
2305}