1699 lines
39 KiB
C
1699 lines
39 KiB
C
/*
|
|
* File: oligo.c
|
|
* Version:
|
|
*
|
|
* Author: Simon Dear
|
|
* MRC Laboratory of Molecular Biology
|
|
* Hills Road
|
|
* Cambridge CB2 2QH
|
|
* United Kingdom
|
|
*
|
|
* Description: oligo selection module
|
|
*
|
|
* Created: 1991
|
|
* Updated: 6 November 1992
|
|
*
|
|
* 6 November 1992
|
|
* Changes for distribution
|
|
*/
|
|
#include <stdio.h>
|
|
#include <stdlib.h> /* getenv & malloc */
|
|
#include <string.h>
|
|
|
|
#include <X11/StringDefs.h>
|
|
#include <X11/Intrinsic.h>
|
|
#include <X11/Shell.h>
|
|
#include <X11/Xaw/Form.h>
|
|
#include <X11/Xaw/Label.h>
|
|
#include <X11/Xaw/Box.h>
|
|
#include <X11/Xaw/Toggle.h>
|
|
#include <X11/Xaw/Text.h>
|
|
#include <X11/Xaw/Command.h>
|
|
#include <X11/Xaw/MenuButton.h>
|
|
#include <X11/Xaw/SimpleMenu.h>
|
|
#include <X11/Xaw/SmeBSB.h>
|
|
|
|
#include "edUtils.h"
|
|
#include "myparams.h"
|
|
#include "defn.h"
|
|
#include "struct.h"
|
|
#include "tagUtils.h"
|
|
#include "oligo.h"
|
|
#include "misc.h"
|
|
#include "oligocom.h"
|
|
|
|
/*
|
|
* Compilation modes:
|
|
*
|
|
* NEMATODE - Make some features switchable by the environment variable SUBCLONES
|
|
* VERBOSENESS - Allow for varying degress of verbose output, including debugging information
|
|
*/
|
|
#define NEMATODE
|
|
#define VERBOSENESS
|
|
|
|
/* nematode - the drink when you're not having a drink */
|
|
int nematode;
|
|
|
|
|
|
#include "subclone.h"
|
|
|
|
/*
|
|
* Useful #defines
|
|
*/
|
|
#define FORWARDS True
|
|
#define BACKWARDS False
|
|
extern void messagef(char *format, ...);
|
|
|
|
/*
|
|
* Widgets and things
|
|
*/
|
|
static EdStruct *thisxx; /* the current EdStruct */
|
|
static int up = 0;
|
|
static Widget oldFogieWid;
|
|
static Widget oligoWid = NULL;
|
|
static Widget form;
|
|
static Widget label;
|
|
|
|
static Widget bbox, strand;
|
|
static int strand_state = FORWARDS;
|
|
|
|
static Widget cbox, change;
|
|
static Widget dbox, find, next;
|
|
static Widget template;
|
|
static Widget ebox, ok, quit;
|
|
|
|
/*
|
|
* Current state of selection
|
|
*/
|
|
static int p; /* cursor position for selection */
|
|
static int l,r; /* position of left and right ends of selection region */
|
|
static int num_oligos; /* number of oligo selected last time */
|
|
static int curr_oligo; /* number of current oligo being considered */
|
|
static Boolean oligo_sense; /* status of sense buttons when find-oligo button pressed */
|
|
static int template_index; /* gel number of current selected template */
|
|
static char template_name[DB_NAMELEN+1]; /* gel name of current selected template */
|
|
static char *consensus = NULL; /* consensus for region used to select oligo*/
|
|
|
|
/*
|
|
* Parameters for template selection
|
|
*/
|
|
#ifdef VERBOSENESS
|
|
static int verbose = 1; /* verbose output is required */
|
|
char verbosity[10]; /* space for string form of verbose */
|
|
#define verbose_debug (verbose==2 || verbose==3)
|
|
#define verbose_panic (verbose==3)
|
|
#endif /*VERBOSENESS*/
|
|
|
|
static int fwd_width = 40; /* how far ahead search window should stretch */
|
|
static int bkwd_width = 40; /* how far back search window should stretch */
|
|
|
|
static int def_insert_size = 1000; /* How far from start of template oligo can be */
|
|
static char filter[100] = "\\.[sSfFrR]1[^a-z]"; /* filter out templates from gel names */
|
|
static char clonelib[100]; /* library of subclone information: initialised in initialise()*/
|
|
static int ave_read_len = 400; /* average read length */
|
|
|
|
|
|
/*
|
|
* A few necessary forward declarations
|
|
*/
|
|
static int findOligos(EdStruct *xx, int sense);
|
|
static void nextOligo(EdStruct *xx, int oligo, int sense);
|
|
static int create_new_oligo_tag(EdStruct *xx, int oligo, int pos, int len, int sense);
|
|
static void destroy_oligo_popup();
|
|
static void destroy_temporary_tag(EdStruct *xx);
|
|
static void display_template_details();
|
|
|
|
|
|
/*********************************************************************************/
|
|
/*
|
|
* Start of code proper
|
|
*/
|
|
|
|
|
|
/*
|
|
* Callback routines
|
|
*/
|
|
|
|
|
|
static void set_strand_state(Widget w, int strand_state)
|
|
{
|
|
Arg args[2];
|
|
Cardinal nargs;
|
|
|
|
nargs = 0;
|
|
XtSetArg(args[nargs], XtNlabel, (strand_state==FORWARDS)?"------>":"<------"); nargs++;
|
|
XtSetValues(w,args,nargs);
|
|
|
|
}
|
|
|
|
|
|
static void strandCallback(Widget w, XtPointer client_data, XtPointer call_data)
|
|
/*
|
|
* Change strand
|
|
*/
|
|
{
|
|
strand_state = (strand_state == FORWARDS)?BACKWARDS:FORWARDS;
|
|
set_strand_state(w,strand_state);
|
|
|
|
XtCallCallbacks(find, XtNcallback, (XtPointer) NULL);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
* Move data[] outside scope of following function - non ANSI to perform
|
|
* aggregate definitions inside a function
|
|
*/
|
|
Field_entry data_1[] = {
|
|
{"Search window bases ahead", (char *)&fwd_width, t_int, sizeof(fwd_width)},
|
|
{"Search window bases back", (char *)&bkwd_width, t_int, sizeof(bkwd_width)},
|
|
{"Default insert size", (char *)&def_insert_size, t_int, sizeof(def_insert_size)},
|
|
{"Average read length", (char *)&ave_read_len, t_int, sizeof(ave_read_len)},
|
|
{"Filter to select templates", (char *)filter, t_char, sizeof(filter)},
|
|
{"Cosmid subclone library", (char *)clonelib, t_char, sizeof(clonelib)},
|
|
#ifdef VERBOSENESS
|
|
{"Verbose output?", (char *)verbosity, t_char, sizeof(verbosity)}
|
|
#endif /*VERBOSENESS*/
|
|
};
|
|
|
|
static void changeMineCallback(Widget w, XtPointer client_data, XtPointer call_data)
|
|
/*
|
|
* Change oligo selection parameters
|
|
*/
|
|
{
|
|
#ifdef VERBOSENESS
|
|
if (verbose_debug) message("Change my parameters\n");
|
|
|
|
/* Verbose output can be "yes", "no", "debug", or "panic"!!!! */
|
|
switch (verbose) {
|
|
case 0: strcpy(verbosity,"No"); break;
|
|
case 1: strcpy(verbosity,"Yes"); break;
|
|
case 2: strcpy(verbosity,"Debug"); break;
|
|
case 3: strcpy(verbosity,"Panic"); break;
|
|
}
|
|
#endif /*VERBOSENESS*/
|
|
|
|
change_params((Widget)w,NULL,data_1,nematode?XtNumber(data_1):4);
|
|
|
|
#ifdef VERBOSENESS
|
|
switch ( verbosity[0] ) {
|
|
case 'p': case 'P':
|
|
verbose = 3;
|
|
break;
|
|
case 'd': case 'D':
|
|
verbose = 2;
|
|
break;
|
|
case 'y': case 'Y':
|
|
verbose = 1;
|
|
break;
|
|
default:
|
|
verbose = 0;
|
|
break;
|
|
}
|
|
#endif /*VERBOSENESS*/
|
|
|
|
XtCallCallbacks(find, XtNcallback, (XtPointer) NULL);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void changeParamsCallback(Widget w, XtPointer client_data, XtPointer call_data)
|
|
/*
|
|
* Change oligo selection parameters
|
|
*/
|
|
{
|
|
#ifdef VERBOSENESS
|
|
if (verbose_debug) message("Change selection parameters\n");
|
|
#endif /*VERBOSENESS*/
|
|
osp_change_parameters(w,&prm,0/*params*/);
|
|
|
|
XtCallCallbacks(find, XtNcallback, (XtPointer) NULL);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void changeWeightsCallback(Widget w, XtPointer client_data, XtPointer call_data)
|
|
/*
|
|
* Change oligo selection parameters
|
|
*/
|
|
{
|
|
#ifdef VERBOSENESS
|
|
if (verbose_debug) message("Change selection weights\n");
|
|
#endif /*VERBOSENESS*/
|
|
osp_change_parameters(w,&prm,1/*weights*/);
|
|
|
|
XtCallCallbacks(find, XtNcallback, (XtPointer) NULL);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void informationCallback(Widget w, XtPointer client_data, XtPointer call_data)
|
|
/*
|
|
* Change oligo selection parameters
|
|
*/
|
|
{
|
|
#ifdef VERBOSENESS
|
|
if (verbose_debug) message("Display information\n");
|
|
#endif /*VERBOSENESS*/
|
|
messagef("%s\n",score_info);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void findCallback(Widget w, XtPointer client_data, XtPointer call_data)
|
|
/*
|
|
* Search for oligo
|
|
*/
|
|
{
|
|
#ifdef VERBOSENESS
|
|
if (verbose_debug) message("Find oligos\n");
|
|
#endif /*VERBOSENESS*/
|
|
|
|
oligo_sense = strand_state;
|
|
|
|
(void) findOligos(thisxx,oligo_sense);
|
|
|
|
/*
|
|
* Reveal buttons depending on result
|
|
*/
|
|
XawFormDoLayout(form,False);
|
|
if (num_oligos>0) {
|
|
XtManageChild(ok);
|
|
XtManageChild(template);
|
|
} else {
|
|
XtUnmanageChild(ok);
|
|
XtUnmanageChild(template);
|
|
}
|
|
if (num_oligos > 1)
|
|
XtManageChild(next);
|
|
else
|
|
XtUnmanageChild(next);
|
|
XawFormDoLayout(form,True);
|
|
|
|
curr_oligo = 0;
|
|
|
|
if (num_oligos>0)
|
|
nextOligo(thisxx,curr_oligo,oligo_sense);
|
|
else
|
|
destroy_temporary_tag(thisxx);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void nextCallback(Widget w, XtPointer client_data, XtPointer call_data)
|
|
/*
|
|
* Search for oligo
|
|
*/
|
|
{
|
|
#ifdef VERBOSENESS
|
|
if (verbose_debug) message("Select next oligo\n");
|
|
#endif /*VERBOSENESS*/
|
|
curr_oligo++;
|
|
if (curr_oligo+1 == num_oligos) {
|
|
XawFormDoLayout(form,False);
|
|
XtUnmanageChild(next);
|
|
XawFormDoLayout(form,True);
|
|
}
|
|
|
|
nextOligo(thisxx,curr_oligo,oligo_sense);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void okCallback(Widget w, XtPointer client_data, XtPointer call_data)
|
|
/*
|
|
* Select current oligo,
|
|
* Create a tag for it and everything else...
|
|
*/
|
|
{
|
|
int i = curr_oligo;
|
|
|
|
|
|
/*
|
|
* To create a new oligo a valid template must have been specified
|
|
*/
|
|
if (!template_index) {
|
|
message("A valid template has not been specified\n");
|
|
return;
|
|
}
|
|
if (oligo_sense == BACKWARDS) {
|
|
(void) create_new_oligo_tag(thisxx,i,
|
|
r-OSP_RESULTS[i].end_position,
|
|
OSP_RESULTS[i].end_position-OSP_RESULTS[i].start_position+1,
|
|
oligo_sense);
|
|
} else {
|
|
(void) create_new_oligo_tag(thisxx,i,
|
|
l+OSP_RESULTS[i].start_position,
|
|
OSP_RESULTS[i].end_position-OSP_RESULTS[i].start_position+1,
|
|
oligo_sense);
|
|
}
|
|
|
|
up = 0;
|
|
|
|
destroy_oligo_popup();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void quitCallback(Widget w, XtPointer client_data, XtPointer call_data)
|
|
/*
|
|
* Leave without selecting an oligo
|
|
*/
|
|
{
|
|
up = 0;
|
|
|
|
destroy_oligo_popup();
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************************/
|
|
|
|
static void initialise()
|
|
/*
|
|
* Initialise miscellaneous variables
|
|
*/
|
|
{
|
|
char *subclones;
|
|
|
|
/* clonelib = subclones:$SUBCLONES */
|
|
if (is_file("subclones"))
|
|
strcpy(clonelib,"subclones");
|
|
else {
|
|
subclones = (char *) getenv("SUBCLONES");
|
|
if (subclones == NULL)
|
|
clonelib[0] = '\0';
|
|
else if (is_file(subclones))
|
|
strcpy(clonelib,subclones);
|
|
else
|
|
clonelib[0] = '\0';
|
|
}
|
|
#ifdef NEMATODE
|
|
nematode=(getenv("SUBCLONES")!=NULL);
|
|
#else /*NEMATODE*/
|
|
nematode=1;
|
|
#endif /*NEMATODE*/
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static void destroy_temporary_tag(EdStruct *xx)
|
|
/*
|
|
* Flag temporary tag as deleted
|
|
*/
|
|
{
|
|
if (DBgetTags(xx,0) != NULL) {
|
|
_delete_tag(xx, 0/*consensus*/, DBgetTags(xx,0));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void create_temporary_tag(EdStruct *xx,int pos, int len)
|
|
/*
|
|
* Create a temporary tag in the consensus to show position of oligo under consideration
|
|
*/
|
|
{
|
|
char *defComment = "*** Temporary Annotation ***\n";
|
|
|
|
tagStruct *tempTag;
|
|
tempTag = DBgetTags(xx,0);
|
|
|
|
/*
|
|
* Create a new tag and insert it with comment into bimbo falix
|
|
*/
|
|
if (tempTag == NULL) {
|
|
tempTag = newTag();
|
|
strncpy(tempTag->tagrec.type.c,"OLIG",4);
|
|
tempTag->newcomment = (char *)malloc(strlen(defComment)+1);
|
|
strcpy(tempTag->newcomment,defComment);
|
|
tempTag->flags =
|
|
TAG_INSERTED |
|
|
TAG_LENGTH_CHANGED |
|
|
TAG_POSITION_CHANGED |
|
|
TAG_TYPE_CHANGED |
|
|
TAG_COMMENT_IN_MEMORY;
|
|
insertTag(xx,0/*consensus*/,tempTag);
|
|
}
|
|
|
|
tempTag->tagrec.position = pos;
|
|
tempTag->tagrec.length = len;
|
|
|
|
/*
|
|
* Jiggle about if tag is off screen
|
|
*/
|
|
if (xx->displayPos > pos || xx->displayPos + xx->displayWidth < pos + len )
|
|
xx->displayPos = (pos+pos+len-xx->displayWidth)/2;
|
|
|
|
redisplaySequences (xx,
|
|
xx->namesWid,
|
|
xx->sequencesWid,
|
|
xx->displayPos,
|
|
xx->displayWidth);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int gel_ok(EdStruct *xx, int pos, int len, int seq)
|
|
/*
|
|
* If gel overlaps region in contig,
|
|
* return true
|
|
*/
|
|
{
|
|
return (pos >= DBgetRelPos(xx,seq) && pos+len <= DBgetRelPos(xx,seq)+DBgetLength(xx,seq));
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int find_gel_for_oligo(EdStruct *xx, int pos, int len, int sense, int trySeq)
|
|
/*
|
|
* Find a gel number for this oligo. Try
|
|
* (A) gel trySeq first, (if valid)
|
|
* (B) then any in the correct sense,
|
|
* (C) otherwise any at all??
|
|
* The position here is a position in the contig
|
|
*/
|
|
{
|
|
int i;
|
|
#ifdef VERBOSENESS
|
|
if (verbose_debug) messagef("Trying to find gel for oligo: pos=%d, len=%d, sense=%d\n",pos,len,sense);
|
|
#endif /*VERBOSENESS*/
|
|
|
|
/**A**/
|
|
if (trySeq > 0) {
|
|
#ifdef VERBOSENESS
|
|
if (verbose_debug) messagef("find_gel_for_oligo: Trying gel %s (%d)...\n",DBgetName(xx,trySeq),trySeq);
|
|
#endif /*VERBOSENESS*/
|
|
if ( gel_ok(xx,pos,len,trySeq) ) {
|
|
#ifdef VERBOSENESS
|
|
if (verbose_debug) messagef("Using gel %s (%d)...\n",DBgetName(xx,trySeq),trySeq);
|
|
#endif /*VERBOSENESS*/
|
|
return trySeq;
|
|
}
|
|
}
|
|
|
|
/**B**/
|
|
#ifdef VERBOSENESS
|
|
if (verbose_debug) message("find_gel_for_oligo: Trying gels in correct sense\n");
|
|
#endif /*VERBOSENESS*/
|
|
for (i=1; i<=xx->DB_gelCount ; i++) {
|
|
if (DBgetComp(xx,i) == COMPLEMENTED && sense == BACKWARDS ||
|
|
DBgetComp(xx,i) == UNCOMPLEMENTED && sense == FORWARDS) {
|
|
if (gel_ok(xx,pos,len,i)) {
|
|
#ifdef VERBOSENESS
|
|
if (verbose_debug) messagef("Using gel %s (%d)...\n",DBgetName(xx,trySeq),trySeq);
|
|
#endif /*VERBOSENESS*/
|
|
return i;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**C**/
|
|
#ifdef VERBOSENESS
|
|
if (verbose_debug) message("find_gel_for_oligo: Trying any gel\n");
|
|
#endif /*VERBOSENESS*/
|
|
for (i=1; i<=xx->DB_gelCount ; i++) {
|
|
if (gel_ok(xx,pos,len,i)) {
|
|
#ifdef VERBOSENESS
|
|
if (verbose_debug) messagef("Using gel %s (%d)...\n",DBgetName(xx,trySeq),trySeq);
|
|
#endif /*VERBOSENESS*/
|
|
return i;
|
|
}
|
|
}
|
|
|
|
#ifdef VERBOSENESS
|
|
if (verbose_debug) message("find_gel_for_oligo: Failed to find any suitable gel\n");
|
|
#endif /*VERBOSENESS*/
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static char *generate_oligo_comment(int oligo)
|
|
{
|
|
char s[200];
|
|
char seq[100];
|
|
char *c;
|
|
|
|
int pos,len;
|
|
#ifdef VERBOSENESS
|
|
if (verbose_debug) message("creating comment for oligo:\n");
|
|
#endif /*VERBOSENESS*/
|
|
pos = OSP_RESULTS[oligo].start_position;
|
|
len = OSP_RESULTS[oligo].end_position - pos + 1;
|
|
strncpy(seq,&consensus[pos],len);
|
|
seq[len]='\0';
|
|
|
|
|
|
sprintf(s,"serial#=\ntemplate=%s\nsequence=%s\nflags=\n",template_name,seq);
|
|
#ifdef VERBOSENESS
|
|
if (verbose_debug) messagef("(%s)\n",s);
|
|
#endif /*VERBOSENESS*/
|
|
|
|
c = TAG_MALLOC(strlen(s)+1);
|
|
strcpy(c,s);
|
|
return c;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int create_new_oligo_tag(EdStruct *xx, int oligo, int pos, int len, int sense)
|
|
/*
|
|
* This routine creates a new oligo tag, prior to leaving the
|
|
* oligo selection window
|
|
*/
|
|
{
|
|
tagStruct *new_oligo;
|
|
int seq;
|
|
|
|
seq = find_gel_for_oligo(xx,pos,len,sense,template_index);
|
|
|
|
if (! seq) {
|
|
messagef("NO SUITABLE GEL FOR THIS OLIGO TAG POSITION %d LENGTH %d\n",pos,len);
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
* Create a new tag and insert it with comment into bimbo falix
|
|
*/
|
|
new_oligo = newTag();
|
|
strncpy(new_oligo->tagrec.type.c,"OLIG",4);
|
|
new_oligo->tagrec.position = normalisePos(xx,seq,pos-DBgetRelPos(xx,seq)+1,len);
|
|
new_oligo->tagrec.length = len;
|
|
new_oligo->flags = TAG_INSERTED | TAG_LENGTH_CHANGED | TAG_POSITION_CHANGED | TAG_TYPE_CHANGED;
|
|
insertTag(xx,seq,new_oligo);
|
|
|
|
new_oligo->flags |= TAG_COMMENT_IN_MEMORY;
|
|
new_oligo->newcomment = generate_oligo_comment(oligo);
|
|
|
|
/*set modified tag flag */
|
|
DBsetFlags(xx,seq,DBgetFlags(xx,seq)|DB_FLAG_TAG_MODIFIED);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int oligo_comp_pos(const void *pa, const void *pb)
|
|
/*
|
|
* we need to sort the oligos according to how far they are from the
|
|
* cursor position (p)
|
|
*/
|
|
{
|
|
const OSP_Results *a = (OSP_Results *)pa;
|
|
const OSP_Results *b = (OSP_Results *)pb;
|
|
#define absval(A) ( ( (A)<0 ) ? (-(A)) : (A) )
|
|
return absval((a->start_position+a->end_position)/2 - p) >
|
|
absval((b->start_position+b->end_position)/2 - p);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int findOligos(EdStruct *xx, int sense)
|
|
/*
|
|
* Find suitable oligos using OSP with current parameter settings.
|
|
* Return ok status
|
|
*/
|
|
{
|
|
int seq = xx->cursorSeq;
|
|
int pos = xx->cursorPos;
|
|
int position; /* in contig */
|
|
int contigLength; /* length of contig */
|
|
int consensusLength;
|
|
int ok; /* return status from osp_analyse */
|
|
int i;
|
|
|
|
#ifdef VERBOSENESS
|
|
if (verbose_debug) message("Finding oligos...\n");
|
|
#endif /*VERBOSENESS*/
|
|
|
|
position = positionInContig(xx,seq,pos);
|
|
contigLength = DBgetLength(xx,0/*consensus*/);
|
|
|
|
|
|
|
|
|
|
/*
|
|
* Conceptually we select off consensus.
|
|
* Determine consensus around point...
|
|
* the oligo will be selected from this region
|
|
*/
|
|
if (sense == FORWARDS) {
|
|
l = (position > bkwd_width)
|
|
? position - bkwd_width : 1;
|
|
r = (position + fwd_width < contigLength)
|
|
? position + fwd_width : contigLength;
|
|
} else {
|
|
l = (position > fwd_width)
|
|
? position - fwd_width : 1;
|
|
r = (position + bkwd_width < contigLength)
|
|
? position + bkwd_width : contigLength;
|
|
}
|
|
p = bkwd_width; /* save position of cursor in consensus fragment */
|
|
|
|
consensusLength = (r-l)+1;
|
|
|
|
/* allocate space for consensus */
|
|
if (consensus != NULL) free(consensus);
|
|
consensus = (char *) malloc ( consensusLength );
|
|
|
|
DBcalcConsensus (xx,l, consensusLength, consensus, BOTH_STRANDS);
|
|
if (sense == BACKWARDS) {
|
|
/* we need to complement the consensus */
|
|
/*
|
|
* Use Rodger's routines in subs89.f
|
|
*/
|
|
sqcom_(consensus, &consensusLength, consensusLength);
|
|
sqrev_(consensus, &consensusLength, consensusLength);
|
|
}
|
|
|
|
#ifdef VERBOSENESS
|
|
if (verbose_debug) messagef("Cursor position = %d\n",pos);
|
|
if (verbose_debug) messagef("Seqence = %s (%d)\n",DBgetName(xx,seq),seq);
|
|
if (verbose_debug) messagef("Consensus for region %d-%d = (%s)\n",l,r,consensus);
|
|
if (verbose_debug) messagef("Sense = %s\n", (sense==FORWARDS)?"forward":"reverse");
|
|
#endif /*VERBOSENESS*/
|
|
|
|
/*
|
|
* A cludge to get around bug in osp_analyse
|
|
*/
|
|
for (i=0;i<MAX_NUM_OLIGOS; i++) OSP_RESULTS[i].score = 0.0;
|
|
|
|
ok=osp_analyse(OSP_RESULTS,consensus,&prm,screens,score_info);
|
|
|
|
#ifdef VERBOSENESS
|
|
if (verbose) messagef("osp_analyse returned with status %d\n", ok);
|
|
#endif /*VERBOSENESS*/
|
|
|
|
/*
|
|
* Determine number of suitable oligos
|
|
*/
|
|
if (ok)
|
|
for (num_oligos=0; OSP_RESULTS[num_oligos].score>0.0; num_oligos++);
|
|
else
|
|
num_oligos=0;
|
|
#ifdef VERBOSENESS
|
|
if (verbose) messagef("%d suitable oligos found\n",num_oligos);
|
|
#endif /*VERBOSENESS*/
|
|
|
|
/* sort? */
|
|
if (num_oligos>1) {
|
|
/* yes - sort by position relative to cursor */
|
|
qsort(OSP_RESULTS,num_oligos,sizeof(OSP_Results),oligo_comp_pos);
|
|
}
|
|
|
|
return (ok);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int check_sense(EdStruct *xx, int i/*template number*/, int sense)
|
|
/*
|
|
* templates that are in the wrong sense should fail
|
|
* returns 0 - ok, 1 - wrong sense
|
|
*/
|
|
{
|
|
return (DBgetComp(xx,i) == COMPLEMENTED && sense == FORWARDS ||
|
|
DBgetComp(xx,i) == UNCOMPLEMENTED && sense == BACKWARDS);
|
|
}
|
|
|
|
|
|
|
|
|
|
static int check_5prime(EdStruct *xx, int i/*template number*/, int sense, int pos, int len)
|
|
/*
|
|
* templates that have their 5' end after the oligo position are not usable
|
|
*/
|
|
{
|
|
int relpos = DBgetRelPos(xx,i);
|
|
int length = DBgetLength(xx,i);
|
|
|
|
if (sense == FORWARDS)
|
|
return (relpos > pos);
|
|
else
|
|
return (relpos+length < pos + len);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int check_template_suitability(EdStruct *xx, int i, int sense, int pos, int len)
|
|
/*
|
|
*
|
|
*/
|
|
{
|
|
int relpos = DBgetRelPos(xx,i);
|
|
int length = DBgetLength(xx,i);
|
|
int near_dist;
|
|
CloneInfo info;
|
|
char mtdname[4];
|
|
|
|
/*
|
|
* Get mtd name from gel reading name
|
|
*/
|
|
strncpy(mtdname, DBgetGelName(xx,i), 3);
|
|
mtdname[3] = '\0';
|
|
|
|
/*
|
|
* Get size information from subclones file
|
|
*/
|
|
if (read_subclone_info(clonelib,mtdname,&info))
|
|
near_dist = def_insert_size;
|
|
else
|
|
near_dist = info.range_from;
|
|
|
|
|
|
/* reject ones that are not near the required interval */
|
|
if (sense == FORWARDS)
|
|
return (pos - relpos > (near_dist-ave_read_len));
|
|
else
|
|
return (relpos+length-pos-len > (near_dist-ave_read_len));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int check_template_for_oligo(EdStruct *xx,int pos, int len, int sense, int i/*template no*/)
|
|
/*
|
|
* The template number here is actually the number of an existing gel for
|
|
* that template
|
|
*
|
|
* The template:
|
|
* 1. must be in the appropriate sense.
|
|
* 2. must exists in our template library.
|
|
* 3. must be found "near" the interval required.
|
|
* 4. need not have a sequenced gel over the interval required,
|
|
* but must be past the 5' end.
|
|
*/
|
|
{
|
|
#define reject_wrong_sense 1
|
|
#define reject_mapped_after 2
|
|
#define reject_not_close 3
|
|
#define reject_not_in_library 4
|
|
|
|
/* reject ones that have a sense reverse to the one required */
|
|
if (check_sense(xx,i,sense)) {
|
|
#ifdef VERBOSENESS
|
|
if (verbose_panic) messagef(" %s rejected because it is in the wrong sense\n",DBgetName(xx,i));
|
|
#endif /*VERBOSENESS*/
|
|
return reject_wrong_sense;
|
|
}
|
|
|
|
|
|
/* reject ones with 5' end after our oligo position */
|
|
if (check_5prime(xx,i,sense,pos,len)){
|
|
#ifdef VERBOSENESS
|
|
if (verbose_panic) messagef(" %s rejected because template starts after oligo primer\n",DBgetName(xx,i));
|
|
#endif /*VERBOSENESS*/
|
|
return reject_mapped_after;
|
|
}
|
|
|
|
|
|
/*
|
|
* Check suitability of template according to position
|
|
*/
|
|
if (check_template_suitability(xx,i,sense,pos,len)){
|
|
#ifdef VERBOSENESS
|
|
if (verbose_panic) messagef(" %s rejected because template isn't near oligo primer position\n",DBgetName(xx,i));
|
|
#endif /*VERBOSENESS*/
|
|
return reject_not_close;
|
|
}
|
|
|
|
|
|
/*
|
|
* check that template exists in our template library
|
|
*/
|
|
if (0 /* ?? */) {
|
|
#ifdef VERBOSENESS
|
|
if (verbose_panic) messagef(" %s rejected because template not in template library\n",DBgetName(xx,i));
|
|
#endif /*VERBOSENESS*/
|
|
return reject_not_in_library;
|
|
}
|
|
|
|
#ifdef VERBOSENESS
|
|
if (verbose_debug) messagef(" %s selected\n",DBgetName(xx,i));
|
|
#endif /*VERBOSENESS*/
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int filter_template(char *template_name)
|
|
/*
|
|
* We are interested in templates rather than simply template gel sequences
|
|
* Reject all but *.s1 *.f1 on this basis
|
|
* We are lucky in that we have a rigid nomenclature for templates
|
|
* Other people will do things differently.
|
|
*/
|
|
{
|
|
char *error_message;
|
|
|
|
error_message = (char *) re_comp(filter);
|
|
if ( error_message != NULL ) {
|
|
messagef(" Error using re_comp: %s\n",error_message);
|
|
return 0;
|
|
}
|
|
return (re_exec(template_name) == 1);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int *find_templates_for_oligo (EdStruct *xx, int pos, int len, int sense)
|
|
/*
|
|
* Once an oligo has been found for the consensus at position pos, length len,
|
|
* search for a suitable template within the contig.
|
|
*
|
|
* Use existing gel readings as a basis to find a suitable template.
|
|
* As there can be several readings from one template, filter out only the
|
|
* initial reads for consideration
|
|
*/
|
|
{
|
|
static int *templateList = NULL;
|
|
int i;
|
|
int count;
|
|
|
|
if (templateList == NULL)
|
|
templateList = (int *) malloc ( xx->DB_gelCount * sizeof(int));
|
|
|
|
#ifdef VERBOSENESS
|
|
if (verbose_debug) message("Finding template for oligo:\n");
|
|
if (verbose_debug) messagef("position = %d, length = %d, forward sense=%d\n",pos,len,sense);
|
|
#endif /*VERBOSENESS*/
|
|
|
|
count = 0;
|
|
if (sense==BACKWARDS) {
|
|
for(i=1;i<=xx->DB_gelCount;i++) {
|
|
char *name;
|
|
name = DBgetGelName(xx,i);
|
|
|
|
/* only nematode extensions */
|
|
if (nematode && ! filter_template(name)) {
|
|
#ifdef VERBOSENESS
|
|
if (verbose_debug) messagef(" %s rejected because template doesn't match filter\n",DBgetName(xx,i));
|
|
#endif /*VERBOSENESS*/
|
|
continue;
|
|
}
|
|
|
|
|
|
if (! check_template_for_oligo(xx,pos,len,sense,i))
|
|
templateList[count++] = i;
|
|
|
|
}
|
|
} else {
|
|
int ind;
|
|
ind=posToIndex(xx,pos); /* optimise a bit */
|
|
if(!ind) ind=xx->DB_gelCount;
|
|
for(;ind>0;ind--) {
|
|
char *name;
|
|
i = xx->DBorder[ind];
|
|
name = DBgetGelName(xx,i);
|
|
|
|
if (nematode && ! filter_template(name)) {
|
|
#ifdef VERBOSENESS
|
|
if (verbose_debug) messagef(" %s rejected because template doesn't match filter\n",DBgetName(xx,i));
|
|
#endif /*VERBOSENESS*/
|
|
continue;
|
|
}
|
|
|
|
|
|
if (! check_template_for_oligo(xx,pos,len,sense,i))
|
|
templateList[count++] = i;
|
|
|
|
}
|
|
}
|
|
|
|
templateList[count] = 0;
|
|
|
|
return templateList;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef OBSELETE
|
|
static void trim_suffix(char * name)
|
|
/*
|
|
* Remove tail from first dot onwards
|
|
*/
|
|
{
|
|
char *suffix;
|
|
|
|
/* truncate at suffix */
|
|
suffix = strchr(name,'.');
|
|
if (suffix != NULL)
|
|
*suffix = '\0';
|
|
}
|
|
#endif /*OBSELETE*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void get_template_name(char *name, EdStruct *xx, int i)
|
|
/*
|
|
* Get the template name for gel number 'i'
|
|
*/
|
|
{
|
|
(void) strcpy(name, DBgetGelName(xx,i) );
|
|
#ifdef OBSELETE
|
|
trim_suffix(name);
|
|
#endif /*OBSELETE*/
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef OBSELETE
|
|
static int score_reading_quality(EdStruct *xx, int seq)
|
|
/*
|
|
* Returns a score for the quality of the read, higher the better.
|
|
* Ideally it would look at the traces, but for now
|
|
* will assume length of read is a good meter for this
|
|
*/
|
|
{
|
|
return DBgetLength(xx,seq);
|
|
}
|
|
#endif /*OBSELETE*/
|
|
|
|
|
|
|
|
static int score_template(EdStruct *xx, int seq)
|
|
/*
|
|
* Score this template
|
|
*/
|
|
{
|
|
#ifdef OBSELETE
|
|
return score_reading_quality(xx,seq);
|
|
#else /*OBSELETE*/
|
|
return 1; /* this should force the first one to be chosen */
|
|
#endif /*OBSELETE*/
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void set_default_template(EdStruct *xx, int *templateList)
|
|
/*
|
|
* Pick a default template from the list of available templates
|
|
*/
|
|
{
|
|
template_index = 0;
|
|
template_name[0] = '\0';
|
|
if (templateList[0]) {
|
|
int i;
|
|
int score, high_score;
|
|
high_score = 0;
|
|
/* search */
|
|
for (i=0; templateList[i]; i++) {
|
|
score = score_template(xx, templateList[i]);
|
|
if (high_score < score) {
|
|
high_score = score;
|
|
template_index = templateList[i];
|
|
}
|
|
}
|
|
/* set template name */
|
|
get_template_name(template_name, xx, template_index);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef OBSELETE
|
|
static int strcmp_ignorecase(char *a, char *b)
|
|
{
|
|
for ( ; tolower(*a) == tolower(*b); a++, b++)
|
|
if (*a == '\0') return 0;
|
|
return tolower(*a) - tolower(*b);
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
static int strncmp_ignorecase(char *a, char *b, int n)
|
|
{
|
|
for ( ; n && tolower(*a) == tolower(*b); a++, b++, n--)
|
|
if (*a == '\0') return 0;
|
|
if (!n)
|
|
return 0;
|
|
else
|
|
return tolower(*a) - tolower(*b);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void check_template_name(EdStruct *xx, char *template_name, int pos, int len, int sense)
|
|
/*
|
|
* Check the template name is valid
|
|
* + that it exists
|
|
* + that is in the correct sense etc etc
|
|
* If it's not valid, set template_index to be 0
|
|
*/
|
|
{
|
|
int i;
|
|
int found_index;
|
|
int template_len;
|
|
int found;
|
|
char this[DB_NAMELEN];
|
|
|
|
strcpy(this,template_name);
|
|
#ifdef OBSELETE
|
|
trim_suffix(this);
|
|
#endif /*OBSELETE*/
|
|
|
|
/*
|
|
* Check template_name exists
|
|
*/
|
|
found = 0;
|
|
template_len= strlen(template_name);
|
|
|
|
for (i=1; i<=xx->DB_gelCount ; i++) {
|
|
char *name;
|
|
|
|
name = DBgetGelName(xx,i);
|
|
|
|
if (nematode && ! filter_template(name))
|
|
continue;
|
|
|
|
if (strncmp_ignorecase(template_name, DBgetGelName(xx,i), template_len) == 0) {
|
|
found++;
|
|
found_index = i;
|
|
#ifdef VERBOSENESS
|
|
if (verbose_debug) messagef("%s matches %s\n",template_name,DBgetName(xx,i));
|
|
#endif /*VERBOSENESS*/
|
|
}
|
|
|
|
}
|
|
|
|
|
|
template_index = 0;
|
|
|
|
if (! found)
|
|
messagef("template %s not found\n", template_name);
|
|
else {
|
|
if (found > 1) {
|
|
#ifdef VERBOSENESS
|
|
if (verbose_debug) messagef("template %s found, but is not unique\n",
|
|
template_name);
|
|
#endif /*VERBOSENESS*/
|
|
} else {
|
|
if (check_sense(xx, found_index, sense)) {
|
|
messagef("template %s in the wrong sense\n", template_name);
|
|
return;
|
|
}
|
|
|
|
if (check_5prime(xx,found_index,sense,pos,len)) {
|
|
messagef("template %s starts after oligo position\n", template_name);
|
|
return;
|
|
}
|
|
|
|
template_index = found_index;
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
* Move data[] outside scope of following function - non ANSI to perform
|
|
* aggregate definitions inside a function
|
|
*/
|
|
Field_entry data_2[] = {
|
|
{"Template", (char *)template_name, t_char, sizeof(template_name)},
|
|
};
|
|
|
|
static void menuSelectCallback(Widget w, XtPointer p_i, XtPointer junk)
|
|
/*
|
|
* A template has been selected off the menu
|
|
* Deal with it
|
|
*/
|
|
{
|
|
int i = (int) p_i;
|
|
|
|
/*
|
|
* i is either -1 (other) or the gel number corresponding to a template
|
|
*/
|
|
if (i<0) {
|
|
#ifdef VERBOSENESS
|
|
if (verbose_debug) message("Menu: Other selected\n");
|
|
#endif /*VERBOSENESS*/
|
|
|
|
template_name[0]='\0';
|
|
|
|
change_params((Widget)oligoWid,"Please specify...",data_2,
|
|
XtNumber(data_2));
|
|
template_index = 0;
|
|
if (oligo_sense == BACKWARDS) {
|
|
check_template_name(thisxx, template_name,
|
|
r-OSP_RESULTS[curr_oligo].end_position,
|
|
OSP_RESULTS[curr_oligo].end_position-OSP_RESULTS[curr_oligo].start_position+1,
|
|
oligo_sense);
|
|
} else {
|
|
check_template_name(thisxx, template_name,
|
|
l+OSP_RESULTS[curr_oligo].start_position,
|
|
OSP_RESULTS[curr_oligo].end_position-OSP_RESULTS[curr_oligo].start_position+1,
|
|
oligo_sense);
|
|
}
|
|
|
|
} else {
|
|
template_index = i;
|
|
get_template_name(template_name,thisxx,i);
|
|
#ifdef VERBOSENESS
|
|
if (verbose_debug) messagef("Menu: %s selected\n", template_name);
|
|
#endif /*VERBOSENESS*/
|
|
}
|
|
|
|
display_template_details();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void create_template_menu(EdStruct *xx, int *list)
|
|
/*
|
|
* Create new list of available templates
|
|
*/
|
|
{
|
|
static Widget menuWid = NULL;
|
|
int i;
|
|
Widget entryWid;
|
|
Arg args[2];
|
|
Cardinal nargs;
|
|
|
|
if (menuWid != NULL)
|
|
XtDestroyWidget(menuWid);
|
|
|
|
|
|
/*
|
|
* Create the menu parent widget
|
|
*/
|
|
menuWid = XtCreatePopupShell("templateMenu", simpleMenuWidgetClass, template,
|
|
NULL, 0);
|
|
|
|
/*
|
|
Put the individual items in.
|
|
When selected, each entry will generate a callback with
|
|
its associated number.
|
|
*/
|
|
for (i = 0; list[i]; i++)
|
|
{
|
|
char name[DB_NAMELEN];
|
|
|
|
#ifdef VERBOSENESS
|
|
if (verbose_debug) messagef("Creating menu for %s\n",DBgetName(xx,list[i]));
|
|
#endif /*VERBOSENESS*/
|
|
|
|
/*
|
|
* Prepare clone name
|
|
*/
|
|
get_template_name(name, xx, list[i]);
|
|
|
|
nargs = 0;
|
|
XtSetArg(args[nargs], XtNlabel, name); nargs++;
|
|
entryWid = XtCreateManagedWidget("entry", smeBSBObjectClass,
|
|
menuWid, args, nargs);
|
|
XtAddCallback(entryWid, XtNcallback, menuSelectCallback,
|
|
(XtPointer) list[i]);
|
|
}
|
|
nargs = 0;
|
|
XtSetArg(args[nargs], XtNlabel, "Other"); nargs++;
|
|
entryWid = XtCreateManagedWidget("entry", smeBSBObjectClass,
|
|
menuWid, args, nargs);
|
|
XtAddCallback(entryWid, XtNcallback, menuSelectCallback,
|
|
(XtPointer) -1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void display_template_details()
|
|
/*
|
|
* Display importand template details
|
|
*/
|
|
{
|
|
if (template_index > 0) {
|
|
messagef("Template: %s\n", template_name);
|
|
} else {
|
|
message("Template: none chosen\n");
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void display_oligo_details(EdStruct *xx, int sense, int oligo)
|
|
/*
|
|
* Display important oligo details
|
|
* a. sequence
|
|
* b. position, length
|
|
* c. osp score, gc, tm
|
|
*/
|
|
{
|
|
char seq[100];
|
|
int pos,len;
|
|
int i;
|
|
char *a;
|
|
int consensus_start, consensus_end;
|
|
|
|
pos = OSP_RESULTS[oligo].start_position;
|
|
len = OSP_RESULTS[oligo].end_position - pos + 1;
|
|
|
|
/*
|
|
* Get consensus sequence with context
|
|
*/
|
|
a = seq;
|
|
for (i=3;i;i--) *a++ = '.';
|
|
for (i=(pos>2)?2:pos;i;i--)
|
|
*a++ = tolower(consensus[pos-i]);
|
|
strncpy(a,&consensus[pos],len); a+=len;
|
|
for (i=0;i<2&&consensus[pos+len+i];i++)
|
|
*a++ = tolower(consensus[pos+len+i]);
|
|
for (i=3;i;i--) *a++ = '.';
|
|
*a++ = '\0';
|
|
|
|
|
|
/*
|
|
* Positions in contig
|
|
*/
|
|
if (sense == BACKWARDS) {
|
|
consensus_start = r-OSP_RESULTS[oligo].end_position;
|
|
consensus_end = consensus_start + len - 1;
|
|
} else {
|
|
consensus_start = l+OSP_RESULTS[oligo].start_position;
|
|
consensus_end = consensus_start + len - 1;
|
|
}
|
|
|
|
messagef("Oligo: %s\n",seq);
|
|
messagef("\
|
|
Primer # %2d PRIMER-SELF PRIMER-OTHER\n\
|
|
5' end 3' end length Score G+C(%%) Tm 3' Internal 3' Internal\n\
|
|
%6d %6d %4d %4.1f %4.1f %4.1f %4.1f %4.1f %4.1f %4.1f\n",
|
|
oligo+1,
|
|
consensus_start,
|
|
consensus_end,
|
|
len,
|
|
OSP_RESULTS[oligo].score,
|
|
OSP_RESULTS[oligo].gc * 100.0,
|
|
OSP_RESULTS[oligo].tm,
|
|
OSP_RESULTS[oligo].psI_score,
|
|
OSP_RESULTS[oligo].ps3_score,
|
|
OSP_RESULTS[oligo].poI_score,
|
|
OSP_RESULTS[oligo].po3_score);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void nextOligo(EdStruct *xx, int oligo, int sense)
|
|
/*
|
|
* We cycle through the oligo list
|
|
* curr-oligo gives the current oligo entry under consideration
|
|
*/
|
|
{
|
|
/*
|
|
* Hilight position of next oligo in contig editor temporarily
|
|
*/
|
|
int *templateList;
|
|
int i = oligo;
|
|
|
|
/*
|
|
* Print out information on oligos
|
|
*/
|
|
#ifdef VERBOSENESS
|
|
if (verbose_debug) messagef("************** %d ************\n",i);
|
|
if (verbose_debug) messagef("stp %d, endp %d, score %f, gc %f, tm %f, psI %f ps3 %f poI %f po3 %f\n",
|
|
OSP_RESULTS[i].start_position,
|
|
OSP_RESULTS[i].end_position,
|
|
OSP_RESULTS[i].score,
|
|
OSP_RESULTS[i].gc,
|
|
OSP_RESULTS[i].tm,
|
|
OSP_RESULTS[i].psI_score,
|
|
OSP_RESULTS[i].ps3_score,
|
|
OSP_RESULTS[i].poI_score,
|
|
OSP_RESULTS[i].po3_score);
|
|
#endif /*VERBOSENESS*/
|
|
display_oligo_details(xx,sense,i);
|
|
|
|
if (sense == BACKWARDS) {
|
|
/*
|
|
* Convert position returned from oligo selection to
|
|
* position in contig
|
|
*/
|
|
templateList =
|
|
find_templates_for_oligo(xx,
|
|
r-OSP_RESULTS[i].end_position,
|
|
OSP_RESULTS[i].end_position-OSP_RESULTS[i].start_position+1,
|
|
sense);
|
|
create_temporary_tag(xx,
|
|
r-OSP_RESULTS[i].end_position,
|
|
OSP_RESULTS[i].end_position-OSP_RESULTS[i].start_position+1);
|
|
} else {
|
|
/*
|
|
* Convert position returned from oligo selection to
|
|
* position in contig
|
|
*/
|
|
templateList =
|
|
find_templates_for_oligo(xx,
|
|
l+OSP_RESULTS[i].start_position,
|
|
OSP_RESULTS[i].end_position-OSP_RESULTS[i].start_position+1,
|
|
sense);
|
|
create_temporary_tag(xx,
|
|
l+OSP_RESULTS[i].start_position,
|
|
OSP_RESULTS[i].end_position-OSP_RESULTS[i].start_position+1);
|
|
}
|
|
|
|
|
|
set_default_template(xx,templateList);
|
|
create_template_menu(xx, templateList);
|
|
|
|
display_template_details();
|
|
|
|
}
|
|
|
|
|
|
/*****************************************************************************************/
|
|
/*
|
|
* External routines
|
|
*/
|
|
|
|
|
|
|
|
void createOligoWidget(Widget parentWid)
|
|
/*
|
|
* Prtend to create it now
|
|
*/
|
|
{
|
|
oldFogieWid = parentWid;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void create_oligo_wid(Widget parentWid)
|
|
/*
|
|
* Create the window for oligo selection
|
|
* This routine should be called just once, in the initialisation phase of xdap
|
|
*/
|
|
{
|
|
Cardinal nargs;
|
|
Arg args[10];
|
|
Position x, y; /* top-left hand corner of new widget */
|
|
Dimension height; /* height of parent widget */
|
|
|
|
/*
|
|
* Determine the position on the screen for this widget
|
|
*/
|
|
#define fromVertWid (thisxx->edWid)
|
|
nargs = 0;
|
|
XtSetArg(args[nargs], XtNheight, &height); nargs++;
|
|
XtGetValues(fromVertWid, args, nargs);
|
|
XtTranslateCoords(fromVertWid, (Position) 0, (Position) height, &x, &y);
|
|
|
|
/*
|
|
* Create popup shell
|
|
*/
|
|
nargs = 0;
|
|
XtSetArg(args[nargs], XtNx, x); nargs++;
|
|
XtSetArg(args[nargs], XtNy, y); nargs++;
|
|
oligoWid = XtCreatePopupShell("oligo", transientShellWidgetClass, parentWid, args, nargs);
|
|
|
|
/*
|
|
* Create main form
|
|
*/
|
|
nargs = 0;
|
|
form = XtCreateManagedWidget("form", formWidgetClass, oligoWid, args, nargs);
|
|
|
|
/*
|
|
* Create title for form
|
|
*/
|
|
nargs = 0;
|
|
XtSetArg(args[nargs], XtNborderWidth, 0); nargs++;
|
|
XtSetArg(args[nargs], XtNlabel, "Select Oligos and Templates"); nargs++;
|
|
label = XtCreateManagedWidget("label", labelWidgetClass, form, args, nargs);
|
|
|
|
#define XtOrientHorizontal "horizontal"
|
|
|
|
/*
|
|
* Create buttons for oligo sense
|
|
*/
|
|
nargs = 0;
|
|
XtSetArg(args[nargs], XtNfromVert, label); nargs++;
|
|
XtSetArg(args[nargs], XtNborderWidth, 0); nargs++;
|
|
XtSetArg(args[nargs], XtNorientation, XtOrientHorizontal); nargs++;
|
|
bbox = XtCreateManagedWidget("bbox", boxWidgetClass, form, args, nargs);
|
|
nargs = 0;
|
|
XtSetArg(args[nargs], XtNborderWidth, 0); nargs++;
|
|
XtSetArg(args[nargs], XtNlabel, "Direction:"); nargs++;
|
|
(void) XtCreateManagedWidget("label", labelWidgetClass, bbox, args, nargs);
|
|
nargs = 0;
|
|
strand = XtCreateManagedWidget("strand", commandWidgetClass,bbox,args,nargs);
|
|
XtAddCallback(strand, XtNcallback, strandCallback, (XtPointer) NULL);
|
|
set_strand_state(strand,strand_state);
|
|
|
|
|
|
/*
|
|
* Create Change Parameter Buttons
|
|
*/
|
|
nargs = 0;
|
|
XtSetArg(args[nargs], XtNfromVert, bbox); nargs++;
|
|
XtSetArg(args[nargs], XtNborderWidth, 0); nargs++;
|
|
XtSetArg(args[nargs], XtNorientation, XtOrientHorizontal); nargs++;
|
|
cbox = XtCreateManagedWidget("cbox", boxWidgetClass, form, args, nargs);
|
|
nargs = 0;
|
|
XtSetArg(args[nargs], XtNlabel, "Parameters"); nargs++;
|
|
change = XtCreateManagedWidget("change", commandWidgetClass, cbox, args, nargs);
|
|
XtAddCallback(change, XtNcallback, changeMineCallback, (XtPointer) NULL);
|
|
nargs = 0;
|
|
XtSetArg(args[nargs], XtNlabel, "Oligo Selection Parameters"); nargs++;
|
|
change = XtCreateManagedWidget("change", commandWidgetClass, cbox, args, nargs);
|
|
XtAddCallback(change, XtNcallback, changeParamsCallback, (XtPointer) NULL);
|
|
nargs = 0;
|
|
XtSetArg(args[nargs], XtNlabel, "Oligo Selection Weights"); nargs++;
|
|
change = XtCreateManagedWidget("change", commandWidgetClass, cbox, args, nargs);
|
|
XtAddCallback(change, XtNcallback, changeWeightsCallback, (XtPointer) NULL);
|
|
nargs = 0;
|
|
XtSetArg(args[nargs], XtNlabel, "Display Selection Information"); nargs++;
|
|
change = XtCreateManagedWidget("information", commandWidgetClass, cbox, args, nargs);
|
|
XtAddCallback(change, XtNcallback, informationCallback, (XtPointer) NULL);
|
|
|
|
/*
|
|
* Create action button
|
|
*/
|
|
nargs = 0;
|
|
XtSetArg(args[nargs], XtNfromVert, cbox); nargs++;
|
|
XtSetArg(args[nargs], XtNborderWidth, 0); nargs++;
|
|
XtSetArg(args[nargs], XtNorientation, XtOrientHorizontal); nargs++;
|
|
XtSetArg(args[nargs], XtNresizable, True); nargs++;
|
|
dbox = XtCreateManagedWidget("dbox", boxWidgetClass, form, args, nargs);
|
|
nargs = 0;
|
|
XtSetArg(args[nargs], XtNlabel, "Find Oligos"); nargs++;
|
|
find = XtCreateManagedWidget("find", commandWidgetClass, dbox, args, nargs);
|
|
XtAddCallback(find, XtNcallback, findCallback, (XtPointer) NULL);
|
|
nargs = 0;
|
|
XtSetArg(args[nargs], XtNlabel, "Select Next"); nargs++;
|
|
next = XtCreateManagedWidget("next", commandWidgetClass, dbox, args, nargs);
|
|
XtAddCallback(next, XtNcallback, nextCallback, (XtPointer) NULL);
|
|
nargs = 0;
|
|
XtSetArg(args[nargs], XtNlabel, "Choose Template for this Oligo"); nargs++;
|
|
XtSetArg(args[nargs], XtNmenuName, "templateMenu"); nargs++;
|
|
template = XtCreateManagedWidget("template", menuButtonWidgetClass, dbox, args, nargs);
|
|
|
|
|
|
/*
|
|
* Exit action
|
|
*/
|
|
nargs = 0;
|
|
XtSetArg(args[nargs], XtNfromVert, dbox); nargs++;
|
|
XtSetArg(args[nargs], XtNborderWidth, 0); nargs++;
|
|
XtSetArg(args[nargs], XtNorientation, XtOrientHorizontal); nargs++;
|
|
XtSetArg(args[nargs], XtNresizable, True); nargs++;
|
|
ebox = XtCreateManagedWidget("ebox", boxWidgetClass, form, args, nargs);
|
|
nargs = 0;
|
|
XtSetArg(args[nargs], XtNlabel, "Create Tag for this Oligo"); nargs++;
|
|
ok = XtCreateManagedWidget("ok", commandWidgetClass, ebox, args, nargs);
|
|
XtAddCallback(ok, XtNcallback, okCallback, (XtPointer) NULL);
|
|
nargs = 0;
|
|
XtSetArg(args[nargs], XtNlabel, "Quit"); nargs++;
|
|
quit = XtCreateManagedWidget("quit", commandWidgetClass, ebox, args, nargs);
|
|
XtAddCallback(quit, XtNcallback, quitCallback, (XtPointer) NULL);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int invokeOligo(EdStruct *xx)
|
|
/*
|
|
* Pop up the oligo selection window
|
|
*/
|
|
{
|
|
if (up) return 0;
|
|
thisxx = xx;
|
|
|
|
if (oligoWid == NULL) {
|
|
initialise();
|
|
osp_initialise();
|
|
create_oligo_wid(oldFogieWid);
|
|
}
|
|
|
|
XtUnmanageChild(ok);
|
|
XtUnmanageChild(next);
|
|
XtUnmanageChild(template);
|
|
|
|
XtPopup(oligoWid, XtGrabNone);
|
|
|
|
up = 1;
|
|
|
|
/* find oligos */
|
|
XtCallCallbacks(find, XtNcallback, (XtPointer) NULL);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int destroyOligo()
|
|
/*
|
|
* Shut this baby down
|
|
*/
|
|
{
|
|
if (up)
|
|
XtCallCallbacks(quit, XtNcallback, (XtPointer) NULL);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void destroy_oligo_popup()
|
|
/*
|
|
* Popdown the oligo popup window,
|
|
* free a few variables
|
|
* then relax
|
|
*/
|
|
{
|
|
EdStruct *xx = thisxx;
|
|
|
|
XtPopdown(oligoWid);
|
|
|
|
destroy_temporary_tag(xx);
|
|
free (consensus);
|
|
consensus = NULL;
|
|
|
|
redisplaySequences (xx,
|
|
xx->namesWid,
|
|
xx->sequencesWid,
|
|
xx->displayPos,
|
|
xx->displayWidth);
|
|
}
|
|
|
|
|