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 axception 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: argparse

Command-line parsing library

This module is an optparse-inspired command-line parsing library that:

  • handles both optional and positional arguments
  • produces highly informative usage messages
  • supports parsers that dispatch to sub-parsers

The following is a simple usage example that sums integers from the command-line and writes the result to a file:

parser = argparse.ArgumentParser(
    description='sum the integers at the command line')
parser.add_argument(
    'integers', metavar='int', nargs='+', type=int,
    help='an integer to be summed')
parser.add_argument(
    '--log', default=sys.stdout, type=argparse.FileType('w'),
    help='the file where the sum should be written')
args = parser.parse_args()
args.log.write('%s' % sum(args.integers))
args.log.close()

The module contains the following public classes:

  • ArgumentParser – The main entry point for command-line parsing. As the
    example above shows, the add_argument() method is used to populate the parser with actions for optional and positional arguments. Then the parse_args() method is invoked to convert the args at the command-line into an object with attributes.
  • ArgumentError – The exception raised by ArgumentParser objects when
    there are errors with the parser’s actions. Errors raised while parsing the command-line are caught by ArgumentParser and emitted as command-line messages.
  • FileType – A factory for defining types of files to be created. As the
    example above shows, instances of FileType are typically passed as the type= argument of add_argument() calls.
  • Action – The base class for parser actions. Typically actions are
    selected by passing strings like ‘store_true’ or ‘append_const’ to the action= argument of add_argument(). However, for greater customization of ArgumentParser actions, subclasses of Action may be defined and passed as the action= argument.
  • HelpFormatter, RawDescriptionHelpFormatter, RawTextHelpFormatter,
    ArgumentDefaultsHelpFormatter – Formatter classes which may be passed as the formatter_class= argument to the ArgumentParser constructor. HelpFormatter is the default, RawDescriptionHelpFormatter and RawTextHelpFormatter tell the parser not to change the formatting for help text, and ArgumentDefaultsHelpFormatter adds information about argument defaults to the help.

All other classes in this module are considered implementation details. (Also note that HelpFormatter and RawDescriptionHelpFormatter are only considered public as object names – the API of the formatter objects is still considered an implementation detail.)

Author: Steven J. Bethard <steven.bethard@gmail.com>.

class soma.argparse.ArgumentParser(prog=None, usage=None, description=None, epilog=None, version=None, parents=[], formatter_class=<class 'soma.argparse.HelpFormatter'>, prefix_chars='-', fromfile_prefix_chars=None, argument_default=None, conflict_handler='error', add_help=True)

Object for parsing command line strings into Python objects.

Keyword Arguments:
 
  • prog -- The name of the program (default (-) – sys.argv[0])
  • usage -- A usage message (default (-) – auto-generated from arguments)
  • description -- A description of what the program does (-) –
  • epilog -- Text following the argument descriptions (-) –
  • parents -- Parsers whose arguments should be copied into this one (-) –
  • formatter_class -- HelpFormatter class for printing help messages (-) –
  • prefix_chars -- Characters that prefix optional arguments (-) –
  • fromfile_prefix_chars -- Characters that prefix files containing (-) – additional arguments
  • argument_default -- The default value for all arguments (-) –
  • conflict_handler -- String indicating how to handle conflicts (-) –
  • add_help -- Add a -h/-help option (-) –
error(message: string)

Prints a usage message incorporating the message to stderr and exits.

If you override this in a subclass, it should not return – it should either exit or raise an exception.

exception soma.argparse.ArgumentError(argument, message)

An error from creating or using an argument (optional or positional).

The string value of this exception is the message, augmented with information about the argument that caused it.

exception soma.argparse.ArgumentTypeError

An error from trying to convert a command line string to a type.

class soma.argparse.FileType(mode='r', bufsize=None)

Factory for creating file object types

Instances of FileType are typically passed as type= arguments to the ArgumentParser add_argument() method.

