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

« back to all changes in this revision

Viewing changes to access/tax3api.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:
 
1
/*   tax3api.c
 
2
* ===========================================================================
 
3
*
 
4
*                            PUBLIC DOMAIN NOTICE
 
5
*            National Center for Biotechnology Information (NCBI)
 
6
*
 
7
*  This software/database is a "United States Government Work" under the
 
8
*  terms of the United States Copyright Act.  It was written as part of
 
9
*  the author's official duties as a United States Government employee and
 
10
*  thus cannot be copyrighted.  This software/database is freely available
 
11
*  to the public for use. The National Library of Medicine and the U.S.
 
12
*  Government do not place any restriction on its use or reproduction.
 
13
*  We would, however, appreciate having the NCBI and the author cited in
 
14
*  any work or product based on this material
 
15
*
 
16
*  Although all reasonable efforts have been taken to ensure the accuracy
 
17
*  and reliability of the software and data, the NLM and the U.S.
 
18
*  Government do not and cannot warrant the performance or results that
 
19
*  may be obtained by using this software or data. The NLM and the U.S.
 
20
*  Government disclaim all warranties, express or implied, including
 
21
*  warranties of performance, merchantability or fitness for any particular
 
22
*  purpose.
 
23
*
 
24
* ===========================================================================
 
25
*
 
26
* File Name:  tax3api.c
 
27
*
 
28
* Author:  Jonathan Kans
 
29
*
 
30
* Version Creation Date:   7/8/04
 
31
*
 
32
* $Revision: 1.12 $
 
33
*
 
34
* File Description: 
 
35
*
 
36
* Modifications:  
 
37
* --------------------------------------------------------------------------
 
38
* Date     Name        Description of modification
 
39
* -------  ----------  -----------------------------------------------------
 
40
*
 
41
*
 
42
* ==========================================================================
 
43
*/
 
44
 
 
45
#include <ncbi.h>
 
46
#include <objseq.h>
 
47
#include <objsset.h>
 
48
#include <tax3api.h>
 
49
#include <sqnutils.h>
 
50
 
 
51
/* low-level connection functions */
 
52
 
 
53
NLM_EXTERN CONN Tax3OpenConnection (
 
54
  void
 
55
)
 
56
 
 
57
{
 
58
  return QUERY_OpenServiceQuery ("TaxService3", NULL, 30);
 
59
}
 
60
 
 
61
#ifdef OS_MAC
 
62
#include <Events.h>
 
63
#endif
 
64
 
 
65
NLM_EXTERN Taxon3ReplyPtr Tax3WaitForReply (
 
66
  CONN conn
 
67
)
 
68
 
 
69
{
 
70
  AsnIoConnPtr    aicp;
 
71
  time_t          currtime, starttime;
 
72
  Int2            max = 0;
 
73
  EIO_Status      status;
 
74
  STimeout        timeout;
 
75
  Taxon3ReplyPtr  t3ry = NULL;
 
76
#ifdef OS_MAC
 
77
  EventRecord     currEvent;
 
78
#endif
 
79
 
 
80
  if (conn == NULL) return NULL;
 
81
 
 
82
#ifdef OS_MAC
 
83
  timeout.sec = 0;
 
84
  timeout.usec = 0;
 
85
#else
 
86
  timeout.sec = 100;
 
87
  timeout.usec = 0;
 
88
#endif
 
89
 
 
90
  starttime = GetSecs ();
 
91
  while ((status = CONN_Wait (conn, eIO_Read, &timeout)) == eIO_Timeout && max < 300) {
 
92
    currtime = GetSecs ();
 
93
    max = currtime - starttime;
 
94
#ifdef OS_MAC
 
95
    WaitNextEvent (0, &currEvent, 0, NULL);
 
96
#endif
 
97
  }
 
98
  if (status == eIO_Success) {
 
99
    aicp = QUERY_AsnIoConnOpen ("rb", conn);
 
100
    t3ry = Taxon3ReplyAsnRead (aicp->aip, NULL);
 
101
    QUERY_AsnIoConnClose (aicp);
 
102
  }
 
103
  CONN_Close (conn);
 
104
 
 
105
  return t3ry;
 
106
}
 
