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.js CHANGED
@@ -2610,6 +2610,31 @@ var CIFTools;
2610
2610
  return out;
2611
2611
  };
2612
2612
  }
2613
+ /**
2614
+ * Options for filling the unit cell of a core CIF by lattice translation
2615
+ * (applied after the symmetry operators have generated the contents of one cell).
2616
+ * nx, ny, nz : number of unit cells along a, b, c (supercell); default 1 1 1
2617
+ * boundary : also emit the periodic image of every atom lying on a cell face/edge/corner
2618
+ * (e.g. NaCl -> 14 Na + 13 Cl instead of 4 Na + 4 Cl); default true.
2619
+ * Set to false to get the original behavior (atoms wrapped into [0,1) only).
2620
+ * Usage (before loading the file): CIFTools.Text.coreCifOptions = {nx: 2, ny: 2, nz: 2, boundary: true};
2621
+ */
2622
+ Text.coreCifOptions = { nx: 1, ny: 1, nz: 1, boundary: true };
2623
+ // g: fractional coordinates wrapped into [0,1). Returns all translated copies of g.
2624
+ function coreLatticeImages(g, nx, ny, nz, bBoundary) {
2625
+ var eps = 1e-3, n = [nx, ny, nz], ranges = [], out = [], k, i, r, x, y, z;
2626
+ for (k = 0; k < 3; k++) {
2627
+ r = [];
2628
+ for (i = 0; i < n[k]; i++) r.push(g[k] + i);
2629
+ if (bBoundary && Math.abs(g[k]) < eps) r.push(g[k] + n[k]); // atom on the 0-face also sits on the far face
2630
+ ranges.push(r);
2631
+ }
2632
+ for (x = 0; x < ranges[0].length; x++)
2633
+ for (y = 0; y < ranges[1].length; y++)
2634
+ for (z = 0; z < ranges[2].length; z++)
2635
+ out.push([ranges[0][x], ranges[1][y], ranges[2][z]]);
2636
+ return out;
2637
+ }
2613
2638
  function convertCoreCif(data) {
2614
2639
  var tk = coreTokens(data), i = 0, n = tk.length, single = {}, loops = [], name = 'data_core', t, cols, rows, cur;
2615
2640
  function isTag(x) { return x && !x.t && x.v.charAt(0) === '_'; }
@@ -2664,6 +2689,11 @@ var CIFTools;
2664
2689
  '_atom_site.Cartn_x', '_atom_site.Cartn_y', '_atom_site.Cartn_z', '_atom_site.occupancy', '_atom_site.B_iso_or_equiv',
2665
2690
  '_atom_site.auth_seq_id', '_atom_site.auth_asym_id', '_atom_site.pdbx_PDB_model_num');
2666
2691
  var serial = 0, seen = [], r, s, f, g, k, dup, j, sym, el, lab, cart;
2692
+ var o = Text.coreCifOptions || {}, images, im;
2693
+ var opt = {
2694
+ nx: Math.max(1, parseInt(o.nx) || 1), ny: Math.max(1, parseInt(o.ny) || 1), nz: Math.max(1, parseInt(o.nz) || 1),
2695
+ boundary: (o.boundary === undefined) ? true : !!o.boundary
2696
+ };
2667
2697
  for (r = 0; r < atoms.rows.length; r++) {
2668
2698
  var row = atoms.rows[r];
2669
2699
  if (get(row, '_atom_site_calc_flag') === 'dum') continue; // dummy atoms
@@ -2681,9 +2711,13 @@ var CIFTools;
2681
2711
  }
2682
2712
  if (dup) continue;
2683
2713
  mySeen.push(g);
