DD4hep  1.30.0
Detector Description Toolkit for High Energy Physics
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 <iostream>
42 #include <boost/property_tree/json_parser.hpp>
43 
44 namespace {
45  class Json;
46  class detector;
47 }
48 
49 using namespace dd4hep;
50 
51 static void setChildTitles(const std::pair<std::string, DetElement>& e) {
52  DetElement parent = e.second.parent();
53  const DetElement::Children& children = e.second.children();
54  if (::strlen(e.second->GetTitle()) == 0) {
55  e.second->SetTitle(parent.isValid() ? parent.type().c_str() : e.first.c_str());
56  }
57  for_each(children.begin(), children.end(), setChildTitles);
58 }
59 
60 namespace dd4hep {
61  template <> void Converter<detector>::operator()(json_h element) const;
62 }
63 
65 template <> void Converter<detector>::operator()(json_h element) const {
66  std::string type = element.attr<std::string>(_U(type));
67  std::string name = element.attr<std::string>(_U(name));
68  std::string name_match = ":" + name + ":";
69  std::string type_match = ":" + type + ":";
70 
71  try {
72  json_attr_t attr_par = element.attr_nothrow(_U(parent));
73  if (attr_par) {
74  // We have here a nested detector. If the mother volume is not yet registered
75  // it must be done here, so that the detector constructor gets the correct answer from
76  // the call to Detector::pickMotherVolume(DetElement).
77  std::string par_name = element.attr<std::string>(attr_par);
78  DetElement parent_detector = description.detector(par_name);
79  if ( !parent_detector.isValid() ) {
80  except("Compact","Failed to access valid parent detector of %s",name.c_str());
81  }
82  description.declareParent(name, parent_detector);
83  }
84  json_attr_t attr_ro = element.attr_nothrow(_U(readout));
86  Segmentation seg;
87  if ( attr_ro ) {
88  Readout ro = description.readout(element.attr<std::string>(attr_ro));
89  if (!ro.isValid()) {
90  throw std::runtime_error("No Readout structure present for detector:" + name);
91  }
92  seg = ro.segmentation();
93  sd = SensitiveDetector(name, "sensitive");
94  sd.setHitsCollection(ro.name());
95  sd.setReadout(ro);
96  description.addSensitiveDetector(sd);
97  }
98  Handle<NamedObject> sens = sd;
99  DetElement det(PluginService::Create<NamedObject*>(type, &description, &element, &sens));
100  if (det.isValid()) {
101  setChildTitles(std::make_pair(name, det));
102  if ( sd.isValid() ) {
104  }
105  if ( seg.isValid() ) {
106  seg->sensitive = sd;
107  seg->detector = det;
108  }
109  }
110  printout(det.isValid() ? INFO : ERROR, "Compact", "%s subdetector:%s of type %s %s",
111  (det.isValid() ? "++ Converted" : "FAILED "), name.c_str(), type.c_str(),
112  (sd.isValid() ? ("[" + sd.type() + "]").c_str() : ""));
113 
114  if (!det.isValid()) {
115  PluginDebug dbg;
116  PluginService::Create<NamedObject*>(type, &description, &element, &sens);
117  throw std::runtime_error("Failed to execute subdetector creation plugin. " + dbg.missingFactory(type));
118  }
119  description.addDetector(det);
120  return;
121  }
122  catch (const std::exception& e) {
123  printout(ERROR, "Compact", "++ FAILED to convert subdetector: %s: %s", name.c_str(), e.what());
124  std::terminate();
125  }
126  catch (...) {
127  printout(ERROR, "Compact", "++ FAILED to convert subdetector: %s: %s", name.c_str(), "UNKNONW Exception");
128  std::terminate();
129  }
130 }
131 
132 static long handle_json(Detector& description, int argc, char** argv) {
133  if ( argc < 1 || (argc<2 && argv[0][0] != '/') ) {
134  ::printf("DD4hep_JsonProcessor <file> <directory> \n"
135  " If file is an absolute path (does NOT start with '/')\n"
136  " the directory path is mandatory. \n"
137  " The file name is then assumed to be relative. \n"
138  "\n");
139  exit(EINVAL);
140  }
141  std::string file = argv[0];
142  if ( file[0] != '/' ) file = std::string(argv[1]) + "/" + file;
143 
144  printout(INFO,"JsonProcessor","++ Processing JSON input: %s",file.c_str());
145  json::DocumentHolder doc(json::DocumentHandler().load(file.c_str()));
146  json::Element elt = doc.root();
147 
148  json_coll_t(elt,_U(detector)).for_each(Converter<detector>(description));
149  printout(INFO,"JsonProcessor","++ ... Successfully processed JSON input: %s",file.c_str());
150  return 1;
151 }
152 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:44
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:183
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:119
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:128
dd4hep::Handle< NamedObject >
dd4hep::Segmentation::detector
Handle< DetElementObject > detector() const
Access the main detector element using this segmentation object.
Definition: Segmentations.cpp:114
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::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:188
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:74
dd4hep::json::Collection_t::for_each
void for_each(T oper) const
Loop processor using function object.
Definition: Elements.h:266
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:332
dd4hep::DetElement::Children
std::map< std::string, DetElement > Children
Definition: DetElement.h:206
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:135
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:358
Printout.h
DocumentHandler.h