Welcome to Glia Packet Manager’s documentation!

Source Code Coverage Black Formatting Documentation Status

Glia is an NMODL asset manager. It can be used with Arbor and NEURON to automatically compile, build, and import assets at runtime. The asset manager caches compiled results and automatically recompiles it when the source code or environment changes.

Packaging your mod files as a Glia package allows you to distribute them as dependencies of your Python models and delegates the installation, distribution, versioning and archiving of your assets to your favorite Python package manager.

Usage

Glia can be installed from pip:

pip install nmodl-glia

Glia will check whether packages have been added, changed or removed and will recompile and load the library if necessary. This means that except for importing Glia there’s not much you need to do!

from neuron import h
import glia as g

section = h.Section(name="soma")
# Load your favourite Kv1 mechanism.
g.insert(section, "Kv1")

# Note: to load the library at import time you can import glia.library instead
import glia.library

Glia avoids conflicts between authors and even variants of the same mechanism and allows you to select sensible default preferences on many levels: globally, per script, per context or per function call.

Asset management

Glia allows for multiple assets to refer to the same mechanism by giving them a unique name per package. The standard naming convention is as follows:

glia__<package-name>__<asset-name>__<variant-name>

Double underscores in packages, assets or variant names are not allowed.

This naming convention allows for multiple people to provide an implementation of the same asset, and by using variants even one package can provide multiple variations on the same mechanism. The default variant is 0.

If you install multiple packages that provide the same asset, or if you would like to specify another variant you will need to tell Glia which one you require. You can do so by setting your asset preferences.

Asset preferences

There are 4 different scopes for providing asset preferences (from low to high priority):

  • Global scope: Selects a default mechanism asset everywhere.

  • Script scope: Selects a default mechanism asset for the remainder of the Python script.

  • Context scope: Select a preferred package or variant for all glia.insert calls within the context block.

  • Single use: Selects a mechanism asset for a single glia.insert call

Single use

Whenever you call glia.insert you can append your preferences for that insert:

g.insert('Kv1', variant='high_activity', pkg='some_package')
# Equivalent to (note the extra parenthesis):
g.insert(('Kv1', 'high_activity', 'some_package'))

Context scope

Any glia.insert or glia.resolve call within the with statement will preferably use the given package or variant:

from patch import p
s = p.Section()
with g.context(pkg='some_package'):
  g.insert(s, 'Kv1')
  g.insert(s, 'Kv1', variant='high_activity')

You can also specify a dictionary with multiple asset-specific preferences:

from patch import p
s = p.Section()
with g.context(assets={
   'Kv1': {'package': 'some_package', 'variant': 'high_activity'},
   'HCN1': {'variant': 'revised'}
}):
  g.insert(s, 'Kv1')
  g.insert(s, 'HCN1')
  # Not affected by the context:
  g.insert(s, 'Kir2.3')

And you can even combine, preferring a certain package unless the dictionary specifies otherwise:

from patch import p
s = p.Section()
with g.context(assets={
   'Kv1': {'package': 'specific_preference', 'variant': 'high_activity'},
   'HCN1': {'variant': 'revised'}
}, package='base_preference'):
  g.insert(s, 'Kv1')
  g.insert(s, 'HCN1')

Contexts may be nested, where the innermost context takes precedence.

Warning

When creating distribution-ready models, set up your models inside of a strict context, with both package and variant explicitly set so that a user’s Glia preferences do not affect the reproducibility of your model.

Note

When using models that set a strict context, the only way to adjust the mechanisms via Glia is to import the package module before Glia, and to set package.mods = [], so that the context fails to find the mechanisms and Glia falls back on your mechanisms.

Script scope

Use glia.select to select a preferred mechanism asset, similar to the single use syntax, for the remainder of the lifetime of the glia module:

section_global_Kv1 = h.Section()
section_local_Kv1 = h.Section()
g.insert(section_global_Kv1, 'Kv1') # Will use your global Kv1 mechanism
g.select('Kv1', pkg='not_my_models', variant='high_activity')
g.insert(section_local_Kv1, 'Kv1') # Will use the above selected Kv1 mechanism

Global scope

Applying global scope uses the Glia command-line tool and will configure glia to always select a mechanism asset as default.

