コード例 #1
0
 def _generate_lineages(self, **kwargs):
     current_time = 0.0
     lineage_data = kwargs.get("lineage_data")
     max_time = kwargs.get("max_time", None)
     num_extant_lineages = kwargs.get("num_extant_lineages", None)
     num_extant_orthospecies = kwargs.get("num_extant_orthospecies", None)
     phase_idx = kwargs.get("phase_idx")
     lineage_taxon_namespace = kwargs.get("lineage_taxon_namespace", None)
     species_taxon_namespace = kwargs.get("species_taxon_namespace", None)
     if phase_idx == 0:
         lineage_data[phase_idx]["lineage_id"] = 1
         lineage_data[phase_idx]["species_id"] = 1
         initial_lineage = self._new_lineage(
             lineage_id=lineage_data[phase_idx]["lineage_id"],
             parent_lineage=None,
             origin_time=-1e-10,
         )
         lineage_data[phase_idx]["orthospecies_lineages"] = [
             initial_lineage
         ]
         lineage_data[phase_idx]["incipient_species_lineages"] = []
     else:
         lineage_data[phase_idx]["lineage_id"] = lineage_data[0].get(
             "lineage_id", 0) + 1
         lineage_data[phase_idx]["species_id"] = lineage_data[0].get(
             "species_id", 0)
         initial_lineage = self._new_lineage(
             lineage_id=lineage_data[phase_idx]["lineage_id"],
             parent_lineage=lineage_data[0]["lineage_collection"][0],
             origin_time=current_time,
         )
         lineage_data[phase_idx]["orthospecies_lineages"] = []
         lineage_data[phase_idx]["incipient_species_lineages"] = [
             initial_lineage
         ]
     lineage_data[phase_idx]["lineage_collection"] = [initial_lineage]
     lineage_collection = lineage_data[phase_idx]["lineage_collection"]
     orthospecies_lineages = lineage_data[phase_idx][
         "orthospecies_lineages"]
     incipient_species_lineages = lineage_data[phase_idx][
         "incipient_species_lineages"]
     while True:
         num_orthospecies = len(orthospecies_lineages)
         num_incipient_species = len(incipient_species_lineages)
         if num_incipient_species + num_orthospecies == 0:
             raise TreeSimTotalExtinctionException()
         ## Draw time to next event
         event_rates = []
         # Event type 0
         event_rates.append(
             self.speciation_initiation_from_orthospecies_rate *
             num_orthospecies)
         # Event type 1
         event_rates.append(self.orthospecies_extinction_rate *
                            num_orthospecies)
         # Event type 2
         event_rates.append(
             self.speciation_initiation_from_incipient_species_rate *
             num_incipient_species)
         # Event type 3
         event_rates.append(self.speciation_completion_rate *
                            num_incipient_species)
         # Event type 4
         event_rates.append(self.incipient_species_extinction_rate *
                            num_incipient_species)
         # All events
         rate_of_any_event = sum(event_rates)
         # Waiting time
         waiting_time = self.rng.expovariate(rate_of_any_event)
         # waiting_time = -math.log(self.rng.uniform(0, 1))/rate_of_any_event
         if max_time and (current_time + waiting_time) > max_time:
             current_time = max_time
             break
         # we do this here so that the (newest) tip lineages have the
         # waiting time to the next event branch lengths
         if num_extant_lineages is not None and (
                 num_incipient_species +
                 num_orthospecies) >= num_extant_lineages:
             final_time = current_time + self.rng.uniform(0, waiting_time)
             lineage_data[phase_idx]["final_time"] = final_time
             break
         elif num_extant_orthospecies is not None:
             ## note: very expensive operation to count orthospecies leaves!
             final_time = current_time + self.rng.uniform(0, waiting_time)
             lineage_collection_snapshot = [
                 lineage.clone() for lineage in itertools.chain(
                     lineage_data[0]["lineage_collection"], lineage_data[1]
                     ["lineage_collection"])
             ]
             try:
                 orthospecies_tree = self._compile_species_tree(
                     lineage_collection=lineage_collection_snapshot,
                     max_time=final_time,
                 )
                 num_leaves = len(orthospecies_tree.leaf_nodes())
                 if num_leaves >= num_extant_orthospecies:
                     lineage_tree = self._compile_lineage_tree(
                         lineage_collection=lineage_collection_snapshot,
                         max_time=final_time,
                         is_drop_extinct=True,
                     )
                     lineage_tree, orthospecies_tree = self._finalize_trees(
                         lineage_tree=lineage_tree,
                         lineage_taxon_namespace=lineage_taxon_namespace,
                         orthospecies_tree=orthospecies_tree,
                         species_taxon_namespace=species_taxon_namespace,
                         lineage_collection=lineage_collection_snapshot,
                     )
                     lineage_data[phase_idx]["lineage_tree"] = lineage_tree
                     lineage_data[phase_idx][
                         "orthospecies_tree"] = orthospecies_tree
                     return
             except ProcessFailedException:
                 pass
         # add to current time
         current_time += waiting_time
         # Select event
         event_type_idx = probability.weighted_index_choice(
             weights=event_rates, rng=self.rng)
         assert (event_type_idx >= 0 and event_type_idx <= 4)
         if event_type_idx == 0:
             # Splitting of new incipient species lineage from orthospecies lineage
             parent_lineage = self.rng.choice(orthospecies_lineages)
             lineage_data[phase_idx]["lineage_id"] += 1
             new_lineage = self._new_lineage(
                 lineage_id=lineage_data[phase_idx]["lineage_id"],
                 parent_lineage=parent_lineage,
                 origin_time=current_time,
             )
             lineage_collection.append(new_lineage)
             incipient_species_lineages.append(new_lineage)
         elif event_type_idx == 1:
             # Extinction of an orthospecies lineage
             lineage_idx = self.rng.randint(0,
                                            len(orthospecies_lineages) - 1)
             orthospecies_lineages[
                 lineage_idx].extinction_time = current_time
             del orthospecies_lineages[lineage_idx]
         elif event_type_idx == 2:
             # Splitting of new incipient species lineage from incipient lineage
             parent_lineage = self.rng.choice(incipient_species_lineages)
             lineage_data[phase_idx]["lineage_id"] += 1
             new_lineage = self._new_lineage(
                 lineage_id=lineage_data[phase_idx]["lineage_id"],
                 parent_lineage=parent_lineage,
                 origin_time=current_time,
             )
             lineage_collection.append(new_lineage)
             incipient_species_lineages.append(new_lineage)
         elif event_type_idx == 3:
             # Completion of speciation
             lineage_idx = self.rng.randint(
                 0,
                 len(incipient_species_lineages) - 1)
             lineage = incipient_species_lineages[lineage_idx]
             lineage.speciation_completion_time = current_time
             lineage_data[phase_idx]["species_id"] += 1
             lineage.species_id = lineage_data[phase_idx]["species_id"]
             orthospecies_lineages.append(lineage)
             del incipient_species_lineages[lineage_idx]
         elif event_type_idx == 4:
             # Extinction of an incipient_species lineage
             lineage_idx = self.rng.randint(
                 0,
                 len(incipient_species_lineages) - 1)
             incipient_species_lineages[
                 lineage_idx].extinction_time = current_time
             del incipient_species_lineages[lineage_idx]
         else:
             raise Exception(
                 "Unexpected event type index: {}".format(event_type_idx))
