From d1a8671fa2bdacca26203a60bbdb6670312b6048 Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Fri, 13 May 2022 16:12:45 -0400
Subject: [PATCH 01/36] Add files via upload
---
File_Utilities/renaming_utilities.ipynb | 200 ++++++++++++++++++++++++
1 file changed, 200 insertions(+)
create mode 100644 File_Utilities/renaming_utilities.ipynb
diff --git a/File_Utilities/renaming_utilities.ipynb b/File_Utilities/renaming_utilities.ipynb
new file mode 100644
index 0000000..d8fb67d
--- /dev/null
+++ b/File_Utilities/renaming_utilities.ipynb
@@ -0,0 +1,200 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import pandas as pd\n",
+ "import matplotlib.pyplot as plt\n",
+ "import seaborn as sns\n",
+ "import numpy as np\n",
+ "import os\n",
+ "import glob\n",
+ "import ete3"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Renaming Utilities\n",
+ "These are simple little things that can save you tons of time. Almost all of these things need a dictionary mapping your old names to new names. Easy made in Excel or whatever."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Phylogeny Renamer"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "This renames the tip labels of a phylogeny (iteratively). Useful for turning your GCA_#######s to meaningful descriptions. You need a dictionary mapping the old labels to the new labels:\n",
+ "example:\n",
+ "{\"GCA_2214\": \"strain 1\", \"GCA_1234\": \"strain2\", etc}"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "#Input: newick file name in quotes. dictonary in proper format\n",
+ "newick = \"\"\n",
+ "name_dict = {}\n",
+ "output_name = \"\""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "phylo = ete3.Tree(newick)\n",
+ "taxa = phylo.get_leaf_names()\n",
+ "for leaf in phylo.iter_leaves():\n",
+ " leaf.name = name_dict[leaf.name]\n",
+ "phylo.write(outfile=output_name)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### This will do it for every file in current directory"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "for filn in glob.glob(\"*.extension\"): #change this to whatever\n",
+ " phylo = ete3.Tree(filn)\n",
+ " taxa = phylo.get_leaf_names()\n",
+ " for leaf in phylo.iter_leaves():\n",
+ " leaf.name = name_dict[leaf.name]\n",
+ " phylo.write(outfile=filn+\"renamed.tre\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Fasta Renamer\n",
+ "Renames fasta records, whatever is after > in a similar fashion to above. Useful for MLSAs and concatenation if you need the same name for every gene family. Every sequence from the same genome will have the same name, you can differentiate them based on the file name or gene fam name."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "with open(input_file_name,'r') as ofh:\n",
+ " for line in ofh:\n",
+ " line = line.strip()\n",
+ " if line.startswith(\">\"): \n",
+ " #where name_dict is the dictionary of names\n",
+ " print(\">\" +name_dict[line[1:]+\".fna\"], file=open(output_file_name,'a'))\n",
+ " else:\n",
+ " print(line, file=open(output_file_name,'a'))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "for everything in the directory"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "for filn in glob.glob(\"*.fasta\"):\n",
+ " with open(filn,'r') as ofh:\n",
+ " for line in ofh:\n",
+ " line = line.strip()\n",
+ " if line.startswith(\">\"): \n",
+ " #where name_dict is the dictionary of names\n",
+ " print(\">\" +name_dict[line[1:]+\".fna\"], file=open(filn + \".re.fasta\",'a'))\n",
+ " else:\n",
+ " print(line, file=open(filn + \".re.fasta\",'a'))"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.6.5"
+ },
+ "toc": {
+ "base_numbering": 1,
+ "nav_menu": {},
+ "number_sections": true,
+ "sideBar": true,
+ "skip_h1_title": false,
+ "title_cell": "Table of Contents",
+ "title_sidebar": "Contents",
+ "toc_cell": false,
+ "toc_position": {},
+ "toc_section_display": true,
+ "toc_window_display": false
+ },
+ "varInspector": {
+ "cols": {
+ "lenName": 16,
+ "lenType": 16,
+ "lenVar": 40
+ },
+ "kernels_config": {
+ "python": {
+ "delete_cmd_postfix": "",
+ "delete_cmd_prefix": "del ",
+ "library": "var_list.py",
+ "varRefreshCmd": "print(var_dic_list())"
+ },
+ "r": {
+ "delete_cmd_postfix": ") ",
+ "delete_cmd_prefix": "rm(",
+ "library": "var_list.r",
+ "varRefreshCmd": "cat(var_dic_list()) "
+ }
+ },
+ "types_to_exclude": [
+ "module",
+ "function",
+ "builtin_function_or_method",
+ "instance",
+ "_Feature"
+ ],
+ "window_display": false
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
From e9dce08bee952e3039eb5d7fa63fadfb645556a9 Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Fri, 13 May 2022 16:15:40 -0400
Subject: [PATCH 02/36] Update table_of_contents.csv
---
table_of_contents.csv | 1 +
1 file changed, 1 insertion(+)
diff --git a/table_of_contents.csv b/table_of_contents.csv
index c3766b3..d678ec9 100644
--- a/table_of_contents.csv
+++ b/table_of_contents.csv
@@ -1,3 +1,4 @@
Script Name,Subdirectory location,Inputs,Outputs,Language,Dependencies,General Description,Author,In or Out of House,Keywords,Date Submitted,Date Updated
---,---,---,---,---,---,---,---,---,---,---,---
convert_csv_to_markdown.pl,File_Utilities,.csv (comma seperated table),.mrkd (markdown formatted table),perl,none,Converts a csv table using commas as the seperator to a markdown formatted table,Sophia Gosselin,In,markdown/csv,21_10_13,N/A
+renaming_utilities.ipynb,File_Utilities,fasta/newick,fasta/newick,python,
From 6f0d87c064b8b6cc10b938690ef136e2f49b5573 Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Fri, 10 Feb 2023 13:34:20 -0500
Subject: [PATCH 03/36] Commands for calling variants from read data
---
Other/varsnps.sh | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
create mode 100644 Other/varsnps.sh
diff --git a/Other/varsnps.sh b/Other/varsnps.sh
new file mode 100644
index 0000000..4bdbfad
--- /dev/null
+++ b/Other/varsnps.sh
@@ -0,0 +1,27 @@
+#requries bcf tools, samtools, and bowtie2 (or other read mapper)
+bowtie2-build ref.fasta refname
+#makes bowtie index for reference genome
+
+bowtie2 -x refname -1 read1.fq -2 read2.fq -U unpairedread.fq -S output.sam
+#map reads back to reference genome for sam file
+
+samtools view -bS output.sam > output.bam
+#convert sam to bam
+
+samtools sort output.bam -O output.sort.bam
+#sort by genomic location
+#need to do next step or the variant annotations are useless
+samtools mpileup --min-BQ number 20-30 \
+-f ref.fasta --BCF bamfromprevious.bam | \
+ bcftools call --consensus-caller \
+--variants-only --pval-threshold 0.05 recommended -Ov -Ob > outputsvariants.bcf ;
+#gets the variants from read mapping file
+
+
+bcftools norm -m-any outputsvariants.bcf | bcftools norm -Ov --check-ref w -f ref.fasta > outputsvariants.vcf ;
+#convert to vcf based off of alignment with refernce genome
+
+
+bcftools view outputsvariants.vcf | vcfutils.pl varFilter -d 18 -w 1 -W 3 -a 1 \
+-e 0.05 -p > outputsvariants.filtered.vcf ;
+#filters those variants that don't meet a certain threshold
From 966a4219787034de180c617ffbbbc877f7dc88f2 Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Fri, 10 Feb 2023 13:37:00 -0500
Subject: [PATCH 04/36] Update table_of_contents.csv
---
table_of_contents.csv | 1 +
1 file changed, 1 insertion(+)
diff --git a/table_of_contents.csv b/table_of_contents.csv
index d678ec9..57d8466 100644
--- a/table_of_contents.csv
+++ b/table_of_contents.csv
@@ -2,3 +2,4 @@ Script Name,Subdirectory location,Inputs,Outputs,Language,Dependencies,General D
---,---,---,---,---,---,---,---,---,---,---,---
convert_csv_to_markdown.pl,File_Utilities,.csv (comma seperated table),.mrkd (markdown formatted table),perl,none,Converts a csv table using commas as the seperator to a markdown formatted table,Sophia Gosselin,In,markdown/csv,21_10_13,N/A
renaming_utilities.ipynb,File_Utilities,fasta/newick,fasta/newick,python,
+varsnps.sh,Other,.fastq/fastq.gz,.bcf/.vcf,Unix,none,Finds variants using read data,Yutian Feng,In,variants/vcf/bcf,10/02/2023,N/A
From d2d037892358a8b4961c8c788f47f75a4dd0052d Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Fri, 10 Feb 2023 13:38:47 -0500
Subject: [PATCH 05/36] concatenate multiple sequence alignments
all taxa across all alignments should have the same name
---
Sequence_Alignment_Utilities/supermatrix.py | 106 ++++++++++++++++++
.../wrapper_supermatrix.py | 34 ++++++
2 files changed, 140 insertions(+)
create mode 100644 Sequence_Alignment_Utilities/supermatrix.py
create mode 100644 Sequence_Alignment_Utilities/wrapper_supermatrix.py
diff --git a/Sequence_Alignment_Utilities/supermatrix.py b/Sequence_Alignment_Utilities/supermatrix.py
new file mode 100644
index 0000000..5fe71e0
--- /dev/null
+++ b/Sequence_Alignment_Utilities/supermatrix.py
@@ -0,0 +1,106 @@
+#!/usr/bin/env python
+
+import sys
+import os
+import textwrap
+
+InFile1 = sys.argv[1]
+InFile2 = sys.argv[2]
+InFile3 = sys.argv[3]
+
+OInFile1 = open(InFile1, 'rU')
+OInFile2 = open(InFile2, 'rU')
+OutFile1 = open(InFile3, 'w')
+
+Concatdict1 = {}
+TaxaList = []
+for Line in OInFile1:
+ Line = Line.strip("\n")
+ if Line[0] == ">":
+ TaxaList.append(Line)
+ Concatdict1[Line] = []
+ else:
+ Concatdict1[TaxaList[len(TaxaList)-1]].append(Line)
+
+Concatdict2 = {}
+TaxaList2 = []
+for Line in OInFile2:
+ Line = Line.strip("\n")
+ if Line[0] == ">":
+ TaxaList2.append(Line)
+ Concatdict2[Line] = []
+ else:
+ Concatdict2[TaxaList2[len(TaxaList2)-1]].append(Line)
+
+MissingSeqs2 = frozenset(Concatdict1.keys()) - frozenset(Concatdict2.keys()) #Keys in 1 but not 2
+MissingSeqs1 = frozenset(Concatdict2.keys()) - frozenset(Concatdict1.keys()) #Keys in 2 but not 1
+
+print MissingSeqs1
+print MissingSeqs2
+
+SeqLengthFile1 = []
+
+X = 1
+for Element in Concatdict1:
+ ValueStr = "".join(Concatdict1[Element])
+ SeqLengthFile1.append(len(ValueStr))
+ X = X + 1
+ if X > 1:
+ break
+#print SeqLengthFile1
+
+EmptySeq1 = "-" * SeqLengthFile1[0]
+
+
+SeqLengthFile2 = []
+X = 1
+for Element in Concatdict2:
+ ValueStr2 = "".join(Concatdict2[Element])
+ SeqLengthFile2.append(len(ValueStr2))
+ X = X + 1
+ if X > 1:
+ break
+#print SeqLengthFile2
+
+EmptySeq2 = "-" * SeqLengthFile2[0]
+
+
+for Elements in MissingSeqs1:
+ Concatdict1[Elements] = list(EmptySeq1)
+for Elements in MissingSeqs2:
+ Concatdict2[Elements] = list(EmptySeq2)
+
+for Element in Concatdict2:
+ SeqStr = "".join(Concatdict2[Element])
+ Concatdict1[Element].append(SeqStr)
+
+for Key in Concatdict1:
+ print Key
+ OutFile1.write(Key + "\n")
+ SeqStr = "".join(Concatdict1[Key])
+ OutFile1.write(SeqStr + "\n")
+ #OutFile1.write(textwrap.fill(SeqStr, width=60) + "\n")
+ print SeqStr
+ #print len(SeqStr)
+
+OInFile1.close()
+OInFile2.close()
+OutFile1.close()
+
+OutFile2 = "MissingSeqs.list_" + InFile3
+OpenOutFile2 = open(OutFile2, 'w')
+OpenOutFile2.write("Missing sequences in " + InFile1 + " are: " + "\n")
+for Element in MissingSeqs1:
+ OpenOutFile2.write(Element + "\n")
+OpenOutFile2.write("Missing sequences in " + InFile2 + " are: " + "\n")
+for Element in MissingSeqs2:
+ OpenOutFile2.write(Element + "\n")
+OpenOutFile2.close()
+
+OutFile3 = "Partition.list_" + InFile3
+openOutFile3 = open(OutFile3, 'w')
+openOutFile3.write(InFile1 + " = 1 - " + str(SeqLengthFile1[0]) + "\n")
+first_value = SeqLengthFile1[0] + 1
+second_value = SeqLengthFile1[0] + SeqLengthFile2[0]
+openOutFile3.write(InFile2 + " = " + str(first_value) + " - " + str(second_value) + "\n")
+openOutFile3.close()
diff --git a/Sequence_Alignment_Utilities/wrapper_supermatrix.py b/Sequence_Alignment_Utilities/wrapper_supermatrix.py
new file mode 100644
index 0000000..4fae2fc
--- /dev/null
+++ b/Sequence_Alignment_Utilities/wrapper_supermatrix.py
@@ -0,0 +1,34 @@
+#!/usr/bin/env python
+
+
+# Supermatrix wrapper
+# Have list of alignments you want concatenated
+# Feed them to supermatrix script
+# Concatenate first two alignments take product and add to next alignment in list ...
+
+import sys
+from subprocess import call
+
+InFile1 = sys.argv[1]
+File1 = open(InFile1, 'rU')
+
+AlignmentFiles = []
+OutFile = "OutFile"
+
+for Line in File1:
+ Line = Line.strip("\n")
+ AlignmentFiles.append(Line)
+File1.close()
+
+X = 1
+call("supermatrix.py " + AlignmentFiles[0] + " " + AlignmentFiles[1] + " " + OutFile + str(X), shell=True)
+
+AlignmentFiles = AlignmentFiles[2:]
+
+for Alignment in AlignmentFiles:
+ Y = X + 1
+ call("supermatrix.py " + OutFile + str(X) + " " + Alignment + " " + OutFile + str(Y), shell=True)
+ X = X + 1
+
+
+
From 859b51945f35c526faece36c4505c7dd00a7e7e6 Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Fri, 10 Feb 2023 13:40:21 -0500
Subject: [PATCH 06/36] Update table_of_contents.csv
---
table_of_contents.csv | 1 +
1 file changed, 1 insertion(+)
diff --git a/table_of_contents.csv b/table_of_contents.csv
index 57d8466..2c09373 100644
--- a/table_of_contents.csv
+++ b/table_of_contents.csv
@@ -3,3 +3,4 @@ Script Name,Subdirectory location,Inputs,Outputs,Language,Dependencies,General D
convert_csv_to_markdown.pl,File_Utilities,.csv (comma seperated table),.mrkd (markdown formatted table),perl,none,Converts a csv table using commas as the seperator to a markdown formatted table,Sophia Gosselin,In,markdown/csv,21_10_13,N/A
renaming_utilities.ipynb,File_Utilities,fasta/newick,fasta/newick,python,
varsnps.sh,Other,.fastq/fastq.gz,.bcf/.vcf,Unix,none,Finds variants using read data,Yutian Feng,In,variants/vcf/bcf,10/02/2023,N/A
+wrapper_supermatrix.py/supermatrix.py,Seq_Utilities,.fasta,.fasta (aligned),Python,none,makes a concatenate of all your gene clusters,Yutian Feng,In,concatenate/msa,10/02/2023,N/A
From 7a9ab6eb1128c9a492b3e0dc01e459271cec05bc Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Fri, 10 Feb 2023 14:18:13 -0500
Subject: [PATCH 07/36] find origin of replication using GC skew
---
Other/ori_analy.py | 78 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 78 insertions(+)
create mode 100644 Other/ori_analy.py
diff --git a/Other/ori_analy.py b/Other/ori_analy.py
new file mode 100644
index 0000000..3e1c9e4
--- /dev/null
+++ b/Other/ori_analy.py
@@ -0,0 +1,78 @@
+### analyze the origin of replication in archaea (haloarchaea at least)
+
+#####assumes you have: *fna of the genomes (single line), blast file with hits to cdc6 (origin) from the genomes
+####usage: ori_analy.py $blastfile $motif[any nt/aa motif]
+#output: dict with origins, *.csv file with clusters of motifs
+
+#read in whole genome seqs
+all_storage = {}
+for fna in glob.glob("*.fna"):
+ storage = {}
+ contig = ""
+ seq = ""
+ with open(fna) as ofh:
+
+ for line in ofh:
+ if not line:
+ continue
+ line = line.strip()
+ if line.startswith(">"):
+ contig = line[1:].split(" ")[0]
+ else:
+ seq = line
+ storage[contig] = seq
+ all_storage[fna] = storage
+
+
+#read in ori data from blast file with hits to cdc6
+#you need to edit the sstart ssend indexes to match your blast output (and maybe the genome name depending on how you want it displayed (cosmetic))
+ori_locs = {}
+with open(sys.argv[0]) as ofh:
+
+ for line in ofh:
+ if not line:
+ continue
+ line = line.strip()
+ genome = line.split("\t")[0].replace(":", "_")
+ sstart = line.split("\t")[2]
+ send = line.split("\t")[3]
+ if int(send) - int(sstart) < 0:
+ ori_locs[genome] = send
+ if int(send) - int(sstart) > 0:
+ ori_locs[genome] = sstart
+
+
+#this gets the contigs that contain the ori
+cdc6_conts = ori_locs.keys()
+
+actually_matters = {}
+for genomes, contigs in all_storage.items():
+ for name, seq in contigs.items():
+ if name in cdc6_conts:
+ actually_matters[name] = seq
+
+
+
+## this function can find motifs [any nucleotide/AA] of interest
+def motif_calc(sys.argv[1])
+ motifs = {}
+ for contig, seq in actually_matters.items():
+ ctags = [m.start() for m in re.finditer(sys.argv[1], seq)]
+ motifs[contig] = ctags
+
+
+# this will find clusters of your motif within the region of interest
+clustered_ctags = {}
+for contigs, region in ori_locs.items():
+ tmp_list = []
+ for inds in motifs[contigs]:
+ numba = (int(inds)-int(region))
+ if -10000 <= numba <= 10000:
+ tmp_list.append(numba)
+ clustered_ctags[contigs] = tmp_list
+
+
+for contig, motifs in clustered_ctags.items():
+ print("{} \t {} \t {} \t {}".format(contig, len(motifs), len(ctag_motifs[contig]),
+ len(actually_matters[contig])),
+ file=open("ori_motif_stats.tab", 'a'))
\ No newline at end of file
From eea8b162a570df1e9a288df6cf04bc51edfadc54 Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Fri, 10 Feb 2023 14:19:49 -0500
Subject: [PATCH 08/36] Update table_of_contents.csv
---
table_of_contents.csv | 1 +
1 file changed, 1 insertion(+)
diff --git a/table_of_contents.csv b/table_of_contents.csv
index 2c09373..f7d0872 100644
--- a/table_of_contents.csv
+++ b/table_of_contents.csv
@@ -4,3 +4,4 @@ convert_csv_to_markdown.pl,File_Utilities,.csv (comma seperated table),.mrkd (ma
renaming_utilities.ipynb,File_Utilities,fasta/newick,fasta/newick,python,
varsnps.sh,Other,.fastq/fastq.gz,.bcf/.vcf,Unix,none,Finds variants using read data,Yutian Feng,In,variants/vcf/bcf,10/02/2023,N/A
wrapper_supermatrix.py/supermatrix.py,Seq_Utilities,.fasta,.fasta (aligned),Python,none,makes a concatenate of all your gene clusters,Yutian Feng,In,concatenate/msa,10/02/2023,N/A
+ori_analy.py,Other,genomic.fna,.pdf/.svg/.png,python,none, find the origin of replication using gc skew,Yutian Feng,In,ori/gc skew,10/02/2023,N/A
From 32647c11b14b767efc12f8095e580eefb6fe9152 Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Fri, 10 Feb 2023 14:27:34 -0500
Subject: [PATCH 09/36] find evolutionary trajectories different in the same
genome
---
Phylogenetic_Utilities/gene_fam_upload.ipynb | 4023 ++++++++++++++++++
1 file changed, 4023 insertions(+)
create mode 100644 Phylogenetic_Utilities/gene_fam_upload.ipynb
diff --git a/Phylogenetic_Utilities/gene_fam_upload.ipynb b/Phylogenetic_Utilities/gene_fam_upload.ipynb
new file mode 100644
index 0000000..9b30b27
--- /dev/null
+++ b/Phylogenetic_Utilities/gene_fam_upload.ipynb
@@ -0,0 +1,4023 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Instructions for use\n",
+ "\n",
+ "Input: a directory with pairwise distance matrices and phylogenies for aligned gene families (with file extension *.mldist and *.treefile)\n",
+ "Output: a distance matrix describing the pairwise relationships b/n gene families\n",
+ "\n",
+ "You can then Run -> ALL or run each cell individually"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/home/tian/anaconda3/lib/python3.6/site-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.\n",
+ " from ._conv import register_converters as _register_converters\n"
+ ]
+ }
+ ],
+ "source": [
+ "import ete3\n",
+ "import random\n",
+ "import pymc3 as pm\n",
+ "from matplotlib import pyplot as plt\n",
+ "import seaborn as sns\n",
+ "import numpy as np\n",
+ "import shutil\n",
+ "import pandas as pd\n",
+ "from scipy.spatial.distance import squareform\n",
+ "from scipy.stats import pearsonr\n",
+ "import os\n",
+ "import subprocess\n",
+ "from itertools import product, combinations\n",
+ "import community\n",
+ "from sklearn.linear_model import HuberRegressor as hr, LinearRegression as lr, BayesianRidge as br\n",
+ "import statsmodels.api as sm\n",
+ "import glob"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "class cd:\n",
+ " \"\"\"\n",
+ " Context manager for changing the current working directory\n",
+ " \"\"\"\n",
+ " def __init__(self, newPath):\n",
+ " self.newPath = os.path.expanduser(newPath)\n",
+ "\n",
+ " def __enter__(self):\n",
+ " self.savedPath = os.getcwd()\n",
+ " os.chdir(self.newPath)\n",
+ "\n",
+ " def __exit__(self, etype, value, traceback):\n",
+ " os.chdir(self.savedPath)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 73,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "topologies = []\n",
+ "\n",
+ "for treenames in glob.glob(\"*.treefile\"):\n",
+ " \n",
+ " tree = ete3.Tree(treenames)\n",
+ " topologies.append(tree.copy())\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "topol"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import glob\n",
+ "\n",
+ "distance_matrices = {}\n",
+ "missing_matrices = {}\n",
+ " \n",
+ "treefiles = []\n",
+ "for distfile in glob.glob(\"*.mldist\"):\n",
+ " treefiles.append(distfile.split('.')[0])\n",
+ "\n",
+ " indexes = []\n",
+ " values = []\n",
+ " for line in open(distfile).readlines()[1:]:\n",
+ " line = line.split()\n",
+ " indexes.append(line[0])\n",
+ " values.append(line[1:])\n",
+ " \n",
+ " distance_matrices[distfile.split('.')[0]] = pd.DataFrame(index=indexes, columns=indexes, data=values, dtype=float\n",
+ " ).reindex(index=taxa, columns=taxa)\n",
+ " missing_matrices[distfile.split('.')[0]] = pd.DataFrame(index=indexes, columns=indexes, data=values, dtype=float\n",
+ " ).reindex(index=taxa, columns=taxa)\n",
+ "\n",
+ "#distance_matrices[\"30S_ribosomal_proteidis\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "
\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " 30S_ribosomal_protei | \n",
+ " 30S_ribosomal_protei | \n",
+ " 50S_ribosomal_protei | \n",
+ " 50S_ribosomal_protei | \n",
+ " cmk | \n",
+ " cysD | \n",
+ " flpA | \n",
+ " ftsH | \n",
+ " 50S_ribosomal_protei | \n",
+ " hisS | \n",
+ " ... | \n",
+ " tpiA | \n",
+ " trkA | \n",
+ " trm1 | \n",
+ " tRNA_cytidine562 | \n",
+ " trpS | \n",
+ " truB | \n",
+ " tuf | \n",
+ " wtpC | \n",
+ " ychF | \n",
+ " zupT | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 30S_ribosomal_protei | \n",
+ " 0 | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " 3 | \n",
+ " 4 | \n",
+ " 5 | \n",
+ " 6 | \n",
+ " 7 | \n",
+ " 8 | \n",
+ " 9 | \n",
+ " ... | \n",
+ " 272 | \n",
+ " 273 | \n",
+ " 274 | \n",
+ " 275 | \n",
+ " 276 | \n",
+ " 277 | \n",
+ " 278 | \n",
+ " 279 | \n",
+ " 280 | \n",
+ " 281 | \n",
+ "
\n",
+ " \n",
+ " | 30S_ribosomal_protei | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " 3 | \n",
+ " 4 | \n",
+ " 5 | \n",
+ " 6 | \n",
+ " 7 | \n",
+ " 8 | \n",
+ " ... | \n",
+ " 271 | \n",
+ " 272 | \n",
+ " 273 | \n",
+ " 274 | \n",
+ " 275 | \n",
+ " 276 | \n",
+ " 277 | \n",
+ " 278 | \n",
+ " 279 | \n",
+ " 280 | \n",
+ "
\n",
+ " \n",
+ " | 50S_ribosomal_protei | \n",
+ " 2 | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " 3 | \n",
+ " 4 | \n",
+ " 5 | \n",
+ " 6 | \n",
+ " 7 | \n",
+ " ... | \n",
+ " 270 | \n",
+ " 271 | \n",
+ " 272 | \n",
+ " 273 | \n",
+ " 274 | \n",
+ " 275 | \n",
+ " 276 | \n",
+ " 277 | \n",
+ " 278 | \n",
+ " 279 | \n",
+ "
\n",
+ " \n",
+ " | 50S_ribosomal_protei | \n",
+ " 3 | \n",
+ " 2 | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " 3 | \n",
+ " 4 | \n",
+ " 5 | \n",
+ " 6 | \n",
+ " ... | \n",
+ " 269 | \n",
+ " 270 | \n",
+ " 271 | \n",
+ " 272 | \n",
+ " 273 | \n",
+ " 274 | \n",
+ " 275 | \n",
+ " 276 | \n",
+ " 277 | \n",
+ " 278 | \n",
+ "
\n",
+ " \n",
+ " | cmk | \n",
+ " 4 | \n",
+ " 3 | \n",
+ " 2 | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " 3 | \n",
+ " 4 | \n",
+ " 5 | \n",
+ " ... | \n",
+ " 268 | \n",
+ " 269 | \n",
+ " 270 | \n",
+ " 271 | \n",
+ " 272 | \n",
+ " 273 | \n",
+ " 274 | \n",
+ " 275 | \n",
+ " 276 | \n",
+ " 277 | \n",
+ "
\n",
+ " \n",
+ " | cysD | \n",
+ " 5 | \n",
+ " 4 | \n",
+ " 3 | \n",
+ " 2 | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " 3 | \n",
+ " 4 | \n",
+ " ... | \n",
+ " 267 | \n",
+ " 268 | \n",
+ " 269 | \n",
+ " 270 | \n",
+ " 271 | \n",
+ " 272 | \n",
+ " 273 | \n",
+ " 274 | \n",
+ " 275 | \n",
+ " 276 | \n",
+ "
\n",
+ " \n",
+ " | flpA | \n",
+ " 6 | \n",
+ " 5 | \n",
+ " 4 | \n",
+ " 3 | \n",
+ " 2 | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " 3 | \n",
+ " ... | \n",
+ " 266 | \n",
+ " 267 | \n",
+ " 268 | \n",
+ " 269 | \n",
+ " 270 | \n",
+ " 271 | \n",
+ " 272 | \n",
+ " 273 | \n",
+ " 274 | \n",
+ " 275 | \n",
+ "
\n",
+ " \n",
+ " | ftsH | \n",
+ " 7 | \n",
+ " 6 | \n",
+ " 5 | \n",
+ " 4 | \n",
+ " 3 | \n",
+ " 2 | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " ... | \n",
+ " 265 | \n",
+ " 266 | \n",
+ " 267 | \n",
+ " 268 | \n",
+ " 269 | \n",
+ " 270 | \n",
+ " 271 | \n",
+ " 272 | \n",
+ " 273 | \n",
+ " 274 | \n",
+ "
\n",
+ " \n",
+ " | 50S_ribosomal_protei | \n",
+ " 8 | \n",
+ " 7 | \n",
+ " 6 | \n",
+ " 5 | \n",
+ " 4 | \n",
+ " 3 | \n",
+ " 2 | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " 1 | \n",
+ " ... | \n",
+ " 264 | \n",
+ " 265 | \n",
+ " 266 | \n",
+ " 267 | \n",
+ " 268 | \n",
+ " 269 | \n",
+ " 270 | \n",
+ " 271 | \n",
+ " 272 | \n",
+ " 273 | \n",
+ "
\n",
+ " \n",
+ " | hisS | \n",
+ " 9 | \n",
+ " 8 | \n",
+ " 7 | \n",
+ " 6 | \n",
+ " 5 | \n",
+ " 4 | \n",
+ " 3 | \n",
+ " 2 | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " ... | \n",
+ " 263 | \n",
+ " 264 | \n",
+ " 265 | \n",
+ " 266 | \n",
+ " 267 | \n",
+ " 268 | \n",
+ " 269 | \n",
+ " 270 | \n",
+ " 271 | \n",
+ " 272 | \n",
+ "
\n",
+ " \n",
+ " | hmtA1 | \n",
+ " 10 | \n",
+ " 9 | \n",
+ " 8 | \n",
+ " 7 | \n",
+ " 6 | \n",
+ " 5 | \n",
+ " 4 | \n",
+ " 3 | \n",
+ " 2 | \n",
+ " 1 | \n",
+ " ... | \n",
+ " 262 | \n",
+ " 263 | \n",
+ " 264 | \n",
+ " 265 | \n",
+ " 266 | \n",
+ " 267 | \n",
+ " 268 | \n",
+ " 269 | \n",
+ " 270 | \n",
+ " 271 | \n",
+ "
\n",
+ " \n",
+ " | hypothetical_protein_109 | \n",
+ " 11 | \n",
+ " 10 | \n",
+ " 9 | \n",
+ " 8 | \n",
+ " 7 | \n",
+ " 6 | \n",
+ " 5 | \n",
+ " 4 | \n",
+ " 3 | \n",
+ " 2 | \n",
+ " ... | \n",
+ " 261 | \n",
+ " 262 | \n",
+ " 263 | \n",
+ " 264 | \n",
+ " 265 | \n",
+ " 266 | \n",
+ " 267 | \n",
+ " 268 | \n",
+ " 269 | \n",
+ " 270 | \n",
+ "
\n",
+ " \n",
+ " | hypothetical_protein_11 | \n",
+ " 12 | \n",
+ " 11 | \n",
+ " 10 | \n",
+ " 9 | \n",
+ " 8 | \n",
+ " 7 | \n",
+ " 6 | \n",
+ " 5 | \n",
+ " 4 | \n",
+ " 3 | \n",
+ " ... | \n",
+ " 260 | \n",
+ " 261 | \n",
+ " 262 | \n",
+ " 263 | \n",
+ " 264 | \n",
+ " 265 | \n",
+ " 266 | \n",
+ " 267 | \n",
+ " 268 | \n",
+ " 269 | \n",
+ "
\n",
+ " \n",
+ " | hypothetical_protein_120 | \n",
+ " 13 | \n",
+ " 12 | \n",
+ " 11 | \n",
+ " 10 | \n",
+ " 9 | \n",
+ " 8 | \n",
+ " 7 | \n",
+ " 6 | \n",
+ " 5 | \n",
+ " 4 | \n",
+ " ... | \n",
+ " 259 | \n",
+ " 260 | \n",
+ " 261 | \n",
+ " 262 | \n",
+ " 263 | \n",
+ " 264 | \n",
+ " 265 | \n",
+ " 266 | \n",
+ " 267 | \n",
+ " 268 | \n",
+ "
\n",
+ " \n",
+ " | hypothetical_protein_22 | \n",
+ " 14 | \n",
+ " 13 | \n",
+ " 12 | \n",
+ " 11 | \n",
+ " 10 | \n",
+ " 9 | \n",
+ " 8 | \n",
+ " 7 | \n",
+ " 6 | \n",
+ " 5 | \n",
+ " ... | \n",
+ " 258 | \n",
+ " 259 | \n",
+ " 260 | \n",
+ " 261 | \n",
+ " 262 | \n",
+ " 263 | \n",
+ " 264 | \n",
+ " 265 | \n",
+ " 266 | \n",
+ " 267 | \n",
+ "
\n",
+ " \n",
+ " | hypothetical_protein_23 | \n",
+ " 15 | \n",
+ " 14 | \n",
+ " 13 | \n",
+ " 12 | \n",
+ " 11 | \n",
+ " 10 | \n",
+ " 9 | \n",
+ " 8 | \n",
+ " 7 | \n",
+ " 6 | \n",
+ " ... | \n",
+ " 257 | \n",
+ " 258 | \n",
+ " 259 | \n",
+ " 260 | \n",
+ " 261 | \n",
+ " 262 | \n",
+ " 263 | \n",
+ " 264 | \n",
+ " 265 | \n",
+ " 266 | \n",
+ "
\n",
+ " \n",
+ " | hypothetical_protein_35 | \n",
+ " 16 | \n",
+ " 15 | \n",
+ " 14 | \n",
+ " 13 | \n",
+ " 12 | \n",
+ " 11 | \n",
+ " 10 | \n",
+ " 9 | \n",
+ " 8 | \n",
+ " 7 | \n",
+ " ... | \n",
+ " 256 | \n",
+ " 257 | \n",
+ " 258 | \n",
+ " 259 | \n",
+ " 260 | \n",
+ " 261 | \n",
+ " 262 | \n",
+ " 263 | \n",
+ " 264 | \n",
+ " 265 | \n",
+ "
\n",
+ " \n",
+ " | hypothetical_protein_48 | \n",
+ " 17 | \n",
+ " 16 | \n",
+ " 15 | \n",
+ " 14 | \n",
+ " 13 | \n",
+ " 12 | \n",
+ " 11 | \n",
+ " 10 | \n",
+ " 9 | \n",
+ " 8 | \n",
+ " ... | \n",
+ " 255 | \n",
+ " 256 | \n",
+ " 257 | \n",
+ " 258 | \n",
+ " 259 | \n",
+ " 260 | \n",
+ " 261 | \n",
+ " 262 | \n",
+ " 263 | \n",
+ " 264 | \n",
+ "
\n",
+ " \n",
+ " | hypothetical_protein_60 | \n",
+ " 18 | \n",
+ " 17 | \n",
+ " 16 | \n",
+ " 15 | \n",
+ " 14 | \n",
+ " 13 | \n",
+ " 12 | \n",
+ " 11 | \n",
+ " 10 | \n",
+ " 9 | \n",
+ " ... | \n",
+ " 254 | \n",
+ " 255 | \n",
+ " 256 | \n",
+ " 257 | \n",
+ " 258 | \n",
+ " 259 | \n",
+ " 260 | \n",
+ " 261 | \n",
+ " 262 | \n",
+ " 263 | \n",
+ "
\n",
+ " \n",
+ " | hypothetical_protein_73 | \n",
+ " 19 | \n",
+ " 18 | \n",
+ " 17 | \n",
+ " 16 | \n",
+ " 15 | \n",
+ " 14 | \n",
+ " 13 | \n",
+ " 12 | \n",
+ " 11 | \n",
+ " 10 | \n",
+ " ... | \n",
+ " 253 | \n",
+ " 254 | \n",
+ " 255 | \n",
+ " 256 | \n",
+ " 257 | \n",
+ " 258 | \n",
+ " 259 | \n",
+ " 260 | \n",
+ " 261 | \n",
+ " 262 | \n",
+ "
\n",
+ " \n",
+ " | hypothetical_protein_86 | \n",
+ " 20 | \n",
+ " 19 | \n",
+ " 18 | \n",
+ " 17 | \n",
+ " 16 | \n",
+ " 15 | \n",
+ " 14 | \n",
+ " 13 | \n",
+ " 12 | \n",
+ " 11 | \n",
+ " ... | \n",
+ " 252 | \n",
+ " 253 | \n",
+ " 254 | \n",
+ " 255 | \n",
+ " 256 | \n",
+ " 257 | \n",
+ " 258 | \n",
+ " 259 | \n",
+ " 260 | \n",
+ " 261 | \n",
+ "
\n",
+ " \n",
+ " | hypothetical_protein_87 | \n",
+ " 21 | \n",
+ " 20 | \n",
+ " 19 | \n",
+ " 18 | \n",
+ " 17 | \n",
+ " 16 | \n",
+ " 15 | \n",
+ " 14 | \n",
+ " 13 | \n",
+ " 12 | \n",
+ " ... | \n",
+ " 251 | \n",
+ " 252 | \n",
+ " 253 | \n",
+ " 254 | \n",
+ " 255 | \n",
+ " 256 | \n",
+ " 257 | \n",
+ " 258 | \n",
+ " 259 | \n",
+ " 260 | \n",
+ "
\n",
+ " \n",
+ " | Ironsulfur_cluster_ | \n",
+ " 22 | \n",
+ " 21 | \n",
+ " 20 | \n",
+ " 19 | \n",
+ " 18 | \n",
+ " 17 | \n",
+ " 16 | \n",
+ " 15 | \n",
+ " 14 | \n",
+ " 13 | \n",
+ " ... | \n",
+ " 250 | \n",
+ " 251 | \n",
+ " 252 | \n",
+ " 253 | \n",
+ " 254 | \n",
+ " 255 | \n",
+ " 256 | \n",
+ " 257 | \n",
+ " 258 | \n",
+ " 259 | \n",
+ "
\n",
+ " \n",
+ " | iscU2 | \n",
+ " 23 | \n",
+ " 22 | \n",
+ " 21 | \n",
+ " 20 | \n",
+ " 19 | \n",
+ " 18 | \n",
+ " 17 | \n",
+ " 16 | \n",
+ " 15 | \n",
+ " 14 | \n",
+ " ... | \n",
+ " 249 | \n",
+ " 250 | \n",
+ " 251 | \n",
+ " 252 | \n",
+ " 253 | \n",
+ " 254 | \n",
+ " 255 | \n",
+ " 256 | \n",
+ " 257 | \n",
+ " 258 | \n",
+ "
\n",
+ " \n",
+ " | pcn | \n",
+ " 24 | \n",
+ " 23 | \n",
+ " 22 | \n",
+ " 21 | \n",
+ " 20 | \n",
+ " 19 | \n",
+ " 18 | \n",
+ " 17 | \n",
+ " 16 | \n",
+ " 15 | \n",
+ " ... | \n",
+ " 248 | \n",
+ " 249 | \n",
+ " 250 | \n",
+ " 251 | \n",
+ " 252 | \n",
+ " 253 | \n",
+ " 254 | \n",
+ " 255 | \n",
+ " 256 | \n",
+ " 257 | \n",
+ "
\n",
+ " \n",
+ " | pelA | \n",
+ " 25 | \n",
+ " 24 | \n",
+ " 23 | \n",
+ " 22 | \n",
+ " 21 | \n",
+ " 20 | \n",
+ " 19 | \n",
+ " 18 | \n",
+ " 17 | \n",
+ " 16 | \n",
+ " ... | \n",
+ " 247 | \n",
+ " 248 | \n",
+ " 249 | \n",
+ " 250 | \n",
+ " 251 | \n",
+ " 252 | \n",
+ " 253 | \n",
+ " 254 | \n",
+ " 255 | \n",
+ " 256 | \n",
+ "
\n",
+ " \n",
+ " | Putative_FKBPtype_p | \n",
+ " 26 | \n",
+ " 25 | \n",
+ " 24 | \n",
+ " 23 | \n",
+ " 22 | \n",
+ " 21 | \n",
+ " 20 | \n",
+ " 19 | \n",
+ " 18 | \n",
+ " 17 | \n",
+ " ... | \n",
+ " 246 | \n",
+ " 247 | \n",
+ " 248 | \n",
+ " 249 | \n",
+ " 250 | \n",
+ " 251 | \n",
+ " 252 | \n",
+ " 253 | \n",
+ " 254 | \n",
+ " 255 | \n",
+ "
\n",
+ " \n",
+ " | putative_KH_and_PIN | \n",
+ " 27 | \n",
+ " 26 | \n",
+ " 25 | \n",
+ " 24 | \n",
+ " 23 | \n",
+ " 22 | \n",
+ " 21 | \n",
+ " 20 | \n",
+ " 19 | \n",
+ " 18 | \n",
+ " ... | \n",
+ " 245 | \n",
+ " 246 | \n",
+ " 247 | \n",
+ " 248 | \n",
+ " 249 | \n",
+ " 250 | \n",
+ " 251 | \n",
+ " 252 | \n",
+ " 253 | \n",
+ " 254 | \n",
+ "
\n",
+ " \n",
+ " | rpa | \n",
+ " 28 | \n",
+ " 27 | \n",
+ " 26 | \n",
+ " 25 | \n",
+ " 24 | \n",
+ " 23 | \n",
+ " 22 | \n",
+ " 21 | \n",
+ " 20 | \n",
+ " 19 | \n",
+ " ... | \n",
+ " 244 | \n",
+ " 245 | \n",
+ " 246 | \n",
+ " 247 | \n",
+ " 248 | \n",
+ " 249 | \n",
+ " 250 | \n",
+ " 251 | \n",
+ " 252 | \n",
+ " 253 | \n",
+ "
\n",
+ " \n",
+ " | rpl5 | \n",
+ " 29 | \n",
+ " 28 | \n",
+ " 27 | \n",
+ " 26 | \n",
+ " 25 | \n",
+ " 24 | \n",
+ " 23 | \n",
+ " 22 | \n",
+ " 21 | \n",
+ " 20 | \n",
+ " ... | \n",
+ " 243 | \n",
+ " 244 | \n",
+ " 245 | \n",
+ " 246 | \n",
+ " 247 | \n",
+ " 248 | \n",
+ " 249 | \n",
+ " 250 | \n",
+ " 251 | \n",
+ " 252 | \n",
+ "
\n",
+ " \n",
+ " | ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ "
\n",
+ " \n",
+ " | rps5 | \n",
+ " 252 | \n",
+ " 251 | \n",
+ " 250 | \n",
+ " 249 | \n",
+ " 248 | \n",
+ " 247 | \n",
+ " 246 | \n",
+ " 245 | \n",
+ " 244 | \n",
+ " 243 | \n",
+ " ... | \n",
+ " 20 | \n",
+ " 21 | \n",
+ " 22 | \n",
+ " 23 | \n",
+ " 24 | \n",
+ " 25 | \n",
+ " 26 | \n",
+ " 27 | \n",
+ " 28 | \n",
+ " 29 | \n",
+ "
\n",
+ " \n",
+ " | rps6e | \n",
+ " 253 | \n",
+ " 252 | \n",
+ " 251 | \n",
+ " 250 | \n",
+ " 249 | \n",
+ " 248 | \n",
+ " 247 | \n",
+ " 246 | \n",
+ " 245 | \n",
+ " 244 | \n",
+ " ... | \n",
+ " 19 | \n",
+ " 20 | \n",
+ " 21 | \n",
+ " 22 | \n",
+ " 23 | \n",
+ " 24 | \n",
+ " 25 | \n",
+ " 26 | \n",
+ " 27 | \n",
+ " 28 | \n",
+ "
\n",
+ " \n",
+ " | rps7 | \n",
+ " 254 | \n",
+ " 253 | \n",
+ " 252 | \n",
+ " 251 | \n",
+ " 250 | \n",
+ " 249 | \n",
+ " 248 | \n",
+ " 247 | \n",
+ " 246 | \n",
+ " 245 | \n",
+ " ... | \n",
+ " 18 | \n",
+ " 19 | \n",
+ " 20 | \n",
+ " 21 | \n",
+ " 22 | \n",
+ " 23 | \n",
+ " 24 | \n",
+ " 25 | \n",
+ " 26 | \n",
+ " 27 | \n",
+ "
\n",
+ " \n",
+ " | rps8 | \n",
+ " 255 | \n",
+ " 254 | \n",
+ " 253 | \n",
+ " 252 | \n",
+ " 251 | \n",
+ " 250 | \n",
+ " 249 | \n",
+ " 248 | \n",
+ " 247 | \n",
+ " 246 | \n",
+ " ... | \n",
+ " 17 | \n",
+ " 18 | \n",
+ " 19 | \n",
+ " 20 | \n",
+ " 21 | \n",
+ " 22 | \n",
+ " 23 | \n",
+ " 24 | \n",
+ " 25 | \n",
+ " 26 | \n",
+ "
\n",
+ " \n",
+ " | rps8e | \n",
+ " 256 | \n",
+ " 255 | \n",
+ " 254 | \n",
+ " 253 | \n",
+ " 252 | \n",
+ " 251 | \n",
+ " 250 | \n",
+ " 249 | \n",
+ " 248 | \n",
+ " 247 | \n",
+ " ... | \n",
+ " 16 | \n",
+ " 17 | \n",
+ " 18 | \n",
+ " 19 | \n",
+ " 20 | \n",
+ " 21 | \n",
+ " 22 | \n",
+ " 23 | \n",
+ " 24 | \n",
+ " 25 | \n",
+ "
\n",
+ " \n",
+ " | sod1 | \n",
+ " 257 | \n",
+ " 256 | \n",
+ " 255 | \n",
+ " 254 | \n",
+ " 253 | \n",
+ " 252 | \n",
+ " 251 | \n",
+ " 250 | \n",
+ " 249 | \n",
+ " 248 | \n",
+ " ... | \n",
+ " 15 | \n",
+ " 16 | \n",
+ " 17 | \n",
+ " 18 | \n",
+ " 19 | \n",
+ " 20 | \n",
+ " 21 | \n",
+ " 22 | \n",
+ " 23 | \n",
+ " 24 | \n",
+ "
\n",
+ " \n",
+ " | spt4 | \n",
+ " 258 | \n",
+ " 257 | \n",
+ " 256 | \n",
+ " 255 | \n",
+ " 254 | \n",
+ " 253 | \n",
+ " 252 | \n",
+ " 251 | \n",
+ " 250 | \n",
+ " 249 | \n",
+ " ... | \n",
+ " 14 | \n",
+ " 15 | \n",
+ " 16 | \n",
+ " 17 | \n",
+ " 18 | \n",
+ " 19 | \n",
+ " 20 | \n",
+ " 21 | \n",
+ " 22 | \n",
+ " 23 | \n",
+ "
\n",
+ " \n",
+ " | secF | \n",
+ " 259 | \n",
+ " 258 | \n",
+ " 257 | \n",
+ " 256 | \n",
+ " 255 | \n",
+ " 254 | \n",
+ " 253 | \n",
+ " 252 | \n",
+ " 251 | \n",
+ " 250 | \n",
+ " ... | \n",
+ " 13 | \n",
+ " 14 | \n",
+ " 15 | \n",
+ " 16 | \n",
+ " 17 | \n",
+ " 18 | \n",
+ " 19 | \n",
+ " 20 | \n",
+ " 21 | \n",
+ " 22 | \n",
+ "
\n",
+ " \n",
+ " | serS | \n",
+ " 260 | \n",
+ " 259 | \n",
+ " 258 | \n",
+ " 257 | \n",
+ " 256 | \n",
+ " 255 | \n",
+ " 254 | \n",
+ " 253 | \n",
+ " 252 | \n",
+ " 251 | \n",
+ " ... | \n",
+ " 12 | \n",
+ " 13 | \n",
+ " 14 | \n",
+ " 15 | \n",
+ " 16 | \n",
+ " 17 | \n",
+ " 18 | \n",
+ " 19 | \n",
+ " 20 | \n",
+ " 21 | \n",
+ "
\n",
+ " \n",
+ " | Signal_recognition_p | \n",
+ " 261 | \n",
+ " 260 | \n",
+ " 259 | \n",
+ " 258 | \n",
+ " 257 | \n",
+ " 256 | \n",
+ " 255 | \n",
+ " 254 | \n",
+ " 253 | \n",
+ " 252 | \n",
+ " ... | \n",
+ " 11 | \n",
+ " 12 | \n",
+ " 13 | \n",
+ " 14 | \n",
+ " 15 | \n",
+ " 16 | \n",
+ " 17 | \n",
+ " 18 | \n",
+ " 19 | \n",
+ " 20 | \n",
+ "
\n",
+ " \n",
+ " | sua5 | \n",
+ " 262 | \n",
+ " 261 | \n",
+ " 260 | \n",
+ " 259 | \n",
+ " 258 | \n",
+ " 257 | \n",
+ " 256 | \n",
+ " 255 | \n",
+ " 254 | \n",
+ " 253 | \n",
+ " ... | \n",
+ " 10 | \n",
+ " 11 | \n",
+ " 12 | \n",
+ " 13 | \n",
+ " 14 | \n",
+ " 15 | \n",
+ " 16 | \n",
+ " 17 | \n",
+ " 18 | \n",
+ " 19 | \n",
+ "
\n",
+ " \n",
+ " | sucD | \n",
+ " 263 | \n",
+ " 262 | \n",
+ " 261 | \n",
+ " 260 | \n",
+ " 259 | \n",
+ " 258 | \n",
+ " 257 | \n",
+ " 256 | \n",
+ " 255 | \n",
+ " 254 | \n",
+ " ... | \n",
+ " 9 | \n",
+ " 10 | \n",
+ " 11 | \n",
+ " 12 | \n",
+ " 13 | \n",
+ " 14 | \n",
+ " 15 | \n",
+ " 16 | \n",
+ " 17 | \n",
+ " 18 | \n",
+ "
\n",
+ " \n",
+ " | sufS | \n",
+ " 264 | \n",
+ " 263 | \n",
+ " 262 | \n",
+ " 261 | \n",
+ " 260 | \n",
+ " 259 | \n",
+ " 258 | \n",
+ " 257 | \n",
+ " 256 | \n",
+ " 255 | \n",
+ " ... | \n",
+ " 8 | \n",
+ " 9 | \n",
+ " 10 | \n",
+ " 11 | \n",
+ " 12 | \n",
+ " 13 | \n",
+ " 14 | \n",
+ " 15 | \n",
+ " 16 | \n",
+ " 17 | \n",
+ "
\n",
+ " \n",
+ " | tatD | \n",
+ " 265 | \n",
+ " 264 | \n",
+ " 263 | \n",
+ " 262 | \n",
+ " 261 | \n",
+ " 260 | \n",
+ " 259 | \n",
+ " 258 | \n",
+ " 257 | \n",
+ " 256 | \n",
+ " ... | \n",
+ " 7 | \n",
+ " 8 | \n",
+ " 9 | \n",
+ " 10 | \n",
+ " 11 | \n",
+ " 12 | \n",
+ " 13 | \n",
+ " 14 | \n",
+ " 15 | \n",
+ " 16 | \n",
+ "
\n",
+ " \n",
+ " | tbp2 | \n",
+ " 266 | \n",
+ " 265 | \n",
+ " 264 | \n",
+ " 263 | \n",
+ " 262 | \n",
+ " 261 | \n",
+ " 260 | \n",
+ " 259 | \n",
+ " 258 | \n",
+ " 257 | \n",
+ " ... | \n",
+ " 6 | \n",
+ " 7 | \n",
+ " 8 | \n",
+ " 9 | \n",
+ " 10 | \n",
+ " 11 | \n",
+ " 12 | \n",
+ " 13 | \n",
+ " 14 | \n",
+ " 15 | \n",
+ "
\n",
+ " \n",
+ " | tfs | \n",
+ " 267 | \n",
+ " 266 | \n",
+ " 265 | \n",
+ " 264 | \n",
+ " 263 | \n",
+ " 262 | \n",
+ " 261 | \n",
+ " 260 | \n",
+ " 259 | \n",
+ " 258 | \n",
+ " ... | \n",
+ " 5 | \n",
+ " 6 | \n",
+ " 7 | \n",
+ " 8 | \n",
+ " 9 | \n",
+ " 10 | \n",
+ " 11 | \n",
+ " 12 | \n",
+ " 13 | \n",
+ " 14 | \n",
+ "
\n",
+ " \n",
+ " | tRNA_guanine10N2 | \n",
+ " 268 | \n",
+ " 267 | \n",
+ " 266 | \n",
+ " 265 | \n",
+ " 264 | \n",
+ " 263 | \n",
+ " 262 | \n",
+ " 261 | \n",
+ " 260 | \n",
+ " 259 | \n",
+ " ... | \n",
+ " 4 | \n",
+ " 5 | \n",
+ " 6 | \n",
+ " 7 | \n",
+ " 8 | \n",
+ " 9 | \n",
+ " 10 | \n",
+ " 11 | \n",
+ " 12 | \n",
+ " 13 | \n",
+ "
\n",
+ " \n",
+ " | tRNA_pseudouridine_s | \n",
+ " 269 | \n",
+ " 268 | \n",
+ " 267 | \n",
+ " 266 | \n",
+ " 265 | \n",
+ " 264 | \n",
+ " 263 | \n",
+ " 262 | \n",
+ " 261 | \n",
+ " 260 | \n",
+ " ... | \n",
+ " 3 | \n",
+ " 4 | \n",
+ " 5 | \n",
+ " 6 | \n",
+ " 7 | \n",
+ " 8 | \n",
+ " 9 | \n",
+ " 10 | \n",
+ " 11 | \n",
+ " 12 | \n",
+ "
\n",
+ " \n",
+ " | thyA | \n",
+ " 270 | \n",
+ " 269 | \n",
+ " 268 | \n",
+ " 267 | \n",
+ " 266 | \n",
+ " 265 | \n",
+ " 264 | \n",
+ " 263 | \n",
+ " 262 | \n",
+ " 261 | \n",
+ " ... | \n",
+ " 2 | \n",
+ " 3 | \n",
+ " 4 | \n",
+ " 5 | \n",
+ " 6 | \n",
+ " 7 | \n",
+ " 8 | \n",
+ " 9 | \n",
+ " 10 | \n",
+ " 11 | \n",
+ "
\n",
+ " \n",
+ " | top6B | \n",
+ " 271 | \n",
+ " 270 | \n",
+ " 269 | \n",
+ " 268 | \n",
+ " 267 | \n",
+ " 266 | \n",
+ " 265 | \n",
+ " 264 | \n",
+ " 263 | \n",
+ " 262 | \n",
+ " ... | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " 3 | \n",
+ " 4 | \n",
+ " 5 | \n",
+ " 6 | \n",
+ " 7 | \n",
+ " 8 | \n",
+ " 9 | \n",
+ " 10 | \n",
+ "
\n",
+ " \n",
+ " | tpiA | \n",
+ " 272 | \n",
+ " 271 | \n",
+ " 270 | \n",
+ " 269 | \n",
+ " 268 | \n",
+ " 267 | \n",
+ " 266 | \n",
+ " 265 | \n",
+ " 264 | \n",
+ " 263 | \n",
+ " ... | \n",
+ " 0 | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " 3 | \n",
+ " 4 | \n",
+ " 5 | \n",
+ " 6 | \n",
+ " 7 | \n",
+ " 8 | \n",
+ " 9 | \n",
+ "
\n",
+ " \n",
+ " | trkA | \n",
+ " 273 | \n",
+ " 272 | \n",
+ " 271 | \n",
+ " 270 | \n",
+ " 269 | \n",
+ " 268 | \n",
+ " 267 | \n",
+ " 266 | \n",
+ " 265 | \n",
+ " 264 | \n",
+ " ... | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " 3 | \n",
+ " 4 | \n",
+ " 5 | \n",
+ " 6 | \n",
+ " 7 | \n",
+ " 8 | \n",
+ "
\n",
+ " \n",
+ " | trm1 | \n",
+ " 274 | \n",
+ " 273 | \n",
+ " 272 | \n",
+ " 271 | \n",
+ " 270 | \n",
+ " 269 | \n",
+ " 268 | \n",
+ " 267 | \n",
+ " 266 | \n",
+ " 265 | \n",
+ " ... | \n",
+ " 2 | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " 3 | \n",
+ " 4 | \n",
+ " 5 | \n",
+ " 6 | \n",
+ " 7 | \n",
+ "
\n",
+ " \n",
+ " | tRNA_cytidine562 | \n",
+ " 275 | \n",
+ " 274 | \n",
+ " 273 | \n",
+ " 272 | \n",
+ " 271 | \n",
+ " 270 | \n",
+ " 269 | \n",
+ " 268 | \n",
+ " 267 | \n",
+ " 266 | \n",
+ " ... | \n",
+ " 3 | \n",
+ " 2 | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " 3 | \n",
+ " 4 | \n",
+ " 5 | \n",
+ " 6 | \n",
+ "
\n",
+ " \n",
+ " | trpS | \n",
+ " 276 | \n",
+ " 275 | \n",
+ " 274 | \n",
+ " 273 | \n",
+ " 272 | \n",
+ " 271 | \n",
+ " 270 | \n",
+ " 269 | \n",
+ " 268 | \n",
+ " 267 | \n",
+ " ... | \n",
+ " 4 | \n",
+ " 3 | \n",
+ " 2 | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " 3 | \n",
+ " 4 | \n",
+ " 5 | \n",
+ "
\n",
+ " \n",
+ " | truB | \n",
+ " 277 | \n",
+ " 276 | \n",
+ " 275 | \n",
+ " 274 | \n",
+ " 273 | \n",
+ " 272 | \n",
+ " 271 | \n",
+ " 270 | \n",
+ " 269 | \n",
+ " 268 | \n",
+ " ... | \n",
+ " 5 | \n",
+ " 4 | \n",
+ " 3 | \n",
+ " 2 | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " 3 | \n",
+ " 4 | \n",
+ "
\n",
+ " \n",
+ " | tuf | \n",
+ " 278 | \n",
+ " 277 | \n",
+ " 276 | \n",
+ " 275 | \n",
+ " 274 | \n",
+ " 273 | \n",
+ " 272 | \n",
+ " 271 | \n",
+ " 270 | \n",
+ " 269 | \n",
+ " ... | \n",
+ " 6 | \n",
+ " 5 | \n",
+ " 4 | \n",
+ " 3 | \n",
+ " 2 | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " 3 | \n",
+ "
\n",
+ " \n",
+ " | wtpC | \n",
+ " 279 | \n",
+ " 278 | \n",
+ " 277 | \n",
+ " 276 | \n",
+ " 275 | \n",
+ " 274 | \n",
+ " 273 | \n",
+ " 272 | \n",
+ " 271 | \n",
+ " 270 | \n",
+ " ... | \n",
+ " 7 | \n",
+ " 6 | \n",
+ " 5 | \n",
+ " 4 | \n",
+ " 3 | \n",
+ " 2 | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " 1 | \n",
+ " 2 | \n",
+ "
\n",
+ " \n",
+ " | ychF | \n",
+ " 280 | \n",
+ " 279 | \n",
+ " 278 | \n",
+ " 277 | \n",
+ " 276 | \n",
+ " 275 | \n",
+ " 274 | \n",
+ " 273 | \n",
+ " 272 | \n",
+ " 271 | \n",
+ " ... | \n",
+ " 8 | \n",
+ " 7 | \n",
+ " 6 | \n",
+ " 5 | \n",
+ " 4 | \n",
+ " 3 | \n",
+ " 2 | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " 1 | \n",
+ "
\n",
+ " \n",
+ " | zupT | \n",
+ " 281 | \n",
+ " 280 | \n",
+ " 279 | \n",
+ " 278 | \n",
+ " 277 | \n",
+ " 276 | \n",
+ " 275 | \n",
+ " 274 | \n",
+ " 273 | \n",
+ " 272 | \n",
+ " ... | \n",
+ " 9 | \n",
+ " 8 | \n",
+ " 7 | \n",
+ " 6 | \n",
+ " 5 | \n",
+ " 4 | \n",
+ " 3 | \n",
+ " 2 | \n",
+ " 1 | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
282 rows × 282 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " 30S_ribosomal_protei 30S_ribosomal_protei \\\n",
+ "30S_ribosomal_protei 0 1 \n",
+ "30S_ribosomal_protei 1 0 \n",
+ "50S_ribosomal_protei 2 1 \n",
+ "50S_ribosomal_protei 3 2 \n",
+ "cmk 4 3 \n",
+ "cysD 5 4 \n",
+ "flpA 6 5 \n",
+ "ftsH 7 6 \n",
+ "50S_ribosomal_protei 8 7 \n",
+ "hisS 9 8 \n",
+ "hmtA1 10 9 \n",
+ "hypothetical_protein_109 11 10 \n",
+ "hypothetical_protein_11 12 11 \n",
+ "hypothetical_protein_120 13 12 \n",
+ "hypothetical_protein_22 14 13 \n",
+ "hypothetical_protein_23 15 14 \n",
+ "hypothetical_protein_35 16 15 \n",
+ "hypothetical_protein_48 17 16 \n",
+ "hypothetical_protein_60 18 17 \n",
+ "hypothetical_protein_73 19 18 \n",
+ "hypothetical_protein_86 20 19 \n",
+ "hypothetical_protein_87 21 20 \n",
+ "Ironsulfur_cluster_ 22 21 \n",
+ "iscU2 23 22 \n",
+ "pcn 24 23 \n",
+ "pelA 25 24 \n",
+ "Putative_FKBPtype_p 26 25 \n",
+ "putative_KH_and_PIN 27 26 \n",
+ "rpa 28 27 \n",
+ "rpl5 29 28 \n",
+ "... ... ... \n",
+ "rps5 252 251 \n",
+ "rps6e 253 252 \n",
+ "rps7 254 253 \n",
+ "rps8 255 254 \n",
+ "rps8e 256 255 \n",
+ "sod1 257 256 \n",
+ "spt4 258 257 \n",
+ "secF 259 258 \n",
+ "serS 260 259 \n",
+ "Signal_recognition_p 261 260 \n",
+ "sua5 262 261 \n",
+ "sucD 263 262 \n",
+ "sufS 264 263 \n",
+ "tatD 265 264 \n",
+ "tbp2 266 265 \n",
+ "tfs 267 266 \n",
+ "tRNA_guanine10N2 268 267 \n",
+ "tRNA_pseudouridine_s 269 268 \n",
+ "thyA 270 269 \n",
+ "top6B 271 270 \n",
+ "tpiA 272 271 \n",
+ "trkA 273 272 \n",
+ "trm1 274 273 \n",
+ "tRNA_cytidine562 275 274 \n",
+ "trpS 276 275 \n",
+ "truB 277 276 \n",
+ "tuf 278 277 \n",
+ "wtpC 279 278 \n",
+ "ychF 280 279 \n",
+ "zupT 281 280 \n",
+ "\n",
+ " 50S_ribosomal_protei 50S_ribosomal_protei cmk \\\n",
+ "30S_ribosomal_protei 2 3 4 \n",
+ "30S_ribosomal_protei 1 2 3 \n",
+ "50S_ribosomal_protei 0 1 2 \n",
+ "50S_ribosomal_protei 1 0 1 \n",
+ "cmk 2 1 0 \n",
+ "cysD 3 2 1 \n",
+ "flpA 4 3 2 \n",
+ "ftsH 5 4 3 \n",
+ "50S_ribosomal_protei 6 5 4 \n",
+ "hisS 7 6 5 \n",
+ "hmtA1 8 7 6 \n",
+ "hypothetical_protein_109 9 8 7 \n",
+ "hypothetical_protein_11 10 9 8 \n",
+ "hypothetical_protein_120 11 10 9 \n",
+ "hypothetical_protein_22 12 11 10 \n",
+ "hypothetical_protein_23 13 12 11 \n",
+ "hypothetical_protein_35 14 13 12 \n",
+ "hypothetical_protein_48 15 14 13 \n",
+ "hypothetical_protein_60 16 15 14 \n",
+ "hypothetical_protein_73 17 16 15 \n",
+ "hypothetical_protein_86 18 17 16 \n",
+ "hypothetical_protein_87 19 18 17 \n",
+ "Ironsulfur_cluster_ 20 19 18 \n",
+ "iscU2 21 20 19 \n",
+ "pcn 22 21 20 \n",
+ "pelA 23 22 21 \n",
+ "Putative_FKBPtype_p 24 23 22 \n",
+ "putative_KH_and_PIN 25 24 23 \n",
+ "rpa 26 25 24 \n",
+ "rpl5 27 26 25 \n",
+ "... ... ... ... \n",
+ "rps5 250 249 248 \n",
+ "rps6e 251 250 249 \n",
+ "rps7 252 251 250 \n",
+ "rps8 253 252 251 \n",
+ "rps8e 254 253 252 \n",
+ "sod1 255 254 253 \n",
+ "spt4 256 255 254 \n",
+ "secF 257 256 255 \n",
+ "serS 258 257 256 \n",
+ "Signal_recognition_p 259 258 257 \n",
+ "sua5 260 259 258 \n",
+ "sucD 261 260 259 \n",
+ "sufS 262 261 260 \n",
+ "tatD 263 262 261 \n",
+ "tbp2 264 263 262 \n",
+ "tfs 265 264 263 \n",
+ "tRNA_guanine10N2 266 265 264 \n",
+ "tRNA_pseudouridine_s 267 266 265 \n",
+ "thyA 268 267 266 \n",
+ "top6B 269 268 267 \n",
+ "tpiA 270 269 268 \n",
+ "trkA 271 270 269 \n",
+ "trm1 272 271 270 \n",
+ "tRNA_cytidine562 273 272 271 \n",
+ "trpS 274 273 272 \n",
+ "truB 275 274 273 \n",
+ "tuf 276 275 274 \n",
+ "wtpC 277 276 275 \n",
+ "ychF 278 277 276 \n",
+ "zupT 279 278 277 \n",
+ "\n",
+ " cysD flpA ftsH 50S_ribosomal_protei hisS ... \\\n",
+ "30S_ribosomal_protei 5 6 7 8 9 ... \n",
+ "30S_ribosomal_protei 4 5 6 7 8 ... \n",
+ "50S_ribosomal_protei 3 4 5 6 7 ... \n",
+ "50S_ribosomal_protei 2 3 4 5 6 ... \n",
+ "cmk 1 2 3 4 5 ... \n",
+ "cysD 0 1 2 3 4 ... \n",
+ "flpA 1 0 1 2 3 ... \n",
+ "ftsH 2 1 0 1 2 ... \n",
+ "50S_ribosomal_protei 3 2 1 0 1 ... \n",
+ "hisS 4 3 2 1 0 ... \n",
+ "hmtA1 5 4 3 2 1 ... \n",
+ "hypothetical_protein_109 6 5 4 3 2 ... \n",
+ "hypothetical_protein_11 7 6 5 4 3 ... \n",
+ "hypothetical_protein_120 8 7 6 5 4 ... \n",
+ "hypothetical_protein_22 9 8 7 6 5 ... \n",
+ "hypothetical_protein_23 10 9 8 7 6 ... \n",
+ "hypothetical_protein_35 11 10 9 8 7 ... \n",
+ "hypothetical_protein_48 12 11 10 9 8 ... \n",
+ "hypothetical_protein_60 13 12 11 10 9 ... \n",
+ "hypothetical_protein_73 14 13 12 11 10 ... \n",
+ "hypothetical_protein_86 15 14 13 12 11 ... \n",
+ "hypothetical_protein_87 16 15 14 13 12 ... \n",
+ "Ironsulfur_cluster_ 17 16 15 14 13 ... \n",
+ "iscU2 18 17 16 15 14 ... \n",
+ "pcn 19 18 17 16 15 ... \n",
+ "pelA 20 19 18 17 16 ... \n",
+ "Putative_FKBPtype_p 21 20 19 18 17 ... \n",
+ "putative_KH_and_PIN 22 21 20 19 18 ... \n",
+ "rpa 23 22 21 20 19 ... \n",
+ "rpl5 24 23 22 21 20 ... \n",
+ "... ... ... ... ... ... ... \n",
+ "rps5 247 246 245 244 243 ... \n",
+ "rps6e 248 247 246 245 244 ... \n",
+ "rps7 249 248 247 246 245 ... \n",
+ "rps8 250 249 248 247 246 ... \n",
+ "rps8e 251 250 249 248 247 ... \n",
+ "sod1 252 251 250 249 248 ... \n",
+ "spt4 253 252 251 250 249 ... \n",
+ "secF 254 253 252 251 250 ... \n",
+ "serS 255 254 253 252 251 ... \n",
+ "Signal_recognition_p 256 255 254 253 252 ... \n",
+ "sua5 257 256 255 254 253 ... \n",
+ "sucD 258 257 256 255 254 ... \n",
+ "sufS 259 258 257 256 255 ... \n",
+ "tatD 260 259 258 257 256 ... \n",
+ "tbp2 261 260 259 258 257 ... \n",
+ "tfs 262 261 260 259 258 ... \n",
+ "tRNA_guanine10N2 263 262 261 260 259 ... \n",
+ "tRNA_pseudouridine_s 264 263 262 261 260 ... \n",
+ "thyA 265 264 263 262 261 ... \n",
+ "top6B 266 265 264 263 262 ... \n",
+ "tpiA 267 266 265 264 263 ... \n",
+ "trkA 268 267 266 265 264 ... \n",
+ "trm1 269 268 267 266 265 ... \n",
+ "tRNA_cytidine562 270 269 268 267 266 ... \n",
+ "trpS 271 270 269 268 267 ... \n",
+ "truB 272 271 270 269 268 ... \n",
+ "tuf 273 272 271 270 269 ... \n",
+ "wtpC 274 273 272 271 270 ... \n",
+ "ychF 275 274 273 272 271 ... \n",
+ "zupT 276 275 274 273 272 ... \n",
+ "\n",
+ " tpiA trkA trm1 tRNA_cytidine562 trpS truB tuf \\\n",
+ "30S_ribosomal_protei 272 273 274 275 276 277 278 \n",
+ "30S_ribosomal_protei 271 272 273 274 275 276 277 \n",
+ "50S_ribosomal_protei 270 271 272 273 274 275 276 \n",
+ "50S_ribosomal_protei 269 270 271 272 273 274 275 \n",
+ "cmk 268 269 270 271 272 273 274 \n",
+ "cysD 267 268 269 270 271 272 273 \n",
+ "flpA 266 267 268 269 270 271 272 \n",
+ "ftsH 265 266 267 268 269 270 271 \n",
+ "50S_ribosomal_protei 264 265 266 267 268 269 270 \n",
+ "hisS 263 264 265 266 267 268 269 \n",
+ "hmtA1 262 263 264 265 266 267 268 \n",
+ "hypothetical_protein_109 261 262 263 264 265 266 267 \n",
+ "hypothetical_protein_11 260 261 262 263 264 265 266 \n",
+ "hypothetical_protein_120 259 260 261 262 263 264 265 \n",
+ "hypothetical_protein_22 258 259 260 261 262 263 264 \n",
+ "hypothetical_protein_23 257 258 259 260 261 262 263 \n",
+ "hypothetical_protein_35 256 257 258 259 260 261 262 \n",
+ "hypothetical_protein_48 255 256 257 258 259 260 261 \n",
+ "hypothetical_protein_60 254 255 256 257 258 259 260 \n",
+ "hypothetical_protein_73 253 254 255 256 257 258 259 \n",
+ "hypothetical_protein_86 252 253 254 255 256 257 258 \n",
+ "hypothetical_protein_87 251 252 253 254 255 256 257 \n",
+ "Ironsulfur_cluster_ 250 251 252 253 254 255 256 \n",
+ "iscU2 249 250 251 252 253 254 255 \n",
+ "pcn 248 249 250 251 252 253 254 \n",
+ "pelA 247 248 249 250 251 252 253 \n",
+ "Putative_FKBPtype_p 246 247 248 249 250 251 252 \n",
+ "putative_KH_and_PIN 245 246 247 248 249 250 251 \n",
+ "rpa 244 245 246 247 248 249 250 \n",
+ "rpl5 243 244 245 246 247 248 249 \n",
+ "... ... ... ... ... ... ... ... \n",
+ "rps5 20 21 22 23 24 25 26 \n",
+ "rps6e 19 20 21 22 23 24 25 \n",
+ "rps7 18 19 20 21 22 23 24 \n",
+ "rps8 17 18 19 20 21 22 23 \n",
+ "rps8e 16 17 18 19 20 21 22 \n",
+ "sod1 15 16 17 18 19 20 21 \n",
+ "spt4 14 15 16 17 18 19 20 \n",
+ "secF 13 14 15 16 17 18 19 \n",
+ "serS 12 13 14 15 16 17 18 \n",
+ "Signal_recognition_p 11 12 13 14 15 16 17 \n",
+ "sua5 10 11 12 13 14 15 16 \n",
+ "sucD 9 10 11 12 13 14 15 \n",
+ "sufS 8 9 10 11 12 13 14 \n",
+ "tatD 7 8 9 10 11 12 13 \n",
+ "tbp2 6 7 8 9 10 11 12 \n",
+ "tfs 5 6 7 8 9 10 11 \n",
+ "tRNA_guanine10N2 4 5 6 7 8 9 10 \n",
+ "tRNA_pseudouridine_s 3 4 5 6 7 8 9 \n",
+ "thyA 2 3 4 5 6 7 8 \n",
+ "top6B 1 2 3 4 5 6 7 \n",
+ "tpiA 0 1 2 3 4 5 6 \n",
+ "trkA 1 0 1 2 3 4 5 \n",
+ "trm1 2 1 0 1 2 3 4 \n",
+ "tRNA_cytidine562 3 2 1 0 1 2 3 \n",
+ "trpS 4 3 2 1 0 1 2 \n",
+ "truB 5 4 3 2 1 0 1 \n",
+ "tuf 6 5 4 3 2 1 0 \n",
+ "wtpC 7 6 5 4 3 2 1 \n",
+ "ychF 8 7 6 5 4 3 2 \n",
+ "zupT 9 8 7 6 5 4 3 \n",
+ "\n",
+ " wtpC ychF zupT \n",
+ "30S_ribosomal_protei 279 280 281 \n",
+ "30S_ribosomal_protei 278 279 280 \n",
+ "50S_ribosomal_protei 277 278 279 \n",
+ "50S_ribosomal_protei 276 277 278 \n",
+ "cmk 275 276 277 \n",
+ "cysD 274 275 276 \n",
+ "flpA 273 274 275 \n",
+ "ftsH 272 273 274 \n",
+ "50S_ribosomal_protei 271 272 273 \n",
+ "hisS 270 271 272 \n",
+ "hmtA1 269 270 271 \n",
+ "hypothetical_protein_109 268 269 270 \n",
+ "hypothetical_protein_11 267 268 269 \n",
+ "hypothetical_protein_120 266 267 268 \n",
+ "hypothetical_protein_22 265 266 267 \n",
+ "hypothetical_protein_23 264 265 266 \n",
+ "hypothetical_protein_35 263 264 265 \n",
+ "hypothetical_protein_48 262 263 264 \n",
+ "hypothetical_protein_60 261 262 263 \n",
+ "hypothetical_protein_73 260 261 262 \n",
+ "hypothetical_protein_86 259 260 261 \n",
+ "hypothetical_protein_87 258 259 260 \n",
+ "Ironsulfur_cluster_ 257 258 259 \n",
+ "iscU2 256 257 258 \n",
+ "pcn 255 256 257 \n",
+ "pelA 254 255 256 \n",
+ "Putative_FKBPtype_p 253 254 255 \n",
+ "putative_KH_and_PIN 252 253 254 \n",
+ "rpa 251 252 253 \n",
+ "rpl5 250 251 252 \n",
+ "... ... ... ... \n",
+ "rps5 27 28 29 \n",
+ "rps6e 26 27 28 \n",
+ "rps7 25 26 27 \n",
+ "rps8 24 25 26 \n",
+ "rps8e 23 24 25 \n",
+ "sod1 22 23 24 \n",
+ "spt4 21 22 23 \n",
+ "secF 20 21 22 \n",
+ "serS 19 20 21 \n",
+ "Signal_recognition_p 18 19 20 \n",
+ "sua5 17 18 19 \n",
+ "sucD 16 17 18 \n",
+ "sufS 15 16 17 \n",
+ "tatD 14 15 16 \n",
+ "tbp2 13 14 15 \n",
+ "tfs 12 13 14 \n",
+ "tRNA_guanine10N2 11 12 13 \n",
+ "tRNA_pseudouridine_s 10 11 12 \n",
+ "thyA 9 10 11 \n",
+ "top6B 8 9 10 \n",
+ "tpiA 7 8 9 \n",
+ "trkA 6 7 8 \n",
+ "trm1 5 6 7 \n",
+ "tRNA_cytidine562 4 5 6 \n",
+ "trpS 3 4 5 \n",
+ "truB 2 3 4 \n",
+ "tuf 1 2 3 \n",
+ "wtpC 0 1 2 \n",
+ "ychF 1 0 1 \n",
+ "zupT 2 1 0 \n",
+ "\n",
+ "[282 rows x 282 columns]"
+ ]
+ },
+ "execution_count": 9,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "spr_distances = pd.DataFrame(index =[ num for num in treefiles],\n",
+ " columns=[num for num in treefiles],\n",
+ " data=[abs(np.arange(len(treefiles))-n) for n in range(len(treefiles))])\n",
+ "spr_distances"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 89,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "for gene in distance_matrices.keys():\n",
+ " pd.DataFrame.fillna(distance_matrices[gene], value=12, inplace=True)\n",
+ " for genome,row in distance_matrices[gene].iterrows():\n",
+ " for (col, colData) in distance_matrices[gene].iteritems():\n",
+ " if col == genome:\n",
+ " row[col] = 0.0\n",
+ " \n",
+ " "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Huber loss function"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def huber_loss(residuals, epsilon=1.35):\n",
+ " # https://en.wikipedia.org/wiki/Huber_loss\n",
+ " corrected_residuals = []\n",
+ " for error in residuals:\n",
+ " if abs(error) <= epsilon:\n",
+ " corrected_residuals.append((error**2)/2)\n",
+ " else:\n",
+ " corrected_residuals.append(epsilon*(abs(error)-epsilon/2))\n",
+ " return(np.mean(corrected_residuals))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [],
+ "source": [
+ "huber = []\n",
+ "\n",
+ "huber_thresh = 1.35\n",
+ "for family1, family2 in combinations(spr_distances.index, 2):\n",
+ " X = squareform(distance_matrices[family1].values)\n",
+ " Y = squareform(distance_matrices[family2].values)\n",
+ "\n",
+ " X_filter = X[(X<=8) & (Y<=8)]\n",
+ " Y_filter = Y[(X<=8) & (Y<=8)]\n",
+ " X_filter = X_filter.reshape(-1, 1)\n",
+ "\n",
+ " regression = hr(epsilon=huber_thresh, fit_intercept=False, alpha=1e-10).fit(X_filter.reshape(-1, 1), Y_filter)\n",
+ " pred_y = regression.predict(X_filter.reshape(-1, 1))\n",
+ " loss_xy = huber_loss(Y_filter-pred_y)\n",
+ " huber_determin = regression.score(X_filter.reshape(-1, 1), Y_filter)\n",
+ " \n",
+ " huber.append(loss_xy)\n",
+ "\n",
+ "huber = pd.DataFrame(index =spr_distances.index,\n",
+ " columns=spr_distances.columns,\n",
+ " data =squareform(huber))\n",
+ "huber"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 27,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(0.053810069871230846, 3.766969479850235e-08)"
+ ]
+ },
+ "execution_count": 27,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "pearsonr(squareform(spr_distances), squareform(huber))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Plot of every pairwise relationship"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 18,
+ "metadata": {
+ "scrolled": false
+ },
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/home/tian/anaconda3/lib/python3.6/site-packages/matplotlib/axes/_axes.py:6462: UserWarning: The 'normed' kwarg is deprecated, and has been replaced by the 'density' kwarg.\n",
+ " warnings.warn(\"The 'normed' kwarg is deprecated, and has been \"\n",
+ "/home/tian/anaconda3/lib/python3.6/site-packages/matplotlib/axes/_axes.py:6462: UserWarning: The 'normed' kwarg is deprecated, and has been replaced by the 'density' kwarg.\n",
+ " warnings.warn(\"The 'normed' kwarg is deprecated, and has been \"\n"
+ ]
+ },
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkwAAAJMCAYAAAAIZPnDAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAPYQAAD2EBqD+naQAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAIABJREFUeJzs3Xt8VNW5P/7PTsidXAgpTkAgyEWMqKCIIAhK4YjaQm2rFUWrxy+tF1qlpx6QloL1V5RWxXPEetf2aEWPxRuCHEFQBINYESGGCmIAhUSaBAZIyG1m/f5IdpiZ7D177dvMnszn/XrlBZnZM7Nnz2T2M8+z1rMUIQSIiIiISF9KvHeAiIiIyOsYMBEREREZYMBEREREZIABExEREZEBBkxEREREBhgwERERERlgwERERERkgAETERERkQEGTEREREQGGDARERERGWDARERERGSAARMRERGRgW7x3gETuEowERF1ZUq8d4D0McNEREREZIABExEREZGBRCrJOerFj/ZHvf7aC/rFaE+IiIjI65hhIiIiIjKQtBkmI0YZKIBZKCIiomTBDBMRERGRAWaYbGAWioiIKDkwYHIZB5cTERElPpbkiIiIiAwwwxRnLOsRERF5HwOmBMCyHhERUXyxJEdERERkgBmmLoBlPSIiIncxw0RERERkgBmmJMFxUERERNYxYCIALOsRERFFw5IcERERkQFmmEgay3pERJSsGDCRY1jWIyKiroolOSIiIiIDzDBRTDELRUREiYgBE3kOx0oREZHXsCRHREREZIAZJko4LOsREVGsMcNEREREZIAZJuqSOA6KiIicxICJkhLLekREZAZLckREREQGmGEi0sGyHhERqRgwEVnEsh4RUfJgSY6IiIjIADNMRC5iWY+IqGtghomIiIjIADNMRHHEcVBERImBARORx7GsR0QUfyzJERERERlghokowbGsR0TkPgZMREmAQRURkT0syREREREZYMBEREREZIAlOSKSwrIeESUzZpiIiIiIDDDDRESOYc8oIuqqGDARUcywrEdEiYolOSIiIiIDihAi3vsgy9EdlfmmS0TewwwUdWFKvHeA9DHDRERERGSAY5iIKKFwHBQRxQMDJiLqcjhbj4icxpIcERERkQFmmIgo6bCsR0RmMWAiItLAsh4RhWJJjoiIiMgAM0xERBawrEeUXJhhIiIiIjLADBMRkUuYhSLqOhgwERHFEQeXEyUGluSIiIiIDDDDRETkYSzrEXkDAyYiogTHsh6R+1iSIyIiIjLADBMRURfHsh6RfQyYiIiIZT0iAyzJERERERlghomIiAyxrEfJjhkmIiIiIgPMMBERkSM4Doq6MgZMREQUEyzrUSJjSY6IiIjIADNMRETkGSzrkVcxYCIiooTBsh7FC0tyRERERAaYYSIioi6FWShyAzNMRERERAaYYSIioqTDweVkliKEiPc+GFIURfH7/UEn7/N///G1k3dHRERJ5uqRfR29v/z8/HwAx0QinJiTUKIETHkA/PHeDyIiIpflCyGOxnsnqLNECZgUALkO3V0ugG8AnArgmEP32VXw2ETH4xMdj48+HpvoeHxOYobJoxJiDFP7m8eRiLst9gLQ9qZkFB+CxyY6Hp/oeHz08dhEx+NDiYCz5IiIiIgMMGAiIiIiMpCMAVMTgHva/6VwPDbR8fhEx+Ojj8cmOh4f8ryEGPRNREREFE/JmGEiIiIiMoUBExEREZEBBkxEREREBhgwERERERlgwERERERkwFTApCjK3YqifKwoyjFFUQ4pivK6oiinG9zmRkVRhMZPpr1dJyIiIooNsxmmCQAeBTAawGS0La3yjqIoOQa3OwqgOPRHCNFo8rGJiIiI4sLUWnJCiCmhvyuKchOAQwDOA7Ah+k1FtfndIyIiIoo/u4vv5rf/W2ewXXdFUfYBSAWwDcB8IcSnehsripIBICPi4nQAtVzFmYiIkhnPkfFhOWBS2paXfgjARiFEeZRN/wngRgA7AOQBuAPAJkVRzhFC7Na5zd0AFkRe6Pf7re4uERGR1ymS2/EcaZ/ssT55A6vBqKIojwK4AsA4IcQ3Jm6XAmArgA1CiF/qbBMZPecC+Mbv9yMvL8/S/hIREXmc1Emc50hHmA6YLGWYFEV5BMBUAOPNBEsAIIQIKoryMYDBUbZpQsgijG3JLCIiIuI5Mj7MthVQFEVZCuCHACYKISrNPmB7KW84gCqztyUiIiKKB7MZpkcBXAtgGoBjiqL42i/3CyFOAICiKP8D4IAQ4u723xcA2AxgN9rGMP0SbQHT7fZ3n4iIiMh9ZgOmW9v/fS/i8psA/KX9//0ABEOuKwDwJAAfAD+AT9FWytti8rGJiIiI4sLyoO9YUhQlD4CfA9qoKxFCoLW1FYFAIN67QkQuS01NRbdu3YzGG1kajMRzpCWxGfRNRPY0NzejqqoKDQ0N8d4VIoqR7OxsFBcXIz09Pd67QhYwYCKKsWAwiMrKSqSmpqJ3795IT0/nLBeiLkwIgebmZvzrX/9CZWUlBg8ejJQUsyuTUbwxYCKKsebmZgSDQfTt2xfZ2dnx3h0iioGsrCykpaVh3759aG5uRmYm159PNAxxieKE3zCJkgv/5hMbXz0iIiIiAwyYiIiIiAwwYCIiIiIywICJiMgj3n//fZx33nnIzMzEaaedhscff9zwNjt27MCECROQlZWFPn364Pe//z0i++stX74cpaWlyMjIQGlpKV577bWO61paWjBnzhycddZZyMnJQe/evXHDDTfg4MGDYffxhz/8ARdeeCGys7NRUFDgzBOOESEEFi5ciN69eyMrKwsXX3wxPv/8c8PbHThwADNmzEDPnj2RnZ2N4cOH45NPPum4XlEUzZ8//elPbj4dihMGTETkec3NzV3+cSsrK3H55Zfjoosuwqeffop58+bhl7/8JZYvX657m6NHj2Ly5Mno3bs3Pv74YzzyyCN44IEH8NBDD3VsU1ZWhp/85Ce4/vrr8dlnn+H666/H1VdfjY8++ggA0NDQgK1bt2L+/PnYunUrXn31VezatQtTp04Ne6zm5mZcddVVuPXWW5Fo/vjHP+Khhx7C0qVL8fHHH8Pn82Hy5Mk4duyY7m0OHz6MsWPHIi0tDW+//TYqKirw4IMPhgWLVVVVYT/PPvssFEXBj370o1g8LYo1IYTnf9C2Bp3w+/2CKNGdOHFCVFRUiBMnTsR7V0ybMGGCuP3228Xtt98u8vPzRWFhofjNb34jgsFgxzZNTU3irrvuEr179xbZ2dli1KhRYv369R3X19TUiGuuuUb06dNHZGVliWHDhokXX3xR83Fmz54tevbsKcaPHy+EEGLBggWib9++Ij09XRQXF4tf/OIXHbepq6sT119/vSgoKBBZWVliypQpYteuXR3XP/fccyI/P1+sXr1aDB06VOTk5IhLL71UHDx4sGObn/70p2LatGli0aJFori4WPTv39/hI6jvP//zP8XQoUPDLvv5z38uRo8erXubP//5zyI/P180NjZ2XHbfffeJ3r17d7wmV199tZgyZUrY7S699FJxzTXX6N7vli1bBACxb9++Ttepx9GK9evXCwDirbfeEmeffbbIyMgQo0aNEtu3b7d0fzKCwaDw+Xzi/vvv77issbFR5Ofni8cff1z3dnPmzBHjxo0z9VjTpk0TEydO1L1e4m+f58jYMX2cmWEiShJCCBxvbMWRhmYcb2ztVLaR9de//hXdunXDRx99hP/+7//GkiVL8PTTT3dcf9NNN2HTpk146aWXsH37dlx11VWYMmUKdu/eDQBobGzEeeedh7feegvl5eX42c9+huuvv74j4xH5OJs2bcITTzyBv//971iyZAmeeOIJ7N69G6+//jrOOuusju1vvPFG/OMf/8Cbb76JsrIyCCFw+eWXo6WlpWObhoYGPPDAA3j++eexYcMG7N+/H7/+9a/DHvfdd9/Fzp07sWbNGrz11luax+CDDz5A9+7do/4sWrTI1HEtKyvDv/3bv4Vddumll+If//hH2HOIvM2ECROQkZERdpuDBw9i7969Ue/3ww8/1N0Xv98PRVFMl95KSkqwcOFCw+3uuusuPPDAA/j444/Rq1cvTJ06Vfc5AsBll11meLz1VFZWorq6OuwYZGRkYMKECVGPwZtvvomRI0fiqquuQq9evTBixAg89dRTutt/++23WLlyJW6++WaDZ0+Jio0riZKA/0QzDh5pREvg5LrYaakp6F2Qifwsc8s09O3bF0uWLIGiKDj99NOxY8cOLFmyBDNnzsSePXuwbNkyfPPNN+jduzcA4Ne//jVWr16N5557DosWLUKfPn3CgpRf/OIXWL16NV555RVccMEFHZcPGjQIf/zjHzt+X7VqFXw+HyZNmoS0tDT069cPo0aNAgDs3r0bb775JjZt2oQLL7wQAPC3v/0Nffv2xeuvv46rrroKQNt4nccffxwDBw4EAMyaNQu///3vw55fTk4Onn766ajLV4wcORLbtm2LepwKCwsNj2Wo6upqnHLKKWGXnXLKKWhtbUVNTQ2Ki4s1b1NSUtLpNup1AwYM0L3f6upqzf1obGzE3Llzce2115pel2zgwIEoKioy3G7BggWYPHkygLbA+NRTT8Vrr72Gq6++WnP7p59+GidOnDC1Lyr1eWodg3379une7quvvsJjjz2GX/3qV5g3bx62bNmCX/7yl8jIyMANN9zQafu//vWvyM3NxQ9/+ENL+0nex4CJqIvzn2jGvtrOa9a1BILYV9uA/j1hKmgaPXp02FIu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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "\n",
+ "\n",
+ "plot = sns.jointplot(x=squareform(spr_distances),\n",
+ " y=squareform(huber))\n",
+ "\n",
+ "plot.fig.set_dpi(100)\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import numpy as np\n",
+ "\n",
+ "from sklearn.cluster import DBSCAN\n",
+ "from sklearn import metrics\n",
+ "from sklearn.datasets import make_blobs\n",
+ "from sklearn.preprocessing import StandardScaler\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [],
+ "source": [
+ "from skbio.stats.ordination import pcoa\n",
+ "from sklearn.metrics.pairwise import pairwise_distances\n",
+ "distance_matrix = pairwise_distances(huber, metric='precomputed')\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "You can use any distance metric you feel appropriate here if you change 'seuclidean'"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 26,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from scipy.spatial.distance import pdist\n",
+ "\n",
+ "n_coor = len(treefiles)\n",
+ "dist = np.zeros((n_coor, n_coor))\n",
+ "row,col = np.triu_indices(n_coor,1)\n",
+ "dist[row,col] = pdist(distance_matrix, metric='seuclidean')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 309,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "output_mat = pd.DataFrame(dist)\n",
+ "output_mat.to_csv('gene_fam_matrix.tsv', sep=' ')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 310,
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " 0 | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " 3 | \n",
+ " 4 | \n",
+ " 5 | \n",
+ " 6 | \n",
+ " 7 | \n",
+ " 8 | \n",
+ " 9 | \n",
+ " ... | \n",
+ " 272 | \n",
+ " 273 | \n",
+ " 274 | \n",
+ " 275 | \n",
+ " 276 | \n",
+ " 277 | \n",
+ " 278 | \n",
+ " 279 | \n",
+ " 280 | \n",
+ " 281 | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 0.0 | \n",
+ " 1.635985e-24 | \n",
+ " 5.847684 | \n",
+ " 5.847684e+00 | \n",
+ " 6.992466 | \n",
+ " 8.419736 | \n",
+ " 6.542187 | \n",
+ " 11.245885 | \n",
+ " 5.950090 | \n",
+ " 8.089884 | \n",
+ " ... | \n",
+ " 11.208851 | \n",
+ " 32.459745 | \n",
+ " 10.827650 | \n",
+ " 10.332986 | \n",
+ " 73.305763 | \n",
+ " 12.814096 | \n",
+ " 32.379255 | \n",
+ " 39.603344 | \n",
+ " 19.077412 | \n",
+ " 27.950357 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 5.847684 | \n",
+ " 5.847684e+00 | \n",
+ " 6.992466 | \n",
+ " 8.419736 | \n",
+ " 6.542187 | \n",
+ " 11.245885 | \n",
+ " 5.950090 | \n",
+ " 8.089884 | \n",
+ " ... | \n",
+ " 11.208851 | \n",
+ " 32.459745 | \n",
+ " 10.827650 | \n",
+ " 10.332986 | \n",
+ " 73.305763 | \n",
+ " 12.814096 | \n",
+ " 32.379255 | \n",
+ " 39.603344 | \n",
+ " 19.077412 | \n",
+ " 27.950357 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 1.284228e-24 | \n",
+ " 3.333780 | \n",
+ " 5.018989 | \n",
+ " 2.408399 | \n",
+ " 9.384877 | \n",
+ " 0.606392 | \n",
+ " 4.523772 | \n",
+ " ... | \n",
+ " 11.277304 | \n",
+ " 34.885022 | \n",
+ " 10.182825 | \n",
+ " 10.041596 | \n",
+ " 75.327944 | \n",
+ " 13.371793 | \n",
+ " 32.859801 | \n",
+ " 41.571037 | \n",
+ " 21.627902 | \n",
+ " 30.393789 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 3.333780 | \n",
+ " 5.018989 | \n",
+ " 2.408399 | \n",
+ " 9.384877 | \n",
+ " 0.606392 | \n",
+ " 4.523772 | \n",
+ " ... | \n",
+ " 11.277304 | \n",
+ " 34.885022 | \n",
+ " 10.182825 | \n",
+ " 10.041596 | \n",
+ " 75.327944 | \n",
+ " 13.371793 | \n",
+ " 32.859801 | \n",
+ " 41.571037 | \n",
+ " 21.627902 | \n",
+ " 30.393789 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 3.745771 | \n",
+ " 3.181081 | \n",
+ " 8.754229 | \n",
+ " 3.327396 | \n",
+ " 4.530104 | \n",
+ " ... | \n",
+ " 11.918027 | \n",
+ " 35.292459 | \n",
+ " 10.588733 | \n",
+ " 10.408935 | \n",
+ " 75.610320 | \n",
+ " 13.464494 | \n",
+ " 33.094732 | \n",
+ " 41.946374 | \n",
+ " 22.179193 | \n",
+ " 30.857050 | \n",
+ "
\n",
+ " \n",
+ " | 5 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 4.225188 | \n",
+ " 6.850064 | \n",
+ " 5.009906 | \n",
+ " 4.085992 | \n",
+ " ... | \n",
+ " 13.764072 | \n",
+ " 34.975183 | \n",
+ " 11.266132 | \n",
+ " 11.431231 | \n",
+ " 74.869157 | \n",
+ " 13.913273 | \n",
+ " 33.318503 | \n",
+ " 41.754932 | \n",
+ " 22.643936 | \n",
+ " 30.760145 | \n",
+ "
\n",
+ " \n",
+ " | 6 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 8.192379 | \n",
+ " 2.467055 | \n",
+ " 3.624743 | \n",
+ " ... | \n",
+ " 12.070196 | \n",
+ " 34.773824 | \n",
+ " 10.359794 | \n",
+ " 10.438431 | \n",
+ " 74.938815 | \n",
+ " 13.457429 | \n",
+ " 32.984851 | \n",
+ " 41.383159 | \n",
+ " 21.856608 | \n",
+ " 30.314101 | \n",
+ "
\n",
+ " \n",
+ " | 7 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 9.371709 | \n",
+ " 7.999477 | \n",
+ " ... | \n",
+ " 17.535290 | \n",
+ " 33.067928 | \n",
+ " 14.088205 | \n",
+ " 14.602494 | \n",
+ " 71.426675 | \n",
+ " 15.057407 | \n",
+ " 31.774783 | \n",
+ " 39.031505 | \n",
+ " 22.443854 | \n",
+ " 29.099044 | \n",
+ "
\n",
+ " \n",
+ " | 8 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 4.482462 | \n",
+ " ... | \n",
+ " 11.266665 | \n",
+ " 34.919529 | \n",
+ " 10.186184 | \n",
+ " 10.041514 | \n",
+ " 75.356727 | \n",
+ " 13.370572 | \n",
+ " 32.860239 | \n",
+ " 41.596742 | \n",
+ " 21.651322 | \n",
+ " 30.422693 | \n",
+ "
\n",
+ " \n",
+ " | 9 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 12.783650 | \n",
+ " 35.742553 | \n",
+ " 11.244306 | \n",
+ " 11.418035 | \n",
+ " 75.075509 | \n",
+ " 14.268797 | \n",
+ " 32.474804 | \n",
+ " 41.386025 | \n",
+ " 22.931278 | \n",
+ " 31.237437 | \n",
+ "
\n",
+ " \n",
+ " | 10 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 22.856634 | \n",
+ " 24.877890 | \n",
+ " 20.565499 | \n",
+ " 20.573981 | \n",
+ " 63.268304 | \n",
+ " 18.995155 | \n",
+ " 34.520954 | \n",
+ " 33.560864 | \n",
+ " 17.355026 | \n",
+ " 21.430145 | \n",
+ "
\n",
+ " \n",
+ " | 11 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 37.172431 | \n",
+ " 28.020323 | \n",
+ " 34.670793 | \n",
+ " 34.656521 | \n",
+ " 59.711336 | \n",
+ " 32.274947 | \n",
+ " 44.105762 | \n",
+ " 37.495072 | \n",
+ " 27.755493 | \n",
+ " 26.751569 | \n",
+ "
\n",
+ " \n",
+ " | 12 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 11.888749 | \n",
+ " 35.903614 | \n",
+ " 13.603039 | \n",
+ " 12.851950 | \n",
+ " 76.353155 | \n",
+ " 16.156336 | \n",
+ " 33.237701 | \n",
+ " 42.477485 | \n",
+ " 22.089583 | \n",
+ " 30.737505 | \n",
+ "
\n",
+ " \n",
+ " | 13 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 10.667421 | \n",
+ " 36.039500 | \n",
+ " 12.673636 | \n",
+ " 11.970012 | \n",
+ " 76.776069 | \n",
+ " 15.300031 | \n",
+ " 33.153807 | \n",
+ " 42.677692 | \n",
+ " 21.553961 | \n",
+ " 30.880786 | \n",
+ "
\n",
+ " \n",
+ " | 14 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 26.408125 | \n",
+ " 31.227641 | \n",
+ " 22.947019 | \n",
+ " 23.382071 | \n",
+ " 67.790984 | \n",
+ " 22.442220 | \n",
+ " 37.810909 | \n",
+ " 39.187655 | \n",
+ " 24.834293 | \n",
+ " 28.689060 | \n",
+ "
\n",
+ " \n",
+ " | 15 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 13.722377 | \n",
+ " 33.114574 | \n",
+ " 13.314578 | \n",
+ " 13.082242 | \n",
+ " 71.503936 | \n",
+ " 14.817873 | \n",
+ " 30.949610 | \n",
+ " 37.787209 | \n",
+ " 20.689663 | \n",
+ " 28.362332 | \n",
+ "
\n",
+ " \n",
+ " | 16 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 10.220223 | \n",
+ " 36.211994 | \n",
+ " 12.488691 | \n",
+ " 11.589880 | \n",
+ " 77.252867 | \n",
+ " 15.141276 | \n",
+ " 33.298005 | \n",
+ " 43.154885 | \n",
+ " 21.613249 | \n",
+ " 31.120557 | \n",
+ "
\n",
+ " \n",
+ " | 17 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 10.472936 | \n",
+ " 36.031809 | \n",
+ " 12.568884 | \n",
+ " 11.753075 | \n",
+ " 76.897113 | \n",
+ " 15.151362 | \n",
+ " 33.150439 | \n",
+ " 42.722551 | \n",
+ " 21.526612 | \n",
+ " 30.866441 | \n",
+ "
\n",
+ " \n",
+ " | 18 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 8.194474 | \n",
+ " 38.267240 | \n",
+ " 13.109328 | \n",
+ " 11.516467 | \n",
+ " 79.305553 | \n",
+ " 15.742804 | \n",
+ " 33.773257 | \n",
+ " 44.702298 | \n",
+ " 22.363908 | \n",
+ " 32.673834 | \n",
+ "
\n",
+ " \n",
+ " | 19 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 10.800889 | \n",
+ " 36.766399 | \n",
+ " 13.325461 | \n",
+ " 12.387707 | \n",
+ " 77.801213 | \n",
+ " 15.920443 | \n",
+ " 33.664572 | \n",
+ " 43.824720 | \n",
+ " 22.108362 | \n",
+ " 31.769740 | \n",
+ "
\n",
+ " \n",
+ " | 20 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 10.790561 | \n",
+ " 36.465497 | \n",
+ " 12.898171 | \n",
+ " 11.975549 | \n",
+ " 76.984900 | \n",
+ " 15.755606 | \n",
+ " 33.218124 | \n",
+ " 43.026383 | \n",
+ " 22.030473 | \n",
+ " 31.310136 | \n",
+ "
\n",
+ " \n",
+ " | 21 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 10.894940 | \n",
+ " 36.991510 | \n",
+ " 13.532222 | \n",
+ " 12.395966 | \n",
+ " 77.767272 | \n",
+ " 16.388287 | \n",
+ " 33.741569 | \n",
+ " 43.891024 | \n",
+ " 22.460495 | \n",
+ " 31.805582 | \n",
+ "
\n",
+ " \n",
+ " | 22 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 27.864020 | \n",
+ " 36.733447 | \n",
+ " 27.535020 | \n",
+ " 27.530177 | \n",
+ " 65.666987 | \n",
+ " 27.482683 | \n",
+ " 31.778748 | \n",
+ " 34.562477 | \n",
+ " 29.196397 | \n",
+ " 32.314605 | \n",
+ "
\n",
+ " \n",
+ " | 23 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 13.751392 | \n",
+ " 34.099356 | \n",
+ " 12.216553 | \n",
+ " 12.275915 | \n",
+ " 73.047877 | \n",
+ " 14.175184 | \n",
+ " 32.059172 | \n",
+ " 39.388661 | \n",
+ " 21.796404 | \n",
+ " 29.529949 | \n",
+ "
\n",
+ " \n",
+ " | 24 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 20.533660 | \n",
+ " 35.469859 | \n",
+ " 18.476965 | \n",
+ " 18.846910 | \n",
+ " 70.406117 | \n",
+ " 19.824924 | \n",
+ " 31.958215 | \n",
+ " 38.158241 | \n",
+ " 25.723348 | \n",
+ " 31.208600 | \n",
+ "
\n",
+ " \n",
+ " | 25 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 11.703405 | \n",
+ " 35.181025 | \n",
+ " 9.890206 | \n",
+ " 10.008000 | \n",
+ " 75.379657 | \n",
+ " 13.312448 | \n",
+ " 33.011138 | \n",
+ " 41.935878 | \n",
+ " 22.097817 | \n",
+ " 30.724826 | \n",
+ "
\n",
+ " \n",
+ " | 26 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 14.752313 | \n",
+ " 29.129545 | \n",
+ " 12.383966 | \n",
+ " 12.315955 | \n",
+ " 69.606314 | \n",
+ " 12.891282 | \n",
+ " 32.600455 | \n",
+ " 37.208829 | \n",
+ " 17.341024 | \n",
+ " 25.023067 | \n",
+ "
\n",
+ " \n",
+ " | 27 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 10.943037 | \n",
+ " 33.957596 | \n",
+ " 9.522301 | \n",
+ " 9.265908 | \n",
+ " 74.677630 | \n",
+ " 12.062871 | \n",
+ " 32.535104 | \n",
+ " 41.026851 | \n",
+ " 20.590425 | \n",
+ " 29.484103 | \n",
+ "
\n",
+ " \n",
+ " | 28 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 27.247120 | \n",
+ " 31.942899 | \n",
+ " 25.423766 | \n",
+ " 25.574065 | \n",
+ " 63.759542 | \n",
+ " 24.772586 | \n",
+ " 32.637077 | \n",
+ " 33.376523 | \n",
+ " 25.857232 | \n",
+ " 28.232339 | \n",
+ "
\n",
+ " \n",
+ " | 29 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 15.479676 | \n",
+ " 35.698163 | \n",
+ " 14.705564 | \n",
+ " 14.705922 | \n",
+ " 72.840324 | \n",
+ " 16.625395 | \n",
+ " 30.975493 | \n",
+ " 39.030125 | \n",
+ " 23.770121 | \n",
+ " 30.946807 | \n",
+ "
\n",
+ " \n",
+ " | ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ "
\n",
+ " \n",
+ " | 252 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 3.448510 | \n",
+ " 35.722079 | \n",
+ " 8.575554 | \n",
+ " 6.487675 | \n",
+ " 77.305815 | \n",
+ " 12.071439 | \n",
+ " 32.769803 | \n",
+ " 43.080685 | \n",
+ " 20.068560 | \n",
+ " 30.393663 | \n",
+ "
\n",
+ " \n",
+ " | 253 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 3.731540 | \n",
+ " 34.504576 | \n",
+ " 8.193579 | \n",
+ " 6.227411 | \n",
+ " 75.982061 | \n",
+ " 11.444541 | \n",
+ " 31.771002 | \n",
+ " 41.548170 | \n",
+ " 19.000166 | \n",
+ " 29.220979 | \n",
+ "
\n",
+ " \n",
+ " | 254 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 4.540530 | \n",
+ " 34.918371 | \n",
+ " 7.334727 | \n",
+ " 5.455660 | \n",
+ " 76.606748 | \n",
+ " 11.197877 | \n",
+ " 32.656112 | \n",
+ " 42.577237 | \n",
+ " 19.646070 | \n",
+ " 29.777591 | \n",
+ "
\n",
+ " \n",
+ " | 255 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 10.559558 | \n",
+ " 35.357880 | \n",
+ " 13.198497 | \n",
+ " 12.052555 | \n",
+ " 72.465927 | \n",
+ " 15.265594 | \n",
+ " 28.718863 | \n",
+ " 37.884900 | \n",
+ " 21.561178 | \n",
+ " 29.489926 | \n",
+ "
\n",
+ " \n",
+ " | 256 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 3.728253 | \n",
+ " 35.921477 | \n",
+ " 10.376165 | \n",
+ " 8.320452 | \n",
+ " 77.429253 | \n",
+ " 13.231519 | \n",
+ " 32.835685 | \n",
+ " 42.854703 | \n",
+ " 19.889235 | \n",
+ " 30.426639 | \n",
+ "
\n",
+ " \n",
+ " | 257 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 4.689337 | \n",
+ " 37.630415 | \n",
+ " 11.943009 | \n",
+ " 9.794315 | \n",
+ " 79.023176 | \n",
+ " 14.629552 | \n",
+ " 33.505429 | \n",
+ " 44.421826 | \n",
+ " 21.303295 | \n",
+ " 32.002460 | \n",
+ "
\n",
+ " \n",
+ " | 258 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 4.051582 | \n",
+ " 34.238326 | \n",
+ " 8.196919 | \n",
+ " 6.156127 | \n",
+ " 75.680954 | \n",
+ " 10.994382 | \n",
+ " 31.901282 | \n",
+ " 41.512204 | \n",
+ " 18.697992 | \n",
+ " 28.888524 | \n",
+ "
\n",
+ " \n",
+ " | 259 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 23.917271 | \n",
+ " 26.482444 | \n",
+ " 17.672909 | \n",
+ " 18.908519 | \n",
+ " 63.326476 | \n",
+ " 17.267651 | \n",
+ " 32.913053 | \n",
+ " 33.794611 | \n",
+ " 21.098635 | \n",
+ " 23.671994 | \n",
+ "
\n",
+ " \n",
+ " | 260 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 10.708086 | \n",
+ " 30.635202 | \n",
+ " 7.327063 | \n",
+ " 7.072394 | \n",
+ " 71.204286 | \n",
+ " 8.901413 | \n",
+ " 31.288575 | \n",
+ " 38.340343 | \n",
+ " 17.177263 | \n",
+ " 25.730924 | \n",
+ "
\n",
+ " \n",
+ " | 261 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 4.240323 | \n",
+ " 35.127554 | \n",
+ " 7.574760 | \n",
+ " 5.610966 | \n",
+ " 76.665618 | \n",
+ " 11.216444 | \n",
+ " 32.473296 | \n",
+ " 42.641235 | \n",
+ " 19.716559 | \n",
+ " 29.900306 | \n",
+ "
\n",
+ " \n",
+ " | 262 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 8.608912 | \n",
+ " 29.761344 | \n",
+ " 7.471771 | \n",
+ " 6.859115 | \n",
+ " 71.912047 | \n",
+ " 9.760597 | \n",
+ " 31.920842 | \n",
+ " 38.312883 | \n",
+ " 15.701408 | \n",
+ " 25.157571 | \n",
+ "
\n",
+ " \n",
+ " | 263 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 5.610322 | \n",
+ " 34.558849 | \n",
+ " 7.389604 | \n",
+ " 5.576253 | \n",
+ " 75.806476 | \n",
+ " 10.498143 | \n",
+ " 32.224656 | \n",
+ " 42.104809 | \n",
+ " 19.337602 | \n",
+ " 29.332375 | \n",
+ "
\n",
+ " \n",
+ " | 264 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 3.663621 | \n",
+ " 35.410620 | \n",
+ " 8.602437 | \n",
+ " 6.681988 | \n",
+ " 76.335322 | \n",
+ " 11.691578 | \n",
+ " 31.564477 | \n",
+ " 41.805131 | \n",
+ " 19.845339 | \n",
+ " 30.003714 | \n",
+ "
\n",
+ " \n",
+ " | 265 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 26.590804 | \n",
+ " 22.973060 | \n",
+ " 21.757323 | \n",
+ " 22.657065 | \n",
+ " 61.307622 | \n",
+ " 19.593522 | \n",
+ " 36.734369 | \n",
+ " 34.769806 | \n",
+ " 18.339224 | \n",
+ " 20.541845 | \n",
+ "
\n",
+ " \n",
+ " | 266 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 11.252636 | \n",
+ " 29.807515 | \n",
+ " 7.902261 | \n",
+ " 7.729341 | \n",
+ " 70.585708 | \n",
+ " 9.277355 | \n",
+ " 31.280957 | \n",
+ " 37.942838 | \n",
+ " 16.586148 | \n",
+ " 24.935636 | \n",
+ "
\n",
+ " \n",
+ " | 267 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 12.237927 | \n",
+ " 25.248271 | \n",
+ " 11.130596 | \n",
+ " 10.311384 | \n",
+ " 68.147786 | \n",
+ " 10.387719 | \n",
+ " 32.324964 | \n",
+ " 35.810892 | \n",
+ " 11.067518 | \n",
+ " 20.598703 | \n",
+ "
\n",
+ " \n",
+ " | 268 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 37.391220 | \n",
+ " 37.000107 | \n",
+ " 35.067355 | \n",
+ " 35.526694 | \n",
+ " 55.564016 | \n",
+ " 34.158048 | \n",
+ " 28.542286 | \n",
+ " 25.822767 | \n",
+ " 35.063551 | \n",
+ " 33.473112 | \n",
+ "
\n",
+ " \n",
+ " | 269 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 3.561336 | \n",
+ " 34.688199 | \n",
+ " 7.821520 | \n",
+ " 5.933478 | \n",
+ " 76.230116 | \n",
+ " 11.427145 | \n",
+ " 32.100121 | \n",
+ " 41.876256 | \n",
+ " 19.241511 | \n",
+ " 29.469038 | \n",
+ "
\n",
+ " \n",
+ " | 270 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 5.776631 | \n",
+ " 37.957794 | \n",
+ " 12.780319 | \n",
+ " 10.782131 | \n",
+ " 79.126588 | \n",
+ " 14.961919 | \n",
+ " 33.438516 | \n",
+ " 44.520042 | \n",
+ " 21.210592 | \n",
+ " 31.945006 | \n",
+ "
\n",
+ " \n",
+ " | 271 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 39.339652 | \n",
+ " 13.022274 | \n",
+ " 35.236933 | \n",
+ " 35.417455 | \n",
+ " 47.623559 | \n",
+ " 31.272172 | \n",
+ " 44.829251 | \n",
+ " 31.894542 | \n",
+ " 22.140707 | \n",
+ " 13.767657 | \n",
+ "
\n",
+ " \n",
+ " | 272 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 0.000000 | \n",
+ " 36.360062 | \n",
+ " 9.379382 | \n",
+ " 7.339407 | \n",
+ " 77.143346 | \n",
+ " 12.749444 | \n",
+ " 31.822407 | \n",
+ " 42.392777 | \n",
+ " 20.404479 | \n",
+ " 30.731355 | \n",
+ "
\n",
+ " \n",
+ " | 273 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 31.750429 | \n",
+ " 32.128395 | \n",
+ " 48.111290 | \n",
+ " 27.840361 | \n",
+ " 41.792473 | \n",
+ " 28.274051 | \n",
+ " 18.391354 | \n",
+ " 12.267940 | \n",
+ "
\n",
+ " \n",
+ " | 274 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 3.237176 | \n",
+ " 73.366051 | \n",
+ " 7.676929 | \n",
+ " 31.651583 | \n",
+ " 39.912536 | \n",
+ " 18.171186 | \n",
+ " 28.006310 | \n",
+ "
\n",
+ " \n",
+ " | 275 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 73.914578 | \n",
+ " 7.771337 | \n",
+ " 31.511371 | \n",
+ " 40.344710 | \n",
+ " 17.604591 | \n",
+ " 27.817552 | \n",
+ "
\n",
+ " \n",
+ " | 276 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 69.187318 | \n",
+ " 66.445812 | \n",
+ " 40.673806 | \n",
+ " 60.986713 | \n",
+ " 50.936505 | \n",
+ "
\n",
+ " \n",
+ " | 277 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 30.328330 | \n",
+ " 36.912364 | \n",
+ " 13.877229 | \n",
+ " 23.819616 | \n",
+ "
\n",
+ " \n",
+ " | 278 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 30.828065 | \n",
+ " 33.616237 | \n",
+ " 37.098563 | \n",
+ "
\n",
+ " \n",
+ " | 279 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 31.965103 | \n",
+ " 26.287641 | \n",
+ "
\n",
+ " \n",
+ " | 280 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 14.102711 | \n",
+ "
\n",
+ " \n",
+ " | 281 | \n",
+ " 0.0 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000e+00 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " ... | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
282 rows × 282 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " 0 1 2 3 4 5 6 \\\n",
+ "0 0.0 1.635985e-24 5.847684 5.847684e+00 6.992466 8.419736 6.542187 \n",
+ "1 0.0 0.000000e+00 5.847684 5.847684e+00 6.992466 8.419736 6.542187 \n",
+ "2 0.0 0.000000e+00 0.000000 1.284228e-24 3.333780 5.018989 2.408399 \n",
+ "3 0.0 0.000000e+00 0.000000 0.000000e+00 3.333780 5.018989 2.408399 \n",
+ "4 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 3.745771 3.181081 \n",
+ "5 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 4.225188 \n",
+ "6 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "7 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "8 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "9 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "10 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "11 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "12 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "13 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "14 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "15 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "16 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "17 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "18 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "19 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "20 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "21 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "22 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "23 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "24 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "25 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "26 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "27 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "28 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "29 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ ".. ... ... ... ... ... ... ... \n",
+ "252 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "253 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "254 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "255 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "256 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "257 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "258 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "259 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "260 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "261 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "262 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "263 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "264 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "265 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "266 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "267 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "268 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "269 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "270 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "271 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "272 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "273 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "274 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "275 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "276 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "277 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "278 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "279 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "280 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "281 0.0 0.000000e+00 0.000000 0.000000e+00 0.000000 0.000000 0.000000 \n",
+ "\n",
+ " 7 8 9 ... 272 273 \\\n",
+ "0 11.245885 5.950090 8.089884 ... 11.208851 32.459745 \n",
+ "1 11.245885 5.950090 8.089884 ... 11.208851 32.459745 \n",
+ "2 9.384877 0.606392 4.523772 ... 11.277304 34.885022 \n",
+ "3 9.384877 0.606392 4.523772 ... 11.277304 34.885022 \n",
+ "4 8.754229 3.327396 4.530104 ... 11.918027 35.292459 \n",
+ "5 6.850064 5.009906 4.085992 ... 13.764072 34.975183 \n",
+ "6 8.192379 2.467055 3.624743 ... 12.070196 34.773824 \n",
+ "7 0.000000 9.371709 7.999477 ... 17.535290 33.067928 \n",
+ "8 0.000000 0.000000 4.482462 ... 11.266665 34.919529 \n",
+ "9 0.000000 0.000000 0.000000 ... 12.783650 35.742553 \n",
+ "10 0.000000 0.000000 0.000000 ... 22.856634 24.877890 \n",
+ "11 0.000000 0.000000 0.000000 ... 37.172431 28.020323 \n",
+ "12 0.000000 0.000000 0.000000 ... 11.888749 35.903614 \n",
+ "13 0.000000 0.000000 0.000000 ... 10.667421 36.039500 \n",
+ "14 0.000000 0.000000 0.000000 ... 26.408125 31.227641 \n",
+ "15 0.000000 0.000000 0.000000 ... 13.722377 33.114574 \n",
+ "16 0.000000 0.000000 0.000000 ... 10.220223 36.211994 \n",
+ "17 0.000000 0.000000 0.000000 ... 10.472936 36.031809 \n",
+ "18 0.000000 0.000000 0.000000 ... 8.194474 38.267240 \n",
+ "19 0.000000 0.000000 0.000000 ... 10.800889 36.766399 \n",
+ "20 0.000000 0.000000 0.000000 ... 10.790561 36.465497 \n",
+ "21 0.000000 0.000000 0.000000 ... 10.894940 36.991510 \n",
+ "22 0.000000 0.000000 0.000000 ... 27.864020 36.733447 \n",
+ "23 0.000000 0.000000 0.000000 ... 13.751392 34.099356 \n",
+ "24 0.000000 0.000000 0.000000 ... 20.533660 35.469859 \n",
+ "25 0.000000 0.000000 0.000000 ... 11.703405 35.181025 \n",
+ "26 0.000000 0.000000 0.000000 ... 14.752313 29.129545 \n",
+ "27 0.000000 0.000000 0.000000 ... 10.943037 33.957596 \n",
+ "28 0.000000 0.000000 0.000000 ... 27.247120 31.942899 \n",
+ "29 0.000000 0.000000 0.000000 ... 15.479676 35.698163 \n",
+ ".. ... ... ... ... ... ... \n",
+ "252 0.000000 0.000000 0.000000 ... 3.448510 35.722079 \n",
+ "253 0.000000 0.000000 0.000000 ... 3.731540 34.504576 \n",
+ "254 0.000000 0.000000 0.000000 ... 4.540530 34.918371 \n",
+ "255 0.000000 0.000000 0.000000 ... 10.559558 35.357880 \n",
+ "256 0.000000 0.000000 0.000000 ... 3.728253 35.921477 \n",
+ "257 0.000000 0.000000 0.000000 ... 4.689337 37.630415 \n",
+ "258 0.000000 0.000000 0.000000 ... 4.051582 34.238326 \n",
+ "259 0.000000 0.000000 0.000000 ... 23.917271 26.482444 \n",
+ "260 0.000000 0.000000 0.000000 ... 10.708086 30.635202 \n",
+ "261 0.000000 0.000000 0.000000 ... 4.240323 35.127554 \n",
+ "262 0.000000 0.000000 0.000000 ... 8.608912 29.761344 \n",
+ "263 0.000000 0.000000 0.000000 ... 5.610322 34.558849 \n",
+ "264 0.000000 0.000000 0.000000 ... 3.663621 35.410620 \n",
+ "265 0.000000 0.000000 0.000000 ... 26.590804 22.973060 \n",
+ "266 0.000000 0.000000 0.000000 ... 11.252636 29.807515 \n",
+ "267 0.000000 0.000000 0.000000 ... 12.237927 25.248271 \n",
+ "268 0.000000 0.000000 0.000000 ... 37.391220 37.000107 \n",
+ "269 0.000000 0.000000 0.000000 ... 3.561336 34.688199 \n",
+ "270 0.000000 0.000000 0.000000 ... 5.776631 37.957794 \n",
+ "271 0.000000 0.000000 0.000000 ... 39.339652 13.022274 \n",
+ "272 0.000000 0.000000 0.000000 ... 0.000000 36.360062 \n",
+ "273 0.000000 0.000000 0.000000 ... 0.000000 0.000000 \n",
+ "274 0.000000 0.000000 0.000000 ... 0.000000 0.000000 \n",
+ "275 0.000000 0.000000 0.000000 ... 0.000000 0.000000 \n",
+ "276 0.000000 0.000000 0.000000 ... 0.000000 0.000000 \n",
+ "277 0.000000 0.000000 0.000000 ... 0.000000 0.000000 \n",
+ "278 0.000000 0.000000 0.000000 ... 0.000000 0.000000 \n",
+ "279 0.000000 0.000000 0.000000 ... 0.000000 0.000000 \n",
+ "280 0.000000 0.000000 0.000000 ... 0.000000 0.000000 \n",
+ "281 0.000000 0.000000 0.000000 ... 0.000000 0.000000 \n",
+ "\n",
+ " 274 275 276 277 278 279 \\\n",
+ "0 10.827650 10.332986 73.305763 12.814096 32.379255 39.603344 \n",
+ "1 10.827650 10.332986 73.305763 12.814096 32.379255 39.603344 \n",
+ "2 10.182825 10.041596 75.327944 13.371793 32.859801 41.571037 \n",
+ "3 10.182825 10.041596 75.327944 13.371793 32.859801 41.571037 \n",
+ "4 10.588733 10.408935 75.610320 13.464494 33.094732 41.946374 \n",
+ "5 11.266132 11.431231 74.869157 13.913273 33.318503 41.754932 \n",
+ "6 10.359794 10.438431 74.938815 13.457429 32.984851 41.383159 \n",
+ "7 14.088205 14.602494 71.426675 15.057407 31.774783 39.031505 \n",
+ "8 10.186184 10.041514 75.356727 13.370572 32.860239 41.596742 \n",
+ "9 11.244306 11.418035 75.075509 14.268797 32.474804 41.386025 \n",
+ "10 20.565499 20.573981 63.268304 18.995155 34.520954 33.560864 \n",
+ "11 34.670793 34.656521 59.711336 32.274947 44.105762 37.495072 \n",
+ "12 13.603039 12.851950 76.353155 16.156336 33.237701 42.477485 \n",
+ "13 12.673636 11.970012 76.776069 15.300031 33.153807 42.677692 \n",
+ "14 22.947019 23.382071 67.790984 22.442220 37.810909 39.187655 \n",
+ "15 13.314578 13.082242 71.503936 14.817873 30.949610 37.787209 \n",
+ "16 12.488691 11.589880 77.252867 15.141276 33.298005 43.154885 \n",
+ "17 12.568884 11.753075 76.897113 15.151362 33.150439 42.722551 \n",
+ "18 13.109328 11.516467 79.305553 15.742804 33.773257 44.702298 \n",
+ "19 13.325461 12.387707 77.801213 15.920443 33.664572 43.824720 \n",
+ "20 12.898171 11.975549 76.984900 15.755606 33.218124 43.026383 \n",
+ "21 13.532222 12.395966 77.767272 16.388287 33.741569 43.891024 \n",
+ "22 27.535020 27.530177 65.666987 27.482683 31.778748 34.562477 \n",
+ "23 12.216553 12.275915 73.047877 14.175184 32.059172 39.388661 \n",
+ "24 18.476965 18.846910 70.406117 19.824924 31.958215 38.158241 \n",
+ "25 9.890206 10.008000 75.379657 13.312448 33.011138 41.935878 \n",
+ "26 12.383966 12.315955 69.606314 12.891282 32.600455 37.208829 \n",
+ "27 9.522301 9.265908 74.677630 12.062871 32.535104 41.026851 \n",
+ "28 25.423766 25.574065 63.759542 24.772586 32.637077 33.376523 \n",
+ "29 14.705564 14.705922 72.840324 16.625395 30.975493 39.030125 \n",
+ ".. ... ... ... ... ... ... \n",
+ "252 8.575554 6.487675 77.305815 12.071439 32.769803 43.080685 \n",
+ "253 8.193579 6.227411 75.982061 11.444541 31.771002 41.548170 \n",
+ "254 7.334727 5.455660 76.606748 11.197877 32.656112 42.577237 \n",
+ "255 13.198497 12.052555 72.465927 15.265594 28.718863 37.884900 \n",
+ "256 10.376165 8.320452 77.429253 13.231519 32.835685 42.854703 \n",
+ "257 11.943009 9.794315 79.023176 14.629552 33.505429 44.421826 \n",
+ "258 8.196919 6.156127 75.680954 10.994382 31.901282 41.512204 \n",
+ "259 17.672909 18.908519 63.326476 17.267651 32.913053 33.794611 \n",
+ "260 7.327063 7.072394 71.204286 8.901413 31.288575 38.340343 \n",
+ "261 7.574760 5.610966 76.665618 11.216444 32.473296 42.641235 \n",
+ "262 7.471771 6.859115 71.912047 9.760597 31.920842 38.312883 \n",
+ "263 7.389604 5.576253 75.806476 10.498143 32.224656 42.104809 \n",
+ "264 8.602437 6.681988 76.335322 11.691578 31.564477 41.805131 \n",
+ "265 21.757323 22.657065 61.307622 19.593522 36.734369 34.769806 \n",
+ "266 7.902261 7.729341 70.585708 9.277355 31.280957 37.942838 \n",
+ "267 11.130596 10.311384 68.147786 10.387719 32.324964 35.810892 \n",
+ "268 35.067355 35.526694 55.564016 34.158048 28.542286 25.822767 \n",
+ "269 7.821520 5.933478 76.230116 11.427145 32.100121 41.876256 \n",
+ "270 12.780319 10.782131 79.126588 14.961919 33.438516 44.520042 \n",
+ "271 35.236933 35.417455 47.623559 31.272172 44.829251 31.894542 \n",
+ "272 9.379382 7.339407 77.143346 12.749444 31.822407 42.392777 \n",
+ "273 31.750429 32.128395 48.111290 27.840361 41.792473 28.274051 \n",
+ "274 0.000000 3.237176 73.366051 7.676929 31.651583 39.912536 \n",
+ "275 0.000000 0.000000 73.914578 7.771337 31.511371 40.344710 \n",
+ "276 0.000000 0.000000 0.000000 69.187318 66.445812 40.673806 \n",
+ "277 0.000000 0.000000 0.000000 0.000000 30.328330 36.912364 \n",
+ "278 0.000000 0.000000 0.000000 0.000000 0.000000 30.828065 \n",
+ "279 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 \n",
+ "280 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 \n",
+ "281 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 \n",
+ "\n",
+ " 280 281 \n",
+ "0 19.077412 27.950357 \n",
+ "1 19.077412 27.950357 \n",
+ "2 21.627902 30.393789 \n",
+ "3 21.627902 30.393789 \n",
+ "4 22.179193 30.857050 \n",
+ "5 22.643936 30.760145 \n",
+ "6 21.856608 30.314101 \n",
+ "7 22.443854 29.099044 \n",
+ "8 21.651322 30.422693 \n",
+ "9 22.931278 31.237437 \n",
+ "10 17.355026 21.430145 \n",
+ "11 27.755493 26.751569 \n",
+ "12 22.089583 30.737505 \n",
+ "13 21.553961 30.880786 \n",
+ "14 24.834293 28.689060 \n",
+ "15 20.689663 28.362332 \n",
+ "16 21.613249 31.120557 \n",
+ "17 21.526612 30.866441 \n",
+ "18 22.363908 32.673834 \n",
+ "19 22.108362 31.769740 \n",
+ "20 22.030473 31.310136 \n",
+ "21 22.460495 31.805582 \n",
+ "22 29.196397 32.314605 \n",
+ "23 21.796404 29.529949 \n",
+ "24 25.723348 31.208600 \n",
+ "25 22.097817 30.724826 \n",
+ "26 17.341024 25.023067 \n",
+ "27 20.590425 29.484103 \n",
+ "28 25.857232 28.232339 \n",
+ "29 23.770121 30.946807 \n",
+ ".. ... ... \n",
+ "252 20.068560 30.393663 \n",
+ "253 19.000166 29.220979 \n",
+ "254 19.646070 29.777591 \n",
+ "255 21.561178 29.489926 \n",
+ "256 19.889235 30.426639 \n",
+ "257 21.303295 32.002460 \n",
+ "258 18.697992 28.888524 \n",
+ "259 21.098635 23.671994 \n",
+ "260 17.177263 25.730924 \n",
+ "261 19.716559 29.900306 \n",
+ "262 15.701408 25.157571 \n",
+ "263 19.337602 29.332375 \n",
+ "264 19.845339 30.003714 \n",
+ "265 18.339224 20.541845 \n",
+ "266 16.586148 24.935636 \n",
+ "267 11.067518 20.598703 \n",
+ "268 35.063551 33.473112 \n",
+ "269 19.241511 29.469038 \n",
+ "270 21.210592 31.945006 \n",
+ "271 22.140707 13.767657 \n",
+ "272 20.404479 30.731355 \n",
+ "273 18.391354 12.267940 \n",
+ "274 18.171186 28.006310 \n",
+ "275 17.604591 27.817552 \n",
+ "276 60.986713 50.936505 \n",
+ "277 13.877229 23.819616 \n",
+ "278 33.616237 37.098563 \n",
+ "279 31.965103 26.287641 \n",
+ "280 0.000000 14.102711 \n",
+ "281 0.000000 0.000000 \n",
+ "\n",
+ "[282 rows x 282 columns]"
+ ]
+ },
+ "execution_count": 310,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "output_mat"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.9.12"
+ },
+ "toc": {
+ "base_numbering": 1,
+ "nav_menu": {},
+ "number_sections": true,
+ "sideBar": true,
+ "skip_h1_title": false,
+ "title_cell": "Table of Contents",
+ "title_sidebar": "Contents",
+ "toc_cell": false,
+ "toc_position": {},
+ "toc_section_display": true,
+ "toc_window_display": false
+ },
+ "varInspector": {
+ "cols": {
+ "lenName": 16,
+ "lenType": 16,
+ "lenVar": 40
+ },
+ "kernels_config": {
+ "python": {
+ "delete_cmd_postfix": "",
+ "delete_cmd_prefix": "del ",
+ "library": "var_list.py",
+ "varRefreshCmd": "print(var_dic_list())"
+ },
+ "r": {
+ "delete_cmd_postfix": ") ",
+ "delete_cmd_prefix": "rm(",
+ "library": "var_list.r",
+ "varRefreshCmd": "cat(var_dic_list()) "
+ }
+ },
+ "types_to_exclude": [
+ "module",
+ "function",
+ "builtin_function_or_method",
+ "instance",
+ "_Feature"
+ ],
+ "window_display": false
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
From 9c177f96523b8a6e61d8460246aa40112e57739e Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Fri, 10 Feb 2023 14:29:15 -0500
Subject: [PATCH 10/36] Update table_of_contents.csv
---
table_of_contents.csv | 1 +
1 file changed, 1 insertion(+)
diff --git a/table_of_contents.csv b/table_of_contents.csv
index f7d0872..6d6d70f 100644
--- a/table_of_contents.csv
+++ b/table_of_contents.csv
@@ -5,3 +5,4 @@ renaming_utilities.ipynb,File_Utilities,fasta/newick,fasta/newick,python,
varsnps.sh,Other,.fastq/fastq.gz,.bcf/.vcf,Unix,none,Finds variants using read data,Yutian Feng,In,variants/vcf/bcf,10/02/2023,N/A
wrapper_supermatrix.py/supermatrix.py,Seq_Utilities,.fasta,.fasta (aligned),Python,none,makes a concatenate of all your gene clusters,Yutian Feng,In,concatenate/msa,10/02/2023,N/A
ori_analy.py,Other,genomic.fna,.pdf/.svg/.png,python,none, find the origin of replication using gc skew,Yutian Feng,In,ori/gc skew,10/02/2023,N/A
+gene_fam_upload.ipynb,Phylogenetics_Utilities,*.mldist,matrix in .tsv,python,none, find evolutionary trajectories in the same genome,Yutian Feng,In,trajectory,10/02/2023,N/A
From e2b1c57eb36e93b0333971925d3fac7cdb3f6a44 Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Fri, 10 Feb 2023 14:56:43 -0500
Subject: [PATCH 11/36] make gene maps. must know coordinates
---
Other/gene_maps.ipynb | 350 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 350 insertions(+)
create mode 100644 Other/gene_maps.ipynb
diff --git a/Other/gene_maps.ipynb b/Other/gene_maps.ipynb
new file mode 100644
index 0000000..0d4574d
--- /dev/null
+++ b/Other/gene_maps.ipynb
@@ -0,0 +1,350 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "94676c24",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import dna_features_viewer\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "0a20460c",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(,\n",
+ " ({GF(Small feature, 0-20 (1)): 0,\n",
+ " GF(Gene 1 with a very long name, 20-500 (1)): 0,\n",
+ " GF(Gene 2, 400-700 (-1)): 1.0,\n",
+ " GF(Gene 3, 600-900 (1)): 0},\n",
+ " {GF(Gene 1 with a very long name, 20-500 (1)): {'feature_y': 0,\n",
+ " 'annotation_y': 2.0},\n",
+ " GF(Small feature, 0-20 (1)): {'feature_y': 0, 'annotation_y': 1.0}}))"
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ },
+ {
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "from dna_features_viewer import GraphicFeature, GraphicRecord\n",
+ "features=[\n",
+ " GraphicFeature(start=0, end=20, strand=+1, color=\"#ffd700\",\n",
+ " label=\"Small feature\"),\n",
+ " GraphicFeature(start=20, end=500, strand=+1, color=\"#ffcccc\",\n",
+ " label=\"Gene 1 with a very long name\"),\n",
+ " GraphicFeature(start=400, end=700, strand=-1, color=\"#cffccc\",\n",
+ " label=\"Gene 2\"),\n",
+ " GraphicFeature(start=600, end=900, strand=+1, color=\"#ccccff\",\n",
+ " label=\"Gene 3\")\n",
+ "]\n",
+ "record = GraphicRecord(sequence_length=1000, features=features)\n",
+ "record.plot(figure_width=5)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "id": "db459f3b",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(,\n",
+ " ({GF(g_5182, 500-860 (1)): 0,\n",
+ " GF(g_2884, 1010-1510 (1)): 0,\n",
+ " GF(g_4943, 1660-3025 (1)): 0,\n",
+ " GF(dppD, 3175-4297 (1)): 0,\n",
+ " GF(g_1455, 4447-5434 (1)): 0,\n",
+ " GF(gsiC, 5584-6580 (1)): 0,\n",
+ " GF(appA, 6730-8374 (1)): 0,\n",
+ " GF(g_481, 8524-10180 (1)): 0,\n",
+ " GF(g_1838, 10330-11179 (1)): 0,\n",
+ " GF(g_5047, 11329-12340 (1)): 0,\n",
+ " GF(g_2821, 12490-13012 (1)): 0},\n",
+ " {GF(g_481, 8524-10180 (1)): {'feature_y': 0, 'annotation_y': 1.0},\n",
+ " GF(appA, 6730-8374 (1)): {'feature_y': 0, 'annotation_y': 2.0},\n",
+ " GF(g_4943, 1660-3025 (1)): {'feature_y': 0, 'annotation_y': 1.0},\n",
+ " GF(dppD, 3175-4297 (1)): {'feature_y': 0, 'annotation_y': 3.0},\n",
+ " GF(g_5047, 11329-12340 (1)): {'feature_y': 0, 'annotation_y': 1.0},\n",
+ " GF(gsiC, 5584-6580 (1)): {'feature_y': 0, 'annotation_y': 1.0},\n",
+ " GF(g_1455, 4447-5434 (1)): {'feature_y': 0, 'annotation_y': 2.0},\n",
+ " GF(g_1838, 10330-11179 (1)): {'feature_y': 0, 'annotation_y': 2.0},\n",
+ " GF(g_2821, 12490-13012 (1)): {'feature_y': 0, 'annotation_y': 3.0},\n",
+ " GF(g_2884, 1010-1510 (1)): {'feature_y': 0, 'annotation_y': 2.0},\n",
+ " GF(g_5182, 500-860 (1)): {'feature_y': 0, 'annotation_y': 3.0}}))"
+ ]
+ },
+ "execution_count": 14,
+ "metadata": {},
+ "output_type": "execute_result"
+ },
+ {
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "features=[\n",
+ " GraphicFeature(start=500, end=860, strand=+1, color=\"#800080\",\n",
+ " label=\"g_5182\"),\n",
+ " GraphicFeature(start=1010, end=1510, strand=+1, color=\"#ffcccc\",\n",
+ " label=\"g_2884\"),\n",
+ " GraphicFeature(start=1660, end=3025, strand=+1, color=\"#ffcccc\",\n",
+ " label=\"g_4943\"),\n",
+ " GraphicFeature(start=3175, end=4297, strand=+1, color=\"#023020\",\n",
+ " label=\"dppD\"), #dipeptide transport ATP binding\n",
+ " GraphicFeature(start=4447, end=5434, strand=+1, color=\"#ffcccc\",\n",
+ " label=\"g_1455\"), \n",
+ " GraphicFeature(start=5584, end=6580, strand=+1, color=\"#023020\",\n",
+ " label=\"gsiC\"), #glutathionine transport permease\n",
+ " GraphicFeature(start=6730, end=8374, strand=+1, color=\"#023020\",\n",
+ " label=\"appA\"), #oligopeptide binding AppA\n",
+ " GraphicFeature(start=8524, end=10180, strand=+1, color=\"#800080\",\n",
+ " label=\"g_481\"), \n",
+ " GraphicFeature(start=10330, end=11179, strand=+1, color=\"#ccccff\",\n",
+ " label=\"g_1838\"), \n",
+ " GraphicFeature(start=11329, end=12340, strand=+1, color=\"#800080\",\n",
+ " label=\"g_5047\"),\n",
+ " GraphicFeature(start=12490, end=13012, strand=+1, color=\"#800080\",\n",
+ " label=\"g_2821\") \n",
+ "]\n",
+ "record = GraphicRecord(sequence_length=13000, features=features)\n",
+ "record.plot(figure_width=5)\n",
+ "\n",
+ "#16 follow this: 12-10-3-MGM,AMM028,AMM036,AMM037,AMM044,AMM081,LD3,UG_101,AMM034,AMM093,\n",
+ "#C191,Hxorientale, fb21,SD690R,UG_123,UG_126 #16"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "id": "b2ee2107",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(,\n",
+ " ({GF(g_5182, 500-860 (1)): 0,\n",
+ " GF(g_2725, 1010-1556 (1)): 0,\n",
+ " GF(g_757, 1706-3590 (1)): 0,\n",
+ " GF(oppD, 3740-4829 (1)): 0,\n",
+ " GF(g_533, 4979-6530 (1)): 0,\n",
+ " GF(dppB, 6680-7769 (1)): 0,\n",
+ " GF(g_340, 7919-9806 (1)): 0,\n",
+ " GF(g_481, 9956-11612 (1)): 0,\n",
+ " GF(g_1756, 11762-12641 (1)): 0,\n",
+ " GF(g_5047, 12791-13802 (1)): 0,\n",
+ " GF(g_2821, 13952-14474 (1)): 0},\n",
+ " {GF(g_340, 7919-9806 (1)): {'feature_y': 0, 'annotation_y': 1.0},\n",
+ " GF(g_757, 1706-3590 (1)): {'feature_y': 0, 'annotation_y': 3.0},\n",
+ " GF(g_481, 9956-11612 (1)): {'feature_y': 0, 'annotation_y': 3.0},\n",
+ " GF(g_533, 4979-6530 (1)): {'feature_y': 0, 'annotation_y': 1.0},\n",
+ " GF(oppD, 3740-4829 (1)): {'feature_y': 0, 'annotation_y': 2.0},\n",
+ " GF(dppB, 6680-7769 (1)): {'feature_y': 0, 'annotation_y': 2.0},\n",
+ " GF(g_5047, 12791-13802 (1)): {'feature_y': 0, 'annotation_y': 1.0},\n",
+ " GF(g_1756, 11762-12641 (1)): {'feature_y': 0, 'annotation_y': 2.0},\n",
+ " GF(g_2725, 1010-1556 (1)): {'feature_y': 0, 'annotation_y': 2.0},\n",
+ " GF(g_2821, 13952-14474 (1)): {'feature_y': 0, 'annotation_y': 3.0},\n",
+ " GF(g_5182, 500-860 (1)): {'feature_y': 0, 'annotation_y': 1.0}}))"
+ ]
+ },
+ "execution_count": 16,
+ "metadata": {},
+ "output_type": "execute_result"
+ },
+ {
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "features=[\n",
+ " GraphicFeature(start=500, end=860, strand=+1, color=\"#800080\",\n",
+ " label=\"g_5182\"),\n",
+ " GraphicFeature(start=1010, end=1556, strand=+1, color=\"#ffcccc\",\n",
+ " label=\"g_2725\"),\n",
+ " GraphicFeature(start=1706, end=3590, strand=+1, color=\"#ffcccc\",\n",
+ " label=\"g_757\"),\n",
+ " GraphicFeature(start=3740, end=4829, strand=+1, color=\"#023020\",\n",
+ " label=\"oppD\"), #oligopeptide transport ATP binding\n",
+ " GraphicFeature(start=4979, end=6530, strand=+1, color=\"#ffcccc\",\n",
+ " label=\"g_533\"), \n",
+ " GraphicFeature(start=6680, end=7769, strand=+1, color=\"#023020\",\n",
+ " label=\"dppB\"), #dipeptide transport permease\n",
+ " GraphicFeature(start=7919, end=9806, strand=+1, color=\"#ffcccc\",\n",
+ " label=\"g_340\"), \n",
+ " GraphicFeature(start=9956, end=11612, strand=+1, color=\"#800080\",\n",
+ " label=\"g_481\"), \n",
+ " GraphicFeature(start=11762, end=12641, strand=+1, color=\"#00FFFF\",\n",
+ " label=\"g_1756\"), \n",
+ " GraphicFeature(start=12791, end=13802, strand=+1, color=\"#800080\",\n",
+ " label=\"g_5047\"),\n",
+ " GraphicFeature(start=13952, end=14474, strand=+1, color=\"#800080\",\n",
+ " label=\"g_2821\") \n",
+ "]\n",
+ "record = GraphicRecord(sequence_length=15000, features=features)\n",
+ "record.plot(figure_width=5)\n",
+ "\n",
+ "#AMM032,AMM045,AMM088,Ec15,Ga36,UG_23,UG_39,UG_66,UG_96, G37,Hxluteum, M4-25-10-8A\n",
+ "#AMM011,AMM013,AMM016,AMM018,AMM027,AMM059,AMM063 #19"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 18,
+ "id": "6ddb8934",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(,\n",
+ " ({GF(g_5182, 500-860 (1)): 0,\n",
+ " GF(g_2725, 1010-1556 (1)): 0,\n",
+ " GF(g_757, 1706-3590 (1)): 0,\n",
+ " GF(oppD, 3740-4829 (1)): 0,\n",
+ " GF(g_533, 4979-6530 (1)): 0,\n",
+ " GF(dppB, 6680-7769 (1)): 0,\n",
+ " GF(g_340, 7919-9806 (1)): 0,\n",
+ " GF(g_481, 9956-11612 (1)): 0,\n",
+ " GF(g_1756, 11762-12641 (1)): 0,\n",
+ " GF(g_5047, 12791-13802 (1)): 0,\n",
+ " GF(g_1192, 13952-15059 (1)): 0,\n",
+ " GF(g_1763, 15209-16088 (1)): 0,\n",
+ " GF(g_1762, 16238-17117 (1)): 0,\n",
+ " GF(g_4172, 17267-17477 (1)): 0,\n",
+ " GF(g_4526, 17627-17765 (1)): 0,\n",
+ " GF(g_3723, 17915-18212 (1)): 0,\n",
+ " GF(g_2821, 18362-18884 (1)): 0},\n",
+ " {GF(g_340, 7919-9806 (1)): {'feature_y': 0, 'annotation_y': 2.0},\n",
+ " GF(g_757, 1706-3590 (1)): {'feature_y': 0, 'annotation_y': 3.0},\n",
+ " GF(g_481, 9956-11612 (1)): {'feature_y': 0, 'annotation_y': 3.0},\n",
+ " GF(g_533, 4979-6530 (1)): {'feature_y': 0, 'annotation_y': 1.0},\n",
+ " GF(g_1192, 13952-15059 (1)): {'feature_y': 0, 'annotation_y': 3.0},\n",
+ " GF(oppD, 3740-4829 (1)): {'feature_y': 0, 'annotation_y': 2.0},\n",
+ " GF(dppB, 6680-7769 (1)): {'feature_y': 0, 'annotation_y': 3.0},\n",
+ " GF(g_5047, 12791-13802 (1)): {'feature_y': 0, 'annotation_y': 2.0},\n",
+ " GF(g_1756, 11762-12641 (1)): {'feature_y': 0, 'annotation_y': 1.0},\n",
+ " GF(g_1763, 15209-16088 (1)): {'feature_y': 0, 'annotation_y': 4.0},\n",
+ " GF(g_1762, 16238-17117 (1)): {'feature_y': 0, 'annotation_y': 1.0},\n",
+ " GF(g_2725, 1010-1556 (1)): {'feature_y': 0, 'annotation_y': 1.0},\n",
+ " GF(g_2821, 18362-18884 (1)): {'feature_y': 0, 'annotation_y': 3.0},\n",
+ " GF(g_5182, 500-860 (1)): {'feature_y': 0, 'annotation_y': 2.0},\n",
+ " GF(g_3723, 17915-18212 (1)): {'feature_y': 0, 'annotation_y': 2.0},\n",
+ " GF(g_4172, 17267-17477 (1)): {'feature_y': 0, 'annotation_y': 5.0},\n",
+ " GF(g_4526, 17627-17765 (1)): {'feature_y': 0, 'annotation_y': 6.0}}))"
+ ]
+ },
+ "execution_count": 18,
+ "metadata": {},
+ "output_type": "execute_result"
+ },
+ {
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "features=[\n",
+ " GraphicFeature(start=500, end=860, strand=+1, color=\"#800080\",\n",
+ " label=\"g_5182\"),\n",
+ " GraphicFeature(start=1010, end=1556, strand=+1, color=\"#ffcccc\",\n",
+ " label=\"g_2725\"),\n",
+ " GraphicFeature(start=1706, end=3590, strand=+1, color=\"#ffcccc\",\n",
+ " label=\"g_757\"),\n",
+ " GraphicFeature(start=3740, end=4829, strand=+1, color=\"#023020\",\n",
+ " label=\"oppD\"), #oligopeptide transport ATP binding\n",
+ " GraphicFeature(start=4979, end=6530, strand=+1, color=\"#ffcccc\",\n",
+ " label=\"g_533\"), \n",
+ " GraphicFeature(start=6680, end=7769, strand=+1, color=\"#023020\",\n",
+ " label=\"dppB\"), #dipeptide transport permease\n",
+ " GraphicFeature(start=7919, end=9806, strand=+1, color=\"#ffcccc\",\n",
+ " label=\"g_340\"), \n",
+ " GraphicFeature(start=9956, end=11612, strand=+1, color=\"#800080\",\n",
+ " label=\"g_481\"), \n",
+ " GraphicFeature(start=11762, end=12641, strand=+1, color=\"#00FFFF\",\n",
+ " label=\"g_1756\"), \n",
+ " GraphicFeature(start=12791, end=13802, strand=+1, color=\"#800080\",\n",
+ " label=\"g_5047\"),\n",
+ " GraphicFeature(start=13952, end=15059, strand=+1, color=\"#FFFF00\",\n",
+ " label=\"g_1192\"),\n",
+ " GraphicFeature(start=15209, end=16088, strand=+1, color=\"#FFFF00\",\n",
+ " label=\"g_1763\"),\n",
+ " GraphicFeature(start=16238, end=17117, strand=+1, color=\"#FFFF00\",\n",
+ " label=\"g_1762\"),\n",
+ " GraphicFeature(start=17267, end=17477, strand=+1, color=\"#FFFF00\",\n",
+ " label=\"g_4172\"),\n",
+ " GraphicFeature(start=17627, end=17765, strand=+1, color=\"#FFFF00\",\n",
+ " label=\"g_4526\"),\n",
+ " GraphicFeature(start=17915, end=18212, strand=+1, color=\"#FFFF00\",\n",
+ " label=\"g_3723\"),\n",
+ " GraphicFeature(start=18362, end=18884, strand=+1, color=\"#800080\",\n",
+ " label=\"g_2821\") \n",
+ "]\n",
+ "record = GraphicRecord(sequence_length=19000, features=features)\n",
+ "record.plot(figure_width=5)\n",
+ "#the 10 UG's"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.9.12"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
From c1c8ea97018e02b1080179f65eb58d9118e7ae94 Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Fri, 10 Feb 2023 14:57:38 -0500
Subject: [PATCH 12/36] Update table_of_contents.csv
---
table_of_contents.csv | 1 +
1 file changed, 1 insertion(+)
diff --git a/table_of_contents.csv b/table_of_contents.csv
index 6d6d70f..efdb07d 100644
--- a/table_of_contents.csv
+++ b/table_of_contents.csv
@@ -6,3 +6,4 @@ varsnps.sh,Other,.fastq/fastq.gz,.bcf/.vcf,Unix,none,Finds variants using read d
wrapper_supermatrix.py/supermatrix.py,Seq_Utilities,.fasta,.fasta (aligned),Python,none,makes a concatenate of all your gene clusters,Yutian Feng,In,concatenate/msa,10/02/2023,N/A
ori_analy.py,Other,genomic.fna,.pdf/.svg/.png,python,none, find the origin of replication using gc skew,Yutian Feng,In,ori/gc skew,10/02/2023,N/A
gene_fam_upload.ipynb,Phylogenetics_Utilities,*.mldist,matrix in .tsv,python,none, find evolutionary trajectories in the same genome,Yutian Feng,In,trajectory,10/02/2023,N/A
+gene_maps.ipynb,Other,list of coordinates for genes,image,python,none, makes gene/operon maps,Yutian Feng,In,gene maps,10/02/2023,N/A
From c2a8d8942fb8673885866dc57b0c47beb71f4b24 Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Fri, 10 Feb 2023 14:59:53 -0500
Subject: [PATCH 13/36] splits a multi fasta into single fastas
---
Sequence_Alignment_Utilities/parse.py | 12 ++++++++++++
1 file changed, 12 insertions(+)
create mode 100644 Sequence_Alignment_Utilities/parse.py
diff --git a/Sequence_Alignment_Utilities/parse.py b/Sequence_Alignment_Utilities/parse.py
new file mode 100644
index 0000000..ecdda32
--- /dev/null
+++ b/Sequence_Alignment_Utilities/parse.py
@@ -0,0 +1,12 @@
+#!/usr/bin/env python
+f=open("core_genes.txt","r");
+opened = False
+for line in f :
+ if(line[0] == ">") :
+ if(opened) :
+ of.close()
+ opened = True
+ of=open("%s" + ".fa" % (line[1:].rstrip()), "w")
+ print(line[1:].rstrip())
+ of.write(line)
+of.close()
From 69728d9a07c1871842aa94155dc25ab3f5c39fc7 Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Fri, 10 Feb 2023 15:00:51 -0500
Subject: [PATCH 14/36] Update table_of_contents.csv
---
table_of_contents.csv | 1 +
1 file changed, 1 insertion(+)
diff --git a/table_of_contents.csv b/table_of_contents.csv
index efdb07d..9c30409 100644
--- a/table_of_contents.csv
+++ b/table_of_contents.csv
@@ -7,3 +7,4 @@ wrapper_supermatrix.py/supermatrix.py,Seq_Utilities,.fasta,.fasta (aligned),Pyth
ori_analy.py,Other,genomic.fna,.pdf/.svg/.png,python,none, find the origin of replication using gc skew,Yutian Feng,In,ori/gc skew,10/02/2023,N/A
gene_fam_upload.ipynb,Phylogenetics_Utilities,*.mldist,matrix in .tsv,python,none, find evolutionary trajectories in the same genome,Yutian Feng,In,trajectory,10/02/2023,N/A
gene_maps.ipynb,Other,list of coordinates for genes,image,python,none, makes gene/operon maps,Yutian Feng,In,gene maps,10/02/2023,N/A
+parse.py,Sequence_Alignment_Utilities,multi.fasta,.fasta,python,none, splits a fasta into smaller fastas,Yutian Feng,In,fasta,10/02/2023,N/A
From 77b7e2eb4479ceeaf171706571e83eedd8240ab8 Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Fri, 10 Feb 2023 15:03:57 -0500
Subject: [PATCH 15/36] find avg. nuc. identitiy to build phylogeny with
bootstrap support
---
Phylogenetic_Utilities/tANI_low_mem.pl | 422 +++++++++++++++++++++++++
1 file changed, 422 insertions(+)
create mode 100644 Phylogenetic_Utilities/tANI_low_mem.pl
diff --git a/Phylogenetic_Utilities/tANI_low_mem.pl b/Phylogenetic_Utilities/tANI_low_mem.pl
new file mode 100644
index 0000000..84259c6
--- /dev/null
+++ b/Phylogenetic_Utilities/tANI_low_mem.pl
@@ -0,0 +1,422 @@
+#!/usr/bin/perl -w
+use warnings;
+use strict;
+use threads;
+use threads::shared;
+
+#Subdirectories
+mkdir "Outputs";
+mkdir "Outputs/AF";
+mkdir "Outputs/Distance";
+mkdir "Outputs/gANI";
+mkdir "Outputs/jANI";
+mkdir "Intermediates";
+mkdir "Intermediates/splits";
+mkdir "Intermediates/BLAST";
+mkdir "Intermediates/blastdb";
+
+#globals
+my @genomefiles = glob "*.fna *.fasta *.faa *.contig *.fa *.contigs";
+my $evalue = "1E-4";
+my $task = "";
+my ($identity,$coverage,$bootnum);
+my (%matrix,%all_lengths,%bootmatrix):shared;
+
+#Parse Input
+if (!exists $ARGV[0]){
+ die "\nNo inputs detected, please use Default, or type -H for assistance.\n\n";
+}
+elsif ($ARGV[0] eq "-H"){
+ die "\nThe following options are available:\n\n\t-ID:# - The identity cutoff value (0-100).\n\t-CV:# - The coverage cutoff value (0-100).\n\t-BT:# - The number of nonparametric bootstraps for tree building (0-n).\n\t-EVAL:# - Change E-Value cutoff of BLAST search.\n\t-TASK:'task name' If you wish to change which default settings BLAST uses for its search criteria.\n\t-Default - Uses default search criteria as described in Gosselin et al. 2020.\n\nIf you encounter negative values in your matrix, or critical errors send an email to sean.gosselin\@uconn.edu. I will try to answer in a reasonable fassion.\n\n\n";
+}
+elsif ($ARGV[0] eq "-Default"){
+ $identity = .7;
+ $coverage = .7;
+ $bootnum = 100;
+}
+else{
+ foreach my $Inputs (@ARGV){
+ if ($Inputs =~ /\-ID\:(.*)/){
+ if ($1 < 1){
+ $identity = ($1*100);
+ }
+ else{
+ $identity = $1;
+ }
+ }
+ elsif ($Inputs =~ /\-CV\:(.*)/){
+ if ($1 > 1){
+ $coverage = ($1/100);
+ }
+ else{
+ $coverage = $1;
+ }
+ }
+ elsif ($Inputs =~ /\-BT\:(.*)/){
+ $bootnum = $1;
+ }
+ elsif ($Inputs =~ /\-EVAL\:(.*)/){
+ $evalue = $1;
+ }
+ elsif ($Inputs =~ /\-TASK\:(.*)/){
+ $task = "-task $1";
+ }
+ }
+}
+
+#Check inputs.
+#Could this be more nicely done? Yes. Will I fix this later? Yes.
+
+if($identity){}
+else{
+ print "\nIdentity value not defined. Use standard (.7)? [Y|N]\n";
+ my $idencheck = ;
+ chomp $idencheck;
+ if($idencheck eq "Y"){
+ $identity=.7;
+ }
+ else{
+ die "Need ID value to run. Stopping.\n";
+ }
+}
+
+if($coverage){}
+else{
+ print "\nCoverage value not defined. Use standard (.7)? [Y|N]\n";
+ my $covcheck = ;
+ chomp $covcheck;
+ if($covcheck eq "Y"){
+ $coverage=.7;
+ }
+ else{
+ die "Need CV value to run. Stopping.\n";
+ }
+}
+
+if($bootnum){}
+else{
+ print "\nBoot value not defined, do you want to use standard (100)? [Y|N]\n";
+ my $bootcheck = ;
+ chomp $bootcheck;
+ if($bootcheck eq "Y"){
+ $bootnum=100;
+ }
+ else{
+ die "Need bootstrap (BT) count. Stopping.\n";
+ }
+}
+
+#mainworkflow
+if (@genomefiles){
+ #splits genomes into fragmented files, and creates blast databases
+ #also creates a reference file for lengths. Acts as a checkpoint.
+ if(-e "Intermediates/genome_lengths.txt"){
+ open (WGL, "< Intermediates/genome_lengths.txt");
+ while(){
+ my @split = split;
+ $all_lengths{$split[0]}=$split[1];
+ }
+ close WGL;
+ }
+ else{
+ threaded("SplitGenomes",\@genomefiles);
+ open (WGL, "+> Intermediates/genome_lengths.txt");
+ foreach my $genome (sort keys %all_lengths){
+ print WGL "$genome\t$all_lengths{$genome}\n";
+ }
+ close WGL;
+ }
+ #comprehensive all vs. all BLAST searches and database creation
+ threaded("BlastGenome",\@genomefiles);
+ #Calculating distance, ANI, AF, and gANI
+ threaded("Calculate_ANI",\@genomefiles);
+ #outs to file. Sends file type
+ Outfile("orig","orig",%matrix);
+ #bootstrapping
+ for (my $bc=0; $bc<$bootnum; $bc++){
+ threaded("Bootstrap_ANI",\@genomefiles);
+ Outfile($bc,"matrix",%bootmatrix);
+ %bootmatrix=();
+ }
+}
+else{
+ print "\nNo genomes present in directory that are recognized.\n\nMake sure to use FASTA formatted files.\n\n";
+}
+
+sub threaded{
+ my ($sub,$arrayref) = @_;
+ my @refdarray = @{$arrayref};
+ my @threads;
+ foreach my $entry (@refdarray){
+ my $thread = threads ->create(\&$sub,$entry);
+ push @threads, $thread;
+ }
+ $_->join() for @threads;
+}
+
+sub SplitGenomes {
+ #splits genomes into 1020, and formats blastdb's
+ open (FILE_TO_SPLIT, "< $_[0]");
+ my ($annotation_counter,$wholegenome) = 0;
+ my (%printhash);
+ my ($annotation,$sequenceinput)="";
+ while(){
+ if ($_=~/\>/){
+ if($annotation_counter==0){
+ $annotation_counter++;
+ }
+ else{
+ my $contiglength = (length($sequenceinput));
+ my @cutcontig =($sequenceinput =~ /(.{1,1020})/g);
+ $wholegenome += $contiglength;
+ $sequenceinput = "";
+ foreach my $cuts (@cutcontig){
+ my $cutl=length($cuts);
+ next if $cutl < 100;
+ my $contigname = "$annotation"."\_$annotation_counter"."\_$contiglength"."\_$cutl";
+ $printhash{$contigname}=$cuts;
+ $annotation_counter++;
+ }
+ }
+ ($annotation) = ($_=~/\>(.*?)[\n\s]/);
+ $annotation =~ s/\s//g;
+ }
+ else{
+ chomp $_;
+ $sequenceinput .= $_;
+ }
+ }
+ my @cutcontig =($sequenceinput =~ /(.{1,1020})/g);
+ my $contiglength = (length($sequenceinput));
+ $wholegenome += $contiglength;
+ $sequenceinput = "";
+ foreach my $cuts (@cutcontig){
+ my $cutl=length($cuts);
+ next if $cutl < 100;
+ my $contigname = "$annotation"."\_$annotation_counter"."\_$contiglength"."\_$cutl";
+ $printhash{$contigname}=$cuts;
+ $annotation_counter++;
+ }
+ close FILE_TO_SPLIT;
+ $all_lengths{$_[0]}=$wholegenome;
+ open (SPLIT, "+> Intermediates/splits/$_[0].split");
+ foreach my $contigname (sort keys %printhash){
+ print SPLIT ">$contigname\n$printhash{$contigname}\n";
+ }
+ close SPLIT;
+ if (-e "Intermediates/blastdb/$_[0].nhr"){
+ }
+ else{
+ system("makeblastdb -dbtype nucl -in $_[0] -input_type fasta -max_file_sz 2GB -out Intermediates/blastdb/$_[0]");
+ }
+}
+
+sub BlastGenome {
+ #self explanitory
+ foreach my $database (@genomefiles){
+ if($database eq $_[0]){
+ next;
+ }
+ elsif (-e "Intermediates/BLAST/$_[0]+$database.blast"){
+ if(-z "Intermediates/BLAST/$_[0]+$database.blast"){
+ system("blastn -db Intermediates/blastdb/$database -query Intermediates/splits/$_[0].split -evalue $evalue -outfmt 6 -out 'Intermediates/BLAST/$_[0]+$database.blast' $task");
+ }
+ else{
+ next;
+ }
+ }
+ else{
+ system("blastn -db Intermediates/blastdb/$database -query Intermediates/splits/$_[0].split -evalue $evalue -outfmt 6 -out 'Intermediates/BLAST/$_[0]+$database.blast' $task");
+ }
+ }
+}
+
+#All calculations are done here; name misleading
+sub Calculate_ANI{
+ #readin query information
+ open(SPLIT, "< Intermediates/splits/$_[0].split");
+ my(%qsplitsize);
+ while(){
+ if($_=~/\>/){
+ my($annotation,$splitsize)=($_=~/\>(.*\_.*?\_.*?\_(.*))/);
+ $qsplitsize{$annotation}=$splitsize;
+ }
+ else{}
+ }
+ close SPLIT;
+ foreach my $database (@genomefiles){
+ if($database eq $_[0]){
+ $matrix{"$_[0]\+$_[0]"} = "1.0\t1.0\t1.0\t0.0";
+ next;
+ }
+ else{}
+ #readin database information
+ open(DB, "< Intermediates/splits/$database.split");
+ my(%dbsplitsize,%dbcontigsize);
+ while(){
+ if($_=~/\>/){
+ my($annotation,$consize)=($_=~/\>(.*)\_.*?\_(.*?)\_.*/);
+ next if exists $dbcontigsize{$annotation};
+ $dbcontigsize{$annotation}=$consize;
+ }
+ else{}
+ }
+ close DB;
+ #start filtering BLAST output
+ my(%BestHits,$gANINumerator,$TotalShort,$TotalID,$shortergene);
+ my $HitCounter = 0;
+ open(BLAST_FILE, "< Intermediates/BLAST/$_[0]+$database.blast");
+ while(){
+ my @Blast_Lines = split;
+ next if exists $BestHits{$Blast_Lines[0]};
+ next if $Blast_Lines[2] < $identity;
+ if ($dbcontigsize{$Blast_Lines[1]} <= $qsplitsize{$Blast_Lines[0]}){
+ $shortergene = $dbcontigsize{$Blast_Lines[1]};
+ }
+ else{
+ $shortergene = $qsplitsize{$Blast_Lines[0]};
+ }
+ next if ($shortergene == 0);
+ next if (($Blast_Lines[3]/$shortergene) < $coverage);
+ my $gANIindv = ($Blast_Lines[3]*($Blast_Lines[2]/100));
+ $BestHits{$Blast_Lines[0]} = 1;
+ $gANINumerator += $gANIindv;
+ $TotalShort += $shortergene;
+ $HitCounter ++;
+ $TotalID += $Blast_Lines[2];
+ }
+ close BLAST_FILE;
+ if($HitCounter == 0){
+ $matrix{"$_[0]\+$database"} = "0.00\t0.00\t0.00\t13.00";
+ }
+ else{
+ my $jANI = ($TotalID/$HitCounter);
+ my $gANI = ($gANINumerator/$TotalShort);
+ my $AF = ($TotalShort/$all_lengths{$_[0]});
+ my $gDistance = -log($gANINumerator/$all_lengths{$_[0]});
+ $matrix{"$_[0]\+$database"} = "$jANI\t$gANI\t$AF\t$gDistance";
+ }
+ }
+}
+
+sub Bootstrap_ANI{
+ #readin query information
+ open(SPLIT, "< Intermediates/splits/$_[0].split");
+ my(%qsplitsize,%randomsample,$bootsize);
+ my $counter = 0;
+ while(){
+ if($_=~/\>/){
+ my($annotation,$splitsize)=($_=~/\>(.*\_.*?\_.*?\_(.*))/);
+ $qsplitsize{$annotation}=$splitsize;
+ $counter++;
+ }
+ else{}
+ }
+ close SPLIT;
+ my @q_keys = keys %qsplitsize;
+ for(my $rngcount=0; $rngcount<$counter; $rngcount++){
+ $randomsample{$rngcount} = $q_keys[rand @q_keys];
+ }
+ foreach my $database (@genomefiles){
+ if($database eq $_[0]){
+ $bootmatrix{"$_[0]\+$_[0]"} = "1.0\t1.0\t1.0\t0.0";
+ next;
+ }
+ else{}
+ #readin database information
+ open(DB, "< Intermediates/splits/$database.split");
+ my(%dbsplitsize,%dbcontigsize);
+ while(){
+ if($_=~/\>/){
+ my($annotation,$consize)=($_=~/\>(.*)\_.*?\_(.*?)\_.*/);
+ next if exists $dbcontigsize{$annotation};
+ $dbcontigsize{$annotation}=$consize;
+ }
+ else{}
+ }
+ close DB;
+ #start filtering BLAST output
+ my(%BestHits,$gANINumerator,$TotalShort,$TotalID,$shortergene);
+ my $HitCounter = 0;
+ open(BLAST_FILE, "< Intermediates/BLAST/$_[0]+$database.blast");
+ while(){
+ my @Blast_Lines = split;
+ next if exists $BestHits{$Blast_Lines[0]};
+ next if $Blast_Lines[2] < $identity;
+ if ($dbcontigsize{$Blast_Lines[1]} <= $qsplitsize{$Blast_Lines[0]}){
+ $shortergene = $dbcontigsize{$Blast_Lines[1]};
+ }
+ else{
+ $shortergene = $qsplitsize{$Blast_Lines[0]};
+ }
+ next if ($shortergene == 0);
+ next if (($Blast_Lines[3]/$shortergene) < $coverage);
+ my $gANIindv = ($Blast_Lines[3]*($Blast_Lines[2]/100));
+ $BestHits{$Blast_Lines[0]} = "$gANIindv\t$Blast_Lines[2]\t$shortergene";
+ }
+ close BLAST_FILE;
+ foreach my $sample (values %randomsample){
+ if(exists $BestHits{$sample}){
+ my @split = split(/ /,$BestHits{$sample});
+ $gANINumerator += $split[0];
+ $TotalShort += $split[2];
+ $HitCounter++;
+ $TotalID += $split[1];
+ }
+ else{
+ }
+ }
+ if($HitCounter == 0){
+ $bootmatrix{"$_[0]\+$database"} = "0.00\t0.00\t0.00\t13.00";
+ }
+ else{
+ my $jANI = ($TotalID/$HitCounter);
+ my $gANI = ($gANINumerator/$TotalShort);
+ my $AF = ($TotalShort/$all_lengths{$_[0]});
+ my $gDistance = -log($gANINumerator/$all_lengths{$_[0]});
+ $bootmatrix{"$_[0]\+$database"} = "$jANI\t$gANI\t$AF\t$gDistance";
+ }
+ }
+}
+
+sub Outfile{
+ #number or indicator to go after the _ but before file extension.
+ my $u1 = shift;
+ #file extension
+ my $u2 = shift;
+ #content of the matrices
+ my %toprint = @_;
+ #checker tool
+ my $currentline = "hi";
+ my %handles;
+ my @outfiles = ("Outputs/jANI/jANI","Outputs/gANI/gANI","Outputs/AF/AF","Outputs/Distance/Distance");
+ foreach my $out1 (@outfiles){
+ open (my $fh, "+>", "$out1\_$u1\.$u2");
+ print {$fh} join("\t",sort @genomefiles);
+ #try a print join approach when you have time
+ $handles{$out1}=$fh;
+ }
+ foreach my $value (sort keys %toprint){
+ my ($check) = ($value =~ /(.*?)\+.*/);
+ if ($check eq $currentline){
+ my $num = 0;
+ my @outputs = split(/ /,$toprint{$value});
+ foreach my $out (@outfiles){
+ print {$handles{$out}} "\t$outputs[$num]";
+ $num++;
+ }
+ }
+ else{
+ $currentline = $check;
+ my $num = 0;
+ my @outputs = split(/ /,$toprint{$value});
+ foreach my $out (@outfiles){
+ print {$handles{$out}} "\n$check\t$outputs[$num]";
+ $num++;
+ }
+ }
+ }
+ foreach my $out2 (@outfiles){
+ close $handles{$out2};
+ }
+}
From 149386d935f2a8b3a3efe80c424f13a981436285 Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Fri, 10 Feb 2023 15:05:08 -0500
Subject: [PATCH 16/36] Update table_of_contents.csv
---
table_of_contents.csv | 1 +
1 file changed, 1 insertion(+)
diff --git a/table_of_contents.csv b/table_of_contents.csv
index 9c30409..5c90069 100644
--- a/table_of_contents.csv
+++ b/table_of_contents.csv
@@ -8,3 +8,4 @@ ori_analy.py,Other,genomic.fna,.pdf/.svg/.png,python,none, find the origin of re
gene_fam_upload.ipynb,Phylogenetics_Utilities,*.mldist,matrix in .tsv,python,none, find evolutionary trajectories in the same genome,Yutian Feng,In,trajectory,10/02/2023,N/A
gene_maps.ipynb,Other,list of coordinates for genes,image,python,none, makes gene/operon maps,Yutian Feng,In,gene maps,10/02/2023,N/A
parse.py,Sequence_Alignment_Utilities,multi.fasta,.fasta,python,none, splits a fasta into smaller fastas,Yutian Feng,In,fasta,10/02/2023,N/A
+tANI_low_mem.pl,Phylogenetics_Utilities,*.fna,matrices in .csv,perl,none, tANI method,Sophia Gosselin,In,tANI,10/02/2023,N/A
From d58d71268cda7729fcc884f250c1da8eed367724 Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Fri, 10 Feb 2023 15:06:36 -0500
Subject: [PATCH 17/36] trims contig to include sequnence of interest with 5000
nt upstream/downstream
---
Other/contigtrimmer.pl | 69 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 69 insertions(+)
create mode 100644 Other/contigtrimmer.pl
diff --git a/Other/contigtrimmer.pl b/Other/contigtrimmer.pl
new file mode 100644
index 0000000..255c7b7
--- /dev/null
+++ b/Other/contigtrimmer.pl
@@ -0,0 +1,69 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+
+my $infasta=$ARGV[0];
+
+open FH1 , "$infasta" or die "$!";
+
+
+
+my @sequence ="";
+my $first = "";
+my $second ="";
+my $begin="";
+my $end="";
+my $front = "";
+my $back = "";
+my $final = "";
+while(){
+ chomp;
+ @sequence = split /\t/, $_;
+ $first = $sequence[6];
+ $second = $sequence[7];
+ if ($first > $second) {
+ $begin = $second;
+ $end = $first;
+ }
+ else{
+ $begin = $first;
+ $end = $second;
+ }
+ my $frontflank = int($begin)-1000;
+ my $backflank = int($end+1000);
+ my $seqname = $sequence[0];
+ open FH2, "$seqname".".seqfile";
+ my $worthless ="";
+ my $cds= "";
+ while(){
+ chomp;
+ if(/^\>(.*)/){
+ $worthless = $worthless . $_;
+ }
+ else{
+ $cds = $cds . $_;
+ }
+ }
+
+ my @readin = split //, $cds;
+
+
+ while ($frontflank < $backflank){
+ $front = $front . $readin[$frontflank];
+ $frontflank += 1;
+
+ }
+
+ $final = $front ;
+
+ print ">".$sequence[0].".seqfile2\n".$final."\n";
+ @sequence ="";
+ $front ="";
+ $final ="";
+ $back ="";
+ $first = "";
+ $second ="";
+ $begin="";
+ $end="";
+}
From 258f2989c244fe44b0a7ec258237b2279d363ad1 Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Fri, 10 Feb 2023 15:07:42 -0500
Subject: [PATCH 18/36] Update table_of_contents.csv
---
table_of_contents.csv | 1 +
1 file changed, 1 insertion(+)
diff --git a/table_of_contents.csv b/table_of_contents.csv
index 5c90069..5726ed0 100644
--- a/table_of_contents.csv
+++ b/table_of_contents.csv
@@ -9,3 +9,4 @@ gene_fam_upload.ipynb,Phylogenetics_Utilities,*.mldist,matrix in .tsv,python,non
gene_maps.ipynb,Other,list of coordinates for genes,image,python,none, makes gene/operon maps,Yutian Feng,In,gene maps,10/02/2023,N/A
parse.py,Sequence_Alignment_Utilities,multi.fasta,.fasta,python,none, splits a fasta into smaller fastas,Yutian Feng,In,fasta,10/02/2023,N/A
tANI_low_mem.pl,Phylogenetics_Utilities,*.fna,matrices in .csv,perl,none, tANI method,Sophia Gosselin,In,tANI,10/02/2023,N/A
+contigtrimmer.pl,Other,.fna,.fasta(s),perl,none, trims contigs keeps 5000 flanking nucleotides,Yutian Feng,In,trimmer,10/02/2023,N/A
From f76dcf1b3ec4ecbaea7bafb34d9b78a7f116e409 Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Fri, 10 Feb 2023 15:14:07 -0500
Subject: [PATCH 19/36] core-genome rarefaction sampling experiments
---
Other/rarefaction_curve.R | 75 +++++++++++++++++++++++++++++++++++++++
1 file changed, 75 insertions(+)
create mode 100644 Other/rarefaction_curve.R
diff --git a/Other/rarefaction_curve.R b/Other/rarefaction_curve.R
new file mode 100644
index 0000000..066f898
--- /dev/null
+++ b/Other/rarefaction_curve.R
@@ -0,0 +1,75 @@
+# =========================================================
+# R script to generate core genome rarefaction curves.
+# Script by Leonardos Mageiros, February 2014
+# =========================================================
+# The input format is shown in sample_input.csv included
+# in this archive. 1=gene present/0=gene absent;
+# 1 column= 1 genome.
+# =========================================================
+# Requests should be made to s.k.sheppard@swansea.ac.uk
+# Visit our lab website: http://www.sheppardlab.com/
+# =========================================================
+# Associated publication: Meric et al. (2014) A reference
+# pan-genome approach to comparative bacterial genomics:
+# identification of novel epidemiological markers in
+# pathogenic Campylobacter
+# =========================================================
+
+
+#Define working directory
+setwd("C:/work/development/R");
+
+#read the input file.
+#The input file must have no header row and column.
+#rows corespond to genes, columns corespond to isolates
+data <- read.table("sample_input.csv", sep="\t");
+transposed_data <- t(data);#we transpose the table to run a for loop row-wise
+nr_rows <- nrow(transposed_data);
+nr_cols <- ncol(transposed_data);
+nr_iterations <- 100; #the number of iterations
+
+#the matrix which will hold the results
+core_results <- matrix(data=NA,nrow=nr_rows,ncol=nr_iterations);
+#a vector the holds the updated results of each iteration
+presence_line <- matrix(data=0,nrow=1,ncol=nr_cols);
+
+# the times that we will run our calculation
+for(times in 1:nr_iterations){
+
+ #for all the rows of the table
+ for (i in 1: nr_rows){
+ sum <- 0;
+ if(i==1){ #for the first row
+ for(j in 1: nr_cols){#calculate the number of genes
+ presence_line[1,j]<-transposed_data[i,j]
+ sum <- sum + transposed_data[i,j];
+ }
+ #and store the first result
+ core_results[i,times] <- sum
+ next;
+ }
+
+ #for every consecutive row, for every gene
+ for(j in 1: nr_cols){
+ #if the gene was and is present count it
+ if(presence_line[1,j] && transposed_data[i,j]){
+ presence_line[1,j] <- 1;
+ }# else dont
+ else{presence_line[1,j] <- 0;}
+ }
+ #count the total number of present genes
+ for(j in 1: nr_cols){
+ sum <- sum + presence_line[1,j];
+ }
+ #store the result
+ core_results[i,times] <- sum;
+
+ }
+ #suffle the matrix and repeat the procedure
+ transposed_data <- transposed_data[sample(nrow(transposed_data),nrow(transposed_data)), ]
+}
+
+#print the results in a tab delemeter file
+write.table(core_results, file = "core_genome.txt", sep="\t");
+
+
From 98be7291c09d271052e7ba703bbb8559ac6b62bc Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Fri, 10 Feb 2023 15:14:38 -0500
Subject: [PATCH 20/36] build phylogeney from matrix distance data
---
Other/buildtree_w_support.R | 78 +++++++++++++++++++++++++++++++++++++
1 file changed, 78 insertions(+)
create mode 100644 Other/buildtree_w_support.R
diff --git a/Other/buildtree_w_support.R b/Other/buildtree_w_support.R
new file mode 100644
index 0000000..a026335
--- /dev/null
+++ b/Other/buildtree_w_support.R
@@ -0,0 +1,78 @@
+# Built for use with the tANI distance and associated methodology
+# Hence matrices are not symmetrical and need to be averaged
+
+
+# If you are not using the tANI script you will need to change these inputs.
+# Make sure your bootstrapped matrices have a unique file extension i.e. .matrix
+ANI_orig_file <- "Distance_.orig"
+bootstrap_suffix <- "*.matrix"
+
+library(ape)
+library(phangorn)
+library(MASS)
+library(Matrix)
+library(reshape2)
+library(OpenMx)
+library(stringr)
+
+# Read in table with DDH info
+ANI_orig <- read.table(file = ANI_orig_file,sep="\t",header=TRUE,stringsAsFactors=FALSE)
+
+#Grab diag for later overwrite
+ANI_orig_diag <- diag2vec(ANI_orig) #Pull out the diagonal of the ANI matrix
+
+# Transpose matrix to flip triangles
+t_ANI_orig <- t(ANI_orig)
+
+# Average the two triangle
+Comb_ANI_orig <- (ANI_orig + t_ANI_orig) / 2
+
+# Reassert the diagonal
+diag(Comb_ANI_orig) <- ANI_orig_diag
+
+#write fastme.bal tree for the distance, write to file, and draw in the plotter
+tree_orig <- fastme.bal(as.matrix(Comb_ANI_orig), nni = TRUE, spr = TRUE, tbr = TRUE)
+write.tree(tree_orig,file="BestTree.tre")
+plot(tree_orig)
+
+# Read in the bootstrap trees
+file_list <- list.files(pattern = bootstrap_suffix)
+BS_set <- list()
+for(a in 1:length(file_list)){
+ BS_set[[a]] <- as.matrix(read.table(file = file_list[a], sep = "\t", row.names = 1, header = TRUE, stringsAsFactors = FALSE))
+}
+
+for(b in 1:length(BS_set)){
+
+ BS_current <- BS_set[[b]]
+ #Grab diag for later overwrite
+ ANI_BS_diag <- diag2vec(BS_current) #Pull out the diagonal of the ANI matrix
+
+ # Transpose matrix to flip triangles
+ t_ANI_BS <- t(BS_current)
+
+ # Average the two triangle
+ Comb_ANI_BS <- (BS_current + t_ANI_BS) / 2
+
+ # Reassert the diagonal
+ diag(Comb_ANI_BS) <- ANI_BS_diag
+
+ bs_tree <- fastme.bal(Comb_ANI_BS, nni = TRUE, spr = TRUE, tbr = TRUE)
+ write.tree(bs_tree,file="BootstrapTrees.tre",append=TRUE)
+}
+
+#Apply Bootstraps to best tree
+
+#bring in the bootsrapped trees from the file
+bs_trees <- read.tree(file="BootstrapTrees.tre")
+
+#bring in the bootsrapped trees from the file
+tree_orig <- read.tree(file="BestTree.tre")
+
+#map the trees as splits with frequencies of splits
+clade_map <- as.splits(bs_trees)
+
+#Plots the bootstrap splits onto best tree
+write.tree(plotBS(tree_orig,bs_trees,p=1),file="BestTree_wSupport.tre")
+
+
From 99cfed5e0ed2aa31cb25c8ae04d162a43931bf44 Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Fri, 10 Feb 2023 15:15:11 -0500
Subject: [PATCH 21/36] Delete placeholder.txt
---
Other/placeholder.txt | 1 -
1 file changed, 1 deletion(-)
delete mode 100644 Other/placeholder.txt
diff --git a/Other/placeholder.txt b/Other/placeholder.txt
deleted file mode 100644
index 8b13789..0000000
--- a/Other/placeholder.txt
+++ /dev/null
@@ -1 +0,0 @@
-
From db7b5f4a95fae4b749c04cb9c8bc4e20ca586925 Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Fri, 10 Feb 2023 15:16:07 -0500
Subject: [PATCH 22/36] build phylogeny with distance data includes
bootstrapping
---
Other/buildtree_w_support.R | 1 -
1 file changed, 1 deletion(-)
diff --git a/Other/buildtree_w_support.R b/Other/buildtree_w_support.R
index a026335..163554f 100644
--- a/Other/buildtree_w_support.R
+++ b/Other/buildtree_w_support.R
@@ -1,7 +1,6 @@
# Built for use with the tANI distance and associated methodology
# Hence matrices are not symmetrical and need to be averaged
-
# If you are not using the tANI script you will need to change these inputs.
# Make sure your bootstrapped matrices have a unique file extension i.e. .matrix
ANI_orig_file <- "Distance_.orig"
From 4f8a3eda32ccf0426da6ff5685eaba7e56a8e1c5 Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Fri, 10 Feb 2023 15:16:34 -0500
Subject: [PATCH 23/36] pan-genome accumulation sampling experiments
---
Other/accumulation_curve.R | 73 ++++++++++++++++++++++++++++++++++++++
1 file changed, 73 insertions(+)
create mode 100644 Other/accumulation_curve.R
diff --git a/Other/accumulation_curve.R b/Other/accumulation_curve.R
new file mode 100644
index 0000000..2dc73bd
--- /dev/null
+++ b/Other/accumulation_curve.R
@@ -0,0 +1,73 @@
+# =========================================================
+# R script to generate pan-genome accumulation curves.
+# Script by Leonardos Mageiros, February 2014
+# =========================================================
+# The input format is shown in sample_input.csv included
+# in this archive. 1=gene present/0=gene absent;
+# 1 column= 1 genome.
+# =========================================================
+# Requests should be made to s.k.sheppard@swansea.ac.uk
+# Visit our lab website: http://www.sheppardlab.com/
+# =========================================================
+# Associated publication: Meric et al. (2014) A reference
+# pan-genome approach to comparative bacterial genomics:
+# identification of novel epidemiological markers in
+# pathogenic Campylobacter
+# =========================================================
+
+#Define working directory
+setwd("C:/work/development/R");
+
+#read the input file.
+#The input file must have no header row and column.
+#rows corespond to genes, columns corespond to isolates
+data <- read.table("sample_input.csv", sep="\t");
+transposed_data <- t(data);#we transpose the table to run a for loop row-wise
+nr_rows <- nrow(transposed_data);
+nr_cols <- ncol(transposed_data);
+nr_iterations <- 100;#the number of iterations
+
+#the matrix which will hold the results
+core_results <- matrix(data=NA,nrow=nr_rows,ncol=nr_iterations);
+#a vector the holds the updated results of each iteration
+presence_line <- matrix(data=0,nrow=1,ncol=nr_cols);
+
+# the times that we will run our calculation
+for(times in 1: nr_iterations){
+
+ #for all the rows of the table
+ for (i in 1: nr_rows){
+ sum <- 0;
+ if(i==1){ #for the first row
+ for(j in 1: nr_cols){#calculate the number of genes
+ presence_line[1,j]<-transposed_data[i,j]
+ sum <- sum + transposed_data[i,j];
+ }
+ #and store the first result
+ core_results[i,times] <- sum
+ next;
+ }
+
+ #for every consecutive row, for every gene
+ for(j in 1: nr_cols){
+ #if we find e new gene count it
+ if(presence_line[1,j] || transposed_data[i,j]){
+ presence_line[1,j] <- 1;
+ }
+ else{presence_line[1,j] <- 0;}
+ }
+ #count the total number of present genes
+ for(j in 1: nr_cols){
+ sum <- sum + presence_line[1,j];
+ }
+ #store the result
+ core_results[i,times] <- sum;
+
+ }
+ #suffle the matrix and repeat the procedure
+ transposed_data <- transposed_data[sample(nrow(transposed_data),nrow(transposed_data)), ]
+}
+
+#print the results in a tab delemeter file
+write.table(core_results, file = "pan_genome.txt", sep="\t");
+
From a63a1805e6719810760af8390cf094741a894260 Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Fri, 10 Feb 2023 15:19:28 -0500
Subject: [PATCH 24/36] Update table_of_contents.csv
---
table_of_contents.csv | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/table_of_contents.csv b/table_of_contents.csv
index 5726ed0..d0ae19a 100644
--- a/table_of_contents.csv
+++ b/table_of_contents.csv
@@ -10,3 +10,7 @@ gene_maps.ipynb,Other,list of coordinates for genes,image,python,none, makes gen
parse.py,Sequence_Alignment_Utilities,multi.fasta,.fasta,python,none, splits a fasta into smaller fastas,Yutian Feng,In,fasta,10/02/2023,N/A
tANI_low_mem.pl,Phylogenetics_Utilities,*.fna,matrices in .csv,perl,none, tANI method,Sophia Gosselin,In,tANI,10/02/2023,N/A
contigtrimmer.pl,Other,.fna,.fasta(s),perl,none, trims contigs keeps 5000 flanking nucleotides,Yutian Feng,In,trimmer,10/02/2023,N/A
+accumulation_curve.R,Other,pan genome matrix,re-sampling matrix in .tsv,R,none, pan-genome resampling experiment,Yutian Feng,In,accumulation,10/02/2023,N/A
+rarefaction_curve.R,Other,pan genome matrix,re-sampling matrix in .tsv,R,none, core-genome resampling experiment,Yutian Feng,In,rarefaction,10/02/2023,N/A
+buildtree_w_support.R,Other,genome tANI matrix,image or newick,R,none, buidls distance based phylogenies,Sophia Gosselin,In,tANI phylogeny,10/02/2023,N/A
+
From 6b4002e720b13fd2d9c1e42af0e35ae28c8377fd Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Fri, 10 Feb 2023 15:20:31 -0500
Subject: [PATCH 25/36] roots a phylogeny using minimal ancestor deviation
---
Phylogenetic_Utilities/mad.R | 173 +++++++++++++++++++++++++++++++++++
1 file changed, 173 insertions(+)
create mode 100644 Phylogenetic_Utilities/mad.R
diff --git a/Phylogenetic_Utilities/mad.R b/Phylogenetic_Utilities/mad.R
new file mode 100644
index 0000000..8898f7b
--- /dev/null
+++ b/Phylogenetic_Utilities/mad.R
@@ -0,0 +1,173 @@
+mad <- function(unrooted_newick,output_mode){
+ if(nargs()==0){ #print help message
+ return(cat("Minimal Ancestor Deviation (MAD) rooting","","Usage: res <- mad(unrooted_newick,output_mode)","",
+ "unrooted_newick: Unrooted tree string in newick format or a tree object of class 'phylo'","",
+ "output_mode: Amount of information to return.", " If 'newick' (default) only the rooted newick string",
+ " If 'stats' also a structure with the ambiguity index, clock cv, the minimum ancestor deviation and the number of roots",
+ " If 'full' also an unrooted tree object, the index of the root branch, the branch ancestor deviations and a rooted tree object",
+ "","res: a list with the results containing one ('newick'), two ('stats') or six elements ('full')","",
+ "Dependencies: 'ape' and 'phytools'","","Version: 1.1, 03-May-2017",sep="\n"))
+ }
+ if (!library('ape',logical.return = TRUE)){
+ stop("'ape' package not found, please install it to run mad")
+ }
+ if (!library('phytools',logical.return = TRUE)){
+ stop("'phytools' package not found, please install it to run mad")
+ }
+ t <- NA
+ if(class(unrooted_newick)=="phylo"){
+ t <- unrooted_newick
+ }
+ else{
+ t <- read.tree(text=unrooted_newick)
+ }
+ if(is.rooted(t)){
+ t<-unroot(t)
+ }
+ #t$node.label<-NULL #To allow parsing when identical OTUs are present
+ if(!is.binary.tree(t)){
+ warning("Input tree is not binary! Internal multifurcations will be converted to branches of length zero and identical OTUs will be collapsed!")
+ t<-multi2di(t)
+ }
+ tf <- t$edge.length<0
+ if(any(tf)){
+ warning("Input tree contains negative branch lengths. They will be converted to zeros!")
+ t$edge.length[tf]<-0
+ }
+
+
+ notu <- length(t$tip.label)
+ nbranch <- dim(t$edge)[1]
+ npairs <- notu*(notu-1)/2
+ nodeids <- 1:(nbranch+1)
+ otuids <- 1:notu
+ dis <- dist.nodes(t) # phenetic distance. All nodes
+ sdis <- dis[1:notu,1:notu] # phenetic distance. otus only
+
+ #### Start recursion to collapse identical OTUs, if present.
+ ii<-which(sdis==0,arr.ind=TRUE)
+ k<-which(ii[,1]!=ii[,2])
+ if(length(k)){
+ r<-ii[k[1],1]
+ c<-ii[k[1],2]
+ vv<-c(paste('@#',t$tip.label[r],'@#',sep=""),paste('(',t$tip.label[r],':0,',t$tip.label[c],':0)',sep=""))
+ st<-drop.tip(t,c)
+ st$tip.label[st$tip.label==t$tip.label[r]]<-vv[1]
+ res<-mad(st,output_mode)
+ if(is.list(res)){
+ res[[1]]<-sub(vv[1],vv[2],res[[1]])
+ }
+ else{
+ res<-sub(vv[1],vv[2],res)
+ }
+ return(res) #create the list 'res' to return the results
+ }
+ #### End of recursion
+
+ t2 <- t
+ t2$edge.length <- rep(1,nbranch)
+ disbr <- dist.nodes(t2) # split distance. All nodes
+ sdisbr <- disbr[1:notu,1:notu] # split distance. otus only
+ rho <- vector(mode = "numeric",length = nbranch) # Store position of the optimized root nodes (branch order as in the input tree)
+ bad <- vector(mode = "numeric",length = nbranch) # Store branch ancestor deviations (branch order as in the input tree)
+ i2p <- matrix(nrow = nbranch+1, ncol = notu)
+ for (br in 1:nbranch){
+ #collect the deviations associated with straddling otu pairs
+ dij <- t$edge.length[br]
+ if(dij==0){
+ rho[br]<-NA
+ bad[br]<-NA
+ next
+ }
+ rbca <- numeric(npairs)
+ i <- t$edge[br,1]
+ j <- t$edge[br,2]
+ sp <- dis[1:notu,i]=2){
+ disbrw <- disbr[,ij[w]]
+ pairids <- otuids[bcsp[w,]]
+ for (z in pairids){
+ i2p[,z] <- disbr[z,]+disbrw==disbrw[z]
+ }
+ for (z in 1:(length(pairids)-1)){
+ p1 <- pairids[z]
+ disp1 <- dis[p1,]
+ pan <- nodeids[i2p[,p1]]
+ for (y in (z+1):length(pairids)){
+ p2 <- pairids[y]
+ pan1 <- pan[i2p[pan,p2]]
+ an <- pan1[which.max(disbrw[pan1])]
+ counter <- counter+1
+ rbca[counter] <- 2*disp1[an]/disp1[p2]-1
+ }
+ }
+ }
+ }
+ if(length(rbca)!=npairs){
+ stop("Unexpected number of pairs. Report this error to ftria@ifam.uni-kiel.de")
+ }
+ bad[br] <- sqrt(mean(rbca^2)) # branch ancestor deviation
+ }
+ # Select the branch with the minum ancestor deviation and calculate the root ambiguity index
+ jj <- sort(bad,index.return = TRUE)
+ tf<-bad==jj$x[1]
+ tf[is.na(tf)]<-FALSE
+ nroots <- sum(tf)
+ if (nroots>1){
+ warning("More than one possible root position. Multiple newick strings printed")
+ }
+ madr <- which(tf) # Index of the mad root branch(es)
+ rai <- jj$x[1]/jj$x[2] # Root ambiguity index
+ badr <- bad[tf] # Branch ancestor deviations value for the root(s)
+ #Root the tree object, calculate the clock CV and retrieve the newick string
+ rt <- vector(mode = "list",nroots) # Rooted tree object
+ ccv <- vector(mode = "numeric",nroots) # Clock CV
+ rooted_newick <- vector(mode = "character",nroots)
+ for (i in 1:length(madr)){
+ pp <- rho[madr[i]]*t$edge.length[madr[i]]
+ nn <- t$edge[madr[i],]
+ rt[[i]] <- reroot(t,nn[2],pos = pp)
+ rooted_newick[i] <- write.tree(rt[[i]])
+ dd <- dis[1:notu,nn]
+ sp <- dd[,1]
Date: Fri, 10 Feb 2023 15:23:27 -0500
Subject: [PATCH 26/36] Update table_of_contents.csv
---
table_of_contents.csv | 1 +
1 file changed, 1 insertion(+)
diff --git a/table_of_contents.csv b/table_of_contents.csv
index d0ae19a..21017b0 100644
--- a/table_of_contents.csv
+++ b/table_of_contents.csv
@@ -13,4 +13,5 @@ contigtrimmer.pl,Other,.fna,.fasta(s),perl,none, trims contigs keeps 5000 flanki
accumulation_curve.R,Other,pan genome matrix,re-sampling matrix in .tsv,R,none, pan-genome resampling experiment,Yutian Feng,In,accumulation,10/02/2023,N/A
rarefaction_curve.R,Other,pan genome matrix,re-sampling matrix in .tsv,R,none, core-genome resampling experiment,Yutian Feng,In,rarefaction,10/02/2023,N/A
buildtree_w_support.R,Other,genome tANI matrix,image or newick,R,none, buidls distance based phylogenies,Sophia Gosselin,In,tANI phylogeny,10/02/2023,N/A
+mad.R,Phylogenetic Utilities,.newick/.phylip,.newick or image,R,none, roots tree using MAD,Yutian Feng,In,minimum ancestor deviation,10/02/2023,N/A
From 2143edb07d682156dab1d2c1948fa603f4e23503 Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Fri, 10 Feb 2023 15:25:09 -0500
Subject: [PATCH 27/36] compares distance matrices using categorical Mantel
---
Other/cat_mat_corr.r | 124 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 124 insertions(+)
create mode 100644 Other/cat_mat_corr.r
diff --git a/Other/cat_mat_corr.r b/Other/cat_mat_corr.r
new file mode 100644
index 0000000..25ba676
--- /dev/null
+++ b/Other/cat_mat_corr.r
@@ -0,0 +1,124 @@
+#functions deriving a (potentially exact) Mantel-like test of whether values in a
+#quantitative matrix differ between levels of a factor in a categorical matrix
+#orders of rows and columns within and across the two matrices must be identical
+#and the two matrices must be of the exact same size and both be quadratic
+#all three functions are needed
+#written by Roger Mundry
+#version Apr. 04, 2013
+#arguments of the function cat.mantel.test are:
+#val.mat: numeric; the matrix with the quantitites
+#cat.mat: numeric, character or factor; the matrix with the categorical variable
+#part: character, the parts of the matrix to be used; can be one of "upper", "lower" or "all"
+#with lower and upper refering to the lower left and upper right triangle, respectively
+#exact.thresh: numeric; for samples larger than this value an approximate permutation test is applied
+#(default is 9, and I recommend to stick with this)
+#n.perm: number of permuations used in the approximate case
+#(default is 10000, and I recommend to stick with this or enlarge it)
+#val.mat, cat.mat: the two matrices to be correlated; are assumed to be square , with equal
+#returns a list with three objects
+#one is named 'result' and a data frame which should be self explaing
+#the other functions are just needed by the main function, but the user doesn't need to worry about them
+
+require(gtools)
+cat.mantel.test<-function(val.mat, cat.mat, part, exact.thresh=9, n.perm=1000, response=c("quantitative", "categorical"), test.stat=mean){
+ response=response[1]
+ if(is.data.frame(cat.mat)){
+ cat.mat=matrix(as.character(unlist(cat.mat)), ncol=ncol(cat.mat), byrow=F)
+ }
+ if(is.data.frame(val.mat)){
+ val.mat=matrix(as.numeric(as.character(unlist(val.mat))), ncol=ncol(val.mat), byrow=F)
+ }
+ if(part=="upper" | part=="lower"){
+ val.mat=convert.mat(val.mat, part)
+ cat.mat=convert.mat(cat.mat, part)
+ }
+ if(response=="quantitative"){
+ orig=measure.test.stat(v.mat=val.mat, c.mat=cat.mat, part=part, test.stat=test.stat)
+ }else{
+ orig=data.frame(value=0)
+ orig$value=measure.test.stat.cat.resp(v.mat=val.mat, c.mat=cat.mat, part=part)
+ }
+ mat.size=ncol(cat.mat)
+ if(mat.size>exact.thresh){
+ appr=1
+ all.res=orig$value
+ }else{
+ perms=permutations(mat.size,mat.size)
+ n.perm=nrow(perms)
+ all.res=c()
+ appr=0
+ }
+ for (i in 1:(n.perm-appr)){
+ if (appr==1){
+ new.ind=sample(1:mat.size, mat.size, replace=F)
+ }else{
+ new.ind=perms[i,]
+ }
+ ran.mat=cat.mat[new.ind, new.ind]
+ if(response=="quantitative"){
+ all.res=rbind(all.res, measure.test.stat(v.mat=val.mat, c.mat=ran.mat, part=part, test.stat=test.stat)$value)
+ }else{
+ all.res=rbind(all.res, measure.test.stat.cat.resp(v.mat=val.mat, c.mat=ran.mat, part=part))
+ }
+ }
+ orig=data.frame(orig, P=apply(all.res, 2, function(x){return(sum(x>=x[1]))})/n.perm)
+ if(appr==1){method="approximate"}else{method="exact"}
+ if(response=="quantitative"){
+ return(list(result=orig, method=method, n.perm=n.perm, response=response))
+ }else{
+ list(result=orig, method=method, n.perm=n.perm, response=response)
+ }
+}
+
+measure.test.stat<-function(v.mat, c.mat, part, test.stat){
+ if(part=="all-diag"){
+ v.mat=c(v.mat[lower.tri(v.mat)],v.mat[upper.tri(v.mat)])
+ c.mat=c(c.mat[lower.tri(c.mat)],c.mat[upper.tri(c.mat)])
+ }else if(part=="all+diag"){
+ v.mat=unlist(c(v.mat))
+ c.mat=unlist(c(c.mat))
+ }else if(part=="lower"){
+ v.mat=as.vector(v.mat[lower.tri(v.mat)])
+ c.mat=as.vector(c.mat[lower.tri(c.mat)])
+ }else if(part=="upper"){
+ v.mat=as.vector(v.mat[upper.tri(v.mat)])
+ c.mat=as.vector(c.mat[upper.tri(c.mat)])
+ }
+ xres=tapply(v.mat, c.mat, FUN=test.stat)
+ total=sum((xres-mean(xres))^2)
+ i.res=abs(outer(xres, xres, "-"))
+ i.res.names=outer(names(xres), names(xres), function(x, y){paste(x, y, sep=" vs. ")})
+ return(data.frame(comparison=c("all", i.res.names[lower.tri(i.res.names)]), value=c(total, i.res[lower.tri(i.res)])))
+}
+
+measure.test.stat.cat.resp<-function(v.mat, c.mat, part){
+ if(part=="all-diag"){
+ v.mat=c(v.mat[lower.tri(v.mat)],v.mat[upper.tri(v.mat)])
+ c.mat=c(c.mat[lower.tri(c.mat)],c.mat[upper.tri(c.mat)])
+ }else if(part=="all+diag"){
+ v.mat=unlist(c(v.mat))
+ c.mat=unlist(c(c.mat))
+ }else if(part=="lower"){
+ v.mat=as.vector(v.mat[lower.tri(v.mat)])
+ c.mat=as.vector(c.mat[lower.tri(c.mat)])
+ }else if(part=="upper"){
+ v.mat=as.vector(v.mat[upper.tri(v.mat)])
+ c.mat=as.vector(c.mat[upper.tri(c.mat)])
+ }
+ xx=table(v.mat, c.mat)
+ E=outer(rowSums(xx), colSums(xx), "*")/sum(xx)
+ return(sum(((xx-E)^2)/E))
+}
+
+convert.mat<-function(mat, part){
+ if (part=="lower"){
+ xxt=t(mat)
+ xxt[lower.tri(xxt)==T]=mat[lower.tri(mat)==T]
+ mat=xxt
+ }else if(part=="upper"){
+ xxt=t(mat)
+ mat[lower.tri(mat)==T]=xxt[lower.tri(xxt)==T]
+ }
+ return(mat)
+}
+
From 18105df24051c6a870f3793efa8b500cb07e4062 Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Fri, 10 Feb 2023 15:26:35 -0500
Subject: [PATCH 28/36] Update table_of_contents.csv
---
table_of_contents.csv | 1 +
1 file changed, 1 insertion(+)
diff --git a/table_of_contents.csv b/table_of_contents.csv
index 21017b0..5e4c064 100644
--- a/table_of_contents.csv
+++ b/table_of_contents.csv
@@ -14,4 +14,5 @@ accumulation_curve.R,Other,pan genome matrix,re-sampling matrix in .tsv,R,none,
rarefaction_curve.R,Other,pan genome matrix,re-sampling matrix in .tsv,R,none, core-genome resampling experiment,Yutian Feng,In,rarefaction,10/02/2023,N/A
buildtree_w_support.R,Other,genome tANI matrix,image or newick,R,none, buidls distance based phylogenies,Sophia Gosselin,In,tANI phylogeny,10/02/2023,N/A
mad.R,Phylogenetic Utilities,.newick/.phylip,.newick or image,R,none, roots tree using MAD,Yutian Feng,In,minimum ancestor deviation,10/02/2023,N/A
+cat_mat_corr.R,Other,distance matrix,statistical summary,R,none, compares two distance matrices and categorically evaluates if different,Yutian Feng,In,mantel distance matrix,10/02/2023,N/A
From 7dcafc97684cd3019cb46622b2f0a5402df5cea1 Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Fri, 10 Feb 2023 15:31:58 -0500
Subject: [PATCH 29/36] c60 mixture model for a 4 letter alphabet
---
Phylogenetic_Utilities/C60sr4.nex | 127 ++++++++++++++++++++++++++++++
1 file changed, 127 insertions(+)
create mode 100644 Phylogenetic_Utilities/C60sr4.nex
diff --git a/Phylogenetic_Utilities/C60sr4.nex b/Phylogenetic_Utilities/C60sr4.nex
new file mode 100644
index 0000000..5515b38
--- /dev/null
+++ b/Phylogenetic_Utilities/C60sr4.nex
@@ -0,0 +1,127 @@
+#nexus
+
+begin models;
+
+frequency C60NT1= 0.6671684132 0.0296031604 0.263873245 0.0393551815;
+
+frequency C60NT2= 0.1276338907 0.0209812196 0.7927062299 0.0586786597;
+
+frequency C60NT3= 0.0163962994 0.0051413956 0.0030074531 0.975454852;
+
+frequency C60NT4= 0.43894983 0.1822394649 0.0174009227 0.3614097825;
+
+frequency C60NT5= 0.0979385646 0.2096596198 0.0222763602 0.6701254554;
+
+frequency C60NT6= 0.245811863 0.1332129821 0.5371646791 0.083810476;
+
+frequency C60NT7= 0.0226930145 0.3959457214 0.0091927563 0.5721685078;
+
+frequency C60NT8= 0.5015838424 0.4308125086 0.0079650295 0.0596386196;
+
+frequency C60NT9= 0.2221963854 0.3881879363 0.1020538807 0.2875617976;
+
+frequency C60NT10= 0.2637737779 0.1509966633 0.2145338888 0.3706956701;
+
+frequency C60NT11= 0.192147964 0.0110024977 0.7823009601 0.0145485781;
+
+frequency C60NT12= 0.1484234234 0.0338349152 0.4455828719 0.3721587895;
+
+frequency C60NT13= 0.7701156248 0.0361294714 0.0511613978 0.142593506;
+
+frequency C60NT14= 0.4210820539 0.0363523971 0.0088100421 0.5337555069;
+
+frequency C60NT15= 0.4443921233 0.0693293801 0.4521540079 0.0341244887;
+
+frequency C60NT16= 0.3775042704 0.0269821801 0.580257087 0.0152564625;
+
+frequency C60NT17= 0.4767453479 0.034379142 0.1231147917 0.3657607185;
+
+frequency C60NT18= 0.0268679326 0.0169276748 0.0098917288 0.9463126639;
+
+frequency C60NT19= 0.3018006878 0.0294470475 0.6420354145 0.0267168502;
+
+frequency C60NT20= 0.3419571734 0.0262071154 0.6184824034 0.0133533078;
+
+frequency C60NT21= 0.0096247416 0.9088039403 0.0103815544 0.0711897638;
+
+frequency C60NT22= 0.1999965426 0.0297517307 0.2954127651 0.4748389616;
+
+frequency C60NT23= 0.1127907248 0.5495098576 0.0691492727 0.268550145;
+
+frequency C60NT24= 0.0776920852 0.0329607437 0.0190469923 0.8703001788;
+
+frequency C60NT25= 0.8938602529 0.0175688123 0.0516233175 0.0369476173;
+
+frequency C60NT26= 0.27898143 0.2724136798 0.2567784573 0.1918264331;
+
+frequency C60NT27= 0.498929145 0.0363065742 0.3503605267 0.1144037542;
+
+frequency C60NT28= 0.2681948281 0.06920056 0.5207582638 0.1418463481;
+
+frequency C60NT29= 0.2045159736 0.0339698809 0.0436529982 0.7178611476;
+
+frequency C60NT30= 0.2691226215 0.0356845278 0.162767839 0.5324250117;
+
+frequency C60NT31= 0.7694198604 0.0996406504 0.090926784 0.040012705;
+
+frequency C60NT32= 0.015577726 0.0724312301 0.0067063212 0.9052847226;
+
+frequency C60NT33= 0.0832030401 0.1132575475 0.2862435644 0.5172958479;
+
+frequency C60NT34= 0.0509990348 0.0082496135 0.0061309345 0.9346204172;
+
+frequency C60NT35= 0.7537265064 0.0213859704 0.1711138164 0.0537737068;
+
+frequency C60NT36= 0.909000965 0.0289286367 0.0266394188 0.0354309794;
+
+frequency C60NT37= 0.9546241163 0.008441069 0.0316827792 0.0052520355;
+
+frequency C60NT38= 0.5192884454 0.0572862542 0.3797587173 0.0436665831;
+
+frequency C60NT39= 0.1341646585 0.5925517098 0.1874442682 0.0858393636;
+
+frequency C60NT40= 0.0448326475 0.0307205308 0.0250541698 0.8993926521;
+
+frequency C60NT41= 0.5664706531 0.0393032078 0.3812930448 0.0129330943;
+
+frequency C60NT42= 0.8370819783 0.0190256158 0.1290970633 0.0147953427;
+
+frequency C60NT43= 0.1120464953 0.0574737723 0.799428803 0.0310509292;
+
+frequency C60NT44= 0.5567531248 0.030047458 0.113077382 0.3001220351;
+
+frequency C60NT45= 0.7530681463 0.0296715581 0.1919452504 0.0253150453;
+
+frequency C60NT46= 0.0813111668 0.4663342365 0.3315560742 0.1207985224;
+
+frequency C60NT47= 0.3493942031 0.0181602391 0.5911205418 0.0413250161;
+
+frequency C60NT48= 0.7273938304 0.0224960247 0.2440348688 0.0060752763;
+
+frequency C60NT49= 0.144800238 0.0781260939 0.6995327663 0.0775409016;
+
+frequency C60NT50= 0.5558261942 0.0217135959 0.355400139 0.0670600707;
+
+frequency C60NT51= 0.0142277933 0.577157862 0.0046886186 0.4039257261;
+
+frequency C60NT52= 0.566952106 0.1662596481 0.0829557817 0.1838324641;
+
+frequency C60NT53= 0.3710307018 0.2568582793 0.3304267825 0.0416842365;
+
+frequency C60NT54= 0.4673591892 0.0443703034 0.0644933219 0.4237771855;
+
+frequency C60NT55= 0.2935718655 0.0371033744 0.5025606284 0.1667641317;
+
+frequency C60NT56= 0.1445054403 0.0175105032 0.8019947085 0.035989348;
+
+frequency C60NT57= 0.5953413269 0.0543418469 0.3379976485 0.0123191777;
+
+frequency C60NT58= 0.5011346064 0.0186312309 0.4456054968 0.034628666;
+
+frequency C60NT59= 0.8862685333 0.0262544484 0.0131639188 0.0743130995;
+
+frequency C60NT60= 0.0386456469 0.0058035261 0.0121187396 0.9434320874;
+
+model C60SR4=GTR+G+FMIX{C60NT1,C60NT2,C60NT3,C60NT4,C60NT5,C60NT6,C60NT7,C60NT8,C60NT9,C60NT10,C60NT11,C60NT12,C60NT13,C60NT14,C60NT15,C60NT16,C60NT17,C60NT18,C60NT19,C60NT20,C60NT21,C60NT22,C60NT23,C60NT24,C60NT25,C60NT26,C60NT27,C60NT28,C60NT29,C60NT30,C60NT31,C60NT32,C60NT33,C60NT34,C60NT35,C60NT36,C60NT37,C60NT38,C60NT39,C60NT40,C60NT41,C60NT42,C60NT43,C60NT44,C60NT45,C60NT46,C60NT47,C60NT48,C60NT49,C60NT50,C60NT51,C60NT52,C60NT53,C60NT54,C60NT55,C60NT56,C60NT57,C60NT58,C60NT59,C60NT60}+F;
+
+end;
\ No newline at end of file
From 5fbe97b930e663904c0e4471584078b292920ed1 Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Fri, 10 Feb 2023 15:33:13 -0500
Subject: [PATCH 30/36] Delete placeholder.txt
---
File_Utilities/placeholder.txt | 1 -
1 file changed, 1 deletion(-)
delete mode 100644 File_Utilities/placeholder.txt
diff --git a/File_Utilities/placeholder.txt b/File_Utilities/placeholder.txt
deleted file mode 100644
index 8b13789..0000000
--- a/File_Utilities/placeholder.txt
+++ /dev/null
@@ -1 +0,0 @@
-
From 062346dfde4273e06f58a68aef214f3475532560 Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Fri, 10 Feb 2023 15:33:34 -0500
Subject: [PATCH 31/36] Delete placeholder.txt
---
Phylogenetic_Utilities/placeholder.txt | 1 -
1 file changed, 1 deletion(-)
delete mode 100644 Phylogenetic_Utilities/placeholder.txt
diff --git a/Phylogenetic_Utilities/placeholder.txt b/Phylogenetic_Utilities/placeholder.txt
deleted file mode 100644
index 8b13789..0000000
--- a/Phylogenetic_Utilities/placeholder.txt
+++ /dev/null
@@ -1 +0,0 @@
-
From 3b8c7f2e320d8d89ebba31ce3378cb5326edf8bf Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Fri, 10 Feb 2023 15:33:43 -0500
Subject: [PATCH 32/36] Delete placeholder.txt
---
Sequence_Alignment_Utilities/placeholder.txt | 1 -
1 file changed, 1 deletion(-)
delete mode 100644 Sequence_Alignment_Utilities/placeholder.txt
diff --git a/Sequence_Alignment_Utilities/placeholder.txt b/Sequence_Alignment_Utilities/placeholder.txt
deleted file mode 100644
index 8b13789..0000000
--- a/Sequence_Alignment_Utilities/placeholder.txt
+++ /dev/null
@@ -1 +0,0 @@
-
From 680dbe9f8dff0adb8f6c3489761a77db9c962821 Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Fri, 10 Feb 2023 15:34:32 -0500
Subject: [PATCH 33/36] c60 mixture model for a 4 letter alphabet
---
Phylogenetic_Utilities/C60sr4.nex | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/Phylogenetic_Utilities/C60sr4.nex b/Phylogenetic_Utilities/C60sr4.nex
index 5515b38..844e13a 100644
--- a/Phylogenetic_Utilities/C60sr4.nex
+++ b/Phylogenetic_Utilities/C60sr4.nex
@@ -123,5 +123,4 @@ frequency C60NT59= 0.8862685333 0.0262544484 0.0131639188 0.0743130995;
frequency C60NT60= 0.0386456469 0.0058035261 0.0121187396 0.9434320874;
model C60SR4=GTR+G+FMIX{C60NT1,C60NT2,C60NT3,C60NT4,C60NT5,C60NT6,C60NT7,C60NT8,C60NT9,C60NT10,C60NT11,C60NT12,C60NT13,C60NT14,C60NT15,C60NT16,C60NT17,C60NT18,C60NT19,C60NT20,C60NT21,C60NT22,C60NT23,C60NT24,C60NT25,C60NT26,C60NT27,C60NT28,C60NT29,C60NT30,C60NT31,C60NT32,C60NT33,C60NT34,C60NT35,C60NT36,C60NT37,C60NT38,C60NT39,C60NT40,C60NT41,C60NT42,C60NT43,C60NT44,C60NT45,C60NT46,C60NT47,C60NT48,C60NT49,C60NT50,C60NT51,C60NT52,C60NT53,C60NT54,C60NT55,C60NT56,C60NT57,C60NT58,C60NT59,C60NT60}+F;
-
-end;
\ No newline at end of file
+end;
From 4202d33b5f5daab17e6b036cf2a692692b1d760c Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Fri, 10 Feb 2023 15:34:57 -0500
Subject: [PATCH 34/36] concatenate multiple sequence alignments
---
Sequence_Alignment_Utilities/supermatrix.py | 1 -
1 file changed, 1 deletion(-)
diff --git a/Sequence_Alignment_Utilities/supermatrix.py b/Sequence_Alignment_Utilities/supermatrix.py
index 5fe71e0..1e91328 100644
--- a/Sequence_Alignment_Utilities/supermatrix.py
+++ b/Sequence_Alignment_Utilities/supermatrix.py
@@ -86,7 +86,6 @@
OInFile1.close()
OInFile2.close()
OutFile1.close()
-
OutFile2 = "MissingSeqs.list_" + InFile3
OpenOutFile2 = open(OutFile2, 'w')
OpenOutFile2.write("Missing sequences in " + InFile1 + " are: " + "\n")
From 623d56f707e11c2753b29945b7a9ddac181d5167 Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Fri, 10 Feb 2023 15:35:46 -0500
Subject: [PATCH 35/36] renames taxa in phylogenies and fasta files
---
File_Utilities/renaming_utilities.ipynb | 1 +
1 file changed, 1 insertion(+)
diff --git a/File_Utilities/renaming_utilities.ipynb b/File_Utilities/renaming_utilities.ipynb
index d8fb67d..813b34d 100644
--- a/File_Utilities/renaming_utilities.ipynb
+++ b/File_Utilities/renaming_utilities.ipynb
@@ -13,6 +13,7 @@
"import os\n",
"import glob\n",
"import ete3"
+
]
},
{
From fe5ed36dccdac255f6e50425eb099b9f5fe05b73 Mon Sep 17 00:00:00 2001
From: yutianfeng <40605156+yutianfeng@users.noreply.github.com>
Date: Wed, 22 Feb 2023 18:26:21 -0500
Subject: [PATCH 36/36] Update README.md
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index e54f3b3..ba3338b 100644
--- a/README.md
+++ b/README.md
@@ -24,7 +24,7 @@ Scripts that:
Note: These scripts should be applicible to more than just one specific analysis.
-#### Databse_Utilities
+#### Database_Utilities
Scripts that: