def test_very_small(self): spine_density = 0.0001 out = get_spine_number(self.soma, spine_density, False) self.assertTrue(out in [0, 1])
def test_length_density(self): spine_density = 0.1 out = get_spine_number(self.soma, spine_density, False) self.assertEqual(out, 10)
def test_area_density(self): spine_density = 0.01 out = get_spine_number(self.soma, spine_density, True) expected = np.pi * spine_density * self.soma.hoc.L * self.soma.hoc.diam self.assertEqual(out, int(np.ceil(expected)))
def add_spines_by_density(self, secs: List[Sec], spine_density, spine_type="generic", **spine_params): """ Add spines with specified linear density (per 1 um) to specified secions (compartments). Spines can have a predifined type (stubby, thin, mushroom) or, alternatively, their dimentions (head_diam, head_len, neck_diam, neck_len) can be specified in spine_params. :param secs: Section that will have spines :param spine_density: spine density in spines/1um :param spine_type: Spine type. There are four predifined types: thin, stubby, mushroom and other. :param **spine_params: See below Keyword arguments: :spine_tag: String attached to name of every head and neck :head_diam: Spine head diameter :head_len: Length of the spine head :neck_diam: Spine neck diameter :neck_len: Length of the spine neck :area_densisty: if False spine_density is treated as linear spine density [um] if True spine_density is treated as area density [um2] :u_random: None seed for the random number generator used for picking out spine positions :spine_g_pas: pas conductance. By default g_pas of the parent section will be used. :spine_E_pas: pas reversal potential. By default pas reversal potential of the parent section will be used. :spine_rm: membrane resistivity. By default 1/pas conductance of the parent section will be used. :spine_ra: axial resistivity. By default axial resistivity of the parent section will be used. :area_densisty: if False spine_density is treated as linear spine density [um] if True spine_density is treated as area density [um2] :add_pas: add passive mechanism :return: TODO change this to list of objects list target location TODO: add spines with a distribution of head dimensions and neck dimensions """ try: spine_dimensions = SPINE_DIMENSIONS[spine_type] except KeyError: spine_dimensions = SPINE_DIMENSIONS["generic"] spine_tag = spine_params.pop("spine_tag", spine_type) head_diam = spine_params.pop("head_diam", spine_dimensions["head_diam"]) head_len = spine_params.pop("head_len", spine_dimensions["head_len"]) neck_diam = spine_params.pop("neck_diam", spine_dimensions["neck_diam"]) neck_len = spine_params.pop("neck_len", spine_dimensions["neck_len"]) # If Falde spine_E_pas = spine_params.pop("spine_E_pas", None) spine_g_pas = spine_params.pop("spine_g_pas", None) spine_rm = spine_params.pop("spine_rm", None) spine_ra = spine_params.pop("spine_ra", None) spine_cm = spine_params.pop("spine_cm", None) add_pas = spine_params.pop("add_pas", False) if isinstance(spine_rm, int) or isinstance(spine_rm, float): spine_g_pas = 1 / spine_rm area_density = spine_params.pop("area_density", False) seed = spine_params.pop("u_random", None) if seed is not None: np.random.seed(seed) all_target_locations = [] for sec in secs: spine_number = get_spine_number(sec=sec, density=spine_density, area_density=area_density) E_pas, g_pas, ra, cm = establish_electric_properties( sec, spine_E_pas, spine_g_pas, spine_ra, spine_cm) if not add_pas: E_pas = None g_pas = None if isinstance(seed, int): target_locations = np.random.uniform(0., 1., spine_number).tolist() else: target_locations = np.linspace(0., .99, spine_number).tolist() self._add_spines_to_section(sec, spine_tag, target_locations, head_diam, head_len, neck_diam, neck_len, E_pas, g_pas, ra, cm, add_pas=add_pas) all_target_locations.append(target_locations) return all_target_locations