diff --git a/CHANGELOG.md b/CHANGELOG.md
index fc5af7f3841efb98bef4dc7f527f01539099863b..ab156a198dc3c3c9a2d138048da470f37faef1a8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@ Note that since we don't clearly distinguish between a public and private interf
- [Fix] Clone ``Canvas3DParams`` when creating a ``Canvas3D`` instance to prevent shared state between multiple instances
- Add ``includeResidueTest`` option to ``alignAndSuperposeWithSIFTSMapping``
- Add ``parentDisplay`` param for interactions representation.
+- Fix handling of PDB TER records (#549)
- Add support for getting multiple loci from a representation (``.getAllLoci()``)
- Add ``key`` property to intra- and inter-bonds for referencing source data
diff --git a/src/mol-model-formats/structure/common/component.ts b/src/mol-model-formats/structure/common/component.ts
index 948a01fcb7df8a3b8942d5798a106a5c13588416..770a095cac67716d4bb64b82157b2a6a4a5af33b 100644
--- a/src/mol-model-formats/structure/common/component.ts
+++ b/src/mol-model-formats/structure/common/component.ts
@@ -32,6 +32,7 @@ const DnaAtomIdsList = [
/** Used to reduce false positives for atom name-based type guessing */
const NonPolymerNames = new Set([
'FMN', 'NCN', 'FNS', 'FMA', 'ATP', 'ADP', 'AMP', 'GTP', 'GDP', 'GMP', // Mononucleotides
+ 'LIG'
]);
const StandardComponents = (function () {
diff --git a/src/mol-model-formats/structure/pdb/atom-site.ts b/src/mol-model-formats/structure/pdb/atom-site.ts
index 7de7aeed37eb9c36cd14b717f05b7b6b02f6b3f9..21d5364d6f546aa041e2992c94b84a156347cf52 100644
--- a/src/mol-model-formats/structure/pdb/atom-site.ts
+++ b/src/mol-model-formats/structure/pdb/atom-site.ts
@@ -39,7 +39,7 @@ export function getAtomSiteTemplate(data: string, count: number) {
};
}
-export function getAtomSite(sites: AtomSiteTemplate, hasTer: boolean): { [K in keyof mmCIF_Schema['atom_site'] | 'partial_charge']?: CifField } {
+export function getAtomSite(sites: AtomSiteTemplate, terIndices: Set<number>): { [K in keyof mmCIF_Schema['atom_site'] | 'partial_charge']?: CifField } {
const pdbx_PDB_model_num = CifField.ofStrings(sites.pdbx_PDB_model_num);
const auth_asym_id = CifField.ofTokens(sites.auth_asym_id);
const auth_seq_id = CifField.ofTokens(sites.auth_seq_id);
@@ -91,7 +91,7 @@ export function getAtomSite(sites: AtomSiteTemplate, hasTer: boolean): { [K in k
if (asymIdCounts.has(asymId)) {
// only change the chains name if there are TER records
// otherwise assume repeated chain name use is from interleaved chains
- if (hasTer && asymIdChanged) {
+ if (terIndices.has(i)) {
const asymIdCount = asymIdCounts.get(asymId)! + 1;
asymIdCounts.set(asymId, asymIdCount);
currLabelAsymId = `${asymId}_${asymIdCount}`;
diff --git a/src/mol-model-formats/structure/pdb/to-cif.ts b/src/mol-model-formats/structure/pdb/to-cif.ts
index 21a2a68f0593c6aeecf3d549600b0836290d167d..792d5a136d2c45388eba6ca8612803c890c7d32c 100644
--- a/src/mol-model-formats/structure/pdb/to-cif.ts
+++ b/src/mol-model-formats/structure/pdb/to-cif.ts
@@ -51,7 +51,7 @@ export async function pdbToMmCif(pdb: PdbFile): Promise<CifFrame> {
let modelNum = 0, modelStr = '';
let conectRange: [number, number] | undefined = undefined;
- let hasTer = false;
+ const terIndices = new Set<number>();
for (let i = 0, _i = lines.count; i < _i; i++) {
let s = indices[2 * i], e = indices[2 * i + 1];
@@ -164,7 +164,7 @@ export async function pdbToMmCif(pdb: PdbFile): Promise<CifFrame> {
break;
case 'T':
if (substringStartsWith(data, s, e, 'TER')) {
- hasTer = true;
+ terIndices.add(atomSite.index);
}
}
}
@@ -183,7 +183,7 @@ export async function pdbToMmCif(pdb: PdbFile): Promise<CifFrame> {
atomSite.label_entity_id[i] = entityBuilder.getEntityId(compId, moleculeType, asymIds.value(i));
}
- const atom_site = getAtomSite(atomSite, hasTer);
+ const atom_site = getAtomSite(atomSite, terIndices);
if (!isPdbqt) delete atom_site.partial_charge;
if (conectRange) {