Skip to content

Fit trunk radius and orientation #273

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 43 commits into from
Jul 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
9c6b302
Add centroid/epineurium to trunk/branch groups
rchristie Mar 2, 2025
0b4cac5
read multiple trunk groups
v-chopovda Mar 25, 2025
90ac1fb
Fit 1-D vagus trunk
rchristie Mar 31, 2025
100b19e
Fit radius
rchristie Apr 2, 2025
45c2ba7
new marker locations
v-chopovda Apr 2, 2025
bbd015d
Fix sample curve from points
rchristie Apr 3, 2025
7cd1f89
Fit twist angle, clean up fitter fields
rchristie Apr 8, 2025
5cbe51a
Fit vagus trunk orientation
rchristie Apr 11, 2025
00f1764
Add level markers
rchristie Apr 11, 2025
1eb9b8a
Add branches, reduce scale factors
rchristie May 21, 2025
6153213
Merge pull request #2 from v-chopovda/update_input_data_reader
rchristie May 30, 2025
eecc730
Add realistic vagus test with orienation and radius
rchristie May 30, 2025
3b01cad
Add material coordinates
rchristie Jun 4, 2025
b1d7043
Add code for material coordinates
rchristie Jun 5, 2025
b0b8353
Fix incorrect variable name
rchristie Jun 5, 2025
626d8f0
Update fieldfitter dependency version
rchristie Jun 5, 2025
b1a0df8
Offset vagus marker nodes to 10001
rchristie Jun 6, 2025
0896af9
Update cmlibs.utils dependency
rchristie Jun 8, 2025
600997f
Add vagus straight coordinates
rchristie Jun 9, 2025
a18bb01
Restore vagus coordinates to +z direction, +x left, +y anterior
rchristie Jun 9, 2025
e5c4f34
Set vagus annotation ID pref UBERON > ILX > FMA
rchristie Jun 13, 2025
93c3645
Test no FMA terms for vagus
rchristie Jun 13, 2025
b78a16c
Use urls for vagus annotation ids
rchristie Jun 16, 2025
b04d234
Add tests for reordered vagus trunk, currently failing
rchristie Jul 1, 2025
96df6ad
trunk nodes ordering
v-chopovda Jul 2, 2025
d1534d5
Merge pull request #3 from v-chopovda/test-richard-nerve-orientation
rchristie Jul 2, 2025
129cfa0
Fix branch start data and fit curvature
rchristie Jul 3, 2025
b3466d5
Improve test failure messages
rchristie Jul 3, 2025
ce8c72b
Reduce tolerance for branch of branch
rchristie Jul 3, 2025
f98badd
Further broaden tolerance
rchristie Jul 3, 2025
3062792
Further broaden tolerance
rchristie Jul 3, 2025
92b0696
Further broaden tolerance
rchristie Jul 3, 2025
a7b1a43
Further broaden tolerance
rchristie Jul 3, 2025
7942cd5
Further broaden tolerance
rchristie Jul 3, 2025
334ac6b
Further broaden tolerance
rchristie Jul 3, 2025
6ddc65f
updated vagus scaffold documentation
v-chopovda Jul 3, 2025
2e615d1
Ignore orientation points too far from centroid
rchristie Jul 4, 2025
1d5c37c
Merge branch 'nerve-orientation' of github.com:rchristie/scaffoldmake…
v-chopovda Jul 4, 2025
ef557db
update vagus terms
v-chopovda Jul 4, 2025
1d128b2
update vagus terms, documentation
v-chopovda Jul 4, 2025
629ea7b
Merge pull request #4 from v-chopovda/test-richard-nerve-orientation
rchristie Jul 7, 2025
61c51af
Fix annotation term typo
rchristie Jul 7, 2025
2c7521c
Improve vagus documentation with images
rchristie Jul 7, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added docs/_images/ssv_3_coordinate_fields.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_images/ssv_material_markers.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 1 addition & 2 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,4 @@ This documentation is intended to be a resource describing details about using i
scaffolds/lung
scaffolds/smallintestine
scaffolds/stomach


scaffolds/vagus
75 changes: 58 additions & 17 deletions docs/scaffolds/vagus.rst
Copy link
Contributor

@v-chopovda v-chopovda Jun 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doc needs updating (we can do this later)

  • add straight coordinates
  • update input file requirements (update approved landmarks, trunk group names)
  • add orientation points requirements

Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,71 @@ Vagus Scaffold
================

