UNPKG

molstar

Version:

A comprehensive macromolecular library.

153 lines (152 loc) 6.74 kB
/** * Copyright (c) 2024 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author David Sehnal <david.sehnal@gmail.com> * @author Alexander Rose <alexander.rose@weirdbyte.de> * @author Ludovic Autin <ludovic.autin@gmail.com> */ import { Coordinates, Time } from '../../mol-model/structure/coordinates'; import { lammpsUnitStyles } from '../../mol-io/reader/lammps/schema'; import { Model } from '../../mol-model/structure/model'; import { Task } from '../../mol-task'; import { Column, Table } from '../../mol-data/db'; import { BasicSchema, createBasic } from './basic/schema'; import { ComponentBuilder } from './common/component'; import { EntityBuilder } from './common/entity'; import { createModels } from './basic/parser'; export function coordinatesFromLammpsTrajectory(file, unitsStyle = 'real') { return Task.create('Parse Lammps Trajectory', async (ctx) => { await ctx.update('Converting to coordinates'); const scale = lammpsUnitStyles[unitsStyle].scale; const deltaTime = Time(file.deltaTime, 'step'); const offsetTime = Time(file.timeOffset, deltaTime.unit); const offset_pos = { x: 0.0, y: 0.0, z: 0.0 }; const offset_scale = { x: 1.0, y: 1.0, z: 1.0 }; const atomsMode = file.frames[0].atomMode; const isScaled = atomsMode.includes('s'); const frames = []; for (let i = 0, il = file.frames.length; i < il; ++i) { const box = file.bounds[i]; if (isScaled) { offset_scale.x = box.length[0]; offset_scale.y = box.length[1]; offset_scale.z = box.length[2]; offset_pos.x = box.lower[0]; offset_pos.y = box.lower[1]; offset_pos.z = box.lower[2]; } const count = file.frames[i].count; const cx = new Float32Array(count); const cy = new Float32Array(count); const cz = new Float32Array(count); let offset = 0; for (let j = 0; j < count; j++) { cx[offset] = (file.frames[i].x.value(j) * offset_scale.x + offset_pos.x) * scale; cy[offset] = (file.frames[i].y.value(j) * offset_scale.y + offset_pos.y) * scale; cz[offset] = (file.frames[i].z.value(j) * offset_scale.z + offset_pos.z) * scale; offset++; } frames.push({ elementCount: file.frames[i].count, x: cx, y: cy, z: cz, xyzOrdering: { isIdentity: true }, time: Time(offsetTime.value + deltaTime.value * i, deltaTime.unit) }); } return Coordinates.create(frames, deltaTime, offsetTime); }); } async function getModels(mol, ctx, unitsStyle = 'real') { const atoms = mol.frames[0]; const count = atoms.count; const atomsMode = atoms.atomMode; const box = mol.bounds[0]; const offset_pos = { x: 0.0, y: 0.0, z: 0.0 }; const offset_scale = { x: 1.0, y: 1.0, z: 1.0 }; const scale = lammpsUnitStyles[unitsStyle].scale; // if caracter s in atomsMode, we need to scale the coordinates if (atomsMode.includes('s')) { offset_scale.x = box.length[0]; offset_scale.y = box.length[1]; offset_scale.z = box.length[2]; offset_pos.x = box.lower[0]; offset_pos.y = box.lower[1]; offset_pos.z = box.lower[2]; } const type_symbols = new Array(count); const id = new Int32Array(count); const cx = new Float32Array(count); const cy = new Float32Array(count); const cz = new Float32Array(count); const model_num = new Int32Array(count); let offset = 0; for (let j = 0; j < count; j++) { type_symbols[offset] = atoms.atomType.value(j).toString(); cx[offset] = (atoms.x.value(j) * offset_scale.x + offset_pos.x) * scale; cy[offset] = (atoms.y.value(j) * offset_scale.y + offset_pos.y) * scale; cz[offset] = (atoms.z.value(j) * offset_scale.z + offset_pos.z) * scale; id[offset] = atoms.atomId.value(j); model_num[offset] = 0; offset++; } const MOL = Column.ofConst('MOL', count, Column.Schema.str); const asym_id = Column.ofLambda({ value: (row) => atoms.moleculeId.value(row).toString(), rowCount: count, schema: Column.Schema.str, }); const seq_id = Column.ofConst(1, count, Column.Schema.int); const type_symbol = Column.ofStringArray(type_symbols); const atom_site = Table.ofPartialColumns(BasicSchema.atom_site, { auth_asym_id: asym_id, auth_atom_id: type_symbol, auth_comp_id: MOL, auth_seq_id: seq_id, Cartn_x: Column.ofFloatArray(cx), Cartn_y: Column.ofFloatArray(cy), Cartn_z: Column.ofFloatArray(cz), id: Column.ofIntArray(id), label_asym_id: asym_id, label_atom_id: type_symbol, label_comp_id: MOL, label_seq_id: seq_id, label_entity_id: Column.ofConst('1', count, Column.Schema.str), occupancy: Column.ofConst(1, count, Column.Schema.float), type_symbol, pdbx_PDB_model_num: Column.ofIntArray(model_num), }, count); const entityBuilder = new EntityBuilder(); entityBuilder.setNames([['MOL', 'Unknown Entity']]); entityBuilder.getEntityId('MOL', 0 /* MoleculeType.Unknown */, 'A'); const componentBuilder = new ComponentBuilder(seq_id, type_symbol); componentBuilder.setNames([['MOL', 'Unknown Molecule']]); componentBuilder.add('MOL', 0); const basic = createBasic({ entity: entityBuilder.getEntityTable(), chem_comp: componentBuilder.getChemCompTable(), atom_site }); const _models = await createModels(basic, LammpsTrajectoryFormat.create(mol), ctx); const first = _models.representative; const coordinates = await coordinatesFromLammpsTrajectory(mol, unitsStyle).runInContext(ctx); return Model.trajectoryFromModelAndCoordinates(first, coordinates); } export { LammpsTrajectoryFormat }; var LammpsTrajectoryFormat; (function (LammpsTrajectoryFormat) { function is(x) { return (x === null || x === void 0 ? void 0 : x.kind) === 'lammpstrj'; } LammpsTrajectoryFormat.is = is; function create(mol) { return { kind: 'lammpstrj', name: 'lammpstrj', data: mol }; } LammpsTrajectoryFormat.create = create; })(LammpsTrajectoryFormat || (LammpsTrajectoryFormat = {})); export function trajectoryFromLammpsTrajectory(mol, unitsStyle) { if (unitsStyle === void 0) unitsStyle = 'real'; return Task.create('Parse Lammps Traj Data', ctx => getModels(mol, ctx, unitsStyle)); }