Skip to content

Commit

Permalink
Classify single sugar as a nonpolymer, not branched
Browse files Browse the repository at this point in the history
  • Loading branch information
benmwebb committed Feb 10, 2024
1 parent 8bbf43b commit 4a01eba
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 15 deletions.
2 changes: 1 addition & 1 deletion ihm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1402,7 +1402,7 @@ def is_polymeric(self):
def is_branched(self):
"""Return True iff this entity is branched (generally
an oligosaccharide)"""
return ((len(self.sequence) > 0
return ((len(self.sequence) > 1
and isinstance(self.sequence[0], SaccharideChemComp)) or
(len(self.sequence) == 0 and self._hint_branched))

Expand Down
25 changes: 17 additions & 8 deletions test/test_dumper.py
Original file line number Diff line number Diff line change
Expand Up @@ -426,9 +426,10 @@ def test_entity_duplicates(self):
def test_entity_duplicate_branched(self):
"""Test EntityDumper with duplicate branched entities"""
system = ihm.System()
sacc = ihm.SaccharideChemComp('NAG')
system.entities.append(ihm.Entity([sacc]))
system.entities.append(ihm.Entity([sacc]))
sacc1 = ihm.SaccharideChemComp('NAG')
sacc2 = ihm.SaccharideChemComp('FUC')
system.entities.append(ihm.Entity([sacc1, sacc2]))
system.entities.append(ihm.Entity([sacc1, sacc2]))
dumper = ihm.dumper._EntityDumper()
dumper.finalize(system) # Assign IDs
out = _get_dumper_output(dumper, system)
Expand Down Expand Up @@ -863,7 +864,8 @@ def test_entity_nonpoly_dumper(self):
e2 = ihm.Entity([ihm.NonPolymerChemComp('HEM')], description='heme')
e3 = ihm.Entity([ihm.WaterChemComp()])
# Branched entity
e4 = ihm.Entity([ihm.SaccharideChemComp('NAG')])
e4 = ihm.Entity([ihm.SaccharideChemComp('NAG'),
ihm.SaccharideChemComp('FUC')])
system.entities.extend((e1, e2, e3, e4))

ed = ihm.dumper._EntityDumper()
Expand Down Expand Up @@ -5064,7 +5066,8 @@ def test_entity_branch_list_dumper(self):
"""Test EntityBranchListDumper"""
system = ihm.System()
system.entities.append(ihm.Entity(
[ihm.SaccharideChemComp('NAG')]))
[ihm.SaccharideChemComp('NAG'),
ihm.SaccharideChemComp('FUC')]))
# Non-branched entity
system.entities.append(ihm.Entity('ACGT'))
ed = ihm.dumper._EntityDumper()
Expand All @@ -5078,14 +5081,16 @@ def test_entity_branch_list_dumper(self):
_pdbx_entity_branch_list.comp_id
_pdbx_entity_branch_list.hetero
1 1 NAG .
1 2 FUC .
#
""")

def test_entity_branch_dumper(self):
"""Test EntityBranchDumper"""
system = ihm.System()
system.entities.append(ihm.Entity(
[ihm.SaccharideChemComp('NAG')]))
[ihm.SaccharideChemComp('NAG'),
ihm.SaccharideChemComp('FUC')]))
# Non-branched entity
system.entities.append(ihm.Entity('ACGT'))
ed = ihm.dumper._EntityDumper()
Expand All @@ -5103,8 +5108,10 @@ def test_entity_branch_dumper(self):
def test_branch_scheme_dumper(self):
"""Test BranchSchemeDumper"""
system = ihm.System()
e1 = ihm.Entity([ihm.SaccharideChemComp('NAG')])
e2 = ihm.Entity([ihm.SaccharideChemComp('FUC')])
e1 = ihm.Entity([ihm.SaccharideChemComp('NAG'),
ihm.SaccharideChemComp('FUC')])
e2 = ihm.Entity([ihm.SaccharideChemComp('FUC'),
ihm.SaccharideChemComp('BGC')])
# Non-branched entity
e3 = ihm.Entity('ACT')
system.entities.extend((e1, e2, e3))
Expand All @@ -5127,7 +5134,9 @@ def test_branch_scheme_dumper(self):
_pdbx_branch_scheme.pdb_mon_id
_pdbx_branch_scheme.pdb_asym_id
A 1 NAG 1 1 1 NAG NAG A
A 1 FUC 2 2 2 FUC FUC A
B 2 FUC 1 6 6 FUC FUC B
B 2 BGC 2 7 7 BGC BGC B
#
""")

Expand Down
22 changes: 16 additions & 6 deletions test/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,19 +219,21 @@ def test_entity(self):
e2 = ihm.Entity('AHCD', description='bar')
e3 = ihm.Entity('AHCDE', description='foo')
heme = ihm.Entity([ihm.NonPolymerChemComp('HEM')])
sugar = ihm.Entity([ihm.SaccharideChemComp('NAG')])
sugar = ihm.Entity([ihm.SaccharideChemComp('NAG'),
ihm.SaccharideChemComp('FUC')])
self.assertEqual(e1, e2)
self.assertNotEqual(e1, e3)
self.assertEqual(e1.seq_id_range, (1, 4))
self.assertEqual(e3.seq_id_range, (1, 5))
sugar2 = ihm.Entity([ihm.SaccharideChemComp('NAG')])
sugar2 = ihm.Entity([ihm.SaccharideChemComp('NAG'),
ihm.SaccharideChemComp('FUC')])
# Branched entities never compare equal unless they are the same object
self.assertEqual(sugar, sugar)
self.assertNotEqual(sugar, sugar2)
# seq_id does not exist for nonpolymers
self.assertEqual(heme.seq_id_range, (None, None))
# We do have an internal seq_id_range for branched entities
self.assertEqual(sugar.seq_id_range, (1, 1))
self.assertEqual(sugar.seq_id_range, (1, 2))

def test_entity_weight(self):
"""Test Entity.formula_weight"""
Expand All @@ -246,7 +248,8 @@ def test_entity_type(self):
protein = ihm.Entity('AHCD')
heme = ihm.Entity([ihm.NonPolymerChemComp('HEM')])
water = ihm.Entity([ihm.WaterChemComp()])
sugar = ihm.Entity([ihm.SaccharideChemComp('NAG')])
sugar = ihm.Entity([ihm.SaccharideChemComp('NAG'),
ihm.SaccharideChemComp('FUC')])
self.assertEqual(protein.type, 'polymer')
self.assertTrue(protein.is_polymeric())
self.assertFalse(protein.is_branched())
Expand All @@ -260,6 +263,12 @@ def test_entity_type(self):
self.assertFalse(sugar.is_polymeric())
self.assertTrue(sugar.is_branched())

# A single sugar should be classified non-polymer
single_sugar = ihm.Entity([ihm.SaccharideChemComp('NAG')])
self.assertEqual(single_sugar.type, 'non-polymer')
self.assertFalse(single_sugar.is_polymeric())
self.assertFalse(single_sugar.is_branched())

# A single amino acid should be classified non-polymer
single_aa = ihm.Entity('A')
self.assertEqual(single_aa.type, 'non-polymer')
Expand Down Expand Up @@ -475,7 +484,8 @@ def test_asym_range(self):
"""Test AsymUnitRange class"""
e = ihm.Entity('AHCDAH')
heme = ihm.Entity([ihm.NonPolymerChemComp('HEM')])
sugar = ihm.Entity([ihm.SaccharideChemComp('NAG')])
sugar = ihm.Entity([ihm.SaccharideChemComp('NAG'),
ihm.SaccharideChemComp('FUC')])
a = ihm.AsymUnit(e, "testdetail")
aheme = ihm.AsymUnit(heme)
asugar = ihm.AsymUnit(sugar)
Expand All @@ -484,7 +494,7 @@ def test_asym_range(self):
# seq_id is not defined for nonpolymers
self.assertEqual(aheme.seq_id_range, (None, None))
# We use seq_id internally for branched entities
self.assertEqual(asugar.seq_id_range, (1, 1))
self.assertEqual(asugar.seq_id_range, (1, 2))
r = a(3, 4)
self.assertEqual(r.seq_id_range, (3, 4))
self.assertEqual(r._id, 42)
Expand Down

0 comments on commit 4a01eba

Please sign in to comment.