The current subject-specific vagus scaffold is ``3D Nerve 1`` built from ``class MeshType_3d_nerve1``.
The vagus scaffold needs an input file with segmentations to built from it.
Each subject-specific vagus scaffold is built from an input file containing segmentations of the trunk, branches,
level markers, radius and orientation points for that subject.

A mockup vagus scaffold with its 3 coordinates is shown in :numref:`fig-scaffoldmaker-vagus-3-coordinates`.

.. _fig-scaffoldmaker-vagus-3-coordinates:

.. figure:: ../_images/ssv_3_coordinate_fields.png
:align: center

Vagus nerve scaffold mockup with (from L-R): geometric coordinates, straight coordinates and material/vagus coordinates.

Translucent surfaces in the above figure show the round equivalent-area epineurium surface, but the bounds of the scaffold is a box of twice these dimensions to enclose the true cross-section shape and nearby tissue.
The boxes along the vagus trunk and branches are 3-D hexahedral finite elements with local coordinate systems spanning from 0.0 to 1.0 along three directions down the vagus, left and up.
These are entirely defined as functions of coordinate position and direction parameters along the centroid of the trunk and branches, and 2-D epineurium surfaces and 1-D centroid lines are defined from the same parameters.
The start of each branch is defined by general linear mapping of parent/trunk parameters making them fully embedded ('built-in') to their host at that point, preserving their relative directions when the scaffold is fitted to other configurations such as in-body trace data.

Input file requirements
-----------------------

The input file should have annotated segmentations for the vagus trunk and the vagal branches.
Vagus trunk should be annotated as either 'left vagus nerve' or 'right vagus nerve'.
All vagal branches should all have distinctive names, e.g. there should not be several branches with the same name.
The following annotations could be used for vagus trunk:

* left/right vagus nerve
* left/right cervical trunk
* left/right thoracic trunk
* left/right cervical vagus nerve
* left/right thoracic vagus nerve
* left/right vagus X nerve trunk

All vagal branches should be annotated with 'branch' or 'nerve' keyword. Each branch should have a distinct name,
including accepted variant names containing letters A, B, C, etc., so there should not be multiple branches with
the same name.

The input file should also have included some of the anatomical landmarks to be able to locate the vagus in the body
and to estimate vagus nerve real length. The current minimum is two included landmarks as marker datapoints.
The list of approved landmarks is as follows.
The list of approved landmarks is as follows (and visualized in :numref:`fig-scaffoldmaker-vagus-material-markers`):

* left/right level of superior border of jugular foramen on the vagus nerve
* left/right level of inferior border of jugular foramen on the vagus nerve
* left/right level of inferior border of jugular foramen on the vagus nerve
* left/right level of inferior border of cranium on the vagus nerve
* left/right level of C1 transverse process on the vagus nerve
* left/right level of angle of the mandible on the vagus nerve
* left/right level of greater horn of hyoid on the vagus nerve
* left/right level of carotid bifurcation on the vagus nerve
* left/right level of laryngeal prominence on the vagus nerve
* left/right level of superior border of the clavicle on the vagus nerve
* left/right level of jugular notch on the vagus nerve
* left/right level of sternal angle on the vagus nerve
* left/right level of 1 cm superior to start of esophageal plexus on the vagus nerve
* left/right level of esophageal hiatus on the vagus nerve
* left/right level of aortic hiatus on the vagus nerve

.. _fig-scaffoldmaker-vagus-material-markers:

.. figure:: ../_images/ssv_material_markers.png
:align: center

Vagus nerve level markers shown in material ``vagus coordinates``.

Orientation points could be included in the input file for better nerve fitting. If included, they should be listed as
``nodes``, not ``datapoints``. The following annotation group names must be used for orientation nodes:

* orientation left
* orientation anterior
* orientation left anterior
* orientation right anterior
* orientation right
* orientation right posterior
* orientation posterior
* orientation left posterior

Variants
--------
Expand All @@ -42,11 +79,15 @@ The vagus scaffold is provided with the following parameter sets:
Coordinates
-----------

The vagus box scaffold defines the geometric and material coordinates.
The vagus box scaffold defines geometric, straight and material coordinates as shown in :numref:`fig-scaffoldmaker-vagus-3-coordinates`

The ``geometric coordinates`` field is fitted to the coordinates supplied in the input file.

