Skip to content

Commit 298308b

Browse files
authored
Merge pull request #554 from petrelharp/no_dup_id_check
Don't check for duplicate haplosome IDs
2 parents 73b4970 + 7d0a5f5 commit 298308b

1 file changed

Lines changed: 12 additions & 19 deletions

File tree

core/species.cpp

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8727,6 +8727,7 @@ void Species::__CreateSubpopulationsFromTabulation(std::unordered_map<slim_objec
87278727
// This could be done with a hash table, but I imagine that would be slower until the number of individuals becomes very large
87288728
// Also, I'm a bit nervous about putting a large number of consecutive integers into a hash table, re: edge-case performance
87298729
std::vector<slim_pedigreeid_t> pedigree_id_check;
8730+
std::vector<slim_haplosomeid_t> haplosome_id_check;
87308731

87318732
gSLiM_next_pedigree_id = 0;
87328733

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

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

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

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

9817-
// Also, check for duplicate pedigree IDs, just in case. __CreateSubpopulationsFromTabulation() does this for individual
9818-
// pedigree IDs; we do it for node pedigree IDs. I decided to use a vector with std::sort() to check even though it is
9819-
// 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
9820-
// due to the nature of the values being inserted. Shouldn't be a big deal in the grand scheme of things.
9822+
// Previously, we checked for duplicate haplosome IDs here as well, just in case.
9823+
// __CreateSubpopulationsFromTabulation() does this in living individuals
9824+
// already; however, it was found to be overly restrictive, in situations
9825+
// involving merging of parallel simulations; see https://github.com/MesserLab/SLiM/issues/538
98219826
tsk_node_table_t &node_table = tables.nodes;
98229827
tsk_size_t node_count = node_table.num_rows;
9823-
std::vector<slim_haplosomeid_t> haplosome_id_check;
98249828

98259829
for (tsk_size_t j = 0; (size_t)j < node_count; j++)
98269830
{
@@ -9833,11 +9837,7 @@ void Species::__CheckNodePedigreeIDs(__attribute__((unused)) EidosInterpreter *p
98339837
{
98349838
// get the metadata record and check the haplosome pedigree ID
98359839
HaplosomeMetadataRec *metadata_rec = (HaplosomeMetadataRec *)(node_table.metadata + offset1);
9836-
slim_haplosomeid_t haplosome_id = metadata_rec->haplosome_id_;
9837-
9838-
haplosome_id_check.emplace_back(haplosome_id); // we will test for collisions below
9839-
9840-
slim_pedigreeid_t pedigree_id = haplosome_id / 2; // rounds down to integer
9840+
slim_pedigreeid_t pedigree_id = metadata_rec->haplosome_id_ / 2; // rounds down to integer
98419841

98429842
if (pedigree_id >= gSLiM_next_pedigree_id)
98439843
{
@@ -9854,13 +9854,6 @@ void Species::__CheckNodePedigreeIDs(__attribute__((unused)) EidosInterpreter *p
98549854
}
98559855
}
98569856
}
9857-
9858-
// Check for haplosome pedigree ID collisions by sorting and looking for duplicates
9859-
std::sort(haplosome_id_check.begin(), haplosome_id_check.end());
9860-
const auto duplicate = std::adjacent_find(haplosome_id_check.begin(), haplosome_id_check.end());
9861-
9862-
if (duplicate != haplosome_id_check.end())
9863-
EIDOS_TERMINATION << "ERROR (Species::__CheckNodePedigreeIDs): the haplosome pedigree ID value " << *duplicate << " was used more than once; haplosome pedigree IDs must be unique." << EidosTerminate();
98649857
}
98659858

98669859
void Species::_ReadAncestralSequence(const char *p_file, Chromosome &p_chromosome)

0 commit comments

Comments
 (0)