diff --git a/include/emp/Evolve/NK.hpp b/include/emp/Evolve/NK.hpp index 099b17f799..5a45a34335 100644 --- a/include/emp/Evolve/NK.hpp +++ b/include/emp/Evolve/NK.hpp @@ -157,6 +157,21 @@ namespace emp { return GetFitness(n, cur_val); } + /// Get the fitness of a whole bitstring (pass by value so can be modified.) + emp::vector GetFitnesses(emp::BitVector genome) const { + // Use a double-length genome to easily handle wrap-around. + genome.Resize(N*2); + genome |= (genome << N); + emp::vector fits; + + size_t mask = emp::MaskLow(K+1); + for (size_t i = 0; i < N; i++) { + const size_t cur_val = (genome >> i).GetUInt(0) & mask; + const double cur_fit = GetFitness(i, cur_val); + fits.push_back(cur_fit); + } + return fits; + } void SetState(size_t n, size_t state, double in_fit) { landscape[n][state] = in_fit; } diff --git a/include/emp/Evolve/Systematics.hpp b/include/emp/Evolve/Systematics.hpp index c246e3619e..0f2637548d 100644 --- a/include/emp/Evolve/Systematics.hpp +++ b/include/emp/Evolve/Systematics.hpp @@ -1,34 +1,39 @@ /* * This file is part of Empirical, https://github.com/devosoft/Empirical * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * date: 2017-2023 + * date: 2024 */ /** * @file * @brief Track genotypes, species, clades, or lineages of organisms in a world. * - * @todo Technically, we don't need to keep the ancestors in a set in order to track a lineage... - * If we delete all of their descendants they should automaticaly be deleted. + * Note that this file powers the Python library phylotrackpy. The main consequence + * is that we should generally prefer emp_optional_throw to emp_assert in any circumstance + * where user input could trigger an error. emp_assert will trigger a segfault in Python + * (killing the whole interpreter), whereas emp_optional_throw will raise a Python exception. + * * @todo We should provide an option to back up systematics data to a file so that it doesn't all * need to be kept in memory, especially if we're only doing post-analysis. * @todo This inheritance system makes adding new systematics-related data tracking kind of a pain. - * Over time, this will probably become a maintainability problem. We can probably make the - * whole inheritance thing go away through judicious use of signals. - * @todo This does not currently handle situations where organisms change locations during their - * lifetimes gracefully. + * Over time, this will probably become a maintainability problem. We could make the inheritance + * go away and just use signals, but then the emp::World could not maintain systematics managers. */ #ifndef EMP_EVOLVE_SYSTEMATICS_HPP_INCLUDE #define EMP_EVOLVE_SYSTEMATICS_HPP_INCLUDE - +#include +#include #include #include #include #include -#include +#include +#include #include +#include "../base/assert_warning.hpp" +#include "../base/optional_throw.hpp" #include "../base/Ptr.hpp" #include "../control/Signal.hpp" #include "../data/DataFile.hpp" @@ -36,6 +41,7 @@ #include "../data/DataNode.hpp" #include "../datastructs/map_utils.hpp" #include "../datastructs/set_utils.hpp" +#include "../io/File.hpp" #include "../math/info_theory.hpp" #include "../math/stats.hpp" #include "../tools/string_utils.hpp" @@ -45,6 +51,9 @@ namespace emp { + template + class Systematics; + /// The systematics manager allows an optional second template type that /// can store additional data about each taxon in the phylogeny. Here are /// some structs containing common pieces of additional data to track. @@ -68,34 +77,41 @@ namespace emp { fitness.Add(fit); } - const double GetFitness() const { + double GetFitness() const { return fitness.GetMean(); } }; + /// Track information related to the mutational landscape + /// Maps a string representing a type of mutation to a count representing + /// the number of that type of mutation that occurred to bring about this taxon. template - struct mut_landscape_info { /// Track information related to the mutational landscape - /// Maps a string representing a type of mutation to a count representing - /// the number of that type of mutation that occurred to bring about this taxon. + struct mut_landscape_info { using phen_t = PHEN_TYPE; using has_phen_t = std::true_type; using has_mutations_t = std::true_type; using has_fitness_t = std::true_type; // using has_phenotype_t = true; - std::unordered_map mut_counts; + std::unordered_map mut_counts = {}; /// The number of mutations of each type that occurred to make this taxon DataNode fitness; /// This taxon's fitness (for assessing deleterious mutational steps) PHEN_TYPE phenotype; /// This taxon's phenotype (for assessing phenotypic change) + /// @returns this taxon's phenotype const PHEN_TYPE & GetPhenotype() const { return phenotype; } - const double GetFitness() const { + /// @returns this taxon's fitness + double GetFitness() const { return fitness.GetMean(); } - void RecordMutation(std::unordered_map muts) { + /// Adds mutations to the list of mutations that occurred to make this taxon + /// @param muts can contain as many strings (types of mutation) as desired, each accompanied + /// by a number indicating how many of that mutation occurred + /// Example: {"point_mutation":2, "insertion":1} + void RecordMutation(const std::unordered_map & muts) { for (auto mut : muts) { if (Has(mut_counts, mut.first)) { mut_counts[mut.first] += mut.second; @@ -105,10 +121,14 @@ namespace emp { } } + /// Record the fitness of this taxon + /// @param fit the fitness void RecordFitness(double fit) { fitness.Add(fit); } + /// Record the phenotype of this taxon + /// @param phen the phenotype void RecordPhenotype(PHEN_TYPE phen) { phenotype = phen; } @@ -124,6 +144,8 @@ namespace emp { /// track an evolutionary pathway) template class Taxon { + template + friend class Systematics; protected: using this_t = Taxon; using info_t = ORG_INFO; @@ -132,10 +154,10 @@ namespace emp { const info_t info; ///< Details for the organisms associated within this taxanomic group. Ptr parent; ///< Pointer to parent group (nullptr if injected) std::set > offspring; ///< Pointers to all immediate offspring taxa - size_t num_orgs; ///< How many organisms currently exist of this group? - size_t tot_orgs; ///< How many organisms have ever existed of this group? - size_t num_offspring; ///< How many direct offspring groups exist from this one. - size_t total_offspring; ///< How many total extant offspring taxa exist from this one (i.e. including indirect) + int num_orgs; ///< How many organisms currently exist of this group? + int tot_orgs; ///< How many organisms have ever existed of this group? + int num_offspring; ///< How many direct offspring groups exist from this one. + int total_offspring; ///< How many total extant offspring taxa exist from this one (i.e. including indirect) size_t depth; ///< How deep in tree is this node? (Root is 0) double origination_time; ///< When did this taxon first appear in the population? double destruction_time; ///< When did this taxon leave the population? @@ -173,26 +195,40 @@ namespace emp { /// Get the number of living organisms currently associated with this Taxon. size_t GetNumOrgs() const { return num_orgs; } + /// Set the number of living organisms currently associated with this Taxon. + void SetNumOrgs(size_t n) { num_orgs = n; } + /// Get the total number of organisms that have ever lived associated with this Taxon size_t GetTotOrgs() const { return tot_orgs; } + /// Set the total number of organisms that have ever lived associated with this Taxon + void SetTotOrgs(size_t n) { tot_orgs = n; } + /// Get the number of taxa that were produced by organisms from this Taxon. size_t GetNumOff() const { return num_offspring; } /// Get the number of taxanomic steps since the ancestral organism was injected into the World. size_t GetDepth() const { return depth; } + /// Get data struct associated with this taxon data_t & GetData() {return data;} + /// Get data struct associated with this taxon const data_t & GetData() const {return data;} + /// Get pointers to this taxon's offspring std::set > GetOffspring() {return offspring;} + /// Set this taxon's data struct to the given value void SetData(data_t d) {data = d;} + /// @returns this taxon's origination time double GetOriginationTime() const {return origination_time;} + /// Set this taxon's origination time void SetOriginationTime(double time) {origination_time = time;} + /// @returns this taxon's destruction time double GetDestructionTime() const {return destruction_time;} + /// Sets this taxon's destruction time void SetDestructionTime(double time) {destruction_time = time;} /// Add a new organism to this Taxon. @@ -221,20 +257,21 @@ namespace emp { /// Remove an organism from this Taxon (after it dies). /// Removals must return true if the taxon needs to continue; false if it should deactivate. bool RemoveOrg() { - emp_assert(num_orgs > 0, num_orgs); + emp_optional_throw(num_orgs > 0, "Removing org from extinct taxon"); --num_orgs; // If we are out of BOTH organisms and offspring, this Taxon should deactivate. return num_orgs; } + /// Remove specified taxon from this taxon's offspring list void RemoveFromOffspring(Ptr offspring_tax) { offspring.erase(offspring_tax); } /// Remove and offspring taxa after its entire sub-tree has died out (pruning) bool RemoveOffspring(Ptr offspring_tax) { - emp_assert(num_offspring > 0, num_offspring, id); + emp_optional_throw(num_offspring > 0, "Removing more offspring than exist"); --num_offspring; RemoveFromOffspring(offspring_tax); @@ -254,8 +291,8 @@ namespace emp { /// A base class for Systematics, maintaining information common to all systematics managers - /// and providing virtual functions. - + /// and providing virtual functions. You probably don't want to instantiate this. It just + /// exists so that you can make containers of Systematics managers of different types. template class SystematicsBase { protected: @@ -269,8 +306,8 @@ namespace emp { // Stats about active taxa... (totals are across orgs, not taxa) size_t org_count; ///< How many organisms are currently active? size_t total_depth; ///< Sum of taxa depths for calculating average. - size_t num_roots; ///< How many distint injected ancestors are currently in population? - int max_depth; ///< Depth of deepest taxon. -1 means needs to be recalculated + size_t num_roots; ///< How many distinct injected ancestors are currently in population? + mutable int max_depth; ///< Depth of deepest taxon. -1 means needs to be recalculated size_t next_id; ///< What ID value should the next new taxon have? size_t curr_update; @@ -318,6 +355,9 @@ namespace emp { /// What is the average phylogenetic depth of organisms in the population? double GetAveDepth() const { return ((double) total_depth) / (double) org_count; } + /// @returns current update/time step + size_t GetUpdate() const {return curr_update;} + /// Are we tracking organisms evolving in synchronous generations? void SetTrackSynchronous(bool new_val) {track_synchronous = new_val; } @@ -336,29 +376,37 @@ namespace emp { /// Are we storing the location of taxa? void SetStorePosition(bool new_val) { store_position = new_val; } - // Returns a reference so that capturing it in a lambda to call on update - // is less confusing. It's possible we should change it to be consistent - // with GetFitnessDataNode, though. + /// Sets the current update/time step + void SetUpdate(size_t ud) {curr_update = ud;} + + /// Add a data node to this systematics manager + /// @param name the name of the data node (so it can be found later) data_ptr_t AddDataNode(const std::string & name) { - emp_assert(!data_nodes.HasNode(name)); + emp_optional_throw(data_nodes.HasNoNode(name), "Invalid node name, already exists"); return &(data_nodes.New(name)); } + /// Add a data node to this systematics manager + /// @param name the name of the data node (so it can be found later) + /// @param pull_set_fun a function to run when the data node is requested to pull data (returns vector of values) data_ptr_t AddDataNode(std::function()> pull_set_fun, const std::string & name) { - emp_assert(!data_nodes.HasNode(name)); + emp_optional_throw(data_nodes.HasNoNode(name), "Invalid node name, already exists"); auto node = AddDataNode(name); node->AddPullSet(pull_set_fun); return node; } + /// Add a data node to this systematics manager + /// @param name the name of the data node (so it can be found later) + /// @param pull_fun a function to run when the data node is requested to pull data (returns single value) data_ptr_t AddDataNode(std::function pull_fun, const std::string & name) { - emp_assert(!data_nodes.HasNode(name)); + emp_optional_throw(data_nodes.HasNoNode(name), "Invalid node name, already exists"); auto node = AddDataNode(name); node->AddPull(pull_fun); return node; } - + /// @returns a pointer to the data node with the specified name data_ptr_t GetDataNode(const std::string & name) { return &(data_nodes.Get(name)); } @@ -376,34 +424,41 @@ namespace emp { virtual size_t GetNumOutside() const = 0; virtual size_t GetTreeSize() const = 0; virtual size_t GetNumTaxa() const = 0; - virtual int GetMaxDepth() = 0; + virtual int GetMaxDepth() const = 0; virtual int GetPhylogeneticDiversity() const = 0; virtual double GetMeanPairwiseDistance(bool branch_only) const = 0; + virtual double GetSumDistance() const = 0; virtual double GetSumPairwiseDistance(bool branch_only) const = 0; virtual double GetVariancePairwiseDistance(bool branch_only) const = 0; virtual emp::vector GetPairwiseDistances(bool branch_only) const = 0; virtual int SackinIndex() const = 0; virtual double CollessLikeIndex() const = 0; + virtual std::unordered_map GetOutDegreeDistribution() const = 0; + virtual double GetAverageOriginTime(bool) const = 0; virtual int GetMRCADepth() const = 0; - virtual void AddOrg(ORG && org, WorldPosition pos, int update) = 0; - virtual void AddOrg(ORG & org, WorldPosition pos, int update) = 0; - virtual bool RemoveOrg(WorldPosition pos, int time=-1) = 0; - virtual void RemoveOrgAfterRepro(WorldPosition pos, int time=-1) = 0; - // virtual bool RemoveNextOrg(WorldPosition pos, int time=-1) = 0; + virtual void AddOrg(ORG && org, WorldPosition pos) = 0; + virtual void AddOrg(ORG & org, WorldPosition pos) = 0; + virtual void AddOrg(ORG && org, WorldPosition pos, WorldPosition parent) = 0; + virtual void AddOrg(ORG & org, WorldPosition pos, WorldPosition parent) = 0; + virtual bool RemoveOrg(WorldPosition pos) = 0; + virtual void RemoveOrgAfterRepro(WorldPosition pos) = 0; virtual void PrintStatus(std::ostream & os) const = 0; virtual double CalcDiversity() const = 0; virtual void Update() = 0; - virtual void SetNextParent(int pos) = 0; - virtual void SetNextParent(WorldPosition & pos) = 0; + virtual void SetNextParent(WorldPosition pos) = 0; + virtual void SwapPositions(WorldPosition p1, WorldPosition p2) = 0; }; + // Forward-declare CollessStruct for use in calculating Colless metric + struct CollessStruct; + /// @brief A tool to track phylogenetic relationships among organisms. /// The systematics class tracks the relationships among all organisms based on the INFO_TYPE /// provided. If an offspring has the same value for INFO_TYPE as its parent, it is grouped into /// the same taxon. Otherwise a new Taxon is created and the old one is used as its parent in - /// the phylogeny. If the provided INFO_TYPE is the organsism's genome, a traditional phylogeny + /// the phylogeny. If the provided INFO_TYPE is the organism's genome, a traditional phylogeny /// is formed, with genotypes. If the organism's behavior/task set is used, then organisms are - /// grouped by phenotypes. If the organsims's position is used, the evolutionary path through + /// grouped by phenotypes. If the organism's position is used, the evolutionary path through /// space is tracked. Any other aspect of organisms can be tracked this way as well. template class Systematics : public SystematicsBase { @@ -416,9 +471,13 @@ namespace emp { using hash_t = typename Ptr::hash_t; using fun_calc_info_t = std::function; - fun_calc_info_t calc_info_fun; - Ptr next_parent; - Ptr most_recent; + fun_calc_info_t calc_info_fun; ///< Function that takes an organism and returns the unit being tracked by systematics + Ptr next_parent; ///< The taxon that has been marked as parent for next new org + Ptr most_recent; ///< The most-recently added taxon + bool num_orgs_defaulted = false; ///< Keep track of whether we have loaded from a file that didn't + /// provide num_orgs + bool total_offspring_defaulted = false; ///< Keep track of whether we have loaded from a file without + /// recalculating total offspring using parent_t::store_active; using parent_t::store_ancestors; @@ -441,28 +500,23 @@ namespace emp { using parent_t::GetNumOutside; using parent_t::GetTreeSize; using parent_t::GetNumTaxa; - // using parent_t::OnNew; - // using parent_t::OnPrune; using parent_t::GetPhylogeneticDiversity; - // using parent_t::GetTaxonDistinctiveness; - // using parent_t::GetEvolutionaryDistinctiveness; using parent_t::GetMeanPairwiseDistance; + using parent_t::GetSumDistance; using parent_t::GetSumPairwiseDistance; using parent_t::GetVariancePairwiseDistance; using parent_t::GetPairwiseDistances; - // using parent_t::GetDistanceToRoot; - // using parent_t::GetBranchesToRoot; - // using parent_t::GetMRCA; + using parent_t::GetOutDegreeDistribution; + using parent_t::GetAverageOriginTime; using parent_t::GetMRCADepth; using parent_t::AddOrg; using parent_t::RemoveOrg; using parent_t::RemoveOrgAfterRepro; - // using parent_t::RemoveNextOrg; - // using parent_t::Parent; using parent_t::PrintStatus; - // using parent_t::PrintLineage; using parent_t::CalcDiversity; using parent_t::Update; + using parent_t::GetUpdate; + using parent_t::SetUpdate; using parent_t::SetNextParent; using parent_t::GetDataNode; @@ -476,11 +530,12 @@ namespace emp { using parent_t::AddMutationCountDataNode; using parent_t::GetMaxDepth; + /// Struct for keeping track of what information to print out in snapshot files struct SnapshotInfo { using snapshot_fun_t = std::function; - snapshot_fun_t fun; - std::string key; - std::string desc; + snapshot_fun_t fun; ///< Function for converting taxon to string containing desired data + std::string key; ///< Column name for data calculated with this function + std::string desc; ///< Description of data in this function SnapshotInfo(const snapshot_fun_t & _fun, const std::string & _key, const std::string & _desc="") : fun(_fun), @@ -489,32 +544,40 @@ namespace emp { { ; } }; - emp::vector user_snapshot_funs; + emp::vector user_snapshot_funs; ///< Collection of all desired snapshot file columns std::unordered_set< Ptr, hash_t > active_taxa; ///< A set of all living taxa. std::unordered_set< Ptr, hash_t > ancestor_taxa; ///< A set of all dead, ancestral taxa. std::unordered_set< Ptr, hash_t > outside_taxa; ///< A set of all dead taxa w/o descendants. - Ptr to_be_removed = nullptr; - int removal_time = -1; - int removal_pos = -1; + Ptr to_be_removed = nullptr; ///< Taxon to remove org from after next call to AddOrg + emp::WorldPosition removal_pos = {0, 0}; ///< Position of taxon to next be removed - emp::vector > taxon_locations; - emp::vector > next_taxon_locations; + emp::vector > > taxon_locations; ///< Positions in this vector indicate taxon positions in world - Signal, ORG & org)> on_new_sig; ///< Trigger when any organism is pruned from tree + Signal, ORG & org)> on_new_sig; ///< Trigger when a new taxon is created + Signal)> on_extinct_sig; ///< Trigger when a taxon goes extinct Signal)> on_prune_sig; ///< Trigger when any organism is pruned from tree mutable Ptr mrca; ///< Most recent common ancestor in the population. - /// Called wheneven a taxon has no organisms AND no descendants. + /// Called whenever a taxon has no organisms AND no descendants. void Prune(Ptr taxon); /// Called when an offspring taxa has been deleted. void RemoveOffspring(Ptr offspring, Ptr taxon); /// Called when there are no more living members of a taxon. There may be descendants. - void MarkExtinct(Ptr taxon, int time=-1); + void MarkExtinct(Ptr taxon); + + #ifndef DOXYGEN_SHOULD_SKIP_THIS + /// Helper function for RemoveBefore + /// @returns true if a a taxon can safely be + /// removed by RemoveBefore + bool CanRemove(Ptr t, int ud); + // Helper for Colless function calculation + CollessStruct RecursiveCollessStep(Ptr curr) const; + #endif // DOXYGEN_SHOULD_SKIP_THIS @@ -522,6 +585,7 @@ namespace emp { /** * Contructor for Systematics; controls what information should be stored. + * @param calc_taxon A function that takes an organism and calculates what taxon it belongs to * @param store_active Should living organisms' taxa be tracked? (typically yes!) * @param store_ancestors Should ancestral organisms' taxa be maintained? (yes for lineages!) * @param store_all Should all dead taxa be maintained? (typically no; it gets BIG!) @@ -545,100 +609,271 @@ namespace emp { outside_taxa.clear(); } + // ===== Functions for modifying phylogeny/systematics manager internal state ==== - void Update() { - ++curr_update; - if (track_synchronous) { + /// Switch to next update/time step + /// Useful for keeping track of taxon survival times + /// and population positions in synchronous generation worlds. + void Update(); - // Clear pending removal - if (to_be_removed != nullptr) { - RemoveOrg(to_be_removed, removal_time); - taxon_locations[removal_pos] = nullptr; - to_be_removed = nullptr; - removal_pos = -1; - } - - std::swap(taxon_locations, next_taxon_locations); - next_taxon_locations.resize(0); + ///@{ + /// Add information about a new organism, including its stored info and parent's taxon; + /// If you would like the systematics manager to track taxon age, you can also supply + /// the update at which the taxon is being added. + /// @returns a pointer for the associated taxon. + /// @param org a reference to the organism being added + /// @param pos the position of the organism being added + /// @param parent a pointer to the org's parent + void AddOrg(ORG && org, WorldPosition pos); + void AddOrg(ORG && org, WorldPosition pos, WorldPosition parent); + Ptr AddOrg(ORG && org, WorldPosition pos, Ptr parent); + Ptr AddOrg(ORG && org, Ptr parent=nullptr); + + void AddOrg(ORG & org, WorldPosition pos); + void AddOrg(ORG & org, WorldPosition pos, WorldPosition parent); + Ptr AddOrg(ORG & org, WorldPosition pos, Ptr parent); + Ptr AddOrg(ORG & org, Ptr parent=nullptr); + ///@} + + ///@{ + /// Remove an instance of an organism; track when it's gone. + /// @param pos the world position of the individual being removed + /// @param taxon a pointer to the taxon of the individual being removed + bool RemoveOrg(WorldPosition pos); + bool RemoveOrg(Ptr taxon); + ///@} + + ///@{ + /// Mark an instance of a taxon to be removed; track when it's gone. + /// This is a work-around to deal with steady state/non-synchronous + /// populations in which an organism might die as its offspring is born + /// (e.g. in a spatial world where the offspring replaces the parent). + /// If the bookkeeping is not handled correctly, we could accidentally + /// mark the taxon as extinct when it is actually continuing. + /// By using this method, the taxon won't be removed until after the + /// next org is added or the next time an org is marked for removal. + /// @param pos the world position of the individual being removed + /// @param taxon a pointer to the taxon of the individual being removed + void RemoveOrgAfterRepro(WorldPosition pos); + void RemoveOrgAfterRepro(Ptr taxon); + ///@} + + + ///@{ + /// Tell systematics manager that the parent of the next taxon added + /// will be the one specified by this function (either at the specified + /// position or the one pointed to by the given pointer) + /// Works with version of AddOrg that only takes org, position, and + /// update. + /// Will be set to null after being assigned as the parent of a taxon + void SetNextParent(WorldPosition pos) { + emp_optional_throw(pos.IsActive() || !pos.IsValid(), "Invalid position"); + if (!pos.IsValid()) { + next_parent = nullptr; + } else { + next_parent = taxon_locations[pos.GetPopID()][pos.GetIndex()]; } } + void SetNextParent(Ptr p) { + next_parent = p; + } + ///@} + + /// Set function used to calculate taxons from organisms void SetCalcInfoFun(fun_calc_info_t f) {calc_info_fun = f;} - // Currently using raw pointers because of a weird bug in emp::Ptr. Should switch when fixed. + /// Remove all taxa that 1) went extinct before the specified update/time step, + /// and 2) only have ancestors that went extinct before the specified update/time step. + /// Warning: this function invalidates most measurements you could make about tree topology. + /// It is useful in select situations where you need to store ancestors for some period of time, + /// but cannot computationally afford to store all ancestors for your entire run. + void RemoveBefore(int ud); + + /// Run the given function on every active taxon (const version) + /// @param fun the function to run on each taxon + void ApplyToActiveTaxa(const std::function tax)> & fun) const { + std::for_each(active_taxa.begin(), active_taxa.end(), fun); + } + + /// Run the given function on every active taxon + /// @param fun the function to run on each taxon + void ApplyToActiveTaxa(const std::function tax)> & fun) { + std::for_each(active_taxa.begin(), active_taxa.end(), fun); + } + + /// Run the given function on every ancestor taxon (const version) + /// @param fun the function to run on each taxon + void ApplyToAncestorTaxa(const std::function tax)> & fun) const { + std::for_each(ancestor_taxa.begin(), ancestor_taxa.end(), fun); + } + + /// Run the given function on every ancestor taxon + /// @param fun the function to run on each taxon + void ApplyToAncestorTaxa(const std::function tax)> & fun) { + std::for_each(ancestor_taxa.begin(), ancestor_taxa.end(), fun); + } + + /// Run the given function on every outside taxon (const version) + /// @param fun the function to run on each taxon + void ApplyToOutsideTaxa(const std::function tax)> & fun) const { + std::for_each(outside_taxa.begin(), outside_taxa.end(), fun); + } + + /// Run the given function on every outside taxon + /// @param fun the function to run on each taxon + void ApplyToOutsideTaxa(const std::function tax)> & fun) { + std::for_each(outside_taxa.begin(), outside_taxa.end(), fun); + } + + /// Run given function on all taxa (const version) + /// @param fun the function to run on each taxon + void ApplyToAllTaxa(const std::function tax)> & fun) const { + ApplyToActiveTaxa(fun); + ApplyToAncestorTaxa(fun); + ApplyToOutsideTaxa(fun); + } + + /// Run given function on all taxa + /// @param fun the function to run on each taxon + void ApplyToAllTaxa(const std::function tax)> & fun) { + ApplyToActiveTaxa(fun); + ApplyToAncestorTaxa(fun); + ApplyToOutsideTaxa(fun); + } + + /// Run given function on all taxa and return result (const version) + /// @param fun the function to run on each taxon + /// @returns a vector containing the results of running the function on each taxon + template + emp::vector ApplyToAllTaxa(const std::function tax)> & fun) const { + emp::vector result; + // TODO: Swap in this version when we update to c++23 and range support is available on more compilers + // const auto all = {std::ranges::ref_view(active_taxa), std::ranges::ref_view(ancestor_taxa), + // std::ranges::ref_view(outside_taxa)}; + // for (emp::Ptr tax : all | std::views::join) { + // result.push_back(fun(tax)); + // } + for (emp::Ptr tax : active_taxa) { + result.push_back(fun(tax)); + } + for (emp::Ptr tax : ancestor_taxa) { + result.push_back(fun(tax)); + } + for (emp::Ptr tax : ancestor_taxa) { + result.push_back(fun(tax)); + } + return result; + } + + /// Run given function on all taxa and return result (const version) + /// @param fun the function to run on each taxon + /// @returns a vector containing the results of running the function on each taxon + template + emp::vector ApplyToAllTaxa(const std::function tax)> & fun) { + emp::vector result; + // TODO: Swap in this version when we update to c++23 and range support is available on more compilers + // const auto all = {std::ranges::ref_view(active_taxa), + // std::ranges::ref_view(ancestor_taxa), + // std::ranges::ref_view(outside_taxa)}; + // for (emp::Ptr tax : all | std::views::join) { + for (emp::Ptr tax : active_taxa) { + result.push_back(fun(tax)); + } + for (emp::Ptr tax : ancestor_taxa) { + result.push_back(fun(tax)); + } + for (emp::Ptr tax : ancestor_taxa) { + result.push_back(fun(tax)); + } + + return result; + } + + // ===== Functions for querying phylogeny/systematics manager internal state ==== + + // Currently using raw pointer because of a weird bug in emp::Ptr. Should switch when fixed. std::unordered_set< Ptr, hash_t > * GetActivePtr() { return &active_taxa; } + /// @returns set of active (extant/living) taxa0 const std::unordered_set< Ptr, hash_t > & GetActive() const { return active_taxa; } + /// @returns set of ancestor taxa (extinct, but have active descendants) const std::unordered_set< Ptr, hash_t > & GetAncestors() const { return ancestor_taxa; } + /// @returns set of outside taxa (extinct, with no active descendants) const std::unordered_set< Ptr, hash_t > & GetOutside() const { return outside_taxa; } - /// How many taxa are still active in the population? + /// @returns the number of taxa that are still active in the population size_t GetNumActive() const { return active_taxa.size(); } - /// How many taxa are ancestors of living organisms (but have died out themselves)? + /// @returns the number of taxa that are ancestors of living organisms (but have died out themselves) size_t GetNumAncestors() const { return ancestor_taxa.size(); } - /// How many taxa are stored that have died out, as have their descendents? + /// @returns the number of taxa that are stored that have died out, as have their descendents size_t GetNumOutside() const { return outside_taxa.size(); } - /// How many taxa are in the current phylogeny? + /// @returns the number of taxa that are in the current phylogeny size_t GetTreeSize() const { return GetNumActive() + GetNumAncestors(); } - /// How many taxa are stored in total? + /// @returns the number of taxa that are stored in total size_t GetNumTaxa() const { return GetTreeSize() + GetNumOutside(); } - int GetMaxDepth() { - if (max_depth != -1) { - return max_depth; - } + /// @returns the phylogenetic depth (lineage length) of the taxon with + /// the longest lineage out of all active taxa + int GetMaxDepth() const; - for (auto tax : active_taxa) { - int depth = tax->GetDepth(); - if (depth > max_depth) { - max_depth = depth; - } - } - return max_depth; + /// @returns the taxon that will be used as the parent + /// of the next taxon created via the version of AddOrg + /// that does not accept a parent + Ptr GetNextParent() const { + return next_parent; } - void SetNextParent(WorldPosition & pos) { - emp_assert(pos.IsActive() || !pos.IsValid()); - if (!pos.IsValid()) { - next_parent = nullptr; - } else { - next_parent = taxon_locations[pos.GetIndex()]; - } + /// @returns the most recently created taxon + Ptr GetMostRecent() const { + return most_recent; } - void SetNextParent(int pos) { - emp_assert(pos < (int)taxon_locations.size(), "Invalid parent", pos, taxon_locations.size()); - if (pos == -1) { - next_parent = nullptr; - } else { - emp_assert(pos >= 0, "Invalid parent", pos); - emp_assert(taxon_locations[pos], pos); - next_parent = taxon_locations[pos]; + /// @returns a pointer to the parent of a given taxon + Ptr Parent(Ptr taxon) const; + + /// @returns true if there is a taxon at specified location + bool IsTaxonAt(WorldPosition id) const { + if (id.GetPopID() >= taxon_locations.size()) { + return false; + } + if (id.GetIndex() >= taxon_locations[id.GetPopID()].size()) { + return false; } + return taxon_locations[id.GetPopID()][id.GetIndex()] != nullptr; } - void SetNextParent(Ptr p) { - next_parent = p; + /// @returns pointer to taxon at specified location + Ptr GetTaxonAt(WorldPosition id) const { + emp_optional_throw(id.GetPopID() < taxon_locations.size(), "Invalid population id"); + emp_optional_throw(id.GetIndex() < taxon_locations[id.GetPopID()].size(), "Invalid taxon location"); + return taxon_locations[id.GetPopID()][id.GetIndex()]; } - Ptr GetNextParent() { - return next_parent; - } + // ===== Functions for adding actions to systematics manager signals ==== - Ptr GetMostRecent() { - return most_recent; - } + /// Provide a function for Systematics to call each time a new taxon is created. + /// Trigger: New taxon is made + /// Argument: Pointer to taxon, reference to org taxon was created from + SignalKey OnNew(std::function t, ORG & org)> & fun) { return on_new_sig.AddAction(fun); } - SignalKey OnNew(std::function, ORG & org)> & fun) { return on_new_sig.AddAction(fun); } + /// Provide a function for Systematics to call each time a taxon goes extinct. + /// Trigger: Taxon is going extinct + /// Argument: Pointer to taxon + SignalKey OnExtinct(std::function t)> & fun) { return on_extinct_sig.AddAction(fun); } - /// Privide a function for Systematics to call each time a taxon is about to be pruned. + /// Provide a function for Systematics to call each time a taxon is about to be pruned (removed from ancestors). /// Trigger: Taxon is about to be killed /// Argument: Pointer to taxon SignalKey OnPrune(std::function)> & fun) { return on_prune_sig.AddAction(fun); } + // ===== Functions for adding data nodes to systematics manager ==== + + /// Add data node that records evolutionary distinctiveness when requested to pull. + /// Used by AddPhylodiversityFile in World_output.hpp virtual data_ptr_t AddEvolutionaryDistinctivenessDataNode(const std::string & name = "evolutionary_distinctiveness") { auto node = AddDataNode(name); @@ -653,6 +888,8 @@ namespace emp { return node; } + /// Add data node that records pairwise distance when requested to pull. + /// Used by AddPhylodiversityFile in World_output.hpp virtual data_ptr_t AddPairwiseDistanceDataNode(const std::string & name = "pairwise_distance") { auto node = AddDataNode(name); node->AddPullSet([this](){ @@ -661,6 +898,8 @@ namespace emp { return node; } + /// Add data node that records phylogenetic distinctiveness when requested to pull. + /// Used by AddPhylodiversityFile in World_output.hpp virtual data_ptr_t AddPhylogeneticDiversityDataNode(const std::string & name = "phylogenetic_diversity") { auto node = AddDataNode(name); node->AddPull([this](){ @@ -669,133 +908,94 @@ namespace emp { return node; } - + /// Add data node that records counts of deleterious steps along + /// lineages in this systematics manager when requested to pull. + /// Used by AddLineageMutationFile in World_output.hpp virtual data_ptr_t AddDeleteriousStepDataNode(const std::string & name = "deleterious_steps") { - return AddDeleteriousStepDataNodeImpl(1, name); - } - - data_ptr_t AddDeleteriousStepDataNodeImpl(bool decoy, const std::string & name = "deleterious_steps") { - emp_assert(false, "Calculating deleterious steps requires suitable DATA_STRUCT"); - return AddDataNode(name); - } - - template - data_ptr_t - AddDeleteriousStepDataNodeImpl(typename std::enable_if::type decoy, const std::string & name = "deleterious_steps") { auto node = AddDataNode(name); - node->AddPullSet([this](){ - emp::vector result; - for (auto tax : active_taxa) { - result.push_back(CountDeleteriousSteps(tax)); - } - return result; - }); + if constexpr (!DATA_STRUCT::has_fitness_t::value) { + emp_optional_throw(false, + "Error: Trying to track deleterious steps in Systematics manager that doesn't track fitness. Please use a DATA_STRUCT type that supports fitness tracking."); + } else { + node->AddPullSet([this](){ + emp::vector result; + std::transform(active_taxa.begin(), active_taxa.end(), std::back_inserter(result), + [this](Ptr tax) { return CountDeleteriousSteps(tax); }); + return result; + }); + } return node; } + /// Add data node that phenotypic volatility (changes in phenotype) along + /// lineages in this systematics manager when requested to pull. + /// Used by AddLineageMutationFile in World_output.hpp virtual data_ptr_t AddVolatilityDataNode(const std::string & name = "volatility") { - return AddVolatilityDataNodeImpl(1, name); - } - - data_ptr_t AddVolatilityDataNodeImpl(bool decoy, const std::string & name = "volatility") { - emp_assert(false, "Calculating taxon volatility requires suitable DATA_STRUCT"); - return AddDataNode(name); - } - - template - data_ptr_t - AddVolatilityDataNodeImpl(typename std::enable_if::type decoy, const std::string & name = "volatility") { auto node = AddDataNode(name); - node->AddPullSet([this](){ - emp::vector result; - for (auto tax : active_taxa) { - result.push_back(CountPhenotypeChanges(tax)); - } - return result; - }); + if constexpr (!DATA_STRUCT::has_phen_t::value) { + emp_optional_throw(false, + "Error: Trying to track phenotypic volatility in Systematics manager that doesn't track fitness. Please use a DATA_STRUCT type that supports phenotype tracking."); + } else { + node->AddPullSet([this](){ + emp::vector result; + std::transform(active_taxa.begin(), active_taxa.end(), std::back_inserter(result), + [this](Ptr tax) { return CountPhenotypeChanges(tax); }); + return result; + }); + } return node; } + /// Add data node that records counts of unique taxa along + /// lineages in this systematics manager when requested to pull. + /// Used by AddLineageMutationFile in World_output.hpp virtual data_ptr_t AddUniqueTaxaDataNode(const std::string & name = "unique_taxa") { - return AddUniqueTaxaDataNodeImpl(1, name); - } + auto node = AddDataNode(name); - data_ptr_t AddUniqueTaxaDataNodeImpl(bool decoy, const std::string & name = "unique_taxa") { - emp_assert(false, "Calculating unique taxa requires suitable DATA_STRUCT"); - return AddDataNode(name); - } + if constexpr (!DATA_STRUCT::has_phen_t::value) { + emp_optional_throw(false, + "Error: Trying to track phenotypic volatility in Systematics manager that doesn't track fitness. Please use a DATA_STRUCT type that supports phenotype tracking."); + } else { - template - data_ptr_t - AddUniqueTaxaDataNodeImpl(typename std::enable_if::type decoy, const std::string & name = "unique_taxa") { - auto node = AddDataNode(name); - node->AddPullSet([this](){ - emp::vector result; - for (auto tax : active_taxa) { - result.push_back(CountUniquePhenotypes(tax)); - } - return result; - }); + node->AddPullSet([this](){ + emp::vector result; + std::transform(active_taxa.begin(), active_taxa.end(), std::back_inserter(result), + [this](Ptr tax) { return CountUniquePhenotypes(tax); }); + return result; + }); + } return node; } + /// Add data node that records counts of mutations of the specified type along + /// lineages in this systematics manager when requested to pull. + /// Used by AddLineageMutationFile in World_output.hpp virtual data_ptr_t AddMutationCountDataNode(const std::string & name = "mutation_count", const std::string & mutation = "substitution") { - return AddMutationCountDataNodeImpl(1, name, mutation); - } - - data_ptr_t AddMutationCountDataNodeImpl(bool decoy, const std::string & name = "mutation_count", const std::string & mutation = "substitution") { - emp_assert(false, "Calculating mutation count requires suitable DATA_STRUCT"); - return AddDataNode(name); - } - - template - data_ptr_t - AddMutationCountDataNodeImpl(typename std::enable_if::type decoy, const std::string & name = "mutation_count", const std::string & mutation = "substitution") { auto node = AddDataNode(name); - node->AddPullSet([this,mutation](){ - emp::vector result; - for (auto tax : active_taxa) { - result.push_back(CountMuts(tax, mutation)); - } - return result; - }); + if constexpr (!DATA_STRUCT::has_mutations_t::value) { + emp_optional_throw(false, + "Error: Trying to track phenotypic volatility in Systematics manager that doesn't track mutations. Please use a DATA_STRUCT type that supports mutation tracking."); + } else { + node->AddPullSet([this,mutation](){ + emp::vector result; + std::transform(active_taxa.begin(), active_taxa.end(), std::back_inserter(result), + [this,mutation](Ptr tax) { return CountMuts(tax, mutation); }); + return result; + }); + } return node; } - /// Add a new snapshot function. - /// When a snapshot of the systematics is taken, in addition to the default - /// set of functions, all user-added snapshot functions are run. Functions - /// take a reference to a taxon as input and return the string to be dumped - /// in the file at the given key. - void AddSnapshotFun(const std::function & fun, - const std::string & key, const std::string & desc="") { - user_snapshot_funs.emplace_back(fun, key, desc); - } - - bool IsTaxonAt(int id) { - emp_assert(id < (int) taxon_locations.size(), "Invalid taxon location", id, taxon_locations.size()); - return taxon_locations[id]; - } - - Ptr GetTaxonAt(int id) { - emp_assert(id < (int) taxon_locations.size(), "Invalid taxon location", id, taxon_locations.size()); - emp_assert(taxon_locations[id], "No taxon at specified location"); - return taxon_locations[id]; - } - Ptr GetNextTaxonAt(int id) { - emp_assert(id < (int)next_taxon_locations.size(), "Invalid taxon location"); - emp_assert(next_taxon_locations[id], "No taxon at specified location"); - return next_taxon_locations[id]; - } + // ===== Functions for calculating phylogeny topology metrics ==== /** From (Faith 1992, reviewed in Winters et al., 2013), phylogenetic diversity is * the sum of edges in the minimal spanning tree connected the taxa you're @@ -812,78 +1012,73 @@ namespace emp { int GetPhylogeneticDiversity() const { // As shown on page 5 of Faith 1992, when all branch lengths are equal the phylogenetic // diversity is the number of internal nodes plus the number of extant taxa - 1. + //int phylodiversity = ancestor_taxa.size() + active_taxa.size() -1; + return ancestor_taxa.size() + active_taxa.size() - 1; } - /** This is a metric of how distinct @param tax is from the rest of the population. + + /// @returns phylogenetic diversity if used without any arguments . + /// If you want to receive normalized data, you need to include the number of generations + /// your tree has + /// you also need to specify a file with which to normalize your data. + /// If value is outside of the values in the file, 100th percentile will be returned + /// NOTE: This is experimental and in early development/research phases! + int GetPhylogeneticDiversityNormalize(int generation = 0, std::string filename = "") const; + + + /** This is a metric of how distinct \c tax is from the rest of the population. * - * (From Vane-Wright et al., 1991; reviewed in Winter et al., 2013) - */ + * (From Vane-Wright et al., 1991; reviewed in Winter et al., 2013) */ double GetTaxonDistinctiveness(Ptr tax) const {return 1.0/GetDistanceToRoot(tax);} /** This metric (from Isaac, 2007; reviewed in Winter et al., 2013) measures how - * distinct @param tax is from the rest of the population, weighted for the amount of + * distinct \c tax is from the rest of the population, weighted for the amount of * unique evolutionary history that it represents. * - * To quantify length of evolutionary history, this method needs @param time: the current + * To quantify length of evolutionary history, this method needs \c time: the current * time, in whatever units time is being measured in when taxa are added to the systematics - * manager. Note that passing a time in the past will produce inacurate results (since we + * manager. Note that passing a time in the past will produce inaccurate results (since we * don't know what the state of the tree was at that time). * - * Assumes the tree is all connected. Will return -1 if this assumption isn't met. - */ - double GetEvolutionaryDistinctiveness(Ptr tax, double time) const { - - double depth = 0; // Length (in time units) of section we're currently exploring - double total = 0; // Count up scores for each section of tree - double divisor = tax->GetTotalOffspring() + 1; // Number of extant taxa this will split into (1 for current taxa, plus its offspring) + * Assumes the tree is all connected. Will return -1 if this assumption isn't met.*/ + double GetEvolutionaryDistinctiveness(Ptr tax, double time) const; - // We're stopping when we hit MRCA, so we need to make sure it's been calculated. - GetMRCA(); - if (tax == mrca) { - return 0; + /** @returns A vector of evolutionary distinctiveness of all active taxa + * @param time The time step at which the calculation is being done + */ + emp::vector GetAllEvolutionaryDistinctivenesses(double time) const { + emp::vector eds; + for (emp::Ptr tax : active_taxa) { + if (tax->GetOriginationTime() <= time) { + eds.push_back(GetEvolutionaryDistinctiveness(tax, time)); + } } + return eds; + } - // std::cout << "Initializing divisor to " << divisor << " Offspring: " << tax->GetTotalOffspring() << std::endl; - // std::cout << "MRCA ID: " << mrca->GetID() << " Tax ID: " << tax->GetID() << " time: " << time << " Orig: " << tax->GetOriginationTime() << std::endl; - - Ptr test_taxon = tax->GetParent(); - - emp_assert(time != -1 && "Invalid time - are you passing time to rg?", time); - emp_assert(time >= tax->GetOriginationTime() - && "GetEvolutionaryDistinctiveness received a time that is earlier than the taxon's origination time.", tax->GetOriginationTime(), time); - - while (test_taxon) { - - // emp_assert(test_taxon->GetOriginationTime() != -1 && - // "Invalid time - are you passing time to rg?", time); - - depth += time - test_taxon->GetOriginationTime(); - // std::cout << "Tax: " << test_taxon->GetID() << " depth: " << depth << " time: " << time << " Orig: " << test_taxon->GetOriginationTime() << " divisor: " << divisor << std::endl; - time = test_taxon->GetOriginationTime(); - if (test_taxon == mrca || !test_taxon) { - // Stop when everything has converged or when we hit the root. - // std::cout << (int)(test_taxon == mrca) << " depth: " << depth << " divisor: " << divisor << std::endl; - total += depth/divisor; - return total; - } else if (test_taxon->GetNumOrgs() > 0) { - // If this taxon is still alive we need to update the divisor - // std::cout << "Alive point" << " depth: " << depth << " divisor: " << divisor << std::endl; - total += depth/divisor; - depth = 0; - divisor = test_taxon->GetTotalOffspring() + 1; - } else if (test_taxon->GetNumOff() > 1) { - // This is a branch point. We need to add the things on the other branch to the divisor.. - // std::cout << "Branch point" << " depth: " << depth << " divisor: " << divisor << std::endl; - total += depth/divisor; - depth = 0; - divisor = test_taxon->GetTotalOffspring(); - } + /** @returns Mean evolutionary distinctiveness of all active taxa + * @param time The time step at which the calculation is being done + */ + double GetMeanEvolutionaryDistinctiveness(double time) const { + emp::vector eds = GetAllEvolutionaryDistinctivenesses(time); + return emp::Mean(eds); + } - test_taxon = test_taxon->GetParent(); - } + /** @returns Sum of evolutionary distinctiveness of all active taxa + * @param time The time step at which the calculation is being done + */ + double GetSumEvolutionaryDistinctiveness(double time) const { + emp::vector eds = GetAllEvolutionaryDistinctivenesses(time); + return emp::Sum(eds); + } - return -1; + /** @returns Variance of evolutionary distinctiveness of all active taxa + * @param time The time step at which the calculation is being done + */ + double GetVarianceEvolutionaryDistinctiveness(double time) const { + emp::vector eds = GetAllEvolutionaryDistinctivenesses(time); + return emp::Variance(eds); } /** Calculates mean pairwise distance between extant taxa (Webb and Losos, 2000). @@ -891,28 +1086,41 @@ namespace emp { * (for demonstration of equivalence see Tucker et al, 2016). This measurement tells * you about the amount of distinctness in the community as a whole. * - * @param branch_only only counts distance in terms of nodes that represent a branch - * between two extant taxa (potentially useful for comparison to biological data, where - * non-branching nodes generally cannot be inferred). - * * This measurement assumes that the tree is fully connected. Will return -1 * if this is not the case. - * */ + * + * @param branch_only only counts distance in terms of nodes that represent a branch + * between two extant taxa (potentially useful for comparison to biological data, where + * non-branching nodes generally cannot be inferred). */ double GetMeanPairwiseDistance(bool branch_only=false) const { emp::vector dists = GetPairwiseDistances(branch_only); return (double)Sum(dists)/dists.size(); } + /** Calculates summed branch lengths of tree. Tucker et al 2017 points + * out that this is a measure of phylogenetic richness. + */ + double GetSumDistance() const { + const auto op = [](const double a, const Ptr& t){ + const auto branch = t->GetParent() ? t->GetOriginationTime() - t->GetParent()->GetOriginationTime(): 0.0; + return a + branch; + }; + return std::accumulate( + std::begin(active_taxa), std::end(active_taxa), double{}, op + ) + std::accumulate( + std::begin(ancestor_taxa), std::end(ancestor_taxa), double{}, op + ); + } + /** Calculates summed pairwise distance between extant taxa. Tucker et al 2017 points * out that this is a measure of phylogenetic richness. * - * @param branch_only only counts distance in terms of nodes that represent a branch - * between two extant taxa (potentially useful for comparison to biological data, where - * non-branching nodes generally cannot be inferred). - * * This measurement assumes that the tree is fully connected. Will return -1 * if this is not the case. - * */ + * + * @param branch_only only counts distance in terms of nodes that represent a branch + * between two extant taxa (potentially useful for comparison to biological data, where + * non-branching nodes generally cannot be inferred) */ double GetSumPairwiseDistance(bool branch_only=false) const { emp::vector v = GetPairwiseDistances(branch_only); return Sum(v); @@ -921,490 +1129,210 @@ namespace emp { /** Calculates variance of pairwise distance between extant taxa. Tucker et al 2017 points * out that this is a measure of phylogenetic regularity. * - * @param branch_only only counts distance in terms of nodes that represent a branch - * between two extant taxa (potentially useful for comparison to biological data, where - * non-branching nodes generally cannot be inferred). - * * This measurement assumes that the tree is fully connected. Will return -1 * if this is not the case. - * */ + * + * @param branch_only only counts distance in terms of nodes that represent a branch + * between two extant taxa (potentially useful for comparison to biological data, where + * non-branching nodes generally cannot be inferred). */ double GetVariancePairwiseDistance(bool branch_only=false) const { emp::vector v = GetPairwiseDistances(branch_only); return Variance(v); } - /** Calculates a vector of all pairwise distances between extant taxa. - * - * @param branch_only only counts distance in terms of nodes that represent a branch - * between two extant taxa (potentially useful for comparison to biological data, where - * non-branching nodes generally cannot be inferred). * * This method assumes that the tree is fully connected. Will return -1 * if this is not the case. - * */ - emp::vector GetPairwiseDistances(bool branch_only=false) const { - // The overarching approach here is to start with a bunch of pointers to all - // extant organisms (since that will include all leaves). Then we trace back up - // the tree, keeping track of distances. When things meet up, we calculate - // distances between the nodes on the sides that just met up. - - emp::vector dists; - - std::map< Ptr, emp::vector> > curr_pointers; - std::map< Ptr, emp::vector> > next_pointers; - + * + * @param branch_only only counts distance in terms of nodes that represent a branch + * between two extant taxa (potentially useful for comparison to biological data, where + * non-branching nodes generally cannot be inferred). * */ + emp::vector GetPairwiseDistances(bool branch_only=false) const; - for (Ptr tax : active_taxa) { - curr_pointers[tax] = emp::vector>({{0}}); - } - // std::cout << "Starting curr_pointers size: " << curr_pointers.size() << std::endl; - - while (curr_pointers.size() > 0) { - for (auto & tax : curr_pointers) { - bool alive = tax.first->GetNumOrgs() > 0; - // std::cout << tax.first << " has " << to_string(tax.second) << "and is waiting for " << tax.first->GetNumOff() + int(alive) << std::endl; - if ( tax.second.size() < tax.first->GetNumOff() + int(alive)) { - if (Has(next_pointers, tax.first)) { - // In case an earlier iteration added this node to next_pointers - for (auto vec : tax.second) { - next_pointers[tax.first].push_back(vec); - } - } else { - next_pointers[tax.first] = curr_pointers[tax.first]; - } - continue; - } - emp_assert(tax.first->GetNumOff() + int(alive) == tax.second.size(), tax.first->GetNumOff(), alive, to_string(tax.second), tax.second.size()); + double GetPairwiseDistance(Ptr t1, Ptr t2, bool branch_only=false) const; - // Okay, things should have just met up. Let's compute the distances - // between everything that just met. + /** + * Returns a vector containing all taxa that were extant at \c time_point and + * were at that time the most recent ancestors of taxa that are now extant + * Example: Say the only current extant taxon is C, its lineage goes A -> B -> C, + * and B and C were both alive at the specified time_point. This function would + * only return B. If, however, there were another currently extant taxon that were + * descended directly from A, then this function would return both A and B. */ + std::set> GetCanopyExtantRoots(int time_point = 0) const; - if (tax.second.size() > 1) { - for (size_t i = 0; i < tax.second.size(); i++ ) { - for (size_t j = i+1; j < tax.second.size(); j++) { - for (int disti : tax.second[i]) { - for (int distj : tax.second[j]) { - // std::cout << "Adding " << disti << " and " << distj << std::endl; - dists.push_back(disti+distj); - } - } - } - } - } - // std::cout << "dists " << to_string(dists) << std::endl; - // Increment distances and stick them in new vector - emp::vector new_dist_vec; - for (auto & vec : tax.second) { - for (int el : vec) { - new_dist_vec.push_back(el+1); - } - } + /** @returns the total number of ancestors between the given taxon and MRCA, if there is one. If + * there is no common ancestor, distance to the root of this tree is calculated instead. + * @param tax the taxon who's distance to root you want to calculate + * */ + int GetDistanceToRoot(Ptr tax) const; - // std::cout << "new_dist_vec " << to_string(new_dist_vec) << std::endl; + /** Calculates the number of branching points leading to multiple extant taxa + * between the given taxon and the most-recent common ancestor (or the root of its subtree, + * if no MRCA exists). This is useful because a lot + * of stats for phylogenies are designed for phylogenies reconstructed from extant taxa. + * These phylogenies generally only contain branching points, rather than every ancestor + * along the way to the current taxon. + * @returns Number of branching points between tax and root + * @param tax taxon to calculate branches from */ + int GetBranchesToRoot(Ptr tax) const; - next_pointers.erase(tax.first); + /** @returns Sackin Index of this tree (Sackin, 1972; reviewed in Shao, 1990). + * Measures tree balance*/ + int SackinIndex() const { + int sackin = 0; + for (auto taxon : active_taxa) { + sackin += GetBranchesToRoot(taxon) + 1; // Sackin index counts root as branch + } + return sackin; + } - Ptr test_taxon = tax.first->GetParent(); - while (test_taxon && test_taxon->GetNumOff() == 1 && test_taxon->GetNumOrgs() == 0) { - if (!branch_only) { - for (size_t i = 0; i < new_dist_vec.size(); i++){ - new_dist_vec[i]++; - } - } - test_taxon = test_taxon->GetParent(); - } + /** Returns dictionary containing a histogram of node out degrees + * e.g. {1:4, 2:10, 3:4} means the tree has 4 unifurcations, + * 10 bifurcations, and 4 trifurcations + * **/ + std::unordered_map GetOutDegreeDistribution() const { + std::unordered_map dist; + ApplyToAllTaxa([&dist](emp::Ptr tax){emp::IncrementCounter(dist, tax->GetNumOff());}); + return dist; + } - if (!test_taxon) { - continue; - } else if (!Has(next_pointers, test_taxon)) { - next_pointers[test_taxon] = emp::vector >({new_dist_vec}); - } else { - next_pointers[test_taxon].push_back(new_dist_vec); - } + /** Get average origin time for whole phylogeny. + * If @param normalize is set to true, will apply normalization to make result + * comparable to what you would expect from a strictly bifurcating tree (as most + * reconstruction methods will produce). This normalization is achieved by multiplying + * each taxon's values by the number of offspring taxa it has minus one. + */ + double GetAverageOriginTime(bool normalize=false) const { + double total = 0.0; + double count = 0.0; + // TODO: Replace when ranges are supported + // const auto all = {std::ranges::ref_view(active_taxa), + // std::ranges::ref_view(ancestor_taxa), + // std::ranges::ref_view(outside_taxa)}; + // for (emp::Ptr tax : all | std::views::join) { + for (emp::Ptr tax : active_taxa) { + const double weight = normalize ? std::max(0, static_cast(tax->GetNumOff()) - 1) : 1.0; + total += tax->GetOriginationTime() * weight; + count += weight; + } + for (emp::Ptr tax : ancestor_taxa) { + double weight = 1; + if (normalize) { + weight = std::max(0, static_cast(tax->GetNumOff()) - 1); + } + total += tax->GetOriginationTime() * weight; + count += weight; + } + for (emp::Ptr tax : outside_taxa) { + double weight = 1; + if (normalize) { + weight = std::max(0, static_cast(tax->GetNumOff()) - 1); } - curr_pointers = next_pointers; - next_pointers.clear(); - // std::cout << curr_pointers.size() << std::endl; + total += tax->GetOriginationTime() * weight; + count += weight; } - if (dists.size() != (active_taxa.size()*(active_taxa.size()-1))/2) { - // The tree is not connected - // It's possible we should do something different here... - return dists; + if (count == 0) { + return 0; } + return total/count; + } - // std::cout << "Total: " << total << "Dists: " << dists.size() << std::endl; + /** Calculate Colless Index of this tree (Colless, 1982; reviewed in Shao, 1990). + * Measures tree balance. The standard Colless index only works for bifurcating trees, + * so this will be a Colless-like Index, as suggested in + * "Sound Colless-like balance indices for multifurcating trees" (Mir, 2018, PLoS One)*/ + double CollessLikeIndex() const { + GetMRCA(); + return RecursiveCollessStep(mrca).total; + } - return dists; + /// @returns a pointer to the Most-Recent Common Ancestor for the population. + Ptr GetMRCA() const; - } + /// @returns the depth of the Most-Recent Common Ancestor; return -1 for none. + int GetMRCADepth() const; + /// @returns a pointer to the Most-Recent Ancestor shared by two taxa. + Ptr GetSharedAncestor(Ptr t1, Ptr t2) const; - /** - * Returns a vector containing all taxa from @param time_point that were - * - * */ - std::set> GetCanopyExtantRoots(int time_point = 0) const { - // NOTE: This could be made faster by doing something similar to the pairwise distance - // function - - std::set< Ptr> result; - // std::cout << "starting " << time_point << std::endl; - for (Ptr tax : active_taxa) { - // std::cout << tax->GetInfo() << std::endl; - while (tax) { - // std::cout << tax->GetInfo() << " " << tax->GetOriginationTime() << " " << tax->GetDestructionTime() << std::endl; - if (tax->GetOriginationTime() <= time_point && tax->GetDestructionTime() > time_point ) { - result.insert(tax); - // std::cout << "inserting " << tax->GetInfo() << std::endl; - break; - } - tax = tax->GetParent(); - } - } - - return result; - - } - - - - /** Counts the total number of ancestors between @param tax and MRCA, if there is one. If - * there is no common ancestor, distance to the root of this tree is calculated instead. - */ - int GetDistanceToRoot(Ptr tax) const { - // Now, trace the line of descent, updating the candidate as we go. - GetMRCA(); - - int depth = 0; - Ptr test_taxon = tax->GetParent(); - while (test_taxon) { - depth++; - if (test_taxon == mrca || !test_taxon) { - return depth; - } - test_taxon = test_taxon->GetParent(); - } - return depth; - } - - /** Counts the number of branching points leading to multiple extant taxa - * between @param tax and the most-recent common ancestor (or the root of its subtree, - * if no MRCA exists). This is useful because a lot - * of stats for phylogenies are designed for phylogenies reconstructed from extant taxa. - * These phylogenies generally only contain branching points, rather than every ancestor - * along the way to the current taxon.*/ - int GetBranchesToRoot(Ptr tax) const { - GetMRCA(); - - int depth = 0; - Ptr test_taxon = tax->GetParent(); - while (test_taxon) { - if (test_taxon == mrca || !test_taxon) { - return depth; - } else if (test_taxon->GetNumOff() > 1) { - depth++; - } - test_taxon = test_taxon->GetParent(); - } - return depth; - } - - /** Calculate Sackin Index of this tree (Sackin, 1972; reviewed in Shao, 1990). - * Measures tree balance - */ - int SackinIndex() const { - int sackin = 0; - - for (auto taxon : active_taxa) { - sackin += GetBranchesToRoot(taxon) + 1; // Sackin index counts root as branch - } - - return sackin; - } - - - // Graph ToGraph() const { - - // std::map, int> ids; - // int next_id = 0; - - // for (Ptr tax : active_taxa) { - // ids[tax] = next_id; - // next_id++; - // } - - // for (Ptr tax : ancestor_taxa) { - // ids[tax] = next_id; - // next_id++; - // } - - // for (Ptr tax : outside_taxa) { - // ids[tax] = next_id; - // next_id++; - // } - - // Graph g(next_id); - - // for (Ptr tax : active_taxa) { - // if (tax->GetParent()) { - // g.AddEdge(ids[tax->GetParent()], ids[tax]); - // } - // } - - // for (Ptr tax : ancestor_taxa) { - // if (tax->GetParent()) { - // g.AddEdge(ids[tax->GetParent()], ids[tax]); - // } - // } - - // for (Ptr tax : outside_taxa) { - // if (tax->GetParent()) { - // g.AddEdge(ids[tax->GetParent()], ids[tax]); - // } - // } - - // return g; - // } - - // Graph ToMinimalGraph() const { - // std::map, int> ids; - // int next_id = 0; - - // for (Ptr tax : active_taxa) { - // if (tax->GetNumOff() == 1) { - // continue; - // } - // ids[tax] = next_id; - // next_id++; - // } - - // for (Ptr tax : ancestor_taxa) { - // if (tax->GetNumOff() == 1) { - // continue; - // } - // ids[tax] = next_id; - // next_id++; - // } - - // for (Ptr tax : outside_taxa) { - // if (tax->GetNumOff() == 1) { - // continue; - // } - // ids[tax] = next_id; - // next_id++; - // } - - // Graph g(next_id); - - // for (Ptr tax : active_taxa) { - // if (tax->GetNumOff() == 1) { - // continue; - // } - - // Ptr parent = tax->GetParent(); - // while (parent) { - // if (parent->GetNumOff() == 1) { - // parent = parent->GetParent(); - // } else { - // g.AddEdge(ids[parent], ids[tax]); - // } - // } - // } - - // for (Ptr tax : ancestor_taxa) { - // if (tax->GetNumOff() == 1) { - // continue; - // } - - // Ptr parent = tax->GetParent(); - // while (parent) { - // if (parent->GetNumOff() == 1) { - // parent = parent->GetParent(); - // } else { - // g.AddEdge(ids[parent], ids[tax]); - // } - // } - // } - - // for (Ptr tax : outside_taxa) { - // if (tax->GetNumOff() == 1) { - // continue; - // } - - // Ptr parent = tax->GetParent(); - // while (parent) { - // if (parent->GetNumOff() == 1) { - // parent = parent->GetParent(); - // } else { - // g.AddEdge(ids[parent], ids[tax]); - // } - // } - // } - - // return g; - // } - - struct CollessStruct { - double total = 0; - emp::vector ns; - }; - - CollessStruct RecursiveCollessStep(Ptr curr) const { - CollessStruct result; - - while (curr->GetNumOff() == 1) { - curr = *(curr->GetOffspring().begin()); - } - - if (curr->GetNumOff() == 0) { - result.ns.push_back(0); // Node itself is calculated at level above - return result; - } - - for (Ptr off : curr->GetOffspring()) { - // std::cout << "Recursing on ID: " << off->GetID() << " Offspring: " << off->GetTotalOffspring() << std::endl; - - CollessStruct new_result = RecursiveCollessStep(off); - result.ns.push_back(Sum(new_result.ns) + log(off->GetOffspring().size() + exp(1))); - result.total += new_result.total; - } + /// @returns the genetic diversity of the population. + double CalcDiversity() const; - // std::cout << "Evaluating: " << curr->GetID() << std::endl; + /// @returns vector containing the lineages of the specified taxon + emp::vector> GetLineage(Ptr tax) const { + emp::vector> lineage; + lineage.push_back(tax); - double med = Median(result.ns); - double sum_diffs = 0; - // std::cout << "Median: " << med << std::endl; - for (double n : result.ns) { - // std::cout << n << std::endl; - sum_diffs += std::abs(n-med); + while (tax) { + tax = Parent(tax); + lineage.push_back(tax); } - // std::cout << "Sumdiffs: " << sum_diffs << " n: " << result.ns.size() << " average: " << sum_diffs/result.ns.size() << std::endl; - result.total += sum_diffs/result.ns.size(); - return result; + return lineage; } - /** Calculate Colless Index of this tree (Colless, 1982; reviewed in Shao, 1990). - * Measures tree balance. The standard Colless index only works for bifurcating trees, - * so this will be a Colless-like Index, as suggested in - * "Sound Colless-like balance indices for multifurcating trees" (Mir, 2018, PLoS One) - */ - double CollessLikeIndex() const { + /// @returns vector containing the lineages of the specified taxon + /// up to and including the MRCA, but not past the MRCA + emp::vector> GetLineageToMRCA(Ptr tax) const { GetMRCA(); + emp::vector> lineage; + lineage.push_back(tax); - return RecursiveCollessStep(mrca).total; - } - - - - void RemoveBefore(int ud) { - - // @ELD: This would be such a nice way to do it - // but we can't because we need to notify offspring - // when their parents are un-tracked - // std::set> to_remove; - // for (Ptr tax : ancestor_taxa) { - // if (tax->GetDestructionTime() < ud) { - // to_remove.insert(tax); - // } - // } - - // for (Ptr tax : to_remove) { - // ancestor_taxa.erase(tax); - // tax.Delete(); - // } - - std::map, std::set>> to_remove; - - for (Ptr tax : active_taxa) { - Ptr curr = tax; - - while (curr && !CanRemove(curr->GetParent(), ud)) { - curr = curr->GetParent(); - } - - if (curr) { - Ptr next = curr->GetParent(); - while (next) { - to_remove[next].insert(curr); - curr = next; - next = next->GetParent(); - } - } - } - // std::cout << "About to remove " << to_remove.size() << " orgs" << std::endl; - for (std::pair, std::set>> el : to_remove) { - emp_assert(el.first->GetDestructionTime() < ud, el.first->GetDestructionTime(), ud); - if (el.first->GetNumOff() == el.second.size()) { - // Everything is account for - for (auto tax : el.second) { - tax->NullifyParent(); - } - ancestor_taxa.erase(el.first); - el.first.Delete(); - } - } - - } - - bool CanRemove(Ptr t, int ud) { - if (!t) { - return false; + while (tax && tax != mrca) { + tax = Parent(tax); + lineage.push_back(tax); } - while (t) { - if (t->GetNumOrgs() > 0 || t->GetDestructionTime() >= ud) { - return false; - } - t = t->GetParent(); - } - return true; + return lineage; } - /// Request a pointer to the Most-Recent Common Ancestor for the population. - Ptr GetMRCA() const; - - /// Request the depth of the Most-Recent Common Ancestor; return -1 for none. - int GetMRCADepth() const; - - /// Add information about a new organism, including its stored info and parent's taxon; - /// If you would like the systematics manager to track taxon age, you can also supply - /// the update at which the taxon is being added. - /// return a pointer for the associated taxon. - void AddOrg(ORG && org, WorldPosition pos, int update=-1); - Ptr AddOrg(ORG && org, WorldPosition pos, Ptr parent=nullptr, int update=-1); - Ptr AddOrg(ORG && org, Ptr parent=nullptr, int update=-1); - - void AddOrg(ORG & org, WorldPosition pos, int update=-1); - Ptr AddOrg(ORG & org, WorldPosition pos, Ptr parent=nullptr, int update=-1); - Ptr AddOrg(ORG & org, Ptr parent=nullptr, int update=-1); - - - /// Remove an instance of an organism; track when it's gone. - bool RemoveOrg(WorldPosition pos, int time=-1); - bool RemoveOrg(Ptr taxon, int time=-1); - void RemoveOrgAfterRepro(WorldPosition pos, int time=-1); - void RemoveOrgAfterRepro(Ptr taxon, int time=-1); - - /// Remove org from next population (for use with synchronous generations) - // bool RemoveNextOrg(WorldPosition pos, int time=-1); - // bool RemoveNextOrg(Ptr taxon, int time=-1); - - /// Climb up a lineage... - Ptr Parent(Ptr taxon) const; + // ===== Output functions ==== /// Print details about the Systematics manager. + /// First prints setting, followed by all active, ancestor, and outside + /// taxa being stored. Format for taxa is + /// [ id | number of orgs in this taxon, number of offspring taxa of this taxon | parent taxon] + /// @param os output stream to print to void PrintStatus(std::ostream & os=std::cout) const; - /// Print whole lineage. + /// Print a whole lineage. Format: "Lineage:", followed by each taxon in the lineage, each on new line + /// @param taxon a pointer to the taxon to print the lineage of + /// @param os output stream to print to void PrintLineage(Ptr taxon, std::ostream & os=std::cout) const; + /// Add a new snapshot function. + /// When a snapshot of the systematics is taken, in addition to the default + /// set of functions, all user-added snapshot functions are run. Functions + /// take a reference to a taxon as input and return the string to be dumped + /// in the file at the given key. + void AddSnapshotFun(const std::function & fun, + const std::string & key, const std::string & desc="") { + user_snapshot_funs.emplace_back(fun, key, desc); + } + + /// Take a snapshot of current state of taxon phylogeny. + /// WARNING: Current, this function assumes one parent taxon per-taxon. + /// @param file_path the file to store the snapshot data in void Snapshot(const std::string & file_path) const; - /// Calculate the genetic diversity of the population. - double CalcDiversity() const; + void SwapPositions(WorldPosition p1, WorldPosition p2) { + emp::vector > & v1 = taxon_locations[p1.GetPopID()]; + emp::vector > & v2 = taxon_locations[p2.GetPopID()]; + std::swap(v1[p1.GetIndex()], v2[p2.GetIndex()]); + } + + /// Load data from a file into the systematics manager. + /// Intended to be used on an empty systematics object + /// Expects a file in ALife phylogeny standard format (see: https://alife-data-standards.github.io/alife-data-standards/phylogeny) + /// @param file_path the file to load data from + /// @param info_col the name of the column in the file that contains the taxon info (i.e. the information distinguishing taxa; should match return type of calc_taxon_info_fun) + /// @param assume_leaves_extant if true, assumes that all leaf nodes correspond to extant taxa + /// @param adjust_total_offspring if true, adjusts the total offspring count of each taxon based on the number of offspring it actually has (time consuming but necessary for some stats) + void LoadFromFile(const std::string & file_path, const std::string & info_col = "info", + bool assume_leaves_extant=true, + bool adjust_total_offspring = true); }; @@ -1414,6 +1342,28 @@ namespace emp { // === === // ============================================================= + // ======= Functions for manipulating systematics manager internals + + template + void Systematics::Update() { + if (track_synchronous) { + + // Clear pending removal + if (to_be_removed != nullptr) { + RemoveOrg(to_be_removed); + taxon_locations[removal_pos.GetPopID()][removal_pos.GetIndex()] = nullptr; + to_be_removed = nullptr; + removal_pos = {0, 0}; + } + + // Assumes that synchronous worlds have two populations, with 0 + // being currently alive and 1 being the one being created + std::swap(taxon_locations[0], taxon_locations[1]); + taxon_locations[1].resize(0); + } + ++curr_update; + } + // Should be called wheneven a taxon has no organisms AND no descendants. template void Systematics::Prune(Ptr taxon) { @@ -1437,14 +1387,22 @@ namespace emp { // If the taxon is still active AND the is the current mrca AND now has only one offspring, // clear the MRCA for lazy re-evaluation later. - else if (taxon == mrca && taxon->GetNumOff() == 1) mrca = nullptr; + else if (taxon == mrca && taxon->GetNumOff() == 1) { + mrca = nullptr; + } } // Mark a taxon extinct if there are no more living members. There may be descendants. template - void Systematics::MarkExtinct(Ptr taxon, int time) { - emp_assert(taxon); - emp_assert(taxon->GetNumOrgs() == 0); + void Systematics::MarkExtinct(Ptr taxon) { + emp_optional_throw(taxon, "Invalid taxon pointer"); + emp_optional_throw(taxon->GetNumOrgs() == 0, "Taxon already extinct"); + + // Track destruction time + taxon->SetDestructionTime(curr_update); + + // Give other functions a chance to do stuff with taxon before extinction + on_extinct_sig.Trigger(taxon); if (max_depth == (int)taxon->GetDepth()) { // We no longer know the max depth @@ -1465,105 +1423,84 @@ namespace emp { taxon.Delete(); return; } - // std::cout << "About to set destruction time " << time << std::endl; - // Only need to track destruction time if we're archiving taxa - taxon->SetDestructionTime(time); if (store_ancestors) { ancestor_taxa.insert(taxon); // Move taxon to ancestors... } + if (taxon == mrca && taxon->GetNumOff() <= 1) { + // If this taxon was mrca and has only one offspring, then the new + // mrca is somewhere farther down the chain. + // If this taxon was mrca and now has no offspring, something very + // strange has happened. + // Either way, we should mark mrca for lazy recalculation + mrca = nullptr; + } if (taxon->GetNumOff() == 0) Prune(taxon); // ...and prune from there if needed. } - - // Request a pointer to the Most-Recent Common Ancestor for the population. + // Add information about a new organism, including its stored info and parent's taxon; + // Can't return a pointer for the associated taxon because of obnoxious inheritance problems template - Ptr::taxon_t> Systematics::GetMRCA() const { - if (!mrca && num_roots == 1) { // Determine if we need to calculate the MRCA. - // First, find a candidate among the living taxa. Only taxa that have one offsrping - // can be on the line-of-descent to the MRCA, so anything else is a good start point. - // There must be at least one! Stop as soon as we find a candidate. - Ptr candidate(nullptr); - for (auto x : active_taxa) { - if (x->GetNumOff() != 1) { candidate = x; break; } - } - - // Now, trace the line of descent, updating the candidate as we go. - Ptr test_taxon = candidate->GetParent(); - while (test_taxon) { - emp_assert(test_taxon->GetNumOff() >= 1); - // If the test_taxon is dead, we only want to update candidate when we hit a new branch point - // If test_taxon is still alive, though, we always need to update it - if (test_taxon->GetNumOff() > 1 || test_taxon->GetNumOrgs() > 0) candidate = test_taxon; - test_taxon = test_taxon->GetParent(); - } - mrca = candidate; - } - return mrca; + void Systematics::AddOrg(ORG & org, WorldPosition pos) { + emp_optional_throw(store_position, "Trying to pass position to a systematics manager that can't use it"); + AddOrg(org, pos, next_parent); + next_parent = nullptr; } - // Request the depth of the Most-Recent Common Ancestor; return -1 for none. + // Add information about a new organism, including its stored info and parent's taxon; + // Can't return a pointer for the associated taxon because of obnoxious inheritance problems template - int Systematics::GetMRCADepth() const { - GetMRCA(); - if (mrca) return (int) mrca->GetDepth(); - return -1; + void Systematics::AddOrg(ORG && org, WorldPosition pos) { + emp_optional_throw(store_position, "Trying to pass position to a systematics manager that can't use it"); + AddOrg(org, pos, next_parent); + next_parent = nullptr; } - - // Add information about a new organism, including its stored info and parent's taxon; // Can't return a pointer for the associated taxon because of obnoxious inheritance problems template - // Ptr::taxon_t> - void Systematics::AddOrg(ORG & org, WorldPosition pos, int update) { - emp_assert(store_position, "Trying to pass position to a systematics manager that can't use it"); - // emp_assert(next_parent, "Adding organism with no parent specified and no next_parent set"); - AddOrg(org, pos, next_parent, update); - next_parent = nullptr; + void Systematics::AddOrg(ORG & org, WorldPosition pos, WorldPosition parent) { + emp_optional_throw(store_position, "Trying to pass position to a systematics manager that can't use it"); + AddOrg(org, pos, taxon_locations[parent.GetPopID()][parent.GetIndex()]); } // Add information about a new organism, including its stored info and parent's taxon; // Can't return a pointer for the associated taxon because of obnoxious inheritance problems template - // Ptr::taxon_t> - void Systematics::AddOrg(ORG && org, WorldPosition pos, int update) { - emp_assert(store_position, "Trying to pass position to a systematics manager that can't use it"); - // emp_assert(next_parent, "Adding organism with no parent specified and no next_parent set"); - AddOrg(org, pos, next_parent, update); - next_parent = nullptr; + void Systematics::AddOrg(ORG && org, WorldPosition pos, WorldPosition parent) { + emp_optional_throw(store_position, "Trying to pass position to a systematics manager that can't use it"); + AddOrg(org, pos, taxon_locations[parent.GetPopID()][parent.GetIndex()]); } // Version for if you aren't tracking positions template Ptr::taxon_t> - Systematics::AddOrg(ORG & org, Ptr parent, int update) { - return AddOrg(org, -1, parent, update); + Systematics::AddOrg(ORG & org, Ptr parent) { + emp_optional_throw(!store_position, "Trying to add org to position-tracking systematics manager without position. Either specify a valid position or turn of position tracking for systematic manager."); + return AddOrg(org, WorldPosition::invalid_id, parent); } // Version for if you aren't tracking positions template Ptr::taxon_t> - Systematics::AddOrg(ORG && org, Ptr parent, int update) { - emp_assert(!store_position && - "Trying to add org to position-tracking systematics manager without position. Either specify a valid position or turn of position tracking for systematic manager.", store_position); - return AddOrg(org, WorldPosition::invalid_id, parent, update); + Systematics::AddOrg(ORG && org, Ptr parent) { + emp_optional_throw(!store_position, "Trying to add org to position-tracking systematics manager without position. Either specify a valid position or turn of position tracking for systematic manager."); + return AddOrg(org, WorldPosition::invalid_id, parent); } // Add information about a new organism, including its stored info and parent's taxon; // return a pointer for the associated taxon. template Ptr::taxon_t> - Systematics::AddOrg(ORG && org, WorldPosition pos, Ptr parent, int update) { - return AddOrg(org, pos, parent, update); + Systematics::AddOrg(ORG && org, WorldPosition pos, Ptr parent) { + return AddOrg(org, pos, parent); } // Add information about a new organism, including its stored info and parent's taxon; - // return a pointer for the associated taxon. template Ptr::taxon_t> - Systematics::AddOrg(ORG & org, WorldPosition pos, Ptr parent, int update) { + Systematics::AddOrg(ORG & org, WorldPosition pos, Ptr parent) { org_count++; // Keep count of how many organisms are being tracked. ORG_INFO info = calc_info_fun(org); @@ -1581,33 +1518,29 @@ namespace emp { if (max_depth != -1 && (int)cur_taxon->GetDepth() > max_depth) { max_depth = cur_taxon->GetDepth(); } - on_new_sig.Trigger(cur_taxon, org); + if (store_active) active_taxa.insert(cur_taxon); // Store new taxon. - if (parent) parent->AddOffspring(cur_taxon); // Track tree info. + if (parent) parent->AddOffspring(cur_taxon); // Track tree info. - cur_taxon->SetOriginationTime(update); + cur_taxon->SetOriginationTime(curr_update); + on_new_sig.Trigger(cur_taxon, org); } - // std::cout << "about to store poisition" << std::endl; - if (store_position && pos.GetIndex() >= 0) { - if (pos.GetPopID()) { - if (pos.GetIndex() >= next_taxon_locations.size()) { - next_taxon_locations.resize(pos.GetIndex()+1); - } - next_taxon_locations[pos.GetIndex()] = cur_taxon; - } else { - if (pos.GetIndex() >= taxon_locations.size()) { - taxon_locations.resize(pos.GetIndex()+1); - } - taxon_locations[pos.GetIndex()] = cur_taxon; - } + if (store_position) { + const uint32_t required_num_pops = std::max(static_cast(taxon_locations.size()), pos.GetPopID() + 1); + if (required_num_pops > static_cast(taxon_locations.size())) { taxon_locations.resize(required_num_pops);} + + const uint32_t required_pop_size = std::max(static_cast(taxon_locations[pos.GetPopID()].size()), pos.GetIndex() + 1); + if (required_pop_size > static_cast(taxon_locations[pos.GetPopID()].size())) { taxon_locations[pos.GetPopID()].resize(required_pop_size);} + + taxon_locations[pos.GetPopID()][pos.GetIndex()] = cur_taxon; } cur_taxon->AddOrg(); // Record the current organism in its taxon. total_depth += cur_taxon->GetDepth(); // Track the total depth (for averaging) if (to_be_removed) { - RemoveOrg(to_be_removed, removal_time); + RemoveOrg(to_be_removed); to_be_removed = nullptr; } @@ -1616,79 +1549,124 @@ namespace emp { } template - void Systematics::RemoveOrgAfterRepro(WorldPosition pos, int time) { - emp_assert(store_position, "Trying to remove org based on position from systematics manager that doesn't track it."); + void Systematics::RemoveOrgAfterRepro(WorldPosition pos) { + emp_optional_throw(store_position, "Trying to remove org based on position from systematics manager that doesn't track it."); - if (pos.GetIndex() >= taxon_locations.size() || !taxon_locations[pos.GetIndex()]) { + if (pos.GetPopID() >= taxon_locations.size() || + pos.GetIndex() >= taxon_locations[pos.GetPopID()].size() || + !taxon_locations[pos.GetPopID()][pos.GetIndex()]) { // There's not actually a taxon here return; } - RemoveOrgAfterRepro(taxon_locations[pos.GetIndex()], time); - removal_pos = pos.GetIndex(); + RemoveOrgAfterRepro(taxon_locations[pos.GetPopID()][pos.GetIndex()]); + removal_pos = pos; } template - void Systematics::RemoveOrgAfterRepro(Ptr taxon, int time) { + void Systematics::RemoveOrgAfterRepro(Ptr taxon) { if (to_be_removed != nullptr) { - RemoveOrg(to_be_removed, removal_time); - taxon_locations[removal_pos] = nullptr; + RemoveOrg(to_be_removed); + taxon_locations[removal_pos.GetPopID()][removal_pos.GetIndex()] = nullptr; to_be_removed = nullptr; - removal_pos = -1; + removal_pos = {0, 0}; } to_be_removed = taxon; - // std::cout << "Setting remove time to " << time << std::endl; - removal_time = time; } - // Remove an instance of an organism; track when it's gone. + // Remove an instance of a taxon; track when it's gone. template - bool Systematics::RemoveOrg(WorldPosition pos, int time) { - emp_assert(store_position, "Trying to remove org based on position from systematics manager that doesn't track it."); - - if (pos.GetPopID() == 0) { - emp_assert(pos.GetIndex() < taxon_locations.size(), "Invalid position requested for removal", pos.GetIndex(), taxon_locations.size()); - bool active = false; - if (taxon_locations[pos.GetIndex()]) { - //TODO: Figure out how this can ever not be true - active = RemoveOrg(taxon_locations[pos.GetIndex()], time); - } - taxon_locations[pos.GetIndex()] = nullptr; - return active; - } else { - emp_assert(pos.GetIndex() < next_taxon_locations.size(), "Invalid position requested for removal", pos.GetIndex(), taxon_locations.size()); - bool active = RemoveOrg(next_taxon_locations[pos.GetIndex()], time); - next_taxon_locations[pos.GetIndex()] = nullptr; - return active; + bool Systematics::RemoveOrg(WorldPosition pos) { + emp_optional_throw(store_position, "Trying to remove org based on position from systematics manager that doesn't track it."); + emp_optional_throw(pos.GetPopID() < taxon_locations.size(), "Invalid population requested for removal"); + emp_optional_throw(pos.GetIndex() < taxon_locations[pos.GetPopID()].size(), "Invalid position requested for removal"); + + bool active = false; + if (taxon_locations[pos.GetPopID()][pos.GetIndex()]) { + //TODO: Figure out how this can ever not be true + active = RemoveOrg(taxon_locations[pos.GetPopID()][pos.GetIndex()]); } + taxon_locations[pos.GetPopID()][pos.GetIndex()] = nullptr; + return active; } - // Remove an instance of an organism; track when it's gone. + // Remove an instance of a taxon; track when it's gone. + // @param taxon the taxon of which one instance is being removed template - bool Systematics::RemoveOrg(Ptr taxon, int time) { - emp_assert(taxon); + bool Systematics::RemoveOrg(Ptr taxon) { + emp_optional_throw(taxon, "Trying to remove org from a null taxon"); // Update stats org_count--; total_depth -= taxon->GetDepth(); - // emp_assert(Has(active_taxa, taxon)); + // emp_optional_throw(Has(active_taxa, taxon)); const bool active = taxon->RemoveOrg(); - if (!active) MarkExtinct(taxon, time); + if (!active) MarkExtinct(taxon); return active; } - // Climb up a lineage... + // Remove all taxa that 1) went extinct before the specified update/time step, + // and 2) only have ancestors that went extinct before the specified update/time step. + // Warning: this function invalidates most measurements you could make about tree topology. + // It is useful in select situations where you need to store ancestors for some period of time, + // but cannot computationally afford to store all ancestors for your entire run. + template + void Systematics::RemoveBefore(int ud) { + + std::set> to_remove; + for (Ptr tax : ancestor_taxa) { + if (tax->GetDestructionTime() < ud && CanRemove(tax, ud)) { + to_remove.insert(tax); + } + } + + for (Ptr tax : to_remove) { + for (Ptr off : tax->GetOffspring()) { + off->NullifyParent(); + } + ancestor_taxa.erase(tax); + tax.Delete(); + } + + } + + #ifndef DOXYGEN_SHOULD_SKIP_THIS + /// Helper function for RemoveBefore + /// @returns true if a a taxon can safely be + /// removed by RemoveBefore + template + bool Systematics::CanRemove(Ptr t, int ud) { + if (!t) { + return false; + } + while (t) { + if (t->GetNumOrgs() > 0 || t->GetDestructionTime() >= ud) { + return false; + } + t = t->GetParent(); + } + return true; + } + #endif // #DOXYGEN_SHOULD_SKIP_THIS + + // ======= Functions for getting information from the systematics manager + + // @returns a pointer to the parent of a given taxon template Ptr::taxon_t> Systematics::Parent(Ptr taxon) const { - emp_assert(taxon); - emp_assert(Has(active_taxa, taxon)); + emp_optional_throw(taxon, "Trying to get parent of a null taxon"); + // emp_optional_throw(Has(active_taxa, taxon)); return taxon->GetParent(); } // Print details about the Systematics manager. + // First prints setting, followed by all active, ancestor, and outside + // taxa being stored. Format for taxa is + // [ id | number of orgs in this taxon, number of offspring taxa of this taxon | parent taxon] + // @param os output stream to print to template void Systematics::PrintStatus(std::ostream & os) const { os << "Systematics Status:\n"; @@ -1721,7 +1699,6 @@ namespace emp { os << std::endl; } - // Print whole lineage. template void Systematics::PrintLineage(Ptr taxon, std::ostream & os) const { os << "Lineage:\n"; @@ -1731,8 +1708,6 @@ namespace emp { } } - /// Take a snapshot of current state of taxon phylogeny. - /// WARNING: Current, this function assumes one parent taxon per-taxon. template void Systematics::Snapshot(const std::string & file_path) const { emp::DataFile file(file_path); @@ -1810,31 +1785,650 @@ namespace emp { // Output header information. file.PrintHeaderKeys(); - // Update file w/active taxa information - for (auto tax : active_taxa) { + // Update file w/ taxa information + // const auto all = {std::ranges::ref_view(active_taxa), std::ranges::ref_view(ancestor_taxa), + // std::ranges::ref_view(outside_taxa)}; + for (emp::Ptr tax : active_taxa) { cur_taxon = tax; file.Update(); } - - // Update file w/ancestor taxa information - for (auto tax : ancestor_taxa) { + for (emp::Ptr tax : ancestor_taxa) { cur_taxon = tax; file.Update(); } - - // Update file w/outside taxa information - for (auto tax : outside_taxa) { + for (emp::Ptr tax : outside_taxa) { cur_taxon = tax; file.Update(); } } - // Calculate the genetic diversity of the population. + // ======= Measurements about the systematics manager + + // @returns the genetic diversity of the population. template double Systematics::CalcDiversity() const { + emp_optional_throw(!num_orgs_defaulted, "Error: calculating diversity from phylogeny missing org counts"); return emp::Entropy(active_taxa, [](Ptr x){ return x->GetNumOrgs(); }, (double) org_count); } + + // @returns a pointer to the Most-Recent Common Ancestor for the population or null pointer if there isn't one + template + Ptr::taxon_t> Systematics::GetMRCA() const { + if (!mrca && num_roots == 1) { // Determine if we need to calculate the MRCA. + // First, find a candidate among the living taxa. Only taxa that have one offsrping + // can be on the line-of-descent to the MRCA, so anything else is a good start point. + // There must be at least one! Stop as soon as we find a candidate. + Ptr candidate = *std::find_if(active_taxa.begin(), active_taxa.end(), + [](Ptr x){ return x->GetNumOff() != 1; } + ); + + // Now, trace the line of descent, updating the candidate as we go. + Ptr test_taxon = candidate->GetParent(); + while (test_taxon) { + emp_assert(test_taxon->GetNumOff() >= 1); + // If the test_taxon is dead, we only want to update candidate when we hit a new branch point + // If test_taxon is still alive, though, we always need to update it + if (test_taxon->GetNumOff() > 1 || test_taxon->GetNumOrgs() > 0) candidate = test_taxon; + test_taxon = test_taxon->GetParent(); + } + mrca = candidate; + } + return mrca; + } + + // @returns the depth of the Most-Recent Common Ancestor or -1 for none. + template + int Systematics::GetMRCADepth() const { + GetMRCA(); + if (mrca) return (int) mrca->GetDepth(); + return -1; + } + + // @returns a pointer to the Most-Recent Ancestor shared by two taxa. + template + Ptr::taxon_t> Systematics::GetSharedAncestor(Ptr t1, Ptr t2) const { + // Same taxon + if (t1 == t2) { + return t1; + } + + // If not same, we have to actually do work + emp::vector > lineage1 = GetLineageToMRCA(t1); + emp::vector > lineage2 = GetLineageToMRCA(t2); + + size_t l1 = lineage1.size() - 1; + size_t l2 = lineage2.size() - 1; + + emp_assert(lineage1[l1] == lineage2[l2], + "Both lineages should start with MRCA"); + + while (lineage1[l1] == lineage2[l2]) { + l1--; + l2--; + } + + return lineage1[l1+1]; + } + + #ifndef DOXYGEN_SHOULD_SKIP_THIS + // Helper for Colless function calculation + struct CollessStruct { + double total = 0; + emp::vector n_values; + }; + + // Helper for Colless function calculation + template + CollessStruct Systematics::RecursiveCollessStep(Ptr curr) const { + CollessStruct result; + + while (curr->GetNumOff() == 1) { + curr = *(curr->GetOffspring().begin()); + } + + if (curr->GetNumOff() == 0) { + result.n_values.push_back(0); // Node itself is calculated at level above + return result; + } + + for (Ptr off : curr->GetOffspring()) { + + CollessStruct new_result = RecursiveCollessStep(off); + result.n_values.push_back(Sum(new_result.n_values) + log(off->GetOffspring().size() + exp(1))); + result.total += new_result.total; + } + + double med = Median(result.n_values); + const double sum_diffs = std::accumulate(result.n_values.begin(), result.n_values.end(), 0.0, [med](double sum, double n) { return sum + std::abs(n-med); }); + + result.total += sum_diffs/result.n_values.size(); + return result; + } + #endif // #DOXYGEN_SHOULD_SKIP_THIS + + template + emp::vector Systematics::GetPairwiseDistances(bool branch_only) const { + // The overarching approach here is to start with a bunch of pointers to all + // extant organisms (since that will include all leaves). Then we trace back up + // the tree, keeping track of distances. When things meet up, we calculate + // distances between the nodes on the sides that just met up. + + // Vector to store distances between all pairs of extant taxa + emp::vector dists; + + /* Map of nodes we are currently looking at (will start at extant taxa and then work our way up) + / to the distances between them and extant taxa below them. So for example, + / if we had this tree: + / X + / | + / A + / / | \ + / B C D + / / \ | + / E F G (with E, F, and G extant) + / And A was in curr_pointers, its value would be: + / [[2, 2], [1], [2]] */ + std::map< Ptr, emp::vector> > curr_pointers; + + // next_pointers is the same, but is the data to consider on the next iteration. + // For example, after we've processed A from the previous example, we would end + // up adding X with the value [[3, 3, 2, 3]] (all of the values from before in + // a single flattened vector and incremented by 1) + std::map< Ptr, emp::vector> > next_pointers; + + + for (Ptr tax : active_taxa) { + curr_pointers[tax] = emp::vector>({{0}}); + } + + while (curr_pointers.size() > 0) { + for (auto & tax : curr_pointers) { + bool alive = tax.first->GetNumOrgs() > 0; + + if ( tax.second.size() < tax.first->GetNumOff() + int(alive)) { + if (Has(next_pointers, tax.first)) { + // In case an earlier iteration added this node to next_pointers + for (auto vec : tax.second) { + next_pointers[tax.first].push_back(vec); + } + } else { + next_pointers[tax.first] = curr_pointers[tax.first]; + } + continue; + } + emp_assert(tax.first->GetNumOff() + int(alive) == tax.second.size(), tax.first->GetNumOff(), alive, to_string(tax.second), tax.second.size()); + + // Okay, things should have just met up. Let's compute the distances + // between everything that just met. + + if (tax.second.size() > 1) { + + for (size_t i = 0; i < tax.second.size(); i++ ) { + for (size_t j = i+1; j < tax.second.size(); j++) { + for (int disti : tax.second[i]) { + for (int distj : tax.second[j]) { + dists.push_back(disti+distj); + } + } + } + } + } + // Increment distances and stick them in new vector + emp::vector new_dist_vec; + for (auto & vec : tax.second) { + for (int el : vec) { + new_dist_vec.push_back(el+1); + } + } + + next_pointers.erase(tax.first); + + Ptr test_taxon = tax.first->GetParent(); + while (test_taxon && test_taxon->GetNumOff() == 1 && test_taxon->GetNumOrgs() == 0) { + if (!branch_only) { + for (size_t i = 0; i < new_dist_vec.size(); i++){ + new_dist_vec[i]++; + } + } + test_taxon = test_taxon->GetParent(); + } + + if (!test_taxon) { + continue; + } else if (!Has(next_pointers, test_taxon)) { + next_pointers[test_taxon] = emp::vector >({new_dist_vec}); + } else { + next_pointers[test_taxon].push_back(new_dist_vec); + } + } + curr_pointers = next_pointers; + next_pointers.clear(); + } + + if (dists.size() != (active_taxa.size()*(active_taxa.size()-1))/2) { + // The tree is not connected + // It's possible we should do something different here... + emp_assert_warning(false, "Warning: Tree is not connected - some pairwise distances are infinite (ommitted)"); + return dists; + } + + return dists; + + } + + template + double Systematics::GetPairwiseDistance(Ptr t1, Ptr t2, bool branch_only) const { + // Same taxon + if (t1 == t2) { + return 0; + } + + // If not same, we have to actually do work + const emp::vector > lineage1 = GetLineageToMRCA(t1); + const emp::vector > lineage2 = GetLineageToMRCA(t2); + + size_t l1 = lineage1.size() - 1; + size_t l2 = lineage2.size() - 1; + + emp_optional_throw(lineage1[l1] == lineage2[l2], + "Both lineages should start with MRCA"); + + while (lineage1[l1] == lineage2[l2]) { + l1--; + l2--; + } + + double count = l1 + l2 + 2; + + if (branch_only) { + count -= std::count_if(lineage1.begin()+1, lineage1.begin() + l1, [](Ptr x){ return x->GetNumOff() == 1; }); + count -= std::count_if(lineage2.begin()+1, lineage2.begin() + l2, [](Ptr x){ return x->GetNumOff() == 1; }); + } + + return count; + } + + template + double Systematics::GetEvolutionaryDistinctiveness(Ptr tax, double time) const { + + // If we loaded this phylogeny from a file without calculating total offspring, + // we need to actually calculate it here + emp_optional_throw(!total_offspring_defaulted, "To calculate evolutionary distinctiveness on phylogeny loaded from file you must calculate total offspring."); + + double depth = 0; // Length (in time units) of section we're currently exploring + double total = 0; // Count up scores for each section of tree + double divisor = tax->GetTotalOffspring() + 1; // Number of extant taxa this will split into (1 for current taxa, plus its offspring) + + // We're stopping when we hit MRCA, so we need to make sure it's been calculated. + GetMRCA(); + if (tax == mrca) { + return 0; + } + + // std::cout << "Initializing divisor to " << divisor << " Offspring: " << tax->GetTotalOffspring() << std::endl; + // std::cout << "MRCA ID: " << mrca->GetID() << " Tax ID: " << tax->GetID() << " time: " << time << " Orig: " << tax->GetOriginationTime() << std::endl; + + Ptr test_taxon = tax->GetParent(); + + emp_optional_throw(time != -1, "Invalid time - are you passing time to rg?"); + emp_optional_throw(time >= tax->GetOriginationTime(), + "GetEvolutionaryDistinctiveness received a time that is earlier than the taxon's origination time."); + + while (test_taxon) { + + depth += time - test_taxon->GetOriginationTime(); + time = test_taxon->GetOriginationTime(); + if (test_taxon == mrca || !test_taxon) { + // Stop when everything has converged or when we hit the root. + total += depth/divisor; + return total; + } else if (test_taxon->GetNumOrgs() > 0) { + // If this taxon is still alive we need to update the divisor + total += depth/divisor; + depth = 0; + divisor = test_taxon->GetTotalOffspring() + 1; + } else if (test_taxon->GetNumOff() > 1) { + // This is a branch point. We need to add the things on the other branch to the divisor.. + total += depth/divisor; + depth = 0; + divisor = test_taxon->GetTotalOffspring(); + } + + test_taxon = test_taxon->GetParent(); + } + + return -1; + } + + template + int Systematics::GetBranchesToRoot(Ptr tax) const { + GetMRCA(); + + int depth = 0; + Ptr test_taxon = tax->GetParent(); + while (test_taxon) { + if (test_taxon == mrca) { + return depth; + } else if (test_taxon->GetNumOff() > 1) { + depth++; + } + test_taxon = test_taxon->GetParent(); + } + return depth; + } + + template + int Systematics::GetDistanceToRoot(Ptr tax) const { + // Now, trace the line of descent, updating the candidate as we go. + GetMRCA(); + + int depth = 0; + Ptr test_taxon = tax->GetParent(); + while (test_taxon) { + depth++; + if (test_taxon == mrca) { + return depth; + } + test_taxon = test_taxon->GetParent(); + } + return depth; + } + + template + std::set::taxon_t>> Systematics::GetCanopyExtantRoots(int time_point) const { + // NOTE: This could be made faster by doing something similar to the pairwise distance + // function + using taxon_t = Systematics::taxon_t; + std::set< Ptr> result; + // std::cout << "starting " << time_point << std::endl; + for (Ptr tax : active_taxa) { + // std::cout << tax->GetInfo() << std::endl; + while (tax) { + // std::cout << tax->GetInfo() << " " << tax->GetOriginationTime() << " " << tax->GetDestructionTime() << std::endl; + if (tax->GetOriginationTime() <= time_point && tax->GetDestructionTime() > time_point ) { + result.insert(tax); + // std::cout << "inserting " << tax->GetInfo() << std::endl; + break; + } + tax = tax->GetParent(); + } + } + + return result; + + } + + template + int Systematics::GetPhylogeneticDiversityNormalize(int generation, std::string filename) const { + int gen_value = ((generation / 10) - 1); //indexes from 0, 100 generations would correspond to the 10th line in the csv + // bool percent_found = false; + int phylogenetic_diversity = ancestor_taxa.size() + active_taxa.size() - 1; + + if(filename == ""){ + //std::cout << "Phylogenetic Diversity is " << phylogenetic_diversity << std::endl; + return phylogenetic_diversity; + } else{ + + emp::File generation_percentiles(filename); //opens file + emp::vector< emp::vector >percentile_data = generation_percentiles.ToData(","); //turns file contents into vector + + for(int j = 0; j <= percentile_data[gen_value].size() - 2; j++){ //searches through vector for slot where phylo diversity fits + + if((percentile_data[gen_value][j] <= phylogenetic_diversity) && (percentile_data[gen_value][j + 1] > phylogenetic_diversity)){ + // std::cout << "phylogenetic diversity is in between: " << percentile_data[gen_value][j] << "and " << percentile_data[gen_value][j+1] << std::endl; + // std::cout << "The phylogenetic diversity value " << phylogenetic_diversity << " is in the " << j << " percentile, in the " << ((gen_value + 1)* 10) << " generation" << std::endl; + return j; + } + } + } + return 100; + } + + template + int Systematics::GetMaxDepth() const { + if (max_depth != -1) { + return max_depth; + } + + for (auto tax : active_taxa) { + max_depth = std::max(max_depth, static_cast(tax->GetDepth())); + } + return max_depth; + } + + template + void Systematics::LoadFromFile(const std::string & file_path, + const std::string & info_col, + bool assume_leaves_extant, + bool adjust_total_offspring ) { + + // We can only load phylogenies from file if their info can be + // converted to this systematics object's ORG_INFO type (if you + // have a complex type, you can just use a string representation) + if constexpr (!emp::is_streamable::value) { + emp_optional_throw(false, "Failed to load phylogeny from file. ORG_INFO template type cannot be created from string"); + return; + } + + emp_optional_throw(active_taxa.size() == 0 && ancestor_taxa.size() == 0 && outside_taxa.size() == 0, + "LoadFromFile is intended to be used on an empty systematics object."); + + // Load files + emp::File in_file(file_path); + emp::vector header = in_file.ExtractRow(); + + // Find column ids + auto id_pos_it = std::find(header.begin(), header.end(), "id"); + emp_optional_throw(id_pos_it != header.end(), + "Input phylogeny file must be in ALife Phylogeny Data Standards format id column is missing"); + size_t id_pos = std::distance(header.begin(), id_pos_it); + + auto anc_pos_it = std::find(header.begin(), header.end(), "ancestor_list"); + emp_optional_throw(anc_pos_it != header.end(), + "Input phylogeny file must be in ALife Phylogeny Data Standards format ancestor_list column is missing"); + size_t anc_pos = std::distance(header.begin(), anc_pos_it); + + auto origin_pos_it = std::find(header.begin(), header.end(), "origin_time"); + int origin_pos = -1; + if(origin_pos_it != header.end()){ + origin_pos = std::distance(header.begin(), origin_pos_it); + } + + auto destruction_pos_it = std::find(header.begin(), header.end(), "destruction_time"); + int destruction_pos = -1; + if (destruction_pos_it != header.end()) { + destruction_pos = std::distance(header.begin(), destruction_pos_it); + } + + auto num_orgs_pos_it = std::find(header.begin(), header.end(), "num_orgs"); + int num_orgs_pos = -1; + if (num_orgs_pos_it != header.end()) { + num_orgs_pos = std::distance(header.begin(), num_orgs_pos_it); + } + + auto tot_orgs_pos_it = std::find(header.begin(), header.end(), "tot_orgs"); + int tot_orgs_pos = -1; + if (tot_orgs_pos_it != header.end()) { + tot_orgs_pos = std::distance(header.begin(), tot_orgs_pos_it); + } + + auto info_pos_it = std::find(header.begin(), header.end(), info_col); + emp_optional_throw(info_pos_it != header.end(), + "Input phylogeny file must be in ALife Phylogeny Data Standards format info column name supplied is not in file."); + size_t info_pos = std::distance(header.begin(), info_pos_it); + + // Keep track taxon objects + std::unordered_map > taxa; + // File is out of order, so we have to link up parents + // and offspring after the fact + std::unordered_map unlinked_parents; + // Keep track of roots + emp::vector> roots; + + // Read in each row and make a taxon for it + size_t num_lines = in_file.GetNumLines(); + for (size_t i = 0; i < num_lines; i++) { + const emp::vector row = in_file.ViewRowSlices(i); + const int id = emp::from_string(row[id_pos]); + + // Inf means this taxon is still alive + // or we don't know which taxa are alive + std::string destruction_time = "inf"; + if (destruction_pos != -1) { + destruction_time = row[destruction_pos]; + } else { + destruction_time = "missing"; + } + + ORG_INFO info; + if constexpr (std::is_same::value) { + info = row[info_pos]; + } else { + info = emp::from_string(row[info_pos]); + } + + // Load ancestor list + std::string ancestor_list_str(row[anc_pos].begin(), row[anc_pos].end()); + emp::remove_chars(ancestor_list_str, "[]\""); + emp::Ptr tax; + + // Make taxon (parent is nullptr for now) + tax.New(id, info); + if (destruction_time != "inf") { + ancestor_taxa.insert(tax); + } else { + active_taxa.insert(tax); + } + + // Fill in destruction and origin time if + // provided + if (origin_pos != -1 ){ + double origin_time = emp::from_string(row[origin_pos]); + tax->SetOriginationTime(origin_time); + } + if (destruction_time != "inf" && destruction_time != "missing") { + tax->SetDestructionTime(emp::from_string(destruction_time)); + } + + // Fill in number of current and total orgs if provided + if (num_orgs_pos != -1) { + size_t num_orgs = emp::from_string(row[num_orgs_pos]); + tax->SetNumOrgs(num_orgs); + } + if (tot_orgs_pos != -1) { + size_t tot_orgs = emp::from_string(row[tot_orgs_pos]); + tax->SetTotOrgs(tot_orgs); + } + + // Store taxon pointer + taxa[id] = tax; + // Keep track of parents so we can link up later + if (emp::to_lower(ancestor_list_str) != "none") { + emp::vector ancestor_split = emp::slice(ancestor_list_str, ','); + emp::vector ancestor_list = emp::from_strings(ancestor_split); + emp_optional_throw(ancestor_list.size()==1, "Error: individual can only have one parent in phylogeny file."); + unlinked_parents[id] = ancestor_list[0]; + } else { + // If no parent, this is a root + num_roots++; + roots.push_back(tax); + } + } + + // Link up parents and offspring + for (auto &[child_id, parent_id] : unlinked_parents) { + taxa[child_id]->parent = taxa[parent_id]; + taxa[parent_id]->offspring.insert(taxa[child_id]); + taxa[parent_id]->num_offspring++; + } + + // Set up depth + emp::vector> leaves; + emp::vector> to_explore; + for (auto root : roots) { + root->depth = 0; + root->total_offspring = 0; + for (auto offspring : root->GetOffspring()) { + to_explore.push_back(offspring); + } + } + + // Step through all taxa and fix their + // bookkeeping + // Traversal starting at roots to ensure + // parent depth is correct when setting offspring + // depth + emp::Ptr curr; + while(!to_explore.empty()) { + curr = to_explore.back(); + to_explore.pop_back(); + curr->total_offspring = 0; + curr->depth = curr->GetParent()->depth + 1; + total_depth += curr->depth; + for (auto offspring : curr->GetOffspring()){ + to_explore.push_back(offspring); + } + if (curr->GetNumOff() == 0) { + leaves.push_back(curr); + } + } + + // If we're assuming that all leave are extant, + // move leaves to active taxa + if (assume_leaves_extant) { + for (auto leaf : leaves) { + if (!Has(active_taxa, leaf)) { + ancestor_taxa.erase(leaf); + active_taxa.insert(leaf); + } + } + } else { + // Move stuff over to outside taxa + for (auto leaf : leaves) { + if (Has(ancestor_taxa, leaf)) { + ancestor_taxa.erase(leaf); + outside_taxa.insert(leaf); + emp::Ptr parent = leaf->GetParent(); + while (parent && Has(ancestor_taxa, parent)) { + ancestor_taxa.erase(parent); + outside_taxa.insert(parent); + parent = parent->GetParent(); + } + } + } + } + + if (num_orgs_pos == -1) { + num_orgs_defaulted = true; + for (auto tax : active_taxa) { + tax->SetNumOrgs(1); + tax->SetTotOrgs(1); + org_count++; + } + } else { + org_count = std::accumulate(active_taxa.begin(), active_taxa.end(), 0, [](int sum, Ptr tax) { + return sum + tax->GetNumOrgs(); + }); + } + + // Adjust total offspring + if (adjust_total_offspring) { + for (auto tax : active_taxa) { + if (tax->parent) { + tax->parent->AddTotalOffspring(); + } + } + } else { + total_offspring_defaulted = true; + } + + // Force stats to be recalculated + max_depth = -1; + mrca = nullptr; + + } + } #endif // #ifndef EMP_EVOLVE_SYSTEMATICS_HPP_INCLUDE diff --git a/include/emp/Evolve/World.hpp b/include/emp/Evolve/World.hpp index 762ddca409..ee539dac78 100644 --- a/include/emp/Evolve/World.hpp +++ b/include/emp/Evolve/World.hpp @@ -943,6 +943,7 @@ namespace emp { }; + #ifndef DOXYGEN_SHOULD_SKIP_THIS // ============================================================= // === === // === Out-of-class member function definitions from above === @@ -972,7 +973,7 @@ namespace emp { // Track the new systematics info for (Ptr > s : systematics) { - s->AddOrg(*new_org, pos, (int) update); + s->AddOrg(*new_org, pos); } SetupOrg(*new_org, pos, *random_ptr); @@ -996,7 +997,7 @@ namespace emp { } for (Ptr > s : systematics) { - s->RemoveOrgAfterRepro(pos, update); // Notify systematics about organism removal + s->RemoveOrgAfterRepro(pos); // Notify systematics about organism removal } } @@ -1489,6 +1490,13 @@ namespace emp { pop.resize(0); std::swap(pops[0], pops[1]); // Move next pop into place. + // Tell systematics manager to swap next population and population + // Needs to happen here so that you can refer to systematics in + // OnPlacement functions + for (Ptr> s : systematics) { + s->Update(); + } + // Update the active population. num_orgs = 0; for (size_t i = 0; i < pop.size(); i++) { @@ -1498,12 +1506,7 @@ namespace emp { } } - // 3. Handle systematics and any data files that need to be printed this update. - - // Tell systematics manager to swap next population and population - for (Ptr> s : systematics) { - s->Update(); - } + // 3. Handle any data files that need to be printed this update. for (auto file : files) file->Update(update); @@ -1734,6 +1737,7 @@ namespace emp { os << std::endl; } } + #endif // DOXYGEN_SHOULD_SKIP_THIS } #endif // #ifndef EMP_EVOLVE_WORLD_HPP_INCLUDE diff --git a/include/emp/base/_assert_macros.hpp b/include/emp/base/_assert_macros.hpp index a403b06b4c..1d24daed43 100644 --- a/include/emp/base/_assert_macros.hpp +++ b/include/emp/base/_assert_macros.hpp @@ -18,6 +18,7 @@ #define emp_assert_STRINGIFY_IMPL(...) #__VA_ARGS__ #define emp_assert_TO_PAIR(X) emp_assert_STRINGIFY(X) , X #define emp_assert_GET_ARG_1(a, ...) a +#define emp_assert_GET_ARG_2(a,b, ...) b #define emp_assert_GET_ARG_21(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t, u, ...) u #define emp_assert_MERGE(A, B) A ## B #define emp_assert_ASSEMBLE(BASE, ARG_COUNT, ...) emp_assert_MERGE(BASE, ARG_COUNT) (__VA_ARGS__) diff --git a/include/emp/base/_optional_throw.hpp b/include/emp/base/_optional_throw.hpp new file mode 100644 index 0000000000..821406c113 --- /dev/null +++ b/include/emp/base/_optional_throw.hpp @@ -0,0 +1,60 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2024 +*/ +/** + * @file + * @brief Implementation of emp_optional_throw. + */ + +#ifndef EMP_BASE__OPTIONAL_THROW_HPP_INCLUDE +#define EMP_BASE__OPTIONAL_THROW_HPP_INCLUDE + +#include +#include + +#include "_is_streamable.hpp" + +namespace emp { + + /// Base case for assert_print... + inline void assert_print_opt(std::stringstream &) { ; } + + /// Print out information about the next variable and recurse... + template + void assert_print_opt(std::stringstream & ss, std::string name, T && val, EXTRA &&... extra) { + if constexpr ( emp::is_streamable::value ) { + ss << name << ": [" << val << "]" << std::endl; + } else ss << name << ": (non-streamable type)" << std::endl; + assert_print_opt(ss, std::forward(extra)...); + } + + template + void assert_print_second_opt(std::stringstream & ss, std::string name, T && val, EXTRA &&... extra) { + assert_print_opt(ss, std::forward(extra)...); + } + + template + void assert_print_second_opt(std::stringstream & ss, std::string name, T && val) {;} + + template + void assert_print_first_opt(std::stringstream & ss, std::string name, T && val, EXTRA &&... extra) { + if constexpr ( emp::is_streamable::value ) { + ss << name << ": [" << val << "]" << std::endl; + } else ss << name << ": (non-streamable type)" << std::endl; + assert_print_second_opt(ss, std::forward(extra)...); + } + + void assert_print_first_opt(std::stringstream & ss, int placeholder) {;} + + template + void assert_throw_opt(std::string filename, size_t line, std::string expr, std::string message, EXTRA &&... extra) { + std::stringstream ss; + ss << "Internal Error (in " << filename << " line " << line << "): " << expr << ".\n\n Message: " << message << "\n\n"; + assert_print_first_opt(ss, std::forward(extra)...); + throw(std::runtime_error(ss.str())); + } +} + +#endif // #ifndef EMP_BASE__OPTIONAL_THROW_HPP_INCLUDE diff --git a/include/emp/base/always_assert.hpp b/include/emp/base/always_assert.hpp index e5ec365210..a4c34b4995 100644 --- a/include/emp/base/always_assert.hpp +++ b/include/emp/base/always_assert.hpp @@ -34,6 +34,7 @@ #include "_assert_macros.hpp" #include "_assert_trigger.hpp" +#include "_optional_throw.hpp" #if defined( __EMSCRIPTEN__ ) @@ -58,6 +59,19 @@ #define emp_always_assert_impl(TEST) emp_always_assert_msvc_impl(TEST) +#elif defined(EMP_OPTIONAL_THROW_ON) + + #define emp_always_assert_impl(...) \ + do { \ + if (!(emp_assert_GET_ARG_1(__VA_ARGS__, ~))) { \ + emp::assert_throw( \ + __FILE__, __LINE__, \ + emp_assert_STRINGIFY( emp_assert_GET_ARG_1(__VA_ARGS__, ~), ), \ + emp_assert_TO_PAIRS(__VA_ARGS__)); \ + } \ + } while(0) + + #else #define emp_always_assert_impl(...) \ diff --git a/include/emp/base/optional_throw.hpp b/include/emp/base/optional_throw.hpp new file mode 100644 index 0000000000..5adc62921e --- /dev/null +++ b/include/emp/base/optional_throw.hpp @@ -0,0 +1,70 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2024 +*/ +/** + * @file + * @brief A version of emp_assert that throws a runtime error if compiled with -DEMP_OPTIONAL_THROW_ON. + * + * This is useful if you want the option to throw a runtime error outside of debug mode. A common use + * case is wrapping C++ code in Python, since segfaults kill the entire Python interpreter. + */ + +#ifndef EMP_BASE_OPTIONAL_THROW_HPP_INCLUDE +#define EMP_BASE_OPTIONAL_THROW_HPP_INCLUDE + +#include "assert.hpp" + +/// NDEBUG should trigger its EMP equivalent. +#ifdef NDEBUG +#define EMP_NDEBUG +#endif + + +#if defined( EMP_OPTIONAL_THROW_ON ) + + // #if defined (_MSC_VER ) + + #define emp_optional_throw(TEST, MESSAGE) \ + do { \ + if (!(TEST)) { \ + emp::assert_throw_opt(__FILE__, __LINE__, #TEST, MESSAGE, 0); \ + } \ + } while(0) + + /* #define emp_optional_throw_impl(TEST, MESSAGE) emp_optional_throw_mscv_impl(TEST, MESSAGE) + + / #else + + / #define emp_optional_throw_impl(...) \ + / do { \ + / if (!(emp_assert_GET_ARG_1(__VA_ARGS__, ~))) { \ + / emp::assert_throw( \ + / __FILE__, __LINE__, \ + / emp_assert_STRINGIFY( emp_assert_GET_ARG_1(__VA_ARGS__, ~), ), \ + / emp_assert_STRINGIFY( emp_assert_GET_ARG_2(__VA_ARGS__, ~), ), \ + / emp_assert_TO_PAIRS(__VA_ARGS__)); \ + / } \ + / } while(0) + + / #endif + + / #define emp_optional_throw(...) emp_optional_throw_impl(__VA_ARGS__) + */ +#elif defined( EMP_NDEBUG ) + + #define emp_optional_throw(...) + +#else + /// Require a specified condition to be true. If it is false, immediately + /// halt execution. Print also extra information on any variables or + /// expressions provided as variadic args. Note: If NDEBUG is defined, + /// emp_assert() will not do anything. Due to macro parsing limitations, extra + /// information will not be printed when compiling with MSVC. + #define emp_optional_throw(...) emp_assert(__VA_ARGS__) + +#endif + + +#endif // #ifndef EMP_BASE_OPTIONAL_THROW_HPP_INCLUDE diff --git a/include/emp/data/DataManager.hpp b/include/emp/data/DataManager.hpp index fa0b2bc03c..b78553f79b 100644 --- a/include/emp/data/DataManager.hpp +++ b/include/emp/data/DataManager.hpp @@ -54,6 +54,10 @@ namespace emp { return Has(node_map, name); } + bool HasNoNode(const std::string & name) { + return !Has(node_map, name); + } + /// Creates and adds a new DataNode /// @param name the name of the DataNode node_t & New(const std::string & name) { diff --git a/include/emp/datastructs/map_utils.hpp b/include/emp/datastructs/map_utils.hpp index 9f97841274..6cd27a4dea 100644 --- a/include/emp/datastructs/map_utils.hpp +++ b/include/emp/datastructs/map_utils.hpp @@ -41,6 +41,19 @@ namespace emp { return in_map.find(key) != in_map.end(); } + /// Take a map where the value is an integer and a key. + /// Increment value associated with that key if its present + /// or if its not add it and set it to 1 + template + inline void IncrementCounter( MAP_T & in_map, const KEY_T & key ) { + static_assert( std::is_same< typename MAP_T::key_type, int >::value); + if (emp::Has(in_map, key)) { + in_map[key]++; + } else { + in_map[key] = 1; + } + } + // Check to see if any of the elements in a map satisfy a function. template bool AnyOf(const std::map & c, FUN_T fun) { diff --git a/include/emp/math/info_theory.hpp b/include/emp/math/info_theory.hpp index d2d9abad82..6891158bcc 100644 --- a/include/emp/math/info_theory.hpp +++ b/include/emp/math/info_theory.hpp @@ -57,7 +57,7 @@ namespace emp { double entropy = 0.0; for (auto & o : objs) { double p = ((double) fun(o)) / total; - entropy -= p * Log2(p); + entropy -= p * log2(p); } return entropy; } diff --git a/tests/Evolve/Systematics.cpp b/tests/Evolve/Systematics.cpp index 8c02c4de46..360ba68fc9 100644 --- a/tests/Evolve/Systematics.cpp +++ b/tests/Evolve/Systematics.cpp @@ -1,14 +1,15 @@ /* * This file is part of Empirical, https://github.com/devosoft/Empirical * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * date: 2021 + * date: 2024 */ /** * @file + * @brief TODO. */ +#include #include -#include #include "third-party/Catch/single_include/catch2/catch.hpp" @@ -23,83 +24,90 @@ #include "emp/Evolve/World_output.hpp" #include "emp/hardware/AvidaGP.hpp" - -TEST_CASE("Test Systematics", "[Evolve]") -{ - +TEST_CASE("Test Systematics", "[Evolve]") { // Taxon emp::Taxon tx(0, "a"); - REQUIRE(tx.GetID() == 0); - REQUIRE(tx.GetParent() == nullptr); - REQUIRE(tx.GetInfo() == "a"); - REQUIRE(tx.GetNumOrgs() == 0); - REQUIRE(tx.GetTotOrgs() == 0); + CHECK(tx.GetID() == 0); + CHECK(tx.GetParent() == nullptr); + CHECK(tx.GetInfo() == "a"); + CHECK(tx.GetNumOrgs() == 0); + CHECK(tx.GetTotOrgs() == 0); tx.AddOrg(); - REQUIRE(tx.GetNumOrgs() == 1); + CHECK(tx.GetNumOrgs() == 1); tx.RemoveOrg(); - REQUIRE(tx.GetNumOrgs() == 0); - REQUIRE(tx.GetTotOrgs() == 1); - REQUIRE(tx.GetTotalOffspring() == 0); + CHECK(tx.GetNumOrgs() == 0); + CHECK(tx.GetTotOrgs() == 1); + CHECK(tx.GetTotalOffspring() == 0); emp::Ptr< emp::Taxon > parentPtr(&tx); emp::Taxon tx_1(1, "b", parentPtr); - REQUIRE(tx_1.GetParent() == parentPtr); + CHECK(tx_1.GetParent() == parentPtr); tx_1.AddTotalOffspring(); - REQUIRE(tx_1.GetTotalOffspring() == 1); - REQUIRE(tx.GetTotalOffspring() == 1); + CHECK(tx_1.GetTotalOffspring() == 1); + CHECK(tx.GetTotalOffspring() == 1); // Systematics std::function calc_taxon = [](double & o){ return o > 50.0 ? "large" : "small"; }; emp::Systematics sys1(calc_taxon); - REQUIRE(sys1.GetTrackSynchronous() == false); - REQUIRE(sys1.GetNumAncestors() == 0); - REQUIRE(sys1.GetNumActive() == 0); - REQUIRE(sys1.GetNumOutside() == 0); - REQUIRE(sys1.GetTreeSize() == 0); - REQUIRE(sys1.GetNumTaxa() == 0); + CHECK(sys1.GetTrackSynchronous() == false); + CHECK(sys1.GetNumAncestors() == 0); + CHECK(sys1.GetNumActive() == 0); + CHECK(sys1.GetNumOutside() == 0); + CHECK(sys1.GetTreeSize() == 0); + CHECK(sys1.GetNumTaxa() == 0); sys1.SetTrackSynchronous(true); - sys1.AddOrg(15.0, {0,0}, 0); - REQUIRE(sys1.GetNumActive() == 1); - REQUIRE(sys1.GetTaxonAt(0)->GetInfo() == "small"); - sys1.AddOrg(56.0, {1,1}, 0); - REQUIRE(sys1.GetNumActive() == 2); - REQUIRE(sys1.GetNextTaxonAt(1)->GetInfo() == "large"); + CHECK(sys1.GetTrackSynchronous() == true); + sys1.AddOrg(15.0, {0,0}); + CHECK(sys1.CalcDiversity() == 0); + CHECK(sys1.GetNumActive() == 1); + CHECK(sys1.GetTaxonAt({0,0})->GetInfo() == "small"); + CHECK(sys1.IsTaxonAt({0,0})); + sys1.AddOrg(56.0, {1,1}); + CHECK(sys1.GetNumActive() == 2); + CHECK(sys1.CalcDiversity() == 1); + CHECK(sys1.GetTaxonAt({1,1})->GetInfo() == "large"); + CHECK(sys1.IsTaxonAt({1,1})); sys1.RemoveOrg({1,1}); - REQUIRE(sys1.GetNumActive() == 1); + CHECK(!sys1.IsTaxonAt({1,1})); + CHECK(sys1.GetNumActive() == 1); + sys1.AddOrg(56.0, {1,0}); + CHECK(sys1.IsTaxonAt({1,0})); + CHECK(!sys1.RemoveOrg({1,0})); + CHECK(!sys1.IsTaxonAt({1,0})); // Base setters and getters - REQUIRE(sys1.GetStoreActive() == true); - REQUIRE(sys1.GetStoreAncestors() == true); - REQUIRE(sys1.GetStoreOutside() == false); - REQUIRE(sys1.GetArchive() == true); - REQUIRE(sys1.GetStorePosition() == true); + CHECK(sys1.GetStoreActive() == true); + CHECK(sys1.GetStoreAncestors() == true); + CHECK(sys1.GetStoreOutside() == false); + CHECK(sys1.GetArchive() == true); + CHECK(sys1.GetStorePosition() == true); sys1.SetStoreActive(false); - REQUIRE(sys1.GetStoreActive() == false); + CHECK(sys1.GetStoreActive() == false); sys1.SetStoreAncestors(false); - REQUIRE(sys1.GetStoreAncestors() == false); + CHECK(sys1.GetStoreAncestors() == false); sys1.SetStoreOutside(true); - REQUIRE(sys1.GetStoreOutside() == true); + CHECK(sys1.GetStoreOutside() == true); sys1.SetArchive(false); - REQUIRE(sys1.GetArchive() == false); + CHECK(sys1.GetArchive() == false); sys1.SetStorePosition(false); - REQUIRE(sys1.GetStorePosition() == false); + CHECK(sys1.GetStorePosition() == false); #ifndef NDEBUG - sys1.AddDeleteriousStepDataNodeImpl(true); - REQUIRE(emp::assert_last_fail); + sys1.AddDeleteriousStepDataNode(); + CHECK(emp::assert_last_fail); emp::assert_clear(); - sys1.AddVolatilityDataNodeImpl(true); - REQUIRE(emp::assert_last_fail); + sys1.AddVolatilityDataNode(); + CHECK(emp::assert_last_fail); emp::assert_clear(); - sys1.AddUniqueTaxaDataNodeImpl(true); - REQUIRE(emp::assert_last_fail); + sys1.AddUniqueTaxaDataNode(); + CHECK(emp::assert_last_fail); emp::assert_clear(); - sys1.AddMutationCountDataNodeImpl(true); - REQUIRE(emp::assert_last_fail); + sys1.AddMutationCountDataNode(); + CHECK(emp::assert_last_fail); emp::assert_clear(); #endif @@ -108,138 +116,161 @@ TEST_CASE("Test Systematics", "[Evolve]") //emp::Systematics sys2(calc_taxon) my_taxon taxon1(1, "medium"); emp::Ptr ptr1 = &taxon1; - REQUIRE(emp::LineageLength(ptr1) == 1); + CHECK(emp::LineageLength(ptr1) == 1); my_taxon taxon2(1, "medium", ptr1); emp::Ptr ptr2 = &taxon2; - REQUIRE(emp::LineageLength(ptr1) == 1); - REQUIRE(emp::LineageLength(ptr2) == 2); + CHECK(emp::LineageLength(ptr1) == 1); + CHECK(emp::LineageLength(ptr2) == 2); std::unordered_map muts; muts["short"] = 12; muts["tall"] = 3; taxon2.GetData().RecordMutation(muts); - REQUIRE(taxon2.GetData().mut_counts.size() == 2); - REQUIRE(taxon2.GetData().mut_counts["tall"] == 3); + CHECK(taxon2.GetData().mut_counts.size() == 2); + CHECK(taxon2.GetData().mut_counts["tall"] == 3); emp::vector types; types.push_back("tall"); types.push_back("short"); - REQUIRE(emp::CountMuts(ptr2, types) == 15); - REQUIRE(emp::CountMutSteps(ptr2, types) == 2); - REQUIRE(emp::CountMutSteps(ptr2, "short") == 1); + CHECK(emp::CountMuts(ptr2, types) == 15); + CHECK(emp::CountMutSteps(ptr2, types) == 2); + CHECK(emp::CountMutSteps(ptr2, "short") == 1); muts["short"] = 4; taxon1.GetData().RecordMutation(muts); - REQUIRE(emp::CountMuts(ptr1, "short") == 4); - REQUIRE(emp::CountMuts(ptr2, "short") == 16); - REQUIRE(emp::CountMutSteps(ptr1, "short") == 1); - REQUIRE(emp::CountMutSteps(ptr2, "short") == 2); - - emp::Systematics sys([](const int & i){return i;}, true, true, true, false); - - std::cout << "\nAddOrg 25 (id1, no parent)\n"; - auto id1 = sys.AddOrg(25, nullptr, 0); - std::cout << "\nAddOrg -10 (id2; parent id1)\n"; - auto id2 = sys.AddOrg(-10, id1, 6); - std::cout << "\nAddOrg 26 (id3; parent id1)\n"; - auto id3 = sys.AddOrg(26, id1, 10); - std::cout << "\nAddOrg 27 (id4; parent id2)\n"; - auto id4 = sys.AddOrg(27, id2, 25); - std::cout << "\nAddOrg 28 (id5; parent id2)\n"; - auto id5 = sys.AddOrg(28, id2, 32); - std::cout << "\nAddOrg 29 (id6; parent id5)\n"; - auto id6 = sys.AddOrg(29, id5, 39); - std::cout << "\nAddOrg 30 (id7; parent id1)\n"; - auto id7 = sys.AddOrg(30, id1, 6); - - - std::cout << "\nRemoveOrg (id2)\n"; + CHECK(emp::CountMuts(ptr1, "short") == 4); + CHECK(emp::CountMuts(ptr2, "short") == 16); + CHECK(emp::CountMutSteps(ptr1, "short") == 1); + CHECK(emp::CountMutSteps(ptr2, "short") == 2); + + emp::Systematics sys([](const int & i){return i;}, true, true, true, false); + + // std::cout << "\nAddOrg 25 (id1, no parent)\n"; + sys.SetUpdate(0); + auto id1 = sys.AddOrg(25, nullptr); + // std::cout << "\nAddOrg -10 (id2; parent id1)\n"; + sys.SetUpdate(6); + auto id2 = sys.AddOrg(-10, id1); + // std::cout << "\nAddOrg 26 (id3; parent id1)\n"; + sys.SetUpdate(10); + auto id3 = sys.AddOrg(26, id1); + // std::cout << "\nAddOrg 27 (id4; parent id2)\n"; + sys.SetUpdate(25); + auto id4 = sys.AddOrg(27, id2); + // std::cout << "\nAddOrg 28 (id5; parent id2)\n"; + sys.SetUpdate(32); + auto id5 = sys.AddOrg(28, id2); + // std::cout << "\nAddOrg 29 (id6; parent id5)\n"; + sys.SetUpdate(39); + auto id6 = sys.AddOrg(29, id5); + // std::cout << "\nAddOrg 30 (id7; parent id1)\n"; + sys.SetUpdate(6); + auto id7 = sys.AddOrg(30, id1); + + CHECK(*id1 < *id2); + CHECK(sys.Parent(id2) == id1); + + // std::cout << "\nRemoveOrg (id2)\n"; sys.RemoveOrg(id1); sys.RemoveOrg(id2); double mpd = sys.GetMeanPairwiseDistance(); - std::cout << "MPD: " << mpd <GetNumOff() == 0); CHECK(outside_taxon->GetParent()->GetID() == 8); + CHECK(sys.GetMaxDepth() == 8); + auto active = sys.GetActive(); emp::vector>> active_vec(active.begin(), active.end()); emp::Sort(active_vec, [](emp::Ptr> & a, emp::Ptr> & b){ @@ -370,80 +403,92 @@ TEST_CASE("Test Systematics", "[Evolve]") CHECK(active_vec[10]->GetNumOrgs() == 1); CHECK(active_vec[10]->GetNumOff() == 0); CHECK(active_vec[10]->GetParent()->GetID() == 17); - } -TEST_CASE("Test not tracking ancestors", "[Evolve]") -{ +TEST_CASE("Test not tracking ancestors", "[Evolve]") { emp::Systematics sys([](const int & i){return i;}, true, false, false, false); - std::cout << "\nAddOrg 25 (id1, no parent)\n"; - auto id1 = sys.AddOrg(25, nullptr, 0); - std::cout << "\nAddOrg -10 (id2; parent id1)\n"; - auto id2 = sys.AddOrg(-10, id1, 6); - std::cout << "\nAddOrg 26 (id3; parent id1)\n"; - auto id3 = sys.AddOrg(26, id1, 10); - std::cout << "\nAddOrg 27 (id4; parent id2)\n"; - auto id4 = sys.AddOrg(27, id2, 25); - std::cout << "\nAddOrg 28 (id5; parent id2)\n"; - auto id5 = sys.AddOrg(28, id2, 32); - std::cout << "\nAddOrg 29 (id6; parent id5)\n"; - auto id6 = sys.AddOrg(29, id5, 39); - std::cout << "\nAddOrg 30 (id7; parent id1)\n"; - auto id7 = sys.AddOrg(30, id1, 6); - - - std::cout << "\nRemoveOrg (id2)\n"; + // std::cout << "\nAddOrg 25 (id1, no parent)\n"; + sys.SetUpdate(0); + auto id1 = sys.AddOrg(25, nullptr); + // std::cout << "\nAddOrg -10 (id2; parent id1)\n"; + sys.SetUpdate(6); + auto id2 = sys.AddOrg(-10, id1); + // std::cout << "\nAddOrg 26 (id3; parent id1)\n"; + sys.SetUpdate(10); + auto id3 = sys.AddOrg(26, id1); + // std::cout << "\nAddOrg 27 (id4; parent id2)\n"; + sys.SetUpdate(25); + auto id4 = sys.AddOrg(27, id2); + // std::cout << "\nAddOrg 28 (id5; parent id2)\n"; + sys.SetUpdate(32); + auto id5 = sys.AddOrg(28, id2); + // std::cout << "\nAddOrg 29 (id6; parent id5)\n"; + sys.SetUpdate(39); + auto id6 = sys.AddOrg(29, id5); + // std::cout << "\nAddOrg 30 (id7; parent id1)\n"; + sys.SetUpdate(6); + auto id7 = sys.AddOrg(30, id1); + + + // std::cout << "\nRemoveOrg (id2)\n"; sys.RemoveOrg(id1); sys.RemoveOrg(id2); - double mpd = sys.GetMeanPairwiseDistance(); - std::cout << "Mean Pairwise Distance = " << mpd << "\n"; - - std::cout << "\nAddOrg 31 (id8; parent id7)\n"; - auto id8 = sys.AddOrg(31, id7, 11); - std::cout << "\nAddOrg 32 (id9; parent id8)\n"; - auto id9 = sys.AddOrg(32, id8, 19); + // std::cout << "\nAddOrg 31 (id8; parent id7)\n"; + sys.SetUpdate(11); + auto id8 = sys.AddOrg(31, id7); + // std::cout << "\nAddOrg 32 (id9; parent id8)\n"; + sys.SetUpdate(19); + auto id9 = sys.AddOrg(32, id8); - std::cout << "\nAddOrg 33 (id10; parent id8)\n"; - auto id10 = sys.AddOrg(33, id8, 19); + // std::cout << "\nAddOrg 33 (id10; parent id8)\n"; + auto id10 = sys.AddOrg(33, id8); sys.RemoveOrg(id7); sys.RemoveOrg(id8); sys.RemoveOrg(id10); - - std::cout << "\nAddOrg 34 (id11; parent id9)\n"; - auto id11 = sys.AddOrg(34, id9, 22); - std::cout << "\nAddOrg 35 (id12; parent id10)\n"; - auto id12 = sys.AddOrg(35, id11, 23); + // std::cout << "\nAddOrg 34 (id11; parent id9)\n"; + sys.SetUpdate(22); + auto id11 = sys.AddOrg(34, id9); + // std::cout << "\nAddOrg 35 (id12; parent id10)\n"; + sys.SetUpdate(23); + auto id12 = sys.AddOrg(35, id11); sys.RemoveOrg(id9); - std::cout << "\nAddOrg 36 (id13; parent id12)\n"; - auto id13 = sys.AddOrg(36, id12, 27); - std::cout << "\nAddOrg 37 (id14; parent id13)\n"; - auto id14 = sys.AddOrg(37, id13, 30); + // std::cout << "\nAddOrg 36 (id13; parent id12)\n"; + sys.SetUpdate(27); + auto id13 = sys.AddOrg(36, id12); + // std::cout << "\nAddOrg 37 (id14; parent id13)\n"; + sys.SetUpdate(30); + auto id14 = sys.AddOrg(37, id13); sys.RemoveOrg(id13); - std::cout << "\nAddOrg 38 (id15; parent id14)\n"; - auto id15 = sys.AddOrg(38, id14, 33); + // std::cout << "\nAddOrg 38 (id15; parent id14)\n"; + sys.SetUpdate(33); + auto id15 = sys.AddOrg(38, id14); sys.RemoveOrg(id14); - std::cout << "\nAddOrg 39 (id16; parent id11)\n"; - auto id16 = sys.AddOrg(39, id11, 35); - std::cout << "\nAddOrg 40 (id17; parent id11)\n"; - auto id17 = sys.AddOrg(40, id11, 35); + // std::cout << "\nAddOrg 39 (id16; parent id11)\n"; + sys.SetUpdate(35); + auto id16 = sys.AddOrg(39, id11); + // std::cout << "\nAddOrg 40 (id17; parent id11)\n"; + auto id17 = sys.AddOrg(40, id11); - std::cout << "\nAddOrg 41 (id18; parent id17)\n"; - auto id18 = sys.AddOrg(41, id17, 36); + // std::cout << "\nAddOrg 41 (id18; parent id17)\n"; + sys.SetUpdate(36); + auto id18 = sys.AddOrg(41, id17); std::cout << "\nAddOrg 42 (id19; parent id17)\n"; - auto id19 = sys.AddOrg(42, id17, 37); - REQUIRE(id17->GetTotalOffspring() > 0); + sys.SetUpdate(37); + auto id19 = sys.AddOrg(42, id17); + + CHECK(id17->GetTotalOffspring() > 0); std::cout << "id3 = " << id3 << std::endl; std::cout << "id4 = " << id4 << std::endl; @@ -533,11 +578,14 @@ TEST_CASE("Pointer to systematics", "[evo]") { sys.Delete(); } -TEST_CASE("Test Data Struct", "[evo]") -{ +TEST_CASE("Test Data Struct", "[evo]") { emp::Ptr >> sys; sys.New([](const int & i){return i;}, true, true, true, false); + sys->AddMutationCountDataNode(); + sys->AddVolatilityDataNode(); + sys->AddUniqueTaxaDataNode(); + auto id1 = sys->AddOrg(1, nullptr); id1->GetData().fitness.Add(2); id1->GetData().phenotype = 6; @@ -559,36 +607,79 @@ TEST_CASE("Test Data Struct", "[evo]") id4->GetData().phenotype = 3; auto id5 = sys->AddOrg(5, id4); - id5->GetData().mut_counts["substitution"] = 1; - id5->GetData().fitness.Add(2); - id5->GetData().phenotype = 6; + std::unordered_map muts; + muts["substitution"] = 1; + id5->GetData().RecordMutation(muts); + id5->GetData().RecordFitness(2); + id5->GetData().RecordPhenotype(6); + CHECK(id5->GetData().GetPhenotype() == 6); + CHECK(id5->GetData().GetFitness() == 2); CHECK(CountMuts(id4) == 3); CHECK(CountDeleteriousSteps(id4) == 1); CHECK(CountPhenotypeChanges(id4) == 1); CHECK(CountUniquePhenotypes(id4) == 2); + CHECK(LineageLength(id4) == 3); CHECK(CountMuts(id3) == 5); CHECK(CountDeleteriousSteps(id3) == 1); CHECK(CountPhenotypeChanges(id3) == 0); CHECK(CountUniquePhenotypes(id3) == 1); + CHECK(LineageLength(id3) == 2); CHECK(CountMuts(id5) == 4); CHECK(CountDeleteriousSteps(id5) == 2); CHECK(CountPhenotypeChanges(id5) == 2); CHECK(CountUniquePhenotypes(id5) == 2); + CHECK(LineageLength(id5) == 4); + + CHECK(FindDominant(*sys) == id4); + + sys->GetDataNode("mutation_count")->PullData(); + CHECK(sys->GetDataNode("mutation_count")->GetMean() == Approx(2.8)); + + sys->GetDataNode("volatility")->PullData(); + CHECK(sys->GetDataNode("volatility")->GetMean() == Approx(0.6)); + + sys->GetDataNode("unique_taxa")->PullData(); + CHECK(sys->GetDataNode("unique_taxa")->GetMean() == Approx(1.4)); + sys.Delete(); -} + emp::Ptr> sys2; + sys2.New([](const int & i){return i;}, true, true, true, false); + sys2->AddDeleteriousStepDataNode(); + + auto new_tax = sys2->AddOrg(1, nullptr); + new_tax->GetData().RecordFitness(2); + CHECK(new_tax->GetData().GetFitness() == 2); + new_tax->GetData().RecordFitness(4); + CHECK(new_tax->GetData().GetFitness() == 3); + + emp::datastruct::fitness fit_data; + fit_data.RecordFitness(5); + new_tax->SetData(fit_data); + CHECK(new_tax->GetData().GetFitness() == 5); + + auto tax2 = sys2->AddOrg(2, new_tax); + tax2->GetData().RecordFitness(1); + + sys->GetDataNode("deleterious_steps")->PullData(); + CHECK(sys->GetDataNode("deleterious_steps")->GetMean() == Approx(.5)); + sys2.Delete(); + + +} + TEST_CASE("World systematics integration", "[evo]") { - // std::function, emp::datastruct::mut_landscape_info>>)> setup_phenotype = [](emp::Ptr, emp::datastruct::mut_landscape_info>> tax){ - // tax->GetData().phenotype = emp::Sum(tax->GetInfo()); - // }; + std::function, emp::datastruct::mut_landscape_info>>, emp::vector &)> setup_phenotype = [](emp::Ptr, emp::datastruct::mut_landscape_info>> tax, emp::vector & org){ + tax->GetData().phenotype = emp::Sum(tax->GetInfo()); + }; using systematics_t = emp::Systematics< emp::vector, @@ -603,13 +694,14 @@ TEST_CASE("World systematics integration", "[evo]") { world.SetMutFun([](emp::vector & org, emp::Random & r){return 0;}); - // world.GetSystematics().OnNew(setup_phenotype); + sys->OnNew(setup_phenotype); world.InjectAt(emp::vector({1,2,3}), 0); - sys->GetTaxonAt(0)->GetData().RecordPhenotype(6); - sys->GetTaxonAt(0)->GetData().RecordFitness(2); + CHECK(sys->GetTaxonAt(0)->GetData().phenotype == 6); + sys->GetTaxonAt(0)->GetData().RecordPhenotype(10); + CHECK(sys->GetTaxonAt(0)->GetData().phenotype == 10); - REQUIRE(sys->GetTaxonAt(0)->GetData().phenotype == 6); + sys->GetTaxonAt(0)->GetData().RecordFitness(2); std::unordered_map mut_counts; mut_counts["substitution"] = 3; @@ -618,10 +710,10 @@ TEST_CASE("World systematics integration", "[evo]") { auto old_taxon = sys->GetTaxonAt(0); world.DoBirth(new_org,0); - REQUIRE(old_taxon->GetNumOrgs() == 0); - REQUIRE(old_taxon->GetNumOff() == 1); - REQUIRE(sys->GetTaxonAt(0)->GetParent()->GetData().phenotype == 6); - REQUIRE((*sys->GetActive().begin())->GetNumOrgs() == 1); + CHECK(old_taxon->GetNumOrgs() == 0); + CHECK(old_taxon->GetNumOff() == 1); + CHECK(sys->GetTaxonAt(0)->GetParent()->GetData().phenotype == 10); + CHECK((*sys->GetActive().begin())->GetNumOrgs() == 1); } @@ -630,35 +722,64 @@ emp::DataFile AddDominantFile(WORLD_TYPE & world){ using mut_count_t [[maybe_unused]] = std::unordered_map; using data_t = emp::datastruct::mut_landscape_info>; using org_t = emp::AvidaGP; - using systematics_t = emp::Systematics; + using systematics_t = emp::Systematics; - auto & file = world.SetupFile("dominant.csv"); - - std::function get_update = [&world](){return world.GetUpdate();}; - std::function dom_mut_count = [&world](){ - return CountMuts(dynamic_cast>(world.GetSystematics(0))->GetTaxonAt(0)); - }; - std::function dom_del_step = [&world](){ - return CountDeleteriousSteps(dynamic_cast>(world.GetSystematics(0))->GetTaxonAt(0)); - }; - std::function dom_phen_vol = [&world](){ - return CountPhenotypeChanges(dynamic_cast>(world.GetSystematics(0))->GetTaxonAt(0)); - }; - std::function dom_unique_phen = [&world](){ - return CountUniquePhenotypes(dynamic_cast>(world.GetSystematics(0))->GetTaxonAt(0)); - }; + auto & file = world.SetupFile("dominant.csv"); - - file.AddFun(get_update, "update", "Update"); - file.AddFun(dom_mut_count, "dominant_mutation_count", "sum of mutations along dominant organism's lineage"); - file.AddFun(dom_del_step, "dominant_deleterious_steps", "count of deleterious steps along dominant organism's lineage"); - file.AddFun(dom_phen_vol, "dominant_phenotypic_volatility", "count of changes in phenotype along dominant organism's lineage"); - file.AddFun(dom_unique_phen, "dominant_unique_phenotypes", "count of unique phenotypes along dominant organism's lineage"); - file.PrintHeaderKeys(); - return file; + std::function get_update = [&world](){return world.GetUpdate();}; + std::function dom_mut_count = [&world](){ + emp::Ptr> sys = world.GetSystematics(0); + emp::Ptr full_sys = sys.DynamicCast(); + if (full_sys->GetNumActive() > 0) { + return emp::CountMuts(emp::FindDominant(*full_sys)); + } + return 0; + }; + std::function dom_del_step = [&world](){ + emp::Ptr> sys = world.GetSystematics(0); + emp::Ptr full_sys = sys.DynamicCast(); + if (full_sys->GetNumActive() > 0) { + return emp::CountDeleteriousSteps(emp::FindDominant(*full_sys)); + } + return 0; + }; + std::function dom_phen_vol = [&world](){ + emp::Ptr> sys = world.GetSystematics(0); + emp::Ptr full_sys = sys.DynamicCast(); + if (full_sys->GetNumActive() > 0) { + return emp::CountPhenotypeChanges(emp::FindDominant(*full_sys)); + } + return 0; + }; + std::function dom_unique_phen = [&world](){ + emp::Ptr> sys = world.GetSystematics(0); + emp::Ptr full_sys = sys.DynamicCast(); + if (full_sys->GetNumActive() > 0) { + return emp::CountUniquePhenotypes(emp::FindDominant(*full_sys)); + } + return 0; + }; + std::function lin_len = [&world](){ + emp::Ptr> sys = world.GetSystematics(0); + emp::Ptr full_sys = sys.DynamicCast(); + if (full_sys->GetNumActive() > 0) { + return emp::LineageLength(emp::FindDominant(*full_sys)); + } + return 0; + }; + + file.AddFun(get_update, "update", "Update"); + file.AddFun(dom_mut_count, "dominant_mutation_count", "sum of mutations along dominant organism's lineage"); + file.AddFun(dom_del_step, "dominant_deleterious_steps", "count of deleterious steps along dominant organism's lineage"); + file.AddFun(dom_phen_vol, "dominant_phenotypic_volatility", "count of changes in phenotype along dominant organism's lineage"); + file.AddFun(dom_unique_phen, "dominant_unique_phenotypes", "count of unique phenotypes along dominant organism's lineage"); + file.AddFun(lin_len, "lineage_length", "number of taxa dominant organism's lineage"); + file.PrintHeaderKeys(); + return file; } +// Integration test for using multiple systematics managers in a world and recording data TEST_CASE("Run world", "[evo]") { using mut_count_t = std::unordered_map; using data_t = emp::datastruct::mut_landscape_info>; @@ -696,6 +817,32 @@ TEST_CASE("Run world", "[evo]") { world.AddSystematics(gene_sys); world.AddSystematics(phen_sys); + std::function, emp::AvidaGP&)> check_update = [&gene_sys, &world](emp::Ptr tax, emp::AvidaGP & org){ + CHECK(tax->GetOriginationTime() == gene_sys->GetUpdate()); + CHECK(tax->GetOriginationTime() == world.GetUpdate()); + CHECK(tax->GetNumOff() == 0); + }; + + gene_sys->OnNew(check_update); + + std::function)> extinction_checks = [&gene_sys, &world](emp::Ptr tax){ + CHECK(tax->GetDestructionTime() == gene_sys->GetUpdate()); + CHECK(tax->GetDestructionTime() == world.GetUpdate()); + CHECK(tax->GetNumOrgs() == 0); + }; + + gene_sys->OnExtinct(extinction_checks); + + std::function)> prune_checks = [&world](emp::Ptr tax){ + CHECK(tax->GetNumOrgs() == 0); + CHECK(tax->GetNumOff() == 0); + CHECK(tax->GetOriginationTime() <= world.GetUpdate()); + CHECK(tax->GetDestructionTime() <= world.GetUpdate()); + }; + + gene_sys->OnPrune(prune_checks); + + emp::Signal on_mutate_sig; ///< Trigger signal before organism gives birth. emp::Signal record_fit_sig; ///< Trigger signal before organism gives birth. emp::Signal)> record_phen_sig; ///< Trigger signal before organism gives birth. @@ -712,9 +859,12 @@ TEST_CASE("Run world", "[evo]") { world.GetSystematics(1).Cast()->GetTaxonAt(pos)->GetData().RecordPhenotype(phen); }); - // world.OnOrgPlacement([&last_mutation, &world](size_t pos){ - // world.GetSystematics(0).Cast()->GetTaxonAt(pos)->GetData().RecordMutation(last_mutation); - // }); + emp::Ptr> sys0 = world.GetSystematics(0); + emp::Ptr sys0_cast = sys0.DynamicCast(); + std::function, emp::AvidaGP&)> capture_mut_fun = [&last_mutation](emp::Ptr tax, emp::AvidaGP & org){ + tax->GetData().RecordMutation(last_mutation); + }; + sys0_cast->OnNew(capture_mut_fun); world.SetupSystematicsFile().SetTimingRepeat(1); world.SetupFitnessFile().SetTimingRepeat(1); @@ -722,7 +872,7 @@ TEST_CASE("Run world", "[evo]") { emp::AddPhylodiversityFile(world, 0, "genotype_phylodiversity.csv").SetTimingRepeat(1); emp::AddPhylodiversityFile(world, 1, "phenotype_phylodiversity.csv").SetTimingRepeat(1); emp::AddLineageMutationFile(world).SetTimingRepeat(1); - // AddDominantFile(world).SetTimingRepeat(1); + AddDominantFile(world).SetTimingRepeat(1); // emp::AddMullerPlotFile(world).SetTimingOnce(1); @@ -761,15 +911,7 @@ TEST_CASE("Run world", "[evo]") { world.SetFitFun(fit_fun); - // emp::vector< std::function > fit_set(16); - // for (size_t out_id = 0; out_id < 16; out_id++) { - // // Setup the fitness function. - // fit_set[out_id] = [out_id](const emp::AvidaGP & org) { - // return (double) -std::abs(org.GetOutput((int)out_id) - (double) (out_id * out_id)); - // }; - // } - - // Build a random initial popoulation. + // Build a random initial population. for (size_t i = 0; i < 1; i++) { emp::AvidaGP cpu; cpu.PushRandom(random, 20); @@ -779,6 +921,12 @@ TEST_CASE("Run world", "[evo]") { for (size_t i = 0; i < 100; i++) { EliteSelect(world, 1, 1); } + + for (size_t i = 0; i < world.GetSize(); i++) { + record_fit_sig.Trigger(i, world.CalcFitnessID(i)); + record_phen_sig.Trigger(i, phen_fun(world.GetOrg(i))); + } + world.Update(); // Do the run... @@ -786,47 +934,34 @@ TEST_CASE("Run world", "[evo]") { // Update the status of all organisms. world.ResetHardware(); world.Process(200); - double fit0 = world.CalcFitnessID(0); - std::cout << (ud+1) << " : " << 0 << " : " << fit0 << std::endl; + TournamentSelect(world, 2, 100); - // Keep the best individual. - EliteSelect(world, 1, 1); - - // Run a tournament for the rest... - TournamentSelect(world, 2, 99); - // LexicaseSelect(world, fit_set, POP_SIZE-1); - // EcoSelect(world, fit_fun, fit_set, 100, 5, POP_SIZE-1); for (size_t i = 0; i < world.GetSize(); i++) { record_fit_sig.Trigger(i, world.CalcFitnessID(i)); record_phen_sig.Trigger(i, phen_fun(world.GetOrg(i))); } world.Update(); - + CHECK(world.GetUpdate() == gene_sys->GetUpdate()); + CHECK(world.GetUpdate() == phen_sys->GetUpdate()); + CHECK(gene_sys->GetTaxonAt(0)->GetOriginationTime() <= world.GetUpdate()); } - - // std::cout << std::endl; - // world[0].PrintGenome(); - // std::cout << std::endl; - // for (int i = 0; i < 16; i++) { - // std::cout << i << ":" << world[0].GetOutput(i) << " "; - // } - // std::cout << std::endl; } - - -TEST_CASE("Test GetCanopy", "[evo]") -{ +TEST_CASE("Test GetCanopy", "[evo]") { emp::Systematics sys([](const int & i){return i;}, true, true, true, false); - auto id1 = sys.AddOrg(1, nullptr, 0); - auto id2 = sys.AddOrg(2, id1, 2); - auto id3 = sys.AddOrg(3, id1, 3); - auto id4 = sys.AddOrg(4, id2, 3); + sys.SetUpdate(0); + auto id1 = sys.AddOrg(1, nullptr); + sys.SetUpdate(2); + auto id2 = sys.AddOrg(2, id1); + sys.SetUpdate(3); + auto id3 = sys.AddOrg(3, id1); + auto id4 = sys.AddOrg(4, id2); - sys.RemoveOrg(id1, 3); - sys.RemoveOrg(id2, 5); + sys.RemoveOrg(id1); + sys.SetUpdate(5); + sys.RemoveOrg(id2); auto can_set = sys.GetCanopyExtantRoots(4); @@ -843,7 +978,8 @@ TEST_CASE("Test GetCanopy", "[evo]") CHECK(Has(can_set, id1)); CHECK(Has(can_set, id2)); - sys.RemoveOrg(id3, 7); + sys.SetUpdate(7); + sys.RemoveOrg(id3); can_set = sys.GetCanopyExtantRoots(2); @@ -853,10 +989,14 @@ TEST_CASE("Test GetCanopy", "[evo]") CHECK(can_set.size() == 1); CHECK(Has(can_set, id2)); - auto id5 = sys.AddOrg(5, id4, 8); - sys.RemoveOrg(id4, 9); - auto id6 = sys.AddOrg(6, id5, 10); - sys.RemoveOrg(id5, 11); + sys.SetUpdate(8); + auto id5 = sys.AddOrg(5, id4); + sys.SetUpdate(9); + sys.RemoveOrg(id4); + sys.SetUpdate(10); + auto id6 = sys.AddOrg(6, id5); + sys.SetUpdate(11); + sys.RemoveOrg(id5); can_set = sys.GetCanopyExtantRoots(7); // Should only be 4 @@ -868,16 +1008,20 @@ TEST_CASE("Test GetCanopy", "[evo]") CHECK(can_set.size() == 1); CHECK(Has(can_set, id5)); - - auto id7 = sys.AddOrg(7, id6, 12); - auto id8 = sys.AddOrg(8, id7, 13); - auto id9 = sys.AddOrg(9, id8, 14); - auto id10 = sys.AddOrg(10, id9, 15); - - sys.RemoveOrg(id6, 20); - sys.RemoveOrg(id7, 20); - sys.RemoveOrg(id8, 20); - sys.RemoveOrg(id9, 20); + sys.SetUpdate(12); + auto id7 = sys.AddOrg(7, id6); + sys.SetUpdate(13); + auto id8 = sys.AddOrg(8, id7); + sys.SetUpdate(14); + auto id9 = sys.AddOrg(9, id8); + sys.SetUpdate(15); + auto id10 = sys.AddOrg(10, id9); + + sys.SetUpdate(20); + sys.RemoveOrg(id6); + sys.RemoveOrg(id7); + sys.RemoveOrg(id8); + sys.RemoveOrg(id9); can_set = sys.GetCanopyExtantRoots(22); // Should only be 10 @@ -906,13 +1050,6 @@ TEST_CASE("Test GetCanopy", "[evo]") CHECK(can_set.size() == 1); CHECK(Has(can_set, id5)); - - // auto id5 = sys.AddOrg(28, id2, 32); - // std::cout << "\nAddOrg 29 (id6; parent id5)\n"; - // auto id6 = sys.AddOrg(29, id5, 39); - // std::cout << "\nAddOrg 30 (id7; parent id1)\n"; - // auto id7 = sys.AddOrg(30, id1, 6); - } // Tests from Shao 1990 tree balance paper @@ -1082,3 +1219,462 @@ TEST_CASE("Tree balance", "[evo]") { CHECK(treecl.SackinIndex() == 18); CHECK(treecl.CollessLikeIndex() == Approx(1.746074)); } + +// Test that MRCA is properly updated when the MRCA is alive and then dies, +// causing a new taxon to be MRCA +TEST_CASE("Dieing MRCA", "[evo]") { + emp::Systematics tree([](const int & i){return i;}, true, true, false, false); + CHECK(!tree.GetTrackSynchronous()); + + // std::cout << "\nAddOrg 25 (id1, no parent)\n"; + tree.SetUpdate(0); + auto id1 = tree.AddOrg(25, nullptr); + // std::cout << "\nAddOrg -10 (id2; parent id1)\n"; + tree.SetUpdate(6); + auto id2 = tree.AddOrg(-10, id1); + // std::cout << "\nAddOrg 26 (id3; parent id1)\n"; + tree.SetUpdate(10); + auto id3 = tree.AddOrg(26, id1); + // std::cout << "\nAddOrg 27 (id4; parent id2)\n"; + tree.SetUpdate(25); + auto id4 = tree.AddOrg(27, id2); + // std::cout << "\nAddOrg 28 (id5; parent id2)\n"; + tree.SetUpdate(32); + auto id5 = tree.AddOrg(28, id2); + // std::cout << "\nAddOrg 29 (id6; parent id5)\n"; + tree.SetUpdate(39); + auto id6 = tree.AddOrg(29, id5); + // std::cout << "\nAddOrg 30 (id7; parent id1)\n"; + tree.SetUpdate(6); + auto id7 = tree.AddOrg(30, id1); + + CHECK(tree.GetMRCA() == id1); + tree.RemoveOrg(id7); + tree.RemoveOrg(id3); + tree.RemoveOrg(id2); + CHECK(tree.GetMRCA() == id1); + tree.RemoveOrg(id1); + CHECK(tree.GetMRCA() == id2); + tree.RemoveOrg(id4); + CHECK(tree.GetMRCA() == id5); + tree.RemoveOrg(id5); + CHECK(tree.GetMRCA() == id6); +} + +TEST_CASE("Test RemoveBefore", "[Evolve]") { + emp::Systematics sys([](const int & i){return i;}, true, true, false, false); + + // std::cout << "\nAddOrg 25 (id1, no parent)\n"; + sys.SetUpdate(0); + auto id1 = sys.AddOrg(25, nullptr); + // std::cout << "\nAddOrg -10 (id2; parent id1)\n"; + sys.SetUpdate(6); + auto id2 = sys.AddOrg(-10, id1); + // std::cout << "\nAddOrg 26 (id3; parent id1)\n"; + sys.SetUpdate(10); + auto id3 = sys.AddOrg(26, id1); + // std::cout << "\nAddOrg 27 (id4; parent id2)\n"; + sys.SetUpdate(25); + auto id4 = sys.AddOrg(27, id2); + // std::cout << "\nAddOrg 28 (id5; parent id2)\n"; + sys.SetUpdate(32); + auto id5 = sys.AddOrg(28, id2); + // std::cout << "\nAddOrg 29 (id6; parent id5)\n"; + sys.SetUpdate(39); + auto id6 = sys.AddOrg(29, id5); + // std::cout << "\nAddOrg 30 (id7; parent id1)\n"; + sys.SetUpdate(6); + auto id7 = sys.AddOrg(30, id1); + sys.SetUpdate(33); + auto id8 = sys.AddOrg(2, id3); + auto id9 = sys.AddOrg(4, id8); + sys.SetUpdate(34); + auto id10 = sys.AddOrg(5, id9); + + sys.SetUpdate(40); + sys.RemoveOrg(id1); + sys.SetUpdate(41); + sys.RemoveOrg(id2); + sys.SetUpdate(40); + sys.RemoveOrg(id9); + sys.SetUpdate(60); + sys.RemoveOrg(id8); + + CHECK(emp::Has(sys.GetAncestors(), id1)); + CHECK(emp::Has(sys.GetAncestors(), id2)); + + sys.RemoveBefore(50); + + CHECK(!emp::Has(sys.GetAncestors(), id1)); + CHECK(!emp::Has(sys.GetAncestors(), id2)); + CHECK(emp::Has(sys.GetAncestors(), id9)); + CHECK(emp::Has(sys.GetActive(), id3)); + CHECK(emp::Has(sys.GetActive(), id4)); + CHECK(emp::Has(sys.GetActive(), id5)); + CHECK(emp::Has(sys.GetActive(), id6)); + CHECK(emp::Has(sys.GetActive(), id7)); + CHECK(emp::Has(sys.GetAncestors(), id8)); + + sys.RemoveBefore(70); + CHECK(!emp::Has(sys.GetActive(), id8)); + CHECK(!emp::Has(sys.GetActive(), id9)); + +} + +TEST_CASE("Test Snapshot", "[Evolve]") { + emp::Systematics sys([](const int & i){return i;}, true, true, true, false); + + sys.SetUpdate(0); + auto id1 = sys.AddOrg(25, nullptr); + sys.SetUpdate(6); + auto id2 = sys.AddOrg(-10, id1); + sys.SetUpdate(10); + auto id3 = sys.AddOrg(26, id1); + sys.SetUpdate(25); + auto id4 = sys.AddOrg(27, id2); + sys.SetUpdate(32); + auto id5 = sys.AddOrg(28, id2); + sys.SetUpdate(39); + auto id6 = sys.AddOrg(29, id5); + sys.SetUpdate(6); + auto id7 = sys.AddOrg(30, id1); + sys.SetUpdate(33); + auto id8 = sys.AddOrg(2, id3); + auto id9 = sys.AddOrg(4, id8); + sys.SetUpdate(34); + auto id10 = sys.AddOrg(5, id9); + + sys.SetUpdate(40); + sys.RemoveOrg(id1); + sys.SetUpdate(41); + sys.RemoveOrg(id2); + sys.SetUpdate(40); + sys.RemoveOrg(id9); + sys.SetUpdate(60); + sys.RemoveOrg(id8); + sys.RemoveOrg(id10); + + sys.AddSnapshotFun([](const emp::Taxon & t){return std::to_string(t.GetInfo());}, "genome", "genome"); + sys.Snapshot("systematics_snapshot.csv"); + + // TODO: Would be nice to compare this to existing snapshot file, but lines could be in any order +} + +TEST_CASE("Test Prune", "[Evolve]") { + emp::Systematics sys([](const int & i){return i;}, true, true, false, false); + + int prunes = 0; + std::function >)> prune_fun = [&prunes](emp::Ptr> tax){prunes++;}; + sys.OnPrune(prune_fun); + + sys.SetUpdate(0); + auto id1 = sys.AddOrg(25, nullptr); + sys.SetUpdate(6); + auto id2 = sys.AddOrg(-10, id1); + sys.SetUpdate(10); + auto id3 = sys.AddOrg(26, id1); + sys.SetUpdate(25); + auto id4 = sys.AddOrg(27, id2); + sys.SetUpdate(32); + auto id5 = sys.AddOrg(28, id2); + sys.SetUpdate(39); + auto id6 = sys.AddOrg(29, id5); + sys.SetUpdate(6); + auto id7 = sys.AddOrg(30, id1); + sys.SetUpdate(33); + auto id8 = sys.AddOrg(2, id3); + auto id9 = sys.AddOrg(4, id8); + sys.SetUpdate(34); + auto id10 = sys.AddOrg(5, id9); + auto id11 = sys.AddOrg(5, id3); + + sys.SetUpdate(40); + sys.RemoveOrg(id1); + sys.RemoveOrg(id2); + sys.RemoveOrg(id3); + sys.RemoveOrg(id8); + sys.RemoveOrg(id9); + + CHECK(sys.GetMRCA() == id1); + + CHECK(prunes == 0); + CHECK(Has(sys.GetAncestors(), id9)); + sys.RemoveOrg(id10); + CHECK(prunes == 3); + CHECK(!Has(sys.GetAncestors(), id9)); + CHECK(Has(sys.GetAncestors(), id3)); + + sys.RemoveOrg(id11); + CHECK(prunes == 5); + CHECK(!Has(sys.GetAncestors(), id3)); + CHECK(sys.GetMRCA() == id1); + + sys.RemoveOrg(id7); + CHECK(prunes == 6); + CHECK(sys.GetMRCA() == id2); +} + +TEST_CASE("Test tracking position", "[Evolve]") { + emp::Systematics sys([](const int & i){return i;}, true, true, true, true); + + sys.SetUpdate(0); + auto id1 = sys.AddOrg(25, {0,0}, nullptr); + sys.SetUpdate(6); + auto id2 = sys.AddOrg(-10, {1,0}, id1); + CHECK(sys.Parent(id2) == id1); + sys.SetNextParent(id1); + sys.SetUpdate(10); + sys.AddOrg(26, {2,0}); + auto id3 = sys.GetMostRecent(); + CHECK(id3->GetParent() == id1); + CHECK(id3->GetInfo() == 26); + CHECK(id3->GetOriginationTime() == 10); + sys.SetNextParent({1,0}); + sys.SetUpdate(25); + sys.AddOrg(27, {3,0}); + auto id4 = sys.GetMostRecent(); + CHECK(id4->GetParent() == id2); + CHECK(id4->GetInfo() == 27); + CHECK(id4->GetOriginationTime() == 25); + + sys.SetUpdate(40); + sys.RemoveOrg({0,0}); + CHECK(id1->GetDestructionTime() == 40); + CHECK(id1->GetNumOrgs() == 0); + + sys.RemoveOrgAfterRepro(id4); + CHECK(!Has(sys.GetAncestors(), id4)); + sys.SetUpdate(34); + auto id5 = sys.AddOrg(88, {4,0}, id4); + CHECK(id4->GetNumOrgs() == 0); + CHECK(id4->GetNumOff() == 1); + CHECK(Has(sys.GetAncestors(), id4)); +} + +TEST_CASE("Test Total Offspring") { + emp::Systematics sys([](const int & i){return i;}, true, true, false, false); + + auto org1 = sys.AddOrg(1, nullptr); + auto org2 = sys.AddOrg(2, org1); + auto org3 = sys.AddOrg(3, org2); + auto org4 = sys.AddOrg(4, org3); + auto org5 = sys.AddOrg(5, org3); + auto org6 = sys.AddOrg(6, org2); + auto org7 = sys.AddOrg(7, org6); + auto org8 = sys.AddOrg(8, org6); + auto org9 = sys.AddOrg(9, org1); + auto org10 = sys.AddOrg(10, org9); + auto org11 = sys.AddOrg(11, org9); + + CHECK(org1->GetNumOff() == 2); + CHECK(org1->GetTotalOffspring() == 10); + + CHECK(org2->GetNumOff() == 2); + CHECK(org2->GetTotalOffspring() == 6); + + CHECK(org3->GetNumOff() == 2); + CHECK(org3->GetTotalOffspring() == 2); + + CHECK(org4->GetNumOff() == 0); + CHECK(org4->GetTotalOffspring() == 0); + + CHECK(org5->GetNumOff() == 0); + CHECK(org5->GetTotalOffspring() == 0); + + CHECK(org6->GetNumOff() == 2); + CHECK(org6->GetTotalOffspring() == 2); + + CHECK(org7->GetNumOff() == 0); + CHECK(org7->GetTotalOffspring() == 0); + + CHECK(org8->GetNumOff() == 0); + CHECK(org8->GetTotalOffspring() == 0); + + CHECK(org9->GetNumOff() == 2); + CHECK(org9->GetTotalOffspring() == 2); + + CHECK(org10->GetNumOff() == 0); + CHECK(org10->GetTotalOffspring() == 0); + + CHECK(org11->GetNumOff() == 0); + CHECK(org11->GetTotalOffspring() == 0); + + sys.RemoveOrg(org1); + + CHECK(org1->GetNumOff() == 2); + CHECK(org1->GetTotalOffspring() == 10); + + sys.RemoveOrg(org2); + + CHECK(org1->GetNumOff() == 2); + CHECK(org1->GetTotalOffspring() == 9); + + CHECK(org2->GetNumOff() == 2); + CHECK(org2->GetTotalOffspring() == 6); + + sys.RemoveOrg(org3); + + CHECK(org3->GetNumOff() == 2); + CHECK(org3->GetTotalOffspring() == 2); + CHECK(org2->GetNumOff() == 2); + CHECK(org2->GetTotalOffspring() == 5); + CHECK(org1->GetNumOff() == 2); + CHECK(org1->GetTotalOffspring() == 8); + + sys.RemoveOrg(org4); + + CHECK(org3->GetNumOff() == 1); + CHECK(org3->GetTotalOffspring() == 1); + CHECK(org2->GetNumOff() == 2); + CHECK(org2->GetTotalOffspring() == 4); + CHECK(org1->GetNumOff() == 2); + CHECK(org1->GetTotalOffspring() == 7); + + + sys.RemoveOrg(org9); + CHECK(org1->GetNumOff() == 2); + CHECK(org1->GetTotalOffspring() == 6); + +} + +TEST_CASE("Test Degree Distribution") { + emp::Systematics sys([](const int & i){return i;}, true, true, false, false); + + auto org1 = sys.AddOrg(1, nullptr); + auto org2 = sys.AddOrg(2, org1); + auto org3 = sys.AddOrg(3, org2); + auto org4 = sys.AddOrg(4, org3); + auto org5 = sys.AddOrg(5, org3); + auto org6 = sys.AddOrg(6, org2); + auto org7 = sys.AddOrg(7, org6); + auto org8 = sys.AddOrg(8, org6); + auto org9 = sys.AddOrg(9, org1); + auto org10 = sys.AddOrg(10, org9); + auto org11 = sys.AddOrg(11, org9); + auto org12 = sys.AddOrg(12, org1); + auto org13 = sys.AddOrg(13, org4); + auto org14 = sys.AddOrg(14, org13); + + std::unordered_map dist = sys.GetOutDegreeDistribution(); + CHECK(dist[0] == 7); + CHECK(dist[1] == 2); + CHECK(dist[2] == 4); + CHECK(dist[3] == 1); + +} + +TEST_CASE("Test Average Origin Time") { + emp::Systematics sys([](const int & i){return i;}, true, true, true, false); + + sys.SetUpdate(0); + auto id1 = sys.AddOrg(25, nullptr); + CHECK(sys.GetAverageOriginTime() == 0); + CHECK(sys.GetAverageOriginTime(true) == 0); + + sys.SetUpdate(6); + auto id2 = sys.AddOrg(-10, id1); + CHECK(sys.GetAverageOriginTime() == 3); + CHECK(sys.GetAverageOriginTime(true) == 0); + + sys.SetUpdate(10); + auto id3 = sys.AddOrg(26, id1); + CHECK(sys.GetAverageOriginTime() == Approx(5.333333)); + CHECK(sys.GetAverageOriginTime(true) == 0); + + sys.SetUpdate(25); + auto id4 = sys.AddOrg(27, id2); + CHECK(sys.GetAverageOriginTime() == Approx(10.25)); + CHECK(sys.GetAverageOriginTime(true) == Approx(0)); + + sys.SetUpdate(32); + auto id5 = sys.AddOrg(28, id2); + CHECK(sys.GetAverageOriginTime() == Approx(14.6)); + CHECK(sys.GetAverageOriginTime(true) == Approx(3)); + + sys.SetUpdate(39); + auto id6 = sys.AddOrg(29, id2); + CHECK(sys.GetAverageOriginTime() == Approx(18.6666667)); + CHECK(sys.GetAverageOriginTime(true) == Approx(4)); + + CHECK(sys.CalcDiversity() == Approx(2.58496)); + + sys.SetUpdate(39); + auto id7 = sys.AddOrg(30, id2); + CHECK(sys.GetAverageOriginTime() == Approx(21.571428571)); + CHECK(sys.GetAverageOriginTime(true) == Approx(4.5)); +} + +TEST_CASE("Test Loading Phylogeny From File") { + emp::Systematics sys([](const int & i){return i;}, true, true, true, true); + sys.LoadFromFile("systematics_snapshot.csv", "genome"); + CHECK(sys.GetNumRoots() == 1); + emp::Ptr> mrca = sys.GetMRCA(); + CHECK(mrca->GetID() == 1); + auto offspring = mrca->GetOffspring(); + for (auto off : offspring) { + CHECK(((off->GetID() == 7) || (off->GetID() == 2) || (off->GetID() == 3))); + } + CHECK(sys.GetNumActive() == 6); + CHECK(sys.GetNumAncestors() == 4); + CHECK(sys.GetNumOutside() == 0); + CHECK(sys.GetNumTaxa() == 10); + CHECK(sys.GetMaxDepth() == 4); + CHECK(mrca->GetTotalOffspring() == 6); + CHECK(mrca->GetNumOff() == 3); + CHECK(mrca->GetNumOrgs() == 0); + + for (auto tax : sys.GetActive()) { + CHECK(((tax->GetNumOrgs() == 1) || (tax->GetID() == 10 ))); + } + + sys.PrintStatus(); + + emp::Systematics sys2([](const int & i){return i;}, true, true, true, true); + sys2.LoadFromFile("systematics_snapshot.csv", "genome", false, false); + CHECK(sys2.GetNumRoots() == 1); + emp::Ptr> mrca2 = sys.GetMRCA(); + CHECK(mrca2->GetID() == 1); + auto offspring2 = mrca2->GetOffspring(); + for (auto off : offspring2) { + CHECK(((off->GetID() == 7) || (off->GetID() == 2) || (off->GetID() == 3))); + } + CHECK(sys2.GetNumActive() == 5); + CHECK(sys2.GetNumAncestors() == 2); + CHECK(sys2.GetNumOutside() == 3); + CHECK(sys2.GetNumTaxa() == 10); + CHECK(sys2.GetMaxDepth() == 3); + CHECK(mrca2->GetTotalOffspring() == 6); + CHECK(mrca2->GetNumOff() == 3); + CHECK(mrca2->GetNumOrgs() == 0); + + for (auto tax : sys2.GetActive()) { + CHECK(tax->GetNumOrgs() == 1); + } + + sys2.PrintStatus(); +} + +TEST_CASE("Test LoadFromFile and Snapshot behavior") { + for (const auto& file : std::filesystem::directory_iterator("assets/")) { + if (file.path().extension() == ".csv") { + // load systematics from original file + emp::Systematics sys([](const int & i){ return emp::to_string(i); }, true, true, true, true); + sys.LoadFromFile(file.path(), "phenotype"); + + sys.AddSnapshotFun([](const emp::Systematics::taxon_t& tax){ return emp::to_string(tax.GetInfo()); }, "phenotype"); + + // save systematics into temp file + const auto temp_path = std::filesystem::temp_directory_path() / file.path().filename(); + sys.Snapshot(temp_path); + + // load original systematics file + emp::File original{emp::String(file.path())}; + + // load saved file + emp::File saved{emp::String(temp_path)}; + + CHECK(saved.AsSet() == original.AsSet()); + } + } + +} diff --git a/tests/Evolve/assets/nk_ecoeaselection.csv b/tests/Evolve/assets/nk_ecoeaselection.csv new file mode 100644 index 0000000000..739ee48383 --- /dev/null +++ b/tests/Evolve/assets/nk_ecoeaselection.csv @@ -0,0 +1,493 @@ +id,ancestor_list,origin_time,destruction_time,num_orgs,tot_orgs,num_offspring,total_offspring,depth,phenotype +286082,[285064],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +286081,[285064],3000,inf,1,1,0,0,318,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.331944 ] +286080,[285064],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.764361 0.941376 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +286079,[285698],3000,inf,1,1,0,0,318,[ 0.655405 0.377253 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.230346 0.610081 ] +286078,[285663],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.371476 0.544384 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +286076,[285064],3000,inf,1,1,0,0,318,[ 0.966415 0.780388 0.339692 0.0417415 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +286075,[285370],3000,inf,1,1,0,0,317,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.0177735 0.996059 0.587459 0.113471 0.399652 0.499309 0.331944 ] +286074,[285440],3000,inf,1,1,0,0,317,[ 0.227434 0.107758 0.311373 0.442382 0.477147 0.659672 0.292154 0.981037 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +286073,[284762],3000,inf,1,1,0,0,317,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.593183 0.749237 0.182193 0.641282 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +286072,[284762],3000,inf,1,1,0,0,317,[ 0.227434 0.107758 0.311373 0.528752 0.151974 0.391884 0.753722 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +286071,[285698],3000,inf,1,1,0,0,318,[ 0.966415 0.780388 0.339692 0.0417415 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +286068,[285602],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +286067,[284971],3000,inf,1,1,0,0,317,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.121833 0.203214 0.420954 ] +286065,[285064],3000,inf,1,1,0,0,318,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.331944 ] +286060,[285064],3000,inf,1,1,0,0,318,[ 0.966415 0.780388 0.339692 0.0417415 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +286059,[285064],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.744291 0.634641 0.409571 0.919135 0.345937 0.113471 0.399652 0.499309 0.796683 ] +286058,[285064],3000,inf,1,1,0,0,318,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.331944 ] +286056,[285064],3000,inf,1,1,0,0,318,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.331944 ] +286054,[285663],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.900739 0.585985 0.316304 0.370609 0.499309 0.796683 ] +286053,[285064],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.264263 0.121833 0.203214 0.433524 ] +286052,[284971],3000,inf,1,1,0,0,317,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.0177735 0.996059 0.587459 0.264263 0.121833 0.203214 0.433524 ] +286051,[285064],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.0398419 0.608768 0.236846 0.370609 0.499309 0.796683 ] +286050,[284762],3000,inf,1,1,0,0,317,[ 0.227434 0.107758 0.311373 0.528752 0.151974 0.391884 0.753722 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +286049,[284762],3000,inf,1,1,0,0,317,[ 0.227434 0.107758 0.311373 0.528752 0.151974 0.391884 0.753722 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +286048,[285370],3000,inf,1,1,0,0,317,[ 0.129614 0.117406 0.617188 0.0417415 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +286047,[284762],3000,inf,1,1,0,0,317,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +286043,[284762],3000,inf,1,1,0,0,317,[ 0.920963 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +286077,[285064],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.0398419 0.608768 0.236846 0.370609 0.499309 0.796683 ] +286042,[285064],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.744291 0.634641 0.409571 0.919135 0.345937 0.113471 0.399652 0.499309 0.796683 ] +286041,[285908],3000,inf,1,1,0,0,318,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.121833 0.203214 0.420954 ] +286040,[285268],3000,inf,1,1,0,0,317,[ 0.227434 0.879461 0.731394 0.310202 0.310443 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +286039,[285064],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.264263 0.121833 0.203214 0.433524 ] +286038,[285064],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.248441 0.543834 0.455503 0.139399 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +286037,[285869],3000,inf,1,1,0,0,319,[ 0.227434 0.107758 0.311373 0.528752 0.759342 0.161715 0.827836 0.981037 0.425415 0.12958 0.882332 0.321388 0.188286 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +286036,[285064],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.659672 0.292154 0.981037 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +286034,[284762],3000,inf,1,1,0,0,317,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.191443 0.588336 0.455492 0.630574 0.41305 0.399652 0.499309 0.331944 ] +286033,[285736],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.915747 0.089723 0.338127 0.499493 0.0177735 0.996059 0.587459 0.113471 0.399652 0.499309 0.796683 ] +286032,[285064],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.592203 0.0610829 0.336801 0.805204 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +286031,[284762],3000,inf,1,1,0,0,317,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.882332 0.321388 0.188286 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +286030,[285064],3000,inf,1,1,0,0,318,[ 0.966415 0.780388 0.339692 0.0417415 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +286029,[285064],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.717128 0.132787 0.737262 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +286028,[284971],3000,inf,1,1,0,0,317,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.593183 0.749237 0.182193 0.641282 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.121833 0.203214 0.433524 ] +286027,[285064],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.33191 0.715529 0.719748 0.464015 0.796683 ] +286070,[285698],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.592203 0.0610829 0.336801 0.805204 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +286026,[285064],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.248441 0.543834 0.455503 0.139399 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +286045,[285064],3000,inf,1,1,0,0,318,[ 0.966415 0.780388 0.339692 0.0417415 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +286025,[285064],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.744291 0.634641 0.409571 0.919135 0.345937 0.113471 0.399652 0.499309 0.796683 ] +286024,[285064],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.528752 0.151974 0.391884 0.753722 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +286023,[284762],3000,inf,1,1,0,0,317,[ 0.227434 0.107758 0.311373 0.528752 0.151974 0.391884 0.753722 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +286022,[284971],3000,inf,1,1,0,0,317,[ 0.374623 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.144926 0.942778 0.334352 ] +286020,[285370],3000,inf,1,1,0,0,317,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +286019,[285698],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.965078 0.502272 0.808106 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +286018,[284762],3000,inf,1,1,0,0,317,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.371476 0.544384 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.331944 ] +286017,[285064],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.592203 0.0610829 0.336801 0.805204 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +286016,[285064],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.33191 0.715529 0.719748 0.464015 0.796683 ] +286015,[285888],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.592203 0.0610829 0.336801 0.805204 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +286014,[285680],3000,inf,1,1,0,0,317,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.593183 0.749237 0.182193 0.641282 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +286013,[284762],3000,inf,1,1,0,0,317,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.882332 0.321388 0.188286 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +286012,[285064],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.764361 0.941376 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +286010,[285064],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.12958 0.882332 0.549424 0.0890584 0.629737 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +286044,[285268],3000,inf,1,1,0,0,317,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.882332 0.321388 0.188286 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +286009,[285923],3000,inf,1,1,0,0,318,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.12958 0.882332 0.321388 0.188286 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +286008,[285696],3000,inf,1,1,0,0,319,[ 0.212209 0.40814 0.592203 0.0610829 0.336801 0.455281 0.00856907 0.39548 0.193967 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +286007,[284762],3000,inf,1,1,0,0,317,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.371476 0.544384 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.331944 ] +286005,[284762],3000,inf,1,1,0,0,317,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.965078 0.502272 0.808106 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +286003,[285064],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.0398419 0.608768 0.236846 0.370609 0.499309 0.796683 ] +286035,[285064],3000,inf,1,1,0,0,318,[ 0.212209 0.669305 0.898177 0.310202 0.310443 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +286002,[285064],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.12958 0.0293499 0.853584 0.254936 0.949996 0.0398419 0.608768 0.236846 0.370609 0.499309 0.796683 ] +286000,[285064],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.882332 0.549424 0.0890584 0.629737 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +285999,[285064],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.593183 0.749237 0.0452397 0.212129 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +285998,[285064],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.882332 0.549424 0.0890584 0.629737 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +285997,[285474],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.121833 0.203214 0.433524 ] +285996,[285064],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.764361 0.941376 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +285995,[285268],3000,inf,1,1,0,0,317,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +285994,[284762],3000,inf,1,1,0,0,317,[ 0.129614 0.117406 0.617188 0.0417415 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +285993,[285268],3000,inf,1,1,0,0,317,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.191443 0.588336 0.455492 0.630574 0.41305 0.399652 0.499309 0.331944 ] +285992,[285763],3000,inf,1,1,0,0,318,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +285991,[285064],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.592203 0.0610829 0.336801 0.805204 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +285990,[285064],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.423132 0.206902 0.630574 0.41305 0.399652 0.499309 0.796683 ] +286001,[285268],3000,inf,1,1,0,0,317,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.191443 0.588336 0.455492 0.630574 0.41305 0.399652 0.499309 0.331944 ] +285989,[285924],3000,inf,1,1,0,0,319,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.12958 0.0293499 0.853584 0.254936 0.423132 0.206902 0.630574 0.41305 0.399652 0.499309 0.796683 ] +285988,[284762],3000,inf,1,1,0,0,317,[ 0.227434 0.107758 0.379804 0.0610829 0.336801 0.805204 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +285987,[284971],3000,inf,1,1,0,0,317,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.121833 0.203214 0.420954 ] +286006,[285440],3000,inf,1,1,0,0,317,[ 0.227434 0.107758 0.379804 0.0610829 0.336801 0.805204 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +285986,[284762],3000,inf,1,1,0,0,317,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.121833 0.203214 0.420954 ] +285984,[285064],3000,inf,1,1,0,0,318,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.331944 ] +286066,[284353],3000,inf,1,1,0,0,316,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.965078 0.502272 0.808106 0.499493 0.408684 0.975653 0.439374 0.0267293 0.121833 0.203214 0.420954 ] +285983,[284762],3000,inf,1,1,0,0,317,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.900739 0.585985 0.316304 0.370609 0.499309 0.331944 ] +285982,[285064],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.264263 0.121833 0.203214 0.433524 ] +285981,[284762],3000,inf,1,1,0,0,317,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.965078 0.502272 0.808106 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +285980,[285064],2999,inf,2,3,0,0,318,[ 0.212209 0.669305 0.898177 0.310202 0.310443 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +285972,[285064],2999,inf,1,2,0,0,318,[ 0.212209 0.669305 0.898177 0.310202 0.310443 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +285968,[285370],2999,inf,3,4,0,0,317,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +285964,[284762],2999,inf,2,3,0,0,317,[ 0.129614 0.117406 0.617188 0.0417415 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +285963,[285370],2999,inf,1,2,0,0,317,[ 0.129614 0.117406 0.617188 0.0417415 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +285959,[284762],2999,inf,1,2,0,0,317,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.121833 0.203214 0.420954 ] +285950,[285846],2999,inf,2,3,0,0,319,[ 0.212209 0.40814 0.0984858 0.528752 0.151974 0.391884 0.753722 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.423132 0.206902 0.630574 0.41305 0.399652 0.499309 0.796683 ] +285946,[284762],2999,inf,2,3,0,0,317,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.882332 0.321388 0.188286 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +286083,[285268],3000,inf,1,1,0,0,317,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.191443 0.588336 0.455492 0.630574 0.41305 0.399652 0.499309 0.331944 ] +285936,[285064],2999,inf,1,2,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.0398419 0.608768 0.236846 0.370609 0.499309 0.796683 ] +285935,[284762],2999,inf,2,3,0,0,317,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +285925,[284762],2999,inf,2,3,0,0,317,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +286011,[284762],3000,inf,1,1,0,0,317,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.900739 0.585985 0.316304 0.370609 0.499309 0.331944 ] +285919,[285064],2999,inf,1,2,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.593183 0.749237 0.0452397 0.212129 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +285912,[284762],2999,inf,3,4,0,0,317,[ 0.129614 0.117406 0.617188 0.0417415 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +285909,[284762],2999,inf,1,2,0,0,317,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +285907,[285064],2999,inf,4,5,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.423132 0.206902 0.630574 0.41305 0.399652 0.499309 0.796683 ] +285899,[284971],2999,inf,1,2,0,0,317,[ 0.212209 0.40814 0.0984858 0.528752 0.151974 0.391884 0.753722 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.121833 0.203214 0.433524 ] +286069,[285440],3000,inf,1,1,0,0,317,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.593183 0.749237 0.182193 0.641282 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +285894,[284951],2999,inf,1,2,0,0,316,[ 0.212209 0.40814 0.0984858 0.528752 0.151974 0.391884 0.753722 0.100874 0.425415 0.915747 0.089723 0.338127 0.191443 0.181613 0.919135 0.345937 0.264263 0.121833 0.203214 0.433524 ] +285892,[284762],2999,inf,1,2,0,0,317,[ 0.920963 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.576072 0.0739211 0.123924 ] +285869,[285479],2998,inf,2,4,1,1,318,[ 0.227434 0.107758 0.311373 0.528752 0.151974 0.391884 0.753722 0.100874 0.425415 0.12958 0.882332 0.321388 0.188286 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +285860,[285440],2998,inf,6,9,0,0,317,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +286064,[285064],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.764361 0.941376 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +285970,[284762],2999,inf,3,4,0,0,317,[ 0.129614 0.117406 0.617188 0.0417415 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +285850,[285064],2998,inf,3,6,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.423132 0.206902 0.630574 0.41305 0.399652 0.499309 0.796683 ] +285879,[284762],2998,inf,1,3,0,0,317,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.882332 0.321388 0.188286 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +285985,[285064],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.717128 0.132787 0.737262 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +285874,[284762],2998,inf,1,3,0,0,317,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.882332 0.321388 0.188286 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +285815,[284971],2998,inf,8,13,0,0,317,[ 0.212209 0.669305 0.898177 0.310202 0.310443 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.121833 0.203214 0.433524 ] +285811,[284762],2998,inf,2,5,1,1,317,[ 0.129614 0.117406 0.617188 0.0417415 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +285804,[285064],2998,inf,1,3,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.423132 0.206902 0.630574 0.41305 0.399652 0.499309 0.796683 ] +285803,[285744],2998,inf,2,5,0,0,318,[ 0.212209 0.669305 0.898177 0.859626 0.742649 0.391884 0.753722 0.593183 0.749237 0.182193 0.641282 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.121833 0.203214 0.433524 ] +285796,[285064],2997,inf,4,10,1,1,318,[ 0.212209 0.40814 0.0984858 0.528752 0.151974 0.391884 0.753722 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +286062,[285796],3000,inf,1,1,0,0,319,[ 0.212209 0.40814 0.0984858 0.528752 0.151974 0.391884 0.753722 0.100874 0.425415 0.915747 0.717128 0.132787 0.737262 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +285763,[285440],2997,inf,2,5,1,1,317,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +285752,[284971],2997,inf,2,5,0,0,317,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +285736,[285643],2997,inf,3,7,1,1,317,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.915747 0.089723 0.338127 0.191443 0.181613 0.919135 0.345937 0.113471 0.399652 0.499309 0.796683 ] +286046,[285268],3000,inf,1,1,0,0,317,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.717128 0.940648 0.233914 0.295506 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +285888,[284762],2999,inf,1,2,1,1,317,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +285725,[284762],2997,inf,3,10,0,0,317,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +285722,[284762],2997,inf,12,25,0,0,317,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +285698,[284971],2996,inf,26,68,4,4,317,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +285696,[285064],2996,inf,3,14,1,1,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +285695,[284971],2996,inf,4,10,0,0,317,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +285680,[284036],2996,inf,4,16,1,1,316,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +286004,[285811],3000,inf,1,1,0,0,318,[ 0.129614 0.117406 0.617188 0.0417415 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.882332 0.321388 0.188286 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +285663,[284762],2996,inf,22,40,2,2,317,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +285634,[284762],2996,inf,1,15,0,0,317,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.371476 0.544384 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.331944 ] +285602,[284971],2995,inf,7,14,1,1,317,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +286057,[284762],3000,inf,1,1,0,0,317,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.191443 0.588336 0.455492 0.630574 0.41305 0.399652 0.499309 0.331944 ] +285553,[284353],2995,inf,8,47,0,0,316,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +286021,[285268],3000,inf,1,1,0,0,317,[ 0.227434 0.879461 0.731394 0.310202 0.310443 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +285479,[284762],2994,inf,1,35,1,2,317,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.882332 0.321388 0.188286 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +285474,[284971],2994,inf,15,38,1,1,317,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +285440,[284353],2994,inf,10,57,5,6,316,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +285643,[285373],2996,inf,23,49,1,2,316,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.191443 0.181613 0.919135 0.345937 0.113471 0.399652 0.499309 0.796683 ] +285370,[284036],2993,inf,15,71,5,5,316,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +285268,[284036],2992,inf,69,383,8,8,316,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +286055,[285064],3000,inf,1,1,0,0,318,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.331944 ] +285310,[284036],2992,inf,2,31,0,0,316,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.121833 0.203214 0.433524 ] +286063,[285064],3000,inf,1,1,0,0,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.744291 0.634641 0.409571 0.919135 0.345937 0.113471 0.399652 0.499309 0.796683 ] +284971,[284353],2989,inf,38,633,14,20,316,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.121833 0.203214 0.433524 ] +284762,[284036],2987,inf,186,1135,40,47,316,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +285923,[284762],2999,inf,2,3,1,1,317,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.882332 0.321388 0.188286 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +286061,[284971],3000,inf,1,1,0,0,317,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.0177735 0.996059 0.587459 0.264263 0.121833 0.203214 0.433524 ] +285937,[284971],2999,inf,2,3,0,0,317,[ 0.374623 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.144926 0.942778 0.334352 ] +284353,[283329],2982,inf,7,872,4,30,315,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.121833 0.203214 0.420954 ] +284036,[283329],2979,inf,3,857,6,67,315,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.121833 0.203214 0.420954 ] +285064,[284853],2990,inf,362,1011,54,56,317,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +285924,[285064],2999,3000,0,1,1,1,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.423132 0.206902 0.630574 0.41305 0.399652 0.499309 0.796683 ] +284951,[284233],2989,2999,0,110,1,1,315,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.191443 0.181613 0.919135 0.345937 0.264263 0.121833 0.203214 0.433524 ] +284233,[282774],2981,2999,0,1745,2,4,314,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.191443 0.181613 0.919135 0.345937 0.264263 0.121833 0.203214 0.420954 ] +285846,[285064],2998,2999,0,1,1,1,318,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.423132 0.206902 0.630574 0.41305 0.399652 0.499309 0.796683 ] +285744,[285697],2997,2998,0,1,1,1,317,[ 0.227434 0.879461 0.731394 0.859626 0.742649 0.391884 0.753722 0.593183 0.749237 0.182193 0.641282 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.121833 0.203214 0.420954 ] +285697,[284036],2996,2997,0,1,1,1,316,[ 0.227434 0.879461 0.731394 0.310202 0.310443 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.121833 0.203214 0.420954 ] +285373,[284233],2993,2997,0,7,1,3,315,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.191443 0.181613 0.919135 0.345937 0.113471 0.399652 0.499309 0.331944 ] +283782,[282992],2976,2995,0,2870,1,57,315,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.965078 0.46792 0.503959 0.737262 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +284853,[283782],2988,2992,0,4,1,57,316,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.764361 0.941376 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +283329,[281920],2971,2990,0,1541,2,99,314,[ 0.920963 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +282774,[281897],2966,2984,0,190,1,4,313,[ 0.920963 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.191443 0.181613 0.919135 0.345937 0.264263 0.144926 0.942778 0.36852 ] +282400,[282090],2962,2971,0,132,1,57,313,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.965078 0.46792 0.527655 0.338034 0.409571 0.919135 0.345937 0.264263 0.121833 0.203214 0.433524 ] +282090,[281315],2959,2964,0,31,1,57,312,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.965078 0.502272 0.808106 0.191443 0.181613 0.919135 0.345937 0.264263 0.121833 0.203214 0.433524 ] +280644,[280437],2943,2962,0,5297,3,160,310,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.915747 0.089723 0.338127 0.191443 0.181613 0.919135 0.345937 0.264263 0.121833 0.203214 0.433524 ] +279538,[279326],2932,2952,0,3985,1,160,307,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.848404 0.704538 0.325857 0.28986 0.921 0.089723 0.338127 0.191443 0.181613 0.919135 0.345937 0.113471 0.399652 0.499309 0.796683 ] +280215,[279538],2939,2946,0,13,1,160,308,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.848404 0.704538 0.325857 0.28986 0.921 0.089723 0.338127 0.191443 0.181613 0.919135 0.345937 0.264263 0.121833 0.203214 0.433524 ] +278123,[277717],2917,2934,0,1156,1,160,304,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.848404 0.704538 0.145159 0.467189 0.439379 0.269206 0.132787 0.737262 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +285908,[284762],2999,3000,0,1,1,1,317,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +277717,[277392],2913,2934,0,1088,1,160,303,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.848404 0.704538 0.145159 0.467189 0.192673 0.212129 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +275198,[275082],2887,2899,0,262,1,160,300,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.336601 0.00856907 0.955973 0.0798934 0.0452397 0.212129 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.331944 ] +72271,[71525],758,764,0,52,1,160,82,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.0304804 0.524015 0.188286 0.408684 0.975653 0.86332 0.895256 0.719748 0.464015 0.796683 ] +109625,[108222],1150,1188,0,1204,1,160,126,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.955973 0.0798934 0.182193 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +247456,[247087],2595,2614,0,715,1,160,265,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.882332 0.321388 0.188286 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +116558,[116358],1224,1234,0,131,1,160,132,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.593183 0.749237 0.182193 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.0267293 0.121833 0.203214 0.433524 ] +65177,[64674],683,685,0,2,1,160,70,[ 0.212209 0.40814 0.0984858 0.528752 0.151974 0.391884 0.753722 0.100874 0.936176 0.971422 0.764361 0.941376 0.0340696 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +86688,[84278],910,921,0,599,1,160,103,[ 0.920963 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.371476 0.544384 0.132798 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +3902,[3503],41,58,0,1055,1,160,8,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.955973 0.0798934 0.182193 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +145389,[145174],1526,1534,0,51,1,160,161,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.593183 0.749237 0.0452397 0.212129 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +111397,[109625],1168,1178,0,72,1,160,127,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.915747 0.717128 0.940648 0.233914 0.295506 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +67123,[66995],705,718,0,350,1,160,76,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.717128 0.132787 0.65396 0.926461 0.0012973 0.86332 0.895256 0.719748 0.464015 0.796683 ] +107600,[106009],1128,1144,0,1124,1,160,123,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.848404 0.305763 0.424829 0.0798934 0.0452397 0.212129 0.853584 0.0340696 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +108019,[107600],1133,1143,0,131,1,160,124,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.848404 0.305763 0.424829 0.0798934 0.0452397 0.212129 0.744291 0.121075 0.295506 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +105064,[104464],1102,1117,0,790,1,160,121,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.848404 0.305763 0.265378 0.193967 0.12958 0.0293499 0.853584 0.0340696 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +239306,[237766],2511,2532,0,4095,1,160,256,[ 0.374623 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.334352 ] +117133,[116858],1230,1245,0,965,1,160,134,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.848404 0.305763 0.424829 0.0798934 0.182193 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.0267293 0.121833 0.203214 0.433524 ] +104464,[104096],1095,1108,0,46,1,160,120,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.848404 0.305763 0.265378 0.193967 0.12958 0.0293499 0.853584 0.0340696 0.926461 0.0012973 0.439374 0.0267293 0.121833 0.203214 0.433524 ] +159750,[158623],1675,1695,0,258,1,160,183,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.248441 0.543834 0.376032 0.448576 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.86332 0.895256 0.719748 0.464015 0.796683 ] +96503,[96318],1011,1023,0,188,1,160,116,[ 0.374623 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.915747 0.717128 0.132787 0.65396 0.926461 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.334352 ] +247087,[246119],2591,2609,0,1318,1,160,264,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.744291 0.121075 0.295506 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +92348,[92206],968,981,0,268,1,160,111,[ 0.374623 0.40814 0.0984858 0.442382 0.477147 0.848404 0.305763 0.424829 0.0798934 0.182193 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.41305 0.576072 0.0739211 0.503752 ] +48790,[48566],514,518,0,11,1,160,52,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.965078 0.502272 0.808106 0.499493 0.408684 0.975653 0.439374 0.0267293 0.121833 0.203214 0.420954 ] +26138,[25953],276,286,0,40,1,160,25,[ 0.920963 0.107758 0.311373 0.442382 0.477147 0.848404 0.305763 0.424829 0.507176 0.300469 0.327029 0.213651 0.121075 0.295506 0.975653 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +139493,[138727],1466,1467,0,1,1,160,153,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.583253 0.153559 0.467189 0.439379 0.269206 0.940648 0.338034 0.409571 0.919135 0.345937 0.113471 0.399652 0.499309 0.796683 ] +87923,[87416],922,937,0,425,1,160,105,[ 0.920963 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.0340696 0.926461 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +95428,[93058],1000,1019,0,910,1,160,114,[ 0.374623 0.40814 0.0984858 0.442382 0.480717 0.336601 0.583253 0.153559 0.467189 0.439379 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.334352 ] +43751,[43222],461,478,0,586,1,160,45,[ 0.227434 0.107758 0.379804 0.0610829 0.316223 0.0151848 0.0106258 0.0819448 0.697365 0.439379 0.269206 0.940648 0.233914 0.295506 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +267357,[265916],2804,2807,0,3,1,160,290,[ 0.129614 0.117406 0.617188 0.0417415 0.480717 0.336601 0.00856907 0.39548 0.193967 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +78646,[78412],826,863,0,5124,1,160,95,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.955973 0.0798934 0.182193 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +83544,[83096],877,891,0,197,1,160,101,[ 0.374623 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.144926 0.942778 0.334352 ] +83096,[82533],873,881,0,31,1,160,100,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.121833 0.203214 0.433524 ] +28881,[26674],305,317,0,30,1,160,27,[ 0.227434 0.107758 0.311373 0.442382 0.477147 0.848404 0.704538 0.145159 0.325585 0.190495 0.327029 0.213651 0.121075 0.295506 0.975653 0.439374 0.0267293 0.121833 0.203214 0.420954 ] +78412,[77952],824,829,0,7,1,160,94,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.583253 0.153559 0.467189 0.439379 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +87416,[86688],917,925,0,67,1,160,104,[ 0.920963 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.717128 0.132787 0.65396 0.926461 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +77453,[76954],813,828,0,367,1,160,92,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.848404 0.704538 0.145159 0.467189 0.192673 0.212129 0.853584 0.0340696 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +30632,[29514],324,345,0,2406,1,160,30,[ 0.227434 0.107758 0.379804 0.0610829 0.316223 0.0151848 0.0106258 0.0819448 0.0798025 0.190495 0.327029 0.213651 0.121075 0.295506 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +76017,[75712],798,824,0,7095,1,160,89,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.848404 0.704538 0.325857 0.961823 0.448576 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +76721,[76017],805,812,0,17,1,160,90,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.848404 0.704538 0.145159 0.325585 0.190495 0.966465 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +235498,[234873],2471,2497,0,852,1,160,254,[ 0.374623 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.144926 0.942778 0.334352 ] +44815,[43942],472,501,0,1025,1,160,47,[ 0.227434 0.107758 0.379804 0.0610829 0.316223 0.0151848 0.0106258 0.936185 0.455503 0.921 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +73301,[72762],769,792,0,2819,1,160,84,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.15077 0.132798 0.707658 0.14092 0.459511 0.464056 0.464015 0.796683 ] +72762,[72271],763,774,0,307,1,160,83,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.86332 0.895256 0.719748 0.464015 0.796683 ] +71525,[71421],750,766,0,183,1,160,81,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.0304804 0.524015 0.188286 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +280437,[280215],2941,2947,0,27,1,160,309,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.583253 0.757819 0.28986 0.921 0.089723 0.338127 0.191443 0.181613 0.919135 0.345937 0.264263 0.121833 0.203214 0.433524 ] +90418,[90236],949,956,0,74,1,160,108,[ 0.374623 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.593183 0.749237 0.0452397 0.212129 0.853584 0.0340696 0.926461 0.0012973 0.439374 0.41305 0.576072 0.0739211 0.503752 ] +174683,[173921],1833,1847,0,667,1,160,204,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.583253 0.153559 0.467189 0.439379 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +271219,[270707],2845,2858,0,104,1,160,296,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.955973 0.0798934 0.182193 0.269206 0.132787 0.737262 0.423132 0.206902 0.619776 0.895256 0.719748 0.464015 0.796683 ] +68605,[67601],720,736,0,206,1,160,78,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.371476 0.544384 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +106009,[105064],1111,1139,0,2583,1,160,122,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.12958 0.0293499 0.853584 0.0340696 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +67601,[67123],710,730,0,2942,1,160,77,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.717128 0.132787 0.65396 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +75712,[75456],794,805,0,58,1,160,88,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.659672 0.0106258 0.936185 0.376032 0.448576 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +43942,[43751],463,501,0,1092,1,160,46,[ 0.227434 0.107758 0.379804 0.0610829 0.316223 0.0151848 0.0106258 0.0819448 0.697365 0.439379 0.641282 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +214665,[209529],2252,2254,0,2,1,160,239,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.0267293 0.121833 0.203214 0.420954 ] +23673,[23527],249,250,0,1,1,160,21,[ 0.920963 0.107758 0.311373 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.915747 0.717128 0.940648 0.233914 0.295506 0.975653 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +178063,[177433],1868,1880,0,481,1,160,210,[ 0.966415 0.882698 0.919753 0.466784 0.742649 0.157893 0.0406684 0.153559 0.467189 0.439379 0.269206 0.132787 0.737262 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +65713,[65658],689,695,0,20,1,160,73,[ 0.212209 0.40814 0.0984858 0.528752 0.151974 0.391884 0.753722 0.100874 0.425415 0.12958 0.0293499 0.853584 0.0340696 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +97552,[96503],1022,1033,0,144,1,160,117,[ 0.374623 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.12958 0.0293499 0.853584 0.0340696 0.926461 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.334352 ] +63239,[62800],662,694,0,3988,1,160,68,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +130421,[129311],1369,1390,0,4535,1,160,145,[ 0.374623 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.0340696 0.926461 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.334352 ] +32849,[32018],347,355,0,22,1,160,33,[ 0.920963 0.107758 0.379804 0.0610829 0.316223 0.0151848 0.0106258 0.0819448 0.0798025 0.190495 0.966465 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.576072 0.0739211 0.123924 ] +65658,[65369],688,694,0,36,1,160,72,[ 0.212209 0.40814 0.592203 0.509351 0.0688961 0.904719 0.753722 0.100874 0.425415 0.12958 0.0293499 0.853584 0.0340696 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +59549,[59146],625,644,0,2585,1,160,64,[ 0.374623 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.334352 ] +120791,[120060],1269,1280,0,50,1,160,138,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.717128 0.132787 0.65396 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +68836,[68605],722,792,0,8238,1,160,79,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +59146,[57555],621,629,0,49,1,160,63,[ 0.920963 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +32018,[31755],338,369,0,7789,1,160,32,[ 0.227434 0.107758 0.379804 0.0610829 0.316223 0.0151848 0.0106258 0.0819448 0.0798025 0.190495 0.966465 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.331944 ] +153404,[152908],1609,1611,0,4,1,160,174,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.86332 0.895256 0.719748 0.464015 0.796683 ] +53288,[51796],561,583,0,2022,1,160,59,[ 0.920963 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +28943,[28881],306,317,0,135,1,160,28,[ 0.227434 0.107758 0.379804 0.0610829 0.316223 0.762226 0.704538 0.145159 0.325585 0.190495 0.327029 0.213651 0.121075 0.295506 0.975653 0.439374 0.0267293 0.121833 0.203214 0.420954 ] +98091,[97552],1028,1108,0,12023,1,160,118,[ 0.374623 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.0340696 0.926461 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.334352 ] +22727,[21135],240,251,0,53,1,160,18,[ 0.920963 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.576072 0.0739211 0.123924 ] +117796,[117133],1237,1273,0,512,1,160,135,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.848404 0.305763 0.424829 0.0798934 0.182193 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +81382,[80488],855,864,0,154,1,160,97,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.915747 0.089723 0.371476 0.544384 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +41313,[40197],435,443,0,37,1,160,41,[ 0.920963 0.107758 0.379804 0.0610829 0.316223 0.0151848 0.0106258 0.0819448 0.0798025 0.00223658 0.464795 0.503959 0.65396 0.926461 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +7877,[7479],82,101,0,823,1,160,13,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +225180,[224794],2363,2396,0,9847,1,160,250,[ 0.374623 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.334352 ] +51796,[51597],545,565,0,4172,1,160,58,[ 0.920963 0.107758 0.379804 0.0610829 0.336801 0.805204 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +50642,[50383],533,559,0,2883,1,160,56,[ 0.227434 0.107758 0.379804 0.0610829 0.336801 0.805204 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.331944 ] +131347,[130421],1380,1405,0,4990,1,160,146,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.0340696 0.926461 0.0012973 0.439374 0.0267293 0.121833 0.203214 0.433524 ] +50383,[50221],530,548,0,3254,1,160,55,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.331944 ] +270707,[269461],2840,2850,0,73,1,160,295,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.955973 0.0798934 0.182193 0.269206 0.132787 0.65396 0.926461 0.0012973 0.86332 0.895256 0.719748 0.464015 0.796683 ] +92206,[90858],967,972,0,14,1,160,110,[ 0.374623 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.955973 0.0798934 0.182193 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.41305 0.576072 0.0739211 0.503752 ] +66995,[65977],703,717,0,259,1,160,75,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.0340696 0.926461 0.0012973 0.86332 0.895256 0.719748 0.464015 0.796683 ] +51597,[50642],543,548,0,24,1,160,57,[ 0.920963 0.107758 0.379804 0.0610829 0.336801 0.805204 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.576072 0.0739211 0.123924 ] +50221,[49147],529,531,0,2,1,160,54,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.965078 0.502272 0.947488 0.544384 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.331944 ] +47946,[47592],505,527,0,4089,1,160,50,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +145596,[145389],1529,1545,0,1334,1,160,162,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +147379,[146568],1547,1562,0,253,1,160,164,[ 0.227434 0.107758 0.379804 0.0610829 0.336801 0.805204 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.331944 ] +77952,[77453],819,854,0,7974,1,160,93,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.848404 0.704538 0.145159 0.467189 0.439379 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +92613,[92348],971,983,0,380,1,160,112,[ 0.374623 0.40814 0.0984858 0.442382 0.477147 0.848404 0.704538 0.145159 0.467189 0.439379 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.41305 0.576072 0.0739211 0.503752 ] +47592,[46541],501,509,0,33,1,160,49,[ 0.227434 0.107758 0.379804 0.0610829 0.336801 0.805204 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +189920,[189083],1992,2011,0,745,1,160,220,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.331944 ] +40197,[40143],424,449,0,6546,1,160,40,[ 0.920963 0.107758 0.379804 0.0610829 0.316223 0.0151848 0.0106258 0.0819448 0.0798025 0.190495 0.327029 0.213651 0.121075 0.295506 0.975653 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +197523,[197319],2071,2089,0,1203,1,160,226,[ 0.227434 0.107758 0.379804 0.0610829 0.336801 0.805204 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.0890584 0.629737 0.188853 0.345937 0.264263 0.121833 0.203214 0.420954 ] +38759,[38036],409,439,0,2860,1,160,38,[ 0.227434 0.107758 0.379804 0.0610829 0.316223 0.0151848 0.0106258 0.0819448 0.0798025 0.190495 0.327029 0.213651 0.121075 0.295506 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +43222,[42575],455,474,0,395,1,160,44,[ 0.227434 0.107758 0.379804 0.0610829 0.316223 0.0151848 0.0106258 0.0819448 0.697365 0.439379 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.331944 ] +41595,[41313],438,457,0,2398,1,160,42,[ 0.920963 0.107758 0.379804 0.0610829 0.316223 0.0151848 0.0106258 0.0819448 0.697365 0.439379 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +218636,[216546],2294,2300,0,11,1,160,242,[ 0.977711 0.565085 0.311373 0.442382 0.480717 0.146235 0.248441 0.543834 0.376032 0.448576 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.230346 0.232522 ] +38036,[37255],401,422,0,1820,1,160,37,[ 0.227434 0.107758 0.379804 0.0610829 0.316223 0.0151848 0.0106258 0.0819448 0.0798025 0.190495 0.327029 0.213651 0.121075 0.295506 0.975653 0.439374 0.0267293 0.121833 0.203214 0.420954 ] +121105,[120791],1272,1309,0,9512,1,160,139,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.0340696 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +223515,[220447],2345,2369,0,769,1,160,248,[ 0.920963 0.107758 0.379804 0.0610829 0.336801 0.805204 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +64674,[63239],678,687,0,94,1,160,69,[ 0.212209 0.40814 0.0984858 0.528752 0.151974 0.391884 0.753722 0.100874 0.936176 0.971422 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +155241,[154989],1628,1636,0,134,1,160,179,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.848404 0.704538 0.325857 0.961823 0.429443 0.502272 0.947488 0.544384 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +32940,[32849],348,404,0,26458,1,160,34,[ 0.920963 0.107758 0.379804 0.0610829 0.316223 0.0151848 0.0106258 0.0819448 0.0798025 0.190495 0.966465 0.408818 0.15077 0.132798 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +179488,[179046],1884,1891,0,40,1,160,213,[ 0.129614 0.117406 0.617188 0.79168 0.151974 0.157893 0.0406684 0.153559 0.467189 0.439379 0.269206 0.132787 0.737262 0.949996 0.188853 0.33191 0.715529 0.719748 0.464015 0.331944 ] +46541,[44815],490,508,0,362,1,160,48,[ 0.227434 0.107758 0.379804 0.0610829 0.316223 0.0151848 0.292154 0.981037 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +37130,[32940],392,393,0,1,1,160,35,[ 0.920963 0.107758 0.379804 0.0610829 0.316223 0.0151848 0.0106258 0.0819448 0.0798025 0.190495 0.966465 0.524015 0.188286 0.408684 0.975653 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +60892,[59549],638,651,0,33,1,160,65,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.0267293 0.121833 0.203214 0.433524 ] +29514,[28943],312,337,0,5920,1,160,29,[ 0.227434 0.107758 0.379804 0.0610829 0.316223 0.0151848 0.0106258 0.0819448 0.0798025 0.190495 0.327029 0.213651 0.121075 0.295506 0.975653 0.439374 0.0267293 0.121833 0.203214 0.420954 ] +179898,[179786],1888,1906,0,468,1,160,215,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.336601 0.583253 0.153559 0.467189 0.439379 0.269206 0.132787 0.737262 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.331944 ] +31755,[30632],335,340,0,22,1,160,31,[ 0.227434 0.107758 0.379804 0.0610829 0.316223 0.0151848 0.0106258 0.0819448 0.0798025 0.190495 0.966465 0.524015 0.188286 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +1,[NONE],0,8,0,3574,1,160,0,[ 0.129614 0.625293 0.313639 0.471491 0.310443 0.336601 0.583253 0.757819 0.28986 0.921 0.089723 0.371476 0.544384 0.132798 0.0012973 0.439374 0.0267293 0.121833 0.203214 0.420954 ] +65369,[65177],685,696,0,248,1,160,71,[ 0.212209 0.40814 0.0984858 0.528752 0.151974 0.391884 0.753722 0.100874 0.425415 0.12958 0.0293499 0.853584 0.0340696 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +12,[1],0,3,0,5,1,160,1,[ 0.129614 0.625293 0.313639 0.471491 0.310443 0.336601 0.583253 0.757819 0.28986 0.139399 0.882332 0.549424 0.15077 0.132798 0.0012973 0.439374 0.0267293 0.121833 0.203214 0.420954 ] +291,[12],2,12,0,35,1,160,2,[ 0.129614 0.117406 0.617188 0.0417415 0.480717 0.336601 0.00856907 0.39548 0.193967 0.12958 0.882332 0.549424 0.15077 0.132798 0.0012973 0.439374 0.0267293 0.121833 0.203214 0.420954 ] +275676,[275198],2892,2919,0,5585,1,160,301,[ 0.227434 0.107758 0.311373 0.442382 0.477147 0.848404 0.305763 0.424829 0.0798934 0.0452397 0.212129 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.331944 ] +116358,[115823],1221,1232,0,145,1,160,131,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.717128 0.132787 0.65396 0.926461 0.0012973 0.439374 0.0267293 0.121833 0.203214 0.433524 ] +108222,[108019],1135,1157,0,4163,1,160,125,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.848404 0.305763 0.424829 0.0798934 0.182193 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +170982,[169837],1793,1800,0,38,1,160,196,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.248441 0.543834 0.376032 0.448576 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.331944 ] +2006,[1184],20,40,0,1949,1,160,5,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.12958 0.0293499 0.853584 0.0340696 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.331944 ] +173735,[173506],1823,1843,0,559,1,160,202,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.583253 0.153559 0.325585 0.00223658 0.460918 0.947488 0.544384 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +2906,[2006],30,46,0,550,1,160,6,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.336601 0.00856907 0.955973 0.0798934 0.0452397 0.212129 0.853584 0.0340696 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.331944 ] +82533,[81962],867,882,0,916,1,160,99,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.121833 0.203214 0.433524 ] +10421,[8154],108,140,0,1150,1,160,15,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +147722,[147379],1550,1558,0,35,1,160,165,[ 0.227434 0.107758 0.379804 0.0610829 0.336801 0.805204 0.445303 0.100874 0.936176 0.971422 0.764361 0.941376 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.331944 ] +49147,[48790],517,529,0,105,1,160,53,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.965078 0.502272 0.947488 0.544384 0.132798 0.0012973 0.439374 0.0267293 0.121833 0.203214 0.420954 ] +8154,[7877],85,121,0,9034,1,160,14,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +277392,[275676],2910,2924,0,151,1,160,302,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.848404 0.305763 0.424829 0.0798934 0.0452397 0.212129 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +7479,[6113],78,87,0,113,1,160,12,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.955973 0.0798934 0.182193 0.641282 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +23053,[22727],243,257,0,1115,1,160,19,[ 0.920963 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +134675,[133907],1415,1428,0,519,1,160,150,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.583253 0.153559 0.467189 0.439379 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.0267293 0.121833 0.203214 0.433524 ] +37255,[37130],393,407,0,745,1,160,36,[ 0.920963 0.107758 0.379804 0.0610829 0.316223 0.0151848 0.0106258 0.0819448 0.0798025 0.190495 0.327029 0.213651 0.121075 0.295506 0.975653 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +81962,[81382],861,873,0,48,1,160,98,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +71421,[68836],749,750,0,1,1,160,80,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.882332 0.321388 0.188286 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +243115,[242561],2550,2565,0,691,1,160,260,[ 0.920963 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.576072 0.0739211 0.123924 ] +246119,[245606],2581,2602,0,2712,1,160,263,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.744291 0.121075 0.295506 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +80488,[78646],846,862,0,556,1,160,96,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.915747 0.717128 0.132787 0.65396 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +88598,[87923],930,958,0,1447,1,160,106,[ 0.374623 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.0340696 0.926461 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.334352 ] +4946,[3902],52,68,0,113,1,160,9,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.848404 0.305763 0.424829 0.0798934 0.182193 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +12589,[10421],131,232,0,30332,1,160,16,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +133907,[133590],1406,1422,0,1174,1,160,149,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.848404 0.704538 0.145159 0.467189 0.439379 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.0267293 0.121833 0.203214 0.433524 ] +165773,[165482],1738,1760,0,3779,1,160,190,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.331944 ] +5178,[4946],54,84,0,3159,1,160,10,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.848404 0.305763 0.424829 0.0798934 0.182193 0.269206 0.940648 0.233914 0.295506 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +188352,[186643],1976,1994,0,301,1,160,218,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.593183 0.749237 0.182193 0.269206 0.132787 0.737262 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.331944 ] +281897,[281428],2957,2975,0,424,1,4,312,[ 0.920963 0.107758 0.311373 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.915747 0.089723 0.338127 0.191443 0.181613 0.919135 0.345937 0.264263 0.144926 0.942778 0.36852 ] +93058,[92613],976,1012,0,15738,1,160,113,[ 0.374623 0.40814 0.0984858 0.442382 0.477147 0.848404 0.704538 0.145159 0.467189 0.439379 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.334352 ] +76954,[76721],808,830,0,3242,1,160,91,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.848404 0.704538 0.145159 0.325585 0.190495 0.327029 0.941376 0.0340696 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +199351,[198961],2091,2126,0,5962,1,160,229,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.0890584 0.629737 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +42575,[41595],448,464,0,540,1,160,43,[ 0.227434 0.107758 0.379804 0.0610829 0.316223 0.0151848 0.0106258 0.0819448 0.697365 0.439379 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.0267293 0.121833 0.203214 0.420954 ] +171381,[171182],1797,1823,0,4729,1,160,198,[ 0.227434 0.107758 0.311373 0.442382 0.477147 0.848404 0.704538 0.325857 0.961823 0.448576 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.331944 ] +62082,[60892],650,671,0,3484,1,160,66,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.248441 0.543834 0.376032 0.448576 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.0267293 0.121833 0.203214 0.433524 ] +264565,[264400],2775,2790,0,773,1,160,287,[ 0.374623 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.144926 0.942778 0.334352 ] +116858,[116558],1227,1233,0,42,1,160,133,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.955973 0.0798934 0.182193 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.0267293 0.121833 0.203214 0.433524 ] +84278,[83544],885,937,0,17414,1,160,102,[ 0.920963 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +26674,[26138],282,316,0,15303,1,160,26,[ 0.920963 0.107758 0.311373 0.442382 0.477147 0.848404 0.704538 0.145159 0.325585 0.190495 0.327029 0.213651 0.121075 0.295506 0.975653 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +96318,[95428],1009,1012,0,3,1,160,115,[ 0.374623 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.955973 0.0798934 0.182193 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.334352 ] +242354,[240081],2542,2546,0,13,1,160,258,[ 0.920963 0.107758 0.311373 0.442382 0.480717 0.146235 0.248441 0.543834 0.376032 0.448576 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +57555,[56841],605,632,0,813,1,160,62,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.0267293 0.121833 0.203214 0.420954 ] +3503,[2906],36,44,0,51,1,160,7,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.336601 0.00856907 0.955973 0.0798934 0.182193 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.331944 ] +75456,[74917],792,795,0,4,1,160,87,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.248441 0.543834 0.376032 0.448576 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +120060,[119531],1261,1281,0,2222,1,160,137,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.593183 0.749237 0.182193 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +104096,[98091],1092,1114,0,707,1,160,119,[ 0.374623 0.40814 0.0984858 0.442382 0.477147 0.848404 0.305763 0.265378 0.193967 0.12958 0.0293499 0.853584 0.0340696 0.926461 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.334352 ] +123105,[121105],1293,1310,0,2370,1,160,140,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.371476 0.544384 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +123602,[123105],1298,1318,0,3052,1,160,141,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +198961,[197935],2087,2102,0,86,1,160,228,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.0890584 0.629737 0.188853 0.345937 0.113471 0.399652 0.499309 0.331944 ] +124666,[123602],1310,1319,0,52,1,160,142,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.121833 0.203214 0.433524 ] +129311,[125170],1358,1374,0,566,1,160,144,[ 0.374623 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.371476 0.544384 0.132798 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.334352 ] +133590,[133204],1403,1413,0,76,1,160,148,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.848404 0.704538 0.145159 0.467189 0.192673 0.212129 0.853584 0.0340696 0.926461 0.0012973 0.439374 0.0267293 0.121833 0.203214 0.433524 ] +133204,[131347],1398,1414,0,563,1,160,147,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.848404 0.305763 0.265378 0.193967 0.12958 0.0293499 0.853584 0.0340696 0.926461 0.0012973 0.439374 0.0267293 0.121833 0.203214 0.433524 ] +281823,[281758],2956,2960,0,9,1,99,312,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.191443 0.181613 0.919135 0.345937 0.264263 0.121833 0.203214 0.420954 ] +135009,[134675],1419,1465,0,14875,1,160,151,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.583253 0.153559 0.467189 0.439379 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +194750,[194658],2042,2081,0,6266,1,160,223,[ 0.227434 0.107758 0.379804 0.0610829 0.336801 0.805204 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.331944 ] +224794,[223515],2360,2368,0,42,1,160,249,[ 0.374623 0.40814 0.592203 0.0610829 0.336801 0.805204 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.334352 ] +138727,[135009],1457,1471,0,571,1,160,152,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.583253 0.153559 0.467189 0.439379 0.269206 0.132787 0.737262 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +140302,[139612],1474,1489,0,398,1,160,155,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.583253 0.153559 0.467189 0.439379 0.269206 0.132787 0.737262 0.949996 0.188853 0.33191 0.715529 0.719748 0.464015 0.796683 ] +90236,[88598],947,961,0,167,1,160,107,[ 0.374623 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.0340696 0.926461 0.0012973 0.439374 0.41305 0.576072 0.0739211 0.503752 ] +141246,[140302],1483,1500,0,176,1,160,156,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.583253 0.153559 0.467189 0.439379 0.269206 0.132787 0.737262 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +119531,[117796],1256,1269,0,413,1,160,136,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.659672 0.292154 0.827349 0.749237 0.182193 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +142389,[141246],1496,1504,0,59,1,160,157,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.583253 0.153559 0.467189 0.439379 0.269206 0.132787 0.737262 0.949996 0.188853 0.33191 0.715529 0.719748 0.464015 0.796683 ] +144717,[143097],1520,1524,0,8,1,160,159,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.248441 0.744368 0.697365 0.439379 0.269206 0.132787 0.737262 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +143097,[142389],1503,1530,0,1990,1,160,158,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.583253 0.153559 0.467189 0.439379 0.269206 0.132787 0.737262 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +281315,[280644],2951,2962,0,205,1,57,311,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.191443 0.181613 0.919135 0.345937 0.264263 0.121833 0.203214 0.433524 ] +146568,[145596],1538,1560,0,2404,1,160,163,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.331944 ] +6113,[5178],64,85,0,583,1,160,11,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.848404 0.305763 0.424829 0.0798934 0.182193 0.641282 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +148509,[147963],1558,1564,0,20,1,160,167,[ 0.227434 0.107758 0.379804 0.0610829 0.336801 0.805204 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.0890584 0.809268 0.206902 0.630574 0.41305 0.399652 0.499309 0.331944 ] +56841,[55029],597,609,0,150,1,160,61,[ 0.920963 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +148923,[148509],1563,1578,0,128,1,160,168,[ 0.227434 0.107758 0.379804 0.0610829 0.336801 0.805204 0.445303 0.100874 0.936176 0.971422 0.0304804 0.524015 0.188286 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +201501,[199351],2113,2120,0,41,1,160,230,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.15077 0.0153166 0.763399 0.587459 0.113471 0.399652 0.499309 0.796683 ] +150061,[148923],1575,1590,0,1208,1,160,169,[ 0.227434 0.107758 0.379804 0.0610829 0.336801 0.455281 0.00856907 0.39548 0.707299 0.971422 0.0304804 0.524015 0.188286 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +23527,[23053],248,249,0,1,1,160,20,[ 0.920963 0.107758 0.311373 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +150791,[150061],1582,1603,0,3510,1,160,170,[ 0.227434 0.107758 0.379804 0.0610829 0.336801 0.455281 0.00856907 0.39548 0.193967 0.12958 0.882332 0.321388 0.188286 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +153531,[153404],1611,1612,0,1,1,160,175,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +153625,[153531],1612,1632,0,1086,1,160,176,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.915747 0.089723 0.371476 0.544384 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +265916,[265542],2790,2819,0,2521,1,160,289,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +158542,[155660],1662,1667,0,10,1,160,181,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.659672 0.0106258 0.936185 0.376032 0.448576 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +167490,[166893],1756,1776,0,1377,1,160,193,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.882332 0.321388 0.188286 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +25953,[25144],274,277,0,4,1,160,24,[ 0.920963 0.107758 0.311373 0.442382 0.480717 0.336601 0.00856907 0.955973 0.507176 0.300469 0.327029 0.213651 0.121075 0.295506 0.975653 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +155660,[155241],1632,1672,0,8861,1,160,180,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.848404 0.704538 0.325857 0.961823 0.448576 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +161168,[159750],1690,1708,0,352,1,160,184,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.583253 0.757819 0.961823 0.448576 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.86332 0.895256 0.719748 0.464015 0.796683 ] +201813,[201501],2117,2140,0,340,1,160,231,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +161825,[161168],1697,1711,0,1012,1,160,185,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.848404 0.704538 0.325857 0.961823 0.448576 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.86332 0.895256 0.719748 0.464015 0.796683 ] +164313,[162918],1723,1734,0,179,1,160,187,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.659672 0.0106258 0.936185 0.376032 0.448576 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +62800,[62082],658,676,0,546,1,160,67,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.248441 0.543834 0.376032 0.448576 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +151450,[150791],1589,1610,0,832,1,160,171,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.12958 0.882332 0.321388 0.188286 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +164733,[164313],1727,1749,0,612,1,160,188,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.248441 0.543834 0.376032 0.448576 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +65977,[65713],692,722,0,1165,1,160,74,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.0340696 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +165482,[164733],1735,1751,0,364,1,160,189,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +40143,[38759],423,424,0,1,1,160,39,[ 0.227434 0.107758 0.379804 0.0610829 0.316223 0.0151848 0.0106258 0.0819448 0.0798025 0.190495 0.327029 0.213651 0.121075 0.295506 0.975653 0.439374 0.0267293 0.121833 0.203214 0.420954 ] +166893,[166738],1750,1762,0,310,1,160,192,[ 0.227434 0.107758 0.379804 0.0610829 0.336801 0.805204 0.445303 0.100874 0.425415 0.12958 0.882332 0.321388 0.188286 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +168534,[167490],1767,1791,0,3473,1,160,194,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.882332 0.321388 0.188286 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +171182,[170982],1795,1799,0,9,1,160,197,[ 0.227434 0.107758 0.311373 0.442382 0.477147 0.659672 0.0106258 0.936185 0.376032 0.448576 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.331944 ] +158623,[158542],1663,1691,0,4822,1,160,182,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.248441 0.543834 0.376032 0.448576 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +169837,[168534],1781,1801,0,2360,1,160,195,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +172399,[171381],1808,1817,0,58,1,160,199,[ 0.227434 0.107758 0.311373 0.442382 0.477147 0.848404 0.704538 0.145159 0.325585 0.190495 0.966465 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.331944 ] +173506,[172658],1820,1823,0,3,1,160,201,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.583253 0.153559 0.325585 0.190495 0.966465 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +173921,[173735],1825,1843,0,1354,1,160,203,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.583253 0.153559 0.467189 0.439379 0.641282 0.371476 0.544384 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +175119,[174683],1837,1848,0,112,1,160,205,[ 0.212209 0.40814 0.0984858 0.528752 0.151974 0.157893 0.0406684 0.153559 0.467189 0.439379 0.269206 0.132787 0.737262 0.423132 0.206902 0.630574 0.41305 0.399652 0.499309 0.796683 ] +176313,[175674],1850,1859,0,151,1,160,207,[ 0.212209 0.669305 0.898177 0.859626 0.742649 0.157893 0.0406684 0.153559 0.467189 0.439379 0.269206 0.132787 0.737262 0.423132 0.206902 0.619776 0.895256 0.719748 0.464015 0.796683 ] +154699,[153625],1623,1628,0,11,1,160,177,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.583253 0.757819 0.28986 0.921 0.089723 0.371476 0.544384 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +250284,[250018],2625,2676,0,19499,1,160,269,[ 0.920963 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +74917,[74482],786,805,0,1838,1,160,86,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +175674,[175119],1843,1860,0,340,1,160,206,[ 0.212209 0.40814 0.0984858 0.528752 0.151974 0.157893 0.0406684 0.153559 0.467189 0.439379 0.269206 0.132787 0.737262 0.423132 0.206902 0.619776 0.895256 0.719748 0.464015 0.796683 ] +220232,[220140],2311,2320,0,123,1,160,246,[ 0.959351 0.565085 0.379804 0.0610829 0.336801 0.805204 0.248441 0.543834 0.376032 0.448576 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.0267293 0.144926 0.83101 0.208752 ] +48566,[47946],512,520,0,53,1,160,51,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.965078 0.502272 0.808106 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +256280,[256006],2688,2691,0,3,1,160,273,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.371476 0.544384 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +176795,[176313],1854,1866,0,382,1,160,208,[ 0.966415 0.882698 0.919753 0.466784 0.742649 0.157893 0.0406684 0.153559 0.467189 0.439379 0.269206 0.132787 0.737262 0.423132 0.206902 0.619776 0.895256 0.719748 0.464015 0.796683 ] +177433,[176795],1861,1876,0,1487,1,160,209,[ 0.966415 0.882698 0.919753 0.466784 0.742649 0.157893 0.0406684 0.153559 0.467189 0.439379 0.269206 0.132787 0.737262 0.949996 0.188853 0.33191 0.715529 0.719748 0.464015 0.796683 ] +74482,[73301],781,796,0,242,1,160,85,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.86332 0.895256 0.719748 0.464015 0.796683 ] +179786,[179488],1887,1889,0,4,1,160,214,[ 0.129614 0.117406 0.617188 0.0417415 0.480717 0.336601 0.583253 0.153559 0.467189 0.439379 0.269206 0.132787 0.737262 0.949996 0.188853 0.33191 0.715529 0.719748 0.464015 0.331944 ] +179046,[178470],1879,1889,0,199,1,160,212,[ 0.129614 0.117406 0.617188 0.79168 0.151974 0.157893 0.0406684 0.153559 0.467189 0.439379 0.269206 0.132787 0.737262 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.331944 ] +178470,[178063],1873,1899,0,884,1,160,211,[ 0.129614 0.625293 0.313639 0.466784 0.742649 0.157893 0.0406684 0.153559 0.467189 0.439379 0.269206 0.132787 0.737262 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.331944 ] +281758,[280644],2955,2960,0,23,1,99,311,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.191443 0.181613 0.919135 0.345937 0.264263 0.121833 0.203214 0.433524 ] +256545,[256280],2691,2706,0,134,1,160,274,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.717128 0.132787 0.65396 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +181246,[179898],1902,1971,0,16346,1,160,216,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.583253 0.153559 0.467189 0.439379 0.269206 0.132787 0.737262 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +186643,[181246],1958,1984,0,4287,1,160,217,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.593183 0.749237 0.182193 0.269206 0.132787 0.737262 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +194658,[190796],2041,2043,0,2,1,160,222,[ 0.212209 0.40814 0.592203 0.0610829 0.336801 0.805204 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +190796,[189920],2002,2067,0,23658,1,160,221,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +197204,[194750],2068,2069,0,1,1,160,224,[ 0.227434 0.107758 0.379804 0.0610829 0.336801 0.805204 0.445303 0.100874 0.936176 0.971422 0.764361 0.941376 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.331944 ] +197935,[197523],2076,2098,0,2977,1,160,227,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.0890584 0.629737 0.188853 0.345937 0.264263 0.121833 0.203214 0.420954 ] +90858,[90418],953,973,0,490,1,160,109,[ 0.374623 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.593183 0.749237 0.182193 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.41305 0.576072 0.0739211 0.503752 ] +264400,[263803],2774,2775,0,1,1,160,286,[ 0.374623 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.915747 0.089723 0.371476 0.544384 0.132798 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.334352 ] +202984,[202774],2129,2144,0,712,1,160,233,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.248441 0.543834 0.376032 0.448576 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.0267293 0.121833 0.203214 0.433524 ] +258629,[256987],2713,2722,0,13,1,160,276,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.717128 0.132787 0.65396 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +202774,[201813],2127,2158,0,10065,1,160,232,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.248441 0.543834 0.376032 0.448576 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +207036,[205045],2172,2187,0,388,1,160,236,[ 0.920963 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +205045,[203791],2152,2176,0,383,1,160,235,[ 0.920963 0.107758 0.311373 0.442382 0.480717 0.146235 0.248441 0.543834 0.376032 0.448576 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +154989,[154699],1626,1633,0,88,1,160,178,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.583253 0.757819 0.961823 0.429443 0.502272 0.947488 0.544384 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +208125,[207036],2184,2208,0,917,1,160,237,[ 0.920963 0.107758 0.311373 0.442382 0.480717 0.146235 0.248441 0.543834 0.376032 0.448576 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +209529,[208125],2198,2256,0,14917,1,160,238,[ 0.920963 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +216546,[214761],2272,2306,0,4072,1,160,241,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.248441 0.543834 0.376032 0.448576 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.331944 ] +220140,[219275],2310,2311,0,1,1,160,245,[ 0.977711 0.565085 0.379804 0.0610829 0.336801 0.805204 0.248441 0.543834 0.376032 0.448576 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.230346 0.232522 ] +219275,[219030],2301,2316,0,556,1,160,244,[ 0.977711 0.3053 0.538128 0.180493 0.726948 0.805204 0.248441 0.543834 0.376032 0.448576 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.230346 0.232522 ] +220447,[220232],2313,2350,0,4806,1,160,247,[ 0.920963 0.107758 0.379804 0.0610829 0.336801 0.805204 0.248441 0.543834 0.376032 0.448576 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +227102,[225180],2384,2402,0,1050,1,160,251,[ 0.374623 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.882332 0.321388 0.188286 0.408684 0.975653 0.439374 0.0267293 0.144926 0.942778 0.334352 ] +279150,[278123],2928,2940,0,52,1,160,305,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.848404 0.704538 0.145159 0.467189 0.439379 0.269206 0.940648 0.338034 0.409571 0.919135 0.345937 0.113471 0.399652 0.499309 0.796683 ] +234873,[228249],2464,2480,0,148,1,160,253,[ 0.920963 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +237766,[235498],2495,2516,0,2100,1,160,255,[ 0.374623 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.882332 0.321388 0.188286 0.408684 0.975653 0.439374 0.0267293 0.144926 0.942778 0.334352 ] +242561,[242354],2544,2565,0,1183,1,160,259,[ 0.920963 0.107758 0.311373 0.442382 0.480717 0.146235 0.248441 0.543834 0.376032 0.448576 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.576072 0.0739211 0.123924 ] +240081,[239306],2519,2547,0,7189,1,160,257,[ 0.374623 0.40814 0.0984858 0.442382 0.480717 0.146235 0.248441 0.543834 0.376032 0.448576 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.334352 ] +244088,[243115],2560,2580,0,146,1,160,261,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.331944 ] +281428,[280644],2952,2969,0,860,1,4,311,[ 0.374623 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.915747 0.089723 0.338127 0.191443 0.181613 0.919135 0.345937 0.264263 0.144926 0.942778 0.334352 ] +245606,[244088],2576,2603,0,1240,1,160,262,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.0340696 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.331944 ] +250018,[249706],2623,2638,0,928,1,160,268,[ 0.374623 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.144926 0.942778 0.334352 ] +189083,[188352],1983,1998,0,353,1,160,219,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.717128 0.132787 0.737262 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.331944 ] +248426,[247456],2606,2651,0,3830,1,160,266,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +23690,[23673],250,273,0,292,1,160,22,[ 0.920963 0.107758 0.311373 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.12958 0.0293499 0.744291 0.121075 0.295506 0.975653 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +253844,[250284],2663,2685,0,1812,1,160,270,[ 0.374623 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.144926 0.942778 0.334352 ] +282992,[282400],2968,2988,0,360,1,57,314,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.965078 0.46792 0.503959 0.737262 0.949996 0.188853 0.345937 0.264263 0.121833 0.203214 0.433524 ] +125170,[124666],1315,1370,0,5015,1,160,143,[ 0.374623 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.144926 0.942778 0.334352 ] +255678,[253844],2681,2690,0,132,1,160,271,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.121833 0.203214 0.433524 ] +267654,[267357],2807,2814,0,73,1,160,291,[ 0.129614 0.117406 0.617188 0.0417415 0.480717 0.336601 0.00856907 0.39548 0.193967 0.915747 0.717128 0.132787 0.65396 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.331944 ] +55029,[53288],579,607,0,1208,1,160,60,[ 0.920963 0.107758 0.311373 0.442382 0.480717 0.146235 0.248441 0.543834 0.376032 0.448576 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +256006,[255678],2685,2693,0,99,1,160,272,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.371476 0.544384 0.132798 0.0012973 0.439374 0.0267293 0.121833 0.203214 0.433524 ] +658,[291],6,21,0,338,1,160,3,[ 0.129614 0.117406 0.617188 0.0417415 0.480717 0.336601 0.00856907 0.39548 0.193967 0.12958 0.0293499 0.853584 0.0340696 0.926461 0.0012973 0.439374 0.0267293 0.121833 0.203214 0.420954 ] +259576,[259124],2723,2731,0,21,1,160,278,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.593183 0.749237 0.182193 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.0267293 0.121833 0.203214 0.433524 ] +115823,[113902],1215,1225,0,145,1,160,130,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.717128 0.132787 0.65396 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +214761,[214665],2253,2286,0,5859,1,160,240,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.331944 ] +256987,[256545],2696,2738,0,7062,1,160,275,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.12958 0.0293499 0.853584 0.0340696 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +259959,[259576],2727,2739,0,205,1,160,279,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.955973 0.0798934 0.182193 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.0267293 0.121833 0.203214 0.433524 ] +281920,[281823],2957,2989,0,4735,1,99,313,[ 0.920963 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.191443 0.181613 0.919135 0.345937 0.264263 0.144926 0.942778 0.36852 ] +172658,[172399],1811,1823,0,188,1,160,200,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.848404 0.704538 0.145159 0.325585 0.190495 0.966465 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +260540,[259959],2733,2746,0,752,1,160,280,[ 0.374623 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.955973 0.0798934 0.182193 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.334352 ] +262335,[260841],2752,2757,0,10,1,160,282,[ 0.920963 0.107758 0.311373 0.442382 0.480717 0.336601 0.583253 0.153559 0.467189 0.439379 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +259124,[258629],2718,2734,0,565,1,160,277,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.593183 0.749237 0.182193 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +262557,[262335],2754,2761,0,32,1,160,283,[ 0.920963 0.107758 0.311373 0.442382 0.480717 0.336601 0.00856907 0.955973 0.0798934 0.182193 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +268599,[268063],2817,2833,0,551,1,160,293,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.336601 0.00856907 0.955973 0.0798934 0.182193 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.331944 ] +260841,[260540],2736,2762,0,2904,1,160,281,[ 0.374623 0.40814 0.0984858 0.442382 0.480717 0.336601 0.583253 0.153559 0.467189 0.439379 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.334352 ] +21135,[12589],222,254,0,4702,1,160,17,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +147963,[147722],1553,1579,0,5009,1,160,166,[ 0.227434 0.107758 0.379804 0.0610829 0.336801 0.805204 0.445303 0.100874 0.936176 0.971422 0.0304804 0.408818 0.0890584 0.629737 0.188853 0.345937 0.113471 0.399652 0.499309 0.331944 ] +263803,[262959],2767,2778,0,350,1,160,285,[ 0.374623 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.915747 0.717128 0.132787 0.65396 0.926461 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.334352 ] +25144,[23690],265,277,0,305,1,160,23,[ 0.920963 0.107758 0.311373 0.442382 0.480717 0.336601 0.00856907 0.39548 0.707299 0.971422 0.764361 0.213651 0.121075 0.295506 0.975653 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +262959,[262557],2758,2770,0,150,1,160,284,[ 0.920963 0.107758 0.311373 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.915747 0.717128 0.132787 0.65396 0.926461 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.36852 ] +152336,[151450],1598,1615,0,1738,1,160,172,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.12958 0.882332 0.321388 0.188286 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +265542,[264565],2786,2794,0,17,1,160,288,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.121833 0.203214 0.433524 ] +113902,[112292],1195,1222,0,1493,1,160,129,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +268063,[267654],2811,2822,0,195,1,160,292,[ 0.129614 0.117406 0.617188 0.0417415 0.480717 0.336601 0.00856907 0.955973 0.0798934 0.182193 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.331944 ] +279326,[279150],2930,2939,0,58,1,160,306,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.848404 0.704538 0.145159 0.467189 0.439379 0.641282 0.338127 0.191443 0.181613 0.919135 0.345937 0.113471 0.399652 0.499309 0.796683 ] +112292,[111397],1178,1207,0,4218,1,160,128,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +269461,[268599],2826,2856,0,1694,1,160,294,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.955973 0.0798934 0.182193 0.269206 0.132787 0.65396 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +219030,[218636],2298,2314,0,1014,1,160,243,[ 0.977711 0.3053 0.731394 0.310202 0.310443 0.146235 0.248441 0.543834 0.376032 0.448576 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.230346 0.232522 ] +271460,[271219],2847,2860,0,951,1,160,297,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.955973 0.0798934 0.182193 0.269206 0.132787 0.737262 0.949996 0.188853 0.33191 0.715529 0.719748 0.464015 0.796683 ] +228249,[227102],2395,2470,0,7410,1,160,252,[ 0.374623 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.144926 0.942778 0.334352 ] +145174,[144717],1524,1534,0,53,1,160,160,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.248441 0.744368 0.697365 0.192673 0.212129 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +249706,[248426],2620,2626,0,16,1,160,267,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.146235 0.445303 0.100874 0.425415 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.0267293 0.121833 0.203214 0.433524 ] +162918,[161825],1708,1737,0,813,1,160,186,[ 0.212209 0.40814 0.0984858 0.442382 0.477147 0.848404 0.704538 0.325857 0.961823 0.448576 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.41305 0.399652 0.499309 0.796683 ] +275082,[272001],2886,2889,0,4,1,160,299,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.955973 0.0798934 0.0452397 0.212129 0.853584 0.254936 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +197319,[197204],2069,2074,0,20,1,160,225,[ 0.227434 0.107758 0.379804 0.0610829 0.336801 0.805204 0.445303 0.100874 0.936176 0.971422 0.764361 0.941376 0.254936 0.949996 0.188853 0.345937 0.264263 0.121833 0.203214 0.420954 ] +152908,[152336],1604,1615,0,82,1,160,173,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.39548 0.193967 0.915747 0.089723 0.338127 0.499493 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.796683 ] +139612,[139493],1467,1488,0,1373,1,160,154,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.583253 0.153559 0.467189 0.439379 0.269206 0.940648 0.338034 0.409571 0.919135 0.33191 0.715529 0.719748 0.464015 0.796683 ] +1184,[658],12,26,0,89,1,160,4,[ 0.129614 0.117406 0.617188 0.0417415 0.480717 0.336601 0.00856907 0.39548 0.193967 0.12958 0.0293499 0.853584 0.0340696 0.926461 0.0012973 0.439374 0.41305 0.399652 0.499309 0.331944 ] +166738,[165773],1748,1753,0,17,1,160,191,[ 0.227434 0.107758 0.311373 0.442382 0.480717 0.146235 0.445303 0.100874 0.936176 0.971422 0.0304804 0.524015 0.188286 0.408684 0.975653 0.439374 0.41305 0.399652 0.499309 0.331944 ] +272001,[271460],2853,2891,0,897,1,160,298,[ 0.212209 0.40814 0.0984858 0.442382 0.480717 0.336601 0.00856907 0.955973 0.0798934 0.182193 0.269206 0.132787 0.737262 0.949996 0.188853 0.345937 0.113471 0.399652 0.499309 0.796683 ] +203791,[202984],2138,2158,0,603,1,160,234,[ 0.374623 0.40814 0.0984858 0.442382 0.480717 0.146235 0.248441 0.543834 0.376032 0.448576 0.0304804 0.408818 0.15077 0.132798 0.0012973 0.439374 0.0267293 0.144926 0.942778 0.334352 ] diff --git a/tests/Evolve/assets/nk_lexicaseselection.csv b/tests/Evolve/assets/nk_lexicaseselection.csv new file mode 100644 index 0000000000..aa047cda61 --- /dev/null +++ b/tests/Evolve/assets/nk_lexicaseselection.csv @@ -0,0 +1,234 @@ +id,ancestor_list,origin_time,destruction_time,num_orgs,tot_orgs,num_offspring,total_offspring,depth,phenotype +4737,[4727],500,inf,1,1,0,0,37,[ 0.78551 0.507546 0.298434 0.703895 0.70148 0.897296 0.852754 0.533489 0.975623 0.814646 0.0274892 0.45607 0.221636 0.767401 0.74891 0.860365 0.319087 0.293359 0.997853 0.770533 ] +4735,[4682],500,inf,1,1,0,0,40,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.973499 0.475437 0.135632 0.369805 0.927945 0.842535 0.639207 0.668826 0.742642 0.581241 0.448677 0.905925 0.313045 0.997853 0.770533 ] +4734,[4568],500,inf,1,1,0,0,51,[ 0.995809 0.187121 0.941875 0.229312 0.955627 0.973499 0.242718 0.876586 0.423019 0.859268 0.842535 0.639207 0.324924 0.896412 0.104071 0.896322 0.312038 0.661591 0.55268 0.953309 ] +4730,[4726],500,inf,1,1,0,0,58,[ 0.853625 0.905349 0.830128 0.72392 0.399304 0.973499 0.242718 0.962165 0.733312 0.00958576 0.0605428 0.357139 0.856259 0.767401 0.74891 0.860365 0.896396 0.495374 0.682412 0.0371882 ] +4729,[4719],500,inf,1,1,0,0,55,[ 0.995809 0.562972 0.284687 0.830449 0.269955 0.403992 0.365416 0.533489 0.975623 0.00958576 0.0605428 0.363967 0.838768 0.896412 0.0801959 0.860365 0.896396 0.495374 0.40972 0.953309 ] +4728,[4703],499,inf,1,2,0,0,39,[ 0.297263 0.477589 0.946456 0.820802 0.70148 0.897296 0.852754 0.533489 0.920642 0.25833 0.0922876 0.858428 0.838768 0.468659 0.793625 0.742182 0.985764 0.293359 0.102403 0.173893 ] +4727,[4521],499,inf,3,4,1,1,36,[ 0.00782676 0.966937 0.946456 0.820802 0.70148 0.897296 0.852754 0.533489 0.975623 0.814646 0.0274892 0.45607 0.221636 0.767401 0.74891 0.860365 0.319087 0.293359 0.997853 0.770533 ] +4720,[4615],498,inf,2,6,0,0,35,[ 0.763682 0.477589 0.946456 0.245193 0.955627 0.548185 0.365416 0.533489 0.920642 0.25833 0.0922876 0.858428 0.838768 0.468659 0.793625 0.742182 0.985764 0.706301 0.743279 0.0810917 ] +4717,[4688],498,inf,4,9,1,1,56,[ 0.853625 0.905349 0.830128 0.72392 0.399304 0.973499 0.242718 0.962165 0.473005 0.25833 0.0922876 0.648338 0.856259 0.767401 0.440932 0.697277 0.888705 0.989524 0.682412 0.0371882 ] +4731,[4568],500,inf,1,1,0,0,51,[ 0.995809 0.187121 0.941875 0.229312 0.955627 0.973499 0.242718 0.876586 0.423019 0.587516 0.982733 0.858428 0.838768 0.896412 0.104071 0.896322 0.775705 0.824472 0.415025 0.333746 ] +4721,[4645],498,inf,1,5,0,0,54,[ 0.995809 0.562972 0.284687 0.830449 0.269955 0.0949958 0.242718 0.962165 0.473005 0.25833 0.579728 0.931965 0.363537 0.374737 0.579269 0.629753 0.312038 0.661591 0.55268 0.953309 ] +4714,[4703],498,inf,2,5,0,0,39,[ 0.297263 0.477589 0.946456 0.820802 0.70148 0.897296 0.852754 0.540698 0.799621 0.587516 0.982733 0.648338 0.856259 0.102744 0.315735 0.742182 0.985764 0.293359 0.102403 0.173893 ] +4701,[4645],497,inf,1,4,0,0,54,[ 0.995809 0.562972 0.284687 0.830449 0.269955 0.0949958 0.242718 0.962165 0.733312 0.00958576 0.0662877 0.831627 0.295311 0.344145 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +4694,[4555],496,inf,1,10,0,0,55,[ 0.78551 0.867437 0.205732 0.830449 0.269955 0.0949958 0.475437 0.411102 0.473947 0.889831 0.579728 0.931965 0.295311 0.344145 0.74891 0.0134918 0.564761 0.270898 0.691646 0.257073 ] +4690,[4676],496,inf,3,10,0,0,53,[ 0.995809 0.187121 0.978541 0.0546537 0.883412 0.0949958 0.242718 0.876586 0.423019 0.587516 0.982733 0.648338 0.856259 0.767401 0.74891 0.0134918 0.564761 0.17016 0.55268 0.953309 ] +4719,[4712],498,inf,2,4,1,1,54,[ 0.995809 0.562972 0.284687 0.830449 0.269955 0.403992 0.365416 0.533489 0.975623 0.00958576 0.0605428 0.363967 0.838768 0.896412 0.104071 0.697277 0.888705 0.989524 0.40972 0.953309 ] +4738,[4672],500,inf,1,1,0,0,45,[ 0.995809 0.187121 0.978541 0.174138 0.779632 0.578599 0.852754 0.540698 0.799621 0.587516 0.982733 0.858428 0.838768 0.896412 0.104071 0.697277 0.888705 0.989524 0.40972 0.953309 ] +4682,[4516],494,inf,4,21,1,1,39,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.973499 0.475437 0.135632 0.369805 0.927945 0.842535 0.639207 0.668826 0.742642 0.436846 0.281887 0.319087 0.293359 0.997853 0.770533 ] +4672,[4551],493,inf,3,15,1,1,44,[ 0.995809 0.562972 0.284687 0.0702805 0.575156 0.578599 0.852754 0.540698 0.799621 0.587516 0.982733 0.858428 0.838768 0.896412 0.104071 0.697277 0.888705 0.989524 0.40972 0.953309 ] +4739,[4612],500,inf,1,1,0,0,53,[ 0.938985 0.148624 0.978541 0.0546537 0.883412 0.0949958 0.242718 0.962165 0.473005 0.25833 0.579728 0.931965 0.295311 0.344145 0.440932 0.896322 0.312038 0.661591 0.384184 0.0371882 ] +4645,[4612],491,inf,1,20,2,2,53,[ 0.995809 0.562972 0.284687 0.830449 0.269955 0.0949958 0.242718 0.962165 0.473005 0.25833 0.579728 0.931965 0.295311 0.344145 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +4707,[4601],497,inf,5,15,0,0,44,[ 0.995809 0.187121 0.978541 0.174138 0.779632 0.578599 0.852754 0.533489 0.975623 0.00958576 0.0605428 0.357139 0.856259 0.767401 0.74891 0.860365 0.896396 0.495374 0.40972 0.953309 ] +4629,[4073],489,inf,4,30,0,0,33,[ 0.357903 0.966937 0.946456 0.245193 0.955627 0.973499 0.242718 0.876586 0.423019 0.587516 0.982733 0.648338 0.856259 0.102744 0.315735 0.742182 0.985764 0.706301 0.23036 0.130208 ] +4686,[4591],494,inf,3,18,0,0,38,[ 0.00782676 0.966937 0.946456 0.820802 0.70148 0.370888 0.15659 0.876586 0.423019 0.587516 0.982733 0.858428 0.838768 0.468659 0.793625 0.742182 0.985764 0.293359 0.997853 0.770533 ] +4615,[4379],487,inf,7,51,1,1,34,[ 0.763682 0.477589 0.946456 0.245193 0.955627 0.973499 0.242718 0.962165 0.473005 0.25833 0.0922876 0.858428 0.838768 0.468659 0.793625 0.742182 0.985764 0.706301 0.743279 0.0810917 ] +4612,[4505],487,inf,3,34,2,4,52,[ 0.995809 0.187121 0.978541 0.0546537 0.883412 0.0949958 0.242718 0.962165 0.473005 0.25833 0.579728 0.931965 0.295311 0.344145 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +4591,[4549],484,inf,5,84,2,3,37,[ 0.00782676 0.966937 0.946456 0.820802 0.70148 0.897296 0.852754 0.540698 0.799621 0.587516 0.982733 0.858428 0.838768 0.468659 0.793625 0.742182 0.985764 0.293359 0.997853 0.770533 ] +4626,[4590],488,inf,4,44,0,0,40,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.973499 0.242718 0.876586 0.423019 0.587516 0.982733 0.858428 0.838768 0.896412 0.0801959 0.860365 0.319087 0.293359 0.997853 0.770533 ] +4568,[4330],482,inf,6,59,2,2,50,[ 0.995809 0.187121 0.941875 0.229312 0.955627 0.973499 0.242718 0.876586 0.423019 0.587516 0.982733 0.858428 0.838768 0.896412 0.104071 0.896322 0.312038 0.661591 0.55268 0.953309 ] +4555,[4500],481,inf,7,85,1,1,54,[ 0.78551 0.867437 0.205732 0.830449 0.269955 0.0949958 0.475437 0.411102 0.473947 0.889831 0.579728 0.931965 0.295311 0.344145 0.440932 0.896322 0.312038 0.884998 0.691646 0.257073 ] +4732,[4546],500,inf,1,1,0,0,53,[ 0.995809 0.562972 0.284687 0.830449 0.269955 0.403992 0.785694 0.649344 0.548345 0.889831 0.579728 0.168103 0.191729 0.351559 0.104071 0.697277 0.888705 0.989524 0.40972 0.953309 ] +4595,[4551],485,inf,2,30,0,0,44,[ 0.995809 0.187121 0.978541 0.174138 0.779632 0.578599 0.852754 0.540698 0.799621 0.587516 0.982733 0.858428 0.838768 0.896412 0.104071 0.697277 0.905925 0.635672 0.23036 0.333746 ] +4546,[4115],479,inf,2,64,2,3,52,[ 0.995809 0.562972 0.284687 0.830449 0.269955 0.403992 0.785694 0.649344 0.548345 0.889831 0.0922876 0.858428 0.838768 0.896412 0.104071 0.697277 0.888705 0.989524 0.40972 0.953309 ] +4517,[4385],476,inf,4,79,0,0,38,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.548185 0.785694 0.498945 0.147207 0.927945 0.842535 0.639207 0.324924 0.468659 0.793625 0.742182 0.985764 0.293359 0.997853 0.770533 ] +4733,[4521],500,inf,1,1,0,0,36,[ 0.297263 0.477589 0.946456 0.820802 0.70148 0.897296 0.852754 0.533489 0.975623 0.814646 0.806981 0.0820834 0.798354 0.344145 0.74891 0.860365 0.319087 0.293359 0.102403 0.173893 ] +4539,[4481],478,inf,5,69,2,2,51,[ 0.995809 0.187121 0.941875 0.229312 0.955627 0.973499 0.242718 0.876586 0.423019 0.587516 0.982733 0.648338 0.856259 0.767401 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +4736,[4539],500,inf,1,1,0,0,52,[ 0.995809 0.562972 0.107549 0.547519 0.399304 0.973499 0.242718 0.876586 0.423019 0.587516 0.982733 0.648338 0.856259 0.767401 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +4447,[4023],469,inf,4,101,1,1,42,[ 0.995809 0.187121 0.978541 0.174138 0.779632 0.578599 0.852754 0.540698 0.799621 0.587516 0.982733 0.648338 0.856259 0.767401 0.74891 0.860365 0.896396 0.495374 0.40972 0.953309 ] +4521,[4263],476,500,0,84,2,3,35,[ 0.00782676 0.966937 0.946456 0.820802 0.70148 0.897296 0.852754 0.533489 0.975623 0.814646 0.806981 0.0820834 0.798354 0.344145 0.74891 0.860365 0.319087 0.293359 0.997853 0.770533 ] +4726,[4717],499,500,0,1,1,1,57,[ 0.853625 0.905349 0.830128 0.72392 0.399304 0.973499 0.242718 0.962165 0.733312 0.00958576 0.0605428 0.357139 0.856259 0.767401 0.440932 0.697277 0.888705 0.989524 0.682412 0.0371882 ] +4688,[4461],495,499,0,9,1,2,55,[ 0.763682 0.682845 0.170814 0.72392 0.399304 0.973499 0.242718 0.962165 0.473005 0.25833 0.0922876 0.648338 0.856259 0.767401 0.440932 0.697277 0.888705 0.989524 0.682412 0.720599 ] +4703,[4591],497,499,0,3,2,2,38,[ 0.297263 0.477589 0.946456 0.820802 0.70148 0.897296 0.852754 0.540698 0.799621 0.587516 0.982733 0.858428 0.838768 0.468659 0.793625 0.742182 0.985764 0.293359 0.102403 0.173893 ] +4601,[4447],485,499,0,26,1,1,43,[ 0.995809 0.187121 0.978541 0.174138 0.779632 0.578599 0.852754 0.533489 0.920642 0.25833 0.0922876 0.648338 0.856259 0.767401 0.74891 0.860365 0.896396 0.495374 0.40972 0.953309 ] +4461,[4420],470,498,0,78,1,2,54,[ 0.763682 0.682845 0.170814 0.72392 0.399304 0.973499 0.242718 0.962165 0.473005 0.25833 0.579728 0.931965 0.295311 0.344145 0.440932 0.697277 0.888705 0.989524 0.682412 0.720599 ] +4712,[4546],497,498,0,1,1,2,53,[ 0.995809 0.562972 0.284687 0.830449 0.269955 0.403992 0.785694 0.649344 0.792434 0.4109 0.0605428 0.363967 0.838768 0.896412 0.104071 0.697277 0.888705 0.989524 0.40972 0.953309 ] +4551,[4439],480,497,0,74,2,3,43,[ 0.995809 0.187121 0.978541 0.174138 0.779632 0.578599 0.852754 0.540698 0.799621 0.587516 0.982733 0.858428 0.838768 0.896412 0.104071 0.697277 0.888705 0.989524 0.40972 0.953309 ] +4549,[4524],480,491,0,31,1,4,36,[ 0.357903 0.966937 0.946456 0.820802 0.70148 0.897296 0.852754 0.540698 0.799621 0.587516 0.982733 0.858428 0.838768 0.468659 0.793625 0.742182 0.985764 0.706301 0.23036 0.130208 ] +4379,[4073],463,490,0,65,1,2,33,[ 0.763682 0.477589 0.946456 0.245193 0.955627 0.973499 0.242718 0.876586 0.423019 0.587516 0.982733 0.858428 0.838768 0.468659 0.793625 0.742182 0.985764 0.706301 0.743279 0.0810917 ] +4590,[4536],484,489,0,11,1,1,39,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.973499 0.242718 0.876586 0.423019 0.859268 0.842535 0.639207 0.324924 0.896412 0.0801959 0.860365 0.319087 0.293359 0.997853 0.770533 ] +4500,[4480],474,488,0,39,1,2,53,[ 0.78551 0.867437 0.205732 0.830449 0.269955 0.0949958 0.242718 0.962165 0.473005 0.25833 0.579728 0.931965 0.295311 0.344145 0.440932 0.896322 0.312038 0.884998 0.691646 0.257073 ] +4439,[4023],468,488,0,51,1,3,42,[ 0.995809 0.187121 0.941875 0.703895 0.70148 0.897296 0.852754 0.540698 0.799621 0.587516 0.982733 0.858428 0.838768 0.896412 0.104071 0.697277 0.888705 0.989524 0.40972 0.953309 ] +4536,[4385],478,485,0,14,1,1,38,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.973499 0.242718 0.876586 0.423019 0.859268 0.842535 0.639207 0.324924 0.468659 0.793625 0.742182 0.985764 0.293359 0.997853 0.770533 ] +4330,[4316],457,483,0,81,2,6,49,[ 0.995809 0.187121 0.941875 0.229312 0.955627 0.973499 0.242718 0.876586 0.423019 0.587516 0.982733 0.648338 0.856259 0.767401 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +4481,[4330],472,498,0,71,1,3,50,[ 0.995809 0.187121 0.941875 0.229312 0.955627 0.973499 0.242718 0.876586 0.423019 0.587516 0.982733 0.648338 0.856259 0.767401 0.440932 0.697277 0.888705 0.989524 0.40972 0.953309 ] +4480,[4469],472,480,0,14,1,2,52,[ 0.108041 0.562972 0.284687 0.830449 0.269955 0.0949958 0.242718 0.962165 0.473005 0.25833 0.579728 0.931965 0.295311 0.344145 0.440932 0.896322 0.312038 0.884998 0.691646 0.732557 ] +4524,[4472],477,480,0,3,1,4,35,[ 0.357903 0.966937 0.946456 0.820802 0.70148 0.897296 0.515747 0.498945 0.147207 0.54765 0.982733 0.858428 0.838768 0.468659 0.793625 0.742182 0.985764 0.706301 0.23036 0.130208 ] +4385,[4166],463,478,0,59,3,4,37,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.973499 0.475437 0.135632 0.369805 0.927945 0.842535 0.639207 0.324924 0.468659 0.793625 0.742182 0.985764 0.293359 0.997853 0.770533 ] +4335,[4332],458,476,0,58,2,7,50,[ 0.995809 0.187121 0.978541 0.0546537 0.883412 0.0949958 0.242718 0.962165 0.473005 0.25833 0.579728 0.931965 0.295311 0.344145 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +4469,[4335],471,473,0,4,1,2,51,[ 0.995809 0.562972 0.284687 0.830449 0.269955 0.0949958 0.242718 0.962165 0.473005 0.25833 0.579728 0.931965 0.295311 0.344145 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +4023,[3734],424,473,0,133,2,5,41,[ 0.995809 0.187121 0.941875 0.703895 0.70148 0.897296 0.852754 0.540698 0.799621 0.587516 0.982733 0.648338 0.856259 0.767401 0.74891 0.860365 0.896396 0.495374 0.40972 0.953309 ] +4420,[4306],467,471,0,8,1,2,53,[ 0.763682 0.682845 0.170814 0.72392 0.399304 0.973499 0.242718 0.962165 0.473005 0.25833 0.579728 0.931965 0.295311 0.344145 0.440932 0.697277 0.905925 0.635672 0.743279 0.0810917 ] +4166,[4161],440,470,0,96,1,4,36,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.973499 0.475437 0.135632 0.369805 0.927945 0.842535 0.639207 0.324924 0.896412 0.0801959 0.860365 0.319087 0.293359 0.997853 0.770533 ] +4306,[4303],455,468,0,62,1,2,52,[ 0.763682 0.682845 0.170814 0.72392 0.399304 0.973499 0.242718 0.962165 0.473005 0.25833 0.579728 0.931965 0.295311 0.344145 0.440932 0.697277 0.888705 0.989524 0.682412 0.720599 ] +4150,[3941],438,467,0,88,1,4,31,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.973499 0.475437 0.135632 0.369805 0.927945 0.842535 0.639207 0.324924 0.468659 0.793625 0.742182 0.985764 0.293359 0.997853 0.770533 ] +2848,[2826],297,462,0,637,1,3,23,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.973499 0.242718 0.962165 0.733312 0.814646 0.806981 0.0820834 0.685525 0.0880566 0.678145 0.815135 0.985764 0.293359 0.997853 0.770533 ] +4316,[4101],456,460,0,8,2,13,48,[ 0.995809 0.187121 0.941875 0.229312 0.955627 0.973499 0.242718 0.962165 0.473005 0.25833 0.0922876 0.648338 0.856259 0.767401 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +4101,[4035],433,460,0,99,1,13,47,[ 0.995809 0.187121 0.941875 0.229312 0.955627 0.973499 0.242718 0.962165 0.473005 0.25833 0.0922876 0.648338 0.856259 0.767401 0.440932 0.697277 0.888705 0.989524 0.40972 0.953309 ] +4141,[4089],437,454,0,76,1,3,33,[ 0.00782676 0.966937 0.946456 0.820802 0.70148 0.897296 0.852754 0.533489 0.975623 0.814646 0.806981 0.0820834 0.685525 0.0880566 0.678145 0.815135 0.985764 0.293359 0.997853 0.770533 ] +4035,[3720],425,447,0,63,1,13,46,[ 0.995809 0.187121 0.941875 0.229312 0.955627 0.973499 0.242718 0.876586 0.423019 0.587516 0.982733 0.648338 0.856259 0.767401 0.440932 0.697277 0.888705 0.989524 0.40972 0.953309 ] +3941,[3397],414,443,0,90,1,4,30,[ 0.357903 0.966937 0.946456 0.245193 0.955627 0.973499 0.475437 0.135632 0.369805 0.927945 0.842535 0.639207 0.324924 0.468659 0.793625 0.742182 0.985764 0.706301 0.23036 0.130208 ] +4089,[3886],432,442,0,26,1,3,32,[ 0.00782676 0.966937 0.946456 0.820802 0.70148 0.897296 0.852754 0.533489 0.975623 0.00958576 0.0662877 0.831627 0.363537 0.0880566 0.678145 0.815135 0.985764 0.293359 0.997853 0.770533 ] +4303,[4284],454,456,0,4,1,2,51,[ 0.357903 0.00398165 0.170814 0.72392 0.399304 0.973499 0.242718 0.962165 0.473005 0.25833 0.579728 0.931965 0.295311 0.344145 0.440932 0.697277 0.888705 0.989524 0.40972 0.560169 ] +4117,[4106],435,440,0,9,1,4,34,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.548185 0.785694 0.498945 0.147207 0.54765 0.982733 0.858428 0.838768 0.896412 0.0801959 0.860365 0.319087 0.293359 0.997853 0.770533 ] +4106,[4093],434,435,0,1,1,4,33,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.548185 0.785694 0.649344 0.548345 0.889831 0.0922876 0.858428 0.838768 0.896412 0.0801959 0.860365 0.319087 0.293359 0.997853 0.770533 ] +3844,[3648],404,435,0,100,1,4,31,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.548185 0.785694 0.498945 0.147207 0.927945 0.842535 0.639207 0.324924 0.896412 0.0801959 0.860365 0.319087 0.293359 0.997853 0.770533 ] +4093,[3844],433,434,0,1,1,4,32,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.548185 0.785694 0.649344 0.548345 0.428048 0.11052 0.639207 0.324924 0.896412 0.0801959 0.860365 0.319087 0.293359 0.997853 0.770533 ] +4060,[3908],428,433,0,13,1,3,31,[ 0.357903 0.966937 0.946456 0.245193 0.955627 0.973499 0.475437 0.135632 0.369805 0.54765 0.982733 0.858428 0.838768 0.468659 0.793625 0.742182 0.985764 0.706301 0.23036 0.130208 ] +3720,[3534],389,430,0,165,2,15,45,[ 0.995809 0.187121 0.941875 0.229312 0.955627 0.973499 0.242718 0.876586 0.423019 0.587516 0.982733 0.648338 0.856259 0.767401 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +3397,[3325],353,419,0,251,3,11,29,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.973499 0.475437 0.135632 0.369805 0.927945 0.842535 0.639207 0.324924 0.468659 0.793625 0.742182 0.985764 0.293359 0.997853 0.770533 ] +3811,[3659],398,413,0,42,1,4,47,[ 0.995809 0.562972 0.284687 0.830449 0.269955 0.403992 0.785694 0.649344 0.548345 0.889831 0.0922876 0.858428 0.838768 0.896412 0.104071 0.896322 0.312038 0.661591 0.55268 0.953309 ] +3916,[3904],411,412,0,1,1,4,49,[ 0.108041 0.562972 0.284687 0.830449 0.269955 0.403992 0.785694 0.649344 0.548345 0.889831 0.579728 0.168103 0.191729 0.351559 0.104071 0.896322 0.312038 0.884998 0.691646 0.732557 ] +3904,[3811],410,411,0,1,1,4,48,[ 0.995809 0.562972 0.284687 0.830449 0.269955 0.403992 0.785694 0.649344 0.548345 0.889831 0.579728 0.168103 0.191729 0.351559 0.104071 0.896322 0.312038 0.661591 0.55268 0.953309 ] +3847,[3807],404,410,0,14,1,3,30,[ 0.00782676 0.966937 0.946456 0.820802 0.70148 0.897296 0.852754 0.540698 0.799621 0.587516 0.75557 0.931965 0.363537 0.0880566 0.678145 0.815135 0.985764 0.293359 0.997853 0.770533 ] +4115,[3920],435,500,0,235,1,4,51,[ 0.995809 0.562972 0.284687 0.830449 0.269955 0.403992 0.785694 0.649344 0.548345 0.889831 0.0922876 0.858428 0.838768 0.896412 0.104071 0.896322 0.312038 0.661591 0.55268 0.953309 ] +4676,[4539],494,496,0,4,1,1,52,[ 0.995809 0.187121 0.978541 0.0546537 0.883412 0.0949958 0.242718 0.876586 0.423019 0.587516 0.982733 0.648338 0.856259 0.767401 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +3648,[3397],380,409,0,108,1,4,30,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.548185 0.785694 0.498945 0.147207 0.927945 0.842535 0.639207 0.324924 0.468659 0.793625 0.742182 0.985764 0.293359 0.997853 0.770533 ] +4472,[4323],471,482,0,29,1,4,34,[ 0.00782676 0.966937 0.946456 0.820802 0.70148 0.897296 0.515747 0.498945 0.147207 0.54765 0.982733 0.858428 0.838768 0.468659 0.793625 0.742182 0.985764 0.293359 0.997853 0.770533 ] +3886,[3847],408,452,0,163,1,3,31,[ 0.00782676 0.966937 0.946456 0.820802 0.70148 0.897296 0.852754 0.533489 0.920642 0.25833 0.579728 0.931965 0.363537 0.0880566 0.678145 0.815135 0.985764 0.293359 0.997853 0.770533 ] +3591,[3464],374,408,0,121,1,5,38,[ 0.995809 0.187121 0.978541 0.174138 0.779632 0.578599 0.852754 0.540698 0.799621 0.587516 0.982733 0.858428 0.838768 0.896412 0.104071 0.697277 0.888705 0.989524 0.40972 0.953309 ] +3874,[3860],407,417,0,24,1,2,47,[ 0.995809 0.562972 0.107549 0.547519 0.399304 0.973499 0.242718 0.962165 0.473005 0.25833 0.0922876 0.648338 0.856259 0.767401 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +3807,[3763],398,406,0,23,1,3,29,[ 0.357903 0.966937 0.946456 0.820802 0.70148 0.897296 0.852754 0.540698 0.799621 0.587516 0.75557 0.931965 0.363537 0.0880566 0.678145 0.815135 0.985764 0.706301 0.23036 0.130208 ] +3464,[3371],361,406,0,153,1,5,37,[ 0.995809 0.187121 0.978541 0.174138 0.779632 0.578599 0.852754 0.540698 0.799621 0.587516 0.982733 0.648338 0.856259 0.767401 0.440932 0.697277 0.888705 0.989524 0.40972 0.953309 ] +3659,[3518],382,404,0,57,1,4,46,[ 0.995809 0.562972 0.284687 0.830449 0.269955 0.403992 0.785694 0.649344 0.548345 0.889831 0.0922876 0.858428 0.838768 0.896412 0.104071 0.896322 0.775705 0.824472 0.415025 0.333746 ] +3689,[3591],385,396,0,25,1,5,39,[ 0.995809 0.187121 0.978541 0.174138 0.779632 0.578599 0.852754 0.540698 0.799621 0.587516 0.982733 0.858428 0.838768 0.896412 0.0801959 0.860365 0.896396 0.495374 0.40972 0.953309 ] +3726,[3702],389,395,0,26,1,3,27,[ 0.357903 0.966937 0.946456 0.245193 0.955627 0.548185 0.365416 0.533489 0.920642 0.25833 0.579728 0.931965 0.363537 0.0880566 0.678145 0.815135 0.985764 0.706301 0.23036 0.130208 ] +3534,[3413],368,391,0,47,1,15,44,[ 0.995809 0.187121 0.978541 0.0546537 0.883412 0.0949958 0.242718 0.876586 0.423019 0.587516 0.982733 0.648338 0.856259 0.767401 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +3481,[3446],363,390,0,76,1,3,25,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.548185 0.365416 0.533489 0.975623 0.00958576 0.0662877 0.831627 0.363537 0.0880566 0.678145 0.815135 0.985764 0.293359 0.997853 0.770533 ] +3413,[3362],355,378,0,60,1,15,43,[ 0.995809 0.187121 0.941875 0.229312 0.955627 0.973499 0.242718 0.876586 0.423019 0.587516 0.982733 0.648338 0.856259 0.767401 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +3325,[3023],347,374,0,123,1,11,28,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.973499 0.475437 0.135632 0.369805 0.54765 0.982733 0.858428 0.838768 0.468659 0.793625 0.742182 0.985764 0.293359 0.997853 0.770533 ] +3445,[3437],359,371,0,26,1,4,44,[ 0.995809 0.562972 0.284687 0.830449 0.269955 0.403992 0.365416 0.533489 0.920642 0.25833 0.0922876 0.648338 0.856259 0.767401 0.440932 0.896322 0.775705 0.824472 0.415025 0.333746 ] +3446,[2848],359,364,0,13,1,3,24,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.548185 0.365416 0.533489 0.975623 0.814646 0.806981 0.0820834 0.685525 0.0880566 0.678145 0.815135 0.985764 0.293359 0.997853 0.770533 ] +3371,[3338],351,363,0,39,1,5,36,[ 0.995809 0.187121 0.978541 0.174138 0.779632 0.578599 0.852754 0.540698 0.799621 0.587516 0.982733 0.648338 0.856259 0.767401 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +3390,[3328],353,362,0,12,1,4,42,[ 0.995809 0.562972 0.284687 0.830449 0.269955 0.403992 0.365416 0.540698 0.799621 0.587516 0.982733 0.648338 0.856259 0.767401 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +4516,[4385],476,494,0,45,1,2,38,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.973499 0.475437 0.135632 0.369805 0.927945 0.842535 0.639207 0.668826 0.244673 0.612517 0.815135 0.985764 0.293359 0.997853 0.770533 ] +3328,[3219],347,358,0,22,1,4,41,[ 0.995809 0.562972 0.284687 0.830449 0.269955 0.403992 0.365416 0.540698 0.799621 0.587516 0.982733 0.858428 0.838768 0.896412 0.104071 0.896322 0.312038 0.661591 0.55268 0.953309 ] +3338,[2955],348,354,0,17,1,5,35,[ 0.995809 0.187121 0.978541 0.174138 0.779632 0.578599 0.852754 0.540698 0.799621 0.587516 0.982733 0.858428 0.838768 0.896412 0.104071 0.896322 0.312038 0.661591 0.55268 0.953309 ] +3219,[3174],335,353,0,65,1,4,40,[ 0.995809 0.562972 0.284687 0.830449 0.269955 0.403992 0.365416 0.540698 0.799621 0.587516 0.982733 0.648338 0.856259 0.767401 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +3035,[2841],315,341,0,73,1,19,37,[ 0.995809 0.562972 0.284687 0.830449 0.269955 0.0949958 0.242718 0.962165 0.473005 0.25833 0.0922876 0.648338 0.856259 0.767401 0.440932 0.697277 0.888705 0.989524 0.40972 0.953309 ] +3174,[3076],329,337,0,19,2,19,39,[ 0.995809 0.562972 0.284687 0.830449 0.269955 0.0949958 0.242718 0.876586 0.423019 0.587516 0.982733 0.648338 0.856259 0.767401 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +1859,[1779],194,327,0,512,1,3,21,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.973499 0.242718 0.962165 0.473005 0.25833 0.579728 0.931965 0.363537 0.0880566 0.678145 0.815135 0.985764 0.293359 0.997853 0.770533 ] +2841,[2751],297,318,0,60,1,19,36,[ 0.995809 0.562972 0.284687 0.830449 0.269955 0.0949958 0.242718 0.962165 0.473005 0.25833 0.0922876 0.858428 0.838768 0.896412 0.104071 0.697277 0.888705 0.989524 0.40972 0.953309 ] +2836,[2791],296,315,0,49,1,5,33,[ 0.995809 0.187121 0.978541 0.174138 0.779632 0.578599 0.852754 0.540698 0.799621 0.587516 0.982733 0.648338 0.856259 0.767401 0.440932 0.697277 0.888705 0.989524 0.40972 0.953309 ] +2955,[2836],307,365,0,253,1,5,34,[ 0.995809 0.187121 0.978541 0.174138 0.779632 0.578599 0.852754 0.540698 0.799621 0.587516 0.982733 0.858428 0.838768 0.896412 0.104071 0.697277 0.888705 0.989524 0.40972 0.953309 ] +3362,[3275],351,356,0,6,1,15,42,[ 0.108041 0.187121 0.941875 0.229312 0.955627 0.973499 0.242718 0.876586 0.423019 0.587516 0.982733 0.648338 0.856259 0.767401 0.440932 0.896322 0.312038 0.884998 0.691646 0.732557 ] +2709,[2563],283,310,0,84,1,11,25,[ 0.752796 0.100866 0.735495 0.245193 0.955627 0.548185 0.785694 0.498945 0.147207 0.927945 0.842535 0.639207 0.324924 0.468659 0.793625 0.742182 0.985764 0.293359 0.997853 0.490444 ] +2791,[2541],292,308,0,68,1,5,32,[ 0.995809 0.187121 0.978541 0.174138 0.779632 0.578599 0.852754 0.540698 0.799621 0.587516 0.982733 0.858428 0.838768 0.896412 0.104071 0.697277 0.888705 0.989524 0.40972 0.953309 ] +2751,[2514],287,300,0,27,1,19,35,[ 0.995809 0.562972 0.284687 0.830449 0.269955 0.0949958 0.242718 0.962165 0.473005 0.25833 0.0922876 0.648338 0.856259 0.767401 0.440932 0.697277 0.888705 0.989524 0.40972 0.953309 ] +2826,[1859],295,297,0,2,1,3,22,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.973499 0.242718 0.962165 0.473005 0.133057 0.276633 0.308157 0.685525 0.0880566 0.678145 0.815135 0.985764 0.293359 0.997853 0.770533 ] +3920,[3916],412,437,0,94,1,4,50,[ 0.108041 0.562972 0.284687 0.830449 0.269955 0.403992 0.785694 0.649344 0.548345 0.889831 0.0922876 0.858428 0.838768 0.896412 0.104071 0.896322 0.312038 0.884998 0.691646 0.732557 ] +2541,[2424],263,294,0,119,1,5,31,[ 0.995809 0.187121 0.978541 0.174138 0.779632 0.578599 0.852754 0.540698 0.799621 0.587516 0.982733 0.858428 0.838768 0.468659 0.741723 0.618092 0.590382 0.989524 0.40972 0.953309 ] +2514,[2456],260,288,0,86,1,19,34,[ 0.995809 0.562972 0.284687 0.830449 0.269955 0.0949958 0.242718 0.876586 0.423019 0.587516 0.982733 0.648338 0.856259 0.767401 0.440932 0.697277 0.888705 0.989524 0.40972 0.953309 ] +2424,[2403],251,264,0,52,1,5,30,[ 0.995809 0.187121 0.978541 0.174138 0.779632 0.578599 0.852754 0.540698 0.799621 0.587516 0.982733 0.648338 0.856259 0.102744 0.46977 0.618092 0.590382 0.989524 0.40972 0.953309 ] +2382,[2358],247,255,0,18,1,19,31,[ 0.995809 0.562972 0.107549 0.547519 0.399304 0.973499 0.242718 0.876586 0.423019 0.587516 0.75557 0.931965 0.295311 0.344145 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +2268,[2150],234,254,0,45,1,5,28,[ 0.995809 0.187121 0.978541 0.174138 0.779632 0.578599 0.852754 0.540698 0.234196 0.545666 0.488427 0.357139 0.856259 0.767401 0.440932 0.697277 0.888705 0.989524 0.40972 0.953309 ] +2403,[2268],250,252,0,4,1,5,29,[ 0.995809 0.187121 0.978541 0.174138 0.779632 0.578599 0.852754 0.540698 0.234196 0.545666 0.488427 0.357139 0.856259 0.102744 0.46977 0.618092 0.590382 0.989524 0.40972 0.953309 ] +2082,[2054],215,245,0,74,1,19,29,[ 0.995809 0.562972 0.107549 0.547519 0.399304 0.973499 0.242718 0.962165 0.473005 0.25833 0.0922876 0.648338 0.856259 0.767401 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +4073,[4060],430,495,0,198,2,3,32,[ 0.357903 0.966937 0.946456 0.245193 0.955627 0.973499 0.242718 0.876586 0.423019 0.587516 0.982733 0.858428 0.838768 0.468659 0.793625 0.742182 0.985764 0.706301 0.23036 0.130208 ] +3437,[3390],358,362,0,6,1,4,43,[ 0.995809 0.562972 0.284687 0.830449 0.269955 0.403992 0.365416 0.533489 0.920642 0.25833 0.0922876 0.648338 0.856259 0.767401 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +3076,[3035],320,335,0,32,1,19,38,[ 0.995809 0.562972 0.284687 0.830449 0.269955 0.0949958 0.242718 0.962165 0.473005 0.25833 0.0922876 0.648338 0.856259 0.767401 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +2358,[2082],245,248,0,8,1,19,30,[ 0.995809 0.562972 0.107549 0.547519 0.399304 0.973499 0.242718 0.962165 0.473005 0.25833 0.579728 0.931965 0.295311 0.344145 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +4505,[4335],475,500,0,59,1,5,51,[ 0.995809 0.187121 0.978541 0.0546537 0.883412 0.0949958 0.242718 0.962165 0.473005 0.25833 0.579728 0.931965 0.295311 0.633164 0.46977 0.333701 0.102967 0.661591 0.55268 0.953309 ] +1905,[1360],198,226,0,106,1,5,26,[ 0.995809 0.187121 0.978541 0.174138 0.779632 0.578599 0.852754 0.533489 0.975623 0.00958576 0.0605428 0.363967 0.838768 0.896412 0.104071 0.697277 0.888705 0.989524 0.40972 0.953309 ] +1603,[1129],169,225,0,215,1,3,17,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.973499 0.242718 0.876586 0.423019 0.587516 0.982733 0.858428 0.838768 0.468659 0.793625 0.742182 0.985764 0.293359 0.997853 0.770533 ] +2072,[1960],214,225,0,17,1,11,22,[ 0.357903 0.966937 0.946456 0.245193 0.955627 0.548185 0.785694 0.498945 0.147207 0.927945 0.842535 0.639207 0.668826 0.244673 0.612517 0.815135 0.985764 0.706301 0.23036 0.130208 ] +2028,[1991],210,214,0,10,1,19,27,[ 0.995809 0.562972 0.107549 0.547519 0.399304 0.973499 0.242718 0.962165 0.473005 0.25833 0.0922876 0.648338 0.856259 0.767401 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +176,[142],18,51,0,133,1,5,7,[ 0.995809 0.187121 0.978541 0.174138 0.779632 0.578599 0.852754 0.533489 0.920642 0.25833 0.579728 0.931965 0.295311 0.633164 0.46977 0.618092 0.590382 0.989524 0.40972 0.953309 ] +4294,[4150],453,458,0,16,1,4,32,[ 0.00782676 0.966937 0.946456 0.820802 0.70148 0.370888 0.741965 0.135632 0.369805 0.927945 0.842535 0.639207 0.324924 0.468659 0.793625 0.742182 0.985764 0.293359 0.997853 0.770533 ] +208,[191],22,46,0,90,1,14,7,[ 0.752796 0.100866 0.735495 0.245193 0.955627 0.973499 0.242718 0.876586 0.423019 0.587516 0.982733 0.648338 0.856259 0.102744 0.315735 0.742182 0.985764 0.293359 0.997853 0.490444 ] +642,[486],65,70,0,12,1,19,14,[ 0.0799833 0.100866 0.735495 0.245193 0.955627 0.973499 0.475437 0.411102 0.473947 0.889831 0.0922876 0.648338 0.414352 0.820117 0.579269 0.448677 0.888705 0.989524 0.40972 0.953309 ] +409,[357],42,45,0,8,1,5,11,[ 0.995809 0.562972 0.284687 0.0702805 0.575156 0.578599 0.852754 0.533489 0.920642 0.25833 0.0922876 0.858428 0.838768 0.896412 0.104071 0.697277 0.888705 0.989524 0.40972 0.953309 ] +357,[336],37,45,0,24,1,5,10,[ 0.995809 0.562972 0.284687 0.0702805 0.575156 0.578599 0.852754 0.533489 0.920642 0.25833 0.0922876 0.648338 0.856259 0.767401 0.440932 0.697277 0.888705 0.989524 0.40972 0.953309 ] +1360,[1151],140,200,0,254,1,5,25,[ 0.995809 0.187121 0.978541 0.174138 0.779632 0.578599 0.852754 0.533489 0.975623 0.00958576 0.0605428 0.363967 0.838768 0.896412 0.104071 0.896322 0.312038 0.661591 0.55268 0.953309 ] +3908,[3397],410,434,0,91,1,3,30,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.973499 0.475437 0.135632 0.369805 0.54765 0.982733 0.858428 0.838768 0.468659 0.793625 0.742182 0.985764 0.293359 0.997853 0.770533 ] +3763,[3726],394,409,0,34,1,3,28,[ 0.357903 0.966937 0.946456 0.820802 0.70148 0.897296 0.852754 0.533489 0.920642 0.25833 0.579728 0.931965 0.363537 0.0880566 0.678145 0.815135 0.985764 0.706301 0.23036 0.130208 ] +2935,[2709],305,324,0,56,1,11,26,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.548185 0.785694 0.498945 0.147207 0.927945 0.842535 0.639207 0.324924 0.468659 0.793625 0.742182 0.985764 0.293359 0.997853 0.770533 ] +142,[132],15,37,0,48,1,5,6,[ 0.995809 0.187121 0.978541 0.174138 0.779632 0.175327 0.15659 0.962165 0.473005 0.25833 0.579728 0.931965 0.295311 0.633164 0.46977 0.618092 0.590382 0.989524 0.40972 0.953309 ] +2118,[2072],219,271,0,161,1,11,23,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.548185 0.785694 0.498945 0.147207 0.927945 0.842535 0.639207 0.668826 0.244673 0.612517 0.815135 0.985764 0.293359 0.997853 0.770533 ] +2456,[2404],254,261,0,16,1,19,33,[ 0.995809 0.562972 0.107549 0.547519 0.399304 0.973499 0.242718 0.876586 0.423019 0.587516 0.982733 0.648338 0.856259 0.767401 0.440932 0.697277 0.888705 0.989524 0.40972 0.953309 ] +1073,[1042],112,151,0,98,1,5,23,[ 0.108041 0.187121 0.978541 0.174138 0.779632 0.578599 0.852754 0.533489 0.975623 0.00958576 0.0605428 0.357139 0.856259 0.767401 0.440932 0.896322 0.312038 0.884998 0.691646 0.732557 ] +301,[176],33,35,0,2,1,5,8,[ 0.995809 0.562972 0.284687 0.0702805 0.575156 0.578599 0.852754 0.533489 0.920642 0.25833 0.579728 0.931965 0.295311 0.633164 0.46977 0.618092 0.590382 0.989524 0.40972 0.953309 ] +46,[18],5,11,0,18,1,14,3,[ 0.887422 0.926932 0.735495 0.820802 0.70148 0.370888 0.15659 0.962165 0.473005 0.25833 0.579728 0.931965 0.295311 0.633164 0.315735 0.742182 0.985764 0.293359 0.102403 0.296413 ] +232,[202],24,34,0,64,1,19,11,[ 0.763682 0.477589 0.946456 0.245193 0.955627 0.973499 0.475437 0.411102 0.473947 0.889831 0.0922876 0.648338 0.856259 0.767401 0.440932 0.896322 0.312038 0.661591 0.384184 0.720599 ] +1179,[1135],123,161,0,148,1,11,18,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.548185 0.785694 0.498945 0.147207 0.927945 0.842535 0.639207 0.324924 0.468659 0.793625 0.742182 0.985764 0.293359 0.997853 0.770533 ] +143,[129],15,22,0,25,1,19,9,[ 0.258271 0.222559 0.298434 0.229312 0.955627 0.973499 0.242718 0.962165 0.473005 0.25833 0.0922876 0.648338 0.856259 0.767401 0.440932 0.896322 0.312038 0.661591 0.384184 0.720599 ] +111,[82],12,22,0,55,1,14,5,[ 0.752796 0.100866 0.735495 0.245193 0.955627 0.973499 0.242718 0.962165 0.473005 0.25833 0.579728 0.931965 0.295311 0.633164 0.315735 0.742182 0.985764 0.293359 0.997853 0.490444 ] +4284,[4230],452,455,0,5,1,2,50,[ 0.733981 0.867437 0.0233672 0.547519 0.399304 0.973499 0.242718 0.962165 0.473005 0.25833 0.579728 0.931965 0.295311 0.344145 0.440932 0.697277 0.888705 0.989524 0.40972 0.560169 ] +33,[5],3,7,0,15,1,24,2,[ 0.938985 0.148624 0.941875 0.703895 0.70148 0.370888 0.15659 0.962165 0.473005 0.25833 0.579728 0.168103 0.191729 0.422191 0.741723 0.618092 0.284055 0.635672 0.743279 0.789499 ] +2,[1],0,6,0,40,1,14,1,[ 0.887422 0.926932 0.735495 0.820802 0.70148 0.897296 0.852754 0.533489 0.920642 0.25833 0.579728 0.168103 0.191729 0.422191 0.793625 0.742182 0.985764 0.293359 0.102403 0.296413 ] +82,[46],10,17,0,22,1,14,4,[ 0.752796 0.100866 0.735495 0.820802 0.70148 0.370888 0.15659 0.962165 0.473005 0.25833 0.579728 0.931965 0.295311 0.633164 0.315735 0.742182 0.985764 0.293359 0.997853 0.490444 ] +64,[48],8,14,0,25,1,19,4,[ 0.938985 0.148624 0.941875 0.703895 0.70148 0.370888 0.15659 0.962165 0.473005 0.25833 0.579728 0.931965 0.295311 0.633164 0.46977 0.618092 0.590382 0.989524 0.682412 0.0371882 ] +646,[634],66,115,0,227,1,5,16,[ 0.995809 0.187121 0.978541 0.174138 0.779632 0.578599 0.852754 0.540698 0.799621 0.587516 0.982733 0.858428 0.838768 0.896412 0.104071 0.697277 0.888705 0.989524 0.40972 0.953309 ] +3275,[3190],341,351,0,27,1,15,41,[ 0.995809 0.187121 0.941875 0.229312 0.955627 0.973499 0.242718 0.876586 0.423019 0.587516 0.982733 0.648338 0.856259 0.767401 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +5,[1],0,8,0,47,1,24,1,[ 0.938985 0.148624 0.941875 0.703895 0.70148 0.897296 0.852754 0.533489 0.920642 0.25833 0.579728 0.168103 0.191729 0.422191 0.741723 0.618092 0.284055 0.635672 0.743279 0.789499 ] +73,[64],9,12,0,8,1,19,5,[ 0.938985 0.148624 0.941875 0.703895 0.70148 0.370888 0.15659 0.962165 0.473005 0.25833 0.0922876 0.648338 0.856259 0.102744 0.46977 0.618092 0.590382 0.989524 0.682412 0.0371882 ] +1900,[1685],197,205,0,15,1,19,25,[ 0.108041 0.187121 0.941875 0.229312 0.955627 0.973499 0.242718 0.962165 0.473005 0.25833 0.0922876 0.648338 0.856259 0.767401 0.440932 0.896322 0.312038 0.884998 0.691646 0.732557 ] +1342,[1272],138,147,0,20,1,19,21,[ 0.995809 0.187121 0.941875 0.229312 0.955627 0.973499 0.242718 0.962165 0.473005 0.25833 0.579728 0.931965 0.295311 0.633164 0.46977 0.618092 0.590382 0.989524 0.40972 0.953309 ] +4323,[4294],457,473,0,47,1,4,33,[ 0.00782676 0.966937 0.946456 0.820802 0.70148 0.897296 0.515747 0.498945 0.147207 0.927945 0.842535 0.639207 0.324924 0.468659 0.793625 0.742182 0.985764 0.293359 0.997853 0.770533 ] +3860,[3720],406,408,0,5,1,2,46,[ 0.995809 0.562972 0.107549 0.547519 0.399304 0.973499 0.242718 0.876586 0.423019 0.587516 0.982733 0.648338 0.856259 0.767401 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +18,[2],1,12,0,96,1,14,2,[ 0.887422 0.926932 0.735495 0.820802 0.70148 0.897296 0.852754 0.533489 0.920642 0.25833 0.579728 0.931965 0.295311 0.633164 0.315735 0.742182 0.985764 0.293359 0.102403 0.296413 ] +2054,[2028],213,219,0,12,1,19,28,[ 0.995809 0.562972 0.107549 0.547519 0.399304 0.973499 0.475437 0.411102 0.473947 0.889831 0.0922876 0.648338 0.856259 0.767401 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +191,[111],20,23,0,5,1,14,6,[ 0.752796 0.100866 0.735495 0.245193 0.955627 0.973499 0.242718 0.876586 0.423019 0.587516 0.75557 0.931965 0.295311 0.633164 0.315735 0.742182 0.985764 0.293359 0.997853 0.490444 ] +48,[33],5,13,0,31,2,24,3,[ 0.938985 0.148624 0.941875 0.703895 0.70148 0.370888 0.15659 0.962165 0.473005 0.25833 0.579728 0.168103 0.191729 0.422191 0.741723 0.618092 0.590382 0.989524 0.682412 0.0371882 ] +4161,[4117],439,444,0,14,1,4,35,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.548185 0.785694 0.498945 0.147207 0.927945 0.842535 0.639207 0.324924 0.896412 0.0801959 0.860365 0.319087 0.293359 0.997853 0.770533 ] +2563,[2118],266,284,0,47,1,11,24,[ 0.752796 0.100866 0.735495 0.245193 0.955627 0.548185 0.785694 0.498945 0.147207 0.927945 0.842535 0.639207 0.668826 0.244673 0.612517 0.815135 0.985764 0.293359 0.997853 0.490444 ] +1,[NONE],0,1,0,90,2,38,0,[ 0.506007 0.148624 0.941875 0.703895 0.70148 0.897296 0.852754 0.533489 0.920642 0.25833 0.579728 0.168103 0.191729 0.422191 0.741723 0.618092 0.284055 0.313045 0.102403 0.296413 ] +202,[143],21,26,0,26,1,19,10,[ 0.763682 0.477589 0.946456 0.245193 0.955627 0.973499 0.242718 0.962165 0.473005 0.25833 0.0922876 0.648338 0.856259 0.767401 0.440932 0.896322 0.312038 0.661591 0.384184 0.720599 ] +288,[232],31,55,0,80,1,19,12,[ 0.763682 0.477589 0.946456 0.245193 0.955627 0.973499 0.475437 0.411102 0.473947 0.889831 0.0922876 0.648338 0.856259 0.767401 0.440932 0.697277 0.888705 0.989524 0.682412 0.720599 ] +4263,[4141],450,486,0,182,1,3,34,[ 0.00782676 0.966937 0.946456 0.820802 0.70148 0.897296 0.852754 0.533489 0.975623 0.814646 0.806981 0.0820834 0.798354 0.633164 0.315735 0.742182 0.985764 0.293359 0.997853 0.770533 ] +427,[208],44,55,0,25,1,14,8,[ 0.752796 0.100866 0.735495 0.245193 0.955627 0.973499 0.242718 0.962165 0.473005 0.25833 0.0922876 0.648338 0.856259 0.102744 0.315735 0.742182 0.985764 0.293359 0.997853 0.490444 ] +2404,[2382],250,256,0,14,1,19,32,[ 0.995809 0.562972 0.107549 0.547519 0.399304 0.973499 0.242718 0.876586 0.423019 0.587516 0.982733 0.648338 0.856259 0.767401 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +132,[112],14,17,0,8,1,5,5,[ 0.995809 0.187121 0.941875 0.703895 0.70148 0.370888 0.15659 0.962165 0.473005 0.25833 0.579728 0.931965 0.295311 0.633164 0.46977 0.618092 0.590382 0.989524 0.40972 0.953309 ] +429,[409],45,60,0,31,1,5,12,[ 0.995809 0.562972 0.284687 0.0702805 0.575156 0.578599 0.852754 0.533489 0.920642 0.25833 0.0922876 0.858428 0.838768 0.896412 0.0801959 0.860365 0.896396 0.495374 0.40972 0.953309 ] +1129,[877],118,173,0,250,1,3,16,[ 0.357903 0.966937 0.946456 0.245193 0.955627 0.973499 0.242718 0.876586 0.423019 0.587516 0.982733 0.858428 0.838768 0.468659 0.793625 0.742182 0.985764 0.706301 0.23036 0.130208 ] +659,[627],67,73,0,13,1,14,11,[ 0.78551 0.507546 0.298434 0.229312 0.955627 0.973499 0.242718 0.962165 0.473005 0.25833 0.0922876 0.648338 0.856259 0.767401 0.74891 0.860365 0.319087 0.293359 0.997853 0.770533 ] +1685,[1567],177,198,0,54,1,19,24,[ 0.108041 0.187121 0.941875 0.229312 0.955627 0.973499 0.242718 0.962165 0.473005 0.25833 0.579728 0.931965 0.295311 0.344145 0.440932 0.896322 0.312038 0.884998 0.691646 0.732557 ] +1779,[1677],185,197,0,33,1,3,20,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.973499 0.242718 0.962165 0.473005 0.25833 0.579728 0.931965 0.295311 0.633164 0.315735 0.742182 0.985764 0.293359 0.997853 0.770533 ] +565,[429],57,65,0,25,1,5,13,[ 0.995809 0.562972 0.284687 0.0702805 0.575156 0.578599 0.852754 0.533489 0.920642 0.25833 0.0922876 0.648338 0.856259 0.767401 0.74891 0.860365 0.896396 0.495374 0.40972 0.953309 ] +3883,[3874],408,447,0,125,1,2,48,[ 0.995809 0.562972 0.107549 0.547519 0.399304 0.973499 0.242718 0.962165 0.473005 0.25833 0.579728 0.931965 0.295311 0.344145 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +514,[427],53,65,0,41,1,14,9,[ 0.752796 0.100866 0.735495 0.245193 0.955627 0.973499 0.242718 0.962165 0.473005 0.25833 0.0922876 0.648338 0.856259 0.767401 0.74891 0.860365 0.319087 0.293359 0.997853 0.490444 ] +634,[618],64,67,0,12,1,5,15,[ 0.995809 0.187121 0.978541 0.174138 0.779632 0.578599 0.852754 0.540698 0.799621 0.587516 0.982733 0.858428 0.838768 0.896412 0.0801959 0.860365 0.896396 0.495374 0.40972 0.953309 ] +627,[514],64,69,0,9,1,14,10,[ 0.108041 0.187121 0.941875 0.229312 0.955627 0.973499 0.242718 0.962165 0.473005 0.25833 0.0922876 0.648338 0.856259 0.767401 0.74891 0.860365 0.319087 0.293359 0.997853 0.490444 ] +4230,[3883],446,452,0,18,1,2,49,[ 0.995809 0.562972 0.107549 0.547519 0.399304 0.973499 0.242718 0.962165 0.473005 0.25833 0.579728 0.931965 0.295311 0.344145 0.440932 0.697277 0.888705 0.989524 0.40972 0.953309 ] +1991,[1900],205,214,0,24,1,19,26,[ 0.108041 0.562972 0.107549 0.547519 0.399304 0.973499 0.242718 0.962165 0.473005 0.25833 0.0922876 0.648338 0.856259 0.767401 0.440932 0.896322 0.312038 0.884998 0.691646 0.732557 ] +486,[288],50,73,0,86,1,19,13,[ 0.357903 0.966937 0.946456 0.245193 0.955627 0.973499 0.475437 0.411102 0.473947 0.889831 0.0922876 0.648338 0.414352 0.820117 0.579269 0.448677 0.888705 0.989524 0.40972 0.560169 ] +129,[113],14,26,0,50,1,19,8,[ 0.258271 0.222559 0.298434 0.229312 0.955627 0.973499 0.242718 0.962165 0.473005 0.25833 0.0922876 0.648338 0.856259 0.767401 0.440932 0.697277 0.888705 0.989524 0.682412 0.720599 ] +727,[677],74,80,0,17,1,14,13,[ 0.78551 0.507546 0.298434 0.229312 0.955627 0.973499 0.242718 0.876586 0.423019 0.587516 0.982733 0.858428 0.838768 0.896412 0.0801959 0.860365 0.319087 0.293359 0.997853 0.770533 ] +336,[301],35,38,0,9,1,5,9,[ 0.995809 0.562972 0.284687 0.0702805 0.575156 0.578599 0.852754 0.533489 0.920642 0.25833 0.579728 0.931965 0.295311 0.344145 0.440932 0.697277 0.888705 0.989524 0.40972 0.953309 ] +677,[659],69,82,0,24,1,14,12,[ 0.78551 0.507546 0.298434 0.229312 0.955627 0.973499 0.242718 0.962165 0.473005 0.25833 0.0922876 0.858428 0.838768 0.896412 0.0801959 0.860365 0.319087 0.293359 0.997853 0.770533 ] +772,[727],78,98,0,105,1,14,14,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.973499 0.242718 0.876586 0.423019 0.587516 0.982733 0.858428 0.838768 0.896412 0.0801959 0.860365 0.319087 0.293359 0.997853 0.770533 ] +99,[73],11,17,0,38,1,19,6,[ 0.938985 0.148624 0.941875 0.229312 0.955627 0.973499 0.242718 0.962165 0.473005 0.25833 0.0922876 0.648338 0.856259 0.102744 0.46977 0.618092 0.590382 0.989524 0.682412 0.0371882 ] +720,[662],73,100,0,70,1,19,16,[ 0.995809 0.187121 0.941875 0.229312 0.955627 0.973499 0.475437 0.411102 0.473947 0.889831 0.0922876 0.648338 0.856259 0.767401 0.440932 0.697277 0.888705 0.989524 0.40972 0.953309 ] +3023,[2935],314,350,0,141,1,11,27,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.973499 0.475437 0.135632 0.369805 0.927945 0.842535 0.639207 0.324924 0.468659 0.793625 0.742182 0.985764 0.293359 0.997853 0.770533 ] +618,[565],63,99,0,156,1,5,14,[ 0.995809 0.187121 0.978541 0.174138 0.779632 0.578599 0.852754 0.540698 0.799621 0.587516 0.982733 0.648338 0.856259 0.767401 0.74891 0.860365 0.896396 0.495374 0.40972 0.953309 ] +842,[646],86,99,0,60,1,5,17,[ 0.995809 0.187121 0.978541 0.174138 0.779632 0.578599 0.852754 0.540698 0.799621 0.587516 0.982733 0.858428 0.838768 0.896412 0.104071 0.896322 0.312038 0.661591 0.55268 0.953309 ] +1007,[987],104,107,0,3,1,5,20,[ 0.995809 0.562972 0.284687 0.0702805 0.575156 0.578599 0.852754 0.533489 0.920642 0.25833 0.0922876 0.648338 0.856259 0.767401 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +1064,[929],111,142,0,115,1,19,18,[ 0.995809 0.187121 0.941875 0.229312 0.955627 0.973499 0.242718 0.962165 0.473005 0.25833 0.0922876 0.648338 0.856259 0.767401 0.74891 0.860365 0.896396 0.495374 0.40972 0.953309 ] +987,[870],102,109,0,13,1,5,19,[ 0.995809 0.187121 0.978541 0.174138 0.779632 0.578599 0.852754 0.533489 0.920642 0.25833 0.0922876 0.648338 0.856259 0.767401 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +1237,[1064],129,134,0,11,1,19,19,[ 0.995809 0.187121 0.941875 0.229312 0.955627 0.973499 0.242718 0.962165 0.473005 0.25833 0.0922876 0.648338 0.856259 0.767401 0.440932 0.697277 0.888705 0.989524 0.40972 0.953309 ] +1042,[1019],109,112,0,4,1,5,22,[ 0.108041 0.562972 0.284687 0.0702805 0.575156 0.578599 0.852754 0.533489 0.975623 0.00958576 0.0605428 0.357139 0.856259 0.767401 0.440932 0.896322 0.312038 0.884998 0.691646 0.732557 ] +1135,[1122],118,129,0,46,1,11,17,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.973499 0.475437 0.135632 0.369805 0.927945 0.842535 0.639207 0.324924 0.468659 0.793625 0.742182 0.985764 0.293359 0.997853 0.770533 ] +929,[720],95,116,0,80,1,19,17,[ 0.995809 0.187121 0.941875 0.229312 0.955627 0.973499 0.242718 0.962165 0.473005 0.25833 0.0922876 0.648338 0.856259 0.767401 0.440932 0.697277 0.888705 0.989524 0.40972 0.953309 ] +877,[772],89,122,0,138,2,14,15,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.973499 0.242718 0.876586 0.423019 0.587516 0.982733 0.858428 0.838768 0.468659 0.793625 0.742182 0.985764 0.293359 0.997853 0.770533 ] +4332,[4316],457,459,0,5,1,7,49,[ 0.995809 0.187121 0.978541 0.0546537 0.883412 0.0949958 0.242718 0.962165 0.473005 0.25833 0.0922876 0.648338 0.856259 0.767401 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +1122,[877],117,120,0,4,1,11,16,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.973499 0.475437 0.135632 0.369805 0.54765 0.982733 0.858428 0.838768 0.468659 0.793625 0.742182 0.985764 0.293359 0.997853 0.770533 ] +3734,[3689],391,424,0,169,1,5,40,[ 0.995809 0.187121 0.978541 0.174138 0.779632 0.578599 0.852754 0.540698 0.799621 0.587516 0.982733 0.648338 0.856259 0.767401 0.74891 0.860365 0.896396 0.495374 0.40972 0.953309 ] +2150,[1905],222,246,0,74,1,5,27,[ 0.995809 0.187121 0.978541 0.174138 0.779632 0.578599 0.852754 0.540698 0.234196 0.545666 0.488427 0.363967 0.838768 0.896412 0.104071 0.697277 0.888705 0.989524 0.40972 0.953309 ] +1906,[1486],198,204,0,13,1,11,20,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.548185 0.785694 0.498945 0.147207 0.927945 0.842535 0.639207 0.324924 0.468659 0.793625 0.742182 0.985764 0.293359 0.997853 0.770533 ] +870,[842],88,127,0,172,1,5,18,[ 0.995809 0.187121 0.978541 0.174138 0.779632 0.578599 0.852754 0.540698 0.799621 0.587516 0.982733 0.648338 0.856259 0.767401 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +1272,[1237],132,142,0,27,1,19,20,[ 0.995809 0.187121 0.941875 0.229312 0.955627 0.973499 0.242718 0.962165 0.473005 0.25833 0.579728 0.931965 0.295311 0.344145 0.440932 0.697277 0.888705 0.989524 0.40972 0.953309 ] +1151,[1073],121,144,0,73,1,5,24,[ 0.995809 0.187121 0.978541 0.174138 0.779632 0.578599 0.852754 0.533489 0.975623 0.00958576 0.0605428 0.357139 0.856259 0.767401 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +1381,[1342],143,172,0,76,1,19,22,[ 0.995809 0.187121 0.941875 0.229312 0.955627 0.973499 0.242718 0.962165 0.473005 0.25833 0.579728 0.931965 0.295311 0.633164 0.46977 0.333701 0.102967 0.661591 0.55268 0.953309 ] +1960,[1906],202,216,0,40,1,11,21,[ 0.357903 0.966937 0.946456 0.245193 0.955627 0.548185 0.785694 0.498945 0.147207 0.927945 0.842535 0.639207 0.324924 0.468659 0.793625 0.742182 0.985764 0.706301 0.23036 0.130208 ] +1567,[1381],166,182,0,37,1,19,23,[ 0.995809 0.187121 0.941875 0.229312 0.955627 0.973499 0.242718 0.962165 0.473005 0.25833 0.579728 0.931965 0.295311 0.344145 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +662,[642],67,74,0,15,1,19,15,[ 0.0799833 0.100866 0.735495 0.245193 0.955627 0.973499 0.475437 0.411102 0.473947 0.889831 0.0922876 0.648338 0.856259 0.767401 0.440932 0.697277 0.888705 0.989524 0.40972 0.953309 ] +1677,[1624],176,197,0,54,1,3,19,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.973499 0.242718 0.962165 0.473005 0.25833 0.0922876 0.648338 0.856259 0.102744 0.315735 0.742182 0.985764 0.293359 0.997853 0.770533 ] +3702,[3481],386,390,0,9,1,3,26,[ 0.357903 0.966937 0.946456 0.245193 0.955627 0.548185 0.365416 0.533489 0.975623 0.00958576 0.0662877 0.831627 0.363537 0.0880566 0.678145 0.815135 0.985764 0.706301 0.23036 0.130208 ] +3190,[3174],332,345,0,30,1,15,40,[ 0.995809 0.187121 0.978541 0.0546537 0.883412 0.0949958 0.242718 0.876586 0.423019 0.587516 0.982733 0.648338 0.856259 0.767401 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +1624,[1603],172,177,0,18,1,3,18,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.973499 0.242718 0.962165 0.473005 0.25833 0.0922876 0.858428 0.838768 0.468659 0.793625 0.742182 0.985764 0.293359 0.997853 0.770533 ] +1019,[1007],105,116,0,27,1,5,21,[ 0.995809 0.562972 0.284687 0.0702805 0.575156 0.578599 0.852754 0.533489 0.975623 0.00958576 0.0605428 0.357139 0.856259 0.767401 0.440932 0.896322 0.312038 0.661591 0.55268 0.953309 ] +1486,[1179],156,200,0,119,1,11,19,[ 0.00782676 0.966937 0.946456 0.245193 0.955627 0.548185 0.785694 0.498945 0.147207 0.927945 0.842535 0.639207 0.324924 0.896412 0.0801959 0.860365 0.319087 0.293359 0.997853 0.770533 ] +3518,[3445],367,389,0,79,1,4,45,[ 0.995809 0.562972 0.284687 0.830449 0.269955 0.403992 0.785694 0.649344 0.548345 0.889831 0.0922876 0.648338 0.856259 0.767401 0.440932 0.896322 0.775705 0.824472 0.415025 0.333746 ] +112,[48],13,16,0,5,1,5,4,[ 0.995809 0.187121 0.941875 0.703895 0.70148 0.370888 0.15659 0.962165 0.473005 0.25833 0.579728 0.168103 0.191729 0.422191 0.741723 0.618092 0.590382 0.989524 0.40972 0.953309 ] +113,[99],13,15,0,3,1,19,7,[ 0.258271 0.222559 0.298434 0.229312 0.955627 0.973499 0.242718 0.962165 0.473005 0.25833 0.0922876 0.648338 0.856259 0.102744 0.46977 0.618092 0.590382 0.989524 0.682412 0.720599 ] diff --git a/tests/Evolve/assets/nk_tournamentselection.csv b/tests/Evolve/assets/nk_tournamentselection.csv new file mode 100644 index 0000000000..ab658e5ccb --- /dev/null +++ b/tests/Evolve/assets/nk_tournamentselection.csv @@ -0,0 +1,18 @@ +id,ancestor_list,origin_time,destruction_time,num_orgs,tot_orgs,num_offspring,total_offspring,depth,phenotype +47645,[250],5000,inf,1,1,0,0,8,[ 0.897281 0.627867 0.842173 0.953767 0.615421 0.849175 0.795495 0.655207 0.630174 0.939279 0.457317 0.102534 0.960229 0.780958 0.248017 0.843595 0.791117 0.595291 0.68697 0.513536 ] +47644,[250],5000,inf,1,1,0,0,8,[ 0.897281 0.627867 0.842173 0.953767 0.615421 0.849175 0.795495 0.655207 0.630174 0.939279 0.457317 0.593252 0.39306 0.326643 0.875924 0.843595 0.198093 0.382351 0.368093 0.459045 ] +47643,[250],5000,inf,1,1,0,0,8,[ 0.295119 0.978285 0.842173 0.953767 0.615421 0.849175 0.795495 0.655207 0.630174 0.939279 0.457317 0.593252 0.39306 0.326643 0.875924 0.843595 0.791117 0.595291 0.339053 0.453858 ] +47642,[250],5000,inf,1,1,0,0,8,[ 0.897281 0.627867 0.842173 0.953767 0.615421 0.849175 0.795495 0.655207 0.630174 0.939279 0.457317 0.102534 0.960229 0.780958 0.248017 0.843595 0.791117 0.595291 0.68697 0.513536 ] +47641,[250],5000,inf,1,1,0,0,8,[ 0.897281 0.142281 0.980493 0.0445365 0.454894 0.849175 0.795495 0.655207 0.630174 0.939279 0.457317 0.593252 0.39306 0.326643 0.875924 0.843595 0.791117 0.595291 0.68697 0.513536 ] +47640,[250],5000,inf,1,1,0,0,8,[ 0.617043 0.542619 0.601551 0.953767 0.615421 0.849175 0.795495 0.655207 0.630174 0.939279 0.457317 0.593252 0.39306 0.326643 0.875924 0.843595 0.791117 0.595291 0.68697 0.622672 ] +47639,[250],5000,inf,1,1,0,0,8,[ 0.897281 0.627867 0.842173 0.879828 0.737197 0.704924 0.503842 0.655207 0.630174 0.939279 0.457317 0.593252 0.39306 0.326643 0.875924 0.843595 0.791117 0.595291 0.68697 0.513536 ] +47626,[250],4999,inf,1,2,0,0,8,[ 0.897281 0.627867 0.842173 0.953767 0.615421 0.849175 0.795495 0.655207 0.630174 0.939279 0.311709 0.840836 0.133292 0.100105 0.875924 0.843595 0.791117 0.595291 0.68697 0.513536 ] +47633,[250],4999,inf,1,2,0,0,8,[ 0.897281 0.627867 0.842173 0.953767 0.615421 0.849175 0.795495 0.655207 0.630174 0.939279 0.457317 0.593252 0.857469 0.267302 0.212507 0.14281 0.791117 0.595291 0.68697 0.513536 ] +250,[201],25,inf,91,442290,9,9,7,[ 0.897281 0.627867 0.842173 0.953767 0.615421 0.849175 0.795495 0.655207 0.630174 0.939279 0.457317 0.593252 0.39306 0.326643 0.875924 0.843595 0.791117 0.595291 0.68697 0.513536 ] +201,[158],20,36,0,260,1,10,6,[ 0.617043 0.542619 0.601551 0.953767 0.615421 0.849175 0.795495 0.655207 0.630174 0.939279 0.457317 0.593252 0.39306 0.326643 0.875924 0.843595 0.791117 0.595291 0.68697 0.622672 ] +158,[80],16,33,0,405,1,10,5,[ 0.617043 0.542619 0.601551 0.953767 0.615421 0.849175 0.795495 0.655207 0.630174 0.939279 0.457317 0.102534 0.960229 0.780958 0.248017 0.843595 0.791117 0.595291 0.68697 0.622672 ] +80,[55],7,24,0,571,1,10,4,[ 0.617043 0.542619 0.601551 0.953767 0.615421 0.849175 0.795495 0.655207 0.630174 0.939279 0.311709 0.535458 0.137209 0.647296 0.248017 0.843595 0.791117 0.595291 0.68697 0.622672 ] +55,[54],5,15,0,166,1,10,3,[ 0.617043 0.542619 0.601551 0.953767 0.615421 0.849175 0.795495 0.655207 0.630174 0.939279 0.311709 0.535458 0.137209 0.647296 0.248017 0.843595 0.198093 0.382351 0.368093 0.943928 ] +9,[1],1,12,0,210,1,10,1,[ 0.617043 0.542619 0.464605 0.76383 0.238735 0.321614 0.795495 0.655207 0.630174 0.939279 0.311709 0.535458 0.137209 0.647296 0.248017 0.727699 0.762139 0.8074 0.0995118 0.943928 ] +54,[9],4,6,0,2,1,10,2,[ 0.617043 0.542619 0.601551 0.953767 0.615421 0.849175 0.795495 0.655207 0.630174 0.939279 0.311709 0.535458 0.137209 0.647296 0.248017 0.727699 0.762139 0.8074 0.0995118 0.943928 ] +1,[NONE],0,6,0,314,1,10,0,[ 0.617043 0.542619 0.464605 0.76383 0.238735 0.321614 0.15161 0.00333426 0.144995 0.913818 0.311709 0.535458 0.137209 0.647296 0.248017 0.727699 0.762139 0.8074 0.0995118 0.943928 ] diff --git a/tests/base/Makefile b/tests/base/Makefile index 85b408be6d..3637f371bf 100644 --- a/tests/base/Makefile +++ b/tests/base/Makefile @@ -1,4 +1,4 @@ -TEST_NAMES = error always_assert_warning always_assert array assert assert_warning errors map MapProxy notify optional Ptr unordered_map vector +TEST_NAMES = error always_assert_warning always_assert array assert assert_warning errors map MapProxy notify optional optional_throw Ptr unordered_map vector # -O3 -Wl,--stack,8388608 -ftrack-macro-expansion=0 FLAGS = -std=c++20 -g -pthread -Wall -Wno-unused-function -Wno-unused-private-field -I../../include/ -I../../ -I../../third-party/cereal/include/ -DCATCH_CONFIG_MAIN diff --git a/tests/base/optional_throw.cpp b/tests/base/optional_throw.cpp new file mode 100644 index 0000000000..dae4434410 --- /dev/null +++ b/tests/base/optional_throw.cpp @@ -0,0 +1,29 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2024 +*/ +/** + * @file + * @brief TODO. + */ + +#include "third-party/Catch/single_include/catch2/catch.hpp" + +#undef NDEBUG +#define TDEBUG 1 +#include "emp/base/optional_throw.hpp" + +TEST_CASE("Optional throw" "[asserts]") { + + emp_optional_throw(false); + REQUIRE(emp::assert_last_fail); + + #define EMP_OPTIONAL_THROW_ON 1 + try { + emp_optional_throw(false); + } + catch (std::runtime_error & error) { + REQUIRE(std::string(error.what()) == "Internal Error (in always_assert.cpp line 37): false,\nfalse: [0]\n"); + } +} diff --git a/third-party/package.json b/third-party/package.json index cde35ee0f8..b61443a207 100644 --- a/third-party/package.json +++ b/third-party/package.json @@ -3,22 +3,24 @@ "version": "1.0.0", "description": "Dev dependencies for Empirical", "main": "index.js", - "dependencies": {}, "devDependencies": { "chai": "4.2.0", - "jsdom": "16.4.0", "jquery": "3.5.1", - "karma": "5.0.9", + "jsdom": "^16.7.0", + "karma": "^6.4.1", "karma-chai": "0.1.0", "karma-chrome-launcher": "3.1.0", "karma-firefox-launcher": "1.3.0", "karma-mocha": "2.0.1", "karma-spec-reporter": "0.0.32", - "mocha": "7.2.0" + "mocha": "^10.2.0" }, "scripts": { "test": "cd ../tests && make test-web" }, "author": "Devosoft", - "license": "MIT" + "license": "MIT", + "dependencies": { + "package.json": "^0.0.0" + } }