diff --git a/solventmapcreator/io/linkagewriter.py b/solventmapcreator/io/linkagewriter.py index f9d399b287bfea30ed3e79398fbf3c7fb8423621..0555fd8fa12613ca26f2e55bb9300a4c5ad4df10 100644 --- a/solventmapcreator/io/linkagewriter.py +++ b/solventmapcreator/io/linkagewriter.py @@ -7,9 +7,9 @@ Script for writing out the linkage matrix, as well as the statistics. """ import logging +import scipy.spatial.distance as scidist import csv - logging.basicConfig() LOGGER = logging.getLogger(__name__) LOGGER.setLevel(logging.WARN) @@ -31,4 +31,56 @@ def create_linkage_file_line(linkage_matrix_row): return ["{:.0f}".format(linkage_matrix_row[0]), "{:.0f}".format(linkage_matrix_row[1]), "{:.7f}".format(linkage_matrix_row[2]), - "{:.0f}".format(linkage_matrix_row[3])] \ No newline at end of file + "{:.0f}".format(linkage_matrix_row[3])] + +def write_cophenetic_and_inconsistency(cophenetic_coefficient, + cophenetic_distances, + inconsistency_matrix, filename): + """This writes out the cophenetic and inconsistency information. + """ + cophenetic_lines = create_cophenetic_lines(cophenetic_coefficient, cophenetic_distances) + inconsistency_lines = create_inconsistency_lines(inconsistency_matrix) + with open(filename, 'w') as outfile: + csv_writer = csv.writer(outfile, delimiter='\t', + quoting=csv.QUOTE_NONE) + csv_writer.writerows(cophenetic_lines) + csv_writer.writerows(inconsistency_lines) + return 0 + + +def create_cophenetic_lines(cophenetic_coefficient, cophenetic_distances): + """This creates a list of lists containing the cophenetic coefficient and + the cophenetic distances. + """ + cophenetic_information = [] + cophenetic_coefficient_line = ["Cophenetic coefficient", "{:.7f}".format(cophenetic_coefficient)] + cophenetic_information.append(cophenetic_coefficient_line) + cophenetic_information.append(["Cophenetic Distance Matrix"]) + square_form_cophenetic_dists = scidist.squareform(cophenetic_distances) + for i in range(square_form_cophenetic_dists.shape[0]): + cophenetic_information.append(create_cophenetic_distance_line(square_form_cophenetic_dists[i])) + return cophenetic_information + +def create_cophenetic_distance_line(cophenetic_distance_line): + """This creastes a line from the symmetric square distance matrix. + """ + return ["{:.7f}".format(cophenetic_distance_line[i]) for i in range(cophenetic_distance_line.shape[0])] + +def create_inconsistency_lines(inconsistency_matrix): + """This creates a list of lists containing the inconsistency matrix + information ready for writing to file. + """ + inconsistency_information = [] + header_line = ["Mean Heights of links", "SD for links", "Number of links", "Inconsistency coefficient"] + inconsistency_information.append(header_line) + for i in range(inconsistency_matrix.shape[0]): + inconsistency_information.append(create_inconsistency_line(inconsistency_matrix[i])) + return inconsistency_information + +def create_inconsistency_line(inconsistency_matrix_line): + """This formats the information in the inconsistency line for writing out. + """ + return ["{:.7f}".format(inconsistency_matrix_line[0]), + "{:.7f}".format(inconsistency_matrix_line[1]), + "{:.1f}".format(inconsistency_matrix_line[2]), + "{:.7f}".format(inconsistency_matrix_line[3])] diff --git a/solventmapcreator/test/iotest/linkagewritertest.py b/solventmapcreator/test/iotest/linkagewritertest.py index 7db36197d6a06d527fd41bf6a4f09553fc6b04c4..ae466413036925c4d1dac70c6f65a94d5d4e2b31 100644 --- a/solventmapcreator/test/iotest/linkagewritertest.py +++ b/solventmapcreator/test/iotest/linkagewritertest.py @@ -27,12 +27,22 @@ class LinkageWriterTestCase(unittest.TestCase): [2., 3., 28., 2.], [6., 7., 33., 5.]]) self.expected_filename = "resources/expectedlinkagematrix.csv" + self.inconsistency_matrix = np.array([[17., 0., 1., 0.], + [19.5, 3.535534, 2., 0.707107], + [28., 0., 1., 0.], + [27.666667,5.507571, 3., 0.968364]]) + self.cophenetic_coefficient = 0.73020316123580109 + self.cophenetic_distance_matrix = np.array([17., 33., 33., 22., 33., + 33., 22., 28., 33., 33.]) + self.expected_cop_filename = "resources/expectedcopfile.csv" def tearDown(self): """Clean up after tests. """ del self.linkage_matrix if os.path.isfile("linkagematrix.csv"): os.remove("linkagematrix.csv") + if os.path.isfile("coph_incons.csv"): + os.remove("coph_incons.csv") def test_write_linkage_matrix(self): """Test to see if expected file is produced. """ @@ -51,3 +61,53 @@ class LinkageWriterTestCase(unittest.TestCase): expected_list = ['0', '1', '17.0000000', '2'] actual_list = linkagewriter.create_linkage_file_line(self.linkage_matrix[0]) self.assertListEqual(expected_list, actual_list) + def test_write_cophenetic_and_inconsistency(self): + """Test to see if expected file is produced + """ + actual_filename = "coph_incons.csv" + coph_out = linkagewriter.write_cophenetic_and_inconsistency(self.cophenetic_coefficient, + self.cophenetic_distance_matrix, + self.inconsistency_matrix, + actual_filename) + with open(self.expected_cop_filename, 'r') as exp_file: + exp_file_lines = exp_file.readlines() + with open(actual_filename, 'r') as act_file: + act_file_lines = act_file.readlines() + self.assertListEqual(act_file_lines, exp_file_lines) + def test_create_cophenetic_lines(self): + """Test to see if expected lines are produced. + """ + expected_lines = [['Cophenetic coefficient', '0.7302032'], + ['Cophenetic Distance Matrix'], + ['0.0000000', '17.0000000', '33.0000000', '33.0000000', '22.0000000'], + ['17.0000000', '0.0000000', '33.0000000', '33.0000000', '22.0000000'], + ['33.0000000', '33.0000000', '0.0000000', '28.0000000', '33.0000000'], + ['33.0000000', '33.0000000', '28.0000000', '0.0000000', '33.0000000'], + ['22.0000000', '22.0000000', '33.0000000', '33.0000000', '0.0000000']] + actual_lines = linkagewriter.create_cophenetic_lines(self.cophenetic_coefficient, + self.cophenetic_distance_matrix) + self.assertListEqual(expected_lines, actual_lines) + def test_create_cophenetic_distance_line(self): + """Test to see if expected distance line is produced. + """ + expected_line = ['0.0000000', '17.0000000', '33.0000000', '33.0000000', '22.0000000'] + actual_line = linkagewriter.create_cophenetic_distance_line(np.array([0.0, 17., 33., 33., 22.])) + self.assertListEqual(expected_line, actual_line) + def test_create_inconsistency_lines(self): + """Test to see if expected list of lists is produced. + """ + expected_lines = [['Mean Heights of links', 'SD for links', + 'Number of links', 'Inconsistency coefficient'], + ['17.0000000', '0.0000000', '1.0', '0.0000000'], + ['19.5000000', '3.5355340', '2.0', '0.7071070'], + ['28.0000000', '0.0000000', '1.0', '0.0000000'], + ['27.6666670', '5.5075710', '3.0', '0.9683640']] + actual_lines = linkagewriter.create_inconsistency_lines(self.inconsistency_matrix) + self.assertListEqual(expected_lines, actual_lines) + def test_create_inconsistency_line(self): + """Test to see if expected list is produced. + """ + expected_line = ['17.0000000', '0.0000000', '1.0', '0.0000000'] + actual_line = linkagewriter.create_inconsistency_line(self.inconsistency_matrix[0]) + self.assertListEqual(expected_line, actual_line) + diff --git a/solventmapcreator/test/resources/expectedcopfile.csv b/solventmapcreator/test/resources/expectedcopfile.csv new file mode 100644 index 0000000000000000000000000000000000000000..f4828b77694f90f0cb69fa7a341a8e5f96b4b6b5 --- /dev/null +++ b/solventmapcreator/test/resources/expectedcopfile.csv @@ -0,0 +1,12 @@ +Cophenetic coefficient 0.7302032 +Cophenetic Distance Matrix +0.0000000 17.0000000 33.0000000 33.0000000 22.0000000 +17.0000000 0.0000000 33.0000000 33.0000000 22.0000000 +33.0000000 33.0000000 0.0000000 28.0000000 33.0000000 +33.0000000 33.0000000 28.0000000 0.0000000 33.0000000 +22.0000000 22.0000000 33.0000000 33.0000000 0.0000000 +Mean Heights of links SD for links Number of links Inconsistency coefficient +17.0000000 0.0000000 1.0 0.0000000 +19.5000000 3.5355340 2.0 0.7071070 +28.0000000 0.0000000 1.0 0.0000000 +27.6666670 5.5075710 3.0 0.9683640