~ubuntu-branches/ubuntu/precise/ncbi-tools6/precise

« back to all changes in this revision

Viewing changes to api/alignmgr2.c

  • Committer: Bazaar Package Importer
  • Author(s): Aaron M. Ucko
  • Date: 2005-03-27 12:00:15 UTC
  • mfrom: (2.1.2 hoary)
  • Revision ID: james.westby@ubuntu.com-20050327120015-embhesp32nj73p9r
Tags: 6.1.20041020-3
* Fix FTBFS under GCC 4.0 caused by inconsistent use of "static" on
  functions.  (Closes: #295110.)
* Add a watch file, now that we can.  (Upstream's layout needs version=3.)

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
*
29
29
* Version Creation Date:  10/01 
30
30
*
31
 
* Revision: 6.23 $
 
31
* $Revision: 6.56 $
32
32
*
33
33
* File Description: SeqAlign indexing, access, and manipulation functions 
34
34
*
35
35
* Modifications:
36
36
* --------------------------------------------------------------------------
37
37
* $Log: alignmgr2.c,v $
 
38
* Revision 6.56  2004/09/15 14:59:19  bollin
 
39
* make sure we do not read outside the alignment index arrays
 
40
*
 
41
* Revision 6.55  2004/05/20 19:46:25  bollin
 
42
* removed unused variables
 
43
*
 
44
* Revision 6.54  2004/05/11 13:19:49  bollin
 
45
* update the dimension of the shared alignment after adding a sequence.
 
46
*
 
47
* Revision 6.53  2004/04/13 14:43:07  kskatz
 
48
* Final resolution of revisions 6.51 and 6.52: reverted 6.52; then  cleaned up readability of AlnMgr2SeqPortRead() and ensured that it will never call SeqPortRead for a length > AM_SEQPORTSIZE
 
49
*
 
50
* Revision 6.52  2004/04/12 19:52:15  kskatz
 
51
* Revision 6.51 was right neighborhood,wrong off-by-one: It was in AlnMgr2ComputeFreqMatrix() call to AlnMgr2SeqPortRead() when using l+AM_SEQPORTSIZE instead of l+AM_SEQPORTSIZE-1
 
52
*
 
53
* Revision 6.51  2004/04/12 17:00:44  kskatz
 
54
* Fixed off-by-one error in AlnMgr2SeqPortRead() length passed to SeqPortRead(); stop-start+1 changed to stop-start
 
55
*
 
56
* Revision 6.50  2004/03/11 14:15:41  bollin
 
57
* added extra check in AlnMgr2GetNthSeqIdPtr to avoid core dump if there are
 
58
* fewer than N SeqIDs in the alignment.
 
59
*
 
60
* Revision 6.49  2003/10/20 17:54:34  kans
 
61
* AlnMgr2ComputeFreqMatrix protect against dereferencing NULL bsp
 
62
*
 
63
* Revision 6.48  2003/10/09 13:46:52  rsmith
 
64
* Add AlnMgr2GetFirstNForSipList.
 
65
*
 
66
* Revision 6.47  2003/05/15 18:53:10  rsmith
 
67
* in AlnMgr2GetSeqRangeForSipInStdSeg always return start & stop in coordinate order. Do not assume what minus strand will do or not.
 
68
*
 
69
* Revision 6.46  2003/04/24 20:28:48  rsmith
 
70
* made AlnMgr2GetNthStdSeg use 1 based numbering like the other Nth functions.
 
71
*
 
72
* Revision 6.45  2003/04/23 20:36:13  rsmith
 
73
* Added four functions in Section 11 to get information about Std-Seg alignments.
 
74
*
 
75
* Revision 6.44  2003/03/31 20:17:11  todorov
 
76
* Added AlnMgr2IndexSeqAlignEx
 
77
*
 
78
* Revision 6.43  2003/02/03 12:36:22  kans
 
79
* AlnMgr2ComputeScoreForSeqAlign checks return value of AlnMgr2ComputeFreqMatrix, returns -1 if NULL to avoid dereference crash
 
80
*
 
81
* Revision 6.42  2002/10/23 16:32:19  todorov
 
82
* CondenseColumns fixed: needed to move the lens too.
 
83
*
 
84
* Revision 6.40  2002/10/16 15:54:28  todorov
 
85
* use the default dim value if not set
 
86
*
 
87
* Revision 6.39  2002/08/07 21:57:33  kans
 
88
* added AlignMgr2GetFirstNForStdSeg
 
89
*
 
90
* Revision 6.38  2002/07/11 14:35:51  kans
 
91
* fixed Mac complaints about prototypes
 
92
*
 
93
* Revision 6.37  2002/07/11 12:55:38  wheelan
 
94
* added support for std-seg alignments
 
95
*
 
96
* Revision 6.36  2002/06/04 17:43:07  todorov
 
97
* 1) Substituted AddInNewSA with a new and optimized AddInNewPairwiseSA function.
 
98
* 2) Fixed a few bugs in other functions.
 
99
*
 
100
* Revision 6.35  2002/05/17 15:04:42  wheelan
 
101
* bug fix in ExtendToCoords
 
102
*
 
103
* Revision 6.34  2002/05/17 11:02:36  wheelan
 
104
* bug fixes in Merge func
 
105
*
 
106
* Revision 6.32  2002/03/04 17:19:18  wheelan
 
107
* added AlnMgr2FuseSet, changed behavior of RemoveInconsistent, fixed GetNextAlnBitBugs
 
108
*
 
109
* Revision 6.31  2002/01/31 17:41:47  wheelan
 
110
* various bug fixes -- no more 0 len segments, better handling of rows that are one big insert, etc.
 
111
*
 
112
* Revision 6.30  2002/01/30 19:12:53  wheelan
 
113
* added RemoveInconsistentAlnsFromSet, ExtractPairwiseSeqAlign, changed behavior of GetSubAlign, changed structures and behavior of GetNextAlnBit, added GetInterruptInfo, added AlnMgr2IndexAsRows, bug fixes in indexing routines
 
114
*
 
115
* Revision 6.29  2002/01/02 15:05:07  wheelan
 
116
* changes to force more efficient ordering in CompareAsp callbacks, plus more stringent checks in AlnMgr2AddInNewSA
 
117
*
 
118
* Revision 6.28  2001/12/28 22:53:20  wheelan
 
119
* bug fixes; added AlnMgr2DupAlnAndIndexes, changed some New and Free funcs
 
120
*
 
121
* Revision 6.27  2001/12/27 16:07:22  wheelan
 
122
* bug fix in ExtendToEnd
 
123
*
 
124
* Revision 6.26  2001/12/20 19:43:20  wheelan
 
125
* bug fix in GetNextAlnBit -- no more incorrect inserts
 
126
*
38
127
* Revision 6.25  2001/12/18 16:36:57  wheelan
39
128
* scattered fixes to unaligned region code
40
129
*
124
213
/* SECTION 1 */
125
214
static SARowDat2Ptr SARowDat2New(void);
126
215
static void SARowDat2Free(SARowDat2Ptr srdp);
 
216
static SARowDat2Ptr SARowDat2Copy(SARowDat2Ptr srdp);
127
217
static SAIndex2Ptr SAIndex2New(void);
 
218
static SAIndex2Ptr SAIndex2Copy(VoidPtr index);
 
219
static AMAlignIndex2Ptr AMAlignIndex2Copy(VoidPtr index);
128
220
static void AMIntervalSetFree(AMIntervalSetPtr amint);
129
221
/* SECTION 2 */
130
222
static void AlnMgr2ConvertDendiagToDensegChain(SeqAlignPtr sap);
154
246
static void AlnMgr2BuildAlignmentFromTree(AMVertexPtr PNTR vertexarray, Int4 numvertices, AMEdgePtr edge_head, SeqAlignPtr sap);
155
247
static AMVertexPtr AlnMgr2GetAdjacentVertices(AMVertexPtr vertex, AMVertexPtr PNTR vertexarray, AMEdgePtr edge_head);
156
248
static void AlnMgr2AddInNewSA(SeqAlignPtr parent, SeqAlignPtr sap);
 
249
static void AlnMgr2AddInNewPairwiseSA(SeqAlignPtr parent, SeqAlignPtr sap);
157
250
static Int4 AlnMgr2MapSegStartToSegStart(SeqAlignPtr sap, Int4 pos, Int4 row1, Int4 row2, Int4 len);
158
251
static Int4 AlnMgr2GetSegForStartPos(SeqAlignPtr sap, Int4 pos, Int4 row);
159
 
static void AlnMgr2CondenseRows(DenseSegPtr dsp);
 
252
static void AlnMgr2CondenseColumns(DenseSegPtr dsp);
 
253
static void AlnMgr2CondenseRows(DenseSegPtr dsp, Int4 whichrow);
160
254
static Boolean AlnMgr2DoCondense(DenseSegPtr dsp, Int4 rownum1, Int4 rownum2);
161
255
static int LIBCALLBACK AlnMgr2CompareCdRows(VoidPtr ptr1, VoidPtr ptr2);
162
256
static int LIBCALLBACK AlnMgr2CompareAsps(VoidPtr ptr1, VoidPtr ptr2);
163
257
static int LIBCALLBACK AlnMgr2CompareAspsMinus(VoidPtr ptr1, VoidPtr ptr2);
164
258
static void AlnMgr2GetFirstSharedRow(SeqAlignPtr sap1, SeqAlignPtr sap2, Int4Ptr n1, Int4Ptr n2);
165
259
static SeqIdPtr AlnMgr2SeqIdListsOverlap(SeqIdPtr sip1, SeqIdPtr sip2);
 
260
static Int4 AlnMgr2OrderSeqIds(SeqIdPtr sip1, SeqIdPtr sip2);
166
261
static void AlnMgr2SetUnaln(SeqAlignPtr sap);
167
262
static int LIBCALLBACK AlnMgr2CompareUnalnAMS(VoidPtr ptr1, VoidPtr ptr2);
168
263
/* SECTION 4 */
169
 
static Boolean AlnMgr2GetNextAnchoredChildBit(SeqAlignPtr sap, AlnMsg2Ptr amp);
170
264
static Int4 binary_search_on_uint4_list(Uint4Ptr list, Uint4 pos, Uint4 listlen);
171
 
static Int4 binary_search_on_uint2_list(Uint2Ptr list, Uint2 ele, Uint2 listlen);
 
265
static Int4 binary_search_on_uint2_list(Uint2Ptr list, Int4 ele, Uint2 listlen);
172
266
static void AlnMgr2GetUnalignedInfo(SeqAlignPtr sap, Int4 segment, Int4 row, Int4Ptr from, Int4Ptr to);
173
267
static void AlnMgr2GetNthSeqRangeInSASet(SeqAlignPtr sap, Int4 n, Int4Ptr start, Int4Ptr stop);
174
268
static Int4 AlnMgr2GetMaxUnalignedLength(SeqAlignPtr sap, Int4 seg);
180
274
static int LIBCALLBACK AMCompareStarts(VoidPtr ptr1, VoidPtr ptr2);
181
275
 
182
276
 
 
277
typedef struct am_seqpieceset AMSeqPieceSet, PNTR AMSeqPieceSetPtr;
 
278
typedef struct am_seqpiece AMSeqPiece, PNTR AMSeqPiecePtr;
 
279
 
 
280
struct am_seqpiece {
 
281
  Int4 beg;
 
282
  Int4 end;
 
283
  Int4 left;
 
284
  Int4 right;
 
285
  Int4 orig_left;
 
286
  Int4 orig_right;
 
287
  Boolean aligned;
 
288
  Int4 seg;
 
289
  Int4 pos;
 
290
  DenseSegPtr alt_dsp;
 
291
  Int4 alt_seg;
 
292
  Int4 alt_pos;
 
293
  AMSeqPiecePtr next;
 
294
  AMSeqPiecePtr prev;
 
295
  AMSeqPieceSetPtr set;
 
296
};
 
297
 
 
298
struct am_seqpieceset {
 
299
  AMSeqPiecePtr head;
 
300
  AMSeqPiecePtr tail;
 
301
  DenseSegPtr dsp;
 
302
  DenseSegPtr alt_dsp;
 
303
  Int4 row;
 
304
  Int4 row2;
 
305
  Int4 alt_row;
 
306
  Int4 alt_row2;
 
307
  Uint1 strand;
 
308
  Boolean plus;
 
309
  Int4 max_pos;
 
310
  Boolean sign;
 
311
  AMSeqPieceSetPtr next;
 
312
};
 
313
 
 
314
 
183
315
 
184
316
/***************************************************************************
185
317
*
186
318
*  SECTION 1: Functions for allocating and freeing data structures used
187
 
*  by the alignment manager.
 
319
*  by the alignment manager; copying functions are also here.
188
320
*
189
321
***************************************************************************/
190
322
 
203
335
      MemFree(srdp->sect);
204
336
   if (srdp->unsect != NULL)
205
337
      MemFree(srdp->unsect);
 
338
   MemFree(srdp->insect);
 
339
   MemFree(srdp->unaligned);
206
340
   MemFree(srdp);
207
341
}
208
342
 
209
343
/* SECTION 1 */
 
344
static SARowDat2Ptr SARowDat2Copy(SARowDat2Ptr srdp)
 
345
{
 
346
   Int4          i;
 
347
   SARowDat2Ptr  srdp2;
 
348
 
 
349
   if (srdp == NULL)
 
350
      return NULL;
 
351
   srdp2 = SARowDat2New();
 
352
   srdp2->numsect = srdp->numsect;
 
353
   srdp2->sect = (Uint2Ptr)MemNew(srdp2->numsect*sizeof(Uint2));
 
354
   for (i=0; i<srdp2->numsect; i++)
 
355
   {
 
356
      srdp2->sect[i] = srdp->sect[i];
 
357
   }
 
358
   srdp2->numunsect = srdp->numunsect;
 
359
   srdp2->unsect = (Uint2Ptr)MemNew(srdp2->numunsect*sizeof(Uint2));
 
360
   for (i=0; i<srdp2->numunsect; i++)
 
361
   {
 
362
      srdp2->unsect[i] = srdp->unsect[i];
 
363
   }
 
364
   srdp2->numinsect = srdp->numinsect;
 
365
   srdp2->insect = (Uint2Ptr)MemNew(srdp2->numinsect*sizeof(Uint2));
 
366
   for (i=0; i<srdp2->numinsect; i++)
 
367
   {
 
368
      srdp2->insect[i] = srdp->insect[i];
 
369
   }
 
370
   srdp2->numunaln = srdp->numunaln;
 
371
   srdp2->unaligned = (Uint2Ptr)MemNew(srdp2->numunaln*sizeof(Uint2));
 
372
   for (i=0; i<srdp2->numunaln; i++)
 
373
   {
 
374
      srdp2->unaligned[i] = srdp->unaligned[i];
 
375
   }
 
376
   return srdp2;
 
377
}
 
378
 
 
379
/* SECTION 1 */
210
380
static SAIndex2Ptr SAIndex2New(void)
211
381
{
212
382
   SAIndex2Ptr  saip;
238
408
}
239
409
 
240
410
/* SECTION 1 */
 
411
NLM_EXTERN void AlnMgr2FreeInterruptInfo(AMInterrInfoPtr interr)
 
412
{
 
413
   if (interr == NULL)
 
414
      return;
 
415
   MemFree(interr->starts);
 
416
   MemFree(interr->lens);
 
417
   MemFree(interr->types);
 
418
   MemFree(interr);
 
419
}
 
420
 
 
421
/* SECTION 1*/
 
422
static SAIndex2Ptr SAIndex2Copy(VoidPtr index)
 
423
{
 
424
   Int4         i;
 
425
   SAIndex2Ptr  saip;
 
426
   SAIndex2Ptr  saip2;
 
427
 
 
428
   saip2 = SAIndex2New();
 
429
   saip = (SAIndex2Ptr)(index);
 
430
   saip2->numseg = saip->numseg;
 
431
   saip2->aligncoords = (Uint4Ptr)MemNew(saip2->numseg*sizeof(Uint4));
 
432
   for (i=0; i<saip2->numseg; i++)
 
433
   {
 
434
      saip2->aligncoords[i] = saip->aligncoords[i];
 
435
   }
 
436
   saip2->anchor = saip->anchor;
 
437
   saip2->numrows = saip->numrows;
 
438
   saip2->numseg = saip->numseg;
 
439
   saip2->srdp = (SARowDat2Ptr PNTR)MemNew(saip2->numrows*sizeof(SARowDat2));
 
440
   for (i=0; i<saip2->numrows; i++)
 
441
   {
 
442
      saip2->srdp[i] = SARowDat2Copy(saip->srdp[i]);
 
443
   }
 
444
   saip2->numunaln = saip->numunaln;
 
445
   saip2->unaln = (Uint4Ptr)MemNew(saip2->numunaln*sizeof(Uint4));
 
446
   for (i=0; i<saip2->numunaln; i++)
 
447
   {
 
448
      saip2->unaln[i] = saip->unaln[i];
 
449
   }
 
450
   saip2->numinchain = saip->numinchain;
 
451
   saip2->numsplitaln = saip->numsplitaln;
 
452
   saip2->score = saip->score;
 
453
   saip2->aligned = saip->aligned;
 
454
   return saip2;
 
455
}
 
456
 
 
457
/* SECTION 1 */
241
458
static AMAlignIndex2Ptr AMAlignIndex2New(void)
242
459
{
243
460
   AMAlignIndex2Ptr  amaip;
252
469
NLM_EXTERN Boolean LIBCALLBACK AMAlignIndex2Free2(VoidPtr index)
253
470
{
254
471
   AMAlignIndex2Ptr  amaip;
 
472
   Int4              i;
255
473
 
256
474
   if (index == NULL)
257
475
      return FALSE;
258
476
   amaip = (AMAlignIndex2Ptr)(index);
 
477
   for (i=0; i<amaip->numrows; i++)
 
478
   {
 
479
      SeqIdFree(amaip->ids[i]);
 
480
   }
 
481
   MemFree(amaip->ids);
 
482
   MemFree(amaip->saps);
 
483
   MemFree(amaip->aligned);
 
484
   SeqAlignFree(amaip->sharedaln);
259
485
   MemFree(amaip);
260
486
   return TRUE;
261
487
}
262
488
 
263
489
/* SECTION 1 */
 
490
static AMAlignIndex2Ptr AMAlignIndex2Copy(VoidPtr index)
 
491
{
 
492
   AMAlignIndex2Ptr  amaip;
 
493
   AMAlignIndex2Ptr  amaip2;
 
494
   Int4              i;
 
495
 
 
496
   if (index == NULL)
 
497
      return NULL;
 
498
   amaip = (AMAlignIndex2Ptr)(index);
 
499
   amaip2 = AMAlignIndex2New();
 
500
   amaip2->alnstyle = amaip->alnstyle;
 
501
   amaip2->anchor = amaip->anchor;
 
502
   amaip2->numrows = amaip->numrows;
 
503
   amaip2->ids = (SeqIdPtr PNTR)MemNew(amaip2->numrows*sizeof(SeqIdPtr));
 
504
   for (i=0; i<amaip2->numrows; i++)
 
505
   {
 
506
      amaip2->ids[i] = SeqIdDup(amaip->ids[i]);
 
507
   }
 
508
   amaip2->numsaps = amaip->numsaps;
 
509
   amaip2->saps = (SeqAlignPtr PNTR)MemNew(amaip2->numsaps*sizeof(SeqAlignPtr));
 
510
   amaip2->aligned = (Boolean PNTR)MemNew(amaip2->numsaps*sizeof(Boolean));
 
511
   for (i=0; i<amaip2->numsaps; i++)
 
512
   {
 
513
      amaip2->saps[i] = SeqAlignDup(amaip->saps[i]);
 
514
      amaip2->aligned[i] = amaip->aligned[i];
 
515
      if (i>0)
 
516
         amaip2->saps[i-1]->next = amaip2->saps[i];
 
517
   }
 
518
   amaip2->sharedaln = AlnMgr2DupAlnAndIndexes(amaip->sharedaln);
 
519
   return amaip2;
 
520
}
 
521
 
 
522
/* SECTION 1 */
264
523
NLM_EXTERN void AMAlignIndexFreeEitherIndex(SeqAlignPtr sap)
265
524
{
266
525
   if (sap == NULL || sap->saip == NULL)
273
532
}
274
533
 
275
534
/* SECTION 1 */
 
535
NLM_EXTERN SeqAlignPtr AlnMgr2DupAlnAndIndexes(SeqAlignPtr sap)
 
536
{
 
537
   AMAlignIndex2Ptr  amaip;
 
538
   SAIndex2Ptr       saip;
 
539
   SeqAlignPtr       sap_new;
 
540
 
 
541
   if (sap == NULL)
 
542
      return NULL;
 
543
   if (sap->saip == NULL)
 
544
      return (SeqAlignDup(sap));
 
545
   sap_new = NULL;
 
546
   if (sap->saip->indextype == INDEX_CHILD)
 
547
   {
 
548
      sap_new = SeqAlignDup(sap);
 
549
      sap_new->saip = (Pointer)SAIndex2Copy(sap->saip);
 
550
      saip = (SAIndex2Ptr)(sap_new->saip);
 
551
      saip->top = AlnMgr2GetParent(sap);
 
552
   } else if (sap->saip->indextype == INDEX_PARENT)
 
553
   {
 
554
      sap_new = SeqAlignNew();
 
555
      sap_new->type = sap->type;
 
556
      sap_new->segtype = sap->segtype;
 
557
      sap_new->saip = (Pointer)(AMAlignIndex2Copy(sap->saip));
 
558
      amaip = (AMAlignIndex2Ptr)(sap_new->saip);
 
559
      sap_new->segs = amaip->saps[0];
 
560
   }
 
561
   return sap_new;
 
562
}
 
563
 
 
564
/* SECTION 1 */
276
565
NLM_EXTERN AlnMsg2Ptr AlnMsgNew2(void)
277
566
{
278
567
   AlnMsg2Ptr  amp;
285
574
/* SECTION 1 */
286
575
NLM_EXTERN AlnMsg2Ptr AlnMsgFree2(AlnMsg2Ptr amp)
287
576
{
288
 
   if (amp->left_insert != NULL)
289
 
   {
290
 
      MemFree(amp->left_insert);
291
 
      amp->left_insert = NULL;
292
 
   }
293
 
   if (amp->right_insert != NULL)
294
 
   {
295
 
      MemFree(amp->right_insert);
296
 
      amp->right_insert = NULL;
297
 
   }
298
 
   if (amp->left_unaligned != NULL)
299
 
   {
300
 
      MemFree(amp->left_unaligned);
301
 
      amp->left_unaligned = NULL;
302
 
   }
303
 
   if (amp->right_unaligned != NULL)
304
 
   {
305
 
      MemFree(amp->right_unaligned);
306
 
      amp->right_unaligned = NULL;
 
577
   if (amp->left_interrupt != NULL)
 
578
   {
 
579
      MemFree(amp->left_interrupt);
 
580
      amp->left_interrupt = NULL;
 
581
   }
 
582
   if (amp->right_interrupt != NULL)
 
583
   {
 
584
      MemFree(amp->right_interrupt);
 
585
      amp->right_interrupt = NULL;
307
586
   }
308
587
   MemFree(amp);
309
588
   return NULL;
314
593
{
315
594
   if (amp == NULL)
316
595
      return;
317
 
   if (amp->left_insert != NULL)
318
 
   {
319
 
      MemFree(amp->left_insert);
320
 
      amp->left_insert = NULL;
321
 
   }
322
 
   if (amp->right_insert != NULL)
323
 
   {
324
 
      MemFree(amp->right_insert);
325
 
      amp->right_insert = NULL;
326
 
   }
327
 
   if (amp->left_unaligned != NULL)
328
 
   {
329
 
      MemFree(amp->left_unaligned);
330
 
      amp->left_unaligned = NULL;
331
 
   }
332
 
   if (amp->right_unaligned != NULL)
333
 
   {
334
 
      MemFree(amp->right_unaligned);
335
 
      amp->right_unaligned = NULL;
 
596
   if (amp->left_interrupt != NULL)
 
597
   {
 
598
      MemFree(amp->left_interrupt);
 
599
      amp->left_interrupt = NULL;
 
600
   }
 
601
   if (amp->right_interrupt != NULL)
 
602
   {
 
603
      MemFree(amp->right_interrupt);
 
604
      amp->right_interrupt = NULL;
336
605
   }
337
606
   amp->real_from = -2;
338
607
   amp->len = -2;
371
640
   MemFree(afp);
372
641
}
373
642
 
 
643
/* SECTION 1 */
 
644
static void AMSeqPieceSetFree(AMSeqPieceSetPtr s_set)
 
645
{
 
646
  AMSeqPieceSetPtr s_set_next;
 
647
  AMSeqPiecePtr s, s_next;
 
648
  
 
649
  while (s_set) {
 
650
    s = s_set->head;
 
651
    while (s) {
 
652
      s_next = s->next;
 
653
      MemFree(s);
 
654
      s = s_next;
 
655
    }
 
656
    s_set_next = s_set->next;
 
657
    MemFree(s_set);
 
658
    s_set = s_set_next;
 
659
  }
 
660
}
 
661
 
374
662
/***************************************************************************
375
663
*
376
664
*  SECTION 2: Functions used to create the indexes for parent and child
545
833
      {
546
834
         unal = FALSE;
547
835
         last = -1;
548
 
         j = i;
549
 
         while (j >= 0 && dsp->starts[dsp->dim*j+row] == -1)
550
 
         {
551
 
            j--;
552
 
         }
 
836
         j = i;  /* only blocks with sequence can have flanking unal. regions */
553
837
         if (j >= 0 && dsp->starts[dsp->dim*j+row] != -1)
554
838
         {
555
839
            if (dsp->strands[row] == Seq_strand_minus)
561
845
         {
562
846
            next = -1;
563
847
            j++;
 
848
            /* find next block of aligned sequence in this row */
564
849
            for (j; j<dsp->numseg && next == -1; j++)
565
850
            {
566
851
               if (dsp->starts[dsp->dim*j+row] != -1)
571
856
                     next = dsp->starts[dsp->dim*j+row];
572
857
               }
573
858
            }
574
 
            if (next > -1)
 
859
            if (next > -1) /* look for unaligned seq on right side of this seg */
575
860
            {
576
861
               if (next != last)
577
862
                  unal = TRUE;
885
1170
*  as a multiple alignment by AlnMgr2 functions.
886
1171
*
887
1172
***************************************************************************/
 
1173
 
888
1174
NLM_EXTERN void AlnMgr2IndexSeqAlign(SeqAlignPtr sap)
889
1175
{
 
1176
   AlnMgr2IndexSeqAlignEx(sap, TRUE);
 
1177
}
 
1178
 
 
1179
NLM_EXTERN void AlnMgr2IndexSeqAlignEx(SeqAlignPtr sap, Boolean replace_gi)
 
1180
{
890
1181
   AMAlignIndex2Ptr  amaip;
891
1182
   AMIntervalSetPtr  amint;
892
1183
   AMIntervalSetPtr  amint_head;
 
1184
   AMEdgePtr         edge;
893
1185
   AMEdgePtr         edge_head;
 
1186
   Int4              i;
894
1187
   Int4              numvertices;
895
1188
   AMVertexPtr       vertex_head;
896
1189
   AMVertexPtr       PNTR vertexarray;
897
1190
 
898
1191
   if (sap == NULL || sap->saip != NULL)
899
1192
      return;
900
 
   SAM_ReplaceGI(sap);
 
1193
   if (replace_gi) {
 
1194
     SAM_ReplaceGI(sap);
 
1195
   }
 
1196
 
901
1197
   AlnMgr2IndexLite(sap);
902
1198
   AlnMgr2DecomposeToPairwise(sap);
903
1199
   amaip = (AMAlignIndex2Ptr)(sap->saip);
915
1211
   }
916
1212
   AlnMgr2UsePrimsAlgorithm(vertexarray, numvertices, edge_head);
917
1213
   AlnMgr2BuildAlignmentFromTree(vertexarray, numvertices, edge_head, sap);
 
1214
   for (i=0; i<numvertices; i++)
 
1215
   {
 
1216
      SeqIdFree(vertexarray[i]->sip);
 
1217
      MemFree(vertexarray[i]);
 
1218
   }
918
1219
   MemFree(vertexarray);
 
1220
   while (edge_head != NULL)
 
1221
   {
 
1222
      edge = edge_head->next;
 
1223
      MemFree(edge_head);
 
1224
      edge_head = edge;
 
1225
   }
919
1226
   amaip = (AMAlignIndex2Ptr)(sap->saip);
920
1227
   amaip->alnstyle = AM2_FULLINDEX;
921
1228
}
974
1281
   MemFree(vertexarray);
975
1282
}
976
1283
 
 
1284
static int LIBCALLBACK AlnMgr2CompareByAnchor(VoidPtr ptr1, VoidPtr ptr2)
 
1285
{
 
1286
   DenseSegPtr  dsp;
 
1287
   int          ret;
 
1288
   SAIndex2Ptr  saip1;
 
1289
   SAIndex2Ptr  saip2;
 
1290
   SeqAlignPtr  sap1;
 
1291
   SeqAlignPtr  sap2;
 
1292
   SeqIdPtr     sip1;
 
1293
   SeqIdPtr     sip2;
 
1294
   Int4         start1;
 
1295
   Int4         start2;
 
1296
   Int4         stop1;
 
1297
   Int4         stop2;
 
1298
 
 
1299
   sap1 = *((SeqAlignPtr PNTR)ptr1);
 
1300
   sap2 = *((SeqAlignPtr PNTR)ptr2);
 
1301
   saip1 = (SAIndex2Ptr)(sap1->saip);
 
1302
   saip2 = (SAIndex2Ptr)(sap2->saip);
 
1303
   dsp = (DenseSegPtr)(sap1->segs);
 
1304
   if (saip1->tmp == 1)
 
1305
      sip1 = dsp->ids->next;
 
1306
   else
 
1307
      sip1 = dsp->ids;
 
1308
   dsp = (DenseSegPtr)(sap2->segs);
 
1309
   if (saip2->tmp == 1)
 
1310
      sip2 = dsp->ids->next;
 
1311
   else
 
1312
      sip2 = dsp->ids;
 
1313
   ret = AlnMgr2OrderSeqIds(sip1, sip2);
 
1314
   if (ret != 0)
 
1315
      return ret;
 
1316
   /* these share both ids -- put best first */
 
1317
   if (saip1->score == 0)
 
1318
      saip1->score = AlnMgr2ComputeScoreForSeqAlign(sap1);
 
1319
   if (saip2->score == 0)
 
1320
      saip2->score = AlnMgr2ComputeScoreForSeqAlign(sap2);
 
1321
   if (saip1->score > saip2->score)
 
1322
      return -1;
 
1323
   else if (saip1->score < saip2->score)
 
1324
      return 1;
 
1325
   AlnMgr2GetNthSeqRangeInSA(sap1, saip1->tmp, &start1, &stop1);
 
1326
   AlnMgr2GetNthSeqRangeInSA(sap2, saip2->tmp, &start2, &stop2);
 
1327
   if (start1 < start2)
 
1328
      return -1;
 
1329
   else if (start1 > start2)
 
1330
      return 1;
 
1331
   else if (stop1 > stop2)
 
1332
      return -1;
 
1333
   else if (stop1 < stop2)
 
1334
      return 1;
 
1335
   return 0;
 
1336
}
 
1337
 
 
1338
/* SECTION 2c */
 
1339
NLM_EXTERN Boolean AlnMgr2IndexAsRows(SeqAlignPtr sap, Uint1 strand, Boolean truncate)
 
1340
{
 
1341
   AMAlignIndex2Ptr  amaip;
 
1342
   DenseSegPtr       dsp;
 
1343
   DenseSegPtr       dsp_tmp;
 
1344
   Boolean           found;
 
1345
   Int4              i;
 
1346
   Boolean           impossible;
 
1347
   Int4              numsaps;
 
1348
   SAIndex2Ptr       saip;
 
1349
   SeqAlignPtr       salp;
 
1350
   SeqAlignPtr       sap_head;
 
1351
   SeqAlignPtr       sap_prev;
 
1352
   SeqAlignPtr       sap_tmp;
 
1353
   SeqAlignPtr       PNTR saparray;
 
1354
   SeqAlignPtr       set_head;
 
1355
   SeqAlignPtr       set_prev;
 
1356
   SeqIdPtr          sharedsip;
 
1357
   SeqIdPtr          sip;
 
1358
   SeqIdPtr          sip_next;
 
1359
   SeqIdPtr          sip_tmp;
 
1360
   Int4              tmp;
 
1361
 
 
1362
   if (sap == NULL)
 
1363
      return FALSE;
 
1364
   if (sap->saip != NULL)
 
1365
      AMAlignIndexFreeEitherIndex(sap);
 
1366
   AlnMgr2IndexLite(sap);
 
1367
   AlnMgr2DecomposeToPairwise(sap);
 
1368
   /* need to figure out which row is shared by all saps */
 
1369
   sap_tmp = (SeqAlignPtr)(sap->segs);
 
1370
   dsp = (DenseSegPtr)(sap_tmp->segs);
 
1371
   sip = dsp->ids;
 
1372
   found = FALSE;
 
1373
   while (!found && sip != NULL)
 
1374
   {
 
1375
      sap_tmp = (SeqAlignPtr)(sap->segs);
 
1376
      sip_next = sip->next;
 
1377
      sip->next = NULL;
 
1378
      impossible = FALSE;
 
1379
      while (!impossible && sap_tmp != NULL)
 
1380
      {
 
1381
         dsp_tmp = (DenseSegPtr)(sap_tmp->segs);
 
1382
         if (AlnMgr2SeqIdListsOverlap(sip, dsp_tmp->ids) == NULL)
 
1383
            impossible = TRUE;
 
1384
         sap_tmp = sap_tmp->next;
 
1385
      }
 
1386
      sip->next = sip_next;
 
1387
      if (!impossible) /* found one that matched a row in every alignment */
 
1388
         found = TRUE;
 
1389
      else
 
1390
         sip = sip_next;
 
1391
   }
 
1392
   if (!found) /* didn't find a seqid that was contained in all alignments */
 
1393
      return FALSE;
 
1394
   /* mark the shared row to make things easier */
 
1395
   sharedsip = SeqIdDup(sip);
 
1396
   sap_tmp = (SeqAlignPtr)(sap->segs);
 
1397
   i = 0;
 
1398
   while (sap_tmp != NULL)
 
1399
   {
 
1400
      saip = (SAIndex2Ptr)(sap_tmp->saip);
 
1401
      dsp_tmp = (DenseSegPtr)(sap_tmp->segs);
 
1402
      if (SeqIdComp(sharedsip, dsp_tmp->ids) == SIC_YES)
 
1403
         saip->tmp = 1;
 
1404
      else
 
1405
         saip->tmp = 2;
 
1406
      sap_tmp = sap_tmp->next;
 
1407
      i++;
 
1408
   }
 
1409
   saparray = (SeqAlignPtr PNTR)MemNew(i*sizeof(SeqAlignPtr));
 
1410
   sap_tmp = (SeqAlignPtr)(sap->segs);
 
1411
   i = 0;
 
1412
   while (sap_tmp != NULL)
 
1413
   {
 
1414
      saparray[i] = sap_tmp;
 
1415
      i++;
 
1416
      sap_tmp = sap_tmp->next;
 
1417
   }
 
1418
   numsaps = i;
 
1419
   HeapSort(saparray, i, sizeof(SeqAlignPtr), AlnMgr2CompareByAnchor);
 
1420
   /* now each clump of alignments is a row -- need to eliminate overlaps next */
 
1421
   sip = NULL;
 
1422
   i = 0;
 
1423
   sap_head = sap_prev = NULL;
 
1424
   while (i<numsaps)
 
1425
   {
 
1426
      saparray[i]->next = NULL;
 
1427
      set_head = set_prev = saparray[i];
 
1428
      saip = (SAIndex2Ptr)(saparray[i]->saip);
 
1429
      sip = AlnMgr2GetNthSeqIdPtr(saparray[i], 3-saip->tmp); /* get other seqid */
 
1430
      i++;
 
1431
      if (i<numsaps)
 
1432
         sip_tmp = AlnMgr2GetNthSeqIdPtr(saparray[i], 3-saip->tmp);
 
1433
      while (i<numsaps && SeqIdComp(sip, sip_tmp) == SIC_YES)
 
1434
      {
 
1435
         set_prev->next = saparray[i];
 
1436
         set_prev = saparray[i];
 
1437
         saparray[i]->next = NULL;
 
1438
         i++;
 
1439
         SeqIdFree(sip_tmp);
 
1440
         if (i<numsaps)
 
1441
            sip_tmp = AlnMgr2GetNthSeqIdPtr(saparray[i], 3-saip->tmp);
 
1442
      }
 
1443
      AlnMgr2IndexLite(set_head);
 
1444
      if (!truncate)
 
1445
         AlnMgr2RemoveInconsistentAlnsFromSet(set_head, 0);
 
1446
      else
 
1447
         AlnMgr2RemoveInconsistentAlnsFromSet(set_head, -1);
 
1448
      sap_tmp = (SeqAlignPtr)(set_head->segs);
 
1449
      while (sap_tmp != NULL)
 
1450
      {
 
1451
         saip = (SAIndex2Ptr)(sap_tmp->saip);
 
1452
         dsp_tmp = (DenseSegPtr)(sap_tmp->segs);
 
1453
         if (SeqIdComp(sharedsip, dsp_tmp->ids) == SIC_YES)
 
1454
            saip->tmp = 1;
 
1455
         else
 
1456
            saip->tmp = 2;
 
1457
         sap_tmp = sap_tmp->next;
 
1458
      }
 
1459
      if (sap_head != NULL)
 
1460
         sap_prev->next = set_head;
 
1461
      else
 
1462
         sap_head = sap_prev = set_head;
 
1463
      while (sap_prev->next != NULL)
 
1464
      {
 
1465
         sap_prev = sap_prev->next;
 
1466
      }
 
1467
      sap_prev->next = NULL;
 
1468
   }
 
1469
   /* now we have lots of freed pointers sitting in the array */
 
1470
   MemFree(saparray);
 
1471
   saparray = NULL;
 
1472
   /* sap_head is the head of a chain of LITE-indexed alignments, each of which is one row */
 
1473
   /* first make sure that the shared row is on the requested strand */
 
1474
   sap_tmp = sap_head;
 
1475
   if (strand == Seq_strand_both || strand == Seq_strand_unknown || strand == 0)
 
1476
      strand = Seq_strand_plus;
 
1477
   while (sap_tmp != NULL)
 
1478
   {
 
1479
      salp = (SeqAlignPtr)(sap_tmp->segs);
 
1480
      saip = (SAIndex2Ptr)(salp->saip);
 
1481
      /* strand is same for all children */
 
1482
      if (AlnMgr2GetNthStrand(salp, saip->tmp) != strand)
 
1483
      {
 
1484
         SeqAlignListReverseStrand(salp);
 
1485
         while (salp != NULL)
 
1486
         {
 
1487
            saip = (SAIndex2Ptr)salp->saip;
 
1488
            tmp = saip->tmp;
 
1489
            SAIndex2Free2(salp->saip);
 
1490
            salp->saip = NULL;
 
1491
            AlnMgr2IndexSingleChildSeqAlign(salp);
 
1492
            saip = (SAIndex2Ptr)salp->saip;
 
1493
            saip->tmp = tmp;
 
1494
            salp = salp->next;
 
1495
         }
 
1496
      }
 
1497
      sap_tmp = sap_tmp->next;
 
1498
   }
 
1499
   sap_tmp = sap_head;
 
1500
   sap->segs = NULL;
 
1501
   AMAlignIndex2Free2(sap->saip);
 
1502
   sap->saip = (SeqAlignIndexPtr)AMAlignIndex2New();
 
1503
   amaip = (AMAlignIndex2Ptr)(sap->saip);
 
1504
   amaip->alnstyle = AM2_FULLINDEX;
 
1505
   set_head = set_prev = NULL;
 
1506
   while (sap_tmp != NULL)
 
1507
   {
 
1508
      salp = (SeqAlignPtr)(sap_tmp->segs);
 
1509
      while (salp != NULL)
 
1510
      {
 
1511
         AlnMgr2AddInNewPairwiseSA(sap, salp);
 
1512
         if (set_head != NULL)
 
1513
         {
 
1514
            set_prev->next = salp;
 
1515
            set_prev = salp;
 
1516
         } else
 
1517
            set_head = set_prev = salp;
 
1518
         salp = salp->next;
 
1519
      }
 
1520
      sap_tmp->segs = NULL;
 
1521
      sap_tmp = sap_tmp->next;
 
1522
   }
 
1523
   AlnMgr2CondenseColumns((DenseSegPtr)(amaip->sharedaln->segs));
 
1524
   AlnMgr2IndexSingleChildSeqAlign(amaip->sharedaln); 
 
1525
   set_prev->next = NULL;
 
1526
   sap->segs = (Pointer)(set_head);
 
1527
   SeqAlignListFree(sap_head);
 
1528
   SeqIdFree(sharedsip);
 
1529
   return TRUE;
 
1530
}
 
1531
 
977
1532
/* SECTION 2c */
978
1533
/***************************************************************************
979
1534
*
1066
1621
            for (j=0; j<dsp->numseg; j++)
1067
1622
            {
1068
1623
               dsp->lens[j] = dsp_orig->lens[j];
1069
 
               dsp->starts[2*j] = dsp_orig->starts[2*j];
1070
 
               dsp->starts[2*j+1] = dsp_orig->starts[2*j+i-1];
1071
 
               dsp->strands[2*j] = dsp_orig->strands[2*j];
1072
 
               dsp->strands[2*j+1] = dsp_orig->strands[2*j+i-1];
 
1624
               dsp->starts[2*j] = dsp_orig->starts[dsp_orig->dim*j];
 
1625
               dsp->starts[2*j+1] = dsp_orig->starts[dsp_orig->dim*j+i-1];
 
1626
               dsp->strands[2*j] = dsp_orig->strands[dsp_orig->dim*j];
 
1627
               dsp->strands[2*j+1] = dsp_orig->strands[dsp_orig->dim*j+i-1];
1073
1628
            }
1074
1629
            salp_new = SeqAlignNew();
1075
1630
            salp_new->dim = 2;
1125
1680
   SeqIdPtr         sip12;
1126
1681
   SeqIdPtr         sip21;
1127
1682
   SeqIdPtr         sip22;
1128
 
   Boolean          start;
1129
1683
   Int4             start11;
1130
1684
   Int4             start12;
1131
1685
   Int4             start21;
1197
1751
         }
1198
1752
      }
1199
1753
   }
 
1754
   MemFree(tossed);
1200
1755
}
1201
1756
 
1202
1757
/* SECTION 2c */
1237
1792
   sap2 = *((SeqAlignPtr PNTR) ptr2);
1238
1793
   sip1 = AlnMgr2GetNthSeqIdPtr(sap1, 1);
1239
1794
   sip2 = AlnMgr2GetNthSeqIdPtr(sap2, 1);
1240
 
   ret = (SAM_OrderSeqID(sip1, sip2));
 
1795
   ret = (AlnMgr2OrderSeqIds(sip1, sip2));
 
1796
   SeqIdFree(sip1);
 
1797
   SeqIdFree(sip2);
1241
1798
   if (ret != 0)
1242
1799
      return ret;
1243
1800
   saip1 = (SAIndex2Ptr)(sap1->saip);
1945
2502
   AMQueuePtr       q_prev;
1946
2503
 
1947
2504
   amaip = (AMAlignIndex2Ptr)(sap->saip);
1948
 
   AlnMgr2AddInNewSA(sap, edge_head->sap);
 
2505
   AlnMgr2AddInNewPairwiseSA(sap, edge_head->sap);
1949
2506
   edge_head->aligned = TRUE;
1950
2507
   q_head = (AMQueuePtr)MemNew(sizeof(AMQueue));
1951
2508
   q_head->vertex = AlnMgr2GetBetterVertex(vertexarray, edge_head);
1974
2531
               /* if the edge is used in the tree but not yet aligned, and it's adjacent, align it */
1975
2532
               if (edge->aligned == FALSE && edge->used == AM_USED && ((AlnMgr2SameSeq(vertexarray[edge->vertex1], q_head->vertex) && AlnMgr2SameSeq(vertexarray[edge->vertex2], adj)) || (AlnMgr2SameSeq(vertexarray[edge->vertex1], adj) && AlnMgr2SameSeq(vertexarray[edge->vertex2], q_head->vertex))))
1976
2533
               {
1977
 
                  AlnMgr2AddInNewSA(sap, edge->sap);
1978
 
                  edge->aligned = TRUE;
 
2534
                 AlnMgr2AddInNewPairwiseSA(sap, edge->sap);
 
2535
                 edge->aligned = TRUE;
1979
2536
               }
1980
2537
               edge = edge->next;
1981
2538
            }
1999
2556
            {
2000
2557
               q_head = (AMQueuePtr)MemNew(sizeof(AMQueue));
2001
2558
               q_head->vertex = AlnMgr2GetBetterVertex(vertexarray, edge);
2002
 
               q_head->vertex->visited = TRUE;
 
2559
               vertexarray[edge->vertex1]->visited = vertexarray[edge->vertex2]->visited = TRUE;
2003
2560
            }
2004
2561
            edge = edge->next;
2005
2562
         }
2011
2568
      vertexarray[j]->next = vertexarray[j+1];
2012
2569
      vertexarray[j+1]->next = NULL;
2013
2570
   }
 
2571
   AlnMgr2CondenseColumns((DenseSegPtr)(amaip->sharedaln->segs));
 
2572
   AlnMgr2IndexSingleChildSeqAlign(amaip->sharedaln); 
2014
2573
}
2015
2574
 
2016
2575
/* SECTION 2c */
2058
2617
}
2059
2618
 
