Skip to content
Snippets Groups Projects
Commit 7266aab4 authored by DESKTOP-O6LIMN9\ludov's avatar DESKTOP-O6LIMN9\ludov
Browse files

support for latest cellpack model.

Example is ExosomeModel.json present in the repo
parent 54c2ef7a
No related branches found
No related tags found
No related merge requests found
......@@ -191,9 +191,9 @@ function GetMiniFrame(points: Vec3[], normals: Vec3[]) {
const rpTmpVec1 = Vec3()
export function getMatFromResamplePoints(points: NumberArray) {
const segmentLength = 3.4
const new_points = ResampleControlPoints(points, 3.4)
export function getMatFromResamplePoints(points: NumberArray, segmentLength: number) {
//const segmentLength = 3.4
const new_points = ResampleControlPoints(points, segmentLength)
const npoints = new_points.length
const new_normal = GetSmoothNormals(new_points)
const frames = GetMiniFrame(new_points, new_normal)
......
......@@ -27,8 +27,7 @@ export interface Cell {
export interface Recipe {
setupfile: string
/** First entry is name, secound is path: [name: string, path: string][] */
paths: [string, string][]
paths: [string, string][] // [name: string, path: string][]
version: string
name: string
}
......@@ -42,21 +41,37 @@ export interface Packing {
ingredients: { [key: string]: Ingredient }
}
export interface Ingredient {
source: IngredientSource
results: [Vec3, Quat][]
name: string
positions?: [Vec3[]] // why wrapped in an extra array?
radii?: [number[]] // why wrapped in an extra array?
export interface Positions
{
coords?: Vec3[];
}
export interface Radii
{
radii?: number[];
}
export interface Ingredient {
source: IngredientSource;
results: [Vec3, Quat][];
name: string;
positions?: [Positions];//Vec3[]];
radii?: [Radii];//number[]];
/** Number of `curveX` properties in the object where `X` is a 0-indexed number */
nbCurve?: number
nbCurve?: number;
/** Curve properties are Vec3[] but that is not expressable in TypeScript */
[curveX: string]: unknown
[curveX: string]: unknown;
principalAxis?: Vec3; /** the orientation in the membrane */
offset?: Vec3; /**offset along membrane */
}
export interface IngredientSource {
pdb: string
transform: { center: boolean, translate?: Vec3 }
biomt?: boolean
pdb: string;
bu?:string; /** biological unit e.g AU,BU1,etc.. */
selection?:string; /** NGL selection or :A or :B etc.. */
model?:string; /** model number e.g 0,1,2... */
transform: {
center: boolean;
translate?: Vec3;
};
biomt?: boolean;
}
\ No newline at end of file
......@@ -8,8 +8,9 @@ import { StateAction, StateBuilder, StateTransformer, State } from '../../../../
import { PluginContext } from '../../../../mol-plugin/context';
import { PluginStateObject as PSO } from '../../../../mol-plugin-state/objects';
import { ParamDefinition as PD } from '../../../../mol-util/param-definition';
import { Ingredient, CellPacking } from './data';
import { Ingredient,IngredientSource, CellPacking } from './data';
import { getFromPdb, getFromCellPackDB } from './util';
import { computeStructureBoundary } from '../../../../mol-model/structure/structure/util/boundary';
import { Model, Structure, StructureSymmetry, StructureSelection, QueryContext, Unit } from '../../../../mol-model/structure';
import { trajectoryFromMmCIF, MmcifFormat } from '../../../../mol-model-formats/structure/mmcif';
import { trajectoryFromPDB } from '../../../../mol-model-formats/structure/pdb';
......@@ -34,27 +35,39 @@ function getCellPackModelUrl(fileName: string, baseUrl: string) {
return `${baseUrl}/results/${fileName}`
}
async function getModel(id: string, baseUrl: string) {
async function getModel(id: string, source:IngredientSource, baseUrl: string) {
let model: Model;
const mid = source.model? parseInt(source.model) : 0;
if (id.match(/^[1-9][a-zA-Z0-9]{3,3}$/i)) {
// return
const cif = await getFromPdb(id)
model = (await trajectoryFromMmCIF(cif).run())[0]
model = (await trajectoryFromMmCIF(cif).run())[mid]
} else {
const pdb = await getFromCellPackDB(id, baseUrl)
model = (await trajectoryFromPDB(pdb).run())[0]
model = (await trajectoryFromPDB(pdb).run())[mid]
}
return model
}
async function getStructure(model: Model, props: { assembly?: string } = {}) {
async function getStructure(model: Model, source:IngredientSource, props: { assembly?: string } = {}) {
let structure = Structure.ofModel(model)
const { assembly } = props
if (assembly) {
structure = await StructureSymmetry.buildAssembly(structure, assembly).run()
}
if (source.selection){
const asymIds:string[] = source.selection.split(":")
const query = MS.struct.modifier.union([
MS.struct.generator.atomGroups({
'chain-test': MS.core.set.has([MS.set(...asymIds), MS.ammp('label_asym_id')])
})
])
const compiled = compile<StructureSelection>(query)
const result = compiled(new QueryContext(structure))
structure = StructureSelection.unionStructure(result)
}
else {
const query = MS.struct.modifier.union([
MS.struct.generator.atomGroups({
'entity-test': MS.core.rel.eq([MS.ammp('entityType'), 'polymer'])
......@@ -63,11 +76,11 @@ async function getStructure(model: Model, props: { assembly?: string } = {}) {
const compiled = compile<StructureSelection>(query)
const result = compiled(new QueryContext(structure))
structure = StructureSelection.unionStructure(result)
}
return structure
}
function getTransform(trans: Vec3, rot: Quat) {
function getTransformLegacy(trans: Vec3, rot: Quat) {
const q: Quat = Quat.create(-rot[3], rot[0], rot[1], rot[2])
const m: Mat4 = Mat4.fromQuat(Mat4.zero(), q)
Mat4.transpose(m, m)
......@@ -76,13 +89,25 @@ function getTransform(trans: Vec3, rot: Quat) {
return m
}
function getResultTransforms(results: Ingredient['results']) {
return results.map((r: Ingredient['results'][0]) => getTransform(r[0], r[1]))
function getTransform(trans: Vec3, rot: Quat) {
const q: Quat = Quat.create(rot[0], rot[1], rot[2], rot[3])
const m: Mat4 = Mat4.fromQuat(Mat4.zero(), q)
const p: Vec3 = Vec3.create(trans[0],trans[1],trans[2])
Mat4.setTranslation(m, p)
return m
}
function getResultTransforms(results: Ingredient['results'],legacy:boolean) {
if (legacy) return results.map((r: Ingredient['results'][0]) => getTransformLegacy(r[0], r[1]))
else return results.map((r: Ingredient['results'][0]) => getTransform(r[0], r[1]))
}
function getCurveTransforms(ingredient: Ingredient) {
const n = ingredient.nbCurve || 0
const instances: Mat4[] = []
const segmentLength = (ingredient.radii)? ((ingredient.radii[0].radii)?ingredient.radii[0].radii[0]*2.0:3.4):3.4;
console.log(ingredient.radii);
console.log(segmentLength);
for (let i = 0; i < n; ++i) {
const cname = `curve${i}`
......@@ -97,7 +122,7 @@ function getCurveTransforms(ingredient: Ingredient) {
}
const points = new Float32Array(_points.length * 3)
for (let i = 0, il = _points.length; i < il; ++i) Vec3.toArray(_points[i], points, i * 3)
const newInstances = getMatFromResamplePoints(points)
const newInstances = getMatFromResamplePoints(points,segmentLength)
instances.push(...newInstances)
}
......@@ -212,7 +237,7 @@ function getCifCurve(name: string, transforms: Mat4[], model: Model) {
};
}
async function getCurve(name: string, transforms: Mat4[], model: Model) {
async function getCurve(name: string, ingredient:Ingredient, transforms: Mat4[], model: Model) {
const cif = getCifCurve(name, transforms, model)
const curveModelTask = Task.create('Curve Model', async ctx => {
......@@ -222,7 +247,7 @@ async function getCurve(name: string, transforms: Mat4[], model: Model) {
})
const curveModel = await curveModelTask.run()
return getStructure(curveModel)
return getStructure(curveModel,ingredient.source)
}
async function getIngredientStructure(ingredient: Ingredient, baseUrl: string) {
......@@ -237,14 +262,53 @@ async function getIngredientStructure(ingredient: Ingredient, baseUrl: string) {
if (source.pdb === 'None') return
const model = await getModel(source.pdb || name, baseUrl)
const model = await getModel(source.pdb || name,source, baseUrl)
if (!model) return
if (nbCurve) {
return getCurve(name, getCurveTransforms(ingredient), model)
return getCurve(name,ingredient, getCurveTransforms(ingredient), model)
} else {
const structure = await getStructure(model, { assembly: source.biomt ? '1' : undefined })
return getAssembly(getResultTransforms(results), structure)
let bu:string|undefined = source.bu ? source.bu : undefined;
if (bu){
if (bu=="AU") {bu = undefined;}
else {
bu=bu.slice(2)
}
}
let structure = await getStructure(model,source, { assembly: bu })
//transform with offset and pcp
let legacy:boolean = true
if (ingredient.offset || ingredient.principalAxis)
//center the structure
{
legacy=false
const boundary = computeStructureBoundary(structure)
let modelCenter:Vec3 = Vec3.zero()
Vec3.scale(modelCenter,boundary.sphere.center,-1.0);//Model.getCenter(structure.models[0])
const m1: Mat4 = Mat4.identity()
Mat4.setTranslation(m1, modelCenter)
structure = Structure.transform(structure,m1)
if (ingredient.offset)
{
if (!Vec3.exactEquals(ingredient.offset,Vec3.zero()))
{
const m: Mat4 = Mat4.identity();
Mat4.setTranslation(m, ingredient.offset)
structure = Structure.transform(structure,m);
}
}
if (ingredient.principalAxis)
{
if (!Vec3.exactEquals(ingredient.principalAxis,Vec3.create(0, 0, 1)))
{
const q: Quat = Quat.identity();
Quat.rotationTo(q,ingredient.principalAxis,Vec3.create(0, 0, 1))
const m: Mat4 = Mat4.fromQuat(Mat4.zero(), q)
structure = Structure.transform(structure,m);
}
}
}
return getAssembly(getResultTransforms(results,legacy), structure)
}
}
......@@ -373,6 +437,7 @@ const LoadCellPackModelParams = {
['HIV-1_0.1.6-8_mixed_radii_pdb.cpr', 'HIV-1_0.1.6-8_mixed_radii_pdb'],
['hiv_lipids.bcif', 'hiv_lipids'],
['influenza_model1.json', 'influenza_model1'],
['ExosomeModel.json', 'ExosomeModel'],
['Mycoplasma1.5_mixed_pdb_fixed.cpr', 'Mycoplasma1.5_mixed_pdb_fixed'],
] as const),
'file': PD.File({ accept: 'id' }),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment