import logging
logger = logging.getLogger(__name__)
[docs]class EmmaaStatement(object):
"""Represents an EMMAA Statement.
Parameters
----------
stmt : indra.statements.Statement
An INDRA Statement
date : datetime
A datetime object that is attached to the Statement. Typically
represents the time at which the Statement was created.
search_terms : list[emmaa.priors.SearchTerm]
The list of search terms that led to the creation of the Statement.
metadata : dict
Additional metadata for the statement.
"""
def __init__(self, stmt, date, search_terms, metadata=None):
ann = emmaa_metadata_json(search_terms, metadata)
add_emmaa_annotations(stmt, ann)
self.stmt = stmt
self.date = date
self.search_terms = search_terms
self.metadata = metadata if metadata else {}
def __repr__(self):
return '%s(%s, %s, %s)' % (self.__class__.__name__, self.stmt,
self.date, self.search_terms)
def to_json(self):
output_json = emmaa_metadata_json(self.search_terms, self.metadata)
output_json['date'] = self.date.strftime('%Y-%m-%d-%H-%M-%S')
# Get json representation of statement
json_stmt = self.stmt.to_json(use_sbo=False)
# Stringify source hashes: JavaScript can't handle int's of length > 16
for ev in json_stmt['evidence']:
ev['source_hash'] = str(ev['source_hash'])
output_json['stmt'] = json_stmt
return output_json
[docs]def to_emmaa_stmts(stmt_list, date, search_terms, metadata=None):
"""Make EMMAA statements from INDRA Statements with the given metadata."""
emmaa_stmts = []
logger.info(f'Making {len(stmt_list)} EMMAA statements with metadata: '
f'{metadata}')
for indra_stmt in stmt_list:
es = EmmaaStatement(indra_stmt, date, search_terms, metadata)
emmaa_stmts.append(es)
return emmaa_stmts
def emmaa_metadata_json(search_terms, metadata):
if not metadata:
metadata = {}
return {'search_terms': [st.to_json() for st in search_terms],
'metadata': metadata}
[docs]def add_emmaa_annotations(indra_stmt, annotation):
"""Add EMMAA annotations to inner INDRA statement."""
for evid in indra_stmt.evidence:
evid.annotations['emmaa'] = annotation
[docs]def check_stmt(stmt, conditions, evid_policy='any'):
"""Decide whether a statement meets the conditions.
Parameters
----------
stmt : indra.statements.Statement
INDRA Statement that should be checked for conditions.
conditions : dict
Conditions represented as key-value pairs that statements'
metadata can be compared to. NOTE if there are multiple conditions
provided, the function will require that all conditions are met to
return True.
evid_policy : str
Policy for checking statement's evidence objects. If 'all', then the
function returns True only if all of statement's evidence objects meet
the conditions. If 'any', the function returns True as long as at
least one of statement's evidences meets the conditions.
Return
------
meets_conditions : bool
Whether the Statement meets the conditions.
"""
evid_checks = []
for evid in stmt.evidence:
emmaa_anns = evid.annotations.get('emmaa')
if emmaa_anns:
metadata = emmaa_anns.get('metadata')
checks = []
for key, value in conditions.items():
checks.append(metadata[key] == value)
evid_checks.append(all(checks))
if all(checks) and evid_policy == 'any':
break
# There are no evidence checks if stmt doesn't have emmaa annotations,
# in this case we say it meets conditions by default
if not evid_checks:
return True
# Make decision based on the evidence policy
if evid_policy == 'any':
return any(evid_checks)
elif evid_policy == 'all':
return all(evid_checks)
[docs]def is_internal(stmt):
"""Check if statement has any internal evidence."""
return check_stmt(stmt, {'internal': True}, evid_policy='any')