3 from __future__
import print_function
5 import FWCore.ParameterSet.Config
as cms
6 from importlib
import import_module
9 import xml.etree.ElementTree
as ET
15 for i
in xrange(len(aList)-1):
16 yield (aList[i], aList[i+1])
20 searchPaths = os.getenv(
'CMSSW_SEARCH_PATH').
split(
':')
22 for baseDir
in searchPaths:
23 print(
"Looking for '" + aRelPath +
"' under '" + baseDir +
"'")
24 if os.path.isfile(os.path.join(baseDir, aRelPath)):
26 resolvedPath = os.path.join(baseDir, aRelPath)
28 if resolvedPath
is None:
29 raise RuntimeError(
"Could not find LUT file '" + aRelPath +
"' under directories in 'CMSSW_SEARCH_PATH'")
31 with open(resolvedPath)
as f:
37 if line.startswith(
'#')
or line ==
'\n':
41 stripped_line = line[:line.find(
'#')]
44 items = stripped_line.split()
46 print(
"ERROR parsing file", resolvedPath,
"on line", line_nr,
"'" + line +
"' : Splitting on whitespace produced", len(items),
"items")
49 entries.append( (
int(items[0]),
int(items[1])) )
52 entries.sort(key=
lambda x : x[0])
55 print(
"ERROR parsing file", resolvedPath,
": No LUT entries defined in the file")
59 if entries[0][0] != 0:
60 print(
"ERROR parsing file", resolvedPath,
": LUT entries before index", entries[0][0],
"are not defined")
64 if x1[0] != (x2[0]-1):
65 print(
"ERROR parsing file", resolvedPath,
": ", x2[0] - x1[0] - 1,
"LUT entries between indices", x1[0],
"and", x2[0],
"are not defined")
68 result = [x[1]
for x
in entries]
70 if (len(result) < aExpectedSize)
and not (aPaddingValue
is None):
71 print (
"WARNING : Padding",
str(len(result))+
"-entry LUT with value", aPaddingValue,
"to have", aExpectedSize,
"entries")
72 result += ([aPaddingValue] * (aExpectedSize - len(result)))
73 elif (len(result) > aExpectedSize)
and aTruncate:
74 print (
"WARNING : Truncating",
str(len(result))+
"-entry LUT to have", aExpectedSize,
"entries")
75 result = result[0:aExpectedSize]
76 elif len(result) != aExpectedSize:
77 print (
"ERROR parsing file", resolvedPath,
": Expected LUT of size", aExpectedSize,
", but", len(result),
"entries were specified (and no padding/truncation requested)")
85 def divideByEgLsb(aParam):
86 return int(aParam.value() / aModule.egLsb.value())
88 def divideByTauLsb(aParam):
89 return int(aParam.value() / aModule.tauLsb.value())
91 def divideByJetLsb(aParam):
92 return int(aParam.value() / aModule.jetLsb.value())
96 ((
'mp_common',
'sdfile'),
None,
''),
97 ((
'mp_common',
'algoRev'),
None,
''),
98 ((
'mp_common',
'leptonSeedThreshold'),
'2_ClusterSeedThreshold.mif', divideByEgLsb(aModule.egSeedThreshold)),
99 ((
'mp_common',
'leptonTowerThreshold'),
'3_ClusterThreshold.mif', divideByEgLsb(aModule.egNeighbourThreshold)),
100 ((
'mp_common',
'pileUpTowerThreshold'),
'4_PileUpThreshold.mif', 0x0)
104 ((
'mp_egamma',
'egammaRelaxationThreshold'),
'10_EgRelaxThr.mif', divideByEgLsb(aModule.egMaxPtHOverE)),
105 ((
'mp_egamma',
'egammaMaxEta'),
'egammaMaxEta.mif', aModule.egEtaCut.value()),
106 ((
'mp_egamma',
'egammaBypassCuts'),
'BypassEgVeto.mif',
bool(aModule.egBypassEGVetos.value())),
107 ((
'mp_egamma',
'egammaBypassShape'),
'BypassEgShape.mif',
bool(aModule.egBypassShape.value())),
108 ((
'mp_egamma',
'egammaBypassEcalFG'),
'BypassEcalFG.mif',
bool(aModule.egBypassECALFG.value())),
109 ((
'mp_egamma',
'egammaBypassExtendedHOverE'),
'_BypassExtHE.mif',
bool(aModule.egBypassExtHOverE)),
110 ((
'mp_egamma',
'egammaHOverECut_iEtaLT15'),
'_RatioCutLt15.mif', aModule.egHOverEcutBarrel.value()),
111 ((
'mp_egamma',
'egammaHOverECut_iEtaGTEq15'),
'_RatioCutGe15.mif', aModule.egHOverEcutEndcap.value()),
112 ((
'mp_egamma',
'egammaEnergyCalibLUT'),
'C_EgammaCalibration_12to18.mif',
parseOfflineLUTfile(aModule.egCalibrationLUTFile.value(), 4096)),
113 ((
'mp_egamma',
'egammaIsoLUT1'),
'D_EgammaIsolation1_13to9.mif',
parseOfflineLUTfile(aModule.egIsoLUTFile.value(), 8192)),
114 ((
'mp_egamma',
'egammaIsoLUT2'),
'D_EgammaIsolation2_13to9.mif',
parseOfflineLUTfile(aModule.egIsoLUTFile2.value(), 8192))
118 ((
'mp_tau',
'tauMaxEta'),
'tauMaxEta.mif', aModule.isoTauEtaMax.value()),
119 ((
'mp_tau',
'tauEnergyCalibLUT'),
'I_TauCalibration_11to18.mif',
parseOfflineLUTfile(aModule.tauCalibrationLUTFile.value(), 2048, 0x0)),
120 ((
'mp_tau',
'tauIsoLUT'),
'H_TauIsolation_12to9.mif',
parseOfflineLUTfile(aModule.tauIsoLUTFile.value(), 4096)),
121 ((
'mp_tau',
'tauTrimmingLUT'),
'P_TauTrimming_13to8.mif',
parseOfflineLUTfile(aModule.tauTrimmingShapeVetoLUTFile.value(), 8192))
125 ((
'mp_jet',
'jetSeedThreshold'),
'1_JetSeedThreshold.mif', divideByJetLsb(aModule.jetSeedThreshold)),
126 ((
'mp_jet',
'jetMaxEta'),
'6_JetEtaMax.mif', 0x00028),
127 ((
'mp_jet',
'jetBypassPileUpSub'),
'BypassJetPUS.mif',
bool(aModule.jetBypassPUS.value())),
128 ((
'mp_jet',
'jetPUSUsePhiRing'),
'PhiRingPUS.mif',
bool(aModule.jetPUSUsePhiRing.value())),
129 ((
'mp_jet',
'jetEnergyCalibLUT'),
'L_JetCalibration_11to18.mif',
parseOfflineLUTfile(aModule.jetCalibrationLUTFile.value(), 2048)),
130 ((
'mp_jet',
'HTMHT_maxJetEta'),
'HTMHT_maxJetEta.mif', aModule.etSumEtaMax[1]),
131 ((
'mp_jet',
'HT_jetThreshold'),
'8_HtThreshold.mif',
int(aModule.etSumEtThreshold[1] / aModule.etSumLsb.value())),
132 ((
'mp_jet',
'MHT_jetThreshold'),
'9_MHtThreshold.mif',
int(aModule.etSumEtThreshold[3] / aModule.etSumLsb.value())),
136 ((
'mp_sums',
'towerCountThreshold'),
'HeavyIonThr.mif',
int(aModule.etSumEtThreshold[4] / aModule.etSumLsb.value()) ),
137 ((
'mp_sums',
'towerCountMaxEta'),
'HeavyIonEta.mif', aModule.etSumEtaMax[4]),
138 ((
'mp_sums',
'ETMET_maxTowerEta'),
'ETMET_maxTowerEta.mif', aModule.etSumEtaMax[0]),
139 ((
'mp_sums',
'ecalET_towerThresholdLUT'),
'X_EcalTHR_11to9.mif',
parseOfflineLUTfile(aModule.etSumEcalSumPUSLUTFile.value(), 2048, aTruncate =
True)),
140 ((
'mp_sums',
'ET_towerThresholdLUT'),
'X_ETTHR_11to9.mif',
parseOfflineLUTfile(aModule.etSumEttPUSLUTFile.value(), 2048, aTruncate =
True)),
141 ((
'mp_sums',
'MET_towerThresholdLUT'),
'X_METTHR_11to9.mif',
parseOfflineLUTfile(aModule.etSumMetPUSLUTFile.value(), 2048))
145 ((
'demux',
'sdfile'),
None,
''),
146 ((
'demux',
'algoRev'),
None, 0xcafe),
147 ((
'demux',
'ET_centralityLowerThresholds'),
'CentralityLowerThrs.mif', [
int(round(loBound / aModule.etSumLsb.value()))
for loBound
in aModule.etSumCentralityLower.value()]),
148 ((
'demux',
'ET_centralityUpperThresholds'),
'CentralityUpperThrs.mif', [
int(round(upBound / aModule.etSumLsb.value()))
for upBound
in aModule.etSumCentralityUpper.value()]),
149 ((
'demux',
'MET_energyCalibLUT'),
'M_METnoHFenergyCalibration_12to18.mif',
parseOfflineLUTfile(aModule.metCalibrationLUTFile.value(), 4096, aTruncate =
True)),
150 ((
'demux',
'METHF_energyCalibLUT'),
'M_METwithHFenergyCalibration_12to18.mif',
parseOfflineLUTfile(aModule.metHFCalibrationLUTFile.value(), 4096, aTruncate =
True)),
151 ((
'demux',
'ET_energyCalibLUT'),
'S_ETcalibration_12to18.mif',
parseOfflineLUTfile(aModule.etSumEttCalibrationLUTFile.value(), 4096, aTruncate =
True)),
152 ((
'demux',
'ecalET_energyCalibLUT'),
'R_EcalCalibration_12to18.mif',
parseOfflineLUTfile(aModule.etSumEcalSumCalibrationLUTFile.value(), 4096, aTruncate =
True)),
153 ((
'demux',
'MET_phiCalibLUT'),
'Q_METnoHFphiCalibration_12to18.mif',
parseOfflineLUTfile(aModule.metPhiCalibrationLUTFile.value(), 4096, aTruncate =
True)),
154 ((
'demux',
'METHF_phiCalibLUT'),
'Q_METwithHFphiCalibration_12to18.mif',
parseOfflineLUTfile(aModule.metHFPhiCalibrationLUTFile.value(), 4096, aTruncate =
True)),
157 result = [(a, b,
parseOfflineLUTfile(c.value())
if isinstance(c, cms.FileInPath)
else c)
for a, b, c
in result]
165 if xmlDetails
is not None:
166 if xmlDetails[0]
in result:
167 result[xmlDetails[0]] += [(xmlDetails[1], value)]
169 result[xmlDetails[0]] = [(xmlDetails[1], value)]
178 return {mifFileName : value
for (_, mifFileName, value)
in fullList
if mifFileName
is not None}
185 if not elem.text
or not elem.text.strip():
187 if not elem.tail
or not elem.tail.strip():
191 if not elem.tail
or not elem.tail.strip():
194 if level
and (
not elem.tail
or not elem.tail.strip()):
198 print(
"Writing MIF file:", aFilePath)
199 with open(aFilePath,
'w')
as f:
200 if isinstance(aValue, bool):
201 aValue = (1
if aValue
else 0)
203 if isinstance(aValue, int):
204 f.write( hex(aValue) )
205 elif isinstance(aValue, list):
206 f.write(
"\n".
join([hex(x)
for x
in aValue]))
208 raise RuntimeError(
"Do not know how to deal with parameter of type " +
str(type(aValue)))
212 topNode = ET.Element(
'algo', id=
'calol2')
213 contextNode = ET.SubElement(topNode,
'context', id=contextId)
214 for paramId, value
in parameters:
215 if isinstance(value, bool):
216 ET.SubElement(contextNode,
'param', id=paramId, type=
'bool').text =
str(value).lower()
217 elif isinstance(value, int):
218 ET.SubElement(contextNode,
'param', id=paramId, type=
'uint').text =
"0x{0:05X}".
format(value)
219 elif isinstance(value, str):
220 ET.SubElement(contextNode,
'param', id=paramId, type=
'string').text = value
221 elif isinstance(value, list):
222 ET.SubElement(contextNode,
'param', id=paramId, type=
'vector:uint').text =
"\n " +
",\n ".
join([
"0x{0:05X}".
format(x)
for x
in value]) +
"\n " 224 raise RuntimeError(
"Do not know how to deal with parameter '" + paramId +
"' of type " +
str(type(value)))
227 print(
"Writing XML file:", outputFilePath)
228 with open(outputFilePath,
'w')
as f:
229 f.write(ET.tostring(topNode))
233 if __name__ ==
'__main__':
235 parser = argparse.ArgumentParser()
237 parser.add_argument(
'params_cfi', help=
'Name of CMSSW cfi python file specifying the values for the calo parameters')
238 parser.add_argument(
'output_dir', help=
'Directory for MIF/XML output files')
240 outputFormatGroup = parser.add_mutually_exclusive_group(required=
True)
241 outputFormatGroup.add_argument(
'--mif', action=
'store_true')
242 outputFormatGroup.add_argument(
'--xml', action=
'store_true')
244 args = parser.parse_args()
246 moduleName =
'L1Trigger.L1TCalorimeter.' + args.params_cfi
247 print(
"Importing calo params from module:", moduleName)
248 caloParams = import_module(moduleName).caloStage2Params
250 print(caloParams.egCalibrationLUTFile.value())
251 print(caloParams.egIsoLUTFile.value())
252 print(caloParams.egIsoLUTFile2.value())
253 os.mkdir(args.output_dir)
257 createMIF(args.output_dir +
'/' + fileName, value)
260 createXML(paramList,
'MainProcessor' if fileTag.startswith(
'mp')
else 'Demux', args.output_dir +
'/algo_' + fileTag +
'.xml')
std::vector< std::string_view > split(std::string_view, const char *)
S & print(S &os, JobReport::InputFile const &f)
static std::string join(char **cmd)