diff --git a/src/mol-model/structure/export/categories/atom_site.ts b/src/mol-model/structure/export/categories/atom_site.ts index 271f9f287c46a7573bdf2f9cae0b758df1e92077..926ed369016843f1be44d3659958d36c839cbeb9 100644 --- a/src/mol-model/structure/export/categories/atom_site.ts +++ b/src/mol-model/structure/export/categories/atom_site.ts @@ -61,10 +61,18 @@ export const _atom_site: CifCategory<CifExportContext> = { } } -export function residueIdFields<K, D>(getLocation: (key: K, data: D) => StructureElement): CifField<K, D>[] { +function prefixed(prefix: string, name: string) { + return prefix ? `${prefix}_${name}` : name; +} + +function mappedProp<K, D>(loc: (key: K, data: D) => StructureElement, prop: (e: StructureElement) => any) { + return (k: K, d: D) => prop(loc(k, d)); +} + +export function residueIdFields<K, D>(getLocation: (key: K, data: D) => StructureElement, prefix = ''): CifField<K, D>[] { return [ - CifField.str('label_comp_id', (k, d) => P.residue.label_comp_id(getLocation(k, d))), - CifField.int('label_seq_id', (k, d) => P.residue.label_seq_id(getLocation(k, d)), { + CifField.str(prefixed(prefix, `label_comp_id`), mappedProp(getLocation, P.residue.label_comp_id)), + CifField.int(prefixed(prefix, `label_seq_id`), mappedProp(getLocation, P.residue.label_seq_id), { encoder: E.deltaRLE, valueKind: (k, d) => { const e = getLocation(k, d); @@ -72,13 +80,21 @@ export function residueIdFields<K, D>(getLocation: (key: K, data: D) => Structur return m.atomicHierarchy.residues.label_seq_id.valueKind(m.atomicHierarchy.residueAtomSegments.index[e.element]); } }), - CifField.str('pdbx_PDB_ins_code', (k, d) => P.residue.pdbx_PDB_ins_code(getLocation(k, d))), + CifField.str(prefixed(prefix, `pdbx_PDB_ins_code`), mappedProp(getLocation, P.residue.pdbx_PDB_ins_code)), - CifField.str('label_asym_id', (k, d) => P.chain.label_asym_id(getLocation(k, d))), - CifField.str('label_entity_id', (k, d) => P.chain.label_entity_id(getLocation(k, d))), + CifField.str(prefixed(prefix, `label_asym_id`), mappedProp(getLocation, P.chain.label_asym_id)), + CifField.str(prefixed(prefix, `label_entity_id`), mappedProp(getLocation, P.chain.label_entity_id)), - CifField.str('auth_comp_id', (k, d) => P.residue.auth_comp_id(getLocation(k, d))), - CifField.int('auth_seq_id', (k, d) => P.residue.auth_seq_id(getLocation(k, d)), { encoder: E.deltaRLE }), - CifField.str('auth_asym_id', (k, d) => P.chain.auth_asym_id(getLocation(k, d))), - ] + CifField.str(prefixed(prefix, `auth_comp_id`), mappedProp(getLocation, P.residue.auth_comp_id)), + CifField.int(prefixed(prefix, `auth_seq_id`), mappedProp(getLocation, P.residue.auth_seq_id), { encoder: E.deltaRLE }), + CifField.str(prefixed(prefix, `auth_asym_id`), mappedProp(getLocation, P.chain.auth_asym_id)) + ]; +} + +export function chainIdFields<K, D>(getLocation: (key: K, data: D) => StructureElement, prefix = ''): CifField<K, D>[] { + return [ + CifField.str(prefixed(prefix, `label_asym_id`), mappedProp(getLocation, P.chain.label_asym_id)), + CifField.str(prefixed(prefix, `label_entity_id`), mappedProp(getLocation, P.chain.label_entity_id)), + CifField.str(prefixed(prefix, `auth_asym_id`), mappedProp(getLocation, P.chain.auth_asym_id)) + ]; } \ No newline at end of file diff --git a/src/mol-model/structure/export/categories/secondary-structure.ts b/src/mol-model/structure/export/categories/secondary-structure.ts index 1c18813be27b4607095b9bf0749be9b092658bfe..afd936db2c5c963820055781fec7fd82049f74fe 100644 --- a/src/mol-model/structure/export/categories/secondary-structure.ts +++ b/src/mol-model/structure/export/categories/secondary-structure.ts @@ -7,11 +7,12 @@ import { Segmentation } from 'mol-data/int'; import { CifWriter } from 'mol-io/writer/cif'; import { SecondaryStructure } from '../../model/properties/seconday-structure'; -import { StructureElement, Unit, StructureProperties as P } from '../../structure'; +import { StructureElement, Unit } from '../../structure'; import { CifExportContext } from '../mmcif'; import CifField = CifWriter.Field import CifCategory = CifWriter.Category import { Column } from 'mol-data/db'; +import { residueIdFields } from './atom_site'; export const _struct_conf: CifCategory<CifExportContext> = { name: 'struct_conf', @@ -37,8 +38,8 @@ function compare_ssr(x: SSElement<SecondaryStructure.Sheet>, y: SSElement<Second const struct_conf_fields: CifField[] = [ CifField.str<number, SSElement<SecondaryStructure.Helix>[]>('conf_type_id', (i, data) => data[i].element.type_id), CifField.str<number, SSElement<SecondaryStructure.Helix>[]>('id', (i, data, idx) => `${data[i].element.type_id}${idx + 1}`), - ...residueIdFields('beg_', e => e.start), - ...residueIdFields('end_', e => e.end), + ...residueIdFields<number, SSElement<SecondaryStructure.Helix>[]>((i, e) => e[i].start, 'beg'), + ...residueIdFields<number, SSElement<SecondaryStructure.Helix>[]>((i, e) => e[i].end, 'end'), CifField.str<number, SSElement<SecondaryStructure.Helix>[]>('pdbx_PDB_helix_class', (i, data) => data[i].element.helix_class), CifField.str<number, SSElement<SecondaryStructure.Helix>[]>('details', (i, data) => data[i].element.details || '', { valueKind: (i, d) => !!d[i].element.details ? Column.ValueKind.Present : Column.ValueKind.Unknown @@ -49,24 +50,11 @@ const struct_conf_fields: CifField[] = [ const struct_sheet_range_fields: CifField[] = [ CifField.str<number, SSElement<SecondaryStructure.Sheet>[]>('sheet_id', (i, data) => data[i].element.sheet_id), CifField.index('id'), - ...residueIdFields('beg_', e => e.start), - ...residueIdFields('end_', e => e.end), + ...residueIdFields<number, SSElement<SecondaryStructure.Sheet>[]>((i, e) => e[i].start, 'beg'), + ...residueIdFields<number, SSElement<SecondaryStructure.Sheet>[]>((i, e) => e[i].end, 'end'), CifField.str('symmetry', (i, data) => '', { valueKind: (i, d) => Column.ValueKind.Unknown }) ]; -function residueIdFields(prefix: string, loc: (e: SSElement<any>) => StructureElement): CifField<number, SSElement<SecondaryStructure.Helix>[]>[] { - return [ - CifField.str(`${prefix}label_comp_id`, (i, d) => P.residue.label_comp_id(loc(d[i]))), - CifField.int(`${prefix}label_seq_id`, (i, d) => P.residue.label_seq_id(loc(d[i]))), - CifField.str(`pdbx_${prefix}PDB_ins_code`, (i, d) => P.residue.pdbx_PDB_ins_code(loc(d[i]))), - CifField.str(`${prefix}label_asym_id`, (i, d) => P.chain.label_asym_id(loc(d[i]))), - CifField.str(`${prefix}label_entity_id`, (i, d) => P.chain.label_entity_id(loc(d[i]))), - CifField.str(`${prefix}auth_comp_id`, (i, d) => P.residue.auth_comp_id(loc(d[i]))), - CifField.int(`${prefix}auth_seq_id`, (i, d) => P.residue.auth_seq_id(loc(d[i]))), - CifField.str(`${prefix}auth_asym_id`, (i, d) => P.chain.auth_asym_id(loc(d[i]))) - ]; -} - interface SSElement<T extends SecondaryStructure.Element> { start: StructureElement, end: StructureElement,