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