Keyword Arguments:
 
  • mode -- A string indicating how the file is to be opened. Accepts the (-) – same values as the builtin open() function.
  • bufsize -- The file's desired buffer size. Accepts the same values as (-) – the builtin open() function.
class soma.argparse.HelpFormatter(prog, indent_increment=2, max_help_position=24, width=None)

Formatter for generating usage messages and argument help strings.

Only the name of this class is considered a public API. All the methods provided by the class are considered an implementation detail.

class soma.argparse.ArgumentDefaultsHelpFormatter(prog, indent_increment=2, max_help_position=24, width=None)

Help message formatter which adds default values to argument help.

Only the name of this class is considered a public API. All the methods provided by the class are considered an implementation detail.

class soma.argparse.RawDescriptionHelpFormatter(prog, indent_increment=2, max_help_position=24, width=None)

Help message formatter which retains any formatting in descriptions.

Only the name of this class is considered a public API. All the methods provided by the class are considered an implementation detail.

class soma.argparse.RawTextHelpFormatter(prog, indent_increment=2, max_help_position=24, width=None)

Help message formatter which retains formatting of all help text.

Only the name of this class is considered a public API. All the methods provided by the class are considered an implementation detail.

class soma.argparse.Namespace(**kwargs)

Simple object for storing attributes.

Implements equality by attribute names and values, and provides a simple string representation.

class soma.argparse.Action(option_strings, dest, nargs=None, const=None, default=None, type=None, choices=None, required=False, help=None, metavar=None)

Information about how to convert command line strings to Python objects.

Action objects are used by an ArgumentParser to represent the information needed to parse a single argument from one or more strings from the command line. The keyword arguments to the Action constructor are also all attributes of Action instances.

