Project

General

Profile

OM Internals

These are some crude notes on how OM works.

OM ROOT Files

Histograms

The Lizard presents the Root file as the directory structure in the file. Basically, one only needs to save histograms (TProfile, TH1, TH2, TGraphError) in any directory and the OM should show them more-or-less correctly.

Histograms are shown in the left area by their name; the pane showing their content uses their title.

It is often convenient to name histograms something like
h_011_special_thing
with a number, in order to force them into being displayed in order. The Lizard shows them in string-sorted alphabetical order

If a histogram uses axis bin labels, these labels will be correctly shown, and a text summary will be included next to the plot. This is useful for counting events or occurances.

Special plots (for example, electronics-space color maps) are specially coded in the front-end, and are recognized by being in specially-named directories (such as mapccc or mappmt or maptpc).

Nothing other than histograms are needed. However, there are many more features of the Lizard presentation that can be controlled via more data structures in ROOT. None require special libraries.

Alerting the user to important errors

One histogram is special: if there exists a TH1 at "errors/h_errors" then the Lizard will show the Big Red Box telling the user something is wrong.

This histogram usually is a bin-labelled TH1 with error counts.

File-level info (the "cycle")

At the root level of the histogram file, the Lizard looks for these objects:

Object type Name Title
TNamed run <run number as a string>
TNamed subrun <subrun number as a string >
TNamed event <last event number as a string>
TTimeStamp firstEventTimeStamp Time of the first event in the file
TTimeStamp lastEventTimeStamp Time of the last event in the file
TTimeStamp fupdateTimeStamp The last time this file was touched

Directory-level Information

At each directory level, including the root directory, the Lizard looks for a TNamed object with the name "DirectoryInfo". The title (GetTitle()) string is interpreted as JSON.

This JSON object holds any number of further JSON elements. Each element is displayed as one line in a table at the top of the Lizard view. Here is an example of a DirectoryInfo string for the "pmt/crate10/card04/chan39" subdirectory:

{"crate":{"title":"Crate Number","value":10},"card":{"title":"Card Number","value":4,"desc":"Card module\/slot number"},"channel":{"title":"Channel Number","value":39,"desc":"FEB Channel number"},"special":{"title":"Special Channel","value":"?-1","desc":"Non-PMT input"}}

Here it is formatted for readability:

{
  "crate":{
        "title":"Crate Number",
       "value":10},
  "card":{
       "title":"Card Number",
       "value":4,
       "desc":"Card module\/slot number" 
       },
  "channel":{
       "title":"Channel Number",
       "value":39,
       "desc":"FEB Channel number" 
       },
  "special":{
       "title":"Special Channel",
       "value":"?-1",
       "desc":"Non-PMT input" 
       }
}

This looks like this:

In addition to "title", "value", and "desc", you may also include "error" with a value which will be shown as <value>+/-<error>

In several places in the OM, other objects are stored in this. For instance, the connection maps from electronics channel to TPC wire are stored in a JSON object called "map" in tpc/maptpc and tpc/mappmt respectively. Special code is written to interpret these maps.

Histogram-level information

In any directory containing a histogram, e.g. "h_10_my_histogram" the file may also optionally gave a TNamed object with the name "h_10_my_histogram_Info". If this object exists, it will be used to modify the histogram.

This object can contain the following elements:

key Description
info An HTML string describing the histogram, shown in italics just below the title. e.g. "This plot shows the average charge per record"
draw_points true or false; if true, use dots to represent the data rather than histogram bars
draw_fill true or false; if true, fills in histogram bars
draw_logy true or false. If false, overrides default (log on vertical scale)
draw_line true or false; if true, draws a line connnecting points
draw_zero_suppress true or false; if true, it offsets the histogram to the data minimum, instead of drawing from zero

The Online Monitor Histogramming Code

The code is in the DAQ repository, under "online_monitor" but incorporates code from other areas (the dispatcher, etc).

Here are some basic concepts:

- All the work is done by a single class called the Integral. This class has code in Integral.h, Integral.cpp, Integral_pmt.cpp, Integral_tpc.cpp
- The Integral class keeps track of all the current histograms, in a map that it references. Histograms can be accessed with a call like:

   MoldType  my_mold(....);
  TH1* h = get_or_create<TH1>(my_mold)

This call is the core idea behind the management of histograms: it either efficiently finds the pre-existing histogram, or creates it if this is the first time the histogram has been accessed during the current run. All histograms are immediately mapped to the file and directory.

The Mold object is a lightweight, short-lived object that serves as a proxy for the histogram name, and is described in the Mold.h header. A Mold describes a kind of histogram, and knows:
- How to make the histogram and label the axes
- What the directory and name of the histogram are
- The descriptive text that accompanies the histogram
- Etc

The idea here is to efficiently separate the code that creates and manages histograms from the code that fills the histograms with content.

Mold objects follow the 'method chaining' syntax, e.g.

hVsWall = get_or_create<TProfile>(MTpcPedestalVsTime()
                                           .start(t0)
                                           .ccc(6,4));

This snippet creates a new histogram if it doesn't already exist, with a left-hand time of t0, with the directory set to "tpc/crate6/card04" and a histogram name that's defined in the MTpcPedestalVsTime object.

This allows a single function (e.g. Integral::integrateTpcWire) to fill all the relevant histograms for that channel. This is efficient in computation time, allowing different histogram-building algorithms to share intermediate code and values. It does mean that these functions are very long, but they are not very complex.