/***************************************************************************** # 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 "guiRemoveReads.h" #include #include #include #include #include #include #include #include "popupErrorMessage.h" #include "popupErrorMessage2.h" #include "guiapp.h" #include "handleWindowManagerDelete2.h" #include "hp_exception_kludge.h" #include #include "locatedFragment.h" #include "consed.h" #include "popupInfoMessage.h" #include "please_wait.h" #include "readsSortedByReadName.h" #include "contig.h" #include #include #include "consedParameters.h" #include "textbox.h" #include "soAddCommas.h" static void cbReadFileButton( Widget wid, XtPointer pClientData, XtPointer pCallData ) { guiRemoveReads* pRemove = (guiRemoveReads*) pClientData; TRY_CATCH_WRAPPER( pRemove->readFile() ); } static void cbCancelButton( Widget wid, XtPointer pClientData, XtPointer pCallData ) { guiRemoveReads* pRemove = (guiRemoveReads*) pClientData; TRY_CATCH_WRAPPER( delete pRemove ); } static void cbDoItButton( Widget wid, XtPointer pClientData, XtPointer pCallData ) { guiRemoveReads* pRemove = (guiRemoveReads*) pClientData; TRY_CATCH_WRAPPER( pRemove->doIt() ); } static void cbDeleteReadsOrPutInOwnContig( Widget wid, XtPointer pClientData, XtPointer pCallData ) { guiRemoveReads* pRemove = (guiRemoveReads*) pClientData; TRY_CATCH_WRAPPER( pRemove->deleteReadsOrPutInOwnContigValueChanged(); ); } // static void cbUserClickedOnAContig( Widget wid, // XtPointer pClientData, // XtPointer pCallData ) { // // debugging // cerr << "cbUserClickedOnAContig called" << endl; // // end debugging // } void guiRemoveReads :: createWindow() { int nArgs; Arg aArg[50]; widPopupShell_ = XtVaCreatePopupShell( "Remove Reads From Assembly", topLevelShellWidgetClass, GAPP->widGetTopLevel(), XmNtitle, "Remove Reads From Assembly", XmNnoResize, False, XmNtransient, False, XmNdeleteResponse, XmDO_NOTHING, NULL ); handleWindowManagerDelete2( widPopupShell_, cbCancelButton, this ); // create a form widget Widget widTopForm = XtVaCreateManagedWidget( "top form", xmFormWidgetClass, widPopupShell_, XmNshadowThickness, 0, XmNborderWidth, 0, NULL ); XmString xmsInstructions = XmStringCreateLtoR( "Either enter the file name containing reads to be deleted or else click on all \ncontigs whose reads are all to be deleted", XmFONTLIST_DEFAULT_TAG ); Widget widInstructions = XtVaCreateManagedWidget( "instructions", xmLabelWidgetClass, widTopForm, XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, 10, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XmNalignment, XmALIGNMENT_BEGINNING, XmNlabelString, xmsInstructions, NULL ); Widget widAbove = widInstructions; widFileOfReadNames_ = XtVaCreateManagedWidget( "file of read names", xmTextFieldWidgetClass, widTopForm, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, widAbove, XmNtopOffset, 10, NULL ); Widget widConnectToWidgetOnTop = widFileOfReadNames_; Widget widReadNamesLabel = XtVaCreateManagedWidget( "File of read names:", xmLabelWidgetClass, widTopForm, XmNleftAttachment, XmATTACH_FORM, XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET, XmNtopWidget, widFileOfReadNames_, XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET, XmNbottomWidget, widFileOfReadNames_, NULL ); const int nSpaceBetweenWidgets = 10; Dimension dimWidth; XtVaGetValues( widReadNamesLabel, XmNwidth, &dimWidth, NULL ); XtVaSetValues( widFileOfReadNames_, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, dimWidth + nSpaceBetweenWidgets, NULL ); XtAddCallback( widFileOfReadNames_, XmNactivateCallback, cbReadFileButton, this ); Widget widReadFileButton = XtVaCreateManagedWidget( "Read File", xmPushButtonWidgetClass, widTopForm, XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET, XmNtopWidget, widFileOfReadNames_, XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET, XmNbottomWidget, widFileOfReadNames_, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, widFileOfReadNames_, XmNleftOffset, 10, NULL ); XtAddCallback( widReadFileButton, XmNactivateCallback, cbReadFileButton, this ); Widget widContigListLabel = XtVaCreateManagedWidget( "Contigs:", xmLabelWidgetClass, widTopForm, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, widConnectToWidgetOnTop, XmNtopOffset, 30, XmNleftAttachment, XmATTACH_FORM, NULL ); Widget widReadListLabel = XtVaCreateManagedWidget( "Reads to be removed:", xmLabelWidgetClass, widTopForm, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, widConnectToWidgetOnTop, XmNtopOffset, 30, NULL ); // we will figure out where to put the left edge of this // label a little later widConnectToWidgetOnTop = widContigListLabel; // now work on widgets at the bottom of the window. Then we will // put on the scrolling list of reads last so that it will be the // widget to resize when the user expands the window. Widget widDoItButton = XtVaCreateManagedWidget( "Do It", xmPushButtonWidgetClass, widTopForm, XmNbottomAttachment, XmATTACH_FORM, XmNbottomOffset, 10, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, 20, XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, 40, NULL ); XtAddCallback( widDoItButton, XmNactivateCallback, cbDoItButton, this ); Widget widCancelButton = XtVaCreateManagedWidget( "Cancel", xmPushButtonWidgetClass, widTopForm, XmNbottomAttachment, XmATTACH_FORM, XmNbottomOffset, 10, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, 60, XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, 80, NULL ); XtAddCallback( widCancelButton, XmNactivateCallback, cbCancelButton, this ); Widget widConnectToWidgetOnBottom = widCancelButton; Widget widDeleteReadsOrPutInOwnContigsRadioBox = XmCreateRadioBox( widTopForm, "deleteOrPutInOwnContigs", NULL, 0 ); XtVaSetValues( widDeleteReadsOrPutInOwnContigsRadioBox, XmNtraversalOn, False, XmNbottomAttachment, XmATTACH_WIDGET, XmNbottomWidget, widConnectToWidgetOnBottom, XmNbottomOffset, 20, XmNleftAttachment, XmATTACH_FORM, XmNorientation, XmVERTICAL, NULL ); widDeleteReads_ = XtVaCreateManagedWidget( "Delete Reads from Assembly", xmToggleButtonWidgetClass, widDeleteReadsOrPutInOwnContigsRadioBox, XmNset, ( pCP->cRemoveReadsLastUsedDeleteOrJustPutInOwnContig_ == consedParameters::cDELETE_READS ? True : False ), NULL ); XtAddCallback( widDeleteReads_, XmNvalueChangedCallback, cbDeleteReadsOrPutInOwnContig, this ); Widget widPutReadsInOwnContigs = XtVaCreateManagedWidget( "Just Put Each Read Into Its Own Contig", xmToggleButtonWidgetClass, widDeleteReadsOrPutInOwnContigsRadioBox, XmNset, ( pCP->cRemoveReadsLastUsedDeleteOrJustPutInOwnContig_ == consedParameters::cDELETE_READS ? False : True ), NULL ); XtManageChild( widDeleteReadsOrPutInOwnContigsRadioBox ); widConnectToWidgetOnBottom = widDeleteReadsOrPutInOwnContigsRadioBox; // collect data to put in widScrollingListOfContigs Assembly* pAssembly = ConsEd::pGetAssembly(); XmStringTable ppXtString = (XmStringTable) XtMalloc( pAssembly->nNumContigs() * sizeof( XmString ) ); RWCString soLineToDisplay( (size_t) 100 ); int nContig; for( nContig = 0; nContig < pAssembly->nNumContigs(); ++nContig ) { Contig* pContig = pAssembly->pGetContig( nContig ); soLineToDisplay = pContig->soGetFancyName(); int nNumberOfReads = pContig->nGetNumberOfFragsInContig(); if ( nNumberOfReads == 1 ) { soLineToDisplay += ": "; LocatedFragment* pLocFrag = pContig->pLocatedFragmentGet( 0 ); soLineToDisplay += pLocFrag->soGetName(); } else { int nContigLength = pAssembly->pGetContig( nContig )->nGetUnpaddedSeqLength(); soLineToDisplay.increaseMaxLengthIfNecessary( 100 ); soLineToDisplay.appendFormat( " (%s reads, %s bps)", soAddCommas( nNumberOfReads ).data(), soAddCommas( nContigLength ).data() ); } ppXtString[ nContig ] = XmStringCreateLocalized( soLineToDisplay.data() ); } nArgs = 0; XtSetArg( aArg[ nArgs ], XmNtopAttachment, XmATTACH_WIDGET ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNtopWidget, widConnectToWidgetOnTop ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNbottomAttachment, XmATTACH_WIDGET ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNbottomWidget, widConnectToWidgetOnBottom ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNvisibleItemCount, 30 ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNtopOffset, 10 ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNbottomOffset, 10 ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNleftAttachment, XmATTACH_FORM ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNitems, ppXtString ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNitemCount, pAssembly->nNumContigs() ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNselectionPolicy, XmEXTENDED_SELECT ); ++nArgs; widScrollingListOfContigs_ = XmCreateScrolledList( widTopForm, "scrolledListOfContigs", aArg, nArgs ); XtManageChild( widScrollingListOfContigs_ ); // get rid of the ppXtString for( nContig = 0; nContig < pAssembly->nNumContigs(); ++nContig ) { XmStringFree( ppXtString[ nContig ] ); } XtFree( (char*) ppXtString ); nArgs = 0; XtSetArg( aArg[ nArgs ], XmNtopAttachment, XmATTACH_WIDGET ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNtopWidget, widConnectToWidgetOnTop ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNbottomAttachment, XmATTACH_WIDGET ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNbottomWidget, widConnectToWidgetOnBottom ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNvisibleItemCount, 30 ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNtopOffset, 10 ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNbottomOffset, 10 ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNleftAttachment, XmATTACH_WIDGET ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNleftWidget, widScrollingListOfContigs_ ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNleftOffset, 30 ); ++nArgs; widScrollingListOfReads_ = XmCreateScrolledList( widTopForm, "scrolledListOfReads", aArg, nArgs ); XtManageChild( widScrollingListOfReads_ ); // I couldn't get this to work // XtAddCallback( widScrollingListOfReads_, // XmNmultipleSelectionCallback, // cbUserClickedOnAContig, // this ); XtVaSetValues( widReadListLabel, XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET, XmNleftWidget, widScrollingListOfReads_, NULL ); XtPopup( widPopupShell_, XtGrabNone ); XmProcessTraversal( widFileOfReadNames_, XmTRAVERSE_CURRENT ); } void guiRemoveReads :: readFile() { char* szFileName; szFileName = XmTextFieldGetString( widFileOfReadNames_ ); FileName filReadNames = szFileName; XtFree( szFileName ); FILE* pFOF = fopen( filReadNames.data(), "r" ); if ( !pFOF ) { RWCString soError = "could not open file "; soError += filReadNames; soError += " because of error: "; soError += strerror( errno ); soError += " or "; soError += RWCString( (long) errno ); popupErrorMessage( soError ); return; } const int nMaxLineSize = 1000; RWCString soLine( (size_t) ( nMaxLineSize + 1 ) ); int nNumberOfReads = 0; while( fgets( soLine.data(), nMaxLineSize, pFOF ) != NULL ) { soLine.nCurrentLength_ = strlen( soLine.data() ); // there might be leading and/or trailing whitespace soLine.stripAllWhitespaceIncludingInternal(); // see if we can find this read LocatedFragment* pLocFrag = ConsEd::pGetAssembly()->pGetLocatedFragmentByName( soLine ); if ( !pLocFrag ) { popupErrorMessage( "read %s is not in the assembly", soLine.data() ); continue; } ++nNumberOfReads; } // the c (rather than c++) method: now that we know how much // space we need, allocate it and read the file again XmStringTable ppXtStringListOfReads = (XmStringTable) XtMalloc( nNumberOfReads * sizeof( XmString ) ); aReadsToRemove_.clear(); // in case the user has already read in // the file (or some other file) aReadsToRemove_.resize( (size_t) nNumberOfReads ); rewind( pFOF ); int nIndex = 0; while( fgets( soLine.data(), nMaxLineSize, pFOF ) != NULL ) { soLine.nCurrentLength_ = strlen( soLine.data() ); // there might be leading and/or trailing whitespace soLine.stripAllWhitespaceIncludingInternal(); // see if we can find this read LocatedFragment* pLocFrag = ConsEd::pGetAssembly()->pGetLocatedFragmentByName( soLine ); if ( !pLocFrag ) { continue; } ppXtStringListOfReads[ nIndex ] = XmStringCreateLocalized( soLine.data() ); aReadsToRemove_.insert( pLocFrag ); ++nIndex; } fclose( pFOF ); XtVaSetValues( widScrollingListOfReads_, XmNitems, ppXtStringListOfReads, XmNitemCount, nNumberOfReads, NULL ); } static int nCompareReadsByPointer( LocatedFragment** ppLocFrag1, LocatedFragment** ppLocFrag2 ) { if ( *ppLocFrag1 < *ppLocFrag2 ) return( -1 ); else if ( *ppLocFrag1 == *ppLocFrag2 ) { return( 0 ); } else { return( 1 ); } } void guiRemoveReads :: removeDuplicatedReads() { void* pArray = aReadsToRemove_.data(); size_t nNumberOfElements = aReadsToRemove_.length(); size_t nSizeOfAnElement = sizeof( LocatedFragment* ); qsort( pArray, nNumberOfElements, nSizeOfAnElement, ( int(*) ( const void*, const void*) ) nCompareReadsByPointer ); // check that they are in order bool bOutOfOrder = false; int nRead; for( nRead = 1; nRead < aReadsToRemove_.length(); ++nRead ) { LocatedFragment* pLocFragA = aReadsToRemove_[ nRead - 1]; LocatedFragment* pLocFragB = aReadsToRemove_[ nRead ]; if ( pLocFragA > pLocFragB ) { cerr << "out of order at positions " << nRead - 1 << " and " << nRead << endl; bOutOfOrder = true; } } if ( bOutOfOrder ) { THROW_ERROR( "reads out of order" ); } int nDuplicatedReads = 0; for( nRead = aReadsToRemove_.length() - 2; nRead >= 0; --nRead ) { LocatedFragment* pLocFragA = aReadsToRemove_[ nRead ]; LocatedFragment* pLocFragB = aReadsToRemove_[ nRead + 1 ]; if ( pLocFragA == pLocFragB ) { ++nDuplicatedReads; aReadsToRemove_.removeAt( nRead + 1 ); } } cerr << "removed " << nDuplicatedReads << " extra copies of duplicated reads" << endl; } guiRemoveReads :: ~guiRemoveReads() { if ( widPopupShell_ ) { XtPopdown( widPopupShell_ ); XtDestroyWidget( widPopupShell_ ); } } static int nCompareReadsByContig( LocatedFragment** ppLocFrag1, LocatedFragment** ppLocFrag2 ) { if ( (*ppLocFrag1)->pContig_->soGetName() < (*ppLocFrag2)->pContig_->soGetName() ) return( -1 ); else if ( (*ppLocFrag1)->pContig_->soGetName() == (*ppLocFrag2)->pContig_->soGetName() ) { // same contig. Should we have a definite order? I don't // think we need one. return( 0 ); } else { return( 1 ); } } void guiRemoveReads :: doIt() { bool bDeleteNotJustPutInOwnContig = ( XmToggleButtonGetState( widDeleteReads_ ) == True ? true : false ); RWTPtrOrderedVector aContigsToRemove; checkIfUserSelectedAnyContigs( aContigsToRemove ); if ( aContigsToRemove.length() > 0 && aReadsToRemove_.length() > 0 ) { popupErrorMessage2( widPopupShell_, "You read a file of reads and select contigs at the same time. Do one or the other at a time." ); return; } if ( aContigsToRemove.length() > 0 ) { contigsToRemoveToReadsToRemove( aContigsToRemove ); } doItAlmostNoGui( widPopupShell_, bDeleteNotJustPutInOwnContig ); delete this; } // no references to guiRemoveReads gui--that way this can be called from // guiPulloutWindow (AssemblyView) void guiRemoveReads :: doItAlmostNoGui( const Widget widParentShell, const bool bDeleteNotJustPutInOwnContig ) { PleaseWait* pPleaseWait = NULL; if ( pCP->bOKToUseGui_ ) { pPleaseWait = new PleaseWait( widParentShell ); } RWCString soMessage; doItNoGui( bDeleteNotJustPutInOwnContig, soMessage ); if ( pCP->bOKToUseGui_ ) { // put into a scrollable box int nNumberOfRowsNeeded = MIN( 20, aReadsToRemove_.length() + 5 ); TextBox* pTextBox = new TextBox( "Reads Removed", nNumberOfRowsNeeded ); pTextBox->append( soMessage ); pTextBox->makeVisible(); } if ( pCP->bOKToUseGui_ ) { ConsEd::pGetConsEd()->updateContigListOnMainConsedWindow(); } // must delete the PleaseWait object before deleting "this" since the // PleaseWait is a child of this's popup shell. if ( pPleaseWait ) delete pPleaseWait; } void guiRemoveReads :: doItNoGui( const bool bDeleteNotJustPutInOwnContig, RWCString& soMessage ) { removeDuplicatedReads(); if ( ( aReadsToRemove_.length() >= ConsEd::pGetAssembly()->nGetNumberOfReadsInAssembly() ) && bDeleteNotJustPutInOwnContig ) { THROW_ERROR( "No, Dave. You cannot delete all the reads in the assembly" ); } // sort aReadsToRemove_ by contig since we will be removing them // by contig void* pArray = aReadsToRemove_.data(); size_t nNumberOfElements = aReadsToRemove_.length(); size_t nSizeOfAnElement = sizeof( LocatedFragment* ); qsort( pArray, nNumberOfElements, nSizeOfAnElement, ( int(*) ( const void*, const void*) ) nCompareReadsByContig ); // check that the reads really are sorted by contig order bool bSorted = true; int nRead; for( nRead = 1; nRead < aReadsToRemove_.length(); ++nRead ) { LocatedFragment* pLocFrag1 = aReadsToRemove_[ nRead - 1 ]; LocatedFragment* pLocFrag2 = aReadsToRemove_[ nRead ]; if ( pLocFrag1->pContig_->soGetName() > pLocFrag2->pContig_->soGetName() ) { bSorted = false; cerr << "elements " << nRead - 1 << " (" << pLocFrag1->soGetName() << " from " << pLocFrag1->pContig_->soGetName() << ") and " << nRead << " (" << pLocFrag2->soGetName() << " from " << pLocFrag2->pContig_->soGetName() << ") are out of order " << endl; } } assert( bSorted ); Contig* pOldContig = NULL; readsSortedByReadName aReadsSortedByReadName; for( nRead = 0; nRead < aReadsToRemove_.length(); ++nRead ) { LocatedFragment* pLocFrag = aReadsToRemove_[ nRead ]; if ( pLocFrag->pContig_ == pOldContig ) { aReadsSortedByReadName.insert( pLocFrag ); } else { // change contigs. First process the old contig. Then // start a new contig. if ( pOldContig ) { // skip if we just started aReadsSortedByReadName.resort(); removeReadsFromOneContig( pOldContig, aReadsSortedByReadName ); } aReadsSortedByReadName.clear(); aReadsSortedByReadName.insert( pLocFrag ); pOldContig = pLocFrag->pContig_; } } // final case aReadsSortedByReadName.resort(); removeReadsFromOneContig( pOldContig, aReadsSortedByReadName ); // Now delete each of these contigs. // myReadsSortedByReadName may include reads that are not // in aReadsToRemove_ since myReadsSortedByReadName will include // all unaligned reads in the contigs. Let's not remove the // additional (unaligned) reads--they will just stay in their own // contigs. The user will be informed about them, though. if ( bDeleteNotJustPutInOwnContig ) soMessage += "\nNote: you must save the assembly or these changes will be lost. \nYou must delete the corresponding files from chromat_dir and \nphd_dir or else the next time you run phredPhrap, \nthese reads will be back in the ace file.\n\n"; else soMessage += "\nNote: you must save the assembly or these changes will be lost.\n\n"; if ( bDeleteNotJustPutInOwnContig ) soMessage += "removed "; else soMessage += "put into own contigs "; soMessage += RWCString( (long) aReadsToRemove_.length() ); soMessage += " reads:\n"; for( nRead = 0; nRead < aReadsToRemove_.length(); ++nRead ) { LocatedFragment* pLocFrag = aReadsToRemove_[ nRead ]; soMessage += pLocFrag->soGetName(); soMessage += "\n"; // now pLocFrag->pContig_ will be different Contig* pContigToRemove = pLocFrag->pContig_; assert( pContigToRemove->nGetNumberOfFragsInContig() == 1 ); if ( bDeleteNotJustPutInOwnContig ) { delete pContigToRemove; } } if ( aAdditionalReadsPutIntoOwnContigs_.length() > 0 ) { soMessage += " In addition, put the following reads into their own contigs \n(but did not remove them) because they were unaligned:\n"; for( nRead = 0; nRead < aAdditionalReadsPutIntoOwnContigs_.length(); ++nRead ) { LocatedFragment* pLocFrag = aAdditionalReadsPutIntoOwnContigs_[ nRead ]; if ( nRead != 0 ) { soMessage += ", "; } soMessage += pLocFrag->soGetName(); soMessage += "\n"; } } // popupInfoMessage( GAPP->widGetTopLevel(), soMessage.data() ); // update the top level window's list of contigs and reads // (the following is done by in contig6.cpp, but only when pulling // out a single read. For this mass pull, sort only once after // pulling reads from all contigs.) ConsEd::pGetAssembly()->sortContigsByName(); ConsEd::pGetAssembly()->setNumberOfReadsInAssemblyAccurate(); } void guiRemoveReads :: removeReadsFromOneContig( Contig* pContig, readsSortedByReadName aReadsSortedByReadName ) { RWTPtrOrderedVector aAdditionalReadsPutIntoOwnContigs; pContig->putReadsIntoTheirOwnContigs( &aReadsSortedByReadName, false, // bOKToUseGui 0, // nOldConsPosDisplayed &aAdditionalReadsPutIntoOwnContigs ); aAdditionalReadsPutIntoOwnContigs_ += aAdditionalReadsPutIntoOwnContigs; } void guiRemoveReads :: deleteReadsOrPutInOwnContigValueChanged() { // just save this for the next time the user uses this pCP->cRemoveReadsLastUsedDeleteOrJustPutInOwnContig_ = ( XmToggleButtonGetState( widDeleteReads_ ) == True ? consedParameters::cDELETE_READS : consedParameters::cPUT_EACH_READ_IN_ITS_OWN_CONTIG ); } void guiRemoveReads :: checkIfUserSelectedAnyContigs( RWTPtrOrderedVector& aContigsToRemove ) { aContigsToRemove.clear(); int* pPositionList; int nNumberOfSelectedItems; if ( !XmListGetSelectedPos( widScrollingListOfContigs_, &pPositionList, &nNumberOfSelectedItems ) ) { nNumberOfSelectedItems = 0; } for( int nSelected = 0; nSelected < nNumberOfSelectedItems; ++nSelected ) { int nPositionInDisplayedList = pPositionList[ nSelected ]; int nContig = nPositionInDisplayedList - 1; aContigsToRemove.insert( ConsEd::pGetAssembly()->pGetContig( nContig ) ); } } void guiRemoveReads :: contigsToRemoveToReadsToRemove( RWTPtrOrderedVector& aContigsToRemove ) { int nNumberOfReadsToRemove = 0; int nContig; for( nContig = 0; nContig < aContigsToRemove.length(); ++nContig ) { nNumberOfReadsToRemove += aContigsToRemove[ nContig ]->nGetNumberOfFragsInContig(); } aReadsToRemove_.clear(); aReadsToRemove_.resize( nNumberOfReadsToRemove ); for( nContig = 0; nContig < aContigsToRemove.length(); ++nContig ) { Contig* pContig = aContigsToRemove[ nContig ]; for( int nRead = 0; nRead < pContig->nGetNumberOfFragsInContig(); ++nRead ) { LocatedFragment* pLocFrag = pContig->pLocatedFragmentGet( nRead ); aReadsToRemove_.insert( pLocFrag ); } } }