From 55219600881c032e11f4e16bd6fcc4b13d2da59c Mon Sep 17 00:00:00 2001 From: "Ryan@fsunuc" Date: Sun, 30 Jul 2023 15:14:19 -0400 Subject: [PATCH] change the html + javascript still do the job --- .gitmodules | 6 - .vscode/c_cpp_properties.json | 5 +- Makefile | 20 -- get_nuclear_data.py | 115 ++++++++ imgui | 1 - implot | 1 - index.html | 205 ++++++++++---- spsGUI.cpp | 161 ----------- spsSim.js | 497 ++++++++++++++++++++++++++++++++++ 9 files changed, 772 insertions(+), 239 deletions(-) delete mode 100644 .gitmodules delete mode 100644 Makefile create mode 100644 get_nuclear_data.py delete mode 160000 imgui delete mode 160000 implot delete mode 100644 spsGUI.cpp create mode 100644 spsSim.js diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index b77ef2b..0000000 --- a/.gitmodules +++ /dev/null @@ -1,6 +0,0 @@ -[submodule "imgui"] - path = imgui - url = https://github.com/ocornut/imgui.git -[submodule "implot"] - path = implot - url = https://github.com/epezent/implot.git diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 4039bef..c85cce5 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -3,7 +3,10 @@ { "name": "Linux", "includePath": [ - "${workspaceFolder}/**" + "${workspaceFolder}/**", + "/opt/root/**", + "${workspaceFolder}/imgui/**", + "${workspaceFolder}/implot/**" ], "defines": [], "compilerPath": "/usr/bin/gcc", diff --git a/Makefile b/Makefile deleted file mode 100644 index c1bb185..0000000 --- a/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -CXX = em++ -OUTPUT = spsGUI.js -IMGUI_DIR = imgui - -SOURCES = spsGUI.cpp -SOURCES += implot/implot.cpp implot/implot_items.cpp -SOURCES += $(IMGUI_DIR)/backends/imgui_impl_glfw.cpp $(IMGUI_DIR)/backends/imgui_impl_opengl3.cpp -SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_widgets.cpp $(IMGUI_DIR)/imgui_tables.cpp - -LIBS = -lGL -WEBGL_VER = -s USE_WEBGL2=1 -s USE_GLFW=3 -s FULL_ES3=1 -USE_WASM = -s WASM=1 - -all: $(SOURCES) $(OUTPUT) - -$(OUTPUT): $(SOURCES) - $(CXX) $(SOURCES) -std=c++11 -o $(OUTPUT) $(LIBS) $(WEBGL_VER) -O2 $(USE_WASM) -Iimplot -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends - -clean: - rm -f $(OUTPUT) diff --git a/get_nuclear_data.py b/get_nuclear_data.py new file mode 100644 index 0000000..af11695 --- /dev/null +++ b/get_nuclear_data.py @@ -0,0 +1,115 @@ +#!/usr/bin/env /usr/bin/python3 + +################################################ +import pandas as pd + +# the API webpage +# https://www-nds.iaea.org/relnsd/vcharthtml/api_v0_guide.html#examples + +# the service URL +livechart = "https://nds.iaea.org/relnsd/v0/data?" + +import urllib.request + +def lc_read_csv(url): + req = urllib.request.Request(url) + req.add_header('User-Agent', 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:77.0) Gecko/20100101 Firefox/77.0') + return pd.read_csv(urllib.request.urlopen(req)) + +mp = 938.27208816 #MeV/c^2 +mn = 939.56542052 + +#=================================================== +import cgi, cgitb + +form = cgi.FieldStorage() + +AZ = form.getvalue('isotopes_name') +maxEx = form.getvalue('maxEx') + +if maxEx == "can be omitted" : + maxEx = -1 + +if AZ == "p" : + AZ = "1H" + +if AZ == "d" : + AZ = "2H" + +if AZ == "t" : + AZ = "3H" + +if AZ == "a" : + AZ = "4He" + +query = livechart + "fields=ground_states&nuclides=" + AZ +temp = lc_read_csv(query) + +print( "Content-type:text/html\r\n\r\n") +print("") +print("") +print("") + +print("
========================= " + AZ ) +try : + Z = temp['z'][0] + N = temp['n'][0] + mass = Z*mp + N*mn - (Z+N)*temp['binding']/1000 + halfLife = temp['half_life_sec'][0] + + print("
A : %3d, Z : %3d, N : %3d" % (Z+N, Z, N)) + print("
Jpi : %3s" % (temp['jp'][0])) + #if halfLife != " " : + print("
half-live : %s sec" % (halfLife)) + print("
Mass : %.4f MeV" % (mass)) + print("
Binding : %.4f MeV/A" % (temp['binding']/1000)) + print("
Binding : %.4f MeV" % (temp['binding']/1000*(Z+N))) + + #print(" magnetic dipole : " + temp['magnetic_dipole'][0] + " mu.N") + #print("electric quadruple : " + temp['electric_quadrupole'][0] + " barn") + #if halfLife > 0 : + # print('------------ decay mode:') + # for i in range(1, 4) : + # print("%5s %s %%" % (temp["decay_%d" % i][0], temp["decay_%d_%%" % i][0])) + # print('--------------------------') +except : + print("
No such Isotopes.") + + +# import os, subprocess +# os.chdir(r"files") + +# result=subprocess.run(['../Cleopatra/IsotopeShort', AZ], stdout=subprocess.PIPE).stdout.decode('utf-8') +# p1 = result.find('Sn:') +# print("
" + result[p1:p1+16]) +# p1 = result.find('Sp') +# print("
" + result[p1:p1+16]) +# p1 = result.find('Sa') +# print("
" + result[p1:p1+16]) +print("
=============================") + +if float(maxEx) > 0 : + print("
") + query = livechart + "fields=levels&nuclides=" + AZ + tempEx = lc_read_csv(query); + ex = tempEx['energy'] + jp = tempEx['jp'] + l = ex.last_valid_index() + try : + print("") + for i in range(0, l+1): + if float(ex[i]) < float(maxEx)*1000: + print("" % (ex[i], jp[i].replace(' ', ','))) + else: + break + print("
%9.3f %s
") + except: + print("
cannot find Ex data") + + +print("") +print("") + + + + diff --git a/imgui b/imgui deleted file mode 160000 index 79d6f4e..0000000 --- a/imgui +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 79d6f4e211f245de24ab7c3a58f33261bd7931bf diff --git a/implot b/implot deleted file mode 160000 index cc5e1da..0000000 --- a/implot +++ /dev/null @@ -1 +0,0 @@ -Subproject commit cc5e1daa5c7f2335a9460ae79c829011dc5cef2d diff --git a/index.html b/index.html index fc0073e..2b3b6be 100644 --- a/index.html +++ b/index.html @@ -1,53 +1,160 @@ - - - - - - WebGui Demo - - - + + + +SPS Simulation + + + + + -
- -
+ - - - - \ No newline at end of file diff --git a/spsGUI.cpp b/spsGUI.cpp deleted file mode 100644 index 363532d..0000000 --- a/spsGUI.cpp +++ /dev/null @@ -1,161 +0,0 @@ -#include - -#ifdef __EMSCRIPTEN__ -#include -#endif - -#define GLFW_INCLUDE_ES3 -#include -#include - -#include "imgui.h" -#include "imgui_impl_opengl3.h" -#include "imgui_impl_glfw.h" - -#ifndef IMPLOT_DISABLE_OBSOLETE_FUNCTIONS -#define IMPLOT_DISABLE_OBSOLETE_FUNCTIONS -#endif -#include "implot.h" - -#include -#include -#include - -GLFWwindow* g_window; -ImVec4 clear_color = ImVec4(0xCE/255., 0xB8/255., 0x88/255., 1.00f); -int g_width; -int g_height; -// Function used by c++ to get the size of the html canvas -EM_JS(int, canvas_get_width, (), { - return Module.canvas.width; -}); - -// Function used by c++ to get the size of the html canvas -EM_JS(int, canvas_get_height, (), { - return Module.canvas.height; -}); - -// Function called by javascript -EM_JS(void, resizeCanvas, (), { - js_resizeCanvas(); -}); - -void on_size_changed(){ - glfwSetWindowSize(g_window, g_width, g_height); - - ImGui::SetCurrentContext(ImGui::GetCurrentContext()); -} - -void loop(){ - - int width = canvas_get_width(); - int height = canvas_get_height(); - - if (width != g_width || height != g_height){ - g_width = width; - g_height = height; - on_size_changed(); - } - - glfwPollEvents(); - - ImGui_ImplOpenGL3_NewFrame(); - ImGui_ImplGlfw_NewFrame(); - ImGui::NewFrame(); - - // Debug Window - { - ImGui::SetNextWindowSize(ImVec2(400, 100), ImGuiCond_FirstUseEver); - ImGui::SetNextWindowPos(ImVec2(1000, 100), ImGuiCond_FirstUseEver); - ImGui::Begin("Debug"); - ImGui::Text("Hello, world!"); // Display some text (you can use a format string too) - ImGui::ColorEdit3("bg color", (float*)&clear_color); // Edit 3 floats representing a color - - ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); - ImGui::End(); - } - - ImGui::Render(); - - int display_w, display_h; - glfwMakeContextCurrent(g_window); - glfwGetFramebufferSize(g_window, &display_w, &display_h); - glViewport(0, 0, display_w, display_h); - glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); - glClear(GL_COLOR_BUFFER_BIT); - - ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); - glfwMakeContextCurrent(g_window); -} - -//^ ######################################################### -int init_gl(){ - if( !glfwInit() ){ - fprintf( stderr, "Failed to initialize GLFW\n" ); - return 1; - } - - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // We don't want the old OpenGL - - // Open a window and create its OpenGL context - int canvasWidth = g_width; - int canvasHeight = g_height; - g_window = glfwCreateWindow(canvasWidth, canvasHeight, "Woods-Saxon Calculation Demo", NULL, NULL); - if( g_window == NULL ){ - fprintf( stderr, "Failed to open GLFW window.\n" ); - glfwTerminate(); - return -1; - } - glfwMakeContextCurrent(g_window); // Initialize GLEW - - return 0; -} - - -int init_imgui(){ - - // Setup Dear ImGui binding - IMGUI_CHECKVERSION(); - ImGui::CreateContext(); - ImGui_ImplGlfw_InitForOpenGL(g_window, true); - ImGui_ImplOpenGL3_Init(); - - ImPlot::CreateContext(); - - // Setup style - //ImGui::StyleColorsDark(); - ImGui::StyleColorsLight(); - - ImGuiIO& io = ImGui::GetIO(); - - resizeCanvas(); - - return 0; -} - - -int init(){ - init_gl(); - init_imgui(); - return 0; -} - -void quit(){ - glfwTerminate(); -} - -extern "C" int main(int argc, char** argv){ - - g_width = canvas_get_width(); - g_height = canvas_get_height(); - if (init() != 0) return 1; - - #ifdef __EMSCRIPTEN__ - emscripten_set_main_loop(loop, 0, 1); - #endif - - quit(); - - return 0; - -} \ No newline at end of file diff --git a/spsSim.js b/spsSim.js new file mode 100644 index 0000000..c2be38e --- /dev/null +++ b/spsSim.js @@ -0,0 +1,497 @@ +var beam = []; +var target = []; +var recoil = []; +var residual = []; +var ExB; //excitation energy of residual +var reactionName; + +var angle; +var BField; + +var parity; +function checkParity(){ + parity = 0; + if( document.getElementById('pos').checked == true ) parity += 1; + if( document.getElementById('neg').checked == true ) parity += 2; + if( document.getElementById('unk').checked == true ) parity += 4; + //console.log(parity); +} + +function addStates(){ + let AZ = residual[3]; + let maxEx = document.getElementById('maxEx').value; + + checkParity(); + let str = 'get_nuclear_data.py?isotopes_name=' + AZ + '&maxEx='+maxEx; + + let table = document.getElementById("ExTable"); + + const client = new XMLHttpRequest(); + + client.addEventListener('loadstart', + function(e){ + document.getElementById('waiting').innerHTML = "wait....retrieving data from IAEA.."; + } + ); + + + client.addEventListener('error', + function(e){ + document.getElementById('waiting').innerHTML = "Error."; + } + ); + + client.addEventListener('loadend', + function(e){ + let result = client.responseText.split(/\r?\n/); + + //clear table + let nRow = table.rows.length; + for( let j = nRow; j > 2; j--){ + table.deleteRow(j - 2); + } + + document.getElementById('waiting').innerHTML = ""; + let count = 0; + + for( let i = 0; i < result.length; i++){ + if( i < 17 ) continue; + if( result[i] == "" ) break; + + let kaka = result[i].split(' ').filter(n => n); + + let ex = parseFloat(kaka[3])/1000.; + let jpi = kaka[7]?.replace('(', '')?.replace(')', ''); + //console.log(ex + ", " + jpi); + + //check parity + if( (((parity >> 2) & 1) != 1) && kaka[7].slice(-1) == ")" ) continue; + if( (((parity >> 2) & 1) != 1) && jpi == "," ) continue; + if( (((parity) & 1) != 1) && jpi.slice(-1) == "+" ) continue; + if( (((parity >> 1) & 1) != 1) && jpi.slice(-1) == "-" ) continue; + + count ++; + nRow = table.rows.length; + let row = table.insertRow(nRow-1); + row.innerHTML = ' \ + \ + \ + '+ kaka[7] +''; + + } + if( count == 0 ){ + document.getElementById('waiting').innerHTML = "no states found."; + nRow = table.rows.length; + let row = table.insertRow(nRow-1); + row.innerHTML = ' \ + \ + '; + } + } + ); + + client.open('GET', str); + client.send(); + +} + +function addRow(ele) { + + let iRow = ele.closest('tr').sectionRowIndex; + + let table = document.getElementById("ExTable"); + let row = table.insertRow(iRow+1); + row.innerHTML = ' \ + \ + '; +} + +function deleteRow(ele){ + let table = document.getElementById("ExTable"); + let nRow = table.rows.length; + let iRow = ele.closest('tr').sectionRowIndex; + if ( nRow > 2){ + table.deleteRow(iRow); + } +} + +function GetMassData(Name, id){ + let str = 'https://fsunuc.physics.fsu.edu/SOLARIS/massProxy.py?AZ=' + Name; + + let client = new XMLHttpRequest(); + client.onreadystatechange = function() { + let mass = client.responseText.split(","); + if( id == 0 ){ //Beam + beam[0] = parseInt(mass[0]); // A + beam[1] = parseInt(mass[1]); // Z + beam[2] = parseFloat(mass[2]); // mass + beam[3] = Name; // Sym + } + if( id == 1 ){ // target + target[0] = parseInt(mass[0]); + target[1] = parseInt(mass[1]); + target[2] = parseFloat(mass[2]); + target[3] = Name; + target[4] = parseFloat(mass[4]); //Sp + target[5] = parseFloat(mass[5]); //Sn + target[6] = parseFloat(mass[6]); //Sa + } + if( id == 2 ){ // Recoil + recoil[0] = parseInt(mass[0]); + recoil[1] = parseInt(mass[1]); + recoil[2] = parseFloat(mass[2]); + recoil[3] = Name; + } + } + client.open('GET', str, false); + client.send(); +} + +function GetMassFromAZ(A,Z){ + let str = 'https://fsunuc.physics.fsu.edu/SOLARIS/massProxy.py?A=' + A + '&Z=' + Z; + + let client = new XMLHttpRequest(); + client.onreadystatechange = function() { + let mass = client.responseText.split(","); + residual[2] = parseFloat(mass[2]); + residual[3] = mass[3]?.trim(); + residual[4] = parseFloat(mass[4]); //Sp + residual[5] = parseFloat(mass[5]); //Sn + residual[6] = parseFloat(mass[6]); //Sa + } + client.open('GET', str, false); + client.send(); + +} + +function UpdateReaction(){ + residual[0] = beam[0] + target[0] - recoil[0]; + residual[1] = beam[1] + target[1] - recoil[1]; + GetMassFromAZ( residual[0], residual[1]); + + var Qvalue = beam[2] + target[2] - recoil[2] - residual[2]; + + document.getElementById('residual').innerHTML = residual[3]; + document.getElementById('residualSp').innerHTML = residual[4].toFixed(3); + document.getElementById('residualSn').innerHTML = residual[5].toFixed(3); + document.getElementById('residualSa').innerHTML = residual[6].toFixed(3); + document.getElementById('Q-value').innerHTML = Qvalue.toFixed(3); + + CalTransferConstant(); +} + +var Etot; // CM frame total energy +var k; //Lab frame momentum of beam +var beta, gamma; // Lorentz boost +var p; // CM frame exist channel momentum + +function CalTransferConstant(){ + let ma = beam[2]; + let mA = target[2]; + let KE = parseFloat(document.getElementById('KEA').value) * beam[0]; + k = Math.sqrt( Math.pow(ma + KE, 2 ) -ma * ma); + beta = k / (ma + KE + mA); + gamma = 1 / Math.sqrt(1 - beta * beta); + Etot = Math.sqrt(Math.pow(ma + KE + mA,2) - k * k); + + reactionName = target[3] + "(" + beam[3] + "," + recoil[3] + ")" + residual[3] + " @ " + KE/beam[0] + " MeV/u"; + + // console.log("Etot : " + Etot); + // console.log("k : " + k); + // console.log("beta : " + beta); + // console.log("gamma : " + gamma); + // console.log(reactionName); +} + +function CalCMMomentum(ExB){ + let mb = recoil[2]; + let mB = residual[2]; + ExB = parseFloat(ExB); + p = Math.sqrt( (Etot*Etot - Math.pow(mb + mB + ExB, 2)) * (Etot*Etot - Math.pow(mb - mB - ExB,2)) ) / 2 / Etot; + + // console.log("p : " + p); +} + +var ExList = []; +var EnergyLab = []; +var data = []; +function PlotKinematic(){ + + // plot recoil Lab energy vs Lab angle; + Plotly.purge("Plot_Kinematics"); + + ExList = Array.from(document.getElementsByName("Ex")); + // for( let i = 0; i < ExList.length; i++){ console.log(ExList[i].value);} + let mb = recoil[2]; + //console.log("Plot--------------"); + data = []; + for( let i = 0; i < ExList.length; i++){ + + let yList = []; // lab energy; + let xList = []; // lab angle in degree; + + let ExB = parseFloat(ExList[i].value).toFixed(3); + CalCMMomentum(ExB); + // console.log("ExB : " + ExB + ", p : " + p); + for( let thetaCM = 0; thetaCM <= 120; thetaCM ++){ + + let thetaRad = thetaCM * Math.PI/ 180.; + let EE = gamma * Math.sqrt(mb*mb + p*p) + gamma * beta * p * Math.cos(thetaRad); + let pz = gamma * beta * Math.sqrt(mb*mb + p*p) + gamma * p * Math.cos(thetaRad); + let pxy = p * Math.sin(thetaRad); + + let thetaLab = Math.atan2(pxy, pz) * 180. / Math.PI; + xList.push(thetaLab); + yList.push((EE-mb)); + } + + let newData = { + x : xList, + y : yList, + mode : "lines", + type: "scatter", + name : ("Ex=" + ExB) + } + + data.push(newData); + }; + + let layout = { + xaxis: {range: [0, 90], title: { text : "Angle Lab [degree]", standoff : 1}, mirror : "allticks", linewidth : "1"}, + yaxis: {range: [0, 20], title: "Kinematic Energy [MeV]" , mirror : "allticks", linewidth : "1"}, + title: reactionName, + dragmode : "pan", + margin: { l: 40, r: 40, b : 60, t : 40}, + legend: {yanchor:"bottom", xanchor:"left", x:"0.01",y:"0.01" } + }; + + Plotly.newPlot( "Plot_Kinematics", data, layout, {responsive: false}); + + ChangeSPSAnglePlotKinematics(); + +} + +function SearchForRecoilEnergy(){ + EnergyLab = []; + angle = parseFloat(document.getElementById("angle").value); + for( let i = 0; i < data.length; i++){ + let low = 0, high = 180; + let elow, ehigh; + + for(let j = 0; j < data[i].x.length; j++ ){ + + let thetaLab = data[i].x[j]; + let energy = data[i].y[j]; + + if( angle >= thetaLab && thetaLab > low) {low = thetaLab; elow = energy; } + if( high > thetaLab && thetaLab >= angle) {high = thetaLab; ehigh = energy;} + } + + EnergyLab.push((ehigh - elow )/ (high - low) * (angle - low) + elow); + // console.log("angle low : " + low + ", " + elow); + // console.log("angle low : " + high + ", " + ehigh); + // console.log("E : " + EnergyLab); + } +} + +function ChangeSPSAnglePlotKinematics(){ + angle = parseFloat(document.getElementById("angle").value); + let shapeArray = [ + { + type: 'rect', + xref: 'x', + yref: 'paper', + x0 : angle - 0.5, + x1 : angle + 0.5, + y0 : 0, + y1 : 1, + fillcolor : '#782F40', + opacity : 0.5, + line : { width : 0} + } + ]; + + var update = { + 'shapes' : shapeArray + } + Plotly.relayout("Plot_Kinematics", update); + + SearchForRecoilEnergy(); +} + +//################################### SPS functions +function recoilRho(KE){ + let mass = parseFloat(recoil[2]); + let charge = parseFloat(recoil[1]); + let momt = Math.sqrt( 2*mass*KE + KE*KE ); + let field = parseFloat(document.getElementById('BField').value); + return momt/ 299.792458 / charge / field * 100; // unit?? +} + +function PlotSPS(){ + Plotly.purge("Plot_SPS"); + + let spsData = []; + for(let i = 0; i < EnergyLab.length; i++){ + + let rho = recoilRho(EnergyLab[i]); + + let newData = { + x : [rho, rho], + y : [0, 1], + mode : "lines", + type: "scatter", + name : ("Ex=" + parseFloat(ExList[i].value).toFixed(3)) + } + + spsData.push(newData); + + //console.log(rho); + + } + + let layout = { + xaxis: {range: [65, 82], title: { text : "rho [cm]", standoff : 1}, mirror : "allticks", linewidth : "1"}, + yaxis: {range: [0, 1], title: "state" , mirror : "allticks", linewidth : "1"}, + title: reactionName, + dragmode : "pan", + margin: { l: 40, r: 40, b : 60, t : 40}, + legend: {yanchor:"top", xanchor:"left", x:"0.01",y:"0.99" } + }; + + Plotly.newPlot( "Plot_SPS", spsData, layout, {responsive: false}); + + +} + +function PlotAll(){ + PlotKinematic(); + PlotSPS(); +} + +//######################################## Add reaction +var reactionCount = 1; +function addReaction(){ + document.getElementById('msg').innerHTML = "not working yet"; + + var table = document.getElementById('ReactionTable'); + var rowCount = table.rows.length; + + if(reactionCount >= 3 ){ + document.getElementById('msg').innerHTML = "maximum # of reaction reached."; + return; + } + + + for (var i = 0; i < rowCount; i++) { + var row = table.rows[i]; + var cell = row.insertCell(-1); // -1 means insert at the end + if( i == 0 ) cell.innerHTML = ''; + if( i == 1 ) cell.innerHTML = ''; + if( i == 2 ) cell.innerHTML = ''; + if( i == 3 ) { + cell.innerHTML = '13C'; + cell.style.textAlign = 'center'; + } + if( i == 4 ) cell.innerHTML = '4.946'; + if( i == 5 ) cell.innerHTML = '17.533'; + if( i == 6 ) cell.innerHTML = '10.648'; + if( i == 7 ) cell.innerHTML = '2.722'; + + if( i >= 4) { + cell.style.textAlign = 'right'; + } + } + reactionCount ++; +} + +function removeRactiion(ele){ + document.getElementById('msg').innerHTML = "not working yet"; + +} + +//######################################### when load +GetMassData( document.getElementById('beam').value, 0); +GetMassData( document.getElementById('target').value, 1); +GetMassData( document.getElementById('recoil').value, 2); +UpdateReaction(); +PlotAll(); + +//########################################## UI control + +document.getElementById('beam').addEventListener('keypress', + function(e){ + if(e.keyCode == 13){ + GetMassData( document.getElementById('beam').value, 0); + UpdateReaction(); + PlotAll(); + } + }, false +); + +document.getElementById('target').addEventListener('keypress', + function(e){ + if(e.keyCode == 13){ + GetMassData( document.getElementById('target').value, 1); + UpdateReaction(); + PlotAll(); + } + }, false +); + +document.getElementById('recoil').addEventListener('keypress', + function(e){ + if(e.keyCode == 13){ + GetMassData( document.getElementById('recoil').value, 2); + UpdateReaction(); + PlotAll(); + } + }, false +); + +document.getElementById('KEA').addEventListener('keypress', + function(e){ + if(e.keyCode == 13){ + document.getElementById('KEARange').value = this.value; + CalTransferConstant(); + PlotAll(); + } + }, false +); +document.getElementById('KEARange').oninput = function(){ + document.getElementById('KEA').value = this.value; + CalTransferConstant(); + PlotAll(); +}; + +document.getElementById('angle').addEventListener('keypress', + function(e){ + if(e.keyCode == 13){ + document.getElementById('angleRange').value = this.value; + angle = this.value; + PlotSPS(); + } + }, false +); +document.getElementById('angleRange').oninput = function(){ + document.getElementById('angle').value = this.value; + angle = this.value; + ChangeSPSAnglePlotKinematics(); + PlotSPS(); +}; + +document.getElementById('BField').addEventListener('keypress', + function(e){ + if(e.keyCode == 13){ + document.getElementById('BRange').value = this.value; + BField - this.value; + ChangeSPSAnglePlotKinematics(); + PlotSPS(); + } + }, false +); +document.getElementById('BRange').oninput = function(){ + document.getElementById('BField').value = this.value; + BField - this.value; + PlotSPS(); +};