Skip to content

Commit

Permalink
• controlmechanism.py, gatingmechanism.py:
Browse files Browse the repository at this point in the history
  - CONTROL: 'CONTROL' -> 'control'
  - GATING: 'GATING' -> 'gating'
  • Loading branch information
jdcpni committed Jan 3, 2022
1 parent a95c82a commit 59e0f3d
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1206,8 +1206,8 @@ class Parameters(ModulatoryMechanism_Base.Parameters):
read_only=True,
structural=True,
parse_spec=True,
aliases=['control', 'control_signals'],
constructor_argument='control'
aliases=[CONTROL, CONTROL_SIGNALS],
constructor_argument=CONTROL
)

# MODIFIED 1/2/22 OLD: - MUCH OF THIS SEEMS TO BE COVERED ELSEWHERE; COMMENTING OUT ONLY CAUSES PROBLEMS WITH
Expand Down Expand Up @@ -1308,7 +1308,7 @@ def __init__(self,
# Only allow one of CONTROL, MODULATORY_SIGNALS OR CONTROL_SIGNALS to be specified
# These are synonyms, but allowing several to be specified and trying to combine the specifications
# can cause problems if different forms of specification are used to refer to the same Component(s)
control_specified = "'control'" if control else ''
control_specified = f"'{CONTROL}'" if control else ''
modulatory_signals_specified = ''
if MODULATORY_SIGNALS in kwargs:
args = kwargs.pop(MODULATORY_SIGNALS)
Expand Down Expand Up @@ -1412,14 +1412,18 @@ def _validate_params(self, request_set, target_set=None, context=None):

if CONTROL in target_set and target_set[CONTROL]:
control = target_set[CONTROL]
assert isinstance(control, list), \
f"PROGRAM ERROR: control arg {control} of {self.name} should have been converted to a list."
for ctl_spec in control:
ctl_spec = _parse_port_spec(port_type=ControlSignal, owner=self, port_spec=ctl_spec)
if not (isinstance(ctl_spec, ControlSignal)
or (isinstance(ctl_spec, dict) and ctl_spec[PORT_TYPE]==ControlSignal.__name__)):
raise ControlMechanismError(f"Invalid specification for '{CONTROL}' argument of {self.name}:"
f"({ctl_spec})")
self._validate_control_arg(control)

def _validate_control_arg(self, control):
"""Treat control arg separately so it can be overridden by subclassses (e.g., GatingMechanism)"""
assert isinstance(control, list), \
f"PROGRAM ERROR: control arg {control} of {self.name} should have been converted to a list."
for ctl_spec in control:
ctl_spec = _parse_port_spec(port_type=ControlSignal, owner=self, port_spec=ctl_spec)
if not (isinstance(ctl_spec, ControlSignal)
or (isinstance(ctl_spec, dict) and ctl_spec[PORT_TYPE] == ControlSignal)):
raise ControlMechanismError(f"Invalid specification for '{CONTROL}' argument of {self.name}:"
f"({ctl_spec})")

# IMPLEMENTATION NOTE: THIS SHOULD BE MOVED TO COMPOSITION ONCE THAT IS IMPLEMENTED
def _instantiate_objective_mechanism(self, input_ports=None, context=None):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,10 +185,11 @@

from psyneulink.core.components.mechanisms.modulatory.control.controlmechanism import ControlMechanism
from psyneulink.core.components.ports.modulatorysignals.gatingsignal import GatingSignal
from psyneulink.core.components.ports.port import _parse_port_spec
from psyneulink.core.globals.defaults import defaultGatingAllocation
from psyneulink.core.globals.keywords import \
GATE, GATING, GATING_PROJECTION, GATING_SIGNAL, GATING_SIGNALS, \
INIT_EXECUTE_METHOD_ONLY, MONITOR_FOR_CONTROL, PROJECTION_TYPE
CONTROL, CONTROL_SIGNALS, GATE, GATING, GATING_PROJECTION, GATING_SIGNAL, GATING_SIGNALS, \
INIT_EXECUTE_METHOD_ONLY, MONITOR_FOR_CONTROL, PORT_TYPE, PROJECTION_TYPE
from psyneulink.core.globals.parameters import Parameter
from psyneulink.core.globals.preferences.basepreferenceset import is_pref_set
from psyneulink.core.globals.preferences.preferenceset import PreferenceLevel
Expand Down Expand Up @@ -427,7 +428,7 @@ class Parameters(ControlMechanism.Parameters):
read_only=True,
structural=True,
parse_spec=True,
aliases=['control', 'control_signals', 'gate', 'gating_signal'],
aliases=[CONTROL, CONTROL_SIGNALS, 'gate', 'gating_signal'],
constructor_argument='gate'
)

Expand Down Expand Up @@ -526,6 +527,16 @@ def _register_control_signal_type(self, context=None):
registry=self._portRegistry,
)