2060
2619
/* SECTION 2c */
 
2620
 
 
2621
static Boolean AlnMgr2GetFirstRowForSeqId(
 
2622
  DenseSegPtr dsp,
 
2623
  SeqIdPtr sip,
 
2624
  Uint1 strand,
 
2625
  Int4Ptr row_curr,
 
2626
  SeqIdPtr PNTR sip_curr)
 
2627
{
 
2628
  Boolean found = FALSE;
 
2629
 
 
2630
  while (*sip_curr) {
 
2631
    (*row_curr)++;
 
2632
    if (SeqIdComp(sip, *sip_curr) == SIC_YES && 
 
2633
        strand == dsp->strands[*row_curr]) {
 
2634
      found = TRUE;
 
2635
    }
 
2636
    *sip_curr = (*sip_curr)->next;
 
2637
    if (found) return TRUE;
 
2638
  }
 
2639
  return FALSE;
 
2640
}
 
2641
 
 
2642
 
 
2643
static AMSeqPieceSetPtr AlnMgr2CreateSeqPieceSet(DenseSegPtr dsp, Int4 row)
 
2644
{
 
2645
  AMSeqPieceSetPtr s_set = (AMSeqPieceSetPtr)MemNew(sizeof(AMSeqPieceSet));
 
2646
  AMSeqPiecePtr s = (AMSeqPiecePtr)MemNew(sizeof(AMSeqPiece));
 
2647
  s->beg = -1;
 
2648
  s->end = -1;
 
2649
  s->seg = -1;
 
2650
  s->pos = row - dsp->dim;
 
2651
  s->set = s_set;
 
2652
  s->prev = NULL;
 
2653
  s->next = NULL;
 
2654
  s->left = -1;
 
2655
  s->right = -1;
 
2656
  s->orig_left = -2;
 
2657
  s->orig_right = -2;
 
2658
  s->aligned = FALSE;
 
2659
  s->alt_dsp = NULL;
 
2660
  s->alt_seg = -1;
 
2661
  s->alt_pos = -1;
 
2662
 
 
2663
  s->next = NULL;
 
2664
 
 
2665
  s_set->dsp = dsp;
 
2666
  s_set->row = row;
 
2667
  s_set->row2 = -1;
 
2668
  s_set->alt_row = -1;
 
2669
  s_set->alt_row2 = -1;
 
2670
  s_set->head = s;
 
2671
  s_set->tail = s;
 
2672
  s_set->max_pos = dsp->dim * dsp->numseg;
 
2673
  s_set->strand = dsp->strands[row];
 
2674
  s_set->plus = s_set->strand != Seq_strand_minus;
 
2675
  s_set->next = NULL;
 
2676
 
 
2677
  return s_set;
 
2678
}
 
2679
 
 
2680
static AMSeqPiecePtr AlnMgr2GetNextSeqPiece(AMSeqPiecePtr s)
 
2681
{
 
2682
  DenseSegPtr dsp;
 
2683
  Int4 max_pos;
 
2684
  AMSeqPiecePtr s_new;
 
2685
 
 
2686
  dsp = s->set->dsp;
 
2687
  max_pos = s->set->max_pos;
 
2688
 
 
2689
  if (s->pos < max_pos) {
 
2690
    s_new = (AMSeqPiecePtr)MemNew(sizeof(AMSeqPiece));
 
2691
    s_new->pos = s->pos + dsp->dim;
 
2692
    s_new->seg = s->seg + 1;
 
2693
    s_new->set = s->set;
 
2694
    s_new->prev = s;
 
2695
    s = s->next = s_new;
 
2696
    s->set->tail = s;
 
2697
 
 
2698
    s->next = NULL;
 
2699
 
 
2700
    /* initialize the following */
 
2701
    s->left = -1;
 
2702
    s->right = -1;
 
2703
    s->aligned = FALSE;
 
2704
    s->alt_dsp = NULL;
 
2705
    s->alt_seg = -1;
 
2706
    s->alt_pos = -1;
 
2707
    s->orig_left = -2;
 
2708
    s->orig_right = -2;
 
2709
 
 
2710
    /* find the beg and end */
 
2711
    while (s->pos < max_pos) {
 
2712
      if (dsp->starts[s->pos] != -1) {
 
2713
        s->beg = s->end = dsp->starts[s->pos];
 
2714
        if (s->set->plus) {
 
2715
          s->end += dsp->lens[s->seg] - 1;
 
2716
        } else {
 
2717
          s->beg += dsp->lens[s->seg] - 1;
 
2718
        }
 
2719
        return s;
 
2720
      } else {
 
2721
        s->seg++;
 
2722
        s->pos += dsp->dim;
 
2723
      }
 
2724
    }
 
2725
    s->beg = -1;
 
2726
    s->end = -1;
 
2727
    return s;
 
2728
  }
 
2729
  return NULL;
 
2730
}
 
2731
 
 
2732
static AMSeqPiecePtr AlnMgr2GetNextLimitedSeqPiece(
 
2733
  AMSeqPiecePtr s,
 
2734
  AMSeqPiecePtr right) 
 
2735
{
 
2736
  DenseSegPtr dsp;
 
2737
  Int4 new_pos, new_seg, max_pos, max_seg;
 
2738
  AMSeqPiecePtr s_new;
 
2739
 
 
2740
  AMSeqPiecePtr left = right->prev;
 
2741
 
 
2742
  dsp = s->set->dsp;
 
2743
  max_pos = s->set->max_pos;
 
2744
  max_seg = right->seg;
 
2745
  new_pos = s->pos + dsp->dim;
 
2746
  new_seg = s->seg + 1;
 
2747
 
 
2748
  while (new_pos < max_pos && new_seg <= max_seg) {
 
2749
    if (dsp->starts[new_pos] != -1) {
 
2750
      s_new = (AMSeqPiecePtr)MemNew(sizeof(AMSeqPiece));
 
2751
      s_new->pos = new_pos;
 
2752
      s_new->seg = new_seg;
 
2753
      s_new->set = s->set;
 
2754
      s_new->next = NULL;
 
2755
      s_new->prev = s;
 
2756
      s = s->next = s_new;
 
2757
      s->set->tail = s;
 
2758
      s->beg = s->end = dsp->starts[s->pos];
 
2759
      if (s->set->plus) {
 
2760
        s->end += dsp->lens[s->seg] - 1;
 
2761
      } else {
 
2762
        s->beg += dsp->lens[s->seg] - 1;
 
2763
      }
 
2764
      /* aligned to a sequence in anchor or not */
 
2765
      if (s->seg == right->seg) {
 
2766
        s->aligned = TRUE;
 
2767
        s->left = right->beg;
 
2768
        s->right = right->end;
 
2769
      } else {
 
2770
        s->aligned = FALSE;
 
2771
        s->left = left->end;
 
2772
        s->right = right->beg;
 
2773
      }
 
2774
      /* these are not yet used */
 
2775
      s->orig_left = -2;
 
2776
      s->orig_right = -2;
 
2777
      s->alt_dsp = NULL;
 
2778
      s->alt_seg = -1;
 
2779
      s->alt_pos = -1;
 
2780
      return s;
 
2781
    }
 
2782
    new_pos += dsp->dim;
 
2783
    new_seg++;
 
2784
  }
 
2785
  return NULL;
 
2786
}
 
2787
 
 
2788
static Boolean AlnMgr2AddSeqPiece(
 
2789
  AMSeqPieceSetPtr set,
 
2790
  AMSeqPiecePtr what)
 
2791
{
 
2792
  AMSeqPiecePtr s;
 
2793
  DenseSegPtr dsp = set->dsp;
 
2794
  DenseSegPtr alt_dsp = what->set->dsp;
 
2795
 
 
2796
  s = (AMSeqPiecePtr)MemNew(sizeof(AMSeqPiece));
 
2797
  s->beg = what->beg;
 
2798
  s->end = what->end;
 
2799
 
 
2800
  if (alt_dsp == dsp) {
 
2801
    s->seg = what->seg;
 
2802
    s->pos = what->pos;
 
2803
    s->alt_dsp = NULL;
 
2804
    s->alt_seg = -1;
 
2805
    s->alt_pos = -1;
 
2806
  } else {
 
2807
    s->seg = -1;
 
2808
    s->pos = -1;
 
2809
    s->alt_dsp = alt_dsp;
 
2810
    s->alt_seg = what->seg;
 
2811
    s->alt_pos = what->pos;
 
2812
  }        
 
2813
  s->left = what->left;
 
2814
  s->right = what->right;
 
2815
  s->orig_left = what->orig_left;
 
2816
  s->orig_right = what->orig_right;
 
2817
  s->aligned = what->aligned;
 
2818
  s->set = set;
 
2819
  s->next = NULL;
 
2820
  if (s->prev = set->tail) {
 
2821
    s->prev->next = s;
 
2822
  }
 
2823
  set->tail = s;
 
2824
}
 
2825
 
 
2826
static Boolean AlnMgr2InsertSeqPiece(
 
2827
  AMSeqPiecePtr where,
 
2828
  AMSeqPiecePtr what,
 
2829
  Int4 end) 
 
2830
{
 
2831
  AMSeqPiecePtr s;
 
2832
  DenseSegPtr dsp = where->set->dsp;
 
2833
  DenseSegPtr alt_dsp = what->set->dsp;
 
2834
 
 
2835
 
 
2836
  s = (AMSeqPiecePtr)MemNew(sizeof(AMSeqPiece));
 
2837
  s->beg = what->beg;
 
2838
  s->end = end;
 
2839
 
 
2840
  if (where->beg == what->beg) {
 
2841
    s->seg = where->seg;
 
2842
    s->pos = where->pos;
 
2843
    where->beg = end + (where->set->plus? 1 : -1);
 
2844
    if (alt_dsp == dsp) {
 
2845
      s->alt_dsp = NULL;
 
2846
      s->alt_seg = -1;
 
2847
      s->alt_pos = -1;
 
2848
    } else {
 
2849
      s->alt_dsp = alt_dsp;
 
2850
      s->alt_seg = what->seg;
 
2851
      s->alt_pos = what->pos;
 
2852
    }
 
2853
  } else {
 
2854
    if (alt_dsp == dsp) {
 
2855
      s->seg = what->seg;
 
2856
      s->pos = what->pos;
 
2857
      s->alt_dsp = NULL;
 
2858
      s->alt_seg = -1;
 
2859
      s->alt_pos = -1;
 
2860
    } else {
 
2861
      s->seg = -1;
 
2862
      s->pos = -1;
 
2863
      s->alt_dsp = alt_dsp;
 
2864
      s->alt_seg = what->seg;
 
2865
      s->alt_pos = what->pos;
 
2866
    }        
 
2867
  }
 
2868
  s->left = what->left;
 
2869
  s->right = what->right;
 
2870
  s->orig_left = what->orig_left;
 
2871
  s->orig_right = what->orig_right;
 
2872
  s->aligned = what->aligned;
 
2873
  s->set = where->set;
 
2874
  s->next = where;
 
2875
  if (s->prev = where->prev) {
 
2876
    if (s->prev) {
 
2877
      s->prev->next = s;
 
2878
    } else {
 
2879
      if (s->set->head == where) {
 
2880
        s->set->head = s;
 
2881
      }
 
2882
    }
 
2883
    where->prev = s;
 
2884
  }
 
2885
}
 
2886
 
 
2887
static void AlnMgr2CopySeg(
 
2888
  DenseSegPtr DSP,
 
2889
  Int4 PNTR SEG_ptr,
 
2890
  Int4 PNTR POS_ptr,
 
2891
  DenseSegPtr Dsp,
 
2892
  Int4 PNTR Seg_ptr,
 
2893
  Int4 PNTR Pos_ptr,
 
2894
  AMSeqPiecePtr PNTR s_ptr)
 
2895
{
 
2896
  Int4 i, rdelta, ldelta, POS, Pos, max_Pos, pos2, alt_pos2, SEG, Seg, 
 
2897
    beg, end;
 
2898
  AMSeqPiecePtr s;
 
2899
  Boolean plus;
 
2900
 
 
2901
  POS = *POS_ptr; Pos = *Pos_ptr;
 
2902
  SEG = *SEG_ptr; Seg = *Seg_ptr;
 
2903
  s = *s_ptr;
 
2904
 
 
2905
  if (s->set->row != s->set->row2) { /* if not a B */
 
2906
    if (!(s->next)) {
 
2907
      *s_ptr = NULL;
 
2908
      return; /* skip the last A */
 
2909
    }
 
2910
  }
 
2911
 
 
2912
  max_Pos = POS+Dsp->dim;
 
2913
 
 
2914
  DSP->lens[SEG] = ABS(s->end - s->beg) + 1;
 
2915
  
 
2916
  if (s->set->dsp != Dsp) { /* the extra row for the non-anchor seq */
 
2917
    for (i = 0; POS < max_Pos; POS++, i++) {
 
2918
      DSP->starts[POS] = -1;
 
2919
      DSP->strands[POS] = Dsp->strands[i];
 
2920
    }
 
2921
    DSP->starts[POS] = MIN(s->beg, s->end);
 
2922
    DSP->strands[POS] = s->set->strand;
 
2923
    POS++;
 
2924
 
 
2925
  } else { /* not dealing with the extra row itself */
 
2926
 
 
2927
    if (s->pos >= 0 && s->set->row != s->set->row2) { /* Dsp involved */
 
2928
      beg = end = s->set->dsp->starts[s->pos];
 
2929
      if (s->set->plus) {
 
2930
        end += s->set->dsp->lens[s->seg]-1;
 
2931
      } else {
 
2932
        beg += s->set->dsp->lens[s->seg]-1;
 
2933
      }
 
2934
      if (ldelta = ABS(s->beg - beg)) {
 
2935
        /* need to "continue" from the orig seg */
 
2936
        Pos = s->pos - s->set->row;
 
2937
        Seg = s->seg;
 
2938
      }
 
2939
      rdelta = ABS(end - s->end);
 
2940
 
 
2941
      for (; POS < max_Pos; POS++, Pos++) {
 
2942
        DSP->strands[POS] = Dsp->strands[Pos];
 
2943
        plus = DSP->strands[POS] != Seq_strand_minus;
 
2944
        if (Dsp->starts[Pos] != -1) {
 
2945
          DSP->starts[POS] = Dsp->starts[Pos] + (plus ? ldelta : rdelta);
 
2946
        } else {
 
2947
          DSP->starts[POS] = -1;
 
2948
        }
 
2949
      }
 
2950
      if (ldelta) {
 
2951
        /* restore these */
 
2952
        Pos = *Pos_ptr;
 
2953
        Seg = *Seg_ptr;
 
2954
      } else {
 
2955
        Seg++;
 
2956
      }
 
2957
 
 
2958
      if (s->alt_dsp) { /* dsp involved too */
 
2959
        alt_pos2 = 
 
2960
          s->alt_pos + s->set->alt_row2 - s->set->alt_row;
 
2961
        beg = end = s->alt_dsp->starts[s->alt_pos];
 
2962
        if (s->alt_dsp->strands[s->alt_pos] == Seq_strand_minus) {
 
2963
          beg += s->alt_dsp->lens[s->alt_seg]-1;
 
2964
        } else {
 
2965
          end += s->alt_dsp->lens[s->alt_seg]-1;
 
2966
        }
 
2967
        ldelta = ABS(s->beg - beg);
 
2968
        rdelta = ABS(end - s->end);
 
2969
 
 
2970
        if (s->set->row2 != -1) { /* 2nd row merged*/
 
2971
          pos2 = POS - DSP->dim + s->set->row2;
 
2972
        } else { /* extra row */
 
2973
          pos2 = POS;
 
2974
          POS++;
 
2975
        }
 
2976
        DSP->strands[pos2] = s->alt_dsp->strands[alt_pos2];
 
2977
        plus = DSP->strands[pos2] != Seq_strand_minus;
 
2978
        if (s->alt_dsp->starts[alt_pos2] != -1) {
 
2979
          DSP->starts[pos2] = s->alt_dsp->starts[alt_pos2] + 
 
2980
            (plus ? ldelta : rdelta);
 
2981
        } else {
 
2982
          DSP->starts[pos2] = -1;
 
2983
        }
 
2984
      } else { /* dsp not involved */
 
2985
        if (s->set->row2 == -1) { /* 2nd row not merged */
 
2986
          DSP->starts[POS] = -1;
 
2987
          DSP->strands[POS] = 
 
2988
            s->set->alt_dsp->strands[s->set->alt_row2];
 
2989
          POS++;
 
2990
        }
 
2991
      }
 
2992
    } else { /* Dsp not involved */
 
2993
      for (i = 0; POS < max_Pos; POS++, i++) {
 
2994
        DSP->starts[POS] = -1;
 
2995
        DSP->strands[POS] = Dsp->strands[i];
 
2996
      }
 
2997
      if (s->set->row == s->set->row2) { /* if a B */
 
2998
        if (!(s->alt_dsp)) {
 
2999
          Pos += s->set->dsp->dim; /* move to next seg */
 
3000
          Seg++;
 
3001
        }
 
3002
      } else { /* not a B */
 
3003
        alt_pos2 = 
 
3004
          s->alt_pos + s->set->alt_row2 - s->set->alt_row;
 
3005
 
 
3006
        beg = end = s->alt_dsp->starts[s->alt_pos];
 
3007
        if (s->alt_dsp->strands[s->alt_pos] == Seq_strand_minus) {
 
3008
          beg += s->alt_dsp->lens[s->alt_seg]-1;
 
3009
        } else {
 
3010
          end += s->alt_dsp->lens[s->alt_seg]-1;
 
3011
        }
 
3012
        ldelta = ABS(s->beg - beg);
 
3013
        rdelta = ABS(end - s->end);
 
3014
 
 
3015
        if (s->set->row2 != -1) { /* merged row2 */
 
3016
          pos2 = POS - DSP->dim + s->set->row2;
 
3017
        } else {
 
3018
          pos2 = POS;
 
3019
          POS++;
 
3020
        }
 
3021
        DSP->strands[pos2] = s->alt_dsp->strands[alt_pos2];
 
3022
        plus = DSP->strands[pos2] != Seq_strand_minus;
 
3023
        if (s->alt_dsp->starts[alt_pos2] != -1) {
 
3024
          DSP->starts[pos2] = s->alt_dsp->starts[alt_pos2] + 
 
3025
            (plus ? ldelta : rdelta);
 
3026
        } else {
 
3027
          DSP->starts[pos2] = -1;
 
3028
        }
 
3029
      }
 
3030
      DSP->starts[POS + s->set->row - DSP->dim] = MIN(s->beg, s->end);
 
3031
    }
 
3032
  }
 
3033
  (*SEG_ptr)++;
 
3034
  *Seg_ptr = Seg;
 
3035
  *s_ptr = (*s_ptr)->next;
 
3036
  *POS_ptr = POS;
 
3037
  *Pos_ptr = Pos;
 
3038
}
 
3039
 
 
3040
NLM_EXTERN void AlnMgr2AddInNewPairwiseSA(SeqAlignPtr parent, SeqAlignPtr sap)
 
