//===================================================================== // File: TracePeakFinder.java // Class: TracePeakFinder // Package: AFLPcore // // Author: Philip DeCamp // Date: June 1, 2001 // Contact: decamp@portalofevil.com // // Genographer v1.0 - Computer assisted scoring of gels. // Copyright (C) 1998 Montana State University // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; version 2 // of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // // The GNU General Public License is distributed in the file GPL //===================================================================== package AFLPcore; /** * This is a simple algorithm that is used to find peaks in a set of trace data. * There is a separate file, PeakLocate.java, that was created with this purpose * in mind, but that wouldn't have done exactly what I wanted. * The algorithm has three steps. * 1) Find a point that is high than the points on either side of it and check * if it's above the minimum threshold. * 2) Check the points thirty samples on either side of it to make sure there's * not a nearby point that's even higher. * 3) Make sure it meets the minimum width requirement. * * It's pretty simple, and fairly effective. The peaks on molecular weight * standards tend to be very well defined. */ public class TracePeakFinder{ //I made a zillion "find" methods for this thing. Most of them are pretty //unnecessary. I'll only define the parameters for the bottom one. public static double find(double [] trace){ return find(trace, 0, 50, 3); } public static double find(double [] trace, int offset){ return find(trace, offset, 50, 3); } public static double find(double [] trace, int offset, double minPeakValue){ return find(trace, offset, minPeakValue, 3); } /** * This is the one method in this class, really. Quite simple, it searches * through the data until it finds a peak, then returns the index of that number. * parameters: * * @trace: the array of doubles that constitutes the trace data * * @offset: the index into the trace data from which to start searching for * a peak. * * @minPeakValue: the minimum value a point must be to be considered a peak. * * @minPeakWidth: the minimum width a peak must be. */ public static long find(double [] trace, int offset, double minPeakValue, double minPeakWidth) { offset++; boolean flag; double temp; int count; //keep going until we run out of data, in which case this method returns //a -1 to signify that no more peaks were found. while(offset < trace.length - 1){ //If the point behind the current offset and the point in front of the current //offset are both lower, and the point meets the minimum peak value, then //this point is further analyzed. if(trace[offset - 1] < trace[offset] && trace[offset + 1] <= trace[offset] && trace[offset] >= minPeakValue){ flag = true; //Makes sure there's no point nearby that is even higher. for(int i = offset - 30; i < offset + 31; i++){ if( i >= 0 && i < trace.length){ if(trace[offset] < trace[i]) flag = false; } } if(flag == true){ count = 0; temp = 0; for(long i = offset - (long)minPeakWidth; i < offset; i++) if(i >= 0) if(trace[(int)i] > trace[(int)i + 1]) flag = false; temp = trace[offset]; for(long i = offset + 1; i <= offset + (long)minPeakWidth; i++) if(i < trace.length) if(trace[(int)i-1] < trace[(int)i]) flag = false; if(flag == true) return offset; } } offset++; } return -1; } }