Belle II Software  release-05-01-25
runTimeDependentVXD_CAF.py
1 from basf2 import *
2 set_log_level(LogLevel.INFO)
3 
4 import os
5 import multiprocessing
6 
7 import ROOT
8 from ROOT import Belle2
9 from ROOT.Belle2 import MillepedeAlgorithm
10 
11 from caf.framework import CAF, Calibration, CentralDatabase
12 from caf import backends
13 from caf import strategies
14 
15 import reconstruction as reco
16 
17 from generators import add_kkmc_generator
18 from simulation import add_simulation
19 from L1trigger import add_tsim
20 
21 # Generate 4 runs, with run number 4, 5, 6, 7
22 runList = [4, 5, 6, 7]
23 # all runs in experiment 0 (default final Phase3 config)
24 expList = [0, 0, 0, 0]
25 # let's have runs 5 and 7 longer and let the PXD move each 20 events below
26 evtNumList = [20, 60, 20, 40]
27 
28 # VXD iDs of the 2 PXD half shells
29 ying = Belle2.VxdID(1, 0, 0, 1)
30 yang = Belle2.VxdID(1, 0, 0, 2)
31 
32 # Their rigid body parameter IDs
33 # x,y, z shift and alpha, beta, gamma rotation
34 params = [1, 2, 3, 4, 5, 6]
35 
36 label = Belle2.GlobalLabel()
37 
38 pxd_labels = []
39 for shell in [ying, yang]:
40  for par in params:
41  label.construct(Belle2.VXDAlignment.getGlobalUniqueID(), shell.getID(), par)
42  pxd_labels.append(label.label())
43 
44 # Configure the the time dependence for calibration
45 timedep = [(pxd_labels, [(0, run, 0) for run in runList] + [(20, 5, 0), (40, 5, 0)] + [(20, 7, 0)])]
46 
47 db_components = ['VXDAlignment']
48 components = ['PXD', 'SVD', 'CDC']
49 
50 
51 def PXDHalfShellsAlignment(files, tags):
52 
53  # Set-up re-processing path
54  path = create_path()
55 
56  path.add_module('Progress')
57  # Remove all non-raw data to run the full reco again
58  # path.add_module('RootInput', branchNames=input_branches)#, entrySequences=['0:1000'])
59  path.add_module('Gearbox')
60  path.add_module('Geometry')
61  # Not needed for di-muon skim cdst or mdst, but needed to re-run reconstruction
62  # with possibly changed global tags
63  # raw.add_unpackers(path)
64  reco.add_mc_reconstruction(path, pruneTracks=False, components=components)
65  path.add_module('DAFRecoFitter')
66 
67  collector = register_module('MillepedeCollector',
68  tracks=['RecoTracks'],
69  primaryVertices=[],
70  calibrateVertex=True, components=db_components,
71  granularity='all', # time dependence needs granularity=all
72  useGblTree=False,
73  absFilePaths=True,
74  timedepConfig=timedep
75  )
76 
77  algorithm = MillepedeAlgorithm()
78  algorithm.invertSign(True)
79  algorithm.ignoreUndeterminedParams(False)
80 
81  std_components = ROOT.vector('string')()
82  for component in db_components:
83  std_components.push_back(component)
84  algorithm.setComponents(std_components)
85 
86  algorithm.steering().command('method diagonalization 3 0.1')
87  algorithm.steering().command('skipemptycons')
88  algorithm.steering().command('threads 4 4')
89  algorithm.steering().command('matiter 1')
90  algorithm.steering().command('scaleerrors 1. 1.')
91  # algorithm.steering().command('entries 10')
92  algorithm.steering().command('printcounts 1')
93  # algorithm.steering().command('histprint')
94  algorithm.steering().command('monitorresiduals')
95  algorithm.steering().command('closeandreopen')
96  algorithm.steering().command('hugecut 50.')
97  # algorithm.steering().command('chiscut 30. 6.')
98  # algorithm.steering().command('outlierdownweighting 3')
99  # algorithm.steering().command('dwfractioncut 0.1')
100  # algorithm.steering().command('presigmas 1.')
101 
102  algorithm.steering().command('Parameters')
103 
104  def fix_vxd_id(vxd_id, params=None):
105  if params is None:
106  params = [1, 2, 3, 4, 5, 6] # rigid body parameters
107  for ipar in params:
108  label = Belle2.GlobalLabel()
109  label.construct(Belle2.VXDAlignment.getGlobalUniqueID(), vxd_id.getID(), ipar)
110  algorithm.steering().command('{} 0.0 -1. ! {}'.format(str(label.label()), str(vxd_id)))
111 
112  # Halfshells
113  # fix_vxd_id(Belle2.VxdID(1, 0, 0, 1)) # ying
114  # fix_vxd_id(Belle2.VxdID(1, 0, 0, 2)) # yang
115  fix_vxd_id(Belle2.VxdID(3, 0, 0, 1)) # pat
116  fix_vxd_id(Belle2.VxdID(3, 0, 0, 2)) # mat
117 
118  ladders = [8, 12, 7, 10, 12, 16]
119  sensors = [2, 2, 2, 3, 4, 5]
120 
121  for layer in range(1, 7):
122  for ladder in range(1, ladders[layer - 1] + 1):
123  fix_vxd_id(Belle2.VxdID(layer, ladder, 0), params=[1, 2, 3, 4, 5, 6])
124  for sensor in range(1, sensors[layer - 1] + 1):
125  # sensors
126  fix_vxd_id(
127  Belle2.VxdID(
128  layer,
129  ladder,
130  sensor),
131  params=[
132  1,
133  2,
134  3,
135  4,
136  5,
137  6,
138  31,
139  32,
140  33,
141  41,
142  42,
143  43,
144  44,
145  51,
146  52,
147  53,
148  54,
149  55,
150  20])
151 
152  algorithm.setTimedepConfig(timedep)
153 
154  calibration = Calibration('PXDHalfShellsAlignment',
155  collector=collector,
156  algorithms=algorithm,
157  input_files=files,
158  pre_collector_path=path,
159  database_chain=[CentralDatabase(tag) for tag in tags],
160  output_patterns=None,
161  max_files_per_collector_job=1,
162  backend_args=None
163  )
164 
165  calibration.strategies = strategies.SingleIOV
166 
167  return calibration
168 
169 
170 def generate_test_data(filename):
171  main = create_path()
172 
173  main.add_module("EventInfoSetter", evtNumList=evtNumList, runList=runList, expList=expList)
174  # add_beamparameters(main, "Y4S")
175  main.add_module('Gearbox')
176  main.add_module('Geometry')
177 
178  add_kkmc_generator(main, 'mu-mu+')
179 
180  add_simulation(main)
181  add_tsim(main)
182 
183  main.add_module("RootOutput", outputFileName=filename)
184  main.add_module("Progress")
185 
186  process(main)
187  print(statistics)
188  return os.path.abspath(filename)
189 
190 if __name__ == "__main__":
191  input_files = [os.path.abspath(file) for file in Belle2.Environment.Instance().getInputFilesOverride()]
192 
193  if not len(input_files):
194  outfile = Belle2.Environment.Instance().getOutputFileOverride()
195  if not outfile:
196  outfile = 'TimeDepCalibration_TestData.root'
197  print("No input file provided. This will now generate test data into {} and run over it.".format(outfile))
198  print("It will take couple of minutes.")
199  print("You can set this file as input next time using -i option of basf2")
200 
201  input_files = [generate_test_data(outfile)]
202 
203  tags = conditions.default_globaltags
204  mp2_beamspot = PXDHalfShellsAlignment(input_files, tags)
205  mp2_beamspot.max_iterations = 1
206 
207  cal_fw = CAF()
208  cal_fw.add_calibration(mp2_beamspot)
209  cal_fw.backend = backends.LSF()
210 
211  # Try to guess if we are at KEKCC and change the backend to Local if not
212  if multiprocessing.cpu_count() < 10:
213  cal_fw.backend = backends.Local(1)
214 
215  cal_fw.run()
strategies.SingleIOV
Definition: strategies.py:172
Belle2::VxdID
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:43
Belle2::VXDAlignment::getGlobalUniqueID
static unsigned short getGlobalUniqueID()
Get global unique id.
Definition: VXDAlignment.h:57
generate_test_data
Definition: generate_test_data.py:1
Belle2::GlobalLabel
Class to convert to/from global labels for Millepede II to/from detector & parameter identificators.
Definition: GlobalLabel.h:51
backends.LSF
Definition: backends.py:1567
Belle2::Environment::Instance
static Environment & Instance()
Static method to get a reference to the Environment instance.
Definition: Environment.cc:31
Calibration
Definition: Calibration.py:1
backends.Local
Definition: backends.py:878