def add_leaf_barcodes(tree, barcode_array): """ Adds barcodes from barcode_array to the corresponding leaves of the tree """ num_cells = barcode_array.shape[0] for cell in range(num_cells): if 'cell' in tree.nodes[cell]: tree.nodes[cell]['cell'].barcode = barcode_array[cell, :] else: tree.nodes[cell]['cell'] = sim.Cell(np.nan, barcode_array[cell, :]) tree.nodes['root']['cell'] = sim.Cell(np.nan, np.zeros(barcode_array.shape[1])) return tree
def recursive_add_barcodes(tree, current_node): """ Fills in the barcodes for internal nodes for a tree whose leaves have barcodes Minimizes the number of mutation events that occur, assuming no backmutations and a known initial barcode """ children = tree.successors(current_node) child_barcodes = [] for child in children: recursive_add_barcodes(tree, child) child_barcodes.append(tree.nodes[child]['cell'].barcode) if 'cell' in tree.nodes[current_node]: return else: # if we've somehow ended up at a leaf with no cell, this will fail # likely this means that the tree was improperly annotated # (e.g., too few barcodes were added) current_barcode = child_barcodes[0].copy() if len(child_barcodes) == 1: warnings.warn( "Some cell has only one descendant. Assuming no mutations occurred between them." ) else: # assume that if a site is missing in one child it equals the # value in the other child current_barcode[child_barcodes[0] == -1] = child_barcodes[1][ child_barcodes[0] == -1] # if the two children differ and neither is missing, set parent to unmutated current_barcode[(child_barcodes[0] != child_barcodes[1]) & (child_barcodes[1] != -1)] = 0 tree.nodes[current_node]['cell'] = sim.Cell(np.nan, current_barcode) return
def add_leaf_x(tree, x_array): """ Adds expression vectors from x_array to the corresponding leaves of the tree """ num_cells = x_array.shape[0] for cell in range(num_cells): if 'cell' in tree.nodes[cell]: tree.nodes[cell]['cell'].x = x_array[cell, :] else: tree.nodes[cell]['cell'] = sim.Cell(x_array[cell, :], np.nan) return tree
def list_tree_to_digraph(list_tree): """ Converts a tree stored as nested lists to a networkx DiGraph Internal nodes are indexed by negative integers, leaves by nonnegative integers """ next_internal_node = -1 next_leaf_node = 0 T, next_internal_node, next_leaf_node, subtree_root = recursive_list_tree_to_digraph( list_tree, next_internal_node, next_leaf_node) barcode_length = len(T.nodes[0]['cell'].barcode) T.add_node('root', cell=sim.Cell(np.nan, np.zeros(barcode_length)), time_to_parent=0) T.add_edge('root', subtree_root, time=T.nodes[subtree_root]['time_to_parent']) return T
timescale = 100 x0_speed = 1 / timescale sim_params = sim.SimulationParameters(division_time_std=0.01 * timescale, flow_type=flow_type, x0_speed=x0_speed, mutation_rate=1 / timescale, mean_division_time=1.1 * timescale, timestep=0.001 * timescale) mean_x0_early = 2 time_early = 4 * timescale # Time when early cells are sampled time_late = time_early + 4 * timescale # Time when late cells are sampled x0_initial = mean_x0_early - time_early * x0_speed initial_cell = sim.Cell(np.array([x0_initial, 0, 0]), np.zeros(sim_params.barcode_length)) sample_times = {'early': time_early, 'late': time_late} # Choosing which of the three dimensions to show in later plots if flow_type == 'mismatched_clusters': dimensions_to_plot = [1, 2] else: dimensions_to_plot = [0, 1] ############################################################################### # Running the simulation # sample = sim.sample_descendants(initial_cell.deepcopy(), time_late, sim_params) ############################################################################### # Processing simulation output