Nemo  2.4.0b
Simulate forward-in-time genetic evolution in a spatially explicit, individual-based stochastic simulator
GeneticMap Class Reference

GeneticMap. More...

#include <ttrait_with_map.h>

+ Collaboration diagram for GeneticMap:

Public Member Functions

 GeneticMap ()
 
 ~GeneticMap ()
 
bool getGeneticMap (trait_t trait, double **table, unsigned int table_length)
 
double getResolution ()
 
double setResolution (double val)
 
void rescaleMap (double val)
 
void reset_tables ()
 
void clear ()
 
void setLookupTable (unsigned int idx)
 Bbuilds the lookup table for each trait. More...
 
void recombine (sex_t SEX)
 Called by TTProtoWithMap::recombine twice to create the two gametes necessary for the creation of a new individual. More...
 
vector< pair< unsigned int, unsigned int > > reduceJunctions (sex_t SEX, unsigned int trait_idx)
 Remove multiple x-over at the same locus when traits differ in number of loci. More...
 
bool registerIndForRecombine (unsigned long ID)
 Called by TTProtoWithMap::recombine with individual ID passed down from Individual::recombine. More...
 
unsigned int addTrait (trait_t trait, unsigned int nChrm, unsigned int nLoc, unsigned int *nLocChrm, double resolution, unsigned int *locPositions)
 Returns the table index for the registered trait. More...
 
void unregisterTrait (trait_t trait)
 
bool checkRegisteredTrait (trait_t trait)
 Returns true if trait 'trait' has registered a genetic map, false otherwise. More...
 
vector< unsigned int > & getRecLoci (sex_t SEX, unsigned int trait)
 Returns a vector of the loci where crossing-overs take place. More...
 
vector< bool > & getFirstRecPosition (sex_t SEX)
 Returns the vector of the first chromosome position for recombination, used for all traits. More...
 
unsigned int * getLocusPositionTable (trait_t trait)
 

Private Attributes

unsigned long _currentIndividual
 
map< trait_t, unsigned int > _traits
 Table mapping trait type to its position index in the following tables. More...
 
unsigned int _nTrait
 Number of traits registered in the map. More...
 
vector< unsigned int * > _lociLookupTable
 A list of tables that map the map position (cM) to a locus, for each trait. More...
 
vector< unsigned int > _numChrsmPerTrait
 Vector of number of chromosomes for each trait. More...
 
vector< unsigned int > _numLociPerTrait
 Vector of number of loci for each trait. More...
 
vector< unsigned int * > _numLociPerChrsmPerTrait
 Vector containing a table of number of loci per chromosome for each trait. More...
 
vector< unsigned int * > _locPositionsPerTrait
 Vector containing the table of map position for the loci of each trait. More...
 
vector< vector< unsigned int > > _recPositions [2]
 Vector of tables containing, for each trait, the locus number at which x-overs happen. More...
 
vector< bool > _chrsmFirstRecombPosition [2]
 Two vectors holding the starting copy of each chromosome to use when creating the two gametes that are used to create a new individual. More...
 
vector< unsigned int > _junctions
 A vector to store the position of the recombination events. More...
 
unsigned int _numChromosome
 
unsigned int * _perChrsmLength
 
unsigned int * _chrsmFirstLocusPosition
 
unsigned int _totalLength
 
unsigned int _recombLength
 
unsigned int _totalNumLoci
 
double _resolution
 
double _totRecombEventsMean
 
double _recombinationRate
 

Detailed Description

Constructor & Destructor Documentation

◆ GeneticMap()

GeneticMap::GeneticMap ( )
inline
unsigned int _nTrait
Number of traits registered in the map.
Definition: ttrait_with_map.h:56
unsigned int _recombLength
Definition: ttrait_with_map.h:88
double _recombinationRate
Definition: ttrait_with_map.h:92
double _totRecombEventsMean
Definition: ttrait_with_map.h:91
unsigned int * _chrsmFirstLocusPosition
Definition: ttrait_with_map.h:86
unsigned int _totalLength
Definition: ttrait_with_map.h:87
unsigned int * _perChrsmLength
Definition: ttrait_with_map.h:85
unsigned int _numChromosome
Definition: ttrait_with_map.h:84
unsigned int _totalNumLoci
Definition: ttrait_with_map.h:89
double _resolution
Definition: ttrait_with_map.h:90
unsigned long _currentIndividual
Definition: ttrait_with_map.h:50

◆ ~GeneticMap()

GeneticMap::~GeneticMap ( )
inline
102 {reset_tables();}
void reset_tables()
Definition: ttrait_with_map.cc:1269

References reset_tables().

Member Function Documentation

◆ addTrait()

unsigned int GeneticMap::addTrait ( trait_t  trait,
unsigned int  nChrm,
unsigned int  nLoc,
unsigned int *  nLocChrm,
double  resolution,
unsigned int *  locPositions 
)

Returns the table index for the registered trait.