def _validate_control_arg(self, gate):
"""Overrided to handle GatingMechanism-specific specifications"""
assert isinstance(gate, list), \
f"PROGRAM ERROR: 'gate' arg ({gate}) of {self.name} should have been converted to a list."
for spec in gate:
spec = _parse_port_spec(port_type=GatingSignal, owner=self, port_spec=spec)
if not (isinstance(spec, GatingSignal)
or (isinstance(spec, dict) and spec[PORT_TYPE] == GatingSignal)):
raise GatingMechanismError(f"Invalid specification for '{GATE}' argument of {self.name}: ({spec})")

def _instantiate_control_signal_type(self, gating_signal_spec, context):
"""Instantiate actual ControlSignal, or subclass if overridden"""
from psyneulink.core.components.ports.port import _instantiate_port
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -822,23 +822,23 @@ def __init__(self,
if MODULATES in kwargs:
# Don't allow **control** and **modulates** to both be specified
if control:
raise ControlSignalError(f"Both 'control' and '{MODULATES}' arguments are specified in the "
raise ControlSignalError(f"Both '{CONTROL}' and '{MODULATES}' arguments are specified in the "
f"constructor for '{name if name else self.__class__.__name__}; "
f"Should use just 'control'.")
f"Should use just '{CONTROL}'.")
# warnings.warn(f"The '{MODULATES}' argument (specified in the constructor for "
# f"'{name if name else self.__class__.__name__}') has been deprecated; "
# f"should use '{'control'}' going forward.")

if PROJECTIONS in kwargs:
raise ControlSignalError(f"Both '{MODULATES}' and '{PROJECTIONS}' arguments are specified "
f"in the constructor for '{name if name else self.__class__.__name__}; "
f"Should use just '{PROJECTIONS}' (or 'control') ")
f"Should use just '{PROJECTIONS}' (or '{CONTROL}') ")
control = kwargs.pop(MODULATES)

elif PROJECTIONS in kwargs:
# Don't allow **control** and **modulates** to both be specified
if control:
raise ControlSignalError(f"Both 'control' and '{PROJECTIONS}' arguments are specified "
raise ControlSignalError(f"Both '{CONTROL}' and '{PROJECTIONS}' arguments are specified "
f"in the constructor for '{name if name else self.__class__.__name__}; "
f"Must use just one or the other.")

Expand Down
7 changes: 4 additions & 3 deletions psyneulink/core/globals/keywords.py
Original file line number Diff line number Diff line change
Expand Up @@ -660,8 +660,7 @@ def _is_metric(metric):
PULSE_CLAMP = "pulse_clamp"
NO_CLAMP = "no_clamp"
LEARNING_RATE = "learning_rate"
CONTROL = 'CONTROL'
GATING = 'gating'
# CONTROL = 'CONTROL'
PROCESS_DEFAULT_PROJECTION_FUNCTION = "Default Projection Function"
PROCESS_EXECUTE = "ProcessExecute"
MECHANISM_EXECUTED_LOG_ENTRY = "Mechanism Executed"
Expand Down Expand Up @@ -764,6 +763,7 @@ def _is_metric(metric):
PREDICTION_MECHANISM_OUTPUT = "PredictionMechanismOutput"

MODULATORY_SIGNALS = 'modulatory_signals'
CONTROL = 'control'
CONTROL_SIGNALS = 'control_signals'
CONTROL_SIGNAL_SPECS = 'CONTROL_SIGNAL_SPECS'
CONTROLLED_PARAMS = 'CONTROLLED_PARAMS'
Expand All @@ -778,9 +778,10 @@ def _is_metric(metric):
ALLOCATION_SAMPLES = "allocation_samples"

# GatingMechanism
GATE = 'gate'
GATING = 'gating'
GATING_SIGNALS = 'gating_signals'
GATING_SIGNAL_SPECS = 'GATING_SIGNAL_SPECS'
GATE = 'GATE'
GATED_PORTS = 'GATED_PORTS'
GATING_PROJECTIONS = 'GatingProjections'
GATING_ALLOCATION = 'gating_allocation'
Expand Down
6 changes: 4 additions & 2 deletions tests/projections/test_projection_specifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -411,12 +411,14 @@ def test_formats_for_gating_specification_of_input_and_output_ports(self, input_
IN_NAME = G_IN[1]
else:
IN_NAME = G_IN
IN_CONTROL = pnl.CONTROL in repr(IN_NAME).split(".")[-1].upper()
# IN_CONTROL = pnl.CONTROL in repr(IN_NAME).split(".")[-1].upper()
IN_CONTROL = 'CONTROL' in repr(IN_NAME).split(".")[-1].upper()
if isinstance(G_OUT, tuple):
OUT_NAME = G_OUT[1]
else:
OUT_NAME = G_OUT
OUT_CONTROL = pnl.CONTROL in repr(OUT_NAME).split(".")[-1].upper()
# OUT_CONTROL = pnl.CONTROL in repr(OUT_NAME).split(".")[-1].upper()
OUT_CONTROL = 'CONTROL' in repr(OUT_NAME).split(".")[-1].upper()

T = pnl.TransferMechanism(
name='T-GATING',
Expand Down

0 comments on commit 59e0f3d

Please sign in to comment.