libvcell 0.0.17__py3-none-win32.whl

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.
libvcell/__init__.py ADDED
@@ -0,0 +1,31 @@
1
+ from importlib.metadata import PackageNotFoundError, version
2
+
3
+ from libvcell.model_utils import (
4
+ sbml_to_vcml,
5
+ vcell_infix_to_num_expr_infix,
6
+ vcell_infix_to_python_infix,
7
+ vcml_to_sbml,
8
+ vcml_to_vcml,
9
+ )
10
+ from libvcell.solver_utils import (
11
+ sbml_to_finite_volume_input,
12
+ vcml_to_finite_volume_input,
13
+ vcml_to_moving_boundary_input,
14
+ )
15
+
16
+ try:
17
+ __version__ = version("libvcell")
18
+ except PackageNotFoundError: # pragma: no cover - source tree, package not installed
19
+ __version__ = "0.0.0"
20
+
21
+ __all__ = [
22
+ "__version__",
23
+ "sbml_to_finite_volume_input",
24
+ "sbml_to_vcml",
25
+ "vcell_infix_to_num_expr_infix",
26
+ "vcell_infix_to_python_infix",
27
+ "vcml_to_finite_volume_input",
28
+ "vcml_to_moving_boundary_input",
29
+ "vcml_to_sbml",
30
+ "vcml_to_vcml",
31
+ ]
File without changes
@@ -0,0 +1,228 @@
1
+ import ctypes
2
+ import logging
3
+ from pathlib import Path
4
+
5
+ from pydantic import BaseModel
6
+
7
+ from libvcell._internal.native_utils import IsolateManager, VCellNativeLibraryLoader
8
+
9
+
10
+ class ReturnValue(BaseModel):
11
+ success: bool
12
+ message: str
13
+
14
+
15
+ class MutableString:
16
+ def __init__(self, value: str):
17
+ self.value: str = value
18
+
19
+
20
+ class VCellNativeCalls:
21
+ def __init__(self) -> None:
22
+ self.loader = VCellNativeLibraryLoader()
23
+ self.lib = self.loader.lib
24
+
25
+ def vcml_to_finite_volume_input(
26
+ self, vcml_content: str, simulation_name: str, output_dir_path: Path
27
+ ) -> ReturnValue:
28
+ try:
29
+ with IsolateManager(self.lib) as isolate_thread:
30
+ json_ptr: ctypes.c_char_p = self.lib.vcmlToFiniteVolumeInput(
31
+ isolate_thread,
32
+ ctypes.c_char_p(vcml_content.encode("utf-8")),
33
+ ctypes.c_char_p(simulation_name.encode("utf-8")),
34
+ ctypes.c_char_p(str(output_dir_path).encode("utf-8")),
35
+ )
36
+
37
+ value: bytes | None = ctypes.cast(json_ptr, ctypes.c_char_p).value
38
+ if value is None:
39
+ logging.error("Failed to convert vcml to finite volume input")
40
+ return ReturnValue(success=False, message="Failed to convert vcml to finite volume input")
41
+ json_str: str = value.decode("utf-8")
42
+ # self.lib.freeString(json_ptr)
43
+ return ReturnValue.model_validate_json(json_data=json_str)
44
+ except Exception as e:
45
+ logging.exception("Error in vcml_to_finite_volume_input()", exc_info=e)
46
+ raise
47
+
48
+ def vcml_to_moving_boundary_input(
49
+ self, vcml_content: str, simulation_name: str, output_dir_path: Path
50
+ ) -> ReturnValue:
51
+ try:
52
+ with IsolateManager(self.lib) as isolate_thread:
53
+ json_ptr: ctypes.c_char_p = self.lib.vcmlToMovingBoundaryInput(
54
+ isolate_thread,
55
+ ctypes.c_char_p(vcml_content.encode("utf-8")),
56
+ ctypes.c_char_p(simulation_name.encode("utf-8")),
57
+ ctypes.c_char_p(str(output_dir_path).encode("utf-8")),
58
+ )
59
+
60
+ value: bytes | None = ctypes.cast(json_ptr, ctypes.c_char_p).value
61
+ if value is None:
62
+ logging.error("Failed to convert vcml to moving boundary input")
63
+ return ReturnValue(success=False, message="Failed to convert vcml to moving boundary input")
64
+ json_str: str = value.decode("utf-8")
65
+ # self.lib.freeString(json_ptr)
66
+ return ReturnValue.model_validate_json(json_data=json_str)
67
+ except Exception as e:
68
+ logging.exception("Error in vcml_to_moving_boundary_input()", exc_info=e)
69
+ raise
70
+
71
+ def sbml_to_finite_volume_input(self, sbml_content: str, output_dir_path: Path) -> ReturnValue:
72
+ try:
73
+ with IsolateManager(self.lib) as isolate_thread:
74
+ json_ptr: ctypes.c_char_p = self.lib.sbmlToFiniteVolumeInput(
75
+ isolate_thread,
76
+ ctypes.c_char_p(sbml_content.encode("utf-8")),
77
+ ctypes.c_char_p(str(output_dir_path).encode("utf-8")),
78
+ )
79
+ value: bytes | None = ctypes.cast(json_ptr, ctypes.c_char_p).value
80
+ if value is None:
81
+ logging.error("Failed to convert sbml to finite volume input")
82
+ return ReturnValue(success=False, message="Failed to convert sbml to finite volume input")
83
+ json_str: str = value.decode("utf-8")
84
+ # self.lib.freeString(json_ptr)
85
+ return ReturnValue.model_validate_json(json_data=json_str)
86
+ except Exception as e:
87
+ logging.exception("Error in sbml_to_finite_volume_input()", exc_info=e)
88
+ raise
89
+
90
+ def vcml_to_sbml(
91
+ self, vcml_content: str, application_name: str, sbml_file_path: Path, round_trip_validation: bool
92
+ ) -> ReturnValue:
93
+ try:
94
+ with IsolateManager(self.lib) as isolate_thread:
95
+ json_ptr: ctypes.c_char_p = self.lib.vcmlToSbml(
96
+ isolate_thread,
97
+ ctypes.c_char_p(vcml_content.encode("utf-8")),
98
+ ctypes.c_char_p(application_name.encode("utf-8")),
99
+ ctypes.c_char_p(str(sbml_file_path).encode("utf-8")),
100
+ ctypes.c_int(int(round_trip_validation)),
101
+ )
102
+
103
+ value: bytes | None = ctypes.cast(json_ptr, ctypes.c_char_p).value
104
+ if value is None:
105
+ logging.error("Failed to convert vcml application to sbml")
106
+ return ReturnValue(success=False, message="Failed to convert vcml to sbml")
107
+ json_str: str = value.decode("utf-8")
108
+ # self.lib.freeString(json_ptr)
109
+ return ReturnValue.model_validate_json(json_data=json_str)
110
+ except Exception as e:
111
+ logging.exception("Error in vcml_to_sbml()", exc_info=e)
112
+ raise
113
+
114
+ def sbml_to_vcml(self, sbml_content: str, vcml_file_path: Path) -> ReturnValue:
115
+ try:
116
+ with IsolateManager(self.lib) as isolate_thread:
117
+ json_ptr: ctypes.c_char_p = self.lib.sbmlToVcml(
118
+ isolate_thread,
119
+ ctypes.c_char_p(sbml_content.encode("utf-8")),
120
+ ctypes.c_char_p(str(vcml_file_path).encode("utf-8")),
121
+ )
122
+
123
+ value: bytes | None = ctypes.cast(json_ptr, ctypes.c_char_p).value
124
+ if value is None:
125
+ logging.error("Failed to convert sbml to vcml")
126
+ return ReturnValue(success=False, message="Failed to convert sbml to vcml")
127
+ json_str: str = value.decode("utf-8")
128
+ # self.lib.freeString(json_ptr)
129
+ return ReturnValue.model_validate_json(json_data=json_str)
130
+ except Exception as e:
131
+ logging.exception("Error in sbml_to_vcml()", exc_info=e)
132
+ raise
133
+
134
+ def vcml_to_vcml(self, vcml_content: str, vcml_file_path: Path) -> ReturnValue:
135
+ try:
136
+ with IsolateManager(self.lib) as isolate_thread:
137
+ json_ptr: ctypes.c_char_p = self.lib.vcmlToVcml(
138
+ isolate_thread,
139
+ ctypes.c_char_p(vcml_content.encode("utf-8")),
140
+ ctypes.c_char_p(str(vcml_file_path).encode("utf-8")),
141
+ )
142
+
143
+ value: bytes | None = ctypes.cast(json_ptr, ctypes.c_char_p).value
144
+ if value is None:
145
+ logging.error("Failed to regenerate vcml")
146
+ return ReturnValue(success=False, message="Failed to regenerate vcml")
147
+ json_str: str = value.decode("utf-8")
148
+ # self.lib.freeString(json_ptr)
149
+ return ReturnValue.model_validate_json(json_data=json_str)
150
+ except Exception as e:
151
+ logging.exception("Error in vcml_to_vcml()", exc_info=e)
152
+ raise
153
+
154
+ def vcell_infix_to_python_infix(
155
+ self, vcell_infix: str, target_python_infix: MutableString, buffer_size: int | None = None
156
+ ) -> ReturnValue:
157
+ try:
158
+ needed_buffer_size = int(1.5 * len(vcell_infix)) if buffer_size is None else buffer_size
159
+ buff = ctypes.create_string_buffer(needed_buffer_size)
160
+ with IsolateManager(self.lib) as isolate_thread:
161
+ json_ptr = self.lib.vcellInfixToPythonInfix(
162
+ isolate_thread, ctypes.c_char_p(vcell_infix.encode("utf-8")), buff, needed_buffer_size
163
+ )
164
+ value: bytes | None = ctypes.cast(json_ptr, ctypes.c_char_p).value
165
+ if value is None:
166
+ logging.error("Failed to regenerate vcml")
167
+ return ReturnValue(success=False, message="Failed to generate python infix")
168
+ json_str = value.decode("utf-8")
169
+ if "not enough room, need: `" in json_str:
170
+ if buffer_size is not None:
171
+ logging.error("Failed to identify correct buffer size reported by previous error")
172
+ return ReturnValue(
173
+ success=False, message="Failed to identify correct buffer size reported by previous error"
174
+ )
175
+ # get the size from the error
176
+ index = json_str.find("not enough room, need: `") + len("not enough room, need: `")
177
+ end_index = json_str.find("`", index)
178
+ size_as_string: str = json_str[index:end_index]
179
+ if not size_as_string.isnumeric():
180
+ logging.error("Buffer size reported by previous error is not an integer!")
181
+ return ReturnValue(
182
+ success=False, message="Buffer size reported by previous error is not an integer!"
183
+ )
184
+ return self.vcell_infix_to_python_infix(vcell_infix, target_python_infix, int(size_as_string))
185
+ # self.lib.freeString(json_ptr)
186
+ target_python_infix.value = buff.value.decode("utf-8")
187
+ return ReturnValue.model_validate_json(json_data=json_str)
188
+ except Exception as e:
189
+ logging.exception("Error in vcell_infix_to_python_infix()", exc_info=e)
190
+ raise
191
+
192
+ def vcell_infix_to_num_expr_infix(
193
+ self, vcell_infix: str, target_num_expr_infix: MutableString, buffer_size: int | None = None
194
+ ) -> ReturnValue:
195
+ try:
196
+ needed_buffer_size = int(1.5 * len(vcell_infix)) if buffer_size is None else buffer_size
197
+ buff = ctypes.create_string_buffer(needed_buffer_size)
198
+ with IsolateManager(self.lib) as isolate_thread:
199
+ json_ptr = self.lib.vcellInfixToNumExprInfix(
200
+ isolate_thread, ctypes.c_char_p(vcell_infix.encode("utf-8")), buff, needed_buffer_size
201
+ )
202
+ value: bytes | None = ctypes.cast(json_ptr, ctypes.c_char_p).value
203
+ if value is None:
204
+ logging.error("Failed to regenerate vcml")
205
+ return ReturnValue(success=False, message="Failed to generate NumExpr infix")
206
+ json_str = value.decode("utf-8")
207
+ if "not enough room, need: `" in json_str:
208
+ if buffer_size is not None:
209
+ logging.error("Failed to identify correct buffer size reported by previous error")
210
+ return ReturnValue(
211
+ success=False, message="Failed to identify correct buffer size reported by previous error"
212
+ )
213
+ # get the size from the error
214
+ index = json_str.find("not enough room, need: `") + len("not enough room, need: `")
215
+ end_index = json_str.find("`", index)
216
+ size_as_string: str = json_str[index:end_index]
217
+ if not size_as_string.isnumeric():
218
+ logging.error("Buffer size reported by previous error is not an integer!")
219
+ return ReturnValue(
220
+ success=False, message="Buffer size reported by previous error is not an integer!"
221
+ )
222
+ return self.vcell_infix_to_num_expr_infix(vcell_infix, target_num_expr_infix, int(size_as_string))
223
+ # self.lib.freeString(json_ptr)
224
+ target_num_expr_infix.value = buff.value.decode("utf-8")
225
+ return ReturnValue.model_validate_json(json_data=json_str)
226
+ except Exception as e:
227
+ logging.exception("Error in vcell_infix_to_num_expr_infix()", exc_info=e)
228
+ raise
@@ -0,0 +1,102 @@
1
+ import ctypes
2
+ import platform
3
+ from _ctypes import byref
4
+ from importlib.resources import files
5
+
6
+ import libvcell
7
+
8
+
9
+ class VCellNativeLibraryLoader:
10
+ lib: ctypes.CDLL
11
+
12
+ def __init__(self) -> None:
13
+ self.lib = self._load_library()
14
+ self._define_entry_points()
15
+
16
+ def _load_library(self) -> ctypes.CDLL:
17
+ system = platform.system()
18
+ lib_ext = {"Linux": ".so", "Darwin": ".dylib", "Windows": ".dll"}.get(system)
19
+
20
+ if lib_ext is None:
21
+ raise OSError(f"Unsupported operating system: {system}")
22
+
23
+ libs_dir = files(libvcell).joinpath("lib")
24
+ if not libs_dir.is_dir():
25
+ raise OSError(f"Could not find the shared library directory {libs_dir}")
26
+
27
+ for file in libs_dir.iterdir():
28
+ if file.name.endswith(lib_ext):
29
+ print(f"Found shared library: {file}")
30
+ return ctypes.CDLL(name=str(file))
31
+
32
+ raise OSError("Could not find the shared library")
33
+
34
+ def _define_entry_points(self) -> None:
35
+ self.lib.vcmlToFiniteVolumeInput.restype = ctypes.c_char_p
36
+ self.lib.vcmlToFiniteVolumeInput.argtypes = [ctypes.c_void_p, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p]
37
+
38
+ self.lib.sbmlToFiniteVolumeInput.restype = ctypes.c_char_p
39
+ self.lib.sbmlToFiniteVolumeInput.argtypes = [ctypes.c_void_p, ctypes.c_char_p, ctypes.c_char_p]
40
+
41
+ self.lib.sbmlToVcml.restype = ctypes.c_char_p
42
+ self.lib.sbmlToVcml.argtypes = [ctypes.c_void_p, ctypes.c_char_p, ctypes.c_char_p]
43
+
44
+ self.lib.vcmlToSbml.restype = ctypes.c_char_p
45
+ self.lib.vcmlToSbml.argtypes = [
46
+ ctypes.c_void_p,
47
+ ctypes.c_char_p,
48
+ ctypes.c_char_p,
49
+ ctypes.c_char_p,
50
+ ctypes.c_int,
51
+ ]
52
+
53
+ self.lib.vcmlToVcml.restype = ctypes.c_char_p
54
+ self.lib.vcmlToVcml.argtypes = [ctypes.c_void_p, ctypes.c_char_p, ctypes.c_char_p]
55
+
56
+ # vcmlToMovingBoundaryInput is only present in native libraries built with moving-boundary
57
+ # support; guard so the package still loads against older shared libraries.
58
+ if hasattr(self.lib, "vcmlToMovingBoundaryInput"):
59
+ self.lib.vcmlToMovingBoundaryInput.restype = ctypes.c_char_p
60
+ self.lib.vcmlToMovingBoundaryInput.argtypes = [
61
+ ctypes.c_void_p,
62
+ ctypes.c_char_p,
63
+ ctypes.c_char_p,
64
+ ctypes.c_char_p,
65
+ ]
66
+
67
+ self.lib.vcellInfixToPythonInfix.restype = ctypes.c_char_p
68
+ self.lib.vcellInfixToPythonInfix.argtypes = [
69
+ ctypes.c_void_p,
70
+ ctypes.c_char_p,
71
+ ctypes.c_char_p,
72
+ ctypes.c_longlong,
73
+ ]
74
+
75
+ self.lib.vcellInfixToNumExprInfix.restype = ctypes.c_char_p
76
+ self.lib.vcellInfixToNumExprInfix.argtypes = [
77
+ ctypes.c_void_p,
78
+ ctypes.c_char_p,
79
+ ctypes.c_char_p,
80
+ ctypes.c_longlong,
81
+ ]
82
+
83
+ self.lib.freeString.restype = None
84
+ self.lib.freeString.argtypes = [ctypes.c_char_p]
85
+
86
+
87
+ class IsolateManager:
88
+ lib: ctypes.CDLL
89
+ isolate: ctypes.c_void_p
90
+ isolate_thread: ctypes.c_void_p
91
+
92
+ def __init__(self, lib: ctypes.CDLL) -> None:
93
+ self.lib = lib
94
+ self.isolate = ctypes.c_void_p()
95
+ self.isolate_thread = ctypes.c_void_p()
96
+
97
+ def __enter__(self) -> ctypes.c_void_p:
98
+ self.lib.graal_create_isolate(None, byref(self.isolate), byref(self.isolate_thread))
99
+ return self.isolate_thread
100
+
101
+ def __exit__(self, exc_type: type | None, exc_val: Exception, exc_tb: object | None) -> None:
102
+ self.lib.graal_tear_down_isolate(self.isolate_thread)
libvcell/lib/.gitkeep ADDED
File without changes
Binary file
@@ -0,0 +1,91 @@
1
+ from pathlib import Path
2
+
3
+ from libvcell._internal.native_calls import MutableString, ReturnValue, VCellNativeCalls
4
+
5
+
6
+ def vcml_to_sbml(
7
+ vcml_content: str, application_name: str, sbml_file_path: Path, round_trip_validation: bool
8
+ ) -> tuple[bool, str]:
9
+ """
10
+ Convert VCML content to SBML file
11
+
12
+ Args:
13
+ vcml_content (str): VCML content
14
+ application_name (str): VCell Biomodel application name
15
+ sbml_file_path (Path): path to resulting SBML file
16
+
17
+ Returns:
18
+ tuple[bool, str]: A tuple containing the success status and a message
19
+ """
20
+ native = VCellNativeCalls()
21
+ return_value: ReturnValue = native.vcml_to_sbml(
22
+ vcml_content=vcml_content,
23
+ application_name=application_name,
24
+ sbml_file_path=sbml_file_path,
25
+ round_trip_validation=round_trip_validation,
26
+ )
27
+ return return_value.success, return_value.message
28
+
29
+
30
+ def sbml_to_vcml(sbml_content: str, vcml_file_path: Path) -> tuple[bool, str]:
31
+ """
32
+ Convert SBML content to finite volume input files
33
+
34
+ Args:
35
+ sbml_content (str): SBML content
36
+ vcml_file_path (Path): path to resulting VCML file
37
+
38
+ Returns:
39
+ tuple[bool, str]: A tuple containing the success status and a message
40
+ """
41
+ native = VCellNativeCalls()
42
+ return_value: ReturnValue = native.sbml_to_vcml(sbml_content=sbml_content, vcml_file_path=vcml_file_path)
43
+ return return_value.success, return_value.message
44
+
45
+
46
+ def vcml_to_vcml(vcml_content: str, vcml_file_path: Path) -> tuple[bool, str]:
47
+ """
48
+ Process VCML content to regenerated VCML file
49
+
50
+ Args:
51
+ vcml_content (str): VCML content
52
+ vcml_file_path (Path): path to resulting VCML file
53
+
54
+ Returns:
55
+ tuple[bool, str]: A tuple containing the success status and a message
56
+ """
57
+ native = VCellNativeCalls()
58
+ return_value: ReturnValue = native.vcml_to_vcml(vcml_content=vcml_content, vcml_file_path=vcml_file_path)
59
+ return return_value.success, return_value.message
60
+
61
+
62
+ def vcell_infix_to_python_infix(vcell_infix: str) -> tuple[bool, str, str]:
63
+ """
64
+ Converts an infix string version of a VCell Native Expression, and converts it to a Python compatible version
65
+
66
+ Args:
67
+ vcell_infix (str): the infix to convert
68
+
69
+ Returns:
70
+ tuple[bool, str, str]: A tuple containing the success status, a message, and the converted infix
71
+ """
72
+ native = VCellNativeCalls()
73
+ target_python_infix = MutableString("")
74
+ return_value: ReturnValue = native.vcell_infix_to_python_infix(vcell_infix, target_python_infix)
75
+ return return_value.success, return_value.message, target_python_infix.value
76
+
77
+
78
+ def vcell_infix_to_num_expr_infix(vcell_infix: str) -> tuple[bool, str, str]:
79
+ """
80
+ Converts an infix string version of a VCell Native Expression, and converts it to a NumExpr compatible version
81
+
82
+ Args:
83
+ vcell_infix (str): the infix to convert
84
+
85
+ Returns:
86
+ tuple[bool, str, str]: A tuple containing the success status, a message, and the converted infix
87
+ """
88
+ native = VCellNativeCalls()
89
+ target_num_expr_infix = MutableString("")
90
+ return_value: ReturnValue = native.vcell_infix_to_num_expr_infix(vcell_infix, target_num_expr_infix)
91
+ return return_value.success, return_value.message, target_num_expr_infix.value
libvcell/py.typed ADDED
File without changes
@@ -0,0 +1,56 @@
1
+ from pathlib import Path
2
+
3
+ from libvcell._internal.native_calls import ReturnValue, VCellNativeCalls
4
+
5
+
6
+ def vcml_to_finite_volume_input(vcml_content: str, simulation_name: str, output_dir_path: Path) -> tuple[bool, str]:
7
+ """
8
+ Convert VCML content to finite volume input files
9
+
10
+ Args:
11
+ vcml_content (str): VCML content
12
+ simulation_name (str): simulation name
13
+ output_dir_path (Path): output directory path
14
+
15
+ Returns:
16
+ tuple[bool, str]: A tuple containing the success status and a message
17
+ """
18
+ native = VCellNativeCalls()
19
+ return_value: ReturnValue = native.vcml_to_finite_volume_input(vcml_content, simulation_name, output_dir_path)
20
+ return return_value.success, return_value.message
21
+
22
+
23
+ def vcml_to_moving_boundary_input(vcml_content: str, simulation_name: str, output_dir_path: Path) -> tuple[bool, str]:
24
+ """
25
+ Convert VCML content to Moving Boundary solver input (a MovingBoundarySetup XML file)
26
+
27
+ The named simulation must be configured for the Moving Boundary solver. The generated
28
+ MovingBoundarySetup XML can be consumed by the vcell-mbsolver package (``MovingBoundarySolver.from_xml``).
29
+
30
+ Args:
31
+ vcml_content (str): VCML content
32
+ simulation_name (str): simulation name (must use the Moving Boundary solver)
33
+ output_dir_path (Path): output directory path
34
+
35
+ Returns:
36
+ tuple[bool, str]: A tuple containing the success status and a message
37
+ """
38
+ native = VCellNativeCalls()
39
+ return_value: ReturnValue = native.vcml_to_moving_boundary_input(vcml_content, simulation_name, output_dir_path)
40
+ return return_value.success, return_value.message
41
+
42
+
43
+ def sbml_to_finite_volume_input(sbml_content: str, output_dir_path: Path) -> tuple[bool, str]:
44
+ """
45
+ Convert SBML content to finite volume input files
46
+
47
+ Args:
48
+ sbml_content (str): SBML content
49
+ output_dir_path (Path): output directory path
50
+
51
+ Returns:
52
+ tuple[bool, str]: A tuple containing the success status and a message
53
+ """
54
+ native = VCellNativeCalls()
55
+ return_value: ReturnValue = native.sbml_to_finite_volume_input(sbml_content, output_dir_path)
56
+ return return_value.success, return_value.message
@@ -0,0 +1,69 @@
1
+ Metadata-Version: 2.4
2
+ Name: libvcell
3
+ Version: 0.0.17
4
+ Summary: This is a python package which wraps a subset of VCell Java code as a native python package.
5
+ License-File: LICENSE
6
+ Author: Jim Schaff
7
+ Author-email: schaff@uchc.edu
8
+ Requires-Python: >=3.10,<4.0
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.10
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Classifier: Programming Language :: Python :: 3.14
15
+ Requires-Dist: pydantic (>=2.10.6,<3.0.0)
16
+ Project-URL: Documentation, https://virtualcell.github.io/libvcell/
17
+ Project-URL: Repository, https://github.com/virtualcell/libvcell
18
+ Description-Content-Type: text/markdown
19
+
20
+ # libvcell
21
+
22
+ [![Release](https://img.shields.io/github/v/release/virtualcell/libvcell)](https://img.shields.io/github/v/release/virtualcell/libvcell)
23
+ [![Build status](https://img.shields.io/github/actions/workflow/status/virtualcell/libvcell/main.yml?branch=main)](https://github.com/virtualcell/libvcell/actions/workflows/main.yml?query=branch%3Amain)
24
+ [![codecov](https://codecov.io/gh/virtualcell/libvcell/branch/main/graph/badge.svg)](https://codecov.io/gh/virtualcell/libvcell)
25
+ [![Commit activity](https://img.shields.io/github/commit-activity/m/virtualcell/libvcell)](https://img.shields.io/github/commit-activity/m/virtualcell/libvcell)
26
+ [![License](https://img.shields.io/github/license/virtualcell/libvcell)](https://img.shields.io/github/license/virtualcell/libvcell)
27
+
28
+ libvcell is a subset of VCell algorithms intended to support the [pyvcell](https://pypi.org/project/pyvcell/) python package.
29
+
30
+ - **Github repository**: <https://github.com/virtualcell/libvcell/>
31
+ - **Documentation** <https://virtualcell.github.io/libvcell/>
32
+
33
+ ## Getting started with your project
34
+
35
+ First, create a repository on GitHub with the same name as this project, and then run the following commands:
36
+
37
+ ```bash
38
+ git init -b main
39
+ git add .
40
+ git commit -m "init commit"
41
+ git remote add origin git@github.com:virtualcell/libvcell.git
42
+ git push -u origin main
43
+ ```
44
+
45
+ Finally, install the environment and the pre-commit hooks with
46
+
47
+ ```bash
48
+ make install
49
+ ```
50
+
51
+ You are now ready to start development on your project!
52
+ The CI/CD pipeline will be triggered when you open a pull request, merge to main, or when you create a new release.
53
+
54
+ To finalize the set-up for publishing to PyPI or Artifactory, see [here](https://fpgmaas.github.io/cookiecutter-poetry/features/publishing/#set-up-for-pypi).
55
+ For activating the automatic documentation with MkDocs, see [here](https://fpgmaas.github.io/cookiecutter-poetry/features/mkdocs/#enabling-the-documentation-on-github).
56
+ To enable the code coverage reports, see [here](https://fpgmaas.github.io/cookiecutter-poetry/features/codecov/).
57
+
58
+ ## Releasing a new version
59
+
60
+ - Create an API Token on [PyPI](https://pypi.org/).
61
+ - Add the API Token to your projects secrets with the name `PYPI_TOKEN` by visiting [this page](https://github.com/virtualcell/libvcell/settings/secrets/actions/new).
62
+ - Create a [new release](https://github.com/virtualcell/libvcell/releases/new) on Github.
63
+ - Create a new tag in the form `*.*.*`.
64
+ - For more details, see [here](https://fpgmaas.github.io/cookiecutter-poetry/features/cicd/#how-to-trigger-a-release).
65
+
66
+ ---
67
+
68
+ Repository initiated with [fpgmaas/cookiecutter-poetry](https://github.com/fpgmaas/cookiecutter-poetry).
69
+
@@ -0,0 +1,13 @@
1
+ libvcell/__init__.py,sha256=QyvFcsVpgutciGNcV2fK4UoetJVwfIugmW-Nv4I2wKo,820
2
+ libvcell/_internal/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ libvcell/_internal/native_calls.py,sha256=xXRC7CcTCGU019WOZD-DF3r7abqHCwWrrbWyknrMiZw,11723
4
+ libvcell/_internal/native_utils.py,sha256=hmSEOI2pCxwtY9CH4oOogQgacMPxk0fSuvB0wibr1sQ,3740
5
+ libvcell/lib/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ libvcell/lib/libvcell.dll,sha256=jYputwvK0ec4M569fAJ8Ei08NU5dJbPHQThzRrWwAk4,126287872
7
+ libvcell/model_utils.py,sha256=6ELwJHL3woshU78PxFpfHjK-GGG0ijRujEOsIi99a1c,3376
8
+ libvcell/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ libvcell/solver_utils.py,sha256=UX6N05i_dMbi2o3ZqD7bocRZQZ8jZf3Pwt040rwwBVY,2255
10
+ libvcell-0.0.17.dist-info/licenses/LICENSE,sha256=uuKYfnhjRd2IOKltacW_z7JSZLVs9Mqj50o9fVnRFyI,1089
11
+ libvcell-0.0.17.dist-info/METADATA,sha256=2EeiBlGt6p5fSuTwU1jeePTpkeSvE94sdG3tLtbkT-U,3424
12
+ libvcell-0.0.17.dist-info/WHEEL,sha256=_2Rjawn4aPnD-wKFdXk6FO5w2r5WnOXvEEEUm7i__ms,92
13
+ libvcell-0.0.17.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: poetry-core 2.4.1
3
+ Root-Is-Purelib: false
4
+ Tag: py3-none-win32
5
+
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025, Jim Schaff
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.