The geometric ``coordinates`` field is built using the coordinates supplied by the input file.
The ``straight coordinates`` field defines a coordinate system with a straight line as vagus trunk, with origin as
the top of the trunk and conserving trunk length from geometric coordinates. The branches have the same dimensions and
relative directions to their origin on a parent branch or trunk, but are straight.

The material ``coordinates`` field defines a coordinate system to give permanent locations for landmarks on the vagus.
The ``material coordinates`` field defines a coordinate system to give permanent locations for landmarks on the vagus.
It is defined as a straight line as vagus trunk, with origin as the top of the vagus trunk and 1 as the bottom end
of the vagus trunk. The branches are defined as lines with the same orientation as when they are leaving the trunk.

Expand All @@ -59,6 +100,6 @@ annotated with standard term names and identifiers from a controlled vocabulary.

Each subject-specific vagus box scaffold has the following defined groups of 3-D elements:

* vagus centroid
* vagus epineureum
* vagus anterior line
* ``vagus centroid`` - centroid of nerve/branch, useful for later fitting centroid data in another geometric configuration such as in-body/MRI tracings.
* ``vagus epineurium`` - approximately round representation of surface of epineurium, useful for later fitting to precise contours of the epineurium boundary.
* ``vagus anterior line`` - line on anterior edge of epineurium, useful for later fitting anterior orientation points in another geometric configuration.
9 changes: 5 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ authors = [
{ name="Richard Christie", email="[email protected]" },
]
dependencies = [
"cmlibs.maths >= 0.7.0",
"cmlibs.utils >= 0.6",
"cmlibs.zinc >= 4.1",
"scaffoldfitter >= 0.9",
"cmlibs.maths >= 0.7.1",
"cmlibs.utils >= 0.12.5",
"cmlibs.zinc >= 4.2.1",
"fieldfitter >= 0.5.1",
"scaffoldfitter >= 0.11.1",
"scipy",
"numpy"
]
Expand Down
38 changes: 38 additions & 0 deletions src/scaffoldmaker/annotation/annotation_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""
Utilities for working with annotations.
"""
import logging


logger = logging.getLogger(__name__)


def annotation_term_id_to_url(term):
"""
Convert short forms of annotation term ids into full urls e.g.:
"UBERON:0000948" --> "http://purl.obolibrary.org/obo/UBERON_0000948"
"ILX:0732254" --> "http://uri.interlex.org/base/ilx_0732254"
"FMA:7088" --> "http://purl.org/sig/ont/fma/fma7088"
Other namespaces should be added as needed, but until then are returned as is with a warning.
:param term_name:
:param term_id: String short form of annotation term id NAMESPACE:#.
:return: term with id converted to url idfpossible.
"""
if not term[1]:
logger.warning("annotation_term_id_to_url: Missing term id for annotation '" + term[0] + "'")
return term
if ":" not in term[1]:
logger.error("annotation_term_id_to_url: Invalid annotation term id ('" + term[0] + "', '" + term[1] + "')")
return term
raw_prefix, number_str = term[1].split(":")
prefix = raw_prefix.upper()
if prefix == "UBERON":
url_prefix = "http://purl.obolibrary.org/obo/UBERON_"
elif prefix == "ILX":
url_prefix = "http://uri.interlex.org/base/ilx_"
elif prefix == "FMA":
url_prefix = "http://purl.org/sig/ont/fma/fma"
else:
logger.warning("annotation_term_id_to_url: No url known for term ('" + term[0] + "', '" + term[1] + "')")
return term
return (term[0], url_prefix + number_str)
7 changes: 5 additions & 2 deletions src/scaffoldmaker/annotation/annotationgroup.py
Original file line number Diff line number Diff line change
Expand Up @@ -554,8 +554,11 @@ def findOrCreateAnnotationGroupForTerm(annotationGroups: list, region, term, isM
name = term[0]
annotationGroup = findAnnotationGroupByName(annotationGroups, name)
if annotationGroup:
assert annotationGroup._id == term[1], "Annotation group '" + name + "' id '" + term[1]\
+ "' does not match existing id '" + annotationGroup._id + "'"
if annotationGroup.getId() == "":
annotationGroup.setId(term[1])
elif term[1] != "":
assert annotationGroup.getId() == term[1], "Annotation group '" + name + "' id '" + term[1] + \
"' does not match existing id '" + annotationGroup.getId() + "'"
else:
annotationGroup = AnnotationGroup(region, term, isMarker=isMarker)
annotationGroups.append(annotationGroup)
Expand Down
Loading