MediaWiki:GlycosphingolipidMassCalculator.js: Difference between revisions

mNo edit summary
No edit summary
 
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
addOnloadHook(GlycosphingolipidMassCalculator_init);  
/*
Last-Update: 2023/01/24
*/
class GlycosphingolipidMassCalculator
{
constructor()
{
// recalculate
document.getElementById("cs_average").onchange = function(){
gVar.gsMassCalc.calculateGlycosphingolipid();
}
// setLactoneMax
document.getElementById("cs_neuac").onchange = function(){
gVar.gsMassCalc.setLactoneMax();
}
document.getElementById("cs_neugc").onchange = function(){
gVar.gsMassCalc.setLactoneMax();
}
document.getElementById("cs_hexua").onchange = function(){
gVar.gsMassCalc.setLactoneMax();
}
document.getElementById("cs_lactone").onchange = function(){
gVar.gsMassCalc.setLactoneMax();
}
// setFattyAcidMax
document.getElementById("cs_fa_carbonno").onchange = function(){
gVar.gsMassCalc.setFattyAcidMax();
}
document.getElementById("cs_fa_unsaturation").onchange = function(){
gVar.gsMassCalc.setFattyAcidMax();
}
document.getElementById("cs_fa_hydroxygroup").onchange = function(){
gVar.gsMassCalc.setFattyAcidMax();
}
// setLongChainBases
document.getElementById("cs_lcb_carbonno").onchange = function(){
gVar.gsMassCalc.setLongChainBasesMax("cs_lcb_carbonno", document.getElementById("cs_lcb_carbonno").min);
}
document.getElementById("cs_lcb_hydroxygroup").onchange = function(){
gVar.gsMassCalc.setLongChainBasesMax("cs_lcb_hydroxygroup", document.getElementById("cs_lcb_hydroxygroup").min);
}
// Polarity
document.getElementById("cs_polarity").onchange = function(){
gVar.gsMassCalc.switchCharge();
}
document.getElementById("cs_charge").onchange = function(){
gVar.gsMassCalc.checkCharge();
}
// calculate button
document.getElementById("calculate_glycosphingolipid_button").onclick = function(){
gVar.gsMassCalc.calculateGlycosphingolipid();
}


function GlycosphingolipidMassCalculator_init()
// sample button
{
// Ganglioside GM1 of FA 18:0, LCB d20:1
// recalculate
document.getElementById("ex_ganglioside").onclick = function(){
document.getElementById("cs_average").onchange = function(){
gVar.gsMassCalc.setExampleNumbers({"cs_hexose":3,
calculateGlycosphingolipid();
"cs_hexnac":1,
"cs_neuac":1,
"cs_fa_carbonno":18,
"cs_lcb_carbonno":20,
"cs_lcb_unsaturation":1,
"cs_lcb_hydroxygroup":2});
gVar.gsMassCalc.calculateGlycosphingolipid();
}
// Sulfatide of FA 24:1, LCB d18:1
document.getElementById("ex_sulfatide").onclick = function(){
gVar.gsMassCalc.setExampleNumbers({"cs_hexose":1,
"cs_fa_carbonno":24,
"cs_fa_unsaturation":1,
"cs_lcb_carbonno":18,
"cs_lcb_unsaturation":1,
"cs_lcb_hydroxygroup":2,
"cs_sulfate":1});
gVar.gsMassCalc.calculateGlycosphingolipid();
}
// Lactotetraosylceramide of FA 16:0, LCB t18:0
document.getElementById("ex_lactotetraosylceramide").onclick = function(){
gVar.gsMassCalc.setExampleNumbers({"cs_hexose":3,
"cs_hexnac":1,
"cs_fa_carbonno":16,
"cs_fa_hydroxygroup":1,
"cs_lcb_carbonno":18,
"cs_lcb_hydroxygroup":3});
gVar.gsMassCalc.calculateGlycosphingolipid();
}
}
}
// setLactoneMax
 
document.getElementById("cs_neuac").onchange = function(){
setExampleNumbers(values)
setLactoneMax();
{
// clear
document.getElementById("cs_hexose"          ).value = 0;
document.getElementById("cs_fucose"          ).value = 0;
document.getElementById("cs_hexua"          ).value = 0;
document.getElementById("cs_hexnac"          ).value = 0;
document.getElementById("cs_neuac"           ).value = 0;
document.getElementById("cs_neugc"          ).value = 0;
document.getElementById("cs_methyl"          ).value = 0;
document.getElementById("cs_acetyl"          ).value = 0;
document.getElementById("cs_nmethylamide"    ).value = 0;
document.getElementById("cs_fa_carbonno"    ).value = 0;
document.getElementById("cs_fa_unsaturation" ).value = 0;
document.getElementById("cs_fa_hydroxygroup" ).value = 0;
document.getElementById("cs_lcb_carbonno"    ).value = 0;
document.getElementById("cs_lcb_unsaturation").value = 0;
document.getElementById("cs_lcb_hydroxygroup").value = 0;
document.getElementById("cs_phosphate"      ).value = 0;
document.getElementById("cs_nh4"            ).value = 0;
document.getElementById("cs_na"              ).value = 0;
document.getElementById("cs_k"              ).value = 0;
document.getElementById("cs_sulfate"        ).value = 0;
document.getElementById("cs_lactone"        ).value = 0;
 
document.getElementById("cs_polarity").selectedIndex = 0;
gVar.gsMassCalc.switchCharge();
 
// set values
for(var key in values){
document.getElementById(key).value = values[key];
}
}
}
document.getElementById("cs_neugc").onchange = function(){
 
setLactoneMax();
setLactoneMax()
{
var neuac = getGlycosphingolipidNum("cs_neuac", 0, 0);
var hexua = getGlycosphingolipidNum("cs_hexua", 0, 0);
var neugc = getGlycosphingolipidNum("cs_neugc", 0, 0);
var lactoneMax = neuac + hexua + neugc;
 
var lactone = document.getElementById("cs_lactone");
lactone.max = lactoneMax;
if(lactoneMax < lactone.value)
lactone.value = lactoneMax;
}
}
document.getElementById("cs_hexua").onchange = function(){
 
setLactoneMax();
setFattyAcidMax()
{
var saturationDOM = document.getElementById("cs_fa_unsaturation");
var hydroxyDOM    = document.getElementById("cs_fa_hydroxygroup");
var carbonno = getGlycosphingolipidNum("cs_fa_carbonno", 0, 0);
if(carbonno < 3){
saturationDOM.max = 0;
saturationDOM.value = '0';
} else {
saturationDOM.max = carbonno-2;
var saturation = getGlycosphingolipidNum("cs_fa_unsaturation", 0, 0);
if(carbonno-2 < saturation)
saturationDOM.value = carbonno-2;
}
if(carbonno < 2)
hydroxyDOM.value = '0';
else {
hydroxyDOM.max = carbonno-1;
var hydroxy = getGlycosphingolipidNum("cs_fa_hydroxygroup", 0, 0);
if(carbonno-1 < hydroxy)
hydroxyDOM.value = carbonno-1;
}
}
}
document.getElementById("cs_lactone").onchange = function(){
 
setLactoneMax();
setLongChainBasesMax(id, min)
{
gVar.gsMassCalc.getGlycosphingolipidNum(id, min, 0);
}
}
// setFattyAcidMax
 
document.getElementById("cs_fa_carbonno").onchange = function(){
switchCharge()
setFattyAcidMax();
{
var display = document.getElementById("cs_polarity").selectedIndex == 0 ? 'none' : 'block';
document.getElementById("div_charge").style.cssText = 'display: ' + display;
}
}
document.getElementById("cs_fa_unsaturation").onchange = function(){
 
setFattyAcidMax();
checkCharge()
{
var charge = Number(document.getElementById("cs_charge").value);
if(charge == 0)
charge = 1;
else if(charge < 0)
charge = -charge;
document.getElementById("cs_charge").value = charge;
}
}
document.getElementById("cs_fa_hydroxygroup").onchange = function(){
 
setFattyAcidMax();
getGlycosphingolipidNum(id, min, max)
{
var dom = document.getElementById(id);
var num = dom.value;
if(num == null || !isFinite(num)){
dom.value = 0;
return 0;
}
num = Number(num);
if(max != 0 && max < num){
dom.value = max;
return max;
}
if(num < min){
dom.value = min;
return min;
}
return num;
}
}
// setLongChainBases
 
document.getElementById("cs_lcb_carbonno").onchange = function(){
checkFormulaNums(atom, count)
setLongChainBasesMax("cs_lcb_carbonno", document.getElementById("cs_lcb_carbonno").min);
{
}
var str = "";
document.getElementById("cs_lcb_hydroxygroup").onchange = function(){
if(count > 0){
setLongChainBasesMax("cs_lcb_hydroxygroup", document.getElementById("cs_lcb_hydroxygroup").min);
str = atom;
}
if(count > 1)
// Polarity
str += count;
document.getElementById("cs_polarity").onchange = function(){
}
switchCharge();
return str;
}
document.getElementById("cs_charge").onchange = function(){
checkCharge();
}
}
// calculate button
document.getElementById("calculate_glycosphingolipid_button").onclick = function(){
calculateGlycosphingolipid();
}
}
function setLactoneMax()
{
var neuac = getGlycosphingolipidNum("cs_neuac", 0, 0);
var hexua = getGlycosphingolipidNum("cs_hexua", 0, 0);
var neugc = getGlycosphingolipidNum("cs_neugc", 0, 0);
var lactoneMax = neuac + hexua + neugc;


var lactone = document.getElementById("cs_lactone");
calculateGlycosphingolipid()
lactone.max = lactoneMax;
{
if(lactoneMax < lactone.value)
var hexose  = gVar.gsMassCalc.getGlycosphingolipidNum("cs_hexose",           0, 0);
lactone.value = lactoneMax;
var fucose  = gVar.gsMassCalc.getGlycosphingolipidNum("cs_fucose",           0, 0);
}
var hexua  = gVar.gsMassCalc.getGlycosphingolipidNum("cs_hexua",           0, 0);
function setFattyAcidMax()
var hexnac  = gVar.gsMassCalc.getGlycosphingolipidNum("cs_hexnac",           0, 0);
{
var neuac  = gVar.gsMassCalc.getGlycosphingolipidNum("cs_neuac",           0, 0);
var saturationDOM = document.getElementById("cs_fa_unsaturation");
var neugc  = gVar.gsMassCalc.getGlycosphingolipidNum("cs_neugc",           0, 0);
var hydroxyDOM    = document.getElementById("cs_fa_hydroxygroup");
var methyl  = gVar.gsMassCalc.getGlycosphingolipidNum("cs_methyl",         -99, 0);
var carbonno = getGlycosphingolipidNum("cs_fa_carbonno", 0, 0);
var acetyl  = gVar.gsMassCalc.getGlycosphingolipidNum("cs_acetyl",         -99, 0);
if(carbonno < 3){
var nma    = gVar.gsMassCalc.getGlycosphingolipidNum("cs_nmethylamide",     0, 0);
saturationDOM.max = 0;
var fac    = gVar.gsMassCalc.getGlycosphingolipidNum("cs_fa_carbonno",     0, 0);
saturationDOM.value = '0';
var faus    = gVar.gsMassCalc.getGlycosphingolipidNum("cs_fa_unsaturation", 0, fac-2 < 0 ? 0 : fac-2);
} else {
var faoh    = gVar.gsMassCalc.getGlycosphingolipidNum("cs_fa_hydroxygroup", 0, fac-1 < 0 ? 0 : fac-1);
saturationDOM.max = carbonno-2;
var lcbc    = gVar.gsMassCalc.getGlycosphingolipidNum("cs_lcb_carbonno",     5, 0);
var saturation = getGlycosphingolipidNum("cs_fa_unsaturation", 0, 0);
var lcbus  = gVar.gsMassCalc.getGlycosphingolipidNum("cs_lcb_unsaturation", 0, 0);
if(carbonno-2 < saturation)
var lcboh  = gVar.gsMassCalc.getGlycosphingolipidNum("cs_lcb_hydroxygroup", 2, 0);
saturationDOM.value = carbonno-2;
var hpo3    = gVar.gsMassCalc.getGlycosphingolipidNum("cs_phosphate",       0, 0);
}
var nh4    = gVar.gsMassCalc.getGlycosphingolipidNum("cs_nh4",             0, 0);
if(carbonno < 2)
var sod    = gVar.gsMassCalc.getGlycosphingolipidNum("cs_na",               0, 0);
hydroxyDOM.value = '0';
var pot    = gVar.gsMassCalc.getGlycosphingolipidNum("cs_k",               0, 0);
else {
var so3    = gVar.gsMassCalc.getGlycosphingolipidNum("cs_sulfate",         0, 0);
hydroxyDOM.max = carbonno-1;
var lactone = gVar.gsMassCalc.getGlycosphingolipidNum("cs_lactone",         0, neuac+neugc+hexua);
var hydroxy = getGlycosphingolipidNum("cs_fa_hydroxygroup", 0, 0);
var charge  = gVar.gsMassCalc.getGlycosphingolipidNum("cs_charge",           0, 0);
if(carbonno-1 < hydroxy)
hydroxyDOM.value = carbonno-1;
}
}
function setLongChainBasesMax(id, min)
{
getGlycosphingolipidNum(id, min, 0);
}
function switchCharge()
{
var display = document.getElementById("cs_polarity").selectedIndex == 0 ? 'none' : 'block';
document.getElementById("div_charge").style.cssText = 'display: ' + display;
}
function checkCharge()
{
var charge = Number(document.getElementById("cs_charge").value);
if(charge == 0)
charge = 1;
else if(charge < 0)
charge = -charge;
document.getElementById("cs_charge").value = charge;
}
function getGlycosphingolipidNum(id, min, max)
{
var dom = document.getElementById(id);
var num = dom.value;
if(num == null || !isFinite(num)){
dom.value = 0;
return 0;
}
if(max != 0 && max < num){
dom.value = max;
return max;
}
if(num < min){
dom.value = min;
return min;
}
return Number(num);
}
function checkFormulaNums(atom, count)
{
var str = "";
if(count > 0){
str = atom;
if(count > 1)
str += count;
}
return str;
}
function calculateGlycosphingolipid()
{
var hexose  = getGlycosphingolipidNum("cs_hexose", 0, 0);
var fucose  = getGlycosphingolipidNum("cs_fucose", 0, 0);
var hexua  = getGlycosphingolipidNum("cs_hexua", 0, 0);
var hexnac  = getGlycosphingolipidNum("cs_hexnac", 0, 0);
var neuac  = getGlycosphingolipidNum("cs_neuac", 0, 0);
var neugc  = getGlycosphingolipidNum("cs_neugc", 0, 0);
var methyl  = getGlycosphingolipidNum("cs_methyl", -99, 0);
var acetyl  = getGlycosphingolipidNum("cs_acetyl", -99, 0);
var nma    = getGlycosphingolipidNum("cs_nmethylamide", 0, 0);
var fac    = getGlycosphingolipidNum("cs_fa_carbonno", 0, 0);
var faus    = getGlycosphingolipidNum("cs_fa_unsaturation", 0, fac-2 < 0 ? 0 : fac-2);
var faoh    = getGlycosphingolipidNum("cs_fa_hydroxygroup", 0, fac-1 < 0 ? 0 : fac-1);
var lcbc    = getGlycosphingolipidNum("cs_lcb_carbonno", 5, 0);
var lcbus  = getGlycosphingolipidNum("cs_lcb_unsaturation", 0, 0);
var lcboh  = getGlycosphingolipidNum("cs_lcb_hydroxygroup", 2, 0);
var hpo3    = getGlycosphingolipidNum("cs_phosphate", 0, 0);
var nh4    = getGlycosphingolipidNum("cs_nh4", 0, 0);
var sod    = getGlycosphingolipidNum("cs_na", 0, 0);
var pot    = getGlycosphingolipidNum("cs_k", 0, 0);
var so3    = getGlycosphingolipidNum("cs_sulfate", 0, 0);
var lactone = getGlycosphingolipidNum("cs_lactone", 0, neuac+neugc+hexua);
var charge  = getGlycosphingolipidNum("cs_charge", 0, 0);


var pol    = document.getElementById("cs_polarity").value;
var pol    = document.getElementById("cs_polarity").value;
switch(pol){
switch(pol){
case 'NON': pol =  0; break;
case 'NON': pol =  0; break;
case 'NEG': pol = -1; break;
case 'NEG': pol = -1; break;
case 'POS': pol =  1; break;
case 'POS': pol =  1; break;
}
}


// struct formula
// struct formula
var formulaNums = [];
var formulaNums = [];
formulaNums[0] = (hexose + fucose + hexua)*6 + hexnac*8 + (neuac + neugc)*11 +
formulaNums[0] = (hexose + fucose + hexua)*6 + hexnac*8 + (neuac + neugc)*11 +
methyl + acetyl*2 + nma + fac + lcbc; // C
methyl + acetyl*2 + nma + fac + lcbc; // C
formulaNums[1] = 2 + (hexose + fucose)*10 + hexnac*13 + (neuac + neugc)*17 +
formulaNums[1] = 2 + (hexose + fucose)*10 + hexnac*13 + (neuac + neugc)*17 +
hexua*8 + hpo3 + (methyl + acetyl - lcbus)*2 +
hexua*8 + hpo3 + (methyl + acetyl - lcbus)*2 +
nma*3 + (lcbc*2+1) + nh4*3 - sod - pot + (pol * charge); // H
nma*3 + (lcbc*2+1) + nh4*3 - sod - pot + (pol * charge); // H
if(fac != 0)
if(fac != 0)
formulaNums[1] = formulaNums[1] + (fac-1)*2 - faus*2;
formulaNums[1] = formulaNums[1] + (fac-1)*2 - faus*2;
formulaNums[2] = 1 + (hexose + hexnac)*5 + fucose*4 + neuac*8 + neugc*9 +
formulaNums[2] = 1 + (hexose + hexnac)*5 + fucose*4 + neuac*8 + neugc*9 +
hexua*6 + (so3 + hpo3)*3 + acetyl - nma + (lcboh-1); // O
hexua*6 + (so3 + hpo3)*3 + acetyl - nma + (lcboh-1); // O
if(fac != 0)
if(fac != 0)
formulaNums[2] = formulaNums[2] + 1 + faoh;
formulaNums[2] = formulaNums[2] + 1 + faoh;
formulaNums[3] = 1 + hexnac + neuac + neugc + nh4 + nma; // N
formulaNums[3] = 1 + hexnac + neuac + neugc + nh4 + nma; // N
formulaNums[4] = so3;  // S
formulaNums[4] = so3;  // S
formulaNums[5] = hpo3; // P
formulaNums[5] = hpo3; // P
formulaNums[6] = sod;  // Na
formulaNums[6] = sod;  // Na
formulaNums[7] = pot;  // K
formulaNums[7] = pot;  // K
// formulaNums[8] = cal;  // Ca
// formulaNums[8] = cal;  // Ca
formulaNums[1] = formulaNums[1] - lactone*2;
formulaNums[1] = formulaNums[1] - lactone*2;
formulaNums[2] = formulaNums[2] - lactone;
formulaNums[2] = formulaNums[2] - lactone;


var formula = 'C' + formulaNums[0];
var formula = 'C' + formulaNums[0];
formula += 'H' + formulaNums[1];
formula += 'H' + formulaNums[1];
formula += 'N';
formula += 'N';
if(formulaNums[3] > 1)
if(formulaNums[3] > 1)
formula += formulaNums[3];
formula += formulaNums[3];
formula += checkFormulaNums('O',  formulaNums[2]);
formula += gVar.gsMassCalc.checkFormulaNums('O',  formulaNums[2]);
formula += checkFormulaNums('P',  formulaNums[5]);
formula += gVar.gsMassCalc.checkFormulaNums('P',  formulaNums[5]);
formula += checkFormulaNums('S',  formulaNums[4]);
formula += gVar.gsMassCalc.checkFormulaNums('S',  formulaNums[4]);
// formula += checkFormulaNums('Ca', formulaNums[8]);
// formula += gVar.gsMassCalc.checkFormulaNums('Ca', formulaNums[8]);
formula += checkFormulaNums('K',  formulaNums[7]);
formula += gVar.gsMassCalc.checkFormulaNums('K',  formulaNums[7]);
formula += checkFormulaNums('Na', formulaNums[6]);
formula += gVar.gsMassCalc.checkFormulaNums('Na', formulaNums[6]);


document.getElementById("cs_formula").value = formula;
document.getElementById("cs_formula").value = formula;




var EXACT = {
var EXACT = {
"C":  12.0,
"C":  12.0,
"H":  1.0078250322,
"H":  1.0078250322,
"Li":  7.01600344,
"Li":  7.01600344,
"O":  15.994914620,
"O":  15.994914620,
"N":  14.003074004,
"N":  14.003074004,
"S":  31.972071174,
"S":  31.972071174,
"P":  30.973761998,
"P":  30.973761998,
"Na": 22.98976928,
"Na": 22.98976928,
"K":  38.96370649,
"K":  38.96370649,
"Ca": 39.9625909
"Ca": 39.9625909
}
}
var electron = 0.00054857990;
var electron = 0.00054857990;
// 質量計算
// 質量計算
// var mass = calculateMassFromFormula(formula, document.getElementById("cs_average").value === 'true');
// var mass = calculateMassFromFormula(formula, document.getElementById("cs_average").value === 'true');
var mass = formulaNums[0] * EXACT["C"]  + formulaNums[1] * EXACT["H"] + formulaNums[2] * EXACT["O"] +
var mass = formulaNums[0] * EXACT["C"]  + formulaNums[1] * EXACT["H"] + formulaNums[2] * EXACT["O"] +
          formulaNums[3] * EXACT["N"]  + formulaNums[4] * EXACT["S"] + formulaNums[5] * EXACT["P"] +
          formulaNums[3] * EXACT["N"]  + formulaNums[4] * EXACT["S"] + formulaNums[5] * EXACT["P"] +
          formulaNums[6] * EXACT["Na"] + formulaNums[7] * EXACT["K"];
          formulaNums[6] * EXACT["Na"] + formulaNums[7] * EXACT["K"];
var nominal = formulaNums[0]*12 +formulaNums[1] +formulaNums[2]*16
var nominal = formulaNums[0]*12 +formulaNums[1] +formulaNums[2]*16
+formulaNums[3]*14 +formulaNums[4]*32 +formulaNums[5]*31
+formulaNums[3]*14 +formulaNums[4]*32 +formulaNums[5]*31
+formulaNums[6]*23 +formulaNums[7]*39;
+formulaNums[6]*23 +formulaNums[7]*39;


if(charge != 0 && pol != 0){
if(charge != 0 && pol != 0){
if(pol > 0)
if(pol > 0)
mass = mass / charge - electron;
mass = mass / charge - electron;
else if(pol < 0)
else if(pol < 0)
mass = mass / charge + electron;
mass = mass / charge + electron;
nominal /= charge;
nominal /= charge;
}
if(Math.floor(nominal) == nominal)
nominal = nominal.toFixed(0);
else
nominal = nominal.toFixed(2);
document.getElementById("cs_mass").value = mass.toFixed(6);
document.getElementById("cs_nominalmass").value = nominal;
}
}
if(Math.floor(nominal) == nominal)
nominal = nominal.toFixed(0);
else
nominal = nominal.toFixed(2);
document.getElementById("cs_mass").value = mass.toFixed(6);
document.getElementById("cs_nominalmass").value = nominal;
}
}

