Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:13:01

0001 #!/usr/bin/env python3
0002 
0003 """
0004 Handle lists of lumi sections. Constuct in several different formats and filter
0005 (mask) a secondary list of lumis.
0006 This class can also handle ranges of events as the structure is identical
0007 or could be subclassed renaming a function or two.
0008 
0009 This code began life in COMP/CRAB/python/LumiList.py
0010 """
0011 
0012 
0013 from builtins import range
0014 import copy
0015 import json
0016 import re
0017 try:
0018     from urllib.request import urlopen
0019 except ImportError:
0020     from urllib2 import urlopen
0021 
0022 class LumiList(object):
0023     """
0024     Deal with lists of lumis in several different forms:
0025     Compact list:
0026         {
0027         '1': [[1, 33], [35, 35], [37, 47], [49, 75], [77, 130], [133, 136]],
0028         '2':[[1,45],[50,80]]
0029         }
0030         where the first key is the run number, subsequent pairs are
0031         ranges of lumis within that run that are desired
0032     Runs and lumis:
0033         {
0034         '1': [1,2,3,4,6,7,8,9,10],
0035         '2': [1,4,5,20]
0036         }
0037         where the first key is the run number and the list is a list of
0038         individual lumi sections. This form also takes a list of these objects
0039         which can be much faster than LumiList += LumiList
0040     Run  lumi pairs:
0041         [[1,1], [1,2],[1,4], [2,1], [2,5], [1,10]]
0042         where each pair in the list is an individual run&lumi
0043     CMSSW representation:
0044         '1:1-1:33,1:35,1:37-1:47,2:1-2:45,2:50-2:80'
0045         The string used by CMSSW in lumisToProcess or lumisToSkip
0046         is a subset of the compactList example above
0047     """
0048 
0049 
0050     def __init__(self, filename = None, lumis = None, runsAndLumis = None, runs = None, compactList = None, url = None):
0051         """
0052         Constructor takes filename (JSON), a list of run/lumi pairs,
0053         or a dict with run #'s as the keys and a list of lumis as the values, or just a list of runs
0054         """
0055         self.compactList = {}
0056         self.duplicates = {}
0057         if filename:
0058             self.filename = filename
0059             jsonFile = open(self.filename,'r')
0060             self.compactList = json.load(jsonFile)
0061         elif url:
0062             self.url = url
0063             jsonFile = urlopen(url)
0064             self.compactList = json.load(jsonFile)
0065         elif lumis:
0066             runsAndLumis = {}
0067             for (run, lumi) in lumis:
0068                 run = str(run)
0069                 if run not in runsAndLumis:
0070                     runsAndLumis[run] = []
0071                 runsAndLumis[run].append(lumi)
0072 
0073         if isinstance(runsAndLumis, list):
0074             queued = {}
0075             for runLumiList in runsAndLumis:
0076                 for run, lumis in runLumiList.items():
0077                     queued.setdefault(run, []).extend(lumis)
0078             runsAndLumis = queued
0079 
0080         if runsAndLumis:
0081             for run in runsAndLumis.keys():
0082                 runString = str(run)
0083                 lastLumi = -1000
0084                 lumiList = runsAndLumis[run]
0085                 if lumiList:
0086                     self.compactList[runString] = []
0087                     self.duplicates[runString] = []
0088                     for lumi in sorted(lumiList):
0089                         if lumi == lastLumi:
0090                             self.duplicates[runString].append(lumi)
0091                         elif lumi != lastLumi + 1: # Break in lumi sequence
0092                             self.compactList[runString].append([lumi, lumi])
0093                         else:
0094                             nRange =  len(self.compactList[runString])
0095                             self.compactList[runString][nRange-1][1] = lumi
0096                         lastLumi = lumi
0097         if runs:
0098             for run in runs:
0099                 runString = str(run)
0100                 self.compactList[runString] = [[1, 0xFFFFFFF]]
0101 
0102         if compactList:
0103             for run in compactList.keys():
0104                 runString = str(run)
0105                 if compactList[run]:
0106                     self.compactList[runString] = compactList[run]
0107 
0108         # Compact each run and make it unique
0109 
0110         for run in self.compactList.keys():
0111             newLumis = []
0112             for lumi in sorted(self.compactList[run]):
0113                 # If the next lumi starts inside or just after the last just change the endpoint of the first
0114                 if isinstance(lumi, int):
0115                     newLumis.append(lumi)
0116                 else:
0117                     if newLumis and newLumis[-1][0] <= lumi[0] <= newLumis[-1][1] + 1:
0118                         newLumis[-1][1] = max(newLumis[-1][1], lumi[1])
0119                     else:
0120                         newLumis.append(lumi)
0121             self.compactList[run] = newLumis
0122 
0123     def __sub__(self, other): # Things from self not in other
0124         result = {}
0125         for run in sorted(self.compactList.keys()):
0126             alumis = sorted(self.compactList[run])
0127             blumis = sorted(other.compactList.get(run, []))
0128             alist = []                    # verified part
0129             for alumi in alumis:
0130                 tmplist = [alumi[0], alumi[1]] # may be part
0131                 for blumi in blumis:
0132                     if blumi[0] <= tmplist[0] and blumi[1] >= tmplist[1]: # blumi has all of alumi
0133                         tmplist = []
0134                         break # blumi is has all of alumi
0135                     if blumi[0] > tmplist[0] and blumi[1] < tmplist[1]: # blumi is part of alumi
0136                         alist.append([tmplist[0], blumi[0]-1])
0137                         tmplist = [blumi[1]+1, tmplist[1]]
0138                     elif blumi[0] <= tmplist[0] and blumi[1] < tmplist[1] and blumi[1]>=tmplist[0]: # overlaps start
0139                         tmplist = [blumi[1]+1, tmplist[1]]
0140                     elif blumi[0] > tmplist[0] and blumi[1] >= tmplist[1] and blumi[0]<=tmplist[1]: # overlaps end
0141                         alist.append([tmplist[0], blumi[0]-1])
0142                         tmplist = []
0143                         break
0144                 if tmplist:
0145                     alist.append(tmplist)
0146             result[run] = alist
0147 
0148         return LumiList(compactList = result)
0149 
0150 
0151     def __and__(self, other): # Things in both
0152         result = {}
0153         aruns = set(self.compactList.keys())
0154         bruns = set(other.compactList.keys())
0155         for run in aruns & bruns:
0156             lumiList = []                    # List for this run
0157             unique = []                    # List for this run
0158             for alumi in self.compactList[run]:
0159                 for blumi in other.compactList[run]:
0160                     if blumi[0] <= alumi[0] and blumi[1] >= alumi[1]: # blumi has all of alumi
0161                         lumiList.append(alumi)
0162                     if blumi[0] > alumi[0] and blumi[1] < alumi[1]: # blumi is part of alumi
0163                         lumiList.append(blumi)
0164                     elif blumi[0] <= alumi[0] and blumi[1] < alumi[1] and blumi[1] >= alumi[0]: # overlaps start
0165                         lumiList.append([alumi[0], blumi[1]])
0166                     elif blumi[0] > alumi[0] and blumi[1] >= alumi[1] and blumi[0] <= alumi[1]: # overlaps end
0167                         lumiList.append([blumi[0], alumi[1]])
0168 
0169 
0170             if lumiList:
0171                 unique = [copy.deepcopy(lumiList[0])]
0172             for pair in lumiList[1:]:
0173                 if pair[0] == unique[-1][1]+1:
0174                     unique[-1][1] = copy.deepcopy(pair[1])
0175                 else:
0176                     unique.append(copy.deepcopy(pair))
0177 
0178             result[run] = unique
0179         return LumiList(compactList = result)
0180 
0181 
0182     def __or__(self, other):
0183         result = {}
0184         aruns = list(self.compactList.keys())
0185         bruns = list(other.compactList.keys())
0186         runs = set(aruns + bruns)
0187         for run in runs:
0188             overlap = sorted(self.compactList.get(run, []) + other.compactList.get(run, []))
0189             unique = [copy.deepcopy(overlap[0])]
0190             for pair in overlap[1:]:
0191                 if pair[0] >= unique[-1][0] and pair[0] <= unique[-1][1]+1 and pair[1] > unique[-1][1]:
0192                     unique[-1][1] = copy.deepcopy(pair[1])
0193                 elif pair[0] > unique[-1][1]:
0194                     unique.append(copy.deepcopy(pair))
0195             result[run] = unique
0196         return LumiList(compactList = result)
0197 
0198 
0199     def __add__(self, other):
0200         # + is the same as |
0201         return self.__or__(other)
0202 
0203     def __len__(self):
0204         '''Returns number of runs in list'''
0205         return len(self.compactList)
0206 
0207     def filterLumis(self, lumiList):
0208         """
0209         Return a list of lumis that are in compactList.
0210         lumilist is of the simple form
0211         [(run1,lumi1),(run1,lumi2),(run2,lumi1)]
0212         """
0213         filteredList = []
0214         for (run, lumi) in lumiList:
0215             runsInLumi = self.compactList.get(str(run), [[0, -1]])
0216             for (first, last) in runsInLumi:
0217                 if lumi >= first and lumi <= last:
0218                     filteredList.append((run, lumi))
0219                     break
0220         return filteredList
0221 
0222 
0223     def __str__ (self):
0224         doubleBracketRE = re.compile (r']],')
0225         return doubleBracketRE.sub (']],\n',
0226                                     json.dumps (self.compactList,
0227                                                 sort_keys=True))
0228 
0229     def getCompactList(self):
0230         """
0231         Return the compact list representation
0232         """
0233         return self.compactList
0234 
0235 
0236     def getDuplicates(self):
0237         """
0238         Return the list of duplicates found during construction as a LumiList
0239         """
0240         return LumiList(runsAndLumis = self.duplicates)
0241 
0242 
0243     def getLumis(self):
0244         """
0245         Return the list of pairs representation
0246         """
0247         theList = []
0248         runs = list(self.compactList.keys())
0249         runs = sorted(run, key=int)
0250         for run in runs:
0251             lumis = self.compactList[run]
0252             for lumiPair in sorted(lumis):
0253                 for lumi in range(lumiPair[0], lumiPair[1]+1):
0254                     theList.append((int(run), lumi))
0255 
0256         return theList
0257 
0258 
0259     def getRuns(self):
0260         '''
0261         return the sorted list of runs contained
0262         '''
0263         return sorted (self.compactList.keys())
0264 
0265 
0266     def _getLumiParts(self):
0267         """
0268         Turn compactList into a list of the format
0269         [ 'R1:L1', 'R2:L2-R2:L3' ] which is used by getCMSSWString and getVLuminosityBlockRange
0270         """
0271 
0272         parts = []
0273         runs = list(self.compactList.keys())
0274         runs = sorted(runs, key=int)
0275         for run in runs:
0276             lumis = self.compactList[run]
0277             for lumiPair in sorted(lumis):
0278                 if isinstance(lumiPair, int):
0279                     parts.append(str("%s:%s" % (run, lumiPair)))
0280                     continue
0281                 if lumiPair[0] == lumiPair[1]:
0282                     parts.append(str("%s:%s" % (run, lumiPair[0])))
0283                 else:
0284                     parts.append(str("%s:%s-%s:%s" %
0285                                  (run, lumiPair[0], run, lumiPair[1])))
0286         return parts
0287 
0288 
0289     def getCMSSWString(self):
0290         """
0291         Turn compactList into a list of the format
0292         R1:L1,R2:L2-R2:L3 which is acceptable to CMSSW LumiBlockRange variable
0293         """
0294 
0295         parts = self._getLumiParts()
0296         output = ','.join(parts)
0297         return str(output)
0298 
0299 
0300     def getVLuminosityBlockRange(self, tracked = False):
0301         """
0302         Turn compactList into an (optionally tracked) VLuminosityBlockRange
0303         """
0304 
0305         import FWCore.ParameterSet.Config as cms
0306         parts = self._getLumiParts()
0307         if tracked:
0308             return cms.VLuminosityBlockRange(parts)
0309         else:
0310             return cms.untracked.VLuminosityBlockRange(parts)
0311 
0312 
0313     def writeJSON(self, fileName):
0314         """
0315         Write out a JSON file representation of the object
0316         """
0317         jsonFile = open(fileName,'w')
0318         jsonFile.write("%s\n" % self)
0319         jsonFile.close()
0320 
0321 
0322     def removeRuns (self, runList):
0323         '''
0324         removes runs from runList from collection
0325         '''
0326         for run in runList:
0327             run = str(run)
0328             if run in self.compactList:
0329                 del self.compactList[run]
0330 
0331         return
0332 
0333 
0334     def selectRuns (self, runList):
0335         '''
0336         Selects only runs from runList in collection
0337         '''
0338         runsToDelete = []
0339         for run in self.compactList.keys():
0340             if int(run) not in runList and run not in runList:
0341                 runsToDelete.append(run)
0342 
0343         for run in runsToDelete:
0344             del self.compactList[run]
0345 
0346         return
0347 
0348     def contains (self, run, lumiSection = None):
0349         '''
0350         returns true if the run, lumi section passed in is contained
0351         in this lumiList.  Input can be either:
0352         - a single tuple of (run, lumi),
0353         - separate run and lumi numbers
0354         - a single run number (returns true if any lumi sections exist)
0355         '''
0356         if lumiSection is None:
0357             # if this is an integer or a string, see if the run exists
0358             if isinstance (run, int) or isinstance (run, str):
0359                 return str(run) in self.compactList
0360             # if we're here, then run better be a tuple or list
0361             try:
0362                 lumiSection = run[1]
0363                 run         = run[0]
0364             except:
0365                 raise RuntimeError("Improper format for run '%s'" % run)
0366         lumiRangeList = self.compactList.get( str(run) )
0367         if not lumiRangeList:
0368             # the run isn't there, so no need to look any further
0369             return False
0370         for lumiRange in lumiRangeList:
0371             # we want to make this as found if either the lumiSection
0372             # is inside the range OR if the lumi section is greater
0373             # than or equal to the lower bound of the lumi range and
0374             # the upper bound is 0 (which means extends to the end of
0375             # the run)
0376             if lumiRange[0] <= lumiSection and \
0377                (0 == lumiRange[1] or lumiSection <= lumiRange[1]):
0378                 # got it
0379                 return True
0380         return False
0381 
0382 
0383     def __contains__ (self, runTuple):
0384         return self.contains (runTuple)
0385 
0386 
0387 
0388 '''
0389 # Unit test code
0390 import unittest
0391 import FWCore.ParameterSet.Config as cms
0392 
0393 class LumiListTest(unittest.TestCase):
0394     """
0395     _LumiListTest_
0396 
0397     """
0398 
0399     def testRead(self):
0400         """
0401         Test reading from JSON
0402         """
0403         exString = "1:1-1:33,1:35,1:37-1:47,2:49-2:75,2:77-2:130,2:133-2:136"
0404         exDict   = {'1': [[1, 33], [35, 35], [37, 47]],
0405                     '2': [[49, 75], [77, 130], [133, 136]]}
0406         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')
0407 
0408         jsonList = LumiList(filename = 'lumiTest.json')
0409         lumiString = jsonList.getCMSSWString()
0410         lumiList = jsonList.getCompactList()
0411         lumiVLBR = jsonList.getVLuminosityBlockRange(True)
0412 
0413         self.assertTrue(lumiString == exString)
0414         self.assertTrue(lumiList   == exDict)
0415         self.assertTrue(lumiVLBR   == exVLBR)
0416 
0417     def testList(self):
0418         """
0419         Test constucting from list of pairs
0420         """
0421 
0422         listLs1 = range(1, 34) + [35] + range(37, 48)
0423         listLs2 = range(49, 76) + range(77, 131) + range(133, 137)
0424         lumis = zip([1]*100, listLs1) + zip([2]*100, listLs2)
0425 
0426         jsonLister = LumiList(filename = 'lumiTest.json')
0427         jsonString = jsonLister.getCMSSWString()
0428         jsonList = jsonLister.getCompactList()
0429 
0430         pairLister = LumiList(lumis = lumis)
0431         pairString = pairLister.getCMSSWString()
0432         pairList = pairLister.getCompactList()
0433 
0434         self.assertTrue(jsonString == pairString)
0435         self.assertTrue(jsonList   == pairList)
0436 
0437 
0438     def testRuns(self):
0439         """
0440         Test constucting from run and list of lumis
0441         """
0442         runsAndLumis = {
0443             1: range(1, 34) + [35] + range(37, 48),
0444             2: range(49, 76) + range(77, 131) + range(133, 137)
0445         }
0446         runsAndLumis2 = {
0447             '1': range(1, 34) + [35] + range(37, 48),
0448             '2': range(49, 76) + range(77, 131) + range(133, 137)
0449         }
0450         blank = {
0451             '1': [],
0452             '2': []
0453         }
0454 
0455         jsonLister = LumiList(filename = 'lumiTest.json')
0456         jsonString = jsonLister.getCMSSWString()
0457         jsonList   = jsonLister.getCompactList()
0458 
0459         runLister = LumiList(runsAndLumis = runsAndLumis)
0460         runString = runLister.getCMSSWString()
0461         runList   = runLister.getCompactList()
0462 
0463         runLister2 = LumiList(runsAndLumis = runsAndLumis2)
0464         runList2 = runLister2.getCompactList()
0465 
0466         runLister3 = LumiList(runsAndLumis = blank)
0467 
0468 
0469         self.assertTrue(jsonString == runString)
0470         self.assertTrue(jsonList   == runList)
0471         self.assertTrue(runList2   == runList)
0472         self.assertTrue(len(runLister3) == 0)
0473 
0474     def testFilter(self):
0475         """
0476         Test filtering of a list of lumis
0477         """
0478         runsAndLumis = {
0479             1: range(1, 34) + [35] + range(37, 48),
0480             2: range(49, 76) + range(77, 131) + range(133, 137)
0481         }
0482 
0483         completeList = zip([1]*150, range(1, 150)) + \
0484                        zip([2]*150, range(1, 150)) + \
0485                        zip([3]*150, range(1, 150))
0486 
0487         smallList    = zip([1]*50,  range(1, 10)) + zip([2]*50, range(50, 70))
0488         overlapList  = zip([1]*150, range(30, 40)) + \
0489                        zip([2]*150, range(60, 80))
0490         overlapRes   = zip([1]*9,   range(30, 34)) + [(1, 35)] + \
0491                        zip([1]*9,   range(37, 40)) + \
0492                        zip([2]*30,  range(60, 76)) + \
0493                        zip([2]*9,   range(77, 80))
0494 
0495         runLister = LumiList(runsAndLumis = runsAndLumis)
0496 
0497         # Test a list to be filtered which is a superset of constructed list
0498         filterComplete = runLister.filterLumis(completeList)
0499         # Test a list to be filtered which is a subset of constructed list
0500         filterSmall    = runLister.filterLumis(smallList)
0501         # Test a list to be filtered which is neither
0502         filterOverlap  = runLister.filterLumis(overlapList)
0503 
0504         self.assertTrue(filterComplete == runLister.getLumis())
0505         self.assertTrue(filterSmall    == smallList)
0506         self.assertTrue(filterOverlap  == overlapRes)
0507 
0508     def testDuplicates(self):
0509         """
0510         Test a list with lots of duplicates
0511         """
0512         result = zip([1]*100, range(1, 34) + range(37, 48))
0513         lumis  = zip([1]*100, range(1, 34) + range(37, 48) + range(5, 25))
0514 
0515         lister = LumiList(lumis = lumis)
0516         self.assertTrue(lister.getLumis() == result)
0517 
0518     def testNull(self):
0519         """
0520         Test a null list
0521         """
0522 
0523         runLister = LumiList(lumis = None)
0524 
0525         self.assertTrue(runLister.getCMSSWString() == '')
0526         self.assertTrue(runLister.getLumis() == [])
0527         self.assertTrue(runLister.getCompactList() == {})
0528 
0529     def testSubtract(self):
0530         """
0531         a-b for lots of cases
0532         """
0533 
0534         alumis = {'1' : range(2,20) + range(31,39) + range(45,49),
0535                   '2' : range(6,20) + range (30,40),
0536                   '3' : range(10,20) + range (30,40) + range(50,60),
0537                  }
0538         blumis = {'1' : range(1,6) + range(12,13) + range(16,30) + range(40,50) + range(33,36),
0539                   '2' : range(10,35),
0540                   '3' : range(10,15) + range(35,40) + range(45,51) + range(59,70),
0541                  }
0542         clumis = {'1' : range(1,6) + range(12,13) + range(16,30) + range(40,50) + range(33,36),
0543                   '2' : range(10,35),
0544                  }
0545         result = {'1' : range(6,12) + range(13,16) + range(31,33) + range(36,39),
0546                   '2' : range(6,10) + range(35,40),
0547                   '3' : range(15,20) + range(30,35) + range(51,59),
0548                  }
0549         result2 = {'1' : range(6,12) + range(13,16) + range(31,33) + range(36,39),
0550                    '2' : range(6,10) + range(35,40),
0551                    '3' : range(10,20) + range (30,40) + range(50,60),
0552                  }
0553         a = LumiList(runsAndLumis = alumis)
0554         b = LumiList(runsAndLumis = blumis)
0555         c = LumiList(runsAndLumis = clumis)
0556         r = LumiList(runsAndLumis = result)
0557         r2 = LumiList(runsAndLumis = result2)
0558 
0559         self.assertTrue((a-b).getCMSSWString() == r.getCMSSWString())
0560         self.assertTrue((a-b).getCMSSWString() != (b-a).getCMSSWString())
0561         # Test where c is missing runs from a
0562         self.assertTrue((a-c).getCMSSWString() == r2.getCMSSWString())
0563         self.assertTrue((a-c).getCMSSWString() != (c-a).getCMSSWString())
0564         # Test empty lists
0565         self.assertTrue(str(a-a) == '{}')
0566         self.assertTrue(len(a-a) == 0)
0567 
0568     def testOr(self):
0569         """
0570         a|b for lots of cases
0571         """
0572 
0573         alumis = {'1' : range(2,20) + range(31,39) + range(45,49),
0574                   '2' : range(6,20) + range (30,40),
0575                   '3' : range(10,20) + range (30,40) + range(50,60),
0576                  }
0577         blumis = {'1' : range(1,6) + range(12,13) + range(16,30) + range(40,50) + range(39,80),
0578                   '2' : range(10,35),
0579                   '3' : range(10,15) + range(35,40) + range(45,51) + range(59,70),
0580                  }
0581         clumis = {'1' : range(1,6) + range(12,13) + range(16,30) + range(40,50) + range(39,80),
0582                   '2' : range(10,35),
0583                  }
0584         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),
0585                   '2' : range(6,20) + range (30,40) + range(10,35),
0586                   '3' : range(10,20) + range (30,40) + range(50,60) + range(10,15) + range(35,40) + range(45,51) + range(59,70),
0587                  }
0588         a = LumiList(runsAndLumis = alumis)
0589         b = LumiList(runsAndLumis = blumis)
0590         c = LumiList(runsAndLumis = blumis)
0591         r = LumiList(runsAndLumis = result)
0592         self.assertTrue((a|b).getCMSSWString() == r.getCMSSWString())
0593         self.assertTrue((a|b).getCMSSWString() == (b|a).getCMSSWString())
0594         self.assertTrue((a|b).getCMSSWString() == (a+b).getCMSSWString())
0595 
0596         # Test list constuction (faster)
0597 
0598         multiple = [alumis, blumis, clumis]
0599         easy = LumiList(runsAndLumis = multiple)
0600         hard = a + b
0601         hard += c
0602         self.assertTrue(hard.getCMSSWString() == easy.getCMSSWString())
0603 
0604     def testAnd(self):
0605         """
0606         a&b for lots of cases
0607         """
0608 
0609         alumis = {'1' : range(2,20) + range(31,39) + range(45,49),
0610                   '2' : range(6,20) + range (30,40),
0611                   '3' : range(10,20) + range (30,40) + range(50,60),
0612                   '4' : range(1,100),
0613                  }
0614         blumis = {'1' : range(1,6) + range(12,13) + range(16,25) + range(25,40) + range(40,50) + range(33,36),
0615                   '2' : range(10,35),
0616                   '3' : range(10,15) + range(35,40) + range(45,51) + range(59,70),
0617                   '5' : range(1,100),
0618                  }
0619         result = {'1' : range(2,6) + range(12,13) + range(16,20) + range(31,39) + range(45,49),
0620                   '2' : range(10,20) + range(30,35),
0621                   '3' : range(10,15) + range(35,40) + range(50,51)+ range(59,60),
0622                  }
0623         a = LumiList(runsAndLumis = alumis)
0624         b = LumiList(runsAndLumis = blumis)
0625         r = LumiList(runsAndLumis = result)
0626         self.assertTrue((a&b).getCMSSWString() == r.getCMSSWString())
0627         self.assertTrue((a&b).getCMSSWString() == (b&a).getCMSSWString())
0628         self.assertTrue((a|b).getCMSSWString() != r.getCMSSWString())
0629 
0630     def testRemoveSelect(self):
0631         """
0632         a-b for lots of cases
0633         """
0634 
0635         alumis = {'1' : range(2,20) + range(31,39) + range(45,49),
0636                   '2' : range(6,20) + range (30,40),
0637                   '3' : range(10,20) + range (30,40) + range(50,60),
0638                   '4' : range(10,20) + range (30,80),
0639                  }
0640 
0641         result = {'2' : range(6,20) + range (30,40),
0642                   '4' : range(10,20) + range (30,80),
0643                  }
0644 
0645         rem = LumiList(runsAndLumis = alumis)
0646         sel = LumiList(runsAndLumis = alumis)
0647         res = LumiList(runsAndLumis = result)
0648 
0649         rem.removeRuns([1,3])
0650         sel.selectRuns([2,4])
0651 
0652         self.assertTrue(rem.getCMSSWString() == res.getCMSSWString())
0653         self.assertTrue(sel.getCMSSWString() == res.getCMSSWString())
0654         self.assertTrue(sel.getCMSSWString() == rem.getCMSSWString())
0655 
0656     def testURL(self):
0657         URL = 'https://cms-service-dqm.web.cern.ch/cms-service-dqm/CAF/certification/Collisions12/8TeV/Reprocessing/Cert_190456-195530_8TeV_08Jun2012ReReco_Collisions12_JSON.txt'
0658         ll = LumiList(url=URL)
0659         self.assertTrue(len(ll) > 0)
0660 
0661 
0662     def testWrite(self):
0663         alumis = {'1' : range(2,20) + range(31,39) + range(45,49),
0664                   '2' : range(6,20) + range (30,40),
0665                   '3' : range(10,20) + range (30,40) + range(50,60),
0666                   '4' : range(1,100),
0667                  }
0668         a = LumiList(runsAndLumis = alumis)
0669         a.writeJSON('newFile.json')
0670 
0671 
0672 if __name__ == '__main__':
0673     jsonFile = open('lumiTest.json','w')
0674     jsonFile.write('{"1": [[1, 33], [35, 35], [37, 47]], "2": [[49, 75], [77, 130], [133, 136]]}')
0675     jsonFile.close()
0676     unittest.main()
0677 '''
0678 # Test JSON file
0679 
0680 #{"1": [[1, 33], [35, 35], [37, 47]], "2": [[49, 75], [77, 130], [133, 136]]}
0681 
0682 if __name__ == '__main__':
0683     #############################################
0684     ## Load and save command line history when ##
0685     ## running interactively.                  ##
0686     #############################################
0687     import os, readline
0688     import atexit
0689     historyPath = os.path.expanduser("~/.pyhistory")
0690 
0691 
0692     def save_history(historyPath=historyPath):
0693         import readline
0694         readline.write_history_file(historyPath)
0695         if os.path.exists(historyPath):
0696             readline.read_history_file(historyPath)
0697 
0698 
0699     atexit.register(save_history)
0700     readline.parse_and_bind("set show-all-if-ambiguous on")
0701     readline.parse_and_bind("tab: complete")
0702     if os.path.exists (historyPath) :
0703         readline.read_history_file(historyPath)
0704         readline.set_history_length(-1)
0705 
0706