<commit_before>#!/usr/bin/python

import os, sys, random, csv, time
import numpy as np
import datetime as dt
from pyoperant import utils, components, local, hwio
from pyoperant.tricks import two_alt_choice

try:
    import simplejson as json
except ImportError:
    import json

class EvidenceAccumExperiment(two_alt_choice.TwoAltChoiceExp):
    """docstring for Experiment"""
    def __init__(self, *args, **kwargs):
        super(EvidenceAccumExperiment, self).__init__(*args, **kwargs)
        self.build_transition_matrices()

    def save(self):
        self.snapshot_f = os.path.join(self.parameters['experiment_path'], self.timestamp+'.json')
        with open(self.snapshot_f, 'wb') as config_snap:
            json.dump(self.parameters,
                      config_snap,
                      sort_keys=True,
                      indent=4,
                      cls=utils.NumpyAwareJSONEncoder)

    def build_transition_matrices(self):
        """run through the transitions for each stimulus and generate transition matrixes"""
        n = len(self.parameters['stim_map'])

        for stim_class, class_params in self.parameters['classes'].items():
            arr = np.zeros((n,n),np.float_)
            for a,b in class_params['transitions']:
                arr[a,b] = 1.0

            self.parameters['classes'][stim_class]['evidence_arrays'] = arr
            self.log.debug('added class %s evidence array %s' % (stim_class,arr))

        stim_classes = self.parameters['classes'].keys()
        assert len(stim_classes) == 2

        for this_class in stim_classes:
            other_class = [cl for cl in stim_classes if (cl != this_class)][0]
            trans = self.parameters['odds'] \
                  * self.parameters['classes'][this_class]['evidence_arrays'] \
                  + self.parameters['classes'][other_class]['evidence_arrays']
            trans[0,1:] = 1.0
            trans = np.cumsum(trans,axis=1)
            trans = trans / trans[:,-1][:,None] # I don't get why it suddenly works to append '[:,None]'
            self.parameters['classes'][this_class]['transition_cdf'] = trans
            self.log.debug('added class %s transition cdf %s' % (this_class, trans))

    def get_stimuli(self,trial_class):
        """ take trial class and return a tuple containing the stimulus event to play and a list of additional events

        """

        input_files = []
        motif_ids = []

        # use transition CDF to get iteratively get next motif id
        append_mot = True
        mid = 0
        while append_mot:
            if len(motif_ids) < self.parameters['strlen_min']:
                mid = (self.parameters['classes'][trial_class]['transition_cdf'][mid] < random.random()).sum()
                motif_ids.append(mid)
            elif len(motif_ids) == (self.parameters['strlen_max']+1):
                if self.parameters['decay'] < 1.0:
                    motif_ids = []
                    mid = 0
                else:
                    append_mot = False
            elif random.random() < self.parameters['decay']:
                mid = (self.parameters['classes'][trial_class]['transition_cdf'][mid] < random.random()).sum()
                motif_ids.append(mid)
            else:
                append_mot = False

        motifs = [self.parameters['stim_map'][mid] for mid in motif_ids]

        motif_isi = [max(random.gauss(self.parameters['isi_mean'], self.parameters['isi_stdev']),0.0) for mot in motifs]
        motif_isi[-1] = 0.0

        input_files = [(self.parameters['stims'][motif_name], isi) for motif_name, isi in zip(motifs,motif_isi)]
        filename =  os.path.join(self.parameters['stim_path'], ''.join(motifs) + '.wav')
        stim, epochs = utils.concat_wav(input_files,filename)
        stim.name = ''.join(motifs)
        self.log.debug('stim %s created at %s' % (stim.name,stim.file_origin))

        for ep in epochs:
            self.log.debug('old epoch.name: %s' % ep.name)
            for stim_name,f_name in self.parameters['stims'].items():
                if ep.name == f_name:
                    ep.name = stim_name
            self.log.debug('new epoch.name: %s' % ep.name)

        return stim, epochs
<commit_msg>added option for 'decay'<commit_after>#!/usr/bin/python

import os, sys, random, csv, time
import numpy as np
import datetime as dt
from pyoperant import utils, components, local, hwio
from pyoperant.tricks import two_alt_choice

try:
    import simplejson as json
except ImportError:
    import json