Keyword Arguments:
 
  • option_strings -- A list of command-line option strings which (-) – should be associated with this action.
  • dest -- The name of the attribute to hold the created object (-) –
  • nargs -- The number of command-line arguments that should be (-) –

    consumed. By default, one argument will be consumed and a single value will be produced. Other values include:

    • N (an integer) consumes N arguments (and produces a list)
    • ‘?’ consumes zero or one arguments
    • ‘*’ consumes zero or more arguments (and produces a list)
    • ‘+’ consumes one or more arguments (and produces a list)

    Note that the difference between the default and nargs=1 is that with the default, a single value will be produced, while with nargs=1, a list containing a single value will be produced.

  • const -- The value to be produced if the option is specified and the (-) – option uses an action that takes no values.
  • default -- The value to be produced if the option is not specified. (-) –
  • type -- The type which the command-line arguments should be converted (-) – to, should be one of ‘string’, ‘int’, ‘float’, ‘complex’ or a callable object that accepts a single string argument. If None, ‘string’ is assumed.
  • choices -- A container of values that should be allowed. If not None, (-) – after a command-line argument has been converted to the appropriate type, an exception will be raised if it is not a member of this collection.
  • required -- True if the action must always be specified at the (-) – command line. This is only meaningful for optional command-line arguments.
  • help -- The help string describing the argument. (-) –
  • metavar -- The name to be used for the option's argument with the (-) – help string. If None, the ‘dest’ value will be used as the name.

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

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`

Event – 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.

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_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
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.
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.
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
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

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=<open file '<stdout>', mode 'w'>, 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

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

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

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.

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 in the message by their correponding html entity.

  • returns: unicode
soma.html.lesserHtmlEscape(msg)[source]

Replace special characters in the message by their correponding html entity.

  • 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 getMatchingObject(object, listName, level=0)[source]

This static method is used to get an object contained in another object.

Parameters:
  • object (module) – object to get objects from.
  • listName (list) – complete name including name hierarchy split in list.
Returns:

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

Return type:

object

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.

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, *args, **kwargs)[source]

Utility finction to allocate worker threads.

Parameters:
  • q (Queue instance) – the jobs queue which will fed with jobs for processing
  • 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.
  • kwargs (args,) – 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, *args, **kwargs)[source]

Internal function: worker thread loop: * pick a job in the queue q * execute it in a remote process (using run_job()) * stopre 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 wel 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

string – default name of the tree

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

unamed

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

visible

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

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
sort(key=None, reverse=False)[source]

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

class EditableTree.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

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

name

string – Text representation of the item

movable

bool – True if the item can be moved in the tree

modifiable

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

delEnabled

bool – True if deletion of the item is allowed

tooltip

string – description associated to the item

copyEnabled

bool – indicates if this item can be copied

visible

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

enabled

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

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 EditableTree.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

EditableTree.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

EditableTree.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.

EditableTree.compItems(id1, id2)[source]

Comparison function

Returns:

  • 1 if i1 > i2
  • -1 if i1 < i2
  • 0 if they are equal
EditableTree.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

EditableTree.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.

EditableTree.removeEmptyBranches()[source]

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

EditableTree.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

int – used to notify insertion of new elements in the list

REMOVE_ACTION

int – used to notify elements deletion

MODIFY_ACTION

int – used to notify elements modification

onChangeNotifier

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

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

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

onRemoveLastListener

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

Parameters:parameterCount (int) – if not None, each registered function must be callable with that number of arguments (checking is done on registration).
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

int – used to notify insertion of new elements in the dictionary

REMOVE_ACTION

int – used to notify elements deletion

MODIFY_ACTION

int – used to notify elements modification

onChangeNotifier

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

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('libpython2.7.so', 'LD_LIBRARY_PATH') could return '/usr/local/lib/libpython2.7.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.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'
soma.path.which(program)[source]

Identifies the location of an executable.

OBSOLETE the same can be done using find_in_path(), this function will be removed in the next version of soma-base.

Parameters:program (string) – The executable to find
Returns:
Return type:The full path of the executable

SubModule: pyro

This module provides the class ThreadSafeProxy.

  • author: Yann Cointepas
  • organization: NeuroSpin
  • license: CeCILL B
class soma.pyro.ThreadSafeProxy(proxy)[source]

This class makes it possible to share Pyro 3 proxy across multiple threads. A single Pyro thread is created. This thread will be the only one to use Pyro proxy objects. A L{ThreadSafeProxy} is a proxy on a Pyro proxy that will send all activity (methods calls and attributes getting and setting) to the Pyro thread.

Example

import Pyro.core
from soma.pyro import ThreadSafeProxy

threadSafeProxy = ThreadSafeProxy(Pyro.core.getProxyFromURI('PYRO://127.0.0.1:7766/84a68da2260374b1b334d9591c4fd84f'))
static pyroThreadCall(*args, **kwargs)[source]

Calls a function from the Pyro thread.

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)[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.
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

classmethod 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:
  • cls (ControllerWidget (mandatory)) – a ControllerWidget class
  • 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
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)[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.

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

string – socket server machine

port

int – port that the socket server listens

socket

socket.socket – python socket object

socketnotifier

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

readLock

threading.Lock – lock to prevent threads from reading at the same time on the socket

writeLock

threading.Lock – lock to prevent threads from writing at the same time on the socket

lock

threading.RLock – 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.

initialized

bool – indicates if the connection is correctly opened

notifyenabled

bool – indicates if message received on the socket must be processed.

loopRetry

int – class attribute: max number of connection tries

defaultPort

int – class attribute: default port for socket server

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.init_matplotlib_backend()[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.

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.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

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

RLock – lock to prevent concurrent access to actions list

actions

list – tasks to execute

mainThread

Thread – current thread at object initialisation

timer

QTimer – timer to wake this object periodically

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.

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.

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

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
sort(key=None, reverse=False)[source]

Sorts the dictionary using key function key.

Parameters:key (function key) –
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.currentThread() 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]

Python 2.5 introduced a very useful function: functools.partial(), this is an implementation that is compatible with Python 2.3 (if functools.partial exists, it is used directly).

functools.partial allow to create a new function from an existing function by setting values to some arguments. The new function will be callable with less parameters. See Python 2.5 documentation for more information.

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')
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.getargspec 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.getargspec(), 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())

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(uuid=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.