// compstru_bh.js
// A script for creating the compstru report page Jmol capability
// Bob Hanson and Ben Hinke, St. Olaf College
// BH 5/30/2018 11:12:27 PM
// put your j2s path here
var j2sPath = "/html/jsmol/j2s";
var loc = document.location.href;
if (loc.indexOf("file") == 0) {
j2sPath = "../jsmol/j2s";
} else if (loc.indexOf("https://chemapps.stolaf") >= 0) {
j2sPath = "https://chemapps.stolaf.edu/jmol/jsmol/j2s";
}
highlightData = function(n, color) {
listPre = $("pre");
if (listPre.length == 0)
return;
if (n == 0) {
for (var i = 0; i < 3; i++) {
listPre[i].style.margin = "10px";
listPre[i].style.padding = "10px";
listPre[i].style.border = "4px solid white";
}
return;
}
listPre[n - 1].style.border = "4px solid " + color;
}
var refcolor = "black";
var othercolor = "lightgreen";
var introText = "
Drag the model with your mouse to view it from different perspectives."
+" Click on two atoms to measure their distance in Angstroms."
var infoText = {
structure1: "This is Structure #1.
It is the reference structure.",
structure2: "This is Structure #2.
It will be compared with the reference structure.",
structure3: "This is Structure #2, described with a unit cell and offset that most closely matches the lattice and atom positions of structure #1.",
compareStructures: "The reference structure is shown, with its unit cell in " + refcolor
+ ". Structure #2 is shown, with its unit cell in " + othercolor
+ ". Its unit cell and offset have been calculated to be the best possible"
+ " fit to the reference structure. Scroll down to see details of the analysis.",
compareLattices: "Shown here is structure #2 with both its original unit cell (" + refcolor
+ ") and its transformed unit cell (" + othercolor +") shown together.",
compareBases: "This is the most similar description of structure #2 compared to the reference structure, both described using the unit cell of the reference."
+ " As such, the second structure here is not a real structure. "
+ " This depiction is useful in that it allows a comparison of the atomic displacements irrespective"
+ " of differences in lattices. This comparison is used for the u, "
+ " dmax, and dave parameters discussed in the analysis."
}
showInfo = function(info) {
$("#infodiv").html(info ? info + introText : "");
}
selectType = function(n, mode) {
var script = "";
switch(mode) {
case -1:
script = "color translucent;"
break;
case 0:
script = "color opaque;"
break;
case 1:
script = "spacefill only;spacefill 23%;wireframe 0.15;";
break;
case 2:
script = "wireframe -0.05;";
break;
case 3:
script = "star -0.4;";
break;
}
// alert(n + ":" + structureType);
switch(n + ":" + structureType) {
case "1:1":
case "2:2":
script = "select 1.1;" + script;
break;
case "1:3 and 1":
case "1:3 as 1":
script = "select 1.1;" + script;
break;
case "2:3 and 1":
case "2:3 as 1":
script = "select 2.1;" + script;
break;
case "2:3 and 2":
// all
break;
default:
return;
}
Jmol.script(jmol, script);
}
setRendering = function(n) {
var d;
for (var i = 0; i < 3; i++) {
d = $("#seltype" + n + "_" + i);
if (d[0].checked) {
selectType(n,i+1);
break;
}
}
d = $("#opaque" + n);
selectType(n, d[0].checked ? 0 : -1);
}
getStructure = function(n) {
var data = document.getElementsByName("stru")[(n-1)*2].value;
return data
}
showDistance = function() {
var num1 = parseFloat(document.getElementById("distnum").value);
if (isNaN(num1))
num1 = 0.5;
var script = 'set labelfor {*} ""; '
+ 'cscheme = "bwr";'
+ 'c = {fx<0.99 & fy <0.99 & fz <0.99 && fx>=-0.01 & fy >=-0.01 & fz >=-0.01};'
+ 'rmax = 1.0;'
+ 's1= {1.1 & c}; s2 = {2.1 & c};'
+ 'x=s2.distance.min({1.1}); s2.property_d = x; select s2; label %3.3[property_d];'
+ 'select {2.1}; color property_d @cscheme range 0 @rmax; z=x.max.format("%3.3f"); y=x.min.format("%3.3f");'
+ 'info = getProperty("auxiliaryinfo.models");'
+ 'abc1 = info[1].unitCellParams; abc2 = info[2].unitCellParams;'
+ 'a1 = abc1[1]; b1 = abc1[2]; c1 = abc1[3];'
+ 'a2 = abc2[1]; b2 = abc2[2]; c2 = abc2[3];'
+ 'dd = b2/b1*c2/c1*a1/a2*a1/a2;'
+ 'dc = s2.fxyz.all.distance.min({1.1}.fxyz.all).average;'
+ 'delta = (sqrt(2) * dc + 1) * (dd < 1 ? 1 / dd : dd) - 1;'
+ 'delta=delta.format("%3.3f") ;set echo bottom left;'
+ 's = "
";'
+ 'for (var a in s2) {\n'
+ ' var b = [a].fxyz.distance.min({1.1}.fxyz.all);'
+ ' var c = [a].xyz.distance.min({1.1}.xyz.all);'
+ ' s += "
" + a.label("%a") + "
" + b + "
" + c + "
";'
+ '}\n'
+ ' s += "
";'
if (structureType == '3 and 1') {
script +='caption="\u2206=@{delta}";';
} else {
script += 'cmin=("" + color(cscheme,0,rmax,y)).replace("{","[").replace("}","]").replace(" ",",");'
+ 'cmax=("" + color(cscheme,0,rmax,z)).replace("{","[").replace("}","]").replace(" ",",");'
+ 'caption="min=@{y}max=@{z}";';
}
script += 'echo @caption;select *;labels off; font labels 20;background labels yellow;set labelfor {property_d >' + num1 + '} "%3.3[property_d]"'
Jmol.scriptWait(jmol, script)
var s = Jmol.evaluateVar(jmol,"s");
$("#results").html(s);
}
var structureType = null;
loadStructure = function(n1,n2,bases) {
highlightData(0);
script = "na = {*}; if (na and !dontsetorientation){save orientation a};load data 'mydata'\n"
+ getStructure(n1) + "\nend 'mydata' {444 666 1};\ndisplay cell=555;"
+"if (na and !dontsetorientation){restore orientation a}else{zoom *2.5;save orientation a};unitcell 2;color unitcell "
+ (n1 == 1 ? refcolor : othercolor) + ";dontsetorientation = false;set picking measure;";
if(bases) {
$("#divfile")[0].style.visibility = 'hidden';
$("#divdist")[0].style.visibility = 'visible';
structureType = "3 as 1";
// This is Bob's idea for comparing bases
// n1 == 1; n2 == 3
// The third structure is loaded using the unit cell of #1 and compared to #1
var struc1 = getStructure(n1).split("\n");
var struc2 = getStructure(n2).split("\n");
struc2[1] = struc1[1];
script += ";load data 'append'\n" + struc2.join("\n")
+ "\nend 'append' packed 0.2; frame all;restore orientation a;display cell=555;";
highlightData(n1, refcolor);
highlightData(n2, refcolor);
showInfo(infoText["compareBases"]);
} else if(n2) {
if (n1 == 1) {
// compare structures
$("#divfile")[0].style.visibility = 'hidden';
$("#divdist")[0].style.visibility = 'visible';
structureType = "3 and 1";
script += ";load data 'append'\n" + getStructure(3)
+ "\nend 'append' packed 0.2; frame all;restore orientation a;display cell=555;"
+ "unitcell {1.1}; draw width 0.1 unitcell mesh nofill color " + refcolor
+ "; unitcell {2.1}; unitcell 2; color unitcell " + othercolor + ";";
highlightData(n1, refcolor);
highlightData(n2, othercolor);
showInfo(infoText["compareStructures"]);
} else {
// compare lattices
$("#divfile")[0].style.visibility = 'hidden';
$("#divdist")[0].style.visibility = 'hidden';
// this is Bob's idea of overlaying structure 2 and structure 3, properly transformed.
// a bug in Jmol requires converting 1/2 to 0.5
structureType = "3 and 2";
cellOffset = transform.split(";")[1];
if (cellOffset.indexOf("/") >= 0) {
var a = cellOffset.split(",");
for (var i = 0; i < 3; i++)
a[i] = eval(a[i]);
cellOffset = a.join(",");
transform = transform.split(";")[0] + ";" + cellOffset;
}
script += ';load append "" supercell "'
+ '!' + transform + '";frame *;unitcell {2.1};unitcell 2;select 2.1;translateSelected @{-{' + cellOffset + '/1}};'
+ 'unitcell offset @{-{' + cellOffset + '}};draw width 0.1 unitcell mesh nofill color ' + refcolor
+ ';unitcell {1.1};unitcell 2;zoomto {visible} 0;dontsetorientation=true';
highlightData(n1, refcolor);
highlightData(n2, othercolor);
showInfo(infoText["compareLattices"]);
}
} else {
// one of the structures
$("#divfile")[0].style.visibility = 'visible';
$("#divdist")[0].style.visibility = 'hidden';
structureType = n1; // 1, 2, or 3
highlightData(n1, (n1 == 1 ? refcolor : othercolor));
setRendering(n1 == 1 ? 1 : 2);
showInfo(infoText["structure"+n1]);
}
//showInfo("
"+script + "
");
Jmol.scriptWait(jmol, script)
if (n1)
setRendering(n1 == 1 ? 1 : 2);
if (n2)
setRendering(2);
//var atomNames = Jmol.evaluateVar(jmol, "{1.1}.atomname.pivot.keys")
//alert(JSON.stringify(atomNames))
//var s = ""
//};
//jQuery $("#atomNames").html(s);
}
var script = "set antialiasdisplay; set zoomlarge false; set picking measure;set measurementunits angstroms";
var transform;
jmolReady = function() {
loadStructure(1);
$("#seltype1_0").click();
$("#seltype2_0").click();
transform = $("body").html().split("Transformation matrix (P, p): ")[1].split("
")[0].replace(/\<\/b\>/,"").replace(/\s+/g,"");
//showInfo("The applet is ready.");
}
var Info = {
width: 600,
height: 600,
script: script,
use: "HTML5",
j2sPath: j2sPath,
isSigned: false,
addSelectionOptions: false,
serverURL: "https://chemapps.stolaf.edu/jmol/jsmol/php/jsmol.php",
readyFunction: jmolReady,
// console: "jmol_infodiv",
// disableInitialConsole: true,
defaultModel: null,
debug: false
}
$(document).ready(function(){
// This demonstration shows that
// what is put on the page can depend upon the platform.
// Note that the use of $(document.ready()) is optional but preferred.
// You can do the traditional in-body coding if you want. See also simple2-nojq.htm.
// But as Gusts Kaksis pointed out, if we are using jQuery for database lookups, we might
// as well use it for more than that.
// note that we create the applet first, before the controls, because
// we need window.jmol to be defined for those, and Jmol.getAppletHtml does that.
$("#middlepanel").html(Jmol.getAppletHtml("jmol", Info));
// alternatively, you can use
//
// jmol = "jmol"
//
// and then create the buttons before the applet itself.
// Just make sure if you do that to use the name of the applet you are
// actually going to be using. So, perhaps:
//
// jmolApplet0 = "jmolApplet0"
//
var use = (Info.use != "JAVA" ? Info.use : Info.isSigned ? "SIGNED" : "JAVA");
var radios = [
["set background white", "white", true],
["set background black", "black"]
];
// right panel
Jmol.setButtonCss(null, "style='width:200px'");
$("#rightpanel").html(
" "
+ Jmol.jmolButton(jmol,[function(){loadStructure(1)}],"Structure #1")
+ " "
+ Jmol.jmolButton(jmol,[function(){loadStructure(2)}],"Structure #2")
+ " "
+ " "
+ Jmol.jmolButton(jmol,[function(){loadStructure(3)}],"Structure #2 (most similar)")
+ "