Triggers
The Triggers package contains many practical tools to manipulate triggers. Triggers are stored in a ROOT TTree structure and follow the GWOLLUM convention for triggers. Triggers can be read, written, plotted, clustered, monitored and so on... The Triggers package is organized around several C++ classes depending on the use of the triggers:
These classes have a lot to offer when you want to browse through millions of triggers. All the functions described in this page can be accessed through the "libTriggers.so" shared library. Index: |
||
A trigger object is composed of 2 TTree structures (+1 optional meta-data TTree). The first one, named 'triggers', is defined as a Ntuple of 10 variables: time = central GPS time of the event [s] frequency = central frequency of the event [Hz] tstart = starting GPS time of the event [s] tend = ending GPS time of the event [s] fstart = starting frequency of the event [Hz] fend = ending frequency of the event [Hz] snr = SNR of the event amplitude = Amplitude of the event [Hz^-½] phase = Phase of the event [rad] q = Q of the event These variable names are hard-coded and cannot be changed; they were designed to fulfill the requirements of Omicron. However, some variables could be used for other purposes and should be seen as data containers. The second TTree structure of the trigger object is named 'segments'. It has 2 variables: 'start' and 'end' and this TTree stores all the time segments in which the triggers were produced. A full description of a trigger object is given in the GWOLLUM convention |
||
Triggers saved in a ROOT file can be easily browsed with internal ROOT routines. In particular, the Scan function can be used to print triggers. Here is an example: > root ./your_trigger_file.root root [0] _file0.ls() TFile** h_4096Hz/h_4096Hz_946415250_84898.root TFile* h_4096Hz/h_4096Hz_946415250_84898.root KEY: TTree triggers;1 triggers KEY: TTree segments;1 segments root [1] triggers->Scan("time:frequency:snr","","colsize=15") ****************************************************************** * Row * time * frequency * snr * ****************************************************************** * 0 * 931157661.28125 * 165.296875 * 5.8337056346755 * * 1 * 931157661.53125 * 166.96875 * 6.3734146529559 * * 2 * 931157661.75 * 210.140625 * 10.925183366289 * ****************************************************************** root [2] root [2] triggers->Scan("time:frequency:snr","snr>10","colsize=15") ****************************************************************** * Row * time * frequency * snr * ****************************************************************** * 2 * 931157661.75 * 210.140625 * 10.925183366289 * ****************************************************************** The first command of this example (root [0]) is a 'ls' command to see what is contained in the ROOT file. We see the presence of a TTree called 'triggers' which we want to explore. Then (root [1]), we use the 'Scan' command to list the triggers in 3 columns (+row): "time:frequency:snr". We see that this TTree contains 3 triggers. The last command (root [2]) shows that it is possible to only print a selection of triggers. Here we picked "snr>10" Many other ROOT operations are available on a TTree. An extensive list of all the functions can be found on the TTree documention page |
||
Triggers are saved in a TTree and in ROOT files via the MakeTriggers C++ class. The principle is very simple; it starts with a constructor: MakeTriggers *YourTriggers = new MakeTriggers(const string aoutdir, const string aoutfile); where you need to provide the path to the output directory and a file name. Then you can start to add triggers: YourTriggers->AddTrigger (const double atime, const double afrequency, const double asnr, const double aq, const double atstart, const double atend, const double afstart, const double afend, const double aamp, const double aphase); At some point you need to save all the triggers in a file: YourTriggers->Write() The AddTrigger() and Write() functions can be used many time to optimize your output. |
||
Triggers can be directly accessed with ROOT functions as explained in Simple browsing. Triggers can also be read via the ReadTriggers C++ class which offers specific actions. Triggers can be found in a single file or in a collection of files. The principle is very simple; it starts with a constructor: ReadTriggers *YourTriggers = new ReadTriggers(const string apattern); where you need to provide a file pattern (for example "/path/to/my/root/files_*.root"). Then you can access the triggers via many basic functions: int GetNTrig (void); // get number of triggers double GetTriggerTime (const int atrig); // get trigger central time double GetTriggerFrequency(const int atrig); // get trigger central frequency double GetTriggerDuration (const int atrig); // get trigger duration double GetTriggerBandWidth(const int atrig); // get trigger bandwidth double GetTriggerQ (const int atrig); // get trigger Q double GetTriggerSNR (const int atrig); // get trigger SNR |
||
Triggers are often saved in text files with multiple columns. A trigger is represented as a line and each column gives a trigger characteristic (frequency, snr...). The GWOLLUM package offers many tools to process triggers and all these tools are based on the ROOT format with the GWOLLUM convention (see What is a trigger?). There is an easy way to convert any text files in root files with the GWOLLUM format thanks to the 'TxtToTriggers.exe' tool. Let's take an example Let's see what is in the current directory: > ls test1.txt test2.txt These are the 2 test files we want to convert. These files contain 3 columns: time, frequency and SNR. The other variables are not provided. The conversion command is the following: > TxtToTriggers.exe "./test*.txt" "mytriggers" "1;3;2;-1;-1;-1;-1;-1" The first argument means that all the test files will be read. The second argument means that the output files will be named 'mytriggers'. The last argument indicates where to find the trigger characteristics. 8 variables are expected in the following order: time, SNR, frequency, tstart, tend, fstart, fend and Q. -1 is given if the variable is missing. In this example our 2 test files verify: time = column #1 SNR = column #3 frequency = column #2 duration = not provided bandwidth = not provided Q = not provided After the code has been used, 2 root files have been created with the triggers: > ls mytriggers_968579064_22.root mytriggers_969649841_9.root test1.txt test2.txt |
||
A basic time-clustering algorithm is implemented in the ReadTriggers C++ class. Triggers are clustered in time if their central times are contained within a ΔT window (the trigger duration is also taken into account). For example the clustering with a 100ms time window can be performed with the following list of commands: ReadTriggers *YourTriggers = new ReadTriggers(const string apattern); YourTriggers->SetClusterizeDeltaT(0.1);// clusterization within 100ms YourTriggers->Clusterize(); NB: the clustering is always performed on the fly. Then you can access the clusters via many basic functions: int GetNCluster (void); // get number of clusters double GetClusterTime (const int aclst); // get cluster central time double GetClusterFrequency(const int aclst); // get cluster central frequency double GetClusterSNR (const int aclst); // get cluster SNR int GetClusterSize (const int aclst); // get cluster size More information, see ReadTriggers |
||
Triggers can be plotted via the TriggerPlot C++ class which offers many plotting options. The TriggerPlot class inherits from the ReadTriggers class. The principle is very simple; it starts with a constructor: TriggerPlot *YourTriggers = new TriggerPlot(const int aNcoll, const string apattern); The TriggerPlot class offers many types of plots, defined by a keyword: keyword: plot: "RATE" trigger rate as a function of time "FREQ" trigger frequency distribution "SNR" trigger SNR distribution "FREQTIME" frequency vs. time distribution "SNRFREQ" SNR vs. frequency distribution "SNRTIME" SNR vs. time distribution The TriggerPlot object is composed of up to 10 plots for each keyword. A different trigger selection can be applied for each plot. Then the plots can be superimposed. Such combinations offer quasi-unlimited plotting possibilities. Let's give some examples. -- Single plot -- root [0] gSystem->Load("libTriggers.so");// load Triggers library root [1] TriggerPlot *T = new TriggerPlot(1, "./*.root");// construct the TriggerPlot class root [2] T->PrintPlot(0, "SNR");// SNR distribution After loading the trigger files, the plot #1 is filled with the trigger distribution (keyword="SNR"). Here is what you get: -- Superimposition -- root [0] gSystem->Load("libTriggers.so");// load Triggers library root [1] TriggerPlot *T = new TriggerPlot(3, "./*.root");// construct the TriggerPlot class root [2] T->GetCollectionSelection(1)->SetSNRMin(10) // SNR>10 root [3] T->GetCollectionSelection(2)->SetSNRMin(20) // SNR>20 root [4] T->PrintCollectionPlot("RATE") // plot rates In this example, a SNR selection is performed and assigned to different plots: all SNR (blue), SNR>10 (green) and SNR>20 (red). Here is what you get: -- Glitchgram -- root [0] gSystem->Load("libTriggers.so");// load Triggers library root [1] TriggerPlot *T = new TriggerPlot(4, "./*.root");// construct the TriggerPlot class root [2] T->Clusterize() // we want to use clusters not individual triggers root [3] T->SetCollectionUseClusters(0,1) // use clusters root [4] T->SetCollectionUseClusters(1,1) // use clusters root [5] T->SetCollectionUseClusters(2,1) // use clusters root [6] T->SetCollectionUseClusters(3,1) // use clusters root [7] T->GetCollectionSelection(1)->SetSNRMin(8) // SNR>8 root [8] T->GetCollectionSelection(2)->SetSNRMin(10) // SNR>10 root [9] T->GetCollectionSelection(3)->SetSNRMin(20) // SNR>20 root [10] T->PrintCollectionPlot("FREQTIME") // plot rates [2]: triggers are first clusterized. [3,4,5,6]: we explicitely indicate we want to plot clusters, not individual triggers. [7,8,9,10]: we apply 4 different SNR thresholds. [11]: we produce the plot. Here is what you get: |
||
The C++ class EventMap was designed to plot trigger time-frequency maps. It inherits from the ReadTriggers class and many new functions are available. We give here a few examples. -- Basic event map -- root [0] gSystem->Load("libTriggers.so");// load Triggers library root [1] EventMap *E = new EventMap("./*.root");// construct the EventMap class root [2] E->BuildMap(0,940838414.069);// build event map #0 centered at GPS=940838414.069 root [3] E->PrintMap(0);// print map #0 After loading the trigger files, the map #0 is filled with triggers around GPS=940838414.069. Then the PrintMap command displays the map. Here is what you get: -- Map parameters -- bool SetMapResolution(const int mapindex, const int TimeRes, const int FreqRes); bool SetMapFrequencyRange(const int mapindex, const double FreqMin, const double FreqMax); bool SetMapTimeRange(const int mapindex, const double TimeRange); For example, the time range can be adjusted: root [0] gSystem->Load("libTriggers.so");// load Triggers library root [1] EventMap *E = new EventMap("./*.root");// construct the EventMap class root [2] E->SetMapTimeRange(0,40);// set a 40s time range root [3] E->BuildMap(0,940838414.069);// build event map #0 centered at GPS=940838414.069 root [4] E->PrintMap(0);// print map #0 This list of commands is the same as before except we set a time range of 40s. With such a time scale, one can see all the detector glitches around the inspiral signal. Here is what you get: -- Cluster Map -- root [0] gSystem->Load("libTriggers.so");// load Triggers library root [1] EventMap *E = new EventMap("./*.root");// construct the EventMap class root [2] E->Clusterize();// clusterize triggers root [3] E->SetMapTimeRange(0,40);// set a 40s time range root [4] E->BuildClusterMap(0,309);// build event map #0 with cluster #309 root [5] E->PrintMap(0);// print map #0 After loading the trigger files, triggers are clusterized in time. Map #0 is scaled to 40s. Then Map#0 is filled with cluster #309 (our inspiral signal) and printed. Here is what you get: It is also possible to plot all the clusters in order to compare them: root [0] gSystem->Load("libTriggers.so");// load Triggers library root [1] EventMap *E = new EventMap("./*.root","",2);// construct the EventMap class root [2] E->Clusterize();// clusterize triggers root [3] E->DisplayClusterMaps(0, 940838400, 940838440,1);// print cluster maps with 1sec between each frame This list of commands is the same as before except that, instead of printing a single map, we ask to display all the clusters between 940838400 and 940838440. Here is what you get: -- Live Map -- root [0] gSystem->Load("libTriggers.so");// load Triggers library root [1] EventMap *E = new EventMap("./*.root");// construct the EventMap class root [2] E->SetMapTimeRange(0,10); // set a 10s time range root [3] E->LiveMap(0,940838400, 940838440); // build live map |
||
|