SubModule: activate_virtualenv

Importation of this module activate a virtualenv if os.environ['SOMA_VIRTUALENV'] contains the directory path of the virutalenv.

This module makes it possible to use a specific virtualenv directory in contexts where it is difficult activate it (for instance in crontab). For instance, a script importing cubicweb the following way:

from soma import activate_virtualenv
import cubicweb

can be set to use a specific virutalenv install of cubicweb:

env SOMA_VIRTUALENV=/path/to/virutalenv python /path/to/script.py

SubModule: application

  • author: Yann Cointepas

  • organization: NeuroSpin

  • license: CeCILL B

class soma.application.Application(*args, **kwargs)[source]

Any program using soma should create an Application instance to manage its configuration and to store any kind of value that have to be global to the program.

The __init__ method of Singleton derived class should do nothing. Derived classes must define __singleton_init__() instead of __init__.

initialize()[source]

This method must be called once to setup the application.

static load_plugin_module(plugin_module)[source]

This method loads a plugin module. It imports the module without raising an exception if it fails.

SubModule: archive

soma.archive.is_archive(filename)[source]

Returns true if filename is an archive and false otherwise.

soma.archive.pack(output_filename, sources)[source]

Packs the source_dir directory in the output_filename archive.

soma.archive.pack_tar(output_filename, sources, type='gz')[source]

Creates a tar archive in output_filename from the source_dir directory.

soma.archive.pack_zip(output_filename, sources)[source]

Creates a zip archive in output_filename from the source_dir directory.

soma.archive.unpack(input_filename, extract_dir)[source]

Unpacks the input_filename archive to the extract_dir directory.

soma.archive.untar(input_filename, extract_dir)[source]

Extracts the input_filename archive to the extract_dir directory.

soma.archive.unzip(input_filename, extract_dir)[source]

Extracts the input_filename archive to the extract_dir directory.

SubModule: bufferandfile

BufferAndFile instances are used to read data from a file (for instance for identification) and “put back” the data on the file.

  • author: Yann Cointepas

  • organization: NeuroSpin

  • license: CeCILL B

class soma.bufferandfile.BufferAndFile(file_object)[source]

This class is a read only file-like object that allows to read ahead and push data back into the stream. All pushed back data are stored in a buffer that is “read” by all subsequent read acces until it is empty. When the buffer is empty, reading is done directly on the attached file object.

Example:

from soma.bufferandfile import BufferAndFile

# Open a file with a buffer
f = BufferAndFile.open(fileName)
# Check that the file content is XML
start = f.read(5)
# Put back the read characters
f.unread( start )
if start == '<?xml':
    # Use the file in an XML parser
    ...
elif start == '&HDF':
    # Use the file in an HDF5 parser
    ...

Create a file-like object that adds an unread() method to an opened file_object.

change_file(file_object)[source]

Change the internal file object (keeps the internal buffer untouched).

clone()[source]

Return a new L{BufferAndFile} instance with the same internale buffer and the same internal file object as C{self}.

next()[source]

Iteration protocol

static open(*args, **kwargs)[source]

Open a file with built-in open() and create a BufferAndFile instance.

read(size=None)[source]

Read the file

readline(size=None)[source]

Read one text line

seek(offset, whence=0)[source]

If whence is 0 or 2 (absolute seek positioning) or if offset is negative, internal buffer is cleared and seek is done directly on the internal file object. Otherwise (relative seek with a positive offset), internal buffer is taken into account.

tell()[source]

Position in file

unread(string_value)[source]

Adds data at the begining of the internal buffer. Data in the internal buffer will be returned by all subsequent read acces until the buffer is empty.

SubModule: config

Config module that sets up version variable and finds the BrainVISA brainvisa-share data directory.

soma.config.fullVersion
soma.config.shortVersion
soma.config.full_version
soma.config.short_version
soma.config.BRAINVISA_SHARE

SubModule: controller: Traits-based controller objects

Classes

API

class soma.controller.controller.Controller(*args, **kwargs)[source]

A Controller contains some traits: attributes typing and observer (callback) pattern.

The class provides some methods to add/remove/inspect user defined traits.

`user_traits_changed`

single event that can be sent when several traits changes. This event has to be triggered explicitely to take into account changes due to call(s) to add_trait or remove_trait.

Type

Event

user_traits()[source]
is_user_trait()[source]
add_trait()[source]
remove_trait()[source]
_clone_trait()[source]

Initilaize the Controller class.

During the class initialization create a class attribute ‘_user_traits’ that contains all the class traits and instance traits defined by user (i.e. the traits that are not automatically defined by HasTraits or Controller). We can access this class parameter with the ‘user_traits’ method.

If user trait parameters are defined directly on derived class, this procedure call the ‘add_trait’ method in order to not share user traits between instances.

add_trait(name, *trait)[source]

Add a new trait.

Parameters
  • name (str (mandatory)) – the trait name.

  • trait (traits.api (mandatory)) – a valid trait.

static checked_trait(trait)[source]

Check the trait and build a new one if needed.

This function mainly checks the default value of the given trait, and tests in some ways whether it is valid ot not. If not, a new trait is created to replace it.

For now it just checks that lists with a non-null minlen will actually get a default value which is a list with this minimum size. Otherwise it causes exceptions in the traits notification system at some point.

Parameters

trait (Trait instance to be checked) –

Returns

new_trait – the returned trait may be the input one (trait), or a new one if it had to be modified.

Return type

Trait instance

copy(with_values=True)[source]

Copy traits definitions to a new Controller object

Parameters

with_values (bool (optional, default: False)) – if True, traits values will be copied, otherwise the defaut trait value will be left in the copy.

Returns

copied – the returned copy will have the same class as the copied object (which may be a derived class from Controller). Traits definitions will be copied. Traits values will only be copied if with_values is True.

Return type

Controller instance

export_to_dict(exclude_undefined=False, exclude_transient=False, exclude_none=False, exclude_empty=False, dict_class=<class 'collections.OrderedDict'>)[source]

return the controller state to a dictionary, replacing controller values in sub-trees to dicts also.

Parameters
  • exclude_undefined (bool (optional)) – if set, do not export Undefined values

  • exclude_transient (bool (optional)) – if set, do not export values whose trait is marked “transcient”

  • exclude_none (bool (optional)) – if set, do not export None values

  • exclude_empty (bool (optional)) – if set, do not export empty lists/dicts values

  • dict_class (class type (optional, default: soma.sorted_dictionary.OrderedDict)) – use this type of mapping type to represent controllers. It should follow the mapping protocol API.

import_from_dict(state_dict, clear=False)[source]

Set Controller variables from a dictionary. When setting values on Controller instances (in the Controller sub-tree), replace dictionaries by Controller instances appropriately.

Parameters
  • state_dict (dict, sorted_dictionary or OrderedDict) – dict containing the variables to set

  • clear (bool (optional, default: False)) – if True, older values (in keys not listed in state_dict) will be cleared, otherwise they are left in place.

is_parameter_protected(param)[source]

Tells whether the given parameter is protected or not

is_user_trait(trait)[source]

Method that evaluate if a trait is a user parameter (i.e. not an Event).

Returns

out – True if the trait is a user trait, False otherwise.

Return type

bool

protect_parameter(param, state=True)[source]

Protect the named parameter.

Protecting is not a real lock, it just marks the parameter a list of “protected” parameters. This is typically used to mark values that have been set manually by the user (using the ControllerWidget for instance) and that should not be later modified by automatic parameters tweaking (such as completion systems).

Protected parameters are listed in an additional trait, “protected_parameters”.

If the “state” parameter is False, then we will unprotect it (calling unprotect_parameter())

remove_trait(name)[source]

Remove a trait from its name.

Parameters

name (str (mandatory)) – the trait name to remove.

reorder_traits(traits_list)[source]

Reorder traits in the controller according to a new ordered list.

If the new list does not contain all user traits, the remaining ones will be appended at the end.

Parameters

traits_list (list) – New list of trait names. This list order will be kept.

unprotect_parameter(param)[source]

Unprotect the named parameter

user_traits()[source]

Method to access the user parameters.

Returns

out – a dictionnary containing class traits and instance traits defined by user (i.e. the traits that are not automatically defined by HasTraits or Controller). Returned values are sorted according to the ‘order’ trait meta-attribute.

Return type

dict

class soma.controller.controller.ControllerTrait(controller, inner_trait=None, **kwargs)[source]

A specialized trait type for Controller values.

Build a Controller valued trait.

Contrarily to Instance(Controller), it ensures better validation when assigning values.

It has the ability to convert values from dictionaries, so the trait value can be assigned with a dict, whereas it is actually a Controller. This works recursively if the controller contains traits which are also controllers.

Parameters
  • controller (Controller instance (mandatory)) – default value for trait, and placeholder for allowed traits

  • inner_trait (Trait instance (optional)) – if provided, the controller is assumed to be an “open key” type, new keys/traits can be added on the fly like in a dictionary, and this inner_trait is the trait type used to instantiate new traits when new keys are encountered while setting values. If inner_trait is not provided, we will look if the controller instance is an OpenKeyController, and in such case, take its value trait.

inner_traits()[source]

Returns a tuple containing the inner traits for this trait. Most trait handlers do not have any inner traits, and so will return an empty tuple. The exceptions are List and Dict trait types, which have inner traits used to validate the values assigned to the trait. For example, in List( Int ), the inner traits for List are ( Int, ).

class soma.controller.controller.JsonControllerDecoder(*args, **kwargs)[source]

object_hook, if specified, will be called with the result of every JSON object decoded and its return value will be used in place of the given dict. This can be used to provide custom deserializations (e.g. to support JSON-RPC class hinting).

object_pairs_hook, if specified will be called with the result of every JSON object decoded with an ordered list of pairs. The return value of object_pairs_hook will be used instead of the dict. This feature can be used to implement custom decoders. If object_hook is also defined, the object_pairs_hook takes priority.

parse_float, if specified, will be called with the string of every JSON float to be decoded. By default this is equivalent to float(num_str). This can be used to use another datatype or parser for JSON floats (e.g. decimal.Decimal).

parse_int, if specified, will be called with the string of every JSON int to be decoded. By default this is equivalent to int(num_str). This can be used to use another datatype or parser for JSON integers (e.g. float).

parse_constant, if specified, will be called with one of the following strings: -Infinity, Infinity, NaN. This can be used to raise an exception if invalid JSON numbers are encountered.

If strict is false (true is the default), then control characters will be allowed inside strings. Control characters in this context are those with character codes in the 0-31 range, including '\t' (tab), '\n', '\r' and '\0'.

class soma.controller.controller.JsonControllerEncoder(*, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)[source]

Constructor for JSONEncoder, with sensible defaults.

If skipkeys is false, then it is a TypeError to attempt encoding of keys that are not str, int, float or None. If skipkeys is True, such items are simply skipped.

If ensure_ascii is true, the output is guaranteed to be str objects with all incoming non-ASCII characters escaped. If ensure_ascii is false, the output can contain non-ASCII characters.

If check_circular is true, then lists, dicts, and custom encoded objects will be checked for circular references during encoding to prevent an infinite recursion (which would cause an RecursionError). Otherwise, no such check takes place.

If allow_nan is true, then NaN, Infinity, and -Infinity will be encoded as such. This behavior is not JSON specification compliant, but is consistent with most JavaScript based encoders and decoders. Otherwise, it will be a ValueError to encode such floats.

If sort_keys is true, then the output of dictionaries will be sorted by key; this is useful for regression tests to ensure that JSON serializations can be compared on a day-to-day basis.

If indent is a non-negative integer, then JSON array elements and object members will be pretty-printed with that indent level. An indent level of 0 will only insert newlines. None is the most compact representation.

If specified, separators should be an (item_separator, key_separator) tuple. The default is (’, ‘, ‘: ‘) if indent is None and (‘,’, ‘: ‘) otherwise. To get the most compact JSON representation, you should specify (‘,’, ‘:’) to eliminate whitespace.

If specified, default is a function that gets called for objects that can’t otherwise be serialized. It should return a JSON encodable version of the object or raise a TypeError.

default(obj)[source]

