Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-12 07:54:05

0001 //==========================================================================
0002 //  AIDA Detector description implementation 
0003 //--------------------------------------------------------------------------
0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005 // All rights reserved.
0006 //
0007 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009 //
0010 // Author     : M.Frank
0011 //
0012 //==========================================================================
0013 
0014 /**
0015    Note:
0016    This is experimental playground.
0017 
0018    It should only proof the concept, that actually input parsers may be mixed:
0019    The MiniTel_json example starts with xml, then inputs a json file, which
0020    is processed here....
0021 
0022    If json is supposed to be really used, then the corresponding machinery
0023    first has to be implemented, similar to simething like Compact or DDDB.
0024 
0025    M. Frank
0026 */
0027 
0028 // Framework inlcude files
0029 #define BOOST_BIND_GLOBAL_PLACEHOLDERS
0030 #include <JSON/Helper.h>
0031 #include <JSON/DocumentHandler.h>
0032 #include <JSON/Conversions.h>
0033 #include <DD4hep/Plugins.h>
0034 #include <DD4hep/Printout.h>
0035 #include <DD4hep/IDDescriptor.h>
0036 #include <DD4hep/detail/SegmentationsInterna.h>
0037 #include <DD4hep/detail/DetectorInterna.h>
0038 #include <DD4hep/detail/ObjectsInterna.h>
0039 
0040 // C/C++ include files
0041 #include <boost/property_tree/json_parser.hpp>
0042 
0043 namespace {
0044   class Json;
0045   class detector;
0046 }
0047 
0048 using namespace dd4hep;
0049 
0050 static void setChildTitles(const std::pair<std::string, DetElement>& e) {
0051   DetElement parent = e.second.parent();
0052   const DetElement::Children& children = e.second.children();
0053   if (::strlen(e.second->GetTitle()) == 0) {
0054     e.second->SetTitle(parent.isValid() ? parent.type().c_str() : e.first.c_str());
0055   }
0056   for_each(children.begin(), children.end(), setChildTitles);
0057 }
0058 
0059 namespace dd4hep  {
0060     template <> void Converter<detector>::operator()(json_h element) const;
0061 }
0062 
0063 /// This is the identical converter as it is used for the XML compact!
0064 template <> void Converter<detector>::operator()(json_h element) const {
0065   std::string type = element.attr<std::string>(_U(type));
0066   std::string name = element.attr<std::string>(_U(name));
0067   std::string name_match = ":" + name + ":";
0068   std::string type_match = ":" + type + ":";
0069 
0070   try {
0071     json_attr_t attr_par = element.attr_nothrow(_U(parent));
0072     if (attr_par) {
0073       // We have here a nested detector. If the mother volume is not yet registered
0074       // it must be done here, so that the detector constructor gets the correct answer from
0075       // the call to Detector::pickMotherVolume(DetElement).
0076       std::string par_name = element.attr<std::string>(attr_par);
0077       DetElement parent_detector = description.detector(par_name);
0078       if ( !parent_detector.isValid() )  {
0079         except("Compact","Failed to access valid parent detector of %s",name.c_str());
0080       }
0081       description.declareParent(name, parent_detector);
0082     }
0083     json_attr_t attr_ro  = element.attr_nothrow(_U(readout));
0084     SensitiveDetector sd;
0085     Segmentation seg;
0086     if ( attr_ro )   {
0087       Readout ro = description.readout(element.attr<std::string>(attr_ro));
0088       if (!ro.isValid()) {
0089         throw std::runtime_error("No Readout structure present for detector:" + name);
0090       }
0091       seg = ro.segmentation();
0092       sd = SensitiveDetector(name, "sensitive");
0093       sd.setHitsCollection(ro.name());
0094       sd.setReadout(ro);
0095       description.addSensitiveDetector(sd);
0096     }
0097     Handle<NamedObject> sens = sd;
0098     DetElement det(PluginService::Create<NamedObject*>(type, &description, &element, &sens));
0099     if (det.isValid()) {
0100       setChildTitles(std::make_pair(name, det));
0101       if ( sd.isValid() )  {
0102         det->flag |= DetElement::Object::HAVE_SENSITIVE_DETECTOR;
0103       }
0104       if ( seg.isValid() )  {
0105         seg->sensitive = sd;
0106         seg->detector  = det;
0107       }
0108     }
0109     printout(det.isValid() ? INFO : ERROR, "Compact", "%s subdetector:%s of type %s %s",
0110              (det.isValid() ? "++ Converted" : "FAILED    "), name.c_str(), type.c_str(),
0111              (sd.isValid() ? ("[" + sd.type() + "]").c_str() : ""));
0112 
0113     if (!det.isValid()) {
0114       PluginDebug dbg;
0115       PluginService::Create<NamedObject*>(type, &description, &element, &sens);
0116       throw std::runtime_error("Failed to execute subdetector creation plugin. " + dbg.missingFactory(type));
0117     }
0118     description.addDetector(det);
0119     return;
0120   }
0121   catch (const std::exception& e) {
0122     printout(ERROR, "Compact", "++ FAILED    to convert subdetector: %s: %s", name.c_str(), e.what());
0123     std::terminate();
0124   }
0125   catch (...) {
0126     printout(ERROR, "Compact", "++ FAILED    to convert subdetector: %s: %s", name.c_str(), "UNKNONW Exception");
0127     std::terminate();
0128   }
0129 }
0130 
0131 static long handle_json(Detector& description, int argc, char** argv) {
0132   if ( argc < 1 || (argc<2 && argv[0][0] != '/') )  {
0133     ::printf("DD4hep_JsonProcessor <file> <directory>                \n"
0134              "  If file is an absolute path (does NOT start with '/')\n"
0135              "  the directory path is mandatory.                     \n"
0136              "  The file name is then assumed to be relative.        \n"
0137              "\n");
0138     exit(EINVAL);
0139   }
0140   std::string file = argv[0];
0141   if ( file[0] != '/' ) file = std::string(argv[1]) + "/" + file;
0142 
0143   printout(INFO,"JsonProcessor","++ Processing JSON input: %s",file.c_str());
0144   json::DocumentHolder doc(json::DocumentHandler().load(file.c_str()));
0145   json::Element elt = doc.root();
0146 
0147   json_coll_t(elt,_U(detector)).for_each(Converter<detector>(description));
0148   printout(INFO,"JsonProcessor","++ ... Successfully processed JSON input: %s",file.c_str());
0149   return 1;
0150 }
0151 DECLARE_APPLY(DD4hep_JsonProcessor,handle_json)