Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:16:47

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 <iostream>
0042 #include <boost/property_tree/json_parser.hpp>
0043 
0044 namespace {
0045   class Json;
0046   class detector;
0047 }
0048 
0049 using namespace dd4hep;
0050 
0051 static void setChildTitles(const std::pair<std::string, DetElement>& e) {
0052   DetElement parent = e.second.parent();
0053   const DetElement::Children& children = e.second.children();
0054   if (::strlen(e.second->GetTitle()) == 0) {
0055     e.second->SetTitle(parent.isValid() ? parent.type().c_str() : e.first.c_str());
0056   }
0057   for_each(children.begin(), children.end(), setChildTitles);
0058 }
0059 
0060 namespace dd4hep  {
0061     template <> void Converter<detector>::operator()(json_h element) const;
0062 }
0063 
0064 /// This is the identical converter as it is used for the XML compact!
0065 template <> void Converter<detector>::operator()(json_h element) const {
0066   std::string type = element.attr<std::string>(_U(type));
0067   std::string name = element.attr<std::string>(_U(name));
0068   std::string name_match = ":" + name + ":";
0069   std::string type_match = ":" + type + ":";
0070 
0071   try {
0072     json_attr_t attr_par = element.attr_nothrow(_U(parent));
0073     if (attr_par) {
0074       // We have here a nested detector. If the mother volume is not yet registered
0075       // it must be done here, so that the detector constructor gets the correct answer from
0076       // the call to Detector::pickMotherVolume(DetElement).
0077       std::string par_name = element.attr<std::string>(attr_par);
0078       DetElement parent_detector = description.detector(par_name);
0079       if ( !parent_detector.isValid() )  {
0080         except("Compact","Failed to access valid parent detector of %s",name.c_str());
0081       }
0082       description.declareParent(name, parent_detector);
0083     }
0084     json_attr_t attr_ro  = element.attr_nothrow(_U(readout));
0085     SensitiveDetector sd;
0086     Segmentation seg;
0087     if ( attr_ro )   {
0088       Readout ro = description.readout(element.attr<std::string>(attr_ro));
0089       if (!ro.isValid()) {
0090         throw std::runtime_error("No Readout structure present for detector:" + name);
0091       }
0092       seg = ro.segmentation();
0093       sd = SensitiveDetector(name, "sensitive");
0094       sd.setHitsCollection(ro.name());
0095       sd.setReadout(ro);
0096       description.addSensitiveDetector(sd);
0097     }
0098     Handle<NamedObject> sens = sd;
0099     DetElement det(PluginService::Create<NamedObject*>(type, &description, &element, &sens));
0100     if (det.isValid()) {
0101       setChildTitles(std::make_pair(name, det));
0102       if ( sd.isValid() )  {
0103         det->flag |= DetElement::Object::HAVE_SENSITIVE_DETECTOR;
0104       }
0105       if ( seg.isValid() )  {
0106         seg->sensitive = sd;
0107         seg->detector  = det;
0108       }
0109     }
0110     printout(det.isValid() ? INFO : ERROR, "Compact", "%s subdetector:%s of type %s %s",
0111              (det.isValid() ? "++ Converted" : "FAILED    "), name.c_str(), type.c_str(),
0112              (sd.isValid() ? ("[" + sd.type() + "]").c_str() : ""));
0113 
0114     if (!det.isValid()) {
0115       PluginDebug dbg;
0116       PluginService::Create<NamedObject*>(type, &description, &element, &sens);
0117       throw std::runtime_error("Failed to execute subdetector creation plugin. " + dbg.missingFactory(type));
0118     }
0119     description.addDetector(det);
0120     return;
0121   }
0122   catch (const std::exception& e) {
0123     printout(ERROR, "Compact", "++ FAILED    to convert subdetector: %s: %s", name.c_str(), e.what());
0124     std::terminate();
0125   }
0126   catch (...) {
0127     printout(ERROR, "Compact", "++ FAILED    to convert subdetector: %s: %s", name.c_str(), "UNKNONW Exception");
0128     std::terminate();
0129   }
0130 }
0131 
0132 static long handle_json(Detector& description, int argc, char** argv) {
0133   if ( argc < 1 || (argc<2 && argv[0][0] != '/') )  {
0134     ::printf("DD4hep_JsonProcessor <file> <directory>                \n"
0135              "  If file is an absolute path (does NOT start with '/')\n"
0136              "  the directory path is mandatory.                     \n"
0137              "  The file name is then assumed to be relative.        \n"
0138              "\n");
0139     exit(EINVAL);
0140   }
0141   std::string file = argv[0];
0142   if ( file[0] != '/' ) file = std::string(argv[1]) + "/" + file;
0143 
0144   printout(INFO,"JsonProcessor","++ Processing JSON input: %s",file.c_str());
0145   json::DocumentHolder doc(json::DocumentHandler().load(file.c_str()));
0146   json::Element elt = doc.root();
0147 
0148   json_coll_t(elt,_U(detector)).for_each(Converter<detector>(description));
0149   printout(INFO,"JsonProcessor","++ ... Successfully processed JSON input: %s",file.c_str());
0150   return 1;
0151 }
0152 DECLARE_APPLY(DD4hep_JsonProcessor,handle_json)