10 Full Simultaneous Global and Local VXD and CDC alignment with Millepede II
12 The 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)
23 from prompt
import CalibrationSettings, INPUT_DATA_FILTERS
24 from prompt.calibrations.caf_cdc
import settings
as cdc_calibration
26 from caf.utils
import IoV
27 from caf
import strategies
31 import reconstruction
as reco
32 import modularAnalysis
as ana
35 from random
import choice
36 from random
import seed
38 import millepede_calibration
as mpc
43 collection_names = [
"cosmic",
"hadron",
"mumu",
"offip"]
46 "cosmic.max_processed_events_per_file": 4000,
47 "hadron.max_processed_events_per_file": 1000,
48 "mumu.max_processed_events_per_file": 5000,
49 "offip.max_processed_events_per_file": 2000,
50 "stage1.method":
"fullLAPACK"
53 quality_flags = [INPUT_DATA_FILTERS[
"Run Type"][
"physics"],
54 INPUT_DATA_FILTERS[
"Data Quality Tag"][
"Good Or Recoverable"],
55 INPUT_DATA_FILTERS[
"Magnet"][
"On"]]
58 settings = CalibrationSettings(name=
"Full VXD and CDC Alignment",
59 expert_username=
"bilkat",
61 input_data_formats=[
"raw"],
62 input_data_names=collection_names,
64 "cosmic": [INPUT_DATA_FILTERS[
"Data Tag"][
"cosmic_calib"]] + quality_flags,
65 "mumu": [INPUT_DATA_FILTERS[
"Data Tag"][
"mumu_tight_or_highm_calib"]] + quality_flags,
66 "hadron": [INPUT_DATA_FILTERS[
"Data Tag"][
"hadron_calib"]] + quality_flags,
67 "offip": [INPUT_DATA_FILTERS[
"Data Tag"][
"offip_calib"]] + quality_flags
70 expert_config=default_config,
71 depends_on=[cdc_calibration])
74 def select_files(all_input_files, min_events, max_processed_events_per_file):
80 all_input_files : list(str)
81 List of all input file names
83 Minimum number of events to select from files
84 max_processed_events_per_file : int
85 Maximum number of events to consider per file
87 all_input_files = all_input_files[:]
91 while total_events < min_events:
94 if not all_input_files:
97 new_file_choice = choice(all_input_files)
99 all_input_files.remove(new_file_choice)
101 total_events_in_file = events_in_basf2_file(new_file_choice)
102 if not total_events_in_file:
106 events_contributed = min(total_events_in_file, max_processed_events_per_file)
108 chosen_files.append(new_file_choice)
109 total_events += events_contributed
111 basf2.B2INFO(f
"Total chosen files = {len(chosen_files)}")
112 basf2.B2INFO(f
"Total events in chosen files = {total_events}")
113 if total_events < min_events:
115 f
"There weren't enough files events selected when max_processed_events_per_file={max_processed_events_per_file}")
119 def create_std_path():
121 Returns default path for collections with standard reconstruction
123 path = basf2.create_path()
124 path.add_module(
'Progress')
125 path.add_module(
'RootInput')
126 path.add_module(
'Gearbox')
127 path.add_module(
'Geometry')
128 raw.add_unpackers(path)
129 path.add_module(
'SetupGenfitExtrapolation')
130 reco.add_reconstruction(
133 skipGeometryAdding=
True,
135 path.add_module(
'DAFRecoFitter')
139 def create_cosmics_path():
141 Returns default path for cosmic collection
143 path = basf2.create_path()
144 path.add_module(
'Progress')
145 path.add_module(
'RootInput')
146 path.add_module(
'Gearbox')
147 path.add_module(
'Geometry')
149 raw.add_unpackers(path)
150 path.add_module(
'SetupGenfitExtrapolation')
151 reco.add_cosmics_reconstruction(
154 skipGeometryAdding=
True,
155 addClusterExpertModules=
False,
159 path.add_module(
'SetRecoTrackMomentum', automatic=
True)
160 path.add_module(
'DAFRecoFitter', pdgCodesToUseForFitting=[13])
162 ana.fillParticleList(
163 'mu+:goodForVXDCDCAlignment',
164 '[z0 <= 57. or abs(d0) >= 26.5] and abs(dz) > 0.4 and nTracks == 1',
166 path.add_module(
'SkimFilter', particleLists=[
'mu+:goodForVXDCDCAlignment']).if_false(basf2.create_path())
171 def make_mumu_collection(
174 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.',
177 Di-muons with vertex+beam constraint collection
184 List of input data files
186 Cut string to select daughter muons
188 Cut string to apply for reconstructed di-muon decay
190 Process only 'prescale' fraction of events
192 path = basf2.create_path()
193 path.add_module(
'Progress')
194 path.add_module(
'RootInput')
196 path.add_module(
'Prescale', prescale=prescale).if_false(basf2.Path(), basf2.AfterConditionPath.END)
198 path.add_module(
'Gearbox')
199 path.add_module(
'Geometry')
201 raw.add_unpackers(path)
203 reco.add_reconstruction(path, pruneTracks=
False)
205 path.add_module(
'DAFRecoFitter', pdgCodesToUseForFitting=[13])
207 ana.fillParticleList(f
"mu+:{name}", muon_cut, path=path)
208 ana.reconstructDecay(f
"Upsilon(4S):{name} -> mu+:{name} mu-:{name}", dimuon_cut, path=path)
210 vtx.raveFit(f
"Upsilon(4S):{name}", 0.001, daughtersUpdate=
True, silence_warning=
True, path=path, constraint=
"ipprofile")
216 primaryVertices=[f
"Upsilon(4S):{name}"])
219 def create_prompt(files, cfg):
221 Returns configured (original) prompt stage alignment
226 Dictionary with all input files by category (name)
228 Expert config dictionary
230 mumu = select_files(files[
"mumu"], 0.2e6, cfg[
"mumu.max_processed_events_per_file"])
231 cosmic = select_files(files[
"cosmic"], 1e6, cfg[
"cosmic.max_processed_events_per_file"])
232 hadron = select_files(files[
"hadron"], 0.5e5, cfg[
"hadron.max_processed_events_per_file"])
233 offip = select_files(files[
"offip"], 0.2e6, cfg[
"offip.max_processed_events_per_file"])
236 name=
'VXDCDCalignment_prompt',
237 dbobjects=[
'VXDAlignment',
'CDCAlignment'],
239 mpc.make_collection(
"cosmic", path=create_cosmics_path(), tracks=[
"RecoTracks"]),
240 mpc.make_collection(
"hadron", path=create_std_path(), tracks=[
"RecoTracks"]),
241 mpc.make_collection(
"mumu", path=create_std_path(), tracks=[
"RecoTracks"]),
242 mpc.make_collection(
"offip", path=create_std_path(), tracks=[
"RecoTracks"])
245 files=dict(mumu=mumu, cosmic=cosmic, hadron=hadron, offip=offip),
253 "method diagonalization 3 0.1",
256 params=dict(minPValue=0.00001, externalIterations=0, granularity=
"run"),
259 cal.max_iterations = 5
264 def create_beamspot(files, cfg):
266 Returns configured beamspot calibration
271 Dictionary with all input files by category (name)
273 Expert config dictionary
276 mumu = select_files(files[
"mumu"], 10e6, cfg[
"mumu.max_processed_events_per_file"])
281 from ROOT.Belle2
import BeamSpotAlgorithm
282 from basf2
import create_path, register_module
287 from caf.framework
import Calibration, Collection
288 from caf.strategies
import SingleIOV
293 path.add_module(
'Progress')
294 path.add_module(
'RootInput')
295 path.add_module(
'Gearbox')
296 path.add_module(
'Geometry')
297 raw.add_unpackers(path)
298 path.add_module(
'SetupGenfitExtrapolation')
299 reco.add_reconstruction(path, skipGeometryAdding=
True)
301 muSelection =
'[p>1.0]'
302 muSelection +=
' and abs(dz)<2.0 and abs(dr)<0.5'
303 muSelection +=
' and nPXDHits >=1 and nSVDHits >= 8 and nCDCHits >= 20'
304 ana.fillParticleList(
'mu+:BS', muSelection, path=path)
305 ana.reconstructDecay(
'Upsilon(4S):BS -> mu+:BS mu-:BS',
'9.5<M<11.5', path=path)
307 collector_bs = register_module(
'BeamSpotCollector', Y4SPListName=
'Upsilon(4S):BS')
308 algorithm_bs = BeamSpotAlgorithm()
312 collection_bs =
Collection(collector=collector_bs,
314 pre_collector_path=path)
316 calibration_bs =
Calibration(
'VXDCDCalignment_beamspot', algorithms=algorithm_bs)
317 calibration_bs.add_collection(
"mumu", collection_bs)
319 calibration_bs.strategies = SingleIOV
321 return calibration_bs
324 def create_stage1(files, cfg):
326 Returns configured stage1 alignment (full constant alignment with wires, beamspot fixed)
331 Dictionary with all input files by category (name)
333 Expert config dictionary
336 mumu = select_files(files[
"mumu"], 1.5e6, cfg[
"mumu.max_processed_events_per_file"])
337 cosmic = select_files(files[
"cosmic"], 0.7e6, cfg[
"cosmic.max_processed_events_per_file"])
338 hadron_and_offip = select_files(files[
"hadron"] + files[
"offip"], int(4.0e6 / 10.), cfg[
"hadron.max_processed_events_per_file"])
341 name=
'VXDCDCalignment_stage1',
342 dbobjects=[
'VXDAlignment',
'CDCAlignment',
'BeamSpot'],
344 mpc.make_collection(
"cosmic", path=create_cosmics_path(), tracks=[
"RecoTracks"]),
345 mpc.make_collection(
"hadron", path=create_std_path(), tracks=[
"RecoTracks"]),
346 make_mumu_collection(name=
"mumu")
349 files=dict(mumu=mumu, cosmic=cosmic, hadron=hadron_and_offip),
359 f
"method {cfg['stage1.method']} 6 0.001",
362 params=dict(minPValue=0.00001, externalIterations=0, granularity=
"run"),
366 std_components = ROOT.vector(
'string')()
367 for component
in [
'VXDAlignment',
'CDCAlignment']:
368 std_components.push_back(component)
369 cal.algorithms[0].algorithm.setComponents(std_components)
371 cal.max_iterations = 0
376 def create_stage2(files, cfg):
378 Returns configured stage2 alignment (run-dependent alignment)
383 Dictionary with all input files by category (name)
385 Expert config dictionary
387 mumu = select_files(files[
"mumu"], 10e6, cfg[
"mumu.max_processed_events_per_file"])
388 cosmic = select_files(files[
"cosmic"], 2e6, cfg[
"cosmic.max_processed_events_per_file"])
391 name=
'VXDCDCalignment_stage2',
392 dbobjects=[
'VXDAlignment',
'CDCAlignment',
'BeamSpot'],
394 mpc.make_collection(
"cosmic", path=create_cosmics_path(), tracks=[
"RecoTracks"]),
395 make_mumu_collection(name=
"mumu")],
397 files=dict(mumu=mumu, cosmic=cosmic),
404 commands=[
"method inversion 6 0.001",
"entries 1000",
"threads 10 10"],
405 params=dict(minPValue=0.00001, externalIterations=0, granularity=
"run"),
409 std_components = ROOT.vector(
'string')()
410 for component
in [
'VXDAlignment',
'CDCAlignment']:
411 std_components.push_back(component)
412 cal.algorithms[0].algorithm.setComponents(std_components)
415 cal.max_iterations = 0
416 cal.algorithms[0].strategy = strategies.SequentialRunByRun
425 def get_calibrations(input_data, **kwargs):
427 Required function called by b2caf-prompt-run.
428 Returns full configured 4-stage final alignment for prompt
433 cfg = kwargs[
'expert_config']
436 for colname
in collection_names:
437 file_to_iov = input_data[colname]
438 input_files = list(file_to_iov.keys())
439 files[colname] = input_files
441 prompt = create_prompt(files, cfg)
442 beamspot = create_beamspot(files, cfg)
443 stage1 = create_stage1(files, cfg)
444 stage2 = create_stage2(files, cfg)
446 requested_iov = kwargs.get(
"requested_iov",
None)
447 output_iov = IoV(requested_iov.exp_low, requested_iov.run_low, -1, -1)
449 for cal
in [prompt, beamspot, stage1, stage2]:
450 for colname
in collection_names:
451 if colname
not in cal.collections.keys():
453 max_processed_events_per_file = cfg[f
'{colname}.max_processed_events_per_file']
454 basf2.set_module_parameters(
455 cal.collections[colname].pre_collector_path,
457 entrySequences=[f
'0:{max_processed_events_per_file}'], branchNames=HLT_INPUT_OBJECTS)
459 for algorithm
in cal.algorithms:
460 algorithm.params = {
"apply_iov": output_iov}
463 for cal
in [prompt, stage1, stage2]:
465 fix_mille_paths_for_algo(cal.algorithms[0])
467 beamspot.depends_on(prompt)
468 stage1.depends_on(beamspot)
469 stage2.depends_on(stage1)
473 beamspot.save_payloads =
False
475 return [prompt, beamspot, stage1, stage2]
478 if __name__ ==
'__main__':
479 get_calibrations(dict(cosmic=dict(), mumu=dict(), hadron=dict(), offip=dict()),
480 requested_iov=IoV(0, 0, -1, -1), expert_config=default_config)
481 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)