OnlineMonitor.cpp 11.4 KB
Newer Older
Simon Spannagel's avatar
Simon Spannagel committed
1
#include "OnlineMonitor.h"
2
#include <TGButtonGroup.h>
3
#include <TVirtualPadEditor.h>
4
#include <regex>
Daniel Hynds's avatar
Daniel Hynds committed
5

6
using namespace corryvreckan;
7
using namespace std;
8

9
OnlineMonitor::OnlineMonitor(Configuration config, std::vector<std::shared_ptr<Detector>> detectors)
10
    : Module(std::move(config), std::move(detectors)) {
11
    canvasTitle = m_config.get<std::string>("canvasTitle", "Corryvreckan Testbeam Monitor");
12
    updateNumber = m_config.get<int>("update", 200);
13

14
15
    // Set up overview plots:
    canvas_overview = m_config.getMatrix<std::string>("Overview",
16
                                                      {{"Tracking4D/trackChi2"},
Jens Kroeger's avatar
Jens Kroeger committed
17
                                                       {"Clustering4D/%REFERENCE%/clusterTot"},
18
                                                       {"TestAlgorithm/%REFERENCE%/hitmap", "colz"},
19
                                                       {"Tracking4D/%REFERENCE%/residualsX"}});
20

21
22
    // Set up individual plots for the DUT
    canvas_dutplots = m_config.getMatrix<std::string>("DUTPlots",
23
24
25
26
27
28
                                                      {{"EventLoaderCLICpix2/%DUT%/hitMap", "colz"},
                                                       {"EventLoaderCLICpix2/%DUT%/hitMapDiscarded", "colz"},
                                                       {"EventLoaderCLICpix2/%DUT%/pixelToT"},
                                                       {"EventLoaderCLICpix2/%DUT%/pixelToA"},
                                                       {"EventLoaderCLICpix2/%DUT%/pixelCnt", "log"},
                                                       {"EventLoaderCLICpix2/%DUT%/pixelsPerFrame", "log"},
29
30
                                                       {"AnalysisDUT/clusterTotAssociated"},
                                                       {"AnalysisDUT/associatedTracksVersusTime"}});
31
32
33
34
35
36
37
    canvas_tracking = m_config.getMatrix<std::string>("Tracking",
                                                      {{"Tracking4D/trackChi2"},
                                                       {"Tracking4D/trackAngleX"},
                                                       {"Tracking4D/trackAngleY"},
                                                       {"Tracking4D/trackChi2ndof"},
                                                       {"Tracking4D/tracksPerEvent"},
                                                       {"Tracking4D/clustersPerTrack"}});
38
    canvas_hitmaps = m_config.getMatrix<std::string>("HitMaps", {{"TestAlgorithm/%DETECTOR%/hitmap", "colz"}});
39
    canvas_residuals = m_config.getMatrix<std::string>("Residuals", {{"Tracking4D/%DETECTOR%/residualsX"}});
40

41
    canvas_cx = m_config.getMatrix<std::string>("CorrelationX", {{"TestAlgorithm/%DETECTOR%/correlationX"}});
42
    canvas_cx2d =
43
44
        m_config.getMatrix<std::string>("CorrelationX2D", {{"TestAlgorithm/%DETECTOR%/correlationX_2Dlocal", "colz"}});
    canvas_cy = m_config.getMatrix<std::string>("CorrelationY", {{"TestAlgorithm/%DETECTOR%/correlationY"}});
45
    canvas_cy2d =
46
        m_config.getMatrix<std::string>("CorrelationY2D", {{"TestAlgorithm/%DETECTOR%/correlationY_2Dlocal", "colz"}});
47

48
    canvas_charge = m_config.getMatrix<std::string>("ChargeDistributions", {{"Clustering4D/%DETECTOR%/clusterTot"}});
49

50
    canvas_time = m_config.getMatrix<std::string>("EventTimes", {{"TestAlgorithm/%DETECTOR%/eventTimes"}});
Daniel Hynds's avatar
Daniel Hynds committed
51
52
}

53
void OnlineMonitor::initialise() {
Simon Spannagel's avatar
Simon Spannagel committed
54
55

    // TApplication keeps the canvases persistent
56
    app = new TApplication("example", nullptr, nullptr);
Simon Spannagel's avatar
Simon Spannagel committed
57
58
59
60
61

    // Make the GUI
    gui = new GuiDisplay();

    // Make the main window object and set the attributes
62
63
64
    gui->m_mainFrame = new TGMainFrame(gClient->GetRoot(), 1200, 600);
    gui->buttonMenu = new TGHorizontalFrame(gui->m_mainFrame, 1200, 50);
    gui->canvas = new TRootEmbeddedCanvas("canvas", gui->m_mainFrame, 1200, 600);
Simon Spannagel's avatar
Simon Spannagel committed
65
66
67
68
69
    gui->m_mainFrame->AddFrame(gui->canvas, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 10, 10, 10, 10));
    gui->m_mainFrame->SetCleanup(kDeepCleanup);
    gui->m_mainFrame->DontCallClose();

    // Add canvases and histograms
