CMS 3D CMS Logo

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