3041
{
 
3042
  AMAlignIndex2Ptr amaip;
 
3043
  DenseSegPtr dsp, Dsp, DSP;
 
3044
  Int4 Seg, SEG;
 
3045
  Int4 Pos, POS, max_POS;
 
3046
  Int4 A_end, B_beg;
 
3047
  Int4 anchor, Anchor;
 
3048
  Int4 row;
 
3049
  SeqIdPtr sip, extra_sip;
 
3050
  AMSeqPieceSetPtr a_set, A_set, b_set, B_set_head, B_set;
 
3051
  AMSeqPiecePtr a, A, b, B;
 
3052
  Boolean conflict;
 
3053
  Boolean a_plus, b_plus;
 
3054
  Int4 upper_limit;
 
3055
  Int4 extra_segs;
 
3056
 
 
3057
  dsp = (DenseSegPtr)(sap->segs);
 
3058
  if (dsp->dim != 2) {
 
3059
    if (dsp->dim == 0) {
 
3060
      dsp->dim = 2; /* set to default */
 
3061
    } else {
 
3062
      ErrPostEx(SEV_ERROR, 0,0,
 
3063
                "AlnMgr2AddInNewPairwiseSA: dsp->dim (=%d) should be 2.",
 
3064
                dsp->dim);
 
3065
      return;
 
3066
    }
 
3067
  }
 
3068
  if (dsp->numseg < 1) {
 
3069
    ErrPostEx(SEV_ERROR, 0,0,
 
3070
              "AlnMgr2AddInNewPairwiseSA: dsp->numseg (=%d) should be > 0.",
 
3071
              dsp->numseg);
 
3072
    return;
 
3073
  }
 
3074
 
 
3075
  amaip = (AMAlignIndex2Ptr)(parent->saip);
 
3076
  if (amaip->sharedaln == NULL) {/* first alignment to be added */
 
3077
    SeqAlignPtr salp;
 
3078
    Int4 i;
 
3079
 
 
3080
    salp = SeqAlignDup(sap);
 
3081
    AlnMgr2IndexSingleChildSeqAlign(salp);
 
3082
    amaip->sharedaln = salp;
 
3083
    amaip->numrows = dsp->dim;
 
3084
    sip = dsp->ids;
 
3085
    amaip->ids = (SeqIdPtr PNTR)MemNew((dsp->dim)*sizeof(SeqIdPtr));
 
3086
    i = 0;
 
3087
    while (sip != NULL) {
 
3088
      amaip->ids[i] = SeqIdDup(sip);
 
3089
      sip = sip->next;
 
3090
      i++;
 
3091
    }
 
3092
    MemFree(amaip->saps);
 
3093
    amaip->saps = (SeqAlignPtr PNTR)MemNew(sizeof(SeqAlignPtr));
 
3094
    amaip->saps[0] = sap;
 
3095
    amaip->numsaps = 1;
 
3096
    MemFree(amaip->aligned);
 
3097
    amaip->aligned =  (Boolean PNTR) MemNew(sizeof(Boolean));
 
3098
    amaip->aligned[0] = TRUE;
 
3099
 
 
3100
    return;
 
3101
  }
 
3102
 
 
3103
  /* add the new sap */
 
3104
  amaip->numsaps++;
 
3105
  amaip->saps = (SeqAlignPtr PNTR) MemMore
 
3106
    (amaip->saps, amaip->numsaps*sizeof(SeqAlignPtr));
 
3107
  amaip->saps[amaip->numsaps-1] = sap;
 
3108
  amaip->aligned = (Boolean PNTR) MemMore
 
3109
    (amaip->aligned, (amaip->numsaps)*sizeof(Boolean));
 
3110
  amaip->aligned[amaip->numsaps-1] = TRUE;
 
3111
 
 
3112
  Dsp = (DenseSegPtr)(amaip->sharedaln->segs);
 
3113
 
 
3114
  AlnMgr2GetFirstSharedRow(amaip->sharedaln, sap, &Anchor, &anchor);
 
3115
 
 
3116
  {{ /* make sure the shared rows are on the same strand */
 
3117
    Uint1 Strand, strand;
 
3118
 
 
3119
    Strand = AlnMgr2GetNthStrand(amaip->sharedaln, Anchor);
 
3120
    if (Strand == Seq_strand_unknown)
 
3121
      Strand = Seq_strand_plus;
 
3122
    strand = AlnMgr2GetNthStrand(sap, anchor);
 
3123
    if (strand == Seq_strand_unknown)
 
3124
      strand = Seq_strand_plus;
 
3125
    if (Strand != strand) {
 
3126
      SeqAlignListReverseStrand(sap);
 
3127
      SAIndex2Free2(sap->saip);
 
3128
      sap->saip = NULL;
 
3129
      AlnMgr2IndexSingleChildSeqAlign(sap);
 
3130
      dsp = (DenseSegPtr)(sap->segs);
 
3131
      strand = AlnMgr2GetNthStrand(sap, anchor);
 
3132
      if (strand == Seq_strand_unknown)
 
3133
        strand = Seq_strand_plus;
 
3134
    }
 
3135
    a_plus = strand != Seq_strand_minus;
 
3136
  }}
 
3137
  anchor--; Anchor--; /* make them 0-based */
 
3138
 
 
3139
  /* create new dsp */
 
3140
  DSP = DenseSegNew();
 
3141
  DSP->numseg = Dsp->numseg;
 
3142
  DSP->dim = Dsp->dim;
 
3143
/*   DSP->ids = SeqIdDupList(Dsp->ids); */
 
3144
 
 
3145
  /* collect other shared seqids */
 
3146
  b_set = B_set = B_set_head = NULL;
 
3147
  row = -1; sip = Dsp->ids;
 
3148
  extra_sip = dsp->ids;
 
3149
  if (anchor == 0) {
 
3150
    extra_sip = extra_sip->next;
 
3151
  }
 
3152
  while (AlnMgr2GetFirstRowForSeqId
 
3153
         (Dsp, extra_sip, dsp->strands[1-anchor], &row, &sip)) {
 
3154
    if (B_set) {
 
3155
      B_set->next = AlnMgr2CreateSeqPieceSet(Dsp, row);
 
3156
      B_set = B_set->next;
 
3157
    } else {
 
3158
      B_set = B_set_head = AlnMgr2CreateSeqPieceSet(Dsp, row);
 
3159
    }
 
3160
  }
 
3161
  b_plus = dsp->strands[1-anchor] != Seq_strand_minus;
 
3162
 
 
3163
  /* ids */
 
3164
  DSP->ids = Dsp->ids;
 
3165
  Dsp->ids = NULL;
 
3166
 
 
3167
  /* collect a, b */
 
3168
  a_set = AlnMgr2CreateSeqPieceSet(dsp, anchor);
 
3169
  a = a_set->head;
 
3170
  b_set = AlnMgr2CreateSeqPieceSet(dsp, 1-anchor);
 
3171
  while (a = AlnMgr2GetNextSeqPiece(a)) {
 
3172
    b = b_set->tail;
 
3173
    while (b = AlnMgr2GetNextLimitedSeqPiece(b, a)) {
 
3174
      if (!b->aligned) {
 
3175
        DSP->numseg++;
 
3176
      }
 
3177
    }
 
3178
  }
 
3179
 
 
3180
  /* collect A, B */
 
3181
  A_set = AlnMgr2CreateSeqPieceSet(Dsp, Anchor);
 
3182
  A = A_set->head;
 
3183
  while (A = AlnMgr2GetNextSeqPiece(A)) {
 
3184
    B_set = B_set_head;
 
3185
    while (B_set) {
 
3186
      B = B_set->tail;
 
3187
      while (B = AlnMgr2GetNextLimitedSeqPiece(B, A)) {};
 
3188
      B_set=B_set->next;
 
3189
    }
 
3190
  }
 
3191
 
 
3192
  /* resolve a, A */
 
3193
  A_set->alt_row = a_set->row;
 
3194
  a = a_set->head->next;
 
3195
  A = A_set->head->next;
 
3196
  while (a && A && a->next && A->next) {
 
3197
    if (a_plus ? a->beg < A->beg : a->beg > A->beg) {
 
3198
      AlnMgr2InsertSeqPiece
 
3199
        (A, a, a_plus ? MIN(a->end, A->beg-1) : MAX(a->end, A->beg+1));
 
3200
      DSP->numseg++;
 
3201
      if (a_plus ? a->end < A->beg : a->end > A->beg) {
 
3202
        a = a->next;
 
3203
      } else {
 
3204
        a->beg = A->beg;
 
3205
      }
 
3206
    } else if (a_plus ? A->beg < a->beg : A->beg > a->beg) {
 
3207
      if (a_plus ? A->end < a->beg : A->end > a->beg) {
 
3208
        A = A->next;
 
3209
      } else {
 
3210
        AlnMgr2InsertSeqPiece(A, A, a_plus ? a->beg - 1 : a->beg + 1);
 
3211
        DSP->numseg++;
 
3212
      }
 
3213
    } else { /* a->beg == A->beg */
 
3214
      if (a_plus ? a->end < A->end : a->end > A->end) {
 
3215
        AlnMgr2InsertSeqPiece(A, a, a->end);
 
3216
        DSP->numseg++;
 
3217
        a = a->next;
 
3218
      } else if (a_plus ? a->end > A->end : a->end < A->end) {
 
3219
        a->beg = A->end + (a_plus ? 1 : -1);
 
3220
        A->alt_dsp = a->set->dsp;
 
3221
        A->alt_seg = a->seg;
 
3222
        A->alt_pos = a->pos;
 
3223
        A = A->next;
 
3224
      } else { /* a->end == A->end */
 
3225
        A->alt_dsp = a->set->dsp;
 
3226
        A->alt_seg = a->seg;
 
3227
        A->alt_pos = a->pos;
 
3228
        a = a->next;
 
3229
        A = A->next;
 
3230
      }
 
3231
    }
 
3232
  }
 
3233
  while (a && a->next) {
 
3234
    AlnMgr2InsertSeqPiece(A, a, a->end);
 
3235
    DSP->numseg++;
 
3236
    a = a->next;
 
3237
  }
 
3238
 
 
3239
  /* set the upper limits */
 
3240
  if (B_set_head) {
 
3241
    if (a_plus) {
 
3242
      upper_limit = 
 
3243
        A_set->tail->end = A_set->tail->beg = A_set->tail->prev->end + 1;
 
3244
 
 
3245
      b = b_set->tail;
 
3246
      while (b && b->right == -1) {
 
3247
        b->right = upper_limit;
 
3248
        b = b->prev;
 
3249
      }
 
3250
      
 
3251
      B_set = B_set_head;
 
3252
      while (B_set) {
 
3253
        B = B_set->tail;
 
3254
        while (B && B->right == -1) {
 
3255
          B->right = upper_limit;
 
3256
          B = B->prev;
 
3257
        }
 
3258
        B_set = B_set->next;
 
3259
      }
 
3260
      
 
3261
    } else {
 
3262
      upper_limit = 
 
3263
        A_set->head->beg = A_set->head->end = A_set->head->next->beg + 1;
 
3264
      
 
3265
      b = b_set->head;
 
3266
      while (b && b->left == -1) {
 
3267
        b->left = upper_limit;
 
3268
        b = b->next;
 
3269
      }
 
3270
      
 
3271
      B_set = B_set_head;
 
3272
      while (B_set) {
 
3273
        B = B_set->head;
 
3274
        while (B && B->left == -1) {
 
3275
          B->left = upper_limit;
 
3276
          B = B->next;
 
3277
        }
 
3278
        B_set = B_set->next;
 
3279
      }
 
3280
      
 
3281
    }
 
3282
  }
 
3283
 
 
3284
  /* try to resolve b, B */
 
3285
  if (B_set_head) {
 
3286
    b = b_set->head->next;
 
3287
    B_set = B_set_head;
 
3288
    while (B_set) {
 
3289
      B = B_set->head->next;
 
3290
      conflict = FALSE;
 
3291
      extra_segs = 0;
 
3292
      while (b && B) {
 
3293
        if (b_plus ? b->beg < B->beg : b->beg > B->beg) {
 
3294
          if (b_plus ? b->end < B->beg : b->end > B->beg) {
 
3295
            /* trim the limits */
 
3296
            if (a_plus ? B->left <= b->left : B->left >= b->left) {
 
3297
              if (a_plus ? B->right < b->left : B->right > b->left) {
 
3298
                conflict = TRUE; break;
 
3299
              } else {
 
3300
                if (B->aligned) {
 
3301
                  conflict = TRUE; break; /* no trimming allowed */
 
3302
                } else {
 
3303
                  B->left = b->left;
 
3304
                }
 
3305
              }
 
3306
              if (a_plus ? b->right > B->right : b->right < B->right) {
 
3307
                if (b->aligned) {
 
3308
                  conflict = TRUE; break; /* no trimming allowed */
 
3309
                } else {
 
3310
                  b->orig_right = b->right; /* for recovering */
 
3311
                  b->right = B->right;
 
3312
                }
 
3313
              }
 
3314
            }
 
3315
            AlnMgr2InsertSeqPiece(B, b, b->end);
 
3316
            if (!(b->aligned)) extra_segs++;
 
3317
            b = b->next;
 
3318
          } else {
 
3319
            conflict = TRUE; break;
 
3320
          } 
 
3321
 
 
3322
        } else if (b_plus ? B->beg < b->beg : B->beg > b->beg) {
 
3323
          if (b_plus ? B->end < b->beg : B->end > b->beg) {
 
3324
            /* trim the limits */
 
3325
            if (a_plus ? b->left < B->left : b->left > B->left) {
 
3326
              if (a_plus ? b->right < B->left : b->right > B->left) {
 
3327
                conflict = TRUE; break;
 
3328
              } else {
 
3329
                if (b->aligned) {
 
3330
                  conflict = TRUE; break; /* no trimming allowed */
 
3331
                } else {
 
3332
                  b->orig_left = b->left; /* for recovering */
 
3333
                  b->left = B->left;
 
3334
                }
 
3335
              }
 
3336
              if (a_plus ? B->right > b->right : B->right < b->right) {
 
3337
                if (B->aligned) {
 
3338
                  conflict = TRUE; break; /* no trimming allowed */
 
3339
                } else {
 
3340
                  B->right = b->right;
 
3341
                }
 
3342
              }
 
3343
            }
 
3344
 
 
3345
            B = B->next;
 
3346
 
 
3347
          } else {
 
3348
            conflict = TRUE; break;
 
3349
          }
 
3350
        } else { /* B->beg == b->beg */
 
3351
          conflict = TRUE; break;
 
3352
        }
 
3353
      }
 
3354
      if (!conflict) {
 
3355
        while (b) {
 
3356
          AlnMgr2AddSeqPiece(B_set, b);
 
3357
          if (!(b->aligned)) extra_segs++;
 
3358
          b = b->next;
 
3359
        }
 
3360
/*         DSP->numseg += extra_segs; */
 
3361
        break;
 
3362
      }
 
3363
      /* conflict, roll back b, recovering limits, try next B */
 
3364
      if (!b) {
 
3365
        b = b_set->tail;
 
3366
      }
 
3367
      while (b) {
 
3368
        if (b->orig_left != -2) {
 
3369
          b->left = b->orig_left;
 
3370
        }
 
3371
        if (b->orig_right != -2) {
 
3372
          b->right = b->orig_right;
 
3373
        }
 
3374
        b = b->prev;
 
3375
      }
 
3376
      b = b_set->head->next;
 
3377
      B_set = B_set->next;
 
3378
    }
 
3379
  }
 
3380
  if (B_set) {  /* B_set has no conflict with b_set */
 
3381
    B = B_set->head->next;
 
3382
    B_set->row2 = B_set->row; /* mark the set */
 
3383
    A_set->row2 = B_set->row;
 
3384
    A_set->alt_row2 = b_set->row; 
 
3385
  } else {  /* this mean extra row */
 
3386
    A_set->row2 = -1;
 
3387
    A_set->alt_row2 = b_set->row;
 
3388
    A_set->alt_dsp = b_set->dsp;
 
3389
    DSP->dim++;
 
3390
    sip = DSP->ids;
 
3391
    while (sip->next) {
 
3392
      sip = sip->next;
 
3393
    }
 
3394
    AddSeqId(&sip, extra_sip);
 
3395
 
 
3396
    /* fix the index too */
 
3397
    amaip->numrows = DSP->dim;
 
3398
    amaip->ids = (SeqIdPtr PNTR)MemMore
 
3399
      (amaip->ids,amaip->numrows*sizeof(SeqIdPtr));
 
3400
    amaip->ids[amaip->numrows-1] = SeqIdDup(extra_sip);
 
3401
 
 
3402
    b_set->row2 = b_set->row; /* mark the set */
 
3403
    B = b_set->head->next;
 
3404
    B_beg = -1; /* nothing to comp Bs to */
 
3405
  }
 
3406
  
 
3407
  /* allocate memory for the new sharedaln matrix */
 
3408
  DSP->starts = (Int4Ptr)MemNew(DSP->numseg * DSP->dim * sizeof(Int4));
 
3409
  DSP->strands = (Uint1Ptr)MemNew(DSP->numseg * DSP->dim * sizeof(Uint1));
 
3410
  DSP->lens = (Int4Ptr)MemNew(DSP->numseg * sizeof(Int4));
 
3411
 
 
3412
  /* loop through segments */
 
3413
  POS = 0; Pos = 0; Seg = 0; SEG = 0;
 
3414
  A = A_set->head->next;
 
3415
  while (Seg < Dsp->numseg) {
 
3416
 
 
3417
    A_end = Dsp->starts[Pos+A_set->row];
 
3418
    if (a_plus && A_end >= 0) {
 
3419
      A_end += Dsp->lens[Seg] - 1;
 
3420
    }
 
3421
    if (B_set) {
 
3422
      B_beg = Dsp->starts[Pos+B_set->row];
 
3423
    }
 
3424
    
 
3425
    if (A_end >= 0) {
 
3426
      while (A && (a_plus ? A->end <= A_end : A->end >= A_end)) {
 
3427
        while (B && (a_plus ? B->left < A->beg : B->left > A->beg)) {
 
3428
          if (B->aligned) {
 
3429
            B = B->next;
 
3430
            break; /* the aligned piece should be last */
 
3431
          } else {
 
3432
            AlnMgr2CopySeg(DSP, &SEG, &POS, Dsp, &Seg, &Pos, &B);
 
3433
          }            
 
3434
        }
 
3435
        if (B && B->aligned && B->left == A->beg) {
 
3436
          B = B->next;
 
3437
        }
 
3438
        AlnMgr2CopySeg(DSP, &SEG, &POS, Dsp, &Seg, &Pos, &A);
 
3439
      }
 
3440
    } else if (B && B_beg >= 0) {
 
3441
      while (B && (b_plus ? B->beg <= B_beg : B->beg >= B_beg)) {
 
3442
        while (A && (a_plus ? A->beg <= B->left : A->beg >= B->left)) {
 
3443
          AlnMgr2CopySeg(DSP, &SEG, &POS, Dsp, &Seg, &Pos, &A);
 
3444
        }
 
3445
        if (B->aligned) {
 
3446
          B = B->next;
 
3447
        } else {
 
3448
          AlnMgr2CopySeg(DSP, &SEG, &POS, Dsp, &Seg, &Pos, &B);
 
3449
        }            
 
3450
      }
 
3451
    } else {
 
3452
      /* just copy the Dsp segment */
 
3453
      DSP->lens[SEG] = Dsp->lens[Seg];
 
3454
      max_POS = POS + Dsp->dim;
 
3455
      for (; POS < max_POS; POS++, Pos++) {
 
3456
        DSP->starts[POS] = Dsp->starts[Pos];
 
3457
        DSP->strands[POS] = Dsp->strands[Pos];
 
3458
      }
 
3459
      if (DSP->dim > Dsp->dim) {
 
3460
        DSP->starts[POS] = -1;
 
3461
        DSP->strands[POS] = dsp->strands[1-anchor];
 
3462
        POS++;
 
3463
      }
 
3464
      SEG++;
 
3465
      Seg++;
 
3466
    }
 
3467
  }
 
3468
  while (A) {
 
3469
    while (B && (a_plus ? B->right <= A->beg : B->right >= A->beg)) {
 
3470
      if (B->aligned) {
 
3471
        B = B->next;
 
3472
      } else {
 
3473
        AlnMgr2CopySeg(DSP, &SEG, &POS, Dsp, &Seg, &Pos, &B);
 
3474
      }            
 
3475
    }
 
3476
    AlnMgr2CopySeg(DSP, &SEG, &POS, Dsp, &Seg, &Pos, &A);
 
3477
  }
 
3478
  while (B) {
 
3479
    if (B->aligned) {
 
3480
      B = B->next;
 
3481
    } else {
 
3482
      AlnMgr2CopySeg(DSP, &SEG, &POS, Dsp, &Seg, &Pos, &B);
 
3483
    }            
 
3484
  }
 
3485
 
 
3486
  /* Done */
 
3487
  AMSeqPieceSetFree(A_set);
 
3488
  AMSeqPieceSetFree(a_set);
 
3489
  AMSeqPieceSetFree(B_set_head);
 
3490
  AMSeqPieceSetFree(b_set);
 
3491
 
 
3492
  amaip->sharedaln->segs = DSP;
 
3493
  /* update the dim for the shared_aln to match the new DensegPtr */
 
3494
  amaip->sharedaln->dim = DSP->dim;
 
3495
  
 
3496
  DenseSegFree(Dsp);
 
3497
}
 
3498
 
2061
3499
/***************************************************************************
2062
3500
*
2063
3501
*  AlnMgr2AddInNewSA adds a seqalign to an existing seqalign. The new
2090
3528
   SeqAlignPtr      salp;
2091
3529
   SeqAlignPtr      sap_new;
2092
3530
   SeqAlignPtr      PNTR saptmp;
2093
 
   Int4             PNTR segs;
2094
3531
   SeqIdPtr         sip;
2095
3532
   SeqIdPtr         sip_head;
2096
3533
   SeqIdPtr         sip_tmp;
2106
3543
      salp = SeqAlignDup(sap);
2107
3544
      AlnMgr2IndexSingleChildSeqAlign(salp);
2108
3545
      dsp = (DenseSegPtr)(salp->segs);
2109
 
      amaip->aligncoords = (Int4Ptr)MemNew((dsp->numseg)*sizeof(Int4));
2110
 
      for (i=1; i<dsp->numseg; i++)
2111
 
      {
2112
 
         amaip->aligncoords[i] = amaip->aligncoords[i-1] + dsp->lens[i-1];
2113
 
      }
2114
3546
      amaip->sharedaln = salp;
2115
3547
      amaip->numrows = dsp->dim;
2116
3548
      sip = dsp->ids;
2122
3554
         sip = sip->next;
2123
3555
         i++;
2124
3556
      }
 
3557
      MemFree(amaip->saps);
2125
3558
      amaip->saps = (SeqAlignPtr PNTR)MemNew(sizeof(SeqAlignPtr));
2126
3559
      amaip->saps[0] = sap;
2127
3560
      amaip->numsaps = 1;
2128
3561
   } else
2129
3562
   {
 
3563
      /* free ids */
2130
3564
      for (i=0; i<amaip->numrows; i++)
2131
3565
      {
2132
3566
         SeqIdFree(amaip->ids[i]);
2133
3567
      }
2134
3568
      MemFree(amaip->ids);
 
3569
 
 
3570
      /* add the new sap */
2135
3571
      saptmp = amaip->saps;
2136
3572
      amaip->saps = (SeqAlignPtr PNTR)MemNew((amaip->numsaps+1)*sizeof(SeqAlignPtr));
2137
3573
      for (i=0; i<amaip->numsaps; i++)
2141
3577
      amaip->saps[amaip->numsaps] = sap;
2142
3578
      MemFree(saptmp);
2143
3579
      amaip->numsaps++;
 
3580
 
 
3581
      /* dsp, dsp_shared, n1, n2 */
2144
3582
      dsp = (DenseSegPtr)(sap->segs);
2145
3583
      dsp_shared = (DenseSegPtr)(amaip->sharedaln->segs);
2146
3584
      AlnMgr2GetFirstSharedRow(amaip->sharedaln, sap, &n1, &n2);
2147
3585
      if (n1 == n2 && n1 == 0)
2148
3586
         return;
 
3587
 
2149
3588
      /* make sure the shared rows are on the same strand */
2150
3589
      strand1 = AlnMgr2GetNthStrand(amaip->sharedaln, n1);
2151
3590
      if (strand1 == Seq_strand_unknown)
2164
3603
         if (strand2 == Seq_strand_unknown)
2165
3604
            strand2 = Seq_strand_plus;
2166
3605
      }
 
3606
 
 
3607
      /* numrows */
2167
3608
      numrows = dsp->dim + dsp_shared->dim - 1; /* for now this works; compress at the end */
2168
3609
      asp_head = NULL;
 
3610
 
 
3611
      /* currstop */
2169
3612
      if (strand1 == Seq_strand_minus)
2170
3613
         AlnMgr2GetNthSeqRangeInSA(amaip->sharedaln, n1, NULL, &currstop);
2171
3614
      else
2172
3615
         currstop = -1;
 
3616
 
 
3617
      /* add asp for each dsp_shared seg */
2173
3618
      for (i=0; i<dsp_shared->numseg; i++)
2174
3619
      {
2175
3620
         asp = (AM_Small2Ptr)MemNew(sizeof(AM_Small2));
2182
3627
            if (asp_head != NULL)
2183
3628
            {
2184
3629
               asp_prev->next = asp;
 
3630
               /*if (asp_prev->n1 == asp->n1)
 
3631
                  asp->n5 = asp_prev->n5+1;*/
2185
3632
               asp_prev = asp;
2186
3633
            } else
2187
3634
               asp_head = asp_prev = asp;
2194
3641
            if (asp_head != NULL)
2195
3642
            {
2196
3643
               asp_prev->next = asp;
 
3644
               /*if (asp_prev->n1 == asp->n1)
 
3645
                  asp->n5 = asp_prev->n5+1;*/
2197
3646
               asp_prev = asp;
2198
3647
            } else
2199
3648
               asp_head = asp_prev = asp;
2213
3662
                  asp->n3 = AM_STOP;
2214
3663
            } else
2215
3664
               asp->n3 = AM_HARDSTOP;
2216
 
            asp->n4 = dsp_shared->lens[i];
 
3665
            if (asp->n3 == AM_HARDSTOP)
 
3666
            {
 
3667
               if (strand1 != Seq_strand_minus)
 
3668
                  asp->n4 = -(dsp_shared->starts[(dsp_shared->dim)*i+n1-1] + dsp_shared->lens[i]-1);
 
3669
               else
 
3670
                  asp->n4 = -dsp_shared->starts[(dsp_shared->dim)*i+n1-1];
 
3671
            } else
 
3672
               asp->n4 = -dsp_shared->lens[i];
2217
3673
            if (strand1 != Seq_strand_minus)
2218
3674
               currstop = asp->n1;
2219
3675
            else
2220
3676
               currstop = asp_prev->n1-1;
2221
3677
            asp_prev->next = asp;
 
3678
            /*if (asp_prev->n1 == asp->n1)
 
3679
               asp->n5 = asp_prev->n5+1;*/
2222
3680
            asp_prev = asp;
2223
3681
         }
2224
 
      }
 
3682
      } /* asp for each dsp_shared seg */
 
3683
      
 
3684
      /* currstop = start of sap's n2-th seq */
2225
3685
      if (strand1 == Seq_strand_minus)
2226
3686
         AlnMgr2GetNthSeqRangeInSA(sap, n2, NULL, &currstop);
2227
3687
      else
2228
 
         currstop = -1;
 
3688
         AlnMgr2GetNthSeqRangeInSA(sap, n2, &currstop, NULL);
 
3689
 
 
3690
      /* add asp for each dsp seg */
2229
3691
      for (i=0; i<dsp->numseg; i++)
2230
3692
      {
2231
3693
         asp = (AM_Small2Ptr)MemNew(sizeof(AM_Small2));
2236
3698
            asp->n3 = AM_GAP;
2237
3699
            asp->n4 = dsp->lens[i];
2238
3700
            asp_prev->next = asp;
 
3701
            /*if (asp_prev->n1 == asp->n1)
 
3702
               asp->n5 = asp_prev->n5 + 1;*/
2239
3703
            asp_prev = asp;
2240
3704
         } else
2241
3705
         {
2244
3708
            asp->n3 = AM_START;
2245
3709
            asp->n4 = dsp->lens[i];
2246
3710
            asp_prev->next = asp;
 
3711
            /*if (asp_prev->n1 == asp->n1)
 
3712
               asp->n5 = asp_prev->n5+1;*/
2247
3713
            asp_prev = asp;
2248
3714
            asp = (AM_Small2Ptr)MemNew(sizeof(AM_Small2));
2249
3715
            asp->n1 = dsp->starts[(dsp->dim)*i + n2 - 1] + dsp->lens[i] - 1;
2261
3727
                  asp->n3 = AM_STOP;
2262
3728
            } else
2263
3729
               asp->n3 = AM_HARDSTOP;
2264
 
            asp->n4 = dsp->lens[i];
 
3730
            if (asp->n3 == AM_HARDSTOP)
 
3731
            {
 
3732
               if (strand1 != Seq_strand_minus)
 
3733
                  asp->n4 = -(dsp->starts[(dsp->dim)*i+n1-1] + dsp->lens[i]-1);
 
3734
               else
 
3735
                  asp->n4 = -dsp->starts[(dsp->dim)*i+n1-1];
 
3736
               /* so if n4 is negative, this is the highest-numbered residue in the interval */
 
3737
            } else
 
3738
               asp->n4 = dsp->lens[i];
2265
3739
            if (strand1 != Seq_strand_minus)
2266
3740
               currstop = asp->n1;
2267
3741
            else
2268
3742
               currstop = asp_prev->n1-1;
2269
3743
            asp_prev->next = asp;
 
3744
            /*if (asp_prev->n1 == asp->n1)
 
3745
               asp->n5 = asp_prev->n5 + 1;*/
2270
3746
            asp_prev = asp;
2271
3747
         }
2272
3748
      }
 
3749
      
 
3750
      /* create asparray and heapsort it */
2273
3751
      asp = asp_head;
2274
3752
      i = 0;
2275
3753
      while (asp != NULL)
2337
3815
               {
2338
3816
                  asp_tmp = asp_tmp->next;
2339
3817
               }
2340
 
               if (state != 0 && asp_tmp != NULL && asp_tmp->n1 != asp->n1+1)
 
3818
               if (state != 0 && asp_tmp != NULL && asp_tmp->n1 != asp->n1+1 && (asp_tmp->n3 != AM_HARDSTOP || asp_tmp->n1 != asp->n1))
2341
3819
                  j++;
2342
 
               else if (state != 0 && asp->next != NULL && asp_tmp != NULL)
 
3820
               else if (state != 0 && asp->next != NULL && asp_tmp != NULL && (asp_tmp->n3 != AM_HARDSTOP || asp_tmp->n1 != asp->n1))
2343
3821
               {
2344
3822
                  asp_tmp2 = asp_tmp;
2345
3823
                  while (asp_tmp2 != NULL && asp->n1+1 == asp_tmp2->n1 && asp_tmp2->n3 != AM_START)
2346
3824
                  {
2347
3825
                     asp_tmp2 = asp_tmp2->next;
2348
3826
                  }
2349
 
                  if (asp_tmp2 != NULL && ((asp_tmp2->n1 == asp->n1+1 && asp_tmp2->n3 != AM_START) || asp_tmp2->n1 != asp->n1+1))
 
3827
                  if (asp_tmp2 != NULL && ((asp_tmp2->n1 == asp->n1+1 && asp_tmp2->n3 != AM_START) || asp_tmp2->n1 != asp->n1+1) && (asp_tmp->n3 != AM_HARDSTOP || asp_tmp->n1 != asp->n1))
2350
3828
                     j++;
2351
3829
               }
2352
3830
            } else if (asp->n3 == AM_GAP)
2397
3875
            asp = asp->next;
2398
3876
         }
2399
3877
      }
 
3878
 
 
3879
      /* dsp_new */
2400
3880
      dsp_new = DenseSegNew();
2401
3881
      dsp_new->dim = numrows;
2402
3882
      dsp_new->numseg = j;
2403
 
      segs = (Int4Ptr)MemNew(j*sizeof(Int4));
2404
3883
      dsp_new->ids = SeqIdDupList(dsp_shared->ids);
2405
3884
      dsp_new->starts = (Int4Ptr)MemNew((dsp_new->numseg)*(dsp_new->dim)*sizeof(Int4));
2406
3885
      dsp_new->strands = (Uint1Ptr)MemNew((dsp_new->numseg)*(dsp_new->dim)*sizeof(Uint1));
2407
3886
      dsp_new->lens = (Int4Ptr)MemNew((dsp_new->numseg)*sizeof(Int4));
 
3887
 
 
3888
      /* get all the ids except for the duplicated one */
2408
3889
      sip_head = NULL;
2409
3890
      sip_tmp = NULL;
2410
3891
      sip = dsp->ids;
2430
3911
         sip = sip->next;
2431
3912
      }
2432
3913
      sip->next = sip_head;
 
3914
 
 
3915
      /* construct starts and lens from asps */
2433
3916
      asp = asp_head;
2434
3917
      i=0;
2435
3918
      state = 0;
2452
3935
               {
2453
3936
                  asp_tmp = asp_tmp->next;
2454
3937
               }
2455
 
               if (state != 0 && asp_tmp != NULL && asp_tmp->n1 != asp->n1+1)
 
3938
               if (state != 0 && asp_tmp != NULL && asp_tmp->n1 != asp->n1+1 && (asp_tmp->n3 != AM_HARDSTOP || asp_tmp->n1 != asp->n1))
2456
3939
               {
2457
3940
                  dsp_new->starts[dsp_new->dim*i+n1-1] = asp->n1 + 1;
 
3941
                  dsp_new->lens[i] = asp->n4;
2458
3942
                  i++;
2459
 
               } else if (state != 0 && asp->next != NULL && asp_tmp != NULL && i < dsp_new->numseg)
 
3943
               } else if (state != 0 && asp->next != NULL && asp_tmp != NULL && i < dsp_new->numseg && (asp_tmp->n3 != AM_HARDSTOP || asp_tmp->n1 != asp->n1))
2460
3944
               {
2461
3945
                  asp_tmp2 = asp_tmp;
2462
3946
                  while (asp_tmp2 != NULL && asp->n1+1 == asp_tmp2->n1 && asp_tmp2->n3 != AM_START)
2463
3947
                  {
2464
3948
                     asp_tmp2 = asp_tmp2->next;
2465
3949
                  }
2466
 
                  if (asp_tmp2 != NULL && ((asp_tmp2->n1 == asp->n1+1 && asp_tmp2->n3 != AM_START) || asp_tmp2->n1 != asp->n1+1))
 
3950
                  if (asp_tmp2 != NULL && ((asp_tmp2->n1 == asp->n1+1 && asp_tmp2->n3 != AM_START) || asp_tmp2->n1 != asp->n1+1) && (asp_tmp->n3 != AM_HARDSTOP || asp_tmp->n1 != asp->n1))
2467
3951
                  {
2468
3952
                     dsp_new->starts[dsp_new->dim*i+n1-1] = asp->n1 + 1;
 
3953
                     dsp_new->lens[i] = asp->n4;
2469
3954
                     i++;
2470
3955
                  }
2471
3956
               }
2488
3973
               if (state != 0 && asp->next != NULL && asp_tmp != NULL && asp_tmp->n1 != asp->n1+1 && i < dsp_new->numseg)
2489
3974
               {
2490
3975
                  dsp_new->starts[dsp_new->dim*i+n1-1] = asp->n1 + 1;
 
3976
                  if (asp->n1 > -asp->n4)
 
3977
                     dsp_new->lens[i] = asp->n4;
2491
3978
                  i++;
2492
3979
               } else if (state != 0 && asp->next != NULL && asp_tmp != NULL && i < dsp_new->numseg)
2493
3980
               {
2499
3986
                  if (asp_tmp2 != NULL && ((asp_tmp2->n1 == asp->n1+1 && asp_tmp2->n3 != AM_START) || asp_tmp2->n1 != asp->n1+1))
2500
3987
                  {
2501
3988
                     dsp_new->starts[dsp_new->dim*i+n1-1] = asp->n1 + 1;
 
3989
                     if (asp->n1 > -asp->n4)
 
3990
                        dsp_new->lens[i] = asp->n4;
2502
3991
                     i++;
2503
3992
                  } else if (asp_tmp2 == NULL)
2504
3993
                  {
2505
3994
                     dsp_new->starts[dsp_new->dim*i+n1-1] = asp->n1 + 1;
 
3995
                     if (asp->n1 > -asp->n4)
 
3996
                        dsp_new->lens[i] = asp->n4;
2506
3997
                     i++;
2507
3998
                  }
2508
3999
               }
2518
4009
               {
2519
4010
                  if (dsp_new->lens[i] == 0)
2520
4011
                     dsp_new->lens[i] = dsp_new->starts[dsp_new->dim*j+n1-1] - dsp_new->starts[dsp_new->dim*i+n1-1];
2521
 
                  else
 
4012
                  else if (dsp_new->lens[i] > 0)
2522
4013
                     dsp_new->lens[i] = MIN(dsp_new->lens[i], dsp_new->starts[dsp_new->dim*j+n1-1] - dsp_new->starts[dsp_new->dim*i+n1-1]);
 
4014
                  else if (dsp_new->lens[i] < 0)
 
4015
                     dsp_new->lens[i] = -dsp_new->lens[i]-dsp_new->starts[dsp_new->dim*i+n1-1]+1;
2523
4016
                  found = TRUE;
2524
4017
               }
2525
4018
            }
2628
4121
         if (dsp_new->starts[dsp_new->dim*j+n1-1] < 0)
2629
4122
            dsp_new->starts[dsp_new->dim*j+n1-1] = -1;
2630
4123
      }
2631
 
      AlnMgr2CondenseRows(dsp_new);
 
4124
if (dsp_new->dim > 10)
 
4125
   dsp_new->dim = dsp_new->dim;
 
4126
      AlnMgr2CondenseRows(dsp_new, dsp_new->dim);
2632
4127
      sap_new = SeqAlignNew();
2633
4128
      sap_new->segtype = SAS_DENSEG;
2634
4129
      sap_new->segs = (Pointer)(dsp_new);
2643
4138
         amaip->ids[i] = SeqIdDup(sip);
2644
4139
         sip = sip->next;
2645
4140
      }
 
4141
      while (asp_head != NULL)
 
4142
      {
 
4143
         asp = asp_head->next;
 
4144
         MemFree(asp_head);
 
4145
         asp_head = asp;
 
4146
      }
2646
4147
   }
2647
4148
}
2648
4149
 
2672
4173
      diff = dsp->lens[seg] - (pos - dsp->starts[dsp->dim*seg+row1-1]) - 1;
2673
4174
   else
2674
4175
      diff = pos - dsp->starts[dsp->dim*seg+row1-1];
 
4176
   if (diff > dsp->lens[seg]) /* unaligned here */
 
4177
      return -1;
2675
4178
   if (strand2 == Seq_strand_minus)
2676
4179
      pos2 = dsp->starts[dsp->dim*seg+row2-1] + dsp->lens[seg] - diff -1;
2677
4180
   else
2740
4243
   return srdp->sect[L];
2741
4244
}
2742
4245
 
 
4246
static void AlnMgr2CondenseColumns(DenseSegPtr dsp)
 
4247
/***************************************************************************
 
4248
*
 
4249
*  AlnMgr2CondenseColumns finds adjacent columns which appear to align but
 
4250
*  were not put in one column by the mixing mechanism because the input was
 
4251
*  a set of pairwise alignment with a gap on the common sequence in this
 
4252
*  segment. Or graphically:
 
4253
*
 
4254
*  ----- ----- ----- -----             -----
 
4255
*  AACCG ----- ----- -----   becomes   AACCG
 
4256
*  ----- AACCG ----- -----             AACCG
 
4257
*  ----- ----- AACCG -----             AACCG
 
4258
*  ----- ----- ----- AACCG             AACCG
 
4259
*
 
4260
***************************************************************************/
 
4261
{
 
4262
  int gap_start_seg = -1;
 
4263
  int gap_end_seg = -1;
 
4264
  int row, seg, base_col, col;
 
4265
  Boolean can_fit;
 
4266
 
 
4267
  for (seg = 0;  seg < dsp->numseg;  ++seg) {
 
4268
    if (dsp->starts[dsp->dim * seg] == -1) {
 
4269
      if (gap_start_seg == -1) {
 
4270
        gap_start_seg = seg;
 
4271
      }
 
4272
      else {
 
4273
        if (seg == dsp->numseg - 1) {
 
4274
          gap_end_seg = seg + 1;
 
4275
        }
 
4276
      }
 
4277
    }
 
4278
    else {
 
4279
      if (gap_start_seg != -1) {
 
4280
        gap_end_seg = seg;
 
4281
      }
 
4282
    }
 
4283
 
 
4284
    if (gap_end_seg != -1) {
 
4285
      for (base_col = gap_start_seg;  base_col<gap_end_seg;  ++base_col) {
 
4286
        int len = dsp->lens[base_col];
 
4287
        for (col = base_col + 1;  col<gap_end_seg;  ++col) {
 
4288
          if (dsp->lens[col] != len) {
 
4289
            continue;
 
4290
          }
 
4291
 
 
4292
          can_fit = TRUE;
 
4293
          for (row = 0;  row < dsp->dim;  ++row) {
 
4294
            if (dsp->starts[dsp->dim * col + row] != -1  &&  
 
4295
                dsp->starts[dsp->dim * base_col + row] != -1) {
 
4296
              can_fit = FALSE;
 
4297
              break;
 
4298
            }
 
4299
          }
 
4300
 
 
4301
          if (can_fit) {
 
4302
            for (row = 0;  row<dsp->dim;  ++row) {
 
4303
              if (dsp->starts[dsp->dim * col + row] != -1) {
 
4304
                dsp->starts[dsp->dim * base_col + row] =
 
4305
                  dsp->starts[dsp->dim * col + row];
 
4306
              }
 
4307
            }
 
4308
 
 
4309
            /* remove column col */
 
4310
            {{
 
4311
              Int4Ptr       starts, lens;
 
4312
              Uint1Ptr      strands;
 
4313
              Uint4         pos, new_pos;
 
4314
 
 
4315
              starts = (Int4Ptr)MemNew(dsp->dim*(dsp->numseg-1)*sizeof(Int4));
 
4316
              strands = (Uint1Ptr)MemNew(dsp->dim*(dsp->numseg-1)*sizeof(Uint1));
 
4317
              lens = (Int4Ptr)MemNew((dsp->numseg-1)*sizeof(Int4));
 
4318
              
 
4319
              for (pos=0; pos<dsp->dim*col; pos++) {
 
4320
                starts[pos] = dsp->starts[pos];
 
4321
                strands[pos] = dsp->strands[pos];
 
4322
              }
 
4323
              for (new_pos=pos, pos+=dsp->dim; pos<dsp->dim*dsp->numseg;
 
4324
                   pos++, new_pos++) {
 
4325
                starts[new_pos] = dsp->starts[pos];
 
4326
                strands[new_pos] = dsp->strands[pos];
 
4327
              }
 
4328
              
 
4329
              for (pos=0; pos<col; pos++) {
 
4330
                lens[pos] = dsp->lens[pos];
 
4331
              }
 
4332
              for (new_pos=pos, pos++; pos<dsp->numseg; pos++, new_pos++) {
 
4333
                lens[new_pos] = dsp->lens[pos];
 
4334
              }
 
4335
 
 
4336
              MemFree(dsp->starts);
 
4337
              MemFree(dsp->strands);
 
4338
              dsp->starts = starts;
 
4339
              dsp->strands = strands;
 
4340
              dsp->lens = lens;
 
4341
 
 
4342
              dsp->numseg--;
 
4343
            }}
 
4344
 
 
4345
            --gap_end_seg;
 
4346
            --seg;
 
4347
            --col;
 
4348
          }
 
4349
        }
 
4350
      }
 
4351
      
 
4352
      gap_start_seg = -1;
 
4353
      gap_end_seg = -1;
 
4354
    }
 
4355
  }
 
4356
}
 
4357
 
2743
4358
/* SECTION 2c */
2744
4359
/***************************************************************************
2745
4360
*
2746
4361
*  AlnMgr2CondenseRows finds rows of a dense-seg structure that are related
2747
4362
*  and that could be condensed into a single row (or fewer rows). It then
2748
4363
*  calls AlnMgr2DoCondense to condense those rows into continuous or
2749
 
*  discontinuous rows.
 
4364
*  discontinuous rows. whichrow designates which row to merge, if
 
4365
*  less than 1, the function tries to merge the last row.
2750
4366
*
2751
4367
***************************************************************************/
2752
 
static void AlnMgr2CondenseRows(DenseSegPtr dsp)
 
