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

Graphing property-level dependencies in disease modules #1475

Open
wants to merge 32 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
93189f3
Updated modules so that all INIT_DEPENDENCIES and OPTIONAL_INIT_DEPEN…
RachelMurray-Watson Oct 4, 2024
d98089d
Updated modules so that all INIT_DEPENDENCIES and OPTIONAL_INIT_DEPEN…
RachelMurray-Watson Oct 4, 2024
1030b35
Updated modules so that all INIT_DEPENDENCIES and OPTIONAL_INIT_DEPEN…
RachelMurray-Watson Oct 4, 2024
fcf1581
Updated modules so that all INIT_DEPENDENCIES and OPTIONAL_INIT_DEPEN…
RachelMurray-Watson Oct 4, 2024
10f438d
Updated modules so that all INIT_DEPENDENCIES and OPTIONAL_INIT_DEPEN…
RachelMurray-Watson Oct 4, 2024
5ab1312
Updated modules so that all INIT_DEPENDENCIES and OPTIONAL_INIT_DEPEN…
RachelMurray-Watson Oct 4, 2024
a2aef46
Updated modules so that all INIT_DEPENDENCIES and OPTIONAL_INIT_DEPEN…
RachelMurray-Watson Oct 4, 2024
d588117
Moved all new dependencies to OPTIONAL_INIT_DEPENDENCIES
RachelMurray-Watson Oct 4, 2024
0fc8682
Type
RachelMurray-Watson Oct 4, 2024
3938a9f
Typo
RachelMurray-Watson Oct 4, 2024
1e0b36f
Updated circular dependencies
RachelMurray-Watson Oct 4, 2024
82b63c0
Updated circular dependencies
RachelMurray-Watson Oct 4, 2024
22cfd7d
Changed to additional dependencies
RachelMurray-Watson Oct 4, 2024
6f86741
Added subgraphs
RachelMurray-Watson Oct 8, 2024
9adb1a4
Graph of properties from disease modules that contribute to other dis…
RachelMurray-Watson Oct 8, 2024
308b522
Delete src/scripts/longterm_projections/property_dependency_graph.py
RachelMurray-Watson Oct 8, 2024
ab3b3b6
isort
RachelMurray-Watson Oct 8, 2024
dc92321
Merge remote-tracking branch 'origin/rmw/update_dependencies' into rm…
RachelMurray-Watson Oct 8, 2024
0911247
isort
RachelMurray-Watson Oct 8, 2024
23cd2d1
Merge branch 'master' into rmw/update_dependencies
RachelMurray-Watson Oct 8, 2024
dc67a0e
Changed names of functions to avoid overlap
RachelMurray-Watson Oct 8, 2024
27bd108
Merge remote-tracking branch 'origin/rmw/update_dependencies' into rm…
RachelMurray-Watson Oct 8, 2024
4f8cb2d
Updated docstring
RachelMurray-Watson Oct 8, 2024
7f4d38f
Initial attempt at creating module-level property graphs
RachelMurray-Watson Oct 8, 2024
fc49e88
Fixed typo
RachelMurray-Watson Oct 8, 2024
31a61a0
Graphs for each individual module
RachelMurray-Watson Oct 8, 2024
3b94583
Aesthetics - still needs colour
RachelMurray-Watson Oct 8, 2024
b17e193
reduced duplication
RachelMurray-Watson Oct 9, 2024
987152f
Removed all additional dependencies
RachelMurray-Watson Oct 17, 2024
8c4f656
Merge branch 'refs/heads/master' into rmw/graph_dependencies
RachelMurray-Watson Oct 17, 2024
f7bb53d
typo
RachelMurray-Watson Oct 17, 2024
5363892
Moved to get_properties folder
RachelMurray-Watson Oct 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions src/scripts/get_properties/module_dependencies_graph.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
"""Construct a graph showing dependencies between modules."""

import argparse
from pathlib import Path
from typing import Dict, Set

from tlo.dependencies import DependencyGetter, get_all_dependencies, get_module_class_map
from tlo.methods import Metadata

try:
import pydot
except ImportError:
pydot = None


def construct_module_dependency_graph(
excluded_modules: Set[str],
disease_module_node_defaults: Dict,
other_module_node_defaults: Dict,
get_dependencies: DependencyGetter = get_all_dependencies,
):
"""Construct a pydot object representing module dependency graph.
:param excluded_modules: Set of ``Module`` subclass names to not included in graph.
:param disease_module_node_defaults: Any dot node attributes to apply to by default
to disease module nodes.
:param other_module_node_defaults: Any dot node attributes to apply to by default
to non-disease module nodes.
:param get_dependencies: Function which given a module gets the set of module
dependencies. Defaults to extracting all dependencies.
:return: Pydot directed graph representing module dependencies.
"""
if pydot is None:
raise RuntimeError("pydot package must be installed")

module_class_map = get_module_class_map(excluded_modules)
module_graph = pydot.Dot("modules", graph_type="digraph")
disease_module_subgraph = pydot.Subgraph("disease_modules")
module_graph.add_subgraph(disease_module_subgraph)
other_module_subgraph = pydot.Subgraph("other_modules")
module_graph.add_subgraph(other_module_subgraph)

# Set default styles for nodes
disease_module_node_defaults["style"] = "filled"
other_module_node_defaults["style"] = "filled"

for name, module_class in module_class_map.items():
# Determine attributes based on module type
node_attributes = {}

if Metadata.DISEASE_MODULE in module_class.METADATA and name.endswith("Cancer"):
node_attributes.update(disease_module_node_defaults)
node_attributes["color"] = "lightblue" # Color for disease modules and Cancer
else:
node_attributes.update(other_module_node_defaults)
node_attributes["color"] = "lightgreen" # Default color for other modules

# Create the node with determined attributes
node = pydot.Node(name, **node_attributes)

# Add the node to the appropriate subgraph
if Metadata.DISEASE_MODULE in module_class.METADATA or name.endswith("Cancer"):
disease_module_subgraph.add_node(node)
else:
other_module_subgraph.add_node(node)

for key, module in module_class_map.items():
for dependency in get_dependencies(module, module_class_map.keys()):
if dependency not in excluded_modules:
module_graph.add_edge(pydot.Edge(key, dependency))

return module_graph


if __name__ == "__main__":
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"output_file", type=Path, help=(
"Path to output graph to. File extension will determine output format - for example: dot, dia, png, svg"
)
)
args = parser.parse_args()

excluded_modules = {
"Mockitis",
"ChronicSyndrome",
"Skeleton",
"AlriPropertiesOfOtherModules",
"DiarrhoeaPropertiesOfOtherModules",
"DummyHivModule",
"SimplifiedBirths",
"Demography",
"HealthBurden",
"SymptomManager",
"DummyTbModule",
"ImprovedHealthSystemAndCareSeekingScenarioSwitcher",
"HealthSeekingBehaviour",
"HealthSystem",
"Deviance",
"SimplifiedPregnancyAndLabour"
}

module_graph = construct_module_dependency_graph(
excluded_modules,
disease_module_node_defaults={"fontname": "Arial", "shape": "box"},
other_module_node_defaults={"fontname": "Arial", "shape": "ellipse"},
)

format = (
args.output_file.suffix[1:] if args.output_file.suffix else "raw"
)
module_graph.write(args.output_file, format=format)
Loading