Belle II Software  light-2303-iriomote
b2biiConversion.py
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 
4 
11 
12 import basf2 as b2
13 import b2bii
14 from modularAnalysis import setAnalysisConfigParams
15 import os
16 import re
17 import requests
18 from ctypes import cdll
19 
20 
21 def setupBelleDatabaseServer():
22  """
23  Sets the Belle DB server to the one recommended in /sw/belle/local/var/belle_postgres_server.
24 
25  If the user does not have the access rights to the above file, the can01 server is set by default.
26  """
27  belleDBServerFile = '/sw/belle/local/var/belle_postgres_server'
28  belleDBServer = 'can01'
29 
30  try:
31  with open(belleDBServerFile) as f:
32  belleDBServer = (f.read()).strip()
33  except IOError:
34  pass
35 
36  os.environ['PGUSER'] = 'g0db'
37  os.environ['BELLE_POSTGRES_SERVER'] = belleDBServer
38 
39 
40 def convertBelleMdstToBelleIIMdst(inputBelleMDSTFile, applySkim=True,
41  useBelleDBServer=None,
42  convertBeamParameters=True,
43  generatorLevelReconstruction=False,
44  generatorLevelMCMatching=False,
45  path=None, entrySequences=None,
46  matchType2E9oE25Threshold=-1.1,
47  enableNisKsFinder=True,
48  HadronA=True, HadronB=True,
49  enableRecTrg=False, enableEvtcls=True,
50  SmearTrack=2, enableLocalDB=True,
51  convertNbar=False):
52  """
53  Loads Belle MDST file and converts in each event the Belle MDST dataobjects to Belle II MDST
54  data objects and loads them to the StoreArray.
55 
56  Args:
57  inputBelleMDSTFile (str): Name of the file(s) to be loaded.
58  applySkim (bool): Apply skim conditions in B2BIIFixMdst.
59  useBelleDBServer (str): None to use the recommended BelleDB server.
60  convertBeamParameters (bool): Convert beam parameters or use information stored in Belle II database.
61  generatorLevelReconstruction (bool): Enables to bypass skims and corrections applied in B2BIIFixMdst.
62  generatorLevelMCMatching (bool): Enables to switch MCTruth matching to generator-level particles.
63  This is recommended for analyses with gammas in the final state.
64  path (basf2.Path): Path to add modules in.
65  entrySequences (list(str)): The number sequences (e.g. 23:42,101) defining
66  the entries which are processed for each inputFileName.
67  matchType2E9oE25Threshold (float): Clusters with a E9/E25 value above this threshold are classified as neutral
68  even if tracks are matched to their connected region (matchType == 2 in basf).
69  enableNisKsFinder (bool): Enables to convert nisKsFinder information.
70  HadronA (bool): Enables to switch on HadronA skim in B2BIIFixMdst module.
71  HadronB (bool): Enables to switch on HadronB skim in B2BIIFixMdst module.
72  enableRecTrg (bool): Enables to convert RecTrg_summary3 table.
73  enableEvtcls (bool): Enables to convert Evtcls and Evtcls_hadronic tables.
74  SmearTrack (float): Smear the MC tracks to match real data.
75  Apart from the recommended default value of 2 it can also be set to 1.
76  Details about the difference between those two options can be found
77  `here <https://belle.kek.jp/secured/wiki/doku.php?id=physics:charm:tracksmearing>`_.
78  Set to 0 to skip smearing (automatically set to 0 internally for real data).
79  enableLocalDB (bool): Enables to use local payloads.
80  convertNbar (bool): Enables conversion of anti-n0:mdst.
81  """
82 
83  # If we are on KEKCC make sure we load the correct NeuroBayes library
84  try:
85  cdll.LoadLibrary(
86  '/sw/belle/local/neurobayes/lib/libNeuroBayesCore_shared.so')
87  except BaseException:
88  pass
89 
90  if useBelleDBServer is None:
91  setupBelleDatabaseServer()
92  else:
93  os.environ['BELLE_POSTGRES_SERVER'] = useBelleDBServer
94 
95  b2.B2INFO('Belle DB server is set to: ' + os.environ['BELLE_POSTGRES_SERVER'])
96 
97  setAnalysisConfigParams({'mcMatchingVersion': 'Belle'}, path)
98 
100 
101  if enableLocalDB is True:
102  b2.conditions.metadata_providers = ["/sw/belle/b2bii/database/conditions/b2bii.sqlite"]
103  b2.conditions.payload_locations = ["/sw/belle/b2bii/database/conditions/"]
104  else:
105  b2.B2WARNING(
106  "B2BII is accessing the payloads from the conditions database.\n"
107  "The recommended procedure is to use the offline database and it is significantly\n"
108  "faster than using the global database.\n"
109  "If you need the payloads which are not included in the current offline database,\n"
110  "please contact b2bii librarian.")
111 
112  input = b2.register_module('B2BIIMdstInput')
113  if inputBelleMDSTFile is not None:
114  input.param('inputFileNames', parse_process_url(inputBelleMDSTFile))
115  if entrySequences is not None:
116  input.param('entrySequences', entrySequences)
117  # input.logging.set_log_level(LogLevel.DEBUG)
118  # input.logging.set_info(LogLevel.DEBUG, LogInfo.LEVEL | LogInfo.MESSAGE)
119  path.add_module(input)
120 
121  # we need magnetic field which is different than default.
122  # shamelessly copied from analysis/scripts/modularAnalysis.py:inputMdst
123  from ROOT import Belle2 # reduced scope of potentially-misbehaving import
124  from ROOT.Math import XYZVector
125  field = Belle2.MagneticField()
126  field.addComponent(
128  XYZVector(0, 0, 1.5 * Belle2.Unit.T)))
129  Belle2.DBStore.Instance().addConstantOverride("MagneticField", field, False)
130 
131  if (not generatorLevelReconstruction):
132  # Fix MSDT Module
133  fix = b2.register_module('B2BIIFixMdst')
134  # fix.logging.set_log_level(LogLevel.DEBUG)
135  # fix.logging.set_info(LogLevel.DEBUG, LogInfo.LEVEL | LogInfo.MESSAGE)
136  # Hadron skim settings
137  fix.param('HadronA', HadronA)
138  fix.param('HadronB', HadronB)
139  fix.param('Smear_trk', SmearTrack)
140  if (HadronA is not True and HadronB is True):
141  b2.B2WARNING(
142  'The Hadron A skim is turned off.'
143  'However, its requirements are still applied since the HadronB(J) skim, which includes them, is turned on.')
144  path.add_module(fix)
145 
146  if(applySkim):
147  emptypath = b2.create_path()
148  # discard 'bad events' marked by fixmdst
149  fix.if_value('<=0', emptypath)
150  else:
151  b2.B2INFO('applySkim is set to be False.'
152  'No bad events marked by fixmdst will be discarded.'
153  'Corrections will still be applied.')
154  else:
155  b2.B2INFO('Perform generator level reconstruction, no corrections or skims in fix_mdst will be applied.')
156  # Convert MDST Module
157  convert = b2.register_module('B2BIIConvertMdst')
158  convert.param('convertBeamParameters', convertBeamParameters)
159  if (generatorLevelMCMatching):
160  convert.param('mcMatchingMode', 'GeneratorLevel')
161  convert.param("matchType2E9oE25Threshold", matchType2E9oE25Threshold)
162  convert.param("nisKsInfo", enableNisKsFinder)
163  convert.param("RecTrg", enableRecTrg)
164  convert.param("convertEvtcls", enableEvtcls)
165  convert.param("convertNbar", convertNbar)
166  # convert.logging.set_log_level(LogLevel.DEBUG)
167  # convert.logging.set_info(LogLevel.DEBUG, LogInfo.LEVEL | LogInfo.MESSAGE)
168  path.add_module(convert)
169  if convertNbar:
170  b2.conditions.append_globaltag('BellePID')
171  path.add_module('BelleNbarMVA', particleList='anti-n0:mdst', identifier='nbarMVA')
172 
173 
174 def parse_process_url(url):
175  """
176  Handle process_url style requests.
177  If url is a list just return it without looking at it. If the url starts
178  with http(s):// return the list of files provided by that url, otherwise
179  check if a file with the name given as url exists and return this as a list
180  with one item. If not such file exists return an empty list
181 
182  >>> parse_process_url(["foo", "bar"])
183  ['foo', 'bar']
184  >>> parse_process_url("/dev/null")
185  ['/dev/null']
186  >>> parse_process_url("missing_file.mdst")
187  []
188  >>> parse_process_url("http://bweb3.cc.kek.jp/mdst.php?ex=55&rs=1&re=5&skm=HadronBorJ&dt=on_resonance&bl=caseB") \
189  # doctest: +NORMALIZE_WHITESPACE
190  ['/group/belle/bdata_b/dstprod/dat/e000055/HadronBJ/0127/on_resonance/00/HadronBJ-e000055r000003-b20090127_0910.mdst',
191  '/group/belle/bdata_b/dstprod/dat/e000055/HadronBJ/0127/on_resonance/00/HadronBJ-e000055r000004-b20090127_0910.mdst',
192  '/group/belle/bdata_b/dstprod/dat/e000055/HadronBJ/0127/on_resonance/00/HadronBJ-e000055r000005-b20090127_0910.mdst']
193 
194  Some files are missing and thus marked with "### LOST ###", make sure we don't pick them up
195 
196  >>> parse_process_url("http://bweb3.cc.kek.jp/mdst.php?ex=65&rs=1&re=30&skm=ypipi")
197  []
198 
199  If the URL cannot be found an error is raised and an empty list is returned.
200  Also for other http errors or non existing urls
201 
202  >>> parse_process_url("http://httpbin.org/status/404")
203  []
204  >>> parse_process_url("http://httpbin.org/status/500")
205  []
206  >>> parse_process_url("http://nosuchurl")
207  []
208  """
209 
210  if isinstance(url, list) or isinstance(url, tuple):
211  return url
212 
213  if not url.startswith("http://") and not url.startswith("https://"):
214  if os.path.exists(url):
215  return [url]
216  else:
217  b2.B2ERROR(
218  "Could not parse url '{0}': no such file or directory".format(url))
219  return []
220 
221  # regular expression to find process_event lines in html response
222  process_event = re.compile(br"^\s*process_event\s+(.*)\s+0$", re.MULTILINE)
223  # get the url
224  try:
225  request = requests.get(url)
226  request.raise_for_status()
227  return [e.decode("ASCII")
228  for e in process_event.findall(request.content)]
229  except (requests.ConnectionError, requests.HTTPError) as e:
230  b2.B2ERROR(
231  "Failed to connect to '{url}': {message}".format(
232  url=url, message=str(e)))
233 
234  return []
def setB2BII()
Definition: b2bii.py:21
Describe one component of the Geometry.
Magnetic field map.
Definition: MagneticField.h:32
static DBStore & Instance()
Instance of a singleton DBStore.
Definition: DBStore.cc:28