107
 
 
108
/* high-level connection functions */
 
109
 
 
110
NLM_EXTERN Taxon3ReplyPtr Tax3SynchronousQuery (
 
111
  Taxon3RequestPtr t3rq
 
112
)
 
113
 
 
114
{
 
115
  AsnIoConnPtr    aicp;
 
116
  CONN            conn;
 
117
  Taxon3ReplyPtr  t3ry;
 
118
 
 
119
  if (t3rq == NULL) return NULL;
 
120
 
 
121
  conn = Tax3OpenConnection ();
 
122
 
 
123
  if (conn == NULL) return NULL;
 
124
 
 
125
  aicp = QUERY_AsnIoConnOpen ("wb", conn);
 
126
 
 
127
  Taxon3RequestAsnWrite (t3rq, aicp->aip, NULL);
 
128
 
 
129
  AsnIoFlush (aicp->aip);
 
130
  QUERY_AsnIoConnClose (aicp);
 
131
 
 
132
  QUERY_SendQuery (conn);
 
133
 
 
134
  t3ry = Tax3WaitForReply (conn);
 
135
 
 
136
  return t3ry;
 
137
}
 
138
 
 
139
NLM_EXTERN Boolean Tax3AsynchronousQuery (
 
140
  Taxon3RequestPtr t3rq,
 
141
  QUEUE* queue,
 
142
  QueryResultProc resultproc,
 
143
  VoidPtr userdata
 
144
)
 
145
 
 
146
{
 
147
  AsnIoConnPtr  aicp;
 
148
  CONN          conn;
 
149
 
 
150
  if (t3rq == NULL) return FALSE;
 
151
 
 
152
  conn = Tax3OpenConnection ();
 
153
 
 
154
  if (conn == NULL) return FALSE;
 
155
 
 
156
  aicp = QUERY_AsnIoConnOpen ("wb", conn);
 
157
 
 
158
  Taxon3RequestAsnWrite (t3rq, aicp->aip, NULL);
 
159
 
 
160
  AsnIoFlush (aicp->aip);
 
161
  QUERY_AsnIoConnClose (aicp);
 
162
 
 
163
  QUERY_SendQuery (conn);
 
164
 
 
165
  QUERY_AddToQueue (queue, conn, resultproc, userdata, TRUE);
 
166
 
 
167
  return TRUE;
 
168
}
 
169
 
 
170
NLM_EXTERN Int4 Tax3CheckQueue (
 
171
  QUEUE* queue
 
172
)
 
173
 
 
174
{
 
175
  return QUERY_CheckQueue (queue);
 
176
}
 
177
 
 
178
NLM_EXTERN Taxon3ReplyPtr Tax3ReadReply (
 
179
  CONN conn,
 
180
  EIO_Status status
 
181
)
 
182
 
 
183
{
 
184
  AsnIoConnPtr    aicp;
 
185
  Taxon3ReplyPtr  t3ry = NULL;
 
186
 
 
187
  if (conn != NULL && status == eIO_Success) {
 
188
    aicp = QUERY_AsnIoConnOpen ("rb", conn);
 
189
    t3ry = Taxon3ReplyAsnRead (aicp->aip, NULL);
 
190
    QUERY_AsnIoConnClose (aicp);
 
191
  }
 
192
  return t3ry;
 
193
}
 
194
 
 
195
NLM_EXTERN Taxon3RequestPtr CreateTaxon3Request (
 
196
  Int4 taxid,
 
197
  CharPtr name,
 
198
  OrgRefPtr orp
 
199
)
 
200
 
 
201
{
 
202
  Taxon3RequestPtr  t2rp;
 
203
 
 
204
  t2rp = Taxon3RequestNew ();
 
205
  if (t2rp == NULL) return NULL;
 
206
 
 
207
  if (StringDoesHaveText (name)) {
 
208
    ValNodeCopyStr (&(t2rp->request), 2, name);
 
209
  } else if (taxid > 0) {
 
210
    ValNodeAddInt (&(t2rp->request), 1, taxid);
 
211
  } else if (orp != NULL) {
 
212
    orp = AsnIoMemCopy ((Pointer) orp,
 
213
                        (AsnReadFunc) OrgRefAsnRead,
 
214
                        (AsnWriteFunc) OrgRefAsnWrite);
 
215
    ValNodeAddPointer (&(t2rp->request), 3, (Pointer) orp);
 
216
  }
 
217
 
 
218
  return t2rp;
 
219
}
 
220
 
 
221
NLM_EXTERN Taxon3RequestPtr CreateMultiTaxon3Request (ValNodePtr org_list)
 
222
{
 
223
  ValNodePtr vnp;
 
224
  Taxon3RequestPtr t3rp;
 
225
  OrgRefPtr orp;
 
226
  
 
227
  t3rp = Taxon3RequestNew ();
 
228
  if (t3rp == NULL) return NULL;
 
229
 
 
230
  for (vnp = org_list; vnp != NULL; vnp = vnp->next)
 
231
  {
 
232
    switch (vnp->choice)
 
233
    {
 
234
      case 1:
 
235
        ValNodeAddInt (&(t3rp->request), 1, vnp->data.intvalue);
 
236
        break;
 
237
      case 2:
 
238
        ValNodeCopyStr (&(t3rp->request), 2, vnp->data.ptrvalue);
 
239
        break;
 
240
      case 3:
 
241
        orp = AsnIoMemCopy (vnp->data.ptrvalue,
 
242
                        (AsnReadFunc) OrgRefAsnRead,
 
243
                        (AsnWriteFunc) OrgRefAsnWrite);
 
244
        ValNodeAddPointer (&(t3rp->request), 3, (Pointer) orp);
 
245
        break;
 
246
    }
 
247
  }
 
248
  return t3rp;
 
249
}
 
250
 
 
251
NLM_EXTERN ValNodePtr Taxon3GetOrgRefList (ValNodePtr org_list)
 
252
{
 
253
  Taxon3RequestPtr t3rq;
 
254
  Taxon3ReplyPtr   t3ry;
 
255
  T3DataPtr        tdp;
 
256
  OrgRefPtr        t3orp = NULL;
 
257
  T3ReplyPtr       trp;
 
258
  T3ErrorPtr       tep;
 
259
  ValNodePtr       response_list = NULL;
 
260
 
 
261
  if (org_list == NULL) return NULL;
 
262
  
 
263
  t3rq = CreateMultiTaxon3Request (org_list);
 
264
  if (t3rq == NULL) return NULL;
 
265
  t3ry = Tax3SynchronousQuery (t3rq);
 
266
  Taxon3RequestFree (t3rq);
 
267
  if (t3ry != NULL) {
 
268
    for (trp = t3ry->reply; trp != NULL; trp = trp->next) {
 
269
      switch (trp->choice) {
 
270
        case T3Reply_error :
 
271
          tep = (T3ErrorPtr) trp->data.ptrvalue;
 
272
          if (tep != NULL) {
 
273
            ErrPostEx (SEV_ERROR, 0, 0, tep->message);
 
274
          }
 
275
          ValNodeAddPointer (&response_list, 3, NULL);
 
276
          break;
 
277
        case T3Reply_data :
 
278
          tdp = (T3DataPtr) trp->data.ptrvalue;
 
279
          if (tdp != NULL) {
 
280
            t3orp = (OrgRefPtr)(tdp->org);
 
281
            ValNodeAddPointer (&response_list, 3, (Pointer) t3orp);
 
282
            tdp->org = NULL;
 
283
          }
 
284
          break;
 
285
        default :
 
286
          break;
 
287
      }
 
288
    }
 
289
    Taxon3ReplyFree (t3ry);
 
290
  }
 
291
  
 
292
  return response_list;
 
293
}
 
