Skip to content

Commit

Permalink
Pull request #648: Users can use iCn3D to detect Ig domains for any s…
Browse files Browse the repository at this point in the history
…tructures and assign IgStrand reference numbers for each residue. The instruction is at https://www.ncbi.nlm.nih.gov/Structure/icn3d/icn3d.html#igrefnum.

Merge in STRUC/icn3d from release3330 to master

* commit 'b8fa42fa64f05d919bf021797c4d32035d871ddc':
  Users can use iCn3D to detect Ig domains for any structures and assign IgStrand reference numbers for each residue. The instruction is at https://www.ncbi.nlm.nih.gov/Structure/icn3d/icn3d.html#igrefnum.
  • Loading branch information
jiywang3 committed Jun 12, 2024
2 parents 4713b3c + b8fa42f commit e22e2c8
Show file tree
Hide file tree
Showing 41 changed files with 14,353 additions and 169 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
## Change Log
[icn3d-3.33.0](https://www.ncbi.nlm.nih.gov/Structure/icn3d/icn3d-3.33.0.zip) was release on June 12, 2024. Users can use iCn3D to detect Ig domains for any structures and assign IgStrand reference numbers for each residue. The instruction is at https://www.ncbi.nlm.nih.gov/Structure/icn3d/icn3d.html#igrefnum.

[icn3d-3.32.0](https://www.ncbi.nlm.nih.gov/Structure/icn3d/icn3d-3.32.0.zip) was release on May 28, 2024. Allowed to load multiple mmCIF text files, which could contain multiple structures separated by "ENDMDL\n".

[icn3d-3.31.4](https://www.ncbi.nlm.nih.gov/Structure/icn3d/icn3d-3.31.4.zip) was release on May 11, 2024. Release Ig templates for assigning reference numbers.
Expand Down
111 changes: 88 additions & 23 deletions build/icn3d.js
Original file line number Diff line number Diff line change
Expand Up @@ -11492,6 +11492,13 @@ var icn3d = (function (exports) {
ic.drawCls.draw();
});

me.myEventCls.onIds("#" + me.pre + "mn6_addlabelIg", "click", function(e) { let ic = me.icn3d; //e.preventDefault();
ic.residueLabelsCls.addIgLabels(ic.hAtoms);
ic.selectionCls.saveSelectionIfSelected();
thisClass.setLogCmd('add ig labels', true);
ic.drawCls.draw();
});

me.myEventCls.onIds("#" + me.pre + "mn6_addlabelChains", "click", function(e) { let ic = me.icn3d; //e.preventDefault();
ic.analysisCls.addChainLabels(ic.hAtoms);
ic.selectionCls.saveSelectionIfSelected();
Expand Down Expand Up @@ -12716,15 +12723,12 @@ var icn3d = (function (exports) {
html += this.getLink('mn1_exportSecondary', 'Secondary Structure', undefined, 2);
}

//!!!
/*
html += this.getMenuText('m1_exportrefnum', 'Reference Numbers', undefined, undefined, 2);
html += "<ul>";
html += this.getLink('mn1_exportIgstrand', 'Ig Strand', undefined, 3);
html += this.getLink('mn1_exportKabat', 'Kabat', undefined, 3);
html += this.getLink('mn1_exportImgt', 'IMGT', undefined, 3);
html += "</ul>";
*/

html += "<li><br/></li>";

Expand Down Expand Up @@ -13567,9 +13571,8 @@ var icn3d = (function (exports) {
html += this.getRadio('mn4_clr', 'mn4_clrConfidence', 'pLDDT', undefined, 1, 1);
//}

//!!!
// html += this.getRadio('mn4_clr', 'mn4_clrIgstrand', 'Ig Strand', undefined, undefined, 2);
// html += this.getRadio('mn4_clr', 'mn4_clrIgproto', 'Ig Protodomain', undefined, undefined, 2);
html += this.getRadio('mn4_clr', 'mn4_clrIgstrand', 'Ig Strand', undefined, undefined, 2);
html += this.getRadio('mn4_clr', 'mn4_clrIgproto', 'Ig Protodomain', undefined, undefined, 2);
}
else {
//if(!me.cfg.hidelicense) html += this.getRadio('mn4_clr', 'mn1_delphi2', 'DelPhi<br><span style="padding-left:1.5em;">Potential ' + me.htmlCls.licenseStr + '</span>');
Expand Down Expand Up @@ -13699,8 +13702,10 @@ var icn3d = (function (exports) {
if(me.cfg.cid === undefined) {
html += this.getRadio('mn6_addlabel', 'mn6_addlabelResidues', 'per Residue', undefined, 1, 2);
html += this.getRadio('mn6_addlabel', 'mn6_addlabelResnum', 'per Residue & Number', undefined, 1, 2);
//!!!
// html += this.getRadio('mn6_addlabel', 'mn6_addlabelRefnum', 'per Reference Number', undefined, 1, 2);

html += this.getRadio('mn6_addlabel', 'mn6_addlabelRefnum', 'per Reference Number', undefined, 1, 2);
html += this.getRadio('mn6_addlabel', 'mn6_addlabelIg', 'per Ig Domain', undefined, 1, 2);

html += this.getRadio('mn6_addlabel', 'mn6_addlabelChains', 'per Chain', undefined, undefined, 2);
html += this.getRadio('mn6_addlabel', 'mn6_addlabelTermini', 'N- & C-Termini', undefined, 1, 2);
}
Expand Down Expand Up @@ -13793,17 +13798,13 @@ var icn3d = (function (exports) {
html += this.getMenuText('mn6_igrefwrap', 'Ref. Number', undefined, undefined, 1);

html += "<ul>";
//!!!
/*

html += this.getLink('mn6_igrefYes', 'Show Ig for Selection', undefined, 2);
html += this.getLink('mn6_igrefTpl', 'Ig w/ Specified Template', undefined, 2);
html += this.getLink('mn6_alignrefTpl', 'Align w/ Specified Template', undefined, 2);
html += this.getLink('mn6_igrefNo', 'Reset Ig Ref. Number', undefined, 2);

html += this.getMenuSep();
*/



html += this.getLink('mn6_customref', 'Custom Ref. Number', undefined, 2);
html += "</ul>";
Expand Down Expand Up @@ -13893,6 +13894,7 @@ var icn3d = (function (exports) {
html += this.getMenuUrl('faq_simialphapdb', me.htmlCls.baseUrl + "icn3d/icn3d.html#simifoldseek", "Similar AlphaFold/PDB", 1, 2);
html += this.getMenuUrl('faq_alnstru', me.htmlCls.baseUrl + "icn3d/icn3d.html#alignmul", "Align Multiple Structures", 1, 2);
html += this.getMenuUrl('faq_batchanal', me.htmlCls.baseUrl + "icn3d/icn3d.html#batchanalysis", "Batch Analysis", 1, 2);
html += this.getMenuUrl('faq_batchanal', me.htmlCls.baseUrl + "icn3d/icn3d.html#igrefnum", "Assign Ig Ref. Numbers", 1, 2);
html += this.getMenuUrl('faq_embedicn3d', me.htmlCls.baseUrl + "icn3d/icn3d.html#embedicn3d", "Embed iCn3D", 1, 2);
html += "</ul>";
html += "</li>";
Expand Down Expand Up @@ -16081,13 +16083,10 @@ var icn3d = (function (exports) {
html += tmpStr1 + me.htmlCls.inputCheckStr + "id='" + me.pre + "anno_interact'>Interactions" + me.htmlCls.space2 + "</span></td>";
html += tmpStr1 + me.htmlCls.inputCheckStr + "id='" + me.pre + "anno_crosslink'>Cross-Linkages" + me.htmlCls.space2 + "</span></td>";
html += tmpStr1 + me.htmlCls.inputCheckStr + "id='" + me.pre + "anno_transmem'>Transmembrane" + me.htmlCls.space2 + "</span></td>";
//!!!
/*

html += "<td></td>";
html += "</tr><tr>";
html += tmpStr1 + me.htmlCls.inputCheckStr + "id='" + me.pre + "anno_ig'>Ig Domains" + me.htmlCls.space2 + "</span></td>";
*/


html += "<td></td>";
html += "</tr></table></div></div>";
Expand Down Expand Up @@ -35758,6 +35757,33 @@ var icn3d = (function (exports) {
ic.hlObjectsCls.removeHlObjects();
}

//Add labels for each Ig domain
addIgLabels(atoms) { let ic = this.icn3d, me = ic.icn3dui;
if(me.bNode) return;

let size = 60; //18;

ic.labels['ig'] = [];
let chainidHash = ic.firstAtomObjCls.getChainsFromAtoms(atoms);

for(let chainid in ic.igLabel2Pos) {
if(!chainidHash.hasOwnProperty(chainid)) continue;

for(let text in ic.igLabel2Pos[chainid]) {
let label = {}; // Each label contains 'position', 'text', 'color', 'background'
label.position = ic.igLabel2Pos[chainid][text];
label.text = text;

label.size = size;
label.color = '#00FFFF';

ic.labels['ig'].push(label);
}
}

ic.hlObjectsCls.removeHlObjects();
}

addNonCarbonAtomLabels(atoms) { let ic = this.icn3d, me = ic.icn3dui;
if(me.bNode) return;

Expand Down Expand Up @@ -42028,6 +42054,8 @@ var icn3d = (function (exports) {
let igCnt = ic.chain2igArray[chnid].length;
let fromArray = [], toArray = [];
let posindex2domainindex = {};
if(!ic.igLabel2Pos) ic.igLabel2Pos = {};
ic.igLabel2Pos[chnid] = {};
for(let i = 0; i < igCnt; ++i) {
let igElem = ic.chain2igArray[chnid][i];
fromArray = fromArray.concat(igElem.startPosArray);
Expand All @@ -42037,6 +42065,18 @@ var icn3d = (function (exports) {
let pos = igElem.startPosArray[j];
posindex2domainindex[pos] = i;
}

let resi1 = ic.ParserUtilsCls.getResi(chnid, igElem.startPosArray[0]);
let resid1 = chnid + "_" + resi1;
let calpha1 = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid1]);

let resi2 = ic.ParserUtilsCls.getResi(chnid, igElem.endPosArray[igElem.endPosArray.length - 1]);
let resid2 = chnid + "_" + resi2;
let calpha2 = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid2]);

let label = chnid.substr(chnid.lastIndexOf('_') + 1) + '-Ig' + (i+1).toString();

ic.igLabel2Pos[chnid][label] = calpha1.coord.clone().add(calpha2.coord).multiplyScalar(0.5);
}

// let htmlCnt = '<span class="icn3d-residueNum" title="Ig domain count">' + igCnt.toString() + ' Igs</span>';
Expand Down Expand Up @@ -42087,6 +42127,7 @@ var icn3d = (function (exports) {
if(igArray.length == 0) return {html: html, html2: html2, html3: html3}
let rangeArray = [], titleArray = [], fullTitleArray = [], domainArray = [];

let chain = chnid.substr(chnid.lastIndexOf('_') + 1);
for(let i = 0, il = igArray.length; i < il; ++i) {
let domainid = igArray[i].domainid;
if(!ic.domainid2info) continue;
Expand All @@ -42098,7 +42139,7 @@ var icn3d = (function (exports) {

let igType = (parseFloat(tmscore) < ic.refnumCls.TMThresholdIgType ) ? 'Ig' : ic.ref2igtype[info.refpdbname];
titleArray.push(igType + ' (TM:' + parseFloat(tmscore).toFixed(2) + ')');
fullTitleArray.push(igType + ' (TM:' + parseFloat(tmscore).toFixed(2) + '), template: ' + info.refpdbname + ', type: ' + ic.ref2igtype[info.refpdbname] + ', Seq. identity: ' + parseFloat(info.seqid).toFixed(2) + ', aligned residues: ' + info.nresAlign);
fullTitleArray.push(igType + ' (TM:' + parseFloat(tmscore).toFixed(2) + '), template: ' + info.refpdbname + ', type: ' + ic.ref2igtype[info.refpdbname] + ', Seq. identity: ' + parseFloat(info.seqid).toFixed(2) + ', aligned residues: ' + info.nresAlign + ', label in 3D: ' + chain + '-Ig' + (i+1).toString());

domainArray.push(igType);

Expand Down Expand Up @@ -49368,7 +49409,7 @@ var icn3d = (function (exports) {
}

//Remove the highlight in the 2D interaction diagram.
removeHl2D() { let ic = this.icn3d; ic.icn3dui;
removeHl2D(bRemoveChainOnly) { let ic = this.icn3d; ic.icn3dui;
// clear nodes in 2d dgm
$("#" + ic.pre + "dl_2ddgm rect").attr('stroke', '#000000');
$("#" + ic.pre + "dl_2ddgm circle").attr('stroke', '#000000');
Expand All @@ -49382,6 +49423,22 @@ var icn3d = (function (exports) {
$("#" + ic.pre + "dl_2ddgm svg line").attr('stroke', '#000000');
$("#" + ic.pre + "dl_2ddgm line").attr('stroke-width', 1);
}

if(!bRemoveChainOnly) {
// clear nodes in 2d interaction network
// $("#" + ic.pre + "dl_linegraph rect").attr('stroke', '#000000');
$("#" + ic.pre + "dl_linegraph circle").attr('stroke', '#000000');

// $("#" + ic.pre + "dl_linegraph rect").attr('stroke-width', 1);
$("#" + ic.pre + "dl_linegraph circle").attr('stroke-width', 1);

// clear nodes in 2d interaction graph
$("#" + ic.pre + "dl_scatterplot rect").attr('stroke', '#000000');
$("#" + ic.pre + "dl_scatterplot circle").attr('stroke', '#000000');

$("#" + ic.pre + "dl_scatterplot rect").attr('stroke-width', 1);
$("#" + ic.pre + "dl_scatterplot circle").attr('stroke-width', 1);
}
}

//Remove the selection in the menu of defined sets.
Expand Down Expand Up @@ -49479,7 +49536,7 @@ var icn3d = (function (exports) {
// update highlight in 2D window
//Update the highlight of 2D interaction diagram according to the current highlighted atoms.
updateHl2D(chainArray2d) { let ic = this.icn3d, me = ic.icn3dui;
this.removeHl2D();
this.removeHl2D(true);

if(ic.hAtoms && ic.atoms && Object.keys(ic.hAtoms).length == Object.keys(ic.atoms).length) return;

Expand Down Expand Up @@ -49906,6 +49963,8 @@ var icn3d = (function (exports) {
&& ic.chainsMapping[chainid2] && ic.chainsMapping[chainid2][resid2]) {
mapping1 = (nodeA.s == "a") ? ic.chainsMapping[chainid1][resid1] : ic.chainsMapping[chainid2][resid2];
mapping2 = (nodeA.s == "a") ? ic.chainsMapping[chainid2][resid2] : ic.chainsMapping[chainid1][resid1];

let bIgRef = (mapping1.length > 4 && !isNaN(parseInt(mapping1.substr(-4, 4)))) || (mapping2.length > 4 && !isNaN(parseInt(mapping2.substr(-4, 4))));

let mappingid = mapping1 + '_' + mapping2 + '_' + link.c; // link.c determines the interaction type

Expand All @@ -49917,7 +49976,7 @@ var icn3d = (function (exports) {
linkDiff.source += separatorDiff + ic.chainsMapping[chainid1][resid1];
linkDiff.target += separatorDiff + ic.chainsMapping[chainid2][resid2];

if(linkedNodeCnt[mappingid] == structureArray.length && linkedNodeInterDiffBool[mappingid] == 0) {
if(linkedNodeCnt[mappingid] == structureArray.length && (bIgRef || linkedNodeInterDiffBool[mappingid] == 0)) {
linkArraySplitCommon[index].push(linkCommon);
}
else {
Expand Down Expand Up @@ -64840,7 +64899,7 @@ var icn3d = (function (exports) {
let chainid = chainidArray[i];
let atoms = me.hashUtilsCls.intHash(ic.hAtoms, ic.chains[chainid]);
let firstAtom = ic.firstAtomObjCls.getFirstAtomObj(atoms);
structHash[firstAtom.structure] = 1;
if(firstAtom) structHash[firstAtom.structure] = 1;
}
}

Expand Down Expand Up @@ -65862,6 +65921,11 @@ var icn3d = (function (exports) {

ic.drawCls.draw();
}
else if(command == 'add ig labels') {
ic.residueLabelsCls.addIgLabels(ic.hAtoms);

ic.drawCls.draw();
}
else if(command == 'add atom labels') {
ic.residueLabelsCls.addAtomLabels(ic.hAtoms);

Expand Down Expand Up @@ -67188,6 +67252,7 @@ var icn3d = (function (exports) {
else if(cmd.indexOf('hide annotation') == 0) return seqAnnoStr + ': checkboxes off';
else if(cmd == 'add residue labels') return labelStr + 'per Residue';
else if(cmd == 'add residue number labels') return labelStr + 'per Residue & Number';
else if(cmd == 'add Ig domain labels') return labelStr + 'per Ig Domain';
else if(cmd == 'add atom labels') return labelStr + 'per Atom';
else if(cmd == 'add chain labels') return labelStr + 'per Chain';
else if(cmd == 'add terminal labels') return labelStr + 'N- & C- Termini';
Expand Down Expand Up @@ -81692,7 +81757,7 @@ var icn3d = (function (exports) {
//even when multiple iCn3D viewers are shown together.
this.pre = this.cfg.divid + "_";

this.REVISION = '3.32.0';
this.REVISION = '3.33.0';

// In nodejs, iCn3D defines "window = {navigator: {}}"
this.bNode = (Object.keys(window).length < 2) ? true : false;
Expand Down
14 changes: 3 additions & 11 deletions build/icn3d.min.js

Large diffs are not rendered by default.

Loading

0 comments on commit e22e2c8

Please sign in to comment.