Ejemplo n.º 1
0
class ItolTest(unittest.TestCase):
    def setUp(self):
        self.export = ItolExport()

    def test_add_export_param_dict(self):
        params = {'asdf': 'qwer'}
        self.export.add_export_param_dict(params)
        self.assertEqual(self.export.params, params)

    def test_set_export_param_value(self):
        params = {'asdf': 'qwer'}
        self.export.set_export_param_value('asdf', 'qwer')
        self.assertEqual(self.export.params, params)

    def test_get_export_params(self):
        params = {'asdf': 'qwer'}
        self.export.add_export_param_dict(params)
        self.assertEqual(self.export.get_export_params(), params)

    def test_export(self):
        with patch('itolapi.Comm.export_image') as mock_upload:
            mock_upload.return_value = b'asdf'
            self.export.export('/tmp/asdf.pdf')
Ejemplo n.º 2
0
class ItolTest(unittest.TestCase):

    def setUp(self):
        self.export = ItolExport()

    def test_add_export_param_dict(self):
        params = {'asdf': 'qwer'}
        self.export.add_export_param_dict(params)
        self.assertEqual(self.export.params, params)

    def test_set_export_param_value(self):
        params = {'asdf': 'qwer'}
        self.export.set_export_param_value('asdf', 'qwer')
        self.assertEqual(self.export.params, params)

    def test_get_export_params(self):
        params = {'asdf': 'qwer'}
        self.export.add_export_param_dict(params)
        self.assertEqual(self.export.get_export_params(), params)

    def test_export(self):
        with patch('itolapi.Comm.export_image') as mock_upload:
            mock_upload.return_value = b'asdf'
            self.export.export('/tmp/asdf.pdf')
Ejemplo n.º 3
0
# Read the tree ID
print('Tree ID: ' + str(test.comm.tree_id))

# Read the iTOL API return statement
print('iTOL output: ' + str(test.comm.upload_output))

# Website to be redirected to iTOL tree
print('Tree Web Page URL: ' + test.get_webpage())

# Warnings associated with the upload
print('Warnings: ' + str(test.comm.warnings))


# Export a pre-made tree to pdf
itol_exporter = ItolExport()
itol_exporter.set_export_param_value('tree', '18793532031912684633930')
itol_exporter.set_export_param_value('format', 'pdf')
itol_exporter.set_export_param_value('datasetList', 'dataset1')
# itol_exporter.export('example_pdf.pdf')
# print('exported tree to ',export_location)

# Export the tree above to pdf
print('Exporting to pdf')
itol_exporter = test.get_itol_export()
export_location = os.path.join(current_dir, 'example_pdf.pdf')
itol_exporter.set_export_param_value('format', 'pdf')
itol_exporter.set_export_param_value('datasetList', 'dataset1')
itol_exporter.export(export_location)
print('exported tree to ', export_location)
Ejemplo n.º 4
0
                        '--column',
                        help="column of interest",
                        required=True,
                        type=str)
    parser.add_argument('--columns',
                        help="available columns",
                        nargs='+',
                        type=str)
    params = parser.parse_args()

    itol_exporter = ItolExport()
    itol_exporter.set_export_param_value('tree', params.tree)
    assert params.format in [
        'png', 'svg', 'eps', 'ps', 'pdf', 'nexus', 'newick'
    ]
    itol_exporter.set_export_param_value('format', params.format)
    itol_exporter.set_export_param_value('display_mode', 2)
    itol_exporter.set_export_param_value('vertical_shift_factor', 0.09)
    itol_exporter.set_export_param_value('label_display', 0)
    col_id = sorted(params.columns).index(params.column)
    itol_exporter.set_export_param_value('datasets_visible',
                                         len(params.columns) + col_id)
    itol_exporter.set_export_param_value('tree_x', 250)
    itol_exporter.set_export_param_value('internal_scale', 1)
    itol_exporter.set_export_param_value('internalScale1', 1000)
    itol_exporter.set_export_param_value('internalScale2', 10)
    itol_exporter.set_export_param_value('arc', 358)
    itol_exporter.set_export_param_value('line_width', 2)

    itol_exporter.export(params.output)
