otsdaq-utilities  3.05.00
VisualSupervisor.cc
1 #include "otsdaq-utilities/Visualization/VisualSupervisor.h"
2 #include "otsdaq/DataManager/DataManagerSingleton.h"
3 #include "otsdaq/Macros/BinaryStringMacros.h"
4 #include "otsdaq/RootUtilities/VisualDataManager.h"
5 #include "otsdaq/XmlUtilities/XmlDocument.h"
6 // #include "otsdaq/otsdaq/Macros/MessageTools.h"
7 #include <boost/regex.hpp>
8 #include "otsdaq/DataManager/DQMHistosConsumerBase.h"
9 #include "otsdaq/Macros/MessageTools.h"
10 #include "otsdaq/RootUtilities/RootFileExplorer.h"
11 
15 #include <TBranchElement.h>
16 #include <TBuffer.h>
17 #include <TBufferJSON.h>
18 #include <TCanvas.h>
19 #include <TClass.h>
20 #include <TDirectory.h>
21 #include <TFile.h>
22 #include <TH1.h>
23 #include <TH2.h>
24 #include <TIterator.h>
25 #include <TKey.h>
26 #include <TProfile.h>
27 #include <TROOT.h>
28 #include <TRegexp.h>
29 #include <TString.h>
30 #include <TTree.h>
31 #include "TBufferFile.h"
32 #include "TObject.h"
33 
34 #include <dirent.h> /*DIR and dirent*/
35 #include <sys/stat.h> /*mkdir*/
36 
37 #include <xdaq/NamespaceURI.h>
38 
39 #include <fstream>
40 #include <iostream>
41 #include <map>
42 #include <mutex>
43 
44 // #include <chrono>
45 // #include <thread>
46 
47 #define ROOT_BROWSER_PATH __ENV__("ROOT_BROWSER_PATH")
48 #define ROOT_DISPLAY_CONFIG_PATH __ENV__("ROOT_DISPLAY_CONFIG_PATH")
49 
50 #define LIVEDQM_DIR std::string("LIVE_DQM")
51 #define PRE_MADE_ROOT_CFG_DIR std::string("Pre-made Views")
52 
53 #define PRE_MADE_ROOT_CFG_FILE_EXT std::string(".rcfg")
54 
55 #define PREFERENCES_PATH std::string(__ENV__("SERVICE_DATA_PATH")) + "/VisualizerData/"
56 #define PREFERENCES_FILE_EXT ".pref"
57 
58 #define ROOT_VIEWER_PERMISSIONS_THRESHOLD 100
59 
60 using namespace ots;
61 
62 #undef __MF_SUBJECT__
63 #define __MF_SUBJECT__ "Visualizer"
64 
65 XDAQ_INSTANTIATOR_IMPL(VisualSupervisor)
66 
67 #undef STDLINE
68 #define STDLINE(X, Y) __COUT__ << X
69 
70 //==============================================================================
71 VisualSupervisor::VisualSupervisor(xdaq::ApplicationStub* stub)
72  : CoreSupervisorBase(stub), theDataManager_(nullptr), loadedRunNumber_(-1)
73 {
74  __SUP_COUT__ << "Constructor." << __E__;
75  INIT_MF("VisualSupervisor");
76 
77  mkdir(((std::string)PREFERENCES_PATH).c_str(), 0755);
78  ROOT::EnableThreadSafety();
79 
80  __SUP_COUT__ << "Constructed." << __E__;
81 } // end constructor
82 
83 //========================================================================================================================
84 VisualSupervisor::~VisualSupervisor(void)
85 {
86  __SUP_COUT__ << "Destructor." << __E__;
87  destroy();
88  __SUP_COUT__ << "Destructed." << __E__;
89 } // end destructor
90 
91 //========================================================================================================================
92 void VisualSupervisor::destroy(void)
93 {
94  __SUP_COUT__ << "Destroying..." << __E__;
95 
96  DataManagerSingleton::deleteInstance(CorePropertySupervisorBase::getSupervisorUID());
97  if(theStateMachineImplementation_.size() > 1)
98  {
99  __SS__ << "Not expecting more than one visual data manager!" << __E__;
100  __SS_THROW__;
101  }
102  if(theStateMachineImplementation_.size())
103  theStateMachineImplementation_.pop_back();
104  else
105  __COUT_WARN__ << "No visual data manager was pushed." << __E__;
106 } // end destroy()
107 
108 //==============================================================================
109 void VisualSupervisor::transitionConfiguring(toolbox::Event::Reference /*e*/)
110 try
111 {
112  __SUP_COUT__ << "Configuring..." << __E__;
113 
114  CoreSupervisorBase::configureInit();
115 
116  try
117  {
118  ConfigurationTree testAppLink = theConfigurationManager_->getNode(
119  "/" +
120  theConfigurationManager_->__GET_CONFIG__(XDAQContextTable)->getTableName() +
121  CorePropertySupervisorBase::getSupervisorConfigurationPath());
122  }
123  catch(const std::runtime_error& e)
124  {
125  __SS__ << "The link to the Visual Supervisor configuration seems to be broken. "
126  "Please check this path: "
127  << "/" +
128  theConfigurationManager_->__GET_CONFIG__(XDAQContextTable)
129  ->getTableName() +
130  CorePropertySupervisorBase::getSupervisorConfigurationPath()
131  << __E__ << __E__ << e.what() << __E__;
132  __SS_THROW__;
133  }
134 
135  ConfigurationTree appLink = theConfigurationManager_->getNode(
136  "/" + theConfigurationManager_->__GET_CONFIG__(XDAQContextTable)->getTableName() +
137  CorePropertySupervisorBase::getSupervisorConfigurationPath());
138 
139  __COUTV__(appLink.getValueAsString());
140 
141  if(!appLink.isDisconnected())
142  {
143  theDataManager_ = DataManagerSingleton::getInstance<VisualDataManager>(
144  theConfigurationManager_->getNode(
145  theConfigurationManager_->__GET_CONFIG__(XDAQContextTable)
146  ->getTableName()),
147  CorePropertySupervisorBase::getSupervisorConfigurationPath(),
148  CorePropertySupervisorBase::getSupervisorUID());
149 
150  CoreSupervisorBase::theStateMachineImplementation_.push_back(theDataManager_);
151 
152  __SUP_COUT__ << "Done instantiating Visual data manager." << __E__;
153  }
154  else
155  __SUP_COUT__ << "No Visual Supervisor configuration link, so skipping Visual "
156  "data manager instantiation."
157  << __E__;
158 
159  // just handle FSMs
160  CoreSupervisorBase::transitionConfiguringFSMs();
161 
162  __SUP_COUT__ << "Configured." << __E__;
163 } // end transitionConfiguring()
164 catch(const std::runtime_error& e)
165 {
166  __SS__ << "Error with VisualSupervisor::transitionConfiguring(): " << e.what()
167  << __E__;
168  __COUT_ERR__ << ss.str();
169  // ExceptionHandler(ExceptionHandlerRethrow::no, ss.str());
170 
171  //__SS_THROW_ONLY__;
172  theStateMachine_.setErrorMessage(ss.str());
173  throw toolbox::fsm::exception::Exception(
174  "Transition Error" /*name*/,
175  ss.str() /* message*/,
176  "VisualSupervisor::transitionConfiguring" /*module*/,
177  __LINE__ /*line*/,
178  __FUNCTION__ /*function*/
179  );
180 } // end transitionConfiguring() catch
181 
182 //==============================================================================
183 void VisualSupervisor::transitionHalting(toolbox::Event::Reference e)
184 {
185  __SUP_COUT__ << "Halting..." << __E__;
186 
188  destroy();
189 
190  __SUP_COUT__ << "Halted." << __E__;
191 } // end transitionHalting()
192 
193 //==============================================================================
198 {
199  CorePropertySupervisorBase::setSupervisorProperty(
200  CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AllowNoLoginRequestTypes,
201  "setUserPreferences | getUserPreferences | getDirectoryContents | getRoot | "
202  "getEvents");
203 
204  CorePropertySupervisorBase::setSupervisorProperty(
205  CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.UserPermissionsThreshold,
206  "*=1 | rootAdminControls=100");
207 } //end setSupervisorPropertyDefaults()
208 
209 //========================================================================================================================
213 {
214  CorePropertySupervisorBase::setSupervisorProperty(
215  CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AutomatedRequestTypes,
216  "getRoot | getEvents");
217  CorePropertySupervisorBase::setSupervisorProperty(
218  CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.NoXmlWhiteSpaceRequestTypes,
219  "getRoot | getEvents");
220  //Note: json data in ROOTJS library expects no funny characters
221 } //end forceSupervisorPropertyValues()
222 
223 //========================================================================================================================
224 void VisualSupervisor::request(const std::string& requestType,
225  cgicc::Cgicc& cgiIn,
226  HttpXmlDocument& xmlOut,
227  const WebUsers::RequestUserInfo& userInfo)
228 {
229  // Commands
230  // getRawData
231  // getGeometry
232  // getEvents
233  // getRoot
234  // getDirectoryContents
235  // setUserPreferences
236  // getUserPreference
237 
238  // if (requestType == "getHisto" && theDataManager_->getLiveDQMHistos() != 0)
239  // {
240  // // TH1I* histo =
241  // (TH1I*)theDataManager_->getLiveDQMHistos()->get("Planes/Plane_0_Occupancy");
242  //
243  // // theDataManager_->load("Run185_Histo.root","Histograms");
244  // //TH1F* histo1d = theDataManager_->getFileDQMHistos().getHisto1D();
245  // //TCanvas* canvas = theDataManager_->getFileDQMHistos().getCanvas ();
246  // //TH2F* histo2d = theDataManager_->getFileDQMHistos().getHisto2D();
247  // //TProfile* profile = theDataManager_->getFileDQMHistos().getProfile();
248  //
249  // }
250  // std::stringstream ss;
251  // ss << "Request type: |" << requestType << "|";
252  // STDLINE(ss.str(),"") ;
253 
254  __SUP_COUT__ << "Request type: " << requestType << __E__;
255  if(requestType ==
256  "getRawData") // ################################################################################################################
257  {
258  __SUP_COUT__ << __E__;
259  try
260  {
261  // TODO -- add timestamp, so we know if data is new
262 
263  if(theDataManager_ == nullptr)
264  {
265  __SS__ << "No data manager instantiated." << __E__;
266  __SS_THROW__;
267  }
268  __SUP_COUT__ << "Getting Raw data and converting to binary string" << __E__;
269  // xmlOut.addBinaryStringToData("rawData",
270  // theDataManager_->getRawData());
271  __SUP_COUT__ << __E__;
272  __SUP_SS__ << "Raw data visualizion is deprecated!" << __E__;
273  __SUP_SS_THROW__;
274  }
275  catch(std::exception const& e)
276  {
277  __SUP_COUT__
278  << "ERROR! Exception while getting raw data. Incoming exception data..."
279  << __E__;
280  __SUP_COUT__ << e.what() << __E__;
281  __SUP_COUT__ << "End Exception Data" << __E__;
282  }
283  catch(...)
284  {
285  __SUP_COUT__ << "ERROR! Something went wrong trying to get raw data."
286  << __E__;
287  try
288  {
289  throw;
290  } //one more try to printout extra info
291  catch(const std::exception& e)
292  {
293  __SUP_COUT_ERR__ << "Exception message: " << e.what();
294  }
295  catch(...)
296  {
297  }
298  __SUP_COUT_INFO__ << "ERROR! Something went wrong trying to get raw data."
299  << __E__;
300  }
301  }
302  else if(
303  requestType == "setUserPreferences" &&
304  userInfo.username_ !=
305  "" /*from allow no user*/) // ################################################################################################################
306  {
307  __SUP_COUT__ << "userInfo.username_: " << userInfo.username_ << __E__;
308  std::string fullPath =
309  (std::string)PREFERENCES_PATH + userInfo.username_ + PREFERENCES_FILE_EXT;
310  __SUP_COUT__ << "fullPath: " << fullPath << __E__;
311 
312  std::string radioSelect = CgiDataUtilities::getData(cgiIn, "radioSelect");
313  std::string autoRefresh = CgiDataUtilities::getData(cgiIn, "autoRefresh");
314  std::string autoHide = CgiDataUtilities::getData(cgiIn, "autoHide");
315  std::string hardRefresh = CgiDataUtilities::getData(cgiIn, "hardRefresh");
316  std::string autoRefreshPeriod =
317  CgiDataUtilities::getData(cgiIn, "autoRefreshPeriod");
318 
319  __SUP_COUT__ << "radioSelect: " << radioSelect << __E__;
320  __SUP_COUT__ << "autoRefresh: " << autoRefresh << __E__;
321  __SUP_COUT__ << "autoHide: " << autoHide << __E__;
322  __SUP_COUT__ << "hardRefresh: " << hardRefresh << __E__;
323  __SUP_COUT__ << "autoRefreshPeriod: " << autoRefreshPeriod << __E__;
324 
325  // read existing
326  FILE* fp = fopen(fullPath.c_str(), "r");
327  if(fp)
328  {
329  char line[100];
330  char val[100];
331 
332  fgets(line, 100, fp);
333  sscanf(line, "%*s %s", val);
334  if(radioSelect == "")
335  radioSelect = val;
336 
337  fgets(line, 100, fp);
338  sscanf(line, "%*s %s", val);
339  if(autoRefresh == "")
340  autoRefresh = val;
341 
342  fgets(line, 100, fp);
343  sscanf(line, "%*s %s", val);
344  if(autoHide == "")
345  autoHide = val;
346 
347  fgets(line, 100, fp);
348  sscanf(line, "%*s %s", val);
349  if(hardRefresh == "")
350  hardRefresh = val;
351 
352  fgets(line, 100, fp);
353  sscanf(line, "%*s %s", val);
354  if(autoRefreshPeriod == "")
355  autoRefreshPeriod = val;
356 
357  fclose(fp);
358  }
359 
360  // write new
361  fp = fopen(fullPath.c_str(), "w");
362  if(fp)
363  {
364  fprintf(fp, "radioSelect %s\n", radioSelect.c_str());
365  fprintf(fp, "autoRefresh %s\n", autoRefresh.c_str());
366  fprintf(fp, "autoHide %s\n", autoHide.c_str());
367  fprintf(fp, "hardRefresh %s\n", hardRefresh.c_str());
368  fprintf(fp, "autoRefreshPeriod %s\n", autoRefreshPeriod.c_str());
369  fclose(fp);
370  }
371  else
372  __SUP_COUT_ERR__ << "Failure writing preferences to file: " << fullPath
373  << __E__;
374  }
375  else if(
376  requestType ==
377  "getUserPreferences") // ################################################################################################################
378  {
379  __SUP_COUT__ << "Next is userinfo" << __E__;
380  __SUP_COUT__ << "userInfo.username_: " << userInfo.username_ << __E__;
381  std::string fullPath =
382  (std::string)PREFERENCES_PATH + userInfo.username_ + PREFERENCES_FILE_EXT;
383  __SUP_COUT__ << "fullPath: " << fullPath << __E__;
384 
385  FILE* fp = fopen(fullPath.c_str(), "r");
386  if(fp)
387  {
388  char line[100];
389  // char val[100];
390  int val;
391 
392  fgets(line, 100, fp);
393  sscanf(line, "%*s %d", &val);
394  if(val < 0 || val > 3)
395  val = 0; // FIXME.. value can get corrupt...
396  xmlOut.addTextElementToData("radioSelect", std::to_string(val));
397  fgets(line, 100, fp);
398  sscanf(line, "%*s %d", &val);
399  xmlOut.addTextElementToData("autoRefresh", std::to_string(val));
400  fgets(line, 100, fp);
401  sscanf(line, "%*s %d", &val);
402  xmlOut.addTextElementToData("autoHide", std::to_string(val));
403  fgets(line, 100, fp);
404  sscanf(line, "%*s %d", &val);
405  xmlOut.addTextElementToData("hardRefresh", std::to_string(val));
406  fgets(line, 100, fp);
407  sscanf(line, "%*s %d", &val);
408  xmlOut.addTextElementToData("autoRefreshPeriod", std::to_string(val));
409  fclose(fp);
410  }
411  else
412  {
413  // else assume user has no preferences yet
414  xmlOut.addTextElementToData("radioSelect", "");
415  xmlOut.addTextElementToData("autoRefresh", "");
416  xmlOut.addTextElementToData("autoHide", "");
417  xmlOut.addTextElementToData("hardRefresh", "");
418  xmlOut.addTextElementToData("autoRefreshPeriod", "");
419  }
420  __SUP_COUT__ << "Done with preferences!" << __E__;
421  }
422  else if(
423  requestType ==
424  "getDirectoryContents") // ################################################################################################################
425  {
426  // return directory structure for requested path, types are "dir" and "file"
427  std::string rootpath =
428  std::string(ROOT_BROWSER_PATH) +
429  "/"; // Base directory where the Visualizer will look for files
430  std::string path = CgiDataUtilities::postData(cgiIn, "Path");
431  boost::regex re("%2F");
432  path = boost::regex_replace(path, re, "/"); // Dario: should be transparent for
433  // Ryan's purposes but required by Extjs
434 
437 
438  // return 1 if user has access to admin controls, else 0
439  char permStr[10];
440  sprintf(permStr,
441  "%d",
442  userInfo.permissionLevel_ >=
444  "rootAdminControls"));
445  xmlOut.addTextElementToData("permissions", permStr); // add permissions
448 
449  std::string dirpath = rootpath + path;
450  // If I am not looking for a file but just for the dir with the premade views
451  if(path == "/" + PRE_MADE_ROOT_CFG_DIR + "/")
452  dirpath = ROOT_DISPLAY_CONFIG_PATH;
453 
454  if(path.find("/" + PRE_MADE_ROOT_CFG_DIR + "/") ==
455  0) // ROOT config path must start the path
456  dirpath = std::string(ROOT_DISPLAY_CONFIG_PATH) + "/" +
457  path.substr(PRE_MADE_ROOT_CFG_DIR.length() + 2);
458 
460  __SUP_COUT__ << "rootpath:-" << rootpath << "-path:-" << path << "-dirpath:-"
461  << dirpath << "-" << __E__;
462 
463  DIR* pDIR;
464  struct dirent* entry;
465  bool isNotRtCfg;
466  bool isDir;
467  if((pDIR = opendir(dirpath.c_str())))
468  {
469  xmlOut.addTextElementToData("path", path);
470  xmlOut.addTextElementToData("headOfSearch", "located");
471 
472  // add LIVE if path is / and DQM is active
473  // add Pre-made Views if path is / and ROOT_DISPLAY_CONFIG_PATH isnt already
474  // there
475  if(theDataManager_ != nullptr)
476  __COUT__ << "path-" << path << "-DM: " << theDataManager_
477  << " Live: " << theDataManager_->getLiveDQMHistos() << std::endl;
478  if(path == "/")
479  {
480  // Add live histos
481  xmlOut.addTextElementToData("dir",
482  LIVEDQM_DIR + ".root"); // add to xml
483 
484  // check for ROOT_DISPLAY_CONFIG_PATH
485  DIR* pRtDIR = opendir(ROOT_DISPLAY_CONFIG_PATH);
486  bool recheck = false;
487  if(!pRtDIR) // if doesn't exist, make it
488  {
489  recheck = true;
490  if(mkdir(ROOT_DISPLAY_CONFIG_PATH,
491  S_IRWXU | (S_IRGRP | S_IXGRP) |
492  (S_IROTH | S_IXOTH))) // mode = drwx r-x r-x
493  __SUP_COUT__ << "Failed to make directory for pre made views: "
494  << ROOT_DISPLAY_CONFIG_PATH << __E__;
495  }
496  else
497  closedir(pRtDIR); // else close and display
498 
499  if(!recheck || (pRtDIR = opendir(ROOT_DISPLAY_CONFIG_PATH)))
500  {
503  xmlOut.addTextElementToData("dir",
504  PRE_MADE_ROOT_CFG_DIR); // add to xml
505  if(recheck)
506  closedir(pRtDIR);
507  }
508  }
510  while((entry = readdir(pDIR)))
511  {
512  //__SUP_COUT__ << int(entry->d_type) << " " << entry->d_name << "\n" <<
513  // __E__;
514  if(entry->d_name[0] != '.' &&
515  (entry->d_type ==
516  0 || // 0 == UNKNOWN (which can happen - seen in SL7 VM)
517  entry->d_type == 4 ||
518  entry->d_type == 8))
519  {
520  //__SUP_COUT__ << int(entry->d_type) << " " << entry->d_name << "\n"
521  //<< __E__;
522  isNotRtCfg =
523  std::string(entry->d_name).find(".rcfg") == std::string::npos;
524  isDir = false;
525 
526  if(entry->d_type == 0)
527  {
528  // unknown type .. determine if directory
530  DIR* pTmpDIR = opendir((dirpath + entry->d_name).c_str());
531  if(pTmpDIR)
532  {
534  isDir = true;
535  closedir(pTmpDIR);
536  }
537  // else //assume file
538  }
539 
540  if((entry->d_type == 8 ||
541  (!isDir && entry->d_type == 0)) // file type
542  && std::string(entry->d_name).find(".root") == std::string::npos &&
543  isNotRtCfg)
544  continue; // skip if not a root file or a config file
545  else if(entry->d_type == 4)
546  isDir = true; // flag directory types
547 
548  xmlOut.addTextElementToData(
549  isDir ? "dir" : (isNotRtCfg ? "dir" : "file"), entry->d_name);
550  }
551  }
552  closedir(pDIR);
553  }
554  else
555  __SUP_COUT__ << "Failed to access directory contents!" << __E__;
556  // std::ostringstream* out ;
557  // xmlOut.outputXmlDocument((std::ostringstream*) out, true);
558  }
559  else if(
560  requestType ==
561  "getRoot") // ################################################################################################################
562  {
563  // return directory structure for requested ROOT path, types are "dir" and "file"
564  std::string path = CgiDataUtilities::postData(cgiIn, "RootPath");
565  __SUP_COUTV__(path);
566 
567  unsigned splitter = path.find(".root") + 5; // 5 = std::string(".root").size();
568  std::string rootFileName =
569  std::string(__ENV__("ROOT_BROWSER_PATH")) + path.substr(0, splitter);
570  __SUP_COUTV__(rootFileName);
571 
572  std::string rootDirectoryName = path.substr(splitter, path.length() - splitter);
573  __SUP_COUTV__(rootDirectoryName);
574 
575  // std::string fullPathToObject = rootFileName + ":" + rootDirectoryName;
576  // __SUP_COUTV__(fullPathToObject);
577 
578  bool isLiveDQM = (path.find("/" + LIVEDQM_DIR + ".root/") == 0) ? true : false;
579  __SUP_COUTV__(isLiveDQM);
580 
581  TFile* rootFile = nullptr;
582  TObject* tObject = nullptr;
583  TDirectory* tDirectory = nullptr;
584 
585  if(!isLiveDQM) // If it is not from LIVE_DQM
586  {
587  rootFile = TFile::Open(rootFileName.c_str());
588 
589  if(rootFile == nullptr || !rootFile->IsOpen())
590  {
591  __SUP_SS__ << "Failed to access ROOT file: " << rootFileName << __E__;
592  __SUP_SS_THROW__;
593  }
594  // First I check if I can find the object to return directly. If not an object
595  // it is a directory
596  if((tObject = rootFile->Get(rootDirectoryName.c_str())) !=
597  nullptr || //for backwards compatibility
598  (rootDirectoryName.size() &&
599  rootDirectoryName[0] == '/' && //for newer root, remove leading '/'
600  (tObject = rootFile->Get(rootDirectoryName.substr(1).c_str())) !=
601  nullptr))
602  {
603  if(tObject->IsA() == TCanvas::Class())
604  {
605  static_cast<TCanvas*>(tObject)->Modified();
606  static_cast<TCanvas*>(tObject)->Update();
607  }
608  TString json = TBufferJSON::ConvertToJSON(tObject);
609  TBufferFile tBuffer(TBuffer::kWrite);
610  tObject->Streamer(tBuffer);
611  std::string hexString = BinaryStringMacros::binaryStringToHexString(
612  tBuffer.Buffer(), tBuffer.Length());
613 
614  __SUP_COUT__ << "Returning object from file '" << tObject->GetName()
615  << "' of class '" << tObject->ClassName() << __E__;
616 
617  xmlOut.addTextElementToData("path", path);
618  xmlOut.addTextElementToData("rootType", tObject->ClassName());
619  xmlOut.addTextElementToData("rootData", hexString);
620  xmlOut.addTextElementToData("rootJSON", json.Data());
621  }
622  else if((tDirectory = rootFile->GetDirectory(rootDirectoryName.c_str())) !=
623  nullptr)
624  {
625  TKey* key;
626  TIter next(tDirectory->GetListOfKeys());
627  xmlOut.addTextElementToData("path", path);
628  while((key = (TKey*)next()))
629  {
630  TString s = key->GetName();
631  TRegexp re("*", kTRUE);
632  if(s.Index(re) == kNPOS)
633  continue;
634  __SUP_COUT__ << "Class Name: " << key->GetClassName() << __E__;
635  xmlOut.addTextElementToData(
636  (std::string(key->GetClassName()).find("Directory") !=
637  std::string::npos ||
638  std::string(key->GetClassName()) == "TTree" ||
639  std::string(key->GetClassName()).find("TBranch") !=
640  std::string::npos) // == "TBranchElement")
641  ? "dir"
642  : "file",
643  key->GetName());
644 
645  if(TTEST(
646  50)) //enable to view json content of each object in directory
647  {
648  tObject = key->ReadObj();
649  __SUP_COUT__ << "JSON : " << key->GetClassName() << __E__;
650 
651  TString json = TBufferJSON::ConvertToJSON(tObject);
652  TBufferFile tBuffer(TBuffer::kWrite);
653  tObject->Streamer(tBuffer);
654  std::string hexString =
656  tBuffer.Length());
657 
658  __SUP_COUT__ << "Returning directory object from file '"
659  << tObject->GetName() << "' of class '"
660  << tObject->ClassName() << __E__;
661 
662  __SUP_COUTV__(json.Data());
663  }
664  }
665  rootFile->Close();
666  }
667  else
668  __SUP_COUT_ERR__ << "Failed to find object " << rootDirectoryName
669  << " in " << rootFileName << __E__;
670  return;
671  }
672  // LIVE DQM PLOTS
673  else if(theDataManager_ != nullptr && theDataManager_->isReady())
674  {
675  if(theDataManager_ != nullptr)
676  theDataManager_->setDoNotStop(true);
677  else
678  return;
679  __SUP_COUT__ << "Attempting to get LIVE ROOT object." << __E__;
680 
681  std::vector<DQMHistosBase*> dqmConsumers = theDataManager_->getLiveDQMs();
682  tObject = nullptr;
683  for(auto const& consumer : dqmConsumers)
684  {
685  rootFile = consumer->getFile();
686  __SUP_COUT__ << "LIVE file name: " << rootFile->GetName() << __E__;
687  if(rootFile == nullptr || !rootFile->IsOpen())
688  {
689  __SUP_SS__ << "Failed to access LIVE ROOT file: " << rootFileName
690  << __E__;
691  theDataManager_->setDoNotStop(false);
692  return;
693  }
694  // If I find an object then I stream it and return
695  if((tObject = rootFile->Get(rootDirectoryName.c_str())) != nullptr)
696  {
697  __SUP_COUT__ << "Object class name: " << tObject->ClassName()
698  << __E__;
699  std::string tmpClassName = tObject->ClassName();
700  TString json;
701  TBufferFile tBuffer(TBuffer::kWrite);
702  if(tObject->IsA() == TCanvas::Class())
703  {
704  static_cast<TCanvas*>(tObject)->Modified();
705  static_cast<TCanvas*>(tObject)->Update();
706  }
707  { // Only locking when converting the object
708  std::unique_lock<std::mutex> lock(
709  static_cast<DQMHistosConsumerBase*>(consumer)
710  ->getFillHistoMutex());
711  json = TBufferJSON::ConvertToJSON(tObject);
712  tObject->Streamer(tBuffer);
713  }
714  std::string hexString = BinaryStringMacros::binaryStringToHexString(
715  tBuffer.Buffer(), tBuffer.Length());
716 
717  __SUP_COUT__ << "Returning object '" << tObject->GetName()
718  << "' of class '" << tObject->ClassName() << __E__;
719 
720  //__SUP_COUT__ << "Data: " << json.Data() << std::endl;
721  xmlOut.addTextElementToData("path", path);
722  xmlOut.addTextElementToData("rootType", tObject->ClassName());
723  xmlOut.addTextElementToData("rootData", hexString);
724  xmlOut.addTextElementToData("rootJSON", json.Data());
725 
726  theDataManager_->setDoNotStop(false);
727  return;
728  }
729  }
730  // If I didn't find any object in the file, then it must be a directory!
731  std::map<std::string, std::string> dirList;
732 
733  for(auto const& consumer : dqmConsumers)
734  {
735  __SUP_COUT__ << "Attempting to get LIVE ROOT directory." << __E__;
736  rootFile = consumer->getFile();
737  __SUP_COUT__ << "LIVE file name: " << rootFile->GetName() << __E__;
738  if(rootFile == nullptr || !rootFile->IsOpen())
739  {
740  __SUP_SS__ << "Failed to access LIVE ROOT file: " << rootFileName
741  << __E__;
742  xmlOut.addTextElementToData("Warning", ss.str());
743  theDataManager_->setDoNotStop(false);
744  return;
745  }
746  if((tDirectory = rootFile->GetDirectory(rootDirectoryName.c_str())) !=
747  nullptr)
748  {
749  xmlOut.addTextElementToData("path", path);
750  __SUP_COUT__ << "Directory found getting the content!" << __E__;
751  TRegexp re("*", kTRUE);
752  TObject* obj;
753  TIter nextobj(tDirectory->GetList());
754  while((obj = (TObject*)nextobj()))
755  {
756  TString s = obj->GetName();
757  if(s.Index(re) == kNPOS)
758  continue;
759  __SUP_COUT__ << "Class Name: " << obj->IsA()->GetName() << __E__;
760  dirList[obj->GetName()] =
761  (std::string(obj->IsA()->GetName()).find("Directory") !=
762  std::string::npos ||
763  std::string(obj->IsA()->GetName()) == "TTree" ||
764  std::string(obj->IsA()->GetName()).find("TBranch") !=
765  std::string::npos) // == "TBranchElement")
766  ? "dir"
767  : "file";
768  }
769  }
770  }
771  for(auto const& dir : dirList)
772  {
773  xmlOut.addTextElementToData(dir.second, dir.first);
774  __SUP_COUT__ << "Class Name: " << dir.second << " Object: " << dir.first
775  << __E__;
776  }
777  }
778 
779  } // END LORENZO GET ROOT
780  // else if(
781  // requestType ==
782  // "RyangetRoot")
783  // //################################################################################################################
784  // {
785  // // return directory structure for requested ROOT path, types are "dir" and "file"
786  // std::string path = CgiDataUtilities::postData(cgiIn, "RootPath");
787 
788  // //////////////////////////////////////////////////////////////////
789  // // DARIO
790  // //////////////////////////////////////////////////////////////////
791  // ss.str("");
792  // ss << "PID: " << ::getpid();
793  // // STDLINE(ss.str(),ACCyan) ;
794  // boost::regex re1("%2F");
795  // path = boost::regex_replace(
796  // path, re1, "/"); // Dario: should be transparent for Ryan's purposes but
797  // // required by Extjs
798  // boost::regex re2("%20");
799  // path = boost::regex_replace(
800  // path, re2, " "); // Dario: should be transparent for Ryan's purposes but
801  // // required by Extjs
802  // boost::regex re3("%3A");
803  // path =
804  // boost::regex_replace(path, re3, ""); // Dario: should be transparent for
805  // // Ryan's purposes but required by Extjs
806  // ss.str("");
807  // ss << "path : " << path;
808  // // STDLINE(ss.str(),ACCyan) ;
809  // //////////////////////////////////////////////////////////////////
810  // // END DARIO
811  // //////////////////////////////////////////////////////////////////
812 
813  // std::string fullPath = std::string(__ENV__("ROOT_BROWSER_PATH")) + path;
814  // __SUP_COUTV__(fullPath);
815 
816  // const size_t rootExtensionStart = fullPath.find(".root");
817  // const size_t rootExtensionEnd = rootExtensionStart + std::string(".root").size();
818 
819  // std::string rootFileName = fullPath.substr(0, rootExtensionEnd);
820 
821  // __SUP_COUTV__(rootFileName);
822  // std::string fullPathToObject =
823  // rootFileName + ":" +
824  // fullPath.substr(rootExtensionEnd, fullPath.size() - rootExtensionEnd + 1);
825 
826  // __SUP_COUTV__(fullPathToObject);
827  // std::string::size_type LDQM_pos = path.find("/" + LIVEDQM_DIR + ".root/");
828  // __SUP_COUTV__(LDQM_pos);
829 
830  // TFile* rootFile = nullptr;
831  // if(LDQM_pos == std::string::npos) // If it is not from LIVE_DQM
832  // {
833  // __SUP_COUTV__(rootFileName);
834  // rootFile = TFile::Open(rootFileName.c_str());
835 
836  // if(rootFile == nullptr || !rootFile->IsOpen())
837  // {
838  // __SUP_SS__ << "Failed to access ROOT file: " << rootFileName << __E__;
839  // __SUP_SS_THROW__;
840  // }
841  // }
842  // else
843  // {
844  // if(theDataManager_ == nullptr || !theDataManager_->isReady())
845  // return;
846  // theDataManager_->setDoNotStop(true);
847  // if(theDataManager_ != nullptr &&
848  // theDataManager_->getLiveDQMHistos() != nullptr)
849  // {
850  // __SUP_COUT__ << "Attempting to get LIVE ROOT object." << __E__;
851  // __SUP_COUTV__(fullPathToObject);
852  // fullPathToObject = path.substr(("/" + LIVEDQM_DIR + ".root").length());
853  // __SUP_COUTV__(fullPathToObject);
854  // rootFile = theDataManager_->getLiveDQMHistos()->getFile();
855 
856  // __SUP_COUT__ << "LIVE file name: " << rootFile->GetName() << __E__;
857 
858  // if(rootFile == nullptr || !rootFile->IsOpen())
859  // {
860  // __SUP_SS__ << "Failed to access LIVE ROOT file: " << rootFileName
861  // << __E__;
862  // __SUP_COUT__ << ss.str();
863  // xmlOut.addTextElementToData("Warning", ss.str());
864  // theDataManager_->setDoNotStop(false);
865  // return; // do not treat LIVE root file missing as error, .. assume
866  // // just not Running
867  // }
868  // }
869  // else
870  // {
871  // __SUP_SS__ << "Failed to access LIVE ROOT file: " << rootFileName
872  // << __E__;
873  // __SUP_COUT__ << ss.str();
874  // xmlOut.addTextElementToData("Warning", ss.str());
875  // theDataManager_->setDoNotStop(false);
876  // return; // do not treat LIVE root file missing as error, .. assume just
877  // // not Running
878  // }
879  // }
880 
881  // // at this point initial ROOT object has been successfully opened
882 
883  // xmlOut.addTextElementToData("path", path);
884 
885  // TDirectory* directory = rootFile->GetDirectory(fullPathToObject.c_str());
886  // __SUP_COUT__ << "Getting dir pointer: " << directory
887  // << " dir name: " << fullPathToObject << __E__;
888  // TObject* tobject = nullptr;
889 
890  // if(!directory) // if not directory yet, peak at object for TTree or
891  // // TBranchElement with children
892  // {
893  // ///////////////////////////////////////////////////////////////////////////
894  // // TREE HANDLING
895  // // if TTree or TBranchElement with children, then treat as a directory
896  // // else if TBranchElement without children, then treat as leaf ROOT object
897 
898  // fullPathToObject = fullPath.substr(
899  // rootExtensionEnd); // re-purpose fullPathToObject as path within TTree
900 
901  // std::vector<std::string> splitTTreePath =
902  // StringMacros::getVectorFromString(fullPathToObject, {'/'});
903  // __SUP_COUTV__(StringMacros::vectorToString(splitTTreePath));
904 
905  // unsigned int spliti = 0;
906  // while(spliti < splitTTreePath.size() && splitTTreePath[spliti].size() == 0)
907  // ++spliti; // search for first non-empty
908 
909  // if(spliti < splitTTreePath.size())
910  // {
911  // __SUP_COUTV__(splitTTreePath[spliti]);
912  // tobject = (TObject*)rootFile->Get(splitTTreePath[spliti].c_str());
913  // ++spliti; // search for next non-empty
914  // }
915 
916  // if(tobject == nullptr)
917  // {
918  // __SUP_SS__ << "Failed to access ROOT sub path: " << fullPathToObject
919  // << __E__;
920  // __SUP_SS_THROW__;
921  // }
922  // __SUP_COUTV__(tobject->ClassName());
923 
924  // if(std::string(tobject->ClassName()) == "TTree" ||
925  // std::string(tobject->ClassName()).find("TBranch") !=
926  // std::string::npos || // == "TBranchElement" ||
927  // std::string(tobject->ClassName()).find("TDirectory") != std::string::npos)
928  // {
929  // // continue traversing name split
930  // do
931  // {
932  // while(spliti < splitTTreePath.size() &&
933  // splitTTreePath[spliti].size() == 0)
934  // ++spliti; // search for next non-empty
935  // if(spliti >= splitTTreePath.size())
936  // break; // reached end of traversal!
937 
938  // __SUP_COUTV__(splitTTreePath[spliti]);
939  // __SUP_COUT__ << "Parent class = " << (tobject->ClassName()) << __E__;
940  // if(std::string(tobject->ClassName()) == "TTree")
941  // tobject = (TObject*)((TTree*)tobject)
942  // ->GetBranch(splitTTreePath[spliti].c_str());
943  // else if(std::string(tobject->ClassName()).find("TBranch") !=
944  // std::string::npos)
945  // tobject = (TObject*)((TBranchElement*)tobject)
946  // ->FindBranch(splitTTreePath[spliti].c_str());
947  // else if(std::string(tobject->ClassName()).find("TDirectory") !=
948  // std::string::npos)
949  // tobject = (TObject*)((TDirectoryFile*)tobject)
950  // ->Get(splitTTreePath[spliti].c_str());
951 
952  // ++spliti; // search for next non-empty
953  // } while(tobject);
954 
955  // if(tobject == nullptr)
956  // {
957  // __SUP_SS__ << "Failed to access root sub path: " << fullPathToObject
958  // << __E__;
959  // __SUP_SS_THROW__;
960  // }
961 
962  // __SUP_COUTV__(tobject->ClassName());
963 
964  // // now at path's target element with tobject
965  // // if no branches, then "file" and tobject stringified
966  // // else "dir"
967 
968  // TObjArray* objects = nullptr;
969 
970  // if(std::string(tobject->ClassName()) == "TTree")
971  // objects = ((TTree*)tobject)->GetListOfBranches();
972  // else if(std::string(tobject->ClassName()).find("TBranch") !=
973  // std::string::npos) //== "TBranchElement")
974  // objects = ((TBranchElement*)tobject)->GetListOfBranches();
975 
976  // if(objects != nullptr && !objects->IsEmpty())
977  // {
978  // __SUP_COUT__ << "Handling as TTree/TBranchElement directory" << __E__;
979 
980  // // treat like a directory, and return branches
981  // TObject* obj;
982  // TIter nextobj(objects->MakeIterator());
983  // TRegexp re("*", kTRUE);
984  // while((obj = (TObject*)nextobj()))
985  // {
986  // std::string name = obj->GetName();
987  // TString s = name;
988  // if(s.Index(re) == kNPOS)
989  // continue;
990 
991  // __SUP_COUT__ << "Child class Name: " << obj->IsA()->GetName()
992  // << " " << name << __E__;
993 
994  // if(std::string(obj->IsA()->GetName()).find("TBranch") !=
995  // std::string::npos) // == "TBranchElement")
996  // {
997  // // decide if leave based on children branches
998  // __SUP_COUT__
999  // << "Child '" << name << "' of type '"
1000  // << ((TBranchElement*)obj)->GetTypeName() << "' isLeaf="
1001  // << ((TBranchElement*)obj)->GetListOfBranches()->IsEmpty()
1002  // << __E__;
1003 
1004  // xmlOut.addTextElementToData(
1005  // (((TBranchElement*)obj)->GetListOfBranches()->IsEmpty())
1006  // ? "file"
1007  // : "dir",
1008  // name);
1009  // }
1010  // else // handle normal way
1011  // {
1012  // xmlOut.addTextElementToData(
1013  // (std::string(obj->IsA()->GetName()).find("Directory") !=
1014  // std::string::npos ||
1015  // std::string(obj->IsA()->GetName()) == "TTree")
1016  // ? "dir"
1017  // : "file",
1018  // name);
1019  // }
1020  // }
1021  // theDataManager_->setDoNotStop(false);
1022  // return;
1023  // } // done handling TTree branches
1024  // } // end TTree and branch handling
1025  // else if(spliti < splitTTreePath.size())
1026  // {
1027  // __COUTV__(fullPathToObject);
1028  // // if more name to mystery object (likely TDirectoryFile), then attempt to
1029  // // get full subpath
1030  // tobject = (TObject*)rootFile->Get(fullPathToObject.c_str());
1031  // }
1032 
1033  // // at this point have tobject to stringify
1034  // } // peaking for TTree
1035 
1036  // if(directory == nullptr) // It MUST be an object to be serialized! tobject !=
1037  // // nullptr at this point.
1038  // {
1039  // __SUP_COUT__ << "This is not a directory!" << __E__;
1040 
1041  // if(tobject == nullptr)
1042  // {
1043  // __SUP_SS__
1044  // << "Something is wrong. Failed to access ROOT TObject at path: "
1045  // << fullPath << __E__;
1046  // __SUP_SS_THROW__;
1047  // }
1048 
1049  // // TObject* tobjectClone = nullptr;
1050 
1051  // if(tobject != nullptr) // turns out was a root object path
1052  // {
1053  // // ignore lock, because Lore says only crashed with Canvas
1054 
1055  // // FIXME -- check this new histo and gDirectory->Get for memory leak!
1056  // bool doJSONobject = false;
1057  // TH1F* h8 = nullptr;
1058  // std::string tmpClassName = tobject->ClassName();
1059  // if(tmpClassName.find("TBranch") != std::string::npos)
1060  // {
1061  // __COUT__ << "Attempting to plot '" << tobject->ClassName()
1062  // << "' type." << __E__;
1063 
1064  // h8 = new TH1F();
1065  // TTree* t3 = ((TBranch*)tobject)->GetTree();
1066  // //__COUT__ << "Attempting to plot '" << t3 << "' type." << __E__;
1067  // //__COUT__ << "JSON=" << TBufferJSON::ConvertToJSON(h8).Data() <<
1068  // //__E__;
1069  // t3->Draw("Value>>h8", "", "goff");
1070  // tobject = gDirectory->Get("h8");
1071 
1072  // __COUT__ << "Attempting to plot '" << tobject->ClassName()
1073  // << "' type." << __E__;
1074  // doJSONobject = true;
1075  // }
1076 
1077  // TString json;
1078  // TBufferFile tBuffer(TBuffer::kWrite);
1079  // if(theDataManager_ != nullptr &&
1080  // theDataManager_->getLiveDQMHistos() != nullptr && LDQM_pos == 0)
1081  // {
1082  // if(tobject->IsA() == TCanvas::Class())
1083  // {
1084  // static_cast<TCanvas*>(tobject)->Modified();
1085  // static_cast<TCanvas*>(tobject)->Update();
1086  // }
1087  // std::unique_lock<std::mutex> lock(
1088  // static_cast<DQMHistosConsumerBase*>(
1089  // theDataManager_->getLiveDQMHistos())
1090  // ->getFillHistoMutex());
1091  // json = TBufferJSON::ConvertToJSON(tobject);
1092  // tobject->Streamer(tBuffer);
1093  // }
1094  // else
1095  // {
1096  // // No need to lock from file!
1097  // json = TBufferJSON::ConvertToJSON(tobject);
1098  // tobject->Streamer(tBuffer);
1099  // }
1100 
1101  // std::string hexString = BinaryStringMacros::binaryStringToHexString(
1102  // tBuffer.Buffer(), tBuffer.Length());
1103 
1104  // __SUP_COUT__ << "Returning object '" << tobject->GetName()
1105  // << "' of class '" << tobject->ClassName() << __E__;
1106 
1107  // //__SUP_COUT__ << "Data: " << json.Data() << std::endl;
1108  // xmlOut.addTextElementToData("rootType",
1109  // doJSONobject ? "JSON" : tobject->ClassName());
1110  // xmlOut.addTextElementToData("rootData", hexString);
1111  // xmlOut.addTextElementToData("rootJSON", json.Data());
1112 
1113  // if(h8 != nullptr)
1114  // delete h8;
1115  // }
1116  // else
1117  // __SUP_COUT_ERR__ << "Failed to access:-" << fullPathToObject << "-"
1118  // << __E__;
1119  // STDLINE("Done with it!", ACBlue);
1120  // }
1121  // else // handle as directory
1122  // {
1123  // __SUP_COUT__ << "directory found getting the content!" << __E__;
1124  // STDLINE("Directory found getting the content!", ACGreen);
1125  // TRegexp re("*", kTRUE);
1126  // if(LDQM_pos == 0)
1127  // {
1128  // TObject* obj;
1129  // TIter nextobj(directory->GetList());
1130  // while((obj = (TObject*)nextobj()))
1131  // {
1132  // TString s = obj->GetName();
1133  // if(s.Index(re) == kNPOS)
1134  // continue;
1135  // __SUP_COUT__ << "Class Name: " << obj->IsA()->GetName() << __E__;
1136 
1137  // xmlOut.addTextElementToData(
1138  // (std::string(obj->IsA()->GetName()).find("Directory") !=
1139  // std::string::npos ||
1140  // std::string(obj->IsA()->GetName()) == "TTree" ||
1141  // std::string(obj->IsA()->GetName()).find("TBranch") !=
1142  // std::string::npos) // == "TBranchElement")
1143  // ? "dir"
1144  // : "file",
1145  // obj->GetName());
1146  // // ss.str("") ; ss << "obj->GetName(): " << obj->GetName() ;
1147  // // //STDLINE(ss.str(),"") ;
1148  // }
1149  // }
1150  // else
1151  // {
1152  // TKey* key;
1153  // TIter next(directory->GetListOfKeys());
1154  // while((key = (TKey*)next()))
1155  // {
1156  // TString s = key->GetName();
1157  // if(s.Index(re) == kNPOS)
1158  // continue;
1159  // __SUP_COUT__ << "Class Name: " << key->GetClassName() << __E__;
1160  // xmlOut.addTextElementToData(
1161  // (std::string(key->GetClassName()).find("Directory") !=
1162  // std::string::npos ||
1163  // std::string(key->GetClassName()) == "TTree" ||
1164  // std::string(key->GetClassName()).find("TBranch") !=
1165  // std::string::npos) // == "TBranchElement")
1166  // ? "dir"
1167  // : "file",
1168  // key->GetName());
1169  // // ss.str("") ; ss << "key->GetName(): " << key->GetName() ;
1170  // ////STDLINE(ss.str(),"") ;
1171  // }
1172  // }
1173  // }
1174  // if(LDQM_pos == std::string::npos)
1175  // rootFile->Close();
1176 
1177  // } // end getRoot handling
1178  else if(
1179  requestType ==
1180  "getEvents") // ################################################################################################################
1181  {
1182  if(theDataManager_ == nullptr)
1183  {
1184  __SS__ << "No Data Manager instantiated." << __E__;
1185  __SS_THROW__;
1186  }
1187 
1188  int Run = atoi(cgiIn("run").c_str());
1189 
1190  __SUP_COUT__ << "getEvents for run " << Run << __E__;
1191 
1192  if(Run != (int)loadedRunNumber_ || loadedRunNumber_ == (unsigned int)-1)
1193  {
1194  theDataManager_->load("Run1684.root", "Monicelli");
1195  loadedRunNumber_ = Run;
1196  }
1197 
1198  /*DOMElement* eventsParent =*/xmlOut.addTextElementToData("events", "");
1199  // DOMElement* eventParent;
1200  // char str[40];
1201 
1202  // const Visual3DEvents& events = theDataManager_->getVisual3DEvents();
1203  // __SUP_COUT__ << "Preparing hits xml" << __E__;
1204  // int numberOfEvents = 0;
1205  // for(Visual3DEvents::const_iterator it=events.begin(); it!=events.end() &&
1206  // numberOfEvents < 10000; it++, numberOfEvents++)
1207  // {
1208  // //__SUP_COUT__ << "Event: " << numberOfEvents << __E__;
1209  // eventParent = xmlOut.addTextElementToParent("event", str,
1210  // eventsParent); const VisualHits& hits = it->getHits();
1211  // for(VisualHits::const_iterator itHits=hits.begin();
1212  // itHits!=hits.end(); itHits++)
1213  // {
1214  // sprintf(str,"%f",itHits->x);
1215  // xmlOut.addTextElementToParent("xyz_point", str, eventParent);
1216  // sprintf(str,"%f",itHits->y);
1217  // xmlOut.addTextElementToParent("xyz_point", str, eventParent);
1218  // sprintf(str,"%f",itHits->z);
1219  // xmlOut.addTextElementToParent("xyz_point", str, eventParent);
1220  // //__SUP_COUT__ << "X: " << itHits->x << " Y: " << itHits->y << "
1221  // Z:
1222  //"
1223  //<< itHits->z << __E__;
1224  // }
1225  // const VisualTracks& tracks = it->getTracks();
1226  // for(VisualTracks::const_iterator itTrks=tracks.begin();
1227  // itTrks!=tracks.end(); itTrks++)
1228  // {
1229  // sprintf(str,"%f",itTrks->slopeX);
1230  // xmlOut.addTextElementToParent("slope", str, eventParent);
1231  // sprintf(str,"%f",itTrks->slopeY);
1232  // xmlOut.addTextElementToParent("slope", str, eventParent);
1233  // sprintf(str,"%f",itTrks->interceptX);
1234  // xmlOut.addTextElementToParent("intcpt", str, eventParent);
1235  // sprintf(str,"%f",itTrks->interceptY);
1236  // xmlOut.addTextElementToParent("intcpt", str, eventParent);
1237  //
1238  // }
1239  //
1240  // }
1241  __SUP_COUT__ << "Done hits xml" << __E__;
1242  }
1243  else if(
1244  requestType ==
1245  "getGeometry") // ################################################################################################################
1246  {
1247  __SUP_COUT__ << "getGeometry" << __E__;
1248 
1249  if(theDataManager_ == nullptr)
1250  {
1251  __SS__ << "No Data Manager instantiated." << __E__;
1252  __SS_THROW__;
1253  }
1254 
1255  // FIXME -- this crashes when the file doesn't exist!
1256  theDataManager_->load("Run1684.geo", "Geometry");
1257 
1258  __SUP_COUT__ << "getGeometry" << __E__;
1259 
1260  /*DOMElement* geometryParent =*/xmlOut.addTextElementToData("geometry", "");
1261  // const Visual3DShapes& shapes =
1262  // theDataManager_->getVisual3DGeometry().getShapes();
1263  //
1264  // __SUP_COUT__ << "getGeometry" << __E__;
1265  //
1266  //
1267  // DOMElement* objectParent;
1268  // char str[40];
1269  // for(Visual3DShapes::const_iterator itShapes=shapes.begin();
1270  // itShapes!=shapes.end(); itShapes++)
1271  // {
1272  // objectParent = xmlOut.addTextElementToParent("object", str,
1273  // geometryParent);
1274  // xmlOut.addTextElementToParent("object_type", "LINE_LOOP",
1275  // objectParent); sprintf(str,"%d",itShapes->numberOfRows);
1276  // xmlOut.addTextElementToParent("object_rows", str, objectParent);
1277  // sprintf(str,"%d",itShapes->numberOfColumns);
1278  // xmlOut.addTextElementToParent("object_columns", str, objectParent);
1279  // for(Points::const_iterator itCorners=itShapes->corners.begin();
1280  // itCorners!=itShapes->corners.end(); itCorners++)
1281  // {
1282  // sprintf(str,"%f",itCorners->x);
1283  // xmlOut.addTextElementToParent("xyz_point", str, objectParent);
1284  // sprintf(str,"%f",itCorners->y);
1285  // xmlOut.addTextElementToParent("xyz_point", str, objectParent);
1286  // sprintf(str,"%f",itCorners->z);
1287  // xmlOut.addTextElementToParent("xyz_point", str, objectParent);
1288  // }
1289  // }
1290  }
1291  else if(
1292  requestType ==
1293  "getRootConfig") // ################################################################################################################
1294  {
1295  std::string path = CgiDataUtilities::postData(cgiIn, "RootConfigPath");
1296  __SUP_COUT__ << "path " << path << __E__;
1297 
1298  if(path.find("/" + PRE_MADE_ROOT_CFG_DIR + "/") ==
1299  0) // ROOT config path must start the path
1300  {
1301  path = std::string(ROOT_DISPLAY_CONFIG_PATH) + "/" +
1302  path.substr(PRE_MADE_ROOT_CFG_DIR.length() + 2);
1303  __SUP_COUT__ << "mod path " << path << __E__;
1304  }
1305 
1306  HttpXmlDocument cfgXml;
1307  if(cfgXml.loadXmlDocument(path))
1308  {
1309  xmlOut.addTextElementToData("status", "1");
1310  xmlOut.copyDataChildren(cfgXml); // copy file to output xml
1311  cfgXml.saveXmlDocument(path);
1312  }
1313  else
1314  xmlOut.addTextElementToData("status",
1315  "Failed. File to properly load config file.");
1316  }
1317  else if(
1318  requestType ==
1319  "rootAdminControls") // ################################################################################################################
1320  {
1321  // if(userPermissions < ROOT_VIEWER_PERMISSIONS_THRESHOLD)
1322  // {
1323  // __SUP_COUT__ << "Insufficient permissions for Root Viewer Admin
1324  // Controls: " << userPermissions << " < " << ROOT_VIEWER_PERMISSIONS_THRESHOLD <<
1325  // __E__;
1326  // xmlOut.addTextElementToData("status", "Failed. Insufficient user
1327  // permissions.");
1328  // }
1329  // else
1330  // {
1331  std::string cmd = cgiIn("cmd"); // possible commands are
1332  // mkdir
1333  // save
1334  // delete
1335 
1336  std::string path = CgiDataUtilities::postData(cgiIn, "path");
1337  std::string name = CgiDataUtilities::postData(cgiIn, "name");
1338  __SUP_COUT__ << "cmd " << cmd << __E__;
1339  __SUP_COUT__ << "path " << path << __E__;
1340  __SUP_COUT__ << "name " << name << __E__;
1341 
1342  if(path.find("/" + PRE_MADE_ROOT_CFG_DIR + "/") ==
1343  0) // ROOT config path must start the path
1344  {
1345  path = std::string(ROOT_DISPLAY_CONFIG_PATH) + "/" +
1346  path.substr(PRE_MADE_ROOT_CFG_DIR.length() + 2) + name;
1347  __SUP_COUT__ << "mod path " << path << __E__;
1348 
1349  if(cmd == "mkdir")
1350  {
1351  if(mkdir(path.c_str(),
1352  S_IRWXU | (S_IRGRP | S_IXGRP) |
1353  (S_IROTH | S_IXOTH))) // mode = drwx r-x r-x
1354  xmlOut.addTextElementToData("status",
1355  "Failed. Directory create rejected.");
1356  else
1357  xmlOut.addTextElementToData("status", "1"); // success
1358  }
1359  else if(cmd == "save")
1360  {
1361  path += PRE_MADE_ROOT_CFG_FILE_EXT; // add file extension
1362 
1363  bool useRunWildCard =
1364  atoi(CgiDataUtilities::postData(cgiIn, "useRunWildCard")
1365  .c_str()); // 0 or 1
1366  std::string config = CgiDataUtilities::postData(cgiIn, "config");
1367  __SUP_COUT__ << "config " << config << __E__;
1368  __SUP_COUT__ << "useRunWildCard " << useRunWildCard << __E__;
1369 
1370  // check if file already exists
1371  FILE* fp = fopen(path.c_str(), "r");
1372  if(fp)
1373  {
1374  fclose(fp);
1375  xmlOut.addTextElementToData("status", "Failed. File already exists.");
1376  __SUP_COUT__ << " Failed. File already exists." << __E__;
1377  }
1378  else
1379  {
1380  // dump to file
1381  // verify proper format through read back
1382  // if successfully loaded, re-save for formatting
1383 
1384  // dump to file
1385  fp = fopen(path.c_str(), "w");
1386  fputs(config.c_str(), fp);
1387  fclose(fp);
1388 
1389  // verify proper format through read back
1390  HttpXmlDocument cfgXml;
1391  if(cfgXml.loadXmlDocument(path))
1392  {
1393  // successfully loaded, re-save for formatting
1394  cfgXml.saveXmlDocument(path);
1395  xmlOut.addTextElementToData("status", "1"); // success
1396  }
1397  else // failed to load properly
1398  {
1399  xmlOut.addTextElementToData(
1400  "status", "Failed. Fatal. Improper file format.");
1401  if(remove(path.c_str()) != 0)
1402  __SUP_COUT__ << "Failed. Could not remove poorly formed Root "
1403  "config file!"
1404  << __E__;
1405  }
1406  }
1407  }
1408  else if(cmd == "delete")
1409  {
1410  // guess first directory and then file
1411  if(rmdir(path.c_str()) == 0 ||
1412  remove((path + PRE_MADE_ROOT_CFG_FILE_EXT).c_str()) == 0)
1413  xmlOut.addTextElementToData("status", "1"); // success
1414  else
1415  xmlOut.addTextElementToData("status",
1416  "Failed. Target could not be deleted.");
1417  }
1418  else
1419  xmlOut.addTextElementToData("status", "Failed. Unrecognized command.");
1420  }
1421  else
1422  xmlOut.addTextElementToData("status", "Failed. Invalid path.");
1423 
1424  //}
1425  }
1426  else if(
1427  requestType ==
1428  "getMeDirs") // ################################################################################################################
1429  {
1430  xmlOut.setDarioStyle(true); // workaround for XML formatting....
1431  std::string fSystemPath = std::string(ROOT_BROWSER_PATH) + "/";
1432  std::string fRootPath = CgiDataUtilities::postData(cgiIn, "Path");
1433  boost::regex re("%2F");
1434  fRootPath = boost::regex_replace(fRootPath, re, "/");
1435  std::string fullPath = fSystemPath + fRootPath;
1436  // fFoldersPath_ = "pippo" ;
1437  STDLINE(std::string("Begin: fSystemPath = ") + fSystemPath, ACWhite);
1438  STDLINE(std::string("Begin: fRootPath = ") + fRootPath, ACWhite);
1439  STDLINE(std::string("Begin: fullPath = ") + fullPath, ACWhite);
1440  // STDLINE(std::string("Begin: fFoldersPath = ")+fFoldersPath_,ACCyan ) ;
1441 
1442  xmlOut.setRootPath(fRootPath);
1443  xmlOut.makeDirectoryBinaryTree(fSystemPath, fRootPath, 0, NULL);
1444  std::ostringstream* out = new std::ostringstream();
1445  xmlOut.outputXmlDocument((std::ostringstream*)out, true);
1446  }
1447  else if(
1448  requestType ==
1449  "getMeRootFile") // ################################################################################################################
1450  {
1451  xmlOut.setDarioStyle(true); // workaround for XML formatting....
1452  std::string fSystemPath = std::string(ROOT_BROWSER_PATH) + "/";
1453  std::string fRootPath = CgiDataUtilities::postData(cgiIn, "fRootPath");
1454  std::string fFoldersPath = CgiDataUtilities::postData(cgiIn, "fFoldersPath");
1455  std::string fHistName = CgiDataUtilities::postData(cgiIn, "fHistName");
1456  std::string fRFoldersPath = CgiDataUtilities::postData(cgiIn, "fRFoldersPath");
1457  std::string fFileName = CgiDataUtilities::postData(cgiIn, "fFileName");
1458  boost::regex re("%2F");
1459  fRootPath = boost::regex_replace(fRootPath, re, "/");
1460  fFoldersPath = boost::regex_replace(fFoldersPath, re, "/");
1461  // STDLINE(std::string("fSystemPath : ")+fSystemPath ,ACCyan);
1462  // STDLINE(std::string("fRootPath : ")+fRootPath ,ACCyan);
1463  // STDLINE(std::string("fFoldersPath : ")+fFoldersPath ,ACCyan);
1464  // STDLINE(std::string("fHistName : ")+fHistName ,ACCyan);
1465  // STDLINE(std::string("fRFoldersPath: ")+fRFoldersPath,ACCyan);
1466  // STDLINE(std::string("fFileName : ")+fFileName ,ACCyan);
1467  RootFileExplorer* theExplorer = new RootFileExplorer(
1468  fSystemPath, fRootPath, fFoldersPath, fHistName, fRFoldersPath, fFileName);
1469  xmlOut.setDocument(theExplorer->initialize(false));
1470  // std::ostringstream* out ;
1471  // xmlOut.outputXmlDocument((std::ostringstream*) out, true);
1472  }
1473  // else if(
1474  // requestType ==
1475  // "getMeLIVE-DQMFile")
1476  // //################################################################################################################
1477  // {
1478  // xmlOut.setDarioStyle(true); // workaround for XML formatting....
1479  // std::string fSystemPath = std::string(ROOT_BROWSER_PATH) + "/";
1480  // std::string fRootPath = CgiDataUtilities::postData(cgiIn, "fRootPath");
1481  // std::string fFoldersPath = CgiDataUtilities::postData(cgiIn, "fFoldersPath");
1482  // std::string fHistName = CgiDataUtilities::postData(cgiIn, "fHistName");
1483  // std::string fRFoldersPath = CgiDataUtilities::postData(cgiIn, "fRFoldersPath");
1484  // std::string fFileName = CgiDataUtilities::postData(cgiIn, "fFileName");
1485  // STDLINE(std::string("fSystemPath : ") + fSystemPath, ACCyan);
1486  // STDLINE(std::string("fRootPath : ") + fRootPath, ACCyan);
1487  // STDLINE(std::string("fFoldersPath : ") + fFoldersPath, ACCyan);
1488  // STDLINE(std::string("fHistName : ") + fHistName, ACCyan);
1489  // STDLINE(std::string("fRFoldersPath: ") + fRFoldersPath, ACCyan);
1490  // STDLINE(std::string("fFileName : ") + fFileName, ACCyan);
1491  // boost::regex re("%2F");
1492  // fRootPath = boost::regex_replace(fRootPath, re, "/");
1493  // fFoldersPath = boost::regex_replace(fFoldersPath, re, "/");
1494 
1495  // TFile* rootFile;
1496  // STDLINE("Getting LiveDQMHistos", ACGreen);
1497  // if(theDataManager_->getLiveDQMHistos() != nullptr)
1498  // {
1499  // STDLINE("Selecting LIVE_DQM.root", ACCyan);
1500  // rootFile = theDataManager_->getLiveDQMHistos()->getFile();
1501  // fRootPath = "LIVE_DQM.root";
1502  // }
1503  // else
1504  // {
1505  // STDLINE(string("fRootPath: ") + fRootPath, ACGreen);
1506  // rootFile = TFile::Open(fRootPath.c_str());
1507  // }
1508  // string cmd = string("ls -la ") + fRootPath;
1509  // system(cmd.c_str());
1510  // // STDLINE(string("before regexp fRootPath: ")+fRootPath,ACGreen) ;
1511  // // fRootPath = rootFile->GetName() ; // Bisogna strippare via il full path!!!
1512  // // boost::regex regg(fSystemPath.c_str()) ;
1513  // // fRootPath = boost::regex_replace(fRootPath,regg,"/") ; // Dario: should be
1514  // // transparent for Ryan's purposes but required by Extjs STDLINE(string("after
1515  // // regexp fRootPath: ")+fRootPath,ACGreen) ;
1516  // STDLINE(std::string("fSystemPath : ") + fSystemPath, ACCyan);
1517  // STDLINE(std::string("fRootPath : ") + fRootPath, ACCyan);
1518  // STDLINE(std::string("fFoldersPath : ") + fFoldersPath, ACCyan);
1519  // STDLINE(std::string("fHistName : ") + fHistName, ACCyan);
1520  // STDLINE(std::string("fRFoldersPath: ") + fRFoldersPath, ACCyan);
1521  // STDLINE(std::string("fFileName : ") + fFileName, ACCyan);
1522  // RootFileExplorer* theExplorer = new RootFileExplorer(fSystemPath,
1523  // fRootPath,
1524  // fFoldersPath,
1525  // fHistName,
1526  // fRFoldersPath,
1527  // fFileName,
1528  // rootFile);
1529  // xmlOut.setDocument(theExplorer->initialize(true));
1530  // // std::ostringstream* out ;
1531  // // xmlOut.outputXmlDocument((std::ostringstream*) out, true);
1532  // }
1533  else if(
1534  requestType ==
1535  "saveConfiguration") // ################################################################################################################
1536  {
1537  std::string configPayload = CgiDataUtilities::postData(cgiIn, "configPayload");
1538  STDLINE("configPayload: ", ACRed);
1539  STDLINE(configPayload, ACYellow);
1540 
1541  fstream outFile;
1542  outFile.open("/tmp/configPayload.json", ios::out | ios::app);
1543  outFile << configPayload << endl;
1544  outFile.close();
1545  }
1546  else if(
1547  requestType ==
1548  "getConfiguration") // ################################################################################################################
1549  {
1550  std::string configPayload = CgiDataUtilities::postData(cgiIn, "configPayload");
1551  std::string JSONPayLoad = "";
1552  std::string line = "";
1553 
1554  ifstream JSONFile("/tmp/configPayload.json");
1555 
1556  if(JSONFile.is_open())
1557  {
1558  while(getline(JSONFile, line))
1559  {
1560  JSONPayLoad += line;
1561  }
1562  JSONFile.close();
1563  }
1564 
1565  xmlOut.addTextElementToData("JSONPayLoad", JSONPayLoad);
1566  // std::ostringstream* out ;
1567  // xmlOut.outputXmlDocument((std::ostringstream*) out, true);
1568  }
1569  else if(
1570  requestType ==
1571  "getState") // ################################################################################################################
1572  {
1573  std::string fsmName = theStateMachine_.getCurrentStateName();
1574  bool in_transition = theStateMachine_.isInTransition();
1575 
1576  xmlOut.addTextElementToData("current_state", fsmName);
1577  xmlOut.addTextElementToData("in_transition", in_transition ? "1" : "0");
1578  }
1579  else
1580  {
1581  __SUP_SS__ << "requestType Request, " << requestType
1582  << ", not recognized by the Visual Supervisor (was it intended for "
1583  "another Supervisor?)."
1584  << __E__;
1585  __SUP_SS_THROW__;
1586  }
1587 
1588  if(theDataManager_ != nullptr)
1589  theDataManager_->setDoNotStop(false);
1590 
1591 } //end request()
static std::string postData(cgicc::Cgicc &cgi, const std::string &needle)
static std::string getData(cgicc::Cgicc &cgi, const std::string &needle)
bool isDisconnected(void) const
ConfigurationTree getNode(const std::string &nodeName, bool doNotThrowOnBrokenUIDLinks=false) const
const std::string & getValueAsString(bool returnLinkTableValue=false) const
WebUsers::permissionLevel_t getSupervisorPropertyUserPermissionsThreshold(const std::string &requestType)
virtual void transitionHalting(toolbox::Event::Reference event)
static void deleteInstance(std::string instanceUID)
void copyDataChildren(HttpXmlDocument &document)
bool loadXmlDocument(const std::string &filePath)
void outputXmlDocument(std::ostringstream *out, bool dispStdOut=false, bool allowWhiteSpace=false, bool printErrors=false)
const std::vector< DQMHistosBase * > & getLiveDQMs(void)
virtual void setSupervisorPropertyDefaults(void) override
virtual void forceSupervisorPropertyValues(void) override
virtual void transitionConfiguring(toolbox::Event::Reference e) override
virtual void request(const std::string &requestType, cgicc::Cgicc &cgiIn, HttpXmlDocument &xmlOut, const WebUsers::RequestUserInfo &userInfo) override
void setDarioStyle(bool darioStyle)
void saveXmlDocument(const std::string &filePath)
void INIT_MF(const char *name)
static std::string binaryStringToHexString(const void *binaryBuffer, unsigned int numberOfBytes, const std::string &resultPreamble="", const std::string &resultDelimiter="")