change the html + javascript still do the job
This commit is contained in:
parent
7f359212fb
commit
5521960088
6
.gitmodules
vendored
6
.gitmodules
vendored
|
@ -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
|
5
.vscode/c_cpp_properties.json
vendored
5
.vscode/c_cpp_properties.json
vendored
|
@ -3,7 +3,10 @@
|
|||
{
|
||||
"name": "Linux",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**"
|
||||
"${workspaceFolder}/**",
|
||||
"/opt/root/**",
|
||||
"${workspaceFolder}/imgui/**",
|
||||
"${workspaceFolder}/implot/**"
|
||||
],
|
||||
"defines": [],
|
||||
"compilerPath": "/usr/bin/gcc",
|
||||
|
|
20
Makefile
20
Makefile
|
@ -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)
|
115
get_nuclear_data.py
Normal file
115
get_nuclear_data.py
Normal file
|
@ -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("<html>")
|
||||
print("<style> body { font-family: courier, courier new, serif; color: #F7CF3C; } </style>")
|
||||
print("<body>")
|
||||
|
||||
print("<br>========================= " + 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("<br> A : %3d, Z : %3d, N : %3d" % (Z+N, Z, N))
|
||||
print("<br> Jpi : %3s" % (temp['jp'][0]))
|
||||
#if halfLife != " " :
|
||||
print("<br> half-live : %s sec" % (halfLife))
|
||||
print("<br> Mass : %.4f MeV" % (mass))
|
||||
print("<br> Binding : %.4f MeV/A" % (temp['binding']/1000))
|
||||
print("<br> 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("<br>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("<br>" + result[p1:p1+16])
|
||||
# p1 = result.find('Sp')
|
||||
# print("<br>" + result[p1:p1+16])
|
||||
# p1 = result.find('Sa')
|
||||
# print("<br>" + result[p1:p1+16])
|
||||
print("<br>=============================")
|
||||
|
||||
if float(maxEx) > 0 :
|
||||
print("<br>")
|
||||
query = livechart + "fields=levels&nuclides=" + AZ
|
||||
tempEx = lc_read_csv(query);
|
||||
ex = tempEx['energy']
|
||||
jp = tempEx['jp']
|
||||
l = ex.last_valid_index()
|
||||
try :
|
||||
print("<table>")
|
||||
for i in range(0, l+1):
|
||||
if float(ex[i]) < float(maxEx)*1000:
|
||||
print("<tr><td style=\"text-align:right\" width=80> %9.3f </td><td style=\"text-align:right\" width=100> %s </td></tr>" % (ex[i], jp[i].replace(' ', ',')))
|
||||
else:
|
||||
break
|
||||
print("</table>")
|
||||
except:
|
||||
print("<br> cannot find Ex data")
|
||||
|
||||
|
||||
print("</body>")
|
||||
print("</html>")
|
||||
|
||||
|
||||
|
||||
|
1
imgui
1
imgui
|
@ -1 +0,0 @@
|
|||
Subproject commit 79d6f4e211f245de24ab7c3a58f33261bd7931bf
|
1
implot
1
implot
|
@ -1 +0,0 @@
|
|||
Subproject commit cc5e1daa5c7f2335a9460ae79c829011dc5cef2d
|
205
index.html
205
index.html
|
@ -1,53 +1,160 @@
|
|||
<!doctype html>
|
||||
<html lang="en-us">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>WebGui Demo</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: arial;
|
||||
margin: 0;
|
||||
padding: none;
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>SPS Simulation</title>
|
||||
<meta name="description" content="SPS simulation">
|
||||
<!-- <link rel="icon" type="image/x-icon" href="logos/SOLARIS_favicon.png"> -->
|
||||
<script src="https://cdn.plot.ly/plotly-2.16.1.min.js"></script>
|
||||
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, user-scalable=no, user-scalable=0"/>
|
||||
</head>
|
||||
|
||||
<style>
|
||||
body{
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
background : #CEB888;
|
||||
}
|
||||
.emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; }
|
||||
div.emscripten { text-align: center; }
|
||||
div.emscripten_border { border: none; }
|
||||
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */
|
||||
canvas.emscripten { border: 0px none; background-color: black; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="emscripten_border">
|
||||
<canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()"></canvas>
|
||||
</div>
|
||||
|
||||
<script type='text/javascript'>
|
||||
var Module = {
|
||||
preRun: [],
|
||||
postRun: [],
|
||||
print: (function() {})(),
|
||||
printErr: function(text) {},
|
||||
canvas: (function() {
|
||||
var canvas = document.getElementById('canvas');
|
||||
// As a default initial behavior, pop up an alert when webgl context is lost. To make your
|
||||
// application robust, you may want to override this behavior before shipping!
|
||||
// See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
|
||||
canvas.addEventListener("webglcontextlost", function(e) { alert('WebGL context lost. You will need to reload the page.'); e.preventDefault(); }, false);
|
||||
return canvas;
|
||||
})(),
|
||||
setStatus: function(text) {},
|
||||
totalDependencies: 0,
|
||||
monitorRunDependencies: function(left) {}
|
||||
};
|
||||
window.addEventListener('resize', js_resizeCanvas, false);
|
||||
function js_resizeCanvas() {
|
||||
document.getElementById('canvas').width = window.innerWidth;
|
||||
document.getElementById('canvas').height = window.innerHeight;
|
||||
input[type="range"] {
|
||||
width: 400px;
|
||||
}
|
||||
input::-webkit-slider-runnable-track {
|
||||
-webkit-appearance: none;
|
||||
position: relative;
|
||||
background-color: #782F40;
|
||||
width: 100%;
|
||||
height: 20px;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
input::-webkit-slider-thumb {
|
||||
position: relative;
|
||||
-webkit-appearance: none;
|
||||
box-shadow: -340px 0 0 320px #782F40, inset 0 0 0 40px #782F40, 340px 0 0 320px #FFFFFF, inset 0 0 0 40px #782F40;
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
|
||||
<h1>Split-Pole Spectrograph Simulation</h1>
|
||||
|
||||
<b>For a given reaction and excited states,</b>
|
||||
<ul>
|
||||
<li> calculate the KE vs Lab angle, then </li>
|
||||
<li> find the KE for each state at SPS angle, then </li>
|
||||
<li> calculate the rho, then </li>
|
||||
<li> plot</li>
|
||||
<li>Could add energy loss in future.</li>
|
||||
</ul>
|
||||
|
||||
<table id="ReactionTable">
|
||||
<tr>
|
||||
<td style="text-align: right;"><b>Beam</b></td>
|
||||
<td><Input type="text" style="text-align: center; width:90px" value="d" id="beam" enterkeyhint="done"/></td>
|
||||
<tr>
|
||||
<td style="text-align: right;"><b>Target</b></td>
|
||||
<td><Input type="text" style="text-align: center; width:90px" value="12C" id="target" enterkeyhint="done"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: right;"><b>Recoil</b></td>
|
||||
<td><Input type="text" style="text-align: center; width:90px" value="p" id="recoil" enterkeyhint="done"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: right;"><b>Residual</b></td>
|
||||
<td id='residual' style="text-align: center;">13C</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: right;"><b>Sp</b></td>
|
||||
<td id="residualSp" style="text-align: right;"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: right;"><b>Sn</b></td>
|
||||
<td id="residualSn" style="text-align: right;"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: right;"><b>Sa</b></td>
|
||||
<td id="residualSa" style="text-align: right;"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: right;"><b>Q-value</b></td>
|
||||
<td id='Q-value' style="text-align: right;"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td><button type="button" onclick="addReaction(this)">Add Reaction</button></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td><button type="button" onclick="removeRactiion(this)">Rm. Reaction</button></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p id="msg" style="color: red;"> Will add more reactions later </p>
|
||||
|
||||
<p></p>
|
||||
<table>
|
||||
<tr>
|
||||
<td style="text-align:right"> <b>Energy :</b></td>
|
||||
<td><Input type="text" style="width:60px" value="8" id="KEA" enterkeyhint="done"/></td>
|
||||
<td>MeV/u</td>
|
||||
<td colspan="6"><Input type="range" min="0" max="20" step="0.05" value="8" id="KEARange"/> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align:right"> <b>SPS Angle :</b></td>
|
||||
<td><Input type="text" style="width:60px" value="20" id="angle" enterkeyhint="done"/></td>
|
||||
<td>degree</td>
|
||||
<td colspan="6"><Input type="range" min="0" max="90" step="1" value="20" id='angleRange'/> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align:right"> <b>SPS B-field :</b></td>
|
||||
<td><Input type="text" style="width:60px" value="0.9" id="BField" enterkeyhint="done"/></td>
|
||||
<td>T</td>
|
||||
<td colspan="6"><Input type="range" min="0" max="1" step="0.001" value="0.9" id='BRange'/> </td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p></p>
|
||||
|
||||
<br>
|
||||
<input type="checkbox" id="pos" onclick="checkParity()" checked/>Positive parity</td>
|
||||
<input type="checkbox" id="neg" onclick="checkParity()" checked/>Negative parity</td>
|
||||
<input type="checkbox" id="unk" onclick="checkParity()" checked/>Unknown parity</td>
|
||||
<br>
|
||||
<button type="button" onclick="addStates()">Add known states</button>
|
||||
Max Ex: <input type="text" id="maxEx" size="5" value="10"/>MeV
|
||||
|
||||
<p id='waiting'></p>
|
||||
|
||||
<table id="ExTable">
|
||||
<tr>
|
||||
<td><b> E<sub>x</sub> [MeV] </b></td>
|
||||
</tr>
|
||||
</tr>
|
||||
<td><input type="text" name="Ex" size="5" value="0"/></td>
|
||||
<td><button type="button" onclick="addRow(this)">Insert Ex</button></td>
|
||||
<td><button type="button" onclick="deleteRow(this)">Remove Ex</button></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p></p>
|
||||
|
||||
<button type="button" onclick="PlotAll(this)" style="width: 300px; height: 50px;"> Calculate SPS Kinematics </button>
|
||||
|
||||
<p></p>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div id="Plot_Kinematics" class="plotStyle" style="width: 400px; height: 400px;"></div>
|
||||
</td>
|
||||
<td>
|
||||
<div id="Plot_SPS" class="plotStyle" style="width: 800px; height: 400px;"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
<script src="spsSim.js"></script>
|
||||
|
||||
</script>
|
||||
<script async type="text/javascript" src="spsGUI.js"></script>
|
||||
</body>
|
||||
</html>
|
161
spsGUI.cpp
161
spsGUI.cpp
|
@ -1,161 +0,0 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#endif
|
||||
|
||||
#define GLFW_INCLUDE_ES3
|
||||
#include <GLES3/gl3.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#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 <iostream>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
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;
|
||||
|
||||
}
|
497
spsSim.js
Normal file
497
spsSim.js
Normal file
|
@ -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] == "</table>" ) 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 = '<td><input type="text" name="Ex" size="5" value="' + ex.toFixed(3) + '"/></td> \
|
||||
<td><button type="button" onclick="addRow(this)">Insert Ex</button></td> \
|
||||
<td><button type="button" onclick="deleteRow(this)">Remove Ex</button></td> \
|
||||
<td>'+ kaka[7] +'</td>';
|
||||
|
||||
}
|
||||
if( count == 0 ){
|
||||
document.getElementById('waiting').innerHTML = "no states found.";
|
||||
nRow = table.rows.length;
|
||||
let row = table.insertRow(nRow-1);
|
||||
row.innerHTML = '<td><input type="text" name="Ex" size="5" value="0"/></td> \
|
||||
<td><button type="button" onclick="addRow(this)">Insert Ex</button></td> \
|
||||
<td><button type="button" onclick="deleteRow(this)">Remove Ex</button></td>';
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
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 = '<td><input type="text" name="Ex" size="5" /></td> \
|
||||
<td><button type="button" onclick="addRow(this)">Insert Ex</button></td> \
|
||||
<td><button type="button" onclick="deleteRow(this)">Remove Ex</button></td>';
|
||||
}
|
||||
|
||||
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 = '<Input type="text" style="text-align: center; width:90px" value="d" id="beam1" enterkeyhint="done"/>';
|
||||
if( i == 1 ) cell.innerHTML = '<Input type="text" style="text-align: center; width:90px" value="12C" id="target1" enterkeyhint="done"/>';
|
||||
if( i == 2 ) cell.innerHTML = '<Input type="text" style="text-align: center; width:90px" value="p" id="recoil1" enterkeyhint="done"/>';
|
||||
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();
|
||||
};
|
Loading…
Reference in New Issue
Block a user