icn3d 3.54.5 → 3.54.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/icn3d.module.js CHANGED
@@ -2603,6 +2603,31 @@ var CIFTools;
2603
2603
  return out;
2604
2604
  };
2605
2605
  }
2606
+ /**
2607
+ * Options for filling the unit cell of a core CIF by lattice translation
2608
+ * (applied after the symmetry operators have generated the contents of one cell).
2609
+ * nx, ny, nz : number of unit cells along a, b, c (supercell); default 1 1 1
2610
+ * boundary : also emit the periodic image of every atom lying on a cell face/edge/corner
2611
+ * (e.g. NaCl -> 14 Na + 13 Cl instead of 4 Na + 4 Cl); default true.
2612
+ * Set to false to get the original behavior (atoms wrapped into [0,1) only).
2613
+ * Usage (before loading the file): CIFTools.Text.coreCifOptions = {nx: 2, ny: 2, nz: 2, boundary: true};
2614
+ */
2615
+ Text.coreCifOptions = { nx: 1, ny: 1, nz: 1, boundary: true };
2616
+ // g: fractional coordinates wrapped into [0,1). Returns all translated copies of g.
2617
+ function coreLatticeImages(g, nx, ny, nz, bBoundary) {
2618
+ var eps = 1e-3, n = [nx, ny, nz], ranges = [], out = [], k, i, r, x, y, z;
2619
+ for (k = 0; k < 3; k++) {
2620
+ r = [];
2621
+ for (i = 0; i < n[k]; i++) r.push(g[k] + i);
2622
+ if (bBoundary && Math.abs(g[k]) < eps) r.push(g[k] + n[k]); // atom on the 0-face also sits on the far face
2623
+ ranges.push(r);
2624
+ }
2625
+ for (x = 0; x < ranges[0].length; x++)
2626
+ for (y = 0; y < ranges[1].length; y++)
2627
+ for (z = 0; z < ranges[2].length; z++)
2628
+ out.push([ranges[0][x], ranges[1][y], ranges[2][z]]);
2629
+ return out;
2630
+ }
2606
2631
  function convertCoreCif(data) {
2607
2632
  var tk = coreTokens(data), i = 0, n = tk.length, single = {}, loops = [], name = 'data_core', t, cols, rows, cur;
2608
2633
  function isTag(x) { return x && !x.t && x.v.charAt(0) === '_'; }
@@ -2657,6 +2682,11 @@ var CIFTools;
2657
2682
  '_atom_site.Cartn_x', '_atom_site.Cartn_y', '_atom_site.Cartn_z', '_atom_site.occupancy', '_atom_site.B_iso_or_equiv',
2658
2683
  '_atom_site.auth_seq_id', '_atom_site.auth_asym_id', '_atom_site.pdbx_PDB_model_num');
2659
2684
  var serial = 0, seen = [], r, s, f, g, k, dup, j, sym, el, lab, cart;
2685
+ var o = Text.coreCifOptions || {}, images, im;
2686
+ var opt = {
2687
+ nx: Math.max(1, parseInt(o.nx) || 1), ny: Math.max(1, parseInt(o.ny) || 1), nz: Math.max(1, parseInt(o.nz) || 1),
2688
+ boundary: (o.boundary === undefined) ? true : !!o.boundary
2689
+ };
2660
2690
  for (r = 0; r < atoms.rows.length; r++) {
2661
2691
  var row = atoms.rows[r];
2662
2692
  if (get(row, '_atom_site_calc_flag') === 'dum') continue; // dummy atoms
@@ -2674,9 +2704,13 @@ var CIFTools;
2674
2704
  }
2675
2705
  if (dup) continue;
2676
2706
  mySeen.push(g);
