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 (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: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:1295

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.

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

References _traits.

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

◆ clear()

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

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

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

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

◆ getLocusPositionTable()

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

References _locPositionsPerTrait, and _traits.

Referenced by TTProtoWithMap::get_locus_map_positions().

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

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.

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

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

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

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

Referenced by addTrait().

◆ reset_tables()

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

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

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

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

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