Beispiel #1
0
def get_helicity_from_edge_props(edge_props):
    qns_label = get_xml_label(XMLLabelConstants.QuantumNumber)
    type_label = get_xml_label(XMLLabelConstants.Type)
    spin_label = StateQuantumNumberNames.Spin
    proj_label = get_xml_label(XMLLabelConstants.Projection)
    for qn in edge_props[qns_label]:
        if qn[type_label] == spin_label.name:
            return qn[proj_label]
    logging.error(edge_props[qns_label])
    raise ValueError("Could not find spin projection quantum number!")
Beispiel #2
0
def remove_spin_projection(edge_props):
    qns_label = get_xml_label(XMLLabelConstants.QuantumNumber)
    type_label = get_xml_label(XMLLabelConstants.Type)
    spin_label = StateQuantumNumberNames.Spin
    proj_label = get_xml_label(XMLLabelConstants.Projection)

    new_edge_props = deepcopy(edge_props)

    for qn_entry in new_edge_props[qns_label]:
        if (StateQuantumNumberNames[qn_entry[type_label]] is spin_label):
            del qn_entry[proj_label]
            break
    return new_edge_props
Beispiel #3
0
    def generate_partial_decay(self, graph, node_id, parameter_props):
        class_label = get_xml_label(XMLLabelConstants.Class)
        name_label = get_xml_label(XMLLabelConstants.Name)
        decay_products = []
        for out_edge_id in get_edges_outgoing_to_node(graph, node_id):
            decay_products.append({
                name_label:
                graph.edge_props[out_edge_id][name_label],
                '@FinalState':
                determine_attached_final_state_string(graph, out_edge_id),
                '@Helicity':
                get_helicity_from_edge_props(graph.edge_props[out_edge_id])
            })

        in_edge_ids = get_edges_ingoing_to_node(graph, node_id)
        if len(in_edge_ids) != 1:
            raise ValueError("This node does not represent a two body decay!")
        dec_part = graph.edge_props[in_edge_ids[0]]

        recoil_edge_id = get_recoil_edge(graph, in_edge_ids[0])
        parent_recoil_edge_id = get_parent_recoil_edge(graph, in_edge_ids[0])
        recoil_system_dict = {}
        if recoil_edge_id is not None:
            tempdict = {
                '@RecoilFinalState':
                determine_attached_final_state_string(graph, recoil_edge_id)
            }
            if parent_recoil_edge_id is not None:
                tempdict.update({
                    '@ParentRecoilFinalState':
                    determine_attached_final_state_string(
                        graph, parent_recoil_edge_id)
                })
            recoil_system_dict['RecoilSystem'] = tempdict

        amp_name = parameter_props[node_id]['Name']
        partial_decay_dict = {
            name_label: amp_name,
            class_label: "HelicityDecay",
            'DecayParticle': {
                name_label: dec_part[name_label],
                '@Helicity': get_helicity_from_edge_props(dec_part)
            },
            'DecayProducts': {
                'Particle': decay_products
            }
        }
        # partial_decay_dict.update(self.generate_magnitude_and_phase(amp_name))
        partial_decay_dict.update(recoil_system_dict)

        return partial_decay_dict
Beispiel #4
0
    def generate_amplitude_info(self, graph_groups, parameter_mapping):
        class_label = get_xml_label(XMLLabelConstants.Class)
        name_label = get_xml_label(XMLLabelConstants.Name)
        type_label = get_xml_label(XMLLabelConstants.Type)
        parameter_label = get_xml_label(XMLLabelConstants.Parameter)

        # for each graph group we create a coherent amplitude
        coherent_amplitudes = []
        for graph_group in graph_groups:
            seq_partial_decays = []
            ggi = graph_groups.index(graph_group)
            for graph in graph_group:
                gi = graph_group.index(graph)
                seq_partial_decays.append(
                    self.generate_sequential_decay(graph,
                                                   parameter_mapping[ggi][gi]))

            # in each coherent amplitude we create a product of partial decays
            coherent_amp_name = "coherent_" + \
                str(graph_groups.index(graph_group))
            coherent_amplitudes.append({
                class_label: 'Coherent',
                name_label: coherent_amp_name,
                parameter_label: {
                    class_label: "Double",
                    type_label: "Strength",
                    name_label: "strength_" + coherent_amp_name,
                    'Value': 1,
                    'Fix': True
                },
                'Amplitude': seq_partial_decays
            })

        # now wrap it with an incoherent intensity
        incoherent_amp_name = "incoherent"
        self.helicity_amplitudes = {
            'Intensity': {
                class_label: "Incoherent",
                name_label: incoherent_amp_name,
                parameter_label: {
                    class_label: "Double",
                    type_label: "Strength",
                    name_label: "strength_" + incoherent_amp_name,
                    'Value': 1,
                    'Fix': True
                },
                'Intensity': coherent_amplitudes
            }
        }
    def test_filter_graphs_for_interaction_qns(self, input_values,
                                               filter_parameters, result):
        graphs = []
        name_label = get_xml_label(XMLLabelConstants.Name)
        value_label = get_xml_label(XMLLabelConstants.Value)
        for x in input_values:
            tempgraph = make_ls_test_graph(x[1][0], x[1][1])
            tempgraph.add_edges([0])
            tempgraph.attach_edges_to_node_ingoing([0], 0)
            tempgraph.edge_props[0] = {name_label: {value_label: x[0]}}
            graphs.append(tempgraph)

        myfilter = require_interaction_property(*filter_parameters)
        filtered_graphs = filter_graphs(graphs, [myfilter])
        assert len(filtered_graphs) == result
