AIDA is a standard set of interfaces for creating and manipulating
histograms, n-tuples and related data analysis objects. It has been created
cooperatively by a group
of developers working on high-energy physics data analysis tools. The goal
of the AIDA project is to provide the user with a powerful set of interfaces
which can be used regardless of which analysis tool they are using. The
advantages of this approach are that:

The user will only need to learn one set of interfaces even if they use
more than one tool.

By pooling the experiences of several different development teams we will
be able to develop a more complete solution to the data analysis problem.

Different analysis tools built using AIDA will be able to interoperate,
for example by exchanging objects in a common storage format (initially XML).

Currently two versions of the AIDA interfaces exist, one for Java and one for
C++. The two interfaces are as identical as the underlying languages will
permit.

We have been careful to avoid using a "lowest common denominator" approach in
the development of the AIDA interfaces. Rather than limiting ourselves by the
existing capabilities of the underlying analysis tools, we have designed a rich
set of interfaces, with the expectation that the tool developers will need to
add new features to support the full AIDA functionality. This does mean however
that the early implementations of AIDA may not completely implement all
features.

A few things to notice in this example, first note that AIDA objects are
always created from factories. Although different implementations of AIDA may
return different objects from their factories, the returned objects will all
implement the same standard AIDA interfaces. In this way it is possible to
change from one AIDA implementation to another just by changing which IAnalysisFactory
is used.

In AIDA instead of creating objects directly using "new" one uses factories.
There is one "master" factory, IAnalysisFactory
from which other factories are obtained. The IAnalysisFactory allows you to
obtain factories for creating trees (ITreeFactory),
histograms, clouds and profile histograms (IHistogramFactory),
tuples (ITupleFactory)
etc.

You will see many examples of using factories in the remainder of this
guide.

Histograms support arithmetic operations, in particular add, subtract,
multiply and divide. In all cases the operation is applied bin-by-bin, and the
histograms involved in the operation must have the same binning. The input
histograms are unchanged, and a new histogram is created as the result of the
operation. All of the arithmetic operations are methods of IHistogramFactory
to reflect the fact that a new histogram is always created as a result of the
operation. For multi-dimensional histograms it is also possible to create slices
and projections.

AIDA supports 1D and 2D profiles. IProfiles are created throught the IHistogramFactory
that also supports arithmetic operations like sum, subtraction, multiplication,
division and weighted mean. As for IHistograms, the IProfiles involved in the
arithmetic operations must have the same binning and will be unchanged by the
operations itself.

Clouds are one, two or three dimensional unbinned collections of data. They
are used for scatter plots or dynamically rebinnable Histograms. A Cloud can be
automatically converted to an Histogram when the number of entries exceeds a
given threshold, or can be manually converted by the user.

In this example the IClouds cl1D and cl2D are set by default to
autoconvert when the threshold is reached. (Please note that in this case the
threshold depends on the particular implementation of the AIDA package you are
using). For the ICloud cl3D we set the threshold at 1500 events and we
choose to switch off the autoConvert option; in this case to convert the
ICloud it is necessary to invoke the convert method.

An IDataPointSet
is a collection of IDataPoints.
Each IDataPoint is an n-dimensional collection of IMeasurements.
Through an IDataPointSetFactory
it is possible to either create empty IDataPointSets or already full sets using
the data stored in IHistograms, IClouds and IProfiles. IDataPoints and
IMeasurements cannot be created, they can only be accessed through the
IDataPointSet.

AIDA also provides arithmetic operations among IDataPointSets that have the
same size and the same dimension.

In the code above tuple1 is created by providing the factory two
arrays specifying, respectively, the name and the type ( i.e. the Class ) of the
Tuple's columns. Alternatively we create tuple2 by providing the
ITupleFactory a single string with name and type for all the columns separated
by either a coma (,) or by a semicolon (;). In both cases the
default values are specified by following the column's name with = value
. Please note that spaces are ignored.

IFilter and
IEvaluator
are simple objects that can be created by ITupleFactory
and help manage data in an ITuple.
Corresponding "create" methods in the factory take String that can
contain ITuple column names, standard arithmetical and boolean operators (like
+, -, /, *, > , <, ==, ...) and standard functions from the java.lang.Math
class ( sin, exp, pow, ...). The string should evaluate to boolean for
IFilter and to double for IEvaluator.

