Exemple #1
0
    def __init__(self, useOracle=False, debug=True):

        self.tdaqdbname = 'COOLONL_TDAQ/CONDBR2'
        self.coolpath = '/TDAQ/RunCtrl'

        self.trigdbname = 'COOLONL_TRIGGER/CONDBR2'
        self.coollbpath = '/TRIGGER/LUMI/LBLB'

        self.dcsdbname = 'COOLOFL_DCS/CONDBR2'
        self.coollhcpath = '/LHC/DCS/FILLSTATE'

        self.oracle = useOracle
        self.debug = debug

        print('open cool db')
        self.cooldb = AtlCoolLib.indirectOpen(self.tdaqdbname, True,
                                              self.oracle, self.debug)
        print('open cooltrig db')
        self.cooltrigdb = AtlCoolLib.indirectOpen(self.trigdbname, True,
                                                  self.oracle, self.debug)
        print('open cooldcs db')
        self.cooldcsdb = AtlCoolLib.indirectOpen(self.dcsdbname, True,
                                                 self.oracle, self.debug)

        self.lbDictCache = {'runnr': None, 'lbDict': None}
Exemple #2
0
    def getLBs(self):
        "Get the number of lumiblocks in each run, using the LBLB folder"
        lbdata = {}
        tdaqdbname = 'COOLONL_TRIGGER/COMP200'
        tdaqdb = AtlCoolLib.indirectOpen(tdaqdbname, True, True)
        if tdaqdb is None:
            print "ERROR - cannot access %s for run/LB mapping lookup" % tdaqdbname
        try:
            lbfolder = tdaqdb.getFolder('/TRIGGER/LUMI/LBLB')
            objs = lbfolder.browseObjects(self.since, self.until,
                                          cool.ChannelSelection(0))
            oldrun = 0
            maxlb = 0
            while objs.goToNext():
                obj = objs.currentRef()
                iovsince = obj.since()
                run = int(iovsince >> 32)
                lb = int(iovsince & 0xFFFFFFFF)
                if (run != oldrun):
                    if oldrun != 0:
                        lbdata[oldrun] = maxlb
                    maxlb = 0
                    oldrun = run
                if lb > maxlb: maxlb = lb
            if oldrun != 0: lbdata[oldrun] = maxlb

        except Exception, e:
            print e
            print "ERROR accessing data for run/LB mapping"
Exemple #3
0
    def __init__(self, dbfile, corrtop, dryrun=False, domagic=True):
        self.corrtop = corrtop
        self.dryrun = dryrun
        self.domagic = domagic
        dbsvc = cool.DatabaseSvcFactory.databaseService()

        if dbfile.endswith('.db'):
            connstring = "sqlite://;schema=%s;dbname=OFLP200" % dbfile
            self.makeleaf = True
        else:
            connstring = dbfile
            self.makeleaf = False

        self.db = AtlCoolLib.indirectOpen(connstring, False, False, True)

        # List of all folders.
        self.folders = []

        # Map from tool creation functions to folders.
        self.funcmap = {}

        # Map from (folder, hier-tag) pairs to individual folder tags
        self.tags = {}

        self.get_all_folders(corrtop)
        return
Exemple #4
0
    def __init__(self, cool_tdaq, cool_trig, oracle=False):
        self.filter = {}
        try:
            self.cool_tdaq = AtlCoolLib.indirectOpen(
                cool_tdaq, True, oracle, debug=False
            )
            self.cool_trig = AtlCoolLib.indirectOpen(
                cool_trig, True, oracle, debug=False
            )
        except Exception:
            logger.exception("Could not open cool database")
            return
        logger.info("Connected to {0}".format(cool_tdaq))

        self.mintime = cool.ValidityKeyMin
        self.maxtime = cool.ValidityKeyMax
Exemple #5
0
    def __init__(self, cool_tdaq, cool_trig, oracle=False):
        self.filter = {}
        try:
            self.cool_tdaq = AtlCoolLib.indirectOpen(cool_tdaq,
                                                     True,
                                                     oracle,
                                                     debug=True)
            self.cool_trig = AtlCoolLib.indirectOpen(cool_trig,
                                                     True,
                                                     oracle,
                                                     debug=True)
        except Exception:
            logging.exception("Could not open cool database")
            return
        logging.info("Connected to {0}".format(cool_tdaq))

        self.mintime = cool.ValidityKeyMin
        self.maxtime = cool.ValidityKeyMax
Exemple #6
0
def ReadRtCool(db_string, folder, tag, run_number):

    try:
        db = AtlCoolLib.indirectOpen(db_string,
                                     oracle=True,
                                     readOnly=True,
                                     debug=True)
    except Exception as e:
        print('Problem opening database', e)
        sys.exit(-1)