Latest revision as of 04:19, 25 January 2023

/*
Last-Update: 2023/01/24
*/
class GlycosphingolipidMassCalculator
{
	constructor()
	{
		// recalculate
		document.getElementById("cs_average").onchange = function(){
			gVar.gsMassCalc.calculateGlycosphingolipid();
		}
		// setLactoneMax
		document.getElementById("cs_neuac").onchange = function(){
			gVar.gsMassCalc.setLactoneMax();
		}
		document.getElementById("cs_neugc").onchange = function(){
			gVar.gsMassCalc.setLactoneMax();
		}
		document.getElementById("cs_hexua").onchange = function(){
			gVar.gsMassCalc.setLactoneMax();
		}
		document.getElementById("cs_lactone").onchange = function(){
			gVar.gsMassCalc.setLactoneMax();
		}
		// setFattyAcidMax
		document.getElementById("cs_fa_carbonno").onchange = function(){
			gVar.gsMassCalc.setFattyAcidMax();
		}
		document.getElementById("cs_fa_unsaturation").onchange = function(){
			gVar.gsMassCalc.setFattyAcidMax();
		}
		document.getElementById("cs_fa_hydroxygroup").onchange = function(){
			gVar.gsMassCalc.setFattyAcidMax();
		}
		// setLongChainBases
		document.getElementById("cs_lcb_carbonno").onchange = function(){
			gVar.gsMassCalc.setLongChainBasesMax("cs_lcb_carbonno", document.getElementById("cs_lcb_carbonno").min);
		}
		document.getElementById("cs_lcb_hydroxygroup").onchange = function(){
			gVar.gsMassCalc.setLongChainBasesMax("cs_lcb_hydroxygroup", document.getElementById("cs_lcb_hydroxygroup").min);
		}
		// Polarity
		document.getElementById("cs_polarity").onchange = function(){
			gVar.gsMassCalc.switchCharge();
		}
		document.getElementById("cs_charge").onchange = function(){
			gVar.gsMassCalc.checkCharge();
		}
		// calculate button
		document.getElementById("calculate_glycosphingolipid_button").onclick = function(){
			gVar.gsMassCalc.calculateGlycosphingolipid();
		}

		// sample button
			// Ganglioside GM1 of FA 18:0, LCB d20:1 
		document.getElementById("ex_ganglioside").onclick = function(){
			gVar.gsMassCalc.setExampleNumbers({"cs_hexose":3,
					"cs_hexnac":1,
					"cs_neuac":1,
					"cs_fa_carbonno":18,
					"cs_lcb_carbonno":20,
					"cs_lcb_unsaturation":1,
					"cs_lcb_hydroxygroup":2});
			gVar.gsMassCalc.calculateGlycosphingolipid();
		}
			// Sulfatide of FA 24:1, LCB d18:1
		document.getElementById("ex_sulfatide").onclick = function(){
			gVar.gsMassCalc.setExampleNumbers({"cs_hexose":1,
					"cs_fa_carbonno":24,
					"cs_fa_unsaturation":1,
					"cs_lcb_carbonno":18,
					"cs_lcb_unsaturation":1,
					"cs_lcb_hydroxygroup":2,
					"cs_sulfate":1});
			gVar.gsMassCalc.calculateGlycosphingolipid();
		}
			// Lactotetraosylceramide of FA 16:0, LCB t18:0 
		document.getElementById("ex_lactotetraosylceramide").onclick = function(){
			gVar.gsMassCalc.setExampleNumbers({"cs_hexose":3,
					"cs_hexnac":1,
					"cs_fa_carbonno":16,
					"cs_fa_hydroxygroup":1,
					"cs_lcb_carbonno":18,
					"cs_lcb_hydroxygroup":3});
			gVar.gsMassCalc.calculateGlycosphingolipid();
		}
	}

