Program: 16344
Project: 16344
Buggy source:
/** 
 * Returns minimum, mean, and maximum RMSD and TM-Score for two superimposed sets of subunits TM score: Yang Zhang and Jeffrey Skolnick, PROTEINS: Structure, Function, and Bioinformatics 57:702–710 (2004)
 * @param subunits subunits to be scored
 * @param transformation transformation matrix
 * @param permutations permutation that determines which subunits are superposed
 * @return
 */
public static QuatSymmetryScores calcScores(Subunits subunits,Matrix4d transformation,List<Integer> permutation){
  QuatSymmetryScores scores=new QuatSymmetryScores();
  double minTm=Double.MAX_VALUE;
  double maxTm=Double.MIN_VALUE;
  double minRmsd=Double.MAX_VALUE;
  double maxRmsd=Double.MIN_VALUE;
  double totalSumTm=0;
  double totalSumDsq=0;
  double totalLength=0;
  Point3d t=new Point3d();
  List<Point3d[]> traces=subunits.getTraces();
  for (int i=0; i < traces.size(); i++) {
    if (permutation.get(i) == -1) {
      continue;
    }
    Point3d[] orig=traces.get(i);
    totalLength+=orig.length;
    Point3d[] perm=traces.get(permutation.get(i));
    int tmLen=Math.max(orig.length,17);
    double d0=1.24 * Math.cbrt(tmLen - 15.0) - 1.8;
    double d0Sq=d0 * d0;
    double sumTm=0;
    double sumDsq=0;
    for (int j=0; j < orig.length; j++) {
      t.set(perm[j]);
      transformation.transform(t);
      double dSq=orig[j].distanceSquared(t);
      sumTm+=1.0 / (1.0 + dSq / d0Sq);
      sumDsq+=dSq;
    }
    double sTm=sumTm / tmLen;
    minTm=Math.min(minTm,sTm);
    maxTm=Math.max(maxTm,sTm);
    double sRmsd=Math.sqrt(sumDsq / orig.length);
    minRmsd=Math.min(minRmsd,sRmsd);
    maxRmsd=Math.max(maxRmsd,sRmsd);
    totalSumTm+=sumTm;
    totalSumDsq+=sumDsq;
  }
  scores.setMinRmsd(minRmsd);
  scores.setMaxRmsd(maxRmsd);
  scores.setMinTm(minTm);
  scores.setMaxTm(maxTm);
  scores.setTm(totalSumTm / totalLength);
  scores.setRmsd(Math.sqrt(totalSumDsq / totalLength));
  calcIntrasubunitScores(subunits,transformation,permutation,scores);
  return scores;
}

Fixed version (ground truth):
/** 
 * Returns minimum, mean, and maximum RMSD and TM-Score for two superimposed sets of subunits TM score: Yang Zhang and Jeffrey Skolnick, PROTEINS: Structure, Function, and Bioinformatics 57:702–710 (2004)
 * @param subunits subunits to be scored
 * @param transformation transformation matrix
 * @param permutations permutation that determines which subunits are superposed
 * @return
 */
public static QuatSymmetryScores calcScores(QuatSymmetrySubunits subunits,Matrix4d transformation,List<Integer> permutation){
  QuatSymmetryScores scores=new QuatSymmetryScores();
  double minTm=Double.MAX_VALUE;
  double maxTm=Double.MIN_VALUE;
  double minRmsd=Double.MAX_VALUE;
  double maxRmsd=Double.MIN_VALUE;
  double totalSumTm=0;
  double totalSumDsq=0;
  double totalLength=0;
  Point3d t=new Point3d();
  List<Point3d[]> traces=subunits.getTraces();
  for (int i=0; i < traces.size(); i++) {
    if (permutation.get(i) == -1) {
      continue;
    }
    Point3d[] orig=traces.get(i);
    totalLength+=orig.length;
    Point3d[] perm=traces.get(permutation.get(i));
    int tmLen=Math.max(orig.length,17);
    double d0=1.24 * Math.cbrt(tmLen - 15.0) - 1.8;
    double d0Sq=d0 * d0;
    double sumTm=0;
    double sumDsq=0;
    for (int j=0; j < orig.length; j++) {
      t.set(perm[j]);
      transformation.transform(t);
      double dSq=orig[j].distanceSquared(t);
      sumTm+=1.0 / (1.0 + dSq / d0Sq);
      sumDsq+=dSq;
    }
    double sTm=sumTm / tmLen;
    minTm=Math.min(minTm,sTm);
    maxTm=Math.max(maxTm,sTm);
    double sRmsd=Math.sqrt(sumDsq / orig.length);
    minRmsd=Math.min(minRmsd,sRmsd);
    maxRmsd=Math.max(maxRmsd,sRmsd);
    totalSumTm+=sumTm;
    totalSumDsq+=sumDsq;
  }
  scores.setMinRmsd(minRmsd);
  scores.setMaxRmsd(maxRmsd);
  scores.setMinTm(minTm);
  scores.setMaxTm(maxTm);
  scores.setTm(totalSumTm / totalLength);
  scores.setRmsd(Math.sqrt(totalSumDsq / totalLength));
  calcIntrasubunitScores(subunits,transformation,permutation,scores);
  return scores;
}