Beispiel #6
0
    def generate_sequential_decay(self, graph, parameter_props):
        class_label = get_xml_label(XMLLabelConstants.Class)
        name_label = get_xml_label(XMLLabelConstants.Name)
        spin_label = StateQuantumNumberNames.Spin
        decay_info_label = get_xml_label(XMLLabelConstants.DecayInfo)
        type_label = get_xml_label(XMLLabelConstants.Type)
        partial_decays = []
        for node_id in graph.nodes:
            # in case a scalar without dynamics decays into daughters with no
            # net helicity, the partial amplitude can be dropped
            # (it is just a constant)
            in_edges = get_edges_ingoing_to_node(graph, node_id)
            out_edges = get_edges_outgoing_to_node(graph, node_id)
            # check mother particle is spin 0
            in_spin = get_particle_property(graph.edge_props[in_edges[0]],
                                            spin_label)
            out_spins = [
                get_particle_property(graph.edge_props[x], spin_label)
                for x in out_edges
            ]
            if (in_spin is not None and None not in out_spins
                    and in_spin.magnitude() == 0):
                if abs(out_spins[0].projection() -
                       out_spins[1].projection()) == 0.0:
                    # check if dynamics is non resonsant (constant)
                    if ('NonResonant' == graph.edge_props[in_edges[0]]
                        [decay_info_label][type_label]):
                        continue

            partial_decays.append(
                self.generate_partial_decay(graph, node_id, parameter_props))

        amp_name = parameter_props['AmplitudeName']
        seq_decay_dict = {
            class_label: "SequentialPartialAmplitude",
            name_label: amp_name,
            'PartialAmplitude': partial_decays
        }
        seq_decay_dict.update(
            self.generate_magnitude_and_phase(parameter_props))
        prefactor = get_prefactor(graph)
        if prefactor != 1.0 and prefactor is not None:
            prefactor_label = get_xml_label(XMLLabelConstants.PreFactor)
            seq_decay_dict[prefactor_label] = {
                '@Magnitude': prefactor,
                '@Phase': 0.0
            }
        return seq_decay_dict
Beispiel #7
0
    def generate(self, graphs):
        if len(graphs) <= 0:
            raise ValueError(
                "Number of solution graphs is not larger than zero!")

        decay_info = {get_xml_label(XMLLabelConstants.Type): 'nonResonant'}
        decay_info_label = get_xml_label(XMLLabelConstants.DecayInfo)
        for g in graphs:
            if self.top_node_no_dynamics:
                init_edges = get_initial_state_edges(g)
                if len(init_edges) > 1:
                    raise ValueError(
                        "Only a single initial state particle allowed")
                eprops = g.edge_props[init_edges[0]]
                eprops[decay_info_label] = decay_info

        self.particle_list = generate_particle_list(graphs)
        self.kinematics = generate_kinematics(graphs)

        # if use_parity_conservation flag is set to None, use automatic
        # settings. check if the parity prefactor is defined, if so use
        # parity conservation
        if self.use_parity_conservation is None:
            prefactors = [x for x in graphs if get_prefactor(x) is not None]
            self.use_parity_conservation = False
            if prefactors:
                self.use_parity_conservation = True
                logging.info("Using parity conservation to connect fit "
                             "parameters together with prefactors.")
        graph_groups = group_graphs_same_initial_and_final(graphs)
        logging.debug("There are " + str(len(graph_groups)) + " graph groups")
        # At first we need to define the fit parameters
        parameter_mapping = self.generate_fit_parameters(
            graph_groups, self.name_generator)
        self.fix_parameters_unambiguously(parameter_mapping)
        fit_params = set()
        for x in parameter_mapping.values():
            for y in x.values():
                if not y['Magnitude'][1]:
                    fit_params.add('Magnitude_' + y['ParameterNameSuffix'])
                if not y['Phase'][1]:
                    fit_params.add('Phase_' + y['ParameterNameSuffix'])
        logging.info("Number of parameters:" + str(len(fit_params)))
        self.generate_amplitude_info(graph_groups, parameter_mapping)
