{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Using `ncbi.datasets` library to download and parse virus datasets\n",
"\n",
"The objective of this notebook is to use the `ncbi.datasets` python library to download and extract genome and annotation data for the coronavirus family of viruses, including SARS-CoV-2. \n",
"\n",
"First, let's import the python modules we'll use. Be sure you have first installed the requirements in 'requirements.txt' into your virtual environment. "
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import ncbi.datasets\n",
"import json\n",
"import jsonlines\n",
"import os\n",
"import csv\n",
"import zipfile\n",
"import pandas as pd\n",
"from pyfaidx import Fasta\n",
"from google.protobuf.json_format import ParseDict\n",
"import ncbi.datasets.v1alpha1.reports.virus_pb2 as virus_report_pb2\n",
"from collections import Counter\n",
"from datetime import datetime, timezone, timedelta"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We will need an API object specific to retrieving viral data. To see all the possible API instances, [visit the documentation on GitHub](https://github.com/ncbi/datasets/tree/master/client_docs/python#documentation-for-api-endpoints). \n",
"Let's go ahead and create the API object."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"virus_api = ncbi.datasets.VirusApi(ncbi.datasets.ApiClient())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## The NCBI data report\n",
"\n",
"Viral genome data downloaded using the NCBI Datasets API uses the same file hierarchy as the other genome assembly download objects (see [Assembly Jupyter Notebook](ncbi-datasets-assembly.ipynb) to learn more). The structured zip archive contains a data report in [JSON Lines](https://jsonlines.org/) format where each line is an individual json-formatted virus data report describing a single viral genome.\n",
"\n",
"To illustrate how you can use these files, we will download all RefSeq genomes for the coronaviridae family and extract some genome and annotation information in tabular form. "
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Download complete\n",
"Archive: ncbi_genomes.zip\n",
" Length Method Size Cmpr Date Time CRC-32 Name\n",
"-------- ------ ------- ---- ---------- ----- -------- ----\n",
" 661 Defl:N 384 42% 12-04-2020 08:22 bc3c97af README.md\n",
" 1918659 Defl:N 665974 65% 12-04-2020 08:22 90dce184 ncbi_dataset/data/genomic.fna\n",
" 701029 Defl:N 105102 85% 12-04-2020 08:22 11c60724 ncbi_dataset/data/data_report.jsonl\n",
" 2398 Defl:N 1050 56% 12-04-2020 08:23 8d3e9da3 ncbi_dataset/data/virus_dataset.md\n",
" 292 Defl:N 162 45% 12-04-2020 08:23 69d40efa ncbi_dataset/data/dataset_catalog.json\n",
"-------- ------- --- -------\n",
" 2623039 772672 71% 5 files\n"
]
}
],
"source": [
"## download all refseq genomes for the coronaviridate family (taxid 11118)\n",
"\n",
"taxid = 11118\n",
"\n",
"viral_genomes = virus_api.virus_genome_download(\n",
" taxid, \n",
" refseq_only=True, \n",
" exclude_sequence=False,\n",
" _preload_content=False\n",
")\n",
"\n",
"zipfn = 'ncbi_genomes.zip'\n",
"with open(zipfn, 'wb') as f:\n",
" f.write(viral_genomes.data)\n",
"\n",
"print(f'Download complete')\n",
"!unzip -v {zipfn}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The contents of the archive are shown above. \n",
"Next, we will use the `get_data_reports()` function below to extract data from the `data_report.jsonl` file and read it into the `genome_data` array.\n",
"Then, we'll create a DataFrame (table) from the data in the array. "
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
Accession
\n",
"
TaxID
\n",
"
VirusName
\n",
"
Host
\n",
"
Isolate
\n",
"
Location
\n",
"
Length
\n",
"
Genes
\n",
"
Proteins
\n",
"
MaturePeptides
\n",
"
\n",
" \n",
" \n",
"
\n",
"
0
\n",
"
NC_001451.1
\n",
"
11120
\n",
"
Infectious bronchitis virus
\n",
"
None
\n",
"
None
\n",
"
None
\n",
"
27608
\n",
"
6
\n",
"
10
\n",
"
14
\n",
"
\n",
"
\n",
"
1
\n",
"
NC_001846.1
\n",
"
11138
\n",
"
Murine hepatitis virus
\n",
"
None
\n",
"
None
\n",
"
None
\n",
"
31357
\n",
"
6
\n",
"
8
\n",
"
26
\n",
"
\n",
"
\n",
"
2
\n",
"
NC_002306.3
\n",
"
11135
\n",
"
Feline infectious peritonitis virus
\n",
"
None
\n",
"
79-1146
\n",
"
USA
\n",
"
29355
\n",
"
10
\n",
"
9
\n",
"
0
\n",
"
\n",
"
\n",
"
3
\n",
"
NC_002645.1
\n",
"
11137
\n",
"
Human coronavirus 229E
\n",
"
None
\n",
"
None
\n",
"
None
\n",
"
27317
\n",
"
7
\n",
"
8
\n",
"
0
\n",
"
\n",
"
\n",
"
4
\n",
"
NC_003436.1
\n",
"
28295
\n",
"
Porcine epidemic diarrhea virus
\n",
"
None
\n",
"
None
\n",
"
None
\n",
"
28033
\n",
"
6
\n",
"
6
\n",
"
13
\n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Accession TaxID VirusName Host Isolate \\\n",
"0 NC_001451.1 11120 Infectious bronchitis virus None None \n",
"1 NC_001846.1 11138 Murine hepatitis virus None None \n",
"2 NC_002306.3 11135 Feline infectious peritonitis virus None 79-1146 \n",
"3 NC_002645.1 11137 Human coronavirus 229E None None \n",
"4 NC_003436.1 28295 Porcine epidemic diarrhea virus None None \n",
"\n",
" Location Length Genes Proteins MaturePeptides \n",
"0 None 27608 6 10 14 \n",
"1 None 31357 6 8 26 \n",
"2 USA 29355 10 9 0 \n",
"3 None 27317 7 8 0 \n",
"4 None 28033 6 6 13 "
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def get_data_reports(zip_file):\n",
" with zipfile.ZipFile(zip_file, 'r') as zip_download:\n",
" with zip_download.open('ncbi_dataset/data/data_report.jsonl') as report_file_handle:\n",
" with jsonlines.Reader(report_file_handle) as json_reader:\n",
" for g in json_reader:\n",
" yield g\n",
" \n",
"genome_data = []\n",
"for g in get_data_reports(zipfn):\n",
" genome_data.append({\n",
" 'Accession': g['accession'],\n",
" 'TaxID': g['virus']['taxId'],\n",
" 'VirusName': g['virus']['sciName'],\n",
" 'Host': g.get('host', {}).get('sciName'),\n",
" 'Isolate': g.get('isolate', {}).get('name'),\n",
" 'Location': g.get('location', {}).get('geographicLocation'),\n",
" 'Length': g.get('length', 0),\n",
" 'Genes': g.get('geneCount', 0),\n",
" 'Proteins': g.get('proteinCount', 0),\n",
" 'MaturePeptides': g.get('maturePeptideCount', 0)\n",
" })\n",
"\n",
"\n",
"df1 = pd.DataFrame(genome_data)\n",
"df1.head()\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can now generate plots using the data in the DataFrame. For example, a set of histograms showing the distribution of the length of the genomes, and the number of genes, proteins and mature peptides is shown below. "
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"scrolled": false
},
"outputs": [
{
"data": {
"text/plain": [
"array([[,\n",
" ],\n",
" [,\n",
" ]], dtype=object)"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"
"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"df1.hist(column=['Length', 'Genes', 'Proteins', 'MaturePeptides'], figsize=(15,10))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Along the same lines, data can be extracted from the `data_report.jsonl` file and saved as a tab-delimited file to use in external applications like R and Excel. Also please note that JSON stores large integers (any integer that may exceed a 32 bit signed integer in size) as a string, so you will sometimes need to explicitly convert strings to integers."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['gene_name', 'nuc_acc', 'nuc_ranges', 'prot_name', 'prot_acc', 'prot_len']\n",
"['1ab', 'NC_001451.1', [[529, 12354], [12354, 20417]], 'ORF1ab polyprotein', 'NP_066134.1', 6629]\n"
]
}
],
"source": [
"genome_table = [['gene_name', 'nuc_acc', 'nuc_ranges', 'prot_name', 'prot_acc', 'prot_len']]\n",
"for g in get_data_reports(zipfn):\n",
" annot = g['annotation']\n",
" for gene in annot.get('genes', []):\n",
" for c in gene.get('cds', []):\n",
" ranges = []\n",
" for r in c['nucleotide']['range']:\n",
" ranges.append([int(r['begin']), int(r['end'])])\n",
" prot_len = int(c['protein']['range'][-1]['end'])\n",
" genome_table.append([gene['name'], c['nucleotide']['accessionVersion'],\n",
" ranges, c['name'], c['protein']['accessionVersion'], prot_len])\n",
"\n",
"tsv_file = 'virus_genome_info.tsv'\n",
"with open(tsv_file, 'wt') as f:\n",
" tbl = csv.writer(f, delimiter = '\\t', lineterminator = os.linesep)\n",
" tbl.writerows(genome_table)\n",
" \n",
"print(genome_table[0])\n",
"print(genome_table[1])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Finally, we can also use the data report to compute useful summaries, like the CDS length of each protein. It's convenient to view the data as a DataFrame."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"cds_lengths = []\n",
"for g in get_data_reports(zipfn):\n",
" annot = g['annotation']\n",
" for gene in annot.get('genes', []):\n",
" for c in gene.get('cds', []):\n",
" cds_len = 0\n",
" for r in c['nucleotide']['range']:\n",
" cds_len += int(r['end']) - int(r['begin']) + 1\n",
" cds_lengths.append({\n",
" 'Accession': g['accession'],\n",
" 'Gene': gene['name'],\n",
" 'Protein': c['name'],\n",
" 'CDS_Length': cds_len\n",
" })"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
Accession
\n",
"
Gene
\n",
"
Protein
\n",
"
CDS_Length
\n",
"
\n",
" \n",
" \n",
"
\n",
"
0
\n",
"
NC_001451.1
\n",
"
1ab
\n",
"
ORF1ab polyprotein
\n",
"
19890
\n",
"
\n",
"
\n",
"
1
\n",
"
NC_001451.1
\n",
"
1ab
\n",
"
ORF1a polyprotein
\n",
"
11856
\n",
"
\n",
"
\n",
"
2
\n",
"
NC_001451.1
\n",
"
2
\n",
"
spike protein
\n",
"
3489
\n",
"
\n",
"
\n",
"
3
\n",
"
NC_001451.1
\n",
"
3
\n",
"
3a protein
\n",
"
174
\n",
"
\n",
"
\n",
"
4
\n",
"
NC_001451.1
\n",
"
3
\n",
"
3b protein
\n",
"
195
\n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Accession Gene Protein CDS_Length\n",
"0 NC_001451.1 1ab ORF1ab polyprotein 19890\n",
"1 NC_001451.1 1ab ORF1a polyprotein 11856\n",
"2 NC_001451.1 2 spike protein 3489\n",
"3 NC_001451.1 3 3a protein 174\n",
"4 NC_001451.1 3 3b protein 195"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df2 = pd.DataFrame(cds_lengths)\n",
"df2.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Add taxid to the FASTA header\n",
"\n",
"In addition to the data report, the virus archive contains one or more sequence files that can be processed together. For example, we can add a different set of attributes to the FASTA header in the sequence files. For this, we will first create a map of genomic accessions to taxids and virus names using the data in `data_report.jsonl` file. Then, we will use the `pyfaidx` python module to change the headers in `genomic.fna` FASTA file to include taxids."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"taxids_by_accession = dict()\n",
"\n",
"for genome in get_data_reports(zipfn):\n",
" taxids_by_accession[genome['accession']] = (genome['virus']['taxId'], genome['virus']['sciName'])"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"## parse data catalog \n",
"with zipfile.ZipFile(zipfn, 'r') as zip:\n",
" data_catalog = json.loads(zip.read('ncbi_dataset/data/dataset_catalog.json'))"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"with zipfile.ZipFile(zipfn, 'r') as zip:\n",
" data = zip.read('ncbi_dataset/data/genomic.fna')\n",
" with open('genomic.fna', 'wb') as f:\n",
" f.write(data)\n",
"\n",
"with open('genomic.out.fna', 'w') as f:\n",
" genomic_seqs = Fasta('genomic.fna')\n",
" for g in genomic_seqs:\n",
" (taxid, org_name) = taxids_by_accession[g.name]\n",
" header = '>' + '|'.join([g.name, str(taxid), org_name, '\\n'])\n",
" f.write(header)\n",
" f.write(genomic_seqs[g.name][:].seq + '\\n')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Fetch all SARS-CoV-2 genomes submitted in the past 7 days\n",
"\n",
"Narrowing our focus a little, if we are interested in just SARS-CoV-2 genomes they too can be downloaded using the `ncbi.datasets` library as shown below. Here, for example, we will restrict the data returned to only those genomes that were submitted in the past 7 days. \n",
"\n",
"A python datetime object is created with the desired date and provided to the api instance. "
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Download genomes release since: 2020-11-27 13:25:25.784012+00:00\n",
"Start downloading ...\n",
"Finished.\n",
"Archive: ncbi_genomes.zip\n",
" Length Method Size Cmpr Date Time CRC-32 Name\n",
"-------- ------ ------- ---- ---------- ----- -------- ----\n",
" 661 Defl:N 384 42% 12-04-2020 08:25 bc3c97af README.md\n",
"35461727 Defl:N 12014763 66% 12-04-2020 08:25 f57a7afd ncbi_dataset/data/genomic.fna\n",
"33510533 Defl:N 3037218 91% 12-04-2020 08:25 7612390e ncbi_dataset/data/data_report.jsonl\n",
" 2398 Defl:N 1050 56% 12-04-2020 08:25 8d3e9da3 ncbi_dataset/data/virus_dataset.md\n",
" 2088828 Defl:N 586156 72% 12-04-2020 08:25 ad7faaf4 ncbi_dataset/data/pdb/6VYB.pdb\n",
" 758727 Defl:N 236717 69% 12-04-2020 08:25 d68f7342 ncbi_dataset/data/pdb/6VYO.pdb\n",
" 66582 Defl:N 19013 71% 12-04-2020 08:25 daa19637 ncbi_dataset/data/pdb/6W37.pdb\n",
" 675378 Defl:N 209771 69% 12-04-2020 08:25 5fd9e206 ncbi_dataset/data/pdb/6W4H.pdb\n",
" 1250964 Defl:N 397566 68% 12-04-2020 08:25 6bb96f3a ncbi_dataset/data/pdb/6W9C.pdb\n",
" 182574 Defl:N 58153 68% 12-04-2020 08:25 fd535fa9 ncbi_dataset/data/pdb/6W9Q.pdb\n",
" 436995 Defl:N 134343 69% 12-04-2020 08:25 d2ecc767 ncbi_dataset/data/pdb/6WEY.pdb\n",
" 983583 Defl:N 274660 72% 12-04-2020 08:25 37d4d1a8 ncbi_dataset/data/pdb/6WJI.pdb\n",
" 1054296 Defl:N 331126 69% 12-04-2020 08:25 759f29dc ncbi_dataset/data/pdb/6WLC.pdb\n",
" 448173 Defl:N 143845 68% 12-04-2020 08:25 fe9086ec ncbi_dataset/data/pdb/7BQY.pdb\n",
" 773145 Defl:N 206610 73% 12-04-2020 08:25 9cac5780 ncbi_dataset/data/pdb/7BV2.pdb\n",
" 1128 Defl:N 232 79% 12-04-2020 08:25 5593dc30 ncbi_dataset/data/dataset_catalog.json\n",
"-------- ------- --- -------\n",
"77695692 17651607 77% 16 files\n"
]
}
],
"source": [
"## to fetch all genomes submitted in the past 7 days\n",
"t = 7\n",
"d = datetime.now(timezone.utc) - timedelta(days=t)\n",
"taxid = 2697049\n",
"\n",
"print(f'Download genomes release since: {d}')\n",
"cov2_genomes = virus_api.virus_genome_download(\n",
" taxid, \n",
" released_since = d.isoformat(),\n",
" include_annotation_type=['PDB_FILES'],\n",
" _preload_content=False)\n",
"\n",
"print('Start downloading ...')\n",
"zipfn = 'ncbi_genomes.zip'\n",
"with open(zipfn, 'wb') as f:\n",
" f.write(cov2_genomes.data)\n",
"print('Finished.')\n",
"!unzip -v {zipfn}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now, we can use the information in the data report to tabulate information such as the number of genomes by collection date and georaphic location. First we'll take a look at how many genomes were collected in each month."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Counter({'2020/08': 597, '2020/10': 130, '2020/07': 115, '2020/06': 86, '2020/09': 65, '2020/05': 55, '2020': 49, '2020/04': 48, '2020/11': 35, '2020/03': 26})\n"
]
}
],
"source": [
"# Warning: This step can take several minutes to execute, depending on the size of the request. \n",
"# You may want to shorten the time window to less than 7 days.\n",
"\n",
"coll_by_month = Counter()\n",
"geo_by_date = []\n",
"\n",
"for g in get_data_reports(zipfn):\n",
" coll_date = g.get('isolate', {}).get('collectionDate')\n",
" if coll_date:\n",
" coll_date = '/'.join(coll_date.split('-')[:2])\n",
" coll_by_month[coll_date] += 1\n",
"\n",
" geo_by_date.append({\n",
" 'Date': g['isolate']['collectionDate'],\n",
" 'Location': g.get('location', {}).get('geographicLocation', '').split(':')[0]\n",
" }) \n",
"\n",
"print(coll_by_month)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now, we'll plot a histogram of genomes by collection month."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
""
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAjQAAAFlCAYAAAD8sXLMAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/Il7ecAAAACXBIWXMAAAsTAAALEwEAmpwYAAAnVklEQVR4nO3df+zd1X3n+ecrNj+GkBgwyOPYpiaqdxN3bAzrElLIEkCD7LAas1rKmlLHRabe1YACEtGOCxK7KzqSu+kwGboQDQt0QEJlafAEbzE/HTod6sBgHLBjvIDLj2LXQMahhgybEsN7/7jH4cb5mu/1Ly6fr58P6ep+7jnnns/5HPGNXznnc+9NVSFJktRlnxr2ACRJkvaXgUaSJHWegUaSJHWegUaSJHWegUaSJHWegUaSJHXe+GEP4GA7/vjja/r06cMehiRJOgCefvrp/1xVJ+xePuYDzfTp01m7du2whyFJkg6AJK+OVO6WkyRJ6jwDjSRJ6jwDjSRJ6rwxfw+NJEld9fOf/5wtW7bws5/9bNhD+dgdeeSRTJ06lcMOO2yg9gYaSZI+obZs2cJnPvMZpk+fTpJhD+djU1Vs376dLVu2cNJJJw30HrecJEn6hPrZz37GxIkTD6kwA5CEiRMn7tXK1JhfodmwdQfTl93/sZ3vleXnf2znkiSNfYdamNllb6/bFRpJkjQU3/72t3n33XcPSF9jfoVGkqSx4kDvOAx7V+Hb3/42v/u7v8tRRx213325QiNJkvbozjvvZPbs2Zx88sksWrSIV155hXPOOYfZs2dz7rnn8rd/+7cA/N7v/R7f/e53f/G+o48+GoC//Mu/5Ktf/SoXXnghX/jCF7jkkkuoKm688Ub+7u/+jrPPPpuzzz57v8fpCo0kSRrRxo0b+cM//EPWrFnD8ccfz09+8hMWL178i8ftt9/ON77xDb73ve99ZD8//OEP2bhxI5/73Oc444wz+Ou//mu+8Y1vcMMNN/DYY49x/PHH7/dYR12hSTItyWNJnkuyMcmVrfy4JI8kebE9H9vKL0myPsmGJGuSnNzX17wkzyfZnGTZbudZmOTaJF9I8oMk/5Dkm7u1uT3Jm0l+tN9XLkmSPtL3v/99fvu3f/sXgeO4447jBz/4Ab/zO78DwKJFi3j88cdH7ee0005j6tSpfOpTn2LOnDm88sorB3ysg2w57QSurqqZwOnA5UlmAsuA1VU1A1jdXgO8DJxVVbOA64FbAJKMA24C5gMzgYtbP7vMBx4EfgJ8A/jjEcby74B5e3OBkiTp4Bs/fjwffPABAB988AHvvffeL+qOOOKIXxyPGzeOnTt3HvDzjxpoqmpbVa1rx+8Am4ApwALgjtbsDuCC1mZNVb3Vyp8Aprbj04DNVfVSVb0H3N36IL3PZs0B1lXVm1X1FPDzEcbyV/QCjyRJOsjOOecc/vzP/5zt27cD8JOf/ITf+q3f4u677wbgrrvu4itf+QoA06dP5+mnnwZg5cqV/Pznv/LP+K/4zGc+wzvvvHNAxrpX99AkmQ6cAjwJTKqqba3qdWDSCG9ZAjzQjqcAr/XVbQG+1I5PAZ6tqtqb8XzEOJcCSwHGffaEA9GlJEmHnN/4jd/g2muv5ayzzmLcuHGccsop/Mmf/AmXXnop3/rWtzjhhBP40z/9UwB+//d/nwULFnDyySczb948Pv3pT4/a/9KlS5k3bx6f+9zneOyxx/ZrrBk0QyQ5GvgPwL+sqhVJ/r6qjumrf6uqju17fTZwM3BmVW1PciEwr6oua/WLgC9V1RVJrgFerqo/63v//wb8tKp+aeuphaq/qKp/Msi4j5g8oyYv/vZA13ggDPsjcJKksWPTpk188YtfHPYwhmak60/ydFXN3b3tQB/bTnIYcC9wV1WtaMVvJJnc6icDb/a1nw3cCiyoqu2teCswra/bqa0M4Dzg4UHGIkmStLtBPuUU4DZgU1Xd0Fe1EljcjhcD97X2JwIrgEVV9UJf+6eAGUlOSnI4sBBYmWQCML4v+EiSJO2VQe6hOQNYBGxI8kwruwZYDtyTZAnwKnBRq7sOmAjc3H6HYWdVza2qnUmuAB4CxgG3V9XGthX16K6TJfnHwFrgs8AHSa4CZlbV20n+DPgqcHySLcD/WlW37fPVS5KkMWHUQFNVjwN7+oWoc0dofxlw2R76WgWs2q14Hr3tqV1tXufDT0bt/v6LRxuvJEljSVUdkj9QubefExr6NwXvuklYkiT9siOPPJLt27czceLEQyrUVBXbt2/nyCOPHPg9Qw80kiRpZFOnTmXLli38+Mc/HvZQPnZHHnkkU6eOuGEzooE/tt1Vc+fOrbVr1w57GJIk6QDYr49tS5IkfZIZaCRJUucZaCRJUucZaCRJUucZaCRJUucZaCRJUucZaCRJUucZaCRJUucZaCRJUucZaCRJUucZaCRJUucZaCRJUucZaCRJUucZaCRJUucZaCRJUueNH/YADrYNW3cwfdn9wx6G9uCV5ecPewiSpDHAFRpJktR5BhpJktR5BhpJktR5BhpJktR5owaaJNOSPJbkuSQbk1zZyo9L8kiSF9vzsa38kiTrk2xIsibJyX19zUvyfJLNSZbtdp6FSa5N8oUkP0jyD0m+uVubPb5fkiQdugZZodkJXF1VM4HTgcuTzASWAauragawur0GeBk4q6pmAdcDtwAkGQfcBMwHZgIXt352mQ88CPwE+Abwx/2DGOD9kiTpEDVqoKmqbVW1rh2/A2wCpgALgDtaszuAC1qbNVX1Vit/Apjajk8DNlfVS1X1HnB364MkAeYA66rqzap6Cvj5bkPZ4/slSdKhba/uoUkyHTgFeBKYVFXbWtXrwKQR3rIEeKAdTwFe66vb0spofT5bVfURp/+o90uSpEPYwF+sl+Ro4F7gqqp6u7eo0lNVlaR2a382vUBz5gDdz+PD4LPfkiwFlgKM++wJB6pbSZL0CTXQCk2Sw+iFmbuqakUrfiPJ5FY/GXizr/1s4FZgQVVtb8VbgWl93U5tZQDnAQ+PMoyPev8vqapbqmpuVc0dd9SE0S5PkiR13CCfcgpwG7Cpqm7oq1oJLG7Hi4H7WvsTgRXAoqp6oa/9U8CMJCclORxYCKxMMgEY3xd89mTE9496hZIkacwbZMvpDGARsCHJM63sGmA5cE+SJcCrwEWt7jpgInBz25ba2VZLdia5AngIGAfcXlUbk1wIPLrrZEn+MbAW+CzwQZKrgJltm+tX3r/vly5JksaKUQNNVT0OZA/V547Q/jLgsj30tQpYtVvxPHrbU7vavM6Hn4wa5P2SJOkQN/Rf224BSJIkaZ/50weSJKnzDDSSJKnzhr7ldLDNmjKBtcvPH/YwJEnSQeQKjSRJ6jwDjSRJ6jwDjSRJ6jwDjSRJ6jwDjSRJ6jwDjSRJ6jwDjSRJ6jwDjSRJ6jwDjSRJ6jwDjSRJ6jwDjSRJ6jwDjSRJ6jwDjSRJ6jwDjSRJ6jwDjSRJ6rzxwx7AwbZh6w6mL7t/2MM4YF5Zfv6whyBJ0ieOKzSSJKnzDDSSJKnzDDSSJKnzDDSSJKnzRg00SaYleSzJc0k2JrmylR+X5JEkL7bnY1v5JUnWJ9mQZE2Sk/v6mpfk+SSbkyzb7TwLk1ybnhtbm/VJTu1r80dJftQe/+OBmwZJktRlg6zQ7ASurqqZwOnA5UlmAsuA1VU1A1jdXgO8DJxVVbOA64FbAJKMA24C5gMzgYtbP7vMBx5szzPaYynwnfb+84FTgTnAl4BvJvnsvl22JEkaS0YNNFW1rarWteN3gE3AFGABcEdrdgdwQWuzpqreauVPAFPb8WnA5qp6qareA+5ufZAk9ILKulZ2Z/U8ARyTZDK9EPRXVbWzqv4LsB6Ytx/XLkmSxoi9uocmyXTgFOBJYFJVbWtVrwOTRnjLEuCBdjwFeK2vbksro/X5bFXVR7R7FpiX5KgkxwNnA9P2MM6lSdYmWfv+uzv25hIlSVIHDfzFekmOBu4Frqqqt3uLKj1VVUlqt/Zn0ws0Zw7Q/Tw+DD4jqqqHk/wmsAb4MfAD4P09tL2FttV1xOQZNVIbSZI0dgy0QpPkMHph5q6qWtGK32hbQbTnN/vazwZuBRZU1fZWvJVfXlGZ2soAzgMeHq1dVf3LqppTVf8UCPDCIOOXJElj2yCfcgpwG7Cpqm7oq1oJLG7Hi4H7WvsTgRXAoqrqDxxPATOSnJTkcGAhsDLJBGB8X/BZCXy9fdrpdGBHVW1LMi7JxHaO2cBsPgxBkiTpEDbIltMZwCJgQ5JnWtk1wHLgniRLgFeBi1rddcBE4Oa2LbWzquZW1c4kVwAPAeOA26tqY5ILgUf7zrcK+BqwGXgXuLSVHwb8x9bn28DvVtXOvb9kSZI01owaaKrqcXrbOyM5d4T2lwGX7aGvVfQCS7959LandrUp4PIR3vszep90kiRJ+iVD/7XtFoAkSZL2mT99IEmSOm/oKzQH26wpE1i7/PxhD0OSJB1ErtBIkqTOM9BIkqTOM9BIkqTOM9BIkqTOM9BIkqTOM9BIkqTOM9BIkqTOM9BIkqTOM9BIkqTOM9BIkqTOM9BIkqTOM9BIkqTOM9BIkqTOM9BIkqTOM9BIkqTOM9BIkqTOGz/sARxsG7buYPqy+4c9DEmSDgmvLD9/KOd1hUaSJHWegUaSJHWegUaSJHXeqIEmybQkjyV5LsnGJFe28uOSPJLkxfZ8bCu/JMn6JBuSrElycl9f85I8n2RzkmW7nWdhkmvTc2Nrsz7JqX1t/o82hk2tTQ7cVEiSpK4aZIVmJ3B1Vc0ETgcuTzITWAasrqoZwOr2GuBl4KyqmgVcD9wCkGQccBMwH5gJXNz62WU+8GB7ntEeS4HvtPf/FnAGMBv4J8BvAmft22VLkqSxZNRAU1XbqmpdO34H2ARMARYAd7RmdwAXtDZrquqtVv4EMLUdnwZsrqqXquo94O7WB22lZQ6wrpXdWT1PAMckmQwUcCRwOHAEcBjwxj5fuSRJGjP26h6aJNOBU4AngUlVta1VvQ5MGuEtS4AH2vEU4LW+ui2tjNbns1VVe2pXVT8AHgO2tcdDVbVpb8YvSZLGpoG/hybJ0cC9wFVV9Xb/7StVVUlqt/Zn0ws0Zw7Q/Tw+DD57Ov+vA1/kwxWfR5J8par+4whtl9LbrmLcZ08Y4PSSJKnLBlqhSXIYvTBzV1WtaMVvtK0g2vObfe1nA7cCC6pqeyveCkzr63ZqKwM4D3h4lHb/PfBEVf20qn5KLwB9eaTxVtUtVTW3quaOO2rCIJcoSZI6bJBPOQW4DdhUVTf0Va0EFrfjxcB9rf2JwApgUVW90Nf+KWBGkpOSHA4sBFYmmQCM7ws+K4Gvt087nQ7saFtbfwuclWR8C1hn0bufR5IkHeIG2XI6A1gEbEjyTCu7BlgO3JNkCfAqcFGruw6YCNzctqV2ttWSnUmuAB4CxgG3V9XGJBcCj/adbxXwNWAz8C5waSv/LnAOsIHeDcIPVtX/s/eXLEmSxppRA01VPQ7s6ftezh2h/WXAZXvoaxW9wNJvHr3tqV1tCrh8hPe+D/xPo41XkiQdeob+45QtAEmSJO0zf/pAkiR1noFGkiR13tC3nA62WVMmsHb5+cMehiRJOohcoZEkSZ1noJEkSZ1noJEkSZ1noJEkSZ1noJEkSZ1noJEkSZ1noJEkSZ1noJEkSZ1noJEkSZ1noJEkSZ1noJEkSZ1noJEkSZ1noJEkSZ1noJEkSZ1noJEkSZ03ftgDONg2bN3B9GX3D3sYh4xXlp8/7CFIkg5BrtBIkqTOM9BIkqTOM9BIkqTOM9BIkqTOGzXQJJmW5LEkzyXZmOTKVn5ckkeSvNiej23llyRZn2RDkjVJTu7ra16S55NsTrJst/MsTHJtem5sbdYnObXVn53kmb7Hz5JccEBnQ5IkddIgKzQ7gauraiZwOnB5kpnAMmB1Vc0AVrfXAC8DZ1XVLOB64BaAJOOAm4D5wEzg4tbPLvOBB9vzjPZYCnwHoKoeq6o5VTUHOAd4F3h4H69bkiSNIaMGmqraVlXr2vE7wCZgCrAAuKM1uwO4oLVZU1VvtfIngKnt+DRgc1W9VFXvAXe3PkgSYA6wrpXdWT1PAMckmbzbsC4EHqiqd/f6iiVJ0pizV/fQJJkOnAI8CUyqqm2t6nVg0ghvWQI80I6nAK/11W1pZbQ+n62qGqXdLguBP/uIcS5NsjbJ2vff3THaZUmSpI4b+Iv1khwN3AtcVVVv9xZVeqqqktRu7c+mF2jOHKD7eXwYfEYbx2RgFvDQntpU1S20ra4jJs+oPbWTJEljw0ArNEkOoxdm7qqqFa34jV1bQe35zb72s4FbgQVVtb0VbwWm9XU7tZUBnMeH98N8VDuAi4B/X1U/H2TskiRp7BvkU04BbgM2VdUNfVUrgcXteDFwX2t/IrACWFRVL/S1fwqYkeSkJIfT2zZamWQCML4v+KwEvt4+7XQ6sKNvawvgYj5iu0mSJB16BtlyOgNYBGxI8kwruwZYDtyTZAnwKr2VE4DrgInAzW1bamdVza2qnUmuoLdVNA64vao2JrkQeLTvfKuArwGb6X2S6dJdFe0enmnAf9j7S5UkSWPVqIGmqh4Hsofqc0dofxlw2R76WkUvsPSbR297alebAi7fw/tf4VdvEJYkSYe4of/adgtAkiRJ+8yfPpAkSZ1noJEkSZ039C2ng23WlAmsXX7+sIchSZIOIldoJElS5xloJElS5xloJElS5xloJElS5xloJElS5xloJElS5xloJElS5xloJElS5xloJElS5xloJElS5xloJElS5xloJElS5xloJElS5xloJElS5xloJElS540f9gAOtg1bdzB92f1DO/8ry88f2rklSTpUuEIjSZI6z0AjSZI6z0AjSZI6z0AjSZI6b9RAk2RakseSPJdkY5IrW/lxSR5J8mJ7PraVX5JkfZINSdYkObmvr3lJnk+yOcmy3c6zMMm16bmxtVmf5NS+NicmeTjJpjae6QdsJiRJUmcNskKzE7i6qmYCpwOXJ5kJLANWV9UMYHV7DfAycFZVzQKuB24BSDIOuAmYD8wELm797DIfeLA9z2iPpcB3+trcCXyrqr4InAa8uddXLEmSxpxRA01Vbauqde34HWATMAVYANzRmt0BXNDarKmqt1r5E8DUdnwasLmqXqqq94C7Wx8kCTAHWNfK7qyeJ4Bjkkxu4Wd8VT3SzvPTqnp3fy5ekiSNDXt1D03b4jkFeBKYVFXbWtXrwKQR3rIEeKAdTwFe66vb0spofT5bVfUR7f4r4O+TrEjywyTfaqs+I41zaZK1Sda+/+6OvblESZLUQQMHmiRHA/cCV1XV2/11LYjUbu3Pphdo/sUA3c/jw+CzJ+OBrwDfBH4T+DzweyM1rKpbqmpuVc0dd9SEAU4vSZK6bKBAk+QwemHmrqpa0YrfSDK51U+m736WJLOBW4EFVbW9FW8FpvV1O7WVAZwHPDxKuy3AM23LaifwPeBUJEnSIW+QTzkFuA3YVFU39FWtBBa348XAfa39icAKYFFVvdDX/ilgRpKTkhwOLARWJplA796Y7X39fr192ul0YEfb2nqK3v00J7R25wDP7f0lS5KksWaQ33I6A1gEbEjyTCu7BlgO3JNkCfAqcFGruw6YCNzcy0LsbNs/O5NcATwEjANur6qNSS4EHu073yrga8Bm4F3gUoCqej/JN4HVLWQ9Dfxf+3bZkiRpLBk10FTV40D2UH3uCO0vAy7bQ1+r6AWWfvPobU/talPA5Xt4/yPA7NHGLEmSDi1D/7XtFoAkSZL2mT99IEmSOm/oKzQH26wpE1i7/PxhD0OSJB1ErtBIkqTOM9BIkqTOM9BIkqTOM9BIkqTOM9BIkqTOM9BIkqTOM9BIkqTOM9BIkqTOM9BIkqTOM9BIkqTOM9BIkqTOM9BIkqTOM9BIkqTOM9BIkqTOM9BIkqTOGz/sARxsG7buYPqy+4c9jIG9svz8YQ9BkqTOcYVGkiR1noFGkiR1noFGkiR1noFGkiR13qiBJsm0JI8leS7JxiRXtvLjkjyS5MX2fGwrvyTJ+iQbkqxJcnJfX/OSPJ9kc5Jlu51nYZJr03Nja7M+yal9bd5P8kx7rDxw0yBJkrpskBWancDVVTUTOB24PMlMYBmwuqpmAKvba4CXgbOqahZwPXALQJJxwE3AfGAmcHHrZ5f5wIPteUZ7LAW+09fm/6uqOe3xz/blgiVJ0tgzaqCpqm1Vta4dvwNsAqYAC4A7WrM7gAtamzVV9VYrfwKY2o5PAzZX1UtV9R5wd+uDJAHmAOta2Z3V8wRwTJLJ+3mdkiRpDNure2iSTAdOAZ4EJlXVtlb1OjBphLcsAR5ox1OA1/rqtrQyWp/PVlWN0u7IJGuTPJHkgr0ZuyRJGrsG/mK9JEcD9wJXVdXbvUWVnqqqJLVb+7PpBZozB+h+Hh8Gn4/ya1W1Ncnnge8n2VBVfzPCWJfS265i3GdPGKBbSZLUZQOt0CQ5jF6YuauqVrTiN3ZtBbXnN/vazwZuBRZU1fZWvBWY1tft1FYGcB7w8GjtqmrX80vAX9Jb2fkVVXVLVc2tqrnjjpowyCVKkqQOG+RTTgFuAzZV1Q19VSuBxe14MXBfa38isAJYVFUv9LV/CpiR5KQkhwMLgZVJJgDj+4LPSuDr7dNOpwM7qmpbkmOTHNHOcTxwBvDcvl22JEkaSwbZcjoDWARsSPJMK7sGWA7ck2QJ8CpwUau7DpgI3Ny2pXa21ZKdSa4AHgLGAbdX1cYkFwKP9p1vFfA1YDPwLnBpK/8i8G+TfEAviC2vKgONJEkaPdBU1eNA9lB97gjtLwMu20Nfq+gFln7z6G1P7WpTwOUjvHcNMGu08UqSpEPP0H9tuwUgSZKkfeZPH0iSpM4z0EiSpM4b+pbTwTZrygTWLj9/2MOQJEkHkSs0kiSp8ww0kiSp8ww0kiSp8ww0kiSp8ww0kiSp8ww0kiSp8ww0kiSp8ww0kiSp8ww0kiSp8ww0kiSp8ww0kiSp8ww0kiSp8ww0kiSp8ww0kiSp8ww0kiSp88YPewAH24atO5i+7P5hD+NXvLL8/GEPQZKkMcMVGkmS1HkGGkmS1HkGGkmS1HkGGkmS1HmjBpok05I8luS5JBuTXNnKj0vySJIX2/OxrfySJOuTbEiyJsnJfX3NS/J8ks1Jlu12noVJrk3Pja3N+iSn7tbus0m2JPk/D8wUSJKkrhtkhWYncHVVzQROBy5PMhNYBqyuqhnA6vYa4GXgrKqaBVwP3AKQZBxwEzAfmAlc3PrZZT7wYHue0R5Lge/sNp7rgb/ay+uUJElj2KiBpqq2VdW6dvwOsAmYAiwA7mjN7gAuaG3WVNVbrfwJYGo7Pg3YXFUvVdV7wN2tD5IEmAOsa2V3Vs8TwDFJJrd2/w0wCXh4P65ZkiSNMXt1D02S6cApwJPApKra1qpepxc0drcEeKAdTwFe66vb0spofT5bVbWndkk+Bfwr4JsDjHNpkrVJ1r7/7o5BLk2SJHXYwF+sl+Ro4F7gqqp6u7eo0lNVlaR2a382vUBz5gDdz+PD4LMn/xxYVVVb+s89kqq6hbbVdcTkGfWRjSVJUucNFGiSHEYvzNxVVSta8RtJJlfVtrYl9GZf+9nArcD8qtreircC0/q6ndrKAM4D/odR2n0Z+EqSfw4cDRye5KdV9Us3F0uSpEPPIJ9yCnAbsKmqbuirWgksbseLgfta+xOBFcCiqnqhr/1TwIwkJyU5HFgIrEwyARjfF3xWAl9vn3Y6HdjR7uO5pKpOrKrp9Lad7jTMSJIkGGyF5gxgEbAhyTOt7BpgOXBPkiXAq8BFre46YCJwc9sa2llVc6tqZ5IrgIeAccDtVbUxyYXAo33nWwV8DdgMvAtcuh/XJ0mSDgHp3Yc7xAEktwK3tk80HXBHTJ5Rkxd/+2B0vV/8cUpJkvZekqerau7u5UP/te2qumzYY5AkSd3mTx9IkqTOG/oKzcE2a8oE1rq9I0nSmOYKjSRJ6jwDjSRJ6jwDjSRJ6jwDjSRJ6jwDjSRJ6jwDjSRJ6jwDjSRJ6jwDjSRJ6jwDjSRJ6jwDjSRJ6jwDjSRJ6jwDjSRJ6jwDjSRJ6jwDjSRJ6jwDjSRJ6jwDjSRJ6rzxwx7AwbZh6w6mL7v/gPX3yvLzD1hfkiTpwHCFRpIkdZ6BRpIkdZ6BRpIkdd6ogSbJtCSPJXkuycYkV7by45I8kuTF9nxsK78kyfokG5KsSXJyX1/zkjyfZHOSZbudZ2GSa9NzY2uzPsmprf7XkqxL8kwbx/98YKdCkiR11SArNDuBq6tqJnA6cHmSmcAyYHVVzQBWt9cALwNnVdUs4HrgFoAk44CbgPnATODi1s8u84EH2/OM9lgKfKfVbwO+XFVzgC8By5J8bl8uWpIkjS2jBpqq2lZV69rxO8AmYAqwALijNbsDuKC1WVNVb7XyJ4Cp7fg0YHNVvVRV7wF3tz5IEmAOsK6V3Vk9TwDHJJlcVe9V1T+0vo4YZOySJOnQsFehIMl04BTgSWBSVW1rVa8Dk0Z4yxLggXY8BXitr25LK6P1+WxV1Ue1a9tf61v9H1XV3+3N+CVJ0tg0cKBJcjRwL3BVVb3dX9eCSO3W/mx6geZfDND9PD4MPntUVa9V1Wzg14HFSUYKUSRZmmRtkrXvv7tjgNNLkqQuGyjQJDmMXpi5q6pWtOI3kkxu9ZOBN/vazwZuBRZU1fZWvBWY1tft1FYGcB7w8ADtAGgrMz8CvjLSeKvqlqqaW1Vzxx01YZBLlCRJHTbIp5wC3AZsqqob+qpWAovb8WLgvtb+RGAFsKiqXuhr/xQwI8lJSQ4HFgIrk0wAxvcFn5XA19unnU4HdlTVtiRTk/yjdo5jgTOB5/ftsiVJ0lgyyE8fnAEsAjYkeaaVXQMsB+5JsgR4Fbio1V0HTARu7mUhdrbVkp1JrgAeAsYBt1fVxiQXAo/2nW8V8DVgM/AucGkr/yLwr5IUEOCPq2rDPlyzJEkaY0YNNFX1OL0AMZJzR2h/GXDZHvpaRS+w9JtHb3tqV5sCLh/hvY8As0cbryRJOvQM/ccpWwCSJEnaZ36XiyRJ6jwDjSRJ6ryhbzkdbLOmTGDt8vOHPQxJknQQuUIjSZI6z0AjSZI6z0AjSZI6z0AjSZI6z0AjSZI6z0AjSZI6z0AjSZI6z0AjSZI6z0AjSZI6z0AjSZI6z0AjSZI6z0AjSZI6z0AjSZI6z0AjSZI6z0AjSZI6b/ywB3Cwbdi6g+nL7h/2MEb0yvLzhz0ESZLGBFdoJElS5xloJElS5xloJElS5xloJElS5x30QJNkWpLHkjyXZGOSK1v5cUkeSfJiez62lV+SZH2SDUnWJDm5r695SZ5PsjnJsoM9dkmS1A0fxwrNTuDqqpoJnA5cnmQmsAxYXVUzgNXtNcDLwFlVNQu4HrgFIMk44CZgPjATuLj1I0mSDnEHPdBU1baqWteO3wE2AVOABcAdrdkdwAWtzZqqequVPwFMbcenAZur6qWqeg+4u/UhSZIOcR/rPTRJpgOnAE8Ck6pqW6t6HZg0wluWAA+04ynAa311W1rZSOdZmmRtkrXvv7vjQAxdkiR9gn1sX6yX5GjgXuCqqno7yS/qqqqS1G7tz6YXaM7c23NV1S20raojJs+oUZpLkqSO+1hWaJIcRi/M3FVVK1rxG0kmt/rJwJt97WcDtwILqmp7K94KTOvrdmorkyRJh7iP41NOAW4DNlXVDX1VK4HF7XgxcF9rfyKwAlhUVS/0tX8KmJHkpCSHAwtbH5Ik6RD3cWw5nQEsAjYkeaaVXQMsB+5JsgR4Fbio1V0HTARubttSO6tqblXtTHIF8BAwDri9qjZ+DOOXJEmfcAc90FTV40D2UH3uCO0vAy7bQ1+rgFUHbnSSJGks8JuCJUlS5xloJElS5xloJElS531s30MzLLOmTGDt8vOHPQxJknQQuUIjSZI6z0AjSZI6z0AjSZI6z0AjSZI6z0AjSZI6z0AjSZI6z0AjSZI6L1U17DEcVEneAZ4f9jg67HjgPw97EB3m/O0f52//OH/7x/nbPwdr/n6tqk7YvXDMf7Ee8HxVzR32ILoqyVrnb985f/vH+ds/zt/+cf72z8c9f245SZKkzjPQSJKkzjsUAs0twx5Axzl/+8f52z/O3/5x/vaP87d/Ptb5G/M3BUuSpLHvUFihkSRJY9yYDTRJ5iV5PsnmJMuGPZ5PoiS3J3kzyY/6yo5L8kiSF9vzsa08SW5s87k+yanDG/knQ5JpSR5L8lySjUmubOXO4QCSHJnkPyV5ts3f/97KT0ryZJun/zvJ4a38iPZ6c6ufPtQL+IRIMi7JD5P8RXvt/O2FJK8k2ZDkmSRrW5l/wwNKckyS7yb5f5NsSvLlYc3fmAw0ScYBNwHzgZnAxUlmDndUn0j/Dpi3W9kyYHVVzQBWt9fQm8sZ7bEU+M7HNMZPsp3A1VU1EzgduLz9d+YcDuYfgHOq6mRgDjAvyenAHwH/uqp+HXgLWNLaLwHeauX/urUTXAls6nvt/O29s6tqTt9HjP0bHty/AR6sqi8AJ9P7b3E481dVY+4BfBl4qO/1HwB/MOxxfRIfwHTgR32vnwcmt+PJ9L7HB+DfAheP1M7HL+bkPuCfOof7NHdHAeuAL9H7Iq7xrfwXf8vAQ8CX2/H41i7DHvuQ520qvX8wzgH+Aojzt9dz+Apw/G5l/g0PNncTgJd3/+9oWPM3JldogCnAa32vt7QyjW5SVW1rx68Dk9qxc/oR2vL9KcCTOIcDa9slzwBvAo8AfwP8fVXtbE365+gX89fqdwATP9YBf/J8G/hfgA/a64k4f3urgIeTPJ1kaSvzb3gwJwE/Bv60bXvemuTTDGn+xmqg0QFQvQjtx+BGkeRo4F7gqqp6u7/OOfxoVfV+Vc2ht9JwGvCF4Y6oO5L8d8CbVfX0sMfScWdW1an0tkMuT/Lf9lf6N/yRxgOnAt+pqlOA/8KH20vAxzt/YzXQbAWm9b2e2so0ujeSTAZoz2+2cud0BEkOoxdm7qqqFa3YOdxLVfX3wGP0tkiOSbLrZ1n65+gX89fqJwDbP96RfqKcAfyzJK8Ad9Pbdvo3OH97paq2tuc3gX9PL1j7NzyYLcCWqnqyvf4uvYAzlPkbq4HmKWBGu9v/cGAhsHLIY+qKlcDidryY3n0hu8q/3u5SPx3Y0bekeEhKEuA2YFNV3dBX5RwOIMkJSY5px/+I3v1Hm+gFmwtbs93nb9e8Xgh8v/2/v0NSVf1BVU2tqun0/jfu+1V1Cc7fwJJ8Oslndh0D5wE/wr/hgVTV68BrSf7rVnQu8BzDmr9h31R0EG9W+hrwAr09+WuHPZ5P4gP4M2Ab8HN6SXsJvT311cCLwKPAca1t6H1y7G+ADcDcYY9/2A/gTHpLqeuBZ9rja87hwPM3G/hhm78fAde18s8D/wnYDPw5cEQrP7K93tzqPz/sa/ikPICvAn/h/O31vH0eeLY9Nu76t8K/4b2awznA2vZ3/D3g2GHNn98ULEmSOm+sbjlJkqRDiIFGkiR1noFGkiR1noFGkiR1noFGkiR1noFGkiR1noFGkiR1noFGkiR13v8PVpiYrQK0dlIAAAAASUVORK5CYII=\n",
"text/plain": [
"
"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"df = pd.DataFrame.from_dict(coll_by_month, orient='index', columns=['count']).sort_index()\n",
"df.plot(kind = 'barh', y='count', figsize=(9,6))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Next, we'll generate a DataFrame showing the geographic locations where these genomes were found. We'll use head to take a look at the first five rows in the DataFrame."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"