コード例 #2
0
 def _generate_lineages(self, **kwargs):
     current_time = 0.0
     lineage_data = kwargs.get("lineage_data")
     max_time = kwargs.get("max_time", None)
     num_extant_lineages = kwargs.get("num_extant_lineages", None)
     num_extant_orthospecies = kwargs.get("num_extant_orthospecies", None)
     phase_idx = kwargs.get("phase_idx")
     lineage_taxon_namespace = kwargs.get("lineage_taxon_namespace", None)
     species_taxon_namespace = kwargs.get("species_taxon_namespace", None)
     if phase_idx == 0:
         lineage_data[phase_idx]["lineage_id"] = 1
         lineage_data[phase_idx]["species_id"] = 1
         initial_lineage = self._new_lineage(
                 lineage_id=lineage_data[phase_idx]["lineage_id"],
                 parent_lineage=None,
                 origin_time=-1e-10,
                 )
         lineage_data[phase_idx]["orthospecies_lineages"] = [initial_lineage]
         lineage_data[phase_idx]["incipient_species_lineages"] = []
     else:
         lineage_data[phase_idx]["lineage_id"] = lineage_data[0].get("lineage_id", 0) + 1
         lineage_data[phase_idx]["species_id"] = lineage_data[0].get("species_id", 0)
         initial_lineage = self._new_lineage(
                 lineage_id=lineage_data[phase_idx]["lineage_id"],
                 parent_lineage=lineage_data[0]["lineage_collection"][0],
                 origin_time=current_time,
                 )
         lineage_data[phase_idx]["orthospecies_lineages"] = []
         lineage_data[phase_idx]["incipient_species_lineages"] = [initial_lineage]
     lineage_data[phase_idx]["lineage_collection"] = [initial_lineage]
     lineage_collection = lineage_data[phase_idx]["lineage_collection"]
     orthospecies_lineages = lineage_data[phase_idx]["orthospecies_lineages"]
     incipient_species_lineages = lineage_data[phase_idx]["incipient_species_lineages"]
     while True:
         num_orthospecies = len(orthospecies_lineages)
         num_incipient_species = len(incipient_species_lineages)
         if num_incipient_species + num_orthospecies == 0:
             raise TreeSimTotalExtinctionException()
         ## Draw time to next event
         event_rates = []
         # Event type 0
         event_rates.append(self.speciation_initiation_from_orthospecies_rate * num_orthospecies)
         # Event type 1
         event_rates.append(self.orthospecies_extinction_rate * num_orthospecies)
         # Event type 2
         event_rates.append(self.speciation_initiation_from_incipient_species_rate * num_incipient_species)
         # Event type 3
         event_rates.append(self.speciation_completion_rate * num_incipient_species)
         # Event type 4
         event_rates.append(self.incipient_species_extinction_rate * num_incipient_species)
         # All events
         rate_of_any_event = sum(event_rates)
         # Waiting time
         waiting_time = self.rng.expovariate(rate_of_any_event)
         # waiting_time = -math.log(self.rng.uniform(0, 1))/rate_of_any_event
         if max_time and (current_time + waiting_time) > max_time:
             current_time = max_time
             break
         # we do this here so that the (newest) tip lineages have the
         # waiting time to the next event branch lengths
         if num_extant_lineages is not None and (num_incipient_species + num_orthospecies) >= num_extant_lineages:
             final_time = current_time + self.rng.uniform(0, waiting_time)
             lineage_data[phase_idx]["final_time"] = final_time
             break
         elif num_extant_orthospecies is not None:
             ## note: very expensive operation to count orthospecies leaves!
             final_time = current_time + self.rng.uniform(0, waiting_time)
             lineage_collection_snapshot = [lineage.clone() for lineage in itertools.chain(lineage_data[0]["lineage_collection"], lineage_data[1]["lineage_collection"])]
             try:
                 orthospecies_tree = self._compile_species_tree(
                         lineage_collection=lineage_collection_snapshot,
                         max_time=final_time,
                         )
                 num_leaves = len(orthospecies_tree.leaf_nodes())
                 if num_leaves >= num_extant_orthospecies:
                     lineage_tree = self._compile_lineage_tree(
                         lineage_collection=lineage_collection_snapshot,
                         max_time=final_time,
                         is_drop_extinct=True,
                         )
                     lineage_tree, orthospecies_tree = self._finalize_trees(
                             lineage_tree=lineage_tree,
                             lineage_taxon_namespace=lineage_taxon_namespace,
                             orthospecies_tree=orthospecies_tree,
                             species_taxon_namespace=species_taxon_namespace,
                             lineage_collection=lineage_collection_snapshot,
                             )
                     lineage_data[phase_idx]["lineage_tree"] = lineage_tree
                     lineage_data[phase_idx]["orthospecies_tree"] = orthospecies_tree
                     return
             except ProcessFailedException:
                 pass
         # add to current time
         current_time += waiting_time
         # Select event
         event_type_idx = probability.weighted_index_choice(weights=event_rates, rng=self.rng)
         assert (event_type_idx >= 0 and event_type_idx <= 4)
         if event_type_idx == 0:
             # Splitting of new incipient species lineage from orthospecies lineage
             parent_lineage = self.rng.choice(orthospecies_lineages)
             lineage_data[phase_idx]["lineage_id"] += 1
             new_lineage = self._new_lineage(
                     lineage_id=lineage_data[phase_idx]["lineage_id"],
                     parent_lineage=parent_lineage,
                     origin_time=current_time,
                     )
             lineage_collection.append(new_lineage)
             incipient_species_lineages.append(new_lineage)
         elif event_type_idx == 1:
             # Extinction of an orthospecies lineage
             lineage_idx = self.rng.randint(0, len(orthospecies_lineages)-1)
             orthospecies_lineages[lineage_idx].extinction_time = current_time
             del orthospecies_lineages[lineage_idx]
         elif event_type_idx == 2:
             # Splitting of new incipient species lineage from incipient lineage
             parent_lineage = self.rng.choice(incipient_species_lineages)
             lineage_data[phase_idx]["lineage_id"] += 1
             new_lineage = self._new_lineage(
                     lineage_id=lineage_data[phase_idx]["lineage_id"],
                     parent_lineage=parent_lineage,
                     origin_time=current_time,
                     )
             lineage_collection.append(new_lineage)
             incipient_species_lineages.append(new_lineage)
         elif event_type_idx == 3:
             # Completion of speciation
             lineage_idx = self.rng.randint(0, len(incipient_species_lineages)-1)
             lineage = incipient_species_lineages[lineage_idx]
             lineage.speciation_completion_time = current_time
             lineage_data[phase_idx]["species_id"] += 1
             lineage.species_id = lineage_data[phase_idx]["species_id"]
             orthospecies_lineages.append(lineage)
             del incipient_species_lineages[lineage_idx]
         elif event_type_idx == 4:
             # Extinction of an incipient_species lineage
             lineage_idx = self.rng.randint(0, len(incipient_species_lineages)-1)
             incipient_species_lineages[lineage_idx].extinction_time = current_time
             del incipient_species_lineages[lineage_idx]
         else:
             raise Exception("Unexpected event type index: {}".format(event_type_idx))
