From 71ca7c33fcfafb1d4c49103bbf737081a091a327 Mon Sep 17 00:00:00 2001 From: David Hendriks <davidhendriks93@gmail.com> Date: Tue, 8 Jun 2021 18:27:28 +0100 Subject: [PATCH] Modifying the behaviour of the multiplicty fraction calculating function --- binarycpython/utils/distribution_functions.py | 84 ++++++++++--------- binarycpython/utils/grid_options_defaults.py | 13 +-- 2 files changed, 53 insertions(+), 44 deletions(-) diff --git a/binarycpython/utils/distribution_functions.py b/binarycpython/utils/distribution_functions.py index f37efc8ca..5e32f4544 100644 --- a/binarycpython/utils/distribution_functions.py +++ b/binarycpython/utils/distribution_functions.py @@ -1069,7 +1069,9 @@ def normalize_dict(result_dict, verbosity=0): def Moe_de_Stefano_2017_multiplicity_fractions(options, verbosity=0): """ - Function that returns a list of multiplicity fractions for a given list + Function that creates a list of probability fractions and + normalizes and merges them according to the users choice. + TODO: make an extrapolation functionality in this. log10(1.6e1) is low, we can probably go a bit further @@ -1083,8 +1085,20 @@ def Moe_de_Stefano_2017_multiplicity_fractions(options, verbosity=0): # Use the global Moecache global Moecache - result = {} - new_result = {} + # Check for length + if not len(options["multiplicity_modulator"])==4: + msg = "Multiplicity modulator has to have 4 elements. Now it is {}, len: {}".format(options["multiplicity_modulator"], len(options["multiplicity_modulator"])) + verbose_print( + msg, + verbosity, + 0, + ) + raise ValueError(msg) + + # Set up some arrays + full_fractions_array = np.zeros(4) # Meant to contain the real fractions + weighted_fractions_array = np.zeros(4) # Meant to contain the fractions multiplied by the multiplicity modulator + multiplicity_modulator_array = np.array(options["multiplicity_modulator"]) # Modulator array # ... it's better to interpolate the multiplicity and then # use a Poisson distribution to calculate the fractions @@ -1104,25 +1118,16 @@ def Moe_de_Stefano_2017_multiplicity_fractions(options, verbosity=0): [np.log10(options["M1"])] )[0] + # Fill the multiplicity array for n in range(4): new_result[n] = poisson(multiplicity, n, 3, verbosity) - result[n] = ( - options["multiplicity_modulator"][n] - * poisson(multiplicity, n, 3, verbosity) - if options["multiplicity_modulator"][n] > 0 - else 0 - ) - print("For mass M1={}".format(options['M1'])) - print("Multiplicty modulator: {}".format(options["multiplicity_modulator"])) - print("Old results: {}".format(result)) + full_fractions_array[n] = poisson(multiplicity, n, 3, verbosity) - # Normalize dict - new_result = normalize_dict(new_result, verbosity=verbosity) - sum_result = sum([new_result[key] for key in new_result]) - print("New result: {} (sum = {})".format(new_result, sum_result)) + # Normalize it so it fills to one when taking all the multiplicities: + full_fractions_array = full_fractions_array/np.sum(full_fractions_array) verbose_print( - "\tM&S: Moe_de_Stefano_2017_multiplicity_fractions: using model {}".format("Poisson"), + "\tM&S: Moe_de_Stefano_2017_multiplicity_fractions: using model {}: full_fractions_array: {}".format("Poisson", full_fractions_array), verbosity, _MS_VERBOSITY_LEVEL, ) @@ -1133,27 +1138,26 @@ def Moe_de_Stefano_2017_multiplicity_fractions(options, verbosity=0): # note that in this case, there are no quadruples: these # are combined with triples + # Fill with the raw values for n in range(3): - result[n] = ( + full_fractions_array[n] = ( Moecache["rinterpolator_multiplicity"].interpolate( [np.log10(options["M1"])] - )[n + 1] - * options["multiplicity_modulator"][n] - ) - result[3] = 0.0 # no quadruples + )[n + 1]) + + # Set last value + full_fractions_array[3] = 0.0 # no quadruples verbose_print( - "\tM&S: Moe_de_Stefano_2017_multiplicity_fractions: using model {}".format("data"), + "\tM&S: Moe_de_Stefano_2017_multiplicity_fractions: using model {}: full_fractions_array: {}".format("data", full_fractions_array), verbosity, _MS_VERBOSITY_LEVEL, ) # Normalisation: if options["normalize_multiplicities"] == "raw": - # TODO: Not sure what actually happens here. It eems the same as above - # do nothing : use raw Poisson predictions - + # Don't multiply by the multiplicity_array, but do give a fractions array verbose_print( - "\tM&S: Moe_de_Stefano_2017_multiplicity_fractions: Not normalizing (using raw results)", + "\tM&S: Moe_de_Stefano_2017_multiplicity_fractions: Not normalizing (using raw results): results: {}".format(full_fractions_array), verbosity, _MS_VERBOSITY_LEVEL, ) @@ -1161,34 +1165,37 @@ def Moe_de_Stefano_2017_multiplicity_fractions(options, verbosity=0): pass elif options["normalize_multiplicities"] == "norm": - # simply normalize so all multiplicities add to 1 - result = normalize_dict(result, verbosity=verbosity) + # Multiply the full_multiplicity_fraction array by the multiplicity_multiplier_array, creating a weighted fractions array + weighted_fractions_array = full_fractions_array * multiplicity_modulator_array + + # Normalize this so it is intotal 1: + result = weighted_fractions_array/np.sum(weighted_fractions_array) verbose_print( - "\tM&S: Moe_de_Stefano_2017_multiplicity_fractions: Normalizing with {}".format("norm"), + "\tM&S: Moe_de_Stefano_2017_multiplicity_fractions: Normalizing with {}. result: {}".format("norm", result), verbosity, _MS_VERBOSITY_LEVEL, ) elif options["normalize_multiplicities"] == "merge": + # Get max multiplicity max_multiplicity = get_max_multiplicity(options["multiplicity_modulator"]) - # Merge the multiplicities - result = merge_multiplicities(result, max_multiplicity, verbosity=verbosity) - - new_result = merge_multiplicities(new_result, max_multiplicity, verbosity=verbosity) + # We first take the full multiplicity array + # (i.e. not multiplied by multiplier) and do the merging + result = merge_multiplicities(full_fractions_array, max_multiplicity, verbosity=verbosity) - # Normalising results again - result = normalize_dict(result, verbosity=verbosity) + # Then normalize to be sure + result = result/np.sum(result) verbose_print( - "\tM&S: Moe_de_Stefano_2017_multiplicity_fractions: Normalizing with {}, max_multiplicity={}".format("merge", max_multiplicity), + "\tM&S: Moe_de_Stefano_2017_multiplicity_fractions: Normalizing with {}, max_multiplicity={} result={}".format("merge", max_multiplicity, result), verbosity, _MS_VERBOSITY_LEVEL, ) verbose_print( - "\tM&S: Multiplicity array: {}".format(str(result)), + "\tM&S: Moe_de_Stefano_2017_multiplicity_fractions: {}".format(str(result)), verbosity, _MS_VERBOSITY_LEVEL, ) @@ -1196,7 +1203,6 @@ def Moe_de_Stefano_2017_multiplicity_fractions(options, verbosity=0): # return array reference return result - def build_q_table(options, m, p, verbosity=0): ############################################################ # diff --git a/binarycpython/utils/grid_options_defaults.py b/binarycpython/utils/grid_options_defaults.py index 3e53a23cb..8b7f14c1c 100644 --- a/binarycpython/utils/grid_options_defaults.py +++ b/binarycpython/utils/grid_options_defaults.py @@ -603,7 +603,7 @@ combined (and there are NO quadruples). e.g. [1,0,0,0] for single stars only [0,1,0,0] for binary stars only -defaults to [1,1,1,1] i.e. all types +defaults to [1,1,0,0] i.e. singles and binaries """, "normalize_multiplicities": """ given a mix of multiplities, you can either (noting that @@ -628,13 +628,16 @@ here (S,B,T,Q) = appropriate modulator * model(S,B,T,Q) ) Note: if multiplicity_modulator == [1,1,1,1] this option does nothing (equivalent to 'raw'). -note: if you only set one multiplicity_modulator -to 1, and all the others to 0, then normalizing +Note: If you only set one multiplicity modulator to 1, and all others to zero, +we will not multiply the fractions by the modulator. The grid will run fine (i.e. it will only run e.g. singles), but it will still take into account the real fraction +This is unlike how this setting was previously implemented: normalizing will mean that you effectively have the same number of stars as single, binary, triple or quad (whichever is non-zero) i.e. the multiplicity fraction is ignored. -This is probably not useful except for -testing purposes or comparing to old grids. + + + + """, "q_low_extrapolation_method": """ q extrapolation (below 0.15) method -- GitLab