@@ -4776,15 +4776,38 @@ def build(node_id, depth):
47764776 # ------------------------------------------------------------------
47774777
47784778 def _build_ancestors_subclass (term_id , depth , visited ):
4779- """Build is-a ancestor chain from SOLR term_info parents."""
4779+ """Build is-a ancestor chain from SOLR term_info parents.
4780+
4781+ Filters to FBbt cell terms only (types includes 'Cell') to
4782+ exclude cross-ontology parents (CL, UBERON, BFO, etc.) and
4783+ non-cell ancestors (developmental lineage, anatomical structure).
4784+ Stops at 'cell' (FBbt_00007002).
4785+ """
47804786 if term_id in visited or (max_depth != - 1 and depth >= max_depth ):
47814787 return []
4788+ if term_id == 'FBbt_00007002' : # cell — top of useful hierarchy
4789+ return []
47824790 visited .add (term_id )
4783- parent_tuples = _term_info_parents (term_id )
4784- if not parent_tuples :
4791+
4792+ try :
4793+ results = vfb_solr .search (f'id:{ term_id } ' , fl = 'term_info' , rows = 1 )
4794+ if not results .docs or 'term_info' not in results .docs [0 ]:
4795+ return []
4796+ raw = results .docs [0 ]['term_info' ]
4797+ ti = json .loads (raw [0 ] if isinstance (raw , list ) else raw )
4798+ parents = ti .get ('parents' , [])
4799+ except Exception :
47854800 return []
4801+
47864802 ancestors = []
4787- for psf , plabel in parent_tuples :
4803+ for p in parents :
4804+ psf = p ['short_form' ]
4805+ # Filter: must be FBbt and must be a cell type
4806+ if not psf .startswith ('FBbt_' ):
4807+ continue
4808+ if 'Cell' not in p .get ('types' , []):
4809+ continue
4810+ plabel = p .get ('label' , psf )
47884811 label_cache [psf ] = plabel
47894812 node = {'id' : psf , 'label' : plabel }
47904813 further = _build_ancestors_subclass (psf , depth + 1 , visited )
0 commit comments