CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/Geometry/TrackerCommonData/data/Materials/insertMaterial.py

Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 import sys
00003 import xml.dom.minidom
00004 import math
00005 import optparse
00006 
00007 maxDist = 0.0001
00008 
00009 #parse .tiles-File
00010 def readFractions(fileName, materialMap):
00011     result = {}
00012     file = open(fileName,"r")
00013     name = None
00014     dens = None
00015     fractions = {}
00016     for line in file:
00017         line = line.strip("\n")
00018         if len(line.split("\""))==3:
00019             contentName = line.split("\"")[1]
00020             content = line.split("\"")[2].split()
00021             if len(content) == 2:
00022                 if not name == None:
00023                     result[name] = dens,fractions
00024                 name = contentName
00025                 dens = content[1]
00026                 fractions = {}
00027             elif len(content) == 1:
00028     #            print "  "+contentName+" "+str(float(content[0][1:])*0.01)
00029                 fractions[getMaterial(contentName,materialMap)] = float(content[0][1:])*0.01
00030     
00031     if not name == None:
00032         result[name] = dens,fractions
00033                         
00034     for material in result:
00035         sum = 0
00036         for fraction in result[material][1]:
00037             sum+= result[material][1][fraction]
00038         if math.fabs(sum - 1.0) > maxDist:
00039             raise StandardError, "Material Fractions do not add up to 100%: "+ material+" "+str(sum)
00040     return result
00041         
00042 #get a source:material from the [material] only
00043 def getMaterial(material, fileName):
00044     materialMap ={}
00045     file = open(fileName,"r")
00046     for line in file:
00047         line = line.strip("\n")
00048         content = line.split()
00049         if len(content) == 2:
00050             materialMap[content[0]] = content[1] 
00051     if material in materialMap:
00052         result = materialMap[material]+":"+material
00053     else:
00054         result =  "materials:"+material
00055     return result
00056 
00057 #parse XML-File
00058 def readXML(fileName):
00059     file = open(fileName,'r')
00060     dom = xml.dom.minidom.parse(file)
00061     file.close()
00062     return dom
00063 
00064 #get the last subnode named [name] of [rootNode]
00065 def getSection(rootNode, name):
00066     result = None
00067     for node in rootNode.childNodes:
00068         if node.nodeName == name:
00069             result = node
00070     if result == None:
00071         raise StandardError, "Could not find: \""+name+"\" in childnodes of the rootNode!"
00072     return result          
00073 
00074 #returns a map of [name] nodes by their names. stating from rootNode
00075 def getNodes(rootNode, name):
00076     result = {}
00077     for node in rootNode.childNodes:
00078         if node.nodeName == name and node.nodeType == node.ELEMENT_NODE:
00079             for i in range(0,node.attributes.length):
00080                 if node.attributes.item(i).name == "name":
00081                     result[node.attributes.item(i).nodeValue] = node
00082     return result
00083 #returns a pretty printed string of [dom] withot whitespace-only-lines
00084 def prettierprint(dom):
00085     result = ""
00086     output = dom.toprettyxml()
00087     for line in output.splitlines():
00088         if not line.strip(" \t") == "":
00089             result+= line+"\n"
00090     return result
00091 
00092 #gets a map of attributes and their values of [node] 
00093 #(not used but interessting for debug)
00094 def getAttributes(node):
00095     result = {};
00096     for i in range(0,node.attributes.length):
00097 #        print "  "+node.attributes.item(i).name+" = "+node.attributes.item(i).nodeValue
00098         result[node.attributes.item(i).name] = node.attributes.item(i).nodeValue    
00099     return result
00100 
00101 #print information on all subnodes of [domina]
00102 #(not used but interessting for debug)
00103 def dokument(domina):
00104     for node in domina.childNodes:
00105         print "NodeName:", node.nodeName,
00106         if node.nodeType == node.ELEMENT_NODE:
00107             print "Typ ELEMENT_NODE"
00108             print getAttributes(node)
00109         elif node.nodeType == node.TEXT_NODE:
00110             print "Typ TEXT_NODE, Content: ", node.nodeValue.strip()
00111         elif node.nodeType == node.COMMENT_NODE:
00112             print "Typ COMMENT_NODE, "
00113         #dokument(node)
00114 
00115 #prints all CompositeMaterials beneeth [rootNode]
00116 #(not used but interessting for debug)
00117 def printMaterials(rootNode):
00118     matNodes = getNodes(rootNode,"CompositeMaterial")
00119     for name in matNodes:
00120         print "  "+name+" (dens = "+getAttributes(matNodes[name])["density"]+")"
00121         for fractionNode in matNodes[name].childNodes:
00122             if fractionNode.nodeName == "MaterialFraction":
00123                 fractionString = getAttributes(fractionNode)["fraction"]
00124                 for materialNode in fractionNode.childNodes:
00125                     if materialNode.nodeName == "rMaterial":
00126                         fractionString += "\tof "+getAttributes(materialNode)["name"].split(":")[1]
00127                         fractionString += "\tfrom "+getAttributes(materialNode)["name"].split(":")[0]
00128                 print "   |-- "+fractionString
00129     
00130 #returns the Material Section doe of a DDD Material xmlfile
00131 def getMaterialSection(rootNode):
00132     dddef = getSection(rootNode,'DDDefinition')
00133     matSec = getSection(dddef,'MaterialSection')
00134     return matSec
00135 
00136 #creates a CompositeMaterial with [name] [method] [density] and [symbol] beneeth [rootNode]. 
00137 #fractions is a map of material Names containing the fractions
00138 #NOTE: if an material of that name allready exists it will be overridden. 
00139 def createCompositeMaterial(doc,rootNode,name, density,fractions,method="mixture by weight", symbol=" "):
00140     newMaterial = doc.createElement("CompositeMaterial")
00141     newMaterial.setAttribute("name",name)
00142     newMaterial.setAttribute("density",density)
00143     newMaterial.setAttribute("method",method)
00144     newMaterial.setAttribute("symbol",symbol)    
00145 
00146     for fracMaterialName in fractions:
00147         fraction = doc.createElement("MaterialFraction")
00148         fraction.setAttribute("fraction",str(fractions[fracMaterialName]))
00149         newMaterial.appendChild(fraction)
00150         fracMaterial = doc.createElement("rMaterial")
00151         fracMaterial.setAttribute("name",fracMaterialName)
00152         fraction.appendChild(fracMaterial)
00153 
00154     exMaterials = getNodes(rootNode,"CompositeMaterial")
00155     if name in exMaterials:
00156         rootNode.replaceChild(newMaterial,exMaterials[name])
00157     else:
00158         rootNode.appendChild(newMaterial)
00159 
00160 #main
00161 def main():
00162     optParser = optparse.OptionParser()
00163     optParser.add_option("-t", "--titles", dest="titlesFile",
00164                   help="the .titles file to parse (as generated by mixture)", metavar="TITLES")
00165     optParser.add_option("-x", "--xml", dest="xmlFile",
00166                   help="the .xml file to parse (must be DDD complient)", metavar="XML")
00167     optParser.add_option("-o", "--output", dest="output",
00168                   help="the file to write the new materials into default: materialOutput.xml", metavar="XMLOUT")
00169     optParser.add_option("-m", "--materialMap", dest="materialMap",
00170                   help="file containing map of materials not defined in materials.xml. default: material.map", metavar="MMAP")
00171 
00172     (options, args) = optParser.parse_args()
00173 
00174     if options.titlesFile == None:
00175         raise StandardError, "no .titles File given!"
00176     if options.xmlFile == None:
00177         raise StandardError, "no .xml File given!"
00178     if options.output == None:
00179         options.output = "materialOutput.xml"
00180     if options.materialMap == None:
00181         options.materialMap = "material.map"
00182     theOptions = options
00183 
00184     materials = readFractions(options.titlesFile, options.materialMap)
00185     
00186     dom = readXML(options.xmlFile)
00187     matSec = getMaterialSection(dom)
00188 
00189  #   print "before:"
00190  #   printMaterials(matSec)
00191 
00192     for material in materials:
00193         createCompositeMaterial(dom,matSec,material,str(materials[material][0])+"*g/cm3",materials[material][1])
00194 
00195 #    print "after:"
00196 #    printMaterials(matSec)
00197     outFile = open(options.output,"w")
00198     outFile.write(prettierprint(dom))
00199     outFile.close()
00200     
00201 main()
00202