whisker_serial_order.models


Copyright © 2016-2018 Rudolf Cardinal (rudolf@pobox.com).

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.


SQLAlchemy models and other data storage classes for the serial order task.

class whisker_serial_order.models.ChoiceHoleRestriction(description: str = '', hole_separator: str = ', ', group_separator: str = ';', permissible_combinations: List[List[int]] = None)[source]

Class to describe choice hole restrictions.

Variables:

permissible_combinations – variable of type Set[Tuple[int]], where the tuples are sorted sequences of hole numbers. If the set is not empty, then only such combinations are allowed.

Parameters:
  • description – textual description like “1,3; 2,4” to restrict to the combinations of “hole 1 versus hole 3” and “hole 2 versus hole 4”.
  • hole_separator – string used to separate holes in a group (usually “,”).
  • group_separator – string used to separate groups (usually “;”).
  • permissible_combinations – list of lists of spatial hole numbers, as an alternative to using description. Use one or the other.
Raises:

argparse.ArgumentTypeError – if its arguments are invalid.

description() → str[source]

Returns the description that can be used to recreate this object.

permissible(choice_holes: Iterable[int]) → bool[source]

Is the supplied list of choice holes compatible with the restrictions?

Parameters:choice_holes – list of spatial holes.
class whisker_serial_order.models.ChoiceHoleRestrictionType(*args, **kwargs)[source]

SQLAlchemy data type to store ChoiceHoleRestriction in a database. See http://docs.sqlalchemy.org/en/latest/core/custom_types.html.

Construct a TypeDecorator.

Arguments sent here are passed to the constructor of the class assigned to the impl class level attribute, assuming the impl is a callable, and the resulting object is assigned to the self.impl instance attribute (thus overriding the class attribute of the same name).

If the class level impl is not a callable (the unusual case), it will be assigned to the same instance attribute ‘as-is’, ignoring those arguments passed to the constructor.

Subclasses can override this to customize the generation of self.impl entirely.

process_bind_param(value: Any, dialect: sqlalchemy.engine.default.DefaultDialect) → Optional[str][source]

Converts a bound Python parameter to the database value.

Parameters:
Returns:

string (outbound to database)

process_literal_param(value: Any, dialect: sqlalchemy.engine.default.DefaultDialect) → str[source]

Receive a literal parameter value to be rendered inline within a statement.

(An abstract method of TypeDecorator, so we should implement it.)

Parameters:
  • value – a Python value
  • dialect – SQLAlchemy database dialect.
Returns:

a string to be baked into some SQL

process_result_value(value: Any, dialect: sqlalchemy.engine.default.DefaultDialect) → Optional[whisker_serial_order.models.ChoiceHoleRestriction][source]

Receive a result-row column value to be converted.

Parameters:
  • value – data fetched from the database (will be a string).
  • dialect – SQLAlchemy database dialect.
Returns:

a ChoiceHoleRestriction object if the string is valid

python_type

Returns the Python type object expected to be returned by instances of this type, if known. It’s ChoiceHoleRestriction.

class whisker_serial_order.models.Config(**kwargs)[source]

SQLAlchemy model for the config table.

Must be clonable by deepcopy_sqla_object(), so must accept empty kwargs.

clone(session: sqlalchemy.orm.session.Session, read_only: bool = False) → whisker_serial_order.models.Config[source]

Makes a copy of itself and adds it to the specified SQLAlchemy session.

Parameters:
  • session – the SQLAlchemy session into which to insert the copy.
  • read_only – sets the read_only property of the copy.
Returns:

the copy.

get_modified_at_pretty() → Optional[str][source]

Gets the modified_at time as a human-readable string.

get_n_stages() → int[source]

Returns the number of stages.

has_stages() → bool[source]

Does the config have at least one stage?

class whisker_serial_order.models.ConfigStage(**kwargs)[source]

SQLAlchemy model for the config_stage table.

Must be clonable by deepcopy_sqla_object(), so must accept empty kwargs.

choice_hole_restriction_desc

Returns the description of any choice_hole_restriction.

serial_pos_restriction_desc

Returns the description of any serial_pos_restriction.

class whisker_serial_order.models.Event(**kwargs)[source]

SQLAlchemy model for the event table.

class whisker_serial_order.models.SequenceTiming(**kwargs)[source]

SQLAlchemy model for the sequence_timing table.

