Example: Configuring a Template Model

This example is built to perform a factor analysis of a design space. It uses the file DynamicDOE.zmf. The model contains only two components: a Calculation component to evaluate design points by calculating a sequence of equations, and a DOE component to generate design points and perform the factor analysis.

The model is a general template as shown below.



Both components are marked as incomplete (yellow triangles icons appear on the component icons). Neither component has any (problem-specific) input or output parameters; the Calculation component has no equations, the DOE component has no factors or responses. All of these items are added to the model by its customization scripts.

The root component actually does have one input parameter—an “in-model” text file parameter named Problem Definition, which describes a concrete DOE application in a simple format. In this example model the default text value describes an Orthogonal Array analysis (of the Aero equations extracted from the standard AirplaneSizing example) as shown below.

Note: The Problem Definition file used in this example represents any custom file that contains information that you need for your application. It is not a specific format supported by Isight and should not be confused with the Problem Formulation file format as described in About Problem Formulation Files. As you will see, the customization script in this example has special parsing for the file used in this example.



The model contains three configuration scripts, one for the whole model and one for each component. The whole-model script reads the text from the Problem Definition File parameter line by line and puts each named block of lines on the blackboard keyed by the block name (it also renames the model if a new name is present).

# EXTRACT THE PROBLEM DEFINITION:
#   Each section of the problem definition consists of an initial 
line
#   containing a section identifier, followed by one or more 
lines containing
#   section data, followed by one blank line marking the end of 
the section.
#   This script reads each section's identifier and data and puts 
the data on
#   the blackboard using the identifier as the section key.

from java.io import InputStreamReader
from java.io import BufferedReader
problemDef = 
VariableUtil.openFileVariableInputStream(data.get("Problem 
Definition"))
lineReader = BufferedReader(InputStreamReader(problemDef))

while lineReader.ready():
    # Extract the next section identifier, skipping blank lines, 
until no more data:
    keyword = lineReader.readLine().lstrip()
    if keyword is None: break
    if keyword == "": continue

    # Accumulate the section's data, line by line, trimming 
leading indentation.
    # Stop at the next blank line (or when the input is 
exhausted):
    value = ""
    while lineReader.ready():
        line = lineReader.readLine().lstrip()
        if line is None or line == "": break
        if line.find('#') == 0: continue
        if line == "":
            value = line
        else:
            value = value + "\n" + line

    # Each identified section must have -some- data!
    if value == "":
        log.logError("There is no data under " + keyword)
    blackboard.addEntry(keyword,value)

lineReader.close()

# If the problem definition supplies a new model name, rename the 
model:
if blackboard.hasEntry("Name"):
    
model.getModelProperties().setModelName(blackboard.getEntry("Name
").strip())

The DOE component script creates the named input and output parameters (all of type “real”), sets the DOE technique to OrthogonalArray, and configures the DOE factors and responses as described in the script.

# CUSTOMIZE THE DOE COMPONENT:
#   Create all input and output parameters (here assumed to be 
all scalars),
#   then use the API to set the technique and configure factors 
and responses:

#----------------------------------------------------------------
---------------
# PREPARATION:

# THE BLACKBOARD MUST HAVE THESE ENTRIES:
assert blackboard.hasEntry("Inputs"), "No input parameters were 
defined"
assert blackboard.hasEntry("Outputs"), "No output parameters were 
defined"
assert blackboard.hasEntry("Technique"), "No technique was named"
assert blackboard.hasEntry("Factors"), "No factors were defined"
assert blackboard.hasEntry("Responses"), "No responses were 
defined"

# [make short aliases for various constants]
type = EsiTypes.REAL
role = Variable.ROLE_PARAMETER

#----------------------------------------------------------------
---------------

# CREATE THE PARAMETERS FOR THE DOE COMPONENT:
mode = Variable.MODE_INPUT
for inname in blackboard.getEntry("Inputs").replace('\n',' 
').split():
    v = 
DtModelManager.createScalarVariable(inname,type,role,mode,None,No
ne)
    component.addParameter(v)

mode = Variable.MODE_OUTPUT
for outname in blackboard.getEntry("Outputs").replace('\n',' 
').split():
    v = 
DtModelManager.createScalarVariable(outname,type,role,mode,None,N
one)
    component.addParameter(v)


# CONFIGURE THE DOE PLAN.  SET THE TECHNIQUE
# AND DEFINE THE FACTORS AND RESPONSES:
#   [The API supplies a scratch Plan object which must be stored 
when done]
component_api.initialize(component)
plan = component_api.getDOEPlan()

plan.setTechnique( "com.engineous.plugin.doe." + 
blackboard.getEntry("Technique").strip())

# FACTOR FORMAT: Var-Name, Baseline, level, ..., level
for facstr in 
blackboard.getEntry("Factors").strip().splitlines():
    facdef = facstr.split()
    factor = plan.addFactor(facdef[0])
    factor.setAttributeValue(Factor.ATTRIBUTE_BASELINE,facdef[1])
    factor.setLevels(facdef[2:])

for resp in blackboard.getEntry("Responses").replace('\n',' 
').split():
    plan.addResponse(resp)

# THE DOE PLAN IS NOT CONFIGURED UNTIL THIS CALL IS MADE:
component_api.apply()

The results of the DOE script are shown below.



The Calculator component script also creates the named parameters, adds dataflow mappings between them, and sets the sequence of equations:

# CUSTOMIZE THE CALCULATOR COMPONENT:
#   Create all input and output parameters (here assumed to be 
all scalars),
#   with mappings to the corresponding DOE parameters; then 
create local
#   parameters (if any) and set the calculation formulae:

#----------------------------------------------------------------
---------------
# PREPARATION:

# THE BLACKBOARD MUST HAVE THESE ENTRIES:
assert blackboard.hasEntry("Inputs"), "No input parameters were 
defined"
assert blackboard.hasEntry("Outputs"), "No output parameters were 
defined"
assert blackboard.hasEntry("Formulas"), "No formulas were 
defined"

# [make short aliases for various constants]
type = EsiTypes.REAL
role = Variable.ROLE_PARAMETER

# Must map calculation parameters to DOE parameters:
parent = component.getParentComponent()

#----------------------------------------------------------------
---------------

# CREATE THE PARAMETERS FOR THE CALCULATOR COMPONENT:
mode = Variable.MODE_INPUT
for inname in blackboard.getEntry("Inputs").replace('\n',' 
').split():
    v = 
DtModelManager.createScalarVariable(inname,type,role,mode,None,No
ne)
    component.addParameter(v)
    pv = parent.getParameter(inname)
    parent.addDataFlow(DtModelManager.createDataFlow(pv,v))

mode = Variable.MODE_OUTPUT
for outname in blackboard.getEntry("Outputs").replace('\n',' 
').split():
    v = 
DtModelManager.createScalarVariable(outname,type,role,mode,None,N
one)
    component.addParameter(v)
    pv = parent.getParameter(outname)
    parent.addDataFlow(DtModelManager.createDataFlow(v,pv))

if blackboard.hasEntry("Locals"):
    mode = Variable.MODE_LOCAL
    for localname in blackboard.getEntry("Locals").replace('\n',' 
').split():
        v = 
DtModelManager.createScalarVariable(localname,type,role,mode,
None,None)
        v.setSaveToDB(0)
        component.addParameter(v)

# SET THE EQUATIONS FOR THE CALCULATOR COMPONENT:
formulas = blackboard.getEntry("Formulas")
component.getProperty("expression").getValueObj().setValue(formul
as)

The results of the Calculator script are shown below.