294
 
 
295
NLM_EXTERN OrgRefPtr Taxon3GetOrg (OrgRefPtr orp)
 
296
 
 
297
{
 
298
  Taxon3RequestPtr t3rq;
 
299
  Taxon3ReplyPtr   t3ry;
 
300
  T3DataPtr        tdp;
 
301
  OrgRefPtr        t3orp = NULL;
 
302
  T3ReplyPtr        trp;
 
303
  T3ErrorPtr        tep;
 
304
        
 
305
  if (orp == NULL) return NULL;
 
306
  
 
307
  t3rq = CreateTaxon3Request (0, NULL, orp);
 
308
  if (t3rq == NULL) return NULL;
 
309
  t3ry = Tax3SynchronousQuery (t3rq);
 
310
  Taxon3RequestFree (t3rq);
 
311
  if (t3ry != NULL) {
 
312
    for (trp = t3ry->reply; trp != NULL; trp = trp->next) {
 
313
      switch (trp->choice) {
 
314
        case T3Reply_error :
 
315
          tep = (T3ErrorPtr) trp->data.ptrvalue;
 
316
          if (tep != NULL) {
 
317
            ErrPostEx (SEV_ERROR, 0, 0, tep->message);
 
318
          }
 
319
          break;
 
320
        case T3Reply_data :
 
321
          tdp = (T3DataPtr) trp->data.ptrvalue;
 
322
          if (tdp != NULL) {
 
323
            t3orp = (OrgRefPtr)(tdp->org);
 
324
            tdp->org = NULL;
 
325
          }
 
326
          break;
 
327
        default :
 
328
          break;
 
329
      }
 
330
    }
 
331
    Taxon3ReplyFree (t3ry);
 
332
  }
 
333
  
 
334
  return t3orp;
 
335
}
 
336
 
 
337
static Boolean DoOrgIdsMatch(BioSourcePtr b1, BioSourcePtr b2)
 
338
{
 
339
  DbtagPtr d1 = NULL, d2 = NULL;
 
340
  ValNodePtr vnp;
 
341
        
 
342
  if (b1 == NULL || b2 == NULL) 
 
343
  {
 
344
    return FALSE;
 
345
  }
 
346
  if (b1->org ==  NULL || b2->org == NULL) 
 
347
  {
 
348
    return FALSE;
 
349
  }
 
350
  for (vnp = b1->org->db; vnp; vnp = vnp->next) 
 
351
  {
 
352
    d1 = (DbtagPtr) vnp->data.ptrvalue;
 
353
    if (StringCmp(d1->db, "taxon") == 0) 
 
354
    {
 
355
      break;
 
356
    }
 
357
  }
 
358
  for (vnp = b2->org->db; vnp; vnp = vnp->next) 
 
359
  {
 
360
    d2 = (DbtagPtr) vnp->data.ptrvalue;
 
361
        if (StringCmp(d2->db, "taxon") == 0) 
 
362
        {
 
363
      break;
 
364
        }
 
365
  }
 
366
  if (d1 && d2) 
 
367
  {
 
368
        if (d1->tag->id == d2->tag->id) 
 
369
        {
 
370
      return TRUE;
 
371
        }
 
372
  }
 
373
  else if (StringICmp(b1->org->taxname, b2->org->taxname) == 0) 
 
374
  {
 
375
        return TRUE;
 
376
  }
 
377
  return FALSE;
 
378
}
 
379
 
 
380
static BioSourcePtr Tax3BioSourceMerge(BioSourcePtr host, BioSourcePtr guest)
 
