From ace15521fbd3b5d8d7005863b46b326dfeb835f2 Mon Sep 17 00:00:00 2001 From: matthewgthomas Date: Wed, 25 Feb 2015 16:34:33 +0000 Subject: [PATCH] Revisions from reviewer comments --- Optimal Birth Intervals/App.config | 28 +++ Optimal Birth Intervals/BirthIntervals.cs | 165 ++++++++++++------ Optimal Birth Intervals/ForwardIteration.cs | 14 ++ .../Optimal Birth Intervals.csproj | 9 + Optimal Birth Intervals/Program.cs | 7 +- .../Properties/AssemblyInfo.cs | 36 ++++ .../Properties/Settings.Designer.cs | 68 ++++++++ .../Properties/Settings.settings | 18 ++ 8 files changed, 290 insertions(+), 55 deletions(-) create mode 100644 Optimal Birth Intervals/Properties/AssemblyInfo.cs create mode 100644 Optimal Birth Intervals/Properties/Settings.Designer.cs create mode 100644 Optimal Birth Intervals/Properties/Settings.settings diff --git a/Optimal Birth Intervals/App.config b/Optimal Birth Intervals/App.config index 92b2f39..989de0d 100644 --- a/Optimal Birth Intervals/App.config +++ b/Optimal Birth Intervals/App.config @@ -1,8 +1,36 @@  + + +
+ + +
+ + + + + + 50 + + + False + + + + + + + 150 + + + J + + + \ No newline at end of file diff --git a/Optimal Birth Intervals/BirthIntervals.cs b/Optimal Birth Intervals/BirthIntervals.cs index 94f6706..53a8587 100644 --- a/Optimal Birth Intervals/BirthIntervals.cs +++ b/Optimal Birth Intervals/BirthIntervals.cs @@ -12,12 +12,12 @@ partial class BirthIntervals { #region Constants int numFamilies = 987; - const int motherAgeMax = 91; - int motherArrayMax = 76; - const int maxTback = 75; + int motherAgeMax = 91; + int motherArrayMax = 76; // calculated from motherAgeMax + //const int maxTback = 75; // not needed -- model runs to convergence const int maxTforward = 150; - int ageAtMaturity; + int ageAtMaturity; // this is calculated by importFamiliesFromString() from the family structures in families.txt const string appWorkingDir = @"WorkingDir"; #endregion @@ -92,13 +92,16 @@ partial class BirthIntervals // Read in family structures and initialise fitness/decision arrays public BirthIntervals() { + // start by importing family structures and calculating a lookup table for them importFamiliesFromString(); CalculateLookupTable(); // before initialising arrays, set some global variables + motherAgeMax = Properties.Settings.Default.MaxAge + 1; // add 1 because we don't want death state in output array numFamilies = family.Count; motherArrayMax = motherAgeMax - ageAtMaturity; + // set up fitness and strategy arrays InitialiseArrays(); InitialisePopulationGrowthRate(); @@ -398,21 +401,26 @@ double calcSurvChild(int motherAge, int[] currentFamily, bool giveBirth, int chi // only those 10 and over can help if (age >= 10) { + double helpModifier = 5.0; // or 10.0 (originally) + switch (siblingHelp) { case MortalityParam.None: break; case MortalityParam.Low: - weight -= 0.1; + //weight -= 0.1; + weight += (double)(.5 - (age * .03333)) * -1.0; break; case MortalityParam.Medium: - weight += (double)(-.5 * (age - 10.0) / 10.0); + //weight += (double)(-.5 * (age - 10.0) / helpModifier); + weight += (double)(1 - (age * .06666)) * -1.0; break; case MortalityParam.High: - weight += (double)(-1.0 * (age - 10.0) / 10.0); + //weight += (double)(-1.0 * (age - 10.0) / helpModifier); + weight += (double)(1 - (age * 0.0357)) * -1.0; break; } } @@ -445,62 +453,86 @@ double calcSurvMother(int motherAge, int[] currentFamily, bool giveBirth, int fa /* Maternal mortality in childbirth * These parameters get varied for no increase with age, or a low, medium and high age-related increase as shown in Figure 1b */ - double alphaBirth = 0.0, betaBirth = 0.0, gammaBirth = 0.0; - - switch (childbirthMortality) + if (giveBirth && childbirthMortality != MortalityParam.None) { - case MortalityParam.None: - alphaBirth = 0.0; - betaBirth = 0.0; - gammaBirth = 0.0; - break; - - case MortalityParam.Low: - // values from Blanc et al. 2013 - alphaBirth = 1.424218e-05; - betaBirth = 5.415419e-04; - gammaBirth = 7.492639e-03; - break; - - case MortalityParam.Medium: - // values from Blanc et al. 2013 - alphaBirth = 1.394538e-05; - betaBirth = 5.268179e-04; - gammaBirth = 8.448535e-03; - break; - - case MortalityParam.High: - // values from Blanc et al. 2013 - alphaBirth = 1.236674e-05; - betaBirth = 4.478437e-04; - gammaBirth = 9.056053e-03; - break; + muBirth = calcMaternalMortality(motherAge); } - /* MORALITY RISK DUE TO CHILDBIRTH + /* calculate survival + * Constant value is the extrinsic adult mortality rate. */ - double initialRiskChildbirthMortality = 0.0; + double muExtrinsic = silerA2; + memoSurvival = Math.Exp((-1.0 * muExtrinsic) - muSen - muBirth); - if (giveBirth) + // and return survival + return memoSurvival; + } + + // returns the mother's probability of dying during childbirth given her age + private double calcMaternalMortality(int motherAge) + { + double muBirth = 0.0; + double alphaBirth = 0.0, betaBirth = 0.0, gammaBirth = 0.0; + + // calculate maternal morality + // J-shaped maternal mortality ratios from Blanc et al. (2013) + // (http://www.plosone.org/article/info%3Adoi%2F10.1371%2Fjournal.pone.0059864) + if (Properties.Settings.Default.MaternalMortalityFunc == "J") { - if (childbirthMortality == MortalityParam.None) + // what level of maternal mortality? + switch (childbirthMortality) { - muBirth = 0.0; + case MortalityParam.Low: + alphaBirth = 1.424218e-05; + betaBirth = 5.415419e-04; + gammaBirth = 7.492639e-03; + break; + + case MortalityParam.Medium: + alphaBirth = 1.394538e-05; + betaBirth = 5.268179e-04; + gammaBirth = 8.448535e-03; + break; + + case MortalityParam.High: + alphaBirth = 1.236674e-05; + betaBirth = 4.478437e-04; + gammaBirth = 9.056053e-03; + break; } - // Maternal mortality ratios from Blanc et al. 2013 (http://www.plosone.org/article/info%3Adoi%2F10.1371%2Fjournal.pone.0059864) // a * (age^2) - b * age + c muBirth = (alphaBirth * Math.Pow(motherAge, 2)) - (betaBirth * motherAge) + gammaBirth; } - /* calculate survival - * Constant value is the extrinsic adult mortality rate. - */ - double muExtrinsic = silerA2; - memoSurvival = Math.Exp((-1.0 * muExtrinsic) - muSen - muBirth); + // Exponential maternal mortality fitted from Grimes (1994) + // as used in from Shanley et al. (2007) + else if (Properties.Settings.Default.MaternalMortalityFunc == "E") + { + // what level of maternal mortality? + switch (childbirthMortality) + { + case MortalityParam.Low: + alphaBirth = 0.002928; + betaBirth = 0.1; + break; - // and return survival - return memoSurvival; + case MortalityParam.Medium: + alphaBirth = 0.000485; + betaBirth = 0.181221; + break; + + case MortalityParam.High: + alphaBirth = 1e-6; + betaBirth = 0.5; + break; + } + + // (a * Exp(b * (age - ageAtMaturity))) + (silerA2 - a) + muBirth = (alphaBirth * Math.Exp(betaBirth * (motherAge - ageAtMaturity))) + (silerA2 - alphaBirth); + } + + return muBirth; } #endregion @@ -556,6 +588,41 @@ private void exploreStateSpace() } } } + + public double TeenageSubfecundityProbability(int motherAge) + { + double pBirth = 1; + + // assign probabilities of giving birth + // linear from 0.25 at age 15 to 1.0 at age 20 -- y = 0.25 + 0.15.x + switch (motherAge) + { + case 15: + pBirth = 0.25; + break; + + case 16: + pBirth = 0.4; //0.5; + break; + + case 17: + pBirth = 0.55; //0.75; + break; + + case 18: + pBirth = 0.7; + break; + + case 19: + pBirth = 0.85; + break; + + default: + break; + } + + return pBirth; + } #endregion #region File import methods diff --git a/Optimal Birth Intervals/ForwardIteration.cs b/Optimal Birth Intervals/ForwardIteration.cs index f6ccd12..fbf8a83 100644 --- a/Optimal Birth Intervals/ForwardIteration.cs +++ b/Optimal Birth Intervals/ForwardIteration.cs @@ -124,6 +124,20 @@ void findFMax(int motherAge, int familyIndex, int arrayIndex) if (births[arrayIndex][familyIndex] == true) giveBirth = true; + // probabilistic age at first birth (teenage sub-fecundity)? + if (Properties.Settings.Default.ProbabilisticAFB && motherAge < 20) // only if mother is younger than 20 + { + double pBirth = TeenageSubfecundityProbability(motherAge); + + Random rnd = new Random(); + if (rnd.NextDouble() >= pBirth) + { + // do not give birth this year + giveBirth = false; + births[arrayIndex][familyIndex] = false; + } + } + // calculate fitness based on mother's age, current family structure and optimal birth decision FwdCalcF(motherAge, family[familyIndex].ToArray(), familyIndex, arrayIndex, giveBirth); } diff --git a/Optimal Birth Intervals/Optimal Birth Intervals.csproj b/Optimal Birth Intervals/Optimal Birth Intervals.csproj index 9d25bf6..3b5a4d6 100644 --- a/Optimal Birth Intervals/Optimal Birth Intervals.csproj +++ b/Optimal Birth Intervals/Optimal Birth Intervals.csproj @@ -50,12 +50,21 @@ + + True + True + Settings.settings + Designer + + SettingsSingleFileGenerator + Settings.Designer.cs + diff --git a/Optimal Birth Intervals/Program.cs b/Optimal Birth Intervals/Program.cs index 09a28da..13ae217 100644 --- a/Optimal Birth Intervals/Program.cs +++ b/Optimal Birth Intervals/Program.cs @@ -395,10 +395,6 @@ private static MortalityParam parseArgs(string arg) returnedValue = MortalityParam.Low; break; - case "J": - returnedValue = MortalityParam.Jshaped; - break; - default: returnedValue = MortalityParam.None; break; @@ -414,7 +410,6 @@ enum MortalityParam None, High, Medium, - Low, - Jshaped + Low } } diff --git a/Optimal Birth Intervals/Properties/AssemblyInfo.cs b/Optimal Birth Intervals/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..1df1183 --- /dev/null +++ b/Optimal Birth Intervals/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Optimal Birth Intervals")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("Optimal Birth Intervals")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2012")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("bc201870-d084-41a3-aeb2-db578107a540")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Optimal Birth Intervals/Properties/Settings.Designer.cs b/Optimal Birth Intervals/Properties/Settings.Designer.cs new file mode 100644 index 0000000..005ad8c --- /dev/null +++ b/Optimal Birth Intervals/Properties/Settings.Designer.cs @@ -0,0 +1,68 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.18444 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Optimal_Birth_Intervals.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("50")] + public int MaxAge { + get { + return ((int)(this["MaxAge"])); + } + set { + this["MaxAge"] = value; + } + } + + [global::System.Configuration.ApplicationScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("150")] + public int ForwardIterations { + get { + return ((int)(this["ForwardIterations"])); + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool ProbabilisticAFB { + get { + return ((bool)(this["ProbabilisticAFB"])); + } + set { + this["ProbabilisticAFB"] = value; + } + } + + [global::System.Configuration.ApplicationScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("J")] + public string MaternalMortalityFunc { + get { + return ((string)(this["MaternalMortalityFunc"])); + } + } + } +} diff --git a/Optimal Birth Intervals/Properties/Settings.settings b/Optimal Birth Intervals/Properties/Settings.settings new file mode 100644 index 0000000..40344a5 --- /dev/null +++ b/Optimal Birth Intervals/Properties/Settings.settings @@ -0,0 +1,18 @@ + + + + + + 50 + + + 150 + + + False + + + J + + + \ No newline at end of file