diff --git a/bigpicture.c b/bigpicture.c index 1ca6295e75053669dac64701bd57c82ea3afb1d2..cda0fad0dff7ae2794d6b5e1b608337e796be023 100644 --- a/bigpicture.c +++ b/bigpicture.c @@ -454,6 +454,11 @@ static void setBigPictureDisplayWidth(GtkWidget *bigPicture, int width, const gb } bigPictureRedrawAll(bigPicture); + + /* This call to refreshGridOrder is not strictly necessary but is included because I can't find + * another way to force the big picture pane to resize when the exon view shrinks, even though + * set_size_request is called on the exon views in calculateExonViewHeight above. */ + refreshGridOrder(bigPicture); } @@ -802,6 +807,7 @@ static void bigPictureRecalculateSize(GtkWidget *bigPicture) static void onSizeAllocateBigPicture(GtkWidget *bigPicture, GtkAllocation *allocation, gpointer data) { bigPictureRecalculateSize(bigPicture); + bigPictureRedrawAll(bigPicture); } diff --git a/blxview.c b/blxview.c index 72f6bff59a9dbab812f3082b6602ee90a26253fb..644902590a5ced0a757a6a6c3a22cf48b5806aa9 100644 --- a/blxview.c +++ b/blxview.c @@ -88,7 +88,7 @@ 01-10-05 Added getsseqsPfetch to fetch all missing sseqs in one go via socket connection to pfetch [RD] * Created: Thu Feb 20 10:27:39 1993 (esr) - * CVS info: $Id: blxview.c,v 1.69 2010-09-27 17:16:11 gb10 Exp $ + * CVS info: $Id: blxview.c,v 1.70 2010-09-30 11:44:52 gb10 Exp $ *------------------------------------------------------------------- */ @@ -1005,6 +1005,20 @@ static void createMissingExonCdsUtr(MSP **exon, MSP **cds, MSP **utr, g_propagate_error(error, tmpError); } } + + /* We should now have all the bits. Set the relationship data. */ + if (*exon && (*cds || *utr)) + { + if (*cds) + (*exon)->childMsps = g_list_append((*exon)->childMsps, *cds); + + if (*utr) + (*exon)->childMsps = g_list_append((*exon)->childMsps, *utr); + } + else + { + g_debug("Incomplete transcript\n"); + } } @@ -1041,9 +1055,8 @@ static void constructTranscriptData(BlxSequence *blxSeq, MSP **lastMsp, MSP **ms gboolean foundGap = FALSE; if (msp && - ((prevMsp && prevMsp->qRange.max < msp->qRange.min) || - (!prevMsp && blxSeq->qRange.min < msp->qRange.min) || - ((mspItem->next == NULL && blxSeq->qRange.max > msp->qRange.max)))) + ((prevMsp && !rangesOverlap(&prevMsp->qRange, &msp->qRange)) || + (!prevMsp && blxSeq->qRange.min < msp->qRange.min))) { foundGap = TRUE; } @@ -1056,13 +1069,33 @@ static void constructTranscriptData(BlxSequence *blxSeq, MSP **lastMsp, MSP **ms reportAndClearIfError(&tmpError, G_LOG_LEVEL_CRITICAL); copyCdsReadingFrame(curExon, curCds, curUtr); - /* Create an intron in the gap, unless there's already one here */ + IntRange newRange = {UNSET_INT, UNSET_INT}; + if (prevExon && curExon && !mspIsIntron(msp) && !mspIsIntron(prevMsp)) + { + /* Create an intron to span the gap */ + newRange.min = prevExon->qRange.max + 1; + newRange.max = curExon->qRange.min; + } + else if (!prevExon && curExon && blxSeq->qRange.min < curExon->qRange.min && !mspIsIntron(msp) && !mspIsIntron(prevMsp)) + { + /* Create an intron at the start */ + newRange.min = blxSeq->qRange.min; + newRange.max = curExon->qRange.min; + } + else if (msp == NULL && curExon && blxSeq->qRange.max > curExon->qRange.max && !mspIsIntron(prevMsp)) + { + /* Create an intron at the end */ + newRange.min = curExon->qRange.max + 1; + newRange.max = blxSeq->qRange.max; + } + + if (newRange.min != UNSET_INT && newRange.max != UNSET_INT) { createNewMsp(lastMsp, mspList, seqList, BLXMSP_INTRON, NULL, UNSET_INT, UNSET_INT, blxSeq->idTag, - NULL, prevExon->qRange.max + 1, curExon->qRange.min, blxSeq->strand, UNSET_INT, blxSeq->fullName, - UNSET_INT, UNSET_INT, blxSeq->strand, NULL, opts, &tmpError); - + NULL, newRange.min, newRange.max, blxSeq->strand, UNSET_INT, blxSeq->fullName, + UNSET_INT, UNSET_INT, blxSeq->strand, NULL, opts, &tmpError); + reportAndClearIfError(&tmpError, G_LOG_LEVEL_CRITICAL); } @@ -1439,6 +1472,7 @@ static MSP* createEmptyMsp(MSP **lastMsp, MSP **mspList) MSP *msp = (MSP *)g_malloc(sizeof(MSP)); msp->next = NULL; + msp->childMsps = NULL; msp->type = BLXMSP_INVALID; msp->score = 0.0; msp->id = 0.0; diff --git a/blxview.h b/blxview.h index 5ae6bd5a2b28000306e1cf5aafd71e2270db2a8a..987301dd5ccbaad307205b6b78fcbd9a6f72084b 100644 --- a/blxview.h +++ b/blxview.h @@ -27,7 +27,7 @@ * Last edited: Aug 21 13:57 2009 (edgrif) * * Aug 26 16:57 1999 (fw): added this header * Created: Thu Aug 26 16:57:17 1999 (fw) - * CVS info: $Id: blxview.h,v 1.35 2010-09-27 11:55:15 gb10 Exp $ + * CVS info: $Id: blxview.h,v 1.36 2010-09-30 11:44:52 gb10 Exp $ *------------------------------------------------------------------- */ #ifndef DEF_BLXVIEW_H @@ -224,8 +224,9 @@ typedef struct _BlxStyle /* Structure holding information about an alignment */ typedef struct _MSP { - struct _MSP *next; - BlxMspType type; /* See enum above */ + struct _MSP *next; /* The next msp in the list. */ + GList *childMsps; /* Child MSPs of this MSP if it has them, e.g. an exon has CDS and UTR children (part_of relationship). */ + BlxMspType type; /* Whether this is a match, exon, SNP etc. */ gdouble score; /* Score as a percentage. Technically this should be a weighted score taking into account gaps, length of the match etc., but for unknown reasons the ID has always been passed instead of score and the ID gets stored in here */ gdouble id; /* Identity as a percentage. A simple comparison of bases within the match, ignoring gaps etc. Currently this is calculated internally by blixem. */ int phase; /* phase: q start coord is offset by this amount to give the first base in the first complete codon (only relevant to CDSs) */ diff --git a/detailview.c b/detailview.c index aa9c04ec5474f089ebad189566b7ae0184e429b0..ebe5f49a1ddc1336924f89aa7a726dfd3819a601 100755 --- a/detailview.c +++ b/detailview.c @@ -4111,7 +4111,7 @@ void detailViewAddMspData(GtkWidget *detailView, MSP *mspList) for ( ; msp; msp = msp->next) { /* Only add matches/exons to trees */ - if (mspIsBlastMatch(msp) || mspIsExon(msp)) + if (msp->type == BLXMSP_MATCH || msp->type == BLXMSP_EXON) { /* Find the tree that this MSP should belong to based on its reading frame and strand */ BlxStrand strand = mspGetRefStrand(msp); diff --git a/detailviewtree.c b/detailviewtree.c index b7d824faa7e29e99c9edf48d4a46d6d1d1380b8d..7358d8cc45a6fb76173d1745543ed5c8f41fbc8e 100755 --- a/detailviewtree.c +++ b/detailviewtree.c @@ -1514,9 +1514,18 @@ void addMspToTree(GtkWidget *tree, MSP *msp) GtkTreeIter iter; gtk_list_store_append(store, &iter); - /* The SequenceCellRenderer expects a GList of MSPs, so put our MSP in a list */ + /* The SequenceCellRenderer expects a GList of MSPs, so put our MSP in a list. For exons, + * we want to add the child CDS/UTRs rather than the exon itself, so use the child list. */ GList *mspGList = NULL; - mspGList = g_list_append(NULL, msp); + + if (msp->type == BLXMSP_EXON && g_list_length(msp->childMsps) > 0) + { + mspGList = msp->childMsps; + } + else + { + mspGList = g_list_append(NULL, msp); + } gtk_list_store_set(store, &iter, BLXCOL_SEQNAME, mspGetSName(msp), diff --git a/sequencecellrenderer.c b/sequencecellrenderer.c index 1ea0a362bfc693291022fd1502ec179909c222ae..9e76063b3b98b5ff4dced39c30c5f6778200207e 100755 --- a/sequencecellrenderer.c +++ b/sequencecellrenderer.c @@ -691,7 +691,7 @@ static void getCoordsForBaseIdx(const int segmentIdx, * coords are within the current display range */ static gboolean drawExonBoundary(const MSP *msp, RenderData *rd) { - if (msp && mspIsExon(msp)) + if (msp && (msp->type == BLXMSP_CDS || msp->type == BLXMSP_UTR)) { /* Get the msp's start/end in terms of the display coords */ const int coord1 = convertDnaIdxToDisplayIdx(msp->qRange.min, rd->bc->seqType, rd->qFrame, rd->bc->numFrames, rd->bc->displayRev, &rd->bc->refSeqRange, NULL);