package org.nextprot.api.core.service;
import static org.junit.Assert.assertTrue;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.Ignore;
import org.junit.Test;
import org.nextprot.api.commons.service.MasterIdentifierService;
import org.nextprot.api.core.domain.Isoform;
import org.nextprot.api.core.domain.annotation.Annotation;
import org.nextprot.api.core.domain.annotation.AnnotationProperty;
import org.nextprot.api.core.test.base.CoreUnitBaseTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ActiveProfiles;
@ActiveProfiles({ "dev" })
public class PeptideMappingServiceIntegrationTest extends CoreUnitBaseTest {
@Autowired
private PeptideMappingService pmService;
@Autowired
private IsoformService isoService;
@Autowired
private MasterIdentifierService miService;
private static final String COLOR_NOT_COVERED = "grey";
private static final String COLOR_PEP_COVERED = "blue";
private static final String COLOR_1_TYPIC_COVERED = "lightgreen";
private static final String COLOR_N_TYPIC_COVERED = "orange";
@Ignore
@Test
public void shouldComputeCoverages() {
//List<String>entryNames = Arrays.asList(new String[]{"NX_Q8IYL9", "NX_Q66K66", "NX_P01308"});
//List<String>entryNames = miService.findUniqueNamesOfChromosome("Y");
// liste Monique
List<String>entryNames = Arrays.asList(new String[]{"NX_Q6UWW9", "NX_Q04118", "NX_P48165","NX_P01308","NX_Q13557"});
String sep = "\t";
System.out.println("Isoform" + sep + "Coverage type" + sep + "isoLength" + sep + "covered" + sep + "rateRounded");
for (String entryName: entryNames) {
List<Annotation> annotations = this.pmService.findNaturalPeptideMappingAnnotationsByMasterUniqueName(entryName);
List<Isoform> isoforms = isoService.findIsoformsByEntryName(entryName);
computeCoverage(isoforms, annotations, false, true);
computeCoverage(isoforms, annotations, true, true);
}
assertTrue(true);
}
//@Ignore
@Test
public void shouldComputeHTML4Highlight() throws FileNotFoundException {
//List<String>entryNames = Arrays.asList(new String[]{"NX_Q8IYL9", "NX_Q66K66", "NX_P01308"});
//List<String>entryNames = miService.findUniqueNamesOfChromosome("Y");
// liste Monique
List<String>entryNames = Arrays.asList(new String[]{"NX_Q6UWW9", "NX_Q04118", "NX_P48165","NX_P01308","NX_Q13557"});
StringBuilder sb = new StringBuilder();
sb.append("<html><body>\n");
sb.append("<ul>");
// sb.append("<span style=\"color:" + chunk.code + "\">");
sb.append("<li style=\"color:" + COLOR_NOT_COVERED + "\">"+ COLOR_NOT_COVERED + ": no peptide</li>");
sb.append("<li style=\"color:" + COLOR_PEP_COVERED + "\">"+ COLOR_PEP_COVERED + ": peptide</li>");
sb.append("<li style=\"color:" + COLOR_1_TYPIC_COVERED + "\">"+ COLOR_1_TYPIC_COVERED + ": single proteotypic</li>");
sb.append("<li style=\"color:" + COLOR_N_TYPIC_COVERED + "\">"+ COLOR_N_TYPIC_COVERED + ": multiple proteotypic</li>");
sb.append("</ul>");
for (String entryName: entryNames) {
List<Annotation> annotations = this.pmService.findNaturalPeptideMappingAnnotationsByMasterUniqueName(entryName);
List<Isoform> isoforms = isoService.findIsoformsByEntryName(entryName);
for (Isoform iso: isoforms) {
String cpep = computeCoverage(iso, annotations, false, false);
String ctyp = computeCoverage(iso, annotations, true, false);
String html = getHighlightHTML(iso, annotations, cpep, ctyp);
sb.append(html);
}
}
sb.append("</body></html>\n");
String filename = "./highlight-coverage-peptide-chromosome-y.html";
PrintWriter out = new PrintWriter(filename);
out.print(sb.toString());
out.close();
System.out.println("Wrote result in file " + filename);
}
private String computeCoverage(Isoform iso, List<Annotation> annotations, boolean proteotypic, boolean sysout) {
String name = iso.getUniqueName();
int isoLength = iso.getSequenceLength();
int[] coverage = new int[isoLength];
for (Annotation annot: annotations) {
if (proteotypic && ! isAboutProteotypicPeptide(annot)) continue;
if (! annot.isAnnotationPositionalForIsoform(name)) continue;
int start = annot.getStartPositionForIsoform(name);
int end = annot.getEndPositionForIsoform(name);
for (int i=start;i<=end;i++) coverage[i-1]=1;
}
int covered = getCoverageCount(coverage);
float rate = (float)100.0 * (float)covered / (float)isoLength;
float rateRounded = Math.round(rate * 100.0f) / 100.0f;
String sep = "\t";
String title = proteotypic ? "proteotypic coverage" : "peptide coverage";
if (sysout) System.out.println(name + sep + title + sep + isoLength + sep + covered + sep + rateRounded);
return (name + " " + title + " iso-length = " + isoLength + " covered = " + covered + " % : " + rateRounded);
// System.out.println(getCoverageString(coverage) + "\n");
}
private void showHighlightString(Isoform iso, List<Annotation> annotations) {
String name = iso.getUniqueName();
int isoLength = iso.getSequenceLength();
int[] coverage = getHighlightCoverage(iso, annotations);
String sep = "\t";
String title = "Natural highlight";
System.out.println(name + sep + title);
System.out.println(getHighlightString(coverage) + "\n");
List<Chunk> chunks = getHighlightChunks(iso.getSequence(),coverage);
for (Chunk chunk: chunks) {
System.out.println(chunk);
}
String html = getHighlightHTML(name, iso.getSequence(), chunks, "turlu", "chouette");
System.out.println(html);
}
private String getHighlightHTML(Isoform iso, List<Annotation> annotations, String cpep, String ctyp) {
String name = iso.getUniqueName();
int[] coverage = getHighlightCoverage(iso, annotations);
List<Chunk> chunks = getHighlightChunks(iso.getSequence(),coverage);
String html = getHighlightHTML(name, iso.getSequence(), chunks, cpep, ctyp);
return html;
}
private int[] getHighlightCoverage(Isoform iso, List<Annotation> annotations) {
String name = iso.getUniqueName();
int isoLength = iso.getSequenceLength();
int[] coverage = new int[isoLength];
// first loop sets aa coverage to 1 if there is a natural peptide on it
for (Annotation annot: annotations) {
if (! annot.isAnnotationPositionalForIsoform(name)) continue;
int start = annot.getStartPositionForIsoform(name);
int end = annot.getEndPositionForIsoform(name);
//System.out.println("first loop: " + start + " " + end);
for (int i=start;i<=end;i++) coverage[i-1]=1;
}
// second loop increments aa coverage if peptide is natural and proteotypic
for (Annotation annot: annotations) {
if (! annot.isAnnotationPositionalForIsoform(name)) continue;
if (isAboutProteotypicPeptide(annot)) {
int start = annot.getStartPositionForIsoform(name);
int end = annot.getEndPositionForIsoform(name);
//System.out.println("second loop: " + start + " " + end);
for (int i=start;i<=end;i++) coverage[i-1]=coverage[i-1]+1;
}
}
return coverage;
}
private boolean isAboutProteotypicPeptide(Annotation annot) {
boolean flag = false;
for (AnnotationProperty p:annot.getProperties()) {
if (p.getName().equals("is proteotypic") && p.getValue().equals("Y")) flag = true;
}
return flag;
}
private void computeCoverage(List<Isoform> isoforms, List<Annotation> annotations, boolean proteotypic, boolean sysout) {
for (Isoform iso: isoforms) {
computeCoverage( iso, annotations, proteotypic, sysout);
}
}
private void computeHighlights(List<Isoform> isoforms, List<Annotation> annotations) {
for (Isoform iso: isoforms) {
showHighlightString(iso, annotations);
}
}
private String getHighlightString(int[] coverage) {
StringBuilder sb = new StringBuilder();
for (int i=0;i<coverage.length;i++) {
if (i>0 && i % 10 ==0) sb.append(" ");
if (i>0 && i % 100 ==0) sb.append("\n");
int val = coverage[i];
String code = "?";
if (val==0) {
code = ".";
} else if (val==1) {
code = "+" ;
} else if (val==2) {
code = "1" ;
} else if (val>2) {
code = "N";
}
sb.append(code);
}
return sb.toString();
}
private String getHighlightHTML(String iso, String seq, List<Chunk> chunks,String cpep, String ctyp) {
StringBuilder sb = new StringBuilder();
String entry = iso.split("-")[0];
sb.append("<h3><a target=\"_blank\" href=\"http://alpha-search.nextprot.org/entry/" + entry + "/view/peptides\">" + iso + "</a></h3>\n");
sb.append("<p>"+ cpep + "</p>");
sb.append("<p>"+ ctyp + "</p>");
int oldLine=-1;
for (Chunk chunk: chunks) {
if (oldLine<chunk.line) {
if (oldLine!=-1) sb.append("</div>\n");
sb.append("<div style=\"font-family: monospace;\">\n");
oldLine=chunk.line;
}
sb.append("<span style=\"color:" + chunk.code + "\">");
sb.append(chunk.str);
sb.append("</span>");
}
sb.append("</div>\n");
return sb.toString();
}
private List<Chunk> getHighlightChunks(String seq, int[] coverage) {
List<Chunk> chunks = new ArrayList<>();
StringBuilder sb = new StringBuilder();
String oldCode="init";
String code = "?";
int line=0;
for (int i=0;i<coverage.length;i++) {
// compute code value
int val = coverage[i];
if (val==0) {
code = COLOR_NOT_COVERED;
} else if (val==1) {
code = COLOR_PEP_COVERED ;
} else if (val==2) {
code = COLOR_1_TYPIC_COVERED ;
} else if (val>2) {
code = COLOR_N_TYPIC_COVERED;
}
// when code changes
if (! oldCode.equals(code)) {
// save previous chunk
if (! oldCode.equals("init")) {
chunks.add(new Chunk(sb.toString(), oldCode, line));
}
// reinit buffer and update oldCode
sb = new StringBuilder();
oldCode = code;
}
// append content to buffer
if (i>0 && i % 10 ==0) sb.append(" ");
if (i>0 && i % 100 ==0) {
// force end of chunk at for end of line
chunks.add(new Chunk(sb.toString(), code, line));
sb=new StringBuilder();
line++;
}
sb.append(seq.charAt(i));
}
if (sb.length()>0) {
chunks.add(new Chunk(sb.toString(), code, line));
}
return chunks;
}
private String getCoverageString(int[] coverage) {
StringBuilder sb = new StringBuilder();
for (int i=0;i<coverage.length;i++) {
if (i>0 && i % 10 ==0) sb.append(" ");
if (i>0 && i % 100 ==0) sb.append("\n");
sb.append(coverage[i]==0 ? "0" : "1");
}
return sb.toString();
}
private int getCoverageCount(int[] coverage) {
int count=0;
for (int i=0;i<coverage.length;i++) {
if (coverage[i]==1) count++;
}
return count;
}
private static class Chunk {
String str;
String code;
int line;
public Chunk(String str, String code, int line) {
this.str=str;
this.code=code;
this.line=line;
}
public String toString() {
return line + "\t" + code + "\t" + str;
}
}
}