/**
* Create title and navigation urls to "all proteins","protein" and "proteoform" of the prsm
* @param {String} folderpath - provides folder path to the data and helps in building urls
*/
function BuildUrl(folderpath)
{
document.title = "Protein-Spectrum-Match for Spectrum #"+prsm_data.prsm.ms.ms_header.ids;
let l_allproteins_url = "proteins.html?folder="+folderpath;
document.getElementById("allprotein_url").href = l_allproteins_url;
document.getElementById("allprotein_url_end").href = l_allproteins_url;
let l_protein_URL = prsm_data.prsm.annotated_protein.sequence_name + " " + prsm_data.prsm.annotated_protein.sequence_description;
document.getElementById("protien_url").innerHTML = l_protein_URL;
document.getElementById("protien_url").href = "protein.html?folder="+folderpath+"&protein_Id="+prsm_data.prsm.annotated_protein.sequence_id;
document.getElementById("protien_url_end").innerHTML = l_protein_URL;
document.getElementById("protien_url_end").href = "protein.html?folder="+folderpath+"&protein_Id="+prsm_data.prsm.annotated_protein.sequence_id;
let l_protroform_URL = "Proteoform #"+prsm_data.prsm.annotated_protein.proteoform_id ;
document.getElementById("proteoform_url").innerHTML = l_protroform_URL;
document.getElementById("proteoform_url").href = "proteoform.html?folder="+folderpath+"&proteoform_Id="+prsm_data.prsm.annotated_protein.proteoform_id;
document.getElementById("proteoform_url_end").innerHTML = l_protroform_URL;
document.getElementById("proteoform_url_end").href ="proteoform.html?folder="+folderpath+"&proteoform_Id="+prsm_data.prsm.annotated_protein.proteoform_id;
document.getElementById("Protein-Spectrum-Match-Id-SpecId").innerHTML ="Protein-Spectrum-Match #"+prsm_data.prsm.prsm_id+" for Spectrum #" + prsm_data.prsm.ms.ms_header.ids;
}
/**
* Get the data of the prsm from global data variable prsm_data.
* Build the data into html to show the information about the prsm
*/
function loadDatafromJson2Html(){
document.getElementById("File_name").innerHTML = prsm_data.prsm.ms.ms_header.spectrum_file_name;
document.getElementById("PrSM_ID").innerHTML = prsm_data.prsm.prsm_id;
document.getElementById("Scan").innerHTML = prsm_data.prsm.ms.ms_header.scans;
document.getElementById("Precursor_charge").innerHTML = prsm_data.prsm.ms.ms_header.precursor_charge;
document.getElementById("precursormz").innerHTML = prsm_data.prsm.ms.ms_header.precursor_mz ;
document.getElementById("Precursor_mass").innerHTML = prsm_data.prsm.ms.ms_header.precursor_mono_mass;
document.getElementById("Proteoform_mass").innerHTML = prsm_data.prsm.annotated_protein.proteoform_mass;
document.getElementById("matched_peaks").innerHTML = prsm_data.prsm.matched_peak_number;
document.getElementById("matched_fragment_ions").innerHTML = prsm_data.prsm.matched_fragment_number;
document.getElementById("unexpected_modifications").innerHTML = prsm_data.prsm.annotated_protein.unexpected_shift_number;
document.getElementById("E_value").innerHTML = prsm_data.prsm.e_value;
document.getElementById("P_value").innerHTML = prsm_data.prsm.p_value;
document.getElementById("Q_value").innerHTML = prsm_data.prsm.fdr;
}
/**
* Build the monomass table with all the data from the peak variable of the prsm_data
* Provide a unique class name to the m/z values to provide on click action to xoom the
* spectrum graph to that position
*/
function createTableElements(){
var table = document.getElementById('spectrum');
var tbdy = document.createElement('tbody');
var ionArray = []; //contains the ion types used in the data
let l_scans = prsm_data.prsm.ms.ms_header.scans.split(" ") ;
let l_specIds = prsm_data.prsm.ms.ms_header.ids.split(" ") ;
let l_matched_peak_count = 0;
prsm_data.prsm.ms.peaks.peak.forEach(function(peak,i){
/* Check if peak contain matched_ions_num attribute */
//for each peak, get the ion type and store it in ionArray to determine which ion type to be checked in Inspect
if (parseInt(peak.matched_ions_num)>0){
let ion = peak.matched_ions.matched_ion.ion_type;
if (ionArray.length < 1){
ionArray.push(ion);
}
else if (ionArray.indexOf(ion) < 0) {
ionArray.push(ion);
}
}
if(peak.hasOwnProperty('matched_ions_num') && parseInt(peak.matched_ions_num)>1)
{
peak.matched_ions.matched_ion.forEach(function(matched_ion,i){
peak.matched_ions.matched_ion = matched_ion ;
loop_matched_ions(peak,i) ;
})
}
else
{
loop_matched_ions(peak,i) ;
}
})
//after looping through the prsm files, store the ion type data to local storage
window.localStorage.setItem('ionType', ionArray);
/**
* Inner function to create a rows and columns for monomass table
* @param {object} peak - contains information of each peak
* @param {int} i - index of the peak
*/
function loop_matched_ions(peak,i){
/* Create row for each peak value object in the table */
var tr = document.createElement('tr');
id = peak.spec_id+"peak"+peak.peak_id;
let l_scan;
if((parseInt(peak.peak_id) + 1)%2 == 0)
{
// class name helps to get unmatched peaks when clicking unmatched peaks
l_class = "unmatched_peak even";
}
else
{
// class name helps to get unmatched peaks when clicking unmatched peaks
l_class = "unmatched_peak odd";
}
if(peak.hasOwnProperty('matched_ions_num'))
{
id = id + peak.matched_ions.matched_ion.ion_type;
if((parseInt(peak.peak_id) + 1)%2 == 0)
{
// class name helps to get matched peaks when clicking matched peaks
l_class = "matched_peak even";
}
else
{
// class name helps to get matched peaks when clicking matched peaks
l_class = "matched_peak odd";
}
l_matched_peak_count++;
// create a name for each row
tr.setAttribute("name",peak.matched_ions.matched_ion.ion_position);
}
// Set "id","class name" and "role" for each row
tr.setAttribute("id", id);
tr.setAttribute("class",l_class);
tr.setAttribute("role","row");
for(let i = 0;i<11;i++){
var td = document.createElement('td');
td.setAttribute("align","center");
if(i == 0)
{
if(peak.spec_id == l_specIds[0]) l_scan = l_scans[0];
else l_scan = l_scans[1];
td.setAttribute("class","row_scanIds");
td.innerHTML = l_scan ;
}
if(i == 1)
{
td.innerHTML = parseInt(peak.peak_id) + 1 ;
td.setAttribute("class","row_peakNum");
}
if(i == 2)
{
td.innerHTML = peak.monoisotopic_mass;
td.setAttribute("class","row_monoMass");
}
if(i == 3)
{
// provide link to click on m/z value to view spectrum
let a = document.createElement('a');
a.href="#!"
a.className = "peakRows"
a.innerHTML = peak.monoisotopic_mz;
td.appendChild(a);
}
if(i == 4)
{
td.innerHTML = peak.intensity;
td.setAttribute("class","row_intensity");
}
if(i == 5)
{
td.innerHTML = peak.charge;
td.setAttribute("class","row_charge");
}
if(peak.hasOwnProperty('matched_ions_num'))
{
if(i == 6)
{
td.innerHTML = peak.matched_ions.matched_ion.theoretical_mass;
}
if(i == 7)
{
td.innerHTML = peak.matched_ions.matched_ion.ion_type+peak.matched_ions.matched_ion.ion_display_position;
}
if(i == 8)
{
td.innerHTML = peak.matched_ions.matched_ion.ion_position;
}
if(i == 9)
{
td.innerHTML = peak.matched_ions.matched_ion.mass_error;
}
if(i == 10)
{
td.innerHTML = peak.matched_ions.matched_ion.ppm;
}
}
tr.appendChild(td);
}
tbdy.appendChild(tr);
}
let l_All_Peaks = prsm_data.prsm.ms.peaks.peak.length;
let l_not_matched_peak_count = l_All_Peaks - l_matched_peak_count;
document.getElementById("all_peak_count").innerHTML = "All peaks (" + l_All_Peaks + ")" ;
document.getElementById("matched_peak_count").innerHTML = "Matched peaks (" + l_matched_peak_count + ")" ;
document.getElementById("not_matched_peak_count").innerHTML = "Not Matched peaks (" + l_not_matched_peak_count + ")" ;
table.appendChild(tbdy);
}
/**
* Get occurence of "Variable" and "Fixed", convert the data to HTML
* @param {object} prsm - prsm is the data attribute inside global prsm_data variable
*/
function occurence_ptm(prsm)
{
let variable_ptm = "";
let fixed_ptm = "" ;
// Check if annotation has ptm attribute inside it
if(prsm.annotated_protein.annotation.hasOwnProperty('ptm'))
{
let ptm = prsm.annotated_protein.annotation.ptm ;
// Check if ptm attribute is an array
if(Array.isArray(ptm))
{
ptm.forEach(function(ptm, index){
// Check if there exist variable or fixed ptms
if(ptm.ptm_type == "Variable")
{
variable_ptm_raw = getVariablePtm(ptm).replace("[", " [");
variable_ptm = variable_ptm + variable_ptm_raw + "] " ;
}
if(ptm.ptm_type == "Fixed")
{
fixed_ptm_raw = getFixedPtm(ptm).replace("[", " [");
fixed_ptm = fixed_ptm + fixed_ptm_raw + "] " ;
}
})
}
else
{
// Check if there exist variable or fixed ptms
if(ptm.ptm_type == "Variable")
{
variable_ptm_raw = getVariablePtm(ptm).replace("[", " [");
variable_ptm = variable_ptm + variable_ptm_raw + "]" ;
}
if(ptm.ptm_type == "Fixed")
{
fixed_ptm_raw = getFixedPtm(ptm).replace("[", " [");
fixed_ptm = fixed_ptm + fixed_ptm_raw + "]" ;
}
}
}
// Add the information of fixed ptms to html at id - ptm_abbreviation
if(fixed_ptm != "")
{
let div = document.getElementById("ptm_abbreviation") ;
let text1 = document.createElement("text");
let text2 = document.createElement("text");
text1.innerHTML = " "+"Fixed PTMs: ";
text2.innerHTML = fixed_ptm ;
text2.target = "_blank";
text2.style = "color:red" ;
div.appendChild(text1);
div.appendChild(text2);
}
// Add the information of varibale ptms to html at id - ptm_abbreviation
if(variable_ptm != "")
{
let div = document.getElementById("ptm_abbreviation") ;
let text1 = document.createElement("text");
let text2 = document.createElement("text");
text1.innerHTML = " "+"Variable PTMs: ";
text2.innerHTML = variable_ptm ;
text2.target = "_blank";
text2.style = "color:red" ;
div.appendChild(text1);
div.appendChild(text2);
}
}
/**
* Get the information about all the unknown ptms
* @param {object} prsm - prsm is the data attribute inside global prsm_data variable
*/
function getUnknownPtms(prsm)
{
let data = " [";
// Check if annotation attribute has mass_shift attribute inside it
if(prsm.annotated_protein.annotation.hasOwnProperty('mass_shift'))
{
let mass_shift = prsm.annotated_protein.annotation.mass_shift ;
let UnknownExist = false;
if(Array.isArray(mass_shift))
{
let len = mass_shift.length;
mass_shift.forEach(function(each_mass_shift, i){
// Check for unexpected mass shifts
if(each_mass_shift.shift_type == "unexpected")
{
UnknownExist = true;
if(i != len-1)
{
data = data + each_mass_shift.anno + "," ;
}
else{
data = data + each_mass_shift.anno + "]" ;
}
}
})
}
else if(mass_shift.shift_type == "unexpected")
{
UnknownExist = true;
data = data + mass_shift.anno + "]" ;
}
// If unexpected modifications exist add them to html at id - ptm_unexpectedmodifications
if(UnknownExist)
{
let val = "Unknown" + data;
document.getElementById("ptm_unexpectedmodification").style.display = "block";
let div = document.getElementById("ptm_unexpectedmodification") ;
let text1 = document.createElement("text");
let text2 = document.createElement("text");
text1.innerHTML = " "+"Unexpected modifications: "; // Adding space using
text2.innerHTML = val ;
text2.target = "_blank";
text2.style = "color:red" ;
div.appendChild(text1);
div.appendChild(text2);
}
}
}
/**
* Get all the variable ptms
* @param {object} prsm - prsm is the data attribute inside global prsm_data variable
*/
function getVariablePtm(ptm)
{
let variable_ptm = "[" ;
let abbrevation = ptm.ptm.abbreviation ;
if(Array.isArray(ptm.occurence))
{
ptm.occurence.forEach(function(occurence,i){
let left = parseInt(occurence.left_pos) + 1;
variable_ptm = variable_ptm + left + "-" + occurence.right_pos ;
if(ptm.occurence.length-1 > i )
{
variable_ptm = variable_ptm + ";" ;
}
})
}
else
{
let left = parseInt(ptm.occurence.left_pos) + 1;
variable_ptm = variable_ptm + left + "-" + ptm.occurence.right_pos ;
}
variable_ptm = ptm.ptm.abbreviation + variable_ptm ;
return variable_ptm ;
}
/**
* Get all the "Fixed" ptms
* @param {object} prsm - prsm is the data attribute inside global prsm_data variable
*/
function getFixedPtm(ptm)
{
let fixed_ptm = "[" ;
let abbrevation = ptm.ptm.abbreviation ;
if(Array.isArray(ptm.occurence))
{
ptm.occurence.forEach(function(occurence,i){
fixed_ptm = fixed_ptm + occurence.right_pos;
if(ptm.occurence.length-1 > i )
{
fixed_ptm = fixed_ptm + ";" ;
}
})
}
else
{
fixed_ptm = fixed_ptm + ptm.occurence.right_pos;
}
fixed_ptm = ptm.ptm.abbreviation + fixed_ptm ;
return fixed_ptm ;
}
/**
* Create buttons to save the svg as png/svg and to redraw the svg with given dimensions
* @param {object} para - contains the parameters to draw the sequence SVG
* @param {object} prsm - prsm is the data attribute inside global prsm_data variable
* @param {String} id - id from the html at which the svg needs to be redraw (Here it is from the modal block)
*/
function buttonsAndAlerts(para,prsm,id)
{
let x,y;
// Id of the pop_up svg
id = "l_popup_svg" ;
// On click action to get pop_up window
d3.select('#saveImage').on("click",function(){
d3.selectAll(".l_popup_svg_g").remove();
para = new parameters();
let prsm = prsm_data.prsm ;
[para,id] = buildSvg(para,prsm,id);
// Get the amount of skipped acid and write the amount
// of skipped acid at the start and end of the sequence
skippedAcidNotification(para,prsm,id) ;
if(para.show_num)
{
// Get the numerical count at the start enad end of
// each row of sequence
getNumValues(para,prsm,id);
}
// Determine the start and end position of the sequence
drawAnnoOfStartEndPosition(para,prsm,id);
// Draw Annotations
annotations(para,prsm,id);
// Get the position of the fixed ptms and color them to red
addColorToFixedPtms(para,prsm,id);
// Color the background of occurence of mass shift
massShiftBackgroundColor(para,prsm,id);
// set the dimensions of popup svg to default values
document.getElementById("row-size").value = para.row_length ;
document.getElementById("letter-width").value = para.letter_width ;
document.getElementById("row-height").value = para.row_height ;
document.getElementById("block-width").value = para.gap_width ;
document.getElementById("num-width").value = para.numerical_width ;
document.getElementsByName("show-num")[0].checked = para.show_num ;
document.getElementsByName("show-skipped-lines")[0].checked = para.show_skipped_lines ;
// Allows to drag the pop up windows
$("#myModal").draggable({
appendTo: "body"
});
});
// Download the svg as ".svg" image
d3.select('#download_SVG').on("click",function(){
x = d3.event.pageX;
y = d3.event.pageY;
popupnamewindow("svg",id,x,y);
});
// Download svg as PNG Image
d3.select('#download_PNG').on("click", function(){
x = d3.event.pageX;
y = d3.event.pageY;
popupnamewindow("png",id,x,y);
}) ;
d3.select('#image_help').on("click",function(){
$("#helpModal").draggable({
appendTo: "#myModal"
});
});
// On Click action to resize the svg with user dimensions
d3.select('#resize').on("click", function(){
d3.selectAll("."+id+"_g").remove();
// Get dimension parameters of svg
var para = new parameters() ;
para.row_length = parseInt(document.getElementById("row-size").value);
para.letter_width = parseInt(document.getElementById("letter-width").value) ;
para.row_height = parseInt(document.getElementById("row-height").value) ;
para.gap_width = parseInt(document.getElementById("block-width").value) ;
para.numerical_width = parseInt(document.getElementById("num-width").value) ;
// Check whether show numbers is checked
if(document.getElementsByName("show-num")[0].checked)
{
para.show_num = true ;
}
else
{
// Reduce the left and right margins when numbers are
// no needed at start and end of each row in svg
para.show_num = false ;
para.left_margin = 20;
para.right_margin = 20;
}
// Check to show skipped lines
if(document.getElementsByName("show-skipped-lines")[0].checked)
{
para.show_skipped_lines = true ;
}
else
{
para.show_skipped_lines = false ;
}
// Redraw the svg with new dimension parameters
prsm = prsm_data.prsm ;
[para,id] = buildSvg(para,prsm,id);
// Get the amount of skipped acid and write the amount
// of skipped acid at the start and end of the sequence
skippedAcidNotification(para,prsm,id) ;
if(para.show_num)
{
// Get the numerical count at the start and end of
// each row of sequence
getNumValues(para,prsm,id);
}
// Determine the start and end position of the sequence
drawAnnoOfStartEndPosition(para,prsm,id) ;
// Draw Annotations
annotations(para,prsm,id);
// Get the position of the fixed ptms and color them to red
addColorToFixedPtms(para,prsm,id);
// Color the background of occurence of mass shift
massShiftBackgroundColor(para,prsm,id);
});
}
/**
* Function to produce a pop up window to provide name and set name to
* the image while downloading the image of Graph SVG and Sequence SVG
* @param {String} type - Provides if the image is downloaded as svg or png
* @param {String} id - Provides the id of the svg to be downloaded
* @param {Float} x - Provides coordinate on where to show a tooltip block to enter name of the image to be downloaded
* @param {Float} y - Provides coordinate on where to show a tooltip block to enter name of the image to be downloaded
*/
function popupnamewindow(type,id,x,y){
d3.selectAll("#tooltip_imagename").remove() ;
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.attr("id","tooltip_imagename")
.style("opacity", 1);
// Provides a tooltip to enter a name for the image to be downloaded
div.transition()
.duration(200)
.style("opacity", .9);
div.html(
'<input type="text" placeholder="Image Name" id="imagename" />'+
'<button id="saveimage" style = "none" type="button">save</button>'
)
.style("left", (x - 30) + "px") // x Coordinate of the position of the tooltip
.style("top", (y - 60) + "px") // y Coordinate of the position of the tooltip
.attr("box-sizing","border")
.attr("display","inline-block")
.attr("min-width","1.5em")
.attr("padding","2px")
.attr("margin-left","0px")
.attr("text-align","center")
.attr("text-decoration","none")
.attr("border","1px solid #111111")
.attr("background-color","white");
// On click action to save the image on click of download button
$("#saveimage").click(function(){
let imagename = $("#imagename").val();
if( imagename == null || imagename == "")
{
imagename = "spectrum";
}
// Check if the image needs to be downloaded as svg
if(type == "svg"){
d3.selectAll("#tooltip_imagename").remove() ;
let svg_element = d3.selectAll("#"+id).node();
svg2svg(svg_element,imagename);
}
// Check if the image needs to be downloaded as png
if(type == "png"){
d3.selectAll("#tooltip_imagename").remove() ;
let l_svgContainer = d3.select("#"+id);
let svgString = getSVGString(l_svgContainer.node());
let specParams = new SpectrumParameters();
let width = specParams.svgWidth;
let height = specParams.svgHeight ;
svgString2Image( svgString, 2*width, 2*height, 'png', save );
function save( dataBlob, filesize ){
saveAs( dataBlob, imagename );
}
}
})
}