static void splitter_AddSubSeqFeat(AjPFeattable ftable, ajuint start, ajuint end, const AjPSeq oldseq) { AjPFeattable old_feattable = NULL; AjIList iter = NULL; old_feattable = ajSeqGetFeatCopy(oldseq); if(!old_feattable) return; iter = ajListIterNewread(old_feattable->Features); while(!ajListIterDone(iter)) { AjPFeature gf = ajListIterGet(iter); AjPFeature copy = NULL; if (((ajFeatGetEnd(gf) < start + 1) && (gf->End2 == 0 || gf->End2 < start + 1)) || ((ajFeatGetStart(gf) > end + 1) && (gf->Start2 == 0 || gf->Start2 > end + 1))) { continue; } copy = ajFeatNewFeat(gf); copy->Start = copy->Start - start; copy->End = copy->End - start; if (copy->Start2 > 0) copy->Start2 = copy->Start2 - start; if (copy->End2 > 0) copy->End2 = copy->End2 - start; ajFeatTrimOffRange (copy, 0, 1, end - start + 1, AJTRUE, AJTRUE); ajFeattableAdd(ftable, copy); } ajFeattableDel(&old_feattable); ajListIterDel(&iter); return; }
static void extractfeat_FeatSeqExtract(const AjPSeq seq, AjPSeqout seqout, AjPFeattable featab, ajint before, ajint after, AjBool join, AjBool featinname, const AjPStr describe) { AjIList iter = NULL; AjPFeature gf = NULL; AjBool single; /* ajtrue = is not a multiple */ AjBool parent; /* ajtrue = is a parent of a multiple */ AjBool child; /* ajTrue = is a child of a multiple */ AjBool compall; /* ajTrue = reverse comp all of join */ AjBool sense; /* ajTrue = forward sense */ AjBool remote; /* ajTrue = remote ID */ AjPStr type = NULL; /* name of feature */ AjPStr featseq = NULL; /* feature sequence string */ AjPStr tmpseq = NULL; /* temporary sequence string */ ajint firstpos; ajint lastpos; /* bounds of feature in sequence */ AjPStr describeout = NULL; /* tag names/values to add to descriptions */ ajuint count = 0; /* For all features... */ if(featab && ajFeattableGetSize(featab)) { /* initialise details of a feature */ featseq = ajStrNew(); tmpseq = ajStrNew(); type = ajStrNew(); remote = ajFalse; compall = ajFalse; sense = ajTrue; firstpos = 0; lastpos = 0; describeout = ajStrNew(); iter = ajListIterNewread(featab->Features); while(!ajListIterDone(iter)) { gf = ajListIterGet(iter) ; /* ** Determine what sort of thing this feature is. Only one of ** these will be true. ** True if this is part of a multiple join and it is not ** the parent */ child = ajFalse; /* True if this is part of a multiple join and it is the parent */ parent = ajFalse; /* True if this is not part of a multiple join */ single = ajFalse; if(ajFeatIsMultiple(gf)) { if(ajFeatIsChild(gf)) child = ajTrue; else parent = ajTrue; } else single = ajTrue; /* ** If not wish to assembling joins(), then force all features ** to be treated as single */ if(!join) { child = ajFalse; parent = ajFalse; single = ajTrue; } ajDebug("feature %S %d-%d is parent %B, child %B, single %B\n", ajFeatGetType(gf), ajFeatGetStart(gf), ajFeatGetEnd(gf), parent, child, single); /* ajUser("feature %S %d-%d is parent %B, child %B, single %B", ajFeatGetType(gf), ajFeatGetStart(gf), ajFeatGetEnd(gf), parent, child, single); */ /* ** If single or parent, write out any stored previous feature ** sequence */ if(count++ && !child) { extractfeat_WriteOut(seqout, &featseq, compall, sense, firstpos, lastpos, before, after, seq, remote, type, featinname, describeout); /* reset joined feature information */ ajStrSetClear(&featseq); ajStrSetClear(&tmpseq); ajStrSetClear(&type); ajStrSetClear(&describeout); remote = ajFalse; compall = ajFalse; sense = ajTrue; firstpos = 0; lastpos = 0; } /* if parent, note if have Complemented Join */ if(parent) compall = ajFeatIsCompMult(gf); /* ** Get the sense of the feature ** NB. if complementing several joined features, then pretend they ** are forward sense until its possible to reverse-complement ** them all together. */ if(!compall && ajFeatGetStrand(gf) == '-') sense = ajFalse; /* get 'type' name of feature */ if(single || parent) ajStrAssignS(&type, ajFeatGetType(gf)); /* ** if single or parent, get 'before' + 'after' sequence ** positions */ if(single || parent) { firstpos = ajFeatGetStart(gf)-1; lastpos = ajFeatGetEnd(gf)-1; } /* if child, update the boundary positions */ if(child) { if(sense) lastpos = ajFeatGetEnd(gf)-1; else firstpos = ajFeatGetStart(gf)-1; } extractfeat_MatchPatternDescribe(gf, describe, &describeout); /* get feature sequence(complement if required) */ if(!child) { if(join) ajFeatGetSeqJoin(gf, featab, seq, &tmpseq); else ajFeatGetSeq(gf, seq, &tmpseq); ajDebug("extracted feature = %d bases\n", ajStrGetLen(tmpseq)); /*ajUser("extracted feature = %d bases", ajStrGetLen(tmpseq));*/ ajStrAssignS(&featseq, tmpseq); } } ajListIterDel(&iter) ; /* ** write out any previous sequence(s) ** - add before + after, complement all */ extractfeat_WriteOut(seqout, &featseq, compall, sense, firstpos, lastpos, before, after, seq, remote, type, featinname, describeout); ajStrDel(&featseq); ajStrDel(&tmpseq); ajStrDel(&type); ajStrDel(&describeout); } return; }