public void Simulation(
      Parameter1 p,
      ArrayList qtl,
      double[] env,
      double[][] w,
      double[][] m,
      ArrayList sm,
      boolean isSelectMarker) {
    Param1 = p;
    QTL = qtl;
    map = new double[m.length][];
    for (int i = 0; i < map.length; i++) {
      map[i] = new double[m[i].length];
      System.arraycopy(m[i], 0, map[i], 0, map[i].length);
    }
    weight = new double[w.length][];
    for (int i = 0; i < w.length; i++) {
      weight[i] = new double[w[i].length];
      System.arraycopy(w[i], 0, weight[i], 0, weight[i].length);
    }
    for (int i = 0; i < map.length; i++) {
      Num_interval += map[i].length == 1 ? map[i].length : map[i].length - 1;
    }
    if (sm != null) {
      selectedMarker = sm;
    } else {
      if (isSelectMarker) {
        selectMarker();
      }
    }
    correctLogBon();
    makeFullMap(QTL, map);
    setup(QTL, map, Param1);
    SimulationResults = new ArrayList();
    for (int i_rep = 0; i_rep < Param1.rep; i_rep++) {
      if (Param1.pt.compareTo("F2") == 0) {
        ap =
            new F2Population(
                Param1.populationSize,
                Param1.pheNum.length,
                Param1.pt,
                distance,
                Param1.seed + i_rep,
                Param1.mu,
                env,
                Param1.sd,
                QTL,
                Param1.mf);
      } else if (Param1.pt.compareTo("DH") == 0) {
        ap =
            new DHPopulation(
                Param1.populationSize,
                Param1.pheNum.length,
                Param1.pt,
                distance,
                Param1.seed + i_rep,
                Param1.mu,
                env,
                Param1.sd,
                QTL,
                Param1.mf);
      } else {
        ap =
            new BackCrossPopulation(
                Param1.populationSize,
                Param1.pheNum.length,
                Param1.pt,
                distance,
                Param1.seed + i_rep,
                Param1.mu,
                env,
                Param1.sd,
                QTL,
                Param1.mf);
      }
      ap.ProducePopulation();

      for (int i = 0; i < Param1.pheNum.length; i++) {
        ap.ProducePhenotype(i, Param1.MU, Param1.T);
      }
      PrintStream cim = null;
      try {
        cim = new PrintStream(new BufferedOutputStream(new FileOutputStream("CIM.mcd")));
      } catch (Exception e) {

      }
      ap.CIMFormat(cim);
      cim.close();
      gs = new GenomeScan(ap, Param1.step);
      gs.CalculateIPP();

      if (Param1.permutation > 0 && i_rep == 0) {
        PrintStream PoutPW = null;
        PrintStream PoutPL = null;
        PrintStream PoutW = null;
        PrintStream PoutL = null;
        try {
          PoutW = new PrintStream(new BufferedOutputStream(new FileOutputStream("PermuWald.txt")));
          PoutL = new PrintStream(new BufferedOutputStream(new FileOutputStream("PermuLN.txt")));
          PoutPW =
              new PrintStream(new BufferedOutputStream(new FileOutputStream("PermuWaldP.txt")));
          PoutPL = new PrintStream(new BufferedOutputStream(new FileOutputStream("PermuLNP.txt")));
        } catch (Exception E) {
          E.printStackTrace(System.err);
        }

        thresholdLOD = new ArrayList();
        thresholdAP = new ArrayList();
        thresholdDP = new ArrayList();
        thresholdPwald = new ArrayList();
        thresholdPF = new ArrayList();
        for (int i_permu = 0; i_permu < Param1.permutation; i_permu++) {
          ArrayList IMStatistic = MappingProcedure(i_rep, i_permu + 1);
          ArrayList IMLOD = new ArrayList();
          ArrayList IMAT = new ArrayList();
          ArrayList IMDT = new ArrayList();
          ArrayList IMAP = new ArrayList();
          ArrayList IMDP = new ArrayList();
          ArrayList IMPWald = new ArrayList();
          ArrayList IMPF = new ArrayList();
          int c = 0;
          int ct = 0;
          int bt = 0;

          for (int j = 0; j < IMStatistic.size(); j++) {
            PointMappingStatistic pms = (PointMappingStatistic) IMStatistic.get(j);
            PoutPW.print(pms.get_P_wald() + " ");
            PoutPL.print(pms.get_P_LN() + " ");
            PoutW.print(pms.get_wald() + " ");
            PoutL.print(pms.get_LN() + " ");
            IMLOD.add(new Double(pms.get_LOD()));
            IMAT.add(new Double(pms.get_tStatistic_additive()));
            IMDT.add(new Double(pms.get_tStatistic_dominance()));
            IMAP.add(new Double(pms.get_logP_additive()));
            IMPWald.add(new Double(pms.get_logP_wald()));
            IMPF.add(new Double(pms.get_logP_F()));
            if (pms.get_logP_additive() > LogBon) {
              c++;
            }
            if (pms.get_P_additive() < BonT) {
              bt++;
            }
            if (weight.length > 1) {
              IMDP.add(new Double(pms.get_logP_dominance()));
            }
          }
          PoutPW.println();
          PoutPL.println();
          PoutW.println();
          PoutL.println();
          if (c > 0) {
            typeI_LogBon += 1;
          }
          thresholdLOD.add(Collections.max(IMLOD));
          thresholdAP.add(Collections.max(IMAP));
          if (weight.length > 1) {
            thresholdDP.add(Collections.max(IMDP));
          }
          thresholdPF.add(Collections.max(IMPF));
          thresholdPwald.add(Collections.max(IMPWald));
        }
        PoutPW.close();
        PoutPL.close();
        PoutW.close();
        PoutL.close();
      }
      ArrayList IMLOD = MappingProcedure(i_rep, 0);
      SimulationResults.add(IMLOD);
    }
  }
 public int[][] ChrInt(int[] SNPIdx) {
   int[][] chrint = new int[SNPIdx.length][2];
   int c = 0;
   int idx = 0;
   for (int i = 0; i < ap.ChromosomeNumber(); i++) {
     for (int j = 0; j < ap.IntervalNumberAtChromosome(i); j++) {
       if (c == SNPIdx[idx]) {
         chrint[idx][0] = i;
         chrint[idx][1] = j;
         idx++;
         if (idx == SNPIdx.length) {
           break;
         }
       }
       c++;
     }
     if (idx == SNPIdx.length) {
       break;
     }
   }
   return chrint;
 }