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) {