Skip to content

Commit

Permalink
Merge branch 'new_genetics' into multispecies
Browse files Browse the repository at this point in the history
  • Loading branch information
TheoPannetier committed Nov 20, 2024
2 parents 39ae45b + c2c38fb commit 2e91e82
Show file tree
Hide file tree
Showing 6 changed files with 400 additions and 132 deletions.
Binary file modified doc/Manual/Batchmode/TraitsFile.xlsx
Binary file not shown.
249 changes: 179 additions & 70 deletions src/BatchMode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2953,7 +2953,7 @@ int CheckTraitsFile(string indir)
{
string header, colheader;
int simNb, nextLineSimNb;
string filename, inTraitType, inSex, inInitDist, inInitParams,
string filename, inTraitType, inSex, inInitDist, inInitParams, inInitDomDist, inInitDomParams,
inDominanceDist, inDominanceParams, inIsInherited, inMutationDist,
inMutationParams, inPositions, inNbPositions, inExpressionType, inMutationRate, inIsOutput;
int nbErrors = 0;
Expand All @@ -2970,13 +2970,15 @@ int CheckTraitsFile(string indir)
bTraitsFile >> header; if (header != "Positions") nbErrors++;
bTraitsFile >> header; if (header != "NbrOfPositions") nbErrors++;
bTraitsFile >> header; if (header != "ExpressionType") nbErrors++;
bTraitsFile >> header; if (header != "InitialDistribution") nbErrors++;
bTraitsFile >> header; if (header != "InitialParameters") nbErrors++;
bTraitsFile >> header; if (header != "DominanceDistribution") nbErrors++;
bTraitsFile >> header; if (header != "DominanceParameters") nbErrors++;
bTraitsFile >> header; if (header != "InitialAlleleDist") nbErrors++;
bTraitsFile >> header; if (header != "InitialAlleleParams") nbErrors++;
bTraitsFile >> header; if (header != "InitialDomDist") nbErrors++;
bTraitsFile >> header; if (header != "InitialDomParams") nbErrors++;
bTraitsFile >> header; if (header != "IsInherited") nbErrors++;
bTraitsFile >> header; if (header != "MutationDistribution") nbErrors++;
bTraitsFile >> header; if (header != "MutationParameters") nbErrors++;
bTraitsFile >> header; if (header != "DominanceDistribution") nbErrors++;
bTraitsFile >> header; if (header != "DominanceParameters") nbErrors++;
bTraitsFile >> header; if (header != "MutationRate") nbErrors++;
bTraitsFile >> header; if (header != "OutputValues") nbErrors++;

Expand Down Expand Up @@ -3005,8 +3007,9 @@ int CheckTraitsFile(string indir)
while (!stopReading) {

// read and validate columns relating to stage and sex-dependency (NB no IIV here)
bTraitsFile >> inTraitType >> inSex >> inPositions >> inNbPositions >> inExpressionType >> inInitDist >> inInitParams
>> inDominanceDist >> inDominanceParams >> inIsInherited >> inMutationDist >> inMutationParams
bTraitsFile >> inTraitType >> inSex >> inPositions >> inNbPositions
>> inExpressionType >> inInitDist >> inInitParams >> inInitDomDist >> inInitDomParams
>> inIsInherited >> inMutationDist >> inMutationParams >> inDominanceDist >> inDominanceParams
>> inMutationRate >> inIsOutput;

current = CheckStageSex(whichInputFile, lineNb, simNb, prev, 0, 0, 0, 0, 0, true, false);
Expand Down Expand Up @@ -3100,24 +3103,19 @@ int CheckTraitsFile(string indir)
nbErrors++;
}

// Check InitialDistribution
// Check InitialAlleleDist
if (tr == NEUTRAL && inInitDist != "uniform") {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "InitialDistribution must be uniform for the neutral trait." << endl;
nbErrors++;
}
if (tr == GENETIC_LOAD && inInitDist != "#") {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "InitialDistribution must be blank (#) for genetic load traits." << endl;
batchLog << "InitialAlleleDist must be uniform for the neutral trait." << endl;
nbErrors++;
}
if (isDisp && inInitDist != "normal" && inInitDist != "uniform") {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "InitialDistribution must be either normal or uniform for dispersal traits." << endl;
batchLog << "InitialAlleleDist must be either normal or uniform for dispersal traits." << endl;
nbErrors++;
}

// Check InitialParameters
// Check InitialAlleleParams
const regex patternParamsUnif{ "^\"?min=[-]?([0-9]*[.])?[0-9]+,max=[-]?([0-9]*[.])?[0-9]+\"?$" };
const regex patternParamsNormal{ "^\"?mean=[-]?([0-9]*[.])?[0-9]+,sd=[-]?([0-9]*[.])?[0-9]+\"?$" };
const regex patternParamsGamma{ "^\"?shape=[-]?([0-9]*[.])?[0-9]+,scale=[-]?([0-9]*[.])?[0-9]+\"?$" };
Expand All @@ -3129,7 +3127,7 @@ int CheckTraitsFile(string indir)
isMatch = regex_search(inInitParams, patternParamsNeutral);
if (!isMatch) {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "For neutral trait with uniform initialisation, InitialParameters must have form max=int" << endl;
batchLog << "For neutral trait with uniform initialisation, InitialAlleleParams must have form max=int" << endl;
nbErrors++;
}
else {
Expand All @@ -3144,103 +3142,135 @@ int CheckTraitsFile(string indir)
// if not uniform then initDist must be blank, no params
else {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "For neutral trait with uniform initialisation, InitialParameters must have form max=int" << endl;
batchLog << "For neutral trait with uniform initialisation, InitialAlleleParams must have form max=int" << endl;
nbErrors++;
}
}
if (tr == GENETIC_LOAD && inInitParams != "#") {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "For genetic load traits, InitialParameters must be blank (#)" << endl;
nbErrors++;
}

if (isDisp) {
if (inInitDist == "uniform") {
isMatch = regex_search(inInitParams, patternParamsUnif);
if (!isMatch) {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "For dispersal trait uniform initialisation, InitialParameters must have form min=float,max=float" << endl;
batchLog << "For dispersal trait uniform initialisation, InitialAlleleParams must have form min=float,max=float" << endl;
nbErrors++;
}
}
else if (inInitDist == "normal") {
isMatch = regex_search(inInitParams, patternParamsNormal);
if (!isMatch) {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "For normal initialisation, InitialParameters must have form mean=float,sd=float" << endl;
batchLog << "For normal initialisation, InitialAlleleParams must have form mean=float,sd=float" << endl;
nbErrors++;
}
}
}

// Check DominanceDistribution and DominanceParameters
if (tr == NEUTRAL) {
if (inDominanceDist != "#") {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "DominanceDistribution must be left blank (#) for the neutral trait." << endl;
nbErrors++;
if (tr == GENETIC_LOAD) {
if (inInitDist == "uniform") {
isMatch = regex_search(inInitParams, patternParamsUnif);
if (!isMatch) {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "For a uniform distribution, InitialAlleleParams must have form min=float,max=float." << endl;
nbErrors++;
}
}
if (inDominanceParams != "#") {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "DominanceParameters must be left blank (#) for the neutral trait." << endl;
nbErrors++;
else if (inInitDist == "normal") {
isMatch = regex_search(inInitParams, patternParamsNormal);
if (!isMatch) {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "For a normal distribution, InitialAlleleParams must have form mean=float,sd=float." << endl;
nbErrors++;
}
}
}
if (isDisp) {
if (inDominanceDist != "#") {
else if (inInitDist == "gamma") {
isMatch = regex_search(inInitParams, patternParamsGamma);
if (!isMatch) {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "For a Gamma distribution, InitialAlleleParams must have form shape=float,scale=float." << endl;
nbErrors++;
}
}
else if (inInitDist == "negExp") {
isMatch = regex_search(inInitParams, patternParamsMean);
if (!isMatch) {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "For a negative exponential distribution, InitialAlleleParams must have form mean=float." << endl;
nbErrors++;
}
}
else if (inInitDist == "#" && inInitParams != "#") {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "DominanceDistribution must be left blank (#) for dispersal traits." << endl;
batchLog << "If InitialAlleleDist is left blank, InitialAlleleParams must also be blank." << endl;
nbErrors++;
}
if (inDominanceParams != "#") {
else {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "DominanceParameters must be left blank (#) for dispersal traits." << endl;
batchLog << "For genetic load traits, InitialAlleleDist must be either blank (#), uniform, gamma, negExp or normal" << endl;
nbErrors++;
}
}
if (tr == GENETIC_LOAD) {
if (inDominanceDist == "normal") {
isMatch = regex_search(inDominanceParams, patternParamsNormal);

// Check InitialDomDist and InitialDomParams
if ((isDisp || tr == NEUTRAL)
&& (inInitDomDist != "#" || inInitDomParams != "#")){
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "InitialDomDist and InitialDomParams must be blank (#) for dispersal and neutral traits." << endl;
nbErrors++;
}
else if (tr == GENETIC_LOAD) {
if (inInitDomDist == "normal") {
isMatch = regex_search(inInitDomParams, patternParamsNormal);
if (!isMatch) {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "For a normal dominance distribution, DominanceParams must have form mean=float,sd=float" << endl;
batchLog << "For a normal dominance distribution, InitialDomParams must have form mean=float,sd=float" << endl;
nbErrors++;
}
}
else if (inDominanceDist == "gamma") {
isMatch = regex_search(inDominanceParams, patternParamsGamma);
else if (inInitDomDist == "gamma") {
isMatch = regex_search(inInitDomParams, patternParamsGamma);
if (!isMatch) {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "For a Gamma dominance distribution, DominanceParams must have form shape=float,scale=float" << endl;
batchLog << "For a Gamma dominance distribution, InitialDomParams must have form shape=float,scale=float" << endl;
nbErrors++;
}
}
else if (inDominanceDist == "uniform") {
isMatch = regex_search(inDominanceParams, patternParamsUnif);
else if (inInitDomDist == "uniform") {
isMatch = regex_search(inInitDomParams, patternParamsUnif);
if (!isMatch) {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "For a uniform dominance distribution, DominanceParams must have form min=float,max=float" << endl;
batchLog << "For a uniform dominance distribution, InitialDomParams must have form min=float,max=float" << endl;
nbErrors++;
}
}
else if (inDominanceDist == "negExp") {
isMatch = regex_search(inDominanceParams, patternParamsMean);
else if (inInitDomDist == "negExp") {
isMatch = regex_search(inInitDomParams, patternParamsMean);
if (!isMatch) {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "For a negative exponential dominance distribution, DominanceParams must have form mean=float" << endl;
batchLog << "For a negative exponential dominance distribution, InitialDomParams must have form mean=float" << endl;
nbErrors++;
}
}
else if (inDominanceDist == "scaled") {
isMatch = regex_search(inDominanceParams, patternParamsMean);
else if (inInitDomDist == "scaled") {
if (inInitDist == "#") {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "Initial scaled dominance distribution requires InitialAlleleDist to be non-blank." << endl;
nbErrors++;
}
isMatch = regex_search(inInitDomParams, patternParamsMean);
if (!isMatch) {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "For a scaled dominance distribution, DominanceParams must have form mean=float" << endl;
batchLog << "For a scaled dominance distribution, InitialDomParams must have form mean=float" << endl;
nbErrors++;
}
}
else if (inInitDomDist == "#" && inInitDomParams != "#") {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "If InitialDomDist is left blank, InitialDomParams must also be blank." << endl;
nbErrors++;
}
else {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "DominanceDistribution must be either normal, gamma, uniform, negExp or scaled for genetic load traits." << endl;
batchLog << "InitialDomDist must be either blank (#), normal, gamma, uniform, negExp or scaled for genetic load traits." << endl;
nbErrors++;
}
}
Expand Down Expand Up @@ -3365,6 +3395,79 @@ int CheckTraitsFile(string indir)
}
}

// Check DominanceDistribution and DominanceParameters
if (tr == NEUTRAL) {
if (inDominanceDist != "#") {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "DominanceDistribution must be left blank (#) for the neutral trait." << endl;
nbErrors++;
}
if (inDominanceParams != "#") {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "DominanceParameters must be left blank (#) for the neutral trait." << endl;
nbErrors++;
}
}
if (isDisp) {
if (inDominanceDist != "#") {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "DominanceDistribution must be left blank (#) for dispersal traits." << endl;
nbErrors++;
}
if (inDominanceParams != "#") {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "DominanceParameters must be left blank (#) for dispersal traits." << endl;
nbErrors++;
}
}
if (tr == GENETIC_LOAD) {
if (inDominanceDist == "normal") {
isMatch = regex_search(inDominanceParams, patternParamsNormal);
if (!isMatch) {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "For a normal dominance distribution, DominanceParams must have form mean=float,sd=float" << endl;
nbErrors++;
}
}
else if (inDominanceDist == "gamma") {
isMatch = regex_search(inDominanceParams, patternParamsGamma);
if (!isMatch) {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "For a Gamma dominance distribution, DominanceParams must have form shape=float,scale=float" << endl;
nbErrors++;
}
}
else if (inDominanceDist == "uniform") {
isMatch = regex_search(inDominanceParams, patternParamsUnif);
if (!isMatch) {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "For a uniform dominance distribution, DominanceParams must have form min=float,max=float" << endl;
nbErrors++;
}
}
else if (inDominanceDist == "negExp") {
isMatch = regex_search(inDominanceParams, patternParamsMean);
if (!isMatch) {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "For a negative exponential dominance distribution, DominanceParams must have form mean=float" << endl;
nbErrors++;
}
}
else if (inDominanceDist == "scaled") {
isMatch = regex_search(inDominanceParams, patternParamsMean);
if (!isMatch) {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "For a scaled dominance distribution, DominanceParams must have form mean=float" << endl;
nbErrors++;
}
}
else {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "DominanceDistribution must be either normal, gamma, uniform, negExp or scaled for genetic load traits." << endl;
nbErrors++;
}
}

if (inIsOutput != "TRUE" && inIsOutput != "FALSE") {
BatchError(whichInputFile, lineNb, 0, " ");
batchLog << "OutputValues must be either TRUE or FALSE." << endl;
Expand Down Expand Up @@ -4918,41 +5021,47 @@ void setUpSpeciesTrait(vector<string> parameters) {
const set<int> positions = stringToLoci(parameters[3], parameters[4], genomeSize);
const ExpressionType expressionType = stringToExpressionType(parameters[5]);

// Initial distribution parameters
// Initial allele distribution parameters
const DistributionType initDist = stringToDistributionType(parameters[6]);
const map<GenParamType, float> initParams = stringToParameterMap(parameters[7]);

// Dominance distribution parameters
const DistributionType dominanceDist = stringToDistributionType(parameters[8]);
const map<GenParamType, float> dominanceParams = stringToParameterMap(parameters[9]);
// Initial dominance distribution parameters
const DistributionType initDomDist = stringToDistributionType(parameters[8]);
const map<GenParamType, float> initDomParams = stringToParameterMap(parameters[9]);

// Mutation parameters
bool isInherited = (parameters[10] == "TRUE");
DistributionType mutationDistribution = isInherited ?
stringToDistributionType(parameters[11]) :
DistributionType::NONE;
map<GenParamType, float> mutationParameters;
float mutationRate = isInherited ? stof(parameters[13]) : 0.0;
if (isInherited) {
mutationParameters = stringToParameterMap(parameters[12]);
}

int ploidy = gNbSexesDisp;
parameters[14].erase(
// Dominance distribution parameters
const DistributionType dominanceDist = stringToDistributionType(parameters[13]);
const map<GenParamType, float> dominanceParams = stringToParameterMap(parameters[14]);

float mutationRate = isInherited ? stof(parameters[15]) : 0.0;

parameters[16].erase(
// send windows line endings to hell where they belong
remove(parameters[14].begin(), parameters[14].end(), '\r'),
parameters[14].end()
remove(parameters[16].begin(), parameters[16].end(), '\r'),
parameters[16].end()
);
const bool isOutput = parameters[14] == "TRUE";
const bool isOutput = parameters[16] == "TRUE";

// Create species trait
int ploidy = gNbSexesDisp;
unique_ptr<SpeciesTrait> trait(new SpeciesTrait(
traitType, sex,
positions, expressionType,
initDist, initParams,
dominanceDist, dominanceParams,
initDomDist, initDomParams,
isInherited, mutationRate,
mutationDistribution, mutationParameters,
dominanceDist, dominanceParams,
ploidy,
isOutput
));
Expand Down
Loading

0 comments on commit 2e91e82

Please sign in to comment.