swcgeom 0.15.0__tar.gz → 0.17.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of swcgeom might be problematic. Click here for more details.
- swcgeom-0.17.0/.github/workflows/build.yml +38 -0
- swcgeom-0.17.0/.github/workflows/github-publish.yml +35 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/.github/workflows/pypi-publish.yml +12 -12
- {swcgeom-0.15.0 → swcgeom-0.17.0}/.github/workflows/test.yml +1 -1
- swcgeom-0.17.0/.vscode/settings.json +15 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/CHANGELOG.md +69 -0
- {swcgeom-0.15.0/swcgeom.egg-info → swcgeom-0.17.0}/PKG-INFO +3 -3
- {swcgeom-0.15.0 → swcgeom-0.17.0}/examples/pytorch/branch_dataset.py +1 -1
- {swcgeom-0.15.0 → swcgeom-0.17.0}/pyproject.toml +2 -2
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/_version.py +2 -2
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/analysis/__init__.py +1 -3
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/analysis/feature_extractor.py +3 -3
- swcgeom-0.15.0/swcgeom/analysis/node_features.py → swcgeom-0.17.0/swcgeom/analysis/features.py +105 -3
- swcgeom-0.17.0/swcgeom/analysis/lmeasure.py +821 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/analysis/sholl.py +31 -2
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/core/__init__.py +4 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/core/branch.py +9 -4
- swcgeom-0.15.0/swcgeom/core/segment.py → swcgeom-0.17.0/swcgeom/core/compartment.py +14 -9
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/core/node.py +0 -8
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/core/path.py +21 -6
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/core/population.py +47 -7
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/core/swc_utils/assembler.py +12 -1
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/core/swc_utils/base.py +12 -5
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/core/swc_utils/checker.py +12 -2
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/core/tree.py +34 -37
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/core/tree_utils.py +4 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/images/augmentation.py +6 -1
- swcgeom-0.17.0/swcgeom/images/contrast.py +107 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/images/folder.py +71 -14
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/images/io.py +74 -88
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/transforms/__init__.py +2 -0
- swcgeom-0.17.0/swcgeom/transforms/image_preprocess.py +100 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/transforms/image_stack.py +1 -4
- swcgeom-0.17.0/swcgeom/transforms/images.py +203 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/transforms/mst.py +5 -5
- swcgeom-0.17.0/swcgeom/transforms/neurolucida_asc.py +495 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/transforms/tree.py +5 -1
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/utils/__init__.py +1 -0
- swcgeom-0.17.0/swcgeom/utils/neuromorpho.py +594 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/utils/numpy_helper.py +14 -4
- swcgeom-0.17.0/swcgeom/utils/plotter_2d.py +130 -0
- swcgeom-0.17.0/swcgeom/utils/renderer.py +133 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/utils/sdf.py +5 -1
- {swcgeom-0.15.0 → swcgeom-0.17.0/swcgeom.egg-info}/PKG-INFO +3 -3
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom.egg-info/SOURCES.txt +9 -4
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom.egg-info/requires.txt +2 -2
- swcgeom-0.17.0/tests/transforms/test_neurolucida_asc.py +150 -0
- swcgeom-0.17.0/tests/utils/test_numpy_helper.py +46 -0
- swcgeom-0.15.0/.github/workflows/build.yml +0 -38
- swcgeom-0.15.0/.github/workflows/github-publish.yml +0 -35
- swcgeom-0.15.0/.vscode/settings.json +0 -20
- swcgeom-0.15.0/swcgeom/analysis/branch_features.py +0 -67
- swcgeom-0.15.0/swcgeom/analysis/path_features.py +0 -37
- swcgeom-0.15.0/swcgeom/transforms/images.py +0 -32
- swcgeom-0.15.0/swcgeom/utils/neuromorpho.py +0 -469
- swcgeom-0.15.0/swcgeom/utils/renderer.py +0 -244
- {swcgeom-0.15.0 → swcgeom-0.17.0}/.gitignore +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/.pylintrc +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/LICENSE +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/README.md +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/examples/Branch.ipynb +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/examples/BranchTree.ipynb +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/examples/CollectTips.ipynb +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/examples/CutTree.ipynb +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/examples/Features.ipynb +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/examples/GeometryTransform.ipynb +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/examples/ImageStack.ipynb +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/examples/MST.ipynb +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/examples/SpectralClustering.ipynb +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/examples/Tree.ipynb +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/examples/data/101711-10_4p5-of-16_initial.CNG.swc +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/examples/data/101711-11_16-of-16_initial.CNG.swc +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/examples/data/1059283677_15257_2226-X16029-Y23953.swc +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/examples/data/toydata.swc +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/examples/dgl/graph.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/examples/pytorch/branch.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/examples/pytorch/tree_folder_dataset.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/git-conventional-commits.yaml +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/setup.cfg +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/__init__.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/analysis/trunk.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/analysis/visualization.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/analysis/volume.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/core/branch_tree.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/core/swc.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/core/swc_utils/__init__.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/core/swc_utils/io.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/core/swc_utils/normalizer.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/core/swc_utils/subtree.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/core/tree_utils_impl.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/images/__init__.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/transforms/base.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/transforms/branch.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/transforms/geometry.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/transforms/path.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/transforms/population.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/transforms/tree_assembler.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/utils/debug.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/utils/download.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/utils/dsu.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/utils/ellipse.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/utils/file.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/utils/solid_geometry.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/utils/transforms.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom/utils/volumetric_object.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom.egg-info/dependency_links.txt +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/swcgeom.egg-info/top_level.txt +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/tests/__init__.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/tests/analysis/test_volume.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/tests/utils/__init__.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/tests/utils/test_dsu.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/tests/utils/test_sdf.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/tests/utils/test_solid_geometry.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/tests/utils/test_transforms.py +0 -0
- {swcgeom-0.15.0 → swcgeom-0.17.0}/tests/utils/test_volumetric_object.py +0 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: Build Python Package
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_call:
|
|
5
|
+
|
|
6
|
+
jobs:
|
|
7
|
+
build:
|
|
8
|
+
runs-on: ubuntu-latest
|
|
9
|
+
steps:
|
|
10
|
+
- uses: actions/checkout@v3
|
|
11
|
+
|
|
12
|
+
- name: Set up Python
|
|
13
|
+
uses: actions/setup-python@v3
|
|
14
|
+
with:
|
|
15
|
+
python-version: "3.10"
|
|
16
|
+
|
|
17
|
+
- name: Get history and tags for SCM versioning to work
|
|
18
|
+
run: |
|
|
19
|
+
git fetch --prune --unshallow
|
|
20
|
+
git fetch --depth=1 origin +refs/tags/*:refs/tags/*
|
|
21
|
+
git describe --tags
|
|
22
|
+
git describe --tags $(git rev-list --tags --max-count=1)
|
|
23
|
+
|
|
24
|
+
- name: Install dependencies
|
|
25
|
+
run: |
|
|
26
|
+
python -m pip install --upgrade pip
|
|
27
|
+
pip install build
|
|
28
|
+
|
|
29
|
+
- name: Build package
|
|
30
|
+
run: python -m build
|
|
31
|
+
|
|
32
|
+
- name: Archive production artifacts
|
|
33
|
+
uses: actions/upload-artifact@v3
|
|
34
|
+
with:
|
|
35
|
+
name: release
|
|
36
|
+
path: |
|
|
37
|
+
dist/
|
|
38
|
+
swcgeom.egg-info/
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
name: Release to GitHub
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- v*
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build:
|
|
13
|
+
uses: ./.github/workflows/build.yml
|
|
14
|
+
|
|
15
|
+
publish:
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
needs: build
|
|
18
|
+
steps:
|
|
19
|
+
- name: Get version
|
|
20
|
+
id: get_version
|
|
21
|
+
run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//}
|
|
22
|
+
|
|
23
|
+
- name: Download release
|
|
24
|
+
uses: actions/download-artifact@v3
|
|
25
|
+
with:
|
|
26
|
+
name: release
|
|
27
|
+
|
|
28
|
+
- name: Pack release
|
|
29
|
+
run: tar czf swcgeom-${{ steps.get_version.outputs.VERSION }}.tgz dist/
|
|
30
|
+
|
|
31
|
+
- name: Create release
|
|
32
|
+
uses: softprops/action-gh-release@v1
|
|
33
|
+
with:
|
|
34
|
+
token: ${{ secrets.GH_TOKEN }}
|
|
35
|
+
files: swcgeom-${{ steps.get_version.outputs.VERSION }}.tgz
|
|
@@ -6,26 +6,26 @@ name: Release to PyPI
|
|
|
6
6
|
on:
|
|
7
7
|
push:
|
|
8
8
|
tags:
|
|
9
|
-
|
|
9
|
+
- v*
|
|
10
10
|
|
|
11
11
|
permissions:
|
|
12
12
|
contents: read
|
|
13
13
|
|
|
14
14
|
jobs:
|
|
15
|
-
build:
|
|
15
|
+
build:
|
|
16
16
|
uses: ./.github/workflows/build.yml
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
publish:
|
|
19
19
|
runs-on: ubuntu-latest
|
|
20
20
|
needs: build
|
|
21
21
|
steps:
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
- name: Download release
|
|
23
|
+
uses: actions/download-artifact@v3
|
|
24
|
+
with:
|
|
25
|
+
name: release
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
- name: Publish package
|
|
28
|
+
uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29
|
|
29
|
+
with:
|
|
30
|
+
user: __token__
|
|
31
|
+
password: ${{ secrets.PYPI_API_TOKEN }}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"[python]": {
|
|
3
|
+
"editor.defaultFormatter": "ms-python.black-formatter"
|
|
4
|
+
},
|
|
5
|
+
"python.analysis.typeCheckingMode": "basic",
|
|
6
|
+
"python.testing.pytestArgs": [
|
|
7
|
+
"tests"
|
|
8
|
+
],
|
|
9
|
+
"python.testing.unittestEnabled": false,
|
|
10
|
+
"python.testing.pytestEnabled": true,
|
|
11
|
+
"isort.args": [
|
|
12
|
+
"--profile",
|
|
13
|
+
"black"
|
|
14
|
+
],
|
|
15
|
+
}
|
|
@@ -1,5 +1,74 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## **0.17.0** <sub><sup>2024-04-04 ([59257cb...2072139](https://github.com/yzx9/swcgeom/compare/59257cbfb6264afd3ca31fcba002f692bbb69ed0...20721393086e5a890b097b3ae32aaa1e4ad6b898?diff=split))</sup></sub>
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
#####  `images`
|
|
8
|
+
|
|
9
|
+
- handle raw file in terafly ([67ecd63](https://github.com/yzx9/swcgeom/commit/67ecd63bf4124d49b00e779c2702a7b939ef710b))
|
|
10
|
+
- add image stack dtype support ([7313ead](https://github.com/yzx9/swcgeom/commit/7313ead09ec61970f221b9e0c3691d31c269b591))
|
|
11
|
+
|
|
12
|
+
#####  `transforms`
|
|
13
|
+
|
|
14
|
+
- add new image transformation classes ([7b5d805](https://github.com/yzx9/swcgeom/commit/7b5d805a1aa0deac3f9d7576a9aecab36b59774b))
|
|
15
|
+
- add image flip and notes ([5f2a4d1](https://github.com/yzx9/swcgeom/commit/5f2a4d1a9c2b5fb68e8221c7b024a411b247ab6d))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### BREAKING CHANGES
|
|
19
|
+
- `images` remove deprecated \`swap\_xy\` and \`filp\_xy\` flag ([2072139](https://github.com/yzx9/swcgeom/commit/20721393086e5a890b097b3ae32aaa1e4ad6b898))
|
|
20
|
+
<br>
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
## **0.16.0** <sub><sup>2024-03-16 ([bf2bf95...7029483](https://github.com/yzx9/swcgeom/compare/bf2bf95ee9fbfb7eba871db7303292f1dfcc7b8f...70294836643e51ca43d039887bbd71de3a9b561b?diff=split))</sup></sub>
|
|
24
|
+
|
|
25
|
+
### Features
|
|
26
|
+
|
|
27
|
+
#####  `analysis`
|
|
28
|
+
|
|
29
|
+
- add l\-measure support \(close \#13\) ([15ddc33](https://github.com/yzx9/swcgeom/commit/15ddc333c4cdce42fe99fb2383fa0768bc2e35b2))
|
|
30
|
+
|
|
31
|
+
#####  `core`
|
|
32
|
+
|
|
33
|
+
- \`Tree\` accpet values with custom names ([722f84f](https://github.com/yzx9/swcgeom/commit/722f84fdd71133d07e74b5f90171b3671a4fe4c9))
|
|
34
|
+
- add \`Population\.map\` parallel processing support ([a1ee5bb](https://github.com/yzx9/swcgeom/commit/a1ee5bb6344ad5ab7b6572962f3b84caedf1351f))
|
|
35
|
+
|
|
36
|
+
#####  `images`
|
|
37
|
+
|
|
38
|
+
- add image contrast functions ([85b881e](https://github.com/yzx9/swcgeom/commit/85b881e91e878daf6fb3aa2862b5cd62eaa3488b))
|
|
39
|
+
- stat image stack folder ([ffc5e3a](https://github.com/yzx9/swcgeom/commit/ffc5e3a649a4d8203c2530b6351a7b509b262cf3))
|
|
40
|
+
|
|
41
|
+
#####  `transforms`
|
|
42
|
+
|
|
43
|
+
- add basic neuronlucida asc format support \(close \#12\) ([619a275](https://github.com/yzx9/swcgeom/commit/619a275aaa5a311c66e1a2438e6251ee4b9bd703))
|
|
44
|
+
- add \`SGuoImPreProcess\` ([dab7481](https://github.com/yzx9/swcgeom/commit/dab74818e5ea82d27450758f868bdc633b8992bf))
|
|
45
|
+
- add image stack related transforms ([7029483](https://github.com/yzx9/swcgeom/commit/70294836643e51ca43d039887bbd71de3a9b561b))
|
|
46
|
+
|
|
47
|
+
#####  `utils`
|
|
48
|
+
|
|
49
|
+
- \`Tree\` support array like inputs ([1f228d0](https://github.com/yzx9/swcgeom/commit/1f228d055b99c8545ba51da5af2bca8d7b760f3f))
|
|
50
|
+
- download source swc and log from neuromorpho ([d4fbfb6](https://github.com/yzx9/swcgeom/commit/d4fbfb6f0b89990bf63b481333d6c3c3cb16705c))
|
|
51
|
+
|
|
52
|
+
### Bug Fixes
|
|
53
|
+
|
|
54
|
+
#####  `utils`
|
|
55
|
+
|
|
56
|
+
- expecting a figure from the axes ([bf2bf95](https://github.com/yzx9/swcgeom/commit/bf2bf95ee9fbfb7eba871db7303292f1dfcc7b8f))
|
|
57
|
+
|
|
58
|
+
### Performance Improvements
|
|
59
|
+
|
|
60
|
+
#####  `core`
|
|
61
|
+
|
|
62
|
+
- use NamedTuple for SWCNames and SWCTypes ([300bfea](https://github.com/yzx9/swcgeom/commit/300bfeac92b90e09f262a850ecc226257c2af2e5))
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
### BREAKING CHANGES
|
|
66
|
+
|
|
67
|
+
- `core` \`Tree\` accpet values with custom names ([722f84f](https://github.com/yzx9/swcgeom/commit/722f84fdd71133d07e74b5f90171b3671a4fe4c9))
|
|
68
|
+
- `core` remove deprecated \`Tree\.Node\.get\_branch\` and \`Node\.child\_ids\` method ([1de86af](https://github.com/yzx9/swcgeom/commit/1de86afc21451be4c6bde5084688170d901eb625))
|
|
69
|
+
|
|
70
|
+
<br>
|
|
71
|
+
|
|
3
72
|
## **0.15.0** <sub><sup>2024-01-28 ([d300b41...8c9e0ab](https://github.com/yzx9/swcgeom/compare/d300b41689ee892fe5a23dad57f92e1054c0f9e9...8c9e0ab45c447d3d8121b0cc4178be5f65d18a56?diff=split))</sup></sub>
|
|
4
73
|
|
|
5
74
|
### Features
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: swcgeom
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.17.0
|
|
4
4
|
Summary: Neuron geometry library for swc format
|
|
5
5
|
Author-email: yzx9 <yuan.zx@outlook.com>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -19,14 +19,14 @@ Requires-Dist: sdflit>=0.2.1
|
|
|
19
19
|
Requires-Dist: seaborn>=0.12.0
|
|
20
20
|
Requires-Dist: tifffile>=2022.8.12
|
|
21
21
|
Requires-Dist: typing_extensions>=4.4.0
|
|
22
|
+
Requires-Dist: tqdm>=4.46.1
|
|
22
23
|
Requires-Dist: v3d-py-helper>=0.1.0
|
|
23
24
|
Provides-Extra: all
|
|
24
25
|
Requires-Dist: beautifulsoup4>=4.11.1; extra == "all"
|
|
25
26
|
Requires-Dist: certifi>=2023.5.7; extra == "all"
|
|
26
27
|
Requires-Dist: chardet>=5.2.0; extra == "all"
|
|
27
28
|
Requires-Dist: lmdb>=1.4.1; extra == "all"
|
|
28
|
-
Requires-Dist:
|
|
29
|
-
Requires-Dist: tqdm>=4.46.1; extra == "all"
|
|
29
|
+
Requires-Dist: requests>=2.0.0; extra == "all"
|
|
30
30
|
Requires-Dist: urllib3>=1.26.0; extra == "all"
|
|
31
31
|
|
|
32
32
|
# SWCGEOM
|
|
@@ -22,6 +22,7 @@ dependencies = [
|
|
|
22
22
|
"seaborn>=0.12.0",
|
|
23
23
|
"tifffile>=2022.8.12",
|
|
24
24
|
"typing_extensions>=4.4.0",
|
|
25
|
+
"tqdm>=4.46.1",
|
|
25
26
|
"v3d-py-helper>=0.1.0",
|
|
26
27
|
]
|
|
27
28
|
|
|
@@ -31,8 +32,7 @@ all = [
|
|
|
31
32
|
"certifi>=2023.5.7",
|
|
32
33
|
"chardet>=5.2.0",
|
|
33
34
|
"lmdb>=1.4.1",
|
|
34
|
-
"
|
|
35
|
-
"tqdm>=4.46.1",
|
|
35
|
+
"requests>=2.0.0",
|
|
36
36
|
"urllib3>=1.26.0",
|
|
37
37
|
]
|
|
38
38
|
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"""Analysis for neuron trees."""
|
|
2
2
|
|
|
3
|
-
from swcgeom.analysis.branch_features import *
|
|
4
3
|
from swcgeom.analysis.feature_extractor import *
|
|
5
|
-
from swcgeom.analysis.
|
|
6
|
-
from swcgeom.analysis.path_features import *
|
|
4
|
+
from swcgeom.analysis.features import *
|
|
7
5
|
from swcgeom.analysis.sholl import *
|
|
8
6
|
from swcgeom.analysis.trunk import *
|
|
9
7
|
from swcgeom.analysis.visualization import *
|
|
@@ -17,13 +17,13 @@ import numpy.typing as npt
|
|
|
17
17
|
import seaborn as sns
|
|
18
18
|
from matplotlib.axes import Axes
|
|
19
19
|
|
|
20
|
-
from swcgeom.analysis.
|
|
21
|
-
from swcgeom.analysis.node_features import (
|
|
20
|
+
from swcgeom.analysis.features import (
|
|
22
21
|
BifurcationFeatures,
|
|
22
|
+
BranchFeatures,
|
|
23
23
|
NodeFeatures,
|
|
24
|
+
PathFeatures,
|
|
24
25
|
TipFeatures,
|
|
25
26
|
)
|
|
26
|
-
from swcgeom.analysis.path_features import PathFeatures
|
|
27
27
|
from swcgeom.analysis.sholl import Sholl
|
|
28
28
|
from swcgeom.analysis.volume import get_volume
|
|
29
29
|
from swcgeom.core import Population, Populations, Tree
|
swcgeom-0.15.0/swcgeom/analysis/node_features.py → swcgeom-0.17.0/swcgeom/analysis/features.py
RENAMED
|
@@ -1,15 +1,26 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""Feature anlysis of tree."""
|
|
2
2
|
|
|
3
3
|
from abc import ABC, abstractmethod
|
|
4
4
|
from functools import cached_property
|
|
5
|
+
from typing import List, TypeVar
|
|
5
6
|
|
|
6
7
|
import numpy as np
|
|
7
8
|
import numpy.typing as npt
|
|
8
9
|
from typing_extensions import Self
|
|
9
10
|
|
|
10
|
-
from swcgeom.core import BranchTree, Tree
|
|
11
|
+
from swcgeom.core import Branch, BranchTree, Tree
|
|
11
12
|
|
|
12
|
-
__all__ = [
|
|
13
|
+
__all__ = [
|
|
14
|
+
"NodeFeatures",
|
|
15
|
+
"BifurcationFeatures",
|
|
16
|
+
"TipFeatures",
|
|
17
|
+
"PathFeatures",
|
|
18
|
+
"BranchFeatures",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
T = TypeVar("T", bound=Branch)
|
|
22
|
+
|
|
23
|
+
# Node Level
|
|
13
24
|
|
|
14
25
|
|
|
15
26
|
class NodeFeatures:
|
|
@@ -31,6 +42,7 @@ class NodeFeatures:
|
|
|
31
42
|
-------
|
|
32
43
|
count : array of shape (1,)
|
|
33
44
|
"""
|
|
45
|
+
|
|
34
46
|
return np.array([self.tree.number_of_nodes()], dtype=np.float32)
|
|
35
47
|
|
|
36
48
|
def get_radial_distance(self) -> npt.NDArray[np.float32]:
|
|
@@ -41,6 +53,7 @@ class NodeFeatures:
|
|
|
41
53
|
radial_distance : npt.NDArray[np.float32]
|
|
42
54
|
Array of shape (N,).
|
|
43
55
|
"""
|
|
56
|
+
|
|
44
57
|
xyz = self.tree.xyz() - self.tree.soma().xyz()
|
|
45
58
|
radial_distance = np.linalg.norm(xyz, axis=1)
|
|
46
59
|
return radial_distance
|
|
@@ -58,6 +71,7 @@ class NodeFeatures:
|
|
|
58
71
|
order : npt.NDArray[np.int32]
|
|
59
72
|
Array of shape (N,), which k is the number of branchs.
|
|
60
73
|
"""
|
|
74
|
+
|
|
61
75
|
order = np.zeros_like(self._branch_tree.id(), dtype=np.int32)
|
|
62
76
|
|
|
63
77
|
def assign_depth(n: Tree.Node, pre_depth: int | None) -> int:
|
|
@@ -88,6 +102,7 @@ class _SubsetNodesFeatures(ABC):
|
|
|
88
102
|
count : npt.NDArray[np.float32]
|
|
89
103
|
Array of shape (1,).
|
|
90
104
|
"""
|
|
105
|
+
|
|
91
106
|
return np.array([np.count_nonzero(self.nodes)], dtype=np.float32)
|
|
92
107
|
|
|
93
108
|
def get_radial_distance(self) -> npt.NDArray[np.float32]:
|
|
@@ -98,6 +113,7 @@ class _SubsetNodesFeatures(ABC):
|
|
|
98
113
|
radial_distance : npt.NDArray[np.float32]
|
|
99
114
|
Array of shape (N,).
|
|
100
115
|
"""
|
|
116
|
+
|
|
101
117
|
return self._features.get_radial_distance()[self.nodes]
|
|
102
118
|
|
|
103
119
|
@classmethod
|
|
@@ -119,3 +135,89 @@ class TipFeatures(_SubsetNodesFeatures):
|
|
|
119
135
|
@cached_property
|
|
120
136
|
def nodes(self) -> npt.NDArray[np.bool_]:
|
|
121
137
|
return np.array([n.is_tip() for n in self._features.tree])
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
# Path Level
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
class PathFeatures:
|
|
144
|
+
"""Path analysis of tree."""
|
|
145
|
+
|
|
146
|
+
tree: Tree
|
|
147
|
+
|
|
148
|
+
def __init__(self, tree: Tree) -> None:
|
|
149
|
+
self.tree = tree
|
|
150
|
+
|
|
151
|
+
def get_count(self) -> int:
|
|
152
|
+
return len(self._paths)
|
|
153
|
+
|
|
154
|
+
def get_length(self) -> npt.NDArray[np.float32]:
|
|
155
|
+
"""Get length of paths."""
|
|
156
|
+
|
|
157
|
+
length = [path.length() for path in self._paths]
|
|
158
|
+
return np.array(length, dtype=np.float32)
|
|
159
|
+
|
|
160
|
+
def get_tortuosity(self) -> npt.NDArray[np.float32]:
|
|
161
|
+
"""Get tortuosity of path."""
|
|
162
|
+
|
|
163
|
+
return np.array([path.tortuosity() for path in self._paths], dtype=np.float32)
|
|
164
|
+
|
|
165
|
+
@cached_property
|
|
166
|
+
def _paths(self) -> List[Tree.Path]:
|
|
167
|
+
return self.tree.get_paths()
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
class BranchFeatures:
|
|
171
|
+
"""Analysis bransh of tree."""
|
|
172
|
+
|
|
173
|
+
tree: Tree
|
|
174
|
+
|
|
175
|
+
def __init__(self, tree: Tree) -> None:
|
|
176
|
+
self.tree = tree
|
|
177
|
+
|
|
178
|
+
def get_count(self) -> int:
|
|
179
|
+
return len(self._branches)
|
|
180
|
+
|
|
181
|
+
def get_length(self) -> npt.NDArray[np.float32]:
|
|
182
|
+
"""Get length of branches."""
|
|
183
|
+
|
|
184
|
+
length = [br.length() for br in self._branches]
|
|
185
|
+
return np.array(length, dtype=np.float32)
|
|
186
|
+
|
|
187
|
+
def get_tortuosity(self) -> npt.NDArray[np.float32]:
|
|
188
|
+
"""Get tortuosity of path."""
|
|
189
|
+
|
|
190
|
+
return np.array([br.tortuosity() for br in self._branches], dtype=np.float32)
|
|
191
|
+
|
|
192
|
+
def get_angle(self, eps: float = 1e-7) -> npt.NDArray[np.float32]:
|
|
193
|
+
"""Get agnle between branches.
|
|
194
|
+
|
|
195
|
+
Returns
|
|
196
|
+
-------
|
|
197
|
+
angle : npt.NDArray[np.float32]
|
|
198
|
+
An array of shape (N, N), which N is length of branches.
|
|
199
|
+
"""
|
|
200
|
+
|
|
201
|
+
return self.calc_angle(self._branches, eps=eps)
|
|
202
|
+
|
|
203
|
+
@staticmethod
|
|
204
|
+
def calc_angle(branches: List[T], eps: float = 1e-7) -> npt.NDArray[np.float32]:
|
|
205
|
+
"""Calc agnle between branches.
|
|
206
|
+
|
|
207
|
+
Returns
|
|
208
|
+
-------
|
|
209
|
+
angle : npt.NDArray[np.float32]
|
|
210
|
+
An array of shape (N, N), which N is length of branches.
|
|
211
|
+
"""
|
|
212
|
+
|
|
213
|
+
vector = np.array([br[-1].xyz() - br[0].xyz() for br in branches])
|
|
214
|
+
vector_dot = np.matmul(vector, vector.T)
|
|
215
|
+
vector_norm = np.linalg.norm(vector, ord=2, axis=1, keepdims=True)
|
|
216
|
+
vector_norm_dot = np.matmul(vector_norm, vector_norm.T) + eps
|
|
217
|
+
arccos = np.clip(vector_dot / vector_norm_dot, -1, 1)
|
|
218
|
+
angle = np.arccos(arccos)
|
|
219
|
+
return angle
|
|
220
|
+
|
|
221
|
+
@cached_property
|
|
222
|
+
def _branches(self) -> List[Tree.Branch]:
|
|
223
|
+
return self.tree.get_branches()
|