/// <summary> /// Performs ICP Alignment using LIBICP 1.4.7. /// Checks if the proteins fit the minimum requirements of the alignment. /// Throws if it does not, or if there are less than two proteins loaded. /// Extract the alpha carbon matrix from the proteins. Sets up the translation and rotation matrices. /// Fits the two matrices using ICP. The rotation matrix is applied to a full atom matrix of Protein2. /// Protein2 is then translated. Calls RMSD() to calculate the RMSD between the two proteins. /// </summary> /// <returns>RMSD value between the two proteins.</returns> public double ICPAlignment() { if (Protein1.Count == 0) { throw (new Exception("Alignment Error: Protein 1 not found.")); } if (Protein2.Count == 0) { throw (new Exception("Alignment Error: Protein 2 not found.")); } //LIBICP doesnt work with less than 5 points if (Protein1.CACount < 5 || Protein2.CACount < 5) { throw (new Exception("Alignment Error: Not enough atoms for alignment.")); } //aligns by CA backbone double[,] prot1Mat = m_prot1.CAMatrix(); double[,] prot2Mat = m_prot2.CAMatrix(); icp_net.ManagedICP align = new icp_net.ManagedICP(prot1Mat, Protein1.CACount, 3); //set up return Rotation matrix double[,] RMat = new double[3, 3]; RMat[0, 0] = 1.0; RMat[1, 1] = 1.0; RMat[2, 2] = 1.0; //set up return Translation matrix double[] TMat = new double[3]; //last parameter is inlier distance, if <= 0, uses all points align.fit(prot2Mat, Protein2.CACount, RMat, TMat, -1); //get full atom matrix to transform // LIBICP actually takes in a n x 3 matrix, but we need a 3 x n matrix for the math, so ToMatrix() gives a full atom matrix in that orientation double[,] prot2FullMat = m_prot2.ToMatrix(); //create objects of Matrix type to perfrom matrix multiplication Matrix <double> prot2MatObj = DenseMatrix.OfArray(prot2FullMat); Matrix <double> RMatObj = DenseMatrix.OfArray(RMat); /*To get the Final dataset B, given dataset A * B = RMat * A + TMat; * Thus Rotation is applied first */ prot2MatObj = RMatObj * prot2MatObj; //sets the protein coordinates to the matrix m_prot2.FromMatrix(prot2MatObj); //translate m_prot2.Translate(TMat[0], TMat[1], TMat[2]); return(RMSD()); }
/// <summary> /// Performs ICP Alignment using LIBICP 1.4.7. /// Checks if the proteins fit the minimum requirements of the alignment. /// Throws if it does not, or if there are less than two proteins loaded. /// Extract the alpha carbon matrix from the proteins. Sets up the translation and rotation matrices. /// Fits the two matrices using ICP. The rotation matrix is applied to a full atom matrix of Protein2. /// Protein2 is then translated. Calls RMSD() to calculate the RMSD between the two proteins. /// </summary> /// <returns>RMSD value between the two proteins.</returns> public double ICPAlignment() { if (Protein1.Count == 0) { throw (new Exception("Alignment Error: Protein 1 not found.")); } if (Protein2.Count == 0) { throw (new Exception("Alignment Error: Protein 2 not found.")); } //LIBICP doesnt work with less than 5 points if (Protein1.CACount < 5 || Protein2.CACount < 5) { throw (new Exception("Alignment Error: Not enough atoms for alignment.")); } //aligns by CA backbone double[,] prot1Mat = m_prot1.CAMatrix(); double[,] prot2Mat = m_prot2.CAMatrix(); icp_net.ManagedICP align = new icp_net.ManagedICP(prot1Mat, Protein1.CACount, 3); //set up return Rotation matrix double[,] RMat = new double[3, 3]; RMat[0, 0] = 1.0; RMat[1, 1] = 1.0; RMat[2, 2] = 1.0; //set up return Translation matrix double[] TMat = new double[3]; //last parameter is inlier distance, if <= 0, uses all points align.fit(prot2Mat, Protein2.CACount, RMat, TMat, -1); //get full atom matrix to transform // LIBICP actually takes in a n x 3 matrix, but we need a 3 x n matrix for the math, so ToMatrix() gives a full atom matrix in that orientation double[,] prot2FullMat = m_prot2.ToMatrix(); //create objects of Matrix type to perfrom matrix multiplication Matrix<double> prot2MatObj = DenseMatrix.OfArray(prot2FullMat); Matrix<double> RMatObj = DenseMatrix.OfArray(RMat); /*To get the Final dataset B, given dataset A * B = RMat * A + TMat; * Thus Rotation is applied first */ prot2MatObj = RMatObj * prot2MatObj; //sets the protein coordinates to the matrix m_prot2.FromMatrix(prot2MatObj); //translate m_prot2.Translate(TMat[0], TMat[1], TMat[2]); return RMSD(); }