10
0
mirror of https://github.com/LCPQ/QUESTDB_website.git synced 2024-12-25 13:53:48 +01:00

Use same class for Absorption and fluorescence files and improve select

This commit is contained in:
Mickaël Véril 2020-01-27 11:09:35 +01:00
parent 7d5d38a1e9
commit 976a56adac
4 changed files with 149 additions and 156 deletions

View File

@ -21,6 +21,7 @@ draft: false
type="text/javascript"></script> type="text/javascript"></script>
<script src="/js/DOICache.js"></script> <script src="/js/DOICache.js"></script>
<script src="/js/nestedCheckbox.js"></script> <script src="/js/nestedCheckbox.js"></script>
<script src="/js/selectSelectAll.js"></script>
<script src="https://unpkg.com/simple-statistics@7.0.2/dist/simple-statistics.min.js"></script> <script src="https://unpkg.com/simple-statistics@7.0.2/dist/simple-statistics.min.js"></script>
<script> <script>
window.onload = async () => { window.onload = async () => {
@ -63,25 +64,15 @@ draft: false
delete (cbextl) delete (cbextl)
delete (allc) delete (allc)
window.doiCache = new DOICache() window.doiCache = new DOICache()
await loadFiles()
} }
async function loadFiles() { async function loadFiles() {
processingIndicator.isActive = true processingIndicator.isActive = true
var chks = [] var chks = []
var chks = $("#form_datFiles > ul > ul > li >input[type=checkbox]:checked") proms = []
var proms = Array.from(chks).map((c) => { proms.push(getAbsFilesName().map((f) => VertDataFile.loadAsync(f, VertExcitationKinds.Absorbtion)));
switch (c.value) { proms.push(getFluoFilesName().map((f) => VertDataFile.loadAsync(f, VertExcitationKinds.Fluorescence)))
case "abs": window.defaultDats = []
return getAbsFilesName().map((f) => AbsDataFile.loadAsync(f));
break;
case "fluo":
return getFluoFilesName().map((f) => FluoDataFile.loadAsync(f));
break;
default:
return []
break;
}
})
window.dats = []
for (const subproms of proms) { for (const subproms of proms) {
var sub = await Promise.all(subproms) var sub = await Promise.all(subproms)
for (mol of uniq(sub.map(d => d.molecule))) { for (mol of uniq(sub.map(d => d.molecule))) {
@ -91,34 +82,21 @@ draft: false
dat.CopyExcitationsTypeFrom(TBE) dat.CopyExcitationsTypeFrom(TBE)
} }
} }
window.dats = window.dats.concat(sub) window.defaultDats = window.defaultDats.concat(sub)
} }
processingIndicator.isActive = false processingIndicator.isActive = false
reloadFileSelector()
await reloadSelect() await reloadSelect()
} }
function reloadFileSelector() {
$("#customFiles_input").attr("value", "").attr("disabled", false)
}
async function reloadSelect() { async function reloadSelect() {
processingIndicator.isActive = true window.dats = window.defaultDats;
radioval = $('#form_dat > fieldset > input[name=datatype]:checked').val(); const kinds=new Map([["file_abs", VertExcitationKinds.Absorbtion], ["file_fluo", VertExcitationKinds.Fluorescence]])
const files = $("#customFiles_input")[0].files for (const el of $('#form_dat > fieldset > div > input[type="file"')) {
for (file of [...files]) { if (kinds.has(el.name)) {
switch (radioval) { for (const f of el.files) {
case "abs": const dat=await VertDataFile.loadAsync(f, kinds.get(this.name))
var dat = await AbsDataFile.loadAsync(file)
window.dats.push(dat) window.dats.push(dat)
break; }
case "fluo":
dat = await FluoDataFile.loadAsync(file)
window.dats.push(dat)
break;
case "ZPE":
dat = await ZPEDataFile.loadAsync(file)
window.dats.push(dat)
break;
} }
} }
$('#form_dat > fieldset > div > select,#sel_ref').each(function () { $('#form_dat > fieldset > div > select,#sel_ref').each(function () {
@ -150,7 +128,6 @@ draft: false
}) })
$('#form_dat > input[type="submit"').prop('disabled', false); $('#form_dat > input[type="submit"').prop('disabled', false);
processingIndicator.isActive = false processingIndicator.isActive = false
await reloadContent()
} }
async function reloadStat() { async function reloadStat() {
processingIndicator.isActive = true processingIndicator.isActive = true
@ -165,9 +142,9 @@ draft: false
sdatdic.set(key, new Map()) sdatdic.set(key, new Map())
} }
for (const exc of d.excitations) { for (const exc of d.excitations) {
const key2 = JSON.stringify([d.molecule, exc.initial, exc.final]) const key2 = JSON.stringify([d.molecule, exc.initial, exc.final, exc.cVertExcitationKind])
const keydic = sdatdic.get(key) const keydic = sdatdic.get(key)
if ((!exc.isUnsafe || window.filterParams[0]) && ((exc.type & window.filterParams[1]) !== 0)) { if ((!exc.isUnsafe || window.filterParams[0]) && ((exc.type & window.filterParams[1]) !== 0) && ((exc.VertExcitationKind & window.filterParams[2]) !== 0)) {
if (!(keydic.has(key2))) { if (!(keydic.has(key2))) {
keydic.set(key2, []) keydic.set(key2, [])
} }
@ -259,7 +236,7 @@ draft: false
processingIndicator.isActive = false processingIndicator.isActive = false
} }
async function reloadContent() { async function reloadContent() {
window.filterParams = [$("#cb_unsafe").prop("checked"), Array.from(Array.from($("#cb_exTypeList>li>input[type=checkbox]:checked")).map(el => parseInt(el.value))).reduce((pv, cv) => pv + cv, 0)] window.filterParams = [$("#cb_unsafe").prop("checked"), Array.from(Array.from($("#cb_exTypeList>li>input[type=checkbox]:checked")).map(el => parseInt(el.value))).reduce((pv, cv) => pv + cv, 0), Array.from(Array.from($("#cb_exVertKindList>li>input[type=checkbox]:checked")).map(el => parseInt(el.value))).reduce((pv, cv) => pv + cv, 0)]
doiCache.clear() doiCache.clear()
processingIndicator.isActive = true processingIndicator.isActive = true
const LatexInline = ['\\(', '\\)'] const LatexInline = ['\\(', '\\)']
@ -349,8 +326,8 @@ draft: false
const key3 = JSON.stringify(dat.method) const key3 = JSON.stringify(dat.method)
for (const ex of dat.excitations) { for (const ex of dat.excitations) {
Reflect.setPrototypeOf(ex.type, excitationType.prototype) Reflect.setPrototypeOf(ex.type, excitationType.prototype)
if ((window.filterParams[1] & ex.type) !== 0) { if (((window.filterParams[1] & ex.type) !== 0) && ((window.filterParams[2] & ex.VertExcitationKind) !== 0)) {
const key2 = JSON.stringify([ex.initial, ex.final, ex.type]) const key2 = JSON.stringify([ex.initial, ex.final, ex.type, ex.VertExcitationKind])
if (!datadic.get(key1).has(key2)) { if (!datadic.get(key1).has(key2)) {
datadic.get(key1).set(key2, new Map()) datadic.get(key1).set(key2, new Map())
} }
@ -365,6 +342,7 @@ draft: false
Reflect.setPrototypeOf(ex[0], state.prototype) Reflect.setPrototypeOf(ex[0], state.prototype)
Reflect.setPrototypeOf(ex[1], state.prototype) Reflect.setPrototypeOf(ex[1], state.prototype)
Reflect.setPrototypeOf(ex[2], excitationType.prototype) Reflect.setPrototypeOf(ex[2], excitationType.prototype)
Reflect.setPrototypeOf(ex[3], VertExcitationKind.prototype)
var tr = $("<tr/>") var tr = $("<tr/>")
var tdmol = $("<td/>") var tdmol = $("<td/>")
if (printmol) { if (printmol) {
@ -372,7 +350,11 @@ draft: false
printmol = false printmol = false
} }
tr.append(tdmol) tr.append(tdmol)
$("<td/>").text(String.raw`${LatexInline[0]}${ex[0].toLaTeX()} \rightarrow ${ex[1].toLaTeX()} (${ex[2].LaTeX}) ${LatexInline[1]}`).appendTo(tr) var Vertkindtext = ""
if (ex[3].Value == VertExcitationKinds.Fluorescence.Value) {
Vertkindtext = String.raw`[${VertExcitationKinds.Fluorescence.LaTeX}]`
}
$("<td/>").text(String.raw`${LatexInline[0]}${ex[0].toLaTeX()} \rightarrow ${ex[1].toLaTeX()} ${Vertkindtext}(${ex[2].LaTeX}) ${LatexInline[1]}`).appendTo(tr)
var entries = Array.from(exdat.entries()) var entries = Array.from(exdat.entries())
for (const method of sortedMethods) { for (const method of sortedMethods) {
td = $("<td/>").addClass("NumberCell") td = $("<td/>").addClass("NumberCell")
@ -436,51 +418,59 @@ draft: false
<li>Now you can see the list of selected data and some statistics about these data</li> <li>Now you can see the list of selected data and some statistics about these data</li>
</ol> </ol>
</p> </p>
<form id="form_datFiles" action="javascript:loadFiles()" method="post">
<legend>Data type</legend>
<ul class="nestedCbList" style="padding-left: 0em;">
<li>
<input type="checkbox" onchange="nestedCheckbox_change(event)" id="cb_fileType_All"></input>
<label for="cb_fileType_All"> All</label>
</li>
<ul class="nestedCbList">
<li>
<input type="checkbox" onchange="nestedCheckbox_change(event)" id="cb_abs" value="abs" name="datatype">
<label for="cb_abs">Absorption</label>
</li>
<li>
<input type="checkbox" onchange="nestedCheckbox_change(event)" id="cb_fluo" value="fluo" name="datatype">
<label for="fluo">Fluorescence</label>
</ul>
</li>
<input type="submit" value="Load files" />
</form>
<form id="form_dat" action="javascript:submitdat()" method="post"> <form id="form_dat" action="javascript:submitdat()" method="post">
<fieldset> <fieldset>
<legend>Import custom files</legend>
<div> <div>
<label for="customFiles_input">Add custom data file</label> <label for="absFiles_input">Add custom absorption data files</label>
<input type="file" multiple onchange="reloadSelect()" id="customFiles_input" disabled=true></input> <input type="file" multiple onchange="reloadSelect()" id="absFiles_input" name="file_abs"></input>
</div>
<div>
<label for="fluoFiles_input">Add custom fluorescence data files</label>
<input type="file" multiple onchange="reloadSelect()" id="fluoFiles_input" name="file_fluo"></input>
</div> </div>
</fieldset> </fieldset>
<fieldset class="table"> <fieldset class="table">
<div style="display: inline-block;"> <div style="display: inline-block;">
<label for="DOI_select">Set</label> <label for="DOI_select">Sets</label>
<button class="SelectAll" onclick="selectSelectAll_click(event)">Select all</button>
<select multiple id="DOI_select" name="DOI"></select> <select multiple id="DOI_select" name="DOI"></select>
</div> </div>
<div style="display:inline-block"> <div style="display:inline-block">
<label for="mol_select">Molecule</label> <label for="mol_select">Molecules</label>
<button class="SelectAll" onclick="selectSelectAll_click(event)">Select all</button>
<select multiple id="mol_select" name="molecule"></select> <select multiple id="mol_select" name="molecule"></select>
</div> </div>
<br /> <br />
<div style="display: inline-block;"> <div style="display: inline-block;">
<label for="method_select">Method</label> <label for="method_select">Methods</label>
<button class="SelectAll" onclick="selectSelectAll_click(event)">Select all</button>
<select multiple id="method_select" name="method"></select> <select multiple id="method_select" name="method"></select>
</div> </div>
<div style="display: inline-block;"> <div style="display: inline-block;">
<label for="basis_select">Basis</label> <label for="basis_select">Basis sets</label>
<button class="SelectAll" onclick="selectSelectAll_click(event)">Select all</button>
<select multiple id="basis_select" name="basis"></select> <select multiple id="basis_select" name="basis"></select>
</div> </div>
</fieldset> </fieldset>
<fieldset>
<legend>Vertical excitation kind</legend>
<ul class="nestedCbList" style="padding-left: 0em;">
<li>
<input type="checkbox" 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>
</ul>
</li>
</fieldset>
<fieldset id="excitationFilter"> <fieldset id="excitationFilter">
<legend>Filters</legend> <legend>Filters</legend>
<ul class="nestedCbList" style="padding-left: 0em;"> <ul class="nestedCbList" style="padding-left: 0em;">

View File

@ -5,6 +5,9 @@ ul.nestedCbList {
list-style-type: none; list-style-type: none;
padding-left: 1em; padding-left: 1em;
} }
form button.SelectAll {
display: block;
}
form label{ form label{
padding-left: 5px; padding-left: 5px;
padding-right: 5px; padding-right: 5px;

View File

@ -1,12 +1,12 @@
class excitationTypes { class excitationTypes {
static get VALENCE() { return new excitationType(1, String.raw`\mathrm{V}`) } static get VALENCE() { return new excitationType(1<< 1, String.raw`\mathrm{V}`) }
static get RYDBERG() { return new excitationType(1 << 1, String.raw`\mathrm{R}`) } static get RYDBERG() { return new excitationType(1 << 2, String.raw`\mathrm{R}`) }
static get PiPis() { return new excitationType(1 << 2, String.raw`\pi \rightarrow \pi^\star`) } static get PiPis() { return new excitationType(1 << 3, String.raw`\pi \rightarrow \pi^\star`) }
static get nPis() { return new excitationType(1 << 3, String.raw`n \rightarrow \pi^\star`) } static get nPis() { return new excitationType(1 << 4, String.raw`n \rightarrow \pi^\star`) }
static get Single() { return new excitationType(1 << 4, "S") } static get Single() { return new excitationType(1 << 5, "S") }
static get Double() { return new excitationType(1 << 5, "D") } static get Double() { return new excitationType(1 << 6, "D") }
static get Singlet() { return new excitationType(1 << 6, "1") } static get Singlet() { return new excitationType(1 << 7, "1") }
static get Triplet() { return new excitationType(1 << 7, "3") } static get Triplet() { return new excitationType(1 << 8, "3") }
// Max bit shifts is 31 because int are int32 So 1 << 31 are -2147483648 // Max bit shifts is 31 because int are int32 So 1 << 31 are -2147483648
static get Others() { return new excitationType(1 << 31, String.raw`\mathrm{Others}`) } static get Others() { return new excitationType(1 << 31, String.raw`\mathrm{Others}`) }
static get All() { static get All() {
@ -25,7 +25,8 @@ class excitationTypes {
return this.All().filter((x) => { value & x[1] }) return this.All().filter((x) => { value & x[1] })
} }
} }
class excitationType {
class LaTeXDescribedValueBase {
constructor(value, laTeX) { constructor(value, laTeX) {
this.Value = value; this.Value = value;
this.LaTeX = laTeX this.LaTeX = laTeX
@ -34,6 +35,12 @@ class excitationType {
return this.Value; return this.Value;
} }
} }
class excitationType extends LaTeXDescribedValueBase{
}
class VertExcitationKind extends LaTeXDescribedValueBase{
}
class code { class code {
constructor(name, version) { constructor(name, version) {
this.name = name; this.name = name;
@ -207,6 +214,10 @@ class dataFileBase {
this.DOI = null this.DOI = null
this.sourceFile = null this.sourceFile = null
} }
static _GetMetaRexEx() {
//metadata RegExp (start with #; maybe somme spaces; : ; maybe somme space; datas)
return /^#\s*([A-Za-z_]+)\s*:\s*(.*)$/;
}
CopyExcitationsTypeFrom(data) { CopyExcitationsTypeFrom(data) {
for (const ex of this.excitations) { for (const ex of this.excitations) {
const ex2=data.excitations.find((e)=>{ const ex2=data.excitations.find((e)=>{
@ -217,7 +228,7 @@ class dataFileBase {
} }
} }
} }
static async loadAsync(file) { static async loadAsync(file,kind=undefined) {
switch (trueTypeOf(file)) { switch (trueTypeOf(file)) {
case String.name: case String.name:
file = getFullDataPath(file) file = getFullDataPath(file)
@ -227,68 +238,67 @@ class dataFileBase {
var str = await getTextFromUploadedFileAsync(file) var str = await getTextFromUploadedFileAsync(file)
break break
} }
var dat = this.loadString(str); var dat = this.loadString(str,kind);
dat.sourceFile = new websiteFile(file) dat.sourceFile = new websiteFile(file)
return dat return dat
} }
static readmetaPair(key, value, dat) { _OnReadMetaPair(key, value) {
switch (key) { switch (key) {
case "molecule": case "molecule":
dat.molecule = value this.molecule = value
break; break;
case "comment": case "comment":
dat.comment = value this.comment = value
break; break;
case "code": case "code":
dat.code = code.fromString(value) this.code = code.fromString(value)
break; break;
case "method": case "method":
dat.method = method.fromString(value) this.method = method.fromString(value)
break; break;
case "doi": case "doi":
dat.DOI = DOI.fromString(value); this.DOI = DOI.fromString(value);
break; break;
default: default:
} }
} }
static loadString(text) { _OnReadRow(line) {
// for each line with metadata var vals = line.match(/\([^\)]+\)|\S+/g)
var ismetaArea = true; var start = new state(parseInt(vals[0], 10), parseInt(vals[1], 10), vals[2]);
//metadata RegExp (start with #; maybe somme spaces; : ; maybe somme space; datas) var end = new state(parseInt(vals[3], 10), parseInt(vals[4],10), vals[5]);
var meta = /^#\s*([A-Za-z_]+)\s*:\s*(.*)$/; var hasType = vals.length >= 7 && isNaN(vals[6])
var classname = this.name var type = ((vals.length >= 7 && hasType) ? vals[6] : null)
var dat = eval(String.raw`new ${this.name}()`) if (type) {
function readmeta(line) { const m = type.match(/^\(([^\)]*)\)$/)
// get key value if (m) {
var match = line.match(meta) type = m[1]
// normalize key to lower
var key = match[1].toLowerCase()
//if data has value
if (match.length == 3 && match[2]) {
var val = match[2]
eval(String.raw`${classname}.readmetaPair(key,val,dat)`)
} }
} }
function readrow(line) { var val = ((vals.length >= 7 + hasType) ? parseFloat(vals[6 + hasType], 10) : NaN)
var vals = line.match(/\([^\)]+\)|\S+/g) var oscilatorForces = ((vals.length >= 8 + hasType) ? parseFloat(vals[7 + hasType], 10) : NaN)
var start = new state(parseInt(vals[0], 10), parseInt(vals[1], 10), vals[2]); var T1 = ((vals.length >= 9 + hasType) ? parseFloat(vals[8 + hasType], 10) : NaN)
var end = new state(parseInt(vals[3], 10), parseInt(vals[4],10), vals[5]); var isUnsafe = ((vals.length >= 10 + hasType) ? vals[9 + hasType] === true.toString() : false)
var hasType = vals.length >= 7 && isNaN(vals[6]) var ex = new excitationValue(start, end, type, val, oscilatorForces, T1, isUnsafe);
var type = ((vals.length >= 7 && hasType) ? vals[6] : null) if (this.VertExcitationKind) {
if (type) { ex.VertExcitationKind=this.VertExcitationKind
const m = type.match(/^\(([^\)]*)\)$/) }
if (m) { return ex;
type = m[1] };
} _OnReadMeta(line) {
} // get key value
var val = ((vals.length >= 7 + hasType) ? parseFloat(vals[6 + hasType], 10) : NaN) var match = line.match(dataFileBase._GetMetaRexEx())
var oscilatorForces = ((vals.length >= 8 + hasType) ? parseFloat(vals[7 + hasType], 10) : NaN) // normalize key to lower
var T1 = ((vals.length >= 9 + hasType) ? parseFloat(vals[8 + hasType], 10) : NaN) var key = match[1].toLowerCase()
var isUnsafe = ((vals.length >= 10 + hasType) ? vals[9 + hasType] === true.toString() : false) //if data has value
var ex = new excitationValue(start, end, type, val, oscilatorForces, T1, isUnsafe); if (match.length == 3 && match[2]) {
dat.excitations.push(ex); var val = match[2]
}; this._OnReadMetaPair(key,val)
}
}
static loadString(text,kind=null) {
// for each line with metadata
var ismetaArea = true;
var dat = new VertDataFile()
for (var line of text.split("\n")) { for (var line of text.split("\n")) {
//if it's not empty line //if it's not empty line
line = line.trim(); line = line.trim();
@ -296,61 +306,43 @@ class dataFileBase {
//if # may be metadata or comment //if # may be metadata or comment
if (line.charAt(0) == "#") { if (line.charAt(0) == "#") {
//if it's metadata //if it's metadata
if (ismetaArea && meta.test(line)) { if (ismetaArea && dataFileBase._GetMetaRexEx().test(line)) {
readmeta(line); dat._OnReadMeta(line);
} }
} else { //else its row } else { //else its row
ismetaArea = false; ismetaArea = false;
readrow(line); dat.excitations.push(dat._OnReadRow(line,kind));
} }
} }
} }
return dat return dat
} }
} }
class VertExcitationKinds{
class oneStateDataFileBase extends dataFileBase { static get Absorbtion() {return new VertExcitationKind(1, String.raw`\mathrm{A}`)}
constructor() { static get Fluorescence() {return new VertExcitationKind(1<<1, String.raw`\mathrm{F}`)}
}
class VertDataFile extends dataFileBase {
constructor(VertExcitationKind) {
super() super()
this.VertExcitationKind=VertExcitationKind
this.geometry = null this.geometry = null
} }
static readmetaPair(key, value, dat) { _OnReadMetaPair(key, value) {
if (key == "geom") { if (key == "geom") {
dat.geometry = method.fromString(value) this.geometry = method.fromString(value)
} }
else { else {
dataFileBase.readmetaPair(key, value, dat) super._OnReadMetaPair(key, value)
} }
} }
} _OnReadRow(line,kind) {
class AbsDataFile extends oneStateDataFileBase { var ex=super._OnReadRow(line)
ex.VertExcitationKind=kind
} return ex
class FluoDataFile extends oneStateDataFileBase {
}
class twoStateDataFileBase extends dataFileBase {
constructor() {
super()
this.GS = null
this.ES = null
}
static readmetaPair(key, value, dat) {
switch (key) {
case "gs":
dat.GS = method.fromString(value)
break;
case "es":
dat.ES = method.fromString(value)
break;
default:
dataFileBase.readmetaPair(key, value, dat)
}
} }
} }
class ZPEDataFile extends twoStateDataFileBase {
}
class CombinedData { class CombinedData {
constructor() { constructor() {
this.Abs = null this.Abs = null

View File

@ -0,0 +1,8 @@
function selectSelectAll_click(e) {
ctrl=$(e.target).next()
if (ctrl.prop('type') == 'select-multiple' ) {
ctrl.find("option").each(function() {
$(this).attr('selected', 'selected');
});
}
}