4368
static void AlnMgr2CondenseRows(DenseSegPtr dsp, Int4 whichrow)
2753
4369
{
 
4370
   Boolean     done;
2754
4371
   Int4        i;
2755
4372
   Int4        j;
2756
4373
   Int4        k;
2758
4375
   AMCdRowPtr  row;
2759
4376
   AMCdRowPtr  PNTR rowarray;
2760
4377
   SeqIdPtr    sip;
 
4378
   SeqIdPtr    targetsip;
2761
4379
 
2762
4380
   sip = dsp->ids;
2763
4381
   rowarray = (AMCdRowPtr PNTR)MemNew((dsp->dim)*sizeof(AMCdRowPtr));
 
4382
   if (whichrow < 1 || whichrow > dsp->dim)
 
4383
      whichrow = dsp->dim;
2764
4384
   for (i=0; i<dsp->dim; i++)
2765
4385
   {
2766
4386
      row = (AMCdRowPtr)MemNew(sizeof(AMCdRow));
2769
4389
      row->strand = dsp->strands[i];
2770
4390
      row->rownum = i+1;
2771
4391
      rowarray[i] = row;
 
4392
      if (i+1 == whichrow)
 
4393
         targetsip = row->sip;
2772
4394
   }
2773
4395
   HeapSort(rowarray, i, sizeof(rowarray), AlnMgr2CompareCdRows);
2774
 
   j = 0; /* j marks the first occurrence of each sip */
 
4396
   numrows = dsp->dim;
 
4397
   j = -1; /* j marks the first occurrence of each sip */
 
4398
   for (i=0; j==-1 && i<numrows; i++)
 
4399
   {
 
4400
      if (SeqIdComp(rowarray[i]->sip, targetsip) == SIC_YES)
 
4401
      {
 
4402
         j = i;
 
4403
         if (rowarray[i]->rownum == whichrow) /* no other rows w/sip */
 
4404
         {
 
4405
            for (i=0; i<numrows; i++)
 
4406
            {
 
4407
               SeqIdFree(rowarray[i]->sip);
 
4408
               MemFree(rowarray[i]);
 
4409
            }
 
4410
            MemFree(rowarray);
 
4411
            return;
 
4412
         }
 
4413
      }
 
4414
   }
2775
4415
   sip = SeqIdDup(rowarray[j]->sip);
2776
 
   numrows = dsp->dim;
2777
 
   for (i=1; i<numrows; i++)
 
4416
   done = FALSE;
 
4417
   for (i=j; !done && rowarray[i]->rownum < whichrow; i++)
2778
4418
   {
2779
4419
      if (SeqIdComp(rowarray[i]->sip, sip) == SIC_YES)
2780
4420
      {
2781
4421
         if (rowarray[i]->strand == rowarray[j]->strand)
2782
4422
         {
2783
 
            if (AlnMgr2DoCondense(dsp, rowarray[i]->rownum, rowarray[j]->rownum))
 
4423
            if (AlnMgr2DoCondense(dsp, rowarray[i]->rownum, whichrow))
2784
4424
            {
2785
4425
               for (k=0; k<numrows; k++)
2786
4426
               {
2787
4427
                  if (rowarray[k]->rownum > rowarray[i]->rownum)
 
4428
                  {
2788
4429
                     rowarray[k]->rownum--;
 
4430
                     whichrow--;
 
4431
                  }
2789
4432
               }
2790
4433
            }
2791
4434
         }
2792
4435
      } else
2793
4436
      {
 
4437
         done = TRUE;
2794
4438
         SeqIdFree(sip);
2795
4439
         sip = SeqIdDup(rowarray[i]->sip);
2796
4440
         j = i;
2797
4441
      }
2798
4442
   }
 
4443
   SeqIdFree(sip);
2799
4444
   for (i=0; i<numrows; i++)
2800
4445
   {
2801
4446
      SeqIdFree(rowarray[i]->sip);
2814
4459
***************************************************************************/
2815
4460
static Boolean AlnMgr2DoCondense(DenseSegPtr dsp, Int4 rownum1, Int4 rownum2)
2816
4461
{
2817
 
   Boolean   disc;
2818
 
   Boolean   done;
2819
 
   Int4      i;
2820
 
   SeqIdPtr  id;
2821
 
   SeqIdPtr  id_head;
2822
 
   SeqIdPtr  id_prev;
2823
 
   Int4      j;
2824
 
   Int4      k;
2825
 
   Int4      left;
2826
 
   Int4      left1;
2827
 
   Int4      left2;
2828
 
   Boolean   merged;
2829
 
   Boolean   OK;
2830
 
   Int4      right;
2831
 
   Int4      right1;
2832
 
   Int4      right2;
2833
 
   Int4      row;
2834
 
   Int4Ptr   starts;
2835
 
   Uint1Ptr  strands;
 
4462
   Int4          aln;
 
4463
   SeqAlignPtr   fake_sap;
 
4464
   Boolean       fits;
 
4465
   Boolean       found;
 
4466
   Int4          i;
 
4467
   SeqIdPtr      id;
 
4468
   SeqIdPtr      id_head;
 
4469
   SeqIdPtr      id_prev;
 
4470
   Int4          j;
 
4471
   Int4          k;
 
4472
   Int4          max1;
 
4473
   Int4          max2;
 
4474
   Boolean       merged;
 
4475
   Int4          min1;
 
4476
   Int4          min2;
 
4477
   SAIndex2Ptr   saip;
 
4478
   Boolean       someseq1;
 
4479
   Boolean       someseq2;
 
4480
   Int4Ptr       starts;
 
4481
   Uint1         strand1;
 
4482
   Uint1         strand2;
 
4483
   Uint1Ptr      strands;
 
4484
   AM_Small2Ptr  window;
 
4485
   AM_Small2Ptr  window_head;
 
4486
   AM_Small2Ptr  window_prev;
2836
4487
 
 
4488
   /* always merge up to rownum1 (better rows are first) */
 
4489
   if (rownum1 > rownum2)
 
4490
   {
 
4491
      i = rownum2;
 
4492
      rownum2 = rownum1;
 
4493
      rownum1 = i;
 
4494
   }
 
4495
   strand1 = dsp->strands[rownum1-1];
 
4496
   strand2 = dsp->strands[rownum2-1];
 
4497
   if (strand1 != strand2)
 
4498
      return FALSE;
2837
4499
   i = 0;
 
4500
   window_head = window_prev = NULL;
 
4501
   while (i < dsp->numseg)
 
4502
   {
 
4503
      j = i;
 
4504
      someseq1 = someseq2 = FALSE;
 
4505
      if (dsp->starts[dsp->dim*j+rownum1-1] >= 0)
 
4506
      {
 
4507
         someseq1 = TRUE;
 
4508
         while (j<dsp->numseg && dsp->starts[dsp->dim*j+rownum2-1] < 0)
 
4509
         {
 
4510
            j++;
 
4511
         }
 
4512
      } else if (dsp->starts[dsp->dim*j+rownum2-1] >= 0)
 
4513
      {
 
4514
         someseq2 = TRUE;
 
4515
         while (j<dsp->numseg && dsp->starts[dsp->dim*j+rownum1-1] < 0)
 
4516
         {
 
4517
            j++;
 
4518
         }
 
4519
      }
 
4520
      fits = FALSE;
 
4521
      if (j > i)
 
4522
      {
 
4523
         if (strand1 == Seq_strand_minus)
 
4524
         {
 
4525
            if (someseq1 == FALSE)
 
4526
            {
 
4527
               min1 = -1;
 
4528
               for (k=j; min1 == -1 && k<dsp->numseg; k++)
 
4529
               {
 
4530
                  if (dsp->starts[dsp->dim*k+rownum1-1] > -1)
 
4531
                     min1 = dsp->starts[dsp->dim*k+rownum1-1]+dsp->lens[k]-1;
 
4532
               }
 
4533
               max1 = -1;
 
4534
               for (k=(i-1); max1 == -1 && k>=0; k--)
 
4535
               {
 
4536
                  max1 = dsp->starts[dsp->dim*k+rownum1-1];
 
4537
               }
 
4538
            } else
 
4539
            {
 
4540
               min1 = -1;
 
4541
               for (k=j-1; min1 == -1 && k>=i; k--)
 
4542
               {
 
4543
                  min1 = dsp->starts[dsp->dim*(k)+rownum1-1];
 
4544
               }
 
4545
               max1 = -1;
 
4546
               for (k=i; min1 == -1 && k<j; k++)
 
4547
               {
 
4548
                  if (dsp->starts[dsp->dim*k+rownum1-1] >= 0)
 
4549
                     max1 = dsp->starts[dsp->dim*k+rownum1-1] + dsp->lens[k] -1;
 
4550
               }
 
4551
            }
 
4552
         } else
 
4553
         {
 
4554
            if (someseq1 == FALSE)
 
4555
            {
 
4556
               min1 = -1;
 
4557
               for (k=i-1; min1 == -1 && k >= 0; k--)
 
4558
               {
 
4559
                  if (dsp->starts[dsp->dim*k+rownum1-1] > -1)
 
4560
                     min1 = dsp->starts[dsp->dim*k+rownum1-1]+dsp->lens[k]-1;
 
4561
               }
 
4562
               max1 = -1;
 
4563
               for (k=j; max1 == -1 && k<dsp->numseg; k++)
 
4564
               {
 
4565
                  max1 = dsp->starts[dsp->dim*k+rownum1-1];
 
4566
               }
 
4567
            } else
 
4568
            {
 
4569
               min1 = -1;
 
4570
               for (k=i; min1 == -1 && k<j; k++)
 
4571
               {
 
4572
                  min1 = dsp->starts[dsp->dim*k+rownum1-1];
 
4573
               }
 
4574
               max1 = -1;
 
4575
               for (k=j-1; max1 == -1 && k>i; k--)
 
4576
               {
 
4577
                  if (dsp->starts[dsp->dim*k+rownum1-1] >= 0)
 
4578
                     max1 = dsp->starts[dsp->dim*(k)+rownum1-1] + dsp->lens[k] - 1;
 
4579
               }
 
4580
            }
 
4581
         }
 
4582
         if (strand2 == Seq_strand_minus)
 
4583
         {
 
4584
            if (someseq2 == FALSE)
 
4585
            {
 
4586
               min2 = -1;
 
4587
               for (k=j; min2 == -1 && k<dsp->numseg; k++)
 
4588
               {
 
4589
                  if (dsp->starts[dsp->dim*k+rownum2-1] > -1)
 
4590
                     min2 = dsp->starts[dsp->dim*k+rownum2-1]+dsp->lens[k]-1;
 
4591
               }
 
4592
               max2 = -1;
 
4593
               for (k=(i-1); max2 == -1 && k>=0; k--)
 
4594
               {
 
4595
                  max2 = dsp->starts[dsp->dim*k+rownum2-1];
 
4596
               }
 
4597
            } else
 
4598
            {
 
4599
               min2 = -1;
 
4600
               for (k=j-1; min2 == -1 && k>=i; k--)
 
4601
               {
 
4602
                  min2 = dsp->starts[dsp->dim*(k)+rownum2-1];
 
4603
               }
 
4604
               max2 = -1;
 
4605
               for (k=i; max2 == -1 && k<j; k++)
 
4606
               {
 
4607
                  if (dsp->starts[dsp->dim*k+rownum2-1] >= 0)
 
4608
                     max2 = dsp->starts[dsp->dim*k+rownum2-1] + dsp->lens[k]-1;
 
4609
               }
 
4610
            }
 
4611
         } else
 
4612
         {
 
4613
            if (someseq2 == FALSE)
 
4614
            {
 
4615
               min2 = -1;
 
4616
               for (k=i-1; min2 == -1 && k >= 0; k--)
 
4617
               {
 
4618
                  if (dsp->starts[dsp->dim*k+rownum2-1] > -1)
 
4619
                     min2 = dsp->starts[dsp->dim*k+rownum2-1]+dsp->lens[k]-1;
 
4620
               }
 
4621
               max2 = -1;
 
4622
               for (k=j; max2 == -1 && k<dsp->numseg; k++)
 
4623
               {
 
4624
                  max2 = dsp->starts[dsp->dim*k+rownum2-1];
 
4625
               }
 
4626
            } else
 
4627
            {
 
4628
               min2 = -1;
 
4629
               for (k=i; min2 == -1 && k<j; k++)
 
4630
               {
 
4631
                  min2 = dsp->starts[dsp->dim*k+rownum2-1];
 
4632
               }
 
4633
               max2 = -1;
 
4634
               for (k=j-1; max2 == -1 && k>=i; k--)
 
4635
               {
 
4636
                  if (dsp->starts[dsp->dim*(k)+rownum2-1] >= 0)
 
4637
                     max2 = dsp->starts[dsp->dim*(k)+rownum2-1] + dsp->lens[k] - 1;
 
4638
               }
 
4639
            }
 
4640
         }
 
4641
         if (someseq1 == FALSE)
 
4642
         {
 
4643
            if ((min1 < min2 || min2 == -1) && (max1 > max2 || max1 == -1))
 
4644
               fits = TRUE;
 
4645
         } else
 
4646
         {
 
4647
            if ((min2 < min1 || min1 == -1) && (max2 > max1 || max2 == -1))
 
4648
               fits = TRUE;
 
4649
         }
 
4650
         window = (AM_Small2Ptr)MemNew(sizeof(AM_Small2));
 
4651
         window->n1 = i;
 
4652
         window->n2 = j-1;
 
4653
         if (!fits)
 
4654
            window->n4 = -1;
 
4655
         if (window_head != NULL)
 
4656
         {
 
4657
            window_prev->next = window;
 
4658
            window_prev = window;
 
4659
         } else
 
4660
            window_head = window_prev = window;
 
4661
      }
 
4662
      if (i == j)
 
4663
         i++;
 
4664
      else
 
4665
         i = j;
 
4666
   }
 
4667
   if (window_head == NULL)
 
4668
      return FALSE;
 
4669
   fake_sap = SeqAlignNew();
 
4670
   fake_sap->segtype = SAS_DENSEG;
 
4671
   fake_sap->segs = (Pointer)dsp;
 
4672
   AlnMgr2IndexSingleChildSeqAlign(fake_sap);
 
4673
   aln = AlnMgr2GetNumAlnBlocks(fake_sap);
 
4674
   if (aln == 1) /* only merge if there is a single fitted window flanked by gaps */
 
4675
   /*or if there are several contiguous fitted windows flanked by gaps */
 
4676
   {
 
4677
      if (window_head->next != NULL && window_head->n4 == 0)
 
4678
      {
 
4679
         window = window_head->next;
 
4680
         while (window_head->n2+1 < dsp->numseg && dsp->starts[dsp->dim*(window_head->n2+1)+rownum1-1] == -1 && dsp->starts[dsp->dim*(window_head->n2+1)+rownum2-1] == -1)
 
4681
         {
 
4682
            window_head->n2++;
 
4683
         }
 
4684
         while (window != NULL && window->n4 == 0 && window->n1 == window_head->n2+1)
 
4685
         {
 
4686
            window_head->n2 = window->n2;
 
4687
            window = window->next;
 
4688
            while (window_head->n2+1 < dsp->numseg && dsp->starts[dsp->dim*(window_head->n2+1)+rownum1-1] == -1 && dsp->starts[dsp->dim*(window_head->n2+1)+rownum2-1] == -1)
 
4689
            {
 
4690
               window_head->n2++;
 
4691
            }
 
4692
         }
 
4693
         if (window != NULL)
 
4694
         {
 
4695
            while (window_head != NULL)
 
4696
            {
 
4697
               window = window_head->next;
 
4698
               MemFree(window_head);
 
4699
               window_head = window;
 
4700
            }
 
4701
            fake_sap->segs = NULL;
 
4702
            SeqAlignFree(fake_sap);
 
4703
            return FALSE;
 
4704
         }
 
4705
      }
 
4706
      if (window_head->n4 == -1)
 
4707
      {
 
4708
         while (window_head != NULL)
 
4709
         {
 
4710
            window = window_head->next;
 
4711
            MemFree(window_head);
 
4712
            window_head = window;
 
4713
         }
 
4714
         fake_sap->segs = NULL;
 
4715
         SeqAlignFree(fake_sap);
 
4716
         return FALSE;
 
4717
      }
 
4718
      found = FALSE;
 
4719
      for (i=0; !found && i<window_head->n1; i++)
 
4720
      {
 
4721
         if (dsp->starts[dsp->dim*i+rownum1-1] != -1 && dsp->starts[dsp->dim*i+rownum2-1] != -1)
 
4722
            found = TRUE;
 
4723
      }
 
4724
      for (i=window_head->n2+1; !found && i<dsp->numseg; i++)
 
4725
      {
 
4726
         if (dsp->starts[dsp->dim*i+rownum1-1] != -1 && dsp->starts[dsp->dim*i+rownum2-1] != -1)
 
4727
            found = TRUE;
 
4728
      }
 
4729
      if (found)
 
4730
      {
 
4731
         while (window_head != NULL)
 
4732
         {
 
4733
            window = window_head->next;
 
4734
            MemFree(window_head);
 
4735
            window_head = window;
 
4736
         }
 
4737
         fake_sap->segs = NULL;
 
4738
         SeqAlignFree(fake_sap);
 
4739
         return FALSE;
 
4740
      }
 
4741
      /* merge whole row up to rownum1 */
 
4742
      for (i=0; i<dsp->numseg; i++)
 
4743
      {
 
4744
         dsp->starts[dsp->dim*i+rownum1-1] = MAX(dsp->starts[dsp->dim*i+rownum1-1], dsp->starts[dsp->dim*i+rownum2-1]);
 
4745
      }
 
4746
      starts = (Int4Ptr)MemNew((dsp->dim-1)*(dsp->numseg)*sizeof(Int4));
 
4747
      strands = (Uint1Ptr)MemNew((dsp->dim-1)*(dsp->numseg)*sizeof(Uint1));
 
4748
      k = 0;
 
4749
      for (i=0; i<dsp->dim; i++)
 
4750
      {
 
4751
         if (i != rownum2-1)
 
4752
         {
 
4753
            for (j=0; j<dsp->numseg; j++)
 
4754
            {
 
4755
               starts[(dsp->dim-1)*j+k] = dsp->starts[dsp->dim*j+i];
 
4756
               strands[(dsp->dim-1)*j+k] = dsp->strands[dsp->dim*j+i];
 
4757
            }
 
4758
            k++;
 
4759
         }
 
4760
      }
 
4761
      MemFree(dsp->starts);
 
4762
      MemFree(dsp->strands);
 
4763
      dsp->starts = starts;
 
4764
      dsp->strands = strands;
 
4765
      dsp->dim--;
 
4766
      id_head = id_prev = NULL;
 
4767
      id = dsp->ids;
 
4768
      j = 0;
 
4769
      while (id != NULL)
 
4770
      {
 
4771
         if (j+1 != rownum2)
 
4772
         {
 
4773
            if (id_head != NULL)
 
4774
            {
 
4775
               id_prev->next = SeqIdDup(id);
 
4776
               id_prev = id_prev->next;
 
4777
            } else
 
4778
               id_head = id_prev = SeqIdDup(id);
 
4779
         }
 
4780
         j++;
 
4781
         id = id->next;
 
4782
      }
 
4783
      SeqIdSetFree(dsp->ids);
 
4784
      dsp->ids = id_head;
 
4785
      while (window_head != NULL)
 
4786
      {
 
4787
         window = window_head->next;
 
4788
         MemFree(window_head);
 
4789
         window_head = window;
 
4790
      }
 
4791
      fake_sap->segs = NULL;
 
4792
      SeqAlignFree(fake_sap);
 
4793
      return TRUE;
 
4794
   }
 
4795
   /* now go through and find the largest piece of every window that can be merged */
 
4796
   /* (can't split up an aligned region with the merge, though)                    */
 
4797
   window = window_head;
 
4798
   saip = (SAIndex2Ptr)(fake_sap->saip);
 
4799
   while (window != NULL)
 
4800
   {
 
4801
      j = k = -1;
 
4802
      found = FALSE;
 
4803
      for (i=0; !found && i<window->n1; i++)
 
4804
      {
 
4805
         if (dsp->starts[dsp->dim*i+rownum1-1] != -1 && dsp->starts[dsp->dim*i+rownum2-1] != -1)
 
4806
            found = TRUE;
 
4807
      }
 
4808
      if (!found)
 
4809
         j = window->n1;
 
4810
      found = FALSE;
 
4811
      for (i=window->n2+1; !found && i<dsp->numseg; i++)
 
4812
      {
 
4813
         if (dsp->starts[dsp->dim*i+rownum1-1] != -1 && dsp->starts[dsp->dim*i+rownum2-1] != -1)
 
4814
            found = TRUE;
 
4815
      }
 
4816
      if (!found)
 
4817
         k = window->n2;
 
4818
      if (j == -1)
 
4819
      {
 
4820
         found = FALSE;
 
4821
         for (i = window->n1-1; !found && i<window->n2; i++)
 
4822
         {
 
4823
            j = binary_search_on_uint4_list(saip->unaln, i, saip->numunaln);
 
4824
            if (j == i)
 
4825
               found = TRUE;
 
4826
            else
 
4827
               j = -1;
 
4828
         }
 
4829
      }
 
4830
      if (k == -1)
 
4831
      {
 
4832
         found = FALSE;
 
4833
         for (i = window->n2; !found && i>=window->n1; i++)
 
4834
         {
 
4835
            k = binary_search_on_uint4_list(saip->unaln, i, saip->numunaln);
 
4836
            if (k == i)
 
4837
               found = TRUE;
 
4838
            else
 
4839
               k = -1;
 
4840
         }
 
4841
      }
 
4842
      if (j > -1 && k > -1 && k > j)
 
4843
      {
 
4844
         window->n1 = j+1;
 
4845
         window->n2 = k;
 
4846
      } else
 
4847
         window->n1 = -1;
 
4848
      window = window->next;
 
4849
   }
 
4850
   window = window_head;
 
4851
   while (window != NULL)
 
4852
   {
 
4853
      if (window->n4 == -1 && i >= 0) /* see if it fits now */
 
4854
      {
 
4855
         i = window->n1;
 
4856
         j = window->n2+1;
 
4857
         if (strand1 == Seq_strand_minus)
 
4858
         {
 
4859
            if (dsp->starts[dsp->dim*(j-1)+rownum1-1] == -1)
 
4860
            {
 
4861
               min1 = -1;
 
4862
               for (k=j; min1 == -1 && k<dsp->numseg; k++)
 
4863
               {
 
4864
                  min1 = dsp->starts[dsp->dim*k+rownum1-1];
 
4865
               }
 
4866
               max1 = -1;
 
4867
               for (k=(i-1); max1 == -1 && k>=0; k--)
 
4868
               {
 
4869
                  max1 = dsp->starts[dsp->dim*k+rownum1-1];
 
4870
               }
 
4871
            } else
 
4872
            {
 
4873
               min1 = dsp->starts[dsp->dim*(j-1)+rownum1-1];
 
4874
               max1 = dsp->starts[dsp->dim*i+rownum1-1] + dsp->lens[i];
 
4875
            }
 
4876
         } else
 
4877
         {
 
4878
            if (dsp->starts[dsp->dim*(j-1)+rownum1-1] == -1)
 
4879
            {
 
4880
               min1 = -1;
 
4881
               for (k=i-1; min1 == -1 && k >= 0; k--)
 
4882
               {
 
4883
                  min1 = dsp->starts[dsp->dim*k+rownum1-1];
 
4884
               }
 
4885
               max1 = -1;
 
4886
               for (k=j; max1 == -1 && k<dsp->numseg; k++)
 
4887
               {
 
4888
                  max1 = dsp->starts[dsp->dim*k+rownum1-1];
 
4889
               }
 
4890
            } else
 
4891
            {
 
4892
               min1 = dsp->starts[dsp->dim*i+rownum1-1];
 
4893
               max1 = dsp->starts[dsp->dim*(j-1)+rownum1-1] + dsp->lens[j-1];
 
4894
            }
 
4895
         }
 
4896
         if (strand2 == Seq_strand_minus)
 
4897
         {
 
4898
            if (dsp->starts[dsp->dim*(j-1)+rownum2-1] == -1)
 
4899
            {
 
4900
               min2 = -1;
 
4901
               for (k=j; min2 == -1 && k<dsp->numseg; k++)
 
4902
               {
 
4903
                  min2 = dsp->starts[dsp->dim*k+rownum2-1];
 
4904
               }
 
4905
               max2 = -1;
 
4906
               for (k=(i-1); max2 == -1 && k>=0; k--)
 
4907
               {
 
4908
                  max2 = dsp->starts[dsp->dim*k+rownum2-1];
 
4909
               }
 
4910
            } else
 
4911
            {
 
4912
               min2 = dsp->starts[dsp->dim*(j-1)+rownum2-1];
 
4913
               max2 = dsp->starts[dsp->dim*i+rownum2-1] + dsp->lens[i];
 
4914
            }
 
4915
         } else
 
4916
         {
 
4917
            if (dsp->starts[dsp->dim*(j-1)+rownum2-1] == -1)
 
4918
            {
 
4919
               min2 = -1;
 
4920
               for (k=i-1; min2 == -1 && k >= 0; k--)
 
4921
               {
 
4922
                  min2 = dsp->starts[dsp->dim*k+rownum2-1];
 
4923
               }
 
4924
               max2 = -1;
 
4925
               for (k=j; max2 == -1 && k<dsp->numseg; k++)
 
4926
               {
 
4927
                  max2 = dsp->starts[dsp->dim*k+rownum2-1];
 
4928
               }
 
4929
            } else
 
4930
            {
 
4931
               min2 = dsp->starts[dsp->dim*i+rownum2-1];
 
4932
               max2 = dsp->starts[dsp->dim*(j-1)+rownum2-1] + dsp->lens[j-1];
 
4933
            }
 
4934
         }
 
4935
         if (dsp->starts[dsp->dim*j+rownum1-1] == -1)
 
4936
         {
 
4937
            if (min1 < min2 && (max1 > max2 || max1 == -1))
 
4938
               window->n4 = 0;
 
4939
         } else
 
4940
         {
 
4941
            if (min2 < min1 && (max2 > max1 || max2 == -1))
 
4942
               window->n4 = 0;
 
4943
         }
 
4944
      }
 
4945
      if (window->n1 >= 0 && window->n4 >= 0)
 
4946
      {
 
4947
         for (i=window->n1; i<=window->n2; i++)
 
4948
         {
 
4949
            dsp->starts[dsp->dim*i+rownum1-1] = MAX(dsp->starts[dsp->dim*i+rownum1-1], dsp->starts[dsp->dim+i+rownum2-1]);
 
4950
         }
 
4951
      }
 
4952
      window = window->next;
 
4953
   }
 
4954
   found = FALSE;
 
4955
   /* check to see if rownum2 is all gaps now */
 
4956
   for (i=0; !found && i<dsp->numseg; i++)
 
4957
   {
 
4958
      if (dsp->starts[dsp->dim*i+rownum2-1] != -1)
 
4959
         found = TRUE;
 
4960
   }
2838
4961
   merged = FALSE;
2839
 
   while (i < dsp->numseg && !merged)
2840
 
   {
2841
 
      if (dsp->starts[dsp->dim*i+rownum1-1] == -1 && dsp->starts[dsp->dim*i+rownum2-1] >= 0)
2842
 
      {
2843
 
         left = -1;
2844
 
         right = -1;
2845
 
         for (j=i-1; j>=0 && left == -1; j--)
2846
 
         {
2847
 
            if (dsp->starts[dsp->dim*j+rownum1-1] >= 0 || dsp->starts[dsp->dim*j+rownum2-1] == -1)
2848
 
               left = j+1;
2849
 
         }
2850
 
         if (left == -1)
2851
 
            left = 0;
2852
 
         for (j=i+1; j<dsp->numseg && right == -1; j++)
2853
 
         {
2854
 
            if (dsp->starts[dsp->dim*j+rownum1-1] >= 0 || dsp->starts[dsp->dim*j+rownum2-1] == -1)
2855
 
               right = j-1;
2856
 
         }
2857
 
         if (right == -1)
2858
 
            right = dsp->numseg-1;
2859
 
         if (dsp->strands[rownum2-1] == Seq_strand_minus)
2860
 
         {
2861
 
            left2 = dsp->starts[dsp->dim*left+rownum2-1] + dsp->lens[left]-1;
2862
 
            right2 = dsp->starts[dsp->dim*right+rownum2-1];
2863
 
         } else
2864
 
         {
2865
 
            left2 = dsp->starts[dsp->dim*left+rownum2-1];
2866
 
            right2 = dsp->starts[dsp->dim*right+rownum2-1] + dsp->lens[right]-1;
2867
 
         }
2868
 
         left1 = right1 = -1;
2869
 
         for (j=i-1; j>=0 && left1 == -1; j--)
2870
 
         {
2871
 
            if (dsp->starts[dsp->dim*j+rownum1-1] >= 0)
2872
 
            {
2873
 
               if (dsp->strands[rownum1-1] == Seq_strand_minus)
2874
 
                  left1 = dsp->starts[dsp->dim*j+rownum1-1];
2875
 
               else
2876
 
                  left1 = dsp->starts[dsp->dim*j+rownum1-1]+dsp->lens[j] - 1;
2877
 
            }
2878
 
         }
2879
 
         for (j=i+1; j<dsp->numseg && right1 == -1; j++)
2880
 
         {
2881
 
            if (dsp->starts[dsp->dim*j+rownum1-1] >= 0)
2882
 
            {
2883
 
               if (dsp->strands[rownum1-1] == Seq_strand_minus)
2884
 
                  right1 = dsp->starts[dsp->dim*j+rownum1-1]+dsp->lens[j] - 1;
2885
 
               else
2886
 
                  right1 = dsp->starts[dsp->dim*j+rownum1-1];
2887
 
            }
2888
 
         }
2889
 
         OK = FALSE;
2890
 
         if (dsp->strands[rownum1-1] == Seq_strand_minus)
2891
 
         {
2892
 
            if (right2 > right1 && (left1 > left2 || left1 == -1))
2893
 
               OK = TRUE;
2894
 
         } else
2895
 
         {
2896
 
            if (left2 > left1 && (right2 < right1 || right1 == -1))
2897
 
               OK = TRUE;
2898
 
         }
2899
 
         if (OK == TRUE && (left1 == -1 || right1 == -1 || abs(left1-right1) > 1))
2900
 
         {
2901
 
            disc = TRUE;
2902
 
            j = i-1;
2903
 
            if (j >= 0)
2904
 
            {
2905
 
               if (dsp->starts[dsp->dim*j+rownum2-1] == -1)
2906
 
               {
2907
 
                  j--;
2908
 
                  done = FALSE;
2909
 
                  while (j>=0 && !done)
2910
 
                  {
2911
 
                     if (dsp->starts[dsp->dim*j+rownum1-1] >= 0)
2912
 
                     {
2913
 
                        done = TRUE;
2914
 
                        if (dsp->strands[rownum2-1] == Seq_strand_minus)
2915
 
                        {
2916
 
                           if (dsp->starts[dsp->dim*i+rownum2-1]+dsp->lens[i] >= dsp->starts[dsp->dim*j+rownum2-1])
2917
 
                              disc = FALSE;
2918
 
 
2919
 
                        } else
2920
 
                        {
2921
 
                           if (dsp->starts[dsp->dim*j+rownum2-1]+dsp->lens[j] >= dsp->starts[dsp->dim*i+rownum2-1])
2922
 
                              disc = FALSE;
2923
 
                        }
2924
 
                     }
2925
 
                     j--;
2926
 
                  }
2927
 
               } else
2928
 
               {
2929
 
                  if (dsp->strands[rownum2-1] == Seq_strand_minus)
2930
 
                  {
2931
 
                     if (dsp->starts[dsp->dim*i+rownum2-1]+dsp->lens[i] >= dsp->starts[dsp->dim*j+rownum2-1])
2932
 
                        disc = FALSE;
2933
 
                  } else
2934
 
                  {
2935
 
                     if (dsp->starts[dsp->dim*j+rownum2-1]+dsp->lens[j] >= dsp->starts[dsp->dim*i+rownum2-1])
2936
 
                        disc = FALSE;
2937
 
                  }
2938
 
               }
2939
 
            }
2940
 
            if (disc == TRUE)
2941
 
            {
2942
 
               for (j=left; j<=right; j++)
2943
 
               {
2944
 
                  dsp->starts[dsp->dim*j+rownum1-1] = dsp->starts[dsp->dim*j+rownum2-1];
2945
 
                  dsp->starts[dsp->dim*j+rownum2-1] = -1;
2946
 
               }
2947
 
               /* now see if rownum2 has anything left on it; if not, delete it */
2948
 
               done = FALSE;
2949
 
               for (j=0; j<dsp->numseg && !done; j++)
2950
 
               {
2951
 
                  if (dsp->starts[dsp->dim*j+rownum2-1] != -1)
2952
 
                     done = TRUE;
2953
 
               }
2954
 
               if (!done) /* nothing but gaps */
2955
 
               {
2956
 
                  starts = (Int4Ptr)MemNew((dsp->dim-1)*dsp->numseg*sizeof(Int4));
2957
 
                  strands = (Uint1Ptr)MemNew((dsp->dim-1)*dsp->numseg*sizeof(Uint1));
2958
 
                  row = 0;
2959
 
                  for (j=0; j<dsp->dim; j++)
2960
 
                  {
2961
 
                     if (j+1 != rownum2)
2962
 
                     {
2963
 
                        for (k=0; k<dsp->numseg; k++)
2964
 
                        {
2965
 
                           starts[(dsp->dim-1)*k+row] = dsp->starts[(dsp->dim)*k+j];
2966
 
                           strands[(dsp->dim-1)*k+row] = dsp->strands[(dsp->dim)*k+j];
2967
 
                        }
2968
 
                        row++;
2969
 
                     }
2970
 
                  }
2971
 
                  MemFree(dsp->starts);
2972
 
                  MemFree(dsp->strands);
2973
 
                  dsp->starts = starts;
2974
 
                  dsp->strands = strands;
2975
 
                  dsp->dim--;
2976
 
                  id_head = id_prev = NULL;
2977
 
                  id = dsp->ids;
2978
 
                  j = 0;
2979
 
                  while (id != NULL)
2980
 
                  {
2981
 
                     if (j+1 != rownum2)
2982
 
                     {
2983
 
                        if (id_head != NULL)
2984
 
                        {
2985
 
                           id_prev->next = SeqIdDup(id);
2986
 
                           id_prev = id_prev->next;
2987
 
                        } else
2988
 
                           id_head = id_prev = SeqIdDup(id);
2989
 
                     }
2990
 
                     j++;
2991
 
                     id = id->next;
2992
 
                  }
2993
 
                  SeqIdSetFree(dsp->ids);
2994
 
                  dsp->ids = id_head;
2995
 
                  merged = TRUE;
2996
 
               }
2997
 
            }
2998
 
         }
2999
 
         i = right+1;
3000
 
      } else if (dsp->starts[dsp->dim*i+rownum1-1] >=0 && dsp->starts[dsp->dim*i+rownum2-1] == -1)
3001
 
      {
3002
 
         left = -1;
3003
 
         right = -1;
3004
 
         for (j=i-1; j>=0 && left == -1; j--)
3005
 
         {
3006
 
            if (dsp->starts[dsp->dim*j+rownum2-1] >= 0 || dsp->starts[dsp->dim*j+rownum1-1] == -1)
3007
 
               left = j+1;
3008
 
         }
3009
 
         if (left == -1)
3010
 
            left = 0;
3011
 
         for (j=i+1; j<dsp->numseg && right == -1; j++)
3012
 
         {
3013
 
            if (dsp->starts[dsp->dim*j+rownum2-1] >= 0 || dsp->starts[dsp->dim*j+rownum1-1] == -1)
3014
 
               right = j-1;
3015
 
         }
3016
 
         if (right == -1)
3017
 
            right = dsp->numseg-1;
3018
 
         if (dsp->strands[rownum1-1] == Seq_strand_minus)
3019
 
         {
3020
 
            left2 = dsp->starts[dsp->dim*left+rownum1-1] + dsp->lens[left]-1;
3021
 
            right2 = dsp->starts[dsp->dim*right+rownum1-1];
3022
 
         } else
3023
 
         {
3024
 
            left2 = dsp->starts[dsp->dim*left+rownum1-1];
3025
 
            right2 = dsp->starts[dsp->dim*right+rownum1-1] + dsp->lens[right]-1;
3026
 
         }
3027
 
         left1 = right1 = -1;
3028
 
         for (j=i-1; j>=0 && left1 == -1; j--)
3029
 
         {
3030
 
            if (dsp->starts[dsp->dim*j+rownum2-1] >= 0)
3031
 
            {
3032
 
               if (dsp->strands[rownum2-1] == Seq_strand_minus)
3033
 
                  left1 = dsp->starts[dsp->dim*j+rownum2-1];
3034
 
               else
3035
 
                  left1 = dsp->starts[dsp->dim*j+rownum2-1]+dsp->lens[j] - 1;
3036
 
            }
3037
 
         }
3038
 
         for (j=i+1; j<dsp->numseg && right1 == -1; j++)
3039
 
         {
3040
 
            if (dsp->starts[dsp->dim*j+rownum2-1] >= 0)
3041
 
            {
3042
 
               if (dsp->strands[rownum2-1] == Seq_strand_minus)
3043
 
                  right1 = dsp->starts[dsp->dim*j+rownum2-1]+dsp->lens[j] - 1;
3044
 
               else
3045
 
                  right1 = dsp->starts[dsp->dim*j+rownum2-1];
3046
 
            }
3047
 
         }
3048
 
         OK = FALSE;
3049
 
         if (dsp->strands[rownum2-1] == Seq_strand_minus)
3050
 
         {
3051
 
            if (right2 > right1 && (left1 > left2 || left1 == -1))
3052
 
               OK = TRUE;
3053
 
         } else
3054
 
         {
3055
 
            if (left2 > left1 && (right2 < right1 || right1 == -1))
3056
 
               OK = TRUE;
3057
 
         }
3058
 
         if (OK == TRUE && (left1 == -1 || right1 == -1 || abs(left1-right1) > 1))
3059
 
         {
3060
 
            disc = TRUE;
3061
 
            j = i-1;
3062
 
            if (j >= 0)
3063
 
            {
3064
 
               if (dsp->starts[dsp->dim*j+rownum1-1] == -1)
3065
 
               {
3066
 
                  j--;
3067
 
                  done = FALSE;
3068
 
                  while (j>=0 && !done)
3069
 
                  {
3070
 
                     if (dsp->starts[dsp->dim*j+rownum2-1] >= 0)
3071
 
                     {
3072
 
                        done = TRUE;
3073
 
                        if (dsp->strands[rownum1-1] == Seq_strand_minus)
3074
 
                        {
3075
 
                           if (dsp->starts[dsp->dim*i+rownum1-1]+dsp->lens[i] >= dsp->starts[dsp->dim*j+rownum1-1])
3076
 
                              disc = FALSE;
3077
 
 
3078
 
                        } else
3079
 
                        {
3080
 
                           if (dsp->starts[dsp->dim*j+rownum1-1]+dsp->lens[j] >= dsp->starts[dsp->dim*i+rownum1-1])
3081
 
                              disc = FALSE;
3082
 
                        }
3083
 
                     }
3084
 
                     j--;
3085
 
                  }
3086
 
               } else
3087
 
               {
3088
 
                  if (dsp->strands[rownum1-1] == Seq_strand_minus)
3089
 
                  {
3090
 
                     if (dsp->starts[dsp->dim*i+rownum1-1]+dsp->lens[i] >= dsp->starts[dsp->dim*j+rownum1-1])
3091
 
                        disc = FALSE;
3092
 
                  } else
3093
 
                  {
3094
 
                     if (dsp->starts[dsp->dim*j+rownum1-1]+dsp->lens[j] >= dsp->starts[dsp->dim*i+rownum1-1])
3095
 
                        disc = FALSE;
3096
 
                  }
3097
 
               }
3098
 
            }
3099
 
            if (disc == TRUE)
3100
 
            {
3101
 
               for (j=left; j<=right; j++)
3102
 
               {
3103
 
                  dsp->starts[dsp->dim*j+rownum2-1] = dsp->starts[dsp->dim*j+rownum1-1];
3104
 
                  dsp->starts[dsp->dim*j+rownum1-1] = -1;
3105
 
               }
3106
 
               /* now see if rownum1 has anything left on it; if not, delete it */
3107
 
               done = FALSE;
3108
 
               for (j=0; j<dsp->numseg && !done; j++)
3109
 
               {
3110
 
                  if (dsp->starts[dsp->dim*j+rownum1-1] != -1)
3111
 
                     done = TRUE;
3112
 
               }
3113
 
               if (!done) /* nothing but gaps */
3114
 
               {
3115
 
                  starts = (Int4Ptr)MemNew((dsp->dim-1)*dsp->numseg*sizeof(Int4));
3116
 
                  strands = (Uint1Ptr)MemNew((dsp->dim-1)*dsp->numseg*sizeof(Uint1));
3117
 
                  row = 0;
3118
 
                  for (j=0; j<dsp->dim; j++)
3119
 
                  {
3120
 
                     if (j+1 != rownum1)
3121
 
                     {
3122
 
                        for (k=0; k<dsp->numseg; k++)
3123
 
                        {
3124
 
                           starts[(dsp->dim-1)*k+row] = dsp->starts[(dsp->dim)*k+j];
3125
 
                           strands[(dsp->dim-1)*k+row] = dsp->strands[(dsp->dim)*k+j];
3126
 
                        }
3127
 
                        row++;
3128
 
                     }
3129
 
                  }
3130
 
                  MemFree(dsp->starts);
3131
 
                  MemFree(dsp->strands);
3132
 
                  dsp->starts = starts;
3133
 
                  dsp->strands = strands;
3134
 
                  dsp->dim--;
3135
 
                  id_head = id_prev = NULL;
3136
 
                  id = dsp->ids;
3137
 
                  j = 0;
3138
 
                  while (id != NULL)
3139
 
                  {
3140
 
                     if (j+1 != rownum1)
3141
 
                     {
3142
 
                        if (id_head != NULL)
3143
 
                        {
3144
 
                           id_prev->next = SeqIdDup(id);
3145
 
                           id_prev = id_prev->next;
3146
 
                        } else
3147
 
                           id_head = id_prev = SeqIdDup(id);
3148
 
                     }
3149
 
                     j++;
3150
 
                     id = id->next;
3151
 
                  }
3152
 
                  SeqIdSetFree(dsp->ids);
3153
 
                  dsp->ids = id_head;
3154
 
                  merged = TRUE;
3155
 
               }
3156
 
            }
3157
 
         }
3158
 
         i = right+1;
3159
 
      } else
3160
 
         i++;
3161
 
   }
 
4962
   if (!found) /* just gaps */
 
4963
   {
 
4964
      /* merge whole row up to rownum1 */
 
4965
      for (i=0; i<dsp->numseg; i++)
 
4966
      {
 
4967
         dsp->starts[dsp->dim*i+rownum1-1] = MAX(dsp->starts[dsp->dim*i+rownum1-1], dsp->starts[dsp->dim*i+rownum2-1]);
 
4968
      }
 
4969
      starts = (Int4Ptr)MemNew((dsp->dim-1)*(dsp->numseg)*sizeof(Int4));
 
4970
      strands = (Uint1Ptr)MemNew((dsp->dim-1)*(dsp->numseg)*sizeof(Uint1));
 
4971
      k = 0;
 
4972
      for (i=0; i<dsp->dim; i++)
 
4973
      {
 
4974
         if (i != rownum2-1)
 
4975
         {
 
4976
            for (j=0; j<dsp->numseg; j++)
 
4977
            {
 
4978
               starts[dsp->dim*j+k] = dsp->starts[dsp->dim*j+i];
 
4979
               strands[dsp->dim*j+k] = dsp->strands[dsp->dim*j+i];
 
4980
            }
 
4981
            k++;
 
4982
         }
 
4983
      }
 
4984
      MemFree(dsp->starts);
 
4985
      MemFree(dsp->strands);
 
4986
      dsp->starts = starts;
 
4987
      dsp->strands = strands;
 
4988
      dsp->dim--;
 
4989
      id_head = id_prev = NULL;
 
4990
      id = dsp->ids;
 
4991
      j = 0;
 
4992
      while (id != NULL)
 
4993
      {
 
4994
         if (j+1 != rownum2)
 
4995
         {
 
4996
            if (id_head != NULL)
 
4997
            {
 
4998
               id_prev->next = SeqIdDup(id);
 
4999
               id_prev = id_prev->next;
 
5000
            } else
 
5001
               id_head = id_prev = SeqIdDup(id);
 
5002
         }
 
5003
         j++;
 
5004
         id = id->next;
 
5005
      }
 
5006
      SeqIdSetFree(dsp->ids);
 
5007
      dsp->ids = id_head;
 
5008
      merged = TRUE;
 
5009
   }
 
5010
   while (window_head != NULL)
 
5011
   {
 
5012
      window = window_head->next;
 
5013
      MemFree(window_head);
 
5014
      window_head = window;
 
5015
   }
 
5016
   fake_sap->segs = NULL;
 
5017
   SeqAlignFree(fake_sap);
3162
5018
   return merged;
3163
5019
}
3164
5020
 
3179
5035
      return 0;
3180
5036
   row1 = *((AMCdRowPtr PNTR)ptr1);
3181
5037
   row2 = *((AMCdRowPtr PNTR)ptr2);
3182
 
   i = SAM_OrderSeqID(row1->sip, row2->sip);
 
5038
   i = AlnMgr2OrderSeqIds(row1->sip, row2->sip);
3183
5039
   if (i == 0) /* sort from least rownum to greatest within each seqid */
3184
5040
   {
3185
5041
      if (row1->rownum < row2->rownum)
3211
5067
         return -1;
3212
5068
      else if (asp1->n1 > asp2->n1)
3213
5069
         return 1;
 
5070
      else if (asp1->n5 < asp2->n5)
 
5071
         return -1;
 
5072
      else if (asp1->n5 > asp2->n5)
 
5073
         return 1;
3214
5074
      else
3215
5075
      {
3216
 
              if (asp1->n3 == AM_GAP && asp2->n3 == AM_GAP)
3217
 
              {
3218
 
                 if (asp1->n2 < asp2->n2)
3219
 
                    return -1;
3220
 
                 if (asp1->n2 > asp2->n2)
3221
 
                    return 1;
3222
 
              }
 
5076
         if (asp1->n3 == AM_GAP && asp2->n3 == AM_GAP)
 
5077
         {
 
5078
            if (asp1->n2 < asp2->n2)
 
5079
               return -1;
 
5080
            if (asp1->n2 > asp2->n2)
 
5081
               return 1;
 
5082
         }
3223
5083
         if (asp1->n3 == AM_START)
3224
5084
         {
3225
5085
            if (asp2->n3 == AM_STOP)
3235
5095
            if (asp2->n3 == AM_START)
3236
5096
               return 1;
3237
5097
            else if (asp2->n3 == AM_GAP)
 
5098
               return 1;
 
5099
            else if (asp2->n3 == AM_HARDSTOP)
3238
5100
               return -1;
3239
 
            else if (asp2->n3 == AM_HARDSTOP)
3240
 
               return 1;
3241
5101
            else
3242
5102
               return 0;
3243
5103
         } else if (asp1->n3 == AM_GAP)
3245
5105
            if (asp2->n3 == AM_START)
3246
5106
               return 1;
3247
5107
            else if (asp2->n3 == AM_STOP)
3248
 
               return 1;
 
5108
               return -1;
3249
5109
            else if (asp2->n3 == AM_HARDSTOP)
 
5110
               return -1;
 
5111
            else
 
5112
               return 0;
 
5113
         } else if (asp1->n3 == AM_HARDSTOP)
 
5114
         {
 
5115
            if (asp2->n3 == AM_START)
 
5116
               return 1;
 
5117
            else if (asp2->n3 == AM_STOP)
 
5118
               return 1;
 
5119
            else if (asp2->n3 == AM_GAP)
3250
5120
               return 1;
3251
5121
            else
3252
5122
               return 0;
3278
5148
         return -1;
3279
5149
      else if (asp1->n1 < asp2->n1)
3280
5150
         return 1;
 
5151
      else if (asp1->n5 < asp2->n5)
 
5152
         return -1;
 
5153
      else if (asp1->n5 > asp2->n5)
 
5154
         return 1;
3281
5155
      else
3282
5156
      {
3283
5157
         if (asp1->n3 == AM_GAP && asp2->n3 == AM_GAP)
3292
5166
            if (asp2->n3 == AM_STOP)
3293
5167
               return 1;
3294
5168
            else if (asp2->n3 == AM_GAP)
3295
 
               return 1;
 
5169
               return -1;
3296
5170
            else if (asp2->n3 == AM_HARDSTOP)
3297
5171
               return 1;
3298
5172
            else
3302
5176
            if (asp2->n3 == AM_START)
3303
5177
               return -1;
3304
5178
            else if (asp2->n3 == AM_GAP)
3305
 
               return 1;
 
5179
               return -1;
3306
5180
            else if (asp2->n3 == AM_HARDSTOP)
3307
5181
               return 1;
3308
5182
            else
3310
5184
         } else if (asp1->n3 == AM_GAP)
3311
5185
         {
3312
5186
            if (asp2->n3 == AM_START)
3313
 
               return -1;
 
5187
               return 1;
3314
5188
            else if (asp2->n3 == AM_STOP)
3315
 
               return -1;
 
5189
               return 1;
3316
5190
            else if (asp2->n3 == AM_HARDSTOP)
 
5191
               return 1;
 
5192
            else
 
5193
               return 0;
 
5194
         } else if (asp1->n3 == AM_HARDSTOP)
 
5195
         {
 
5196
            if (asp2->n3 == AM_START)
 
5197
               return -1;
 
5198
            else if (asp2->n3 == AM_STOP)
 
5199
               return -1;
 
5200
            else if (asp2->n3 == AM_GAP)
3317
5201
               return -1;
3318
5202
            else
3319
5203
               return 0;
3392
5276
   return NULL;
3393
5277
}
3394
5278
 
 
5279
/***************************************************************************
 
5280
*
 
5281
*  AlnMgr2OrderSeqIds simply alphabetizes printed seqids in order to sort
 
5282
*  them in order to group identical ones in a set.
 
5283
*
 
5284
***************************************************************************/
 
5285
static Int4 AlnMgr2OrderSeqIds(SeqIdPtr sip1, SeqIdPtr sip2)
 
5286
{
 
5287
   Char  txt1[42];
 
5288
   Char  txt2[42];
 
5289
 
 
5290
   if (sip1 == NULL && sip2 == NULL)
 
5291
      return 0;
 
5292
   if (sip1 == NULL && sip2 != NULL)
 
5293
      return 1;
 
5294
   if (sip1 != NULL && sip2 == NULL)
 
5295
      return -1;
 
5296
   SeqIdWrite(sip1, txt1, PRINTID_TEXTID_ACC_VER, 41);
 
5297
   SeqIdWrite(sip2, txt2, PRINTID_TEXTID_ACC_VER, 41);
 
5298
   txt1[41] = txt2[41] = '\0';
 
5299
   return StringICmp(txt1, txt2);
 
5300
}
 
5301
 
3395
5302
/* SECTION 2d */
3396
5303
/***************************************************************************
3397
5304
*
3646
5553
   AlnMsgFree2(amp);
3647
5554
}
3648
5555
 
 
5556
/* SECTION 3 */
 
5557
NLM_EXTERN void AlnMgr2DumpIndexedAlnToFile(SeqAlignPtr sap, CharPtr filename)
 
5558
{
 
5559
   AsnIoPtr          aip;
 
5560
   AMAlignIndex2Ptr  amaip;
 
5561
   SeqAlignPtr       sap_tmp;
 
5562
 
 
5563
   if (sap == NULL || sap->saip == NULL)
 
5564
      return;
 
5565
   if (sap->saip->indextype == INDEX_CHILD)
 
5566
   {
 
5567
      if (sap->dim == 0)
 
5568
         sap->dim = AlnMgr2GetNumRows(sap);
 
5569
      aip = AsnIoOpen(filename, "w");
 
5570
      SeqAlignAsnWrite(sap, aip, NULL);
 
5571
      AsnIoClose(aip);
 
5572
      return;
 
5573
   }
 
5574
   amaip = (AMAlignIndex2Ptr)(sap->saip);
 
5575
   aip = AsnIoOpen(filename, "w");
 
5576
   if (amaip->alnstyle != AM2_LITE)
 
5577
   {
 
5578
      amaip->sharedaln->dim = 0;  /* mark it as the sharedaln */
 
5579
      SeqAlignAsnWrite(amaip->sharedaln, aip, NULL);
 
5580
   }
 
5581
   sap_tmp = sap;
 
5582
   if (sap->dim == 0)
 
5583
      sap->dim = AlnMgr2GetNumRows(sap);
 
5584
   while (sap_tmp != NULL)
 
5585
   {
 
5586
      SeqAlignAsnWrite(sap_tmp, aip, NULL);
 
5587
      sap_tmp = sap_tmp->next;
 
5588
   }
 
5589
   AsnIoClose(aip);
 
5590
}
 
5591
 
 
5592
NLM_EXTERN SeqAlignPtr AlnMgr2ReadIndexedAlnFromFile(CharPtr filename)
 
5593
{
 
5594
   AsnIoOpen(filename, "r");
 
5595
}
 
5596
 
3649
5597
/***************************************************************************
3650
5598
*
3651
5599
*  SECTION 4: API-level functions (and their helper functions) used to
3676
5624
   AMAlignIndex2Ptr  amaip;
3677
5625
   Uint2Ptr         array;
3678
5626
   Int4             arraylen;
 
5627
   Int4             ctr;
3679
5628
   Int4             disc;
 
5629
   Int4             disc1;
3680
5630
   DenseSegPtr      dsp;
3681
5631
   Int4             endoffset;
3682
5632
   Boolean          found;
3683
5633
   Int4             i;
3684
 
   Int4             ilen;
3685
5634
   Int4             index;
3686
 
   Int4             insert;
 
5635
   Int4             intfrom;
 
5636
   Int4             intto;
3687
5637
   Int4             j;
3688
5638
   Int4             len;
3689
5639
   Int4             offset;
3696
5646
   
3697
5647
   if (sap == NULL || sap->saip == NULL || amp == NULL)
3698
5648
      return FALSE;
3699
 
   if (amp->left_insert != NULL)
3700
 
   {
3701
 
      MemFree(amp->left_insert);
3702
 
      amp->left_insert = NULL;
3703
 
   }
3704
 
   if (amp->right_insert != NULL)
3705
 
   {
3706
 
      MemFree(amp->right_insert);
3707
 
      amp->right_insert = NULL;
3708
 
   }
3709
 
   if (amp->left_unaligned != NULL)
3710
 
   {
3711
 
      MemFree(amp->left_unaligned);
3712
 
      amp->left_unaligned = NULL;
3713
 
   }
3714
 
   if (amp->right_unaligned != NULL)
3715
 
   {
3716
 
      MemFree(amp->right_unaligned);
3717
 
      amp->right_unaligned = NULL;
 
5649
   if (amp->left_interrupt != NULL)
 
5650
   {
 
5651
      MemFree(amp->left_interrupt);
 
5652
      amp->left_interrupt = NULL;
 
5653
   }
 
5654
   if (amp->right_interrupt != NULL)
 
5655
   {
 
5656
      MemFree(amp->right_interrupt);
 
5657
      amp->right_interrupt = NULL;
3718
5658
   }
3719
5659
   if (sap->saip->indextype == INDEX_CHILD)
3720
5660
   {
3781
5721
   if (amp->row_num == saip->anchor)
3782
5722
   {
3783
5723
      amp->type = AM_SEQ;
3784
 
      found = FALSE;
3785
 
      disc = -1;
3786
 
      for (i=0; i<saip->srdp[amp->row_num-1]->numunaln && !found; i++)
3787
 
      {
3788
 
         if (saip->srdp[amp->row_num-1]->unaligned[i] >= trans[start_sect] && saip->srdp[amp->row_num-1]->unaligned[i] < trans[stop_sect])
3789
 
         {
3790
 
            disc = saip->srdp[amp->row_num-1]->unaligned[i];
3791
 
            stop_sect = binary_search_on_uint2_list(trans, disc, translen);
3792
 
            found = TRUE;
3793
 
         }
3794
 
      }
3795
 
      if (disc != -1) /* found an unaligned region */
3796
 
      {
3797
 
         amp->right_unaligned = (AMAdjacPtr)MemNew(sizeof(AMAdjac));
3798
 
         AlnMgr2GetUnalignedInfo(sap, disc, amp->row_num, &amp->right_unaligned->from, &amp->right_unaligned->to);
3799
 
         if (amp->right_unaligned->from == amp->right_unaligned->to && amp->right_unaligned->to == -1)
3800
 
         {
3801
 
            MemFree(amp->right_unaligned);
3802
 
            amp->right_unaligned = NULL;
3803
 
         }
3804
 
      }
3805
 
      found = FALSE;
3806
 
      disc = -1;
3807
 
      for (i=0; offset == 0 && i<saip->srdp[amp->row_num-1]->numunaln && !found && saip->srdp[amp->row_num-1]->unaligned[i] < start_sect; i++)
3808
 
      {
3809
 
         if (saip->srdp[amp->row_num-1]->unaligned[i] == start_sect-1)
3810
 
         {
3811
 
            disc = i;
3812
 
            found = TRUE;
3813
 
         }
3814
 
      }
3815
 
      if (disc != -1)
3816
 
      {
3817
 
         amp->left_unaligned = (AMAdjacPtr)MemNew(sizeof(AMAdjac));
3818
 
         AlnMgr2GetUnalignedInfo(sap, saip->srdp[amp->row_num-1]->unaligned[disc], amp->row_num, &amp->left_unaligned->from, &amp->left_unaligned->to);
3819
 
         if (amp->left_unaligned->from == amp->left_unaligned->to && amp->left_unaligned->to == -1)
3820
 
         {
3821
 
            MemFree(amp->left_unaligned);
3822
 
            amp->left_unaligned = NULL;
3823
 
         }
3824
 
      }
3825
 
      for (i=start_sect; i<=stop_sect; i++)
3826
 
      {
3827
 
         if (amp->type != AM_GAP)
3828
 
            len += dsp->lens[srdp->sect[i]];
3829
 
         else
3830
 
            len += dsp->lens[srdp->unsect[i]];
3831
 
      }
3832
 
      endoffset = dsp->lens[trans[stop_sect]] - (amp->to_aln - saip->aligncoords[stop_sect]) - 1;
 
5724
      /* find limits of aligned region */
 
5725
      i = start_sect;
 
5726
      j = srdp->sect[start_sect];
 
5727
      disc = binary_search_on_uint2_list(srdp->unaligned, j, srdp->numunaln);
 
5728
      while (j<srdp->sect[stop_sect] && disc == -1)
 
5729
      {
 
5730
         j++;
 
5731
         disc = binary_search_on_uint2_list(srdp->unaligned, j, srdp->numunaln);
 
5732
      }
 
5733
      i = binary_search_on_uint2_list(srdp->sect, j, srdp->numsect);
 
5734
      if (i == -1)
 
5735
      {
 
5736
         i = binary_search_on_uint2_list(srdp->unsect, j, srdp->numunsect);
 
5737
      }
 
5738
      endoffset = dsp->lens[trans[i]] - (amp->to_aln - saip->aligncoords[i]) - 1;
3833
5739
      if (endoffset < 0)
3834
5740
         endoffset = 0;
3835
 
      if (amp->right_unaligned != NULL && endoffset > 0)
3836
 
      {
3837
 
         MemFree(amp->right_unaligned);
3838
 
         amp->right_unaligned = NULL;
 
5741
      if (i<stop_sect && endoffset == 0) /* there's an unaligned region here, and we go to the end of the segment */
 
5742
      {
 
5743
         AlnMgr2GetUnalignedInfo(sap, trans[i], amp->row_num, &intfrom, &intto);
 
5744
         amp->right_interrupt = (AMInterruptPtr)MemNew(sizeof(AMInterrupt));
 
5745
         amp->right_interrupt->row = amp->row_num;
 
5746
         amp->right_interrupt->unalnlen = intto - intfrom + 1;
 
5747
         amp->right_interrupt->segnum = trans[i];
 
5748
         amp->right_interrupt->which_side = AM2_RIGHT;
 
5749
      }
 
5750
      stop_sect = i;
 
5751
      if (start_sect > 0 && offset == 0)
 
5752
      {
 
5753
         disc = binary_search_on_uint2_list(srdp->unaligned, trans[start_sect]-1, srdp->numunaln);
 
5754
         if (disc != -1) /* there is a left unaligned region */
 
5755
         {
 
5756
            AlnMgr2GetUnalignedInfo(sap, trans[start_sect]-1, amp->row_num, &intfrom, &intto);
 
5757
            amp->left_interrupt = (AMInterruptPtr)MemNew(sizeof(AMInterrupt));
 
5758
            amp->left_interrupt->row = amp->row_num;
 
5759
            amp->left_interrupt->unalnlen = intto - intfrom + 1;
 
5760
            amp->left_interrupt->segnum = trans[start_sect];
 
5761
            amp->left_interrupt->which_side = AM2_LEFT;
 
5762
         }
 
5763
      }
 
5764
      len = 0;
 
5765
      for (i=start_sect; i<= stop_sect; i++)
 
5766
      {
 
5767
         len += dsp->lens[trans[i]];
3839
5768
      }
3840
5769
      len = len - offset - endoffset;
3841
5770
      if (amp->strand == Seq_strand_minus)
3844
5773
         amp->from_row = dsp->starts[trans[start_sect]*dsp->dim+amp->row_num-1] + offset;
3845
5774
      amp->to_row = amp->from_row + len - 1;
3846
5775
      amp->real_from += amp->to_row - amp->from_row + 1;
 
5776
      if (saip->anchor <= 0)
 
5777
         MemFree(trans);
3847
5778
      return TRUE;
3848
5779
   }
3849
5780
   /* look for limits of aligned/gapped region */
3850
 
   found = FALSE;
3851
 
   if (index+1 < arraylen && array[index+1] > trans[stop_sect])
3852
 
   {
3853
 
      found = TRUE;
3854
 
      stop_sect = binary_search_on_uint2_list(trans, array[index], translen);
3855
 
   }
3856
 
   for (i=index+1; i<arraylen && !found && array[i-1]<=trans[stop_sect]; i++)
3857
 
   {
3858
 
      if (array[i] != array[i-1]+1)
3859
 
      {
3860
 
         found = TRUE;
3861
 
         stop_sect = binary_search_on_uint2_list(trans, array[i-1], translen);
3862
 
      }
3863
 
   }
3864
 
   if (i > 0 && array[i-1] > trans[stop_sect]) /* all gap/aligned from start to stop */
3865
 
      found = TRUE;
3866
 
   if (!found) /* make sure the last segments aren't different (switch to gap, etc) */
3867
 
   {
3868
 
      if (array[arraylen-1] < dsp->numseg-1) /* this gap/aligned region doesn't go to the end */
3869
 
         stop_sect = binary_search_on_uint2_list(trans, array[arraylen-1], translen);
3870
 
   }
3871
 
   /* look for interrupting unaligned or inserted regions */
3872
 
   found = FALSE;
3873
 
   disc = -1;
3874
 
   for (i=0; i<saip->srdp[amp->row_num-1]->numunaln && !found; i++)
3875
 
   {
3876
 
      if (saip->srdp[amp->row_num-1]->unaligned[i] >= trans[start_sect] && saip->srdp[amp->row_num-1]->unaligned[i] <= trans[stop_sect])
3877
 
      {
3878
 
         disc = saip->srdp[amp->row_num-1]->unaligned[i];
3879
 
         stop_sect = binary_search_on_uint2_list(trans, disc, translen);
3880
 
         found = TRUE;
3881
 
      }
3882
 
   }
3883
 
   for (j=trans[stop_sect]+1; srdp->numinsect > 0 && stop_sect < translen-1 && j<trans[stop_sect+1] && trans[stop_sect] < srdp->insect[srdp->numinsect-1]; j++)
3884
 
   {
3885
 
      if ((insert = binary_search_on_uint2_list(srdp->insect, j, srdp->numinsect)) != -1)
3886
 
      {
3887
 
         amp->right_insert = (AMAdjacPtr)MemNew(sizeof(AMAdjac));
3888
 
         ilen = dsp->lens[srdp->insect[insert]];
3889
 
         for (i = insert; i<srdp->numinsect-1 && srdp->insect[i] == srdp->insect[i+1]-1; i++)
3890
 
         {
3891
 
            ilen += dsp->lens[srdp->insect[i+1]];
3892
 
         }
3893
 
         if (amp->strand == Seq_strand_minus)
3894
 
         {
3895
 
            amp->right_insert->from = dsp->starts[srdp->insect[i]*dsp->dim+amp->row_num-1];
3896
 
            amp->right_insert->to = amp->right_insert->from + ilen - 1;
3897
 
         } else
3898
 
         {
3899
 
            amp->right_insert->from = dsp->starts[srdp->insect[insert]*dsp->dim+amp->row_num-1];
3900
 
            amp->right_insert->to = amp->right_insert->from + ilen - 1;
3901
 
         }
3902
 
      }
3903
 
   }
3904
 
   if (disc != -1) /* found an unaligned region */
3905
 
   {
3906
 
      amp->right_unaligned = (AMAdjacPtr)MemNew(sizeof(AMAdjac));
3907
 
      AlnMgr2GetUnalignedInfo(sap, disc, amp->row_num, &amp->right_unaligned->from, &amp->right_unaligned->to);
3908
 
      if (amp->right_unaligned->from == amp->right_unaligned->to && amp->right_unaligned->to == -1)
3909
 
      {
3910
 
         MemFree(amp->right_unaligned);
3911
 
         amp->right_unaligned = NULL;
3912
 
      }
3913
 
   }
3914
 
   /* now look for inserts/unaligned regions to the left */
3915
 
   found = FALSE;
3916
 
   disc = -1;
3917
 
   for (i=0; offset == 0 && i<saip->srdp[amp->row_num-1]->numunaln && !found && saip->srdp[amp->row_num-1]->unaligned[i] < trans[start_sect]; i++)
3918
 
   {
3919
 
      if (saip->srdp[amp->row_num-1]->unaligned[i] == trans[start_sect]-1)
3920
 
      {
3921
 
         disc = saip->srdp[amp->row_num-1]->unaligned[i];
3922
 
         found = TRUE;
3923
 
      }
3924
 
   }
3925
 
   if (disc != -1)
3926
 
   {
3927
 
      amp->left_unaligned = (AMAdjacPtr)MemNew(sizeof(AMAdjac));
3928
 
      AlnMgr2GetUnalignedInfo(sap, disc, amp->row_num, &amp->left_unaligned->from, &amp->left_unaligned->to);
3929
 
      if (amp->left_unaligned->from == amp->left_unaligned->to && amp->left_unaligned->to == -1)
3930
 
      {
3931
 
         MemFree(amp->left_unaligned);
3932
 
         amp->left_unaligned = NULL;
3933
 
      }
3934
 
   }
3935
 
   for (j=trans[start_sect]-1; srdp->numinsect > 0 && start_sect > 0 && trans[start_sect] > srdp->insect[0] && j>trans[start_sect-1]; j--)
3936
 
   {
3937
 
      if ((insert = binary_search_on_uint2_list(srdp->insect, j, srdp->numinsect)) != -1)
3938
 
      {
3939
 
         amp->left_insert = (AMAdjacPtr)MemNew(sizeof(AMAdjac));
3940
 
         ilen = dsp->lens[srdp->insect[insert]];
3941
 
         for (i=insert; i>0 && srdp->insect[i-1] == srdp->insect[i]-1; i--)
3942
 
         {
3943
 
           if (i>0)
3944
 
              ilen += dsp->lens[srdp->insect[i-1]];
3945
 
         }
3946
 
         if (amp->strand == Seq_strand_minus)
3947
 
         {
3948
 
            amp->left_insert->from = dsp->starts[srdp->insect[insert]*dsp->dim+amp->row_num-1];
3949
 
            amp->left_insert->to = amp->left_insert->from + ilen - 1;
3950
 
         } else
3951
 
         {
3952
 
            if (i>=0)
3953
 
               amp->left_insert->from = dsp->starts[srdp->insect[i]*dsp->dim+amp->row_num-1];
3954
 
            else
3955
 
               amp->left_insert->from = dsp->starts[srdp->insect[insert]*dsp->dim+amp->row_num-1];
3956
 
            amp->left_insert->to = amp->left_insert->from + ilen - 1;
 
5781
   i = index;
 
5782
   j = start_sect+1;
 
5783
   disc = -1;
 
5784
   found = FALSE;
 
5785
   while (i+1<arraylen && disc == -1 && array[i] <= trans[stop_sect] && array[i+1]-1 == array[i])
 
5786
   {
 
5787
      disc = binary_search_on_uint2_list(srdp->unaligned, array[i], srdp->numunaln);
 
5788
      if (disc == -1)
 
5789
         i++;
 
5790
   }
 
5791
   disc = binary_search_on_uint2_list(srdp->unaligned, array[i], srdp->numunaln);
 
5792
   j = binary_search_on_uint2_list(trans, array[i], translen);
 
5793
   if (amp->type == AM_SEQ && j <= stop_sect) /* there is an interrupting region, either seq/gap, insert, or unaligned, plus just check last piece */
 
5794
   {
 
5795
      i = binary_search_on_uint2_list(srdp->insect, trans[j]+1, srdp->numinsect);
 
5796
      if (i != -1) /* there's an insert */
 
5797
      {
 
5798
         amp->right_interrupt = (AMInterruptPtr)MemNew(sizeof(AMInterrupt));
 
5799
         amp->right_interrupt->row = amp->row_num;
 
5800
         amp->right_interrupt->segnum = trans[j];
 
5801
         amp->right_interrupt->insertlen = dsp->lens[srdp->insect[i]];
 
5802
         amp->right_interrupt->which_side = AM2_RIGHT;
 
5803
         /* look for unaligned regions off insert */
 
5804
         disc1 = -1;
 
5805
         if (j > 0)
 
5806
            disc1 = binary_search_on_uint2_list(srdp->unaligned, trans[j]+1, srdp->numunaln);
 
5807
         if (disc1 != -1)
 
5808
         {
 
5809
            AlnMgr2GetUnalignedInfo(sap, srdp->unaligned[disc1], amp->row_num, &intfrom, &intto);
 
5810
            amp->right_interrupt->unalnlen = intto - intfrom + 1;
 
5811
         }
 
5812
         i++;
 
5813
         ctr = 1;
 
5814
         while (i<srdp->numinsect && srdp->insect[i] == srdp->insect[i-1]+1)
 
5815
         {
 
5816
            amp->right_interrupt->insertlen += dsp->lens[srdp->insect[i]];
 
5817
            /* look for unaligned regions off insert */
 
5818
            disc1 = -1;
 
5819
            if (j > 0) {
 
5820
              disc1 = binary_search_on_uint2_list(srdp->unaligned, trans[j]+1+ctr, srdp->numunaln);
 
5821
            }
 
5822
            if (disc1 != -1)
 
5823
            {
 
5824
               AlnMgr2GetUnalignedInfo(sap, srdp->unaligned[disc1], amp->row_num, &intfrom, &intto);
 
5825
               amp->right_interrupt->unalnlen += intto - intfrom + 1;
 
5826
            }
 
5827
            i++;
 
5828
            ctr++;
 
5829
         }
 
5830
      }
 
5831
      if (disc != -1) /* there's an unaligned region */
 
5832
      {
 
5833
         if (amp->right_interrupt == NULL)
 
5834
            amp->right_interrupt = (AMInterruptPtr)MemNew(sizeof(AMInterrupt));
 
5835
         amp->right_interrupt->row = amp->row_num;
 
5836
         amp->right_interrupt->segnum = trans[j];
 
5837
         amp->right_interrupt->which_side = AM2_RIGHT;
 
5838
         AlnMgr2GetUnalignedInfo(sap, srdp->unaligned[disc], amp->row_num, &intfrom, &intto);
 
5839
         amp->right_interrupt->unalnlen += intto - intfrom + 1;
 
5840
      }
 
5841
   }
 
5842
   stop_sect = j;
 
5843
   /* now look for left-side unaligned or inserted regions if offset == 0 */
 
5844
   if (amp->type == AM_SEQ && offset == 0)
 
5845
   {
 
5846
      disc = -1;
 
5847
      j = 1;
 
5848
      i = -1;
 
5849
      if ((Int2)trans[start_sect]-j > 0)
 
5850
      i = binary_search_on_uint2_list(srdp->sect, trans[start_sect]-j, srdp->numsect);
 
5851
      while (i == -1 && (Int2)(trans[start_sect])-j-1 >= 0)
 
5852
      {
 
5853
         i = binary_search_on_uint2_list(srdp->sect, trans[start_sect]-j-1, srdp->numsect);
 
5854
         j++;
 
5855
      }
 
5856
      disc = binary_search_on_uint2_list(srdp->unaligned, trans[start_sect]-j, srdp->numunaln);;
 
5857
      if (disc > -1)
 
5858
      {
 
5859
         AlnMgr2GetUnalignedInfo(sap, trans[start_sect]-j, amp->row_num, &intfrom, &intto);
 
5860
         amp->left_interrupt = (AMInterruptPtr)MemNew(sizeof(AMInterrupt));
 
5861
         amp->left_interrupt->row = amp->row_num;
 
5862
         amp->left_interrupt->segnum = trans[start_sect];
 
5863
         amp->left_interrupt->which_side = AM2_LEFT;
 
5864
         amp->left_interrupt->unalnlen = intto - intfrom + 1;
 
5865
      }
 
5866
      i = binary_search_on_uint2_list(srdp->insect, trans[start_sect]-j, srdp->numinsect);
 
5867
      if (i != -1) /* there's an insert */
 
5868
      {
 
5869
         if (amp->left_interrupt == NULL)
 
5870
            amp->left_interrupt = (AMInterruptPtr)MemNew(sizeof(AMInterrupt));
 
5871
         amp->left_interrupt->row = amp->row_num;
 
5872
         amp->left_interrupt->segnum = trans[start_sect];
 
5873
         amp->left_interrupt->which_side = AM2_LEFT;
 
5874
         amp->left_interrupt->insertlen = dsp->lens[srdp->insect[i]];
 
5875
         /* look for unaligned regions off insert */
 
5876
         j = trans[start_sect]-j;
 
5877
         disc1 = binary_search_on_uint2_list(srdp->unaligned, j, srdp->numunaln);
 
5878
         if (disc1 != -1)
 
5879
         {
 
5880
            AlnMgr2GetUnalignedInfo(sap, srdp->unaligned[disc1], amp->row_num, &intfrom, &intto);
 
5881
            amp->left_interrupt->unalnlen += intto - intfrom + 1;
 
5882
         }
 
5883
         i--;
 
5884
         j--;
 
5885
         while (i-1>=0 && srdp->insect[i] == srdp->insect[i+1]-1)
 
5886
         {
 
5887
            amp->left_interrupt->insertlen += dsp->lens[srdp->insect[i]];
 
5888
            disc1 = binary_search_on_uint2_list(srdp->unaligned, j, srdp->numunaln);
 
5889
            if (disc1 != -1)
 
5890
            {
 
5891
               AlnMgr2GetUnalignedInfo(sap, srdp->unaligned[disc1], amp->row_num, &intfrom, &intto);
 
5892
               amp->left_interrupt->unalnlen += intto - intfrom + 1;
 
5893
            }
 
5894
            i--;
 
5895
            j--;
 
5896
         }
 
5897
         if (i>=0) /* look one more over for unaligned */
 
5898
         {
 
5899
            disc1 = binary_search_on_uint2_list(srdp->unaligned, j, srdp->numunaln);
 
5900
            if (disc1 != -1)
 
5901
            {
 
5902
               AlnMgr2GetUnalignedInfo(sap, srdp->unaligned[disc1], amp->row_num, &intfrom, &intto);
 
5903
               amp->left_interrupt->unalnlen += intto - intfrom + 1;
 
5904
            }
3957
5905
         }
3958
5906
      }
3959
5907
   }
3960
5908
   endoffset = dsp->lens[trans[stop_sect]] - (amp->to_aln - saip->aligncoords[stop_sect]) - 1;
3961
5909
   if (endoffset < 0)
3962
5910
      endoffset = 0;
3963
 
   if (amp->right_unaligned != NULL && endoffset > 0)
 
5911
   if (amp->right_interrupt != NULL && endoffset > 0)
3964
5912
   {
3965
 
      MemFree(amp->right_unaligned);
3966
 
      amp->right_unaligned = NULL;
 
5913
      MemFree(amp->right_interrupt);
 
5914
      amp->right_interrupt = NULL;
3967
5915
   }
3968
5916
   len = 0;
3969
5917
   for (i=start_sect; i<=stop_sect; i++)
3994
5942
}
3995
5943
 
3996
5944
/* SECTION 4a */
3997
 
static Boolean AlnMgr2GetNextAnchoredChildBit(SeqAlignPtr sap, AlnMsg2Ptr amp)
3998
 
{
3999
 
   AMAlignIndex2Ptr  amaip;
4000
 
   Uint2Ptr         array;
4001
 
   Int4             arraylen;
4002
 
   Int4             beg;
4003
 
   DenseSegPtr      dsp;
4004
 
   Int4             end;
4005
 
   Int4             endoffset;
4006
 
   Boolean          found;
4007
 
   Int4             i;
4008
 
   Int4             index;
4009
 
   AMAdjacPtr       left;
4010
 
   Int4             len;
4011
 
   Int4             offset;
4012
 
   AMAdjacPtr       right;
4013
 
   SAIndex2Ptr       saip;
4014
 
   Boolean          space;
4015
 
   SARowDat2Ptr      srdp;
4016
 
   Int4             start_row;
4017
 
   Int4             stop_row;
4018
 
   Int4             start_sect;
4019
 
   Int4             stop_sect;
4020
 
   Uint2Ptr         trans;
4021
 
 
4022
 
   if (sap->saip->indextype == INDEX_CHILD)
4023
 
   {
4024
 
      dsp = (DenseSegPtr)(sap->segs);
4025
 
      saip = (SAIndex2Ptr)(sap->saip);
4026
 
   } else if (sap->saip->indextype == INDEX_PARENT)
4027
 
   {
4028
 
      amaip = (AMAlignIndex2Ptr)(sap->saip);
4029
 
      saip = (SAIndex2Ptr)(amaip->sharedaln->saip);
4030
 
      dsp = (DenseSegPtr)(amaip->sharedaln->segs);
4031
 
   }
4032
 
   if (saip->anchor > 0)
4033
 
      trans = saip->srdp[saip->anchor-1]->sect;
4034
 
   else
4035
 
   {
4036
 
      trans = (Uint2Ptr)MemNew((dsp->numseg)*sizeof(Uint2));
4037
 
      for (i=0; i<dsp->numseg; i++)
4038
 
      {
4039
 
         trans[i] = i;
4040
 
      }
4041
 
   }
4042
 
   endoffset = 0;
4043
 
   start_sect = binary_search_on_uint4_list(saip->aligncoords, amp->real_from, saip->numseg);
4044
 
   found = FALSE;
4045
 
   for (i=0; i<saip->srdp[amp->row_num-1]->numunaln && !found && saip->srdp[amp->row_num-1]->unaligned[i] < start_sect; i++)
4046
 
   {
4047
 
      if (saip->srdp[amp->row_num-1]->unaligned[i] == start_sect-1)
4048
 
         found = TRUE;
4049
 
   }
4050
 
   i--;
4051
 
   if (found)
4052
 
   {
4053
 
      left = (AMAdjacPtr)MemNew(sizeof(AMAdjac));
4054
 
      AlnMgr2GetUnalignedInfo(sap, saip->srdp[amp->row_num-1]->unaligned[i], amp->row_num, &left->from, &left->to);
4055
 
      if (left->from == left->to == -1)
4056
 
         MemFree(left);
4057
 
      else
4058
 
         amp->left_unaligned = left;
4059
 
   }
4060
 
   found = FALSE;
4061
 
   for (i=0; i<saip->srdp[amp->row_num-1]->numunaln && !found; i++)
4062
 
   {
4063
 
      if (saip->srdp[amp->row_num-1]->unaligned[i] >= start_sect)
4064
 
         found = TRUE;
4065
 
   }
4066
 
   i--;
4067
 
   stop_sect = binary_search_on_uint4_list(saip->aligncoords, amp->to_aln, saip->numseg);
4068
 
   if (found && i>=0 && saip->srdp[amp->row_num-1]->unaligned[i] < stop_sect)
4069
 
   {
4070
 
      right = (AMAdjacPtr)MemNew(sizeof(AMAdjac));
4071
 
      AlnMgr2GetUnalignedInfo(sap, saip->srdp[amp->row_num-1]->unaligned[i], amp->row_num, &right->from, &right->to);
4072
 
      if (right->from == right->to == -1)
4073
 
         MemFree(right);
4074
 
      else
4075
 
      {
4076
 
         amp->right_unaligned = right;
4077
 
         stop_sect = saip->srdp[amp->row_num-1]->unaligned[i];
4078
 
         endoffset = 0;
4079
 
      }
4080
 
   }
4081
 
   offset = amp->real_from - saip->aligncoords[start_sect];
4082
 
   srdp = saip->srdp[amp->row_num - 1];
4083
 
   if (saip->anchor == amp->row_num)
4084
 
   {
4085
 
      amp->type = AM_SEQ;
4086
 
      if (start_sect == stop_sect)
4087
 
         len = dsp->lens[srdp->sect[start_sect]] - offset - endoffset;
4088
 
      else
4089
 
         len = dsp->lens[srdp->sect[start_sect]] - offset;
4090
 
      for (i=start_sect+1; i<stop_sect; i++)
4091
 
      {
4092
 
         len += dsp->lens[srdp->sect[i]];
4093
 
      }
4094
 
      if (start_sect+1 < stop_sect)
4095
 
         len -= endoffset;
4096
 
      if (amp->strand != Seq_strand_minus)
4097
 
      {
4098
 
         amp->from_row = dsp->starts[(trans[start_sect])*(dsp->dim) + amp->row_num -1] + offset;
4099
 
         amp->to_row = amp->from_row + len - 1;
4100
 
      } else
4101
 
      {
4102
 
         amp->from_row = dsp->starts[(trans[stop_sect])*(dsp->dim) + amp->row_num - 1];
4103
 
         amp->to_row = amp->from_row + len - offset - 1;
4104
 
      }
4105
 
      amp->real_from += amp->to_row - amp->from_row + 1;
4106
 
   } else
4107
 
   {
4108
 
      if ((start_row = binary_search_on_uint2_list(srdp->sect, trans[start_sect], srdp->numsect)) != -1)
4109
 
      {
4110
 
         amp->type = AM_SEQ;
4111
 
         array = srdp->sect;
4112
 
         index = start_row;
4113
 
         arraylen = srdp->numsect;
4114
 
      } else if ((start_row = binary_search_on_uint2_list(srdp->unsect, trans[start_sect], srdp->numunsect)) != -1)
4115
 
      {
4116
 
         amp->type = AM_GAP;
4117
 
         array = srdp->unsect;
4118
 
         index = start_row;
4119
 
         arraylen = srdp->numunsect;
4120
 
      } else
4121
 
         return FALSE;
4122
 
      offset = amp->real_from - saip->aligncoords[start_sect];
4123
 
      len = 0;
4124
 
      space = FALSE;
4125
 
      if (array[index] == trans[stop_sect])
4126
 
         len += dsp->lens[trans[index]];
4127
 
      for (i=index; !space && i<arraylen-1 && array[i] < trans[stop_sect]; i++)
4128
 
      {
4129
 
         len += dsp->lens[trans[i]];
4130
 
         if (i>0 && i<arraylen-1)
4131
 
         {
4132
 
            if (array[i+1] == array[i]+1)
4133
 
               space = FALSE;
4134
 
            else
4135
 
               space = TRUE;
4136
 
         }
4137
 
      }
4138
 
      i--;
4139
 
      len -= offset;
4140
 
      if (array[index] == trans[stop_sect])
4141
 
      {
4142
 
         end = trans[stop_sect];
4143
 
         endoffset = dsp->lens[trans[stop_sect]] - (amp->to_aln - saip->aligncoords[trans[stop_sect]]);
4144
 
         if (endoffset < 0)
4145
 
            endoffset = 0;
4146
 
      } else if (array[i] == trans[stop_sect] && array[i] == array[i-1]+1)
4147
 
      {
4148
 
         endoffset = dsp->lens[trans[stop_sect]] - (amp->to_aln - saip->aligncoords[trans[stop_sect]]);
4149
 
         if (endoffset < 0)
4150
 
            endoffset = 0;
4151
 
      } else
4152
 
      {
4153
 
         end = array[i-1];
4154
 
         endoffset = 0;
4155
 
      }
4156
 
      beg = trans[start_sect];
4157
 
      if (amp->type == AM_GAP)
4158
 
      {
4159
 
         amp->from_row = amp->real_from;
4160
 
         amp->to_row = amp->from_row + len + endoffset - 1;
4161
 
      } else
4162
 
      {
4163
 
         if (amp->strand != Seq_strand_minus)
4164
 
         {
4165
 
            amp->from_row = dsp->starts[trans[start_sect]*(dsp->dim)+amp->row_num-1] + offset;
4166
 
            amp->to_row = amp->from_row + len + endoffset - 1;
4167
 
         } else
4168
 
         {
4169
 
            amp->from_row = dsp->starts[trans[i-1]*(dsp->dim)+amp->row_num-1] + endoffset;
4170
 
            amp->to_row = amp->from_row + len - 1;
4171
 
         }
4172
 
      }
4173
 
      amp->real_from += (amp->to_row - amp->from_row) + 1;
4174
 
      /* now look for adjacent inserts */
4175
 
      if ((start_row = binary_search_on_uint2_list(srdp->insect, beg-1, srdp->numinsect)) != -1)
4176
 
      {
4177
 
         array = srdp->insect;
4178
 
         amp->left_insert = (AMAdjacPtr)MemNew(sizeof(AMAdjac));
4179
 
         len = 0;
4180
 
         for (i=start_row-1; array[i] == array[i+1]-1 && i >= 0; i--)
4181
 
         {
4182
 
            len += dsp->lens[array[i]];
4183
 
         }
4184
 
         if (amp->strand != Seq_strand_minus)
4185
 
         {
4186
 
            amp->left_insert->from = dsp->starts[array[start_row]*(dsp->dim) + amp->row_num-1] - len;
4187
 
            amp->left_insert->to = amp->from_row - 1;
4188
 
         } else
4189
 
         {
4190
 
            amp->left_insert->from = amp->to_row + 1;
4191
 
            amp->left_insert->to = dsp->starts[(array[start_row]-1)*(dsp->dim) + amp->row_num-1] + len;
4192
 
         }
4193
 
      }
4194
 
      if ((stop_row = binary_search_on_uint2_list(srdp->insect, end+1, srdp->numinsect)) != -1)
4195
 
      {
4196
 
         array = srdp->insect;
4197
 
         amp->right_insert = (AMAdjacPtr)MemNew(sizeof(AMAdjac));
4198
 
         len = 0;
4199
 
         for (i=stop_row+1; array[i] == array[i-1] + 1 && i < srdp->numinsect; i++)
4200
 
         {
4201
 
            len += dsp->lens[array[i]];
4202
 
         }
4203
 
         if (amp->strand != Seq_strand_minus)
4204
 
         {
4205
 
            amp->right_insert->from = amp->to_row + 1;
4206
 
            amp->right_insert->to = dsp->starts[(array[stop_row])*(dsp->dim) + amp->row_num - 1] + dsp->lens[array[stop_row]] + len-1;
4207
 
         } else
4208
 
         {
4209
 
            amp->right_insert->from = dsp->starts[array[stop_row]*(dsp->dim) + amp->row_num - 1] - len;
4210
 
            amp->right_insert->to = amp->from_row - 1;
4211
 
         }
4212
 
      }
4213
 
   }
4214
 
   if (saip->anchor < 1)
4215
 
      MemFree(trans);
4216
 
   return TRUE;
4217
 
}
4218
 
 
4219
 
/* SECTION 4a */
4220
5945
static Int4 binary_search_on_uint4_list(Uint4Ptr list, Uint4 pos, Uint4 listlen)
4221
5946
{
4222
5947
   Uint4  L;
4239
5964
}
4240
5965
 
4241
5966
/* SECTION 4a */
4242
 
static Int4 binary_search_on_uint2_list(Uint2Ptr list, Uint2 ele, Uint2 listlen)
 
5967
static Int4 binary_search_on_uint2_list(Uint2Ptr list, Int4 ele, Uint2 listlen)
4243
5968
{
4244
5969
   Uint2  L;
4245
5970
   Uint2  mid;
4246
5971
   Uint2  R;
4247
5972
 
4248
 
   if (list == NULL || listlen == 0)
 
5973
   if (list == NULL || listlen == 0 || ele < 0)
4249
5974
      return -1;
4250
5975
   L = 0;
4251
5976
   R = listlen - 1;
4272
5997
   Int4             i;
4273
5998
   SAIndex2Ptr       saip;
4274
5999
   Uint1            strand;
 
6000
   Int4             tmp;
4275
6001
 
4276
6002
   if (sap == NULL)
4277
6003
      return;
4312
6038
      }
4313
6039
   }
4314
6040
   if (*from > *to)
4315
 
      *from = *to = -1;
 
6041
   {
 
6042
      tmp = *from;
 
6043
      *from = *to;
 
6044
      *to = tmp;
 
6045
   }
 
6046
}
 
6047
 
 
6048
/* SECTION 4a */
 
6049
/***************************************************************************
 
6050
*
 
6051
*  AlnMgr2GetInterruptInfo returns a structure describing the inserts and
 
6052
*  unaligned regions in an interrupt. The structure is allocated by this
 
6053
*  function and must be freed with AlnMgr2FreeInterruptInfo.
 
6054
*
 
6055
***************************************************************************/
 
6056
NLM_EXTERN AMInterrInfoPtr AlnMgr2GetInterruptInfo(SeqAlignPtr sap, AMInterruptPtr interrupt)
 
6057
{
 
6058
   AMAlignIndex2Ptr  amaip;
 
6059
   Int4              disc;
 
6060
   Boolean           done;
 
6061
   DenseSegPtr       dsp;
 
6062
   Int4              i;
 
6063
   AMInterrInfoPtr   iip;
 
6064
   Int4              inserts;
 
6065
   Int4              intfrom;
 
6066
   Int4              intto;
 
6067
   Int4              j;
 
6068
   Int4              k;
 
6069
   Int4              n;
 
6070
   SAIndex2Ptr       saip;
 
6071
   SARowDat2Ptr      srdp;
 
6072
   Uint1             strand;
 
6073
   Uint2Ptr          trans;
 
6074
   Int4              translen;
 
6075
   Int4              u;
 
6076
 
 
6077
   if (interrupt == NULL || sap == NULL || sap->saip == NULL)
 
6078
      return NULL;
 
6079
   if (sap->saip->indextype == INDEX_CHILD)
 
6080
   {
 
6081
      dsp = (DenseSegPtr)(sap->segs);
 
6082
      saip = (SAIndex2Ptr)(sap->saip);
 
6083
   } else if (sap->saip->indextype == INDEX_PARENT)
 
6084
   {
 
6085
      amaip = (AMAlignIndex2Ptr)(sap->saip);
 
6086
      if (amaip->alnstyle == AM2_LITE)
 
6087
         return FALSE;
 
6088
      dsp = (DenseSegPtr)(amaip->sharedaln->segs);
 
6089
      saip = (SAIndex2Ptr)(amaip->sharedaln->saip);
 
6090
   }
 
6091
   if (dsp->numseg < interrupt->segnum)
 
6092
      return NULL;
 
6093
   if (saip->anchor > 0)
 
6094
   {
 
6095
      trans = saip->srdp[saip->anchor-1]->sect;
 
6096
      translen = saip->srdp[saip->anchor-1]->numsect;
 
6097
   } else
 
6098
   {
 
6099
      trans = (Uint2Ptr)MemNew(dsp->numseg*sizeof(Uint2));
 
6100
      for (i=0; i<dsp->numseg; i++)
 
6101
      {
 
6102
         trans[i] = i;
 
6103
      }
 
6104
      translen = dsp->numseg;
 
6105
   }
 
6106
   strand = AlnMgr2GetNthStrand(sap, interrupt->row-1);
 
6107
   srdp = saip->srdp[interrupt->row-1];
 
6108
   /* now look for inserts and unaligned regions on the side indicated */
 
6109
   if (interrupt->which_side == AM2_RIGHT)
 
6110
   {
 
6111
      /* check if this is unaligned */
 
6112
      disc = binary_search_on_uint2_list(srdp->unaligned, interrupt->segnum, srdp->numunaln);
 
6113
      /* then look for inserts */
 
6114
      done = FALSE;
 
6115
      iip = (AMInterrInfoPtr)MemNew(sizeof(AMInterrInfo));
 
6116
      if (disc != -1)
 
6117
         iip->num = 1;
 
6118
      inserts = 0;
 
6119
      for (i=interrupt->segnum+1; !done; i++)
 
6120
      {
 
6121
         n = binary_search_on_uint2_list(srdp->insect, i, srdp->numinsect);
 
6122
         if (n == -1)
 
6123
            n = binary_search_on_uint2_list(srdp->unsect, i, srdp->numunsect);
 
6124
         if (n == -1)
 
6125
         {
 
6126
            done = TRUE;
 
6127
         } else
 
6128
         {
 
6129
            inserts++; /* only increment if region gets interrupted */
 
6130
            disc = binary_search_on_uint2_list(srdp->unaligned, i, srdp->numunaln);
 
6131
            if (disc != -1) /* this insert has an unaligned region */
 
6132
            {
 
6133
               iip->num += inserts;
 
6134
               iip->num++;
 
6135
               inserts = 0;
 
6136
            }
 
6137
         }
 
6138
      }
 
6139
      if (inserts != 0)
 
6140
         iip->num++;
 
6141
      iip->starts = (Int4Ptr)MemNew(iip->num*sizeof(Int4));
 
6142
      iip->lens = (Int4Ptr)MemNew(iip->num*sizeof(Int4));
 
6143
      iip->types = (Int4Ptr)MemNew(iip->num*sizeof(Int4));
 
6144
      k = 0;
 
6145
      disc = binary_search_on_uint2_list(srdp->unaligned, interrupt->segnum, srdp->numunaln);
 
6146
      if (disc != -1) /* starts with unaligned */
 
6147
      {
 
6148
         AlnMgr2GetUnalignedInfo(sap, interrupt->segnum, interrupt->row, &intfrom, &intto);
 
6149
         iip->starts[k] = intfrom;
 
6150
         iip->lens[k] = intto - intfrom + 1;
 
6151
         iip->types[k] = AM_UNALIGNED;
 
6152
         k++;
 
6153
      }
 
6154
      disc = 0;
 
6155
      done = FALSE;
 
6156
      for (i=interrupt->segnum+1; !done; i++)
 
6157
      {
 
6158
         n = binary_search_on_uint2_list(srdp->insect, i, srdp->numinsect);
 
6159
         u = binary_search_on_uint2_list(srdp->unsect, i, srdp->numinsect);
 
6160
         if (n == -1 && u == -1)
 
6161
         {
 
6162
            done = TRUE;
 
6163
         } else
 
6164
         {
 
6165
            if (u == -1)
 
6166
            {
 
6167
               if (disc != -1 || strand == Seq_strand_minus) /* only record new start if region gets interrupted or if on minus strand */
 
6168
                  iip->starts[k] = dsp->starts[dsp->dim*i + interrupt->row-1];
 
6169
               iip->lens[k] += dsp->lens[i];
 
6170
               iip->types[k] = AM_INSERT;
 
6171
               disc = binary_search_on_uint2_list(srdp->unaligned, i, srdp->numunaln);
 
6172
               if (disc != -1) /* this insert has an unaligned region */
 
6173
               {
 
6174
                  k++;
 
6175
                  AlnMgr2GetUnalignedInfo(sap, i, interrupt->row, &intfrom, &intto);
 
6176
                  iip->starts[k] = intfrom;
 
6177
                  iip->lens[k] = intto - intfrom + 1;
 
6178
                  iip->types[k] = AM_UNALIGNED;
 
6179
                  k++;
 
6180
               }
 
6181
            }
 
6182
         }
 
6183
      }
 
6184
   } else if (interrupt->which_side == AM2_LEFT)
 
6185
   {
 
6186
      /* check if the next non-gap segment to the left has unaligned */
 
6187
      j = 1;
 
6188
      n = 0;
 
6189
      while (n != -1 && interrupt->segnum-j >= 0)
 
6190
      {
 
6191
         n = binary_search_on_uint2_list(srdp->unsect, interrupt->segnum-j, srdp->numunsect);
 
6192
         if (n == -1)
 
6193
            n = binary_search_on_uint2_list(srdp->insect, interrupt->segnum-j, srdp->numinsect);
 
6194
         if (n != -1)
 
6195
            j++;
 
6196
      }
 
6197
      disc = binary_search_on_uint2_list(srdp->unaligned, interrupt->segnum-j, srdp->numunaln);
 
6198
      /* then look for inserts */
 
6199
      done = FALSE;
 
6200
      iip = (AMInterrInfoPtr)MemNew(sizeof(AMInterrInfo));
 
6201
      if (disc != -1)
 
6202
         iip->num = 1;
 
6203
      inserts = 0;
 
6204
      for (i=interrupt->segnum-1; !done; i--)
 
6205
      {
 
6206
         n = binary_search_on_uint2_list(srdp->insect, i, srdp->numinsect);
 
6207
         if (n == -1)
 
6208
            n = binary_search_on_uint2_list(srdp->unsect, i, srdp->numunsect);
 
6209
         if (n == -1)
 
6210
         {
 
6211
            done = TRUE;
 
6212
         } else
 
6213
         {
 
6214
            inserts++; /* only increment if region gets interrupted */
 
6215
            disc = binary_search_on_uint2_list(srdp->unaligned, i, srdp->numunaln);
 
6216
            if (disc != -1) /* this insert has an unaligned region */
 
6217
            {
 
6218
               iip->num += inserts;
 
6219
               iip->num++;
 
6220
               inserts = 0;
 
6221
            }
 
6222
         }
 
6223
      }
 
6224
      i++;
 
6225
      iip->starts = (Int4Ptr)MemNew(iip->num*sizeof(Int4));
 
6226
      iip->lens = (Int4Ptr)MemNew(iip->num*sizeof(Int4));
 
6227
      iip->types = (Int4Ptr)MemNew(iip->num*sizeof(Int4));
 
6228
      k = 0;
 
6229
      disc = 0;
 
6230
      /* check first non-inserted segment for unaligned */
 
6231
      if (i >= 0)
 
6232
      {
 
6233
         disc = binary_search_on_uint2_list(srdp->unaligned, i, srdp->numunaln);
 
6234
         if (disc != -1) /* there's an unaligned region */
 
6235
         {
 
6236
            AlnMgr2GetUnalignedInfo(sap, i, interrupt->row, &intfrom, &intto);
 
6237
            iip->starts[k] = intfrom;
 
6238
            iip->lens[k] = intto - intfrom + 1;
 
6239
            iip->types[k] = AM_UNALIGNED;
 
6240
            k++;
 
6241
         }
 
6242
      }
 
6243
      i++; /* start from leftmost end of inserts/unaligned */
 
6244
      for (i; i<interrupt->segnum; i++)
 
6245
      {
 
6246
         u = binary_search_on_uint2_list(srdp->unsect, i, srdp->numunsect);
 
6247
         if (u == -1)
 
6248
         {
 
6249
            if (disc != -1 || strand == Seq_strand_minus) /* only record new start if region gets interrupted or if on minus strand */
 
6250
               iip->starts[k] = dsp->starts[dsp->dim*i + interrupt->row-1];
 
6251
            iip->lens[k] += dsp->lens[i];
 
6252
            iip->types[k] = AM_INSERT;
 
6253
            disc = binary_search_on_uint2_list(srdp->unaligned, i, srdp->numunaln);
 
6254
            if (disc != -1) /* this insert has an unaligned region */
 
6255
            {
 
6256
               k++;
 
6257
               AlnMgr2GetUnalignedInfo(sap, binary_search_on_uint2_list(trans, i, translen), interrupt->row, &intfrom, &intto);
 
6258
               iip->starts[k] = intfrom;
 
6259
               iip->lens[k] = intto - intfrom + 1;
 
6260
               iip->types[k] = AM_UNALIGNED;
 
6261
               k++;
 
6262
            }
 
6263
         }
 
6264
      }
 
6265
   }
 
6266
   iip->strand = strand;
 
6267
   return iip;
4316
6268
}
4317
6269
 
4318
6270
/* SECTION 4b */
4335
6287
      dsp = (DenseSegPtr)(sap->segs);
4336
6288
      if (n > dsp->dim)
4337
6289
         return 0;
 
6290
      if (dsp->strands == NULL)
 
6291
         return Seq_strand_plus;
4338
6292
      return (dsp->strands[n-1]);
4339
6293
   } else if (sap->saip->indextype == INDEX_PARENT)
4340
6294
   {
4344
6298
      dsp = (DenseSegPtr)(amaip->sharedaln->segs);
4345
6299
      if (n > dsp->dim)
4346
6300
         return 0;
 
6301
      if (dsp->strands == NULL)
 
6302
         return Seq_strand_plus;
4347
6303
      return (dsp->strands[n-1]);
4348
6304
   }
4349
6305
   return 0;
4372
6328
      if (n > dsp->dim)
4373
6329
         return NULL;
4374
6330
      sip = dsp->ids;
4375
 
      for (i=1; i<n; i++)
 
6331
      for (i=1; i<n && sip != NULL; i++)
4376
6332
      {
4377
6333
         sip = sip->next;
4378
6334
      }
 
6335
      if (sip == NULL) return NULL;
4379
6336
      return (SeqIdDup(sip));
4380
6337
   } else if (sap->saip->indextype == INDEX_PARENT)
4381
6338
   {
4393
6350
*
4394
6351
*  AlnMgr2GetNthSeqRangeInSA returns the smallest and largest sequence
4395
6352
*  coordinates contained in the nth row of an indexed seqalign. Either
4396
 
*  start or stop can be NULL to only retrieve one of the coordinates. RANGE
 
6353
*  start or stop can be NULL to only retrieve one of the coordinates. 
 
6354
*  If start and stop are -1, there is an error; if they are both -2, the
 
6355
*  row is just one big insert. RANGE
4397
6356
*
4398
6357
***************************************************************************/
4399
6358
NLM_EXTERN void AlnMgr2GetNthSeqRangeInSA(SeqAlignPtr sap, Int4 n, Int4Ptr start, Int4Ptr stop)
4430
6389
   if (n > saip->numrows || n <= 0)
4431
6390
      return;
4432
6391
   srdp = saip->srdp[n-1];
 
6392
   beg = -1;
 
6393
   if (srdp->numsect == 0) /* just one big insert */
 
6394
      beg = end = -2;
4433
6395
   strand = AlnMgr2GetNthStrand(sap, n);
4434
 
   if (strand != Seq_strand_minus)
 
6396
   if (beg != -2 && strand != Seq_strand_minus)
4435
6397
   {
4436
6398
      beg = dsp->starts[srdp->sect[0]*(dsp->dim) + n-1];
4437
6399
      end = dsp->starts[srdp->sect[srdp->numsect-1]*(dsp->dim) + n-1] + dsp->lens[srdp->sect[srdp->numsect-1]] - 1;
4438
 
   } else
 
6400
   } else if (beg != -2)
4439
6401
   {
4440
6402
      beg = dsp->starts[srdp->sect[srdp->numsect-1]*(dsp->dim) + n-1];
4441
6403
      end = dsp->starts[srdp->sect[0]*(dsp->dim) + n-1] + dsp->lens[srdp->sect[0]] - 1;
4615
6577
         } else
4616
6578
         {
4617
6579
            if (start)
4618
 
               *start = tmp_stop-1;
 
6580
               *start = tmp_stop+1;
4619
6581
            if (stop)
4620
6582
               *stop = bsp->length-1;
4621
6583
         }
4773
6735
   SAIndex2Ptr       saip;
4774
6736
 
4775
6737
   if (sap == NULL || sap->saip == NULL)
4776
 
      return FALSE;
 
6738
      return -1;
4777
6739
   if (sap->saip->indextype == INDEX_CHILD)
4778
6740
   {
4779
6741
      saip = (SAIndex2Ptr)(sap->saip);
4781
6743
   {
4782
6744
      amaip = (AMAlignIndex2Ptr)(sap->saip);
4783
6745
      if (amaip->alnstyle == AM2_LITE)
4784
 
         return FALSE;
 
6746
         return -1;
4785
6747
      saip = (SAIndex2Ptr)(amaip->sharedaln->saip);
4786
6748
   }
4787
 
   return (saip->numunaln);
 
6749
   if (saip->numunaln >= 0)
 
6750
      return (saip->numunaln + 1);
 
6751
   else if (saip->numunaln == -1)
 
6752
      return 1;
 
6753
   else
 
6754
      return -1;
4788
6755
}
4789
6756
 
4790
6757
/* SECTION 4c */ /* FOR DDV */
4862
6829
         *stop = -1;
4863
6830
      return FALSE;
4864
6831
   }
4865
 
   seg = saip->unaln[unaligned-1];
 
6832
   seg = -1;
 
6833
   if (unaligned <= saip->numunaln && unaligned > 0)
 
6834
      seg = saip->unaln[unaligned-1];
4866
6835
   if (start)
4867
6836
      *start = -1;
4868
6837
   if (stop)
5229
7198
 
5230
7199
/***************************************************************************
5231
7200
*
 
7201
*  AlnMgr2GetFirstNForSipList returns the first row that one of a list of seqids occur on,
 
7202
*  or -1 if none of the seqids are in the alignment or if there is another
 
7203
*  error. 
 
7204
*  Handy if sip comes from a BioSeq, where it can point to a linked list
 
7205
*  of SeqIds.
 
7206
*
 
7207
***************************************************************************/
 
7208
NLM_EXTERN Int4 AlnMgr2GetFirstNForSipList(SeqAlignPtr sap, SeqIdPtr sip)
 
7209
{
 
7210
    Int4    i;
 
7211
    if (sap == NULL || sap->saip == NULL)
 
7212
        return -1;
 
7213
    
 
7214
    for (; sip; sip = sip->next) {
 
7215
        i = AlnMgr2GetFirstNForSip(sap, sip);
 
7216
        if (i != -1)
 
7217
            return i;
 
7218
    }
 
7219
    return -1;
 
7220
}
 
7221
 
 
7222
/***************************************************************************
 
7223
*
5232
7224
*  AlnMgr2GetParent returns the top-level seqalign associated with a given
5233
7225
*  indexed alignment. It returns the actual pointer, not a copy.
5234
7226
*
5288
7280
      AlnMgr2IndexSingleDenseSegSA(sap);
5289
7281
      if (which_row <= 0)
5290
7282
         return;
 
7283
      saip = (SAIndex2Ptr)(sap->saip);
5291
7284
   }
5292
7285
   numunsect = saip->srdp[which_row-1]->numunsect;
5293
7286
   if (numunsect > 0)
5512
7505
   Int4             mid;
5513
7506
   Int4             offset;
5514
7507
   Int4             R;
 
7508
   Int4             retval;
5515
7509
   SAIndex2Ptr       saip;
5516
7510
   SARowDat2Ptr      srdp;
5517
7511
   Int4             start;
5555
7549
   {
5556
7550
      while (L < R)
5557
7551
      {
5558
 
         mid = (L + R)/2;
5559
 
         if (dsp->starts[(srdp->sect[mid+1])*(dsp->dim)+row-1] >= pos)
 
7552
         mid = ceil((L + R)/2);
 
7553
         if (dsp->starts[(srdp->sect[mid])*(dsp->dim)+row-1] > pos)
5560
7554
            L = mid + 1;
5561
7555
         else
5562
7556
            R = mid;
5570
7564
      array = saip->srdp[saip->anchor-1]->sect;
5571
7565
      R = binary_search_on_uint2_list(array, srdp->sect[L], saip->srdp[saip->anchor-1]->numsect);
5572
7566
      L = R;
 
7567
      srdp = saip->srdp[saip->anchor-1];
 
7568
      if (strand != Seq_strand_minus)
 
7569
         retval = (saip->aligncoords[L] + offset);
 
7570
      else
 
7571
         retval = (saip->aligncoords[L] + dsp->lens[srdp->sect[L]] - offset - 1);
 
7572
   } else
 
7573
   {
 
7574
      if (strand != Seq_strand_minus)
 
7575
         retval = saip->aligncoords[srdp->sect[L]] + offset;
 
7576
      else
 
7577
         retval = (saip->aligncoords[srdp->sect[L]] + dsp->lens[srdp->sect[L]] - offset - 1);
5573
7578
   }
5574
 
   if (strand != Seq_strand_minus)
5575
 
      return (saip->aligncoords[srdp->sect[L]] + offset);
5576
 
   else
5577
 
      return (saip->aligncoords[srdp->sect[L]] + dsp->lens[srdp->sect[L]] - offset - 1);
 
7579
   return retval;
5578
7580
}
5579
7581
 
5580
7582
/* SECTION 6 */
5617
7619
      saip = (SAIndex2Ptr)(amaip->sharedaln->saip);
5618
7620
      dsp = (DenseSegPtr)(amaip->sharedaln->segs);
5619
7621
   }
 
