2019-09-28 15:23:25 +02:00
---
2020-06-08 16:27:22 +02:00
title: "Dataset"
2019-09-28 15:23:25 +02:00
date: 2019-09-27 16:41
draft: false
---
2019-10-07 12:10:45 +02:00
< link rel = "stylesheet" type = "text/css" href = "/css/modal.css" / >
2019-10-10 10:40:34 +02:00
< 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" / >
2019-10-07 10:23:21 +02:00
< 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 >
2019-10-07 11:22:44 +02:00
< script src = "/js/processingIndicator.js" > < / script >
2019-10-07 10:23:21 +02:00
< script src = "/js/noNan.js" > < / script >
< script src = "/js/websiteFile.js" > < / script >
2020-02-15 11:19:36 +01:00
< script src = "/js/getPublis.js" > < / script >
2019-11-02 15:53:53 +01:00
< script src = "/js/DOICache.js" > < / script >
2020-01-04 18:07:31 +01:00
< script src = "/js/nestedCheckbox.js" > < / script >
2020-01-27 11:09:35 +01:00
< 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-08-20 15:28:06 +02:00
< script src = "/js/PubliDB.js" > < / script >
2019-09-28 15:23:25 +02:00
< script >
2020-02-16 11:48:55 +01:00
function adjustSticky() {
const height = $("nav").height()
$("thead.sticky > tr > th ").css("top", height)
2020-02-03 14:26:11 +01:00
}
2019-10-09 20:10:48 +02:00
window.onload = async () => {
2020-02-16 11:48:55 +01:00
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")
2020-02-03 14:26:11 +01:00
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)
})
2020-02-16 11:48:55 +01:00
$('[data-needbrowser],[data-neednotbrowser]').each(function () {
function test(key, value) {
2020-02-04 12:07:03 +01:00
switch (key) {
case "Engine":
2020-02-16 11:48:55 +01:00
return value.some((v) => browser.isEngine(v))
2020-02-04 12:07:03 +01:00
break;
case "Browser":
2020-02-16 11:48:55 +01:00
return value.some((v) => browser.isBrowser(v))
2020-02-04 12:07:03 +01:00
case "Platform":
2020-02-16 11:48:55 +01:00
return value.some((v) => browser.isPlatform(v))
2020-02-04 12:07:03 +01:00
case "OS":
2020-02-16 11:48:55 +01:00
return value.some((v) => browser.isOS(v))
2020-02-04 12:07:03 +01:00
default:
return true
break;
}
}
2020-02-16 11:48:55 +01:00
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) {
2020-01-29 10:37:39 +01:00
$(this).show()
2020-02-04 12:07:03 +01:00
} else {
$(this).hide()
2020-01-29 10:37:39 +01:00
}
})
2020-01-04 18:07:31 +01:00
var cbextl = $("#cb_exTypeList")
2020-01-28 17:33:56 +01:00
var extl = $("#exTypeList")
2020-02-16 11:48:55 +01:00
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
2020-03-08 16:17:04 +01:00
if (value.description.isLaTeX) {
2020-04-23 17:12:33 +02:00
txt = MathJaxUtils.getMathJaxString(txt)
2019-12-19 12:19:32 +01:00
}
2020-03-08 16:17:04 +01:00
$("< li / > ").text(txt).appendTo(extl)
2020-01-04 18:07:31 +01:00
var cbli = $("< li / > ")
2020-08-20 15:28:06 +02:00
if (!DebugMode.Enabled & & value == (1 < < 31 ) ) {
2020-06-10 15:18:39 +02:00
cbli.hide()
}
2020-01-04 18:07:31 +01:00
$("< input / > ", { type: "checkbox", id: "cb_" + name, name: name, value: Number(value) }).change(nestedCheckbox_change).appendTo(cbli);
2020-03-08 16:17:04 +01:00
$('< label / > ', { 'for': 'cb_' + name, text: txt }).appendTo(cbli);
2020-01-04 18:07:31 +01:00
cbextl.append(cbli);
2019-12-15 19:32:14 +01:00
}
await MathJax.typesetPromise();
2020-01-04 18:07:31 +01:00
delete (cbextl)
2020-01-28 17:33:56 +01:00
delete (extl)
delete (vertkindtl)
2019-11-02 15:53:53 +01:00
window.doiCache = new DOICache()
2020-01-27 11:09:35 +01:00
await loadFiles()
2020-01-14 10:06:31 +01:00
}
async function loadFiles() {
processingIndicator.isActive = true
2020-01-14 11:20:38 +01:00
var chks = []
2020-08-20 15:28:06 +02:00
var data = await loadAllData()
2020-01-27 11:09:35 +01:00
window.defaultDats = []
2020-05-24 18:49:16 +02:00
for (const sub of Object.values(data)) {
2020-08-02 16:59:35 +02:00
for (const doi of uniq(sub.map(d => (d.DOI == null ? "" : d.DOI.string)))) {
const subdoi = sub.filter(d => (d.DOI == null ? "" : d.DOI.string) === doi)
2020-02-16 11:48:55 +01:00
for (mol of uniq(subdoi.map(d => d.molecule))) {
const submol = subdoi.filter(d => d.molecule === mol)
2020-03-31 14:28:45 +02:00
const source = submol.find((d) => {
2020-08-02 16:59:35 +02:00
if ((d.DOI == null ? "" : d.DOI.string) === "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-02-16 11:48:55 +01:00
}
}
2020-01-15 13:10:21 +01:00
}
}
2020-02-16 11:48:55 +01:00
2020-01-27 11:09:35 +01:00
window.defaultDats = window.defaultDats.concat(sub)
2020-01-15 13:10:21 +01:00
}
2020-08-20 15:28:06 +02:00
await doiCache.addRange(Array.from(new Set(window.defaultDats.filter(d => d.DOI !== null).map(d => d.DOI.string))))
window.defaultDats = window.defaultDats.sort((datfa, datfb) => {
const DOIa = datfa.DOI
const DOIb = datfb.DOI
2020-08-02 16:59:35 +02:00
if (DOIa == null & & DOIb == null) {
return 0
}
2020-08-20 15:28:06 +02:00
else if (DOIa == null) {
2020-08-02 16:59:35 +02:00
return 1
}
2020-08-20 15:28:06 +02:00
else if (DOIb == null) {
2020-08-02 16:59:35 +02:00
return -1
}
else {
const puba = doiCache.get(DOIa.string).format('data', { format: 'object' })[0]
const pubb = doiCache.get(DOIb.string).format('data', { format: 'object' })[0]
2020-08-20 15:28:06 +02:00
return pubUtils.getIssuedDate(puba) - pubUtils.getIssuedDate(pubb)
2020-08-02 16:59:35 +02:00
}
2020-05-04 14:13:25 +02:00
})
2020-01-14 10:06:31 +01:00
processingIndicator.isActive = false
2020-01-28 11:41:06 +01:00
reloadCustomFiles()
2019-09-28 15:23:25 +02:00
}
2020-01-27 11:13:49 +01:00
async function reloadCustomFiles() {
2020-01-27 11:09:35 +01:00
window.dats = window.defaultDats;
2020-01-28 11:41:06 +01:00
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"')) {
2020-01-27 11:09:35 +01:00
if (kinds.has(el.name)) {
for (const f of el.files) {
2020-01-28 11:41:06 +01:00
const dat = await VertDataFile.loadAsync(f, kinds.get(this.name))
2019-10-02 19:20:37 +02:00
window.dats.push(dat)
2020-01-27 11:09:35 +01:00
}
2019-10-02 19:20:37 +02:00
}
}
2020-01-28 11:41:06 +01:00
reloadSelect("DOI")
2020-01-27 11:13:49 +01:00
}
2020-01-28 11:41:06 +01:00
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
}
2020-01-28 11:41:06 +01:00
function getAllSelect() {
2020-05-18 18:22:18 +02:00
return $('#form_dat > fieldset > fieldset > div > select')
2020-01-28 11:41:06 +01:00
}
2020-01-28 17:33:56 +01:00
function getAllSelectAfter(Name, include = false) {
const selects = getAllSelect()
2020-01-28 11:41:06 +01:00
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()
2020-01-28 11:41:06 +01:00
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
2020-01-28 11:41:06 +01:00
if (!isLast) {
await reloadSelect(afters.prop("name"))
}
2020-02-16 11:48:55 +01:00
const fillArray = ["molecule"]
2020-01-29 17:53:37 +01:00
if (fillArray.includes(afters.prop("name"))) {
selectSelectAll(afters.first())
}
2020-01-28 11:41:06 +01:00
}
2020-08-20 15:28:06 +02:00
function getAllVals(select) {
var baseval = $(select).val()
switch (select.name) {
case "DOI":
vals=baseval.reduce((accumulator,currentValue)=>accumulator.concat(JSON.parse(currentValue)),[])
return vals
break;
default:
return baseval
}
}
2020-01-28 11:41:06 +01:00
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))
})
var AAllValsCache = Array.from(AllValsCache)
2020-08-20 15:28:06 +02:00
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
2020-01-28 11:41:06 +01:00
})
}).map((d) => getSelectValue(d, name)))
2020-08-20 15:28:06 +02:00
const publis = await (async () => {
2020-04-14 15:59:05 +02:00
if (name === "DOI") {
2020-08-20 15:28:06 +02:00
const publis = await publiDB.loadAsync()
return publis
2020-02-15 11:19:36 +01:00
}
2020-04-14 15:59:05 +02:00
else {
2020-02-15 11:19:36 +01:00
return undefined
}
})()
2020-08-20 15:28:06 +02:00
if (name === "DOI") {
let newvals = []
for (const val of vals) {
for (const set of publis.sets.values()) {
if (set.includes(val)) {
newvals.push(set)
}
}
}
vals = newvals
}
textSelctor = function (value) {
2020-04-27 16:50:17 +02:00
switch (name) {
case "DOI":
2020-08-20 15:28:06 +02:00
setname = publis.findNameFromSet(value, true)
return setname === null ? value.toString() : setname
2020-04-27 16:50:17 +02:00
break;
case "molecule":
2020-08-20 15:28:06 +02:00
const mhchemCE = /^\\ce\{(.*)\}$/
const m = value.match(mhchemCE)
2020-04-29 15:44:45 +02:00
if (m) {
return m[1]
} else {
return value
}
2020-04-27 16:50:17 +02:00
break;
default:
return value.toString()
}
}
2020-08-20 15:28:06 +02:00
valueSelector = function (value) {
if (typeof value === 'object') {
return JSON.stringify(value)
}
else {
return value
}
}
2020-01-28 11:41:06 +01:00
for (const val of vals) {
if (val !== null) {
$("< option / > ", {
2020-08-20 15:28:06 +02:00
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-08-20 15:28:06 +02:00
if (name === "molecule") {
await MathJax.typesetPromise()
}
2020-04-27 16:50:17 +02:00
}
2020-01-28 11:41:06 +01:00
}
function getSelectValue(data, name) {
switch (name) {
case "method":
return data.method.name
break;
case "basis":
return data.method.basis
case "DOI":
2020-08-02 16:59:35 +02:00
return data.DOI === null ? "" : data.DOI.string
2020-01-28 11:41:06 +01:00
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()
2020-05-05 13:52:00 +02:00
var refstr = $("#sel_ref option:selected").val()
2019-10-09 20:10:48 +02:00
var sdatdic = new Map()
2020-01-04 18:07:31 +01:00
for (const d of window.filtData) {
2020-05-05 13:12:09 +02:00
const key = JSON.stringify(d.method)
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-08-02 16:59:35 +02:00
const myT1s = T1ref.get(d.DOI == null ? "" : d.DOI.string).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-01-27 11:09:35 +01:00
const key2 = JSON.stringify([d.molecule, exc.initial, exc.final, exc.cVertExcitationKind])
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
}
2020-05-05 13:52:00 +02:00
2019-10-09 20:10:48 +02:00
var sdic = new Map()
for (const [key, sdat] of sdatdic) {
2020-05-05 13:52:00 +02:00
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
}
2020-05-05 13:52:00 +02:00
sdic.get(key).push(exval - ((sdatdic.has(refstr)) ? sdatdic.get(refstr).get(key2) : NaN))
2019-10-01 14:37:26 +02:00
}
}
2020-05-05 13:52:00 +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)
2020-05-05 13:52:00 +02:00
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-05-05 13:12:09 +02:00
name: key.toString() + " MAD : " + ss.mean(avals).toPrecision(4),
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: {
text: 'Energy (eV)',
}
},
bgcolor: '#E2E2E2',
bordercolor: '#FFFFFF',
borderwidth: 2,
// autosize: false,
width: 850,
height: 500,
margin: {
l: 0,
r: 10,
b: 15,
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())
}
2020-04-08 11:34:52 +02:00
}
2019-11-02 15:53:53 +01:00
doiCache.clear()
2019-10-09 20:10:48 +02:00
processingIndicator.isActive = true
2020-01-04 18:07:31 +01:00
window.filtData = window.dats
2020-05-18 18:22:54 +02:00
getAllSelect().each(function () {
2019-10-09 20:10:48 +02:00
const prop = $(this).attr("name")
2020-08-20 15:28:06 +02:00
const values = getAllVals(this)
2020-01-04 18:07:31 +01:00
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))
2020-01-14 10:06:31 +01:00
delete (val)
2019-09-28 15:23:25 +02:00
})
})
2020-04-14 15:59:05 +02:00
window.T1ref = new Map()
2020-08-20 15:28:06 +02:00
var dois = new Set(window.filtData.map((d) => d.DOI === null ? "" : d.DOI.string))
2020-04-08 11:34:52 +02:00
var mols = new Set(window.filtData.map((d) => d.molecule))
await window.doiCache.addRange(dois)
for (const doi of dois) {
2020-04-14 15:59:05 +02:00
window.T1ref.set(doi, new Map())
2020-04-08 11:34:52 +02:00
for (const mol of mols) {
2020-04-14 15:59:05 +02:00
window.T1ref.get(doi).set(mol, new Map())
2020-08-02 16:59:35 +02:00
var TBESortdat = window.dats.filter(d => (d.DOI === null ? "" : d.DOI.string) === doi & & 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-04-14 15:59:05 +02:00
if (d1.method.name === "TBE(FC)" & & d2.method.name === "TBE") {
2020-04-08 11:34:52 +02:00
return -1
2020-04-14 15:59:05 +02:00
} else if (d1.method.name === "TBE" & & d2.method.name === "TBE(FC)") {
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-04-14 15:59:05 +02:00
window.T1ref.get(doi).get(mol).set(JSON.stringify((exc.initial, exc.final)), exc.T1)
2020-04-08 11:34:52 +02:00
}
}
}
}
2020-05-05 13:52:00 +02:00
$(sel_ref).empty()
2020-08-02 16:59:35 +02:00
for (const el of uniq(window.filtData.map(d => [d.method, (d.DOI === null ? null : d.DOI.string)]))) {
2020-05-05 13:52:00 +02:00
op = $("< option / > ", {
value: JSON.stringify(el)
}).text(el[0])
if (el[0].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();
2020-01-04 18:07:31 +01:00
if (window.filtData.length > 0) {
2020-08-20 15:28:06 +02:00
var publis = await publiDB.loadAsync()
var PreviousSetName = undefined
var CurrentsetName = undefined
2020-01-03 17:12:43 +01:00
for (const doi of doiCache.keys()) {
2020-01-04 18:07:31 +01:00
paperdata = window.filtData.filter((d) => {
2020-08-02 16:59:35 +02:00
return (d.DOI === null ? "" : d.DOI.string) == doi
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-08-20 15:28:06 +02:00
CurrentsetName = publis.findSetNameFromDOI(doi, true)
if (PreviousSetName !== CurrentsetName) {
$("< h1 / > ").text(CurrentsetName).appendTo(div)
}
$("< h2 / > ").text(doiCache.get(doi).format('data', { format: 'object' })[0].title).appendTo(div)
2020-01-03 17:12:43 +01:00
var table = $("< table / > ").addClass("datatable").appendTo(div)
var head = $("< tr / > ")
2020-02-03 14:26:11 +01:00
$("< 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)))
2020-02-20 11:55:22 +01:00
head.append(sortedMethods.map(x => th.clone().text(x.toString("\n").split('-').join('\u2011'))))
2020-02-03 14:26:11 +01:00
adjustSticky();
2020-01-03 17:12:43 +01:00
datadic = new Map()
for (const dat of paperdata) {
const key1 = dat.molecule;
2020-08-02 16:59:35 +02:00
const myT1s = T1ref.get(dat.DOI == null ? "" : dat.DOI.string).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) {
2020-01-14 10:06:31 +01:00
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) {
2020-01-27 11:09:35 +01:00
const key2 = JSON.stringify([ex.initial, ex.final, ex.type, ex.VertExcitationKind])
2020-01-04 18:07:31 +01:00
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
}
2019-12-18 17:51:53 +01:00
}
2020-01-03 17:12:43 +01:00
for (const [molecule, moldat] of datadic.entries()) {
var printmol = true;
2020-08-20 15:28:06 +02:00
const mhchemCE = /^\\ce\{.*\}$/
2020-01-03 17:12:43 +01:00
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)
2020-01-27 11:09:35 +01:00
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
}
2020-01-27 11:09:35 +01:00
var Vertkindtext = ""
if (ex[3].Value == VertExcitationKinds.Fluorescence.Value) {
2020-03-08 16:17:04 +01:00
Vertkindtext = String.raw`[\mathrm{F}]`
2020-01-27 11:09:35 +01:00
}
2020-08-20 15:28:06 +02:00
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) {
2020-01-04 18:07:31 +01:00
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
}
2020-04-03 16:16:08 +02:00
if (unsafe & & !filterParams.unsafe) {
2020-02-01 17:54:09 +01:00
td.append($("< s / > ").append(val.toString()))
2020-01-04 12:53:01 +01:00
}
2020-01-04 18:07:31 +01:00
else {
2020-02-01 17:54:09 +01:00
td.append(val.toString())
2020-01-04 12:53:01 +01:00
}
2020-01-03 17:12:43 +01:00
}
tr.append(td)
}
tbody.append(tr)
}
2019-09-30 09:20:13 +02:00
}
2020-08-20 15:28:06 +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
}
2020-04-13 14:53:49 +02:00
await reloadRef()
}
2020-04-14 15:59:05 +02:00
async function reloadRef() {
2020-04-13 14:53:49 +02:00
$(sel_ref).empty()
2020-05-05 13:12:09 +02:00
for (const el of uniq(window.filtData.map(d => d.method))) {
2020-04-13 14:53:49 +02:00
op = $("< option / > ", {
value: JSON.stringify(el)
2020-05-05 13:12:09 +02:00
}).text(el)
if (el.name.includes("TBE")) {
2020-04-13 14:53:49 +02:00
$(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
}
2020-01-14 10:06:31 +01:00
async function submitdat() {
2020-08-06 18:57:18 +02:00
if (!DebugMode.Enabled) {
2020-08-20 15:28:06 +02:00
window.onbeforeunload = () => { return ''; }
window.onbeforeunload = () => { return ''; }
window.onbeforeunload = () => { return ''; }
2020-08-06 18:57:18 +02:00
}
2020-01-09 13:11:20 +01:00
await reloadContent();
}
2019-09-28 15:23:25 +02:00
< / script >
{{< getDataFilesName > }}
2020-01-22 15:48:49 +01:00
< 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
2020-01-22 15:48:49 +01:00
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-08-20 15:28:06 +02:00
On this page you can compare multiple dataset and have some statistics to evaluate method accuracy (All fields marked
with a red asterisk (< span style = "color: red;" > *< / span > ) are mandatory).
2019-10-09 20:10:48 +02:00
< / p >
2020-01-09 13:11:20 +01:00
< form id = "form_dat" action = "javascript:submitdat()" method = "post" >
2020-05-18 10:58:02 +02:00
< fieldset class = "main" >
2020-08-20 15:28:06 +02:00
< fieldset >
< legend > Import custom files< / legend >
< p >
Import custom files to compare it's data to the reference datasets.
< / 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 >
< 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 >
< fieldset class = "table" >
< legend > Data selection< / legend >
< p > Choose each parameter (of course you can select multiple values for each) you can use the < button
disabled>Select all< / button > button to select all items < span hidden
2020-05-05 14:41:09 +02:00
data-needbrowser='{"Engine":["WebKit","Blink"],"Platform":["desktop"]}'>or use the < kbd
data-needbrowser='{"OS":["MacOS"]}'>⌘< / kbd > < kbd
data-neednotbrowser='{"OS":["MacOS"]}'>Ctrl< / kbd > +< kbd > A< / kbd > shortcut key< / span >
2020-08-20 15:28:06 +02:00
< / p >
< div style = "display: inline-block;" >
< label for = "DOI_select" class = "required" > Sets< / label >
< button class = "SelectAll" type = "button" onclick = "selectSelectAll_click(event)" > Select all< / button >
< select multiple id = "DOI_select" required name = "DOI" onchange = "reloadNextSelect(event)" > < / select >
< / div >
< div style = "display:inline-block" >
< label for = "mol_select" class = "required" > Molecules< / 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;" >
< label for = "method_select" class = "required" > Methods< / 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;" >
< label for = "basis_select" class = "required" > Basis sets< / 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 >
< fieldset >
< legend class = "required" > Vertical excitation kind< / legend >
< p > Choose what kind of vertical excitations you want< / p >
< ul class = "nestedCbList" style = "padding-left: 0em;" >
2020-01-27 11:09:35 +01:00
< li >
2020-08-20 15:28:06 +02:00
< input type = "checkbox" data-onerequired = "true" checked onchange = "nestedCheckbox_change(event)"
id="cb_fileType_All">< / input >
< label for = "cb_fileType_All" > All< / label >
2020-01-27 11:09:35 +01:00
< / li >
2020-08-20 15:28:06 +02:00
< 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 >
< fieldset id = "excitationFilter" >
< legend class = "required" > Filters< / legend >
< p > Choose other excitation parameters you want< / p >
< ul class = "nestedCbList" style = "padding-left: 0em;" >
2020-01-27 11:09:35 +01:00
< li >
2020-08-20 15:28:06 +02:00
< 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 >
2020-08-20 15:28:06 +02:00
< ul id = "cb_exTypeList" class = "nestedCbList" >
< / ul >
< p > Choose if you want to include unsafe values in statistics< / p >
< li id = "li_cb_unsafe" >
< input type = "checkbox" id = "cb_unsafe" name = "unsafe" >
< label for = "cb_unsafe" > Unsafe< / label >
< / li >
< / fieldset >
< fieldset >
< legend > \(\mathrm{\%T_1}\)< / legend >
< p > Chose the range of \(\mathrm{\%T_1}\) range using the two number box< / 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-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" >
2020-05-18 10:58:02 +02:00
< fieldset class = "main" >
2020-08-20 15:28:06 +02:00
< fieldset >
< legend > statistics< / legend >
< p > Select a reference from < strong > already selected data< / strong > (by default first is selected -it's the < abbr
title="Theoretical best estimate">TBE< / abbr > if present- is already selected)< / p >
< label for = "sel_ref" > Reference< / label >
< select id = "sel_ref" onchange = "reloadStat()" > < / select >
< / fieldset >
< / fieldset >
2019-10-09 20:10:48 +02:00
< / form >
2020-05-05 14:41:09 +02:00
< p > Now you can see the list of selected data and some statistics about these data< / 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" >
2020-02-03 14:26:11 +01:00
< 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 >
2020-04-30 18:21:38 +02:00
< 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 >
2020-04-30 18:21:38 +02:00
< 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 >
2020-04-30 18:21:38 +02:00
< 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 >
2019-10-04 11:03:30 +02:00
< div id = "graph_div" > < / div >
2019-09-28 15:23:25 +02:00
< / table >
2019-10-09 20:10:48 +02:00
< / section >
2019-10-07 14:00:15 +02:00
{{< waitModal > }}