Implement this method in a subclass such that it returns a serializable object for o, or calls the base implementation (to raise a TypeError).

For example, to support arbitrary iterators, you could implement default like this:

def default(self, o):
    try:
        iterable = iter(o)
    except TypeError:
        pass
    else:
        return list(iterable)
    # Let the base class default method raise the TypeError
    return JSONEncoder.default(self, o)
class soma.controller.controller.OpenKeyController(value_trait=<traits.trait_types.Any object>, *args, **kwargs)[source]

A dictionary-like controller, with “open keys”: items may be added on the fly, traits are created upon assignation.

A value trait type should be specified to build the items.

Usage:

>>> dict_controller = OpenKeyController(value_trait=traits.Str())
>>> print(dict_controller.user_traits().keys())
[]
>>> dict_controller.my_item = 'bubulle'
>>> print(dict_controller.user_traits().keys())
['my_item']
>>> print(dict_controller.export_to_dict())
{'my_item': 'bubulle'}
>>> del dict_controller.my_item
>>> print(dict_controller.export_to_dict())
{}

Build an OpenKeyController controller.

Parameters

value_trait (Trait instance (optional, default: Any())) – trait type to be used when creating traits on the fly

soma.controller.controller.controller_to_dict(item, exclude_undefined=False, exclude_transient=False, exclude_none=False, exclude_empty=False, dict_class=<class 'collections.OrderedDict'>)[source]

Convert an item to a Python value where controllers had been converted to dictionary. It can recursively convert the values contained in a Controller instances or a dict instances. All other items are returned untouched.

Parameters
  • exclude_undefined (bool (optional)) – if set, do not export Undefined values

  • exclude_transient (bool (optional)) – if set, do not export values whose trait is marked “transcient”

  • exclude_none (bool (optional)) – if set, do not export None values

  • exclude_empty (bool (optional)) – if set, do not export empty lists/dicts values

  • dict_class (class type (optional, default: soma.sorted_dictionary.OrderedDict)) – use this type of mapping type to represent controllers. It should follow the mapping protocol API.

SubModule: crypt

Functions to manage private/public keys encryption. This module needs Crypto module.

soma.crypt.decrypt_RSA(private_key_loc, package)[source]

param: public_key_loc Path to your private key param: package String to be decrypted return decrypted string

soma.crypt.encrypt_RSA(public_key_loc, message)[source]

param: public_key_loc Path to public key param: message String to be encrypted return base64 encoded encrypted string

soma.crypt.generate_RSA(bits=2048)[source]

Generate an RSA keypair with an exponent of 65537 in PEM format param: bits The key length in bits Return private key and public key

SubModule: debug

Utility classes and functions for debugging.

  • author: Yann Cointepas

  • organization: NeuroSpin

  • license: CeCILL B

soma.debug.function_call_info(frame=None)[source]

Return a dictionary that gives information about a frame corresponding to a function call. The directory contains the following items:

  • ‘function’: name of the function called

  • ‘filename’: name of the python file containing the function

  • ‘lineno’: line number executed in ‘filename’

  • ‘arguments’: arguments passed to the function. It is a list containing pairs of (argument name, argument value).

soma.debug.print_stack(out=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>, frame=None)[source]

Print information about the stack, including argument passed to functions called.

soma.debug.stack_calls_info(frame=None)[source]

Return a list containing function_call_info(frame) for all frame in the stack.

SubModule: factory

class soma.factory.ClassFactory(class_types={})[source]

ClassFactory is the base class for creating factories that can look for classes in Python modules and create instances.

find_class(class_type, factory_id)[source]

Finds a class deriving of the class corresponding to class_type and whose factory_id attribute has a given value. Look for all subclasses of parent class declared in the modules of self.module_path and returns the first one having cls.factory_id == factory_id. If none is found, returns None.

get(class_type, factory_id)[source]

Returns an instance of the class identified by class_type and factory_id. There can be only one instance per class_type and factory_id. Once created with the first call of this method, it is stored in self.instances and simply returned in subsequent calls.

If get_class is True, returns the class instead of an instance

get_class(class_type)[source]

Returns the class corresponding to a given class type. First look for a dictionary in self.class_types, then look into parent classes.

soma.factory.find_items_in_module(module_name, check)[source]

Finds all the items defined in a Python module that where check(cls) is True. If the module is a package, it also look recursively into submodules.

soma.factory.find_subclasses_in_module(module_name, parent_class)[source]

Finds all the classes defined in a Python module that derive from a given class or class name. If the module is a package, it also look into submodules.

SubModule: fom: File Organization Model

File Organization Model (FOM)

A FOM is a JSON file (dictionary) describing how to make filenames from a set of attributes.

FOM definition

Ex:

