Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:13:30

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