ihmwg / python-ihm

Python package for handling IHM mmCIF and BinaryCIF files
MIT License
14 stars 7 forks source link

Allow ihm.dumper to exclude specific categories #71

Closed brindakv closed 2 years ago

brindakv commented 2 years ago

The dumper currently outputs a default set of categories. The dumper should perhaps allow for excluding certain categories, such as, audit_conform or output certain categories to different files.

benmwebb commented 2 years ago

One way to do this (using the code that was recently added for associated files in modelcif, 0bbab144e) would be to write a custom Variant subclass that wraps the usual mmCIF/BinaryCIF writer class with one that ignores certain categories, e.g.

class NullLoopCategoryWriter(object):
    def write(self, *args, **keys):
        pass

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        pass

class IgnoreWriter(object):
    def __init__(self, base_writer, ignores):
        self._base_writer = base_writer
        self._ignore_category = frozenset(ignores)

    def category(self, category):
        if category in self._ignore_category:
            return NullLoopCategoryWriter()
        else:
            return self._base_writer.category(category)

    def loop(self, category, keys):
        if category in self._ignore_category:
            return NullLoopCategoryWriter()
        else:
            return self._base_writer.loop(category, keys)

    # Pass through other methods to base_writer
    def flush(self):
        return self._base_writer.flush()

    def end_block(self):
        return self._base_writer.end_block()

    def start_block(self, name):
        return self._base_writer.start_block(name)

    def write_comment(self, comment):
        return self._base_writer.write_comment(comment)

class IgnoreVariant(ihm.dumper.IHMVariant):
    def get_system_writer(self, system, writer_class, writer):
        return IgnoreWriter(writer, ['_audit_conform'])

with open('output.cif', 'w') as fh:
    ihm.dumper.write(fh, [system], variant=IgnoreVariant)
brindakv commented 2 years ago

This is a good solution. Thanks, @benmwebb

benmwebb commented 2 years ago

... and if this works for you and you think you'll use it regularly, we could add IgnoreVariant to dumper.py and test/document it. I think that's cleaner than trying to mess with the Dumper classes directly (which are private classes and don't anyway have a 1:1 mapping to CIF categories) or adding another argument to ihm.dumper.write. My philosophy is that the average user shouldn't need to know what the categories are called (but if they do know, they can use this advanced and non-default functionality).

brindakv commented 2 years ago

Agree that this is much cleaner. No need to mess with the Dumper classes.

Yes, it would be good to add IgnoreVariant to dumper.py.