KarrLab/wc_sim

View on GitHub
wc_sim/metadata.py

Summary

Maintainability
A
0 mins
Test Coverage
A
100%
""" Store metadata about a WC simulation run

:Author: Arthur Goldberg <Arthur.Goldberg@mssm.edu>
:Date: 2020-03-29
:Copyright: 2020, Karr Lab
:License: MIT
"""

import os
from dataclasses import dataclass
import warnings

from wc_sim.multialgorithm_errors import MultialgorithmError
from wc_sim.sim_config import WCSimulationConfig
from wc_utils.util.git import get_repo_metadata, RepoMetadataCollectionType, RepositoryMetadata
from wc_utils.util.misc import EnhancedDataClass
from wc_sim.multialgorithm_errors import MultialgorithmWarning


@dataclass
class WCSimulationMetadata(EnhancedDataClass):
    """ Represent a WC simulation's metatdata

    Attributes:
        wc_sim_config (:obj:`WCSimulationConfig`): a Whole-cell simulation configuration
        wc_simulator_repo (:obj:`RepositoryMetadata`, optional): Git repository repo metadata about
            the WC simulator
        wc_model_repo (:obj:`RepositoryMetadata`, optional): Git repository repo metadata about
            the WC repo storing the WC model being simulated
    """

    wc_sim_config: WCSimulationConfig
    wc_simulator_repo: RepositoryMetadata = None
    wc_model_repo: RepositoryMetadata = None

    def __setattr__(self, name, value):
        """ Validate an attribute when it is changed """
        try:
            super().__setattr__(name, value)
        except TypeError as e:
            raise MultialgorithmError(e)

    def __post_init__(self):
        self.wc_simulator_repo = self._get_repo_metadata(__file__)

    def _get_repo_metadata(self, pathname):
        """ Get metadata about the repo that contains the file at `pathname`

        Args:
            pathname (:obj:`str`): path to a file in a Git repository

        Warns:
            :obj:`MultialgorithmWarning`: if obj:`pathname` is not a path in a Git repository,
                or if the repository is not suitable for gathering metadata

        Returns:
            :obj:`RepositoryMetadata`: metadata about the repo that contains the file at `pathname`;
                returns :obj:`None` if a warning is issued
        """
        try:
            repo_metadata, _ = get_repo_metadata(path=pathname,
                                                 repo_type=RepoMetadataCollectionType.SCHEMA_REPO)
            return repo_metadata

        except ValueError as e:
            warnings.warn(f"Cannot obtain metadata for git repo containing model at '{pathname}': {e}",
                          MultialgorithmWarning)

    def set_wc_model_repo(self, model_path):
        """ Set the value of `wc_model_repo` if it can be obtained from `model_path`

        Args:
            model_path (:obj:`str`): path to a file in the model's Git repository
        """
        self.wc_model_repo = self._get_repo_metadata(model_path)

    @staticmethod
    def get_pathname(dirname):
        """ See docstring in :obj:`EnhancedDataClass`
        """
        return os.path.join(dirname, 'wc_simulation_metadata.pickle')

    def semantically_equal(self, other):
        """ Are two instances semantically equal with respect to a simulation's predictions?

        Overrides `semantically_equal` in :obj:`EnhancedDataClass`.
        Ignore `verbose`, `changes`, and `perturbations`.
        `verbose` does not influence a simulation's predictions and `changes` and `perturbations`
        are not currently used.

        Args:
            other (:obj:`Object`): other object

        Returns:
            :obj:`bool`: :obj:`True` if `other` is semantically equal to `self`, :obj:`False` otherwise
        """
        return self.wc_sim_config.semantically_equal(other.wc_sim_config) and \
            self.wc_simulator_repo == other.wc_simulator_repo and \
            self.wc_model_repo == other.wc_model_repo