Program: 149549
Project: 149549
Buggy source:
private void summariseResults(HashMap<Integer,FilterCandidates> filterCandidates){
  createTable();
  StoredDataStatistics distanceStats=new StoredDataStatistics();
  StoredDataStatistics depthStats=new StoredDataStatistics();
  createFilterCriteria();
  StoredDataStatistics[][] stats=new StoredDataStatistics[3][filterCriteria.length];
  for (int i=0; i < stats.length; i++)   for (int j=0; j < stats[i].length; j++)   stats[i][j]=new StoredDataStatistics();
  final double nmPerPixel=simulationParameters.a;
  final boolean mle=fitConfig.getFitSolver() == FitSolver.MLE;
  double tp=0, fp=0;
  int failcTP=0, failcFP=0;
  int cTP=0, cFP=0;
  int[] status=null, status2=null;
  status=new int[FitStatus.values().length];
  status2=new int[status.length];
  for (  FilterCandidates result : filterCandidates.values()) {
    tp+=result.tp;
    fp+=result.fp;
    for (int i=0; i < result.fitResult.length; i++) {
      if (result.spots[i].match)       cTP++;
 else       cFP++;
      final FitResult fitResult=result.fitResult[i];
      if (fitResult.getStatus() != FitStatus.OK) {
        if (status != null) {
          status[result.fitResult[i].getStatus().ordinal()]++;
          status2[result.fitResultWithNeighbours[i].getStatus().ordinal()]++;
        }
        if (result.spots[i].match)         failcTP++;
 else         failcFP++;
        stats[0][FILTER_ITERATIONS].add(fitResult.getIterations());
        stats[0][FILTER_EVALUATIONS].add(fitResult.getEvaluations());
      }
 else {
        final double[] p=fitResult.getParameters();
        final double[] initialParams=fitResult.getInitialParameters();
        final double s0=(p[Gaussian2DFunction.X_SD] + p[Gaussian2DFunction.Y_SD]) * 0.5;
        final double s=s0 * nmPerPixel;
        final double N=p[Gaussian2DFunction.SIGNAL] / simulationParameters.gain;
        final double b2=Math.max(0,(p[Gaussian2DFunction.BACKGROUND] - simulationParameters.bias) / simulationParameters.gain);
        double precision;
        if (mle)         precision=PeakResult.getMLPrecisionX(nmPerPixel,s,N,b2,simulationParameters.emCCD);
 else         precision=PeakResult.getPrecisionX(nmPerPixel,s,N,b2,simulationParameters.emCCD);
        final double signal=p[Gaussian2DFunction.SIGNAL] / simulationParameters.gain;
        final double snr=p[Gaussian2DFunction.SIGNAL] / result.noise;
        final double width=s0 / fitConfig.getInitialPeakStdDev0();
        final double xShift=p[Gaussian2DFunction.X_POSITION] - initialParams[Gaussian2DFunction.X_POSITION];
        final double yShift=p[Gaussian2DFunction.Y_POSITION] - initialParams[Gaussian2DFunction.Y_POSITION];
        double shift=((Math.abs(xShift) > Math.abs(yShift)) ? xShift : yShift) / fitConfig.getInitialPeakStdDev0();
        shift=Math.abs(shift);
        final double eshift=Math.sqrt(xShift * xShift + yShift * yShift);
        stats[0][FILTER_SIGNAL].add(signal);
        stats[0][FILTER_SNR].add(snr);
        if (width < 1)         stats[0][FILTER_MIN_WIDTH].add(width);
 else         stats[0][FILTER_MAX_WIDTH].add(width);
        stats[0][FILTER_SHIFT].add(shift);
        stats[0][FILTER_ESHIFT].add(eshift);
        stats[0][FILTER_PRECISION].add(precision);
        stats[0][FILTER_ITERATIONS].add(fitResult.getIterations());
        stats[0][FILTER_EVALUATIONS].add(fitResult.getEvaluations());
        final int index=(result.fitMatch[i]) ? 1 : 2;
        stats[index][FILTER_SIGNAL].add(signal);
        stats[index][FILTER_SNR].add(snr);
        if (width < 1)         stats[index][FILTER_MIN_WIDTH].add(width);
 else         stats[index][FILTER_MAX_WIDTH].add(width);
        stats[index][FILTER_SHIFT].add(shift);
        stats[index][FILTER_ESHIFT].add(eshift);
        stats[index][FILTER_PRECISION].add(precision);
        stats[index][FILTER_ITERATIONS].add(fitResult.getIterations());
        stats[index][FILTER_EVALUATIONS].add(fitResult.getEvaluations());
      }
    }
    for (int i=0; i < result.match.length; i++) {
      if (!result.match[i].isFitResult())       continue;
      FitMatch fitMatch=(FitMatch)result.match[i];
      distanceStats.add(fitMatch.d * nmPerPixel);
      depthStats.add(fitMatch.z * nmPerPixel);
    }
  }
  double[] i1=new double[depthStats.getN()];
  double[] i2=new double[i1.length];
  double[] is=new double[i1.length];
  int ci=0;
  for (  FilterCandidates result : filterCandidates.values()) {
    for (int i=0; i < result.match.length; i++) {
      if (!result.match[i].isFitResult())       continue;
      FitMatch fitMatch=(FitMatch)result.match[i];
      ScoredSpot spot=result.spots[i];
      i1[ci]=fitMatch.predictedSignal;
      i2[ci]=fitMatch.actualSignal;
      is[ci]=spot.intensity;
      ci++;
    }
  }
  if (status != null) {
    String name=PeakFit.getSolverName(fitConfig);
    if (fitConfig.getFitSolver() == FitSolver.MLE && fitConfig.isModelCamera())     name+="String_Node_Str";
    System.out.println("String_Node_Str" + name);
    for (int i=0; i < status.length; i++) {
      if (status[i] != 0)       System.out.printf("String_Node_Str",FitStatus.values()[i].toString(),status[i]);
    }
    for (int i=0; i < status2.length; i++) {
      if (status2[i] != 0)       System.out.printf("String_Node_Str",FitStatus.values()[i].toString(),status2[i]);
    }
  }
  StringBuilder sb=new StringBuilder();
  final double signal=simulationParameters.signalPerFrame;
  final int n=results.size();
  sb.append(imp.getStackSize()).append("String_Node_Str");
  final int w=imp.getWidth();
  final int h=imp.getHeight();
  sb.append(w).append("String_Node_Str");
  sb.append(h).append("String_Node_Str");
  sb.append(n).append("String_Node_Str");
  double density=((double)n / imp.getStackSize()) / (w * h) / (simulationParameters.a * simulationParameters.a / 1e6);
  sb.append(Utils.rounded(density)).append("String_Node_Str");
  sb.append(Utils.rounded(signal)).append("String_Node_Str");
  sb.append(Utils.rounded(simulationParameters.s)).append("String_Node_Str");
  sb.append(Utils.rounded(simulationParameters.a)).append("String_Node_Str");
  sb.append(Utils.rounded(simulationParameters.depth)).append("String_Node_Str");
  sb.append(simulationParameters.fixedDepth).append("String_Node_Str");
  sb.append(Utils.rounded(simulationParameters.gain)).append("String_Node_Str");
  sb.append(Utils.rounded(simulationParameters.readNoise)).append("String_Node_Str");
  sb.append(Utils.rounded(simulationParameters.b)).append("String_Node_Str");
  sb.append(Utils.rounded(simulationParameters.b2)).append("String_Node_Str");
  double noise=simulationParameters.b2;
  if (simulationParameters.emCCD) {
    final double readVariance=noise - simulationParameters.b;
    noise=simulationParameters.b * 2 + readVariance;
  }
  if (simulationParameters.fullSimulation) {
  }
  sb.append(Utils.rounded(signal / Math.sqrt(noise))).append("String_Node_Str");
  sb.append(Utils.rounded(simulationParameters.s / simulationParameters.a)).append("String_Node_Str");
  sb.append(spotFilter.getDescription());
  addCount(sb,nP + nN);
  addCount(sb,nP);
  addCount(sb,nN);
  addCount(sb,fP);
  addCount(sb,fN);
  String name=PeakFit.getSolverName(fitConfig);
  if (fitConfig.getFitSolver() == FitSolver.MLE && fitConfig.isModelCamera())   name+="String_Node_Str";
  add(sb,name);
  add(sb,config.getFitting());
  resultPrefix=sb.toString();
  add(sb,(100.0 * cTP) / nP);
  add(sb,(100.0 * cFP) / nN);
  add(sb,cTP + cFP);
  add(sb,cTP);
  add(sb,cFP);
  FractionClassificationResult m=new FractionClassificationResult(cTP,cFP,0,simulationParameters.molecules - cTP);
  add(sb,m.getRecall());
  add(sb,m.getPrecision());
  add(sb,m.getF1Score());
  add(sb,m.getJaccard());
  add(sb,failcTP);
  add(sb,failcFP);
  add(sb,tp);
  add(sb,fp);
  m=new FractionClassificationResult(tp,fp,0,simulationParameters.molecules - tp);
  add(sb,m.getRecall());
  add(sb,m.getPrecision());
  add(sb,m.getF1Score());
  add(sb,m.getJaccard());
  add(sb,tp);
  m=new FractionClassificationResult(tp,0,0,simulationParameters.molecules - tp);
  add(sb,m.getRecall());
  add(sb,m.getF1Score());
  add(sb,m.getJaccard());
  double median=distanceStats.getMedian();
  add(sb,median);
  WindowOrganiser wo=new WindowOrganiser();
  String label=String.format("String_Node_Str",Utils.rounded(m.getRecall()),distanceStats.getN(),Utils.rounded(median),Utils.rounded(distanceStats.getStandardDeviation()));
  int id=Utils.showHistogram(TITLE,distanceStats,"String_Node_Str",0,0,0,label);
  if (Utils.isNewWindow())   wo.add(id);
  median=depthStats.getMedian();
  add(sb,median);
  int[] indices=Utils.newArray(i1.length,0,1);
  if (showCorrelation)   Sort.sort(indices,is,rankByIntensity);
  double[] r=(showCorrelation) ? new double[i1.length] : null;
  double[] sr=(showCorrelation) ? new double[i1.length] : null;
  double[] rank=(showCorrelation) ? new double[i1.length] : null;
  ci=0;
  FastCorrelator fastCorrelator=new FastCorrelator();
  ArrayList<Ranking> pc1=new ArrayList<Ranking>();
  ArrayList<Ranking> pc2=new ArrayList<Ranking>();
  for (  int ci2 : indices) {
    fastCorrelator.add((long)Math.round(i1[ci2]),(long)Math.round(i2[ci2]));
    pc1.add(new Ranking(i1[ci2],ci));
    pc2.add(new Ranking(i2[ci2],ci));
    if (showCorrelation) {
      r[ci]=fastCorrelator.getCorrelation();
      sr[ci]=Correlator.correlation(rank(pc1),rank(pc2));
      if (rankByIntensity)       rank[ci]=is[0] - is[ci];
 else       rank[ci]=ci;
    }
    ci++;
  }
  final double pearsonCorr=fastCorrelator.getCorrelation();
  final double rankedCorr=Correlator.correlation(rank(pc1),rank(pc2));
  SimpleRegression regression=new SimpleRegression(false);
  for (int i=0; i < pc1.size(); i++)   regression.addData(pc1.get(i).value,pc2.get(i).value);
  final double slope=regression.getSlope();
  if (showCorrelation) {
    String title=TITLE + "String_Node_Str";
    Plot plot=new Plot(title,"String_Node_Str","String_Node_Str");
    double[] limits1=Maths.limits(i1);
    double[] limits2=Maths.limits(i2);
    plot.setLimits(limits1[0],limits1[1],limits2[0],limits2[1]);
    label=String.format("String_Node_Str",Utils.rounded(pearsonCorr),Utils.rounded(rankedCorr),Utils.rounded(slope));
    plot.addLabel(0,0,label);
    plot.setColor(Color.red);
    plot.addPoints(i1,i2,Plot.DOT);
    if (slope > 1)     plot.drawLine(limits1[0],limits1[0] * slope,limits1[1],limits1[1] * slope);
 else     plot.drawLine(limits2[0] / slope,limits2[0],limits2[1] / slope,limits2[1]);
    PlotWindow pw=Utils.display(title,plot);
    if (Utils.isNewWindow())     wo.add(pw);
    title=TITLE + "String_Node_Str";
    plot=new Plot(title,"String_Node_Str","String_Node_Str");
    double[] xlimits=Maths.limits(rank);
    double[] ylimits=Maths.limits(r);
    ylimits=Maths.limits(ylimits,sr);
    plot.setLimits(xlimits[0],xlimits[1],ylimits[0],ylimits[1]);
    plot.setColor(Color.red);
    plot.addPoints(rank,r,Plot.LINE);
    plot.setColor(Color.blue);
    plot.addPoints(rank,sr,Plot.LINE);
    plot.setColor(Color.black);
    plot.addLabel(0,0,label);
    pw=Utils.display(title,plot);
    if (Utils.isNewWindow())     wo.add(pw);
  }
  add(sb,pearsonCorr);
  add(sb,rankedCorr);
  add(sb,slope);
  label=String.format("String_Node_Str",depthStats.getN(),Utils.rounded(median));
  id=Utils.showHistogram(TITLE,depthStats,"String_Node_Str",0,1,0,label);
  if (Utils.isNewWindow())   wo.add(id);
  double[] lower=new double[filterCriteria.length];
  double[] upper=new double[lower.length];
  for (int i=0; i < stats[0].length; i++) {
    double[] limits=showDoubleHistogram(stats,i,wo);
    lower[i]=limits[0];
    upper[i]=limits[1];
  }
  upper[FILTER_SIGNAL]*=2;
  upper[FILTER_SNR]*=2;
  lower[FILTER_PRECISION]*=0.5;
  double factor=0.25;
  if (lower[FILTER_MIN_WIDTH] != 0)   upper[FILTER_MIN_WIDTH]=1 - Math.max(0,factor * (1 - lower[FILTER_MIN_WIDTH]));
  if (upper[FILTER_MIN_WIDTH] != 0)   lower[FILTER_MAX_WIDTH]=1 + Math.max(0,factor * (upper[FILTER_MAX_WIDTH] - 1));
  double[] increment=new double[lower.length];
  for (int i=0; i < increment.length; i++)   increment[i]=(upper[i] - lower[i]) / 10;
  increment[FILTER_SIGNAL]=Double.POSITIVE_INFINITY;
  increment[FILTER_ESHIFT]=Double.POSITIVE_INFINITY;
  for (int i=0; i < stats[0].length; i++) {
    lower[i]=Maths.round(lower[i]);
    upper[i]=Maths.round(upper[i]);
    increment[i]=Maths.round(increment[i]);
    sb.append("String_Node_Str").append(lower[i]).append('-').append(upper[i]);
  }
  wo.tile();
  summaryTable.append(sb.toString());
  if (saveFilterRange) {
    GlobalSettings gs=SettingsManager.loadSettings();
    FilterSettings filterSettings=gs.getFilterSettings();
    String filename=Utils.getFilename("String_Node_Str",filterSettings.filterSetFilename);
    if (filename == null)     return;
    filename=Utils.replaceExtension(filename,"String_Node_Str");
    filterSettings.filterSetFilename=filename;
    ArrayList<Filter> filters=new ArrayList<Filter>(3);
    filters.add(new MultiFilter2(lower[0],(float)lower[1],lower[2],lower[3],lower[4],lower[5],lower[6]));
    filters.add(new MultiFilter2(upper[0],(float)upper[1],upper[2],upper[3],upper[4],upper[5],upper[6]));
    filters.add(new MultiFilter2(increment[0],(float)increment[1],increment[2],increment[3],increment[4],increment[5],increment[6]));
    ArrayList<FilterSet> filterList=new ArrayList<FilterSet>(1);
    filterList.add(new FilterSet("String_Node_Str",filters));
    FileOutputStream fos=null;
    try {
      fos=new FileOutputStream(filename);
      XStreamWrapper.getInstance().toXML(filterList,fos);
      SettingsManager.saveSettings(gs);
    }
 catch (    Exception e) {
      IJ.log("String_Node_Str" + e.getMessage());
    }
 finally {
      if (fos != null) {
        try {
          fos.close();
        }
 catch (        IOException e) {
        }
      }
    }
  }
}

