CMS 3D CMS Logo

generateGeometry.py
Go to the documentation of this file.
1 from __future__ import print_function
2 from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter, RawTextHelpFormatter, RawDescriptionHelpFormatter
3 import sys, os, operator
4 from pprint import pprint
5 import filecmp
6 
7 # convenience definition
8 # (from ConfigArgParse)
10  ArgumentDefaultsHelpFormatter,
11  RawTextHelpFormatter,
12  RawDescriptionHelpFormatter):
13  """HelpFormatter that adds default values AND doesn't do line-wrapping"""
14 pass
15 
17  def __init__(self, scriptName, detectorVersionDefault, detectorPrefix, detectorYear, maxSections, allDicts, detectorVersionDict, deprecatedDets = None, deprecatedSubdets = None, detectorVersionType = int):
18  self.scriptName = scriptName
19  self.detectorVersionDefault = detectorVersionDefault
20  self.detectorPrefix = detectorPrefix
21  self.detectorYear = detectorYear
22  self.maxSections = maxSections
23  self.allDicts = allDicts
24  self.detectorVersionDict = detectorVersionDict
25  self.deprecatedDets = deprecatedDets
26  self.deprecatedSubdets = deprecatedSubdets
27  self.detectorVersionType = detectorVersionType
28 
29  def generateGeom(self, detectorTuple, args):
30  detectorVersion = self.detectorPrefix+str(args.detectorVersionManual)
31  # reverse dict search if overall D# specified
32  if args.v_detector>0:
33  detectorVersion = self.detectorPrefix+str(args.v_detector)
34  if detectorVersion in self.detectorVersionDict.values():
35  detectorTuple = self.detectorVersionDict.keys()[self.detectorVersionDict.values().index(detectorVersion)]
36  else:
37  print("Unknown detector "+detectorVersion)
38  sys.exit(1)
39  elif detectorTuple in self.detectorVersionDict.keys():
40  detectorVersion = self.detectorVersionDict[detectorTuple]
41  else:
42  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))
43 
44  # check for deprecation
45  if self.deprecatedDets is not None and detectorVersion in self.deprecatedDets:
46  print("Error: "+detectorVersion+" is deprecated and cannot be used.")
47  sys.exit(1)
48  if self.deprecatedSubdets is not None:
49  for subdet in detectorTuple:
50  if subdet in self.deprecatedSubdets:
51  print("Error: "+subdet+" is deprecated and cannot be used.")
52  sys.exit(1)
53 
54  # create output files
55  xmlName = "cmsExtendedGeometry"+self.detectorYear+detectorVersion+"XML_cfi.py"
56  xmlDD4hepName = "cmsExtendedGeometry"+self.detectorYear+detectorVersion+".xml"
57  simName = "GeometryExtended"+self.detectorYear+detectorVersion+"_cff.py"
58  simDD4hepName = "GeometryDD4hepExtended"+self.detectorYear+detectorVersion+"_cff.py"
59  recoName = "GeometryExtended"+self.detectorYear+detectorVersion+"Reco_cff.py"
60  recoDD4hepName = "GeometryDD4hepExtended"+self.detectorYear+detectorVersion+"Reco_cff.py"
61 
62  # check directories
63  CMSSWBASE = os.getenv("CMSSW_BASE")
64  CMSSWRELBASE = os.getenv("CMSSW_RELEASE_BASE")
65  if CMSSWBASE is None: CMSSWBASE = ""
66  xmlDir = os.path.join(CMSSWBASE,"src","Geometry","CMSCommonData","python")
67  xmlDD4hepDir = os.path.join(CMSSWBASE,"src","Geometry","CMSCommonData","data","dd4hep")
68  simrecoDir = os.path.join(CMSSWBASE,"src","Configuration","Geometry","python")
69  simrecoDD4hepDir = os.path.join(CMSSWBASE,"src","Configuration","Geometry","python")
70  if args.doTest:
71  if not os.path.isdir(xmlDir):
72  xmlDir = os.path.join(CMSSWRELBASE,"src","Geometry","CMSCommonData","python")
73  xmlDD4hepDir = os.path.join(CMSSWRELBASE,"src","Geometry","CMSCommonData","data","dd4hep")
74  else:
75  mvCommands = ""
76  if not os.path.isdir(xmlDir):
77  mvCommands += "mv "+xmlName+" "+xmlDir+"/\n"
78  else:
79  xmlName = os.path.join(xmlDir,xmlName)
80  if not os.path.isdir(xmlDD4hepDir):
81  mvCommands += "mv "+xmlDD4hepName+" "+xmlDD4hepDir+"/\n"
82  else:
83  xmlDD4hepName = os.path.join(xmlDD4hepDir,xmlDD4hepName)
84  if not os.path.isdir(simrecoDir):
85  mvCommands += "mv "+simName+" "+simrecoDir+"/\n"
86  mvCommands += "mv "+recoName+" "+simrecoDir+"/\n"
87  else:
88  simName = os.path.join(simrecoDir,simName)
89  recoName = os.path.join(simrecoDir,recoName)
90  if not os.path.isdir(simrecoDD4hepDir):
91  mvCommands += "mv "+simDD4hepName+" "+simrecoDD4hepDir+"/\n"
92  mvCommands += "mv "+recoDD4hepName+" "+simrecoDD4hepDir+"/\n"
93  else:
94  simDD4hepName = os.path.join(simrecoDD4hepDir,simDD4hepName)
95  recoDD4hepName = os.path.join(simrecoDD4hepDir,recoDD4hepName)
96  if len(mvCommands)>0:
97  print("Warning: some geometry packages not checked out.\nOnce they are available, please execute the following commands manually:\n"+mvCommands)
98 
99  # open files
100  xmlFile = open(xmlName,'w')
101  xmlDD4hepFile = open(xmlDD4hepName,'w')
102  simFile = open(simName,'w')
103  simDD4hepFile = open(simDD4hepName,'w')
104  recoFile = open(recoName,'w')
105  recoDD4hepFile = open(recoDD4hepName,'w')
106 
107  # common preamble
108  preamble = "import FWCore.ParameterSet.Config as cms"+"\n"+"\n"
109  preamble += "# This config was generated automatically using "+self.scriptName+"\n"
110  preamble += "# If you notice a mistake, please update the generating script, not just this config"+"\n"+"\n"
111 
112  # create XML config
113  xmlFile.write(preamble)
114  # extra preamble
115  xmlFile.write("XMLIdealGeometryESSource = cms.ESSource(\"XMLIdealGeometryESSource\","+"\n")
116  xmlFile.write(" geomXMLFiles = cms.vstring("+"\n")
117  for section in range(1,self.maxSections+1):
118  # midamble
119  if section==2:
120  xmlFile.write(" )+"+"\n"+" cms.vstring("+"\n")
121  for iDict,aDict in enumerate(self.allDicts):
122  if section in aDict[detectorTuple[iDict]].keys():
123  xmlFile.write('\n'.join([ " '"+aLine+"'," for aLine in aDict[detectorTuple[iDict]][section] ])+"\n")
124  # postamble
125  xmlFile.write(" ),"+"\n"+" rootNodeName = cms.string('cms:OCMS')"+"\n"+")"+"\n")
126  xmlFile.close()
127 
128  # create DD4hep XML config
129  xmlDD4hepFile.write("<?xml version=\"1.0\"?>\n"+
130  "<DDDefinition>\n"+
131  " <open_geometry/>\n"+
132  " <close_geometry/>\n"+
133  "\n"+
134  " <IncludeSection>\n")
135  for section in range(1,self.maxSections+1):
136  # midamble
137  for iDict,aDict in enumerate(self.allDicts):
138  if section in aDict[detectorTuple[iDict]].keys():
139  xmlDD4hepFile.write('\n'.join([ " <Include ref='"+aLine+"'/>" for aLine in aDict[detectorTuple[iDict]][section] ])+"\n")
140  # postamble
141  xmlDD4hepFile.write(" </IncludeSection>\n"+
142  "</DDDefinition>"+"\n")
143  xmlDD4hepFile.close()
144 
145  # create sim config
146  simFile.write(preamble)
147  # always need XML
148  simFile.write("from Geometry.CMSCommonData."+os.path.basename(xmlName).replace(".py","")+" import *"+"\n")
149  for iDict,aDict in enumerate(self.allDicts):
150  if "sim" in aDict[detectorTuple[iDict]].keys():
151  simFile.write('\n'.join([ aLine for aLine in aDict[detectorTuple[iDict]]["sim"] ])+"\n")
152  simFile.close()
153 
154  # create simDD4hep config
155  simDD4hepFile.write(preamble)
156  # always need XML
157  simDD4hepFile.write("from Configuration.Geometry.GeometryDD4hep_cff"+" import *"+"\n")
158  simDD4hepFile.write("DDDetectorESProducer.confGeomXMLFiles = cms.FileInPath(\"Geometry/CMSCommonData/data/dd4hep/"+os.path.basename(xmlDD4hepName)+"\")\n\n")
159  for iDict,aDict in enumerate(self.allDicts):
160  if "sim" in aDict[detectorTuple[iDict]].keys():
161  simDD4hepFile.write('\n'.join([ aLine for aLine in aDict[detectorTuple[iDict]]["sim"] ])+"\n")
162  simDD4hepFile.close()
163 
164  # create reco config
165  recoFile.write(preamble)
166  # always need sim
167  recoFile.write("from Configuration.Geometry."+os.path.basename(simName).replace(".py","")+" import *"+"\n\n")
168  for iDict,aDict in enumerate(self.allDicts):
169  if "reco" in aDict[detectorTuple[iDict]].keys():
170  recoFile.write("# "+aDict["name"]+"\n")
171  recoFile.write('\n'.join([ aLine for aLine in aDict[detectorTuple[iDict]]["reco"] ])+"\n\n")
172  recoFile.close()
173 
174  # create recoDD4hep config
175  recoDD4hepFile.write(preamble)
176  # always need sim
177  recoDD4hepFile.write("from Configuration.Geometry."+os.path.basename(simDD4hepName).replace(".py","")+" import *"+"\n\n")
178  for iDict,aDict in enumerate(self.allDicts):
179  if "reco" in aDict[detectorTuple[iDict]].keys():
180  recoDD4hepFile.write("# "+aDict["name"]+"\n")
181  recoDD4hepFile.write('\n'.join([ aLine for aLine in aDict[detectorTuple[iDict]]["reco"] ])+"\n\n")
182  recoDD4hepFile.close()
183 
184  from Configuration.StandardSequences.GeometryConf import GeometryConf
185  if not args.doTest: # todo: include these in unit test somehow
186  # specify Era customizations
187  # must be checked manually in:
188  # Configuration/StandardSequences/python/Eras.py
189  # Configuration/Eras/python/
190  # Configuration/PyReleaseValidation/python/upgradeWorkflowComponents.py (workflow definitions)
191  eraLine = ""
192  eraLineItems = []
193  for iDict,aDict in enumerate(self.allDicts):
194  if "era" in aDict[detectorTuple[iDict]].keys():
195  eraLineItems.append(aDict[detectorTuple[iDict]]["era"])
196  eraLine += ", ".join([ eraLineItem for eraLineItem in eraLineItems ])
197  print("The Era for this detector should contain:")
198  print(eraLine)
199 
200  # specify GeometryConf
201  if not 'Extended'+self.detectorYear+detectorVersion in GeometryConf.keys():
202  print("Please add this line in Configuration/StandardSequences/python/GeometryConf.py:")
203  print(" 'Extended"+self.detectorYear+detectorVersion+"' : 'Extended"+self.detectorYear+detectorVersion+",Extended"+self.detectorYear+detectorVersion+"Reco',")
204 
205  errorList = []
206 
207  if args.doTest:
208  # tests for Configuration/Geometry
209  simFile = os.path.join(simrecoDir,simName)
210  if not os.path.isfile(simFile):
211  errorList.append(simName+" missing")
212  elif not filecmp.cmp(simName,simFile):
213  errorList.append(simName+" differs")
214  simDD4hepFile = os.path.join(simrecoDD4hepDir,simDD4hepName)
215  if not os.path.isfile(simDD4hepFile):
216  errorList.append(simDD4hepName+" missing")
217  elif not filecmp.cmp(simDD4hepName,simDD4hepFile):
218  errorList.append(simDD4hepName+" differs")
219  recoFile = os.path.join(simrecoDir,recoName)
220  if not os.path.isfile(recoFile):
221  errorList.append(recoName+" missing")
222  elif not filecmp.cmp(recoName,recoFile):
223  errorList.append(recoName+" differs")
224  recoDD4hepFile = os.path.join(simrecoDD4hepDir,recoDD4hepName)
225  if not os.path.isfile(recoDD4hepFile):
226  errorList.append(recoDD4hepName+" missing")
227  elif not filecmp.cmp(recoDD4hepName,recoDD4hepFile):
228  errorList.append(recoDD4hepName+" differs")
229  # test for Configuration/StandardSequences
230  if not 'Extended'+self.detectorYear+detectorVersion in GeometryConf.keys():
231  errorList.append('Extended'+self.detectorYear+detectorVersion+" missing from GeometryConf")
232  # test for Geometry/CMSCommonData
233  xmlFile = os.path.join(xmlDir,xmlName)
234  if not os.path.isfile(xmlFile):
235  errorList.append(xmlName+" missing")
236  elif not filecmp.cmp(xmlName,xmlFile):
237  errorList.append(xmlName+" differs")
238  # test for dd4hep xml
239  xmlDD4hepFile = os.path.join(xmlDD4hepDir,xmlDD4hepName)
240  if not os.path.exists(xmlDD4hepFile):
241  errorList.append(xmlDD4hepName+" differs")
242  elif not filecmp.cmp(xmlDD4hepName,xmlDD4hepFile):
243  errorList.append(xmlDD4hepName+" differs")
244  return errorList
245 
246  def run(self):
247  # define options
248  parser = ArgumentParser(formatter_class=ArgumentDefaultsRawHelpFormatter)
249  for aDict in self.allDicts:
250  parser.add_argument("-"+aDict["abbrev"], "--"+aDict["name"], dest="v_"+aDict["name"], default=aDict["default"], type=int, help="version for "+aDict["name"])
251  parser.add_argument("-V", "--version", dest="detectorVersionManual", default=self.detectorVersionDefault, type=int, help="manual detector version number")
252  parser.add_argument("-D", "--detector", dest="v_detector", default=0, type=self.detectorVersionType, help="version for whole detector, ignored if 0, overrides subdet versions otherwise")
253  parser.add_argument("-l", "--list", dest="doList", default=False, action="store_true", help="list known detector versions and exit")
254  parser.add_argument("-t", "--test", dest="doTest", default=False, action="store_true", help="enable unit test mode")
255  args = parser.parse_args()
256 
257  # check options
258  if args.doList and not args.doTest:
259  pprint(sorted(self.detectorVersionDict.items(),key=operator.itemgetter(1)))
260  sys.exit(0)
261  elif args.doTest:
262  # list of errors
263  errorList = []
264  # run all known possibilities
265  for detectorTuple in self.detectorVersionDict:
266  errorTmp = self.generateGeom(detectorTuple,args)
267  errorList.extend(errorTmp)
268  if len(errorList)>0:
269  print('\n'.join([anError for anError in errorList]))
270  sys.exit(1)
271  else:
272  sys.exit(0)
273  else:
274  detectorTuple = tuple([aDict["abbrev"]+str(getattr(args,"v_"+aDict["name"])) for aDict in self.allDicts])
275  self.generateGeom(detectorTuple,args)
276  sys.exit(0)
277 
FastTimerService_cff.range
range
Definition: FastTimerService_cff.py:34
resolutioncreator_cfi.object
object
Definition: resolutioncreator_cfi.py:4
generateGeometry.GeometryGenerator.generateGeom
def generateGeom(self, detectorTuple, args)
Definition: generateGeometry.py:29
join
static std::string join(char **cmd)
Definition: RemoteFile.cc:17
generateGeometry.GeometryGenerator.deprecatedSubdets
deprecatedSubdets
Definition: generateGeometry.py:26
relativeConstraints.keys
keys
Definition: relativeConstraints.py:89
mps_monitormerge.items
list items
Definition: mps_monitormerge.py:29
generateGeometry.GeometryGenerator.allDicts
allDicts
Definition: generateGeometry.py:23
generateGeometry.GeometryGenerator.run
def run(self)
Definition: generateGeometry.py:246
contentValuesCheck.values
values
Definition: contentValuesCheck.py:38
str
#define str(s)
Definition: TestProcessor.cc:52
generateGeometry.GeometryGenerator.maxSections
maxSections
Definition: generateGeometry.py:22
generateGeometry.GeometryGenerator.detectorVersionDefault
detectorVersionDefault
Definition: generateGeometry.py:19
print
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:46
generateGeometry.GeometryGenerator
Definition: generateGeometry.py:16
generateGeometry.GeometryGenerator.deprecatedDets
deprecatedDets
Definition: generateGeometry.py:25
generateGeometry.GeometryGenerator.detectorVersionDict
detectorVersionDict
Definition: generateGeometry.py:24
generateGeometry.GeometryGenerator.detectorYear
detectorYear
Definition: generateGeometry.py:21
generateGeometry.GeometryGenerator.__init__
def __init__(self, scriptName, detectorVersionDefault, detectorPrefix, detectorYear, maxSections, allDicts, detectorVersionDict, deprecatedDets=None, deprecatedSubdets=None, detectorVersionType=int)
Definition: generateGeometry.py:17
AlignmentPI::index
index
Definition: AlignmentPayloadInspectorHelper.h:46
generateGeometry.GeometryGenerator.scriptName
scriptName
Definition: generateGeometry.py:18
generateGeometry.GeometryGenerator.detectorPrefix
detectorPrefix
Definition: generateGeometry.py:20
generateGeometry.ArgumentDefaultsRawHelpFormatter
Definition: generateGeometry.py:12
generateGeometry.GeometryGenerator.detectorVersionType
detectorVersionType
Definition: generateGeometry.py:27
python.rootplot.root2matplotlib.replace
def replace(string, replacements)
Definition: root2matplotlib.py:444