mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-27 13:45:36 -04:00
Merge pull request #362 from bhermanmit/xml-validation
XML Validation script
This commit is contained in:
commit
47a6eecbf8
5 changed files with 175 additions and 9 deletions
|
|
@ -51,6 +51,55 @@ files are called:
|
|||
* ``plots.xml``
|
||||
* ``cmfd.xml``
|
||||
|
||||
--------------------
|
||||
Validating XML Files
|
||||
--------------------
|
||||
|
||||
Input files can be checked before executing OpenMC using the ``xml_validate``
|
||||
script. It is located in ``src/utils/xml_validate.py`` in the source code or in
|
||||
``bin/xml_validate`` in the install directory. Before use, the third party
|
||||
package TRANG_ must be installed and in your ``PATH`` to convert the compact
|
||||
RelaxNG schema to standard RelaxNG format. For Ubuntu, you can install with:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo apt-get install trang
|
||||
|
||||
Two command line arguments can be set when running ``xml_validate``:
|
||||
|
||||
* ``-i``, ``--input-path`` - Location of OpenMC input files.
|
||||
*Default*: current working directory
|
||||
* ``-r``, ``--relaxng-path`` - Location of OpenMC RelaxNG files.
|
||||
*Default*: None
|
||||
|
||||
If the RelaxNG path is not set, ``xml_validate`` will search for these files
|
||||
because it expects that the user is either running the script located in the
|
||||
install directory ``bin`` folder or in ``src/utils``. Once executed, it will
|
||||
match OpenMC XML files with their RelaxNG schema and check if they are valid.
|
||||
Below is a table of the messages that will be printed after each file is
|
||||
checked.
|
||||
|
||||
======================== ===================================
|
||||
Message Description
|
||||
======================== ===================================
|
||||
[XML ERROR] Cannot parse XML file.
|
||||
[NO RELAXNG FOUND] No RelaxNG file found for XML file.
|
||||
[TRANG FAILED] TRANG not installed properly.
|
||||
[NOT VALID] XML file does not match RelaxNG.
|
||||
[VALID] XML file matches RelaxNG.
|
||||
======================== ===================================
|
||||
|
||||
As an example, if OpenMC is installed in the directory
|
||||
``/opt/openmc/0.6.2`` and the current working directory is where
|
||||
OpenMC XML input files are located, they can be validated using
|
||||
the following command:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
/opt/openmc/0.6.2/bin/xml_validate
|
||||
|
||||
.. _TRANG: http://www.thaiopensource.com/relaxng/trang.html
|
||||
|
||||
--------------------------------------
|
||||
Settings Specification -- settings.xml
|
||||
--------------------------------------
|
||||
|
|
|
|||
|
|
@ -272,6 +272,10 @@ install(PROGRAMS utils/statepoint_meshplot.py
|
|||
install(PROGRAMS utils/update_inputs.py
|
||||
DESTINATION bin
|
||||
RENAME update_inputs)
|
||||
install(PROGRAMS utils/xml_validate.py
|
||||
DESTINATION bin
|
||||
RENAME xml_validate)
|
||||
install(DIRECTORY relaxng DESTINATION share)
|
||||
install(FILES ../man/man1/openmc.1 DESTINATION share/man/man1)
|
||||
install(FILES ../LICENSE DESTINATION "share/doc/${program}/copyright")
|
||||
|
||||
|
|
|
|||
|
|
@ -904,7 +904,7 @@ contains
|
|||
integer :: universe_num
|
||||
integer :: n_cells_in_univ
|
||||
integer :: coeffs_reqd
|
||||
integer :: temp_int_array3(3)
|
||||
integer :: temp_double_array3(3)
|
||||
integer, allocatable :: temp_int_array(:)
|
||||
real(8) :: phi, theta, psi
|
||||
logical :: file_exists
|
||||
|
|
@ -1052,10 +1052,10 @@ contains
|
|||
end if
|
||||
|
||||
! Copy rotation angles in x,y,z directions
|
||||
call get_node_array(node_cell, "rotation", temp_int_array3)
|
||||
phi = -temp_int_array3(1) * PI/180.0_8
|
||||
theta = -temp_int_array3(2) * PI/180.0_8
|
||||
psi = -temp_int_array3(3) * PI/180.0_8
|
||||
call get_node_array(node_cell, "rotation", temp_double_array3)
|
||||
phi = -temp_double_array3(1) * PI/180.0_8
|
||||
theta = -temp_double_array3(2) * PI/180.0_8
|
||||
psi = -temp_double_array3(3) * PI/180.0_8
|
||||
|
||||
! Calculate rotation matrix based on angles given
|
||||
allocate(c % rotation(3,3))
|
||||
|
|
|
|||
|
|
@ -26,10 +26,8 @@ element tallies {
|
|||
"surface" | "mesh" | "energy" | "energyout" ) } |
|
||||
attribute type { ( "cell" | "cellborn" | "material" | "universe" |
|
||||
"surface" | "mesh" | "energy" | "energyout" ) }) &
|
||||
(element bins { list { xsd:string { maxLength = "20" }+ } } |
|
||||
attribute bins { list { xsd:string { maxLength = "20" }+ } }) &
|
||||
(element groups { xsd:string { maxLength = "20" }+ } |
|
||||
attribute groups { xsd:string { maxLength = "20" }+ })?
|
||||
(element bins { list { xsd:double+ } } |
|
||||
attribute bins { list { xsd:double+ } })
|
||||
}* &
|
||||
element nuclides {
|
||||
list { xsd:string { maxLength = "12" }+ }
|
||||
|
|
|
|||
115
src/utils/xml_validate.py
Executable file
115
src/utils/xml_validate.py
Executable file
|
|
@ -0,0 +1,115 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
import sys
|
||||
import glob
|
||||
import lxml.etree as etree
|
||||
from subprocess import call
|
||||
from optparse import OptionParser
|
||||
|
||||
# Command line parsing
|
||||
parser = OptionParser()
|
||||
parser.add_option('-r', '--relaxng-path', dest='relaxng',
|
||||
help="Path to RelaxNG files.")
|
||||
parser.add_option('-i', '--input-path', dest='inputs', default=os.getcwd(),
|
||||
help="Path to OpenMC input files." )
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
# Colored output
|
||||
if sys.stdout.isatty():
|
||||
OK = '\033[92m'
|
||||
FAIL = '\033[91m'
|
||||
NOT_FOUND = '\033[93m'
|
||||
ENDC = '\033[0m'
|
||||
BOLD = '\033[1m'
|
||||
else:
|
||||
OK = ''
|
||||
FAIL = ''
|
||||
ENDC = ''
|
||||
BOLD = ''
|
||||
NOT_FOUND = ''
|
||||
|
||||
# Get absolute paths
|
||||
if options.relaxng is not None:
|
||||
relaxng_path = os.path.abspath(options.relaxng)
|
||||
if options.inputs is not None:
|
||||
inputs_path = os.path.abspath(options.inputs)
|
||||
|
||||
# Search for relaxng path if not set
|
||||
if options.relaxng is None:
|
||||
xml_validate_path = os.path.abspath(os.path.dirname(sys.argv[0]))
|
||||
if "bin" in xml_validate_path:
|
||||
relaxng_path = os.path.join(xml_validate_path, "..", "share", "relaxng")
|
||||
elif os.path.join("src", "utils") in xml_validate_path:
|
||||
relaxng_path = os.path.join(xml_validate_path, "..", "relaxng")
|
||||
else:
|
||||
raise Exception("Set RelaxNG path with -r command line option.")
|
||||
if not os.path.exists(relaxng_path):
|
||||
raise Exception("RelaxNG path: {0} does not exist, set with -r "
|
||||
"command line option.".format(relaxng_path))
|
||||
|
||||
# Make sure there are .rnc files in RelaxNG path
|
||||
rnc_files = glob.glob(os.path.join(relaxng_path, "*.rnc"))
|
||||
if len(rnc_files) == 0:
|
||||
raise Exception("No .rnc files found in RelaxNG "
|
||||
"path: {0}.".format(relaxng_path))
|
||||
|
||||
# Get list of xml input files
|
||||
xml_files = glob.glob(os.path.join(inputs_path, "*.xml"))
|
||||
if len(xml_files) == 0:
|
||||
raise Exception("No .xml files found at input path: {0}"
|
||||
".".format(inputs_path))
|
||||
|
||||
# Begin loop around input files
|
||||
for xml_file in xml_files:
|
||||
|
||||
text = "Validating {0}".format(os.path.basename(xml_file))
|
||||
print(text + '.'*(30 - len(text)), end="")
|
||||
|
||||
# Validate the XML file
|
||||
try:
|
||||
xml_tree = etree.parse(xml_file)
|
||||
except etree.XMLSyntaxError as e:
|
||||
print(BOLD + FAIL + '[XML ERROR]' + ENDC)
|
||||
print(" {0}".format(e))
|
||||
continue
|
||||
|
||||
# Get xml_filename prefix
|
||||
xml_prefix = os.path.basename(xml_file)
|
||||
xml_prefix = xml_prefix.split(".")[0]
|
||||
|
||||
# Search for rnc file
|
||||
rnc_file = os.path.join(relaxng_path, xml_prefix + ".rnc")
|
||||
rng_file = xml_prefix + ".rng"
|
||||
if rnc_file in rnc_files:
|
||||
|
||||
# convert RNC to RNG file
|
||||
rc = call("trang {0} {1}".format(rnc_file, rng_file), shell=True)
|
||||
|
||||
# check return code
|
||||
if rc == 0:
|
||||
|
||||
# read in RelaxNG
|
||||
relaxng_doc = etree.parse(rng_file)
|
||||
relaxng = etree.RelaxNG(relaxng_doc)
|
||||
|
||||
# validate xml file again RelaxNG
|
||||
try:
|
||||
relaxng.assertValid(xml_tree)
|
||||
print(BOLD + OK + '[VALID]' + ENDC)
|
||||
except (etree.DocumentInvalid, TypeError) as e:
|
||||
print(BOLD + FAIL + '[NOT VALID]' + ENDC)
|
||||
print(" {0}".format(e))
|
||||
|
||||
# remove rng file
|
||||
os.remove(rng_file)
|
||||
|
||||
# trang command failed
|
||||
else:
|
||||
print(BOLD + FAIL + '[TRANG FAILED]' + ENDC)
|
||||
|
||||
# RNC file does not exist
|
||||
else:
|
||||
print(BOLD + NOT_FOUND + '[NO RELAXNG FOUND]' + ENDC)
|
||||
Loading…
Add table
Add a link
Reference in a new issue