CalculationThread(
      int i,
      LinkedBlockingQueue<WorkPackage> packageQueue,
      LinkedBlockingQueue<WorkPackage> resultQueue,
      TriTyperExpressionData[] expressiondata,
      DoubleMatrixDataset<String, String>[] covariates,
      IntMatrix2D probeTranslationTable,
      int[][] expressionToGenotypeIds,
      Settings settings,
      EQTLPlotter plotter,
      boolean binaryoutput,
      boolean useAbsoluteZScores,
      boolean testSNPsPresentInBothDatasets) {
    //        m_binaryoutput = binaryoutput;
    m_name = i;
    m_workpackage_queue = packageQueue;
    m_result_queue = resultQueue;
    m_probeTranslation = probeTranslationTable;
    m_expressiondata = expressiondata;
    boolean m_cis = settings.cisAnalysis;
    boolean m_trans = settings.transAnalysis;
    metaAnalyseInteractionTerms = settings.metaAnalyseInteractionTerms;
    metaAnalyseModelCorrelationYHat = settings.metaAnalyseModelCorrelationYHat;
    m_useAbsoluteZScores = useAbsoluteZScores;
    m_name = i;
    m_numProbes = m_probeTranslation.columns();
    m_numDatasets = m_probeTranslation.rows();
    m_expressionToGenotypeIds = expressionToGenotypeIds;

    //        probeVariance = new double[m_numDatasets][0];
    //        probeMean = new double[m_numDatasets][0];
    //        probeName = new String[m_numDatasets][0];
    //        for (int d = 0; d < m_numDatasets; d++) {
    //            probeVariance[d] = expressiondata[d].getProbeVariance();
    //            probeMean[d] = expressiondata[d].getProbeMean();
    //            probeName[d] = expressiondata[d].getProbes();
    //        }

    m_covariates = covariates;

    this.testSNPsPresentInBothDatasets = testSNPsPresentInBothDatasets;

    cisOnly = false;
    //        cisTrans = false;
    transOnly = false;

    determinebeta = settings.provideBetasAndStandardErrors;
    determinefoldchange = settings.provideFoldChangeData;

    if (m_cis && !m_trans) {
      cisOnly = true;
    } else if (!m_cis && m_trans) {
      transOnly = true;
    }
    //        else if (m_cis && m_trans) {
    //            cisTrans = true;
    //        }

    m_eQTLPlotter = plotter;
    m_pvaluePlotThreshold = settings.plotOutputPValueCutOff;

    //        if (covariates != null) {
    //            try {
    //                rConnection = new RConnection();
    //                REXP x = rConnection.eval("R.version.string");
    //                System.out.println("Thread made R Connection: " + x.asString());
    ////                rConnection.voidEval("install.packages('sandwich')");
    //                rConnection.voidEval("library(sandwich)");
    //            } catch (RserveException ex) {
    //                Logger.getLogger(CalculationThread.class.getName()).log(Level.SEVERE, null,
    // ex);
    //                rConnection = null;
    //            } catch (REXPMismatchException ex) {
    //                Logger.getLogger(CalculationThread.class.getName()).log(Level.SEVERE, null,
    // ex);
    //                rConnection = null;
    //            }
    //        }
  }
  private void analyze(WorkPackage wp) {
    testsPerformed = 0;
    currentWP = wp;
    wp.setNumTested(0);
    //        RunTimer t1 = new RunTimer();
    // load SNP genotypes
    SNP[] snps = wp.getSnps();
    int[] probes = wp.getProbes();
    Result dsResults = null;

    double[] snpvariances = new double[m_numDatasets];
    double[][] snpmeancorrectedgenotypes = new double[m_numDatasets][0];
    double[][] originalgenotypes = new double[m_numDatasets][0];
    boolean[][] includeExpressionSample = new boolean[m_numDatasets][0];

    for (int d = 0; d < m_numDatasets; d++) {
      SNP dSNP = snps[d];

      if (dSNP != null) {

        double[] x = dSNP.selectGenotypes(m_expressionToGenotypeIds[d], false, true);
        originalgenotypes[d] = dSNP.selectGenotypes(m_expressionToGenotypeIds[d], false, false);

        int xLen = x.length;
        double meanX = JSci.maths.ArrayMath.mean(x);

        snpmeancorrectedgenotypes[d] = new double[xLen];

        for (int i = 0; i < xLen; i++) {
          snpmeancorrectedgenotypes[d][i] = x[i] - meanX;
        }

        double varianceX = JSci.maths.ArrayMath.variance(x);
        if (varianceX != 0) {
          snpvariances[d] = varianceX;

          int inds[] = m_expressionToGenotypeIds[d];
          int sampleCount = m_expressionToGenotypeIds[d].length;
          includeExpressionSample[d] = new boolean[sampleCount];
          byte[] genotypes = dSNP.getGenotypes();
          for (int s = 0; s < sampleCount; s++) {
            int ind = inds[s];
            double valX = genotypes[ind]; // loadedSNPGenotype[ind];
            if (valX != -1) {
              includeExpressionSample[d][s] = true;
            } else {
              includeExpressionSample[d][s] = false;
            }
          }
        } else {
          dSNP.clearGenotypes();
          dSNP = null;
          wp.getFlipSNPAlleles()[d] = null;
          snps[d] = null;
        }
      }
    }

    if (cisOnly) {
      dsResults = new Result(m_numDatasets, wp.getProbes().length, wp.getId());
      for (int d = 0; d < m_numDatasets; d++) {
        SNP dSNP = snps[d];

        if (dSNP != null) {
          dsResults.numSamples[d] = snpmeancorrectedgenotypes[d].length;
          double[][] rawData = m_expressiondata[d].getMatrix();
          double[] varY = m_expressiondata[d].getProbeVariance();
          double[] meanY = m_expressiondata[d].getProbeMean();
          int samplecount = m_expressiondata[d].getIndividuals().length;

          double[][] covariates = null;
          if (m_covariates != null) {
            DoubleMatrixDataset<String, String> covariateData = m_covariates[d];
            covariates = covariateData.rawData;
          }

          for (int p = 0; p < probes.length; p++) {
            int pid = probes[p];
            Integer probeId = m_probeTranslation.get(d, pid);
            if (probeId != -9) {
              test(
                  d,
                  p,
                  probeId,
                  snpmeancorrectedgenotypes[d],
                  originalgenotypes[d],
                  snpvariances[d],
                  varY[probeId],
                  meanY[probeId],
                  includeExpressionSample[d],
                  samplecount,
                  rawData,
                  covariates,
                  dsResults,
                  this.currentWP,
                  this.metaAnalyseModelCorrelationYHat,
                  this.metaAnalyseInteractionTerms,
                  this.determinefoldchange);
            } else {
              dsResults.correlations[d][p] = Double.NaN;
              dsResults.zscores[d][p] = Double.NaN;
            }
          }

        } else {
          for (int p = 0; p < probes.length; p++) {
            dsResults.correlations[d][p] = Double.NaN;
            dsResults.zscores[d][p] = Double.NaN;
          }
        }
      }
    } else if (transOnly) {

      HashSet<Integer> probestoExclude = null;
      if (probes != null) {
        probestoExclude = new HashSet<Integer>();
        for (int p = 0; p < probes.length; p++) {
          probestoExclude.add(probes[p]);
        }
      }
      dsResults = new Result(m_numDatasets, m_numProbes, wp.getId());
      for (int d = 0; d < m_numDatasets; d++) {
        SNP dSNP = snps[d];
        dsResults.numSamples[d] = snpmeancorrectedgenotypes[d].length;
        double[][] rawData = m_expressiondata[d].getMatrix();
        double[] varY = m_expressiondata[d].getProbeVariance();
        double[] meanY = m_expressiondata[d].getProbeMean();
        int samplecount = m_expressiondata[d].getIndividuals().length;
        if (dSNP != null) {
          dsResults.numSamples[d] = snpmeancorrectedgenotypes[d].length;
          for (int pid = 0; pid < m_numProbes; pid++) {
            if (probestoExclude == null || !probestoExclude.contains(pid)) {
              Integer probeId = m_probeTranslation.get(d, pid);
              if (probeId != -9) {
                test(
                    d,
                    pid,
                    probeId,
                    snpmeancorrectedgenotypes[d],
                    originalgenotypes[d],
                    snpvariances[d],
                    varY[probeId],
                    meanY[probeId],
                    includeExpressionSample[d],
                    samplecount,
                    rawData,
                    null,
                    dsResults,
                    this.currentWP,
                    this.metaAnalyseModelCorrelationYHat,
                    this.metaAnalyseInteractionTerms,
                    this.determinefoldchange);
              } else {
                dsResults.correlations[d][pid] = Double.NaN;
                dsResults.zscores[d][pid] = Double.NaN;
              }
            } else {
              dsResults.correlations[d][pid] = Double.NaN;
              dsResults.zscores[d][pid] = Double.NaN;
            }
          }
        } else {
          for (int p = 0; p < m_numProbes; p++) {
            dsResults.correlations[d][p] = Double.NaN;
            dsResults.zscores[d][p] = Double.NaN;
          }
        }
      }
    } else {
      dsResults = new Result(m_numDatasets, m_numProbes, wp.getId());
      for (int d = 0; d < m_numDatasets; d++) {
        SNP dSNP = snps[d];
        dsResults.numSamples[d] = snpmeancorrectedgenotypes[d].length;
        double[][] rawData = m_expressiondata[d].getMatrix();
        double[] varY = m_expressiondata[d].getProbeVariance();
        double[] meanY = m_expressiondata[d].getProbeMean();
        int samplecount = m_expressiondata[d].getIndividuals().length;
        if (dSNP != null) {
          dsResults.numSamples[d] = snpmeancorrectedgenotypes[d].length;
          //                    RunTimer t2 = new RunTimer();
          for (int pid = 0; pid < m_numProbes; pid++) {
            Integer probeId = m_probeTranslation.get(d, pid);
            if (probeId != -9) {
              test(
                  d,
                  pid,
                  probeId,
                  snpmeancorrectedgenotypes[d],
                  originalgenotypes[d],
                  snpvariances[d],
                  varY[probeId],
                  meanY[probeId],
                  includeExpressionSample[d],
                  samplecount,
                  rawData,
                  null,
                  dsResults,
                  this.currentWP,
                  this.metaAnalyseModelCorrelationYHat,
                  this.metaAnalyseInteractionTerms,
                  this.determinefoldchange);
            } else {
              dsResults.correlations[d][pid] = Double.NaN;
              dsResults.zscores[d][pid] = Double.NaN;
            }
          }
          //                    System.out.println("Test: "+t2.getTimeDesc());
        } else {
          for (int p = 0; p < m_numProbes; p++) {
            dsResults.correlations[d][p] = Double.NaN;
            dsResults.zscores[d][p] = Double.NaN;
          }
        }
      }
    }

    convertResultsToPValues(wp, dsResults);

    if (m_eQTLPlotter != null) {
      for (int p = 0; p < dsResults.pvalues.length; p++) {
        double pval = dsResults.pvalues[p];
        if (!Double.isNaN(pval)) {
          if (pval < m_pvaluePlotThreshold) {
            ploteQTL(wp, p);
          }
        }
      }
    }

    snps = wp.getSnps();
    if (snps != null) {
      for (SNP snp : snps) {
        if (snp != null) {
          snp.clearGenotypes();
        }
      }
    }

    // if result output is binary, convert to bytes and deflate the set of bytes.
    //        if (m_binaryoutput) {
    //            deflateResults(wp);
    //        }
    // now push the results in the queue..
    try {
      wp.setNumTested(testsPerformed);
      m_result_queue.put(wp);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

    //        System.out.println("Analyze: "+t1.getTimeDesc());
  }