#get folder and tag
    cool_folder = db.getFolder(folder)
    cool_tag = ResolveTag(cool_folder, tag)

    #data to be filled
    graphs = {}
    splines = {}
    iovs = set([])

    myiov = (run_number << 32)

    objs = cool_folder.browseObjects(myiov, myiov, cool.ChannelSelection.all(),
                                     cool_tag)
    for obj in objs:
        iov = (obj.since(), obj.until())
        iovs.add(iov)
        sp = UnpackData(obj.payload()['data']).split('\n')
        sp1 = sp[0].split(',')
        chamber = int(sp1[0])
        n_points = int(sp1[1])
        sp2 = sp[1].split(',')
        graphs[chamber] = TGraphErrors(n_points)
        up = MuonFixedIdUnpack(chamber)
        if up.stationNameString() == 'XXX':
            print("Invalid station name in ", obj.payload()['file'])
            sys.exit(1)
        nm = up.stationNameString() + "_" + str(up.stationPhi()) + "_" + str(
            up.stationEta())
        #		print (nm)
        ts_applied = TimeSlewingApplied(obj)
        for i in range(0, n_points):
            r = float(sp2[3 * i])
            t = float(sp2[3 * i + 1])
            s = float(sp2[3 * i + 2])
            if not ts_applied:
                t_new = NoTs2Ts(r, t)
                t = t_new
            graphs[chamber].SetPoint(i, r, t)
            graphs[chamber].SetPointError(i, 0, s)
        splines[chamber] = TSpline3("sp_" + nm, graphs[chamber])
        if gDirectory.IsWritable():
            splines[chamber].Write("sp_" + nm)
            graphs[chamber].Write("gr_" + nm)

    return graphs, splines, iovs
Exemple #7
0
def ReadRtCool(db_string, folder, tag, run_number):

    try:
        db = AtlCoolLib.indirectOpen(db_string,
                                     oracle=True,
                                     readOnly=True,
                                     debug=True)
    except Exception, e:
        print 'Problem opening database', e
        sys.exit(-1)
	def ResolveGlobalTag(self, tag, dbstring="COOLOFL_MDT/CONDBR2"):
		if self.Tag:
			print "INFO Tag for", self.Folder, "already set to", self.Tag
			print "INFO Not resolving global tag"
			return
		try:
			db=AtlCoolLib.indirectOpen(dbstring, oracle=True, readOnly=True, debug=True)
		except Exception,e:
			print 'Problem opening database',e
			sys.exit(-1)	
Exemple #9
0
def DumpFolderSummary(db_string, folder, tag, run=None):

    try:
        db = AtlCoolLib.indirectOpen(db_string,
                                     oracle=True,
                                     readOnly=True,
                                     debug=True)
    except Exception, e:
        print 'Problem opening database', e
        sys.exit(-1)
def linkDummy (dbfile, folder):
    htags, dtag = get_htags (folder)

    if dbfile.endswith ('.db'):
        connstring = "sqlite://;schema=%s;dbname=OFLP200" % dbfile
    else:
        connstring = dbfile
    db = AtlCoolLib.indirectOpen(connstring,False,False,True)
    f = db.getFolder (folder)
    for h in htags:
        link_tag (f, h, dtag)
Exemple #11
0
def connect(connectString, verbose=False):
    """
    Connects to the given database and returns a tuple
       database, connectString
    where 'database' is a cool.IDatabase object and 'connectString' is the
    possibly expanded connectString that 'database' is based on.
    
    This expansion can occur when a connect string without a containing
    '://' is specified. In this case the string is interpreted as a sqlite
    file name and rewritten to a RAL compliant format:
    
        TEST.db  --> 'sqlite://;schema=TEST.db;dbname=TEST'
        TEST     --> 'sqlite://;schema=TEST;dbname=TEST'
    
    The filename can have a '.db' suffix which will be stripped for the
    'dbname' part of the connect string. Other suffixes will not be recognized.
    
    Note that the COOL database inside the file must have the same name as the
    base of the filename for this shortcut to work. Storing a COOL database
    MYTEST in a file mytest.db will not work.
    
    Set verbose to True to obtain an error print out.
    """
    connectString = expandConnectString(connectString)
    forceoracle = True
    debug = False
    if (';readoracle' in connectString):
        # new default is forceOracle - but giving keyword explicitly
        # forces debug printout
        connectString = connectString.replace(';readoracle', '')
        debug = True
    if (';readsqlite' in connectString):
        connectString = connectString.replace(';readsqlite', '')
        debug = True
        forceoracle = False
    try:
        dbSvc = cool.DatabaseSvcFactory.databaseService()
        readonly = True
        # frontier/logical cannot do update connections - only real dbs
        if ('oracle' in connectString or 'mysql' in connectString
                or 'sqlite' in connectString):
            readonly = False
        db = AtlCoolLib.indirectOpen(connectString, readonly, forceoracle,
                                     debug)
    except Exception as e:
        if 'The database does not exist' in str(e):
            print("Creating new database")
            db = dbSvc.createDatabase(connectString)
        else:
            if verbose: print('Error while connecting:', str(e))
            db = None
    return db, connectString
Exemple #12
0
def scrub(dbfile, folder):
    if dbfile.endswith('.db'):
        connstring = "sqlite://;schema=%s;dbname=OFLP200" % dbfile
    else:
        connstring = dbfile

    db = AtlCoolLib.indirectOpen(connstring, False, False, True)
    if not db.existsFolderSet(folder):
        print("Can't find folder", folder)
        sys.exit(1)
    fs = db.getFolderSet(folder)
    for f in fs.listFolders():
        scrubFolder(db, f)
    return
