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 
90 using namespace std;
91 
93 
95 map<TRestRealTimeDrawingProcess*, bool> TRestRealTimeDrawingProcess::fPauseResponse;
98 vector<TRestAnalysisPlot*> TRestRealTimeDrawingProcess::fPlots;
99 
104 
109 
115  fDrawInterval = 0;
116  fThreadWaitTimeoutMs = 1000;
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);
136  plt->LoadConfigFromElement(ele, fElementGlobal, fVariables);
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 
227 void 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 
280  BeginPrintProcess();
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 }
A base class for any REST event.
Definition: TRestEvent.h:38
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.
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.
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.
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.
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.