Event Analysis Tool
Quick Start Guide

Masahiro Ito, Daniel Sigg, January 2002


  1. Overview
  2. What is an Event?
  3. First Steps
  4. Events: Second Look
    1. Event Class
    2. Name Class
    3. Column Names
    4. Column Class
    5. Info Class
    6. Layout Class
  5. Dealing with Sets of Events
    1. Set Class
    2. Basic Operations
    3. Read and Write Events from/to a File
    4. Advanced Topic: List and Chain Classes
  6. Working with Events: Selection
    1. Event Window
    2. Event Condition
    3. Event Function
    4. Event Index
    5. Value Class
    6. Selection Algorithms
    7. Sorting Algorithms
    8. Coincidence Algorithms
    9. Cluster Algorithms
  7. Working with Events: Histograms
    1. 1D and 2D Histograms
    2. Time Series
  8. Advanced Topics
    1. Root Settings
    2. Compilation
    3. Writing your own Conditions and Functions


Overview

The event analysis tools was written with the idea to provide an interactive command line interface which will allow the user to take events from the LIGO database and to explore their properties graphically and conveniently. The event tool is a C++ package developed to run under ROOT which allows the selection and plotting of events generated in gravitational wave detectors. It features the capability to handle events with varying column layout (not just n-tuples) as well as handling the most common column data types.

