<commit_before>"""
Contains a variety of sensory models, specifically models for the
visual pathway.
"""
import topo
import param
import numbergen
import lancet
import numpy
import imagen


from imagen.patterncoordinator import PatternCoordinator

from topo.base.arrayutil import DivideWithConstant
from topo.submodel import Model
from topo import sheet, transferfn

from collections import OrderedDict


class SensoryModel(Model):

    dims = param.List(default=['xy'],class_=str,doc="""
        Stimulus dimensions to include, out of the possible list:
          :'xy': Position in x and y coordinates""")

    num_inputs = param.Integer(default=2,bounds=(1,None),doc="""
        How many input patterns to present per unit area at each
        iteration, when using discrete patterns (e.g. Gaussians).""")



class VisualInputModel(SensoryModel):

    dims = param.List(default=['xy','or'],class_=str,doc="""
        Stimulus dimensions to include, out of the possible list:
          :'xy': Position in x and y coordinates
          :'or': Orientation
          :'od': Ocular dominance
          :'dy': Disparity
          :'dr': Direction of motion
          :'sf': Spatial frequency
          :'cr': Color (not implemented yet)""")

    area = param.Number(default=1.0,bounds=(0,None),
        inclusive_bounds=(False,True),doc="""
        Linear size of cortical area to simulate.
        2.0 gives a 2.0x2.0 Sheet area in V1.""")

    dim_fraction = param.Number(default=0.7,bounds=(0.0,1.0),doc="""
        Fraction by which the input brightness varies between the two
        eyes.  Only used if 'od' in 'dims'.""")

    contrast=param.Number(default=70, bounds=(0,100),doc="""
        Brightness of the input patterns as a contrast (percent). Only
        used if 'od' not in 'dims'.""")

    sf_spacing=param.Number(default=2.0,bounds=(1,None),doc="""
        Determines the factor by which successive SF channels increase
        in size.  Only used if 'sf' in 'dims'.""")

    sf_channels=param.Integer(default=2,bounds=(1,None),softbounds=(1,4),doc="""
        Number of spatial frequency channels. Only used if 'sf' in 'dims'.""")

    max_disparity = param.Number(default=4.0,bounds=(0,None),doc="""
        Maximum disparity between input pattern positions in the left
        and right eye. Only used if 'dy' in 'dims'.""")

    num_lags = param.Integer(default=4, bounds=(1,None),doc="""
        Number of successive frames before showing a new input
        pattern.  This also determines the number of connections
        between each individual LGN sheet and V1. Only used if 'dr' in
        'dims'.""")

    speed=param.Number(default=2.0/24.0,bounds=(0,None),
                       softbounds=(0,3.0/24.0),doc="""
        Distance in sheet coordinates between successive frames, when
        translating patterns. Only used if 'dr' in 'dims'.""")

    __abstract = True


    def property_setup(self, properties):
        properties = super(VisualInputModel, self).property_setup(properties)
        properties['binocular'] = 'od' in self.dims or 'dy' in self.dims
        properties['SF']=range(1,self.sf_channels+1) if 'sf' in self.dims else [1]
        properties['lags'] = range(self.num_lags) if 'dr' in self.dims else [0]

        if 'dr' in self.dims and not numbergen.RandomDistribution.time_dependent:
            numbergen.RandomDistribution.time_dependent = True
            self.message('Setting time_dependent to True for motion model.')
        return properties


    def training_pattern_setup(self, **overrides):
        # all the below will eventually end up in PatternCoordinator!
        disparity_bound = 0.0
        position_bound_x = self.area/2.0+0.25
        position_bound_y = self.area/2.0+0.25

        if 'dy' in self.dims:
            disparity_bound = self.max_disparity*0.041665/2.0
            #TFALERT: Formerly: position_bound_x = self.area/2.0+0.2
            position_bound_x -= disparity_bound

        pattern_labels=['LeftRetina','RightRetina'] if self['binocular'] else ['Retina']
        # all the above will eventually end up in PatternCoordinator!
        params = dict(features_to_vary=self.dims,
                      pattern_labels=pattern_labels,
                      pattern_parameters={'size': 0.088388 if 'or' in self.dims else 3*0.088388,
                                          'aspect_ratio': 4.66667 if 'or' in self.dims else 1.0,
                                          'scale': self.contrast/100.0},<commit_msg>Introduce position buffer when motion is used<commit_after>"""
Contains a variety of sensory models, specifically models for the
visual pathway.
"""
import topo
import param
import numbergen
import lancet
import numpy
import imagen


from imagen.patterncoordinator import PatternCoordinator

from topo.base.arrayutil import DivideWithConstant
from topo.submodel import Model
from topo import sheet, transferfn

from collections import OrderedDict


class SensoryModel(Model):

    dims = param.List(default=['xy'],class_=str,doc="""
        Stimulus dimensions to include, out of the possible list:
          :'xy': Position in x and y coordinates""")

    num_inputs = param.Integer(default=2,bounds=(1,None),doc="""
        How many input patterns to present per unit area at each
        iteration, when using discrete patterns (e.g. Gaussians).""")



class VisualInputModel(SensoryModel):

    dims = param.List(default=['xy','or'],class_=str,doc="""
        Stimulus dimensions to include, out of the possible list:
          :'xy': Position in x and y coordinates
          :'or': Orientation
          :'od': Ocular dominance
          :'dy': Disparity
          :'dr': Direction of motion
          :'sf': Spatial frequency
          :'cr': Color (not implemented yet)""")

    area = param.Number(default=1.0,bounds=(0,None),
        inclusive_bounds=(False,True),doc="""
        Linear size of cortical area to simulate.
        2.0 gives a 2.0x2.0 Sheet area in V1.""")

    dim_fraction = param.Number(default=0.7,bounds=(0.0,1.0),doc="""
        Fraction by which the input brightness varies between the two
        eyes.  Only used if 'od' in 'dims'.""")

    contrast=param.Number(default=70, bounds=(0,100),doc="""
        Brightness of the input patterns as a contrast (percent). Only
        used if 'od' not in 'dims'.""")

    sf_spacing=param.Number(default=2.0,bounds=(1,None),doc="""
        Determines the factor by which successive SF channels increase
        in size.  Only used if 'sf' in 'dims'.""")

    sf_channels=param.Integer(default=2,bounds=(1,None),softbounds=(1,4),doc="""
        Number of spatial frequency channels. Only used if 'sf' in 'dims'.""")

    max_disparity = param.Number(default=4.0,bounds=(0,None),doc="""
        Maximum disparity between input pattern positions in the left
        and right eye. Only used if 'dy' in 'dims'.""")

    num_lags = param.Integer(default=4, bounds=(1,None),doc="""
        Number of successive frames before showing a new input
        pattern.  This also determines the number of connections
        between each individual LGN sheet and V1. Only used if 'dr' in
        'dims'.""")

    speed=param.Number(default=2.0/24.0,bounds=(0,None),
                       softbounds=(0,3.0/24.0),doc="""
        Distance in sheet coordinates between successive frames, when
        translating patterns. Only used if 'dr' in 'dims'.""")

    motion_buffer=param.Number(default=0.15,bounds=(0,None),doc="""
        Buffer in sheet coordinates by which the range should be
        extended where pattern are drawn from. Only used if
        'dr' in 'dims'.""")

    __abstract = True


    def property_setup(self, properties):
        properties = super(VisualInputModel, self).property_setup(properties)
        properties['binocular'] = 'od' in self.dims or 'dy' in self.dims
        properties['SF']=range(1,self.sf_channels+1) if 'sf' in self.dims else [1]
        properties['lags'] = range(self.num_lags) if 'dr' in self.dims else [0]

        if 'dr' in self.dims and not numbergen.RandomDistribution.time_dependent:
            numbergen.RandomDistribution.time_dependent = True
            self.message('Setting time_dependent to True for motion model.')
        return properties


    def training_pattern_setup(self, **overrides):
        # all the below will eventually end up in PatternCoordinator!
        disparity_bound = 0.0
        position_bound_x = self.area/2.0+0.25
        position_bound_y = self.area/2.0+0.25

        if 'dy' in self.dims:
            disparity_bound = self.max_disparity*0.041665/2.0
            #TFALERT: Formerly: position_bound_x = self.area/2.0+0.2
            position_bound_x -= disparity_bound

        if 'dr' in self.dims:
            #TFALERT: Should probably depend on speed
            position_bound_x+=self.position_buffer_motion
            position_bound_y+=self.position_buffer_motion

        pattern_labels=['LeftRetina','RightRetina'] if self['binocular'] else ['Retina']
        # all the above will eventually end up in PatternCoordinator!
        params = dict(features_to_vary=self.dims,
                      pattern_labels=pattern_labels,
                      pattern_parameters={'size': 0.088388 if 'or' in self.dims else 3*0.088388,
                                          'aspect_ratio': 4.66667 if 'or' in self.dims else 1.0,
                                          'scale': self.contrast/100.0},
{'fraction_non_alphanumeric': 0.11181635459642442, 'fraction_numerical': 0.022638315878557073, 'mean_word_length': 2.81979797979798, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1181744', 'n_tokens_mistral': 2860, 'n_tokens_neox': 2699, 'n_words': 830}