code: public static AFPChain refineSymmetry(AFPChain afpChain, Atom[] ca1, Atom[] ca2, int k)
  			throws StructureException, RefinerFailedException {
  
  		// Transform alignment to a Map
  		Map<Integer, Integer> alignment = AlignmentTools.alignmentAsMap(afpChain);
  
  		// Refine the alignment Map
  		Map<Integer, Integer> refined = refineSymmetry(alignment, k);
  		if (refined.size() < 1)
  			throw new RefinerFailedException("Refiner returned empty alignment");
  
  		//Substitute and partition the alignment
  		try {
  			AFPChain refinedAFP = AlignmentTools.replaceOptAln(afpChain, ca1, ca2, refined);
  			refinedAFP = partitionAFPchain(refinedAFP, ca1, ca2, k);
  			if (refinedAFP.getOptLength() < 1)
  				throw new IndexOutOfBoundsException("Refined alignment is empty.");
  			return refinedAFP;
  		} catch (IndexOutOfBoundsException e){
  			// This Exception is thrown when the refined alignment is not consistent
  			throw new RefinerFailedException("Refiner failure: non-consistent result", e);
  		}
  	}
docs: Refines a CE-Symm alignment so that it is perfectly symmetric.
  
  The resulting alignment will have a one-to-one correspondance between
  aligned residues of each symmetric part.
  
  @param afpChain Input alignment from CE-Symm
  @param k Symmetry order. This can be guessed by {@link CeSymm#getSymmetryOrder(AFPChain)}
  @return The refined alignment
  @throws StructureException
  @throws RefinerFailedException