From a user's point of view the following concepts are important to understand:

  • Basic event definition and handling
  • Containers for storing sets of events
  • Functions which take event arguments and return values
  • Conditions which take event arguments and return either true or false
  • Algorithms which select, modify and sort events.

  • The event analysis package uses the power of C++ to make these concepts available across all classes and user functions. It allows the user to take existing functionality, extent it to the current need and plug it right back into existing macros. Special care was taken to hide most of the "C++ magic" behind a few
    simple classes the user needs to know to solve straight forward problems, but allows the advanced user to take full advantage of the strength of the underlying architecture.

    Since it is all pure C++ code, any macro developed in the interactive ROOT environment can readily
    be compiled into a stand-alone program. Because the event analysis tool is part of the GDS distribution and compiles into a shared object library, DMT monitors can access these features by simply including the necessary header files.



    What is an Event?

    One of the features of interferometeric gravitational wave detectors is that events do not follow a standard layout. In high energy physics an event is usually described as an n-tuple with each column having a specific meaning. Rather than building on n-tuples with implicit column definition, the event analysis package uses a "free format". An event is defined by an event layout and an event data block. The Figure below depicts how an event is represented:

    Fig. 1: Representation of an event.

    In general, the number of event layouts will be far less than the number of actual events. To make the code efficient the package maintains a global list of all event layouts and each event will just store a pointer to one of the global layouts. In order to be able to distinguish events of different type each layout must have assigned a unique event type name. For instance, coincidence events are stored with type name "CoincidenceN" with N = 2, 3 for double and triple coincidences, respectively. Apart from its type the event layout maintains a list of columns; each column has a name, a type and an offset into the data block associated with it. The column name has to be unique within an event of a certain type, but can be the same for columns with the same meaning in events of different types. As a matter of fact, all events have the following columns in common:
     
    Table 1: Fixed columns of an event. 
    Name Description Type
    Time describes the time of the event in GPS seconds Time
    Name described the name of an event Int
    Ifo describes the interferometer(s) in which the event was detected Int
    ColumnNumber describes the number of columns used by this event Int

    Every event must contain a time, and for most analysis algorithms events have to be ordered in time. The Name field is intended to identify the subtype of an event. For GDS triggers the name field is used directly, whereas for most ldas events the search field is used instead. For efficieny reason an indexed string list is used and the name field is of type integer. A special "Filter" class exists to select events based on their type and name. The "Name" class is used to lookup a string index and to add a new string to the index. The Ifo field is intended as a bit encoded value with each bit representing a detector. An event from one detector would set one of the bits, an event from another detector would set another bit, whereas the coincidence event would the set both bits. This way one can keep track of where the events were originally generated. A special "IfoSet" class exist to facilitate this capability. Both the Name and the Ifo field are mainly there for convenience and to avoid costly string comparison operations.

    The column number field is mainly used internally to keep track of the length of the data block. This makes it possible to later add columns to existing events without the need to update all previously created events of the same type. When a column is read from an event which is "too short", the default value of the corresponding column type is returned (usually zero). When a column which does not (yet) exist is written to, the data block of the event is automatically enlarged to encompass the new fields.

    To support a wide variety of events and make them as useful as possible, the following column types (classes in C++ parlance) are supported:
     
    Table 2: Data types of event columns. 
    Name Description C++
    Int 32 bit signed integer int
    Real double precision floating point value double
    Complex double precision complex number std::complex
    Time DMT Time class representing GPS seconds and nanoseconds ::Time
    String string class representing an ASCII string of arbitrary length std::string
    Event the event class itself event::Event

    It is important to recognize that an event can contain other events as part of its columns! This is used by the coincidence event type to store the original events leading to the coincidence. For instance, an event of type "Coincidence2" contains three additional columns (apart from the common ones) which are named "Order", "Event(0)" and "Event(1)". The first field is of type Int and yield 2, whereas the other two fields are of type Event and store the original two events which lead to the coincidence.

    Event layouts for the following event types exist:
     
    Table 3: Predefined event layouts. 
    Type Description Additional Columns Type
    Simple Only the basic columns -
    Standard Pretty much the same as simple -
    CoincidenceN Coincidence events with N 
    representing the coincidence order
    Order Int
    Event(i) Event
    ClusterN Cluster events with N 
    representing the cluster order
    Order Int
    Event(i) Event
    GDS_Trigger GDS trigger see T990101
    Sngl_Burst Burst event see T990101
    Sngl_Inspiral Inspiral event see T990101
    Sngl_Ringdown Ringdown event see T990101
    Sngl_Unmodeled Unmodeled event see T990101
    Sngl_DPeriodic Periodic event see T990101

    When reading ldas events from an XML file the following translation rules are applied:

  • The search field is stored in the name field of the event,
  • A time stamp in the database uses two fields (GPS s and ns) which are stored as a single time value,
  • The start time field is used for the event time, and
  • The ifo string field is stored as a bit encoded value in the field of the same name.

  • When writing events to a file no translation rules are applied and they can be read back identically.


    First Steps

    Try the example script and data on the ROOT command line and see how the event analysis tool works. Tar-gzipped example file can be downloaded from the bottom of this section.

    This example reads two data sets, looks for coincident events and plots histogram of time difference of coincidence events. Each sample data contains 300 events of glitchMon triggers taken from Meta Database through GUILD. myevent1.txt contains 300 events of H0:PEM-MX_SEISX and 300 events of H0:PEM-MY_SEISX for myevent2.txt .

    using namespace events; // Lazy! Avoid using events::
    //--- Read events from ASCII files. ---
    Set s1; // Prepare a container for events.
    s1.Restore("myevents1.xml"); // Read a set of events.
    s1.AddChain("myevents2.xml"); // Read another set of events
                                  // and add to s1.
    //--- Sort events in chronological order. ---
    s1.Sort();
    //--- Search coincidence events. ---
    Set s2; // Prepare another container.
    s2.SetWindow(10.0,-5.0); // Set time window from -5.0 to +5.0 seconds.
    s2.Coincidence(s1); // look for coincidence events in s1
                        // with the time window and store results in s2 .
    //--- Plot histogram. --
    Histogram1 h("Time Diff",12,-6.0,6.0,"Time Difference (sec)",
                 "Nubmer of Events"); // Prepare a histogram container.
    s2.Histogram(h, Column("Time(0)") - Column("Time(1)"));
       // Fill the histogram with time difference of
       // two coincidence event in s2 .
    PlotHistogram(h); // Plot the result.
    You will see a histogram window popping up as below:
    Histogram Window
    download example script and data.


    Events: Taking a Second Look

    Event Class

    An event is a simple class with only a few methods. The most important ones are:
     
    Table 4: Event class. 
    Method Return Arguments Description
    Event - layout Create an event with the specified layout
    IsValid valid - Is this a valid event with a valid layout?
    GetValue success, value name Get the column value of the given name
    SetValue success name, value Set the column value of the given name
    GetTime time - Get the event time
    SetTime - time Set the event time
    GetName name - Get the name of the event
    SetName - name Set the name of the event
    GetIfo ifo - Get the ifo set of an event
    SetIfo - ifo Set the ifo set of an event
    Dump - stream Dump the column values to the output stream
    GetData data ptr - Get a pointer to the data block
    GetLayout layout - Get the layout of the event
    == equal event True if events are equal in layout and data
    < less event Compares events by their time stamp

    The GetValue and SetValue functions require a column name.

    Name Class

    A dedicated name class exists to make looking up events using their name field efficient. The name class implements a global index list for strings. The most important methods are:
     
    Table 5: Name class. 
    Method Return Arguments Description
    Name - string Finds the index of the string; makes a new entry if 
    string does not exits
    Name - id Uses the specified Id as the index
    GetId id - Returns the index number
    GetName string - Returns the string associated with the current index
    SetName success string Sets a new string
    == equal name Compares two string by their index number

    Since selecting events of a given name is such an often task, a special Filter class exists to faciliated this.

    Column Names

    Column names are case insensitive ASCII strings. For example "Time" represents the event time. A special case are columns which are themselves events:

    "Event(1)"         // Column of event type
    "Event(1).Amplitude// Amplitude of event stored in Event(1) column
    "Amplitude(1)      // Short form
    The short form can always be used, if the name of the event column is of the form "Event(n)" with n a non negative integer. Even so not a likely case, it is possible to have an event with an event column which contains yet another event column. These columns can be accessed by specifying names such as
    "Event(m).Event(n).Amplitutde"
    "Event(m).Amplitutde(n)"
    "Amplitutde(m,n)"
    "Event(m,n).Amplitutde"
    which all correspond to the same amplitude value with m and n the event column indices of the first and second sub event, respectively. Column names can not contain the characters "[", "]", ".", "*" or "?". They should not contain "(", ")" unless they are of the event type and contain the string "Event".
    "Time[0]"     // wrong!
    "Channel*"    // wrong!
    "?"           // wrong!
    "Time.1"      // wrong!
    "Event(1)"    // ok, if type is Event
    "Amplitude(1)"// wrong!
    Using something like "Amplitude(1)" as a column name would be confusing.
     

    Column Class

    Using the GetValue and SetValue methods of an event is not very efficient, since for each call the column list in the layout must be searched to determine data type and offset. The Column class serves as a quick means to access identical columns names from a series of events. The important methods of the column class are:
     
    Table 6: Column class 
    Method Return Arguments Description
    Column - name Creates a column of the specified name
    IsValid valid - Checks if this is a valid column
    Get success, value event Gets the corresponding column value
    Set success event, value Sets the corresponding column value
    Evaluate success, value argument Returns the column value

    The column class implements a caching algorithms based on the event layout type which avoids successive lookups of column names if the event layout stays the same. In the example of the previous section, the column object was also used as an event function which can be used in expressions.

    Example:

    // A series of events is stored in a array. All events are of the same
    // type and have columns for amplitude and noise. The example explains
    // how one can use the column class to add a significance column.

    // Here are the iterators of the event array
    Iterator beg = ...
    Iterator end = ...
    // Get the layout and add a column
    beg->GetLayout().AddColumn ("Significance", ColumnType::kReal);
    // Create column objects
    Column sigma ("Significance");
    FunctionPtr expression = Column ("Amplitude") / Column ("Noise");
    Value val;
    WindowIterator i (beg, end, 1, 0.0);
    WindowIterator e (end, end, 1, 0.0);
    // Now go through the list and compute the new value
    for (; i != e; ++i) {
       if (expression->Evaluate (*i, val)) {
          sigma.Set (i->Current(), val);
       }
    }
    // Since setting a new column value is such a common task, one could use
    // SetColumn (beg, end, Column ("Significance"),
    //            Column ("Amplitude") / Column ("Noise"));
    // instead of the code after the AddColumn line.

    The only complication in the above example is that one has to use a window iterator rather than a standard iterator for calling the Evaluate function of the column class. We will see in one of the sections below why this is necessary.
     

    Info Class

    Sometimes one may want to access the information which is stored in the layout of an event rather than its values. This is done with the Info class:
     
    Table 7: Info class 
    Method Return Argument Description
    Info - name Creates an info object with the specified name
    Info - name, function Creates an info object with the specified name and function
    IsValid valid - Checks if this is a valid information token
    Evaluate success, value argument Returns the required information

    The Info class recognizes the following names:
     
    Table 8: Information tokens. 
    Name Type Description
    Type String Event type name
    Name String Event name
    TypeId Int Event type identification number
    NameId Int Event name identification number
    Size Int Size of event data block in bytes
    RefCount Int Number of events with identical layout
    ColumnNumber Int Number of columns
    Column(i)::Name String Column name
    Column(i)::Type String Column type name
    Column(i)::TypeId Int Column type identification number
    Column(i)::TypeSize Int Type size
    Column(i)::Fixed Int One if fixed column, zero otherwise
    Column(i)::Index Int Column index
    Column(i)::Offset Int Column byte offset

    The column index i can be specified as a number or as a column name. The notation "m:n" can be used to specify that the index should be enumerated over indices m to n. If the second argument is missing, i.e., "m:", the enumeration goes till the last column. When enumerating columns, the result is always returned as a string of comma separated values. The special literal "dollar" can be used to represent a column index which is specified at run-time. For example,

    Info ("Column($)::Name", Info ("ColumnNumber") - 1)
    can be used to get the name of the last column. If an information item is specified without an event index, the default is zero. As with the column class the information function can also access events stored as event columns. The same notation applies. For example, use
    Info ("Event(1).Type")
    Info ("Type(1)")
    to access the type information from the event stored in a column named "Event(1)".
     

    Layout Class

    Generally, events are read from file and the user doesn't have to use the Layout class directly, but sometimes one wants to define a new layout to be used for processed events.

    Example:

    // Create a new layout of type "myevent" and "mysub"
    Layout layout ("myevent");
    // Now add the columns we want; remember common columns are always there
    layout.AddColumn ("Amplitude", ColumnType::kReal);
    layout.AddColumn ("Channel", ColumnType::kString);
    // Important: A layout has to be registered before it is used for
    // the first time.
    layout.Register();
    // Now create an event of this type and fill in some values
    Event event (layout);
    event.SetTime (Now()); // Current time
    event.SetName (Name ("Glitch")); // Name is glitch
    event.SetValue ("Ifo", IfoVal ("H1")); // LHO 4K event
    event.SetValue ("Amplitude", Value (10.0)); // Amplitude is 10
    event.SetValue ("Channel", Value ("H0:PEM-MY_SENSOR")); // Set channel
    // Now check newly created layout and event
    layout.Dump();
    event.Dump();
    This should produce the following output:
    Type = myevent
            ColumnNumber: [Fixed,Int,0]
            Name: [Fixed,Int,4]
            Time: [Fixed,Time,8]
            Ifo: [Fixed,Int,16]
            Amplitude: [Variable,Real,24]
            Channel: [Variable,String,32]
    and
    Type = myevent
    ColumnNumber [Fixed,Int,0] = 6
    Name [Fixed,Int,4] = 1 "Glitch"
    Time [Fixed,Time,8] = 695987744.617635608
    Ifo [Fixed,Int,16] = 1 "H1"
    Amplitude [Variable,Real,24] = 10
    Channel [Variable,String,32] = "H0:PEM-MY_SENSOR"
    The important methods of the Layout class are:
     
    Table 9: Layout class. 
    Method Return Arguments Description
    Layout - name, subtype Create a layout with the specified name and subtype
    IsRegistered true/false - Checks if the layout is already registered
    UseSubtype true/false - Checks if the layout is using the subtype
    Register success - Registers the layout in the global list
    GetColumnList list - Gets the column list
    AddColumn success name, type Adds a column to the layout
    RemoveColumn success name Removes a column from the layout
    GetColumn column name Gets the column with the specified name
    Dump - stream Dumps the layout to the output stream
    DumpAll - stream Dumps all registered layouts to the output stream
    GetSimple layout - Get the minimal layout
    GetStandard layout - Get the standard layout
    GetCoincidence layout order Get a coincidence layout of specified order
    GetCluster layout number Get a cluster layout of specified number


    Dealing with Sets of Events

    Set Class

    Set class is the fundamental container of events on which users do event analysis operations. Users can do basic operations such as addition and deletion of single or multiple events from/to the event set and dump contents of the event set, and also do more complicated operations such as sorting events, finding coincidence and cluster events and making a histogram.

    Important! The Set class allows the user to add, remove and modify events on an individual basis. It also supports a Sort algorithm which can be used to pick, say, the 10 biggest events. However, analysis algorithms such as Coincidence and Select as well as plotting functions will only work if the events are ordered in time. Use the Sort() method to bring a Set in the correct order, if necessary.

    Here is the list of important methods of the Set class.
     
    Table 10: The event set. 
    Method Description
    Clear Clear all contents of the set.
    Size Get total number of events.
    Dump Dump contents of the set to the specified stream.
    DumpColumn Dump value of the specified column to the specified stream.
    Empty Check if the set is empty.
    Join Join all events in the specified set into the current set.
    Begin Begin iterator.
    End End iterator.
    PushBack Insert an event at the back.
    Erase Erase an event.
    PopBack Remove an event from the end of the event set.
    SetWindow Set the time window of the analysis.
    SetColumn Set new values to the column of selected events fulfill the given event condition in the given time window.
    Select Select events satisfying the given event condition in the given time window.
    Sort Sort events by the given event function in ascending/descending order.
    Coincidence Select coincidence events fulfilling the given event condition in the given time window.
    TripleCoincidence Select triple coincidence events fulfilling the given event condition in the given time window.
    MultiCoincidence Select multiple coincidence events fulfilling the given event condition in the given time window.
    ChainCoincidence Select coincidence events between the different chains of a set which fulfill the given event condition in the given time window.
    Clusters Select events fulfilling the given event condition and threshold in the given time window.
    Histogram Fill 1-D or 2-D histogram with given event functions and conditions.
    TimeSeries Compute the event rate or an event function value as function of time.

    Basic Operation

    Users can add, erase and get basic information of the contents of a Set container through following class methods.
     
    Table 11: Methods of basic operations 
    Method Return Arguments Description
    Clear - - Cleat the set.
    Size # of events - Get total number of events in the set.
    Dump - # of events, stream Dump contents of the set to the specified stream.
    DumpColumn - name, # of events, stream Dump value of the specified column to the specified stream.
    Empty true - Check if the set is empty.
    Join - event set Join all events in the specified set into the current set.
    Begin iterator - Begin iterator
    End iterator - End iterator
    PushBack - event Inserts an event at the back.
    Erase - iterator Erase events
    PopBack - - Remove an event from the end of the event set.
    SetWindow - duration, offset Set the time window of the analysis.
    SetColumn - column, function, (condition), (window) Set new values to the column of selected events fulfill the given event condition in the given time window.

    Example:
    Let a set, eventset, contains 100 events.

    cout << eventset.Size() << endl; // show size of the set.
    100  <== the event set holds 100 events.
    cout << eventset.Empty() <<endl; // check if the event is empty.
    0    <== return false for non-empty set.
    The Clear method erase all events in the event set.
    eventset.Clear(); // clear the set.
    cout << eventset.Empty() << endl;
    1    <== return true for empty set.
    cout << eventset.Size() << endl;
    0    <== the size of the event set is zero.
    Given set1 and set2 containing 100 and 200 events respectively.
    cout << set1.Size() << endl;
    100  <== set1 holds 100 events.
    cout << set2.Size() << endl;
    200  <== set2 holds 200 events.
    set1.Join(set2); // join set2 to set1.
    cout << set1.Size() << endl;
    300  <== now, events in set2 added to set1, then set1 holds 300 events.
    Copy contents of anotherset, to eventset through iterator loop and PushBack method. Actually, Set container can be copied simply by set1 = set2.
    for (Iterator itr = anotherset.Begin(); itr != anotherset.End(); ++itr) {
        eventset.PushBack(*itr);
    }
    Erase all events in eventset one by one using iterator.
    for (Iterator itr = eventset.Begin(); itr != eventset.End(); ) {
        itr = eventset.Erase(itr);
    }
    Erase all events.
    eventset.Erase(evetnset.Begin(),eventset.End());
    Calculate the ratio of Amplitude to Sigma and set the value to Significance. If the event layout doesn't have Significance column, the column is added to the layout.
    eventset.SetColumn(Column("Significance), Column("Amplitude")/Column("Sigma"));
    Set the time window of the current set to -5.0 to +5.0 second. The first argument is the duration of the time window and the second is the offset.
    eventset.SetWindow(10.0,-5.0);
    Dump the content of 100 events from the first.
    eventset.Dump(100);
    Dump value of the specified column in all events.
    eventset.DumpColumn("Amplitude");


    Read and Write Events from/to a File

    XML files

    Set class provides methods to import/export event data from/to XML files. LDAS Metadata retrieved through GUILD and saved in XML format is readable by the following methods (Set, Restore and AddChain).
     
    Table 12: XML File handling function 
    Method Return Arguments Description
    Set - filename Create a Set from event data on the specified file.
    Restore true/false filename Clear all events in the set, then read XML event table from the specified file.
    AddChain true/false filename Read XML event table from the specified file and add to the existing events.
    Save true/false filename, #events/file, max #events Save events to a file/files.

    Importing event data from XML file.

    Set eventset("eventdata.xml");
                  // Create an event set from the specified file.
    Another way to import event data.
    Set eventset; // Make an event set.
    eventset.Restore("eventdata1.xml");
                  // clear eventset, then read eventdata1.xml.
    eventset.AddChain("eventdata2.xml");
                  // read another file, eventdata2.xml, and
                  // add the events to eventset.
    Exporting event data to a file or multiple files.
    eventset.Save("eventsave.xml");
               // Save all events in eventset to eventsave.xml.
    Save events to multiple files.
    eventset.Save("eventsave.xml",10);
                  // Save all events in eventset to multiple
                  // files---each containing 10 events.
    The data will be saved on the files, eventsave.xml.1, eventsave.xml.2 , eventsave.xml.3 and so on.
     

    ASCII files

    An utility function, ReadMetaData, handles reading event data from comma delimited text file with column names saved by GUILD .
     
    Table 13: ASCII File handling function 
    Function Return Arguments Description
    ReadMetaData - filename, eventset Import ASCII formatted event data into event set.

    To make a data file, start up GUILD.
    Select GDS Triggers from LDAS metadata database menu.
    Get your event list.
    Save the list in ASCII format delimited by comma with column name option ON.
    Then, go back to ROOT and import the event data into an event set.

    Set eventset; // Make a event set.
    ReadMetaData("yourdatafile.txt",eventset);
                  // import data file into the event set.


    Advanced Topic: List and Chain Classes

    TBD



    Working with Events: Selection

    Event Window

    The basic concepts for selecting and analyzing events are the event window, the event condition and the event function. A Set container provides iterators for accessing all the events of the set in series. A typical for loop which enumerates the events of a set can be written like:

    for (Iterator i = set.Begin(), i != set.End(), ++i) {
       ... // *i is the current event
    }
    However, this is not a good way to generalize analyzing a set of events, since events which are close in time may have to be considered as vetoes. The analysis algorithms should have access to all events within a certain time window, so it can decide whether they are coincidences or vetoes. Hence, the event analysis tool introduces the concept of a sliding window which keeps track of all events with the chosen time interval and slides one-by-one through the event list. The Window class is used to represent both the list of events within the time window as well as the currently investigated candidate event(s). The number of candidate events is called the analysis order; it is one for a simple selection, two for coincidence algorithms, three for triple coincidence algorithms, and so for. (See the last section for a detailed description of the Window class.) A better way to loop through a list of events is:
    int order = 1;
    TimeWindow timewin (1, -0.5);
    WindowIterator beg (set.Begin(), set.End(), order, timewin);
    WindowIterator end (set.End(),   set.End(), order, timewin);
    for (WindowIterator i = beg; i != end; ++i) {
       ... // *i is a Window object
    }
    The WindowIterator takes two iterators, the order and a time window as initialization arguments. When dereferenced it returns a Window object which can be used for analysis. Window iterators only work on event arrays which are ordered in time.
     

    Event Condition

    This concept can be readily generalized for selecting events, if one also generalizes event conditions. An event condition and its close relative the event function are classes which take a Window as an argument and return true/false states and values, respectively. Predefined event conditions are:
     
    Table 14 : Available event conditions. 
    Condition Description
    Filter Select events based on their type and/or subtype
    IfoSet Select events based on their detector bit(s)
    Veto/Coincidence Check for nearby events
    Cluster Count the events which are nearby

    Event conditions can also be used in boolean expressions and are produced when comparing two event functions. Supported expressions are:
     
    Table 15: Event condition operations. 
    Operation Arguments Description
    ! condition Logical NOT
    && condition, condition Logical AND
    || condition, condition Logical OR
    == function, function Compare two function values for equality
    != function, function Compare two function values for inequality
    < function, function Compare two function values by less
    <= function, function Compare two function values by less or equal
    > function, function Compare two function values by greater
    >= function, function Compare two function values by greater or equal
    WithIn function, function, tolerance Check if two function values are within a given tolerance

    It is important to understand that at the time the condition is specified it is not evaluated, but rather an internal representation of the specified expression is build up in a tree like structure. This "condition tree" can the be used repeatedly to evaluate the condition on a series of events, or more precise a series of Window objects.
     

    Event Function

    The cousin of the event condition is the event function. It returns values of type real, complex, integer, string, time or event rather than a boolean value. It also supports math expressions and string processing (at this time not yet implemented). Predefined functions are few
     
    Table 16: Available event functions 
    Function Description
    Value A constant value
    Column A column value
    Info An event information token

    but all standard math functions are supported:
     
    Table 17: Math operations. 
    Function Arguments Description
    +, - (unary) function positive or negative
    +, -, *, /, % function, function plus, minus, times, over, remainder
    abs function absolute value
    sqrt function square root
    pow function, function power
    exp function exponential
    log, log10 function natural and base 10 logarithms
    sin, cos, tan function trigonometric functions
    asin, acos, atan function inverse trigonometric functions
    atan2 function, function 4 quadrant inverse tangent
    sinh, cosh, tanh function hyperbolic trigonometric functions
    ceil, floor function ceiling, floor
    ~ function bit wise negate
    &, |, ^ function, function bit wise logical operations
    >>, << function, function bit wise shift
    conj function complex conjugate
    polar function, function complex number in polar notation
    real, imag function real and imaginary part
    arg function argument of a complex number
    norm function norm of a complex number

    Since math operations are not evaluated at the time of specification, type checking is performed when the function is applied to a Window object (run-time). As a matter of fact the Evaluate method of a condition or function returns an additional status indicating whether the operation was successful. Typically, the selection algorithms will reject the candidate event(s), if evaluating the condition fails. Similarly, the histogram routines will ignore events which return invalid values.

    Here are a few examples:

    // Condition: checks that the amplitude of an event is larger than 5
    Column ("Amplitude") > 5
    // Function: square of the amplitude
    pow (Column ("Amplitude"), 2)
    // Condition: checks that the amplitude of the first candidate is
    // larger than 5 and larger than 10 for the second
    Column ("Amplitude[0]") > 5 && Column (Amplitude[1]) > 10
    // Function: product of the two amplitudes
    Column ("Amplitude[0]") * Column (Amplitude[1])
    // Condition: checks that the amplitude is between 5 and 10
    5 < Column ("Amplitude") <= 10
    // Condition: filters all burst events
    Filter ("burst::*")
    // Condition: burst events which are not vetoed by a PSL event
    Filter ("burst::*") && !Veto (Filter ("psl::*"))
    // Condition: get all H1 or L1 events
    IfoSet ("H1L1", IfoSet::kAnyOne)
    // Condition: get H1 and L1 coincidences
    IfoSet ("H1[0]") && IfoSet("L1[1]")
    // Condition: true if more than 5 events are located nearby
    Cluster (5)
    In most cases expressions which are allowed by C/C++ are also allowed in the event analysis tool. The exception are constructs of the form "function <ops> function <ops> function" with ops a comparison operator. One can also store an expression in a variable. To do this one has to use the FunctionPtr and ConditionPtr classes. Example:
    ConditionPtr cond = Filter ("burst::*") && !Veto (Filter ("psl::*"));
    FunctionPtr func = pow (Column ("Amplitude"), 2);
    A ConditionPtr or FunctionPtr can typically be used as an argument of an algorithm instead of the standard condition or function, respectively.
     

    Event Index

    When selecting single events the event window contains a single candidate event as well as all events within the chosen time window. In a coincidence analysis the event window will contain two candidate events--the event index is used to discriminate them. All conditions or functions which evaluate on a candidate event optionally allow to specify the event index using square brackets in the argument string. The following examples

    Column ("Time[1]")
    Filter ("burst:*[1]")
    IfoSet ("H1[1]")
    Info ("Type[1]")
    all evaluate on the second candidate event (index 1). If the index is omitted, they are evaluated on the first candidate event (index 0). If one wants to change the behavior of an already defined condition or function to evaluate on the second rather than the first candidate, one can use the Shift function. Both
    Shift (cond)
    Shift (func)
    evaluate the previously defined expressions on the event with index 1. However, the Shift function will simply strip of the first event and it will no longer be accessible.
     

    Value Class

    The Value class is derived from the event function and represents a constant value. The value class is also used as a return argument by the Evaluate method of an event function as well as an argument of the GetValue and SetValue methods of an event. Since it is derived from the event function, it can be used as part of any event function expression. The Value class implements the actual math operations. For instance:

    Value(1.0) + Value(2.0)
    computes to Value(3.0). The most important methods are:
     
    Table 18: Value class. 
    Method Return Arguments Description
    Value - value Creates a Value.
    Write success, value - Writes the value to a variable.
    Read success value Reads the value from a variable.
    Type type - Returns the type of Value.
    <ops> Value Value, (Value) All common math operations.

    The constructor together with the Read and Write methods are overloaded. They accept all valid column data types (see Table 2). If a math operation between Values fails because their respective data types are incompatible, a Value of type ColumnType::kInvalid is returned. A special set of classes is used for type conversion. Examples:

    IVal(Column("Amplitude"))// Get the amplitude and converts it to Int
    RVal(Column("Noise"))    // Get the noise value and converts it to Real
    CVal(Column("Noise"))    // Get the noise value and converts it to Complex
    TVal(Column("Test"))     // Get the test value and converts it to Time
    SVal(Column("Amplitude"))// Get the amplitude and converts it to String
    IfoVal("L1")             // A value representing the L1 detector


    From a user's point of view most of the complications involved in evaluating expressions are irrelevant. One should be able to write a condition or function in a form that makes sense and let C++ do the magic!
     

    Selection Algorithms

    The Select method creates a subset of the current or a specified event set by given conditions. The destination set is cleared and filled with the selected set.
     
    Table 19: Select Method 
    Method Return Arguments Description
    Select # of events (event set), condition Select events satisfying the condition and put them into the destination event set.

    Example:
    Select events which DURATION column is greater than 5.0.

    eventset.Select(Column("DURATION") > 5.0);
    Do the same operation as the previous example, but events are selected from anotherset and stored in eventset .
    eventset.Select(anotherset, Column("DURATION") > 5.0);


    Sorting Algorithms

    The Sort method provides not only the simple sort by column values, but also sort by expressions of math operations on one or more columns.
     
    Table 20: Sort Method 
    Method Return Arguments Description
    Sort # of events (event set), event function, 
    sort order, max # of events
    Sort events by specified column in the ascending/descending order.

    Example:

    Sort events by Amplitude in ascending order. The contents of eventset is replaced by the sorted events.

    eventset.Sort(Column("Amplitude"));
    Sort events by Duration in descending order.
    eventset.Sort(Column("DURATION"), false);
    Sort anotherset by Duration in descending order.
    eventset.Sort(anotherset, Column("DURATION"), false);
    The Sort method accepts an event function. This is an example of sorting anotherset by the ratio of Amplitude to StdDev.
    FunctionPtr func = Column("Amplitude") / Column("StdDev");
    eventset.Sort(anotherset, func);
    Important! If a Set has an order different than ascending in time, it can not be used for analysis methods.
     

    Coincidence Algorithms

    The Set class provides three types of coincidence methods, Coincidence , TripleCoincidence and MultiCoincidence, to find coincident events. These methods search around each event in the event set within its own or given time window. Coincidence and TripleCoincidence look for coincidence of two and three events respectively. MultiCoincidence finds coincidence between any given number of events.
     
    Table 21: Coincidence Methods 
    Method Return Arguments Description
    Coincidence # of events (event set), (time window), condition Search for coincidence events and return results into the destination set.
    TripleCoincidence # of events (event set), (time window), condition Search for triple coincidence events.
    MultiCoincidence # of events # of coincidence, (event set), (time window), condition Search for multiple coincidence events.
    ChainCoincidence # of events (event set), (time window), condition Search for coincidence events between the chains of a set.

    Example:
    Find coincidence within the time window of -5.0 to +5.0 seconds relative to each event. If no time window is specified in arguments of Coincidence method, the time window of the current event set is used.

    eventset.SetWindow(10.0,-5.0); // set time window of the current event set
                                   // to -5.0 sec to +5.0 sec.
    eventset.Coincidence();        // look for coincidence within the
                                   // current time window.
    Find coincidence from anotherset within the time window of +20.0 to +30.0 seconds. Since no time window is given in the argument of Coincidence method, the time window of eventset is used.
    eventset.SetWindow(10.0,20.0);    // set time window from +20.0 sec
                                      // to +30.0 sec
    eventset.Coincidence(anotherset); // look for coincidence events
                                      // in anotherset.
    Look for coincidence events within a -30 to +30 seconds time window which fulfill the condition that the first event is an H1 event and has an amplitude less than 100.0.
    eventset.Coincidence(anotherset, TimeWindow(60.0,-30.0),
                         IfoSet("H1") && Column("Amplitude") < 100.0);
    The same operation--but now requiring the second event to be an L1 event--can be done by using ConditionPtr.
    ConditionPtr cond1 = IfoSet("H1") && Column("Amplitude") < 100.0;
    ConditionPtr cond2 = IfoSet("L1") && Column("Amplitude") < 100.0;
    eventset.Coincidence(anotherset, TimeWindow(60.0,-30.0),
                         cond1 && Shift (cond2));
    *The usage of Triple and MultiCoincidence method is essentially the same as in above examples.

    The ChainCoincidence algorithm can be used to look for coincidences between different event chains. For example:

    Set eventset ("H1.xml");       // load H1 events into Chain 0
    eventset.addChain ("H2.xml");  // load H2 events into Chain 1
    eventset.ChainCoincidence();   // look for H1/H2 coincidences
    Using the ChainCoincidence algorithm instead of the normal Coincidence in the above example guarantees that H1/H1 and H2/H2 coincidences are not considered. If one of the event chains is much smaller than the other, this can be significantly less less computation. One important thing to make sure is that the Set contains exactly as many chains as the required coicindence order. For instance, the following example
    Set eventset;                  // Make Chain 0 !!! WRONG !!!
    eventset.addChain ("H1.xml");  // load H1 events into Chain 1
    eventset.addChain ("H2.xml");  // load H2 events into Chain 2
    eventset.ChainCoincidence();   // look for H1/H2 coincidences
    would make a set with three chains. The subsequent ChainCoincidence call would then look for triple coincidences and find none, since the first chain is empty. This is probably not what was intended!

    Cluster Algorithms

    Cluster event consists of multiple events selected by the given event condition, threshold and time window. Cluster event contains at least threshold + 1 events.
     
    Table 22: Clusters Method 
    Method Return Arguments Description
    Clusters # of events (event set), threshold, (time window), condition Search for cluster events and return results into the destination set.

    Example:
    Set the time window to -5.0 to +5.0 seconds, and find groups of more than three events within the time window in eventset.

    eventset.SetWindow(10.0,-5.0);
    eventset.Clusters(2);
    Finding clusters from events in anotherset using the time window from -5.0 to +5.0 seconds and picked up from burst::* type. The threshold set to 2.
    eventset.Clusters(anotherset, 2, TimeWindow(10.0,-5.0),
                      Filter ("burst::*"));


    Working with Events: Histograms

    1D and 2D Histograms

    The Set class provides two types of class methods to make histograms. The Histogram method fills the DMT histogram container, Histogram1 or Histogram2, with the value processed by the given event function from the event fulfilling the given event condition.
     
    Table 23: Histogram Method 
    Method Return Arguments Description
    Histogram # of events 1-D histogram, event function, condition Pick up events fulfilling the condition and Fill the histogram with value of the event function.
    Histogram # of events 2-D histogram, event function for X-axis, event function for Y-axis, condition Pick up events fulfilling the condition and Fill the histogram with value of event functions.

    Plot and PlotHistogram creates a window to show the 1-D histogram using DMT graphics libraries, so users can change the plot settings by its option pad. Plot function accepts up to 8 hitograms and display them on a single pad. PlotRootHistogram can plot both 1-D and 2-D histograms with the ROOT graphics libraries and accept the ROOT histogram options as the second argument.
     
    Table 24: Histogram Plotting Functions 
    Function Return Arguments Description
    Plot TLGMultiPad* Histogram1 (up to 8 histograms) Plot histogram.
    PlotHistogram - Histogram1 Plot histogram (1-D only) with DMT graphics library.
    PlotRootHistogram - Histogram1 or Histogram2, option Plot histogram (1-D and 2-D) with ROOT graphics library. The function accepts ROOT histogram option.

    Example:
    Create a 1-D histogram container with 20 bins ranging from 0.0 to 20.0. Then, it is filled with the value of SIZE column in eventset. The result is plotted by two different plotting functions.

    Histogram1 hsize("Size", 20, 0.0, 20.0, "Amplitude",
                     "Num. Events/Bin");
    eventset.Histogram(hsize, Column("SIZE"));
    Plot(hsize);              // Plot with DMT graphics.
    PlotHistogram(hsize);     // ... another function to plot
                              // histogram with DMT graphics.
    PlotRootHistogram(hsize); // Plot with ROOT graphics.
    Plot multiple histograms at a time.
    Histogram1 hamp("Amplitude", 100, 0.0, 100.0, "Amplitude",
                    "Num. Events/Bin");
    Histogram1 hdur("Duration", 50, 0.0, 50.0, "Duration",
                    "Num. Events/Bin");
    eventset.Histogram(hamp, Column("AMPLITUDE"));
    eventset.Histogram(hdur, Column("DURATION"));
    Plot(hamp, hdur); // Plot hamp and hdur on a DMT graphics pad.


    Make a 2-D histogram container with 20 bins ranging from 0.0 to 20.0 in X, and 30 bins ranging from 0.0 to 15.0 in Y. Next, the histogram is filled with values of SIZE for the X-axis and DURATION for the Y-axis. The result is plotted with the ROOT 2-D histogram option "col" which shows cells by colors.

    Histogram2 h2("Size-Duration", 20, 0.0, 20.0, 30, 0.0, 15.0,
                  "Amplitude", "Duration");
    eventset.Histogram(h2, Column("SIZE"), Column("DURATION"));
       // Fill histogram with the value of the column SIZE and DURATION
    PlotRootHistogram(h2, "col"); // Plot 2-D histogram with
                                  // ROOT graphics library.
    DMT histograms can be converted to and from ROOT histograms. They can be written to and read from file using the LIGO lightweight format. This format is based on XML (see T000067 for definition).
     
    Table 25: Histogram Utility Functions 
    Function/Class Return Arguments Description
    ConvertHistogram ROOT histogram
    ROOT Histogram
    Histogram1
    Histogram2
    Histogram1
    Histogram2
    ROOT Histogram
    ROOT Histogram
    Convert histograms 
    between DMT 
    and ROOT format.
    xsilHistogram - Histogram1
    Histogram2
    Write a histogram in 
    XML format.
    xsilHandlerQueryHistogram
    xsilParser
    vector<Histogram1>
    vector<Histogram2>
    - Read a histogram from 
    XML format.

    Example:

    Histogram1 hsize("Size", 20, 0.0, 20.0, "Amplitude",
                     "Num. Events/Bin");
    eventset.Histogram(hsize, Column("SIZE"));
    TH1D rhsize;
    ConvertHistogram (hsize, rhsize);   // Convert to a ROOT histogram
                                        // Uses from/to signature
    Writing to an XML file:
    Histogram1 h1("Size", 20, 0.0, 20.0, "Amplitude",
                  "Num. Events/Bin");
    eventset.Histogram(h1, Column("SIZE"));
    Histogram2 h2("Size-Duration", 20, 0.0, 20.0, 30, 0.0, 15.0,
                  "Amplitude", "Duration");
    eventset.Histogram(h2, Column("SIZE"), Column("DURATION"));
    ofstream out ("myfile.xml");        // Open file
    out << xsilHeader() << endl;        // Write XML header
    out << xsilHistogram (h1) << endl;  // Write histogram
    out << xsilHistogram (h2) << endl;  // Write another histogram...
    out << xsilTrailer() << endl;       // Write XML footer
    Reading from an XML file:
    vector<Histogram1> vh1;
    vector<Histogram2> vh2;
    xsilHandlerQueryHistogram histQ (vh1, vh2); // Setup handler
    xsilParser parser;                          // XML parser
    parser.AddHandler (histQ);                  // Add histogram handler
    parser.Parse ("myfile.xml");                // Read histograms
    for (vector<Histogram1>::iterator i = vh1.begin();
         i != vh1.end(); ++i) Plot (*i);        // Plot them
    Any number of histograms, time series, frequency series, frequency spectra or other DMT containers can be written to an XML file. Similarly, when reading an XML file each container type has to setup its own callback handler and a list of containters which is filled by the XML parser whenever a corresponding container is read from file.

    Time Series

    TimeSeries method creates a time series of event rate, column values, or values of event function, and store it on a DMT TSeries container. An integrated event rate option is available. Users can filter events by giving event conditions and process column values through the event function.
     
    Table 26: Time Series Method 
    Method Return Arguments Description
    TimeSeries # of events TSeries, time window, integrated, condition Make time series of event rate.
    TimeSeries # of events TSeries, event function, condition Make time series of values of event function.

    Plot function provides a capability of displaying 1 to 8 time series onto a single DMT graphics pad. Users can change plot options through the option pad on the graphics pad.
     
    Table 27: Time Series Plotting Functions 
    Function Return Arguments Description
    Plot TLGMultiPad* TSeries (up to 8 TSeries) Plot time series. 

    Example:

    Create a time series of event rate and plot it on a display.

    TSeries trate;
    trate.setName("Event Rate"); // Name the TSeries.
    eventset.TimeSeries(trate);  // Fill the TSeries with event rate.
    Plot(trate);                 // Plot on a display.
    Make a time series of integrated event rate of SIZE greater than 10.0.
    TSeries trate;
    eventset.TimeSeries(trate, true, Column("SIZE") > 10.0);
    Make a time series of durations of events.
    TSeries tdur;
    eventset.TimeSeries(tdur, Column("DURATION"));
    Set an event function and create time series of the value of the function.
    FunctionPtr func = Column("Amplitude")/Column("StdDev");
    TSeries ts;
    eventset.TimeSeries(ts, func);
    Plot multiple time series on a pad. Plot function requires name for each TSeries.
    TSeries trate;
    TSeries tdur;
    trate.setName("Rate");
    tdur.setName("Duration");
    eventset.TimeSeries(trate, true);
    eventset.TimeSeries(tdur, Column("DURATION"));
    Plot(trate, tdur);


    Advanced Topics

    Root Settings

    Before you start ROOT, make sure if DMTHOME enviroment variable points to your build of gds tree (<path to your gds>/gds).

    If your rootlogon.C in gds/root/macros/ doesn't have lines as following, you need to add them to load required libraries at starting up the ROOT.

    gSystem->Load("/home/mito/gds/lib/libgdsevent.so");
    gSystem->Load("/home/mito/gds/lib/libdttview.so");
    gSystem->Load("/home/mito/gds/lib/libgdsplot.so");
    Compilation

    LD_LIBRARY_PATH contains path to <path to your ROOT >/root/lib and <path to your gds>/gds/lib.
    Event Analysis Tool requires following two libraries to build an executable.

    libgdsevent.so
    libdttview.so
    libgdsplot.so


    Writing your own Conditions and Functions

    Writing your own event conditions or event functions is done by deriving from the Condition or Function classes, respectively, and override the Copy and Evaluate methods. These user defined conditions and functions can then be used in existing algorithms. Example:

    // MyCondition: derive from Condition
    class MyCondition : public events::Condition {
       public:
          // Constructor
          MyCondition (int n) : mN (n) {};
          // Override Copy method; define copy constructor if necessary
          virtual MyCondition* Copy() const {
             return new MyCondition (*this); }
          // Override the Evaluate method
          virtual bool Evaluate (const events::Argument& arg,
                                 bool& val) const;
       private:
          int              mN;
       ...
       };
    // MyFunction: derive from Function
    class MyFunction : public events::Function {
       public:
          // Default constructor
          MyFunction() : mC1 ("Amplitude"), mC2 ("Noise") {}
          // Override Copy method; define copy constructor if necessary
          virtual MyFunction* Copy() const {
             return new MyFunction (*this); }
          // Override the Evaluate method
          virtual bool Evaluate (const events::Argument& arg,
                                 events::Value& val) const;
       private:
          // Define the columns we are want to access
          events::Column   mC1;
          events::Column   mC2;
       ...
       };
    For instance, the newly defined condition can then be used to select events which are added to a histogram using the new function:
    Set s3 ("test.xml");
    Histogram1 h1 ("Test", -1, +1, 200);
    s3.Histogram (h1, MyFunction(), MyCondition(3));
    Before going into the details how to write the Evaluate method we take a quick look at the Argument class which in turn contains a reference to a Window object. The Window class is used to represent a sliding event window. It contains a list of all events within the current time window as well as a list of candidate events. The number of candidate events is equal to the coincidence order. For a simple select algorithm the order is one. The most important methods of the Argument and the Window class are essentially the same:
     
    Table 28: Argument and Window class. 
    Method Return Argument Description
    GetOrder order - Gets the coincidence order
    () event i Returns the i-th candidate event
    Size number - Gets the number of events within the time window 
    include the candidate events if time window includes zero
    [] event n Returns the n-th event within the time window
    Front event - Returns the first event of the time window
    Back event - Returns the last event of the time window
    Begin iterator - Returns an iterator to the begin of the event list
    End iterator - Returns an iterator to the end of the event list
    Empty true/false - Returns true if event list is empty
    Argument only
    GetWindow window - Get the window object
    Window only
    GetTimeFirst time - Get time of first event in list
    GetTimeLast time - Get time of last event in list
    GetTime time - Averaged time of candidate events
    GetStartTime time - Get start time of window
    GetStopTime time - Get end time of window
    SetWindow - time window Set the time window
    GetOffset interval - Get offset of the time window
    GetWidth interval - Get width of the time window

    Here is an example implementation for a condition which makes sure that the number of events within the event window is exactly as specified:

    bool MyCondition::Evaluate (const events::Argument& arg,
                               bool& val) const
    {
       val = (arg.Size() == mN); // Compute the condition
       return true;              // successfully evaluated the condition
    }
    Similarly, one can write an event function computes the rms of the significance over all events within the window.
    bool MyFunction::Evaluate (const events::Argument& arg,
                               Value& val) const
    {
       // Compute the function
       Value sum (0.0);
       for (ConstIterator i = arg.Begin(); i != arg.End(); ++i) {
          Value amp, noise;
          if (!mC1.Get(*i, amp) || !mC2.Get(*i, noise)) {
             return false;  // Getting the column values failed: quit
          }
          sum += pow (amp / noise, Value(2));
       }
       val = sqrt (sum);
       return true;         // successfully evaluated the function
    }