ATLAS Offline Software
dqBeamSpot.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 # Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
4 
5 from __future__ import print_function
6 
7 
8 """
9 Calculate beamspot DQ defects automatically from result of beamspot fit and
10 produce locally sqlite file that can later be merged into HEAD. Also dump
11 results to txt file for linking to web page
12 
13 """
14 __author__ = 'Carl Gwilliam'
15 __version__ = '$Id $'
16 __usage__ = '%prog [options] nt.root [nt.root ...]'
17 
18 import sys,os
19 from math import *
21 
22 # Argument parsing
23 from optparse import OptionParser
24 parser = OptionParser(usage=__usage__, version=__version__)
25 parser.add_option('-b', '--batch', dest='batch', action='store_true', default=False, help='run in batch mode')
26 parser.add_option('-i', '--interactive', dest='interactive', action='store_true', default=False, help='interactive')
27 parser.add_option('-e', '--extend', dest='extend', action='store_true', default=False, help='extend existing SQLite file (default: delete any existing file)')
28 parser.add_option('', '--noaverage', dest='noaverage', action='store_true', default=False, help='do not write per-run average beam spot with large width')
29 parser.add_option('', '--statlist', dest='statlist', default='59', help='comma separated list of status word values to accept (must have known fitId)')
30 parser.add_option('', '--lbmin', dest='lbmin', type='int', default=None, help='Minimum LB to consider')
31 parser.add_option('', '--lbmax', dest='lbmax', type='int', default=None, help='Maximum LB to consider')
32 parser.add_option('-o', '--output', dest='output', default='dqflags.db', help='name of output COOL SQLite file for DQ (default: dqflags.db')
33 parser.add_option('-t', '--tag', dest='tag', default='nominal', help='COOL tag (default: nominal)')
34 parser.add_option('-a', '--absent', dest='absent', action='store_true', default=False, help='Write absent (as well as present) defects to the DB (default: False)')
35 
36 (options,args) = parser.parse_args()
37 if len(args) < 1:
38  parser.error('wrong number of command line arguments')
39 
40 
41 # Setup ROOT
42 if options.batch:
43  os.unsetenv('DISPLAY')
44 import ROOT
45 from InDetBeamSpotExample import ROOTUtils
46 #ROOTUtils.setStyle()
47 
48 from InDetBeamSpotExample.Utils import getRunFromName
49 
50 # Prepare list of algorithms to consider
51 statList = []
52 fitIdList = []
53 for a in options.statlist.split(','):
54  statList.append(int(a))
55  try:
56  fitIDInt = int( format( int(a), '08b')[:4], 2)
57  fitIdList.append( fitIDInt )
58  except:
59  print ('ERROR: Status word value of %i has no known fitId entry' % int(a))
60  sys.exit(1)
61 
62 # First loop over all input files to determine if an everage is available
63 # (i.e. nEntires with correct fit status > 0)
64 
65 # Set initial min and max run numbers from file names
66 #try:
67 runs = [int(getRunFromName(f)) for f in args]
68 minRun = min(runs)
69 maxRun = max(runs)
70 #except:
71 # minRun = 1E10
72 # maxRun = -1
73 nEntries = 0
74 
75 print ('\nDetermining if average beamspot parameters available')
76 for filename in args:
77  print ('\nExtracting from file ',filename,':')
78 
79  f = ROOT.TFile(filename)
80  if f.Get('BeamSpotNt'):
81  bsNt = BeamSpotNt(filename)
82  elif f.Get('Beamspot/Beamspots'):
83  bsNt = BeamSpotFinderNt(filename)
84 
85  for bs in bsNt.allData():
86 
87  # Skip fits outside of desired LB range
88  if options.lbmin and options.lbmin>bs.lbStart:
89  continue
90  if options.lbmax and options.lbmax<bs.lbEnd+1:
91  continue
92  if not bs.status in statList:
93  continue
94  #Convert status word to ints for fitStatus and fitID
95  fitStatusInt = int( format( bs.status, '08b')[-2:], 2)
96  fitIDInt = int( format( bs.status, '08b')[:4], 2)
97 
98  print ('[%i, %3i - %3i]: %5i vertices, fitStatus = %i, fitID = %i' % (bs.run,bs.lbStart,bs.lbEnd+1,bs.nEvents,fitStatusInt,fitIDInt))
99 
100  minRun = min(bs.run,minRun)
101  maxRun = max(bs.run,maxRun)
102 
103  # Skip undesired fits
104  if fitStatusInt!=3:
105  print ('*** Skipping unsuccessful fit ...\n')
106  continue
107  if not fitIDInt in fitIdList:
108  print ('*** Skipping fit with ID =',fitIDInt,'\n')
109  continue
110 
111  nEntries += 1
112  print()
113 
114  f.Close()
115 
116 # Set DQ defect to 'ID_BS_NOBEAMSPOT' if there is no average beamspot or 'ID_BS_RUNAVERAGE' if
117 # there is (i.e. at least one succesfull fit and not options.noaverage)
118 
119 from InDetBeamSpotExample.DQUtilities import IDBSDefectWriter
120 idbsDefects = IDBSDefectWriter(options.output, not options.extend)
121 
122 if nEntries>0 and not options.noaverage:
123  print ('\nInitially Setting DQ defect to ID_BS_RUNAVERAGE for runs %s ... %s with average beamspot available' %(minRun, maxRun))
124  idbsDefects.defectType('ID_BS_RUNAVERAGE')
125 else:
126  print ('\nInitially setting DQ defect to ID_BS_NOBEAMSPOT for runs %s ... %s without average beamspot available' % (minRun, maxRun))
127  idbsDefects.defectType('ID_BS_NOBEAMSPOT')
128 
129 # for protection against multiple rows with same LB range
130 good_lbs={}
131 if minRun==maxRun:
132  good_lbs[minRun]={}
133 else:
134  for i in range(minRun,maxRun):
135  good_lbs[i]={}
136 # Loop over ntuple and set LBs for which beamspot is correctly determined (i.e. no defects)
137 for filename in args:
138  print ('Copying beam spot data from',filename)
139  f = ROOT.TFile(filename)
140  if f.Get('BeamSpotNt'):
141  bsNt = BeamSpotNt(filename)
142  elif f.Get('Beamspot/Beamspots'):
143  bsNt = BeamSpotFinderNt(filename)
144 
145  for bs in bsNt.allData():
146  # Skip entries outside of desired LB range
147  if options.lbmin and options.lbmin>bs.lbStart:
148  continue
149  if options.lbmax and options.lbmax<bs.lbEnd+1:
150  continue
151 
152  if bs.status in statList and bs.lbStart not in good_lbs[bs.run]:
153  # Fill GOOD Lbs where defect is NOT present (lbEnd for DQ is exclusive)
154  idbsDefects.add(minRun, maxRun, bs.lbStart, bs.lbEnd+1)
155  good_lbs[bs.run][bs.lbStart]=1
156 
157  else:
158  print ('WARNING: Skipping entry with status word %3s, lbStart=%4d, lbEnd=%4d' % (bs.status, bs.lbStart, bs.lbEnd))
159 
160  f.Close()
161 
162 # Set defects for those LBs where beamspot is not correctly determined by inverting good LB list
163 idbsDefects.complete(minRun, maxRun)
164 idbsDefects.dump()
165 
166 # Write to sqlite db and text file
167 if options.output:
168  idbsDefects.writeDefects(nonpresent = options.absent)
169  idbsDefects.dump(options.output)
170 
171 if options.lbmin or options.lbmax:
172  print ('\n**** WARNING: ONLY CONSIDERED ENTRIES IN RANGE [%s,%s] ****\n' % (options.lbmin,options.lbmax))
173 
174 # Enter interactive mode if desired
175 if options.interactive:
176  os.environ['PYTHONINSPECT'] = '1'
BeamSpotData
max
#define max(a, b)
Definition: cfImp.cxx:41
vtune_athena.format
format
Definition: vtune_athena.py:14
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
python.Utils.getRunFromName
def getRunFromName(name, default='', asInt=False)
Definition: InnerDetector/InDetExample/InDetBeamSpotExample/python/Utils.py:13
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
min
#define min(a, b)
Definition: cfImp.cxx:40
dbg::print
void print(std::FILE *stream, std::format_string< Args... > fmt, Args &&... args)
Definition: SGImplSvc.cxx:70