7622
   if (row > saip->numrows)
 
7623
   return -1;
 
7624
 
5620
7625
   sect = binary_search_on_uint4_list(saip->aligncoords, pos, saip->numseg);
5621
7626
   offset = pos - saip->aligncoords[sect];
5622
7627
   if (saip->anchor > 0)
5710
7715
               to = from;
5711
7716
               from = tmp;
5712
7717
            }
5713
 
            sap1 = AlnMgr2GetSubAlign(sap, from, to, 0);
 
7718
            sap1 = AlnMgr2GetSubAlign(sap, from, to, 0, TRUE);
5714
7719
            AlnMgr2IndexSingleChildSeqAlign(sap1);
5715
7720
            from = AlnMgr2MapBioseqToSeqAlign(sap, stop+1, row);
5716
7721
            if (from < 0)
5722
7727
               to = from;
5723
7728
               from = tmp;
5724
7729
            }
5725
 
            sap2 = AlnMgr2GetSubAlign(sap, from, to, 0);
 
7730
            sap2 = AlnMgr2GetSubAlign(sap, from, to, 0, TRUE);
5726
7731
            sap2->next = sap->next;
5727
7732
            sap->next = sap2;
5728
7733
            dsp = (DenseSegPtr)(sap->segs);
5744
7749
            to = from;
