From 58f0e4059a0e43935a1eda96b39433a7363f7191 Mon Sep 17 00:00:00 2001 From: Matthew Andres Moreno Date: Tue, 14 Nov 2023 22:25:36 -0500 Subject: [PATCH] Impl, test save/load birth counts --- avida-core/source/actions/SaveLoadActions.cc | 61 ++++++- avida-core/source/main/cDeme.h | 1 + .../demes_loadbirthcounts/config/avida.cfg | 168 ++++++++++++++++++ .../config/detailgermlines-500.sgerm | 11 ++ .../config/environment.cfg | 9 + .../demes_loadbirthcounts/config/events.cfg | 10 ++ .../config/instset-transsmt.cfg | 35 ++++ .../demes_loadbirthcounts/expected/.gitignore | 0 .../expected/data/deme_replication.dat | 1 + .../expected/data/injectlog.dat | 7 + .../expected/data/out-10.sgerm | 12 ++ .../expected/data/out-10.spop | 26 +++ .../tests/demes_loadbirthcounts/test_list | 36 ++++ 13 files changed, 376 insertions(+), 1 deletion(-) create mode 100644 avida-core/tests/demes_loadbirthcounts/config/avida.cfg create mode 100644 avida-core/tests/demes_loadbirthcounts/config/detailgermlines-500.sgerm create mode 100644 avida-core/tests/demes_loadbirthcounts/config/environment.cfg create mode 100644 avida-core/tests/demes_loadbirthcounts/config/events.cfg create mode 100644 avida-core/tests/demes_loadbirthcounts/config/instset-transsmt.cfg create mode 100644 avida-core/tests/demes_loadbirthcounts/expected/.gitignore create mode 100644 avida-core/tests/demes_loadbirthcounts/expected/data/deme_replication.dat create mode 100644 avida-core/tests/demes_loadbirthcounts/expected/data/injectlog.dat create mode 100644 avida-core/tests/demes_loadbirthcounts/expected/data/out-10.sgerm create mode 100644 avida-core/tests/demes_loadbirthcounts/expected/data/out-10.spop create mode 100644 avida-core/tests/demes_loadbirthcounts/test_list diff --git a/avida-core/source/actions/SaveLoadActions.cc b/avida-core/source/actions/SaveLoadActions.cc index 3dfee1bd8..88b45e775 100644 --- a/avida-core/source/actions/SaveLoadActions.cc +++ b/avida-core/source/actions/SaveLoadActions.cc @@ -187,20 +187,23 @@ class cActionSaveGermlines : public cAction { private: cString m_filename; + bool m_birthcounts; public: cActionSaveGermlines(cWorld* world, const cString& args, Feedback& feedback) - : cAction(world, args), m_filename("") + : cAction(world, args), m_filename(""), m_birthcounts(false) { cArgSchema schema(':','='); // String Entries schema.AddEntry("filename", 0, "detailgermlines"); + schema.AddEntry("birthcounts", 0, false); cArgContainer* argc = cArgContainer::Load(args, schema, feedback); if (argc) { m_filename = argc->GetString(0); + m_birthcounts = argc->GetInt(1); } delete argc; @@ -223,6 +226,11 @@ class cActionSaveGermlines : public cAction const auto& genome = germline.GetLatest(); df->Write(i, "Deme ID", "deme_id"); genome.LegacySave(Apto::GetInternalPtr(df)); + if (m_birthcounts) { + df->Write( + deme.GetBirthCount(), "Deme Birth Count", "deme_birth_count" + ); + } df->Endl(); } @@ -302,6 +310,56 @@ class cActionLoadGermlines : public cAction } }; +class cActionLoadBirthCounts : public cAction +{ +private: + cString m_filename; + bool m_verbose; + +public: + cActionLoadBirthCounts(cWorld* world, const cString& args, Feedback& feedback) + : cAction(world, args), m_filename(""), m_verbose(false) + { + cString largs(args); + if (largs.GetSize()) m_filename = largs.PopWord(); + if (largs.GetSize()) m_verbose = largs.PopWord().AsInt(); + } + + static const cString GetDescription() { return "Arguments: [string filename='detailgermlines']"; } + + void Process(cAvidaContext& ctx) { + cInitFile input_file( + m_filename, + m_world->GetWorkingDir(), + ctx.Driver().Feedback() + ); + assert(input_file.WasOpened()); + if (m_verbose) printf( + "LoadBirthCounts input file %s has %d lines.\n", + (const char*)m_filename, + input_file.GetNumLines() + ); + + for (int line_id = 0; line_id < input_file.GetNumLines(); line_id++) { + auto file_props = input_file.GetLineAsDict(line_id); + const int deme_id = Apto::StrAs(file_props->Get("deme_id")); + const int deme_birth_count = Apto::StrAs(file_props->Get("deme_birth_count")); + if (m_verbose) + printf( + "LoadBirthCounts deme %d has %d births.\n", deme_id, deme_birth_count + ); + + auto& deme = m_world->GetPopulation().GetDeme(deme_id); + deme.SetBirthCount(deme_birth_count); + printf( + "LoadBirthCounts set deme %d birth counts to %d.\n", + deme_id, + deme.GetBirthCount() + ); + } + } +}; + class cActionLoadStructuredSystematicsGroup : public cAction { @@ -416,6 +474,7 @@ void RegisterSaveLoadActions(cActionLibrary* action_lib) action_lib->Register("SavePopulation"); action_lib->Register("LoadGermlines"); action_lib->Register("SaveGermlines"); + action_lib->Register("LoadBirthCounts"); action_lib->Register("LoadStructuredSystematicsGroup"); action_lib->Register("SaveStructuredSystematicsGroup"); action_lib->Register("SaveFlameData"); diff --git a/avida-core/source/main/cDeme.h b/avida-core/source/main/cDeme.h index 882dc13de..94c583019 100644 --- a/avida-core/source/main/cDeme.h +++ b/avida-core/source/main/cDeme.h @@ -176,6 +176,7 @@ class cDeme int GetBirthCount() const { return cur_birth_count; } int GetLastBirthCount() const { return last_birth_count; } void IncBirthCount() { cur_birth_count++; birth_count_perslot++;} + void SetBirthCount(const int count) { cur_birth_count = count; } int GetOrgCount() const { return cur_org_count; } int GetLastOrgCount() const { return last_org_count; } diff --git a/avida-core/tests/demes_loadbirthcounts/config/avida.cfg b/avida-core/tests/demes_loadbirthcounts/config/avida.cfg new file mode 100644 index 000000000..8e871e23d --- /dev/null +++ b/avida-core/tests/demes_loadbirthcounts/config/avida.cfg @@ -0,0 +1,168 @@ +############################################################################# +# This file includes all the basic run-time defines for Avida. +# For more information, see doc/config.html +############################################################################# + +# Let's output a bit about the threads and parasites to stdout +VERBOSITY 3 +# We use a bigger world than default +WORLD_X 10 +WORLD_Y 20 +NUM_DEMES 2 +RANDOM_SEED 1 + +# DEME CONFIGURATION +#------------------------------------------------------------------------------ + +# Deme seeding method. +# 0 = Maintain old consistency +# 1 = New method using genotypes +DEMES_SEED_METHOD 0 + +# Number of organisms in a deme to trigger its replication (0 = OFF). +DEMES_REPLICATE_ORGS 100 + +# Deme divide method. +# Only works with DEMES_SEED_METHOD 1 +# 0 = Replace source and target demes +# 1 = Replace target deme, reset source deme to founders +# 2 = Replace target deme, leave source deme unchanged +# 3 = Replace the target deme, and reset the number of resources consumed by the source deme. +# 4 = Replace the target deme, reset the number of resources consumed by the source deme, and kill the germ line organisms of the source deme +DEMES_DIVIDE_METHOD 0 + +# one deme population +DEMES_PARTITION_INTERVAL 0 + +# Should demes use a distinct germline? +# 0: No +# 1: Traditional germ lines +# 2: Genotype tracking +# 3: Organism flagging germline +DEMES_USE_GERMLINE 1 + +# Give empty demes preference as targets of deme replication? +DEMES_PREFER_EMPTY 1 + +# Reset resources in demes on replication? +# 0 = reset both demes +# 1 = reset target deme +# 2 = deme resources remain unchanged +DEMES_RESET_RESOURCES 2 + +# Number of offspring produced by a deme to trigger its replication. +# 0 = OFF +DEMES_REPLICATE_BIRTHS 0 + +# Max number of births that can occur within a deme; +# used with birth-count replication +DEMES_MAX_BIRTHS 0 + +# Give empty demes preference as targets of deme replication? +DEMES_PREFER_EMPTY 1 + +# Which demes can an offspring land in when it migrates? +# 0 = Any other deme +# 1 = Eight neighboring demes +# 2 = Two adjacent demes in list +# 3 = Proportional based on the number of points +# 4 = Use the weight matrix specified in MIGRATION_FILE +DEMES_MIGRATION_METHOD 0 + +# Probability of a parasite migrating to a different deme +DEMES_PARASITE_MIGRATION_RATE 0 + +# Probability of an offspring being born in a different deme. +DEMES_MIGRATION_RATE 0 + +# Log deme replications? +LOG_DEMES_REPLICATE 1 + +# Log injection of organisms. 0/1 (off/on) +LOG_INJECT 1 + + +# Cell Configuration +#------------------------------------------------------------------------------ + +# Make birth non-spatial +# Which organism should be replaced when a birth occurs? +# 0 = Random organism in neighborhood +# 1 = Oldest in neighborhood +# 2 = Largest Age/Merit in neighborhood +# 3 = None (use only empty cells in neighborhood) +# 4 = Random from population (Mass Action) +# 5 = Oldest in entire population +# 6 = Random within deme +# 7 = Organism faced by parent +# 8 = Next grid cell (id+1) +# 9 = Largest energy used in entire population +# 10 = Largest energy used in neighborhood +# 11 = Local neighborhood dispersal +# 12 = Kill offpsring after recording birth stats (for behavioral trials) +# 13 = Kill parent and offpsring (for behavioral trials) +BIRTH_METHOD 6 # random within deme +# Overide BIRTH_METHOD to preferentially choose empty cells for offsping? +PREFER_EMPTY 0 + +# Hosts get to live a bit longer than usual +# When should death by old age occur? +# When executed genome_length * AGE_LIMIT (+dev) instructions +AGE_LIMIT 30 + + + +# MUTATION CONFIGURATION --- no mutation +#------------------------------------------------------------------------------ + +# Substitution rate (per copy) +# We assign mtuation rates independently for hosts/parasites +COPY_MUT_PROB 0 +# Insertion rate (per copy) +COPY_INS_PROB 0 +# Deletion rate (per copy) +COPY_DEL_PROB 0 +# Uniform mutation probability (per copy) +# Randomly apply insertion, deletion or substition mutation +COPY_UNIFORM_PROB 0 +# Slip rate (per copy) +COPY_SLIP_PROB 0 + +# Substitution rate (per site, applied on divide) +DIV_MUT_PROB 0.001000 +# Insertion rate (per site, applied on divide) +DIV_INS_PROB 0.0 +# Deletion rate (per site, applied on divide) +DIV_DEL_PROB 0.0 +# Uniform mutation probability (per site, applied on divide)\n- Randomly apply insertion, deletion or point mutation +DIV_UNIFORM_PROB 0.0 +# Slip rate (per site, applied on divide) +DIV_SLIP_PROB 0.0 + +# Substitution rate (max one, per divide +DIVIDE_MUT_PROB 0 +# Insertion rate (max one, per divide) +DIVIDE_INS_PROB 0 +# Deletion rate (max one, per divide) +DIVIDE_DEL_PROB 0 + +# Substitution rate (per site, applied on inject) +INJECT_MUT_PROB 0.0 +# Insertion rate (per site, applied on inject) +INJECT_INS_PROB 0.0 +# Deletion rate (per site, applied on inject) +INJECT_DEL_PROB 0.0 + +# Prob. of copy mutations during germline replication +GERMLINE_COPY_MUT ${GERMLINE_COPY_MUT} +# Prob. of insertion mutations during germline replication +GERMLINE_INS_MUT 0.0 +# Prob. of deletion mutations during germline replication +GERMLINE_DEL_MUT 0.0 + +# Keep genomes from programatically creating their own variation +# ...because it's complicated enough as is +# Should genotypes that cannot replicate perfectly not be allowed to replicate? +STERILIZE_UNSTABLE 1 + +#include INST_SET=instset-transsmt.cfg diff --git a/avida-core/tests/demes_loadbirthcounts/config/detailgermlines-500.sgerm b/avida-core/tests/demes_loadbirthcounts/config/detailgermlines-500.sgerm new file mode 100644 index 000000000..14f8eff7f --- /dev/null +++ b/avida-core/tests/demes_loadbirthcounts/config/detailgermlines-500.sgerm @@ -0,0 +1,11 @@ +#filetype germline_data +#format deme_id hw_type inst_set sequence deme_birth_count +# Mode 1 Germline Save +# Tue Aug 29 01:14:50 2023 +# 1: Deme ID +# 2: Hardware Type ID +# 3: Inst Set Name +# 4: Genome Sequence +# 5: Deme Birth Count + +0 2 transsmt ycdBCiEdimFjfCDaknmsAjemEEcgccgssmhEEcsdseDcAcBcggclEEcDEgcvrsAmlzessjhcdcggkhamtmciEEvjDdhjidzoAyndvmEdbgznjDmcjohohooayaxdyalbcekzebjcogEtjgjacblDvubADnslyyocgsAcjCbobffhmvnnAdbDfkmxcagBFfndytqhutjdzfdjsnflfoqCwcvhsjcvbmlsqcjrgyiDivvnFhrArcsmifbClvluDqmCBbtiDhiEfACcarpEczijdljujACbfzuDEFyaqqekizDosbbzjgmpczypqvcrGxab 42 diff --git a/avida-core/tests/demes_loadbirthcounts/config/environment.cfg b/avida-core/tests/demes_loadbirthcounts/config/environment.cfg new file mode 100644 index 000000000..a68e81b37 --- /dev/null +++ b/avida-core/tests/demes_loadbirthcounts/config/environment.cfg @@ -0,0 +1,9 @@ +REACTION NOT not process:value=1.0:type=pow requisite:max_count=1 +REACTION NAND nand process:value=1.0:type=pow requisite:max_count=1 +REACTION AND and process:value=2.0:type=pow requisite:max_count=1 +REACTION ORN orn process:value=2.0:type=pow requisite:max_count=1 +REACTION OR or process:value=3.0:type=pow requisite:max_count=1 +REACTION ANDN andn process:value=3.0:type=pow requisite:max_count=1 +REACTION NOR nor process:value=4.0:type=pow requisite:max_count=1 +REACTION XOR xor process:value=4.0:type=pow requisite:max_count=1 +REACTION EQU equ process:value=5.0:type=pow requisite:max_count=1 diff --git a/avida-core/tests/demes_loadbirthcounts/config/events.cfg b/avida-core/tests/demes_loadbirthcounts/config/events.cfg new file mode 100644 index 000000000..e7b452b0a --- /dev/null +++ b/avida-core/tests/demes_loadbirthcounts/config/events.cfg @@ -0,0 +1,10 @@ +i InjectSequence ycdBCiEdimFjfCDaknmsAjemEEcgccgssmhEEcsdseDcAcBcggclEEcDEgcvrsAmlzessjhcdcggkhamtmciEEvjDdhjidzoAyndvmEdbgznjDmcjohohooayaxdyalbcekzebjcogEtjgjacblDvubADnslyyocgsAcjCbobffhmvnnAdbDfkmxcagBFfndytqhutjdzfdjsnflfoqCwcvhsjcvbmlsqcjrgyiDivvnFhrArcsmifbClvluDqmCBbtiDhiEfACcarpEczijdljujACbfzuDEFyaqqekizDosbbzjgmpczypqvcrGxab 101 +i LoadGermlines detailgermlines-500.sgerm +i LoadBirthCounts detailgermlines-500.sgerm 1 + +u 5 ReplicateDeme 1 + +u 10 SavePopulation filename=out +u 10 SaveGermlines filename=out:birthcounts=1 + +u 10 Exit diff --git a/avida-core/tests/demes_loadbirthcounts/config/instset-transsmt.cfg b/avida-core/tests/demes_loadbirthcounts/config/instset-transsmt.cfg new file mode 100644 index 000000000..aa2a05df2 --- /dev/null +++ b/avida-core/tests/demes_loadbirthcounts/config/instset-transsmt.cfg @@ -0,0 +1,35 @@ +INSTSET transsmt:hw_type=2 + +INST Nop-A +INST Nop-B +INST Nop-C +INST Nop-D +INST Val-Shift-R +INST Val-Shift-L +INST Val-Nand +INST Val-Add +INST Val-Sub +INST Val-Mult +INST Val-Div +INST Val-Mod +INST Val-Inc +INST Val-Dec +INST SetMemory +INST Inst-Read +INST Inst-Write +INST If-Equal +INST If-Not-Equal +INST If-Less +INST If-Greater +INST Head-Push +INST Head-Pop +INST Head-Move +INST Search +INST Push-Next +INST Push-Prev +INST Push-Comp +INST Val-Delete +INST Val-Copy +INST IO +INST Inject +INST Divide-Erase diff --git a/avida-core/tests/demes_loadbirthcounts/expected/.gitignore b/avida-core/tests/demes_loadbirthcounts/expected/.gitignore new file mode 100644 index 000000000..e69de29bb diff --git a/avida-core/tests/demes_loadbirthcounts/expected/data/deme_replication.dat b/avida-core/tests/demes_loadbirthcounts/expected/data/deme_replication.dat new file mode 100644 index 000000000..fcf473520 --- /dev/null +++ b/avida-core/tests/demes_loadbirthcounts/expected/data/deme_replication.dat @@ -0,0 +1 @@ +5,1,0 diff --git a/avida-core/tests/demes_loadbirthcounts/expected/data/injectlog.dat b/avida-core/tests/demes_loadbirthcounts/expected/data/injectlog.dat new file mode 100644 index 000000000..c4648f141 --- /dev/null +++ b/avida-core/tests/demes_loadbirthcounts/expected/data/injectlog.dat @@ -0,0 +1,7 @@ +# 1: Update +# 2: Organism ID +# 3: Deme ID +# 4: Facing + +5 1 1 3 +5 2 0 3 diff --git a/avida-core/tests/demes_loadbirthcounts/expected/data/out-10.sgerm b/avida-core/tests/demes_loadbirthcounts/expected/data/out-10.sgerm new file mode 100644 index 000000000..854e6c880 --- /dev/null +++ b/avida-core/tests/demes_loadbirthcounts/expected/data/out-10.sgerm @@ -0,0 +1,12 @@ +#filetype germline_data +#format deme_id hw_type inst_set sequence deme_birth_count +# Mode 1 Germline Save +# Tue Nov 14 22:24:30 2023 +# 1: Deme ID +# 2: Hardware Type ID +# 3: Inst Set Name +# 4: Genome Sequence +# 5: Deme Birth Count + +0 2 transsmt ycdBCiEdimFjfCDaknmsAjemEEcgccgssmhEEcsdseDcAcBcggclEEcDEgcvrsAmlzessjhcdcggkhamtmciEEvjDdhjidzoAyndvmEdbgznjDmcjohohooayaxdyalbcekzebjcogEtjgjacblDvubADnslyyocgsAcjCbobffhmvnnAdbDfkmxcagBFfndytqhutjdzfdjsnflfoqCwcvhsjcvbmlsqcjrgyiDivvnFhrArcsmifbClvluDqmCBbtiDhiEfACcarpEczijdljujACbfzuDEFyaqqekizDosbbzjgmpczypqvcrGxab 0 +1 2 transsmt ycdBCiEdimFjfCDaknmsAjemEEcgccgssmhEEcsdseDcAcBcggclEEcDEgcvrsAmlzessjhcdcggkhamtmciEEvjDdhjidzoAyndvmEdbgznjDmcjohohooayaxdyalbcekzebjcogEtjgjacblDvubADnslyyocgsAcjCbobffhmvnnAdbDfkmxcagBFfndytqhutjdzfdjsnflfoqCwcvhsjcvbmlsqcjrgyiDivvnFhrArcsmifbClvluDqmCBbtiDhiEfACcarpEczijdljujACbfzuDEFyaqqekizDosbbzjgmpczypqvcrGxab 0 diff --git a/avida-core/tests/demes_loadbirthcounts/expected/data/out-10.spop b/avida-core/tests/demes_loadbirthcounts/expected/data/out-10.spop new file mode 100644 index 000000000..e6d371635 --- /dev/null +++ b/avida-core/tests/demes_loadbirthcounts/expected/data/out-10.spop @@ -0,0 +1,26 @@ +#filetype genotype_data +#format id src src_args parents num_units total_units length merit gest_time fitness gen_born update_born update_deactivated depth hw_type inst_set sequence cells gest_offset lineage +# Structured Population Save +# Tue Nov 14 22:24:30 2023 +# 1: ID +# 2: Source +# 3: Source Args +# 4: Parent ID(s) +# 5: Number of currently living organisms +# 6: Total number of organisms that ever existed +# 7: Genome Length +# 8: Average Merit +# 9: Average Gestation Time +# 10: Average Fitness +# 11: Generation Born +# 12: Update Born +# 13: Update Deactivated +# 14: Phylogenetic Depth +# 15: Hardware Type ID +# 16: Inst Set Name +# 17: Genome Sequence +# 18: Occupied Cell IDs +# 19: Gestation (CPU) Cycle Offsets +# 20: Lineage Label + +2 dup:int germline (none) 2 2 320 0 0 0 0 6 -1 0 2 transsmt ycdBCiEdimFjfCDaknmsAjemEEcgccgssmhEEcsdseDcAcBcggclEEcDEgcvrsAmlzessjhcdcggkhamtmciEEvjDdhjidzoAyndvmEdbgznjDmcjohohooayaxdyalbcekzebjcogEtjgjacblDvubADnslyyocgsAcjCbobffhmvnnAdbDfkmxcagBFfndytqhutjdzfdjsnflfoqCwcvhsjcvbmlsqcjrgyiDivvnFhrArcsmifbClvluDqmCBbtiDhiEfACcarpEczijdljujACbfzuDEFyaqqekizDosbbzjgmpczypqvcrGxab 50,150 0,0 0,0 diff --git a/avida-core/tests/demes_loadbirthcounts/test_list b/avida-core/tests/demes_loadbirthcounts/test_list new file mode 100644 index 000000000..2f7282cca --- /dev/null +++ b/avida-core/tests/demes_loadbirthcounts/test_list @@ -0,0 +1,36 @@ +;--- Begin Test Configuration File (test_list) --- +[main] +; Command line arguments to pass to the application +args = -s 100 +app = %(default_app)s +nonzeroexit = disallow ; Exit code handling (disallow, allow, or require) + ; disallow - treat non-zero exit codes as failures + ; allow - all exit codes are acceptable + ; require - treat zero exit codes as failures, useful + ; for creating tests for app error checking +createdby = Dave Knoester ; Who created the test +email = dk@cse.msu.edu ; Email address for the test's creator + +[consistency] +enabled = yes ; Is this test a consistency test? +long = no ; Is this test a long test? + +[performance] +enabled = no ; Is this test a performance test? +long = no ; Is this test a long test? + +; The following variables can be used in constructing setting values by calling +; them with %(variable_name)s. For example see 'app' above. +; +; app +; builddir +; cpus +; mode +; perf_repeat +; perf_user_margin +; perf_wall_margin +; svn +; svnmetadir +; svnversion +; testdir +;--- End Test Configuration File ---