Revision 4fd44c7b3c641895603c91ef130c3d3b10b80eef authored by Axel Naumann on 07 February 2014, 22:40:52 UTC, committed by Axel Naumann on 07 February 2014, 22:41:59 UTC
(cherry picked from commit f5b530ffcaba9cd95b1aafef268bcd5904ba3718)
1 parent 5e1543d
writer.py
# @(#)root/gdml:$Id$
# Author: Witold Pokorski 05/06/2006
# This is the application-independent part of the GDML 'writer' implementation.
# It contains the 'writeFile' method (at the end of the file) which does the actual
# formating and writing out of the GDML file as well as the specialized 'add-element'
# methods for all the supported GDML elements. These methods are used to build
# the content of the GDML document, which is then generatd using the 'writeFile' method.
# The constructor of this class takes the output file (.gdml) as argument.
# An instance of this class should be passed to the constructor of application-specific
# 'writer binding' (in the present case ROOTwriter) as argument.
# For any question or remarks concerning this code, please send an email to
# Witold.Pokorski@cern.ch.
class writer(object):
def __init__(self, fname):
self.gdmlfile = fname
self.define = ['define',{},[]]
self.materials = ['materials',{},[]]
self.solids = ['solids',{},[]]
self.structure = ['structure',{},[]]
self.document = ['gdml',{'xmlns:gdml':"http://cern.ch/2001/Schemas/GDML",
'xmlns:xsi':"http://www.w3.org/2001/XMLSchema-instance",
'xsi:noNamespaceSchemaLocation':"gdml.xsd"},
[self.define, self.materials, self.solids, self.structure]]
def addPosition(self, name, x, y, z):
self.define[2].append(['position',{'name':name, 'x':x, 'y':y, 'z':z, 'unit':'cm'},[]])
def addRotation(self, name, x, y, z):
self.define[2].append(['rotation',{'name':name, 'x':x, 'y':y, 'z':z, 'unit':'deg'},[]])
def addMaterial(self, name, a, z, rho):
self.materials[2].append(['material', {'name':name, 'Z':z},
[['D',{'value':rho},[]], ['atom',{'value':a},[]]] ] )
def addMixture(self, name, rho, elems):
subel = [ ['D',{'value':rho},[]] ]
for el in elems.keys():
subel.append(['fraction',{'n':elems[el],'ref':el}, []])
self.materials[2].append(['material',{'name':name},
subel])
def addElement(self, symb, name, z, a):
self.materials[2].append(['element', {'name':name, 'formula':symb, 'Z':z},
[['atom', {'value':a},[]] ]])
def addReflSolid(self, name, solid, dx, dy, dz, sx, sy, sz, rx, ry, rz):
self.solids[2].append(['reflectedSolid',{'name':name, 'solid':solid, 'dx':dx, 'dy':dy, 'dz':dz, 'sx':sx, 'sy':sy, 'sz':sz, 'rx':rx, 'ry':ry, 'rz':rz},[]])
def addBox(self, name, dx, dy, dz):
self.solids[2].append(['box',{'name':name, 'x':dx, 'y':dy, 'z':dz, 'lunit':'cm'},[]])
def addParaboloid(self, name, rlo, rhi, dz):
self.solids[2].append(['paraboloid',{'name':name, 'rlo':rlo, 'rhi':rhi, 'dz':dz, 'lunit':'cm'},[]])
def addArb8(self, name, v1x, v1y, v2x, v2y, v3x, v3y, v4x, v4y, v5x, v5y, v6x, v6y, v7x, v7y, v8x, v8y, dz):
self.solids[2].append(['arb8',{'name':name, 'v1x':v1x, 'v1y':v1y, 'v2x':v2x, 'v2y':v2y, 'v3x':v3x, 'v3y':v3y, 'v4x':v4x, 'v4y':v4y, 'v5x':v5x, 'v5y':v5y, 'v6x':v6x, 'v6y':v6y, 'v7x':v7x, 'v7y':v7y, 'v8x':v8x, 'v8y':v8y, 'dz':dz, 'lunit':'cm'},[]])
def addSphere(self, name, rmin, rmax, startphi, deltaphi, starttheta, deltatheta):
self.solids[2].append(['sphere',{'name':name, 'rmin':rmin, 'rmax':rmax,
'startphi':startphi, 'deltaphi':deltaphi,
'starttheta':starttheta, 'deltatheta':deltatheta,
'aunit':'deg', 'lunit':'cm'},[]])
def addCone(self, name, z, rmin1, rmin2, rmax1, rmax2, sphi, dphi):
self.solids[2].append(['cone',{'name':name, 'z':z, 'rmin1':rmin1, 'rmin2':rmin2,
'rmax1':rmax1, 'rmax2':rmax2,
'startphi':sphi, 'deltaphi':dphi, 'lunit':'cm', 'aunit':'deg'}, []] )
def addPara(self, name, x, y, z, alpha, theta, phi):
self.solids[2].append(['para',{'name':name, 'x':x, 'y':y, 'z':z,
'alpha':alpha, 'theta':theta, 'phi':phi, 'lunit':'cm', 'aunit':'deg'}, []] )
def addTrap(self, name, z, theta, phi, y1, x1, x2, alpha1, y2, x3, x4, alpha2):
self.solids[2].append(['trap', {'name':name, 'z':z, 'theta':theta, 'phi':phi,
'x1':x1, 'x2':x2, 'x3':x3, 'x4':x4,
'y1':y1, 'y2':y2, 'alpha1':alpha1, 'alpha2':alpha2, 'lunit':'cm', 'aunit':'deg'}, []])
def addTwistedTrap(self, name, z, theta, phi, y1, x1, x2, alpha1, y2, x3, x4, alpha2, twist):
self.solids[2].append(['twistTrap', {'name':name, 'z':z, 'theta':theta, 'phi':phi,
'x1':x1, 'x2':x2, 'x3':x3, 'x4':x4,
'y1':y1, 'y2':y2, 'alpha1':alpha1, 'alpha2':alpha2, 'twist':twist, 'aunit':'deg', 'lunit':'cm'}, []])
def addTrd(self, name, x1, x2, y1, y2, z):
self.solids[2].append(['trd',{'name':name, 'x1':x1, 'x2':x2,
'y1':y1, 'y2':y2, 'z':z, 'lunit':'cm'}, []])
def addTube(self, name, rmin, rmax, z, startphi, deltaphi):
self.solids[2].append(['tube',{'name':name, 'rmin':rmin, 'rmax':rmax,
'z':z, 'startphi':startphi, 'deltaphi':deltaphi, 'lunit':'cm', 'aunit':'deg'},[]])
def addCutTube(self, name, rmin, rmax, z, startphi, deltaphi, lowX, lowY, lowZ, highX, highY, highZ):
self.solids[2].append(['cutTube',{'name':name, 'rmin':rmin, 'rmax':rmax,
'z':z, 'startphi':startphi, 'deltaphi':deltaphi,
'lowX':lowX, 'lowY':lowY, 'lowZ':lowZ, 'highX':highX, 'highY':highY, 'highZ':highZ, 'lunit':'cm', 'aunit':'deg'},[]])
def addPolycone(self, name, startphi, deltaphi, zplanes):
zpls = []
for zplane in zplanes:
zpls.append( ['zplane',{'z':zplane[0], 'rmin':zplane[1], 'rmax':zplane[2]},[]] )
self.solids[2].append(['polycone',{'name':name,
'startphi':startphi, 'deltaphi':deltaphi, 'lunit':'cm', 'aunit':'deg'}, zpls])
def addTorus(self, name, r, rmin, rmax, startphi, deltaphi):
self.solids[2].append( ['torus',{'name':name, 'rtor':r, 'rmin':rmin, 'rmax':rmax,
'startphi':startphi, 'deltaphi':deltaphi, 'lunit':'cm', 'aunit':'deg'},[]] )
def addPolyhedra(self, name, startphi, deltaphi, numsides, zplanes):
zpls = []
for zplane in zplanes:
zpls.append( ['zplane',{'z':zplane[0], 'rmin':zplane[1], 'rmax':zplane[2]},[]] )
self.solids[2].append(['polyhedra',{'name':name,
'startphi':startphi, 'deltaphi':deltaphi,
'numsides':numsides, 'lunit':'cm', 'aunit':'deg'}, zpls])
def addXtrusion(self, name, vertices, sections):
elems = []
for vertex in vertices:
elems.append( ['twoDimVertex',{'x':vertex[0], 'y':vertex[1]},[]] )
for section in sections:
elems.append( ['section',{'zOrder':section[0], 'zPosition':section[1], 'xOffset':section[2], 'yOffset':section[3], 'scalingFactor':section[4]},[]] )
self.solids[2].append(['xtru',{'name':name, 'lunit':'cm'}, elems])
def addEltube(self, name, x, y, z):
self.solids[2].append( ['eltube', {'name':name, 'dx':x, 'dy':y, 'dz':z, 'lunit':'cm'},[]] )
def addHype(self, name, rmin, rmax, inst, outst, z):
self.solids[2].append( ['hype', {'name':name, 'rmin':rmin, 'rmax':rmax,
'inst':inst, 'outst':outst, 'z':z, 'lunit':'cm', 'aunit':'deg'},[]] )
def addPos(self, subels, type, name, v):
if v[0]!=0.0 or v[1]!=0.0 or v[2]!=0.0:
subels.append( [type,{'name':name, 'x':v[0], 'y':v[1], 'z':v[2], 'unit':'cm'},[]] )
def addRot(self, subels, type, name, v):
if v[0]!=0.0 or v[1]!=0.0 or v[2]!=0.0:
subels.append( [type,{'name':name, 'x':v[0], 'y':v[1], 'z':v[2], 'unit':'deg'},[]] )
def addUnion(self, name, lname, ltr, lrot, rname, rtr, rrot):
subels = [['first',{'ref':lname},[]],
['second',{'ref':rname},[]]]
self.addPos(subels, 'position', rname+'pos', rtr)
self.addRot(subels, 'rotation', rname+'rot', rrot)
self.addPos(subels, 'firstposition', lname+'pos', ltr)
self.addRot(subels, 'firstrotation', lname+'rot', lrot)
self.solids[2].append( ['union',{'name':name}, subels])
def addSubtraction(self, name, lname, ltr, lrot, rname, rtr, rrot):
subels = [['first',{'ref':lname},[]],
['second',{'ref':rname},[]]]
self.addPos(subels, 'position', rname+'pos', rtr)
self.addRot(subels, 'rotation', rname+'rot', rrot)
self.addPos(subels, 'firstposition', lname+'pos', ltr)
self.addRot(subels, 'firstrotation', lname+'rot', lrot)
self.solids[2].append( ['subtraction',{'name':name}, subels])
def addIntersection(self, name, lname, ltr, lrot, rname, rtr, rrot):
subels = [['first',{'ref':lname},[]],
['second',{'ref':rname},[]]]
self.addPos(subels, 'position', rname+'pos', rtr)
self.addRot(subels, 'rotation', rname+'rot', rrot)
self.addPos(subels, 'firstposition', lname+'pos', ltr)
self.addRot(subels, 'firstrotation', lname+'rot', lrot)
self.solids[2].append( ['intersection',{'name':name}, subels])
def addVolume(self, volume, solid, material, daughters):
subels = [['materialref',{'ref':material},[]],
['solidref',{'ref':solid},[]]]
for child in daughters:
subsubels = [['volumeref',{'ref':child[0]},[]],
['positionref',{'ref':child[1]},[]]]
if child[2]!='':
subsubels.append( ['rotationref',{'ref':child[2]},[]] )
subels.append( ['physvol',{}, subsubels])
used = 0
self.structure[2].append(['volume',{'name':volume}, subels, used])
def addAssembly(self, volume, daughters):
subels = []
for child in daughters:
subsubels = [['volumeref',{'ref':child[0]},[]],
['positionref',{'ref':child[1]},[]]]
if child[2]!='':
subsubels.append( ['rotationref',{'ref':child[2]},[]] )
subels.append( ['physvol',{}, subsubels])
self.structure[2].append(['assembly',{'name':volume}, subels])
def addSetup(self, name, version, world):
self.document[2].append( ['setup',{'name':name, 'version':version},
[ ['world',{'ref':world},[]]] ] )
def writeFile(self):
file = open(self.gdmlfile,'w')
offset = ''
def writeElement(elem, offset):
offset = offset + ' '
file.write(offset+'<%s' %(elem[0]))
for attr in elem[1].keys():
file.write(' %s="%s"' %(attr,elem[1][attr]))
if elem[2].__len__()>0:
file.write('>\n')
for subel in elem[2]:
writeElement(subel, offset)
file.write(offset+'</%s>\n' %(elem[0]))
else:
file.write('/>\n')
file.write('<?xml version="1.0" encoding="UTF-8" ?>\n')
writeElement(self.document,'')
![swh spinner](/static/img/swh-spinner.gif)
Computing file changes ...