"git@code.ihep.ac.cn:cinema-developers/xerces-c.git" did not exist on "f341d03277e145a38b4497477152cd0cdd61806f"
Newer
Older
# ==========================================================================
# AIDA Detector description implementation
# --------------------------------------------------------------------------
# Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
Markus Frank
committed
# All rights reserved.
#
# For the licensing terms see $DD4hepINSTALL/LICENSE.
# For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
#
# ==========================================================================
from __future__ import absolute_import, unicode_literals
import xml.etree.ElementTree as xml
from math import cos, sin, pi, tan
from os import path, listdir
Pere Mato
committed
from functools import partial
from ROOT import SetOwnership, dd4hep, TGeoMixture, TGeoMedium, gGeoManager, TNamed
logging.basicConfig(format='%(levelname)s: %(message)s')
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
Detector = dd4hep.Geometry.Detector
Constant = dd4hep.Geometry.Constant
Material = dd4hep.Geometry.Material
VisAttr = dd4hep.Geometry.VisAttr
Box = dd4hep.Geometry.Box
Tube = dd4hep.Geometry.Tube
Trapezoid = dd4hep.Geometry.Trapezoid
Volume = dd4hep.Geometry.Volume
Position = dd4hep.Geometry.Position
Rotation = dd4hep.Geometry.Rotation
Handle = dd4hep.Geometry.Handle
Readout = dd4hep.Geometry.Readout
GridXYZ = dd4hep.Geometry.GridXYZ
GlobalGridXY = dd4hep.Geometry.GlobalGridXY
CartesianGridXY = dd4hep.Geometry.CartesianGridXY
NoSegmentation = dd4hep.Geometry.NoSegmentation
GridPhiEta = dd4hep.Geometry.GridPhiEta
GridRPhiEta = dd4hep.Geometry.GridRPhiEta
ProjectiveCylinder = dd4hep.Geometry.ProjectiveCylinder
NonProjectiveCylinder = dd4hep.Geometry.NonProjectiveCylinder
ProjectiveZPlane = dd4hep.Geometry.ProjectiveZPlane
IDDescriptor = dd4hep.Geometry.IDDescriptor
_toDictionary = dd4hep.Geometry._toDictionary
unique_mat_id = 0x7FFEFEED
constants = {}
constants.update(SystemOfUnits.__dict__)
Pere Mato
committed
constants.update(math.__dict__)
drivers = {}
drivers.update(math.__dict__)
# ---Enhancing the Element class with dedicated accessors--------------------------
def _getInt(self, attrib): return int(eval(self.get(attrib).replace('(int)', ''), constants))
def _getFloat(self, *attrib):
Pere Mato
committed
sval = self.get(attrib[0], None)
if not sval and len(attrib) > 1:
return attrib[1]
else:
return float(eval(sval.replace('(int)', ''), constants))
def _getBool(self, attrib):
return self.get(attrib, '').lower() in ('true', 'yes', 'on')
xml._ElementInterface.getI = _getInt
xml._ElementInterface.getF = _getFloat
xml._ElementInterface.getB = _getBool
Pere Mato
committed
xml._ElementInterface.name = property(lambda self: self.get('name'))
xml._ElementInterface.type = property(lambda self: self.get('type'))
xml._ElementInterface.vis = property(lambda self: self.get('vis'))
xml._ElementInterface.ref = property(lambda self: self.get('ref'))
xml._ElementInterface.value = property(lambda self: self.getF('value'))
Pere Mato
committed
xml._ElementInterface.material = property(lambda self: self.get('material'))
xml._ElementInterface.module = property(lambda self: self.get('module'))
xml._ElementInterface.id = property(lambda self: self.getI('id'))
xml._ElementInterface.number = property(lambda self: self.getI('number'))
xml._ElementInterface.x1 = property(lambda self: self.getF('x1'))
xml._ElementInterface.x2 = property(lambda self: self.getF('x2'))
xml._ElementInterface.x = property(lambda self: self.getF('x'))
xml._ElementInterface.y = property(lambda self: self.getF('y'))
xml._ElementInterface.z = property(lambda self: self.getF('z'))
Pere Mato
committed
xml._ElementInterface.zstart = property(lambda self: self.getF('zstart'))
xml._ElementInterface.offset = property(lambda self: self.getF('offset'))
xml._ElementInterface.radius = property(lambda self: self.getF('radius'))
xml._ElementInterface.zhalf = property(lambda self: self.getF('zhalf'))
Pere Mato
committed
xml._ElementInterface.phi0 = property(lambda self: self.getF('phi0'))
xml._ElementInterface.r = property(lambda self: self.getF('r'))
xml._ElementInterface.dz = property(lambda self: self.getF('dz'))
Pere Mato
committed
xml._ElementInterface.thickness = property(lambda self: self.getF('thickness'))
xml._ElementInterface.length = property(lambda self: self.getF('length'))
xml._ElementInterface.width = property(lambda self: self.getF('width'))
xml._ElementInterface.inner_r = property(lambda self: self.getF('inner_r'))
xml._ElementInterface.outer_r = property(lambda self: self.getF('outer_r'))
xml._ElementInterface.z_length = property(lambda self: self.getF('z_length'))
xml._ElementInterface.rmin = property(lambda self: self.getF('rmin'))
xml._ElementInterface.rmax = property(lambda self: self.getF('rmax'))
def getRotation(rot):
if rot is not None:
return Rotation(rot.getF('x', 0.0), rot.getF('y', 0.0), rot.getF('z', 0.0))
else:
return Rotation()
Pere Mato
committed
if pos is not None:
return Position(pos.getF('x', 0.0), pos.getF('y', 0.0), pos.getF('z', 0.0))
else:
return Position()
Pere Mato
committed
drivers['getRotation'] = getRotation
drivers['getPosition'] = getPosition
Pere Mato
committed
# ---------------------------------------------------------------------------------
args = [path.join(path.dirname(__file__), 'drivers')]
for arg in args:
if path.exists(arg):
if path.isfile(arg):
Marko Petric
committed
logger.info("Loading driver file ... %s" % arg)
execfile(arg, drivers)
elif path.isdir(arg):
if path.splitext(f)[1] == '.py':
logger.info("Loading driver file ... %s" % path.join(arg, f))
execfile(path.join(arg, f), drivers)
else:
raise "Path '%s' is not a directory or file" % arg
else:
raise "Path '%s' does not exists" % arg
# ---------------------------------------------------------------------------------
file = file.replace('file:', '')
root = xml.parse(file).getroot()
Pere Mato
committed
tags = ('includes', 'define', 'materials', 'properties', 'limits', 'display',
'readouts', 'detectors', 'alignments', 'fields', 'sensitive_detectors')
Pere Mato
committed
for tag in tags:
for e in root.findall(tag):
Pere Mato
committed
def process_tag(description, elem):
if elem.tag == 'detectors':
description.init() # call init before processing 'detectors' (need world volume)
procs = globals().get('process_%s' % elem.tag, None)
if not procs:
procs = drivers.get('process_%s' % elem.tag, None)
if procs:
apply(procs, (description, elem))
else:
logger.info('XML tag %s not processed!!! No function found.' % elem.tag)
# --------------------------------------------------------------------------------
Marko Petric
committed
logger.info('Converting Compact file: %s', xmlfile)
process_xmlfile(description, xmlfile)
return description
# ---------------------------------------------------------------------------------
Marko Petric
committed
logger.info('Adding Gdml file ... %s', c.get('ref'))
fname = c.get('ref').replace('file:', '')
if not path.isabs(fname):
fname = path.join(path.dirname(current_xmlfile), fname)
Marko Petric
committed
logger.info('Adding PyBuilder ... %s', c.get('ref'))
Pere Mato
committed
fname = c.get('ref')
if not path.isabs(fname):
fname = path.join(path.dirname(current_xmlfile), fname)
Pere Mato
committed
load_drivers(fname)
Pere Mato
committed
for c in elem.findall('alignment'):
Marko Petric
committed
logger.info('Adding Alignment file ... %s', c.get('ref'))
fname = c.get('ref').replace('file:', '')
if not path.isabs(fname):
fname = path.join(path.dirname(current_xmlfile), fname)
Pere Mato
committed
# ---------------------------------------------------------------------------------
Pere Mato
committed
pass
# ---------------------------------------------------------------------------------
for c in elem.findall('constant'):
description.addConstant(Constant(c.get('name'), c.get('value')))
_toDictionary(c.get('name'), c.get('value')) # -- Make it known to the evaluator
constants[c.get('name')] = c.getF('value')
# ---------------------------------------------------------------------------------
ename = elem.get('name')
Pere Mato
committed
tab = gGeoManager.GetElementTable()
element = tab.FindElement(ename)
if not element:
atom = elem.find('atom')
tab.AddElement(atom.get('name'), atom.get('formula'), atom.getI('Z'), atom.getI('value'))
# ---------------------------------------------------------------------------------
for m in elem.findall('material'):
# ---------------------------------------------------------------------------------
# <material formula="Ac" name="Actinium" state="solid" >
# <RL type="X0" unit="cm" value="0.601558" />
# <NIL type="lambda" unit="cm" value="21.2048" />
# <D type="density" unit="g/cm3" value="10.07" />
# <composite n="1" ref="Ac" />
# </material>
# <material name="G10">
# <D type="density" value="1.7" unit="g/cm3"/>
# <fraction n="0.08" ref="Cl"/>
# <fraction n="0.773" ref="Quartz"/>
# <fraction n="0.147" ref="Epoxy"/>
radlen = m.find('RL')
intlen = m.find('NIL')
composites = m.findall('fraction') or m.findall('composite')
Pere Mato
committed
table = gGeoManager.GetElementTable()
mat = TGeoMixture(m.name, len(composites), eval(density.get(
'value') + '*' + density.get('unit') + '/(g/cm3)', constants))
SetOwnership(mat, False)
rl = (radlen is not None) and eval(radlen.get('value') + '*' + radlen.get('unit'), constants) or 0.0
il = (intlen is not None) and eval(intlen.get('value') + '*' + intlen.get('unit'), constants) or 0.0
elts = [mat.GetElement(i).GetName() for i in range(mat.GetNelements())]
for c in composites:
if c.tag == 'composite':
fraction = c.getI('n')
elif c.tag == 'fraction':
fraction = c.getF('n')
if table.FindElement(nam):
mat.AddElement(table.FindElement(nam), fraction)
Pere Mato
committed
elif gGeoManager.GetMaterial(nam):
mat.AddElement(gGeoManager.GetMaterial(nam), fraction)
else:
raise 'Something going very wrong. Undefined material:' + nam
if not medium:
global unique_mat_id
unique_mat_id = unique_mat_id - 1
SetOwnership(medium, False)
medium.SetTitle('material')
medium.SetUniqueID(unique_mat_id)
# ----------------------------------------------------------------------------------
for v in elem.findall('vis'):
r, g, b = 1., 1., 1.
if 'r' in v.keys():
r = v.getF('r')
if 'g' in v.keys():
g = v.getF('g')
if 'b' in v.keys():
b = v.getF('b')
visattr.setColor(r, g, b)
if 'showDaughters' in v.keys():
visattr.setShowDaughters(v.getB('showDaughters'))
if 'visible' in v.keys():
visattr.setVisible(v.getB('visible'))
if 'alpha' in v.keys():
visattr.setAlpha(v.getF('alpha'))
if 'lineStyle' in v.keys():
Pere Mato
committed
ls = v.get('lineStyle')
if ls == 'unbroken':
visattr.setLineStyle(VisAttr.SOLID)
if ls == 'broken':
visattr.setLineStyle(VisAttr.DASHED)
Pere Mato
committed
else:
visattr.setLineStyle(VisAttr.SOLID)
if 'drawingStyle' in v.keys():
Pere Mato
committed
ds = v.get('drawingStyle')
if ds == 'wireframe':
visattr.setDrawingStyle(VisAttr.WIREFRAME)
# <limit name="step_length_max" particles="*" value="5.0" unit="mm" />
limit = Limit(description.document(), l.get('name'))
limit.setParticles(l.get('particles'))
limit.setValue(l.getF('value'))
limit.setUnit(l.get('unit'))
# -----------------------------------------------------------------------------------
for d in elem.findall('detector'):
procs = drivers.get('detector_%s' % d.get('type'), None)
if procs:
detector = apply(procs, (description, d))
Marko Petric
committed
logger.info('Detector type %s not found' % d.get('type'))
# -----------------------------------------------------------------------------------
Pere Mato
committed
for a in elem.findall('alignment'):
Pere Mato
committed
# -----------------------------------------------------------------------------------
def process_alignment(description, elem):
alignment = AlignmentEntry(description, elem.name)
Pere Mato
committed
pos = getPosition(elem.find('position'))
rot = getRotation(elem.find('rotation'))
Marko Petric
committed
logger.info("%s %s", pos.isNull(), rot.isNull())
Pere Mato
committed
return alignment
# -----------------------------------------------------------------------------------
Pere Mato
committed
for a in elem.findall('readout'):
Pere Mato
committed
# -----------------------------------------------------------------------------------
Pere Mato
committed
readout = Readout(elem.name)
seg = elem.find('segmentation')
if seg is not None:
procs = globals().get('create_%s' % seg.get('type'), None)
if not procs:
procs = drivers.get('create_%s' % seg.get('type'), None)
if procs:
segment = apply(procs, (description, seg))
Pere Mato
committed
readout.setSegmentation(segment)
Marko Petric
committed
logger.info('Segmentation type %s not found' % seg.get('type'))
Pere Mato
committed
id = elem.find('id')
if id is not None:
idSpec = IDDescriptor(id.text)
idSpec.SetName(elem.name)
readout.setIDDescriptor(idSpec)
description.addIDSpecification(idSpec)
description.addReadout(readout)
Pere Mato
committed
# ---Segmentations--------------------------------------------------------------------
def create_GridXYZ(description, elem):
if 'gridSizeX' in elem.keys():
obj.setGridSizeX(elem.getF('gridSizeX'))
if 'gridSizeY' in elem.keys():
obj.setGridSizeY(elem.getF('gridSizeY'))
if 'gridSizeZ' in elem.keys():
obj.setGridSizeZ(elem.getF('gridSizeZ'))
def create_GlobalGridXY(description, elem):
if 'gridSizeX' in elem.keys():
obj.setGridSizeX(elem.getF('gridSizeX'))
if 'gridSizeY' in elem.keys():
obj.setGridSizeY(elem.getF('gridSizeY'))
def create_CartesianGridXY(description, elem):
if 'gridSizeX' in elem.keys():
obj.setGridSizeX(elem.getF('gridSizeX'))
if 'gridSizeY' in elem.keys():
obj.setGridSizeY(elem.getF('gridSizeY'))
def create_NoSegmentation(description, elem):
obj = NoSegmentation()
return obj
def create_ProjectiveCylinder(description, elem):
Pere Mato
committed
obj = ProjectiveCylinder()
if 'phiBins' in elem.keys():
obj.setPhiBins(elem.getI('phiBins'))
if 'thetaBins' in elem.keys():
obj.setThetaBins(elem.getI('thetaBins'))
Pere Mato
committed
return obj
Pere Mato
committed
def create_NonProjectiveCylinder(description, elem):
if 'gridSizePhi' in elem.keys():
obj.setThetaBinSize(elem.getF('gridSizePhi'))
if 'gridSizeZ' in elem.keys():
obj.setPhiBinSize(elem.getI('gridSizeZ'))
def create_ProjectiveZPlane(description, elem):
if 'phiBins' in elem.keys():
obj.setPhiBins(elem.getI('phiBins'))
if 'thetaBins' in elem.keys():
obj.setThetaBins(elem.getI('thetaBins'))
def create_GridPhiEta(description, elem):
obj = GridPhiEta()
if 'phiBins' in elem.keys():
obj.setPhiBins(elem.getI('phiBins'))
if 'gridSizeEta' in elem.keys():
obj.setGridSizeEta(elem.getI('gridSizeEta'))
def create_GridRPhiEta(description, elem):
obj = GridRPhiEta()
if 'phiBins' in elem.keys():
obj.setPhiBins(elem.getI('gridSizeR'))
if 'gridSizeEta' in elem.keys():
obj.setGridSizeEta(elem.getI('gridSizeEta'))
if 'gridSizeR' in elem.keys():
obj.setGridSizeR(elem.getI('gridSizeR'))