2677
- cart = toCart(g);
2678
- out.push(['HETATM', ++serial, el, lab, '.', 'MOL', 'A', 1, '.', cart[0].toFixed(3), cart[1].toFixed(3), cart[2].toFixed(3),
2679
- coreToNumber(get(row, '_atom_site_occupancy') === '?' ? 1 : get(row, '_atom_site_occupancy')), '0.00', 1, 'A', 1].join(' '));
2707
+ // fill the cell (and optional supercell) by lattice translation of the symmetry-generated site
2708
+ images = coreLatticeImages(g, opt.nx, opt.ny, opt.nz, opt.boundary);
2709
+ for (im = 0; im < images.length; im++) {
2710
+ cart = toCart(images[im]);
2711
+ out.push(['HETATM', ++serial, el, lab, '.', 'MOL', 'A', 1, '.', cart[0].toFixed(3), cart[1].toFixed(3), cart[2].toFixed(3),
2712
+ coreToNumber(get(row, '_atom_site_occupancy') === '?' ? 1 : get(row, '_atom_site_occupancy')), '0.00', 1, 'A', 1].join(' '));
2713
+ }
2680
2714
  }
2681
2715
  }
2682
2716
  out.push('#');
@@ -56775,6 +56809,29 @@ class ParasCls {
56775
56809
  CM: 1.69
56776
56810
  };
56777
56811
 
