Updating model XML file format w/ indentation.

This commit is contained in:
Patrick Shriwise 2022-11-25 08:22:57 -06:00
parent fe47d565fd
commit 6f7a6febd3
4 changed files with 111 additions and 50 deletions

View file

@ -1,22 +1,36 @@
def clean_indentation(element, level=0, spaces_per_level=2):
"""
copy and paste from https://effbot.org/zone/element-lib.htm#prettyprint
it basically walks your tree and adds spaces and newlines so the tree is
printed in a nice way
def clean_indentation(element, level=0, spaces_per_level=2, trailing_indent=True):
"""Set indentation of XML element and its sub-elements.
Copied and pastee from https://effbot.org/zone/element-lib.htm#prettyprint.
It walks your tree and adds spaces and newlines so the tree is
printed in a nice way.
Parameters
----------
level : int
Indentation level for the element passed in (default 0)
spaces_per_level : int
Number of spaces per indentation level (default 2)
trailing_indent : bool
Whether or not to include an indentation after closing the element
"""
i = "\n" + level*spaces_per_level*" "
# ensure there's awlays some tail for the element passed in
if not element.tail:
element.tail = ""
if len(element):
if not element.text or not element.text.strip():
element.text = i + spaces_per_level*" "
if not element.tail or not element.tail.strip():
if trailing_indent and (not element.tail or not element.tail.strip()):
element.tail = i
for sub_element in element:
clean_indentation(sub_element, level+1, spaces_per_level)
if not sub_element.tail or not sub_element.tail.strip():
sub_element.tail = i
else:
if level and (not element.tail or not element.tail.strip()):
if trailing_indent and level and (not element.tail or not element.tail.strip()):
element.tail = i

View file

@ -1449,7 +1449,7 @@ class Materials(cv.CheckedList):
for material in self:
material.make_isotropic_in_lab()
def _write_xml(self, file, header=True):
def _write_xml(self, file, header=True, level=0, spaces_per_level=2, trailing_indent=True):
"""Writes XML content of the materials to an open file handle.
Parameters
@ -1458,33 +1458,46 @@ class Materials(cv.CheckedList):
Open file handle to write content into.
header : bool
Whether or not to write the XML header
level : int
Indentation level of materials element
spaces_per_level : int
Number of spaces per indentation
trailing_indentation : bool
Whether or not to write a trailing indentation for the materials element
"""
indentation = level*spaces_per_level*' '
# Write the header and the opening tag for the root element.
if header:
file.write("<?xml version='1.0' encoding='utf-8'?>\n")
file.write('<materials>\n')
file.write(indentation+'<materials>\n')
# Write the <cross_sections> element.
if self.cross_sections is not None:
element = ET.Element('cross_sections')
element.text = str(self.cross_sections)
clean_indentation(element, level=1)
clean_indentation(element, level=level+1)
element.tail = element.tail.strip(' ')
file.write(' ')
file.write((level+1)*spaces_per_level*' ')
reorder_attributes(element) # TODO: Remove when support is Python 3.8+
ET.ElementTree(element).write(file, encoding='unicode')
# Write the <material> elements.
for material in sorted(self, key=lambda x: x.id):
element = material.to_xml_element()
clean_indentation(element, level=1)
clean_indentation(element, level=level+1)
element.tail = element.tail.strip(' ')
file.write(' ')
file.write((level+1)*spaces_per_level*' ')
reorder_attributes(element) # TODO: Remove when support is Python 3.8+
ET.ElementTree(element).write(file, encoding='unicode')
# Write the closing tag for the root element.
file.write('</materials>\n')
file.write(indentation+'</materials>\n')
# Write a trailing indentation for the next element
# at this level if needed
if trailing_indent:
file.write(indentation)
def export_to_xml(self, path: PathLike = 'materials.xml'):

View file

@ -552,6 +552,9 @@ class Model:
settings_element = self.settings.to_xml_element(memo)
geometry_element = self.geometry.to_xml_element()
xml.clean_indentation(geometry_element, level=1)
xml.clean_indentation(settings_element, level=1)
# If a materials collection was specified, export it. Otherwise, look
# for all materials in the geometry and use that to automatically build
# a collection.
@ -567,16 +570,18 @@ class Model:
fh.write("<model>\n")
# Write the materials collection to the open XML file first.
# This will write the XML header also
materials._write_xml(fh, False)
materials._write_xml(fh, False, level=1)
# Write remaining elements as a tree
ET.ElementTree(geometry_element).write(fh, encoding='unicode')
ET.ElementTree(settings_element).write(fh, encoding='unicode')
if self.tallies:
tallies_element = self.tallies.to_xml_element(memo)
xml.clean_indentation(tallies_element, level=1, trailing_indent=self.plots)
ET.ElementTree(tallies_element).write(fh, encoding='unicode')
if self.plots:
plots_element = self.plots.to_xml_element()
xml.clean_indentation(plots_element, level=1, trailing_indent=False)
ET.ElementTree(plots_element).write(fh, encoding='unicode')
fh.write("</model>\n")

View file

@ -1,38 +1,67 @@
<?xml version='1.0' encoding='utf-8'?>
<model>
<materials>
<material depletable="true" id="1">
<density units="g/cc" value="10.0" />
<nuclide ao="1.0" name="U235" />
</material>
<material id="2">
<density units="g/cc" value="0.1" />
<nuclide ao="0.1" name="H1" />
</material>
</materials>
<geometry>
<cell id="1" material="1" region="-1" universe="1" />
<cell id="2" material="2" region="1" universe="1" />
<cell id="3" fill="1" region="2 -3 4 -5 6 -8" rotation="10 20 30" universe="2" />
<cell id="4" fill="1" region="2 -3 4 -5 8 -7" translation="0 0 15" universe="2" />
<surface id="1" type="sphere" coeffs="1.0 0.0 0.0 5.0" />
<surface id="2" name="minimum x" type="x-plane" boundary="vacuum" coeffs="-7.5" />
<surface id="3" name="maximum x" type="x-plane" boundary="vacuum" coeffs="7.5" />
<surface id="4" name="minimum y" type="y-plane" boundary="vacuum" coeffs="-7.5" />
<surface id="5" name="maximum y" type="y-plane" boundary="vacuum" coeffs="7.5" />
<surface id="6" type="z-plane" boundary="vacuum" coeffs="-7.5" />
<surface id="7" type="z-plane" boundary="vacuum" coeffs="22.5" />
<surface id="8" type="z-plane" coeffs="7.5" />
</geometry>
<settings>
<run_mode>eigenvalue</run_mode>
<particles>10000</particles>
<batches>10</batches>
<inactive>5</inactive>
<source strength="1.0">
<space type="box">
<parameters>-4.0 -4.0 -4.0 4.0 4.0 4.0</parameters>
</space>
</source>
</settings>
<materials>
<material id="6">
<density units="g/cm3" value="2.6989" />
<nuclide ao="1.0" name="Al27" />
</material>
</materials>
<geometry>
<cell id="12" material="void" region="-16 17 -18" universe="10" />
<cell id="13" material="6" region="-16 18 -19" universe="10" />
<cell id="14" material="void" region="~(-16 17 -19)" universe="10" />
<surface id="16" type="x-cylinder" boundary="vacuum" coeffs="0.0 0.0 1.0" />
<surface id="17" type="x-plane" boundary="vacuum" coeffs="-1.0" />
<surface id="18" type="x-plane" coeffs="1.0" />
<surface id="19" type="x-plane" boundary="vacuum" coeffs="1000000000.0" />
</geometry>
<settings>
<run_mode>fixed source</run_mode>
<particles>10000</particles>
<batches>1</batches>
<source strength="1.0">
<space type="point">
<parameters>0 0 0</parameters>
</space>
<angle type="monodirectional" reference_uvw="1.0 0.0 0.0" />
<energy type="discrete">
<parameters>14000000.0 1.0</parameters>
</energy>
</source>
<electron_treatment>ttb</electron_treatment>
<photon_transport>true</photon_transport>
<cutoff>
<energy_photon>1000.0</energy_photon>
</cutoff>
</settings>
<tallies>
<filter id="1" type="surface">
<bins>16</bins>
</filter>
<filter id="2" type="particle">
<bins>neutron photon electron positron</bins>
</filter>
<tally id="1">
<filters>1 2</filters>
<scores>current</scores>
</tally>
<tally id="2">
<filters>2</filters>
<nuclides>Al27 total</nuclides>
<scores>total (n,gamma)</scores>
<estimator>tracklength</estimator>
</tally>
<tally id="3">
<filters>2</filters>
<nuclides>Al27 total</nuclides>
<scores>total heating (n,gamma)</scores>
<estimator>collision</estimator>
</tally>
<tally id="4">
<filters>2</filters>
<nuclides>Al27 total</nuclides>
<scores>total heating (n,gamma)</scores>
<estimator>analog</estimator>
</tally>
</tallies>
</model>