Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A rs.cifdump utility? #229

Open
dennisbrookner opened this issue Oct 12, 2023 · 1 comment
Open

A rs.cifdump utility? #229

dennisbrookner opened this issue Oct 12, 2023 · 1 comment
Labels
enhancement Improvement to existing feature good first issue Good for newcomers

Comments

@dennisbrookner
Copy link
Contributor

In the matchmaps quickstart guide, I recommend using the rs.mtzdump utility to figure out what the columns in your dataset are called. However, now that matchmaps also supports cif inputs, I'm realizing that there is no equivalent command-line utility for such files! It seems to me that, if we're deciding that we want to support cifs, that we should fully commit to that.

There is also no function for writing out a cif file, but that feels less urgent to me. Others may disagree.

@dennisbrookner dennisbrookner added good first issue Good for newcomers enhancement Improvement to existing feature labels Oct 12, 2023
@DHekstra
Copy link
Contributor

DHekstra commented Jun 5, 2024

for future reference, I did this the other day by mostly a simple find and replace on rs.mtzdump. I asked @LuisA92 to make a corresponding fix to rs.read_cif() to better handle multi-block sfCIFs.

#!/usr/bin/env python
"""
Summarize the contents of an sfCIF file.

Examples
--------
In order to summarize contents of file.cif::

    > rs.cifdump file.cif

If you would like to interactively inspect file.cif in an IPython
shell, use the "--embed" argument::

    > rs.cifdump file.cif --embed

If multiple CIF files are listed, they will be summarized sequentially,
and can be accessed in an IPython shell as a dictionary called `cifs`::

    > rs.cifdump file1.cif file2.cif file3.cif --embed

Usage Details
-------------
"""
import argparse

import pandas as pd

import reciprocalspaceship as rs

# If matplotlib is available, use pylab to setup IPython environment
try:
    from pylab import *
except:
    pass


def parse_arguments():
    """Parse commandline arguments"""

    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawTextHelpFormatter, description=__doc__
    )

    # Required arguments
    parser.add_argument("cif", nargs="+", help="cif file(s) to summarize")

    # Optional arguments
    parser.add_argument(
        "--embed",
        action="store_true",
        help=(
            "cif file(s) will be summarized, and an IPython " "shell will be started"
        ),
    )
    parser.add_argument(
        "-p",
        "--precision",
        type=int,
        default=3,
        help="Number of significant digits to output for floats",
    )

    return parser


def summarize(ds, precision):
    """Summarize contents of cif file"""
    with pd.option_context("display.precision", precision):
        print(f"Spacegroup: {ds.spacegroup.short_name()}")
        print(f"Extended Hermann-Mauguin name: {ds.spacegroup.xhm()}")
        print(
            (
                f"Unit cell dimensions: {ds.cell.a:.3f} {ds.cell.b:.3f} {ds.cell.c:.3f} "
                f"{ds.cell.alpha:.3f} {ds.cell.beta:.3f} {ds.cell.gamma:.3f}"
            )
        )
        print(f"\nds.head():\n\n{ds.head()}")
        print(f"\nds.describe():\n\n{ds.describe()}")
        print(f"\nds.dtypes:\n\n{ds.dtypes}")
    return


def main():
    # Parse commandline arguments
    parser = parse_arguments()
    args = parser.parse_args()

    if len(args.cif) == 1:
        cif = rs.read_cif(args.cif[0])
        summarize(cif, args.precision)
    else:
        cifs = dict(zip(args.cif, map(rs.read_cif, args.cif)))
        for key, value in cifs.items():
            print(f"cif file: {key}\n")
            summarize(value, args.precision)
            print(f"{'-'*50}")

    # Begin IPython shell
    if args.embed:
        from IPython import embed

        bold = "\033[1m"
        end = "\033[0m"
        if "cifs" in locals():
            header = f"rs.DataSets stored in {bold}cifs{end} dictionary"
        else:
            header = f"rs.DataSet stored as {bold}cif{end}"
        print()
        embed(colors="neutral", header=header)

    return


if __name__ == "__main__":
    parser = main()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Improvement to existing feature good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

2 participants