<commit_before>"""
FeatureMap and associated functions and classes.

$Id$
"""
__version__='$Revision$'

# CEB,JBFC

# To do:
# - this file is difficult to understand!
# - remove temporary testing code
# - give the variables better names!
# - get rid of non-used import statement

from Numeric import array, zeros, Float 
from topo.base.distribution import Distribution
from topo.base.topoobject import TopoObject

from topo.base.sheet import Sheet
from topo.sheets.generatorsheet import GeneratorSheet
from topo.base.utils import cross_product, frange
from topo.base.sheetview import SheetView
from math import pi

## temporary ...? ##
from topo.patterns.basic import GaussianGenerator, SineGratingGenerator
from topo.commands.basic import pattern_present, restore_input_generators, save_input_generators

import topo.base.registry
from topo.base import sheetview
from topo.base.registry import get_console

## Should only import this when using display option
import topo.tkgui.topoconsole 


class SineGratingPresenter(object):
    """Function object for presenting sine gratings, for use with e.g. measure_or_pref."""
    
    def __init__(self,sim=None,apply_output_fn=True,duration=1.0):
        self.sim=sim
        self.apply_output_fn=apply_output_fn
        self.duration=duration

    def __call__(self,features_values,param_dict):
        gen = SineGratingGenerator()

        ### JABHACKALERT!  Should be able to do this more cleanly.
        for param, value in param_dict.iteritems():
            update_generator = "gen." + param + "=" + repr(value)
            exec update_generator

        for feature,value in features_values.iteritems():
            update_generator = "gen." + feature + "=" + repr(value)
            exec update_generator

        inputs = dict().fromkeys(self.sim.objects(GeneratorSheet),gen)

        pattern_present(inputs, self.duration, self.sim, learning=False,
                        apply_output_fn=self.apply_output_fn)



def measure_or_pref(sim=None,num_phase=18,num_orientation=4,frequencies=[2.4],
                    scale=0.3,offset=0.0,display=False,
                    user_function_class=SineGratingPresenter,
                    apply_output_fn=False, duration=1.0):
    """Measure orientation maps, using a sine grating by default."""

    # CEBHACKALERT:
    # Is there some way that lissom_or.ty could set the value of a variable
    # that measure_or_pref reads, so that measure_or_pref could default to
    # duration=1.0, but when LISSOM is loaded switches to 0.06?  Otherwise
    # people playing around with CFSOM will think it doesn't work for
    # orientation maps...

    
    if not sim:
        sim = topo.base.registry.active_sim()

    if sim:

        if num_phase <= 0 or num_orientation <= 0:
            raise ValueError("num_phase and num_orientation must be greater than 0")
            
        else:
            user_function=user_function_class(sim,apply_output_fn, duration)
            step_phase=2*pi/num_phase
            step_orientation=pi/num_orientation
        
            feature_values = {"orientation": ( (0.0,pi), step_orientation, True),
                              "phase": ( (0.0,2*pi),step_phase,True),
                              "frequency": ((min(frequencies),max(frequencies)),frequencies,False)}

            x=MeasureFeatureMap(sim,feature_values)

            param_dict = {"scale":scale,"offset":offset}
            
            x.measure_maps(user_function, param_dict, display)

    else:
        TopoObject().warning('No active Simulator.')


def measure_activity():
    """Measure an activity map. Command called when opening an activity plot group panel.
    To be exact, just add the activity sheet_view for Sheets objects of the simulator
    """
    simulator = topo.base.registry.active_sim()
    for sheet in simulator.objects(Sheet).values():
        print sheet<commit_msg>Got rid of an unused debug print.<commit_after>"""
FeatureMap and associated functions and classes.

$Id$
"""
__version__='$Revision$'

# CEB,JBFC

# To do:
# - this file is difficult to understand!
# - remove temporary testing code
# - give the variables better names!
# - get rid of non-used import statement

from Numeric import array, zeros, Float 
from topo.base.distribution import Distribution
from topo.base.topoobject import TopoObject

from topo.base.sheet import Sheet
from topo.sheets.generatorsheet import GeneratorSheet
from topo.base.utils import cross_product, frange
from topo.base.sheetview import SheetView
from math import pi

## temporary ...? ##
from topo.patterns.basic import GaussianGenerator, SineGratingGenerator
from topo.commands.basic import pattern_present, restore_input_generators, save_input_generators

import topo.base.registry
from topo.base import sheetview
from topo.base.registry import get_console

## Should only import this when using display option
import topo.tkgui.topoconsole 


class SineGratingPresenter(object):
    """Function object for presenting sine gratings, for use with e.g. measure_or_pref."""
    
    def __init__(self,sim=None,apply_output_fn=True,duration=1.0):
        self.sim=sim
        self.apply_output_fn=apply_output_fn
        self.duration=duration

    def __call__(self,features_values,param_dict):
        gen = SineGratingGenerator()

        ### JABHACKALERT!  Should be able to do this more cleanly.
        for param, value in param_dict.iteritems():
            update_generator = "gen." + param + "=" + repr(value)
            exec update_generator

        for feature,value in features_values.iteritems():
            update_generator = "gen." + feature + "=" + repr(value)
            exec update_generator

        inputs = dict().fromkeys(self.sim.objects(GeneratorSheet),gen)

        pattern_present(inputs, self.duration, self.sim, learning=False,
                        apply_output_fn=self.apply_output_fn)



def measure_or_pref(sim=None,num_phase=18,num_orientation=4,frequencies=[2.4],
                    scale=0.3,offset=0.0,display=False,
                    user_function_class=SineGratingPresenter,
                    apply_output_fn=False, duration=1.0):
    """Measure orientation maps, using a sine grating by default."""

    # CEBHACKALERT:
    # Is there some way that lissom_or.ty could set the value of a variable
    # that measure_or_pref reads, so that measure_or_pref could default to
    # duration=1.0, but when LISSOM is loaded switches to 0.06?  Otherwise
    # people playing around with CFSOM will think it doesn't work for
    # orientation maps...

    
    if not sim:
        sim = topo.base.registry.active_sim()

    if sim:

        if num_phase <= 0 or num_orientation <= 0:
            raise ValueError("num_phase and num_orientation must be greater than 0")
            
        else:
            user_function=user_function_class(sim,apply_output_fn, duration)
            step_phase=2*pi/num_phase
            step_orientation=pi/num_orientation
        
            feature_values = {"orientation": ( (0.0,pi), step_orientation, True),
                              "phase": ( (0.0,2*pi),step_phase,True),
                              "frequency": ((min(frequencies),max(frequencies)),frequencies,False)}

            x=MeasureFeatureMap(sim,feature_values)

            param_dict = {"scale":scale,"offset":offset}
            
            x.measure_maps(user_function, param_dict, display)

    else:
        TopoObject().warning('No active Simulator.')


def measure_activity():
    """Measure an activity map. Command called when opening an activity plot group panel.
    To be exact, just add the activity sheet_view for Sheets objects of the simulator
    """
    simulator = topo.base.registry.active_sim()
    for sheet in simulator.objects(Sheet).values():
{'fraction_non_alphanumeric': 0.08886894075403949, 'fraction_numerical': 0.006924852526288792, 'mean_word_length': 3.020103092783505, 'pattern_counts': {'":': 10, '<': 7, '<?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': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1333497', 'n_tokens_mistral': 2274, 'n_tokens_neox': 2172, 'n_words': 609}