Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:03:38

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