/* * @(#)ORonnModel.java 1.0 June 2010 * * Copyright (c) 2010 Peter Troshin * * BioJava development code * * This code may be freely distributed and modified under the * terms of the GNU Lesser General Public Licence. This should * be distributed with the code. If you do not have a copy, * see: * * http://www.gnu.org/copyleft/lesser.html * * Copyright for this code is held jointly by the individual * authors. These should be listed in @author doc comments. * * For more information on the BioJava project and its aims, * or to join the biojava-l mailing list, visit the home page * at: * * http://www.biojava.org/ * */ package org.biojava.nbio.ronn; import org.biojava.nbio.ronn.ModelLoader.Model; import org.biojava.nbio.ronn.ModelLoader.Threshold; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.io.FileNotFoundException; import java.io.PrintWriter; /** * Fully re-factored version of RONN model. Based on the code in C version of * RONN. * * @author Peter Troshin * @version 1.0 * @since 3.0.2 */ public final class ORonnModel { private static final Logger logger = LoggerFactory.getLogger(ORonnModel.class); /** * Order probability, corresponds to disorder as 1-order */ private final float disorder_weight; private final static int AA_ALPHABET = 19; private final static int maxR = 110; //private final static float coef = 1.0f; /** * Holds encoded query sequence */ private final short[] seqAA; /** * Holds query sequence */ private final char[] query; private final Model model; /** * Disorder scores for all residues */ private float[] scores = null; final float[] detect() { scores = new float[query.length]; int sResidue; int dIndex; int r; float est, fOrder, pDisor, fDisor; final float[][] Z = new float[seqAA.length][ORonnModel.maxR]; final int[] Q = new int[seqAA.length]; final Threshold thold = new ModelLoader.Threshold(model.modelNum); /* * 19 looks like a size of the sliding window. So for any sequences * shorted than 19 AA the score will be NaN. Original RONN segfault in * such condition */ for (sResidue = 0; sResidue <= query.length - ORonnModel.AA_ALPHABET; sResidue++) { est = 0.0f; for (dIndex = 0; dIndex < model.numOfDBAAseq; dIndex++) { final float[] rho = align(sResidue, dIndex);// search for the // maximum alignment between ith peptide from the // query and the dIndex-th database sequence est += model.W[dIndex] * Math.exp((rho[1] - rho[0]) / rho[0]); } fOrder = (float) (Math.exp(-0.5 * Math.pow(est - thold.mu0, 2.0) / thold.sigma0) / (Math.sqrt(6.28) * thold.sigma0)); fDisor = (float) (Math.exp(-0.5 * Math.pow(est - thold.mu1, 2.0) / thold.sigma1) / (Math.sqrt(6.28) * thold.sigma1)); pDisor = (float) (disorder_weight * fDisor / ((1.0 - disorder_weight) * fOrder + disorder_weight * fDisor)); for (r = sResidue; r < sResidue + ORonnModel.AA_ALPHABET; r++) { Z[r][Q[r]] = pDisor; Q[r]++; } } for (sResidue = 0; sResidue < query.length; sResidue++) { est = 0.0f; float[] zRow = Z[sResidue]; int numOfIterations = Q[sResidue]; for (r = 0; r < numOfIterations; r++) { est += zRow[r]; } scores[sResidue] = est / numOfIterations; } return scores; } public void getScores(final File outfile) throws FileNotFoundException { final PrintWriter output = new PrintWriter(outfile); if (scores == null) { synchronized (this) { if (scores == null) { detect(); } } } for (int i = 0; i < scores.length; i++) { output.printf("%c\t%f\n", query[i], scores[i]); } output.close(); } // sResidue query sequence index and dIndex database sequence index private final float[] align(final int sResidue, final int dIndex) { int dResidue, r; float maxScore = -1000000; float rho1 = 0; int maxIdx = 0; float rho0 = 0; short[] dbAARow = model.dbAA[dIndex]; int numOfIterations = model.Length[dIndex] - ORonnModel.AA_ALPHABET; for (dResidue = 0; dResidue <= numOfIterations; dResidue++) { // go though the database sequence for maximised alignment rho1 = 0.0f; for (r = 0; r < ORonnModel.AA_ALPHABET; r++) { // go through the query sequence for one alignment rho1 += RonnConstraint.Blosum62[seqAA[sResidue + r]][dbAARow[dResidue + r]]; } if (rho1 > maxScore) { maxScore = rho1; maxIdx = dResidue; } } for (r = 0; r < ORonnModel.AA_ALPHABET; r++) { rho0 += RonnConstraint.Blosum62[dbAARow[maxIdx + r]][dbAARow[maxIdx + r]]; } return new float[] { rho0, maxScore }; } public ORonnModel(final String sequence, final Model model, final float disorder) throws NumberFormatException { this.disorder_weight = disorder; this.model = model; query = sequence.toCharArray(); seqAA = new short[query.length]; assert model != null; assert model.numOfDBAAseq > 0; for (int sResidue = 0; sResidue < sequence.length(); sResidue++) { seqAA[sResidue] = RonnConstraint.INDEX[query[sResidue] - 'A']; if ((seqAA[sResidue] < 0) || (seqAA[sResidue] > 19)) { logger.error("seqAA[sResidue]={}({})", seqAA[sResidue], query[sResidue]); System.exit(1); } } } }