Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-12-01 23:40:25

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