Skip to content
Snippets Groups Projects
Commit 0ddb6bfc authored by Michal Malý's avatar Michal Malý
Browse files

ReDNATCO plugin stage 30

parent ebbdf3c6
No related branches found
No related tags found
No related merge requests found
...@@ -3,25 +3,44 @@ import { StructureElement, StructureProperties } from '../../mol-model/structure ...@@ -3,25 +3,44 @@ import { StructureElement, StructureProperties } from '../../mol-model/structure
import { Location } from '../../mol-model/structure/structure/element/location'; import { Location } from '../../mol-model/structure/structure/element/location';
export namespace Step { export namespace Step {
export type Description = { export interface Description {
name: string;
model: number; model: number;
entryId: string; entryId: string;
chain: string; chain: string;
resNo1: number; resNo1: number;
comp1: string; compId1: string;
altId1?: string; altId1?: string;
insCode1?: string; insCode1: string;
resNo2: number; resNo2: number;
comp2: string; compId2: string;
altId2?: string; altId2?: string;
insCode2?: string; insCode2: string;
}; };
function nameResidue(seqId: number, compId: string, altId?: string, insCode?: string) { export interface ExtendedDescription extends Description{
return `${compId}${altId ? `.${altId}` : ''}_${seqId}${insCode ? `.${insCode}` : '' }`; assignedNtC: string;
closestNtC: string;
};
function nameResidue(seqId: number, compId: string, altId: string|undefined, insCode: string) {
return `${compId}${altId ? `.${altId}` : ''}_${seqId}${insCode !== '' ? `.${insCode}` : '' }`;
}
function nameStep(
entryId: string,
modelNum: number, asymId: string,
seqId1: number, compId1: string, altId1: string|undefined, insCode1: string,
seqId2: number, compId2: string, altId2: string|undefined, insCode2: string,
multipleModels: boolean
) {
const res1 = nameResidue(seqId1, compId1, altId1, insCode1);
const res2 = nameResidue(seqId2, compId2, altId2, insCode2);
return `${entryId}${multipleModels ? `-m${modelNum}` : ''}_${asymId}_${res1}_${res2}`;
} }
function residueDescription(a: string, b: string): { comp: string, altId?: string, resNo: number, insCode?: string }|undefined { function residueDescription(a: string, b: string): { comp: string, altId?: string, resNo: number, insCode: string }|undefined {
const toksA = a.split('.'); const toksA = a.split('.');
const toksB = b.split('.'); const toksB = b.split('.');
...@@ -36,35 +55,37 @@ export namespace Step { ...@@ -36,35 +55,37 @@ export namespace Step {
comp: toksA[0], comp: toksA[0],
altId: toksA.length === 2 ? toksA[1] : void 0, altId: toksA.length === 2 ? toksA[1] : void 0,
resNo, resNo,
insCode: toksB.length === 2 ? toksB[1] : void 0, insCode: toksB.length === 2 ? toksB[1] : '',
}; };
} }
export function describe(loci: StructureElement.Loci) { export function describe(loci: StructureElement.Loci, multipleModels: boolean) {
const es = loci.elements[0]; // Ignore multiple selections const es = loci.elements[0]; // Ignore multiple selections
const loc = Location.create(loci.structure, es.unit); const loc = Location.create(loci.structure, es.unit);
loc.element = es.unit.elements[OrderedSet.getAt(es.indices, 0)]; // We're assuming a non-empty set loc.element = es.unit.elements[OrderedSet.getAt(es.indices, 0)]; // We're assuming a non-empty set
const description: Description = { const description: Description = {
name: '',
model: es.unit.model.modelNum, model: es.unit.model.modelNum,
entryId: loci.structure.model.entryId.toLowerCase(), entryId: loci.structure.model.entryId.toLowerCase(),
chain: StructureProperties.chain.auth_asym_id(loc), chain: StructureProperties.chain.auth_asym_id(loc),
resNo1: StructureProperties.residue.auth_seq_id(loc), resNo1: StructureProperties.residue.auth_seq_id(loc),
comp1: StructureProperties.atom.auth_comp_id(loc), compId1: StructureProperties.atom.auth_comp_id(loc),
altId1: StructureProperties.atom.label_alt_id(loc), altId1: StructureProperties.atom.label_alt_id(loc) === '' ? void 0 : StructureProperties.atom.label_alt_id(loc),
insCode1: StructureProperties.residue.pdbx_PDB_ins_code(loc), insCode1: StructureProperties.residue.pdbx_PDB_ins_code(loc),
resNo2: -1, resNo2: -1,
comp2: '', compId2: '',
altId2: void 0, altId2: void 0,
insCode2: void 0, insCode2: '',
}; };
let found = false; let found = false;
const len = OrderedSet.size(es.indices); const len = OrderedSet.size(es.indices);
const labelResNo = StructureProperties.residue.label_seq_id(loc);
for (let idx = 1; idx < len; idx++) { for (let idx = 1; idx < len; idx++) {
loc.element = es.unit.elements[OrderedSet.getAt(es.indices, idx)]; loc.element = es.unit.elements[OrderedSet.getAt(es.indices, idx)];
if (StructureProperties.residue.auth_seq_id(loc) !== description.resNo1) { if (StructureProperties.residue.label_seq_id(loc) !== labelResNo) {
found = true; found = true;
break; break;
} }
...@@ -74,26 +95,34 @@ export namespace Step { ...@@ -74,26 +95,34 @@ export namespace Step {
return void 0; return void 0;
description.resNo2 = StructureProperties.residue.auth_seq_id(loc); description.resNo2 = StructureProperties.residue.auth_seq_id(loc);
description.comp2 = StructureProperties.atom.auth_comp_id(loc); description.compId2 = StructureProperties.atom.auth_comp_id(loc);
description.altId2 = StructureProperties.atom.label_alt_id(loc); description.altId2 = StructureProperties.atom.label_alt_id(loc) === '' ? void 0 : StructureProperties.atom.label_alt_id(loc);
description.insCode2 = StructureProperties.residue.pdbx_PDB_ins_code(loc); description.insCode2 = StructureProperties.residue.pdbx_PDB_ins_code(loc);
description.name = nameStep(
description.entryId,
description.model, description.chain,
description.resNo1, description.compId1, description.altId1, description.insCode1,
description.resNo2, description.compId2, description.altId2, description.insCode2,
multipleModels
);
return description; return description;
} }
export function fromName(name: string) { export function fromName(name: string) {
const description: Description = { const description: Description = {
name: '',
model: -1, model: -1,
entryId: '', entryId: '',
chain: '', chain: '',
resNo1: -1, resNo1: -1,
comp1: '', compId1: '',
altId1: void 0, altId1: void 0,
insCode1: void 0, insCode1: '',
resNo2: -1, resNo2: -1,
comp2: '', compId2: '',
altId2: void 0, altId2: void 0,
insCode2: void 0, insCode2: '',
}; };
const toks = name.split('_'); const toks = name.split('_');
...@@ -140,13 +169,14 @@ export namespace Step { ...@@ -140,13 +169,14 @@ export namespace Step {
} }
description.resNo1 = res1.resNo; description.resNo1 = res1.resNo;
description.comp1 = res1.comp; description.compId1 = res1.comp;
description.altId1 = res1.altId; description.altId1 = res1.altId;
description.insCode1 = res1.insCode; description.insCode1 = res1.insCode;
description.resNo2 = res2.resNo; description.resNo2 = res2.resNo;
description.comp2 = res2.comp; description.compId2 = res2.comp;
description.altId2 = res2.altId; description.altId2 = res2.altId;
description.insCode2 = res2.insCode; description.insCode2 = res2.insCode;
description.name = name;
return description; return description;
} }
...@@ -170,11 +200,4 @@ export namespace Step { ...@@ -170,11 +200,4 @@ export namespace Step {
return false; return false;
} }
export function name(description: Description, multipleModels: boolean) {
const res1 = nameResidue(description.resNo1, description.comp1, description.altId1, description.insCode1);
const res2 = nameResidue(description.resNo2, description.comp2, description.altId2, description.insCode2);
return `${description.entryId}${multipleModels ? `-m${description.model}` : ''}_${description.chain}_${res1}_${res2}`;
}
} }
...@@ -55,22 +55,6 @@ const NtCSupSel = 'ntc-sup-sel'; ...@@ -55,22 +55,6 @@ const NtCSupSel = 'ntc-sup-sel';
const NtCSupNext = 'ntc-sup-next'; const NtCSupNext = 'ntc-sup-next';
const SphereBoundaryHelper = new BoundaryHelper('98'); const SphereBoundaryHelper = new BoundaryHelper('98');
type StepInfo = {
name: string;
assignedNtC: string;
closestNtC: string;
chain: string;
resNo1: number;
resNo2: number;
compId1: string;
compId2: string;
altId1?: string;
altId2?: string;
insCode1: string;
insCode2: string;
model: number;
}
function superpositionAtomsIndices(loci: StructureElement.Loci) { function superpositionAtomsIndices(loci: StructureElement.Loci) {
const es = loci.elements[0]; const es = loci.elements[0];
const loc = Location.create(loci.structure, es.unit, es.unit.elements[OrderedSet.getAt(es.indices, 0)]); const loc = Location.create(loci.structure, es.unit, es.unit.elements[OrderedSet.getAt(es.indices, 0)]);
...@@ -249,7 +233,7 @@ const ReDNATCOLociSelectionProvider = PluginBehavior.create({ ...@@ -249,7 +233,7 @@ const ReDNATCOLociSelectionProvider = PluginBehavior.create({
export class ReDNATCOMspViewer { export class ReDNATCOMspViewer {
private haveMultipleModels = false; private haveMultipleModels = false;
private steps: StepInfo[] = []; private steps: Step.ExtendedDescription[] = [];
private stepNames: Map<string, number> = new Map(); private stepNames: Map<string, number> = new Map();
private app: ReDNATCOMsp; private app: ReDNATCOMsp;
...@@ -671,12 +655,12 @@ export class ReDNATCOMspViewer { ...@@ -671,12 +655,12 @@ export class ReDNATCOMspViewer {
this.focusOnLoci(focusOn); this.focusOnLoci(focusOn);
} }
gatherStepInfo(): { steps: StepInfo[], stepNames: Map<string, number> }|undefined { gatherStepInfo(): { steps: Step.ExtendedDescription[], stepNames: Map<string, number> }|undefined {
const obj = this.plugin.state.data.cells.get(IDs.ID('model', '', BaseRef))?.obj; const obj = this.plugin.state.data.cells.get(IDs.ID('model', '', BaseRef))?.obj;
if (!obj) if (!obj)
return void 0; return void 0;
const model = (obj as StateObject<Model>); const struModel = (obj as StateObject<Model>);
const sourceData = model.data.sourceData; const sourceData = struModel.data.sourceData;
if (!MmcifFormat.is(sourceData)) if (!MmcifFormat.is(sourceData))
return void 0; return void 0;
...@@ -709,7 +693,7 @@ export class ReDNATCOMspViewer { ...@@ -709,7 +693,7 @@ export class ReDNATCOMspViewer {
const len = _ids.length; const len = _ids.length;
const stepNames = new Map<string, number>(); const stepNames = new Map<string, number>();
const steps = new Array<StepInfo>(len); const steps = new Array<Step.ExtendedDescription>(len);
for (let idx = 0; idx < len; idx++) { for (let idx = 0; idx < len; idx++) {
const id = _ids[idx]; const id = _ids[idx];
...@@ -732,6 +716,8 @@ export class ReDNATCOMspViewer { ...@@ -732,6 +716,8 @@ export class ReDNATCOMspViewer {
// We're assuming that steps are ID'd with a contigious, monotonic sequence starting from 1 // We're assuming that steps are ID'd with a contigious, monotonic sequence starting from 1
steps[id - 1] = { steps[id - 1] = {
name, name,
model,
entryId: struModel.data.entryId,
assignedNtC, assignedNtC,
closestNtC, closestNtC,
chain, chain,
...@@ -743,7 +729,6 @@ export class ReDNATCOMspViewer { ...@@ -743,7 +729,6 @@ export class ReDNATCOMspViewer {
altId2, altId2,
insCode1, insCode1,
insCode2, insCode2,
model
}; };
stepNames.set(name, id - 1); stepNames.set(name, id - 1);
break; break;
...@@ -941,11 +926,9 @@ export class ReDNATCOMspViewer { ...@@ -941,11 +926,9 @@ export class ReDNATCOMspViewer {
const loci = Loci.normalize(selected.loci, 'two-residues'); const loci = Loci.normalize(selected.loci, 'two-residues');
if (loci.kind === 'element-loci') { if (loci.kind === 'element-loci') {
const stepDesc = Step.describe(loci); const stepDesc = Step.describe(loci, this.haveMultipleModels);
if (stepDesc) { if (stepDesc && this.stepNames.has(stepDesc.name))
const stepName = Step.name(stepDesc, this.haveMultipleModels); this.app.viewerStepSelected(stepDesc.name);
this.app.viewerStepSelected(stepName);
}
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment