def dexp(stack): """ Applies a double-exponential function entry-by-entry to the datastream: y = v1 - v2*exp[-exp{v3*(x-v4)}] where x is the input matrix and v1,v2,v3,v4 are fitted parameters applied to each matrix entry (the same across all entries) Performs a fit on the nonlinearity parameters, as well. """ # load the incoming pred/resp to guess at initial conditions resp = stack.modules[-1].unpack_data('resp', use_dout=True) pred = stack.modules[-1].unpack_data('pred', use_dout=True) if resp.shape[0] > pred.shape[0]: resp = resp[:pred.shape[0], :] keepidx = np.isfinite(resp) * np.isfinite(pred) resp = resp[keepidx] pred = pred[keepidx] # choose phi s.t. dexp starts as almost a straight line # phi=[max_out min_out slope mean_in] meanr = np.nanmean(resp) stdr = np.nanstd(resp) phi = np.array( [[meanr - stdr * 4, stdr * 8, np.std(pred) / 10, np.mean(pred)]]) log.info(phi) stack.append(nm.nonlin.gain, nltype='dexp', fit_fields=['phi'], phi=phi) mini_fit(stack, mods=['nonlin.gain'])
def logsig(stack): # a=self.phi[0,0] # baseline # b=self.phi[0,1] # amplitude # c=self.phi[0,2] # inflection # d=self.phi[0,3] # slope # Y=a+b/(1+np.exp(-(X-c)/d)) resp = stack.modules[-1].unpack_data('resp', use_dout=True) pred = stack.modules[-1].unpack_data('pred', use_dout=True) meanr = np.mean(resp) stdr = np.std(resp) phi = np.array([[meanr - stdr * 3, stdr * 6, np.mean(pred), np.std(pred)]]) stack.append(nm.nonlin.gain, nltype='logsig', fit_fields=['phi'], phi=phi) mini_fit(stack, mods=['nonlin.gain'])
def exp(stack): """ Applies an exponential function entry-by-entry to the datastream: y = exp(v1*(x+v2)) where x is the input matrix and v1, v2 are fitted parameters applied to each matrix entry (the same across all entries) Performs a fit on the nonlinearity parameters, as well. """ stack.append(nm.nonlin.gain, nltype='exp', fit_fields=['phi'], phi=np.array([[1, 1]])) mini_fit(stack, mods=['nonlin.gain'])
def behgain(stack): """ Applies a linear pupil gain function entry-by-entry to the datastream: y = v1 + v2*x + v3*p + v4*x*p where x is the input matrix, p is the matrix of pupil diameters, and v1,v2 are fitted parameters applied to each matrix entry (the same across all entries) """ theta0 = [0, 1, 0, 0] stack.append(nm.state.state_gain, gain_type='lingain', state_var='behavior_condition', fit_fields=['theta'], theta=theta0) mini_fit(stack, mods=['state.state_gain']) log.info(stack.modules[-1].theta)
def behgainctl(stack): """ Applies a DC gain function entry-by-entry to the datastream: y = v1 + v2*x + <randomly shuffled pupil dc-gain> where x is the input matrix and v1,v2 are fitted parameters applied to each matrix entry (the same across all entries) """ theta0 = [0, 1, 0, 0] stack.append(nm.state.state_gain, gain_type='lingainctl', state_var='behavior_condition', fit_fields=['theta'], theta=theta0) mini_fit(stack, mods=['state.state_gain']) log.info(stack.modules[-1].theta)
def fir(stack, n_coefs, random): """ Adds a temporal bin finite impluse response (FIR) filter to the datastream. This filter can serve as either the entire STRF for the cell and be fitted as such, or as the temporal filter in the factorized STRF if used in conjuction with the weight channel spectral filter. """ stack.append(aux.normalize) stack.append(filters.FIR, num_coefs=n_coefs, random_init=random) if 'mini_fit' in stack.meta.keys() and not stack.meta['mini_fit']: pass else: mini_fit( stack, mods=['filters.weight_channels', 'filters.fir', 'filters.stp'])
def tanhsig(stack): """ Applies a tanh sigmoid function(commonly used as a neural net activation function) entry-by-entry to the datastream: y = v1*tanh(v2*x - v3) + v1 where x is the input matrix and v1,v2,v3 are fitted parameters applied to each matrix entry (the same across all entries) Performs a fit on the nonlinearity parameters, as well. """ stack.append(nm.nonlin.gain, nltype='tanh', fit_fields=['phi'], phi=[1, 1, 0]) mini_fit(stack, mods=['nonlin.gain'])
def pupgainctl(stack): """ Applies a DC gain function entry-by-entry to the datastream: y = v1 + v2*x + <randomly shuffled pupil dc-gain> where x is the input matrix and v1,v2 are fitted parameters applied to each matrix entry (the same across all entries) Only uses first pupil variable (raw pupil, not derivatives) """ theta0 = [0, 1, 0, 0] stack.append(nm.state.state_gain, gain_type='lingainctl', fit_fields=['theta'], theta=theta0) mini_fit(stack, mods=['state.state_gain']) log.info(stack.modules[-1].theta)