	setExampleNumbers(values)
	{
		// clear
		document.getElementById("cs_hexose"          ).value = 0;
		document.getElementById("cs_fucose"          ).value = 0;
		document.getElementById("cs_hexua"           ).value = 0;
		document.getElementById("cs_hexnac"          ).value = 0;
		document.getElementById("cs_neuac"           ).value = 0;
		document.getElementById("cs_neugc"           ).value = 0;
		document.getElementById("cs_methyl"          ).value = 0;
		document.getElementById("cs_acetyl"          ).value = 0;
		document.getElementById("cs_nmethylamide"    ).value = 0;
		document.getElementById("cs_fa_carbonno"     ).value = 0;
		document.getElementById("cs_fa_unsaturation" ).value = 0;
		document.getElementById("cs_fa_hydroxygroup" ).value = 0;
		document.getElementById("cs_lcb_carbonno"    ).value = 0;
		document.getElementById("cs_lcb_unsaturation").value = 0;
		document.getElementById("cs_lcb_hydroxygroup").value = 0;
		document.getElementById("cs_phosphate"       ).value = 0;
		document.getElementById("cs_nh4"             ).value = 0;
		document.getElementById("cs_na"              ).value = 0;
		document.getElementById("cs_k"               ).value = 0;
		document.getElementById("cs_sulfate"         ).value = 0;
		document.getElementById("cs_lactone"         ).value = 0;

		document.getElementById("cs_polarity").selectedIndex = 0;
		gVar.gsMassCalc.switchCharge();

		// set values
		for(var key in values){
			document.getElementById(key).value = values[key];
		}
	}