70
71
72
73
    AddCanvasGroup("Tracking");
    AddCanvas("Overview", "Tracking", canvas_overview);
    AddCanvas("Tracking Performance", "Tracking", canvas_tracking);
    AddCanvas("Residuals", "Tracking", canvas_residuals);
Simon Spannagel's avatar
Simon Spannagel committed
74

75
76
77
78
79
80
81
82
83
84
85
86
87
88
    AddCanvasGroup("Detectors");
    AddCanvas("Hitmaps", "Detectors", canvas_hitmaps);
    AddCanvas("Event Times", "Detectors", canvas_time);
    AddCanvas("Charge Distributions", "Detectors", canvas_charge);

    AddCanvasGroup("Correlations 1D");
    AddCanvas("1D X", "Correlations 1D", canvas_cx);
    AddCanvas("1D Y", "Correlations 1D", canvas_cy);

    AddCanvasGroup("Correlations 2D");
    AddCanvas("2D X", "Correlations 2D", canvas_cx2d);
    AddCanvas("2D Y", "Correlations 2D", canvas_cy2d);

    AddCanvasGroup("DUTs");
89
90
    for(auto& detector : get_detectors()) {
        if(detector->isDUT()) {
91
            AddCanvas(detector->name(), "DUTs", canvas_dutplots, detector->name());
92
93
        }
    }
94

Simon Spannagel's avatar
Simon Spannagel committed
95
    // Set up the main frame before drawing
96
97
98
99
100
101
102
103
104
105
    AddCanvasGroup("Controls");
    ULong_t color;

    // Pause button
    gClient->GetColorByName("green", color);
    gui->buttons["pause"] = new TGTextButton(gui->buttonGroups["Controls"], "   &Pause Monitoring   ");
    gui->buttons["pause"]->ChangeBackground(color);
    gui->buttons["pause"]->Connect("Pressed()", "corryvreckan::GuiDisplay", gui, "TogglePause()");
    gui->buttonGroups["Controls"]->AddFrame(gui->buttons["pause"], new TGLayoutHints(kLHintsTop | kLHintsExpandX));

Simon Spannagel's avatar
Simon Spannagel committed
106
    // Exit button
107
108
109
110
111
    gClient->GetColorByName("yellow", color);
    gui->buttons["exit"] = new TGTextButton(gui->buttonGroups["Controls"], "&Exit Monitor");
    gui->buttons["exit"]->ChangeBackground(color);
    gui->buttons["exit"]->Connect("Pressed()", "corryvreckan::GuiDisplay", gui, "Exit()");
    gui->buttonGroups["Controls"]->AddFrame(gui->buttons["exit"], new TGLayoutHints(kLHintsTop | kLHintsExpandX));
Simon Spannagel's avatar
Simon Spannagel committed
112
113
114

    // Main frame resizing
    gui->m_mainFrame->AddFrame(gui->buttonMenu, new TGLayoutHints(kLHintsLeft, 10, 10, 10, 10));
115
    gui->m_mainFrame->SetWindowName(canvasTitle.c_str());
Simon Spannagel's avatar
Simon Spannagel committed
116
117
118
119
120
121
122
123
    gui->m_mainFrame->MapSubwindows();
    gui->m_mainFrame->Resize(gui->m_mainFrame->GetDefaultSize());

    // Draw the main frame
    gui->m_mainFrame->MapWindow();

    // Plot the overview tab (if it exists)
    if(gui->histograms["OverviewCanvas"].size() != 0) {
124
        gui->Display(const_cast<char*>(std::string("OverviewCanvas").c_str()));
Simon Spannagel's avatar
Simon Spannagel committed
125
126
    }

127
128
129
130
    gui->canvas->GetCanvas()->Paint();
    gui->canvas->GetCanvas()->Update();
    gSystem->ProcessEvents();

Simon Spannagel's avatar
Simon Spannagel committed
131
132
    // Initialise member variables
    eventNumber = 0;
Daniel Hynds's avatar
Daniel Hynds committed
133
134
}

135
StatusCode OnlineMonitor::run(std::shared_ptr<Clipboard>) {
136

137
138
139
140
141
    if(!gui->isPaused()) {
        // Draw all histograms
        if(eventNumber % updateNumber == 0) {
            gui->Update();
        }
Simon Spannagel's avatar
Simon Spannagel committed
142
143
    }
    gSystem->ProcessEvents();
144

145
    // Increase the event number
Simon Spannagel's avatar
Simon Spannagel committed
146
    eventNumber++;
147
    return StatusCode::Success;
Daniel Hynds's avatar
Daniel Hynds committed
148
149
}

150
151
152
153
154
155
156
157
158
159
void OnlineMonitor::AddCanvasGroup(std::string group_title) {
    gui->buttonGroups[group_title] = new TGVButtonGroup(gui->buttonMenu, group_title.c_str());
    gui->buttonMenu->AddFrame(gui->buttonGroups[group_title], new TGLayoutHints(kLHintsLeft | kLHintsTop, 10, 10, 10, 10));
    gui->buttonGroups[group_title]->Show();
}

