def __init__(self, params, Settings): from utils.SignalAnalysis import Signal, Envelope # List of Parameters that will be modified during evolution self.evolKeys = Settings['evolKeys'] # Initialize Wilson-Cowan Model self.simFreq = 500 # simulation frequency in seconds self.WC = WCModel( Cmat=Settings['Cmat'], Dmat=Settings['Dmat']) # Initialize Wilson Cowan model self.NumberStrRegions = self.WC.params['N'] self.WC.params[ 'duration'] = Settings['Duration'] * 1000 # Duration in ms self.WC.params['dt'] = 1000 * (1 / self.simFreq) # timestep in ms # Runt WC simulations with parameter self._runWC(params) # Calculate Low-pass Envelope of Carrier Frequency self.Limits = Settings['CarrierFreq'] ExcSignal = Signal(self.WC.outputs.exc, self.simFreq) self.ExcEnv = ExcSignal.getLowPassEnvelope(Limits=self.Limits) # Downsample Envelope self.downNum = 300 # has to be the same as for MEG CCD self.dExcEnv = Envelope(self.ExcEnv).downsampleSignal(self.downNum) # Get Fit empCCD = Settings['empCCD'] self.Fit = self.getFit(empCCD)
def test_compare_w_neurolib_native_model(self): """ Compare with neurolib's native Wilson-Cowan model. """ # run this model wc_multi = self._create_node() multi_result = wc_multi.run( DURATION, DT, ZeroInput(wc_multi.num_noise_variables).as_array(DURATION, DT), backend="numba") # run neurolib's model wc_neurolib = WCModel(seed=SEED) wc_neurolib.params["duration"] = DURATION wc_neurolib.params["dt"] = DT # match initial state wc_neurolib.params["exc_init"] = np.array([[wc_multi.initial_state[0]] ]) wc_neurolib.params["inh_init"] = np.array([[wc_multi.initial_state[1]] ]) wc_neurolib.run() for (var_multi, var_neurolib) in NEUROLIB_VARIABLES_TO_TEST: corr_mat = np.corrcoef(wc_neurolib[var_neurolib], multi_result[var_multi].values.T) self.assertTrue(np.greater(corr_mat, CORR_THRESHOLD).all())
def test_network(self): logging.info("\t > WC: Testing brain network (chunkwise integration and BOLD simulation) ...") start = time.time() ds = Dataset("gw") wc = WCModel(Cmat=ds.Cmat, Dmat=ds.Dmat) wc.params["signalV"] = 4.0 wc.params["duration"] = 10 * 1000 wc.params["sigma_ou"] = 0.1 wc.params["K_gl"] = 0.6 wc.params["x_ext_mean"] = 0.72 wc.run(chunkwise=True, bold=True, append_outputs=True) end = time.time() logging.info("\t > Done in {:.2f} s".format(end - start))
def test_single_node(self): logging.info("\t > WC: Testing single node ...") start = time.time() wc = WCModel() wc.params["duration"] = 2.0 * 1000 wc.params["sigma_ou"] = 0.03 wc.run() end = time.time() logging.info("\t > Done in {:.2f} s".format(end - start))
def test_compare_w_neurolib_native_model(self): """ Compare with neurolib's native Wilson-Cowan model. """ wc_multi = WilsonCowanNetwork(self.SC, self.DELAYS) multi_result = wc_multi.run(DURATION, DT, ZeroInput(DURATION, DT).as_array(), backend="numba") # run neurolib's model wc_neurolib = WCModel(Cmat=self.SC, Dmat=self.DELAYS, seed=SEED) wc_neurolib.params["duration"] = DURATION wc_neurolib.params["dt"] = DT # there is no "global coupling" parameter in MultiModel wc_neurolib.params["K_gl"] = 1.0 # delays <-> length matrix wc_neurolib.params["signalV"] = 1.0 wc_neurolib.params["sigma_ou"] = 0.0 # match initial state wc_neurolib.params["exc_init"] = wc_multi.initial_state[::2][:, np. newaxis] wc_neurolib.params["inh_init"] = wc_multi.initial_state[1::2][:, np. newaxis] wc_neurolib.run() for (var_multi, var_neurolib) in NEUROLIB_VARIABLES_TO_TEST: for node_idx in range(len(wc_multi)): corr_mat = np.corrcoef( wc_neurolib[var_neurolib][node_idx, :], multi_result[var_multi].values.T[node_idx, :]) self.assertTrue(np.greater(corr_mat, CORR_THRESHOLD).all())
class evWC(): """ Class to handle the model simulations and """ def __init__(self, params, Settings): from utils.SignalAnalysis import Signal, Envelope # List of Parameters that will be modified during evolution self.evolKeys = Settings['evolKeys'] # Initialize Wilson-Cowan Model self.simFreq = 500 # simulation frequency in seconds self.WC = WCModel( Cmat=Settings['Cmat'], Dmat=Settings['Dmat']) # Initialize Wilson Cowan model self.NumberStrRegions = self.WC.params['N'] self.WC.params[ 'duration'] = Settings['Duration'] * 1000 # Duration in ms self.WC.params['dt'] = 1000 * (1 / self.simFreq) # timestep in ms # Runt WC simulations with parameter self._runWC(params) # Calculate Low-pass Envelope of Carrier Frequency self.Limits = Settings['CarrierFreq'] ExcSignal = Signal(self.WC.outputs.exc, self.simFreq) self.ExcEnv = ExcSignal.getLowPassEnvelope(Limits=self.Limits) # Downsample Envelope self.downNum = 300 # has to be the same as for MEG CCD self.dExcEnv = Envelope(self.ExcEnv).downsampleSignal(self.downNum) # Get Fit empCCD = Settings['empCCD'] self.Fit = self.getFit(empCCD) def _runWC(self, params): """ :param params: list of parameters that are passed into the WC-model :return: Envelopes of the excitatory and inhibitory spiking series """ print("Calculating Wilson-Cowan simulation.") for idx, key in enumerate(self.evolKeys): self.WC.params[key] = params[idx] self.WC.params['exc_init'] = 0.05 * np.random.uniform( 0, 1, (self.NumberStrRegions, 1)) # setting random initial values self.WC.params['inh_init'] = 0.05 * np.random.uniform( 0, 1, (self.NumberStrRegions, 1)) self.WC.run(chunkwise=True, append=True) def getFit(self, empData, Type='CCD'): """Calculate the fit between empirical and WC-model with params as parameter. The fit is defined as the KS Distance between the Coherence Connectivity Dynamics of empirical and simulated data. :param params: list of parameter that are passed into the WC-model :return: Fit """ from utils.SignalAnalysis import Envelope if Type == 'CCD': self.simCCD = Envelope(self.dExcEnv).getCCD() self.empCCD = empData fit = self._getKSD(self.empCCD, self.simCCD) if Type == 'FC': self.simFC = Envelope(self.ExcEnv).getFC() self.empFC = empData fit = self._getKSD(self.empFC, self.simFC) pass print("Fit: ", fit) return fit def _getKSD(self, empMat, simMat): """ Returns the Kolmogorov-Smirnov distance which ranges from 0-1 :param simCCD: numpy ndarray containing the simulated CCD :return: KS distance between simulated and empirical data """ from scipy.stats import ks_2samp if empMat.shape != simMat.shape: raise ValueError("Input matrices must have the same shape.") rows = empMat.shape[-1] idx = np.triu_indices(rows, k=1) empValues = empMat[idx] simValues = simMat[idx] # Bin values bins = np.arange(0, 1, 0.01) simIdx = np.digitize(simValues, bins) empIdx = np.digitize(empValues, bins) binnedSim = bins[simIdx - 1] binnedEmp = bins[empIdx - 1] KSD = ks_2samp( binnedEmp, binnedSim)[0] # Omits the p-value and outputs the KSD distance return KSD