Back to home page

EIC code displayed by LXR

 
 

    


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

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 // Framework include files
0015 #include <DDCond/ConditionsRepository.h>
0016 #include <DDCond/ConditionsManager.h>
0017 #include <DDCond/ConditionsIOVPool.h>
0018 #include <DDCond/ConditionsTags.h>
0019 #include <DD4hep/detail/ConditionsInterna.h>
0020 #include <DD4hep/Printout.h>
0021 #include <XML/DocumentHandler.h>
0022 #include <XML/XMLTags.h>
0023 
0024 // C/C++ include files
0025 #include <cstring>
0026 #include <fstream>
0027 #include <climits>
0028 #include <cerrno>
0029 #include <map>
0030 
0031 using namespace dd4hep::cond;
0032 typedef dd4hep::xml::Handle_t xml_h;
0033 typedef dd4hep::xml::Element xml_elt_t;
0034 typedef dd4hep::xml::Document xml_doc_t;
0035 typedef dd4hep::xml::Collection_t xml_coll_t;
0036 
0037 typedef std::map<dd4hep::Condition::key_type,dd4hep::Condition> AllConditions;
0038 
0039 /// Default constructor
0040 ConditionsRepository::ConditionsRepository()  {
0041 }
0042 
0043 /// Default destructor
0044 ConditionsRepository::~ConditionsRepository()   {
0045 }
0046 
0047 namespace {
0048 
0049   int createXML(const std::string& output, const AllConditions& all) {
0050     const char comment[] = "\n"
0051       "      +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"
0052       "      ++++   Linear collider detector description Detector in C++  ++++\n"
0053       "      ++++   dd4hep Detector description generator.            ++++\n"
0054       "      ++++                                                     ++++\n"
0055       "      ++++                                                     ++++\n"
0056       "      ++++                              M.Frank CERN/LHCb      ++++\n"
0057       "      +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n  ";
0058     dd4hep::xml::DocumentHandler docH;
0059     xml_doc_t doc = docH.create("collection", comment);
0060     xml_elt_t root = doc.root(), cond(0);
0061     for( const auto& i : all )  {
0062       char text[32];
0063       dd4hep::Condition c = i.second;
0064       std::snprintf(text,sizeof(text),"0x%16llX",c.key());
0065       root.append(cond = xml_elt_t(doc, _U(ref)));
0066       cond.setAttr(_U(key), text);
0067 #if !defined(DD4HEP_MINIMAL_CONDITIONS)
0068       cond.setAttr(_U(name), c.name());
0069       cond.setAttr(_U(ref), c.address());
0070 #endif
0071     }
0072     dd4hep::printout(dd4hep::ALWAYS,"ConditionsRepository","++ Handled %ld conditions.",all.size());
0073     if ( !output.empty() )  {
0074       return docH.output(doc, output);
0075     }
0076     return 1;
0077   }
0078 
0079   /// Load the repository from file and fill user passed data structory
0080   int readXML(const std::string& input, ConditionsRepository::Data& data)    {
0081     struct Conv {
0082       /// Reference to optional user defined parameter
0083       ConditionsRepository::Data& data;
0084       /// Initializing constructor of the functor
0085       Conv(ConditionsRepository::Data& p) : data(p) {}
0086       /// Callback operator to be specialized depending on the element type
0087       void operator()(xml_h element) const   {
0088         std::string key = element.attr<std::string>(_U(key));
0089         std::size_t cap = data.capacity();
0090         ConditionsRepository::Entry e;
0091         ::sscanf(key.c_str(),"0x%16llX",&e.key);
0092         e.name = element.attr<std::string>(_U(name));
0093         e.address = element.attr<std::string>(_U(ref));
0094         if ( data.size() == cap ) data.reserve(cap+500);
0095         data.emplace_back(e);
0096       }
0097     };
0098     dd4hep::xml::DocumentHolder doc(dd4hep::xml::DocumentHandler().load(input));
0099     xml_h root = doc.root();
0100     xml_coll_t(root, _U(ref)).for_each(Conv(data));
0101     return 1;
0102   }
0103   
0104 #if defined(DD4HEP_MINIMAL_CONDITIONS)
0105   int createText(const std::string& output, const AllConditions&, char)
0106 #else
0107     int createText(const std::string& output, const AllConditions& all, char sep)
0108 #endif
0109   {
0110     std::ofstream out(output);
0111 #if !defined(DD4HEP_MINIMAL_CONDITIONS)
0112     std::size_t siz_nam=0, siz_add=0, siz_tot=0;
0113     char fmt[64], text[2*PATH_MAX+64];
0114     if ( !out.good() )  {
0115       dd4hep::except("ConditionsRepository",
0116                      "++ Failed to open output file:%s [errno:%d %s]",
0117                      output.c_str(), errno, ::strerror(errno));
0118     }
0119     else if ( sep )  {
0120       std::snprintf(fmt,sizeof(fmt),"%%16llX%c%%s%c%%s%c",sep,sep,sep);
0121     }
0122     else   {
0123       for( const auto& i : all )  {
0124         dd4hep::Condition::Object* c = i.second.ptr();
0125         std::size_t siz_n = c->name.length();
0126         std::size_t siz_a = c->address.length();
0127         if ( siz_nam < siz_n ) siz_nam = siz_n;
0128         if ( siz_add < siz_a ) siz_add = siz_a;
0129         if ( siz_tot < (siz_n+siz_a) ) siz_tot = siz_n+siz_a;
0130       }
0131       siz_tot += 8+2+1;
0132       std::snprintf(fmt,sizeof(fmt),"%%16llX %%-%lds %%-%lds",long(siz_nam),long(siz_add));
0133     }
0134     out << "dd4hep." << char(sep ? sep : '-')
0135         << "." << long(siz_nam)
0136         << "." << long(siz_add)
0137         << "." << long(siz_tot) << std::endl;
0138     for( const auto& i : all )  {
0139       dd4hep::Condition c = i.second;
0140       std::snprintf(text, sizeof(text), fmt, c.key(), c.name(), c.address().c_str());
0141       out << text << std::endl;
0142     }
0143 #endif
0144     out.close();
0145     return 1;
0146   }
0147 
0148   /// Load the repository from file and fill user passed data structory
0149   int readText(const std::string& input, ConditionsRepository::Data& data)    {
0150     std::size_t   idx, siz_nam, siz_add, siz_tot;
0151     char     sep, c, text[2*PATH_MAX];
0152     ConditionsRepository::Entry e;
0153     std::ifstream in(input);
0154 
0155     in >> c >> c >> c >> c >> c >> c >> c >> sep 
0156        >> c >> siz_nam
0157        >> c >> siz_add
0158        >> c >> siz_tot;
0159     text[0] = 0;
0160     siz_nam = std::min(siz_nam, 1024UL);
0161     siz_add = std::min(siz_add, 1024UL);
0162     in.getline(text,sizeof(text),'\n');
0163     text[sizeof(text)-1] = 0;
0164     do {
0165       text[0] = 0;
0166       in.getline(text,sizeof(text),'\n');
0167       if ( in.good() )  {
0168         text[sizeof(text)-1] = 0;
0169         if ( siz_tot )  {
0170           text[8] = 0;
0171           // Direct access mode with fixed record size
0172           if ( 9+siz_nam < sizeof(text) )  {
0173             text[9+siz_nam] = 0;
0174             e.name = text+9;
0175           }
0176           if ( 10+siz_nam+siz_add < (long)sizeof(text) )  {
0177             text[10+siz_nam+siz_add] = 0;
0178             e.address = text+10+siz_nam;  
0179             if ( (idx=e.name.find(' ')) != std::string::npos && idx < e.name.length() )
0180               e.name[idx] = 0;
0181             if ( (idx=e.address.find(' ')) != std::string::npos && idx < e.address.length() )
0182               e.address[idx] = 0;
0183           }
0184           else  {
0185             dd4hep::except("ConditionsRepository","+++ Invalid record encountered. [Sever error]");
0186           }
0187         }
0188         else  {
0189           // Variable record size
0190           e.name=text+9;
0191           if ( (idx=e.name.find(sep)) != std::string::npos && idx < sizeof(text)-10 )
0192             text[9+idx] = 0, e.address=text+idx+10, e.name=text+9;
0193           if ( (idx=e.address.find(sep)) != std::string::npos && idx < e.address.length() )
0194             e.address[idx] = 0;
0195           else if ( (idx=e.address.find('\n')) != std::string::npos && idx < e.address.length() )
0196             e.address[idx] = 0;
0197         }
0198         size_t cap = data.capacity();
0199         ::sscanf(text,"%16llX",&e.key);
0200         if ( data.size() == cap ) data.reserve(cap+500);
0201         data.emplace_back(e);
0202       }
0203     } while(in.good() && !in.eof() );
0204     in.close();
0205     return 1;
0206   }
0207 }
0208 
0209 /// Save the repository to file
0210 int ConditionsRepository::save(ConditionsManager manager, const std::string& output)  const  {
0211   AllConditions all;
0212   const auto types = manager.iovTypesUsed();
0213   for( const IOVType* type : types )  {
0214     if ( type )   {
0215       ConditionsIOVPool* pool = manager.iovPool(*type);
0216       if ( pool )  {
0217         for( const auto& cp : pool->elements )   {
0218           RangeConditions rc;
0219           cp.second->select_all(rc);
0220           for( const auto& cond : rc )
0221             all[cond.key()] = cond;
0222         }
0223       }
0224     }
0225   }
0226 
0227   if ( output.find(".xml") != std::string::npos )   {
0228     /// Write XML file with conditions addresses
0229     return createXML(output, all);
0230   }
0231   else if ( output.find(".txt") != std::string::npos )   {
0232     /// Write fixed records with conditions addresses
0233     return createText(output, all, 0);
0234   }
0235   else if ( output.find(".daf") != std::string::npos )   {
0236     /// Write fixed records with conditions addresses
0237     return createText(output, all, 0);
0238   }
0239   else if ( output.find(".csv") != std::string::npos )   {
0240     /// Write records separated by ';' with conditions addresses
0241     return createText(output, all, ';');
0242   }
0243   return 0;
0244 }
0245 
0246 /// Load the repository from file and fill user passed data structory
0247 int ConditionsRepository::load(const std::string& input, Data& data)  const  {
0248   if ( input.find(".xml") != std::string::npos )   {
0249     return readXML(input, data);
0250   }
0251   else if ( input.find(".txt") != std::string::npos )   {
0252     return readText(input, data);
0253   }
0254   else if ( input.find(".daf") != std::string::npos )   {
0255     return readText(input, data);
0256   }
0257   else if ( input.find(".csv") != std::string::npos )   {
0258     return readText(input, data);
0259   }
0260   return 0;
0261 }