Beispiel #8
0
class GammaCheck(InteractionDeterminationFunctorInterface):
    name_label = get_xml_label(XMLLabelConstants.Name)

    def check(self, in_edge_props, out_edge_props, node_props):
        int_type = InteractionTypes.Undefined
        for edge_props in in_edge_props + out_edge_props:
            if ('gamma' in edge_props[self.name_label]):
                int_type = InteractionTypes.EM
                break

        return int_type
Beispiel #9
0
 def create_node_variables(self, node_id, qn_list):
     """
     Creates variables for the quantum numbers of the specified node.
     """
     variables = {}
     type_label = get_xml_label(XMLLabelConstants.Type)
     if node_id in self.graph.node_props:
         qns_label = get_xml_label(XMLLabelConstants.QuantumNumber)
         for qn_name in qn_list:
             converter = QNClassConverterMapping[
                 QNNameClassMapping[qn_name]]
             found_prop = None
             for node_qn in self.graph.node_props[node_id][qns_label]:
                 if (node_qn[type_label] == qn_name.name):
                     found_prop = node_qn
                     break
             if found_prop is not None:
                 value = converter.parse_from_dict(found_prop)
                 variables[qn_name] = value
     return variables
Beispiel #10
0
def remove_qns_from_graph(graph, qn_list):
    qns_label = get_xml_label(XMLLabelConstants.QuantumNumber)
    type_label = get_xml_label(XMLLabelConstants.Type)

    int_qns = [x for x in qn_list if isinstance(
        x, InteractionQuantumNumberNames)]
    state_qns = [x for x in qn_list if isinstance(
        x, StateQuantumNumberNames)]
    part_props = [x for x in qn_list if isinstance(
        x, ParticlePropertyNames)]

    graph_copy = deepcopy(graph)

    for int_qn in int_qns:
        for props in graph_copy.node_props.values():
            if qns_label in props:
                for qn_entry in props[qns_label]:
                    if (InteractionQuantumNumberNames[qn_entry[type_label]]
                            is int_qn):
                        del props[qns_label][props[qns_label].index(qn_entry)]
                        break

    for state_qn in state_qns:
        for props in graph_copy.edge_props.values():
            if qns_label in props:
                for qn_entry in props[qns_label]:
                    if (StateQuantumNumberNames[qn_entry[type_label]]
                            is state_qn):
                        del props[qns_label][props[qns_label].index(qn_entry)]
                        break

    for part_prop in part_props:
        for props in graph_copy.edge_props.values():
            if qns_label in props:
                for qn_entry in graph_copy.edge_props[qns_label]:
                    if (ParticlePropertyNames[qn_entry[type_label]]
                            is part_prop):
                        del props[qns_label][props[qns_label].index(qn_entry)]
                        break

    return graph_copy
Beispiel #11
0
def generate_particle_list(graphs):
    # create particle entries
    temp_particle_names = []
    particles = []
    for g in graphs:
        for edge_props in g.edge_props.values():
            new_edge_props = remove_spin_projection(edge_props)
            par_name = new_edge_props[get_xml_label(XMLLabelConstants.Name)]
            if par_name not in temp_particle_names:
                particles.append(new_edge_props)
                temp_particle_names.append(par_name)
    return {'ParticleList': {'Particle': particles}}
Beispiel #12
0
class LeptonCheck(InteractionDeterminationFunctorInterface):
    lepton_flavour_labels = [
        StateQuantumNumberNames.ElectronLN,
        StateQuantumNumberNames.MuonLN,
        StateQuantumNumberNames.TauLN
    ]
    name_label = get_xml_label(XMLLabelConstants.Name)
    qns_label = get_xml_label(XMLLabelConstants.QuantumNumber)

    def check(self, in_edge_props, out_edge_props, node_props):
        node_interaction_type = InteractionTypes.Undefined
        for edge_props in in_edge_props + out_edge_props:
            if sum([get_particle_property(edge_props, x)
                    for x in self.lepton_flavour_labels
                    if get_particle_property(edge_props, x) is not None]):
                if [x for x in
                        ['ve', 'vebar', 'vmu', 'vmubar', 'vtau', 'vtaubar']
                        if x == edge_props[self.name_label]]:
                    node_interaction_type = InteractionTypes.Weak
                    break
                if edge_props[self.qns_label] != 0:
                    node_interaction_type = InteractionTypes.EM
        return node_interaction_type
