CMS 3D CMS Logo

cond2xml.py
Go to the documentation of this file.
1 
2 import os
3 import shutil
4 import sys
5 import time
6 import glob
7 import importlib
8 
9 # as we need to load the shared lib from here, make sure it's in our path:
10 if os.path.join( os.environ['CMSSW_BASE'], 'src') not in sys.path:
11  sys.path.append( os.path.join( os.environ['CMSSW_BASE'], 'src') )
12 
13 # -------------------------------------------------------------------------------------------------------
14 
15 payload2xmlCodeTemplate = """
16 
17 #include <iostream>
18 #include <string>
19 #include <memory>
20 
21 #include <boost/python/class.hpp>
22 #include <boost/python/module.hpp>
23 #include <boost/python/init.hpp>
24 #include <boost/python/def.hpp>
25 #include <iostream>
26 #include <string>
27 #include <sstream>
28 
29 #include "boost/archive/xml_oarchive.hpp"
30 #include "CondFormats/Serialization/interface/Serializable.h"
31 #include "CondFormats/Serialization/interface/Archive.h"
32 
33 #include "CondCore/Utilities/src/CondFormats.h"
34 
35 namespace { // Avoid cluttering the global namespace.
36 
37  std::string %(plTypeSan)s2xml( const std::string &payloadData, const std::string &payloadType ) {
38 
39  // now to convert
40  std::unique_ptr< %(plType)s > payload;
41 
42  std::stringbuf sdataBuf;
43  sdataBuf.pubsetbuf( const_cast<char *> ( payloadData.c_str() ), payloadData.size() );
44 
45  std::istream inBuffer( &sdataBuf );
46  eos::portable_iarchive ia( inBuffer );
47  payload.reset( new %(plType)s );
48  ia >> (*payload);
49 
50  // now we have the object in memory, convert it to xml in a string and return it
51 
52  std::ostringstream outBuffer;
53  boost::archive::xml_oarchive xmlResult( outBuffer );
54  xmlResult << boost::serialization::make_nvp( "cmsCondPayload", *payload );
55 
56  return outBuffer.str();
57  }
58 
59 } // end namespace
60 
61 
62 BOOST_PYTHON_MODULE(%(mdName)s)
63 {
64  using namespace boost::python;
65  def ("%(plTypeSan)s2xml", %(plTypeSan)s2xml);
66 }
67 
68 """
69 
70 buildFileTemplate = """
71 <flags CXXFLAGS="-Wno-sign-compare -Wno-unused-variable -Os"/>
72 <use name="boost"/>
73 <use name="boost_python"/>
74 <use name="boost_iostreams"/>
75 <use name="boost_serialization"/>
76 <use name="boost_program_options"/>
77 <use name="CondCore/CondDB"/>
78 <use name="CondFormats/HLTObjects"/>
79 <use name="CondFormats/Alignment"/>
80 <use name="CondFormats/BeamSpotObjects"/>
81 <use name="CondFormats/CastorObjects"/>
82 <use name="CondFormats/HIObjects"/>
83 <use name="CondFormats/CSCObjects"/>
84 <use name="CondFormats/DTObjects"/>
85 <use name="CondFormats/ESObjects"/>
86 <use name="CondFormats/EcalObjects"/>
87 <use name="CondFormats/EgammaObjects"/>
88 <use name="CondFormats/Luminosity"/>
89 <use name="CondFormats/HcalObjects"/>
90 <use name="CondFormats/JetMETObjects"/>
91 <use name="CondFormats/L1TObjects"/>
92 <use name="CondFormats/PhysicsToolsObjects"/>
93 <use name="CondFormats/GeometryObjects"/>
94 <use name="CondFormats/RecoMuonObjects"/>
95 <use name="CondFormats/RPCObjects"/>
96 <use name="CondFormats/RunInfo"/>
97 <use name="CondFormats/SiPixelObjects"/>
98 <use name="CondFormats/SiStripObjects"/>
99 <use name="CondFormats/Common"/>
100 <use name="CondFormats/BTauObjects"/>
101 <use name="CondFormats/MFObjects"/>
102 <use name="CondFormats/PCLConfig"/>
103 <export>
104  <lib name="1"/>
105 </export>
106 """
107 
108 # helper function
109 def sanitize(typeName):
110  return typeName.replace(' ','').replace('<','_').replace('>','')
111 
113 
114  def __init__(self, condDBIn):
115  self.conddb = condDBIn
116  self._pl2xml_isPrepared = False
117 
118  if not os.path.exists( os.path.join( os.environ['CMSSW_BASE'], 'src') ):
119  raise Exception("Looks like you are not running in a CMSSW developer area, $CMSSW_BASE/src/ does not exist")
120 
121  self.fakePkgName = "fakeSubSys4pl/fakePkg4pl"
122  self._pl2xml_tmpDir = os.path.join( os.environ['CMSSW_BASE'], 'src', self.fakePkgName )
123 
124  self.doCleanup = True
125 
126  def __del__(self):
127 
128  if self.doCleanup:
129  shutil.rmtree( '/'.join( self._pl2xml_tmpDir.split('/')[:-1] ) )
130  os.unlink( os.path.join( os.environ['CMSSW_BASE'], 'src', './pl2xmlComp.so') )
131  return
132 
133  def discover(self, payloadType):
134 
135  # print "discover> checking for plugin of type %s" % payloadType
136 
137  # first search in developer area:
138  libDir = os.path.join( os.environ["CMSSW_BASE"], 'lib', os.environ["SCRAM_ARCH"] )
139  pluginList = glob.glob( libDir + '/plugin%s_toXML.so' % sanitize(payloadType) )
140 
141  # if nothing found there, check release:
142  if not pluginList:
143  libDir = os.path.join( os.environ["CMSSW_RELEASE_BASE"], 'lib', os.environ["SCRAM_ARCH"] )
144  pluginList = glob.glob( libDir + '/plugin%s_toXML.so' % sanitize(payloadType) )
145 
146  # if pluginList:
147  # print "found plugin for %s (in %s) : %s " % (payloadType, libDir, pluginList)
148  # else:
149  # print "no plugin found for type %s" % payloadType
150 
151  xmlConverter = None
152  if len(pluginList) > 0:
153  dirPath, libName = os.path.split( pluginList[0] )
154  sys.path.append(dirPath)
155  # print "going to import %s from %s" % (libName, dirPath)
156  xmlConverter = importlib.import_module( libName.replace('.so', '') )
157  # print "found methods: ", dir(xmlConverter)
158  self.doCleanup = False
159 
160  return xmlConverter
161 
162  def prepPayload2xml(self, session, payload):
163 
164  startTime = time.time()
165 
166  Payload = session.get_dbtype(self.conddb.Payload)
167  # get payload from DB:
168  result = session.query(Payload.data, Payload.object_type).filter(Payload.hash == payload).one()
169  data, plType = result
170 
171  info = { "mdName" : "pl2xmlComp",
172  'plType' : plType,
173  'plTypeSan' : sanitize(plType),
174  }
175 
176  converter = self.discover(plType)
177  if converter: return converter
178 
179  code = payload2xmlCodeTemplate % info
180 
181  tmpDir = self._pl2xml_tmpDir
182  if ( os.path.exists( tmpDir ) ) :
183  msg = '\nERROR: %s already exists, please remove if you did not create that manually !!' % tmpDir
184  self.doCleanup = False
185  raise Exception(msg)
186 
187  os.makedirs( tmpDir+'/src' )
188 
189  buildFileName = "%s/BuildFile.xml" % (tmpDir,)
190  with open(buildFileName, 'w') as buildFile:
191  buildFile.write( buildFileTemplate )
192  buildFile.close()
193 
194  tmpFileName = "%s/src/%s" % (tmpDir, info['mdName'],)
195  with open(tmpFileName+'.cpp', 'w') as codeFile:
196  codeFile.write(code)
197  codeFile.close()
198 
199  libDir = os.path.join( os.environ["CMSSW_BASE"], 'tmp', os.environ["SCRAM_ARCH"], 'src', self.fakePkgName, 'src', self.fakePkgName.replace('/',''))
200  libName = libDir + '/lib%s.so' % self.fakePkgName.replace('/','')
201  cmd = "source /afs/cern.ch/cms/cmsset_default.sh;"
202  cmd += "(cd %s ; scram b 2>&1 >build.log && cp %s $CMSSW_BASE/src/pl2xmlComp.so )" % (tmpDir, libName)
203  ret = os.system(cmd)
204  if ret != 0 : self.doCleanup = False
205 
206  buildTime = time.time()-startTime
207  print >> sys.stderr, "buillding done in ", buildTime, 'sec., return code from build: ', ret
208 
209  if (ret != 0):
210  return None
211 
212  return importlib.import_module( 'pl2xmlComp' )
213 
214  def payload2xml(self, session, payload):
215 
216  if not self._pl2xml_isPrepared:
217  xmlConverter = self.prepPayload2xml(session, payload)
218  if not xmlConverter:
219  msg = "Error preparing code for "+payload
220  raise Exception(msg)
221  self._pl2xml_isPrepared = True
222 
223 
224  Payload = session.get_dbtype(self.conddb.Payload)
225  # get payload from DB:
226  result = session.query(Payload.data, Payload.object_type).filter(Payload.hash == payload).one()
227  data, plType = result
228 
229  convFuncName = sanitize(plType)+'2xml'
230  sys.path.append('.')
231  func = getattr(xmlConverter, convFuncName)
232  resultXML = func( str(data), str(plType) )
233 
234  print resultXML
235 
def __init__(self, condDBIn)
Definition: cond2xml.py:114
def replace(string, replacements)
def sanitize(typeName)
Definition: cond2xml.py:109
def discover(self, payloadType)
Definition: cond2xml.py:133
def prepPayload2xml(self, session, payload)
Definition: cond2xml.py:162
def payload2xml(self, session, payload)
Definition: cond2xml.py:214
static std::string join(char **cmd)
Definition: RemoteFile.cc:18