Nemo  2.4.0
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 (const 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:55
unsigned int _recombLength
Definition: ttrait_with_map.h:87
double _recombinationRate
Definition: ttrait_with_map.h:91
double _totRecombEventsMean
Definition: ttrait_with_map.h:90
unsigned int * _chrsmFirstLocusPosition
Definition: ttrait_with_map.h:85
unsigned int _totalLength
Definition: ttrait_with_map.h:86
unsigned int * _perChrsmLength
Definition: ttrait_with_map.h:84
unsigned int _numChromosome
Definition: ttrait_with_map.h:83
unsigned int _totalNumLoci
Definition: ttrait_with_map.h:88
double _resolution
Definition: ttrait_with_map.h:89
unsigned long _currentIndividual
Definition: ttrait_with_map.h:49

◆ ~GeneticMap()

GeneticMap::~GeneticMap ( )
inline
101 {reset_tables();}
void reset_tables()
Definition: ttrait_with_map.cc:1299

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.

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

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().

+ Here is the caller graph for this function:

◆ 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.
674 {
675  map<trait_t, unsigned int>::iterator tIter = _traits.find(trait);
676 
677  return ( tIter != _traits.end() );
678 }

References _traits.

Referenced by TTProtoWithMap::is_mapped(), and TTQuantiFH::setOutputOption().

+ Here is the caller graph for this function:

◆ clear()

void GeneticMap::clear ( )
683 {
684  reset_tables();
685  _traits.clear();
686  _nTrait = 0;
687 }

References _nTrait, _traits, and reset_tables().

Referenced by IndFactory::clearPrototype().

+ Here is the caller graph for this function:

◆ getFirstRecPosition()

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

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

171  { 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:78

References _chrsmFirstRecombPosition.

◆ getGeneticMap()

bool GeneticMap::getGeneticMap ( trait_t  trait,
double **  table,
unsigned int  table_length 
)
915 {
916  map< trait_t, unsigned int>::const_iterator ITER = _traits.find(trait);
917 
918  if(ITER == _traits.end())
919  return(error("GeneticMap::getGeneticMap::failed to find trait \"%s\" in genetic map\n", trait.c_str()));
920 
921  unsigned int idx = ITER->second;
922 
923  assert(table_length == _numLociPerTrait[idx]);
924 
925  unsigned int chr = 0, loc_cnt = _numLociPerChrsmPerTrait[idx][0];
926 
927  for(unsigned int i = 0; i < table_length; ++i) {
928 
929  if(i >= loc_cnt) {
930  chr++;
931  loc_cnt += _numLociPerChrsmPerTrait[idx][chr];
932  }
933 
934  table[i][0] = chr;
935  table[i][1] = _locPositionsPerTrait[idx][i];
936 
937  }
938 
939  return true;
940 }
int error(const char *str,...)
Definition: output.cc:78

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

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

+ Here is the caller graph for this function:

◆ getLocusPositionTable()

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

References _locPositionsPerTrait, and _traits.

Referenced by TTProtoWithMap::get_locus_map_positions().

+ Here is the caller graph for this function:

◆ getRecLoci()

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

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

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

References _recPositions.

◆ getResolution()

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

References _resolution.

Referenced by TTProtoWithMap::recordRandomMap().

+ Here is the caller graph for this function:

◆ 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
1106 {
1107  unsigned int nbRec = 0;
1108 
1109 
1110  //empty the array of x-over positions
1111  for (unsigned int t = 0; t < _nTrait; t++) {
1112  _recPositions[SEX][t].clear();
1113  }
1114 
1115  //create a gamete:
1116 
1117  //draw the number of x-over depending on the total map size
1118  nbRec = (unsigned int)RAND::Poisson( _totRecombEventsMean );
1119 
1120 // nbRec = (unsigned int)RAND::Binomial( _recombinationRate , _totalLength );
1121 // call to Poisson() is faster
1122 
1123 #ifdef _REC_DEBUG_
1124  cout << "\n@@@ GeneticMap::recombine( SEX = "<<SEX<<" nbRec = "<<nbRec<<")"<<endl;
1125 #endif
1126 
1127  //adjust
1128  if(nbRec > _totalNumLoci - 1) nbRec = _totalNumLoci - 1;
1129 
1130  //now determine where the x-over will take place
1131  if(nbRec > 0) {
1132 
1133  //reset the list of recombination events.
1134  _junctions.resize(nbRec);
1135 
1136  auto drawRecPosition = [this](unsigned int& n){n = (unsigned int)(RAND::Uniform()*_recombLength);};
1137 
1138  //draw the positions
1139  for_each(_junctions.begin(), _junctions.end(), drawRecPosition);
1140 
1141  //sort them
1142  sort(_junctions.begin(), _junctions.end());
1143 
1144 #ifdef _REC_DEBUG_
1145  cout<< " --- sorted junctions ("<< _junctions.size()<<"): ";
1146  auto print = [this](unsigned int& n){cout<<" "<<n;};
1147  for_each(_junctions.begin(), _junctions.end(), print);
1148  cout<<endl;
1149 #endif
1150 
1151  //remove the duplicates, we keep only one when that happens (in principle very rarely):
1152  auto last = unique(_junctions.begin(), _junctions.end());
1153 
1154 
1155  // UPDATE NUMBER OF RECOMBINATION EVENTS
1156 
1157  nbRec = last - _junctions.begin(); // these are the unique x-over map positions
1158 
1159 #ifdef _REC_DEBUG_
1160  cout<<" --- after removing duplicates ("<< last - _junctions.begin()<<"): ";
1161  for_each(_junctions.begin(), last, print);
1162  cout<<endl;
1163 
1164  cout<<" --- computing rec map position: \n";
1165 #endif
1166 
1167  size_t pos;
1168 
1169  for (unsigned int t = 0; t < _nTrait; t++) {
1170 
1171 #ifdef _REC_DEBUG_
1172  cout<<" trait "<< t << endl;
1173 #endif
1174 
1175  for(unsigned int i = 0, hit; i < nbRec; ++i) {
1176 
1177  pos = _junctions[i];
1178 
1179  hit = _lociLookupTable[t][pos];
1180 
1181  _recPositions[SEX][t].push_back( hit );
1182 
1183 
1184 #ifdef _REC_DEBUG_
1185  cout<< " ["<<i<<"] @"<<pos<<" -> loc "<< hit <<"\n";
1186 #endif
1187 
1188  }// end_for_bRec
1189  }// end_for_traits
1190  } // end_if_nbRec
1191 
1192  // we always add the last position possible, to avoid returning an empty vector
1193  for (unsigned int t = 0; t < _nTrait; t++) {
1194  _recPositions[SEX][t].push_back(_numLociPerTrait[t]);
1195  }
1196 
1197  //set the starting point for each chromosome randomly (which chromosome copy to use first)
1198 
1199  _chrsmFirstRecombPosition[SEX].assign(_numChromosome, 0); //re-initialise the array
1200 
1201  for(unsigned int c = 0; c < _numChromosome; ++c) {
1203  }
1204 
1205 }
vector< unsigned int > _junctions
A vector to store the position of the recombination events.
Definition: ttrait_with_map.h:81
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:126
static bool RandBool()
Returns a random boolean.
Definition: Uniform.h:164

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

Referenced by TTProtoWithMap::recombine().

+ Here is the caller graph for this function:

◆ 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.

1210 {
1211  unsigned int prevLoc = 0, cEnd = 0;
1212  bool flipper;
1213  //number of x-overs
1214  vector< unsigned int >& recTable = _recPositions[SEX][trait_idx];
1215  unsigned int nbRec = recTable.size();
1216 
1217  vector< pair<unsigned int, unsigned int> > junctions;
1218 
1219  unsigned int num_copied = 0;
1220 
1221 #ifdef _REC_DEBUG_
1222  cout << "GeneticMap::reduceJunctions; trait "<<trait_idx<< "; nb Rec = "<<nbRec - 1<<endl;
1223  cout << " --sex = "<<SEX<<"\n";
1224 #endif
1225 
1226  // c is the chromosome number
1227  // stride is the number of loci considered so-far, sum of chromosome loci
1228  // rec is the number of x-over done so-far
1229  for(unsigned int c = 0, cStart = 0, rec = 0; c < _numChromosome; ++c) {
1230 
1231  //the copy of the chromosome with which with start
1232  flipper = _chrsmFirstRecombPosition[SEX][c];
1233 
1234  //number of loci to consider, including previous chromosomes
1235  cEnd = cStart + _numLociPerChrsmPerTrait[trait_idx][c] ;
1236 
1237  //last locus at which a x-over happened, will be first position on current chromosome
1238  prevLoc = cStart;
1239 
1240  num_copied = 0;
1241 
1242 #ifdef _REC_DEBUG_
1243  cout<<" --chrm "<<c<<", start="<<cStart<<", end="<<cEnd<<" (rec="<<rec<<"; rec pos = "
1244  <<recTable[rec]<<")"<<", side="<<flipper<<endl;
1245 #endif
1246 
1247  // zip forward if x-over on previous chrm were past the last locus on previous chrm
1248  // we need to catch up with position in the current chrm without changing the flipper
1249  while(recTable[rec] == cStart) rec++;
1250 
1251  // copy blocs of loci between x-over points on current chromosome
1252  // skip x-over if locus is not on this chromosome but a latter one (junction pos > cEnd)
1253  for(; recTable[rec] < cEnd && rec < nbRec; rec++) {
1254 
1255  //skip recombination events that would lead to copying 0 byte because even num x-over at same locus
1256  if(recTable[rec] == prevLoc){
1257  //but switch side for next bloc to copy on this chromosome
1258  //absolutely necessary to be in sync with other traits on the map
1259  flipper = !flipper;
1260  continue;
1261  }
1262 
1263 
1264 #ifdef _REC_DEBUG_
1265  cout<< " ["<<rec<<"] junction "<<recTable[rec]<< " on side "<<flipper<<std::endl;
1266 #endif
1267 
1268  junctions.push_back(pair<unsigned int, unsigned int>(recTable[rec], flipper));
1269 
1270  num_copied += recTable[rec] - prevLoc;
1271 
1272  //update the starting locus to the next recombination point
1273  prevLoc = recTable[rec];
1274 
1275  //switch side for next bloc to copy on this chromosome
1276  flipper = !flipper;
1277  }
1278 
1279 #ifdef _REC_DEBUG_
1280  cout << " --copy til end of chrmsm from "<<prevLoc<<" to "<<cEnd<<" on side "<<flipper<<endl;
1281 #endif
1282 
1283  num_copied += cEnd - prevLoc;
1284 
1285  junctions.push_back(pair<unsigned int, unsigned int>(cEnd, flipper));
1286 
1287  if(num_copied != _numLociPerChrsmPerTrait[trait_idx][c])
1288  error("number of loci copied on chromosome %i is %i != %i\n", c, num_copied, _numLociPerChrsmPerTrait[trait_idx][c]);
1289 
1290  cStart += _numLociPerChrsmPerTrait[trait_idx][c];
1291  }
1292 
1293  return junctions;
1294 }

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

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

+ Here is the caller graph for this function:

◆ 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
144  {
145  if (ID == _currentIndividual) return false;
146  else _currentIndividual = ID;
147  return true;
148  }

References _currentIndividual.

Referenced by TTProtoWithMap::recombine().

+ Here is the caller graph for this function:

◆ rescaleMap()

void GeneticMap::rescaleMap ( double  val)
945 {
946  assert(val < _resolution);
947 
948  double ratio = _resolution/val; //it is assumed that val < _resolution
949 
950  _resolution = val;
951 
952  //we have to update all positions
953  for (unsigned int i = 0; i < _nTrait; ++i) {
954  for (unsigned int j = 0; j < _numLociPerTrait[i]; ++j) {
955  _locPositionsPerTrait[i][j] *= ratio;
956  }
957  }
958 
959  for (unsigned int i = 0; i < _numChromosome; ++i) {
960  _perChrsmLength[i] *= ratio;
961  _chrsmFirstLocusPosition[i] *= ratio;
962  }
963 
964  _totalLength *= ratio;
965  _totRecombEventsMean = (double)_totalLength * 0.01 * _resolution;
966 
967  //reset all lookup tables, the total length has changed!
968  for (unsigned int i = 0; i < _nTrait; ++i) setLookupTable(i);
969 }

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

Referenced by addTrait().

+ Here is the caller graph for this function:

◆ reset_tables()

void GeneticMap::reset_tables ( )
1300 {
1301  if(_perChrsmLength != NULL) delete [] _perChrsmLength;
1302  _perChrsmLength = NULL;
1303 
1304  if(_chrsmFirstLocusPosition != NULL) delete [] _chrsmFirstLocusPosition;
1305  _chrsmFirstLocusPosition = NULL;
1306 
1307  _numChrsmPerTrait.clear();
1308  _numLociPerTrait.clear();
1309 
1310  for (unsigned int i = 0; i < _lociLookupTable.size(); ++i) {
1311  if(_lociLookupTable[i] != NULL) delete [] _lociLookupTable[i];
1312  else error("GeneticMap::reset_tables::found null pointer in _lociLookupTable\n");
1313  }
1314  _lociLookupTable.clear();
1315 
1316  for (unsigned int i = 0; i < _numLociPerChrsmPerTrait.size(); ++i) {
1317  if(_numLociPerChrsmPerTrait[i] != NULL) delete [] _numLociPerChrsmPerTrait[i];
1318  else error("GeneticMap::reset_tables::found null pointer in _numLociPerChrsmPerTrait\n");
1319  }
1320  _numLociPerChrsmPerTrait.clear();
1321 
1322  for (unsigned int i = 0; i < _locPositionsPerTrait.size(); ++i) {
1323  if(_locPositionsPerTrait[i] != NULL) delete [] _locPositionsPerTrait[i];
1324  else error("GeneticMap::reset_tables::found null pointer in _locPositionsPerTrait\n");
1325  }
1326  _locPositionsPerTrait.clear();
1327 
1328  _recPositions[0].clear();
1329  _recPositions[1].clear();
1330 
1331  _chrsmFirstRecombPosition[0].clear();
1332  _chrsmFirstRecombPosition[1].clear();
1333 
1334 }

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

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

+ Here is the caller graph for this function:

◆ 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 !!!!

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

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

Referenced by addTrait(), and rescaleMap().

+ Here is the caller graph for this function:

◆ setResolution()

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

References _resolution.

◆ unregisterTrait()

void GeneticMap::unregisterTrait ( trait_t  trait)
650 {
651  map<trait_t, unsigned int>::iterator tIter;
652 
653  tIter = _traits.find(trait);
654 
655  if ( tIter != _traits.end() ) {
656 
657 // cout<<"GeneticMap::unregisterTrait::"<<tIter->first<<" (idx: "<<tIter->second<<")"<<endl;
658 
659  _traits.erase(tIter);
660 
661  //@TODO trait lookup tables must be erased as well
662 
663 // cout<<"GeneticMap::unregisterTrait::done\n";
664  }
665  else fatal("Genetic map::unregisterTrait: trait \"%s\" is not registered\n", trait.c_str());
666 
667  _nTrait--;
668 }

References _nTrait, _traits, and fatal().

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

+ Here is the caller graph for this function:

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.0 by  doxygen 1.9.1 -- Nemo is hosted on  Download Nemo

Locations of visitors to this page
Catalogued on GSR