Go to your favorite command-line and enter:

glia select Kv1 --pkg=some_pkg_name --variant=non_default

This will set your preference in any script you use.

Packaging

Glia packages use flit:

pip install flit

Creating a package

Use the following command, and fill out the prompts:

glia pkg new

This creates a template package that can be immediately published with flit publish. You can change the version inside of __init__.py by changing __version__.

Adding mod files

Use the following command, and fill out the prompts:

glia pkg add path/to/file.mod

You can specify a different --name and --variant. Defaults to the file name without extension and "0" respectively.

glia

Module contents

NMODL Asset Manager for Arbor and NEURON

~ Glues your neurons together!

Manage a local NMODL library that’s automatically compiled, loaded, and recompiled whenever you change your NMODL code or simulator environment.

glia.catalogue(name)

Load or build an Arbor mechanism catalogue.

Parameters:

name (str) – Name of the Glia installed Arbor catalogue.

glia.compile()

Compile and test all mod files found in all Glia packages.

glia.context(assets=None, pkg=None, variant=None)

Creates a context that sets glia preferences during a with statement.

glia.get_cache_path()

Get the cache path where intermediary files are stored.

Glia also stores a JSON cache in another directory, which you won’t find here, but glia cache --clear can reset.

glia.get_packages()

Return all installed packages.

glia.insert(section, asset, variant=None, pkg=None, /, attributes=None, x=None)

Insert a mechanism or point process into a Section.

Parameters:
  • section (Section) – The section to insert the asset into.

  • asset (string) – The name of the asset. Will be resolved into a fully qualified NEURON name based on preferences, unless a fully qualified name is given.

  • attributes (dict) – Attributes of the asset to set on the section/mechanism.

  • pkg (string) – Package preference. Overrides global & script preferences.

  • variant (string) – Variant preference. Overrides global & script preferences.

  • x (float) – Position along the section to place the point process at. Does not apply to mechanisms.

Raises:

LibraryError if the asset isn’t found or was incorrectly marked as a point process.

glia.load_library()

Load the glia library (if it isn’t loaded yet).

glia.package(name)

Return package.

Parameters:

name (str) – Name of the installed glia package.

glia.resolve(asset, pkg=None, variant=None)

Resolve an asset selection command to the name known to NEURON.

glia.select(asset, pkg=None, variant=None)

Set script scope preferences for an asset.

Parameters:
  • asset (string) – Unresolved asset name.

  • pkg (string) – Name of the package to prefer.

  • variant (string) – Name of the variant to prefer.

glia.assets module

class glia.assets.Catalogue(package: Package)

Bases: object

assemble_arbor_mod_dir()
build(verbose=None, debug=False, gpu=None)
is_fresh()
load() arbor.catalogue
property name
class glia.assets.Mod(relpath: str, asset_name, *, variant='0', is_point_process=False, is_artificial_cell=False, dialect: Literal['arbor'] | Literal['neuron'] = None, builtin=False)

Bases: object

property arbor_name
property mech_id
property mod_name
property path: Path
property pkg
property pkg_name
set_package(package: Package)
class glia.assets.ModName(pkg_name: str, asset: str, variant: str)

Bases: object

property arbor_mod_name
property full_mod_name
property mech_id
classmethod parse(name: str)
classmethod parse_path(path: str)
property short_mod_name
class glia.assets.Package(name: str, root: Path, *, mods: list[Mod] = None, builtin=False)

Bases: object

build_catalogue(*args, **kwargs) arbor.catalogue
property catalogue
get_mods(dialect=None) list[Mod]
property hash
load_catalogue() arbor.catalogue
property mod_hash
property name
property root

glia.resolution module

Resolves package, mechanism and variant constraints into asset names that can be requested from the Glia library.

class glia.resolution.IndexEntry(name)

Bases: object

append(asset)
class glia.resolution.Resolver(manager)

Bases: object

construct_index()
has_preference(asset_name)
lookup(mod_name)
preference_context(assets=None, pkg=None, variant=None)
resolve(asset_name, pkg=None, variant=None)
resolve_preference(asset_name, pkg=None, variant=None)
set_preference(asset_name, glbl=False, pkg=None, variant=None)

Indices and tables