record_hole_lit(timestamp: arrow.arrow.Arrow) → None[source]

Records that the hole has been illuminated.

record_hole_response(timestamp: arrow.arrow.Arrow) → None[source]

Records that the hole has been responded to.

record_mag_lit(timestamp: arrow.arrow.Arrow) → None[source]

Records that the food magazine has been illuminated.

record_mag_response(timestamp: arrow.arrow.Arrow) → None[source]

Records that the food magazine has been responded to.

class whisker_serial_order.models.SerialPosRestriction(description: str = '', position_separator: str = ', ', group_separator: str = ';', permissible_combinations: List[List[int]] = None)[source]

Class to describe restrictions on the serial order positions offered at the choice phase.

Variables:

permissible_combinations – variable of type Set[Tuple[int]], where the tuples are sorted sequences of serial order position numbers (1 being the first). If the set is not empty, then only such combinations are allowed.

Parameters:
  • description – textual description like “1,3; 2,3” to restrict to the combinations of “serial position 1 versus 3” and “serial position 2 versus 3”.
  • position_separator – string used to separate positions (usually “,”).
  • group_separator – string used to separate groups (usually “;”).
  • permissible_combinations – list of lists of serial order positions, as an alternative to using description. Use one or the other.
Raises:

argparse.ArgumentTypeError – if its arguments are invalid.

description() → str[source]

Returns the description that can be used to recreate this object.

permissible(serial_positions: Iterable[int]) → bool[source]

Is the supplied list of serial order position to be tested compatible with the restrictions?

Parameters:serial_positions – the serial order positions to be presented in the choice phase
class whisker_serial_order.models.SerialPosRestrictionType(*args, **kwargs)[source]

SQLAlchemy data type to store SerialPosRestriction in a database. See http://docs.sqlalchemy.org/en/latest/core/custom_types.html.

Construct a TypeDecorator.

Arguments sent here are passed to the constructor of the class assigned to the impl class level attribute, assuming the impl is a callable, and the resulting object is assigned to the self.impl instance attribute (thus overriding the class attribute of the same name).

If the class level impl is not a callable (the unusual case), it will be assigned to the same instance attribute ‘as-is’, ignoring those arguments passed to the constructor.

Subclasses can override this to customize the generation of self.impl entirely.

process_bind_param(value: Any, dialect: sqlalchemy.engine.default.DefaultDialect) → Optional[str][source]

Converts a bound Python parameter to the database value.

Parameters:
Returns:

string (outbound to database)

process_literal_param(value: Any, dialect: sqlalchemy.engine.default.DefaultDialect) → str[source]

Receive a literal parameter value to be rendered inline within a statement.

(An abstract method of TypeDecorator, so we should implement it.)

Parameters:
  • value – a Python value
  • dialect – SQLAlchemy database dialect.
Returns:

a string to be baked into some SQL

process_result_value(value: Any, dialect: sqlalchemy.engine.default.DefaultDialect) → Optional[whisker_serial_order.models.SerialPosRestriction][source]

Receive a result-row column value to be converted.

Parameters:
  • value – data fetched from the database (will be a string).
  • dialect – SQLAlchemy database dialect.
Returns:

a SerialPosRestriction object if the string is valid

python_type

Returns the Python type object expected to be returned by instances of this type, if known. It’s SerialPosRestriction.

class whisker_serial_order.models.TaskSession(**kwargs)[source]

SQLAlchemy model for the session table (renamed from Session to TaskSession to avoid confusion with SQLAlchemy Session).

class whisker_serial_order.models.Trial(**kwargs)[source]

SQLAlchemy model for the trial table.

get_choice_holes_as_str() → str[source]

Returns a CSV string of the choice holes.

get_sequence_holes_as_str() → str[source]

Returns a CSV string of the sequence holes.

record_choice_offered(timestamp: arrow.arrow.Arrow) → None[source]

Records the time that the choice was offered.

record_initiation(timestamp: arrow.arrow.Arrow) → None[source]

Records the time of trial initiation.

record_iti_start(timestamp: arrow.arrow.Arrow) → None[source]

Records the time that the intertrial interval started.

record_premature(timestamp: arrow.arrow.Arrow) → None[source]

Records a premature response.

record_reinf_collection(timestamp: arrow.arrow.Arrow) → None[source]

