/***************************************************************************** # 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 "guiFindRestrictionEnzymeSites.h" #include "consedParameters.h" #include "handleWindowManagerDelete2.h" #include "guiapp.h" #include #include #include #include #include #include #include "restrictionEnzyme.h" #include "contig.h" #include "consed.h" #include #include #include "popupErrorMessage.h" #include "guiDisplayDigest.h" #include "digestForOneEnzyme.h" #include "rwctokenizer.h" #include "hp_exception_kludge.h" #include "popupErrorMessage2.h" #include "please_wait.h" #include "bIsNumericMaybeWithWhitespace.h" #include "consed.h" #include "bGuiGetAnswerYesNo.h" #include "clScaffold.h" #include #include #include "complement_so.h" static void cbGuiShowDocumentationForRestrictionDigest( Widget wid, XtPointer pClientData, XtPointer pCallData ) { TRY_CATCH_WRAPPER( guiDisplayDigest::showDocumentationForRestrictionDigest() ); } static void cbWhatToDigest( Widget wid, XtPointer pClientData, XtPointer pCallData ) { guiFindRestrictionEnzymeSites* pGuiFind = (guiFindRestrictionEnzymeSites*) pClientData; TRY_CATCH_WRAPPER( pGuiFind->radioButtonChanged( wid, pCallData ); ); } static void cbUserPushedCancel( Widget wid, XtPointer pClientData, XtPointer pCallData ) { guiFindRestrictionEnzymeSites* pGuiFind = ( guiFindRestrictionEnzymeSites* ) pClientData; delete pGuiFind; } static void cbUserPushedOK( Widget wid, XtPointer pClientData, XtPointer pCallData ) { guiFindRestrictionEnzymeSites* pGuiFind = ( guiFindRestrictionEnzymeSites* ) pClientData; TRY_CATCH_WRAPPER( pGuiFind->userPushedOK() ); } guiFindRestrictionEnzymeSites :: guiFindRestrictionEnzymeSites() : pGuiDisplayDigest_( NULL ) { aSelectedEnzymeNames_.soName_ = "aSelectedEnzymeNames_"; aSelectedEnzymeBases_.soName_ = "aSelectedEnzymeBases_"; } void guiFindRestrictionEnzymeSites :: getUsersAnswers() { pCP->makeListOfRestrictionEnzymes(); widPopupShell_ = XtVaCreatePopupShell( "guiFindRestrictionSites", topLevelShellWidgetClass, GuiApp::pGetGuiApp()->widGetTopLevel(), XmNtitle, (char*) "Select Enzyme and Contigs", XmNtransient, False, XmNdeleteResponse, XmDO_NOTHING, NULL ); handleWindowManagerDelete2( widPopupShell_, cbUserPushedCancel, this ); // the immediate child of the application shell is a main window (so // there can be a menu bar) Widget widMainWin = XtVaCreateManagedWidget( "mainwin", xmMainWindowWidgetClass, widPopupShell_, XmNancestorSensitive, True, NULL ); // put menu bar on the main window int nArgs = 0; Arg aArg[ 50 ]; Widget widMenuBar = XmCreateMenuBar( widMainWin, "menubar", aArg, nArgs ); XtManageChild( widMenuBar ); // create help menu button nArgs = 0; Widget widHelpMenu = XmCreatePulldownMenu( widMenuBar, "Help", aArg, nArgs ); nArgs = 0; XtSetArg( aArg[ nArgs ], XmNsubMenuId, widHelpMenu ); ++nArgs; Widget widHelpCascade = XmCreateCascadeButton( widMenuBar, "Help", aArg, nArgs ); XtManageChild( widHelpCascade ); XtVaSetValues( widMenuBar, XmNmenuHelpWidget, widHelpCascade, NULL ); // now add help menu item Widget widShowDocumentation = XtVaCreateManagedWidget( "Show Documentation for Restriction Digest", xmPushButtonWidgetClass, widHelpMenu, NULL ); XtAddCallback( widShowDocumentation, XmNactivateCallback, cbGuiShowDocumentationForRestrictionDigest, this ); Widget widForm = XtVaCreateManagedWidget( "form", xmFormWidgetClass, widMainWin, XmNancestorSensitive, True, NULL ); // put buttons on the bottom widOKButton_ = XtVaCreateManagedWidget( "OK", xmPushButtonWidgetClass, widForm, XmNbottomAttachment, XmATTACH_FORM, XmNbottomOffset, 10, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, 35, XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, 45, NULL ); XtAddCallback( widOKButton_, XmNactivateCallback, (XtCallbackProc ) cbUserPushedOK, this ); Widget widCancelButton = XtVaCreateManagedWidget( "Cancel", xmPushButtonWidgetClass, widForm, XmNbottomAttachment, XmATTACH_FORM, XmNbottomOffset, 10, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, 55, XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, 65, NULL ); XtAddCallback( widCancelButton, XmNactivateCallback, (XtCallbackProc ) cbUserPushedCancel, this ); // build up from the bottom widPathnameOfVectorSequence_ = XtVaCreateManagedWidget( "Vector", xmTextFieldWidgetClass, widForm, XmNtraversalOn, True, XmNbottomAttachment, XmATTACH_WIDGET, XmNbottomWidget, widOKButton_, XmNbottomOffset, 10, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 10, XmNrightAttachment, XmATTACH_FORM, XmNrightOffset, 10, XmNvalue, pCP->filDefaultVectorPathnameForRestrictionFragments_.data(), NULL ); Widget widPathnameOfVectorSequenceLabel = XtVaCreateManagedWidget( "Full Pathname of File of Vector Sequence:", xmLabelWidgetClass, widForm, XmNbottomAttachment, XmATTACH_WIDGET, XmNbottomWidget, widPathnameOfVectorSequence_, XmNbottomOffset, 10, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 10, NULL ); Widget widBottomSoFar = widPathnameOfVectorSequenceLabel; widPathnameOfSizesFile_ = XtVaCreateManagedWidget( "Sizes", xmTextFieldWidgetClass, widForm, XmNtraversalOn, True, XmNbottomAttachment, XmATTACH_WIDGET, XmNbottomWidget, widBottomSoFar, XmNbottomOffset, 10, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 10, XmNrightAttachment, XmATTACH_FORM, XmNrightOffset, 10, XmNvalue, pCP->filRestrictionEnzymesActualFragmentsFile_.data(), NULL ); widBottomSoFar = widPathnameOfSizesFile_; Widget widPathnameOfSizesFileLabel = XtVaCreateManagedWidget( "Full Pathname of Actual Gel Sizes File:", xmLabelWidgetClass, widForm, XmNbottomAttachment, XmATTACH_WIDGET, XmNbottomWidget, widBottomSoFar, XmNbottomOffset, 10, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 10, NULL ); widBottomSoFar = widPathnameOfSizesFileLabel; widContigOrderAndOrientation_ = XtVaCreateManagedWidget( "Contigs", xmTextFieldWidgetClass, widForm, XmNtraversalOn, True, XmNbottomAttachment, XmATTACH_WIDGET, XmNbottomWidget, widBottomSoFar, XmNbottomOffset, 10, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 10, XmNrightAttachment, XmATTACH_FORM, XmNrightOffset, 10, NULL ); widBottomSoFar = widContigOrderAndOrientation_; RWCString soMessage = "Contig order and orientation:"; XmString xms = XmStringCreateLtoR( (char*) soMessage.data(), XmFONTLIST_DEFAULT_TAG ); Widget widContigOrderAndOrientationLabel = XtVaCreateManagedWidget( "ContigLabel", xmLabelWidgetClass, widForm, XmNlabelString, xms, XmNalignment, XmALIGNMENT_BEGINNING, XmNbottomAttachment, XmATTACH_WIDGET, XmNbottomWidget, widBottomSoFar, XmNbottomOffset, 10, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 10, NULL ); widBottomSoFar = widContigOrderAndOrientationLabel; XmStringFree( xms ); // now build down from the top XmString xmsCommonEnzymes = XmStringCreateLtoR( "Commonly Used\nRestriction\nEnzymes", XmFONTLIST_DEFAULT_TAG ); Widget widLabelCommonEnzymes = XtVaCreateManagedWidget( "common", xmLabelWidgetClass, widForm, XmNlabelString, xmsCommonEnzymes, XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, 20, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 20, NULL ); XmStringFree( xmsCommonEnzymes ); // build short list XmStringTable ppXtStringCommonEnzymes = (XmStringTable) XtMalloc( pCP->aCommonRestrictionEnzymes_.length() * sizeof( XmString ) ); int n; for( n = 0; n < pCP->aCommonRestrictionEnzymes_.length(); ++n ) { ppXtStringCommonEnzymes[ n ] = XmStringCreateLocalized( pCP->aCommonRestrictionEnzymes_[ n ].data() ); } XtSetArg( aArg[ nArgs ], XmNtopAttachment, XmATTACH_WIDGET ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNtopWidget, widLabelCommonEnzymes ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNtopOffset, 10 ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNbottomAttachment, XmATTACH_WIDGET ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNbottomWidget, widBottomSoFar ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNbottomOffset, 40 ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNleftWidget, widLabelCommonEnzymes ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNrightWidget, widLabelCommonEnzymes ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNvisibleItemCount, 20 ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNtraversalOn, True ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNitems, ppXtStringCommonEnzymes ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNitemCount, pCP->aCommonRestrictionEnzymes_.length() ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNselectionPolicy, XmMULTIPLE_SELECT ); ++nArgs; widCommonEnzymesList_ = XmCreateScrolledList( widForm, "commonList", aArg, nArgs ); XtManageChild( widCommonEnzymesList_ ); // pre-select any items RWTValOrderedVector aPreselectedEnzymes; RWCTokenizer tokPreselected( pCP->soDefaultSelectedRestrictionEnzymes_ ); RWCString soOnePreselectedEnzyme; while( !(soOnePreselectedEnzyme = tokPreselected()).isNull() ) { aPreselectedEnzymes.insert( soOnePreselectedEnzyme ); } for( n = 0; n < pCP->aCommonRestrictionEnzymes_.length(); ++n ) { for( int n2 = 0; n2 < aPreselectedEnzymes.length(); ++n2 ) { if ( pCP->aCommonRestrictionEnzymes_[n] == aPreselectedEnzymes[n2] ) { // found a preselected enzyme. Select it in the list int nListIndex = n + 1; XmListSelectPos( widCommonEnzymesList_, nListIndex, False ); break; } } } // label for huge list XmString xmsHugeList = XmStringCreateLtoR( "Huge List of\nRestriction\nEnzymes", XmFONTLIST_DEFAULT_TAG ); Widget widLabelHugeList = XtVaCreateManagedWidget( "huge", xmLabelWidgetClass, widForm, XmNlabelString, xmsHugeList, XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, 20, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, widLabelCommonEnzymes, XmNleftOffset, 40, NULL ); // now build huge list XmStringTable ppXtStringAllEnzymes = (XmStringTable) XtMalloc( pCP->aRestrictionEnzymes_.length() * sizeof( XmString ) ); for( n = 0; n < pCP->aRestrictionEnzymes_.length(); ++n ) { ppXtStringAllEnzymes[ n ] = XmStringCreateLocalized( pCP->aRestrictionEnzymes_[ n ]->soName_.data() ); } nArgs = 0; XtSetArg( aArg[ nArgs ], XmNtopAttachment, XmATTACH_WIDGET ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNtopWidget, widLabelCommonEnzymes ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNtopOffset, 10 ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNbottomAttachment, XmATTACH_WIDGET ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNbottomWidget, widBottomSoFar ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNbottomOffset, 40 ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNleftWidget, widLabelHugeList ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNvisibleItemCount, 20 ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNtraversalOn, True ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNitems, ppXtStringAllEnzymes ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNitemCount, pCP->aRestrictionEnzymes_.length() ); ++nArgs; XtSetArg( aArg[ nArgs ], XmNselectionPolicy, XmMULTIPLE_SELECT ); ++nArgs; widHugeEnzymesList_ = XmCreateScrolledList( widForm, "hugeList", aArg, nArgs ); XtManageChild(widHugeEnzymesList_ ); // radio box of digesting the entire clone or a portion of // the clone XmString xmsWhatToDigest = XmStringCreateLtoR( "What do you want to digest?", XmFONTLIST_DEFAULT_TAG ); Widget widWhatToDigestLabel = XtVaCreateManagedWidget( "whatToDigestLabel", xmLabelWidgetClass, widForm, XmNlabelString, xmsWhatToDigest, XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, 20, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, widLabelHugeList, XmNleftOffset, 40, NULL ); XmStringFree( xmsWhatToDigest ); Widget widWhatToDigestRadioBox = XmCreateRadioBox( widForm, "whatToDigestRadio", NULL, 0 ); XtVaSetValues( widWhatToDigestRadioBox, XmNtraversalOn, False, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, widWhatToDigestLabel, XmNtopOffset, 10, XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET, XmNleftWidget, widWhatToDigestLabel, XmNorientation, XmVERTICAL, NULL ); widDigestEntireClone_ = XtVaCreateManagedWidget( "Entire Clone", xmToggleButtonWidgetClass, widWhatToDigestRadioBox, XmNset, ( pCP->cFindRestrictionEnzymeSitesLastUsedWholeCloneOrPartOfCloneOrWholeContig_ == cWHOLE_CLONE ? True : False ), NULL ); XtAddCallback( widDigestEntireClone_, XmNvalueChangedCallback, cbWhatToDigest, this ); widDigestJustPartOfClone_ = XtVaCreateManagedWidget( "Just Part of Clone", xmToggleButtonWidgetClass, widWhatToDigestRadioBox, XmNset, ( pCP->cFindRestrictionEnzymeSitesLastUsedWholeCloneOrPartOfCloneOrWholeContig_ == cPART_OF_CLONE ? True : False ), NULL ); XtAddCallback( widDigestJustPartOfClone_, XmNvalueChangedCallback, cbWhatToDigest, this ); widDigestSingleContig_ = XtVaCreateManagedWidget( "Entire Single Contig", xmToggleButtonWidgetClass, widWhatToDigestRadioBox, XmNset, ( pCP->cFindRestrictionEnzymeSitesLastUsedWholeCloneOrPartOfCloneOrWholeContig_ == cWHOLE_CONTIG ? True : False ), NULL ); XtAddCallback( widDigestSingleContig_, XmNvalueChangedCallback, cbWhatToDigest, this ); XtManageChild( widWhatToDigestRadioBox ); // now the box for the user to enter the portion of the clone to // be digested XmString xmsWhatToDigest2 = XmStringCreateLtoR( // "Enter scaffold of contigs in same\nformat as the contig order\nand orientation map (below)", "Enter scaffold of contigs in\nsame format as the contig\norder and orientation map (below)", XmFONTLIST_DEFAULT_TAG ); widWhatToDigestLabel2_ = XtVaCreateManagedWidget( "whatToDigestLabel2", xmLabelWidgetClass, widForm, XmNlabelString, xmsWhatToDigest2, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, widWhatToDigestRadioBox, XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET, XmNleftWidget, widWhatToDigestRadioBox, XmNalignment, XmALIGNMENT_BEGINNING, XmNsensitive, ( pCP->cFindRestrictionEnzymeSitesLastUsedWholeCloneOrPartOfCloneOrWholeContig_ == cPART_OF_CLONE ? True : False ), NULL ); XmStringFree( xmsWhatToDigest2 ); widWhatToDigest_ = XtVaCreateManagedWidget( "whatToDigest", xmTextFieldWidgetClass, widForm, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, widWhatToDigestLabel2_, XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET, XmNleftWidget, widWhatToDigestLabel2_, XmNrightAttachment, XmATTACH_FORM, XmNrightOffset, 10, XmNsensitive, ( pCP->cFindRestrictionEnzymeSitesLastUsedWholeCloneOrPartOfCloneOrWholeContig_ == cPART_OF_CLONE ? True : False ), XmNvalue, ( pCP->cFindRestrictionEnzymeSitesLastUsedWholeCloneOrPartOfCloneOrWholeContig_ == cPART_OF_CLONE ? pCP->soFindRestrictionEnzymeSitesLastUsedUserEnteredContigMap_.data() : "" ), NULL ); XmString xmsLeftContigStartPos = XmStringCreateLtoR( "Leftmost Contig\nStart Pos:", XmFONTLIST_DEFAULT_TAG ); widLeftContigStartPosLabel_ = XtVaCreateManagedWidget( "LeftContigStartPosLabel", xmLabelWidgetClass, widForm, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, widWhatToDigest_, XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET, XmNleftWidget, widWhatToDigest_, XmNlabelString, xmsLeftContigStartPos, XmNsensitive, ( pCP->cFindRestrictionEnzymeSitesLastUsedWholeCloneOrPartOfCloneOrWholeContig_ == cPART_OF_CLONE ? True : False ), XmNalignment, XmALIGNMENT_BEGINNING, NULL ); XmStringFree( xmsLeftContigStartPos ); widLeftContigStartPos_ = XtVaCreateManagedWidget( "LeftContigStartPos", xmTextFieldWidgetClass, widForm, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, widLeftContigStartPosLabel_, XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET, XmNleftWidget, widLeftContigStartPosLabel_, XmNcolumns, 6, XmNsensitive, ( pCP->cFindRestrictionEnzymeSitesLastUsedWholeCloneOrPartOfCloneOrWholeContig_ == cPART_OF_CLONE ? True : False ), NULL ); if ( pCP->cFindRestrictionEnzymeSitesLastUsedWholeCloneOrPartOfCloneOrWholeContig_ == cPART_OF_CLONE ) { RWCString soLeftContigStartPos( (long) pCP->nFindRestrictionEnzymeSitesLastUsedStartUnpaddedConsPos_ ); XtVaSetValues( widLeftContigStartPos_, XmNvalue, soLeftContigStartPos.data(), NULL ); } XmString xmsRightContigEndPos = XmStringCreateLtoR( "Rightmost Contig\nEnd Pos:", XmFONTLIST_DEFAULT_TAG ); widRightContigEndPosLabel_ = XtVaCreateManagedWidget( "RightContigEndPosLabel", xmLabelWidgetClass, widForm, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, widWhatToDigest_, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, widLeftContigStartPosLabel_, XmNleftOffset, 1, XmNrightOffset, 5, // to fix shadow XmNlabelString, xmsRightContigEndPos, XmNalignment, XmALIGNMENT_BEGINNING, XmNsensitive, ( pCP->cFindRestrictionEnzymeSitesLastUsedWholeCloneOrPartOfCloneOrWholeContig_ == cPART_OF_CLONE ? True : False ), NULL ); XmStringFree( xmsRightContigEndPos ); widRightContigEndPos_ = XtVaCreateManagedWidget( "RightContigEndPos", xmTextFieldWidgetClass, widForm, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, widRightContigEndPosLabel_, XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET, XmNleftWidget, widRightContigEndPosLabel_, XmNcolumns, 6, XmNsensitive, ( pCP->cFindRestrictionEnzymeSitesLastUsedWholeCloneOrPartOfCloneOrWholeContig_ == cPART_OF_CLONE ? True : False ), NULL ); if ( pCP->cFindRestrictionEnzymeSitesLastUsedWholeCloneOrPartOfCloneOrWholeContig_ == cPART_OF_CLONE ) { RWCString soRightContigEndPos( (long) pCP->nFindRestrictionEnzymeSitesLastUsedEndUnpaddedConsPos_ ); XtVaSetValues( widRightContigEndPos_, XmNvalue, soRightContigEndPos.data(), NULL ); } // option menu for selecting which single contig Widget widSingleEntireContigForm = XtVaCreateManagedWidget( "single_entire_contig_form", xmFormWidgetClass, widForm, XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET, XmNleftWidget, widWhatToDigestRadioBox, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, widLeftContigStartPos_, XmNrightAttachment, XmATTACH_FORM, NULL ); widSingleEntireContigLabel_ = XtVaCreateManagedWidget( "Single entire contig:", xmLabelWidgetClass, widSingleEntireContigForm, XmNleftAttachment, XmATTACH_FORM, XmNtopAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, NULL ); widSingleEntireContig_ = XtVaCreateManagedWidget( "single_entire_contig", xmTextFieldWidgetClass, widSingleEntireContigForm, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, widSingleEntireContigLabel_, XmNtopAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, XmNcolumns, 10, XmNvalue, ( pCP->cFindRestrictionEnzymeSitesLastUsedWholeCloneOrPartOfCloneOrWholeContig_ == cWHOLE_CONTIG ? pCP->soFindRestrictionEnzymeSitesLastUsedContigAbbreviatedName_.data() : "" ), NULL ); if ( pCP->cFindRestrictionEnzymeSitesLastUsedWholeCloneOrPartOfCloneOrWholeContig_ != cWHOLE_CONTIG ) { XtVaSetValues( widSingleEntireContigLabel_, XmNsensitive, False, NULL ); XtVaSetValues( widSingleEntireContig_, XmNsensitive, False, NULL ); } XtPopup( widPopupShell_, XtGrabNone ); // clean up memory for( n = 0; n < pCP->aCommonRestrictionEnzymes_.length(); ++n ) { XmStringFree( ppXtStringCommonEnzymes[ n ] ); } XtFree( (char*) ppXtStringCommonEnzymes ); for( n = 0; n < pCP->aRestrictionEnzymes_.length(); ++n ) { XmStringFree( ppXtStringAllEnzymes[ n ] ); } XtFree( (char*) ppXtStringAllEnzymes ); fillInContigBox(); } guiFindRestrictionEnzymeSites :: ~guiFindRestrictionEnzymeSites() { XtPopdown( widPopupShell_ ); XtDestroyWidget( widPopupShell_ ); } void guiFindRestrictionEnzymeSites :: fillInContigBox() { // fill in order and orientation of contig PleaseWait* pPleaseWait = new PleaseWait( widPopupShell_ ); RWCString soDiagram = ConsEd::pGetAssembly()->soGetContigMap(); delete pPleaseWait; cerr << "contig map: " << soDiagram << endl; XtVaSetValues( widContigOrderAndOrientation_, XmNvalue, soDiagram.data(), NULL ); } bool guiFindRestrictionEnzymeSites :: bGetUsersChoices() { int* pPositionListCommon; int nNumberOfSelectedEnzymesCommon; if ( !XmListGetSelectedPos( widCommonEnzymesList_, &pPositionListCommon, &nNumberOfSelectedEnzymesCommon ) ) { nNumberOfSelectedEnzymesCommon = 0; } int* pPositionListHuge; int nNumberOfSelectedEnzymesHuge; if ( !XmListGetSelectedPos( widHugeEnzymesList_, &pPositionListHuge, &nNumberOfSelectedEnzymesHuge ) ) { nNumberOfSelectedEnzymesHuge = 0; } int nNumberOfSelectedEnzymes = nNumberOfSelectedEnzymesCommon + nNumberOfSelectedEnzymesHuge; if ( nNumberOfSelectedEnzymes == 0 ) { popupErrorMessage( "You must select at least 1 enzyme" ); return( false ); } aSelectedEnzymeNames_.clear(); aSelectedEnzymeBases_.clear(); aSelectedEnzymeNames_.resize( (size_t) nNumberOfSelectedEnzymes ); aSelectedEnzymeBases_.resize( (size_t) nNumberOfSelectedEnzymes ); int nSelected; for( nSelected = 0; nSelected < nNumberOfSelectedEnzymesCommon; ++nSelected ) { int nPositionInDisplayedList = pPositionListCommon[ nSelected ]; RWCString soSelectedEnzymeName = pCP->aCommonRestrictionEnzymes_[ nPositionInDisplayedList - 1 ]; // find the bases in the huge list restrictionEnzyme res; res.soName_ = soSelectedEnzymeName; int nIndex = pCP->aRestrictionEnzymes_.nFindIndexOfMatchOrSuccessor( &res ); if ( nIndex != RW_NPOS && pCP->aRestrictionEnzymes_[ nIndex ]->soName_ == soSelectedEnzymeName ) { RWCString soSelectedEnzymeBases = pCP->aRestrictionEnzymes_[ nIndex ]->soBases_; aSelectedEnzymeNames_.insert( soSelectedEnzymeName ); aSelectedEnzymeBases_.insert( soSelectedEnzymeBases ); } else { popupErrorMessage( "something wrong with common enzyme %s", soSelectedEnzymeName.data() ); return( false ); } } for( nSelected = 0; nSelected < nNumberOfSelectedEnzymesHuge; ++nSelected ) { int nPositionInDisplayedList = pPositionListHuge[ nSelected ]; RWCString soSelectedEnzymeName = pCP->aRestrictionEnzymes_[ nPositionInDisplayedList - 1 ]->soName_; RWCString soSelectedEnzymeBases = pCP->aRestrictionEnzymes_[ nPositionInDisplayedList - 1 ]->soBases_; aSelectedEnzymeNames_.insert( soSelectedEnzymeName ); aSelectedEnzymeBases_.insert( soSelectedEnzymeBases ); } assert( aSelectedEnzymeNames_.length() == aSelectedEnzymeBases_.length() ); // clean up memory XtFree( (char*) pPositionListCommon ); XtFree( (char*) pPositionListHuge ); if ( XmToggleButtonGetState( widDigestJustPartOfClone_ ) == True ) cWholeCloneOrPartOfCloneOrWholeContig_ = cPART_OF_CLONE; else if ( XmToggleButtonGetState( widDigestEntireClone_ ) == True ) cWholeCloneOrPartOfCloneOrWholeContig_ = cWHOLE_CLONE; else if ( XmToggleButtonGetState( widDigestSingleContig_ ) == True ) cWholeCloneOrPartOfCloneOrWholeContig_ = cWHOLE_CONTIG; else assert( false ); if ( cWholeCloneOrPartOfCloneOrWholeContig_ == cPART_OF_CLONE ) { char* szValue = XmTextFieldGetString( widWhatToDigest_ ); soUserEnteredContigMap_ = szValue; XtFree( szValue ); // let's do some elementary syntax checking first soUserEnteredContigMap_.stripAllWhitespaceIncludingInternal(); RWCString soUsage = "To do a digest of less than the entire assembly, you must enter the contigs in the order that you want them connected to be digested, as in 3-5c-2 where 3 means Contig3 and 5c means Contig5 is complemented and 2 means Contig2, connected in this order"; if ( soUserEnteredContigMap_.isNull() ) { popupErrorMessage2( widPopupShell_, "%s", soUsage.data() ); return( false ); } // now check that all the contigs exist RWCTokenizer tokContig( soUserEnteredContigMap_ ); Contig* pFirstContig = NULL; Contig* pLastContig = NULL; RWCString soContigAbb; while( !( soContigAbb = tokContig( '-' )).isNull() ) { if ( soContigAbb.cGetLastChar() == 'c' ) soContigAbb.remove( soContigAbb.length() - 1 ); // now let's see if what is left matches the abbreviated contig // name of some contig. This is probably a job for the Assembly // object Contig* pContig = ConsEd::pGetAssembly()->pGetContigByAbbreviatedName( soContigAbb ); if ( !pContig ) { popupErrorMessage2( widPopupShell_, "cannot find contig %s in the assembly. %s", soContigAbb.data(), soUsage.data() ); return( false ); } if ( !pFirstContig ) pFirstContig = pContig; pLastContig = pContig; } // check that the start and end positions are valid szValue = XmTextFieldGetString( widLeftContigStartPos_ ); RWCString soLeftmostContigStartPos = szValue; XtFree( szValue ); szValue = XmTextFieldGetString( widRightContigEndPos_ ); RWCString soRightmostContigEndPos = szValue; XtFree( szValue ); if ( !bIsNumericMaybeWithWhitespace( soLeftmostContigStartPos, nStartUnpaddedConsPos_ ) ) { popupErrorMessage2( widPopupShell_, "leftmost contig start pos must be numeric" ); return( false ); } if ( !bIsNumericMaybeWithWhitespace( soRightmostContigEndPos, nEndUnpaddedConsPos_ ) ) { popupErrorMessage2( widPopupShell_, "rightmost contig end pos must be numeric" ); return( false ); } if ( nStartUnpaddedConsPos_ < pFirstContig->nGetUnpaddedStartIndex() || pFirstContig->nGetUnpaddedEndIndex() < nStartUnpaddedConsPos_ ) { popupErrorMessage2( widPopupShell_, "leftmost contig start pos must be between %d and %d, the range of positions of contig %s", pFirstContig->nGetUnpaddedStartIndex(), pFirstContig->nGetUnpaddedEndIndex(), pFirstContig->soGetName().data() ); return( false ); } if ( nEndUnpaddedConsPos_ < pLastContig->nGetUnpaddedStartIndex() || pLastContig->nGetUnpaddedEndIndex() < nEndUnpaddedConsPos_ ) { popupErrorMessage2( widPopupShell_, "rightmost contig end pos must be between %d and %d, the range of positions of contig %s", pLastContig->nGetUnpaddedStartIndex(), pLastContig->nGetUnpaddedEndIndex(), pLastContig->soGetName().data() ); return( false ); } RWTPtrOrderedVector aScaffoldArray; RWCString soErrorMessage; ConsEd::pGetAssembly()->createScaffoldsFromUserContigMap( soUserEnteredContigMap_, nStartUnpaddedConsPos_, nEndUnpaddedConsPos_, &aScaffoldArray, soErrorMessage ); // we will create this all over again in doSearch--we just // created it to see what the problems were aScaffoldArray.clearAndDestroy(); if ( !soErrorMessage.isNull() ) { RWCString soQuestion = soErrorMessage + " Do you want to proceed (Yes) or not proceed (No) and modify your contig map?"; if ( !bGuiGetAnswerYesNo( soQuestion ) ) return( false ); } } // if ( cWholeCloneOrPartOfCloneOrWholeContig_ == cPART_OF_CLONE ) { else if ( cWholeCloneOrPartOfCloneOrWholeContig_ == cWHOLE_CONTIG ) { char* szContigName = XmTextFieldGetString( widSingleEntireContig_ ); RWCString soContigName( szContigName ); XtFree( szContigName ); Assembly* pAssembly = ConsEd::pGetAssembly(); Contig* pContig = pAssembly->pGetContigByName( soContigName ); if ( pContig == NULL ) { RWCString soTryAnother = "Contig" + soContigName; pContig = pAssembly->pGetContigByName( soTryAnother ); if ( pContig == NULL ) { popupErrorMessage2( widPopupShell_, "could not find contig %s", soContigName.data() ); return( false ); } } soUserEnteredContigMap_ = pContig->soGetAbbreviatedName(); nStartUnpaddedConsPos_ = pContig->nGetUnpaddedStartIndex(); nEndUnpaddedConsPos_ = pContig->nGetUnpaddedEndIndex(); // we will create this all over again in doSearch--we just // created it to see what the problems were RWTPtrOrderedVector aScaffoldArray; RWCString soErrorMessage; ConsEd::pGetAssembly()->createScaffoldsFromUserContigMap( soUserEnteredContigMap_, nStartUnpaddedConsPos_, nEndUnpaddedConsPos_, &aScaffoldArray, soErrorMessage ); aScaffoldArray.clearAndDestroy(); if ( !soErrorMessage.isNull() ) { RWCString soQuestion = soErrorMessage + " Do you want to proceed (Yes) or not proceed (No) and modify your contig map?"; if ( !bGuiGetAnswerYesNo( soQuestion ) ) return( false ); } } // save these answers for next time the user wants to bring up // a digest: pCP->cFindRestrictionEnzymeSitesLastUsedWholeCloneOrPartOfCloneOrWholeContig_ = cWholeCloneOrPartOfCloneOrWholeContig_; if ( cWholeCloneOrPartOfCloneOrWholeContig_ == cPART_OF_CLONE ) { pCP->soFindRestrictionEnzymeSitesLastUsedUserEnteredContigMap_ = soUserEnteredContigMap_; pCP->nFindRestrictionEnzymeSitesLastUsedStartUnpaddedConsPos_ = nStartUnpaddedConsPos_; pCP->nFindRestrictionEnzymeSitesLastUsedEndUnpaddedConsPos_ = nEndUnpaddedConsPos_; } else if ( cWholeCloneOrPartOfCloneOrWholeContig_ == cWHOLE_CONTIG ) { pCP->soFindRestrictionEnzymeSitesLastUsedContigAbbreviatedName_ = soUserEnteredContigMap_; // this actually is the abbreviated name } return( true ); } void guiFindRestrictionEnzymeSites :: userPushedOK() { if ( pGuiDisplayDigest_ ) delete pGuiDisplayDigest_; pGuiDisplayDigest_ = new guiDisplayDigest(); if (!bGetUsersChoices() ) return; try { readVectorSequence(); } catch( InputDataError eb) { popupErrorMessage2( widPopupShell_, eb.szGetDesc()); return; } createListOfDigestForOneEnzyme(); try { readActualGelSizesFile(); } catch( InputDataError eb ) { popupErrorMessage2( widPopupShell_, eb.szGetDesc() ); return; } // point of no return bool bUseUserEnteredContigMap; if ( cWholeCloneOrPartOfCloneOrWholeContig_ == cPART_OF_CLONE || cWholeCloneOrPartOfCloneOrWholeContig_ == cWHOLE_CONTIG ) bUseUserEnteredContigMap = true; else bUseUserEnteredContigMap = false; pGuiDisplayDigest_->createWindow( aSelectedEnzymeNames_, aSelectedEnzymeBases_, bUseUserEnteredContigMap, soUserEnteredContigMap_, nStartUnpaddedConsPos_, nEndUnpaddedConsPos_ ); pGuiDisplayDigest_->doSearch( ); delete this; } void guiFindRestrictionEnzymeSites :: readVectorSequence() { pGuiDisplayDigest_->soVectorSequence_ = ""; FileName filVectorPathname; char* szValue = XmTextFieldGetString( widPathnameOfVectorSequence_ ); filVectorPathname = szValue; XtFree( szValue ); if ( filVectorPathname.isNull() ) { RWCString soError = "you must specify a vector sequence file"; THROW_ERROR( soError ); } FILE* pVectorFile = fopen( filVectorPathname.data(), "r" ); if ( ! pVectorFile ) { if ( errno == 2 ) { RWCString soError = "there is no file " + filVectorPathname; THROW_ERROR( soError ); } else { RWCString soError = "could not open file " + filVectorPathname + "\nsince error = " + RWCString( (long) errno ) + " which means " + strerror( errno ); THROW_ERROR( soError ); } } // if we could open the file, save its name in case the user // used some file other than the default and will want to use // it again pCP->filDefaultVectorPathnameForRestrictionFragments_ = filVectorPathname; const int SZLINE_SIZE = 2000; RWCString soLine( (size_t) SZLINE_SIZE ); // first line must be of the form: // >name of sequence // We will just throw that away. if ( fgets( soLine.data(), SZLINE_SIZE, pVectorFile ) == NULL ) { RWCString soError = "file " + filVectorPathname + " is empty"; THROW_ERROR( soError ); } if ( soLine.data()[0] != '>' ) { RWCString soError = "vector file " + filVectorPathname + " must be in fasta format which means the first line must be of the form " + ">(name of vector\nand subsequent lines must just contain acgt"; THROW_ERROR( soError ); } while( fgets( soLine.data(), SZLINE_SIZE, pVectorFile ) != NULL ) { soLine.nCurrentLength_ = strlen( soLine.data() ); // chop off the trailing newline soLine.stripAllWhitespaceIncludingInternal(); soLine.toLower(); if ( strcspn( soLine.data(), "acgt" ) != 0 ) { RWCString soError; soError = "Vector data in " + filVectorPathname + " must just be acgt's, but instead contains " + soLine; if ( soLine.data()[0] == '>' ) { soError += "\nCould there be more than one vector in this file? There shouldn't be."; THROW_ERROR( soError ); } } pGuiDisplayDigest_->soVectorSequence_ += soLine; } fclose( pVectorFile ); pGuiDisplayDigest_->soComplementedVectorSequence_ = soComplementSO( pGuiDisplayDigest_->soVectorSequence_ ); } void guiFindRestrictionEnzymeSites :: createListOfDigestForOneEnzyme() { for( int nEnzyme = 0; nEnzyme < aSelectedEnzymeBases_.length(); ++nEnzyme ) { digestForOneEnzyme* pDigest = new digestForOneEnzyme(); pGuiDisplayDigest_->aDigests_.insert( pDigest ); pDigest->soEnzymeName_ = aSelectedEnzymeNames_[ nEnzyme ]; pDigest->soEnzymeBases_ = aSelectedEnzymeBases_[ nEnzyme ]; pDigest->pGuiDisplayDigest_ = pGuiDisplayDigest_; } } void guiFindRestrictionEnzymeSites :: readActualGelSizesFile() { char* szValue = XmTextFieldGetString( widPathnameOfSizesFile_ ); FileName filActualGelSizesFilePathname( szValue ); XtFree( szValue ); if ( filActualGelSizesFilePathname.isNull() ) return; FILE* pSizesFile = fopen( filActualGelSizesFilePathname.data(), "r" ); if ( !pSizesFile ) { if ( errno == 2 ) { RWCString soError = "there is no file " + filActualGelSizesFilePathname; THROW_ERROR( soError ); } else { RWCString soError = "could not open file " + filActualGelSizesFilePathname + "\nsince error = " + RWCString( (long) errno ) + " which means " + strerror( errno ); THROW_ERROR( soError ); } } // if the file could be opened, save it in case the user wants to use // the same file again pCP->filRestrictionEnzymesActualFragmentsFile_ = filActualGelSizesFilePathname; const int SZLINE_SIZE = 2000; RWCString soLine( (size_t) SZLINE_SIZE ); // we will only get the fragments for the particular enzymes we are // interested in. Those are in aSelectedEnzymeNames_. Some of // these may have aliases, however, so we should probably create a // list of those as well. Should we be concerned that the same // enzyme might be more than once in the file? RWTValOrderedVector aTempSelectedEnzymeNames = aSelectedEnzymeNames_; // make lower case for( int nEnzyme = 0; nEnzyme < aTempSelectedEnzymeNames.length(); ++nEnzyme ) { aTempSelectedEnzymeNames[ nEnzyme ].toLower(); } while( fgets( soLine.data(), SZLINE_SIZE, pSizesFile ) != NULL ) { soLine.nCurrentLength_ = strlen( soLine.data() ); if ( soLine.length() > 0 && soLine[0] == '>' ) { // found a header. Is it an enzyme we want? // get rid of > at beginning soLine = soLine.soGetRestOfString( 1 ); RWCTokenizer tok( soLine ); // there might be other data on the enzyme line, such as: // >EcoRI b48N4 44 532 RWCString soEnzyme = tok(); RWCString soEnzymeLowerCase = soEnzyme; soEnzymeLowerCase.toLower(); if ( aTempSelectedEnzymeNames.index( soEnzymeLowerCase ) == RW_NPOS ) continue; cerr << "found " << soEnzyme << " in aTempSelectedEnzymeNames " << endl; aTempSelectedEnzymeNames.removeAt( aTempSelectedEnzymeNames.index( soEnzymeLowerCase ) ); // found an enzyme we want. Find the corresponding // digestForOneEnzyme in aDigests_ digestForOneEnzyme* pDigestInFile = NULL; for( int nDigest = 0; nDigest < pGuiDisplayDigest_->aDigests_.length(); ++nDigest ) { digestForOneEnzyme* pDigest = pGuiDisplayDigest_->aDigests_[ nDigest ]; if ( pDigest->soEnzymeName_.returnToLower() == soEnzymeLowerCase ) { pDigestInFile = pDigest; break; } } if ( !pDigestInFile ) { RWCString soError = "program inconsistency for enzyme " + soEnzyme + " in file " + filActualGelSizesFilePathname; THROW_ERROR( soError ); } // now start reading the lines for the fragment sizes until // we get to the -1 delimiter pDigestInFile->aActualRestrictionFragments_.clearAndDestroy(); while( fgets( soLine.data(), SZLINE_SIZE, pSizesFile ) != NULL ) { soLine.nCurrentLength_ = strlen( soLine.data() ); soLine = soLine.stripWhitespace( RWCString::BOTH ); if ( soLine == "-1" ) break; int nFragmentSize; if ( !bIsNumericMaybeWithWhitespace( soLine, nFragmentSize ) ) { RWCString soError = soLine + " is not numeric but should be the fragment size in file " + filActualGelSizesFilePathname; THROW_ERROR( soError ); } restrictionFragment* pActualFrag = new restrictionFragment( restrictionFragment::ACTUAL_FRAGMENT ); pActualFrag->nSize_ = nFragmentSize; pActualFrag->fPositionOnGel_ = ConsEd::fGetPositionOnGelFromRestrictionFragmentSize( nFragmentSize ); pDigestInFile->aActualRestrictionFragments_.insert( pActualFrag ); } } // if ( soLine.length() > 0 && soLine[0] == '>' ) { } // while( fgets( soLine.data(), SZLINE_SIZE, pSizesFile ) != NULL ) { fclose( pSizesFile ); if ( aTempSelectedEnzymeNames.length() != 0 ) { RWCString soError = "problem: the actual fragment sizes file " + filActualGelSizesFilePathname + " did not contain data for the following enzymes: "; for( int n = 0; n < aTempSelectedEnzymeNames.length(); ++n ) { soError += aTempSelectedEnzymeNames[n]; soError += " "; } THROW_ERROR( soError ); } for( int nDigest = 0; nDigest < pGuiDisplayDigest_->aDigests_.length(); ++nDigest ) { digestForOneEnzyme* pDigest = pGuiDisplayDigest_->aDigests_[ nDigest ]; pDigest->aActualRestrictionFragments_.sortFragmentsBySize(); } } void guiFindRestrictionEnzymeSites :: radioButtonChanged( Widget wid, XtPointer pCallData ) { if ( wid == widDigestJustPartOfClone_ ) { Boolean bSensitiveFlag = XmToggleButtonGetState( widDigestJustPartOfClone_ ); XtVaSetValues( widWhatToDigestLabel2_, XmNsensitive, bSensitiveFlag, NULL ); XtVaSetValues( widWhatToDigest_, XmNsensitive, bSensitiveFlag, NULL ); XtVaSetValues( widLeftContigStartPosLabel_, XmNsensitive, bSensitiveFlag, NULL ); XtVaSetValues( widLeftContigStartPos_, XmNsensitive, bSensitiveFlag, NULL ); XtVaSetValues( widRightContigEndPosLabel_, XmNsensitive, bSensitiveFlag, NULL ); XtVaSetValues( widRightContigEndPos_, XmNsensitive, bSensitiveFlag, NULL ); } else if ( wid == widDigestSingleContig_ ) { Boolean bSensitiveFlag = XmToggleButtonGetState( widDigestSingleContig_ ); XtVaSetValues( widSingleEntireContigLabel_, XmNsensitive, bSensitiveFlag, NULL ); XtVaSetValues( widSingleEntireContig_, XmNsensitive, bSensitiveFlag, NULL ); } }