56812
+ this.ionRadii = { // https://en.wikipedia.org/wiki/Ionic_radius
56813
+ H: 1.40, HE: 0.28, LI: 0.76, BE: 0.45, B: 0.27,
56814
+ C: 0.16, N: 1.46, O: 1.40, F: 1.33, NE: 0.58,
56815
+ NA: 1.02, MG: 0.72, AL: 0.54, SI: 0.40, P: 0.38,
56816
+ S: 1.84, CL: 1.81, AR: 1.06, K: 1.38, CA: 1.00,
56817
+ SC: 0.75, TI: 0.86, V: 0.79, CR: 0.73, MN: 0.67,
56818
+ FE: 0.55, CO: 0.65, NI: 0.69, CU: 0.73, ZN: 0.74,
56819
+ GA: 0.62, GE: 0.73, AS: 0.58, SE: 1.98, BR: 1.96,
56820
+ KR: 1.16, RB: 1.52, SR: 1.18, Y: 0.90, ZR: 0.72,
56821
+ NB: 0.72, MO: 0.69, TC: 0.65, RU: 0.68, RH: 0.67,
56822
+ PD: 0.86, AG: 1.15, CD: 0.95, IN: 0.80, SN: 1.02,
56823
+ SB: 0.76, TE: 0.97, I: 2.20, XE: 0.48, CS: 1.67,
56824
+ BA: 1.35, LA: 1.03, CE: 1.01, PR: 0.99, ND: 1.29,
56825
+ PM: 0.97, SM: 1.22, EU: 1.17, GD: 0.94, TB: 0.92,
56826
+ DY: 1.07, HO: 0.90, ER: 0.89, TM: 1.03, YB: 1.02,
56827
+ LU: 0.86, HF: 0.71, TA: 0.72, W: 0.66, RE: 0.63,
56828
+ OS: 0.63, IR: 0.68, PT: 0.80, AU: 1.37, HG: 1.19,
56829
+ TL: 1.50, PB: 1.19, BI: 1.03, PO: 0.94, AT: 0.62,
56830
+ RN: 1.50, FR: 1.80, RA: 1.48, AC: 1.07, TH: 0.94,
56831
+ PA: 1.04, U: 1.03, NP: 1.10, PU: 1.00, AM: 1.26,
56832
+ CM: 0.97
56833
+ };
56834
+
56778
56835
  /*
56779
56836
  this.surfaces = {
56780
56837
  1: undefined,
@@ -59958,6 +60015,19 @@ class ClickMenu {
59958
60015
 
59959
60016
  }
59960
60017
 
60018
+ async setSupercell(n) { let me = this.icn3dui, ic = me.icn3d;
60019
+ ic.loadCIFCls.loadCIF(ic.cifData, undefined, ic.cifText, false, n);
60020
+
60021
+ if(Object.keys(ic.proteins).length == 0 || Object.keys(ic.nucleotides).length == 0) {
60022
+ ic.pk = 1;
60023
+ ic.opts['pk'] = 'atom';
60024
+ }
60025
+
60026
+ ic.setStyleCls.setAtomStyleByOptions(ic.opts);
60027
+ ic.setColorCls.setColorByOptions(ic.opts, ic.atoms);
60028
+ await ic.ParserUtilsCls.renderStructure();
60029
+ }
60030
+
59961
60031
  clickMenu6() { let me = this.icn3dui, ic = me.icn3d;
59962
60032
  if(me.bNode) return;
59963
60033
 
@@ -59975,6 +60045,23 @@ class ClickMenu {
59975
60045
  ic.drawCls.draw();
59976
60046
  });
59977
60047
 
60048
+ me.myEventCls.onIds("#" + me.pre + "mn6_assembly0", "click", async function(e) { me.icn3d; //e.preventDefault();
60049
+ await thisClass.setSupercell(0);
60050
+ thisClass.setLogCmd('set supercell 0', true);
60051
+ });
60052
+ me.myEventCls.onIds("#" + me.pre + "mn6_assembly1", "click", async function(e) { me.icn3d; //e.preventDefault();
60053
+ await thisClass.setSupercell(1);
60054
+ thisClass.setLogCmd('set supercell 1', true);
60055
+ });
60056
+ me.myEventCls.onIds("#" + me.pre + "mn6_assembly2", "click", async function(e) { me.icn3d; //e.preventDefault();
60057
+ await thisClass.setSupercell(2);
60058
+ thisClass.setLogCmd('set supercell 2', true);
60059
+ });
60060
+ me.myEventCls.onIds("#" + me.pre + "mn6_assembly3", "click", async function(e) { me.icn3d; //e.preventDefault();
60061
+ await thisClass.setSupercell(3);
60062
+ thisClass.setLogCmd('set supercell 3', true);
60063
+ });
60064
+
59978
60065
  me.myEventCls.onIds("#" + me.pre + "mn6_igrefYes", "click", async function(e) { let ic = me.icn3d; //e.preventDefault();
59979
60066
  ic.bRunRefnumAgain = true;
59980
60067
 
@@ -62569,13 +62656,19 @@ class SetMenu {
62569
62656
 
62570
62657
  html += this.getLink('mn6_DSSP', 'DSSP Secondary', undefined, 1);
62571
62658
 
62572
- let bOnePdb = me.cfg.mmtfid !== undefined || me.cfg.pdbid !== undefined || me.cfg.opmid !== undefined || me.cfg.mmcifid !== undefined || me.cfg.mmdbid !== undefined || me.cfg.mmdbafid !== undefined || me.cfg.gi !== undefined || me.cfg.blast_rep_id !== undefined;
62659
+ let bInputid = me.cfg.mmtfid !== undefined || me.cfg.pdbid !== undefined || me.cfg.opmid !== undefined || me.cfg.mmcifid !== undefined || me.cfg.bcifid !== undefined || me.cfg.mmdbid !== undefined || me.cfg.mmdbafid !== undefined || me.cfg.gi !== undefined || me.cfg.blast_rep_id !== undefined;
62573
62660
 
62574
- if(bOnePdb) {
62661
+ //if(bInputid) {
62575
62662
  html += this.getMenuText('assemblyWrapper', 'Assembly', undefined, 1, 1);
62576
62663
  html += "<ul>";
62577
62664
 
62578
- if(!me.cfg.bu) {
62665
+ if(!bInputid || me.cfg.mmcifid !== undefined || me.cfg.bcifid !== undefined) { // e.g., cif file input
62666
+ html += this.getRadio('mn6_assembly', 'mn6_assembly0', 'Original Assembly', undefined, 1, 2);
62667
+ html += this.getRadio('mn6_assembly', 'mn6_assembly1', '1 x 1 x 1', true, 1, 2);
62668
+ html += this.getRadio('mn6_assembly', 'mn6_assembly2', '2 x 2 x 2', undefined, 1, 2);
62669
+ html += this.getRadio('mn6_assembly', 'mn6_assembly3', '3 x 3 x 3', undefined, 1, 2);
62670
+ }
62671
+ else if(!me.cfg.bu) {
62579
62672
  html += this.getRadio('mn6_assembly', 'mn6_assemblyYes', 'Biological Assembly', undefined, 1, 2);
62580
62673
  html += this.getRadio('mn6_assembly', 'mn6_assemblyNo', 'Asymmetric Unit', true, 1, 2);
62581
62674
  }
@@ -62586,12 +62679,12 @@ class SetMenu {
62586
62679
 
62587
62680
  html += "</ul>";
62588
62681
  html += "</li>";
62589
- }
62682
+ //}
62590
62683
 
62591
62684
  html += this.getMenuText('mn6_symmetrywrap', 'Symmetry', undefined, undefined, 1);
62592
62685
 
62593
62686
  html += "<ul>";
62594
- if(bOnePdb) html += this.getLink('mn6_symmetry', 'from PDB(precalculated) ' + me.htmlCls.wifiStr, undefined, 2);
62687
+ if(bInputid) html += this.getLink('mn6_symmetry', 'from PDB(precalculated) ' + me.htmlCls.wifiStr, undefined, 2);
62595
62688
 
62596
62689
  html += this.getLink('mn6_symd', 'from SymD(Dynamic) ' + me.htmlCls.wifiStr, undefined, 2);
62597
62690
  html += this.getLink('mn6_clear_sym', 'Clear SymD Symmetry', undefined, 2);
@@ -65324,7 +65417,7 @@ class Events {
65324
65417
  }
65325
65418
  }
65326
65419
 
65327
- async readFile(bAppend, files, index, dataStrAll, bmmCIF, bPng) { let me = this.icn3dui, ic = me.icn3d, thisClass = this;
65420
+ async readFile(bAppend, files, index, dataStrAll, bmmCIF, bPng, fileType) { let me = this.icn3dui, ic = me.icn3d, thisClass = this;
65328
65421
  let file = files[index];
65329
65422
  let commandName = (bAppend) ? 'append': 'load';
65330
65423
  commandName += (bmmCIF) ? ' mmcif file ' : (bPng) ? ' png file ' : ' pdb file ';
@@ -65374,7 +65467,7 @@ class Events {
65374
65467
  ic.dAtoms = {};
65375
65468
  }
65376
65469
  if(bmmCIF) {
65377
- await ic.mmcifParserCls.loadMultipleMmcifData(dataStrAll, undefined, bAppend);
65470
+ await ic.mmcifParserCls.loadMultipleMmcifData(dataStrAll, undefined, bAppend, fileType);
65378
65471
  }
65379
65472
  else {
65380
65473
  await ic.pdbParserCls.loadPdbData(dataStrAll, undefined, undefined, bAppend);
@@ -65400,7 +65493,12 @@ class Events {
65400
65493
  };
65401
65494
 
65402
65495
  if (typeof file === "object") {
65403
- reader.readAsText(file);
65496
+ if(bmmCIF && fileType == 'bcif') {
65497
+ reader.readAsArrayBuffer(file);
65498
+ }
65499
+ else {
65500
+ reader.readAsText(file);
65501
+ }
65404
65502
  }
65405
65503
  }
65406
65504
 
@@ -68935,8 +69033,8 @@ class Events {
68935
69033
  let fileName = file.name;
68936
69034
 
68937
69035
  let fileType = fileName.substr(fileName.lastIndexOf('.') + 1).toLowerCase();
68938
- if(fileType == 'pdb' || fileType == 'mmcif' || fileType == 'png') {
68939
- await me.htmlCls.eventsCls.readFile(true, files, i, '', (fileType == 'mmcif'), (fileType == 'png'));
69036
+ if(fileType == 'pdb' || fileType == 'mmcif' || fileType == 'cif' || fileType == 'bcif' || fileType == 'png') {
69037
+ await me.htmlCls.eventsCls.readFile(true, files, i, '', (fileType == 'mmcif' || fileType == 'cif' || fileType == 'bcif'), (fileType == 'png'), fileType);
68940
69038
  }
68941
69039
  else if(fileType == 'bcf') {
68942
69040
  await thisClass.openBcf(file);
@@ -125360,8 +125458,9 @@ class MmcifParser {
125360
125458
  }
125361
125459
  }
125362
125460
 
125363
- async loadMultipleMmcifData(data, mmcifid, bAppend) { let ic = this.icn3d; ic.icn3dui;
125364
- let bText = true;
125461
+ async loadMultipleMmcifData(data, mmcifid, bAppend, fileType) { let ic = this.icn3d; ic.icn3dui;
125462
+ let bText = (fileType == 'bcif') ? false : true;
125463
+
125365
125464
  ic.loadCIFCls.loadCIF(data, mmcifid, bText, bAppend);
125366
125465
 
125367
125466
  if(Object.keys(ic.structures).length > 1) {
@@ -134829,11 +134928,14 @@ class LoadPDB {
134829
134928
  prevCarbonArray.push(atom);
134830
134929
  }
134831
134930
 
134931
+ // remove trailing digits in the residue name, e.g., "Na1" -> "NA"
134932
+ let resnSimple = atom.resn.trim().replace(/\d+$/, '').toUpperCase();
134933
+
134832
134934
  if(atom.resn === 'HOH' || atom.resn === 'WAT' || atom.resn === 'SOL') {
134833
134935
  ic.water[atom.serial] = 1;
134834
134936
  atom.color = me.parasCls.atomColors[atom.elem];
134835
134937
  }
134836
- else if($.inArray(atom.resn.trim(), me.parasCls.ionsArray) !== -1 || atom.elem.trim() === atom.resn.trim()) {
134938
+ else if($.inArray(resnSimple, me.parasCls.ionsArray) !== -1 || $.inArray(atom.elem.trim().toUpperCase(), me.parasCls.ionsArray) !== -1 || atom.elem.trim() === atom.resn.trim()) {
134837
134939
  ic.ions[atom.serial] = 1;
134838
134940
  atom.color = me.parasCls.atomColors[atom.elem];
134839
134941
  }
@@ -134884,6 +134986,13 @@ class LoadPDB {
134884
134986
  }
134885
134987
  } // end of for
134886
134988
 
134989
+ if(Object.keys(ic.ions).length > 0 && Object.keys(ic.proteins).length == 0 && Object.keys(ic.nucleotides).length == 0 && Object.keys(ic.chemicals).length == 0 && Object.keys(ic.water).length == 0) {
134990
+ for(let serial in ic.ions) {
134991
+ let atom = ic.atoms[serial];
134992
+ me.parasCls.vdwRadii[atom.elem.toUpperCase()] = me.parasCls.ionRadii[atom.elem.toUpperCase()];
134993
+ }
134994
+ }
134995
+
134887
134996
  // last residue
134888
134997
  //refreshBonds();
134889
134998
  this.refreshBonds(curResAtoms, prevCarbonArray[0]);
@@ -135233,7 +135342,20 @@ class LoadCIF {
135233
135342
  return secondarySet.has(resid.substr(resid.indexOf('_') + 1));
135234
135343
  }
135235
135344
 
135236
- loadCIF(bcifData, bcifid, bText, bAppend) { let ic = this.icn3d, me = ic.icn3dui;
135345
+ loadCIF(bcifData, bcifid, bText, bAppend, supercell) { let ic = this.icn3d, me = ic.icn3dui;
135346
+ ic.cifText = bText;
135347
+ ic.cifData = bcifData;
135348
+
135349
+ if(supercell === undefined) {
135350
+ CIFTools.Text.coreCifOptions = { nx: 1, ny: 1, nz: 1, boundary: true };
135351
+ }
135352
+ else if(supercell === 0) {
135353
+ CIFTools.Text.coreCifOptions = { nx: 1, ny: 1, nz: 1, boundary: false };
135354
+ }
135355
+ else {
135356
+ CIFTools.Text.coreCifOptions = { nx: supercell, ny: supercell, nz: supercell, boundary: true };
135357
+ }
135358
+
135237
135359
  let hAtoms = {};
135238
135360
 
135239
135361
  let bNMR = false;
@@ -135286,7 +135408,6 @@ class LoadCIF {
135286
135408
  helixStart = [];
135287
135409
  helixEnd = [];
135288
135410
 
135289
-
135290
135411
  // bcifData could be binary or text
135291
135412
  let parsed = (bText) ? CIFTools.Text.parse(cifArray[index]) : CIFTools.Binary.parse(cifArray[index]);
135292
135413
 
@@ -136086,17 +136207,19 @@ class LoadCIF {
136086
136207
  }
136087
136208
  }
136088
136209
  else if(atom.het) {
136210
+ let resnSimple = atom.resn.trim().replace(/\d+$/, '').toUpperCase();
136211
+
136089
136212
  if(atom.resn === 'HOH' || atom.resn === 'WAT' || atom.resn === 'SOL') {
136090
136213
  ic.water[atom.serial] = 1;
136091
136214
  }
136092
- else if($.inArray(atom.resn, me.parasCls.ionsArray) !== -1 || atom.elem.trim() === atom.resn.trim()) {
136215
+ else if($.inArray(resnSimple, me.parasCls.ionsArray) !== -1 || $.inArray(atom.elem.trim().toUpperCase(), me.parasCls.ionsArray) !== -1 || atom.elem.trim() === atom.resn.trim()) {
136093
136216
  ic.ions[atom.serial] = 1;
136094
136217
  }
136095
136218
  else {
136096
136219
  ic.chemicals[atom.serial] = 1;
136097
136220
  }
136098
136221
 
136099
- atom.color = me.parasCls.atomColors[atom.elem];
136222
+ atom.color = me.parasCls.atomColors[atom.elem.toUpperCase()];
136100
136223
  }
136101
136224
 
136102
136225
  if(!(curChain === atom.chain && curResi === atom.resi)) {
@@ -136117,6 +136240,13 @@ class LoadCIF {
136117
136240
  }
136118
136241
  } // end of for
136119
136242
 
136243
+ if(Object.keys(ic.ions).length > 0 && Object.keys(ic.proteins).length == 0 && Object.keys(ic.nucleotides).length == 0 && Object.keys(ic.chemicals).length == 0 && Object.keys(ic.water).length == 0) {
136244
+ for(let serial in ic.ions) {
136245
+ let atom = ic.atoms[serial];
136246
+ me.parasCls.vdwRadii[atom.elem.toUpperCase()] = me.parasCls.ionRadii[atom.elem.toUpperCase()];
136247
+ }
136248
+ }
136249
+
136120
136250
  // last residue
136121
136251
  //refreshBonds();
136122
136252
  ic.loadPDBCls.refreshBonds(curResAtoms, prevCarbonArray[0]);
@@ -137195,6 +137325,12 @@ class ApplyCommand {
137195
137325
  else if(command == 'set assembly off') {
137196
137326
  ic.bAssembly = false;
137197
137327
  }
137328
+ else if(command.indexOf('set supercell') !== -1) {
137329
+ let pos = command.lastIndexOf(' ');
137330
+ let supercell = parseInt(command.substr(pos + 1));
137331
+
137332
+ await me.htmlCls.clickMenuCls.setSupercell(supercell);
137333
+ }
137198
137334
  else if(command == 'set chemicalbinding show') {
137199
137335
  ic.setOptionCls.setOption('chemicalbinding', 'show');
137200
137336
  }
@@ -141850,7 +141986,7 @@ class Selection {
141850
141986
 
141851
141987
  resetAll() { let ic = this.icn3d, me = ic.icn3dui;
141852
141988
  ic.maxD = ic.oriMaxD;
141853
- ic.center = ic.oriCenter.clone();
141989
+ ic.center = (ic.oriCenter) ? ic.oriCenter.clone() : new THREE.Vector3(0, 0, 0);
141854
141990
 
141855
141991
  ic.opts = me.hashUtilsCls.cloneHash(ic.optsOri);
141856
141992
 
@@ -150155,7 +150291,7 @@ class Transform {
150155
150291
 
150156
150292
  //reset ic.maxD
150157
150293
  ic.maxD = ic.oriMaxD;
150158
- ic.center = ic.oriCenter.clone();
150294
+ ic.center = (ic.oriCenter) ? ic.oriCenter.clone() : new Vector3$1(0, 0, 0);
150159
150295
 
150160
150296
  if(ic.ori_chemicalbinding == 'show') {
150161
150297
  ic.bSkipChemicalbinding = false;
@@ -154889,7 +155025,7 @@ class iCn3DUI {
154889
155025
  //even when multiple iCn3D viewers are shown together.
154890
155026
  this.pre = this.cfg.divid + "_";
154891
155027
 
154892
- this.REVISION = '3.54.2';
155028
+ this.REVISION = '3.54.3';
154893
155029
 
154894
155030
  // In nodejs, iCn3D defines "window = {navigator: {}}", and added window = {navigator: {}, "__THREE__":"177"}
154895
155031
  this.bNode = (Object.keys(window).length < 3) ? true : false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "icn3d",
3
- "version": "3.54.5",
3
+ "version": "3.54.6",
4
4
  "main": "./icn3d.js",
5
5
  "exports": {
6
6
  ".": {