~ubuntu-branches/ubuntu/lucid/ncbi-tools6/lucid

« back to all changes in this revision

Viewing changes to access/pmfapi.c

  • Committer: Bazaar Package Importer
  • Author(s): Aaron M. Ucko
  • Date: 2002-04-04 22:13:09 UTC
  • Revision ID: james.westby@ubuntu.com-20020404221309-vfze028rfnlrldct
Tags: upstream-6.1.20011220a
ImportĀ upstreamĀ versionĀ 6.1.20011220a

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*   pmfapi.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:  pmfapi.c
 
27
*
 
28
* Author:  Jonathan Kans
 
29
*
 
30
* Version Creation Date:   5/5/00
 
31
*
 
32
* $Revision: 1.11 $
 
33
*
 
34
* File Description: 
 
35
*
 
36
* Modifications:  
 
37
* --------------------------------------------------------------------------
 
38
*
 
39
* ==========================================================================
 
40
*/
 
41
 
 
42
#include <ncbi.h>
 
43
#include <urlquery.h>
 
44
#include <pmfapi.h>
 
45
#include <objmedli.h>
 
46
#include <objpubme.h>
 
47
#include <objsset.h>
 
48
#include <objmgr.h>
 
49
#include <sequtil.h>
 
50
#include <ent2api.h>
 
51
 
 
52
#ifdef OS_MAC
 
53
#include <Events.h>
 
54
#endif
 
55
 
 
56
#ifdef OS_UNIX
 
57
#include <sys/times.h>
 
58
#include <limits.h>
 
59
#endif
 
60
 
 
61
/* ml to std code modified from original in medutil.c */
 
62
 
 
63
static Boolean AllUpperCase (
 
64
  CharPtr p
 
65
)
 
66
 
 
67
{
 
68
  Char  ch;
 
69
 
 
70
  if (p == NULL) return FALSE;
 
71
  ch = *p;
 
72
  while (ch != '\0') {
 
73
    if (! IS_UPPER (ch)) return FALSE;
 
74
    p++;
 
75
    ch = *p;
 
76
  }
 
77
  return TRUE;
 
78
}
 
79
 
 
80
static void SplitMLAuthorName (
 
81
  CharPtr name,
 
82
  CharPtr last,
 
83
  CharPtr initials,
 
84
  CharPtr suffix
 
85
)
 
