Source code for myogen

import numpy as np
from numpy.random import Generator

SEED: int = 180319  # Seed for reproducibility
RANDOM_GENERATOR: Generator = np.random.default_rng(SEED)


[docs] def set_random_seed(seed: int = SEED) -> None: """ Set the random seed for reproducibility. Parameters ---------- seed : int, optional Seed value to set, by default SEED """ global RANDOM_GENERATOR RANDOM_GENERATOR = np.random.default_rng(seed) print(f"Random seed set to {seed}.")
class MyoGenSetupError(Exception): """Exception raised when MyoGen setup fails.""" pass def _setup_myogen(quiet: bool = False, force_rebuild: bool = False, strict: bool = False) -> bool: """ Set up MyoGen with NEURON mechanism compilation and loading. This function handles the compilation and loading of NMODL files required for neural simulations. It also compiles Cython extensions if they are not already available (typically only needed in development mode). Parameters ---------- quiet : bool, optional If True, suppress most output messages, by default False force_rebuild : bool, optional If True, force recompilation of Cython extensions even if they appear to be already compiled, by default False strict : bool, optional If True, raise exceptions on errors instead of returning False. Recommended for CI/CD pipelines and production deployments. Returns ------- bool True if setup completed successfully, False otherwise Raises ------ MyoGenSetupError If strict=True and setup fails """ def error(msg): """Handle errors based on strict mode.""" if strict: raise MyoGenSetupError(msg) else: print(f"ERROR: {msg}") return False # Check if Cython extensions are already compiled (from installed package) cython_modules = [ "myogen.simulator.neuron._cython._spindle", "myogen.simulator.neuron._cython._hill", "myogen.simulator.neuron._cython._gto", "myogen.simulator.neuron._cython._poisson_process_generator", "myogen.simulator.neuron._cython._gamma_process_generator", "myogen.simulator.neuron._cython._simulate_fiber", ] all_compiled = True if not force_rebuild: for module_name in cython_modules: try: __import__(module_name) except ImportError: all_compiled = False break else: all_compiled = False # Only compile Cython extensions if not already available if not all_compiled: if not quiet: print("Compiling Cython extensions (development mode)...") import os from pathlib import Path # Check if .pyx files exist (development install) myogen_root = Path(__file__).parent pyx_files_exist = ( myogen_root / "simulator" / "neuron" / "_cython" / "_spindle.pyx" ).exists() if not pyx_files_exist: if not quiet: print("Cython source files not found. This is expected for installed packages.") print("Cython extensions should have been compiled during installation.") # Try importing again to give a clearer error if truly missing try: from myogen.simulator.neuron._cython import _spindle if not quiet: print("Cython extensions are available.") except ImportError as e: return error( f"Cython extensions are not available: {e}\n" "Please reinstall MyoGen or run setup from a development clone." ) else: # Development mode: compile in-place from Cython.Build import cythonize from setuptools import Extension, setup setup( ext_modules=cythonize( [ Extension( "myogen.simulator.neuron._cython._spindle", ["myogen/simulator/neuron/_cython/_spindle.pyx"], extra_compile_args=["-O2", "-march=native", "-ffast-math"], ), Extension( "myogen.simulator.neuron._cython._hill", ["myogen/simulator/neuron/_cython/_hill.pyx"], extra_compile_args=["-O2", "-march=native"], ), Extension( "myogen.simulator.neuron._cython._gto", ["myogen/simulator/neuron/_cython/_gto.pyx"], extra_compile_args=["-O2", "-march=native", "-ffast-math"], ), Extension( "myogen.simulator.neuron._cython._poisson_process_generator", ["myogen/simulator/neuron/_cython/_poisson_process_generator.pyx"], extra_compile_args=["-O2", "-march=native", "-ffast-math"], ), Extension( "myogen.simulator.neuron._cython._gamma_process_generator", ["myogen/simulator/neuron/_cython/_gamma_process_generator.pyx"], extra_compile_args=["-O2", "-march=native", "-ffast-math"], ), Extension( "myogen.simulator.neuron._cython._simulate_fiber", ["myogen/simulator/neuron/_cython/_simulate_fiber.pyx"], extra_compile_args=["-O2", "-march=native", "-ffast-math"], ), ], compiler_directives={"embedsignature": True}, nthreads=4, ), script_args=["build_ext", "--inplace"], include_dirs=[np.get_include()], ) if not quiet: print("Cython extensions compiled successfully.") elif not quiet: print("Cython extensions already available.") # Compile NMODL files for NEURON try: from pathlib import Path import platform # Check if NMODL files are already compiled myogen_root = Path(__file__).parent nmodl_path = myogen_root / "simulator" / "nmodl_files" # Check for compiled NMODL libraries nmodl_compiled = False if platform.system() == "Windows": # On Windows, look for nrnmech.dll nmodl_compiled = any(nmodl_path.glob("*nrnmech.dll")) else: # On Unix, look for libnrnmech.so or x86_64 directory nmodl_compiled = (nmodl_path / "x86_64").exists() or any(nmodl_path.glob("*nrnmech.so")) if nmodl_compiled and not force_rebuild: if not quiet: print("NMODL mechanisms already compiled.") return True else: if not quiet: print("Compiling NMODL mechanisms...") from myogen.utils.nmodl import compile_nmodl_files result = compile_nmodl_files(quiet=quiet) if result and not quiet: print("NMODL mechanisms compiled successfully.") return result except ImportError as e: return error(f"NEURON not available, cannot compile mechanisms: {e}") except Exception as e: return error(f"MyoGen setup failed: {e}") from myogen.utils.nmodl import ( load_nmodl_mechanisms, NMODLLoadError, get_mechanism_parameters, validate_mechanism_parameter, set_mechanism_param, ) # Auto-load NMODL mechanisms when MyoGen is imported # quiet=True suppresses success messages, but warnings are still shown # Use strict=True in your code to raise exceptions on failure _nmodl_loaded = load_nmodl_mechanisms(quiet=True, strict=False) __all__ = [ "RANDOM_GENERATOR", "SEED", "set_random_seed", "load_nmodl_mechanisms", "NMODLLoadError", "MyoGenSetupError", "get_mechanism_parameters", "validate_mechanism_parameter", "set_mechanism_param", "_setup_myogen", ]