///////////////////////////////////////// // Functions to keep after refactoring // ///////////////////////////////////////// var syncKetcherLock = 0; var ignoreKetcherUpdates = 0 var ignoreTextFieldUpdates = 0 // The SMILES generated by Ketcher might look different than the one inserted // however we need this for internal comparison to check whether the SMILES taken // from the TextInput generates the same smiles. var SMILES = ""; // FIXME: marked for removal // function syncTextInputToKetcher(textInputId, ketcherId) { // var ketcher = getKetcher(ketcherId); // var textInputSMILES = $('#' + textInputId).val(); // data = { // "struct": textInputSMILES, // "output_format": "chemical/x-mdl-molfile", // "options": { // "smart-layout": true, // "ignore-stereochemistry-errors": true, // "mass-skip-error-on-pseudoatoms": false, // "gross-formula-add-rsites": true // } // } // ketcher.server.layout(data).then( // function(response) { // if(response.struct != '') { // console.log("Writing " + textInputSMILES + " to Ketcher"); // ketcher.setMolecule(textInputSMILES); // // Wait for ketcher to accept the change and set global SMILES // setTimeout(function() { // SMILES = ketcher.getSmiles(); // }, 250); // } // } // ).catch( // function(res) { // console.log("Promise failed" + res); // } // ); // } // FIXME: marked for removal // function syncKetcherToTextInput(ketcherId, textInputId) { // // Obtain values // var ketcher = getKetcher(ketcherId); // // Get the SMILES of the molecule currently drawn in Ketcher // var tempKetcherSMILES; // try { // tempKetcherSMILES = ketcher.getSmiles(); // } catch(err) { // console.log(err); // return; // } // // compare to SMILES from global scope // if(SMILES == tempKetcherSMILES) { // // There was no change originating from TextInput // return // } else { // SMILES = tempKetcherSMILES; // $("#" + textInputId).val(SMILES); // } // } // FIXME: marked for removal // function syncKetcherAndTextInput(origin, ketcherId, textInputId) { // // check if function is "locked" // if(origin == 'ketcher') { // // Early exit - no op // if (ignoreKetcherUpdates == 1) { // return; // } // // Lock updates triggered by textInput // ignoreTextFieldUpdates = 1; // // Do the sync // syncKetcherToTextInput(ketcherId, textInputId); // ignoreTextFieldUpdates = 0; // } else { // // Early exit - no op // if(ignoreTextFieldUpdates == 1) { // return; // } // ignoreKetcherUpdates = 1; // // Do the sync // syncTextInputToKetcher(textInputId, ketcherId); // ignoreKetcherUpdates = 0; // } // } // Returns the ketcher object usually located in an iframe function getKetcher(idToUse){ if (idToUse === undefined) { console.log("getKetcher() called without id!"); idToUse = 'ifKetcher'; } var ketcherFrame = document.getElementById(idToUse); if ('contentDocument' in ketcherFrame) { return ketcherFrame.contentWindow.ketcher; } else { // IE7 return document.frames[idToUse].window.ketcher; } } // FIXME: marked for removal // function enterKeyPressed(event){ // // 13 means return/enter // if (event.which == 13 || event.keyCode == 13) { // return false; // } // return true // }; // FIXME: marked for removal // Function to attach an RSS feed available at feedUrl and attaches it to attachElement // async function loadRSSFeed(attachElement, feedUrl) { // try { // const response = await fetch(feedUrl, { // headers: { // 'Accept': 'application/rss+xml' // } // }); // const text = await response.text(); // const parser = new DOMParser(); // const data = parser.parseFromString(text, 'application/xml'); // const items = data.querySelectorAll('item'); // items.forEach(item => { // const link = item.querySelector('link')?.textContent || ''; // const title = item.querySelector('title')?.textContent || ''; // const pubDate = item.querySelector('pubDate')?.textContent || ''; // const description = item.querySelector('description')?.textContent || ''; // document.getElementById(attachElement).innerHTML += // '
  • ' + // '

    ' + // '' + // title + // '

    ' + // pubDate + // '

    ' + // description + // '

  • '; // }); // } catch (error) { // console.error('Error loading RSS feed:', error); // } // } // FIXME: marked for removal // function hasValue(id) { // var element = document.getElementById(id); // if(element.value === "" // || element.value === undefined // || element.value === null // || element.value === "undefined"){ // return false; // } // return true; // } // FIXME: marked for removal // async function beforePredict(){ // // TODO make it a parameter // if(!hasValue("smilesinput")) { // return; // } // const smilesInput = document.getElementById('smilesinput'); // const encodedSMILES = encodeURIComponent(smilesInput.value); // // TODO Fix via templating to set host // const url = "/pathway?rootNode="+ encodedSMILES; // try { // const response = await fetch(url); // const result = await response.json(); // // If something is found the returned dict contains the key "pathway" if not it contains "object" // if(result.pathway){ // // TODO set as param // attachObjectsAsList("foundPathways", result.pathway); // } else { // document.getElementById("index-form").submit(); // } // } catch (error) { // console.error('Error in beforePredict:', error); // } // } // FIXME: marked for removal // function attachObjectsAsList(elementId, objects){ // var content =''; // console.log(foundone); // if(foundone){ // document.getElementById("foundPathways").innerHTML += content; // // Show the modal using native dialog API // const modal = document.getElementById("foundMatching"); // if (modal && modal.showModal) { // modal.showModal(); // } // } else { // document.getElementById("index-form").submit(); // } // } // FIXME: marked for removal // class Setting { // constructor(nameInputId, selectedPackagesId, relativeReasoningSelectId, cutoffInputId, evaluationTypeSelectId, // availableTSSelectId, formsId, tableId, summaryTableId) { // this.nameInputId = nameInputId; // this.selectedPackagesId = selectedPackagesId; // this.relativeReasoningSelectId = relativeReasoningSelectId; // this.cutoffInputId = cutoffInputId; // this.evaluationTypeSelectId = evaluationTypeSelectId; // this.availableTSSelectId = availableTSSelectId; // this.formsId = formsId; // this.tableId = tableId; // this.summaryTableId = summaryTableId; // // General settings // this.name = null; // this.selectedPackages = []; // // Relative Reasoning related // this.selectedRelativeReasoning = null; // this.cutoff = null; // this.evaluationType = null; // // parameters such as { "lowPH": 7, "highPH": 8 } // this.tsParams = {}; // } // FIXME: marked for removal // extractName() { // var tempName = $('#' + this.nameInputId).val() // if (tempName == '') { // console.log("Name was empty..."); // return; // } // this.name = tempName; // } // extractSelectedPackages() { // var selPacks = $("#" + this.selectedPackagesId + " :selected"); // var ref = this; // ref.selectedPackages = []; // selPacks.each(function () { // var obj = {} // obj['id'] = this.value; // obj['name'] = this.text; // ref.selectedPackages.push(obj); // }); // } // extractRelativeReasoning() { // var tempRR = $('#' + this.relativeReasoningSelectId + " :selected").val() // if (tempRR == '') { // console.log("RR was empty..."); // return; // } // var obj = {} // obj['id'] = $('#' + this.relativeReasoningSelectId + " :selected").val() // obj['name'] = $('#' + this.relativeReasoningSelectId + " :selected").text() // this.selectedRelativeReasoning = obj; // } // extractCutoff() { // var tempCutoff = $('#' + this.cutoffInputId).val() // if (tempCutoff == '') { // console.log("Cutoff was empty..."); // return; // } // this.cutoff = tempCutoff; // } // extractEvaluationType() { // var tempEvaluationType = $('#' + this.evaluationTypeSelectId).val() // if (tempEvaluationType == '') { // console.log("EvaluationType was empty..."); // return; // } // this.evaluationType = tempEvaluationType; // } // addTruncator() { // // triggered by "Add" // // will extract values and afterwards updates table + summary // var type = $("#" + this.availableTSSelectId + " :selected").val(); // var text = $("#" + this.availableTSSelectId + " :selected").text(); // var form = $("#" + type + "_form > :input") // // flag to check whether at least one input had a valid value // var addedValue = false; // // reference being used in each // var ref = this; // form.each(function() { // if(this.value == "" || this.value === "undefined"){ // console.log(this); // console.log("Skipping " + this.name); // } else { // var obj = {} // obj[this.name] = this.value; // obj['text'] = text; // ref.tsParams[type] = obj // } // }); // this.updateTable(); // this.updateSummaryTable(); // } // removeTruncator(rowId) { // var summary = rowId.startsWith("sum") ? true : false; // // plain key // var key = rowId.replace(summary ? "sum" : "trunc", "").replace("row", ""); // console.log("Removing " + key); // // remove the rows // $("#trunc"+ key + "row").remove(); // if($("#sum"+ key + "row").length > 0) { // $("#sum"+ key + "row").remove(); // } // delete this.tsParams[key]; // } // updateTable() { // // remove all children // $('#'+this.tableId + "Body").empty() // var innerHTML = "" + // "Name" + // "Value" + // "Action" + // ""; // for (var x in this.tsParams) { // var val = ""; // for (var y in this.tsParams[x]){ // if (y == 'text') { // continue; // } // val += this.tsParams[x][y] // } // innerHTML += "" + // "" + this.tsParams[x]['text'] + "" + // "" + val + "" + // ""+ // "" + // "" + // ""; // } // $('#'+this.tableId + "Body").append(innerHTML); // } // packageRows() { // var res = ''; // for(var p in this.selectedPackages) { // var obj = this.selectedPackages[p]; // res += "" + // "Package" + // "" + obj['name'] + "" + // "" + // // "" + // "" + // ""; // } // return res; // } // modelRow() { // if(this.selectedRelativeReasoning == null) { // return ''; // } // return "" + // "Relative Reasoning" + // "" + this.selectedRelativeReasoning['name'] + " " + (this.evaluationType == "singleGen" ? "SG" : "MG") + " with t=" + this.cutoff + " " + // "" + // // "" + // "" + // ""; // } // updateSummaryTable() { // // remove all children // $('#'+this.summaryTableId + "Body").empty() // var innerHTML = "" + // "Name" + // "Value" + // "Action" + // ""; // innerHTML += this.packageRows(); // innerHTML += this.modelRow(); // // var innerHTML = '' // for (var x in this.tsParams) { // var val = ""; // for (var y in this.tsParams[x]){ // if (y == 'text') { // continue; // } // val += this.tsParams[x][y] // } // innerHTML += "" + // "" + this.tsParams[x]['text'] + "" + // "" + val + "" + // ""+ // "" + // "" + // ""; // } // $('#'+this.summaryTableId + "Body").append(innerHTML); // } // } // TODO function queryResultToTable(appendId, result) { const container = document.getElementById(appendId); container.innerHTML = ''; var table = '' + '' + ''; var header = ''; for (var r in result['result']) { var keys = Object.keys(result['result'][r]); for (var k in keys) { header += ''; } break; } table += header; table += ''; table += ''; table += ''; var body = ''; for (var r in result['result']) { body += ''; for (var k in result['result'][r]) { body += ''; } body += ''; } table += body; table += ''; table += '
    ' + keys[k] + '
    ' + result['result'][r][k] + '
    '; container.innerHTML = table; } function showLoadingSpinner(attachOb) { // Benzene ring spinner - hexagon with rotating double bonds const spinnerHtml = `
    `; // Handle both ID selectors and DOM elements let element; if (typeof attachOb === 'string') { element = attachOb.startsWith('#') ? document.querySelector(attachOb) : document.getElementById(attachOb); } else { element = attachOb; } if (element) { element.innerHTML = spinnerHtml; } } // Keep old function name for backwards compatibility function makeLoadingGif(attachOb) { showLoadingSpinner(attachOb); } // FIXME: marked for removal // function cleanIdName(idName) { // return idName.replace(/[ \-()]/g, "") // } // FIXME: marked for removal // function makeAccordionHead(accordionId, accordionTitle, reviewStatus) { // return "
    " // + "
    " // + "
    " // + accordionTitle + reviewStatus // + "
    " // + "
    "; // } // FIXME: marked for removal // function makeAccordionPanel(accordionId, panelName, panelContent, collapsed, id) { // if(panelContent == "" || panelContent == "no description") { // return ""; // } // if(collapsed == true) { // collapsed = "in"; // } else { // collapsed = ""; // } // var panelId = typeof id === "undefined" ? cleanIdName(panelName) : id; // return "
    " // + "

    " // + "" // + panelName // + "" // + "

    " // + "
    " // + ""; // } // FIXME: marked for removal // async function fillPRCurve(modelUri, onclick){ // if (modelUri == '') { // return; // } // // clear div // const plotDiv = document.getElementById('plotDiv'); // plotDiv.innerHTML = ''; // // for the time being add animation // makeLoadingGif('#plotDiv'); // try { // const response = await fetch(modelUri + "?prcurve"); // const result = await response.json(); // // remove loading gif // plotDiv.innerHTML = ''; // // check if model is in a proper state // if(result.hasOwnProperty('error')){ // var content = '
    '+result.error+' \nYou can check the model here.
    '; // plotDiv.innerHTML += content; // return // } // var chartPanel = '
    '; // plotDiv.innerHTML += chartPanel; // // Labels // var x = ['Recall']; // var y = ['Precision']; // var thres = ['threshold']; // // Compare function for the given array // function compare(a, b) { // if (a.threshold < b.threshold) // return -1; // else if (a.threshold > b.threshold) // return 1; // else // return 0; // } // // gets the index for a certain value // function getIndexForValue(data, val, val_name) { // for(var idx in data) { // if(data[idx][val_name] == val) { // return idx; // } // } // return -1; // } // var data = result.prdata; // var dataLength = Object.keys(data).length; // data.sort(compare); // // collect data in 3 individual arrays // for (var idx in data) { // var d = data[idx]; // x.push(d.recall); // y.push(d.precision); // thres.push(d.threshold); // } // // generate the actual chart with values collected above // var chart = c3.generate({ // bindto: '#chart', // data: { // onclick: function (d, e) { // var idx = d.index; // var thresh = data[dataLength-idx-1].threshold; // onclick(thresh) // }, // x: 'Recall', // y: 'Precision', // columns: [ // x, // y, // //thres // ] // }, // size: { // height: 400, // TODO: Make variable to current modal width // width: 480 // }, // axis: { // x: { // max: 1, // min: 0, // label: 'Recall', // padding: 0, // tick: { // fit: true, // values: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] // } // }, // y: { // max: 1, // min: 0, // label: 'Precision', // padding: 0, // tick: { // fit: true, // values: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] // } // } // }, // point: { // r: 4 // }, // tooltip: { // format: { // title: function (recall) { // idx = getIndexForValue(data, recall, "recall"); // if(idx != -1) { // return "Threshold: " + data[idx].threshold; // } // return ""; // }, // value: function (precision, ratio, id) { // return undefined; // } // } // }, // zoom: { // enabled: true // } // }); // } catch (error) { // console.error('Error loading PR curve:', error); // const plotDiv = document.getElementById('plotDiv'); // plotDiv.innerHTML = '
    Error loading PR curve data.
    '; // } // } function handleAssessmentResponse(depict_url, data) { var inside_app_domain = "This compound is " + (data["assessment"]["inside_app_domain"] ? "inside" : "outside") + " the Applicability Domain derived from the chemical (PCA) space constructed using the training data." + ""; var functionalGroupsImgSrc = null; var reactivityCentersImgSrc = null; if (data['assessment']['node'] !== undefined) { functionalGroupsImgSrc = ""; reactivityCentersImgSrc = "" } else { functionalGroupsImgSrc = ""; reactivityCentersImgSrc = "" } tpl = `

    Functional Groups Covered by Model

    ${inside_app_domain}

    ${functionalGroupsImgSrc}

    Reactivity Centers

    ${reactivityCentersImgSrc}
    ` var transformations = ''; for (t in data['assessment']['transformations']) { transObj = data['assessment']['transformations'][t]; var neighbors = ''; for (n in transObj['neighbors']) { neighObj = transObj['neighbors'][n]; var neighImg = ""; var objLink = `${neighObj['name']}` var neighPredProb = "Predicted probability: " + neighObj['probability'].toFixed(2) + ""; var pwLinks = ''; for (pw in neighObj['related_pathways']) { var pwObj = neighObj['related_pathways'][pw]; pwLinks += "" + pwObj['name'] + ""; } var expPathways = `

    Experimental Pathways

    ${pwLinks}
    ` if (pwLinks === '') { expPathways = '' } neighbors += `

    Analog Transformation on ${neighObj['name']}

    ${objLink} ${neighPredProb} ${expPathways}

    ${neighImg}
    ` } var panelName = null; var objLink = null; if (transObj['is_predicted']) { panelName = `Predicted Transformation by ${transObj['rule']['name']}`; for (e in transObj['edges']) { objLink = `${transObj['edges'][e]['name']}` break; } } else { panelName = `Potential Transformation by applying ${transObj['rule']['name']}`; objLink = `${transObj['rule']['name']}` } var predProb = "Predicted probability: " + transObj['probability'].toFixed(2) + ""; var timesTriggered = "This rule has triggered " + transObj['times_triggered'] + " times in the training set"; var reliability = "Reliability: " + transObj['reliability'].toFixed(2) + " (" + (transObj['reliability'] > data['ad_params']['reliability_threshold'] ? ">" : "<") + " Reliability Threshold of " + data['ad_params']['reliability_threshold'] + ") "; var localCompatibility = "Local Compatibility: " + transObj['local_compatibility'].toFixed(2) + " (" + (transObj['local_compatibility'] > data['ad_params']['local_compatibility_threshold'] ? ">" : "<") + " Local Compatibility Threshold of " + data['ad_params']['local_compatibility_threshold'] + ")"; var transImg = ""; var transformation = `

    ${panelName}

    ${objLink} ${predProb} ${timesTriggered} ${reliability} ${localCompatibility}

    ${transImg}

    ${neighbors}
    ` transformations += transformation; } res = tpl + transformations; document.getElementById('appDomainAssessmentResultTable').innerHTML += res; }