/***************************************************************************** # Copyright (C) 1994-2008 by David Gordon. # All rights reserved. # # This software is part of a beta-test version of the Consed/Autofinish # package. It should not be redistributed or # used for any commercial purpose, including commercially funded # sequencing, without written permission from the author and the # University of Washington. # # This software is provided ``AS IS'' and any express or implied # warranties, including, but not limited to, the implied warranties of # merchantability and fitness for a particular purpose, are disclaimed. # In no event shall the authors or the University of Washington be # liable for any direct, indirect, incidental, special, exemplary, or # consequential damages (including, but not limited to, procurement of # substitute goods or services; loss of use, data, or profits; or # business interruption) however caused and on any theory of liability, # whether in contract, strict liability, or tort (including negligence # or otherwise) arising in any way out of the use of this software, even # if advised of the possibility of such damage. # # Building Consed from source is error prone and not simple which is # why I provide executables. Due to time limitations I cannot # provide any assistance in building Consed. Even if you do not # modify the source, you may introduce errors due to using a # different version of the compiler, a different version of motif, # different versions of other libraries than I used, etc. For this # reason, if you discover Consed bugs, I can only offer help with # those bugs if you first reproduce those bugs with an executable # provided by me--not an executable you have built. # # Modifying Consed is also difficult. Although Consed is modular, # some modules are used by many other modules. Thus making a change # in one place can have unforeseen effects on many other features. # It may takes months for you to notice these other side-effects # which may not seen connected at all. It is not feasable for me to # provide help with modifying Consed sources because of the # potentially huge amount of time involved. # #*****************************************************************************/ #include "filename.h" #include "applyEditHistory.h" #include "rwcstring.h" #include using namespace std; #include #include "rwctokenizer.h" #include #include "mbt_exception.h" #include "assert.h" #include "contig.h" #include "consed.h" #include "editaction.h" #include "bIsNumeric.h" #include "bIsABase.h" #include "assembly.h" #include "editOverstrike.h" #include "editInsertColOfPads.h" #include "editChangeToNs.h" #include "editChangeToNsToLeft.h" #include "editChangeToNsToRight.h" #include "editChangeToXs.h" #include "editMakeHighQuality.h" #include "editMakeHighQualityAndChangeConsensus.h" #include "editMakeLowQuality.h" #include "editMakeLowQualityToLeft.h" #include "editMakeLowQualityToRight.h" #include "editAddReadTag.h" #include "editAddConsensusTag.h" #include "edit_complement_contig.h" #include "oligoTag.h" #include "rwcregexp.h" #include "numutil.h" #include "mbt_errors.h" #include "editDeleteReadTag.h" #include "editDeleteConsensusTag.h" #include "bIsNumericMaybeWithWhitespace.h" #include "editOverstrikeAllReadsAtConsPos.h" #include "editAddTagsToAllReadsAtConsPos.h" #include "editOverstrikeConsensus.h" #define PARSE_PANIC( szMessage ) \ { ostringstream ost; \ ost << "Error detected from source file " \ << __FILE__ << " at " << __LINE__ <= 1 && soNextLine[0] == '!' ); // return with new data return true; } static RWCString soGetTagCommentIfAny( ifstream& ifsInFile ) { // the tag may not have a comment, so we may be at the end of the file if (!bGetNextLine( ifsInFile ) ) return( "" ); if ( soNextLine != "BEGIN_COMMENT" ) { bAlreadyReadNextLine = true; return( "" ); } // so we are in a comment RWCString soComment; bool bFoundEnd = false; while( !bFoundEnd ) { if (! bGetNextLine( ifsInFile ) ) PARSE_PANIC( "premature end of file looking for END_COMMENT" ); if (soNextLine == "END_COMMENT" ) bFoundEnd = true; else { // separate comment lines by newline if ( soComment.length() != 0 ) soComment += "\n"; soComment += soNextLine; } } soComment = soComment.stripWhitespace( RWCString::TRAILING ); return( soComment ); } static RWCString soGetTagMiscInfoIfAny( ifstream& ifsInFile ) { // the tag may not have misc data (probably won't), so we may be at the end of the file if (!bGetNextLine( ifsInFile ) ) return( "" ); if ( soNextLine != "BEGIN_MISC" ) { bAlreadyReadNextLine = true; return( "" ); } // so we are in a misc data block RWCString soMiscData; bool bFoundEnd = false; do { if ( !bGetNextLine( ifsInFile ) ) PARSE_PANIC( "premature end of file looking for END_MISC" ); if ( soNextLine == "END_MISC" ) bFoundEnd = true; else { // separate misc lines by newline if ( !soMiscData.isNull() ) soMiscData += "\n"; soMiscData += soNextLine; } } while( !bFoundEnd ); soMiscData = soMiscData.stripWhitespace( RWCString::TRAILING ); return( soMiscData ); } static void getContigAndRead( const RWCString& soContigName, const RWCString& soReadName, Contig*& pContig, LocatedFragment*& pLocFrag, const bool bIgnoreRead ) { pContig = ConsEd::pGetAssembly()->pGetContigByName( soContigName ); if (!pContig) PARSE_PANIC("Contig not found"); if (bIgnoreRead) { pLocFrag = NULL; return; } pLocFrag = pContig->pLocFragGetByName( soReadName ); if (! pLocFrag ) PARSE_PANIC("Read not found" ); pLocFrag->readTraces( true ); // ask user for pathname if can't open traces // This is necessary to read some other header information in the phd files // Commented out 8/99 since phred calls are now read at startup. // pLocFrag->readPhredCalls(); } static void applyOverstrike() { RWCTokenizer tok( soNextLine ); RWCString soTok1 = tok(); RWCString soContigName = tok(); RWCString soReadName = tok(); RWCString soConsPos = tok(); RWCString soBase = tok(); if (soTok1.isNull() || soContigName.isNull() || soReadName.isNull() || soConsPos.isNull() || soBase.isNull() ) { PARSE_PANIC( " should be 5 tokens for overstrike " ); } if (!bIsNumeric( soConsPos ) ) PARSE_PANIC("Consensus Position not numeric"); if (!bIsABase( soBase, true ) ) // allow ambiguity codes PARSE_PANIC( " not a base " ); int nConsPos = atoi( soConsPos.data() ); Contig *pContig; LocatedFragment *pLocFrag; getContigAndRead( soContigName, soReadName, pContig, pLocFrag, false ); Ntide ntOld = pLocFrag->ntGetFragFromConsPos(nConsPos); char c = *(soBase.data()); Quality ucQual; if (isupper(c) ) ucQual = ucQualityHighEdited; else ucQual = ucDefaultQualityEdited; // form the new ntide Ntide ntNew(c, // passed char ucQual ); // point position is left unchanged in its array // form the edit action EditOverstrike* pEdOv = new EditOverstrike(pLocFrag, nConsPos, // position ALWAYS supplied ntNew); // newly formed ntide // tell the ConsEd ConsEd::pGetConsEd()->doEditAction(pEdOv, false ); } static void applyInsertColumnOfPads() { RWCTokenizer tok( soNextLine ); RWCString soTok1 = tok(); RWCString soContigName = tok(); RWCString soConsPos = tok(); Contig* pContig = ConsEd::pGetAssembly()->pGetContigByName( soContigName ); if (pContig == NULL) PARSE_PANIC( "contig not found" ); if (!bIsNumeric( soConsPos ) ) PARSE_PANIC("Consensus Position not numeric"); int nConsPos = atoi( soConsPos.data() ); EditInsertColOfPads* pEdColPads = new EditInsertColOfPads(pContig, nConsPos ); ConsEd::pGetConsEd()->doEditAction(pEdColPads, false ); } static void applyUndo() { ConsEd::pGetConsEd()->undoLastEditAction( false ); } static void convertToRange( const RWCString& soContigName, const RWCString& soReadName, const RWCString& soConsPosLeft, const RWCString& soConsPosRight, Contig*& pContig, LocatedFragment*& pLocFrag, int& nConsPosLeft, int& nConsPosRight, const bool bIgnoreReadName) { if (!bIsNumeric( soConsPosLeft ) ) PARSE_PANIC("Consensus Position start not numeric"); nConsPosLeft = atoi( soConsPosLeft.data() ); if (!bIsNumeric( soConsPosRight ) ) PARSE_PANIC("Consensus Position end not numeric"); nConsPosRight = atoi( soConsPosRight.data() ); getContigAndRead( soContigName, soReadName, pContig, pLocFrag, bIgnoreReadName ); } static void parseForRange( Contig*& pContig, LocatedFragment*& pLocFrag, int& nConsPosLeft, int& nConsPosRight ) { RWCTokenizer tok( soNextLine ); RWCString soTok1 = tok(); RWCString soContigName = tok(); RWCString soReadName = tok(); RWCString soConsPosLeft = tok(); RWCString soConsPosRight = tok(); if (soTok1.isNull() || soContigName.isNull() || soReadName.isNull() || soConsPosLeft.isNull() || soConsPosRight.isNull() ) { PARSE_PANIC( " should be 5 tokens for changeToNs " ); } convertToRange( soContigName, soReadName, soConsPosLeft, soConsPosRight, pContig, pLocFrag, nConsPosLeft, nConsPosRight, false ); } static void applyChangeToNs() { Contig* pContig; LocatedFragment* pLocFrag; int nConsPosLeft; int nConsPosRight; parseForRange( pContig, pLocFrag, nConsPosLeft, nConsPosRight ); EditAction* pEditAction = new editChangeToNs( pLocFrag, nConsPosLeft, nConsPosRight ); ConsEd::pGetConsEd()->doEditAction( pEditAction, false ); } static void parseForUnlimitedRange( Contig*& pContig, LocatedFragment*& pLocFrag, int& nConsPos ) { RWCTokenizer tok( soNextLine ); RWCString soTok1 = tok(); RWCString soContigName = tok(); RWCString soReadName = tok(); RWCString soConsPos = tok(); if (soTok1.isNull() || soContigName.isNull() || soReadName.isNull() || soConsPos.isNull() ) { PARSE_PANIC( " should be 4 tokens for changeToNs " ); } if (!bIsNumeric( soConsPos ) ) PARSE_PANIC("Consensus Position start not numeric"); nConsPos = atoi( soConsPos.data() ); getContigAndRead( soContigName, soReadName, pContig, pLocFrag, false ); } static void applyMakeHighQuality() { Contig* pContig; LocatedFragment* pLocFrag; int nConsPosLeft; int nConsPosRight; parseForRange( pContig, pLocFrag, nConsPosLeft, nConsPosRight ); EditAction* pEditAction = new editMakeHighQuality( pLocFrag, nConsPosLeft, nConsPosRight ); ConsEd::pGetConsEd()->doEditAction( pEditAction, false ); // false means don't write to edit history // file } static void applyMakeHighQualityAndChangeConsensus() { Contig* pContig; LocatedFragment* pLocFrag; int nConsPosLeft; int nConsPosRight; parseForRange( pContig, pLocFrag, nConsPosLeft, nConsPosRight ); EditAction* pEditAction = new editMakeHighQualityAndChangeConsensus( pLocFrag, nConsPosLeft, nConsPosRight ); ConsEd::pGetConsEd()->doEditAction( pEditAction, false ); // false means don't write to edit history // file } static void applyMakeLowQuality() { Contig* pContig; LocatedFragment* pLocFrag; int nConsPosLeft; int nConsPosRight; parseForRange( pContig, pLocFrag, nConsPosLeft, nConsPosRight ); EditAction* pEditAction = new editMakeLowQuality( pLocFrag, nConsPosLeft, nConsPosRight ); ConsEd::pGetConsEd()->doEditAction( pEditAction, false ); // false means don't write to edit history // file } static void applyMakeLowQualityToLeft() { Contig* pContig; LocatedFragment* pLocFrag; int nConsPos; parseForUnlimitedRange( pContig, pLocFrag, nConsPos ); EditAction* pEditAction = new editMakeLowQualityToLeft( pLocFrag, nConsPos ); ConsEd::pGetConsEd()->doEditAction( pEditAction, false ); // false means don't write to edit history // file } static void applyMakeLowQualityToRight() { Contig* pContig; LocatedFragment* pLocFrag; int nConsPos; parseForUnlimitedRange( pContig, pLocFrag, nConsPos ); EditAction* pEditAction = new editMakeLowQualityToRight( pLocFrag, nConsPos ); ConsEd::pGetConsEd()->doEditAction( pEditAction, false ); // false means don't write to edit history // file } static void applyChangeToNsToLeft() { Contig* pContig; LocatedFragment* pLocFrag; int nConsPos; parseForUnlimitedRange( pContig, pLocFrag, nConsPos ); EditAction* pEditAction = new editChangeToNsToLeft( pLocFrag, nConsPos ); ConsEd::pGetConsEd()->doEditAction( pEditAction, false ); // false means don't write to edit history // file } static void applyChangeToNsToRight() { Contig* pContig; LocatedFragment* pLocFrag; int nConsPos; parseForUnlimitedRange( pContig, pLocFrag, nConsPos ); EditAction* pEditAction = new editChangeToNsToRight( pLocFrag, nConsPos ); ConsEd::pGetConsEd()->doEditAction( pEditAction, false ); // false means don't write to edit history // file } static void applyChangeToXsToLeft() { Contig* pContig; LocatedFragment* pLocFrag; int nConsPos; parseForUnlimitedRange( pContig, pLocFrag, nConsPos ); EditAction* pEditAction = new editChangeToXs( pLocFrag, pLocFrag->nGetAlignStart(), nConsPos, 'l' ); // LEFT ConsEd::pGetConsEd()->doEditAction( pEditAction, false ); // false means don't write to edit history file } static void applyChangeToXsToRight() { Contig* pContig; LocatedFragment* pLocFrag; int nConsPos; parseForUnlimitedRange( pContig, pLocFrag, nConsPos ); EditAction* pEditAction = new editChangeToXs( pLocFrag, nConsPos, pLocFrag->nGetAlignEnd(), 'r' ); ConsEd::pGetConsEd()->doEditAction( pEditAction, false ); // false means don't write to edit history file } static void applyComplementContig() { RWCTokenizer tok( soNextLine ); RWCString soTok1 = tok(); RWCString soContigName = tok(); if (soTok1.isNull() || soContigName.isNull() ) { PARSE_PANIC( " should be 2 tokens for complementContig" ); } Contig* pContig = ConsEd::pGetAssembly()->pGetContigByName( soContigName ); EditAction *pEditAction = new EditComplementContig( pContig ); ConsEd::pGetConsEd()->doEditAction( pEditAction, false ); // false means don't write to edit history // file } #define OLIGO_INFO_LINE_FORM( szMessage ) \ "Line should be of form { " szMessage static void getOligoInfo( ifstream& ifsInFile, RWCString& soOligoName, RWCString& soOligoBases, int& nMeltingTemp, bool& bComplementedWithRespectToWayPhrapCreatedContig, RWCString& soTemplates ) { if (!bGetNextLine( ifsInFile ) ) PARSE_PANIC( "premature end of file in oligo tag while looking for 2nd line" ); RWCTokenizer tok( soNextLine ); RWCString soBracket = tok(); soOligoName = tok(); soOligoBases = tok(); RWCString soMeltingTemp = tok(); RWCString soComplementedWithRespectToWayPhrapCreatedContig = tok(); if (soBracket != "{" ) PARSE_PANIC( OLIGO_INFO_LINE_FORM( "2nd oligo line should start with \"{\"" ) ); if ( (soOligoName.length() == 0) || (soOligoBases.length() == 0 ) || (soMeltingTemp.length() == 0) || (soComplementedWithRespectToWayPhrapCreatedContig.length() == 0 ) ) PARSE_PANIC( OLIGO_INFO_LINE_FORM( "missing fields in oligo tag." ) ); if ( nAToIWithError( soMeltingTemp.data(), nMeltingTemp ) != NO_ERROR ) PARSE_PANIC( OLIGO_INFO_LINE_FORM( "melting temp must be numeric" ) ); if ( soComplementedWithRespectToWayPhrapCreatedContig == "U" ) bComplementedWithRespectToWayPhrapCreatedContig = false; else if ( soComplementedWithRespectToWayPhrapCreatedContig == "C" ) bComplementedWithRespectToWayPhrapCreatedContig = true; else PARSE_PANIC( OLIGO_INFO_LINE_FORM( "but found other than U or C" ) ); if (!bGetNextLine( ifsInFile ) ) PARSE_PANIC( "premature end of file in oligo tag while looking for templates" ); soTemplates = soNextLine; if (!bGetNextLine( ifsInFile ) ) PARSE_PANIC( "premature end of file in oligo tag while looking for purpose" ); RWCRegexp regexp("^}[ \t]*$"); // allow trailing whitespace if ( soNextLine( regexp ).length() == 0 ) PARSE_PANIC( "end of oligo tag must be a line with just \"}\"" ); } static void applyAddColumnOfReadTags( ifstream& ifsInFile ) { // looks like: addColumnOfReadTags polymorphism Contig1 454 455 // comment RWCTokenizer tok( soNextLine ); tok(); // throw away keyword RWCString soTagType = tok(); RWCString soContig = tok(); RWCString soConsPosStart = tok(); RWCString soConsPosEnd = tok(); RWCString soDate = tok(); int nConsPosStart; int nConsPosEnd; if ( !bIsNumericMaybeWithWhitespace( soConsPosStart, nConsPosStart ) ) { RWCString soError = soNextLine + " has non-numeric nConsPosStart: " + soConsPosStart; PARSE_PANIC( soError ); } if ( !bIsNumericMaybeWithWhitespace( soConsPosEnd, nConsPosEnd ) ) { RWCString soError = soNextLine + " has non-numeric nConsPosEnd: " + soConsPosEnd; PARSE_PANIC( soError ); } Contig* pContig = ConsEd::pGetAssembly()->pGetContigByName( soContig ); if ( !pContig ) { RWCString soError = soNextLine + " but " + soContig + " cannot be found in assembly"; PARSE_PANIC( soError ); } // get comment RWCString soComment = soGetTagCommentIfAny( ifsInFile ); EditAction* pEditAction = new editAddTagsToAllReadsAtConsPos( pContig, nConsPosStart, nConsPosEnd, soTagType, soComment ); ConsEd::pGetConsEd()->doEditAction( pEditAction, false ); // false means don't write to edit history // file } static void applyAddTag( ifstream& ifsInFile, const int nTagType ) { RWCTokenizer tok( soNextLine ); RWCString soTok1 = tok(); RWCString soTagType = tok(); RWCString soTagSource = tok(); RWCString soContigName = tok(); RWCString soReadName; if (nTagType == READTAG ) soReadName = tok(); RWCString soConsPosStart = tok(); RWCString soConsPosEnd = tok(); RWCString soDate = tok(); bool bNoTrans = false; if (nTagType == READTAG ) { RWCString soTime = tok(); soDate = soDate + " " + soTime; } else { RWCString soNoTrans = tok(); if ( soNoTrans == "NoTrans" ) bNoTrans = true; else if ( soNoTrans.isNull() ) { // fine } else { PARSE_PANIC_2_ARGS( "add tag line should look like this: but 7th parameter was %s intead of NoTrans", (char*)soNoTrans.data(), "" ); } } Contig* pContig; LocatedFragment* pLocFrag; int nConsPosStart; int nConsPosEnd; convertToRange( soContigName, soReadName, soConsPosStart, soConsPosEnd, pContig, pLocFrag, nConsPosStart, nConsPosEnd, ( nTagType == READTAG ? false : true ) // ignore read ); RWCString soComment = soGetTagCommentIfAny( ifsInFile ); if ( soTagType == "oligo" ) { RWCString soOligoName; RWCString soOligoBases; int nMeltingTemp; bool bComplementedWithRespectToWayPhrapCreatedContig; RWCString soTemplates; getOligoInfo( ifsInFile, soOligoName, soOligoBases, nMeltingTemp, bComplementedWithRespectToWayPhrapCreatedContig, soTemplates ); tag* pTag = new oligoTag( pContig, nConsPosStart, nConsPosEnd, soTagSource, soDate, bNoTrans, soOligoName, soOligoBases, nMeltingTemp, bComplementedWithRespectToWayPhrapCreatedContig, soTemplates, soComment ); EditAction* pEditAction = new editAddConsensusTag( pTag ); ConsEd::pGetConsEd()->doEditAction( pEditAction, false ); Assembly* pAssembly = ConsEd::pGetAssembly(); pAssembly->perhapsIncreaseLastUsedOligoNumber( soOligoName ); } else { bool bWriteTagToPhdFileNotAceFile = ( pLocFrag ) ? true : false; tag* pTag = new tag( pLocFrag, pContig, soTagType, nConsPosStart, nConsPosEnd, bWriteTagToPhdFileNotAceFile, soComment, soTagSource, soDate, bNoTrans ); RWCString soMiscData = soGetTagMiscInfoIfAny( ifsInFile ); if ( !soMiscData.isNull() ) pTag->soMiscData_ = soMiscData; EditAction* pEditAction; if (nTagType == READTAG ) pEditAction = new editAddReadTag( pTag ); else pEditAction = new editAddConsensusTag( pTag ); ConsEd::pGetConsEd()->doEditAction( pEditAction, false ); // false means don't write to edit history // file } } RWCRegexp regDateFormat1( "^[0-9][0-9][0-9][0-9][0-9][0-9]:[0-9][0-9][0-9][0-9][0-9][0-9]$" ); RWCRegexp regDateFormat2( "^[0-9][0-9]/[0-9][0-9]/[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]$" ); static void applyDeleteTag( ifstream& ifsInFile, const int nReadTagOrConsensusTag ) { RWCString soSaveForErrorMessage = soNextLine; RWCTokenizer tok( soNextLine ); RWCString soTok1 = tok(); RWCString soTagType = tok(); RWCString soTagSource = tok(); RWCString soContigName = tok(); RWCString soReadName; if ( nReadTagOrConsensusTag == READTAG ) soReadName = tok(); RWCString soConsPosStart = tok(); RWCString soConsPosEnd = tok(); RWCString soDate = tok(); if ( soDate( regDateFormat1 ) != soDate ) { // try and see if the date is the other format 00/03/17 11:44:16 RWCString soTime = tok(); soDate = soDate + " " + soTime; if ( soDate( regDateFormat2 ) != soDate ) { PARSE_PANIC( ("date " + soDate + " is not in a recognized format") ); } } Contig* pContig; LocatedFragment* pLocFrag; int nConsPosStart; int nConsPosEnd; convertToRange( soContigName, soReadName, soConsPosStart, soConsPosEnd, pContig, pLocFrag, nConsPosStart, nConsPosEnd, ( nReadTagOrConsensusTag == READTAG ? false : true ) // ignore read ); RWCString soOligoName; RWCString soOligoBases; RWCString soTemplates; int nMeltingTemp; bool bComplementedWithRespectToWayPhrapCreatedContig; RWCString soComment = soGetTagCommentIfAny( ifsInFile ); RWCString soMiscData = soGetTagMiscInfoIfAny( ifsInFile ); if ( soTagType == "oligo" ) { getOligoInfo( ifsInFile, soOligoName, soOligoBases, nMeltingTemp, bComplementedWithRespectToWayPhrapCreatedContig, soTemplates ); } // try to find tag tag* pFoundTag = NULL; if ( nReadTagOrConsensusTag == READTAG ) { for( int nTag = 0; nTag < pLocFrag->aTags_.entries() && !pFoundTag; ++nTag ) { tag* pTag = pLocFrag->aTags_[ nTag ]; if ( pTag->soDate_ == soDate ) { if ( pTag->nPaddedConsPosStart_ == nConsPosStart && pTag->nPaddedConsPosEnd_ == nConsPosEnd && pTag->soType_ == soTagType && pTag->soSource_ == soTagSource && pTag->soComment_ == soComment && pTag->soMiscData_ == soMiscData ) { pFoundTag = pTag; } } } } else { // consensus tag for( int nTag = 0; nTag < pContig->aConsensusTags_.entries() && !pFoundTag; ++nTag ) { tag* pTag = pContig->aConsensusTags_[ nTag ]; if ( pTag->soDate_ == soDate ) { if ( pTag->nPaddedConsPosStart_ == nConsPosStart && pTag->nPaddedConsPosEnd_ == nConsPosEnd && pTag->soType_ == soTagType && pTag->soSource_ == soTagSource && pTag->soComment_ == soComment && pTag->soMiscData_ == soMiscData ) { if ( soTagType == "oligo" ) { oligoTag* pOligoTag = (oligoTag*) pTag; if ( pOligoTag->soName_ == soOligoName && pOligoTag->soBases_ == soOligoBases && pOligoTag->bComplementedWithRespectToWayPhrapCreatedContig_ == bComplementedWithRespectToWayPhrapCreatedContig ) { pFoundTag = pTag; } } else pFoundTag = pTag; } } } } if ( pFoundTag ) { EditAction* pEditAction; if ( nReadTagOrConsensusTag == READTAG ) pEditAction = new editDeleteReadTag( pFoundTag ); else pEditAction = new editDeleteConsensusTag( pFoundTag ); ConsEd::pGetConsEd()->doEditAction( pEditAction, false ); // don't write to edit history } else { RWCString soErrorMessage = "could not find tag " + soSaveForErrorMessage; PARSE_PANIC( soErrorMessage ); } } static void applyChangeAllReads() { // looks like: // changeAllReads Contig1 djs74-824.s1 1894 RWCString soSaveForErrorMessage = soNextLine; Contig* pContig = NULL; LocatedFragment* pMasterLocFrag = NULL; int nConsPos; RWCTokenizer tok( soNextLine ); RWCString soTok1 = tok(); RWCString soContigName = tok(); RWCString soMasterReadName = tok(); RWCString soConsPos = tok(); if (soTok1.isNull() || soContigName.isNull() || soMasterReadName.isNull() || soConsPos.isNull() ) { PARSE_PANIC( " should be 4 tokens for changeToNs " ); } if ( !bIsNumericMaybeWithWhitespace( soConsPos, nConsPos ) ) { PARSE_PANIC("Consensus Position start not numeric"); } getContigAndRead( soContigName, soMasterReadName, pContig, pMasterLocFrag, false ); // now get all the reads that should be changed RWTPtrOrderedVector aReadsToOverstrike; RWCString soReadName; while( !( soReadName = tok() ).bIsNull() ) { // found another read in the list LocatedFragment* pLocFrag = pContig->pLocFragGetByName( soReadName ); if ( !pLocFrag ) { RWCString soError = soReadName + " not found in ace file--.wrk file probably corrupted"; PARSE_PANIC( soError ); } aReadsToOverstrike.insert( pLocFrag ); } EditAction* pEditAction = new editOverstrikeAllReadsAtConsPos( nConsPos, pMasterLocFrag, aReadsToOverstrike ); ConsEd::pGetConsEd()->doEditAction( pEditAction, false ); // don't write to edit history } static void applyOverstrikeConsensus() { // looks like: // overstrikeConsensus Contig2 padded: 2345 * RWCTokenizer tok( soNextLine ); RWCString soTok1 = tok(); RWCString soContigName = tok(); RWCString soPaddedKeyword = tok(); RWCString soConsPos = tok(); RWCString soNewBase = tok(); if ( soNewBase.bIsNull() ) { PARSE_PANIC( "should be of form: overstrikeConsensus Contig2 padded: 2345 g but there are not enough words" ); } Contig* pContig = ConsEd::pGetAssembly()->pGetContigByName( soContigName ); if (pContig == NULL) PARSE_PANIC( "contig not found" ); int nConsPos; if ( !bIsNumericMaybeWithWhitespace( soConsPos, nConsPos ) ) { PARSE_PANIC( "should be of form: overstrikeConsensus Contig2 padded: 2345 g but padded consensus position is not numeric" ); } if ( soNewBase.length() != 1 ) { PARSE_PANIC( "should be of form: overstrikeConsensus Contig2 padded: 2345 g but base is not just 1 character" ); } char cNewBase = soNewBase[0]; EditAction* pEditAction = new editOverstrikeConsensus( pContig, nConsPos, cNewBase ); ConsEd::pGetConsEd()->doEditAction( pEditAction, false ); // don't write to edit history } void applyEditHistory( const RWCString& soAceFile ) { filEditHistory = soAceFile + ".wrk"; ifstream ifsInFile( (char*)filEditHistory.data(), ios::in); // file open? if (!ifsInFile) { ostringstream ost; ost << "Unable to open file " << filEditHistory << endl << ends; SysRequestFailed srf(ost.str().c_str()); srf.includeErrnoDescription(); throw srf; } while( bGetNextLine( ifsInFile ) ) { RWCTokenizer tok( soNextLine ); RWCString soFirstToken = tok(); if (soFirstToken == "overstrike") applyOverstrike(); else if (soFirstToken == "undo") applyUndo(); else if (soFirstToken == "insertColumnOfPads") applyInsertColumnOfPads(); else if (soFirstToken == "complementContig") applyComplementContig(); else if (soFirstToken == "changeToNs" ) applyChangeToNs(); else if (soFirstToken == "changeToNsToRight" ) applyChangeToNsToRight(); else if (soFirstToken == "changeToNsToLeft" ) applyChangeToNsToLeft(); else if (soFirstToken == "changeToXsToLeft" ) applyChangeToXsToLeft(); else if (soFirstToken == "changeToXsToRight" ) applyChangeToXsToRight(); else if (soFirstToken == "makeHighQuality" ) applyMakeHighQuality(); else if (soFirstToken == "makeHighQualityAndChangeConsensus" ) applyMakeHighQualityAndChangeConsensus(); else if (soFirstToken == "makeLowQuality" ) applyMakeLowQuality(); else if (soFirstToken == "makeLowQualityToLeft" ) applyMakeLowQualityToLeft(); else if (soFirstToken == "makeLowQualityToRight" ) applyMakeLowQualityToRight(); else if (soFirstToken == "addTag" ) applyAddTag( ifsInFile, READTAG ); else if (soFirstToken == "addReadTag" ) applyAddTag( ifsInFile, READTAG ); else if (soFirstToken == "addConsensusTag" ) applyAddTag( ifsInFile, CONSENSUSTAG ); else if (soFirstToken == "deleteReadTag" ) applyDeleteTag( ifsInFile, READTAG ); else if (soFirstToken == "deleteConsensusTag" ) applyDeleteTag( ifsInFile, CONSENSUSTAG ); else if ( soFirstToken == "changeAllReads" ) applyChangeAllReads(); else if ( soFirstToken == "addColumnOfReadTags" ) applyAddColumnOfReadTags( ifsInFile ); else if ( soFirstToken == "overstrikeConsensus" ) applyOverstrikeConsensus(); else { PARSE_PANIC( "unrecognized operation" ); } } }