381
{
 
382
  SubSourcePtr ssp, sp, last_ssp;
 
383
  OrgModPtr omp, homp, last_omp;
 
384
  OrgNamePtr    onp;
 
385
        
 
386
  if (host == NULL && guest == NULL) 
 
387
  {
 
388
    return NULL;
 
389
  }
 
390
  if (host == NULL && guest != NULL) 
 
391
  {
 
392
        host = AsnIoMemCopy(guest, (AsnReadFunc) BioSourceAsnRead, 
 
393
                                                                (AsnWriteFunc) BioSourceAsnWrite);
 
394
        return host;
 
395
  }
 
396
  if (host != NULL && guest == NULL) 
 
397
  {
 
398
    return host;
 
399
  }
 
400
  if (host->genome == 0 && guest->genome != 0) 
 
401
  {
 
402
    host->genome = guest->genome;
 
403
  }
 
404
  if (host->origin == 0 && guest->origin != 0) 
 
405
  {
 
406
    host->origin = guest->origin;
 
407
  }
 
408
  last_ssp = host->subtype;
 
409
  while (last_ssp != NULL && last_ssp->next != NULL)
 
410
  {
 
411
        last_ssp = last_ssp->next;
 
412
  }
 
413
  for (ssp = guest->subtype; ssp; ssp = ssp->next) 
 
414
  {
 
415
    sp = AsnIoMemCopy(ssp, (AsnReadFunc) SubSourceAsnRead, 
 
416
                                                                (AsnWriteFunc) SubSourceAsnWrite);
 
417
    if (last_ssp == NULL)
 
418
    {
 
419
      host->subtype = sp;
 
420
    }
 
421
    else
 
422
    {
 
423
      last_ssp->next = sp;
 
424
      last_ssp = sp;
 
425
    }
 
426
  }
 
427
  if (guest->org->orgname) 
 
428
  {
 
429
        if ((onp = host->org->orgname)  == NULL) 
 
430
        {
 
431
          onp = OrgNameNew();
 
432
          host->org->orgname = onp;
 
433
    }   
 
434
    last_omp = onp->mod;                
 
435
    while (last_omp != NULL && last_omp->next != NULL)
 
436
    {
 
437
      last_omp = last_omp->next;
 
438
    }
 
439
    for (omp = guest->org->orgname->mod; omp; omp = omp->next) 
 
440
    {
 
441
      homp = AsnIoMemCopy(omp, (AsnReadFunc) OrgModAsnRead, 
 
442
                                                                (AsnWriteFunc) OrgModAsnWrite);
 
443
      if (last_omp == NULL)
 
444
      {
 
445
        onp->mod = homp;
 
446
      }
 
447
      else
 
448
      {
 
449
        last_omp->next = homp;
 
450
        last_omp = homp;
 
451
      }
 
452
    }
 
453
  }
 
454
  return host;
 
455
}
 
456
 
 
457
 
 
458
/**************************************************************************
 
459
*       Compare BioSources in one bioseq->descr using Taxonomy to find
 
460
*       their join parent
 
461
*       merge if organisms are the same or create a feature if different
 
462
*
 
463
**************************************************************************/
 
464
NLM_EXTERN void Tax3MergeSourceDescr (SeqEntryPtr sep, Pointer data, Int4 index, Int2 indent)
 
