5 Full Simultaneous Global and Local VXD and CDC alignment with Millepede II
7 The input collections are:
8 - cosmics (hlt skim) - mandatorry
9 - hadron - for "low" momentum tracks from IP
10 - mumu - mumu_2trk or mumu_tight - for high momentum tracks from IP
11 - offip - tracks from outside IP (beam background, beam-gas)
18 from prompt
import CalibrationSettings, INPUT_DATA_FILTERS
19 from prompt.calibrations.caf_cdc
import settings
as cdc_calibration
21 from caf.utils
import IoV
22 from caf
import strategies
26 import reconstruction
as reco
27 import modularAnalysis
as ana
30 from random
import choice
31 from random
import seed
33 import millepede_calibration
as mpc
38 collection_names = [
"cosmic",
"hadron",
"mumu",
"offip"]
41 "cosmic.max_processed_events_per_file": 4000,
42 "hadron.max_processed_events_per_file": 1000,
43 "mumu.max_processed_events_per_file": 5000,
44 "offip.max_processed_events_per_file": 2000,
45 "stage1.method":
"fullLAPACK"
48 quality_flags = [INPUT_DATA_FILTERS[
"Run Type"][
"physics"],
49 INPUT_DATA_FILTERS[
"Data Quality Tag"][
"Good Or Recoverable"],
50 INPUT_DATA_FILTERS[
"Magnet"][
"On"]]
53 settings = CalibrationSettings(name=
"Full VXD and CDC Alignment",
54 expert_username=
"bilkat",
56 input_data_formats=[
"raw"],
57 input_data_names=collection_names,
59 "cosmic": [INPUT_DATA_FILTERS[
"Data Tag"][
"cosmic_calib"]] + quality_flags,
60 "mumu": [INPUT_DATA_FILTERS[
"Data Tag"][
"mumutight_calib"]] + quality_flags,
61 "hadron": [INPUT_DATA_FILTERS[
"Data Tag"][
"hadron_calib"]] + quality_flags,
62 "offip": [INPUT_DATA_FILTERS[
"Data Tag"][
"offip_calib"]] + quality_flags
65 expert_config=default_config,
66 depends_on=[cdc_calibration])
69 def select_files(all_input_files, min_events, max_processed_events_per_file):
75 all_input_files : list(str)
76 List of all input file names
78 Minimum number of events to select from files
79 max_processed_events_per_file : int
80 Maximum number of events to consider per file
82 all_input_files = all_input_files[:]
86 while total_events < min_events:
89 if not all_input_files:
92 new_file_choice = choice(all_input_files)
94 all_input_files.remove(new_file_choice)
96 total_events_in_file = events_in_basf2_file(new_file_choice)
97 if not total_events_in_file:
101 events_contributed = min(total_events_in_file, max_processed_events_per_file)
103 chosen_files.append(new_file_choice)
104 total_events += events_contributed
106 basf2.B2INFO(f
"Total chosen files = {len(chosen_files)}")
107 basf2.B2INFO(f
"Total events in chosen files = {total_events}")
108 if total_events < min_events:
110 f
"There weren't enough files events selected when max_processed_events_per_file={max_processed_events_per_file}")
114 def create_std_path():
116 Returns default path for collections with standard reconstruction
118 path = basf2.create_path()
119 path.add_module(
'Progress')
120 path.add_module(
'RootInput')
121 path.add_module(
'Gearbox')
122 path.add_module(
'Geometry')
123 raw.add_unpackers(path)
124 path.add_module(
'SetupGenfitExtrapolation')
125 reco.add_reconstruction(
128 skipGeometryAdding=
True,
130 path.add_module(
'DAFRecoFitter')
134 def create_cosmics_path():
136 Returns default path for cosmic collection
138 path = basf2.create_path()
139 path.add_module(
'Progress')
140 path.add_module(
'RootInput')
141 path.add_module(
'Gearbox')
142 path.add_module(
'Geometry')
144 raw.add_unpackers(path)
145 path.add_module(
'SetupGenfitExtrapolation')
146 reco.add_cosmics_reconstruction(
149 skipGeometryAdding=
True,
150 addClusterExpertModules=
False,
154 path.add_module(
'SetRecoTrackMomentum', automatic=
True)
155 path.add_module(
'DAFRecoFitter', pdgCodesToUseForFitting=[13])
157 ana.fillParticleList(
158 'mu+:goodForVXDCDCAlignment',
159 '[z0 <= 57. or abs(d0) >= 26.5] and abs(dz) > 0.4 and nTracks == 1',
161 path.add_module(
'SkimFilter', particleLists=[
'mu+:goodForVXDCDCAlignment']).if_false(basf2.create_path())
166 def make_mumu_collection(
169 muon_cut='p > 1.0 and abs(dz) < 2.0
and dr < 0.5
and nTracks==2
', dimuon_cut='9.5 < M and M < 11.',
172 Di-muons with vertex+beam constraint collection
179 List of input data files
181 Cut string to select daughter muons
183 Cut string to apply for reconstructed di-muon decay
185 Process only 'prescale' fraction of events
187 path = basf2.create_path()
188 path.add_module(
'Progress')
189 path.add_module(
'RootInput')
191 path.add_module(
'Prescale', prescale=prescale).if_false(basf2.Path(), basf2.AfterConditionPath.END)
193 path.add_module(
'Gearbox')
194 path.add_module(
'Geometry')
196 raw.add_unpackers(path)
198 reco.add_reconstruction(path, pruneTracks=
False)
200 path.add_module(
'DAFRecoFitter', pdgCodesToUseForFitting=[13])
202 ana.fillParticleList(f
"mu+:{name}", muon_cut, path=path)
203 ana.reconstructDecay(f
"Upsilon(4S):{name} -> mu+:{name} mu-:{name}", dimuon_cut, path=path)
205 vtx.raveFit(f
"Upsilon(4S):{name}", 0.001, daughtersUpdate=
True, silence_warning=
True, path=path, constraint=
"ipprofile")
211 primaryVertices=[f
"Upsilon(4S):{name}"])
214 def create_prompt(files, cfg):
216 Returns configured (original) prompt stage alignment
221 Dictionary with all input files by category (name)
223 Expert config dictionary
225 mumu = select_files(files[
"mumu"], 0.2e6, cfg[
"mumu.max_processed_events_per_file"])
226 cosmic = select_files(files[
"cosmic"], 1e6, cfg[
"cosmic.max_processed_events_per_file"])
227 hadron = select_files(files[
"hadron"], 0.5e5, cfg[
"hadron.max_processed_events_per_file"])
228 offip = select_files(files[
"offip"], 0.2e6, cfg[
"offip.max_processed_events_per_file"])
231 name=
'VXDCDCalignment_prompt',
232 dbobjects=[
'VXDAlignment',
'CDCAlignment'],
234 mpc.make_collection(
"cosmic", path=create_cosmics_path(), tracks=[
"RecoTracks"]),
235 mpc.make_collection(
"hadron", path=create_std_path(), tracks=[
"RecoTracks"]),
236 mpc.make_collection(
"mumu", path=create_std_path(), tracks=[
"RecoTracks"]),
237 mpc.make_collection(
"offip", path=create_std_path(), tracks=[
"RecoTracks"])
240 files=dict(mumu=mumu, cosmic=cosmic, hadron=hadron, offip=offip),
248 "method diagonalization 3 0.1",
251 params=dict(minPValue=0.00001, externalIterations=0, granularity=
"run"),
254 cal.max_iterations = 5
259 def create_beamspot(files, cfg):
261 Returns configured beamspot calibration
266 Dictionary with all input files by category (name)
268 Expert config dictionary
276 from ROOT.Belle2
import BeamSpotAlgorithm
277 from basf2
import create_path, register_module
282 from caf.framework
import Calibration, Collection
283 from caf.strategies
import SingleIOV
288 path.add_module(
'Progress')
289 path.add_module(
'RootInput')
290 path.add_module(
'Gearbox')
291 path.add_module(
'Geometry')
292 raw.add_unpackers(path)
293 path.add_module(
'SetupGenfitExtrapolation')
294 reco.add_reconstruction(path, skipGeometryAdding=
True)
296 muSelection =
'[p>1.0]'
297 muSelection +=
' and abs(dz)<2.0 and abs(dr)<0.5'
298 muSelection +=
' and nPXDHits >=1 and nSVDHits >= 8 and nCDCHits >= 20'
299 ana.fillParticleList(
'mu+:BS', muSelection, path=path)
300 ana.reconstructDecay(
'Upsilon(4S):BS -> mu+:BS mu-:BS',
'9.5<M<11.5', path=path)
302 collector_bs = register_module(
'BeamSpotCollector', Y4SPListName=
'Upsilon(4S):BS')
303 algorithm_bs = BeamSpotAlgorithm()
307 collection_bs =
Collection(collector=collector_bs,
309 pre_collector_path=path)
311 calibration_bs =
Calibration(
'VXDCDCalignment_beamspot', algorithms=algorithm_bs)
312 calibration_bs.add_collection(
"mumu", collection_bs)
314 calibration_bs.strategies = SingleIOV
316 return calibration_bs
319 def create_stage1(files, cfg):
321 Returns configured stage1 alignment (full constant alignment with wires, beamspot fixed)
326 Dictionary with all input files by category (name)
328 Expert config dictionary
331 mumu = select_files(files[
"mumu"], 1.5e6, cfg[
"mumu.max_processed_events_per_file"])
332 cosmic = select_files(files[
"cosmic"], 0.7e6, cfg[
"cosmic.max_processed_events_per_file"])
333 hadron_and_offip = select_files(files[
"hadron"] + files[
"offip"], int(4.0e6 / 10.), cfg[
"hadron.max_processed_events_per_file"])
336 name=
'VXDCDCalignment_stage1',
337 dbobjects=[
'VXDAlignment',
'CDCAlignment',
'BeamSpot'],
339 mpc.make_collection(
"cosmic", path=create_cosmics_path(), tracks=[
"RecoTracks"]),
340 mpc.make_collection(
"hadron", path=create_std_path(), tracks=[
"RecoTracks"]),
341 make_mumu_collection(name=
"mumu")
344 files=dict(mumu=mumu, cosmic=cosmic, hadron=hadron_and_offip),
354 f
"method {cfg['stage1.method']} 6 0.001",
357 params=dict(minPValue=0.00001, externalIterations=0, granularity=
"run"),
361 std_components = ROOT.vector(
'string')()
362 for component
in [
'VXDAlignment',
'CDCAlignment']:
363 std_components.push_back(component)
364 cal.algorithms[0].algorithm.setComponents(std_components)
366 cal.max_iterations = 0
371 def create_stage2(files, cfg):
373 Returns configured stage2 alignment (run-dependent alignment)
378 Dictionary with all input files by category (name)
380 Expert config dictionary
382 mumu = select_files(files[
"mumu"], 10e6, cfg[
"mumu.max_processed_events_per_file"])
383 cosmic = select_files(files[
"cosmic"], 2e6, cfg[
"cosmic.max_processed_events_per_file"])
386 name=
'VXDCDCalignment_stage2',
387 dbobjects=[
'VXDAlignment',
'CDCAlignment',
'BeamSpot'],
389 mpc.make_collection(
"cosmic", path=create_cosmics_path(), tracks=[
"RecoTracks"]),
390 make_mumu_collection(name=
"mumu")],
392 files=dict(mumu=mumu, cosmic=cosmic),
399 commands=[
"method inversion 6 0.001",
"entries 1000",
"threads 10 10"],
400 params=dict(minPValue=0.00001, externalIterations=0, granularity=
"run"),
404 std_components = ROOT.vector(
'string')()
405 for component
in [
'VXDAlignment',
'CDCAlignment']:
406 std_components.push_back(component)
407 cal.algorithms[0].algorithm.setComponents(std_components)
410 cal.max_iterations = 0
420 def get_calibrations(input_data, **kwargs):
422 Required function called by b2caf-prompt-run.
423 Returns full configured 4-stage final alignment for prompt
428 cfg = kwargs[
'expert_config']
431 for colname
in collection_names:
432 file_to_iov = input_data[colname]
433 input_files = list(file_to_iov.keys())
434 files[colname] = input_files
436 prompt = create_prompt(files, cfg)
437 beamspot = create_beamspot(files, cfg)
438 stage1 = create_stage1(files, cfg)
439 stage2 = create_stage2(files, cfg)
441 requested_iov = kwargs.get(
"requested_iov",
None)
442 output_iov = IoV(requested_iov.exp_low, requested_iov.run_low, -1, -1)
444 for cal
in [prompt, beamspot, stage1, stage2]:
445 for colname
in collection_names:
446 if colname
not in cal.collections.keys():
448 max_processed_events_per_file = cfg[f
'{colname}.max_processed_events_per_file']
449 basf2.set_module_parameters(
450 cal.collections[colname].pre_collector_path,
452 entrySequences=[f
'0:{max_processed_events_per_file}'], branchNames=HLT_INPUT_OBJECTS)
454 for algorithm
in cal.algorithms:
455 algorithm.params = {
"apply_iov": output_iov}
458 for cal
in [prompt, stage1, stage2]:
460 fix_mille_paths_for_algo(cal.algorithms[0])
462 beamspot.depends_on(prompt)
463 stage1.depends_on(beamspot)
464 stage2.depends_on(stage1)
466 return [prompt, beamspot, stage1, stage2]
469 if __name__ ==
'__main__':
470 get_calibrations(dict(cosmic=dict(), mumu=dict(), hadron=dict(), offip=dict()),
471 requested_iov=IoV(0, 0, -1, -1), expert_config=default_config)
472 def make_collection(name, files=None, path=None, **argk)
def vxd_sensors(layers=None, rigid=True, surface=True, surface2=True, surface3=True, surface4=True, parameters=None)