86
 
 
87
{
 
88
  CharPtr  p, p2;
 
89
  Int2     i;
 
90
  Char     sbuf [20], ibuf [20];
 
91
 
 
92
  /* Clear the ibuf field and transfer the entire name to 'last',
 
93
  excluding leading and trailing spaces */
 
94
 
 
95
  if (name == NULL) return;
 
96
 
 
97
  ibuf [0] = '\0';
 
98
  sbuf [0] = '\0';
 
99
  last [0] = '\0';
 
100
  initials [0] = '\0';
 
101
  suffix [0] = '\0';
 
102
  while (*name <= ' ') {
 
103
    name++;
 
104
    if (*name == '\0') return;
 
105
  }
 
106
  StringCpy( last, name );
 
107
 
 
108
  for (i=StringLen (last) - 1; ((i >= 0) && (last [i] <= ' ')); i--) {
 
109
    last[i] = '\0';
 
110
  }
 
111
 
 
112
  /* Strip off the last token (initials or name suffix (Jr, Sr, suffix.) */
 
113
 
 
114
  p = StringRChr (last, (int) ' ');
 
115
  if (p != NULL) { /* more than just last name */
 
116
 
 
117
    /* Separate the token from the last name */
 
118
 
 
119
    p2 = p + 1;
 
120
    while ((p > last) && (*p == ' ')) {
 
121
      *p = '\0';
 
122
      p--;
 
123
    }
 
124
 
 
125
    /* If the last token is not all upper case, and there are more than
 
126
    two tokens, see if the next to the last are initials (upper case) */
 
127
 
 
128
    if (! AllUpperCase (p2) && (p = StringRChr (last, (int) ' ' )) != NULL) {
 
129
 
 
130
      /* We have at least three tokens, is the next to last initials? */
 
131
 
 
132
      if (AllUpperCase (p + 1)) {
 
133
 
 
134
        /* Yes - concatenate the last two tokens as initials */
 
135
 
 
136
        StringCpy (ibuf, p + 1);
 
137
        StringCpy (sbuf, p2);
 
138
        while (p > last && (*p == ' ')) {
 
139
          *p = '\0';
 
140
          p--;
 
141
        }
 
142
      }
 
143
    }
 
144
    
 
145
    if (ibuf [0] == '\0') { /* Only the last token goes in ibuf */
 
146
      StringCpy (ibuf, p2);
 
147
    }
 
148
  }
 
149
 
 
150
  /* now add periods to ibuf and convert suffix */
 
151
 
 
152
  for (p = initials, p2 = ibuf; *p2 != '\0'; p2++, p++) {
 
153
    *p = *p2;
 
154
    if (! IS_LOWER(*(p2 + 1))) { /* watch out for foreign names */
 
155
      p++;
 
156
      *p = '.';
 
157
    }
 
158
  }
 
159
  *p = '\0';
 
160
 
 
161
  if (sbuf [0]) {
 
162
    if (StringCmp (sbuf, "1d") == 0)
 
163
      p = StringMove (suffix, "I.");
 
164
    else if (StringCmp (sbuf, "2d") == 0)
 
165
      p = StringMove (suffix, "II.");
 
166
    else if (StringCmp (sbuf, "3d") == 0)
 
167
      p = StringMove (suffix, "III.");
 
168
    else if (StringCmp (sbuf, "4th") == 0)
 
169
      p = StringMove (suffix, "IV.");
 
170
    else if (StringCmp (sbuf, "5th") == 0)
 
171
      p = StringMove (suffix, "V.");
 
172
    else if (StringCmp (sbuf, "6th") == 0)
 
173
      p = StringMove (suffix, "VI.");
 
174
    else if (StringCmp (sbuf, "Sr") == 0)
 
175
      p = StringMove (suffix, "Sr.");
 
176
    else if (StringCmp (sbuf, "Jr") == 0)
 
177
      p = StringMove (suffix, "Jr.");
 
178
    else
 
179
      p = StringMove (suffix, sbuf);
 
180
  }
 
181
}
 
182
 
 
183
static ValNodePtr ConvertMLtoSTD (
 
184
  CharPtr token
 
185
)
 
186
 
 
187
{
 
188
  AuthorPtr   aup;
 
189
  CharPtr     eptr;
 
190
  Char        last [80], initials [20], suffix [20];
 
191
  NameStdPtr  nsp;
 
192
  PersonIdPtr pid;
 
193
  ValNodePtr  vnp;
 
194
 
 
195
  if (token == NULL) return NULL;
 
196
  for (eptr = token + StringLen (token) - 1;
 
197
       eptr > token && *eptr == ' ';
 
198
       eptr--) continue;
 
199
 
 
200
  SplitMLAuthorName (token, last, initials, suffix);
 
201
 
 
202
  nsp = NameStdNew ();
 
203
  if (nsp == NULL) return NULL;
 
204
  nsp->names [0] = StringSave (last);
 
205
  if (initials [0] != '\0') {
 
206
    nsp->names[4] = StringSave (initials);
 
207
  }
 
208
  if (suffix[0] != '\0') {
 
209
    nsp->names[5] = StringSave (suffix);
 
210
  }
 
211
  if (nsp->names[0] != NULL) {
 
212
    pid = PersonIdNew ();
 
213
    pid->choice = 2; /* name */
 
214
    pid->data = nsp;
 
215
    aup = AuthorNew ();
 
216
    aup->name = pid;
 
217
    vnp = ValNodeNew (NULL);
 
218
    vnp->data.ptrvalue = (Pointer) aup;
 
219
    return vnp;
 
220
  }
 
221
  return NULL;
 
222
}
 
