// // Makes a copy of a Genome, but with only one of the sex chromosomes. // // The fate of the mitochondrion is that of the X chromosome. // Genome * Genome::copy(bool copyX, bool copyY, bool copyM) const { Genome *newCopy = new Genome(getCountOfBases(),getCountOfBases(), chromosomePadding); if (NULL == newCopy) { WriteErrorMessage("Genome::copy: failed to allocate space for copy.\n"); return NULL; } const Genome::Contig *currentContig = NULL; const Genome::Contig *nextContig = getContigAtLocation(0); unsigned offsetInReference = 0; while (offsetInReference < getCountOfBases()) { if (NULL != nextContig && offsetInReference >= nextContig->beginningOffset) { // // Start of a new contig. See if we want to skip it. // currentContig = nextContig; nextContig = getNextContigAfterLocation(offsetInReference + 1); if ((!copyX && !strcmp(currentContig->name,"chrX")) || (!copyY && !strcmp(currentContig->name,"chrY")) || (!copyM && !strcmp(currentContig->name,"chrM"))) { // // Yes, skip over this contig. // nextContig = getNextContigAfterLocation(offsetInReference + 1); if (NULL == nextContig) { // // The chromosome that we're skipping was the last one, so we're done. // break; } else { offsetInReference = nextContig->beginningOffset; continue; } } // If skipping this chromosome newCopy->startContig(currentContig->name); } // If new contig beginning const size_t maxCopySize = 10000; char dataBuffer[maxCopySize + 1]; unsigned amountToCopy = maxCopySize; if (nextContig && nextContig->beginningOffset < offsetInReference + amountToCopy) { amountToCopy = nextContig->beginningOffset - offsetInReference; } if (getCountOfBases() < offsetInReference + amountToCopy) { amountToCopy = getCountOfBases() - offsetInReference; } memcpy(dataBuffer,getSubstring(offsetInReference,amountToCopy), amountToCopy); dataBuffer[amountToCopy] = '\0'; newCopy->addData(dataBuffer); offsetInReference += amountToCopy; } newCopy->fillInContigLengths(); newCopy->sortContigsByName(); return newCopy; }
// // Makes a copy of a Genome, but with only one of the sex chromosomes. // // The fate of the mitochondrion is that of the X chromosome. // Genome * Genome::copy(bool copyX, bool copyY, bool copyM) const { Genome *newCopy = new Genome(getCountOfBases(),getCountOfBases()); if (NULL == newCopy) { fprintf(stderr,"Genome::copy: failed to allocate space for copy.\n"); return NULL; } const Genome::Piece *currentPiece = NULL; const Genome::Piece *nextPiece = getPieceAtLocation(0); unsigned offsetInReference = 0; while (offsetInReference < getCountOfBases()) { if (NULL != nextPiece && offsetInReference >= nextPiece->beginningOffset) { // // Start of a new piece. See if we want to skip it. // currentPiece = nextPiece; nextPiece = getNextPieceAfterLocation(offsetInReference + 1); if ((!copyX && !strcmp(currentPiece->name,"chrX")) || (!copyY && !strcmp(currentPiece->name,"chrY")) || (!copyM && !strcmp(currentPiece->name,"chrM"))) { // // Yes, skip over this piece. // nextPiece = getNextPieceAfterLocation(offsetInReference + 1); if (NULL == nextPiece) { // // The chromosome that we're skipping was the last one, so we're done. // break; } else { offsetInReference = nextPiece->beginningOffset; continue; } } // If skipping this chromosome newCopy->startPiece(currentPiece->name); } // If new piece beginning const size_t maxCopySize = 10000; char dataBuffer[maxCopySize + 1]; unsigned amountToCopy = maxCopySize; if (nextPiece && nextPiece->beginningOffset < offsetInReference + amountToCopy) { amountToCopy = nextPiece->beginningOffset - offsetInReference; } if (getCountOfBases() < offsetInReference + amountToCopy) { amountToCopy = getCountOfBases() - offsetInReference; } memcpy(dataBuffer,getSubstring(offsetInReference,amountToCopy), amountToCopy); dataBuffer[amountToCopy] = '\0'; newCopy->addData(dataBuffer); offsetInReference += amountToCopy; } return newCopy; }