static void calculateEigenvector(String file, String chr, int binsize) throws IOException {
    if (!file.endsWith("hic")) {
      System.err.println("Only 'hic' files are supported");
      System.exit(-1);
    }
    // Load the expected density function, if it exists.
    Map<Integer, DensityFunction> zoomToDensityMap = null;
    String densityFile = file + ".densities";
    if (FileUtils.resourceExists(densityFile)) {
      InputStream is = null;
      try {
        is = ParsingUtils.openInputStream(densityFile);
        zoomToDensityMap = DensityUtil.readDensities(is);

      } finally {
        if (is != null) is.close();
      }
    } else {
      System.err.println("Densities file doesn't exist");
      System.exit(-1);
    }

    SeekableStream ss = IGVSeekableStreamFactory.getStreamFor(file);
    Dataset dataset = (new DatasetReader(ss)).read();
    Chromosome[] tmp = dataset.getChromosomes();

    Map<String, Chromosome> chromosomeMap = new HashMap<String, Chromosome>();
    for (Chromosome c : tmp) {
      chromosomeMap.put(c.getName(), c);
    }

    if (!chromosomeMap.containsKey(chr)) {
      System.err.println("Unknown chromosome: " + chr);
      System.exit(-1);
    }
    int zoomIdx = 0;
    boolean found = false;
    for (; zoomIdx < HiCGlobals.zoomBinSizes.length; zoomIdx++) {
      if (HiCGlobals.zoomBinSizes[zoomIdx] == binsize) {
        found = true;
        break;
      }
    }

    if (!found) {
      System.err.println("Unknown bin size: " + binsize);
      System.exit(-1);
    }

    Matrix matrix = dataset.getMatrix(chromosomeMap.get(chr), chromosomeMap.get(chr));
    MatrixZoomData zd = matrix.getObservedMatrix(zoomIdx);
    final DensityFunction df = zoomToDensityMap.get(zd.getZoom());
    double[] eigenvector = zd.computeEigenvector(df, 0);
    for (double ev : eigenvector) System.out.print(ev + " ");
    System.out.println();
  }
  /**
   * Load chromosomes from given ID or file name.
   *
   * @param idOrFile Genome ID or file name where chromosome lengths written
   * @return Chromosome lengths
   * @throws IOException if chromosome length file not found
   */
  public static List<Chromosome> loadChromosomes(String idOrFile) throws IOException {

    InputStream is = null;

    try {
      // Note: to get this to work, had to edit Intellij settings
      // so that "?*.sizes" are considered sources to be copied to class path
      is = HiCTools.class.getResourceAsStream(idOrFile + ".chrom.sizes");

      if (is == null) {
        // Not an ID,  see if its a file
        File file = new File(idOrFile);
        if (file.exists()) {
          is = new FileInputStream(file);
        } else {
          throw new FileNotFoundException("Could not find chromosome sizes file for: " + idOrFile);
        }
      }

      List<Chromosome> chromosomes = new ArrayList();
      chromosomes.add(0, null); // Index 0 reserved for "whole genome" psuedo-chromosome

      Pattern pattern = Pattern.compile("\t");
      BufferedReader reader = new BufferedReader(new InputStreamReader(is));
      String nextLine;
      long genomeLength = 0;
      int idx = 1;

      while ((nextLine = reader.readLine()) != null) {
        String[] tokens = pattern.split(nextLine);
        if (tokens.length == 2) {
          String name = tokens[0];
          int length = Integer.parseInt(tokens[1]);
          genomeLength += length;
          chromosomes.add(idx, new Chromosome(idx, name, length));
          idx++;
        } else {
          System.out.println("Skipping " + nextLine);
        }
      }

      // Add the "psuedo-chromosome" All, representing the whole genome.  Units are in kilo-bases
      chromosomes.set(0, new Chromosome(0, "All", (int) (genomeLength / 1000)));

      return chromosomes;
    } finally {
      if (is != null) is.close();
    }
  }
  static void dumpMatrix(String file, String chr1, String chr2, int binsize, String type)
      throws IOException {

    if (!file.endsWith("hic")) {
      System.err.println("Only 'hic' files are supported");
      System.exit(-1);
    }
    // Load the expected density function, if it exists.
    Map<Integer, DensityFunction> zoomToDensityMap = null;
    if (type.equals("oe") || type.equals("pearson")) {
      String densityFile = file + ".densities";
      if (FileUtils.resourceExists(densityFile)) {
        InputStream is = null;
        try {
          is = ParsingUtils.openInputStream(densityFile);
          zoomToDensityMap = DensityUtil.readDensities(is);

        } finally {
          if (is != null) is.close();
        }
      } else {
        System.err.println("Densities file doesn't exist, cannot calculate O/E or Pearson's");
        System.exit(-1);
      }
    }

    SeekableStream ss = IGVSeekableStreamFactory.getStreamFor(file);
    Dataset dataset = (new DatasetReader(ss)).read();
    Chromosome[] tmp = dataset.getChromosomes();

    Map<String, Chromosome> chromosomeMap = new HashMap<String, Chromosome>();
    for (Chromosome c : tmp) {
      chromosomeMap.put(c.getName(), c);
    }

    if (!chromosomeMap.containsKey(chr1)) {
      System.err.println("Unknown chromosome: " + chr1);
      System.exit(-1);
    } else if (!chromosomeMap.containsKey(chr2)) {
      System.err.println("Unknown chromosome: " + chr2);
      System.exit(-1);
    }
    if (type.equals("oe") || type.equals("pearson")) {
      if (!chr1.equals(chr2)) {
        System.err.println("Chromosome " + chr1 + " not equal to Chromosome " + chr2);
        System.err.println("Currently only intrachromosomal O/E and Pearson's are supported.");
        System.exit(-1);
      }
    }

    int zoomIdx = 0;
    boolean found = false;
    for (; zoomIdx < HiCGlobals.zoomBinSizes.length; zoomIdx++) {
      if (HiCGlobals.zoomBinSizes[zoomIdx] == binsize) {
        found = true;
        break;
      }
    }

    if (!found) {
      System.err.println("Unknown bin size: " + binsize);
    }

    Matrix matrix = dataset.getMatrix(chromosomeMap.get(chr1), chromosomeMap.get(chr2));
    MatrixZoomData zd = matrix.getObservedMatrix(zoomIdx);
    if (type.equals("oe") || type.equals("pearson")) {
      final DensityFunction df = zoomToDensityMap.get(zd.getZoom());
      if (df == null) {
        System.err.println("Densities not calculated to this resolution.");
        System.exit(-1);
      }
      zd.dumpOE(df, type.equals("oe"));
    } else zd.dump();
  }