Parameter Database and Services for Same
========================================
This facility is meant to address the need to store and access parameters
(such as detector dimensions or smearing parameters) which condition
a process (such as gismo event generation or fast MC). It has nothing
to do with reading, writing or storing event data.
Visible structure of the data
-----------------------------
Information is organized into _components_
Each component has
a unique _name_. Kept in the form of string. Required
a unique _handle_ Required, assigned
by facility
list of _properties_ Kept as strings Optional
list of field-identifier-value pairs Optional
a _field-identifier_ is a string
a _value_ may be any of
boolean
integer
floating point
string
array (list) of integer
array (list) of floating point
array (list) of strings
component handle (maybe)
(A property can be viewed as an identifier-value pair where the
the value is boolean)
Is this sufficient or will we need to allow values having a more arbitrary
structure?
* * * * * * * * *
Services
--------
1. Register. This makes the most sense for applications which are initialized
before the dbs is assembled (say by reading in one or more files)
An application (i.e., class) should be able to register to be called back
- for a particular (top-level only?) component, by name
- for all (top-level?) components having a particular property
The application could then be called back
- when the component is first assembled
- when a field changes its value
- when it is being deleted from the dbs (if we have such an operation)
2. Read. Several kinds of information can be obtained.
a. Given a component name, return its handle (if any)
b. Given a component handle, return its name
c. Given a component handle, return list of properties
d. Given a component handle and field identifier, return value type
(e.g. list-of-float)
e. Given a component handle and field identifer, return its
value. Maybe have separate routines to do this for different
value types?
3. Scan.
a. Given a property name, call back once for each component with
that property (handle and property name would be arguments to
the callback)
b. Given a component handle, callback once for each field.
Arguments passed to callback would include field name, perhaps
also field type.
4. Write
a. Establish a component (i.e., give it a name)
b. Add a property
c. Add a field (supply name, type, data)
d. Modify value of existing field (probably not allowed to change
type except maybe to change length of list
e. Notify registrants of change
5. Delete??
* * * * * * * * *
Some elements of the implementation
-----------------------------------
For each component, keep associative array (e.g., map) of name versus
handle. Handle is a pointer a structure including
* a list of all the fields (including properties)
of the component. Information for a field looks like
name
type ID
list length, maybe also total size
pointer to value
* a list of registrants for this components
* (maybe) pointer to parent component, if any
There also has to be some facility for looking up a particular field
of a component. Could have entries in the associative array of
form (fully-qualified field name, pointer to field information).
E.g. ("HAD_EC.rOuter", ptr), ("EM_Barrel.material.names", ptr)
("TrackSmear.PtMin", ptr). Or could find a particular field by doing
one lookup for each qualifying piece of name. E.g., for
EM_Barrel.material.names first get handle for "EM_Barrel" component,
then for subcomponent "materials" (looking in EM_Barrel assoc. array),
then for field "names" (in subcomponent materials assoc. array).
To handle registration by property, need to keep a list of registrants
per property (where here the property name is *not* qualified by component
name) as well. May want to restrict this to properties which appear in
top-level components.
Ideally there would be implementations both for Java and for C++ which
would be linked in as utilities in most if not all of our standard programs.
* * * * * * * * *
Typical components
------------------
1. Physical detector components, e.g. HAD_EC.
Component name
HAD_EC
Property-list
Calorimeter
Endcap
Hadronic_Calorimeter
Active
Cylinder
Physical [implicit from Cylinder property]
Layered
Segmented
Additional fields
(Assume in addition to above field types there is known type "material"
consisting of a string name and thickness. Typical value
for this type looks like ("Polystyrene", 0.5)
inner_radius = <float value> # Existence of these four fields is
outer_radius = <float value> # implied by "Cylinder" property
inner_z = <float value>
outer_z = <float value>
n_layers = <integer value>
layer_materials = <array of material>
inner_wall = <material>
outer_wall = <material>
The above is more or less the set of values appearing in detector
definitions used by gismo. A different, partially overlapping
set is appropriate for Fast MC. For example, instead of detailed
materials information, Fast MC would need average values for
interaction length/cm and radiation length/cm.
2. More abstract or global properties associated with the physical
detector, e.g.
Component name
HAD_Segmentation
Properties
Calorimeter
Hadronic_Calorimeter
Segmentation
Fields
phi-seg = <integer value>
costheta-seg = <integer value>
(could perhaps also describe tower id mapping here.
For each field within tag need at least
a name
first bit in bit field
width of bit field
)
(Might also move n_layers here and include handle for HAD_Segmentation
among fields of HAD_EC. Similarly, if materials layout is to be
the same for EC and Barrel, might define a separate component for that
and let HAD_EC, HAD_Barrel point to it.)
3. Sets of analysis parameters. For example, Fast MC calorimeter smearing
parameters
Component name
FastMC_Cal
Properties
Calorimeter
FastMC
Fields
energySmearEM = <list of floats>
energySmearHad = <list of floats>
transverseSmearEM = <list of floats>
transverseSmearHad = <list of floats>
* * * * * * * * *
Setting values en masse
-----------------------
Detailed discussion of how the values get from the outside world into
into the parameter database (that is, into some piece of code which can
invoke the write services) is outside the scope of this note. Doing this
in a flexible manner would be the job of a separate facility. Probably
the most difficult part of this problem is to determine the type
of a value in a particular field. There are at least three possible
approaches:
1. For each field, write a special piece of code which knows how
to parse that field (more or less the way iniData operates now).
2. Define a sort of database definition file which describes sizes and
types for all possible components and their fields. Some compile-like
procedure would produce a binary version of this information so that
code attempting to read a parameter-values file could look up how to
read any particlar field. This is similar to VMS CLD files.
3. Come up with a format for the parameters file which includes
type information along with the values.
I lean towards 3 if it can be made to work because it is the most
flexible. It is likely that there will be many changes and additions
to the set of interesting parameters.
One question I have is whether the usual primitive types (string, float,
etc.) and homogenous lists of these types is adequate. If not, where do
we draw the line?
* * * * * * * * *
Layering
--------
The parameter database is meant to be at the bottom of perhaps several
layers of utilities allowing access to parameters. It is purposely
designed *not* to provide the sort of higher level of organization of
data which might be desirable for a particular application, such as a
one-event display. The hope is that it provides an adequate interface
for a tool to do just that. The expectation is that the services
provided by the parameter database would generally not be invoked by
top-level application code, but by such intermediate utilities.
|