def iCSD(lfp_data): #patch quantities with the SI unit Siemens if it does not exist for symbol, prefix, definition, u_symbol in zip( ['siemens', 'S', 'mS', 'uS', 'nS', 'pS'], ['', '', 'milli', 'micro', 'nano', 'pico'], [pq.A / pq.V, pq.A / pq.V, 'S', 'mS', 'uS', 'nS'], [None, None, None, None, u'uS', None]): if type(definition) is str: definition = lastdefinition / 1000 if not hasattr(pq, symbol): setattr( pq, symbol, pq.UnitQuantity(prefix + 'siemens', definition, symbol=symbol, u_symbol=u_symbol)) lastdefinition = definition #prepare lfp data for use, by changing the units to SI and append quantities, #along with electrode geometry, conductivities and assumed source geometry lfp_data = lfp_data * 1E-6 * pq.V # [uV] -> [V] #z_data = np.linspace(100E-6, 2300E-6, 23) * pq.m # [m] z_data = np.linspace(100E-6, 1000E-6, 32) * pq.m # [m] #diam = 500E-6 * pq.m # [m] diam = 250E-6 * pq.m # [m] bigger vals make smaller sources/sinks h = 100E-6 * pq.m # [m] (makes no difference with spline iCSD method) sigma = 0.3 * pq.S / pq.m # [S/m] or [1/(ohm*m)] (makes no difference with spline iCSD method) sigma_top = 0.3 * pq.S / pq.m # [S/m] or [1/(ohm*m)] # Input dictionaries for each method spline_input = { 'lfp': lfp_data, 'coord_electrode': z_data, 'diam': diam, 'sigma': sigma, 'sigma_top': sigma, 'num_steps': 201, # Spatial CSD upsampling to N steps 'tol': 1E-12, 'f_type': 'gaussian', 'f_order': (20, 5), } # how to call! csd_obj = icsd.SplineiCSD(**spline_input) csd = csd_obj.get_csd() csd = csd_obj.filter_csd(csd) return csd
def test_SplineiCSD_01(self): '''test using standard SI units, deep electrode coordinates''' #set some parameters for ground truth csd and csd estimates., e.g., #we will use same source diameter as in ground truth #contact point coordinates z_j = np.arange(10, 31) * 1E-4 * pq.m #source coordinates z_i = z_j #current source density magnitude C_i = np.zeros(z_i.size) * pq.A / pq.m**3 C_i[7:12:2] += np.array([-.5, 1., -.5]) * pq.A / pq.m**3 #source radius (delta, step) R_i = np.ones(z_i.size) * 1E-3 * pq.m #source height (cylinder) h_i = np.ones(z_i.size) * 1E-4 * pq.m #conductivity, use same conductivity for top layer (z_j < 0) sigma = 0.3 * pq.S / pq.m sigma_top = sigma #construct interpolators, spline method assume underlying source #pattern generating LFPs that are cubic spline interpolates between #contacts so we generate CSD data relying on the same assumption f_C = interp1d(z_i, C_i, kind='cubic') f_R = interp1d(z_i, R_i) num_steps = 201 z_i_i = np.linspace(float(z_i[0]), float(z_i[-1]), num_steps) * z_i.units C_i_i = f_C(np.asarray(z_i_i)) * C_i.units R_i_i = f_R(z_i_i) * R_i.units h_i_i = np.ones(z_i_i.size) * np.diff(z_i_i).min() #flag for debug plots plot = False #get LFP and CSD at contacts phi_j, C_i = get_lfp_of_cylinders(z_j, z_i_i, C_i_i, R_i_i, h_i_i, sigma, plot) spline_input = { 'lfp': phi_j, 'coord_electrode': z_j, 'diam': R_i * 2, 'sigma': sigma, 'sigma_top': sigma, 'num_steps': num_steps, 'tol': 1E-12, # Tolerance in numerical integration 'f_type': 'gaussian', 'f_order': (3, 1), } spline_icsd = icsd.SplineiCSD(**spline_input) csd = spline_icsd.get_csd() self.assertEqual(C_i.units, csd.units) nt.assert_array_almost_equal(C_i, csd, decimal=3)