Exemple #13
0
 def ResolveGlobalTag(self, tag, dbstring="COOLOFL_MDT/CONDBR2"):
     if self.Tag:
         print("INFO Tag for", self.Folder, "already set to", self.Tag)
         print("INFO Not resolving global tag")
         return
     try:
         db = AtlCoolLib.indirectOpen(dbstring,
                                      oracle=True,
                                      readOnly=True,
                                      debug=True)
     except Exception as e:
         print('Problem opening database', e)
         sys.exit(-1)
     cool_folder = db.getFolder(self.Folder)
     self.Tag = ResolveTag(cool_folder, tag)
     print("INFO tag '" + tag + "' resolves to '" + self.Tag +
           "' for folder '" + self.Folder + "'")
Exemple #14
0
def DumpFolderSummary(db_string, folder, tag, run=None):

    try:
        db = AtlCoolLib.indirectOpen(db_string,
                                     oracle=True,
                                     readOnly=True,
                                     debug=True)
    except Exception as e:
        print('Problem opening database', e)
        sys.exit(-1)


#get folder and tag
    cool_folder = db.getFolder(folder)
    cool_tag = ResolveTag(cool_folder, tag)

    counters = {}
    if run:
        objs = cool_folder.browseObjects((run << 32), ((run + 1) << 32),
                                         cool.ChannelSelection.all(), cool_tag)
    else:
        objs = cool_folder.browseObjects(0, (999999 << 32),
                                         cool.ChannelSelection.all(), cool_tag)
    for obj in objs:
        file_col = obj.payload()['file']
        file_items = re.split('[A-Z,a-z]*', file_col)
        site = "default"
        head_id = -1
        if len(file_items) == 2:
            try:
                head_id = int(file_items[1])
                site = re.sub("[0-9]", "", file_col)
            except ValueError:
                site = file_col
        ts = "NOTS"
        if TimeSlewingApplied(obj):
            ts = "TS"
        ident = (obj.since() >> 32, obj.until() >> 32, site, head_id, ts)
        if not ident in counters:
            counters[ident] = 0
        counters[ident] += 1
    for ident in sorted(counters.keys(), key=iov_keygen):
        print("[", ident[0], ",", ident[1], "[", ident[2], ident[3], ident[4],
              ":", counters[ident])
def get_htags (folder):
    connstring = 'COOLOFL_CALO/OFLP200'
    db = AtlCoolLib.indirectOpen (connstring, True, True, True)
    parent = os.path.dirname (folder)
    fs = db.getFolderSet (parent)
    tags = fs.listTags()
    subf = db.getFolder (folder)
    htags = []
    for t in tags:
        try:
            rtag = subf.resolveTag(t)
        except:
            htags.append (t)

    tags = subf.listTags()
    dtag = None
    for t in tags:
        if t.endswith ('-dummy'):
            dtag = t
            break
    return (htags, dtag)
Exemple #16
0
def ReadT0Cool(db_string, folder, tag, run_number):

    try:
        db = AtlCoolLib.indirectOpen(db_string,
                                     oracle=True,
                                     readOnly=True,
                                     debug=True)
    except Exception as e:
        print('Problem opening database', e)
        sys.exit(-1)


#get folder and tag
    cool_folder = db.getFolder(folder)
    cool_tag = ResolveTag(cool_folder, tag)
    myiov = (run_number << 32)
    #data
    t0_values = {}

    objs = cool_folder.browseObjects(myiov, myiov, cool.ChannelSelection.all(),
                                     cool_tag)

    for obj in objs:
        sp = UnpackData(obj.payload()['data']).split('\n')
        sp1 = sp[0].split(',')
        ch_sp = sp1[0][2:].split("_")
        ch_id = (ch_sp[0], int(ch_sp[1]), int(ch_sp[2]))
        ntubes = int(sp1[-1])

        t0_items = sp[1].split(",")
        t0_values[ch_id] = []
        ts_applied = TimeSlewingApplied(obj)
        for i in range(0, ntubes):
            t0 = float(t0_items[3 * i + 0])
            if not ts_applied:
                t0 += GasmonDriftTimeOffsetT0
            t0_values[ch_id].append(
                (t0, int(t0_items[3 * i + 1]), float(t0_items[3 * i + 2])))

    return t0_values
