npdet_to_teve.cxx
Go to the documentation of this file.
1 #include "Math/Vector3D.h"
2 #include "Math/Vector4D.h"
3 #include "Math/VectorUtil.h"
4 #include "TCanvas.h"
5 #include "TLegend.h"
6 #include "TMath.h"
7 #include "TRandom3.h"
8 #include "TFile.h"
9 #include "TH1F.h"
10 #include "TH2F.h"
11 #include "TH1D.h"
12 #include "TH2D.h"
13 #include "TTree.h"
14 #include "TF1.h"
15 
16 #include <vector>
17 #include <tuple>
18 #include <algorithm>
19 #include <iterator>
20 #include <thread>
21 #include <experimental/filesystem>
22 namespace fs = std::experimental::filesystem;
23 
24 // DD4hep
25 // -----
26 // In .rootlogon.C
27 // gSystem->Load("libDDDetectors");
28 // gSystem->Load("libDDG4IO");
29 // gInterpreter->AddIncludePath("/opt/software/local/include");
30 #include "DD4hep/Detector.h"
31 #include "DD4hep/Printout.h"
32 #include "DDG4/Geant4Data.h"
33 #include "DDRec/CellIDPositionConverter.h"
34 #include "DDRec/SurfaceManager.h"
35 #include "DDRec/Surface.h"
36 #include "DD4hep/DD4hepUnits.h"
37 
38 #include "TApplication.h"
39 #include "TMultiGraph.h"
40 #include "TGraph.h"
41 
42 #include "TGeoManager.h"
43 #include "TGeoNode.h"
44 #include "TGeoVolume.h"
45 #include "TEveManager.h"
46 #include "TEveGeoNode.h"
47 #include "TEveGeoShapeExtract.h"
48 #include "TEveGeoShape.h"
49 #include "TEveBrowser.h"
50 #include "TSystem.h"
51 #include "ROOT/TFuture.hxx"
52 
53 #include "Math/DisplacementVector3D.h"
54 
55 #include <iostream>
56 #include <string>
57 #include <chrono>
58 
59 #include "clipp.h"
60 using namespace clipp;
61 //______________________________________________________________________________
62 
63 enum class mode { none, help, list, part };
64 
65 struct settings {
66  bool help = false;
67  bool success = false;
68  std::string infile = "";
69  std::string outfile = "detector_geometry";
70  std::string p_name = "";
71  int part_level = -1;
72  bool level_set = false;
73  int geo_level = -1;
74  bool list_all = false;
75  mode selected = mode::list;
76  int color = 1;
77  double alpha = 1;
78  std::map<std::string,int> part_name_levels;
79  std::map<std::string,int> part_name_colors;
80  std::map<std::string,double> part_name_alphas;
81 };
82 //______________________________________________________________________________
83 
84 void run_list_mode(const settings& s);
85 void run_part_mode(const settings& s);
86 //______________________________________________________________________________
87 
88 template<typename T>
89 void print_usage(T cli, const char* argv0 )
90 {
91  //used default formatting
92  std::cout << "Usage:\n" << usage_lines(cli, argv0)
93  << "\nOptions:\n" << documentation(cli) << '\n';
94 }
95 //______________________________________________________________________________
96 
97 template<typename T>
98 void print_man_page(T cli, const char* argv0 ){
99  //all formatting options (with their default values)
100  auto fmt = clipp::doc_formatting{}
101  .start_column(8) //column where usage lines and documentation starts
102  .doc_column(20) //parameter docstring start col
103  .indent_size(4) //indent of documentation lines for children of a documented group
104  .line_spacing(0) //number of empty lines after single documentation lines
105  .paragraph_spacing(1) //number of empty lines before and after paragraphs
106  .flag_separator(", ") //between flags of the same parameter
107  .param_separator(" ") //between parameters
108  .group_separator(" ") //between groups (in usage)
109  .alternative_param_separator("|") //between alternative flags
110  .alternative_group_separator(" | ") //between alternative groups
111  .surround_group("(", ")") //surround groups with these
112  .surround_alternatives("(", ")") //surround group of alternatives with these
113  .surround_alternative_flags("", "") //surround alternative flags with these
114  .surround_joinable("(", ")") //surround group of joinable flags with these
115  .surround_optional("[", "]") //surround optional parameters with these
116  .surround_repeat("", "..."); //surround repeatable parameters with these
117  //.surround_value("<", ">") //surround values with these
118  //.empty_label("") //used if parameter has no flags and no label
119  //.max_alternative_flags_in_usage(1) //max. # of flags per parameter in usage
120  //.max_alternative_flags_in_doc(2) //max. # of flags per parameter in detailed documentation
121  //.split_alternatives(true) //split usage into several lines for large alternatives
122  //.alternatives_min_split_size(3) //min. # of parameters for separate usage line
123  //.merge_alternative_flags_with_common_prefix(false) //-ab(cdxy|xy) instead of -abcdxy|-abxy
124  //.merge_joinable_flags_with_common_prefix(true); //-abc instead of -a -b -c
125 
126  auto mp = make_man_page(cli, argv0, fmt);
127  mp.prepend_section("DESCRIPTION", "Geometry tool for converting compact files to STEP (cad) files.");
128  mp.append_section("EXAMPLES", " $ npdet_to_teve list compact.xml");
129  std::cout << mp << "\n";
130 }
131 //______________________________________________________________________________
132 
133 settings cmdline_settings(int argc, char* argv[])
134 {
135  settings s;
136  auto listMode = "list mode:" % repeatable(
137  command("list").set(s.selected,mode::list) % "list detectors and print info about geometry ",
138  repeatable(
139  option("-l","--level").set(s.level_set)
140  & value("level",s.part_level)
141  & value("name")([&](const std::string& p)
142  {
143  s.p_name = p;
144  if(!s.level_set) { s.part_level = -1; }
145  s.part_name_levels[p] = s.part_level;
146  s.level_set = false;
147  }) % "Part/Node name (must be child of top node)"
148  )
149  );
150 
151  auto partMode = "part mode:" % repeatable(
152  command("part").set(s.selected,mode::part) % "Select only the first level nodes by name",
153  //(
154  //repeatable(
155  // required("-l","--level").set(s.level_set) & integer("level",s.part_level) % "Maximum level navigated to for part",
156  // value("name")([&](const std::string& p)
157  // {
158  // s.color++;
159  // s.p_name = p;
160  // if(!s.level_set) { s.p_level = -1; }
161  // s.level_set = false;
162  // s.part_name_levels[p] = s.part_level;
163  // s.part_name_colors[p] = s.color;
164  // s.part_name_alphas[p] = s.alpha;
165  // }) % "Part/Node name (must be child of top node)"
166  // ) |
167  //repeatable(
168  // required("-l","--level").set(s.level_set) & integer("level",s.part_level) % "Maximum level navigated to for part",
169  // required("-c","--color") & integer("color",s.color),
170  // value("name")([&](const std::string& p)
171  // {
172  // s.p_name = p;
173  // if(!s.level_set) { s.part_level = -1; }
174  // s.level_set = false;
175  // s.part_name_levels[p] = s.part_level;
176  // s.part_name_colors[p] = s.color;
177  // s.part_name_alphas[p] = s.alpha;
178  // }) % "Part/Node name (must be child of top node)"
179  // )|
180  repeatable(
181  required("-l","--level").set(s.level_set) & integer("level",s.part_level) % "Maximum level navigated to for part",
182  option("-c","--color") & integer("color",s.color),
183  option("-a","--alpha") & number("alpha",s.alpha),
184  value("name")([&](const std::string& p)
185  {
186  s.p_name = p;
187  if(!s.level_set) { s.part_level = -1; }
188  s.level_set = false;
189  std::cout << "s.color " << s.color << "\n";
190  std::cout << "s.alpha " << s.alpha << "\n";
191  s.part_name_levels[p] = s.part_level;
192  s.part_name_colors[p] = s.color;
193  s.part_name_alphas[p] = s.alpha;
194  }) % "Part/Node name (must be child of top node)"
195  )
196  //|
197  //repeatable(
198  // required("-l","--level").set(s.level_set) & integer("level",s.part_level) % "Maximum level navigated to for part",
199  // required("-c","--color") & integer("color",s.color),
200  // required("-t","--transparency") & number("transparency",s.alpha),
201  // value("name")([&](const std::string& p)
202  // {
203  // s.p_name = p;
204  // if(!s.level_set) { s.part_level = -1; }
205  // s.level_set = false;
206  // s.part_name_levels[p] = s.part_level;
207  // s.part_name_colors[p] = s.color;
208  // s.part_name_alphas[p] = 1.0 - s.alpha;
209  // }) % "Part/Node name (must be child of top node)"
210  // )
211  //)
212  );
213 
214  auto lastOpt = " options:" % (
215  option("-h", "--help").set(s.selected, mode::help) % "show help",
216  option("-g","--global_level") & integer("level",s.geo_level),
217  option("-o","--output") & value("out",s.outfile),
218  value("file",s.infile).if_missing([]{ std::cout << "You need to provide an input xml filename as the last argument!\n"; } )
219  % "input xml file"
220  );
221 
222  std::string wrong;
223  auto cli = (
224  command("help").set(s.selected, mode::help) | (partMode | listMode , lastOpt),
225  any_other(wrong)
226  );
227 
228 
229  assert( cli.flags_are_prefix_free() );
230 
231  auto res = parse(argc, argv, cli);
232 
233  std::cout << "wrong " << wrong << std::endl;
234 
235  //if( res.any_error() ) {
236  // s.success = false;
237  // std::cout << make_man_page(cli, argv[0]).prepend_section("error: ",
238  // " The best thing since sliced bread.");
239  // return s;
240  //}
241  s.success = true;
242 
243  if(s.selected == mode::help) {
244  print_man_page<decltype(cli)>(cli,argv[0]);
245  };
246  return s;
247 }
248 //______________________________________________________________________________
249 
250 
251 int main (int argc, char *argv[]) {
252 
253  settings s = cmdline_settings(argc,argv);
254  if( !s.success ) {
255  return 1;
256  }
257 
258  if(s.selected == mode::help) {
259  return 0;
260  }
261 
262  // ------------------------
263  // CLI Checks
264  if( !fs::exists(fs::path(s.infile)) ) {
265  std::cerr << "file, " << s.infile << ", does not exist\n";
266  return 1;
267  }
268  auto has_suffix = [&](const std::string &str, const std::string &suffix) {
269  return str.size() >= suffix.size() &&
270  str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
271  };
272  if( !has_suffix(s.outfile,".root") ) {
273  s.outfile += ".root";
274  }
275  //for(const auto& [part_name, part_level] : s.part_name_levels ) {
276  // std::cout << " SOME Part : " << part_name << ", level = " << part_level <<"\n";
277  //}
278 
279  // ---------------------------------------------
280  // Run modes
281  //
282  switch(s.selected) {
283  case mode::list:
284  run_list_mode(s);
285  break;
286  case mode::part:
287  run_part_mode(s);
288  break;
289  default:
290  break;
291  }
292 
293  return 0;
294 }
295 //______________________________________________________________________________
296 
297 
298 void run_list_mode(const settings& s)
299 {
300  dd4hep::setPrintLevel(dd4hep::WARNING);
301  gErrorIgnoreLevel = kWarning;// kPrint, kInfo, kWarning,
302 
303  // -------------------------
304  // Get the DD4hep instance
305  dd4hep::Detector& detector = dd4hep::Detector::getInstance();
306  detector.fromCompact(s.infile);
307 
308  std::cout << gGeoManager->GetPath() << "\n";
309 
310  for(const auto& [p,l] : s.part_name_levels) {
311  bool dir = gGeoManager->cd(p.c_str());
312  if (!dir) {
313  std::cerr << p << " not found!\n";
314  continue;
315  }
316  TGeoNode *node = gGeoManager->GetCurrentNode();
317  int level = gGeoManager->GetLevel();
318  if( level > l ){
319  std::cout << "\n" << p << " found at level " << level << " but above selected level of " << l << ")\n";
320  continue;
321  }
322  std::cout << "\n";
323  std::cout << "Subnodes for \"" << p << "\" (level = " << level << ")\n";
324  if(node->GetNdaughters() == 0) {
325  continue;
326  }
327  TObjArrayIter node_array_iter(node->GetVolume()->GetNodes());
328  TGeoNode* a_node = nullptr;
329  while( (a_node = dynamic_cast<TGeoNode*>(node_array_iter.Next())) ) {
330  std::cout << p << "/" << a_node->GetName() << "\n";
331  }
332 
333  //TGeoNode* currentNode = nullptr;
334  //auto res = new TEveGeoNode(node);
335  //TGeoIterator nextNode( node->GetVolume() );
336  //nextNode.SetType(1);
337  //while( (currentNode = nextNode()) ) {
338  // auto nlevel = nextNode.GetLevel();
339  // if( nlevel > l-level ) {
340  // break;
341  // }
342  // //auto daughter = new TEveGeoNode( currentNode );
343  // //res->AddElement(daughter);
344  // currentNode->ls();
345  //}
346  }
347 }
348 //______________________________________________________________________________
349 
350 void run_part_mode(const settings& s)
351 {
352  int root_argc = 0;
353  char *root_argv[1] = {"npdet_to_teve"};
354  //argv[0] = "npdet_fields";
355 
356  gErrorIgnoreLevel = kWarning;// kPrint, kInfo, kWarning,
357  TApplication app("tapp", &root_argc, root_argv);
358 
359  // Get the DD4hep instance
360  dd4hep::setPrintLevel(dd4hep::WARNING);
361  dd4hep::Detector& detector = dd4hep::Detector::getInstance();
362  detector.fromCompact(s.infile);
363 
364  TEveManager::Create();//true,"");
365 
366  TEveGeoTopNode* eve_top_n = new TEveGeoTopNode(&(detector.manager()),detector.manager().GetTopNode());
367  detector.manager().GetTopNode()->SetVisibility(kFALSE);
368  eve_top_n->SetVisLevel(0);
369  std::cout << "Path is " << gGeoManager->GetPath() << "\n";
370 
371  for(const auto& [p,l] : s.part_name_levels) {
372  bool dir = gGeoManager->cd(p.c_str());
373  if (!dir) {
374  std::cerr << p << " not found!\n";
375  return;
376  }
377  TGeoNode *node = gGeoManager->GetCurrentNode();
378  if(!node){
379  std::cerr << " bad node\n";
380  return;
381  }
382  int ilevel = gGeoManager->GetLevel();
383  if( ilevel > l ){
384  std::cout << p << " found at level " << ilevel << " but above selected level of " << l << "\n";
385  //return;
386  }
387 
388  int istate = gGeoManager->GetCurrentNodeId();
389  std::string ipath = gGeoManager->GetPath();
390 
391  auto pcolor = s.part_name_colors.find(p)->second;
392  auto ptransparency = 100.0*(1.0 - s.part_name_alphas.find(p)->second);
393 
394  std::cout << " color " << pcolor << "\n";
395  std::cout << " ptransparency " << ptransparency << "\n";
396 
397  node->GetVolume()->SetLineColor(pcolor);
398  node->GetVolume()->SetFillColor(pcolor);
399  node->GetVolume()->SetTransparency(ptransparency);
400  node->GetVolume()->SetTransparency(ptransparency);
401 
402 
403  TEveGeoNode* res = new TEveGeoNode(node);
404  std::map<int,TEveGeoNode*> eve_nodes;
405  eve_nodes[0] = res;
406 
407  TGeoIterator nextNode( node->GetVolume() );
408  int path_index = 0;
409  TGeoNode* currentNode = nullptr;
410 
411  while( (currentNode = nextNode()) ) {
412  nextNode.SetType(0);
413  // Not iterator level starts at 1
414  auto nlevel = nextNode.GetLevel();
415  if( nlevel > l ) {
416  continue;
417  }
418  //if( path_index == nlevel) {
419  // if(pcolor != s.part_name_colors.end() ){
420  currentNode->GetVolume()->SetLineColor(pcolor);
421  currentNode->GetVolume()->SetFillColor(pcolor);
422  currentNode->GetVolume()->SetTransparency(ptransparency);
423  currentNode->GetVolume()->SetTransparency(ptransparency);
424  // }
425  TEveGeoNode* daughter = new TEveGeoNode( currentNode );
426  eve_nodes[nlevel] = daughter;
427  eve_nodes[nlevel-1]->AddElement(daughter);
428  //}
429  //std::cout << nlevel << "\n";
430  //std::cout << gGeoManager->PushPath() << "\n";
431 
432  //res->AddElement(daughter);
433  currentNode->ls();
434  }
435  eve_top_n->AddElement(res);
436  }
437 
438  eve_top_n->SaveExtract(s.outfile.c_str(), "extract", kTRUE);
439 
440  //--------------------------------------------
441  // Now Quit ... it is harder than it should be.
442  app.Run(kFALSE);
443  TEveManager::Terminate();
444  app.Terminate(0);
445 
446  //std::cout << "derp1 \n";
447  //ROOT::EnableImplicitMT(2);
449  //auto wi0 = ROOT::Experimental::Async([&](){app.Run(kFALSE); return std::string("done1");});
450  //auto wi1 = ROOT::Experimental::Async([&]() {
451  // //using namespace std::chrono_literals;
452  // std::cout << "Hello waiter" << std::endl;
453  // gEve->GetBrowser()->CloseWindow();
454  // gSystem->ProcessEvents() ;
455  // std::chrono::seconds sec(2);
456  // std::this_thread::sleep_for(sec);
457  // std::cout << "Hello waiter" << std::endl;
458  // app.Terminate(0);
459  // std::cout << " " << wi0.get() << std::endl;
460  // return std::string("done 2");
461  //});
463  //std::cout << " " << wi1.get() << std::endl;
469  //std::cout << "derp \n";
470 }
471 
void run_list_mode(const settings &s)
std::map< std::string, int > part_name_levels
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
std::map< std::string, int > part_name_colors
doc_formatting & indent_size(int indent)
determines indent of documentation lines for children of a documented group
Definition: clipp.h:5083
detail::assign_value< T, V > set(T &target, V value)
makes function object with a const char* parameter that assigns a value to a ref-captured object
Definition: clipp.h:1055
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
parameter repeatable(parameter p)
makes a repeatable copy of a parameter
Definition: clipp.h:3592
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
double alpha
std::string p_name
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
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
settings cmdline_settings(int argc, char *argv[])
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
void print_man_page(T cli, const char *argv0)
parameter required(String &&flag, Strings &&... flags)
makes required non-blocking exact match parameter
Definition: clipp.h:2063
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
void print_usage(T cli, const char *argv0)
doc_formatting & surround_repeat(const string &prefix, const string &postfix)
determnines strings surrounding repeatable parameters/groups
Definition: clipp.h:5151
parameter number(const doc_string &label, Targets &&... tgts)
makes required, blocking value parameter; matches any string that represents a number
Definition: clipp.h:2286
generates parameter and group documentation from docstrings
Definition: clipp.h:5781
parameter any_other(Targets &&... tgts)
makes catch-all value parameter
Definition: clipp.h:2429
void run_part_mode(const settings &s)
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