10
0
mirror of https://github.com/LCPQ/QUESTDB_website.git synced 2024-11-04 13:13:55 +01:00
QUESTDB_website/content/dataset.html

855 lines
31 KiB
HTML
Raw Normal View History

2019-09-28 15:23:25 +02:00
---
title: "Dataset"
2019-09-28 15:23:25 +02:00
date: 2019-09-27 16:41
draft: false
---
<link rel="stylesheet" type="text/css" href="/css/modal.css" />
<link rel="stylesheet" type="text/css" href="/css/form.css" />
2019-12-29 20:00:13 +01:00
<link rel="stylesheet" type="text/css" href="/css/table.css" />
2020-02-16 18:09:37 +01:00
<link rel="stylesheet" type="text/css" href="/css/emoji.css" />
<script src="/js/data.js" type="text/javascript"></script>
<script src="/js/loadAllData.js" type="text/javascript"></script>
<script src="/js/getFullDataPath.js" type="text/javascript"></script>
<script src="/js/getTextFromFile.js" type="text/javascript"></script>
<script src="/js/trueTypeOf.js" type="text/javascript"></script>
<script src="/js/uniq.js"></script>
<script src="/js/processingIndicator.js"></script>
<script src="/js/noNan.js"></script>
<script src="/js/websiteFile.js"></script>
<script src="/js/PubliData.js"></script>
<script src="/js/nestedCheckbox.js"></script>
<script src="/js/selectSelectAll.js"></script>
2020-04-08 11:34:52 +02:00
<script src="/js/numberRangeChange.js"></script>
2020-06-10 15:18:39 +02:00
<script src="/js/DebugMode.js"></script>
2020-02-04 09:44:48 +01:00
<script src="/js/numberUtils.js"></script>
2020-09-20 17:53:58 +02:00
<script src="/js/indexDB.js"></script>
<script src="/js/ArrayExtensions.js"></script>
2020-09-28 09:31:11 +02:00
<script src="/js/mhchemCE.js"></script>
2020-09-24 16:55:51 +02:00
<link rel="stylesheet" href="/css/ChemDoodleWeb.css" type="text/css">
<script type="text/javascript" src="/js/ChemDoodleWeb.js"></script>
2020-09-28 15:41:23 +02:00
<script src="/js/Geometry.js"></script>
<script src="/js/GeometriesLoader.js"></script>
<script src="/js/GeometryParseMetadataExtension.js"></script>
2019-09-28 15:23:25 +02:00
<script>
function adjustSticky() {
const height = $("nav").height()
$("thead.sticky > tr > th ").css("top", height)
}
2019-10-09 20:10:48 +02:00
window.onload = async () => {
window.browser = bowser.getParser(window.navigator.userAgent);
2020-05-19 10:30:28 +02:00
$("input[type='checkbox']").trigger("change")
2020-04-08 11:34:52 +02:00
$("input[type='number'].range").trigger("change")
adjustSticky();
$(window).resize(adjustSticky)
2020-04-23 17:12:33 +02:00
2020-01-28 17:33:56 +01:00
var slist = $("#SelectList")
getAllSelect().each(function () {
$("<li/>").text($('label[for="' + $(this).attr('id') + '"]').text()).appendTo(slist)
})
$('[data-needbrowser],[data-neednotbrowser]').each(function () {
function test(key, value) {
2020-02-04 12:07:03 +01:00
switch (key) {
case "Engine":
return value.some((v) => browser.isEngine(v))
2020-02-04 12:07:03 +01:00
break;
case "Browser":
return value.some((v) => browser.isBrowser(v))
2020-02-04 12:07:03 +01:00
case "Platform":
return value.some((v) => browser.isPlatform(v))
2020-02-04 12:07:03 +01:00
case "OS":
return value.some((v) => browser.isOS(v))
2020-02-04 12:07:03 +01:00
default:
return true
break;
}
}
const needdata = $(this).data("needbrowser")
const neednotdata = $(this).data("neednotbrowser")
const need = ((needdata == null) ? true : Object.entries(needdata).every(kv => test(kv[0], kv[1])))
const neednot = ((neednotdata == null) ? true : Object.entries(neednotdata).some(kv => !test(kv[0], kv[1])))
if (need && neednot) {
$(this).show()
2020-02-04 12:07:03 +01:00
} else {
$(this).hide()
}
})
var cbextl = $("#cb_exTypeList")
2020-01-28 17:33:56 +01:00
var extl = $("#exTypeList")
var vertkindtl = $("#exVertKindList")
2020-01-28 17:33:56 +01:00
for (const [name, value] of VertExcitationKinds.All) {
$("<li/>").text(name).appendTo(vertkindtl)
}
2020-01-03 17:12:43 +01:00
for (const [name, value] of excitationTypes.All) {
2020-04-14 15:59:05 +02:00
var txt = value.description.string
if (value.description.isLaTeX) {
2020-04-23 17:12:33 +02:00
txt = MathJaxUtils.getMathJaxString(txt)
2019-12-19 12:19:32 +01:00
}
$("<li/>").text(txt).appendTo(extl)
var cbli = $("<li/>")
if (!DebugMode.Enabled && value == (1 << 31)) {
2020-06-10 15:18:39 +02:00
cbli.hide()
}
$("<input/>", { type: "checkbox", id: "cb_" + name, name: name, value: Number(value) }).change(nestedCheckbox_change).appendTo(cbli);
$('<label />', { 'for': 'cb_' + name, text: txt }).appendTo(cbli);
cbextl.append(cbli);
}
await MathJax.typesetPromise();
delete (cbextl)
2020-01-28 17:33:56 +01:00
delete (extl)
delete (vertkindtl)
window.publiCache = new Map()
await loadFiles()
}
async function loadFiles() {
processingIndicator.isActive = true
var data = await loadAllData()
window.defaultDats = []
2020-05-24 18:49:16 +02:00
for (const sub of Object.values(data)) {
2020-09-20 17:53:58 +02:00
for (const exSet of uniq(sub.map(d => d.set))) {
const subset = sub.filter(d => d.set.isSameSet(exSet))
for (mol of uniq(subset.map(d => d.molecule))) {
const submol = subset.filter(d => d.molecule === mol)
const source = await submol.findAsync(async (d) => {
2020-09-20 17:53:58 +02:00
if (await d.set.getDOIAsync() === "10.1021/acs.jctc.8b01205") {
2020-04-14 15:59:05 +02:00
return d.method.name === "CASPT2" && d.method.basis === "aug-cc-pVDZ"
2020-03-31 14:28:45 +02:00
} else {
return d.method.isTBE
}
})
if (source !== undefined) {
2020-08-11 12:24:34 +02:00
for (const dat of submol.filter((d) => d !== source)) {
2020-03-31 14:28:45 +02:00
dat.CopyExcitationsTypeFrom(source)
}
}
2020-01-15 13:10:21 +01:00
}
}
window.defaultDats = window.defaultDats.concat(sub)
2020-01-15 13:10:21 +01:00
}
await indexDB.loadAsync()
2020-09-20 17:53:58 +02:00
window.defaultDats = window.defaultDats.sort((datfA, datfB) => {
const exSetA = datfA.set
const exSetB = datfB.set
if (exSetA.isSameSet(exSetB)) {
return exSetA.index-exSetB.index
}
else {
2020-09-20 17:53:58 +02:00
setNames = Array.from(window.indexDB.sets.keys())
return setNames.indexOf(exSetA.name)-setNames.indexOf(exSetB.name)
}
2020-05-04 14:13:25 +02:00
})
processingIndicator.isActive = false
2020-09-29 12:13:00 +02:00
await reloadGeoms()
2020-09-29 11:45:05 +02:00
reloadCustomFiles()
2020-09-28 15:41:23 +02:00
}
async function reloadGeoms(){
2020-09-29 11:47:22 +02:00
processingIndicator.isActive = true
2020-09-28 15:41:23 +02:00
window.geoms = await GeometriesLoader.loadForAsync(uniq(window.defaultDats.map(d=>{
return {
set:d.set.name,
molecule:d.molecule
}
})))
2020-09-29 12:13:00 +02:00
processingIndicator.isActive = false
reloadSizeSelector()
}
function reloadSizeSelector() {
if (window.geoms && window.dats) {
const nHnums=window.geoms.map((g)=>{
return g.molecule.atoms.count((a)=>a.label!=="H")
})
2020-09-29 15:25:14 +02:00
const nHmin = ss.min(nHnums)
const nMin=$("#nHmin")
nMin.attr("min",nHmin)
const nHmax = ss.max(nHnums)
const nMax=$("#nHmax")
nMax.attr("max",nHmax)
var init = nMin.attr("data-init")
if (typeof init !== undefined && init !== false) {
nMin.removeAttr("data-init")
nMin.val(nHmin)
updateNumberRange(nMin[0])
}
init = nMax.attr("data-init")
if (typeof init !== undefined && init !== false) {
nMin.removeAttr("data-init")
nMax.val(nHmax)
updateNumberRange(nMax[0])
}
2020-09-29 12:13:00 +02:00
const mols = uniq(window.geoms.map(g=>g.parseMetadata().molecule))
const shownHunknow=window.dats.some((d)=>!mols.includes(d.molecule))
const nHUnknowDiv = $("#cb_nHUnknow").parent()
if (shownHunknow) {
nHUnknowDiv.show()
}
else{
nHUnknowDiv.hide()
}
2020-09-29 11:47:22 +02:00
}
2019-09-28 15:23:25 +02:00
}
async function reloadCustomFiles() {
2020-09-29 11:47:22 +02:00
processingIndicator.isActive = true
window.dats = window.defaultDats;
const kinds = new Map([["file_abs", VertExcitationKinds.Absorbtion], ["file_fluo", VertExcitationKinds.Fluorescence]])
2020-05-18 18:22:18 +02:00
for (const el of $('#form_dat > fieldset > fieldset > div > input[type="file"')) {
if (kinds.has(el.name)) {
for (const f of el.files) {
const dat = await VertDataFile.loadAsync(f, kinds.get(this.name))
2019-10-02 19:20:37 +02:00
window.dats.push(dat)
}
2019-10-02 19:20:37 +02:00
}
}
2020-09-29 11:47:22 +02:00
processingIndicator.isActive = false
2020-09-29 12:13:00 +02:00
reloadSizeSelector()
2020-09-20 17:53:58 +02:00
reloadSelect("sets")
}
async function clearSelect(BeforeName = null) {
var selects = ((BeforeName == null) ? getAllSelect() : getAllSelectAfter(BeforeName, true))
selects.add($('#sel_ref'))
selects.each(function () {
2020-01-13 09:35:15 +01:00
$(this).empty()
2019-10-10 09:49:39 +02:00
})
2020-01-27 11:16:57 +01:00
}
function getAllSelect() {
2020-05-18 18:22:18 +02:00
return $('#form_dat > fieldset > fieldset > div > select')
}
2020-01-28 17:33:56 +01:00
function getAllSelectAfter(Name, include = false) {
const selects = getAllSelect()
var index = selects.index($(`[name="${Name}"]`))
if (!include) {
index++
}
return selects.slice(index)
}
function getAllSelectBefore(Name, include = false) {
2020-01-28 17:33:56 +01:00
const selects = getAllSelect()
var index = selects.index($(`[name="${Name}"]`))
if (include) {
index++
}
return selects.slice(0, index)
}
async function reloadNextSelect(e) {
2020-01-28 17:33:56 +01:00
const afters = getAllSelectAfter(e.target.name)
const isLast = afters.length == 0
if (!isLast) {
await reloadSelect(afters.prop("name"))
}
2020-09-03 17:12:08 +02:00
if (afters.prop("name") ==="molecule"){
selectSelectAll(afters.first())
}
}
function getAllVals(select) {
2020-09-20 17:53:58 +02:00
return $(select).val()
}
async function reloadSelect(name) {
clearSelect(name)
var selects = getAllSelectBefore(name, true)
var currentselect = selects.last()
2020-01-28 17:33:56 +01:00
selects = selects.slice(0, selects.length - 1)
2020-08-24 12:35:05 +02:00
var AllValsCache = new Map()
selects.each(function() {
AllValsCache.set(this.name,getAllVals(this))
})
2020-08-24 12:35:05 +02:00
var AAllValsCache = Array.from(AllValsCache)
var vals = uniq(window.dats.filter(d => {
2020-08-24 12:35:05 +02:00
return AAllValsCache.every(([k,v]) => {
return v.indexOf(getSelectValue(d, k)) !== -1
})
}).map((d) => getSelectValue(d, name)))
2020-09-21 11:13:36 +02:00
if (name!="sets") {
vals = vals.sort((a,b)=>{
a = textSelctor(a)
b = textSelctor(b)
if (a === b) {
return 0
}
else {
switch (name) {
case "method":
if (a.startsWith("TBE") && b.startsWith("TBE")) {
return (a === "TBE" ? -1 : 1)
}
else if(a.startsWith("TBE")) {
return -1
}
else if (b.startsWith("TBE")) {
return 1
}
else {
return a.localeCompare(b)
}
break;
case "basis":
if (a === "aug-cc-pVTZ") {
return -1
}
else if (b === "aug-cc-pVTZ") {
2020-10-09 10:32:02 +02:00
return 1
2020-09-21 11:13:36 +02:00
}
else {
return a.localeCompare(b)
}
case "sets":
return 0
default:
return a.localeCompare(b)
}
}
})
}
textSelctor = function (value) {
2020-04-27 16:50:17 +02:00
switch (name) {
2020-09-20 17:53:58 +02:00
case "sets":
if (value==="") {
return "Unnamed set"
}
2020-04-27 16:50:17 +02:00
case "molecule":
2020-09-28 09:31:11 +02:00
return mhchemCE.extract(value)
2020-04-27 16:50:17 +02:00
break;
default:
return value.toString()
}
}
valueSelector = function (value) {
if (typeof value === 'object') {
return JSON.stringify(value)
}
else {
return value
}
}
for (const val of vals) {
if (val !== null) {
$("<option/>", {
value: valueSelector(val)
2020-04-27 16:50:17 +02:00
}).text(textSelctor(val)).appendTo(currentselect)
2019-10-09 17:53:10 +02:00
}
2020-04-27 16:50:17 +02:00
}
}
function getSelectValue(data, name) {
switch (name) {
case "method":
return data.method.name
break;
case "basis":
return data.method.basis
2020-09-20 17:53:58 +02:00
break;
case "sets":
return data.set.name
break;
default:
return data[name]
break;
}
2019-09-28 15:23:25 +02:00
}
2019-10-09 20:10:48 +02:00
async function reloadStat() {
processingIndicator.isActive = true
var stb = $("#stat_table > tbody")
2019-10-09 17:53:10 +02:00
$("#graph_div").empty()
$(stb).empty()
var refstr = $("#sel_ref option:selected").val()
2019-10-09 20:10:48 +02:00
var sdatdic = new Map()
for (const d of window.filtData) {
2020-05-05 13:12:09 +02:00
const key = JSON.stringify(d.method)
2020-09-20 17:53:58 +02:00
const SetName = d.set.name
2019-10-09 20:10:48 +02:00
if (!(sdatdic.has(key))) {
sdatdic.set(key, new Map())
2019-10-01 14:37:26 +02:00
}
2020-09-04 12:15:37 +02:00
const myT1s = T1ref.get(SetName).get(d.molecule)
2019-10-09 20:10:48 +02:00
for (const exc of d.excitations) {
2020-04-14 15:59:05 +02:00
var allowT1 = false
const T1Key = JSON.stringify((exc.initial, exc.final))
const T1range = filterParams.T1
if (T1range.min === 0 && T1range.max === 100) {
allowT1 = true
2020-04-08 11:34:52 +02:00
} else if (myT1s.has(T1Key)) {
2020-04-14 15:59:05 +02:00
const T1Val = myT1s.get(T1Key)
if (T1range.min <= T1Val && T1Val <= T1range.max) {
allowT1 = true
2020-04-08 11:34:52 +02:00
}
}
2020-09-03 16:55:26 +02:00
const key2 = JSON.stringify([d.molecule, exc.initial, exc.final, exc.VertExcitationKind])
2019-10-09 20:10:48 +02:00
const keydic = sdatdic.get(key)
2020-04-08 11:34:52 +02:00
if ((!exc.isUnsafe || window.filterParams.unsafe) && ((exc.type & window.filterParams.exType) !== 0) && ((exc.VertExcitationKind & window.filterParams.exVertKind) !== 0) && allowT1) {
2020-01-06 09:45:29 +01:00
if (!(keydic.has(key2))) {
2020-04-14 15:59:05 +02:00
keydic.set(key2, exc.value)
2020-01-06 09:45:29 +01:00
}
2019-10-01 14:37:26 +02:00
}
2019-10-09 20:10:48 +02:00
}
2019-10-01 14:37:26 +02:00
}
2019-10-09 20:10:48 +02:00
var sdic = new Map()
for (const [key, sdat] of sdatdic) {
for (const [key2, exval] of sdat) {
2019-10-09 20:10:48 +02:00
if (!(sdic.has(key))) {
sdic.set(key, [])
2019-10-01 14:37:26 +02:00
}
sdic.get(key).push(exval - ((sdatdic.has(refstr)) ? sdatdic.get(refstr).get(key2) : NaN))
2019-10-01 14:37:26 +02:00
}
}
sdic.delete(refstr)
2019-10-09 20:10:48 +02:00
var graphdat = []
for (const [keystr, vals] of sdic) {
row = $("<tr/>")
key = JSON.parse(keystr)
Reflect.setPrototypeOf(key, method.prototype)
2020-02-20 14:42:40 +01:00
th = $("<th/>", { scope: "column" })
2020-05-05 13:12:09 +02:00
const meth = key
2020-02-20 14:42:40 +01:00
th.clone().text(meth.toString("\n").split('-').join('\u2011')).appendTo(row)
2020-04-14 15:59:05 +02:00
const noNanVals = (vals.every((v) => Number.isNaN(v))) ? vals : (vals.filter((v) => !Number.isNaN(v)))
const avals = noNanVals.map(v => Math.abs(v))
th.clone().text(noNanVals.length).appendTo(row)
for (const val of [ss.min(noNanVals), ss.max(noNanVals), ss.mean(noNanVals), ss.mean(avals), ss.median(noNanVals), ss.median(avals), ss.rootMeanSquare(noNanVals), ss.variance(noNanVals), ss.standardDeviation(noNanVals)]) {
$("<td/>").text(noNanFixed(val, 2)).appendTo(row)
2020-02-20 14:42:40 +01:00
}
2020-04-14 15:59:05 +02:00
$(stb).append(row)
var box = {
x: noNanVals,
amean: ss.mean(avals).toFixed(3),
2020-09-16 09:27:06 +02:00
name: `${key.toString()} MAE : ${ss.mean(avals).toPrecision(4)} eV` ,
2020-04-14 15:59:05 +02:00
type: 'box',
boxmean: 'sd'
};
graphdat.push(box)
}
var layout = {
paper_bgcolor: 'rgba(0,0,0,0)',
plot_bgcolor: 'rgba(0,0,0,0)',
gap: 0,
legend: {
traceorder: 'reversed',
},
xaxis: {
title: {
2020-09-16 09:21:20 +02:00
text: 'Error (eV)',
2020-04-14 15:59:05 +02:00
}
},
bgcolor: '#E2E2E2',
bordercolor: '#FFFFFF',
borderwidth: 2,
// autosize: false,
2020-09-16 10:01:40 +02:00
width: 1275,
height: 750,
2020-04-14 15:59:05 +02:00
margin: {
l: 0,
r: 10,
2020-09-15 16:53:47 +02:00
// b: 15,
2020-04-14 15:59:05 +02:00
t: 20,
pad: 0,
},
}
Plotly.newPlot('graph_div', graphdat, layout);
processingIndicator.isActive = false
2019-10-01 14:37:26 +02:00
}
2019-10-09 20:10:48 +02:00
async function reloadContent() {
2020-04-14 15:59:05 +02:00
window.filterParams = {
unsafe: $("#cb_unsafe").prop("checked"),
exType: Array.from(Array.from($("#cb_exTypeList>li>input[type=checkbox]:checked")).map(el => parseInt(el.value))).reduce((pv, cv) => pv + cv, 0),
exVertKind: Array.from(Array.from($("#cb_exVertKindList>li>input[type=checkbox]:checked")).map(el => parseInt(el.value))).reduce((pv, cv) => pv + cv, 0),
T1: {
min: parseFloat($("#T1min").val()),
max: parseFloat($("#T1max").val())
},
nHnum: {
min: parseInt($("#nHmin").val(),10),
max: parseInt($("#nHmax").val(),10),
allowUnknow:$("#cb_nHUnknow").is(':checked')
2020-04-14 15:59:05 +02:00
}
2020-04-08 11:34:52 +02:00
}
window.publiCache.clear()
2019-10-09 20:10:48 +02:00
processingIndicator.isActive = true
window.filtData = window.dats
//Filter with select
2020-05-18 18:22:54 +02:00
getAllSelect().each(function () {
2019-10-09 20:10:48 +02:00
const prop = $(this).attr("name")
const values = getAllVals(this)
window.filtData = window.filtData.filter((d) => {
2019-10-09 20:10:48 +02:00
if (typeof values == "undefined" || values == null) {
return false
2019-09-28 15:23:25 +02:00
}
2020-01-28 17:33:56 +01:00
return values.includes(getSelectValue(d, prop))
delete (val)
2019-09-28 15:23:25 +02:00
})
})
// Filter with molSize
const allowednHSize=window.filterParams.nHnum
window.filtData=window.filtData.filter((d)=>{
const geom=window.geoms.find((g)=>{
const met=g.parseMetadata()
return met.molecule === d.molecule && JSON.stringify(met.method) === JSON.stringify(d.geometry)
})
if (geom) {
const size = geom.molecule.atoms.count(a=>a.label!=="H")
return (allowednHSize.min <= size && size <= allowednHSize.max)
}
else {
return allowednHSize.allowUnknow
}
})
2020-04-14 15:59:05 +02:00
window.T1ref = new Map()
2020-09-20 17:53:58 +02:00
var exSets = new uniq(window.filtData.map((d) => d.set))
2020-04-08 11:34:52 +02:00
var mols = new Set(window.filtData.map((d) => d.molecule))
2020-09-20 17:53:58 +02:00
for (const exSet of exSets) {
const DOI= await exSet.getDOIAsync()
if (DOI!=null) {
publiCache.set(DOI,await PubliData.loadAsync(DOI))
}
2020-09-20 17:53:58 +02:00
const setName = exSet.name
2020-09-04 12:15:37 +02:00
window.T1ref.set(setName, new Map())
2020-04-08 11:34:52 +02:00
for (const mol of mols) {
2020-09-04 12:15:37 +02:00
window.T1ref.get(setName).set(mol, new Map())
2020-09-20 17:53:58 +02:00
var TBESortdat = window.dats.filter((d)=>exSet.name === d.set.name && d.molecule === mol).sort((d1, d2) => {
2020-04-08 11:34:52 +02:00
if (d1.method.isTBE && !d2.method.isTBE) {
return -1
2020-04-14 15:59:05 +02:00
} else if (!d1.method.isTBE && d2.method.isTBE) {
2020-04-08 11:34:52 +02:00
return 1
} else if (d1.method.isTBE && d2.method.isTBE) {
2020-09-09 18:23:39 +02:00
if (d1.method.name === "TBE" && d2.method.name === "TBE(Full)") {
2020-04-08 11:34:52 +02:00
return -1
2020-09-09 18:23:39 +02:00
} else if (d1.method.name === "TBE(Full)" && d2.method.name === "TBE") {
2020-04-08 11:34:52 +02:00
return 1
}
else {
return 0
}
}
})
2020-04-14 15:59:05 +02:00
if (TBESortdat.length > 0 && TBESortdat[0].method.isTBE) {
2020-04-08 11:34:52 +02:00
for (const exc of TBESortdat[0].excitations) {
2020-09-04 12:15:37 +02:00
window.T1ref.get(setName).get(mol).set(JSON.stringify((exc.initial, exc.final)), exc.T1)
2020-04-08 11:34:52 +02:00
}
}
}
}
$(sel_ref).empty()
2020-09-20 17:53:58 +02:00
for (const me of uniq(window.filtData.map(d => d.method))) {
op = $("<option/>", {
2020-09-20 17:53:58 +02:00
value: JSON.stringify(me)
}).text(me)
if (me.name.includes("TBE")) {
$(sel_ref).prepend(op)
}
else {
$(sel_ref).append(op)
}
}
$(sel_ref).prop("selectedIndex", 0);
2020-01-03 17:12:43 +01:00
var data = $("#data")
2020-01-04 12:57:22 +01:00
$(data).empty();
if (window.filtData.length > 0) {
var PreviousSetName = undefined
var CurrentsetName = undefined
2020-09-20 17:53:58 +02:00
for (const exSet of exSets) {
paperdata = window.filtData.filter((d) => {
2020-09-20 17:53:58 +02:00
return d.set.name === exSet.name && d.set.index === exSet.index
2020-01-03 17:12:43 +01:00
})
var methods = uniq(paperdata.map(d => d.method))
const sortedMethods = methods.sort((a, b) => {
if (a.isTBE && !b.isTBE) {
return -1
}
else if (a.isTBE && b.isTBE) {
2020-04-14 15:59:05 +02:00
if (a.basis !== "CBS" && b.basis === "CBS") {
2020-01-03 17:12:43 +01:00
return -1
}
else {
return 1
}
}
else if (!a.isTBE && b.isTBE) {
return 1
}
else {
return 0
}
})
var div = $('<div/>').appendTo(data)
2020-09-20 17:53:58 +02:00
CurrentsetName = exSet.name
if (PreviousSetName !== CurrentsetName) {
$("<h1/>").text(CurrentsetName).appendTo(div)
}
2020-09-20 17:53:58 +02:00
var doi= await exSet.getDOIAsync()
if (publiCache.has(doi)) {
const publiDat = publiCache.get(doi)
$("<h2/>").append($("<a>",{href:publiDat.URL,target:"_blank"}).text(publiDat.title)).appendTo(div)
2020-08-24 13:49:01 +02:00
}
2020-01-03 17:12:43 +01:00
var table = $("<table/>").addClass("datatable").appendTo(div)
var head = $("<tr/>")
$("<thead/>").addClass("sticky").append(head).appendTo(table)
2020-01-03 17:12:43 +01:00
var tbody = $("<tbody/>").appendTo(table)
2020-02-20 14:42:40 +01:00
var th = $("<th/>", { scope: "column" })
2020-02-20 11:45:04 +01:00
head.append(["Molecule", "Transition"].map(x => th.clone().text(x)))
head.append(sortedMethods.map(x => th.clone().text(x.toString("\n").split('-').join('\u2011'))))
adjustSticky();
2020-01-03 17:12:43 +01:00
datadic = new Map()
for (const dat of paperdata) {
2020-09-20 17:53:58 +02:00
const setName = dat.set.name
2020-01-03 17:12:43 +01:00
const key1 = dat.molecule;
2020-09-04 12:15:37 +02:00
const myT1s = T1ref.get(setName).get(dat.molecule)
2020-01-03 17:12:43 +01:00
if (!datadic.has(key1)) {
datadic.set(key1, new Map())
}
const key3 = JSON.stringify(dat.method)
for (const ex of dat.excitations) {
Reflect.setPrototypeOf(ex.type, excitationType.prototype)
2020-04-14 15:59:05 +02:00
var allowT1 = false
const T1Key = JSON.stringify((ex.initial, ex.final))
const T1range = filterParams.T1
if (T1range.min === 0 && T1range.max === 100) {
allowT1 = true
2020-04-08 11:34:52 +02:00
} else if (myT1s.has(T1Key)) {
2020-04-14 15:59:05 +02:00
const T1Val = myT1s.get(T1Key)
if (T1range.min <= T1Val && T1Val <= T1range.max) {
allowT1 = true
2020-04-08 11:34:52 +02:00
}
}
if (((window.filterParams.exType & ex.type) !== 0) && ((window.filterParams.exVertKind & ex.VertExcitationKind) !== 0) && allowT1) {
const key2 = JSON.stringify([ex.initial, ex.final, ex.type, ex.VertExcitationKind])
if (!datadic.get(key1).has(key2)) {
datadic.get(key1).set(key2, new Map())
}
datadic.get(key1).get(key2).set(key3, [ex.value, ex.isUnsafe])
2020-01-03 17:12:43 +01:00
}
2019-11-27 18:29:29 +01:00
}
}
2020-01-03 17:12:43 +01:00
for (const [molecule, moldat] of datadic.entries()) {
var printmol = true;
for (const [jsonex, exdat] of moldat.entries()) {
const ex = JSON.parse(jsonex)
Reflect.setPrototypeOf(ex[0], state.prototype)
Reflect.setPrototypeOf(ex[1], state.prototype)
Reflect.setPrototypeOf(ex[2], excitationType.prototype)
Reflect.setPrototypeOf(ex[3], VertExcitationKind.prototype)
2020-01-03 17:12:43 +01:00
var tr = $("<tr/>")
if (printmol) {
2020-04-27 16:50:17 +02:00
$("<th/>", { scope: "row", rowspan: moldat.size }).text((mhchemCE.test(molecule) ? MathJaxUtils.getMathJaxString(molecule.toString()) : molecule)).appendTo(tr)
2020-01-03 17:12:43 +01:00
printmol = false
}
var Vertkindtext = ""
if (ex[3].Value == VertExcitationKinds.Fluorescence.Value) {
Vertkindtext = String.raw`[\mathrm{F}]`
}
desctex = ""
2020-04-14 15:59:05 +02:00
if (ex[2].description.string) {
desctex = "(" + ex[2].description.string + ")"
2020-03-31 14:24:01 +02:00
}
2020-04-23 17:12:33 +02:00
$("<th/>", { scope: "rowgroup" }).text(MathJaxUtils.getMathJaxString(String.raw`${ex[0].toLaTeX()} \rightarrow ${ex[1].toLaTeX()} ${Vertkindtext} ${desctex}`)).appendTo(tr)
2020-01-03 17:12:43 +01:00
var entries = Array.from(exdat.entries())
for (const method of sortedMethods) {
2020-01-24 12:17:58 +01:00
td = $("<td/>").addClass("NumberCell")
2020-01-03 17:12:43 +01:00
kv = entries.find(x => {
return JSON.stringify(method) == x[0]
})
if (kv !== undefined) {
const [val, unsafe] = kv[1]
2020-01-03 17:12:43 +01:00
if (unsafe) {
2020-02-16 18:09:37 +01:00
td.append($("<span/>", { title: "unsafe value", role: "img", "aria-label": "Warning" }).addClass("emoji").text('⚠'))
2020-01-03 17:12:43 +01:00
}
if (unsafe && !filterParams.unsafe) {
2020-02-01 17:54:09 +01:00
td.append($("<s/>").append(val.toString()))
}
else {
2020-02-01 17:54:09 +01:00
td.append(val.toString())
}
2020-01-03 17:12:43 +01:00
}
tr.append(td)
}
tbody.append(tr)
}
2019-09-30 09:20:13 +02:00
}
PreviousSetName = CurrentsetName
2019-09-28 15:23:25 +02:00
}
2020-01-03 17:12:43 +01:00
await MathJax.typesetPromise()
2019-09-29 15:58:34 +02:00
}
await reloadRef()
}
2020-04-14 15:59:05 +02:00
async function reloadRef() {
$(sel_ref).empty()
2020-05-05 13:12:09 +02:00
for (const el of uniq(window.filtData.map(d => d.method))) {
op = $("<option/>", {
value: JSON.stringify(el)
2020-05-05 13:12:09 +02:00
}).text(el)
if (el.name.includes("TBE")) {
$(sel_ref).prepend(op)
}
else {
$(sel_ref).append(op)
}
}
$(sel_ref).prop("selectedIndex", 0);
$(sel_ref).trigger("change")
2019-09-28 15:23:25 +02:00
}
async function submitdat() {
if (!DebugMode.Enabled) {
window.onbeforeunload = () => { return ''; }
}
2020-01-09 13:11:20 +01:00
await reloadContent();
}
2019-09-28 15:23:25 +02:00
</script>
{{< getDataFilesName >}}
<noscript>
2020-01-24 16:48:29 +01:00
<p style="background-color: red; color: white; font-size: 20; font-weight: bold;">
2020-02-16 18:09:37 +01:00
<span role="img" aria-label="Warning" class="emoji"></span>
2020-01-24 16:48:29 +01:00
<span>This website work only if JavaScript is enable. You must enable
JavaScript.
<a href="https://www.enable-javascript.com/" target="_blank">How to enable JavaScript ?</a></span>
</p>
</noscript>
2019-10-09 20:10:48 +02:00
<p>
2020-09-10 14:14:20 +02:00
This page allows you to compare multiple dataset and perform statistical analyses to evaluate the accuracy of a given method.
All fields marked with an asterisk (<span style="color: red;">*</span>) are mandatory).
2019-10-09 20:10:48 +02:00
</p>
<form id="form_dat" action="javascript:submitdat()">
<fieldset class="main">
<fieldset>
<legend>Import custom files</legend>
<p>
2020-09-10 14:14:20 +02:00
Import a custom file to compare its data to the reference dataset.
</p>
<div>
<label for="absFiles_input">Import custom absorption data files</label>
<input type="file" multiple onchange="reloadCustomFiles()" id="absFiles_input" name="file_abs"></input>
</div>
<div>
2020-09-10 14:14:20 +02:00
<label for="fluoFiles_input">Import custom fluorescence data files</label>
<input type="file" multiple onchange="reloadCustomFiles()" id="fluoFiles_input" name="file_fluo"></input>
</div>
</fieldset>
2020-09-10 14:14:20 +02:00
<br>
<fieldset class="table">
<legend>Data selection</legend>
2020-09-10 14:14:20 +02:00
<p>Select parameters. You can use <button
disabled>Select all</button> to select all items <span hidden
data-needbrowser='{"Engine":["WebKit","Blink"],"Platform":["desktop"]}'> or the shortcut key <kbd
2020-05-05 14:41:09 +02:00
data-needbrowser='{"OS":["MacOS"]}'>⌘</kbd><kbd
2020-09-10 14:14:20 +02:00
data-neednotbrowser='{"OS":["MacOS"]}'>Ctrl</kbd>+<kbd>A</kbd></span>
</p>
<div style="display: inline-block;">
2020-09-10 14:14:20 +02:00
<label for="DOI_select" class="required">Set</label>
<button class="SelectAll" type="button" onclick="selectSelectAll_click(event)">Select all</button>
2020-09-20 17:53:58 +02:00
<select multiple id="DOI_select" required name="sets" onchange="reloadNextSelect(event)"></select>
</div>
<div style="display:inline-block">
2020-09-10 14:14:20 +02:00
<label for="mol_select" class="required">Molecule</label>
<button class="SelectAll" type="button" onclick="selectSelectAll_click(event)">Select all</button>
<select multiple id="mol_select" required name="molecule" onchange="reloadNextSelect(event)"></select>
</div>
<br />
<div style="display: inline-block;">
2020-09-10 14:14:20 +02:00
<label for="method_select" class="required">Method</label>
<button class="SelectAll" type="button" onclick="selectSelectAll_click(event)">Select all</button>
<select multiple id="method_select" required name="method" onchange="reloadNextSelect(event)"></select>
</div>
<div style="display: inline-block;">
2020-09-10 14:14:20 +02:00
<label for="basis_select" class="required">Basis set</label>
<button class="SelectAll" type="button" onclick="selectSelectAll_click(event)">Select all</button>
<select multiple id="basis_select" required name="basis" onchange="reloadNextSelect(event)"></select>
</div>
</fieldset>
2020-09-10 14:14:20 +02:00
<br>
<fieldset>
2020-09-10 14:14:20 +02:00
<legend class="required">Nature of vertical excitations</legend>
<p>Select the kind of vertical excitations you want to consider</p>
<ul class="nestedCbList" style="padding-left: 0em;">
<li>
<input type="checkbox" data-onerequired="true" checked onchange="nestedCheckbox_change(event)"
id="cb_fileType_All"></input>
<label for="cb_fileType_All"> All</label>
</li>
<ul class="nestedCbList" id="cb_exVertKindList">
<li>
<input type="checkbox" onchange="nestedCheckbox_change(event)" id="cb_abs" value="1" name="datatype">
<label for="cb_abs">Absorption</label>
</li>
<li>
<input type="checkbox" onchange="nestedCheckbox_change(event)" id="cb_fluo" value="2" name="datatype">
<label for="fluo">Fluorescence</label>
</li>
</ul>
</ul>
</fieldset>
2020-09-10 14:14:20 +02:00
<br>
<fieldset id="excitationFilter">
<legend class="required">Filters</legend>
2020-09-10 14:14:20 +02:00
<p>Select nature of the excited states and/or transitions</p>
<ul class="nestedCbList" style="padding-left: 0em;">
<li>
<input type="checkbox" data-onerequired="true" onchange="nestedCheckbox_change(event)"
id="cb_exType_All"></input>
<label for="cb_exType_All"> All</label>
2020-05-05 14:42:42 +02:00
</li>
<ul id="cb_exTypeList" class="nestedCbList">
</ul>
2020-09-10 14:14:20 +02:00
<p>Select if you want to include unsafe reference values in the statistics</p>
<li id="li_cb_unsafe">
<input type="checkbox" id="cb_unsafe" name="unsafe">
<label for="cb_unsafe">Unsafe</label>
</li>
</fieldset>
2020-09-10 14:14:20 +02:00
<br>
<fieldset>
<legend>Molecule Size</legend>
<p>Select the molecule size (by the number of non H atoms)</p>
2020-09-29 15:25:14 +02:00
<input class="range min" airia-label="Minimum value" data-init type="number" id="nHmin" onchange="numberRangeChange(event)">
<span>\(\leq \text{non-H atoms} \leq\)</span>
2020-09-29 15:25:14 +02:00
<input class="range max" airia-label="Maximum value" data-init type="number" id="nHmax" onchange="numberRangeChange(event)">
<div hidden=true>
<input type="checkbox" id="cb_nHUnknow" name="nHUnknoww">
2020-09-29 13:04:55 +02:00
<label for="cb_nHUnknow">Unknow size</label>
</div>
</fieldset>
<br>
<fieldset>
<legend>\(\mathrm{\%T_1}\)</legend>
2020-09-10 14:14:20 +02:00
<p>Select the range of single-excitation percentage \(\mathrm{\%T_1}\) of the transitions </p>
<input class="range min" airia-label="Minimum value" type="number" id="T1min" onchange="numberRangeChange(event)"
min="0" value="0">
<span>\(\leq \mathrm{\%T_1} \leq\)</span>
<input class="range max" airia-label="Maximum value" type="number" id="T1max" onchange="numberRangeChange(event)"
max="100" value="100">
</fieldset>
2020-09-10 14:14:20 +02:00
<br>
2020-04-08 11:34:52 +02:00
</fieldset>
2020-05-19 10:30:28 +02:00
<input type="submit" value="Load"></input>
2019-10-09 20:10:48 +02:00
</form>
<form id="form_ref">
<fieldset class="main">
<fieldset>
2020-09-10 14:14:20 +02:00
<legend>Reference data for statistical analyses</legend>
<p>Select a reference from <strong>already selected data</strong> (by default <abbr
title="Theoretical best estimate">TBE</abbr> if selected)</p>
<label for="sel_ref">Reference</label>
<select id="sel_ref" onchange="reloadStat()"></select>
</fieldset>
2020-09-10 14:14:20 +02:00
<br>
</fieldset>
2019-10-09 20:10:48 +02:00
</form>
2020-09-10 14:14:20 +02:00
<p>List of selected data and their corresponding statistical analysis</p>
2020-01-03 17:12:43 +01:00
<section id="data">
2019-10-09 20:10:48 +02:00
</section>
<section>
2019-12-29 20:00:13 +01:00
<table id="stat_table" class="datatable">
<thead class="sticky">
2020-02-20 14:42:40 +01:00
<th scope="col">Method</th>
2020-04-09 13:01:22 +02:00
<th scope="col">Count</th>
2020-02-20 14:42:40 +01:00
<th scope="col">Min</th>
<th scope="col">Max</th>
<th scope="col"><abbr title="Mean signed error">MSE</abbr></th>
<th scope="col"><abbr title="Mean absolute error">MAE</abbr></th>
2020-02-20 14:42:40 +01:00
<th scope="col">Median</th>
<th scope="col">Absolute Median</th>
<th scope="col"><abbr title="Root-mean square error ">RMSE</abbr></th>
2020-02-20 14:42:40 +01:00
<th scope="col">Variance</th>
<th scope="col"><abbr title="Standard deviation of the errors">SDE</abbr></th>
2019-09-29 15:58:34 +02:00
</thead>
2019-10-09 17:53:10 +02:00
<tbody>
2019-09-28 15:23:25 +02:00
</tbody>
<div id="graph_div"></div>
2019-09-28 15:23:25 +02:00
</table>
2019-10-09 20:10:48 +02:00
</section>
2020-09-10 14:14:20 +02:00
{{< waitModal >}}