223
 
 
224
static void ChangeMedlineAuthorsToISO (
 
225
  MedlineEntryPtr mep
 
226
)
 
227
 
 
228
{
 
229
  AuthListPtr  alp;
 
230
  CitArtPtr    cap;
 
231
  ValNodePtr   curr, oldnames, tmp, v;
 
232
 
 
233
  if (mep == NULL) return;
 
234
  cap = mep->cit;
 
235
  if (cap == NULL) return;
 
236
  alp = cap->authors;
 
237
  if (alp == NULL || alp->choice != 2) return;
 
238
 
 
239
  oldnames = alp->names;
 
240
  alp->names = NULL;
 
241
  alp->choice = 1; /* make std names */
 
242
 
 
243
  for (tmp = oldnames; tmp != NULL; tmp = tmp->next) {
 
244
    curr = ConvertMLtoSTD ((CharPtr) tmp->data.ptrvalue);
 
245
    if (alp->names == NULL) {
 
246
      alp->names = curr;
 
247
    } else {
 
248
      for (v = alp->names; v->next != NULL; v = v->next) continue;
 
249
      v->next = curr;
 
250
    }
 
251
  }
 
252
 
 
253
  ValNodeFreeData (oldnames);
 
254
}
 
255
 
 
256
NLM_EXTERN CONN PMFetchOpenConnection (
 
257
  CharPtr db,
 
258
  Int4 uid
 
259
)
 
260
 
 
261
{
 
262
  Char  query [64];
 
263
 
 
264
  if (StringHasNoText (db) || uid < 1) return NULL;
 
265
  if (StringICmp (db, "PubMed") != 0 &&
 
266
      StringICmp (db, "Protein") != 0&&
 
267
      StringICmp (db, "Nucleotide") != 0&&
 
268
      StringICmp (db, "Popset") != 0) {
 
269
    ErrPostEx (SEV_ERROR, 0, 0,  "Unrecognized database %s", db);
 
270
    return NULL;
 
271
  }
 
272
  sprintf (query, "db=%s&id=%ld&report=asn1&mode=text", db, (long) uid);
 
273
  return QUERY_OpenUrlQuery ("www.ncbi.nlm.nih.gov", 80, "/entrez/utils/pmfetch.fcgi",
 
274
                             query, "Entrez2Tool", 30, eMIME_T_NcbiData,
 
275
                             eMIME_AsnText, eENCOD_None, 0);
 
276
}
 
277
 
 
278
static EIO_Status CommonWaitForReply (
 
279
  CONN conn
 
280
)
 
281
 
 
282
{
 
283
  time_t           currtime, starttime;
 
284
  Int2             max = 0;
 
285
  EIO_Status       status;
 
286
  STimeout         timeout;
 
287
#ifdef OS_MAC
 
288
  EventRecord      currEvent;
 
289
#endif
 
290
 
 
291
  if (conn == NULL) return eIO_Unknown;
 
292
 
 
293
#ifdef OS_MAC
 
294
  timeout.sec = 0;
 
295
  timeout.usec = 0;
 
296
#else
 
297
  timeout.sec = 100;
 
298
  timeout.usec = 0;
 
299
#endif
 
300
 
 
301
  starttime = GetSecs ();
 
302
  while ((status = CONN_Wait (conn, eIO_Read, &timeout)) != eIO_Success && max < 300) {
 
303
    currtime = GetSecs ();
 
304
    max = currtime - starttime;
 
305
#ifdef OS_MAC
 
306
    WaitNextEvent (0, &currEvent, 0, NULL);
 
307
#endif
 
308
  }
 
309
 
 
310
  return status;
 
311
}
 
312
 
 
313
NLM_EXTERN PubmedEntryPtr PubMedWaitForReply (
 
314
  CONN conn
 
315
)
 
