def test_multidimensional_features(): """Features should be split into sub-features when they are multidimensional. This should be the case even when the feature is `None` or `[]` The following neuron has no axon but the axon feature segment_midpoints for the axon should still be made of 3 values (X, Y and Z) Cf: https://github.com/BlueBrain/NeuroM/issues/859 """ neuron = nm.load_neuron(Path(SWC_PATH, 'no-axon.swc')) config = { 'neurite': { 'segment_midpoints': ['max'] }, 'neurite_type': ['AXON'] } actual = ms.extract_dataframe(neuron, config) assert_array_equal( actual['axon'][[ 'max_segment_midpoint_0', 'max_segment_midpoint_1', 'max_segment_midpoint_2' ]].values, [[None, None, None]]) config = {'neurite': {'partition_pairs': ['max']}} actual = ms.extract_dataframe(neuron, config) assert_array_equal( actual['axon'][['max_partition_pair_0', 'max_partition_pair_1']].values, [[None, None]])
def test_extract_dataframe_multiproc(): nrns = nm.load_neurons([Path(SWC_PATH, name) for name in ['Neuron.swc', 'simple.swc']]) with warnings.catch_warnings(record=True) as w: actual = ms.extract_dataframe(nrns, REF_CONFIG, n_workers=2) expected = pd.read_csv(Path(DATA_PATH, 'extracted-stats.csv'), index_col=0, header=[0, 1]) assert_frame_equal(actual, expected) with warnings.catch_warnings(record=True) as w: actual = ms.extract_dataframe(nrns, REF_CONFIG, n_workers=os.cpu_count() + 1) assert_equal(len(w), 1, "Warning not emitted") assert_frame_equal(actual, expected)
def features(self, config: Dict, n_workers=1): '''Returns a dataframe containing morphometrics and neurondb information Args: config: a NeuroM morph_stas config. See https://neurom.readthedocs.io/en/latest/morph_stats.html for more information n_workers: the number of workers to use to perform the computations Returns: A jointure dataframe between `neurom.stats.extract_dataframe` and `self.df` Raises: ValueError: if `self.df` has undefined (ie. None) paths ''' missing_morphs = self.df[self.df.path.isnull()].name.to_list() if missing_morphs: raise ValueError( f'DataFrame has morphologies with undefined filepaths: {missing_morphs}' ) df = self.df.copy().reset_index(drop=True) df.columns = pd.MultiIndex.from_product( (["properties"], df.columns.values)) stats = extract_dataframe(df['properties', 'path'], config, n_workers) return df.join(stats.drop(columns='name', level=1), how='inner')
def test_extract_dataframe_multiproc(): nrns = nm.load_neurons([Path(SWC_PATH, name) for name in ['Neuron.swc', 'simple.swc']]) with warnings.catch_warnings(record=True) as w: actual = ms.extract_dataframe(nrns, REF_CONFIG, n_workers=2) expected = pd.read_csv(Path(DATA_PATH, 'extracted-stats.csv'), index_col=0) # Compare sorted DataFrame since Pool.imap_unordered disrupted the order assert_frame_equal(actual.sort_values(by=['name']).reset_index(drop=True), expected.sort_values(by=['name']).reset_index(drop=True)) with warnings.catch_warnings(record=True) as w: actual = ms.extract_dataframe(nrns, REF_CONFIG, n_workers=os.cpu_count() + 1) assert_equal(len(w), 1, "Warning not emitted") assert_frame_equal(actual.sort_values(by=['name']).reset_index(drop=True), expected.sort_values(by=['name']).reset_index(drop=True))
def test_extract_dataframe_multiproc(): # FIXME: Cannot use Neuron objects in the extract_dataframe ctor right now # because of "TypeError: can't pickle Neuron objects" # nrns = nm.load_neurons([Path(SWC_PATH, name) # for name in ['Neuron.swc', 'simple.swc']]) nrns = [Path(SWC_PATH, name) for name in ['Neuron.swc', 'simple.swc']] with warnings.catch_warnings(record=True) as w: actual = ms.extract_dataframe(nrns, REF_CONFIG, n_workers=2) expected = pd.read_csv(Path(DATA_PATH, 'extracted-stats.csv'), index_col=0, header=[0, 1]) assert_frame_equal(actual, expected) with warnings.catch_warnings(record=True) as w: actual = ms.extract_dataframe(nrns, REF_CONFIG, n_workers=os.cpu_count() + 1) assert len(w) == 1, "Warning not emitted" assert_frame_equal(actual, expected)
def test_extract_dataframe(): # Vanilla test nrns = nm.load_neurons([Path(SWC_PATH, name) for name in ['Neuron.swc', 'simple.swc']]) actual = ms.extract_dataframe(nrns, REF_CONFIG) expected = pd.read_csv(Path(DATA_PATH, 'extracted-stats.csv'), header=[0, 1], index_col=0) assert_frame_equal(actual, expected) # Test with a single neuron in the population nrns = nm.load_neurons(Path(SWC_PATH, 'Neuron.swc')) actual = ms.extract_dataframe(nrns, REF_CONFIG) assert_frame_equal(actual, expected.iloc[[0]], check_dtype=False) # Test with a config without the 'neuron' key nrns = nm.load_neurons([Path(SWC_PATH, name) for name in ['Neuron.swc', 'simple.swc']]) config = {'neurite': {'section_lengths': ['total']}, 'neurite_type': ['AXON', 'APICAL_DENDRITE', 'BASAL_DENDRITE', 'ALL']} actual = ms.extract_dataframe(nrns, config) idx = pd.IndexSlice expected = expected.loc[:, idx[:, ['name', 'total_section_length']]] assert_frame_equal(actual, expected) # Test with a FstNeuron argument nrn = nm.load_neuron(Path(SWC_PATH, 'Neuron.swc')) actual = ms.extract_dataframe(nrn, config) assert_frame_equal(actual, expected.iloc[[0]], check_dtype=False) # Test with a List[FstNeuron] argument nrns = [nm.load_neuron(Path(SWC_PATH, name)) for name in ['Neuron.swc', 'simple.swc']] actual = ms.extract_dataframe(nrns, config) assert_frame_equal(actual, expected) # Test with a List[Path] argument nrns = [Path(SWC_PATH, name) for name in ['Neuron.swc', 'simple.swc']] actual = ms.extract_dataframe(nrns, config) assert_frame_equal(actual, expected) # Test without any neurite_type keys, it should pick the defaults config = {'neurite': {'total_length_per_neurite': ['total']}} actual = ms.extract_dataframe(nrns, config) expected_columns = pd.MultiIndex.from_tuples( [('property', 'name'), ('axon', 'total_total_length_per_neurite'), ('basal_dendrite', 'total_total_length_per_neurite'), ('apical_dendrite', 'total_total_length_per_neurite'), ('all', 'total_total_length_per_neurite')]) expected = pd.DataFrame( columns=expected_columns, data=[['Neuron', 207.87975221, 418.43241644, 214.37304578, 840.68521442], ['simple', 15., 16., 0., 31., ]]) assert_frame_equal(actual, expected)
def test_extract_dataframe(): # Vanilla test nrns = nm.load_neurons([Path(SWC_PATH, name) for name in ['Neuron.swc', 'simple.swc']]) actual = ms.extract_dataframe(nrns, REF_CONFIG) expected = pd.read_csv(Path(DATA_PATH, 'extracted-stats.csv'), index_col=0) assert_frame_equal(actual, expected) # Test with a single neuron in the population nrns = nm.load_neurons(Path(SWC_PATH, 'Neuron.swc')) actual = ms.extract_dataframe(nrns, REF_CONFIG) assert_frame_equal(actual, expected[expected.name == 'Neuron'], check_dtype=False) # Test with a config without the 'neuron' key nrns = nm.load_neurons([Path(SWC_PATH, name) for name in ['Neuron.swc', 'simple.swc']]) config = {'neurite': {'section_lengths': ['total']}, 'neurite_type': ['AXON', 'APICAL_DENDRITE', 'BASAL_DENDRITE', 'ALL']} actual = ms.extract_dataframe(nrns, config) expected = expected[['name', 'neurite_type', 'total_section_length']] assert_frame_equal(actual, expected) # Test with a FstNeuron argument nrn = nm.load_neuron(Path(SWC_PATH, 'Neuron.swc')) actual = ms.extract_dataframe(nrn, config) assert_frame_equal(actual, expected[expected.name == 'Neuron'], check_dtype=False) # Test with a List[FstNeuron] argument nrns = [nm.load_neuron(Path(SWC_PATH, name)) for name in ['Neuron.swc', 'simple.swc']] actual = ms.extract_dataframe(nrns, config) assert_frame_equal(actual, expected) # Test with a List[Path] argument nrns = [Path(SWC_PATH, name) for name in ['Neuron.swc', 'simple.swc']] actual = ms.extract_dataframe(nrns, config) assert_frame_equal(actual, expected) # Test without any neurite_type keys, it should pick the defaults config = {'neurite': {'total_length_per_neurite': ['total']}} actual = ms.extract_dataframe(nrns, config) expected = pd.DataFrame( columns=['name', 'neurite_type', 'total_total_length_per_neurite'], data=[['Neuron', 'axon', 207.879752], ['Neuron', 'basal_dendrite', 418.432416], ['Neuron', 'apical_dendrite', 214.373046], ['Neuron', 'all', 840.685214], ['simple', 'axon', 15.000000], ['simple', 'basal_dendrite', 16.000000], ['simple', 'apical_dendrite', 0.000000], ['simple', 'all', 31.000000]]) assert_frame_equal(actual, expected)