File indexing completed on 2024-12-01 23:40:06
0001 from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter, RawTextHelpFormatter, RawDescriptionHelpFormatter
0002 import sys, os, operator
0003 from pprint import pprint
0004 import filecmp
0005
0006
0007
0008 class ArgumentDefaultsRawHelpFormatter(
0009 ArgumentDefaultsHelpFormatter,
0010 RawTextHelpFormatter,
0011 RawDescriptionHelpFormatter):
0012 """HelpFormatter that adds default values AND doesn't do line-wrapping"""
0013 pass
0014
0015 class GeometryGenerator(object):
0016 def __init__(self, scriptName, detectorVersionDefault, detectorPrefix, detectorYear, maxSections, allDicts, detectorVersionDict, deprecatedDets = None, deprecatedSubdets = None, detectorVersionType = int):
0017 self.scriptName = scriptName
0018 self.detectorVersionDefault = detectorVersionDefault
0019 self.detectorPrefix = detectorPrefix
0020 self.detectorYear = detectorYear
0021 self.maxSections = maxSections
0022 self.allDicts = allDicts
0023 self.detectorVersionDict = detectorVersionDict
0024 self.deprecatedDets = deprecatedDets
0025 self.deprecatedSubdets = deprecatedSubdets
0026 self.detectorVersionType = detectorVersionType
0027 self.detectorVersionNull = self.detectorVersionType(0)
0028 self.dd4hepDetectorVersion = 91
0029
0030 def generateGeom(self, detectorTuple, args):
0031 detectorVersion = self.detectorPrefix+str(args.detectorVersionManual)
0032
0033 if args.v_detector!=self.detectorVersionNull:
0034 detectorVersion = self.detectorPrefix+str(args.v_detector)
0035 if detectorVersion in self.detectorVersionDict.values():
0036 detectorTuple = list(self.detectorVersionDict.keys())[list(self.detectorVersionDict.values()).index(detectorVersion)]
0037 else:
0038 print("Unknown detector "+detectorVersion)
0039 sys.exit(1)
0040 elif detectorTuple in self.detectorVersionDict.keys():
0041 detectorVersion = self.detectorVersionDict[detectorTuple]
0042 else:
0043 if not args.doTest: print("Detector "+str(detectorTuple)+" not found in dictionary, using "+("default" if args.detectorVersionManual==self.detectorVersionDefault else "provided")+" version number "+str(detectorVersion))
0044
0045
0046 if self.deprecatedDets is not None and detectorVersion in self.deprecatedDets:
0047 print("Error: "+detectorVersion+" is deprecated and cannot be used.")
0048 sys.exit(1)
0049 if self.deprecatedSubdets is not None:
0050 for subdet in detectorTuple:
0051 if subdet in self.deprecatedSubdets:
0052 print("Error: "+subdet+" is deprecated and cannot be used.")
0053 sys.exit(1)
0054
0055
0056 xmlName = "cmsExtendedGeometry"+self.detectorYear+detectorVersion+"XML_cfi.py"
0057 xmlDD4hepName = "cmsExtendedGeometry"+self.detectorYear+detectorVersion+".xml"
0058 simName = "GeometryExtended"+self.detectorYear+detectorVersion+"_cff.py"
0059 simDD4hepName = "GeometryDD4hepExtended"+self.detectorYear+detectorVersion+"_cff.py"
0060 recoName = "GeometryExtended"+self.detectorYear+detectorVersion+"Reco_cff.py"
0061 recoDD4hepName = "GeometryDD4hepExtended"+self.detectorYear+detectorVersion+"Reco_cff.py"
0062
0063
0064 CMSSWBASE = os.getenv("CMSSW_BASE")
0065 CMSSWRELBASE = os.getenv("CMSSW_RELEASE_BASE")
0066 if CMSSWBASE is None: CMSSWBASE = ""
0067 xmlDir = os.path.join(CMSSWBASE,"src","Geometry","CMSCommonData","python")
0068 xmlDD4hepDir = os.path.join(CMSSWBASE,"src","Geometry","CMSCommonData","data","dd4hep")
0069 simrecoDir = os.path.join(CMSSWBASE,"src","Configuration","Geometry","python")
0070 simrecoDD4hepDir = os.path.join(CMSSWBASE,"src","Configuration","Geometry","python")
0071 if args.doTest:
0072 if not os.path.isdir(xmlDir):
0073 xmlDir = os.path.join(CMSSWRELBASE,"src","Geometry","CMSCommonData","python")
0074 xmlDD4hepDir = os.path.join(CMSSWRELBASE,"src","Geometry","CMSCommonData","data","dd4hep")
0075 else:
0076 mvCommands = ""
0077 if not os.path.isdir(xmlDir):
0078 mvCommands += "mv "+xmlName+" "+xmlDir+"/\n"
0079 else:
0080 xmlName = os.path.join(xmlDir,xmlName)
0081 if not os.path.isdir(xmlDD4hepDir):
0082 mvCommands += "mv "+xmlDD4hepName+" "+xmlDD4hepDir+"/\n"
0083 else:
0084 xmlDD4hepName = os.path.join(xmlDD4hepDir,xmlDD4hepName)
0085 if not os.path.isdir(simrecoDir):
0086 mvCommands += "mv "+simName+" "+simrecoDir+"/\n"
0087 mvCommands += "mv "+recoName+" "+simrecoDir+"/\n"
0088 else:
0089 simName = os.path.join(simrecoDir,simName)
0090 recoName = os.path.join(simrecoDir,recoName)
0091 if not os.path.isdir(simrecoDD4hepDir):
0092 mvCommands += "mv "+simDD4hepName+" "+simrecoDD4hepDir+"/\n"
0093 mvCommands += "mv "+recoDD4hepName+" "+simrecoDD4hepDir+"/\n"
0094 else:
0095 simDD4hepName = os.path.join(simrecoDD4hepDir,simDD4hepName)
0096 recoDD4hepName = os.path.join(simrecoDD4hepDir,recoDD4hepName)
0097 if len(mvCommands)>0:
0098 print("Warning: some geometry packages not checked out.\nOnce they are available, please execute the following commands manually:\n"+mvCommands)
0099
0100
0101 xmlFile = open(xmlName,'w')
0102 xmlDD4hepFile = open(xmlDD4hepName,'w')
0103 simFile = open(simName,'w')
0104 simDD4hepFile = open(simDD4hepName,'w')
0105 recoFile = open(recoName,'w')
0106 recoDD4hepFile = open(recoDD4hepName,'w')
0107
0108
0109 preamble = "import FWCore.ParameterSet.Config as cms"+"\n"+"\n"
0110 preamble += "# This config was generated automatically using "+self.scriptName+"\n"
0111 preamble += "# If you notice a mistake, please update the generating script, not just this config"+"\n"+"\n"
0112
0113
0114 xmlFile.write(preamble)
0115
0116 xmlFile.write("XMLIdealGeometryESSource = cms.ESSource(\"XMLIdealGeometryESSource\","+"\n")
0117 xmlFile.write(" geomXMLFiles = cms.vstring("+"\n")
0118 for section in range(1,self.maxSections+1):
0119
0120 if section==2:
0121 xmlFile.write(" )+"+"\n"+" cms.vstring("+"\n")
0122 for iDict,aDict in enumerate(self.allDicts):
0123 if section in aDict[detectorTuple[iDict]].keys():
0124 xmlFile.write('\n'.join([ " '"+aLine+"'," for aLine in aDict[detectorTuple[iDict]][section] ])+"\n")
0125
0126 xmlFile.write(" ),"+"\n"+" rootNodeName = cms.string('cms:OCMS')"+"\n"+")"+"\n")
0127 xmlFile.close()
0128
0129
0130 xmlDD4hepFile.write("<?xml version=\"1.0\"?>\n"+
0131 "<DDDefinition>\n"+
0132 " <open_geometry/>\n"+
0133 " <close_geometry/>\n"+
0134 "\n"+
0135 " <IncludeSection>\n")
0136 for section in range(1,self.maxSections+1):
0137
0138 for iDict,aDict in enumerate(self.allDicts):
0139 if section in aDict[detectorTuple[iDict]].keys():
0140 xmlDD4hepFile.write('\n'.join([ " <Include ref='"+aLine+"'/>" for aLine in aDict[detectorTuple[iDict]][section] ])+"\n")
0141
0142 xmlDD4hepFile.write(" </IncludeSection>\n"+
0143 "</DDDefinition>"+"\n")
0144 xmlDD4hepFile.close()
0145
0146
0147 simFile.write(preamble)
0148
0149 simFile.write("from Geometry.CMSCommonData."+os.path.basename(xmlName).replace(".py","")+" import *"+"\n")
0150 for iDict,aDict in enumerate(self.allDicts):
0151 if "sim" in aDict[detectorTuple[iDict]].keys():
0152 simFile.write('\n'.join([ aLine for aLine in aDict[detectorTuple[iDict]]["sim"] ])+"\n")
0153 simFile.close()
0154
0155
0156 simDD4hepFile.write(preamble)
0157
0158 simDD4hepFile.write("from Configuration.Geometry.GeometryDD4hep_cff"+" import *"+"\n")
0159 simDD4hepFile.write("DDDetectorESProducer.confGeomXMLFiles = cms.FileInPath(\"Geometry/CMSCommonData/data/dd4hep/"+os.path.basename(xmlDD4hepName)+"\")\n\n")
0160 for iDict,aDict in enumerate(self.allDicts):
0161 if "sim" in aDict[detectorTuple[iDict]].keys():
0162 simDD4hepFile.write('\n'.join([ aLine for aLine in aDict[detectorTuple[iDict]]["sim"] ])+"\n")
0163 simDD4hepFile.close()
0164
0165
0166 recoFile.write(preamble)
0167
0168 recoFile.write("from Configuration.Geometry."+os.path.basename(simName).replace(".py","")+" import *"+"\n\n")
0169 for iDict,aDict in enumerate(self.allDicts):
0170 if "reco" in aDict[detectorTuple[iDict]].keys():
0171 recoFile.write("# "+aDict["name"]+"\n")
0172 recoFile.write('\n'.join([ aLine for aLine in aDict[detectorTuple[iDict]]["reco"] ])+"\n\n")
0173 recoFile.close()
0174
0175
0176 recoDD4hepFile.write(preamble)
0177
0178 recoDD4hepFile.write("from Configuration.Geometry."+os.path.basename(simDD4hepName).replace(".py","")+" import *"+"\n\n")
0179 for iDict,aDict in enumerate(self.allDicts):
0180 if "reco" in aDict[detectorTuple[iDict]].keys():
0181 recoDD4hepFile.write("# "+aDict["name"]+"\n")
0182 recoDD4hepFile.write('\n'.join([ aLine for aLine in aDict[detectorTuple[iDict]]["reco"] ])+"\n\n")
0183 recoDD4hepFile.close()
0184
0185 from Configuration.StandardSequences.GeometryConf import GeometryConf
0186 if not args.doTest:
0187
0188
0189
0190
0191
0192 eraLine = ""
0193 eraLineItems = []
0194 for iDict,aDict in enumerate(self.allDicts):
0195 if "era" in aDict[detectorTuple[iDict]].keys():
0196 eraLineItems.append(aDict[detectorTuple[iDict]]["era"])
0197 eraLine += ", ".join([ eraLineItem for eraLineItem in eraLineItems ])
0198 print("The Era for this detector should contain:")
0199 print(eraLine)
0200
0201
0202 if not 'Extended'+self.detectorYear+detectorVersion in GeometryConf.keys():
0203 print("Please add this line in Configuration/StandardSequences/python/GeometryConf.py:")
0204 print(" 'Extended"+self.detectorYear+detectorVersion+"' : 'Extended"+self.detectorYear+detectorVersion+",Extended"+self.detectorYear+detectorVersion+"Reco',")
0205 if self.detectorYear == "Run4" and int(args.v_detector) > self.dd4hepDetectorVersion:
0206 print(" 'DD4hepExtended"+self.detectorYear+detectorVersion+"' : 'DD4hepExtended"+self.detectorYear+detectorVersion+",DD4hepExtended"+self.detectorYear+detectorVersion+"Reco',")
0207
0208 errorList = []
0209
0210 if args.doTest:
0211
0212 simFile = os.path.join(simrecoDir,simName)
0213 if not os.path.isfile(simFile):
0214 errorList.append(simName+" missing")
0215 elif not filecmp.cmp(simName,simFile):
0216 errorList.append(simName+" differs")
0217 simDD4hepFile = os.path.join(simrecoDD4hepDir,simDD4hepName)
0218 if not os.path.isfile(simDD4hepFile):
0219 errorList.append(simDD4hepName+" missing")
0220 elif not filecmp.cmp(simDD4hepName,simDD4hepFile):
0221 errorList.append(simDD4hepName+" differs")
0222 recoFile = os.path.join(simrecoDir,recoName)
0223 if not os.path.isfile(recoFile):
0224 errorList.append(recoName+" missing")
0225 elif not filecmp.cmp(recoName,recoFile):
0226 errorList.append(recoName+" differs")
0227 recoDD4hepFile = os.path.join(simrecoDD4hepDir,recoDD4hepName)
0228 if not os.path.isfile(recoDD4hepFile):
0229 errorList.append(recoDD4hepName+" missing")
0230 elif not filecmp.cmp(recoDD4hepName,recoDD4hepFile):
0231 errorList.append(recoDD4hepName+" differs")
0232
0233 if not 'Extended'+self.detectorYear+detectorVersion in GeometryConf.keys():
0234 errorList.append('Extended'+self.detectorYear+detectorVersion+" missing from GeometryConf")
0235
0236 xmlFile = os.path.join(xmlDir,xmlName)
0237 if not os.path.isfile(xmlFile):
0238 errorList.append(xmlName+" missing")
0239 elif not filecmp.cmp(xmlName,xmlFile):
0240 errorList.append(xmlName+" differs")
0241
0242 xmlDD4hepFile = os.path.join(xmlDD4hepDir,xmlDD4hepName)
0243 if not os.path.exists(xmlDD4hepFile):
0244 errorList.append(xmlDD4hepName+" differs")
0245 elif not filecmp.cmp(xmlDD4hepName,xmlDD4hepFile):
0246 errorList.append(xmlDD4hepName+" differs")
0247 return errorList
0248
0249 def run(self):
0250
0251 parser = ArgumentParser(formatter_class=ArgumentDefaultsRawHelpFormatter)
0252 for aDict in self.allDicts:
0253 parser.add_argument("-"+aDict["abbrev"], "--"+aDict["name"], dest="v_"+aDict["name"], default=aDict["default"], type=int, help="version for "+aDict["name"])
0254 parser.add_argument("-V", "--version", dest="detectorVersionManual", default=self.detectorVersionDefault, type=int, help="manual detector version number")
0255 parser.add_argument("-D", "--detector", dest="v_detector", default=self.detectorVersionNull, type=self.detectorVersionType, help="version for whole detector, ignored if 0, overrides subdet versions otherwise")
0256 parser.add_argument("-l", "--list", dest="doList", default=False, action="store_true", help="list known detector versions and exit")
0257 parser.add_argument("-t", "--test", dest="doTest", default=False, action="store_true", help="enable unit test mode")
0258 args = parser.parse_args()
0259
0260
0261 if args.doList and not args.doTest:
0262 pprint(sorted(self.detectorVersionDict.items(),key=operator.itemgetter(1)))
0263 sys.exit(0)
0264 elif args.doTest:
0265
0266 errorList = []
0267
0268 for detectorTuple in self.detectorVersionDict:
0269 errorTmp = self.generateGeom(detectorTuple,args)
0270 errorList.extend(errorTmp)
0271 if len(errorList)>0:
0272 print('\n'.join([anError for anError in errorList]))
0273 sys.exit(1)
0274 else:
0275 sys.exit(0)
0276 else:
0277 detectorTuple = tuple([aDict["abbrev"]+str(getattr(args,"v_"+aDict["name"])) for aDict in self.allDicts])
0278 self.generateGeom(detectorTuple,args)
0279 sys.exit(0)
0280