316
 
 
317
{
 
318
  AsnIoConnPtr    aicp;
 
319
  PubmedEntryPtr  pep = NULL;
 
320
 
 
321
  if (conn == NULL) return NULL;
 
322
 
 
323
  if (CommonWaitForReply (conn) == eIO_Success) {
 
324
    aicp = QUERY_AsnIoConnOpen ("r", conn);
 
325
    pep = PubmedEntryAsnRead (aicp->aip, NULL);
 
326
    QUERY_AsnIoConnClose (aicp);
 
327
  }
 
328
  CONN_Close (conn);
 
329
 
 
330
  ChangeMedlineAuthorsToISO ((MedlineEntryPtr) pep->medent);
 
331
 
 
332
  return pep;
 
333
}
 
334
 
 
335
NLM_EXTERN SeqEntryPtr PubSeqWaitForReply (
 
336
  CONN conn
 
337
)
 
338
 
 
339
{
 
340
  AsnIoConnPtr  aicp;
 
341
  SeqEntryPtr   sep = NULL;
 
342
 
 
343
  if (conn == NULL) return NULL;
 
344
 
 
345
  if (CommonWaitForReply (conn) == eIO_Success) {
 
346
    aicp = QUERY_AsnIoConnOpen ("r", conn);
 
347
    sep = SeqEntryAsnRead (aicp->aip, NULL);
 
348
    QUERY_AsnIoConnClose (aicp);
 
349
  }
 
350
  CONN_Close (conn);
 
351
 
 
352
  return sep;
 
353
}
 
354
 
 
355
NLM_EXTERN PubmedEntryPtr PubMedSynchronousQuery (
 
356
  Int4 uid
 
357
)
 
358
 
 
359
{
 
360
  CONN            conn;
 
361
  PubmedEntryPtr  pep;
 
362
#ifdef OS_UNIX
 
363
  Boolean         logtimes;
 
364
  clock_t         starttime;
 
365
  clock_t         stoptime;
 
366
  struct tms      timebuf;
 
367
#endif
 
368
 
 
369
  if (uid < 1) return NULL;
 
370
 
 
371
#ifdef OS_UNIX
 
372
  logtimes = (Boolean) ((getenv ("NCBI_LOG_SYNC_QUERY_TIMES")) != NULL);
 
373
#endif
 
374
 
 
375
  conn = PMFetchOpenConnection ("PubMed", uid);
 
376
 
 
377
  if (conn == NULL) return NULL;
 
378
 
 
379
  QUERY_SendQuery (conn);
 
380
 
 
381
#ifdef OS_UNIX
 
382
  if (logtimes) {
 
383
    starttime = times (&timebuf);
 
384
  }
 
385
#endif
 
386
 
 
387
  pep = PubMedWaitForReply (conn);
 
388
 
 
389
#ifdef OS_UNIX
 
390
  if (logtimes) {
 
391
    stoptime = times (&timebuf);
 
392
    printf ("PubMedWaitForReply %ld\n", (long) (stoptime - starttime));
 
393
  }
 
394
#endif
 
395
 
 
396
  return pep;
 
397
}
 
398
 
 
399
NLM_EXTERN SeqEntryPtr PubSeqSynchronousQuery (
 
400
  CharPtr db,
 
401
  Int4 uid
 
402
)
 
