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__.
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.
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 openedfile_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}.
- static open(*args, **kwargs)[source]¶
Open a file with built-in
open()
and create aBufferAndFile
instance.
SubModule: config
¶
Config module that sets up version variable and finds the BrainVISA brainvisa-share data directory.
- soma.config.fullVersion¶
- soma.config.shortVersion¶
- soma.config.full_version¶
- soma.config.short_version¶
- soma.config.BRAINVISA_SHARE¶
SubModule: controller
: Traits-based controller objects¶
Classes¶
API¶
- class soma.controller.controller.Controller(*args, **kwargs)[source]¶
A Controller contains some traits: attributes typing and observer (callback) pattern.
The class provides some methods to add/remove/inspect user defined traits.
- `user_traits_changed`
single event that can be sent when several traits changes. This event has to be triggered explicitely to take into account changes due to call(s) to add_trait or remove_trait.
- Type:
Event
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.
- 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:
- protect_parameter(param, state=True)[source]¶
Protect the named parameter.
Protecting is not a real lock, it just marks the parameter a list of “protected” parameters. This is typically used to mark values that have been set manually by the user (using the ControllerWidget for instance) and that should not be later modified by automatic parameters tweaking (such as completion systems).
Protected parameters are listed in an additional trait, “protected_parameters”.
If the “state” parameter is False, then we will unprotect it (calling unprotect_parameter())
- remove_trait(name)[source]¶
Remove a trait from its name.
- Parameters:
name (str (mandatory)) – the trait name to remove.
- reorder_traits(traits_list)[source]¶
Reorder traits in the controller according to a new ordered list.
If the new list does not contain all user traits, the remaining ones will be appended at the end.
- Parameters:
traits_list (list) – New list of trait names. This list order will be kept.
- 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:
- class soma.controller.controller.ControllerTrait(controller, inner_trait=None, **kwargs)[source]¶
A specialized trait type for Controller values.
Build a Controller valued trait.
Contrarily to Instance(Controller), it ensures better validation when assigning values.
It has the ability to convert values from dictionaries, so the trait value can be assigned with a dict, whereas it is actually a Controller. This works recursively if the controller contains traits which are also controllers.
- Parameters:
controller (Controller instance (mandatory)) – default value for trait, and placeholder for allowed traits
inner_trait (Trait instance (optional)) – if provided, the controller is assumed to be an “open key” type, new keys/traits can be added on the fly like in a dictionary, and this inner_trait is the trait type used to instantiate new traits when new keys are encountered while setting values. If inner_trait is not provided, we will look if the controller instance is an OpenKeyController, and in such case, take its value trait.
- inner_traits()[source]¶
Returns a tuple containing the inner traits for this trait. Most trait handlers do not have any inner traits, and so will return an empty tuple. The exceptions are List and Dict trait types, which have inner traits used to validate the values assigned to the trait. For example, in List( Int ), the inner traits for List are ( Int, ).
- class soma.controller.controller.JsonControllerDecoder(*args, **kwargs)[source]¶
object_hook
, if specified, will be called with the result of every JSON object decoded and its return value will be used in place of the givendict
. This can be used to provide custom deserializations (e.g. to support JSON-RPC class hinting).object_pairs_hook
, if specified will be called with the result of every JSON object decoded with an ordered list of pairs. The return value ofobject_pairs_hook
will be used instead of thedict
. This feature can be used to implement custom decoders. Ifobject_hook
is also defined, theobject_pairs_hook
takes priority.parse_float
, if specified, will be called with the string of every JSON float to be decoded. By default this is equivalent to float(num_str). This can be used to use another datatype or parser for JSON floats (e.g. decimal.Decimal).parse_int
, if specified, will be called with the string of every JSON int to be decoded. By default this is equivalent to int(num_str). This can be used to use another datatype or parser for JSON integers (e.g. float).parse_constant
, if specified, will be called with one of the following strings: -Infinity, Infinity, NaN. This can be used to raise an exception if invalid JSON numbers are encountered.If
strict
is false (true is the default), then control characters will be allowed inside strings. Control characters in this context are those with character codes in the 0-31 range, including'\t'
(tab),'\n'
,'\r'
and'\0'
.
- class soma.controller.controller.JsonControllerEncoder(*, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)[source]¶
Constructor for JSONEncoder, with sensible defaults.
If skipkeys is false, then it is a TypeError to attempt encoding of keys that are not str, int, float or None. If skipkeys is True, such items are simply skipped.
If ensure_ascii is true, the output is guaranteed to be str objects with all incoming non-ASCII characters escaped. If ensure_ascii is false, the output can contain non-ASCII characters.
If check_circular is true, then lists, dicts, and custom encoded objects will be checked for circular references during encoding to prevent an infinite recursion (which would cause an RecursionError). Otherwise, no such check takes place.
If allow_nan is true, then NaN, Infinity, and -Infinity will be encoded as such. This behavior is not JSON specification compliant, but is consistent with most JavaScript based encoders and decoders. Otherwise, it will be a ValueError to encode such floats.
If sort_keys is true, then the output of dictionaries will be sorted by key; this is useful for regression tests to ensure that JSON serializations can be compared on a day-to-day basis.
If indent is a non-negative integer, then JSON array elements and object members will be pretty-printed with that indent level. An indent level of 0 will only insert newlines. None is the most compact representation.
If specified, separators should be an (item_separator, key_separator) tuple. The default is (’, ‘, ‘: ‘) if indent is
None
and (‘,’, ‘: ‘) otherwise. To get the most compact JSON representation, you should specify (‘,’, ‘:’) to eliminate whitespace.If specified, default is a function that gets called for objects that can’t otherwise be serialized. It should return a JSON encodable version of the object or raise a
TypeError
.- default(obj)[source]¶
Implement this method in a subclass such that it returns a serializable object for
o
, or calls the base implementation (to raise aTypeError
).For example, to support arbitrary iterators, you could implement default like this:
def default(self, o): try: iterable = iter(o) except TypeError: pass else: return list(iterable) # Let the base class default method raise the TypeError return JSONEncoder.default(self, o)
- class soma.controller.controller.OpenKeyController(value_trait=<traits.trait_types.Any object>, *args, **kwargs)[source]¶
A dictionary-like controller, with “open keys”: items may be added on the fly, traits are created upon assignation.
A value trait type should be specified to build the items.
Usage:
>>> dict_controller = OpenKeyController(value_trait=traits.Str()) >>> print(dict_controller.user_traits().keys()) [] >>> dict_controller.my_item = 'bubulle' >>> print(dict_controller.user_traits().keys()) ['my_item'] >>> print(dict_controller.export_to_dict()) {'my_item': 'bubulle'} >>> del dict_controller.my_item >>> print(dict_controller.export_to_dict()) {}
Build an OpenKeyController controller.
- Parameters:
value_trait (Trait instance (optional, default: Any())) – trait type to be used when creating traits on the fly
- soma.controller.controller.controller_to_dict(item, exclude_undefined=False, exclude_transient=False, exclude_none=False, exclude_empty=False, dict_class=<class 'collections.OrderedDict'>)[source]¶
Convert an item to a Python value where controllers had been converted to dictionary. It can recursively convert the values contained in a Controller instances or a dict instances. All other items are returned untouched.
- Parameters:
exclude_undefined (bool (optional)) – if set, do not export Undefined values
exclude_transient (bool (optional)) – if set, do not export values whose trait is marked “transcient”
exclude_none (bool (optional)) – if set, do not export None values
exclude_empty (bool (optional)) – if set, do not export empty lists/dicts values
dict_class (class type (optional, default: soma.sorted_dictionary.OrderedDict)) – use this type of mapping type to represent controllers. It should follow the mapping protocol API.
SubModule: crypt
¶
Functions to manage private/public keys encryption. This module needs Crypto module.
- soma.crypt.decrypt_RSA(private_key_loc, package)[source]¶
param: public_key_loc Path to your private key param: package String to be decrypted return decrypted string
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).
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 havingcls.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
SubModule: fom
: File Organization Model¶
File Organization Model (FOM)¶
A FOM is a JSON file (dictionary) describing how to make filenames from a set of attributes.
FOM definition¶
Ex:
{
"fom_name": "morphologist-auto-nonoverlap-1.0",
"fom_import": ["formats-brainvisa-1.0", "brainvisa-formats-3.2.0",
"shared-brainvisa-1.0"],
"attribute_definitions" : {
"acquisition" : {"default_value" : "default_acquisition"},
"analysis" : {"default_value" : "default_analysis"},
"sulci_recognition_session" : {"default_value" : "default_session"},
"graph_version": {"default_value": "3.1"},
},
"shared_patterns": {
"acquisition": "<center>/<subject>/t1mri/<acquisition>",
"analysis": "{acquisition}/<analysis>",
"recognition_analysis": "{analysis}/folds/<graph_version>/<sulci_recognition_session>_auto",
},
"processes" : {
"Morphologist" : {
"t1mri":
[["input:{acquisition}/<subject>", "images"],
"imported_t1mri":
[["output:{acquisition}/<subject>", "images"]],
"t1mri_referential":
[["output:{acquisition}/registration/RawT1-<subject>_<acquisition>", "Referential"]],
"reoriented_t1mri":
[["output:{acquisition}/<subject>", "images"]],
"t1mri_nobias":
[["output:{analysis}/nobias_<subject>", "images" ]],
"split_brain":
[["output:{analysis}/segmentation/voronoi_<subject>","images"]],
"left_graph":
[["output:{analysis}/folds/<graph_version>/<side><subject>",
"Graph and data",
{"side": "L", "labelled": "No"}]],
"left_labelled_graph":
[["output:{recognition_analysis}/<side><subject>_<sulci_recognition_session>_auto",
"Graph and data", {"side": "L"}]],
"right_graph":
[["output:{analysis}/folds/<graph_version>/<side><subject>",
"Graph and data", {"side":"R","labelled":"No"}]],
"right_labelled_graph":
[["output:{recognition_analysis}/<side><subject>_<sulci_recognition_session>_auto",
"Graph and data", {"side": "R"}]],
"Talairach_transform":
[["output:{acquisition}/registration/RawT1-<subject>_<acquisition>_TO_Talairach-ACPC",
"Transformation matrix"]]
}
}
}
The dictionary may contain:
- fom_name: string
identifier of the FOM model. Several FOMs may coexist under different identifiers.
- fom_import: list
dependencies between FOMs. A Fom may import others to benefit from its formats, patterns etc.
- attribute_definitions: dict
a dict of predefines attributes. It is generally used to define default values for some attributes. Each attribute defined here is also a dict. In this sub-dict, the key “default_value” provides the attribute default value.
Attributes don’t need to be defined here, they are automatically defined as they are used in path patterns. But here we can assign them additional information (typically default values).
- shared_patterns: dict
mapping of reusable patterns. Such patterns will be replaced with their contents when used in the file paths patterns. To use such a pattern, place it with brackets {} in file paths patterns:
"input:{acquisition}/<subject>"
here
{aquisition}
is the shared pattern “aquisition”, and<subject>
is the attribute “subject”A pattern definition may also use attributes between
<attribute_name>
quotes, and / or reuse other patterns between{pattern}
curly brackets.- processes: dict
dictionary of processes supported by the FOM, and path definitions for their parameters. The dict is organized by process, then in each process a sub-dict contains its parameters definitions. For a given parameter, a list of the FOM rules is given: several rules are allowed.
Process names keys may be a fully qualified module/class name, or a short identifier, or a “contextual” name: the name a process has in the context of a pipeline.
A FOM rule is a list of 2 or 3 elements:
[patterrn, formats, attributes]
- pattern: string
the FOM pattern for the file path of the given parameter. A pattern starts with a directory identifier (
input
,output
,shared
), followed by a semicolon (:
), and a file pattern which may contain attributes (<attrib>
) and/or shared patterns ({pattern}
). Ex:"input:{acquisition}/<subject>"
- formats: string or list
name of a format, a formats list, or a list of allowed formats names. The formats will rule the possible file extensions.
- attributes: dict, optional
An optional dict assigning locally some attributes values. Ex:
{"side": "left"}
The attributes values here are used both to replace attributes values in the current file path pattern, and to select the matching rule when attributes values are given externally (hm, to be checked actually).
A FOM file is a JSON file (actually a JSON/YAML extended file, to allow comments within it), which should be placed in a common directory where the FOM manager will look for it (share/foms/
)
How to use FOMS¶
At higher level, they are used for instance in CAPSUL.
At lower level, they are used through several classes:
FileOrganizationModelManager
manages a set of FOMs, looks for them in a search path, reads them.FileOrganizationModels
represents a FOM rules set.AttributesToPaths
is used to convert a set of attributes into filenames (which is the main use of FOMs).PathToAttributes
performs the reverse operation: match attributes and determines their values from a given filename.
- class soma.fom.AttributesToPaths(foms, selection=None, directories={}, preferred_formats={}, debug=None)[source]¶
Utility class for attributes set -> file paths transformation. Part of the FOM engine.
- class soma.fom.FileOrganizationModelManager(paths=None)[source]¶
Manage the discovery and instanciation of available FileOrganizationModel (FOM). A FOM can be represented as a YAML/JSON file (or a series of YAML/JSON files in a directory). This class allows to identify these files contained in a predefined set of directories (see find_fom method) and to instanciate a FileOrganizationModel for each identified file (see get_fom method).
Create a FOM manager that will use the given paths to find available FOMs.
- find_foms()[source]¶
Return a list of file organisation model (FOM) names. These FOMs can be loaded with load_foms. FOM files (or directories) are looked for in self.paths.
- fom_files()[source]¶
Return a list of file organisation model (FOM) names, as in
find_foms()
, but does not clear and reload the cache. These FOMs can be loaded with load_foms. FOM files (or directories) are looked for in self.paths.
- class soma.fom.PathToAttributes(foms, selection=None)[source]¶
Utility class for file paths -> attributes set transformation. Part of the FOM engine.
- soma.fom.deep_update(update, original)[source]¶
Recursively update a dict. Subdict’s won’t be overwritten but also updated.
- class soma.fom.json_reader[source]¶
This class has a single static method load that loads an JSON file with two features not provided by all JSON readers:
JSON syntax is extended. For instance comments are allowed.
The order of elements in dictionaries can be preserved by using parameter object_pairs_hook=OrderedDict (as in Python 2.7 JSON reader).
SubModule: global_naming
¶
SubModule: html
¶
Utility functions for HTML format.
author: Yann Cointepas
organization: NeuroSpin
license: CeCILL B
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__.- importInModule(moduleName, globals, locals, importedModuleName, namespacesList=[], handlersList=None, *args, **kwargs)[source]¶
This method is used to import a module applying rules (rename rule, delete rule, …) .
- Parameters:
moduleName (string) – name of the module to import into (destination, not where to find it).
globals (dict) – globals dictionary of the module to import into.
locals (dict) – locals dictionary of the module to import into.
importedModuleName (string) – name of the imported module. Normally relative to the current calling module package.
namespacesList (list) – a list of rules concerned namespaces for the imported module.
handlersList (list) – a list of handlers to apply during the import of the module.
- class soma.importer.ExtendedImporterHelper[source]¶
Static methods declared to help extended import process.
- static getModuleObject(module, name)[source]¶
This static method is used to get an object contained in the namespace of a module.
- Parameters:
name (string) – complete name including namespace of the object to get.
module (module) – module object to get objects from.
- Returns:
Object found in the module or None if no object was found.
- Return type:
- 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 theExtendedModule
.
- 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
¶
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
:
for reading minf files:
iterateMinf()
,readMinf()
for writing minf files:
createMinfWriter()
,writeMinf()
for customizing minf files:
createReducerAndExpander()
,registerClass()
,registerClassAs()
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:
destFile – see
createMinfWriter()
args (sequence or iterator) – series of values to write
format – see
createMinfWriter()
reducer – see
createMinfWriter()
SubModule: mpfork
¶
Run worker functions in separate processes.
The use case is somewhat similar to what can be done using either queue.Queue
and threads, or using multiprocessing
. That is: run a number of independent job functions, dispatched over a number of worker threads/processes.
The mpfork module is useful in cases the above methods cannot work:
threading in python is globally mainly inefficient because of the GIL.
multiprocessing
makes heavy use of pickles to pass objects and parameters, and there are cases we are using objects which cannot be pickled, or which pickling generates heavy IO traffic (large data objects)
The method here is based on the queue / thread schema, but uses fork() to actually execute the workers in a separate process. Only results are passed through pickles, so the worker return results must be picklable, but not the input arguments and objects.
Use:
allocate a
Queue
allocate a results list with the exact size of the jobs number
allocate a set of worker threads (typically one per processor or core). The function
allocate_workers()
can do this for you.fill the queue with jobs, each being a tuple (job_index, function, args, kwargs, results_list)
add a number of empty jobs (None) to the queue, one per allocated worker: this will be the marker for the end of processing in each worker thread. It is necessary to explicitly add these empty jobs since an empty queue is not the signal for the end of processing: it can be re-filled at any time.
jobs run in workers
join the queue
join the worker threads
the result list gets the return data for each job
njobs = 10
q = queue.Queue()
res = [None] * njobs
workers = allocate_workers(q, 0) # one per core
for i in range(njobs):
job = (i, sum, ((i, i), ), {}, res)
q.put(job)
# add as many empty jobs as the workers number to end them
for i in range(len(workers)):
q.put(None)
# wait for every job to complete
q.join()
# terminate all threads
for w in workers:
w.join()
print('result:', res)
In case of error, the job result will be an exception with stack information: (exception type, exception instance, stack_info)
Availability: Unix
- soma.mpfork.allocate_workers(q, nworker=0, thread_only=False, *args, **kwargs)[source]¶
Utility finction to allocate worker threads.
- Parameters:
q (
Queue
instance) – the jobs queue which will be fed with jobs for processingthread_only (bool) – if True, workers will run jobs in the worker thread, not using a separate process. This flag thus allows to choose a threaded or multiprocessing implementation.
nworker (int) – number of worker threads (jobs which will run in parallel). A positive number (1, 2…) will be used as is, 0 means all available CPU cores (see
multiprocessing.cpu_count()
), and a negative number means all CPU cores except this given number.args – additional arguments will be pased to the jobs function(s) after individual jobs arguments: they are args common to all jobs (if any)
kwargs – additional arguments will be pased to the jobs function(s) after individual jobs arguments: they are args common to all jobs (if any)
- Returns:
workers – workers list, each is a
thread
instance running the worker loop function. Threads are already started (ie.- Return type:
- soma.mpfork.run_job(f, *args, **kwargs)[source]¶
Internal function, runs the function in a remote process. Uses fork() to perform it.
Availability: Unix
- soma.mpfork.worker(q, thread_only, *args, **kwargs)[source]¶
Internal function: worker thread loop: * pick a job in the queue q * execute it, either in the current thread, or in a remote process (using
run_job()), depending on the thread_only parameter value
store the result in the result list
start again with another job
The loop ends when a job in the queue is None.
Warning
Here we are making use of fork() (Unix only) inside a thread. Some systems do not behave well in this situation. See
the os.fork() doc
SubModule: notification
¶
This module provides a notification system that can be used to register
callbacks (i.e Python callables) that will all be called by a single
Notifier.notify()
call.
author: Yann Cointepas, Dominique Geffroy
organization: NeuroSpin
license: CeCILL B
- class soma.notification.EditableTree(name=None, id=None, modifiable=True, content=[], visible=True, enabled=True)[source]¶
The base class to model a tree of items. This class can be derived to change implementation.
An EditableTree contains items which can be
an item branch: it contains other items as children
an item leaf: doesn’t have children
The list of items is an
ObservableSortedDictionary
which notifies its changes to registred listeners.If the tree is modifiable, new items can be added.
Every item is an
EditableTree.Item
.EditableTree is iterable over its items.
EditableTree also inherits from
ObservableAttributes
, so registred listeners can be notified of attributes value change.To call a method when item list changes:
editableTree.addListener(callbackMethod)
To call a method when an item list changes at any depth in the tree:
editableTree.addListenerRec(callbackMethod)
To call a method when an attribute of the tree changes:
editableTree.onAttributeChange(attributeName, callbackMethod)
To call a method when an attribute changes at any depth in the tree:
editableTree.onAttributeChangeRec(attributeName, callbackMethod)
- defaultName¶
default name of the tree
- Type:
string
- name¶
the name of the tree
- Type:
string
- id¶
tree identifier (a hash by default)
- Type:
string
- visible¶
indicates if the tree is visible (if not it may be hidden in a graphical representation)
- Type:
- 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 fromObservableSortedDictionary
, 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
- class Item(name=None, id=None, icon=None, tooltip=None, copyEnabled=True, modifiable=True, delEnabled=True, visible=True, enabled=True, *args)[source]¶
Base element of an
EditableTree
Item inherits from
ObservableAttributes
, so it can notify registred listeners of attributes changes (for examplename
).- icon¶
filename of the image that can be used to represent the item
- Type:
string
- name¶
Text representation of the item
- Type:
string
- tooltip¶
description associated to the item
- Type:
string
- visible¶
indicates if current item is visible (if not it may be hidden in a graphical representation)
- Type:
- class Leaf(name='new', id=None, icon=None, tooltip=None, copyEnabled=True, modifiable=True, delEnabled=True, visible=True, enabled=True)[source]¶
A tree item that cannot have children items
- add(item)[source]¶
Adds an item in the tree. If this item’s id is already present in the tree as a key, add the item’s content in the corresponding key.
recursive method
- addListenerRec(listener)[source]¶
Add a listener to the tree recursivly at every level. The listener is added to the notifier of all branches of the tree.
- compItems(id1, id2)[source]¶
Comparison function
Returns:
1 if
i1 > i2
-1 if
i1 < i2
0 if they are equal
- isDescendant(item)[source]¶
Returns True if the current item is a child or a child’s child… of the item in parameter
Always False for the root of the tree
- onAttributeChangeRec(attributeName, listener)[source]¶
Add a listener of the changes of this attribute value in the tree recursivly at every level.
The listener is added to the attribute change notifier of all branches of the tree.
- 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, itsnotify()
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 tonotify()
will only store the notification parameters untilrestartNotification()
is called.
- 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 areNotifier
instance, theirnotify()
method is calledSee also
- remove(listener)[source]¶
Remove an item from the notification list. Do nothing if listener is not in the list.
- restartNotification()[source]¶
Restart notifications that have been delayed by
delayNotification()
. All the calls tonotify()
that have been done between the call todelayNotification()
and the call torestartNotification()
, 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 todelayAttributeNotification()
, all modification notification will only be stored untilrestartAttributeNotification()
is called. This call is recursive on all attributes values that are instance ofObservableAttributes
.- 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.
See also
- 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 ofremoveOnAttributeChange()
must be the same as those passed toonAttributeChange()
to register the function.
- restartAttributeNotification()[source]¶
Restarts notifications that have been delayed by
delayAttributeNotification()
. All the modifications that happened between the call todelayAttributeNotification()
and the call torestartAttributeNotification()
, 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)
calls
update(INSERT_ACTION, [e], len(l))
- 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
- 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 0if
i > len(self)
, returnslen(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 bylen(self)
- 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.
- class soma.notification.ObservableNotifier(parameterCount=None)[source]¶
This notifier can notify when the first listener is added and when the last listener is removed.
It enables to use the notifier only when there are some listeners registred.
- onAddFirstListener¶
register a listener on this notifier to be called when the first listener is registred on ObservableNotifier
- Type:
- onRemoveLastListener¶
register a listener on this notifier to be called when the last listener is removed from ObservableNotifier
- Type:
- 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.
- 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)
calls
update(INSERT_ACTION, [e], index)
- onChangeNotifier¶
the Notifier’s notify method is called when the dictionaty has changed.
- Type:
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
- 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
- class soma.notification.VariableParametersNotifier(mainParameters, *otherParameters)[source]¶
This class is a notifier that can register functions with various arguments count.
See also
todo documentation
SubModule: path
¶
Some useful functions to manage file or directorie names.
author: Yann Cointepas
organization: NeuroSpin
license: CeCILL B
- soma.path.ensure_is_dir(d, clear_dir=False)[source]¶
If the directory doesn’t exist, use os.makedirs
- soma.path.find_in_path(file, path=None)[source]¶
Look for a file in a series of directories. By default, directories are contained in
PATH
environment variable. But another environment variable name or a sequence of directories names can be given in path parameter.Examples:
find_in_path('sh') could return '/bin/sh' find_in_path('libpython3.10.so', 'LD_LIBRARY_PATH') could return '/usr/lib/x86_64-linux-gnu/libpython3.10.so'
- soma.path.locate_file(pattern, root='.')[source]¶
Locates a file in a directory tree
- Parameters:
pattern (string) – The pattern to find
root (string) – The search root directory
- Returns:
The first found occurrence
- soma.path.parse_query_string(path)[source]¶
Parses the query string from a path and returns a dictionary.
Example
- soma.path.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¶m2=val2¶mN=valN
remove_query_string( '/dir1/file1?param1=val1¶m2=val2¶mN=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¶m2=val2¶mN=valN
split_query_string( '/dir1/file1?param1=val1¶m2=val2¶mN=valN' )
would return:
('/dir1/file1', '?param1=val1¶m2=val2¶mN=valN')
- soma.path.strict_urlparse(path)[source]¶
A “fixed” version of urlparse.urlparse() which preserves the case of the drive letter in windows paths. The standard urlparse changes ‘Z:/some/path’ to ‘z:/some/path’
- soma.path.update_hash_from_directory(directory, hash)[source]¶
Update a hash object from the content of a directory. The hash will reflect the recursive content of all files as well as the paths in all directories.
- soma.path.update_query_string(path, params, params_update_mode=0)[source]¶
Update the query string parameters in a path.
- Parameters:
path (string) – The path to update parameters within.
params (dict|list) – A dictionnary that contains keys and parameters to set in the query string
params_update_mode (dict|string|list|int) –
The default value is QueryStringParamUpdateMode.REPLACE that lead to replace value in the query string path by the one given in the params dictionary.
It is possible to change the default behaviour giving the value QueryStringParamUpdateMode.APPEND. This will lead to always append values of the params dictionary to values of the query string path. The default behaviour can also be changed by specifying a parameter name as string, in this case only values for that parameter name will be appended. It can also contains a list or a tuple of parameter names for which values will be appended.
Finally, this parameter can be a dictionary that specifies which parameter has to be appended or replaced. The dictionary contains parameter names in its keys and QueryStringParamUpdateMode in values.
- Returns:
path – The path updated with given parameters
- Return type:
string
Example
A path containing a query string is:
/dir1/file1?param1=val1¶m2=val2¶mN=valN
the params dictionary contains:
{'param1':'newval1', param2=newval2', param3':'newval3'}
update_query_string('/dir1/file1?param1=val1¶m2=val2¶mN=valN', {'param1':'newval1', 'param2':'newval2', 'param3':'newval3'})
would return:
'/dir1/file1?param1=newval1¶m2=newval2¶mN=valN¶m3=newval3'
update_query_string('/dir1/file1?param1=val1¶m2=val2¶mN=valN', {'param1':'newval1', 'param2':'newval2', 'param3':'newval3'}, QueryStringParamUpdateMode.APPEND)
would return:
'/dir1/file1?param1=val1¶m1=newval1¶m2=val2¶m2=newval2¶mN=valN¶m3=newval3'
update_query_string('/dir1/file1?param1=val1¶m2=val2¶mN=valN', {'param1':'newval1', 'param2':'newval2', 'param3':'newval3'}, 'param2')
would return:
'/dir1/file1?param1=newval1¶m2=val2¶m2=newval2¶mN=valN¶m3=newval3'
update_query_string('/dir1/file1?param1=val1¶m2=val2¶mN=valN', {'param1':'newval1', 'param2':'newval2', 'param3':'newval3'}, ('param1', 'param2'))
would return:
'/dir1/file1?param1=val1¶m1=newval1¶m2=val2¶m2=newval2¶mN=valN¶m3=newval3'
update_query_string('/dir1/file1?param1=val1¶m2=val2¶mN=valN', {'param1':'newval1', 'param2':'newval2', 'param3':'newval3'}, {'param1': QueryStringParamUpdateMode.APPEND, 'param2': QueryStringParamUpdateMode.REPLACE})
would return:
'/dir1/file1?param1=val1¶m1=newval1¶m2=val2¶m2=newval2¶mN=valN¶m3=newval3'
SubModule: qimage2ndarray
¶
QImage <-> numpy.ndarray conversion module.
* ATTENTION: This code is outdated - I released a better extension * named ‘qimage2ndarray’ (that completes all TODO items below) in * the meantime, which is available via PyPI and here: * http://kogs-www.informatik.uni-hamburg.de/~meine/software/qimage2ndarray/
This supports conversion in both directions; note that in contrast to C++, in Python it is not possible to convert QImages into ndarrays without copying the data. The conversion functions in the opposite direction however do not copy the data.
TODO:
support record arrays in rgb2qimage (i.e. grok the output of qimage2numpy)
support unusual widths/alignments also in gray2qimage and rgb2qimage
make it possible to choose between views and copys of the data (eventually in both directions, when implemented in C++)
allow for normalization in numpy->QImage conversion (i.e. to quickly visualize images with different value ranges)
implement in C++
- soma.qimage2ndarray.gray2qimage(gray)[source]¶
Convert the 2D numpy array gray into a 8-bit QImage with a gray colormap. The first dimension represents the vertical image axis.
ATTENTION: This QImage carries an attribute ndimage with a reference to the underlying numpy array that holds the data. On Windows, the conversion into a QPixmap does not copy the data, so that you have to take care that the QImage does not get garbage collected (otherwise PyQt will throw away the wrapper, effectively freeing the underlying memory - boom!).
- soma.qimage2ndarray.qimage2numpy(qimage, dtype='array')[source]¶
Convert QImage to numpy.ndarray. The dtype defaults to uint8 for QImage.Format_Indexed8 or bgra_dtype (i.e. a record array) for 32bit color images. You can pass a different dtype to use, or ‘array’ to get a 3D uint8 array for color images.
- soma.qimage2ndarray.rgb2qimage(rgb)[source]¶
Convert the 3D numpy array rgb into a 32-bit QImage. rgb must have three dimensions with the vertical, horizontal and RGB image axes.
ATTENTION: This QImage carries an attribute ndimage with a reference to the underlying numpy array that holds the data. On Windows, the conversion into a QPixmap does not copy the data, so that you have to take care that the QImage does not get garbage collected (otherwise PyQt will throw away the wrapper, effectively freeing the underlying memory - boom!).
SubModule: qt_gui
¶
SubModule: qt_gui.controller_widget
¶
- class soma.qt_gui.controller_widget.ControllerWidget(controller, parent=None, name=None, live=False, hide_labels=False, select_controls=None, editable_labels=False, override_control_types=None, user_data=None, userlevel=0)[source]¶
Class that create a widget to set the controller parameters.
Method to initilaize the ControllerWidget class.
- Parameters:
controller (derived Controller instance (mandatory)) – a class derived from the Controller class we want to parametrize with a widget.
parent (QtGui.QWidget (optional, default None)) – the controller widget parent widget.
name ((optional, default None)) – the name of this controller widget
live (bool (optional, default False)) – if True, synchronize the edited values in the widget with the controller values on the fly, otherwise, wait the synchronization instruction to update the controller values.
hide_labels (bool (optional, default False)) – if True, don’t show the labels associated with the controls
select_controls (str (optional, default None)) – parameter to select specific conrtoller traits. Authorized options are ‘inputs’ or ‘outputs’.
editable_labels (bool (optional, default False)) – if True, labels (trait keys) may be edited by the user, their modification will trigger a signal.
override_control_types (dict (optional)) – if given, this is a “factory” dict assigning new controller editor types to some traits types.
user_data (any type (optional)) – optional user data that can be accessed by individual control editors
userlevel (int) – the current user level: some traits may be marked with a non-zero userlevel, and will only be visible if the ControllerWidget userlevel is more than (or equal) the trait level.
- connect()[source]¶
Connect the controller trait and the controller widget controls
At the end al control will be connected with the associated trait, and when a ‘user_traits_changed’ signal is emited, the controls are updated (ie, deleted if necessary).
- create_control(trait_name, trait)[source]¶
Create a control associated to a trait.
- Parameters:
trait_name (str (mandatory)) – the name of the trait from which we want to create a control. The control widget will share the same name
trait (Trait (mandatory)) – a trait item
- get_control_class(trait)[source]¶
Find the control associated with the input trait.
The mapping is defined in the global class parameter ‘_defined_controls’.
- Parameters:
trait (Trait (mandatory)) – a trait item
- Returns:
control_class – the control class associated with the input trait. If no match has been found, return None
- Return type:
class
- is_valid()[source]¶
Check that all edited fields are correct.
- Returns:
valid – True if all the controller widget controls are correctly filled, False otherwise
- Return type:
- static static_disconnect(controller, update_controls, groups_vibility_changed, controls, widget)[source]¶
disconnect() cannot be called at the right time. static_disconnect() is called via a Qt signat when the widget is destroyed. But the python part is already destroyed then.
- update_controller()[source]¶
Update the controller.
At the end the controller traits values will match the controller widget user defined parameters.
- class soma.qt_gui.controller_widget.DeletableLineEdit(text=None, parent=None)[source]¶
Close button + line editor, used for modifiable key labels
- class soma.qt_gui.controller_widget.ScrollControllerWidget(controller, parent=None, name=None, live=False, hide_labels=False, select_controls=None, disable_controller_widget=False, override_control_types=None, user_data=None, userlevel=0)[source]¶
Class that create a widget to set the controller parameters.
The widget is placed in a scroll area when large sets of parameters have to be tuned.
Method to initilaize the ScrollControllerWidget class.
- Parameters:
controller (derived Controller instance (mandatory)) – a class derived from the Controller class we want to parametrize with a widget.
parent (QtGui.QWidget (optional, default None)) – the controller widget parent widget.
name ((optional, default None)) – the name of this controller widget
live (bool (optional, default False)) – if True, synchronize the edited values in the widget with the controller values on the fly, otherwise, wait synchronization instructions to update the controller values.
hide_labels (bool (optional, default False)) – if True, don’t show the labels associated with the controls
select_controls (str (optional, default None)) – parameter to select specific conrtoller traits. Authorized options are ‘inputs’ or ‘outputs’.
disable_controller_widget (bool (optional, default False)) – if True disable the controller widget.
override_control_types (dict (optional)) – if given, this is a “factory” dict assigning new controller editor types to some traits types.
user_data (any type (optional)) – optional user data that can be accessed by individual control editors
userlevel (int) – the current user level: some traits may be marked with a non-zero userlevel, and will only be visible if the ControllerWidget userlevel is more than (or equal) the trait level.
SubModule: qt_gui.io
¶
Utils for socket communication
- class soma.qt_gui.io.Socket(host, port=None)[source]¶
Opens a connection to a socket server and provides methods to read from and write to socket streams. To handle specific message format, redefine readMessage method. By default it reads a line on the socket. To process messages, redefine processMessage method. By default it prints the message to standard output.
- dest¶
socket server machine
- Type:
string
- socket¶
python socket object
- Type:
- socketnotifier¶
the notifier sends a signal when there’s something to read on the socket.
- Type:
qt.QSocketNotifier
- readLock¶
lock to prevent threads from reading at the same time on the socket
- Type:
- writeLock¶
lock to prevent threads from writing at the same time on the socket
- Type:
- lock¶
lock to prevent concurrent access on object data because it can be used by multiple threads. At least principal thread and reading messages thread when it not possible to use a QSocketNotifier.
- Type:
- Parameters:
host (string) – socket server machine (localhost if it is current machine)
port (int) – port that the socket server listens
- 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:
- 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:
- 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
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.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
- Return type:
the loaded submodule
- soma.qt_gui.qt_backend.imshow_widget(widget, figure=None, show=False)[source]¶
Display a shapshot of a QWidget into a Matplotlib figure using pylab.imshow(). This is useful to use the sphinx_gallery module for documentation.
- soma.qt_gui.qt_backend.init_matplotlib_backend(force=True)[source]¶
Initialize Matplotlib to use Qt, and the appropriate Qt/Python binding (PySide or PyQt) according to the configured/loaded toolkit. Moreover, the appropriate FigureCanvas type is set in the current module, and returned by this function.
- Parameters:
force (bool) – if False, if the backend is already initialized with a different value, then raise an exception. If True (the default), force the new backend in matplotlib. If matplotlib does not support the force parameter, then the backend will not be forced.
- soma.qt_gui.qt_backend.init_traitsui_handler()[source]¶
Setup handler for traits notification in Qt GUI. This function needs to be called before using traits notification which trigger GUI modification from non-principal threads.
WARNING: depending on the Qt bindings (PyQt or PySide), this function may instantiate a QApplication. It seems that when using PyQt4, QApplication is not instantiated, whereas when using PySide, it is. This means that after this function has been called, one must check if the application has been created before recreating it:
app = QtGui.QApplication.instance() if not app: app = QtGui.QApplication(sys.argv)
This behaviour is triggered somewhere in the traitsui.qt4.toolkit module, we cannot change it easily.
- soma.qt_gui.qt_backend.loadUi(ui_file, *args, **kwargs)[source]¶
Load a
.ui
file and returns the widget instance.This function is a replacement of PyQt4.uic.loadUi. The only difference is that relative icon or pixmap file names that are stored in the
*.ui
file are considered to be relative to the directory containing the ui file. With PyQt4.uic.loadUi, relative file names are considered relative to the current working directory therefore if this directory is not the one containing the ui file, icons cannot be loaded.
- soma.qt_gui.qt_backend.loadUiType(uifile, from_imports=False)[source]¶
PyQt4 / PySide abstraction to uic.loadUiType. Not implemented for PySide, actually, because PySide does not have this feature.
- soma.qt_gui.qt_backend.qimage_to_np(qimage)[source]¶
Utility function to transorm a Qt QImage into a numpy array suitable for matplotlib imshow() for instance.
- soma.qt_gui.qt_backend.set_qt_backend(backend=None, pyqt_api=1, compatible_qt5=None)[source]¶
set the Qt backend.
If a different backend has already setup or loaded, a warning is issued. If no backend is specified, try to guess which one is already loaded.
If no backend is loaded yet, try to behave like IPython does. See: https://ipython.org/ipython-doc/dev/interactive/reference.html#pyqt-and-pyside
More precisely this means: * If QT_API environement variable is not set, use PyQt4, with PyQt API v1 * if QT_API is set to “pyqt” or “pyqt4”, use PyQt4, with PyQt API v2 * if QT_API is set to “pyside”, use PySide * if QT_API is set to “pyqt5”, use PyQt5 * if QT_API is set to “pyqt6”, use PyQt6
Moreover if using PyQt4, QtCore is patched to duplicate QtCore.pyqtSignal and QtCore.pyqtSlot as QtCore.Signal and QtCore.Slot. This is meant to ease code portability between both worlds.
if compatible_qt5 is set to True, modules QtGui and QtWidgets will be exposed and completed to contain the same content, with both Qt4 and Qt5.
- Parameters:
backend (str (default: None)) – name of the backend to use
pyqt_api (int (default: 1)) – PyQt API version: 1 or 2, only useful for PyQt4
compatible_qt5 (bool (default: None)) – expose QtGui and QtWidgets with the same content. If None (default), do not change the current setting. If True, in Qt5, when QtGui or QtWidgets is loaded, the other module (QtWidgets or QtGui) is also loaded, and the QtGui module is modified to contain also the contents of QtWidgets, so as to have more or less the same elements as in Qt4. It is a bit dirty and crappy but allows the same code to work with both versions of Qt. In Qt4, when QtGui is loaded, the module is also registered as QtWidgets, so QtGui and QtWidgets are the same module. Loading QtWidgets will also bring QtGui.
Examples
>>> from soma.qt_gui import qt_backend >>> qt_backend.set_qt_backend('PySide') >>> qt_backend.import_qt_submodule('QtCore') <module 'PySide.QtCore' from '/usr/lib/python2.7/dist-packages/PySide/QtCore.so'>
SubModule: qt_gui.qtThread
¶
This module enables to make a function to be executed in qt thread (main thread). It is useful when you want to call qt functions from another thread. It enables to do thread safe calls because all tasks sent are executed in the same thread (qt main thread).
author: Dominique Geffroy
organization: NeuroSpin
license: CeCILL B
- class soma.qt_gui.qtThread.FakeQtThreadCall[source]¶
Fake QtThreadCall that behave as if always used from main thread.
- class soma.qt_gui.qtThread.MainThreadLife(obj_life=None, *args, **kwargs)[source]¶
This wrapper class ensures the contained object is deleted in the main thread, and not in the current non-GUI thread. The principle is the following:
acquire a lock
pass the object to something in the main thread
the main thread waits on the lock while holding a reference on the object
we delete the object in the calling thread
the lock is releasd from the calling thread
now the main thread can go on, and del / release the ref on the object: it is the last ref on it, so it is actually deleted there.
Warning
The thing is only working if no other reference is held anywhere on the underlying object, otherwise we do not control its deletion.
Ex:
# from a secondary thread widget = QtThreadCall().call(Qt.QWidget) # widget.show() # should crash QtThreadCall().push(widget.show) # ... use it ... # del widget # should crash
# from a secondary thread widget = MainThreadLife(QtThreadCall().call(Qt.QWidget)) QtThreadCall().push(widget.ref().show) # ... use it ... del widget # OK
- class soma.qt_gui.qtThread.QtThreadCall(*args, **kwargs)[source]¶
This object enables to send tasks to be executed by qt thread (main thread). This object must be initialized in qt thread. It starts a QTimer and periodically execute tasks in its actions list.
- lock¶
lock to prevent concurrent access to actions list
- Type:
RLock
- mainThread¶
current thread at object initialisation
- Type:
Thread
- timer¶
timer to wake this object periodically
- Type:
QTimer
The __init__ method of
Singleton
derived class should do nothing. Derived classes must define__singleton_init__()
instead of __init__.- call(function, *args, **kwargs)[source]¶
Send the function call to be executed in the qt main thread and wait for the result. The result will be returned to the calling thread.
Warning
If returned objects are thread-depenendent (typically, Qt widgets), they must be destroyed within the thread which created them, namely the main thread. The
MainThreadLife
object wrapper may be helpful for this.- Parameters:
function (function) – the function to call in main thread.
- 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.
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
- Parameters:
qLineEdit ((QtGui.QLineEdit instance)) – widget associated with this QLineEditModificationTimer.
timerInterval ((milliseconds)) – minimum inactivity period before emitting userModification signal. Default value is QLineEditModificationTimer.defaultTimerInterval
- startInternalModification()[source]¶
Restart emitting C{userModification} signal when associated QLineEdit is modified.
See also
- 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.
SubModule: safemkdir
¶
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 functionfrom_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 modulemy_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.
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.
author: Yann Cointepas
organization: NeuroSpin
license: CeCILL B (http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html)
SubModule: sorted_dictionary
¶
Sorted dictionary behave like a dictionary but keep the item insertion order.
author: Yann Cointepas
organization: NeuroSpin
license: CeCILL B (http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html)
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.
- 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
. Ifkey
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
- pop(k[, d]) v, remove specified key and return the corresponding value. [source]¶
If the key is not found, return the default if given; otherwise, raise a KeyError.
- popitem()[source]¶
Remove and return a (key, value) pair as a 2-tuple.
Pairs are returned in LIFO (last-in, first-out) order. Raises KeyError if the dict is empty.
- setdefault(key, value=None)[source]¶
Insert key with a value of default if key is not in the dictionary.
Return the value for key if key is in the dictionary, else default.
- sort(key=None, reverse=False)[source]¶
Sorts the dictionary using key function key.
- Parameters:
key (function key) –
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().
- 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
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 (seepush()
).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 callprocessFunctions()
to execute the functions that have been registered withcall()
andpush()
.- Parameters:
thread (
threading.Thread
instance or None) – Processing thread. If None,threading.current_thread()
is used.
- call(function, *args, **kwargs)[source]¶
Registers a function call and waits for the processing thread to call it.
Returns the result of the function. If an exception is raised during the execution of the function, this exception is also raised by
call()
. Thereforecall()
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
- 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:
- processingLoop()[source]¶
Continuously executes
processFunctions()
until it returns NoneSee also
- push(function, *args, **kwargs)[source]¶
Same as the
call()
method but always puts the function on the queue and returns immediatly. Ifpush()
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()
andpush()
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
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 onldconfig
, which only searches system paths, not user paths norLD_LIBRARY_PATH
, or alternatively usesgcc
, which is not always installed nor configured.Here we are looking in
[[DY]LD_LIBRARY_]PATH
(depending on the system)
- soma.utils.find_library.patch_ctypes_find_library()[source]¶
replace
ctypes.util.find_library()
by our version
SubModule: utils.functiontools
¶
Utility classes and functions for Python callable.
- class soma.utils.functiontools.SomaPartial(function, *args, **kwargs)[source]¶
This is a reimplementation of
functools.partial()
, which adds compatibility with thetraits
module.See the documentation of
functools.partial()
for details: https://docs.python.org/library/functools.html#functools.partialExample:
from soma.functiontools import partial def f(a, b, c): return (a, b, c) g = partial(f, 'a', c='c') g('b') # calls f('a', 'b', c='c')
- property func_code¶
This property make SomaPartial useable with traits module. The method on_trait_change is requiring that the function has a func_code.co_argcount attribute.
- soma.utils.functiontools.checkParameterCount(callable, paramCount)[source]¶
Checks that a callable can be called with paramCount arguments. If not, a RuntimeError is raised.
See also
- Parameters:
callable (callable) – function, method, class or instance to inspect
paramCount (int) – number of parameters
- soma.utils.functiontools.drange(start, stop, step=1)[source]¶
Creates lists containing arithmetic progressions of any number type (int, float, …)
- soma.utils.functiontools.getArgumentsSpecification(callable)[source]¶
This is an extension of Python module
inspect.getfullargspec
that accepts classes and returns only information about the parameters that can be used in a call to callable (e.g. the first self parameter of bound methods is ignored). If callable has not an appropriate type, aTypeError
exception is raised.- Parameters:
callable (callable) – function, method, class or instance to inspect
- Returns:
As
inspect.getfullargspec()
, returns (args, varargs, varkw, defaults) where args is a list of the argument names (it may contain nested lists). varargs and varkw are the names of the*
and**
arguments or None. defaults is a n-tuple of the default values of the last n arguments.- Return type:
- 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.
See also
- Parameters:
callable (callable) – function, method, class or instance to inspect
parameterName (string) – name of the parameter
- Return type:
- 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.
See also
- Parameters:
callable (callable) – function, method, class or instance to inspect
- Returns:
two elements (minimum, maximum)
- Return type:
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.
SubModule: utils.weak_proxy
¶
Utility functions to make a weak proxy which also keeps an access to its original object reference. weakref.proxy()
doesn’t allow this, but functions that check types (C+/Python bindings for instance) cannot work with proxies.
We build such a proxy by setting a weakref.ref()
object in the proxy (actually in the object itself).
- soma.utils.weak_proxy.get_ref(obj)[source]¶
Get a regular reference to an object, whether it is already a regular reference, a weak reference, or a weak proxy which holds an access to the original reference (built using
weak_proxy()
). In case of a weak proxy not built usingweak_proxy()
, we try to get theself
from a bound method of the object, namelyobj.__init__.__self__
, if it exists.
- class soma.utils.weak_proxy.proxy_method(obj, method=None)[source]¶
Indirect proxy for a bound method
It replaces a bound method, ie
a.method
with a proxy callable which does not take a reference ona
.Especially useful for callbacks. If we want to set a notifier with a callback on a proxy object (without adding a new reference on it), we can use proxy_method:
a = anatomist.Anatomist() a.onCursorNotifier.onAddFirstListener.add( partial(proxy_method(a, 'enableListening'), "LinkedCursor", a.onCursorNotifier))) del a
Without this mechanism, using:
a.onCursorNotifier.onAddFirstListener.add( partial(a.enableListening, "LinkedCursor", a.onCursorNotifier)))
would increment the reference count on a, because
a.enableListening
, as a bound method, contains a reference to a, and will prevent the deletion ofa
(here the Anatomist application)The constructor takes as parameters, either the object and its method name (as a string), or the bound method itself.
- soma.utils.weak_proxy.weak_proxy(obj, callback=None)[source]¶
Build a weak proxy (
weakref.ProxyType
) from an object, if it is not already one, and keep a reference to the original object (via aweakref.ReferenceType
) in it.callback is passed to
weakref.proxy()
.
SubModule: uuid
¶
Universal unique identifier.
author: Yann Cointepas
organization: NeuroSpin
license: CeCILL B
- class soma.uuid.Uuid(value=None)[source]¶
An Uuid instance is a universal unique identifier. It is a 128 bits random value.
Uuid constructor. If uuid is ommited or None, a new random Uuid is created; if it is a string if must be 36 characters long and follow the pattern:
XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
where
X
is an hexadecimal digit (example:'ad2d8fb0-7831-50bc-2fb6-5df048304001'
).If uuid is an Uuid instance, no new instance is created, in this case, Uuid(uuid) returns uuid.