# Path: augur/frequency_estimators.py
# def timestamp_to_float(time):
#     """Convert a pandas timestamp to a floating point date.
#     This is not entirely accurate as it doesn't account for months with different
#     numbers of days, but should be close enough to be accurate for weekly pivots.
# 
#     >>> import datetime
#     >>> time = datetime.date(2010, 10, 1)
#     >>> timestamp_to_float(time)
#     2010.75
#     >>> time = datetime.date(2011, 4, 1)
#     >>> timestamp_to_float(time)
#     2011.25
#     >>> timestamp_to_float(datetime.date(2011, 1, 1))
#     2011.0
#     >>> timestamp_to_float(datetime.date(2011, 12, 1)) == (2011.0 + 11.0 / 12)
#     True
#     """
#     return time.year + ((time.month - 1) / 12.0) + ((time.day - 1) / 365.25)
# 
# Path: augur/reconstruct_sequences.py
# def load_alignments(sequence_files, gene_names):
#     from Bio import AlignIO
#     alignments = {}
#     for fname, gene in zip(sequence_files, gene_names):
#         alignments[gene] = AlignIO.read(fname, 'fasta')
#     return alignments
# 
# Path: augur/utils.py
# def annotate_parents_for_tree(tree):
#     """Annotate each node in the given tree with its parent.
# 
#     >>> import io
#     >>> tree = Bio.Phylo.read(io.StringIO("(A, (B, C))"), "newick")
#     >>> not any([hasattr(node, "parent") for node in tree.find_clades()])
#     True
#     >>> tree = annotate_parents_for_tree(tree)
#     >>> tree.root.parent is None
#     True
#     >>> all([hasattr(node, "parent") for node in tree.find_clades()])
#     True
#     """
#     tree.root.parent = None
#     for node in tree.find_clades(order="level"):
#         for child in node.clades:
#             child.parent = node
# 
#     # Return the tree.
#     return tree
# 
# def read_node_data(fnames, tree=None):
#     return NodeDataReader(fnames, tree).read()
# 
# def write_json(data, file_name, indent=(None if os.environ.get("AUGUR_MINIFY_JSON") else 2), include_version=True):
#     """
#     Write ``data`` as JSON to the given ``file_name``, creating parent directories
#     if necessary. The augur version is included as a top-level key "augur_version".
# 
#     Parameters
#     ----------
#     data : dict
#         data to write out to JSON
#     file_name : str
#         file name to write to
#     indent : int or None, optional
#         JSON indentation level. Default is `None` if the environment variable `AUGUR_MINIFY_JSON`
#         is truthy, else 1
#     include_version : bool, optional
#         Include the augur version. Default: `True`.
# 
#     Raises
#     ------
#     OSError
#     """
#     #in case parent folder does not exist yet
#     parent_directory = os.path.dirname(file_name)
#     if parent_directory and not os.path.exists(parent_directory):
#         try:
#             os.makedirs(parent_directory)
#         except OSError: #Guard against race condition
#             if not os.path.isdir(parent_directory):
#                 raise
# 
#     if include_version:
#         data["generated_by"] = {"program": "augur", "version": get_augur_version()}
# 
#     with open(file_name, 'w', encoding='utf-8') as handle:
#         json.dump(data, handle, indent=indent, sort_keys=True)


