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