Program: 17005
Project: 17005
Buggy source:
public static AFPChain filterDuplicateAFPs(AFPChain afpChain,CECalculator ceCalc,Atom[] ca1,Atom[] ca2duplicated,int minCPlength) throws StructureException {
  AFPChain newAFPChain=new AFPChain(afpChain);
  int ca2len=afpChain.getCa2Length() / 2;
  newAFPChain.setCa2Length(ca2len);
  int[][][] optAln=afpChain.getOptAln();
  int[] optLen=afpChain.getOptLen();
  int alignLen=afpChain.getOptLength();
  if (alignLen < 1)   return newAFPChain;
  assert(afpChain.getBlockNum() == 1);
  int nStart=optAln[0][1][0];
  int cEnd=optAln[0][1][alignLen - 1];
  int firstRes=nStart;
  int lastRes=nStart + ca2len;
  if (nStart >= ca2len || cEnd < ca2len) {
    firstRes=nStart;
    lastRes=cEnd;
  }
 else {
    int overlapLength=cEnd + 1 - nStart - ca2len;
    if (overlapLength <= 0) {
      CPRange minCP=calculateMinCP(optAln[0][1],alignLen,ca2len,minCPlength);
      firstRes=nStart;
      lastRes=cEnd;
      if (firstRes > minCP.n) {
        firstRes=ca2len;
        if (debug) {
          System.out.format("String_Node_Str" + "String_Node_Str",minCP.mid,minCPlength);
        }
      }
      if (lastRes < minCP.c) {
        lastRes=ca2len - 1;
        if (debug) {
          System.out.format("String_Node_Str" + "String_Node_Str",optLen[0] - minCP.mid,minCPlength);
        }
      }
    }
 else {
      CutPoint cp=calculateCutPoint(optAln[0][1],nStart,cEnd,overlapLength,alignLen,minCPlength,ca2len,firstRes);
      firstRes=cp.firstRes;
      lastRes=cp.lastRes;
    }
  }
  List<ResiduePair> left=new ArrayList<ResiduePair>();
  List<ResiduePair> right=new ArrayList<ResiduePair>();
  for (int i=0; i < optLen[0]; i++) {
    if (optAln[0][1][i] >= firstRes && optAln[0][1][i] <= lastRes) {
      if (optAln[0][1][i] < ca2len) {
        left.add(new ResiduePair(optAln[0][0][i],optAln[0][1][i]));
      }
 else {
        right.add(new ResiduePair(optAln[0][0][i],optAln[0][1][i] - ca2len));
      }
    }
  }
  alignLen=0;
  List<List<ResiduePair>> blocks=new ArrayList<List<ResiduePair>>(2);
  if (!left.isEmpty()) {
    blocks.add(left);
    alignLen+=left.size();
  }
  if (!right.isEmpty()) {
    blocks.add(right);
    alignLen+=right.size();
  }
  left=null;
  right=null;
  int[][][] newAlign=new int[blocks.size()][][];
  int[] blockLengths=new int[blocks.size()];
  for (int blockNum=0; blockNum < blocks.size(); blockNum++) {
    List<ResiduePair> block=blocks.get(blockNum);
    newAlign[blockNum]=new int[2][block.size()];
    for (int i=0; i < block.size(); i++) {
      ResiduePair pair=block.get(i);
      newAlign[blockNum][0][i]=pair.a;
      newAlign[blockNum][1][i]=pair.b;
    }
    blockLengths[blockNum]=block.size();
  }
  newAFPChain.setOptAln(newAlign);
  newAFPChain.setOptLen(blockLengths);
  newAFPChain.setOptLength(alignLen);
  newAFPChain.setBlockNum(blocks.size());
  newAFPChain.setBlockResSize(blockLengths.clone());
  newAFPChain.setSequentialAlignment(blocks.size() == 1);
  Atom[] atoms1=new Atom[alignLen];
  Atom[] atoms2=new Atom[alignLen];
  int pos=0;
  for (  List<ResiduePair> block : blocks) {
    for (    ResiduePair pair : block) {
      atoms1[pos]=ca1[pair.a];
      atoms2[pos]=ca2duplicated[pair.b];
      pos++;
    }
  }
  assert(pos == alignLen);
  double rmsd;
  double[] blockRMSDs=new double[blocks.size()];
  Matrix[] blockRotationMatrices=new Matrix[blocks.size()];
  Atom[] blockShifts=new Atom[blocks.size()];
  if (alignLen > 0) {
    rmsd=ceCalc.calc_rmsd(atoms1,atoms2,alignLen,true,false);
    blockRMSDs[0]=rmsd;
    blockRotationMatrices[0]=ceCalc.getRotationMatrix();
    blockShifts[0]=ceCalc.getShift();
    for (int i=1; i < blocks.size(); i++) {
      blockRMSDs[i]=rmsd;
      blockRotationMatrices[i]=(Matrix)blockRotationMatrices[0].clone();
      blockShifts[i]=(Atom)blockShifts[0].clone();
    }
  }
  newAFPChain.setOptRmsd(blockRMSDs);
  newAFPChain.setBlockRmsd(blockRMSDs);
  newAFPChain.setBlockRotationMatrix(blockRotationMatrices);
  newAFPChain.setBlockShiftVector(blockShifts);
  Atom[] ca2=new Atom[ca2len];
  for (int i=0; i < ca2len; i++) {
    ca2[i]=ca2duplicated[i];
  }
  AFPAlignmentDisplay.getAlign(newAFPChain,ca1,ca2duplicated);
  return newAFPChain;
}

