Skip to content

Commit

Permalink
Update prov jsonld representation
Browse files Browse the repository at this point in the history
  • Loading branch information
omar-rifai committed Feb 7, 2022
1 parent 25438e4 commit 44bb79d
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 58 deletions.
71 changes: 20 additions & 51 deletions clinica/engine/prov_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,15 @@ class Identifier:
validator=attr.validators.optional(attr.validators.instance_of(str)),
)

def __repr__(self):
return "%s" % self.label


class ProvElement(ABC):
@property
@classmethod
@abstractmethod
def id(cls):
def uid(cls):
"""id is required for ProvElements"""
return NotImplementedError

Expand Down Expand Up @@ -61,67 +64,33 @@ class ProvRelation(ABC):
class ProvEntity(ProvElement):
"""Provenance Entity element"""

id: Identifier = field(validator=[attr.validators.instance_of(Identifier)])
uid: Identifier = field(validator=[attr.validators.instance_of(Identifier)])
attributes: dict = field(default=attr.Factory(dict))

def unstrct(self):
return {"id": str(self.uid), **self.attributes}


@define
class ProvActivity(ProvElement):
"""Provenance Activity element"""

id: Identifier = field(validator=[attr.validators.instance_of(Identifier)])
uid: Identifier = field(validator=[attr.validators.instance_of(Identifier)])
attributes: dict = field(default=attr.Factory(dict))

def unstrct(self):
return {"id": str(self.uid), **self.attributes}


@define
class ProvAgent(ProvElement):
"""Provenance Agent element"""

id: Identifier = field(validator=[attr.validators.instance_of(Identifier)])
attributes: dict = field(
default=attr.Factory(dict),
validator=attr.validators.optional(attr.validators.instance_of(dict)),
)


# Define PROV Relations


@define
class ProvGeneration(ProvRelation):
id: Identifier = field(
init=False,
validator=attr.validators.optional(attr.validators.instance_of(Identifier)),
)

src: ProvActivity = field(
init=False,
validator=attr.validators.optional(attr.validators.instance_of(ProvActivity)),
)
dest: ProvEntity = field(
init=False,
validator=attr.validators.optional(attr.validators.instance_of(ProvEntity)),
)

def __attrs_post_init__(self):
self.id = Identifier(label="")
self.src = ProvActivity()
self.dest = ProvEntity()

# entity: an identifier (e) for a created entity;
# activity: an OPTIONAL identifier (a) for the activity that creates the entity;
# time: an OPTIONAL "generation time" (t), the time at which the entity was completely created;
# attributes: an OPTIONALa


@define
class ProvUsage(ProvRelation):
pass

uid: Identifier = field(validator=[attr.validators.instance_of(Identifier)])
attributes: dict = field(default=attr.Factory(dict))

@define
class ProvAssociation(ProvRelation):
pass
def unstrct(self):
return {"id": str(self.uid), **self.attributes}


@define
Expand All @@ -146,18 +115,18 @@ class ProvRecord:

def __getitem__(self, idx):
for element in self.elements:
if element.id == idx:
if element.uid == idx:
return element

def json(self):
json_dict = {}
json_dict["prov:Agent"] = [
cattr.unstructure(x) for x in self.elements if isinstance(x, ProvAgent)
x.unstrct() for x in self.elements if isinstance(x, ProvAgent)
]
json_dict["prov:Activity"] = [
cattr.unstructure(x) for x in self.elements if isinstance(x, ProvActivity)
x.unstrct() for x in self.elements if isinstance(x, ProvActivity)
]
json_dict["prov:Entity"] = [
cattr.unstructure(x) for x in self.elements if isinstance(x, ProvEntity)
x.unstrct() for x in self.elements if isinstance(x, ProvEntity)
]
return json_dict
3 changes: 2 additions & 1 deletion clinica/engine/prov_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def get_last_activity(path_entity: Path) -> Optional[ProvActivity]:
last_activity = [
x for x in prov_record.elements if isinstance(x, ProvActivity)
][-1]
return last_activity.id.label
return str(last_activity.uid)
return None


Expand All @@ -99,6 +99,7 @@ def create_prov_file(prov_command, prov_path):

with open(prov_path, "w") as fp:
json.dump(prov_command.json(), fp, indent=4)

return


Expand Down
12 changes: 6 additions & 6 deletions clinica/engine/provenance.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def write_prov_file(
entity_path: path of the prov-associated element
"""

from .prov_utils import read_prov_jsonld, get_path_prov
from .prov_utils import get_path_prov

prov_path = get_path_prov(path_entity)

Expand All @@ -130,7 +130,7 @@ def get_agent() -> ProvAgent:
import clinica
from .prov_utils import generate_agent_id

new_agent = ProvAgent(id=generate_agent_id())
new_agent = ProvAgent(uid=generate_agent_id())

new_agent.attributes["version"] = clinica.__version__
new_agent.attributes["label"] = clinica.__name__
Expand All @@ -146,13 +146,13 @@ def get_activity(self, agent: Identifier, entities: List[ProvEntity]) -> ProvAct
import sys
from .prov_utils import generate_activity_id

new_activity = ProvActivity(id=generate_activity_id(self.fullname))
new_activity = ProvActivity(uid=generate_activity_id(self.fullname))

new_activity.attributes["parameters"] = self.parameters
new_activity.attributes["label"] = self.fullname
new_activity.attributes["command"] = (sys.argv[1:],)
new_activity.attributes["used"] = [x.id for x in entities]
new_activity.attributes["wasAssociatedWith"] = agent.id
new_activity.attributes["used"] = [str(x.uid) for x in entities]
new_activity.attributes["wasAssociatedWith"] = str(agent.uid)

return new_activity

Expand All @@ -164,7 +164,7 @@ def get_entity(path_curr: Path) -> ProvEntity:

from clinica.engine.prov_utils import generate_entity_id, get_last_activity

new_entity = ProvEntity(id=generate_entity_id(path_curr))
new_entity = ProvEntity(uid=generate_entity_id(path_curr))
new_entity.attributes["label"] = path_curr.name
new_entity.attributes["path"] = str(path_curr)

Expand Down

0 comments on commit 44bb79d

Please sign in to comment.