{
    "fom_name": "morphologist-auto-nonoverlap-1.0",

    "fom_import": ["formats-brainvisa-1.0", "brainvisa-formats-3.2.0",
                  "shared-brainvisa-1.0"],

    "attribute_definitions" : {
      "acquisition" : {"default_value" : "default_acquisition"},
      "analysis" : {"default_value" : "default_analysis"},
      "sulci_recognition_session" :  {"default_value" : "default_session"},
      "graph_version": {"default_value": "3.1"},
    },

    "shared_patterns": {
      "acquisition": "<center>/<subject>/t1mri/<acquisition>",
      "analysis": "{acquisition}/<analysis>",
      "recognition_analysis": "{analysis}/folds/<graph_version>/<sulci_recognition_session>_auto",
    },

    "processes" : {
        "Morphologist" : {
            "t1mri":
                [["input:{acquisition}/<subject>", "images"],
            "imported_t1mri":
                [["output:{acquisition}/<subject>", "images"]],
            "t1mri_referential":
                [["output:{acquisition}/registration/RawT1-<subject>_<acquisition>", "Referential"]],
            "reoriented_t1mri":
                [["output:{acquisition}/<subject>", "images"]],
            "t1mri_nobias":
                [["output:{analysis}/nobias_<subject>", "images" ]],
            "split_brain":
                [["output:{analysis}/segmentation/voronoi_<subject>","images"]],
            "left_graph":
                [["output:{analysis}/folds/<graph_version>/<side><subject>",
                    "Graph and data",
                    {"side": "L", "labelled": "No"}]],
            "left_labelled_graph":
                [["output:{recognition_analysis}/<side><subject>_<sulci_recognition_session>_auto",
                    "Graph and data", {"side": "L"}]],
            "right_graph":
                [["output:{analysis}/folds/<graph_version>/<side><subject>",
                    "Graph and data", {"side":"R","labelled":"No"}]],
            "right_labelled_graph":
                [["output:{recognition_analysis}/<side><subject>_<sulci_recognition_session>_auto",
                    "Graph and data", {"side": "R"}]],
            "Talairach_transform":
                [["output:{acquisition}/registration/RawT1-<subject>_<acquisition>_TO_Talairach-ACPC",
                    "Transformation matrix"]]
        }
    }
}

The dictionary may contain:

fom_name: string

identifier of the FOM model. Several FOMs may coexist under different identifiers.

fom_import: list

dependencies between FOMs. A Fom may import others to benefit from its formats, patterns etc.

attribute_definitions: dict

a dict of predefines attributes. It is generally used to define default values for some attributes. Each attribute defined here is also a dict. In this sub-dict, the key “default_value” provides the attribute default value.

Attributes don’t need to be defined here, they are automatically defined as they are used in path patterns. But here we can assign them additional information (typically default values).

shared_patterns: dict

mapping of reusable patterns. Such patterns will be replaced with their contents when used in the file paths patterns. To use such a pattern, place it with brackets {} in file paths patterns:

"input:{acquisition}/<subject>"

here {aquisition} is the shared pattern “aquisition”, and <subject> is the attribute “subject”

A pattern definition may also use attributes between <attribute_name> quotes, and / or reuse other patterns between {pattern} curly brackets.

processes: dict

dictionary of processes supported by the FOM, and path definitions for their parameters. The dict is organized by process, then in each process a sub-dict contains its parameters definitions. For a given parameter, a list of the FOM rules is given: several rules are allowed.

Process names keys may be a fully qualified module/class name, or a short identifier, or a “contextual” name: the name a process has in the context of a pipeline.

A FOM rule is a list of 2 or 3 elements:

[patterrn, formats, attributes]
pattern: string

the FOM pattern for the file path of the given parameter. A pattern starts with a directory identifier (input, output, shared), followed by a semicolon (:), and a file pattern which may contain attributes (<attrib>) and/or shared patterns ({pattern}). Ex:

"input:{acquisition}/<subject>"
formats: string or list

name of a format, a formats list, or a list of allowed formats names. The formats will rule the possible file extensions.

attributes: dict, optional

An optional dict assigning locally some attributes values. Ex:

{"side": "left"}

The attributes values here are used both to replace attributes values in the current file path pattern, and to select the matching rule when attributes values are given externally (hm, to be checked actually).

A FOM file is a JSON file (actually a JSON/YAML extended file, to allow comments within it), which should be placed in a common directory where the FOM manager will look for it (share/foms/)

How to use FOMS

At higher level, they are used for instance in CAPSUL.

At lower level, they are used through several classes:

  • FileOrganizationModelManager manages a set of FOMs, looks for them in a search path, reads them.

  • FileOrganizationModels represents a FOM rules set.

  • AttributesToPaths is used to convert a set of attributes into filenames (which is the main use of FOMs).

  • PathToAttributes performs the reverse operation: match attributes and determines their values from a given filename.

class soma.fom.AttributesToPaths(foms, selection=None, directories={}, preferred_formats={}, debug=None)[source]

Utility class for attributes set -> file paths transformation. Part of the FOM engine.

allowed_extensions_for_parameter(**kwargs)[source]

Either formats or (process_name and param) should be passed kwargs —— formats: list of str

if provided only this parameter will be used

process_name: str

name of the process

param: str

name of the process parameter

class soma.fom.FileOrganizationModelManager(paths=None)[source]

Manage the discovery and instanciation of available FileOrganizationModel (FOM). A FOM can be represented as a YAML/JSON file (or a series of YAML/JSON files in a directory). This class allows to identify these files contained in a predefined set of directories (see find_fom method) and to instanciate a FileOrganizationModel for each identified file (see get_fom method).

Create a FOM manager that will use the given paths to find available FOMs.

find_foms()[source]

Return a list of file organisation model (FOM) names. These FOMs can be loaded with load_foms. FOM files (or directories) are looked for in self.paths.

fom_files()[source]

Return a list of file organisation model (FOM) names, as in find_foms(), but does not clear and reload the cache. These FOMs can be loaded with load_foms. FOM files (or directories) are looked for in self.paths.

class soma.fom.PathToAttributes(foms, selection=None)[source]

Utility class for file paths -> attributes set transformation. Part of the FOM engine.

soma.fom.deep_update(update, original)[source]

Recursively update a dict. Subdict’s won’t be overwritten but also updated.

class soma.fom.json_reader[source]

This class has a single static method load that loads an JSON file with two features not provided by all JSON readers:

  • JSON syntax is extended. For instance comments are allowed.

  • The order of elements in dictionaries can be preserved by using parameter object_pairs_hook=OrderedDict (as in Python 2.7 JSON reader).

soma.fom.read_json(file_name)[source]

Read a json-like file using yaml or json. In case of failure, issue a clearer message with filename, and when appropriate a warning about yaml not being installed.

SubModule: global_naming

class soma.global_naming.GlobalNaming(*args, **kwargs)[source]

No doc ?

The __init__ method of Singleton derived class should do nothing. Derived classes must define __singleton_init__() instead of __init__.

get_name(obj)[source]
get_object(global_name)[source]
parse_global_name(global_name)[source]
soma.global_naming.get_name(obj)[source]
soma.global_naming.get_object(global_name)[source]

SubModule: html

Utility functions for HTML format.

  • author: Yann Cointepas

  • organization: NeuroSpin

  • license: CeCILL B

soma.html.htmlEscape(msg)[source]

Replace special characters by their correponding html entity.

All characters that have a corresponding named HTML entity are replaced.

  • returns: unicode

soma.html.lesserHtmlEscape(msg)[source]

Replace special characters by their correponding html entity.

All characters that have a corresponding named HTML entity are replaced, except accented characters commonly used in French text (éàèâêôîûàö) and the double-quote character (“).

  • returns: unicode

SubModule: importer

Utility classes and functions for Python import and sip namespace renaming.

  • author: Yann Cointepas

  • organization: NeuroSpin

  • license: CeCILL B

class soma.importer.ExtendedImporter(*args, **kwargs)[source]

ExtendedImporter is used to import external modules in a module managing rules that allow ro rename and delete or do anything else on the imported package. As imported packages could modify each others, all the registered rules are applied after each import using this ExtendedImporter.

The __init__ method of Singleton derived class should do nothing. Derived classes must define __singleton_init__() instead of __init__.

applyRules()[source]

This method apply rules for each extended module.

importInModule(moduleName, globals, locals, importedModuleName, namespacesList=[], handlersList=None, *args, **kwargs)[source]

This method is used to import a module applying rules (rename rule, delete rule, …) .

Parameters
  • moduleName (string) – name of the module to import into (destination, not where to find it).

  • globals (dict) – globals dictionary of the module to import into.

  • locals (dict) – locals dictionary of the module to import into.

  • importedModuleName (string) – name of the imported module. Normally relative to the current calling module package.

  • namespacesList (list) – a list of rules concerned namespaces for the imported module.

  • handlersList (list) – a list of handlers to apply during the import of the module.

class soma.importer.ExtendedImporterHelper[source]

Static methods declared to help extended import process.

static getModuleObject(module, name)[source]

This static method is used to get an object contained in the namespace of a module.

Parameters
  • name (string) – complete name including namespace of the object to get.

  • module (module) – module object to get objects from.

Returns

Object found in the module or None if no object was found.

Return type

object

class soma.importer.ExtendedModule(moduleName, globals, locals)[source]

Register a series of rules to apply during the import process of the extended module. An extended module is able to refer to other modules and to apply rules to these other modules. The extended module manages the globals and locals variables declared for the module.

Each rule contains the module to which it refers, and the handlers to call for the rule to apply. The calling order is the registering order.

addHandlerRules(module, handlersList=[], *args, **kwargs)[source]

This method is used to add handler rules (renaming rule, deleting rule, …) .

Parameters
  • module (module) – module object to apply rules to.

  • handlersList (list) – a list of handlers to the module.

addPartialRules(module, partialsList=[])[source]

This method is used to add handler rules (renaming rule, deleting rule, …) .

Parameters
  • module (module) – module object to apply rules to.

  • partialsList (list) – a list of functools.partial() objects that will be called during the import of the module.

applyRules()[source]

Apply the functools.partial() handler rules (renaming rule, deleting rule, …) for the ExtendedModule.

class soma.importer.GenericHandlers[source]

Static generic handlers used as import rules.

static moveChildren(namespace, extendedModule, referedModule)[source]

This static method is used to move child objects of a refered module to the extended module.

Parameters
  • namespace (string) – namespace of the referedModule to get objects to move from.

  • extendedModule (ExtendedModule) – ExtendedModule object into which move objects.

  • referedModule (module) – refered module object to get objects to move from.

static removeChildren(namespace, prefixes, extendedModule, referedModule)[source]

This static method is used to remove children from the extended module.

Parameters
  • namespace (string) – namespace of the referedModule.

  • prefixes (list) – list of prefixes of objects to remove.

  • extendedModule (ExtendedModule) – ExtendedModule object to remove objects from.

  • referedModule (module) – refered module object.

soma.importer.execfile(filename, globals=None, locals=None)[source]

Replacement for python2 execfile() six.exec_() needs an open file, hence this wrapper for convenience. Files are open with UTF-8 encoding on python3.

SubModule: info

Information module, containing version variables, plus some setuptools-related variables .. attribute:: version_major

soma.info.version_minor
soma.info.version_micro
soma.info.version_extra

SubModule: logging

soma.logging.create_logger(name)[source]

SubModule: minf

This module contains all the framework necessary to customize, read and write minf files. A minf file is composed of structured data saved in XML or Python format. The minf framework provides tools to read and write minf files but also to customize the way Python objects are read an written.

There are several submodules in this package but main functions and classes can be imported from soma.minf.api:

  • author: Yann Cointepas

  • organization: NeuroSpin

  • license: CeCILL B

soma.minf.api.createMinfWriter(destFile, format='XML', reducer='minf_2.0')[source]

Create a writer for storing objects in destFile. Example:

from soma.minf.api import createMinfWriter
writer = createMinfWriter( '/tmp/test.minf' )
writer.write( 'A string' )
writer.write( { 'A dict key': [ 'A list', 'with two elements' ] } )
writer.close()
Parameters
  • format (string) – name of the format to write.

  • reducer (string) – name of the reducer to use (see L{soma.minf.tree} for more information about reducers).

soma.minf.api.iterateMinf(source, targets=None, stop_on_error=True, exceptions=[])[source]

Returns an iterator over all objects stored in a minf file.

Example:

from soma.minf.api import iterateMinf

for item in iterateMinf('test.minf'):
  print(repr(item))
Parameters

source (string) – Input file name or file object. If it is a file name, it is opened with C{open( source )}.

soma.minf.api.minfFormat(source)[source]

Return a pair (format, reduction) identifying the minf format. If source is not a minf file, (None, None) is returned. Otherwise, format is a string representing the format of the minf file: ‘XML’ or ‘python’. reduction is the name of the reducer used to write the minf file or None if format is ‘python’.

Example:

from soma.minf.api import minfFormat
format, reduction = minfFormat('/home/me/test.minf')

If source is a BufferAndFile instance, this call behave as if nothing has been read from the file. This can be useful if you have an opened file that cannot be seeked backward:

Example:

from soma.bufferandfile import BufferAndFile
from soma.minf.api import minfFormat, readMinf

bf = BufferAndFile(stream_file_object)
format, reduction = minfFormat(bf)
if format is not None:
  minfContent = readMinf(bf)
Parameters

source (string) – Input file name or file object. If it is a file name, it is opened with open(source).

soma.minf.api.readMinf(source, targets=None, stop_on_error=True, exceptions=[])[source]

Entirerly reads a minf file and returns its content in a tuple. Equivalent to tuple(iterateMinf(source)).

see: :func`iterateMinf`

soma.minf.api.writeMinf(destFile, args, format='XML', reducer=None)[source]

Creates a minf writer with createMinfWriter() and write the content of args in it.

Parameters

SubModule: mpfork

Run worker functions in separate processes.

The use case is somewhat similar to what can be done using either queue.Queue and threads, or using multiprocessing. That is: run a number of independent job functions, dispatched over a number of worker threads/processes.

The mpfork module is useful in cases the above methods cannot work:

  • threading in python is globally mainly inefficient because of the GIL.

  • multiprocessing makes heavy use of pickles to pass objects and parameters, and there are cases we are using objects which cannot be pickled, or which pickling generates heavy IO traffic (large data objects)

The method here is based on the queue / thread schema, but uses fork() to actually execute the workers in a separate process. Only results are passed through pickles, so the worker return results must be picklable, but not the input arguments and objects.

Use:

  • allocate a Queue

  • allocate a results list with the exact size of the jobs number

  • allocate a set of worker threads (typically one per processor or core). The function allocate_workers() can do this for you.

  • fill the queue with jobs, each being a tuple (job_index, function, args, kwargs, results_list)

  • add a number of empty jobs (None) to the queue, one per allocated worker: this will be the marker for the end of processing in each worker thread. It is necessary to explicitly add these empty jobs since an empty queue is not the signal for the end of processing: it can be re-filled at any time.

  • jobs run in workers

  • join the queue

  • join the worker threads

  • the result list gets the return data for each job

njobs = 10
q = queue.Queue()
res = [None] * njobs
workers = allocate_workers(q, 0) # one per core
for i in range(njobs):
    job = (i, sum, ((i, i), ), {}, res)
    q.put(job)

# add as many empty jobs as the workers number to end them
for i in range(len(workers)):
    q.put(None)

# wait for every job to complete
q.join()
# terminate all threads
for w in workers:
    w.join()

print('result:', res)

In case of error, the job result will be an exception with stack information: (exception type, exception instance, stack_info)

Availability: Unix

soma.mpfork.allocate_workers(q, nworker=0, thread_only=False, *args, **kwargs)[source]

Utility finction to allocate worker threads.

Parameters
  • q (Queue instance) – the jobs queue which will be fed with jobs for processing

  • thread_only (bool) – if True, workers will run jobs in the worker thread, not using a separate process. This flag thus allows to choose a threaded or multiprocessing implementation.

  • nworker (int) – number of worker threads (jobs which will run in parallel). A positive number (1, 2…) will be used as is, 0 means all available CPU cores (see multiprocessing.cpu_count()), and a negative number means all CPU cores except this given number.

  • args – additional arguments will be pased to the jobs function(s) after individual jobs arguments: they are args common to all jobs (if any)

  • kwargs – additional arguments will be pased to the jobs function(s) after individual jobs arguments: they are args common to all jobs (if any)

Returns

workers – workers list, each is a thread instance running the worker loop function. Threads are already started (ie.

Return type

list

soma.mpfork.run_job(f, *args, **kwargs)[source]

Internal function, runs the function in a remote process. Uses fork() to perform it.

Availability: Unix

soma.mpfork.worker(q, thread_only, *args, **kwargs)[source]

Internal function: worker thread loop: * pick a job in the queue q * execute it, either in the current thread, or in a remote process (using

run_job()), depending on the thread_only parameter value

  • store the result in the result list

  • start again with another job

The loop ends when a job in the queue is None.

Warning

Here we are making use of fork() (Unix only) inside a thread. Some systems do not behave well in this situation. See the os.fork() doc

SubModule: notification

This module provides a notification system that can be used to register callbacks (i.e Python callables) that will all be called by a single Notifier.notify() call.

  • author: Yann Cointepas, Dominique Geffroy

  • organization: NeuroSpin

  • license: CeCILL B

class soma.notification.EditableTree(name=None, id=None, modifiable=True, content=[], visible=True, enabled=True)[source]

The base class to model a tree of items. This class can be derived to change implementation.

An EditableTree contains items which can be

  • an item branch: it contains other items as children

  • an item leaf: doesn’t have children

The list of items is an ObservableSortedDictionary which notifies its changes to registred listeners.

If the tree is modifiable, new items can be added.

Every item is an EditableTree.Item.

EditableTree is iterable over its items.

EditableTree also inherits from ObservableAttributes, so registred listeners can be notified of attributes value change.

To call a method when item list changes:

editableTree.addListener(callbackMethod)

To call a method when an item list changes at any depth in the tree:

editableTree.addListenerRec(callbackMethod)

To call a method when an attribute of the tree changes:

editableTree.onAttributeChange(attributeName, callbackMethod)

To call a method when an attribute changes at any depth in the tree:

editableTree.onAttributeChangeRec(attributeName, callbackMethod)
defaultName

default name of the tree

Type

string

name

the name of the tree

Type

string

id

tree identifier (a hash by default)

Type

string

modifiable

if True, new items can be added, items can be deleted and modified

Type

bool

unamed

indicates if name parameter was none, so the tree has the default name.

Type

bool

visible

indicates if the tree is visible (if not it may be hidden in a graphical representation)

Type

bool

Parameters
  • name (string) – the name of the tree

  • id (string) – tree identifier (a hash by default)

  • modifiable (bool) – if True, new items can be added, items can be deleted and modified

  • content (list) – children items (EditableTree.Item)

  • visible (bool) – indicates if the tree is visible (if not it may be hidden in a graphical representation)

  • enabled (bool) –

class Branch(name=None, id=None, icon=None, tooltip=None, copyEnabled=True, modifiable=True, delEnabled=True, content=[], visible=True, enabled=True)[source]

A Branch is an Item that can contain other items.

It inherits from Item and from ObservableSortedDictionary, so it can have children items.

All parameters must have default values to be able to create new elements automatically

add(item)[source]

Adds an item in the tree. If this item’s id is already present in the tree as a key, add the item’s content in the corresponding key.

recursive method

compItems(id1, id2)[source]

Comparison function

Returns

  • 1 if i1 > i2

  • -1 if i1 < i2

  • 0 if they are equal

isLeaf()[source]

Must be redefined in subclasses to say if the item is a leaf

sort(key=None, reverse=False)[source]

Recursive sort of the tree: items are sorted in all branches.

class Item(name=None, id=None, icon=None, tooltip=None, copyEnabled=True, modifiable=True, delEnabled=True, visible=True, enabled=True, *args)[source]

Base element of an EditableTree

Item inherits from ObservableAttributes, so it can notify registred listeners of attributes changes (for example name).

icon

filename of the image that can be used to represent the item

Type

string

name

Text representation of the item

Type

string

movable

True if the item can be moved in the tree

Type

bool

modifiable

True if the item can changed (add children, change text, icon)

Type

bool

delEnabled

True if deletion of the item is allowed

Type

bool

tooltip

description associated to the item

Type

string

copyEnabled

indicates if this item can be copied

Type

bool

visible

indicates if current item is visible (if not it may be hidden in a graphical representation)

Type

bool

enabled

indicates if the item is enabled, it could be visible but disabled

Type

bool

isDescendant(item)[source]

Returns True if the current item is a child or a child’s child… of the item in parameter

isLeaf()[source]

Must be redefined in subclasses to say if the item is a leaf

setAllModificationsEnabled(bool)[source]

Recursivly enables or disables item’s modification.

class Leaf(name='new', id=None, icon=None, tooltip=None, copyEnabled=True, modifiable=True, delEnabled=True, visible=True, enabled=True)[source]

A tree item that cannot have children items

isLeaf()[source]

Must be redefined in subclasses to say if the item is a leaf

add(item)[source]

Adds an item in the tree. If this item’s id is already present in the tree as a key, add the item’s content in the corresponding key.

recursive method

addListenerRec(listener)[source]

Add a listener to the tree recursivly at every level. The listener is added to the notifier of all branches of the tree.

compItems(id1, id2)[source]

Comparison function

Returns:

  • 1 if i1 > i2

  • -1 if i1 < i2

  • 0 if they are equal

isDescendant(item)[source]

Returns True if the current item is a child or a child’s child… of the item in parameter

Always False for the root of the tree

onAttributeChangeRec(attributeName, listener)[source]

Add a listener of the changes of this attribute value in the tree recursivly at every level.

The listener is added to the attribute change notifier of all branches of the tree.

removeEmptyBranches()[source]

If a branch item doesn’t contain any leaf or branch that contains leaf recursivly, the item is removed from the tree.

sort(key=None, reverse=False)[source]

Recursive sort of the tree: items are sorted in all branches.

class soma.notification.Notifier(parameterCount=None)[source]

Register a series of functions (or Notifier instances) which are all called whith the notify() method. The calling order is the registering order. If a Notifier is registered, its notify() method is called whenever self.notify() is called.

Parameters

parameterCount (int) – if not None, each registered function must be callable with that number of arguments (checking is done on registration).

add(listener)[source]

Register a callable or a Notifier that will be called whenever notify() is called. If the notifier has a parameterCount, checkParameterCount is used to verify that listener can be called with parameterCount parameters.

Parameters

listener (Python callable (function, method, etc.) or Notifier instance) – item to add to the notification list.

delayNotification(ignoreDoubles=False)[source]

Stop notification until restartNotification() is called. After a call to :meth`delayNotification`, all calls to notify() will only store the notification parameters until restartNotification() is called.

Parameters

ignoreDoubles (bool) – If True (the default), all calls to notify() with the same parameters as a previous call will be ignored (i.e. notification will be done only once for two identical calls).

notify(*args)[source]

Calls all the registered items in the notification list. All the parameters given to notify() are passed to the items in the list. For items in the list that are Notifier instance, their notify() method is called

remove(listener)[source]

Remove an item from the notification list. Do nothing if listener is not in the list.

Parameters

listener (Python callable or Notifier instance) – item previously registered with add().

Returns

True if a listener has been removed, False otherwise.

Return type

bool

restartNotification()[source]

Restart notifications that have been delayed by delayNotification(). All the calls to notify() that have been done between the call to delayNotification() and the call to restartNotification(), are applied immediately.

class soma.notification.ObservableAttributes(*args, **kwargs)[source]

ObservableAttributes allows to track modification of attributes at runtime. By registering callbacks, it is possible to be warn of the modification (setting and deletion) of any attribute of the instance.

delayAttributeNotification(ignoreDoubles=False)[source]

Stop attribute modification notification until restartAttributeNotification() is called. After a call to delayAttributeNotification(), all modification notification will only be stored until restartAttributeNotification() is called. This call is recursive on all attributes values that are instance of ObservableAttributes.

Parameters

ignoreDoubles (bool) – If True (False is the default), all notification with the same parameters as a previous notification will be ignored (i.e. notification will be done only once for two identical events).

notifyAttributeChange(name, value, oldValue=<undefined>)[source]

First, calls functions registered for modification of the attribute named name, then call functions registered for modification of any attribute.

onAttributeChange(first, second=None)[source]

Registers a function to be called when an attribute is modified or deleted. To call the function for any attribute modification, use the following syntax:

instance.onAttributeChange(function)

To register a function for a named attribute, use the following syntax:

instance.onAttributeChange(attributeName, function)

The registered function can have 0 to 4 parameters. Depending on its number of parameters, it will be called with the following values:

  • 4 parameters: (object, attributeName, newValue, oldValue)

  • 3 parameters: (attributeName, newValue, oldValue)

  • 2 parameters: (newValue, oldValue)

  • 1 parameter: (newValue)

Where:

  • object is the object whose attribute has been modified or deleted.

  • attributeName is the name of the modified or deleted attribute.

  • newValue is the value of the attribute after modification or Undefined if the attribute has been deleted.

  • oldValue is the value of the attribute before modification. If the attribute was not defined, oldValue = Undefined.

If the function accepts a variable number of parameters, it will be called with the maximum number of arguments possible.

removeOnAttributeChange(first, second=None)[source]

Remove a function previously registered with onAttributeChange(). To remove a function, the arguments of removeOnAttributeChange() must be the same as those passed to onAttributeChange() to register the function.

restartAttributeNotification()[source]

Restarts notifications that have been delayed by delayAttributeNotification(). All the modifications that happened between the call to delayAttributeNotification() and the call to restartAttributeNotification(), are notified immediately.

class soma.notification.ObservableList(content=None)[source]

A list that notifies its changes to registred listeners. Inherits from python list and contains an instance of Notifier (onChangeNotifier).

Example:

l = ObservableList()
l.addListener(update)
l.append(e)
INSERT_ACTION

used to notify insertion of new elements in the list

Type

int

REMOVE_ACTION

used to notify elements deletion

Type

int

MODIFY_ACTION

used to notify elements modification

Type

int

onChangeNotifier

the Notifier’s notify method is called when the list has changed.

Type

Notifier

Parameters

content (list) – elements to initialize the list content

addListener(listener)[source]

Registers the listener callback method in the notifier. The method must take 3 arguments: action, elems list, position

action should be one of:

  • INSERT_ACTION: elems have been inserted at position in the list

  • REMOVE_ACTION: elems have been removed [at position] in the list

  • MODIFY_ACTION: at position, some elements have been replaced by elems

The position given in the notify method will be between 0 and len(self)

Parameters

listener (function) – function to call to notify changes

append(elem)[source]

Adds the element at the end of the list. Notifies an insert action.

extend(l)[source]

Adds the content of the list l at the end of current list. Notifies an insert action.

getIndexInRange(i)[source]

Returns an index in the range of the list.

  • if i < 0 returns 0

  • if i > len(self), returns len(self)

getPositiveIndex(i)[source]

Returns an index between 0 and len(self)

  • if i is negative, it is replaced by len(self) + i

  • if index is again negative, it is replaced by 0

  • if index is beyond len(self) it is replaced by len(self)

insert(pos, elem)[source]

Inserts elem at position pos in the list. Notifies an insert action.

itemIndex(item)[source]

Returns item’s index in the list. It is different from the list.index() method that returns the index of the first element that has the same value as item.

pop(pos=None)[source]

Removes the element at position pos or the last element if pos is None.

Notifies a remove action.

Returns

the removed element

Return type

object

remove(elem)[source]

Removes the first occurence of elem in the list.

Notifies a remove action.

reverse()[source]

Inverses the order of the list. Notifies a modify action.

sort(key=None, reverse=False)[source]

Sorts the list using key function key.

Notifies a modify action.

Returns

key – key function: elem->key

Return type

function

class soma.notification.ObservableNotifier(parameterCount=None)[source]

This notifier can notify when the first listener is added and when the last listener is removed.

It enables to use the notifier only when there are some listeners registred.

onAddFirstListener

register a listener on this notifier to be called when the first listener is registred on ObservableNotifier

Type

Notifier

onRemoveLastListener

register a listener on this notifier to be called when the last listener is removed from ObservableNotifier

Type

Notifier

Parameters

parameterCount (int) – if not None, each registered function must be callable with that number of arguments (checking is done on registration).

add(listener)[source]

Register a callable or a Notifier that will be called whenever notify() is called. If the notifier has a parameterCount, checkParameterCount is used to verify that listener can be called with parameterCount parameters.

Parameters

listener (Python callable (function, method, etc.) or Notifier instance) – item to add to the notification list.

remove(listener)[source]

Remove an item from the notification list. Do nothing if listener is not in the list.

Parameters

listener (Python callable or Notifier instance) – item previously registered with add().

Returns

True if a listener has been removed, False otherwise.

Return type

bool

class soma.notification.ObservableSortedDictionary(*args)[source]

A sorted dictionary that notifies its changes. Inherits from python list and contains an instance of Notifier (onChangeNotifier).

Example:

d=ObservableSortedDictionary()
d.addListener(update)
d.insert(index, key, e)
INSERT_ACTION

used to notify insertion of new elements in the dictionary

Type

int

REMOVE_ACTION

used to notify elements deletion

Type

int

MODIFY_ACTION

used to notify elements modification

Type

int

onChangeNotifier

the Notifier’s notify method is called when the dictionaty has changed.

Type

Notifier

Initialize the dictionary with a list of ( key, value ) pairs.

addListener(listener)[source]

Registers the listener callback method in the notifier. The method must take 3 arguments: action, elems list, position

action should be one of:

  • INSERT_ACTION: elems have been inserted at position in the dictionary

  • REMOVE_ACTION: elems have been removed [at position] in the dict

  • MODIFY_ACTION: at position, some elements have been replaced by elems

The position given in the notify method will be between 0 and len(self)

Parameters

listener (function) – function to call to notify changes

clear()[source]

Removes all items from dictionary

insert(index, key, value)[source]

inserts a (key, value) pair in the sorted dictionary before position index. If key is already in the dictionary, a KeyError is raised.

Parameters
  • key – key to insert

  • value – value associated to key

Returns

index – index of C{key} in the sorted keys

Return type

integer

sort(key=None, reverse=False)[source]

Sorts the dictionary using function key to compare keys.

Notifies a modify action.

Parameters

key (function) – key function key->key

class soma.notification.ReorderedCall(function, parametersOrder)[source]

todo: documentation

class soma.notification.VariableParametersNotifier(mainParameters, *otherParameters)[source]

This class is a notifier that can register functions with various arguments count.

See also

Notifier

todo documentation

add(listener)[source]

See also

Notifier.add()

todo: documentation

remove(listener)[source]

todo: documentation

SubModule: path

Some useful functions to manage file or directorie names.

  • author: Yann Cointepas

  • organization: NeuroSpin

  • license: CeCILL B

soma.path.ensure_is_dir(d, clear_dir=False)[source]

If the directory doesn’t exist, use os.makedirs

soma.path.find_in_path(file, path=None)[source]

Look for a file in a series of directories. By default, directories are contained in PATH environment variable. But another environment variable name or a sequence of directories names can be given in path parameter.

Examples:

find_in_path('sh') could return '/bin/sh'
find_in_path('libpython3.10.so', 'LD_LIBRARY_PATH') could return '/usr/lib/x86_64-linux-gnu/libpython3.10.so'
soma.path.locate_file(pattern, root='.')[source]

Locates a file in a directory tree

Parameters
  • pattern (string) – The pattern to find

  • root (string) – The search root directory

Returns

The first found occurrence

soma.path.parse_query_string(path)[source]

Parses the query string from a path and returns a dictionary.

Example

soma.path.path_hash(path, hash=None)[source]

Return a hash hexdigest for a file or a directory.

soma.path.relative_path(path, referenceDirectory)[source]

Return a relative version of a path given a reference directory.

os.path.join(referenceDirectory, relative_path(path, referenceDirectory))
returns os.path.abspath(pat)

Example

relative_path('/usr/local/brainvisa-3.1/bin/brainvisa', '/usr/local')
returns 'brainvisa-3.1/bin/brainvisa'

relative_path('/usr/local/brainvisa-3.1/bin/brainvisa', '/usr/local/bin')
returns '../brainvisa-3.1/bin/brainvisa'

relative_path('/usr/local/brainvisa-3.1/bin/brainvisa', '/tmp/test/brainvisa')
returns '../../../usr/local/brainvisa-3.1/bin/brainvisa'
soma.path.remove_query_string(path)[source]

Remove the query string from a path.

Example

A path containing a query string is:

/dir1/file1?param1=val1&param2=val2&paramN=valN
remove_query_string( '/dir1/file1?param1=val1&param2=val2&paramN=valN' )

would return:

'/dir1/file1'
soma.path.split_path(path)[source]

Iteratively apply os.path.split() to build a list. Ignore trailing directory separator.

Examples

split_path('/home/myaccount/data/file.csv') returns ['/', 'home', 'myaccount', 'data', 'file.csv']
split_path('home/myaccount/data/file.csv') returns ['home', 'myaccount', 'data', 'file.csv']
split_path('/home/myaccount/data/') returns ['/', 'home', 'myaccount', 'data']
split_path('/home/myaccount/data') returns ['/', 'home', 'myaccount', 'data']
split_path('') returns ['']
soma.path.split_query_string(path)[source]

Split a path and its query string.

Example

A path containing a query string is:

/dir1/file1?param1=val1&param2=val2&paramN=valN
split_query_string( '/dir1/file1?param1=val1&param2=val2&paramN=valN' )

would return:

('/dir1/file1', '?param1=val1&param2=val2&paramN=valN')
soma.path.strict_urlparse(path)[source]

A “fixed” version of urlparse.urlparse() which preserves the case of the drive letter in windows paths. The standard urlparse changes ‘Z:/some/path’ to ‘z:/some/path’

soma.path.update_hash_from_directory(directory, hash)[source]

Update a hash object from the content of a directory. The hash will reflect the recursive content of all files as well as the paths in all directories.

soma.path.update_query_string(path, params, params_update_mode=0)[source]

Update the query string parameters in a path.

Parameters
  • path (string) – The path to update parameters within.

  • params (dict|list) – A dictionnary that contains keys and parameters to set in the query string

  • params_update_mode (dict|string|list|int) –

    The default value is QueryStringParamUpdateMode.REPLACE that lead to replace value in the query string path by the one given in the params dictionary.

    It is possible to change the default behaviour giving the value QueryStringParamUpdateMode.APPEND. This will lead to always append values of the params dictionary to values of the query string path. The default behaviour can also be changed by specifying a parameter name as string, in this case only values for that parameter name will be appended. It can also contains a list or a tuple of parameter names for which values will be appended.

    Finally, this parameter can be a dictionary that specifies which parameter has to be appended or replaced. The dictionary contains parameter names in its keys and QueryStringParamUpdateMode in values.

Returns

path – The path updated with given parameters

Return type

string

Example

A path containing a query string is:

/dir1/file1?param1=val1&param2=val2&paramN=valN

the params dictionary contains:

{'param1':'newval1', param2=newval2', param3':'newval3'}
update_query_string('/dir1/file1?param1=val1&param2=val2&paramN=valN',
                    {'param1':'newval1', 'param2':'newval2', 'param3':'newval3'})

would return:

'/dir1/file1?param1=newval1&param2=newval2&paramN=valN&param3=newval3'
update_query_string('/dir1/file1?param1=val1&param2=val2&paramN=valN',
                    {'param1':'newval1', 'param2':'newval2', 'param3':'newval3'},
                    QueryStringParamUpdateMode.APPEND)

would return:

'/dir1/file1?param1=val1&param1=newval1&param2=val2&param2=newval2&paramN=valN&param3=newval3'
update_query_string('/dir1/file1?param1=val1&param2=val2&paramN=valN',
                    {'param1':'newval1', 'param2':'newval2', 'param3':'newval3'},
                    'param2')

would return:

'/dir1/file1?param1=newval1&param2=val2&param2=newval2&paramN=valN&param3=newval3'
update_query_string('/dir1/file1?param1=val1&param2=val2&paramN=valN',
                    {'param1':'newval1', 'param2':'newval2', 'param3':'newval3'},
                    ('param1', 'param2'))

would return:

'/dir1/file1?param1=val1&param1=newval1&param2=val2&param2=newval2&paramN=valN&param3=newval3'
update_query_string('/dir1/file1?param1=val1&param2=val2&paramN=valN',
                    {'param1':'newval1', 'param2':'newval2', 'param3':'newval3'},
                    {'param1': QueryStringParamUpdateMode.APPEND,
                    'param2': QueryStringParamUpdateMode.REPLACE})

would return:

'/dir1/file1?param1=val1&param1=newval1&param2=val2&param2=newval2&paramN=valN&param3=newval3'

SubModule: qimage2ndarray

QImage <-> numpy.ndarray conversion module.

* ATTENTION: This code is outdated - I released a better extension * named ‘qimage2ndarray’ (that completes all TODO items below) in * the meantime, which is available via PyPI and here: * http://kogs-www.informatik.uni-hamburg.de/~meine/software/qimage2ndarray/

This supports conversion in both directions; note that in contrast to C++, in Python it is not possible to convert QImages into ndarrays without copying the data. The conversion functions in the opposite direction however do not copy the data.

TODO:

  • support record arrays in rgb2qimage (i.e. grok the output of qimage2numpy)

  • support unusual widths/alignments also in gray2qimage and rgb2qimage

  • make it possible to choose between views and copys of the data (eventually in both directions, when implemented in C++)

  • allow for normalization in numpy->QImage conversion (i.e. to quickly visualize images with different value ranges)

  • implement in C++

soma.qimage2ndarray.gray2qimage(gray)[source]

Convert the 2D numpy array gray into a 8-bit QImage with a gray colormap. The first dimension represents the vertical image axis.

ATTENTION: This QImage carries an attribute ndimage with a reference to the underlying numpy array that holds the data. On Windows, the conversion into a QPixmap does not copy the data, so that you have to take care that the QImage does not get garbage collected (otherwise PyQt will throw away the wrapper, effectively freeing the underlying memory - boom!).

soma.qimage2ndarray.qimage2numpy(qimage, dtype='array')[source]

Convert QImage to numpy.ndarray. The dtype defaults to uint8 for QImage.Format_Indexed8 or bgra_dtype (i.e. a record array) for 32bit color images. You can pass a different dtype to use, or ‘array’ to get a 3D uint8 array for color images.

soma.qimage2ndarray.rgb2qimage(rgb)[source]

Convert the 3D numpy array rgb into a 32-bit QImage. rgb must have three dimensions with the vertical, horizontal and RGB image axes.

ATTENTION: This QImage carries an attribute ndimage with a reference to the underlying numpy array that holds the data. On Windows, the conversion into a QPixmap does not copy the data, so that you have to take care that the QImage does not get garbage collected (otherwise PyQt will throw away the wrapper, effectively freeing the underlying memory - boom!).

SubModule: qt_gui

SubModule: qt_gui.controller_widget

class soma.qt_gui.controller_widget.ControllerWidget(controller, parent=None, name=None, live=False, hide_labels=False, select_controls=None, editable_labels=False, override_control_types=None, user_data=None, userlevel=0)[source]

Class that create a widget to set the controller parameters.

Method to initilaize the ControllerWidget class.

Parameters
  • controller (derived Controller instance (mandatory)) – a class derived from the Controller class we want to parametrize with a widget.

  • parent (QtGui.QWidget (optional, default None)) – the controller widget parent widget.

  • name ((optional, default None)) – the name of this controller widget

  • live (bool (optional, default False)) – if True, synchronize the edited values in the widget with the controller values on the fly, otherwise, wait the synchronization instruction to update the controller values.

  • hide_labels (bool (optional, default False)) – if True, don’t show the labels associated with the controls

  • select_controls (str (optional, default None)) – parameter to select specific conrtoller traits. Authorized options are ‘inputs’ or ‘outputs’.

  • editable_labels (bool (optional, default False)) – if True, labels (trait keys) may be edited by the user, their modification will trigger a signal.

  • override_control_types (dict (optional)) – if given, this is a “factory” dict assigning new controller editor types to some traits types.

  • user_data (any type (optional)) – optional user data that can be accessed by individual control editors

  • userlevel (int) – the current user level: some traits may be marked with a non-zero userlevel, and will only be visible if the ControllerWidget userlevel is more than (or equal) the trait level.

connect()[source]

Connect the controller trait and the controller widget controls

At the end al control will be connected with the associated trait, and when a ‘user_traits_changed’ signal is emited, the controls are updated (ie, deleted if necessary).

create_control(trait_name, trait)[source]

Create a control associated to a trait.

Parameters
  • trait_name (str (mandatory)) – the name of the trait from which we want to create a control. The control widget will share the same name

  • trait (Trait (mandatory)) – a trait item

disconnect()[source]

Disconnect the controller trait and the controller widget controls

get_control_class(trait)[source]

Find the control associated with the input trait.

The mapping is defined in the global class parameter ‘_defined_controls’.

Parameters

trait (Trait (mandatory)) – a trait item

Returns

control_class – the control class associated with the input trait. If no match has been found, return None

Return type

class

is_valid()[source]

Check that all edited fields are correct.

Returns

valid – True if all the controller widget controls are correctly filled, False otherwise

Return type

bool

static static_disconnect(controller, update_controls, groups_vibility_changed, controls, widget)[source]

disconnect() cannot be called at the right time. static_disconnect() is called via a Qt signat when the widget is destroyed. But the python part is already destroyed then.

update_controller()[source]

Update the controller.

At the end the controller traits values will match the controller widget user defined parameters.

update_controller_widget()[source]

Update the controller widget.

At the end the controller widget user editable parameters will match the controller traits values.

update_controls()[source]

Event to refresh controller widget controls and intern parameters.

The refresh is done off line, ie. we need first to disconnect the controller and the controller widget.

class soma.qt_gui.controller_widget.DeletableLineEdit(text=None, parent=None)[source]

Close button + line editor, used for modifiable key labels

class soma.qt_gui.controller_widget.ScrollControllerWidget(controller, parent=None, name=None, live=False, hide_labels=False, select_controls=None, disable_controller_widget=False, override_control_types=None, user_data=None, userlevel=0)[source]

Class that create a widget to set the controller parameters.

The widget is placed in a scroll area when large sets of parameters have to be tuned.

Method to initilaize the ScrollControllerWidget class.

Parameters
  • controller (derived Controller instance (mandatory)) – a class derived from the Controller class we want to parametrize with a widget.

  • parent (QtGui.QWidget (optional, default None)) – the controller widget parent widget.

  • name ((optional, default None)) – the name of this controller widget

  • live (bool (optional, default False)) – if True, synchronize the edited values in the widget with the controller values on the fly, otherwise, wait synchronization instructions to update the controller values.

  • hide_labels (bool (optional, default False)) – if True, don’t show the labels associated with the controls

  • select_controls (str (optional, default None)) – parameter to select specific conrtoller traits. Authorized options are ‘inputs’ or ‘outputs’.

  • disable_controller_widget (bool (optional, default False)) – if True disable the controller widget.

  • override_control_types (dict (optional)) – if given, this is a “factory” dict assigning new controller editor types to some traits types.

  • user_data (any type (optional)) – optional user data that can be accessed by individual control editors

  • userlevel (int) – the current user level: some traits may be marked with a non-zero userlevel, and will only be visible if the ControllerWidget userlevel is more than (or equal) the trait level.

SubModule: qt_gui.io

Utils for socket communication

class soma.qt_gui.io.Socket(host, port=None)[source]

Opens a connection to a socket server and provides methods to read from and write to socket streams. To handle specific message format, redefine readMessage method. By default it reads a line on the socket. To process messages, redefine processMessage method. By default it prints the message to standard output.

dest

socket server machine

Type

string

port

port that the socket server listens

Type

int

socket

python socket object

Type

socket.socket

socketnotifier

the notifier sends a signal when there’s something to read on the socket.

Type

qt.QSocketNotifier

readLock

lock to prevent threads from reading at the same time on the socket

Type

threading.Lock

writeLock

lock to prevent threads from writing at the same time on the socket

Type

threading.Lock

lock

lock to prevent concurrent access on object data because it can be used by multiple threads. At least principal thread and reading messages thread when it not possible to use a QSocketNotifier.

Type

threading.RLock

initialized

indicates if the connection is correctly opened

Type

bool

notifyenabled

indicates if message received on the socket must be processed.

Type

bool

loopRetry

class attribute: max number of connection tries

Type

int

defaultPort

class attribute: default port for socket server

Type

int

Parameters
  • host (string) – socket server machine (localhost if it is current machine)

  • port (int) – port that the socket server listens

close()[source]

Closes the connection.

disableHandler()[source]

Disables reading from the socket.

enableHandler()[source]

Enables reading from the socket.

findFreePort()[source]

Try to find the first unused port. @rtype: int @return: numero of a free port

getMessage(timeout=30)[source]

Called by message handler to gets the last received message. If socket communication is managed by a QSocketNotifier, the message is not yet read, so this method read it. If reading is in another process, the message is already read and it is in messages queue.

initialize(port=None)[source]

Connects the socket to the server and sets the frame to read data from the socket. Two methods for reading:

  • reading thread

  • QSocketNotifier (not possible on windows platform)

Returns

port – port that the socket server listens

Return type

int

messageHandler()[source]

This method is called when a message is received on the socket. Gets and processes the message.

processMessage(msg, excep)[source]

Processes a message received on the socket. This method only print the message. To do some specific treatment, subclass Socket and redefine this method.

readForever()[source]

Reading loop to handle reading messages from the socket. Used only if QSocketNotifier cannot be used.

readLine(timeout)[source]

Reads a line of data from the socket (a string followed by '\n'). self.readLock must be acquired before calling this method. If data cannot be read before timeout (in seconds), an IOError exception is raised.

Returns

timeout – max time to wait before reading the message.

Return type

int

readMessage(timeout=30)[source]

Reads a message from the socket. This method only gets the readlock and reads a line. To read specific message formats, subclass Socket and redefine this method.

Parameters

timeout (int) – max time to wait before reading the message.

Returns

message – the message received from the socket

Return type

string

send(msg)[source]

Sends data to the connected socket. @type msg: string @param msg: the message to send.

soma.qt_gui.io.findPlatform()[source]
Identify platform, possible return values are :
  • ‘windows’: Windows

  • ‘linux’: Linux

  • ‘sunos’: SunOS (Solaris)

  • ‘darwin’: Darwin (MacOS X)

  • None: unknown

SubModule: qt_gui.qt_backend

Compatibility module for PyQt and PySide. Currently supports PyQt4, PySide, and PyQt5. This modules handles differences between PyQt and PySide APIs and behaviours, and offers a few functions to make it easier to build neutral GUI code, which can run using either backend.

The main funcion here is set_qt_backend() which must be called to initialize the appropriate backend. Most functions of this module assume set_qt_backend() has been called first to setup internal variables.

Note that such compatibility generally requires to use PyQt4 with SIP API version 2, ie do not use QString, QVariant, QDate and similar classes, but directly convert to/from python types, which is also PySide behaviour. The qt_backend module switches to this API level 2, but this only works before the PyQt modules are imported, thus it may fail if PyQt has already be imported without such settings.

Qt submodules can be imported in two ways:

>>> from soma.qt_gui import qt_backend
>>> qt_backend.import_qt_submodule('QtWebKit')

or using the import statement:

>>> from soma.qt_gui.qt_backend import QtWebKit

in the latter case, set_qt_backend() will be called automatically to setup the appropriate Qt backend, so that the use of the backend selection is more transparent.

soma.qt_gui.qt_backend.getExistingDirectory(parent=None, caption='', directory='', options=None)[source]

PyQt4 / PySide compatible call to QFileDialog.getExistingDirectory

soma.qt_gui.qt_backend.getOpenFileName(parent=None, caption='', directory='', filter='', selectedFilter=None, options=0)[source]

PyQt4 / PySide compatible call to QFileDialog.getOpenFileName

soma.qt_gui.qt_backend.getSaveFileName(parent=None, caption='', directory='', filter='', selectedFilter=None, options=0)[source]

PyQt4 / PySide compatible call to QFileDialog.getSaveFileName

soma.qt_gui.qt_backend.get_qt_backend()[source]

get currently setup or loaded Qt backend name: “PyQt4” or “PySide”

soma.qt_gui.qt_backend.get_qt_module()[source]

Get the main Qt module (PyQt4 or PySide)

soma.qt_gui.qt_backend.import_qt_submodule(submodule)[source]

Import a specified Qt submodule. An alternative to the standard statement:

>>> from soma.qt_gui.qt_backend import <submodule>

The main differences is that it forces loading the module from the appropriate backend, whereas the import statement will reuse the already loaded one. Moreover it returns the module.

For instance,

>>> from soma.qt_gui import qt_backend
>>> qt_backend.set_qt_backend('PyQt4')
>>> from soma.qt_gui.qt_backend import QtWebKit
>>> QtWebKit
<module 'PyQt4.QtWebKit' from '/usr/lib/python2.7/dist-packages/PyQt4/QtWebKit.so'>
>>> qt_backend.set_qt_backend('PySide') # changing backend
WARNING:root:set_qt_backend: a different backend, PyQt4, has already be set, and PySide is now requested
>>> from soma.qt_gui.qt_backend import QtWebKit
>>> QtWebKit
<module 'PyQt4.QtWebKit' from '/usr/lib/python2.7/dist-packages/PyQt4/QtWebKit.so'>

In the above example, we are still using the QtWebKit from PyQt4. Now:

>>> QtWebKit = qt_backend.import_qt_submodule('QtWebKit')
>>> QtWebKit
<module 'PySide.QtWebKit' from '/usr/lib/python2.7/dist-packages/PySide/QtWebKit.so'>

We are now actually using PySide. Note that it is generally a bad idea to mix both…

Parameters

submodule (str (mandatory)) – submodule name, ex: QtWebKit

Returns

Return type

the loaded submodule

soma.qt_gui.qt_backend.imshow_widget(widget, figure=None, show=False)[source]

Display a shapshot of a QWidget into a Matplotlib figure using pylab.imshow(). This is useful to use the sphinx_gallery module for documentation.

soma.qt_gui.qt_backend.init_matplotlib_backend(force=True)[source]

Initialize Matplotlib to use Qt, and the appropriate Qt/Python binding (PySide or PyQt) according to the configured/loaded toolkit. Moreover, the appropriate FigureCanvas type is set in the current module, and returned by this function.

Parameters

force (bool) – if False, if the backend is already initialized with a different value, then raise an exception. If True (the default), force the new backend in matplotlib. If matplotlib does not support the force parameter, then the backend will not be forced.

soma.qt_gui.qt_backend.init_traitsui_handler()[source]

Setup handler for traits notification in Qt GUI. This function needs to be called before using traits notification which trigger GUI modification from non-principal threads.

WARNING: depending on the Qt bindings (PyQt or PySide), this function may instantiate a QApplication. It seems that when using PyQt4, QApplication is not instantiated, whereas when using PySide, it is. This means that after this function has been called, one must check if the application has been created before recreating it:

app = QtGui.QApplication.instance()
if not app:
    app = QtGui.QApplication(sys.argv)

This behaviour is triggered somewhere in the traitsui.qt4.toolkit module, we cannot change it easily.

soma.qt_gui.qt_backend.loadUi(ui_file, *args, **kwargs)[source]

Load a .ui file and returns the widget instance.

This function is a replacement of PyQt4.uic.loadUi. The only difference is that relative icon or pixmap file names that are stored in the *.ui file are considered to be relative to the directory containing the ui file. With PyQt4.uic.loadUi, relative file names are considered relative to the current working directory therefore if this directory is not the one containing the ui file, icons cannot be loaded.

soma.qt_gui.qt_backend.loadUiType(uifile, from_imports=False)[source]

PyQt4 / PySide abstraction to uic.loadUiType. Not implemented for PySide, actually, because PySide does not have this feature.

soma.qt_gui.qt_backend.qimage_to_np(qimage)[source]

Utility function to transorm a Qt QImage into a numpy array suitable for matplotlib imshow() for instance.

soma.qt_gui.qt_backend.set_qt_backend(backend=None, pyqt_api=1, compatible_qt5=None)[source]

set the Qt backend.

If a different backend has already setup or loaded, a warning is issued. If no backend is specified, try to guess which one is already loaded.

If no backend is loaded yet, try to behave like IPython does. See: https://ipython.org/ipython-doc/dev/interactive/reference.html#pyqt-and-pyside

More precisely this means: * If QT_API environement variable is not set, use PyQt4, with PyQt API v1 * if QT_API is set to “pyqt” or “pyqt4”, use PyQt4, with PyQt API v2 * if QT_API is set to “pyside”, use PySide * if QT_API is set to “pyqt5”, use PyQt5 * if QT_API is set to “pyqt6”, use PyQt6

Moreover if using PyQt4, QtCore is patched to duplicate QtCore.pyqtSignal and QtCore.pyqtSlot as QtCore.Signal and QtCore.Slot. This is meant to ease code portability between both worlds.

if compatible_qt5 is set to True, modules QtGui and QtWidgets will be exposed and completed to contain the same content, with both Qt4 and Qt5.

Parameters
  • backend (str (default: None)) – name of the backend to use

  • pyqt_api (int (default: 1)) – PyQt API version: 1 or 2, only useful for PyQt4

  • compatible_qt5 (bool (default: None)) – expose QtGui and QtWidgets with the same content. If None (default), do not change the current setting. If True, in Qt5, when QtGui or QtWidgets is loaded, the other module (QtWidgets or QtGui) is also loaded, and the QtGui module is modified to contain also the contents of QtWidgets, so as to have more or less the same elements as in Qt4. It is a bit dirty and crappy but allows the same code to work with both versions of Qt. In Qt4, when QtGui is loaded, the module is also registered as QtWidgets, so QtGui and QtWidgets are the same module. Loading QtWidgets will also bring QtGui.

Examples

>>> from soma.qt_gui import qt_backend
>>> qt_backend.set_qt_backend('PySide')
>>> qt_backend.import_qt_submodule('QtCore')
<module 'PySide.QtCore' from '/usr/lib/python2.7/dist-packages/PySide/QtCore.so'>

SubModule: qt_gui.qtThread

This module enables to make a function to be executed in qt thread (main thread). It is useful when you want to call qt functions from another thread. It enables to do thread safe calls because all tasks sent are executed in the same thread (qt main thread).

  • author: Dominique Geffroy

  • organization: NeuroSpin

  • license: CeCILL B

class soma.qt_gui.qtThread.FakeQtThreadCall[source]

Fake QtThreadCall that behave as if always used from main thread.

class soma.qt_gui.qtThread.MainThreadLife(obj_life=None, *args, **kwargs)[source]

This wrapper class ensures the contained object is deleted in the main thread, and not in the current non-GUI thread. The principle is the following:

  • acquire a lock

  • pass the object to something in the main thread

  • the main thread waits on the lock while holding a reference on the object

  • we delete the object in the calling thread

  • the lock is releasd from the calling thread

  • now the main thread can go on, and del / release the ref on the object: it is the last ref on it, so it is actually deleted there.

Warning

The thing is only working if no other reference is held anywhere on the underlying object, otherwise we do not control its deletion.

Ex:

# from a secondary thread

widget = QtThreadCall().call(Qt.QWidget)
# widget.show() # should crash
QtThreadCall().push(widget.show)
# ... use it ...
# del widget # should crash
# from a secondary thread

widget = MainThreadLife(QtThreadCall().call(Qt.QWidget))
QtThreadCall().push(widget.ref().show)
# ... use it ...
del widget # OK
ref()[source]

Access the underlying object

class soma.qt_gui.qtThread.QtThreadCall(*args, **kwargs)[source]

This object enables to send tasks to be executed by qt thread (main thread). This object must be initialized in qt thread. It starts a QTimer and periodically execute tasks in its actions list.

lock

lock to prevent concurrent access to actions list

Type

RLock

actions

tasks to execute

Type

list

mainThread

current thread at object initialisation

Type

Thread

timer

timer to wake this object periodically

Type

QTimer

The __init__ method of Singleton derived class should do nothing. Derived classes must define __singleton_init__() instead of __init__.

call(function, *args, **kwargs)[source]

Send the function call to be executed in the qt main thread and wait for the result. The result will be returned to the calling thread.

Warning

If returned objects are thread-depenendent (typically, Qt widgets), they must be destroyed within the thread which created them, namely the main thread. The MainThreadLife object wrapper may be helpful for this.

Parameters

function (function) – the function to call in main thread.

Returns

Return type

function call result

doAction()[source]

This method is called each time the timer timeout. It executes all functions in actions list.

event(self, QEvent) bool[source]
isInMainThread()[source]
Returns

boolean

Return type

True if the current thread is the main thread

push(function, *args, **kwargs)[source]

Add a function call to the actions list. the call is executed immediatly if current thread is main thread. Otherwise it will be executed some time in the main thread (asynchronously to the current thread). The function return value is ignored and will be lost.

Parameters

function (function) – the function to call in main thread.

SubModule: qt_gui.rangeSlider

class soma.qt_gui.rangeSlider.QRangeSlider(parent=None)[source]

The QRangeSlider class implements a horizontal range slider widget.

Inherits QWidget.

Methods

  • __init__ (self, QWidget parent = None)

  • bool drawValues (self)

  • int end (self)

  • (int, int) getRange (self)

  • int max (self)

  • int min (self)

  • int start (self)

  • setBackgroundStyle (self, QString styleSheet)

  • setDrawValues (self, bool draw)

  • setEnd (self, int end)

  • setStart (self, int start)

  • setRange (self, int start, int end)

  • setSpanStyle (self, QString styleSheet)

Signals

  • endValueChanged (int)

  • maxValueChanged (int)

  • minValueChanged (int)

  • startValueChanged (int)

  • rangeChanged (int, int)

Customizing QRangeSlider

You can style the range slider as below:

QRangeSlider * {
    border: 0px;
    padding: 0px;
}
QRangeSlider #Head {
    background: #222;
}
QRangeSlider #Span {
    background: #393;
}
QRangeSlider #Span:active {
    background: #282;
}
QRangeSlider #Tail {
    background: #222;
}

