2025-01-23 14:33:43 +01:00
<!DOCTYPE html>
< meta charset = "utf-8" >
< html >
< header >
< link href = "bootstrap-5.0.2-dist/css/bootstrap.min.css" rel = "stylesheet" > < / link >
< script src = "bootstrap-5.0.2-dist/js/bootstrap.bundle.min.js" > < / script >
< / header >
< body >
2025-02-25 18:11:42 +01:00
< nav class = "navbar navbar-expand-lg navbar-light bg-light" >
< div class = "container-fluid" >
< button class = "navbar-toggler" type = "button" data-bs-toggle = "collapse" data-bs-target = "#navbarTogglerDemo03" aria-controls = "navbarTogglerDemo03" aria-expanded = "false" aria-label = "Toggle navigation" >
< span class = "navbar-toggler-icon" > < / span >
< / button >
< a class = "navbar-brand" href = "#" > Open Microscopy App< / a >
< div class = "collapse navbar-collapse" id = "navbarTogglerDemo03" >
< ul class = "navbar-nav me-auto mb-2 mb-lg-0" >
< li class = "nav-item dropdown" >
< a class = "nav-link dropdown-toggle" href = "#" id = "navbarScrollingDropdown" role = "button" data-bs-toggle = "dropdown" aria-expanded = "false" >
Settings
< / a >
< ul class = "dropdown-menu" aria-labelledby = "navbarScrollingDropdown" >
< li > < a class = "dropdown-item" href = "/setup_microscope.html" > Setup Camera< / a > < / li >
< li > < a class = "dropdown-item" href = "/sample_prep_protocol.html" > Setup Preparation Protocol< / a > < / li >
< li > < hr class = "dropdown-divider" > < / li >
< li > < a class = "dropdown-item" href = "#" > Defaults< / a > < / li >
< / ul >
< / li >
< li class = "nav-item" >
< a class = "nav-link active" aria-current = "page" href = "/sample_intake.html" > add sample< / a >
< / li >
< li class = "nav-item dropdown" >
< a class = "nav-link dropdown-toggle" href = "#" id = "navbarScrollingDropdown" role = "button" data-bs-toggle = "dropdown" aria-expanded = "false" >
Observe
< / a >
< ul class = "dropdown-menu" aria-labelledby = "navbarScrollingDropdown" >
< li > < a class = "dropdown-item" href = "/observe_nema.html" > Nematodes< / a > < / li >
< li > < a class = "dropdown-item" href = "/observe_main.html" > Filamentous and Protozoa< / a > < / li >
< li > < a class = "dropdown-item" href = "/observe_bact.html" > Bacteria< / a > < / li >
< / ul >
< / li >
< li class = "nav-item" >
< a class = "nav-link" href = "/create_report.html" > generate report< / a >
< / li >
< / ul >
< / div >
< / div >
< / nav >
2025-01-23 14:33:43 +01:00
< div class = "container" >
< div class = "row" >
< div class = "col-3" >
< label class = "form-label" for = "sample_chooser" > choose the sample< / label >
< select class = "form-select" name = "sample_chooser" id = "sample_chooser" > < / select >
< / div >
< / div >
2025-01-29 15:43:14 +01:00
< h1 > Report for Sample Number < span id = "sample_id" > ???< / span > < / h1 >
< p >
< span id = "sample_name" > ???< / span > is a < span id = "sample_type" > ???< / span >
sample taken on < span id = "sample_date" > ???< / span > at these coordinates
< span id = "sample_location" > ???< / span > .
< / p >
< div id = "main_scan_div" >
< h2 > Filamentous Organisms and Protozoa < / h2 >
< p id = "main_scan_text" >
The main scan was performed on < span id = main_scan_datetime > ???< / span > using the
protocol < span id = "prep_protocol_name" > ???< / span > and camera setup
< span id = cam_setup_name > ???< / span > .
< / p >
< p >
2025-02-06 14:00:58 +01:00
Dividing the sample volume V< sub > Sample< / sub > = < span id = "sample_volume" > ???< / span > uL
by the size of the coverslip A< sub > coverslip< / sub > =
2025-01-29 15:43:14 +01:00
< span id = "coverslip_height" > ???< / span > mm x < span id = "coverslip_width" > ???< / span > mm
2025-02-06 14:00:58 +01:00
yields the observed height h< sub > observed< / sub > = V< sub > Sample< / sub > / A< sub > coverslip< / sub > =
< span id = "observed_height" > < / span > um. Multipilcation with the size of the the field of view
A< sub > FoV< / sub > = < span id = "FoV_height" > ???< / span > um x
< span id = "FoV_width" > ???< / span > um
yields the observed Volume V< sub > observed< / sub > =
h< sub > observed< / sub > * A< sub > FoV< / sub > = < span id = "observed_volume" > ???< / span > uL per FoV.
The volume of organisms per FoV is multiplied with the
dilution Factor F< sub > dilution< / sub > = < span id = "dilution_factor" > ???< / span >
and devided by V< sub > observed< / sub > to calculate the abundance per uL.
2025-01-29 15:43:14 +01:00
< / p >
< p >
F< sub > multiplication< / sub > = F< sub > dilution< / sub > * 1 uL / V< sub > observed< / sub > = < span id = "factor" > ???< / span >
< / p >
2025-01-23 14:33:43 +01:00
2025-02-05 14:08:44 +01:00
< h3 > Filamentous Organisms and Protozoa Table< / h3 >
2025-01-29 15:43:14 +01:00
< table class = "table" id = "main_scan_table" style = "width:100%" >
2025-01-23 14:33:43 +01:00
< thead >
< tr >
< th >
2025-01-29 15:43:14 +01:00
organism
2025-01-23 14:33:43 +01:00
< / th >
< th >
2025-02-05 14:08:44 +01:00
abundance [ug/uL] or [1/uL]
2025-01-23 14:33:43 +01:00
< / th >
< th >
2025-01-29 15:43:14 +01:00
standard deviation [%]
< / th >
2025-01-23 14:33:43 +01:00
< / th >
< / tr >
< / thead >
2025-01-29 15:43:14 +01:00
< tbody >
< / tbody >
2025-01-23 14:33:43 +01:00
< / table >
2025-01-29 15:43:14 +01:00
< / div >
2025-02-05 14:09:24 +01:00
< div id = "bacteria_scan_div" >
< h2 > Bacteria Scan< / h2 >
< p >
2025-02-06 14:00:58 +01:00
The bacteria scan has been performed on < span id = "bact_scan_datetime" > ???< / span > .
Dividing the sample volume V< sub > Sample< / sub > = < span id = "sample_volume_bact" > ???< / span > uL
by the size of the coverslip A< sub > coverslip< / sub > =
2025-02-05 14:09:24 +01:00
< span id = "coverslip_height_bact" > ???< / span > mm x < span id = "coverslip_width_bact" > ???< / span > mm
2025-02-06 14:00:58 +01:00
yields the observed height h< sub > observed< / sub > = V< sub > Sample< / sub > / A< sub > coverslip< / sub > =
< span id = "observed_height_bact" > < / span > um. Multipilcation with the size of the
2025-02-05 14:09:24 +01:00
the field of view A< sub > FoV< / sub > = < span id = "FoV_height_bact" > ???< / span > um x
2025-02-06 14:00:58 +01:00
< span id = "FoV_width_bact" > ???< / span > um yields the observed Volume
V< sub > observed< / sub > = h< sub > observed< / sub > * A< sub > FoV< / sub > = < span id = "observed_volume_bact" > ???< / span > uL per FoV. The volume of organisms per FoV is multiplied with the
dilution Factor F< sub > dilution< / sub > = < span id = "dilution_factor_bact" > ???< / span >
and devided by V< sub > observed< / sub > to calculate the abundance per uL:
< / p >
< p >
F< sub > multiplication< / sub > = F< sub > dilution< / sub > * 1 uL / V< sub > observed< / sub > = < span id = "factor_bact" > ???< / span >
< / p >
2025-02-05 14:09:24 +01:00
< h3 > Bacteria Table < / h3 >
< table class = "table" id = "bact_scan_table" style = "width:100%" >
< thead >
< tr >
< th >
type of Bacteria
< / th >
< th >
count per FoV
< / th >
< th >
area [um²] per FoV
< / th >
< th >
number per uL +- [%]
< / th >
< th >
~ ug / uL +- [%]
< / th >
< / tr >
< / thead >
< tbody >
< / tbody >
< / table >
< h3 > Bacterial to Fungal Biomass < / h3 >
< p > The Bacterial m< sub > Bacteria< / sub > = < span id = "bacterial_biomass" > ???< / span >
to Fungal Biomass m< sub > Fungi< / sub > = < span id = "fungal_biomass" > ???< / span > .< br >
m< sub > Fungi< / sub > / m< sub > Bacteria< / sub > = < span id = "f_to_b_biomass" > ???< / span >
< / p >
< / div >
2025-01-29 15:43:14 +01:00
< div id = "nematode_scan_div" >
< h2 > Nematode Scan < / h2 >
< p >
2025-02-05 14:09:24 +01:00
The namatode scan has been performed on < span id = "nema_scan_datetime" > ???< / span >
using the protocol < span id = "prep_protocol_name_bact" > ???< / span > and camera setup
< span id = cam_setup_name_bact > ???< / span > . < br >
2025-01-29 15:43:14 +01:00
To calculate the abundance of nematodes per cubic centimeter of sample the dilution Factor F< sub > dilution< / sub > =
< span id = "dilution_nema" > ???< / span > is divided by the sample size V< sub > sample< / sub > =
< span id = "samplesize_nema" > ???< / span > uL. < br >
The multiplication factor for the nematode scan is: < br >
F< sub > nematode< / sub > = F< sub > dilution< / sub > / V< sub > sample< / sub > = < span id = "multiplication_factor_nema" > ???< / span >
< / p >
2025-02-05 14:09:24 +01:00
2025-01-29 15:43:14 +01:00
< h3 > Nematode Table < / h3 >
< table class = "table" id = "nema_scan_table" style = "width:100%" >
2025-01-23 14:33:43 +01:00
< thead >
< tr >
< th >
2025-01-29 15:43:14 +01:00
functional group
2025-01-23 14:33:43 +01:00
< / th >
< th >
2025-01-29 15:43:14 +01:00
count
2025-01-23 14:33:43 +01:00
< / th >
< th >
2025-01-29 15:43:14 +01:00
number per cm³
2025-01-23 14:33:43 +01:00
< / th >
< / tr >
< / thead >
2025-01-29 15:43:14 +01:00
< tbody >
< / tbody >
2025-01-23 14:33:43 +01:00
< / table >
< / div >
2025-01-29 15:43:14 +01:00
2025-02-05 14:09:24 +01:00
2025-01-29 15:43:14 +01:00
< / div >
2025-01-23 14:33:43 +01:00
< / body >
< script >
var sample;
var samples = {};
2025-01-29 15:43:14 +01:00
var main_scan_result
var prep_protocol;
var microscope_setup;
var multiplication_factor_main_scan;
var nema_scan_result
var prep_protocol_nema;
var microscope_setup_nema
var multiplication_factor_nema_scan;
var bact_scan_result;
var prep_protocol_bact;
var microscope_setup_bact;
var multiplication_factor_bact_scan;
var multiplication_factor_main_scan;
// open db
var db;
let openRequest = indexedDB.open("my_db");
2025-01-23 14:33:43 +01:00
openRequest.onerror = function() {
console.error("Error", openRequest.error);
};
openRequest.onsuccess = function() {
db = openRequest.result;
get_all_samples();
// continue working with database using db object
};
2025-01-29 15:43:14 +01:00
// first get all samples and make a sample chooser
2025-01-23 14:33:43 +01:00
function get_all_samples(){
const request = db.transaction('sample')
.objectStore('sample')
.openCursor();
request.onsuccess = ()=> {
let cursor = event.target.result;
if (cursor) {
// Access the current record
make_sample_chooser(cursor.value, cursor.key);
2025-01-29 15:43:14 +01:00
2025-01-23 14:33:43 +01:00
// Move to the next record
cursor.continue();
}
2025-01-29 15:43:14 +01:00
else{
sample = samples[sample_chooser.value];
write_sample_description(sample);
get_result_main(sample_chooser.value);
get_result_nema(sample_chooser.value);
2025-02-05 14:09:42 +01:00
get_result_bact(sample_chooser.value);
2025-01-29 15:43:14 +01:00
}
2025-01-23 14:33:43 +01:00
}
request.onerror = (err)=> {
console.error(`Error to get all setups: ${err}`)
}
}
var sample_chooser = document.querySelector("#sample_chooser");
function make_sample_chooser(sample, key){
let sampleID = document.createElement("option");
let text = document.createTextNode(sample.Name);
sampleID.value = key;
samples[key] = sample;
sampleID.appendChild(text);
sample_chooser.appendChild(sampleID);
}
sample_chooser.addEventListener("change", change_sample);
function change_sample(){
sample = samples[this.value];
2025-01-29 15:43:14 +01:00
write_sample_description(sample);
get_result_main(this.value);
get_result_nema(this.value);
2025-02-05 14:09:42 +01:00
get_result_bact(this.value);
2025-01-29 15:43:14 +01:00
2025-01-23 14:33:43 +01:00
};
2025-01-29 15:43:14 +01:00
function write_sample_description(sample){
2025-02-06 14:00:58 +01:00
let latLon = sample.Place.split(', ');
let lat = Number(latLon[0]);
let lon = Number(latLon[1]);
2025-01-29 15:43:14 +01:00
document.querySelector("#sample_id").textContent = sample_chooser.value;
document.querySelector("#sample_name").textContent = sample.Name;
document.querySelector("#sample_type").textContent = sample.Type;
2025-02-06 14:00:58 +01:00
document.querySelector("#sample_date").textContent = sample.Date_Collected.toDateString() + ' at ' + sample.Date_Collected.toLocaleTimeString();
document.querySelector("#sample_location").textContent = lat.toFixed(4) + ', ' + lon.toFixed(4);
2025-01-29 15:43:14 +01:00
}
function write_main_scan_description(main_result, prep_protocol, microscope_setup){
// observed height in um -> sample size [uL] * 10^9 / coverslip Area [mm²] * 10^6
// -> yields 1000 * samplesize[uL] / coverslipArea[mm²]
let observed_height = 1000 * Number(prep_protocol.Sample_Size) /
(Number(microscope_setup.Slip_Height) * Number(microscope_setup.Slip_Width));
// observed Volume in uL -> height [um] * FoV [um²] = um³ -- 1 um³ = 1* 10^-9 uL
let observed_volume = observed_height *
Number(microscope_setup.FoV_Width)*Number(microscope_setup.FoV_Height)*Math.pow(10, -9);
multiplication_factor_main_scan = main_result.dilution / observed_volume;
2025-02-06 14:00:58 +01:00
document.querySelector("#main_scan_datetime").textContent = main_result.datetime.toDateString() + ' at ' + main_result.datetime.toLocaleTimeString();
sample.Date_Collected.toDateString() + ' at ' + sample.Date_Collected.toLocaleTimeString();
2025-01-29 15:43:14 +01:00
document.querySelector("#prep_protocol_name").textContent = prep_protocol.name;
document.querySelector("#cam_setup_name").textContent = microscope_setup.name;
document.querySelector("#coverslip_height").textContent = microscope_setup.Slip_Height;
document.querySelector("#coverslip_width").textContent = microscope_setup.Slip_Width;
document.querySelector("#sample_volume").textContent = prep_protocol.Sample_Size;
document.querySelector("#observed_height").textContent = observed_height.toFixed(2);
document.querySelector("#FoV_height").textContent = microscope_setup.FoV_Height;
document.querySelector("#FoV_width").textContent = microscope_setup.FoV_Width;
document.querySelector("#observed_volume").textContent = observed_volume.toExponential(2);
document.querySelector("#dilution_factor").textContent = main_result.dilution;
2025-02-06 14:00:58 +01:00
document.querySelector("#factor").textContent = multiplication_factor_main_scan.toFixed(2);
2025-01-29 15:43:14 +01:00
}
// get results of the main scan + prep_protocol and microscope_setup
function get_result_main(sampleID){
const transaction = db.transaction('main_scan');
const objStore = transaction.objectStore('main_scan')
const index = objStore.index("sampleID");
const get_request = index.get(sampleID);
get_request.onsuccess = () => {
get_prep_protocol(get_request.result);
get_microscope_setup(get_request.result);
main_scan_result = get_request.result;
}
get_request.onerror = (err)=> {
console.error(`Error to get all setups: ${err}`)
}
}
function get_prep_protocol(result_obj){
const request = db.transaction('prep_protocol')
.objectStore('prep_protocol')
.get(Number(result_obj.prepID));
request.onsuccess = () => {
prep_protocol = request.result;
if (microscope_setup & & prep_protocol & & main_scan_result){
write_main_scan_description(main_scan_result, prep_protocol, microscope_setup);
render_main_scan_table(main_scan_result.result);
}
}
request.onerror = (err)=> {
console.error(`Error to get all setups: ${err}`)
}
}
function get_microscope_setup(result_obj){
console.log(result_obj);
const request = db.transaction('microscope_setup')
.objectStore('microscope_setup')
.get(Number(result_obj.setupID));
request.onsuccess = () => {
microscope_setup = request.result;
if (microscope_setup & & prep_protocol & & main_scan_result){
write_main_scan_description(main_scan_result, prep_protocol, microscope_setup);
render_main_scan_table(main_scan_result.result);
}
}
request.onerror = (err)=> {
console.error(`Error to get all setups: ${err}`)
}
}
function total_organisms_in_FoV(FoV){
var total = {
"Fungi" : 0.0,
"Oomycete" : 0.0,
"Actinobacteria" : 0.0,
"Flagelate" : 0.0,
"Ciliate" : 0.0,
"Amoeba" : 0.0,
}
FoV.forEach((item, i) => {
var all_organisms_in_picture = total_organisms(item.organisms);
var keys = Object.keys(all_organisms_in_picture);
for (let i = 0; i < keys.length ; + + i ) {
total[keys[i]] += all_organisms_in_picture[keys[i]];
2025-01-23 14:33:43 +01:00
}
2025-01-29 15:43:14 +01:00
});
return total;
}
function total_organisms(organisms){
var total = {
"Fungi" : 0.0,
"Oomycete" : 0.0,
"Actinobacteria" : 0.0,
"Flagelate" : 0.0,
"Ciliate" : 0.0,
"Amoeba" : 0.0,
}
organisms.forEach((item, i) => {
switch (item.type){
case "Fungi":
// calculate the Volume of filamentous organisms
total.Fungi += item.length*Number(microscope_setup.FoV_Width)*
Math.pow((item.width*Number(microscope_setup.FoV_Width)),2.0)*Math.PI/4.0;
break
case "Oomycete":
total.Oomycete += item.length*Number(microscope_setup.FoV_Width)*
Math.pow((item.width*Number(microscope_setup.FoV_Width)),2.0)*Math.PI/4.0;
break
case "Actinobacteria":
2025-02-05 14:09:42 +01:00
total.Actinobacteria += item.length*Number(microscope_setup.FoV_Width)*Math.PI/4.0;
2025-01-29 15:43:14 +01:00
break
case "Flagelate":
total.Flagelate +=1;
break
case "Ciliate":
total.Ciliate +=1;
break
case "Amoeba":
total.Amoeba +=1;
break
}
});
return total;
}
function get_standard_deviation(reading){
var total = {
"Fungi" : 0.0,
"Oomycete" : 0.0,
"Actinobacteria" : 0.0,
"Flagelate" : 0.0,
"Ciliate" : 0.0,
"Amoeba" : 0.0,
}
reading.forEach((item, index) => {
var all_organisms_in_FoV = total_organisms_in_FoV(item);
var keys = Object.keys(all_organisms_in_FoV);
for (let i = 0; i < keys.length ; + + i ) {
total[keys[i]] += all_organisms_in_FoV[keys[i]];
}
});
var mean = {};
var standard_deviation = {};
var keys = Object.keys(total);
for (var i = 0; i < keys.length ; + + i ) {
mean[keys[i]] = total[keys[i]]/reading.length;
standard_deviation[keys[i]] = 0;
}
reading.forEach((item, index) => {
var all_organisms_in_FoV = total_organisms_in_FoV(item);
var keys = Object.keys(all_organisms_in_FoV);
for (var i = 0; i < keys.length ; + + i ) {
standard_deviation[keys[i]] += Math.pow(all_organisms_in_FoV[keys[i]]-mean[keys[i]], 2);
}
});
for (var i = 0; i < keys.length ; + + i ) {
standard_deviation[keys[i]] = Math.sqrt(standard_deviation[keys[i]]/reading.length);
}
return {"mean" : mean, "standard_deviation" : standard_deviation};
}
var result_table = document.querySelector("#main_scan_table");
function render_main_scan_table(result){
// combine all readings into one dataset
combined_set = [];
result.forEach((item, i) => {
item.forEach((item2, j) => {
combined_set.push(item2);
});
});
let res = get_standard_deviation(combined_set);
console.log(res);
for (key in res.mean){
render_main_scan_table_row(key, res.mean[key], res.standard_deviation[key])
}
}
function render_main_scan_table_row(key, mean, stdev){
let newRow = result_table.children[1].insertRow();
switch(key){
case "Fungi":
case "Oomycete":
case "Actinobacteria":
newRow.insertCell(0).innerHTML = key ;
// get
2025-02-06 14:00:58 +01:00
newRow.insertCell(1).innerHTML = (mean * Math.pow(10, -6) * multiplication_factor_main_scan).toFixed(2);
newRow.insertCell(2).innerHTML = (stdev/mean * 100).toFixed(2);
2025-01-29 15:43:14 +01:00
break
default:
newRow.insertCell(0).innerHTML = key;
2025-02-06 14:00:58 +01:00
newRow.insertCell(1).innerHTML = (mean * multiplication_factor_main_scan).toFixed(2);
newRow.insertCell(2).innerHTML = (stdev/mean * 100).toFixed(2);
2025-01-29 15:43:14 +01:00
}
}
// Nematodes
function get_result_nema(sampleID){
const transaction = db.transaction('nematode_scan');
const objStore = transaction.objectStore('nematode_scan')
const index = objStore.index("sampleID");
const get_request = index.get(sampleID);
get_request.onsuccess = () => {
console.log(get_request.result);
get_prep_protocol_nema(get_request.result);
get_microscope_setup_nema(get_request.result);
nema_scan_result = get_request.result;
}
get_request.onerror = (err)=> {
console.error(`Error to get all setups: ${err}`)
}
}
function get_prep_protocol_nema(result_obj){
const request = db.transaction('prep_protocol')
.objectStore('prep_protocol')
.get(Number(result_obj.prepID));
request.onsuccess = () => {
prep_protocol_nema = request.result;
if (microscope_setup_nema & & prep_protocol_nema & & nema_scan_result){
write_nema_scan_description(main_scan_result, prep_protocol_nema, microscope_setup_nema);
render_nema_scan_table(nema_scan_result.result);
}
2025-01-23 14:33:43 +01:00
}
request.onerror = (err)=> {
console.error(`Error to get all setups: ${err}`)
}
}
2025-01-29 15:43:14 +01:00
function get_microscope_setup_nema(result_obj){
console.log(result_obj);
const request = db.transaction('microscope_setup')
.objectStore('microscope_setup')
.get(Number(result_obj.setupID));
request.onsuccess = () => {
microscope_setup = request.result;
if (microscope_setup & & prep_protocol & & main_scan_result){
write_nema_scan_description(main_scan_result, prep_protocol, microscope_setup);
render_nema_scan_table(nema_scan_result.nematodes);
}
}
request.onerror = (err)=> {
console.error(`Error to get all setups: ${err}`)
}
}
function write_nema_scan_description(result, protocol, setup){
multiplication_factor_nema_scan = (result.dilution / protocol.Sample_Size) * Math.pow(10,3);
2025-02-06 14:00:58 +01:00
document.querySelector("#nema_scan_datetime").innerHTML = result.datetime.toDateString() + ' at ' + result.datetime.toLocaleTimeString();
2025-01-29 15:43:14 +01:00
document.querySelector("#dilution_nema").innerHTML = result.dilution;
document.querySelector("#samplesize_nema").innerHTML = protocol.Sample_Size;
document.querySelector("#multiplication_factor_nema").innerHTML = multiplication_factor_nema_scan;
}
var nema_table = document.querySelector("#nema_scan_table");
function render_nema_scan_table(result){
let nema_count = {
"Fungal_Feeding" : 0,
"Bacterial_Feeding" : 0,
"Root_Feeding" : 0,
"Predatory" : 0,
}
for (let i = 0; i < result.length ; i + + ) {
nema_count[result[i].type] +=1;
}
for (key in nema_count){
render_nema_scan_table_row(key, nema_count[key]);
}
}
function render_nema_scan_table_row(key, count){
let newRow = nema_table.children[1].insertRow();
newRow.insertCell(0).innerHTML = key;
newRow.insertCell(1).innerHTML = count;
newRow.insertCell(2).innerHTML = count * multiplication_factor_nema_scan;
}
2025-02-05 14:09:42 +01:00
// bacteria
function get_result_bact(sampleID){
const transaction = db.transaction('bacterial_scan');
const objStore = transaction.objectStore('bacterial_scan')
const index = objStore.index("sampleID");
const get_request = index.get(sampleID);
get_request.onsuccess = () => {
bact_scan_result = get_request.result;
get_prep_protocol_bact(get_request.result);
get_microscope_setup_bact(get_request.result);
}
get_request.onerror = (err)=> {
console.error(`Error to get all setups: ${err}`)
}
}
function get_prep_protocol_bact(result_obj){
const request = db.transaction('prep_protocol')
.objectStore('prep_protocol')
.get(Number(result_obj.prepID));
request.onsuccess = () => {
prep_protocol_bact = request.result;
if (microscope_setup_bact & & prep_protocol_bact & & bact_scan_result){
write_bact_scan_description(bact_scan_result, prep_protocol_bact, microscope_setup_bact);
render_bact_scan_table(bact_scan_result);
}
}
request.onerror = (err)=> {
console.error(`Error to get all setups: ${err}`)
}
}
function get_microscope_setup_bact(result_obj){
const request = db.transaction('microscope_setup')
.objectStore('microscope_setup')
.get(Number(result_obj.setupID));
request.onsuccess = () => {
microscope_setup_bact = request.result;
if (microscope_setup_bact & & prep_protocol_bact & & bact_scan_result){
write_bact_scan_description(bact_scan_result, prep_protocol_bact, microscope_setup_bact);
render_bact_scan_table(bact_scan_result.result);
}
}
request.onerror = (err)=> {
console.error(`Error to get all setups: ${err}`)
}
}
function write_bact_scan_description(result, protocol, setup){
console.log('hi from writer')
// observed height in um -> sample size [uL] * 10^9 / coverslip Area [mm²] * 10^6
// -> yields 1000 * samplesize[uL] / coverslipArea[mm²]
let observed_height_bact = 1000 * Number(protocol.Sample_Size) /
(Number(setup.Slip_Height) * Number(setup.Slip_Width));
// observed Volume in uL -> height [um] * FoV [um²] = um³ -- 1 um³ = 1* 10^-9 uL
let observed_volume_bact = observed_height_bact *
Number(setup.FoV_Width)*Number(setup.FoV_Height)*Math.pow(10, -9);
multiplication_factor_bact_scan = result.dilution / observed_volume_bact;
2025-02-06 14:00:58 +01:00
document.querySelector("#bact_scan_datetime").textContent = result.datetime.toDateString() + " at " + result.datetime.toLocaleTimeString();
2025-02-05 14:09:42 +01:00
document.querySelector("#prep_protocol_name_bact").textContent = protocol.name;
document.querySelector("#cam_setup_name_bact").textContent = setup.name;
document.querySelector("#coverslip_height_bact").textContent = setup.Slip_Height;
document.querySelector("#coverslip_width_bact").textContent = setup.Slip_Width;
document.querySelector("#sample_volume_bact").textContent = prep_protocol.Sample_Size;
document.querySelector("#observed_height_bact").textContent = observed_height_bact.toFixed(2);
document.querySelector("#FoV_height_bact").textContent = microscope_setup.FoV_Height;
document.querySelector("#FoV_width_bact").textContent = microscope_setup.FoV_Width;
document.querySelector("#observed_volume_bact").textContent = observed_volume_bact.toExponential(2);
document.querySelector("#dilution_factor_bact").textContent = result.dilution;
2025-02-06 14:00:58 +01:00
document.querySelector("#factor_bact").textContent = multiplication_factor_bact_scan.toFixed(2);
2025-02-05 14:09:42 +01:00
}
var bact_table = document.querySelector("#bact_scan_table");
function render_bact_scan_table(result){
let counts = [];
if (result[0][0].length == 0){
for (let i=0; i< result.length ; i + + ) {
let res = result[i][1].slice(0, -1).map(Number);;
counts.push(res);
}
} else {
for (let i=0; i< result.length ; i + + ) {
counts.push(update_bact_count(result[i][0]));
}
}
console.log(counts);
means = [];
sds = [];
for (let i=0; i< counts [ 0 ] . length ; i + + ) {
let sum = 0;
for (let j=0; j< counts.length ; j + + ) {
sum += counts[j][i];
}
means.push(sum/counts.length);
}
for (let i=0; i< counts [ 0 ] . length ; i + + ) {
let sd = 0;
for (let j=0; j< counts.length ; j + + ) {
sd += Math.pow(means[i] - counts[j][i],2);
}
sd = Math.sqrt(sd/counts.length);
sds.push(sd);
}
console.log(means);
console.log(sds);
keys = [
'Bacilli','','Cocci','','Pathogenic',''
]
for (let i=0; i< means.length ; i + = 2 ) {
render_bact_scan_table_row(keys[i], [means[i],means[i+1]], [sds[i],sds[i+1]]);
}
2025-02-06 14:00:58 +01:00
bact_mass = means[1] + means[3] + means[5];
2025-02-05 14:16:56 +01:00
fungi_mass = Number(result_table.children[1].children[0].children[1].innerHTML);
2025-02-05 18:13:56 +01:00
2025-02-06 14:00:58 +01:00
document.querySelector("#bacterial_biomass").textContent = bact_mass.toFixed(2)
document.querySelector("#fungal_biomass").textContent = fungi_mass.toFixed(2)
2025-02-05 14:16:56 +01:00
2025-02-06 14:00:58 +01:00
document.querySelector("#f_to_b_biomass").textContent = (fungi_mass / bact_mass).toFixed(5)
2025-02-05 14:09:42 +01:00
}
function render_bact_scan_table_row(key, mean, sd){
console.log(mean)
let newRow = bact_table.children[1].insertRow();
newRow.insertCell(0).innerHTML = key;
newRow.insertCell(1).innerHTML = mean[0] + " +/- " + sd[0];
newRow.insertCell(2).innerHTML = mean[1].toFixed(2) + " +/- " + sd[1].toFixed(2);
newRow.insertCell(3).innerHTML = (mean[0] * multiplication_factor_bact_scan).toFixed(2)
+ " +/- " + (100*(sd[0]/mean[0])).toFixed(2);
newRow.insertCell(4).innerHTML = (mean[1] * multiplication_factor_bact_scan*Math.pow(10,-6)).toExponential(2)
+ " +/- " + (100*(sd[1]/mean[1])).toFixed(2);
}
function update_bact_count(bacteria){
let bc = 0;
let cc = 0;
let pc = 0;
let abc = 0;
let acc = 0;
let apc = 0;
bacteria.forEach(function (item, index) {
switch(item[1]){
case "Bacteria":
bc += 1
abc += item[2];
break;
case "Cocci":
cc += 1
acc += item[2];
break;
case "Vibrio":
case "Spirilla":
case "Spirochetes":
pc += 1
apc += item[2];
break;
}
});
return [bc, abc, cc, acc, pc, apc];
}
2025-01-23 14:33:43 +01:00
< / script >
< / html >