================= Component Facades ================= As this code needs to support multiple different back-ends (AnalysisBase component configs and athena old and new-style configurables) this module provides a set of 'facades' which can be converted to the correct underlying representation. Components are created as the relevant type (algorithm, service or public/private tool) and are specified by their concrete type and name. In contrast to the underlying implementations, properties are *not* set through attribute access (e.g. :python:`component.property = value`) but by dictionary access (e.g. :python:`component['property'] = value`). This is chosen to ensure that there are no clashes between property names and attributes set on the python classes themselves, but also because properties are a key -> value mapping which is precisely the model that dictionaries are designed to represent. Properties on child components can be accessed by placing a '.' between the propery names, that is :python:`component['child']['property']` and :python:`component['child.property']` are exactly equivalent. This means that property values cannot contain '.' characters, but this is already more or less enforced by athena. There is also a shortcut for setting properties from the constructor: any further keyword arguments passed will be treated as properties to be set. .. code-block:: python tool = PrivateTool(type="MyToolType", name="MyToolName") tool.property = value is equivalent to .. code-block:: python tool = PrivateTool(type="MyToolType", name="MyToolName", property=value) ---------------------------------------- Setting Tools and Services as Properties ---------------------------------------- Tools and services can also be set as properties on components. This can be done by creating the tool and setting it as a property through the normal mechanism: .. code-block:: python tool = PrivateTool(type="MyToolType", name="tool", property=value) algorithm["tool"] = tool is equivalent to .. code-block:: python tool = algorithm.setPrivateTool(key="tool", type="MyToolType", property=value) Similar methods exist to set `public tools <../cpalgnodes.componentfacade.html#cpalgnodes.componentfacade.Component.setPublicTool>`_ or `services <../cpalgnodes.componentfacade.html#cpalgnodes.componentfacade.Component.setServices>`_ as well as to append to arrays of `services <../cpalgnodes.componentfacade.html#cpalgnodes.componentfacade.Component.appendToServiceArray>`_, `public <../cpalgnodes.componentfacade.html#cpalgnodes.componentfacade.Component.appendToPublicToolArray>`_ or `private tools <../cpalgnodes.componentfacade.html#cpalgnodes.componentfacade.Component.appendToPrivateToolArray>`_. ------------------------------ Creating the Job Configuration ------------------------------ The actual configuration of the job is held by a `JobConfiguration <../cpalgnodes.componentfacade.html#cpalgnodes.componentfacade.JobConfiguration>`_ object. This is essentially a list of `ConfigFragments <../cpalgnodes.componentfacade.html#cpalgnodes.componentfacade.ConfigFragment>`_, typically algorithms. The job can be created in the relevant back-end through the `create <../cpalgnodes.componentfacade.html#cpalgnodes.componentfacade.JobConfiguration>.create>`_ method. Component Accumulator --------------------- To use the component accumulator back-end an accumulator must be passed, into which the configuration will be merged. The corresponding :python:`ConfigFlags` must also be provided. The list of configured algorithms will be returned, but the full configuration (including these algorithms) will be held in the provided :python:`ComponentAccumulator`. A sequence name can be provided, in which case all algorithms will be created as a member of that sequence. .. code-block:: python job_config.create(accumulator=accumulator, flags=ConfigFlags) Athena ------ To use in old-style athena job options no arguments need to be provided to the :python:`create` method. The returned algorithms just need to be added to an :python:`AlgSequence`. .. code-block:: python athAlgSeq += job_config.create() EventLoop --------- In EventLoop a sequence object must be provided to receive all the public components that must be created. The returned algorithms must also be manually addded to the sequence. .. code-block:: python seq = AlgSequence() seq += job_config.create(sequence=seq)