Styling the range slider handles follows QSplitter options:

QRangeSlider > QSplitter::handle {
    background: #393;
}
QRangeSlider > QSplitter::handle:vertical {
    height: 4px;
}
QRangeSlider > QSplitter::handle:pressed {
    background: #ca5;
}

Create a new QRangeSlider instance.

Parameters

parent – QWidget parent

Returns

New QRangeSlider instance.

drawValues()[source]
Returns

True if slider values will be drawn

end()[source]
Returns

range slider end value

getRange()[source]
Returns

the start and end values as a tuple

keyPressEvent(event)[source]

overrides key press event to move range left and right

max()[source]
Returns

maximum value

min()[source]
Returns

minimum value

setBackgroundStyle(style)[source]

sets background style

setDrawValues(draw)[source]

sets draw values boolean to draw slider values

setEnd(value)[source]

set the range slider end value

setMax(value)[source]

sets maximum value

setMin(value)[source]

sets minimum value

setRange(start, end)[source]

set the start and end values

setSpanStyle(style)[source]

sets range span handle style

setStart(value)[source]

sets the range slider start value

start()[source]
Returns

range slider start value

SubModule: qt_gui.timered_widgets

QLineEditModificationTimer and TimeredQLineEdit classes associate a QtCore.QTimer to a QtGui.QLineEdit in order to signal user modification only after an inactivity period.

  • author: Yann Cointepas

  • organization: NeuroSpin

  • license: CeCILL B