5745
7750
            from = tmp;
5746
7751
         }
5747
 
         sap1 = AlnMgr2GetSubAlign(sap, from, to, 0);
 
7752
         sap1 = AlnMgr2GetSubAlign(sap, from, to, 0, TRUE);
5748
7753
         if (mstop == stop) /* done */
5749
7754
         {
5750
7755
            dsp = (DenseSegPtr)(sap->segs);
5766
7771
               to = from;
5767
7772
               from = tmp;
5768
7773
            }
5769
 
            sap2 = AlnMgr2GetSubAlign(sap, from, to, 0);
 
7774
            sap2 = AlnMgr2GetSubAlign(sap, from, to, 0, TRUE);
5770
7775
            sap2->next = sap->next;
5771
7776
            sap->next = sap2;
5772
7777
            AlnMgr2IndexSingleChildSeqAlign(sap2);
5863
7868
*  'from' to 'to' in the row coordinates specified, or if which_row is 0,
5864
7869
*  'from' and 'to' are assumed to be alignment coordinates. If 'to' is -1,
5865
7870
*  the subalignment will go to the end of the specified row (or to the end
5866
 
*  of the whole alignment).
 
7871
*  of the whole alignment). If the alignment is discontinuous and fill_in
 
7872
*  is FALSE, the alignment will be returned as an SAS_DISC set, each piece
 
7873
*  represented by a single alignment. If the alignment is discontinuous and
 
7874
*  fill_in is TRUE, the unaligned regions will be added in to the alignment,
 
7875
*  with all gaps in all other rows. If the alignment is continuous, it
 
7876
*  doesn't matter whether fill_in is TRUE or FALSE. (SUBALIGN)
5867
7877
*
5868
7878
***************************************************************************/
5869
 
NLM_EXTERN SeqAlignPtr AlnMgr2GetSubAlign(SeqAlignPtr sap, Int4 from, Int4 to, Int4 which_row)
 
7879
NLM_EXTERN SeqAlignPtr AlnMgr2GetSubAlign(SeqAlignPtr sap, Int4 from, Int4 to, Int4 which_row, Boolean fill_in)
5870
7880
{
5871
7881
   Int4             a;
5872
7882
   AMAlignIndex2Ptr  amaip;
5873
7883
   AlnMsg2Ptr        amp;
5874
7884
   Boolean          anchored;
 
7885
   Int4             currlen;
5875
7886
   DenseSegPtr      dsp;
 
7887
   DenseSegPtr      dsp_new;
5876
7888
   Int4             from_aln;
5877
7889
   Int4             from_seq;
5878
7890
   Int4             i;
5879
7891
   SeqIdPtr         id;
5880
7892
   Int4             j;
 
7893
   Int4             k;
5881
7894
   Int4             len;
 
7895
   Int4             lengthbit;
5882
7896
   Int4             minlen;
5883
7897
   Boolean          more;
5884
7898
   Int4             n;
5885
7899
   Int4             numseg;
 
7900
   Int4             numunaln;
5886
7901
   AMRowInfoPtr     row;
5887
7902
   AMRowInfoPtr     row_head;
5888
7903
   AMRowInfoPtr     row_prev;
5889
7904
   AMRowInfoPtr     PNTR rowheads;
5890
7905
   AMRowInfoPtr     PNTR rows;
5891
7906
   SeqAlignPtr      salp;
 
7907
   SeqAlignPtr      salp_head;
 
7908
   SeqAlignPtr      salp_prev;
5892
7909
   SeqAlignPtr      sap_real;
 
7910
   Int4             seg;
5893
7911
   Int4             start_seg;
5894
7912
   Uint1            strand;
5895
7913
   SeqAlignPtr      subsalp;
5896
7914
   Int4             tmp;
5897
7915
   Int4             to_aln;
5898
7916
   Int4             to_seq;
 
7917
   Int4             ustart;
 
7918
   Int4             ustop;
5899
7919
 
5900
7920
   if (sap == NULL || sap->saip == NULL)
5901
7921
      return NULL;
5902
7922
   len = AlnMgr2GetAlnLength(sap, FALSE);
5903
 
   if (to > len-1 || from < 0)
 
7923
   if (which_row == 0 && (to > len-1 || from < 0))
5904
7924
      return NULL;
5905
7925
   n = AlnMgr2GetNumRows(sap);
5906
7926
   if (which_row < 0 || which_row > n)
5920
7940
      if (amaip->alnstyle == AM2_LITE)
5921
7941
         return NULL;
5922
7942
      sap_real = amaip->sharedaln;
5923
 
      if (from == 0 && to == len-1)  /* need whole aln -- take a shortcut! */
 
7943
      if (from == 0 && to == len-1 && !AlnMgr2IsSAPDiscAli(sap_real))  /* need whole aln -- take a shortcut! */
5924
7944
         return SeqAlignDup(sap_real);
5925
7945
   }
