DD4hep  1.31.0
Detector Description Toolkit for High Energy Physics
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
JsonProcessor.cpp
Go to the documentation of this file.
1 //==========================================================================
2 // AIDA Detector description implementation
3 //--------------------------------------------------------------------------
4 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
5 // All rights reserved.
6 //
7 // For the licensing terms see $DD4hepINSTALL/LICENSE.
8 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
9 //
10 // Author : M.Frank
11 //
12 //==========================================================================
13 
28 // Framework inlcude files
29 #define BOOST_BIND_GLOBAL_PLACEHOLDERS
30 #include <JSON/Helper.h>
31 #include <JSON/DocumentHandler.h>
32 #include <JSON/Conversions.h>
33 #include <DD4hep/Plugins.h>
34 #include <DD4hep/Printout.h>
35 #include <DD4hep/IDDescriptor.h>
39 
40 // C/C++ include files
41 #include <boost/property_tree/json_parser.hpp>
42 
43 namespace {
44  class Json;
45  class detector;
46 }
47 
48 using namespace dd4hep;
49 
50 static void setChildTitles(const std::pair<std::string, DetElement>& e) {
51  DetElement parent = e.second.parent();
52  const DetElement::Children& children = e.second.children();
53  if (::strlen(e.second->GetTitle()) == 0) {
54  e.second->SetTitle(parent.isValid() ? parent.type().c_str() : e.first.c_str());
55  }
56  for_each(children.begin(), children.end(), setChildTitles);
57 }
58 
59 namespace dd4hep {
60  template <> void Converter<detector>::operator()(json_h element) const;
61 }
62 
64 template <> void Converter<detector>::operator()(json_h element) const {
65  std::string type = element.attr<std::string>(_U(type));
66  std::string name = element.attr<std::string>(_U(name));
67  std::string name_match = ":" + name + ":";
68  std::string type_match = ":" + type + ":";
69 
70  try {
71  json_attr_t attr_par = element.attr_nothrow(_U(parent));
72  if (attr_par) {
73  // We have here a nested detector. If the mother volume is not yet registered
74  // it must be done here, so that the detector constructor gets the correct answer from
75  // the call to Detector::pickMotherVolume(DetElement).
76  std::string par_name = element.attr<std::string>(attr_par);
77  DetElement parent_detector = description.detector(par_name);
78  if ( !parent_detector.isValid() ) {
79  except("Compact","Failed to access valid parent detector of %s",name.c_str());
80  }
81  description.declareParent(name, parent_detector);
82  }
83  json_attr_t attr_ro = element.attr_nothrow(_U(readout));
85  Segmentation seg;
86  if ( attr_ro ) {
87  Readout ro = description.readout(element.attr<std::string>(attr_ro));
88  if (!ro.isValid()) {
89  throw std::runtime_error("No Readout structure present for detector:" + name);
90  }
91  seg = ro.segmentation();
92  sd = SensitiveDetector(name, "sensitive");
93  sd.setHitsCollection(ro.name());
94  sd.setReadout(ro);
95  description.addSensitiveDetector(sd);
96  }
97  Handle<NamedObject> sens = sd;
98  DetElement det(PluginService::Create<NamedObject*>(type, &description, &element, &sens));
99  if (det.isValid()) {
100  setChildTitles(std::make_pair(name, det));
101  if ( sd.isValid() ) {
103  }
104  if ( seg.isValid() ) {
105  seg->sensitive = sd;
106  seg->detector = det;
107  }
108  }
109  printout(det.isValid() ? INFO : ERROR, "Compact", "%s subdetector:%s of type %s %s",
110  (det.isValid() ? "++ Converted" : "FAILED "), name.c_str(), type.c_str(),
111  (sd.isValid() ? ("[" + sd.type() + "]").c_str() : ""));
112 
113  if (!det.isValid()) {
114  PluginDebug dbg;
115  PluginService::Create<NamedObject*>(type, &description, &element, &sens);
116  throw std::runtime_error("Failed to execute subdetector creation plugin. " + dbg.missingFactory(type));
117  }
118  description.addDetector(det);
119  return;
120  }
121  catch (const std::exception& e) {
122  printout(ERROR, "Compact", "++ FAILED to convert subdetector: %s: %s", name.c_str(), e.what());
123  std::terminate();
124  }
125  catch (...) {
126  printout(ERROR, "Compact", "++ FAILED to convert subdetector: %s: %s", name.c_str(), "UNKNONW Exception");
127  std::terminate();
128  }
129 }
130 
131 static long handle_json(Detector& description, int argc, char** argv) {
132  if ( argc < 1 || (argc<2 && argv[0][0] != '/') ) {
133  ::printf("DD4hep_JsonProcessor <file> <directory> \n"
134  " If file is an absolute path (does NOT start with '/')\n"
135  " the directory path is mandatory. \n"
136  " The file name is then assumed to be relative. \n"
137  "\n");
138  exit(EINVAL);
139  }
140  std::string file = argv[0];
141  if ( file[0] != '/' ) file = std::string(argv[1]) + "/" + file;
142 
143  printout(INFO,"JsonProcessor","++ Processing JSON input: %s",file.c_str());
144  json::DocumentHolder doc(json::DocumentHandler().load(file.c_str()));
145  json::Element elt = doc.root();
146 
147  json_coll_t(elt,_U(detector)).for_each(Converter<detector>(description));
148  printout(INFO,"JsonProcessor","++ ... Successfully processed JSON input: %s",file.c_str());
149  return 1;
150 }
151 DECLARE_APPLY(DD4hep_JsonProcessor,handle_json)
dd4hep::DetElement::children
const Children & children() const
Access to the list of children.
Definition: DetElement.cpp:207
dd4hep::SensitiveDetector
Handle class to hold the information of a sensitive detector.
Definition: DetElement.h:43
dd4hep::DetElement::parent
DetElement parent() const
Access to the detector elements's parent.
Definition: DetElement.cpp:239
dd4hep::exception
void exception(const std::string &src, const std::string &msg)
Definition: RootDictionary.h:69
dd4hep::DetElement::type
std::string type() const
Access detector type (structure, tracker, calorimeter, etc.).
Definition: DetElement.cpp:97
dd4hep::json::Handle_t::attr
T attr(const Attribute a) const
Access typed attribute value by the JsonAttr.
Definition: Elements.h:182
dd4hep::SensitiveDetector::setHitsCollection
SensitiveDetector & setHitsCollection(const std::string &spec)
Assign the name of the hits collection.
Definition: DetElement.cpp:441
dd4hep::Segmentation::sensitive
Handle< SensitiveDetectorObject > sensitive() const
Access the sensitive detector using this segmentation object.
Definition: Segmentations.cpp:125
DECLARE_APPLY
#define DECLARE_APPLY(name, func)
Definition: Factories.h:281
Helper.h
dd4hep::Handle::isValid
bool isValid() const
Check the validity of the object held by the handle.
Definition: Handle.h:126
dd4hep::Handle< NamedObject >
dd4hep::Segmentation::detector
Handle< DetElementObject > detector() const
Access the main detector element using this segmentation object.
Definition: Segmentations.cpp:120
DetectorInterna.h
dd4hep::json::DocumentHandler
Class supporting to read and parse XML documents.
Definition: DocumentHandler.h:33
dd4hep::Handle::name
const char * name() const
Access the object name (or "" if not supported by the object)
dd4hep::detail::printf
std::size_t printf(const char *fmt,...)
Definition: Printout.cpp:97
dd4hep::json::Handle_t::attr_nothrow
Attribute attr_nothrow(const char *tag) const
Access attribute pointer by the attribute's unicode name (no exception thrown if not present)
Definition: Elements.cpp:261
json_coll_t
dd4hep::json::Collection_t json_coll_t
Definition: Helper.h:25
dd4hep::DetElement
Handle class describing a detector element.
Definition: DetElement.h:187
dd4hep::DetElementObject::flag
unsigned int flag
Flag to remember internally calculated quatities.
Definition: DetectorInterna.h:100
_U
#define _U(a)
Definition: Tags.h:23
Plugins.h
dd4hep::PluginDebug
Helper to debug plugin manager calls.
Definition: Plugins.h:73
dd4hep::json::Collection_t::for_each
void for_each(T oper) const
Loop processor using function object.
Definition: Elements.h:265
dd4hep::SensitiveDetector::setReadout
SensitiveDetector & setReadout(Readout readout)
Assign the IDDescriptor reference.
Definition: DetElement.cpp:414
dd4hep::Readout::segmentation
Segmentation segmentation() const
Access segmentation structure.
Definition: Readout.cpp:134
dd4hep::PluginDebug::missingFactory
std::string missingFactory(const std::string &name) const
Helper to check factory existence.
Definition: Plugins.cpp:147
dd4hep::SensitiveDetector::type
std::string type() const
Access the type of the sensitive detector.
Definition: DetElement.cpp:409
Conversions.h
SegmentationsInterna.h
dd4hep::json::DocumentHolder
Class supporting the basic functionality of an JSON document including ownership.
Definition: Elements.h:331
dd4hep::DetElement::Children
std::map< std::string, DetElement > Children
Definition: DetElement.h:205
IDDescriptor.h
ObjectsInterna.h
dd4hep
Namespace for the AIDA detector description toolkit.
Definition: AlignmentsCalib.h:28
det
DetElement::Object * det
Definition: AlignmentsCalculator.cpp:66
dd4hep::json::Handle_t
Class to easily access the properties of single JsonElements.
Definition: Elements.h:134
dd4hep::Detector
The main interface to the dd4hep detector description package.
Definition: Detector.h:90
dd4hep::Readout
Handle to the implementation of the readout structure of a subdetector.
Definition: Readout.h:38
dd4hep::Segmentation
Handle class supporting generic Segmentations of sensitive detectors.
Definition: Segmentations.h:41
json_attr_t
dd4hep::json::Attribute json_attr_t
Definition: Helper.h:24
dd4hep::DetElementObject::HAVE_SENSITIVE_DETECTOR
@ HAVE_SENSITIVE_DETECTOR
Definition: DetectorInterna.h:92
dd4hep::json::Element
User abstraction class to manipulate JSON elements within a document.
Definition: Elements.h:357
Printout.h
DocumentHandler.h