Package: ornl-wasp
Wasp Python Interfaces (WaspPy)WaspPy provides a python interface for utilizing WASP's parsing and validation functionality. The primary design consideration is to enable access to data represented in SON, DDI, EDDI, HIT, and HALITE formats.WaspPy places an emphasis on client convenience and provides overloading of the ".", dot operator. This is intended to allow a client to interact with their input with calls of the following form,doc.subnode1.subnode2, where doc is the object containing the parsed input andsubnode*are branches of the parse tree defined in the schema.WaspPy can be generated by adding the-Dwasp_ENABLE_SWIG=ONflag to the existing usable configuration script, i.eRequirementsIn addition to standard wasp requirements:Swig-4.1.1 is additionally required.Python-3.8 or later is required in lieu of python 2.7Code Configuration and Compilation#!/bin/bash
# Linux bash file example
cmake \
 -D CMAKE_BUILD_TYPE:STRING=RELEASE \
 -D wasp_ENABLE_ALL_PACKAGES:BOOL=ON \
 -D wasp_ENABLE_TESTS:BOOL=ON \
 -D wasp_ENABLE_SWIG=ON \ #Added to build the python wrappers
 -D CMAKE_INSTALL_PREFIX=`pwd`/install \
 -G "Unix Makefiles" \
 ~/waspExampleWASP supports structured and definition-driven syntaxes. Structured syntaxes (SON, HIT), do not require an input schema to be brought into memory. Definition-driven syntaxes (DDI, EDDI) require an input schema to construct the hierarchy of the desired parse tree. The following example illustrates how to bring input data into a program data structure using structured and definition-driven syntax.Problem DescriptionThe following fictional application is a general chemistry code describing salts and property interpolation. Specifically, the input is composed of a collection of salts and series of temperatures at which to query salt density.The input schema that describes the input hierarchy and parameter constraint isbelow. A legal input follows and depicts 2 salts,LiFandNaF, and temperatures queries at1100, 1200, 1300, 1400:salts{%Favoritesaltsalt(LiF){MeltTemp:1121.2MolecularWeight:25.9394BoilTemp:2512Density{A:2.37B:5.0e-4MinTemp:1123.6MaxTemp:1367.5}}salt(NaF){MolecularWeight:41.9882MeltTemp:1268BoilTemp:1978Density{A:2.76B:6.36e-4MinTemp:1273MaxTemp:1373}}}queries{temperatures=[1100120013001400]}Python programfromwaspimport*importmathclassLinearModel:''' _b*x + _c*y = _a '''def__init__(self,params):self._a=0.0self._b=1.0self._c=1.0self._minT=math.infself._maxT=-math.infforitinparams:ifit.name()=="MinTemp":self._maxT=float(it)elifit.name()=="MaxTemp":self._minT=float(it)elifit.name()=="A":self._a=float(it)elifit.name()=="B":self._b=float(it)elifit.name()=="C":self._c=float(it)defget_y(self,x:float)->"float":ifself._c==0.0:returnmath.infreturn(self._a-(self._b*x))/self._cclassSalt:def__init__(self,params):self._name=""self._molew=0.0self._meltT=0.0self._boilT=0.0self._density:LinearModel# Loop over salt parametersforitinparams:ifit.name()=="id":self._name=str(it)elifit.name()=="MolecularWeight":self._molew=float(it)elifit.name()=="MeltTemp":self._meltT=float(it)elifit.name()=="BoilTemp":self._boilT=float(it)elifit.name()=="Density":self._density=LinearModel(it)defdensity(self,T:float)->"float":returnself._density.get_y(T)if__name__=='__main__':importsysschemapath="path/to/application/schema.sch or schema data"input_file=sys.argv[1]interpreter=Interpreter(Syntax.SON,schema=schemapath,path=input_file)errors=interpreter.errors()iferrors:print("\n".join(errors))sys.exit(1)document=interpreter.root()# Obtain required queries parameterqueries=document.queries# Obtain required saltssalts=[]forcomponentindocument.salts.salt:salts.append(Salt(component))# Obtain each salt's melt temperature valueforvindocument.salts.salt.MeltTemp.value:# Print salt's id (located at ../../id of value node) and melt temperatureprint("MeltTemp of",str(v.parent().parent().id),"is",float(v))# Obtain query temperaturestemperatures=[]fortinqueries.temperatures.value:temperatures.append(float(t))# Evaluate salt density for each temperatureforsinsalts:fortintemperatures:print("Salt",s._name,"density at",t,"is",s.density(t))When executing the above program and providing the given input you can expect the following output:MeltTemp of LiF is 1121.2
