From 164c62e091886855cb16260803060c6e05a5631b Mon Sep 17 00:00:00 2001 From: David Sehnal <david.sehnal@gmail.com> Date: Sat, 28 Oct 2017 14:28:37 +0200 Subject: [PATCH] more data model --- .../collections/_spec/segmentation.spec.ts | 7 ++-- .../collections/integer/impl/segmentation.ts | 12 +++--- .../collections/integer/segmentation.ts | 1 - src/mol-data/atom.ts | 1 + src/mol-data/model.ts | 15 ++++++-- .../model/{formats => builders}/mmcif.ts | 38 +++++++++++-------- src/mol-data/model/{interfaces => }/common.ts | 0 src/mol-data/model/common/keys.ts | 5 +++ .../model/{interfaces => }/macromolecule.ts | 0 src/mol-data/structure/base.ts | 15 ++++++++ src/script.ts | 4 +- 11 files changed, 66 insertions(+), 32 deletions(-) rename src/mol-data/model/{formats => builders}/mmcif.ts (71%) rename src/mol-data/model/{interfaces => }/common.ts (100%) create mode 100644 src/mol-data/model/common/keys.ts rename src/mol-data/model/{interfaces => }/macromolecule.ts (100%) diff --git a/src/mol-base/collections/_spec/segmentation.spec.ts b/src/mol-base/collections/_spec/segmentation.spec.ts index 005b0bbe8..b44766e5f 100644 --- a/src/mol-base/collections/_spec/segmentation.spec.ts +++ b/src/mol-base/collections/_spec/segmentation.spec.ts @@ -20,11 +20,10 @@ describe('segments', () => { }); it('map', () => { - const segs = Segmentation.create([1, 2, 3]); + const segs = Segmentation.create([0, 1, 2]); expect(segs.segmentMap).toEqual(new Int32Array([0, 1])); - expect(segs.offset).toEqual(1); - expect(Segmentation.getSegment(segs, 1)).toBe(0); - expect(Segmentation.getSegment(segs, 2)).toBe(1); + expect(Segmentation.getSegment(segs, 0)).toBe(0); + expect(Segmentation.getSegment(segs, 1)).toBe(1); }) it('iteration', () => { diff --git a/src/mol-base/collections/integer/impl/segmentation.ts b/src/mol-base/collections/integer/impl/segmentation.ts index e24f4757d..a821db8ae 100644 --- a/src/mol-base/collections/integer/impl/segmentation.ts +++ b/src/mol-base/collections/integer/impl/segmentation.ts @@ -10,22 +10,22 @@ import Interval from '../interval' import SortedArray from '../sorted-array' import Segs from '../segmentation' -type Segmentation = { segments: SortedArray, segmentMap: ArrayLike<number>, offset: number, count: number } +type Segmentation = { segments: SortedArray, segmentMap: ArrayLike<number>, count: number } export function create(values: ArrayLike<number>): Segmentation { const segments = SortedArray.ofSortedArray(values); - const min = SortedArray.min(segments), max = SortedArray.max(segments); - const segmentMap = new Int32Array(max - min); + const max = SortedArray.max(segments); + const segmentMap = new Int32Array(max); for (let i = 0, _i = values.length - 1; i < _i; i++) { - for (let j = values[i] - min, _j = values[i + 1] - min; j < _j; j++) { + for (let j = values[i], _j = values[i + 1]; j < _j; j++) { segmentMap[j] = i; } } - return { segments, segmentMap, offset: min, count: values.length - 1 }; + return { segments, segmentMap, count: values.length - 1 }; } export function count({ count }: Segmentation) { return count; } -export function getSegment({ segmentMap, offset }: Segmentation, value: number) { return segmentMap[value - offset]; } +export function getSegment({ segmentMap }: Segmentation, value: number) { return segmentMap[value]; } export function projectValue({ segments }: Segmentation, set: OrderedSet, value: number): Interval { const last = OrderedSet.max(segments); diff --git a/src/mol-base/collections/integer/segmentation.ts b/src/mol-base/collections/integer/segmentation.ts index 5d1e6c3bb..6ecdbdf27 100644 --- a/src/mol-base/collections/integer/segmentation.ts +++ b/src/mol-base/collections/integer/segmentation.ts @@ -24,7 +24,6 @@ namespace Segmentation { interface Segmentation { '@type': 'segmentation', readonly segmentMap: ArrayLike<number>, - readonly offset: number, readonly count: number } diff --git a/src/mol-data/atom.ts b/src/mol-data/atom.ts index 30f225fa7..037a78c3c 100644 --- a/src/mol-data/atom.ts +++ b/src/mol-data/atom.ts @@ -6,6 +6,7 @@ import Tuple from '../mol-base/collections/integer/tuple' +/** Atom pointer */ interface Atom { '@type': Tuple['@type'] } namespace Atom { diff --git a/src/mol-data/model.ts b/src/mol-data/model.ts index 14d427b43..54f89ceb9 100644 --- a/src/mol-data/model.ts +++ b/src/mol-data/model.ts @@ -5,18 +5,25 @@ */ import * as Formats from './model/formats' -import CommonInterface from './model/interfaces/common' -import MacromoleculeInterface from './model/interfaces/common' +import CommonInterface from './model/common' +import MacromoleculeInterface from './model/macromolecule' import Segmentation from '../mol-base/collections/integer/segmentation' +/** + * Interface to the "source data" of the molecule. + * + * "Atoms" are integers in the range [0, atomCount). + */ interface Model { - data: Formats.RawData, + sourceData: Formats.RawData, common: CommonInterface, macromolecule: MacromoleculeInterface + atomCount: number, chains: Segmentation, - residues: Segmentation + residues: Segmentation, + entities: Segmentation } export default Model \ No newline at end of file diff --git a/src/mol-data/model/formats/mmcif.ts b/src/mol-data/model/builders/mmcif.ts similarity index 71% rename from src/mol-data/model/formats/mmcif.ts rename to src/mol-data/model/builders/mmcif.ts index c1cc176dd..71eff5052 100644 --- a/src/mol-data/model/formats/mmcif.ts +++ b/src/mol-data/model/builders/mmcif.ts @@ -21,10 +21,11 @@ function findModelBounds(data: mmCIF, startIndex: number) { function segment(data: mmCIF, bounds: Interval) { const start = Interval.start(bounds), end = Interval.end(bounds); - const residues = [start], chains = [start]; + const residues = [0], chains = [0], entities = [0]; const { label_entity_id, auth_asym_id, auth_seq_id, pdbx_PDB_ins_code } = data.atom_site; + let offset = 1; for (let i = start + 1; i < end; i++) { const newEntity = !label_entity_id.areValuesEqual(i - 1, i); const newChain = newEntity || !auth_asym_id.areValuesEqual(i - 1, i); @@ -32,31 +33,43 @@ function segment(data: mmCIF, bounds: Interval) { || !auth_seq_id.areValuesEqual(i - 1, i) || !pdbx_PDB_ins_code.areValuesEqual(i - 1, i); - if (newResidue) residues[residues.length] = i; - if (newChain) chains[chains.length] = i; + if (newEntity) entities[entities.length] = offset; + if (newResidue) residues[residues.length] = offset; + if (newChain) chains[chains.length] = offset; + offset++; } - residues[residues.length] = end; - chains[chains.length] = end; + residues[residues.length] = offset; + chains[chains.length] = offset; + entities[entities.length] = offset; - return { residues: Segmentation.create(residues), chains: Segmentation.create(chains) }; + return { + residues: Segmentation.create(residues), + chains: Segmentation.create(chains), + entities: Segmentation.create(entities) + }; } function createModel(raw: RawData, data: mmCIF, bounds: Interval): Model { const segments = segment(data, bounds); return { - data: raw, + sourceData: raw, common: 0 as any, macromolecule: 0 as any, + atomCount: Interval.size(bounds), residues: segments.residues, - chains: segments.chains + chains: segments.chains, + entities: segments.entities }; } -function getModels(data: mmCIF): ArrayLike<Model> { +function buildModels(data: mmCIF): ArrayLike<Model> { const raw: RawData = { source: 'mmCIF', data }; const models: Model[] = []; const atomCount = data.atom_site._rowCount; + + if (atomCount === 0) return models; + let modelStart = 0; while (modelStart < atomCount) { const bounds = findModelBounds(data, modelStart); @@ -67,9 +80,4 @@ function getModels(data: mmCIF): ArrayLike<Model> { return models; } -export default getModels; - -// function createStructure() { - -// } - +export default buildModels; \ No newline at end of file diff --git a/src/mol-data/model/interfaces/common.ts b/src/mol-data/model/common.ts similarity index 100% rename from src/mol-data/model/interfaces/common.ts rename to src/mol-data/model/common.ts diff --git a/src/mol-data/model/common/keys.ts b/src/mol-data/model/common/keys.ts new file mode 100644 index 000000000..1a7b5e35b --- /dev/null +++ b/src/mol-data/model/common/keys.ts @@ -0,0 +1,5 @@ +/** + * Copyright (c) 2017 molio contributors, licensed under MIT, See LICENSE file for more info. + * + * @author David Sehnal <david.sehnal@gmail.com> + */ diff --git a/src/mol-data/model/interfaces/macromolecule.ts b/src/mol-data/model/macromolecule.ts similarity index 100% rename from src/mol-data/model/interfaces/macromolecule.ts rename to src/mol-data/model/macromolecule.ts diff --git a/src/mol-data/structure/base.ts b/src/mol-data/structure/base.ts index e69de29bb..5a03161e3 100644 --- a/src/mol-data/structure/base.ts +++ b/src/mol-data/structure/base.ts @@ -0,0 +1,15 @@ +/** + * Copyright (c) 2017 molio contributors, licensed under MIT, See LICENSE file for more info. + * + * @author David Sehnal <david.sehnal@gmail.com> + */ + +import Model from '../model' +import Structure from '../structure' + +//export const Empty { } + +export function ofModel(model: Model): Structure { + // TODO: create a unit for each chain in the model + return 0 as any; +} \ No newline at end of file diff --git a/src/script.ts b/src/script.ts index 345e177e6..e05c5e817 100644 --- a/src/script.ts +++ b/src/script.ts @@ -17,7 +17,7 @@ import CIF from './mol-io/reader/cif' import Computation from './mol-base/computation' -import createModels from './mol-data/model/formats/mmcif' +import buildModels from './mol-data/model/builders/mmcif' // import { toTypedFrame as applySchema } from './reader/cif/schema' import { generateSchema } from './mol-io/reader/cif/schema/utils' @@ -115,7 +115,7 @@ async function runCIF(input: string | Uint8Array) { console.log(mmcif.pdbx_struct_oper_list.matrix.value(0)); console.time('createModels'); - const models = createModels(mmcif); + const models = buildModels(mmcif); console.timeEnd('createModels'); console.log(models[0].common); -- GitLab