	setLactoneMax()
	{
		var neuac = getGlycosphingolipidNum("cs_neuac", 0, 0);
		var hexua = getGlycosphingolipidNum("cs_hexua", 0, 0);
		var neugc = getGlycosphingolipidNum("cs_neugc", 0, 0);
		var lactoneMax = neuac + hexua + neugc;

		var lactone = document.getElementById("cs_lactone");
		lactone.max = lactoneMax;
		if(lactoneMax < lactone.value)
			lactone.value = lactoneMax;
	}

	setFattyAcidMax()
	{
		var saturationDOM = document.getElementById("cs_fa_unsaturation");
		var hydroxyDOM    = document.getElementById("cs_fa_hydroxygroup");
		var carbonno = getGlycosphingolipidNum("cs_fa_carbonno", 0, 0);
		if(carbonno < 3){
			saturationDOM.max = 0;
			saturationDOM.value = '0';
		} else {
			saturationDOM.max = carbonno-2;
			var saturation = getGlycosphingolipidNum("cs_fa_unsaturation", 0, 0);
			if(carbonno-2 < saturation)
				saturationDOM.value = carbonno-2;
		}
		if(carbonno < 2)
			hydroxyDOM.value = '0';
		else {
			hydroxyDOM.max = carbonno-1;
			var hydroxy = getGlycosphingolipidNum("cs_fa_hydroxygroup", 0, 0);
			if(carbonno-1 < hydroxy)
				hydroxyDOM.value = carbonno-1;
		}
	}