403
 
 
404
{
 
405
  CONN         conn;
 
406
  SeqEntryPtr  sep;
 
407
#ifdef OS_UNIX
 
408
  Boolean      logtimes;
 
409
  clock_t      starttime;
 
410
  clock_t      stoptime;
 
411
  struct tms   timebuf;
 
412
#endif
 
413
 
 
414
  if (StringHasNoText (db) || uid < 1) return NULL;
 
415
 
 
416
#ifdef OS_UNIX
 
417
  logtimes = (Boolean) ((getenv ("NCBI_LOG_SYNC_QUERY_TIMES")) != NULL);
 
418
#endif
 
419
 
 
420
  conn = PMFetchOpenConnection (db, uid);
 
421
 
 
422
  if (conn == NULL) return NULL;
 
423
 
 
424
  QUERY_SendQuery (conn);
 
425
 
 
426
#ifdef OS_UNIX
 
427
  if (logtimes) {
 
428
    starttime = times (&timebuf);
 
429
  }
 
430
#endif
 
431
 
 
432
  sep = PubSeqWaitForReply (conn);
 
433
 
 
434
#ifdef OS_UNIX
 
435
  if (logtimes) {
 
436
    stoptime = times (&timebuf);
 
437
    printf ("PubSeqWaitForReply %ld\n", (long) (stoptime - starttime));
 
438
  }
 
439
#endif
 
440
 
 
441
  return sep;
 
442
}
 
443
 
 
444
NLM_EXTERN Boolean PubMedAsynchronousQuery (
 
445
  Int4 uid,
 
446
  QUEUE* queue,
 
447
  QueryResultProc resultproc,
 
448
  VoidPtr userdata
 
449
)
 
450
 
 
451
{
 
452
  CONN  conn;
 
453
 
 
454
  conn = PMFetchOpenConnection ("PubMed", uid);
 
455
 
 
456
  if (conn == NULL) return FALSE;
 
457
 
 
458
  QUERY_SendQuery (conn);
 
459
 
 
460
  QUERY_AddToQueue (queue, conn, resultproc, userdata, TRUE);
 
461
 
 
462
  return TRUE;
 
463
}
 
464
 
 
465
NLM_EXTERN Int4 PubMedCheckQueue (
 
466
  QUEUE* queue
 
467
)
 
468
 
 
469
{
 
470
  return QUERY_CheckQueue (queue);
 
471
}
 
472
 
 
473
NLM_EXTERN PubmedEntryPtr PubMedReadReply (
 
474
  CONN conn,
 
475
  EIO_Status status
 
476
)
 
477
 
 
478
{
 
479
  AsnIoConnPtr    aicp;
 
480
  PubmedEntryPtr  pep = NULL;
 
481
 
 
482
  if (conn != NULL && status == eIO_Success) {
 
483
    aicp = QUERY_AsnIoConnOpen ("rb", conn);
 
484
    pep = PubmedEntryAsnRead (aicp->aip, NULL);
 
485
    QUERY_AsnIoConnClose (aicp);
 
486
  }
 
487
  return pep;
 
488
}
 
489
 
 
490
NLM_EXTERN Boolean PubSeqAsynchronousQuery (
 
491
  CharPtr db,
 
492
  Int4 uid,
 
493
  QUEUE* queue,
 
494
  QueryResultProc resultproc,
 
495
  VoidPtr userdata
 
496
)
 
497
 
 
498
{
 
499
  CONN  conn;
 
500
 
 
501
  conn = PMFetchOpenConnection (db, uid);
 
502
 
 
503
  if (conn == NULL) return FALSE;
 
504
 
 
505
  QUERY_SendQuery (conn);
 
506
 
 
507
  QUERY_AddToQueue (queue, conn, resultproc, userdata, TRUE);
 
508
 
 
509
  return TRUE;
 
510
}
 
511
 
 
512
NLM_EXTERN Int4 PubSeqCheckQueue (
 
513
  QUEUE* queue
 
514
)
 
515
 
 
516
{
 
517
  return QUERY_CheckQueue (queue);
 
518
}
 
519
 
 
520
NLM_EXTERN SeqEntryPtr PubSeqReadReply (
 
521
  CONN conn,
 
522
  EIO_Status status
 
523
)
 
524
 
 
525
{
 
526
  AsnIoConnPtr  aicp;
 
527
  SeqEntryPtr   sep = NULL;
 
528
 
 
529
  if (conn != NULL && status == eIO_Success) {
 
530
    aicp = QUERY_AsnIoConnOpen ("rb", conn);
 
531
    sep = SeqEntryAsnRead (aicp->aip, NULL);
 
532
    QUERY_AsnIoConnClose (aicp);
 
533
  }
 
534
  return sep;
 
535
}
 