class soma.qt_gui.timered_widgets.QLineEditModificationTimer(qLineEdit, timerInterval=None)[source]

A QLineEditModificationTimer instance is accociated to a QtGui.QLineEdit instance, it listens all user modification (Qt signal ‘textChanged( const QString & )’) and emits a signal ‘userModification()’ when timerInterval milliseconds passed since the last user modification.

See also

TimeredQLineEdit

Parameters
  • qLineEdit ((QtGui.QLineEdit instance)) – widget associated with this QLineEditModificationTimer.

  • timerInterval ((milliseconds)) – minimum inactivity period before emitting userModification signal. Default value is QLineEditModificationTimer.defaultTimerInterval

isActive()[source]

Returns True if the timer is active, or False otherwise.

startInternalModification()[source]

Restart emitting C{userModification} signal when associated QLineEdit is modified.

stop()[source]

Stop the timer if it is active.

stopInternalModification()[source]

Stop emitting userModification signal when associated QLineEdit is modified.

class soma.qt_gui.timered_widgets.TimeredQLineEdit(*args, **kwargs)[source]

Create a QLineEdit instance that has an private attribute containing a QLineEditModificationTimer associated to self. Whenever the internal QLineEditModificationTimer emits a userModification signal, this signal is also emited by the TimeredQLineEdit instance.