5926
7946
   if ((a = AlnMgr2FindAnchor(sap_real)) > 0)
5971
7991
      }
5972
7992
   }
5973
7993
   rows = (AMRowInfoPtr PNTR)MemNew(n*sizeof(AMRowInfoPtr));
5974
 
   numseg = AlnMgr2GetNumSegsInRange(sap, from_aln, to_aln, &start_seg);
5975
 
   if (start_seg < 0)
5976
 
      return NULL;
5977
7994
   amp = AlnMsgNew2();
5978
 
   for (i=0; i<n; i++)
5979
 
   {
5980
 
      row_head = NULL;
5981
 
      for (j=start_seg; j<numseg+start_seg; j++)
5982
 
      {
5983
 
         AlnMsgReNew2(amp);
5984
 
         AlnMgr2GetNthSegmentRange(sap, j+1, &amp->from_aln, &amp->to_aln);
5985
 
         amp->from_aln = MAX(amp->from_aln, from_aln);
5986
 
         amp->to_aln = MIN(amp->to_aln, to_aln);
5987
 
         amp->row_num = i+1;
5988
 
         while ((more = AlnMgr2GetNextAlnBit(salp, amp)) == TRUE)
5989
 
         {
5990
 
            row = (AMRowInfoPtr)MemNew(sizeof(AMRowInfo));
5991
 
            if (amp->type == AM_GAP)
5992
 
               row->from = -1;
5993
 
            else
5994
 
               row->from = amp->from_row;
5995
 
            row->len = amp->to_row - amp->from_row + 1;
5996
 
            if (row_head != NULL)
5997
 
            {
5998
 
               row_prev->next = row;
5999
 
               row_prev = row;
6000
 
            } else
6001
 
               row_head = row_prev = row;
6002
 
         }
6003
 
      }
6004
 
      rows[i] = row_head;
6005
 
   }
6006
 
   AlnMsgFree2(amp);
6007
 
   rowheads = (AMRowInfoPtr PNTR)MemNew(n*sizeof(AMRowInfoPtr));
6008
 
   for (i=0; i<n; i++)
6009
 
   {
6010
 
      rowheads[i] = rows[i];
6011
 
   }
6012
 
   while (rows[0] != NULL)
6013
 
   {
6014
 
      minlen = -1;
6015
 
      for (i=0; i<n; i++)
6016
 
      {
6017
 
         if (rows[i]->len < minlen || minlen == -1)
6018
 
            minlen = rows[i]->len;
6019
 
      }
6020
 
      for (i=0; i<n; i++)
6021
 
      {
6022
 
         if (rows[i]->len > minlen)
6023
 
         {
6024
 
            row = (AMRowInfoPtr)MemNew(sizeof(AMRowInfo));
6025
 
            row->next = rows[i]->next;
6026
 
            rows[i]->next = row;
6027
 
            if (rows[i]->from == -1)
6028
 
               row->from = -1;
6029
 
            else if (AlnMgr2GetNthStrand(salp, i) == Seq_strand_minus)
6030
 
            {
6031
 
               row->from = rows[i]->from;
6032
 
               rows[i]->from = rows[i]->from + rows[i]->len - 1 - minlen;
6033
 
            } else
6034
 
               row->from = rows[i]->from + minlen;
6035
 
            row->len = rows[i]->len - minlen;
6036
 
            rows[i]->len = minlen;
6037
 
         }
6038
 
         rows[i] = rows[i]->next;
6039
 
      }
6040
 
   }
6041
 
   for (i=0; i<n; i++)
6042
 
   {
6043
 
      rows[i] = rowheads[i];
6044
 
   }
6045
 
   MemFree(rowheads);
6046
 
   dsp = DenseSegNew();
6047
 
   row = rows[0];
6048
 
   while (row != NULL)
6049
 
   {
6050
 
      dsp->numseg++;
6051
 
      row = row->next;
6052
 
   }
6053
 
   dsp->dim = n;
6054
 
   dsp->lens = (Int4Ptr)MemNew((dsp->numseg)*sizeof(Int4));
6055
 
   dsp->starts = (Int4Ptr)MemNew((dsp->numseg)*(dsp->dim)*sizeof(Int4));
6056
 
   dsp->strands = (Uint1Ptr)MemNew((dsp->numseg)*(dsp->dim)*sizeof(Int4));
6057
 
   j = 0;
6058
 
   row = rows[0];
6059
 
   while (row != NULL)
6060
 
   {
6061
 
      dsp->lens[j] = row->len;
6062
 
      j++;
6063
 
      row = row->next;
6064
 
   }
6065
 
   id = AlnMgr2GetNthSeqIdPtr(salp, 0);
6066
 
   dsp->ids = id;
6067
 
   for (i=0; i<n; i++)
