10Full Simultaneous Global and Local VXD and CDC alignment with Millepede II
12The input collections are:
13- cosmics (hlt skim) - mandatorry
14- hadron - for "low" momentum tracks from IP
15- mumu - mumu_2trk or mumu_tight - for high momentum tracks from IP
16- offip - tracks from outside IP (beam background, beam-gas)
23from prompt
import CalibrationSettings, INPUT_DATA_FILTERS
24from prompt.calibrations.caf_cdc
import settings
as cdc_calibration
25from prompt.calibrations.caf_svd_time
import settings
as svd_time_calibration
28from caf.utils
import IoV
29from caf
import strategies
33import reconstruction
as reco
34import modularAnalysis
as ana
37from random
import choice
38from random
import seed
40import millepede_calibration
as mpc
47collection_names = [
"cosmic",
"hadron",
"mumu",
"offip"]
51 "cosmic.max_processed_events_per_file": 4000,
52 "hadron.max_processed_events_per_file": 1000,
53 "mumu.max_processed_events_per_file": 5000,
54 "offip.max_processed_events_per_file": 2000,
55 "beamspot.min_pxd_hits": 0,
56 "stage1.method":
"decomposition",
57 "stage1.z_offset":
True
60quality_flags = [INPUT_DATA_FILTERS[
"Run Type"][
"physics"],
61 INPUT_DATA_FILTERS[
"Data Quality Tag"][
"Good Or Recoverable"],
62 INPUT_DATA_FILTERS[
"Magnet"][
"On"]]
65settings = CalibrationSettings(name=
"Full VXD and CDC Alignment",
66 expert_username=
"tadeas.bilka",
67 subsystem=
"alignment",
69 input_data_formats=[
"raw"],
70 input_data_names=collection_names,
72 "cosmic": [INPUT_DATA_FILTERS[
"Data Tag"][
"cosmic_calib"]] + quality_flags,
73 "mumu": [INPUT_DATA_FILTERS[
"Data Tag"][
"mumu_tight_or_highm_calib"]] + quality_flags,
74 "hadron": [INPUT_DATA_FILTERS[
"Data Tag"][
"hadron_calib"]] + quality_flags,
75 "offip": [INPUT_DATA_FILTERS[
"Data Tag"][
"offip_calib"]] + quality_flags
78 expert_config=default_config,
79 depends_on=[cdc_calibration, svd_time_calibration],
80 produced_payloads=[
"VXDAlignment",
"CDCAlignment"])
83def select_files(all_input_files, min_events, max_processed_events_per_file):
89 all_input_files : list(str)
90 List of all input file names
92 Minimum number of events to select from files
93 max_processed_events_per_file : int
94 Maximum number of events to consider per file
96 all_input_files = all_input_files[:]
100 while total_events < min_events:
103 if not all_input_files:
106 new_file_choice = choice(all_input_files)
108 all_input_files.remove(new_file_choice)
110 total_events_in_file = events_in_basf2_file(new_file_choice)
111 if not total_events_in_file:
115 events_contributed = min(total_events_in_file, max_processed_events_per_file)
117 chosen_files.append(new_file_choice)
118 total_events += events_contributed
120 basf2.B2INFO(f
"Total chosen files = {len(chosen_files)}")
121 basf2.B2INFO(f
"Total events in chosen files = {total_events}")
122 if total_events < min_events:
124 f
"There weren't enough files events selected when max_processed_events_per_file={max_processed_events_per_file}")
128def create_std_path():
130 Returns default path for collections with standard reconstruction
132 path = basf2.create_path()
133 path.add_module(
'Progress')
134 path.add_module(
'RootInput')
135 path.add_module(
'Gearbox')
136 path.add_module(
'Geometry')
137 raw.add_unpackers(path)
138 path.add_module(
'SetupGenfitExtrapolation')
139 reco.add_reconstruction(
142 skipGeometryAdding=
True,
144 path.add_module(
'DAFRecoFitter')
148def create_dimuon_validation_path():
150 Returns default path for dimuon validation collection
152 path = create_std_path()
153 ana.fillParticleList(
'mu+:validation',
'p > 1.0 and abs(dz) < 2.0 and abs(dr) < 0.5 and nTracks == 2', path=path)
154 ana.reconstructDecay(
'Upsilon(4S):validation -> mu+:validation mu-:validation',
'9.5<M<11.5', path=path)
155 vtx.treeFit(
'Upsilon(4S):validation', path=path)
158 'd0',
'z0',
'phi0',
'omega',
'tanLambda',
'pt',
159 'z0FromIP',
'd0FromIP',
'phi0FromIP',
160 'electronID',
'muonID',
161 'nVXDHits',
'nPXDHits',
'nSVDHits',
'nCDCHits',
166 ana.variablesToNtuple(
'Upsilon(4S):validation',
171 'p',
'E',
'theta',
'phi',
173 'date',
'eventTimeSeconds',
176 + variables.collections.vertex
177 + [
'daughter(0, {})'.format(var)
for var
in track_variables]
178 + [
'daughter(1, {})'.format(var)
for var
in track_variables]
179 + [
'useRestFrame(daughter(0, {}))'.format(var)
for var
in track_variables]
180 + [
'useRestFrame(daughter(1, {}))'.format(var)
for var
in track_variables]
181 + [
'useCMSFrame(daughter(0, {}))'.format(var)
for var
in track_variables]
182 + [
'useCMSFrame(daughter(1, {}))'.format(var)
for var
in track_variables]
183 + [
'V0d0(0)',
'V0d0(1)',
'V0z0(0)',
'V0z0(1)'],
184 filename=
'dimuon_ana.root',
188 path.add_module(
"TrackDQM")
189 path.add_module(
"AlignDQM")
194def create_cosmic_validation_path():
196 Returns validation path for cosmic collection
198 path = basf2.create_path()
199 path.add_module(
'Progress')
200 path.add_module(
'RootInput')
201 path.add_module(
'Gearbox')
202 path.add_module(
'Geometry')
204 raw.add_unpackers(path)
205 path.add_module(
'SetupGenfitExtrapolation')
206 reco.add_cosmics_reconstruction(
209 skipGeometryAdding=
True,
210 addClusterExpertModules=
False,
214 path.add_module(
'SetRecoTrackMomentum', automatic=
True)
215 path.add_module(
'DAFRecoFitter', pdgCodesToUseForFitting=[13])
217 ana.fillParticleList(
218 'mu+:goodForVXDCDCAlignment',
219 '[z0 <= 57. or abs(d0) >= 26.5] and abs(dz) > 0.4 and nTracks == 2',
221 path.add_module(
'SkimFilter', particleLists=[
'mu+:goodForVXDCDCAlignment']).if_false(basf2.create_path())
225 StoreTrackParErrors=
True,
226 Output=
"cosmic_ana.root")
228 path.add_module(
"TrackDQM")
229 path.add_module(
"AlignDQM")
234def create_cosmics_path():
236 Returns default path for cosmic collection
238 path = basf2.create_path()
239 path.add_module(
'Progress')
240 path.add_module(
'RootInput')
241 path.add_module(
'Gearbox')
242 path.add_module(
'Geometry')
244 raw.add_unpackers(path)
245 path.add_module(
'SetupGenfitExtrapolation')
246 reco.add_cosmics_reconstruction(
249 skipGeometryAdding=
True,
250 addClusterExpertModules=
False,
254 path.add_module(
'SetRecoTrackMomentum', automatic=
True)
255 path.add_module(
'DAFRecoFitter', pdgCodesToUseForFitting=[13])
257 ana.fillParticleList(
258 'mu+:goodForVXDCDCAlignment',
259 '[z0 <= 57. or abs(d0) >= 26.5] and abs(dz) > 0.4 and nTracks == 1',
261 path.add_module(
'SkimFilter', particleLists=[
'mu+:goodForVXDCDCAlignment']).if_false(basf2.create_path())
266def make_mumu_collection(
269 muon_cut='p > 1.0 and abs(dz) < 2.0
and dr < 0.5
and nTracks==2
',
270 dimuon_cut='9.5 < M and M < 11.',
273 Di-muons with vertex+beam constraint collection
280 List of input data files
282 Cut string to select daughter muons
284 Cut string to apply for reconstructed di-muon decay
286 Process only 'prescale' fraction of events
288 path = basf2.create_path()
289 path.add_module(
'Progress')
290 path.add_module(
'RootInput')
292 path.add_module(
'Prescale', prescale=prescale).if_false(basf2.Path(), basf2.AfterConditionPath.END)
294 path.add_module(
'Gearbox')
295 path.add_module(
'Geometry')
297 raw.add_unpackers(path)
299 reco.add_reconstruction(path, pruneTracks=
False)
301 path.add_module(
'DAFRecoFitter', pdgCodesToUseForFitting=[13])
303 ana.fillParticleList(f
"mu+:{name}", muon_cut, path=path)
304 ana.reconstructDecay(f
"Upsilon(4S):{name} -> mu+:{name} mu-:{name}", dimuon_cut, path=path)
306 vtx.raveFit(f
"Upsilon(4S):{name}", 0.001, daughtersUpdate=
True, silence_warning=
True, path=path, constraint=
"ipprofile")
312 primaryVertices=[f
"Upsilon(4S):{name}"])
315def create_validation(files, cfg, name='VXDCDCalignment_validation'):
317 Returns configured (original) validation stage alignment
322 Dictionary with all input files by category (name)
324 Expert config dictionary
326 mumu = select_files(files[
"mumu"], 0.2e6, cfg[
"mumu.max_processed_events_per_file"])
327 cosmic = select_files(files[
"cosmic"], 1e6, cfg[
"cosmic.max_processed_events_per_file"])
331 dbobjects=[
'VXDAlignment',
'CDCAlignment'],
333 mpc.make_collection(
"cosmic", path=create_cosmic_validation_path(), tracks=[
"RecoTracks"]),
334 mpc.make_collection(
"mumu", path=create_dimuon_validation_path(), tracks=[
"RecoTracks"])
337 files=dict(mumu=mumu, cosmic=cosmic),
345 "method diagonalization 3 0.1",
349 params=dict(minPValue=0.00001, externalIterations=0, granularity=
"run"),
352 cal.max_iterations = 0
353 cal.save_payloads =
False
358def create_prompt(files, cfg, name='VXDCDCalignment_prompt'):
360 Returns configured (original) prompt stage alignment
365 Dictionary with all input files by category (name)
367 Expert config dictionary
369 mumu = select_files(files[
"mumu"], 0.2e6, cfg[
"mumu.max_processed_events_per_file"])
370 cosmic = select_files(files[
"cosmic"], 1e6, cfg[
"cosmic.max_processed_events_per_file"])
371 hadron = select_files(files[
"hadron"], 0.5e5, cfg[
"hadron.max_processed_events_per_file"])
372 offip = select_files(files[
"offip"], 0.2e6, cfg[
"offip.max_processed_events_per_file"])
376 dbobjects=[
'VXDAlignment',
'CDCAlignment'],
378 mpc.make_collection(
"cosmic", path=create_cosmics_path(), tracks=[
"RecoTracks"]),
379 mpc.make_collection(
"hadron", path=create_std_path(), tracks=[
"RecoTracks"]),
380 mpc.make_collection(
"mumu", path=create_std_path(), tracks=[
"RecoTracks"]),
381 mpc.make_collection(
"offip", path=create_std_path(), tracks=[
"RecoTracks"])
384 files=dict(mumu=mumu, cosmic=cosmic, hadron=hadron, offip=offip),
392 "method diagonalization 3 0.1",
396 params=dict(minPValue=0.00001, externalIterations=0, granularity=
"run"),
399 cal.max_iterations = 5
404def create_beamspot(files, cfg, name='VXDCDCalignment_beamspot'):
406 Returns configured beamspot calibration
411 Dictionary with all input files by category (name)
413 Expert config dictionary
416 mumu = select_files(files[
"mumu"], 10e6, cfg[
"mumu.max_processed_events_per_file"])
421 from ROOT.Belle2
import BeamSpotAlgorithm
422 from basf2
import create_path, register_module
427 from caf.framework
import Calibration, Collection
428 from caf.strategies
import SingleIOV
433 path.add_module(
'Progress')
434 path.add_module(
'RootInput')
435 path.add_module(
'Gearbox')
436 path.add_module(
'Geometry')
437 raw.add_unpackers(path)
438 path.add_module(
'SetupGenfitExtrapolation')
439 reco.add_reconstruction(path, skipGeometryAdding=
True)
441 muSelection =
'[p>1.0]'
442 muSelection +=
' and abs(dz)<2.0 and abs(dr)<0.5'
443 muSelection += f
' and nPXDHits >= {cfg["beamspot.min_pxd_hits"]} and nSVDHits >= 8 and nCDCHits >= 20'
444 ana.fillParticleList(
'mu+:BS', muSelection, path=path)
445 ana.reconstructDecay(
'Upsilon(4S):BS -> mu+:BS mu-:BS',
'9.5<M<11.5', path=path)
447 collector_bs = register_module(
'BeamSpotCollector', Y4SPListName=
'Upsilon(4S):BS')
448 algorithm_bs = BeamSpotAlgorithm()
452 collection_bs =
Collection(collector=collector_bs,
454 pre_collector_path=path)
456 calibration_bs = Calibration(name, algorithms=algorithm_bs)
457 calibration_bs.add_collection(
"mumu", collection_bs)
459 calibration_bs.strategies = SingleIOV
461 return calibration_bs
464def create_stage1(files, cfg, name='VXDCDCalignment_stage1'):
466 Returns configured stage1 alignment (full constant alignment with wires, beamspot fixed)
471 Dictionary with all input files by category (name)
473 Expert config dictionary
476 mumu = select_files(files[
"mumu"], 1.5e6, cfg[
"mumu.max_processed_events_per_file"])
477 cosmic = select_files(files[
"cosmic"], 0.7e6, cfg[
"cosmic.max_processed_events_per_file"])
478 hadron_and_offip = select_files(files[
"hadron"] + files[
"offip"], int(4.0e6 / 10.), cfg[
"hadron.max_processed_events_per_file"])
482 dbobjects=[
'VXDAlignment',
'CDCAlignment',
'BeamSpot'],
484 mpc.make_collection(
"cosmic", path=create_cosmics_path(), tracks=[
"RecoTracks"]),
485 mpc.make_collection(
"hadron", path=create_std_path(), tracks=[
"RecoTracks"]),
486 make_mumu_collection(name=
"mumu")
489 files=dict(mumu=mumu, cosmic=cosmic, hadron=hadron_and_offip),
499 f
"method {cfg['stage1.method']} 6 0.001",
502 params=dict(minPValue=0.00001, externalIterations=0, granularity=
"run"),
506 std_components = ROOT.vector(
'string')()
507 for component
in [
'VXDAlignment',
'CDCAlignment']:
508 std_components.push_back(component)
509 cal.algorithms[0].algorithm.setComponents(std_components)
511 cal.max_iterations = 0
516def create_stage2(files, cfg, name='VXDCDCalignment_stage2'):
518 Returns configured stage2 alignment (run-dependent alignment)
523 Dictionary with all input files by category (name)
525 Expert config dictionary
527 mumu = select_files(files[
"mumu"], 10e6, cfg[
"mumu.max_processed_events_per_file"])
528 cosmic = select_files(files[
"cosmic"], 2e6, cfg[
"cosmic.max_processed_events_per_file"])
532 dbobjects=[
'VXDAlignment',
'CDCAlignment',
'BeamSpot'],
534 mpc.make_collection(
"cosmic", path=create_cosmics_path(), tracks=[
"RecoTracks"]),
535 make_mumu_collection(name=
"mumu")],
537 files=dict(mumu=mumu, cosmic=cosmic),
544 commands=[
"method inversion 6 0.001",
"entries 1000",
"threads 10 10"],
545 params=dict(minPValue=0.00001, externalIterations=0, granularity=
"run"),
549 std_components = ROOT.vector(
'string')()
550 for component
in [
'VXDAlignment',
'CDCAlignment']:
551 std_components.push_back(component)
552 cal.algorithms[0].algorithm.setComponents(std_components)
555 cal.max_iterations = 0
565def get_calibrations(input_data, **kwargs):
567 Required function called by b2caf-prompt-run.
568 Returns full configured 4-stage final alignment for prompt
573 cfg = kwargs[
'expert_config']
576 for colname
in collection_names:
577 file_to_iov = input_data[colname]
578 input_files = list(file_to_iov.keys())
579 files[colname] = input_files
581 prompt = create_prompt(files, cfg)
582 beamspot = create_beamspot(files, cfg)
583 stage1 = create_stage1(files, cfg)
584 stage2 = create_stage2(files, cfg)
587 validation = create_validation(files, cfg)
589 requested_iov = kwargs.get(
"requested_iov",
None)
590 output_iov = IoV(requested_iov.exp_low, requested_iov.run_low, -1, -1)
592 for cal
in [prompt, beamspot, stage1, stage2, validation]:
593 for colname
in collection_names:
594 if colname
not in cal.collections.keys():
596 max_processed_events_per_file = cfg[f
'{colname}.max_processed_events_per_file']
597 basf2.set_module_parameters(
598 cal.collections[colname].pre_collector_path,
600 entrySequences=[f
'0:{max_processed_events_per_file}'], branchNames=HLT_INPUT_OBJECTS)
602 for algorithm
in cal.algorithms:
603 algorithm.params = {
"apply_iov": output_iov}
606 for cal
in [prompt, stage1, stage2]:
608 fix_mille_paths_for_algo(cal.algorithms[0])
610 beamspot.depends_on(prompt)
611 stage1.depends_on(beamspot)
612 stage2.depends_on(stage1)
614 validation.depends_on(stage2)
618 beamspot.save_payloads =
False
620 if cfg[
"only_prompt"]:
623 return [prompt, beamspot, stage1, stage2, validation]
626if __name__ ==
'__main__':
627 get_calibrations(dict(cosmic=dict(), mumu=dict(), hadron=dict(), offip=dict()),
628 requested_iov=IoV(0, 0, -1, -1), expert_config=default_config)
make_collection(name, files=None, path=None, **argk)
vxd_sensors(layers=None, rigid=True, surface=True, surface2=True, surface3=True, surface4=True, parameters=None)