JSON¶
Contents¶
Overview¶
The developers of PsyNeuLink are collaborating with the scientific community, as part of the OpenNeuro effort, to create a standard, JSON-based format for the description and exchange of computational models of brain and psychological function across different simulation environments. As part of this effort, PsyNeuLink includes the ability to export models into, and import valid Python scripts that express a PsyNeuLink model from this JSON format.
Any PsyNeuLink Composition or Component can be exported to the JSON format using its json_summary
method, that
uses its _dict_summary
. This generates a string that, passed into the
generate_script_from_json
function, produces a valid Python script replicating the original PsyNeuLink model.
write_json_file
can be used to write the json_summary for one or more Compositions into a specified file (though
see note). generate_script_from_json
can accept either the string returned
by generate_script_from_json
or the name of a file containing one.
Calling exec(generate_script_from_json(<input>))
will load into the current namespace all of the PsyNeuLink
objects specified in the input
; and get_compositions
can be used to retrieve a list of all of the Compositions
in that namespace, including any generated by execution of generate_script_from_json
.
Warning
Use of generate_script_from_json
to generate a Python script from a file without taking proper precautions can
introduce a security risk to the system on which the Python interpreter is running. This is because it calls
exec, which has the potential to execute non-PsyNeuLink-related code embedded in the file. Therefore,
generate_script_from_json
should be used to read only files of known and secure origin.
Model Examples¶
Below is an example of a script that implements a PsyNeuLink model of the Stroop model with conflict monitoring,
and its output in JSON. Running generate_script_from_json
on the output will produce another PsyNeuLink script
that will give the same results when run on the same input as the original.
JSON Model Specification¶
Note
The JSON format is in early development, and is subject to change.
The outermost level of a JSON model is a dictionary with entry graphs
, a list of Composition objects.
Each Component’s JSON object contains multiple entries. Those that are common to all are:
name
: a label for the Componentparameters
(non-Functions) /args
(Functions) : a dictionary where each entry is either aParameter
name and value, or a subdictionary of modeling-environment specific parameters. For PsyNeuLink, this is indicated byPNL
:
"args": {
"PNL": {
"execution_count": 0,
"has_initializers": false,
"variable": [
0.01
]
},
"bounds": null,
"intercept": 0.0,
"slope": 1.0
}
Note that the value of a parameter may be a long-form dictionary when it corresponds to a ParameterPort.
In this case, it will indicate the ParameterPort in a source
field:
"intercept": {
"source": "A.input_ports.intercept",
"type": "float",
"value": 2.0
}
type
: a dictionary with entries based on modeling environment to describe the type of the object. Thegeneric
entry is populated if the object has a universal name (such as a linear function). Modeling-environment-specific entries are populated when relevant.
"type": {
"PNL": "Composition",
"generic": "graph"
}
Mechanisms, Projections, and Ports each have:
functions
: a list of primary Function JSON objects. In PsyNeuLink, only one primary function is allowed.
"functions": [
{
"args": {
"intercept": {
"source": "A.input_ports.intercept",
"type": "float",
"value": 2.0
},
"slope": {
"source": "A.input_ports.slope",
"type": "float",
"value": 5.0
}
},
"name": "Linear Function-1",
"type": {
"generic": "Linear"
}
}
]
Mechanisms have:
input_ports
: a list of InputPort and ParameterPort JSON objectsoutput_ports
: a list of OutputPort JSON objects
Projections have:
sender
: the name of the Component it projects fromsender_port
: the name of the port on thesender
to which it connectsreceiver
: the name of the Component it projects toreceiver_port
: the name of the port on thereceiver
to which it connects
Ports have:
dtype
: the type of accepted input/output for the Port. This corresponds to numpy.dtypeshape
: the shape of the accepted input/output. This corresponds to numpy ndarray shapes. (numpy.zeros(<shape>)
would produce an array with the correct shape)
Compositions have:
nodes
: a dictionary of Mechanisms or Compositions keyed on their names that are part of the Compositionedges
: a dictionary of Projections keyed on their names that connect nodes of the Compositioncontroller
: the name of the Mechanism in the Composition’s nodes that serves as the Composition’s controller, if it exists
- class psyneulink.core.globals.json.PNLJSONEncoder(*, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)¶
A JSONEncoder that parses
_dict_summary
output into a more JSON-friendly format.- default(o)¶
Implement this method in a subclass such that it returns a serializable object for
o
, or calls the base implementation (to raise aTypeError
).For example, to support arbitrary iterators, you could implement default like this:
def default(self, o): try: iterable = iter(o) except TypeError: pass else: return list(iterable) # Let the base class default method raise the TypeError return JSONEncoder.default(self, o)
- psyneulink.core.globals.json.generate_script_from_json(model_input)¶
Generate a Python script from JSON model_input in the general JSON format
Warning
Use of
generate_script_from_json
to generate a Python script from a file without taking proper precautions can introduce a security risk to the system on which the Python interpreter is running. This is because it calls exec, which has the potential to execute non-PsyNeuLink-related code embedded in the file. Therefore,generate_script_from_json
should be used to read only files of known and secure origin.- Parameters
model_input (str) – a JSON string in the proper format, or a filename containing such
- Returns
Text of Python script
- Return type
str
- psyneulink.core.globals.json.write_json_file(compositions, filename, path=None)¶
Write one or more Compositions and associated objects to file in the general JSON format
Note
At present, if more than one Composition is specified, all must be fully disjoint; that is, they must not share any Components (e.g., Mechanism, Projections etc.). This limitation will be addressed in a future update.
- Parameters
compositions (Composition or list˚) – specifies Composition or list of ones to be written to filename
filename (str) – specifies name of file in which to write JSON specification of Composition(s) and associated objects.
path (str : default None) – specifies path of file for JSON specification; if it is not specified then the current directory is used.