Skip to content
Snippets Groups Projects
Commit 87171e14 authored by David Sehnal's avatar David Sehnal
Browse files

wip, refactoring mmCIF parsing for better IHM model support

parent 9b1c299d
No related branches found
No related tags found
No related merge requests found
......@@ -198,10 +198,24 @@ export function printIHMModels(model: Model) {
console.log(Table.formatToString(model.coarseHierarchy.models));
}
export function printModelStats(models: ReadonlyArray<Model>) {
console.log('\nModels\n=============');
for (const m of models) {
if (m.coarseHierarchy.isDefined) {
console.log(`${m.label} ${m.modelNum}: ${m.atomicHierarchy.atoms._rowCount} atom(s), ${m.coarseHierarchy.spheres.count} sphere(s), ${m.coarseHierarchy.gaussians.count} gaussian(s)`);
} else {
console.log(`${m.label} ${m.modelNum}: ${m.atomicHierarchy.atoms._rowCount} atom(s)`);
}
}
console.log();
}
async function run(frame: CifFrame, args: Args) {
const models = await Model.create(Format.mmCIF(frame)).run();
const structure = Structure.ofModel(models[0]);
if (args.models) printModelStats(models);
if (args.seq) printSequence(models[0]);
if (args.ihm) printIHMModels(models[0]);
if (args.units) printUnits(structure);
......@@ -230,6 +244,7 @@ const parser = new argparse.ArgumentParser({
parser.addArgument(['--download', '-d'], { help: 'Pdb entry id' });
parser.addArgument(['--file', '-f'], { help: 'filename' });
parser.addArgument(['--models'], { help: 'print models info', action: 'storeTrue' });
parser.addArgument(['--seq'], { help: 'print sequence', action: 'storeTrue' });
parser.addArgument(['--ihm'], { help: 'print IHM', action: 'storeTrue' });
parser.addArgument(['--units'], { help: 'print units', action: 'storeTrue' });
......@@ -243,6 +258,7 @@ interface Args {
download?: string,
file?: string,
models?:boolean,
seq?: boolean,
ihm?: boolean,
units?: boolean,
......
......@@ -101,6 +101,18 @@ namespace Table {
return ret as Table<R>;
}
export function window<S extends R, R extends Schema>(table: Table<S>, schema: R, start: number, end: number) {
const ret = Object.create(null);
const columns = Object.keys(schema);
ret._rowCount = view.length;
ret._columns = columns;
ret._schema = schema;
for (const k of columns) {
(ret as any)[k] = Column.window(table[k], start, end);
}
return ret as Table<R>;
}
export function concat<S extends R, R extends Schema>(tables: Table<S>[], schema: R) {
const ret = Object.create(null);
const columns = Object.keys(schema);
......
......@@ -5,89 +5,27 @@
*/
import { Column, Table } from 'mol-data/db';
import { Interval, Segmentation } from 'mol-data/int';
import { mmCIF_Database, mmCIF_Schema } from 'mol-io/reader/cif/schema/mmcif';
import { Spacegroup, SpacegroupCell, SymmetryOperator } from 'mol-math/geometry';
import { Vec3, Tensor } from 'mol-math/linear-algebra';
import { Task } from 'mol-task';
import { Tensor, Vec3 } from 'mol-math/linear-algebra';
import { Task, RuntimeContext } from 'mol-task';
import UUID from 'mol-util/uuid';
import Format from '../format';
import Model from '../model';
import { AtomicConformation, AtomicData, AtomicSegments, AtomsSchema, ChainsSchema, ResiduesSchema } from '../properties/atomic';
import { Entities } from '../properties/common';
import { CustomProperties } from '../properties/custom';
import { ModelSymmetry } from '../properties/symmetry';
import { getAtomicKeys } from '../properties/utils/atomic-keys';
import { ElementSymbol } from '../types';
import { createAssemblies } from './mmcif/assembly';
import { getIHMCoarse } from './mmcif/ihm';
import { getAtomicHierarchyAndConformation } from './mmcif/atomic';
import { ComponentBond } from './mmcif/bonds';
import { getIHMCoarse, EmptyIHMCoarse, IHMData } from './mmcif/ihm';
import { getSecondaryStructureMmCif } from './mmcif/secondary-structure';
import { getSequence } from './mmcif/sequence';
import { sortAtomSite } from './mmcif/sort';
import { mmCIF_Database, mmCIF_Schema } from 'mol-io/reader/cif/schema/mmcif';
import { Element } from '../../../structure'
import { CustomProperties } from '../properties/custom';
import mmCIF_Format = Format.mmCIF
import { ComponentBond } from './mmcif/bonds';
type AtomSite = mmCIF_Database['atom_site']
function findModelEnd({ data }: mmCIF_Format, startIndex: number) {
const num = data.atom_site.pdbx_PDB_model_num;
const atomCount = num.rowCount;
if (!num.isDefined) return atomCount;
let endIndex = startIndex + 1;
while (endIndex < atomCount && num.areValuesEqual(startIndex, endIndex)) endIndex++;
return endIndex;
}
function findHierarchyOffsets(atom_site: AtomSite) {
if (atom_site._rowCount === 0) return { residues: [], chains: [] };
const start = 0, end = atom_site._rowCount;
const residues = [start as Element], chains = [start as Element];
const { label_entity_id, label_asym_id, label_seq_id, auth_seq_id, pdbx_PDB_ins_code, label_comp_id } = atom_site;
for (let i = start + 1; i < end; i++) {
const newChain = !label_entity_id.areValuesEqual(i - 1, i) || !label_asym_id.areValuesEqual(i - 1, i);
const newResidue = newChain
|| !label_seq_id.areValuesEqual(i - 1, i)
|| !auth_seq_id.areValuesEqual(i - 1, i)
|| !pdbx_PDB_ins_code.areValuesEqual(i - 1, i)
|| !label_comp_id.areValuesEqual(i - 1, i);
if (newResidue) residues[residues.length] = i as Element;
if (newChain) chains[chains.length] = i as Element;
}
return { residues, chains };
}
function createHierarchyData(atom_site: AtomSite, offsets: { residues: ArrayLike<number>, chains: ArrayLike<number> }): AtomicData {
const atoms = Table.ofColumns(AtomsSchema, {
type_symbol: Column.ofArray({ array: Column.mapToArray(atom_site.type_symbol, ElementSymbol), schema: Column.Schema.Aliased<ElementSymbol>(Column.Schema.str) }),
label_atom_id: atom_site.label_atom_id,
auth_atom_id: atom_site.auth_atom_id,
label_alt_id: atom_site.label_alt_id,
pdbx_formal_charge: atom_site.pdbx_formal_charge
});
const residues = Table.view(atom_site, ResiduesSchema, offsets.residues);
// Optimize the numeric columns
Table.columnToArray(residues, 'label_seq_id', Int32Array);
Table.columnToArray(residues, 'auth_seq_id', Int32Array);
const chains = Table.view(atom_site, ChainsSchema, offsets.chains);
return { atoms, residues, chains };
}
function getConformation(atom_site: AtomSite): AtomicConformation {
return {
id: UUID.create(),
atomId: atom_site.id,
occupancy: atom_site.occupancy,
B_iso_or_equiv: atom_site.B_iso_or_equiv,
x: atom_site.Cartn_x.toArray({ array: Float32Array }),
y: atom_site.Cartn_y.toArray({ array: Float32Array }),
z: atom_site.Cartn_z.toArray({ array: Float32Array }),
}
}
type AtomSite = mmCIF_Database['atom_site']
function getSymmetry(format: mmCIF_Format): ModelSymmetry {
const assemblies = createAssemblies(format);
......@@ -129,14 +67,6 @@ function getNcsOperators(format: mmCIF_Format) {
}
return opers;
}
function isHierarchyDataEqual(a: AtomicData, b: AtomicData) {
// need to cast because of how TS handles type resolution for interfaces https://github.com/Microsoft/TypeScript/issues/15300
return Table.areEqual(a.chains as Table<ChainsSchema>, b.chains as Table<ChainsSchema>)
&& Table.areEqual(a.residues as Table<ResiduesSchema>, b.residues as Table<ResiduesSchema>)
&& Table.areEqual(a.atoms as Table<AtomsSchema>, b.atoms as Table<AtomsSchema>)
}
function getModifiedResidueNameMap(format: mmCIF_Format) {
const data = format.data.pdbx_struct_mod_residue;
const map = new Map<string, string>();
......@@ -168,35 +98,13 @@ function getAsymIdSerialMap(format: mmCIF_Format) {
return map;
}
// TODO split IHM data into models as well, atomistic ihm models have `atom_site.ihm_model_id`,
// how to handle it in a generic way, i.e. when there is no ihm data, use `atom_site.pdbx_PDB_model_num`
// but if there is use `atom_site.ihm_model_id`, `ihm_sphere_obj_site.model_id` and
// `ihm_gaussian_obj_site.model_id` for splitting
// - PDBDEV_00000002 is an example for an IHM structure with multiple models
function createModel(format: mmCIF_Format, atom_site: AtomSite, previous?: Model): Model {
const hierarchyOffsets = findHierarchyOffsets(atom_site);
const hierarchyData = createHierarchyData(atom_site, hierarchyOffsets);
if (previous && isHierarchyDataEqual(previous.atomicHierarchy, hierarchyData)) {
return {
...previous,
atomicConformation: getConformation(atom_site)
};
}
const hierarchySegments: AtomicSegments = {
residueSegments: Segmentation.ofOffsets(hierarchyOffsets.residues, Interval.ofBounds(0, atom_site._rowCount)),
chainSegments: Segmentation.ofOffsets(hierarchyOffsets.chains, Interval.ofBounds(0, atom_site._rowCount)),
function createStandardModel(format: mmCIF_Format, atom_site: AtomSite, entities: Entities, previous?: Model): Model {
const atomic = getAtomicHierarchyAndConformation(format, atom_site, entities, previous);
if (previous && atomic.sameAsPrevious) {
return { ...previous, atomicConformation: atomic.conformation };
}
const entities: Entities = { data: format.data.entity, getEntityIndex: Column.createIndexer(format.data.entity.id) };
const hierarchyKeys = getAtomicKeys(hierarchyData, entities, hierarchySegments);
const atomicHierarchy = { ...hierarchyData, ...hierarchyKeys, ...hierarchySegments };
const coarse = getIHMCoarse(format.data, entities);
const coarse = EmptyIHMCoarse;
const label = format.data.entry.id.valueKind(0) === Column.ValueKind.Present
? format.data.entry.id.value(0)
: format.data._name;
......@@ -211,13 +119,47 @@ function createModel(format: mmCIF_Format, atom_site: AtomSite, previous?: Model
modelNum: atom_site.pdbx_PDB_model_num.value(0),
entities,
symmetry: getSymmetry(format),
atomicHierarchy,
sequence: getSequence(format.data, entities, atomicHierarchy, modifiedResidueNameMap),
atomicConformation: getConformation(atom_site),
sequence: getSequence(format.data, entities, atomic.hierarchy, modifiedResidueNameMap),
atomicHierarchy: atomic.hierarchy,
atomicConformation: atomic.conformation,
coarseHierarchy: coarse.hierarchy,
coarseConformation: coarse.conformation,
properties: {
secondaryStructure: getSecondaryStructureMmCif(format.data, atomicHierarchy),
secondaryStructure: getSecondaryStructureMmCif(format.data, atomic.hierarchy),
modifiedResidueNameMap,
asymIdSerialMap
},
customProperties: new CustomProperties(),
_staticPropertyData: Object.create(null),
_dynamicPropertyData: Object.create(null)
};
}
// TODO split IHM data into models as well, atomistic ihm models have `atom_site.ihm_model_id`,
// how to handle it in a generic way, i.e. when there is no ihm data, use `atom_site.pdbx_PDB_model_num`
// but if there is use `atom_site.ihm_model_id`, `ihm_sphere_obj_site.model_id` and
// `ihm_gaussian_obj_site.model_id` for splitting
// - PDBDEV_00000002 is an example for an IHM structure with multiple models
function createModelIHM(format: mmCIF_Format, data: IHMData): Model {
const atomic = getAtomicHierarchyAndConformation(format, data.atom_site, data.entities);
const coarse = getIHMCoarse(data);
const modifiedResidueNameMap = getModifiedResidueNameMap(format);
const asymIdSerialMap = getAsymIdSerialMap(format)
return {
id: UUID.create(),
label: data.model_name,
sourceData: format,
modelNum: data.model_id,
entities: data.entities,
symmetry: getSymmetry(format),
sequence: getSequence(format.data, data.entities, atomic.hierarchy, modifiedResidueNameMap),
atomicHierarchy: atomic.hierarchy,
atomicConformation: atomic.conformation,
coarseHierarchy: coarse.hierarchy,
coarseConformation: coarse.conformation,
properties: {
secondaryStructure: getSecondaryStructureMmCif(format.data, atomic.hierarchy),
modifiedResidueNameMap,
asymIdSerialMap
},
......@@ -231,28 +173,101 @@ function attachProps(model: Model) {
ComponentBond.attachFromMmCif(model);
}
function findModelEnd(num: Column<number>, startIndex: number) {
const rowCount = num.rowCount;
if (!num.isDefined) return rowCount;
let endIndex = startIndex + 1;
while (endIndex < rowCount && num.areValuesEqual(startIndex, endIndex)) endIndex++;
return endIndex;
}
async function readStandard(ctx: RuntimeContext, format: mmCIF_Format) {
const atomCount = format.data.atom_site._rowCount;
const entities: Entities = { data: format.data.entity, getEntityIndex: Column.createIndexer(format.data.entity.id) };
const models: Model[] = [];
let modelStart = 0;
while (modelStart < atomCount) {
const modelEnd = findModelEnd(format.data.atom_site.pdbx_PDB_model_num, modelStart);
const atom_site = await sortAtomSite(ctx, format.data.atom_site, modelStart, modelEnd);
const model = createStandardModel(format, atom_site, entities, models.length > 0 ? models[models.length - 1] : void 0);
attachProps(model);
models.push(model);
modelStart = modelEnd;
}
return models;
}
function splitTable<T extends Table<any>>(table: T, col: Column<number>) {
const ret = new Map<number, T>()
const rowCount = table._rowCount;
let modelStart = 0;
while (modelStart < rowCount) {
const modelEnd = findModelEnd(col, modelStart);
const id = col.value(modelStart);
const window = Table.window(table, table._schema, modelStart, modelEnd) as T;
ret.set(id, window);
modelStart = modelEnd;
}
return ret;
}
async function readIHM(ctx: RuntimeContext, format: mmCIF_Format) {
const { ihm_model_list } = format.data;
const entities: Entities = { data: format.data.entity, getEntityIndex: Column.createIndexer(format.data.entity.id) };
const atom_sites = splitTable(format.data.atom_site, format.data.atom_site.ihm_model_id);
const sphere_sites = splitTable(format.data.ihm_sphere_obj_site, format.data.ihm_sphere_obj_site.model_id);
const gauss_sites = splitTable(format.data.ihm_gaussian_obj_site, format.data.ihm_gaussian_obj_site.model_id);
const models: Model[] = [];
const { model_id, model_name } = ihm_model_list;
for (let i = 0; i < ihm_model_list._rowCount; i++) {
const id = model_id.value(i);
const data: IHMData = {
model_id: id,
model_name: model_name.value(i),
ihm_model_list,
entities: entities,
atom_site: atom_sites.has(id) ? atom_sites.get(id)! : Table.window(format.data.atom_site, format.data.atom_site._schema, 0, 0),
ihm_sphere_obj_site: sphere_sites.has(id) ? sphere_sites.get(id)! : Table.window(format.data.ihm_sphere_obj_site, format.data.ihm_sphere_obj_site._schema, 0, 0),
ihm_gaussian_obj_site: gauss_sites.has(id) ? gauss_sites.get(id)! : Table.window(format.data.ihm_gaussian_obj_site, format.data.ihm_gaussian_obj_site._schema, 0, 0)
};
const model = createModelIHM(format, data);
attachProps(model);
models.push(createModelIHM(format, data));
}
return models;
// const atomCount = format.data.atom_site._rowCount;
// const isIHM = format.data.ihm_model_list._rowCount > 0;
// if (atomCount === 0) {
// return isIHM
// ? [createModel(format, format.data.atom_site, void 0)]
// : [];
// }
// const models: Model[] = [];
// let modelStart = 0;
// while (modelStart < atomCount) {
// const modelEnd = findModelEnd(format, modelStart);
// const atom_site = await sortAtomSite(ctx, format.data.atom_site, modelStart, modelEnd);
// const model = createModel(format, atom_site, models.length > 0 ? models[models.length - 1] : void 0);
// attachProps(model);
// models.push(model);
// modelStart = modelEnd;
// }
// return models;
}
function buildModels(format: mmCIF_Format): Task<ReadonlyArray<Model>> {
return Task.create('Create mmCIF Model', async ctx => {
const atomCount = format.data.atom_site._rowCount;
const isIHM = format.data.ihm_model_list._rowCount > 0;
if (atomCount === 0) {
return isIHM
? [createModel(format, format.data.atom_site, void 0)]
: [];
}
const models: Model[] = [];
let modelStart = 0;
while (modelStart < atomCount) {
const modelEnd = findModelEnd(format, modelStart);
const atom_site = await sortAtomSite(ctx, format.data.atom_site, modelStart, modelEnd);
const model = createModel(format, atom_site, models.length > 0 ? models[models.length - 1] : void 0);
attachProps(model);
models.push(model);
modelStart = modelEnd;
}
return models;
return isIHM ? await readIHM(ctx, format) : await readStandard(ctx, format);
});
}
......
/**
* Copyright (c) 2017-2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { Column, Table } from 'mol-data/db';
import { Interval, Segmentation } from 'mol-data/int';
import { mmCIF_Database } from 'mol-io/reader/cif/schema/mmcif';
import UUID from 'mol-util/uuid';
import { Element } from '../../../../structure';
import Format from '../../format';
import Model from '../../model';
import { AtomicConformation, AtomicData, AtomicHierarchy, AtomicSegments, AtomsSchema, ChainsSchema, ResiduesSchema } from '../../properties/atomic';
import { getAtomicKeys } from '../../properties/utils/atomic-keys';
import { ElementSymbol } from '../../types';
import { Entities } from '../../properties/common';
import mmCIF_Format = Format.mmCIF
type AtomSite = mmCIF_Database['atom_site']
function findHierarchyOffsets(atom_site: AtomSite) {
if (atom_site._rowCount === 0) return { residues: [], chains: [] };
const start = 0, end = atom_site._rowCount;
const residues = [start as Element], chains = [start as Element];
const { label_entity_id, label_asym_id, label_seq_id, auth_seq_id, pdbx_PDB_ins_code, label_comp_id } = atom_site;
for (let i = start + 1; i < end; i++) {
const newChain = !label_entity_id.areValuesEqual(i - 1, i) || !label_asym_id.areValuesEqual(i - 1, i);
const newResidue = newChain
|| !label_seq_id.areValuesEqual(i - 1, i)
|| !auth_seq_id.areValuesEqual(i - 1, i)
|| !pdbx_PDB_ins_code.areValuesEqual(i - 1, i)
|| !label_comp_id.areValuesEqual(i - 1, i);
if (newResidue) residues[residues.length] = i as Element;
if (newChain) chains[chains.length] = i as Element;
}
return { residues, chains };
}
function createHierarchyData(atom_site: AtomSite, offsets: { residues: ArrayLike<number>, chains: ArrayLike<number> }): AtomicData {
const atoms = Table.ofColumns(AtomsSchema, {
type_symbol: Column.ofArray({ array: Column.mapToArray(atom_site.type_symbol, ElementSymbol), schema: Column.Schema.Aliased<ElementSymbol>(Column.Schema.str) }),
label_atom_id: atom_site.label_atom_id,
auth_atom_id: atom_site.auth_atom_id,
label_alt_id: atom_site.label_alt_id,
pdbx_formal_charge: atom_site.pdbx_formal_charge
});
const residues = Table.view(atom_site, ResiduesSchema, offsets.residues);
// Optimize the numeric columns
Table.columnToArray(residues, 'label_seq_id', Int32Array);
Table.columnToArray(residues, 'auth_seq_id', Int32Array);
const chains = Table.view(atom_site, ChainsSchema, offsets.chains);
return { atoms, residues, chains };
}
function getConformation(atom_site: AtomSite): AtomicConformation {
return {
id: UUID.create(),
atomId: atom_site.id,
occupancy: atom_site.occupancy,
B_iso_or_equiv: atom_site.B_iso_or_equiv,
x: atom_site.Cartn_x.toArray({ array: Float32Array }),
y: atom_site.Cartn_y.toArray({ array: Float32Array }),
z: atom_site.Cartn_z.toArray({ array: Float32Array }),
}
}
function isHierarchyDataEqual(a: AtomicData, b: AtomicData) {
// need to cast because of how TS handles type resolution for interfaces https://github.com/Microsoft/TypeScript/issues/15300
return Table.areEqual(a.chains as Table<ChainsSchema>, b.chains as Table<ChainsSchema>)
&& Table.areEqual(a.residues as Table<ResiduesSchema>, b.residues as Table<ResiduesSchema>)
&& Table.areEqual(a.atoms as Table<AtomsSchema>, b.atoms as Table<AtomsSchema>)
}
export function getAtomicHierarchyAndConformation(format: mmCIF_Format, atom_site: AtomSite, entities: Entities, previous?: Model) {
const hierarchyOffsets = findHierarchyOffsets(atom_site);
const hierarchyData = createHierarchyData(atom_site, hierarchyOffsets);
if (previous && isHierarchyDataEqual(previous.atomicHierarchy, hierarchyData)) {
return {
sameAsPrevious: true,
hierarchy: previous.atomicHierarchy,
conformation: getConformation(atom_site)
};
}
const hierarchySegments: AtomicSegments = {
residueSegments: Segmentation.ofOffsets(hierarchyOffsets.residues, Interval.ofBounds(0, atom_site._rowCount)),
chainSegments: Segmentation.ofOffsets(hierarchyOffsets.chains, Interval.ofBounds(0, atom_site._rowCount)),
}
const hierarchyKeys = getAtomicKeys(hierarchyData, entities, hierarchySegments);
const hierarchy: AtomicHierarchy = { ...hierarchyData, ...hierarchyKeys, ...hierarchySegments };
return {
sameAsPrevious: false,
hierarchy,
conformation: getConformation(atom_site)
};
}
\ No newline at end of file
......@@ -43,6 +43,7 @@ export namespace ComponentBond {
}
export function attachFromMmCif(model: Model): boolean {
if (model.customProperties.has(Descriptor)) return true;
if (model.sourceData.kind !== 'mmCIF') return false;
const { chem_comp_bond } = model.sourceData.data;
if (chem_comp_bond._rowCount === 0) return false;
......
......@@ -14,24 +14,39 @@ import { Segmentation, Interval } from 'mol-data/int';
import { Mat3, Tensor } from 'mol-math/linear-algebra';
import { Element } from '../../../structure'
export function getIHMCoarse(data: mmCIF, entities: Entities): { hierarchy: CoarseHierarchy, conformation: CoarseConformation } {
if (data.ihm_model_list._rowCount === 0) return { hierarchy: CoarseHierarchy.Empty, conformation: void 0 as any };
type AtomSite = mmCIF['atom_site']
type SphereSite = mmCIF['ihm_sphere_obj_site']
type GaussSite = mmCIF['ihm_gaussian_obj_site']
type IHMModels = mmCIF['ihm_model_list']
export interface IHMData {
model_id: number,
model_name: string,
ihm_model_list: IHMModels,
entities: Entities,
atom_site: AtomSite,
ihm_sphere_obj_site: SphereSite,
ihm_gaussian_obj_site: GaussSite
}
export const EmptyIHMCoarse = { hierarchy: CoarseHierarchy.Empty, conformation: void 0 as any }
export function getIHMCoarse(data: IHMData): { hierarchy: CoarseHierarchy, conformation: CoarseConformation } {
const { ihm_model_list, ihm_sphere_obj_site, ihm_gaussian_obj_site } = data;
const modelIndex = Column.createIndexer(ihm_model_list.model_id);
const sphereData = getData(ihm_sphere_obj_site);
const sphereConformation = getSphereConformation(ihm_sphere_obj_site);
const sphereKeys = getCoarseKeys(sphereData, modelIndex, entities);
const sphereKeys = getCoarseKeys(sphereData, modelIndex, data.entities);
const gaussianData = getData(ihm_gaussian_obj_site);
const gaussianConformation = getGaussianConformation(ihm_gaussian_obj_site);
const gaussianKeys = getCoarseKeys(gaussianData, modelIndex, entities);
const gaussianKeys = getCoarseKeys(gaussianData, modelIndex, data.entities);
return {
hierarchy: {
isDefined: true,
models: ihm_model_list,
//models: ihm_model_list,
spheres: { ...sphereData, ...sphereKeys },
gaussians: { ...gaussianData, ...gaussianKeys },
},
......
......@@ -15,8 +15,9 @@ export interface CoarsedElementKeys {
chainKey: ArrayLike<number>,
// assign a key to each element, index to the Model.entities.data table
entityKey: ArrayLike<number>,
// assign a key to each element, index to the CoarseHierarchy.models table
modelKey: ArrayLike<number>,
// // assign a key to each element, index to the CoarseHierarchy.models table
// modelKey: ArrayLike<number>,
/** find index of the residue/feature element where seq_id is included */
findSequenceKey(entityId: string, asym_id: string, seq_id: number): number
......@@ -38,7 +39,7 @@ export type CoarseElements = CoarsedElementKeys & CoarseElementData
export interface CoarseHierarchy {
isDefined: boolean,
models: mmCIF['ihm_model_list'],
//models: mmCIF['ihm_model_list'],
spheres: CoarseElements,
gaussians: CoarseElements
}
......
......@@ -92,5 +92,5 @@ export function getCoarseKeys(data: CoarseElementData, modelIndex: (id: number)
const { findChainKey, findSequenceKey } = createLookUp(entities, chainMaps, seqMaps);
return { chainKey, entityKey, modelKey, findSequenceKey, findChainKey };
return { chainKey, entityKey, /*modelKey,*/ findSequenceKey, findChainKey };
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment