causaliq-core 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 CausalIQ
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,176 @@
1
+ Metadata-Version: 2.4
2
+ Name: causaliq-core
3
+ Version: 0.1.0
4
+ Summary: Core utilities and classes for the CausalIQ ecosystem
5
+ Author-email: CausalIQ <info@causaliq.org>
6
+ Maintainer-email: "Dr. Ken Kitson" <info@causaliq.org>
7
+ License: MIT
8
+ Project-URL: Homepage, https://github.com/causaliq/causaliq-core
9
+ Project-URL: Documentation, https://github.com/causaliq/causaliq-core#readme
10
+ Project-URL: Repository, https://github.com/causaliq/causaliq-core
11
+ Project-URL: Bug Tracker, https://github.com/causaliq/causaliq-core/issues
12
+ Keywords: causaliq
13
+ Classifier: Development Status :: 2 - Pre-Alpha
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.9
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Topic :: Scientific/Engineering
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Requires-Python: >=3.9
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Requires-Dist: click>=8.0.0
28
+ Requires-Dist: numpy>=1.20.0
29
+ Requires-Dist: pandas>=1.3.0
30
+ Requires-Dist: platformdirs>=3.0.0
31
+ Requires-Dist: py-cpuinfo>=9.0.0
32
+ Requires-Dist: psutil>=5.8.0
33
+ Provides-Extra: dev
34
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
35
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
36
+ Requires-Dist: pytest-mock>=3.10.0; extra == "dev"
37
+ Requires-Dist: black>=22.0.0; extra == "dev"
38
+ Requires-Dist: isort>=5.10.0; extra == "dev"
39
+ Requires-Dist: flake8>=5.0.0; extra == "dev"
40
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
41
+ Requires-Dist: types-requests>=2.32.0; extra == "dev"
42
+ Requires-Dist: types-psutil>=5.9.0; extra == "dev"
43
+ Requires-Dist: pandas-stubs>=1.5.0; extra == "dev"
44
+ Requires-Dist: pre-commit>=2.20.0; extra == "dev"
45
+ Requires-Dist: build>=0.8.0; extra == "dev"
46
+ Requires-Dist: twine>=4.0.0; extra == "dev"
47
+ Provides-Extra: test
48
+ Requires-Dist: pytest>=7.0.0; extra == "test"
49
+ Requires-Dist: pytest-cov>=4.0.0; extra == "test"
50
+ Requires-Dist: pytest-mock>=3.10.0; extra == "test"
51
+ Provides-Extra: docs
52
+ Requires-Dist: mkdocs>=1.5.0; extra == "docs"
53
+ Requires-Dist: mkdocs-material>=9.0.0; extra == "docs"
54
+ Requires-Dist: mkdocstrings==0.30.1; extra == "docs"
55
+ Requires-Dist: mkdocstrings-python==1.18.2; extra == "docs"
56
+ Dynamic: license-file
57
+
58
+ # causaliq-core
59
+
60
+ [![Python Support](https://img.shields.io/pypi/pyversions/zenodo-sync.svg)](https://pypi.org/project/zenodo-sync/)
61
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
62
+
63
+ This is a template for **creating new CausalIQ repos** which provides a new **capability** and follows CausalIQ development practices.
64
+
65
+ ## Status
66
+
67
+ 🚧 **Active Development** - This repository is currently in active development. It will be updated periodically to align with the latest approaches used in CausalIQ repos. New repos within the CausalIQ project should follow the naming convention causaliq-[capability], e.g. "causaliq-discovery" or "causaliq-analysis".
68
+
69
+
70
+ ## Features
71
+
72
+ - 📁 **Standardised project structure**: following current best practices
73
+ - ⌨️ **CLI Interface**: An initial dummy command-line interface.
74
+ - 📖 **Documentation framework**: using mkdocs with shared CausalIQ branding.
75
+ - 🐍 **Python setup**: providing virtual environments for Python 3.9, 3.10, 3.11 and 3.12.
76
+ - 🔬 **pytest test framework**: for unit, functional and integration testing including code coverage.
77
+ - 🔄 **Continuous Integration testing**: across Python versions and operating systems using GitHub actions
78
+
79
+
80
+ ## New CausalIQ repo creation
81
+
82
+ This section provides instructions for **creating a completely new CausalIQ repo** which offers a **new capability**. This capability will be referred to as "newcapability" in the following instructions below, but should in practice be a word which meaningfully summarises the capability e.g. "pipeline" or "score".
83
+
84
+ ### Prerequisites
85
+
86
+ - Git
87
+ - Latest stable versions of Python 3.9, 3.10. 3.11 and 3.12
88
+
89
+ ### Create the new repo on GitHub
90
+
91
+ - Create the new repo with name causaliq-newcapability specifying **this repository (i.e. causaliq-core) as the template** with an initial commit message "feat: initial project setup from causaliq-core"
92
+
93
+ ### Clone the new repo locally and check that it works
94
+
95
+ Clone the causaliq-newcapability repo locally as normal
96
+
97
+ ```bash
98
+ git clone https://github.com/causaliq/causaliq-newcapability.git
99
+ ```
100
+
101
+ Set up the Python virtual environments and activate the default Python virtual environment. You may see
102
+ messages from VSCode (if you are using it as your IDE) that new Python environments are being created
103
+ as the scripts/setup-env runs - these messages can be safely ignored at this stage.
104
+
105
+ ```text
106
+ scripts/setup-env -Install
107
+ scripts/activate
108
+ ```
109
+
110
+ Check that the causaliq-core CLI is working, check that all CI tests pass, and start up the local mkdocs webserver. There should be no errors reported in any of these.
111
+
112
+ ```text
113
+ causaliq-core --help
114
+ scripts/check_ci
115
+ mkdocs serve
116
+ ```
117
+
118
+ Enter **http://127.0.0.1:8000/** in a browser and check that the
119
+ causaliq-core skeleton documentation is visible.
120
+
121
+ If all of the above works, this confirms that the code from the template repo is working successfully on your system.
122
+
123
+ ### Change all references in package to new package name
124
+
125
+ In the IDE (e.g. VSCode) editor make the following GLOBAL changes to all files and folder names
126
+
127
+ - replace **causaliq-core** with **causaliq-newcapability** in all files (57 changes across 16 files)
128
+ - replace **causaliq_core** with **causaliq_newcapability** in all files (13 changes across 5 files)
129
+ - rename folder **src/causaliq_core** to **src/causaliq_newcapability**
130
+ - manually delete the **src/causaliq-core.egg-info** package file
131
+ - manually delete all folders under venv (which will contain references to the causaliq-core)
132
+
133
+ ⚠️ **Important**: Make sure to use underscores for Python package names (`causaliq_newcapability`) and hyphens for repo names (`causaliq-newcapability`)
134
+
135
+ ### Check newly named package works OK and commit to GitHub
136
+
137
+ - Remove and re-setup the virtual environments again (which will then contain the package causaliq-newcapability), and activate the default Pyhton virtual environment
138
+
139
+ ```text
140
+ scripts/setup-env -Install
141
+ scripts/activate
142
+ ```
143
+
144
+ Check the causaliq-newcapability command runs, that all CI checks pass with the new
145
+ package name, and that mkdocs for the renamed package can be served.
146
+
147
+ ```text
148
+ causaliq-newcapability --help
149
+ scripts/check_ci
150
+ mkdocs serve
151
+ ```
152
+ This should all work without any errors and the mkdocs should refer to causaliq-newcapability
153
+ rather than causaliq-core.
154
+
155
+ This confirms that the package name has been successfully changed to "causaliq-newcapability". These changes can be commited to the new repo with message "refactor: package name changed to causaliq-newcapability"
156
+
157
+ ### Start work on new package
158
+
159
+ The real work of implementing the functionality of this new CausalIQ package can now begin!
160
+
161
+ ### Checklist
162
+ - [ ] GitHub repo created from template
163
+ - [ ] Repo cloned locally
164
+ - [ ] Initial tests pass
165
+ - [ ] All references renamed
166
+ - [ ] Folder renamed
167
+ - [ ] venv folders deleted
168
+ - [ ] Final tests pass
169
+ - [ ] Commit changes implementing new package name to GitHub
170
+ - [ ] Start work on the new package functionality!
171
+
172
+
173
+ ---
174
+
175
+ **Supported Python Versions**: 3.9, 3.10, 3.11, 3.12
176
+ **Default Python Version**: 3.11
@@ -0,0 +1,119 @@
1
+ # causaliq-core
2
+
3
+ [![Python Support](https://img.shields.io/pypi/pyversions/zenodo-sync.svg)](https://pypi.org/project/zenodo-sync/)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ This is a template for **creating new CausalIQ repos** which provides a new **capability** and follows CausalIQ development practices.
7
+
8
+ ## Status
9
+
10
+ 🚧 **Active Development** - This repository is currently in active development. It will be updated periodically to align with the latest approaches used in CausalIQ repos. New repos within the CausalIQ project should follow the naming convention causaliq-[capability], e.g. "causaliq-discovery" or "causaliq-analysis".
11
+
12
+
13
+ ## Features
14
+
15
+ - 📁 **Standardised project structure**: following current best practices
16
+ - ⌨️ **CLI Interface**: An initial dummy command-line interface.
17
+ - 📖 **Documentation framework**: using mkdocs with shared CausalIQ branding.
18
+ - 🐍 **Python setup**: providing virtual environments for Python 3.9, 3.10, 3.11 and 3.12.
19
+ - 🔬 **pytest test framework**: for unit, functional and integration testing including code coverage.
20
+ - 🔄 **Continuous Integration testing**: across Python versions and operating systems using GitHub actions
21
+
22
+
23
+ ## New CausalIQ repo creation
24
+
25
+ This section provides instructions for **creating a completely new CausalIQ repo** which offers a **new capability**. This capability will be referred to as "newcapability" in the following instructions below, but should in practice be a word which meaningfully summarises the capability e.g. "pipeline" or "score".
26
+
27
+ ### Prerequisites
28
+
29
+ - Git
30
+ - Latest stable versions of Python 3.9, 3.10. 3.11 and 3.12
31
+
32
+ ### Create the new repo on GitHub
33
+
34
+ - Create the new repo with name causaliq-newcapability specifying **this repository (i.e. causaliq-core) as the template** with an initial commit message "feat: initial project setup from causaliq-core"
35
+
36
+ ### Clone the new repo locally and check that it works
37
+
38
+ Clone the causaliq-newcapability repo locally as normal
39
+
40
+ ```bash
41
+ git clone https://github.com/causaliq/causaliq-newcapability.git
42
+ ```
43
+
44
+ Set up the Python virtual environments and activate the default Python virtual environment. You may see
45
+ messages from VSCode (if you are using it as your IDE) that new Python environments are being created
46
+ as the scripts/setup-env runs - these messages can be safely ignored at this stage.
47
+
48
+ ```text
49
+ scripts/setup-env -Install
50
+ scripts/activate
51
+ ```
52
+
53
+ Check that the causaliq-core CLI is working, check that all CI tests pass, and start up the local mkdocs webserver. There should be no errors reported in any of these.
54
+
55
+ ```text
56
+ causaliq-core --help
57
+ scripts/check_ci
58
+ mkdocs serve
59
+ ```
60
+
61
+ Enter **http://127.0.0.1:8000/** in a browser and check that the
62
+ causaliq-core skeleton documentation is visible.
63
+
64
+ If all of the above works, this confirms that the code from the template repo is working successfully on your system.
65
+
66
+ ### Change all references in package to new package name
67
+
68
+ In the IDE (e.g. VSCode) editor make the following GLOBAL changes to all files and folder names
69
+
70
+ - replace **causaliq-core** with **causaliq-newcapability** in all files (57 changes across 16 files)
71
+ - replace **causaliq_core** with **causaliq_newcapability** in all files (13 changes across 5 files)
72
+ - rename folder **src/causaliq_core** to **src/causaliq_newcapability**
73
+ - manually delete the **src/causaliq-core.egg-info** package file
74
+ - manually delete all folders under venv (which will contain references to the causaliq-core)
75
+
76
+ ⚠️ **Important**: Make sure to use underscores for Python package names (`causaliq_newcapability`) and hyphens for repo names (`causaliq-newcapability`)
77
+
78
+ ### Check newly named package works OK and commit to GitHub
79
+
80
+ - Remove and re-setup the virtual environments again (which will then contain the package causaliq-newcapability), and activate the default Pyhton virtual environment
81
+
82
+ ```text
83
+ scripts/setup-env -Install
84
+ scripts/activate
85
+ ```
86
+
87
+ Check the causaliq-newcapability command runs, that all CI checks pass with the new
88
+ package name, and that mkdocs for the renamed package can be served.
89
+
90
+ ```text
91
+ causaliq-newcapability --help
92
+ scripts/check_ci
93
+ mkdocs serve
94
+ ```
95
+ This should all work without any errors and the mkdocs should refer to causaliq-newcapability
96
+ rather than causaliq-core.
97
+
98
+ This confirms that the package name has been successfully changed to "causaliq-newcapability". These changes can be commited to the new repo with message "refactor: package name changed to causaliq-newcapability"
99
+
100
+ ### Start work on new package
101
+
102
+ The real work of implementing the functionality of this new CausalIQ package can now begin!
103
+
104
+ ### Checklist
105
+ - [ ] GitHub repo created from template
106
+ - [ ] Repo cloned locally
107
+ - [ ] Initial tests pass
108
+ - [ ] All references renamed
109
+ - [ ] Folder renamed
110
+ - [ ] venv folders deleted
111
+ - [ ] Final tests pass
112
+ - [ ] Commit changes implementing new package name to GitHub
113
+ - [ ] Start work on the new package functionality!
114
+
115
+
116
+ ---
117
+
118
+ **Supported Python Versions**: 3.9, 3.10, 3.11, 3.12
119
+ **Default Python Version**: 3.11
@@ -0,0 +1,175 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "causaliq-core"
7
+ dynamic = ["version"]
8
+ description = "Core utilities and classes for the CausalIQ ecosystem"
9
+ readme = "README.md"
10
+ license = {text = "MIT"}
11
+ authors = [
12
+ {name = "CausalIQ", email = "info@causaliq.org"},
13
+ ]
14
+ maintainers = [
15
+ {name = "Dr. Ken Kitson", email = "info@causaliq.org"},
16
+ ]
17
+ classifiers = [
18
+ "Development Status :: 2 - Pre-Alpha",
19
+ "Intended Audience :: Science/Research",
20
+ "License :: OSI Approved :: MIT License",
21
+ "Operating System :: OS Independent",
22
+ "Programming Language :: Python :: 3",
23
+ "Programming Language :: Python :: 3.9",
24
+ "Programming Language :: Python :: 3.10",
25
+ "Programming Language :: Python :: 3.11",
26
+ "Programming Language :: Python :: 3.12",
27
+ "Topic :: Scientific/Engineering",
28
+ "Topic :: Software Development :: Libraries :: Python Modules",
29
+ ]
30
+ keywords = ["causaliq"]
31
+ requires-python = ">=3.9"
32
+ dependencies = [
33
+ "click>=8.0.0",
34
+ "numpy>=1.20.0",
35
+ "pandas>=1.3.0",
36
+ "platformdirs>=3.0.0",
37
+ "py-cpuinfo>=9.0.0",
38
+ "psutil>=5.8.0",
39
+ ]
40
+
41
+ [project.optional-dependencies]
42
+ dev = [
43
+ "pytest>=7.0.0",
44
+ "pytest-cov>=4.0.0",
45
+ "pytest-mock>=3.10.0",
46
+ "black>=22.0.0",
47
+ "isort>=5.10.0",
48
+ "flake8>=5.0.0",
49
+ "mypy>=1.0.0",
50
+ "types-requests>=2.32.0",
51
+ "types-psutil>=5.9.0",
52
+ "pandas-stubs>=1.5.0",
53
+ "pre-commit>=2.20.0",
54
+ "build>=0.8.0",
55
+ "twine>=4.0.0",
56
+ ]
57
+ test = [
58
+ "pytest>=7.0.0",
59
+ "pytest-cov>=4.0.0",
60
+ "pytest-mock>=3.10.0",
61
+ ]
62
+ docs = [
63
+ "mkdocs>=1.5.0",
64
+ "mkdocs-material>=9.0.0",
65
+ "mkdocstrings==0.30.1",
66
+ "mkdocstrings-python==1.18.2"
67
+ ]
68
+
69
+ [project.urls]
70
+ Homepage = "https://github.com/causaliq/causaliq-core"
71
+ Documentation = "https://github.com/causaliq/causaliq-core#readme"
72
+ Repository = "https://github.com/causaliq/causaliq-core"
73
+ "Bug Tracker" = "https://github.com/causaliq/causaliq-core/issues"
74
+
75
+ [project.scripts]
76
+ causaliq-core = "causaliq_core.cli:main"
77
+ cqcor = "causaliq_core.cli:main"
78
+
79
+ [tool.setuptools.dynamic]
80
+ version = {attr = "causaliq_core.__version__"}
81
+
82
+ [tool.setuptools.packages.find]
83
+ where = ["src"]
84
+
85
+ [tool.setuptools.package-dir]
86
+ "" = "src"
87
+
88
+ [tool.pytest.ini_options]
89
+ minversion = "7.0"
90
+ addopts = "-ra -q --strict-markers --cov=causaliq_core --cov-report=term-missing --cov-report=html"
91
+ testpaths = [
92
+ "tests",
93
+ ]
94
+ python_files = [
95
+ "test_*.py",
96
+ "*_test.py",
97
+ ]
98
+ python_classes = [
99
+ "Test*",
100
+ ]
101
+ python_functions = [
102
+ "test_*",
103
+ ]
104
+ markers = [
105
+ "unit: Unit tests (fast, no external dependencies)",
106
+ "functional: Functional tests (CLI behavior, mocked external deps)",
107
+ "integration: Integration tests (real external dependencies)",
108
+ "slow: Slow tests that take significant time",
109
+ ]
110
+
111
+ [tool.coverage.run]
112
+ source = ["src/causaliq_core"]
113
+ omit = [
114
+ "*/tests/*",
115
+ "*/test_*.py",
116
+ ]
117
+ parallel = true
118
+ concurrency = ["thread", "multiprocessing"]
119
+
120
+ [tool.coverage.report]
121
+ exclude_lines = [
122
+ "pragma: no cover",
123
+ "def __repr__",
124
+ "if self.debug:",
125
+ "if settings.DEBUG",
126
+ "raise AssertionError",
127
+ "raise NotImplementedError",
128
+ "if 0:",
129
+ "if __name__ == .__main__.:",
130
+ "class .*\\bProtocol\\):",
131
+ "@(abc\\.)?abstractmethod",
132
+ ]
133
+
134
+ [tool.black]
135
+ line-length = 79
136
+ target-version = ['py39']
137
+ include = '\.pyi?$'
138
+ extend-exclude = '''
139
+ /(
140
+ # directories
141
+ \.eggs
142
+ | \.git
143
+ | \.hg
144
+ | \.mypy_cache
145
+ | \.tox
146
+ | \.venv
147
+ | build
148
+ | dist
149
+ )/
150
+ '''
151
+
152
+ [tool.isort]
153
+ profile = "black"
154
+ multi_line_output = 3
155
+ line_length = 79
156
+ known_first_party = ["causaliq_core"]
157
+
158
+ [tool.mypy]
159
+ python_version = "3.9"
160
+ warn_return_any = true
161
+ warn_unused_configs = true
162
+ disallow_untyped_defs = true
163
+ disallow_incomplete_defs = true
164
+ check_untyped_defs = true
165
+ disallow_untyped_decorators = true
166
+ no_implicit_optional = true
167
+ warn_redundant_casts = true
168
+ warn_unused_ignores = true
169
+ warn_no_return = true
170
+ warn_unreachable = true
171
+ strict_equality = true
172
+
173
+ [[tool.mypy.overrides]]
174
+ module = "tests.*"
175
+ disallow_untyped_defs = false
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,30 @@
1
+ """
2
+ causaliq-core: Core utilities and classes for the CausalIQ ecosystem
3
+ """
4
+
5
+ __version__ = "0.1.0"
6
+ __author__ = "CausalIQ"
7
+ __email__ = "info@causaliq.org"
8
+
9
+ # Package metadata
10
+ __title__ = "causaliq-core"
11
+ __description__ = "Core utilities and classes for the CausalIQ ecosystem"
12
+
13
+ __url__ = "https://github.com/causaliq/causaliq-core"
14
+ __license__ = "MIT"
15
+
16
+
17
+ # Version tuple for programmatic access
18
+ VERSION = tuple(map(int, __version__.split(".")))
19
+
20
+ # Legacy software version constant (migrated from legacy.py)
21
+ SOFTWARE_VERSION: int = 229
22
+
23
+
24
+ __all__ = [
25
+ "__version__",
26
+ "__author__",
27
+ "__email__",
28
+ "VERSION",
29
+ "SOFTWARE_VERSION",
30
+ ]
@@ -0,0 +1,30 @@
1
+ """Command-line interface for causaliq-core."""
2
+
3
+ import click
4
+
5
+
6
+ @click.command(name="causaliq-core")
7
+ @click.version_option(version="0.1.0")
8
+ @click.argument(
9
+ "name",
10
+ metavar="NAME",
11
+ required=True,
12
+ nargs=1,
13
+ )
14
+ @click.option("--greet", default="Hello", help="Greeting to use")
15
+ def cli(name: str, greet: str) -> None:
16
+ """
17
+ Simple CLI example.
18
+
19
+ NAME is the person to greet
20
+ """
21
+ click.echo(f"{greet}, {name}!")
22
+
23
+
24
+ def main() -> None:
25
+ """Entry point for the CLI."""
26
+ cli(prog_name="causaliq-core (cqcor)")
27
+
28
+
29
+ if __name__ == "__main__": # pragma: no cover
30
+ main()
@@ -0,0 +1,63 @@
1
+ """
2
+ Graph-related enums and utilities for CausalIQ Core.
3
+ """
4
+
5
+ from enum import Enum
6
+ from typing import Dict, List, Optional
7
+
8
+ from pandas import DataFrame
9
+
10
+ # Supported BayeSys versions for graph comparison semantics
11
+ BAYESYS_VERSIONS = ["v1.3", "v1.5+"]
12
+
13
+
14
+ def adjmat(columns: Optional[Dict[str, List[int]]] = None) -> DataFrame:
15
+ """
16
+ Create an adjacency matrix with specified entries.
17
+
18
+ :param dict columns: data for matrix specified by column
19
+
20
+ :raises TypeError: if arg types incorrect
21
+ :raises ValueError: if values specified are invalid
22
+
23
+ :returns DataFrame: the adjacency matrix
24
+ """
25
+ if (
26
+ columns is None
27
+ or not isinstance(columns, dict)
28
+ or not all([isinstance(c, list) for c in columns.values()])
29
+ or not all([isinstance(e, int) for c in columns.values() for e in c])
30
+ ):
31
+ raise TypeError("adjmat called with bad arg type")
32
+
33
+ if not all([len(c) == len(columns) for c in columns.values()]):
34
+ raise ValueError("some columns wrong length for adjmat")
35
+
36
+ valid = [e.value[0] for e in EdgeType] # valid edge integer codes
37
+ if not all([e in valid for c in columns.values() for e in c]):
38
+ raise ValueError("invalid integer values for adjmat")
39
+
40
+ adjmat_df = DataFrame(columns, dtype="int8")
41
+ adjmat_df[""] = list(adjmat_df.columns)
42
+ return adjmat_df.set_index("")
43
+
44
+
45
+ class EdgeMark(Enum):
46
+ """Supported 'ends' of an edge in a graph."""
47
+
48
+ NONE = 0
49
+ LINE = 1
50
+ ARROW = 2
51
+ CIRCLE = 3
52
+
53
+
54
+ class EdgeType(Enum):
55
+ """Supported edge types and their symbols."""
56
+
57
+ NONE = (0, EdgeMark.NONE, EdgeMark.NONE, "")
58
+ DIRECTED = (1, EdgeMark.LINE, EdgeMark.ARROW, "->")
59
+ UNDIRECTED = (2, EdgeMark.LINE, EdgeMark.LINE, "-")
60
+ BIDIRECTED = (3, EdgeMark.ARROW, EdgeMark.ARROW, "<->")
61
+ SEMIDIRECTED = (4, EdgeMark.CIRCLE, EdgeMark.ARROW, "o->")
62
+ NONDIRECTED = (5, EdgeMark.CIRCLE, EdgeMark.CIRCLE, "o-o")
63
+ SEMIUNDIRECTED = (6, EdgeMark.CIRCLE, EdgeMark.LINE, "o-")