diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6942c6b123d8118cb00b9bfe677c6c8a5613feb5 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,9 @@ +version: 2 + +sphinx: + configuration: docs/source/conf.py + +python: + version: 3.7 + install: + - requirements: docs/source/requirements.txt diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..07d6a392710fed96a570e6cc7a5e2cd1fb9e021d --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,4 @@ +# Never commit compiled documentation files +build/* +# mac stuff +.DS_Store diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..ba501f6f5b1bfd30093a73f5fc04b85122e604a4 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,19 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/pptx/EventConverters.ppt b/docs/pptx/EventConverters.ppt new file mode 100644 index 0000000000000000000000000000000000000000..a4e39803a1fc6da100ba21ff083001269d9d6052 Binary files /dev/null and b/docs/pptx/EventConverters.ppt differ diff --git a/docs/pptx/EventModel.ppt b/docs/pptx/EventModel.ppt new file mode 100644 index 0000000000000000000000000000000000000000..ec059321a1d7ba3fa7fddc25d43e5dff5c525484 Binary files /dev/null and b/docs/pptx/EventModel.ppt differ diff --git a/docs/pptx/GaudiArchitecture.ppt b/docs/pptx/GaudiArchitecture.ppt new file mode 100644 index 0000000000000000000000000000000000000000..dc560f107c1d4162643511460d8f1a4a027d3699 Binary files /dev/null and b/docs/pptx/GaudiArchitecture.ppt differ diff --git a/docs/pptx/MiniArchitecture.ppt b/docs/pptx/MiniArchitecture.ppt new file mode 100644 index 0000000000000000000000000000000000000000..66051921acd340ed38064a6eaee007d9f765195b Binary files /dev/null and b/docs/pptx/MiniArchitecture.ppt differ diff --git a/docs/pptx/PackageLayout.ppt b/docs/pptx/PackageLayout.ppt new file mode 100644 index 0000000000000000000000000000000000000000..95949dde1db14887ae1eb88f9b4e2328e721b25e Binary files /dev/null and b/docs/pptx/PackageLayout.ppt differ diff --git a/docs/pptx/Packages-LHCb.ppt b/docs/pptx/Packages-LHCb.ppt new file mode 100644 index 0000000000000000000000000000000000000000..9eba92e252b4f7689fd1f5d5024630f79f817410 Binary files /dev/null and b/docs/pptx/Packages-LHCb.ppt differ diff --git a/docs/pptx/Packages.ppt b/docs/pptx/Packages.ppt new file mode 100644 index 0000000000000000000000000000000000000000..683b2e3acd154429e16b9c5fb728261190e6d78a Binary files /dev/null and b/docs/pptx/Packages.ppt differ diff --git a/docs/pptx/ToolsDiagram.ppt b/docs/pptx/ToolsDiagram.ppt new file mode 100644 index 0000000000000000000000000000000000000000..45ebb0f7716be449e4e4eee08d381215a05e1e44 Binary files /dev/null and b/docs/pptx/ToolsDiagram.ppt differ diff --git a/docs/pptx/ToolsHierarchy.ppt b/docs/pptx/ToolsHierarchy.ppt new file mode 100644 index 0000000000000000000000000000000000000000..42ab92f45caa3afa0e7b4d0887fa3ce6213927c7 Binary files /dev/null and b/docs/pptx/ToolsHierarchy.ppt differ diff --git a/docs/pptx/job.ppt b/docs/pptx/job.ppt new file mode 100644 index 0000000000000000000000000000000000000000..45be89023b76b43f91f22a66dd6454f7b6b73c1a Binary files /dev/null and b/docs/pptx/job.ppt differ diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 0000000000000000000000000000000000000000..6c88f721eb750555f952438149d4ae2e33d561de --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,168 @@ +# -*- coding: utf-8 -*- +# +# Configuration file for the Sphinx documentation builder. +# +# This file does only contain a selection of the most common options. For a +# full list see the documentation: +# http://www.sphinx-doc.org/en/master/config + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + +# -- Project information ----------------------------------------------------- + +project = 'Gaudi' +copyright = '2019, CERN' +author = 'The Gaudi Developers' + +# The short X.Y version +version = '' +# The full version, including alpha/beta/rc tags +release = 'v31' + +# -- General configuration --------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.autodoc', +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = [] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = None + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'sphinx_rtd_theme' + +html_logo = 'gaudilogo_square.png' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# The default sidebars (for documents that don't match any pattern) are +# defined by theme itself. Builtin themes are using these templates by +# default: ``['localtoc.html', 'relations.html', 'sourcelink.html', +# 'searchbox.html']``. +# +# html_sidebars = {} + +# -- Options for HTMLHelp output --------------------------------------------- + +# Output file base name for HTML help builder. +htmlhelp_basename = 'Gaudidoc' + +# -- Options for LaTeX output ------------------------------------------------ + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'Gaudi.tex', 'Gaudi Documentation', 'Gaudi Developers', + 'manual'), +] + +# -- Options for manual page output ------------------------------------------ + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [(master_doc, 'gaudi', 'Gaudi Documentation', [author], 1)] + +# -- Options for Texinfo output ---------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'Gaudi', 'Gaudi Documentation', author, 'Gaudi', + 'One line description of project.', 'Miscellaneous'), +] + +# -- Options for Epub output ------------------------------------------------- + +# Bibliographic Dublin Core info. +epub_title = project + +# The unique identifier of the text. This can be a ISBN number +# or the project homepage. +# +# epub_identifier = '' + +# A unique identification for the text. +# +# epub_uid = '' + +# A list of files that should not be packed into the epub file. +epub_exclude_files = ['search.html'] + +# -- Extension configuration ------------------------------------------------- + +numfig = True diff --git a/docs/source/contributing.rst b/docs/source/contributing.rst new file mode 100644 index 0000000000000000000000000000000000000000..5ba05e5ce65ce9e55f61a83131e51d90cf4a6eac --- /dev/null +++ b/docs/source/contributing.rst @@ -0,0 +1,7 @@ +Gaudi Contribution Guide +======================== + +The Gaudi project is open source and welcomes contributions from experiments +and users. + +This is how to do it... diff --git a/docs/source/gaudilogo_square.png b/docs/source/gaudilogo_square.png new file mode 100644 index 0000000000000000000000000000000000000000..af7126f9b54f417209acc4483a9cecd867236871 Binary files /dev/null and b/docs/source/gaudilogo_square.png differ diff --git a/docs/source/help.rst b/docs/source/help.rst new file mode 100644 index 0000000000000000000000000000000000000000..040bd977e3998de7c74de1c6e0fa9d4686185266 --- /dev/null +++ b/docs/source/help.rst @@ -0,0 +1,6 @@ +Gaudi Help +========== + +You can `raise an issue <https://gitlab.cern.ch/gaudi/Gaudi/issues>`_ on +GitLab or just send an email to the +`Gaudi developer list <mailto:gaudi-developers@cern.ch>`_. diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..7240718031737d3ebe34f3c08dfb0ebe82ebb415 --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,50 @@ +.. Gaudi documentation master file, created by + sphinx-quickstart on Tue Apr 30 09:34:58 2019. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to the Gaudi Project documentation +========================================== + +Gaudi is a framework software package that is used to build data processing +applications for High-Energy Physics experiments. It contains all of the +components and interfaces to allow you to build event data processing +frameworks for your experiment. + +Gaudi scales to the needs of the most demanding experiments at the LHC, but is +simple enough to get started quickly and have an application running in just +a short time. + +Gaudi has been in production for the ATLAS and LHCb experiments and others +for many years and is also the framework used by the Future Circular Collider +(hh). + +.. toctree:: + :maxdepth: 2 + :caption: Basics + + tutorial + help + +.. toctree:: + :maxdepth: 2 + :caption: Reference + + user_guide + old/GDG + +.. toctree:: + :maxdepth: 2 + :caption: Developers + + contributing + license + + +================== +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/source/license.rst b/docs/source/license.rst new file mode 100644 index 0000000000000000000000000000000000000000..115f883321ba28faf1f34f591a663a5a3176fc62 --- /dev/null +++ b/docs/source/license.rst @@ -0,0 +1,21 @@ +Gaudi License +============= + +Copyright 1998-2019 CERN, for the benefit of the LHCb and ATLAS collaborations + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Contact +------- + +Please contact gaudidev@cern.ch. diff --git a/docs/source/old/GDG.rst b/docs/source/old/GDG.rst new file mode 100644 index 0000000000000000000000000000000000000000..b714aa5767adbf18a46192c6ae750f7e8279a300 --- /dev/null +++ b/docs/source/old/GDG.rst @@ -0,0 +1,37 @@ +.. include:: ./global.rst + +|newpage| + +|Gaudi logo| + +Gaudi Developers Guide v9 (outdated) +==================================== + +.. toctree:: + :maxdepth: 2 + :numbered: + :caption: Table of Contents + + GDG_frontmatter + GDG_Overview + GDG_Architecture + GDG_Installation + GDG_Starting + GDG_Algorithms + GDG_DataAccess + GDG_EventData + GDG_DetDescription + GDG_Histogram + GDG_Ntuple + GDG_Services + GDG_Tools + GDG_Converters + GDG_Scripting + GDG_Visualization + GDG_Libraries + GDG_Utilities + GDG_A_References + GDG_A_Options + GDG_A_JobOptions + GDG_A_Design + GDG_IX.rst diff --git a/docs/source/old/GDG_A_Design.rst b/docs/source/old/GDG_A_Design.rst new file mode 100644 index 0000000000000000000000000000000000000000..d2704ffdc9a025fb82f5faa26bd7666a5d888a4e --- /dev/null +++ b/docs/source/old/GDG_A_Design.rst @@ -0,0 +1,218 @@ +.. include:: ./global.rst + +|newpage| + +|Gaudi logo| + +.. _chapDesi: + +Appendix D Design considerations +================================ + +D.1 Generalities +------------------ + + In this chapter we look at how you might actually go about designing + and implementing a real physics algorithm. It includes points + covering various aspects of software development process and in + particular: + + | · The need for more "thinking before coding" when using an OO language like C++. + | · Emphasis on the specification and analysis of an algorithm in mathematical and natural language, rather than trying to force it into (unnatural?) object orientated thinking. + | · The use of OO in the design phase, i.e. how to map the concepts identified in the analysis phase into data objects and algorithm objects. + | · The identification of classes which are of general use. These could be implemented by the computing group, thus saving you work! + | · The structuring of your code by defining private utility methods within concrete classes. + + When designing and implementing your code we suggest that your + priorities should be as follows: (1) Correctness, (2) Clarity, (3) + Efficiency and, very low in the scale, OOness + + Tips about specific use of the C++ language can be found in the coding rules document + [LHCB-2001-054]_ or specialized literature. + + .. was <http://lhcb.cern.ch/notes/postscript/98notes/98-049.ps>`__\ `[6] <GDG_A_References.html#1048726>`__ + + +D.2 Designing within the Framework +------------------------------------ + + A physicist designing a real physics algorithm does not start with a + white sheet of paper. The fact that he or she is using a framework + imposes some constraints on the possible or allowed designs. The + framework defines some of the basic components of an application and + their interfaces and therefore it also specifies the places where + concrete physics algorithms and concrete data types will fit in with + the rest of the program. The consequences of this are: on one hand, + that the physicists designing the algorithms do not have complete + freedom in the way algorithms may be implemented; but on the other + hand, neither do they need worry about some of the basic + functionalities, such as getting end-user options, reporting + messages, accessing event and detector data independently of the + underlying storage technology, etc. In other words, the framework + imposes some constraints in terms of interfaces to basic services, + and the interfaces the algorithm itself is implementing towards the + rest of the application. The definition of these interfaces + establishes the so called "master walls" of the data processing + application in which the concrete physics code will be deployed. + Besides some general services provided by the framework, this + approach also guarantees that later integration will be possible of + many small algorithms into a much larger program, for example a + reconstruction program. In any case, there is still a lot of room + for design creativity when developing physics code within the + framework and this is what we want to illustrate in the next + sections. + + To design a physics algorithm within the framework you need to know + very clearly what it should do (the requirements). In particular you + need to know the following: + + | · What is the input data to the algorithm? What is the relationship of these data to other data (e.g. event or detector data)? + | · What new data is going to be produced by the algorithm? + | · What's the purpose of the algorithm and how is it going function? Document this in terms of mathematical expressions and plain english. [#]_ + | · What does the algorithm need in terms of configuration parameters? + | · How can the algorithm be partitioned (structured) into smaller "algorithm chunks" that make it easier to develop (design, code, test) and maintain? + | · What data is passed between the different chunks? How do they communicate? + | · How do these chunks collaborate together to produce the desired final behaviour? Is there a controlling object? Are they self-organizing? Are they triggered by the existence of some data? + | · How is the execution of the algorithm and its performance monitored (messages, histograms, etc.)? + | · Who takes the responsibility of bootstrapping the various algorithm chunks. + + For didactic purposes we would like to illustrate some of these + design considerations using a hypothetical example. Imagine that we + would like to design a tracking algorithm based on a Kalman-filter + algorithm. + +D.3 Analysis Phase +-------------------- + + As mentioned before we need to understand in detail what the + algorithm is supposed to do before we start designing it and of + course before we start producing lines of C++ code. One old + technique for that, is to think in terms of data flow diagrams, as + illustrated in :numref:`fig-trackdfd`, where we + have tried to decompose the tracking algorithm into various + processes or steps. + + .. figure:: images/TrackDFD.png + :name: fig-trackdfd + + Hypothetical decomposition of a tracking algorithm based on a Kalman filter using a Data flow Diagram + + In the analysis phase we identify the data which is needed as input + (event data, geometry data, configuration parameters, etc.) and the + data which is produced as output. We also need to think about the + intermediate data. Perhaps this data may need to be saved in the + persistency store to allow us to run a part of the algorithm without + starting always from the beginning. + + We need to understand precisely what each of the steps of the + algorithm is supposed to do. In case a step becomes too complex we + need to sub-divide it into several ones. Writing in plain english + and using mathematics whenever possible is extremely useful. The + more we understand about what the algorithm has to do the better we + are prepared to implement it. + +D.4 Design Phase +------------------ + + We now need to decompose our physics algorithm into one or more + Algorithms (as framework components) and define the way in which + they will collaborate. After that we need to specify the data types + which will be needed by the various Algorithms and their + relationships. Then, we need to understand if these new data types + will be required to be stored in the persistency store and how they + will map to the existing possibilities given by the object + persistency technology. This is done by designing the appropriate + set of Converters. Finally, we need to identify utility classes + which will help to implement the various algorithm chunks. + +D.4.1 Defining Algorithms +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Most of the steps of the algorithm have been identified in the + analysis phase. We need at this moment to see if those steps can be + realized as framework Algorithms. Remember that an Algorithm from + the view point of the framework is basically a quite simple + interface (initialize, execute, finalize) with a few facilities to + access the basic services. In the case of our hypothetical algorithm + we could decide to have a "master" Algorithm which will orchestrate + the work of a number of sub-Algorithms. This master Algorithm will + be also be in charge of bootstraping them. Then, we could have an + Algorithm in charge of finding the tracking seeds, plus a set of + others, each one associated to a different tracking station in + charge of propagating a proto-track to the next station and deciding + whether the proto-track needs to be kept or not. Finally, we could + introduce another Algorithm in charge of producing the final tracks + from the surviving proto-tracks. + + It is interesting perhaps in this type of algorithm to distribute + parts of the calculations (extrapolations, etc.) to more + sophisticated "hits" than just the unintelligent original ones. This + could be done by instantiating new data types (clever hits) for each + event having references to the original hits. For that, it would be + required to have another Algorithm whose role is to prepare these + new data objects, see :numref:`fig-design`. + + The master Algorithm (TrackingAlg) is in charge of setting up the + other algorithms and scheduling their execution. It is the only one + that has a global view but it does not need to know the details of + how the different parts of the algorithm have been implemented. The + application manager of the framework only interacts with the master + algorithm and does not need to know that in fact the tracking + algorithm is implemented by a collaboration of Algorithms. + + .. figure:: images/GDG_A_Designa.png + :name: fig-design + + Object diagram (a) and class diagram (b) showing how the complete example tracking algorithm could be decomposed into a set of specific algorithms that collaborate to perform the complete task. + +D.4.2 Defining Data Objects +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The input, output and intermediate data objects need to be + specified. Typically, the input and output are specified in a more + general way (algorithm independent) and basically are pure data + objects. This is because they can be used by a range of different + algorithms. We could have various types of tracking algorithm all + using the same data as input and producing similar data as output. + On the contrary, the intermediate data types can be designed to be + very algorithm dependent. + + The way we have chosen to communicate between the different + Algorithms which constitute our physics algorithm is by using the + transient event data store. This allows us to have low coupling + between them, but other ways could be envisaged. For instance, we + could implement specific methods in the algorithms and allow other + "friend" algorithms to use them directly. + + Concerning the relationships between data objects, it is strongly + discouraged to have links from the input data objects to the newly + produced ones (i.e. links from hits to tracks). In the other + direction this should not be a problem (i.e from tracks to + constituent hits). + + For data types that we would like to save permanently we need to + implement a specific Converter. One converter is required for each + type of data and each kind of persistency technology that we wish to + use. This is not the case for the data types that are used as + intermediate data, since these data are completely transient. + +D.4.3 Mathematics and other utilities +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + It is clear that to implement any algorithm we will need the help of + a series of utility classes. Some of these classes are very generic + and they can be found in common class libraries. For example the + standard template library. Other utilities will be more high energy + physics specific, especially in cases like fitting, error treatment, + etc. We envisage making as much use of these kinds of utility + classes as possible. + + Some algorithms or algorithm-parts could be designed in a way that + allows them to be reused in other similar physics algorithms. For + example, perhaps fitting or clustering algorithms could be designed + in a generic way such that they can be used in various concrete + algorithms. During design is the moment to identify this kind of + re-usable component or to identify existing ones that could be used + instead and adapt the design to make possible their usage. + +.. [#] Catalan is also acceptable. diff --git a/docs/source/old/GDG_A_JobOptions.rst b/docs/source/old/GDG_A_JobOptions.rst new file mode 100644 index 0000000000000000000000000000000000000000..4f17196b7a5ab5e56aa3479beefd95ef225fa8f0 --- /dev/null +++ b/docs/source/old/GDG_A_JobOptions.rst @@ -0,0 +1,172 @@ +.. include:: ./global.rst + +|newpage| + +|Gaudi logo| + +.. _chapJobo: + +Appendix C Job Options Grammar and Error Codes +============================================== + +C.1 The EBNF grammar of the Job Options files +----------------------------------------------- + + The syntax of the Job-Options-File is defined through the following + EBNF-Grammar. + + Job-Options-File = {Statements} . + + Statements = {Include-Statement} \| {Assign-Statement} \| {Append-Statement} \| + {Platform-Dependency} . + + AssertableStatements = {Include-Statement} \| {Assign-Statement} \| {Append-Statement} . + + AssertionStatement = '#ifdef' \| '#ifndef' . + + Platform-Dependency = AssertionStatement 'WIN32' <AsertableStatements> [ #else + <AssertableStatements> ] #endif + + Include-Statement = \`#include' string . + + Assign-Statement = Identifier \`.' Identifier \`=' value \`;' . + + Append-Statement = Identifier \`.' Identifier \`+=' value \`;' . + + Identifier = letter {letter \| digit} . + + value = boolean \| integer \| double \| string \| vector . + + vector = \`{' vectorvalue { \`,' vectorvalue } \`}' . + + vectorvalue = boolean \| integer \| double \| string . + + boolean = \`true' \| \`false' . + + integer = prefix scientificdigit . + + double = | ( prefix <digit> \`.' [ scientificdigit ] ) \| | ( prefix \`.' scientificdigit ) . + + string = \`"' {char} \`"' . + + scientificdigit = < digit> [ ( \`e' \| \`E' ) < digit> ] . + + digit = <figure> . + + prefix = [ \`+' \| \`-' ] . + + figure = \`0' \| \`1' \| \`2' \| \`3' \| \`4' \| \`5' \| \`6' \| \`7' \| \`8' + \| \`9'. + + char = any character from the ASCII-Code + + letter = set of all capital- and non-capital letter + +C.2 Job Options Error Codes and Error Messages +------------------------------------------------ + + The table below lists the error codes and error messages that the + Job Options compiler may generate, their reason and how to avoid + them. + + .. table:: Possible Error-Codes + + +-------------------------------+-----------------------------------------------+-----------------------------------------------+ + | Error-Code | Reason | How to avoid it | + +-------------------------------+-----------------------------------------------+-----------------------------------------------+ + | Error #000 Internal | - | This,code normally should never appear. | + | compiler error | | If this code is shown there is maybe, | + | | | a problem with your memory, your | + | | | disk-space or the property-file is, | + | | | corrupted. | + +-------------------------------+-----------------------------------------------+-----------------------------------------------+ + | Error #001 Included | - wrong path in #include-directive, | Please check if any of the listed | + | property-file does | - wrong file or mistyped filename, | reasons occured in your case. | + | not exists or can | - file is exclusively locked by | | + | not be opened | another application, | | + | | - no memory available to open this file | | + +-------------------------------+-----------------------------------------------+-----------------------------------------------+ + | Warning #001 File already | The file was already included by another | Remove the #include-directive | + | included by another file | file and will not be included a second | | + | | time.,The compiler will ignore this | | + | | #include-directive and will continue | | + | | with the next statement. | | + +-------------------------------+-----------------------------------------------+-----------------------------------------------+ + | Error #002 syntax error: | The compiler expected an object at the | Maybe you mistyped the name of the | + | Object expected | given position. | object or the object contains | + | | | unknown characters or does not fit | + | | | the given rules. | + +-------------------------------+-----------------------------------------------+-----------------------------------------------+ + | Error #003 syntax error: | The compiler expect a dot between the | Check if the dot between the Object | + | Missing dot between | Object and the Propertyname. | and the Propertyname is missing. | + | Object and Propertyname | | | + +-------------------------------+-----------------------------------------------+-----------------------------------------------+ + | Error #004 syntax error: | The compiler expected an identifier at | Maybe you mistyped the name of the | + | Identifier expected | the given position. | identifier or the identifier contains | + | | | unknown characters or does not fit the | + | | | given rules. | + +-------------------------------+-----------------------------------------------+-----------------------------------------------+ + | Error #005 syntax error: | The compiler expected an operator | Check if there is a valid operator | + | Missing operator '+=' | between the Propertyname and the value. | after the Propertyname. Note that | + | or '=' | | a blank or tab is not allowed between | + | | | '+='! | + +-------------------------------+-----------------------------------------------+-----------------------------------------------+ + | Error #006 String is not | A string (value) was not terminated by a ". | Check,if all your strings are beginning | + | terminated by a " | | and ending with ". Note that the, | + | | | position given by the compiler can be | + | | | wrong because the compiler may, | + | | | thought that following statements | + | | | are part of the string! | + +-------------------------------+-----------------------------------------------+-----------------------------------------------+ + | Error #007 syntax error: | The next token after the #include is not | Make sure that after the #include-directive | + | #include-statement is | a string. | there is specified the file to include. | + | not correct | | The file must be defined as a string! | + +-------------------------------+-----------------------------------------------+-----------------------------------------------+ + | Error #008 syntax error: | The include-directive was terminated by a ; | Remove the ; after the #include-directive. | + | #include does not end | | | + | with a ; | | | + +-------------------------------+-----------------------------------------------+-----------------------------------------------+ + | Error #009 syntax error: | One or more values within a vector were not | Check,if every value in the vector is | + | Values must be separated | separated with a ',' or one ore more values | separated by a ','. If so the reason, | + | with ',' | within a vector are mistyped. | for this message may result in mistyped | + | | | values in the vector (maybe,there is a | + | | | blank or tab between numbers). | + +-------------------------------+-----------------------------------------------+-----------------------------------------------+ + | Error #010 syntax error: | The closing bracket is missing or the vector | Check, if the vector ends with a '}' and | + | Vector must end with '}' | is not terminated correctly. | if there is no semicolon before the | + | | | ending-bracket. | + +-------------------------------+-----------------------------------------------+-----------------------------------------------+ + | Error #011 syntax error: | The statement is not terminated correctly. | Check if the statement ends with a | + | Statement must end with a ; | | semicolon ';'. | + +-------------------------------+-----------------------------------------------+-----------------------------------------------+ + | Runtime-Error #012: Cannot | The compiler cannot append the values to | Check,if the refered object is defined | + | append to object because | the object.propertyname because the | in one of the included files, if so, | + | it does not exists | object does not exist. | check if you writed the object-name | + | | | exactly like in the include-file. | + +-------------------------------+-----------------------------------------------+-----------------------------------------------+ + | Runtime-Error #013 Cannot | The compiler cannot append the values to | Check,if there was already something | + | append to object because | the object.propertyname because the | assigned to the refered property (in the, | + | Property does not exists | property does not exist. | include-file or in the current file). | + | | | If not then modify the, append-statement | + | | | into a assign-statement. If there was | + | | | already something assigned, check if the | + | | | object-name and the property-name are typed | + | | | correctly. | + +-------------------------------+-----------------------------------------------+-----------------------------------------------+ + | Error #014 Elements in the | One,or more elements in the vector have | Check declaration of vector, check the types | + | vector are not of the same | a different type than the first,element | and check, if maybe a value is mistyped. | + | type | in the vector. All elements must have | | + | | the same type like the,first declarated | | + | | element. | | + +-------------------------------+-----------------------------------------------+-----------------------------------------------+ + | Error #015 Value(s) expected | The compiler didn't find values to | Check the statement if there exists values | + | | append or assign | and if they are written correctly. Maybe | + | | | this error is a result of a previous error! | + +-------------------------------+-----------------------------------------------+-----------------------------------------------+ + | Error #016 Specified | The compiler was not able to include a | Check,if you are using enviornment-variables | + | property-file does not exist | property-file or didn't found the file. | to resolve the file, if they are,mistyped | + | or can not be resolved | A reason can be that the compiler was | (wether in the system or in the | + | | not able to resolve an,environment-variable | #include-directive) or not set,correctly. | + | | which points to the location of the | | + | | property-file. | | + +-------------------------------+-----------------------------------------------+-----------------------------------------------+ diff --git a/docs/source/old/GDG_A_Options.rst b/docs/source/old/GDG_A_Options.rst new file mode 100644 index 0000000000000000000000000000000000000000..e6d9538f7109576fbffe424365fcbd3ba3477402 --- /dev/null +++ b/docs/source/old/GDG_A_Options.rst @@ -0,0 +1,297 @@ +.. include:: ./global.rst + +|newpage| + +|Gaudi logo| + +.. _chapOpti: + +Appendix B Options for standard components +========================================== + + The following is a list of options that may be set for the standard components: e.g. data files for input, print-out level for the message service, etc. The options are listed in tabular form for each component along with the default value and a short explanation. The component name is given in the table caption thus: [ComponentName]. + + .. table:: Standard Options for the Application manager [ApplicationMgr] + :name: tab-b1 + + ==================== ================ ===================================================================================================================================================== + Option name Default value Meaning + ==================== ================ ===================================================================================================================================================== + EvtSel "" If "NONE", no event input [#]_ + EvtMax -1 Maximum number of events to process. The default is -1 (infinite) unless EvtSel = "NONE"; in which case it is 10. + TopAlg {} List of top level algorithms. Format: + {<Type>/<Name>[, <Type2>/<Name2>,...]}; + ExtSvc {} List of external services to be explicitly created by the ApplicationMgr (see section :numref:`serv-requ`). Format: + {<Type>/<Name>[, <Type2>/<Name2>,...]}; + OutStream {} Declares an output stream object for writing data to a persistent store, e.g. {"DstWriter"}; See also :numref:`tab-b10` + DLLs {} Search list of libraries for dynamic loading. Format: {<dll1>[,<dll2>,...]}; + HistogramPersistency "NONE" Histogram and N-tuple persistency mechanism. Available options are "HBOOK", "ROOT", "NONE" + Runable "AppMgrRunable" Type of runable object to be created by Application manager + EventLoop "EventLoopMgr" Type of event loop: + "EventLoopMgr" is standard event loop + "MinimalEventLoop" executes algorithms but does not read events + OutputLevel MSG::INFO Same as MessageSvc.OutputLevel. See :numref:`tab-b2` for possible values + JobOptionsType "FILE" Type of file (FILE implies ascii) + JobOptionsPath "jobOptions.txt" Path for job options source + ==================== ================ ===================================================================================================================================================== + + | NB: The last two options define the source of the job options file and so they cannot be defined in the job options file itself. There are two possibilities to set these options, the first one is using a environment variable called JOBOPTPATH or setting the option to the application manager directly from the main program [#]_. The coded option takes precedence. + +.. [#] A basic DataObject object is created as event root ("/Event") +.. [#] The setting of properties from the main program is discussed in :numref:`chapStar`. + + .. container:: + + .. table:: Standard Options for the message service [MessageSvc] + :name: tab-b2 + + =========== ======================== ===================================== + Option name Default value Meaning + =========== ======================== ===================================== + OutputLevel 0 Verboseness threshold level: + 0=NIL,1=VERBOSE, 2=DEBUG, 3=INFO, + 4=WARNING, 5=ERROR, 6=FATAL, 7=ALWAYS + Format "% F%18W%S%7W%R%T %0W%M" Format string. + =========== ======================== ===================================== + + .. table:: Standard Options for all algorithms [<myAlgorithm>]. Any algorithm derived from the Algorithm base class can override the global Algorithm options thus: + name: tab-b3 + + =============== ============= =================================================================================================================== + Option name Default value Meaning + =============== ============= =================================================================================================================== + OutputLevel 0 Message Service Verboseness threshold level. See :numref:`tab-b2` for possible values + Enable true If false, application manager skips execution of this algorithm + ErrorMax 1 Job stops when this number of errors is reached + ErrorCount 0 Current error count + AuditInitialize false Enable/Disable auditing of Algorithm initialisation + AuditExecute true Enable/Disable auditing of Algorithm execution + AuditFinalize false Enable/Disable auditing of Algorithm finalisation + =============== ============= =================================================================================================================== + + .. table:: Standard Options for all services [<myService>]. Any service derived from the Service base class can override the global + :name: tab-b4 + + =========== ============= =================================================================================================================== + Option name Default value Meaning + =========== ============= =================================================================================================================== + OutputLevel 0 Message Service Verboseness threshold level. See :numref:`tab-b2` for possible values + =========== ============= =================================================================================================================== + + .. container:: + + .. table:: Standard Options for all Tools [<myTool>]. Any tool derived from the AlgTool base class can override the global + :name: tab-b5 + + =========== ============= =================================================================================================================== + Option name Default value Meaning + =========== ============= =================================================================================================================== + OutputLevel 0 Message Service Verboseness threshold level. See :numref:`tab-b2` for possible values + =========== ============= =================================================================================================================== + + .. table:: Standard Options for all Associators [<myAssociator>] + :name: tab-b6 + + ============ ============= =============================================================================== + Option name Default value Meaning + ============ ============= =============================================================================== + FollowLinks true Instruct the associator to follow the links instead of using cached information + DataLocation "" Location where to get association information in the data store + ============ ============= =============================================================================== + + .. table:: Standard Options for Auditor service [AuditorSvc] + :name: tab-b7 + + =========== ============= ============================================================================== + Option name Default value Meaning + =========== ============= ============================================================================== + Auditors {}; List of Auditors to be loaded and to be used. + See section :numref:`serv-audi` for list of possible auditors + =========== ============= ============================================================================== + + .. table:: Standard Options for all Auditors [<myAuditor>]. Any Auditor derived from the Auditor base class can override the global Auditor options thus: + :name: tab-b8 + + =========== ============= =================================================================================================================== + Option name Default value Meaning + =========== ============= =================================================================================================================== + OutputLevel 0 Message Service Verboseness threshold level. See :numref:`tab-b2` for possible values + Enable true If false, application manager skips execution of the auditor + =========== ============= =================================================================================================================== + + .. table:: Options of Algorithms in GaudiAlg package(see :numref:`algo-filt`) + :name: tab-b9 + + ============== ============= ============= ======================================================== + Algorithm name Option Name Default value Meaning + ============== ============= ============= ======================================================== + EventCounter Frequency 1; Frequency with which number of events should be reported + Prescaler PercentPass 100.0; Percentage of events that should be passed + Sequencer Members Names of algorithms in the sequence + Sequencer BranchMembers Names of algorithms on the branch + Sequencer StopOverride false; If true, do not stop sequence if a filter fails + ============== ============= ============= ======================================================== + + .. container:: + + .. table:: Options available for output streams (e.g. DstWriter). Output stream objects are used for writing user created data into data files or databases. They are created and named by setting the option ApplicationMgr.OutStream. For each output stream the following options are available + :name: tab-b10 + + ================ ===================== ================================================================================ + Option name Default value Meaning + ================ ===================== ================================================================================ + ItemList {} The list of data objects to be written to this stream, e.g. + {"/Event#1","Event/MyTracks/#1"}; + Preload true; Preload items in ItemList + Output "" Output data stream specification. Format: + {"DATAFILE='mydst.root' TYP='ROOT'"}; + OutputFile "" Output file specification - same as DATAFILE in previous option + EvtDataSvc "EventDataSvc" The service from which to retrieve objects. + EvtConversionSvc "EventPersistencySvc" The persistency service to be used + AcceptAlgs {} If any of these algorithms sets filterflag=true; the event is accepted + RequireAlgs {} If any of these algorthms is not executed, the event is rejected + VetoAlgs {} If any of these algorithms does not set filterflag = true; the event is rejected + ================ ===================== ================================================================================ + + .. table:: Standard Options for persistency services (e.g. EventPersistencySvc) + :name: tab-b11 + + =========== ============= ===================================================================================================== + Option name Default value Meaning + =========== ============= ===================================================================================================== + CnvServices {} Conversion services to be used by the service to load or store persistent data (e.g. "RootEvtCnvSvc") + =========== ============= ===================================================================================================== + + .. table:: Standard Options for conversion services (e.g. RootEvtCnvSvc) + :name: tab-b12 + + =========== ============= ==================================== + Option name Default value Meaning + =========== ============= ==================================== + DbType "" Persistency technology (e.g. "ROOT") + =========== ============= ==================================== + + .. table:: Standard Options for the histogram service [HistogramPersistencySvc] + :name: tab-b13 + + =================== ============= ============================================================================================================================================================ + Option name Default value Meaning + =================== ============= ============================================================================================================================================================ + OutputFile "" Output file for histograms. Histograms not saved if not given. + RowWiseNTuplePolicy "FLOAT_ONLY" Persistent representation of NTuple data types. Other possible value is "USE_DATA_TYPES". See :numref:`ntup-spec` for details + PrintHistos false Print the histograms also to standard output (HBOOK only) + =================== ============= ============================================================================================================================================================ + + .. table:: Standard Options for the N-tuple service [NTupleSvc] (see :numref:`ntup-spec`) + :name: tab-b14 + + =========== ============= ==================================================== + Option name Default value Meaning + =========== ============= ==================================================== + Input {} Input file(s) for n-tuples. Format: + {"FILE1 DATAFILE='tuple1.typ' OPT='OLD' ", + Â ["FILE2 DATAFILE='tuple2.typ' OPT='OLD' ",...]} + Output {} Output file(s) for n-tuples. Format: + {"FILE1 DATAFILE='tuple1.typ' OPT='NEW'", + Â ["FILE2 DATAFILE='tuple2.typ' OPT='NEW'",...]} + StoreName "/NTUPLES" Name of top level entry + =========== ============= ==================================================== + + .. table:: Standard Options for the Event Collection service [TagCollectionSvc] (see :numref:`ntup-ecpe`) + :name: tab-b15 + + =========== ============= =========================================================================================== + Option name Default value Meaning + =========== ============= =========================================================================================== + Output {} Output file specification. See :numref:`ntup-ecpe` for details + StoreName "/NTUPLES" Name of top level entry + =========== ============= =========================================================================================== + + .. table:: Standard Options for the standard event selector [EventSelector] + :name: tab-b16 + + =========== ============= =========================================================================== + Option name Default value Meaning + =========== ============= =========================================================================== + Input {} Input data stream specification. + Format: "<tagname> = '<tagvalue>' <opt>" + Possible tags are different depending on input data type. + For Event data, see :numref:`data-redp` + For Event Collections, see :numref:`ntup-ecpe` + FirstEvent 1 First event to process (allows skipping of preceding events) + PrintFreq 10 Frequency with which event number is reported + =========== ============= =========================================================================== + + .. table:: Event Tag Collection Selector [EventCollectionSelector]. The following options are used internally by the EventCollectionSelector. They should not normally be used directly by users, who should set them via the "tags" of the EventSelector.Input option + :name: tab-b17 + + ============== ======================================== ================== ============================= + Option name Corresponding tag of EventSelector.Input Default value Meaning + ============== ======================================== ================== ============================= + CnvService SVC "EvtTupleSvc" Conversion service to be used + Authentication AUTH "" Authentication to be used + Container "B2PiPi" Container name + Item "Address" Item name + Criteria SEL "" Selection criteria + DB DATAFILE "" Database name + DbType TYP "" Database type + Function FUN "NTuple::Selector" Selection function + ============== ======================================== ================== ============================= + + .. table:: Standard Options for Random Numbers Generator Service [RndmGenSvc] + :name: tab-b18 + + =========== =============================== ================================== + Option name Default value Meaning + =========== =============================== ================================== + Engine "HepRndm::Engine<RanluxEngine>" Random number generator engine + Seeds Table of generator seeds + Column 0 Number of columns in seed table -1 + Row 1 Number of rows in seed table -1 + Luxury 3 Luxury value for the generator + UseTable false Switch to use seeds table + =========== =============================== ================================== + + .. table:: Standard Options for Particle Property Service [ParticlePropertySvc] + :name: tab-b19 + + ====================== =============================== ===================================== + Option name Default value Meaning + ====================== =============================== ===================================== + ParticlePropertiesFile "($LHCBDBASE)/cdf/particle.cdf" Particle properties database location + ====================== =============================== ===================================== + + .. container:: + + .. table:: Standard Options for Chrono and Stat Service [ChronoStatSvc] + :name: tab-b20 + + ====================== ============= ======================================================== + Option name Default value Meaning + ====================== ============= ======================================================== + ChronoPrintOutTable true Global switch for profiling printout + PrintUserTime true Switch to print User Time + PrintSystemTime false Switch to print System Time + PrintEllapsedTime false Switch to print Elapsed time (Note typo in option name!) + ChronoDestinationCout false If true, printout goes to cout rather than MessageSvc + ChronoPrintLevel 3 Print level for profiling (values as for MessageSvc) + ChronoTableToBeOrdered true Switch to order printed table + StatPrintOutTable true Global switch for statistics printout + StatDestinationCout false If true, printout goes to cout rather than MessageSvc + StatPrintLevel 3 Print level for profiling (values as for MessageSvc) + StatTableToBeOrdered true Switch to order printed table + ====================== ============= ======================================================== + +B.1 Obsolete options +--------------------- + + The following options are obsolete and should not be used. They are documented here for completeness and may be removed in a future release. + + .. table:: Obsolete Options + :name: tab-b21 + + ==================== ====================================================================== + Obsolete Option Replacement + ==================== ====================================================================== + EventSelector.EvtMax ApplicationMgr.EvtMax (:numref:`tab-b1`) + ==================== ====================================================================== diff --git a/docs/source/old/GDG_A_References.rst b/docs/source/old/GDG_A_References.rst new file mode 100644 index 0000000000000000000000000000000000000000..fc322adca432753c227a2eb6035da3de66214a1d --- /dev/null +++ b/docs/source/old/GDG_A_References.rst @@ -0,0 +1,32 @@ +.. include:: ./global.rst + +|newpage| + +|Gaudi logo| + +.. _chapRefe: + +Appendix A References +===================== + +.. [LHCB-98-064] 1 GAUDI - Architecture Design Report, http://weblib.cern.ch/record/691746 + +.. [GAUDI-DOXY] 2 GAUDI online code documentation, http://gaudi.web.cern.ch/gaudi/doxygen/master/index.html + +.. [LHCB-98-065] 3 GAUDI - User Requirements Document, http://weblib.cern.ch/record/684466 + +.. [Barrand:467678] 4 G.Barrand et al., GAUDI - A software architecture and framework for building LHCb data processing applications, doi: 10.1016/S0010-4655(01)00254-5, https://cds.cern.ch/record/467678 + +.. [LHCB-UNITS] 5 LHCb Physical Units Convention, http://lhcb-comp.web.cern.ch/lhcb-comp/Support/Conventions/units.pdf + +.. [LHCB-2001-054] 6 Revised LHCb coding conventions, http://weblib.cern.ch/record/684691 + +.. [CMT] CMT configuration management environment, http://www.cmtsite.net/ + +.. [Chytracek:2000] 7 R.Chytracek et al., The LHCb Detector Description Framework, [Proc CHEP 2000], http://cern.ch/lhcb-comp/General/Publications/pap-a155.pdf + +.. .. [LHCB-TALK-2001-023] I.Belyaev et al., Integration of GEANT4 with GAUDI, [Proc CHEP 2001], https://cds.cern.ch/record/1745074 + +.. [LHCB-TALK-2000-003] M.Frank et al., Data Persistency Solution for LHCb, [Proc CHEP 2000], http://cern.ch/lhcb-comp/General/Publications/pap-c153.pdf + +.. [AIDA] AIDA: Abstract Interfaces for Data Analysis, http://aida.freehep.org/ diff --git a/docs/source/old/GDG_Algorithms.rst b/docs/source/old/GDG_Algorithms.rst new file mode 100644 index 0000000000000000000000000000000000000000..99bcf713aa21e15674384f6563205de361fee4be --- /dev/null +++ b/docs/source/old/GDG_Algorithms.rst @@ -0,0 +1,567 @@ +.. include:: ./global.rst + +|newpage| + +|Gaudi logo| + +.. _chapAlgo: + +Writing algorithms +==================== + +Overview +------------ + + As mentioned previously the framework makes use of the inheritance + mechanism for specialising the Algorithm component. In other words, + a concrete algorithm class must inherit from ("be derived from" in + C++ parlance, "extend" in Java) the Algorithm base class. + + In this chapter we first look at the base class itself. We then + discuss what is involved in creating concrete algorithms: + specifically how to declare properties, what to put into the methods + of the IAlgorithm interface, the use of private objects and how to + nest algorithms. Finally we look at how to set up sequences of + algorithms and how to control processing through the use of branches + and filters. + +.. _algo-base: + +Algorithm base class +------------------------ + + Since a concrete algorithm object is-an Algorithm object it may use + all of the public and protected methods of the Algorithm base class. + The base class has no protected or public data members, so in fact, + these are the only methods that are available. Most of these methods + are provided solely to make the implementation of derived algorithms + easier. The base class has two main responsibilities: the + initialization of certain internal pointers and the management of + the properties of derived algorithm classes. + + A part of the Algorithm base class definition is shown in + :numref:`lstg-algobase`. Include directives, forward + declarations and private member variables have all been suppressed. + It declares a constructor and destructor; some methods of the + IAlgorithm interface; several accessors to services that a concrete + algorithm will almost certainly require; a method to create a sub + algorithm, the two methods of the IProperty interface; and a whole + series of methods for declaring properties. + + .. was 5.1 + + .. code-block:: cpp + :name: lstg-algobase + :caption: The definition of the Algorithm base class + + class Algorithm : virtual public IAlgorithm, + virtual public IProperty { + public: + + // Constructor and destructor + Algorithm( const std::string& name, + ISvcLocator* svcloc ); + virtual ~Algorithm(); + + // IAlgorithm interface only partially implemented + StatusCode sysInitialize(); + StatusCode sysExecute(); + StatusCode sysFinalize(); + StatusCode beginRun(); + StatusCode endRun(); + const std::string& name() const; + + virtual bool isExecuted() const; + virtual StatusCode setExecuted( bool state ); + virtual StatusCode resetExecuted(); + virtual bool isEnabled() const; + virtual bool filterPassed() const; + virtual StatusCode setFilterPassed( bool state); + + // Service accessors + template<class T> StatusCode service( const std::string& name, + T*& svc, + bool createIf = false ); + void setOutputLevel( int level ); + IMessageSvc* msgSvc() const; + IAuditorSvc* auditorSvc() const; + IDataProviderSvc* eventSvc() const; + IConversionSvc* eventCnvSvc() const; + IDataProviderSvc* detSvc() const; + IConversionSvc* detCnvSvc() const; + IHistogramSvc* histoSvc() const; + INtupleSvc* ntupleSvc() const; + IChronoStatSvc* chronoSvc() const; + IRndmGenSvc* randSvc() const; + IToolSvc* toolSvc() const; + ISvcLocator* serviceLocator() const; + + StatusCode createSubAlgorithm( const std::string& type, + const std::string& name, + Algorithm*& pSubAlg ); + std::vector<Algorithm*>* subAlgorithms() const; + + // IProperty interface + virtual StatusCode setProperty( const Property& p); + virtual StatusCode setProperty( std::istream s& ); + virtual StatusCode setProperty( const std::string& n, + const std::string& v); + virtual StatusCode getProperty( Property* p ) const; + const Property& getProperty( const std::string& name) const; + virtual StatusCode getProperty( const std::string& n, + std::string& v) const; + const std::vector<Property*>& getProperties() const; + StatusCode setProperties(); + template <class T> + StatusCode declareProperty(const std::string& name, + T& property); + StatusCode declareRemoteProperty(const std::string& name, + IProperty* rsvc, + const std::string& rname = "") const; + // Methods for IInterface + unsigned long addRef(); + unsigned long release(); + StatusCode queryInterface(const IID& riid, + void**); + + protected: + + bool isInitialized( ) const; + void setInitialized( ); + bool isFinalized( ) const; + void setFinalized( ); + + private: + + // Data members not shown + Algorithm(const Algorithm& a); // NO COPY ALLOWED + Algorithm& operator=(const Algorithm& rhs); // NO ASSIGNMENT ALLOWED}; + }; + + + | Constructor and Destructor + | The base class has a single constructor which takes two arguments: The first is the name that will identify the algorithm object being instantiated and the second is a pointer to one of the interfaces implemented by the application manager: ISvcLocator. This interface may be used to request special services that an algorithm may wish to use, but which are not available via the standard accessor methods (below). + | + | The IAlgorithm interface + | The base class only partially implements this interface: the three pure virtual methods initialize(), execute() and finalize() must be implemented by a derived algorithm: these are where the algorithm does its useful work and are discussed in more detail in section :numref:`algo-deri`. The base class provides default implementations of the methods beginRun() and endRun(), and the accessor name() which returns the algorithm's identifying name. The methods sysInitialize(), sysFinalize(), sysExecute() are used internally by the framework; they are not virtual and may not be overridden. + | + | Service accessor methods + | Lines 25 to 35 declare accessor methods which return pointers to key service interfaces. These methods are available for use only after the Algorithm base class has been initialized, i.e. they may not be used from within a concrete algorithm constructor, but may be used from within the initialize() method (see :numref:`algo-ialg`). The services and interface types to which they point are self explanatory. Services may be located by name using the templated service() function in line 23 or by using the serviceLocator() accessor method on line 36, as described in :numref:`serv-requ`. Line 24 declares a facility to modify the message output level from within the code (the message service is described in :numref:`serv-mess`). + | + | Creation of sub algorithms + | The methods on lines 38 to 39 are intended to be used by a derived class to manage sub-algorithms, as discussed in section :numref:`algo-nest`. + | + | Declaration and setting of properties + | A concrete algorithm must declare its properties to the framework using the templated declareProperty method (line 50), as discussed in :numref:`algo-decl` and :numref:`serv-prop`. The Algorithm base class then uses the setProperties() method (line 49) to tell the framework to set these properties to the values defined in the job options file. The methods in lines 42 to 48 can later be used to access and modify the values of specific properties, as explained in :numref:`serv-modi`. + | + | Filtering + | The methods in lines 14 to 19 are used by sequencers and filters to access the state of the algorithm, as discussed in :numref:`algo-filt`. + +.. _algo-deri: + +Derived algorithm classes +----------------------------- + + In order for an algorithm object to do anything useful it must be + specialised, i.e. it must extend (inherit from, be derived from) the + Algorithm base class. In general it will be necessary to implement + the methods of the IAlgorithm interface, and declare the algorithm's + properties to the property management machinery of the Algorithm + base class. Additionally there is one non-obvious technical matter + to cover, namely algorithm factories. + +.. _algo-crea: + +Creation (and algorithm factories) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + A concrete algorithm class must specify a single constructor with + the same parameter signature as the constructor of the base class. + + In addition to this, a concrete algorithm factory must be provided. + This is a technical matter which permits the application manager to + create new algorithm objects without having to include all of the + concrete algorithm header files. From the point of view of an + algorithm developer it implies adding three lines into the + implementation file, of the form: + + .. code-block:: cpp + + #include "GaudiKernel/AlgFactory.h" + // ... + static const AlgFactory<ConcreteAlgorithm> s_factory; + const IAlgFactory& ConcreteAlgorithmFactory = s_factory; + + where "ConcreteAlgorithm" should be replaced by the name of the + derived algorithm class (see for example lines 10 and 11 in :numref:`memvars` below). + +.. _algo-decl: + +Declaring properties +~~~~~~~~~~~~~~~~~~~~~~~~~~ + + In general, a concrete algorithm class will have several data + members which are used in the execution of the algorithm proper. + These data members should of course be initialized in the + constructor, but if this was the only mechanism available to set + their value it would be necessary to recompile the code every time + you wanted to run with different settings. In order to avoid this, + the framework provides a mechanism for setting the values of member + variables at run time. + + The mechanism comes in two parts: the declaration of properties and + the setting of their values. As an example consider the class + TriggerDecision in :numref:`memvars` + which has a number of variables whose value we would like to set at + run time. + + .. was 5.2. + + .. code-block:: cpp + :name: memvars + :caption: Declaring member variables as properties + + //------- In the header file -------------------------------------- + class TriggerDecision : public Algorithm { + + private: + + bool m_passAllMode; + int m_muonCandidateCut; + std::vector m_ECALEnergyCuts; + } + + //------- In the implementation file ------------------------------- + static const AlgFactory<TriggerDecision> s_factory; + const IAlgFactory& TriggerDecisionFactory = s_factory; + + TriggerDecision::TriggerDecision(std::string name, ISvcLocator* pSL) : + Algorithm(name, pSL), m_passAllMode(false), m_muonCandidateCut(0) { + m_ECALenergyCuts.push_back(0.0); + m_ECALenergyCuts.push_back(0.6); + + declareProperty("PassAllMode", m_passAllMode); + declareProperty("MuonCandidateCut", m_muonCandidateCut); + declareProperty("ECALEnergyCuts", m_ECALEnergyCuts); + } + + StatusCode TriggerDecision::initialize() { + } + + The default values for the variables are set within the constructor + (within an initialiser list). To declare them as properties it + suffices to call the declareProperty() method. This method is + templated to take an std::string as the first parameter and a + variety of different types for the second parameter. The first + parameter is the name by which this member variable shall be + referred to, and the second parameter is a reference to the member + variable itself. + + In the example we associate the name "PassAllMode" to the member + variable m\_passAllMode, and the name "MuonCandidateCut" to + m\_muonCandidateCut. The first is of type boolean and the second an + integer. If the job options service (described in :numref:`serv-jopt`) finds an option in the job + options file belonging to this algorithm and whose name matches one + of the names associated with a member variable, then that member + variable will be set to the value specified in the job options file. + +.. _algo-ialg: + +Implementing IAlgorithm +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Any concrete algorithm must implement the three pure virtual methods + initialize(), execute() and finalize() of the IAlgorithm interface. + For a top level algorithm, i.e. one controlled directly by the + application manager, the methods are invoked as is described in + :numref:`star-exec`. This dictates what it + is useful to put into each of the methods. + + | Initialization + + :numref:`fig-alginit` shows an example trace of the initialization phase. + + .. figure:: images/AlgorithmInitialize.png + :name: fig-alginit + + Algorithm initialization + + In a standard job the application manager will initialize all top + level algorithms exactly once before reading any event data. It does + this by invoking the sysInitialize() method of each top-level + algorithm in turn, in which the framework takes care of setting up + internal references to standard services and to set the algorithm + properties (using the mechanism described in :numref:`serv-prop`). At the end, sysInitialize() + calls the initialize() method, which can be used to do such things + as creating histograms, or creating sub-algorithms if required + (sub-algorithms are discussed in + :numref:`algo-nest`). If an algorithm + fails to initialize it should return StatusCode::FAILURE. This will + cause the job to terminate. + + | Execution + + The guts of the algorithm class is in the execute() method. For top + level algorithms this will be called once per event for each + algorithm object in the order in which they were declared to the + application manager. For sub-algorithms + (:numref:`algo-nest`) the control flow may + be as you like: you may call the execute() method once, many times + or not at all. + + Just because an algorithm derives from the Algorithm base class does + not mean that it is limited to using or overriding only the methods + defined by the base class. In general, your code will be much better + structured (i.e. understandable, maintainable, etc.) if you do not, + for example, implement the execute() method as a single block of 100 + lines, but instead define your own utility methods and classes to + better structure the code. + + If an algorithm fails in some manner, e.g. a fit fails to converge, + or its data is nonsense it should return from the execute() method + with StatusCode::FAILURE. This will cause the application manager to + stop processing events and end the job. This default behaviour can + be modified by setting the <myAlgorithm>.ErrorMax job option to + something greater than 1. In this case a message will be printed, + but the job will continue as if there had been no error, and just + increment an error count. The job will only stop if the error count + reaches the ErrorMax limit set in the job option. + + The framework (the Algorithm base class) calls the execute() method + within a try/catch clause. This means that any exception not handled + in the execution of an Algorithm will be caught at the level of + sysExecute() implemented in the base class. The behaviour on these + exceptions is identical to that described above for errors. + + | Finalization + + The finalize() method is called at the end of the job. It can be + used to analyse statistics, fit histograms, or whatever you like. + Similarly to initialization, the framework invokes a sysFinalize() + method which in turn invokes the finalize() method of the algorithm + and of any sub-algorithms. + + Optionally, the methods beginRun() and endRun() can also be + implemented. These are called at the beginning and the end of the + event loop respectively. + + Monitoring of the execution (e.g. cpu usage) of each Algorithm + instance is performed by auditors under control of the Auditor + service (described in :numref:`serv-audi`). This monitoring can be + turned on or off with the boolean properties AuditInitialize, + AuditExecute, AuditFinalize. + + The following is a list of things to do when implementing an + algorithm. + + | · Derive your algorithm from the Algorithm base class. + | · Provide the appropriate constructor and the three methods initialize(), execute() and finalize(). + | · Make sure you have implemented a factory by adding the magic two lines of code (see :numref:`algo-deri`). + +.. _algo-nest: + +Nesting algorithms +---------------------- + + The application manager is responsible for initializing, executing + once per event, and finalizing the set of top level algorithms, i.e. + the set of algorithms specified in the job options file. However + such a simple linear structure is very limiting. You may wish to + execute some algorithms only for specific types of event, or you may + wish to "loop" over an algorithm's execute method. Within the Gaudi + application framework the way to have such control is via the + nesting of algorithms or through algorithm sequences (described in + section 5.5). A nested (or sub-) algorithm is one which is created + by, and thus belongs to and is controlled by, another algorithm (its + parent) as opposed to the application manager. In this section we + discuss a number of points which are specific to sub-algorithms. + + In the first place, the parent algorithm will need a member variable + of type Algorithm\* (see the code fragment below) in which to store + a pointer to the sub-algorithm. + + .. code-block:: cpp + + Algorithm* m_pSubAlgorithm; // Pointer to the sub algorithm + // Must be a member variable of the parent class + std::string type; // Type of sub algorithm + std::string name; // Name to be given to subAlgorithm + StatusCode sc; // Status code returned by the call + sc = createSubAlgorithm(type, name, Algorithm*& m_pSubAlgorithm); + + + The sub-algorithm itself is created by invoking the + createSubAlgorithm() method of the Algorithm base class. The + parameters passed are the type of the algorithm, its name and a + reference to the pointer which will be set to point to the newly + created sub-algorithm. Note that the name passed into the + createSubAlgorithm() method is the same name that should be used + within the job options file for specifying algorithm properties. + + The algorithm type (i.e. class name) string is used by the + application manager to decide which factory should create the + algorithm object. + + The execution of the sub-algorithm is entirely the responsibility of + the parent algorithm whereas the initialize() and finalize() methods + are invoked automatically by the framework as shown in :numref:`fig-alginit`. Similarly the properties of a + sub-algorithm are also automatically set by the framework. + + Note that the createSubAlgorithm() method returns a pointer to an + Algorithm object, not an IAlgorithm interface. This means that you + have access to the methods of both the IAlgorithm and IProperty + interfaces, and consequently as well as being able to call execute() + etc. you may also change the properties of a sub-algorithm during + the main event loop as explained in :numref:`serv-modi`. Note also that the + vector of pointers to the sub-algorithms is available via the + subAlgorithms() method. + +.. _algo-filt: + +Algorithm sequences, branches and filters +--------------------------------------------- + + A physics application may wish to execute different algorithms + depending on the physics signature of each event, which might be + determined at run-time as a result of some reconstruction. This + capability is supported in Gaudi through sequences, branches and + filters. A sequence is a list of Algorithms. Each Algorithm may make + a filter decision, based on some characteristics of the event, which + can either allow or bypass processing of the downstream algorithms + in the sequence. The filter decision may also cause a branch whereby + a different downstream sequence of Algorithms will be executed for + events that pass the filter decision relative to those that fail it. + Eventually the particular set of sequences, filters and branches + might be used to determine which of multiple output destinations + each event is written to (if at all). This capability is not yet + implemented but is planned for a future release of Gaudi. + + A Sequencer class is available in the GaudiAlg package which manages + algorithm sequences using filtering and branching protocols which + are implemented in the Algorithm class itself. The list of + Algorithms in a Sequencer is specified through the Members property. + Algorithms can call setFilterPassed( true/false ) during their + execute() function. Algorithms in the membership list downstream of + one that sets this flag to false will not be executed, unless the + StopOverride property of the Sequencer has been set, or the + filtering algorithm itself is of type Sequencer and its + BranchMembers property specifies a branch with downstream members. + Please note that, if a sub-algorithm is of type Sequencer, the + parent algorithm must call the resetExecuted() method of the + sub-algorithm before calling the execute() method, otherwise the + sequence will only be executed once in the lifetime of the job! + + An algorithm instance is executed only once per event, even if it + appears in multiple sequences. It may also be enabled or disabled, + being enabled by default. This is controlled by the Enable property. + Enabling and disabling of algorithm instances is a capability that + is designed for a future release of Gaudi that will include an + interactive scripting language. + + The filter passed or failed logic for a particular Algorithm + instance in a sequence may be inverted by specifying the :invert + optional flag in the Members list for the Sequencer in the job + options file. + + A Sequencer will report filter success if either of its main and + branch member lists succeed. The two cases may be differentiated + using the Sequencer branchFilterPassed() boolean function. If this + is set true, then the branch filter was passed, otherwise both it + and the main sequence indicated failure. + + The following examples illustrate the use of sequences with + filtering and branching. + +Filtering example +~~~~~~~~~~~~~~~~~~~~~~~ + + :numref:`exjobopts` is an extract of the + job options file of the AlgSequencer example: a Sequencer instance + is created (line 2) with two + members (line 5 ); each member is + itself a Sequencer, implementing the sequences set up in lines 7 + and 8, which consist of Prescaler, + EventCounter and HelloWorld algorithms. The StopOverride property of + the TopSequence is set to true, which causes both sequences to be + executed, even if the first one indicates a filter failure. + + The Prescaler and EventCounter classes are example algorithms + distributed with the GaudiAlg package. The Prescaler class acts as a + filter, passing the fraction of events specified by the PercentPass + property (as a percentage). The EventCounter class just prints each + event as it is encountered, and summarizes at the end of job how + many events were seen. Thus at the end of job, the Counter1 instance + will report seeing 50% of the events, while the Counter2 instance + will report seeing 10%. + + Note the same instance of the HelloWorld class appears in both + sequences. It will be executed in Sequence1 if Prescaler1 passes the + event. It will be executed in Sequence2 if Prescaler2 passes the + event only if Prescaler1 failed it. + + .. was 5.3 + + .. code-block:: cpp + :name: exjobopts + :caption: Example job options using Sequencers demonstrating filtering + + ApplicationMgr.DLLs += { "GaudiAlg" }; + ApplicationMgr.TopAlg = { "Sequencer/TopSequence" }; + + // Setup the next level sequencers and their members + TopSequence.Members = {"Sequencer/Sequence1", "Sequencer/Sequence2"}; + TopSequence.StopOverride = true; + Sequence1.Members = {"Prescaler/Prescaler1", "HelloWorld", "EventCounter/Counter1"}; + Sequence2.Members = {"Prescaler/Prescaler2", "HelloWorld", "EventCounter/Counter2"}; + + Prescaler1.PercentPass = 50.; + Prescaler2.PercentPass = 10.; + + +Sequence branching +~~~~~~~~~~~~~~~~~~~~~~~~ + + :numref:`exjoboptseq` illustrates the use of + explicit branching. The BranchMembers property of the Sequencer + specifies some algorithms to be executed if the algorithm that is + the first member of the branch (which is common to both the main and + branch membership lists) indicates a filter failure. In this example + the EventCounter instance Counter1 will report seeing 80% of the + events, whereas Counter2 will report seeing 20%. + + .. was 5.4 + + .. code-block:: cpp + :name: exjoboptseq + :caption: Example job options using Sequencers demonstrating branching + + ApplicationMgr.DLLs += { "GaudiAlg" }; + ApplicationMgr.TopAlg = { "Sequencer" }; + + // Setup the next level sequencers and their members + Sequencer.Members = {"HelloWorld", "Prescaler", "EventCounter/Counter1"}; + Sequencer.BranchMembers = {"Prescaler", "EventCounter/Counter2"}; + + Prescaler.PercentPass = 80.; + + + :numref:`exjoboptinv` illustrates the use of + inverted logic. It achieves the same goal as the example in + :numref:`exjoboptseq` through use of two sequences + with the same instance of a Prescaler filter, but where the second + sequence contains inverted logic for the single instance. + + .. was 5.5 + + .. code-block:: cpp + :name: exjoboptinv + :caption: Example job options using Sequencers demonstrating inverted logic + + ApplicationMgr.DLLs += { "GaudiAlg" }; + ApplicationMgr.TopAlg = { "Sequencer/Seq1", "Sequencer/Seq2" }; + + // Setup the next level sequencers and their members + Seq1.Members = {"HelloWorld", "Prescaler", "EventCounter/Counter1"}; + Seq2.Members = {"HelloWorld", "Prescaler:invert", "EventCounter/Counter2"}; + + Prescaler.PercentPass = 80.; diff --git a/docs/source/old/GDG_Architecture.rst b/docs/source/old/GDG_Architecture.rst new file mode 100644 index 0000000000000000000000000000000000000000..a8bff4827843a0cd93475f2f257d05715b99ac64 --- /dev/null +++ b/docs/source/old/GDG_Architecture.rst @@ -0,0 +1,310 @@ +.. include:: ./global.rst + +|newpage| + +|Gaudi logo| + +.. _chapArch: + +The framework architecture +============================ + +Overview +------------ + + In this chapter we outline some of the main features of the Gaudi + architecture. A (more) complete view of the architecture, along with + a discussion of the main design choices and the reasons for these + choices may be found in references [LHCB-98-064]_ and [Barrand:467678]_. + +Why architecture? +--------------------- + + The basic "requirement" of the physicists is a set of programs for + doing event simulation, reconstruction, visualisation, etc. and a + set of tools which facilitate the writing of analysis programs. + Additionally a physicist wants something that is easy to use and + (though he or she may claim otherwise) is extremely flexible. The + purpose of the Gaudi application framework is to provide software + which fulfils these requirements, but which additionally addresses a + larger set of requirements, including the use of some of the + software online. + + If the software is to be easy to use it must require a limited + amount of learning on the part of the user. In particular, once + learned there should be no need to re-learn just because technology + has moved on (you do not need to re-take your licence every time you + buy a new car). Thus one of the principal design goals was to + insulate users (physicist developers and physicist analysists) from + irrelevant details such as what software libraries we use for data + I/O, or for graphics. We have done this by developing an + architecture. An architecture consists of the specification of a + number of components and their interactions with each other. A + component is a "block" of software which has a well specified + interface and functionality. An interface is a collection of methods + along with a statement of what each method actually does, i.e. its + functionality. + + The main components of the Gaudi software architecture can be seen + in the object diagram shown in :numref:`fig-gaudiarch`. Object diagrams are very + illustrative for explaining how a system is decomposed. They + represent a hypothetical snapshot of the state of the system, + showing the objects (in our case component instances) and their + relationships in terms of ownership and usage. They do not + illustrate the structure, i.e. class hierarchy, of the software. + + .. figure:: images/GaudiArchitecture.png + :name: fig-gaudiarch + + Gaudi Architecture Object Diagram + + It is intended that almost all software written by physicists, + whether for event generation, reconstruction or analysis, will be in + the form of specialisations of a few specific components. Here, + specialisation means taking a standard component and adding to its + functionality while keeping the interface the same. Within the + application framework this is done by deriving new classes from one + of the base classes: + + | · DataObject + | · Algorithm + | · Converter + + In this chapter we will briefly consider the first two of these + components and in particular the subject of the "separation" of data + and algorithms. They will be covered in more depth in chapters + :numref:`chapAlgo` and :numref:`chapData`. The third base class, + Converter, exists more for technical necessity than anything else + and will be discussed in :numref:`chapConv`. Following this we give a brief + outline of the main components that a physicist developer will come + into contact with. + +Data versus code +-------------------- + + Broadly speaking, tasks such as physics analysis and event + reconstruction consist of the manipulation of mathematical or + physical quantities: points, vectors, matrices, hits, momenta, etc., + by algorithms which are generally specified in terms of equations + and natural language. The mapping of this type of task into a + programming language such as FORTRAN is very natural, since there is + a very clear distinction between "data" and "code". Data consists of + variables such as: + + .. code-block:: fortran + + integer n + real p(3) + + and code which may consist of a simple statement or a set of + statements collected together into a function or procedure: + + .. code-block:: fortran + + real function innerProduct(p1, p2) + real p1(3), p2(3) + innerProduct = p1(1) * p2(1) + p1(2) * p2(2) + p1(3) * p2(3) + end + + Thus the physical and mathematical quantities map to data and the + algorithms map to a collection of functions. + + A priori, we see no reason why moving to a language which supports + the idea of objects, such as C++, should change the way we think of + doing physics analysis. Thus the idea of having essentially + mathematical objects such as vectors, points etc. and these being + distinct from the more complex beasts which manipulate them, e.g. + fitting algorithms etc. is still valid. This is the reason why the + Gaudi application framework makes a clear distinction between "data" + objects and "algorithm" objects. + + Anything which has as its origin a concept such as hit, point, + vector, trajectory, i.e. a clear "quantity-like" entity should be + implemented by deriving a class from the DataObject base class. + + On the other hand anything which is essentially a "procedure", i.e. + a set of rules for performing transformations on more data-like + objects, or for creating new data-like objects should be designed as + a class derived from the Algorithm base class. + + Further more you should not have objects derived from DataObject + performing long complex algorithmic procedures. The intention is + that these objects are "small". + + Tracks which fit themselves are of course possible: you could have a + constructor which took a list of hits as a parameter; but they are + silly. Every track object would now have to contain all of the + parameters used to perform the track fit, making it far from a + simple object. Track-fitting is an algorithmic procedure; a track is + probably best represented by a point and a vector, or perhaps a set + of points and vectors. They are different. + +Main components +------------------- + + The principle functionality of an algorithm is to take input data, + manipulate it and produce new output data. :numref:`fig-miniarch` shows how a concrete + algorithm object interacts with the rest of the application + framework to achieve this. + + .. figure:: images/MiniArchitecture.png + :name: fig-miniarch + + The main components of the framework as seen by an algorithm object + + The figure shows the four main services that algorithm objects use: + + | · The event data store + | · The detector data store + | · The histogram service + | · The message service + + The particle property service is an example of additional services + that are available to an algorithm. The job options service (see + :numref:`chapServ`) is used by the Algorithm + base class, but is not usually explicitly seen by a concrete + algorithm. + + Each of these services is provided by a component and the use of + these components is via an interface. The interface used by + algorithm objects is shown in the figure, e.g. for both the event + data and detector data stores it is the IDataProviderSvc interface. + In general a component implements more than one interface. For + example the event data store implements another interface: + IDataManagerSvc which is used by the application manager to clear + the store before a new event is read in. + + An algorithm's access to data, whether the data is coming from or + going to a persistent store or whether it is coming from or going to + another algorithm is always via one of the data store components. + The IDataProviderSvc interface allows algorithms to access data in + the store and to add new data to the store. It is discussed further + in :numref:`chapData` where we consider the + data store components in more detail. + + The histogram service is another type of data store intended for the + storage of histograms and other "statistical" objects, i.e. data + objects with a lifetime of longer than a single event. Access is via + the IHistogramSvc which is an extension to the IDataProviderSvc + interface, and is discussed in :numref:`chapHist`. The n-tuple service is similar, + with access via the INtupleSvc extension to the IDataProviderSvc + interface, as discussed in :numref:`chapNtup`. + + In general, an algorithm will be configurable: It will require + certain parameters, such as cut-offs, upper limits on the number of + iterations, convergence criteria, etc., to be initialised before the + algorithm may be executed. These parameters may be specified at run + time via the job options mechanism. This is done by the job options + service. Though it is not explicitly shown in the figure this + component makes use of the IProperty interface which is implemented + by the Algorithm base class. + + During its execution an algorithm may wish to make reports on its + progress or on errors that occur. All communication with the outside + world should go through the message service component via the + IMessageSvc interface. Use of this interface is discussed in + :numref:`chapServ`. + + As mentioned above, by virtue of its derivation from the Algorithm + base class, any concrete algorithm class implements the IAlgorithm + and IProperty interfaces, except for the three methods initialize(), + execute(), and finalize() which must be explicitly implemented by + the concrete algorithm. IAlgorithm is used by the application + manager to control top-level algorithms. IProperty is usually used + only by the job options service. + + The figure also shows that a concrete algorithm may make use of + additional objects internally to aid it in its function. These + private objects do not need to inherit from any particular base + class so long as they are only used internally. These objects are + under the complete control of the algorithm object itself and so + care is required to avoid memory leaks etc. + + We have used the terms "interface" and "implements" quite freely + above. Let us be more explicit about what we mean. We use the term + interface to describe a pure virtual C++ class, i.e. a class with no + data members, and no implementation of the methods that it declares. + For example: + + .. code-block:: cpp + + class PureAbstractClass { + virtual void method1() = 0; + virtual void method2() = 0; + }; + + is a pure abstract class or interface. We say that a class + implements such an interface if it is derived from it, for example: + + .. code-block:: cpp + + class ConcreteComponent: public PureAbstractClass { + void method1() {} + void method2() {} + }; + + A component which implements more than one interface does so via + multiple inheritance, however, since the interfaces are pure + abstract classes the usual problems associated with multiple + inheritance do not occur. These interfaces are identified by a + unique number which is available via a global constant of the form: + IID\_InterfaceType, such as for example IID\_IDataProviderSvc. + Interface identifiers are discussed in detail in :numref:`chapLibr`. + + Within the framework every component, e.g. services and algorithms, + has two qualities: + + | · A concrete component class, e.g. TrackFinderAlgorithm or MessageSvc. + | · Its name, e.g. "KalmanFitAlgorithm" or "MessageService". + +Controlling and Scheduling +------------------------------ + +Application Bootstrapping +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The application is bootstrapped by creating an instance of the + ApplicationMgr component. The ApplicationMgr is in charge of + creating an initializing a minimal set of basic and essential + services before control is given to specialized scheduling services. + These services are shown in :numref:`fig-arch2`. The EventLoopMgr is in + charge controlling the main physics event [#]_ + loop and scheduling the top algorithms. There will be a number of + more or less specialized implementations of EventLoopMgr which will + perform the different actions depending on the running environment, + and experiment specific policies (clearing stores, saving + histograms, etc.). There exists the possibility to give the full + control of the application to a component implementing the IRunable + interface. This is needed for interactive applications such as event + display, interactive analysis, etc. The Runable component can + interact directly with the EventLoopMgr for triggering the + processing of the next physics event. + + The essential services that the ApplicationMgr need to instantiate + and initialize are the MessageSvc and JobOptionsSvc. + + .. figure:: images/GDG_Architecture2.png + :name: fig-arch2 + + Control and Scheduling collaboration + +Algorithm Scheduling +~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The Gaudi architecture foresees explicit invocation of algorithms by + the framework or by other algorithms. This latter possibility allows + for a hierarchical organization of algorithms, for example, a high + level algorithm invoking a number of sub-algorithms. + + The EventLoopMgr component is in charge of initializing, finalizing + and executing the set of Algorithms that have been declared with the + TopAlg property. These Algorithms are executed unconditionally in + the order they have been declared. This vary basic scheduling is + insufficient for many use cases (event filtering, conditional + execution, etc.). Therefore, a number of Algorithms have been + introduced that perform more sophisticated scheduling and can be + configured by some properties. Examples are: Sequencers, Prescalers, + etc. and the list can be easily extended. See :numref:`algo-filt` + for more details on these generic high level Algorithms. + +.. [#] We state physics event to differentiate from what is called generally an event in computing. diff --git a/docs/source/old/GDG_Converters.rst b/docs/source/old/GDG_Converters.rst new file mode 100644 index 0000000000000000000000000000000000000000..8c83dc22c1aaab1ef01650a13d8c069c55f1c046 --- /dev/null +++ b/docs/source/old/GDG_Converters.rst @@ -0,0 +1,330 @@ +.. include:: ./global.rst + +|newpage| + +|Gaudi logo| + +.. _chapConv: + +Converters +============= + +Overview +------------- + + Consider a small piece of detector; a silicon wafer for example. + This "object" will appear in many contexts: it may be drawn in an + event display, it may be traversed by particles in a Geant4 + simulation, its position and orientation may be stored in a + database, the layout of its strips may be queried in an analysis + program, etc. All of these uses or views of the silicon wafer will + require code. + + One of the key issues in the design of the framework was how to + encompass the need for these different views within Gaudi. In this + chapter we outline the design adopted for the framework and look at + how the conversion process works. This is followed by sections which + deal with the technicalities of writing converters for reading from + and writing to ROOT files. + +Persistency converters +--------------------------- + + Gaudi gives the possibility to read event data from, and to write + data back to, ROOT files. The use of ODBC compliant databases is + also possible, though this is not yet part of the Gaudi release. + Other persistency technologies have been implemented for LHCb, in + particular the reading of data from LHCb DSTs based on ZEBRA. + + :numref:`fig-conv` is a schematic + illustrating how converters fit into the transient-persistent + translation of event data. We will not discuss in detail how the + transient data store (e.g. the event data service) or the + persistency service work, but simply look at the flow of data in + order to understand how converters are used. + + .. figure:: images/EventConverters.png + :name: fig-conv + + Persistency conversion services in Gaudi + + An introduction to the persistency mechanism of Gaudi can be found + in reference [LHCB-TALK-2000-003]_. + + One of the issues considered when designing the Gaudi framework was + the capability for users to "create their own data types and save + objects of those types along with references to already existing + objects". A related issue was the possibility of having links + between objects which reside in different stores (i.e. files and + databases) and even between objects in different types of store. + + :numref:`fig-conv` shows that data may be + read from an ODBC database and/or ROOT files into the transient + event data store and that data may be written out again to the same + media. It is the job of the persistency service to orchestrate this + transfer of data between memory and disk. + + The figure shows two "slave" services: the ODBC conversion service + and the ROOT I/O service. These services are responsible for + managing the conversion of objects between their transient and + persistent representations. Each one has a number of converter + objects which are actually responsible for the conversion itself. As + illustrated by the figure a particular converter object converts + between the transient representation and one other form, here either + MS Access or ROOT. + +Collaborators in the conversion process +-------------------------------------------- + + In general the conversion process occurs between the transient + representation of an object and some other representation. In this + chapter we will be using persistent forms, but it should be borne in + mind that this could be any other "transient" form such as those + required for visualisation or those which serve as input into other + packages (e.g. Geant4). + + :numref:`fig-convclassdiag` shows the interfaces + (classes whose name begins with "I") which must be implemented in + order for the conversion process to function + + .. figure:: images/ConversionClassDiag.png + :name: fig-convclassdiag + + The classes (and interfaces) collaborating in the conversion process + + The conversion process is essentially a collaboration between the + following types: + + | · IConversionSvc + | · IConverter + | · IOpaqueAddress + + For each persistent technology, or "non-transient" representation, a + specific conversion service is required. This is illustrated in the + figure by the class AConversionSvc which implements the + IConversionSvc interface. + + A given conversion service will have at its disposal a set of + converters. These converters are both type and technology specific. + In other words a converter knows how to convert a single transient + type (e.g. MuonHit) into a single persistent type (e.g. RootMuonHit) + and vice versa. Specific converters implement the IConverter + interface, possibly by extending an existing converter base class. + + A third collaborator in this process are the opaque address objects. + A concrete opaque address class must implement the IOpaqueAddress + interface. This interface allows the address to be passed around + between the transient data service, the persistency service, and the + conversion services without any of them being able to actually + decode the address. Opaque address objects are also technology + specific. The internals of an OdbcAddress object are different from + those of a RootAddress object. + + Only the converters themselves know how to decode an opaque address. + In other words only converters are permitted to invoke those methods + of an opaque address object which do not form a part of the + IOpaqueAddress interface. + + Converter objects must be "registered" with the conversion service + in order to be usable. For the "standard" converters this will be + done automatically. For user defined converters (for user defined + types) this registration must be done at initialisation time (see + :numref:`data-pers`. + +The conversion process +--------------------------- + + As an example (see :numref:`fig-convtrace`) we + consider a request from the event data service to the persistency + service for an object to be loaded from a data file. + + .. figure:: images/ConversionTrace1.png + :name: fig-convtrace + + A trace of the creation of a new transient object + + As we saw previously, the persistency service has one conversion + service slave for each persistent technology in use. The persistency + service receives the request in the form of an opaque address + object. The svcType() method of the IOpaqueAddress interface is + invoked to decide which conversion service the request should be + passed onto. This returns a "technology identifier" which allows the + persistency service to choose a conversion service. + + The request to load an object (or objects) is then passed onto a + specific conversion service. This service then invokes another + method of the IOpaqueAddress interface, clID(), in order to decide + which converter will actually perform the conversion. The opaque + address is then passed onto the concrete converter who knows how to + decode it and create the appropriate transient object. + + The converter is specific to a specific type, thus it may + immediately create an object of that type with the new operator. The + converter must now "unpack" the opaque address, i.e. make use of + accessor methods specific to the address type in order to get the + necessary information from the persistent store. + + For example, a ZEBRA converter might get the name of a bank from the + address and use that to locate the required information in the ZEBRA + common block. On the other hand a ROOT converter may extract a file + name, the names of a ROOT TTree and an index from the address and + use these to load an object from a ROOT file. The converter would + then use the accessor methods of this "persistent" object in order + to extract the information necessary to build the transient object. + + We can see that the detailed steps performed within a converter + depend very much on the nature of the non-transient data and (to a + lesser extent) on the type of the object being built. + + If all transient objects were independent, i.e. if there were no + references between objects then the job would be finished. However + in general objects in the transient store do contain references to + other objects. + + These references can be of two kinds: + + | i. "Macroscopic" references appear as separate "leaves" in the data store. They have to be registered with a separate opaque address structure in the data directory of the object being converted. This must be done after the object was registered in the data store in the method fillObjRefs(). + | + | ii. Internal references must be handled differently. There are two possibilities for resolving internal references: + | + | 1. Load on demand. If the object the reference points to should only be loaded when accessed, the pointer must no longer be a raw C++ pointer, but rather a smart pointer object containing itself the information for later resolution of the reference. This is the preferred solution for references to objects within the same data store (e.g. references from Monte-Carlo tracks to Monte-Carlo vertices) and is generated by th Object Description Tools when a relation tag is found in the XML class description (see :numref:`data-sref`). + | + | 2. Filling of raw C++ pointers. This is only necessary if the object points to an object in another store, e.g. the detector data store, and should be avoided in classes foreseen to be made persistent. To resolve the reference a converter has to retrieve the other object and set the raw pointer. These references should be set in the fillObjRefs() method. This of course is more complicated, because it must be ensured that both objects are present at the time the reference is accessed (i.e. when the pointer is actually used). + +Converter implementation - general considerations +------------------------------------------------------ + + After covering the ground work in the preceding sections, let us + look exactly what needs to be implemented in a specific converter + class. The starting point is the Converter base class from which a + user converter should be derived. + + .. was 13.1 + + .. code-block:: cpp + :name: lstg-exconfclass + :caption: An example converter class + + // Converter for class UDO. + extern const CLID& CLID_UDO; + extern unsigned char OBJY_StorageType; + static CnvFactory<UDOCnv> s_factory; + const ICnvFactory& UDOCnvFactory = s_factory; + class UDOCnv : public Converter { + + public: + + UDOCnv(ISvcLocator* svcLoc) : Converter( Objectivity_StorageType, + CLID_UDO, + svcLoc) { } + + createRep(DataObject* pO, IOpaqueAddress*& a); // transient->persistent + createObj(IOpaqueAddress* pa, DataObject*& pO); // persistent->transient + fillObjRefs( ... ); // transient->persistent + fillRepRefs( ... ); // persistent->transient + } + + The converter shown in :numref:`lstg-exconfclass` is responsible for the + conversion of UDO type objects into objects that may be stored into + an Objectivity database and vice-versa. The UDOCnv constructor calls + the Converter base class constructor with arguments which contain + this information. These are the values CLID\_UDO, defined in the UDO + class, and Objectivity\_StorageType which is also defined elsewhere. + The first two extern statements simply state that these two + identifiers are defined elsewhere. + + All of the "book-keeping" can now be done by the Converter base + class. It only remains to fill in the guts of the converter. If + objects of type UDO have no links to other objects, then it suffices + to implement the methods createRep() for conversion from the + transient form (to Objectivity in this case) and createObj() for the + conversion to the transient form. + + If the object contains links to other objects then it is also + necessary to implement the methods fillRepRefs() and fillObjRefs(). + +Storing Data using the ROOT I/O Engine +------------------------------------------- + + One possibility for storing data is to use the ROOT I/O engine to + write ROOT files. Although ROOT by itself is not an object oriented + database, with modest effort a structure can be built on top to + allow the Converters to emulate this behaviour. In particular, the + issue of object linking had to be solved in order to resolve + pointers in the transient world. + + The concept of ROOT supporting paged tuples called trees and + branches is adequate for storing bulk event data. Trees split into + one or several branches containing individual leaves with data. + + The data structure within the Gaudi data store is also tree like. In + the transient world Gaudi objects are sub-class instances of the + "DataObject". The DataObject offers some basic functionality like + the implicit data directory which allows e.g. to browse a data + store. This tree structure will be mapped to a flat structure in the + ROOT file resulting in a separate tree representing each leaf of the + data store. Each data tree contains a single branch containing + objects of the same type. The Gaudi tree is split up into individual + ROOT trees in order to give easy access to individual items + represented in the transient model without the need of loading + complete events from the root file i.e. to allow for selective data + retrieval. The feature of ROOT supporting selective data reading + using split trees did not seem too attractive since, generally, + complete nodes in the transient store should be made available in + one go. + + However, ROOT expects "ROOT" objects, they must inherit from + TObject. Therefore the objects from the transient store have to be + converted to objects understandable by ROOT. + + The following sections are an introduction to the machinery provided + by the Gaudi framework to achieve the migration of transient objects + to persistent objects. The ROOT specific aspects are not discussed + here; the ROOT I/O engine is documetned on the ROOT web site + http://root.cern.ch). Note that Gaudi only uses the I/O engine, not + all ROOT classes are available. Within Gaudi the ROOT I/O engine is + implemented in the GaudiRootDb package. + +The Conversion from Transient Objects to ROOT Objects +---------------------------------------------------------- + + As for any conversion of data from one representation to another + within the Gaudi framework, conversion to/from ROOT objects is based + on Converters. The support of a "generic" Converter accesses + pre-defined entry points in each object. The transient object + converts itself to an abstract byte stream. However, for specialized + objects specific converters must be built. + + Whenever objects must change their representation within Gaudi, data + converters are involved. For the ROOT case, the converters must have + some knowledge of ROOT internals and of the service finally used to + migrate ROOT objects (->TObject) to a file. They must be able to + translate the functionality of the DataObject component to/from the + ROOT storage. Within ROOT itself the object is stored as a Binary + Large Object (BLOB). + + The generic data conversion mechanism relies on two functionalities, + which must be present: + + | . When writing or reading objects, the object's data must be "serializable". The corresponding persistent type is of a generic type, the data are stored as a machine independent byte stream. This method is implemented automatically if the class is described using the Gaudi Object Description tools (described in :numref:`data-defi`). + | . When reading objects, an empty object must be created before any de-serialization can take place. The constructor must be called. This functionality does not imply any knowledge of the conversion mechanism itself and hence can be encapsulated into an object factory simply returning a DataObject. These data object factories are distinguished within Gaudi through the persistent data type information, the class ID. For this reason the class ID of objects, which are written must only depend on the object type, i.e. every class needs it's own class ID. The instantiation of the appropriate factory is done by a macro. Please see the RootIO example for details how to instantiate the factory. + +Storing Data using other I/O Engines +----------------------------------------- + + Once objects are stored as BLOBs, it is possible to adopt any + storage technology supporting this datatype. This is the case not + only for ROOT, but also for + + | · Objectivity/DB + | · most relational databases, which support an ODBC interface like + | · Microsoft Access, + | · Microsoft SQL Server, + | · MySQL, + | · ORACLE and others. + + Note that although storing objects using these technologies is + possible, there is currently no implementation available in the + Gaudi release. If you desperately want to use Objectivity or one of + the ODBC databases, please contact Markus Frank + (Markus.Frank@cern.ch). diff --git a/docs/source/old/GDG_DataAccess.rst b/docs/source/old/GDG_DataAccess.rst new file mode 100644 index 0000000000000000000000000000000000000000..2738c0ac8dbd8d55985065f59ad0170f313cd3c5 --- /dev/null +++ b/docs/source/old/GDG_DataAccess.rst @@ -0,0 +1,660 @@ +.. include:: ./global.rst + +|newpage| + +|Gaudi logo| + +.. _chapData: + +Accessing data +================ + +Overview +------------ + + The data stores are a key component in the application framework. + All data which comes from persistent storage, or which is + transferred between algorithms, or which is to be made persistent + must reside within a data store. In this chapter we use a trivial + event data model to look at how to access data within the stores, + and also at the DataObject base class and some container classes + related to it. + + We also cover how to define your own data types and the steps + necessary to save newly created objects to disk files. The writing + of the converters necessary for the latter is covered in `Chapter + 13 <GDG_Converters.html#1010951>`__. + +Using the data stores +------------------------- + + There are four data stores currently implemented within the Gaudi + framework: the event data store, the detector data store, the + histogram store and the n-tuple store. Event data is the subject of + this chapter. The other data stores are described in chapters + :numref:`chapDetd` and :numref:`chapHist` and :numref:`chapNtup` respectively. The stores themselves + are no more than logical constructs with the actual access to the + data being via the corresponding services. Both the event data + service and the detector data service implement the same + IDataProviderSvc interface, which can be used by algorithms to + retrieve and store data. The histogram and n-tuple services + implement extended versions of this interface (IHistogramSvc, + INTupleSvc) which offer methods for creating and manipulating + histograms and n-tuples, in addition to the data access methods + provided by the other two stores. + + Only objects of a type derived from the DataObject base class may be + placed directly within a data store. Within the store the objects + are arranged in a tree structure, just like a Unix file system. As + an example consider :numref:`fig-evtmod` + which shows the trivial transient event data model of the RootIO + example. An object is identified by its position in the tree + expressed as a string such as: "/Event", or "/Event/MyTracks". In + principle the structure of the tree, i.e. the set of all valid + paths, may be deduced at run time by making repeated queries to the + event data service, but this is unlikely to be useful in general + since the structure will be largely fixed. + + .. figure:: images/EventModel.png + :name: fig-evtmod + + The structure the event data model of the RootIO example + + Interactions with the data stores are usually via the + IDataProviderSvc interface, whose key methods are shown in + :numref:`lstg-idataprovsvc`. + + .. was 6.1 + + .. code-block:: cpp + :name: lstg-idataprovsvc + :caption: Some of the key methods of the IDataProviderSvc interface + + StatusCode findObject(const std::string& path, DataObject*& pObject); + StatusCode findObject(DataObject* node, const std::string& path, DataObject*& pObject); + StatusCode retrieveObject(const std::string& path, DataObject*& pObject); + StatusCode retrieveObject(DataObject* node, const std::string& path, DataObject*& pObject); + StatusCode registerObject(const std::string path, DataObject*& pObject); + StatusCode registerObject(DataObject *node, DataObject*& pObject); + + The first four methods are for retrieving a pointer to an object + that is already in the store. How the object got into the store, + whether it has been read in from a persistent store or added to the + store by an algorithm, is irrelevant. + + The find and retrieve methods come in two versions: one version uses + a full path name as an object identifier, the other takes a pointer + to a previously retrieved object and the name of the object to look + for below that node in the tree. + + Additionally the find and retrieve methods differ in one important + respect: the find method will look in the store to see if the object + is present (i.e. in memory) and if it is not will return a null + pointer. The retrieve method, however, will attempt to load the + object from a persistent store (database or file) if it is not found + in memory. Only if it is not found in the persistent data store will + the method return a null pointer (and a bad status code of course). + + Navigation through the tree stucture of the data store is possible + via the IDataManagerSvc interface of the data service, as described + for example in + http://cern.ch/lhcb-comp/Frameworks/Gaudi/Gaudi_v9/Changes_cookbook.pdf. + +Using data objects +---------------------- + + Whatever the concrete type of the object you have retrieved from the + store the pointer which you have is a pointer to a DataObject, so + before you can do anything useful with that object you must cast it + to the correct type, for example: + + .. code-block:: cpp + + typedef ObjectVector<MyTrack> MyTrackVector; + DataObject *pObject; + + StatusCode sc = eventSvc()->retrieveObject("/Event/MyTracks", pObject); + if( sc.isFailure() ) + return sc; + + MyTrackVector *tv = 0; + try { + tv = dynamic_cast<MyTrackVector *> (pObject); + } catch(...) { + // Print out an error message and return + } + // tv may now be manipulated. + + + .. code-block:: cpp + + typedef ObjectVector<MyTrack> MyTrackVector; + DataObject *pObject; + + StatusCode sc = eventSvc()->retrieveObject("/Event/MyTracks", pObject); + if( sc.isFailure() ) + return sc; + + MyTrackVector *tv = 0; + try { + tv = dynamic_cast<MyTrackVector *> (pObject); + } catch(...) { + // Print out an error message and return + } + // tv may now be manipulated. + + + The typedef on line 1 is just to + save typing: in what follows we will use the two syntaxes + interchangeably. After the dynamic\_cast on line + 10 all of the methods of the + MyTrackVector class become available. If the object which is + returned from the store does not match the type to which you try to + cast it, an exception will be thrown. If you do not catch this + exception it will be caught by the algorithm base class, and the + program will stop, probably with an obscure message. A more elegant + way to retrieve the data involves the use of Smart Pointers - this + is discussed in section :numref:`data-smrt`. + + The last two methods shown in :numref:`lstg-idataprovsvc` are for registering objects + into the store. Suppose that an algorithm creates objects of type + UDO from, say, objects of type MyTrack and wishes to place these + into the store for use by other algorithms. Code to do this might + look something like: + + .. was 6.2 + + .. code-block:: cpp + :name: lstg-regobjsevtstore + :caption: Registering of objects into the event data store + + UDO* pO; // Pointer to an object of type UDO (derived from DataObject) + StatusCode sc; + + pO = new UDO; + sc = eventSvc()->registerObject("/Event/tmp","OK", pO); + + // THE NEXT LINE IS AN ERROR, THE OBJECT NOW BELONGS TO THE STORE + delete pO; + + UDO autopO; + // ERROR: AUTOMATIC OBJECTS MAY NOT BE REGISTERED + sc = eventSvc()->registerObject("/Event/tmp", "notOK", autopO); + + Once an object is registered into the store, the algorithm which + created it relinquishes ownership. In other words the object should + not be deleted. This is also true for objects which are contained + within other objects, such as those derived from or instantiated + from the ObjectVector class (see the following section). Furthermore + objects which are to be registered into the store must be created on + the heap, i.e. they must be created with the new operator. + +Object containers +--------------------- + + As mentioned before, all objects which can be placed directly within + one of the stores must be derived from the DataObject class. There + is, however, another (indirect) way to store objects within a store. + This is by putting a set of objects (themselves not derived from + DataObject and thus not directly storable) into an object which is + derived from DataObject and which may thus be registered into a + store. + + An object container base class is implemented within the framework + and a number of templated object container classes may be + implemented in the future. For the moment, two "concrete" container + classes are implemented: ObjectVector<T> and ObjectList<T>. These + classes are based upon the STL classes and provide mostly the same + interface. Unlike the STL containers which are essentially designed + to hold objects, the container classes within the framework contain + only pointers to objects, thus avoiding a lot of memory to memory + copying. + + A further difference with the STL containers is that the type T + cannot be anything you like. It must be a type derived from the + ContainedObject base class, see :numref:`fig-contobj`. In this way all "contained" + objects have a pointer back to their containing object. This is + required, in particular, by the converters for dealing with links + between objects. A ramification of this is that container objects + may not contain other container objects (without the use of multiple + inheritance). + + .. figure:: images/containedObject.png + :name: fig-contobj + + The relationship between the DataObject, ObjectVector and ContainedObjec classes + + As mentioned above, objects which are contained within one of these + container objects may not be located, or registered, individually + within the store. Only the container object may be located via a + call to findObject() or retrieveObject(). Thus with regard to + interaction with the data stores a container object and the objects + that it contains behave as a single object. + + The intention is that "small" objects such as clusters, hits, + tracks, etc. are derived from the ContainedObject base class and + that in general algorithms will take object containers as their + input data and produce new object containers of a different type as + their output. + + The reason behind this is essentially one of optimization. If all + objects were treated on an equal footing, then there would be many + more accesses to the persistent store to retrieve very small + objects. By grouping objects together like this we are able to have + fewer accesses, with each access retrieving bigger objects. + +Using object containers +--------------------------- + + The code fragment below shows the creation of an object container. + This container can contain pointers to objects of type MyTrack and + only to objects of this type (including derived types). An object of + the required type is created on the heap (i.e. via a call to new) + and is added to the container with the standard STL call. + + .. code-block:: cpp + + ObjectVector<MyTrack> trackContainer; + MyTrack* h1 = new MyTrack; + trackContainer.push_back(h1); + + + After the call to push\_back() the MyTrack object "belongs" to the + container. If the container is registered into the store, the hits + that it contains will go with it. Note in particular that if you + delete the container you will also delete its contents, i.e. all of + the objects pointed to by the pointers in the container. + + Removing an object from a container may be done in two semantically + different ways. The difference being whether on removal from a + container the object is also deleted or not. Removal with deletion + may be achieved in several ways (following previous code fragment): + + .. code-block:: cpp + + trackContainer.pop_back(); + trackContainer.erase( end() ); + delete h1; + + The method pop\_back() removes the last element in the container, + whereas erase() maybe used to remove any other element via an + iterator. In the code fragment above it is used to remove the last + element also. + + Deleting a contained object, the third option above, will + automatically trigger its removal from the container. This is done + by the destructor of the ContainedObject base class. + + If you wish to remove an object from the container without + destroying it (the second possible semantic) use the release() + method: + + .. code-block:: cpp + + trackContainer.release(h1); + + Since the fate of a contained object is so closely tied to that of + its container life would become more complex if objects could belong + to more than one container. Suppose that an object belonged to two + containers, one of which was deleted. Should the object be deleted + and removed from the second container, or not deleted? To avoid such + issues an object is allowed to belong to a single container only. + + If you wish to move an object from one container to another, you + must first remove it from one and then add to the other. However, + the first operation is done implicitly for you when you try to add + an object to a second container: + + .. code-block:: cpp + + container1.push_back(h1); // Add to fist container + container2.push_back(h1); // Move to second container, internally invokes release() + + Since the object h1 has a link back to its container, the + push\_back() method is able to first follow this link and invoke the + release() method to remove the object from the first container, + before adding it into the second. + + In general your first exposure to object containers is likely to be + when retrieving data from the event data store. The sample code in + :numref:`lstg-useobjvect` shows how, once you + have retrieved an object container from the store you may iterate + over its contents, just as with an STL vector. + + .. was 6.3 + + .. code-block:: cpp + :name: lstg-useobjvect + :caption: Use of the ObjectVector templated class + + typedef ObjectVector<MyTrack> MyTrackVector; + MyTrackVector* tracks; + MyTrackVector::iterator it; + + for( it = tracks->begin(); it != tracks->end(); it++ ) { + // Get the energy of the track and histogram it + double energy = (*it)->fourMomentum().e(); + m_hEnergyDist->fill( energy, 1. ); + } + + The variable tracks is set to point to an object in the event data + store of type: ObjectVector<MyTrack> with a dynamic cast (not shown + above). An iterator (i.e. a pointer-like object for looping over the + contents of the container) is defined on line 3 and this is used within the loop + to point consecutively to each of the contained objects. In this + case the objects contained within the ObjectVector are of type + "pointer to MyTrack". The iterator returns each object in turn and + in the example, the energy of the object is used to fill a + histogram. + +Data access checklist +------------------------- + + A little reminder: + + | · Do not delete objects that you have registered. + | · Do not delete objects that are contained within an object that you have registered. + | · Do not register local objects, i.e. objects NOT created with the new operator. + | · Do not delete objects which you got from the store via findObject() or retrieveObject(). + | · Do delete objects which you create on the heap, i.e. by a call to new, and which you do not register into a store. + +.. _data-defi: + +Defining Data Objects +------------------------- + + If you want to create a new data object in the transient or + persistent stores of Gaudi, you will have to define the structure of + this object. This structure will be defined by C++-classes. These + classes in general look very similar to each other; mainly they + define the members of the class, which are either data values or + which point to another class (eg. via a Smart Reference - see + :numref:`data-sref`). For each of these + members there is usually a set- and a get-method and some more stuff + for the Smart Reference Vectors. + + The writing of these classes is a tedious task and having to write + this redundant information many times, of course, also bears the + risk of many unnecessary typos. To overcome this problem one may use + XML in conjunction with the GaudiObjDesc package to describe the + data-objects. There were two key issues which led to the development + of this description language: + + | · The core information of a data-object lies in the members of the class, most of the rest is redundant information which can be produced automatically around the members. + | · There is a lot of information which also must be provided, but which has a default-value in most of the cases. + + The information provided in the XML files can be used to produce not + only the object information in the classes but also reflection + information about the objects (see :numref:`serv-refl`). Future + releases may also produce, e.g., converters, or a description of the + object in other languages. + + As an example, the following XML code describes an MCParticle class: + + .. was 6.4 + + .. code-block:: xml + :name: lstg-god + :caption: Part of the XML description of the MCParticle class + + <class name='MCParticle' author='Pavel Binko' id='210' desc='The Monte Carlo particle kinematics information'> + <base name='ContainedObject'/> + <attribute name='subEvtID' type='short' desc='Sub-event ID'/> + <relation name='originMCVertex' multiplicity='1' type='MCVertex' desc='Pointer to origin vertex'/> + <relation name='decayMCVertices' multiplicity='M' type='MCVertex' desc='Vector of pointers to decay vertices'/> + </class> + + All of the elements in this listing (eg. <class>, <attribute>, + <relation>) have several attributes with default values (eg. for + relations and attributes " setMeth='TRUE' "), which don't have to be + mentioned explicitly. If one doesn't want to use the default, the + only thing that has to be done is to set the corresponding attribute + to another value. There are also several hooks which can be applied + eg. to define your own methods if they were not created + automatically. The complete syntax of this description language can + be found on the web at http://cern.ch/lhcb-comp/Frameworks/DataDictionary/. + + Once a set of data-objects is defined, the XML file has to be saved + to the xml directory of the package. The production of the C++ + header files containing the object description can be automated by + adding a line to the CMT requirements file of the package, as shown + for example below: + + .. code-block:: bash + + document obj2doth LHCbEventObj2Doth ../xml/LHCbEvent.xml + + Another possibility is to produce the information by hand with the + tools of the GaudiObjDesc package (eg. GODCppHeaderWriter.exe) and + then compile it. + +The class ID +~~~~~~~~~~~~~~~~~~ + + The class definition on line 1 of :numref:`lstg-god` contains an 'id' + attribute. This class identifier is required if the objects of this + class are to be made persistent. It is used by the data persistency + services to make the translation between the transient and + persistent representations of the object, ising the conversoin + mechanism described in :numref:`chapConv`. + For this mechanism to work, these identifiers must uniquely identify + the class and no two classes may have the same identifier. The + procedure for allocating unique class identifiers is, for the time + being, experiment specific. + + Types which are derived from ContainedObject must have a class ID in + the range of an unsigned short. Contained objects may only reside in + the store when they belong to a container, e.g. an ObjectVector<T> + which is registered into the store. The class identifier of a + concrete object container class is calculated (at run time) from the + type of the objects which it contains, by setting bit 16. + +.. _data-smrt: + +The SmartDataPtr/SmartDataLocator utilities +----------------------------------------------- + + The usage of the data services is simple, but extensive status + checking and other things tend to make the code difficult to read. + It would be more convenient to access data items in the store in a + similar way to accessing objects with a C++ pointer. This is + achieved with smart pointers, which hide the internals of the data + services. + +Using SmartDataPtr/SmartDataLocator objects +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The SmartDataPtr and a SmartDataLocator are smart pointers that + differ by the access to the data store. SmartDataPtr first checks + whether the requested object is present in the transient store and + loads it if necessary (similar to the retrieveObject method of + IDataProviderSvc). SmartDataLocator only checks for the presence of + the object but does not attempt to load it (similar to findObject). + + Both SmartDataPtr and SmartDataLocator objects use the data service + to get hold of the requested object and deliver it to the user. + Since both objects have similar behaviour and the same user + interface, in the following only the SmartDataPtr is discussed. + + An example use of the SmartDataPtr class is shown in :numref:`lstg-usesmartdataptr`. + + .. was 6.5 + + .. code-block:: cpp + :name: lstg-usesmartdataptr + :caption: Use of a SmartDataPtr object + + StatusCode myAlgo::execute() { + MsgStream log(msgSvc(), name()); + SmartDataPtr<Event> evt(eventSvc(), "/Event"); + if ( evt ) { + log << MSG::INFO << " Run:" << evt->run() + << " Event:" << evt->event() << endreq; // Print the event number + } + else { + log << MSG::ERROR << "Error accessing event" << endreq; + return StatusCode::FAILURE; + } + } + + The SmartDataPtr class can be thought of as a normal C++ pointer + having a constructor. It is used in the same way as a normal C++ + pointer. + + The SmartDataPtr and SmartDataLocator offer a number of possible + constructors and operators to cover a wide range of needs when + accessing data stores. Check the online reference documentation + [GAUDI-DOXY]_ for up-to date information + concerning the interface of these utilities. + +.. _data-sref: + +Smart References and Smart Reference Vectors +------------------------------------------------ + + It is foreseen that data objects in the transient data stores can + reference other objects in the same data store. This relationship + can be described in the XML data description using the 'relation' + attribute of the class definition, as shown on line + 4 of :numref:`lstg-god`. + + The current implementation of these relationships use 'Smart + References' and 'Smart Reference Vectors'. These are similar to + smart pointers, they provide safe data access and automate the + loading on demand of referenced data, and are used instead of C++ + pointers. For example, suppose that MCParticles are already loaded + but MCVertices are not, and that an algorithm dereferences a + variable pointing to the origin vertex: if a smart reference is + used, the MCVertices would be loaded automatically and only after + that would the variable be dereferenced. If a C++ plain pointer were + used instead, the program would crash. Smart references provide an + automatic conversion to a pointer to the object and load the object + from the persistent medium during the conversion process. + + The XML code in :numref:`lstg-god` will + generate Smart Reference and Smart Reference Vector declarations as + shown below: + + .. code-block:: cpp + + #include "GaudiKernel/SmartRef.h" + #include "GaudiKernel/SmartRefVector.h" + + class MCParticle { + private: + + /// Smart reference to origin vertex + SmartRef<MCVertex> m_originMCVertex; + /// Vector of smart references to decay vertices + SmartRefVector<MCVertex> m_decayMCVertices; + + public: + + /// Access the origin Vertex + /// Note: When the smart reference is converted to MCVertex* the object + /// will be loaded from the persistent medium. + MCVertex* originMCVertex() { return m_originMCVertex; } + }; + + The syntax of usage of smart references is identical to plain C++ + pointers. The Algorithm only sees a pointer to the MCVertex object: + + .. code-block:: cpp + + #include "GaudiKernel/SmartDataPtr.h" + // Use a SmartDataPtr to get the MC particles from the event store + SmartDataPtr<MCParticleVector> particles(eventSvc(), "/Event/MC/MCParticles"); + MCParticleVector::const_iterator iter; + // Loop over the particles to access the MCVertex via the SmartRef + for( iter = particles->begin(); iter != particles->end(); iter++ ) { + MCVertex* originVtx = (* iter)->originMCVertex(); + if( 0 != originVtx ) { + std::cout << "Origin vertex = " << *(*iter) << std::endl; + } + } + + SmartRef offers a number of possible constructors and operators, see + the online reference documentation [GAUDI-DOXY]_. + +.. _data-pers: + +Persistent storage of data +------------------------------- + +.. _data-save: + +Saving event data to a persistent store +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Suppose that you have defined your own data type as discussed in + section :numref:`data-defi`. Suppose futhermore + that you have an algorithm which creates instances of your object + type which you then register into the transient event store. How can + you save these objects for use at a later date? + + You must do the following: + + | · Write the appropriate converter (see :numref:`chapConv`) + | · Put some instructions (i.e. options) into the job option file (see :numref:`lstg-optsoutsto`) + | · Register your object in the store us usual, typically in the execute() method of your algorithm. + + .. code-block:: cpp + + // myAlg implementation file + StatusCode myAlg::execute() { + // Create a UDO object and register it into the event data store + UDO* p = new UDO(); + eventSvc->registerObject("/Event/myStuff/myUDO", p); + } + + | + + In order to actually trigger the conversion and saving of the + objects at the end of the current event processing it is necessary + to inform the application manager. This requires some options to be + specified in the job options file: + + .. was 6.6 + + .. code-block:: cpp + :name: lstg-optsoutsto + :caption: Job options for output to persistent storage + + ApplicationMgr.OutStream = { "DstWriter" }; + DstWriter.ItemList = { "/Event#1", "/Event/MyTracks#1"}; + DstWriter.EvtDataSvc = "EventDataSvc"; + DstWriter.Output = "DATAFILE='RootDst.root' TYP='ROOT'"; + ApplicationMgr.DLLs += { "GaudiDb", "GaudiRootDb"}; + ApplicationMgr.ExtSvc += { "DbEventCnvSvc/RootEvtCnvSvc" }; + EventPersistencySvc.CnvServices += { "RootEvtCnvSvc" }; + RootEvtCnvSvc.DbType = "ROOT"; + + The first option tells the application manager that you wish to + create an output stream called "DstWriter". You may create as many + output streams as you like and give them whatever name you prefer. + + For each output stream object which you create you must set several + properties. The ItemList option specifies the list of paths to the + objects which you wish to write to this output stream. The number + after the "#" symbol denotes the number of directory levels below + the specified path which should be traversed. The (optional) + EvtDataSvc option specifies in which transient data service the + output stream should search for the objects in the ItemList, the + default is the standard transient event data service EventDataSvc. + The Output option specifies the name of the output data file and the + type of persistency technology, ROOT in this example. The last three + options are needed to tell the Application manager to instantiate + the RootEvtCnvSvc and to associate the ROOT persistency type to this + service. + + An example of saving data to a ROOT persistent data store is + available in the RootIO example distributed with the framework. + +.. _data-redp: + +Reading event data from a persistent store +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Suppose you want to read back the file written out in the previous + section. To do this, your job options would look something like + those described in :numref:`star-jobi`. diff --git a/docs/source/old/GDG_DetDescription.rst b/docs/source/old/GDG_DetDescription.rst new file mode 100644 index 0000000000000000000000000000000000000000..c0bb719f289a252895b0d9f4ed636045971bcb5f --- /dev/null +++ b/docs/source/old/GDG_DetDescription.rst @@ -0,0 +1,54 @@ +.. include:: ./global.rst + +|newpage| + +|Gaudi logo| + +.. _chapDetd: + +Detector Description +====================== + +Overview +------------ + + This chapter is a place holder for documenting how to access the + detector description data in the Gaudi transient detector data + store. A detector description implementation based on XML exists in + the LHCb extensions to Gaudi [Chytracek:2000]_ but it is not distributed with the + framework. + + The Gaudi architecture aims to shield the applications from the + details of the persistent detector description and calibration + databases. Ideally, the detector will be described in a logically + unique detector description database (DDDB), containing data from + many sources (e.g. editors and CAD tools for geometry data, + calibration and alignment programs, detector control system for + environmental data) as shown in :numref:`fig-detdesc`. The job of the Gaudi + detector data service is to populate the transient detector data + store with a snapshot of the detector description, which is valid + for the event currently being analysed. Conversion services can be + invoked to provide different transient representations of the same + persistent data, appropriate to the specific application. For + example, detector simulation, reconstruction and event display all + require a geometry description of the detector, but with different + levels of detail. In the Gaudi architecture it is possible to have a + single, generic, persistent geometry description, from which a set + of different representations can be extracted and made available to + the data processing applications.. + + The LHCb implementation of the detector description database + describes the logical structure of the detector in terms of a + hierarchy of detector elements and the basic geometry in terms of + volumes, solids and materials, and provides facilities for + customizing the generic description to many specific detector needs. + This should allow to develop detector specific code which can + provide geometry answers to questions from the physics algorithms. + The persistent representation of the LHCb detector description is + based on text files in XML format. An XML editor that understands + the detector description semantics has been developed. + + .. figure:: images/GDG_DetDescriptiona.png + :name: fig-detdesc + + Overview of the Detector Description model diff --git a/docs/source/old/GDG_EventData.rst b/docs/source/old/GDG_EventData.rst new file mode 100644 index 0000000000000000000000000000000000000000..c8553069fbea75ea9a4572e29c5a2ac9e295f733 --- /dev/null +++ b/docs/source/old/GDG_EventData.rst @@ -0,0 +1,16 @@ +.. include:: ./global.rst + +|newpage| + +|Gaudi logo| + +.. _chapEven: + +Event Data +============ + +Overview +------------ + + This chapter is a place holder for documenting the experiment + specific event data models. diff --git a/docs/source/old/GDG_Histogram.rst b/docs/source/old/GDG_Histogram.rst new file mode 100644 index 0000000000000000000000000000000000000000..4c6821f18fba4493961207fdfddf5d62c7e4b826 --- /dev/null +++ b/docs/source/old/GDG_Histogram.rst @@ -0,0 +1,206 @@ +.. include:: ./global.rst + +|newpage| + +|Gaudi logo| + +.. _chapHist: + +Histogram facilities +====================== + +Overview +------------ + + The histogram data store is one of the data stores discussed in + :numref:`chapArch`. Its purpose is to + store statistics based data and user created objects that have a + lifetime of more than a single event (e.g. histograms). + + As with the other data stores, all access to data is via a service + interface. In this case it is via the IHistogramSvc interface, which + is derived from the IDataProviderSvc interface discussed in `Chapter + 6 <GDG_DataAccess.html#1010951>`__. The user asks the Histogram + Service to book a histogram and register it in the histogram data + store. The service returns a pointer to the histogram, which can + then be used to fill and manipulate the histogram, using the methods + defined in the IHistogram1D and IHistogram2D interfaces and + documented on the AIDA (Abstract Interfaces for Data Analysis) + project web pages: http://wwwinfo.cern.ch/asd/lhc++/AIDA/. + + Internally, Gaudi uses the transient part of HTL (Histogram Template + Library, http://wwwinfo.cern.ch/asd/lhc++/HTL/) to implement + histograms. + +The Histogram service +------------------------- + + An instance of the histogram data service is created by the + application manager. After the service has been initialised, the + histogram data store will contain a root directory, always called + "/stat", in which users may book histograms and/or create + sub-directories (for example, in the code fragment below, the + histogram is stored in the subdirectory "/stat/simple"). A suggested + naming convention for the sub-directories is given in + :numref:`over-name`. Note that the string + "/stat/" can be omitted when referring to a histogram in the data + store: "/stat/simple" is equivalent to "simple", without a leading + "/". + + As discussed in :numref:`algo-base`, the + Algorithm base class defines a member function which returns a + pointer to the IHistogramSvc interface of the standard histogram + data service + + .. code-block:: cpp + + IHistogramSvc* histoSvc() + + + . Access to any other non-standard histogram data service (if one + exists) must be sought via the ISvcLocator interface of the + application manager as discussed in section :numref:`serv-requ`. + +Using histograms and the histogram service +---------------------------------------------- + + The code fragment below shows how to book a 1D histogram and place + it in a directory within the histogram data store, followed by a + simple statement which fills the histogram. + + .. code-block:: cpp + + #include "AIDA/IHistogram1d.h" + // ... + + // Book 1D histogram in the histogram data store + IHistogram1d* m_hTrackCount= histoSvc()-> + book( "simple", 1, "TrackCount", 100, 0., 3000. ); + SmartDataPtr<MyTrackVector> particles( eventSvc(), "/Event/MyTracks" ) + if ( 0 != particles ) { + m_hTrackCount->fill(particles->size(), 1.); // Filling the track count histogram + } + + The parameters of the book function are the directory in which to + store the histogram in the data store, the histogram identifier, the + histogram title, the number of bins and the lower and upper limits + of the X axis. 1D histograms with fixed and variable binning are + available. In the case of 2D histograms, the book method requires in + addition the number of bins and lower and upper limits of the Y + axis. + + If using HBOOK for persistency, the histogram identifier should be a + valid HBOOK histogram identifier (number) and must be unique within + the RZ directory the histogram is assigned to. The name of the RZ + directory is given by the directory and parent directories in the + transient histogram store. Please note that HBOOK accepts only + directory names, which are shorter than 16 characters and that HBOOK + internally converts any directory name into upper case. Even if + using another persistency solution (e.g. ROOT) it is recommended to + comply with the HBOOK constraints in order to make the code + independent of the persistency choice. + + The call to histoSvc()->book(...) returns a pointer to an object of + type IHistogram1D (or IHistogram2D in the case of a 2D histogram). + All the methods of this interface can be used to further manipulate + the histogram, and in particular to fill it, as shown in the + example. Note that this pointer is guaranteed to be non-null, the + algorithm would have failed the initialisation step if the histogram + data service could not be found. On the contrary the user variable + particles may be null (in case of absence of tracks in the transient + data store and in the persistent storage), and the fill statement + would fail - so the value of particles must be checked before using + it. + + Algorithms that create histograms will in general keep pointers to + those histograms, which they may use for filling operations. However + it may be that you wish to share histograms between different + algorithms. Maybe one algorithm is responsible for filling the + histogram and another algorithm is responsible for fitting it at the + end of the job. In this case it may be necessary to look for + histograms within the store. The mechanism for doing this is + identical to the method for locating event data objects within the + event data store, namely via the use of smart pointers, as discussed + in section :numref:`data-smrt`. + + .. code-block:: cpp + + SmartDataPtr<IHistogram1D> hist1D( histoSvc(), "simple/1" ); + if( 0 != hist1D ) { + histoSvc()->print( hist1D ); // Print the found histogram + } + +.. _hist-stor: + +Persistent storage of histograms +------------------------------------ + + By default, Gaudi does not produce a persistent histogram output. + The options exist to write out histograms either in HBOOK or in ROOT + format. The choice is made by giving the job option + ApplicationMgr.HistogramPersistency, which can take the values + "NONE" (no histograms saved, default), "HBOOK" or "ROOT". Depending + on the choice, additional job options are needed, as described + below. + +HBOOK persistency +~~~~~~~~~~~~~~~~~~~~~~~ + + The HBOOK conversion service converts objects of types IHistogram1D + and IHistogram2D into a form suitable for storage in a standard + HBOOK file. In order to use it you first need to tell Gaudi where to + find the HbookCnv shared library. If you are using CMT, this is done + by adding the following line to the CMT requirements file: + + .. code-block:: bash + + use HbookCnv v* + + | You then have to tell the application manager to load this shared library and to create the HBOOK conversion service, by adding the following lines to your job options file: + + .. code-block:: cpp + + ApplicationMgr.DLLs += {"HbookCnv"}; + ApplicationMgr.HistogramPersistency = "HBOOK"; + + Finally, you have to tell the histogram persistency service the name + of the output file: + + .. code-block:: cpp + + HistogramPersistencySvc.OuputFile = "histo.hbook"; + + Note that it is also possible to print the histograms to the + standard output destination (HISTDO) by setting the following job + option (default is false). + + .. code-block:: cpp + + HistogramPersistencySvc.PrintHistos = true; + +ROOT persistency +~~~~~~~~~~~~~~~~~~~~~~ + + The ROOT conversion service converts objects of types IHistogram1D + and IHistogram2D into a form suitable for storage in a standard ROOT + file. In order to use it you first need to tell Gaudi where to find + the RootHistCnv shared library. If you are using CMT, this is done + by adding the following line to the CMT requirements file: + + .. code-block:: bash + + use RootHistCnv v* + + | You then have to tell the application manager to load this shared library and to create the ROOT histograms conversion service, by adding the following lines to your job options file: + + .. code-block:: cpp + + ApplicationMgr.DLLs += {"RootHistCnv"}; + ApplicationMgr.HistogramPersistency = "ROOT"; + + Finally, you have to tell the histogram persistency service the name + of the output file: + + .. code-block:: cpp + + HistogramPersistencySvc.OuputFile = "histo.rt"; diff --git a/docs/source/old/GDG_IX.rst b/docs/source/old/GDG_IX.rst new file mode 100644 index 0000000000000000000000000000000000000000..1bd60dc818f865579e13ff0ad5c9db9ae373de1b --- /dev/null +++ b/docs/source/old/GDG_IX.rst @@ -0,0 +1,560 @@ +.. include:: ./global.rst + +|newpage| + +|Gaudi logo| + +.. _chapIx: + +IndexTable +========== + + **` <#IX_A>`__** + + A - `B <#IX_B>`__ - `C <#IX_C>`__ - `D <#IX_D>`__ - `E <#IX_E>`__ - + `F <#IX_F>`__ - `G <#IX_G>`__ - `H <#IX_H>`__ - `I <#IX_I>`__ - + `J <#IX_J>`__ - `K <#IX_K>`__ - `L <#IX_L>`__ - `M <#IX_M>`__ - + `N <#IX_N>`__ - `O <#IX_O>`__ - `P <#IX_P>`__ - `Q <#IX_Q>`__ - + `R <#IX_R>`__ - `S <#IX_S>`__ - `T <#IX_T>`__ - `U <#IX_U>`__ - + `V <#IX_V>`__ - `W <#IX_W>`__ - `X <#IX_X>`__ - `Y <#IX_Y>`__ - + `Z <#IX_Z>`__ + + | Index + +Symbols +------- + + , `1 <GDG_Installation.html#1066509>`__ + +A +- + + AIDA, `1 <GDG_Utilities.html#1138664>`__, `see Interfaces <GDG_Histogram.html#1041156>`__, `1 <GDG_Histogram.html#1041156>`__ + + Algorithm, `1 <GDG_Architecture.html#1029978>`__ + + Base class, `1 <GDG_Architecture.html#1032018>`__, `2 <GDG_Algorithms.html#1061344>`__ + + branches, `1 <GDG_Algorithms.html#1065537>`__ + + Concrete, `1 <GDG_Algorithms.html#1030770>`__, `2 <GDG_Algorithms.html#1031111>`__ + + Constructor, `1 <GDG_Algorithms.html#1030339>`__, `2 <GDG_Algorithms.html#1031179>`__ + + Declaring properties, `1 <GDG_Algorithms.html#1031545>`__ + + Execution, `1 <GDG_Starting.html#1039064>`__, `2 <GDG_Algorithms.html#1088697>`__ + + Filters, `1 <GDG_Algorithms.html#1065537>`__ + + Finalisation, `1 <GDG_Starting.html#1052133>`__, `2 <GDG_Algorithms.html#1086966>`__ + + Initialisation, `1 <GDG_Starting.html#1153084>`__, `2 <GDG_Algorithms.html#1065884>`__, `3 <GDG_Algorithms.html#1031666>`__, `4 <GDG_Algorithms.html#1086966>`__ + + Nested, `1 <GDG_Algorithms.html#1029897>`__ + + sequences, `1 <GDG_Algorithms.html#1065537>`__ + + Setting properties, `1 <GDG_Algorithms.html#1031545>`__ + + Algorithms + + EventCounter, `1 <GDG_Algorithms.html#1088479>`__, `2 <GDG_Services.html#1109396>`__ + + Prescaler, `1 <GDG_Algorithms.html#1088479>`__ + + Sequencer, `1 <GDG_Algorithms.html#1086836>`__ + + Application Manager, `1 <GDG_Architecture.html#1031230>`__ + + instantiation, `1 <GDG_Starting.html#1033539>`__ + + `ApplicationMgr. See Application Manager <GDG_Starting.html#1033539>`__\ `1 <GDG_Starting.html#1033539>`__ + + Architecture, `1 <GDG_Architecture.html#1029959>`__ + + Associators, `1 <GDG_Tools.html#1109260>`__ + + Example, `1 <GDG_Tools.html#1109285>`__ + +B +- + + Branches, `1 <GDG_Algorithms.html#1065537>`__ + +C +- + + Casting + + of DataObjects, `1 <GDG_DataAccess.html#1030820>`__ + + Changes + + in the new release, `1 <GDG_Installation.html#1066509>`__ + + incompatible in release v7, `1 <GDG_Installation.html#1166571>`__ + + incompatible in release v8, `1 <GDG_Installation.html#1166676>`__ + + incompatible in release v9, `1 <GDG_Installation.html#1175603>`__ + + `see also Deprecated Features <GDG_Installation.html#1066509>`__\ `1 <GDG_Installation.html#1066509>`__ + + Checklist + + for implementing algorithms, `1 <GDG_Algorithms.html#1060441>`__ + + Class + + identifier (CLID), `1 <GDG_DataAccess.html#1055556>`__ + + CLHEP, `1 <GDG_Utilities.html#1048757>`__ + + Units, `1 <GDG_Overview.html#1052502>`__ + + CMT + + Building libraries with, `1 <GDG_Libraries.html#1127472>`__ + + Component, `1 <GDG_Architecture.html#1029959>`__, `2 <GDG_Libraries.html#1128448>`__ + + libraries, `1 <GDG_Libraries.html#1128388>`__, `2 <GDG_Libraries.html#1128422>`__ + + ContainedObject, `1 <GDG_DataAccess.html#1045638>`__ + + Conventions, `1 <GDG_Overview.html#1030010>`__ + + Coding, `1 <GDG_Overview.html#1086230>`__ + + Naming, `1 <GDG_Overview.html#1062165>`__ + + Units, `1 <GDG_Overview.html#1052502>`__ + + used in this this document, `1 <GDG_Overview.html#1086885>`__ + + Converters, `1 <GDG_Converters.html#1010951>`__ + + CVS + + password, `1 <GDG_Installation.html#1162621>`__ + +D +- + + Data Store, `1 <GDG_DataAccess.html#1029881>`__ + + finding objects in, `1 <GDG_DataAccess.html#1044646>`__, `2 <GDG_DataAccess.html#1076735>`__ + + Histograms, `1 <GDG_Histogram.html#1040450>`__ + + registering objects into, `1 <GDG_DataAccess.html#1030843>`__ + + DataObject, `1 <GDG_Architecture.html#1031677>`__, `2 <GDG_DataAccess.html#1031169>`__, `3 <GDG_DataAccess.html#1030820>`__, `4 <GDG_DataAccess.html#1030283>`__ + + Defining, `1 <GDG_DataAccess.html#1165938>`__ + + ownership, `1 <GDG_DataAccess.html#1032046>`__ + + DECLARE\_ALGORITHM, `1 <GDG_Libraries.html#1189540>`__ + + DECLARE\_FACTORY\_ENTRIES, `1 <GDG_Libraries.html#1189539>`__ + + Deprecated Features, `1 <GDG_Installation.html#1145364>`__ + +E +- + + endreq, MsgStream manipulator, `1 <GDG_Services.html#1061832>`__ + + Event Collections, `1 <GDG_Ntuple.html#1148342>`__ + + Filling, `1 <GDG_Ntuple.html#1080033>`__ + + Reading Events with, `1 <GDG_Ntuple.html#1082356>`__ + + Writing, `1 <GDG_Ntuple.html#1082353>`__ + + `EventCounter algorithm. See Algorithms <GDG_Algorithms.html#1088479>`__\ `1 <GDG_Algorithms.html#1088479>`__ + + Example Application + + Main program, `1 <GDG_Starting.html#1036193>`__ + + Trace of execution, `1 <GDG_Starting.html#1039951>`__ + + Examples + + Associator, `1 <GDG_Tools.html#1109285>`__ + + distributed with Gaudi, `1 <GDG_Starting.html#1078217>`__ + + HelloWorld, `1 <GDG_Starting.html#1032543>`__ + + Exception + + when casting, `1 <GDG_DataAccess.html#1030410>`__ + +F +- + + Factory + + for a concrete algorithm, `1 <GDG_Algorithms.html#1030420>`__ + + Filters, `1 <GDG_Algorithms.html#1065537>`__ + + FORTRAN, `1 <GDG_Architecture.html#1029978>`__ + + and shareable libraries, `1 <GDG_Libraries.html#1128844>`__ + +G +- + + GEANT4 + + units, `1 <GDG_Overview.html#1052502>`__ + + getFactoryEntries, `1 <GDG_Libraries.html#1128073>`__ + + Guidelines + + for software packaging, `1 <GDG_Libraries.html#1189969>`__ + +H +- + + HBOOK + + Constraints on histograms, `1 <GDG_Histogram.html#1058840>`__ + + For histogram persistency, `1 <GDG_Histogram.html#1039939>`__ + + Limitations on N-tuples, `1 <GDG_Ntuple.html#1048965>`__, `2 <GDG_Ntuple.html#1050067>`__, `3 <GDG_Ntuple.html#1199302>`__ + + Histograms + + data service, `1 <GDG_Histogram.html#1142755>`__ + + HTL, `1 <GDG_Utilities.html#1098909>`__ + + Naming convention for, `1 <GDG_Overview.html#1062211>`__ + + Persistency service, `1 <GDG_Histogram.html#1039938>`__ + + HTL, `1 <GDG_Utilities.html#1098909>`__ + +I +- + + Inheritance, `1 <GDG_Algorithms.html#1030770>`__ + + Installation + + of the framework, `1 <GDG_Installation.html#1166069>`__ + + Outside CERN, `1 <GDG_Installation.html#1175723>`__ + + Interactive Analysis + + of N-tuples, `1 <GDG_Ntuple.html#1078401>`__ + + Interface, `1 <GDG_Architecture.html#1029959>`__ + + and multiple inheritance, `1 <GDG_Architecture.html#1031393>`__ + + Identifier, `1 <GDG_Architecture.html#1031393>`__, `2 <GDG_Libraries.html#1130046>`__ + + In C++, `1 <GDG_Architecture.html#1030062>`__ + + Interfaces + + AIDA, `1 <GDG_Histogram.html#1041156>`__, `2 <GDG_Utilities.html#1138664>`__ + + IAlgorithm, `1 <GDG_Architecture.html#1032897>`__, `2 <GDG_Algorithms.html#1030322>`__, `3 <GDG_Algorithms.html#1030881>`__, `4 <GDG_Algorithms.html#1030526>`__ + + IAlgTool, `1 <GDG_Tools.html#1110386>`__ + + IAppMgrUI, `1 <GDG_Starting.html#1037327>`__ + + IAssociator, `1 <GDG_Tools.html#1110561>`__ + + IAuditor, `1 <GDG_Services.html#1108964>`__ + + IConversionSvc, `1 <GDG_Converters.html#1095037>`__ + + IConverter, `1 <GDG_Converters.html#1053186>`__ + + IDataManagerSvc, `1 <GDG_Architecture.html#1031230>`__, `2 <GDG_DataAccess.html#1167674>`__ + + IDataProviderSvc, `1 <GDG_Architecture.html#1031230>`__, `2 <GDG_DataAccess.html#1030728>`__, `3 <GDG_DataAccess.html#1033265>`__, `4 <GDG_Ntuple.html#1080234>`__ + + IDataProvideSvc, `1 <GDG_Histogram.html#1041156>`__ + + IHistogram1D, `1 <GDG_Histogram.html#1041156>`__ + + IHistogram2D, `1 <GDG_Histogram.html#1041156>`__ + + IHistogramSvc, `1 <GDG_Architecture.html#1031357>`__, `2 <GDG_DataAccess.html#1030728>`__, `3 <GDG_Histogram.html#1041156>`__ + + IIncidentListener, `1 <GDG_Services.html#1108563>`__ + + IMessageSvc, `1 <GDG_Architecture.html#1031296>`__ + + in Gaudi, `1 <GDG_Libraries.html#1129999>`__ + + INTupleSvc, `1 <GDG_DataAccess.html#1030728>`__, `2 <GDG_Ntuple.html#1080234>`__ + + INtupleSvc, `1 <GDG_Architecture.html#1031357>`__ + + IOpaqueAddress, `1 <GDG_Converters.html#1053187>`__ + + IParticlePropertySvc, `1 <GDG_Services.html#1062125>`__ + + IProperty, `1 <GDG_Architecture.html#1031205>`__, `2 <GDG_Starting.html#1037327>`__, `3 <GDG_Algorithms.html#1030322>`__ + + IRunable, `1 <GDG_Architecture.html#1163823>`__ + + ISvcLocator, `1 <GDG_Algorithms.html#1030343>`__ + + IToolSvc, `1 <GDG_Tools.html#1093151>`__ + + Navigating between, `1 <GDG_Libraries.html#1130061>`__ + + Introspection, `1 <GDG_Services.html#1173950>`__ + +J +- + + Job Options + + `see also Properties <GDG_Services.html#1175245>`__\ `1 <GDG_Services.html#1175245>`__ + + Job options, `1 <GDG_Services.html#1175245>`__ + +L +- + + Libraries + + Building, `1 <GDG_Libraries.html#1127472>`__ + + Building, with CMT, `1 <GDG_Libraries.html#1127472>`__ + + Component, `1 <GDG_Libraries.html#1128388>`__, `2 <GDG_Libraries.html#1128422>`__ + + containing FORTRAN code, `1 <GDG_Libraries.html#1128844>`__ + + Linker, `1 <GDG_Libraries.html#1127467>`__ + + Linux, `1 <GDG_Installation.html#1161562>`__ + + LOAD\_FACTORY\_ENTRIES, `1 <GDG_Libraries.html#1189600>`__ + +M +- + + Message service, `1 <GDG_Services.html#1089928>`__ + + Monitoring + + of algorithm calls, with the Auditor service, `1 <GDG_Services.html#1108930>`__ + + statistical, using the Chrono&stat service, `1 <GDG_Services.html#1069852>`__ + + Monte Carlo truth + + navigation using Associators, `1 <GDG_Tools.html#1109260>`__ + +N +- + + NAG C, `1 <GDG_Utilities.html#1138672>`__ + + N-tuples, `1 <GDG_Ntuple.html#1040441>`__ + + Booking and declaring tags, `1 <GDG_Ntuple.html#1200309>`__ + + filling, `1 <GDG_Ntuple.html#1050097>`__ + + Interactive Analysis of, `1 <GDG_Ntuple.html#1078401>`__ + + Limitations imposed by HBOOK, `1 <GDG_Ntuple.html#1048965>`__, `2 <GDG_Ntuple.html#1050067>`__, `3 <GDG_Ntuple.html#1199302>`__ + + persistency, `1 <GDG_Ntuple.html#1081988>`__, `2 <GDG_Ntuple.html#1148483>`__ + + reading, `1 <GDG_Ntuple.html#1080430>`__ + + Service, `1 <GDG_Ntuple.html#1041162>`__ + +O +- + + Object Container, `1 <GDG_DataAccess.html#1030514>`__ + + and STL, `1 <GDG_DataAccess.html#1045261>`__ + + ObjectList, `1 <GDG_DataAccess.html#1045261>`__ + + ObjectVector, `1 <GDG_DataAccess.html#1045261>`__ + +P +- + + Package, `1 <GDG_Libraries.html#1127896>`__ + + Internal layout, `1 <GDG_Libraries.html#1127433>`__ + + structure of LHCb software, `1 <GDG_Libraries.html#1127896>`__ + + Packages + + Dependencies of Gaudi, `1 <GDG_Libraries.html#1127896>`__ + + Guidelines, `1 <GDG_Libraries.html#1189969>`__ + + PAW + + for N-Tuple analysis, `1 <GDG_Ntuple.html#1200612>`__ + + Persistency + + of histograms, `1 <GDG_Histogram.html#1039938>`__ + + of N-tuples, `1 <GDG_Ntuple.html#1081988>`__, `2 <GDG_Ntuple.html#1148483>`__ + + Persistent store + + saving data to, `1 <GDG_DataAccess.html#1165790>`__ + + Platform + + Available platforms, `1 <GDG_Installation.html#1176618>`__ + + Platforms + + on which Gaudi is supported, `1 <GDG_Installation.html#1176618>`__ + + `Prescaler algorithm. See Algorithms <GDG_Algorithms.html#1088479>`__\ `1 <GDG_Algorithms.html#1088479>`__ + + Problems + + Reporting, `1 <GDG_Overview.html#1052468>`__ + + Profiling + + of execution time, using the Chrono&Stat service, `1 <GDG_Services.html#1069813>`__ + + of execution time, with the Auditor service, `1 <GDG_Services.html#1108931>`__ + + of memory usage, with the Auditor service, `1 <GDG_Services.html#1108932>`__ + + Properties + + Accessing and Modifying, `1 <GDG_Services.html#1173740>`__ + + Python, `1 <GDG_Scripting.html#1010951>`__ + + Python scripts + + file extension for, `1 <GDG_Scripting.html#1321423>`__ + +R +- + + Random numbers + + generating, `1 <GDG_Services.html#1085701>`__ + + Service, `1 <GDG_Services.html#1085701>`__ + + Release notes, `1 <GDG_Installation.html#1166069>`__ + + Reporting problems, `1 <GDG_Overview.html#1052468>`__ + + Retrieval, `1 <GDG_Tools.html#1093151>`__ + + ROOT, `1 <GDG_Utilities.html#1098881>`__ + + for histogram persistency, `1 <GDG_Histogram.html#1134504>`__ + + for N-Tuple analysis, `1 <GDG_Ntuple.html#1200615>`__, `2 <GDG_Ntuple.html#1148571>`__ + +S +- + + Saving data, `1 <GDG_DataAccess.html#1165790>`__ + + `Sequencer algorithm. See Algorithms <GDG_Algorithms.html#1086836>`__\ `1 <GDG_Algorithms.html#1086836>`__ + + Sequences, `1 <GDG_Algorithms.html#1065537>`__ + + Services, `1 <GDG_Architecture.html#1031159>`__ + + Auditor Service, `1 <GDG_Services.html#1108927>`__ + + Chrono&Stat service, `1 <GDG_Services.html#1058569>`__ + + Histogram data service, `1 <GDG_Histogram.html#1142755>`__ + + Histogram Persistency Services, `1 <GDG_Histogram.html#1039938>`__ + + Incident service, `1 <GDG_Services.html#1106308>`__ + + Introspection service, `1 <GDG_Services.html#1173950>`__ + + Job Options service, `1 <GDG_Services.html#1175245>`__ + + Message Service, `1 <GDG_Services.html#1089928>`__ + + N-tuples Service, `1 <GDG_Ntuple.html#1041162>`__ + + Particle Properties Service, `1 <GDG_Services.html#1061641>`__ + + Random numbers service, `1 <GDG_Services.html#1085701>`__ + + requesting and accessing, `1 <GDG_Services.html#1108864>`__ + + ToolSvc, `1 <GDG_Tools.html#1094308>`__, `2 <GDG_Tools.html#1092938>`__ + + vs. Tools, `1 <GDG_Tools.html#1090035>`__ + + SmartDataLocator, `1 <GDG_DataAccess.html#1076735>`__ + + SmartDataPtr, `1 <GDG_DataAccess.html#1076735>`__ + + SmartRef, `1 <GDG_DataAccess.html#1064634>`__ + + Sripting, `1 <GDG_Scripting.html#1010951>`__ + + StatusCode, `1 <GDG_Algorithms.html#1088697>`__ + +T +- + + Tools, `1 <GDG_Tools.html#1094308>`__ + + Associators, `1 <GDG_Tools.html#1109260>`__ + + provided in Gaudi, `1 <GDG_Tools.html#1109177>`__ + + vs. Services, `1 <GDG_Tools.html#1090035>`__ + + `ToolSvc, see Services <GDG_Tools.html#1092938>`__\ `1 <GDG_Tools.html#1092938>`__ + +U +- + + Units, `1 <GDG_Overview.html#1052502>`__ + + Convention, `1 <GDG_Overview.html#1052502>`__ + +V +- + + Visualization, `1 <GDG_Visualization.html#1056919>`__ + +W +- + + Windows NT, `1 <GDG_Installation.html#1176620>`__ diff --git a/docs/source/old/GDG_Installation.rst b/docs/source/old/GDG_Installation.rst new file mode 100644 index 0000000000000000000000000000000000000000..657f31e4755ed41594c8a0b91ee01ec576d54651 --- /dev/null +++ b/docs/source/old/GDG_Installation.rst @@ -0,0 +1,347 @@ +.. include:: ./global.rst + +|newpage| + +|Gaudi logo| + +.. _chapInst: + +Release notes and software installation +========================================= + +Release History +------------------- + + The Gaudi architecture and framework, which was initially developed + by the LHCb collaboration, became a joint development project + between several experiments, starting from release v6. At this time + the package structure was modified, to split the experiment specific + packages from the common packages. The following table reflects the + version history since the re-packaging. For the history of earlier + releases, please refer to previous versions of the (LHCb) Gaudi + Users Guide. + + +--------------------------+--------------------------+----------------------------+ + | Version | Date | Package List | | + +==========================+==========================+============================+ + | v7 | 23/03/2001 | | GaudiPolicy[v4], | + | | | | GaudiExamples[v7], | + | | | | GaudiKernel[v9], | + | | | | GaudiSvc[v5], | + | | | | GaudiAud[v3], | + | | | | GaudiAlg[v3], | + | | | | GaudiTools[v3], | + | | | | GaudiNagC[v5r3p1], | + | | | | GaudiDb[v3], | + | | | | HbookCnv[v9], | + | | | | RootHistCnv[v3], | + | | | | SIPython[v1r1] | + +--------------------------+--------------------------+----------------------------+ + | v8r1 | July 2001 | | GaudiPolicy[v5], | + | | | | GaudiExamples[v8], | + | | | | GaudiKernel[v10], | + | | | | GaudiSvc[v6], | + | | | | GaudiAud[v4], | + | | | | GaudiAlg[v4], | + | | | | GaudiTools[v4], | + | | | | GaudiNagC[v5r3p2], | + | | | | GaudiDb[v4], | + | | | | GauiRootDb[v4], | + | | | | GaudiODBCDb[v3], | + | | | | HbookCnv[v10r1], | + | | | | RootHistCnv[v4], | + | | | | SIPython[v2] | + +--------------------------+--------------------------+----------------------------+ + | v9 | Dec 2001 | | GaudiPolicy[v5], | + | | | | GaudiExamples[v9], | + | | | | GaudiKernel[v11], | + | | | | GaudiSvc[v7], | + | | | | GaudiAud[v5], | + | | | | GaudiAlg[v5], | + | | | | GaudiTools[v5], | + | | | | GaudiNagC[v6], | + | | | | GaudiDb[v5], | + | | | | GauiRootDb[v5], | + | | | | GaudiODBCDb[v5], | + | | | | HbookCnv[v11], | + | | | | RootHistCnv[v5], | + | | | | GaudiPython[v2], | + | | | | GaudiObjDesc[v2], | + | | | | GaudiIntrospection[v2] | + +--------------------------+--------------------------+----------------------------+ + +Current Functionality +------------------------- + + We use an incremental and iterative approach for producing the Gaudi + software. We plan to expand its capabilities release by release. The + functionality list that follows is organized by categories. + + | Interfaces + | A set of interfaces that facilitates the interaction between the different components of the framework. Mainly these are interfaces to services. + | Basic framework services + | This set of services offer the minimal functionality needed for constructing applications. They are described in detail in :numref:`chapServ`. + | The message service is used to send and format messages generated in the code, with an associated severity that is used for filtering and dispatching them. + | The job options service allows the configuration of the application by end users assigning values to properties defined within the code; properties can be basic types (float, bool, int, string), or extended with bounds checking, hierarchical lists, and immediate callback from string "commands". + | The Random Numbers service makes available several random number distributions via a standard interface, and ensures that applications use a unique random number engine in a reproducible fashion. + | The Chrono service offers the functionality for measuring elapsed time and job execution statistics. + | Auditors and AuditorSvc provide monitoring of various characteristics of the execution of Algorithms. Auditors are called before and after invocation of any Algorithm method. + | The Incident service provides a synchronization between objects within the Application by using named incidents that are communicated to listener clients. + | The Tools service, which provides management of Tools, is discussed in :numref:`chapTool`. Tools are lightweight objects which can be requested and used many times by other components to perform well defined tasks. A base class for associator tools has been added in this release. + | Data services provide the access to the transient data objects (event, detector and statistical data). The data services are described in :numref:`chapData`, :numref:`chapEven`, :numref:`chapDetd`, :numref:`chapHist` and :numref:`chapNtup` . The basic building blocks for the implementation of the experiment specific data models are also described in :numref:`chapData`. + | Event data persistent storage + | The current version provides a set of generic classes for implementing event data persistency (GaudiDb package) and a set of classes supporting persistent I/O to ROOT files (GaudiRootDb package). Details can be found in :numref:`chapConv`. + | Histograms & N-tuples + | The framework provides facilities for creating histograms (1 and 2 dimensional) and n-tuples (row and column wise) from user algorithms. The histogram interface is the AIDA [AIDA]_ common interface. Saving histograms and n-tuples is currently implemented using the HBOOK and ROOT format. The interface to histograms and n-tuples from the user code should not be affected if the persistency representation is changed later. Details of the histogram and n-tuple facilities can be found in :numref:`chapHist` and :numref:`chapNtup` respectively. + | Event tag collections + | The framework provides facilities for creating and using collections of event tags (based on an n-tuples implementation) for fast direct access to physics events. The user can specify an event tag collection as input data to an application and perform sophisticated selections using the facilities existing in the data storage technology. This is explained in :numref:`chapNtup`. + | Detector description and geometry + | The framework provides facilities for accessing detector description and geometry data. This is described in :numref:`chapDetd`. A concrete implementation exists in LHCb, but is not distributed with Gaudi. + | Analysis services + | A number of facilities and services are included in the current release to facilitate writing physics analysis code. The GaudiAlg package is a collection of general purpose algorithms, including a sequencer which uses the filtering capability of algorithms to manage the execution of algorithm sequences in a filtering application (see :numref:`algo-filt`). The Particle Properties service (:numref:`serv-prse`) provides the properties of all the elementary particles. Numerical utilities are available via the CLHEP and NAG C libraries ( :numref:`chapUtil`). + | Visualization services + | The framework provides a mechanism for the visualisation of event and detector data. A prototyp implementation exists in LHCb, but is not distributed with Gaudi. This is briefly described in :numref:`chapVisu`. + | Object Description and Object Introspection + | The framework provides object modelling and description using XML files. Two code generation back-ends are currently available: to generate the data object header files and to generate the object dictionaries for the object introspection. Refer to + | Scripting services + | The framework provides a service for interfacing Python with a Gaudi application. The user can interact with a Gaudi application from the Python prompt. The current functionality allows the user to set and get properties from Algorithms and Services, interact with the data stores (event, detector and histogram) using the object introspection capability, and to schedule the execution of the application's algorithms. Refer to . + | Dynamic loading of libraries + | The framework can be used to implement different data processing applications for different environments. It is important that the services and their concrete implementations are extendable and configurable dynamically at run time and not statically. The latter would imply linking with all the available libraries producing huge executables. And in certain applications and environments some of the libraries will surely never be used. The framework provides support for dynamic libraries for the Windows and Linux platforms. + +Changes between releases +---------------------------- + +Changes between current release (v9) and previous release (v8) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + | · Object description and object introspection. Two new packages has been added that provide the object description based on XML files and run-time object introspection capability. Refer to :numref:`data-defi` and :numref:`serv-refl` for more details. + | · Python service. The scripting service based on Python has been re-implemented using the Boost library [#]_. Its functionality has been extended. Refer to :numref:`chapScri` for more details. + | · Algorithms. Added toolSvc() accessor to Algorithm base class. + | · Algorithm Tools. Added initialize() and finalize() methods in IAlgTool interface. The base class AlgTool implements them as dummy but allows an implementation of them on specific Algorithm Tools. Removed the need to implement a queryInterface() in specific Algorithm tools. Instead use the expression declareInterface<Ixxxx>(this) in the constructor. + | · A number of small internal framework improvements: + | · ApplicationMgr. Re-organization to relocate the management of services to ServiceManager class. The interfaces ISvcManager and ISvcLocator have changed. + | · Introduced a new constructor for InterfaceID that uses a name (class name) instead of an interface number. + | · JobOptions. Introduced new options #pragma print on, #pragma print off to switch the printing of job options on and off. + | · Histograms. New job option HistogramPersistencySvc.PrintHistos to steer printing to standard output. Allow RZ directory names up to 16 characters rather than 8. + +Incompatible changes +```````````````````````````` + + In this section we will list changes that users need to make to + their code in order to upgrade to the current version of Gaudi from + the previous version. + + | 1. In the area of Data Stores many low level base classes (DataObject, DataSvc, Converters, Registry, GenericAddress, etc.) have changed together with some basic interfaces (IConverter, IDataManagerSvc, IDataProviderSvc, etc.). This implies that some packages, typically converters packages, will need deep changes in the code. Instructions on how to upgrade them can be found in http://cern.ch/lhcb-comp/Frameworks/Gaudi/Gaudi_v9/Changes_cookbook.pdf. + | End user algorithm packages should not be too affected by these changes. + | 2. Removed the list of default interfaces in ApplicationMgr. Services are late created if needed. This may cause problems if the order of creation played a role. The Algorithms and Tools that were accessing service using the call serviceLocator()->service("name", interface) may require to force the creation of a previously default service by adding a third argument with true to force such creation if not existing. + | 3. The constant CLID\_Event has been removed from ClassID.h. It needs to be defined now in the Event.h header file. + | 4. Algorithm tools are required to implement an interface (pure abstract base class) using the facility provided for declaring it as mentioned above in the list of changes. + +Changes between release v8 and release v7 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Incompatible changes +```````````````````````````` + + In this section we will list changes that users need to make to + their code in order to upgrade to version v8 of Gaudi from version + v7. + + | 1. Location of Histogram Interfaces. Gaudi version v8 uses the standard AIDA interfaces for histograms. These interfaces are located in the AIDA project area. The changes to the end-user code is that the include file should be prefixed with AIDA/ instead of the current GaudiKernel/. + | 2. Persistent representation of N-tuples. N-tuples saved in HBOOK format no longer have type information in the first row. See the discussion in :numref:`ntup-spec` for more details. + | 3. The output of N-tuples to ODBC () is no longer supported. N-Tuple preselections based on SQL or interpreted C++ are no longer available. If you rely on these features, please contact the Gaudi development team. + | 4. When saving data objects in a data store, all the sub-directory nodes in the path must already exist or should be explicitly created. In fact this is not a new feature, but a bug fix! Implicit creation of sub-directory nodes will be implemented in a future version. + +Changes between release v7 and release v6 +----------------------------------------------- + + | · The control of the "physics event" loop has been separated from the ApplicationMgr and has become a new component, the event loop manager. A number of subsequent specializations have been provided: MininalEventLoopMgr, EventLoopMgr, and GaudiEventLoopMgr. These changes have been made to allow the possibility to have other types of event loop processing. These changes are backward compatible. + | · The first version of a scripting service based on Python has been released. + | · A number of small internal framework improvements: + | · Elimination of the up to now required static libraries. + | · Added version number (major and minor) to the Interface ID to check for interface compatibility at run-time. + | · Re-shuffling of the System class and conversion to a namespace. + | · Handling empty vectors in JobOptions. + +Incompatible changes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + In this section we will list changes that users need to make to + their code in order to upgrade to version v7 of Gaudi from version + v6. + + | 1. Histogram persistency. In previous versions, the HBOOK histogram persistency service was created by default. From this version there is no default histogram persistency: the ROOT or HBOOK persistency services have to be explicitly declared. See :numref:`hist-stor` for details. + | 2. EvtMax. In previous versions it was possible to declare the number of events to be processed through either of the properties ApplicationMgr.EvtMax or EventSelector.EvtMax. In this release, only ApplicationMgr.EvtMax is supported, the default being all the events in the input file + | 3. The property EventSelector.JobInput has been removed. Use EventSelector.Input instead (note the change in format of the value string). + +Deprecated features +~~~~~~~~~~~~~~~~~~~~~~~~~ + + We list here features of the framework which have become obsolete, + because they have been superseded by more recent features. Users are + discouraged from using the deprecated features, which may be removed + in a future release. + + | Adding indexed items to N-tuples + | Use the function addIndexedItem instead of addItem. + | Accessors names in Algorithm + | Use the service accessors with short names (e.g. msgSvc() ) instead of the long equivalent ones (e.g. messageService() ) + | Access to extra services from Algorithms. + | Use the templated method service() instead of using the serviceLocator() together with the queryInterface() to get a reference to a service interface. + | User Parameters in detector elements. + | The XML tag for user parameters in the detector description (detector elements, etc.) is now <param/> instead of <userparameter/>. The old name will be maintained for a while. The methods in DetectorElement and Condition classes will accordonly be changed to use the word param instead of userParameter. + +Availability +---------------- + + The application framework is supported on the following platforms: + + | · Windows NT4 and Windows 2000, using the Developer Studio 6.0 SP2 Visual C++ environment + | · RedHat Linux 6.1 (certified CERN Linux distribution with SUE and AFS) with egcs-2.91.66 and gcc-2.95.2. + + The code, documentation and installation instructions are available + from the Gaudi web site at: http://cern.ch/proj-gaudi/ + + Framework sources and binaries are also available in the CERN AFS cell, at /afs/cern.ch/sw/Gaudi . + +.. _inst-usin: + +Using the framework +----------------------- + +CVS repository +~~~~~~~~~~~~~~~~~~~~ + + The framework sources are stored in CVS and can be accessed using + the CVS server. You have to specify the following option in your CVS + command: + + | -d :pserver:cerncvs@lhcbcvs.cern.ch:/local/gaudicvs + + You have to login to the CVS server first: + + | cvs -d :pserver:cerncvs@lhcbcvs.cern.ch:/local/gaudicvs login + + The server will ask for a password, reply CERNuser. You can now send + all the CVS commands that don't require write access. If you use a + command like commit, you will get an error message. When you have + finished, you can logout of the server. + +CMT +~~~~~~~~~ + + The framework libraries have been built using the Configuration + Management Tool (CMT) [CMT]_. + Therefore, using the CMT tool is the recommended way to modify + existing packages or re-build the examples included in the release. + If CMT is not available in your system, please follow the + installation instructions in [CMT]_. The following simple + examples are for Unix, but similar commands exist also for Windows. + They assume that the CMTPATH environment variable is set to + $HOME/mycmt:$GAUDIHOME. + + | Getting a copy of a package: + | Suppose you want to build the latest released version of the GaudiExamples package: + + .. code-block:: bash + + cd mycmt + cmt checkout GaudiExamples -r v7 + + + | Building and running an example: + | Now that you have the code, suppose you want to modify the AlgSequencer example, then build it and run it: + + .. code-block:: bash + + cd GaudiExamples/v7/src/AlgSequencer + emacs HelloWorld.cpp + ----- Make your modification, then + cd ../../cmt + source setup.csh + emacs requirements + ----- Uncomment AlgSequencer and comment all the others + gmake + cd ../home + emacs AlgSequencer.txt + ----- Make any modification if needed + ../$CMTCONFIG/AlgSequencer.exe + + + | Modifying a library and rerunning the example: + | Suppose now you want to modify one of the Gaudi libraries, build it, then rerun the AlgSequencer example with it: + + .. code-block:: bash + + cd $HOME/mycmt + cmt checkout GaudiAlg v3 + cd GaudiAlg/v3/src + emacs ... + ---- Make your modification... + cd ../cmt + source setup.csh + gmake + cd $HOME/mycmt/GaudiExamples/v7/cmt + cmt show uses + ---- Verify the you are now using the GaudiAlg version from $HOME/mycmt + ---- There is no need to relink, since GaudiAlg is a component library + cd ../home + ../$CMTCONFIG/AlgSequencer.exe + + +Using the framework on Windows with Developer Studio or Nmake +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The libraries for Windows are available for download from the web, + and in AFS in the Win32Debug subdirectory of each package. + + .. Instructions for installing the Gaudi environment on Windows and for customising MS Visual Studio will be made available here in due course. For now, please refer to the LHCb specific instructions at: http://cern.ch/lhcb-comp/Support/html/DevStudio/default.htm + + The requirements files and CMT commands expect the following + environment variables: + + | · HOME Needs to be set to the user\'s home directory. Typically this is in a network server and will have the form "\server\username" or can also be a local directory like "C:\\home". This environment variable is used to locate the .cmtrc file that contains the default CMTPATH. + | · PATH Should be set up correctly to locate the Developer Studio executables (this is typically the case after installation). + | · TEMP Location for temporary files. This is set correctly after the operating system installation. + | · SITEROOT This is the root where software is installed. Typically it will point to some share in some server (\server\siteroot) or to the locally mounted AFS drive (F:\\cern.ch). + | · CMTPATH The first location where CMT is looking for packages. This is typically the local directory C:/mycmt + | · CMTSITE This is your site name. At CERN site and for the Windows platform we use CERN\_WIN32. + +Using the framework in Unix +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + | The libraries for Linux are available for download from the web, and in AFS in the i386\_linux22 an Linuxdbx subdirectories of each package (for the optimised and debug versions respectively). + | Instructions for installing the Gaudi environment on Linux will be made available here in due course. For now, please refer to the LHCb specific instructions at: http://cern.ch/lhcb-comp/Support/html/start_gaudi.htm + +Working with development releases +------------------------------------- + + This User Guide corresponds to release v9 of the Gaudi software. + + For Gaudi packages, before they are publicly released and frozen, + the development versions are periodically rebuilt from the head + revision of the CVS repository in the development release area. + These versions are not guaranteed to work and may change without + notice; they are intended for integration tests. They should be used + with care, mainly if you wish to use new features of the software + which have not yet been incorporated in a public release. + +Installation of the framework outside CERN +---------------------------------------------- + +Package installation +~~~~~~~~~~~~~~~~~~~~~~~~~~ + + To use the Gaudi framework you also need to have access to + installations of some external packages, listed below: + + CMT, CLHEP, NAG C, HTL, Python, Xerces, qqlhcb, ROOT, BOOST and + CERNLIB. + + Up to date instructions for installation of these packages and + setting of the environment (variables, path,..) needed to use the + framework can be found on the Web at + http://cern.ch/lhcb-comp/Support/html/Install.htm. + + +.. [#] http://www.boost.org/libs/libraries.htm diff --git a/docs/source/old/GDG_Libraries.rst b/docs/source/old/GDG_Libraries.rst new file mode 100644 index 0000000000000000000000000000000000000000..c7fcb540da9e5848e655c52dea6279a2e419c8ef --- /dev/null +++ b/docs/source/old/GDG_Libraries.rst @@ -0,0 +1,534 @@ +.. include:: ./global.rst + +|newpage| + +|Gaudi logo| + +.. _chapLibr: + +Framework packages, interfaces and libraries +=============================================== + +Overview +------------- + + It is clearly important to decompose large software systems into + hierarchies of smaller and more manageable entities. This + decomposition can have important consequences for implementation + related issues, such as compile-time and link dependencies, + configuration management, etc. A package is the grouping of related + components into a cohesive physical entity. A package is also the + minimal unit of software release. + + In this chapter we describe the Gaudi package structure, and how + these packages are implemented in libraries. We also discuss + abstract inerfaces, which are one of the main design features of + Gaudi + +Gaudi Package Structure +---------------------------- + + The Gaudi software is decomposed into the packages shown in :numref:`fig-packages`. + + .. figure:: images/Packages.png + :name: fig-packages + + Package structure of the Gaudi software + + At the lower level we find GaudiKernel, which is the framework + itself, and whose only dependency is on the GaudiPolicy package, + which contains the various flags defining the CMT [CMT]_ + configuration management + environment needed to build the Gaudi software. At the next level + are the packages containing standard framework components (GaudiSvc, + GaudiDb, GaudiTools, GaudiAlg, GaudiAud,GaudiIntrospection), which + depend on the framework and on widely available foundation libraries + such as CLHEP and HTL. These external libraries are accessed via CMT + interface packages which use environment variables defined in the + ExternalLibs package, which should be tailored to the software + installation at a given site. All the above packages are grouped + into the GaudiSys set of packages which are the minimal set required + for a complete Gaudi installation + + The remaining packages are optional packages which can be used + according to the specific technology choices for a given + application. In this distribution, there are two specific + implementations of the histogram persistency service, based on HBOOK + (HbookCnv) and ROOT (RootHistCnv) and two implementations of the + event data persistency service (GaudiRootDb and GaudiODBCDb) which + understand ROOT and ODBC compliant databases respecively. There is + also a scripting service (GaudiPython) depending on the Python + scripting language and a data description service (GaudiObjDesc) + based on the Xerces XML parser. Finally, at the top level we find + the applications (GaudiExamples) which depend on GaudiSys and the + scripting and persistency services. + +Gaudi Package Layout +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + :numref:`fig-packlay` shows the layout for Gaudi packages. + + .. figure:: images/PackageLayout.png + :name: fig-packlay + + Layout of Gaudi software packages + + Note that the binaries directories are not in CVS, they are created + by CMT when building a package. + +Packaging Guidelines +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Packaging is an important architectural issue for the Gaudi + framework, but also for the experiment specific software packages + based on Gaudi. Typically, experiment packages consist of: + + | · Specific event model + | · Specific detector description + | · Sets of algorithms (digitisation, reconstruction, etc.) + + The packaging should be such as to minimise the dependencies between + packages, and must absolutely avoid cyclic dependencies. The + granularity should not be too small or too big. Care should be taken + to identify the external interfaces of packages: if the same + interfaces are shared by many packages, they should be promoted to a + more basic package that the others would then depend on. It is a + good idea to discuss your packaging with the librarian and/or + architect. + +Interfaces in Gaudi +------------------------ + + One of the main design choices at the architecture level in Gaudi + was to favour abstract interfaces when building collaborations of + various classes. This is the way we best decouple the client of a + class from its real implementation. + + An abstract interface in C++ is a class where all the methods are + pure virtual. We have defined some practical guidelines for defining + interfaces. An example is shown in :numref:`lstg-exabstrint`: + + .. was 16.1 + + .. code-block:: cpp + :name: lstg-exabstrint + :caption: Example of an abstract interface (IService) + + // $Header: $ + #ifndef GAUDIKERNEL_ISERVICE_H + #define GAUDIKERNEL_ISERVICE_H + + // Include files + #include "GaudiKernel/IInterface.h" + #include <string> + + // Declaration of the interface ID. (id, major, minor) + static const InterfaceID IID_IService(2, 1, 0); + + /* @class IService IService.h GaudiKernel/IService.h + + General service interface definition + + @author Pere Mato + */ + + class IService : virtual public IInterface { + + public: + + /// Retrieve name of the service + virtual const std::string& name() const = 0; + /// Retrieve ID of the Service. Not really used. + virtual const IID& type() const = 0; + /// Initilize Service + virtual StatusCode initialize() = 0; + /// Finalize Service + virtual StatusCode finalize() = 0; + /// Retrieve interface ID + static const InterfaceID& interfaceID() { return IID_IService; } + }; + + #endif // GAUDIKERNEL_ISERVICE_H + + + From this example we can make the following observations: + + | · Interface Naming. The name of the class has to start with capital "I" to denote that it is an interface. + | · Derived from IInterface. We follow the convention that all interfaces should be derived from a basic interface IInterface. This interface defined 3 methods: addRef(), release() and queryInterface(). This methods allow the framework to manage the reference counting of the framework components and the possibility to obtain a different interface of a component using any interface (see :numref:`libr-quin`). + | · Pure Abstract Methods. All the methods should be pure abstract (virtual ReturnType method(...) = 0;) With the exception of the static method interfaceID() (see later) and some inline templated methods to facilitate the use of the interface by the end-user. + | · Interface ID. Each interface should have a unique identification (see :numref:`libr-ifid`) used by the query interface mechanism. + +.. _libr-ifid: + +Interface ID +~~~~~~~~~~~~~~~~~~~ + + We needed to introduce an interface ID for identifying interfaces + for the queryInterface functionality. The interface ID is made of a + numerical identifier (generated from the interface name by a hash + function) and major and minor version numbers. The version number is + used to decide if the interface the service provider is returning is + compatible with the interface the client is expecting. The rules for + deciding if the interface request is compatible are: + + | · The interface identifier is the same + | · The major version is the same + | · The minor version of the client is less than or equal to the one of the service provider. This allows the service provider to add functionality (incrementing minor version number) keeping old clients still compatible. + + The interface ID is defined in the same header file as the rest of + the interface. Care should be taken of globally allocating the + interface identifier (by giving a unique name to the constructor), + and of modifying the version whenever a change of the interface is + required, according to the rules. Of course changes to interfaces + should be minimized. + + .. code-block:: cpp + + static const InterfaceID IID_Ixxx("Ixxx" /* id */, 1 /* major */, 0 /* minor */ ); + + class Ixxx : public IInterface { + // ... + + static const InterfaceID& interfaceID() { return IID_Ixxx; } + + }; + + + The static method Ixxx::interfaceID() is useful for the implementation of templated methods and classes using an interface as template parameter. The construct T::interfaceID() returns the interface ID of interface T. + +.. _libr-quin: + +Query Interface +~~~~~~~~~~~~~~~~~~~~~~ + + The method queryInterface() is used to request a reference to an + interface implemented by a component within the Gaudi framework. + This method is implemented by each component class of the framework + and allows us to navigate from one interface of a component to + another, as shown for example in :numref:`lstg-exusequint`, where we navigate from the + IMessageSvc interface of the message service to its IProperty + interface, in order to discover the value of its "OutputLevel" + property. + + .. was 16.2 + + .. code-block:: cpp + :name: lstg-exusequint + :caption: Example usage of queryInterface to navigate between interfaces + + IMessageSvc* msgSvc(); + // ... + IProperty* msgProp; + msgSvc()->queryInterface( IID_IProperty, (void**)&msgProp ); + std::string dfltLevel; + StatusCode scl = msgProp->getProperty( "OutputLevel", dfltLevel ); + + + The implementation of queryInterface() is usually not very visible + since it is done in the base class from which you inherit. A typical + implementation is shown in :numref:`lstg-eximpquint`: + + .. was 16.3 + + .. code-block:: cpp + :name: lstg-eximpquint + :caption: Example implementation of queryInterface() + + StatusCode DataSvc::queryInterface(const InterfaceID& riid, + void** ppvInterface) { + if ( IID_IDataProviderSvc.versionMatch(riid) ) { + *ppvInterface = (IDataProviderSvc*)this; + } + else if ( IID_IDataManagerSvc.versionMatch(riid) ) { + *ppvInterface = (IDataManagerSvc*)this; + } else { + return Service::queryInterface(riid, ppvInterface); + } + addRef(); + return SUCCESS; + } + + The implementation returns the corresponding interface pointer if + there is a match between the received InterfaceID and the + implemented one. The method versionMatch() takes into account the + rules mentioned in :numref:`libr-ifid`. + + If the requested interface is not recognized at this level (line 9), + the call can be forwarded to the inherited base class or possible + sub-components of this component. + +Libraries in Gaudi +----------------------- + + Two different sorts of library can be identified that are relevant + to the framework. These are component libraries, and linker + libraries. These libraries are used for different purposes and are + built in different ways. + +Component libraries +~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Component libraries are shared libraries that contain standard + framework components which implement abstract interfaces. Such + components are Algorithms, Auditors, Services, Tools or Converters. + These libraries do not export their symbols apart from one which is + used by the framework to discover what components are contained by + the library. Thus component libraries should not be linked against, + they are used purely at run-time, being loaded dynamically upon + request, the configuration being specified by the job options file. + Changes in the implementation of a component library do not require + the application to be relinked. + + Component libraries contain factories for their components, and it + is important that the factory entries are declared and loaded + correctly. The following sections describe how this is done. + + When a component library is loaded, the framework attempts to locate + a single entrypoint, called getFactoryEntries(). This is expected to + declare and load the component factories from the library. Several + macros are available to simplify the declaration and loading of the + components via this function. + + Consider a simple package MyComponents, that declares and defines + the MyAlgorithm class, being a subclass of Algorithm, and the + MyService class, being a subclass of Service. Thus the package will + contain the header and implementation files for these classes + (MyAlgorithm.h, MyAlgorithm.cpp, MyService.h and MyService.cpp) in + addition to whatever other files are necessary for the correct + functioning of these components. + + In order to satisfy the requirements of a component library, two + additional files must also be present in the package. One is used to + declare the components, the other to load them. Because of the + technical limitations inherent in the use of shared libraries, it is + important that these two files remain separate, and that no attempt + is made to combine their contents into a single file. + + The names of these files and their contents are described in the + following sections. + +Declaring Components +````````````````````````````` + + Components within the component library are declared in a file + MyComponents\_load.cpp. By convention, the name of this file is the + package name concatenated with \_load. The contents of this file are + shown below: + + .. was 16.4 + + .. code-block:: cpp + :name: lstg-mycompcpp + :caption: The MyComponents\_load.cpp file + + #include "GaudiKernel/DeclareFactoryEntries.h" + + DECLARE_FACTORY_ENTRIES( MyComponents ) { [1] + DECLARE_ALGORITHM( MyAlgorithm ); [2] + DECLARE_SERVICE ( MyService ); + } + + Notes: + + | 1. The argument to the DECLARE\_FACTORY\_ENTRIES statement is the name of the component library. + | 2. Each component within the library should be declared using one of the DECLARE\_XXX statements discussed in detail in the next Section. + +Component declaration statements +````````````````````````````````````````` + + The complete set of statements that are available for declaring + components is given below. They include those that support C++ + classes in different namespaces, as well as for DataObjects or + ContainedObjects using the generic converters. + + .. was 16.5 + + .. code-block:: cpp + :name: lstg-availcompdecl + :caption: The available component declaration statements + + DECLARE_ALGORITHM(X) + DECLARE_AUDITOR(X) + DECLARE_CONVERTER(X) + DECLARE_GENERIC_CONVERTER(X) [1] + DECLARE_OBJECT(X) + DECLARE_SERVICE(X) + DECLARE_NAMESPACE_ALGORITHM(N,X) [2] + DECLARE_NAMESPACE_AUDITOR(N,X) + DECLARE_NAMESPACE_CONVERTER(N,X) + DECLARE_NAMESPACE_GENERIC_CONVERTER(N,X) + DECLARE_NAMESPACE_OBJECT(N,X) + DECLARE_NAMESPACE_SERVICE(N,X) + + Notes: + + | 1. Declarations of the form DECLARE\_GENERIC\_CONVERTER(X) are used to declare the generic converters for DataObject and ContainedObject classes. For DataObject classes, the argument should be the class name itself (e.g. EventHeader), whereas for ContainedObject classes, the argument should be the class name concatenated with either List or Vector (e.g. CellVector) depending on whether the objects are associated with an ObjectList or ObjectVector. + | 2. Declarations of this form are used to declare components from explicit C++ namespaces. The first argument is the namespace (e.g. Atlfast), the second is the class name (e.g. CellMaker). + +Loading Components +``````````````````````````` + + Components within the component library are loaded in a file + MyComponents\_dll.cpp. By convention, the name of this file is the + package name concatenated with \_dll. The contents of this file are + shown below: + + .. was 16.6 + + .. code-block:: cpp + :name: lstg-mycompdllcpp + :caption: The MyComponents\_dll.cpp file + + #include "GaudiKernel/LoadFactoryEntries.h" + LOAD_FACTORY_ENTRIES( MyComponents ) [1] + + Notes: + + | 1. The argument of LOAD\_FACTORY\_ENTRIES is the name of the component library. + +.. _libr-scar: + +Specifying component libraries at run-time +``````````````````````````````````````````````````` + + The fragment of the job options file that specifies the component + library at run-time is shown below. + + .. was 16.7 + + .. code-block:: cpp + :name: lstg-selextut + :caption: Selecting and running the desired tutorial example + + ApplicationMgr.DLLs += { "MyComponents" }; [1] + + Notes: + + | 1. This is a list property, allowing multiple such libraries to be specified in a single line. + | 2. It is important to use the "+=" syntax to append the new component library or libraries to any that might already have been configured. + + The convention in Gaudi is that component libraries have the same + name as the package they belong to (prefixed by "lib" on Linux). + When trying to load a component library, the framework will look for + it in various places following this sequence: + + | - Look for an environment variable with the name of the package, suffixed by "Shr" (e.g. ${MyComponentsShr}). If it exists, it should translate to the full name of the library, without the file type suffix (e.g. ${MyComponentsShr}="$MYSOFT/MyComponents/v1/i386\_linux22/libMyComponents" ). + | - Try to locate the file libMyComponents.so using the LD\_LIBRARY\_PATH (on Linux), or MyComponents.dll using the PATH (on Windows). + +Linker libraries +~~~~~~~~~~~~~~~~~~~~~~~ + + These are libraries containing implementation classes. For example, + libraries containing code of a number of base classes or specific + classes without abstract interfaces, etc. These libraries, contrary + to the component libraries, export all the symbols and are needed + during the linking phase in the application building. These + libraries can be linked to the application "statically" or + "dynamically", requiring a different file format. In the first case + the code is added physically to the executable file. In this case, + changes in these libraries require the application to be re-linked, + even if these changes do not affect the interfaces. In the second + case, the linker only adds into the executable minimal information + required for loading the library and resolving the symbols at run + time. Locating and loading the proper shareable library at run time + is done exclusively using the LD\_LIBRARY\_PATH for Linux and PATH + for Windows. The convention in Gaudi is that linker libraries have + the same name as the package, suffixed by "Lib" (and prefixed by + "lib" on Linux, e.g. libMyComponentsLib.so). + +Library strategy and dual purpose libraries +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Because component libraries are not designed to be linked against, + it is important to separate the functionalities of these libraries + from linker libraries. For example, consider the case of a + DataProvider service that provides DataObjects for clients. It is + important that the declarations and definitions of the DataObjects + be handled by a different shared library than that handling the + service itself. This implies the presence of two different packages + - one for the component library, the other for the DataObjects. + Clients should only depend on the second of these packages. + Obviously the package handling the component library will in general + also depend on the second package. + + It is possible to have dual purpose libraries - ones which are + simultaneously component and linker libraries. In general such + libraries will contain DataObjects and ContainedObjects, together + with their converters and associated factories. It is recommended + that such dual purpose libraries be separated from single purpose + component or linker libraries. Consider the case where several + Algorithms share the use of several DataObjects (e.g. where one + Algorithm creates them and registers them with the transient event + store, and another Algorithm locates them), and also share the use + of some helper classes in order to decode and manipulate the + contents of the DataObjects. It is recommended that three different + packages be used for this - one pure component package for the + Algorithms, one dual-purpose for the DataObjects, and one pure + linker package for the helper classes. + +Building and linking with the libraries +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Gaudi libraries and applications are built using CMT, but may be + used also by experiments using other configuration management tools. + +Building and linking to the Gaudi libraries with CMT +````````````````````````````````````````````````````````````` + + Gaudi libraries and applications are built using CMT taking + advantage of the CMT macros defined in the GaudiPolicy package. As + an example, the CMT requirements file of the GaudiTools package is + shown in :numref:`lstg-cmtreqgdtool`. The linker + and component libraries are defined on lines 23 and 26 respectively - the linker + library is defined first because it must be built ahead of the + component library. Lines 28 and 34 set up the generic linker + options and flags for the linker library, which are suffixed by the + package specific flags set up by line 35. Line 31 tells CMT to generate the + symbols needed for the component library, while line 33 + sets up the corresponding linker + flags for the component library. Finally, line 30 updates LD\_LIBRARY\_PATH (or + PATH on Windows) for this package. In packages with only a component + library and no linker library, line 30 could be replaced by + "apply\_pattern packageShr", which would create the logical name + required to access the component library by the first of the two + methods described in :numref:`libr-scar`. + + .. was 16.8 + + .. code-block:: bash + :name: lstg-cmtreqgdtool + :caption: CMT requirements file for the GaudiTools package + + package GaudiTools + version v1 + + branches GaudiTools cmt doc src + use GaudiKernel v8* + include_dirs "$(GAUDITOOLSROOT)" + + #linker library + library GaudiToolsLib ../src/Associator.cpp ../src/IInterface.cpp + + #component library + library GaudiTools ../src/GaudiTools_load.cpp ../src/GaudiTools_dll.cpp + + apply_pattern package_Llinkopts + + apply_pattern ld_library_path + macro_append GaudiTools_stamps "$(GaudiToolsDir)/GaudiToolsLib.stamp" + + apply_pattern package_Cshlibflags + apply_pattern package_Lshlibflags + macro_append GaudiToolsLib_shlibflags $(GaudiKernel_linkopts) + +Linking FORTRAN code +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Any library containing FORTRAN code (more specifically, code that + references COMMON blocks) must be linked statically. This is because + COMMON blocks are, by definition, static entities. When mixing C++ + code with FORTRAN, it is recommended to build separate libraries for + the C++ and FORTRAN, and to write the code in such a way that + communication between the C++ and FORTRAN worlds is done exclusively + via wrappers. This makes it possible to build shareable libraries + for the C++ code, even if it calls FORTRAN code internally. diff --git a/docs/source/old/GDG_Ntuple.rst b/docs/source/old/GDG_Ntuple.rst new file mode 100644 index 0000000000000000000000000000000000000000..a5d8af2476967ac32eeb67a47b5018f6356717fb --- /dev/null +++ b/docs/source/old/GDG_Ntuple.rst @@ -0,0 +1,700 @@ +.. include:: ./global.rst + +|newpage| + +|Gaudi logo| + +.. _chapNtup: + +N-tuple and Event Collection facilities +========================================== + +Overview +------------- + + In this chapter we describe facilities available in Gaudi to create + and retrieve N-tuples. We discuss how Event Collections, which can + be considered an extension of N-tuples, can be used to make + preselections of event data. Finally, we explore some possible tools + for the interactive analysis of N-tuples. + +N-tuples and the N-tuple Service +------------------------------------- + + User data - so called N-tuples - are very similar to event data. Of + course, the scope may be different: a row of an N-tuple may + correspond to a track, an event or complete runs. Nevertheless, user + data must be accessible by interactive tools such as PAW or ROOT. + + Gaudi N-tuples allow to freely format structures. Later, during the + running phase of the program, data are accumulated and written to + disk. + + The transient image of an N-tuple is stored in a Gaudi data store + which is connected to the N-tuple service. Its purpose is to store + user created objects that have a lifetime of more than a single + event. + + As with the other data stores, all access to data is via a service + interface. In this case it is via the INTupleSvc interface which + extends the IDataProviderSvc interface. In addition the interface to + the N-tuple service provides methods for creating N-tuples, saving + the current row of an N-tuple or retrieving N-tuples from a file. + The N-tuples are derived from DataObject in order to be storable, + and are stored in the same type of tree structure as the event data. + This inheritance allows to load and locate N-tuples on the store + with the same smart pointer mechanism as is available for event data + items (c.f. :numref:`chapData`). + +.. _ntup-accs: + +Access to the N-tuple Service from an Algorithm +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The Algorithm base class defines a member function which returns a + pointer to the INTupleSvc interface + + .. code-block:: cpp + + INTupleSvc* ntupleSvc() + + The N-tuple service provides methods for the creation and + manipulation of N-tuples and the location of N-tuples within the + persistent store. + + The top level directory of the N-tuple transient data store is + always called "/NTUPLES". The next directory layer is connected to + the different output streams: e.g. "/NTUPLES/FILE1", where FILE1 is + the logical name of the requested output file for a given stream. + There can be several output streams connected to the service. In + case of persistency using HBOOK, "FILE1" corresponds to the top + level RZ directory of the file (...the name given to HROPEN). From + then on the tree structure is reflected with normal RZ directories + (caveat: HBOOK only accepts directory names with less than 8 + characters! It is recommended to keep directory names to less than 8 + characters even when using another technology (e.g. ROOT) for + persistency, to make the code independent of the persistency + choice.). Note that the top level directory name "/NTUPLES/" can be + omitted when referring to an N-tuple in the transient data store - + in the example above the name could start with "FILE1" (without a + leading "/"). + +Using the N-tuple Service +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + This section explains the steps to be performed when defining an + N-tuple: + + | · The N-tuple tags must be defined. + | · The N-tuple must be booked and the tags must be declared to the N-tuple. + | · The N-tuple entries have to be filled. + | · The filled row of the N-tuple must be committed. + | · Persistent aspects are steered by the job options. + +.. _ntup-dftg: + +Defining N-tuple tags +`````````````````````````````` + + When creating an N-tuple it is necessary to first define the tags to + be filled in the N-tuple, as shown for example in :numref:`lstg-defntuptag`: + + .. was 10.1 + + .. code-block:: cpp + :name: lstg-defntuptag + :caption: Definition of N-tuple tags + + NTuple::Item<long> m_ntrk; // A scalar item (number) + NTuple::Array<bool> m_flag; // Vector items + NTuple::Array<long> m_index; + NTuple::Array<float> m_px, m_py, m_pz; + NTuple::Matrix<long> m_hits; // Two dimensional tag + + Typically the tags belong to the filling algorithm and hence should + be provided in the Algorithm's header file. Currently the supported + data types are: bool, long, float and double. double types (Fortran + REAL\*8) are not recommened if using HBOOK for persistency: HBOOK + will complain if the N-tuple structure is not defined in a way that + aligns double types to 8 byte boundaries. In addition PAW cannot + understand double types. + +Booking and Declaring Tags to the N-tuple +`````````````````````````````````````````````````` + + :numref:`lstg-crecolntup` shows how to book a + column-wise N-Tuple. The first directory specifier (FILE1 in the + example) must correspond to an open output stream (see :numref:`ntup-rcol`); + lower directory levels are created automatically. After booking, the previously + defined tags must be declared to the N-tuple; if not, they are + invalid and will cause an access violation at run-time. + + .. was 10.2 + + .. code-block:: cpp + :name: lstg-crecolntup + :caption: Creation of a column-wise N-tuple in a specified directory and file + + #include "GaudiKernel/NTuple.h" + // .. + NTuplePtr nt1(ntupleSvc(), "FILE1/MC/1"); + if ( !nt1 ) { // Check if already booked + nt1=ntupleSvc()->book("FILE1/MC/1",CLID_ColumnWiseTuple,"Hello World"); + if ( 0 != nt1 ) { + // Add an index column + status = nt1->addItem ("Ntrack", m_ntrk, 0, 5000 ); + // Add a variable size column, type float (length=length of index col) + status = nt1->addIndexedItem ("px", m_ntrk, m_px); + status = nt1->addIndexedItem ("py", m_ntrk, m_py); + status = nt1->addIndexedItem ("pz", m_ntrk, m_pz); + // Another one, but this time of type bool + status = nt1->addIndexedItem ("flg",m_ntrk, m_flag); + // Another one, type integer, numbers must be within [0, 5000] + status = nt1->addIndexedItem ("idx",m_ntrk, m_index, 0, 5000 ); + // Add 2-dim column: [0:m_ntrk][0:2]; numerical numbers within [0, 8] + status = nt1->addIndexedItem ("hit",m_ntrk, 2, m_hits, 0, 8 ); + } + else { // did not manage to book the N tuple.... + return StatusCode::FAILURE; + } + } + + In previous versions of Gaudi (up to v8), indexed items were added + with the addItem function, causing confusion for users. For this + reason the calls to add indexed arrays and matrices were changed, + these should now be added using the member function addIndexedItem. + Please consult the doxygen code documentation for further details. + The old calls still exist, however they are deprecated. + + Row wise N-tuples are booked in the same way, but giving the type + CLID\_RowWiseTuple. However, only individual items (class + NTuple::Item) can be filled, no arrays and no matrices. Clearly this + excludes the usage of indexed items. For row-wise N-tuples to be + saved in HBOOK format, it is recommended to use only float type, for + the reasons explained in :numref:`ntup-hbok`. + + When using HBOOK for persistency, the N-tuple identifier ("1" in + this example) must be a number and must be unique in a given + directory. This is a limitation imposed by HBOOK RZ directories. It + is recommended to keep this number unique even when using another + technology (e.g. ROOT) for persistency, to make the code independent + of the persistency choice. + +Filling the N-tuple +```````````````````````````` + + Tags are usable just like normal data items, where + + | · Items<TYPE> are the equivalent of numbers: bool, long, float. + | · Array<TYPE> are equivalent to 1 dimensional arrays: bool[size], long[size], float[size] + | · Matrix<TYPE> are equivalent to an array of arrays or matrix: bool[dim1][dim2]. + + Implicit bounds checking is not possible without a rather big + overhead at run-time. Hence it is up to the user to ensure the + arrays do not overflow. + + When all entries are filled, the row must be committed, i.e. the + record of the 7N-tuple must be written. + + .. was 10.3 + + .. code-block:: cpp + :name: lstg-fillntuple + :caption: Filling an N-tuple + + m_ntrk = 0; + for( MyTrackVector::iterator i = mytracks->begin(); i != mytracks->end(); i++ ) { + const HepLorentzVector& mom4 = (*i)->fourMomentum(); + m_px[m_ntrk] = mom4.px(); + m_py[m_ntrk] = mom4.py(); + m_pz[m_ntrk] = mom4.pz(); + m_index[m_ntrk] = cnt; + m_flag[m_ntrk] = (m_ntrk%2 == 0) ? true : false; + m_hits[m_ntrk][0] = 0; + m_hits[m_ntrk][1] = 1; + m_ntrk++; + // Make sure the array(s) do not overflow. + if ( m_ntrk > m_ntrk->range().distance() ) break; + } + // Commit N tuple row. See :numref:`lstg-crecolntup` for initialisation of m_ntuple + status = m_ntuple->write(); + if ( !status.isSuccess() ) { + log << MSG::ERROR << "Cannot fill id 1" << endreq; + } + + +Reading N-tuples +````````````````````````` + + Although N-tuples intended for interactive analysis, they can also + be read by a regular program. An example of reading back such an + N-tuple is given in :numref:`lstg-readntuple`. + + .. code-block:: cpp + :name: lstg-readntuple + :caption: Reading an N-tuple + + NTuplePtr nt(ntupleSvc(), "FILE1/ROW\_WISE/2"); + if ( nt ) { + long count = 0; + NTuple::Item<float> px, py, pz; + status = nt->item("px", px); + status = nt->item("py", py); + status = nt->item("pz", pz); + // Access the N tuple row by row and print the first 10 tracks + while ( nt->read().isSuccess() ) { + log << MSG::INFO << " Entry [" << count++ << "]:"; + log << " Px=" << px << " Py=" << py << " Pz=" << pz << endreq; + } + } + + +N-tuple Persistency +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Choice of persistency technology +````````````````````````````````````````` + + N-tuples are of special interest to the end-user, because they can + be accessed using commonly known tools such as PAW, ROOT or Java + Analysis Studio (JAS). In the past it was not a particular strength + of the software used in HEP to plug into many possible persistent + data representations. Except for JAS, only proprietary data formats + are understood. For this reason the choice of the output format of + the data depends on the preferred analysis tool/viewer. + + | HBOOK + | + | This data format is used by PAW. PAW can understand this and only this data format. Files of this type can be converted to the ROOT format using the h2root data conversion program. The use of PAW in the long term is deprecated. + | ROOT + | + | This data format is used by the interactive ROOT program. + + In the current implementation, N-tuples must use the same + persistency technology as histograms. The choice of technology is + therefore made in the same way as for histograms, as described in + :numref:`hist-stor`. Obviously the options + have to be given only once and are valid for both histograms and + N-tuples. The only difference is that histograms are saved to a + different output file (defined by the job option + HistogramPersistencySvc.OuputFile), a different output file (or set + of output files) must be defined for the N-tuples. + +.. _ntup-spec: + +Input and Output File Specification +```````````````````````````````````````````` + + Conversion services exist to convert N-tuple objects into a form + suitable for persistent storage in a number of storage technologies. + In order to use this facility it is necessary to add the following + line in the job options file: + + .. code-block:: cpp + + NTupleSvc.Output = {"FILE1 DATAFILE='tuples.hbook' OPT='NEW'", + "FILE2 ...", + // ... + "FILEN ..."}; + + where <tuples.hbook> should be replaced by the name of the file to + which you wish to write the N-tuple. FILE1 is the logical name of + the output file, which must be the same as the data store directory + name described in :numref:`ntup-accs`. + Several files are possible, corresponding to different data store + directories whose name can be chosen at will. + + The detailed syntax of the options is as follows. In each case only + the three leading characters are significant: DATAFILE=<...>, + DATABASE=<...> or simply DATA=<...> would lead to the same result. + + | · DATAFILE='<file-specs>' + | Specifies the datafile (file name) of the output stream. + | · OPT='<opt-spec>' + | · NEW, CREATE, WRITE: Create a new data file. Not all implementations allow to over-write existing files. + | · OLD, READ: Access an existing file for read purposes + | · UPDATE: Open an existing file and add records. It is not possible to update already existing records. + + A similar option NTupleSvc.Input exists for N-tuple input. + +.. _ntup-hbok: + +Saving row wise N-tuples in HBOOK +`````````````````````````````````````````` + + Since the persistent representation of row wise N-tuples in HBOOK is + done by floats only, a convention is needed to access the proper + data type. By default the float type is assumed, i.e. all data + members are of float type. This is the recommended format. + + It is possible to define row wise N-tuples in Gaudi containing data + types other than float. This was the default in Gaudi versions + previous to v8, where the first row of the N-tuple contained the + type information. This possibility can be switched on by using the + option + + .. code-block:: python + + HistogramPersistencySvc.RowWiseNTuplePolicy = "USE_DATA_TYPES"; + + which also provides backwards compatibility for reading back old + N-tuples produced with old Gaudi versions. Remember however that + when using PAW to read N-tuples produced using this option, you must + skip the first row and start with the second event. + +Event Collections +---------------------- + + Event collections or, to be more precise, event tag collections, are + used to minimize data access by performing preselections based on + small amounts of data. Event tag data contain flexible event + classification information according to the physics needs. This + information could either be stored as flags indicating that the + particular event has passed some preselection criteria, or as a + small set of parameters which describe basic attributes of the + event. Fast access is required for this type of event data. + + Event tag collections can exist in several versions: + + | · Collections recorded during event processing stages from the online, reconstruction, reprocessing etc. + | · Event collections defined by analysis groups with pre-computed items of special interest to a given group. + | · Private user defined event collections. + + Starting from this definition an event tag collection can be + interpreted as an N-tuple which allows to access the data used to + create the N-tuple. Using this approach any N-tuple which allows + access to the data is an event collection. + + Event collections allow pre-selections of event data. These + pre-selections depend on the underlying storage technology. + + First stage pre-selections based on scalar components of the event + collection. First stage preselection is not necessarily executed on + your computer but on a database server e.g. when using ORACLE. Only + the accessed columns are read from the event collection. If the + criteria are fulfilled, the N-tuple data are returned to the user + process. Preselection criteria are set through a job options, as + described in section :numref:`ntup-rcol`. + + The second stage pre-selection is triggered for all items which + passed the first stage pre-selection criteria. For this + pre-selection, which is performed on the client computer, all data + in the N-tuple can be used. The further preselection is implemented + in a user defined function object (functor) as described in section + :numref:`ntup-rcol`. Gaudi algorithms are called + only when this pre-selector also accepts the event, and normal event + processing can start. + +Writing Event Collections +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Event collections are written to the data file using a Gaudi + sequencer. A sequencer calls a series of algorithms, as discussed in + section :numref:`algo-base`. The execution of + these algorithms may terminate at any point of the series (and the + event not selected for the collection) if one of the algorithms in + the sequence fails to pass a filter. + +Defining the Address Tag +````````````````````````````````` + + The event data is accessed using a special N-tuple tag of the type + + .. code-block:: cpp + + NTuple::Item<IOpaqueAddress*> m_evtAddress + + It is defined in the algorithm's header file in addition to any + other ordinary N-tuple tags, as described in section + :numref:`ntup-dftg`. When booking the N-tuple, + the address tag must be declared like any other tag, as shown in + :numref:`lstg-conncolladdr`. It is recommended to use + the name "Address" for this tag. + + .. was 10.5 + + .. code-block:: cpp + :name: lstg-conncolladdr + :caption: Connecting an address tag to an event collection N-tuple + + StatusCode status = service("EvtTupleSvc", m_evtTupleSvc); + if ( status.isSuccess() ) { + NTuplePtr nt(m_evtTupleSvc, "/NTUPLES/EvtColl/Collection"); + // ... Book N-tuple + // Add an event address column + status = nt->addItem ("Address", m_evtAddress); + + The usage of this tag is identical to any other tag except that it + only accepts variables of type IOpaqueAddress - the information + necessary to retrieve the event data. + + Please note that the event tuple service necessary for writing event + collections is not instantiated by default and hence must be + specified in the job options file: + + .. was 10.6 + + .. code-block:: cpp + :name: lstg-addcolljobopts + :caption: Adding the event tag collection service to the job options + + ApplicationMgr.ExtSvc += { "TagCollectionSvc/EvtTupleSvc" }; + + It is up to the user to locally remember within the algorithm + writing the event collection tuple the reference to the + corresponding service. Although the TagCollectionSvc looks like an + N-tuple service, the implementation is different. + +Filling the Event Collection +````````````````````````````````````` + + At fill time the address of the event must be supplied to the + Address item. Otherwise the N-tuple may be written, but the + information to retrieve the corresponding event data later will be + lost. :numref:`lstg-filladdntupexec` also demonstrates + the setting of a filter to steer whether the event is written out to + the event collection. + + .. was 10.7 + + .. code-block:: cpp + :name: lstg-filladdntupexec + :caption: Fill the address tag of an N-tuple at execution time + + SmartDataPtr<Event> evt(eventSvc(),"/Event"); + if ( evt ) { + // ... Some data analysis deciding whether to keep the event or not + // keep_event=true if event should be written to event collection + setFilterPassed( keep_event ); + m_evtAddrColl = evt->address(); + } + +.. _ntup-ecpe: + +Event Collection Persistency +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Output File Specification +`````````````````````````````````` + + Conversion services exist to convert event collection objects into a + form suitable for persistent storage in a number of storage + technologies. In order to use this facility it is necessary to add + the following line in the job options file: + + .. code-block:: cpp + + EvtTupleSvc.Output = {"FILE1 DATAFILE='coll.root' TYP='ROOT' OPT='NEW'", + "FILE2 ...", + ... + "FILEN ..."}; + + where <coll.root> should be replaced by the name of the file to + which you wish to write the event collection. FILE1 is the logical + name of the output file - it could be any other string. + + The options are the same as for N-tuples (see + :numref:`ntup-spec`) with the following + additions: + + | · TYP='<typ-spec>' + | + | Specifies the type of the output stream. Currently supported types are: + | + | · ROOT: Write as a ROOT tree. + | · MS Access: Write as a Microsoft Access database. + | + | · There is also weak support for the following database types1: + | · SQL Server + | · MySQL + | · Oracle ODBC + | These database technologies are supported through their ODBC interface. They were tested privately on local installations. However all these types need special setup to grant access to the database. + | + | You need to specify the use of the technology specific persistency package (i.e. GaudiRootDb) in your CMT requirements file and to load explicitly in the job options the DLLs containing the generic (GaudiDb) and technology specific (e.g. GaudiRootDb) implementations of the database access drivers: + | ApplicationMgr.DLLs += { "GaudiDb", "GaudiRootDb" }; + | + | · SVC='<service-spec>' (optional) + | + | Connect this file directly to an existing conversion service. This option however needs special care. It should only be used to replace default services. + | + | · AUTHENTICATION='<authentication-specs>' (optional) + | + | For protected datafiles (e.g. Microsoft Access) it can happen that the file is password protected. In this case the authentication string allows to connect to these databases. The connection string in this case is the string that must be passed to ODBC, for example: AUTH='SERVER=server\_host;UID=user\_name;PWD=my\_password;' + | + | · All other options are passed without any interpretation directly to the conversion service responsible to handle the specified output file. + + For all options at most three leading characters are significant: + DATAFILE=<...>, DATABASE=<...> or simply DATA=<...> would lead to + the same result. Additional options are availible when accessing + events using an event tag collection. + +Writing out the Event Collection +````````````````````````````````````````` + + The event collection is written out by an EvtCollectionStream, which + is the last member of the event collection Sequencer. :numref:`lstg-joboptwritevtcoll` (which is taken from the job + options of EvtCollection example), shows how to set up such a + sequence consisting of a user written Selector algorithm (which + could for example contain the code in :numref:`lstg-filladdntupexec`), and of the EvtCollectionStream. + + .. was 10.8 + + .. code-block:: cpp + :name: lstg-joboptwritevtcoll + :caption: Job options for writing out an event collection + + ApplicationMgr.OutStream = { "Sequencer/EvtCollection" }; + ApplicationMgr.ExtSvc += { "TagCollectionSvc/EvtTupleSvc" }; + EvtCollection.Members = { "EvtCollectionWrite/Selector", "EvtCollectionStream/Writer"}; + Writer.ItemList = { "/NTUPLES/EvtColl/Collection" }; + Writer.EvtDataSvc = "EvtTupleSvc"; + EvtTupleSvc.Output = { "EvtColl DATAFILE='MyEvtCollection.root' OPT='NEW' TYP='ROOT'" }; + +.. _ntup-rcol: + +Reading Events using Event Collections +``````````````````````````````````````````````` + + Reading event collections as the input for further event processing + in Gaudi is transparent. The main change is the specification of the + input data to the event selector: + + .. was 10.9 + + .. code-block:: cpp + :name: lstg-connaddtup + :caption: Connecting an address tag to an N-tuple + + EventSelector.Input = { "COLLECTION='Collection' ADDRESS='Address' DATAFILE='MyEvtCollection.root' TYP='ROOT' SEL='(Ntrack>80)' FUN='EvtCollectionSelector'" + }; + + The tags that were not already introduced earlier are: + + | · COLLECTION + | + | Specifies the sub-path of the N-tuple used to write the collection. If the N-tuple which was written was called e.g. "/NTUPLES/FILE1/Collection", the value of this tag must be "Collection". + | + | · ADDRESS (optional) + | + | Specifies the name of the N-tuple tag which was used to store the opaque address to be used to retrieve the event data later. This is an optional tag, the default value is "Address". Please use this default value when writing, conventions are useful! + | + | · SELECTION (optional): + | + | Specifies the selection string used for the first stage pre-selection. The syntax depends on the database implementation; it can be: + | + | · SQL like, if the event collection was written using ODBC. Example: (NTrack>200 AND Energy>200) + | + | · C++ like, if the event collection was written using ROOT. Example: (NTrack>200 && Energy>200). + | + | Note that event collections written with ROOT also accept the SQL operators 'AND' instead of '&&' as well as 'OR' instead of '\|\|'. Other SQL operators are not supported. + | + | · FUNCTION (optional) + | + | Specifies the name of a function object used for the second-stage preselection. An example of a such a function object is shown in :numref:`lstg-exfunobpresel`. Note that the factory declaration on line 16 is mandatory in order to allow Gaudi to instantiate the function object. + | + | · The DATAFILE and TYP tags, as well as additional optional tags, have the same meaning and syntax as for N-tuples, as described in section :numref:`ntup-spec`. + + .. was 10.10 + + .. code-block:: cpp + :name: lstg-exfunobpresel + :caption: Example of a function object for second stage pre-selections + + class EvtCollectionSelector : public NTuple::Selector { + + NTuple::Item<long> m_ntrack; + + public: + + EvtCollectionSelector(IInterface* svc) : NTuple::Selector(svc) { } + virtual ~EvtCollectionSelector() { } + /// Initialization + virtual StatusCode initialize(NTuple::Tuple* nt) { + return nt->item("Ntrack", m_ntrack); + } + + /// Specialized callback for NTuples + virtual bool operator()(NTuple::Tuple* nt) { + return m_ntrack>cut; + } + }; + + ObjectFactory<EvtCollectionSelector> EvtCollectionSelectorFactory + + +Interactive Analysis using Event Tag Collections +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Event tag collections are very similar to N-tuples and hence allow + within limits some interactive analysis. + +ROOT +````````````` + + This data format is used by the interactive ROOT program. Using the + helper library TBlob located in the package GaudiRootDb it is + possible to interactively analyse the N-tuples written in ROOT + format. However, access is only possible to scalar items (int, + float, ...) not to arrays. + + Analysis is possible through directly plotting variables: + + .. code-block:: cpp + + root [1] gSystem->Load("D:/mycmt/GaudiRootDb/v3/Win32Debug/TBlob"); + root [2] TFile* f = new TFile("tuple.root"); + root [3] TTree* t = (TTree*)f->Get("<local>_MC_ROW_WISE_2"); + root [4] t->Draw("pz"); + + or using a ROOT macro interpreted by ROOT's C/C++ interpreter (see + for example the code fragment interactive.C shown in `Listing + 10.11 <GDG_Ntuple.html#1080947>`__): + + .. code-block:: cpp + + root [0] gSystem->Load("D:/mycmt/GaudiRootDb/v3/Win32Debug/TBlob"); + root [1] .L ./v8/NTuples/interactive.C + root [2] interactive("./v8/NTuples/tuple.root"); + + More detailed explanations can be found in the ROOT tutorials + (http://root.cern.ch). + + .. was 10.11 + + .. code-block:: cpp + :name: lstg-rootntupana + :caption: Interactive analysis of ROOT N-tuples: interactive.C + + void interactive(const char* fname) { + TFile *input = new TFile(fname); + TTree *tree = (TTree*)input->Get("<local>_MC_ROW_WISE_2"); + if ( 0 == tree ) { + printf("Cannot find the requested tree in the root file!\n"); + return; + } + Int_t ID, OBJSIZE, NUMLINK, NUMSYMB; + TBlob *BUFFER = 0; + Float_t px, py, pz; + tree->SetBranchAddress("ID",&ID); + tree->SetBranchAddress("OBJSIZE",&OBJSIZE); + tree->SetBranchAddress("NUMLINK",&NUMLINK); + tree->SetBranchAddress("NUMSYMB",&NUMSYMB); + tree->SetBranchAddress("BUFFER", &BUFFER); + tree->SetBranchAddress("px",&px); + tree->SetBranchAddress("py",&py); + tree->SetBranchAddress("pz",&pz); + Int_t nbytes = 0; + for (Int_t i = 0, nentries = tree->GetEntries(); i<nentries;i++) { + nbytes += tree->GetEntry(i); + printf("Trk#=%d PX=%f PY=%f PZ=%f\n",i,px,py,pz); + } + printf("I have read a total of %d Bytes.\n", nbytes); + delete input; + } + +Known Problems +------------------- + + Nothing is perfect and there are always things to be sorted out.... + + | · When building the GaudiRootDb package on Linux using CMT you must first set up the ROOT environment, by sourcing the setup.csh file diff --git a/docs/source/old/GDG_Overview.rst b/docs/source/old/GDG_Overview.rst new file mode 100644 index 0000000000000000000000000000000000000000..32c6bbefc72f4d88d738645695cf1134d2cb810b --- /dev/null +++ b/docs/source/old/GDG_Overview.rst @@ -0,0 +1,266 @@ +.. include:: ./global.rst + +|newpage| + +|Gaudi logo| + +.. _chapOver: + +Introduction +============== + +Purpose of the document +--------------------------- + + This document is intended as a combination of user guide and + tutorial for the use of the Gaudi application framework software. It + is complemented principally by two other "documents": the + Architecture Design Document (ADD) [LHCB-98-064]_, and the online + auto-generated reference documentation [GAUDI-DOXY]_. A third document + [LHCB-98-065]_ lists the User Requirements + and Scenarios that were used as input and validation of the + architecture design. All these documents and other information about + Gaudi, including this user guide and source code documentation, are + available via the Gaudi home page: http://cern.ch/proj-gaudi. + + The ADD contains a discussion of the architecture of the framework, + the major design choices taken in arriving at this architecture and + some of the reasons for these choices. It should be of interest to + anyone who wishes to write anything other than private analysis + code. + + As discussed in the ADD the application framework should be usable + for implementing the full range of offline computing tasks: the + generation of events, simulation of the detector, event + reconstruction, testbeam data analysis, detector alignment, + visualisation, etc. etc.. + + In this document we present the main components of the framework + which are available in the current release of the software. It is + intended to increment the functionality of the software at each + release, so this document will also develop as the framework + increases in functionality. Having said that, physicist users and + developers actually see only a small fraction of the framework code + in the form of a number of key interfaces. These interfaces should + change very little if at all and the user of the framework cares + very little about what goes on in the background. + + The document is arranged as follows: :numref:`chapArch` is a short resume of the + framework architecture, presented from an "Algorithm-centric" point + of view, and re-iterating only a part of what is presented in the + ADD. + + :numref:`chapInst` contains a summary of + the functionality which is present in the current release, and + details of how to obtain and install the software. + + :numref:`chapStar` discusses in some detail + an example which comes with the framework library. It covers the + main program, some of the basic aspects of implementing algorithms, + the specification of job options and takes a look at how the code is + actually executed. The subject of coding algorithms is treated in + more depth in :numref:`chapAlgo`. + + :numref:`chapData` discusses the use of the + framework data stores and event data. :numref:`chapEven` is a placeholder for describing + the experiment specific event data models. :numref:`chapDetd`, :numref:`chapHist`, :numref:`chapNtup` + discuss the other types of data accessible via these stores: + detector description data (material and geometry), histogram data + and n-tuples. + + :numref:`chapServ` deals with services + available in the framework: job options, messages, particle + properties, auditors, chrono & stat, random numbers, incidents, + introspection. It also has a section on developing new services. + Framework tools are discussed in :numref:`chapTool`, the use and implementation of + converter classes in :numref:`chapConv`. + + :numref:`chapScri` discusses scripting as a + means of configuring and controlling the application interactively. + This is followed by a description in :numref:`chapVisu` of how visualisation + facilities might be implemented inside Gaudi. + + :numref:`chapLibr` describes the package + structure of Gaudi and discusses the different types of libraries in + the distribution. + + :numref:`chapUtil` gives pointers to the + documentation for class libraries which we are recommending to be + used within Gaudi. + + :numref:`chapRefe` contains a list of + references. :numref:`chapOpti` lists the + options which may be specified for the standard components available + in the current release. :numref:`chapJobo` gives the details of the syntax + and possible error messages of the job options compiler. Finally, + :numref:`chapDesi` is a small guide to + designing classes that are to be used in conjunction with the + application framework. + +Conventions +--------------- + +Units +~~~~~~~~~~~ + + We have decided to adopt the same system of units as CLHEP, as used + also by GEANT4. This system is fully documented in the CLHEP web + pages, at the URL: http://proj-clhep.web.cern.ch/proj-clhep/doc/CLHEP_1_7/UserGuide/Units/units.html + + The list of basic units is reproduced in :numref:`tab-units`. Note that this differs from the + convention used in GEANT 3, where the basic units of length, time + and energy are, respectively, centimetre, GeV, second.. + + .. table:: CLHEP system of units + :name: tab-units + + +--------------------------------------+--------------------------------------+ + | Quantity | Unit | + +======================================+======================================+ + | Length | millimeter | + +--------------------------------------+--------------------------------------+ + | Time | nanosecond | + +--------------------------------------+--------------------------------------+ + | Energy | MeV | + +--------------------------------------+--------------------------------------+ + | Electric charge | positron charge | + +--------------------------------------+--------------------------------------+ + | Temperature | Kelvin | + +--------------------------------------+--------------------------------------+ + | Amount of substance | mole | + +--------------------------------------+--------------------------------------+ + | Plane angle | radian | + +--------------------------------------+--------------------------------------+ + + Users should not actually need to know what units are used in the + internal representation of the data, as long as they are consistent + throughout the Gaudi data stores. What they care about is that they + can define and plot quantities with the correct units. In some + specialised algorithms they may also wish to renormalise the data to + a different set of units, if the default set would lead to numerical + precision problems. + + We therefore propose the following rules, which are discussed more + fully in reference [LHCB-UNITS]_. + + | 1. All dimensioned quantities in the Gaudi data stores shall conform to the CLHEP system of units. + | 2. All definitions of dimensioned quantities shall be dimensioned by multiplying by the units defined in the CLHEP/Units/SystemOfUnits.h header file. For example: + + .. code-block:: cpp + + const double my_height = 170*cm; + const double my_weight = 75*kg; + + | Note that the user should not care about the numerical value of the numbers my\_height and my\_weight. Internally these numbers are represented as 1700. and 4.68e+26. respectively, but the user does not need to know. + | 3. All output of dimensioned quantities should be converted to the required units by dividing by the units defined in the CLHEP/Units/SystemOfUnits.h header file. For example: + + .. code-block:: cpp + + my_hist = histoSvc()->book( "/stat/diet","corpulence (kg / m ** 2)", 30, 10., 40.); + double my_corpulence = my_weight / ( my_height * my_height ); + my_hist->fill( my_corpulence / ( kg / m2 ), 1. ); + + | which, for a healthy person, should plot a number between 19. and 25.... + | 4. Physical constants should not be defined in user code. They should be taken directly from the CLHEP/Units/PhysicalConstants.h header file. For example: + + .. code-block:: cpp + + float my_rest_energy = my_weight* c_squared; + + | 5. Users may wish to use a different set of units for specific purposes (e.g. when the default units may lead to precision problems). In this case algorithms can renormalise their private copy of the data (as shown in the last line of the rule 3 example) for internal use, but making sure that any data subsequently published to the public data stores is converted back to the CLHEP units. + +Coding Conventions +~~~~~~~~~~~~~~~~~~~~~~~~ + + The Gaudi software follows (or should follow!) the LHCb C++ coding + conventions described in reference [LHCB-2001-054]_. + +File extensions +``````````````````````` + + One consequence of following the LHCb coding conventions is that the + specification of the C++ classes is done in two parts: the header or + ".h" file and the implementation or ".cpp" file. + + We also define file extensions for Gaudi specific files. The + recommended file extension for Job Options files is ".opts" (see + :numref:`serv_jobo`. For + Python scripts, the extension ".py" is mandatory (see :numref:`chapScri`). + +.. _over-name: + +Naming Conventions +~~~~~~~~~~~~~~~~~~~~~~~~ + + | Histograms + | In order to avoid clashes in histogram identifiers, we suggest that histograms are placed in named subdirectories of the transient histogram store. The top level subdirectory should be the name of a sub-detector group (e.g. VELO). Below this, users are free to define their own structure. One possibility is to group all histograms produced by a given algorithm into a directory named after the algorithm. + +Conventions of this document +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + | Angle brackets are used in two contexts. To avoid confusion we outline the difference with an example. + + The definition of a templated class uses angle brackets. These are + required by C++ syntax, so in the instantiation of a templated class + the angle brackets are retained: + + .. code-block:: cpp + + AlgFactory<UserDefinedAlgorithm> s_factory; + + This is to be contrasted with the use of angle brackets to denote + "replacement" such as in the specification of the string: + + .. code-block:: xml + + "<concreteAlgorithmType>/<algorithmName>" + + which implies that the string should look like: + + .. code-block:: cpp + + "EmptyAlgorithm/Empty" + + Hopefully what is intended will be clear from the context. + +Reporting problems +---------------------- + + Users of the Gaudi software are encouraged to report problems and + requests for new features via https://gitlab.cern.ch/gaudi/Gaudi . + + To report a new problem, go to the Gaudi gitlab home page + https://gitlab.cern.ch/gaudi/Gaudi, click on Issue, create a "New Issue" + and fill in the form. This will add the report to the system + and notify the developers by E-mail. You will receive E-mail + notification of any changes in the status of your report. + + To view the list of current problems, and their status click the "List" + button under the Issues tab at https://gitlab.cern.ch/gaudi/Gaudi/issues + + Active developers of the Gaudi software are encouraged to use the + gaudi-developers mailing list for discussion of Gaudi features and + future developments. This list is not, primarily, intended for bug + reports. In order to send mail to gaudi-developers@cern.ch, + you must first subscribe to the list, using the form at + https://e-groups.cern.ch/e-groups/EgroupsSubscription.do?egroupName=gaudi-developers. + You need a CERN mailserver account to be able to use this form ... + + The archive of the mailing list is publically accessible on the Web, + at https://groups.cern.ch/group/gaudi-developers/default.aspx. + +Editor's note +----------------- + + This document is a snapshot of the Gaudi software at the time of the + release of the current version. We have made every effort to ensure that the + information it contains is correct, but in the event of any + discrepancies between this document and information published on the + Web, the latter should be regarded as correct, since it is + maintained between releases and, in the case of code documentation, + it is automatically generated from the code. + + We encourage our readers to provide feedback about the structure, + contents and correctness of this document and of other Gaudi + documentation. Please send your comments to the editor, + Marco.Cattaneo@cern.ch diff --git a/docs/source/old/GDG_Scripting.rst b/docs/source/old/GDG_Scripting.rst new file mode 100644 index 0000000000000000000000000000000000000000..2e8ca89e2f3565ec6d63df18c4d8dc710b0d119b --- /dev/null +++ b/docs/source/old/GDG_Scripting.rst @@ -0,0 +1,388 @@ +.. include:: ./global.rst + +|newpage| + +|Gaudi logo| + +.. _chapScri: + +Scripting and Interactivity +============================== + +Overview +------------- + + A scripting capability has been added to the Gaudi framework. The + current functionality is likely to change rapidly, so users should + check with the latest release notes for changes or new functionality + that might not be documented here. + + In keeping with the design philosophy of the Gaudi architecture, + scripting is defined by an abstract scripting service interface, + with the possibility of there being several different + implementations. The first implementation available is based on + Python, a public-domain programming language. Python is ideal both + as a scripting interface for modern systems, and as a standalone + rapid-development language. Its object-oriented nature mixes well + with frameworks written in C++. + + The Python scripting language will not be described in detail here. + There are many Python books available, among them we recommend: + + | · Learning Python, by M. Lutz & D. Ascher, O'Reilly, 1999 + | · Programming Python (2nd ed.), by M. Lutz, O'Reilly, 2001 + +How to enable Python scripting +----------------------------------- + + Three different mechanisms are available for enabling Python + scripting. + + | 1. Replace the job options text file by a Python script that is specified on the command line. + | 2. Use a job options text file which hands control over to the Python shell once the initial configuration has been established. + | 3. Load and start a Gaudi application from a Python shell. + +Using a Python script for configuration and control +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + One can avoid using a job options text file for configuration by + specifying a Python script as a command line argument, as shown in + :numref:`lstg-pyjobo`. + + .. was 14.1 + + .. code-block:: python + :name: lstg-pyjobo + :caption: Using a Python script for job configuration + + myjob MyPythonScript.py [1] + + Note: The file extension .py is used to identify the job options file as a Python script. All other extensions are assumed to be job options text files. + + This approach may be used in two modes. The first uses such a script + to establish the configuration, but results in the job being left at + the Python shell prompt. This supports interactive sessions. The + second specifies a complete configuration and control sequence and + thus supports a batch style of processing. The particular mode is + controlled by the presence or absence of Gaudi-specific Python + commands described in Section :numref:`scri-ctje`. + +Using a text JobOptions file and giving control to the Python interactive shell +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Python scripting is enabled when using a job options text file for + job configuration by adding the lines shown in :numref:`lsgt-joboptspy` to the job options file. + + .. was 14.2 + + .. code-block:: python + :name: lsgt-joboptspy + :caption: Job Options text file entries to enable Python scripting + + ApplicationMgr.DLLs += { "GaudiPython" }; # [1] + ApplicationMgr.Runable = "PythonScriptingSvc"; # [2] + PythonScriptingSvc.StartupScript = "../options/AnalysisTest.py"; # [3] + + Notes: + + | 1. This entry specifies the component library that implements Python scripting. + | 2. This entry specifies that the Python scripting should take the control (runable) of the application. + | 3. Optional startup python script. + + Once the initial configuration has been established by the job + options text file, control will be handed over to the Python shell + when the startup script, if specified, will be executed. The user + can then issue interactive commands. + +Starting a Gaudi application from the Python shell +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + It is also possible to bootstrap a Gaudi application directly from a + Python shell. The user needs to import the Python extension module + called gaudimodule, which allows the interaction with Gaudi from + Python. :numref:`lstg-expyexegaudi` shows a small + Python program that instantiates a Gaudi application, configure it + and runs for a number of events. This program would work from the + Python shell a long as the environment (LD\_LIBRARY\_PATH/PATH) is + properly set up. + + .. was 14.3 + + .. code-block:: python + :name: lstg-expyexegaudi + :caption: Example of a Python program that executes a Gaudi program + + from gaudimodule import * + theApp = AppMgr() + theApp.JobOptionsType = 'NONE' + theApp.EvtSel = 'NONE' + theApp.config() + theApp.Dlls = ['GaudiAlg'] + myseq = theApp.algorithm('Sequencer/MySeq') + myseq.Members = ['EventCounter/Count1', 'EventCounter/Count2'] + theApp.topAlg = ['MySeq'] + theApp.initialize() + theApp.run(10) + theApp.exit() + + +Current functionality +-------------------------- + + The current functionality is limited to the following capabilities: + + | 1. The ability to set and get basic properties for all framework components (Algorithms, Services, Auditors etc.) and the main ApplicationMgr that controls the application. Arrays of simple properties are mapped into Python Lists. + | 2. The ability to interact with the transient data stores. Browsing store contents, registering, unregistering and retrieving objects, getting and setting object data members (with the help of the IntrospectionSvc) and limited method invocation. + | 3. The ability to interact with the Histograms (1D and 2D) in the transient store. This includes booking, filling, dumping contents, etc. + | 4. The ability to add new services and component libraries and access their capabilities. + | 5. The ability to control the execution of the application by adding Algorithms into the list of top level Algorithms, executing single events or a set of events, executing single Algorithms, etc. + | 6. The ability to define Python Algorithms that will be managed and scheduled as normal Gaudi Algorithms. + +Property manipulation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + An example of the use of the scripting language to display and set + component properties is shown in :numref:`lstg-propmanipsh`: + + .. was 14.4 + + .. code-block:: python + :name: lstg-propmanipsh + :caption: Property manipulation from the Python interactive shell + + >>> theApp [1][2] + <AppMgr object at 00AD22E8> + >>> theApp.ExtSvc [3] + ['IntrospectionSvc', 'ParticlePropertySvc'] + >>> theApp.ExtSvc = theApp.ExtSvc + ['AnotherSvc'] [4] + >>> theApp.ExtSvc + ['IntrospectionSvc', 'ParticlePropertySvc', 'AnotherSvc'] + >>> theApp.EvtMax = 100 + >>> theApp.properties() [5] + {'EvtMax': 100, 'JobOptionsType': 'NONE', 'TopAlg': ['seq1', 'PhysAnalAlg'], 'Go': 0, 'Exit': 0, 'Dlls': ['GaudiAlg', 'GaudiIntrospection'], 'JobOptionsPath': '..\home\test.py', 'OutStream': [], 'OutputLevel': 3, 'EventLoop': 'EventLoopMgr', 'HistogramPersistency': 'NONE', 'EvtSel': 'NONE', 'ExtSvc': ['IntrospectionSvc', 'ParticlePropertySvc', 'AnotherSvc'], 'Runable': 'PythonScriptingSvc'} + >>> theApp.algorithms() [6] + ['seq1', 'WriteAlg', 'PhysAnalAlg'] + >>> alg = Algorithm('WriteAlg') [7] + >>> alg.properties() + {'ErrorCount': 0, 'OutputLevel': 0, 'AuditExecute': 1, 'AuditInitialize': 0, 'Enable': 1, 'AuditFinalize': 0, 'ErrorMax': 1} + + Notes: + + | 1. The ">>>" is the Python shell prompt. Typing the name of a variable, Python prints its value in textual form. + | 2. The variable theApp is always defined and it represents the ApplicationMgr. An alias g has also been defined. + | 3. The name of the property is used as a data member in Python. It returns the correct type directly. + | 4. You can use the properties in normal Python expressions + | 5. The list of all properties (as a Python Dictionary) of a component can be obtained with the method properties(). + | 6. The list of algorithms can be obtained with the method algorithms(). + | 7. To access an Algorithm by name (creating it if it does not exist) the constructor Algorithm() is used. Similarly for services with Service(). + +Creating Algorithms and Services +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + It is possible to create new Algorithms or Services as a result of a + scripting command. Examples of this are shown in :numref:`lstg-expycralg`: + + .. was 14.5 + + .. code-block:: python + :name: lstg-expycralg + :caption: Examples of Python commands that create new Algorithms or Services + + >>> myseq = theApp.algorithm('Sequencer/MySeq') + >>> myseq.members = ['HelloWorld', 'WriteAlg'] + MySeq INFO HelloWorld doesn't exist - created and appended to member list-table + MySeq INFO WriteAlg already exists - appended to member list + >>> theApp.topAlg = ['MySeq'] + >>> g.run(1) + HelloWorld INFO initializing.... + HelloWorld INFO executing.... + WriteAlg INFO Generated event 5 + StatusCode::SUCCESS + + If the specified Algorithm or Service does not exist, it is created. + Its properties can immediately be accessed for read and write. They + will be initialized when the application will start processing + events. + +Interaction with Transient Data Stores +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + It is possible to get the list of data stores and to interact with + them. The following commands are available: + + | theApp.datastores() + | Returns the list of all available data stores (all services that implement the IDataProviderSvc interface). + | + | theApp.datastore(name) + | Returns a generic data store. + | + | theApp.histoSvc() + | Returns the standard histogram data service ("HistogramDataSvc") + | + | theApp.evtSvc() + | Returns the standard event data service ("EventDataSvc") + | + | theApp.detSvc() + | Returns the standard detector data service ("DetectorDataSvc") + | + | theApp.ntupleSvc() + | Returns the standard ntuple data service ("NTupleSvc") + | + | datastore.dump() + | Prints the contents of the transient data store (names and types) + | + | datastore.clear() + | Clears the contents of the transient data store + | + | datastore.object(name), datastore[name], datastore.retrieve(name) + | Retrieves the named object from the transient data store. If the IntrospectionSvc [#]_ is loaded and the dictionaries are available for the requested object then it creates an object that can be introspected. + | + | datastore.register(name, obj), datastore.unregister(name) + | Registers and unregisters an object to/from the data store + | + | datastore.clear(),datastore.clear(name) + | Clears the whole store or a sub-tree. + + A complete example of the capabilities on the interaction with the + event transient store is shown in + + .. code-block:: python + :name: lstg-exinttes + :caption: Example of interaction with the event transient store taken from LHCb + + evt = theApp.evtSvc() + evt.dump() + parts = evt['/Event/MC/MCParticles'] + for p in parts : + print p.particleID.id + +Interaction with Histograms +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The data store commands described in the previous section are also + available for the histogram data store. The following histogram + specific commands are available in addition: + + | histosvc.histo(name), histosvc[name] + | Retrieves the histogram from the histogram data store. It returns either an 1D or 2D histogram. + | + | histosvc.book(id, title, xbin, xmin, xmax [,ybin, ymin, ymax]) + | Books 1D or 2D histogram and registers it in the histogram store. + | + | histo.title(), dim(), mean(), rms(), maxbin(), minbin() + | Returns the title, dimensions, mean, rms, maximum bin contents, minimum bin contents of the histogram + | + | histo.fill(x [,y,w]), histo.reset() + | Fills 1D or 2D histogram, resets the contents + | + | histo.heights(), entries(), errors(), edges() + | Returns in a Python list the heights, entries, errors and edges of the 1D histogram + | + | histo.projections() + | Returns X and Y projections (tuple) of a 2D histogram + +Interaction with Data Objects +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + If the dictionaries of the classes have been loaded by the object + introspection service, then it is possible to browse and interact + with the data objects in the transient store. Loading the + dictionaries is done by configuring the application as it is shown + in :numref:`lstg-confrefljobo` + + .. was 14.7 + + .. code-block:: python + :name: lstg-confrefljobo + :caption: Configuring the Gaudi Introspection Service using the JobOptions text file + + ApplicationMgr.DLLs += { "GaudiIntrospection"}; + pplicationMgr.ExtSvc += { "IntrospectionSvc" }; + IntrospectionSvc.Dictionaries = { "PhysEventDict" }; + + + The following commands are currently available: + + | obj.<attribute> + | Returns the value of the attribute for the object. If the attribute is of a complex type it returns a reference to it, such that it can be browsed recursively. + | + | obj.<attribute> = value + | Sets the value of attribute for the object if this is a simple type. + | + | obj.<method>() + | Invokes the class method. This is currently only available for methods without arguments. + | + | obj.values() + | Returns a Python dictionary with all the attributes and their values. + | + | obj.names() + | Returns a Python list with all the available attribute names. + | + | obj.desc() + | Prints the description of the class of the object. + | + | obj.type() + | Returns the object type (C++ class) + +.. _scri-ctje: + +Controlling job execution +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + There exist a few commands to control the job execution + interactively: + + | theApp.run(number) + | The control is returned from the Python shell to the Gaudi environment with this command. The argument is the number (-1 for infinite) of events to be processed, after which control will be returned to the Python shell. + | + | theApp.exit() + | Typing Ctrl-D (or Ctrl-Z in Windows) at the Python shell prompt will cause an orderly termination of the job. Alternatively, this command will also cause an orderly application termination. + +Physics Analysis Environment +--------------------------------- + + It is possible to declare an Algorithm in Python that can be + declared to the list of top level algorithms to be executed for each + event by the ApplicationMgr. This can be useful for constructing an + interactive physics analysis environment. An example is shown in + :numref:`lstg-exintana` + + .. code-block:: python + :name: lstg-exintana + :caption: Example Analysis + + # -- User analysis algortihm class + class PhysAnalAlg(PyAlgorithm): [1] + + def initialize(self): + global h1 + h1 = his.book('h1','Histogram Test', 10, 0., 10.) + print '....User Analysis Initialized' + return 1 + + def finalize(self): + print 'Finalizing User Analysis...' + return 1 + + def execute(self) + cands = evt['Anal/AxPartCandidates'] + print 'Found '+ \`len(cands)\` + ' candidates' + for c in cands : + h1.fill(c.momentum) + return 1 + + # -- Initialization and Configuration + his = theApp.histoSvc() [2] + evt = theApp.evtSvc() + det = theApp.detSvc() + pdt = PartSvc() + physalg = PhysAnalAlg(theApp,'PhysAnalAlg') [3] + theApp.topAlg = theApp.topAlg + ['PhysAnalAlg'] + + Notes: + + | 1. The analysis algorithm must inherit from the class PyAlgorithm + | 2. Useful variables to avoid long typing + | 3. An instance of the new class needs to be instantiated and declared in the list of top level algorithms. + +.. [#] See :numref:`serv-refl` diff --git a/docs/source/old/GDG_Services.rst b/docs/source/old/GDG_Services.rst new file mode 100644 index 0000000000000000000000000000000000000000..aa3110506df9f4768655f96e5c4e6a8572c39f81 --- /dev/null +++ b/docs/source/old/GDG_Services.rst @@ -0,0 +1,1389 @@ +.. include:: ./global.rst + +|newpage| + +|Gaudi logo| + +.. _chapServ: + +Framework services +===================== + +Overview +------------- + + Services are generally sizeable components that are setup and + initialized once at the beginning of the job by the framework and + used by many algorithms as often as they are needed. It is not + desirable in general to require more than one instance of each + service. Services cannot have a "state" because there are many + potential users of them so it would not be possible to guarantee + that the state is preserved in between calls. + + In this chapter we describe how services are created and accessed, + and then give an overview of the various services, other than the + data access services, which are available for use within the Gaudi + framework. The Job Options service, the Message service, the + Particle Properties service, the Chrono & Stat service, the Auditor + service, the Random Numbers service, the Incident service and the + Introspection service are available in this release. The Tools + service is described in :numref:`chapTool`. + + We also describe how to implement new services for use within the + Gaudi environment. We look at how to code a service, what facilities + the Service base class provides and how a service is managed by the + application manager. + +.. _serv-requ: + +Requesting and accessing services +-------------------------------------- + + The Application manager only creates by default the JobOptionsSvc + and MessageSvc. Other services are created on demand the first time + they are accessed, provided the corresponding DLL has been loaded. + The services in the GaudiSvc package are accessible in this way by + default - these are the default data store services (EventDataSvc, + DetectorDataSvc, HistogramDataSvc, NTupleSvc) and many of the + framework services described in this chapter and in :numref:`chapTool` (ToolSvc, ParticlePropertySvc, + ChronoStatSvc, AuditorSvc, RndmGenSvc, IncidentSvc). + + Additional services can be made accessible by loading the + appropriate DLL, using the property ApplicationMgr.DLLs in the job + options file, as shown for example in :numref:`lstg-optsoutsto`. + + Sometimes it may be necessary to force the Application Manager to + create a service at initialisation (for example if the order of + creation is important). This can be done using the property + ApplicationMgr.ExtSvc. In the example below this option is used to + create a specific type of persistency service.: + + .. was 11.1 + + .. code-block:: cpp + :name: joboptaddserv + :caption: Job Option to create additional services + + ApplicationMgr.ExtSvc += { "DbEventCnvSvc/RootEvtCnvSvc" }; + + Once created, services must be accessed via their interface. The + Algorithm base class provides a number of accessor methods for the + standard framework services, listed on lines 25 to 36 + of :numref:`lstg-algobase`. Other services can be + located using the templated service function. In the example below + we use this function to return the IParticlePropertySvc interface of + the Particle Properties Service: + + .. was 11.2 + + .. code-block:: cpp + :name: ipartpropsvcint + :caption: Code to access the IParticlePropertySvc interface from an Algorithm + + #include "GaudiKernel/IParticlePropertySvc.h" + // ... + IParticlePropertySvc* m_ppSvc; + StatusCode sc = service( "ParticlePropertySvc", m_ppSvc, true ); + if ( sc.isFailure) { + // ... + + The third argument is optional: when set to true, the service will + be created if it does not already exist; if it is missing, or set to + false, the service will not be created if it is not found, and an + error is returned. + + In components other than Algorithms and Services (e.g. Tools, + Converters), which do not provide the service function, you can + locate a service using the serviceLocator function: + + .. code-block:: cpp + + #include "GaudiKernel/IParticlePropertySvc.h" + // ... + IParticlePropertySvc* m_ppSvc; + IService* theSvc; + StatusCode sc=serviceLocator()->getService("ParticlePropertySvc",theSvc,true); + if ( sc.isSuccess() ) { + sc = theSvc->queryInterface(IID_IParticlePropertySvc, (void**)&m_ppSvc); + } + if ( sc.isFailure) { + // ... + +.. _serv-jopt: + +The Job Options Service +---------------------------- + + The Job Options Service is a mechanism which allows to configure an + application at run time, without the need to recompile or relink. + The options, or properties, are set via a job options file, which is + read in when the Job Options Service is initialised by the + Application Manager. In what follows we describe the format of the + job options file, including some examples. + +.. _serv-prop: + +Algorithm, Tool and Service Properties +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + In general a concrete Algorithm, Service or Tool will have several + data members which are used to control execution. These data members + (properties) can be of a basic data type (int, float, etc.) or class + (Property) encapsulating some common behaviour and higher level of + functionality. Each concrete Algorithm, Service, Tool declares its + properties to the framework using the declareProperty templated + method as shown for example on line 12 of :numref:`evtcounter` + (see also :numref:`algo-decl`). The method + setProperties() is called by the framework in the initialization + phase; this causes the job options service to make repeated calls to + the setProperty() method of the Algorithm, Service or Tool (once for + each property in the job options file), which actually assigns + values to the data members. + +SimpleProperties +````````````````````````` + + Simple properties are a set of classes that act as properties + directly in their associated Algorithm, Tool or Service, replacing + the corresponding basic data type instance. The primary motivation + for this is to allow optional bounds checking to be applied, and to + ensure that the Algorithm, Tool or Service itself doesn't violate + those bounds. Available SimpleProperties are: + + | · int ==> IntegerProperty or SimpleProperty<int> + | · double ==> DoubleProperty or SimpleProperty<double> + | · bool ==> BooleanProperty or SimpleProperty<bool>) + | · std::string ==> StringProperty or SimpleProperty<std::string> + + and the equivalent vector classes + + | · std::vector<int> ==> IntegerArrayProperty or SimpleProperty<std::vector<int>> + | · etc. + + The use of these classes is illustrated by the EventCounter class + (Listings :numref:`evtcounterheader` and :numref:`evtcounter`). + + .. was 11.3 + + .. code-block:: cpp + :name: evtcounterheader + :caption: EventCounter.h + + #include "GaudiKernel/Algorithm.h" + #include "GaudiKernel/Property.h" + + class EventCounter : public Algorithm { + + public: + + EventCounter( const std::string& name, ISvcLocator* pSvcLocator ); + ~EventCounter( ); + StatusCode initialize(); + StatusCode execute(); + StatusCode finalize(); + + private: + + IntegerProperty m_frequency; + int m_skip; + int m_total; + }; + + .. was 11.4 + + .. code-block:: cpp + :name: evtcounter + :caption: EventCounter.cpp + + #include "GaudiAlg/EventCounter.h" + #include "GaudiKernel/MsgStream.h" + #include "GaudiKernel/AlgFactory.h" + + static const AlgFactory<EventCounter> Factory; + const IAlgFactory& EventCounterFactory = Factory; + + EventCounter::EventCounter(const std::string& name, ISvcLocator* pSvcLocator) : + Algorithm(name, pSvcLocator), m_skip ( 0 ), m_total( 0 ) { + declareProperty( "Frequency", m_frequency=1 ); // [1] + m_frequency.setBounds( 0, 1000 ); // [2] + } + + StatusCode EventCounter::initialize() { + MsgStream log(msgSvc(), name()); + log << MSG::INFO << "Frequency: " << m_frequency << endreq; // [3] + return StatusCode::SUCCESS; + } + + In the Algorithm constructor, when calling declareProperty, you can + optionally set the bounds using any of: + + | setBounds( const T& lower, const T& upper ); + | setLower ( const T& lower ); + | setUpper ( const T& upper ); + + There are similar selectors and modifiers to determine whether a + bound has been set etc., or to clear a bound. + + | bool hasLower( ) + | bool hasUpper( ) + | T lower( ) + | T upper( ) + | void clearBounds( ) + | void clearLower( ) + | void clearUpper( ) + + You can set the value using the "=" operator or the set functions + + | bool set( const T& value ) + | bool setValue( const T& value ) + + The function value indicates whether the new value was within any + bounds and was therefore successfully updated. In order to access + the value of the property, use: + + | m\_property.value( ); + + In addition there's a cast operator, so you can also use m\_property + directly instead of m\_property.value(). + +CommandProperty +```````````````````````` + + CommandProperty is a subclass of StringProperty that has a handler + that is called whenever the value of the property is changed. + Currently that can happen only during the job initialization so it + is not terribly useful. Alternatively, an Algorithm could set the + property of one of its sub-algorithms. However, it is envisaged that + Gaudi will be extended with a scripting language such that + properties can be modified during the course of execution. + + The relevant portion of the interface to CommandProperty is: + + .. code-block:: cpp + + class CommandProperty : public StringProperty { + public: + + // [...] + virtual void handler( const std::string& value ) = 0; + [...] + }; + + Thus subclasses should override the handler() member function, which + will be called whenever the property value changes. A future + development is expected to be a ParsableProperty (or something + similar) that would offer support for parsing the string. + +.. _serv-modi: + +Accessing and modifiying properties +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Properties are private data which are initialised by the framework + using the default values given when they are declared in + constructors, or the values read from the job options file. On + occasions it may be necessary for components to access (or even + modify) the values of properties of other components. This can be + done by using the getProperty() and setProperty() methods of the + IProperty interface. In the example below, + + .. code-block:: cpp + + Algorithm* myAlg; + // ... + std:string dfltCut; + StatusCode sc = myAlg->getProperty( "TheCut", dfltCut ); + if ( sc.isSuccess() ) { + msgAlg->setProperty( "TheCut", "0.8" ); + StatusCode sc1 = myAlg->execute(); + // ... + } + if( scl.isSuccess() ) msgProp->setProperty( "The Cut", dfltCut ); + + ,an algorithm stores the default value of a cut of its + sub-algorithm, then executes the sub-algorithm with a different cut, + before resetting the cut back to its default value. Note that in the + example we begin with a pointer to an Algorithm object, not an + IAlgorithm interface. This means that we have access to the methods + of both the IAlgorithm and IProperty interfaces and can therefore + call the methods of the IProperty interface. In the general one may + need to navigate to the IProperty interface first, as explaned in + :numref:`libr-quin`. + +.. _serv_jobo: + +Job options file format +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + An example of a job options file was shown in :numref:`optionsio`. + The job options file has a + well-defined syntax (similar to a simplified C++-Syntax) without + data types. The data types are recognised by the "Job Options + Compiler", which interprets the job options file according to the + syntax (described in :numref:`chapJobo` + together with possible compiler error codes). + + The job options file is an ASCII-File, composed logically of a + series of statements. The end of a statement is signalled by a + semicolon ";" - as in C++. + + Comments are the same as in C++, with '//' until the end of the + line, or between '/\*' and '\*/'. + + There are four constructs which can be used in a job options file: + + | · Assignment statement + | · Append statement + | · Include directive + | · Platform dependent execution directive + +Assignment statement +````````````````````````````` + + An assignment statement assigns a certain value (or a vector of + values) to a property of an object or identifier. An assignment + statement has the following structure: + + .. code-block:: cpp + + <Object / Identifier> . < Propertyname > = < value >; + + The first token (Object / Identifier) specifies the name of the + object whose property is to be set. This must be followed by a dot + ('.') + + The next token (Propertyname) is the name of the option to be set, + as declared in the declareProperty() method of the IProperty + interface. This must be followed by an assign symbol ('='). + + The final token (value) is the value to be assigned to the property. + It can be a vector of values, in which case the values are enclosed + in array brackets ('{\`,'}\`), and separated by commas (,). The + token must be terminated by a semicolon (';'). + + The type of the value(s) must match that of the variable whose value + is to be set, as declared in declareProperty(). The following types + are recognised: + + | Boolean-type, written as true or false. e.g. true; false; + | + | Integer-type, written as an integer value (containing one or more of the digits '0', '1', '2', '3', '4', '5', '6', '7', '8', '9') e.g.: 123; -923; or in scientific notation, e.g.: 12e2; + | + | Real-type (similar to double in C++), written as a real value (containing one or more of the digits '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' followed by a dot '.' and optionally one or more of digits again) e.g.: 123.; -123.45; or in scientific notation, e.g. 12.5e7; + | + | String type, written within a pair of double quotes (\` " ') e.g.: "I am a string"; (Note: strings without double quotes are not allowed!) + | + | Vector of the types above, within array-brackets ('{', '}'), separated by a comma (',') e.g.: {true, false, true}; {124, -124, 135e2}; {123.53, -23.53, 123., 12.5e2}; {"String 1", "String 2", "String 3"}; + | + | A single element which should be stored in a vector must be within array-brackets without a comma e.g. {true}; {"String"}; + | + | A vector which has already been defined earlier in the file (or in included files) can be reset to an empty vector e.g. {}; + +Append Statement +````````````````````````` + + Because of the possibility of including other job option files (see + below), it is sometimes necessary to extend a vector of values + already defined in the other job option file. This functionality is + provided be the append statement. + + An append statement has the following syntax: + + .. code-block:: cpp + + <Object / Identifier> . < Propertyname > += < value >; + + The only difference from the assignment statement is that the append + statement requires the '+=' symbol instead of the \`=' symbol to + separate the Propertyname and value tokens. + + The value must be an array of one or more values + + | e.g.: {true}; + | e.g.: {"String"}; + | e.g.: {true, false, true}; + | e.g.: {124, -124, 135e2}; + | e.g.: {123.53, -23.53, 123., 12.5e2}; + | e.g.: {"String 1", "String 2", "String 3"}; + + The job options compiler itself tests if the object or identifier + already exists (i.e. has already been defined in an included file) + and the type of the existing property. If the type is compatible and + the object exists the compiler appends the value to the existing + property. If the property does not exist then the append operation + "+=" behaves as assignment operation "=". + +Including other Job Option Files +````````````````````````````````````````` + + It is possible to include other job option files in order to use + pre-defined options for certain objects. This is done using the + #include directive: + + .. code-block:: cpp + + #include "filename.opts" + + The "filename" can also contain the path where this file is located. + By convention we use ".opts" as the file extension for job options. + The include directive can be placed anywhere in the job option file, + usually at the top (as in C++). Note that the value of a property + defined earlier in the file may be over-ridden by assigning a new + value to the same property: the last value assigned is the valid + value! This makes it possible to over-ride the value of a property + defined in a previously included file without changing the include + file. + + It is possible to use environment variables in the #include + statement, either standalone or as part of a string. Both Unix style + ("$environmentvariable") and Windows style ("%environmentvariable%") + are understood (on both platforms!). For example, in line 2 of :numref:`optionsio` + the logical name $STDOPTS, which + is defined in the GaudiExamples package, points to a directory + containing a number of standard job options include files that can + be used by applications. + + As mentioned above, you can append values to vectors defined in an + included job option file. The interpreter creates these vectors at + the moment he interprets the included file, so you can only append + elements defined in a file included before the append-statement! + + As in C/C++, an included job option file can include other job + option files. The compiler checks itself whether the include file + has already been included, so there is no need for #ifndef + statements as in C or C++ to check for multiple inclusion. + +Platform dependent execution +````````````````````````````````````` + + The possibility exists to execute statements only according to the + used platform. Statements within platform dependent clauses are only + executed if they are asserted to the current used platform.: + + .. code-block:: cpp + + #ifdef WIN32 + // (Platform-Dependent Statement) + #else (optional) + // (Platform-Dependent Statement) + #endif + + Only the variable WIN32 is defined! An #ifdef WIN32 will check if + the used platform is a Windows platform. If so, it will execute the + statements until an #endif or an optional #else. On non-Windows + platforms it will execute the code within #else and #endif. + Alternatively one directly can check for a non-Windows platform by + using the #ifndef WIN32 clause. + +Switching on/off printing +`````````````````````````````````` + + By default, the Job Options Service prints out the contents of the + Job Options files to the standard output destination. The + possibility exists to switch off this printing, and to toggle + between the two states, as shown below: + + .. code-block:: cpp + + // Switch off printing + #pragma print off + // ..(some job options) + //Switch printing back on + #pragma print on + + In the example above, all lines between line 2 and line + 5 will not be printed. + +.. _serv-mess: + +The Standard Message Service +--------------------------------- + + One of the components directly visible to an algorithm object is the + message service. The purpose of this service is to provide + facilities for the logging of information, warnings, errors etc. The + advantage of introducing such a component, as opposed to using the + standard std::cout and std::cerr streams available in C++ is that we + have more control over what is printed and where it is printed. + These considerations are particularly important in an online + environment. + + The Message Service is configurable via the job options file to only + output messages if their "activation level" is equal to or above a + given "output level". The output level can be configured with a + global default for the whole application: + + .. code-block:: cpp + + // Set output level threshold + //(1=VERBOSE, 2=DEBUG, 3=INFO, 4=WARNING, 5=ERROR, 6=FATAL, 7=ALWAYS) + MessageSvc.OutputLevel = 4; + + and/or locally for a given client object (e.g. myAlgorithm): + + .. code-block:: cpp + + myAlgorithm.OutputLevel = 2; + + Any object wishing to print some output should (must) use the + message service. A pointer to the IMessageSvc interface of the + message service is available to an algorithm via the accessor method + msgSvc(), see section :numref:`algo-base`. It is + of course possible to use this interface directly, but a utility + class called MsgStream is provided which should be used instead. + +The MsgStream utility +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The MsgStream class is responsible for constructing a Message object + which it then passes onto the message service. Where the message is + ultimately sent to is decided by the message service. + + In order to avoid formatting messages which will not be sent because + the verboseness level is too high, a MsgStream object first checks + to see that a message will be printed before actually constructing + it. However the threshold for a MsgStream object is not dynamic, + i.e. it is set at creation time and remains the same. Thus in order + to keep synchronized with the message service, which in principle + could change its printout level at any time, MsgStream objects + should be made locally on the stack when needed. For example, if you + look at the listing of the HelloWorld class (see also :numref:`usemsgstrobj` + below) you will note that + MsgStream objects are instantiated locally (i.e. not using new) in + all three of the IAlgorithm methods and thus are destructed when the + methods return. If this is not done messages may be lost, or too + many messages may be printed. + + The MsgStream class has been designed to resemble closely a normal + stream class such as std::cout, and in fact internally uses an + ostrstream object. All of the MsgStream member functions write + unformatted data; formatted output is handled by the insertion + operators. + + An example use of the MsgStream class is shown below. + + .. was 11.5 + + .. code-block:: cpp + :name: usemsgstrobj + :caption: Use of a MsgStream object + + #include "GaudiKernel/MgsStream.h" + + StatusCode myAlgo::finalize() { + StatusCode status = Algorithm::finalise(); + MsgStream log(msgSvc(), name()); + if ( status.isFailure() ) { + // Print a two line message in case of failure. + log << MSG::ERROR << " Finalize failed" << endl + << "Error initializing Base class." << endreq; + } + else { + log << MSG::DEBUG << "Finalize completed successfully" << endreq; + } + return status; + } + + When using the MsgStream class just think of it as a configurable + output stream whose activation is actually controlled by the first + word (message level) and which actually prints only when "endreq" is + supplied. For all other functionality simply refer to the C++ + ostream class. + + The "activation level" of the MsgStream object is controlled by the + first expression, e.g. MSG::ERROR or MSG::DEBUG in the example + above. Possible values are given by the enumeration below: + + .. code-block:: cpp + + enum MSG::Level { VERBOSE, DEBUG, INFO, WARNING, ERROR, FATAL, ALWAYS }; + + Thus the code in :numref:`usemsgstrobj` will + produce NO output if the print level of the message service is set + higher than MSG::ERROR. In addition if the service's print level is + lower than or equal to MSG::DEBUG the "Finalize completed + successfully" message will be printed (assuming of course it was + successful). + + | User interface + | + | What follows is a technical description of the part of the MsgStream user interface most often seen by application developers. Please refer to the header file for the complete interface. + | + | Insertion Operator + | + | The MsgStream class overloads the '<<\` operator as described below. + | + | MsgStream& operator <<(TYPE arg); + | Insertion operator for various types. The argument is only formatted by the stream object if the print level is sufficiently high and the stream is active. Otherwise the insertion operators simply return. Through this mechanism extensive debug printout does not cause large run-time overheads. All common base types such as char, unsigned char, int, float, etc. are supported + | + | MsgStream& operator <<(MSG::Level level); + | This insertion operator does not format any output, but rather (de)activates the stream's formatting and forwarding engine depending on the value of level. + | + | Accepted Stream Manipulators + | + | The MsgStream specific manipulators are presented below, e.g. endreq: MsgStream& endreq(MsgStream& stream). Besides these, the common ostream and ios manipulators such as std::ends, std::endl,... are also accepted. + | + | endl + | Inserts a newline sequence. Opposite to the ostream behaviour this manipulator does not flush the buffer. Full name: MsgStream& endl(MsgStream& s) + | ends + | Inserts a null character to terminate a string. Full name: MsgStream& ends(MsgStream& s) + | flush + | Flushes the stream's buffer but does not produce any output! Full name: MsgStream& flush(MsgStream& s) + | endreq + | Terminates the current message formatting and forwards the message to the message service. If no message service is assigned the output is sent to std::cout. Full name: MsgStream& endreq(MsgStream& s) + | endmsg + | Same as endreq + +.. _serv-prse: + +The Particle Properties Service +------------------------------------ + + The Particle Property service is a utility to find information about a named particle's Geant3 ID, Jetset/Pythia ID, Geant3 tracking type, charge, mass or lifetime. The database used by the service can be changed, but by default is the same as that used by the LHCb SICB program. Note that the units conform to the CLHEP convention, in particular MeV for masses and ns for lifetimes. Any comment to the contrary in the code is just a leftover which has been overlooked! + +Initialising and Accessing the Service +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + This service is created by adding the following line in the Job + Options file:: + + .. code-block:: cpp + + // Create the particle properties service + ApplicationMgr.ExtSvc += { "ParticlePropertySvc" }; + + :numref:`ipartpropsvcint` shows how to access this + service from within an algorithm. + +Service Properties +~~~~~~~~~~~~~~~~~~~~~~~~~ + + The Particle Property Service currently only has one property: + ParticlePropertiesFile. This string property is the name of the + database file that should be used by the service to build up its + list of particle properties. The default value of this property, on + all platforms, is $LHCBDBASE/cdf/particle.cdf [#]_ + +Service Interface +~~~~~~~~~~~~~~~~~~~~~~~~ + + The service implements the IParticlePropertySvc interface. In order + to use it, clients must include the file + GaudiKernel/IParticlePropertySvc.h. + + The service itself consists of one STL vector to access all of the + existing particle properties, and three STL maps, one to map + particles by name, one to map particles by Geant3 ID and one to map + particles by stdHep ID. + + Although there are three maps, there is only one copy of each + particle property and thus each property must have a unique particle + name and a unique Geant3 ID. Particles that are known to Geant but + not to stdHep, such as Deuteron, have an artificial stdHep ID using + unreserved (>7) digits. Although retrieving particles by name should + be sufficient, the second and third maps are there because most + often generated data stores a particle's Geant3 ID or stdHep ID, and + not the particle's name. These maps speed up searches using the IDs. + + The IParticlePropertySvc interface provides the following functions: + + .. was 11.6 + + .. code-block:: cpp + :name: ipartpropsvcint2 + :caption: The IParticlePropertySvc interface + + // IParticlePropertySvc interface: + // Create a new particle property. + // Input: particle, String name of the particle. + // Input: geantId, Geant ID of the particle. + // Input: jetsetId, Jetset ID of the particle. + // Input: type, Particle type. + // Input: charge, Particle charge (/e). + // Input: mass, Particle mass (MeV). + // Input: tlife, Particle lifetime (ns). + // Return: StatusCode - SUCCESS if the particle property was added. + virtual StatusCode push_back( const std::string& particle, int geantId, int jetsetId, int type, double charge, double mass, double tlife ); + // Create a new particle property. + // Input: pp, a particle property class. + // Return: StatusCode - SUCCESS if the particle property was added. + virtual StatusCode push_back( ParticleProperty* pp ); + // Get a const reference to the begining of the map. + virtual const_iterator begin() const; + // Get a const reference to the end of the map. + virtual const_iterator end() const; + // Get the number of properties in the map. + virtual int size() const; + // Retrieve a property by geant id. + // Pointer is 0 if no property found. + virtual ParticleProperty* find( int geantId ); + // Retrieve a property by particle name. + // Pointer is 0 if no property found. + virtual ParticleProperty* find( const std::string& name ); + // Retrieve a property by StdHep id + // Pointer is 0 if no property found. + virtual ParticleProperty* findByStdHepID( int stdHepId ); + // Erase a property by geant id. + virtual StatusCode erase( int geantId ); + // Erase a property by particle name. + virtual StatusCode erase( const std::string& name ); + // Erase a property by StdHep id + virtual StatusCode eraseByStdHepID( int stdHepId ); + + The IParticlePropertySvc interface also provides some typedefs for + easier coding: + + .. code-block:: cpp + + typedef ParticleProperty* mapped_type; + typedef std::map< int, mapped_type, std::less<int> > MapID; + typedef std::map< std::string, mapped_type, std::less<std::string> > MapName; + typedef std::map< int, mapped_type, std::less<int> > MapStdHepID; + typedef IParticlePropertySvc::VectPP VectPP; + typedef IParticlePropertySvc::const_iterator const_iterator; + typedef IParticlePropertySvc::iterator iterator; + +Examples +~~~~~~~~~~~~~~~ + + Below are some extracts of code from the LHCb ParticleProperties + example to show how one might use the service: + + .. was 11.7 + + .. code-block:: cpp + :name: findpartpropbyname + :caption: Code fragment to find particle properties by particle name + + // Try finding particles by the different methods + log << MSG::INFO << "Trying to find properties by Geant3 ID..." << endreq; + ParticleProperty* pp1 = m_ppSvc->find( 1 ); + if ( pp1 ) log << MSG::INFO << *pp1 << endreq; + log << MSG::INFO << "Trying to find properties by name..." << endreq; + ParticleProperty* pp2 = m_ppSvc->find( "e+" ); + if ( pp2 ) log << MSG::INFO << *pp2 << endreq; + log << MSG::INFO << "Trying to find properties by StdHep ID..." << endreq; + ParticleProperty* pp3 = m_ppSvc->findByStdHepID( 521 ); + if ( pp3 ) log << MSG::INFO << *pp3 << endreq; + + .. was 11.8 + + .. code-block:: cpp + :name: usemapitaccprop + :caption: Code fragment showing how to use the map iterators to access particle properties + + // List all properties + log << MSG::DEBUG << "Listing all properties..." << endreq; + for( IParticlePropertySvc::const_iterator i = m_ppSvc->begin(); i != m_ppSvc->end(); i++ ) { + if ( *i ) log << *(*i) << endreq; + } + + +The Chrono & Stat service +------------------------------ + + The Chrono & Stat service provides a facility to do time profiling + of code (Chrono part) and to do some statistical monitoring of + simple quantities (Stat part). The service is created by default by + the Application Manager, with the name "ChronoStatSvc" and service + ID extern const CLID& IID\_IChronoStatSvc To access the service from + inside an algorithm, the member function chronoSvc() is provided. + The job options to configure this service are described in + :numref:`chapOpti`, :numref:`tab-b20`. + +Code profiling +~~~~~~~~~~~~~~~~~~~~~ + + Profiling is performed by using the chronoStart() and chronoStop() + methods inside the codes to be profiled, e.g: + + .. code-block:: cpp + + /// ... + IChronoStatSvc* svc = chronoSvc(); + /// start + svc->chronoStart( "Some Tag" ); + /// here some user code are placed: + // ... + /// stop + svc->chronoStop( "SomeTag" ); + + + The profiling information accumulates under the tag name given as + argument to these methods. The service measures the time elapsed + between subsequent calls of chronoStart() and chronoStop() with the + same tag. The latter is important, since in the sequence of calls + below, only the elapsed time between lines 3 and 5 lines and between + lines 7 and 9 lines would be accumulated.: + + .. code-block:: cpp + + svc->chronoStop("Tag"); + svc->chronoStop("Tag"); + svc->chronoStart("Tag"); + svc->chronoStart("Tag"); + svc->chronoStop("Tag"); + svc->chronoStop("Tag"); + svc->chronoStart("Tag"); + svc->chronoStart("Tag"); + svc->chronoStop("Tag"); + + The profiling information could be printed either directly using the + chronoPrint() method of the service, or in the summary table of + profiling information at the end of the job. + + Note that this method of code profiling should be used only for fine + grained monitoring inside algorithms. To profile a complete + algorithm you should use the Auditor service, as described in + section :numref:`serv-audi`. + +Statistical monitoring +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Statistical monitoring is performed by using the stat() method + inside user code: + + .. code-block:: cpp + + /// ... Flag and Weight to be accumulated: + svc->stat( " Number of Tracks " , Flag , Weight ); + + The statistical information contains the "accumulated" flag, which + is the sum of all Flags for the given tag, and the "accumulated" + weight, which is the product of all Weights for the given tag. The + information is printed in the final table of statistics. + + In some sense the profiling could be considered as statistical + monitoring, where the variable Flag equals the elapsed time of the + process. + +Chrono and Stat helper classes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + To simplify the usage of the Chrono & Stat Service, two helper + classes were developed: class Chrono and class Stat. Using these + utilities, one hides the communications with Chrono & Stat Service + and provides a more friendly environment. + +Chrono +``````````````` + + Chrono is a small helper class which invokes the chronoStart() + method in the constructor and the chronoStop() method in the + destructor. It must be used as an automatic local object. + + It performs the profiling of the code between its own creation and + the end of the current scope, e.g: + + .. code-block:: cpp + + #include GaudiKernel/Chrono.h + /// ... + { // begin of the scope + Chrono chrono( chronoSvc() , "ChronoTag" ) ; + /// some codes: + // ... + /// + } // end of the scope + /// ... + + If the Chrono & Stat Service is not accessible, the Chrono object + does nothing + +Stat +````````````` + + Stat is a small helper class, which invokes the stat() method in the + constructor. + + .. code-block:: cpp + + GaudiKernel/Stat.h + /// ... + Stat stat( chronoSvc() , "StatTag" , Flag , Weight ) ; + /// ... + + If the Chrono & Stat Service is not accessible, the Stat object does + nothing. + +Performance considerations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The implementation of the Chrono & Stat Service uses two std::map + containers and could generate a performance penalty for very + frequent calls. Usually the penalty is small relative to the elapsed + time of algorithms, but it is worth avoiding both the direct usage + of the Chrono & Stat Service as well as the usage of it through the + Chrono or Stat utilities inside internal loops: + + .. code-block:: cpp + + /// ... + { /// begin of the scope + Chrono chrono( chronoSvc() , "Good Chrono"); /// OK + long double a = 0 ; + for( long i = 0 ; i < 1000000 ; ++i ) + { + Chrono chrono( svc , "Bad Chrono"); /// not OK + /// some codes : + a += sin( cos( sin( cos( (long double) i ) ) ) ); + /// end of codes + Stat stat ( svc , "Bad Stat", a ); /// not OK + } + Stat stat ( svc , "Good Stat", a); /// OK + } /// end of the scope! + /// ... + +.. _serv-audi: + +The Auditor Service +------------------------ + + The Auditor Service provides a set of auditors that can be used to + provide monitoring of various characteristics of the execution of + Algorithms. Each auditor is called immediately before and after each + call to each Algorithm instance, and can track some resource usage + of the Algorithm. Calls that are thus monitored are initialize(), + execute() and finalize(), although monitoring can be disabled for + any of these for particular Algorithm instances. Only the execute() + function monitoring is enabled by default. + + Several examples of auditors are provided. These are: + + | · NameAuditor. This just emits the name of the Algorithm to the Standard Message Service immediately before and after each call. It therefore acts as a diagnostic tool to trace program execution. + | · ChronoAuditor. This monitors the cpu usage of each algorithm and reports both the total and per event average at the end of job. + | · MemoryAuditor. This monitors the state of memory usage during execution of each Algorithm, and will warn when memory is allocated within a call without being released on exit. Unfortunately this will in fact be the general case for Algorithms that are creating new data and registering them with the various transient stores. Such Algorithms will therefore cause warning messages to be emitted. However, for Algorithms that are just reading data from the transient stores, these warnings will provide an indication of a possible memory leak. Note that currently the MemoryAuditor is only available for Linux. + | · MemStatAuditor. The same as MemoryAuditor, but prints a table of memory usage statistics at the end. + +Enabling the Auditor Service and specifying the enabled Auditors +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The Auditor Service is enabled by the following line in the Job + Options file: + + .. code-block:: cpp + + // Enable the Auditor Service + ApplicationMgr.DLLs += { "GaudiAud" }; + + Specifying which auditors are enabled is illustrated by the + following example: + + .. code-block:: cpp + + // Enable the NameAuditor and ChronoAuditor + AuditorSvc.Auditors = { "NameAuditor", "ChronoAuditor" }; + +Overriding the default Algorithm monitoring +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + By default, only monitoring of the Algorithm execute() function is + enabled by default. This default can be overridden for individual + Algorithms by use of the following Algorithm properties: + + .. code-block:: cpp + + // Enable initialize and finalize auditing & disable execute auditing + // for the myAlgorithm Algorithm + myAlgorithm.AuditInitialize = true; + myAlgorithm.AuditExecute = false; + myAlgorithm.AuditFinalize = true; + +Implementing new Auditors +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The relevant portion of the IAuditor abstract interface is shown + below: + + .. code-block:: cpp + + virtual StatusCode beforeInitialize( IAlgorithm* theAlg ) = 0; + virtual StatusCode afterInitialize ( IAlgorithm* theAlg ) = 0; + virtual StatusCode beforeExecute ( IAlgorithm* theAlg ) = 0; + virtual StatusCode afterExecute ( IAlgorithm* theAlg ) = 0; + virtual StatusCode beforeFinalize ( IAlgorithm* theAlg ) = 0; + virtual StatusCode afterFinalize ( IAlgorithm* theAlg ) = 0; + + A new Auditor should inherit from the Auditor base class and + override the appropriate functions from the IAuditor abstract + interface. The following code fragment is taken from the + ChronoAuditor: + + .. code-block:: cpp + + #include "GaudiKernel/Auditor.h" + class ChronoAuditor : virtual public Auditor { + + public: + + ChronoAuditor(const std::string& name, ISvcLocator* pSvcLocator); + virtual ~ChronoAuditor(); + virtual StatusCode beforeInitialize(IAlgorithm* alg); + virtual StatusCode afterInitialize(IAlgorithm* alg); + virtual StatusCode beforeExecute(IAlgorithm* alg); + virtual StatusCode afterExecute(IAlgorithm* alg); + virtual StatusCode beforeFinalize(IAlgorithm* alg); + virtual StatusCode afterFinalize(IAlgorithm* alg); + }; + +The Random Numbers Service +------------------------------- + + When generating random numbers two issues must be considered: + + | · reproducibility and + | · randomness of the generated numbers. + + In order to ensure both, Gaudi implements a single service ensuring + that these criteria are met. The encapsulation of the actual random + generator into a service has several advantages: + + | · Random seeds are set by the framework. When debugging the detector simulation, the program could start at any event independent of the events simulated before. Unlike the random number generators that were known from CERNLIB, the state of modern generators is no longer defined by one or two numbers, but rather by a fairly large set of numbers. To ensure reproducibility the random number generator must be initialized for every event. + | · The distribution of the random numbers generated is independent of the random number engine behind. Any distribution can be generated starting from a flat distribution. + | · The actual number generator can easily be replaced if at some time in the future better generators become available, without affecting any user code. + + The implementation of both generators and random number engines are + taken from CLHEP. The default random number engine used by Gaudi is + the RanLux engine of CLHEP with a luxury level of 3, which is also + the default for Geant4, so as to use the same mechanism to generate + random numbers as the detector simulation. + + :numref:`fig-services` shows the general + architecture of the Gaudi random number service. The client + interacts with the service in the following way: + + | · The client requests a generator from the service, which is able to produce a generator according to a requested distribution. The client then retrieves the requested generator. + | · Behind the scenes, the generator service creates the requested generator and initializes the object according to the parameters. The service also supplies the shared random number engine to the generator. + | · After the client has finished using the generator, the object must be released in order to inhibit resource leaks + + .. figure:: images/GDG_Services2.png + :name: fig-services + + The architecture of the random number service. The client requests from the service a random number generator satisfying certain criteria + + There are many different distributions available. The shape of the + distribution must be supplied as a parameter when the generator is + requested by the user. + + Currently implemented distributions include the following. See also + the header file GaudiKernel/RndmGenerators.h for a description of + the parameters to be supplied. + + | · Generate random bit patterns with parameters Rndm::Bit() + | · Generate a flat distribution with boundaries [min, max] with parameters: + | Rndm::Flat(double min, double max) + | · Generate a gaussian distribution with parameters: Rndm::Gauss(double mean, double sigma) + | · Generate a poissonian distribution with parameters: Rndm::Poisson(double mean) + | · Generate a binomial distribution according to n tests with a probability p with parameters: Rndm::Binomial(long n, double p) + | · Generate an exponential distribution with parameters: Rndm::Exponential(double mean) + | · Generate a Chi\*\*2 distribution with n\_dof degrees of freedom with parameters: Rndm::Chi2(long n\_dof) + | · Generate a Breit-Wigner distribution with parameters: Rndm::BreitWigner(double mean, double gamma) + | · Generate a Breit-Wigner distribution with a cut-off with parameters: Rndm::BreitWignerCutOff (mean, gamma, cut-off) + | · Generate a Landau distribution with parameters: Rndm::Landau(double mean, double sigma) + | · Generate a user defined distribution. The probability density function is given by a set of descrete points passed as a vector of doubles: Rndm::DefinedPdf(const std::vector<double>& pdf, long intpol) + + Clearly the supplied list of possible parameters is not exhaustive, + but probably represents most needs. The list only represents the + present content of generators available in CLHEP and can be updated + in case other distributions will be implemented. + + Since there is a danger that the interfaces are not released, a + wrapper is provided that automatically releases all resources once + the object goes out of scope. This wrapper allows the use of the + random number service in a simple way. Typically there are two + different usages of this wrapper: + + | · Within the user code a series of numbers is required only once, i.e. not every event. In this case the object is used locally and resources are released immediately after use. This example is shown in :numref:`rndnumgenhist` + + .. was 11.9 + + .. code-block:: cpp + :name: rndnumgenhist + :caption: Example of the use of the random number generator to fill a histogram with a Gaussian distribution within a standard Gaudi algorithm + + Rndm::Numbers gauss(randSvc(), Rndm::Gauss(0.5,0.2)); + if ( gauss ) { + IHistogram1D* his = histoSvc()->book("/stat/2","Gaussian",40,0.,3.); + for ( long i = 0; i < 5000; i++ ) + his->fill(gauss(), 1.0); + } + + + | · One or several random numbers are required for the processing of every event. An example is shown in :numref:`rndnumbgenuseevt` + + .. was 11.10 + + .. code-block:: cpp + :name: rndnumbgenuseevt + :caption: Example of the use of the random number generator within a standard Gaudi algorithm, for use at every event. The wrapper to the generator is part of the Algorithm itself and must be initialized before being used. Afterwards the usage is identical to the example described in :numref:`rndnumgenhist` + + #include "GaudiKernel/RndmGenerators.h" + + // Constructor + class myAlgorithm : public Algorithm { + Rndm::Numbers m_gaussDist; + // ... + }; + + // Initialisation + StatusCode myAlgorithm::initialize() { + ... + StatusCode sc=m_gaussDist.initialize( randSvc(), Rndm::Gauss(0.5,0.2)); + if ( !status.isSuccess() ) { + // put error handling code here... + } + ... + } + + There are a few points to be mentioned in order to ensure the + reproducibility: + + | · Do not keep numbers across events. If you need a random number ask for it. Usually caching does more harm than good. If there is a performance penalty, it is better to find a more generic solution. + | · Do not access the RndmEngine directly. + | · Do not manipulate the engine. The random seeds should only be set by the framework on an event by event basis. + +.. _serv-inci: + +The Incident Service +------------------------- + + The Incident service provides synchronization facilities to + components in a Gaudi application. Incidents are named software + events that are generated by software components and that are + delivered to other components that have requested to be informed + when that incident happens. The Gaudi components that want to use + this service need to implement the IIncidentListener interface, + which has only one method: handle(Incident&), and they need to add + themselves as Listeners to the IncidentSvc. The following code + fragment works inside Algorithms. + + .. code-block:: cpp + + #include "GaudiKernel/IIncidentListener.h" + #include "GaudiKernel/IIncidentSvc.h" + class MyAlgorithm : public Algorithm, virtual public IIncidentListener { + ... + }; + + MyAlgorithm::Initialize() { + IIncidentSvc* incsvc; + StatusCode sc = service("IncidentSvc", incsvc); + int priority = 100; + if ( sc.isSuccess() ) { + incsvc->addListener( this, "BeginEvent", priority); + incsvc->addListener( this, "EndEvent"); + } + } + MyAlgorithm::handle(Incident& inc) { + log << "Got informed of incident: " << inc.type() + << " generated by: " << inc.source() << endreq; + } + + The third argument in method addListener() is for specifying the + priority by which the component will be informed of the incident in + case several components are listeners of the same named incident. + This parameter is used by the IncidentSvc to sort the listeners in + order of priority. + +Known Incidents +~~~~~~~~~~~~~~~~~~~~~~ + + .. was 11.1 + + .. table:: Table of known named incidents + + +--------------------------+--------------------------+--------------------------+ + | Incident Type | Source | Description | + +==========================+==========================+==========================+ + | BeginEvent | ApplicationMgr | The ApplicationMgr is | + | | | starting processing of a | + | | | new physics event. This | + | | | incident can be use to | + | | | clear caches of the | + | | | previous event in | + | | | Services and Tools. | + +--------------------------+--------------------------+--------------------------+ + | EndEvent | ApplicationMgr | The ApplicationMgr has | + | | | finished processing the | + | | | physics event. The Event | + | | | data store is not yet | + | | | purged at this moment. | + +--------------------------+--------------------------+--------------------------+ + +.. _serv-refl: + +The Gaudi Introspection Service +------------------------------------- + + Introspection is the ability of a programming language to interact + with objects from a meta-level. The Gaudi Introspection package + defines a meta-model which gives the layout of this + meta-information. + + The data to fill this meta-information (i.e. the dictionary) can be + generated by the Gaudi Object Description package (described in :numref:`data-defi`) by adding + a few lines to the CMT requirements file, as shown for example in + :numref:`cmtreqgendic`. + + .. was 11.1 + + .. code-block:: cpp + :name: cmtreqgendic + :caption: CMT requirements for generation of data dictionary of the LHCbEvent package + + #---- dictionary + document obj2dict LHCbEventObj2Dict -group=dict ../xml/LHCbEvent.xml + library LHCbEventDict -group=dict ../dict/*.cpp + macro LHCbEventDict_shlibflags "$(use_linkopts) $(libraryshr_linkopts)" + + + The C++-code generated in this way is compiled into a dll and loaded + into the Gaudi Introspection Model at runtime. + + To get a reference to information about a real object, clients have + to use the Gaudi Introspection Service (IntrospectionSvc). The + service can also be used to load the meta-information into the + model. The Gaudi Introspection Service is already used in several + places in the framework (e.g. Interface to Python, Data Store + Browser). + + Further information about this service is available at + http://cern.ch/lhcb-comp/Frameworks/DataDictionary/default.htm. + +Developing new services +----------------------------- + +The Service base class +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Within Gaudi we use the term "Service" to refer to a class whose job + is to provide a set of facilities or utilities to be used by other + components. In fact we mean more than this because a concrete + service must derive from the Service base class and thus has a + certain amount of predefined behaviour; for example it has + initialize() and finalize() methods which are invoked by the + application manager at well defined times. + + :numref:`fig-services2` shows the inheritance + structure for an example service called SpecificService. The key + idea is that a service should derive from the Service base class and + additionally implement one or more pure abstract classes + (interfaces) such as IConcreteSvcType1 and IConcreteSvcType2 in the + figure. + + .. figure:: images/GDG_Servicesa.png + :name: fig-services2 + + Implementation of a concrete service class. Though not shown in the figure, both of the IConcreteSvcType interfaces are derived from IInterface + + As discussed above, it is necessary to derive from the Service base + class so that the concrete service may be made accessible to other + Gaudi components. The actual facilities provided by the service are + available via the interfaces that it provides. For example the + ParticleProperties service implements an interface which provides + methods for retrieving, for example, the mass of a given particle. + In :numref:`fig-services2` the service + implements two interfaces each of two methods. + + A component which wishes to make use of a service makes a request to + the application manager. Services are requested by a combination of + name, and interface type, i.e. an algorithm would request + specifically either IConcreteSvcType1 or IConcreteSvcType2. + + The identification of what interface types are implemented by a + particular class is done via the queryInterface method of the + IInterface interface. This method must be implemented in the + concrete service class. In addition the initialize() and finalize() + methods should be implemented. After initialization the service + should be in a state where it may be used by other components. + + The service base class offers a number of facilities itself which + may be used by derived concrete service classes: + + | · Properties are provided for services just as for algorithms. Thus concrete services may be fine tuned by setting options in the job options file. + | · A serviceLocator method is provided which allows a component to request the use of other services which it may need. + | · A message service. + +Implementation details +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The following is essentially a checklist of the minimal code + required for a service. + + | 1. Define the interfaces + | 2. Derive the concrete service class from the Service base class. + | 3. Implement the queryInterface() method. + | 4. Implement the initialize() method. Within this method you should make a call to Service::initialize() as the first statement in the method and also make an explicit call to setProperties() in order to read the service's properties from the job options (note that this is different from Algorithms, where the call to setProperties() is done in the base class). + + .. was 11.12 + + .. code-block:: cpp + :name: intclass + :caption: An interface class + + #include "GaudiKernel/IInterface.h" + + class IConcreteSvcType1 : virtual public IInterface { + + public: + + void method1() = 0; + int method2() = 0; + } + + #include "IConcreteSvcType1.h" + const IID& IID_IConcreteSvcType1 = 143; // UNIQUE within LHCb !! + + .. was 11.13 + + .. code-block:: cpp + :name: minservimpl + :caption: A minimal service implementation + + #include "GaudiKernel/Service.h" + #include "IConcreteSvcType1.h" + #include "IConcreteSvcType2.h" + + class SpecificService : public Service, + virtual public IConcreteSvcType1, + virtual public IConcreteSvcType2 { + + public: + + // Constructor of this form required: + SpecificService(const std::string& name, ISvcLocator* sl); + queryInterface(constIID& riid, void** ppvIF); + }; + + // Factory for instantiation of service objects + static SvcFactory<SpecificService> s_factory; + const ISvcFactory& SpecificServiceFactory = s_factory; + + // UNIQUE Interface identifiers defined elsewhere + extern const IID& IID_IConcreteSvcType1; + extern const IID& IID_IConcreteSvcType2; + + // queryInterface + StatusCode SpecificService::queryInterface(const IID& riid, void** ppvIF) { + if(IID_IConcreteSvcType1 == riid) { + *ppvIF = dynamic_cast<IConcreteSvcType1*> (this); + return StatusCode::SUCCESS; + } else if(IID_IConcreteSvcType2 == riid) { + *ppvIF = dynamic_cast<IConcreteSvcType2*> (this); + return StatusCode::SUCCESS; + } else { + return Service::queryInterface(riid, ppvIF); + } + } + + StatusCode SpecificService::initialize() { ... } + StatusCode SpecificService::finalize() { ... } + + // Implement the specifics ... + SpecificService::method1() {...} + SpecificService::method2() {...} + SpecificService::method3() {...} + SpecificService::method4() {...} + + +.. [#] This is an LHCb specific file. A generic implementation will be available in a future release of Gaudi diff --git a/docs/source/old/GDG_Starting.rst b/docs/source/old/GDG_Starting.rst new file mode 100644 index 0000000000000000000000000000000000000000..f7973bbd51cea839f3095fbb2fc549e74e175958 --- /dev/null +++ b/docs/source/old/GDG_Starting.rst @@ -0,0 +1,442 @@ +.. include:: ./global.rst + +|newpage| + +|Gaudi logo| + +.. _chapStar: + +Getting started +================= + +Overview +------------ + + In this chapter we walk through one of the example applications + (RandomNumber) which are distributed with the framework. We look + briefly at the different files and go over the steps needed to + compile and execute the code. We also outline where various subjects + are covered in more detail in the remainder of the document. Finally + we cover briefly the other example applications which are + distributed and say a few words on what each one is intended to + demonstrate. + +Creating a job +------------------ + + Traditionally, a "job" is the running of a program on a specified + set of input data to produce a set of output data, usually in batch. + + For the example applications supplied this is essentially a two step + process. First the executable must be produced, and secondly the + necessary environment variables must be set and the required job + options specified, as illustrated in :numref:`fig-job`. + + .. figure:: images/job.png + :name: fig-job + + Creating a job from the AlgSequencer example application + + The example applications consist of a number of "source code" files + which together allow you to generate an executable program. These + are: + + | · The main program. + | · Header and implementation files for each of the concrete algorithm classes. + | · A CMT requirements file. + | · The set of Gaudi libraries. + + In order for the job to run as desired you must provide the correct + configuration information for the executable. This is done via + entries in the job options file. + +The main program +-------------------- + + The main program is needed to bootstrap the job. It can be + completely general, and can be reused by all Gaudi applications. An + example main program, from the package GaudiExamples, is shown in + :numref:`main`. + + .. was 4.1 + + .. code-block:: cpp + :caption: The example main program + :name: main + + // Include files + #include "GaudiKernel/SmartIF.h" + #include "GaudiKernel/Bootstrap.h" + #include "GaudiKernel/IAppMgrUI.h" + #include "GaudiKernel/IProperty.h" + #include <iostream> + + //--- Example main program + int main(int argc, char** argv) { + + // Create an instance of an application manager + IInterface* iface = Gaudi::createApplicationMgr(); + + SmartIF<IProperty> propMgr ( IID_IProperty, iface ); + SmartIF<IAppMgrUI> appMgr ( IID_IAppMgrUI, iface ); + + if( !appMgr.isValid() || !propMgr.isValid() ) { + std::cout << "Fatal error creating ApplicationMgr " << std::endl; + return 1; + } + + // Get the input configuration file from arguments + std:: string opts = (argc>1) ? argv[1] : "../options/job.opts"; + + propMgr->setProperty( "JobOptionsPath", opts ); + + // Run the application manager and process events + appMgr->run(); + + // All done - exit + return 0; + } + + It is constructed as follows: + + | Include + | + | These are needed for the creation of the application manager and Smart interface pointers. + | + | Application Manager instantiation + | + | Line 12 instantiates an ApplicationMgr object. The application manager is essentially the job controller. It is responsible for creating and correctly initialising all of the services and algorithms required, for looping over the input data events and executing the algorithms specified in the job options file, and for terminating the job cleanly. + | + | Retrieval of Interface pointers + | + | The code on lines 14 and 15 retrieves the pointers to the IProperty and IAppMgrUI interfaces of the application manager. + | + | Setting the application manager's properties + | + | The only property which needs to be set explicitly in the main program is the name of the job options file which contains all of the other configuration information needed to run the job. In this example, the name is the first argument of the program and defaults to "../options/job.opts" (line 23); it is set on line 25. + | + | Program execution + | + | All of the code before line 28 is essentially for setting up the job. Once this is done, a call to appMgr::run() is all that is needed to start the job proper! The steps that occur within this method are discussed briefly in section :numref:`star-exec`. + +Configuring the job +----------------------- + + The application framework makes use of a job options file for job + configuration. Part of the job options file of an example + application is shown in :numref:`optionsio`. + + .. was 4.2 + + .. code-block:: cpp + :name: optionsio + :caption: Part of the job options file for the RootIORead example application + + // Include standard option files + #include "$STDOPTS/Common.opts" + + // Private Application Configuration options + ApplicationMgr.DLLs += { "GaudiDb", "GaudiRootDb" }; + ApplicationMgr.ExtSvc += { "DbEventCnvSvc/RootEvtCnvSvc" }; + ApplicationMgr.TopAlg = { "ReadAlg" }; + + // Set output level threshold (2=DEBUG,3=INFO,4=WARNING,5=ERROR,6=FATAL) + MessageSvc.OutputLevel = 4; + EventSelector.OutputLevel = 2; + + // Input File + EventSelector.Input = {"DATAFILE='RootDst.root' TYP='ROOT' OPT='READ'"}; + EventSelector.FirstEvent = 1; + ApplicationMgr.EvtMax = 5; + + // Persistency service setup: + EventPersistencySvc.CnvServices += { "RootEvtCnvSvc" }; + + // Setup for ROOT I/O system + RootEvtCnvSvc.DbType = "ROOT"; + + The format of an options file is discussed fully in `Chapter + 11 <GDG_Services.html#1010951>`__. Options may be set both for + algorithms and services and the list of available options for + standard components is given in :numref:`chapOpti`. Here we look briefly at + a few of the more commonly used options. + +Defining the algorithms to be executed +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The option ApplicationMgr.TopAlg (line 7) is a list of algorithms that will + be created and controlled directly by the application manager, the + so-called top-level algorithms. The syntax is a list of the form: + + .. code-block:: python + + ApplicationMgr.TopAlg = { "Type1/Name1", "Type2/Name2" }; + + The line above instructs the application manager to create two top + level algorithms. One of type Type1 called "Name1" and one of type + Type2 called "Name2". + + In the case where the name of the algorithm is the same as the + algorithm's type (i.e. class), only the class name is necessary. In + the example, an instance of the class "ReadAlg" will be created with + name "ReadAlg". + +Defining the job input +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Event data input is controlled by an EventSelector. The + EventSelector uses a storage technology dependent data persistency + service to load the data into the transient event data store, with + the help of converters which are able to convert the data from the + technology dependent persistent representation, to the technology + independent representation in the transient data store. + + In order to set up this mechanism, one needs a number of job + options: + + | - Line 14 defines the input data file, and the persistency technology (ROOT I/O in this example). + | - Line 6 tells the application manager to create a new event conversion service, to be called RootEvtCnvSvc. Note that this is just a name for our convenience, the service is of type DbEventCnvSvc and does not (yet) know that it will deal with ROOT technology. The configuration of RootEvtCnvSvc to use the ROOT I/O technology is done in line 22. + | - Line 19 tells the event persistency service (EventPersistencySvc created by the application manager by default) to use the RootEvtCnvSvc to do the conversion between persistent and transient data representations. + | - Line 5 tells the application manager which additional libraries to load in order to find the required conversion service. In this example, the GaudiDb library contains the DbEventCnvSvc class, the GaudiRootDb library contains the ROOT specific database drivers. + | - Finally, the options on lines 15 and 16 tell the EventSelector to start reading sequentially from the first event in the file, for five events. + + In the special case where no event input is required (e.g. for event + generation), one can replace the above options by the two options: + + .. code-block:: cpp + + ApplicationMgr.EvtMax = 20; // events to be processed (default is 10) + ApplicationMgr.EvtSel = "NONE"; // do not use any event input + + A discussion of event I/O can be found in :numref:`chapNtup`. Converters and the conversion + process are described in :numref:`chapConv`. + +.. _star-jobi: + +Defining job output +~~~~~~~~~~~~~~~~~~~~~~~~~ + + One can consider three types of job output: event data (including + event collections and n-tuples), statistical data (histograms) and + printout. Here we discuss only the simplest (printout); histograms + are discussed in :numref:`chapHist`, event + data in :numref:`data-save`, event collections in :numref:`serv-prop`. + + Printout in Gaudi is handled by the message service (described in + :numref:`chapServ`), which allows to control + the amount of printout according to severity level. The global + threshold for printout is set by the option on line 10 - in this example only messages + of severity level WARNING or above will be printed. This can be + over-ridden for individual algorithms or services, as in + line 11, where the threshold for EventSelector is set to DEBUG. + +Algorithms +-------------- + + The subject of specialising the Algorithm base class to do something + useful will be covered in detail in :numref:`chapAlgo`. Here we will limit ourselves to + looking at an example HelloWorld class. + +The HelloWorld.h header file +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The HelloWorld class definition is shown in :numref:`lstg-helloheader` + + .. was 4.3 + + .. code-block:: cpp + :name: lstg-helloheader + :caption: The header file of the class: HelloWorld + + // Include files + #include "GaudiKernel/Algorithm.h" + // Required for inheritance + #include "GaudiKernel/Property.h" + #include "GaudiKernel/MsgStream.h" + + class HelloWorld : public Algorithm { + + public: + + /// Constructor of this form must be provided + HelloWorld(const std::string& name, ISvcLocator* pSvcLocator); + + /// Three mandatory member functions of any algorithm + StatusCode initialize(); + StatusCode execute(); + StatusCode finalize(); + + private: + + /// These data members are used in the execution of this algorithm + /// and are set in the initialisation phase by the job options service + int m_int; + double m_double; + std::string m_string; + }; + + + Note the following: + + | · The class is derived from the Algorithm base class as must be all specialised algorithm classes. This implies that the Algorithm.h file must be included (line 6). + | · All derived algorithm classes must provide a constructor with the parameters shown in line 9 . The first parameter is the name of the algorithm and is used amongst other things to locate any options that may have been specified in the job options file. + | · The HistoAlgorithm class has three (private) data members, defined in lines 18 to 20. These are properties that can be set via the job options file. + | · The three methods on lines 12 to 14 must be implemented, since they are pure virtual in the base class. + +The HelloWorld implementation file +---------------------------------------- + + The implementation file contains the actual code for the constructor + and for the methods: initialize(), execute() and finalize(). It also + contains two lines of code for the HelloWorld factory, which we will + discuss in section :numref:`algo-crea` + + | The constructor + | + | must call the base class constructor, passing on its two arguments. As usual, member variables should be initialised. Here we declare and initialise the member variables that we wish to be set by the job options service. This is done by calling the declareProperty() method. + + .. code-block:: cpp + + HelloWorld::HelloWorld(const std::string& name, ISvcLocator* ploc) : Algorithm(name, ploc) { + //----------------------------------------------------------------------- + // Declare the algorithm's properties + declareProperty( "Int", m_int = 100 ); + declareProperty( "Double", m_double = 100.); + declareProperty( "String", m_string = std::string("one hundred")); + } + + | Initialisation + | + | The application manager invokes the sysInitialize() method of the algorithm base class which, in turn, invokes the initialize() method of the base class, the setProperties() method, and finally the initialize() method of the concrete algorithm class. As a consequence all of an algorithm's properties will have been set before its initialize() method is invoked, and all of the standard services such as the message service are available. This is discussed in more detail in :numref:`chapAlgo`. + + Looking at the code in the example (:numref:`lstg-helloinit`) we see that we are now able to + print out the values of the algorithm's properties, using the + message service and the MsgStream utility class. A local MsgStream + object is created (line 3 ), which + uses the Algorithm's standard message service via the msgSvc() + accessor, and the algorithm's name via the name() accessor. The use + of these is discussed in more detail in :numref:`chapServ`. + + Note that the job will stop if the initialize() method of any + algorithm does not return StatusCode::SUCCESS. This is to avoid + processing with a badly configured application.: + + .. was 4.4 + + .. code-block:: cpp + :name: lstg-helloinit + :caption: Example of initialize() method + + + StatusCode HelloWorld::initialize() { + //---------------------------------------------------------------------- + MsgStream log(msgSvc(), name()); + log << MSG::INFO << "initializing...." << endreq; + log << MSG::INFO << "Property Int = " << m_int << endreq; + log << MSG::INFO << "Property Double = " << m_double << endreq; + log << MSG::INFO << "Property String = " << m_string << endreq; + + m_initialized = true; + return StatusCode::SUCCESS; + } + + | execution + | + | The execute() method is called by the application manager once for every event. This is where most of the real action should take place. The trivial HelloWorld class just prints out a message... Note that the method must return StatusCode::SUCCESS on successful completion. If a particular algorithm returns a FAILURE status code more than a (configurable) maximum number of times, the application manager will decide that this algorithm is badly configured and jump to the finalisation stage before all events have been processed. + + .. code-block:: cpp + + StatusCode HelloWorld::execute() { + //---------------------------------------------------------------------- + MsgStream log( msgSvc(), name() ); + log << MSG::INFO << "executing...." << endreq; + + return StatusCode::SUCCESS; + } + + + | Finalisation + | + | The finalize() method is called at the end of the job. In this trivial example a message is printed. + + .. code-block:: cpp + + StatusCode HelloWorld::finalize() { + //---------------------------------------------------------------------- + MsgStream log(msgSvc(), name()); + log << MSG::INFO << "finalizing...." << endreq; + + return StatusCode::SUCCESS; + } + +.. _star-exec: + +Job execution +----------------- + + From the main program and the CMT requirements file we can make an + executable, as explained in section :numref:`inst-usin`. This executable together + with the file of job options form a job which may be submitted for + batch or run interactively. :numref:`fig-extrace` shows a trace of an example + program execution. The diagram is not intended to be complete, + merely to illustrate a few of the points mentioned earlier in the + chapter. + + .. figure:: images/Exampletrace.png + :name: fig-extrace + + A sequence diagram showing a part of the execution of an example program + + | 1. The application manager instantiates the required services and initialises them. The message service is done first to allow the other services to use it, and the job options service is second so that the other services may be configured at run time. + | 2. The algorithms which have been declared to the application manager within the job options (via the TopAlg option) are created. We denote these algorithms "top-level" as they are the only ones controlled directly by the application manager. For illustration purposes we instantiate an EmptyAlgorithm and a HistoAlgorithm. + | 3. The top-level algorithms are initialised. Their properties (if they have any) are set and they may make use of the message service. If any algorithm fails to initialise, the job is stopped. + | 4. The application manager now starts to loop over events. After each event is read, it executes each of the top level algorithms in order. The order of execution of the algorithms is the order in which they appear in the TopAlg option. This will continue until the required number of events has been processed, unless one or more of the algorithms return a FAILURE status code more than the maximum number of times, in which case the application manager will jump to the finalisation stage before all events have been processed. + | 5. After the required data sample has been read the application manager finalises each top level algorithm. + | 6. Services are finalised. + | 7. All objects are deleted and resources freed. The program terminates. + +Examples distributed with Gaudi +----------------------------------- + + A number of examples is included in the current release of the + framework, in the GaudiExamples package. The package has some + sub-directories in addition to the standard ones shown in :numref:`fig-packlay`. The options sub-directory + contains files of standard job options common to many examples. + These files are included in the job options of the specific examples + when necessary. The specific job options files can be found in the + home sub-directory. + + The code of the examples is in sub-directories of the src directory, + one sub-directory per example. The intention is that each example + demonstrates how to make use of some part of the functionality of + the framework. The list of available examples is shown in :numref:`tab-startexamples`. + + .. table:: List of examples available in Gaudi release v9 + :name: tab-startexamples + + +--------------------------------------+--------------------------------------+ + | Example Name | Target Functionality | + +======================================+======================================+ + | AlgSequencer | Illustraing the use of the sequencer | + | | algorithm provided with teh GaudiAlg | + | | package | + +--------------------------------------+--------------------------------------+ + | AlgTool | Example implementation and use of a | + | | Gaudi Tool | + +--------------------------------------+--------------------------------------+ + | Common | Actually not a complete example: | + | | contains the main program used in | + | | the examples | + +--------------------------------------+--------------------------------------+ + | GPython | Exercise the Python scripting | + | | packages | + +--------------------------------------+--------------------------------------+ + | Properties | Trivial algorithm showing how to set | + | | and retrieve Properties | + +--------------------------------------+--------------------------------------+ + | RandomNumber | Example of use of the Random Number | + | | service | + +--------------------------------------+--------------------------------------+ + | RootIO | Two examples, reading and writing | + | | persistend data with ROOT I/O | + +--------------------------------------+--------------------------------------+ diff --git a/docs/source/old/GDG_Tools.rst b/docs/source/old/GDG_Tools.rst new file mode 100644 index 0000000000000000000000000000000000000000..7bbf541084d4fe294dfc90b96c7031b84d3a7dd7 --- /dev/null +++ b/docs/source/old/GDG_Tools.rst @@ -0,0 +1,746 @@ +.. include:: ./global.rst + +|newpage| + +|Gaudi logo| + +.. _chapTool: + +Tools and ToolSvc +==================== + +Overview +------------- + + Tools are light weight objects whose purpose is to help other + components perform their work. A framework service, the ToolSvc, is + responsible for creating and managing Tools. An Algorithm requests + the tools it needs to the ToolSvc, specifying if requesting a + private instance by declaring itself as the parent. Since Tools are + managed by the ToolSvc, any component [#]_ can + request a tool. Algorithms, Services and other Tools can declare + themselves as Tools parents. + + In this chapter we first describe these objects and the difference + between "private" and "shared" tools. We then look at the AlgTool + base class and how to write concrete Tools. + + In section :numref:`tool-serv` we describe the ToolSvc + and show how a component can retrieve Tools via the service. + + Finally we describe Associators, common utility GaudiTools for which + we provide the interface and base class. + +Tools and Services +----------------------- + + As mentioned elsewhere Algorithms make use of framework services to + perform their work. In general the same instance of a service is + used by many algorithms and Services are setup and initialized once + at the beginning of the job by the framework. Algorithms also + delegate some of their work to sub-algorithms. Creation and + execution of sub-algorithms are the responsibilities of the parent + algorithm whereas the initialize() and finalize() methods are + invoked automatically by the framework while initializing the parent + algorithm. The properties of a sub-algorithm are automatically set + by the framework but the parent algorithm can change them during + execution. Sharing of data between nested algorithms is done via the + Transient Event Store. + + Both Services and Algorithms are created during the initialization + stage of a job and live until the jobs ends. + + Sometimes an encapsulated piece of code needs to be executed only + for specific events, in which case it is desirable to create it only + when necessary. On other occasions the same piece of code needs to + be executed many times per event. Moreover it can be necessary to + execute a sub-algorithm on specific contained objects that are + selected by the parent algorithm or have the sub-algorithm produce + new contained objects that may or may not be put in the Transient + Store. Finally different algorithms may wish to configure the same + piece of code slightly differently or share it as-is with other + algorithms. + + To provide this kind of functionality we have introduced a category + of processing objects that encapsulate these "light" algorithms. We + have called this category Tools. + + Some examples of possible tools are single track fitters, + association to Monte Carlo truth information, vertexing between + particles, smearing of Monte Carlo quantities. + +"Private" and "Shared" Tools +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Algorithms can share instances of Tools with other Algorithms if the + configuration of the tool is suitable. In some cases however an + Algorithm will need to customize a tool in a specific way in order + to use it. This is possible by requesting the ToolSvc to provide a + "private" instance of a tool. + + If an Algorithm passes a pointer to itself when it asks the ToolSvc + to provide it with a tool, it is declaring itself as the parent and + a "private" instance is supplied. Private instances can be + configured according to the needs of each particular Algorithm. + + As mentioned above many Algorithms can use a tool as-is, in which + case only one instance of a Tool is created, configured and passed + by the ToolSvc to the different algorithms. This is called a + "shared" instance. The parent of "shared" tools is the ToolSvc. + +The Tool classes +~~~~~~~~~~~~~~~~~~~~~~~ + +.. _tool-atbc: + +The AlgTool base class +``````````````````````````````` + + The main responsibilities of the AlgTool base class (see `Listing + 12.1 <GDG_Tools.html#1166507>`__) are the identification of the + tools instances, the initialisation of certain internal pointers + when the tool is created and the management of the tools properties. + The AlgTool base class also offers some facilities to help in the + implementation of derived tools and management of the additional + tools interfaces.. + + .. was 12.1 + + .. code-block:: cpp + :name: defalgbaseclass + :caption: The definition of the AlgTool Base class. Highlighted in bold are methods relevant for the implementation of concrete tools + + class AlgTool : public virtual IAlgTool, + public virtual IProperty { + + public: + + // Standard Constructor. + AlgTool( const std::string& type, + const std::string& name, + const IInterface* parent); + + ISvcLocator* serviceLocator() const; + IMessageSvc* msgSvc() const; + + virtual StatusCode setProperty( const Property& p ); + virtual StatusCode setProperty( std::istream& s ); + virtual StatusCode setProperty( const std::string& n, const std::string& v ); + virtual StatusCode getProperty(Property* p) const; + virtual const Property& getProperty( const std::string& name ) const; + virtual StatusCode getProperty( const std::string& n,std::string& v ) const; + virtual const std::vector<Property*>& getProperties( ) const; + + StatusCode setProperties(); + + template <class T> + StatusCode declareProperty(const std::string& name, T& property) const + + virtual const std::string& name() const; + virtual const std::string& type() const; + virtual const IInterface* parent() const; + + virtual StatusCode initialize(); + virtual StatusCode finalize(); + + virtual StatusCode queryInterface(const IID& riid, void** ppvUnknown); + void declInterface( const IID&, void*); + + template <class I> class declareInterface { + + public: + + template <class T> declareInterface(T* tool) + } + + protected: + + // Standard destructor. + virtual ~AlgTool(); + }; + + | Constructor + | + | The base class has a single constructor which takes three arguments. The first is the type (i.e. the class) of the Tool object being instantiated, the second is the full name of the object and the third is a pointer to the IInterface of the parent component. The name is used for the identification of the tool instance as described below.The parent interface is used by the tool to access for example the outputLevel of the parent. + | + | Access to Services + | + | A serviceLocator() method is provided to enable the derived tools to locate the services necessary to perform their jobs. Since concrete Tools are instantiated by the ToolSvc upon request, all Services created by the framework prior to the creation of a tool are available. In addition access to the message service is provided via the msgSvc() method. Both pointers are retrieved from the parent of the tool. + | + | Properties + | + | A template method for declaring properties similarly to Algorithms is provided. This allows tuning of data members used by the Tools via JobOptions files. The ToolSvc takes care of calling the setProperties() method of the AlgTool base class after having instantiated a tool. Properties need to be declared in the constructor of a Tool. The property outputLevel is declared in the base class and is identically set to that of the parent component, unless specified otherwise in the JobOptions. For details on Properties see section :numref:`serv-prop`. + | + | IAlgTool Interface + | + | It consists of three accessor methods for the identification and managment of the tools: type(), name() and parent(). These methods are all implemented by the base class and should not be overridden. Two additional methods, initialize() and finalize(), allow concrete tools to be configured after creation and orderly terminated before deletion. An empty implementation is provided by the AlgTool base class and concrete tools need to implement these methods only when relevant for their purpose. The ToolSvc is responsible for calling these methods at the appropriate time. + | + | Tools Interfaces + | + | Concrete tools must implement additional interfaces that will inherit from IAlgTool. When a component implements more that one interface it is necessary to "recognize" the various interfaces. This is taken care of by the AlgTool base class once the additional interface is declared by a concrete tool (or tools' base class). The declaration of the additional interface must be done in the constructor of a concrete tool and is done via the template method declareInterface. + +Tools identification +````````````````````````````` + + A tool instance is identified by its full name. The name consist of + the concatenation of the parent name, a dot, and a tool dependent + part. The tool dependent part can be specified by the user, when not + specified the tool type (i.e. the class) is automatically taken as + the tool dependent part of the name. Examples of tool names are + RecPrimaryVertex.VertexSmearer (a private tool) and + ToolSvc.AddFourMom (a shared tool). The full name of the tool has to + be used in the jobOptions file to set its properties. + +Concrete tools classes +``````````````````````````````` + + Operational functionalities of tools must be provided in the derived + tool classes. A concrete tool class must inherit directly or + indirectly from the AlgTool base class to ensure that it has the + predefined behaviour needed for management by the ToolSvc. + + Concrete tools must implement additional interfaces, specific to the + task a tool is designed to perform. Specialised tools intended to + perform similar tasks can be derived from a common base class that + will provide the common functionality and implement the common + interface. Consider as example the vertexing of particles, where + separate tools can implement different algorithms but the arguments + passed are the same. The ToolSvc interacts with specialized tools + only through the additional tools interface, therefore the interface + itself must inherit from the IAlgTool interface in order for the + tool to be correctly managed by the ToolSvc. + + The inheritance structure of derived tools is shown in :numref:`fig-tools`. ConcreteTool1 implements one + additional abstract interface while ConcreteTool2 and ConcreteTool3 + derive from a base class SubTool that provides them with additional + common functionality. + + .. figure:: images/ToolsHierarchy.png + :name: fig-tools + + Tools class hierarchy + +Implementation of concrete tools +````````````````````````````````````````` + + An example minimal implementation of a concrete tool is shown in + :numref:`exconctooladdint`, :numref:`exconctooladdintheader` and + :numref:`exconctooladdintcpp`, taken from the LHCb ToolsAnalysis + example application + + .. was 12.2 + + .. code-block:: cpp + :name: exconctooladdint + :caption: Example of a concrete tool additional interface + + static const InterfaceID IID_IVertexSmearer("IVertexSmearer", 1 , 0); + + class IVertexSmearer : virtual public IAlgTool { + public: + + /// Retrieve interface ID + static const InterfaceID& interfaceID() { return IID_IVertexSmearer; } + // Actual operator function + virtual StatusCode smear( MyAxVertex* ) = 0; + }; + + .. was 12.3 + + .. code-block:: cpp + :name: exconctooladdintheader + :caption: Example of a concrete tool minimal implementation header file + + #include "GaudiKernel/AlgTool.h" + + class VertexSmearer : public AlgTool, virtual public IVertexSmearer { + public: + + // Constructor + VertexSmearer( const std::string& type, + const std::string& name, + const IInterface* parent); + // Standard Destructor + virtual ~VertexSmearer() { } + // specific method of this tool + StatusCode smear( MyAxVertex* pvertex ); + }; + + .. was 12.4 + + .. code-block:: cpp + :name: exconctooladdintcpp + :caption: Example of a concrete tool minimal implementation file + + #include "GaudiKernel/ToolFactory.h" + // Static factory for instantiation of algtool objects + static ToolFactory<VertexSmearer> s_factory; + const IToolFactory& VertexSmearerFactory = s_factory; + + // Standard Constructor + VertexSmearer::VertexSmearer( const std::string& type, + const std::string& name, + const IInterface* parent) : AlgTool( type, name, parent ) { + + // Locate service needed by the specific tool + m_randSvc = 0; + + if( serviceLocator() ) { + + StatusCode sc=StatusCode::FAILURE; + sc = serviceLocator()->service( "RndmGenSvc", m_randSvc, true ); + } + + // Declare additional interface + declareInterface<IVertexSmearer>(this); + + // Declare properties of the specific tool + declareProperty("dxVtx", m_dxVtx = 9 * micrometer); + declareProperty("dyVtx", m_dyVtx = 9 * micrometer); + declareProperty("dzVtx", m_dzVtx = 38 * micrometer); + } + + // Implement the specific method .... + StatusCode VertexSmearer::smear( MyAxVertex* pvertex ) {...} + + + The creation of concrete tools is similar to that of Algorithms, + making use of a Factory Method. As for Algorithms, Tool factories + enable their creator to instantiate new tools without having to + include any of the concrete tools header files. A template factory + is provided and a tool developer will only need to add the concrete + factory in the implementation file as shown in lines 1 4 of + :numref:`exconctooladdintcpp` + + In addition a concrete tool class must specify a single constructor + with the same parameter signatures as the constructor of the AlgTool + base class as shown in line 5 of :numref:`exconctooladdintheader`. + + Below is the minimal checklist of the code necessary when developing + a Tool: + + 1. Define the specific interface (inheriting from the IAlgTool interface). + 2. Derive the tool class from the AlgTool base class + 3. Provide the constructor + 4. Declare the additional interface in the constructor. + 5. Implement the factory adding the lines of code shown in :numref:`exconctooladdintcpp` + 6. Implement the specific interface methods. + + In addition if a tool requires special initialization and + termination you can implement the initialize and finalize methods. + +.. _tool-serv: + +The ToolSvc +---------------- + + The ToolSvc manages Tools. It is its responsibility to create tools, + configure them, make them available to Algorithms or Services and + terminate them in an orderly fashion before deleting them. + + The ToolSvc verifies if a tool type is available and creates the + necessary instance after having verified if it doesn't already + exist. If a tool instance exists the ToolSvc will not create a new + identical one but pass to the algorithm the existing instance. Tools + are created on a "first request" basis: the first Algorithm + requesting a tool will prompt its creation. The relationship between + an algorithm, the ToolSvc and Tools is shown in :numref:`fig-toolsdia`. + + .. figure:: images/ToolsDiagram.png + :name: fig-toolsdia + + ToolSvc design diagram + + Immediately after having created a tool, the ToolSvc will configure + it by setting its properties and calling the tool initialize() + method. + + The ToolSvc will "hold" a tool until it is no longer used by any + component or until the finalize() method of the tool service is + called. Algorithms can inform the ToolSvc they are not going to use + a tool previously requested via the releaseTool method of the + IToolSvc interface. Before deleting the tools the ToolSvc will + cleanly terminate them by calling their finalize() method. + + The ToolSvc is created by default by the ApplicationMgr and + algorithms wishing to use the service can do so via the algorithm + toolSvc() accessor method. Services and AlgTools need to retrieve it + using the serviceLocator() method of their respective base classes. + +Retrieval of tools via the IToolSvc interface +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The IToolSvc interface is the ToolSvc specific interface providing + methods to retrieve tools. The interface has two retrieve methods + that differ in their parameters signature, as shown in :numref:`itoolsvcmeths` + + .. was 12.5 + + .. code-block:: cpp + :name: itoolsvcmeths + :caption: The IToolSvc interface methods + + virtual StatusCode retrieve( const std::string& type, + const IID&, + IAlgTool*& tool, + const IInterface* parent=0, + bool createIf=true ) = 0; + virtual StatusCode retrieve( const std::string& type, + const IID&, + const std::string& name, + IAlgTool*& tool, + const IInterface* parent=0, + bool createIf=true ) = 0; + + + The arguments of the method shown in :numref:`itoolsvcmeths` line 1, + are the tool type (i.e. the class), + the tool additional interface ID and the IAlgTool interface of the + returned tool. In addition there are two arguments with default + values: one is the IInterface of the component requesting the tool, + the other a boolean creation flag. If the component requesting a + tool passes a pointer to itself as the third argument, it declares + to the ToolSvc that it is asking for a "private" instance of the + tool. By default a "shared" instance is provided. In general if the + requested instance of a Tool does not exist the ToolSvc will create + it. This behaviour can be changed by setting to false the last + argument of the method. + + The method shown in :numref:`itoolsvcmeths`, line 2 + differs from the one shown in line 1 by an extra argument, a string + specifying the tool dependent part of the full tool name. This + enables a component to request two separately configurable instances + of the same tool. + + When retriving concrete tools, it is recommended to use the two + templated functions provided in the IToolSvc interface file which + are shown in :numref:`itoolsvctemplmeths`. + + .. was 12.6 + + .. code-block:: cpp + :name: itoolsvctemplmeths + :caption: The IToolSvc template methods + + template <class T> + StatusCode retrieveTool( const std::string& type, + T*& tool, + const IInterface* parent=0, + bool createIf=true ) {...} + template <class T> + StatusCode retrieveTool( const std::string& type, + const std::string& name, + T*& tool, + const IInterface* parent=0, + bool createIf=true ) {...} + + The two template methods correspond to the IToolSvc retrieve methods + but have the tool returned as a template parameter. Using these + methods the component retrieving a tool avoids explicit + dynamic-casting to specific additional interfaces or to derived + classes. + + :numref:`exretrshrdtool` shows an example of retrieval of a shared and of a common tool. + + .. was 12.7 + + .. code-block:: cpp + :name: exretrshrdtool + :caption: Example of retrieval by an algorithm of a shared tool in line 4 and of a private tool in line 10 + + // Example of tool belonging to the ToolSvc and shared between algorithms + StatusCode sc; + sc = toolsvc()->retrieveTool("AddFourMom", m_sum4p ); + if( sc.isFailure() ) { + log << MSG::FATAL << " Unable to create AddFourMom tool" << endreq; + return sc; + } + // Example of private tool + sc = toolsvc()->retrieveTool("ImpactPar", m_ip, this ); + if( sc.isFailure() ) { + log << MSG::FATAL << " Unable to create ImpactPar tool" << endreq; + return sc; + } + +GaudiTools +--------------- + + In general concrete tools are specific to applications or detectors' + code but there are some tools of common utility for which interfaces + and base classes can be provided. The Associators described below + and contained in the GaudiTools package are one of such tools. + +Associators +~~~~~~~~~~~~~~~~~~ + + When working with Monte Carlo data it is often necessary to compare + the results of reconstruction or physics analysis with the original + corresponding Monte Carlo quantities on an event-by-event basis as + well as on a statistical level. + + Various approaches are possible to implement navigation from + reconstructed simulated data back to the Monte Carlo truth + information. Each of the approaches has its advantages and could be + more suited for a given type of event data or data-sets. In addition + the reconstruction and physics analysis code should treat simulated + data in an identical way to real data. + + In order to shield the code from the details of the navigation + procedure, and to provide a uniform interface to the user code, a + set of Gaudi Tools, called Associators, has been introduced. The + user can navigate between any two arbitrary classes in the Event + Model using the same interface as long as a corresponding associator + has been implemented. Since an Associator retrieves existing + navigational information, its actual implementation depends on the + Event Model and how the navigational information is stored. For some + specific Associators, in addition, it can depend on some algorithmic + choices: consider as an example a physics analysis particle and a + possible originating Monte Carlo particle where the associating + discriminant could be the fractional number of hits used in the + reconstruction of the tracks. An advantage of this approach is that + the implementation of the navigation can be modified without + affecting the reconstruction and analysis algorithms because it + would affect only the associators. In addition short-cuts or + complete navigational information can be provided to the user in a + transparent way. By limiting the use of such associators to + dedicated monitoring algorithms where the comparison between + raw/reconstructed data and MC truth is done, one could ensure that + the reconstruction and analysis code treat simulated and real data + in an identical way. + + Associators must implement a common interface called IAssociator. An + Associator base class providing at the same time common + functionality and some facilities to help in the implementation of + concrete Associators is provided. A prototype version of these + classes is provided in the current release of Gaudi. + +The IAssociator Interface +`````````````````````````````````` + + As already mentioned Associators must implement the IAssociator + interface. + + In order for Associators to be retrieved from the ToolSvc only via + the IAssociator interface, the interface itself inherits from the + IAlgTool interface. While the implementation of the IAlgTool + interface is done in the AlgTool base class, the implementation of + the IAssociator interface is the full responsibility of concrete + associators. + + The four methods of the IAssociator interface that a concrete + Associator must implement are show in :numref:`iassocmeths` + + .. was 12.8 + .. :name: iassocmeths + .. :caption: Methods of the IAssociator Interface that must be implemented by concrete associators + + .. code-block:: cpp + :name: iassocmeths + :caption: Methods of the IAssociator Interface that must be implemented by concrete associators + + virtual StatusCode i_retrieveDirect( ContainedObject* objFrom, + std::vector<ContainedObject*>& vObjTo, + const CLID idFrom, + const CLID idTo ) = 0; + + virtual StatusCode i_retrieveInverse( ContainedObject* objFrom, + ContainedObject*& objTo, + const CLID idFrom, + const CLID idTo) = 0; + + virtual StatusCode i_retrieveInverse( ContainedObject* objFrom, + std::vector<ContainedObject*>& vObjTo, + const CLID idFrom, + const CLID idTo) = 0; + + Two i\_retrieveDirect methods must be implemented for retrieving + associated classes following the same direction as the links in the + data: for example from reconstructed particles to Monte Carlo + particles. The first parameter is a pointer to the object for which + the associated Monte Carlo quantity(ies) is requested. The second + parameter, the discriminating signature between the two methods, is + one or a vector of pointers to the associated Monte Carlo objects of + the type requested. Some reconstructed quantities will have only one + possible Monte Carlo associated object of a certain type, some will + have many, others will have many out of which a "best" associated + object can be extracted. If one of the two methods is not valid for + a concrete associator, such method must return a failure. The third + and fourth parameters are the class IDs of the objects for which the + association is requested. This allows to verify at run time if the + objects' types are those the concrete associator has been + implemented for. + + The two i\_retrieveInverse methods are complementary and are for + retrieving the association between the same two classes but in the + opposite direction to that of the links in the data: for example + from Monte Carlo particles to reconstructed particles. The different + name is intended to alert the user that navigation in this direction + may be a costly operation + + + + Four corresponding template methods are implemented in IAssociator + to facilitate the use of Associators by Algorithms + (see :numref:`iassoctemplmeth`). Using these methods the component + retrieving a tool avoids some explicit dynamic-casting as well as + the setting of class IDs. An example of how to use such methods is + described in section :numref:`tool-iaex` + + .. was 12.9 + + .. code-block:: cpp + :name: iassoctemplmeth + :caption: Template methods of the IAssociator interface + + template <class T1, class T2> + StatusCode retrieveDirect( T1* from, T2*& to ) { // ... + } + + template <class T1> + StatusCode retrieveDirect( T1* from, + std::vector<ContainedObject*>& objVTo, + const CLID idTo ) { // ... + } + + template <class T1, class T2> + StatusCode retrieveInverse( T1* from, T2*& to ) { // ... + } + + template <class T1> + StatusCode retrieveInverse( T1* from, + std::vector<ContainedObject*>& objVTo, + const CLID idTo ) { // ... + } + + +The Associator base class +`````````````````````````````````` + + An associator is a type of AlgTool,so the Associator base class + inherits from the AlgTool base class. Thus, Associators can be + created and managed as AlgTools by the ToolSvc. Since all the + methods of the AlgTool base class (as described in section + :numref:`tool-atbc`) are available in the + Associator base class, only the additional functionality is + described here. + + | Access to Event Data Service + | + | An eventSvc() method is provided to access the Event Data Service since most concrete associators will need to access data, in particular if accessing navigational short-cuts. + | + | Associator Properties + | + | Two properties are declared in the constructor and can be set in the jobOptions: "FollowLinks" and "DataLocation". They are respectively a bool with initial value true and a std::string with initial value set to " ". The first is foreseen to be used by an associator when it is possible to either follow links between classes or retrieve navigational short cuts from the data. A user can choose to set either behaviour at run time. The second property contains the location in the data where the stored navigational information is located. Currently it must be set via the jobOptions when necessary, as shown in :numref:`exsetpropassjo` for a particular implementation provided in the Associator example. Two corresponding methods are provided for using the information from these properties: followLinks() and whichTable(). + | + | Inverse Association + | + | Retrieving information in the direction opposite to that of the links in the data is in general a time consuming operation, that implies checking all the direct associations to access the inverse relation for a specified object. For this reason Associators should keep a local copy of the inverse associations after receiving the first request for an event. A few methods are provided to facilitate the work of Associators in this case. The methods inverseExist() and setInverseFlag(bool) help in keeping track of the status of the locally kept inverse information.The method buildInverse() has to be overridden by concrete associators since they choose in which form to keep the information and should be called by the associator when receiving the first request during the processing of an event. + | + | Locally kept information + | + | When a new event is processed, the associator needs to reset its status to the same conditions as those after having been created. In order to be notified of such an incident happening the Associator base class implements the IListener interface and, in the constructor, registers itself with the Incident Service (see section :numref:`serv-inci` for details of the Incident Service). The associator's flushCache() method is called in the implementation of the IListener interface in the Associator base class. This method must be overridden by concrete associators wanting to do a meaningful reset of their initial status. + +.. _tool-iaex: + +A concrete example +``````````````````````````` + + In this section we look at an example implementation of a specific + associator. The code is taken from the LHCb Associator example, but + the points illustrated should be clear even without a knowledge of + the LHCb data model. + + The AxPart2MCParticleAsct provides association between physics + analysis particles (AxPartCandidate) and the corresponding Monte + Carlo particles (MCParticle). The direct navigational information is + stored in the persistent data as short-cuts, and is retrieved in the + form of a SmartRefTable in the Transient Event Store. This choice is + specific to AxPart2MCParticleAsct, any associator can use internally + a different navigational mechanism. The location in the Event Store + where the navigational information can be found is set in the job + options via the "DataLocation" property, as shown in `Listing + 12.10 <GDG_Tools.html#1110534>`__. + + .. was 12.10 + + .. code-block:: cpp + :name: exsetpropassjo + :caption: Example of setting properties for an associator via jobOptions + + ToolSvc.AxPart2MCParticleAsct.DataLocation = "/Event/Anal/AxPart2MCParticle"; + + In the current LHCb data model only a single MCParticle can be + associated to one AxPartCandidate and vice-versa only one or no + AxPartCandidate can be associated to one MCParticle. For this reason + only the i\_retrieveDirect and i\_retrieveInverse methods providing + one-to-one association are meaningful. Both methods verify that the + objects passed are of the correct type before attempting to retrieve + the information, as shown in :numref:`checkobjsassoctyp`. When no association is found, a + StatusCode::FAILURE is returned. + + .. was 12.11 + + .. code-block:: cpp + :name: checkobjsassoctyp + :caption: Checking if objects to be associated are of the correct type + + if ( idFrom != AxPartCandidate::classID() ) { + objTo = 0; + return StatusCode::FAILURE; + } + if ( idTo != MCParticle::classID() ) { + objTo = 0; + return StatusCode::FAILURE; + } + + The i\_retrieveInverse method providing the one-to-many association + returns a failure, while a fake implementation of the one-to-many + i\_retrieveDirect method is implemented in the example, to show how + an Algorithm can use such a method. In the AxPart2MCParticleAsct + example the inverse table is kept locally and both the + buildInverse() and flushCache() methods are overridden. In the + example the choice has been made to implement an additional method + buildDirect() to retrieve the direct navigational information on a + first request per event basis. + + :numref:`codeasctexalg` shows how a monitoring + Algorithm can get an associator from the ToolSvc and use it to + retrieve associated objects through the template interfaces. + + .. was 12.12 + + .. code-block:: cpp + :name: codeasctexalg + :caption: Extracted code from the AsctExampleAlgorithm + + #include "GaudiTools/IAssociator.h" + + // Example of retrieving an associator IAssociator + StatusCode sc = toolsvc()->retrieveTool("AxPart2MCParticleAsct", m_pAsct); + if( sc.isFailure() ) { + log << MSG::FATAL << "Unable to create Associator tool" << endreq; + return sc; + } + + // Example of retrieving inverse one-to-one information from an associator + SmartDataPtr<MCParticleVector> vmcparts (evt,"/MC/MCParticles"); + for( MCParticleVector::iterator itm = vmcparts->begin(); vmcparts->end() != itm; itm++) { + AxPartCandidate* mptry = 0; + StatusCode sc = m_pAsct->retrieveInverse( *itm, mptry ); + if( sc.isSuccess() ) {...} + else {...} + } + + // Example of retrieving direct one-to-many information from an associator + SmartDataPtr<AxPartCandidateVector> candidates(evt, "/Anal/AxPartCandidates"); + std::vector<ContainedObject*> pptry; + AxPartCandidate* itP = *(candidates->begin()); + StatusCode sa = m_pAsct->retrieveDirect(itP, pptry, MCParticle::classID()); + if( sa.isFailure() ) {...} + else { + for (std::vector<ContainedObject*>::iterator it = pptry.begin(); pptry.end() != it; it++ ) { + MCParticle* imc = dynamic_cast<MCParticle*>( *it ); + } + } + +.. [#] In this chapter we will use an Algorithm as example component requesting tools. diff --git a/docs/source/old/GDG_Utilities.rst b/docs/source/old/GDG_Utilities.rst new file mode 100644 index 0000000000000000000000000000000000000000..16be2fd1cf9198598ec1f82769a076ccdf37ba81 --- /dev/null +++ b/docs/source/old/GDG_Utilities.rst @@ -0,0 +1,71 @@ +.. include:: ./global.rst + +|newpage| + +|Gaudi logo| + +.. _chapUtil: + +Analysis utilities +===================== + +Overview +------------- + + In this chapter we give pointers to some of the third party software + libraries that we use within Gaudi or recommend for use by + algorithms implemented in Gaudi. + +CLHEP +---------- + + CLHEP ("Class Library for High Energy Physics") is a set of + HEP-specific foundation and utility classes such as random + generators, physics vectors, geometry and linear algebra. It is + structured in a set of packages independent of any external package. + The documentation for CLHEP can be found on WWW at + http://proj-clhep.web.cern.ch/proj-clhep/ + + CLHEP is used extensively inside Gaudi, in the GaudiSvc and GaudiDb + packages. + +HTL +-------- + + HTL ("Histogram Template Library") is used internally in Gaudi + (GaudiSvc package) to provide histogramming functionality. It is + accessed through its abstract AIDA [AIDA]_ compliant interfaces. + Gaudi uses only the transient part of HTL. Histogram persistency is + available with ROOT or HBOOK. + + The documentation on HTL is available at + http:cern.ch/anaphe/documentation.html. + +NAG C +---------- + + The NAG C library is a commercial mathematical library providing a + similar functionality to the FORTRAN mathlib (part of CERNLIB). It + is organised into chapters, each chapter devoted to a branch of + numerical or statistical computation. A full list of the functions + is available at + http://cern.ch/anaphe/documentation/Nag_C/NAGdoc/cl/html/mark6.html + + NAG C is not explicitly used in the Gaudi framework, but developers + are encouraged to use it for mathematical computations. Instructions + for linking NAG C with Gaudi can be found at + http://cern.ch/lhcb-comp/Support/NagC/nagC.html + + Some NAG C functions print error messages to stdout by default, + without any information about the calling algorithm and without + filtering on severity level. A facility is provided by Gaudi to + redirect these messages to the Gaudi MessageSvc. This is documented + at http://cern.ch/lhcb-comp/Support/NagC/GaudiNagC.html + +ROOT +--------- + + ROOT is used by Gaudi for I/O and as a persistency solution for + event data, histograms and n-tuples. In addition, it can be used for + interactive analysis, as discussed in :numref:`chapNtup`. Information about ROOT can be found + at http://root.cern.ch/ diff --git a/docs/source/old/GDG_Visualization.rst b/docs/source/old/GDG_Visualization.rst new file mode 100644 index 0000000000000000000000000000000000000000..799229368608a1d4f1758d3c42eb7e5c6d9c9aa1 --- /dev/null +++ b/docs/source/old/GDG_Visualization.rst @@ -0,0 +1,69 @@ +.. include:: ./global.rst + +|newpage| + +|Gaudi logo| + +.. _chapVisu: + +Visualization Facilities +=========================== + +Overview +------------- + + In this chapter we describe how visualization facilities are + provided to the applications based on the Gaudi framework. A + prototype implementation (GaudiLab) exists in LHCb but is not + distributed with the framework. It is based on the packages that + constitute the Open Scientist suite (OpenGL, OpenInventor(soFree), + Lab,... see http://www.lal.in2p3.fr/OpenScientist/). An event and + geometry display application has been built using these facilities. + +The data visualization model +--------------------------------- + + The Gaudi architecture envisaged implementing data visualization + using a similar pattern to data persistency. We do not want to + implement visualization methods in each data object. In other words, + we do not want to tell an object to "draw" itself. Instead we would + implement converters as separate entities that are able to create + specific graphical representations for each type of data object and + for each graphical package that we would like to use. In that way, + as for the persistency case, we decouple the definition and + behaviour of the data objects from the various technologies for + graphics. We could configure at run time to have 2D or 3D graphics + depending on the needs of the end-user at that moment. + + :numref:`fig-visu` illustrates the + components that need to be included in an application to make it + capable of visualizing data objects (the "So" prefix in the names is + taken from the GaudiLab implementation). The interactive user + interface is a Service which allows the end-user to interact with + all the components of the application. The user could select which + objects to display, which algorithms to run, what properties of + which algorithm to inspect and modify, etc. This interaction can be + implemented using a graphical user interface or by using a scripting + language. + + The User interface service is also in charge of managing one or more + GUI windows where views of the graphical representations are going + to be displayed. + + .. figure:: images/visualmodel.png + :name: fig-visu + + Components for visualization** + + The other main component is a Conversion Service that handles the + conversion of objects into their graphical representation. This + service requires the help of a number of specialized converters, one + for each type of data object that needs to be graphically displayed. + The transient store of graphical representations is shared by the + conversion service, together with the converters, and the user + interface component. The form of this transient store depends on the + choice of graphics package. Typically it is the user interface + component that would trigger the conversion service to start the + conversion of a number of objects (next event), but this service can + also be triggered by any algorithm that would like to display some + objects. diff --git a/docs/source/old/GDG_frontmatter.rst b/docs/source/old/GDG_frontmatter.rst new file mode 100644 index 0000000000000000000000000000000000000000..71e239d8d61e6308bf3b05076446c2cdaf2915d5 --- /dev/null +++ b/docs/source/old/GDG_frontmatter.rst @@ -0,0 +1,24 @@ +.. include:: ./global.rst + +|newpage| + +|Gaudi logo| + +.. _chapFron: + +Gaudi Frontmatter +================= + + | Gaudi Data Processing Applications Framework Developers Guide + | + | Corresponding to Gaudi release v9 + | Version: 2 + | Issue: 0 + | Edition: 0 + | Status: + | ID: + | Date: 20 December 2001 + + | European Laboratory for Particle Physics + | Laboratoire Européen pour la Physique des Particules + | CH-1211 Genève 23 - Suisse diff --git a/docs/source/old/global.rst b/docs/source/old/global.rst new file mode 100644 index 0000000000000000000000000000000000000000..a05376daa25b5d2b84db3b74e3b13261529aa41c --- /dev/null +++ b/docs/source/old/global.rst @@ -0,0 +1,14 @@ +.. |Gaudi logo| image:: images/gaudiSF.png + :scale: 10 % + +.. |newpage| raw:: latex + + \newpage + +.. highlight:: python + :linenothreshold: 5 + +.. highlight:: cpp + :linenothreshold: 5 + +.. otherwise :linenos: diff --git a/docs/source/old/images/AlgorithmInitialize.png b/docs/source/old/images/AlgorithmInitialize.png new file mode 100644 index 0000000000000000000000000000000000000000..2feb80eab22b2ba5db64d9619e04f83014457558 Binary files /dev/null and b/docs/source/old/images/AlgorithmInitialize.png differ diff --git a/docs/source/old/images/ConversionClassDiag.png b/docs/source/old/images/ConversionClassDiag.png new file mode 100644 index 0000000000000000000000000000000000000000..4164038821461afd1ea6cd617d36bc2eabf749c0 Binary files /dev/null and b/docs/source/old/images/ConversionClassDiag.png differ diff --git a/docs/source/old/images/ConversionTrace1.png b/docs/source/old/images/ConversionTrace1.png new file mode 100644 index 0000000000000000000000000000000000000000..e5d56aeea147e270ff2b7f29b64a62ec6daa2ee3 Binary files /dev/null and b/docs/source/old/images/ConversionTrace1.png differ diff --git a/docs/source/old/images/EventConverters.png b/docs/source/old/images/EventConverters.png new file mode 100644 index 0000000000000000000000000000000000000000..1f4679f9ecb1fe058edeb8c577e9d978dbda04fd Binary files /dev/null and b/docs/source/old/images/EventConverters.png differ diff --git a/docs/source/old/images/EventModel.png b/docs/source/old/images/EventModel.png new file mode 100644 index 0000000000000000000000000000000000000000..02b25059709711275397b462fb29164cb1720b0f Binary files /dev/null and b/docs/source/old/images/EventModel.png differ diff --git a/docs/source/old/images/Exampletrace.png b/docs/source/old/images/Exampletrace.png new file mode 100644 index 0000000000000000000000000000000000000000..1de2b6589e030db5170e9b1efba06e1ca17f61c4 Binary files /dev/null and b/docs/source/old/images/Exampletrace.png differ diff --git a/docs/source/old/images/GDG_A_Designa.png b/docs/source/old/images/GDG_A_Designa.png new file mode 100644 index 0000000000000000000000000000000000000000..6ca0fa130e73207d138e285f2a6ac4214769ba55 Binary files /dev/null and b/docs/source/old/images/GDG_A_Designa.png differ diff --git a/docs/source/old/images/GDG_Architecture2.png b/docs/source/old/images/GDG_Architecture2.png new file mode 100644 index 0000000000000000000000000000000000000000..3a93fd2326ec95fdb9accef8d034f7ffccec2a08 Binary files /dev/null and b/docs/source/old/images/GDG_Architecture2.png differ diff --git a/docs/source/old/images/GDG_Convertersa.gif b/docs/source/old/images/GDG_Convertersa.gif new file mode 100644 index 0000000000000000000000000000000000000000..7392f744ba1a87ffc344b8d241c848d7deab04d9 Binary files /dev/null and b/docs/source/old/images/GDG_Convertersa.gif differ diff --git a/docs/source/old/images/GDG_DetDescriptiona.png b/docs/source/old/images/GDG_DetDescriptiona.png new file mode 100644 index 0000000000000000000000000000000000000000..c49a92147d336e7b0897d435ff04e29d9939fea0 Binary files /dev/null and b/docs/source/old/images/GDG_DetDescriptiona.png differ diff --git a/docs/source/old/images/GDG_Histograma.gif b/docs/source/old/images/GDG_Histograma.gif new file mode 100644 index 0000000000000000000000000000000000000000..0e7b3b465c8863b7b23a55557ad9eb1488f8bf3c Binary files /dev/null and b/docs/source/old/images/GDG_Histograma.gif differ diff --git a/docs/source/old/images/GDG_Services2.png b/docs/source/old/images/GDG_Services2.png new file mode 100644 index 0000000000000000000000000000000000000000..af72a8c3e86540a62e714ba114e6860231db1834 Binary files /dev/null and b/docs/source/old/images/GDG_Services2.png differ diff --git a/docs/source/old/images/GDG_Servicesa.png b/docs/source/old/images/GDG_Servicesa.png new file mode 100644 index 0000000000000000000000000000000000000000..024b00106569fceeb9465cf3aea7891fd8e32a4b Binary files /dev/null and b/docs/source/old/images/GDG_Servicesa.png differ diff --git a/docs/source/old/images/GaudiArchitecture.png b/docs/source/old/images/GaudiArchitecture.png new file mode 100644 index 0000000000000000000000000000000000000000..7e13033c3180583756b99fdf66a1adc3f448e875 Binary files /dev/null and b/docs/source/old/images/GaudiArchitecture.png differ diff --git a/docs/source/old/images/MiniArchitecture.png b/docs/source/old/images/MiniArchitecture.png new file mode 100644 index 0000000000000000000000000000000000000000..eecaad629ac1d0c66aa296caa5928d88198847ef Binary files /dev/null and b/docs/source/old/images/MiniArchitecture.png differ diff --git a/docs/source/old/images/PackageLayout.png b/docs/source/old/images/PackageLayout.png new file mode 100644 index 0000000000000000000000000000000000000000..27e57e75886e87641305c8cb7f97bf4651699409 Binary files /dev/null and b/docs/source/old/images/PackageLayout.png differ diff --git a/docs/source/old/images/Packages.png b/docs/source/old/images/Packages.png new file mode 100644 index 0000000000000000000000000000000000000000..76fecde131cca4fc13c069ca81f91205e012386e Binary files /dev/null and b/docs/source/old/images/Packages.png differ diff --git a/docs/source/old/images/ToolsDiagram.png b/docs/source/old/images/ToolsDiagram.png new file mode 100644 index 0000000000000000000000000000000000000000..e32963800c43564dab9096fbe35a5abb8a61470a Binary files /dev/null and b/docs/source/old/images/ToolsDiagram.png differ diff --git a/docs/source/old/images/ToolsHierarchy.png b/docs/source/old/images/ToolsHierarchy.png new file mode 100644 index 0000000000000000000000000000000000000000..e21c0d7b32d0858d62b67d349978bab988ffd037 Binary files /dev/null and b/docs/source/old/images/ToolsHierarchy.png differ diff --git a/docs/source/old/images/TrackDFD.png b/docs/source/old/images/TrackDFD.png new file mode 100644 index 0000000000000000000000000000000000000000..1a29182d1327204544f51b4cec4abef5d240c8a8 Binary files /dev/null and b/docs/source/old/images/TrackDFD.png differ diff --git a/docs/source/old/images/containedObject.png b/docs/source/old/images/containedObject.png new file mode 100644 index 0000000000000000000000000000000000000000..6d4b9099c332e12bac0b5d04f46a77300826a989 Binary files /dev/null and b/docs/source/old/images/containedObject.png differ diff --git a/docs/source/old/images/gaudiSF.bmp b/docs/source/old/images/gaudiSF.bmp new file mode 100644 index 0000000000000000000000000000000000000000..ce69c5dc62bad479d7c1395443ceb39592b09b5b Binary files /dev/null and b/docs/source/old/images/gaudiSF.bmp differ diff --git a/docs/source/old/images/gaudiSF.gif b/docs/source/old/images/gaudiSF.gif new file mode 100644 index 0000000000000000000000000000000000000000..879e3976fdf138b244ca44d66b3d4cb16543c578 Binary files /dev/null and b/docs/source/old/images/gaudiSF.gif differ diff --git a/docs/source/old/images/gaudiSF.png b/docs/source/old/images/gaudiSF.png new file mode 100644 index 0000000000000000000000000000000000000000..589062bb1aba6455bb39373c516bb23ec3c3facf Binary files /dev/null and b/docs/source/old/images/gaudiSF.png differ diff --git a/docs/source/old/images/job.png b/docs/source/old/images/job.png new file mode 100644 index 0000000000000000000000000000000000000000..71031353f62981eeb5ebbcf606a005f7f0a90e09 Binary files /dev/null and b/docs/source/old/images/job.png differ diff --git a/docs/source/old/images/visualmodel.png b/docs/source/old/images/visualmodel.png new file mode 100644 index 0000000000000000000000000000000000000000..9897befa9073b4d26d656d6b654d4d4bf42f032a Binary files /dev/null and b/docs/source/old/images/visualmodel.png differ diff --git a/docs/source/requirements.txt b/docs/source/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..b7ba1d226aa6c8497e4c3fe8a3b24a2773547ce1 --- /dev/null +++ b/docs/source/requirements.txt @@ -0,0 +1,4 @@ +# These dependencies should be installed using pip in order +# to build the documentation. + +sphinx-rtd-theme==0.4.3 diff --git a/docs/source/tutorial.rst b/docs/source/tutorial.rst new file mode 100644 index 0000000000000000000000000000000000000000..2db92cc93743df74bf3bec75c9001e472c1c4715 --- /dev/null +++ b/docs/source/tutorial.rst @@ -0,0 +1,4 @@ +Gaudi Tutorial +============== + +This is the Gaudi tutorial. diff --git a/docs/source/user_guide.rst b/docs/source/user_guide.rst new file mode 100644 index 0000000000000000000000000000000000000000..6db61dd68551ebf712635f0275d2f07e6911a81d --- /dev/null +++ b/docs/source/user_guide.rst @@ -0,0 +1,8 @@ +Gaudi User Guide +================ + +The Gaudi User Guide is being *revamped* with a description of all the +new features and great recent additions. + +In the meantime we refer you to the `old user guide +<http://gaudi.web.cern.ch/gaudi/resources/GUG/index.html>`_.