2684
- cart = toCart(g);
2685
- out.push(['HETATM', ++serial, el, lab, '.', 'MOL', 'A', 1, '.', cart[0].toFixed(3), cart[1].toFixed(3), cart[2].toFixed(3),
2686
- coreToNumber(get(row, '_atom_site_occupancy') === '?' ? 1 : get(row, '_atom_site_occupancy')), '0.00', 1, 'A', 1].join(' '));
2714
+ // fill the cell (and optional supercell) by lattice translation of the symmetry-generated site
2715
+ images = coreLatticeImages(g, opt.nx, opt.ny, opt.nz, opt.boundary);
2716
+ for (im = 0; im < images.length; im++) {
2717
+ cart = toCart(images[im]);
2718
+ out.push(['HETATM', ++serial, el, lab, '.', 'MOL', 'A', 1, '.', cart[0].toFixed(3), cart[1].toFixed(3), cart[2].toFixed(3),
2719
+ coreToNumber(get(row, '_atom_site_occupancy') === '?' ? 1 : get(row, '_atom_site_occupancy')), '0.00', 1, 'A', 1].join(' '));
2720
+ }
2687
2721
  }
2688
2722
  }
2689
2723
  out.push('#');
@@ -55874,6 +55908,29 @@ class ParasCls {
55874
55908
  CM: 1.69
55875
55909
  };
55876
55910
 
