diff --git a/QtSLiM/QtSLiMWindow.cpp b/QtSLiM/QtSLiMWindow.cpp
index 88023788..5d4d16c4 100644
--- a/QtSLiM/QtSLiMWindow.cpp
+++ b/QtSLiM/QtSLiMWindow.cpp
@@ -3974,78 +3974,92 @@ void QtSLiMWindow::displayProfileResults(void)
continue;
}
- int64_t power_tallies[20]; // we only go up to 1024 mutruns right now, but this gives us some headroom
- int64_t power_tallies_total = static_cast(focal_species->profile_mutcount_history_.size());
-
- for (int power = 0; power < 20; ++power)
- power_tallies[power] = 0;
-
- for (int32_t count : focal_species->profile_mutcount_history_)
- {
- int power = static_cast(round(log2(count)));
-
- power_tallies[power]++;
- }
-
- for (int power = 0; power < 20; ++power)
- {
- if (power_tallies[power] > 0)
- {
- tc.insertText(QString("%1%").arg((power_tallies[power] / static_cast(power_tallies_total)) * 100.0, 6, 'f', 2), menlo11_d);
- tc.insertText(QString(" of ticks : %1 mutation runs per haplosome\n").arg(static_cast(round(pow(2.0, power)))), optima13_d);
- }
- }
-
-
- int64_t regime_tallies[3];
- int64_t regime_tallies_total = static_cast(focal_species->profile_nonneutral_regime_history_.size());
-
- for (int regime = 0; regime < 3; ++regime)
- regime_tallies[regime] = 0;
-
- for (int32_t regime : focal_species->profile_nonneutral_regime_history_)
- if ((regime >= 1) && (regime <= 3))
- regime_tallies[regime - 1]++;
- else
- regime_tallies_total--;
-
- tc.insertText(" \n", optima13_d);
-
- for (int regime = 0; regime < 3; ++regime)
- {
- tc.insertText(QString("%1%").arg((regime_tallies[regime] / static_cast(regime_tallies_total)) * 100.0, 6, 'f', 2), menlo11_d);
- tc.insertText(QString(" of ticks : regime %1 (%2)\n").arg(regime + 1).arg(regime == 0 ? "no mutationEffect() callbacks" : (regime == 1 ? "constant neutral mutationEffect() callbacks only" : "unpredictable mutationEffect() callbacks present")), optima13_d);
- }
-
-
- tc.insertText(" \n", optima13_d);
-
- tc.insertText(QString("%1").arg(focal_species->profile_mutation_total_usage_), menlo11_d);
- tc.insertText(" mutations referenced, summed across all ticks\n", optima13_d);
-
- tc.insertText(QString("%1").arg(focal_species->profile_nonneutral_mutation_total_), menlo11_d);
- tc.insertText(" mutations considered potentially nonneutral\n", optima13_d);
-
- tc.insertText(QString("%1%").arg(((focal_species->profile_mutation_total_usage_ - focal_species->profile_nonneutral_mutation_total_) / static_cast(focal_species->profile_mutation_total_usage_)) * 100.0, 0, 'f', 2), menlo11_d);
- tc.insertText(" of mutations excluded from fitness calculations\n", optima13_d);
+ {
+ int64_t regime_tallies[3];
+ int64_t regime_tallies_total = static_cast(focal_species->profile_nonneutral_regime_history_.size());
+
+ for (int regime = 0; regime < 3; ++regime)
+ regime_tallies[regime] = 0;
+
+ for (int32_t regime : focal_species->profile_nonneutral_regime_history_)
+ if ((regime >= 1) && (regime <= 3))
+ regime_tallies[regime - 1]++;
+ else
+ regime_tallies_total--;
+
+ for (int regime = 0; regime < 3; ++regime)
+ {
+ tc.insertText(QString("%1%").arg((regime_tallies[regime] / static_cast(regime_tallies_total)) * 100.0, 6, 'f', 2), menlo11_d);
+ tc.insertText(QString(" of ticks : regime %1 (%2)\n").arg(regime + 1).arg(regime == 0 ? "no mutationEffect() callbacks" : (regime == 1 ? "constant neutral mutationEffect() callbacks only" : "unpredictable mutationEffect() callbacks present")), optima13_d);
+ }
+
+ tc.insertText(" \n", optima8_d);
+ }
- tc.insertText(QString("%1").arg(focal_species->profile_max_mutation_index_), menlo11_d);
+ tc.insertText(QString("%1").arg(focal_species->profile_max_mutation_index_), menlo11_d);
tc.insertText(" maximum simultaneous mutations\n", optima13_d);
+
+
+ const std::vector &chromosomes = focal_species->Chromosomes();
-
- tc.insertText(" \n", optima13_d);
-
- tc.insertText(QString("%1").arg(focal_species->profile_mutrun_total_usage_), menlo11_d);
- tc.insertText(" mutation runs referenced, summed across all ticks\n", optima13_d);
-
- tc.insertText(QString("%1").arg(focal_species->profile_unique_mutrun_total_), menlo11_d);
- tc.insertText(" unique mutation runs maintained among those\n", optima13_d);
-
- tc.insertText(QString("%1%").arg((focal_species->profile_mutrun_nonneutral_recache_total_ / static_cast(focal_species->profile_unique_mutrun_total_)) * 100.0, 6, 'f', 2), menlo11_d);
- tc.insertText(" of mutation run nonneutral caches rebuilt per tick\n", optima13_d);
-
- tc.insertText(QString("%1%").arg(((focal_species->profile_mutrun_total_usage_ - focal_species->profile_unique_mutrun_total_) / static_cast(focal_species->profile_mutrun_total_usage_)) * 100.0, 6, 'f', 2), menlo11_d);
- tc.insertText(" of mutation runs shared among haplosomes", optima13_d);
+ for (Chromosome *focal_chromosome : chromosomes)
+ {
+ tc.insertText(" \n", optima13_d);
+ tc.insertText("Chromosome ", optima13i_d);
+ tc.insertText(QString::fromStdString(focal_chromosome->Symbol()), optima13i_d);
+ tc.insertText(":\n", optima13i_d);
+ tc.insertText(" \n", optima3_d);
+
+ {
+ int64_t power_tallies[20]; // we only go up to 1024 mutruns right now, but this gives us some headroom
+ int64_t power_tallies_total = static_cast(focal_chromosome->profile_mutcount_history_.size());
+
+ for (int power = 0; power < 20; ++power)
+ power_tallies[power] = 0;
+
+ for (int32_t count : focal_chromosome->profile_mutcount_history_)
+ {
+ int power = static_cast(round(log2(count)));
+
+ power_tallies[power]++;
+ }
+
+ for (int power = 0; power < 20; ++power)
+ {
+ if (power_tallies[power] > 0)
+ {
+ tc.insertText(QString("%1%").arg((power_tallies[power] / static_cast(power_tallies_total)) * 100.0, 6, 'f', 2), menlo11_d);
+ tc.insertText(QString(" of ticks : %1 mutation runs per haplosome\n").arg(static_cast(round(pow(2.0, power)))), optima13_d);
+ }
+ }
+ }
+
+ tc.insertText(" \n", optima8_d);
+
+ tc.insertText(QString("%1").arg(focal_chromosome->profile_mutation_total_usage_), menlo11_d);
+ tc.insertText(" mutations referenced, summed across all ticks\n", optima13_d);
+
+ tc.insertText(QString("%1").arg(focal_chromosome->profile_nonneutral_mutation_total_), menlo11_d);
+ tc.insertText(" mutations considered potentially nonneutral\n", optima13_d);
+
+ tc.insertText(QString("%1%").arg(((focal_chromosome->profile_mutation_total_usage_ - focal_chromosome->profile_nonneutral_mutation_total_) / static_cast(focal_chromosome->profile_mutation_total_usage_)) * 100.0, 0, 'f', 2), menlo11_d);
+ tc.insertText(" of mutations excluded from fitness calculations\n", optima13_d);
+
+
+ tc.insertText(" \n", optima8_d);
+
+ tc.insertText(QString("%1").arg(focal_chromosome->profile_mutrun_total_usage_), menlo11_d);
+ tc.insertText(" mutation runs referenced, summed across all ticks\n", optima13_d);
+
+ tc.insertText(QString("%1").arg(focal_chromosome->profile_unique_mutrun_total_), menlo11_d);
+ tc.insertText(" unique mutation runs maintained among those\n", optima13_d);
+
+ tc.insertText(QString("%1%").arg((focal_chromosome->profile_mutrun_nonneutral_recache_total_ / static_cast(focal_chromosome->profile_unique_mutrun_total_)) * 100.0, 6, 'f', 2), menlo11_d);
+ tc.insertText(" of mutation run nonneutral caches rebuilt per tick\n", optima13_d);
+
+ tc.insertText(QString("%1%").arg(((focal_chromosome->profile_mutrun_total_usage_ - focal_chromosome->profile_unique_mutrun_total_) / static_cast(focal_chromosome->profile_mutrun_total_usage_)) * 100.0, 6, 'f', 2), menlo11_d);
+ tc.insertText(" of mutation runs shared among haplosomes\n", optima13_d);
+ }
}
#endif
@@ -4062,7 +4076,6 @@ void QtSLiMWindow::displayProfileResults(void)
double average_total = (mem_tot_C.totalMemoryUsage + mem_tot_S.totalMemoryUsage) / ddiv;
double final_total = mem_last_C.totalMemoryUsage + mem_last_S.totalMemoryUsage;
- tc.insertText(" \n", menlo11_d);
tc.insertText(" \n", optima13_d);
tc.insertText("SLiM memory usage (average / final tick)\n", optima14b_d);
tc.insertText(" \n", optima3_d);
diff --git a/SLiMgui/SLiMWindowController.mm b/SLiMgui/SLiMWindowController.mm
index d2b99ef3..4547d0ec 100644
--- a/SLiMgui/SLiMWindowController.mm
+++ b/SLiMgui/SLiMWindowController.mm
@@ -2059,78 +2059,92 @@ - (void)displayProfileResults
continue;
}
- int64_t power_tallies[20]; // we only go up to 1024 mutruns right now, but this gives us some headroom
- int64_t power_tallies_total = (int)focal_species->profile_mutcount_history_.size();
-
- for (int power = 0; power < 20; ++power)
- power_tallies[power] = 0;
-
- for (int32_t count : focal_species->profile_mutcount_history_)
{
- int power = (int)round(log2(count));
+ int64_t regime_tallies[3];
+ int64_t regime_tallies_total = (int)focal_species->profile_nonneutral_regime_history_.size();
- power_tallies[power]++;
- }
-
- for (int power = 0; power < 20; ++power)
- {
- if (power_tallies[power] > 0)
+ for (int regime = 0; regime < 3; ++regime)
+ regime_tallies[regime] = 0;
+
+ for (int32_t regime : focal_species->profile_nonneutral_regime_history_)
+ if ((regime >= 1) && (regime <= 3))
+ regime_tallies[regime - 1]++;
+ else
+ regime_tallies_total--;
+
+ for (int regime = 0; regime < 3; ++regime)
{
- [content eidosAppendString:[NSString stringWithFormat:@"%6.2f%%", (power_tallies[power] / (double)power_tallies_total) * 100.0] attributes:menlo11_d];
- [content eidosAppendString:[NSString stringWithFormat:@" of ticks : %d mutation runs per haplosome\n", (int)(round(pow(2.0, power)))] attributes:optima13_d];
+ [content eidosAppendString:[NSString stringWithFormat:@"%6.2f%%", (regime_tallies[regime] / (double)regime_tallies_total) * 100.0] attributes:menlo11_d];
+ [content eidosAppendString:[NSString stringWithFormat:@" of ticks : regime %d (%@)\n", regime + 1, (regime == 0 ? @"no mutationEffect() callbacks" : (regime == 1 ? @"constant neutral mutationEffect() callbacks only" : @"unpredictable mutationEffect() callbacks present"))] attributes:optima13_d];
}
+
+ [content eidosAppendString:@"\n" attributes:optima8_d];
}
-
- int64_t regime_tallies[3];
- int64_t regime_tallies_total = (int)focal_species->profile_nonneutral_regime_history_.size();
-
- for (int regime = 0; regime < 3; ++regime)
- regime_tallies[regime] = 0;
-
- for (int32_t regime : focal_species->profile_nonneutral_regime_history_)
- if ((regime >= 1) && (regime <= 3))
- regime_tallies[regime - 1]++;
- else
- regime_tallies_total--;
-
- [content eidosAppendString:@"\n" attributes:optima13_d];
-
- for (int regime = 0; regime < 3; ++regime)
- {
- [content eidosAppendString:[NSString stringWithFormat:@"%6.2f%%", (regime_tallies[regime] / (double)regime_tallies_total) * 100.0] attributes:menlo11_d];
- [content eidosAppendString:[NSString stringWithFormat:@" of ticks : regime %d (%@)\n", regime + 1, (regime == 0 ? @"no mutationEffect() callbacks" : (regime == 1 ? @"constant neutral mutationEffect() callbacks only" : @"unpredictable mutationEffect() callbacks present"))] attributes:optima13_d];
- }
-
-
- [content eidosAppendString:@"\n" attributes:optima13_d];
-
- [content eidosAppendString:[NSString stringWithFormat:@"%lld", (long long int)focal_species->profile_mutation_total_usage_] attributes:menlo11_d];
- [content eidosAppendString:@" mutations referenced, summed across all ticks\n" attributes:optima13_d];
-
- [content eidosAppendString:[NSString stringWithFormat:@"%lld", (long long int)focal_species->profile_nonneutral_mutation_total_] attributes:menlo11_d];
- [content eidosAppendString:@" mutations considered potentially nonneutral\n" attributes:optima13_d];
-
- [content eidosAppendString:[NSString stringWithFormat:@"%0.2f%%", ((focal_species->profile_mutation_total_usage_ - focal_species->profile_nonneutral_mutation_total_) / (double)focal_species->profile_mutation_total_usage_) * 100.0] attributes:menlo11_d];
- [content eidosAppendString:@" of mutations excluded from fitness calculations\n" attributes:optima13_d];
-
[content eidosAppendString:[NSString stringWithFormat:@"%lld", (long long int)focal_species->profile_max_mutation_index_] attributes:menlo11_d];
[content eidosAppendString:@" maximum simultaneous mutations\n" attributes:optima13_d];
- [content eidosAppendString:@"\n" attributes:optima13_d];
-
- [content eidosAppendString:[NSString stringWithFormat:@"%lld", (long long int)focal_species->profile_mutrun_total_usage_] attributes:menlo11_d];
- [content eidosAppendString:@" mutation runs referenced, summed across all ticks\n" attributes:optima13_d];
-
- [content eidosAppendString:[NSString stringWithFormat:@"%lld", (long long int)focal_species->profile_unique_mutrun_total_] attributes:menlo11_d];
- [content eidosAppendString:@" unique mutation runs maintained among those\n" attributes:optima13_d];
-
- [content eidosAppendString:[NSString stringWithFormat:@"%6.2f%%", (focal_species->profile_mutrun_nonneutral_recache_total_ / (double)focal_species->profile_unique_mutrun_total_) * 100.0] attributes:menlo11_d];
- [content eidosAppendString:@" of mutation run nonneutral caches rebuilt per tick\n" attributes:optima13_d];
+ const std::vector &chromosomes = focal_species->Chromosomes();
- [content eidosAppendString:[NSString stringWithFormat:@"%6.2f%%", ((focal_species->profile_mutrun_total_usage_ - focal_species->profile_unique_mutrun_total_) / (double)focal_species->profile_mutrun_total_usage_) * 100.0] attributes:menlo11_d];
- [content eidosAppendString:@" of mutation runs shared among haplosomes" attributes:optima13_d];
+ for (Chromosome *focal_chromosome : chromosomes)
+ {
+ [content eidosAppendString:@"\n" attributes:optima13_d];
+ [content eidosAppendString:@"Chromosome " attributes:optima13i_d];
+ [content eidosAppendString:[NSString stringWithUTF8String:focal_chromosome->Symbol().c_str()] attributes:optima13i_d];
+ [content eidosAppendString:@":\n" attributes:optima13i_d];
+ [content eidosAppendString:@"\n" attributes:optima3_d];
+
+ {
+ int64_t power_tallies[20]; // we only go up to 1024 mutruns right now, but this gives us some headroom
+ int64_t power_tallies_total = (int)focal_chromosome->profile_mutcount_history_.size();
+
+ for (int power = 0; power < 20; ++power)
+ power_tallies[power] = 0;
+
+ for (int32_t count : focal_chromosome->profile_mutcount_history_)
+ {
+ int power = (int)round(log2(count));
+
+ power_tallies[power]++;
+ }
+
+ for (int power = 0; power < 20; ++power)
+ {
+ if (power_tallies[power] > 0)
+ {
+ [content eidosAppendString:[NSString stringWithFormat:@"%6.2f%%", (power_tallies[power] / (double)power_tallies_total) * 100.0] attributes:menlo11_d];
+ [content eidosAppendString:[NSString stringWithFormat:@" of ticks : %d mutation runs per haplosome\n", (int)(round(pow(2.0, power)))] attributes:optima13_d];
+ }
+ }
+ }
+
+ [content eidosAppendString:@"\n" attributes:optima8_d];
+
+ [content eidosAppendString:[NSString stringWithFormat:@"%lld", (long long int)focal_chromosome->profile_mutation_total_usage_] attributes:menlo11_d];
+ [content eidosAppendString:@" mutations referenced, summed across all ticks\n" attributes:optima13_d];
+
+ [content eidosAppendString:[NSString stringWithFormat:@"%lld", (long long int)focal_chromosome->profile_nonneutral_mutation_total_] attributes:menlo11_d];
+ [content eidosAppendString:@" mutations considered potentially nonneutral\n" attributes:optima13_d];
+
+ [content eidosAppendString:[NSString stringWithFormat:@"%0.2f%%", ((focal_chromosome->profile_mutation_total_usage_ - focal_chromosome->profile_nonneutral_mutation_total_) / (double)focal_chromosome->profile_mutation_total_usage_) * 100.0] attributes:menlo11_d];
+ [content eidosAppendString:@" of mutations excluded from fitness calculations\n" attributes:optima13_d];
+
+
+ [content eidosAppendString:@"\n" attributes:optima8_d];
+
+ [content eidosAppendString:[NSString stringWithFormat:@"%lld", (long long int)focal_chromosome->profile_mutrun_total_usage_] attributes:menlo11_d];
+ [content eidosAppendString:@" mutation runs referenced, summed across all ticks\n" attributes:optima13_d];
+
+ [content eidosAppendString:[NSString stringWithFormat:@"%lld", (long long int)focal_chromosome->profile_unique_mutrun_total_] attributes:menlo11_d];
+ [content eidosAppendString:@" unique mutation runs maintained among those\n" attributes:optima13_d];
+
+ [content eidosAppendString:[NSString stringWithFormat:@"%6.2f%%", (focal_chromosome->profile_mutrun_nonneutral_recache_total_ / (double)focal_chromosome->profile_unique_mutrun_total_) * 100.0] attributes:menlo11_d];
+ [content eidosAppendString:@" of mutation run nonneutral caches rebuilt per tick\n" attributes:optima13_d];
+
+ [content eidosAppendString:[NSString stringWithFormat:@"%6.2f%%", ((focal_chromosome->profile_mutrun_total_usage_ - focal_chromosome->profile_unique_mutrun_total_) / (double)focal_chromosome->profile_mutrun_total_usage_) * 100.0] attributes:menlo11_d];
+ [content eidosAppendString:@" of mutation runs shared among haplosomes\n" attributes:optima13_d];
+ }
}
#endif
@@ -2147,7 +2161,6 @@ - (void)displayProfileResults
double average_total = (mem_tot_C.totalMemoryUsage + mem_tot_S.totalMemoryUsage) / ddiv;
double final_total = mem_last_C.totalMemoryUsage + mem_last_S.totalMemoryUsage;
- [content eidosAppendString:@"\n" attributes:menlo11_d];
[content eidosAppendString:@"\n" attributes:optima13_d];
[content eidosAppendString:@"SLiM memory usage (average / final tick)\n" attributes:optima14b_d];
[content eidosAppendString:@"\n" attributes:optima3_d];
diff --git a/core/chromosome.h b/core/chromosome.h
index 0f382aba..0770d26e 100644
--- a/core/chromosome.h
+++ b/core/chromosome.h
@@ -267,6 +267,18 @@ class Chromosome : public EidosDictionaryRetained
// a user-defined tag value
slim_usertag_t tag_value_ = SLIM_TAG_UNSET_VALUE;
+ // PROFILING : Chromosome keeps track of some additional profile information that is per-chromosome
+#if (SLIMPROFILING == 1)
+#if SLIM_USE_NONNEUTRAL_CACHES
+ std::vector profile_mutcount_history_; // a record of the mutation run count used in each cycle
+ int64_t profile_mutation_total_usage_ = 0; // how many (non-unique) mutations were used by mutation runs, summed across cycles
+ int64_t profile_nonneutral_mutation_total_ = 0; // of profile_mutation_total_usage_, how many were deemed to be nonneutral
+ int64_t profile_mutrun_total_usage_ = 0; // how many (non-unique) mutruns were used by haplosomes, summed across cycles
+ int64_t profile_unique_mutrun_total_ = 0; // of profile_mutrun_total_usage_, how many unique mutruns existed, summed across cycles
+ int64_t profile_mutrun_nonneutral_recache_total_ = 0; // of profile_unique_mutrun_total_, how many mutruns regenerated their nonneutral cache
+#endif // SLIM_USE_NONNEUTRAL_CACHES
+#endif // (SLIMPROFILING == 1)
+
Chromosome(const Chromosome&) = delete; // no copying
Chromosome& operator=(const Chromosome&) = delete; // no copying
Chromosome(void) = delete; // no null constructor
diff --git a/core/community.cpp b/core/community.cpp
index 7d5ddd6c..8cbc0928 100644
--- a/core/community.cpp
+++ b/core/community.cpp
@@ -3299,14 +3299,18 @@ void Community::StartProfiling(void)
// zero out mutation run metrics that are collected by CollectMutationProfileInfo()
for (Species *focal_species : all_species_)
{
- focal_species->profile_mutcount_history_.clear();
focal_species->profile_nonneutral_regime_history_.clear();
- focal_species->profile_mutation_total_usage_ = 0;
- focal_species->profile_nonneutral_mutation_total_ = 0;
- focal_species->profile_mutrun_total_usage_ = 0;
- focal_species->profile_unique_mutrun_total_ = 0;
- focal_species->profile_mutrun_nonneutral_recache_total_ = 0;
focal_species->profile_max_mutation_index_ = 0;
+
+ for (Chromosome *focal_chromosome : focal_species->Chromosomes())
+ {
+ focal_chromosome->profile_mutcount_history_.clear();
+ focal_chromosome->profile_mutation_total_usage_ = 0;
+ focal_chromosome->profile_nonneutral_mutation_total_ = 0;
+ focal_chromosome->profile_mutrun_total_usage_ = 0;
+ focal_chromosome->profile_unique_mutrun_total_ = 0;
+ focal_chromosome->profile_mutrun_nonneutral_recache_total_ = 0;
+ }
}
#endif
diff --git a/core/slim_globals.cpp b/core/slim_globals.cpp
index 57b572c5..426afd2b 100644
--- a/core/slim_globals.cpp
+++ b/core/slim_globals.cpp
@@ -2339,38 +2339,6 @@ void WriteProfileResults(std::string profile_output_path, std::string model_name
continue;
}
- {
- int64_t power_tallies[20]; // we only go up to 1024 mutruns right now, but this gives us some headroom
- int64_t power_tallies_total = (int)focal_species->profile_mutcount_history_.size();
-
- for (int power = 0; power < 20; ++power)
- power_tallies[power] = 0;
-
- for (int32_t count : focal_species->profile_mutcount_history_)
- {
- int power = (int)round(log2(count));
-
- power_tallies[power]++;
- }
-
- fout << "";
- bool first_line = true;
-
- for (int power = 0; power < 20; ++power)
- {
- if (power_tallies[power] > 0)
- {
- if (!first_line)
- fout << "
\n";
- snprintf(buf, 256, "%6.2f%%", (power_tallies[power] / (double)power_tallies_total) * 100.0);
- fout << "" << HTMLMakeSpacesNonBreaking(buf) << " of ticks : " << ((int)(round(pow(2.0, power)))) << " mutation runs per haplosome";
- first_line = false;
- }
- }
-
- fout << "
\n";
- }
-
{
int64_t regime_tallies[3];
int64_t regime_tallies_total = (int)focal_species->profile_nonneutral_regime_history_.size();
@@ -2399,18 +2367,58 @@ void WriteProfileResults(std::string profile_output_path, std::string model_name
fout << "
\n";
}
- fout << "" << focal_species->profile_mutation_total_usage_ << " mutations referenced, summed across all ticks
\n";
- fout << "" << focal_species->profile_nonneutral_mutation_total_ << " mutations considered potentially nonneutral
\n";
- snprintf(buf, 256, "%0.2f%%", ((focal_species->profile_mutation_total_usage_ - focal_species->profile_nonneutral_mutation_total_) / (double)focal_species->profile_mutation_total_usage_) * 100.0);
- fout << "" << buf << " of mutations excluded from fitness calculations
\n";
- fout << "" << focal_species->profile_max_mutation_index_ << " maximum simultaneous mutations
\n";
-
- fout << "" << focal_species->profile_mutrun_total_usage_ << " mutation runs referenced, summed across all ticks
\n";
- fout << "" << focal_species->profile_unique_mutrun_total_ << " unique mutation runs maintained among those
\n";
- snprintf(buf, 256, "%6.2f%%", (focal_species->profile_mutrun_nonneutral_recache_total_ / (double)focal_species->profile_unique_mutrun_total_) * 100.0);
- fout << "" << HTMLMakeSpacesNonBreaking(buf) << " of mutation run nonneutral caches rebuilt per tick
\n";
- snprintf(buf, 256, "%6.2f%%", ((focal_species->profile_mutrun_total_usage_ - focal_species->profile_unique_mutrun_total_) / (double)focal_species->profile_mutrun_total_usage_) * 100.0);
- fout << "" << HTMLMakeSpacesNonBreaking(buf) << " of mutation runs shared among haplosomes
\n\n";
+ fout << "" << focal_species->profile_max_mutation_index_ << " maximum simultaneous mutations
\n";
+
+ const std::vector &chromosomes = focal_species->Chromosomes();
+
+ for (Chromosome *focal_chromosome : chromosomes)
+ {
+ fout << "Chromosome " << focal_chromosome->Symbol() << ":
\n";
+
+ {
+ int64_t power_tallies[20]; // we only go up to 1024 mutruns right now, but this gives us some headroom
+ int64_t power_tallies_total = (int)focal_chromosome->profile_mutcount_history_.size();
+
+ for (int power = 0; power < 20; ++power)
+ power_tallies[power] = 0;
+
+ for (int32_t count : focal_chromosome->profile_mutcount_history_)
+ {
+ int power = (int)round(log2(count));
+
+ power_tallies[power]++;
+ }
+
+ fout << "";
+ bool first_line = true;
+
+ for (int power = 0; power < 20; ++power)
+ {
+ if (power_tallies[power] > 0)
+ {
+ if (!first_line)
+ fout << "
\n";
+ snprintf(buf, 256, "%6.2f%%", (power_tallies[power] / (double)power_tallies_total) * 100.0);
+ fout << "" << HTMLMakeSpacesNonBreaking(buf) << " of ticks : " << ((int)(round(pow(2.0, power)))) << " mutation runs per haplosome";
+ first_line = false;
+ }
+ }
+
+ fout << "
\n";
+ }
+
+ fout << "" << focal_chromosome->profile_mutation_total_usage_ << " mutations referenced, summed across all ticks
\n";
+ fout << "" << focal_chromosome->profile_nonneutral_mutation_total_ << " mutations considered potentially nonneutral
\n";
+ snprintf(buf, 256, "%0.2f%%", ((focal_chromosome->profile_mutation_total_usage_ - focal_chromosome->profile_nonneutral_mutation_total_) / (double)focal_chromosome->profile_mutation_total_usage_) * 100.0);
+ fout << "" << buf << " of mutations excluded from fitness calculations
\n";
+
+ fout << "" << focal_chromosome->profile_mutrun_total_usage_ << " mutation runs referenced, summed across all ticks
\n";
+ fout << "" << focal_chromosome->profile_unique_mutrun_total_ << " unique mutation runs maintained among those
\n";
+ snprintf(buf, 256, "%6.2f%%", (focal_chromosome->profile_mutrun_nonneutral_recache_total_ / (double)focal_chromosome->profile_unique_mutrun_total_) * 100.0);
+ fout << "" << HTMLMakeSpacesNonBreaking(buf) << " of mutation run nonneutral caches rebuilt per tick
\n";
+ snprintf(buf, 256, "%6.2f%%", ((focal_chromosome->profile_mutrun_total_usage_ - focal_chromosome->profile_unique_mutrun_total_) / (double)focal_chromosome->profile_mutrun_total_usage_) * 100.0);
+ fout << "" << HTMLMakeSpacesNonBreaking(buf) << " of mutation runs shared among haplosomes
\n\n";
+ }
}
#endif
diff --git a/core/species.cpp b/core/species.cpp
index 931f6326..7ea17a4b 100644
--- a/core/species.cpp
+++ b/core/species.cpp
@@ -3307,14 +3307,7 @@ void Species::ReturnShuffleBuffer(void)
#if SLIM_USE_NONNEUTRAL_CACHES
void Species::CollectMutationProfileInfo(void)
{
- // FIXME MULTICHROM this profile info should be moved to be per-chromosome; for now, we protect against not having a chromosome
- if (chromosomes_.size() == 0)
- return;
-
- Chromosome &chromosome = TheChromosome(); // only keeping the history for the first chromosome right now, should keep it for all
-
- // maintain our history of the number of mutruns per haplosome and the nonneutral regime
- profile_mutcount_history_.emplace_back(chromosome.mutrun_count_);
+ // maintain our history of the nonneutral regime
profile_nonneutral_regime_history_.emplace_back(last_nonneutral_regime_);
// track the maximum number of mutations in existence at one time
@@ -3323,46 +3316,56 @@ void Species::CollectMutationProfileInfo(void)
population_.MutationRegistry(®istry_size);
profile_max_mutation_index_ = std::max(profile_max_mutation_index_, (int64_t)registry_size);
- // tally up the number of mutation runs, mutation usage metrics, etc.
- int haplosome_count_per_individual = HaplosomeCountPerIndividual();
+ // tally per-chromosome information
int64_t operation_id = MutationRun::GetNextOperationID();
- for (std::pair &subpop_pair : population_.subpops_)
+ for (Chromosome *chromosome : Chromosomes())
{
- Subpopulation *subpop = subpop_pair.second;
+ int first_haplosome_index = FirstHaplosomeIndices()[chromosome->Index()];
+ int last_haplosome_index = LastHaplosomeIndices()[chromosome->Index()];
+
+ // maintain our history of the number of mutruns per haplosome
+ chromosome->profile_mutcount_history_.emplace_back(chromosome->mutrun_count_);
- for (Individual *ind : subpop->parent_individuals_)
- {
- Haplosome **haplosomes = ind->haplosomes_;
-
- for (int haplosome_index = 0; haplosome_index < haplosome_count_per_individual; haplosome_index++)
- {
- Haplosome *haplosome = haplosomes[haplosome_index];
-
- const MutationRun **mutruns = haplosome->mutruns_;
- int32_t mutrun_count = haplosome->mutrun_count_;
-
- profile_mutrun_total_usage_ += mutrun_count;
-
- for (int32_t mutrun_index = 0; mutrun_index < mutrun_count; ++mutrun_index)
- {
- const MutationRun *mutrun = mutruns[mutrun_index];
-
- if (mutrun)
- {
- if (mutrun->operation_id_ != operation_id)
- {
- mutrun->operation_id_ = operation_id;
- profile_unique_mutrun_total_++;
- }
-
- // tally the total and nonneutral mutations
- mutrun->tally_nonneutral_mutations(&profile_mutation_total_usage_, &profile_nonneutral_mutation_total_, &profile_mutrun_nonneutral_recache_total_);
- }
- }
- }
- }
- }
+ // tally up the number of mutation runs, mutation usage metrics, etc.
+ for (std::pair &subpop_pair : population_.subpops_)
+ {
+ Subpopulation *subpop = subpop_pair.second;
+
+ for (Individual *ind : subpop->parent_individuals_)
+ {
+ Haplosome **haplosomes = ind->haplosomes_;
+
+ for (int haplosome_index = first_haplosome_index; haplosome_index <= last_haplosome_index; haplosome_index++)
+ {
+ Haplosome *haplosome = haplosomes[haplosome_index];
+ const MutationRun **mutruns = haplosome->mutruns_;
+ int32_t mutrun_count = haplosome->mutrun_count_;
+
+ chromosome->profile_mutrun_total_usage_ += mutrun_count;
+
+ for (int32_t mutrun_index = 0; mutrun_index < mutrun_count; ++mutrun_index)
+ {
+ const MutationRun *mutrun = mutruns[mutrun_index];
+
+ if (mutrun)
+ {
+ if (mutrun->operation_id_ != operation_id)
+ {
+ mutrun->operation_id_ = operation_id;
+ chromosome->profile_unique_mutrun_total_++;
+ }
+
+ // tally the total and nonneutral mutations
+ mutrun->tally_nonneutral_mutations(&chromosome->profile_mutation_total_usage_,
+ &chromosome->profile_nonneutral_mutation_total_,
+ &chromosome->profile_mutrun_nonneutral_recache_total_);
+ }
+ }
+ }
+ }
+ }
+ }
}
#endif
#endif
diff --git a/core/species.h b/core/species.h
index c1849192..d1b2c306 100644
--- a/core/species.h
+++ b/core/species.h
@@ -383,17 +383,12 @@ class Species : public EidosDictionaryUnretained
#if (SLIMPROFILING == 1)
// PROFILING : Species keeps track of its memory usage profile info and mutation-related profile info
+ // BCH 11/24/2024: Note that Chromosome now keeps additional profile information that is per-chromosome
SLiMMemoryUsage_Species profile_last_memory_usage_Species;
SLiMMemoryUsage_Species profile_total_memory_usage_Species;
#if SLIM_USE_NONNEUTRAL_CACHES
- std::vector profile_mutcount_history_; // a record of the mutation run count used in each cycle
std::vector profile_nonneutral_regime_history_; // a record of the nonneutral regime used in each cycle
- int64_t profile_mutation_total_usage_; // how many (non-unique) mutations were used by mutation runs, summed across cycles
- int64_t profile_nonneutral_mutation_total_; // of profile_mutation_total_usage_, how many were deemed to be nonneutral
- int64_t profile_mutrun_total_usage_; // how many (non-unique) mutruns were used by haplosomes, summed across cycles
- int64_t profile_unique_mutrun_total_; // of profile_mutrun_total_usage_, how many unique mutruns existed, summed across cycles
- int64_t profile_mutrun_nonneutral_recache_total_; // of profile_unique_mutrun_total_, how many mutruns regenerated their nonneutral cache
int64_t profile_max_mutation_index_; // the largest mutation index seen over the course of the profile
#endif // SLIM_USE_NONNEUTRAL_CACHES
#endif // (SLIMPROFILING == 1)
diff --git a/core/species_eidos.cpp b/core/species_eidos.cpp
index 510a4297..7bf9f1a1 100644
--- a/core/species_eidos.cpp
+++ b/core/species_eidos.cpp
@@ -3399,7 +3399,7 @@ EidosValue_SP Species::ExecuteMethod_subsetMutations(EidosGlobalStringID p_metho
EIDOS_TERMINATION << "ERROR (Species::ExecuteMethod_subsetMutations): (internal error) chromosome lookup failed." << EidosTerminate();
chromosome = chromosomes_[chromosome_indices[0]];
- chromosome_index = chromosome->index_;
+ chromosome_index = chromosome->Index();
}
// SPECIES CONSISTENCY CHECK