10A set of common purose translators from complex framework objects to flat dictionaries
20from ROOT
import Belle2
28Belle2.RecoTrack.getRightLeftInformation[
"Belle2::CDCHit"]
29ROOT.gSystem.Load(
"libtracking")
31formatter = TolerateMissingKeyFormatter()
36def format_crop_keys(peel_func):
37 @functools.wraps(peel_func)
38 def peel_func_formatted_keys(*args, key="{part_name}", **kwargs):
39 crops = peel_func(*args, **kwargs, key=key)
40 if key
and hasattr(crops,
'items'):
41 crops_with_formatted_keys = dict()
42 for part_name, value
in list(crops.items()):
43 formatted_key = formatter.format(key, part_name=part_name)
44 crops_with_formatted_keys[formatted_key] = value
45 return crops_with_formatted_keys
50 return peel_func_formatted_keys
56def peel_mc_particle(mc_particle, key="{part_name}"):
58 helix = getHelixFromMCParticle(mc_particle)
59 momentum = mc_particle.getMomentum()
60 vertex = mc_particle.getVertex()
61 charge = mc_particle.getCharge()
62 pdg_code = mc_particle.getPDG()
63 is_primary = bool(mc_particle.hasStatus(Belle2.MCParticle.c_PrimaryParticle))
65 decay_vertex = mc_particle.getDecayVertex()
66 number_of_daughters = mc_particle.getNDaughters()
67 status = mc_particle.getStatus()
71 d0_truth=helix.getD0(),
72 phi0_truth=helix.getPhi0() % (2.0 * math.pi),
73 omega_truth=helix.getOmega(),
74 z0_truth=helix.getZ0(),
75 tan_lambda_truth=helix.getTanLambda(),
78 pt_truth=momentum.Rho(),
79 px_truth=momentum.X(),
80 py_truth=momentum.Y(),
81 pz_truth=momentum.Z(),
86 decay_vertex_radius_truth=decay_vertex.R(),
87 decay_vertex_x_truth=decay_vertex.X(),
88 decay_vertex_y_truth=decay_vertex.Y(),
89 decay_vertex_z_truth=decay_vertex.Z(),
90 number_of_daughters_truth=number_of_daughters,
95 pdg_code_truth=pdg_code,
96 is_primary=is_primary,
107 tan_lambda_truth=nan,
118 decay_vertex_radius_truth=nan,
119 decay_vertex_x_truth=nan,
120 decay_vertex_y_truth=nan,
121 decay_vertex_z_truth=nan,
122 number_of_daughters_truth=nan,
136def peel_reco_track_hit_content(reco_track, key="{part_name}"):
139 first_pxd_layer = nan
141 first_svd_layer = nan
143 first_cdc_layer = nan
152 n_cdc_hits = reco_track.getNumberOfCDCHits()
153 n_svd_hits = reco_track.getNumberOfSVDHits()
154 n_pxd_hits = reco_track.getNumberOfPXDHits()
155 ndf = 2 * n_pxd_hits + n_svd_hits + n_cdc_hits
157 pxd_hits = [hit.getSensorID().getLayerNumber()
for hit
in getObjectList(reco_track.getPXDHitList())]
159 first_pxd_layer = min(pxd_hits)
160 last_pxd_layer = max(pxd_hits)
161 svd_hits = [hit.getSensorID().getLayerNumber()
for hit
in getObjectList(reco_track.getSVDHitList())]
163 first_svd_layer = min(svd_hits)
164 last_svd_layer = max(svd_hits)
165 cdc_hits = [hit.getICLayer()
for hit
in getObjectList(reco_track.getCDCHitList())]
167 first_cdc_layer = min(cdc_hits)
168 last_cdc_layer = max(cdc_hits)
169 for hit_info
in getObjectList(reco_track.getRelationsWith(
"RecoHitInformations")):
170 track_point = reco_track.getCreatedTrackPoint(hit_info)
172 fitted_state = track_point.getFitterInfo()
174 W = max(fitted_state.getWeights())
176 if W > 0.5
and hit_info.getTrackingDetector() == Belle2.RecoHitInformation.c_CDC:
177 layer = hit_info.getRelated(
"CDCHits").getICLayer()
178 if layer > last_fit_layer:
179 last_fit_layer = layer
181 n_pxd_hits=n_pxd_hits,
182 n_svd_hits=n_svd_hits,
183 n_cdc_hits=n_cdc_hits,
184 n_hits=n_pxd_hits + n_svd_hits + n_cdc_hits,
186 first_pxd_layer=first_pxd_layer,
187 last_pxd_layer=last_pxd_layer,
188 first_svd_layer=first_svd_layer,
189 last_svd_layer=last_svd_layer,
190 first_cdc_layer=first_cdc_layer,
191 last_cdc_layer=last_cdc_layer,
192 sum_of_weights=sum_of_weights,
193 last_fit_layer=last_fit_layer
202 first_pxd_layer=first_pxd_layer,
203 last_pxd_layer=last_pxd_layer,
204 first_svd_layer=first_svd_layer,
205 last_svd_layer=last_svd_layer,
206 first_cdc_layer=first_cdc_layer,
207 last_cdc_layer=last_cdc_layer,
208 sum_of_weights=sum_of_weights,
209 last_fit_layer=last_fit_layer
216def peel_reco_track_seed(reco_track, key="{part_name}"):
218 seed_fit_result = get_seed_track_fit_result(reco_track)
219 return peel_track_fit_result(seed_fit_result, key=
"seed_{part_name}")
222 return peel_track_fit_result(
None, key=
"seed_{part_name}")
228def peel_event_info(event_meta_data, key="{part_name}"):
230 event_number=event_meta_data.getEvent(),
231 run_number=event_meta_data.getRun(),
232 experiment_number=event_meta_data.getExperiment(),
239def peel_store_array_info(item, key="{part_name}"):
242 store_array_number=item.getArrayIndex()
246 store_array_number=float(
"nan")
253def peel_store_array_size(array_name, key="{part_name}"):
255 return {str(array_name) +
"_size": array.getEntries()
if array
else 0}
261def peel_event_level_tracking_info(event_level_tracking_info, key="{part_name}"):
262 if not event_level_tracking_info:
264 has_vxdtf2_failure_flag=
False,
265 has_svdckf_failure_flag=
False,
266 has_pxdckf_failure_flag=
False,
267 has_unspecified_trackfinding_failure=
False,
269 return dict(has_vxdtf2_failure_flag=event_level_tracking_info.hasVXDTF2AbortionFlag(),
270 has_svdckf_failure_flag=event_level_tracking_info.hasSVDCKFAbortionFlag(),
271 has_pxdckf_failure_flag=event_level_tracking_info.hasPXDCKFAbortionFlag(),
272 has_unspecified_trackfinding_failure=event_level_tracking_info.hasUnspecifiedTrackFindingFailure(),
279def peel_quality_indicators(reco_track, key="{part_name}"):
287 qi = reco_track.getQualityIndicator()
288 space_point_track_cand = reco_track.getRelated(
'SPTrackCands')
291 if not space_point_track_cand:
292 svd_track_cand = reco_track.getRelated(
'SVDRecoTracks')
293 if not svd_track_cand:
294 svd_cdc_track_cand = reco_track.getRelated(
'SVDCDCRecoTracks')
295 if svd_cdc_track_cand:
296 svd_track_cand = svd_cdc_track_cand.getRelated(
'SVDRecoTracks')
297 if not svd_track_cand:
298 temp_svd_track_cand = svd_cdc_track_cand.getRelated(
'SVDPlusCDCStandaloneRecoTracks')
299 if temp_svd_track_cand:
300 svd_track_cand = temp_svd_track_cand.getRelated(
'SVDRecoTracks')
302 space_point_track_cand = svd_track_cand.getRelated(
'SPTrackCands')
304 if space_point_track_cand:
305 svd_qi = space_point_track_cand.getQualityIndicator()
307 cdc_track_cand = reco_track.getRelated(
'CDCRecoTracks')
308 if not cdc_track_cand:
309 svd_cdc_track_cand = reco_track.getRelated(
'SVDCDCRecoTracks')
310 if svd_cdc_track_cand:
311 cdc_track_cand = svd_cdc_track_cand.getRelated(
'CDCRecoTracks')
312 if not cdc_track_cand:
313 cdc_track_cand = svd_cdc_track_cand.getRelated(
'CKFCDCRecoTracks')
314 if not cdc_track_cand:
315 temp_cdc_track_cand = svd_cdc_track_cand.getRelated(
'SVDPlusCDCStandaloneRecoTracks')
316 if temp_cdc_track_cand:
317 cdc_track_cand = temp_cdc_track_cand.getRelated(
'CDCRecoTracks')
320 cdc_qi = cdc_track_cand.getQualityIndicator()
323 quality_indicator=qi,
324 svd_quality_indicator=svd_qi,
325 cdc_qualityindicator=cdc_qi,
334def peel_trackfinder(reco_track, key="{part_name}"):
335 used_CDCTrackFinder =
False
336 used_VXDTrackFinder =
False
337 used_SVDHough =
False
338 used_SVDtoCDCCKF =
False
339 used_ECLtoCDCCKF =
False
340 used_CDCtoSVDCKF =
False
343 if reco_track.getNumberOfSVDHits() > 0:
344 info = get_reco_hit_information(reco_track, reco_track.getSVDHitList()[0])
345 svd_tf = info.getFoundByTrackFinder()
346 used_VXDTrackFinder = svd_tf == Belle2.RecoHitInformation.c_VXDTrackFinder
347 used_CDCtoSVDCKF = svd_tf == Belle2.RecoHitInformation.c_CDCtoSVDCKF
348 used_SVDHough = svd_tf == Belle2.RecoHitInformation.c_SVDHough
350 if reco_track.getNumberOfCDCHits() > 0:
351 info = get_reco_hit_information(reco_track, reco_track.getCDCHitList()[0])
352 cdc_tf = info.getFoundByTrackFinder()
353 used_CDCTrackFinder = cdc_tf == Belle2.RecoHitInformation.c_CDCTrackFinder
354 used_SVDtoCDCCKF = cdc_tf == Belle2.RecoHitInformation.c_SVDtoCDCCKF
355 used_ECLtoCDCCKF = cdc_tf == Belle2.RecoHitInformation.c_ECLtoCDCCKF
358 foundby_CDCTrackFinder=used_CDCTrackFinder,
359 foundby_VXDTrackFinder=used_VXDTrackFinder,
360 foundby_SVDHough=used_SVDHough,
361 foundby_SVDtoCDCCKF=used_SVDtoCDCCKF,
362 foundby_CDCtoSVDCKF=used_CDCtoSVDCKF,
363 foundby_ECLtoCDCCKF=used_ECLtoCDCCKF,
372def peel_fit_status(reco_track, key="{part_name}"):
390 crops[
"is_fitted"] = reco_track.wasFitSuccessful()
392 for rep
in getObjectList(reco_track.getRepresentations()):
393 was_successful = reco_track.wasFitSuccessful(rep)
394 pdg_code = rep.getPDG()
396 for crop
in crops.keys():
397 if crop.startswith(
"fit_"):
398 particle_name = crop.split(
"_")[1]
399 if abs(getattr(
Belle2.Const, particle_name).getPDGCode()) == abs(pdg_code):
400 crops[crop] = was_successful
403 crops[f
"ndf_{particle_name}"] = reco_track.getTrackFitStatus(rep).getNdf()
411def peel_track_fit_result(track_fit_result, key="{part_name}"):
414 cov6 = track_fit_result.getCovariance6()
415 mom = track_fit_result.getMomentum()
416 pos = track_fit_result.getPosition()
418 pt_estimate = mom.Rho()
420 pt_variance = np.divide(
421 mom.X() ** 2 * cov6(3, 3) + mom.Y() ** 2 * cov6(4, 4) - 2 * mom.X() * mom.Y() * cov6(3, 4),
425 pt_resolution = np.divide(pt_variance, pt_estimate)
428 has_trackFitResult=
True,
429 d0_estimate=track_fit_result.getD0(),
430 d0_variance=track_fit_result.getCov()[0],
431 phi0_estimate=track_fit_result.getPhi() % (2.0 * math.pi),
432 phi0_variance=track_fit_result.getCov()[5],
433 omega_estimate=track_fit_result.getOmega(),
434 omega_variance=track_fit_result.getCov()[9],
435 z0_estimate=track_fit_result.getZ0(),
436 z0_variance=track_fit_result.getCov()[12],
437 tan_lambda_estimate=track_fit_result.getCotTheta(),
438 tan_lambda_variance=track_fit_result.getCov()[14],
441 x_variance=cov6(0, 0),
443 y_variance=cov6(1, 1),
445 z_variance=cov6(2, 2),
447 pt_estimate=pt_estimate,
448 pt_variance=pt_variance,
449 pt_resolution=pt_resolution,
451 track_charge=track_fit_result.getChargeSign(),
455 px_variance=cov6(3, 3),
457 py_variance=cov6(4, 4),
459 pz_variance=cov6(5, 5),
461 p_value=track_fit_result.getPValue(),
466 has_trackFitResult=
False,
475 tan_lambda_estimate=nan,
476 tan_lambda_variance=nan,
507def get_reco_hit_information(reco_track, hit):
508 """Helper function for getting the correct reco hit info"""
509 for info
in getObjectList(hit.getRelationsFrom(
"RecoHitInformations")):
510 if info.getRelatedFrom(reco_track.getArrayName()) == reco_track:
516def peel_subdetector_hit_efficiency(mc_reco_track, reco_track, key="{part_name}"):
517 def get_efficiency(detector_string):
518 if not reco_track
or not mc_reco_track:
519 hit_efficiency = float(
"nan")
521 mc_reco_hits = getObjectList(getattr(mc_reco_track, f
"get{detector_string.upper()}HitList")())
522 if len(mc_reco_hits) == 0:
523 hit_efficiency = float(
'nan')
527 for mc_reco_hit
in mc_reco_hits:
528 info = get_reco_hit_information(mc_reco_track, mc_reco_hit)
530 if info.getFoundByTrackFinder() == Belle2.RecoHitInformation.c_MCTrackFinderAuxiliaryHit:
533 mc_reco_hit_size += 1
535 for reco_hit
in getObjectList(getattr(reco_track, f
"get{detector_string.upper()}HitList")()):
536 if mc_reco_hit.getArrayIndex() == reco_hit.getArrayIndex():
540 if not mc_reco_hit_size:
541 hit_efficiency = float(
'nan')
543 hit_efficiency /= mc_reco_hit_size
545 return {f
"{detector_string.lower()}_hit_efficiency": hit_efficiency}
547 return dict(**get_efficiency(
"CDC"), **get_efficiency(
"SVD"), **get_efficiency(
"PXD"))
552def peel_subdetector_hit_purity(reco_track, mc_reco_track, key="{part_name}"):
553 def get_efficiency(detector_string):
554 if not reco_track
or not mc_reco_track:
555 hit_purity = float(
"nan")
557 reco_hits = getObjectList(getattr(reco_track, f
"get{detector_string.upper()}HitList")())
558 reco_hit_size = len(reco_hits)
560 if reco_hit_size == 0:
561 hit_purity = float(
'nan')
564 for reco_hit
in reco_hits:
565 for mc_reco_hit
in getObjectList(getattr(mc_reco_track, f
"get{detector_string.upper()}HitList")()):
566 if mc_reco_hit.getArrayIndex() == reco_hit.getArrayIndex():
570 hit_purity /= reco_hit_size
572 return {f
"{detector_string.lower()}_hit_purity": hit_purity}
574 return dict(**get_efficiency(
"CDC"), **get_efficiency(
"SVD"), **get_efficiency(
"PXD"))
579def peel_hit_information(hit_info, reco_track, key="{part_name}"):
582 crops = dict(residual=nan,
587 tracking_detector=hit_info.getTrackingDetector(),
588 use_in_fit=hit_info.useInFit(),
593 if hit_info.useInFit()
and reco_track.hasTrackFitStatus():
594 track_point = reco_track.getCreatedTrackPoint(hit_info)
595 fitted_state = track_point.getFitterInfo()
598 res_state = fitted_state.getResidual().getState()
599 crops[
"residual"] = np.sqrt(res_state.Norm2Sqr())
600 if res_state.GetNoElements() == 2:
601 crops[
"residual_x"] = res_state[0]
602 crops[
"residual_y"] = res_state[1]
603 weights = fitted_state.getWeights()
604 crops[
'weight'] = max(weights)
605 except BaseException:
608 if hit_info.getTrackingDetector() == Belle2.RecoHitInformation.c_SVD:
609 hit = hit_info.getRelated(
"SVDClusters")
610 crops[
"hit_time"] = hit.getClsTime()
611 crops[
"layer_number"] = hit.getSensorID().getLayerNumber()
612 if hit_info.getTrackingDetector() == Belle2.RecoHitInformation.c_PXD:
613 hit = hit_info.getRelated(
"PXDClusters")
614 crops[
"layer_number"] = hit.getSensorID().getLayerNumber()
615 if hit_info.getTrackingDetector() == Belle2.RecoHitInformation.c_CDC:
616 hit = hit_info.getRelated(
"CDCHits")
617 crops[
"layer_number"] = hit.getICLayer()
624def peel_module_statistics(modules=None, key="{part_name}"):
627 module_stats = dict()
629 for module
in basf2.statistics.modules:
630 if module.name
in modules:
631 module_stats[str(module.name) +
"_mem"] = module.memory_sum(basf2.statistics.EVENT)
632 module_stats[str(module.name) +
"_time"] = module.time_sum(basf2.statistics.EVENT)
633 module_stats[str(module.name) +
"_calls"] = module.calls(basf2.statistics.EVENT)
641def get_seed_track_fit_result(reco_track):
642 position = reco_track.getPositionSeed()
643 momentum = reco_track.getMomentumSeed()
644 cartesian_covariance = reco_track.getSeedCovariance()
645 charge_sign = (-1
if reco_track.getChargeSeed() < 0
else 1)
647 particle_type = Belle2.Const.pion
648 p_value = float(
'nan')
658 cartesian_covariance,
668 return track_fit_result
673def is_correct_rl_information(cdc_hit, reco_track, hit_lookup):
674 rl_info = reco_track.getRightLeftInformation[
"const Belle2::CDCHit"](cdc_hit)
675 truth_rl_info = hit_lookup.getRLInfo(cdc_hit)
677 if rl_info == Belle2.RecoHitInformation.c_right
and truth_rl_info == 1:
679 if rl_info == Belle2.RecoHitInformation.c_left
and truth_rl_info == 65535:
This class provides a set of constants for the framework.
A (simplified) python wrapper for StoreArray.
Values of the result of a track fit with a given particle hypothesis.
static void getField(const double *pos, double *field)
return the magnetic field at a given position.