コード例 #3
0
    def _run_protracted_speciation_process(self, **kwargs):
        self.reset()
        max_time = kwargs.get("max_time", None)
        max_extant_protracted_speciation_lineages = kwargs.get("max_extant_protracted_speciation_lineages", None)
        max_full_species = kwargs.get("max_full_species", None)
        is_correlate_protracted_speciation_and_full_speciation_trees = kwargs.get("is_correlate_protracted_speciation_and_full_speciation_trees", False)
        taxon_namespace = kwargs.get("taxon_namespace", None)

        is_full_species = not kwargs.get("is_initial_species_incipient", False)
        if is_full_species:
            initial_lineage = self._new_lineage(parent_lineage=None, is_full_species=True)
        else:
            initial_lineage = self._new_lineage(parent_lineage=None, is_full_species=False)
        seed_node = self._new_node(lineage=initial_lineage)
        protracted_speciation_tree = self.tree_factory( taxon_namespace=taxon_namespace, seed_node=seed_node)
        protracted_speciation_tree.is_rooted = True

        while True:

            ## Draw time to next event
            event_rates = []
            num_full_species = len(self.current_full_species_lineages)
            if max_full_species is not None:
                ## note: expensive operation to count leaves!
                try:
                    full_species_tree = self._assemble_full_species_tree(taxon_namespace=taxon_namespace)
                    num_leaves = len(full_species_tree.leaf_nodes())
                    if num_leaves >= max_full_species:
                        return self._postprocess_psm_and_full_species_trees(
                                full_species_tree=full_species_tree,
                                protracted_speciation_tree=protracted_speciation_tree,
                                is_correlate_protracted_speciation_and_full_speciation_trees=is_correlate_protracted_speciation_and_full_speciation_trees,
                                )
                except ProtractedSpeciationModel.ProcessFailedException:
                    pass

            num_incipient_species = len(self.current_incipient_species_lineages)
            if max_extant_protracted_speciation_lineages is not None and (num_incipient_species + num_full_species) >= max_extant_protracted_speciation_lineages:
                break

            # Event type 0
            event_rates.append(self.full_species_birth_rate * num_full_species)

            # Event type 1
            event_rates.append(self.full_species_extinction_rate * num_full_species)

            # Event type 2
            event_rates.append(self.incipient_species_birth_rate * num_incipient_species)

            # Event type 3
            event_rates.append(self.incipient_species_conversion_rate * num_incipient_species)

            # Event type 4
            event_rates.append(self.incipient_species_extinction_rate * num_incipient_species)

            # All events
            rate_of_any_event = sum(event_rates)

            # Waiting time
            waiting_time = self.rng.expovariate(rate_of_any_event)
            if max_time and (self.current_time + waiting_time) > max_time:
                t = max_time - self.current_time
                for lineage in itertools.chain(self.current_full_species_lineages, self.current_incipient_species_lineages):
                    lineage.node.edge.length += t
                self.current_time = max_time
                break
            self.current_time += waiting_time
            for lineage in itertools.chain(self.current_full_species_lineages, self.current_incipient_species_lineages):
                lineage.node.edge.length += waiting_time

            # Select event
            event_type_idx = probability.weighted_index_choice(weights=event_rates, rng=self.rng)
            assert (event_type_idx >= 0 and event_type_idx <= 4)
            # print("time {}: {}, selected = {}".format(self.current_time, event_rates, event_type_idx))

            if event_type_idx == 0:
                self._process_full_species_birth(protracted_speciation_tree)
            elif event_type_idx == 1:
                self._process_full_species_extinction(protracted_speciation_tree)
            elif event_type_idx == 2:
                self._process_incipient_species_birth(protracted_speciation_tree)
            elif event_type_idx == 3:
                self._process_incipient_species_conversion(protracted_speciation_tree)
            elif event_type_idx == 4:
                self._process_incipient_species_extinction(protracted_speciation_tree)
            else:
                raise Exception("Unexpected event type index: {}".format(event_type_idx))

            if len(self.current_full_species_lineages) + len(self.current_incipient_species_lineages) == 0:
                raise TreeSimTotalExtinctionException()

        full_species_tree = self._assemble_full_species_tree(taxon_namespace=taxon_namespace)
        return self._postprocess_psm_and_full_species_trees(
                protracted_speciation_tree=protracted_speciation_tree,
                full_species_tree=full_species_tree,
                is_correlate_protracted_speciation_and_full_speciation_trees=is_correlate_protracted_speciation_and_full_speciation_trees,
                )