class EvidenceAccumExperiment(two_alt_choice.TwoAltChoiceExp):
    """docstring for Experiment"""
    def __init__(self, *args, **kwargs):
        super(EvidenceAccumExperiment, self).__init__(*args, **kwargs)
        self.build_transition_matrices()

    def save(self):
        self.snapshot_f = os.path.join(self.parameters['experiment_path'], self.timestamp+'.json')
        with open(self.snapshot_f, 'wb') as config_snap:
            json.dump(self.parameters,
                      config_snap,
                      sort_keys=True,
                      indent=4,
                      cls=utils.NumpyAwareJSONEncoder)

    def build_transition_matrices(self):
        """run through the transitions for each stimulus and generate transition matrixes"""
        n = len(self.parameters['stim_map'])

        for stim_class, class_params in self.parameters['classes'].items():
            arr = np.zeros((n,n),np.float_)
            for a,b in class_params['transitions']:
                arr[a,b] = 1.0

            self.parameters['classes'][stim_class]['evidence_arrays'] = arr
            self.log.debug('added class %s evidence array %s' % (stim_class,arr))

        stim_classes = self.parameters['classes'].keys()
        assert len(stim_classes) == 2

        for this_class in stim_classes:
            other_class = [cl for cl in stim_classes if (cl != this_class)][0]
            trans = self.parameters['odds'] \
                  * self.parameters['classes'][this_class]['evidence_arrays'] \
                  + self.parameters['classes'][other_class]['evidence_arrays']
            trans[0,1:] = 1.0
            trans = np.cumsum(trans,axis=1)
            trans = trans / trans[:,-1][:,None] # I don't get why it suddenly works to append '[:,None]'
            self.parameters['classes'][this_class]['transition_cdf'] = trans
            self.log.debug('added class %s transition cdf %s' % (this_class, trans))

    def next_motif(self,mid,trial_class):
        return (self.parameters['classes'][trial_class]['transition_cdf'][mid] < random.random()).sum()

    def get_stimuli(self,trial_class):
        """ take trial class and return a tuple containing the stimulus event to play and a list of additional events

        """

        input_files = []
        motif_ids = []

        # use transition CDF to get iteratively get next motif id
        append_mot = True
        mid = 0
        if 'decay' not in self.parameters.keys():
            self.parameters['decay'] = 1.0

        if self.parameters['decay'] < 1.0:
            while append_mot:
                if len(motif_ids) < self.parameters['strlen_min']:
                    mid = self.next_motif(self,mid,trial_class)
                    motif_ids.append(mid)
                elif len(motif_ids) == (self.parameters['strlen_max']+1):
                    motif_ids = []
                    mid = 0
                elif random.random() < self.parameters['decay']:
                    mid = self.next_motif(self,mid,trial_class)
                    motif_ids.append(mid)
                else:
                    append_mot = False
        else:
            while append_mot:
                if len(motif_ids) < self.parameters['strlen_min']:
                    mid = self.next_motif(self,mid,trial_class)
                    motif_ids.append(mid)
                else:
                    append_mot = False

        motifs = [self.parameters['stim_map'][mid] for mid in motif_ids]

        motif_isi = [max(random.gauss(self.parameters['isi_mean'], self.parameters['isi_stdev']),0.0) for mot in motifs]
        motif_isi[-1] = 0.0

        input_files = [(self.parameters['stims'][motif_name], isi) for motif_name, isi in zip(motifs,motif_isi)]
        filename =  os.path.join(self.parameters['stim_path'], ''.join(motifs) + '.wav')
        stim, epochs = utils.concat_wav(input_files,filename)
        stim.name = ''.join(motifs)
        self.log.debug('stim %s created at %s' % (stim.name,stim.file_origin))

        for ep in epochs:
            self.log.debug('old epoch.name: %s' % ep.name)
            for stim_name,f_name in self.parameters['stims'].items():
                if ep.name == f_name:
                    ep.name = stim_name
            self.log.debug('new epoch.name: %s' % ep.name)

        return stim, epochs

{'fraction_non_alphanumeric': 0.12286650842093365, 'fraction_numerical': 0.004973437323386459, 'mean_word_length': 2.263740317226116, 'pattern_counts': {'":': 0, '<': 13, '<?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': '1538305', 'n_tokens_mistral': 2686, 'n_tokens_neox': 2546, 'n_words': 580}