/** * Builds an {@link AFPChain} from already-matched arrays of atoms and residues. * * @param ca1 An array of atoms in the first structure * @param ca2 An array of atoms in the second structure * @param residues1 An array of {@link ResidueNumber ResidueNumbers} in the first structure that * are aligned. Only null ResidueNumbers are considered to be unaligned * @param residues2 An array of {@link ResidueNumber ResidueNumbers} in the second structure that * are aligned. Only null ResidueNumbers are considered to be unaligned * @throws StructureException */ private static AFPChain buildAlignment( Atom[] ca1, Atom[] ca2, ResidueNumber[] residues1, ResidueNumber[] residues2) throws StructureException { // remove any gap // this includes the ones introduced by the nullifying above List<ResidueNumber> alignedResiduesList1 = new ArrayList<ResidueNumber>(); List<ResidueNumber> alignedResiduesList2 = new ArrayList<ResidueNumber>(); for (int i = 0; i < residues1.length; i++) { if (residues1[i] != null && residues2[i] != null) { alignedResiduesList1.add(residues1[i]); alignedResiduesList2.add(residues2[i]); } } ResidueNumber[] alignedResidues1 = alignedResiduesList1.toArray(new ResidueNumber[alignedResiduesList1.size()]); ResidueNumber[] alignedResidues2 = alignedResiduesList2.toArray(new ResidueNumber[alignedResiduesList2.size()]); AFPChain afpChain = AlignmentTools.createAFPChain(ca1, ca2, alignedResidues1, alignedResidues2); afpChain.setAlgorithmName("unknown"); AlignmentTools.updateSuperposition(afpChain, ca1, ca2); afpChain.setBlockSize(new int[] {afpChain.getNrEQR()}); afpChain.setBlockRmsd(new double[] {afpChain.getTotalRmsdOpt()}); afpChain.setBlockGap(new int[] {afpChain.getGapLen()}); return afpChain; }
/** * Guesses the order of symmetry in an alignment * * <p>Uses {@link #getSymmetryOrder(Map alignment, Map identity, int, float)} to determine the the * symmetry order. For the identity alignment, sorts the aligned residues of each protein * sequentially, then defines the ith residues of each protein to be equivalent. */ public static int getSymmetryOrder(AFPChain afpChain, int maxSymmetry, float minimumMetricChange) throws StructureException { // alignment comes from the afpChain alignment Map<Integer, Integer> alignment = AlignmentTools.alignmentAsMap(afpChain); // Now construct identity to map aligned residues in sequential order Map<Integer, Integer> identity = guessSequentialAlignment(alignment, true); return AlignmentTools.getSymmetryOrder(alignment, identity, maxSymmetry, minimumMetricChange); }
/** * It replaces an optimal alignment of an AFPChain and calculates all the new alignment scores and * variables. */ public static AFPChain replaceOptAln(int[][][] newAlgn, AFPChain afpChain, Atom[] ca1, Atom[] ca2) throws StructureException { // The order is the number of groups in the newAlgn int order = newAlgn.length; // Calculate the alignment length from all the subunits lengths int[] optLens = new int[order]; for (int s = 0; s < order; s++) { optLens[s] = newAlgn[s][0].length; } int optLength = 0; for (int s = 0; s < order; s++) { optLength += optLens[s]; } // Create a copy of the original AFPChain and set everything needed for the structure update AFPChain copyAFP = (AFPChain) afpChain.clone(); // Set the new parameters of the optimal alignment copyAFP.setOptLength(optLength); copyAFP.setOptLen(optLens); copyAFP.setOptAln(newAlgn); // Set the block information of the new alignment copyAFP.setBlockNum(order); copyAFP.setBlockSize(optLens); copyAFP.setBlockResList(newAlgn); copyAFP.setBlockResSize(optLens); copyAFP.setBlockGap(calculateBlockGap(newAlgn)); // Recalculate properties: superposition, tm-score, etc Atom[] ca2clone = StructureTools.cloneAtomArray(ca2); // don't modify ca2 positions AlignmentTools.updateSuperposition(copyAFP, ca1, ca2clone); // It re-does the sequence alignment strings from the OptAlgn information only copyAFP.setAlnsymb(null); AFPAlignmentDisplay.getAlign(copyAFP, ca1, ca2clone); return copyAFP; }
/** * @param afpChain Input afpchain. UNMODIFIED * @param ca1 * @param ca2 * @param optLens * @param optAln * @return A NEW AfpChain based off the input but with the optAln modified * @throws StructureException if an error occured during superposition */ public static AFPChain replaceOptAln( AFPChain afpChain, Atom[] ca1, Atom[] ca2, int blockNum, int[] optLens, int[][][] optAln) throws StructureException { int optLength = 0; for (int blk = 0; blk < blockNum; blk++) { optLength += optLens[blk]; } // set everything AFPChain refinedAFP = (AFPChain) afpChain.clone(); refinedAFP.setOptLength(optLength); refinedAFP.setBlockSize(optLens); refinedAFP.setOptLen(optLens); refinedAFP.setOptAln(optAln); refinedAFP.setBlockNum(blockNum); // TODO recalculate properties: superposition, tm-score, etc Atom[] ca2clone = StructureTools.cloneAtomArray(ca2); // don't modify ca2 positions AlignmentTools.updateSuperposition(refinedAFP, ca1, ca2clone); AFPAlignmentDisplay.getAlign(refinedAFP, ca1, ca2clone); return refinedAFP; }