/**
   * Sample and calculate the probability of hitting each type of marker (marker.class). Creates
   * 'numReads' reads of size 'readLen' and count how many of them hit each marker type.
   */
  CountByType randomSampling(int readLen, int numReads) {
    CountByType countReads = new CountByType();
    RandMarker randMarker = new RandMarker(snpEffectPredictor.getGenome());

    for (int i = 0; i < numReads; i++) {
      // Random read
      Marker read = randMarker.rand(readLen);

      // Where does it hit?
      Markers regions = snpEffectPredictor.queryDeep(read);
      HashSet<String> doneRegion = new HashSet<String>();
      for (Marker m : regions) {
        String mtype = markerTypes.getType(m);
        String msubtype = markerTypes.getSubType(m);

        if (!doneRegion.contains(mtype)) {
          countReads.inc(mtype); // Count reads
          doneRegion.add(mtype); // Do not count twice
        }

        if ((msubtype != null) && !doneRegion.contains(msubtype)) {
          countReads.inc(msubtype); // Count reads
          doneRegion.add(msubtype); // Do not count twice
        }
      }
    }

    return countReads;
  }
  /** Count bases covered for each marker type */
  public void countBases() {
    // ---
    // Add all markers
    // ---
    Markers markers = new Markers();
    markers.add(snpEffectPredictor.getMarkers());
    for (Gene gene : snpEffectPredictor.getGenome().getGenes()) {
      markers.add(gene);
      markers.add(gene.markers());
    }

    for (Chromosome chr : snpEffectPredictor.getGenome()) markers.add(chr);

    // ---
    // Calculate raw counts
    // ---
    for (Marker m : markers) {
      String mtype = markerTypes.getType(m);
      String msubtype = markerTypes.getSubType(m);

      rawCountMarkers.inc(mtype);
      rawCountBases.inc(mtype, m.size());

      // Count sub-types (if any)
      if (msubtype != null) {
        rawCountMarkers.inc(msubtype);
        rawCountBases.inc(msubtype, m.size());
      }
    }

    // ---
    // Count number of bases for each marker type (overlap and join)
    // ---
    for (String mtype : rawCountMarkers.keysSorted()) {
      if (mtype.equals(Chromosome.class.getSimpleName()))
        continue; // We calculate chromosomes later (it's faster)

      if (verbose) System.err.print(mtype + ":");

      if (countMarkers.get(mtype) == 0) {
        for (Chromosome chr : snpEffectPredictor.getGenome()) countBases(mtype, chr, markers);
      }

      if (verbose) System.err.println("");
    }

    // Show chromosomes length
    String mtype = Chromosome.class.getSimpleName();
    for (Chromosome chr : snpEffectPredictor.getGenome()) {
      countBases.inc(mtype, chr.size());
      countMarkers.inc(mtype);
    }
  }