import Bio
import Bio.Phylo
import copy
import json
import numpy as np
import pandas as pd
import sys
from collections import defaultdict
from itertools import chain
from .frequency_estimators import timestamp_to_float
from .reconstruct_sequences import load_alignments
from .utils import annotate_parents_for_tree, read_node_data, write_json

    Parameters
    ----------
    tree : Bio.Phylo
        a rooted tree whose node names match the given dictionary of sequences
        by node and gene

    sequences_by_node_and_gene : dict
        nucleotide or amino acid sequences by node name and gene

    distance_map : dict
        site-specific and, optionally, sequence-specific distances between two
        sequences

    earliest_date, latest_date : pandas.Timestamp
        earliest or latest date to consider a node for comparison to a given
        sample; used to define a range of previous seasons relative to the most
        recent samples in the given tree. Dates are open intervals (inclusive)
        for interval of previous seasons. The latest date is a closed lower
        bound on the interval of the current season.

    Returns
    -------
    dict :
        distances calculated between each sample in the tree and all samples
        from previous samples with distances indexed by primary sample name and
        then past sample name

    """
    if earliest_date is not None:

# Path: augur/frequency_estimators.py
# def timestamp_to_float(time):
#     """Convert a pandas timestamp to a floating point date.
#     This is not entirely accurate as it doesn't account for months with different
#     numbers of days, but should be close enough to be accurate for weekly pivots.
# 
#     >>> import datetime
#     >>> time = datetime.date(2010, 10, 1)
#     >>> timestamp_to_float(time)
#     2010.75
#     >>> time = datetime.date(2011, 4, 1)
#     >>> timestamp_to_float(time)
#     2011.25
#     >>> timestamp_to_float(datetime.date(2011, 1, 1))
#     2011.0
#     >>> timestamp_to_float(datetime.date(2011, 12, 1)) == (2011.0 + 11.0 / 12)
#     True
#     """
#     return time.year + ((time.month - 1) / 12.0) + ((time.day - 1) / 365.25)
# 
# Path: augur/reconstruct_sequences.py
# def load_alignments(sequence_files, gene_names):
#     from Bio import AlignIO
#     alignments = {}
#     for fname, gene in zip(sequence_files, gene_names):
#         alignments[gene] = AlignIO.read(fname, 'fasta')
#     return alignments
# 
# Path: augur/utils.py
# def annotate_parents_for_tree(tree):
#     """Annotate each node in the given tree with its parent.
# 
#     >>> import io
#     >>> tree = Bio.Phylo.read(io.StringIO("(A, (B, C))"), "newick")
#     >>> not any([hasattr(node, "parent") for node in tree.find_clades()])
#     True
#     >>> tree = annotate_parents_for_tree(tree)
#     >>> tree.root.parent is None
#     True
#     >>> all([hasattr(node, "parent") for node in tree.find_clades()])
#     True
#     """
#     tree.root.parent = None
#     for node in tree.find_clades(order="level"):
#         for child in node.clades:
#             child.parent = node
# 
#     # Return the tree.
#     return tree
# 
# def read_node_data(fnames, tree=None):
#     return NodeDataReader(fnames, tree).read()
# 
# def write_json(data, file_name, indent=(None if os.environ.get("AUGUR_MINIFY_JSON") else 2), include_version=True):
#     """
#     Write ``data`` as JSON to the given ``file_name``, creating parent directories
#     if necessary. The augur version is included as a top-level key "augur_version".
# 
#     Parameters
#     ----------
#     data : dict
#         data to write out to JSON
#     file_name : str
#         file name to write to
#     indent : int or None, optional
#         JSON indentation level. Default is `None` if the environment variable `AUGUR_MINIFY_JSON`
#         is truthy, else 1
#     include_version : bool, optional
#         Include the augur version. Default: `True`.
# 
#     Raises
#     ------
#     OSError
#     """
#     #in case parent folder does not exist yet
#     parent_directory = os.path.dirname(file_name)
#     if parent_directory and not os.path.exists(parent_directory):
#         try:
#             os.makedirs(parent_directory)
#         except OSError: #Guard against race condition
#             if not os.path.isdir(parent_directory):
#                 raise
# 
#     if include_version:
#         data["generated_by"] = {"program": "augur", "version": get_augur_version()}
# 
#     with open(file_name, 'w', encoding='utf-8') as handle:
#         json.dump(data, handle, indent=indent, sort_keys=True)


# Path: augur/distance.py
import Bio
import Bio.Phylo
import copy
import json
import numpy as np
import pandas as pd
import sys
from collections import defaultdict
from itertools import chain
from .frequency_estimators import timestamp_to_float
from .reconstruct_sequences import load_alignments
from .utils import annotate_parents_for_tree, read_node_data, write_json


    Parameters
    ----------
    tree : Bio.Phylo
        a rooted tree whose node names match the given dictionary of sequences
        by node and gene

    sequences_by_node_and_gene : dict
        nucleotide or amino acid sequences by node name and gene

    distance_map : dict
        site-specific and, optionally, sequence-specific distances between two
        sequences

    earliest_date, latest_date : pandas.Timestamp
        earliest or latest date to consider a node for comparison to a given
        sample; used to define a range of previous seasons relative to the most
        recent samples in the given tree. Dates are open intervals (inclusive)
        for interval of previous seasons. The latest date is a closed lower
        bound on the interval of the current season.

    Returns
    -------
    dict :
        distances calculated between each sample in the tree and all samples
        from previous samples with distances indexed by primary sample name and
        then past sample name

    """
    if earliest_date is not None:

        earliest_date = timestamp_to_float(earliest_date)