536
 
 
537
/* object manager registerable fetch function */
 
538
 
 
539
static CharPtr pubseqfetchproc = "PubSeqBioseqFetch";
 
540
 
 
541
static Int2 LIBCALLBACK PubSeqBioseqFetchFunc (Pointer data)
 
542
 
 
543
{
 
544
  BioseqPtr         bsp;
 
545
  Char              id [41];
 
546
  OMProcControlPtr  ompcp;
 
547
  ObjMgrProcPtr     ompp;
 
548
  SeqEntryPtr       sep = NULL;
 
549
  SeqIdPtr          sid;
 
550
  SeqIdPtr          sip;
 
551
  Int4              uid;
 
552
 
 
553
  ompcp = (OMProcControlPtr) data;
 
554
  if (ompcp == NULL) return OM_MSG_RET_ERROR;
 
555
  ompp = ompcp->proc;
 
556
  if (ompp == NULL) return OM_MSG_RET_ERROR;
 
557
  sip = (SeqIdPtr) ompcp->input_data;
 
558
  if (sip == NULL) return OM_MSG_RET_ERROR;
 
559
 
 
560
  if (sip->choice == SEQID_GI) {
 
561
 
 
562
    uid = sip->data.intvalue;
 
563
    if (uid == 0) return OM_MSG_RET_ERROR;
 
564
 
 
565
    sep = PubSeqSynchronousQuery ("nucleotide", uid);
 
566
    if (sep == NULL) {
 
567
      sep = PubSeqSynchronousQuery ("protein", uid);
 
568
    }
 
569
 
 
570
  } else {
 
571
 
 
572
    sid = SeqIdDup (sip);
 
573
    SeqIdWrite (sid, id, PRINTID_FASTA_LONG, sizeof (id) - 1);
 
574
    SeqIdFree (sid);
 
575
 
 
576
    uid = EntrezGetUIDforSeqIdString ("nucleotide", id);
 
577
    if (uid != 0) {
 
578
      sep = PubSeqSynchronousQuery ("nucleotide", uid);
 
579
    } else {
 
580
      uid = EntrezGetUIDforSeqIdString ("protein", id);
 
581
      if (uid == 0) return OM_MSG_RET_ERROR;
 
582
      sep = PubSeqSynchronousQuery ("protein", uid);
 
583
    }
 
584
  }
 
585
 
 
586
  if (sep == NULL) return OM_MSG_RET_ERROR;
 
587
  bsp = BioseqFindInSeqEntry (sip, sep);
 
588
  ompcp->output_data = (Pointer) bsp;
 
589
  ompcp->output_entityID = ObjMgrGetEntityIDForChoice (sep);
 
590
  return OM_MSG_RET_DONE;
 
591
}
 
592
 
 
593
NLM_EXTERN Boolean PubSeqFetchEnable (void)
 
594
 
 
595
{
 
596
  ObjMgrProcLoad (OMPROC_FETCH, pubseqfetchproc, pubseqfetchproc,
 
597
                  OBJ_SEQID, 0, OBJ_BIOSEQ, 0, NULL,
 
598
                  PubSeqBioseqFetchFunc, PROC_PRIORITY_DEFAULT);
 
599
  return TRUE;
 
600
}
 
601
 
 
602
NLM_EXTERN void PubSeqFetchDisable (void)
 
603
 
 
604
{
 
605
  ObjMgrPtr      omp;
 
606
  ObjMgrProcPtr  ompp;
 
607
 
 
608
  omp = ObjMgrGet ();
 
609
  ompp = ObjMgrProcFind (omp, 0, pubseqfetchproc, OMPROC_FETCH);
 
610
  if (ompp == NULL) return;
 
611
  ObjMgrFreeUserData (0, ompp->procid, OMPROC_FETCH, 0);
 
612
}
 
613