File indexing completed on 2023-03-17 11:03:30
0001 from __future__ import print_function
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 import io
0027 import types
0028
0029
0030
0031
0032
0033
0034
0035 def pset_dict_to_string(psetDict):
0036 """Convert dictionary representing a PSet to a string consistent
0037 with the configuration grammar."""
0038 stream = io.StringIO()
0039 stream.write('\n{\n')
0040
0041 for name, value in psetDict.items():
0042 stream.write('%s' % printable_parameter(name, value))
0043 stream.write('\n')
0044
0045 stream.write('}\n')
0046 return stream.getvalue()
0047
0048
0049 def secsource_dict_to_string(secSourceDict):
0050 """Make a string representing the secsource"""
0051 stream = io.StringIO()
0052 stream.write("%s\n{\n" % secSourceDict["@classname"][2])
0053 for name, value in secSourceDict.items():
0054 if name[0] != '@':
0055 stream.write('%s' % printable_parameter(name, value))
0056 stream.write('\n')
0057
0058 stream.write('}\n')
0059 return stream.getvalue()
0060
0061
0062 class printable_parameter:
0063 """A class to provide automatic unpacking of the tuple (triplet)
0064 representation of a single parameter, suitable for printing.
0065
0066 Note that 'value' may in fact be a list."""
0067
0068 def __init__(self, aName, aValueTuple):
0069 self.name = aName
0070 self.type, self.trackedCode, self.value = aValueTuple
0071
0072
0073
0074 if self.trackedCode == "tracked":
0075 self.trackedCode = ""
0076 else:
0077 self.trackedCode = "untracked "
0078
0079
0080 if self.type in ["vbool", "vint32", "vuint32", "vdouble", "vstring", "VInputTag", "VESInputTag"]:
0081
0082
0083
0084 temp = '{'
0085
0086 temp += ", ".join(self.value)
0087 temp += '}'
0088 self.value = temp
0089
0090 if self.type == "PSet":
0091 self.value = pset_dict_to_string(self.value)
0092 if self.type == "secsource":
0093 self.value = secsource_dict_to_string(self.value)
0094 if self.type == "VPSet":
0095 temp = '{'
0096 tup = [ pset_dict_to_string(x) for x in self.value ]
0097 temp += ", ".join( tup )
0098 temp += '}'
0099 self.value = temp
0100
0101 def __str__(self):
0102 """Print this parameter in the right format for a
0103 configuration file."""
0104 s = "%(trackedCode)s%(type)s %(name)s = %(value)s" % self.__dict__
0105 return s
0106
0107
0108
0109
0110 class cmsconfig:
0111 """A class to provide convenient access to the contents of a
0112 parsed CMS configuration file."""
0113
0114 def __init__(self, stringrep):
0115 """Create a cmsconfig object from the contents of the (Python)
0116 exchange format for configuration files."""
0117 self.psdata = eval(stringrep)
0118
0119 def numberOfModules(self):
0120 return len(self.psdata['modules'])
0121
0122 def numberOfOutputModules(self):
0123 return len(self.outputModuleNames())
0124
0125 def moduleNames(self):
0126 """Return the names of modules. Returns a list."""
0127 return self.psdata['modules'].keys()
0128
0129 def module(self, name):
0130 """Get the module with this name. Exception raised if name is
0131 not known. Returns a dictionary."""
0132 return self.psdata['modules'][name]
0133
0134 def psetNames(self):
0135 """Return the names of psets. Returns a list."""
0136 return self.psdata['psets'].keys()
0137
0138 def pset(self, name):
0139 """Get the pset with this name. Exception raised if name is
0140 not known. Returns a dictionary."""
0141 return self.psdata['psets'][name]
0142
0143 def outputModuleNames(self):
0144 return self.psdata['output_modules']
0145
0146 def moduleNamesWithSecSources(self):
0147 return self.psdata['modules_with_secsources']
0148
0149 def esSourceNames(self):
0150 """Return the names of all ESSources. Names are of the form '<C++ type>@<label>' where
0151 label can be empty. Returns a list."""
0152 return self.psdata['es_sources'].keys()
0153
0154 def esSource(self, name):
0155 """Get the ESSource with this name. Exception raised if name is
0156 not known. Returns a dictionary."""
0157 return self.psdata['es_sources'][name]
0158
0159 def esModuleNames(self):
0160 """Return the names of all ESModules. Names are of the form '<C++ type>@<label>' where
0161 label can be empty. Returns a list."""
0162 return self.psdata['es_modules'].keys()
0163
0164 def esModule(self, name):
0165 """Get the ESModule with this name. Exception raised if name is
0166 not known. Returns a dictionary."""
0167 return self.psdata['es_modules'][name]
0168
0169 def esPreferNames(self):
0170 """Return the names of all es_prefer statements. Names are of the form 'esprefer_<C++ type>@<label>' where
0171 label can be empty. Returns a list."""
0172 return self.psdata['es_prefers'].keys()
0173
0174 def esPrefer(self, name):
0175 """Get the es_prefer statement with this name. Exception raised if name is
0176 not known. Returns a dictionary."""
0177 return self.psdata['es_prefers'][name]
0178
0179 def serviceNames(self):
0180 """Return the names of all Services. Names are actually the C++ class names
0181 Returns a list."""
0182 return self.psdata['services'].keys()
0183
0184 def service(self, name):
0185 """Get the Service with this name. Exception raised if name is
0186 not known. Returns a dictionary."""
0187 return self.psdata['services'][name]
0188
0189 def pathNames(self):
0190 return self.psdata['paths'].keys()
0191
0192 def path(self, name):
0193 """Get the path description for the path of the given
0194 name. Exception raised if name is not known. Returns a
0195 string."""
0196 return self.psdata['paths'][name]
0197
0198 def schedule(self):
0199 return self.psdata['schedule']
0200
0201 def sequenceNames(self):
0202 return self.psdata['sequences'].keys()
0203
0204 def sequence(self, name):
0205 """Get the sequence description for the sequence of the given
0206 name. Exception raised if name is not known. Returns a
0207 string."""
0208 return self.psdata['sequences'][name]
0209
0210 def endpathNames(self):
0211 return self.psdata['endpaths'].keys()
0212
0213 def endpath(self, name):
0214 """Return the endpath description, as a string."""
0215 return self.psdata['endpaths'][name]
0216
0217 def mainInputSource(self):
0218 """Return the description of the main input source, as a
0219 dictionary."""
0220 return self.psdata['main_input']
0221
0222 def looper(self):
0223 """Return the description of the looper, as a
0224 dictionary."""
0225 return self.psdata['looper']
0226
0227 def procName(self):
0228 """Return the process name, a string"""
0229 return self.psdata['procname']
0230
0231 def asConfigurationString(self):
0232 """Return a string conforming to the configuration file
0233 grammar, encoding this configuration."""
0234
0235
0236
0237 result = ""
0238
0239 try:
0240 stream = io.StringIO()
0241 self.__write_self_to_stream(stream)
0242 result = stream.getvalue()
0243
0244 finally:
0245 stream.close()
0246
0247 return result
0248
0249 def asPythonString(self):
0250 """Return a string containing the python psdata source of
0251 this object to facilitate saving and loading of python format"""
0252 result = "#!/usr/bin/env python\n"
0253 result += str(self.psdata)
0254 return result
0255
0256 def __write_self_to_stream(self, fileobj):
0257 """Private method.
0258 Return None.
0259 Write the contents of self to the file-like object fileobj."""
0260
0261
0262 fileobj.write('process %s = \n{\n' % self.procName())
0263 self.__write_process_block_guts(fileobj)
0264 fileobj.write('}\n')
0265
0266 def __write_process_block_guts(self, fileobj):
0267 """Private method.
0268 Return None.
0269 Write the guts of the process block to the file-like object
0270 fileobj."""
0271
0272
0273
0274 self.__write_main_source(fileobj)
0275 self.__write_looper(fileobj)
0276 self.__write_psets(fileobj)
0277 self.__write_es_sources(fileobj)
0278 self.__write_es_modules(fileobj)
0279 self.__write_es_prefers(fileobj)
0280 self.__write_modules(fileobj)
0281 self.__write_services(fileobj)
0282 self.__write_sequences(fileobj)
0283 self.__write_paths(fileobj)
0284 self.__write_endpaths(fileobj)
0285 self.__write_schedule(fileobj)
0286
0287 def __write_psets(self, fileobj):
0288 """Private method.
0289 Return None
0290 Write all the psets to the file-like object fileobj."""
0291 for name in self.psetNames():
0292 psettuple = self.pset(name)
0293
0294
0295 fileobj.write('%s' % printable_parameter(name, psettuple))
0296
0297
0298
0299
0300
0301 def __write_modules(self, fileobj):
0302 """Private method.
0303 Return None
0304 Write all the modules to the file-like object fileobj."""
0305 for name in self.moduleNames():
0306 moddict = self.module(name)
0307 fileobj.write("module %s = %s\n{\n" % (name, moddict['@classname'][2]))
0308 self.__write_module_guts(moddict, fileobj)
0309 fileobj.write('}\n')
0310
0311 def __write_es_sources(self, fileobj):
0312 """Private method.
0313 Return None
0314 Write all ESSources to the file-like object
0315 fileobj."""
0316 for name in self.esSourceNames():
0317 es_source_dict = self.esSource(name)
0318 fileobj.write("es_source %s = %s\n{\n" % (es_source_dict['@label'][2], es_source_dict['@classname'][2]))
0319 self.__write_module_guts(es_source_dict, fileobj)
0320 fileobj.write('}\n')
0321
0322 def __write_es_modules(self, fileobj):
0323 """Private method.
0324 Return None
0325 Write all ESModules to the file-like object
0326 fileobj."""
0327 for name in self.esModuleNames():
0328 es_mod_dict = self.esModule(name)
0329 fileobj.write("es_module %s = %s\n{\n" % (es_mod_dict['@label'][2], es_mod_dict['@classname'][2]))
0330 self.__write_module_guts(es_mod_dict, fileobj)
0331 fileobj.write('}\n')
0332
0333 def __write_es_prefers(self, fileobj):
0334 """Private method.
0335 Return None
0336 Write all es_prefer statements to the file-like object
0337 fileobj."""
0338 for name in self.esPreferNames():
0339 es_mod_dict = self.esPrefer(name)
0340 fileobj.write("es_prefer %s = %s\n{\n" % (es_mod_dict['@label'][2], es_mod_dict['@classname'][2]))
0341 self.__write_module_guts(es_mod_dict, fileobj)
0342 fileobj.write('}\n')
0343
0344 def __write_services(self, fileobj):
0345 """Private method.
0346 Return None
0347 Write all Services to the file-like object
0348 fileobj."""
0349 for name in self.serviceNames():
0350 es_mod_dict = self.service(name)
0351 fileobj.write("service = %s\n{\n" % (es_mod_dict['@classname'][2]))
0352 self.__write_module_guts(es_mod_dict, fileobj)
0353 fileobj.write('}\n')
0354
0355 def __write_sequences(self, fileobj):
0356 """Private method.
0357 Return None
0358 Write all the sequences to the file-like object fileobj."""
0359 for name in self.sequenceNames():
0360 fileobj.write("sequence %s = {%s}\n" % (name, self.sequence(name)))
0361
0362
0363 def __write_paths(self, fileobj):
0364 """Private method.
0365 Return None
0366 Write all the paths to the file-like object fileobj."""
0367 for name in self.pathNames():
0368 fileobj.write("path %s = {%s}\n" % (name, self.path(name)))
0369
0370
0371 def __write_endpaths(self, fileobj):
0372 """Private method.
0373 Return None
0374 Write all the endpaths to the file-like object
0375 fileobj."""
0376 for name in self.endpathNames():
0377 fileobj.write("endpath %s = {%s}\n" % (name, self.endpath(name)))
0378
0379 def __write_schedule(self, fileobj):
0380 fileobj.write("schedule = {%s}\n" % self.schedule())
0381
0382 def __write_main_source(self, fileobj):
0383 """Private method.
0384 Return None
0385 Write the (main) source block to the file-like object
0386 fileobj."""
0387 mis = self.mainInputSource()
0388 if mis:
0389 fileobj.write('source = %s\n{\n' % mis['@classname'][2])
0390 self.__write_module_guts(mis, fileobj)
0391 fileobj.write('}\n')
0392
0393 def __write_looper(self, fileobj):
0394 """Private method.
0395 Return None
0396 Write the looper block to the file-like object
0397 fileobj."""
0398 mis = self.looper()
0399 if mis:
0400 fileobj.write('looper = %s\n{\n' % mis['@classname'][2])
0401 self.__write_module_guts(mis, fileobj)
0402 fileobj.write('}\n')
0403
0404
0405 def __write_module_guts(self, moddict, fileobj):
0406 """Private method.
0407 Return None
0408 Print the body of the block for this 'module'. This includes
0409 all the dictionary contents except for the classname (because
0410 the classname does not appear within the block).
0411
0412 NOTE: This should probably be a static method, because it doesn't
0413 use any member data of the object, but I'm not sure we can
0414 rely on a new-enough version of Python to make use of static
0415 methods."""
0416 for name, value in moddict.items():
0417 if name[0] != '@':
0418 fileobj.write('%s' % printable_parameter(name, value))
0419 fileobj.write('\n')
0420
0421
0422
0423 if __name__ == "__main__":
0424 from sys import argv
0425 filename = "complete.pycfg"
0426 if len(argv) > 1:
0427 filename = argv[1]
0428
0429 txt = file(filename).read()
0430 cfg = cmsconfig(txt)
0431 print(cfg.asConfigurationString())
0432
0433