Exemple #17
0
    def execute(self):

        initialPosX = self.bs.beamPos().x()
        initialPosY = self.bs.beamPos().y()
        initialPosZ = self.bs.beamPos().z()
        initialSigmaX = self.bs.beamSigma(0)
        initialSigmaY = self.bs.beamSigma(1)
        initialSigmaZ = self.bs.beamSigma(2)
        initialTiltXZ = self.bs.beamTilt(0)
        initialTiltYZ = self.bs.beamTilt(1)

        self.msg.verbose('Intial position from DB (%f, %f, %f)' %
                         (initialPosX, initialPosY, initialPosZ))
        self.msg.verbose('Intial width from DB (%f, %f, %f)' %
                         (initialSigmaX, initialSigmaY, initialSigmaZ))

        if self.targetBStag != '' or self.initialBStag != '':
            #Get Event info object
            eventInfo = self.sg.retrieve('EventInfo', "McEventInfo")
            iov = eventInfo.event_ID().run_number() << 32 | (
                eventInfo.event_ID().lumi_block() & 0xFFFFFFFF)

            #Get BS from database
            from CoolConvUtilities import AtlCoolLib
            from PyCool import cool
            cooldbBS = AtlCoolLib.indirectOpen('COOLOFL_INDET/OFLP200', True,
                                               True, False)
            folderBS = cooldbBS.getFolder('/Indet/Beampos')

            if self.initialBStag != '':
                self.msg.info(
                    'Taking initial beamspot information from conditions database: %s'
                    % self.initialBStag)
                itrBS = folderBS.browseObjects(iov, iov,
                                               cool.ChannelSelection.all(),
                                               self.initialBStag)
                while itrBS.goToNext():
                    obj = itrBS.currentRef()
                    self.initialSigmaX = float(obj.payloadValue("sigmaX"))
                    self.initialSigmaY = float(obj.payloadValue("sigmaY"))
                    self.initialSigmaZ = float(obj.payloadValue("sigmaZ"))
                    self.initialTiltXZ = float(obj.payloadValue("tiltX"))
                    self.initialTiltYZ = float(obj.payloadValue("tiltY"))
                    self.initialPosX = float(obj.payloadValue("posX"))
                    self.initialPosY = float(obj.payloadValue("posY"))
                    self.initialPosZ = float(obj.payloadValue("posZ"))
                    break
                self.initialBStag = ''
                self.msg.info(
                    'Intial BS position from tag  (%f, %f, %f)' %
                    (self.initialPosX, self.initialPosY, self.initialPosZ))
                self.msg.info('Intial BS width from tag (%f, %f, %f)' %
                              (self.initialSigmaX, self.initialSigmaY,
                               self.initialSigmaZ))

            if self.targetBStag != '':

                self.msg.info(
                    'Taking target beamspot information from conditions database: %s'
                    % self.targetBStag)
                self.msg.info('Only widths are considered not positions!!!')
                itrBS = folderBS.browseObjects(iov, iov,
                                               cool.ChannelSelection.all(),
                                               self.targetBStag)
                while itrBS.goToNext():
                    obj = itrBS.currentRef()
                    self.targetSigmaX = float(obj.payloadValue("sigmaX"))
                    self.targetSigmaY = float(obj.payloadValue("sigmaY"))
                    self.targetSigmaZ = float(obj.payloadValue("sigmaZ"))
                    break
                self.targetBStag = ''
                self.msg.info(
                    'Target width (%f, %f, %f)' %
                    (self.targetSigmaX, self.targetSigmaY, self.targetSigmaZ))

        targetSigmaX = self.targetSigmaX if self.targetSigmaX > 0. else initialSigmaX
        targetSigmaY = self.targetSigmaY if self.targetSigmaY > 0. else initialSigmaY
        targetSigmaZ = self.targetSigmaZ if self.targetSigmaZ > 0. else initialSigmaZ

        initialSigmaX = self.initialSigmaX if self.initialSigmaX > 0. else initialSigmaX
        initialSigmaY = self.initialSigmaY if self.initialSigmaY > 0. else initialSigmaY
        initialSigmaZ = self.initialSigmaZ if self.initialSigmaZ > 0. else initialSigmaZ
        initialPosX = self.initialPosX if self.initialPosX > -999. else initialPosX
        initialPosY = self.initialPosY if self.initialPosY > -999. else initialPosY
        initialPosZ = self.initialPosZ if self.initialPosZ > -999. else initialPosZ
        initialTiltXZ = self.initialTiltXZ if self.initialTiltXZ > -999. else initialTiltXZ
        initialTiltYZ = self.initialTiltYZ if self.initialTiltYZ > -999. else initialTiltYZ

        self.msg.verbose('Intial position used (%f, %f, %f)' %
                         (initialPosX, initialPosY, initialPosZ))
        self.msg.verbose('Intial width used (%f, %f, %f)' %
                         (initialSigmaX, initialSigmaY, initialSigmaZ))
        self.msg.verbose('Target width used (%f, %f, %f)' %
                         (targetSigmaX, targetSigmaY, targetSigmaZ))

        #Get Signa event
        truthEventCollection = self.sg.retrieve("McEventCollection",
                                                "TruthEvent")
        # get GenEvent
        genEvent = truthEventCollection[0]
        # get Signal Vertex
        sigVtx = genEvent.signal_process_vertex()

        deltaZ = initialPosZ - sigVtx.position().z()
        deltaX = initialPosX + deltaZ * initialTiltXZ - sigVtx.position().x()
        deltaY = initialPosY + deltaZ * initialTiltYZ - sigVtx.position().y()
        # Calculate prob of keeping this event
        weight =  self.calcScale( initialSigmaX, targetSigmaX, deltaX) \
                  * self.calcScale( initialSigmaY, targetSigmaY, deltaY) \
                  * self.calcScale( initialSigmaZ, targetSigmaZ, deltaZ)

        # Decide if you keep
        accept = weight > ROOT.gRandom.Rndm()
        self.setFilterPassed(accept)

        self.nProcessed += 1
        if accept:
            self.nEventPassed += 1

        return StatusCode.Success
