|
@@ -120,8 +120,6 @@ export async function loadWithUNITMPMembraneRepresentation(plugin: PluginUIConte
|
|
|
|
|
|
membrane = createMembraneOrientation(pdbtmDescriptor);
|
|
|
|
|
|
- console.log('DEBUG-02', membrane.planePoint2);
|
|
|
-
|
|
|
localStorage.setItem(MEMBRANE_STORAGE_KEY, JSON.stringify(membrane));
|
|
|
|
|
|
// load structure
|
|
@@ -148,6 +146,7 @@ type PDBTMChain = {
|
|
|
}[]
|
|
|
};
|
|
|
type PDBTMRegion = { site: string, auth_ids: number[], color: number[] };
|
|
|
+type PDBTMVec3 = { x: number, y: number, z: number };
|
|
|
type PDBTMTransformationMatrixRow = { x: number, y: number, z: number, t: number };
|
|
|
type PDBTMTransformationMatrix = {
|
|
|
rowx: PDBTMTransformationMatrixRow,
|
|
@@ -155,11 +154,12 @@ type PDBTMTransformationMatrix = {
|
|
|
rowz: PDBTMTransformationMatrixRow
|
|
|
};
|
|
|
type PDBTMDescriptor = {
|
|
|
+ pdb_id: string,
|
|
|
chains: PDBTMChain[],
|
|
|
site: { site_id: number, label: string }[],
|
|
|
additional_entry_annotations: {
|
|
|
membrane: {
|
|
|
- normal: { x: number, y: number, z: number },
|
|
|
+ normal: PDBTMVec3,
|
|
|
transformation_matrix: PDBTMTransformationMatrix,
|
|
|
radius: number
|
|
|
}
|
|
@@ -167,11 +167,8 @@ type PDBTMDescriptor = {
|
|
|
};
|
|
|
|
|
|
function createMembraneOrientation(pdbtmDescriptor: PDBTMDescriptor): MembraneOrientation {
|
|
|
- const membraneNormal: Vec3 = Vec3.fromObj(
|
|
|
- pdbtmDescriptor.additional_entry_annotations.membrane.normal
|
|
|
- );
|
|
|
- membraneNormal[0] = membraneNormal[2];
|
|
|
- membraneNormal[2] = 0;
|
|
|
+ const normal = pdbtmDescriptor.additional_entry_annotations.membrane.normal;
|
|
|
+ const membraneNormal: Vec3 = Vec3.fromObj(normal);
|
|
|
|
|
|
const membraneOrientation: MembraneOrientation = {
|
|
|
planePoint1: Vec3.fromArray(Vec3.zero(), membraneNormal, 0),
|
|
@@ -184,7 +181,8 @@ function createMembraneOrientation(pdbtmDescriptor: PDBTMDescriptor): MembraneOr
|
|
|
// (NOTE: the TMDET extension calculates and sets it during applying preset)
|
|
|
radius: pdbtmDescriptor.additional_entry_annotations.membrane.radius
|
|
|
};
|
|
|
- membraneOrientation.planePoint2[0] *= -1;
|
|
|
+ membraneOrientation.planePoint2[2] *= -1;
|
|
|
+
|
|
|
return membraneOrientation;
|
|
|
}
|
|
|
|
|
@@ -195,34 +193,34 @@ async function createStructureRepresentation(plugin: PluginUIContext, pdbtmDescr
|
|
|
|
|
|
await buildStructureRepresentation(plugin, components);
|
|
|
|
|
|
- // TODO: colors of not curated sites
|
|
|
- const siteColors = [
|
|
|
- [255,100,100], // Side1
|
|
|
- [100,100,255], // Side2
|
|
|
- [255,255,0], // TM alpha
|
|
|
- [255,255,0], // TM beta
|
|
|
- [255,127,0], // TM re-entrant loop
|
|
|
- [0,255, 0], // Interfacial Helix
|
|
|
- [196,196,196], // Unknow localization
|
|
|
- [0,255, 0], // Membrane Inside
|
|
|
- ];
|
|
|
- const siteDefinitions = pdbtmDescriptor.sites.map(
|
|
|
- (siteDefinition: any) => siteDefinition.label
|
|
|
- );
|
|
|
- pdbtmDescriptor.chains.forEach((chain: any) => {
|
|
|
-
|
|
|
- for (let residueItem of chain.residues) {
|
|
|
- const siteIndex = residueItem.site_data[0].site_id_ref - 1;
|
|
|
- const residue: PDBTMRegion = {
|
|
|
- "auth_ids": [ Number(residueItem.pdb_res_label) ],
|
|
|
- "color": siteColors[siteIndex],
|
|
|
- "site": siteDefinitions[siteIndex]
|
|
|
- };
|
|
|
- const regionUpdates = plugin.build();
|
|
|
- createRegionRepresentation(plugin, chain.chain_label, residue, regionUpdates.to(structure));
|
|
|
- regionUpdates.commit();
|
|
|
- }
|
|
|
- });
|
|
|
+ // // TODO: colors of not curated sites
|
|
|
+ // const siteColors = [
|
|
|
+ // [255,100,100], // Side1
|
|
|
+ // [100,100,255], // Side2
|
|
|
+ // [255,255,0], // TM alpha
|
|
|
+ // [255,255,0], // TM beta
|
|
|
+ // [255,127,0], // TM re-entrant loop
|
|
|
+ // [0,255, 0], // Interfacial Helix
|
|
|
+ // [196,196,196], // Unknow localization
|
|
|
+ // [0,255, 0], // Membrane Inside
|
|
|
+ // ];
|
|
|
+ // const siteDefinitions = pdbtmDescriptor.sites.map(
|
|
|
+ // (siteDefinition: any) => siteDefinition.label
|
|
|
+ // );
|
|
|
+ // pdbtmDescriptor.chains.forEach((chain: any) => {
|
|
|
+
|
|
|
+ // for (let residueItem of chain.residues) {
|
|
|
+ // const siteIndex = residueItem.site_data[0].site_id_ref - 1;
|
|
|
+ // const residue: PDBTMRegion = {
|
|
|
+ // "auth_ids": [ Number(residueItem.pdb_res_label) ],
|
|
|
+ // "color": siteColors[siteIndex],
|
|
|
+ // "site": siteDefinitions[siteIndex]
|
|
|
+ // };
|
|
|
+ // const regionUpdates = plugin.build();
|
|
|
+ // createRegionRepresentation(plugin, chain.chain_label, residue, regionUpdates.to(structure));
|
|
|
+ // regionUpdates.commit();
|
|
|
+ // }
|
|
|
+ // });
|
|
|
}
|
|
|
|
|
|
async function createStructureComponents(plugin: PluginUIContext, structure: StateObjectCell<PMS, StateTransform<StateTransformer<StateObject<any, StateObject.Type<any>>, StateObject<any, StateObject.Type<any>>, any>>>) {
|
|
@@ -234,7 +232,6 @@ async function createStructureComponents(plugin: PluginUIContext, structure: Sta
|
|
|
}
|
|
|
|
|
|
function createRegionRepresentation(plugin: PluginUIContext, chain: string, residue: PDBTMRegion, update: StateBuilder.To<any, any>) {
|
|
|
- console.log('RESI', residue);
|
|
|
const regionLabel: string = `${chain}: ${residue.auth_ids[0]} | ${residue.site}`;
|
|
|
const color: Color = Color.fromArray(residue.color, 0);
|
|
|
const query: Expression = getAtomGroupExpression(chain, residue.auth_ids);
|
|
@@ -261,19 +258,57 @@ async function buildStructureRepresentation(plugin: PluginUIContext, components:
|
|
|
await update.commit();
|
|
|
}
|
|
|
|
|
|
-async function loadStructure(ctx: PluginUIContext, params: any, pdbtmDescriptor: any): Promise<void> {
|
|
|
+async function loadStructure(ctx: PluginUIContext, params: any, pdbtmDescriptor: PDBTMDescriptor): Promise<void> {
|
|
|
const builders = ctx.builders;
|
|
|
const data = await builders.data.download({
|
|
|
url: params.structureUrl,
|
|
|
- label: `UniTMP: ${pdbtmDescriptor['pdb-id']}`,
|
|
|
+ label: `UniTMP: ${pdbtmDescriptor.pdb_id}`,
|
|
|
isBinary: false
|
|
|
}); // , { state: { isGhost: true } });
|
|
|
const trajectory = await builders.structure.parseTrajectory(data, 'mmcif');
|
|
|
+
|
|
|
+ if (trajectory.data != null) {
|
|
|
+ let new_x = [];
|
|
|
+ let new_y = [];
|
|
|
+ let new_z = [];
|
|
|
+ let atomicConformationX = trajectory.data.representative.atomicConformation.x;
|
|
|
+ let atomicConformationY = trajectory.data.representative.atomicConformation.y;
|
|
|
+ let atomicConformationZ = trajectory.data.representative.atomicConformation.z;
|
|
|
+ let tmatrix = pdbtmDescriptor.additional_entry_annotations.membrane.transformation_matrix;
|
|
|
+
|
|
|
+ for (let i = 0; i < atomicConformationX.length; i++) {
|
|
|
+ let coords = {
|
|
|
+ x: atomicConformationX[i],
|
|
|
+ y: atomicConformationY[i],
|
|
|
+ z: atomicConformationZ[i]
|
|
|
+ };
|
|
|
+ coords = applyTransformationMatrix(coords, tmatrix);
|
|
|
+ new_x.push(coords.x);
|
|
|
+ new_y.push(coords.y);
|
|
|
+ new_z.push(coords.z);
|
|
|
+ }
|
|
|
+ trajectory.data.representative.atomicConformation.x = new_x;
|
|
|
+ trajectory.data.representative.atomicConformation.y = new_y;
|
|
|
+ trajectory.data.representative.atomicConformation.z = new_z;
|
|
|
+ }
|
|
|
+
|
|
|
// create membrane representation
|
|
|
await builders.structure.hierarchy.applyPreset(
|
|
|
trajectory, 'default', { representationPreset: 'preset-membrane-orientation' as any });
|
|
|
}
|
|
|
|
|
|
+function applyTransformationMatrix(coords: PDBTMVec3, tmatrix: PDBTMTransformationMatrix): PDBTMVec3 {
|
|
|
+ return {
|
|
|
+ x: tmatrix.rowx.t + vectorMultiply(coords, tmatrix.rowx),
|
|
|
+ y: tmatrix.rowy.t + vectorMultiply(coords, tmatrix.rowy),
|
|
|
+ z: tmatrix.rowz.t + vectorMultiply(coords, tmatrix.rowz)
|
|
|
+ };
|
|
|
+}
|
|
|
+
|
|
|
+function vectorMultiply(v1: PDBTMVec3, v2: PDBTMVec3): number {
|
|
|
+ return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z
|
|
|
+}
|
|
|
+
|
|
|
function getAtomGroupExpression(chainId: string, auth_array: number[]): Expression {
|
|
|
const query: Expression =
|
|
|
MS.struct.generator.atomGroups({
|