All non keyword parameters of the constructor are passed to QLineEdit constructor. An optional timerInterval keyword parameter can be given, it is passed to QLineEditModificationTimer constructor. At the time this class was created, QLineEdit constructor did not accept keyword parameters.

close(self) bool[source]
startInternalModification()[source]
stopInternalModification()[source]

SubModule: safemkdir

soma.safemkdir.makedirs(dirname, mode=511)[source]

Same as os.makedirs, but try to prevent errors occurring from concurrent creation by several threads/processes.

soma.safemkdir.mkdir(dirname, mode=511)[source]

Same as os.mkdir, but try to prevent errors occurring from concurrent creation by several threads/processes.

SubModule: serialization

class soma.serialization.JSONSerializable[source]

Instances of classes deriving from JSONSerializable can be serialized in a JSON compatible object with to_json() method. This JSON object contains a reference to a factory as well as the full state of the instance. Calling the factory with the state of the instance makes it possible to recreate the instance (this is what function from_json() is doing). A typical usage of this serialization system is to store the JSON serialization of an instance in a configuration file (or database) and latter (possibly in another Python instance) recreate the same instance. This is an alternative to pickle allowing to use a standard representation format (JSON) and to have full control on instances creation.

to_json()[source]

Return a JSON serialization of self. The returned object can be given to from_json() to create another instance that is eqivalent to self. Here, equivalent means that all attributes values are the same and the methods called with the same parameters give the same results.

See from_json() to have insight of what is a JSON serialization object.

soma.serialization.find_factory(reference)[source]

Finds a factory callable given its reference. The reference is simply a string containing a module name and the name of fatory in that module separated by a dot. For instance 'my_packages.my_module.my_factory' would refer to the item my_factory in the module my_packages.my_module. This funcion simply loads the module and returns the module attribute with the factory name.

exceptions.ValueError is raised if the factory cannot be found.

soma.serialization.from_json(json_serialization)[source]

Takes a JSON serialization object (typically created by a JSONSerializable.to_json() method) and create and return the corresponding instance.

A JSON serialization object can have one of the following structures: - A simple string containing a factory reference - A list with one, two or three of the following items:

  • factory: a mandatory item containing a reference to a factory (see find_factory())

  • args: an optional item containing a list of parameters values for the factory

  • kwargs: an optional item containing a dictionary of parameters for the factory

A reference to a factory identifies a callable (e.g a function or a class) in a Python module. It is a string containing the module name and the callable name separated by a dot. For instance 'catidb.data_models.catidb_3_4' would identify the catidb_3_4 callable in the catidb.data_models module.

soma.serialization.to_json(object)[source]

Return a JSON serialization of an object. Standard types (None, bool, int, float, str, etc.) are using json.dumps whereas other type of object must define a to_json method returning the serialization.

SubModule: singleton

Singleton pattern.

  • author: Yann Cointepas

  • organization: NeuroSpin

  • license: CeCILL B

class soma.singleton.Singleton(*args, **kwargs)[source]

Implements the singleton pattern. A class deriving from Singleton can have only one instance. The first instanciation will create an object and other instanciations return the same object. Note that the __init__() method (if any) is still called at each instanciation (on the same object). Therefore, Singleton derived classes should define __singleton_init__() instead of __init__() because the former is only called once.

Example:

from singleton import Singleton

class MyClass( Singleton ):
  def __singleton_init__( self ):
    self.attribute = 'value'

o1 = MyClass()
o2 = MyClass()
print(o1 is o2)

The __init__ method of Singleton derived class should do nothing. Derived classes must define __singleton_init__() instead of __init__.

SubModule: somatime

Utility classes and functions for time handling.

soma.somatime.timeDifferenceToString(difference)[source]

SubModule: sorted_dictionary

Sorted dictionary behave like a dictionary but keep the item insertion order.

In addition OrderedDict is provided here, either as the standard collections.OrderedDict class if python version >= 2.7, or based on SortedDictionary if python version < 2.7.

class soma.sorted_dictionary.SortedDictionary(*args)[source]

Sorted dictionary behave like a dictionary but keep the item insertion order. In addition to python 2.7 OrderedDict, SortedDictionary also has an insert() method allowing insersion at a specified index position.

Example:

from SortedDictionary import SortedDictionary
sd = SortedDictionary(('fisrt', 1), ('second', 2))
sd['third'] = 3
sd.insert(0, 'zero', 0)
sd.items() == [('zero', 0), ('fisrt', 1), ('second', 2), ('third', 3)]

Initialize the dictionary with a list of (key, value) pairs.

clear()[source]

Remove all items from dictionary

compValues(key1, key2)[source]

Use this comparaison function in sort method parameter in order to sort the dictionary by values. if data[key1]<data[key2] return -1 if data[key1]>data[key2] return 1 if data[key1]==data[key2] return 0

copy() a shallow copy of D[source]
index(key)[source]

Returns the index of the key in the sorted dictionary, or -1 if this key isn’t in the dictionary.

insert(index, key, value)[source]

insert a (key, value) pair in sorted dictionary before position index. If key is already in the dictionary, a KeyError is raised.

Parameters
  • index (integer) – index of key in the sorted keys

  • key (key to insert) – value associated to key

items()[source]
Returns

sorted list of (key, value) pairs

Return type

list

iteritems()[source]

returns an iterator over the sorted (key, value) pairs

iterkeys()[source]

returns an iterator over the sorted keys

itervalues()[source]

returns an iterator over the sorted values

keys()[source]
Returns

sorted list of keys

Return type

list

pop(k[, d]) v, remove specified key and return the corresponding value.[source]

If the key is not found, return the default if given; otherwise, raise a KeyError.

popitem()[source]

Remove and return a (key, value) pair as a 2-tuple.

Pairs are returned in LIFO (last-in, first-out) order. Raises KeyError if the dict is empty.

setdefault(key, value=None)[source]

Insert key with a value of default if key is not in the dictionary.

Return the value for key if key is in the dictionary, else default.

sort(key=None, reverse=False)[source]

Sorts the dictionary using key function key.

Parameters

key (function key) –

update([E, ]**F) None.  Update D from dict/iterable E and F.[source]

If E is present and has a .keys() method, then does: for k in E: D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]

values()[source]
Returns

values – sorted list of values

Return type

list

SubModule: sqlite_tools

This module contains functions and classes related to sqlite databases.

  • author: Yann Cointepas

  • organization: NeuroSpin

  • license: CeCILL B

class soma.sqlite_tools.ThreadSafeSQLiteConnection(*args, **kwargs)[source]