Exemple #18
0
    def execute(self):
        # print "Name is %s" AtlCoolLib.getHostname()
        # prepare an empty StatusList for each channel
        statuslists = {}
        for chan in self.namelookup.allNums():
            statuslists[chan] = DetStatusLib.StatusList()

        # deduce the source database instance name, looking for xyzP200
        idx = self.conn.find('P200')
        if (idx >= 3):
            dbinst = self.conn[idx - 3:idx + 4]
            print "Working with database instance %s" % dbinst
        else:
            print "Cannot deduce database instance name, assume COMP200"
            dbinst = 'COMP200'

        # Extract timestamp information for mapping to run/LB
        tsconvdb = AtlCoolLib.indirectOpen('COOLONL_TRIGGER/' + dbinst,
                                           oracle=self.oracle)
        # initialize the converter
        tsToRLB = AtlCoolLib.TimeStampToRLB(tsconvdb, self.since, self.until)
        tsconvdb.closeDatabase()

        StartTime = tsToRLB.StartTime
        EndTime = tsToRLB.EndTime

        # open auxillary databases for online and DCS info
        onlinedb = AtlCoolLib.indirectOpen('COOLONL_GLOBAL/' + dbinst,
                                           oracle=self.oracle)
        dcsdb = AtlCoolLib.indirectOpen('COOLOFL_GLOBAL/' + dbinst,
                                        oracle=self.oracle)

        # loop over all 'AND' folders and merge information
        ngood = 0
        nbad = 0
        for (afolder, atag, override) in self.folderinfo:
            print "Process folder %s tag %s override %d" % (afolder, atag,
                                                            override)
            try:
                atsindexed = 0
                isonline = 0
                if (afolder.find("ONL") != -1):
                    isonline = 1

                isdcs = 0
                if (afolder.find("DCS") != -1):
                    isdcs = 1

                tostart = self.since
                toend = self.until
                ifolder = None

                if (isonline):
                    ifolder = onlinedb.getFolder(afolder)
                elif (isdcs):
                    ifolder = dcsdb.getFolder(afolder)
                else:
                    ifolder = self.db.getFolder(afolder)

                descr = ifolder.description()

                if (descr.find("<timeStamp>time") != -1):
                    atsindexed = 1
                    tostart = StartTime
                    toend = EndTime

                objs = None
                if (isonline | isdcs):
                    objs = ifolder.browseObjects(tostart, toend,
                                                 cool.ChannelSelection.all())
                else:
                    objs = ifolder.browseObjects(tostart, toend,
                                                 cool.ChannelSelection.all(),
                                                 atag)

                while objs.goToNext():
                    obj = objs.currentRef()
                    chan = obj.channelId()
                    if (chan in statuslists.keys()):
                        start = obj.since()
                        stop = obj.until()
                        payload = obj.payload()
                        code = payload['Code']
                        deadfrac = payload['deadFrac']
                        thrust = payload['Thrust']
                        if ('NConfig' in payload.keys()):
                            nconfig = payload['NConfig']
                            nworking = payload['NWorking']
                        else:
                            nconfig = -1
                            nworking = -1

                        if ('Comment' in payload.keys()):
                            comment = payload['Comment']
                        else:
                            comment = ''
                        #override=False

                        if (atsindexed):
                            start = tsToRLB.getRLB(start, True)
                            stop = tsToRLB.getRLB(stop, False) + 1

                        statuslists[chan].merge(
                            DetStatusLib.StatusObj(start, stop, code, deadfrac,
                                                   thrust, nconfig, nworking,
                                                   comment), override)
                        ngood += 1
                    else:
                        print "Data found for unexpected channel %i" % chan
                        nbad += 1
            except Exception, e:
                print e
                print "Problem accessing folder %s" % afolder
                nbad += 1