	setLongChainBasesMax(id, min)
	{
		gVar.gsMassCalc.getGlycosphingolipidNum(id, min, 0);
	}

	switchCharge()
	{
		var display = document.getElementById("cs_polarity").selectedIndex == 0 ? 'none' : 'block';
		document.getElementById("div_charge").style.cssText = 'display: ' + display;
	}

	checkCharge()
	{
		var charge = Number(document.getElementById("cs_charge").value);
		if(charge == 0)
			charge = 1;
		else if(charge < 0)
			charge = -charge;
		document.getElementById("cs_charge").value = charge;
	}

	getGlycosphingolipidNum(id, min, max)
	{
		var dom = document.getElementById(id);
		var num = dom.value;
		if(num == null || !isFinite(num)){
			dom.value = 0;
			return 0;
		}
		num = Number(num);
		if(max != 0 && max < num){
			dom.value = max;
			return max;
		}
		if(num < min){
			dom.value = min;
			return min;
		}
		return num;
	}

	checkFormulaNums(atom, count)
	{
		var str = "";
		if(count > 0){
			str = atom;
			if(count > 1)
				str += count;
		}
		return str;
	}

	calculateGlycosphingolipid()
	{
		var hexose  = gVar.gsMassCalc.getGlycosphingolipidNum("cs_hexose",           0, 0);
		var fucose  = gVar.gsMassCalc.getGlycosphingolipidNum("cs_fucose",           0, 0);
		var hexua   = gVar.gsMassCalc.getGlycosphingolipidNum("cs_hexua",            0, 0);
		var hexnac  = gVar.gsMassCalc.getGlycosphingolipidNum("cs_hexnac",           0, 0);
		var neuac   = gVar.gsMassCalc.getGlycosphingolipidNum("cs_neuac",            0, 0);
		var neugc   = gVar.gsMassCalc.getGlycosphingolipidNum("cs_neugc",            0, 0);
		var methyl  = gVar.gsMassCalc.getGlycosphingolipidNum("cs_methyl",         -99, 0);
		var acetyl  = gVar.gsMassCalc.getGlycosphingolipidNum("cs_acetyl",         -99, 0);
		var nma     = gVar.gsMassCalc.getGlycosphingolipidNum("cs_nmethylamide",     0, 0);
		var fac     = gVar.gsMassCalc.getGlycosphingolipidNum("cs_fa_carbonno",      0, 0);
		var faus    = gVar.gsMassCalc.getGlycosphingolipidNum("cs_fa_unsaturation",  0, fac-2 < 0 ? 0 : fac-2);
		var faoh    = gVar.gsMassCalc.getGlycosphingolipidNum("cs_fa_hydroxygroup",  0, fac-1 < 0 ? 0 : fac-1);
		var lcbc    = gVar.gsMassCalc.getGlycosphingolipidNum("cs_lcb_carbonno",     5, 0);
		var lcbus   = gVar.gsMassCalc.getGlycosphingolipidNum("cs_lcb_unsaturation", 0, 0);
		var lcboh   = gVar.gsMassCalc.getGlycosphingolipidNum("cs_lcb_hydroxygroup", 2, 0);
		var hpo3    = gVar.gsMassCalc.getGlycosphingolipidNum("cs_phosphate",        0, 0);
		var nh4     = gVar.gsMassCalc.getGlycosphingolipidNum("cs_nh4",              0, 0);
		var sod     = gVar.gsMassCalc.getGlycosphingolipidNum("cs_na",               0, 0);
		var pot     = gVar.gsMassCalc.getGlycosphingolipidNum("cs_k",                0, 0);
		var so3     = gVar.gsMassCalc.getGlycosphingolipidNum("cs_sulfate",          0, 0);
		var lactone = gVar.gsMassCalc.getGlycosphingolipidNum("cs_lactone",          0, neuac+neugc+hexua);
		var charge  = gVar.gsMassCalc.getGlycosphingolipidNum("cs_charge",           0, 0);

		var pol     = document.getElementById("cs_polarity").value;
		switch(pol){
			case 'NON': pol =  0; break;
			case 'NEG': pol = -1; break;
			case 'POS': pol =  1; break;
		}

		// struct formula
		var formulaNums = [];
		formulaNums[0] = (hexose + fucose + hexua)*6 + hexnac*8 + (neuac + neugc)*11 +
					methyl + acetyl*2 + nma + fac + lcbc; // C
		formulaNums[1] = 2 + (hexose + fucose)*10 + hexnac*13 + (neuac + neugc)*17 +
					hexua*8 + hpo3 + (methyl + acetyl - lcbus)*2 +
					nma*3 + (lcbc*2+1) + nh4*3 - sod - pot + (pol * charge); // H
		if(fac != 0)
			formulaNums[1] = formulaNums[1] + (fac-1)*2 - faus*2;
		formulaNums[2] = 1 + (hexose + hexnac)*5 + fucose*4 + neuac*8 + neugc*9 +
					hexua*6 + (so3 + hpo3)*3 + acetyl - nma + (lcboh-1); // O
		if(fac != 0)
			formulaNums[2] = formulaNums[2] + 1 + faoh;
		formulaNums[3] = 1 + hexnac + neuac + neugc + nh4 + nma; // N
		formulaNums[4] = so3;  // S
		formulaNums[5] = hpo3; // P
		formulaNums[6] = sod;  // Na
		formulaNums[7] = pot;  // K
	//	formulaNums[8] = cal;  // Ca
		formulaNums[1] = formulaNums[1] - lactone*2;
		formulaNums[2] = formulaNums[2] - lactone;

		var formula = 'C' + formulaNums[0];
		formula += 'H' + formulaNums[1];
		formula += 'N';
		if(formulaNums[3] > 1)
			formula += formulaNums[3];
		formula += gVar.gsMassCalc.checkFormulaNums('O',  formulaNums[2]);
		formula += gVar.gsMassCalc.checkFormulaNums('P',  formulaNums[5]);
		formula += gVar.gsMassCalc.checkFormulaNums('S',  formulaNums[4]);
	//	formula += gVar.gsMassCalc.checkFormulaNums('Ca', formulaNums[8]);
		formula += gVar.gsMassCalc.checkFormulaNums('K',  formulaNums[7]);
		formula += gVar.gsMassCalc.checkFormulaNums('Na', formulaNums[6]);

		document.getElementById("cs_formula").value = formula;


		var EXACT = {
			"C":  12.0,
			"H":   1.0078250322,
			"Li":  7.01600344,
			"O":  15.994914620,
			"N":  14.003074004,
			"S":  31.972071174,
			"P":  30.973761998,
			"Na": 22.98976928,
			"K":  38.96370649,
			"Ca": 39.9625909
		}
		var electron = 0.00054857990;
		// 質量計算
	//	var mass = calculateMassFromFormula(formula, document.getElementById("cs_average").value === 'true');
		var mass = formulaNums[0] * EXACT["C"]  + formulaNums[1] * EXACT["H"] + formulaNums[2] * EXACT["O"] +
		           formulaNums[3] * EXACT["N"]  + formulaNums[4] * EXACT["S"] + formulaNums[5] * EXACT["P"] +
		           formulaNums[6] * EXACT["Na"] + formulaNums[7] * EXACT["K"];
		var nominal = formulaNums[0]*12 +formulaNums[1] +formulaNums[2]*16
			+formulaNums[3]*14 +formulaNums[4]*32 +formulaNums[5]*31
			+formulaNums[6]*23 +formulaNums[7]*39;

		if(charge != 0 && pol != 0){
			if(pol > 0)
				mass = mass / charge - electron;
			else if(pol < 0)
				mass = mass / charge + electron;
			nominal /= charge;
		}
		if(Math.floor(nominal) == nominal)
			nominal = nominal.toFixed(0);
		else
			nominal = nominal.toFixed(2);
		document.getElementById("cs_mass").value = mass.toFixed(6);
		document.getElementById("cs_nominalmass").value = nominal;
	}
}