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 import six
13 
14 # These aren't all typedefs, but can sometimes make the output more
15 # readable
16 typedefsDict = \
17  {
18  # What we want <= What we have
19  'unsigned int' : ['unsignedint', 'UInt32_t', 'uint32_t'],
20  'unsigned long': ['unsignedlong'],
21  'int' : ['Int32_t'],
22  'float' : ['Float_t'],
23  'double' : ['Double_t'],
24  'char' : ['Char_t'],
25  '< ' : ['<', '&lt;'],
26  ' >' : ['>', '&gt;'],
27  ', ' : [','],
28  }
29 
30 
31 # Equivalent names for packages - lets script know that, for example,
32 # 'TrackReco' package should have objects 'reco::Track'.
33 #Ordered List to search for matched packages
34 equivDict = \
35  [
36  {'TrajectoryState' : ['TrajectoryStateOnSurface']},
37  {'TrackTriggerAssociation' : ['(TTClusterAssociationMap|TTStubAssociationMap|TTTrackAssociationMap).*Phase2TrackerDigi',
38  '(TTStub|TTCluster|TTTrack).*Phase2TrackerDigi']},
39  {'L1TCalorimeter' : ['l1t::CaloTower.*']},
40  {'GsfTracking' : ['reco::GsfTrack(Collection|).*(MomentumConstraint|VertexConstraint)', 'Trajectory.*reco::GsfTrack']},
41  {'ParallelAnalysis' : ['examples::TrackAnalysisAlgorithm']},
42  {'PatCandidates' : ['pat::PATObject','pat::Lepton']},
43  {'BTauReco' : ['reco::.*SoftLeptonTagInfo', 'reco::SoftLeptonProperties','reco::SecondaryVertexTagInfo','reco::IPTagInfo','reco::TemplatedSecondaryVertexTagInfo', 'reco::CATopJetProperties','reco::HTTTopJetProperties']},
44  {'CastorReco' : ['reco::CastorJet']},
45  {'JetMatching' : ['reco::JetFlavourInfo', 'reco::JetFlavour','reco::MatchedPartons']},
46  {'TrackingAnalysis' : ['TrackingParticle']},
47  {'Egamma' : ['reco::ElectronID']},
48  {'TopObjects' : ['reco::CATopJetProperties']},
49  {'TauReco' : ['reco::L2TauIsolationInfo','reco::RecoTauPiZero','reco::BaseTau']},
50  {'ValidationFormats' : ['PGlobalDigi::.+','PGlobalRecHit::.+']},
51  {'TrajectorySeed' : ['TrajectorySeed']},
52  {'TrackCandidate' : ['TrackCandidate']},
53  {'PatternTools' : ['MomentumConstraint','VertexConstraint','Trajectory']},
54  {'TrackerRecHit2D' : ['SiStrip(Matched|)RecHit[12]D','SiTrackerGSRecHit[12]D','SiPixelRecHit']},
55  {'MuonReco' : ['reco::Muon(Ref|)(Vector|)']},
56  {'MuonSeed' : ['L3MuonTrajectorySeed']},
57  {'HepMCCandidate' : ['reco::GenParticle.*']},
58  {'L1Trigger' : ['l1extra::L1.+Particle']},
59  {'TrackInfo' : ['reco::TrackingRecHitInfo']},
60  {'EgammaCandidates' : ['reco::GsfElectron.*','reco::Photon.*']},
61  {'HcalIsolatedTrack' : ['reco::IsolatedPixelTrackCandidate', 'reco::EcalIsolatedParticleCandidate', 'reco::HcalIsolatedTrackCandidate']},
62  {'HcalRecHit' : ['HFRecHit','HORecHit','ZDCRecHit','HBHERecHit']},
63  {'PFRootEvent' : ['EventColin::']},
64  {'CaloTowers' : ['CaloTower.*']},
65  {'GsfTrackReco' : ['GsfTrack.*']},
66  {'METReco' : ['reco::(Calo|PF|Gen|)MET','reco::PFClusterMET']},
67  {'ParticleFlowReco' : ['reco::RecoPFClusterRefCandidateRef.*']},
68  {'ParticleFlowCandidate' : ['reco::PFCandidateRef','reco::PFCandidateFwdRef','reco::PFCandidate']},
69  {'PhysicsToolsObjects' : ['PhysicsTools::Calibration']},
70  {'RecoCandidate' : ['reco::Candidate']},
71  {'TrackReco' : ['reco::Track','reco::TrackRef']},
72  {'VertexReco' : ['reco::Vertex']},
73  {'TFWLiteSelectorTest' : ['tfwliteselectortest']},
74  {'PatCandidates' : ['reco::RecoCandidate','pat::[A-Za-z]+Ref(Vector|)']},
75  {'TauReco' : ['reco::PFJetRef']},
76  {'JetReco' : ['reco::.*Jet','reco::.*Jet(Collection|Ref)']},
77  {'HGCDigi' : ['HGCSample']},
78  ]
79 
80 ignoreEdmDP = {
81  'LCGReflex/__gnu_cxx::__normal_iterator<std::basic_string<char>*,std::vector<std::basic_string<char>%>%>' : 1,
82  '' : 1
83 }
84 
86  """ Searches through the requested directory looking at
87  'classes_def.xml' files looking for duplicate Reflex definitions."""
88  # compile necessary RE statements
89  classNameRE = re.compile (r'class\s+name\s*=\s*"([^"]*)"')
90  spacesRE = re.compile (r'\s+')
91  stdRE = re.compile (r'std::')
92  srcClassNameRE = re.compile (r'(\w+)/src/classes_def.*[.]xml')
93  ignoreSrcRE = re.compile (r'.*/FWCore/Skeletons/scripts/mkTemplates/.+')
94  braketRE = re.compile (r'<.+>')
95  print "Searching for 'classes_def.xml' in '%s'." % os.path.join(os.environ.get('CMSSW_BASE'),'src')
96  xmlFiles = []
97  for srcDir in [os.environ.get('CMSSW_BASE'),os.environ.get('CMSSW_RELEASE_BASE')]:
98  if not len(srcDir): continue
99  for xml in commands.getoutput ('cd '+os.path.join(srcDir,'src')+'; find . -name "*classes_def*.xml" -follow -print').split ('\n'):
100  if xml and (not xml in xmlFiles):
101  xmlFiles.append(xml)
102  if options.showXMLs:
103  pprint.pprint (xmlFiles)
104  # try and figure out the names of the packages
105  xmlPackages = []
106  packagesREs = {}
107  equivREs = {}
108  explicitREs = []
109  for item in equivDict:
110  for pack in item:
111  for equiv in item[pack]:
112  explicitREs.append( (re.compile(r'\b' + equiv + r'\b'),pack))
113  if options.lostDefs:
114  for filename in xmlFiles:
115  if (not filename) or (ignoreSrcRE.match(filename)): continue
116  match = srcClassNameRE.search (filename)
117  if not match: continue
118  packageName = match.group(1)
119  xmlPackages.append (packageName)
120  matchString = r'\b' + packageName + r'\b'
121  packagesREs[packageName] = re.compile (matchString)
122  equivList = equivREs.setdefault (packageName, [])
123  for item in equivDict:
124  for equiv in item.get (packageName, []):
125  matchString = re.compile(r'\b' + equiv + r'\b')
126  equivList.append( (matchString, equiv) )
127  equivList.append( (packagesREs[packageName], packageName) )
128  classDict = {}
129  ncdict = {'class' : 'className', 'function' : 'functionName'}
130  for filename in xmlFiles:
131  if (not filename) or (ignoreSrcRE.match(filename)): continue
132  dupProblems = ''
133  exceptName = ''
134  regexList = []
135  localObjects = []
136  simpleObjectREs = []
137  if options.lostDefs:
138  lostMatch = srcClassNameRE.search (filename)
139  if lostMatch:
140  exceptName = lostMatch.group (1)
141  regexList = equivREs[exceptName]
142  xcount = len(regexList)-1
143  if not regexList[xcount][0].search (exceptName):
144  print '%s not found in' % exceptName,
145  print regexList[xcount][0]
146  sys.exit()
147  else: continue
148  if options.verbose:
149  print "filename", filename
150  try:
151  filepath = os.path.join(os.environ.get('CMSSW_BASE'),'src',filename)
152  if not os.path.exists(filepath):
153  filepath = os.path.join(os.environ.get('CMSSW_RELEASE_BASE'),'src',filename)
154  xmlObj = xml2obj (filename = filepath,
155  filtering = True,
156  nameChangeDict = ncdict)
157  except Exception as detail:
158  print "File %s is malformed XML. Please fix." % filename
159  print " ", detail
160  continue
161  try:
162  classList = xmlObj.selection.className
163  except:
164  try:
165  classList = xmlObj.className
166  except:
167  # this isn't a real classes_def.xml file. Skip it
168  print "**** SKIPPING '%s' - Doesn't seem to have proper information." % filename
169  continue
170  if not classList:
171  classList = xmlObj.functionName
172  if not classList:
173  print "**** SKIPPING '%s' - Dosen't seem to have proper information(not class/function)." % filename
174  continue
175  for piece in classList:
176  try:
177  className = spacesRE.sub ('', piece.name)
178  except:
179  # must be one of these class pattern things. Skip it
180  #print " skipping %s" % filename, piece.__repr__()
181  continue
182  className = stdRE.sub ('', className)
183  # print " ", className
184  # Now get rid of any typedefs
185  for typedef, tdList in six.iteritems(typedefsDict):
186  for alias in tdList:
187  className = re.sub (alias, typedef, className)
188  classDict.setdefault (className, set()).add (filename)
189  # should we check for lost definitions?
190  if not options.lostDefs:
191  continue
192  localObjects.append (className)
193  if options.lazyLostDefs and not braketRE.search (className):
194  #print " ", className
195  matchString = r'\b' + className + r'\b'
196  simpleObjectREs.append( (re.compile (matchString), className ) )
197  for className in localObjects:
198  # if we see our name (or equivalent) here, then let's
199  # skip complaining about this
200  foundEquiv = False
201  for equivRE in regexList:
202  #print "searching %s for %s" % (equivRE[1], className)
203  if equivRE[0].search (className):
204  foundEquiv = True
205  break
206  for simpleRE in simpleObjectREs:
207  if simpleRE[0].search (className):
208  foundEquiv = True
209  if options.verbose and simpleRE[1] != className:
210  print " Using %s to ignore %s" \
211  % (simpleRE[1], className)
212  break
213  if foundEquiv: continue
214  for exRes in explicitREs:
215  if exRes[0].search(className):
216  dupProblems += " %s : %s\n" % (exRes[1], className)
217  foundEquiv = True
218  break
219  if foundEquiv: continue
220  for packageName in xmlPackages:
221  # don't bother looking for the name of this
222  # package in this package
223  if packagesREs[packageName].search (className):
224  dupProblems += " %s : %s\n" % (packageName, className)
225  break
226  # for piece
227  if dupProblems:
228  print '\n%s\n%s\n' % (filename, dupProblems)
229  # for filename
230  if options.dups:
231  for name, fileSet in sorted( six.iteritems(classDict) ):
232  if len (fileSet) < 2:
233  continue
234  print name
235  fileList = sorted (fileSet)
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