MeltTemp of NaF is 1268.0
Salt LiF density at 1100.0 is 1.82
Salt LiF density at 1200.0 is 1.77
Salt LiF density at 1300.0 is 1.7200000000000002
Salt LiF density at 1400.0 is 1.67
Salt NaF density at 1100.0 is 2.0603999999999996
Salt NaF density at 1200.0 is 1.9968
Salt NaF density at 1300.0 is 1.9331999999999998
Salt NaF density at 1400.0 is 1.8695999999999997If an input error is encountered, as defined in the input schema, the program will emit a user-friendly diagnostic and exit. For example, if aMaxTempvalue violates theMinTempvalue constraint the following diagnostic is emitted.line:12 column:29 - Validation Error: MaxTemp value "1367.5" is less than or equal to the allowed minimum exclusive value of "1523.6" from "../../MinTemp/value"AccessorsThe dot operator provides the ability to navigate the hierarchy of the parse tree given the name of the subcomponents. When a subcomponent name conflicts with a Python reserved keyword the bracket operator[]can be used.SyntaxesThe syntax can be specified using theSyntax.XwhereXis one ofHIT,SON,DDI, andEDDI.For example, the input above is equivalent to the followiing HIT-formatted input and will produce the same out with only changing the one line:- interpreter = Interpreter(Syntax.SON, schema=schemapath, path=input_file)+ interpreter = Interpreter(Syntax.HIT, schema=schemapath, path=input_file)...[salts]
    # Favorite salt
    [salt]
        id = LiF
        MeltTemp = 1121.2
        MolecularWeight = 25.9394
        BoilTemp = 2512
        [Density]
            A = 2.37
            B = 5.0e-4
            MinTemp = 1123.6
            MaxTemp = 1367.5
        []
    []
    [salt]
        id = NaF
        MolecularWeight = 41.9882
        MeltTemp = 1268
        BoilTemp = 1978
        [Density]
            A = 2.76
            B = 6.36e-4
            MinTemp = 1273
            MaxTemp = 1373
        []
    []
[]
[queries]
    temperatures = '1100 1200 1300 1400'
[]Input Schemasalts{Description="The collection of salts in the system"MinOccurs=1MaxOccurs=1salt{MinOccurs=1MaxOccurs=NoLimitid{MinOccurs=1MaxOccurs=1ValEnums=[LiFNaFCaF2NH4FNaCl]}BoilTemp{MinOccurs=1MaxOccurs=1value{MinOccurs=1MaxOccurs=1ValType=Real}%endvalue}%endBoilTempDensity{MinOccurs=1MaxOccurs=1A{MinOccurs=0MaxOccurs=1value{MinOccurs=1MaxOccurs=1ValType=Real}%endvalue}%endAB{MinOccurs=0MaxOccurs=1value{MinOccurs=1MaxOccurs=1ValType=RealMinValInc=0}%endvalue}%endBMaxTemp{MinOccurs=0MaxOccurs=1value{MinOccurs=1MaxOccurs=1ValType=RealMinValExc="../../MinTemp/value"}%endvalue}%endMaxTempMinTemp{MinOccurs=0MaxOccurs=1value{MinOccurs=1MaxOccurs=1ValType=RealMinValExc=0}%endvalue}%endMinTemp}%endDensityMeltTemp{MinOccurs=1MaxOccurs=1value{MinOccurs=1MaxOccurs=1ValType=RealMinValInc=0}%endvalue}%endMeltTempMolecularWeight{MinOccurs=0MaxOccurs=1InputDefault="1.0"value{MinOccurs=1MaxOccurs=1ValType=RealMinValExc=0}%endvalue}%endMolecularWeight}%endsalt}%endsaltsqueries{Description="Parameters for queries salt properties"MinOccurs=1MaxOccurs=1temperatures{Description="Temperatures (C) at which to query density"MinOccurs=1MaxOccurs=1value{MinOccurs=1MaxOccurs=NoLimitValType=RealMinValInc=0}%endvalue}%endtemperatures}%endqueries