/* udvseq.c * =========================================================================== * * PUBLIC DOMAIN NOTICE * National Center for Biotechnology Information (NCBI) * * This software/database is a "United States Government Work" under the * terms of the United States Copyright Act. It was written as part of * the author's official duties as a United States Government employee and * thus cannot be copyrighted. This software/database is freely available * to the public for use. The National Library of Medicine and the U.S. * Government do not place any restriction on its use or reproduction. * We would, however, appreciate having the NCBI and the author cited in * any work or product based on this material * * Although all reasonable efforts have been taken to ensure the accuracy * and reliability of the software and data, the NLM and the U.S. * Government do not and cannot warrant the performance or results that * may be obtained by using this software or data. The NLM and the U.S. * Government disclaim all warranties, express or implied, including * warranties of performance, merchantability or fitness for any particular * purpose. * * =========================================================================== * * File Name: udvseq.c * * Author: Patrick Durand * * Version Creation Date: 5/3/99 * * $Revision: 6.25 $ * * File Description: * * Modifications: * -------------------------------------------------------------------------- * $Log: udvseq.c,v $ * Revision 6.25 2006/07/13 17:06:39 bollin * use Uint4 instead of Uint2 for itemID values * removed unused variables * resolved compiler warnings * * Revision 6.24 2002/03/14 16:40:03 kans * SeqMgrIndexFeaturesEx takes dorevfeats, SeqMgrExploreFeaturesRev and featsByRev added for asn2gb * * Revision 6.23 2001/10/03 00:15:47 vakatov * Replaced some ASSERTs by VERIFYs * * Revision 6.22 2000/05/31 21:05:38 kans * suppress all source features * * Revision 6.21 2000/05/09 17:00:18 kans * suppresses full-length biosource features * * Revision 6.20 2000/05/08 19:24:22 lewisg * fix UDV_CreateParaGList to stop at last character instead of one before * * Revision 6.19 2000/04/13 13:57:33 durand * allowed udv to display reverse complement sequence * * Revision 6.18 2000/02/03 15:55:14 hurwitz * added constructor and destructor for MsaTxtDisp * * Revision 6.17 1999/12/02 13:47:32 durand * add new function for Entrez sequence viewer * * Revision 6.16 1999/11/03 13:46:15 durand * add UDV_GetStrandinPGP, UDV_GetStrandinPGPList and UDV_GetBspRangeinPGPList for DDV * * Revision 6.15 1999/10/02 15:11:09 durand * update the code to be used by wwwudv * * Revision 6.14 1999/09/16 18:51:52 durand * move MsaTxtDisp struct from pgppop.h to udvseq.h * * Revision 6.13 1999/09/14 12:09:48 durand * don't show publication features * * Revision 6.12 1999/09/07 19:39:18 durand * don't display special features * * Revision 6.11 1999/08/07 17:04:00 sicotte * fixed cast warning * * Revision 6.10 1999/07/31 14:28:07 durand * take into account parent for seg-set * * Revision 6.9 1999/07/30 20:08:27 durand * updates for the new Entrez graphical viewer * * Revision 6.8 1999/07/21 21:38:45 durand * fix a bug for the display of spanning features on circular DNA * * Revision 6.7 1999/07/12 21:12:09 durand * fix a bug in the cgi-bin release of UDV * * Revision 6.6 1999/06/16 13:07:51 durand * update UDV functions to be used by DDV * * Revision 6.5 1999/06/15 15:24:40 durand * update for DDV * * Revision 6.4 1999/06/07 15:10:19 durand * add LOG line to keep track of the history * * * * ========================================================================== */ #include #include #include #include /******************************************************************************* Function : WhatBspName() Purpose : retrieve the name of the bsp. Currently call only BioseqGetTitle; may be changed in the future Parameters : bsp; pointer to the Bioseq szName; filled with the Bioseq's name Return value : none *******************************************************************************/ static void WhatBspName(BioseqPtr bsp,CharPtr szName) { szName=BioseqGetTitle(bsp); } /******************************************************************************* Function : WhatBspID() Purpose : retrieve the identifier of the bsp. Parameters : bsp; pointer to the Bioseq szAccess; filled with the Bioseq's accession number Return value : none *******************************************************************************/ static void WhatBspID(BioseqPtr bsp,CharPtr szAccess) { SeqIdWrite(bsp->id,szAccess,PRINTID_TEXTID_ACCESSION,20); } /******************************************************************************* Function : WhatBspDataType() Purpose : retrieve the coding type of the sequence. Parameters : bsp; pointer to the Bioseq szDtype; filled with the Bioseq's coding type Return value : none *******************************************************************************/ static void WhatBspDataType(BioseqPtr bsp,CharPtr szDtype) { Uint1 i; Char *datatype[]={"IUPACna","IUPACaa","NCBI2na","NCBI4na", "NCBI8na","NCBIpna","NCBI8aa","NCBIeaa", "NCBIpaa","iupacaa3","NCBIstdaa","Unknown"}; i=bsp->seq_data_type; switch(i){ case Seq_code_iupacna: case Seq_code_iupacaa: case Seq_code_ncbi2na: case Seq_code_ncbi4na: case Seq_code_ncbi8na: case Seq_code_ncbipna: case Seq_code_ncbi8aa: case Seq_code_ncbieaa: case Seq_code_ncbipaa: case Seq_code_iupacaa3: case Seq_code_ncbistdaa: StringCpy(szDtype,datatype[i-1]); break; default: StringCpy(szDtype,datatype[11]); break; } } /******************************************************************************* Function : WhatBspStrand() Purpose : retrieve the strand def. of the BioSeq Parameters : bsp; pointer to the Bioseq szStrand; filled with the Bioseq's strand def. Return value : none *******************************************************************************/ static void WhatBspStrand(BioseqPtr bsp,CharPtr szStrand) { Uint1 i; Char *strand[]={"Single","Double","Mixed","Unknown"}; i=bsp->strand; switch(i){ case 1: case 2: case 3: StringCpy(szStrand,strand[i-1]); break; default: StringCpy(szStrand,strand[3]); break; } } /******************************************************************************* Function : WhatBspTopo() Purpose : retrieve the topology of the Bioseq Parameters : bsp; pointer to the Bioseq szTopo; filled with the Bioseq's topology. Return value : none *******************************************************************************/ static void WhatBspTopo(BioseqPtr bsp,CharPtr szTopo) { Uint1 i; Char *topo[]={"Linear","Circular","Tandem","Unknown"}; i=bsp->topology; switch(i){ case 1: case 2: case 3: StringCpy(szTopo,topo[i-1]); break; default: StringCpy(szTopo,topo[3]); break; } } /******************************************************************************* Function : WhatBspMol() Purpose : what's the bioseq ? Parameters : bsp; pointer to the Bioseq szMol; filled with the Bioseq's type. Return value : TRUE if Bioseq is nucleic acid *******************************************************************************/ static Boolean WhatBspMol(BioseqPtr bsp,CharPtr szMol) { Uint1 i; Char *mol[]={"DNA","RNA","AA","NA","Unknown"}; i=bsp->mol; switch(i){ case Seq_mol_dna: case Seq_mol_rna: case Seq_mol_aa: case Seq_mol_na: StringCpy(szMol,mol[i-1]); break; default: StringCpy(szMol,mol[4]); break; } return(ISA_na(i)); } /******************************************************************************* Function : WhatBspRepr() Purpose : What's the bioseq representation Parameters : bsp; pointer to the Bioseq szRepr; filled with the Bioseq's representation. Return value : none *******************************************************************************/ static void WhatBspRepr(BioseqPtr bsp,CharPtr szRepr) { Uint1 i; Char *repr[]={"Virtual","Raw","Segmented","Constructed", "Reference","Consensus","Map","Delta","Unknown"}; i=Bioseq_repr(bsp); switch(i){ case Seq_repr_virtual: case Seq_repr_raw: case Seq_repr_seg: case Seq_repr_const: case Seq_repr_ref: case Seq_repr_consen: case Seq_repr_map: case Seq_repr_delta: StringCpy(szRepr,repr[i-1]); break; default: StringCpy(szRepr,repr[8]); break; } } /******************************************************************************* Function : UDV_ReadBspDataForViewer() Purpose : call all of the above functions; exported function Parameters : Return value : *******************************************************************************/ NLM_EXTERN void UDV_ReadBspDataForViewer(BspInfoPtr bsp_i) { WhatBspName(bsp_i->bsp,bsp_i->bspName); WhatBspID(bsp_i->bsp,bsp_i->bspAccNum); WhatBspDataType(bsp_i->bsp,bsp_i->bspDataType); WhatBspStrand(bsp_i->bsp,bsp_i->bspStrand); WhatBspTopo(bsp_i->bsp,bsp_i->bspTopo); bsp_i->bspMolNuc=WhatBspMol(bsp_i->bsp,bsp_i->bspMol); WhatBspRepr(bsp_i->bsp,bsp_i->bspRepr); bsp_i->bspLength=BioseqGetLen(bsp_i->bsp); } /******************************************************************************* Function : UDV_FreeListParaG() Purpose : delete the ParaG population Parameters : head of the ParaG val_node list Return value : none *******************************************************************************/ NLM_EXTERN void UDV_FreeListParaG(ValNodePtr PNTR vnp_head) { ValNodePtr vnp,vnp2; ParaGPtr pgp; if ((*vnp_head)){ for(vnp=(*vnp_head) ; vnp != NULL ; vnp=vnp->next){ if (vnp->data.ptrvalue){ pgp=(ParaGPtr)vnp->data.ptrvalue; if (pgp->pFeatList) ValNodeFree(pgp->pFeatList); if (pgp->ptxtList){ for(vnp2=pgp->ptxtList;vnp2 != NULL ; vnp2=vnp2->next){ if(vnp2->data.ptrvalue) MemFree(vnp2->data.ptrvalue); } ValNodeFree(pgp->ptxtList); } Free(pgp); } } ValNodeFree(*vnp_head); *vnp_head=NULL; } } /******************************************************************************* Function: UDV_DecodeIdxFeat() Purpose: decode a 32 bits integer containing val1 (lower 16 bits) and val2 (higher 16 bits) Parameters: index_g; value to decode in 'val1' and 'val2' *******************************************************************************/ NLM_EXTERN void UDV_DecodeIdxFeat (Uint4 index_g, Uint2Ptr val1, Uint4Ptr val2) { Uint2Ptr index_g2; index_g2 = (Uint2Ptr) (&index_g); if (val1) *val1 = (Uint2) index_g2 [0]; if (val2) *val2 = index_g2 [1]; } /******************************************************************************* Function: UDV_BigDecodeIdxFeat() Purpose: decode a 64 bits integer into 16 bits integers Parameters: index_g; value to decode in 'val1' and 'val2' *******************************************************************************/ NLM_EXTERN void UDV_BigDecodeIdxFeat (Uint8 index_g, Uint4Ptr val1, Uint2Ptr val2, Uint2Ptr val3, Uint2Ptr val4) { Uint2Ptr index_g2; index_g2 = (Uint2Ptr) (&index_g); if (val1) *val1 = index_g2 [0]; if (val2) *val2 = (Uint2) index_g2 [1]; if (val3) *val3 = (Uint2) index_g2 [2]; if (val4) *val4 = (Uint2) index_g2 [3]; } /******************************************************************************* Function: UDV_EncodeIdxFeat() Purpose: encode a 32 bits integer with val1 (lower 16 bits) and val2 (higher 16 bits) Parameters: values to decode -> 'val1' and 'val2' Return : the 32 bits encoded value *******************************************************************************/ NLM_EXTERN Uint4 UDV_EncodeIdxFeat (Uint2 val1,Uint2 val2) { Uint2 index_g[2]; index_g[0]=val1; index_g[1]=val2; return *((Int4Ptr) index_g); } /******************************************************************************* Function: UDV_BigEncodeIdxFeat() Purpose: encode a 64 bits integer with 4 16 bits integers Parameters: values to decode Return : the 64 bits encoded value *******************************************************************************/ NLM_EXTERN Uint8 UDV_BigEncodeIdxFeat (Uint2 val1,Uint2 val2,Uint2 val3,Uint2 val4) { Uint2 index_g[4]; index_g[0]=val1; index_g[1]=val2; index_g[2]=val3; index_g[3]=val4; return *((Uint8Ptr) index_g); } /******************************************************************************* Function: UDV_ConvertFeatContext() Purpose: convert the coordinates from master bioseq to a part sequence (seg-set) *******************************************************************************/ NLM_EXTERN SeqMgrFeatContextPtr UDV_ConvertFeatContext( SeqMgrFeatContextPtr context,Int4 cumOffset,Int4 bsp_part_length) { SeqMgrFeatContextPtr newContext; Int2 i,i2; newContext=(SeqMgrFeatContextPtr)MemNew(sizeof(SeqMgrFeatContext)); if (!newContext) return(NULL); memcpy(newContext,context,sizeof(SeqMgrFeatContext)); newContext->left=context->left-cumOffset; if (newContext->left<0 && newContext->bsp->topology!=TOPOLOGY_CIRCULAR) newContext->left=0; newContext->right=context->right-cumOffset; if (newContext->right<0 && newContext->bsp->topology!=TOPOLOGY_CIRCULAR) newContext->right=0; if (newContext->right>bsp_part_length){ newContext->right=bsp_part_length-1; } i2=context->numivals*2; newContext->ivals=(Int4Ptr)MemNew((i2)*sizeof(Int4)); for(i=0;iivals[i]=context->ivals[i]-cumOffset; /*if (newContext->ivals[i]<0 && newContext->bsp->topology!=TOPOLOGY_CIRCULAR) newContext->ivals[i]=0;*/ newContext->ivals[i+1]=context->ivals[i+1]-cumOffset; /*if (newContext->ivals[i+1]<0 && newContext->bsp->topology!=TOPOLOGY_CIRCULAR) newContext->ivals[i+1]=0;*/ } return(newContext); } /******************************************************************************* Function: UDV_ComputeBspCoordRangeinPGP() Purpose: compute from and to in Bioseq coordinates given the line descriptor (pgp->ptxtList) of a ParaG invloved in a multiple sequence alignement (MSA). Parameters: pgp; the ParaG to analyse from, to; return values *******************************************************************************/ NLM_EXTERN void UDV_ComputeBspCoordRangeinPGP(ParaGPtr pgp,Int4Ptr from, Int4Ptr to) { ValNodePtr vnp2; MsaTxtDispPtr mtdp; *from=INT4_MAX; *to=INT4_MIN; if (!pgp->ptxtList) return; for(vnp2=pgp->ptxtList;vnp2!=NULL;vnp2=vnp2->next){ mtdp=(MsaTxtDispPtr)(vnp2->data.ptrvalue); if (mtdp){ if (mtdp->IsGap==FALSE) { *from=MIN(*from,mtdp->from); *to=MAX(*to,mtdp->to); } } } } /******************************************************************************* Function: UDV_GetStrandinPGP() Purpose: get the strand of the sequence in a ParaG. Parameters: pgp; the ParaG to analyse strand; return value *******************************************************************************/ NLM_EXTERN void UDV_GetStrandinPGP(ParaGPtr pgp,Uint1Ptr strand) { ValNodePtr vnp2; MsaTxtDispPtr mtdp; if (!pgp->ptxtList) return; *strand=Seq_strand_unknown; for(vnp2=pgp->ptxtList;vnp2!=NULL;vnp2=vnp2->next){ mtdp=(MsaTxtDispPtr)(vnp2->data.ptrvalue); if (mtdp && mtdp->IsGap==FALSE) { *strand=mtdp->strand; break; } } } /******************************************************************************* Function: UDV_GetStrandinPGPList() Purpose: get the strand of the sequence in a list of ParaG (usually called by DDV to scan a row). Parameters: pgp_list; list of ParaG (row) to analyse strand; return value *******************************************************************************/ NLM_EXTERN void UDV_GetStrandinPGPList(ValNodePtr pgp_list,Uint1Ptr strand) { ValNodePtr vnp,vnp2; MsaTxtDispPtr mtdp; ParaGPtr pgp; if (!pgp_list) return; *strand=Seq_strand_unknown; vnp=pgp_list; while(vnp){ pgp=(ParaGPtr)vnp->data.ptrvalue; if (pgp){ vnp2=pgp->ptxtList; while(vnp2){ mtdp=(MsaTxtDispPtr)(vnp2->data.ptrvalue); if (mtdp && mtdp->IsGap==FALSE) { *strand=mtdp->strand; return; } vnp2=vnp2->next; } } vnp=vnp->next; } } /******************************************************************************* Function: UDV_GetBspRangeinPGPList() Purpose: get the start,stop (bsp coord) of the sequence in a list of ParaG (usually called by DDV to scan a row). Note : bsp_start is always less than bsp_stop (so, don't forget to swap the values if minus strand) *******************************************************************************/ NLM_EXTERN void UDV_GetBspRangeinPGPList(ValNodePtr pgp_list, Int4Ptr bsp_start,Int4Ptr bsp_stop) { ValNodePtr vnp; ParaGPtr pgp; Int4 from_bsp,to_bsp; *bsp_start=INT4_MAX; *bsp_stop=INT4_MIN; vnp=pgp_list; while(vnp){ pgp=(ParaGPtr)vnp->data.ptrvalue; if (pgp){ UDV_ComputeBspCoordRangeinPGP(pgp,&from_bsp,&to_bsp); /*skip full-gapped ParaG*/ if (from_bsp!=INT4_MAX && to_bsp!=INT4_MIN){ *bsp_start=MIN(*bsp_start,from_bsp); *bsp_stop=MAX(*bsp_stop,to_bsp); } } vnp=vnp->next; } } /******************************************************************************* Function: UDV_IsTranslationNeeded() Purpose: for a CDS in a ParaG, determine whether a translation is needed or not Parameters: context ; feature data pgp ; ParaG structure Return : TRUE is a translation is needed *******************************************************************************/ NLM_EXTERN Boolean UDV_IsTranslationNeeded(SeqMgrFeatContextPtr context,ParaGPtr pgp) { Int2 i,numivals2,i_decal; /*counters*/ Uint1 strand; Int4 StartLetter,StopLetter; strand=context->strand; /*temporary situation; will be modified in the future*/ if (strand>Seq_strand_minus || strand==Seq_strand_unknown) strand=Seq_strand_plus; /*strand PLUS*/ if (strand==Seq_strand_plus){ numivals2=context->numivals*2; i=0; i_decal=2; } /*strand MINUS*/ if (strand==Seq_strand_minus){ numivals2=2*context->numivals-2; i=numivals2; i_decal=-2; } /*are the ParaG from a MSA ?*/ if (pgp->ptxtList){ UDV_ComputeBspCoordRangeinPGP(pgp,&StartLetter, &StopLetter); } else{ StartLetter=pgp->StartLetter; StopLetter=pgp->StopLetter; } while (TRUE){ /*if ivals.stop<= start ParaG : not yet in the current ParaG*/ if (context->ivals[i+1]2 && i+2 inter-region: fill the ParaG with a thin line; this is the case for coding region: draw thin line to delineate the introns*/ if (context->ivals[i+2]>StopLetter){ return(FALSE); } } } if (strand==Seq_strand_minus){ if (numivals2>2 && i-2>-1){ /*stop ParaG < start next ivals -> inter-region: fill the ParaG with a thin line; this is the case for coding region: draw thin line to delineate the introns*/ if (context->ivals[i-2]>StopLetter){ return(FALSE); } } } } if (strand==Seq_strand_plus){ i=i+i_decal; if (i>numivals2-2) break; } if (strand==Seq_strand_minus){ i=i+i_decal; if (i<0) break; } } return(TRUE); } /******************************************************************************* Function: UDV_ParaGFTableFeatures() Purpose: populate several ParaG with one feature at a time Parameters: see explore.h *******************************************************************************/ NLM_EXTERN Boolean LIBCALLBACK UDV_ParaGFTableFeatures (SeqFeatPtr sfp, SeqMgrFeatContextPtr context2) { ParaGFeaturesInLocPtr pgfl; ValNodePtr vnp,vnp2,vnp3,vnp4; ParaGPtr pgp; Int4 BeginLines=0,PosFeat,StartLetter,StopLetter; Int2 nLines=0,i=1,j,nFeatLines,decal; Boolean FeatInParaG=FALSE; Boolean bFirst=TRUE,bTrouve=FALSE; Boolean IsTransNeeded=FALSE; SeqMgrFeatContextPtr context; SeqAnnotPtr sap; if (!context2->sfp) return (TRUE); /* for test only : print out the Feature list*/ /*{{ Char str [256]; int i; if (FeatDefLabel (sfp, str, sizeof (str) - 1, OM_LABEL_BOTH)) { printf ( " Feature item %d index %d (%d) (%d - %d) (%d) %s\n", (int) context2->itemID, (int) context2->index, (int) context2->numivals,(int) context2->left, (int) context2->right,(int) context2->strand,str); if (context2->numivals>1){ for (i=0;inumivals*2;i+=2){ printf ( " Ivals: (%d - %d)\n", context2->ivals[i], context2->ivals[i+1]); } } } }} */ pgfl = (ParaGFeaturesInLocPtr) context2->userdata; /*don't retrieve special annotations*/ sap = context2->sap; if (sap && sap->desc!=NULL) return(TRUE); if (context2->seqfeattype==SEQFEAT_PUB) return(TRUE); if (context2->seqfeattype == SEQFEAT_BIOSRC) { /* if (context2->bsp != NULL) { MemSet ((Pointer) &vn, 0, sizeof (ValNode)); vn.choice = SEQLOC_WHOLE; vn.data.ptrvalue = (Pointer) SeqIdFindBest (context2->bsp->id, 0); vn.next = NULL; if (SeqLocCompare (sfp->location, &vn) == SLC_A_EQ_B) return TRUE; } */ return TRUE; /* now decided to suppress all source features */ } context=UDV_ConvertFeatContext(context2,pgfl->cumOffset,pgfl->bsp_part_length); if (!context) return(TRUE); vnp=pgfl->ParaG_head; pgp=(ParaGPtr)vnp->data.ptrvalue; BeginLines=pgp->StartLine; pgfl->nFeat++; /*HET feature correction for the ends*/ if(context->featdeftype== FEATDEF_HET){ context->right=context->ivals[2*context->numivals-1]; } if(context->left<0){/*if circular DNA with feature overlapping the junction*/ /*technically, just for the purpose of a display, a feature overlapping the ends of a circular DNA covers all the sequence; that is because I ALWAYS display from LEFT to RIGHT.*/ context->left=0; context->right=context->bsp->length-1; } while(TRUE){ pgp=(ParaGPtr)vnp->data.ptrvalue; FeatInParaG=FALSE; if (pgp){ /*are the ParaG from a MSA ?*/ if (pgp->ptxtList){ UDV_ComputeBspCoordRangeinPGP(pgp,&StartLetter, &StopLetter); } else{ StartLetter=pgp->StartLetter; StopLetter=pgp->StopLetter; } if (StartLetter>context->right){ pgfl->ParaG_last_head=vnp;/*uses to count last ParaG of the list where there is no feature*/ break; } /*Feature in pgp ?*/ /*if(StopLetter>=context->left && StopLetter<=context->right){ FeatInParaG=TRUE; } else if(StartLetter>=context->left && StartLetter<=context->right){ FeatInParaG=TRUE; } else if(StartLetter<=context->left && StopLetter>=context->right){ FeatInParaG=TRUE; }*/ if(StopLetter>=context->left && StartLetter<=context->right){ FeatInParaG=TRUE; } if (FeatInParaG){ nLines=1;decal=0; if (pgfl->DispType&DDV_DISP_VERT){/*UDV*/ if (bFirst) { pgfl->ParaG_next_head=vnp; bFirst=FALSE; } if (context->sfp->data.choice==SEQFEAT_CDREGION) { IsTransNeeded=UDV_IsTranslationNeeded(context,pgp); if (IsTransNeeded) { nLines++; pgp->nTrans++; decal=1; } } if (pgfl->ShowFeatures) { if (context->left<=pgp->OccupyTo){/*new line of features*/ pgp->nLines+=nLines; pgp->nFeatLines+=nLines; } else{/*same feature line, but CDS*/ /*for the translation*/ if (context->sfp->data.choice==SEQFEAT_CDREGION){ pgp->nLines++; pgp->nFeatLines++; } } pgp->OccupyTo=context->right; /*this is mainly for wwwudv in order to display labels*/ if ((pgfl->DispType&DDV_DISP_VERT) && (pgfl->DispType&DDV_DISP_LABEL)){ pgp->OccupyTo+=StringLen(context->label); } } PosFeat=pgp->nFeatLines; } else{/*DDV (MSA only)*/ if (context->sfp->data.choice==SEQFEAT_CDREGION) { /*IsTransNeeded=UDV_IsTranslationNeeded(context,pgp); if (IsTransNeeded) {*/ nLines++; pgp->nTrans++; /*}*/ } decal=0; if (bFirst) { /*A*/ /*where to put the feature (line number); I compute this value when I populate the first ParaG with the current feature. To populate next ParaG with the same feature, see B./ /PosFeat is used for every ParaG where the current feature is located. In that way, the feature always belongs to the same line from one ParaG to the next one*/ PosFeat=0;/*always base 1 for a line number;*/ j=0; while(jnFeatLines){ if (context->left>pgfl->OccupyTo[j]){ if (context->sfp->data.choice==SEQFEAT_CDREGION){ if (context->left>pgfl->OccupyTo[j+1]){ PosFeat=j+1;break; } } else { PosFeat=j+1;break; } } j++; } if (PosFeat==0){/*if this case, means we need to create nLines new lines*/ PosFeat=pgp->nFeatLines+1; pgp->nFeatLines+=nLines; } pgfl->OccupyTo[PosFeat-1]=context->right; if (context->sfp->data.choice==SEQFEAT_CDREGION) pgfl->OccupyTo[PosFeat]=context->right; pgfl->ParaG_next_head=vnp; nFeatLines=pgp->nFeatLines; bFirst=FALSE; } else{ /*B*/ /*to pupulate other ParaG with the current feature, I check if there is blank line before PosFeat line (use ONLY for a full vertical display)*/ /* for(j=0;jOccupyTo[j]StartLetter){ decal++; } }*/ pgp->nFeatLines=nFeatLines/*-decal*/; } /*new number of lines in the ParaG*/ if (pgfl->ShowFeatures) pgp->nLines=pgp->MinLine+pgp->nFeatLines; else pgp->nLines=pgp->MinLine; } /*total number of features in a ParaG*/ pgp->nFeat++; /*(re)populate Features structure; if a previous structure already exists, use it; avoid a lot of MemNew/MemFree; see also the function which create/(re)populate ParaG structure (CreateParaGList)*/ if (pgp->pFeatList==NULL) { pgp->pFeatList = ValNodeAddBigInt(&pgp->pFeatList,0, UDV_BigEncodeIdxFeat ( context->itemID, (Uint2) context->index,(Uint2)PosFeat-decal,(Uint2)0)); if (!pgp->pFeatList) return TRUE; } else { i=1;bTrouve=FALSE; for (vnp2=pgp->pFeatList ; vnp2!=NULL ; vnp2=vnp2->next){ if (i==pgp->nFeat){ bTrouve=TRUE; break; } i++; vnp3=vnp2; } /*mem alloc only if it's needed*/ if (bTrouve) { vnp2->data.bigintvalue=UDV_BigEncodeIdxFeat( context->itemID, (Uint2) context->index, (Uint2)(PosFeat-decal),(Uint2)0); } else{ vnp4=ValNodeAddBigInt(&vnp3,0, UDV_BigEncodeIdxFeat ( context->itemID, (Uint2) context->index, (Uint2)PosFeat-decal,(Uint2)0)); if (!vnp4)return TRUE; } } } pgp->StartLine=BeginLines;/*beginning of this ParaG*/ BeginLines+=pgp->nLines;/*will be used for the next ParaG*/ vnp=vnp->next;/*get the next ParaG*/ if (vnp==NULL){ pgfl->ParaG_next_head=NULL; /*end*/ break; } } } pgfl->nTotLines_new=BeginLines; if (pgfl->ParaG_next_head) pgfl->ParaG_head=pgfl->ParaG_next_head; MemFree(context->ivals); MemFree(context); return TRUE; } /******************************************************************************* Function: UDV_CreateOneFeatureIndex() Purpose: Call Sequence Manager to create the Feature Index of a BioSeq. Parameter: entityID_seq ; entityID of the BioSeq. Return value: the index value to use with others Sequence Manager functions. (Ex.: SeqMgrExplore... functions) *******************************************************************************/ NLM_EXTERN Uint2 UDV_CreateOneFeatureIndex(Uint2 entityID_seq, BioseqPtr bsp, Boolean bReverse) { Uint2 EntityID; EntityID=entityID_seq; /*Is a previous Index exists for this sequence*/ if (SeqMgrFeaturesAreIndexed (entityID_seq) == 0) { /*create the index*/ if (bsp) EntityID=SeqMgrIndexFeaturesEx (0, bsp, bReverse, FALSE); else EntityID=SeqMgrIndexFeaturesEx (entityID_seq, NULL, bReverse, FALSE); } if (EntityID == 0) { Message (MSG_ERROR, "SeqMgrIndexFeaturesEx failed."); EntityID=INDEX_CREATION_ERROR; } return(EntityID); } /******************************************************************************* Function : UDV_CreateParaGList() Purpose : Create and populate ParaG val_node_list without features Parameters : nCharByLine; # of char by line bsp_length; length of the bsp ShowTop; show scale on top if TRUE ShowTick; show scale's ticks if TRUE ShowSequence; show sequence if TRUE ShowBlank; add blank line at the bottom of the ParaG nTotL; total number of single lines for the whole ParaG list ParaG_head; head of the ParaG list Note : use this function to create a simple representation of a sequence without the features. If you want to show the features, first call this function, then UDV_CreateOneFeatureIndex() to create feature index, and finally PopulateParaGFeatures() to populate ParaG with the features. Return value : a ValNodePtr which is the head of the ParaG list Indeed, in this function ,the value of ParaG_head (passed in here) is modified. This is done to speed up the population of ParaG. (see also nTotL) *******************************************************************************/ NLM_EXTERN ValNodePtr UDV_CreateParaGList(Int2 nCharByLine, Int4 bsp_length,Int4 from,Int4 to, Boolean ShowTop,Boolean ShowTick,Boolean ShowSequence, Boolean ShowBlank,Int4Ptr nTotL,ValNodePtr ParaG_head) { ParaGPtr pgp=NULL; /*ParaG data*/ ValNodePtr local_head=NULL, /*these are used to scan ParaG*/ vnp1=NULL, vnp2=NULL; Boolean isFailed=FALSE; /*memory allocation failure*/ Boolean bFirst=TRUE; /*used to avoid non-neces. mem alloc*/ Int4 start=0, /*letter start, zero based*/ stop=0, /*letter stop. zero based*/ nTotLines=0; /*Total lines in viewer*/ Int1 minLineByParaG=0; /*min height of a paraG, nb. of lines*/ Int4 nParaG=0; /*ParaG counter*/ /*Minimum ParaG height*/ if (ShowTop) minLineByParaG++; if (ShowTick) minLineByParaG++; if (ShowSequence) minLineByParaG++; if (ShowBlank) minLineByParaG++; /*stop=MIN(nCharByLine,bsp_length);*/ local_head=ParaG_head; vnp1=ParaG_head; start=from; /*to++; stop=MIN(nCharByLine,to);*/ /*(re)populate ParaG structure; if a previous structure already exists, use it; avoid a lot of MemNew/MemFree*/ while(!(start>to)){ if (vnp1){ pgp=(ParaGPtr)vnp1->data.ptrvalue; if (!pgp){ isFailed=TRUE; break; } /*Features; note that pgp->FeatList is not deleted : see the function which populates this structure (ParaGFTableFeatures)*/ pgp->nFeat=0;pgp->nTrans=0; if (bFirst) bFirst=FALSE; vnp2=vnp1; vnp1=vnp1->next; } else{ /*allocate new ParaG*/ pgp=(ParaGPtr)MemNew(sizeof(ParaG)); if (!pgp){ isFailed=TRUE; break; } MemSet(pgp,0,sizeof(ParaG)); /*create a new node*/ if (vnp2==NULL) vnp2=ValNodeAddPointer(NULL,0,pgp); else vnp2=ValNodeAddPointer(&vnp2,0,pgp); if (!vnp2){ isFailed=TRUE; break; } if (bFirst){ local_head=vnp2; bFirst=FALSE; } } /*Fill in pgp*/ pgp->StartLine=nTotLines; pgp->nLines=minLineByParaG; pgp->StartLetter=start; pgp->NumOrder=nParaG+1; pgp->nFeatLines=0; /*modify values*/ nTotLines+=minLineByParaG; start+=nCharByLine; stop=start-1; if (stop>to) stop=to; pgp->StopLetter=stop; pgp->OccupyTo=pgp->StopLetter; /*this element is used to keep track of the minimum number of lines in a ParaG; i.e. ruler+sequence, 1 to 3 lines. I need this value in the function UDV_ParaGFTableFeatures() to increase pgp->nLines during the population of the ParaG with the features*/ pgp->MinLine=(Int2)minLineByParaG; nParaG++; } if (isFailed){ UDV_FreeListParaG(&local_head); nTotLines=0; } if (vnp1){ ValNodeFree(vnp1); vnp2->next=NULL; } *nTotL=nTotLines; return(local_head); } /******************************************************************************* Function : UDV_PopulateParaGFeatures() Purpose : populate ParaG val_node_list with features Parameters : GrData; graphical data bsp; BioseqPtr of the Bioseq ParaG_vnp; valnode list of the ParaG. Each node has a data.ptrvalue which is of type ParaGPtr. rcP; size and position of the UnD viewer's panel nTotL; total number of single lines for the whole ParaG list Note : this function, if called, MUST BE used after a call to UDV_CreateParaGList(). Return value : TRUE if features found; otherwise FALSE (see also nTotL) *******************************************************************************/ NLM_EXTERN Boolean UDV_PopParaGFeaturesEx(BioseqPtr bsp,ValNodePtr ParaG_vnp, Boolean ShowFeatures,Int4Ptr nTotL,Uint4 DispType,Int2Ptr nFeatFound, BoolPtr FeatDefTable,Int4 from_bsp,Int4 to_bsp) { ParaGFeaturesInLoc pgfl; /*used for the Explore features function*/ ValNodePtr vnp; /*to scan ParaG list*/ ParaGPtr pgp; /*to modify ParaG, when needed*/ Int4 n=0; /*a little counter*/ Boolean nRet; /*variables used to populate a bsp which is a segment of a "master" sequence (parent)*/ BioseqPtr parent; SeqMgrSegmentContext context; SeqLocPtr slp; Int4 from,to; Int2 nFeat; if (ParaG_vnp == NULL) {*nTotL=0;return(FALSE);} /*prepare the Exploration of Features*/ pgfl.ParaG_head=ParaG_vnp; pgfl.nTotLines_new=0; pgfl.ParaG_next_head=NULL; /*pgfl.LineH=GrData.udv_font.LineHeight;*/ /*pgfl.rcP_top=rcP.top;*/ pgfl.ParaG_last_head=NULL; pgfl.ShowFeatures=ShowFeatures; pgfl.DispType=DispType; MemSet(pgfl.OccupyTo,(Int4)-1,sizeof(pgfl.OccupyTo)); /*the current bsp is just a segment ?*/ parent=SeqMgrGetParentOfPart(bsp,&context); /*convert the from-to of the segment to the "master" bioseq coordinates system*/ if (parent){ from=context.cumOffset+from_bsp; /*to=from+context.to-context.from;*/ to=context.cumOffset+to_bsp; slp=SeqLocIntNew(from, to, Seq_strand_plus, parent->id); pgfl.cumOffset=context.cumOffset; pgfl.bsp_part_length=bsp->length; } else{ slp=SeqLocIntNew (from_bsp, to_bsp, Seq_strand_plus, bsp->id);; pgfl.cumOffset=0; pgfl.bsp_part_length=bsp->length; } /*Explore the features */ nFeat=SeqMgrExploreFeatures ((parent!=NULL ? parent : bsp), (Pointer) &pgfl, UDV_ParaGFTableFeatures, slp, NULL, FeatDefTable); if (nFeatFound){ *nFeatFound=nFeat; } /*complete the list where no features have been found; actually, this code is used to locate (RecT) correctly the end of the ParaG list*/ if (pgfl.ParaG_next_head && pgfl.ParaG_last_head){ n=pgfl.nTotLines_new; for(vnp=pgfl.ParaG_last_head ; vnp != NULL ; vnp=vnp->next){ if (vnp->data.ptrvalue){ pgp=(ParaGPtr)vnp->data.ptrvalue; pgp->StartLine=n; n+=pgp->nLines; } } pgfl.nTotLines_new=n; } /*pgfl.nTotLines_new could be 0 if no features*/ if (pgfl.nTotLines_new>0) { *nTotL=pgfl.nTotLines_new; nRet=TRUE; } else nRet=FALSE; MemFree(slp); /*DEBUG purpose : check the feature content of each ParaG {{ ValNodePtr vnp2; Int4 i; Uint2 eID,idx,line,not; vnp=ParaG_vnp; i=0; while(vnp){ pgp=(ParaGPtr)vnp->data.ptrvalue; printf("ParaG [%6i]:[%7i..%7i]================\n",i,pgp->StartLetter+1,pgp->StopLetter+1); vnp2=pgp->pFeatList; while(vnp2){ UDV_BigDecodeIdxFeat((Uint8)vnp2->data.bigintvalue, &eID, &idx, &line, ¬); printf(" eID:%4i ; idx:%4i ; Line :%4i\n",eID,idx,line); vnp2=vnp2->next; } vnp=vnp->next;i++; } }}*/ return(nRet); } NLM_EXTERN Boolean UDV_PopulateParaGFeatures(BioseqPtr bsp,ValNodePtr ParaG_vnp, Boolean ShowFeatures,Int4Ptr nTotL,Uint4 DispType,Int2Ptr nFeatFound) { return(UDV_PopParaGFeaturesEx(bsp,ParaG_vnp,ShowFeatures,nTotL,DispType, nFeatFound,NULL,0,bsp->length-1)); } /******************************************************************************* Function : UDV_Read_SequenceEx() Purpose : read a sequence Parameters : Warning, from must be < than to; always Return value : the sequence *******************************************************************************/ NLM_EXTERN CharPtr UDV_Read_SequenceEx (SeqIdPtr sip, Int4 from, Int4 to, Boolean IsProt,Int2 len,Uint1 strand) { /*BioseqPtr bsp;*/ SeqLocPtr slp; SeqPortPtr spp; CharPtr str = NULL; Uint1 residue; Uint2 i=0; /*from always < than to*/ slp = SeqLocIntNew (from, to, strand, sip); spp = SeqPortNewByLoc (slp, (Uint1)(IsProt==TRUE ? Seq_code_iupacaa : Seq_code_iupacna)); if (spp != NULL) { str = MemNew ((len+1) * sizeof(Char)); if (!str) return(NULL); while ((residue = SeqPortGetResidue(spp)) != SEQPORT_EOF) { if (IS_residue(residue)) { str[i] = residue; i++; } } /*SeqPortRead(spp, (BytePtr)str, len);*/ SeqPortFree (spp); } SeqLocFree (slp); return str; } /******************************************************************************* Function : UDV_Read_Sequence() Purpose : read a sequence Parameters : Warning, from must be < than to; always Return value : the sequence *******************************************************************************/ NLM_EXTERN CharPtr UDV_Read_Sequence (SeqIdPtr sip, Int4 from, Int4 to, Boolean IsProt,Int2 len) { return (UDV_Read_SequenceEx ( sip, from, to, IsProt, len,Seq_strand_plus)); } /******************************************************************************* Function : UDV_RevertBioSeqCoord() Purpose : given a 5'->3' coord, get back the 3'->5' coord (nuc. seq only) IMPORTANT NOTE : the return value is ONE-BASED *******************************************************************************/ NLM_EXTERN Int4 UDV_RevertBioSeqCoord(Int4 bsp_coord,Int4 bsp_length) { return(bsp_length-bsp_coord); } NLM_EXTERN MsaTxtDispPtr UDV_MsaTxtDispNew(MsaTxtDispPtr pTxtDisp) { /*---------------------------------------------------------------------------- * makes a copy of an MsaTxtDisp. * returns pointer to a new MsaTxtDisp. *---------------------------------------------------------------------------*/ MsaTxtDispPtr pTxtDispCopy; pTxtDispCopy = MemNew(sizeof(MsaTxtDisp)); ASSERT(pTxtDispCopy != NULL); MemCopy(pTxtDispCopy, pTxtDisp, sizeof(MsaTxtDisp)); return(pTxtDispCopy); } NLM_EXTERN MsaTxtDispPtr UDV_MsaTxtDispFree(MsaTxtDispPtr pTxtDisp) { /******************************************************************************* * frees memory used for MsaTxtDisp. * returns NULL for successful completion. *******************************************************************************/ ASSERT(pTxtDisp != NULL); VERIFY(MemFree(pTxtDisp) == NULL); return(NULL); }