Exemple #19
0
def main():
    f1 = "%s::%s" % (db1, options.folderBS)
    f2 = "%s::%s" % (db2, options.folderLumi)

    print("=" * 100)
    print("Comparing: ")
    print("  * ", f1, options.tagBS)
    print("  * ", f2, options.tagLumi)
    print("=" * 100)

    requiredForNtuple = ['posX', 'posY', 'posZ', 'sigmaX', 'sigmaY', 'sigmaZ']
    checkNtupleProd = all(item in varColl for item in requiredForNtuple)
    if not checkNtupleProd:
        print('Ntuple will not be filled missing vars')

    #Open up required databases
    from PyCool import cool
    from CoolConvUtilities import AtlCoolLib
    cooldbBS = AtlCoolLib.indirectOpen(db1, True, True, False)
    cooldbLumi = AtlCoolLib.indirectOpen(db2, True, True, False)

    folderBS = cooldbBS.getFolder(options.folderBS)
    folderLumi = cooldbLumi.getFolder(options.folderLumi)

    from InDetBeamSpotExample.COOLUtils import COOLQuery
    coolQuery = COOLQuery()

    if options.runMin is not None:
        iov1 = options.runMin << 32
        if options.runMax is not None:
            iov2 = (options.runMax + 1) << 32
        else:
            iov2 = (options.runMin + 1) << 32
        print('Plotting runs %i to %i ' % (iov1, iov2))
    else:
        print('No run selected -- ERROR')
        return

    if (iov2 > cool.ValidityKeyMax):
        iov2 = cool.ValidityKeyMax

    print("Reading data from database")
    itrBS = folderBS.browseObjects(iov1, iov2, cool.ChannelSelection.all(),
                                   options.tagBS)
    print("...finished getting BS data")

    lbDict = dict()

    startRLB = 0x7FFFFFFFFFFFFFFF
    endRLB = 0

    outfile = ROOT.TFile("BeamspotLumi_%i.root" % (options.runMin), "recreate")
    ntuple = ROOT.TNtupleD(
        'BeamspotLumi', 'BeamSpotLumi',
        "x:y:z:sigma_x:sigma_y:sigma_z:run:mu:lumi:year:month:day:hour:minute:epoch"
    )

    runs = set()
    while itrBS.goToNext():

        obj = itrBS.currentRef()

        since = obj.since()

        runBegin = since >> 32
        lumiBegin = since & 0xFFFFFFFF

        until = obj.until()
        runUntil = until >> 32
        lumiUntil = until & 0xFFFFFFFF

        status = int(obj.payloadValue('status'))
        if status != 59:
            continue

        runs.add(runBegin)

        if since < startRLB:
            startRLB = since
        if until > endRLB:
            endRLB = until

        values = {}
        for var in varColl:
            values[var] = float(obj.payloadValue(var))
            values[var + 'Err'] = float(obj.payloadValue(var + 'Err'))
        values['until'] = until
        lbDict[since] = values

    print('Runs: ', runs)

    lumi = array('d')
    xd = array('d')
    exd = array('d')
    ydDict = {}
    eydDict = {}
    ydDict2 = {}

    sqtrt2pi = math.sqrt(2 * math.pi)

    lblb = CoolDataReader('COOLONL_TRIGGER/CONDBR2', '/TRIGGER/LUMI/LBLB')
    from DQUtils.sugar import RANGEIOV_VAL, RunLumi
    from DQUtils import IOVSet

    grlIOVs = IOVSet.from_grl(
        "data15_13TeV.periodAllYear_DetStatus-v89-pro21-02_Unknown_PHYS_StandardGRL_All_Good_25ns.xml"
    )
    grlIOVs += IOVSet.from_grl(
        "data16_13TeV.periodAllYear_DetStatus-v89-pro21-01_DQDefects-00-02-04_PHYS_StandardGRL_All_Good_25ns.xml"
    )
    grlIOVs += IOVSet.from_grl(
        "data17_13TeV.periodAllYear_DetStatus-v99-pro22-01_Unknown_PHYS_StandardGRL_All_Good_25ns_Triggerno17e33prim.xml"
    )
    grlIOVs += IOVSet.from_grl(
        "data18_13TeV.periodAllYear_DetStatus-v102-pro22-04_Unknown_PHYS_StandardGRL_All_Good_25ns_Triggerno17e33prim.xml"
    )

    for run in runs:
        iov1 = run << 32
        iov2 = (run + 1) << 32

        itrLumi = folderLumi.browseObjects(iov1, iov2,
                                           cool.ChannelSelection.all(),
                                           options.tagLumi)
        print("...finished getting Lumi data for run %i" % run)

        lblb.setIOVRangeFromRun(run)
        lblb.readData()
        if len(lblb.data) < 1:
            print('No LBLB data found!')
            continue
        # Make time map
        lblbMap = dict()
        for obj in lblb.data:
            lblbMap[obj.since()] = (obj.payload()['StartTime'],
                                    obj.payload()['EndTime'])

        while itrLumi.goToNext():
            obj = itrLumi.currentRef()

            since = obj.since()
            runBegin = since >> 32
            lumiBegin = since & 0xFFFFFFFF

            until = obj.until()
            runUntil = until >> 32
            lumiUntil = until & 0xFFFFFFFF

            inGRL = False
            for sinceGRL, untilGRL, grl_states in process_iovs(grlIOVs):
                if grl_states[0].since == None:
                    continue
                if (sinceGRL.run <= runBegin and untilGRL.run >= runUntil
                        and sinceGRL.lumi <= lumiBegin
                        and untilGRL.lumi >= lumiUntil):
                    inGRL = True
                    break

            if not inGRL:
                continue

            mu = float(obj.payloadValue('LBAvEvtsPerBX'))
            instlumi = float(obj.payloadValue('LBAvInstLumi'))

            #if( mu <  10 or mu > 65 ):
            #print 'Mu: %2.1f Run : %d  LB: %d - %d Lumi: %f' % (mu,runBegin,lumiBegin,lumiUntil,instlumi)

            if since in lbDict:
                if lbDict[since]['sigmaX'] > 0.1:
                    continue
                startTime = lblbMap.get(obj.since(), (0., 0.))[0]
                endTime = lblbMap.get(lbDict[since]['until'],
                                      (0., 0.))[0]  #[1] end of lumiblock
                mylumi = (endTime - startTime) / 1e9 * instlumi / 1e9
                thisTime = time.gmtime(startTime / 1.e9)
                year = thisTime[0]
                month = thisTime[1]
                day = thisTime[2]
                hour = thisTime[3]
                mins = thisTime[4]
                sec = thisTime[5]
                lumi.append(mylumi)
                # in fb^-1
                xd.append(mu)
                exd.append(0)

                if options.plotSomething:
                    for var in varColl:
                        if not var in ydDict:
                            ydDict[var] = array('d')
                            ydDict2[var] = array('d')
                            eydDict[var] = array('d')

                        ydDict2[var].append(mu /
                                            (lbDict[since][var] * sqtrt2pi))
                        ydDict[var].append(lbDict[since][var])
                        eydDict[var].append(lbDict[since][var + 'Err'])

                if checkNtupleProd and lbDict[since]['sigmaZErr'] < 5:
                    ntuple.Fill(lbDict[since]['posX'], lbDict[since]['posY'],
                                lbDict[since]['posZ'], lbDict[since]['sigmaX'],
                                lbDict[since]['sigmaY'],
                                lbDict[since]['sigmaZ'], runBegin, mu, mylumi,
                                year, month, day, hour, mins, startTime / 1.e9)

    runStart = startRLB >> 32
    runEnd = endRLB >> 32
    fillStart = fillEnd = 0
    timeStart = timeEnd = 0
    beamEnergy = 13
    try:
        timeStart = coolQuery.lbTime(int(startRLB >> 32),
                                     int(startRLB & 0xFFFFFFFF))[0]
    except:
        pass
    try:
        timeEnd = coolQuery.lbTime(int(endRLB >> 32),
                                   int(endRLB & 0xFFFFFFFF) - 1)[1]
    except:
        pass
    try:
        fillStart = coolQuery.getLHCInfo(timeStart).get('FillNumber', 0)
    except:
        pass
    try:
        fillEnd = coolQuery.getLHCInfo(timeEnd).get('FillNumber', 0)
    except:
        pass
    try:
        beamEnergy = coolQuery.getLHCInfo(timeStart).get('BeamEnergyGeV', 0)
        beamEnergy *= 2e-3
    except:
        pass

    ntuple.Write()

    if not options.plotSomething:
        return

    from InDetBeamSpotExample import ROOTUtils
    ROOTUtils.setStyle()
    canvas = ROOT.TCanvas('BeamSpotComparison', 'BeamSpotComparison', 1600,
                          1200)

    canvas.cd()
    ROOT.gPad.SetTopMargin(0.05)
    ROOT.gPad.SetLeftMargin(0.15)
    ROOT.gPad.SetRightMargin(0.05)

    if not options.plotGraph:
        ROOT.gPad.SetRightMargin(0.15)

    #Plot each variable
    for var in varColl:
        if var not in ydDict:
            print('Missing yd: ', var)
        if var not in eydDict:
            print('Missing eyd: ', var)
            continue

        gr = ROOT.TGraphErrors(len(xd), xd, ydDict[var], exd, eydDict[var])
        xmin = min(xd)
        xmax = max(xd)
        ymin = min(ydDict[var])
        ymax = max(ydDict[var])

        h = (ymax - ymin)
        ymin -= 0.25 * h
        ymaxSmall = ymax + 0.25 * h
        ymax += 0.75 * h

        ymin2 = min(ydDict2[var])
        ymax2 = max(ydDict2[var])

        h = (ymax2 - ymin2)
        ymin2 -= 0.25 * h
        ymax2 += 0.75 * h

        h = (xmax - xmin)
        xmin -= 0.05 * h
        xmax += 0.05 * h

        #This histogram is made just to make it easier to manipulate the margins
        histo = ROOT.TH2D('hd' + var, 'hd' + var, 100, xmin, xmax, 100, ymin,
                          ymax)
        histo.GetYaxis().SetTitle(varDef(var, 'atit', var))
        histo.GetXaxis().SetTitle('Average interactions per bunch crossing')
        histo.GetZaxis().SetTitle('Entries')

        histo2 = ROOT.TH2D('hd2' + var, 'hd2' + var, 100, xmin, xmax, 100,
                           ymin2, ymax2)
        histo2.GetYaxis().SetTitle(
            "<Interaction density> @ z=0 [interactions/mm]")
        histo2.GetXaxis().SetTitle('Average interactions per bunch crossing')
        histo2.GetZaxis().SetTitle('Entries')

        histo2W = ROOT.TH2D('hd3' + var, 'hd3' + var, 100, xmin, xmax, 100,
                            ymin2, ymax2)
        histo2W.GetYaxis().SetTitle(
            "<Interaction density> @ z=0 [interactions/mm]")
        histo2W.GetXaxis().SetTitle('Average interactions per bunch crossing')
        histo2W.GetZaxis().SetTitle('Integrated Luminosity (fb^{-1}/bin)')

        histoW = ROOT.TH2D('hdW' + var, 'hdW' + var, 100, xmin, xmax, 100,
                           ymin, ymax)
        histoW.GetYaxis().SetTitle(varDef(var, 'atit', var))
        histoW.GetXaxis().SetTitle('Average interactions per bunch crossing')
        histoW.GetZaxis().SetTitle('Integrated Luminosity (fb^{-1}/bin)')

        histoW1D = ROOT.TH1D('hd1D' + var, 'hd1D' + var, 100, ymin, ymaxSmall)
        histoW1D.GetXaxis().SetTitle(varDef(var, 'atit', var))
        histoW1D.GetYaxis().SetTitle('Integrated Luminosity (fb^{-1}/bin)')

        histo.Draw()
        if options.plotGraph:
            gr.Draw("p")
        else:
            for mu, x, l in zip(xd, ydDict[var], lumi):
                histo.Fill(mu, x)
                histoW.Fill(mu, x, l)
                histoW1D.Fill(x, l)
            for mu, x, l in zip(xd, ydDict2[var], lumi):
                histo2.Fill(mu, x)
                histo2W.Fill(mu, x, l)
            histo.Draw("colz")

        histo.Write()
        histoW.Write()
        histo2.Write()
        histo2W.Write()
        histoW1D.Write()

        # Add some information to the graph
        ROOTUtils.atlasLabel(0.53,
                             0.87,
                             False,
                             offset=0.12,
                             isForApproval=False,
                             customstring="Internal",
                             energy='%2.0f' % beamEnergy,
                             size=0.055)
        ROOTUtils.drawText(0.18, 0.87, 0.055, varDef(var, 'title', var))

        comments = []

        if runStart == runEnd:
            comments.append('Run %i' % runStart)
        else:
            comments.append('Runs %i - %i' % (runStart, runEnd))

        if fillStart == fillEnd:
            comments.append('Fill %i' % fillStart)
        else:
            comments.append('Fills %i - %i' % (fillStart, fillEnd))

        t1 = time.strftime('%d %b %Y', time.localtime(timeStart))
        t2 = time.strftime('%d %b %Y', time.localtime(timeEnd))
        if t1 == t2:
            comments.append(t1)
        else:
            comments.append('%s - %s' % (t1, t2))

        ROOTUtils.drawText(0.18, 0.81, 0.05, ';'.join(comments), font=42)

        canvas.Print("Run_%d_%sVsMu.png" % (options.runMin, var))
        canvas.Print("Run_%d_%sVsMu.pdf" % (options.runMin, var))
        if not options.plotGraph:
            canvas.SetLogz(True)
            canvas.Print("Run_%d_%sVsMuLog.png" % (options.runMin, var))
            canvas.Print("Run_%d_%sVsMuLog.pdf" % (options.runMin, var))
            canvas.SetLogz(False)

            histo2.Draw("colz")
            ROOTUtils.atlasLabel(0.53,
                                 0.87,
                                 False,
                                 offset=0.12,
                                 isForApproval=False,
                                 customstring="Internal",
                                 energy='%2.0f' % beamEnergy,
                                 size=0.055)
            ROOTUtils.drawText(0.18, 0.87, 0.055, "Interaction density")
            ROOTUtils.drawText(0.18, 0.81, 0.05, ';'.join(comments), font=42)
            canvas.Print("Run_%d_Mu%sVsMu.png" % (options.runMin, var))
            canvas.Print("Run_%d_Mu%sVsMu.pdf" % (options.runMin, var))
            canvas.SetLogz(True)
            canvas.Print("Run_%d_Mu%sVsMuLog.png" % (options.runMin, var))
            canvas.Print("Run_%d_Mu%sVsMuLog.pdf" % (options.runMin, var))
            canvas.SetLogz(False)

            histoW.Draw("colz")
            histoW.SetMinimum(0.005)
            ROOTUtils.atlasLabel(0.53,
                                 0.87,
                                 False,
                                 offset=0.12,
                                 isForApproval=False,
                                 customstring="Internal",
                                 energy='%2.0f' % beamEnergy,
                                 size=0.055)
            ROOTUtils.drawText(0.18, 0.87, 0.055, varDef(var, 'title', var))
            ROOTUtils.drawText(0.18, 0.81, 0.05, ';'.join(comments), font=42)
            canvas.Print("Run_%d_%sVsMuW.png" % (options.runMin, var))
            canvas.Print("Run_%d_%sVsMuW.pdf" % (options.runMin, var))
            canvas.SetLogz(True)
            canvas.Print("Run_%d_%sVsMuWLog.png" % (options.runMin, var))
            canvas.Print("Run_%d_%sVsMuWLog.pdf" % (options.runMin, var))
            canvas.SetLogz(False)

            histo2W.Draw("colz")
            histo2W.SetMinimum(0.01)

            ROOTUtils.atlasLabel(0.53,
                                 0.87,
                                 False,
                                 offset=0.12,
                                 isForApproval=False,
                                 customstring="Internal",
                                 energy='%2.0f' % beamEnergy,
                                 size=0.055)
            ROOTUtils.drawText(0.18, 0.87, 0.055, "Interaction density")
            ROOTUtils.drawText(0.18, 0.81, 0.05, ';'.join(comments), font=42)
            canvas.Print("Run_%d_Mu%sVsMuW.png" % (options.runMin, var))
            canvas.Print("Run_%d_Mu%sVsMuW.pdf" % (options.runMin, var))
            canvas.SetLogz(True)
            canvas.Print("Run_%d_Mu%sVsMuWLog.png" % (options.runMin, var))
            canvas.Print("Run_%d_Mu%sVsMuWLog.pdf" % (options.runMin, var))
            canvas.SetLogz(False)

            histoW1D.Draw("colz")
            ROOTUtils.atlasLabel(0.53,
                                 0.87,
                                 False,
                                 offset=0.12,
                                 isForApproval=False,
                                 customstring="Internal",
                                 energy='%2.0f' % beamEnergy,
                                 size=0.055)
            ROOTUtils.drawText(0.18, 0.87, 0.055, varDef(var, 'title', var))
            ROOTUtils.drawText(0.18,
                               0.81,
                               0.05,
                               "#mu=%2.4f RMS=%2.4f" %
                               (histoW1D.GetMean(), histoW1D.GetRMS()),
                               font=42)
            canvas.Print("Run_%d_%s1D.png" % (options.runMin, var))
            canvas.Print("Run_%d_%s1D.pdf" % (options.runMin, var))
            canvas.SetLogy(True)
            canvas.Print("Run_%d_%s1DLog.png" % (options.runMin, var))
            canvas.Print("Run_%d_%s1DLog.pdf" % (options.runMin, var))
            canvas.SetLogy(False)