/**
   * @throws InvalidColumnIndexException
   * @throws IOException
   */
  public void executeLimma() {

    Limma limma = null;
    if (classValues.size() > 2) {
      limma = new Limma(babelomicsHomePath + "/bin/diffexp/limma_multiclasses.r");
    } else if (classValues.size() == 2) {
      limma = new Limma(babelomicsHomePath + "/bin/diffexp/limma_twoclasses.r");
    } else if (classValues.size() == 1) {
      limma = new Limma(babelomicsHomePath + "/bin/diffexp/limma_oneclass.r");
    } else {
      abort(
          "testmismatched_executelimma_classcomparison",
          "test " + test + " not supported for " + classValues.size() + "-class test",
          "test " + test + " not supported for " + classValues.size() + "-class test",
          "test " + test + " not supported for " + classValues.size() + "-class test");
    }

    // System.out.println("dataset = " + dataset.toString());
    System.out.println("class name = " + className);

    limma.setInputFilename(dataset.getDatasetFile().getAbsolutePath());
    limma.setClasses(dataset.getVariables().getByName(className).getValues());
    limma.setContrast(classValues);

    try {
      Dataset subDataset = dataset.getSubDataset(className, classValues);

      // apply test and multiple test correction according
      //
      TestResultList<LimmaTestResult> res = limma.compute();
      DiffExpressionUtils.multipleTestCorrection(res, correction);

      // create output file
      //
      int[] columnOrder =
          ListUtils.order(subDataset.getVariables().getByName(className).getValues());
      int[] rowOrder = ListUtils.order(ArrayUtils.toList(res.getStatistics()), true);

      DataFrame dataFrame = new DataFrame(subDataset.getFeatureNames().size(), 0);
      dataFrame.addColumn(
          "statistic",
          ListUtils.toStringList(
              ListUtils.ordered(ArrayUtils.toList(res.getStatistics()), rowOrder)));
      dataFrame.addColumn(
          "p-value",
          ListUtils.toStringList(ListUtils.ordered(ArrayUtils.toList(res.getPValues()), rowOrder)));
      dataFrame.addColumn(
          "adj. p-value",
          ListUtils.toStringList(
              ListUtils.ordered(ArrayUtils.toList(res.getAdjPValues()), rowOrder)));
      dataFrame.setRowNames(ListUtils.ordered(subDataset.getFeatureNames(), rowOrder));

      FeatureData featureData = new FeatureData(dataFrame);
      File file = new File(outdir + "/" + test + ".txt");
      featureData.save(file);
      if (file.exists()) {
        result.addOutputItem(
            new Item(
                test + "file",
                file.getName(),
                "Limma output file",
                TYPE.FILE,
                new ArrayList<String>(2),
                new HashMap<String, String>(2),
                "Limma output files"));
      }

      // getting significative genes
      //
      DiffExpressionUtils.addSignificativeResults(
          subDataset,
          test,
          "statistic",
          res.getStatistics(),
          "adj. p-value",
          res.getAdjPValues(),
          "p-value",
          res.getPValues(),
          null,
          null,
          null,
          null,
          className,
          columnOrder,
          pValue,
          maxDisplay,
          this);
      DiffExpressionUtils.createFatiScanRedirection(dataFrame, test, "statistic", result, outdir);
    } catch (Exception e) {
      e.printStackTrace();
      abort(
          "exception_executelimma_classcomparison",
          "error running limma",
          "error running limma: " + e.toString(),
          "error running limma: " + e.toString());
    }
  }
  @Override
  public void execute() {

    List<String> values = null;

    // init
    //
    test = commandLine.getOptionValue("test", null);
    className = commandLine.getOptionValue("class-name", null);
    values =
        (commandLine.hasOption("class-values")
            ? StringUtils.toList(commandLine.getOptionValue("class-values", null), ",")
            : null);
    correction = commandLine.getOptionValue("correction", "fdr");
    String pValueParam = commandLine.getOptionValue("p-value", "0.05");
    String foldChangeValueParam = commandLine.getOptionValue("fold-change-value", "2");
    String datasetParam = commandLine.getOptionValue("dataset");

    if (className != null) {
      if (values == null) {
        values = ListUtils.unique(dataset.getVariables().getByName(className).getValues());
      } else {
        values = ListUtils.unique(values);
      }

      classValues = new ArrayList<String>();
      for (String val : values) {
        if (val != null && val.trim().length() > 0) {
          classValues.add(val.trim());
        }
      }
    }

    if ("fold-change".equalsIgnoreCase(test) || "fold_change".equalsIgnoreCase(test)) {
      try {
        foldChangeValue = Double.parseDouble(foldChangeValueParam);
      } catch (NumberFormatException e) {
        foldChangeValue = 0.05;
      }
    } else {
      try {
        pValue = Double.parseDouble(pValueParam);
        if (pValue > 1 || pValue < 0) {
          pValue = 0.05;
        }
      } catch (NumberFormatException e) {
        pValue = 0.05;
      }
    }

    // input parameters
    //
    result.addOutputItem(
        new Item(
            "dataset_input_param",
            (datasetParam == null ? "" : new File(datasetParam).getName()),
            "Dataset file name",
            Item.TYPE.MESSAGE,
            Arrays.asList("INPUT_PARAM"),
            new HashMap<String, String>(),
            "Input parameters"));
    result.addOutputItem(
        new Item(
            "test_input_param",
            test,
            "Test",
            Item.TYPE.MESSAGE,
            Arrays.asList("INPUT_PARAM"),
            new HashMap<String, String>(),
            "Input parameters"));
    result.addOutputItem(
        new Item(
            "class_input_param",
            (className == null ? "" : className)
                + " ["
                + ListUtils.toString(classValues, ", ")
                + "]",
            "Class",
            Item.TYPE.MESSAGE,
            Arrays.asList("INPUT_PARAM"),
            new HashMap<String, String>(),
            "Input parameters"));
    if ("fold_change".equalsIgnoreCase(test) || "fold-change".equalsIgnoreCase(test)) {
      result.addOutputItem(
          new Item(
              "fold_change_value_input_param",
              foldChangeValueParam,
              "Fold-change value",
              Item.TYPE.MESSAGE,
              Arrays.asList("INPUT_PARAM"),
              new HashMap<String, String>(),
              "Input parameters"));
    } else {
      result.addOutputItem(
          new Item(
              "correction_input_param",
              correction,
              "Multiple-test correction",
              Item.TYPE.MESSAGE,
              Arrays.asList("INPUT_PARAM"),
              new HashMap<String, String>(),
              "Input parameters"));
      result.addOutputItem(
          new Item(
              "pvalue_input_param",
              pValueParam,
              "Adjusted p-value",
              Item.TYPE.MESSAGE,
              Arrays.asList("INPUT_PARAM"),
              new HashMap<String, String>(),
              "Input parameters"));
    }

    // check input parameters
    //
    if (datasetParam == null) {
      abort(
          "missingdataset_execute_classcomparison",
          "Missing dataset",
          "Missing dataset",
          "Missing dataset");
    }

    if (className == null) {
      abort(
          "classnamemissing_execute_classcomparison",
          "class name missing",
          "class name missing",
          "class name missing");
    }

    if (classValues == null) {
      abort(
          "classvaluesmissing_execute_classcomparison",
          "class values missing",
          "class values missing",
          "class values missing");
    }

    if (test == null) {
      abort(
          "testmissing_execute_classcomparison",
          "class comparison test missing",
          "class comparison test missing",
          "class comparison test missing");
    }

    // reading dataset
    //
    File datasetFile = new File(datasetParam);
    try {
      dataset = new Dataset(datasetFile);
      if (!dataset.load() && !dataset.validate()) {
        abort(
            "exception_execute_classcomparison",
            "Error",
            "Error loading dataset "
                + datasetFile.getName()
                + ": "
                + dataset.getMessages().getErrorString(""),
            "");
      }
    } catch (Exception e) {
      abort(
          "exception_execute_clustering",
          "Error",
          "Error reading dataset " + datasetFile.getName(),
          "");
    }

    // executing test
    //
    updateJobStatus("40", "computing " + test);
    if ("limma".equalsIgnoreCase(test)) {
      executeLimma();
    } else if ("t".equalsIgnoreCase(test)) {
      if (classValues.size() == 2) {
        executeT();
      } else {
        abort(
            "testmismatched_execute_classcomparison",
            "test " + test + " not supported for " + classValues.size() + "-class test",
            "test " + test + " not supported for " + classValues.size() + "-class test",
            "test " + test + " not supported for " + classValues.size() + "-class test");
      }
    } else if ("fold_change".equalsIgnoreCase(test) || "fold-change".equalsIgnoreCase(test)) {

      if (classValues.size() == 2) {
        executeFoldChange();
      } else {
        abort(
            "testmismatched_execute_classcomparison",
            "test " + test + " not supported for " + classValues.size() + "-class test",
            "test " + test + " not supported for " + classValues.size() + "-class test",
            "test " + test + " not supported for " + classValues.size() + "-class test");
      }
    } else if ("anova".equalsIgnoreCase(test)) {
      if (classValues.size() > 2) {
        executeAnova();
      } else {
        abort(
            "testmismatched_execute_classcomparison",
            "test " + test + " not supported for " + classValues.size() + "-class test",
            "test " + test + " not supported for " + classValues.size() + "-class test",
            "test " + test + " not supported for " + classValues.size() + "-class test");
      }
    } else {
      abort(
          "testunknown_execute_classcomparison",
          "unknown test " + test,
          "unknown test " + test,
          "unknown test " + test);
    }
  }
  public void executeAnova() {

    DoubleMatrix matrix = null;
    List<String> vars = new ArrayList<String>();
    List<Integer> indices = new ArrayList<Integer>();
    List<String> values = dataset.getVariables().getByName(className).getValues();

    if (values.size() == classValues.size()) {
      matrix = dataset.getDoubleMatrix();
      vars = values;
    } else {
      for (int i = 0; i < values.size(); i++) {
        if (classValues.contains(values.get(i))) {
          indices.add(i);
          vars.add(values.get(i));
        }
      }
      matrix = dataset.getSubMatrixByColumns(ListUtils.toIntArray(indices));
    }

    try {
      Dataset subDataset = dataset.getSubDataset(className, classValues);

      // apply test and multiple test correction according
      //
      AnovaTest anova = new AnovaTest(matrix, vars);
      TestResultList<AnovaTestResult> res = anova.compute();
      DiffExpressionUtils.multipleTestCorrection(res, correction);

      // create output file
      //
      int[] columnOrder =
          ListUtils.order(subDataset.getVariables().getByName(className).getValues());
      int[] rowOrder = ListUtils.order(ArrayUtils.toList(res.getStatistics()), true);

      DataFrame dataFrame = new DataFrame(subDataset.getFeatureNames().size(), 0);
      dataFrame.addColumn(
          "statistic",
          ListUtils.toStringList(
              ListUtils.ordered(ArrayUtils.toList(res.getStatistics()), rowOrder)));
      dataFrame.addColumn(
          "p-value",
          ListUtils.toStringList(ListUtils.ordered(ArrayUtils.toList(res.getPValues()), rowOrder)));
      dataFrame.addColumn(
          "adj. p-value",
          ListUtils.toStringList(
              ListUtils.ordered(ArrayUtils.toList(res.getAdjPValues()), rowOrder)));
      dataFrame.setRowNames(ListUtils.ordered(subDataset.getFeatureNames(), rowOrder));

      FeatureData featureData = new FeatureData(dataFrame);
      File file = new File(outdir + "/" + test + ".txt");
      featureData.save(file);
      if (file.exists()) {
        result.addOutputItem(
            new Item(
                test + "file",
                file.getName(),
                "Anova output file",
                TYPE.FILE,
                new ArrayList<String>(2),
                new HashMap<String, String>(2),
                "Anova output files"));
      }

      // getting significative genes
      //
      DiffExpressionUtils.addSignificativeResults(
          subDataset,
          test,
          "statistic",
          res.getStatistics(),
          "adj. p-value",
          res.getAdjPValues(),
          "p-value",
          res.getPValues(),
          null,
          null,
          null,
          null,
          className,
          columnOrder,
          pValue,
          maxDisplay,
          this);
      DiffExpressionUtils.createFatiScanRedirection(dataFrame, test, "statistic", result, outdir);
    } catch (Exception e) {
      e.printStackTrace();
      abort(
          "exception_executeanova_classcomparison",
          "error running anova",
          "error running anova: " + e.getMessage(),
          "error running anova: " + e.getMessage());
    }
  }
  public void executeT() {

    int[] cols = dataset.getColumnIndexesByVariableValue(className, classValues.get(0));
    DoubleMatrix sample1 = dataset.getSubMatrixByColumns(cols);

    cols = dataset.getColumnIndexesByVariableValue(className, classValues.get(1));
    DoubleMatrix sample2 = dataset.getSubMatrixByColumns(cols);

    try {
      Dataset subDataset = dataset.getSubDataset(className, classValues);

      // apply test and multiple test correction according
      //
      TTest tTest = new TTest();
      TestResultList<TTestResult> res = tTest.tTest(sample1, sample2);
      DiffExpressionUtils.multipleTestCorrection(res, correction);

      // create output file
      //
      int[] columnOrder =
          ListUtils.order(subDataset.getVariables().getByName(className).getValues());
      int[] rowOrder = ListUtils.order(ArrayUtils.toList(res.getStatistics()), true);

      DataFrame dataFrame = new DataFrame(subDataset.getFeatureNames().size(), 0);
      dataFrame.addColumn(
          "statistic",
          ListUtils.toStringList(
              ListUtils.ordered(ArrayUtils.toList(res.getStatistics()), rowOrder)));
      dataFrame.addColumn(
          "p-value",
          ListUtils.toStringList(ListUtils.ordered(ArrayUtils.toList(res.getPValues()), rowOrder)));
      dataFrame.addColumn(
          "adj. p-value",
          ListUtils.toStringList(
              ListUtils.ordered(ArrayUtils.toList(res.getAdjPValues()), rowOrder)));
      dataFrame.setRowNames(ListUtils.ordered(subDataset.getFeatureNames(), rowOrder));

      FeatureData featureData = new FeatureData(dataFrame);
      File file = new File(outdir + "/t.txt");
      featureData.save(file);
      if (file.exists()) {
        result.addOutputItem(
            new Item(
                "tfile",
                file.getName(),
                "T-test output file",
                TYPE.FILE,
                new ArrayList<String>(),
                new HashMap<String, String>(),
                "T-test output files"));
      }

      // getting significative genes
      //
      DiffExpressionUtils.addSignificativeResults(
          subDataset,
          test,
          "statistic",
          res.getStatistics(),
          "adj. p-value",
          res.getAdjPValues(),
          "p-value",
          res.getPValues(),
          null,
          null,
          null,
          null,
          className,
          columnOrder,
          pValue,
          maxDisplay,
          this);
      DiffExpressionUtils.createFatiScanRedirection(dataFrame, test, "statistic", result, outdir);
    } catch (Exception e) {
      e.printStackTrace();
      abort("exception_executet_classcomparison", "ERROR", "Error running t-test", "");
    }
  }