REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestRealTimeDrawingProcess.cxx
1/*************************************************************************
2 * This file is part of the REST software framework. *
3 * *
4 * Copyright (C) 2016 GIFNA/TREX (University of Zaragoza) *
5 * For more information see http://gifna.unizar.es/trex *
6 * *
7 * REST is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, either version 3 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * REST is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have a copy of the GNU General Public License along with *
18 * REST in $REST_PATH/LICENSE. *
19 * If not, see http://www.gnu.org/licenses/. *
20 * For the list of contributors see $REST_PATH/CREDITS. *
21 *************************************************************************/
22
82#include "TRestRealTimeDrawingProcess.h"
83
84#include "TRestMessenger.h"
85
86#ifdef __APPLE__
87#include <unistd.h>
88#endif
89
90using namespace std;
91
93
95map<TRestRealTimeDrawingProcess*, bool> TRestRealTimeDrawingProcess::fPauseResponse;
98vector<TRestAnalysisPlot*> TRestRealTimeDrawingProcess::fPlots;
99
104
109
115 fDrawInterval = 0;
117 fPlots.clear();
118 fLastDrawnEntry = 0;
119 fPauseResponse[this] = false;
120 fPauseInvoke = false;
121}
122
128 // For example, try to initialize a pointer to existing metadata
129 // accessible from TRestRun
130
131 if (fPlots.size() == 0) {
132 TiXmlElement* ele = GetElement("TRestAnalysisPlot");
133 while (ele != nullptr) {
135 plt->SetHostmgr(this->fHostmgr);
137 plt->SetName(plt->GetName() +
138 (TString)ToString(this)); // to prevent deleting canvas with same name
139 fPlots.push_back(plt);
140
141 ele = GetNextElement(ele);
142 }
143 }
144
145 if (fProcessesToDraw.size() == 0) {
146 TiXmlElement* ele = GetElement("ProcessDrawing");
147 while (ele != nullptr) {
148 string proc = GetParameter("processName", ele);
149 if (GetFriendLive(proc) == nullptr) {
150 RESTError << "TRestRealTimeDrawingProcess: cannot find process \"" << proc
151 << "\" to call drawing!" << RESTendl;
152 exit(1);
153 }
154 fProcessesToDraw.push_back(proc);
155
156 ele = GetNextElement(ele);
157 }
158 }
159}
160
165 fEvent = inputEvent;
166 if (fDrawInterval == 0) {
167 return fEvent;
168 }
169 if (GetFullAnalysisTree() == nullptr) {
170 return fEvent;
171 }
172
173 // check the pause flag from other thread's TRestRealTimeDrawingProcess
174 // need to pause during drawing, to avoid writing to AnalysisTree
175 while (fPauseInvoke == true) {
176 fPauseResponse[this] = true;
177 usleep(1000); // sleep 1 ms
178 }
179 fPauseResponse[this] = false;
180
181 if (GetFullAnalysisTree()->GetEntries() >= fDrawInterval + fLastDrawnEntry) {
182 fPauseInvoke = true;
183
184 RESTInfo << "TRestRealTimeDrawingProcess: reached drawing flag. Waiting for other processes to pause"
185 << RESTendl;
186 // wait while all other TRestRealTimeDrawingProcess is paused
187 for (auto iter = fPauseResponse.begin(); iter != fPauseResponse.end(); iter++) {
188 if (iter->first == this) continue;
189 int i = 0;
190 while (iter->second == false) {
191 usleep(1000); // sleep 1 ms
192 i++;
193 if (i > fThreadWaitTimeoutMs) {
194 // to prevent last event in the process chain
195 RESTWarning
196 << "TRestRealTimeDrawingProcess: waiting time reaches maximum, plotting job aborted"
197 << RESTendl;
198 fPauseInvoke = false;
199 return fEvent;
200 }
201 }
202 }
203
204 // starts drawing
205 RESTInfo << "TRestRealTimeDrawingProcess: drawing..." << RESTendl;
206 DrawOnce();
207
208 fLastDrawnEntry = GetFullAnalysisTree()->GetEntries();
209 fPauseInvoke = false;
210 }
211
212 return fEvent;
213}
214
219 if (fPauseInvoke == false) {
220 RESTInfo << "TRestRealTimeDrawingProcess: end drawing..." << RESTendl;
221 DrawOnce();
222
223 fPauseInvoke = true;
224 }
225}
226
227void TRestRealTimeDrawingProcess::DrawOnce() {
228 Long64_t totalentries = GetFullAnalysisTree()->GetEntries();
229 for (unsigned int i = 0; i < fPlots.size(); i++) {
230 fPlots[i]->SetTreeEntryRange(totalentries - fLastDrawnEntry, fLastDrawnEntry);
231 fPlots[i]->PlotCombinedCanvas();
232 }
233 for (unsigned int i = 0; i < fProcessesToDraw.size(); i++) {
234 GetFriendLive(fProcessesToDraw[i])->Draw();
235 }
236}
237
239 auto messager = GetMetadata<TRestMessenger>();
240 int runNumber = StringToInteger(GetParameter("runNumber"));
241 if (runNumber == -1) {
242 RESTError << "TRestRealTimeDrawingProcess::DrawWithNotification: runNumber must be given!"
243 << RESTendl;
244 RESTError << "consider adding \"--d xx\" in restManager command" << RESTendl;
245 abort();
246 }
247 while (true) {
248 // consmue the message, take out from the message pool
249 string message = messager->ConsumeMessage();
250 if (message != "") {
251 RESTInfo << "Recieveing message: " << message << RESTendl;
252 if (TRestTools::fileExists(message) && TRestTools::isRootFile(message)) {
253 TRestRun* run = new TRestRun(message);
254 int _runNumber = run->GetRunNumber();
255 delete run;
256 if (_runNumber == runNumber) {
257 for (auto& plot : fPlots) {
258 plot->SetFile(message);
259 plot->PlotCombinedCanvas();
260 }
261 } else {
262 // if the runnumber does not match, we put this message back to pool
263 // maybe other processes need it
264 RESTWarning << "file: " << message << RESTendl;
265 RESTWarning << "It is not the file we wanted! runNumber in file: " << _runNumber
266 << ", run we are processing: " << runNumber << RESTendl;
267 messager->SendMessage(message);
268 }
269 }
270 }
271 usleep(1000);
272 }
273}
274
281
282 RESTMetadata << "Number of AnalysisPlots added: " << fPlots.size() << RESTendl;
283 for (auto p : fPlots) {
284 RESTMetadata << p->GetName();
285 }
286 RESTMetadata << RESTendl;
287 RESTMetadata << "Number of process plots added: " << fProcessesToDraw.size() << RESTendl;
288 for (auto p : fProcessesToDraw) {
289 RESTMetadata << p;
290 }
291 RESTMetadata << RESTendl;
292 RESTMetadata << "Draw interval" << fDrawInterval << RESTendl;
293 RESTMetadata << "Waiting time for other thread to stop " << fThreadWaitTimeoutMs << RESTendl;
294
295 EndPrintProcess();
296}
void BeginPrintProcess()
[name, cut range]
A base class for any REST event.
Definition: TRestEvent.h:38
std::map< std::string, std::string > fVariables
Saving a list of rml variables. name-value std::pair.
endl_t RESTendl
Termination flag object for TRestStringOutput.
TiXmlElement * GetElement(std::string eleDeclare, TiXmlElement *e=nullptr)
Get an xml element from a given parent element, according to its declaration.
TiXmlElement * fElementGlobal
Saving the global element, to be passed to the resident class, if necessary.
void SetHostmgr(TRestManager *m)
Set the host manager for this class.
Int_t LoadConfigFromElement(TiXmlElement *eSectional, TiXmlElement *eGlobal, std::map< std::string, std::string > envs={})
Main starter method.
TRestManager * fHostmgr
All metadata classes can be initialized and managed by TRestManager.
TiXmlElement * GetNextElement(TiXmlElement *e)
Get the next sibling xml element of this element, with same eleDeclare.
std::string GetParameter(std::string parName, TiXmlElement *e, TString defaultValue=PARAMETER_NOT_FOUND_STR)
Returns the value for the parameter named parName in the given section.
static Long64_t fLastDrawnEntry
Last drawn entry of analysis tree.
static std::vector< TRestAnalysisPlot * > fPlots
TRestAnalysisPlot object called for drawing.
static std::map< TRestRealTimeDrawingProcess *, bool > fPauseResponse
Pause response flag from other threads when recieving pause signal.
TRestEvent * fEvent
The event pointer is not used in this process.
static std::vector< std::string > fProcessesToDraw
TRestAnalysisPlot object called for drawing.
void EndProcess() override
Function to use when all events have been processed.
void DrawWithNotification()
Returns a new instance of this class.
Int_t fThreadWaitTimeoutMs
How many events passed when it starts next drawing.
void PrintMetadata() override
It prints out the process parameters stored in the metadata structure.
void InitProcess() override
Function to use in initialization of process members before starting to process the event.
TRestRealTimeDrawingProcess()
Default constructor.
void Initialize() override
Function to initialize input/output event members and define the section name and library version.
int fDrawInterval
How many events passed when it starts next drawing.
TRestEvent * ProcessEvent(TRestEvent *inputEvent) override
The main processing event function.
static bool fPauseInvoke
Pause signal send for other threads when start drawing.
Data provider and manager in REST.
Definition: TRestRun.h:18
static bool fileExists(const std::string &filename)
Returns true if the file (or directory) with path filename exists.
Definition: TRestTools.cxx:728
static bool isRootFile(const std::string &filename)
Returns true if the filename has *.root* extension.
Definition: TRestTools.cxx:733
Int_t StringToInteger(std::string in)
Gets an integer from a string.