コード例 #4
0
    def _run_protracted_speciation_process(self, **kwargs):
        self.reset()
        max_time = kwargs.get("max_time", None)
        max_extant_lineages = kwargs.get("max_extant_lineages", None)
        max_extant_orthospecies = kwargs.get("max_extant_orthospecies", None)
        is_correlate_lineage_and_species_trees = kwargs.get(
            "is_correlate_lineage_and_species_trees", False)
        taxon_namespace = kwargs.get("taxon_namespace", None)
        initial_lineage = self._new_lineage(
            parent_lineage=None,
            orthospecies_index=self.current_orthospecies_index,
            is_orthospecies=kwargs.get("is_initial_lineage_orthospecies",
                                       True),
        )
        seed_node = self._new_node(lineage=initial_lineage)
        lineage_tree = self.tree_factory(taxon_namespace=taxon_namespace,
                                         seed_node=seed_node)
        lineage_tree.is_rooted = True

        while True:

            ## Draw time to next event
            event_rates = []
            num_orthospecies = len(self.current_orthospecies_lineages)
            if max_extant_orthospecies is not None:
                ## note: expensive operation to count leaves!
                try:
                    orthospecies_tree = self._assemble_orthospecies_tree(
                        taxon_namespace=taxon_namespace)
                    num_leaves = len(orthospecies_tree.leaf_nodes())
                    if num_leaves >= max_extant_orthospecies:
                        return self._postprocess_psm_and_orthospecies_trees(
                            orthospecies_tree=orthospecies_tree,
                            lineage_tree=lineage_tree,
                            is_correlate_lineage_and_species_trees=
                            is_correlate_lineage_and_species_trees,
                        )
                except ProcessFailedException:
                    pass

            num_incipient_species = len(
                self.current_incipient_species_lineages)
            if max_extant_lineages is not None and (
                    num_incipient_species +
                    num_orthospecies) >= max_extant_lineages:
                break

            # Event type 0
            event_rates.append(
                self.speciation_initiation_from_orthospecies_rate *
                num_orthospecies)

            # Event type 1
            event_rates.append(self.orthospecies_extinction_rate *
                               num_orthospecies)

            # Event type 2
            event_rates.append(
                self.speciation_initiation_from_incipient_species_rate *
                num_incipient_species)

            # Event type 3
            event_rates.append(self.speciation_completion_rate *
                               num_incipient_species)

            # Event type 4
            event_rates.append(self.incipient_species_extinction_rate *
                               num_incipient_species)

            # All events
            rate_of_any_event = sum(event_rates)

            # Waiting time
            waiting_time = self.rng.expovariate(rate_of_any_event)
            if max_time and (self.current_time + waiting_time) > max_time:
                t = max_time - self.current_time
                for lineage in itertools.chain(
                        self.current_orthospecies_lineages,
                        self.current_incipient_species_lineages):
                    lineage.node.edge.length += t
                self.current_time = max_time
                break
            self.current_time += waiting_time
            for lineage in itertools.chain(
                    self.current_orthospecies_lineages,
                    self.current_incipient_species_lineages):
                lineage.node.edge.length += waiting_time

            # Select event
            event_type_idx = probability.weighted_index_choice(
                weights=event_rates, rng=self.rng)
            assert (event_type_idx >= 0 and event_type_idx <= 4)
            # print("time {}: {}, selected = {}".format(self.current_time, event_rates, event_type_idx))

            if event_type_idx == 0:
                self._process_initiation_of_speciation_from_orthospecies(
                    lineage_tree)
            elif event_type_idx == 1:
                self._process_orthospecies_extinction(lineage_tree)
            elif event_type_idx == 2:
                self._process_initiation_of_speciation_from_incipient_species(
                    lineage_tree)
            elif event_type_idx == 3:
                self._process_completion_of_specation(lineage_tree)
            elif event_type_idx == 4:
                self._process_incipient_species_extinction(lineage_tree)
            else:
                raise Exception(
                    "Unexpected event type index: {}".format(event_type_idx))

            if len(self.current_orthospecies_lineages) + len(
                    self.current_incipient_species_lineages) == 0:
                raise TreeSimTotalExtinctionException()

        orthospecies_tree = self._assemble_orthospecies_tree(
            taxon_namespace=taxon_namespace)
        return self._postprocess_psm_and_orthospecies_trees(
            lineage_tree=lineage_tree,
            orthospecies_tree=orthospecies_tree,
            is_correlate_lineage_and_species_trees=
            is_correlate_lineage_and_species_trees,
        )