public String getOutputRecord(int tagIndex, double[][] theResults) {
   int GNum = 0;
   for (int i = 0; i < theResults.length; i++) {
     if (theResults[i] != null) GNum++;
   }
   StringBuilder sb = new StringBuilder();
   sb.append(BaseEncoder.getSequenceFromLong(tbt.getTag(tagIndex))).append("\t");
   sb.append(String.valueOf(tbt.getNumberOfTaxaWithTag(tagIndex))).append("\t");
   sb.append(String.valueOf(GNum)).append("\t");
   // chr, bestSite, refAlignment.getPositionInLocus(bestSite), bestP, countSig, (double)-1,
   // bestNewTestFamilies.length, (double)this.getFamilyCode(bestNewTestFamilies)}
   for (int i = 0; i < theResults.length; i++) {
     if (theResults[i] == null) continue;
     sb.append(String.valueOf((int) theResults[i][0])).append("\t");
     sb.append(String.valueOf((int) theResults[i][1])).append("\t");
     sb.append(String.valueOf((int) theResults[i][2])).append("\t");
     sb.append(String.valueOf(theResults[i][3])).append("\t");
     sb.append(String.valueOf((int) theResults[i][4])).append("\t");
     sb.append(String.valueOf(theResults[i][5])).append("\t");
     sb.append(String.valueOf((int) theResults[i][6])).append("\t");
     sb.append(String.valueOf((long) theResults[i][7])).append("\t");
   }
   sb.append("\n");
   return sb.toString();
 }
 private long[] getTagsInBits(TagsByTaxaByte aTBT, int tagIndex, int[] reDirect, int anchorTaxa) {
   int lgPerSite = (anchorTaxa / 64) + 1;
   long[] seq = new long[lgPerSite];
   for (int j = 0; j < aTBT.getTaxaCount(); j++) {
     if (reDirect[j] < 0) continue;
     int index = reDirect[j] / 64;
     int offset = reDirect[j] % 64;
     if (aTBT.getReadCountForTagTaxon(tagIndex, j) > 0) { // reference alleles
       seq[index] = seq[index] | (1L << offset);
     }
   }
   return seq;
 }
    public void run() {
      long starttime = System.currentTimeMillis();
      ArrayList<String> resultList = new ArrayList();
      for (int i = 0; i < tbt.getTagCount(); i++) {
        int[] minPresentFamilies = getMinPresentFamily(i, (float) 0.08);
        if (minPresentFamilies == null) continue;

        ArrayList segregationList =
            this.getSegregationFamilyGroups(i, minPresentFamilies, 10, pThresh);
        if (segregationList == null) continue;
        int[][] segregationFamilyGroups = (int[][]) segregationList.get(0);
        int[] bestChrs = (int[]) segregationList.get(1);
        int minGnum = segregationFamilyGroups.length;
        if (familyGroupNum < minGnum) minGnum = familyGroupNum;
        double[][] theResults = new double[minGnum][];
        boolean nullFlag = true;
        for (int j = 0;
            j < minGnum;
            j++) { // it should be bestChrs.length, only caculate 2 loci for now
          ScanChromosome scanOnBestChrom =
              new ScanChromosome(
                  tbt,
                  i,
                  theAnchorChrInBits[bestChrs[j] - 1],
                  segregationFamilyGroups[j],
                  j,
                  theResults,
                  0.00001,
                  1);
          scanOnBestChrom.scan();
          if (theResults[j] == null) continue;
          nullFlag = false;
        }
        if (nullFlag) continue;
        resultList.add(this.getOutputRecord(i, theResults));
      }
      result = resultList.toArray(new String[resultList.size()]);
      double secs = (double) (System.currentTimeMillis() - starttime) * 0.001;
      System.out.println(
          "Task "
              + taskID
              + " with "
              + tbt.getTagCount()
              + " tags is finished in "
              + secs
              + " seconds");
    }
 public long[] getTagDistInBits(int[] newTestFamilies) {
   int lgPerSite = (refAlignment.getSequenceCount() / 64) + 1;
   long[] seq = new long[lgPerSite];
   for (int i = 0; i < newTestFamilies.length; i++) {
     for (int j = 0; j < family2TBTIndex[newTestFamilies[i]].length; j++) {
       int index =
           tbt2anchorRedirect[newTestFamilies[i]][family2TBTIndex[newTestFamilies[i]][j]] / 64;
       int offset =
           tbt2anchorRedirect[newTestFamilies[i]][family2TBTIndex[newTestFamilies[i]][j]] % 64;
       if (tbt.getReadCountForTagTaxon(tagIndex, family2TBTIndex[newTestFamilies[i]][j])
           > 0) { // reference alleles
         seq[index] = seq[index] | (1L << offset);
       }
     }
   }
   return seq;
 }
 private int[] getMinPresentFamily(int tagIndex, float minPresentInFamily) {
   ArrayList<Integer> overMinPresentFamilyList = new ArrayList();
   for (int i = 0; i < family2TBTIndex.length; i++) {
     int cnt = 0;
     for (int j = 0; j < family2TBTIndex[i].length; j++) {
       if (tbt.getReadCountForTagTaxon(tagIndex, family2TBTIndex[i][j]) != 0) cnt++;
     }
     float rate = (float) cnt / family2TBTIndex[i].length;
     if (rate > minPresentInFamily) overMinPresentFamilyList.add(i);
   }
   if (overMinPresentFamilyList.isEmpty()) return null;
   int[] overMinPresentFamily = new int[overMinPresentFamilyList.size()];
   for (int i = 0; i < overMinPresentFamily.length; i++) {
     overMinPresentFamily[i] = overMinPresentFamilyList.get(i);
   }
   return overMinPresentFamily;
 }
 public void run() {
   long starttime = System.currentTimeMillis();
   ArrayList<String> resultList = new ArrayList();
   for (int i = 0; i < tbt.getTagCount(); i++) {
     if (tbt.getNumberOfTaxaWithTag(i) < 30) continue;
     double[] bestR = {-1, -1, -1, 1, -1};
     int blastChr = -1, blastPos = -1, bestAlignment = -1, refDiv = -1;
     long[] testTag = tbt.getTag(i);
     long[] testTagDist;
     double[][] theResults = new double[theAnchorChrInBits.length][];
     ScanChromosomeMTR[] scanOnChr = new ScanChromosomeMTR[theAnchorChrInBits.length];
     for (int cn = 0; cn < theAnchorChrInBits.length; cn++) {
       testTagDist =
           getTagsInBits(
               tbt, i, tbt2anchRedirect[cn], theAnchorChrInBits[cn].getSequenceCount());
       scanOnChr[cn] =
           new ScanChromosomeMTR(
               theAnchorChrInBits[cn], testTagDist, cn, theResults, 0.000001, 1, blastPos);
       scanOnChr[cn].scan();
     }
     int countRealSig = 0;
     double[] pRank = new double[theAnchorChrInBits.length];
     for (int cn = 0; cn < theAnchorChrInBits.length; cn++) {
       double[] r = theResults[cn];
       pRank[cn] = r[3];
       if (r[3] < bestR[3]) {
         bestR = r.clone();
         bestAlignment = cn;
       }
       if (r[3] < 0.000001) countRealSig++;
     }
     Arrays.sort(pRank);
     double[][] bestResWithNewThreshold = new double[1][];
     testTagDist =
         getTagsInBits(
             tbt,
             i,
             tbt2anchRedirect[bestAlignment],
             theAnchorChrInBits[bestAlignment].getSequenceCount());
     ScanChromosomeMTR bestChrNewThres =
         new ScanChromosomeMTR(
             theAnchorChrInBits[bestAlignment],
             testTagDist,
             0,
             bestResWithNewThreshold,
             pRank[1],
             1,
             blastPos);
     bestChrNewThres.scan();
     int countOfSitesBetterThanNextBestChr = (int) bestResWithNewThreshold[0][4];
     String s =
         String.format(
             "%s %d %d %d %d %d %d %d %g %d %d %d %g %g %d %d %d %n",
             BaseEncoder.getSequenceFromLong(testTag),
             i,
             blastChr,
             blastPos,
             refDiv,
             (int) bestR[0],
             (int) bestR[1],
             (int) bestR[2],
             bestR[3],
             (int) bestR[4],
             tbt.getNumberOfTaxaWithTag(i),
             countRealSig,
             Math.log10(pRank[1] / pRank[0]),
             Math.log10(pRank[theAnchorChrInBits.length / 2] / pRank[0]),
             countOfSitesBetterThanNextBestChr,
             bestChrNewThres.minSigPos,
             bestChrNewThres.maxSigPos);
     resultList.add(s);
   }
   result = resultList.toArray(new String[resultList.size()]);
   double secs = (double) (System.currentTimeMillis() - starttime) * 0.001;
   System.out.println(
       "Task "
           + taskID
           + " with "
           + tbt.getTagCount()
           + " tags is finished in "
           + secs
           + " seconds");
 }