55911
+ this.ionRadii = { // https://en.wikipedia.org/wiki/Ionic_radius
55912
+ H: 1.40, HE: 0.28, LI: 0.76, BE: 0.45, B: 0.27,
55913
+ C: 0.16, N: 1.46, O: 1.40, F: 1.33, NE: 0.58,
55914
+ NA: 1.02, MG: 0.72, AL: 0.54, SI: 0.40, P: 0.38,
55915
+ S: 1.84, CL: 1.81, AR: 1.06, K: 1.38, CA: 1.00,
55916
+ SC: 0.75, TI: 0.86, V: 0.79, CR: 0.73, MN: 0.67,
55917
+ FE: 0.55, CO: 0.65, NI: 0.69, CU: 0.73, ZN: 0.74,
55918
+ GA: 0.62, GE: 0.73, AS: 0.58, SE: 1.98, BR: 1.96,
55919
+ KR: 1.16, RB: 1.52, SR: 1.18, Y: 0.90, ZR: 0.72,
55920
+ NB: 0.72, MO: 0.69, TC: 0.65, RU: 0.68, RH: 0.67,
55921
+ PD: 0.86, AG: 1.15, CD: 0.95, IN: 0.80, SN: 1.02,
55922
+ SB: 0.76, TE: 0.97, I: 2.20, XE: 0.48, CS: 1.67,
55923
+ BA: 1.35, LA: 1.03, CE: 1.01, PR: 0.99, ND: 1.29,
55924
+ PM: 0.97, SM: 1.22, EU: 1.17, GD: 0.94, TB: 0.92,
55925
+ DY: 1.07, HO: 0.90, ER: 0.89, TM: 1.03, YB: 1.02,
55926
+ LU: 0.86, HF: 0.71, TA: 0.72, W: 0.66, RE: 0.63,
55927
+ OS: 0.63, IR: 0.68, PT: 0.80, AU: 1.37, HG: 1.19,
55928
+ TL: 1.50, PB: 1.19, BI: 1.03, PO: 0.94, AT: 0.62,
55929
+ RN: 1.50, FR: 1.80, RA: 1.48, AC: 1.07, TH: 0.94,
55930
+ PA: 1.04, U: 1.03, NP: 1.10, PU: 1.00, AM: 1.26,
55931
+ CM: 0.97
55932
+ };
55933
+
55877
55934
  /*
55878
55935
  this.surfaces = {
55879
55936
  1: undefined,
@@ -59057,6 +59114,19 @@ class ClickMenu {
59057
59114
 
59058
59115
  }
59059
59116
 
59117
+ async setSupercell(n) { let me = this.icn3dui, ic = me.icn3d;
59118
+ ic.loadCIFCls.loadCIF(ic.cifData, undefined, ic.cifText, false, n);
59119
+
59120
+ if(Object.keys(ic.proteins).length == 0 || Object.keys(ic.nucleotides).length == 0) {
59121
+ ic.pk = 1;
59122
+ ic.opts['pk'] = 'atom';
59123
+ }
59124
+
59125
+ ic.setStyleCls.setAtomStyleByOptions(ic.opts);
59126
+ ic.setColorCls.setColorByOptions(ic.opts, ic.atoms);
59127
+ await ic.ParserUtilsCls.renderStructure();
59128
+ }
59129
+
59060
59130
  clickMenu6() { let me = this.icn3dui, ic = me.icn3d;
59061
59131
  if(me.bNode) return;
59062
59132
 
@@ -59074,6 +59144,23 @@ class ClickMenu {
59074
59144
  ic.drawCls.draw();
59075
59145
  });
59076
59146
 
59147
+ me.myEventCls.onIds("#" + me.pre + "mn6_assembly0", "click", async function(e) { me.icn3d; //e.preventDefault();
59148
+ await thisClass.setSupercell(0);
59149
+ thisClass.setLogCmd('set supercell 0', true);
59150
+ });
59151
+ me.myEventCls.onIds("#" + me.pre + "mn6_assembly1", "click", async function(e) { me.icn3d; //e.preventDefault();
59152
+ await thisClass.setSupercell(1);
59153
+ thisClass.setLogCmd('set supercell 1', true);
59154
+ });
59155
+ me.myEventCls.onIds("#" + me.pre + "mn6_assembly2", "click", async function(e) { me.icn3d; //e.preventDefault();
59156
+ await thisClass.setSupercell(2);
59157
+ thisClass.setLogCmd('set supercell 2', true);
59158
+ });
59159
+ me.myEventCls.onIds("#" + me.pre + "mn6_assembly3", "click", async function(e) { me.icn3d; //e.preventDefault();
59160
+ await thisClass.setSupercell(3);
59161
+ thisClass.setLogCmd('set supercell 3', true);
59162
+ });
59163
+
59077
59164
  me.myEventCls.onIds("#" + me.pre + "mn6_igrefYes", "click", async function(e) { let ic = me.icn3d; //e.preventDefault();
59078
59165
  ic.bRunRefnumAgain = true;
59079
59166
 
@@ -61668,13 +61755,19 @@ class SetMenu {
61668
61755
 
61669
61756
  html += this.getLink('mn6_DSSP', 'DSSP Secondary', undefined, 1);
61670
61757
 
61671
- 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;
61758
+ 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;
61672
61759
 
61673
- if(bOnePdb) {
61760
+ //if(bInputid) {
61674
61761
  html += this.getMenuText('assemblyWrapper', 'Assembly', undefined, 1, 1);
61675
61762
  html += "<ul>";
61676
61763
 
61677
- if(!me.cfg.bu) {
61764
+ if(!bInputid || me.cfg.mmcifid !== undefined || me.cfg.bcifid !== undefined) { // e.g., cif file input
61765
+ html += this.getRadio('mn6_assembly', 'mn6_assembly0', 'Original Assembly', undefined, 1, 2);
61766
+ html += this.getRadio('mn6_assembly', 'mn6_assembly1', '1 x 1 x 1', true, 1, 2);
61767
+ html += this.getRadio('mn6_assembly', 'mn6_assembly2', '2 x 2 x 2', undefined, 1, 2);
61768
+ html += this.getRadio('mn6_assembly', 'mn6_assembly3', '3 x 3 x 3', undefined, 1, 2);
61769
+ }
61770
+ else if(!me.cfg.bu) {
61678
61771
  html += this.getRadio('mn6_assembly', 'mn6_assemblyYes', 'Biological Assembly', undefined, 1, 2);
61679
61772
  html += this.getRadio('mn6_assembly', 'mn6_assemblyNo', 'Asymmetric Unit', true, 1, 2);
61680
61773
  }
@@ -61685,12 +61778,12 @@ class SetMenu {
61685
61778
 
61686
61779
  html += "</ul>";
61687
61780
  html += "</li>";
61688
- }
61781
+ //}
61689
61782
 
61690
61783
  html += this.getMenuText('mn6_symmetrywrap', 'Symmetry', undefined, undefined, 1);
61691
61784
 
61692
61785
  html += "<ul>";
61693
- if(bOnePdb) html += this.getLink('mn6_symmetry', 'from PDB(precalculated) ' + me.htmlCls.wifiStr, undefined, 2);
61786
+ if(bInputid) html += this.getLink('mn6_symmetry', 'from PDB(precalculated) ' + me.htmlCls.wifiStr, undefined, 2);
61694
61787
 
61695
61788
  html += this.getLink('mn6_symd', 'from SymD(Dynamic) ' + me.htmlCls.wifiStr, undefined, 2);
61696
61789
  html += this.getLink('mn6_clear_sym', 'Clear SymD Symmetry', undefined, 2);
@@ -64423,7 +64516,7 @@ class Events {
64423
64516
  }
64424
64517
  }
64425
64518
 
64426
- async readFile(bAppend, files, index, dataStrAll, bmmCIF, bPng) { let me = this.icn3dui, ic = me.icn3d, thisClass = this;
64519
+ async readFile(bAppend, files, index, dataStrAll, bmmCIF, bPng, fileType) { let me = this.icn3dui, ic = me.icn3d, thisClass = this;
64427
64520
  let file = files[index];
64428
64521
  let commandName = (bAppend) ? 'append': 'load';
64429
64522
  commandName += (bmmCIF) ? ' mmcif file ' : (bPng) ? ' png file ' : ' pdb file ';
@@ -64473,7 +64566,7 @@ class Events {
64473
64566
  ic.dAtoms = {};
64474
64567
  }
64475
64568
  if(bmmCIF) {
64476
- await ic.mmcifParserCls.loadMultipleMmcifData(dataStrAll, undefined, bAppend);
64569
+ await ic.mmcifParserCls.loadMultipleMmcifData(dataStrAll, undefined, bAppend, fileType);
64477
64570
  }
64478
64571
  else {
64479
64572
  await ic.pdbParserCls.loadPdbData(dataStrAll, undefined, undefined, bAppend);
@@ -64499,7 +64592,12 @@ class Events {
64499
64592
  };
64500
64593
 
64501
64594
  if (typeof file === "object") {
64502
- reader.readAsText(file);
64595
+ if(bmmCIF && fileType == 'bcif') {
64596
+ reader.readAsArrayBuffer(file);
64597
+ }
64598
+ else {
64599
+ reader.readAsText(file);
64600
+ }
64503
64601
  }
64504
64602
  }
64505
64603
 
@@ -68034,8 +68132,8 @@ class Events {
68034
68132
  let fileName = file.name;
68035
68133
 
68036
68134
  let fileType = fileName.substr(fileName.lastIndexOf('.') + 1).toLowerCase();
68037
- if(fileType == 'pdb' || fileType == 'mmcif' || fileType == 'png') {
68038
- await me.htmlCls.eventsCls.readFile(true, files, i, '', (fileType == 'mmcif'), (fileType == 'png'));
68135
+ if(fileType == 'pdb' || fileType == 'mmcif' || fileType == 'cif' || fileType == 'bcif' || fileType == 'png') {
68136
+ await me.htmlCls.eventsCls.readFile(true, files, i, '', (fileType == 'mmcif' || fileType == 'cif' || fileType == 'bcif'), (fileType == 'png'), fileType);
68039
68137
  }
68040
68138
  else if(fileType == 'bcf') {
68041
68139
  await thisClass.openBcf(file);
@@ -124459,8 +124557,9 @@ class MmcifParser {
124459
124557
  }
124460
124558
  }
124461
124559
 
124462
- async loadMultipleMmcifData(data, mmcifid, bAppend) { let ic = this.icn3d; ic.icn3dui;
124463
- let bText = true;
124560
+ async loadMultipleMmcifData(data, mmcifid, bAppend, fileType) { let ic = this.icn3d; ic.icn3dui;
124561
+ let bText = (fileType == 'bcif') ? false : true;
124562
+
124464
124563
  ic.loadCIFCls.loadCIF(data, mmcifid, bText, bAppend);
124465
124564
 
124466
124565
  if(Object.keys(ic.structures).length > 1) {
@@ -133928,11 +134027,14 @@ class LoadPDB {
133928
134027
  prevCarbonArray.push(atom);
133929
134028
  }
133930
134029
 
134030
+ // remove trailing digits in the residue name, e.g., "Na1" -> "NA"
134031
+ let resnSimple = atom.resn.trim().replace(/\d+$/, '').toUpperCase();
134032
+
133931
134033
  if(atom.resn === 'HOH' || atom.resn === 'WAT' || atom.resn === 'SOL') {
133932
134034
  ic.water[atom.serial] = 1;
133933
134035
  atom.color = me.parasCls.atomColors[atom.elem];
133934
134036
  }
133935
- else if($.inArray(atom.resn.trim(), me.parasCls.ionsArray) !== -1 || atom.elem.trim() === atom.resn.trim()) {
134037
+ else if($.inArray(resnSimple, me.parasCls.ionsArray) !== -1 || $.inArray(atom.elem.trim().toUpperCase(), me.parasCls.ionsArray) !== -1 || atom.elem.trim() === atom.resn.trim()) {
133936
134038
  ic.ions[atom.serial] = 1;
133937
134039
  atom.color = me.parasCls.atomColors[atom.elem];
133938
134040
  }
@@ -133983,6 +134085,13 @@ class LoadPDB {
133983
134085
  }
133984
134086
  } // end of for
133985
134087
 
134088
+ 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) {
134089
+ for(let serial in ic.ions) {
134090
+ let atom = ic.atoms[serial];
134091
+ me.parasCls.vdwRadii[atom.elem.toUpperCase()] = me.parasCls.ionRadii[atom.elem.toUpperCase()];
134092
+ }
134093
+ }
134094
+
133986
134095
  // last residue
133987
134096
  //refreshBonds();
133988
134097
  this.refreshBonds(curResAtoms, prevCarbonArray[0]);
@@ -134332,7 +134441,20 @@ class LoadCIF {
134332
134441
  return secondarySet.has(resid.substr(resid.indexOf('_') + 1));
134333
134442
  }
134334
134443
 
134335
- loadCIF(bcifData, bcifid, bText, bAppend) { let ic = this.icn3d, me = ic.icn3dui;
134444
+ loadCIF(bcifData, bcifid, bText, bAppend, supercell) { let ic = this.icn3d, me = ic.icn3dui;
134445
+ ic.cifText = bText;
134446
+ ic.cifData = bcifData;
134447
+
134448
+ if(supercell === undefined) {
134449
+ CIFTools.Text.coreCifOptions = { nx: 1, ny: 1, nz: 1, boundary: true };
134450
+ }
134451
+ else if(supercell === 0) {
134452
+ CIFTools.Text.coreCifOptions = { nx: 1, ny: 1, nz: 1, boundary: false };
134453
+ }
134454
+ else {
134455
+ CIFTools.Text.coreCifOptions = { nx: supercell, ny: supercell, nz: supercell, boundary: true };
134456
+ }
134457
+
134336
134458
  let hAtoms = {};
134337
134459
 
134338
134460
  let bNMR = false;
@@ -134385,7 +134507,6 @@ class LoadCIF {
134385
134507
  helixStart = [];
134386
134508
  helixEnd = [];
134387
134509
 
134388
-
134389
134510
  // bcifData could be binary or text
134390
134511
  let parsed = (bText) ? CIFTools.Text.parse(cifArray[index]) : CIFTools.Binary.parse(cifArray[index]);
134391
134512
 
@@ -135185,17 +135306,19 @@ class LoadCIF {
135185
135306
  }
135186
135307
  }
135187
135308
  else if(atom.het) {
135309
+ let resnSimple = atom.resn.trim().replace(/\d+$/, '').toUpperCase();
135310
+
135188
135311
  if(atom.resn === 'HOH' || atom.resn === 'WAT' || atom.resn === 'SOL') {
135189
135312
  ic.water[atom.serial] = 1;
135190
135313
  }
135191
- else if($.inArray(atom.resn, me.parasCls.ionsArray) !== -1 || atom.elem.trim() === atom.resn.trim()) {
135314
+ else if($.inArray(resnSimple, me.parasCls.ionsArray) !== -1 || $.inArray(atom.elem.trim().toUpperCase(), me.parasCls.ionsArray) !== -1 || atom.elem.trim() === atom.resn.trim()) {
135192
135315
  ic.ions[atom.serial] = 1;
135193
135316
  }
135194
135317
  else {
135195
135318
  ic.chemicals[atom.serial] = 1;
135196
135319
  }
135197
135320
 
135198
- atom.color = me.parasCls.atomColors[atom.elem];
135321
+ atom.color = me.parasCls.atomColors[atom.elem.toUpperCase()];
135199
135322
  }
135200
135323
 
135201
135324
  if(!(curChain === atom.chain && curResi === atom.resi)) {
@@ -135216,6 +135339,13 @@ class LoadCIF {
135216
135339
  }
135217
135340
  } // end of for
135218
135341
 
135342
+ 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) {
135343
+ for(let serial in ic.ions) {
135344
+ let atom = ic.atoms[serial];
135345
+ me.parasCls.vdwRadii[atom.elem.toUpperCase()] = me.parasCls.ionRadii[atom.elem.toUpperCase()];
135346
+ }
135347
+ }
135348
+
135219
135349
  // last residue
135220
135350
  //refreshBonds();
135221
135351
  ic.loadPDBCls.refreshBonds(curResAtoms, prevCarbonArray[0]);
@@ -136294,6 +136424,12 @@ class ApplyCommand {
136294
136424
  else if(command == 'set assembly off') {
136295
136425
  ic.bAssembly = false;
136296
136426
  }
136427
+ else if(command.indexOf('set supercell') !== -1) {
136428
+ let pos = command.lastIndexOf(' ');
136429
+ let supercell = parseInt(command.substr(pos + 1));
136430
+
136431
+ await me.htmlCls.clickMenuCls.setSupercell(supercell);
136432
+ }
136297
136433
  else if(command == 'set chemicalbinding show') {
136298
136434
  ic.setOptionCls.setOption('chemicalbinding', 'show');
136299
136435
  }
@@ -140949,7 +141085,7 @@ class Selection {
140949
141085
 
140950
141086
  resetAll() { let ic = this.icn3d, me = ic.icn3dui;
140951
141087
  ic.maxD = ic.oriMaxD;
140952
- ic.center = ic.oriCenter.clone();
141088
+ ic.center = (ic.oriCenter) ? ic.oriCenter.clone() : new THREE.Vector3(0, 0, 0);
140953
141089
 
140954
141090
  ic.opts = me.hashUtilsCls.cloneHash(ic.optsOri);
140955
141091
 
@@ -149254,7 +149390,7 @@ class Transform {
149254
149390
 
149255
149391
  //reset ic.maxD
149256
149392
  ic.maxD = ic.oriMaxD;
149257
- ic.center = ic.oriCenter.clone();
149393
+ ic.center = (ic.oriCenter) ? ic.oriCenter.clone() : new Vector3$1(0, 0, 0);
149258
149394
 
149259
149395
  if(ic.ori_chemicalbinding == 'show') {
149260
149396
  ic.bSkipChemicalbinding = false;
@@ -153988,7 +154124,7 @@ class iCn3DUI {
153988
154124
  //even when multiple iCn3D viewers are shown together.
153989
154125
  this.pre = this.cfg.divid + "_";
153990
154126
 
153991
- this.REVISION = '3.54.2';
154127
+ this.REVISION = '3.54.3';
153992
154128
 
153993
154129
  // In nodejs, iCn3D defines "window = {navigator: {}}", and added window = {navigator: {}, "__THREE__":"177"}
153994
154130
  this.bNode = (Object.keys(window).length < 3) ? true : false;