void OnlineMonitor::AddCanvas(std::string canvas_title,
                              std::string canvasGroup,
                              Matrix<std::string> canvas_plots,
                              std::string detector_name) {
160
161
    std::string canvas_name = canvas_title + "Canvas";

162
163
164
165
166
167
168
169
170
    if(canvasGroup.empty()) {
        gui->buttons[canvas_title] = new TGTextButton(gui->buttonMenu, canvas_title.c_str());
        gui->buttonMenu->AddFrame(gui->buttons[canvas_title], new TGLayoutHints(kLHintsLeft, 10, 10, 10, 10));
    } else {
        gui->buttons[canvas_title] = new TGTextButton(gui->buttonGroups[canvasGroup], canvas_title.c_str());
        gui->buttonGroups[canvasGroup]->AddFrame(gui->buttons[canvas_title],
                                                 new TGLayoutHints(kLHintsTop | kLHintsExpandX, 0, 0, 0, 0));
    }

171
172
173
174
    string command = "Display(=\"" + canvas_name + "\")";
    LOG(INFO) << "Connecting button with command " << command.c_str();
    gui->buttons[canvas_title]->Connect("Pressed()", "corryvreckan::GuiDisplay", gui, command.c_str());

175
    AddPlots(canvas_name, canvas_plots, detector_name);
176
177
}

178
void OnlineMonitor::AddPlots(std::string canvas_name, Matrix<std::string> canvas_plots, std::string detector_name) {
179
    for(auto plot : canvas_plots) {
180
181
182

        // Add default plotting style if not set:
        plot.resize(2, "");
183
184
185
186

        // Do we need to plot with a LogY scale?
        bool log_scale = (plot.back().find("log") != std::string::npos) ? true : false;

187
        // Replace reference placeholders and add histogram
188
        std::string name = std::regex_replace(plot.front(), std::regex("%REFERENCE%"), get_reference()->name());
189
190
191
192

        // Parse other placeholders:
        if(name.find("%DUT%") != std::string::npos) {
            // Do we have a DUT placeholder?
193
194
195
            if(!detector_name.empty()) {
                LOG(DEBUG) << "Adding plot " << name << " for detector " << detector_name;
                auto detector = get_detector(detector_name);
196
197
                AddHisto(
                    canvas_name, std::regex_replace(name, std::regex("%DUT%"), detector->name()), plot.back(), log_scale);
198
199
200
201
202
203
204
205
206
207
208
209

            } else {
                LOG(DEBUG) << "Adding plot " << name << " for all DUTs.";
                for(auto& detector : get_detectors()) {
                    if(!detector->isDUT()) {
                        continue;
                    }
                    AddHisto(canvas_name,
                             std::regex_replace(name, std::regex("%DUT%"), detector->name()),
                             plot.back(),
                             log_scale);
                }
210
211
212
            }
        } else if(name.find("%DETECTOR%") != std::string::npos) {
            // Do we have a detector placeholder?
213
214
215
            if(!detector_name.empty()) {
                LOG(DEBUG) << "Adding plot " << name << " for detector " << detector_name;
                auto detector = get_detector(detector_name);
216
                AddHisto(canvas_name,
217
                         std::regex_replace(name, std::regex("%DETECTOR%"), detector->name()),
218
219
                         plot.back(),
                         log_scale);
220
221
222
223
224
225
226
227
            } else {
                LOG(DEBUG) << "Adding plot " << name << " for all detectors.";
                for(auto& detector : get_detectors()) {
                    AddHisto(canvas_name,
                             std::regex_replace(name, std::regex("%DETECTOR%"), detector->name()),
                             plot.back(),
                             log_scale);
                }
228
229
230
            }
        } else {
            // Single histogram only.
231
            AddHisto(canvas_name, name, plot.back(), log_scale);
232
233
234
235
        }
    }
}

236
void OnlineMonitor::AddHisto(string canvasName, string histoName, string style, bool logy) {
Daniel Hynds's avatar
Daniel Hynds committed
237

238
239
    // Add root directory to path:
    histoName = "/" + histoName;
240

241
    TH1* histogram = static_cast<TH1*>(gDirectory->Get(histoName.c_str()));
Simon Spannagel's avatar
Simon Spannagel committed
242
    if(histogram) {
243
        gui->histograms[canvasName].push_back(static_cast<TH1*>(gDirectory->Get(histoName.c_str())));
244
        gui->logarithmic[gui->histograms[canvasName].back()] = logy;
Simon Spannagel's avatar
Simon Spannagel committed
245
        gui->styles[gui->histograms[canvasName].back()] = style;
Simon Spannagel's avatar
Simon Spannagel committed
246
247
248
    } else {
        LOG(WARNING) << "Histogram " << histoName << " does not exist";
    }
Daniel Hynds's avatar
Daniel Hynds committed
249
}