Records when the subject collected reinforcement.

record_reinforcement(timestamp: arrow.arrow.Arrow) → None[source]

Records the delivery of reinforcement.

record_response(response_hole: int, timestamp: arrow.arrow.Arrow) → bool[source]

Records the response during the choice phase. IMPLEMENTS THE KEY TASK RULE: “Which came first?”

Parameters:
  • response_hole – the hole that the subject responded to
  • timestamp – when the response occurred
  • the response correct? (was) –
record_sequence_hole_lit(timestamp: arrow.arrow.Arrow, holenum: int) → None[source]

Records the time and hole number that a sequence hole was illuminated.

record_sequence_hole_response(timestamp: arrow.arrow.Arrow) → None[source]

Records a response to a sequence hole.

record_sequence_mag_lit(timestamp: arrow.arrow.Arrow) → None[source]

Records illumination of the food magazine during the initial sequence.

record_sequence_mag_response(timestamp: arrow.arrow.Arrow) → None[source]

Records a response to the food magazine during the initial sequence.

set_choice(choice_holes: List[int]) → None[source]

Sets the choice holes offered in the second phase of the trial.

Parameters:choice_holes – a list, of length 2, of the hole numbers.
set_sequence(sequence_holes: List[int]) → None[source]

Sets the sequence for the first phase of the trial.

Parameters:sequence_holes – ordered list of hole numbers.
was_reinf_collected() → bool[source]

Was reinforcement collected?

was_reinforced() → bool[source]

Was the trial reinforced?

class whisker_serial_order.models.TrialPlan(sequence: List[int], serial_order_choice: List[int])[source]

Describes the planned sequence of holes to be offered, and then holes to be tested, for a single trial.

Variables:
  • sequence – sequence of 1-based hole numbers to be offered
  • serial_order_choice – serial positions within the offered sequence to offer as choices (will be SORTED as they are offered simultaneously)
  • hole_choice – hole positions to offer for the choice (will be SORTED as they are offered simultaneously)

What’s independent?

  • sequence and serial_order_choice are independent
  • sequence and correct_is_on_right are not independent (they are mediated by serial_order_choice)
  • serial_order_choice and correct_is_on_right are not independent (they are mediated by sequence)
Parameters:
  • sequence – the sequence of hole numbers to be offered (e.g. [3, 4, 1] to present hole 3, hole 4, and hole 1 in that order).
  • serial_order_choice – the serial order positions to be tested (e.g. [1, 3] for the first and third).
correct_hole

The correct hole number, from the test phase.

Type:Returns
correct_incorrect_holes

(correct_hole, incorrect_hole) for the test phase.

Type:Returns
Type:tuple
correct_is_on_right

Is the correct hole on the right?

Type:Returns
incorrect_hole

The incorrect hole number, for the test phase.

Type:Returns
meets_restrictions(choice_hole_restriction: whisker_serial_order.models.ChoiceHoleRestriction = None, serial_pos_restriction: whisker_serial_order.models.SerialPosRestriction = None) → bool[source]

Does the trial plan meet the specified restrictions?

sequence_length

The length of the sequence presented.

Type:Returns
whisker_serial_order.models.serial_order_to_spatial(hole_sequence: List[int], seq_positions: List[int]) → List[int][source]

Converts a first-phase hole sequence and a list of serial order positions (at the choice phase) into a list of spatial holes at test.

Parameters:
  • hole_sequence – ordered list of spatial hole numbers to be presented in the first phase of the task, e.g. [3, 1, 4].
  • seq_positions – list of serial orders, e.g [1, 3] for the first and third in the sequence.
Returns:

list of spatial hole numbers (e.g. [3, 4] in this example).

whisker_serial_order.models.spatial_to_serial_order(hole_sequence: List[int], holes: List[int]) → List[int][source]

Converts a temporal sequence of spatial holes into a list of serial order positions.

Converts the list of spatial holes in use (hole_sequence) and the temporal sequence of hole indexes (holes) into a sequence of spatial hole numbers.

Parameters:
  • hole_sequence – ordered list of spatial hole numbers to be presented in the first phase of the task, e.g. [3, 1, 4].
  • holes – spatial hole numbers to be enquired about: “what was the temporal order of these holes in the first phase?”; e.g. [4, 3].
Returns:

[3, 1]).

Return type:

list of serial order positions (in this example