package HMMR_ATAC; /* * Copyright (C) 2019 Evan Tarbell and Tao Liu 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, either version 3 of the License, or (at your option) any later version. 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, see <https://www.gnu.org/licenses/>. */ import java.io.IOException; import java.util.ArrayList; import org.apache.commons.math3.stat.descriptive.moment.Mean; import org.apache.commons.math3.stat.descriptive.rank.Max; import org.broad.igv.bbfile.BBFileReader; import org.broad.igv.bbfile.BigWigIterator; import org.broad.igv.bbfile.WigItem; import Node.TagNode; public class GetSignal { private String wig = null; private int start; private int stop; private String chr; private double score; private double median; private double max; private ArrayList<Double> val; private TagNode node; /** * Constructor * @param w a String representing the bigwig file * @param c a String representing the chromosome name * @param b an integer representing the start of the region to score * @param e an integer representing the stop of the region to score * @throws IOException */ public GetSignal(String w,String c, int b,int e) throws IOException{ wig = w; chr = c; start = b; stop = e; find(); } /** * Access the average score * @return a double representing the average score */ public double getScore(){return score;} /** * Access the median score * @return a double representing the median score */ public double getMedian(){return median;} /** * Access the max score * @return a double representing the maximum score */ public double getMax(){return max;} /** * Access the bigwig scores * @return an ArrayList of doubles representing all the bigwig scores */ public ArrayList<Double> getValues(){return val;} /** * Access the position with the maximum score * @return a TagNode representing the position having the maximum score */ public TagNode getMaxPos(){return node;} /** * Find the max and the max position * @throws IOException */ private void find() throws IOException{ BBFileReader wigReader = new BBFileReader(wig); BigWigIterator iter = wigReader.getBigWigIterator(chr,start,chr,stop,false); Max m = new Max(); Mean mu = new Mean(); ArrayList<Double> values = new ArrayList<Double>(); double tempMax=0; node = null; while (iter.hasNext()){ WigItem item = iter.next(); double value = item.getWigValue(); m.increment(value); for (int i = item.getStartBase();i < item.getEndBase();i++){ values.add(value); mu.increment(value); if (value > tempMax){ tempMax = value; node = new TagNode(chr,i,i+1); } } } val = values; if (values.size()>0){ score = mu.getResult(); max = m.getResult(); median = values.get(values.size()/2); } else{ score=0;max=0;median=0; } wigReader = null; } /** * Find max positions and extend toward second highest position * @throws IOException */ public void findAll() throws IOException{ if (max > 0){ ArrayList<TagNode> temp = new ArrayList<TagNode>(); BBFileReader wigReader = new BBFileReader(wig); BigWigIterator iter = wigReader.getBigWigIterator(chr,start,chr,stop,false); while (iter.hasNext()){ WigItem item = iter.next(); double value = item.getWigValue(); for (int i = item.getStartBase();i < item.getEndBase();i++){ if (value == max){ TagNode tempNode = new TagNode(chr,i,i+1); temp.add(tempNode); } } } if (temp.size() > 1){ TagNode left = temp.get(0); TagNode right = temp.get(temp.size()-1); int start = ((right.getStop() - left.getStart())/2) + left.getStart(); node = new TagNode(left.getChrom(),start,start+1); } wigReader=null; } } /** * Find max and max position of gaussian smoothed data * @param stdev an integer representing the standard deviation for smoothing * @throws IOException */ public void findSmooth(int stdev) throws IOException{ if (max > 0){ // Use a window size equal to +/- 3 SD's double[] filter = new double[6*stdev+1]; double sum = 0; for (int i = 0; i < filter.length; i++) { double x = i - 3*stdev; double value = (double) Math.exp(-(x*x) / (2*stdev*stdev)); filter[i] = value; sum += value; } // Normalize so that the filter is area-preserving (has total area = 1) for (int i = 0; i < filter.length; i++) { filter[i] /= sum; } BBFileReader wigReader = new BBFileReader(wig); int paddedStart = start-(3*stdev); int paddedStop = stop+(3*stdev); BigWigIterator iter = wigReader.getBigWigIterator(chr,paddedStart,chr,paddedStop,false); double[] data = new double[paddedStop-paddedStart]; while (iter.hasNext()){ WigItem item = iter.next(); double value = item.getWigValue(); for (int i = item.getStartBase();i < item.getEndBase();i++){ if (i >= paddedStart && i < paddedStop){ data[i - paddedStart] = value; } } } wigReader=null; // Convolve the data with the filter double[] smoothed = new double[stop-start]; for (int i = 0; i < smoothed.length; i++) { for (int j = 0; j < filter.length; j++) { smoothed[i] += data[i+j] * filter[j]; } } double tempMax = 0.0; for (int i = 0;i < smoothed.length;i++){ if (smoothed[i] > tempMax){ tempMax = smoothed[i]; node = new TagNode(chr,start+i,start+i+1); } } } } }