Python wrapping of SQLite do not allow sharing of database connection between threads. This class allows to automatically create a connection for each thread.

A ThreadSafeSQLiteConnection is created with the parameters that would be used for a call to sqlite3.connect() in a single thread system. These parameters are stored to allow to create a separate SQLite connection for any thread with get_connection().

close()[source]

After this call no more connection can be opened

closeSqliteConnections()

Mark the opened connection for all the threads as closed. Subsequent calls to get_connection() will have to recreate the sqlite connection with sqlite3.connect(). This method does not delete the connection of the current thread.

close_connections()[source]

Mark the opened connection for all the threads as closed. Subsequent calls to get_connection() will have to recreate the sqlite connection with sqlite3.connect(). This method does not delete the connection of the current thread.

currentThreadCleanup()

Delete the connection previously created for the current thread with get_connection()

delete_connection()[source]

Delete the connection previously created for the current thread with get_connection()

get_connection()[source]

Returns a SQLite connection (i.e. the result of sqlite3.connect) for the current thread. If it does not already exists, it is created and stored for the current thread. In order to destroy this connection it is necessary to call self.delete_connection() from the current thread. If a ThreadSafeSQLiteConnection is destroyed in a thread, all connections opened in other threads must have been deleted.

SubModule: stringtools

This module contains text related functions.

  • author: Yann Cointepas

  • organization: NeuroSpin

  • license: CeCILL B

soma.stringtools.list_to_string(l)[source]
soma.stringtools.quote_string(unquoted)[source]
soma.stringtools.string_to_list(s)[source]
soma.stringtools.unquote_string(quoted)[source]

SubModule: thread_calls

This module is useful whenever you need to be sure that a function (more exactly anything that can be called by python) is executed in a particular thread.

For exemple, if you use PyMat (which is an interface between Python and a Matlab, see U{http://claymore.engineer.gvsu.edu/~steriana/Python} for more information) it is necessary that all calls to pymat.eval are done by the same thread that called pymat.open. If you want to use PyMat in a multi-threaded application, you will have to build appropriate calling mechanism as the one proposed in this module.

The main idea is to use a list containing functions to be called with their parameters. A single thread is used to get entries from the list and execute the corresponding functions. Any thread can put a call request on the list either asynchonously (the requesting thread continues to run without waiting for the call to be done) or synchronously (the requesting thread is stopped until the call is done and the result available).

  • author: Yann Cointepas

  • organization: NeuroSpin

  • license: CeCILL B

class soma.thread_calls.SingleThreadCalls(thread=None)[source]

Allows the registration of functions that are going to be called from a single thread. This single thread must continuously call processFunctions().

Registration can be blocking (see call()) or non blocking (see push()).

Blocking registration waits for the function to be processed and returns its result (or raises its exception). Non blocking registration puts the function in the list and returns immediately, ignoring any return value or exception.

Example:

stc = SingleThreadCall()
processingThread = threading.Thread(target=stc.processingLoop)
stc.setProcessingThread(processingThread)
processingThread.start()

The thread passed in parameter is the processing thread of this SingleThreadCalls. When started (which is not been done by SingleThreadCall) it must continuously call processFunctions() to execute the functions that have been registered with call() and push().

Parameters

thread (threading.Thread instance or None) – Processing thread. If None, threading.current_thread() is used.

call(function, *args, **kwargs)[source]

Registers a function call and waits for the processing thread to call it.

Returns the result of the function. If an exception is raised during the execution of the function, this exception is also raised by call(). Therefore call() behaves like a direct call to the function.

It is possible to use call() from the processing thread. In this case, no registration is done (the function is executed immedialey).

Parameters
  • function (callable) – function to execute

  • args – parameters of the function

  • kwargs – keyword parameters of the function

Returns

the result of the function call

Return type

any type

processFunctions(blocking=False)[source]

This method extracts all functions (along with their parameters) from the queue and execute them. It returns the number of function executed None if self.stop() has been called (in that case the processing loop must end).

The processing thread must continuoulsy call this method until None is returned.

See also

processingLoop()

Parameters

blocking (bool) – if blocking is False (the default), processFunctions

Returns

  • Returns 0 immediately if it cannot access the function list (for example if it is locked by another thread that is registering a function).

  • If blocking is True, processFunctions waits until the function list is available, and returns the number of function called

  • If stop() has been called, None is returned

Return type

int

processingLoop()[source]

Continuously executes processFunctions() until it returns None

push(function, *args, **kwargs)[source]

Same as the call() method but always puts the function on the queue and returns immediatly. If push() is called from the processing thread, the function is called immediately (i.e. synchronously).

Parameters
  • function (callable) – function to execute

  • args – parameters of the function

  • kwargs – keyword parameters of the function

Returns

push() does not return anything.

Return type

None

setProcessingThread(thread)[source]

Defines the thread that processes the functions. The behaviour of call() and push() is different if called from the processing thread or from another one.

Parameters

thread (threading.Thread) – Processing thread

stop()[source]

Tells the processing thread to finish the processing of functions in the queue and then stop all processing. This call pushes a special value on the function list. All functions that are on the list before this value will be processed but functions registered after the special value will be ignored.

SubModule: translation

Importing this module defines a translate() function that translates messages of an application. The current implementation does nothing but defines a minimum API.

Example:

from soma.translation import translate as _
try:
    f = open(configurationFileName)
except OSError:
    raise RuntimeError(_('Cannot open configuration file "%s"')
                      % (configurationFileName, ))
  • author: Yann Cointepas

  • organization: NeuroSpin

  • license: CeCILL B

soma.translation.translate(message)[source]

Translate message into the current application language. The current implementation does nothing, message is returned untouched.

Parameters

message (unicode) – message to translate

SubModule: undefined

Undefined (or undefined) is a constant that can be used as a special value different from any other Python value including None.

If the traits library is available, we just use its Undefined implementation.

Example:

from soma.undefined import undefined

if object.value is undefined:
    # do something
  • author: Yann Cointepas

  • organization: NeuroSpin

  • license: CeCILL B

SubModule: utils

SubModule: utils.find_library

replacement for ctypes.util.find_library(). Provides a better version of find_library(), and allows to patch the ctypes module to use our version: see patch_ctypes_find_library().

soma.utils.find_library.find_library(name)[source]

ctypes.util.find_library() is broken on linux at least: it relies on ldconfig, which only searches system paths, not user paths nor LD_LIBRARY_PATH, or alternatively uses gcc, which is not always installed nor configured.

Here we are looking in [[DY]LD_LIBRARY_]PATH (depending on the system)

soma.utils.find_library.patch_ctypes_find_library()[source]

replace ctypes.util.find_library() by our version

SubModule: utils.functiontools

Utility classes and functions for Python callable.

class soma.utils.functiontools.SomaPartial(function, *args, **kwargs)[source]

This is a reimplementation of functools.partial(), which adds compatibility with the traits module.

See the documentation of functools.partial() for details: https://docs.python.org/library/functools.html#functools.partial

Example:

from soma.functiontools import partial

def f(a, b, c):
    return (a, b, c)

g = partial(f, 'a', c='c')
g('b') # calls f('a', 'b', c='c')
property func_code

This property make SomaPartial useable with traits module. The method on_trait_change is requiring that the function has a func_code.co_argcount attribute.

soma.utils.functiontools.checkParameterCount(callable, paramCount)[source]

Checks that a callable can be called with paramCount arguments. If not, a RuntimeError is raised.

Parameters
  • callable (callable) – function, method, class or instance to inspect

  • paramCount (int) – number of parameters

soma.utils.functiontools.drange(start, stop, step=1)[source]

Creates lists containing arithmetic progressions of any number type (int, float, …)

soma.utils.functiontools.getArgumentsSpecification(callable)[source]

This is an extension of Python module inspect.getfullargspec that accepts classes and returns only information about the parameters that can be used in a call to callable (e.g. the first self parameter of bound methods is ignored). If callable has not an appropriate type, a TypeError exception is raised.

Parameters

callable (callable) – function, method, class or instance to inspect

Returns

As inspect.getfullargspec(), returns (args, varargs, varkw, defaults) where args is a list of the argument names (it may contain nested lists). varargs and varkw are the names of the * and ** arguments or None. defaults is a n-tuple of the default values of the last n arguments.

Return type

tuple

soma.utils.functiontools.getCallableString(callable)[source]

Returns a translated human readable string representing a callable.

Parameters

callable (callable) – function, method, class or instance to inspect

Returns

type and name of the callable

Return type

string

soma.utils.functiontools.hasParameter(callable, parameterName)[source]

Returns True if callable can be called with a parameter named parameterName. Otherwise, returns False.

Parameters
  • callable (callable) – function, method, class or instance to inspect

  • parameterName (string) – name of the parameter

Returns

Return type

bool

soma.utils.functiontools.numberOfParameterRange(callable)[source]

Returns the minimum and maximum number of parameter that can be used to call a function. If the maximum number of argument is not defined, it is set to None.

Parameters

callable (callable) – function, method, class or instance to inspect

Returns

two elements (minimum, maximum)

Return type

tuple

SubModule: utils.loader

soma.utils.loader.cleanup(attribute)[source]

cleanup avoiding:

  • Windows reserved characters

  • ‘_’ since it is reserved by Brainvisa

  • tab, newline and null character

soma.utils.loader.insert_tool(tools, tool, allowed_instances)[source]

Add tool to list if tool is sub class of one item in allowed_instances

soma.utils.loader.load_objects(module_name, object_name=None, allowed_instances=None)[source]

Load a python object

The object is described by a string module_name and object_name. If object_name is None import the full module content. Can also filtered objects and only keep objects of types defined in allowed_instances.

Parameters
  • module (str) – module name

  • tool (str) – tool name

  • allowed_instances (list) – list of instance to load

Returns

tools – a list of objects.

Return type

list

SubModule: utils.weak_proxy

Utility functions to make a weak proxy which also keeps an access to its original object reference. weakref.proxy() doesn’t allow this, but functions that check types (C+/Python bindings for instance) cannot work with proxies.

We build such a proxy by setting a weakref.ref() object in the proxy (actually in the object itself).

soma.utils.weak_proxy.get_ref(obj)[source]

Get a regular reference to an object, whether it is already a regular reference, a weak reference, or a weak proxy which holds an access to the original reference (built using weak_proxy()). In case of a weak proxy not built using weak_proxy(), we try to get the self from a bound method of the object, namely obj.__init__.__self__, if it exists.

class soma.utils.weak_proxy.proxy_method(obj, method=None)[source]

Indirect proxy for a bound method

It replaces a bound method, ie a.method with a proxy callable which does not take a reference on a.

Especially useful for callbacks. If we want to set a notifier with a callback on a proxy object (without adding a new reference on it), we can use proxy_method:

a = anatomist.Anatomist()
a.onCursorNotifier.onAddFirstListener.add(
    partial(proxy_method(a, 'enableListening'),
    "LinkedCursor", a.onCursorNotifier)))
del a

Without this mechanism, using:

a.onCursorNotifier.onAddFirstListener.add(
    partial(a.enableListening, "LinkedCursor", a.onCursorNotifier)))

would increment the reference count on a, because a.enableListening, as a bound method, contains a reference to a, and will prevent the deletion of a (here the Anatomist application)

The constructor takes as parameters, either the object and its method name (as a string), or the bound method itself.

soma.utils.weak_proxy.weak_proxy(obj, callback=None)[source]

Build a weak proxy (weakref.ProxyType) from an object, if it is not already one, and keep a reference to the original object (via a weakref.ReferenceType) in it.

callback is passed to weakref.proxy().

SubModule: uuid

Universal unique identifier.

  • author: Yann Cointepas

  • organization: NeuroSpin

  • license: CeCILL B

class soma.uuid.Uuid(value=None)[source]

An Uuid instance is a universal unique identifier. It is a 128 bits random value.

Uuid constructor. If uuid is ommited or None, a new random Uuid is created; if it is a string if must be 36 characters long and follow the pattern:

XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX

where X is an hexadecimal digit (example: 'ad2d8fb0-7831-50bc-2fb6-5df048304001').

If uuid is an Uuid instance, no new instance is created, in this case, Uuid(uuid) returns uuid.