Fixed version (ground truth):
private void summariseResults(HashMap<Integer,FilterCandidates> filterCandidates){
  createTable();
  StoredDataStatistics distanceStats=new StoredDataStatistics();
  StoredDataStatistics depthStats=new StoredDataStatistics();
  createFilterCriteria();
  StoredDataStatistics[][] stats=new StoredDataStatistics[3][filterCriteria.length];
  for (int i=0; i < stats.length; i++)   for (int j=0; j < stats[i].length; j++)   stats[i][j]=new StoredDataStatistics();
  final double nmPerPixel=simulationParameters.a;
  final boolean mle=fitConfig.getFitSolver() == FitSolver.MLE;
  double tp=0, fp=0;
  int failcTP=0, failcFP=0;
  int cTP=0, cFP=0;
  int[] status=null, status2=null;
  status=new int[FitStatus.values().length];
  status2=new int[status.length];
  for (  FilterCandidates result : filterCandidates.values()) {
    tp+=result.tp;
    fp+=result.fp;
    for (int i=0; i < result.fitResult.length; i++) {
      if (result.spots[i].match)       cTP++;
 else       cFP++;
      final FitResult fitResult=result.fitResult[i];
      if (fitResult.getStatus() != FitStatus.OK) {
        if (status != null) {
          status[result.fitResult[i].getStatus().ordinal()]++;
          if (result.fitResultWithNeighbours[i] != null)           status2[result.fitResultWithNeighbours[i].getStatus().ordinal()]++;
        }
        if (result.spots[i].match)         failcTP++;
 else         failcFP++;
        stats[0][FILTER_ITERATIONS].add(fitResult.getIterations());
        stats[0][FILTER_EVALUATIONS].add(fitResult.getEvaluations());
      }
 else {
        final double[] p=fitResult.getParameters();
        final double[] initialParams=fitResult.getInitialParameters();
        final double s0=(p[Gaussian2DFunction.X_SD] + p[Gaussian2DFunction.Y_SD]) * 0.5;
        final double s=s0 * nmPerPixel;
        final double N=p[Gaussian2DFunction.SIGNAL] / simulationParameters.gain;
        final double b2=Math.max(0,(p[Gaussian2DFunction.BACKGROUND] - simulationParameters.bias) / simulationParameters.gain);
        double precision;
        if (mle)         precision=PeakResult.getMLPrecisionX(nmPerPixel,s,N,b2,simulationParameters.emCCD);
 else         precision=PeakResult.getPrecisionX(nmPerPixel,s,N,b2,simulationParameters.emCCD);
        final double signal=p[Gaussian2DFunction.SIGNAL] / simulationParameters.gain;
        final double snr=p[Gaussian2DFunction.SIGNAL] / result.noise;
        final double width=s0 / fitConfig.getInitialPeakStdDev0();
        final double xShift=p[Gaussian2DFunction.X_POSITION] - initialParams[Gaussian2DFunction.X_POSITION];
        final double yShift=p[Gaussian2DFunction.Y_POSITION] - initialParams[Gaussian2DFunction.Y_POSITION];
        double shift=((Math.abs(xShift) > Math.abs(yShift)) ? xShift : yShift) / fitConfig.getInitialPeakStdDev0();
        shift=Math.abs(shift);
        final double eshift=Math.sqrt(xShift * xShift + yShift * yShift);
        stats[0][FILTER_SIGNAL].add(signal);
        stats[0][FILTER_SNR].add(snr);
        if (width < 1)         stats[0][FILTER_MIN_WIDTH].add(width);
 else         stats[0][FILTER_MAX_WIDTH].add(width);
        stats[0][FILTER_SHIFT].add(shift);
        stats[0][FILTER_ESHIFT].add(eshift);
        stats[0][FILTER_PRECISION].add(precision);
        stats[0][FILTER_ITERATIONS].add(fitResult.getIterations());
        stats[0][FILTER_EVALUATIONS].add(fitResult.getEvaluations());
        final int index=(result.fitMatch[i]) ? 1 : 2;
        stats[index][FILTER_SIGNAL].add(signal);
        stats[index][FILTER_SNR].add(snr);
        if (width < 1)         stats[index][FILTER_MIN_WIDTH].add(width);
 else         stats[index][FILTER_MAX_WIDTH].add(width);
        stats[index][FILTER_SHIFT].add(shift);
        stats[index][FILTER_ESHIFT].add(eshift);
        stats[index][FILTER_PRECISION].add(precision);
        stats[index][FILTER_ITERATIONS].add(fitResult.getIterations());
        stats[index][FILTER_EVALUATIONS].add(fitResult.getEvaluations());
      }
    }
    for (int i=0; i < result.match.length; i++) {
      if (!result.match[i].isFitResult())       continue;
      FitMatch fitMatch=(FitMatch)result.match[i];
      distanceStats.add(fitMatch.d * nmPerPixel);
      depthStats.add(fitMatch.z * nmPerPixel);
    }
  }
  double[] i1=new double[depthStats.getN()];
  double[] i2=new double[i1.length];
  double[] is=new double[i1.length];
  int ci=0;
  for (  FilterCandidates result : filterCandidates.values()) {
    for (int i=0; i < result.match.length; i++) {
      if (!result.match[i].isFitResult())       continue;
      FitMatch fitMatch=(FitMatch)result.match[i];
      ScoredSpot spot=result.spots[i];
      i1[ci]=fitMatch.predictedSignal;
      i2[ci]=fitMatch.actualSignal;
      is[ci]=spot.intensity;
      ci++;
    }
  }
  if (status != null) {
    String name=PeakFit.getSolverName(fitConfig);
    if (fitConfig.getFitSolver() == FitSolver.MLE && fitConfig.isModelCamera())     name+="String_Node_Str";
    System.out.println("String_Node_Str" + name);
    for (int i=0; i < status.length; i++) {
      if (status[i] != 0)       System.out.printf("String_Node_Str",FitStatus.values()[i].toString(),status[i]);
    }
    for (int i=0; i < status2.length; i++) {
      if (status2[i] != 0)       System.out.printf("String_Node_Str",FitStatus.values()[i].toString(),status2[i]);
    }
  }
  StringBuilder sb=new StringBuilder();
  final double signal=simulationParameters.signalPerFrame;
  final int n=results.size();
  sb.append(imp.getStackSize()).append("String_Node_Str");
  final int w=imp.getWidth();
  final int h=imp.getHeight();
  sb.append(w).append("String_Node_Str");
  sb.append(h).append("String_Node_Str");
  sb.append(n).append("String_Node_Str");
  double density=((double)n / imp.getStackSize()) / (w * h) / (simulationParameters.a * simulationParameters.a / 1e6);
  sb.append(Utils.rounded(density)).append("String_Node_Str");
  sb.append(Utils.rounded(signal)).append("String_Node_Str");
  sb.append(Utils.rounded(simulationParameters.s)).append("String_Node_Str");
  sb.append(Utils.rounded(simulationParameters.a)).append("String_Node_Str");
  sb.append(Utils.rounded(simulationParameters.depth)).append("String_Node_Str");
  sb.append(simulationParameters.fixedDepth).append("String_Node_Str");
  sb.append(Utils.rounded(simulationParameters.gain)).append("String_Node_Str");
  sb.append(Utils.rounded(simulationParameters.readNoise)).append("String_Node_Str");
  sb.append(Utils.rounded(simulationParameters.b)).append("String_Node_Str");
  sb.append(Utils.rounded(simulationParameters.b2)).append("String_Node_Str");
  double noise=simulationParameters.b2;
  if (simulationParameters.emCCD) {
    final double readVariance=noise - simulationParameters.b;
    noise=simulationParameters.b * 2 + readVariance;
  }
  if (simulationParameters.fullSimulation) {
  }
  sb.append(Utils.rounded(signal / Math.sqrt(noise))).append("String_Node_Str");
  sb.append(Utils.rounded(simulationParameters.s / simulationParameters.a)).append("String_Node_Str");
  sb.append(spotFilter.getDescription());
  addCount(sb,nP + nN);
  addCount(sb,nP);
  addCount(sb,nN);
  addCount(sb,fP);
  addCount(sb,fN);
  String name=PeakFit.getSolverName(fitConfig);
  if (fitConfig.getFitSolver() == FitSolver.MLE && fitConfig.isModelCamera())   name+="String_Node_Str";
  add(sb,name);
  add(sb,config.getFitting());
  resultPrefix=sb.toString();
  add(sb,(100.0 * cTP) / nP);
  add(sb,(100.0 * cFP) / nN);
  add(sb,cTP + cFP);
  add(sb,cTP);
  add(sb,cFP);
  FractionClassificationResult m=new FractionClassificationResult(cTP,cFP,0,simulationParameters.molecules - cTP);
  add(sb,m.getRecall());
  add(sb,m.getPrecision());
  add(sb,m.getF1Score());
  add(sb,m.getJaccard());
  add(sb,failcTP);
  add(sb,failcFP);
  add(sb,tp);
  add(sb,fp);
  m=new FractionClassificationResult(tp,fp,0,simulationParameters.molecules - tp);
  add(sb,m.getRecall());
  add(sb,m.getPrecision());
  add(sb,m.getF1Score());
  add(sb,m.getJaccard());
  add(sb,tp);
  m=new FractionClassificationResult(tp,0,0,simulationParameters.molecules - tp);
  add(sb,m.getRecall());
  add(sb,m.getF1Score());
  add(sb,m.getJaccard());
  double median=distanceStats.getMedian();
  add(sb,median);
  WindowOrganiser wo=new WindowOrganiser();
  String label=String.format("String_Node_Str",Utils.rounded(m.getRecall()),distanceStats.getN(),Utils.rounded(median),Utils.rounded(distanceStats.getStandardDeviation()));
  int id=Utils.showHistogram(TITLE,distanceStats,"String_Node_Str",0,0,0,label);
  if (Utils.isNewWindow())   wo.add(id);
  median=depthStats.getMedian();
  add(sb,median);
  int[] indices=Utils.newArray(i1.length,0,1);
  if (showCorrelation)   Sort.sort(indices,is,rankByIntensity);
  double[] r=(showCorrelation) ? new double[i1.length] : null;
  double[] sr=(showCorrelation) ? new double[i1.length] : null;
  double[] rank=(showCorrelation) ? new double[i1.length] : null;
  ci=0;
  FastCorrelator fastCorrelator=new FastCorrelator();
  ArrayList<Ranking> pc1=new ArrayList<Ranking>();
  ArrayList<Ranking> pc2=new ArrayList<Ranking>();
  for (  int ci2 : indices) {
    fastCorrelator.add((long)Math.round(i1[ci2]),(long)Math.round(i2[ci2]));
    pc1.add(new Ranking(i1[ci2],ci));
    pc2.add(new Ranking(i2[ci2],ci));
    if (showCorrelation) {
      r[ci]=fastCorrelator.getCorrelation();
      sr[ci]=Correlator.correlation(rank(pc1),rank(pc2));
      if (rankByIntensity)       rank[ci]=is[0] - is[ci];
 else       rank[ci]=ci;
    }
    ci++;
  }
  final double pearsonCorr=fastCorrelator.getCorrelation();
  final double rankedCorr=Correlator.correlation(rank(pc1),rank(pc2));
  SimpleRegression regression=new SimpleRegression(false);
  for (int i=0; i < pc1.size(); i++)   regression.addData(pc1.get(i).value,pc2.get(i).value);
  final double slope=regression.getSlope();
  if (showCorrelation) {
    String title=TITLE + "String_Node_Str";
    Plot plot=new Plot(title,"String_Node_Str","String_Node_Str");
    double[] limits1=Maths.limits(i1);
    double[] limits2=Maths.limits(i2);
    plot.setLimits(limits1[0],limits1[1],limits2[0],limits2[1]);
    label=String.format("String_Node_Str",Utils.rounded(pearsonCorr),Utils.rounded(rankedCorr),Utils.rounded(slope));
    plot.addLabel(0,0,label);
    plot.setColor(Color.red);
    plot.addPoints(i1,i2,Plot.DOT);
    if (slope > 1)     plot.drawLine(limits1[0],limits1[0] * slope,limits1[1],limits1[1] * slope);
 else     plot.drawLine(limits2[0] / slope,limits2[0],limits2[1] / slope,limits2[1]);
    PlotWindow pw=Utils.display(title,plot);
    if (Utils.isNewWindow())     wo.add(pw);
    title=TITLE + "String_Node_Str";
    plot=new Plot(title,"String_Node_Str","String_Node_Str");
    double[] xlimits=Maths.limits(rank);
    double[] ylimits=Maths.limits(r);
    ylimits=Maths.limits(ylimits,sr);
    plot.setLimits(xlimits[0],xlimits[1],ylimits[0],ylimits[1]);
    plot.setColor(Color.red);
    plot.addPoints(rank,r,Plot.LINE);
    plot.setColor(Color.blue);
    plot.addPoints(rank,sr,Plot.LINE);
    plot.setColor(Color.black);
    plot.addLabel(0,0,label);
    pw=Utils.display(title,plot);
    if (Utils.isNewWindow())     wo.add(pw);
  }
  add(sb,pearsonCorr);
  add(sb,rankedCorr);
  add(sb,slope);
  label=String.format("String_Node_Str",depthStats.getN(),Utils.rounded(median));
  id=Utils.showHistogram(TITLE,depthStats,"String_Node_Str",0,1,0,label);
  if (Utils.isNewWindow())   wo.add(id);
  double[] lower=new double[filterCriteria.length];
  double[] upper=new double[lower.length];
  for (int i=0; i < stats[0].length; i++) {
    double[] limits=showDoubleHistogram(stats,i,wo);
    lower[i]=limits[0];
    upper[i]=limits[1];
  }
  upper[FILTER_SIGNAL]*=2;
  upper[FILTER_SNR]*=2;
  lower[FILTER_PRECISION]*=0.5;
  double factor=0.25;
  if (lower[FILTER_MIN_WIDTH] != 0)   upper[FILTER_MIN_WIDTH]=1 - Math.max(0,factor * (1 - lower[FILTER_MIN_WIDTH]));
  if (upper[FILTER_MIN_WIDTH] != 0)   lower[FILTER_MAX_WIDTH]=1 + Math.max(0,factor * (upper[FILTER_MAX_WIDTH] - 1));
  double[] increment=new double[lower.length];
  for (int i=0; i < increment.length; i++)   increment[i]=(upper[i] - lower[i]) / 10;
  increment[FILTER_SIGNAL]=Double.POSITIVE_INFINITY;
  increment[FILTER_ESHIFT]=Double.POSITIVE_INFINITY;
  for (int i=0; i < stats[0].length; i++) {
    lower[i]=Maths.round(lower[i]);
    upper[i]=Maths.round(upper[i]);
    increment[i]=Maths.round(increment[i]);
    sb.append("String_Node_Str").append(lower[i]).append('-').append(upper[i]);
  }
  wo.tile();
  summaryTable.append(sb.toString());
  if (saveFilterRange) {
    GlobalSettings gs=SettingsManager.loadSettings();
    FilterSettings filterSettings=gs.getFilterSettings();
    String filename=Utils.getFilename("String_Node_Str",filterSettings.filterSetFilename);
    if (filename == null)     return;
    filename=Utils.replaceExtension(filename,"String_Node_Str");
    filterSettings.filterSetFilename=filename;
    ArrayList<Filter> filters=new ArrayList<Filter>(3);
    filters.add(new MultiFilter2(lower[0],(float)lower[1],lower[2],lower[3],lower[4],lower[5],lower[6]));
    filters.add(new MultiFilter2(upper[0],(float)upper[1],upper[2],upper[3],upper[4],upper[5],upper[6]));
    filters.add(new MultiFilter2(increment[0],(float)increment[1],increment[2],increment[3],increment[4],increment[5],increment[6]));
    ArrayList<FilterSet> filterList=new ArrayList<FilterSet>(1);
    filterList.add(new FilterSet("String_Node_Str",filters));
    FileOutputStream fos=null;
    try {
      fos=new FileOutputStream(filename);
      XStreamWrapper.getInstance().toXML(filterList,fos);
      SettingsManager.saveSettings(gs);
    }
 catch (    Exception e) {
      IJ.log("String_Node_Str" + e.getMessage());
    }
 finally {
      if (fos != null) {
        try {
          fos.close();
        }
 catch (        IOException e) {
        }
      }
    }
  }
}