671 {
672  map<trait_t, unsigned int>::iterator tIter;
673 
674  unsigned int traitIdx = 0;
675 
676  bool do_add = true;
677 
678  tIter = _traits.find(trait);
679 
680  if ( tIter != _traits.end() ) {
681  //this shouldn't happen... unless we are loading a pop from source!!
682 
683  traitIdx = tIter->second;
684 
685  if(_numChrsmPerTrait[traitIdx] != nChrm)
686  fatal("mismatch while loading source population and resetting genetic map for trait \"%s\" \n\
687 >>>>> number of chromosomes differ (%i != %i)\n\
688 >>>>> please check match between init file and source population\n",trait.c_str(),_numChrsmPerTrait[traitIdx],nChrm);
689 
690  if(_numLociPerTrait[traitIdx] != nLoc)
691  fatal("mismatch while loading source population and resetting genetic map for trait \"%s\"\n\
692 >>>>> number of loci differ (%i != %i)\n\
693 >>>>> please check match between init file and source population\n",trait.c_str(),_numLociPerTrait[traitIdx], nLoc);
694 
695  unsigned int *locTable = _numLociPerChrsmPerTrait[traitIdx];
696 
697  for (unsigned int i=0; i<nChrm; i++)
698  if(locTable[i] != nLocChrm[i])
699  fatal("mismatch while loading source population and resetting genetic map for trait \"%s\"\n\
700 >>>>> number of loci differ (%i != %i) on chromosome %i\n\
701 >>>>> please check match between init file and source population\n",trait.c_str(),locTable[i], nLocChrm[i], i+1);
702 
703  do_add = false;
704 
705  }
706 
707 #ifdef _DEBUG_
708  cout << "GeneticMap::addTrait: \n";
709  cout << " _numChromosome = "<<nChrm<<endl;
710  cout << " _totalNumLoci = "<<_totalNumLoci<<endl;
711  cout << " _resolution = "<<_resolution<<endl;
712  cout << " _totalLength = "<<_totalLength<<endl;
713  cout << ":::"<<trait<<"::: params:\n";
714  cout << " num chromosome = "<<nChrm<<endl;
715  cout << " num loci = "<<nLoc<<endl;
716  cout << " map resolution = "<<resolution<<endl;
717 #endif
718 
719  if (_nTrait == 0) { //this is the first trait to register its map
720 
721  _numChromosome = nChrm;
722  _totalNumLoci = nLoc;
723  _resolution = resolution;
724  _totalLength = locPositions[nLoc-1];
725 
726  //destroy all previously allocated tables
727  reset_tables();
728 
729  _perChrsmLength = new unsigned int[_numChromosome];
730  _chrsmFirstLocusPosition = new unsigned int[_numChromosome];
731 
732  } else {
733  //we have already registered some trait's genetic map, we append this trait's info and update the map
734 
735  if (nChrm != _numChromosome) //check chromosome numbers
736  fatal("Traits in init file don't have same number of chromosomes, cannot set the genetic map!\n");
737 
738  //number of loci
739  _totalNumLoci = max(_totalNumLoci, nLoc);
740 
741  //setting the resolution:
742  if (resolution < _resolution) {
743 
744 // cout << "GeneticMap::addTrait: rescaling map resolution (old "<< _resolution << "; new "<< resolution<< ")\n";
745 
746  rescaleMap(resolution);
747 
748  } else if (resolution > _resolution) {
749 
750 // cout << "GeneticMap::addTrait: rescaling locus position (old "<< _resolution << "; new "<< resolution<< "; ratio "<< resolution/_resolution <<")\n";
751 
752  double ratio = resolution/_resolution;
753 
754  for(unsigned int i = 0; i < nLoc; ++i)
755  locPositions[i] = (unsigned int)((double)locPositions[i]*ratio);
756  }
757 
758  }
759 
760  if(do_add) { //only at the start of a simulation, not when loading pop from binary source
761 
762  traitIdx = _nTrait;
763 
764  _traits[trait] = _nTrait++;
765 
766 
767  //---- record num chrmsm
768  if ( _numChrsmPerTrait.size() != _nTrait -1 ) {
769  fatal("Genetic map::wrong size of table of num chrms per trait (%i != %i)",
770  _numChrsmPerTrait.size(), _nTrait -1);
771  } else
772  _numChrsmPerTrait.push_back(nChrm);
773 
774  //---- record num loci
775  if ( _numLociPerTrait.size() != _nTrait -1 ) {
776  fatal("Genetic map::wrong size of table of num loci per trait (%i != %i)",
777  _numLociPerTrait.size(), _nTrait -1);
778  } else
779  _numLociPerTrait.push_back(nLoc);
780 
781  //---- record table of num loci per chrmsm
782  if ( _numLociPerChrsmPerTrait.size() != _nTrait -1 )
783  fatal("Genetic map::wrong size of table of num loci per chrms per trait (%i != %i)",
785 
786  unsigned int* locTable = new unsigned int[nChrm];
787 
788  for (unsigned int i = 0; i < nChrm; i++) locTable[i] = nLocChrm[i];
789 
790  _numLociPerChrsmPerTrait.push_back(locTable);
791 
792  //---- record the locus positions
793  if ( _locPositionsPerTrait.size() != _nTrait -1 ) {
794  fatal("Genetic map::wrong size of table of loc position per trait (%i != %i)",
795  _locPositionsPerTrait.size(), _nTrait-1);
796  }
797 
798  //copy the locus positions, they are at the correct resolution already
799  unsigned int* posTable = new unsigned int[nLoc];
800 
801  for (unsigned int i = 0; i < nLoc; ++i) {
802  posTable[i] = locPositions[i];
803  }
804 
805  _locPositionsPerTrait.push_back(posTable);
806 
807 
808  //---- create tables to record positions of x-over, for each gamete (male and female)
809 
810  for(unsigned int s = 0; s < 2; ++s){
811  if ( _recPositions[s].size() != _nTrait -1 )
812  fatal("Genetic map::wrong size of rec positions table (%i != %i)",
813  _recPositions[s].size(), _nTrait-1);
814 
815  _recPositions[s].push_back(vector<unsigned int>()); //add an empty array for each trait
816  }
817 
818 
819  //---- set the map positions according to other trait's
820  //---- need to correctly set starting position and length of each chromosome
821 
822  if (_nTrait == 1) { //first trait to register
823 
824  for (unsigned int c = 0, stride = 0; c < _numChromosome; ++c) {
825  _chrsmFirstLocusPosition[c] = locPositions[stride];
826  _perChrsmLength[c] = locPositions[stride + nLocChrm[c] - 1] - locPositions[stride]; //position of last locus - position of first locus on that chromosome.
827  stride += nLocChrm[c];
828  }
829 
830  } else {
831 
832  for (unsigned int c = 0, lastPos, stride = 0; c < _numChromosome; ++c) {
833 
834  lastPos = max(locPositions[stride + nLocChrm[c] - 1],
836 
837  _chrsmFirstLocusPosition[c] = min(_chrsmFirstLocusPosition[c], locPositions[stride]);
838 
839  _perChrsmLength[c] = lastPos - _chrsmFirstLocusPosition[c];
840 
841  stride += nLocChrm[c];
842  }
843  }
844 
845  //---- compute total chromosome length
846  _totalLength = 0;
847  for (unsigned int c = 0; c < _numChromosome; ++c) _totalLength += _perChrsmLength[c];
848 
849  //---- mean num recombination events, map length of 1M = 1 x-over on average
850  _totRecombEventsMean = (double)_totalLength * 0.01 * _resolution;
851 
852  //---- set the map size used to draw recombination spots; one less operation in recombine()...
854 
855  //---- set the recombination rate between adjacent positions on the map;
857 
858 
859 #ifdef _DEBUG_
860  cout << "GeneticMap::addTrait: "<<endl;
861  cout << " map stats for trait \""<<trait<<"\"\n";
862  cout << " _totalLength = "<<_totalLength<<endl;
863  cout << " _totRecombEventsMean = "<<_totRecombEventsMean<<endl;
864 #endif
865 
866  if(_totalLength > 9e+8)
867  warning("Your genetic map is larger than %.2fcM with %i elements, you may experience memory allocation problems\
868  as well as problems at runtime.\n",
870 
871  //---- create new slot for the lookup table of that trait
872  // will be allocated and filled in setLookupTable
873  if ( _lociLookupTable.size() != _nTrait -1 )
874  fatal("Genetic map::wrong size of loci lookup tables (%i != %i)",
875  _lociLookupTable.size(), _nTrait-1);
876 
877  _lociLookupTable.push_back(NULL);
878 
879  //---- set all lookup tables (all genetic maps):
880  // we reset all tables each time a trait is added because _totalLength changes
881  for (unsigned int t = 0; t < _nTrait; ++t) setLookupTable(t);
882  }
883 
884  return traitIdx;
885 }
void setLookupTable(unsigned int idx)
Bbuilds the lookup table for each trait.
Definition: ttrait_with_map.cc:948
vector< unsigned int > _numLociPerTrait
Vector of number of loci for each trait.
Definition: ttrait_with_map.h:65
vector< unsigned int * > _lociLookupTable
A list of tables that map the map position (cM) to a locus, for each trait.
Definition: ttrait_with_map.h:61
vector< unsigned int > _numChrsmPerTrait
Vector of number of chromosomes for each trait.
Definition: ttrait_with_map.h:63
vector< unsigned int * > _locPositionsPerTrait
Vector containing the table of map position for the loci of each trait.
Definition: ttrait_with_map.h:70
vector< vector< unsigned int > > _recPositions[2]
Vector of tables containing, for each trait, the locus number at which x-overs happen.
Definition: ttrait_with_map.h:75
vector< unsigned int * > _numLociPerChrsmPerTrait
Vector containing a table of number of loci per chromosome for each trait.
Definition: ttrait_with_map.h:67
map< trait_t, unsigned int > _traits
Table mapping trait type to its position index in the following tables.
Definition: ttrait_with_map.h:53
void rescaleMap(double val)
Definition: ttrait_with_map.cc:919
void fatal(const char *str,...)
Definition: output.cc:96
void warning(const char *str,...)
Definition: output.cc:58

References _chrsmFirstLocusPosition, _lociLookupTable, _locPositionsPerTrait, _nTrait, _numChromosome, _numChrsmPerTrait, _numLociPerChrsmPerTrait, _numLociPerTrait, _perChrsmLength, _recombinationRate, _recombLength, _recPositions, _resolution, _totalLength, _totalNumLoci, _totRecombEventsMean, _traits, fatal(), rescaleMap(), reset_tables(), setLookupTable(), and warning().

Referenced by TTProtoWithMap::registerGeneticMap().

◆ checkRegisteredTrait()

bool GeneticMap::checkRegisteredTrait ( trait_t  trait)

Returns true if trait 'trait' has registered a genetic map, false otherwise.

Parameters
traitThe trait name to check for in the trait table.
649 {
650  map<trait_t, unsigned int>::iterator tIter = _traits.find(trait);
651 
652  return ( tIter != _traits.end() );
653 }

References _traits.

Referenced by TTQuantiFH::setOutputOption().

◆ clear()

void GeneticMap::clear ( )
658 {
659  reset_tables();
660  _traits.clear();
661  _nTrait = 0;
662 }

References _nTrait, _traits, and reset_tables().

Referenced by IndFactory::clearPrototype().

◆ getFirstRecPosition()

vector< bool >& GeneticMap::getFirstRecPosition ( sex_t  SEX)
inline

Returns the vector of the first chromosome position for recombination, used for all traits.

172  { return _chrsmFirstRecombPosition[SEX]; }
vector< bool > _chrsmFirstRecombPosition[2]
Two vectors holding the starting copy of each chromosome to use when creating the two gametes that ar...
Definition: ttrait_with_map.h:79

References _chrsmFirstRecombPosition.

◆ getGeneticMap()

bool GeneticMap::getGeneticMap ( trait_t  trait,
double **  table,
unsigned int  table_length 
)
890 {
891  map< trait_t, unsigned int>::const_iterator ITER = _traits.find(trait);
892 
893  if(ITER == _traits.end())
894  return(error("GeneticMap::getGeneticMap::failed to find trait \"%s\" in genetic map\n", trait.c_str()));
895 
896  unsigned int idx = ITER->second;
897 
898  assert(table_length == _numLociPerTrait[idx]);
899 
900  unsigned int chr = 0, loc_cnt = _numLociPerChrsmPerTrait[idx][0];
901 
902  for(unsigned int i = 0; i < table_length; ++i) {
903 
904  if(i >= loc_cnt) {
905  chr++;
906  loc_cnt += _numLociPerChrsmPerTrait[idx][chr];
907  }
908 
909  table[i][0] = chr;
910  table[i][1] = _locPositionsPerTrait[idx][i];
911 
912  }
913 
914  return true;
915 }
int error(const char *str,...)
Definition: output.cc:77

References _locPositionsPerTrait, _numLociPerChrsmPerTrait, _numLociPerTrait, _traits, and error().

Referenced by TTNeutralGenesFH::write_PLINK(), and TTQuantiFH::write_PLINK().

◆ getLocusPositionTable()

unsigned int* GeneticMap::getLocusPositionTable ( trait_t  trait)
inline
175  {return _locPositionsPerTrait[ _traits[ trait ] ];}

References _locPositionsPerTrait, and _traits.

◆ getRecLoci()

vector< unsigned int>& GeneticMap::getRecLoci ( sex_t  SEX,
unsigned int  trait 
)
inline

Returns a vector of the loci where crossing-overs take place.

166  {
167  return _recPositions[SEX][trait];
168  }

References _recPositions.

◆ getResolution()

double GeneticMap::getResolution ( )
inline
106 {return _resolution;}

References _resolution.

Referenced by TTProtoWithMap::recordRandomMap().

◆ recombine()

void GeneticMap::recombine ( sex_t  SEX)

Called by TTProtoWithMap::recombine twice to create the two gametes necessary for the creation of a new individual.

This function sets the location of the x-over on the chromosome map and records the loci positions at which x-over happen for each trait separately. The positions are stored in GeneticMap::_recPositions, which are then passed to the trait-specific inheritance functions when setting up the genetics of the traits in new individuals.

Parameters
SEXthe origin of the gamete, whether from the father or the mother
1076 {
1077  unsigned int nbRec = 0;
1078 
1079 
1080  //empty the array of x-over positions
1081  for (unsigned int t = 0; t < _nTrait; t++) {
1082  _recPositions[SEX][t].clear();
1083  }
1084 
1085  //create a gamete:
1086 
1087  //draw the number of x-over depending on the total map size
1088  nbRec = (unsigned int)RAND::Poisson( _totRecombEventsMean );
1089 
1090 // nbRec = (unsigned int)RAND::Binomial( _recombinationRate , _totalLength );
1091 // call to Poisson() is faster
1092 
1093 #ifdef _REC_DEBUG_
1094  cout << "\n@@@ GeneticMap::recombine( SEX = "<<SEX<<" nbRec = "<<nbRec<<")"<<endl;
1095 #endif
1096 
1097  //adjust
1098  if(nbRec > _totalNumLoci - 1) nbRec = _totalNumLoci - 1;
1099 
1100  //now determine where the x-over will take place
1101  if(nbRec > 0) {
1102 
1103  //reset the list of recombination events.
1104  _junctions.resize(nbRec);
1105 
1106  auto drawRecPosition = [this](unsigned int& n){n = (unsigned int)(RAND::Uniform()*_recombLength);};
1107 
1108  //draw the positions
1109  for_each(_junctions.begin(), _junctions.end(), drawRecPosition);
1110 
1111  //sort them
1112  sort(_junctions.begin(), _junctions.end());
1113 
1114 #ifdef _REC_DEBUG_
1115  cout<< " --- sorted junctions ("<< _junctions.size()<<"): ";
1116  auto print = [this](unsigned int& n){cout<<" "<<n;};
1117  for_each(_junctions.begin(), _junctions.end(), print);
1118  cout<<endl;
1119 #endif
1120 
1121  //remove the duplicates, we keep only one when that happens (in principle very rarely):
1122  auto last = unique(_junctions.begin(), _junctions.end());
1123 
1124 
1125  // UPDATE NUMBER OF RECOMBINATION EVENTS
1126 
1127  nbRec = last - _junctions.begin(); // these are the unique x-over map positions
1128 
1129 #ifdef _REC_DEBUG_
1130  cout<<" --- after removing duplicates ("<< last - _junctions.begin()<<"): ";
1131  for_each(_junctions.begin(), last, print);
1132  cout<<endl;
1133 
1134  cout<<" --- computing rec map position: \n";
1135 #endif
1136 
1137  size_t pos;
1138 
1139  for (unsigned int t = 0; t < _nTrait; t++) {
1140 
1141 #ifdef _REC_DEBUG_
1142  cout<<" trait "<< t << endl;
1143 #endif
1144 
1145  for(unsigned int i = 0, hit; i < nbRec; ++i) {
1146 
1147  pos = _junctions[i];
1148 
1149  hit = _lociLookupTable[t][pos];
1150 
1151  _recPositions[SEX][t].push_back( hit );
1152 
1153 
1154 #ifdef _REC_DEBUG_
1155  cout<< " ["<<i<<"] @"<<pos<<" -> loc "<< hit <<"\n";
1156 #endif
1157 
1158  }// end_for_bRec
1159  }// end_for_traits
1160  } // end_if_nbRec
1161 
1162  // we always add the last position possible, to avoid returning an empty vector
1163  for (unsigned int t = 0; t < _nTrait; t++) {
1164  _recPositions[SEX][t].push_back(_numLociPerTrait[t]);
1165  }
1166 
1167  //set the starting point for each chromosome randomly (which chromosome copy to use first)
1168 
1169  _chrsmFirstRecombPosition[SEX].assign(_numChromosome, 0); //re-initialise the array
1170 
1171  for(unsigned int c = 0; c < _numChromosome; ++c) {
1173  }
1174 
1175 }
vector< unsigned int > _junctions
A vector to store the position of the recombination events.
Definition: ttrait_with_map.h:82
static double Poisson(double mean)
From the Numerical Recieps.
Definition: Uniform.h:219
static double Uniform()
Generates a random number from [0.0, 1.0[ uniformly distributed.
Definition: Uniform.h:124
static bool RandBool()
Returns a random boolean.
Definition: Uniform.h:162

References _chrsmFirstRecombPosition, _junctions, _lociLookupTable, _nTrait, _numChromosome, _numLociPerTrait, _recombLength, _recPositions, _totalNumLoci, _totRecombEventsMean, RAND::Poisson(), RAND::RandBool(), and RAND::Uniform().

Referenced by TTProtoWithMap::recombine().

◆ reduceJunctions()

vector< pair< unsigned int, unsigned int > > GeneticMap::reduceJunctions ( sex_t  SEX,
unsigned int  trait_idx 
)

Remove multiple x-over at the same locus when traits differ in number of loci.

1180 {
1181  unsigned int prevLoc = 0, cEnd = 0;
1182  bool flipper;
1183  //number of x-overs
1184  vector< unsigned int >& recTable = _recPositions[SEX][trait_idx];
1185  unsigned int nbRec = recTable.size();
1186 
1187  vector< pair<unsigned int, unsigned int> > junctions;
1188 
1189  unsigned int num_copied = 0;
1190 
1191 #ifdef _REC_DEBUG_
1192  cout << "GeneticMap::reduceJunctions; trait "<<trait_idx<< "; nb Rec = "<<nbRec - 1<<endl;
1193  cout << " --sex = "<<SEX<<"\n";
1194 #endif
1195 
1196  // c is the chromosome number
1197  // stride is the number of loci considered so-far, sum of chromosome loci
1198  // rec is the number of x-over done so-far
1199  for(unsigned int c = 0, cStart = 0, rec = 0; c < _numChromosome; ++c) {
1200 
1201  //the copy of the chromosome with which with start
1202  flipper = _chrsmFirstRecombPosition[SEX][c];
1203 
1204  //number of loci to consider, including previous chromosomes
1205  cEnd = cStart + _numLociPerChrsmPerTrait[trait_idx][c] ;
1206 
1207  //last locus at which a x-over happened, will be first position on current chromosome
1208  prevLoc = cStart;
1209 
1210  num_copied = 0;
1211 
1212 #ifdef _REC_DEBUG_
1213  cout<<" --chrm "<<c<<", start="<<cStart<<", end="<<cEnd<<" (rec="<<rec<<"; rec pos = "
1214  <<recTable[rec]<<")"<<", side="<<flipper<<endl;
1215 #endif
1216 
1217  // zip forward if x-over on previous chrm were past the last locus on previous chrm
1218  // we need to catch up with position in the current chrm without changing the flipper
1219  while(recTable[rec] == cStart) rec++;
1220 
1221  // copy blocs of loci between x-over points on current chromosome
1222  // skip x-over if locus is not on this chromosome but a latter one (junction pos > cEnd)
1223  for(; recTable[rec] < cEnd && rec < nbRec; rec++) {
1224 
1225  //skip recombination events that would lead to copying 0 byte because even num x-over at same locus
1226  if(recTable[rec] == prevLoc){
1227  //but switch side for next bloc to copy on this chromosome
1228  //absolutely necessary to be in sync with other traits on the map
1229  flipper = !flipper;
1230  continue;
1231  }
1232 
1233 
1234 #ifdef _REC_DEBUG_
1235  cout<< " ["<<rec<<"] junction "<<recTable[rec]<< " on side "<<flipper<<std::endl;
1236 #endif
1237 
1238  junctions.push_back(pair<unsigned int, unsigned int>(recTable[rec], flipper));
1239 
1240  num_copied += recTable[rec] - prevLoc;
1241 
1242  //update the starting locus to the next recombination point
1243  prevLoc = recTable[rec];
1244 
1245  //switch side for next bloc to copy on this chromosome
1246  flipper = !flipper;
1247  }
1248 
1249 #ifdef _REC_DEBUG_
1250  cout << " --copy til end of chrmsm from "<<prevLoc<<" to "<<cEnd<<" on side "<<flipper<<endl;
1251 #endif
1252 
1253  num_copied += cEnd - prevLoc;
1254 
1255  junctions.push_back(pair<unsigned int, unsigned int>(cEnd, flipper));
1256 
1257  if(num_copied != _numLociPerChrsmPerTrait[trait_idx][c])
1258  error("number of loci copied on chromosome %i is %i != %i\n", c, num_copied, _numLociPerChrsmPerTrait[trait_idx][c]);
1259 
1260  cStart += _numLociPerChrsmPerTrait[trait_idx][c];
1261  }
1262 
1263  return junctions;
1264 }

References _chrsmFirstRecombPosition, _numChromosome, _numLociPerChrsmPerTrait, _recPositions, and error().

Referenced by TProtoBDMI::inherit_low(), TProtoDeletMutations_bitstring::inherit_low(), TProtoQuanti::inherit_low(), and TProtoNeutralGenes::inherit_low().

◆ registerIndForRecombine()

bool GeneticMap::registerIndForRecombine ( unsigned long  ID)
inline

Called by TTProtoWithMap::recombine with individual ID passed down from Individual::recombine.

Returns false when already called by the same individual. The function is called for each trait separately but recombination must be computed once per individual only. It is so because some functions create new individual's trait separately, for instance in breed_selection when traits under viability selection are created before neutral traits.

Parameters
IDthe ID number of the individual calling the recombination function
145  {
146  if (ID == _currentIndividual) return false;
147  else _currentIndividual = ID;
148  return true;
149  }

References _currentIndividual.

Referenced by TTProtoWithMap::recombine().

◆ rescaleMap()

void GeneticMap::rescaleMap ( double  val)
920 {
921  assert(val < _resolution);
922 
923  double ratio = _resolution/val; //it is assumed that val < _resolution
924 
925  _resolution = val;
926 
927  //we have to update all positions
928  for (unsigned int i = 0; i < _nTrait; ++i) {
929  for (unsigned int j = 0; j < _numLociPerTrait[i]; ++j) {
930  _locPositionsPerTrait[i][j] *= ratio;
931  }
932  }
933 
934  for (unsigned int i = 0; i < _numChromosome; ++i) {
935  _perChrsmLength[i] *= ratio;
936  _chrsmFirstLocusPosition[i] *= ratio;
937  }
938 
939  _totalLength *= ratio;
940  _totRecombEventsMean = (double)_totalLength * 0.01 * _resolution;
941 
942  //reset all lookup tables, the total length has changed!
943  for (unsigned int i = 0; i < _nTrait; ++i) setLookupTable(i);
944 }

References _chrsmFirstLocusPosition, _locPositionsPerTrait, _nTrait, _numChromosome, _numLociPerTrait, _perChrsmLength, _resolution, _totalLength, _totRecombEventsMean, and setLookupTable().

Referenced by addTrait().

◆ reset_tables()

void GeneticMap::reset_tables ( )
1270 {
1271  if(_perChrsmLength != NULL) delete [] _perChrsmLength;
1272  _perChrsmLength = NULL;
1273 
1274  if(_chrsmFirstLocusPosition != NULL) delete [] _chrsmFirstLocusPosition;
1275  _chrsmFirstLocusPosition = NULL;
1276 
1277  _numChrsmPerTrait.clear();
1278  _numLociPerTrait.clear();
1279 
1280  for (unsigned int i = 0; i < _lociLookupTable.size(); ++i) {
1281  if(_lociLookupTable[i] != NULL) delete [] _lociLookupTable[i];
1282  else error("GeneticMap::reset_tables::found null pointer in _lociLookupTable\n");
1283  }
1284  _lociLookupTable.clear();
1285 
1286  for (unsigned int i = 0; i < _numLociPerChrsmPerTrait.size(); ++i) {
1287  if(_numLociPerChrsmPerTrait[i] != NULL) delete [] _numLociPerChrsmPerTrait[i];
1288  else error("GeneticMap::reset_tables::found null pointer in _numLociPerChrsmPerTrait\n");
1289  }
1290  _numLociPerChrsmPerTrait.clear();
1291 
1292  for (unsigned int i = 0; i < _locPositionsPerTrait.size(); ++i) {
1293  if(_locPositionsPerTrait[i] != NULL) delete [] _locPositionsPerTrait[i];
1294  else error("GeneticMap::reset_tables::found null pointer in _locPositionsPerTrait\n");
1295  }
1296  _locPositionsPerTrait.clear();
1297 
1298  _recPositions[0].clear();
1299  _recPositions[1].clear();
1300 
1301  _chrsmFirstRecombPosition[0].clear();
1302  _chrsmFirstRecombPosition[1].clear();
1303 
1304 }

References _chrsmFirstLocusPosition, _chrsmFirstRecombPosition, _lociLookupTable, _locPositionsPerTrait, _numChrsmPerTrait, _numLociPerChrsmPerTrait, _numLociPerTrait, _perChrsmLength, _recPositions, and error().

Referenced by addTrait(), clear(), and ~GeneticMap().

◆ setLookupTable()

void GeneticMap::setLookupTable ( unsigned int  idx)

Bbuilds the lookup table for each trait.

A lookup table maps a chromosomal position to a locus so that when a x-over is placed at a given map position, the corresponding locus can be directly found. The size of the lookup table depends on the _totalLength and _resolution of the map. The lookup table for a 1M map at the 0.01 cM scale will have 10,000 elements.

Parameters
idxthe index of the trait in the table (stored in the trait prototype)

!!! +1 needed here because map must start with 0 !!!!

949 {
950  if(_lociLookupTable[idx] != NULL) delete [] _lociLookupTable[idx];
951 
952  _lociLookupTable[idx] = new unsigned int [_totalLength +1];
954 
955  if(_lociLookupTable[idx] == NULL)
956  fatal("GeneticMap::set lookup table: memory exhausted?\n");
957 
958  //------------------------------------------------------------------------
959  int pre_offset = 0, post_offset = 0, offset;
960 
961 // cout<<"\n-- Genetic map #"<<idx<<":"<<endl;
962 
963  for (unsigned int loc = 0, pos = 0, stride = 0,
964  c = 0; c < _numChromosome; ++c) {
965 
966 // cout<<"Chrm "<<c+1<<" ("<<_perChrsmLength[c]<<" ["<<_resolution<<"cM]):\n"<<"{ ";
967 
968  loc = stride;
969 
970  stride += _numLociPerChrsmPerTrait[idx][c];
971 
972  //the map must start with position zero for the first locus with lowest position
973  pre_offset = -_chrsmFirstLocusPosition[c];
974 
975  //chromosomes are contiguous
976  offset = pre_offset + post_offset;
977 
978  for(; loc < stride && loc < _numLociPerTrait[idx]; ++loc)
979  {
980 
981  while (pos <= ( _locPositionsPerTrait[idx][loc] + offset) &&
982  ((int)pos - post_offset) <= (int)_perChrsmLength[c])
983  //table has 1 more elmnt, hence "<="
984 
985  _lociLookupTable[idx][pos++] = loc;
986 
987 // cout << loc<<":"<<pos-1<<"("<<(int)pos - post_offset<<"; tab["<<pos-1<<"]="<<_lociLookupTable[idx][pos-1]<<") ";
988 
989  }
990 
991  post_offset += _perChrsmLength[c];
992 
993  // need to pad to the right when we reached last locus on a chromosome but not at the last map position of that chrm
994  // this must apply only to all chrm but the last, hence loc < max num loci
995  while( pos < post_offset && loc == stride && loc < _numLociPerTrait[idx])
996  {
997  _lociLookupTable[idx][pos++] = loc;
998 // cout << loc<<":"<<pos-1<<"(tab["<<pos-1<<"]="<<_lociLookupTable[idx][pos-1]<<") ";
999 
1000  }
1001 
1002  // we need to pad to the right when position of last locus is within last chromosome (chrom length set by other traits too)
1003  // pad with last locus number+1 (tot num loci) on that chromosome
1004  while (pos < _totalLength+1 && loc >= _numLociPerTrait[idx])
1005  {
1006 
1007  _lociLookupTable[idx][pos++] = _numLociPerTrait[idx];
1008 
1009 // cout << loc<<":"<<pos-1<<"(tab["<<pos-1<<"]="<<_lociLookupTable[idx][pos-1]<<") ";
1010 
1011  }
1012 // cout << "}\n";
1013  }
1014 
1015 
1016 #ifdef _DEBUG_
1017 // map< trait_t, unsigned int>::iterator ITER = _traits.begin() + idx;
1018 
1019  cout << "\nGeneticMap::setLookupTable ("<<idx<<")\n";
1020 
1021  cout << "lookup table: [";
1022  for(unsigned int i = 0; i < _totalLength+1 && i < 101; ++i) {
1023  cout << _lociLookupTable[idx][i] << " ";
1024  if( i == 100) cout << "|>100) ";
1025  }
1026  if(_totalLength >= 100) cout << "... last pos ("<<_totalLength<<") "<<_lociLookupTable[idx][_totalLength];
1027  cout << "] (truncated if > 100 positions)\n";
1028 
1029  pre_offset = 0; post_offset = 0;
1030  for(unsigned int c = 0, stride = 0; c < _numChromosome; c++) {
1031 
1032  cout<<"+++Chrm "<<c+1<<" ("<<_perChrsmLength[c]<<" ["<<_resolution<<"cM]):\n";
1033  cout << "Loc positions: [ ";
1034 
1035  for(unsigned int i = 0; i < _numLociPerChrsmPerTrait[idx][c] && i < 101; ++i){
1036  if( i < 100 || !(i % 100) )
1037  cout << _locPositionsPerTrait[idx][i+stride] << " " ;
1038  if( i == 100) cout << "|>100) ";
1039  }
1040  cout << "]\n";
1041 
1042  pre_offset = -_chrsmFirstLocusPosition[c];
1043  offset = pre_offset + post_offset;
1044 
1045  cout << "lookup table: [ ";
1046 
1047  for(unsigned int cnt=0, i = _chrsmFirstLocusPosition[c]+offset; i < _chrsmFirstLocusPosition[c]+_perChrsmLength[c]+offset && cnt < 100; ++i, ++cnt){
1048  cout << _lociLookupTable[idx][i] << " " ;
1049  }
1050  cout << "] (first 100 positions only)\n{position:locus} {";
1051 
1052  for(unsigned int i = 0; i < _numLociPerChrsmPerTrait[idx][c]-1; ++i) {
1053  if( i < 100 || !(i % 100) ) cout<<_locPositionsPerTrait[idx][i+stride]+offset<<":"<<_lociLookupTable[idx][_locPositionsPerTrait[idx][i+stride]+offset]<<", ";
1054  if( i == 100) cout << "|>100) ";
1055  }
1056  cout<<_locPositionsPerTrait[idx][stride + _numLociPerChrsmPerTrait[idx][c]-1]+offset
1057  <<":"<<_lociLookupTable[idx][_locPositionsPerTrait[idx][stride + _numLociPerChrsmPerTrait[idx][c]-1]+offset]<<"}\n";
1058 
1059  post_offset += _perChrsmLength[c];
1060  stride += _numLociPerChrsmPerTrait[idx][c];
1061  }
1062  cout<<endl;
1063 // cout<<"Loc pos lookup table:"<<endl<<"{";
1064 // for(unsigned int i = 0; i < _superChrsmLength; ++i)
1065 // cout<<_recLociPositionTable[i]<<", ";
1066 // cout<<"}"<<endl;
1067 
1068  cout<<" Tot map length: "<<_totalLength<<endl;
1069  cout<<" Mean num recombination events: "<<_totRecombEventsMean<<endl;
1070 #endif
1071 }

References _chrsmFirstLocusPosition, _lociLookupTable, _locPositionsPerTrait, _numChromosome, _numLociPerChrsmPerTrait, _numLociPerTrait, _perChrsmLength, _resolution, _totalLength, _totRecombEventsMean, and fatal().

Referenced by addTrait(), and rescaleMap().

◆ setResolution()

double GeneticMap::setResolution ( double  val)
inline
109  {
110  _resolution = (val < _resolution ? val : _resolution);
111  return _resolution;
112  }

References _resolution.

◆ unregisterTrait()

void GeneticMap::unregisterTrait ( trait_t  trait)
625 {
626  map<trait_t, unsigned int>::iterator tIter;
627 
628  tIter = _traits.find(trait);
629 
630  if ( tIter != _traits.end() ) {
631 
632 // cout<<"GeneticMap::unregisterTrait::"<<tIter->first<<" (idx: "<<tIter->second<<")"<<endl;
633 
634  _traits.erase(tIter);
635 
636  //@TODO trait lookup tables must be erased as well
637 
638 // cout<<"GeneticMap::unregisterTrait::done\n";
639  }
640  else fatal("Genetic map::unregisterTrait: trait \"%s\" is not registered\n", trait.c_str());
641 
642  _nTrait--;
643 }

References _nTrait, _traits, and fatal().

Referenced by TTProtoWithMap::reset(), and TTProtoWithMap::unregisterFromGeneticMap().

Member Data Documentation

◆ _chrsmFirstLocusPosition

unsigned int* GeneticMap::_chrsmFirstLocusPosition
private

◆ _chrsmFirstRecombPosition

vector< bool > GeneticMap::_chrsmFirstRecombPosition[2]
private

Two vectors holding the starting copy of each chromosome to use when creating the two gametes that are used to create a new individual.

Referenced by getFirstRecPosition(), recombine(), reduceJunctions(), and reset_tables().

◆ _currentIndividual

unsigned long GeneticMap::_currentIndividual
private

Referenced by registerIndForRecombine().

◆ _junctions

vector< unsigned int > GeneticMap::_junctions
private

A vector to store the position of the recombination events.

Referenced by recombine().

◆ _lociLookupTable

vector< unsigned int* > GeneticMap::_lociLookupTable
private

A list of tables that map the map position (cM) to a locus, for each trait.

The length of the table is the length of the genetic map, which depends on the map resolution (cM by default).

Referenced by addTrait(), recombine(), reset_tables(), and setLookupTable().

◆ _locPositionsPerTrait

vector< unsigned int* > GeneticMap::_locPositionsPerTrait
private

Vector containing the table of map position for the loci of each trait.

Positions are recorded according to the minimum map resolution as used in the lookup table.

Referenced by addTrait(), getGeneticMap(), getLocusPositionTable(), rescaleMap(), reset_tables(), and setLookupTable().

◆ _nTrait

unsigned int GeneticMap::_nTrait
private

Number of traits registered in the map.

Length of following arrays.

Referenced by addTrait(), clear(), recombine(), rescaleMap(), and unregisterTrait().

◆ _numChromosome

unsigned int GeneticMap::_numChromosome
private

◆ _numChrsmPerTrait

vector< unsigned int > GeneticMap::_numChrsmPerTrait
private

Vector of number of chromosomes for each trait.

Referenced by addTrait(), and reset_tables().

◆ _numLociPerChrsmPerTrait

vector< unsigned int* > GeneticMap::_numLociPerChrsmPerTrait
private

Vector containing a table of number of loci per chromosome for each trait.

Referenced by addTrait(), getGeneticMap(), reduceJunctions(), reset_tables(), and setLookupTable().

◆ _numLociPerTrait

vector< unsigned int > GeneticMap::_numLociPerTrait
private

Vector of number of loci for each trait.

Referenced by addTrait(), getGeneticMap(), recombine(), rescaleMap(), reset_tables(), and setLookupTable().

◆ _perChrsmLength

unsigned int* GeneticMap::_perChrsmLength
private

◆ _recombinationRate

double GeneticMap::_recombinationRate
private

Referenced by addTrait().

◆ _recombLength

unsigned int GeneticMap::_recombLength
private

Referenced by addTrait(), and recombine().

◆ _recPositions

vector< vector < unsigned int > > GeneticMap::_recPositions[2]
private

Vector of tables containing, for each trait, the locus number at which x-overs happen.

Updated at each generation. There is matrix per sex/gamete with one trait per row and a variable number of elements in each row.

Referenced by addTrait(), getRecLoci(), recombine(), reduceJunctions(), and reset_tables().

◆ _resolution

double GeneticMap::_resolution
private

◆ _totalLength

unsigned int GeneticMap::_totalLength
private

◆ _totalNumLoci

unsigned int GeneticMap::_totalNumLoci
private

Referenced by addTrait(), and recombine().

◆ _totRecombEventsMean

double GeneticMap::_totRecombEventsMean
private

◆ _traits

map< trait_t, unsigned int > GeneticMap::_traits
private

Table mapping trait type to its position index in the following tables.

Referenced by addTrait(), checkRegisteredTrait(), clear(), getGeneticMap(), getLocusPositionTable(), and unregisterTrait().


The documentation for this class was generated from the following files:

Generated for Nemo v2.4.0b by  doxygen 1.9.1 -- Nemo is hosted on  Download Nemo

Locations of visitors to this page
Catalogued on GSR