ATLAS Offline Software
Loading...
Searching...
No Matches
BeamSpotUpdate.py
Go to the documentation of this file.
1#!/usr/bin/env python
2#
3# Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
4
5"""
6Module to test beamspot updates using a local sqlite file. Two steps are necessary:
7
81) Create a modified bytestream file that contains the correct COOL update information
9 in the CTP fragment. To do this simply run this script with a RAW file and it will
10 write a modified file into the current directory with beamspot updates on LBs as
11 specified in Config.lb_updateBeamspot.
12
132) Configure a job with the BeamSpotWriteAlg in the topSequence. This algorithm will
14 write a new beamspot into the sqlite file one LB before the actual update is
15 triggered via the CTP fragment. See TrigP1Test/python/BeamSpotReader.py
16 for an example.
17"""
18
19import os
20import sys
21import logging
22import eformat
23from TrigByteStreamTools import trigbs_modifyEvent
24from TrigByteStreamTools import CTPfragment
25from AthenaPython import PyAthena
26
27class Config:
28 """Configuration options for this module"""
29 lb_updateBeamspot = {3:(4,4), # LB : (LB of beamspot update, status)
30 4:(5,7),
31 8:(9,7)
32 }
33
34trigbs_modifyEvent.Config.eventsPerLB = 5
35folderList = [] # list of COOL folder updates
36log = logging.getLogger(__name__)
37
39 """Algorithm to write a new Beamspot to COOL (sqlite file) for given LBs"""
40
41 def __init__(self, name='BeamSpotWriteAlg', **kwargs):
42 super(BeamSpotWriteAlg, self).__init__(name, **kwargs)
43 setup()
44 return
45
46 def execute(self):
47 if self.getContext() is None:
48 self.log.info('No EventContext available')
49 return PyAthena.StatusCode.Success
50
51 # Write beamspot to sqlite one LB before the update appears in the
52 # CTP fragmment. Beamspot position derived from LB number.
53 run = self.getContext().eventID().run_number()
54 lb = self.getContext().eventID().lumi_block() + 1
55 if lb in Config.lb_updateBeamspot:
56 l, status = Config.lb_updateBeamspot.pop(lb)
57 setBeamSpot(run, l, l/100.0, 1+l/100.0, -4-l/10.0, status)
58
59 return PyAthena.StatusCode.Success
60
61
62def setBeamSpot(run,lb,x,y,z,
63 status=7,
64 dbname='sqlite://;schema=beampos.db;dbname=CONDBR2',
65 tag='IndetBeamposOnl-HLT-UPD1-001-00'):
66
67 log.info('============================= Creating new beamspot in COOL ===================================')
68 log.info('run=%d, lb=%d, x=%f, y=%f, z=%f', run, lb, x, y, z)
69 sys.stdout.flush()
70 os.system("beamSpotOnl_set.py --output=sqlite:beampos.db --run=%d --lbn=%d %d %f %f %f" % (run,lb,status,x,y,z))
71 if log.level<=logging.DEBUG:
72 log.info('Current content of beampos.db sqlite file:')
73 os.system("AtlCoolConsole.py 'sqlite://;schema=beampos.db;dbname=CONDBR2' <<< 'more Indet/Onl/Beampos'")
74 log.info('===============================================================================================')
75 sys.stdout.flush()
76
77
78def addFolderUpdate(event):
79 """Add COOL folder update to event"""
80
81 ctp_robs = [rob for rob in event if rob.source_id().subdetector_id()==eformat.helper.SubDetector.TDAQ_CTP]
82
83 if len(ctp_robs)==0:
84 log.error("Cannot find CTP ROB in event")
85 return event
86
87 # Copy event except CTP ROBs
88 new_event = eformat.write.FullEventFragment()
89 new_event.copy_header(event)
90 for r in event:
91 if r.source_id().subdetector_id() != eformat.helper.SubDetector.TDAQ_CTP:
92 new_event.append(eformat.write.ROBFragment(r))
93
94 # Set the CTP extra payload
95 for rob in ctp_robs:
96 x = CTPfragment.ExtraPayload() # start from empty payload object
97 for f in folderList: x.updateFolder(f)
98 new_ctp_rob = CTPfragment.setHltExtraPayloadWords(rob, [d for d in x.serialize()])
99 new_event.append(eformat.write.ROBFragment(new_ctp_rob))
100
101 return new_event
102
103
104def modify(event):
105 event = eformat.write.FullEventFragment(event)
106
107 # Modify LB and HLT counter in CTP fragment
108 newevt = trigbs_modifyEvent.modify(event)
109 lb = newevt.lumi_block()
110
111 # Write conditions update into CTP fragment
112 if lb in Config.lb_updateBeamspot:
113 lb_for_update,status = Config.lb_updateBeamspot.pop(lb)
114
115 fe = CTPfragment.FolderEntry()
116 fe.folderIndex = 0 # /Indet/Onl/Beampos
117 fe.lumiBlock = lb_for_update
118 folderList.append(fe)
119 log.info('Added COOL folder update to event: folderIndex=%d, LB=%d', fe.folderIndex,fe.lumiBlock)
120
121 return addFolderUpdate(newevt).readonly()
122
123
124def setup():
125 """Initial setup"""
126
127 log.info('Will perform beamspot udpate on these LBs (LB,status): %s', sorted(Config.lb_updateBeamspot.values()))
128
129 # Delete any previous sqlite file
130 try:
131 os.remove('beampos.db')
132 except OSError:
133 pass
134
135 # Create an open-ended IOV with a default beamspot
136 setBeamSpot(1,0,0.06,1.06,-4.6,4)
137
138
139def run(flags):
140 """CA cfg function to be used from athenaHLT"""
141
142 from AthenaCommon.Constants import DEBUG
143 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
144 from AthenaConfiguration.ComponentFactory import CompFactory
145 from IOVDbSvc.IOVDbSvcConfig import addFolders
146
147 from pathlib import Path
148
149 flags.lock()
150 cfg = ComponentAccumulator()
151
152 # addFolders requires at least an empty sqlite file
153 Path('beampos.db').touch()
154
155 # These folders are filled in Testing/condStopStart.trans
156 cfg.merge( addFolders(flags, '/Indet/Onl/Beampos <key>/Indet/Beampos</key>',
157 detDb='beampos.db',
158 tag='IndetBeamposOnl-HLT-UPD1-001-00',
159 className='AthenaAttributeList',
160 extensible=True) )
161
162 cfg.addEventAlgo( BeamSpotWriteAlg() )
163 cfg.addEventAlgo( CompFactory.InDet.InDetBeamSpotReader(VxContainer = "") )
164 cfg.addCondAlgo( CompFactory.BeamSpotCondAlg(OutputLevel = DEBUG) )
165
166 return cfg
167
168
169# For standalone running and writing a new output file
170if __name__ == '__main__':
171 import argparse
172 from eformat import EventStorage
173
174 parser = argparse.ArgumentParser(description=__doc__)
175 parser.add_argument('file', metavar='FILE', nargs=1, help='input file')
176 parser.add_argument('-n', '--events', type=int, default=-1, help='number of events to process')
177 parser.add_argument('-o', '--output', type=str, help='core output file name')
178
179 args = parser.parse_args()
180 dr = EventStorage.pickDataReader(args.file[0])
181 output = eformat.ostream(core_name = args.output or dr.fileNameCore(),
182 run_number = dr.runNumber(),
183 trigger_type = dr.triggerType(),
184 detector_mask = dr.detectorMask(),
185 beam_type = dr.beamType(),
186 beam_energy = dr.beamEnergy(),
187 meta_data_strings=dr.freeMetaDataStrings(),
188 compression=dr.compression())
189
190 i = 0
191 for event in eformat.istream(args.file[0]):
192 i += 1
193 if args.events>0 and i>args.events:
194 break
195 newevt = modify(event)
196 output.write(newevt)
197
198 del output # explicitly close file (ADHI-4985)
virtual StatusCode execute() override
__init__(self, name='BeamSpotWriteAlg', **kwargs)
setBeamSpot(run, lb, x, y, z, status=7, dbname='sqlite://;schema=beampos.db;dbname=CONDBR2', tag='IndetBeamposOnl-HLT-UPD1-001-00')
Definition run.py:1