Beispiel #13
0
def generate_model_xml():
    from expertsystem.ui.system_control import (StateTransitionManager,
                                                InteractionTypes)

    from expertsystem.amplitude.helicitydecay import (
        HelicityDecayAmplitudeGeneratorXML)

    from expertsystem.state.particle import get_xml_label, XMLLabelConstants
    # initialize the graph edges (initial and final state)
    initial_state = [("D1(2420)0", [-1, 1])]
    final_state = [("D0", [0]), ("pi-", [0]), ("pi+", [0])]

    tbd_manager = StateTransitionManager(initial_state, final_state, ['D*'])
    tbd_manager.number_of_threads = 1
    tbd_manager.set_allowed_interaction_types([InteractionTypes.Strong])
    graph_interaction_settings_groups = tbd_manager.prepare_graphs()

    (solutions, violated_rules
     ) = tbd_manager.find_solutions(graph_interaction_settings_groups)

    print("found " + str(len(solutions)) + " solutions!")

    print("intermediate states:")
    decinfo_label = get_xml_label(XMLLabelConstants.DecayInfo)
    for g in solutions:
        print(g.edge_props[1]['@Name'])
        for edge_props in g.edge_props.values():
            if decinfo_label in edge_props:
                del edge_props[decinfo_label]
                edge_props[decinfo_label] = {
                    get_xml_label(XMLLabelConstants.Type): "nonResonant"
                }

    xml_generator = HelicityDecayAmplitudeGeneratorXML()
    xml_generator.generate(solutions)
    xml_generator.write_to_file('model.xml')
Beispiel #14
0
def add_qn_to_graph_element(graph, var_info, value):
    if value is None:
        return
    qns_label = get_xml_label(XMLLabelConstants.QuantumNumber)

    element_id = var_info.element_id
    qn_name = var_info.qn_name
    graph_prop_dict = graph.edge_props
    if var_info.graph_element_type is graph_element_types.node:
        graph_prop_dict = graph.node_props

    converter = QNClassConverterMapping[QNNameClassMapping[qn_name]]

    if element_id not in graph_prop_dict:
        graph_prop_dict[element_id] = {qns_label: []}

    graph_prop_dict[element_id][qns_label].append(
        converter.convert_to_dict(qn_name, value))
Beispiel #15
0
 def generate_magnitude_and_phase(self, parameter_mapping):
     par_label = get_xml_label(XMLLabelConstants.Parameter)
     par_suffix = parameter_mapping['ParameterNameSuffix']
     mag = parameter_mapping['Magnitude']
     phase = parameter_mapping['Phase']
     return {
         par_label: [{
             '@Class': "Double",
             '@Type': "Magnitude",
             '@Name': "Magnitude_" + par_suffix,
             'Value': mag[0],
             'Fix': mag[1]
         }, {
             '@Class': "Double",
             '@Type': "Phase",
             '@Name': "Phase_" + par_suffix,
             'Value': phase[0],
             'Fix': phase[1]
         }]
     }
Beispiel #16
0
    def generate(self, graph, node_id):
        # get ending node of the edge
        # then make name for
        in_edges = get_edges_ingoing_to_node(graph, node_id)
        out_edges = get_edges_outgoing_to_node(graph, node_id)
        name_label = get_xml_label(XMLLabelConstants.Name)
        names = []
        hel = []
        for i in in_edges + out_edges:
            names.append(graph.edge_props[i][name_label])
            temphel = float(get_helicity_from_edge_props(graph.edge_props[i]))
            # remove .0
            if temphel % 1 == 0:
                temphel = int(temphel)
            hel.append(temphel)

        par_name_suffix = '_to_'
        par_name_suffix += names[1] + '_' + str(hel[1])
        par_name_suffix += '+' + names[2] + '_' + str(hel[2])
        name = names[0] + '_' + str(hel[0]) + par_name_suffix
        par_name_suffix = names[0] + par_name_suffix
        if par_name_suffix not in self.generated_parameter_names:
            append_name = True
            if self.use_parity_conservation:
                # first check if parity partner exists
                pp_par_name_suffix = names[0]
                pp_par_name_suffix += '_to_'
                pp_par_name_suffix += names[1] + '_' + str(-1 * hel[1])
                pp_par_name_suffix += '+' + \
                    names[2] + '_' + str(-1 * hel[2])
                if pp_par_name_suffix in self.generated_parameter_names:
                    par_name_suffix = pp_par_name_suffix
                    append_name = False
            if append_name:
                self.generated_parameter_names.append(par_name_suffix)
        return (name, par_name_suffix)
Beispiel #17
0
def create_edge_id_particle_mapping(graph, external_edge_getter_function):
    name_label = get_xml_label(XMLLabelConstants.Name)
    return {i: graph.edge_props[i][name_label]
            for i in external_edge_getter_function(graph)}