Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 12 additions & 19 deletions core/species.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8727,6 +8727,7 @@ void Species::__CreateSubpopulationsFromTabulation(std::unordered_map<slim_objec
// This could be done with a hash table, but I imagine that would be slower until the number of individuals becomes very large
// Also, I'm a bit nervous about putting a large number of consecutive integers into a hash table, re: edge-case performance
std::vector<slim_pedigreeid_t> pedigree_id_check;
std::vector<slim_haplosomeid_t> haplosome_id_check;

gSLiM_next_pedigree_id = 0;

Expand Down Expand Up @@ -8806,12 +8807,16 @@ void Species::__CreateSubpopulationsFromTabulation(std::unordered_map<slim_objec
individual->spatial_z_ = subpop_info.spatial_z_[tabulation_index];

p_nodeToHaplosomeMap.emplace(node_id_0, individual->haplosomes_[first_haplosome_index]);
individual->haplosomes_[first_haplosome_index]->haplosome_id_ = pedigree_id * 2;
slim_haplosomeid_t haplosome_id = pedigree_id * 2;
individual->haplosomes_[first_haplosome_index]->haplosome_id_ = haplosome_id;
haplosome_id_check.emplace_back(haplosome_id); // we will test for collisions below

if (last_haplosome_index != first_haplosome_index)
{
p_nodeToHaplosomeMap.emplace(node_id_1, individual->haplosomes_[last_haplosome_index]);
individual->haplosomes_[last_haplosome_index]->haplosome_id_ = pedigree_id * 2 + 1;
haplosome_id = pedigree_id * 2 + 1;
individual->haplosomes_[last_haplosome_index]->haplosome_id_ = haplosome_id;
haplosome_id_check.emplace_back(haplosome_id); // we will test for collisions below
}

// check the referenced nodes; right now this is not essential for re-creating the saved state, but is just a crosscheck
Expand Down Expand Up @@ -9814,13 +9819,12 @@ void Species::__CheckNodePedigreeIDs(__attribute__((unused)) EidosInterpreter *p
// could be nodes in the node table with haplosome pedigree IDs greater than those in use by individuals, in nonWF models.
// See https://github.com/MesserLab/SLiM/pull/420 for an example model that does this very easily.

// Also, check for duplicate pedigree IDs, just in case. __CreateSubpopulationsFromTabulation() does this for individual
// pedigree IDs; we do it for node pedigree IDs. I decided to use a vector with std::sort() to check even though it is
// O(n log n), rather than a hash table for O(n), because I'm nervous about hitting a bad edge case with the hash table
// due to the nature of the values being inserted. Shouldn't be a big deal in the grand scheme of things.
// Previously, we checked for duplicate haplosome IDs here as well, just in case.
// __CreateSubpopulationsFromTabulation() does this in living individuals
// already; however, it was found to be overly restrictive, in situations
// involving merging of parallel simulations; see https://github.com/MesserLab/SLiM/issues/538
tsk_node_table_t &node_table = tables.nodes;
tsk_size_t node_count = node_table.num_rows;
std::vector<slim_haplosomeid_t> haplosome_id_check;

for (tsk_size_t j = 0; (size_t)j < node_count; j++)
{
Expand All @@ -9833,11 +9837,7 @@ void Species::__CheckNodePedigreeIDs(__attribute__((unused)) EidosInterpreter *p
{
// get the metadata record and check the haplosome pedigree ID
HaplosomeMetadataRec *metadata_rec = (HaplosomeMetadataRec *)(node_table.metadata + offset1);
slim_haplosomeid_t haplosome_id = metadata_rec->haplosome_id_;

haplosome_id_check.emplace_back(haplosome_id); // we will test for collisions below

slim_pedigreeid_t pedigree_id = haplosome_id / 2; // rounds down to integer
slim_pedigreeid_t pedigree_id = metadata_rec->haplosome_id_ / 2; // rounds down to integer

if (pedigree_id >= gSLiM_next_pedigree_id)
{
Expand All @@ -9854,13 +9854,6 @@ void Species::__CheckNodePedigreeIDs(__attribute__((unused)) EidosInterpreter *p
}
}
}

// Check for haplosome pedigree ID collisions by sorting and looking for duplicates
std::sort(haplosome_id_check.begin(), haplosome_id_check.end());
const auto duplicate = std::adjacent_find(haplosome_id_check.begin(), haplosome_id_check.end());

if (duplicate != haplosome_id_check.end())
EIDOS_TERMINATION << "ERROR (Species::__CheckNodePedigreeIDs): the haplosome pedigree ID value " << *duplicate << " was used more than once; haplosome pedigree IDs must be unique." << EidosTerminate();
}

void Species::_ReadAncestralSequence(const char *p_file, Chromosome &p_chromosome)
Expand Down
Loading