Ejemplo n.º 5
0
    sys.exit(1)

# Read the tree ID
print('Tree ID: ' + str(test.comm.tree_id))

# Read the iTOL API return statement
print('iTOL output: ' + str(test.comm.upload_output))

# Website to be redirected to iTOL tree
print('Tree Web Page URL: ' + test.get_webpage())

# Warnings associated with the upload
print('Warnings: ' + str(test.comm.warnings))

# Export a pre-made tree to pdf
itol_exporter = ItolExport()
itol_exporter.set_export_param_value('tree', '18793532031912684633930')
itol_exporter.set_export_param_value('format', 'pdf')
itol_exporter.set_export_param_value('datasetList', 'dataset1')
# itol_exporter.export('example_pdf.pdf')
# print('exported tree to ',export_location)

# Export the tree above to pdf
print('Exporting to pdf')
itol_exporter = test.get_itol_export()
export_location = os.path.join(current_dir, 'example_pdf.pdf')
itol_exporter.set_export_param_value('format', 'pdf')
itol_exporter.set_export_param_value('datasetList', 'dataset1')
itol_exporter.export(export_location)
print('exported tree to ', export_location)
Ejemplo n.º 6
0
def upload_and_export_itol(
    cassiopeia_tree: CassiopeiaTree,
    tree_name: str,
    export_filepath: str,
    itol_config: str = "~/.itolconfig",
    api_key: Optional[str] = None,
    project_name: Optional[str] = None,
    meta_data: List[str] = [],
    allele_table: Optional[pd.DataFrame] = None,
    indel_colors: Optional[pd.DataFrame] = None,
    indel_priors: Optional[pd.DataFrame] = None,
    rect: bool = False,
    include_legend: bool = False,
    use_branch_lengths: bool = False,
    palette: List[str] = palettes.Category20[20],
    random_state: Optional[np.random.RandomState] = None,
    user_dataset_files: Optional[List[str]] = None,
    verbose: bool = True,
    **kwargs,
):
    """Uploads a tree to iTOL and exports it.

    This function takes in a tree, plots it with iTOL, and exports it locally.
    A user can also specify meta data and allele tables to visualize alongside
    their tree. The function requires a user to have an account with iTOL and
    can pass these credentials to the function in one of two ways: first, the
    user can specify an `api_key` and a `project_name`, which corresponds to one
    in the user's iTOL account' second, the user can have a hidden `itolconfig`
    file that can store these credentials (the default location we will check
    is in ~/.itolconfig, though this can be overridden by the user). We
    preferentially take values passed in explicitly to the function in the
    `api_key` and `project_name` arguments.

    TODO(mgjones): Add the ability to pass in min/max colors for specific
        numeric meta data to use when creating the gradient files.

    Args:
        cassiopeia_tree: A CassiopeiaTree instance, populated with a tree.
        tree_name: Name of the tree. This is what the tree will be called
            within your project directory on iTOL
        export_filepath: Output file path to save your tree. Must end with
            one of the following suffixes: ['png', 'svg', 'eps', 'ps', 'pdf'].
        itol_config: A configuration file that a user can maintain for storing
            iTOL account details (specifically, an API key and a project name
            for uploading trees). We assume that the information is stored under
            the [DEFAULT] header. We also will be default check the path
            `~/itolconfig` but the user can pass in another path should they
            wish. If an `api_key` and `project_name` are also passed in, we
            will preferentially take those values.
        api_key: API key linking to your iTOL account
        project_name: Project name to upload to.
        meta_data: Meta data to plot alongside the tree, which must be columns
            in the CassiopeiaTree.cell_meta variable.
        allele_table: Alleletable to plot alongside the tree.
        indel_colors: Color mapping to use for plotting the alleles for each
            cell. Only necessary if `allele_table` is specified.
        indel_priors: Prior probabilities for each indel. Only useful if an
            allele table is to be plotted and `indel_colors` is None.
        rect: Boolean indicating whether or not to save your tree as a circle
            or rectangle.
        use_branch_lengths: Whether or not to use branch lengths when exporting
            the tree.
        include_legend: Plot legend along with meta data.
        palette: A palette of colors in hex format.
        random_state: A random state for reproducibility
        user_dataset_files: List of paths to additional dataset files to upload.
            See https://itol.embl.de/help.cgi#dsType for available dataset types
            and their definitions.
        verbose: Include extra print statements.
        **kwargs: additional keyword arguments are passed as iTOL export parameters.
            See https://itol.embl.de/help.cgi#batch for a full list.

    Raises:
        iTOLError if iTOL credentials cannot be found, if the output format is
            not supported, if meta data to be plotted cannot be found, or if
            an error with iTOL is encountered.
    """

    # create temporary directory for storing files we'll upload to iTOL
    temporary_directory = tempfile.mkdtemp()

    if api_key is None or project_name is None:
        if os.path.exists(os.path.expanduser(itol_config)):

            config = configparser.ConfigParser()
            with open(os.path.expanduser(itol_config), "r") as f:
                config_string = f.read()
            config.read_string(config_string)

            try:
                api_key = config["DEFAULT"]["api_key"]
                project_name = config["DEFAULT"]["project_name"]
            except KeyError:
                raise iTOLError(
                    "Error reading the itol config file passed in.")

        else:
            raise iTOLError(
                "Specify an api_key and project_name, or a valid iTOL "
                "config file.")

    with open(os.path.join(temporary_directory, "tree_to_plot.tree"),
              "w") as f:
        f.write(cassiopeia_tree.get_newick(record_branch_lengths=True))

    file_format = export_filepath.split("/")[-1].split(".")[-1]

    if file_format not in ["png", "svg", "eps", "ps", "pdf"]:
        raise iTOLError("File format must be one of "
                        "'png', 'svg', 'eps', 'ps', 'pdf']")

    itol_uploader = Itol()
    itol_uploader.add_file(
        os.path.join(temporary_directory, "tree_to_plot.tree"))

    files = user_dataset_files.copy() if user_dataset_files else []
    if allele_table is not None:
        files += create_indel_heatmap(
            allele_table,
            cassiopeia_tree,
            f"{tree_name}.allele",
            temporary_directory,
            indel_colors,
            indel_priors,
            random_state,
        )

    for meta_item in meta_data:
        if meta_item not in cassiopeia_tree.cell_meta.columns:
            raise iTOLError("Meta data item not in CassiopeiaTree cell meta.")

        values = cassiopeia_tree.cell_meta[meta_item]

        if pd.api.types.is_numeric_dtype(values):
            files.append(
                create_gradient_from_df(
                    values,
                    cassiopeia_tree,
                    f"{tree_name}.{meta_item}",
                    temporary_directory,
                ))

        if pd.api.types.is_string_dtype(values):
            colors = palette[:len(values.unique())]
            colors = [utilities.hex_to_rgb(color) for color in colors]
            colormap = dict(zip(np.unique(values), colors))

            files.append(
                create_colorbar(
                    values,
                    cassiopeia_tree,
                    colormap,
                    f"{tree_name}.{meta_item}",
                    temporary_directory,
                    create_legend=include_legend,
                ))

    for _file in files:
        itol_uploader.add_file(_file)

    itol_uploader.params["treeName"] = tree_name
    itol_uploader.params["APIkey"] = api_key
    itol_uploader.params["projectName"] = project_name

    good_upload = itol_uploader.upload()
    if not good_upload:
        raise iTOLError(itol_uploader.comm.upload_output)

    if verbose:
        print("iTOL output: " + str(itol_uploader.comm.upload_output))
        print("Tree Web Page URL: " + itol_uploader.get_webpage())
        print("Warnings: " + str(itol_uploader.comm.warnings))

    tree_id = itol_uploader.comm.tree_id

    itol_exporter = ItolExport()

    # set parameters:
    itol_exporter.set_export_param_value("tree", tree_id)
    itol_exporter.set_export_param_value("format", file_format)
    if rect:
        # rectangular tree settings
        itol_exporter.set_export_param_value("display_mode", 1)
    else:
        # circular tree settings
        itol_exporter.set_export_param_value("display_mode", 2)
        itol_exporter.set_export_param_value("arc", 359)
        itol_exporter.set_export_param_value("rotation", 270)

    itol_exporter.set_export_param_value("leaf_sorting", 1)
    itol_exporter.set_export_param_value("label_display", 0)
    itol_exporter.set_export_param_value("internal_marks", 0)
    itol_exporter.set_export_param_value("ignore_branch_length",
                                         1 - int(use_branch_lengths))

    itol_exporter.set_export_param_value(
        "datasets_visible", ",".join([str(i) for i in range(len(files))]))

    itol_exporter.set_export_param_value("horizontal_scale_factor", 1)

    for key, value in kwargs.items():
        itol_exporter.set_export_param_value(key, value)

    # export!
    itol_exporter.export(export_filepath)

    # remove intermediate files
    shutil.rmtree(temporary_directory)