6068
 
   {
6069
 
      if (i > 0)
6070
 
      {
6071
 
         id->next = AlnMgr2GetNthSeqIdPtr(salp, i+1);
6072
 
         id = id->next;
6073
 
      }
6074
 
      row = rows[i];
 
7995
   seg = lengthbit = 0;
 
7996
   currlen = 0;
 
7997
   numunaln = 0;
 
7998
   salp_head = salp_prev = NULL;
 
7999
   while (AlnMgr2GetNextLengthBit(sap, &lengthbit, &seg))
 
8000
   {
 
8001
      if (currlen <= to_aln && seg >= 0 && currlen+lengthbit-1 >= from_aln)
 
8002
      {
 
8003
         numseg = AlnMgr2GetNumSegsInRange(sap, currlen, currlen+lengthbit-1, &start_seg);
 
8004
         numunaln = 0;
 
8005
         for (i=0; i<n; i++)
 
8006
         {
 
8007
            row_head = NULL;
 
8008
            for (j=start_seg; j<numseg+start_seg; j++)
 
8009
            {
 
8010
               AlnMsgReNew2(amp);
 
8011
               AlnMgr2GetNthSegmentRange(sap, j+1, &amp->from_aln, &amp->to_aln);
 
8012
               amp->from_aln = MAX(amp->from_aln, from_aln);
 
8013
               amp->to_aln = MIN(amp->to_aln, to_aln);
 
8014
               amp->row_num = i+1;
 
8015
               while ((more = AlnMgr2GetNextAlnBit(salp, amp)) == TRUE)
 
8016
               {
 
8017
                  if (amp->right_interrupt != NULL && amp->right_interrupt->unalnlen > 0)
 
8018
                     numunaln++;
 
8019
                  row = (AMRowInfoPtr)MemNew(sizeof(AMRowInfo));
 
8020
                  if (amp->type == AM_GAP)
 
8021
                     row->from = -1;
 
8022
                  else
 
8023
                     row->from = amp->from_row;
 
8024
                  row->len = amp->to_row - amp->from_row + 1;
 
8025
                  if (row_head != NULL)
 
8026
                  {
 
8027
                     row_prev->next = row;
 
8028
                     row_prev = row;
 
8029
                  } else
 
8030
                     row_head = row_prev = row;
 
8031
               }
 
8032
            }
 
8033
            rows[i] = row_head;
 
8034
         }
 
8035
      }
 
8036
      rowheads = (AMRowInfoPtr PNTR)MemNew(n*sizeof(AMRowInfoPtr));
 
8037
      for (i=0; i<n; i++)
 
8038
      {
 
8039
         rowheads[i] = rows[i];
 
8040
      }
 
8041
      while (rows[0] != NULL)
 
8042
      {
 
8043
         minlen = -1;
 
8044
         for (i=0; i<n; i++)
 
8045
         {
 
8046
            if (rows[i]->len < minlen || minlen == -1)
 
8047
               minlen = rows[i]->len;
 
8048
         }
 
8049
         for (i=0; i<n; i++)
 
8050
         {
 
8051
            if (rows[i]->len > minlen)
 
8052
            {
 
8053
               row = (AMRowInfoPtr)MemNew(sizeof(AMRowInfo));
 
8054
               row->next = rows[i]->next;
 
8055
               rows[i]->next = row;
 
8056
               if (rows[i]->from == -1)
 
8057
                  row->from = -1;
 
8058
               else if (AlnMgr2GetNthStrand(salp, i) == Seq_strand_minus)
 
8059
               {
 
8060
                  row->from = rows[i]->from;
 
8061
                  rows[i]->from = rows[i]->from + rows[i]->len - 1 - minlen;
 
8062
               } else
 
8063
                  row->from = rows[i]->from + minlen;
 
8064
               row->len = rows[i]->len - minlen;
 
8065
               rows[i]->len = minlen;
 
8066
            }
 
8067
            rows[i] = rows[i]->next;
 
8068
         }
 
8069
      }
 
8070
      for (i=0; i<n; i++)
 
8071
      {
 
8072
         rows[i] = rowheads[i];
 
8073
      }
 
8074
      MemFree(rowheads);
 
8075
      dsp = DenseSegNew();
 
8076
      row = rows[0];
 
8077
      while (row != NULL)
 
8078
      {
 
8079
         dsp->numseg++;
 
8080
         row = row->next;
 
8081
      }
 
8082
      if (fill_in)
 
8083
         dsp->numseg += numunaln;
 
8084
      dsp->dim = n;
 
8085
      dsp->lens = (Int4Ptr)MemNew((dsp->numseg)*sizeof(Int4));
 
8086
      dsp->starts = (Int4Ptr)MemNew((dsp->numseg)*(dsp->dim)*sizeof(Int4));
 
8087
      dsp->strands = (Uint1Ptr)MemNew((dsp->numseg)*(dsp->dim)*sizeof(Int4));
6075
8088
      j = 0;
6076
 
      strand = AlnMgr2GetNthStrand(salp, i+1);
 
8089
      row = rows[0];
6077
8090
      while (row != NULL)
6078
8091
      {
6079
 
         dsp->starts[n*j + i] = row->from;
6080
 
         dsp->strands[n*j + i] = strand;
 
8092
         dsp->lens[j] = row->len;
6081
8093
         j++;
6082
8094
         row = row->next;
6083
8095
      }
6084
 
   }
6085
 
   subsalp = SeqAlignNew();
6086
 
   subsalp->type = SAT_PARTIAL;
6087
 
   subsalp->segtype = SAS_DENSEG;
6088
 
   subsalp->dim = n;
6089
 
   subsalp->segs = (Pointer)(dsp);
6090
 
   for (i=0; i<n; i++)
6091
 
   {
6092
 
      row = rows[i];
6093
 
      while (row != NULL)
6094
 
      {
6095
 
         row_prev = row->next;
6096
 
         MemFree(row);
6097
 
         row = row_prev;
6098
 
      }
 
8096
      id = AlnMgr2GetNthSeqIdPtr(salp, 0);
 
8097
      dsp->ids = id;
 
8098
      for (i=0; i<n; i++)
 
8099
      {
 
8100
         if (i > 0)
 
8101
         {
 
8102
            id->next = AlnMgr2GetNthSeqIdPtr(salp, i+1);
 
8103
            id = id->next;
 
8104
         }
 
8105
         row = rows[i];
 
8106
         j = 0;
 
8107
         strand = AlnMgr2GetNthStrand(salp, i+1);
 
8108
         while (row != NULL)
 
8109
         {
 
8110
            dsp->starts[n*j + i] = row->from;
 
8111
            dsp->strands[n*j + i] = strand;
 
8112
            j++;
 
8113
            row = row->next;
 
8114
         }
 
8115
      }
 
8116
      if (fill_in)
 
8117
      {
 
8118
         for (i=0; i<n; i++)
 
8119
         {
 
8120
            AlnMgr2GetNthUnalignedForNthRow(sap, seg+1, i+1, &ustart, &ustop);
 
8121
            if (ustart >= 0 && ustop >= ustart)
 
8122
            {
 
8123
               for (k=0; k<n; k++)
 
8124
               {
 
8125
                  dsp->starts[n*j + k] = -1;
 
8126
                  dsp->strands[n*j + k] = dsp->strands[i];
 
8127
               }
 
8128
               dsp->starts[n*j + i] = ustart;
 
8129
               j++;
 
8130
            }
 
8131
         }
 
8132
      }
 
8133
      subsalp = SeqAlignNew();
 
8134
      subsalp->type = SAT_PARTIAL;
 
8135
      subsalp->segtype = SAS_DENSEG;
 
8136
      subsalp->dim = n;
 
8137
      subsalp->segs = (Pointer)(dsp);
 
8138
      for (i=0; i<n; i++)
 
8139
      {
 
8140
         row = rows[i];
 
8141
         while (row != NULL)
 
8142
         {
 
8143
            row_prev = row->next;
 
8144
            MemFree(row);
 
8145
            row = row_prev;
 
8146
         }
 
8147
      }
 
8148
      if (seg < 0)
 
8149
         seg = -seg;
 
8150
      currlen += lengthbit;
 
8151
      seg++;
 
8152
      if (salp_head != NULL)
 
8153
      {
 
8154
         salp_prev->next = subsalp;
 
8155
         salp_prev = subsalp;
 
8156
      } else
 
8157
         salp_head = salp_prev = subsalp;
6099
8158
   }
6100
8159
   MemFree(rows);
 
8160
   AlnMsgFree2(amp);
 
8161
   if (fill_in && salp_head->next != NULL)  /* stick subsalps together into a big aln */
 
8162
   {
 
8163
      j = 0;
 
8164
      subsalp = salp_head;
 
8165
      while (subsalp != NULL)
 
8166
      {
 
8167
         dsp = (DenseSegPtr)(subsalp->segs);
 
8168
         j += dsp->numseg;
 
8169
         subsalp = subsalp->next;
 
8170
      }
 
8171
      dsp_new = DenseSegNew();
 
8172
      dsp_new->dim = n;
 
8173
      dsp_new->numseg = j;
 
8174
      dsp_new->lens = (Int4Ptr)MemNew((dsp->numseg)*sizeof(Int4));
 
8175
      dsp_new->starts = (Int4Ptr)MemNew((dsp->numseg)*(dsp->dim)*sizeof(Int4));
 
8176
      dsp_new->strands = (Uint1Ptr)MemNew((dsp->numseg)*(dsp->dim)*sizeof(Int4));
 
8177
      subsalp = salp_head;
 
8178
      k = 0;
 
8179
      while (subsalp != NULL)
 
8180
      {
 
8181
         dsp = (DenseSegPtr)(subsalp->segs);
 
8182
         for (j=0; j<dsp->numseg; j++)
 
8183
         {
 
8184
            dsp_new->lens[k] = dsp->lens[j];
 
8185
            for (i=0; i<n; i++)
 
8186
            {
 
8187
               dsp_new->starts[k*n+i] = dsp->starts[j*n+i];
 
8188
               dsp_new->strands[k*n+i] = dsp->strands[j*n+i];
 
8189
            }
 
8190
            k++;
 
8191
         }
 
8192
         subsalp = subsalp->next;
 
8193
      }
 
8194
      subsalp = SeqAlignNew();
 
8195
      subsalp->type = SAT_PARTIAL;
 
8196
      subsalp->segtype = SAS_DENSEG;
 
8197
      subsalp->dim = n;
 
8198
      subsalp->segs = (Pointer)(dsp_new);
 
8199
      SeqAlignSetFree(salp_head);
 
8200
   } else if (!fill_in && salp_head->next != NULL)
 
8201
   {
 
8202
      subsalp = SeqAlignNew();
 
8203
      subsalp->segtype = SAS_DISC;
 
8204
      subsalp->type = SAT_PARTIAL;
 
8205
      subsalp->segs = (SeqAlignPtr)(salp_head);
 
8206
      salp_prev = salp_head;
 
8207
      while (salp_prev != NULL)
 
8208
      {
 
8209
         AMAlignIndexFreeEitherIndex(salp_prev);
 
8210
         salp_prev = salp_prev->next;
 
8211
      }
 
8212
   } else  /* if !salp_head->next */
 
8213
   {
 
8214
      subsalp = salp_head;
 
8215
      subsalp->dim = AlnMgr2GetNumRows(subsalp);
 
8216
      subsalp->type = SAT_PARTIAL;
 
8217
      AMAlignIndexFreeEitherIndex(subsalp);
 
8218
   }
6101
8219
   if (anchored)
6102
8220
      SeqAlignFree(salp);
6103
8221
   return subsalp;
6168
8286
   mismatch = 0;
6169
8287
   seqscore = 0;
6170
8288
   afp = AlnMgr2ComputeFreqMatrix(sap, 0, -1, 0);
 
8289
   if (afp == NULL)
 
8290
     return -1;
6171
8291
   for (i=0; i<afp->len; i++)
6172
8292
   {
6173
8293
      res1 = -1;
6191
8311
   return score;
6192
8312
}
6193
8313
 
 
8314
static Int4 AlnMgr2SeqPortRead(SeqPortPtr PNTR spp, Uint1Ptr buf, Int4Ptr bufpos, Int4 start, Int4 stop, Uint1 strand, Uint1 code, BioseqPtr bsp)
 
8315
{
 
8316
    if (*spp == NULL) /* first call */ {
 
8317
        if (strand == Seq_strand_minus){
 
8318
            *spp = SeqPortNew(bsp, MAX(0, stop-AM_SEQPORTSIZE), stop, strand, code);
 
8319
            *bufpos = MAX(0, stop-AM_SEQPORTSIZE);
 
8320
        } 
 
8321
        else {
 
8322
            *spp = SeqPortNew(bsp, start, MIN(start+AM_SEQPORTSIZE, bsp->length-1), strand, code);
 
8323
            *bufpos = start;
 
8324
        }
 
8325
    }
 
8326
    /* see if what we need is in current seqport or a new one is needed */ 
 
8327
    else if ((start < *bufpos) || (start > *bufpos+AM_SEQPORTSIZE) 
 
8328
             || (stop < *bufpos) || (stop > *bufpos+AM_SEQPORTSIZE)) {
 
8329
        SeqPortFree(*spp);
 
8330
        if (strand == Seq_strand_minus) {         
 
8331
            *spp = SeqPortNew(bsp, MAX(0, stop-AM_SEQPORTSIZE), stop, strand, code);
 
8332
            *bufpos = MAX(0, stop-AM_SEQPORTSIZE);
 
8333
        } 
 
8334
        else {
 
8335
            *spp = SeqPortNew(bsp, start, MIN(start+AM_SEQPORTSIZE, bsp->length-1), strand, code);
 
8336
            *bufpos = start;
 
8337
        }
 
8338
    }
 
8339
    return (SeqPortRead(*spp, buf, (MIN(start+AM_SEQPORTSIZE-1, stop)) - start+1));
 
8340
}
 
8341
 
6194
8342
/* SECTION 8 */
6195
8343
/***************************************************************************
6196
8344
*
6207
8355
   AMFreqPtr   afp;
6208
8356
   AlnMsg2Ptr  amp;
6209
8357
   BioseqPtr   bsp;
 
8358
   Uint1       buf[AM_SEQPORTSIZE];
 
8359
   Int4        bufpos;
6210
8360
   Uint1       code;
6211
8361
   Int4        counter;
 
8362
   Int4        ctr;
6212
8363
   Int4        from_a;
6213
8364
   Int4        i;
6214
8365
   Boolean     isna;
6215
8366
   Int4        j;
 
8367
   Int4        l;
6216
8368
   Int4        len;
6217
8369
   Boolean     more;
6218
8370
   Int4        n;
6226
8378
   if (sap == NULL || sap->saip == NULL || (from > to && to != -1))
6227
8379
      return NULL;
6228
8380
   numrows = AlnMgr2GetNumRows(sap);
 
8381
   bufpos = -1;
6229
8382
   if (row > numrows || row < 0)
6230
8383
      return NULL;
6231
8384
   len = AlnMgr2GetAlnLength(sap, FALSE);
6277
8430
   }
6278
8431
   for (i=0; i<numrows; i++)
6279
8432
   {
 
8433
      spp = NULL;
6280
8434
      AlnMsgReNew2(amp);
6281
8435
      amp->from_aln = from_a;
6282
8436
      amp->to_aln = to_a;
6283
8437
      amp->row_num = i+1;
6284
8438
      j = 0;
6285
 
      while (more = AlnMgr2GetNextAlnBit(sap, amp))
 
8439
      while ((more = AlnMgr2GetNextAlnBit(sap, amp)))
6286
8440
      {
6287
8441
         if (amp->type == AM_GAP)
6288
8442
         {
6289
8443
            for (n=0; n<(amp->to_row - amp->from_row+1); n++)
6290
8444
            {
6291
 
               afp->freq[0][j]++;
 
8445
               afp->freq[0][j] = afp->freq[0][j]+1;
6292
8446
               j++;
6293
8447
            }
6294
8448
         } else if (amp->type == AM_SEQ)
6295
8449
         {
6296
8450
            sip = AlnMgr2GetNthSeqIdPtr(sap, i+1);
6297
8451
            bsp = BioseqLockById(sip);
6298
 
            spp = SeqPortNew(bsp, amp->from_row, amp->to_row, amp->strand, code);
6299
 
            counter = 0;
6300
 
            while (counter < (amp->to_row-amp->from_row+1))
6301
 
            {
6302
 
               res = SeqPortGetResidue(spp);
6303
 
               if (isna)
6304
 
               {
6305
 
                  if (res == 1 || res == 2)
6306
 
                     afp->freq[res][j]++;
6307
 
                  else if (res == 4)
6308
 
                     afp->freq[3][j]++;
6309
 
                  else if (res == 8)
6310
 
                     afp->freq[4][j]++;
6311
 
                  else
6312
 
                     afp->freq[5][j]++;
6313
 
               } else
6314
 
                  afp->freq[res][j]++;
6315
 
               j++;
6316
 
               counter++;
 
8452
            if (bsp != NULL) {
 
8453
              for (l=amp->from_row; l<=amp->to_row; l+=AM_SEQPORTSIZE)
 
8454
              {
 
8455
                 counter = AlnMgr2SeqPortRead(&spp, buf, &bufpos, l, MIN(l+AM_SEQPORTSIZE, amp->to_row), amp->strand, code, bsp);
 
8456
                 ctr = 0;
 
8457
                 while (ctr < counter)
 
8458
                 {
 
8459
                    res = buf[ctr];
 
8460
                    if (isna)
 
8461
                    {
 
8462
                       if (res == 1 || res == 2)
 
8463
                          afp->freq[res][j]++;
 
8464
                       else if (res == 4)
 
8465
                          afp->freq[3][j]++;
 
8466
                       else if (res == 8)
 
8467
                          afp->freq[4][j]++;
 
8468
                       else
 
8469
                          afp->freq[5][j]++;
 
8470
                    } else
 
8471
                       afp->freq[res][j]++;
 
8472
                    j++;
 
8473
                    ctr++;
 
8474
                 }
 
8475
              }
 
8476
              BioseqUnlock(bsp);
6317
8477
            }
6318
 
            SeqPortFree(spp);
6319
 
            BioseqUnlock(bsp);
6320
8478
            SeqIdFree(sip);
6321
8479
         }
6322
8480
      }
 
8481
      SeqPortFree(spp);
6323
8482
   }
 
8483
   AlnMsgFree2(amp);
6324
8484
   return afp;
6325
8485
}
6326
8486
 
6522
8682
   if (sap1_orig->next != NULL)
6523
8683
   {
6524
8684
      AlnMgr2IndexSeqAlign(sap1_orig);
6525
 
      sap1 = AlnMgr2GetSubAlign(sap1_orig, 0, -1, 0);
 
8685
      sap1 = AlnMgr2GetSubAlign(sap1_orig, 0, -1, 0, TRUE);
6526
8686
   } else
6527
8687
      sap1 = SeqAlignDup(sap1_orig);
6528
8688
   if (sap2_orig->next != NULL)
6529
8689
   {
6530
8690
      AlnMgr2IndexSeqAlign(sap2_orig);
6531
 
      sap2 = AlnMgr2GetSubAlign(sap2_orig, 0, -1, 0);
 
8691
      sap2 = AlnMgr2GetSubAlign(sap2_orig, 0, -1, 0, TRUE);
6532
8692
   } else
6533
8693
      sap2 = SeqAlignDup(sap2_orig);
6534
8694
   AlnMgr2IndexSingleChildSeqAlign(sap1);
6705
8865
   Int4         j;
6706
8866
   Int4         numrows;
6707
8867
   Int4         numseg;
 
8868
   Int4         prediff1;
 
8869
   Int4         prediff2;
6708
8870
   Int4         seg;
6709
8871
   SeqIdPtr     sip;
6710
8872
   Int4         start;
6737
8899
   if (numseg == 0)
6738
8900
      return;
6739
8901
   sip = dsp->ids;
 
8902
   prediff1 = diff1;
 
8903
   prediff2 = diff2;
6740
8904
   for (i=0; i<numrows; i++)
6741
8905
   {
6742
8906
      bsp = BioseqLockById(sip);
6744
8908
      {
6745
8909
         if (dsp->starts[i]+dsp->lens[0]+diff1 > bsp->length)
6746
8910
            diff1 = bsp->length - (dsp->starts[i] + dsp->lens[0]);
6747
 
         if (dsp->starts[(dsp->numseg-1)*dsp->dim+i] < diff2)
 
8911
         if (dsp->starts[(dsp->numseg-1)*dsp->dim+i] > diff2)
6748
8912
            diff2 = dsp->starts[(dsp->numseg-1)*dsp->dim+i];
6749
8913
      } else
6750
8914
      {
6751
8915
         if (dsp->starts[i] < diff1)
6752
8916
            diff1 = dsp->starts[i];
6753
 
         if (dsp->starts[(dsp->numseg-1)*dsp->dim+i]+dsp->lens[dsp->numseg-1]+diff1 > bsp->length)
 
8917
         if (dsp->starts[(dsp->numseg-1)*dsp->dim+i]+dsp->lens[dsp->numseg-1]+diff2 > bsp->length)
6754
8918
            diff2 = bsp->length - (dsp->starts[(dsp->numseg-1)*dsp->dim+i] + dsp->lens[dsp->numseg-1]);
6755
8919
      }
6756
8920
      sip = sip->next;
6757
8921
      BioseqUnlock(bsp);
6758
8922
   }
6759
 
   if (diff1 == 0)
 
8923
   if (diff1 == 0 && prediff1 != 0)
6760
8924
      numseg--;
6761
 
   if (diff2 == 0)
 
8925
   if (diff2 == 0 && prediff2 != 0)
6762
8926
      numseg--;
6763
8927
   if (numseg == 0)
6764
8928
      return;
6783
8947
      dsp_new->lens[0] = diff1;
6784
8948
      seg++;
6785
8949
   }
6786
 
   for (i=0; i<dsp_new->numseg; i++)
 
8950
   for (i=0; i<dsp->numseg; i++)
6787
8951
   {
6788
8952
      for (j=0; j<dsp->dim; j++)
6789
8953
      {
6790
 
         dsp_new->starts[(i+seg)*dsp->dim+j] = dsp->starts[i*dsp->dim+j];
6791
 
         dsp_new->strands[(i+seg)*dsp->dim+j] = dsp->strands[i*dsp->dim+j];
 
8954
         dsp_new->starts[(seg)*dsp->dim+j] = dsp->starts[i*dsp->dim+j];
 
8955
         dsp_new->strands[(seg)*dsp->dim+j] = dsp->strands[i*dsp->dim+j];
6792
8956
      }
6793
 
      dsp_new->lens[i+seg] = dsp->lens[i];
 
8957
      dsp_new->lens[seg] = dsp->lens[i];
6794
8958
      seg++;
6795
8959
   }
6796
8960
   if (diff2 > 0)
6999
9163
   MemFree(lenarray);
7000
9164
   return sap_new;
7001
9165
}
 
9166
 
 
9167
/* SECTION 10 */
 
9168
/***************************************************************************
 
9169
*
 
9170
*  AlnMgr2ExtractPairwiseSeqAlign takes an indexed alignment (parent or
 
9171
*  child, but must be fully indexed, not lite) and extracts a pairwise
 
9172
*  subalignment containing the two requested rows. The subalignment is
 
9173
*  unindexed and may have internal unaligned regions.
 
9174
*
 
9175
***************************************************************************/
 
9176
NLM_EXTERN SeqAlignPtr AlnMgr2ExtractPairwiseSeqAlign(SeqAlignPtr sap, Int4 n1, Int4 n2)
 
9177
{
 
9178
   AMAlignIndex2Ptr  amaip;
 
9179
   DenseSegPtr       dsp;
 
9180
   DenseSegPtr       dsp_new;
 
9181
   Int4              i;
 
9182
   Int4              j;
 
9183
   Int4              n;
 
9184
   SeqAlignPtr       sap_new;
 
9185
 
 
9186
   if (sap == NULL || sap->saip == NULL || n1 == n2 || n1 <= 0 || n2 <= 0)
 
9187
      return NULL;
 
9188
   if (sap->saip->indextype == INDEX_CHILD)
 
9189
      dsp = (DenseSegPtr)(sap->segs);
 
9190
   else
 
9191
   {
 
9192
      amaip = (AMAlignIndex2Ptr)(sap->saip);
 
9193
      dsp = (DenseSegPtr)(amaip->sharedaln->segs);
 
9194
   }
 
9195
   if (n1 > dsp->dim || n2 > dsp->dim)
 
9196
      return NULL;
 
9197
   n = 0;
 
9198
   for (i=0; i<dsp->numseg; i++)
 
9199
   {
 
9200
      if (dsp->starts[dsp->dim*i+n1-1] == -1 && dsp->starts[dsp->dim*i+n2-1] == -1)
 
9201
         n++;
 
9202
   }
 
9203
   if (n == dsp->numseg) /* no overlap at all */
 
9204
      return NULL;
 
9205
   dsp_new = DenseSegNew();
 
9206
   dsp_new->numseg = dsp->numseg - n;
 
9207
   dsp_new->starts = (Int4Ptr)MemNew(2*dsp_new->numseg*sizeof(Int4));
 
9208
   dsp_new->strands = (Uint1Ptr)MemNew(2*dsp_new->numseg*sizeof(Uint1));
 
9209
   dsp_new->lens = (Int4Ptr)MemNew(dsp_new->numseg*sizeof(Int4));
 
9210
   dsp_new->dim = 2;
 
9211
   dsp_new->ids = AlnMgr2GetNthSeqIdPtr(sap, n1);
 
9212
   dsp_new->ids->next = AlnMgr2GetNthSeqIdPtr(sap, n2);
 
9213
   j = 0;
 
9214
   for (i=0; i<dsp->numseg; i++)
 
9215
   {
 
9216
      if (dsp->starts[dsp->dim*i+n1-1] > -1 || dsp->starts[dsp->dim*i+n2-1] > -1)
 
9217
      {
 
9218
         dsp_new->starts[2*j] = dsp->starts[dsp->dim*i+n1-1];
 
9219
         dsp_new->starts[2*j+1] = dsp->starts[dsp->dim*i+n2-1];
 
9220
         dsp_new->strands[2*j] = dsp->strands[n1-1];
 
9221
         dsp_new->strands[2*j+1] = dsp->strands[n2-1];
 
9222
         dsp_new->lens[j] = dsp->lens[i];
 
9223
         j++;
 
9224
      }
 
9225
   }
 
9226
   sap_new = SeqAlignNew();
 
9227
   sap_new->dim = 2;
 
9228
   sap_new->type = SAT_PARTIAL;
 
9229
   sap_new->segtype = SAS_DENSEG;
 
9230
   sap_new->segs = (Pointer)dsp_new;
 
9231
   return sap_new;
 
9232
}
 
9233
 
 
9234
/* SECTION 10 */
 
9235
static void amconssetfree(AMConsSetPtr acp)
 
9236
{
 
9237
   AMConsSetPtr  acp_next;
 
9238
 
 
9239
   while (acp != NULL)
 
9240
   {
 
9241
      acp_next = acp->next;
 
9242
      MemFree(acp->starts);
 
9243
      MemFree(acp->stops);
 
9244
      MemFree(acp->strands);
 
9245
      MemFree(acp);
 
9246
      acp = acp_next;
 
9247
   }
 
9248
}
 
9249
 
 
9250
static int LIBCALLBACK AlnMgr2SortForConsistent(VoidPtr ptr1, VoidPtr ptr2)
 
9251
{
 
9252
   AMConsSetPtr  acp1;
 
9253
   AMConsSetPtr  acp2;
 
9254
   SAIndex2Ptr   saip1;
 
9255
   SAIndex2Ptr   saip2;
 
9256
 
 
9257
   acp1 = *((AMConsSetPtr PNTR)ptr1);
 
9258
   acp2 = *((AMConsSetPtr PNTR)ptr2);
 
9259
   saip1 = (SAIndex2Ptr)(acp1->sap->saip);
 
9260
   saip2 = (SAIndex2Ptr)(acp2->sap->saip);
 
9261
   if (saip1->score == 0)
 
9262
      saip1->score = AlnMgr2ComputeScoreForSeqAlign(acp1->sap);
 
9263
   if (saip2->score == 0)
 
9264
      saip2->score = AlnMgr2ComputeScoreForSeqAlign(acp2->sap);
 
9265
   if (saip1->score > saip2->score)
 
9266
      return -1;
 
9267
   else if (saip1->score < saip2->score)
 
9268
      return 1;
 
9269
   else
 
9270
      return 0;
 
9271
}
 
9272
 
 
9273
/* SECTION 10 */
 
9274
/***************************************************************************
 
9275
*
 
9276
*  AlnMgr2RemoveInconsistentAlnsFromSet takes an alignment that is
 
9277
*  indexed at least at the AM2_LITE level, and prunes the child
 
9278
*  alignments so that the remaining alignments form a consistent,
 
9279
*  nonoverlapping set. All alignments must have the same number of rows,
 
9280
*  and they must be the same rows (although not necessarily in the same
 
9281
*  order). The function uses a simple greedy algorithm to construct the
 
9282
*  nonoverlapping set, starting with the highest-scoring alignment.
 
9283
*  If fuzz is negative, the function creates the best nonoverlapping set
 
9284
*  by actually truncating alignments.
 
9285
*
 
9286
***************************************************************************/
 
9287
NLM_EXTERN void AlnMgr2RemoveInconsistentAlnsFromSet(SeqAlignPtr sap_head, Int4 fuzz)
 
9288
{
 
9289
   AMConsSetPtr  acp;
 
9290
   AMConsSetPtr  acp_head;
 
9291
   AMConsSetPtr  acp_prev;
 
9292
   AMConsSetPtr  PNTR acparray;
 
9293
   DenseSegPtr   dsp;
 
9294
   Int4          i;
 
9295
   Int4          j;
 
9296
   Int4          k;
 
9297
   Int4          lfuzz;
 
9298
   SeqAlignPtr   newsap;
 
9299
   Int4          numrows;
 
9300
   Int4          numsaps;
 
9301
   Int4          orientation;
 
9302
   Int4          row;
 
9303
   SAIndex2Ptr   saip;
 
9304
   SeqAlignPtr   salp_head;
 
9305
   SeqAlignPtr   salp_prev;
 
9306
   SeqAlignPtr   sap;
 
9307
   SeqAlignPtr   sapnext;
 
9308
   Int4          score;
 
9309
   SeqIdPtr      sip;
 
9310
   SeqIdPtr      sip_head;
 
9311
   Uint1         strand;
 
9312
 
 
9313
   lfuzz = fuzz;
 
9314
   if (fuzz < 0)
 
9315
      fuzz = 1;
 
9316
   sap = (SeqAlignPtr)(sap_head->segs);
 
9317
   if (sap->next == NULL)
 
9318
      return;
 
9319
   dsp = (DenseSegPtr)(sap->segs);
 
9320
   sip_head = dsp->ids;
 
9321
   numrows = AlnMgr2GetNumRows(sap);
 
9322
   acp_head = NULL;
 
9323
   strand = AlnMgr2GetNthStrand(sap, 1);
 
9324
   numsaps = 0;
 
9325
   while (sap != NULL)
 
9326
   {
 
9327
      if (AlnMgr2GetNumRows(sap) != numrows)
 
9328
      {
 
9329
         amconssetfree(acp_head);
 
9330
         return;
 
9331
      }
 
9332
      numsaps++;
 
9333
      acp = (AMConsSetPtr)MemNew(sizeof(AMConsSet));
 
9334
      acp->starts = (Int4Ptr)MemNew(numrows*sizeof(Int4));
 
9335
      acp->stops = (Int4Ptr)MemNew(numrows*sizeof(Int4));
 
9336
      acp->strands = (Uint1Ptr)MemNew(numrows*sizeof(Uint1));
 
9337
      acp->which = (Int4Ptr)MemNew(numrows*sizeof(Int4));
 
9338
      acp->sap = sap;
 
9339
      if (acp_head != NULL)
 
9340
      {
 
9341
         acp_prev->next = acp;
 
9342
         acp_prev = acp;
 
9343
      } else
 
9344
         acp_head = acp_prev = acp;
 
9345
      sip = sip_head;
 
9346
      row = AlnMgr2GetFirstNForSip(sap, sip);
 
9347
      if (row <= 0)
 
9348
      {
 
9349
         amconssetfree(acp_head);
 
9350
         return;
 
9351
      }
 
9352
      if (acp->strands[row] != strand)
 
9353
      {
 
9354
         sapnext = acp->sap->next;
 
9355
         acp->sap->next = NULL;
 
9356
         score = ((SAIndex2Ptr)(acp->sap->saip))->score;
 
9357
         SeqAlignListReverseStrand(acp->sap);
 
9358
         AMAlignIndexFreeEitherIndex(acp->sap);
 
9359
         AlnMgr2IndexSingleChildSeqAlign(acp->sap);
 
9360
         saip = (SAIndex2Ptr)(acp->sap->saip);
 
9361
         saip->score = score;
 
9362
         acp->strands[row] = strand;
 
9363
         acp->sap->next = sapnext;
 
9364
      }
 
9365
      for (i=0; i<numrows; i++)
 
9366
      {
 
9367
         acp->which[i] = row;
 
9368
         AlnMgr2GetNthSeqRangeInSA(sap, i+1, &acp->starts[i], &acp->stops[i]);
 
9369
         acp->strands[i] = AlnMgr2GetNthStrand(sap, i+1);
 
9370
      }
 
9371
      sap = sap->next;
 
9372
   }
 
9373
   acparray = (AMConsSetPtr PNTR)MemNew(numsaps*sizeof(AMConsSetPtr));
 
9374
   acp = acp_head;
 
9375
   i = 0;
 
9376
   while (acp != NULL)
 
9377
   {
 
9378
      acparray[i] = acp;
 
9379
      acp = acp->next;
 
9380
      i++;
 
9381
   }
 
9382
   HeapSort(acparray, numsaps, sizeof(AMConsSetPtr), AlnMgr2SortForConsistent);
 
9383
   /* orientation -1 means that ith is before jth in ALL rows, 1 means ith is after jth in ALL rows */
 
9384
   for (i=0; i<numsaps; i++)
 
9385
   {
 
9386
      if (acparray[i]->used != -1)
 
9387
      {
 
9388
         for (j=i+1; j<numsaps; j++)
 
9389
         {
 
9390
            orientation = 0;
 
9391
            for (k=0; acparray[j]->used != -1 && k<numrows; k++)
 
9392
            {
 
9393
               if (acparray[i]->strands[k] != acparray[j]->strands[k])
 
9394
                  acparray[j]->used = -1;
 
9395
               if (acparray[i]->starts[k] - fuzz < acparray[j]->starts[k])
 
9396
               {
 
9397
                  if (acparray[i]->stops[k] - fuzz < acparray[j]->starts[k])
 
9398
                  {
 
9399
                     if ((acparray[i]->strands[k] == Seq_strand_plus && orientation == 1) || (acparray[i]->strands[k] == Seq_strand_minus && orientation == -1))
 
9400
                        acparray[j]->used = -1;
 
9401
                     else if (orientation == 0)
 
9402
                     {
 
9403
                        if (acparray[i]->strands[k] == Seq_strand_minus)
 
9404
                           orientation = 1;
 
9405
                        else
 
9406
                           orientation = -1;
 
9407
                     }
 
9408
                  } else
 
9409
                  {
 
9410
                     if (lfuzz >= 0) /* just mark it for deletion */
 
9411
                        acparray[j]->used = -1;
 
9412
                     else /* truncate it */
 
9413
                     {
 
9414
                        if (acparray[j]->stops[k] > acparray[i]->stops[k])
 
9415
                        {
 
9416
                           newsap = AlnMgr2GetSubAlign(acparray[j]->sap, acparray[i]->stops[k]+1, acparray[j]->stops[k], k+1, TRUE);
 
9417
                           SeqAlignFree(acparray[j]->sap);
 
9418
                           acparray[j]->sap = newsap;
 
9419
                           acparray[j]->starts[k] = acparray[i]->stops[k]+1;
 
9420
                        } else
 
9421
                           acparray[j]->used = -1;
 
9422
                     }
 
9423
                  }
 
9424
               } else if (acparray[i]->starts[k] - fuzz > acparray[j]->starts[k])
 
9425
               {
 
9426
                 if (acparray[i]->starts[k] + fuzz > acparray[j]->stops[k])
 
9427
                  {
 
9428
                     if ((acparray[i]->strands[k] == Seq_strand_plus && orientation == -1) || (acparray[i]->strands[k] == Seq_strand_minus && orientation == 1))
 
9429
                        acparray[j]->used = -1;
 
9430
                     else if (orientation == 0)
 
9431
                     {
 
9432
                        if (acparray[i]->strands[k] == Seq_strand_minus)
 
9433
                           orientation = -1;
 
9434
                        else
 
9435
                           orientation = 1;
 
9436
                     }
 
9437
                  } else
 
9438
                  {
 
9439
                     if (lfuzz >= 0) /* mark for deletion */
 
9440
                        acparray[j]->used = -1;
 
9441
                     else /* truncate */
 
9442
                     {
 
9443
                        if (acparray[j]->starts[k] < acparray[i]->starts[k])
 
9444
                        {
 
9445
                           newsap = AlnMgr2GetSubAlign(acparray[j]->sap, acparray[j]->starts[k], acparray[i]->starts[k]-1, k+1, TRUE);
 
9446
                           SeqAlignFree(acparray[j]->sap);
 
9447
                           acparray[j]->sap = newsap;
 
9448
                           AlnMgr2IndexSingleChildSeqAlign(newsap);
 
9449
                           acparray[j]->starts[k] = acparray[i]->stops[k]+1;
 
9450
                        } else
 
9451
                           acparray[j]->used = -1;
 
9452
                     }
 
9453
                  }
 
9454
               } else
 
9455
                  acparray[j]->used = -1;
 
9456
            }
 
9457
         }
 
9458
      }
 
9459
   }
 
9460
   /* now free all the unused ones, stick the rest back together, reindex, and return */
 
9461
   salp_head = salp_prev = NULL;
 
9462
   for (i=0; i<numsaps; i++)
 
9463
   {
 
9464
      if (acparray[i]->used == -1)
 
9465
      {
 
9466
         SeqAlignFree(acparray[i]->sap);
 
9467
         acparray[i]->sap = NULL;
 
9468
      } else
 
9469
      {
 
9470
         if (salp_head != NULL)
 
9471
         {
 
9472
            salp_prev->next = acparray[i]->sap;
 
9473
            salp_prev = acparray[i]->sap;
 
9474
            salp_prev->next = NULL;
 
9475
         } else
 
9476
         {
 
9477
            salp_head = salp_prev = acparray[i]->sap;
 
9478
            salp_prev->next = NULL;
 
9479
         }
 
9480
      }
 
9481
   }
 
9482
   amconssetfree(acp_head);
 
9483
   MemFree(acparray);
 
9484
   sap_head->segs = (Pointer)(salp_head);
 
9485
   AMAlignIndex2Free2(sap_head->saip);
 
9486
   AlnMgr2IndexLite(sap_head);
 
9487
}
 
9488
 
 
9489
static int LIBCALLBACK AlnMgr2CompareByScore(VoidPtr ptr1, VoidPtr ptr2)
 
9490
{
 
9491
   SAIndex2Ptr  saip1;
 
9492
   SAIndex2Ptr  saip2;
 
9493
   SeqAlignPtr  sap1;
 
9494
   SeqAlignPtr  sap2;
 
9495
 
 
9496
   if (ptr1 == NULL || ptr2 == NULL)
 
9497
      return 0;
 
9498
   sap1 = *((SeqAlignPtr PNTR) ptr1);
 
9499
   sap2 = *((SeqAlignPtr PNTR) ptr2);
 
9500
   saip1 = (SAIndex2Ptr)(sap1->saip);
 
9501
   saip2 = (SAIndex2Ptr)(sap2->saip);
 
9502
   if (saip1->score == 0)
 
9503
      saip1->score = AlnMgr2ComputeScoreForSeqAlign(sap1);
 
9504
   if (saip2->score == 0)
 
9505
      saip2->score = AlnMgr2ComputeScoreForSeqAlign(sap2);
 
9506
   if (saip1->score > saip2->score)
 
9507
      return -1;
 
9508
   if (saip1->score < saip2->score)
 
9509
      return 1;
 
9510
   return 0;
 
9511
}
 
9512
 
 
9513
/***************************************************************************
 
9514
*
 
9515
*  AlnMgr2FuseSet takes a set of alignments sharing all their rows and orders
 
9516
*  the alignments, then fuses together any adjacent alignments. If returnall
 
9517
*  is TRUE, all pieces are returned; if not, then only the largest piece is
 
9518
*  returned. This function will work best when called after
 
9519
*  AlnMgr2RemoveInconsistentAlnsFromSet(sap_head, -1).
 
9520
*
 
9521
***************************************************************************/
 
9522
NLM_EXTERN SeqAlignPtr AlnMgr2FuseSet(SeqAlignPtr sap_head, Boolean returnall)
 
9523
{
 
9524
   AMAlignIndex2Ptr  amaip;
 
9525
   DenseSegPtr       dsp_new;
 
9526
   DenseSegPtr       dsp1;
 
9527
   DenseSegPtr       dsp2;
 
9528
   Boolean           found;
 
9529
   Int4              i;
 
9530
   Int4              n;
 
9531
   Int4              numrows;
 
9532
   Int4              r;
 
9533
   SeqAlignPtr       sap_keep;
 
9534
   SeqAlignPtr       sap_keep_head;
 
9535
   SeqAlignPtr       sap_keep_prev;
 
9536
   SAIndex2Ptr       saip;
 
9537
   SeqAlignPtr       PNTR saparray;
 
9538
   Int4              start1;
 
9539
   Int4              start2;
 
9540
   Int4              stop1;
 
9541
   Int4              stop2;
 
9542
   Uint1             strand;
 
9543
 
 
9544
   if (sap_head == NULL || sap_head->saip == NULL)
 
9545
      return NULL;
 
9546
   AlnMgr2SortAlnSetByNthRowPos(sap_head, 1);
 
9547
   amaip = (AMAlignIndex2Ptr)(sap_head->saip);
 
9548
   sap_keep = amaip->saps[0];
 
9549
   sap_keep_head = sap_keep_prev = NULL;
 
9550
   numrows = AlnMgr2GetNumRows(sap_keep);
 
9551
   for (i=1; i<amaip->numsaps; i++)
 
9552
   {
 
9553
      /* check for consistency with sap_keep; fuse if possible */
 
9554
      found = FALSE;
 
9555
      for (n=0; !found && n<numrows; n++)
 
9556
      {
 
9557
         strand = AlnMgr2GetNthStrand(sap_keep, n+1);
 
9558
         AlnMgr2GetNthSeqRangeInSA(sap_keep, n+1, &start1, &stop1);
 
9559
         AlnMgr2GetNthSeqRangeInSA(amaip->saps[i], n+1, &start2, &stop2);
 
9560
         if (strand == Seq_strand_minus)
 
9561
         {
 
9562
            if (stop2+1 != start1)
 
9563
               found = TRUE;
 
9564
         } else
 
9565
         {
 
9566
            if (start2 != stop1+1)
 
9567
               found = TRUE;
 
9568
         }
 
9569
      }
 
9570
      if (!found) /* fuse together */
 
9571
      {
 
9572
         dsp1 = (DenseSegPtr)(sap_keep->segs);
 
9573
         dsp2 = (DenseSegPtr)(amaip->saps[i]->segs);
 
9574
         dsp_new = DenseSegNew();
 
9575
         dsp_new->dim = dsp1->dim;
 
9576
         dsp_new->numseg = dsp1->numseg+dsp2->numseg;
 
9577
         dsp_new->starts = (Int4Ptr)MemNew(dsp_new->numseg*dsp_new->dim*sizeof(Int4));
 
9578
         dsp_new->lens = (Int4Ptr)MemNew(dsp_new->numseg*sizeof(Int4));
 
9579
         dsp_new->strands = (Uint1Ptr)MemNew(dsp_new->numseg*dsp_new->dim*sizeof(Int4));
 
9580
         for (n=0; n<dsp_new->numseg; n++)
 
9581
         {
 
9582
            for (r=0; r<dsp_new->dim; r++)
 
9583
            {
 
9584
               if (n >= dsp1->numseg)
 
9585
                  dsp_new->starts[r*n*r] = dsp2->starts[r*(n-dsp1->numseg)+r];
 
9586
               else
 
9587
                  dsp_new->starts[r*n+r] = dsp1->starts[r*n+r];
 
9588
               dsp_new->strands[r*n*r] = dsp1->strands[r];
 
9589
            }
 
9590
            if (n >= dsp1->numseg)
 
9591
               dsp_new->lens[n] = dsp2->lens[n-dsp1->numseg];
 
9592
            else
 
9593
               dsp_new->lens[n] = dsp1->lens[n];
 
9594
         }
 
9595
         SeqAlignFree(amaip->saps[i]);
 
9596
         amaip->saps[i] = NULL;
 
9597
      } else /* add next alignment to keepers pile */
 
9598
      {
 
9599
         if (sap_keep_head == NULL)
 
9600
         {
 
9601
            if (sap_keep != NULL)
 
9602
            {
 
9603
               sap_keep_head = sap_keep;
 
9604
               sap_keep->next = amaip->saps[i];
 
9605
               sap_keep_prev = amaip->saps[i];
 
9606
            } else
 
9607
               sap_keep_head = sap_keep_prev = amaip->saps[i];
 
9608
         } else
 
9609
         {
 
9610
            sap_keep_prev->next = amaip->saps[i];
 
9611
            sap_keep_prev = amaip->saps[i];
 
9612
         }
 
9613
      }
 
9614
   }
 
9615
   if (sap_keep_head == NULL || sap_keep_head->next == NULL) /* everything was fused */
 
9616
      sap_keep_head = sap_keep;
 
9617
   if (returnall)
 
9618
   {
 
9619
      sap_head->segs = (Pointer)(sap_keep_head);
 
9620
      return sap_keep_head;
 
9621
   }
 
9622
   i=0;
 
9623
   sap_keep = sap_keep_head;
 
9624
   while (sap_keep != NULL)
 
9625
   {
 
9626
      sap_keep = sap_keep->next;
 
9627
      i++;
 
9628
   }
 
9629
   saparray = (SeqAlignPtr PNTR)MemNew(i*sizeof(SeqAlignPtr));
 
9630
   i = 0;
 
9631
   sap_keep = sap_keep_head;
 
9632
   while (sap_keep != NULL)
 
9633
   {
 
9634
      saip = (SAIndex2Ptr)(sap_keep->saip);
 
9635
      saip->score = 0;
 
9636
      saparray[i] = sap_keep;
 
9637
      i++;
 
9638
      sap_keep = sap_keep->next;
 
9639
   }
 
9640
   HeapSort(saparray, i, sizeof(SeqAlignPtr), AlnMgr2CompareByScore);
 
9641
   sap_keep = saparray[0];
 
9642
   for (n=1; n<i; n++)
 
9643
   {
 
9644
      SeqAlignFree(saparray[n]);
 
9645
   }
 
9646
   MemFree(saparray);
 
9647
   return sap_keep;
 
9648
}
 
9649
 
 
9650
NLM_EXTERN void AlnMgr2FillInUnaligned(SeqAlignPtr sap)
 
9651
{
 
9652
   Int4         curr;
 
9653
   DenseSegPtr  dsp;
 
9654
   DenseSegPtr  dsp_new;
 
9655
   Boolean      found;
 
9656
   Int4         i;
 
9657
   Int4         j;
 
9658
   Int4         k;
 
9659
   Int4         last;
 
9660
   Int4         n;
 
9661
   Int4         offset;
 
9662
   Int4         start;
 
9663
   Int4         stop;
 
9664
   Uint1        strand;
 
9665
 
 
9666
   if (sap == NULL || (sap->saip != NULL && sap->saip->indextype != INDEX_CHILD))
 
9667
      return;
 
9668
   n = 0;
 
9669
   dsp = (DenseSegPtr)(sap->segs);
 
9670
   for (i=0; i<dsp->dim; i++)
 
9671
   {
 
9672
      j = 0;
 
9673
      AlnMgr2GetNthSeqRangeInSA(sap, i, &start, &stop);
 
9674
      strand = dsp->strands[i];
 
9675
      last = -1;
 
9676
      while (j<dsp->numseg-1)
 
9677
      {
 
9678
         if (strand == Seq_strand_minus)
 
9679
         {
 
9680
            if (last != -1)
 
9681
            {
 
9682
               found = FALSE;
 
9683
               while (j<dsp->numseg && !found)
 
9684
               {
 
9685
                  if (dsp->starts[j*dsp->dim+i] != -1)
 
9686
                  {
 
9687
                     if (dsp->starts[j*dsp->dim+i]+dsp->lens[j] != last)
 
9688
                        n++;
 
9689
                     found = TRUE;
 
9690
                  }
 
9691
                  if (!found)
 
9692
                     j++;
 
9693
               }
 
9694
            } else
 
9695
               last = dsp->starts[j*dsp->dim+i];
 
9696
         } else
 
9697
         {
 
9698
            if (last != -1)
 
9699
            {
 
9700
               found = FALSE;
 
9701
               while (j<dsp->numseg && !found)
 
9702
               {
 
9703
                  if (dsp->starts[j*dsp->dim+i] != -1)
 
9704
                  {
 
9705
                     if (dsp->starts[j*dsp->dim+i]+dsp->lens[j] != last)
 
9706
                        n++;
 
9707
                     found = TRUE;
 
9708
                  }
 
9709
                  if (!found)
 
9710
                     j++;
 
9711
               }
 
9712
            } else
 
9713
            {
 
9714
               last = dsp->starts[j*dsp->dim+i];
 
9715
               if (last != -1)
 
9716
                  last += dsp->lens[j];
 
9717
            }
 
9718
         }
 
9719
      }
 
9720
   }
 
9721
   if (n == 0) /* no unaligned regions */
 
9722
      return;
 
9723
   dsp_new = DenseSegNew();
 
9724
   dsp_new->numseg = dsp->numseg + n;
 
9725
   dsp_new->dim = dsp->dim;
 
9726
   dsp_new->starts = (Int4Ptr)MemNew(dsp_new->dim*dsp_new->numseg*sizeof(Int4));
 
9727
   dsp_new->strands = (Uint1Ptr)MemNew(dsp_new->dim*dsp_new->numseg*sizeof(Uint1));
 
9728
   for (i=0; i<dsp_new->numseg; i++)
 
9729
   {
 
9730
      for (j=0; j<dsp_new->dim; j++)
 
9731
      {
 
9732
         dsp_new->strands[i*dsp_new->dim+j] = dsp->strands[j];
 
9733
      }
 
9734
   }
 
9735
   dsp_new->ids = SeqIdDupList(dsp->ids);
 
9736
   dsp_new->lens = (Int4Ptr)MemNew(dsp_new->numseg*sizeof(Int4));
 
9737
   curr = 0;
 
9738
   for (j=0; j<dsp->numseg; j++)
 
9739
   {
 
9740
      for (i=0; i<dsp->dim; i++)
 
9741
      {
 
9742
         offset = 0;
 
9743
         strand = dsp->strands[i];
 
9744
         if (dsp->starts[j*dsp->dim+i] == -1)
 
9745
            dsp_new->starts[curr*dsp_new->dim+i] = -1;
 
9746
         else
 
9747
         {
 
9748
            k = j+1;
 
9749
            found = FALSE;
 
9750
            while (k < dsp->numseg)
 
9751
            {
 
9752
               if (dsp->starts[k*dsp->dim+i] != -1)
 
9753
               {
 
9754
                  found = TRUE;
 
9755
                  if (strand == Seq_strand_minus)
 
9756
                  {
 
9757
                     if (dsp->starts[k*dsp->dim+i] + dsp->lens[k] != dsp->starts[j*dsp->dim+i])
 
9758
                     {
 
9759
                        dsp_new->lens[curr+offset] = dsp->starts[j*dsp->dim+i] - dsp->starts[k*dsp->dim+i] - dsp->lens[k];
 
9760
                        dsp_new->starts[(curr+offset)*dsp->dim+i] = dsp->starts[k*dsp->dim+i] + dsp->lens[k];
 
9761
                        offset++;
 
9762
                     }
 
9763
                  } else
 
9764
                  {
 
9765
                     if (dsp->starts[j*dsp->dim+i] + dsp->lens[j] != dsp->starts[k*dsp->dim+i])
 
9766
                     {
 
9767
                        dsp_new->lens[curr+offset] = dsp->starts[k*dsp->dim+i] - dsp->starts[j*dsp->dim+i] - dsp->lens[j];
 
9768
                        dsp_new->starts[(curr+offset)*dsp->dim+i] = dsp->starts[j*dsp->dim+i] + dsp->lens[j];
 
9769
                     }
 
9770
                  }
 
9771
               }
 
9772
               k++;
 
9773
            }
 
9774
         }
 
9775
      }
 
9776
      curr = curr + 1 + offset;
 
9777
   }
 
9778
   DenseSegFree(dsp);
 
9779
   sap->segs = (Pointer)(dsp_new);
 
9780
   AMAlignIndexFreeEitherIndex(sap);
 
9781
}
 
9782
 
 
9783
/* SECTION 11 -- functions for std-segs */
 
9784
NLM_EXTERN SeqIdPtr AlnMgr2GetNthSeqIdPtrStdSeg(SeqAlignPtr sap, Int4 n)
 
9785
{
 
9786
   SeqLocPtr  slp;
 
9787
   StdSegPtr  ssp;
 
9788
 
 
9789
   if (sap == NULL || sap->segtype != SAS_STD)
 
9790
      return NULL;
 
9791
   ssp = (StdSegPtr)(sap->segs);
 
9792
   slp = ssp->loc;
 
9793
   n--;
 
9794
   while (n > 0)
 
9795
   {
 
9796
      if (slp == NULL)
 
9797
         return NULL;
 
9798
      slp = slp->next;
 
9799
      n--;
 
9800
   }
 
9801
   return (SeqIdDup(SeqLocId(slp)));
 
9802
}
 
9803
 
 
9804
NLM_EXTERN Int4 AlignMgr2GetFirstNForStdSeg(SeqAlignPtr sap, SeqIdPtr sip)
 
9805
{
 
9806
   Int4       i;
 
9807
   SeqIdPtr   sip_tmp;
 
9808
   StdSegPtr  ssp;
 
9809
 
 
9810
   if (sap == NULL || sap->segtype != SAS_STD)
 
9811
      return -1;
 
9812
   ssp = (StdSegPtr)(sap->segs);
 
9813
   sip_tmp = ssp->ids;
 
9814
   i = 1;
 
9815
   while (sip_tmp != NULL)
 
9816
   {
 
9817
      if (SeqIdComp(sip, sip_tmp) == SIC_YES)
 
9818
         return i;
 
9819
      sip_tmp = sip_tmp->next;
 
9820
      i++;
 
9821
   }
 
9822
   return -1;
 
9823
}
 
9824
 
 
9825
NLM_EXTERN void AlnMgr2GetNthSeqRangeInSAStdSeg(SeqAlignPtr sap, Int4 n, Int4Ptr start, Int4Ptr stop)
 
9826
{
 
9827
   SeqLocPtr  slp;
 
9828
   StdSegPtr  ssp;
 
9829
 
 
9830
   if (start != NULL)
 
9831
      *start = -1;
 
9832
   if (stop != NULL)
 
9833
      *stop = -1;
 
9834
   if (sap == NULL || sap->segtype != SAS_STD)
 
9835
      return;
 
9836
   ssp = (StdSegPtr)(sap->segs);
 
9837
   slp = ssp->loc;
 
9838
   n--;
 
9839
   while (n > 0)
 
9840
   {
 
9841
      if (slp == NULL)
 
9842
         return;
 
9843
      slp = slp->next;
 
9844
      n--;
 
9845
   }
 
9846
   if (slp == NULL)
 
9847
      return;
 
9848
   if (start != NULL)
 
9849
      *start = SeqLocStart(slp);
 
9850
   if (stop != NULL)
 
9851
      *stop = SeqLocStop(slp);
 
9852
}
 
9853
 
 
9854
 
 
9855
/***************************************************************************
 
9856
*
 
9857
*   AlnMgr2GetSeqRangeForSipInSAStdSeg  returns the smallest and largest sequence
 
9858
*  coordinates in in a Std-Seg seqalign for a given Sequence Id.  Also return the 
 
9859
*  strand type.  Either start, stop or strand can be NULL to only retrieve some of them.
 
9860
*  If start and stop are -1, there is an error (not a std-seg), the SeqID does not participate in this
 
9861
*  alignment or the alignment is one big insert on that id.  Returns true if the sip was found
 
9862
*  in the alignment with real coordinates, i.e. *start would not be -1.  RANGE
 
9863
*
 
9864
***************************************************************************/
 
9865
NLM_EXTERN Boolean AlnMgr2GetSeqRangeForSipInSAStdSeg(SeqAlignPtr sap, SeqIdPtr sip, Int4Ptr start, Int4Ptr stop, Uint1Ptr strand)
 
9866
{
 
9867
    Int4        c_start, c_stop;
 
9868
    Uint1       c_strand;
 
9869
    StdSegPtr   ssp;
 
9870
    Boolean     range_found = FALSE;
 
9871
    Boolean     strands_inconsistent = FALSE;
 
9872
 
 
9873
    if (start) *start = -1;
 
9874
    if (stop)  *stop  = -1;
 
9875
    if (strand) *strand = Seq_strand_unknown;
 
9876
    
 
9877
    if (sap->segtype != SAS_STD)
 
9878
        return FALSE;
 
9879
 
 
9880
    ssp = (StdSegPtr)(sap->segs);
 
9881
    while (ssp) { 
 
9882
        if (AlnMgr2GetSeqRangeForSipInStdSeg(ssp, sip, &c_start, &c_stop, &c_strand, NULL) &&
 
9883
            c_start != -1) /* skip inserts on our bioseq */
 
9884
        {
 
9885
             range_found = TRUE;
 
9886
                
 
9887
            if (start) {
 
9888
                if (*start == -1) {
 
9889
                    *start = c_start;
 
9890
                } else {
 
9891
                    *start = MIN(*start, c_start);
 
9892
                }
 
9893
            }
 
9894
            if (stop) {
 
9895
                *stop = MAX(*stop, c_stop);
 
9896
            }
 
9897
            if (strand && ! strands_inconsistent) {
 
9898
            /* if strands are different each time, ignore them. */
 
9899
                if (*strand != Seq_strand_unknown && *strand != c_strand) {
 
9900
                    *strand = Seq_strand_unknown;
 
9901
                    strands_inconsistent = TRUE;
 
9902
                } else {
 
9903
                    *strand = c_strand;
 
9904
                }
 
9905
            }
 
9906
        }
 
9907
        ssp = ssp->next;
 
9908
    }
 
9909
    return range_found;
 
9910
}
 
9911
 
 
9912
 
 
9913
/***************************************************************************
 
9914
*
 
9915
*   AlnMgr2GetSeqRangeForSipInStdSeg  returns the start and stop sequence
 
9916
*  coordinates in a Std-Segment for a given Sequence Id.  Also return the 
 
9917
*  strand type.  Either start, stop or strand can be NULL to only retrieve some of them.
 
9918
*  If start and stop are -1, the SeqID was not found in this segment.  
 
9919
*  Returns true if the sip was found, even if it is a gap (start, stop = -1).  RANGE
 
9920
*
 
9921
***************************************************************************/
 
9922
NLM_EXTERN Boolean AlnMgr2GetSeqRangeForSipInStdSeg(
 
9923
    StdSegPtr   ssp, 
 
9924
    SeqIdPtr    sip, 
 
9925
    Int4Ptr     start, 
 
9926
    Int4Ptr     stop, 
 
9927
    Uint1Ptr    strand,
 
9928
    Uint1Ptr    segType) /* AM_SEQ, AM_GAP, AM_INSERT */
 
9929
{
 
9930
    SeqLocPtr   loc;
 
9931
    Uint1       m_strand;
 
9932
    Int4        m_start, m_stop, m_swap;
 
9933
    Boolean     s_present = FALSE;
 
9934
    Boolean     m_present = FALSE;
 
9935
    Boolean     found_id = FALSE;
 
9936
    
 
9937
    for ( loc = ssp->loc;
 
9938
          loc != NULL;  
 
9939
          loc = loc->next ) {
 
9940
    /* One SeqLoc for each Sequence aligned by this segment. */
 
9941
        /* find the one that matches the sip parameter. */
 
9942
        if (SeqIdForSameBioseq(sip, SeqLocId(loc))) {
 
9943
            m_strand = SeqLocStrand(loc);
 
9944
            m_start  = SeqLocStart(loc);
 
9945
            m_stop   = SeqLocStop(loc);
 
9946
            /* Might have to reverse the order of start and stop on
 
9947
               minus strands so that start is less than stop. */
 
9948
            if (m_start > m_stop) {
 
9949
              m_swap  = m_start;
 
9950
              m_start = m_stop;
 
9951
              m_stop = m_swap;
 
9952
            }
 
9953
            if (start)  *start  = m_start;
 
9954
            if (stop)   *stop   = m_stop;
 
9955
            if (strand) *strand = m_strand;
 
9956
            if (m_start != -1)
 
9957
                m_present = TRUE;
 
9958
                
 
9959
            /* found our sequence in this segment. */
 
9960
            found_id = TRUE;
 
9961
        } else { /* a different sequence */
 
9962
            if (SeqLocStart(loc) != -1)
 
9963
                s_present = TRUE;
 
9964
        }
 
9965
    }
 
9966
    
 
9967
    if (segType) {
 
9968
        if (m_present && s_present)
 
9969
            *segType = AM_SEQ;
 
9970
        else if (!m_present && s_present)
 
9971
            *segType = AM_INSERT;
 
9972
        else if (m_present && !s_present)
 
9973
            *segType = AM_GAP;
 
9974
        else
 
9975
            *segType = AM_GAP; /* start will be -1 */
 
9976
    }
 
9977
    return found_id;
 
9978
}
 
9979
 
 
9980
 
 
9981
/***************************************************************************
 
9982
*
 
9983
*   AlnMgr2GetNthStdSeg  returns the a pointer to the Nth segment of
 
9984
*   a standard segment alignment.  Numbering starts with 1.
 
9985
*   returns NULL if not n segments or is not a std-seg aligment.
 
9986
*   Useful to pass its return value to AlnMgr2GetSeqRangeForSipInStdSeg()
 
9987
*
 
9988
***************************************************************************/
 
9989
NLM_EXTERN StdSegPtr AlnMgr2GetNthStdSeg(SeqAlignPtr sap, Int2 n)
 
9990
{
 
9991
    StdSegPtr   ssp;
 
9992
        Int2        i;
 
9993
 
 
9994
    if (sap == NULL || sap->segtype != SAS_STD || n < 1)
 
9995
        return NULL;
 
9996
      
 
9997
    i = 1;
 
9998
    ssp = (StdSegPtr)(sap->segs);
 
9999
    while(ssp)
 
10000
    {
 
10001
        if (i == n)
 
10002
            return ssp;
 
10003
        ++i;
 
10004
        ssp = ssp->next;
 
10005
    }
 
10006
 
 
10007
    return NULL;
 
10008
}
 
10009
 
 
10010
/***************************************************************************
 
10011
*
 
10012
*  AlnMgr2GetNumStdSegs returns the number of segments in a standar-seg alignment.
 
10013
*   returns -1 if sap is null or not a standard-seg alignment.
 
10014
*
 
10015
***************************************************************************/
 
10016
NLM_EXTERN Int4 AlnMgr2GetNumStdSegs(SeqAlignPtr sap)
 
10017
{
 
10018
    Int4        seg_count = 0;
 
10019
    StdSegPtr   ssp;
 
10020
    
 
10021
    if (sap == NULL || sap->segtype != SAS_STD)
 
10022
        return -1;
 
10023
        
 
10024
    ssp = (StdSegPtr)(sap->segs);
 
10025
        while(ssp)
 
10026
        {
 
10027
                ++seg_count;
 
10028
                ssp = ssp->next;
 
10029
        }
 
10030
        return seg_count;
 
10031
}   
 
10032
   
 
10033
static SeqLocPtr AlnMgr2GetLongestSeqLoc(SeqAlignPtr sap)
 
10034
{
 
10035
   Int4       longest;
 
10036
   Int4       n;
 
10037
   SeqLocPtr  slp;
 
10038
   SeqLocPtr  slp_longest;
 
10039
   StdSegPtr  ssp;
 
10040
 
 
10041
   if (sap == NULL || sap->segtype != SAS_STD)
 
10042
      return NULL;
 
10043
   longest = -1;
 
10044
   ssp = (StdSegPtr)(sap->segs);
 
10045
   slp = ssp->loc;
 
10046
   while (slp != NULL)
 
10047
   {
 
10048
      n = SeqLocLen(slp);
 
10049
      if (n > longest)
 
10050
      {
 
10051
         slp_longest = slp;
 
10052
         longest = n;
 
10053
      }
 
10054
      slp = slp->next;
 
10055
   }
 
10056
   return slp_longest;
 
10057
}
 
10058
 
 
10059
/***************************************************************************
 
10060
*
 
10061
*  The two mapping functions act a little differently for std-segs. The
 
10062
*  alignment coordinates are 1:1 linearly correlated with the longest
 
10063
*  seqloc in the set; the others may be significantly shorter.
 
10064
*  The mapping functions deal with % lengths, and map those instead of
 
10065
*  coordinates (which may not be linear);
 
10066
*
 
10067
***************************************************************************/
 
10068
NLM_EXTERN Int4 AlnMgr2MapBioseqToSeqAlignStdSeg(SeqAlignPtr sap, Int4 n, Int4 pos)
 
10069
{
 
10070
   SeqLocPtr  slp;
 
10071
   SeqLocPtr  slp_longest;
 
10072
   StdSegPtr  ssp;
 
10073
   Int4       start1;
 
10074
   Int4       start2;
 
10075
   Int4       stop1;
 
10076
   Int4       stop2;
 
10077
 
 
10078
   if (sap == NULL || sap->segtype != SAS_STD)
 
10079
      return -1;
 
10080
   slp_longest = AlnMgr2GetLongestSeqLoc(sap);
 
10081
   start1 = SeqLocStart(slp_longest);
 
10082
   stop1 = SeqLocStop(slp_longest);
 
10083
   ssp = (StdSegPtr)(sap->segs);
 
10084
   slp = ssp->loc;
 
10085
   n--;
 
10086
   while (n > 0)
 
10087
   {
 
10088
      if (slp == NULL)
 
10089
         return -1;
 
10090
      n--;
 
10091
      slp = slp->next;
 
10092
   }
 
10093
   if (slp == NULL)
 
10094
      return -1;
 
10095
   start2 = SeqLocStart(slp);
 
10096
   stop2 = SeqLocStop(slp);
 
10097
   if (start2 == -1) /* NULL */
 
10098
      return -1;
 
10099
   return (((stop1-start1)*(pos - start2))/(stop2-start2));
 
10100
}
 
10101
 
 
10102
NLM_EXTERN Int4 AlnMgr2MapSeqAlignToBioseqStdSeg(SeqAlignPtr sap, Int4 n, Int4 pos)
 
10103
{
 
10104
   SeqLocPtr  slp;
 
10105
   SeqLocPtr  slp_longest;
 
10106
   StdSegPtr  ssp;
 
10107
   Int4       start1;
 
10108
   Int4       start2;
 
10109
   Int4       stop1;
 
10110
   Int4       stop2;
 
10111
 
 
10112
   if (sap == NULL || sap->segtype != SAS_STD)
 
10113
      return -1;
 
10114
   slp_longest = AlnMgr2GetLongestSeqLoc(sap);
 
10115
   start1 = SeqLocStart(slp_longest);
 
10116
   stop1 = SeqLocStop(slp_longest);
 
10117
   ssp = (StdSegPtr)(sap->segs);
 
10118
   slp = ssp->loc;
 
10119
   n--;
 
10120
   while (n > 0)
 
10121
   {
 
10122
      if (slp == NULL)
 
10123
         return -1;
 
10124
      n--;
 
10125
      slp = slp->next;
 
10126
   }
 
10127
   if (slp == NULL)
 
10128
      return -1;
 
10129
   start2 = SeqLocStart(slp);
 
10130
   stop2 = SeqLocStop(slp);
 
10131
   if (start2 == -1)  /* NULL */
 
10132
      return -1;
 
10133
   return (start2 + ((stop2-start2)*(pos-start1))/(stop1-start1));
 
10134
}
 
10135
 
 
10136
NLM_EXTERN Int4 AlnMgr2GetAlnLengthStdSeg(SeqAlignPtr sap)
 
10137
{
 
10138
   SeqLocPtr  slp_longest;
 
10139
 
 
10140
   if (sap == NULL || sap->segtype != SAS_STD)
 
10141
      return -1;
 
10142
   slp_longest = AlnMgr2GetLongestSeqLoc(sap);
 
10143
   return (SeqLocLen(slp_longest));
 
10144
}