Fixed version (ground truth):
public static AFPChain filterDuplicateAFPs(AFPChain afpChain,CECalculator ceCalc,Atom[] ca1,Atom[] ca2duplicated,int minCPlength) throws StructureException {
  AFPChain newAFPChain=new AFPChain(afpChain);
  int ca2len=afpChain.getCa2Length() / 2;
  newAFPChain.setCa2Length(ca2len);
  int[][][] optAln=afpChain.getOptAln();
  int[] optLen=afpChain.getOptLen();
  int alignLen=afpChain.getOptLength();
  if (alignLen < 1)   return newAFPChain;
  assert(afpChain.getBlockNum() == 1);
  int nStart=optAln[0][1][0];
  int cEnd=optAln[0][1][alignLen - 1];
  int firstRes=nStart;
  int lastRes=nStart + ca2len;
  if (nStart >= ca2len || cEnd < ca2len) {
    firstRes=nStart;
    lastRes=cEnd;
  }
 else {
    int overlapLength=cEnd + 1 - nStart - ca2len;
    if (overlapLength <= 0) {
      CPRange minCP=calculateMinCP(optAln[0][1],alignLen,ca2len,minCPlength);
      firstRes=nStart;
      lastRes=cEnd;
      if (firstRes > minCP.n) {
        firstRes=ca2len;
        if (debug) {
          System.out.format("String_Node_Str" + "String_Node_Str",minCP.mid,minCPlength);
        }
      }
      if (lastRes < minCP.c) {
        lastRes=ca2len - 1;
        if (debug) {
          System.out.format("String_Node_Str" + "String_Node_Str",optLen[0] - minCP.mid,minCPlength);
        }
      }
    }
 else {
      CutPoint cp=calculateCutPoint(optAln[0][1],nStart,cEnd,overlapLength,alignLen,minCPlength,ca2len,firstRes);
      firstRes=cp.firstRes;
      lastRes=cp.lastRes;
    }
  }
  List<ResiduePair> left=new ArrayList<ResiduePair>();
  List<ResiduePair> right=new ArrayList<ResiduePair>();
  for (int i=0; i < optLen[0]; i++) {
    if (optAln[0][1][i] >= firstRes && optAln[0][1][i] <= lastRes) {
      if (optAln[0][1][i] < ca2len) {
        left.add(new ResiduePair(optAln[0][0][i],optAln[0][1][i]));
      }
 else {
        right.add(new ResiduePair(optAln[0][0][i],optAln[0][1][i] - ca2len));
      }
    }
  }
  alignLen=0;
  List<List<ResiduePair>> blocks=new ArrayList<List<ResiduePair>>(2);
  if (!left.isEmpty()) {
    blocks.add(left);
    alignLen+=left.size();
  }
  if (!right.isEmpty()) {
    blocks.add(right);
    alignLen+=right.size();
  }
  left=null;
  right=null;
  int[][][] newAlign=new int[blocks.size()][][];
  int[] blockLengths=new int[blocks.size()];
  for (int blockNum=0; blockNum < blocks.size(); blockNum++) {
    List<ResiduePair> block=blocks.get(blockNum);
    newAlign[blockNum]=new int[2][block.size()];
    for (int i=0; i < block.size(); i++) {
      ResiduePair pair=block.get(i);
      newAlign[blockNum][0][i]=pair.a;
      newAlign[blockNum][1][i]=pair.b;
    }
    blockLengths[blockNum]=block.size();
  }
  newAFPChain.setOptAln(newAlign);
  newAFPChain.setOptLen(blockLengths);
  newAFPChain.setOptLength(alignLen);
  newAFPChain.setBlockNum(blocks.size());
  newAFPChain.setBlockResSize(blockLengths.clone());
  newAFPChain.setSequentialAlignment(blocks.size() == 1);
  Atom[] atoms1=new Atom[alignLen];
  Atom[] atoms2=new Atom[alignLen];
  int pos=0;
  for (  List<ResiduePair> block : blocks) {
    for (    ResiduePair pair : block) {
      atoms1[pos]=ca1[pair.a];
      atoms2[pos]=ca2duplicated[pair.b];
      pos++;
    }
  }
  assert(pos == alignLen);
  double rmsd=-1;
  double[] blockRMSDs=new double[blocks.size()];
  Matrix[] blockRotationMatrices=new Matrix[blocks.size()];
  Atom[] blockShifts=new Atom[blocks.size()];
  if (alignLen > 0) {
    rmsd=ceCalc.calc_rmsd(atoms1,atoms2,alignLen,true,false);
    blockRMSDs[0]=rmsd;
    blockRotationMatrices[0]=ceCalc.getRotationMatrix();
    blockShifts[0]=ceCalc.getShift();
    for (int i=1; i < blocks.size(); i++) {
      blockRMSDs[i]=rmsd;
      blockRotationMatrices[i]=(Matrix)blockRotationMatrices[0].clone();
      blockShifts[i]=(Atom)blockShifts[0].clone();
    }
  }
  newAFPChain.setOptRmsd(blockRMSDs);
  newAFPChain.setBlockRmsd(blockRMSDs);
  newAFPChain.setBlockRotationMatrix(blockRotationMatrices);
  newAFPChain.setBlockShiftVector(blockShifts);
  newAFPChain.setTotalRmsdOpt(rmsd);
  Atom[] ca2=new Atom[ca2len];
  for (int i=0; i < ca2len; i++) {
    ca2[i]=ca2duplicated[i];
  }
  AFPAlignmentDisplay.getAlign(newAFPChain,ca1,ca2duplicated);
  return newAFPChain;
}