Ejemplo n.º 7
0
def upload_to_itol(
    tree,
    apiKey,
    projectName,
    tree_name="test",
    files=[],
    outfp="test.pdf",
    fformat=None,
    rect=False,
    **kwargs,
):

    _leaves = tree.get_leaf_names()
    tree.write(outfile="tree_to_plot.tree", format=1)

    if fformat is None:
        fformat = outfp.split(".")[-1]

    itol_uploader = Itol()
    itol_uploader.add_file("tree_to_plot.tree")

    for file in files:
        itol_uploader.add_file(file)

    itol_uploader.params["treeName"] = tree_name
    itol_uploader.params["APIkey"] = apiKey
    itol_uploader.params["projectName"] = projectName

    good_upload = itol_uploader.upload()
    if not good_upload:
        print("There was an error:" + itol_uploader.comm.upload_output)
    print("iTOL output: " + str(itol_uploader.comm.upload_output))
    print("Tree Web Page URL: " + itol_uploader.get_webpage())
    print("Warnings: " + str(itol_uploader.comm.warnings))

    tree_id = itol_uploader.comm.tree_id

    itol_exporter = ItolExport()

    # set parameters:
    itol_exporter.set_export_param_value("tree", tree_id)
    itol_exporter.set_export_param_value(
        "format",
        outfp.split(
            ".")[-1])  # ['png', 'svg', 'eps', 'ps', 'pdf', 'nexus', 'newick']
    if rect:
        itol_exporter.set_export_param_value("display_mode",
                                             1)  # rectangular tree
    else:
        itol_exporter.set_export_param_value("display_mode",
                                             2)  # circular tree
        itol_exporter.set_export_param_value("arc", 359)
        itol_exporter.set_export_param_value("rotation", 270)

    itol_exporter.set_export_param_value("leaf_sorting", 1)
    itol_exporter.set_export_param_value("label_display", 1)
    itol_exporter.set_export_param_value("internal_marks", 1)
    itol_exporter.set_export_param_value("ignore_branch_length", 1)

    itol_exporter.set_export_param_value(
        "datasets_visible", ",".join([str(i) for i in range(len(files))]))

    itol_exporter.set_export_param_value(
        "horizontal_scale_factor", 1)  # doesnt actually scale the artboard

    # export!
    itol_exporter.export(outfp)

    os.remove("tree_to_plot.tree")