Example below demonstrates how to use IFilter and
IEvaluator
to filter and evaluate ITuple data on a row-by-row basis (1) and how to fill
histograms from an ITuple (2).

Note: IFilters and IEvaluators are created as a stand-alone objects.
You must associate them with ITuple with initialize(ITuple tuple) method
before you can use them.

ITupleFactory
has several methods to group ITuples
together and to create ITuple with a reduced data set.

createChained methods create a logical chain of ITuples. All ITuples
in the set must have the same structure and resulting chained ITuple can not be
filled. In a sense, chained ITuple is just a view of original Ituples, so no
data is copied during creation of chained ITuple.

createFiltered method creates a new reduced tuple (less rows) from an
existing one by applying a filter. Data is explicitly copied to a new n-tuple.
User also has ability to copy only selected subset of columns by providing array
with column names

Within AIDA it is possible to create ITuples containing columns of ITuples.
This allows the user to create ITuples with complex structures. Here is an
example of how to create, fill and retrieve data from such an ITuple:

Notice the different ways of accessing the inner ITuple when filling and when
retrieving the data. The getTuple(int index) method returns the ITuple
ready to be filled, while the getObject(int index) method, invoked on the
same column, returns the same ITuple but with the current row pointing to the
current row of the higher level ITuple. For this reason the getObject(int
index) method is used to retrieve the data. Also notice that the
addRow() method has to be called for each of the individual inner ITuples
evey time a row is ready to be stored.

The AIDA ITree
interface provide two capabilities. The ability to group analysis objects such
as Histograms, Clouds, Tuples etc. into hierarchical directories (or
folders), and the ability to save and restore sets of analysis objects into
files or databases.

A second use for trees is to allow objects to be stored and retrieved from
files or databases. So far we have always used the ITreeFactory.create()
method to create ITree's. This
method creates an ITree that is
not associated with any storage, so the objects associated with this type of
Tree are only valid within the current process. The other methods of ITreeFactory
allow ITree's to be
associated with a file or database. The following example shows how to create a
set of histograms and store them in a file.

In this case we are creating a compressed XML file. The precise types of
files or databases which can be used will depend on which implementation of AIDA
you are using, however all AIDA implementations should support reading and
writing XML files to allow easy interchange of objects. The next example shows
how to read an XML file back in.

In designing the ITree interface we have borrowed some other concepts from
Unix. In particular ITree's allow other ITree's to be mounted and unmounted at
an arbitrary point in the tree. This allows a whole set of files to be opened
but be viewed by the AIDA user as a single ITree. ITree's also support symbolic
links.

We have already seen simple use of plots the AIDA IPlotter
interface. By default the plotter contains a single plotting region that covers
the entire page, however any number of regions can be defined by the user. These
regions may either consist of a regular grid created using the IPlotter.createRegions()
method, or an arbitrary arrangement of regions created using the IPlotter.createRegion()
method. At any time there is one currentRegion, which is the region that will be
used when a new item is plotted. The Plotter allows histograms, clouds, and
functions to be plotted. If more than one item is added to the same region the
items will be overlaid on the same plot.

The AIDA IFitter
interface provides the user the possibility to fit IFunctions to any AIDA data
storage object. Binned fits can be perfomed on IHistograms, IProfiles and
IDataPointSets, while unbinned fits can be performed on IClouds and ITuples.
Simple fits can be perfomed directely on the data storage objects while the IFitData
interface is to be used for a greater control over the data, in particular its
ranges and the connection to the IFunction's variables. Through the IFitter it
is also possible to change the underlying optimization engine as well as the fit
method used.

In the example below it is shown how to perfom a binned and an unbinned fit
over the same data using different optimizers and fit methods.

In the JAIDA implementation there are currently two optimizers available:
Minuit and Uncmin and it is possible to choose among the following
fit methods: ChiSquared, CleverChiSquared,
BinnedMaximumLikelihood, LeastSquares,
UnbinnedMaximumLikelihood.

With the IFitter interface it is possible to have a more direct control over
the fit: the parameters in the fit can be controlled with the IFitParameterSettings
interface and it is also possible to set constraints among them. In the example
below we create a scripted function an show how to control its parameters: