# Create standard terminology for new segmentation project

**URL:** <https://discourse.slicer.org/t/create-standard-terminology-for-new-segmentation-project/35798>\
**Category:** Support\
**Tags:** segmentation\
**Created:** [April 25, 2024, 7:35pm UTC](https://discourse.slicer.org/t/create-standard-terminology-for-new-segmentation-project/35798 "2024-04-25T19:35:50Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [April 25, 2024, 7:35pm UTC](https://discourse.slicer.org/t/create-standard-terminology-for-new-segmentation-project/35798/1 "2024-04-25T19:35:50Z")

</div>

> [@Exporting a segmentation paired to a custom colortable](https://discourse.slicer.org/t/exporting-a-segmentation-paired-to-a-custom-colortable/35719/8):
>
> am not sure how this will fix the conversion to the labelmap though. Labelmaps are what goes into the ML training, and they need to have indices. So we will always need some sort of lookup between segment labels and labelmap indices, regardless if the segment labels comes from a standardized terminology. Or am I overlooking something?

The key is to use a project-independent, universal, archival quality segmentation file format. For example, .seg.nrrd file with terminology or DICOM Segmentation Object can both fulfill this role.

You can perform a very simple fully-automatic normalization step (e.g., that is [implemented in slicerio Python package](https://github.com/lassoan/slicerio?tab=readme-ov-file#extract-selected-segments-with-chosen-label-values)) to convert the universal segmentation files to project-specific nrrd files (where you use the same label values for the same structure in all labelmap images). This allows compilation of data from many collections, it does not matter what label values are used in each collection, or if different internal names are used, or some collections have extra segments, etc. These automatically-derived normalized segmentation files are considered temporary files, only used for training, and should not be shared or archived (to avoid redundant storage, backup, complex administration of licenses of combined collections, etc).

I’ve provided a bit more details [here](https://github.com/lassoan/SlicerMONAIAuto3DSeg/blob/main/UsingStandardTerminology.md#use-standard-terminology-during-model-training).

---

<div class="post-metadata">

**Author:** ![muratmaga](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/muratmaga/32/3622_2.png) [@muratmaga](https://discourse.slicer.org/u/muratmaga)\
**Post date:** [April 25, 2024, 7:52pm UTC](https://discourse.slicer.org/t/create-standard-terminology-for-new-segmentation-project/35798/2 "2024-04-25T19:52:09Z")

</div>

> [@lassoan](#):
>
> The key is to use a project-independent, universal, archival quality segmentation file format.

Exactly. We are starting a new project that will involve segmenting a lot of different organisms using a consistent terminology. But we have to build our own terminology from scratch. So any pointers on how to go about it correctly is much appreciated.

> [@lassoan](#):
>
> For example, .seg.nrrd file with terminology

Will it be possible to embed custom terminology in seg.nrrd? How is this different than current practice.

[From here](https://github.com/lassoan/SlicerMONAIAuto3DSeg/blob/main/UsingStandardTerminology.md#use-standard-terminology-during-model-training)

I did not understand this sentence:

```auto
The segmentation (.seg.nrrd) files may have the segments in different order, therefore different label values may be used for the same segment in each file.

```

Is this meant to be a warning about the ordering?

Also, for the labels.csv that needs to be created for slicerio conversion, it is not clear to me whether the header file is fixed or we create our own custom header? Most of these do not fit our terminology

```auto
LabelValue,Name,SegmentedPropertyCategoryCodeSequence.CodingSchemeDesignator,SegmentedPropertyCategoryCodeSequence.CodeValue,SegmentedPropertyCategoryCodeSequence.CodeMeaning,SegmentedPropertyTypeCodeSequence.CodingSchemeDesignator,SegmentedPropertyTypeCodeSequence.CodeValue,SegmentedPropertyTypeCodeSequence.CodeMeaning,SegmentedPropertyTypeModifierCodeSequence.CodingSchemeDesignator,SegmentedPropertyTypeModifierCodeSequence.CodeValue,SegmentedPropertyTypeModifierCodeSequence.CodeMeaning,AnatomicRegionSequence.CodingSchemeDesignator,AnatomicRegionSequence.CodeValue,AnatomicRegionSequence.CodeMeaning,AnatomicRegionModifierSequence.CodingSchemeDesignator,AnatomicRegionModifierSequence.CodeValue,AnatomicRegionModifierSequence.CodeMeaning

```

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [April 25, 2024, 8:04pm UTC](https://discourse.slicer.org/t/create-standard-terminology-for-new-segmentation-project/35798/3 "2024-04-25T20:04:08Z")

</div>

> [@muratmaga](#):
>
> Will it be possible to embed custom terminology in seg.nrrd?

The codes are embedded in the seg.nrrd file. The terminology must be an external file (you don’t want to redefine the entire terminology in each segmentation file).

> [@muratmaga](#):
>
> How is this different than current practice.

The current practice unfortunately is that people leave the terminology code at the general “tissue” default, and use the segment name to identify segments.

> [@muratmaga](#):
>
> Also, for the labels.csv that needs to be created for slicerio conversion, it is not clear to me whether the header file is fixed or we create our own custom header? Most of these do not fit our terminology

There are 2 main hierarchy levels: category and type (with an optional modifier). In addition to this, you can specify anatomical region (with an optional modifier). This is universal terminology, so it should be applicable to anything in biomedical computing. We’ll simplify the column names to the ones described [here](https://github.com/Slicer/Slicer/issues/7593), because I agree that the current column names are too long and confusing.

You don’t have to use SNOMED CT, the scheme is compatible with any terminology, such as TA2, FMA, etc.

> Is this meant to be a warning about the ordering?

It is just an example of why you may end up having segment ending up with different label values. Maybe not the best example. I need to clarify it more.

---

<div class="post-metadata">

**Author:** ![muratmaga](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/muratmaga/32/3622_2.png) [@muratmaga](https://discourse.slicer.org/u/muratmaga)\
**Post date:** [April 25, 2024, 8:56pm UTC](https://discourse.slicer.org/t/create-standard-terminology-for-new-segmentation-project/35798/4 "2024-04-25T20:56:59Z")

</div>

> [@lassoan](#):
>
> You don’t have to use SNOMED CT, the scheme is compatible with any terminology, such as TA2, FMA, etc.

We are using UBERON which provides the largest consolidated terminology for vertebrates. Here are some terms we are likely to include (all of them are bones). How would you go about building a terminology from these?

[UBERON:0011639 (ebi.ac.uk)](https://www.ebi.ac.uk/ols4/ontologies/uberon/classes/http%253A%252F%252Fpurl.obolibrary.org%252Fobo%252FUBERON_0011639)

[UBERON:0004743 (ebi.ac.uk)](https://www.ebi.ac.uk/ols4/ontologies/uberon/classes/http%253A%252F%252Fpurl.obolibrary.org%252Fobo%252FUBERON_0004743)

[UBERON:0001688 (ebi.ac.uk)](https://www.ebi.ac.uk/ols4/ontologies/uberon/classes/http%253A%252F%252Fpurl.obolibrary.org%252Fobo%252FUBERON_0001688)

[UBERON:0008194 (ebi.ac.uk)](https://www.ebi.ac.uk/ols4/ontologies/uberon/classes/http%253A%252F%252Fpurl.obolibrary.org%252Fobo%252FUBERON_0008194)

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [April 25, 2024, 10:03pm UTC](https://discourse.slicer.org/t/create-standard-terminology-for-new-segmentation-project/35798/5 "2024-04-25T22:03:07Z")

</div>

UBERON is a great choice. It has a wide scope and it is freely usable, including the ontology.

The coding scheme designator is [UBERON](https://dicom.nema.org/medical/dicom/current/output/html/part16.html#table_8-1), code value is for example `0011639`, and code meaning is `frontoparietal bone`.

You can put all the codes you want to use in a .term.json file, drag-and-drop it to the Slicer window, and they will be automatically be imported and will be available in the terminology popup.

Since UBERON is open, we could try to format entire terminology (all the anatomical structures) as a .term.json file and see how well Slicer’s terminology selector can cope with it.

---

<div class="post-metadata">

**Author:** ![muratmaga](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/muratmaga/32/3622_2.png) [@muratmaga](https://discourse.slicer.org/u/muratmaga)\
**Post date:** [April 26, 2024, 2:40am UTC](https://discourse.slicer.org/t/create-standard-terminology-for-new-segmentation-project/35798/6 "2024-04-26T02:40:35Z")

</div>

> [@lassoan](#):
>
> Since UBERON is open, we could try to format entire terminology (all the anatomical structures) as a .term.json file and see how well Slicer’s terminology selector can cope with it.

Uberon has thousands of terms. If we fully incorporate it, I am worried that it might be too big to manage and navigate (having to search for terms for a segment wouldn’t be conducive to using terminology).

I have an abbreviated version of some common [skeletal terms here](https://github.com/SlicerMorph/MD_E15/blob/main/SlicerMorph_segmentation_category_type.json)

Can you take a look and comment on it? It seems to work with terminology (i.e, valid JSON file), but I am not sure if we correctly organized it. (BTW, assigned UBERON numbers are fake. I didn’t try to query and pull from it).

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [April 26, 2024, 5:00am UTC](https://discourse.slicer.org/t/create-standard-terminology-for-new-segmentation-project/35798/7 "2024-04-26T05:00:23Z")

</div>

I did a quick test, downloaded [`uberon-full.json`](https://obophenotype.github.io/uberon/current_release/) and wrote this little script to convert all anatomical structures into a Slicer terminology json file.

```python
uberonFile = "path/to/uberon-full.json"
terminologyFile = "path/to/uberon.term.json"

import json
import random

with open(uberonFile, 'r', encoding='utf-8') as file_object:
    uberon = json.load(file_object)

types = []
for node in uberon["graphs"][0]["nodes"]:
    if not node["id"].startswith("http://purl.obolibrary.org/obo/UBERON_"):
        continue
    if not node.get("lbl"):
        # deprecated
        continue
    types.append({
        "CodingSchemeDesignator": "UBERON",
        "CodeValue": node["id"].split("_")[-1],
        "CodeMeaning": node["lbl"],
        "recommendedDisplayRGBValue": [random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)]
        })

terminology = {
  "SegmentationCategoryTypeContextName": "Segmentation category and type - Uberon anatomical structures",
  "@schema": "https://raw.githubusercontent.com/qiicr/dcmqi/master/doc/segment-context-schema.json#",
  "SegmentationCodes": {
    "Category": [
      {
        "CodingSchemeDesignator": "SCT", "CodeValue": "123037004", "CodeMeaning": "Anatomical Structure",
        "showAnatomy": False,
        "Type": types
      }
    ]
  }
}

with open(terminologyFile, "w") as f:
    json.dump(terminology, f, indent=4)

```

The result is a small file containing 15574 structures. You can download it from [here](https://github.com/lassoan/PublicTestingData/releases/download/data/uberon.term.json). You can drag-and-drop it into Slicer and you have all UBERON terms readily selectable - no chance for typos, no need to manually copy codes, etc.

Slicer terminology selector was a bit slow (filtering by name took a few seconds), but after some optimization it is now very fluid. I’ve submit a [pull request](https://github.com/Slicer/Slicer/pull/7714) with the changes, it should be available in the Slicer Preview Release within a few days.

There are a few limitations of this approach:

- The terminology browser in Slicer currently does not use an ontology (shows just a flat list, not possible to jump to parent or get a list of children), so it may be difficult to find the right term. However, you can use the online UBERON browser to explore the various ontologies and find the right term, which you can then very easily find by name in Slicer.
- I’m not sure if you need modifiers. If yes, then you need to find an automated way to figure out what modifiers are relevant for what structures. Maybe something simple like adding `left` and `right` modifier to every type that does not have left or right in the name already could cover what is needed.
- Color is now generated randomly. It could make sense to get generic color from the ontologies (e.g., bones are white/yellow, muscles red, arteries deep red, veins blue, etc. maybe with some randomization)

To make the selection easier, it may make sense to also create smaller terminology files for specific projects that contains a subset of this full list. This subset file would have a unique `SegmentationCategoryTypeContextName`, for example `SlicerMorph Dentition`. I would keep the `Anatomical Structure` category for [DICOM compatibility](https://dicom.nema.org/medical/dicom/current/output/chtml/part16/sect_CID_7150.html). `showAnatomy` has to be set to false for anatomical structures (it only makes sense to specify anatomical region selector if the type is not an anatomical structure, e.g., if the type is a `needle` then you can specify the anatomical region it is in). I don’t think you need to use modifiers (the UBERON codes seem to usually include it). I would drop all the attributes that you don’t use (context group name, cid, etc.).

It would look something like this:

```json
{
    "SegmentationCategoryTypeContextName": "SlicerMorph Dentition",
    "@schema": "https://raw.githubusercontent.com/qiicr/dcmqi/master/doc/schemas/segment-context-schema.json#",
    "SegmentationCodes": {
        "Category": [
            {
                "CodingSchemeDesignator": "SCT",
                "CodeValue": "123037004",
                "CodeMeaning": "Anatomical Structure",
                "showAnatomy": false,
                "Type": [
                    {
                        "recommendedDisplayRGBValue": [0, 179, 92],
                        "CodeValue": "100022",
                        "CodingSchemeDesignator": "UBERON",
                        "CodeMeaning": "Maxillary Molar 1",
                        "3dSlicerLabel": "maxillary molar 1",
                        "Modifier": [
                            {
                                "recommendedDisplayRGBValue": [0, 179, 92],
                                "CodingSchemeDesignator": "SCT",
                                "CodeValue": "24028007",
                                "CodeMeaning": "Right",
                                "3dSlicerLabel": "right maxillary molar 1",
                            },
...
                      ]
                    }
                ]
            }
        ]
    }
}
...

```

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [April 26, 2024, 12:11pm UTC](https://discourse.slicer.org/t/create-standard-terminology-for-new-segmentation-project/35798/8 "2024-04-26T12:11:20Z")

</div>

> [@lassoan](#):
>
> Color is now generated randomly. It could make sense to get generic color from the ontologies (e.g., bones are white/yellow, muscles red, arteries deep red, veins blue, etc. maybe with some randomization)

It would be great if we could pull in community contributed standards like the one Jiami has done:  
[http://www.graysvertebrateanatomy.com/work/colorsofskullanatomy/](http://www.graysvertebrateanatomy.com/work/colorsofskullanatomy/)

But these should be selectable - sometimes you’ll want all the bones to be the same and sometimes you’ll want to subdivide them.

---

<div class="post-metadata">

**Author:** ![muratmaga](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/muratmaga/32/3622_2.png) [@muratmaga](https://discourse.slicer.org/u/muratmaga)\
**Post date:** [April 26, 2024, 3:43pm UTC](https://discourse.slicer.org/t/create-standard-terminology-for-new-segmentation-project/35798/9 "2024-04-26T15:43:55Z")

</div>

Dear Andras, thank you so much for doing this. I downloaded the file you generated.

> [@lassoan](#):
>
> The terminology browser in Slicer currently does not use an ontology (shows just a flat list, not possible to jump to parent or get a list of children), so it may be difficult to find the right term. However, you can use the online UBERON browser to explore the various ontologies and find the right term, which you can then very easily find by name in Slicer.

This is important to optimize, because if search takes longer than manually renaming a segment, it is unlikely that people will bother to use the terminologies.

At this point, everything seems to be listed under the “anatomical structure”. We should divide this into other contexts, such as skeletal system, muscles, organs etc. To make navigating the list easier and faster.

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/c/7/c7b7dbec25bb2c0d0efd2cab9a1d08593943f6b3.png)

> [@lassoan](#):
>
> I’m not sure if you need modifiers.

The only modifier we need is the L/R, and for some of the skeletal terms Uberon seem to provide left and right as separate structures. So at this point I can’t think of other usage, but I will check with my colleagues.

> [@lassoan](#):
>
> Color is now generated randomly.

We have about 20 visually distinct colors. I think the idea is to use these colors in regions that are closeby or in articulation (e.g., cranial bones), and then recycle them for different anatomical regions. Assigning same color to patella and scapula wouldn’t hurt the visual representation, as they are not near by. Most of our segmentations are bones, so having a fixed color for bone types will not really work for us.

---

<div class="post-metadata">

**Author:** ![rkikinis](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/rkikinis/32/791_2.png) [@rkikinis](https://discourse.slicer.org/u/rkikinis)\
**Post date:** [April 26, 2024, 3:52pm UTC](https://discourse.slicer.org/t/create-standard-terminology-for-new-segmentation-project/35798/10 "2024-04-26T15:52:21Z")

</div>

For human anatomy you can look at

[

[TA2 Viewer](https://ta2viewer.openanatomy.org/?id=3932)  
[ta2viewer.openanatomy.org](https://ta2viewer.openanatomy.org/?id=3932)

[![apple-touch-icon.png](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/4/9/49377266fff8fa85038a7f62817a2cdec07fe8fa.png)](https://ta2viewer.openanatomy.org/?id=3932)

]([TA2 Viewer](https://ta2viewer.openanatomy.org/?id=3932))

Best  
Ron

This email is intended for non-work related messages
