Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:49:04

0001 #!/usr/bin/env python
0002 from __future__ import print_function
0003 import sys
0004 import xml.dom.minidom
0005 import math
0006 import optparse
0007 
0008 maxDist = 0.0001
0009 
0010 #parse .tiles-File
0011 def readFractions(fileName, materialMap):
0012     result = {}
0013     file = open(fileName,"r")
0014     name = None
0015     dens = None
0016     fractions = {}
0017     for line in file:
0018         line = line.strip("\n")
0019         if len(line.split("\""))==3:
0020             contentName = line.split("\"")[1]
0021             content = line.split("\"")[2].split()
0022             if len(content) == 2:
0023                 if not name == None:
0024                     result[name] = dens,fractions
0025                 name = contentName
0026                 dens = content[1]
0027                 fractions = {}
0028             elif len(content) == 1:
0029     #            print "  "+contentName+" "+str(float(content[0][1:])*0.01)
0030                 fractions[getMaterial(contentName,materialMap)] = float(content[0][1:])*0.01
0031 
0032     if not name == None:
0033         result[name] = dens,fractions
0034 
0035     for material in result:
0036         sum = 0
0037         for fraction in result[material][1]:
0038             sum+= result[material][1][fraction]
0039         if math.fabs(sum - 1.0) > maxDist:
0040             raise Exception("Material Fractions do not add up to 100%: "+ material+" "+str(sum))
0041     return result
0042 
0043 #get a source:material from the [material] only
0044 def getMaterial(material, fileName):
0045     materialMap ={}
0046     file = open(fileName,"r")
0047     for line in file:
0048         line = line.strip("\n")
0049         content = line.split()
0050         if len(content) == 2:
0051             materialMap[content[0]] = content[1]
0052     if material in materialMap:
0053         result = materialMap[material]+":"+material
0054     else:
0055         result =  "materials:"+material
0056     return result
0057 
0058 #parse XML-File
0059 def readXML(fileName):
0060     file = open(fileName,'r')
0061     dom = xml.dom.minidom.parse(file)
0062     file.close()
0063     return dom
0064 
0065 #get the last subnode named [name] of [rootNode]
0066 def getSection(rootNode, name):
0067     result = None
0068     for node in rootNode.childNodes:
0069         if node.nodeName == name:
0070             result = node
0071     if result == None:
0072         raise Exception("Could not find: \""+name+"\" in childnodes of the rootNode!")
0073     return result
0074 
0075 #returns a map of [name] nodes by their names. stating from rootNode
0076 def getNodes(rootNode, name):
0077     result = {}
0078     for node in rootNode.childNodes:
0079         if node.nodeName == name and node.nodeType == node.ELEMENT_NODE:
0080             for i in range(0,node.attributes.length):
0081                 if node.attributes.item(i).name == "name":
0082                     result[node.attributes.item(i).nodeValue] = node
0083     return result
0084 #returns a pretty printed string of [dom] withot whitespace-only-lines
0085 def prettierprint(dom):
0086     result = ""
0087     output = dom.toprettyxml()
0088     for line in output.splitlines():
0089         if not line.strip(" \t") == "":
0090             result+= line+"\n"
0091     return result
0092 
0093 #gets a map of attributes and their values of [node] 
0094 #(not used but interessting for debug)
0095 def getAttributes(node):
0096     result = {};
0097     for i in range(0,node.attributes.length):
0098 #        print "  "+node.attributes.item(i).name+" = "+node.attributes.item(i).nodeValue
0099         result[node.attributes.item(i).name] = node.attributes.item(i).nodeValue    
0100     return result
0101 
0102 #print information on all subnodes of [domina]
0103 #(not used but interessting for debug)
0104 def dokument(domina):
0105     for node in domina.childNodes:
0106         print("NodeName:", node.nodeName, end=' ')
0107         if node.nodeType == node.ELEMENT_NODE:
0108             print("Typ ELEMENT_NODE")
0109             print(getAttributes(node))
0110         elif node.nodeType == node.TEXT_NODE:
0111             print("Typ TEXT_NODE, Content: ", node.nodeValue.strip())
0112         elif node.nodeType == node.COMMENT_NODE:
0113             print("Typ COMMENT_NODE, ")
0114         #dokument(node)
0115 
0116 #prints all CompositeMaterials beneeth [rootNode]
0117 #(not used but interessting for debug)
0118 def printMaterials(rootNode):
0119     matNodes = getNodes(rootNode,"CompositeMaterial")
0120     for name in matNodes:
0121         print("  "+name+" (dens = "+getAttributes(matNodes[name])["density"]+")")
0122         for fractionNode in matNodes[name].childNodes:
0123             if fractionNode.nodeName == "MaterialFraction":
0124                 fractionString = getAttributes(fractionNode)["fraction"]
0125                 for materialNode in fractionNode.childNodes:
0126                     if materialNode.nodeName == "rMaterial":
0127                         fractionString += "\tof "+getAttributes(materialNode)["name"].split(":")[1]
0128                         fractionString += "\tfrom "+getAttributes(materialNode)["name"].split(":")[0]
0129                 print("   |-- "+fractionString)
0130 
0131 #returns the Material Section doe of a DDD Material xmlfile
0132 def getMaterialSection(rootNode):
0133     dddef = getSection(rootNode,'DDDefinition')
0134     matSec = getSection(dddef,'MaterialSection')
0135     return matSec
0136 
0137 #creates a CompositeMaterial with [name] [method] [density] and [symbol] beneeth [rootNode]. 
0138 #fractions is a map of material Names containing the fractions
0139 #NOTE: if an material of that name allready exists it will be overridden.
0140 def createCompositeMaterial(doc,rootNode,name, density,fractions,method="mixture by weight", symbol=" "):
0141     newMaterial = doc.createElement("CompositeMaterial")
0142     newMaterial.setAttribute("name",name)
0143     newMaterial.setAttribute("density",density)
0144     newMaterial.setAttribute("method",method)
0145     newMaterial.setAttribute("symbol",symbol)
0146 
0147     for fracMaterialName in fractions:
0148         fraction = doc.createElement("MaterialFraction")
0149         fraction.setAttribute("fraction",str(fractions[fracMaterialName]))
0150         newMaterial.appendChild(fraction)
0151         fracMaterial = doc.createElement("rMaterial")
0152         fracMaterial.setAttribute("name",fracMaterialName)
0153         fraction.appendChild(fracMaterial)
0154 
0155     exMaterials = getNodes(rootNode,"CompositeMaterial")
0156     if name in exMaterials:
0157         rootNode.replaceChild(newMaterial,exMaterials[name])
0158     else:
0159         rootNode.appendChild(newMaterial)
0160 
0161 #main
0162 def main():
0163     optParser = optparse.OptionParser()
0164     optParser.add_option("-t", "--titles", dest="titlesFile",
0165                   help="the .titles file to parse (as generated by mixture)", metavar="TITLES")
0166     optParser.add_option("-x", "--xml", dest="xmlFile",
0167                   help="the .xml file to parse (must be DDD complient)", metavar="XML")
0168     optParser.add_option("-o", "--output", dest="output",
0169                   help="the file to write the new materials into default: materialOutput.xml", metavar="XMLOUT")
0170     optParser.add_option("-m", "--materialMap", dest="materialMap",
0171                   help="file containing map of materials not defined in materials.xml. default: material.map", metavar="MMAP")
0172 
0173     (options, args) = optParser.parse_args()
0174 
0175     if options.titlesFile == None:
0176         raise Exception("no .titles File given!")
0177     if options.xmlFile == None:
0178         raise Exception("no .xml File given!")
0179     if options.output == None:
0180         options.output = "materialOutput.xml"
0181     if options.materialMap == None:
0182         options.materialMap = "material.map"
0183     theOptions = options
0184 
0185     materials = readFractions(options.titlesFile, options.materialMap)
0186 
0187     dom = readXML(options.xmlFile)
0188     matSec = getMaterialSection(dom)
0189 
0190  #   print "before:"
0191  #   printMaterials(matSec)
0192 
0193     for material in materials:
0194         createCompositeMaterial(dom,matSec,material,str(materials[material][0])+"*g/cm3",materials[material][1])
0195 
0196 #    print "after:"
0197 #    printMaterials(matSec)
0198     outFile = open(options.output,"w")
0199     outFile.write(prettierprint(dom))
0200     outFile.close()
0201 
0202 main()
0203