465
{
 
466
        BioseqPtr    bsp = NULL;
 
467
        ValNodePtr   vnp, newlist;
 
468
        SeqFeatPtr   sfp;
 
469
        BioSourcePtr first_biop = NULL;
 
470
        BioSourcePtr other_biop;
 
471
        BioSourcePtr tmp_biop;
 
472
        ObjValNodePtr ovp;
 
473
 
 
474
        if (!IS_Bioseq(sep)) {
 
475
                return;
 
476
        }
 
477
        newlist = (ValNodePtr) data;
 
478
        bsp = (BioseqPtr) sep->data.ptrvalue;
 
479
        if ((bsp->repr != Seq_repr_raw) && (bsp->repr != Seq_repr_const) 
 
480
                        && (bsp->repr != Seq_repr_delta))
 
481
                return;
 
482
 
 
483
        if (! ISA_na(bsp->mol))
 
484
                return;
 
485
        
 
486
        /* add the descriptors in newlist to the end of the list in bsp->descr*/
 
487
        if (bsp->descr == NULL)
 
488
        {
 
489
          bsp->descr = newlist;
 
490
        }
 
491
        else
 
492
        {
 
493
          for (vnp = bsp->descr; vnp->next != NULL; vnp = vnp->next)
 
494
          {     
 
495
          }
 
496
          vnp->next = newlist;
 
497
        }
 
498
        
 
499
        /* now find the first source descriptor in bsp->descr that has an org*/
 
500
    /* note - we can't use SeqMgrGetNextDescriptor here because we have just
 
501
     * added to the descriptors, so they are not indexed. */
 
502
        for (vnp = bsp->descr; vnp != NULL; vnp = vnp->next)
 
503
        {
 
504
          if (vnp->choice != Seq_descr_source) continue;
 
505
          if (vnp->data.ptrvalue == NULL)
 
506
          {
 
507
                ErrPostStr(SEV_WARNING, 0, 0, "Source descriptor missing data");
 
508
                if (vnp->extended)
 
509
                {
 
510
                  ovp = (ObjValNodePtr) vnp;
 
511
                  ovp->idx.deleteme = TRUE;
 
512
                }
 
513
          }
 
514
          if (first_biop == NULL)
 
515
          {
 
516
                first_biop = vnp->data.ptrvalue;
 
517
          }
 
518
          else
 
519
          {
 
520
                other_biop = vnp->data.ptrvalue;
 
521
                /* detach biosource pointer from descr, so that it will not be freed
 
522
                 * when the descriptor is deleted.
 
523
                 */
 
524
                vnp->data.ptrvalue = NULL;
 
525
        if (vnp->extended)
 
526
        {
 
527
          ovp = (ObjValNodePtr) vnp;
 
528
                  ovp->idx.deleteme = TRUE;
 
529
        }
 
530
        if (DoOrgIdsMatch(first_biop, other_biop)) 
 
531
                {
 
532
                  /* merge the two sources */
 
533
                  tmp_biop = Tax3BioSourceMerge(first_biop, other_biop);
 
534
                  if (tmp_biop == NULL)
 
535
                  {
 
536
                        ErrPostStr (SEV_WARNING, 0, 0, "Failed to merge biosources");
 
537
                  }
 
538
                  else
 
539
                  {
 
540
                        first_biop = tmp_biop;
 
541
                  }
 
542
                  other_biop = BioSourceFree (other_biop);
 
543
                } else {
 
544
                  /* create a source feature */
 
545
                  sfp = CreateNewFeatureOnBioseq (bsp, SEQFEAT_BIOSRC, NULL);
 
546
                  if (sfp != NULL)
 
547
                  {
 
548
            sfp->data.value.ptrvalue = other_biop;
 
549
                  }
 
550
        }
 
551
          }
 
552
        }
 
553
        return;
 
554
}
 
555
 
 
556
static Int4 GetTaxIdFromOrgRef (OrgRefPtr orp)
 
557
{
 
558
  Int4       tax_id = -1;
 
559
  ValNodePtr vnp;
 
560
  DbtagPtr   d;
 
561
 
 
562
  if (orp != NULL)
 
563
  {
 
564
    for (vnp = orp->db; vnp != NULL; vnp = vnp->next) 
 
565
    {
 
566
      d = (DbtagPtr) vnp->data.ptrvalue;
 
567
      if (StringCmp(d->db, "taxon") == 0) 
 
568
      {
 
569
        tax_id = d->tag->id;
 
570
        break;
 
571
      }
 
572
    }
 
573
  }
 
574
  return tax_id;
 
575
}
 
576
 
 
577
NLM_EXTERN Int4 Taxon3GetTaxIdByOrgRef (OrgRefPtr orp)
 
578
{
 
579
  OrgRefPtr  orp_repl;
 
580
  Int4       tax_id = -1;
 
581
  
 
582
  if (orp == NULL) return -1;
 
583
  
 
584
  orp_repl = Taxon3GetOrg (orp);
 
585
  tax_id = GetTaxIdFromOrgRef (orp_repl);
 
586
  OrgRefFree (orp_repl);
 
587
  
 
588
  return tax_id;
 
589
}
 
