Mercurial > repos > pieterlukasse > nist_wrapper
diff templates/spectrum_gen.js @ 0:cce6989ed423
new NIST wrapper demo tools
author | pieter.lukasse@wur.nl |
---|---|
date | Thu, 22 Jan 2015 16:14:57 +0100 |
parents | |
children | 82368bd06e1d |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/spectrum_gen.js Thu Jan 22 16:14:57 2015 +0100 @@ -0,0 +1,277 @@ +function getMax(values) +{ + var result = 0; + for (var i = 0; i < values.length; i++) + { + if (values[i] > result) + result = values[i]; + } + return result; +} + +/** + * This function will first convert the spectrum mass and intensities list in MSP format + * to the internal lists needed by renderSpectrum function. + * + * @param spectrumMSPString : list of masses and intensities in the following format: + * e.g. : "14 8; 15 15; 27 18; 28 15; 29 15; 30 11; 32 19; 39 32; 40 12; 41 68;" + */ +function renderSpectrumFromMSPString(spectrumMSPString, targetElement) +{ + var spectrum1 = getSpectrumObjectFromMSPString(spectrumMSPString); + renderSpectrum(spectrum1, null,targetElement); +} + +function endsWith(str, suffix) { + return str.indexOf(suffix, str.length - suffix.length) !== -1; +} + +function getSpectrumObjectFromCouplesString(spectrumCouplesString, couplesSeparator, massAndIntensitySeparator) +{ + var couples = spectrumCouplesString.split(couplesSeparator); + var masses = new Array(); + var intensities = new Array(); + for (var i = 0; i < couples.length; i++) + { + var couple = couples[i].trim().split(massAndIntensitySeparator) + var mass = parseInt(couple[0]) + var intensity = parseInt(couple[1]) + masses.push(mass); + intensities.push(intensity); + } + var spectrum1 = new Object(); + spectrum1.masses = masses; + spectrum1.intensities = intensities; + return spectrum1; +} + +function getSpectrumObjectFromMSPString(spectrumMSPString) +{ + spectrumMSPString = spectrumMSPString.trim(); + if (endsWith(spectrumMSPString, ";")) + spectrumMSPString = spectrumMSPString.substring(0, spectrumMSPString.length - 1); + return getSpectrumObjectFromCouplesString(spectrumMSPString, ';', ' '); +} + + +function getSpectrumObjectFromJCAMPString(spectrumJCAMPString) +{ + var spectrum = getSpectrumObjectFromCouplesString(spectrumJCAMPString, ' ', ','); + for (var i = 0; i < spectrum.intensities.length; i++) + spectrum.intensities[i] = spectrum.intensities[i]/10; + return spectrum; +} + +/** + * This function will render a comparison spectrum comparable to + * the NIST "head to tail" visualization to compare the measured spectrum + * with the matched library spectrum. + * + * NB: One important detail in this function + * is that the library spectrum is not available in NIST output, so + * its representative is retrieved from NIST's webbook website in this case. + * (e.g. http://webbook.nist.gov/cgi/cbook.cgi?JCAMP=C537268&Index=0&Type=Mass + * for casNr = "C537268" ) + * + * + * @param spectrumMSPString + * @param casNr + * @param targetElement + */ +function renderComparisonSpectrum(spectrumMSPString, casNr, targetElement) +{ + var peakTable; + try + { + //remove dashes: + casNr = casNr.replace("-", ""); + peakTable = httpGet2("/nist_controller/get_nistdata?casnr="+casNr); + + } + catch(e) + { + //assume running locally: + alert("Error while trying to get data from NIST. Rendering library spectrum with dummy data."); + peakTable = "55,290 56,240 57,100 58,80"+ + " 63,30 65,150 66,50 67,1271"+ + " 68,370 69,100 70,210 71,10"+ + " 74,50 75,60 76,120 77,2312"+ + " 78,220 79,120 80,190 81,630"+ + " 82,4884 83,2702 84,240 85,20"+ + " 91,180 92,50 93,210 94,3353"+ + " 95,1371 96,1261 97,370 98,120"+ + " 105,1621 106,160 107,70 108,220"+ + " 109,80 110,60 111,30 112,40"+ + " 121,30 122,460 123,940 124,9999"; + //note that the intensities in jcamp response are 10x when compared to MSP format + } + var spectrum1 = getSpectrumObjectFromMSPString(spectrumMSPString); + var spectrum2 = getSpectrumObjectFromJCAMPString(peakTable); + renderSpectrum(spectrum1, spectrum2,targetElement); +} + +function httpGet2(theUrl) +{ + //Tried many options: the solution was to add a new service to our + //Galaxy server to act as a proxy to the NIST site and then retrieve the data. + + //way of working: added a new controller to + // /home/lukas007/galaxy-dist/lib/galaxy/webapps/galaxy/controllers + // which gives the service "/nist_controller/get_nistdata?casnr=<casnr>" + + var xmlHttp = null; + + xmlHttp = new XMLHttpRequest(); + xmlHttp.open( "GET", theUrl, false ); + xmlHttp.send( null ); + return xmlHttp.responseText; +} + + + +/** + * This function will ensure only the local highest peaks get a label + * to make the spectrum more readable and avoid all the overlapping labels + * of minor peaks. + * + * @param spectrum + */ +function getSpectrumLabels(spectrum) +{ + //TODO - improve logic to include more labels when area of peaks is sparse enough. + //for now we let all labels, keep only the ones where intensity > 100: + //and leave the largest/last mass as well: + var result = new Array(); + for (var i = 0; i < spectrum.masses.length; i++) + { + if (spectrum.intensities[i] > 100 || i == spectrum.masses.length-1) + result.push(spectrum.masses[i]); + else + result.push(""); + } + return result; +} + +function renderSpectrum(spectrum1, spectrum2, targetElement) +{ + var maxMassSpectrum1 = getMax(spectrum1.masses); + var maxX = maxMassSpectrum1; + spectrum1.labels = getSpectrumLabels(spectrum1) + var maxMassSpectrum2 = 0; + if (spectrum2 != null) + { + maxMassSpectrum2 = getMax(spectrum2.masses); + if (maxMassSpectrum2 > maxMassSpectrum1) + maxX = maxMassSpectrum2; + spectrum2.labels = getSpectrumLabels(spectrum2) + } + maxX += 20; + + var margin = {top: 80, right: 80, bottom: 80, left: 80}; + //var width = maxX*2 - margin.left - margin.right; + //fixed width is better: + var width = 600 - margin.left - margin.right; + var zoomFactor = 1; + + var height; + //if (spectrum2 != null) + //height = 800 - margin.top - margin.bottom; + //else + height = 400 - margin.top - margin.bottom; + + //var x = d3.scale.ordinal() + // .rangeRoundBands([0, width], .1); + + var x = d3.scale.linear().domain([0, maxX]).range([0, width]); + + var y0 = d3.scale.linear().domain([300, 1100]).range([height, 0]); + + var xAxis = d3.svg.axis() + .scale(x) + .orient("center"); + + // create left yAxis + var yAxisLeft = d3.svg.axis().scale(y0).ticks(4).orient("left"); + + + var svg = d3.select(targetElement).append("svg") + .attr("width", width + margin.left + margin.right) + .attr("height", height + margin.top + margin.bottom) + .append("g") + .attr("class", "graph") + .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); + + + //x.domain([0,10,500]); + if (spectrum2 != null) + { + y0.domain([-999, 999]); + } + else + { + y0.domain([0, 999]); + } + svg.append("g") + .attr("class", "x axis") + .append("line") + .attr("y1", y0(0)) + .attr("y2", y0(0)) + .attr("x2", width); + + svg.append("g") + .attr("class", "y axis axisLeft") + .attr("transform", "translate(0,0)") + .call(yAxisLeft) + .append("text") + .attr("y", 6) + .attr("dy", "-2em") + .style("text-anchor", "end") + .text("Relative Intensity"); + + + + //for each mass in spectrum 1, generate bar: + for (var i = 0; i < spectrum1.masses.length; i++) + { + var heightFactor = 1; + if (spectrum2 != null) + heightFactor = 2; + + svg.append("rect") + .attr("class", "bar1") + .attr("x", x(spectrum1.masses[i]*zoomFactor)) + .attr("width", 1) + .attr("y", y0(spectrum1.intensities[i])) + .attr("height", height/heightFactor - y0(spectrum1.intensities[i])); + svg.append("text") + .attr("x", x(spectrum1.masses[i]*zoomFactor)) + .attr("y", y0(spectrum1.intensities[i])) + .attr("dy", "-1em") + .attr("dx", "-1em") + .style("text-anchor", "start") + .text(spectrum1.labels[i]); + } + + if (spectrum2 != null) + { + for (var i = 0; i < spectrum2.masses.length; i++) + { + heightFactor = 2; + + svg.append("rect") + .attr("class", "bar2") + .attr("x", x(spectrum2.masses[i]*zoomFactor)) + .attr("width", 1) + .attr("y", y0(0)) + .attr("height", height/heightFactor - y0(spectrum2.intensities[i])); + svg.append("text") + .attr("x", x(spectrum2.masses[i]*zoomFactor)) + .attr("y", y0(-spectrum2.intensities[i])) + .attr("dy", "1.5em") + .attr("dx", "-1em") + .style("text-anchor", "start") + .text(spectrum2.labels[i]); + } + } + +}