content: /*
   * The MIT License (MIT)
   *
   * Copyright (c) 2011-2020 Broad Institute, Aiden Lab, Rice University, Baylor College of Medicine
   *
   * Permission is hereby granted, free of charge, to any person obtaining a copy
   * of this software and associated documentation files (the "Software"), to deal
   * in the Software without restriction, including without limitation the rights
   * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   * copies of the Software, and to permit persons to whom the Software is
   * furnished to do so, subject to the following conditions:
   *
   * The above copyright notice and this permission notice shall be included in
   * all copies or substantial portions of the Software.
   *
   *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   *  THE SOFTWARE.
   */
  
  package juicebox.tools.utils.original;
  
  import org.broad.igv.bbfile.BBFileReader;
  import org.broad.igv.bbfile.BigWigIterator;
  import org.broad.igv.bbfile.WigItem;
  
  import java.io.IOException;
  
  /**
   * Some utils for querying bigwig files
   *
   * @author jrobinso
   *         Date: 5/28/13
   *         Time: 3:27 PM
   */
  public class BigWigUtils {
  
      public static void computeBins(String path, int windowSize) throws IOException {
  
          BBFileReader reader = new BBFileReader(path);
          for (String chr : reader.getChromosomeNames()) {
              computeBins(reader, chr, 0, Integer.MAX_VALUE, windowSize);
          }
  
      }
  
  
      public static void computeBins(String path, String chr, int start, int end, int windowSize) throws IOException {
  
          BBFileReader reader = new BBFileReader(path);
          boolean found = false;
          StringBuilder errString = new StringBuilder();
          for (String chr1 : reader.getChromosomeNames()) {
              if (chr.equals(chr1)) found = true;
              errString.append("\"").append(chr1).append("\" ");
          }
          if (!found) {
              System.err.println("Chromosome \"" + chr + "\" not found in " + path);
              System.err.println("The chromosomes in " + path + " are " + errString);
              return;
          }
          computeBins(reader, chr, start, end, windowSize);
  
      }
  
      /**
       * Private method, does the actual work
       *
       * @param reader
       * @param chr
       * @param start
       * @param end
       * @param windowSize
       */
      private static void computeBins(BBFileReader reader, String chr, int start, int end, int windowSize) {
          BigWigIterator iter = reader.getBigWigIterator(chr, start, chr, end, false);
          double sum = 0;
          int nPts = 0;
          double max = 0;
          int currentBin = 0;
  
          while (iter.hasNext()) {
              WigItem datum = iter.next();
              int dPosition = (datum.getStartBase() + datum.getEndBase()) / 2;
  
  
              if (dPosition > (currentBin + 1) * windowSize) {
                  // Output previous window
                  // if (nPts > 0) {
  
                  double mean = sum / nPts;
                  int wStart = windowSize * currentBin;
                  int wEnd = wStart + windowSize;
                  // unclear why, but sometimes datum.getChromosome() is null
                  //System.out.println(datum.getChromosome() + "\t" + wStart + "\t" + wEnd + "\t" + mean + "\t" + max);
                  System.out.println(chr + "\t" + wStart + "\t" + wEnd + "\t" + mean + "\t" + max);
  
                  currentBin++;
  
                  // deal with empty bins
                  while (currentBin < dPosition / windowSize) {
                      wStart = windowSize * currentBin;
                      wEnd = wStart + windowSize;
                      mean = 0;
                      max = 0;
                      System.out.println(chr + "\t" + wStart + "\t" + wEnd + "\t" + mean + "\t" + max);
                      // System.out.println(datum.getChromosome() + "\t" + wStart + "\t" + wEnd + "\t" + mean + "\t" + max);
                      currentBin++;
                  }
                  // Start new window
                  currentBin = dPosition / windowSize;
                  sum = 0;
                  nPts = 0;
                  max = 0;
              }
  
              sum += datum.getWigValue();
              max = Math.max(max, datum.getWigValue());
              nPts++;
  
          }
      }
  
  
      /**
       * Example usage
       * <p/>
       * First argument (required): path, either file or URL.
       * http://hgdownload.cse.ucsc.edu/goldenPath/hg19/encodeDCC/wgEncodeUwTfbs/wgEncodeUwTfbsGm12878CtcfStdRawRep1.bigWig
       * /Users/jrobinso/projects/hic/data/wgEncodeUwTfbsGm12878CtcfStdRawRep1.bigWig
       * Second argument (required): windowSize in base pairs
       * 25000
       * Third argument (optional): chromosome
       * Fourth argument (optional): start base -- if supplied end base must also be supplied
       * Firth argument (optional):  end base
       */
      // Example use
      public static void main(String[] args) throws Exception {
  
          if (args.length < 2) {
              System.err.println("Chromosome and window size are required");
              System.exit(5);
          }
  
          String path = args[0];
          int windowSize = Integer.parseInt(args[1]);
          if (args.length == 2) {
              computeBins(path, windowSize);
          } else {
              String chr = args[2];
              if (args.length == 3) {
                  computeBins(path, chr, 0, Integer.MAX_VALUE, windowSize);
              } else {
                  int start = Integer.parseInt(args[3]) - 1;  // Convert to "zero" based coords
                  int end = Integer.parseInt(args[4]);
                  computeBins(path, chr, start, end, windowSize);
              }
  
          }
  
  
      }
  
  }
  