CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
LumiList.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 """
4 Handle lists of lumi sections. Constuct in several different formats and filter
5 (mask) a secondary list of lumis.
6 This class can also handle ranges of events as the structure is identical
7 or could be subclassed renaming a function or two.
8 
9 This code began life in COMP/CRAB/python/LumiList.py
10 """
11 
12 __revision__ = "$Id: LumiList.py,v 1.15 2011/11/02 16:06:57 ewv Exp $"
13 __version__ = "$Revision: 1.15 $"
14 
15 import copy
16 import json
17 import re
18 import urllib2
19 
21  """
22  Deal with lists of lumis in several different forms:
23  Compact list:
24  {
25  '1': [[1, 33], [35, 35], [37, 47], [49, 75], [77, 130], [133, 136]],
26  '2':[[1,45],[50,80]]
27  }
28  where the first key is the run number, subsequent pairs are
29  ranges of lumis within that run that are desired
30  Runs and lumis:
31  {
32  '1': [1,2,3,4,6,7,8,9,10],
33  '2': [1,4,5,20]
34  }
35  where the first key is the run number and the list is a list of
36  individual lumi sections. This form also takes a list of these objects
37  which can be much faster than LumiList += LumiList
38  Run lumi pairs:
39  [[1,1], [1,2],[1,4], [2,1], [2,5], [1,10]]
40  where each pair in the list is an individual run&lumi
41  CMSSW representation:
42  '1:1-1:33,1:35,1:37-1:47,2:1-2:45,2:50-2:80'
43  The string used by CMSSW in lumisToProcess or lumisToSkip
44  is a subset of the compactList example above
45  """
46 
47 
48  def __init__(self, filename = None, lumis = None, runsAndLumis = None, runs = None, compactList = None, url = None):
49  """
50  Constructor takes filename (JSON), a list of run/lumi pairs,
51  or a dict with run #'s as the keys and a list of lumis as the values, or just a list of runs
52  """
53  self.compactList = {}
54  self.duplicates = {}
55  if filename:
56  self.filename = filename
57  jsonFile = open(self.filename,'r')
58  self.compactList = json.load(jsonFile)
59  elif url:
60  self.url = url
61  jsonFile = urllib2.urlopen(url)
62  self.compactList = json.load(jsonFile)
63  elif lumis:
64  runsAndLumis = {}
65  for (run, lumi) in lumis:
66  run = str(run)
67  if not runsAndLumis.has_key(run):
68  runsAndLumis[run] = []
69  runsAndLumis[run].append(lumi)
70 
71  if isinstance(runsAndLumis, list):
72  queued = {}
73  for runLumiList in runsAndLumis:
74  for run, lumis in runLumiList.items():
75  queued.setdefault(run, []).extend(lumis)
76  runsAndLumis = queued
77 
78  if runsAndLumis:
79  for run in runsAndLumis.keys():
80  runString = str(run)
81  lastLumi = -1000
82  lumiList = runsAndLumis[run]
83  if lumiList:
84  self.compactList[runString] = []
85  self.duplicates[runString] = []
86  for lumi in sorted(lumiList):
87  if lumi == lastLumi:
88  self.duplicates[runString].append(lumi)
89  elif lumi != lastLumi + 1: # Break in lumi sequence
90  self.compactList[runString].append([lumi, lumi])
91  else:
92  nRange = len(self.compactList[runString])
93  self.compactList[runString][nRange-1][1] = lumi
94  lastLumi = lumi
95  if runs:
96  for run in runs:
97  runString = str(run)
98  self.compactList[runString] = [[1, 0xFFFFFFF]]
99 
100  if compactList:
101  for run in compactList.keys():
102  runString = str(run)
103  if compactList[run]:
104  self.compactList[runString] = compactList[run]
105 
106 
107  def __sub__(self, other): # Things from self not in other
108  result = {}
109  for run in sorted(self.compactList.keys()):
110  alumis = sorted(self.compactList[run])
111  blumis = sorted(other.compactList.get(run, []))
112  alist = [] # verified part
113  for alumi in alumis:
114  tmplist = [alumi[0], alumi[1]] # may be part
115  for blumi in blumis:
116  if blumi[0] <= tmplist[0] and blumi[1] >= tmplist[1]: # blumi has all of alumi
117  tmplist = []
118  break # blumi is has all of alumi
119  if blumi[0] > tmplist[0] and blumi[1] < tmplist[1]: # blumi is part of alumi
120  alist.append([tmplist[0], blumi[0]-1])
121  tmplist = [blumi[1]+1, tmplist[1]]
122  elif blumi[0] <= tmplist[0] and blumi[1] < tmplist[1] and blumi[1]>=tmplist[0]: # overlaps start
123  tmplist = [blumi[1]+1, tmplist[1]]
124  elif blumi[0] > tmplist[0] and blumi[1] >= tmplist[1] and blumi[0]<=tmplist[1]: # overlaps end
125  alist.append([tmplist[0], blumi[0]-1])
126  tmplist = []
127  break
128  if tmplist:
129  alist.append(tmplist)
130  result[run] = alist
131 
132  return LumiList(compactList = result)
133 
134 
135  def __and__(self, other): # Things in both
136  result = {}
137  aruns = set(self.compactList.keys())
138  bruns = set(other.compactList.keys())
139  for run in aruns & bruns:
140  lumiList = [] # List for this run
141  unique = [] # List for this run
142  for alumi in self.compactList[run]:
143  for blumi in other.compactList[run]:
144  if blumi[0] <= alumi[0] and blumi[1] >= alumi[1]: # blumi has all of alumi
145  lumiList.append(alumi)
146  if blumi[0] > alumi[0] and blumi[1] < alumi[1]: # blumi is part of alumi
147  lumiList.append(blumi)
148  elif blumi[0] <= alumi[0] and blumi[1] < alumi[1] and blumi[1] >= alumi[0]: # overlaps start
149  lumiList.append([alumi[0], blumi[1]])
150  elif blumi[0] > alumi[0] and blumi[1] >= alumi[1] and blumi[0] <= alumi[1]: # overlaps end
151  lumiList.append([blumi[0], alumi[1]])
152 
153 
154  if lumiList:
155  unique = [lumiList[0]]
156  for pair in lumiList[1:]:
157  if pair[0] == unique[-1][1]+1:
158  unique[-1][1] = copy.deepcopy(pair[1])
159  else:
160  unique.append(copy.deepcopy(pair))
161 
162  result[run] = unique
163  return LumiList(compactList = result)
164 
165 
166  def __or__(self, other):
167  result = {}
168  aruns = self.compactList.keys()
169  bruns = other.compactList.keys()
170  runs = set(aruns + bruns)
171  for run in runs:
172  overlap = sorted(self.compactList.get(run, []) + other.compactList.get(run, []))
173  unique = [overlap[0]]
174  for pair in overlap[1:]:
175  if pair[0] >= unique[-1][0] and pair[0] <= unique[-1][1]+1 and pair[1] > unique[-1][1]:
176  unique[-1][1] = copy.deepcopy(pair[1])
177  elif pair[0] > unique[-1][1]:
178  unique.append(copy.deepcopy(pair))
179  result[run] = unique
180  return LumiList(compactList = result)
181 
182 
183  def __add__(self, other):
184  # + is the same as |
185  return self.__or__(other)
186 
187  def __len__(self):
188  '''Returns number of runs in list'''
189  return len(self.compactList)
190 
191  def filterLumis(self, lumiList):
192  """
193  Return a list of lumis that are in compactList.
194  lumilist is of the simple form
195  [(run1,lumi1),(run1,lumi2),(run2,lumi1)]
196  """
197  filteredList = []
198  for (run, lumi) in lumiList:
199  runsInLumi = self.compactList.get(str(run), [[0, -1]])
200  for (first, last) in runsInLumi:
201  if lumi >= first and lumi <= last:
202  filteredList.append((run, lumi))
203  break
204  return filteredList
205 
206 
207  def __str__ (self):
208  doubleBracketRE = re.compile (r']],')
209  return doubleBracketRE.sub (']],\n',
210  json.dumps (self.compactList,
211  sort_keys=True))
212 
213  def getCompactList(self):
214  """
215  Return the compact list representation
216  """
217  return self.compactList
218 
219 
220  def getDuplicates(self):
221  """
222  Return the list of duplicates found during construction as a LumiList
223  """
224  return LumiList(runsAndLumis = self.duplicates)
225 
226 
227  def getLumis(self):
228  """
229  Return the list of pairs representation
230  """
231  theList = []
232  runs = self.compactList.keys()
233  runs.sort(key=int)
234  for run in runs:
235  lumis = self.compactList[run]
236  for lumiPair in sorted(lumis):
237  for lumi in range(lumiPair[0], lumiPair[1]+1):
238  theList.append((int(run), lumi))
239 
240  return theList
241 
242 
243  def getRuns(self):
244  '''
245  return the sorted list of runs contained
246  '''
247  return sorted (self.compactList.keys())
248 
249 
250  def _getLumiParts(self):
251  """
252  Turn compactList into a list of the format
253  [ 'R1:L1', 'R2:L2-R2:L3' ] which is used by getCMSSWString and getVLuminosityBlockRange
254  """
255 
256  parts = []
257  runs = self.compactList.keys()
258  runs.sort(key=int)
259  for run in runs:
260  lumis = self.compactList[run]
261  for lumiPair in sorted(lumis):
262  if lumiPair[0] == lumiPair[1]:
263  parts.append("%s:%s" % (run, lumiPair[0]))
264  else:
265  parts.append("%s:%s-%s:%s" %
266  (run, lumiPair[0], run, lumiPair[1]))
267  return parts
268 
269 
270  def getCMSSWString(self):
271  """
272  Turn compactList into a list of the format
273  R1:L1,R2:L2-R2:L3 which is acceptable to CMSSW LumiBlockRange variable
274  """
275 
276  parts = self._getLumiParts()
277  output = ','.join(parts)
278  return str(output)
279 
280 
281  def getVLuminosityBlockRange(self, tracked = False):
282  """
283  Turn compactList into an (optionally tracked) VLuminosityBlockRange
284  """
285 
286  import FWCore.ParameterSet.Config as cms
287  parts = self._getLumiParts()
288  if tracked:
289  return cms.VLuminosityBlockRange(parts)
290  else:
291  return cms.untracked.VLuminosityBlockRange(parts)
292 
293 
294  def writeJSON(self, fileName):
295  """
296  Write out a JSON file representation of the object
297  """
298  jsonFile = open(fileName,'w')
299  jsonFile.write("%s\n" % self)
300  jsonFile.close()
301 
302 
303  def removeRuns (self, runList):
304  '''
305  removes runs from runList from collection
306  '''
307  for run in runList:
308  run = str(run)
309  if self.compactList.has_key (run):
310  del self.compactList[run]
311 
312  return
313 
314 
315  def selectRuns (self, runList):
316  '''
317  Selects only runs from runList in collection
318  '''
319  runsToDelete = []
320  for run in self.compactList.keys():
321  if int(run) not in runList and run not in runList:
322  runsToDelete.append(run)
323 
324  for run in runsToDelete:
325  del self.compactList[run]
326 
327  return
328 
329  def contains (self, run, lumiSection = None):
330  '''
331  returns true if the run, lumi section passed in is contained
332  in this lumiList. Input can be either:
333  - a single tuple of (run, lumi),
334  - separate run and lumi numbers
335  - a single run number (returns true if any lumi sections exist)
336  '''
337  if lumiSection is None:
338  # if this is an integer or a string, see if the run exists
339  if isinstance (run, int) or isinstance (run, str):
340  return self.compactList.has_key( str(run) )
341  # if we're here, then run better be a tuple or list
342  try:
343  lumiSection = run[1]
344  run = run[0]
345  except:
346  raise RuntimeError, "Improper format for run '%s'" % run
347  lumiRangeList = self.compactList.get( str(run) )
348  if not lumiRangeList:
349  # the run isn't there, so no need to look any further
350  return False
351  for lumiRange in lumiRangeList:
352  # we want to make this as found if either the lumiSection
353  # is inside the range OR if the lumi section is greater
354  # than or equal to the lower bound of the lumi range and
355  # the upper bound is 0 (which means extends to the end of
356  # the run)
357  if lumiRange[0] <= lumiSection and \
358  (0 == lumiRange[1] or lumiSection <= lumiRange[1]):
359  # got it
360  return True
361  return False
362 
363 
364  def __contains__ (self, runTuple):
365  return self.contains (runTuple)
366 
367 
368 
369 '''
370 # Unit test code
371 import unittest
372 import FWCore.ParameterSet.Config as cms
373 
374 class LumiListTest(unittest.TestCase):
375  """
376  _LumiListTest_
377 
378  """
379 
380  def testRead(self):
381  """
382  Test reading from JSON
383  """
384  exString = "1:1-1:33,1:35,1:37-1:47,2:49-2:75,2:77-2:130,2:133-2:136"
385  exDict = {'1': [[1, 33], [35, 35], [37, 47]],
386  '2': [[49, 75], [77, 130], [133, 136]]}
387  exVLBR = cms.VLuminosityBlockRange('1:1-1:33', '1:35', '1:37-1:47', '2:49-2:75', '2:77-2:130', '2:133-2:136')
388 
389  jsonList = LumiList(filename = 'lumiTest.json')
390  lumiString = jsonList.getCMSSWString()
391  lumiList = jsonList.getCompactList()
392  lumiVLBR = jsonList.getVLuminosityBlockRange(True)
393 
394  self.assertTrue(lumiString == exString)
395  self.assertTrue(lumiList == exDict)
396  self.assertTrue(lumiVLBR == exVLBR)
397 
398  def testList(self):
399  """
400  Test constucting from list of pairs
401  """
402 
403  listLs1 = range(1, 34) + [35] + range(37, 48)
404  listLs2 = range(49, 76) + range(77, 131) + range(133, 137)
405  lumis = zip([1]*100, listLs1) + zip([2]*100, listLs2)
406 
407  jsonLister = LumiList(filename = 'lumiTest.json')
408  jsonString = jsonLister.getCMSSWString()
409  jsonList = jsonLister.getCompactList()
410 
411  pairLister = LumiList(lumis = lumis)
412  pairString = pairLister.getCMSSWString()
413  pairList = pairLister.getCompactList()
414 
415  self.assertTrue(jsonString == pairString)
416  self.assertTrue(jsonList == pairList)
417 
418 
419  def testRuns(self):
420  """
421  Test constucting from run and list of lumis
422  """
423  runsAndLumis = {
424  1: range(1, 34) + [35] + range(37, 48),
425  2: range(49, 76) + range(77, 131) + range(133, 137)
426  }
427  runsAndLumis2 = {
428  '1': range(1, 34) + [35] + range(37, 48),
429  '2': range(49, 76) + range(77, 131) + range(133, 137)
430  }
431  blank = {
432  '1': [],
433  '2': []
434  }
435 
436  jsonLister = LumiList(filename = 'lumiTest.json')
437  jsonString = jsonLister.getCMSSWString()
438  jsonList = jsonLister.getCompactList()
439 
440  runLister = LumiList(runsAndLumis = runsAndLumis)
441  runString = runLister.getCMSSWString()
442  runList = runLister.getCompactList()
443 
444  runLister2 = LumiList(runsAndLumis = runsAndLumis2)
445  runList2 = runLister2.getCompactList()
446 
447  runLister3 = LumiList(runsAndLumis = blank)
448 
449 
450  self.assertTrue(jsonString == runString)
451  self.assertTrue(jsonList == runList)
452  self.assertTrue(runList2 == runList)
453  self.assertTrue(len(runLister3) == 0)
454 
455  def testFilter(self):
456  """
457  Test filtering of a list of lumis
458  """
459  runsAndLumis = {
460  1: range(1, 34) + [35] + range(37, 48),
461  2: range(49, 76) + range(77, 131) + range(133, 137)
462  }
463 
464  completeList = zip([1]*150, range(1, 150)) + \
465  zip([2]*150, range(1, 150)) + \
466  zip([3]*150, range(1, 150))
467 
468  smallList = zip([1]*50, range(1, 10)) + zip([2]*50, range(50, 70))
469  overlapList = zip([1]*150, range(30, 40)) + \
470  zip([2]*150, range(60, 80))
471  overlapRes = zip([1]*9, range(30, 34)) + [(1, 35)] + \
472  zip([1]*9, range(37, 40)) + \
473  zip([2]*30, range(60, 76)) + \
474  zip([2]*9, range(77, 80))
475 
476  runLister = LumiList(runsAndLumis = runsAndLumis)
477 
478  # Test a list to be filtered which is a superset of constructed list
479  filterComplete = runLister.filterLumis(completeList)
480  # Test a list to be filtered which is a subset of constructed list
481  filterSmall = runLister.filterLumis(smallList)
482  # Test a list to be filtered which is neither
483  filterOverlap = runLister.filterLumis(overlapList)
484 
485  self.assertTrue(filterComplete == runLister.getLumis())
486  self.assertTrue(filterSmall == smallList)
487  self.assertTrue(filterOverlap == overlapRes)
488 
489  def testDuplicates(self):
490  """
491  Test a list with lots of duplicates
492  """
493  result = zip([1]*100, range(1, 34) + range(37, 48))
494  lumis = zip([1]*100, range(1, 34) + range(37, 48) + range(5, 25))
495 
496  lister = LumiList(lumis = lumis)
497  self.assertTrue(lister.getLumis() == result)
498 
499  def testNull(self):
500  """
501  Test a null list
502  """
503 
504  runLister = LumiList(lumis = None)
505 
506  self.assertTrue(runLister.getCMSSWString() == '')
507  self.assertTrue(runLister.getLumis() == [])
508  self.assertTrue(runLister.getCompactList() == {})
509 
510  def testSubtract(self):
511  """
512  a-b for lots of cases
513  """
514 
515  alumis = {'1' : range(2,20) + range(31,39) + range(45,49),
516  '2' : range(6,20) + range (30,40),
517  '3' : range(10,20) + range (30,40) + range(50,60),
518  }
519  blumis = {'1' : range(1,6) + range(12,13) + range(16,30) + range(40,50) + range(33,36),
520  '2' : range(10,35),
521  '3' : range(10,15) + range(35,40) + range(45,51) + range(59,70),
522  }
523  clumis = {'1' : range(1,6) + range(12,13) + range(16,30) + range(40,50) + range(33,36),
524  '2' : range(10,35),
525  }
526  result = {'1' : range(6,12) + range(13,16) + range(31,33) + range(36,39),
527  '2' : range(6,10) + range(35,40),
528  '3' : range(15,20) + range(30,35) + range(51,59),
529  }
530  result2 = {'1' : range(6,12) + range(13,16) + range(31,33) + range(36,39),
531  '2' : range(6,10) + range(35,40),
532  '3' : range(10,20) + range (30,40) + range(50,60),
533  }
534  a = LumiList(runsAndLumis = alumis)
535  b = LumiList(runsAndLumis = blumis)
536  c = LumiList(runsAndLumis = clumis)
537  r = LumiList(runsAndLumis = result)
538  r2 = LumiList(runsAndLumis = result2)
539 
540  self.assertTrue((a-b).getCMSSWString() == r.getCMSSWString())
541  self.assertTrue((a-b).getCMSSWString() != (b-a).getCMSSWString())
542  # Test where c is missing runs from a
543  self.assertTrue((a-c).getCMSSWString() == r2.getCMSSWString())
544  self.assertTrue((a-c).getCMSSWString() != (c-a).getCMSSWString())
545  # Test empty lists
546  self.assertTrue(str(a-a) == '{}')
547  self.assertTrue(len(a-a) == 0)
548 
549  def testOr(self):
550  """
551  a|b for lots of cases
552  """
553 
554  alumis = {'1' : range(2,20) + range(31,39) + range(45,49),
555  '2' : range(6,20) + range (30,40),
556  '3' : range(10,20) + range (30,40) + range(50,60),
557  }
558  blumis = {'1' : range(1,6) + range(12,13) + range(16,30) + range(40,50) + range(39,80),
559  '2' : range(10,35),
560  '3' : range(10,15) + range(35,40) + range(45,51) + range(59,70),
561  }
562  clumis = {'1' : range(1,6) + range(12,13) + range(16,30) + range(40,50) + range(39,80),
563  '2' : range(10,35),
564  }
565  result = {'1' : range(2,20) + range(31,39) + range(45,49) + range(1,6) + range(12,13) + range(16,30) + range(40,50) + range(39,80),
566  '2' : range(6,20) + range (30,40) + range(10,35),
567  '3' : range(10,20) + range (30,40) + range(50,60) + range(10,15) + range(35,40) + range(45,51) + range(59,70),
568  }
569  a = LumiList(runsAndLumis = alumis)
570  b = LumiList(runsAndLumis = blumis)
571  c = LumiList(runsAndLumis = blumis)
572  r = LumiList(runsAndLumis = result)
573  self.assertTrue((a|b).getCMSSWString() == r.getCMSSWString())
574  self.assertTrue((a|b).getCMSSWString() == (b|a).getCMSSWString())
575  self.assertTrue((a|b).getCMSSWString() == (a+b).getCMSSWString())
576 
577  # Test list constuction (faster)
578 
579  multiple = [alumis, blumis, clumis]
580  easy = LumiList(runsAndLumis = multiple)
581  hard = a + b
582  hard += c
583  self.assertTrue(hard.getCMSSWString() == easy.getCMSSWString())
584 
585  def testAnd(self):
586  """
587  a&b for lots of cases
588  """
589 
590  alumis = {'1' : range(2,20) + range(31,39) + range(45,49),
591  '2' : range(6,20) + range (30,40),
592  '3' : range(10,20) + range (30,40) + range(50,60),
593  '4' : range(1,100),
594  }
595  blumis = {'1' : range(1,6) + range(12,13) + range(16,25) + range(25,40) + range(40,50) + range(33,36),
596  '2' : range(10,35),
597  '3' : range(10,15) + range(35,40) + range(45,51) + range(59,70),
598  '5' : range(1,100),
599  }
600  result = {'1' : range(2,6) + range(12,13) + range(16,20) + range(31,39) + range(45,49),
601  '2' : range(10,20) + range(30,35),
602  '3' : range(10,15) + range(35,40) + range(50,51)+ range(59,60),
603  }
604  a = LumiList(runsAndLumis = alumis)
605  b = LumiList(runsAndLumis = blumis)
606  r = LumiList(runsAndLumis = result)
607  self.assertTrue((a&b).getCMSSWString() == r.getCMSSWString())
608  self.assertTrue((a&b).getCMSSWString() == (b&a).getCMSSWString())
609  self.assertTrue((a|b).getCMSSWString() != r.getCMSSWString())
610 
611  def testRemoveSelect(self):
612  """
613  a-b for lots of cases
614  """
615 
616  alumis = {'1' : range(2,20) + range(31,39) + range(45,49),
617  '2' : range(6,20) + range (30,40),
618  '3' : range(10,20) + range (30,40) + range(50,60),
619  '4' : range(10,20) + range (30,80),
620  }
621 
622  result = {'2' : range(6,20) + range (30,40),
623  '4' : range(10,20) + range (30,80),
624  }
625 
626  rem = LumiList(runsAndLumis = alumis)
627  sel = LumiList(runsAndLumis = alumis)
628  res = LumiList(runsAndLumis = result)
629 
630  rem.removeRuns([1,3])
631  sel.selectRuns([2,4])
632 
633  self.assertTrue(rem.getCMSSWString() == res.getCMSSWString())
634  self.assertTrue(sel.getCMSSWString() == res.getCMSSWString())
635  self.assertTrue(sel.getCMSSWString() == rem.getCMSSWString())
636 
637  def testURL(self):
638  URL = 'https://cms-service-dqm.web.cern.ch/cms-service-dqm/CAF/certification/Collisions12/8TeV/Reprocessing/Cert_190456-195530_8TeV_08Jun2012ReReco_Collisions12_JSON.txt'
639  ll = LumiList(url=URL)
640  self.assertTrue(len(ll) > 0)
641 
642 
643  def testWrite(self):
644  alumis = {'1' : range(2,20) + range(31,39) + range(45,49),
645  '2' : range(6,20) + range (30,40),
646  '3' : range(10,20) + range (30,40) + range(50,60),
647  '4' : range(1,100),
648  }
649  a = LumiList(runsAndLumis = alumis)
650  a.writeJSON('newFile.json')
651 
652 
653 if __name__ == '__main__':
654  jsonFile = open('lumiTest.json','w')
655  jsonFile.write('{"1": [[1, 33], [35, 35], [37, 47]], "2": [[49, 75], [77, 130], [133, 136]]}')
656  jsonFile.close()
657  unittest.main()
658 '''
659 # Test JSON file
660 
661 #{"1": [[1, 33], [35, 35], [37, 47]], "2": [[49, 75], [77, 130], [133, 136]]}
662 
663 if __name__ == '__main__':
664  #############################################
665  ## Load and save command line history when ##
666  ## running interactively. ##
667  #############################################
668  import os, readline
669  import atexit
670  historyPath = os.path.expanduser("~/.pyhistory")
671 
672 
673  def save_history(historyPath=historyPath):
674  import readline
675  readline.write_history_file(historyPath)
676  if os.path.exists(historyPath):
677  readline.read_history_file(historyPath)
678 
679 
680  atexit.register(save_history)
681  readline.parse_and_bind("set show-all-if-ambiguous on")
682  readline.parse_and_bind("tab: complete")
683  if os.path.exists (historyPath) :
684  readline.read_history_file(historyPath)
685  readline.set_history_length(-1)
686 
687 
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
def getVLuminosityBlockRange
Definition: LumiList.py:281
list object
Definition: dbtoconf.py:77
def save_history
Definition: LumiList.py:673
void set(const std::string &name, int value)
set the flag, with a run-time name