ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
DataQuality
DQUtils
python
lumi.py
Go to the documentation of this file.
1
# Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
2
3
from
DQUtils
import
fetch_iovs, process_iovs, IOVSet
4
5
class
UnknownTrigger
(RuntimeError):
6
"Raised when an unknown trigger is requested for a time interval"
7
8
LVL1_MENU =
"COOLONL_TRIGGER::/TRIGGER/LVL1/Menu"
9
10
def
get_trigger_channel
(trigger, iovrange):
11
"""
12
Returns the set of iovs for which the trigger is valid
13
"""
14
15
raise
NotImplementedError(
"Implementation incomplete"
)
16
17
# First check just the first run.
18
iovs = fetch_iovs(LVL1_MENU, runs=iovrange.since.run, what=[
"ItemName"
])
19
20
result = [i
for
i
in
iovs
if
i.ItemName == trigger]
21
if
not
result:
22
raise
UnknownTrigger
()
23
24
assert
len(result) == 1,
"This should not happen."
25
26
channel = result[0].channel
27
28
iovs = fetch_iovs(LVL1_MENU, *iovrange, channels=[channel], what=[
"ItemName"
])
29
30
return
iovs.select(ItemName = trigger)
31
32
def
compute_lumi
(lbs, lumis, iovs, exclude_iovsets=[], good_runs=None):
33
"""
34
Compute luminosity for an IOVSet iovs using lbs, lumis from fetch_lumi_inputs.
35
36
exclude_iovsets is a list of IOVSets for channels to be excluded from the
37
calculation such as not_ready, busy, etc.
38
39
good_runs is an optional set of runs to consider, such as the set of runs
40
which are OK for physics.
41
"""
42
# This is the old simple approach, which doesn't have a lot of features
43
#inputs = process_iovs(lbs, lumis, iovs)
44
#return sum((lb.EndTime - lb.StartTime)/1e9 * lumi.LBAvInstLumi
45
# #for since, until, (lb, lumi, good) in inputs
46
# #if lb and lumi and good)
47
48
inputs = process_iovs(lbs, lumis, iovs, *exclude_iovsets)
49
total_lumi = 0
50
for
since, until, states
in
inputs:
51
lb, lumi, good, excludes = states[0], states[1], states[2], states[3:]
52
53
# Skip this iov if requested info not available
54
# or if any excluded channels are present
55
if
not
lb
or
not
lumi
or
not
good
or
any(excludes):
56
continue
57
58
# Optional set of runs to consider. Reject if not in set
59
if
good_runs
and
since.run
not
in
good_runs:
60
continue
61
62
total_lumi += (lb.EndTime - lb.StartTime)/1e9 * lumi.LBAvInstLumi
63
64
return
total_lumi
65
66
def
compute_lumi_many_channels
(lbs, lumis, iovs, exclude_iovsets=[], good_runs=None):
67
"""
68
Compute luminosity per channel for an IOVSet iovs using
69
lbs, lumis from fetch_lumi_inputs.
70
71
exclude_iovsets is a list of IOVSets for channels to be excluded from the
72
calculation such as not_ready, busy, etc.
73
74
good_runs is an optional set of runs to consider, such as the set of runs
75
which are OK for physics.
76
77
Return type is a dictionary of {channel name: lumi}
78
"""
79
# Split the IOVSet by channel
80
chans, iovsets = iovs.chans_iovsets
81
result = {}
82
83
# Old method, keeping it here for now
84
#inputs = process_iovs(lbs, lumis, *iovsets)
85
#for since, until, states in inputs:
86
# #(lb, lumi), defects = states[:2], states[2:]
87
# #if not (lb and lumi and lumi.LBAvInstLumi):
88
# #continue
89
# #lumi = (lb.EndTime - lb.StartTime)/1e9 * lumi.LBAvInstLumi
90
# #for name, defect_iov in zip(chans, defects):
91
# #if defect_iov:
92
# #result[name] = result.get(name, 0) + lumi
93
94
# New approach, adding new functionality
95
num_exclude = len(exclude_iovsets)
96
full_iovsets = exclude_iovsets
97
full_iovsets.extend(iovsets)
98
inputs = process_iovs(lbs, lumis, *full_iovsets)
99
for
since, until, states
in
inputs:
100
# I find the below version conceptually cleaner
101
#(lb, lumi), excludes, defects = (states[:2], states[2:2+num_exclude],
102
# #states[2+num_exclude:])
103
(lb, lumi), defectstates = states[:2], states[2:]
104
excludes, defects = defectstates[:num_exclude], defectstates[num_exclude:]
105
106
# Skip this iov if requested info not available
107
# or if any excluded channels are present
108
#if not (lb and lumi and lumi.LBAvInstLumi):
109
if
not
lb
or
not
lumi
or
any(excludes):
110
continue
111
112
# Optional set of runs to consider. Reject if not in set
113
if
good_runs
and
since.run
not
in
good_runs:
114
continue
115
116
# Lumi for this lb
117
lumi = (lb.EndTime - lb.StartTime)/1e9 * lumi.LBAvInstLumi
118
# Loop over channels present, add lumi
119
for
name, defect_iov
in
zip(chans, defects):
120
if
defect_iov:
121
result[name] = result.get(name, 0) + lumi
122
123
return
result
124
125
def
fetch_lumi_inputs
(range_iov, tag="OflLumi-7TeV-002"):
126
"""
127
Retrieve information required to calculate the luminosity from the database
128
"""
129
lbs = fetch_iovs(
"LBLB"
, *range_iov, with_channel=
False
)
130
131
if
tag ==
"ONLINE"
:
132
lumis = fetch_iovs(
"COOLONL_TRIGGER::/TRIGGER/LUMI/OnlPrefLumi"
,
133
*range_iov,
134
channels=[0])
135
136
# Select valid
137
lumis = IOVSet(l
for
l
in
lumis
if
(l.Valid & 0xFFFF) % 10 == 0)
138
else
:
139
# Apparently this string changes from time to time...
140
lumi_folder =
"COOLOFL_TRIGGER::/TRIGGER/OFLLUMI/OflPrefLumi"
# Run-2
141
#lumi_folder = "COOLOFL_TRIGGER::/TRIGGER/OFLLUMI/LBLESTOFL" # Run-1
142
lumis = fetch_iovs(lumi_folder,
143
*range_iov,
144
tag=tag,
145
channels=[0])
146
147
148
return
lbs, lumis
python.lumi.UnknownTrigger
Definition
lumi.py:5
compute_lumi
Definition
compute_lumi.py:1
python.lumi.compute_lumi_many_channels
compute_lumi_many_channels(lbs, lumis, iovs, exclude_iovsets=[], good_runs=None)
Definition
lumi.py:66
python.lumi.fetch_lumi_inputs
fetch_lumi_inputs(range_iov, tag="OflLumi-7TeV-002")
Definition
lumi.py:125
python.lumi.get_trigger_channel
get_trigger_channel(trigger, iovrange)
Definition
lumi.py:10
Generated on
for ATLAS Offline Software by
1.17.0