CMS 3D CMS Logo

duplicateReflexLibrarySearch.py
Go to the documentation of this file.
1 #! /usr/bin/env python
2 
3 from __future__ import print_function
4 import optparse
5 import os
6 import commands
7 import re
8 import sys
9 import pprint
10 import commands
11 import subprocess
12 from XML2Python import xml2obj
13 import six
14 
15 # These aren't all typedefs, but can sometimes make the output more
16 # readable
17 typedefsDict = \
18  {
19  # What we want <= What we have
20  'unsigned int' : ['unsignedint', 'UInt32_t', 'uint32_t'],
21  'unsigned long': ['unsignedlong'],
22  'int' : ['Int32_t'],
23  'float' : ['Float_t'],
24  'double' : ['Double_t'],
25  'char' : ['Char_t'],
26  '< ' : ['<', '&lt;'],
27  ' >' : ['>', '&gt;'],
28  ', ' : [','],
29  }
30 
31 
32 # Equivalent names for packages - lets script know that, for example,
33 # 'TrackReco' package should have objects 'reco::Track'.
34 #Ordered List to search for matched packages
35 equivDict = \
36  [
37  {'TrajectoryState' : ['TrajectoryStateOnSurface']},
38  {'TrackTriggerAssociation' : ['(TTClusterAssociationMap|TTStubAssociationMap|TTTrackAssociationMap).*Phase2TrackerDigi',
39  '(TTStub|TTCluster|TTTrack).*Phase2TrackerDigi']},
40  {'L1TCalorimeter' : ['l1t::CaloTower.*']},
41  {'GsfTracking' : ['reco::GsfTrack(Collection|).*(MomentumConstraint|VertexConstraint)', 'Trajectory.*reco::GsfTrack']},
42  {'ParallelAnalysis' : ['examples::TrackAnalysisAlgorithm']},
43  {'PatCandidates' : ['pat::PATObject','pat::Lepton']},
44  {'BTauReco' : ['reco::.*SoftLeptonTagInfo', 'reco::SoftLeptonProperties','reco::SecondaryVertexTagInfo','reco::IPTagInfo','reco::TemplatedSecondaryVertexTagInfo', 'reco::CATopJetProperties','reco::HTTTopJetProperties']},
45  {'CastorReco' : ['reco::CastorJet']},
46  {'JetMatching' : ['reco::JetFlavourInfo', 'reco::JetFlavour','reco::MatchedPartons']},
47  {'TrackingAnalysis' : ['TrackingParticle']},
48  {'Egamma' : ['reco::ElectronID']},
49  {'TopObjects' : ['reco::CATopJetProperties']},
50  {'TauReco' : ['reco::L2TauIsolationInfo','reco::RecoTauPiZero','reco::BaseTau']},
51  {'ValidationFormats' : ['PGlobalDigi::.+','PGlobalRecHit::.+']},
52  {'TrajectorySeed' : ['TrajectorySeed']},
53  {'TrackCandidate' : ['TrackCandidate']},
54  {'PatternTools' : ['MomentumConstraint','VertexConstraint','Trajectory']},
55  {'TrackerRecHit2D' : ['SiStrip(Matched|)RecHit[12]D','SiTrackerGSRecHit[12]D','SiPixelRecHit']},
56  {'MuonReco' : ['reco::Muon(Ref|)(Vector|)']},
57  {'MuonSeed' : ['L3MuonTrajectorySeed']},
58  {'HepMCCandidate' : ['reco::GenParticle.*']},
59  {'L1Trigger' : ['l1extra::L1.+Particle']},
60  {'TrackInfo' : ['reco::TrackingRecHitInfo']},
61  {'EgammaCandidates' : ['reco::GsfElectron.*','reco::Photon.*']},
62  {'HcalIsolatedTrack' : ['reco::IsolatedPixelTrackCandidate', 'reco::EcalIsolatedParticleCandidate', 'reco::HcalIsolatedTrackCandidate']},
63  {'HcalRecHit' : ['HFRecHit','HORecHit','ZDCRecHit','HBHERecHit']},
64  {'PFRootEvent' : ['EventColin::']},
65  {'CaloTowers' : ['CaloTower.*']},
66  {'GsfTrackReco' : ['GsfTrack.*']},
67  {'METReco' : ['reco::(Calo|PF|Gen|)MET','reco::PFClusterMET']},
68  {'ParticleFlowReco' : ['reco::RecoPFClusterRefCandidateRef.*']},
69  {'ParticleFlowCandidate' : ['reco::PFCandidateRef','reco::PFCandidateFwdRef','reco::PFCandidate']},
70  {'PhysicsToolsObjects' : ['PhysicsTools::Calibration']},
71  {'RecoCandidate' : ['reco::Candidate']},
72  {'TrackReco' : ['reco::Track','reco::TrackRef']},
73  {'VertexReco' : ['reco::Vertex']},
74  {'TFWLiteSelectorTest' : ['tfwliteselectortest']},
75  {'PatCandidates' : ['reco::RecoCandidate','pat::[A-Za-z]+Ref(Vector|)']},
76  {'TauReco' : ['reco::PFJetRef']},
77  {'JetReco' : ['reco::.*Jet','reco::.*Jet(Collection|Ref)']},
78  {'HGCDigi' : ['HGCSample']},
79  ]
80 
81 ignoreEdmDP = {
82  'LCGReflex/__gnu_cxx::__normal_iterator<std::basic_string<char>*,std::vector<std::basic_string<char>%>%>' : 1,
83  '' : 1
84 }
85 
87  """ Searches through the requested directory looking at
88  'classes_def.xml' files looking for duplicate Reflex definitions."""
89  # compile necessary RE statements
90  classNameRE = re.compile (r'class\s+name\s*=\s*"([^"]*)"')
91  spacesRE = re.compile (r'\s+')
92  stdRE = re.compile (r'std::')
93  srcClassNameRE = re.compile (r'(\w+)/src/classes_def.*[.]xml')
94  ignoreSrcRE = re.compile (r'.*/FWCore/Skeletons/scripts/mkTemplates/.+')
95  braketRE = re.compile (r'<.+>')
96  print("Searching for 'classes_def.xml' in '%s'." % os.path.join(os.environ.get('CMSSW_BASE'),'src'))
97  xmlFiles = []
98  for srcDir in [os.environ.get('CMSSW_BASE'),os.environ.get('CMSSW_RELEASE_BASE')]:
99  if not len(srcDir): continue
100  for xml in commands.getoutput ('cd '+os.path.join(srcDir,'src')+'; find . -name "*classes_def*.xml" -follow -print').split ('\n'):
101  if xml and (not xml in xmlFiles):
102  xmlFiles.append(xml)
103  if options.showXMLs:
104  pprint.pprint (xmlFiles)
105  # try and figure out the names of the packages
106  xmlPackages = []
107  packagesREs = {}
108  equivREs = {}
109  explicitREs = []
110  for item in equivDict:
111  for pack in item:
112  for equiv in item[pack]:
113  explicitREs.append( (re.compile(r'\b' + equiv + r'\b'),pack))
114  if options.lostDefs:
115  for filename in xmlFiles:
116  if (not filename) or (ignoreSrcRE.match(filename)): continue
117  match = srcClassNameRE.search (filename)
118  if not match: continue
119  packageName = match.group(1)
120  xmlPackages.append (packageName)
121  matchString = r'\b' + packageName + r'\b'
122  packagesREs[packageName] = re.compile (matchString)
123  equivList = equivREs.setdefault (packageName, [])
124  for item in equivDict:
125  for equiv in item.get (packageName, []):
126  matchString = re.compile(r'\b' + equiv + r'\b')
127  equivList.append( (matchString, equiv) )
128  equivList.append( (packagesREs[packageName], packageName) )
129  classDict = {}
130  ncdict = {'class' : 'className', 'function' : 'functionName'}
131  for filename in xmlFiles:
132  if (not filename) or (ignoreSrcRE.match(filename)): continue
133  dupProblems = ''
134  exceptName = ''
135  regexList = []
136  localObjects = []
137  simpleObjectREs = []
138  if options.lostDefs:
139  lostMatch = srcClassNameRE.search (filename)
140  if lostMatch:
141  exceptName = lostMatch.group (1)
142  regexList = equivREs[exceptName]
143  xcount = len(regexList)-1
144  if not regexList[xcount][0].search (exceptName):
145  print('%s not found in' % exceptName, end=' ')
146  print(regexList[xcount][0])
147  sys.exit()
148  else: continue
149  if options.verbose:
150  print("filename", filename)
151  try:
152  filepath = os.path.join(os.environ.get('CMSSW_BASE'),'src',filename)
153  if not os.path.exists(filepath):
154  filepath = os.path.join(os.environ.get('CMSSW_RELEASE_BASE'),'src',filename)
155  xmlObj = xml2obj (filename = filepath,
156  filtering = True,
157  nameChangeDict = ncdict)
158  except Exception as detail:
159  print("File %s is malformed XML. Please fix." % filename)
160  print(" ", detail)
161  continue
162  try:
163  classList = xmlObj.selection.className
164  except:
165  try:
166  classList = xmlObj.className
167  except:
168  # this isn't a real classes_def.xml file. Skip it
169  print("**** SKIPPING '%s' - Doesn't seem to have proper information." % filename)
170  continue
171  if not classList:
172  classList = xmlObj.functionName
173  if not classList:
174  print("**** SKIPPING '%s' - Dosen't seem to have proper information(not class/function)." % filename)
175  continue
176  for piece in classList:
177  try:
178  className = spacesRE.sub ('', piece.name)
179  except:
180  # must be one of these class pattern things. Skip it
181  #print " skipping %s" % filename, piece.__repr__()
182  continue
183  className = stdRE.sub ('', className)
184  # print " ", className
185  # Now get rid of any typedefs
186  for typedef, tdList in six.iteritems(typedefsDict):
187  for alias in tdList:
188  className = re.sub (alias, typedef, className)
189  classDict.setdefault (className, set()).add (filename)
190  # should we check for lost definitions?
191  if not options.lostDefs:
192  continue
193  localObjects.append (className)
194  if options.lazyLostDefs and not braketRE.search (className):
195  #print " ", className
196  matchString = r'\b' + className + r'\b'
197  simpleObjectREs.append( (re.compile (matchString), className ) )
198  for className in localObjects:
199  # if we see our name (or equivalent) here, then let's
200  # skip complaining about this
201  foundEquiv = False
202  for equivRE in regexList:
203  #print "searching %s for %s" % (equivRE[1], className)
204  if equivRE[0].search (className):
205  foundEquiv = True
206  break
207  for simpleRE in simpleObjectREs:
208  if simpleRE[0].search (className):
209  foundEquiv = True
210  if options.verbose and simpleRE[1] != className:
211  print(" Using %s to ignore %s" \
212  % (simpleRE[1], className))
213  break
214  if foundEquiv: continue
215  for exRes in explicitREs:
216  if exRes[0].search(className):
217  dupProblems += " %s : %s\n" % (exRes[1], className)
218  foundEquiv = True
219  break
220  if foundEquiv: continue
221  for packageName in xmlPackages:
222  # don't bother looking for the name of this
223  # package in this package
224  if packagesREs[packageName].search (className):
225  dupProblems += " %s : %s\n" % (packageName, className)
226  break
227  # for piece
228  if dupProblems:
229  print('\n%s\n%s\n' % (filename, dupProblems))
230  # for filename
231  if options.dups:
232  for name, fileSet in sorted( six.iteritems(classDict) ):
233  if len (fileSet) < 2:
234  continue
235  print(name)
236  fileList = sorted (fileSet)
237  for filename in fileList:
238  print(" ", filename)
239  print()
240  # for name, fileSet
241  # if not noDups
242  #pprint.pprint (classDict)
243 
244 
246  """ Searches the edmpluginFile to find any duplicate
247  plugins."""
248  edmpluginFile = ''
249  libenv = 'LD_LIBRARY_PATH'
250  if os.environ.get('SCRAM_ARCH').startswith('osx'): libenv = 'DYLD_FALLBACK_LIBRARY_PATH'
251  biglib = '/biglib/'+os.environ.get('SCRAM_ARCH')
252  for libdir in os.environ.get(libenv).split(':'):
253  if libdir.endswith(biglib): continue
254  if os.path.exists(libdir+'/.edmplugincache'): edmpluginFile = edmpluginFile + ' ' + libdir+'/.edmplugincache'
255  if edmpluginFile == '': edmpluginFile = os.path.join(os.environ.get('CMSSW_BASE'),'lib',os.environ.get('SCRAM_ARCH'),'.edmplugincache')
256  cmd = "cat %s | awk '{print $2\" \"$1}' | sort | uniq | awk '{print $1}' | sort | uniq -c | grep '2 ' | awk '{print $2}'" % edmpluginFile
257  output = commands.getoutput (cmd).split('\n')
258  for line in output:
259  if line in ignoreEdmDP: continue
260  line = line.replace("*","\*")
261  cmd = "cat %s | grep ' %s ' | awk '{print $1}' | sort | uniq " % (edmpluginFile,line)
262  out1 = commands.getoutput (cmd).split('\n')
263  print(line)
264  for plugin in out1:
265  if plugin:
266  print(" **"+plugin+"**")
267  print()
268 
269 if __name__ == "__main__":
270  # setup options parser
271  parser = optparse.OptionParser ("Usage: %prog [options]\n"\
272  "Searches classes_def.xml for wrong/duplicate "\
273  "definitions")
274  xmlGroup = optparse.OptionGroup (parser, "ClassDef XML options")
275  dumpGroup = optparse.OptionGroup (parser, "EdmPluginDump options")
276  xmlGroup.add_option ('--dups', dest='dups', action='store_true',
277  default=False,
278  help="Search for duplicate definitions")
279  xmlGroup.add_option ('--lostDefs', dest='lostDefs', action='store_true',
280  default=False,
281  help="Looks for definitions in the wrong libraries")
282  xmlGroup.add_option ('--lazyLostDefs', dest='lazyLostDefs',
283  action='store_true',
284  default=False,
285  help="Will try to ignore as many lost defs as reasonable")
286  xmlGroup.add_option ('--verbose', dest='verbose',
287  action='store_true',
288  default=False,
289  help="Prints out a lot of information")
290  xmlGroup.add_option ('--showXMLs', dest='showXMLs', action='store_true',
291  default=False,
292  help="Shows all 'classes_def.xml' files")
293  xmlGroup.add_option ('--dir', dest='srcdir', type='string', default='',
294  help="Obsolete")
295  dumpGroup.add_option ('--edmPD', dest='edmPD', action='store_true',
296  default=False,
297  help="Searches EDM Plugin Dump for duplicates")
298  dumpGroup.add_option ('--edmFile', dest='edmFile', type='string',
299  default='',
300  help="Obsolete")
301  parser.add_option_group (xmlGroup)
302  parser.add_option_group (dumpGroup)
303  (options, args) = parser.parse_args()
304 
305  # Let's go:
306  if options.lazyLostDefs:
307  options.lostDefs = True
308  if options.showXMLs or options.lostDefs or options.dups:
309  searchClassDefXml ()
310  if options.edmPD:
311  searchDuplicatePlugins ()
std::vector< T >::const_iterator search(const cond::Time_t &val, const std::vector< T > &container)
Definition: IOVProxy.cc:314
S & print(S &os, JobReport::InputFile const &f)
Definition: JobReport.cc:66
double split
Definition: MVATrainer.cc:139