590
 
 
591
NLM_EXTERN OrgRefPtr Taxon3GetOrgRefByName (CharPtr orgname)
 
592
{
 
593
  OrgRefPtr request, org;
 
594
  
 
595
  request = OrgRefNew ();
 
596
  if (request == NULL) return NULL;
 
597
  request->taxname = orgname;
 
598
  org = Taxon3GetOrg (request);
 
599
  request->taxname = NULL;
 
600
  OrgRefFree (request);
 
601
  return org;
 
602
}
 
603
 
 
604
NLM_EXTERN Int4 Taxon3GetTaxIdByName (CharPtr orgname)
 
605
{
 
606
  OrgRefPtr orp;
 
607
  Int4      tax_id;
 
608
  
 
609
  orp = Taxon3GetOrgRefByName (orgname);
 
610
  tax_id = GetTaxIdFromOrgRef (orp);
 
611
 
 
612
  OrgRefFree(orp);
 
613
  return tax_id;
 
614
}
 
615
 
 
616
static void AddBioSourceToList (BioSourcePtr biop, Pointer userdata)
 
617
{
 
618
  ValNodePtr PNTR list;
 
619
  
 
620
  if (biop == NULL || userdata == NULL) return;
 
621
  list = (ValNodePtr PNTR) userdata;
 
622
  ValNodeAddPointer (list, 4, (Pointer) biop);
 
623
}
 
624
 
 
625
NLM_EXTERN void Taxon3ReplaceOrgInSeqEntry (SeqEntryPtr sep, Boolean keep_syn)
 
626
{
 
627
  ValNodePtr   biop_list = NULL;
 
628
  ValNodePtr   request_list = NULL;
 
629
  ValNodePtr   response_list = NULL;
 
630
  ValNodePtr   biop_vnp, response_vnp;
 
631
  BioSourcePtr biop;
 
632
  OrgRefPtr    swap_org, response_org;
 
633
  
 
634
  VisitBioSourcesInSep (sep, &biop_list, AddBioSourceToList);
 
635
 
 
636
  for (biop_vnp = biop_list; biop_vnp != NULL; biop_vnp = biop_vnp->next)
 
637
  {
 
638
    biop = (BioSourcePtr) biop_vnp->data.ptrvalue;
 
639
    ValNodeAddPointer (&request_list, 3, biop->org);
 
640
  }
 
641
  response_list = Taxon3GetOrgRefList (request_list);
 
642
 
 
643
  if (ValNodeLen (response_list) != ValNodeLen (request_list))
 
644
  {
 
645
    Message (MSG_POST, "Unable to retrieve information from tax server");
 
646
    return;
 
647
  }
 
648
 
 
649
  for (biop_vnp = biop_list, response_vnp = response_list;
 
650
       biop_vnp != NULL && response_vnp != NULL;
 
651
       biop_vnp = biop_vnp->next, response_vnp = response_vnp->next)
 
652
  {
 
653
    biop = (BioSourcePtr) biop_vnp->data.ptrvalue;
 
654
    swap_org = biop->org;
 
655
    response_org = response_vnp->data.ptrvalue;
 
656
    if (response_org == NULL)
 
657
    {
 
658
      Message (MSG_POST, "No tax server information for %s", biop->org->taxname);
 
659
    }
 
660
    else
 
661
    {
 
662
      biop->org = response_org;
 
663
      response_vnp->data.ptrvalue = NULL;
 
664
      OrgRefFree (swap_org);
 
665
      if (! keep_syn)
 
666
      {
 
667
        biop->org->syn = ValNodeFreeData(biop->org->syn);
 
668
      }
 
669
    }
 
670
  }
 
671
  ValNodeFree (request_list);
 
672
  ValNodeFree (response_list);
 
673
  ValNodeFree (biop_list);   
 
674
}