OHDSI Home | Forums | Wiki | Github

Question about Concept_ancestor

Hello all,
I need some additional help understanding how the ancestor table works. I read the thread on " Question about Concept_ancestor and Concept_relationship table" and have related questions–specifically with SNOMED procedures and min/max levels of separation.

If I am looking at all of the ancestors of a procedure, is there a way to list them in a way that is least specific/broadest to most specific/ closest ancestor? Similar to ATC tiers where you can create a hierarchy.

Can you incorporate the min/max levels of separation to specify how recent an ancestor it is?

Thank you for any help/feedback!

If you want to traverse ancestors of arbitrary concepts “breadth first”, you will need to group concept_ancestor by descendant_concept_id and sort by min_levels_of_separation in ascending order.

Each concept will have a min_levels_of_separation=0 entry to self, then to immediate parents with exactly 1 (reflecting presence of ‘Is a’ relationship in concept_relationship), then 2 for their immediate parents, and so on.

Concept of differences of levels of separation specifically in SNOMED arises from the multiaxial nature of SNOMED hierarchy. There may be multiple paths from an ancestor to a descendant: laparoscopic appendectomy will be a descendant of both excision of intestine and medical imaging guided procedure, and will be an eventual descendant of a generic “Procedure” concept through both of them. Length of each such branch is somewhat random, and only depends on amount of arbitrary intermediate grouping concepts SNOMED authors introduced. I found pure value of hierarchy depth to be an unreliable predictor of concepts “specificity”. But longest possible path between concepts is still “remembered” in max_levels_of_separation. Even so, you will probably not get a clean picture of hierarchy along multiple paths, as you would in a more rigid classification like ATC or ICD10PCS.

From all SNOMED browsers, CSIRO Shrimp has the best hierarchy visualization. You can see how different branches leading from root to concept of interest have to jump levels, so they have different effective length.

@Eduard_Korchmar Thank you so much! That was very informative. I checked out the resource you linked and it’s a great visualization of what I am trying to accomplish.

If I used min_levels_of_separation = 1 to identify immediate parents, and then 2 to identify grandparents, and so on, would that be an accurate portrayal of hierarchy or is SNOMED not designed for any type of hierarchy? All other ones where min and max levels are not equal/ they jump over levels would be fit in as well.

I think min_levels_of_separation should alone be enough to reconstruct the SNOMED hierarchy computationally through iteration. SNOMED does have a strict one-directional hierarchical graph, but it is hard to visualize because it has arbitrary leveling and branching paths between nodes by design. There is, however, a single root node that is a shared parent of every single SNOMED concept, and loops are not allowed.

I see. I tried that with some SQL, but I am getting different results than the CSIRO visualization tool. There, they had 71 procedures stemming from “Procedure, concept code= 71388002”, but when I looked for direct children of 71388002, I got 33 instead. I saw that some of them weren’t in the procedure domain, which I am specifically looking at.

Could you take a look at my code and see if you spot what is going on? I joined concept_ancestor to concept to put names to the ancestors and descendants, looking at the direct children (max and min separation= 1) of Procedure (concept code= 71388002), which is what I thought to be the common ancestor of all SNOMED procedures, based on the visualization tool.

Again, thank you for your help. I appreciate it greatly.

(
SELECT
CONCEPT.CONCEPT_NAME as ancestor_name
, c2.CONCEPT_NAME as desc_name
, CONCEPT_ANCESTOR.*
FROM
CONCEPT_ANCESTOR
LEFT OUTER JOIN
CONCEPT
ON
CONCEPT.CONCEPT_ID = CONCEPT_ANCESTOR.ANCESTOR_CONCEPT_ID
LEFT OUTER JOIN
CONCEPT c2
ON
c2.CONCEPT_ID = CONCEPT_ANCESTOR.DESCENDANT_CONCEPT_ID
WHERE
CONCEPT.VOCABULARY_ID = ‘SNOMED’
AND
c2.VOCABULARY_ID = ‘SNOMED’
AND
CONCEPT.DOMAIN_ID = ‘Procedure’
AND
c2.DOMAIN_ID = ‘Procedure’
AND
CONCEPT_ANCESTOR.MAX_LEVELS_OF_SEPARATION = 1
AND
MIN_LEVELS_OF_SEPARATION = 1
AND
CONCEPT.CONCEPT_CODE = ‘71388002’
)
;

t