4161
(BioseqPtr bsp, Int4Ptr p_start, Int4Ptr p_stop)
4163
BioseqSetPtr parts_bssp, seg_bssp;
4164
BioseqPtr master_bsp, other_part;
4168
if (bsp == NULL || bsp->idx.parentptr == NULL || bsp->idx.parenttype != OBJ_BIOSEQSET) return NULL;
4170
parts_bssp = (BioseqSetPtr) bsp->idx.parentptr;
4171
if (parts_bssp->_class != BioseqseqSet_class_parts
4172
|| parts_bssp->idx.parentptr == NULL
4173
|| parts_bssp->idx.parenttype != OBJ_BIOSEQSET)
4178
seg_bssp = (BioseqSetPtr) parts_bssp->idx.parentptr;
4179
if (seg_bssp->_class != BioseqseqSet_class_segset
4180
|| seg_bssp->seq_set == NULL
4181
|| !IS_Bioseq (seg_bssp->seq_set))
4186
master_bsp = (BioseqPtr) seg_bssp->seq_set->data.ptrvalue;
4188
if (p_start != NULL || p_stop != NULL)
4190
sep = parts_bssp->seq_set;
4191
while (sep != NULL && sep->data.ptrvalue != bsp)
4193
if (IS_Bioseq (sep) && sep->data.ptrvalue != NULL)
4195
other_part = sep->data.ptrvalue;
4196
offset += other_part->length;
4200
if (p_start != NULL)
4206
*p_stop = offset + bsp->length - 1;
4214
static Boolean AdjustOffsetsForSegment (SeqIdPtr del_id, SeqIdPtr target_id, Int4Ptr from, Int4Ptr to)
4216
BioseqPtr bsp_del, bsp_target, bsp_master;
4217
Int4 seg_offset = 0, seg_end = 0;
4218
Boolean rval = FALSE;
4220
if (del_id == NULL || target_id == NULL || from == NULL || to == NULL)
4225
bsp_del = BioseqFind (del_id);
4226
bsp_target = BioseqFind (target_id);
4227
if (bsp_del == NULL || bsp_target == NULL) return FALSE;
4229
bsp_master = GetParentForSegment (bsp_del, &seg_offset, &seg_end);
4230
if (bsp_master != NULL)
4232
if (bsp_master == bsp_target && seg_offset < *to)
4234
/* loc to delete is in parent coordinates */
4235
if (*from > seg_end || *to < seg_offset)
4237
/* loc to delete is entirely past this segment */
4241
*from = MAX (0, *from - seg_offset);
4242
*to = MIN (bsp_target->length, *to - seg_offset);
4251
static void SeqEdInsertSeqPnt (SeqPntPtr spp, SeqIdPtr target_id, Int4 pos, Int4 len, SeqIdPtr newid)
4253
Int4 to = pos + len;
4256
if (spp == NULL) return;
4258
if ((id_in_list = SeqIdIn(spp->id, target_id))
4259
|| AdjustOffsetsForSegment (spp->id, target_id, &pos, &to))
4261
if (id_in_list && newid != NULL) /* change id? */
4264
spp->id = SeqIdDup(newid);
4267
if (spp->point >= pos)
4283
SeqIntPtr PNTR split_end)
4285
Int4 to = pos + len;
4290
if (sip == NULL || split_end == NULL) return;
4292
if (!(id_in_list = SeqIdIn(sip->id, target_id))
4293
&& ! AdjustOffsetsForSegment(sip->id, target_id, &pos, &to))
4298
if (newid != NULL && id_in_list) /* change id? */
4301
sip->id = SeqIdDup(newid);
4304
if (sip->to < pos) /* completely before insertion */
4309
if ((! split) || (sip->from >= pos)) /* interval unbroken */
4311
if (sip->from >= pos)
4316
/* split interval */
4318
slp = ValNodeNew(NULL);
4319
slp->choice = SEQLOC_INT;
4320
slp->data.ptrvalue = (Pointer)sip2;
4321
sip2->strand = sip->strand;
4322
sip2->id = SeqIdDup(sip->id);
4324
sip2->to = sip->to + len;
4325
sip2->from = pos + len;
4326
sip2->if_to = sip->if_to;
4132
4334
/*****************************************************************************
4134
4336
* SeqEdSeqLocInsert()
4163
4365
NLM_EXTERN SeqLocPtr LIBCALL SeqEdSeqLocInsert (SeqLocPtr head, BioseqPtr target, Int4 pos, Int4 len,
4164
4366
Boolean split, SeqIdPtr newid)
4166
SeqIntPtr sip, sip2;
4168
PackSeqPntPtr pspp, pspp2;
4170
SeqLocPtr slp, tmp, prev, next, thead, tmp2;
4171
Int4 diff, numpnt, i, tpos;
4176
if ((head == NULL) || (target == NULL))
4179
head->next = NULL; /* caller maintains chains */
4183
switch (head->choice)
4185
case SEQLOC_BOND: /* bond -- 2 seqs */
4187
vn.choice = SEQLOC_PNT;
4189
sbp = (SeqBondPtr)(head->data.ptrvalue);
4190
vn.data.ptrvalue = (Pointer)(sbp->a);
4191
SeqEdSeqLocInsert(&vn, target, pos, len, split, newid);
4192
sbp->a = (SeqPntPtr)(vn.data.ptrvalue);
4195
vn.data.ptrvalue = (Pointer)(sbp->b);
4196
SeqEdSeqLocInsert(&vn, target, pos, len, split, newid);
4197
sbp->b = (SeqPntPtr)(vn.data.ptrvalue);
4200
case SEQLOC_FEAT: /* feat -- can't track yet */
4201
case SEQLOC_NULL: /* NULL */
4203
case SEQLOC_EMPTY: /* empty */
4204
case SEQLOC_WHOLE: /* whole */
4207
sidp = (SeqIdPtr)(head->data.ptrvalue);
4208
if ( SeqIdIn(sidp, target->id))
4211
sidp = SeqIdDup(newid);
4212
head->data.ptrvalue = (Pointer)sidp;
4216
case SEQLOC_MIX: /* mix -- more than one seq */
4217
case SEQLOC_EQUIV: /* equiv -- ditto */
4218
case SEQLOC_PACKED_INT: /* packed int */
4221
for (slp = (SeqLocPtr)(head->data.ptrvalue); slp != NULL; slp = next)
4224
oldchoice = slp->choice;
4225
tmp = SeqEdSeqLocInsert(slp, target, pos, len, split, newid);
4228
if ((head->choice != SEQLOC_EQUIV) &&
4229
(oldchoice != tmp->choice)) /* split interval? */
4231
if ((oldchoice == SEQLOC_INT) &&
4232
(tmp->choice == SEQLOC_PACKED_INT))
4235
tmp = (SeqLocPtr)(tmp2->data.ptrvalue);
4237
while (tmp->next != NULL)
4255
head->data.ptrvalue = thead;
4257
head = SeqLocFree(head);
4259
case SEQLOC_INT: /* int */
4260
sip = (SeqIntPtr)(head->data.ptrvalue);
4261
if (SeqIdIn(sip->id, target->id))
4263
if (newid != NULL) /* change id? */
4266
sip->id = SeqIdDup(newid);
4269
if (sip->to < pos) /* completely before insertion */
4274
if ((! split) || (sip->from >= pos)) /* interval unbroken */
4276
if (sip->from >= pos)
4282
/* split interval */
4284
slp = ValNodeNew(NULL);
4285
slp->choice = SEQLOC_INT;
4286
slp->data.ptrvalue = (Pointer)sip2;
4287
sip2->strand = sip->strand;
4288
sip2->id = SeqIdDup(sip->id);
4290
sip2->to = sip->to + len;
4291
sip2->from = pos + len;
4292
sip2->if_to = sip->if_to;
4297
if (sip->strand == Seq_strand_minus) /* reverse order */
4299
head->data.ptrvalue = (Pointer)sip2;
4300
slp->data.ptrvalue = (Pointer)sip;
4303
thead = head; /* make split interval into PACKED_INT */
4304
head = ValNodeNew(NULL);
4305
head->choice = SEQLOC_PACKED_INT;
4306
head->data.ptrvalue = thead;
4310
case SEQLOC_PNT: /* pnt */
4311
spp = (SeqPntPtr)(head->data.ptrvalue);
4312
if (SeqIdIn(spp->id, target->id))
4314
if (newid != NULL) /* change id? */
4317
spp->id = SeqIdDup(newid);
4320
if (spp->point >= pos)
4324
case SEQLOC_PACKED_PNT: /* packed pnt */
4325
pspp = (PackSeqPntPtr)(head->data.ptrvalue);
4326
if (SeqIdIn(pspp->id, target->id))
4328
if (newid != NULL) /* change id? */
4330
SeqIdFree(pspp->id);
4331
pspp->id = SeqIdDup(newid);
4334
numpnt = PackSeqPntNum(pspp);
4335
pspp2 = PackSeqPntNew();
4336
head->data.ptrvalue = pspp2;
4337
for (i = 0; i < numpnt; i++)
4339
tpos = PackSeqPntGet(pspp, i);
4342
PackSeqPntPut(pspp2, tpos);
4344
pspp2->id = pspp->id;
4346
pspp2->fuzz = pspp->fuzz;
4368
SeqIntPtr sip, sip2;
4370
PackSeqPntPtr pspp, pspp2;
4372
SeqLocPtr slp, tmp, prev, next, thead, tmp2;
4373
Int4 diff, numpnt, i, tpos;
4378
if ((head == NULL) || (target == NULL))
4381
head->next = NULL; /* caller maintains chains */
4385
switch (head->choice)
4387
case SEQLOC_BOND: /* bond -- 2 seqs */
4388
sbp = (SeqBondPtr)(head->data.ptrvalue);
4389
SeqEdInsertSeqPnt (sbp->a, target->id, pos, len, newid);
4390
SeqEdInsertSeqPnt (sbp->b, target->id, pos, len, newid);
4392
case SEQLOC_FEAT: /* feat -- can't track yet */
4393
case SEQLOC_NULL: /* NULL */
4395
case SEQLOC_EMPTY: /* empty */
4396
case SEQLOC_WHOLE: /* whole */
4399
sidp = (SeqIdPtr)(head->data.ptrvalue);
4400
if ( SeqIdIn(sidp, target->id))
4403
sidp = SeqIdDup(newid);
4404
head->data.ptrvalue = (Pointer)sidp;
4408
case SEQLOC_MIX: /* mix -- more than one seq */
4409
case SEQLOC_EQUIV: /* equiv -- ditto */
4410
case SEQLOC_PACKED_INT: /* packed int */
4413
for (slp = (SeqLocPtr)(head->data.ptrvalue); slp != NULL; slp = next)
4416
oldchoice = slp->choice;
4417
tmp = SeqEdSeqLocInsert(slp, target, pos, len, split, newid);
4420
if ((head->choice != SEQLOC_EQUIV) &&
4421
(oldchoice != tmp->choice)) /* split interval? */
4423
if ((oldchoice == SEQLOC_INT) &&
4424
(tmp->choice == SEQLOC_PACKED_INT))
4427
tmp = (SeqLocPtr)(tmp2->data.ptrvalue);
4429
while (tmp->next != NULL)
4447
head->data.ptrvalue = thead;
4449
head = SeqLocFree(head);
4451
case SEQLOC_INT: /* int */
4452
sip = (SeqIntPtr)(head->data.ptrvalue);
4454
SeqEdInsertSeqInt (sip, target->id, pos, len, split, newid, &sip2);
4457
thead = head; /* make split interval into PACKED_INT */
4458
head = ValNodeNew (NULL);
4459
head->choice = SEQLOC_PACKED_INT;
4461
slp = ValNodeNew (NULL);
4462
slp->choice = SEQLOC_INT;
4463
slp->data.ptrvalue = sip2;
4465
if (sip->strand == Seq_strand_minus) /* reverse order */
4467
head->data.ptrvalue = slp;
4472
head->data.ptrvalue = thead;
4477
case SEQLOC_PNT: /* pnt */
4478
spp = (SeqPntPtr)(head->data.ptrvalue);
4479
SeqEdInsertSeqPnt (spp, target->id, pos, len, newid);
4481
case SEQLOC_PACKED_PNT: /* packed pnt */
4482
pspp = (PackSeqPntPtr)(head->data.ptrvalue);
4483
if ((id_in_list = SeqIdIn(pspp->id, target->id))
4484
|| AdjustOffsetsForSegment(pspp->id, target->id, &pos, NULL))
4486
if (id_in_list && newid != NULL) /* change id? */
4488
SeqIdFree(pspp->id);
4489
pspp->id = SeqIdDup(newid);
4492
numpnt = PackSeqPntNum(pspp);
4493
pspp2 = PackSeqPntNew();
4494
head->data.ptrvalue = pspp2;
4495
for (i = 0; i < numpnt; i++)
4497
tpos = PackSeqPntGet(pspp, i);
4500
PackSeqPntPut(pspp2, tpos);
4502
pspp2->id = pspp->id;
4504
pspp2->fuzz = pspp->fuzz;
4347
4505
pspp->fuzz = NULL;
4348
4506
pspp2->strand = pspp->strand;
4349
4507
PackSeqPntFree(pspp);
4357
ErrPost(CTX_NCBIOBJ, 1, "SeqEdSeqLocInsert: lost a SeqLoc");
4515
ErrPost(CTX_NCBIOBJ, 1, "SeqEdSeqLocInsert: lost a SeqLoc");
4521
/* return TRUE if spp should be deleted */
4522
static Boolean SeqEdDeleteFromSeqPnt (SeqPntPtr spp, SeqIdPtr target_id, Int4 from, Int4 to)
4524
Boolean rval = FALSE;
4525
Int4 diff = to - from + 1;
4527
if (spp == NULL) return FALSE;
4529
if (SeqIdIn (spp->id, target_id)
4530
|| AdjustOffsetsForSegment (spp->id, target_id, &from, &to))
4532
if ((spp->point >= from) && (spp->point <= to))
4536
else if (spp->point > to)
4362
4545
static SeqLocPtr
4363
4546
SeqEdDeleteFromSeqLocBond (SeqLocPtr head, SeqIdPtr target, Int4 from, Int4 to, Boolean merge, BoolPtr changed)
4365
4548
SeqBondPtr sbp;
4369
4550
if (head == NULL || target == NULL || head->choice != SEQLOC_BOND) return NULL;
4370
4551
sbp = (SeqBondPtr)(head->data.ptrvalue);
4372
diff = to - from + 1;
4374
if (SeqIdForSameBioseq(spp->id, target))
4376
if (spp->point >= from)
4378
if (spp->point <= to) /* delete it */
4381
sbp->a = SeqPntFree(spp);
4392
if (SeqIdForSameBioseq(spp->id, target))
4394
if (spp->point >= from)
4396
if (spp->point <= to) /* delete it */
4399
sbp->b = SeqPntFree(spp);
4553
if (SeqEdDeleteFromSeqPnt (sbp->a, target, from, to))
4556
sbp->a = SeqPntFree(sbp->a);
4559
if (SeqEdDeleteFromSeqPnt (sbp->b, target, from, to))
4562
sbp->b = SeqPntFree(sbp->b);
4408
4565
if (sbp->a == NULL)
4410
if (sbp->b != NULL) /* only a required */
4567
if (sbp->b != NULL) /* only a required */
4412
4569
sbp->a = sbp->b;
4417
head = SeqLocFree(head);
4574
head = SeqLocFree(head);