def assign_particles_to_graph(particles, default_repr, desired_repr=None, filter_pdgid=None, filter_pdgid_final=None, remove_redundants=True): """Wrapper to easily assign particles to graph, change representation, filter out certain PDGIDs, and remove redundants. Parameters ---------- particles : list[NodeParticle], list[EdgeParticle] List of particles to be assigned to a graph. Must include relationship information. default_repr : {"NODE", "EDGE"} Particle representation for particles desired_repr : {"NODE", "EDGE"}, optional Desired output representation. filter_pdgid : list[int], optional filter_pdgid_final : list[int], optional These two args allow for removal of particles from the graph based on PDGID, the latter only removing final-state particles. Note that both particles and anti-particles will be removed. remove_redundants : bool, optional Whether to remove redundant particles from the graph. Returns ------- NetworkX.MultiDiGraph """ check_representation_str(default_repr, "default_repr") if default_repr == "NODE": graph = assign_particles_nodes(particles) elif default_repr == "EDGE": graph = assign_particles_edges(particles) new_repr = default_repr if desired_repr and desired_repr != default_repr: check_representation_str(desired_repr, "desired_repr") new_repr = desired_repr if (default_repr, desired_repr) == ("NODE", "EDGE"): graph = node_to_edge(graph) elif (default_repr, desired_repr) == ("EDGE", "NODE"): graph = edge_to_node(graph) filterer = remove_nodes_by_pdgid if new_repr == "NODE" else remove_edges_by_pdgid filter_pdgid = filter_pdgid or [] for pdgid in filter_pdgid: filterer(graph, pdgid, False) filter_pdgid_final = filter_pdgid_final or [] for pdgid in filter_pdgid_final: filterer(graph, pdgid, True) if remove_redundants: if new_repr == "NODE": remove_redundant_nodes(graph) elif new_repr == "EDGE": remove_redundant_edges(graph) return graph
def test_1_to_2(self): """Very simple scenario: 1 particle decays to 2 daughters""" p1 = NodeParticle(particle=Particle(barcode=1, pdgid=1), parent_barcodes=list(range(0, 1))) p2 = NodeParticle(particle=Particle(barcode=2, pdgid=2), parent_barcodes=list(range(1, 2))) p3 = NodeParticle(particle=Particle(barcode=3, pdgid=3), parent_barcodes=list(range(1, 2))) particles = [p1, p2, p3] g = ng.assign_particles_nodes(particles) self.check_graph_nodes([p.particle for p in particles], g) edges = [(1, 3), (1, 2)] self.check_graph_edges(edges, g)
def test_node_removal_simple(self): """Test whether node removal works in simple scenario. (1) -> (2) -> (3) becomes (1) -> (3) """ p1 = NodeParticle(particle=Particle(barcode=1), parent_barcodes=[]) p2 = NodeParticle(particle=Particle(barcode=2), parent_barcodes=[1]) p3 = NodeParticle(particle=Particle(barcode=3), parent_barcodes=[2]) g = ng.assign_particles_nodes([p1, p2, p3]) ng.remove_particle_node(g, 2) self.check_graph_edges([(1, 3)], g) self.check_graph_nodes([np.particle for np in [p1, p3]], g)
def assign_particles_to_graph(particles, default_repr, desired_repr=None, remove_redundants=True): """Wrapper to easily assign particles to graph, change representation, remove redundants. Parameters ---------- particles : list[NodeParticle], list[EdgeParticle] List of particles to be assigned to a graph. Must include relationship information. default_repr : {"NODE", "EDGE"} Particle representation for particles desired_repr : {"NODE", "EDGE"}, optional Desired output representation. remove_redundants : bool, optional Whether to remove redundant particles from the graph. Returns ------- NetworkX.MultiDiGraph """ check_representation_str(default_repr, "default_repr") if default_repr == "NODE": graph = assign_particles_nodes(particles) elif default_repr == "EDGE": graph = assign_particles_edges(particles) remove_edges_by_pdgid(graph, 22, True) new_repr = default_repr if desired_repr and desired_repr != default_repr: check_representation_str(desired_repr, "desired_repr") new_repr = desired_repr if (default_repr, desired_repr) == ("NODE", "EDGE"): graph = node_to_edge(graph) elif (default_repr, desired_repr) == ("EDGE", "NODE"): graph = edge_to_node(graph) if remove_redundants: if new_repr == "NODE": remove_redundant_nodes(graph) elif new_repr == "EDGE": remove_redundant_edges(graph) return graph
def test_2_to_1_to_3(self): """2 particles (1,2) to 1 (3) to 3 (4,5,6)""" p1 = NodeParticle(particle=Particle(barcode=1, pdgid=11), parent_barcodes=list(range(0, 1))) p2 = NodeParticle(particle=Particle(barcode=2, pdgid=-11), parent_barcodes=list(range(0, 1))) p3 = NodeParticle(particle=Particle(barcode=3, pdgid=22), parent_barcodes=list(range(1, 3))) p4 = NodeParticle(particle=Particle(barcode=4, pdgid=11), parent_barcodes=list(range(3, 4))) p5 = NodeParticle(particle=Particle(barcode=5, pdgid=12), parent_barcodes=list(range(3, 4))) p6 = NodeParticle(particle=Particle(barcode=6, pdgid=13), parent_barcodes=list(range(3, 4))) particles = [p1, p2, p3, p4, p5, p6] g = ng.assign_particles_nodes(particles) self.check_graph_nodes([p.particle for p in particles], g) edges = [(1, 3), (2, 3), (3, 4), (3, 5), (3, 6)] self.check_graph_edges(edges, g)
def test_1_to_2_node_to_edge(self): """Simple graph that does not require duplicate nodes.""" p1 = NodeParticle(particle=Particle(barcode=1, pdgid=1), parent_barcodes=[]) p2 = NodeParticle(particle=Particle(barcode=2, pdgid=2), parent_barcodes=[1]) p3 = NodeParticle(particle=Particle(barcode=3, pdgid=3), parent_barcodes=[1]) particles = [p1, p2, p3] g_node = assign_particles_nodes(particles) g_edge = node_to_edge(g_node) p1 = EdgeParticle(particle=Particle(barcode=1, pdgid=1), vtx_out_barcode=0, vtx_in_barcode=1) p2 = EdgeParticle(particle=Particle(barcode=2, pdgid=2), vtx_out_barcode=1, vtx_in_barcode=2) p3 = EdgeParticle(particle=Particle(barcode=3, pdgid=3), vtx_out_barcode=1, vtx_in_barcode=3) self.check_graph_edge_particles([p1.particle, p2.particle, p3.particle], g_edge) self.check_graph_edges([(0, 1), (1, 2), (1, 3)], g_edge)
def test_2_to_3_node_to_edge(self): """Simple graph structure that requires duplicate nodes""" p1 = NodeParticle(particle=Particle(barcode=1, pdgid=1), parent_barcodes=[]) p2 = NodeParticle(particle=Particle(barcode=2, pdgid=2), parent_barcodes=[]) p3 = NodeParticle(particle=Particle(barcode=3, pdgid=3), parent_barcodes=[1]) p4 = NodeParticle(particle=Particle(barcode=4, pdgid=4), parent_barcodes=[1, 2]) p5 = NodeParticle(particle=Particle(barcode=5, pdgid=5), parent_barcodes=[2]) particles = [p1, p2, p3, p4, p5] g_node = assign_particles_nodes(particles) g_edge = node_to_edge(g_node) self.check_graph_edges([(0, 1), (1, 4), (1, 5), (5, 6), (3, 7), (2, 3), (3, 5)], g_edge) new1 = Particle(barcode=20001, pdgid=1) new2 = Particle(barcode=20002, pdgid=2) self.check_graph_edge_particles([p1.particle, p2.particle, p3.particle, p4.particle, p5.particle, new1, new2], g_edge)
def test_redundant(self): """Check remove_redundants code. (1) to (2,3). Then (2)->(4)->(5), and (3) -> (5). So (4) should be redundant. """ p1 = NodeParticle(particle=Particle(barcode=1, pdgid=11), parent_barcodes=list(range(0, 1))) p2 = NodeParticle(particle=Particle(barcode=2, pdgid=-11), parent_barcodes=list(range(1, 2))) p3 = NodeParticle(particle=Particle(barcode=3, pdgid=22), parent_barcodes=list(range(1, 2))) p4 = NodeParticle(particle=Particle(barcode=4, pdgid=-11), parent_barcodes=list(range(2, 3))) p5 = NodeParticle(particle=Particle(barcode=5, pdgid=12), parent_barcodes=list(range(3, 5))) particles = [p1, p2, p3, p4, p5] g = ng.assign_particles_nodes(particles) ng.remove_redundant_nodes(g) particles.remove(p4) self.check_graph_nodes([p.particle for p in particles], g) edges = [(1, 2), (1, 3), (2, 5), (3, 5)] self.check_graph_edges(edges, g)
def test_2_to_3_node_to_edge(self): """Simple graph structure that requires duplicate nodes""" p1 = NodeParticle(particle=Particle(barcode=1, pdgid=1), parent_barcodes=[]) p2 = NodeParticle(particle=Particle(barcode=2, pdgid=2), parent_barcodes=[]) p3 = NodeParticle(particle=Particle(barcode=3, pdgid=3), parent_barcodes=[1]) p4 = NodeParticle(particle=Particle(barcode=4, pdgid=4), parent_barcodes=[1, 2]) p5 = NodeParticle(particle=Particle(barcode=5, pdgid=5), parent_barcodes=[2]) particles = [p1, p2, p3, p4, p5] g_node = assign_particles_nodes(particles) g_edge = node_to_edge(g_node) self.check_graph_edges([(0, 1), (1, 4), (1, 5), (5, 6), (3, 7), (2, 3), (3, 5)], g_edge) new1 = Particle(barcode=20001, pdgid=1) new2 = Particle(barcode=20002, pdgid=2) self.check_graph_edge_particles([ p1.particle, p2.particle, p3.particle, p4.particle, p5.particle, new1, new2 ], g_edge)
def test_1_to_2_node_to_edge(self): """Simple graph that does not require duplicate nodes.""" p1 = NodeParticle(particle=Particle(barcode=1, pdgid=1), parent_barcodes=[]) p2 = NodeParticle(particle=Particle(barcode=2, pdgid=2), parent_barcodes=[1]) p3 = NodeParticle(particle=Particle(barcode=3, pdgid=3), parent_barcodes=[1]) particles = [p1, p2, p3] g_node = assign_particles_nodes(particles) g_edge = node_to_edge(g_node) p1 = EdgeParticle(particle=Particle(barcode=1, pdgid=1), vtx_out_barcode=0, vtx_in_barcode=1) p2 = EdgeParticle(particle=Particle(barcode=2, pdgid=2), vtx_out_barcode=1, vtx_in_barcode=2) p3 = EdgeParticle(particle=Particle(barcode=3, pdgid=3), vtx_out_barcode=1, vtx_in_barcode=3) self.check_graph_edge_particles( [p1.particle, p2.particle, p3.particle], g_edge) self.check_graph_edges([(0, 1), (1, 2), (1, 3)], g_edge)
def test_intial_final_state(self): """Test whether particles marked as initial/final state correctly (1)+(2) -> (3) -> (4),(5),(6) """ p1 = NodeParticle(particle=Particle(barcode=1, pdgid=11), parent_barcodes=list(range(0, 1))) p2 = NodeParticle(particle=Particle(barcode=2, pdgid=-11), parent_barcodes=list(range(0, 1))) p3 = NodeParticle(particle=Particle(barcode=3, pdgid=22), parent_barcodes=list(range(1, 3))) p4 = NodeParticle(particle=Particle(barcode=4, pdgid=11), parent_barcodes=list(range(3, 4))) p5 = NodeParticle(particle=Particle(barcode=5, pdgid=12), parent_barcodes=list(range(3, 4))) p6 = NodeParticle(particle=Particle(barcode=6, pdgid=13), parent_barcodes=list(range(3, 4))) particles = [p1, p2, p3, p4, p5, p6] g = ng.assign_particles_nodes(particles) # dummy var to hold graph self.assertTrue(p1.particle.initial_state) self.assertTrue(p2.particle.initial_state) self.assertTrue(p4.particle.final_state) self.assertTrue(p5.particle.final_state) self.assertTrue(p6.particle.final_state)