/* File: trace.c * Author: Danielle et Jean Thierry-Mieg (mieg@mrc-lmb.cam.ac.uk) * Copyright (C) J Thierry-Mieg and R Durbin, 1994 * ------------------------------------------------------------------- * Acedb is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * or see the on-line version at http://www.gnu.org/copyleft/gpl.txt * ------------------------------------------------------------------- * This file is part of the ACEDB genome database package, written by * Richard Durbin (MRC LMB, UK) rd@mrc-lmba.cam.ac.uk, and * Jean Thierry-Mieg (CRBM du CNRS, France) mieg@crbm.cnrs-mop.fr * * Description: * linked in with graphical acembly programs * Exported functions: * HISTORY: * Last edited: May 6 13:35 2003 (edgrif) * Created: Mon Apr 18 17:41:24 1994 (mieg) *------------------------------------------------------------------- */ /* $Id: trace.c,v 1.44 2003/05/06 13:13:58 edgrif Exp $ */ /* #define ARRAY_CHECK #define MALLOC_CHECK */ #include #include #include #include #include #include #include #include #include #include #include /* opaque decl of LOOK */ #include /* completes LookStruct -> TRACELOOK */ #include #include /* public fmap function headers */ /************************************************************/ static int nextError (LOOK look, BOOL down) ; static LOOK traceLook = 0 ; static Graph traceGraph = 0 ; static float lastMag = 0, genex = 0 ; /************************************************************/ static int BASE_COLOR [] = {A_COLOR, G_COLOR, C_COLOR, T_COLOR, N_COLOR} ; static void traceDraw (LOOK look) ; static BOOL fineTune(LOOK look, LANE **lane1p, LANE *lane) ; static void traceSelect(LOOK look, int box) ; static void traceMiddleDown (double x, double y) ; static void traceLeftDown (int box, double xx, double yy, int modifier_unused) ; static BOOL isLaneShown (LOOK look, LANE *lane) ; static void traceDnaLane (LOOK look, MAP map, LANE *lane, float *offset, int min, int max) ; static void traceDnaLaneErrors (LOOK look, MAP map, LANE *lane, float *offset, int min, int max, BOOL foundSplice) ; static int jackPotSearch (LOOK look, MAP map, LANE *lane, float *offset, int min, int max) ; static void traceEdLaneBases (LOOK look, LANE *lane, float *offset, int start, int stop, int type, BOOL isAligned) ; static void laneShowExtrema(LOOK look, LANE *lane, float *offset, int min, int max) ; BOOL traceGetLane (LOOK look, LANE *lane) ; /* static void fixButton (void) ; */ static void traceRealignAll (void) ; static void laneDoTag (LOOK look, LANE *lane, KEY key, char *buf) ; static void newFixButton (void) ; static void newBigFixButton (void) ; static BOOL traceLaneCrossing (Array lanes, LANE *lane) ; #define CHECKLANE { if (!lane->scf) traceGetLane (look, lane) ; \ if (lane->scf > 1 && !lane->errArray) \ laneMakeErrArray (look, lane) ; } #define CHECKSEQ { if (lane->scf == 2) { baseCallGetSeq(lane) ; }} #define CHECKPOS { if (lane->scf == 3 && !lane->basePos) baseCallFakePos (lane) ; \ else if (lane->scf > 3 && !lane->basePos) baseCallGet(lane); } static BOOL showSelect = TRUE ; int laneGlobalOrder (void *a, void *b) ; #define SHOW_ALL 0 #define HIDE_UP 1 #define HIDE_DOWN 2 #define SHOW_BEST_ERR 4 #define HIDE_NON_BEST 12 #define SHOW_CLIP 16 #define SHOW_SPLICER 32 static int showDefaultMode = SHOW_BEST_ERR ; static int showChosenMode = SHOW_ALL ; static LANE* lastUnclippedLane = 0 ; static KEY lastVectorClippedRead = 0 ; #define NEXT_ERROR 1 #define NEXT_PROBLEM 2 #define NEXT_COMPARE 3 #define NEXT_CLIP 4 #define NEXT_HOLE 5 #define NEXT_TAG 6 static FREEOPT nextMenu[] = { {6, "Next What"}, {NEXT_PROBLEM, "Problem"}, {NEXT_ERROR, "Difference"}, {NEXT_CLIP, "Clip"}, {NEXT_HOLE, "Hole"}, {NEXT_TAG, "Tag"}, {NEXT_COMPARE, "Comparison"} } ; static BOOL sortNeeded = TRUE ; static int dragFast = -1, dragBox = 0 ; /************************************************************/ static void* TRACELOOK_ASSOC; /* find the (TRACE)LOOK on the active graph */ static void* TRACELOOK_MAGIC; /* verify the (TRACE)LOOK pointer */ #define TRACELOOKGET(name) \ LOOK look ; \ if (!graphAssFind (&TRACELOOK_ASSOC, &look)) \ messcrash ("graph not found in %s", name) ; \ if (look->magic != &TRACELOOK_MAGIC) \ messcrash ("%s received a wrong pointer", name) /************************************************************/ /***************** Editor *******************************/ #ifndef NON_GRAPHIC /************************************************************/ static void updateConsensus (LOOK look) { if (!look->dnaKey || look->mode != SHOTGUN) return ; defCptForget (look->link, look->dnaKey); dnaStoreDestroy (look->dnaKey, arrayCopy(look->dna)) ; if (look->fMapLook) fMapPleaseRecompute (look->fMapLook) ; } /************************************************************/ static FREEOPT errorChoiceAll[] = { {22, "Define"}, {2, "A->T"}, {3, "A->G"}, {4, "A->C"}, {1002, "T->A"}, {1004, "T->G"}, {1003, "T->C"}, {5, "G->A"}, {6, "G->T"}, {7, "G->C"}, {1006, "C->A"}, {1005, "C->T"}, {1007, "C->G"}, {101, "Delete A"}, {1101, "Delete T"}, {102, "Delete G"}, {1102, "Delete C"}, {201, "Insert A"}, {1201, "Insert T"}, {202, "Insert G"}, {1202, "Insert C"}, {400, "Other"}, {1400, "Other"} } ; static FREEOPT errorChoiceA[] = { {9, "Define"}, {2, "A->T"}, {3, "A->G"}, {4, "A->C"}, {101, "Delete A"}, {201, "Insert A"}, {1201, "Insert T"}, {202, "Insert G"}, {1202, "Insert C"}, {400, "Other"} } ; static FREEOPT errorChoiceT[] = { {9, "Define"}, {1002, "T->A"}, {1004, "T->G"}, {1003, "T->C"}, {1101, "Delete T"}, {201, "Insert A"}, {1201, "Insert T"}, {202, "Insert G"}, {1202, "Insert C"}, {400, "Other"} } ; static FREEOPT errorChoiceG[] = { {9, "Define"}, {5, "G->A"}, {6, "G->T"}, {7, "G->C"}, {102, "Delete G"}, {201, "Insert A"}, {1201, "Insert T"}, {202, "Insert G"}, {1202, "Insert C"}, {400, "Other"} } ; static FREEOPT errorChoiceC[] = { {9, "Define"}, {1006, "C->A"}, {1005, "C->T"}, {1007, "C->G"}, {1102, "Delete C"}, {201, "Insert A"}, {1201, "Insert T"}, {202, "Insert G"}, {1202, "Insert C"}, {400, "Other"} } ; static void doRegisterSequenceError (OBJ Cosmid, int x, int k, char *cp) { bsAddData (Cosmid, str2tag ("Possible_error_at_base"),_Int,&x) ; freekey2text(k, errorChoiceAll) ; bsAddData (Cosmid, _bsRight, _Text, freekey2text(k, errorChoiceAll)) ; bsAddData (Cosmid, _bsRight, _Text, cp) ; } static void registerSequenceError (LOOK look, KEY type, int pos, char cBase) { KEY gene = look->gene, cosmid = 0 ; OBJ Cosmid = 0 ; int a1, a2, x, k ; FREEOPT *errorChoice ; if (bIndexGetKey (gene,str2tag ("Genomic_sequence"), &cosmid)) Cosmid = bsUpdate (cosmid) ; if (!Cosmid || !bsFindKey (Cosmid, _Transcribed_gene, gene) || !bsGetData (Cosmid, _bsRight,_Int, &a1) || !bsGetData (Cosmid, _bsRight,_Int, &a2) ) goto abort ; if (a1 < a2) x = pos + a1 - 1 ; else x = a1 - pos + 1 ; switch (cBase) { case A_: errorChoice = errorChoiceA ; break ; case T_: errorChoice = errorChoiceT ; break ; case G_: errorChoice = errorChoiceG ; break ; default: errorChoice = errorChoiceC ; break ; } if (graphSelect (&k, errorChoice)) { ACEIN motif_in = 0 ; if (a1 > a2) { if (k < 1000) k += 1000 ; else k -= 1000 ; } if ((motif_in = messPrompt ("Please comment","","t", 0))) { char *comment = strnew (aceInWord(motif_in),0) ; if (bsFindTag (Cosmid, str2tag("Genomic"))) doRegisterSequenceError (Cosmid, x, k, comment) ; else if (bsFindTag (Cosmid, str2tag("Junction"))) { KEYSET parts = 0 ; KEY source = 0 ; bsSave (Cosmid) ; parts = queryKey (cosmid, ">Parts") ; if (bIndexGetKey (cosmid, _Source, &source) && keySetMax (parts)) { int u1, u2 ; OBJ Source = bsCreate (source) ; if (Source && bsFindKey (Source, _Subsequence, cosmid) && bsGetData (Source, _bsRight,_Int, &u1) && bsGetData (Source, _bsRight,_Int, &u2)) { int iPart = keySetMax (parts) ; int xx = u1 < u2 ? u1 + x - 1 : u1 - x + 1 ; /* in source */ while (iPart--) { KEY pp = keySet(parts, iPart) ; int z1, z2 ; if (bsFindKey (Source, _Subsequence, pp) && bsGetData (Source, _bsRight,_Int, &z1) && bsGetData (Source, _bsRight,_Int, &z2)) { int xxx = z1 < z2 ? xx - z1 + 1 : z1 - xx + 1 ; int longueur = z1 < z2 ? z2 - z1 + 1 : z1 - z2 + 1 ; if (xxx > 0 && xxx < longueur) { OBJ Part = bsUpdate (pp) ; if (Part) doRegisterSequenceError (Part, xxx, k, comment) ; bsSave (Part) ; } } } keySetDestroy (parts) ; } bsDestroy (Source) ; } keySetDestroy (parts) ; } messfree (comment) ; } aceInDestroy (motif_in) ; } abort: bsSave (Cosmid) ; } /************************************************************/ static FREEOPT baseDoEditMenu[] = { {12, "edit"}, {'a', "A"}, {'t', "T"}, {'g', "G"}, {'c', "C"}, {'n', "n"}, {'d', "Delete"}, {'N', "Insert"}, /* modifying this to register hand clips {'x', "Clip Start"}, {'y', "Clip End"}, */ {'J', "Clip Start"}, {'j', "Clip End"}, {'X', "Clip Start Insert"}, {'Y', "Clip End Insert"}, {'U', "Tag this base"} /* {1, "Clip Excellent"}, {2, "Clip Good"}, {3, "Clip Fair"}, {'B', "Neural-net base call"}, {14,"NN Excellent"}, {13, "NN Good"}, {12, "NN Fair"}, {11, "NN Poor"}, {10, "NN Bad"}, {'w', "push down"}, {'u', "push up"}, {'s', "Show Trace"}, {'h', "Hide Trace"}, {'i', "more clip"}, // used by clipMore button {400, "Close down jack pot"}, {401, "Close up jack pot"}, {'I', "Other Hint"}, */ } ; static FREEOPT baseDoEditcDNAMenu[] = { {20, "edit"}, {'a', "A"}, {'t', "T"}, {'g', "G"}, {'c', "C"}, {'n', "n"}, {'d', "Delete"}, {'P', "Insert"}, {'X', "Clip Start Insert:"}, {'Y', "Clip End Insert"}, /* {'Z', "Clip End Quality"}, */ { 300, "PolyA"}, { 311, "Fake internal priming"}, { 301, "SL1:cccaagtttgag"}, { 302, "SL2:cagttactcaag"}, { 303, "SL3:cagttaaccaag"}, /* { 304, "SL0: capped clone"}, */ { 305, "gccgtgctc"}, { 306, "other motif"}, /* { 320, "Favor normal"}, */ { 321, "Favor delete"}, { 322, "Favor insert"}, { 312, "Stops matching"}, { 330, "Error in genomic"} } ; /* static FREEOPT baseDoSuperEditMenu[] = { {6, "Super Edit"}, {'a', "A"}, {'t', "T"}, {'g', "G"}, {'c', "C"}, {'n', "n"}, {'d', "Delete"} } ; */ static FREEOPT baseDoInsertMenu[] = { {5, "insert"}, {'A', "Insert A"}, {'T', "Insert T"}, {'G', "Insert G"}, {'C', "Insert C"}, {'N', "Insert n"} } ; static FREEOPT *baseEditMenu = &baseDoEditMenu[0]; static void baseEdit1 (KEY key, int box) ; static void (*baseEdit)(KEY key, int box) = baseEdit1 ; static void saveHandClip (LOOK look, LANE *lane) { OBJ obj = 0 ; int x ; if (look->mode == CDNA) return ; if ((obj = bsUpdate (lane->key))) { if (bsIsTagInObj (obj, lane->key, _Hand_Clipping)) { x = lane->clipTop + 1 ; bsAddData (obj, _Hand_Clipping, _Int, &x) ; x = lane->clipEnd ; bsAddData (obj, _bsRight, _Int, &x) ; } bsSave (obj) ; } } static void baseDoEdit (LOOK look, LANE *lane, KEY key, int iLong, int iShort, BOOL doRedraw) { int i, min, max, move = 0, pos = 0 ; char cc, *base, *cBase, *cp ; short *basePos ; float offSet, mag ; MAP map = look->map ; char buf [2] ; int oldErrMax = arrayMax(look->dna) ; BOOL isHand = FALSE ; HINT *hh = 0 ; static BOOL firstPass = TRUE ; if (look && firstPass) { firstPass = FALSE ; sessionAutoSave (60 * 30, 60 * 5) ; /* save every 30 minutes, or after 5 minutes inactivity */ } look->activeLane = lane ; if (key == 'P') { /* solves a tiny interface problem when sequence is very dense */ key = 'N' ; if (!lane->upSequence) { iShort++ ; iLong++ ; } } if (!lane->base || iShort < 0 || iShort >= arrayMax(lane->base)) return ; base = arrp (lane->base, iShort, char) ; if (iLong >= 0 && iLong < arrayMax(look->dna)) cBase = arrp (look->dna, iLong, char) ; else return ; basePos = arrp (lane->basePos, iShort, short) ; lao: move = 0 ; switch (key) /* non edit functions */ { case 'J': isHand = TRUE ; key = 'x' ; goto lao ; break ; case 'j': isHand = TRUE ; key = 'y' ; goto lao ; break ; case 'h': if (lane->hide) return ; lane->hide = TRUE ; traceDraw (look) ; return ; case 1: case 2: case 3: case 'x': case 'y': case 'X': case 'Y': case 'Z': case 'i': case 400: case 401: case 'B': case 10: case 11: case 12: case 13: case 14: switch (key) { case 'B': cc = arr (lane->base, pos, char) ; nnBaseCall (lane, iShort) ; if (cc != arr (lane->base, pos, char)) arr (lane->base, pos, char) |= BC_HAND ; break ; case 10: case 11: case 12: case 13: case 14: nnQualityTrain (lane, iShort,key - 10) ; return ; case 1: baseCallUnclipLane (lane, 'E', &i) ; break ; case 2: baseCallUnclipLane (lane, 'G', &i) ; break ; case 3: baseCallUnclipLane (lane, 'F', &i) ; break ; case 'X': i = iShort - lane->vectorTop ; if (i*i > 36 && iShort > 40 && !messQuery( messprintf("Do you really want to move the vector clipping by %d bases", i))) return ; lane->vectorTop = iShort ; if (lane->vectorTop < 0) lane->vectorTop = 0 ; lastVectorClippedRead = lane->key ; /* fall thru */ case 'x': case 401: i = iShort - lane->clipTop ; lane->clipTop = iShort ; if (lane->clipTop < 0) lane->clipTop = 0 ; lane->x1 += i * (lane->upSequence ? -1 : 1) ; break ; case 'y': case 'Y': case 'Z': case 'J': case 400: case 305: i = iShort - lane->clipEnd ; if ( i + lane->clipEnd < lane->clipTop + 10) i = lane->clipTop + 10 - lane->clipEnd ; if ( i + lane->clipEnd > arrayMax (lane->dna)) i = arrayMax (lane->dna) - lane->clipEnd ; if (key != 400 && key != 500 && i*i > 2500 && !messQuery( messprintf("Do you really want to move the clipping by %d bases", i))) return ; if (lane->upSequence) { arrayDestroy (lane->errArray) ; lane->clipEnd += i + 1; lane->x2 -= (i + 1) ; lane->x2 += -1 ; /* key = 'l' ; */ if (look->fMapLook) fMapPleaseRecompute (look->fMapLook) ; sortNeeded = TRUE ; } else { lane->clipEnd += i ; lane->x2 += i ; } if (key == 'Y') { lane->vectorEnd = lane->clipEnd ; lastVectorClippedRead = lane->key ; } else if (key == 'Z') lane->qualityEnd = lane->clipEnd ; break ; case 'i': i = lane->clipEnd ; if (lane->vectorEnd > 0 && lane->vectorEnd <= arrayMax(lane->base) && 60 + iShort > lane->vectorEnd) lane->clipEnd = lane->vectorEnd ; else if (60 + iShort > arrayMax(lane->base)) lane->clipEnd = arrayMax(lane->base) ; else lane->clipEnd += 60 ; lane->x2 += (lane->clipEnd - i) * (lane->upSequence ? -1 : 1) ; break ; } if (isHand) switch (key) { case 'x': lane->handClipTop = lane->clipTop ; saveHandClip (look, lane) ; break ; case 'y': lane->handClipEnd = lane->clipEnd ; saveHandClip (look, lane) ; break ; default: break ; } lastUnclippedLane = lane ; key = 'l' ; if (lane->upSequence) { if (look->fMapLook) fMapPleaseRecompute (look->fMapLook) ; sortNeeded = TRUE ; goto lao ; } findXclipping (lane) ; goto saveedits ; case 'l': lane->x2 += lane->upSequence ? +1 : -1 ; dnaAlignRecale(look->dna, &(lane->x1), &(lane->x2), lane->dna, lane->clipTop, lane->clipEnd - 1) ; lane->x2 -= lane->upSequence ? +1 : -1 ; findXclipping (lane) ; goto saveedits ; case 'I': /* other hint */ lane->getNewSpliceHint = lane->lastSpliceHint ? 2 : 0 ; goto redraw ; } if (lane->scf < 4) /* trace not visible, only n are acceptables */ switch (key) { case 'a': case 't': case 'g': case 'c': case 'n': key = 'n' ; break ; case 'A': case 'T': case 'G': case 'C': case 'N': key = 'N' ; break ; } if (iLong >= 0) if (*cBase == N_ || !*cBase) /* remove N from consesnsus */ switch (freelower(key)) { case 'a': *cBase = A_ ; updateConsensus (look) ; break ; case 't': *cBase = T_ ; updateConsensus (look) ; break ; case 'g': *cBase = G_ ; updateConsensus (look) ; break ; case 'c': *cBase = C_ ; updateConsensus (look) ; break ; } if (lane->upSequence) switch (key) { case 'a': key = 't' ; break ; case 't': key = 'a' ; break ; case 'g': key = 'c' ; break ; case 'c': key = 'g' ; break ; case 'A': key = 'T' ; break ; case 'T': key = 'A' ; break ; case 'G': key = 'C' ; break ; case 'C': key = 'G' ; break ; case 'u': key = 'w' ; break ; case 'w': key = 'u' ; break ; } switch (key) { case 'a': *base &= ~BC_TAG ; *base = BC_LOW | BC_HAND | A_ ; break ; case 't': *base &= ~BC_TAG ; *base = BC_LOW | BC_HAND | T_ ; break ; case 'g': *base &= ~BC_TAG ; *base = BC_LOW | BC_HAND | G_ ; break ; case 'c': *base &= ~BC_TAG ; *base = BC_LOW | BC_HAND | C_ ; break ; case 'n': *base &= ~BC_TAG ; *base = BC_LOW | BC_HAND | N_ ; break ; case 'U': *base |= BC_TAG ; { OBJ obj ; if ((obj = bsUpdate (lane->key))) { buf [1] = 0 ; buf [0] = dnaDecodeChar [*base & 0x0f] ; cp = buf ; i = iShort + 1 ; if (bsAddData (obj, _Significant_bases, _Int, &i)) bsAddData (obj, _bsRight, _Text, cp) ; bsSave (obj) ; if (look->fMapLook) fMapPleaseRecompute (look->fMapLook) ; } } break ; case 300: case 301: case 302: case 303: case 304: case 305: case 306: case 311: case 312: { OBJ obj = 0 ; KEY tsl ; if ((obj = bsUpdate (lane->key))) { switch (key) { case 300: cBase = arrp (look->dna, iLong, char) ; while (*cBase == A_) { if (lane->upSequence) { cBase-- ; iLong-- ; iShort++ ;} else { cBase++ ; iLong++ ; iShort++ ;} } if (lane->upSequence) iShort += 0 ; else iShort += 0 ; bsAddData (obj, _PolyA_after_base, _Int, &iShort) ; break ; case 311: if (lane->upSequence) iShort += 2 ; bsAddTag (obj, str2tag("Fake_internal_poly_A")) ; { KEYSET ks2 = queryKey (lane->key, ">cDNA_clone ; >Read") ; int iks = keySetMax(ks2) ; OBJ obj2 = 0 ; KEY key2 ; while (iks--) { key2 = keySet(ks2, iks) ; if (key2 != lane->key && (obj2 = bsUpdate (key2))) { bsAddTag (obj2, str2tag("Fake_internal_poly_A")) ; bsSave (obj2) ; } } keySetDestroy (ks2) ; } break ; case 301: lexaddkey ("SL1", &tsl, _VMotif) ; bsAddKey (obj, _Transpliced_to, tsl) ; iShort++ ; if (bsFindKey (obj, _Transpliced_to, tsl)) bsAddData (obj, _bsRight, _Int, &iShort) ; iShort-- ; break ; case 302: lexaddkey ("SL2", &tsl, _VMotif) ; iShort++ ; bsAddKey (obj, _Transpliced_to, tsl) ; if (bsFindKey (obj, _Transpliced_to, tsl)) bsAddData (obj, _bsRight, _Int, &iShort) ; iShort-- ; break ; case 303: lexaddkey ("SL3", &tsl, _VMotif) ; bsAddKey (obj, _Transpliced_to, tsl) ; iShort++ ; if (bsFindKey (obj, _Transpliced_to, tsl)) bsAddData (obj, _bsRight, _Int, &iShort) ; iShort-- ; break ; case 304: lexaddkey ("SL0", &tsl , _VMotif) ; iShort++ ; bsAddKey (obj, _Transpliced_to, tsl ) ; if (bsFindKey (obj, _Transpliced_to, tsl )) bsAddData (obj, _bsRight, _Int, &iShort) ; iShort-- ; break ; case 305: lexaddkey ("gccgtgctc", &tsl , _VMotif) ; iShort++ ; bsAddKey (obj, _Transpliced_to, tsl ) ; if (bsFindKey (obj, _Transpliced_to, tsl )) bsAddData (obj, _bsRight, _Int, &iShort) ; iShort-- ; break ; case 306: { ACEIN motif_in; if (!(motif_in = messPrompt ("Motif de bas en haut","","w", 0))) { bsDestroy (obj) ; return ; } lexaddkey (aceInWord(motif_in), &tsl, _VMotif) ; aceInDestroy (motif_in); iShort++ ; bsAddKey (obj, _Transpliced_to, tsl) ; if (bsFindKey (obj, _Transpliced_to, tsl)) bsAddData (obj, _bsRight, _Int, &iShort) ; iShort-- ; } break ; case 312: bsDestroy (obj) ; obj = bsUpdate (lane->clone) ; if (!obj) return ; i = 0 ; /* search if we cur up or down */ if (lane->nextTop && !lane->previousEnd) i = -1 ; /* cut above */ if (!lane->nextTop && lane->previousEnd) i = 1 ; /* cut below */ if (!i) i = (iShort - lane->x1 < iShort - lane->x2) ? -1 : 1 ; cp = i == -1 ? messprintf("stops matching before %d",iShort) : messprintf("stops matching after %d",iShort) ; { ACEIN motif_in; if (!(motif_in = messPrompt ("Stops Matching ?",cp,"w", 0))) { bsDestroy (obj) ; return ; } cp = aceInWord(motif_in) ; iShort++ ; if (bsAddData (obj, _Problem, _Text, cp)) ; iShort-- ; aceInDestroy (motif_in); } if (i == -1) { key = 'X' ; iShort++ ; } else { key = 'Y' ; iShort-- ; } break ; } bsSave (obj) ; if (look->fMapLook) fMapPleaseRecompute (look->fMapLook) ; switch (key) { case 300: if (!lane->upSequence) { key = 'y' ; iShort++ ; } /* was key = 305 */ else { key = 'x' ; iShort-- ; } /* -- since += 2 above */ break ; case 301: case 302: case 303: case 304: case 305: case 306: if (lane->upSequence) { key = 'y' ; iShort-- ; } else { key = 'x' ; iShort++ ; } break ; case 311: goto saveedits ; break ; case 312: break ; } goto lao ; } } break ; case 320: /* favor normal */ lane->favorDelete = 1 ; break ; case 321: /* favor delete */ lane->favorDelete = 2 ; key = 'd' ; goto lao ; break ; case 322: /* favor insert */ lane->favorDelete = 3 ; key = 'N' ; if (!lane->upSequence) { iShort++ ; iLong++ ; } goto lao ; break ; case 330: /* Error in genomic */ if (lane->upSequence) i = lane->x1 - iShort + lane->clipTop + 1 ; else i = lane->x1 + iShort - lane->clipTop + 1 ; { int j = lane->upSequence ? i - 1 : i - 1 ; i -= look->origin ; if (j >= 0 && look->dna && j < arrayMax(look->dna)) registerSequenceError (look, key, i, arr(look->dna,j,char)) ; } return ; case 'd': *(basePos - 1) += (*basePos - *(basePos - 1)) / 3 ; *(basePos + 1) += (*basePos - *(basePos + 1)) / 3 ; i = arrayMax (lane->base) - iShort - 1 ; if (i > 0) while (i--) { *base = *(base + 1) ; base++ ; *basePos = *(basePos + 1) ; basePos++ ; } arrayMax(lane->base)-- ; arrayMax(lane->basePos)-- ; if (iShort < lane->clipTop) lane->clipTop-- ; if (iShort < lane->clipEnd) lane->clipEnd-- ; if (iShort < lane->vectorTop) lane->vectorTop-- ; if (iShort < lane->vectorEnd) lane->vectorEnd-- ; if (iShort < lane->clipExtend) lane->clipExtend-- ; if (lane->clipEnd > arrayMax(lane->dna)) lane->clipEnd = arrayMax(lane->dna) ; pos = iShort ; /* for update in laneEdit Save */ move = -1 ; break ; case 'u': *basePos -= (*basePos - *(basePos - 1)) / 3 ; break ; case 'w': *basePos -= (*basePos - *(basePos + 1)) / 3 ; break ; case 'A': case 'T': case 'G': case 'C': case 'N': /* extend */ if (iShort < lane->clipTop) lane->clipTop++ ; if (iShort < lane->clipEnd) lane->clipEnd++ ; if (iShort < lane->clipExtend) lane->clipExtend++ ; if (iShort < lane->vectorTop) lane->vectorTop++ ; if (iShort < lane->vectorEnd) lane->vectorEnd++ ; base = arrayp(lane->base, arrayMax(lane->base) , char) ; basePos = arrayp(lane->basePos, arrayMax(lane->basePos) , short) ; i = arrayMax (lane->base) - iShort - 1 ; while (i--) { *base = *(base - 1) ; base-- ; *basePos = *(basePos - 1) ; basePos-- ; } base = arrp (lane->base, iShort, char) ; basePos = arrp (lane->basePos, iShort, short) ; *(basePos + 1) += ( *(basePos + 2) - *(basePos + 1))/ 3 ; *(basePos) -= ( *(basePos) - *(basePos - 1))/ 3 ; switch (key) { case 'A': *base &= ~BC_TAG ; *base = BC_LOW | BC_HAND | A_ ; break ; case 'T': *base &= ~BC_TAG ; *base = BC_LOW | BC_HAND | T_ ; break ; case 'G': *base &= ~BC_TAG ; *base = BC_LOW | BC_HAND | G_ ; break ; case 'C': *base &= ~BC_TAG ; *base = BC_LOW | BC_HAND | C_ ; break ; case 'N': *base &= ~BC_TAG ; *base = BC_LOW | BC_HAND | N_ ; break ; } pos = iShort ; /* ? update seulement dans les ins/del ? */ move = 1 ; /* for update in laneEditSave */ break ; } saveedits: laneEditSave (look, lane, iShort /* pos */, move) ; if (!doRedraw) return ; oldErrMax = arrayMax(lane->errArray) ; if (arrayMax(lane->errArray) > oldErrMax + 6) /* something stupid happenned */ { if (look->mode == CDNA && key == 'x') ; /* just open intron */ else { /* realign */ key = 'l' ; goto lao ; } } if (!isWriteAccess ()) /* may occur is somebody else grabed it */ sessionGainWriteAccess() ; /* try to grab it */ if (look->fMapLook) fMapPleaseRecompute (look->fMapLook) ; if (key == 'l') { traceDraw(look) ; return ; } redraw: i = arrayMax(look->hints) ; while (i--) { hh = arrp(look->hints,i, HINT) ; if (lane == hh->lane) hh->lane = 0 ; } graphBoxClear (lane->laneBaseCallBox) ; graphBoxClear (lane->edLaneBaseBox) ; map->centre -= lane->dy ; mag = map->mag ; map->mag *= lane->ddy ; lane->laneBaseCallBox = graphBoxStart () ; offSet = lane->laneBaseCallBoxOffSet ; min = lane->laneBaseCallBoxMin ; max = lane->laneBaseCallBoxMax ; traceDnaLane (look, look->map, lane, &offSet, min, max) ; graphBoxEnd () ; map->centre += lane->dy ; map->mag = mag ; offSet = lane->edLaneBaseBoxOffSet ; map->mag *= look->edMag ; if (lane->scf >= 3) traceEdLaneBases (look, lane, &offSet, look->edMin, look->edMax, lane->scf, FALSE) ; map->mag = mag ; graphBoxDraw (lane->laneBaseCallBox, -1, -1) ; graphBoxDraw (lane->edLaneBaseBox, -1, -1) ; } /*****************/ static void baseEdit1 (KEY key, int box) { HINT* hh ; TRACELOOKGET("baseedit1") ; if (box < arrayMax(look->baseBoxes) && (hh = arrp(look->baseBoxes,box, HINT))) { if (hh->iLong == 1 && hh->y > 0) hh->iLong = GRAPH2MAP (look->map, hh->y) ; if (hh->iLong < 0 || hh->iLong >= arrayMax(look->dna)) hh->iLong = 1 ; baseDoEdit (look, hh->lane, key, hh->iLong, hh->iShort, TRUE) ; } } /********************/ static void hintAccept (LOOK look, HINT *hh) { if (hh && hh->lane) { if (hh->lane->hide) { hh->lane->hide = FALSE ; traceDraw (look) ; } else { if (hh->isSpliceHint == 2) hh->lane->getNewSpliceHint = 1 ; /* stabilize these hints */ baseDoEdit (look, hh->lane, hh->key, hh->iLong, hh->iShort, TRUE) ; hh->lane = 0 ; /* do not reuse */ } } } /************************************************************/ static void doAcceptZoneEdits (BOOL ok, BOOL doDraw, BOOL isV, LANE *myLane, float y1, float y2) { int i ; HINT *hh ; TRACELOOKGET("doAcceptZoneEdits") ; i = arrayMax(look->hints) ; while (i--) { hh = arrp(look->hints,i, HINT) ; if (!hh || !hh->lane || !hh->iLong || hh->lane->hide || hh->isSpliceHint || /* no zone editing of splice hints */ hh->lane->scf < 4) /* no zone editing if trace not seen */ continue ; if (myLane && (hh->lane != myLane)) continue ; if (!hh->lane->upSequence && !hh->lane->previousEnd && hh->iShort < hh->lane->clipTop + 6 && hh->lane->vectorTop < 5) { if (!isV) continue ; /* do not edit too close to vector */ else { int xv =-1, yv = -1, j ; HINT *h2 ; LANE *lane = hh->lane ; for (j = 0, h2 = arrp(look->hints,j, HINT) ; j < arrayMax(look->hints) ; j++, h2++) { if (h2 && h2->lane && h2->lane == lane && h2->iShort < 80 && h2->iShort < h2->lane->clipTop + 8 && xv < h2->iShort ) { xv = h2->iShort ; yv = h2->iLong ; h2->lane = 0 ; } } if (xv > 0) baseDoEdit (look, lane, 'X', yv + 1, xv + 1, FALSE) ; continue ; } } switch (hh->key) { case 'A': case 'T': case 'G': case 'C': case 'N': if (!ok) hh->key = 'N' ; break ; case 'a': case 't': case 'g': case 'c': if (!ok) hh->key = 'n' ; break ; case 'd': break ; default: continue ; } if (!y1 && !y2) { y1 = look->topMargin + 2 ; y2 = look->graphHeight - 2 ; } if (hh->key == 'A' || hh->key == 'T' || hh->key == 'G' || hh->key == 'C' || hh->key == 'N' || !(BC_HAND & arr (hh->lane->base, hh->iShort, char))) /* do not Re edit in zone mode */ { if (hh->y > y1 && hh->y + .9 < y2) baseDoEdit (look, hh->lane, hh->key, hh->iLong, hh->iShort, FALSE) ; } hh->lane = 0 ; /* no recursion */ } showSelect = myLane ? FALSE : TRUE ; /* FALSE ; si on veut stabiliser et voir les editions */ if (doDraw) traceDraw(look) ; showSelect = TRUE ; } /*****************/ static void acceptZoneEdits (void) { doAcceptZoneEdits (TRUE, TRUE, FALSE, 0, 0, 0) ; } /*****************/ static void nifyZoneEdits (void) { doAcceptZoneEdits (FALSE, TRUE, FALSE, 0, 0, 0) ; } /*****************/ static void vectorifyZoneEdits (void) { doAcceptZoneEdits (FALSE, TRUE, TRUE, 0, 0, 0) ; } /*****************/ #ifdef APPARENTLY_NOT_NEEDED static void undoLastVectorClip (void) { OBJ obj ; BOOL done = FALSE ; if ((obj = bsUpdate(lastVectorClippedRead))) { if (bsFindTag (obj, _Vector_Clipping)) { bsRemove (obj) ; done = TRUE ; } bsSave (obj) ; } lastVectorClippedRead = 0 ; if (done) newFixButton () ; else messout ("No previous vector cliping, sorry") ; } #endif /* APPARENTLY_NOT_NEEDED */ /************************************************************/ static void traceDiscard (LOOK look, KEY key) { int ii ; KEY clone = 0, gene = look->gene ; LANE *lane ; ii = arrayMax (look->lanes) ; if (!ii) return ; while (ii--) { lane = arrp (look->lanes, ii, LANE) ; if (key == lane->key) lane->scf = 1 ; } showSelect = TRUE ; bIndexGetKey (key, _cDNA_clone, &clone) ; cDNARemoveCloneFromGene (clone, gene) ; if (look->fMapLook) fMapPleaseRecompute (look->fMapLook) ; } /************************************************************/ static void laneTagger (KEY key, int box) { extern void fMapTraceSuppress (KEY key, KEY tag, BOOL keep); /* fmaptrace.c */ LANE *lane ; int i, ii, c1, c2 ; char *cp ; OBJ obj = 0 ; KEY kk ; TRACELOOKGET("laneTagger") ; ii = arrayExists(look->laneShown) ? arrayMax (look->laneShown) : 0 ; if (!ii) return ; while (ii--) { lane = arr (look->laneShown, ii, LANE*) ; if (box == lane->boxName) { switch (key) { case 'e': lanePlotDerivee (look, lane) ; return ; case 'p': lanePlotPeriodicite (look, lane) ; return ; case 'B': nnLaneTrain (look, lane) ; return ; case 'q': if (look->mode == CDNA) { messout ("Open just a single est trace from the Est menu in the sequence window re-base call") ; return ; } if (!messQuery(messprintf("%s\n%s\n\n%s", "I will irreversibly replace the present base call by the acembly basecall", "corresponding to the colored horizontal lines", "Should I proceed (y/n)"))) return ; CHECKLANE ; if (lane->scf < 3) break ; baseCallRedoLaneBaseCall (lane, 0) ; baseDoEdit(look, lane, 'l', 1,1, TRUE) ; if (arrayMax(look->lanes) == 1) /* single read, then redraw all */ graphDestroy () ; return ; case 's': case 'S': lane->scf = 1 ; /* will suppress further display */ if (look->fMapLook) { fMapPleaseRecompute (look->fMapLook) ; if (graphExists(look->fMapGraph)) { Graph old = graphActive() ; graphActivate (look->fMapGraph) ; fMapTraceSuppress (lane->key, _Assembled_into,key == 's' ? TRUE : FALSE) ; graphActivate (old) ; } } traceDraw (look) ; return ; case 'h': /* hide */ lane->hide = TRUE ; showSelect = FALSE ; traceDraw (look) ; break ; case 'd': traceDiscard (look, lane->key) ; break ; case 'z': doAcceptZoneEdits(TRUE, TRUE, FALSE, lane, 0, 0) ; /* see also lane->boxClose */ return ; break ; case 'w': display(lane->key, 0, "TREE") ; return ; case 'V': lane->vectorTop = lane->vectorEnd = 0 ; i = trackVector (0, lane->key, TRUE) ; if (!i) return ; obj = bsCreate (lane->key) ; if (!obj || !bsGetData (obj, _Clipping, _Int, &c1) || !bsGetData (obj, _bsRight, _Int, &c2)) messcrash ("doTrackVector should have entered these values") ; bsDestroy (obj) ; i = c1 - lane->clipTop ; lane->clipTop += i ; lane->x1 += i * (lane->upSequence ? -1 : 1) ; i = c2 - lane->clipEnd ; if ( i + lane->clipEnd < lane->clipTop + 10) i = lane->clipTop + 10 - lane->clipEnd ; if ( i + lane->clipEnd > arrayMax (lane->dna)) i = arrayMax (lane->dna) - lane->clipEnd ; lane->clipEnd += i ; lane->x2 += i * (lane->upSequence ? -1 : 1) ; lane->vectorTop = c1 - 1 ; lane->vectorEnd = c2 ; lastUnclippedLane = lane ; sortNeeded = TRUE ; if (lane->upSequence && look->fMapLook) fMapPleaseRecompute (look->fMapLook) ; lane->x2 += lane->upSequence ? +1 : -1 ; dnaAlignRecale(look->dna, &(lane->x1), &(lane->x2), lane->dna, lane->clipTop, lane->clipEnd - 1) ; lane->x2 -= lane->upSequence ? +1 : -1 ; findXclipping (lane) ; laneEditSave (look, lane, 0, 0) ; if (!isWriteAccess ()) /* may occur is somebody else grabed it */ sessionGainWriteAccess() ; /* try to grab it */ break ; case 1001: /* select */ if (!keySetExists(look->selectedKs)) look->selectedKs = keySetCreate() ; kk = lane->clone ? lane->clone : lane->key ; keySetInsert (look->selectedKs, kk) ; break ; case 1002: /* unselect */ if (keySetExists(look->selectedKs)) { kk = lane->clone ? lane->clone : lane->key ; keySetRemove (look->selectedKs, kk) ; } break ; default: { ACEIN comments_in; if (!(comments_in = messPrompt ("Comments ?:", "", "t", 0))) return ; cp = aceInWord (comments_in) ; laneDoTag (look, lane, key, cp) ; aceInDestroy (comments_in); } break ; } fMapPleaseRecompute (look->fMapLook) ; traceDraw (look) ; break ; } } } /************/ static FREEOPT laneTagMenu [] = { {7, "TagMenu"}, {'w', "Who am I"}, {'t', "Tag"}, {'s', "Move to new contig"}, {'S', "Discard"}, /* {'h', "Hide Lane"}, {'e', "energie de la derivee"}, {'B', "Neural-Net Training"}, */ {'p', "periodicite"}, {'V', "Search Vector"}, {'q', "Base Call"} } ; static FREEOPT laneTagcDNAMenu [] = { {5, "TagMenu"}, {'w', "Who am I"}, {'V', "Search Vector"}, {'d', "Discard from this gene"}, {1001, "Select"}, {1002, "Unselect"}, } ; static FREEOPT traceTagMenu [] = { {4, "TagMenu"}, {'t', "Comment"}, {'c', "Compression"}, {'a', "Ambiguity"}, {'r', "Resolved"} } ; /************************************************************/ /***************** Destruction ******** *********************/ static void traceDoDestroy (LOOK look) { int i ; LANE *lane ; if (look->lanes && (i = arrayMax(look->lanes))) while (i--) { lane = arrp(look->lanes, i, LANE) ; laneDestroy (lane) ; } arrayDestroy (look->lanes) ; keySetDestroy (look->modifiedTraces) ; arrayDestroy(look->dna) ; arrayDestroy(look->dnaR) ; arrayDestroy(look->hints) ; arrayDestroy(look->laneShown) ; arrayDestroy(look->baseBoxes) ; arrayDestroy(look->hits) ; arrayDestroy(look->geneSplicing) ; arrayDestroy(look->selectedKs) ; } static void traceDestroy (void) { LOOK look = traceLook ; if (look && graphExists (traceGraph)) { mapDestroy (look->map) ; graphAssRemove (&MAP2LOOK_ASSOC) ; /* detach this graph from a map (or vice versa) */ arrayDestroy (look->box2seg) ; traceDoDestroy (look) ; } traceGraph = 0 ; traceLook = 0 ; if (look) { look->magic = 0 ; messfree (look) ; } } /************************************************************/ /***************** Mouse and Kbd ****************************/ /************************************************************/ static void traceSelect(LOOK look, int box) { HINT *hh ; if (box < arrayMax(look->hints) && arrp(look->hints,box, HINT)) { hintAccept (look, arrp(look->hints,box, HINT)) ; return ; } if (box < arrayMax(look->baseBoxes) && (hh = arrp(look->baseBoxes,box, HINT))) look->activeLane = hh->lane ; } static void tracePick (int box, double x, double y) { LANE *lane = 0 ; int i ; TRACELOOKGET("tracePick") ; if (!box) return ; i = arrayMax(look->lanes) ; while (i--) { lane = arrp(look->lanes, i, LANE) ; if (!isLaneShown (look, lane)) continue ; if (box == lane->edLaneBaseBox) { lane->hide = !lane->hide ; showSelect = FALSE ; traceDraw (look) ; return ; } if (!lane->isShown) continue ; if (box == lane->boxMoreClip) { baseDoEdit (look, lane, 'i', 0, lane->clipEnd - 1, TRUE) ; return ; } else if (box == lane->boxLessClip) { if (lane->clipEnd > lane->clipTop + 22) baseDoEdit (look, lane, 'y', 0, lane->clipEnd - 10, TRUE) ; return ; } else if (box == lane->boxLessClipTop) { /*lane->showTraceBeforeClipTop = TRUE ; traceDraw (look) ; */ if (lane->clipTop > 0) baseDoEdit (look, lane, 'x', 0, lane->vectorTop > 0 && lane->clipTop > lane->vectorTop ? lane->vectorTop : (lane->clipTop > 20 ? lane->clipTop - 20 : 0) , TRUE) ; return ; } else if (box == lane->boxClose) { laneTagger ('z', lane->boxName) ; /* lane->hide = TRUE ; showSelect = FALSE ; traceDraw (look) ; return ; */ return ; } else if (box == lane->boxName) { display(lane->key, 0, "TREE") ; return ; } else if (box == lane->boxNewSpliceHint) { baseDoEdit (look, lane, 'I', 0, 0, TRUE) ; return ; } } if (box == look->geneBox) { look->map->centre = look->geneMin + y * (look->geneMax - look->geneMin) / (.8 * ((float)look->graphHeight - look->topMargin)) ; (look->map->draw) () ; return ; } if (box == look->map->thumb.box) { int cc = look->map->centre - look->origin ; if (look->mode == CDNA) fMapDrawFromTrace (look->fMapLook, look->gene, cc, 1) ; else { i = arrayMax(look->lanes) ; while (i--) { lane = arrp(look->lanes, i, LANE) ; if (cc >= lane->x1 && cc < lane->x2) break ; } /* take smallest value, because seg in fmap are always downwards */ i = lane->x1 < lane->x2 ? lane->x1 : lane->x2 ; if (graphActivate (look->fMapGraph) && look->fMapLook) fMapDrawFromTrace (look->fMapLook, lane->key, (int)( look->map->centre - i - look->origin), 1) ; else display (look->link, lane->key, 0) ; } graphActivate (look->graph) ; } else { if (box > look->minLiveBox) traceSelect (look, box) ; look->activeBox = box ; } } /*********************************************************/ /****************** get sequences ************************/ /*********************************************************/ /* lane->seq == the ABI file, * lane->dna == the edited-assembled sequence, clipTop... */ /* extern BOOL dnaAlignForceMatch (Array longDna, int x1, int x2, Array shortDna, int y1, int y2, int*topp, int *endp, int *sensp) ; */ /*********************************************************/ static int lanePlotOrder (void *a, void *b) { LANE* la = *(LANE**)a, *lb = *(LANE**) b ; BOOL ra = la->upSequence , rb = lb->upSequence ; int xa = la->x1 , xb = lb->x1 ; if (ra && !rb) return -1 ; if (rb && !ra) return 1 ; return xa - xb ; /* best traces will be on the outside */ /* else favor closest clipTop if (ra) //thus rb return xa - xb ; else return xb - xb ; */ } /***************************************************************************/ static BOOL traceMakeLanes (LOOK look, int sens) { Array aa = arrayCreate (1000, BSunit), aa1 = arrayCreate (30, BSunit) ; int i, ii = 10000, j, x1, x2 , x3, ct, ce, max = look->map->max ; LANE *lane ; BSunit *u ; OBJ obj = 0 ; KEY key ; if ((obj = bsCreate (look->key))) { if (bsGetArray (obj, _Assembled_from, aa, 5)) ; else /* a read, artificially create one lane */ { array(aa, 0, BSunit).k = look->key ; x1 = 1 ; x2 = arrayMax(look->dna) ; array(aa, 1, BSunit).i = x1 ; array(aa, 2, BSunit).i = x2 ; array(aa, 3, BSunit).i = x1 ; array(aa, 4, BSunit).i = x2 ; } if (bsGetArray (obj, _Aligned, aa1, 5)) /* pour rester en periodicite 5 */ { ii = i = arrayMax(aa) ; for (j = 0 ; j < arrayMax (aa1) ; i++, j++) array (aa, i, BSunit) = array (aa1, j, BSunit) ; } bsDestroy (obj) ; } look->lanes = arrayCreate (12, LANE) ; if (sens > 0) { for (i = 0 , j = 0 ; i < arrayMax(aa) ; i += 5) { u = arrp (aa, i, BSunit) ; key = u[0].k ; x1 = u[1].i ; x2 = u[2].i ; ct = u[3].i ; ce = u[4].i ; x3 = (x1 < x2 ? 1 : -1) * 50 + x2 ; lane = arrayp (look->lanes, j++, LANE) ; lane->key = key ; lane->hide = look->hide ; if (x1 < x2) { lane->upSequence = FALSE ; lane->x1 = x1 - 1 ; lane->x2 = x2 ; lane->x3 = x2 ; /* later += (lane->clipExtend - lane->clipEnd) */ } else { lane->upSequence = TRUE ; lane->x1 = x1 - 1 ; lane->x2 = x2 - 2 ; lane->x3 = x2 - 2 ; } lane->clipTop = ct - 1 ; lane->clipEnd = ce ; lane->scf = 0 ; /* will search it when needed */ if (i >= ii) lane->isAligned = TRUE ; if (look->mode == CDNA) bIndexGetKey (lane->key, _cDNA_clone, &(lane->clone)) ; } } else /* contig a l'envers dans le link */ { for (i = 0 , j = 0 ; i < arrayMax(aa) ; i+= 5) { u = arrp (aa, i, BSunit) ; key = u[0].k ; x1 = u[1].i ; x2 = u[2].i ; ct = u[3].i ; ce = u[4].i ; x3 = (x1 < x2 ? 1 : -1) * 50 + x2 ; lane = arrayp (look->lanes,j++, LANE) ; lane->key = key ; lane->hide = look->hide ; if (x1 > x2) { lane->upSequence = FALSE ; lane->x1 = max - x1 ; lane->x2 = max - x2 + 1 ; lane->x3 = max - x2 + 1 ; } else { lane->upSequence = TRUE ; lane->x1 = max - x1 ; lane->x2 = max - x2 - 1 ; lane->x3 = max - x2 - 1 ; } lane->clipTop = ct - 1 ; lane->clipEnd = ce ; lane->scf = 0 ; /* will search it when needed */ if (i >= ii) lane->isAligned = TRUE ; if (look->mode == CDNA) bIndexGetKey (lane->key,_cDNA_clone, &(lane->clone)) ; } } arrayDestroy (aa) ; arrayDestroy (aa1) ; arraySort(look->lanes, laneGlobalOrder) ; sortNeeded = FALSE ; return arrayMax (look->lanes) ; } /***************************************************************************/ static BOOL traceMakeHitLanes (LOOK look, int sens) { Array aa = arrayCreate (1000, BSunit), aa1 = arrayCreate (30, BSunit) ; int j, j1, x1, x2 , c3, ct, ce, max = look->map->max ; LANE *lane ; HIT *hh ; look->lanes = arrayCreate (12, LANE) ; if (sens > 0) { for (j = j1 = 0 ; j1 < arrayMax(look->hits) ; j1++) { hh = arrp (look->hits, j1, HIT) ; x1 = hh->a1 ; x2 = hh->a2 ; ct = hh->x1 ; ce = hh->x2 ; lane = arrayp (look->lanes, j++, LANE) ; lane->key = hh->est ; lane->hide = look->hide ; if (ct < ce) { lane->upSequence = FALSE ; lane->x1 = x1 - 1 ; lane->x2 = x2 ; lane->x3 = x2 ; /* later += (lane->clipExtend - lane->clipEnd) */ if (j1 > 0 && hh->est == (hh-1)->est) lane->previousEnd = (hh-1)->a2 ; if (j1 < arrayMax(look->hits) - 1 && hh->est == (hh+1)->est) lane->nextTop = (hh+1)->a1 ; } else { lane->upSequence = TRUE ; lane->x1 = x2 - 1 ; lane->x2 = x1 - 2 ; lane->x3 = x1 - 2 ; c3 = ce ; ce = ct ; ct = c3 ; if (j1 > 0 && hh->est == (hh-1)->est) lane->nextTop = (hh-1)->a2 ; if (j1 < arrayMax(look->hits) - 1 && hh->est == (hh+1)->est) lane->previousEnd = (hh+1)->a1 ; } lane->clipTop = ct - 1 ; lane->clipEnd = ce ; lane->scf = 0 ; /* will search it when needed */ bIndexGetKey (lane->key,_cDNA_clone, &(lane->clone)) ; } } else /* contig a l'envers dans le link */ { for (j = j1 = 0 ; j1 < arrayMax(look->hits) ; j1++) { hh = arrp (look->hits, j1, HIT) ; x1 = hh->a1 ; x2 = hh->a2 ; ct = hh->x1 ; ce = hh->x2 ; lane = arrayp (look->lanes,j++, LANE) ; lane->key = hh->est ; lane->hide = look->hide ; if (x1 > x2) { lane->upSequence = FALSE ; lane->x1 = max - x1 ; lane->x2 = max - x2 + 1 ; lane->x3 = max - x2 + 1 ; if (j1 > 0 && hh->est == (hh-1)->est) lane->previousEnd = (hh-1)->a2 ; if (j1 < arrayMax(look->hits) - 1 && hh->est == (hh+1)->est) lane->nextTop = (hh+1)->a1 ; } else { lane->upSequence = TRUE ; lane->x1 = max - x1 ; lane->x2 = max - x2 - 1 ; lane->x3 = max - x2 - 1 ; if (j1 > 0 && hh->est == (hh-1)->est) lane->nextTop = (hh-1)->x2 ; if (j1 < arrayMax(look->hits) - 1 && hh->est == (hh+1)->est) lane->previousEnd = (hh+1)->a1 ; } lane->clipTop = ct - 1 ; lane->clipEnd = ce ; lane->scf = 0 ; /* will search it when needed */ bIndexGetKey (lane->key,_cDNA_clone, &(lane->clone)) ; } } arrayDestroy (aa) ; arrayDestroy (aa1) ; arraySort(look->lanes, laneGlobalOrder) ; sortNeeded = FALSE ; return arrayMax (look->lanes) ; } /***************************************************************************/ static void traceMakeGene (LOOK look, int sens) { OBJ obj = 0 ; Array aa ; BSunit *u ; int i, min = UT_INT_MAX, max = 0 ; if (!look->gene) return ; aa = look->geneSplicing = arrayCreate (36, BSunit) ; if ((obj = bsCreate (look->gene)) && bsGetArray (obj, _Splicing, aa, 4)) for (i = 0 ; i < arrayMax(aa) ; i += 4) { u = arrp (aa, i, BSunit) ; u[0].i += look->origin ; u[1].i += look->origin ; if (u[0].i < min) min = u[0].i ; if (u[1].i > max) max = u[1].i ; } if (max < min) { min = 0 ; max = 1000 ; } look->geneMin = min ; look->geneMax = max ; bsDestroy (obj) ; } /*********************************************************/ /****************** columns ************************/ /*********************************************************/ static void traceConsensus (LOOK look, float *offset) { int i, j, box ; HINT *hh ; LANE *lane ; BOOL old = FALSE ; char *cp, buf[2] ; float x = *offset, oldW, y, yy, yy1, yy2 ; int start, stop ; MAP map = look->map ; start = GRAPH2MAP (map, look->topMargin) ; stop = GRAPH2MAP (map, look->graphHeight) ; buf[1] = 0 ; if (start >= arrayMax(look->dna)) start = arrayMax(look->dna) - 1 ; if (start < 0) start = 0 ; if (stop > arrayMax(look->dna)) stop = arrayMax(look->dna) ; i = stop - start ; cp = arrp (look->dna, start, char) ; j = start ; if (i>0) while (i--) { buf[0] = dnaDecodeChar[(int)*cp++] ; y = MAP2GRAPH(map, j) ; /* no zero */ box = graphBoxStart () ; hh = arrayp (look->baseBoxes, box, HINT) ; hh->lane = (LANE *)(-1) ; hh->iShort = 1 ; hh->iLong = j ; hh->y = y ; hh->key = 0 ; graphText(buf, x, y) ; /* graphColor (WHITE) ; graphRectangle (x - .3, y, x, y) ; */ graphBoxEnd() ; /* graphBoxFreeMenu (box, baseEdit, baseDoSuperEditMenu) ; crash le code pour le moment */ j++ ; yy = MAP2GRAPH(map, j) - .1; if (map->mag > 0) { yy1 = y + 1 ; yy2 = yy - .1 ; } else { yy1 = yy + 1 ; yy2 = y - .1 ; } if (TRUE || yy2 > yy1) { box = graphBoxStart () ; hh = arrayp (look->baseBoxes, box, HINT) ; hh->lane = (LANE *)(-1) ; hh->iShort = 1 ; hh->iLong = j ; hh->key = 0 ; hh->y = (yy1 + yy2) / 2 ; graphRectangle (*offset - 3, yy1, *offset + 1, yy2) ; graphBoxEnd() ; graphBoxDraw (box, WHITE, WHITE) ; graphBoxFreeMenu (box, baseEdit, baseDoInsertMenu) ; } } *offset += 1 ; /* after consensus */ if (look->consensus) { for (i = 0, old = FALSE ; i < arrayMax (look->laneShown) ; i++) { lane = arr (look->laneShown ,i, LANE*) ; if (!lane->isAligned) continue ; CHECKSEQ ; if (!old) { old = TRUE ; *offset += 2 ; /* betweeen up and down */ } traceEdLaneBases (look, lane, offset, look->edMin, look->edMax, 3, TRUE) ; lane->nerr = -1 ; /* don t use as best trace */ } } /* line after consensus */ oldW = graphLinewidth(.3) ; *offset += 1 ; graphLine (*offset, look->topMargin, *offset, look->graphHeight) ; *offset += 6 ; /* 1.5 ; */ graphLinewidth(oldW) ; } /***************************************************************************************/ /***************************************************************************************/ static void showDoIt (LOOK look) { LANE *lane ; int i ; switch (look->hide) { case SHOW_BEST_ERR: case HIDE_NON_BEST: break ; case SHOW_ALL: if (look->lanes && (i = arrayMax(look->lanes))) { lane = arrp (look->lanes, 0, LANE) - 1 ; while (lane++, i--) lane->hide = FALSE ; break ; } break ; } switch (look->hideUp) { case HIDE_UP: case HIDE_DOWN: if (look->lanes && (i = arrayMax(look->lanes))) { lane = arrp (look->lanes, 0, LANE) - 1 ; while (lane++, i--) switch (look->hideUp) { case HIDE_UP: lane->hide = lane->upSequence ; break ; case HIDE_DOWN: lane->hide = !lane->upSequence ; break ; } } break ; default: break ; } showSelect = TRUE ; traceDraw (look) ; } /***********/ static void showChooser (KEY k, int box) { TRACELOOKGET("showChooser") ; switch (k) { case HIDE_UP: case HIDE_DOWN: look->hideUp = k ; break ; case SHOW_ALL: if (look->hideUp) look->hide = SHOW_BEST_ERR ; /* to provoke redraw */ look->hideUp = 0 ; default: if (look->hide == k) return ; look->hide = showChosenMode = k ; } showDoIt (look) ; } /***********/ static void showButton (void) /* toggles SHOW_BEST_ERR */ { TRACELOOKGET("showButton") ; if (look->hide != showChosenMode) look->hide = showChosenMode ; else if (showDefaultMode != showChosenMode) look->hide = showDefaultMode ; else { if (look->hide != SHOW_ALL) look->hide = SHOW_ALL ; else look->hide = SHOW_BEST_ERR ; } showDoIt (look) ; } /****************************************************/ /****************************************************/ static BOOL traceMakeLaneTags (LANE *lane) { OBJ obj ; Array units = 0 ; if (lane->hasTag == 1) return FALSE ; lane->hasTag = 1 ; obj = bsCreate (lane->key) ; if (!obj) return FALSE ; units = arrayReCreate (lane->tags, 12, BSunit) ; if (bsFindTag (obj, _Assembly_tags) && bsFlatten (obj, 4, units) && arrayMax (units)) lane->tags = units ; else { arrayDestroy (units) ; bsDestroy (obj) ; return FALSE ; } bsDestroy (obj) ; lane->hasTag = 2 ; return TRUE ; } static BOOL traceDrawDnaTag (LOOK look, MAP map, LANE *lane, float *offset) { int i , box, col, x, x1, x2, u1, u2, min, max ; float y1, y2 ; static Array units = 0 ; BSunit *u ; char *cp ; BOOL found = FALSE ; if (!traceMakeLaneTags(lane)) return FALSE ; min = look->edMin ; max = look->edMax ; u1 = lane->x1 ; u2 = lane->x2 ; if (u1 > u2) { i = u1 ; u1 = u2 ; u2 = i ; } if (min < u1) min = u1 ; if (max > u2) max = u2 ; if (min >= max) return FALSE ; units = lane->tags ; for ( i = 0 ; i < arrayMax(units) ; i += 4) { u = arrp(units,i,BSunit) ; cp = u[0].s ; x1 = u[1].i ; x2 = u[2].i ; if (lane->upSequence) { x1 = u2 - x1 + lane->clipTop ; x2 = u2 - x2 + lane->clipTop ; } else { x1 = u1 + x1 - lane->clipTop ; x2 = u1 + x2 - lane->clipTop ; } if (x1 > x2) { x = x1 ; x1 = x2 ; x2 = x ; } if ( x1 > max || x2 < min) continue ; if (x1 < min) x1 = min ; if (x2 > max) x2 = max ; y1 = MAP2GRAPH (map, x1) ; y2 = MAP2GRAPH (map, x2) ; box = graphBoxStart () ; graphRectangle (*offset, y1, *offset + .8, y2) ; graphBoxEnd () ; if (!strcmp (cp, "Compression")) col = LIGHTRED ; else if (!strcmp (cp, "Ambiguity")) col = LIGHTRED ; else col = LIGHTGREEN ; graphBoxDraw (box, BLACK, col) ; found = TRUE ; } if (found) *offset += 1 ; return found ; } /***********/ static void traceDnaLane (LOOK look, MAP map, LANE *lane, float *offset, int min, int max) { int n = 0, top, fin, foundSplice ; float y = 0, yy = 0, yy1 = 0, yy2 = 0 ; int nBase , box , color, bgcolor, vv ; char c, *base, *cp ; short *basePos ; char buf[2] ; /* BOOL showCoord = look->coord ; */ BOOL compl = map->mag < 0 ? TRUE : FALSE ; HINT *hh ; KEY key ; CHECKSEQ ; CHECKPOS ; if (!lane->base) return ; *offset += 1.5; /* shift right (for errors sake) */ buf[1] = 0 ; nBase = arrayMax (lane->base) ; if (min < 0) min = 0 ; if (max > lane->maxPos) max = lane->maxPos ; if (min < lane->xClipTop ) { int box = graphBoxStart() ; graphRectangle (*offset, MAP2GRAPH(map, min), *offset + 1, MAP2GRAPH(map, lane->xClipTop)) ; graphBoxEnd () ; color = YELLOW ; if (look->mode == CDNA && lane->previousEnd) color = PALEMAGENTA ; graphBoxDraw (box, BLACK, color) ; } if (lane->vectorTop > 0 && lane->vectorTop < arrayMax(lane->basePos)) { vv = (arr(lane->basePos, lane->vectorTop, short) + arr(lane->basePos, lane->vectorTop - 1 , short)) / 2 ; if (min < vv ) { int box = graphBoxStart() ; graphRectangle (*offset, MAP2GRAPH(map, min), *offset + 1, MAP2GRAPH(map, vv)) ; graphBoxEnd () ; graphBoxDraw (box, BLACK, LIGHTBLUE) ; } } if (max > lane->xClipEnd ) { int box = graphBoxStart() ; graphRectangle (*offset, MAP2GRAPH(map, lane->xClipEnd), *offset + 1, MAP2GRAPH(map, max)) ; graphBoxEnd () ; color = YELLOW ; if (look->mode == CDNA && lane->nextTop) color = PALEMAGENTA ; graphBoxDraw (box, BLACK, color) ; } if (lane->vectorEnd > 0 && lane->vectorEnd < arrayMax(lane->basePos)) { vv = (arr(lane->basePos, lane->vectorEnd, short) + arr(lane->basePos, lane->vectorEnd - 1 , short)) / 2 ; if (max > vv ) { int box = graphBoxStart() ; graphRectangle (*offset, MAP2GRAPH(map, vv), *offset + 1, compl ? look->topMargin : look->graphHeight) ; graphBoxEnd () ; graphBoxDraw (box, BLACK, ORANGE) ; } } base = arrp (lane->base, 0, char) ; basePos = arrp (lane->basePos, 0, short) ; while(*basePos < min && nBase) { basePos++ ; base++ ; nBase-- ; n++ ; } top = n + 1 ; /* Plato */ graphTextFormat (BOLD) ; lane->minBaseBox = graphBoxStart() ; graphBoxEnd () ; lane->minBase = base - arrp (lane->base, 0, char) ; color = WHITE ; while(*basePos < max && nBase) { n++ ; box = graphBoxStart() ; hh = arrayp (look->baseBoxes, box, HINT) ; hh->lane = lane ; hh->iShort = base - arrp (lane->base, 0, char) ; hh->iLong = 1 ; hh->key = 0 ; y = MAP2GRAPH(map, *basePos) ; hh->y = y ; c = *base & 0x0f ; *buf = dnaDecodeChar[(int)(compl ? complementBase[(int)c] : c)] ; if (*base & BC_LOW) *buf = freelower (*buf) ; else *buf = freeupper (*buf) ; if (c == N_) *buf = '?' ; graphText(" ", *offset - 1.8, y) ; /* make the box bit bigger */ graphText(buf, *offset, y) ; graphBoxEnd() ; color = BLACK ; switch (freelower(*buf)) { case 'a': color = LIGHTGREEN ; break ; case 't': color = T_COLOR ; break ; case 'g': color = BLACK ; break ; case 'c': color = BLUE ; break ; case '?': color = MAGENTA ; break ; } bgcolor = WHITE ; if (*base & BC_ACE) bgcolor = GREEN ; if (*base & BC_HAND) bgcolor = YELLOW ; if (*base & BC_TAG) { bgcolor = color ; color = BLACK ; } graphBoxDraw(box, color, bgcolor) ; graphBoxFreeMenu (box, baseEdit, baseEditMenu) ; yy = MAP2GRAPH(map, *(basePos + 1)) ; if (map->mag > 0) { yy1 = y + 1 ; yy2 = yy - .1 ; } else { yy1 = yy + 1 ; yy2 = y - .1 ; } if (hh->iShort >= lane->clipTop - 1 && hh->iShort < lane->clipEnd && yy2 > yy1) { box = graphBoxStart () ; hh = arrayp (look->baseBoxes, box, HINT) ; hh->lane = lane ; hh->iShort = base + 1 - arrp (lane->base, 0, char) ; hh->iLong = 1 ; hh->key = 0 ; hh->y = (yy1 + yy2) / 2 ; graphRectangle (*offset - 3, yy1, *offset + .8 , yy2) ; graphBoxEnd() ; graphBoxDraw (box, WHITE, WHITE) ; graphBoxFreeMenu (box, baseEdit, baseDoInsertMenu) ; } basePos++ ; base++ ; nBase-- ; } lane->maxBase = fin = n ; if (!lane->hide) { int x = *offset - .8 ; float oldW, y ; lane->xHideButton = x ; lane->boxName = box = graphBoxStart () ; y = look->topMargin ; oldW = graphLinewidth(.3) ; if (compl) { graphLine (x, y, x + 2 , y) ; graphLine (x, y, x + 1 , y - 1) ; graphLine (x + 1 , y - 1, x + 2 , y) ; } else { graphLine (x, y - 1, x + 2 , y - 1) ; graphLine (x, y - 1, x + 1 , y) ; graphLine (x + 1 , y, x + 2 , y - 1) ; } graphLinewidth(oldW) ; graphBoxEnd () ; graphBoxFreeMenu (box, laneTagger, look->mode == CDNA ? laneTagcDNAMenu : laneTagMenu) ; color = TRANSPARENT ; if (lane->color) color = lane->color ; key = lane->clone ? lane->clone : lane->key ; if (keySetExists(look->selectedKs) && keySetFind (look->selectedKs, key ,0)) color = RED ; graphBoxDraw (box, BLACK, color) ; box = graphBoxStart () ; cp = messprintf("%d", compl ? fin : top) ; graphText (cp, x - strlen(cp) + 1.9, y - 2.3) ; graphBoxEnd () ; if (lane == look->activeLane) graphBoxDraw (box, BLACK, LIGHTBLUE) ; } else lane->boxName = 0 ; graphTextFormat (PLAIN_FORMAT) ; /* was: *offset += showCoord ? 1.5 + strlen(messprintf("%d",n)) : 1.8 ; */ foundSplice = look->mode == CDNA ? jackPotSearch (look, map, lane, offset, min, max) : 0 ; lane->getNewSpliceHint = 0 ; if (foundSplice < 2) traceDnaLaneErrors (look, map, lane, offset, min, max, foundSplice) ; *offset += 1.95 ; /* was 1.8 */ } /***********/ #ifdef JUNK static FREEOPT jackPotMenu [] = { {4, "Jack-Pot"}, {'a', "Accept"}, {'c', "Close"}, {'r', "Reduce match"}, {'i', "Increase match"}, } ; /************/ static void jackPotAction (KEY key, int box) { LANE *lane, *lane1 ; int i, ii ; TRACELOOKGET("jackPotAction") ; ii = arrayExists(look->laneShown) ? arrayMax (look->laneShown) : 0 ; if (!ii) return ; while (ii--) { lane = arr (look->laneShown, ii, LANE*) ; if (box == lane->boxNewSpliceHint) { switch (key) { case 'a': /* accept */ lane1 = 0 ; { if (lane->jackPotSens == 1 && lane->nextTop) { i = arrayMax (look->lanes) ; while (i--) { lane1 = arrp (look->lanes, i, LANE) ; if (lane != lane1 && lane->key == lane1->key && lane1->x1 == lane->nextTop - 1) break ; } if (i == -1) lane1 = 0 ; } else if (lane->jackPotSens == -1 && lane->previousEnd) { i = arrayMax (look->lanes) ; while (i--) { lane1 = arrp (look->lanes, i, LANE) ; if (lane != lane1 && lane->key == lane1->key && lane1->x1 == lane->previousEnd + 1) break ; } if (i == -1) lane1 = 0 ; } if (lane->jackPotSens == 1) { if (lane1) { baseDoEdit (look, lane1, 'x', lane->jackPotOriginLong + lane->jackPotJump, lane->jackPotOriginShort + 1, FALSE) ; lane->nextTop = lane->jackPotOriginLong + lane->jackPotJump ; lane1->previousEnd = lane->jackPotOriginLong ; } baseDoEdit (look, lane, 'y', lane->jackPotOriginLong, lane->jackPotOriginShort, TRUE) ; } else { if (lane1) { baseDoEdit (look, lane1, 'y', lane->jackPotOriginLong - lane->jackPotJump, lane->jackPotOriginShort - 1, FALSE) ; lane->previousEnd = lane->jackPotOriginLong - lane->jackPotJump ; lane1->nextTop = lane->jackPotOriginLong ; } baseDoEdit (look, lane, 'x', lane->jackPotOriginLong, lane->jackPotOriginShort, TRUE) ; } } break ; case 'c': /* close */ if (lane->jackPotSens == 1) baseDoEdit (look, lane, 400, lane->jackPotOriginLong, lane->jackPotOriginShort, TRUE) ; else if (lane->jackPotSens == -1) baseDoEdit (look, lane, 401, lane->jackPotOriginLong, lane->jackPotOriginShort, TRUE) ; break ; case 'r': /* reduce */ if (lane->jackPotMatchLength > 4) lane->jackPotMatchLength-- ; baseDoEdit (look, lane, 'I', 0, 0, TRUE) ; case 'i': /* increase */ if (lane->jackPotMatchLength < 9) lane->jackPotMatchLength++ ; baseDoEdit (look, lane, 'I', 0, 0, TRUE) ; } break ; } } } #endif /***********/ static BOOL jackPotHint (LOOK look, MAP map, LANE *lane, float *offset, int min, int max, int iShort, int iLong, int jump, int sens, BOOL justTheButton) { float y ; int i, n = 0, nBase , box , color, sensShort, origin = look->origin ; char *base ; short *basePos , bp ; char c, cc, *cp, *cq, buf[2] ; HINT *hh ; BOOL done = FALSE ; CHECKSEQ ; if (lane->scf < 3) return FALSE ; CHECKPOS ; buf[1] = 0 ; nBase = arrayMax (lane->base) ; if (min < 0) min = 0 ; if (max > lane->maxPos) max = lane->maxPos ; base = arrp (lane->base, 0, char) ; basePos = arrp (lane->basePos, 0, short) ; while(*basePos < min && nBase) { basePos++ ; base++ ; nBase-- ; n++ ; } lane->minBase = base - arrp (lane->base, 0, char) ; if (lane->upSequence) { } else { } *offset -= 3.2 ; sensShort = lane->upSequence ? -sens : sens ; bp = (arr (lane->basePos, iShort - sensShort, short) + arr (lane->basePos, iShort, short))/2 ; if (bp > min && bp < max) { y = MAP2GRAPH(map, bp) + (1.0 - sens) / 4.0 ; if (!justTheButton) { graphLine (*offset -1, y, *offset+3, y) ; graphLine (*offset -1, y +.3 * sens, *offset+3, y +.3 * sens) ; if (sens == -1) y -= .8 ; if (sens == -1) graphText (messprintf("%d", iLong - origin + (lane->upSequence ? +1 : +1)), *offset-1, y - sens*1.9) ; else graphText (messprintf("%d", iLong - origin + (lane->upSequence ? +1 : +1)), *offset-1, y - sens*1.9) ; if (sens == -1) graphText (messprintf("%d", iLong - origin + jump * sens + (lane->upSequence ? +2 : +2)), *offset-1, y - sens*1.0) ; else graphText (messprintf("%d", iLong - origin + jump * sens + (lane->upSequence ? +0 : +0)), *offset-1, y - sens*1.0) ; if (sens == -1) y += .8 ; } if ((!lane->upSequence && sens == 1) || (lane->upSequence && sens == -1)) { lane->jackPotOriginLong = iLong - 1 ; lane->jackPotOriginShort = iShort - 1 ; lane->jackPotSens = 1 ; } else { lane->jackPotOriginLong = iLong + 1 ; lane->jackPotOriginShort = iShort + 1 ; lane->jackPotSens = -1 ; } lane->jackPotJump = jump ; lane->boxNewSpliceHint = box = graphBoxStart() ; graphCircle (*offset, y - 3*sens, 1) ; graphCircle (*offset, y - 3*sens, .8) ; graphBoxEnd () ; /* graphBoxFreeMenu (box, jackPotAction,jackPotMenu) ; ce truc est tout faux, a verifier avant de reactiver */ } if (justTheButton) { lane->lastSpliceHint = 0 ; *offset += 3.2 ; return FALSE ; } lane->lastSpliceHint = sens * jump ; iLong += jump * sens ; color = WHITE ; iLong -= sens ; iShort -= sensShort ; i++ ; cp = arrp (look->dna, iLong, char) ; cq = arrp (lane->dna, iShort, char) ; while (cp += sens , cq += sensShort, iLong += sens, iShort += sensShort, iShort >= 0 && iShort < arrayMax(lane->basePos) && iLong >= 0 && iLong < arrayMax(look->dna) ) { bp = arr (lane->basePos, iShort, short) ; if (bp > max) break ; y = MAP2GRAPH(map, bp) ; if (y < look->topMargin || y > look->graphHeight) continue ; done = TRUE ; cc = !lane->upSequence ? *cq : complementBase [(int)(*cq)] ; c = dnaDecodeChar[(int)(*cp)] ; c = freelower(c) ; box = graphBoxStart () ; color = WHITE ; if (*cp != cc) { hh = arrayp (look->hints, box, HINT) ; hh->lane = lane ; hh->iShort = iShort ; hh->iLong = iLong ; hh->y = y ; hh->key = c ; hh->isSpliceHint = 2 ; buf[0] = ' ' ; color = RED ; switch(c) { case 'a': color = A_COLOR ; break ; case 't': color = T_COLOR ; break ; case 'g': color = G_COLOR ; break ; case 'c': color = C_COLOR ; break ; } } buf[0] = c ; graphText(buf, *offset, y) ; graphBoxEnd() ; graphBoxDraw (box, BLACK, color) ; } *offset += 3.2 ; /* shift back (for errors sake) */ return done ; } /***********/ static int jackPotSearch (LOOK look, MAP map, LANE *lane, float *offset, int min, int max) { int i, maxA, n = 0, n1, n2, j, j1 = 0, oldsens = 0, sens ; Array a = lane->errArray ; A_ERR * ep = 0 ; char *cp, *cq ; int isQ = 0 ; /* useless now, */ lane->boxNewSpliceHint = 0 ; if (!a || (maxA = arrayMax(a)) < 5 || look->mode != CDNA) return 0 ; /* try to propose alternative editions */ /* going down */ /* if (lane->upSequence) return 0 ; */ if (lane->getNewSpliceHint) oldsens = lane->lastSpliceHint < 0 ? -1 : 1 ; sens = oldsens ? oldsens : 1 ; for (;sens > -2 ; sens -= 2) { if (oldsens && sens != oldsens) break ; if (sens == 1) { for (i = 0, ep = arrp (a, i, A_ERR) ; ep->iLong < look->wmin && i < maxA ; i++, ep++) ; n2 = i < maxA ? look->wmax - ep->iLong : 0 ; j = i ; for (n1 = 1 ; i < maxA && ep->iLong < look->wmax ; i++, n1++, ep++) ; ep = j < maxA ? arrp (a, j, A_ERR) : 0 ; } else { for (i = arrayMax (a) - 1, ep = arrp (a, i, A_ERR) ; ep->iLong > look->wmax && i >= 0 ; i--, ep--) ; n2 = i >= 0 ? ep->iLong - look->wmin : 0 ; j = i ; for (n1 = 0 ; i >= 0 && ep->iLong > look->wmin ; i--, n1++, ep--) ; ep = j >= 0 ? arrp (a, j, A_ERR) : 0 ; } if (!ep || n1 < 4 || 2*n1 < n2) continue ; switch (lane->getNewSpliceHint) { case 0: j1 = 20 ; break ; case 1: j1 = oldsens * lane->lastSpliceHint ; break ; case 2: j1 = oldsens * lane->lastSpliceHint + 20 ; break ; } for (; j1 < 12000 ; j1++) { j = ep->iLong + j1 * sens ; if (j < 0 || j >= arrayMax(look->dna)) break ; cp = arrp (lane->dna, ep->iShort, char) ; cq = arrp (look->dna, j, char) ; n = lane->jackPotMatchLength ? lane->jackPotMatchLength : 6 ; lane->jackPotMatchLength = n ; while (j1 > (1 << (2 * n - 4))) n++ ; isQ = 0 ; while (n--) if (!lane->upSequence) { if ( !(*cp & *cq)) break ; if (*cp != *cq) { n++ ; isQ++ ; } if (isQ > 1) break ; if (sens == 1) { cp++ ; cq++ ; } else { cp-- ; cq-- ; } } else { if ( !(*cp & complementBase[(int)(*cq)])) break ; if (*cp != complementBase[(int)(*cq)]) { n++ ; isQ++ ; } if (isQ > 1) break ; if (sens == 1) { cp-- ; cq++ ; } else { cp++ ; cq-- ; } } if (n > -1) continue ; /* now count the new set of errors in region */ cp = arrp (lane->dna, ep->iShort, char) ; cq = arrp (look->dna, j, char) ; if (sens == 1) { n = look->wmax - ep->iLong ; n2 = 0 ; while (n--) { if (!lane->upSequence) { if (*cp++ != *cq++) n2++ ;} else { if (*cp-- != complementBase[(int)(*cq++)]) n2++ ;} } } else { n = ep->iLong - look->wmin ; n2 = 0 ; while (n--) { if (!lane->upSequence) { if (*cp-- != *cq--) n2++ ;} else { if (*cp++ != complementBase[(int)(*cq--)]) n2++ ;} } } if (n2 > n1 - 3) continue ; /* success */ if (!jackPotHint (look, map, lane, offset, min, max, ep->iShort, ep->iLong, j1, sens, FALSE)) return 0 ; return 2 ; /* 2 => do not draw also local hints */ } } if (oldsens) jackPotHint (look, map, lane, offset, min, max, ep->iShort, ep->iLong, j1, oldsens, TRUE) ; return 0 ; } /***********/ static void traceDnaLaneErrors (LOOK look, MAP map, LANE *lane, float *offset, int min, int max, BOOL foundSplice) { int n = 0, gotOne = 0 ; float y ; int i, nBase , box , color, sens ; char *base ; short *basePos , bp ; char c, buf[2] ; Array a = 0 ; A_ERR * ep ; HINT *hh ; CHECKSEQ ; if (lane->scf < 3) return ; CHECKPOS ; a = lane->errArray ; buf[1] = 0 ; nBase = arrayMax (lane->base) ; if (min < 0) min = 0 ; if (max > lane->maxPos) max = lane->maxPos ; i = arrayMax(a) ; if (!i) return ; base = arrp (lane->base, 0, char) ; basePos = arrp (lane->basePos, 0, short) ; while(*basePos < min && nBase) { basePos++ ; base++ ; nBase-- ; n++ ; } lane->minBase = base - arrp (lane->base, 0, char) ; if (lane->upSequence) { sens = -1 ; ep = arrp(a, i - 1, A_ERR) ; } else { sens = 1 ; ep = arrp(a, 0, A_ERR) ; } while (i && ep->iShort < lane->minBase) { ep += sens ; i-- ;} if (i < 0) return ; *offset -= 1.2 ; gotOne = 1 ; color = WHITE ; i++ ; ep -= sens ; while (ep += sens , i-- && ep->iShort >= 0 && ep->iShort < arrayMax(lane->basePos) && ep->iShort < lane->clipEnd && ep->iLong >= 0 && ep->iLong < arrayMax(look->dna) ) { bp = arr (lane->basePos, ep->iShort, short) ; if (bp > max) break ; y = MAP2GRAPH(map, bp) ; c = dnaDecodeChar[(int)arr(look->dna, ep->iLong, char)] ; c = freelower(c) ; box = graphBoxStart () ; hh = arrayp (look->hints, box, HINT) ; hh->lane = lane ; hh->iShort = ep->iShort ; hh->iLong = ep->iLong ; hh->y = y ; if (foundSplice) hh->isSpliceHint = 1 ; switch(ep->type) { case TROU_DOUBLE: case TROU: hh->key = freeupper(c) ; if(lane->upSequence) hh->iShort++ ; break ; case AMBIGUE: case ERREUR: hh->key = c ; break ; case INSERTION: /*_AVANT: */ case INSERTION_DOUBLE: /*_AVANT: */ hh->key = 'd' ; break ; } buf[0] = ' ' ; switch(ep->type) { case TROU: graphText(buf, *offset, y - 1) ; case AMBIGUE: case ERREUR: color = RED ; switch(c) { case 'a': color = A_COLOR ; break ; case 't': color = T_COLOR ; break ; case 'g': color = G_COLOR ; break ; case 'c': color = C_COLOR ; break ; } break ; case INSERTION: /*_AVANT: */ color = CYAN ; c = '*' ; break ; case INSERTION_DOUBLE: /*_AVANT: */ color = MAGENTA ; c = '#' ; break ; case TROU_DOUBLE: graphText(buf, *offset, y - 2) ; graphText(buf, *offset, y - 1) ; color = MAGENTA ; c = 'X' ; break ; } buf[0] = c ; graphText(buf, *offset, y) ; graphBoxEnd() ; graphBoxDraw (box, BLACK, color) ; } *offset += 1.2 ; } /***************************************************************************************/ /****************************** plots **************************************************/ static BOOL traceLaneCrossing (Array lanes, LANE *lane) { int nl = arrayMax(lanes) ; LANE *ll = arrp(lanes, 0, LANE) - 1 ; while (ll++, nl--) if (ll->key != lane->key && ll->clone && ll->clone == lane->clone && ((lane->upSequence && !ll->upSequence && lane->x2 < ll->x2) || (!lane->upSequence && ll->upSequence && lane->x2 > ll->x2) )) return TRUE ; return FALSE ; } /***************************************************************************************/ static void laneHeight (LANE *lane, TRACE **ap) { int k, i ; TRACE *sp, hMin = 0, hMax = 0 ; int min = 0, max = lane->maxPos ; if (lane->basePos && arrayMax(lane->basePos) > 2) min = arr (lane->basePos,1,short) ; hMin = hMax = 0 ; for (k=0 ; k<4 ; k++) { sp = ap[k] ; for (i = min, sp += min ; i < max ; i++, sp++) { if (hMax < *sp && *sp < 1000) hMax = *sp ; if (hMin > *sp) hMin = *sp ; } } lane->laneMax = hMax > hMin ? hMax : -1 ; /* -1 will prevent recursion */ lane->laneMin = hMin ; } /***************************************************************************************/ static Array histoTrace0 = 0, histoTrace1 = 0, histoTrace2 = 0, histoTrace3 = 0, histoTrace4 = 0 ; static void traceDoPlot (LOOK look, LANE *lane, int min, int max, float *offset, MAP map, TRACE *ap[4], int laneMin, int laneMax, int width, int seqmax) { int k, i, p, origin = look->origin ; float hScale, x0, x1, x2, y1, y2, dy; int box ; float oldW ; BOOL compl ; static Array points = 0 ; if (laneMax <= 0 || width < 5) return ; hScale = (width - 3) / (float) (laneMax - laneMin) ; x0 = *offset - laneMin * hScale ; if (min < 0) min = 0 ; if (max > seqmax) max = seqmax ; if (!lane->showTraceBeforeClipTop && min < lane->xClipTop ) min = lane->xClipTop ; if (max > lane->xClipEnd ) max = lane->xClipEnd ; oldW = graphLinewidth(.3) ; for (k=0 ; k<4 ; k++) { int z0, z1 , z2, z3, z4, /* various predictors */ u1, u2, u3, u4 ; /* previous values */ TRACE *sp = ap[k] ; /* actual trace */ u1 = u2 = u3 = u4 = 0 ; box = graphBoxStart() ; dy = MAP2GRAPH(map,min + 1) - MAP2GRAPH(map,min) ; points = arrayReCreate (points, 2*(max - min) + 8 , float) ; p = 0 ; for (i = min, sp += min, x1 = x0 + *sp * hScale , y1 = y2 = MAP2GRAPH(map,min), array (points, p++, float) = x1, array (points, p++, float) = y1 ; i < max ; i++, sp++) { x2 = x0 + *sp * hScale ; y2 += dy ; z0 = 0 ; z1 = u1 ; if (z1 < 0) z1 = 0 ; if (z1 > 255) z1 = 255 ; z2 = 2*u1 - u2 ; if (z2 < 0) z2 = 0 ; if (z2 > 255) z2 = 255 ; z3 = 3*u1 - 3*u2 + u3 ; if (z3 > 255) z3 = 255 ; if (z3 < 0) z3 = 0 ; z4 = 4*u1 - 6*u2 + 4*u3 - u4; if (z4 > 255) z4 = 255 ; if (z4 < 0) z4 = 0 ; if (i < min + 1) z1 = z0 ; if (i < min + 2) z2 = z1 ; if (i < min + 3) z3 = z2 ; if (i < min + 4) z4 = z3 ; if (histoTrace0) array(histoTrace0, (300 + (*sp - z0 )) , int)++ ; if (histoTrace1) array(histoTrace1, (300 + (*sp - z1 )) , int)++ ; if (histoTrace2) array(histoTrace2, (300 + (*sp - z2 )) , int)++ ; if (histoTrace3) array(histoTrace3, (300 + (*sp - z3 )) , int)++ ; if (histoTrace4) array(histoTrace4, (300 + (*sp - z4 )) , int)++ ; u4 = u3 ; u3 = u2 ; u2 = u1 ; u1 = *sp ; /* here is the place to make any transform you like on the display example: x2 = x0 + z3 * hScale ; */ array (points, p++, float) = x2 ; array (points, p++, float) = y2 ; x1 = x2 ; y1 = y2 ; } graphLineSegs (points) ; graphBoxEnd() ; graphBoxDraw(box, BASE_COLOR[lane->upSequence ? 3 - k : k], TRANSPARENT) ; } graphLinewidth(oldW) ; lane->boxLessClip = lane->boxMoreClip = 0 ; compl = lane->x1 > lane->x2 ; if ((compl && y2 > look->topMargin + 4 ) || (!compl && y2 < look->graphHeight - 4)) { float x = x0 + 1, y, dy = compl ? -1 : 1 ; if (lane->nextTop) { y = compl ? y2 - 2 : y2 + 2 ; graphText (messprintf ("%d", lane->x2 - origin + 1), x, !compl ? y2 + 1.5 : y2 - 1.5) ; graphText (messprintf ("%d", lane->nextTop - origin + (compl ? 1 : - 1)), x, !compl ? y2 + 2.5 : y2 - 2.5) ; y = compl ? y2 - 4 : y2 + 3 ; } else { y = compl ? y2 - 2 : y2 + 2 ; box = graphBoxStart () ; lane->boxLessClip = box ; graphLine (x, y, x + 2 , y) ; graphLine (x, y, x + 1 , y - dy ) ; graphLine (x + 1 , y - dy, x + 2 , y) ; graphBoxEnd () ; if (lane->handClipTop && lane->clipTop == lane->handClipTop) graphBoxDraw(box, BLACK, ORANGE) ; } y += compl ? - .7 : .7 ; box = graphBoxStart () ; if (lane->clipEnd < arrayMax(lane->dna)) { lane->boxMoreClip = box ; graphLine (x, y , x + 2 , y ) ; graphLine (x, y, x + 1 , y + dy) ; graphLine (x + 1 , y + dy , x + 2 , y) ; } else { lane->boxMoreClip = 0 ; graphRectangle (x, y , x + 2 , y + dy) ; } graphBoxEnd () ; if (lane->handClipEnd && lane->clipEnd == lane->handClipEnd) graphBoxDraw(box, BLACK, ORANGE) ; if (traceLaneCrossing (look->lanes, lane)) graphBoxDraw(box, BLACK, ORANGE) ; } lane->boxLessClipTop = lane->boxMoreClipTop = 0 ; y1 = MAP2GRAPH(map,min) ; if (look->mode == CDNA && lane->clipTop > 0 /* lane->vectorTop */ && ( (!compl && y1 > look->topMargin + 4 ) || (compl && y1 < look->graphHeight - 4)) ) { float x = x0 + 1, y = compl ? y1 + 4 : y1 - 4 , dy = compl ? -1 : 1 ; if (lane->previousEnd) { graphText (messprintf ("%d", lane->x1 - origin + (lane->upSequence ? 2 : 0)), x, compl ? y1 + 1.5 : y1 - 1.5) ; graphText (messprintf ("%d", lane->previousEnd - origin + (lane->upSequence ? -1 : 1)), x, compl ? y1 + 2.5 : y1 - 2.5) ; } box = graphBoxStart () ; lane->boxLessClipTop = box ; graphLine (x, y, x + 2 , y) ; graphLine (x, y, x + 1 , y - dy ) ; graphLine (x + 1 , y - dy, x + 2 , y) ; graphBoxEnd () ; } laneShowExtrema (look, lane, offset, min, max) ; *offset += width ; } /***********/ static void tracePlotLane(LOOK look, LANE *lane, float *offset, int min, int max) { TRACE *bp[4] ; lane->boxClose = graphBoxStart () ; graphCircle ( *offset + 2.345, look->topMargin - .9, 1.1) ; graphText(messprintf("e"), *offset + 2, look->topMargin - 1.45) ; graphBoxEnd() ; if (lane->favorDelete == 2) graphText(messprintf("*"), *offset + 4, look->topMargin - 1.45) ; else if (lane->favorDelete == 3) graphText(messprintf("#"), *offset + 4, look->topMargin - 1.45) ; bp[0] = lane->seq->traceA ; bp[1] = lane->seq->traceG ; bp[2] = lane->seq->traceC ; bp[3] = lane->seq->traceT ; if (!lane->laneMax) laneHeight (lane, bp) ; traceDoPlot(look, lane, min, max, offset, look->map, bp, lane->laneMin, lane->laneMax, look->traceWidth, lane->maxPos ) ; } /***********/ static BOOL isLaneShown (LOOK look, LANE *lane) { int x1, x2, u1 = look->wmin + 1 , u2 = look->wmax - 1 ; if (lane->upSequence) { x1 = lane->x2 ; x2 = lane->x1 ; } else { x1 = lane->x1 ; x2 = lane->x2 ; } if (x1 > u2 || x2 < u1) return FALSE ; CHECKLANE ; return lane->scf > 1; } /***********/ static void selectBestTraces (LOOK look) { MAP map = look->map ; LANE *bestUp, *bestDown, *lane, *lane1 = 0 ; int i, e, eUp, eDown, wmin = look->wmin, wmax = look->wmax, wc1 = wmin + (wmax - wmin) / 6, wc2 = wmax - (wmax - wmin) / 6, nUp = 0, nDown = 0, nPerfectUp = 0, nPerfectDown = 0, nClippedNoError = 0, j, min, max ; KEY key ; float mag ; A_ERR *ep ; /* check and count */ i = arrayMax (look->laneShown) ; if (!i) return ; while (i--) { lane = arr (look->laneShown ,i, LANE*) ; if (lane->isAligned) continue ; lane->hide = 0 ; /* abuse lane->hide */ if (!fineTune (look, &lane1, lane)) continue ; key = lane->clone ? lane->clone : lane->key ; if (look->select && keySetExists(look->selectedKs) && !keySetFind (look->selectedKs, key, 0)) continue ; CHECKLANE ; if (lane->scf < 2) /* data is lacking */ continue ; lane->hide = 1 ; /* 1: data exists */ if (lane->upSequence) nUp++ ; else nDown++ ; if (arrayMax(lane->errArray)) { ep = arrp (lane->errArray, 0, A_ERR) - 1 ; j = arrayMax (lane->errArray) ; while (ep++, j--) { if (ep->iLong < wc1) continue ; if (ep->iLong < wc2) lane->hide |= /* 2: ambigue */ (ep->type == AMBIGUE ? /* 4: ambigue editee */ ((BC_HAND & arr (lane->base, ep->iShort, char)) ? 4 : 2) : 8) ; /* 8: error */ if (ep->iLong >= wc2) break ; } } if (lane->x1 > look->wmin && lane->x1 < look->wmax) { lane->hide |= 16 ; /* 16: clip top */ if (look->hide == SHOW_SPLICER) { /* see if there is no error close to the splice site */ if (!arrayMax(lane->errArray)) lane->hide |= 128 ; else { if (!lane->upSequence) { ep = arrp (lane->errArray, 0, A_ERR) - 1 ; j = arrayMax (lane->errArray) ; while (ep++, j--) if (ep->iLong > lane->x1) { /* first error further than splice site + 9 */ if (ep->iLong > lane->x1 + 7) lane->hide |= 128 ; break ; } } else { ep = arrp (lane->errArray, arrayMax(lane->errArray) -1 , A_ERR) + 1 ; j = arrayMax (lane->errArray) ; while (ep--, j--) if (ep->iLong < lane->x1) { /* first error further than splice site + 9 */ if (ep->iLong < lane->x1 - 7) lane->hide |= 128 ; break ; } } if (j == -1) lane->hide |= 128 ; } } } if (lane->x2 > look->wmin && lane->x2 < look->wmax) { lane->hide |= 32 ; /* 32: clip end */ if (look->hide == SHOW_SPLICER) { /* see if there is no error close to the splice site */ if (!arrayMax(lane->errArray)) lane->hide |= 128 ; else { if (lane->upSequence) { ep = arrp (lane->errArray, 0, A_ERR) - 1 ; j = arrayMax (lane->errArray) ; while (ep++, j--) if (ep->iLong > lane->x2 + 1) { /* first error further than splice site + 9 */ if (ep->iLong > lane->x2 + 8) lane->hide |= 128 ; break ; } } else { ep = arrp (lane->errArray, arrayMax(lane->errArray) -1 , A_ERR) + 1 ; j = arrayMax (lane->errArray) ; while (ep--, j--) if (ep->iLong < lane->x2 - 1) { /* first error further than splice site + 9 */ if (ep->iLong < lane->x2 - 8) lane->hide |= 128 ; break ; } } if (j == -1) lane->hide |= 128 ; } } } if (lane->hide == 1) { if (lane->upSequence) nPerfectUp++ ; else nPerfectDown++ ; } else if (!(lane->hide & 10)) nClippedNoError++ ; } switch (look->hide) { case SHOW_ALL: goto ok ; } /* look for best among perfect */ bestUp = bestDown = 0 ; eUp = eDown = 0 ; i = arrayMax (look->laneShown) ; while (i--) { lane = arr (look->laneShown ,i, LANE*) ; if (lane->isAligned) continue ; if (!(lane->hide & 1)) continue ; if (lane->upSequence) { switch (nPerfectUp) { case 0: if (nClippedNoError && (lane->hide & 10)) continue ; break ; /* measure the energy of all bads */ case 1: /* single candidate */ if (lane->hide == 1) bestUp = lane ; continue ; default: /* only measure the best ones */ if (lane->hide != 1) continue ; } } else { switch (nPerfectDown) { case 0: if (nClippedNoError && (lane->hide & 10)) continue ; break ; /* measure the energy of all bads */ case 1: /* single candidate */ if (lane->hide == 1) bestDown = lane ; continue ; default: /* only measure the best ones */ if (lane->hide != 1) continue ; } } map->centre -= lane->dy ; mag = map->mag ; map->mag *= lane->ddy ; min = GRAPH2MAP(map, look->topMargin) ; max = GRAPH2MAP(map, look->graphHeight) ; if (lane->upSequence) { j = min ; min = max ; max = j ; } e = seqEnergyOfDerivee(lane->seq, min, max) ; map->centre += lane->dy ; map->mag = mag ; if (lane->upSequence && e > eUp) { eUp = e ; bestUp = lane ; } if (!lane->upSequence && e > eDown) { eDown = e ; bestDown = lane ; } } if (bestUp) bestUp->hide |= 64 ; /* 64: best */ if (bestDown) bestDown->hide |= 64 ; /* restore */ ok: i = arrayMax (look->laneShown) ; if (look->mode == CDNA && look->hide == SHOW_BEST_ERR) { int x1, x2, ok ; KEYSET ks = keySetCreate () ; while (i--) { lane = arr (look->laneShown, i, LANE*) ; /* printf("%s hide = %d x1 = %d x2 = %d\n", name(lane->key), lane->hide, lane->x1 - look->origin , lane->x2 - look->origin) ; */ switch (look->hideUp) { case HIDE_UP: if (lane->upSequence) { lane->hide = TRUE ; continue ; } break ; case HIDE_DOWN: if (!lane->upSequence) { lane->hide = TRUE ; continue ; } break ; } if (!(lane->hide & 1)) /* can't fineTune */ { lane->hide = TRUE ; continue ; } if (lane->hide & 10) /* errors */ { lane->hide = FALSE ; continue ; } if ( ( (lane->hide & 16) && /* clip top 5p */ !lane->upSequence && lane->clipTop > 0 && (lane->clipTop != lane->vectorTop ) ) || ( (lane->hide & 16) && /* clip top 3p */ lane->upSequence && lane->clipTop > 0 && (lane->clipTop != lane->vectorTop ) ) || ( (lane->hide & 32) && /* clip end 5p */ !lane->upSequence && (lane->nextTop || !traceLaneCrossing (look->lanes, lane)) ) || ( (lane->hide & 32) && /* clip end 3p */ lane->upSequence && (lane->nextTop || !traceLaneCrossing (look->lanes, lane)) ) ) { x1 = lane->x1 ; x2 = lane->x2 ; lane->hide = TRUE ; ok = 0 ; if (x1 > 0 && x1 > look->wmin && x1 < look->wmax) { if (!keySet( ks, x1)) { keySet (ks, x1) = 1 ; lane->hide = FALSE ; } x1 = lane->previousEnd ; if (x1 && !keySet( ks, x1)) { keySet (ks, x1) = 1 ; lane->hide = FALSE ; } } if (x2 > 0 && x2 > look->wmin && x2 < look->wmax) { if (!keySet( ks, x2)) { keySet (ks, x2) = 1 ; lane->hide = FALSE ; } x2 = lane->nextTop ; if (x2 && !keySet( ks, x2)) { keySet (ks, x2) = 1 ; lane->hide = FALSE ; } } continue ; } else { if (lane->hide & 64) /* best */ { lane->hide = FALSE ; continue ; } lane->hide = TRUE ; /* default */ } } keySetDestroy (ks) ; return ; } i = arrayMax (look->laneShown) ; while (i--) { lane = arr (look->laneShown, i, LANE*) ; if (!(lane->hide & 1)) /* can't fineTune */ { lane->hide = TRUE ; continue ; } switch (look->hideUp) { case HIDE_UP: if (lane->upSequence) { lane->hide = TRUE ; continue ; } break ; case HIDE_DOWN: if (!lane->upSequence) { lane->hide = TRUE ; continue ; } break ; } if ((look->next == NEXT_CLIP || look->next == NEXT_HOLE) && lane == lastUnclippedLane) { lane->hide = FALSE ; } else switch (look->hide) { case SHOW_ALL: lane->hide = FALSE ; break ; case SHOW_BEST_ERR: if (lane->hide & (64 + 8 + 4 + 2)) lane->hide = FALSE ; else lane->hide = TRUE ; break ; case HIDE_NON_BEST: if (lane->hide & 64) lane->hide = FALSE ; else lane->hide = TRUE ; break ; case SHOW_CLIP: if (lane->hide & (64 + 32 + 16)) lane->hide = FALSE ; else lane->hide = TRUE ; break ; case SHOW_SPLICER: /* show lane contributing to splicing */ if (lane->hide & 128) lane->hide = FALSE ; else lane->hide = TRUE ; break ; } } } /****************/ static void tracePlotAllLanes (LOOK look, float *offset) { LANE *lane, *lane1 = 0 ; MAP map = look->map ; int i, j1, j2, min, max, fin ; BOOL old = TRUE ; float mag, y, x0 = *offset ; j1 = j2 = 0 ; i = arrayMax (look->laneShown) ; if (!i) return ; while (i--) { lane = arr (look->laneShown, i, LANE*) ; CHECKSEQ ; CHECKPOS ; if (!lane->hide && !lane->isAligned && lane->scf >= 3) j1++ ; if (!lane->hide && !lane->isAligned && lane->scf >= 4) j2++ ; } if (!j1) return ; if (!j2) j2 = 1 ; look->traceWidth = (look->graphWidth - *offset - 5 - 3.8 * j1) / j2 ; if (look->traceWidth < 12) /* was 8 */ look->traceWidth = 12 ; /* was 6 */ if (look->traceWidth > 18) look->traceWidth = 18 ; old = TRUE ; for (i = 0 ; i < arrayMax (look->laneShown) ; i++) { lane = arr (look->laneShown, i, LANE*) ; if (lane->hide || lane->isAligned) continue ; if (*offset > look->graphWidth - 3) { if (lane->greenBox) graphBoxDraw (lane->greenBox, WHITE, TRANSPARENT) ; continue ; } if (!showSelect && /* did fineTune */ !fineTune (look, &lane1, lane) ) continue ; map->centre -= lane->dy ; mag = map->mag ; map->mag *= lane->ddy ; min = GRAPH2MAP(map, look->topMargin) ; max = GRAPH2MAP(map, look->graphHeight) ; if (min > max) /* mag < 0, reverse to simplify maths */ { int tmp = max ; max = min ; min = tmp ; } #ifdef JUNK if (old != lane->upSequence) { old = lane->upSequence ; *offset += .8 ; graphLine (*offset, min, *offset, max) ; *offset += .4 ; graphLine (*offset, min, *offset, max) ; *offset += .8 ; } #endif fin = look->showClip ? lane->xClipExtend : lane->xClipEnd ; lane->laneBaseCallBox = graphBoxStart () ; lane->laneBaseCallBoxOffSet = *offset ; lane->laneBaseCallBoxMin = min ; lane->laneBaseCallBoxMax = max ; CHECKSEQ ; CHECKPOS ; traceDnaLane (look, look->map, lane, offset, min, max) ; lane->isShown = TRUE ; /* enables box pick */ graphBoxEnd () ; if (!lane->hide) { if (lane->scf >= 4) tracePlotLane (look,lane, offset, min, max) ; else { char *cp = name(lane->key) ; char buf[2] ; int y = 12 ; buf[1] = 0 ; while (*cp && y < look->graphHeight - 4) { buf[0] = *cp++ ; graphText (buf, *offset + .2, y++) ; } y += 6 ; cp = "no trace" ; while (*cp && y < look->graphHeight - 4) { buf[0] = *cp++ ; graphText (buf, *offset + .2, y++) ; } graphRectangle (*offset, look->topMargin + 2, *offset + 1.4, look->graphHeight - 2) ; *offset += 3.0 ; } } map->centre += lane->dy ; map->mag = mag ; } y = MAP2GRAPH (look->map, look->map->centre) ; graphLine (x0, y, *offset, y) ; } /************************************/ void traceScale (LOOK look, float *offset) { float y, unit, subunit ; int x, origin = look->origin, iUnit, iSubunit, max = look->wmax + 1 - origin , /* no zero */ min = look->wmin + 1 - origin ; unit = subunit = 1.0 ; mapFindScaleUnit (look->map, &unit, &subunit) ; iUnit = unit + 0.5 ; if (iUnit < 1) iUnit = 1 ; iSubunit = subunit + 0.5 ; if (iSubunit < 1) iSubunit = 1 ; x = iUnit * (min/iUnit) ; while (x < min) x += iUnit ; for ( ; x < max ; x += iUnit) { y = MAP2GRAPH(look->map, x + origin - 1) + .5; /* NO ZERO */ graphLine (*offset+1.0, y, *offset+1.8, y) ; graphText (messprintf ("%d", x), *offset+1.95, y - .5) ; } x = iSubunit * (min/iSubunit) ; while (x < min) x += subunit ; for ( ; x < max ; x += subunit) { y = MAP2GRAPH(look->map, x + origin - 1) + .5; graphLine (*offset+1.0, y, *offset+1.5, y) ; } graphLine (*offset+1, look->topMargin+2, *offset+1, look->graphHeight-0.5) ; *offset += 8 ; } /*****************************************************************/ /****************** left most, gene center ********************/ /*****************************************************************/ void traceGene (LOOK look, float *offset) { float x, y1, y2 ; int i, x1, x2, box ; KEY tt ; MAP map = look->map ; float mag = map->mag, centre = map->centre; BSunit *u ; if (look->mode != CDNA || !look->gene || !look->geneSplicing || !arrayMax(look->geneSplicing)) return ; genex = x = *offset + .2 ; map->centre = (look->geneMax + look->geneMin) / 2 ; map->mag = .8 * ((float)look->graphHeight - look->topMargin) / (look->geneMax - look->geneMin) ; y1 = MAP2GRAPH (map, look->edMin) ; y2 = MAP2GRAPH (map, look->edMax) ; box = graphBoxStart () ; graphRectangle (x -1.0, y1, x + 1.4, y2) ; graphBoxEnd () ; graphBoxDraw (box, GREEN, GREEN) ; y1 = MAP2GRAPH (map, look->wmin) ; y2 = MAP2GRAPH (map, look->wmax) ; box = graphBoxStart () ; graphRectangle (x +.2, y1, x + 3, y2) ; graphBoxEnd () ; graphBoxDraw (box, GREEN, GREEN) ; look->geneBox = graphBoxStart () ; graphColor (MAGENTA) ; for (i = 0 ; i < arrayMax(look->geneSplicing) ; i += 4) { u = arrp (look->geneSplicing, i, BSunit) ; x1 = u[0].i ; x2 = u[1].i ; tt = u[2].k ; y1 = MAP2GRAPH (map, x1) ; y2 = MAP2GRAPH (map, x2) ; if (tt == _Intron) { float mid = (y1 + y2) / 2 ; if (!u[3].s || strcmp("gt_ag", u[3].s)) graphColor (BLUE) ; graphLine (x +.2, y2, x + 1.6 , mid) ; graphLine (x +1.6, mid, x + .2, y1 +.1) ; } else if (tt == _Alternative_intron) { float mid = (y1 + y2) / 2 ; if (!u[3].s || strcmp("gt_ag", u[3].s)) graphColor (BLUE) ; graphLine (x +.5, y2, x + 1.9 , mid) ; graphLine (x +1.9, mid, x + .5, y1 +.1) ; } else if (tt == _Exon || tt == _First_exon || tt == _Last_exon) { box = graphBoxStart () ; graphRectangle (x +.2, y1, x + 1.4 , y2) ; graphBoxEnd () ; graphBoxDraw (box,MAGENTA, PALEMAGENTA) ; graphBoxSetPick (box, FALSE) ; } else if (tt == _Alternative_exon || tt == _Alternative_partial_exon) { float old = graphLinewidth (.2) ; box = graphBoxStart () ; graphRectangle (x -.2, y1, x + 1.9 , y2) ; graphBoxEnd () ; graphBoxDraw (box,ORANGE, TRANSPARENT) ; graphBoxSetPick (box, FALSE) ; graphLinewidth (old) ; } else if (tt == _Partial_exon) { graphRectangle (x +.2, y1, x + 1.4 , y2) ; } else if (tt == _Gap) { graphColor (BLACK) ; graphLine (x +.8, y1, x + .8 , y2) ; } else { graphColor (RED) ; graphRectangle (x +.1, y1, x + .4 , y2) ; } graphColor (MAGENTA) ; } graphColor (BLACK) ; graphBoxEnd () ; graphBoxDraw (look->geneBox,MAGENTA, TRANSPARENT) ; map->mag = mag ; map->centre = centre ; *offset += 2 ; } /*****************************************************************/ /****************** left half/sequence editor ********************/ /*****************************************************************/ #ifdef JUNK static void countVisibleTraces (float x) { int i = arrayMax(look->lanes) ; LANE *lane = i ? arrp(look->lanes,0,LANE) - 1 : 0 ; x += 1.6 /* edconcensus */ + 1 ; /* trace eds */ while(lane++, i--) if (isLaneShown (look, lane)) } #endif /*****************************************************************/ void traceEdCoords (LOOK look, float *offset) { float x, y ; int n, i, di, origin = look->origin ; char *cp = 0 ; int start = look->edMin - origin, stop = look->edMax - origin ; MAP map = look->map ; float mag = map->mag ; map->mag *= look->edMag ; graphTextHeight (0.75) ; n = stop - start ; n /= 4 ; di = 1 ; lao: if (2*di > n) goto done ; di *= 2 ; if (5*di > 2*n) goto done ; di *= 5 ; di /= 2 ; if (2*di > n) goto done ; di *= 2 ; goto lao ; done: for (i = ((start + di - 1)/di) * di ; i < stop ; i += di) { x = i ; y = MAP2GRAPH(map,x + origin) - 1 ; graphText (cp = messprintf("%d", i), *offset+0.9, y) ; } graphTextHeight (0) ; map->mag = mag ; *offset += .5 + ( cp ? strlen(cp) : 0 ); /* countVisibleTraces (*offset) ; */ } /***************************************************************************************/ /* start, stop are the first and last consensus base on screen */ static void traceEdConsensus (LOOK look, float *offset) { char *cp, buf[2] ; float x = *offset, y ; int start = look->edMin, stop = look->edMax ; MAP map = look->map ; int i , j ; float mag = map->mag ; map->mag *= look->edMag ; buf[1] = 0 ; if (start >= arrayMax(look->dna)) start = arrayMax(look->dna) - 1 ; if (start < 0) start = 0 ; if (stop > arrayMax(look->dna)) stop = arrayMax(look->dna) ; i = stop - start ; cp = arrp (look->dna, start, char) ; j = start ; while (i--) { buf[0] = dnaDecodeChar[(int)*cp++] ; y = MAP2GRAPH(map, j++) ; /* no zero */ graphText(buf, x, y) ; } map->mag = mag ; *offset += 1.6 ; /* see traceEdCoords */ } /**********************************************************************/ /* start, stop are the first and last consensus base on screen */ static void traceEdLaneBases (LOOK look, LANE *lane, float *offset, int start, int stop, int type, BOOL isAligned) { char c, buf[2] ; int color, i, nn, u1, u2, u3, nerr = 0, v1 = lane->vectorTop, v2 = lane->vectorEnd, w1, w2, x1 = lane->x1, x2 = lane->x2 , x3 = lane->x3 ; BOOL upSequence = lane->upSequence ; float x = *offset, y = look->topMargin, ddx, ddy ; Array a ; MAP map = look->map ; A_ERR * ep ; if (look->hideDots & 0x1) /* 1:auto or 3:hand set to hide */ return ; a = lane->errArray ; /* baseCallGet (lane) ; */ if (lane->scf != type || lane->isAligned != isAligned) return ; if (lane->scf == 2) *offset += .5 ; if (!look->showClip) x3 = x2 ; if (upSequence) { u1 = x3 ; u2 = x2 ; u3 = x1 ; } else { u1 = x1 ; u2 = x2 ; u3 = x3 ; } if (lane->hasTag != 1) traceDrawDnaTag (look, look->map, lane, offset) ; x = *offset ; i = GRAPH2MAP (look->map, look->topMargin) ; if (start < i) start = i ; i = GRAPH2MAP (look->map, look->graphHeight) ; if (stop > i) stop = i ; if (u3 < start || u1 >= stop) return ; lane->edLaneBaseBox = graphBoxStart () ; lane->edLaneBaseBoxOffSet = *offset ; if (u1 < start) u1 = start ; if (u2 < start) u2 = start ; if (u2 > stop) u2 = stop ; if (u3 > stop) u3 = stop ; /* show clipping */ if (!lane->hide) { int ngreen = 0, box = graphBoxStart() ; graphRectangle (*offset - .2, MAP2GRAPH(map, start - .8), *offset + 1.0, MAP2GRAPH(map, stop)) ; graphBoxEnd () ; if (ngreen++ < 1000) /* look->maxVisibleTraces) */ graphBoxDraw (box, PALEGREEN, PALEGREEN) ; graphBoxSetPick (box, FALSE) ; lane->greenBox = box ; } if (!upSequence && start < u1) { int box = graphBoxStart() ; graphRectangle (*offset - .1, MAP2GRAPH(map, start - .8), *offset + .9, MAP2GRAPH(map, u1 - .15)) ; graphBoxEnd() ; color = YELLOW ; if (look->mode == CDNA && lane->previousEnd) color = PALEMAGENTA ; graphBoxDraw (box, BLACK, color) ; graphBoxSetPick (box, FALSE) ; } if (upSequence && stop > x1) { int box = graphBoxStart() ; graphRectangle (*offset - .1, MAP2GRAPH(map, x1 + .80), *offset + .9, MAP2GRAPH(map, stop)) ; graphBoxEnd() ; color = YELLOW ; if (look->mode == CDNA && lane->previousEnd) color = PALEMAGENTA ; graphBoxDraw (box, BLACK, color) ; graphBoxSetPick (box, FALSE) ; } if (!upSequence && stop > u2) { int box = graphBoxStart() ; graphRectangle (*offset - .1, MAP2GRAPH(map, u2), *offset + .9, MAP2GRAPH(map, stop)) ; graphBoxEnd() ; color = YELLOW ; if (look->mode == CDNA && lane->nextTop) color = PALEMAGENTA ; graphBoxDraw (box, BLACK, color) ; graphBoxSetPick (box, FALSE) ; } if (upSequence && start < u2) { int box = graphBoxStart() ; graphRectangle (*offset - .1, MAP2GRAPH(map, start - .8), *offset + .9, MAP2GRAPH(map, u2 + .85)) ; graphBoxEnd() ; color = YELLOW ; if (look->mode == CDNA && lane->nextTop) color = PALEMAGENTA ; graphBoxDraw (box, BLACK, color) ; graphBoxSetPick (box, FALSE) ; } /* show vector clipping */ if (lane->dna && lane->clipEnd == arrayMax(lane->dna)) v2 = lane->clipEnd ; if (v1 >= 0 || v2 > 0) { float oldW = graphLinewidth(.3) ; w1 = w2 = -1 ; if (!lane->upSequence) { if (v1 > 0) w1 = lane->x1 + v1 - lane->clipTop ; if (v2 > 0) w2 = lane->x2 + v2 - lane->clipEnd - 1 ; } else { if (v1 > 0) w1 = lane->x1 - v1 + lane->clipTop ; if (v2 > 0) w2 = lane->x2 - v2 + lane->clipEnd + 1 ; } if (!upSequence && start < w1) { int box = graphBoxStart() ; graphRectangle (*offset - .1, MAP2GRAPH(map, start - .8), *offset + .9, MAP2GRAPH(map, w1 - .15)) ; graphBoxEnd() ; graphBoxDraw (box, BLACK, LIGHTBLUE) ; graphBoxSetPick (box, FALSE) ; } if (w1 > 0 && upSequence && stop > w1) { int box = graphBoxStart() ; graphRectangle (*offset - .1, MAP2GRAPH(map, w1 + .85), *offset + .9, MAP2GRAPH(map, stop)) ; graphBoxEnd() ; graphBoxDraw (box, BLACK, LIGHTBLUE) ; graphBoxSetPick (box, FALSE) ; } if (w2 > 0 && !upSequence && stop >= w2) { int box = graphBoxStart() ; graphRectangle (*offset - .1, MAP2GRAPH(map, w2), *offset + .9, MAP2GRAPH(map, stop)) ; graphBoxEnd() ; graphBoxDraw (box, BLACK, PALEORANGE) ; graphBoxSetPick (box, FALSE) ; if (u2 == w2) u3-- ; } if (w2 > 0 && upSequence && start <= w2) { int box = graphBoxStart() ; graphRectangle (*offset - .1, MAP2GRAPH(map, start - .8), *offset + .9, MAP2GRAPH(map, w2 - .15)) ; graphBoxEnd() ; graphBoxDraw (box, BLACK, PALEORANGE) ; graphBoxSetPick (box, FALSE) ; if (u2 == w2) u3-- ; } graphLinewidth(oldW) ; } /********/ buf[0] ='.' ; buf[1] = 0 ; if (upSequence) u3++ ; for (i = u1 ; i < u3 ; i++) graphText(buf, x, MAP2GRAPH(map, i - .2)) ; if (!arrayExists(a) || !arrayMax(a)) goto done; ep = arrp(a, 0, A_ERR) - 1 ; i = arrayMax(a) ; nerr = 0 ; while (ep++, i--) { c = dnaDecodeChar[upSequence ? complementBase[(int)ep->baseShort] : (int)ep->baseShort] ; if (c == 'w') c = 'X' ; ddx = 0 ; ddy = 0 ; switch(ep->type) { case ERREUR: color = RED ; c = freelower(c) ; break ; case TROU: color = BLUE ; c = '*' ; break ; case TROU_DOUBLE: color = BLUE ; c = '#' ; break ; case INSERTION: /*_AVANT: */ color = BLUE ; c = freeupper(c) ; ddx = -.5 ; ddy = -.5 ; break ; /* case INSERTION_APRES: color = BLUE ; c = freeupper(c) ; ddx = .5 ; ddy = .5 ; break ; */ case INSERTION_DOUBLE: /*_AVANT: */ color = ORANGE ; /* BLUE ; */ c = 'Y' ; ddx = -.5 ; ddy = -.5 ; break ; /* case INSERTION_DOUBLE_APRES: color = BLUE ; c = 'X' ; ddx = .5 ; ddy = .5 ; break ; */ case AMBIGUE: color = GREEN ; c = freelower(c) ; break ; } if (upSequence) { ddx *= -1 ; /* ddy *= -1 ; */ } nn = ep->iLong ; y = MAP2GRAPH(map, nn) ; buf[0] = c ; if (nn >= start && nn < stop && ep->iShort >= lane->clipTop && ep->iShort < lane->clipEnd) { graphText(buf, x + ddx, y + ddy) ; nerr++ ; } } /* this is a duplicate ? if (lane->scf == 2) { int box ; float oldW = graphLinewidth(.3) ; lane->boxName = box = graphBoxStart () ; y = look->topMargin ; x = *offset - .2 ; if (lane->upSequence) { graphLine (x, y, x + 2 , y) ; graphLine (x, y, x + 1 , y - 1) ; graphLine (x + 1 , y - 1, x + 2 , y) ; } else { graphLine (x, y - 1, x + 2 , y - 1) ; graphLine (x, y - 1, x + 1 , y) ; graphLine (x + 1 , y, x + 2 , y - 1) ; } graphLinewidth(oldW) ; graphBoxEnd () ; graphBoxDraw (box, BLACK, look->activeLane && lane == look->activeLane ? LIGHTBLUE : TRANSPARENT) ; } else lane->boxName = 0 ; */ done: graphBoxEnd () ; /* if (lane->boxName) { if (lane->upSequence) graphText (messprintf("%d", u3), x +.1, y - 2.3) ; else graphText (messprintf("%d", u1 + 1), x +.1, y - 2.3) ; } */ lane->nerr = nerr ; *offset += lane->scf >= 3 ? 1.4 : 2.4 ; } /*****************************************************************/ void traceEds (LOOK look, float *offset) { int k = 0, i = arrayMax(look->lanes) ; LANE *lane = i ? arrp(look->lanes,0,LANE) - 1 : 0 ; BOOL old = FALSE ; float mag = look->map->mag ; Array a ; a = look->laneShown = arrayReCreate (look->laneShown, 20, LANE*) ; look->map->mag *= look->edMag ; *offset += 1 ; /* after consensus */ while(lane++, i--) { lane->isShown = FALSE ; lane->greenBox = 0 ; if (isLaneShown (look, lane)) { CHECKSEQ ; if (lane->isAligned || lane->scf >= 3) array (a, k++, LANE*) = lane ; } } if (showSelect) selectBestTraces (look) ; /* will fineTune */ if (sortNeeded) arraySort(look->lanes, laneGlobalOrder) ; sortNeeded = FALSE ; arraySort (a, lanePlotOrder) ; if (look->hideDots < 2) /* auto choice, count and choose */ { int nn = 0 ; for (i = 0 ; i < k ; i++) { lane = arr (a, i, LANE*) ; if (!lane->isAligned && lane->scf >= 3) nn++ ; } look->hideDots = nn > 6 ? 1 : 0 ; } if (! (look->hideDots & 0x1)) for (i = 0 ; i < k ; i++) { lane = arr (a, i, LANE*) ; if (old != lane->upSequence) *offset += 1 ; /* betweeen up and down */ old = lane->upSequence ; if (!lane->isAligned && lane->scf >= 3) traceEdLaneBases (look, lane, offset, look->edMin, look->edMax, lane->scf, FALSE) ; } look->map->mag = mag ; *offset += 1 ; /* see traceEdCoords */ } /*****************************************************************/ /*************************** Header ******************************/ /**********************************************************/ static void exportLane0(void) { TRACE *bp[4], *sp, x ; int u1, u2, u3, u4, z ; LANE *lane ; FILE *ff = 0 ; int i, j, n ; Array a ; char *cp ; TRACELOOKGET("export") ; if (!look->lanes || !arrayMax(look->lanes)) return ; lane = arrp(look->lanes, 0, LANE) ; traceGetLane (look, lane) ; CHECKSEQ ; if (lane->scf < 4) return ; bp[0] = lane->seq->traceA ; bp[1] = lane->seq->traceG ; bp[2] = lane->seq->traceC ; bp[3] = lane->seq->traceT ; if ((ff = filopen (messprintf("%s", name(lane->key)), "trx", "w"))) { fprintf (ff, " pos A T G C\n\n") ; for (n=0 ; n < lane->maxPos ; n++) { fprintf(ff, "\n %6d: ", n) ; j = *(bp[0] + n) ; j = *(bp[3] + n) ; j = *(bp[1] + n) ; j = *(bp[2] + n) ; fprintf (ff, "%6d", j) ; } filclose (ff) ; } if ((ff = filopen (messprintf("%s", name(lane->key)), "tr0", "w"))) { i = 4 ; while (i--) { cp = (char*) bp[i] ; n = lane->maxPos * sizeof (TRACE) ; fwrite (cp, n, 1, ff) ; } filclose (ff) ; } if ((ff = filopen (messprintf("%s", name(lane->key)), "tr1", "w"))) { i = 4 ; while (i--) { a = arrayCreate (lane->maxPos, char) ; array (a, lane->maxPos - 1 , char) = 0 ; cp = arrp (a, 0, char) ; sp = bp[i] ; x = 0 ; u1 = u2 = u3 = 0 ; for (j=0 ; j < lane->maxPos ; cp++, sp++, j++) { z = u1 ; *cp = (char) ((*sp - z) & 255) ; u3 = u2 ; u2 = u1 ; u1 = *sp ; } n = arrayMax (a) ; cp = arrp (a, 0, char) ; fwrite (cp, n, 1, ff) ; arrayDestroy (a) ; } filclose (ff) ; } if ((ff = filopen (messprintf("%s", name(lane->key)), "tr2", "w"))) { i = 4 ; while (i--) { a = arrayCreate (lane->maxPos, char) ; array (a, lane->maxPos - 1 , char) = 0 ; cp = arrp (a, 0, char) ; sp = bp[i] ; x = 0 ; u1 = u2 = u3 = 0 ; for (j=0 ; j < lane->maxPos ; cp++, sp++, j++) { z = 2*u1 - u2 ; if (z < 0) z = 0 ; if (z > 255) z = 255 ; *cp = (char) ((*sp - z) & 255) ; u3 = u2 ; u2 = u1 ; u1 = *sp ; } n = arrayMax (a) ; cp = arrp (a, 0, char) ; fwrite (cp, n, 1, ff) ; arrayDestroy (a) ; } filclose (ff) ; } if ((ff = filopen (messprintf("%s", name(lane->key)), "tr3", "w"))) { i = 4 ; while (i--) { a = arrayCreate (lane->maxPos, char) ; array (a, lane->maxPos - 1 , char) = 0 ; cp = arrp (a, 0, char) ; sp = bp[i] ; x = 0 ; u1 = u2 = u3 = 0 ; for (j=0 ; j < lane->maxPos ; cp++, sp++, j++) { z = 3*u1 - 3*u2 + u3 ; if (z > 255) z = 255 ; if (z < 0) z = 0 ; *cp = (char) ((*sp - z) & 255) ; u3 = u2 ; u2 = u1 ; u1 = *sp ; } n = arrayMax (a) ; cp = arrp (a, 0, char) ; fwrite (cp, n, 1, ff) ; arrayDestroy (a) ; } filclose (ff) ; } if ((ff = filopen (messprintf("%s", name(lane->key)), "tr4", "w"))) { i = 4 ; while (i--) { a = arrayCreate (lane->maxPos, char) ; array (a, lane->maxPos - 1 , char) = 0 ; cp = arrp (a, 0, char) ; sp = bp[i] ; x = 0 ; u1 = u2 = u3 = u4 = 0 ; z = 4*u1 - 6*u2 + 4*u3 - u4; for (j=0 ; j < lane->maxPos ; cp++, sp++, j++) { z = 3*u1 - 3*u2 + u3 ; if (z > 255) z = 255 ; if (z < 0) z = 0 ; *cp = (char) ((*sp - z) & 255) ; u4 = u3 ; u3 = u2 ; u2 = u1 ; u1 = *sp ; } n = arrayMax (a) ; cp = arrp (a, 0, char) ; fwrite (cp, n, 1, ff) ; arrayDestroy (a) ; } filclose (ff) ; } } /**********************************************************/ static void traceHisto (void); static void baseCallPatchButton (void) ; static FREEOPT showMenu[] = { {6, "Show What"}, {SHOW_ALL, "All Traces"}, {HIDE_UP, "Hide Up Traces"}, {HIDE_DOWN, "Hide Down Traces"}, {SHOW_BEST_ERR, "Best + Errors"}, {HIDE_NON_BEST, "Best traces"}, {SHOW_SPLICER, "Exact splice sites"} } ; static void dummyButton (void) { return ; } static void nextChooser (KEY k, int box) { TRACELOOKGET("nextChooser") ; look->next = k ; switch (k) { case NEXT_ERROR: showDefaultMode = SHOW_BEST_ERR ; break ; case NEXT_PROBLEM: showDefaultMode = SHOW_BEST_ERR ; break ; case NEXT_COMPARE: showDefaultMode = HIDE_NON_BEST ; look->consensus = TRUE ; break ; case NEXT_CLIP: showDefaultMode = HIDE_NON_BEST ; break ; case NEXT_HOLE: showDefaultMode = HIDE_NON_BEST ; break ; case NEXT_TAG: showDefaultMode = SHOW_BEST_ERR ; break ; } } static void nnTrain (void) { TRACELOOKGET("nnTrain") ; nnAssemblyTrain (look) ; } static MENUOPT emptyMenu[] = { {menuSpacer,""}, {0, 0} } ; /* static MENUOPT globalEditMenu[] = { {undoLastVectorClip,"Undo last vector clipping"}, {0, 0} } ; */ static MENUOPT complexMenu[] = { {mapColControl, "Display Control"}, {traceHisto, "Signal Histograms"}, {exportLane0, "Export lane 0"}, {nnTrain, "Train Neural-Net"}, {0, 0} } ; static MENUOPT fixMenu[] = { {newFixButton, "Fix Window"}, {newBigFixButton, "Fix Contig"}, /* {fixButton, "Fix Whole Contig"}, */ {traceRealignAll, "Realign"}, {baseCallPatchButton, "Auto Edit BaseCall"}, {0, 0} } ; #ifdef APPARENTLY_NOT_NEEDED static void tagButton(void) { messout ("This is a menu. Please, use the right mouse button") ; return ; } #endif /* APPARENTLY_NOT_NEEDED */ void traceMapZoomIn (void) { MAP map = currentMap("traceMapZoomIn"); lastMag = map->mag *= 1.414 ; (map->draw) () ; return; } /* traceMapZoomIn */ void traceMapZoomOut (void) { MAP map = currentMap("traceMapZoomOut"); lastMag = map->mag /= 1.414 ; (map->draw)() ; return; } /* traceMapZoomOut */ void selectButton (void) { TRACELOOKGET("selectButton") ; look->select = TRUE ; traceDraw (look) ; } void hideDotsButton (void) { TRACELOOKGET("selectButton") ; if (look->hideDots & 0x1) look->hideDots = 2 ; else look->hideDots = 3 ; traceDraw (look) ; } void selectArrows (void) { TRACELOOKGET("selectButton") ; look->select = TRUE ; traceDraw (look) ; } void unselectButton (void) { TRACELOOKGET("unselectButton") ; look->select = FALSE ; traceDraw (look) ; } Array traceAddTagMenu = 0 ; static MENUOPT buttonOpts[] = { {graphDestroy, "Quit"}, {help, "Help"}, {traceMapZoomIn, "Zoom In"}, {traceMapZoomOut, "Zoom Out"}, {graphPrint, "Print"}, {newFixButton, "Fix"}, /* {tagButton, "Tag..."}, */ {0, 0} } ; /************************************************************/ /***************** Registered routines *********************/ static void traceKbd (int k, int unused) { TRACELOOKGET("traceKbd") ; if (look->mode == CDNA) { switch (k) { case 'e': case RETURN_KEY: case SPACE_KEY: acceptZoneEdits () ; break ; case 'n': nifyZoneEdits () ; break ; case 'v': vectorifyZoneEdits () ; break ; case 'f': newFixButton () ; graphPop () ; return ; case 'g': { Graph old = graphActive () ; newFixButton () ; if (graphActivate (look->fMapGraph)) graphPop () ; graphActivate (old) ; } return ; case LEFT_KEY: traceMapZoomIn() ; break ; case RIGHT_KEY: traceMapZoomOut() ; break ; case UP_KEY: look->map->centre -= 5 ; look->map->centre = nextError (look, FALSE) ; (look->map->draw) () ; break ; case DOWN_KEY: look->map->centre += 5 ; look->map->centre = nextError (look, TRUE) ; (look->map->draw) () ; break ; default: break ; } return ; } } /*************************************************************/ static void traceCentre (LOOK look, float from) { int nx, ny ; graphFitBounds (&look->graphWidth,&look->graphHeight) ; halfGraphHeight = 0.5*(look->graphHeight - look->topMargin) ; nx = look->graphWidth ; ny = look->graphHeight - look->topMargin - 5 ; look->map->centre = from ; if (!look->map->mag) look->map->mag = ny / (look->mode == CDNA ? 50.0 : 22.0) ; if (look->map->mag <= 0) /* safeguard */ look->map->mag = 0.05 ; } /*************************************************************/ static void traceDraw (LOOK look) { float mag, x ; char *cp ; int box, min, max ; if (graphActivate(look->graph)) graphPop() ; else return ; graphClear () ; if (!look->dna) { graphRedraw() ; graphDestroy () ; return ; } arrayDestroy (histoTrace0) ; arrayDestroy (histoTrace1) ; arrayDestroy (histoTrace2) ; arrayDestroy (histoTrace3) ; arrayDestroy (histoTrace4) ; histoTrace0 = arrayCreate (256, int) ; histoTrace1 = arrayCreate (256, int) ; histoTrace2 = arrayCreate (256, int) ; histoTrace3 = arrayCreate (256, int) ; histoTrace4 = arrayCreate (256, int) ; genex = 0 ; dragFast = -1 ; look->topMargin = 5 ; /* see traceGene */ traceCentre (look, look->map->centre) ; if (!assExists(look->traceAss)) look->traceAss = assCreate () ; look->box2seg = arrayReCreate (look->box2seg, 256, int) ; look->hints = arrayReCreate (look->hints, 100, HINT) ; look->baseBoxes = arrayReCreate (look->baseBoxes, 100, HINT) ; look->wmin = GRAPH2MAP(look->map, look->topMargin) + .8 ; look->wmax = GRAPH2MAP(look->map, look->graphHeight) + .9 ; mag = look->map->mag ; look->map->mag = 1.2 ; look->edMag = look->map->mag / mag ; min = GRAPH2MAP(look->map, look->topMargin) ; max = GRAPH2MAP(look->map, look->graphHeight) ; if (min < 0) min = 0 ; if (max > arrayMax(look->dna)) max = arrayMax(look->dna) ; if (max < 0) max = 0 ; if (min > arrayMax(look->dna)) min = arrayMax(look->dna) ; look->edMin = look->map->min = min ; look->edMax = look->map->max = max ; look->map->mag = mag ; graphMenu (emptyMenu) ; look->summaryBox = graphBoxStart () ; graphTextPtr (look->summary, look->graphWidth - 6, 2, 4) ; graphBoxEnd() ; graphBoxDraw (look->summaryBox, BLACK, LIGHTBLUE) ; look->activeBox = 0 ; mapDrawColumns (look->map) ; box = graphButtons(buttonOpts, 1,1.21,look->graphWidth) ; graphBoxMenu (box + 4, complexMenu) ; if (look->mode != CDNA) graphBoxMenu (box + 5, fixMenu) ; /* graphBoxFreeMenu (box + 6, (FreeMenuFunction) traceTagger, traceTagMenu) ; */ x = 56.0 ; box = graphButton ("Show...", showButton, x, .2) ; graphBoxFreeMenu (box, (FreeMenuFunction) showChooser, showMenu) ; cp = freekey2text (look->hide, showMenu) ; graphText (cp, x + 8.5, .2) ; if (look->mode != CDNA) { box = graphButton ("Next...", dummyButton, x, 1.30) ; graphBoxFreeMenu (box, (FreeMenuFunction) nextChooser, nextMenu) ; cp = freekey2text (look->next, nextMenu) ; graphText (cp, x + 8.5, 1.32) ; } else { if (look->select) graphButton ("Unselect", unselectButton, x, 1.30) ; else graphButton ("Select", selectButton, x, 1.30) ; } if (look->hideDots & 0x1) graphButton ("Show dots", hideDotsButton, x + 10, 1.30) ; else graphButton ("Hide dots", hideDotsButton, x + 10, 1.30) ; switch (look->hideUp) { case HIDE_UP: graphText ("and Hide Up traces", x + 25, .2) ; break ; case HIDE_DOWN: graphText ("and Hide Down traces", x + 25, .2) ; break ; } graphRedraw() ; } static void traceHisto (void) { if (histoTrace0 && arrayMax(histoTrace0)) plotHisto ("Distribution des traces", histoTrace0) ; if (histoTrace1 && arrayMax(histoTrace1)) plotHisto ("Distribution des derivees premieres", histoTrace1) ; if (histoTrace2 && arrayMax(histoTrace2)) plotHisto ("Distribution des derivees secondes", histoTrace2) ; if (histoTrace3 && arrayMax(histoTrace3)) plotHisto ("Distribution des derivees troisiemes", histoTrace3) ; if (histoTrace4 && arrayMax(histoTrace4)) plotHisto ("Distribution des derivees quatriemes", histoTrace4) ; histoTrace0 = 0 ; /* destroys in plot */ histoTrace1 = 0 ; /* destroys in plot */ histoTrace2 = 0 ; /* destroys in plot */ histoTrace3 = 0 ; /* destroys in plot */ histoTrace4 = 0 ; /* destroys in plot */ } /************** little function to act as a callback ***********/ static void drawVoid (void) { TRACELOOKGET("drawVoid") ; traceDraw (look) ; pickRememberDisplaySize ("DtMultiTrace") ; } /*****************************************************************/ /*********************************************************/ /*********************************************************/ /* needed after some of the edition operations in fmaptrace */ void traceGraphDestroy (void) { Graph old = graphActive() ; if (graphActivate (traceGraph)) graphDestroy () ; graphActivate (old) ; } BOOL multiTraceDisplay (KEY key, KEY from, BOOL isOldGraph, void *unused) { KEYSET ks ; Array linkDna = 0 ; LOOK look ; KEY dnaKey, linkKey ; Graph fMapGraph ; int sens, p1, p2 ; OBJ Link = 0 ; FeatureMap fLook = 0 ; fMapActive(&linkDna, 0, &linkKey, &fLook) ; fMapGraph = fMapActiveGraph () ; ks = queryKey(key, "{ >Assembled_from} $| {>Aligned}") ; /*; SCF_File*/ if (!keySetMax(ks)) keySet(ks, 0) = key ; if (!traceLook) { traceLook = (LOOK) messalloc (sizeof(struct LookStruct)) ; traceLook->magic = &TRACELOOK_MAGIC ; } look = traceLook ; look->activeBox = 0 ; look->mode = acemblyMode ; if (bIndexTag (key, str2tag("Is_Reference"))) look->mode = MUTANT ; baseEditMenu = look->mode == CDNA ? &baseDoEditcDNAMenu[0] : &baseDoEditMenu[0]; showSelect = TRUE ; if (!graphActivate (traceGraph)) { traceGraph = look->graph = displayCreate ("DtMultiTrace") ; graphAssociate (&TRACELOOK_ASSOC, look) ; graphAssociate (&MAP2LOOK_ASSOC, look) ; look->box2seg = arrayCreate (64,int) ; #ifdef JUNK look->map = mapCreate2 (colInfo, drawVoid) ; static MapColRec2 colInfo[] = { { 1.1, TRUE, "Locator", mapShowLocator}, { 1.5, TRUE, "EditorCoor", traceEdCoords}, { 2.0, TRUE, "EditorConsensus", traceEdConsensus}, { 3.0, TRUE, "Editor", traceEds}, { 4.0, TRUE, "Gene", traceGene}, { 5.0, TRUE, "Scale", traceScale}, { 6.0, TRUE, "Consensus", traceConsensus}, { 7.0, TRUE, "Traces", tracePlotAllLanes}, { 0.0 , 0, 0, 0} /* terminator */ } ; #endif look->map = mapCreate (drawVoid) ; mapInsertCol (look->map,1.1, TRUE, "Locator", mapShowLocator) ; mapInsertCol (look->map,1.5, TRUE, "EditorCoor", traceEdCoords) ; mapInsertCol (look->map,2.0, TRUE, "EditorConsensus", traceEdConsensus) ; mapInsertCol (look->map,3.0, TRUE, "Editor", traceEds) ; mapInsertCol (look->map,4.0, TRUE, "Gene", traceGene) ; mapInsertCol (look->map,5.0, TRUE, "Scale", traceScale) ; mapInsertCol (look->map,6.0, TRUE, "Consensus", traceConsensus) ; mapInsertCol (look->map,7.0, TRUE, "Traces", tracePlotAllLanes) ; look->map->mag = lastMag ; look->next = NEXT_PROBLEM ; look->hide = SHOW_BEST_ERR ; look->hideUp = 0 ; showDefaultMode = SHOW_BEST_ERR ; graphRegister (RESIZE, drawVoid) ; graphRegister (DESTROY, traceDestroy) ; graphRegister (PICK, traceLeftDown) ; graphRegister (KEYBOARD, traceKbd) ; graphRegister (MIDDLE_DOWN, traceMiddleDown) ; graphHelp ("Trace_Editor") ; } look->map->min = 0 ; if (fLook) /* if i registered from fmap */ { look->fMapLook = fLook ; look->fMapGraph = fMapGraph ; look->link = linkKey ; } Link = bsCreate (look->link) ; if (Link && (bsFindKey (Link, _Subsequence, key) || bsFindKey (Link, _Transcribed_gene, key)) && bsGetData (Link, _bsRight, _Int, &p1) && bsGetData (Link, _bsRight, _Int, &p2)) sens = p2 - p1 ; else sens = 1 ; bsDestroy (Link) ; if (fMapcDNAReferenceDna || key != look->key || look->sens * sens < 0) { traceDoDestroy (look) ; look->key = key ; look->sens = sens ; look->hide = SHOW_BEST_ERR ; if (key != look->key || look->sens * sens < 0) look->hideUp = 0 ; look->next = NEXT_PROBLEM ; showDefaultMode = SHOW_BEST_ERR ; showChosenMode = SHOW_ALL ; if (fMapcDNAReferenceDna) { sens = 1 ; look->dnaKey = 0 ; look->mode = CDNA ; baseEditMenu = &baseDoEditcDNAMenu[0]; look->dna = fMapcDNAReferenceDna ; look->hits = fMapcDNAReferenceHits ; look->gene = fMapcDNAReferenceGene ; look->origin = fMapcDNAReferenceOrigin ; fMapcDNAReferenceHits = 0 ; fMapcDNAReferenceDna = 0 ; /* now mine */ fMapcDNAReferenceGene = 0 ; fMapcDNAReferenceOrigin = 0 ; look->hide = SHOW_BEST_ERR ; look->hideUp = 0 ; look->next = NEXT_ERROR ; showDefaultMode = SHOW_BEST_ERR ; showChosenMode = SHOW_ALL ; } else if (!lexReClass (look->key, &dnaKey, _VDNA) || !(look->dnaKey = dnaKey) || !(look->dna = dnaGet(dnaKey))) { look->dnaKey = 0 ; /* never edit somebody else dna */ if (!(look->dna = dnaGet (look->key))) /* try to construct the dna */ { messout ("no refernce dna") ; graphDestroy () ; return FALSE ; } } look->dnaR = arrayCopy (look->dna) ; if (sens > 0) reverseComplement (look->dnaR) ; else /* contig a l'envers dans le link */ reverseComplement (look->dna) ; look->map->max = arrayMax (look->dna) ; look->wmin = 0 ; look->wmax = look->map->max ; traceMakeGene (look, sens) ; if (look->hits) traceMakeHitLanes (look, sens) ; else traceMakeLanes (look, sens) ; look->hideDots = 0 ; } graphRetitle (messprintf("Traces: %s", name(key))) ; look->map->centre = from + look->origin ; if (fMapcDNAReferenceEst) { LANE *lane ; int i = arrayMax(look->lanes) ; while (i--) { lane = arrp(look->lanes, i, LANE) ; if (lane->key == fMapcDNAReferenceEst) { look->activeLane = lane ; break ; } } } traceDraw (look) ; return TRUE ; } /*********************************************************/ /*********************************************************/ /* Adapt precisely by sliding an heptamer */ static BOOL fineTuneDx1(Array dna, LANE *lane, int u0, int *zp) { char *cp, *cp0 ; Array bc = lane->baseCall ; int dy, s, j0, x0 = *zp, max = arrayMax(bc), bestdy, delta = 2, delta1 = 2, /* align on 5-mers */ i, n ; BOOL up = lane->upSequence ; BASECALL *bb, *bb0, *bestbb ; char mybase[] = { A_, G_, C_, T_ } ; if (u0 < 0 || u0 >= arrayMax(dna)) return FALSE ; cp0 = arrp(dna, u0, char) ; s = -10 ; bestdy = 0 ; /* search for the last base left of x0 */ j0 = 0 ; bb0 = arrp (bc, j0, BASECALL) ; while (j0 < max && bb0->x < x0) { j0 += 20 ; bb0 += 20 ; } if (j0 > 0) { bb0 -= 20 ; j0 -= 20 ; } while (j0 < max && bb0->x < x0) { j0 ++ ; bb0++ ;} if (j0 > 0) { bb0-- ; j0-- ;} bestbb = bb0 ; if (!up) { i = bb0 - arrp (bc, 0, BASECALL) ; if (i < delta + delta1 || i + delta + delta1 >= max) return FALSE ; dy = 0 ; /* hope fineTuneDx did a good job */ { cp = cp0 - delta1 ; bb = bb0 - delta1 + dy ; i = 2*delta1 + 1 ; n = 0 ; while (i--) if (mybase[(int)((bb++)->t)] == *cp++) n++ ; if (n > s) { s = n ; bestbb = bb0 + dy ; } } if (s < 2*delta1 + 1) for (dy = -delta ; dy < delta ; dy++) { cp = cp0 - delta1 ; bb = bb0 - delta1 + dy ; i = 2*delta1 + 1 ; n = 0 ; while (i--) if (mybase[(int)((bb++)->t)] == *cp++) n++ ; if (n > s) { s = n ; bestbb = bb0 + dy ; } } } else { i = bb0 - arrp (bc, 0, BASECALL) ; if (i < delta + delta1 || i + delta + delta1 >= max) return FALSE ; dy = 0 ; { cp = cp0 + delta1 ; bb = bb0 - delta1 + dy ; i = 2*delta1 + 1 ; n = 0 ; while (i--) if (mybase[(int)3 - (bb++)->t] == *cp--) n++ ; if (n > s) { s = n ; bestbb = bb0 + dy ; } } if (s < 2*delta1 + 1) for (dy = -delta ; dy < delta ; dy++) { cp = cp0 + delta1 ; bb = bb0 - delta1 + dy ; i = 2*delta1 + 1 ; n = 0 ; while (i--) if (mybase[(int)3 - (bb++)->t] == *cp--) n++ ; if (n > s) { s = n ; bestbb = bb0 + dy ; } } } if (s >= 2*delta1) /* one error only */ *zp = bestbb->x ; else *zp = bb0->x ; *zp += up ? +1 : +1 ; return TRUE ; } /**********/ static int fineTuneDx(LOOK look, LANE *lane, int u0, int *zp) { A_ERR *ep ; Array dna = look->dna ; int x0, di = 0, n ; int x1 = lane->x1, x2 = lane->x2 , x3 = lane->x3 ; if (!look->showClip) x3 = x2 ; if (!lane->upSequence && (x3 < u0 || x1 >= u0)) return FALSE ; if (lane->upSequence && (x1 < u0 || x3 >= u0)) return FALSE ; if (!lane->errArray) /* happens after a fix */ laneMakeErrArray (look, lane) ; n = arrayMax (lane->errArray) ; #ifdef JUNK BASECALL *xp ; /* in case of perfect match, verify that the whole base call is not shifted */ if (!n || arrp(lane->errArray, 0, A_ERR)->iLong > u0 ) /* perfect match */ { if (!lane->upSequence) x0 = u0 - lane->x1 + lane->clipTop ; else x0 = - u0 + lane->x2 + lane->clipEnd ; if (x0 < 200 && x0 > 100 && /* verifier l'alignement global des basecall */ lane->baseCall && arrayMax(lane->baseCall)) { int min = x0 - 20, max = x0 + 20, max = x0 + 20, delta[] = {0,1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,9,-9,10,-10} ; xp = arrp(lane->baseCall, 0, BASECALL) ; i = arrayMax(lane->baseCall) ; while(xp->x < min && i) xp++ , i-- ; while(i && xp->x < max) { if (xp->t == k) { y = MAP2GRAPH(map, xp->x + 1) ; if (xp->flag & BC_LOW) ; } xp++ ; i-- ; } k1 = lane->upSequence ? 3 - k : k ; } } #endif /* align using the edited data */ if (!n || arrp(lane->errArray, 0, A_ERR)->iLong > u0 + 30) /* perfect match */ { if (!lane->upSequence) x0 = u0 - lane->x1 + lane->clipTop ; else x0 = - u0 + lane->x2 + lane->clipEnd ; } else { ep = arrp(lane->errArray, 0, A_ERR) ; if (n-- > 1 && ep->iLong < u0) { while (ep++, n--) if (ep->iLong > u0) break ; if (ep > arrp(lane->errArray, 0, A_ERR)) ep-- ; /* last correct error, <= u0 */ else { if (!lane->upSequence) x0 = u0 - lane->x1 + lane->clipTop ; else x0 = - u0 + lane->x2 + lane->clipEnd ; goto ok ; } } if (ep->iLong != u0) switch (ep->type) { case TROU: di = -1 ; break ; case TROU_DOUBLE: di = -2 ; break ; case INSERTION : /*_AVANT: */ di = 1 ; break ; case INSERTION_DOUBLE: /* _AVANT: */ di = 2 ; break ; default: break ; } if (!lane->upSequence) x0 = di + u0 - ep->iLong + ep->iShort ; else x0 = - di + ep->iLong - u0 + ep->iShort ; } ok: if (lane->scf >= 3) { if (x0 < 0 || !lane->basePos || x0 >= arrayMax(lane->basePos)) return FALSE ; *zp = arr (lane->basePos, x0, short) ; /* now adapt to the unedited sequence */ if (lane->baseCall && !lane->hide) fineTuneDx1 (dna, lane, u0, zp) ; } return TRUE ; } /***********/ static void selectBestLane(LOOK look, LANE **lane1p) { int i = arrayMax (look->lanes), nn = arrayMax (look->dna) ; LANE *lane = arrp (look->lanes, 0, LANE) - 1 ; while (lane++, i--) if (lane->scf >=3 && lane->nerr >= 0 && lane->nerr < nn) { nn = lane->nerr ; *lane1p = lane ; } if (!fineTune (look, lane1p, *lane1p)) *lane1p = (LANE *)1 ; } static BOOL fineTuneTrace (LOOK look, LANE **lane1p, LANE *lane, int x0, int u0, int u1, int u2) { int dx ; LANE *lane1 ; BOOL direct ; if (!*lane1p) selectBestLane(look, lane1p) ; lane1 = *lane1p ; if (lane1 < (LANE *)2) return FALSE ; direct = (lane->upSequence == (*lane1p)->upSequence ? TRUE : FALSE ) ; if (lane1->seq && lane->seq && baseCorrel (lane1->seq, lane1->t1, direct, lane->seq, x0, lane1->t2, 80, 1, &dx)) { lane->ddy = lane1->ddy * (direct ? 1 : -1) ; lane->dy = look->map->centre - (x0 + dx) ; return TRUE ; /* ulrich */ } else return FALSE ; } /***********/ static BOOL fineTune (LOOK look, LANE **lane1p, LANE *lane) { int x0 = -100000, x1, x2, x01, x02, ww = look->wmax - look->wmin, u1 = look->wmin + 1 , u01 = look->wmin + ww/4, u2 = look->wmax - 1, u02 = look->wmax - ww/4, u0 = look->map->centre ; BOOL r0, r1, r2, r01, r02 ; if (u1 + 5 > u2) return FALSE ; CHECKSEQ ; CHECKPOS ; if (lane->isAligned || lane->scf < 3) return FALSE ; r0 = fineTuneDx(look, lane, u0, &x0) ; if (r0 && lane->nerr > 3 && /* difficult case */ *lane1p != (LANE *)1 && /* bestlane did not fine tune */ *lane1p != lane && fineTuneTrace (look, lane1p, lane, x0, u0, u1, u2)) /* align lane against *lane1p */ return TRUE ; x1 = x2 = x0 ; r1 = fineTuneDx(look, lane, u1, &x1) ; r2 = fineTuneDx(look, lane, u2, &x2) ; if (!r0) { return FALSE ; /* BUG, j'arrive pas a centre */ r01 = r02 = FALSE ; if (r1) r01 = fineTuneDx(look, lane, u01, &x01) ; else if (r2) r02 = fineTuneDx(look, lane, u02, &x02) ; if (!r01 && !r02) return FALSE ; else if (r01) x0 = x1 + (x01 - x1) * (u0 - u1)/(u01 - u1) ; else if (r02) x0 = x2 - (x2 - x02) * (u2 - u0)/(u2 - u02) ; } lane->t1 = x0 ; lane->t2 = x2 > x1 ? x2 - x1 : x1 - x2 ; if (r0 && r1 && r2) { if (x2 == x1) return FALSE ; lane->ddy = (u2 - u1) / ((float)(x2 - x1)) ; } else if (r0 && r1) { if (x0 == x1) return FALSE ; lane->ddy = (u0 - u1) / ((float)(x0 - x1)) ; u2 = 2*u0 - u1 ; } else if (r0 && r2) { if (x0 == x2) return FALSE ; lane->ddy = (u0 - u2) / ((float)(x0 - x2)) ; u1 = 2*u0 - u2 ; } else return FALSE ; lane->dy = look->map->centre - x0 ; return TRUE ; } /***********/ static void newFixButton (void) { extern BOOL fMapcDNAPickTrace (KEY gene, KEY est, int from); int z1, z2, dz, zmax, x ; KEY gene = 0, newGene ; KEYSET selKs = 0 ; void* fMapLook = 0 ; Graph fMapGraph = 0, traceGraph = 0 ; TRACELOOKGET("newFixButton") ; traceGraph = look->graph ; switch (look->mode) { case 0: break ; case CDNA: selKs = look->selectedKs ; look->selectedKs = 0 ; newGene = cDNARealignGene (look->gene, 0, 0) ; if (look->fMapLook) { Graph old = graphActive () ; fMapPleaseRecompute (fMapLook = look->fMapLook) ; tracePick (look->map->thumb.box, MAP2GRAPH (look->map, look->map->centre), 0) ; gene = look->gene ; fMapGraph = look->fMapGraph ; x = look->map->centre - look->origin ; if (graphActivate (old)) { /* graphDestroy () ; */ traceDoDestroy (look) ; /* destroys look */ graphClear () ; } if (graphActivate (fMapGraph)) { fMapcDNAPickTrace (gene, 0, x) ; if (graphActivate (old)) /* graphPop () pop in 'g' case in traceKbd */; } else if (graphActivate (old)) graphDestroy () ; /* trace graph needed to reconstruct fixed gene */ } if (newGene != gene) /* gene changed name, coords are lost */ graphDestroy () ; if (selKs && graphActivate (traceGraph) && graphAssFind (&TRACELOOK_ASSOC, &look)) { look->selectedKs = selKs ; selKs = 0 ; traceDraw (look) ; } keySetDestroy (selKs) ; return ; case MUTANT: break ; default: messout("In the current mode, you cannot edit the consensus") ; return ; } if (arrayMax(look->lanes) == 1) /* single read, then redraw all */ { multiTraceDisplay (look->key, 0, TRUE) ; return ;} dz = (look->wmax - look->wmin)/2 ; zmax = arrayMax (look->dna) ; z1 = look->wmin - dz ; if (z1 < 0) z1 = 0 ; z2 = look->wmax + dz ; if (z2 > zmax ) z2 = zmax ; trackContig (look, z1, z2, FALSE) ; updateConsensus (look) ; traceDraw (look) ; } /***********/ static void newBigFixButton (void) { int zmax ; TRACELOOKGET("newFixButton") ; if (look->mode) { messout("In the current, you cannot edit the consensus") ; return ; } if (arrayMax(look->lanes) == 1) /* single read, then redraw all */ { multiTraceDisplay (look->key, 0, TRUE) ; return ;} zmax = arrayMax (look->dna) ; trackContig (look, 0, zmax, TRUE) ; updateConsensus (look) ; traceDraw (look) ; /* traceRealignAll () ; traceRealignAll () ; */ } /***********/ static BOOL isProblem (LOOK look, LANE *ln1, int z, BOOL down) { int i, j, k, y, u1, u2 ; LANE *lane ; A_ERR *ep ; BOOL upClip = FALSE, downClip = FALSE ; static Array a, aUp = 0, aDown = 0 ; int nLanesUp = 0, nLanesDown = 0 ; int nVoisins = 0, nExactUp = 0, nExactDown = 0; /* comptons les sequences up et down couvrant la region */ aUp = arrayReCreate (aUp, 12, LANE*) ; aDown = arrayReCreate (aDown, 12, LANE*) ; i = arrayMax(look->lanes) ; lane = arrp (look->lanes, 0, LANE) - 1 ; while (lane++, i--) { if (lane->upSequence) { u1 = lane->x2 ; u2 = lane->x1 ; } else { u1 = lane->x1 ; u2 = lane->x2 ; } if (u1 > z || u2 < z) continue ; CHECKLANE ; if (lane->scf < 2) continue ; if (lane->x2 == z) { if (look->next == NEXT_CLIP) return TRUE ; if (lane->upSequence) upClip = TRUE ; else downClip = TRUE ; } if (lane->upSequence) array (aUp, nLanesUp++, LANE*) = lane ; else array (aDown, nLanesDown++, LANE*) = lane ; } if (look->next == NEXT_HOLE) { if ( (upClip && nLanesUp < 3) || (downClip && nLanesDown < 3) ) return TRUE ; else return FALSE ; } if ((ln1->upSequence && nLanesUp < 3) || (!ln1->upSequence && nLanesDown < 3)) return TRUE ; k = nLanesDown ; while (k--) { lane = arr (aDown, k, LANE*) ; a = lane->errArray ; j = arrayMax(a) ; if (!j) continue ; ep = arrp(lane->errArray, 0, A_ERR) - 1 ; while(ep++, j--) { y = ep->iLong ; if (y > z - 3 && y < z + 3) nVoisins++ ; if (y > z + 3) break ; if (y == z) nExactDown++ ; } } k = nLanesUp ; while (k--) { lane = arr (aUp, k, LANE*) ; a = lane->errArray ; j = arrayMax(a) ; if (!j) continue ; ep = arrp(lane->errArray, 0, A_ERR) - 1 ; while(ep++, j--) { y = ep->iLong ; if (y > z - 3 && y < z + 3) nVoisins++ ; if (y > z + 3) break ; if (y == z) nExactUp++ ; } } if (nLanesUp < 2*nExactUp || nLanesDown < 2*nExactDown || (nLanesUp + nLanesDown) < 3*(nExactUp + nExactDown) || 2 * nVoisins > 3 *(nLanesUp + nLanesDown)) { if (nLanesUp > 5 && nLanesUp - nExactUp > 2 && nLanesDown > 5 && nLanesDown - nExactDown > 2) return FALSE ; return TRUE ; } else return FALSE ; } /***************************************************************/ static int nextError (LOOK look, BOOL down) { int i, j, i1, x = look->map->centre, y, ys, z, z0, top, end, u1, u2, minTop, maxEnd ; LANE *lane, *ln1 = 0 ; A_ERR *ep ; KEY key ; Array a ; int dlane = down ? 1 : -1 , isEnd = 0 ; int nextType = look->next ; minTop = 0 ; maxEnd = arrayMax (look->dna) ; look->hide = showDefaultMode ; x += down ? 3 : -3 ; encore: z = z0 = x + (down ? 2 * arrayMax(look->dna) : - arrayMax(look->dna)) ; i = arrayMax(look->lanes) ; lane = down ? arrp (look->lanes, 0, LANE) - 1 : arrp (look->lanes, arrayMax(look->lanes) - 1, LANE) + 1 ; while (lane += dlane, i--) { if ((nextType == NEXT_COMPARE) ^ lane->isAligned) continue ; switch (look->hideUp) { case HIDE_UP: if (lane->upSequence) continue ; break ; case HIDE_DOWN: if (!lane->upSequence) continue ; break ; } if (lane->upSequence) { u1 = lane->x2 ; u2 = lane->x1 ; } else { u1 = lane->x1 ; u2 = lane->x2 ; } if (u1 < minTop) minTop = u1 ; if (u2 > maxEnd) maxEnd = u2 ; if ((down && (u1 >= z || u2 <= x)) || (!down && (u1 >= x || u2 <= z))) continue ; if (look->mode == CDNA || nextType == NEXT_CLIP || nextType == NEXT_HOLE) { if ( (down && x < lane->x2 && z > lane->x2 ) || (!down && x > lane->x2 && z < lane->x2 )) { CHECKLANE ; if (lane->dna && lane->clipEnd < arrayMax(lane->dna) - 5) { BOOL forget = FALSE ; int nl = arrayMax(look->lanes) ; LANE *ll = arrp(look->lanes, 0, LANE) - 1 ; while (ll++, nl--) if (ll->key != lane->key && ll->clone && ll->clone == lane->clone && ((lane->upSequence && !ll->upSequence && lane->x2 < ll->x2) || (!lane->upSequence && ll->upSequence && lane->x2 > ll->x2) )) { forget = TRUE ; break ; } if (!forget) { ln1 = lane ; z = lane->x2 ; isEnd = lane->upSequence ? -2 : 2 ; } } } } if (look->mode == CDNA) { if ( !lane->upSequence && ( (down && x < lane->x1 && z > lane->x1 ) || (!down && x > lane->x1 && z < lane->x1 )) ) { CHECKLANE ; if (lane->clipTop > lane->vectorTop || ( (down && i == arrayMax(look->lanes) - 1 ) || (!down && i == 0) )) { ln1 = lane ; z = lane->x1 ; isEnd = lane->upSequence ? +2 : -2 ; } } if ( lane->upSequence && ( (down && x < lane->x1 && z > lane->x1 ) || (!down && x > lane->x1 && z < lane->x1 )) ) { CHECKLANE ; if (lane->clipTop > lane->vectorTop || ( (!down && i == arrayMax(look->lanes) - 1 ) || (down && i == 0) )) { ln1 = lane ; z = lane->x1 ; isEnd = lane->upSequence ? +2 : -2 ; } } } if (nextType == NEXT_CLIP || nextType == NEXT_HOLE) continue ; if (nextType == NEXT_TAG) { if ( (down && x < lane->x2 && z > lane->x2 ) || (!down && x > lane->x2 && z < lane->x2 )) { CHECKLANE ; if (lane->hasTag != 1 && traceMakeLaneTags(lane)) { Array units = lane->tags ; BSunit *u ; for (i1 = 0 ; i1 < arrayMax (units) ; i1 += 4) { u = arrp(units, i1, BSunit) ; y = (u[1].i + u[2].i) / 2 ; if (lane->upSequence) y = lane->x1 - y + lane->clipTop ; else y = lane->x1 + y - lane->clipTop ; if ( (down && y > x && y < z) || (!down && y < x && y > z)) { ln1 = lane ; z = y ; } } } } continue ; } key = lane->clone ? lane->clone : lane->key ; if (look->select && keySetExists(look->selectedKs) && !keySetFind (look->selectedKs, key,0)) continue ; /* next difference */ CHECKLANE ; CHECKSEQ ; CHECKPOS ; if (lane->scf < 3 || !lane->base) /* data is lacking */ continue ; a = lane->errArray ; j = arrayMax(a) ; if (!j) continue ; top = lane->clipTop ; end = lane->clipEnd ; ep = arrp(lane->errArray, 0, A_ERR) - 1 ; while(ep++, j--) { if (look->mode == CDNA && ep->type == AMBIGUE && (BC_HAND & arr (lane->base, ep->iShort, char)) ) continue ; y = ep->iLong ; if (down) { if (y > x) { ys = ep->iShort ; if (y < z && ys >= top && ys < end) { ln1 = lane ; z = y ; } if (y >= z) break ; } } else { if (y >= x) break ; if (y > z && (ys = ep->iShort) && ys >= top && ys < end) { ln1 = lane ; z = y ; } } } } if (z == z0) { if (ln1) ln1->hide = FALSE ; return down ? maxEnd - 2 : minTop + 2 ; } x = z ; switch (look->next) { case NEXT_PROBLEM: /* ATTENTION general fall thru */ case NEXT_HOLE: if (!isProblem(look, ln1, z, down)) goto encore ; case NEXT_CLIP: case NEXT_ERROR: if (!baseCallGetSeq (ln1)) goto encore ; case NEXT_COMPARE: case NEXT_TAG: break ; } if (ln1) ln1->hide = FALSE ; return z - 1 * isEnd ; } /***************************************************************/ /* dragging */ /*************************************************/ /************* middle button for thumb **********/ static double oldx, oldy, oldDy, xOrigin, yOrigin ; static double dfx1, dfx2, dfy1, dfy2 ; /* static int dragFast = -1, dragBox = 0 ; declared at top of file */ static void traceMiddleDrag (double x, double y) { MAP map ; TRACELOOKGET("traceMiddleDrag") ; map = look->map ; switch (dragFast) { case 0: graphXorLine (map->thumb.x, oldy, look->graphWidth, oldy) ; /* register zone edit in mid button if (x > xOrigin + 3 || x < xOrigin - 3) dragFast = 2 ; */ break ; case 1: graphXorLine (0, oldy - oldDy, map->thumb.x, oldy - oldDy) ; graphXorLine (0, oldy + oldDy, map->thumb.x, oldy + oldDy) ; break ; case 2: graphXorLine (dfx1, dfy1, dfx1, dfy2) ; graphXorLine (dfx1, dfy1, dfx2, dfy1) ; graphXorLine (dfx2, dfy1, dfx2, dfy2) ; graphXorLine (dfx1, dfy2, dfx2, dfy2) ; break ; } oldy = y ; switch (dragFast) { case 0: graphXorLine (map->thumb.x, y, look->graphWidth, y) ; break ; case 1: oldDy *= exp ((x - oldx) / 25.) ; oldx = x ; graphXorLine (0, y - oldDy, map->thumb.x, y - oldDy) ; graphXorLine (0, y + oldDy, map->thumb.x, y + oldDy) ; break ; case 2: if (x > xOrigin) { dfx1 = xOrigin ; dfx2 = x ; } else { dfx2 = xOrigin ; dfx1 = x ; } if (y > yOrigin) { dfy1 = yOrigin ; dfy2 = y ; } else { dfy2 = yOrigin ; dfy1 = y ; } graphXorLine (dfx1, dfy1, dfx1, dfy2) ; graphXorLine (dfx1, dfy1, dfx2, dfy1) ; graphXorLine (dfx2, dfy1, dfx2, dfy2) ; graphXorLine (dfx1, dfy2, dfx2, dfy2) ; break ; } } static void traceMiddleUp (double x, double y) { float x1,x2,y1,y2 ; MAP map ; LANE *lane ; int i ; BOOL doDraw = FALSE ; TRACELOOKGET("traceMiddleUp") ; map = look->map ; switch (dragFast) { case 0: if (y - yOrigin > 2) map->centre = nextError (look, TRUE) ; else if (y - yOrigin < -2) map->centre = nextError (look, FALSE) ; else map->centre = GRAPH2MAP(map,y) ; doDraw = TRUE ; break ; case 1: graphBoxDim (map->thumb.box, &x1, &y1, &x2, &y2) ; map->mag *= (y2 - y1) / (2. * oldDy) ; map->centre = WHOLE2MAP(map, y) ; doDraw = TRUE ; break ; case 2: i = arrayMax(look->lanes) ; while (i--) { lane = arrp (look->lanes, i, LANE) ; if (!lane->isShown) continue ; if (dfx1 < lane->laneBaseCallBoxOffSet - .1 && dfx2 > lane->laneBaseCallBoxOffSet + 1.2) { doDraw = TRUE ; doAcceptZoneEdits (TRUE, FALSE,FALSE, lane, dfy1, dfy2) ; } } if (doDraw) traceDraw(look) ; break ; } dragBox = 0 ; dragFast = -1 ; (map->draw) () ; } static void traceMiddleDown (double x, double y) { float x1,x2,y1,y2 ; MAP map ; TRACELOOKGET("traceMiddleDown") ; map = look->map ; if (map->thumb.box) graphBoxDim (map->thumb.box, &x1, &y1, &x2, &y2) ; oldDy = (y2 - y1) / 2. ; dragFast = (x < map->thumb.x) || x < genex ? 1 : 0 ; if (dragFast) { if (genex) map->thumb.x = genex ; graphXorLine (0, y - oldDy, map->thumb.x, y - oldDy) ; graphXorLine (0, y + oldDy, map->thumb.x, y + oldDy) ; } else { graphXorLine (map->thumb.x, y, look->graphWidth, y) ; } oldx = xOrigin = x ; oldy = yOrigin = y ; graphRegister (MIDDLE_DRAG, traceMiddleDrag) ; /* must redo */ graphRegister (MIDDLE_UP, traceMiddleUp) ; } /****************************************************/ /************* left button for thumb **********/ static void traceLeftDrag (double x, double y) { MAP map ; TRACELOOKGET("traceLeftDrag") ; map = look->map ; switch (dragFast) { case 0: break ; case 1: graphXorLine (dfx1, dfy1, dfx1, dfy2) ; graphXorLine (dfx1, dfy1, dfx2, dfy1) ; graphXorLine (dfx2, dfy1, dfx2, dfy2) ; graphXorLine (dfx1, dfy2, dfx2, dfy2) ; break ; default: return ; } if (x > xOrigin) { dfx1 = xOrigin ; dfx2 = x ; } else { dfx2 = xOrigin ; dfx1 = x ; } if (y > yOrigin) { dfy1 = yOrigin ; dfy2 = y ; } else { dfy2 = yOrigin ; dfy1 = y ; } if (dfx2 > dfx1 + 1 || dfy2 > dfy1 + 1) dragFast = 1 ; switch (dragFast) { case 0: break ; case 1: graphXorLine (dfx1, dfy1, dfx1, dfy2) ; graphXorLine (dfx1, dfy1, dfx2, dfy1) ; graphXorLine (dfx2, dfy1, dfx2, dfy2) ; graphXorLine (dfx1, dfy2, dfx2, dfy2) ; break ; } } static void traceLeftUp (double x, double y) { float x1,x2,y1,y2 ; LANE *lane ; int i ; BOOL doDraw = FALSE ; TRACELOOKGET("traceLeftUp") ; switch (dragFast) { case 0: graphBoxDim (dragBox, &x1, &y1, &x2, &y2) ; tracePick (dragBox, xOrigin - x1, yOrigin - y1) ; dragBox = 0 ; /* doDraw = TRUE ; */ break ; case 1: graphXorLine (dfx1, dfy1, dfx1, dfy2) ; graphXorLine (dfx1, dfy1, dfx2, dfy1) ; graphXorLine (dfx2, dfy1, dfx2, dfy2) ; graphXorLine (dfx1, dfy2, dfx2, dfy2) ; i = arrayMax(look->lanes) ; while (i--) { lane = arrp (look->lanes, i, LANE) ; if (!lane->isShown) continue ; if (dfx1 < lane->laneBaseCallBoxOffSet - .1 && dfx2 > lane->laneBaseCallBoxOffSet + 1.2) { doDraw = TRUE ; doAcceptZoneEdits (TRUE, FALSE,FALSE, lane, dfy1, dfy2) ; } } if (doDraw) traceDraw(look) ; dragBox = 0 ; break ; } dragFast = -1 ; } static void traceLeftDown (int box, double xx, double yy, int modifier_unused) { float x1,x2,y1,y2 ; double x, y ; TRACELOOKGET("traceLeftDown") ; dragBox = box ; graphBoxDim (box, &x1, &y1, &x2, &y2) ; x = xx + x1 ; y = yy + y1 ; oldx = xOrigin = x ; oldy = yOrigin = y ; dragFast = 0 ; graphRegister (LEFT_DRAG, traceLeftDrag) ; /* must redo */ graphRegister (LEFT_UP, traceLeftUp) ; } /****************************************************/ LANE *tagLane = 0 ; /****************************************************/ static void laneDoTag (LOOK look, LANE *lane, KEY key, char *buf) { int x1, x2 ; OBJ obj = 0 ; char *myTag = freekey2text (key, traceTagMenu) ; lane->hasTag = 0 ; /* force reevaluation */ if (!lane->upSequence) x1 = look->map->centre - lane->x1 + lane->clipTop + 1 ; else x1 = - look->map->centre + lane->x1 + lane->clipTop ; x1 -= 10 ; x2 = x1 + 20 ; if ((obj = bsUpdate (lane->key))) { bsAddData (obj, _Assembly_tags, _Text, myTag) ; bsAddData (obj, _bsRight, _Int, &x1) ; bsAddData (obj, _bsRight, _Int, &x2) ; if (buf) bsAddData (obj, _bsRight, _Text, buf) ; bsSave (obj) ; } } /****************************************************/ #ifdef APPARENTLY_NOT_NEEDED static void traceTagger (KEY key) { LANE *lane ; int i ; char *cp ; TRACELOOKGET("traceTagger") ; i = arrayExists(look->laneShown) ? arrayMax (look->laneShown) : 0 ; if (!i) return ; if (!messPrompt ("Comments ?:", "", "t")) return ; cp = freeword () ; while (i--) { lane = arr (look->laneShown, i, LANE*) ; if (!lane->isAligned) laneDoTag (look, lane, key, cp) ; } traceDraw (look) ; } #endif /* APPARENTLY_NOT_NEEDED */ /****************************************************/ #ifdef OLDJUNK static int tagBegin = -1 ; static void traceDoAddTag (KEY key, int box) { HINT* hh ; MAP map ; LANE *lane ; int min, max, tagEnd ; float mag, offSet ; OBJ obj ; TRACELOOKGET("traceDoAddTag") ; if (key == 1) return ; if (box < arrayMax(look->baseBoxes) && (hh = arrp(look->baseBoxes,box, HINT))) { tagEnd = hh->iShort ; if (tagBegin > tagEnd) { min = tagEnd ; tagEnd = tagBegin ; tagBegin = min ; } if (tagBegin > 0 && tagLane == hh->lane && (obj = bsUpdate(hh->lane->key))) { if (bsAddData (obj, key, _Int, &tagBegin)) bsAddData (obj, _bsRight, _Int, &tagEnd) ; bsSave (obj) ; } /* reregister the menu */ tagLane = 0 ; tagBegin = -1 ; lane = hh->lane ; graphBoxClear (lane->laneBaseCallBox) ; map = look->map ; map->centre -= lane->dy ; mag = map->mag ; map->mag *= lane->ddy ; lane->laneBaseCallBox = graphBoxStart () ; offSet = lane->laneBaseCallBoxOffSet ; min = lane->laneBaseCallBoxMin ; max = lane->laneBaseCallBoxMax ; traceDnaLane (look, look->map, lane, &offSet, min, max) ; graphBoxEnd () ; map->centre += lane->dy ; map->mag = mag ; graphBoxDraw (lane->laneBaseCallBox, -1, -1) ; } } /****************************************************/ static void traceAddTag (LOOK look, LANE *lane, int nn) { FREEOPT *fp ; MAP map = look->map ; int min, max ; float mag, offSet ; OBJ obj ; Array aa ; KEY model, tag ; int i, j ; tagBegin = nn ; tagLane = lane ; #if !defined(NEW_MODELS) model = KEYMAKE (_VSequence, 0) ; #else model = pickList[_VSequence].model ; #endif if (!traceAddTagMenu) { traceAddTagMenu = arrayCreate(20, FREEOPT) ; obj = bsCreate (model) ; j = 0 ; aa = arrayCreate(12, BSunit) ; if (obj) { if (bsFindTag (obj, _Ace_mbly_tags) && bsFlatten (obj, 2, aa)) for (i = 1 ; i < arrayMax(aa) ; i+= 2) { tag = arr(aa, i, BSunit).k ; fp = arrayp(traceAddTagMenu,++j,FREEOPT) ; fp->key = tag ; fp->text = name(tag) ; } while (bsGetKeyTags (obj, _bsDown, &tag)) ; bsDestroy (obj) ; } arrayDestroy (aa) ; fp = arrayp(traceAddTagMenu,++j,FREEOPT) ; fp->key = 1 ; fp->text = "Cancel" ; fp = arrayp(traceAddTagMenu,0,FREEOPT) ; fp->key = j ; fp->text = "toto" ; if (!j) { arrayDestroy (traceAddTagMenu) ; return ; } } /* reregister the menu */ baseEditMenu = arrp(traceAddTagMenu, 0, FREEOPT) ; baseEdit = traceDoAddTag ; graphBoxClear (lane->laneBaseCallBox) ; map->centre -= lane->dy ; mag = map->mag ; map->mag *= lane->ddy ; lane->laneBaseCallBox = graphBoxStart () ; offSet = lane->laneBaseCallBoxOffSet ; min = lane->laneBaseCallBoxMin ; max = lane->laneBaseCallBoxMax ; traceDnaLane (look, look->map, lane, &offSet, min, max) ; graphBoxEnd () ; map->centre += lane->dy ; map->mag = mag ; graphBoxDraw (lane->laneBaseCallBox, -1, -1) ; baseEditMenu = look->mode == CDNA ? &baseDoEditcDNAMenu[0] : &baseDoEditMenu[0]; baseEdit = baseEdit1 ; } /****************************************************/ static FREEOPT *traceMakeAddTagMenu (void) { FREEOPT *fp ; OBJ obj ; Array aa ; KEY model, tag ; int i, j ; #if !defined(NEW_MODELS) model = KEYMAKE (_VSequence, 0) ; #else model = pickList[_VSequence].model ; #endif if (!traceAddTagMenu) { traceAddTagMenu = arrayCreate(20, FREEOPT) ; obj = bsCreate (model) ; j = 0 ; aa = arrayCreate(12, BSunit) ; if (obj) { if (bsFindTag (obj, _Ace_mbly_tags) && bsFlatten (obj, 2, aa)) for (i = 1 ; i < arrayMax(aa) ; i+= 2) { tag = arr(aa, i, BSunit).k ; fp = arrayp(traceAddTagMenu,++j,FREEOPT) ; fp->key = tag ; fp->text = name(tag) ; } while (bsGetKeyTags (obj, _bsDown, &tag)) ; bsDestroy (obj) ; } arrayDestroy (aa) ; fp = arrayp(traceAddTagMenu,++j,FREEOPT) ; fp->key = 1 ; fp->text = "Cancel" ; fp = arrayp(traceAddTagMenu,0,FREEOPT) ; fp->key = j ; fp->text = "toto" ; if (!j) { arrayDestroy (traceAddTagMenu) ; return ; } } /* reregister the menu */ return arrp(traceAddTagMenu, 0, FREEOPT) ; } #endif /****************************************************/ /****************************************************/ /***************** segs ***********************************/ static void laneShowExtrema(LOOK look, LANE *lane, float *offset, int min, int max) { int i , k, k1 ; float y, x1 = *offset + look->traceWidth, x2 = *offset, x3 = (x1 + x2) / 2 ; MAP map = look->map ; int box ; BASECALL *xp ; CHECKLANE ; if (lane->scf < 4) return ; if (! arrayExists(lane->baseCall) && ! findBaseCall (lane)) return ; if (! arrayMax(lane->baseCall)) return ; for (k=0 ; k<4 ; k++) { box = graphBoxStart() ; xp = arrp(lane->baseCall, 0, BASECALL) ; i = arrayMax(lane->baseCall) ; while(xp->x < min && i) xp++ , i-- ; while(i && xp->x < max) { if (xp->t == k) { y = MAP2GRAPH(map, xp->x + 1) ; if (xp->flag & BC_LOW) graphLine(x3, y, x2, y) ; else graphLine(x1, y, x2, y) ; } xp++ ; i-- ; } graphBoxEnd() ; k1 = lane->upSequence ? 3 - k : k ; graphBoxDraw(box, BASE_COLOR[k1], TRANSPARENT) ; } *offset += 0 ; /* Redraw en place */ } /***************************************************/ static void baseCallPatchButton (void) { int i ; LANE *lane ; TRACELOOKGET("patch") ; messStatus ("Autoedit") ; lane = arrp (look->lanes, 0, LANE) -1 ; i = arrayMax (look->lanes) ; while (lane++, i--) { if (!lane->isShown) continue ; CHECKLANE ; if (lane->scf < 2) continue ; if (findBaseCall(lane)) { findXclipping (lane) ; baseCallPatchLane (look->dna, look->dnaR, lane) ; findXclipping (lane) ; laneEditSave (look, lane, 0, 0) ; } } if (look->fMapLook) fMapPleaseRecompute (look->fMapLook) ; traceDraw (look) ; } /***************************************************/ static void traceRealignAll (void) { int i ; LANE *lane ; TRACELOOKGET("realign") ; messStatus ("Realigning") ; lane = arrp (look->lanes, 0, LANE) - 1 ; i = arrayMax (look->lanes) ; while (lane++, i--) { if (!lane->isShown && !lane->isAligned) continue ; CHECKLANE ; if (lane->scf < 2) continue ; lane->x2 += lane->upSequence ? +1 : -1 ; /* lane->clipEnd = arrayMax(lane->dna) ; */ dnaAlignRecale(look->dna, &(lane->x1), &(lane->x2), lane->dna, lane->clipTop, lane->clipEnd - 1) ; lane->x2 -= lane->upSequence ? +1 : -1 ; findXclipping (lane) ; laneEditSave (look, lane, 0, 0) ; } traceDraw (look) ; } #endif /* non graphic */ /***************************************************/ /***************************************************/