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(); };