dd_web_display.cxx
Go to the documentation of this file.
1 #include "TApplication.h"
2 #include "TCanvas.h"
3 #include "TEveBrowser.h"
4 #include "TEveGeoNode.h"
5 #include "TEveGeoShape.h"
6 #include "TEveGeoShapeExtract.h"
7 #include "TEveManager.h"
8 #include "TFile.h"
9 #include "TGeoManager.h"
10 #include "TGeoNode.h"
11 #include "TGeoVolume.h"
12 #include "TGraph.h"
13 #include "THttpServer.h"
14 #include "TLegend.h"
15 #include "TMath.h"
16 #include "TMessage.h"
17 #include "TMonitor.h"
18 #include "TMultiGraph.h"
19 #include "TServerSocket.h"
20 #include "TSocket.h"
21 #include "TSystem.h"
22 
23 #include <algorithm>
24 #include <chrono>
25 #include <csignal>
26 #include <cstring>
27 #include <experimental/filesystem>
28 #include <functional>
29 #include <iostream>
30 #include <iterator>
31 #include <map>
32 #include <memory>
33 #include <stdexcept>
34 #include <string>
35 #include <thread>
36 #include <tuple>
37 #include <vector>
38 
39 #include "DD4hep/DD4hepUnits.h"
40 #include "DD4hep/Detector.h"
41 #include "DD4hep/Printout.h"
42 #include "DDG4/Geant4Data.h"
43 #include "DDRec/CellIDPositionConverter.h"
44 #include "DDRec/Surface.h"
45 #include "DDRec/SurfaceManager.h"
46 
47 #include "spdlog/spdlog.h"
48 #include "spdlog/sinks/basic_file_sink.h"
49 
50 namespace fs = std::experimental::filesystem;
51 
52 volatile sig_atomic_t sig_caught = 0;
53 
54 void handle_sig(int signum) {
55  /* in case we registered this handler for multiple signals */
56  if (signum == SIGINT) {
57  sig_caught = 1;
58  }
59  if (signum == SIGTERM) {
60  sig_caught = 2;
61  }
62  if (signum == SIGABRT) {
63  sig_caught = 3;
64  }
65 }
66 
67 #include "clipp.h"
68 using namespace clipp;
69 using std::string;
70 //______________________________________________________________________________
71 
72 enum class mode { none, help, list, part };
73 
74 struct settings {
75  bool help = false;
76  bool success = false;
77  std::string compact_file = "";
78  std::string infile = "";
79  std::string outfile = "detector_geometry";
80  std::string p_name = "";
81  int part_level = -1;
82  bool level_set = false;
83  int geo_level = -1;
84  bool list_all = false;
85  mode selected = mode::list;
86  int color = 1;
87  double alpha = 1;
88  std::map<std::string,int> part_name_levels;
89  std::map<std::string,int> part_name_colors;
90  std::map<std::string,double> part_name_alphas;
91  int http_port = 8090;
92  string http_host = "127.0.0.1";
93  string in_out_file = "";
94 };
95 
96 void run_http_server(const settings& s);
97 
98 template<typename T>
99 void print_usage(T cli, const char* argv0 )
100 {
101  //used default formatting
102  std::cout << "Usage:\n" << usage_lines(cli, argv0)
103  << "\nOptions:\n" << documentation(cli) << '\n';
104 }
105 //______________________________________________________________________________
106 
107 template<typename T>
108 void print_man_page(T cli, const char* argv0 ){
109  //all formatting options (with their default values)
110  auto fmt = clipp::doc_formatting{}
111  .start_column(8) //column where usage lines and documentation starts
112  .doc_column(20) //parameter docstring start col
113  .indent_size(4) //indent of documentation lines for children of a documented group
114  .line_spacing(0) //number of empty lines after single documentation lines
115  .paragraph_spacing(1) //number of empty lines before and after paragraphs
116  .flag_separator(", ") //between flags of the same parameter
117  .param_separator(" ") //between parameters
118  .group_separator(" ") //between groups (in usage)
119  .alternative_param_separator("|") //between alternative flags
120  .alternative_group_separator(" | ") //between alternative groups
121  .surround_group("(", ")") //surround groups with these
122  .surround_alternatives("(", ")") //surround group of alternatives with these
123  .surround_alternative_flags("", "") //surround alternative flags with these
124  .surround_joinable("(", ")") //surround group of joinable flags with these
125  .surround_optional("[", "]") //surround optional parameters with these
126  .surround_repeat("", "..."); //surround repeatable parameters with these
127  //.surround_value("<", ">") //surround values with these
128  //.empty_label("") //used if parameter has no flags and no label
129  //.max_alternative_flags_in_usage(1) //max. # of flags per parameter in usage
130  //.max_alternative_flags_in_doc(2) //max. # of flags per parameter in detailed documentation
131  //.split_alternatives(true) //split usage into several lines for large alternatives
132  //.alternatives_min_split_size(3) //min. # of parameters for separate usage line
133  //.merge_alternative_flags_with_common_prefix(false) //-ab(cdxy|xy) instead of -abcdxy|-abxy
134  //.merge_joinable_flags_with_common_prefix(true); //-abc instead of -a -b -c
135 
136  auto mp = make_man_page(cli, argv0, fmt);
137  mp.prepend_section("DESCRIPTION", "Web display for compact geometry.");
138  mp.append_section("EXAMPLES", " $ dd_web_display compact.xml");
139  std::cout << mp << "\n";
140 }
141 //______________________________________________________________________________
142 
143 settings cmdline_settings(int argc, char* argv[])
144 {
145  settings s;
146  auto lastOpt = " options:" % (
147  option("-h", "--help").set(s.selected, mode::help) % "show help",
148  option("-g","--global_level") & integer("level",s.geo_level),
149  option("-o","--output") & value("out",s.outfile),
150  value("file",s.infile).if_missing([]{
151  std::cout << "You need to provide an input xml filename as the last argument!\n";
152  } ) % "input xml file"
153  );
154 
155  auto server_cli =
156  ((option("-p", "--port") & value("http_port", s.http_port)) %
157  "port to which the http serve attaches. Default: 8090 ",
158  (option("-H", "--host") & value("http_host", s.http_host)) %
159  "Http server host name or IP address. Default: 127.0.0.1",
160  (option("-f", "--file") & value("io_file", s.in_out_file)) %
161  "File used to initialize and save plots. Default: top_folder.root");
162 
163  auto cli = (command("help").set(s.selected, mode::help) | (server_cli, lastOpt));
164 
165  assert( cli.flags_are_prefix_free() );
166 
167  auto res = parse(argc, argv, cli);
168 
169  //if( res.any_error() ) {
170  // s.success = false;
171  // std::cout << make_man_page(cli, argv[0]).prepend_section("error: ",
172  // " The best thing since sliced bread.");
173  // return s;
174  //}
175  s.success = true;
176 
177  if(s.selected == mode::help) {
178  print_man_page<decltype(cli)>(cli,argv[0]);
179  };
180  return s;
181 }
182 //______________________________________________________________________________
183 
184 int main (int argc, char *argv[]) {
185 
186  settings s = cmdline_settings(argc,argv);
187  if( !s.success ) {
188  return 1;
189  }
190 
191  if(s.selected == mode::help) {
192  return 0;
193  }
194 
195  // ------------------------
196  // CLI Checks
197  if( !fs::exists(fs::path(s.infile)) ) {
198  std::cerr << "file, " << s.infile << ", does not exist\n";
199  return 1;
200  }
201  auto has_suffix = [&](const std::string &str, const std::string &suffix) {
202  return str.size() >= suffix.size() &&
203  str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
204  };
205  if( !has_suffix(s.outfile,".root") ) {
206  s.outfile += ".root";
207  }
208 
209  run_http_server(s);
210 
211  return 0;
212 }
213 //______________________________________________________________________________
214 
215 void run_http_server(const settings& s) {
216  dd4hep::setPrintLevel(dd4hep::WARNING);
217  gErrorIgnoreLevel = kWarning;// kPrint, kInfo, kWarning,
218 
219  void (*prev_handler)(int);
220  prev_handler = signal(SIGINT, handle_sig);
221 
222  // -------------------------
223  // Get the DD4hep instance
224  dd4hep::Detector& detector = dd4hep::Detector::getInstance();
225  detector.fromCompact(s.infile);
226 
227  auto serv = new THttpServer((std::string("http:") + s.http_host + ":" +
228  std::to_string(s.http_port) +
229  std::string("?top=geometry&thrds=1;rw;noglobal"))
230  .c_str());
231 
232  spdlog::info("Creating display server at http://{}:{}",s.http_host,s.http_port);
233  if( !(serv->IsAnyEngine()) ) {
234  spdlog::error("Failed to start http server.");
235  std::exit(-1);
236  }
237  //_server->SetDefaultPage("online.htm");
238  //_server->SetDefaultPage("draw.htm");
239  serv->SetCors();
240 
241  detector.manager().GetTopNode()->SetVisibility(kFALSE);
242  gGeoManager->SetVisLevel(6);
243 
244  serv->Register("/",detector.manager().GetTopNode());
245  serv->Register("/geoManager",gGeoManager);
246 
247  // Loop until an interrupt (ctrl-c) is issued
248  while (1) {
249  serv->ProcessRequests();
250  if (sig_caught) {
251  break;
252  }
253  std::this_thread::sleep_for(std::chrono::milliseconds(100));
254 
255  }
256 
257  signal(SIGINT, prev_handler);
258 }
259 
std::map< std::string, int > part_name_levels
void handle_sig(int signum)
int main(int argc, char *argv[])
parameter value(const doc_string &label, Targets &&... tgts)
makes required, blocking, repeatable value parameter; matches any non-empty string
Definition: clipp.h:2094
primary namespace
Definition: clipp.h:36
doc_formatting & alternative_group_separator(const string &sep)
determines string for separating alternative groups
Definition: clipp.h:5116
void print_man_page(T cli, const char *argv0)
std::map< std::string, int > part_name_colors
void print_usage(T cli, const char *argv0)
doc_formatting & indent_size(int indent)
determines indent of documentation lines for children of a documented group
Definition: clipp.h:5083
man_page make_man_page(const group &params, doc_string progname="", const doc_formatting &fmt=doc_formatting{})
generates man sections from command line parameters with sections "synopsis" and "options"
Definition: clipp.h:6086
void run_http_server(const settings &s)
doc_formatting & start_column(int col)
determines column where documentation printing starts
Definition: clipp.h:5074
std::map< std::string, double > part_name_alphas
std::string outfile
parameter option(String &&flag, Strings &&... flags)
makes optional, non-blocking exact match parameter
Definition: clipp.h:2078
doc_formatting & surround_optional(const string &prefix, const string &postfix)
determnines strings surrounding optional parameters/groups
Definition: clipp.h:5141
doc_formatting & surround_alternative_flags(const string &prefix, const string &postfix)
determnines strings surrounding alternative flags
Definition: clipp.h:5171
doc_formatting & param_separator(const string &sep)
determines string for separating parameters
Definition: clipp.h:5095
string http_host
doc_formatting & alternative_param_separator(const string &sep)
determines string for separating alternative parameters
Definition: clipp.h:5109
parsing_result parse(arg_list args, const group &cli)
parses vector of arg strings and executes actions
Definition: clipp.h:4941
generates usage lines
Definition: clipp.h:5316
Derived & if_missing(simple_action a)
adds an action that will be called if a required parameter is missing
Definition: clipp.h:1252
string in_out_file
doc_formatting & line_spacing(int lines)
determines number of empty rows after one single-line documentation entry
Definition: clipp.h:5217
std::string infile
parameter integer(const doc_string &label, Targets &&... tgts)
makes required, blocking value parameter; matches any string that represents an integer
Definition: clipp.h:2358
doc_formatting & doc_column(int col)
determines column where docstrings start
Definition: clipp.h:5078
parameter command(String &&flag, Strings &&... flags)
makes required non-blocking exact match parameter
Definition: clipp.h:2048
doc_formatting & surround_group(const string &prefix, const string &postfix)
determnines strings surrounding non-exclusive groups
Definition: clipp.h:5181
Derived & set(Target &t)
adds an action that will set the value of 't' from a 'const char*' arg
Definition: clipp.h:1215
Detector
Definition: DDG4.py:69
documentation formatting options
Definition: clipp.h:5069
doc_formatting & flag_separator(const string &sep)
determines string for separating flags of the same parameter
Definition: clipp.h:5123
doc_formatting & surround_repeat(const string &prefix, const string &postfix)
determnines strings surrounding repeatable parameters/groups
Definition: clipp.h:5151
generates parameter and group documentation from docstrings
Definition: clipp.h:5781
volatile sig_atomic_t sig_caught
settings cmdline_settings(int argc, char *argv[])
doc_formatting & paragraph_spacing(int lines)
determines number of empty rows before and after a paragraph; a paragraph is defined by a documented ...
Definition: clipp.h:5226
doc_formatting & surround_alternatives(const string &prefix, const string &postfix)
determnines strings surrounding exclusive groups
Definition: clipp.h:5161
doc_formatting & group_separator(const string &sep)
determines string for separating groups (in usage lines)
Definition: clipp.h:5102
doc_formatting & surround_joinable(const string &prefix, const string &postfix)
determnines strings surrounding joinable groups
Definition: clipp.h:5191