diff --git a/src/decaylanguage/dec/dec.py b/src/decaylanguage/dec/dec.py index 639f55da..12833eaa 100644 --- a/src/decaylanguage/dec/dec.py +++ b/src/decaylanguage/dec/dec.py @@ -39,7 +39,6 @@ from __future__ import annotations import copy -import operator import os import re import warnings @@ -878,6 +877,10 @@ def print_decay_modes( optionally with decay model information and/or normalisation or scaling of the branching fractions. + Note + ---- + Branching fractions are truncated to 7 significant digits for readability. + Parameters ---------- mother: str @@ -915,17 +918,17 @@ def print_decay_modes( >>> >>> # Simply print what has been parsed >>> p.print_decay_modes("MyD_0*+") - 0.533 MyD0 pi+ PHSP; - 0.08 MyD*0 pi+ pi0 PHSP; - 0.0542 MyD*+ pi+ pi- PHSP; - 0.0271 MyD*+ pi0 pi0 PHSP; + 0.533 MyD0 pi+ PHSP; + 0.08 MyD*0 pi+ pi0 PHSP; + 0.0542 MyD*+ pi+ pi- PHSP; + 0.0271 MyD*+ pi0 pi0 PHSP; >>> >>> # Print normalizing the sum of all mode BFs to unity >>> p.print_decay_modes("MyD_0*+", normalize=True) - 0.7676796774 MyD0 pi+ PHSP; - 0.1152239666 MyD*0 pi+ pi0 PHSP; - 0.07806423736 MyD*+ pi+ pi- PHSP; - 0.03903211868 MyD*+ pi0 pi0 PHSP; + 0.7676797 MyD0 pi+ PHSP; + 0.115224 MyD*0 pi+ pi0 PHSP; + 0.07806424 MyD*+ pi+ pi- PHSP; + 0.03903212 MyD*+ pi0 pi0 PHSP; >>> >>> # Print scaling all BFs relative to the BF of the highest-BF mode in the list, >>> # the latter being set to the value of "scale". @@ -933,10 +936,10 @@ def print_decay_modes( >>> # that about 35% of the total decay width is not accounted for in the list of modes, >>> # since the sum of probabilities, interpreted as BFs, sum to about 65%. >>> p.print_decay_modes("MyD_0*+", scale=0.5) - 0.5 MyD0 pi+ PHSP; - 0.07504690432 MyD*0 pi+ pi0 PHSP; - 0.05084427767 MyD*+ pi+ pi- PHSP; - 0.02542213884 MyD*+ pi0 pi0 PHSP; + 0.5 MyD0 pi+ PHSP; + 0.0750469 MyD*0 pi+ pi0 PHSP; + 0.05084428 MyD*+ pi+ pi- PHSP; + 0.02542214 MyD*+ pi0 pi0 PHSP; """ if scale is not None: @@ -955,39 +958,38 @@ def print_decay_modes( dms = self._find_decay_modes(mother) - ls_dict = {} + max_length: int = 0 + ls = [] for dm in dms: - dmdict = self._decay_mode_details(dm, display_photos_keyword) - model_params = [str(i) for i in dmdict["model_params"]] - ls_dict[dmdict["bf"]] = ( - dmdict["fs"], - dmdict["model"], - model_params, + dmdict: DecayModeDict = self._decay_mode_details(dm, display_photos_keyword) + model_params_list: list[str] = [str(i) for i in dmdict["model_params"]] + model_params: str = ( + "" if model_params_list == [] else " ".join(model_params_list) ) + decay_chain: str = " ".join(list(dmdict["fs"])) # type: ignore[arg-type] + if len(decay_chain) > max_length: + max_length = len(decay_chain) + ls.append((dmdict["bf"], decay_chain, dmdict["model"], model_params)) - dec_details = list(ls_dict.values()) - ls_attrs_aligned = list( - zip_longest( - *[self._align_items(i) for i in zip(*dec_details)], fillvalue="" - ) - ) - - ls = [(bf, ls_attrs_aligned[idx]) for idx, bf in enumerate(ls_dict)] - ls.sort(key=operator.itemgetter(0), reverse=(not ascending)) + # Sort decays by decreasing BF + ls = sorted(ls, key=lambda x: -x[0]) - norm = 1.0 + norm: float = 1.0 if normalize: - norm = sum(bf for bf, _ in ls) + norm = sum(bf for bf, _, _, _ in ls) elif scale is not None: # Get the largest branching fraction i = -1 if ascending else 0 norm = ls[i][0] / scale - for bf, info in ls: + max_length_string = str(max_length + 2) + for bf, fs, model, model_params in ls: if print_model: - line = " {:<15.10g} {} {} {}".format(bf / norm, *info) + line = " {:<10.7g} {:<{max_length}} {} {}".format( + bf / norm, fs, model, model_params, max_length=max_length_string + ) else: - line = f" {bf / norm:<15.10g} {info[0]}" + line = f" {bf / norm:<10.7g} {fs}" print(line.rstrip() + ";") # noqa: T201 @staticmethod diff --git a/tests/dec/test_dec.py b/tests/dec/test_dec.py index e6399bff..9a5e8be2 100644 --- a/tests/dec/test_dec.py +++ b/tests/dec/test_dec.py @@ -197,7 +197,7 @@ def test_particle_property_definitions(): "MyK*0": {"mass": 0.892, "width": 0.051}, "MyPhi": {"mass": 1.02, "width": 0.004}, "rho0": {"mass": 0.8, "width": 0.2}, - "MyRho0": {"mass": 0.8, "width": 149.1}, + "MyRho0": {"mass": 0.8, "width": 147.4}, } @@ -515,7 +515,7 @@ def test_multiline_model(): def test_custom_model_name(): - p = DecFileParser("./tests/data/test_custom_decay_model.dec") + p = DecFileParser(DIR / "../data/test_custom_decay_model.dec") p.load_additional_decay_models("CUSTOM_MODEL1", "CUSTOM_MODEL2") assert p.grammar() is not None @@ -590,6 +590,23 @@ def test_print_decay_modes_basics(): p.print_decay_modes("D*(2010)-", pdg_name=True) +def list_complement(l_m, l_s): + return [i for i in l_m if i not in l_s] + + +def test_print_decay_modes_full(): + p = DecFileParser(DIR / "../data/test_Bd2Dst0X_D02KPi.dec") + p.parse() + + decays = list_complement( + p.list_decay_mother_names(), p.list_charge_conjugate_decays() + ) + + for d in decays: + print(f"Decay {d}") + p.print_decay_modes(d, normalize=True) + + def test_print_decay_modes_options(): p1 = DecFileParser(DIR / "../data/test_example_Dst.dec") p1.parse() diff --git a/tests/output/DtoKpipipi_v2.cu b/tests/output/DtoKpipipi_v2.cu index dda3e4d8..54134210 100644 --- a/tests/output/DtoKpipipi_v2.cu +++ b/tests/output/DtoKpipipi_v2.cu @@ -162,7 +162,7 @@ ONE Variable K_1_1270_minus_M { "K_1_1270_minus_M" , 1253 }; Variable K_1_1270_minus_W { "K_1_1270_minus_W" , 90 }; Variable rho_770_0_M { "rho_770_0_M" , 775.26 }; - Variable rho_770_0_W { "rho_770_0_W" , 149.1 }; + Variable rho_770_0_W { "rho_770_0_W" , 147.4 }; Variable a_1_1260_plus_M { "a_1_1260_plus_M" , 1230 }; Variable a_1_1260_plus_W { "a_1_1260_plus_W" , 420 }; Variable PiPi2_M { "PiPi2_M" , 9990 };