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

« back to all changes in this revision

Viewing changes to network/taxon1/taxon2/tc2proc.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
/*----------------*/
 
2
 
 
3
#include <stdlib.h>
 
4
#include <ncbi.h>
 
5
#include <taxinc.h>
 
6
#include <txclient.h>
 
7
#define REALTAXsyb
 
8
 
 
9
#define MAX_ORG_LIST    10
 
10
 
 
11
#define BUFF_SIZE 16
 
12
#define TAX_READ 0
 
13
#define TAX_WRITE 1
 
14
 
 
15
 
 
16
static TreePtr tax_tree= NULL;
 
17
 
 
18
static Int2 VRL_div= 0;
 
19
static Int2 PHG_div= 0;
 
20
 
 
21
static Int2 SpeciesRank= 26;
 
22
static Int2 SubspeciesRank= 27;
 
23
static Int2 GenusRank= 22;
 
24
static Int2 FamilyRank= 0;
 
25
static Int2 OrderRank= 0;
 
26
static Int2 ClassRank= 0;
 
27
static Int2 SYNONYM= 0;
 
28
static Int2 COMMON_NAME= 0;
 
29
static Int2 PREF_COMMON= 0;
 
30
 
 
31
static int my_timer= 0;
 
32
 
 
33
typedef struct t_nameList {
 
34
    struct t_nameList* next;
 
35
    char* name;
 
36
} NameList, *NameListPtr;
 
37
 
 
38
static struct t_or_buff {
 
39
    Int4 tax_id;
 
40
    OrgRefPtr p_org_ref;
 
41
    int timer;
 
42
    int is_uncultured;
 
43
    int is_species;
 
44
    int has_modif;
 
45
    NameListPtr blast_name;
 
46
} or_buff[BUFF_SIZE];
 
47
 
 
48
static CharPtr DB_PATH= "TAX_OS";
 
49
 
 
50
static Boolean we_want_synonyms= 0;
 
51
 
 
52
static OrgRefPtr getFromBuff(Int4 id, int* is_sp, int* is_uncult, NameListPtr* bnl);
 
53
static void loadInBuff(Int4 id);
 
54
static void bldOrgRefOut(OrgRefPtr dst, OrgRefPtr src, Int4 tax_id);
 
55
 
 
56
Boolean tax1_setSynonyms(Boolean on_off)
 
57
{
 
58
    Boolean ret;
 
59
 
 
60
    ret= we_want_synonyms;
 
61
    we_want_synonyms= on_off;
 
62
    return ret;
 
63
}
 
64
 
 
65
  
 
66
static Boolean tc2_toNode(TreeCursorPtr cursor, Int4 tax_id)
 
67
{
 
68
    if(!tax_ptree_toTaxId(cursor, tax_id, FALSE)) {
 
69
        /* this node is not in our tree */
 
70
        return (tax_ptree_addNode(tax_tree, tax_id)) ? 
 
71
            tax_ptree_toTaxId(cursor, tax_id, FALSE) : FALSE;
 
72
    }
 
73
    return TRUE;
 
74
}
 
75
 
 
76
static void lockBuff(int mode)
 
77
{
 
78
    mode= mode;
 
79
}
 
80
 
 
81
static void unlockBuff(void)
 
82
{
 
83
}
 
84
 
 
85
static void initBuff(void)
 
86
{
 
87
    int i;
 
88
 
 
89
    my_timer= 0;
 
90
  
 
91
    for(i= 0; i < BUFF_SIZE; i++) {
 
92
        or_buff[i].tax_id= 0;
 
93
        or_buff[i].p_org_ref= NULL;
 
94
        or_buff[i].blast_name= NULL;
 
95
    }
 
96
}
 
97
 
 
98
static Int4 getLiveId(Int4 id)
 
99
{
 
100
    TreeCursorPtr cursor= tree_openCursor(tax_tree, NULL, NULL);
 
101
    Uint2 s;
 
102
    TXC_TreeNodePtr tnp;
 
103
    
 
104
    if((cursor == NULL) || (!tc2_toNode(cursor, id))) return 0;
 
105
 
 
106
    tnp= tree_getNodeData(cursor, &s);
 
107
    tree_closeCursor(cursor);
 
108
    return (tnp != NULL)? tnp->tax_id : 0;
 
109
}
 
110
 
 
111
 
 
112
/**************************************************************************
 
113
 *
 
114
 *      InitTaxDB
 
115
 *
 
116
 **************************************************************************/
 
117
 
 
118
int InitTaxDB(void)
 
119
{
 
120
    CharPtr tmp;
 
121
 
 
122
    if((tmp=getenv("TAXDBPATH")) != NULL) DB_PATH= tmp;
 
123
 
 
124
    if(!txc_connect2Server(DB_PATH, "soussov", "vladimir", "tax2cl")) {
 
125
 
 
126
        return 0;
 
127
    }
 
128
       
 
129
    if((!txc_loadNameClasses()) || (!txc_loadRanks()) || 
 
130
       (!txc_loadDivisions()) || (!txc_loadGCs())) {
 
131
 
 
132
        return 0;
 
133
    }
 
134
 
 
135
 
 
136
    SpeciesRank=    tax_getRankId("species");
 
137
    SubspeciesRank= tax_getRankId("subspecies");
 
138
    GenusRank=      tax_getRankId("genus");
 
139
    FamilyRank=     tax_getRankId("family");
 
140
    OrderRank=      tax_getRankId("order");
 
141
    ClassRank=      tax_getRankId("class");
 
142
 
 
143
 
 
144
    VRL_div= tax_getDivisionId("VRL", NULL);
 
145
    PHG_div= tax_getDivisionId("PHG", NULL);
 
146
 
 
147
    SYNONYM=     tax_getClass_cde("synonym");
 
148
    COMMON_NAME= tax_getClass_cde("common name");
 
149
    PREF_COMMON= tax_getClass_cde("preferred common name");
 
150
 
 
151
    initBuff();
 
152
    tax_tree= tax_ptree_new();
 
153
  
 
154
    return (tax_tree == NULL)? 0 : 1;
 
155
}
 
156
 
 
157
/**************************************************************************
 
158
 *
 
159
 *      CloseTaxDB
 
160
 *
 
161
 **************************************************************************/
 
162
 
 
163
static void free_blast_name(NameListPtr   blast_name)
 
164
{
 
165
    if(blast_name != NULL) {
 
166
        NameListPtr t;
 
167
 
 
168
        do {
 
169
            t= blast_name->next;
 
170
            MemFree(blast_name);
 
171
            blast_name= t;
 
172
        }
 
173
        while(blast_name);
 
174
    }   
 
175
}
 
176
 
 
177
int CloseTaxDB(void)
 
178
{
 
179
    int i;
 
180
 
 
181
    if(tax_tree != NULL) {
 
182
        tree_delete(tax_tree);
 
183
 
 
184
        txc_close();
 
185
 
 
186
        for(i= 0; i < BUFF_SIZE; i++) {
 
187
            if(or_buff[i].p_org_ref != NULL) {
 
188
                OrgRefFree(or_buff[i].p_org_ref);
 
189
                if(or_buff[i].blast_name != NULL) {
 
190
                    free_blast_name(or_buff[i].blast_name);
 
191
                }
 
192
            }
 
193
        }
 
194
    }
 
195
    return 1;
 
196
}
 
197
 
 
198
Int4 tax1_getParent(Int4 id_tax)
 
199
{
 
200
    TreeCursorPtr cursor;
 
201
    Int4 ret_id= -1;
 
202
 
 
203
    if(tax_tree == NULL) return -1;
 
204
 
 
205
    if(id_tax == 1) return 0;
 
206
 
 
207
    cursor= tree_openCursor(tax_tree, NULL, NULL);
 
208
    if(cursor == NULL) return -1;
 
209
 
 
210
    if(tc2_toNode(cursor, id_tax)) {
 
211
        TXC_TreeNodePtr tnp;
 
212
        Uint2 s;
 
213
 
 
214
        tree_parent(cursor);
 
215
        tnp= tree_getNodeData(cursor, &s);
 
216
        if(tnp != NULL) ret_id= tnp->tax_id;
 
217
    }
 
218
    
 
219
    tree_closeCursor(cursor);
 
220
    return ret_id;
 
221
}
 
222
 
 
223
Int4 tax1_getGenus(Int4 id_tax)
 
224
{
 
225
    TreeCursorPtr cursor;
 
226
    Int4 ret_id= -1;
 
227
 
 
228
    if(tax_tree == NULL) return -1;
 
229
 
 
230
    if(id_tax == 1) return 0;
 
231
 
 
232
    cursor= tree_openCursor(tax_tree, NULL, NULL);
 
233
    if(cursor == NULL) return -1;
 
234
 
 
235
    if(tc2_toNode(cursor, id_tax)) {
 
236
        TXC_TreeNodePtr tnp;
 
237
        Uint2 s;
 
238
        Int2 rank;
 
239
 
 
240
        do {
 
241
            tree_parent(cursor);
 
242
            tnp= tree_getNodeData(cursor, &s);
 
243
            if(tnp == NULL) {
 
244
                ret_id= -1;
 
245
                break;
 
246
            }
 
247
            ret_id= tnp->tax_id;
 
248
            rank= tnp->flags & 0xFF;
 
249
            --rank;
 
250
            if(rank == GenusRank) break;
 
251
            if((rank > 0) && (rank < GenusRank)) ret_id= -1;
 
252
        }
 
253
        while(ret_id > 1);
 
254
    }
 
255
    
 
256
    tree_closeCursor(cursor);
 
257
    return (ret_id > 1)? ret_id : -1;
 
258
}
 
259
 
 
260
int tax1_getChildren(Int4 id_tax, Int4** ids_out)
 
261
{
 
262
    int n= 0;
 
263
    Int4* ids;
 
264
    TreeCursorPtr cursor= tree_openCursor(tax_tree, NULL, NULL);
 
265
 
 
266
    *ids_out= NULL;
 
267
 
 
268
    if(cursor == NULL) return 0;
 
269
 
 
270
    if(tc2_toNode(cursor, id_tax)) {
 
271
        if(tax_ptree_addChildren(cursor) && tree_child(cursor)) {
 
272
            TXC_TreeNodePtr tnp;
 
273
            Uint2 s;
 
274
 
 
275
            do {
 
276
                n++;
 
277
            }
 
278
            while(tree_sibling(cursor));
 
279
 
 
280
            *ids_out= ids= MemNew(n*sizeof(Int4));
 
281
 
 
282
            tree_parent(cursor);
 
283
            tree_child(cursor);
 
284
            n= 0;
 
285
            do {
 
286
                tnp= tree_getNodeData(cursor, &s);
 
287
                if(tnp != NULL) ids[n++]= tnp->tax_id;
 
288
            }
 
289
            while(tree_sibling(cursor));
 
290
        }
 
291
    }
 
292
 
 
293
    tree_closeCursor(cursor);
 
294
    return n;
 
295
}
 
296
    
 
297
 
 
298
/* find last common ancestor for two nodes */
 
299
Int4 tax1_join(Int4 taxid1, Int4 taxid2)
 
300
{
 
301
    TreeNodeId nid;
 
302
    Int4 aid= 0;
 
303
    TreeCursorPtr cursor1= tree_openCursor(tax_tree, NULL, NULL);
 
304
    TreeCursorPtr cursor2= tree_openCursor(tax_tree, NULL, NULL);
 
305
 
 
306
    if((cursor1 == NULL) || (cursor2 == NULL) || 
 
307
       (!tc2_toNode(cursor1, taxid1)) || (!tc2_toNode(cursor2, taxid2))) {
 
308
        if(cursor1 != NULL) tree_closeCursor(cursor1);
 
309
        if(cursor2 != NULL) tree_closeCursor(cursor2);
 
310
        return -1;
 
311
    }
 
312
 
 
313
    nid= tree_getAncestor(cursor1, cursor2);
 
314
 
 
315
    if(tree_toNode(cursor1, nid)) {
 
316
        TXC_TreeNodePtr tnp;
 
317
        Uint2 s;
 
318
 
 
319
        tnp= tree_getNodeData(cursor1, &s);
 
320
        if(tnp != NULL) aid= tnp->tax_id;
 
321
    }
 
322
 
 
323
    tree_closeCursor(cursor1);
 
324
    tree_closeCursor(cursor2);
 
325
    return aid;
 
326
}
 
327
 
 
328
 
 
329
/***************************************************
 
330
 * Get tax_id by organism name
 
331
 * returns:
 
332
 *       tax_id if one node found
 
333
 *       0      no organism found
 
334
 *       -tax_id if more than one node found
 
335
 */
 
336
Int4 tax1_getTaxIdByName(CharPtr orgname)
 
337
{
 
338
    return tax_getIdByName(orgname, NULL, 0);
 
339
}
 
340
 
 
341
/***************************************************
 
342
 * Get all tax_id by organism name
 
343
 * returns:
 
344
 *       Number of tax ids found
 
345
 */
 
346
Int4 tax1_getAllTaxIdByName(CharPtr orgname, Int4 **Ids_out)
 
347
{
 
348
    int i;
 
349
    TaxNamePtr nameList;
 
350
    Int4 *Ids;
 
351
    int n= tax_findByName(orgname, TAX_NAME_SEARCH, &nameList);
 
352
 
 
353
    if(n < 1) return 0;
 
354
 
 
355
    *Ids_out= Ids= MemNew(n*sizeof(Int4));
 
356
    if(Ids != NULL) {
 
357
        for(i= 0; i < n; i++) {
 
358
            Ids[i]= nameList[i].tax_id;
 
359
            if(nameList[i].name_txt != NULL) MemFree(nameList[i].name_txt);
 
360
            if(nameList[i].unique_name != NULL) MemFree(nameList[i].unique_name);
 
361
        }
 
362
    }
 
363
    else {
 
364
        for(i= 0; i < n; i++) {
 
365
            if(nameList[i].name_txt != NULL) MemFree(nameList[i].name_txt);
 
366
            if(nameList[i].unique_name != NULL) MemFree(nameList[i].unique_name);
 
367
        }
 
368
        n= 0;
 
369
    }
 
370
    MemFree(nameList);
 
371
    return n;
 
372
}
 
373
 
 
374
static Boolean goodOrgMode(Uint1 t)
 
375
{
 
376
    return (t != 254) && (t != 20);
 
377
}
 
378
        
 
379
static Int4 getIdByOrgRef(CharPtr sname, OrgNamePtr orNm)
 
380
{
 
381
    if(orNm != NULL) {
 
382
        OrgModPtr o_mod= orNm->mod;
 
383
        Boolean om_flag= FALSE;
 
384
        Int4 tax_id, id;
 
385
        CharPtr altname= NULL;
 
386
        int nof_mods= 0;
 
387
        _subspecPtr ss;
 
388
        _subspec src;
 
389
 
 
390
        /* first try to search using search name */
 
391
        for(;o_mod != NULL; o_mod= o_mod->next) {
 
392
            if(o_mod->subtype == 254) {
 
393
                /* search name */
 
394
                altname= o_mod->subname;
 
395
            }
 
396
            else if(o_mod->subtype != 20) nof_mods++;
 
397
        }
 
398
 
 
399
        if(nof_mods == 0) {
 
400
            /* we have no modifiers */
 
401
            if(altname != NULL) {
 
402
                if((tax_id= tax_getIdByName(altname, NULL, 0)) > 0) return tax_id;
 
403
                return tax_getIdByName(sname, altname, 254);
 
404
            }
 
405
            return tax_getIdByName(sname, NULL, 0);
 
406
        }
 
407
                
 
408
        if(nof_mods == 1) {
 
409
            /* we have one valuable modifier */
 
410
            for(o_mod= orNm->mod; o_mod != NULL; o_mod= o_mod->next) {
 
411
                if(goodOrgMode(o_mod->subtype)) {
 
412
                    if(altname != NULL) {
 
413
                        if((tax_id= tax_getIdByName(altname, o_mod->subname, o_mod->subtype)) > 0) 
 
414
                            return tax_id; /* find by old name and modifier */
 
415
                        if((tax_id= tax_getIdByName(sname, o_mod->subname, o_mod->subtype)) > 0) 
 
416
                            return tax_id; /* find by new name and modifier */
 
417
                        return tax_getIdByName(sname, altname, 254); /* find by new name and old name */
 
418
                    }
 
419
                    return tax_getIdByName(sname, o_mod->subname, o_mod->subtype);
 
420
                }
 
421
            }
 
422
            return 0;
 
423
        }
 
424
 
 
425
        /* we have more than one modifier */
 
426
        /* first try to find organism using just names */
 
427
        if(altname != NULL) {
 
428
            if((tax_id= tax_getIdByName(altname, NULL, 0)) == 0) {
 
429
                tax_id= tax_getIdByName(sname, altname, 254);
 
430
            }
 
431
        }
 
432
        else {
 
433
            tax_id= tax_getIdByName(sname, NULL, 0);
 
434
        }
 
435
 
 
436
        if(tax_id == 0) return 0; /* we have no such names */
 
437
        if(tax_id > 0) {
 
438
            /* we have found just one node, check it against modifiers */
 
439
            id= 0;
 
440
            for(o_mod= orNm->mod; o_mod != NULL; o_mod= o_mod->next) {
 
441
                if(o_mod->subtype != 20) {
 
442
                    src.stype= o_mod->subtype;
 
443
                    src.sname= o_mod->subname;
 
444
                    src.rname= NULL;
 
445
                    if((ss= tax_SSget(tax_id, &src)) != NULL) {
 
446
                        if(ss->rname != NULL) MemFree(ss->rname);
 
447
                        if((ss->r_id != 0) && (ss->r_id != tax_id)) {
 
448
                            if(id == 0) id= ss->r_id;
 
449
                            else if(id != ss->r_id) {
 
450
                                id= -id; /* conflict in mapping */
 
451
                                break;
 
452
                            }
 
453
                        }
 
454
                    }
 
455
                }
 
456
            }
 
457
            if(id == 0) return tax_id;
 
458
            if(id < 0) return -tax_id; /* we have a mapping conflict */
 
459
            
 
460
            /* we have a mapping without conflict, we try to make the best assumption */
 
461
            return id;
 
462
        }
 
463
 
 
464
        if(tax_id < 0) {
 
465
            /* more than one tax_id was found */
 
466
            Int4Ptr ids;
 
467
            Int4 n;
 
468
 
 
469
            if(altname != NULL) {
 
470
                n= tax1_getAllTaxIdByName(altname, &ids);
 
471
                if(n < 1) n= tax1_getAllTaxIdByName(sname, &ids);
 
472
            }
 
473
            else n= tax1_getAllTaxIdByName(sname, &ids);
 
474
 
 
475
            id= 0;
 
476
            while(n-- > 0) {
 
477
                for(o_mod= orNm->mod; o_mod != NULL; o_mod= o_mod->next) {
 
478
                    if(goodOrgMode(o_mod->subtype)) {
 
479
                        src.stype= o_mod->subtype;
 
480
                        src.sname= o_mod->subname;
 
481
                        src.rname= NULL;
 
482
                        if((ss= tax_SSget(ids[n], &src)) != NULL) {
 
483
                            if(ss->rname != NULL) MemFree(ss->rname);
 
484
                            if(ss->r_id != 0) {
 
485
                                if(id == 0) id= ss->r_id;
 
486
                                else if(id != ss->r_id) id= -id;
 
487
                            }
 
488
                        }
 
489
                    }
 
490
                }
 
491
            }
 
492
            if(ids != NULL) MemFree(ids);
 
493
            if(id > 0) return id;
 
494
        }
 
495
        return tax_id;
 
496
    }
 
497
    else {
 
498
        /* we have no modifiers */
 
499
        return tax_getIdByName(sname, NULL, 0);
 
500
    }
 
501
 
 
502
}
 
503
 
 
504
Int4 tax1_getTaxIdByOrgRef(OrgRefPtr orgRef)
 
505
{
 
506
#ifdef TAXSERVICE
 
507
    return txc_getTaxIdByOrgRef(orgRef);
 
508
#else
 
509
    Int4 tax_id, id;
 
510
 
 
511
    if(orgRef == NULL) return 0;
 
512
 
 
513
    tax_id= 0;
 
514
 
 
515
    if((orgRef->taxname != NULL) &&
 
516
       ((tax_id= getIdByOrgRef(orgRef->taxname, orgRef->orgname)) > 0)) return tax_id;
 
517
        
 
518
    if((orgRef->common != NULL) &&
 
519
       ((tax_id= getIdByOrgRef(orgRef->common, orgRef->orgname)) > 0)) return tax_id;
 
520
 
 
521
    if(orgRef->syn != NULL) {
 
522
        ValNodePtr synonym;
 
523
        
 
524
        id= 0;
 
525
 
 
526
        for(synonym= orgRef->syn; (synonym != NULL) && (id < 1); synonym= synonym->next) {
 
527
            id= getIdByOrgRef(synonym->data.ptrvalue, orgRef->orgname);
 
528
        }
 
529
    }
 
530
 
 
531
    return (id > 0)? id : tax_id;
 
532
#endif
 
533
}
 
534
 
 
535
/*******************************************************************
 
536
 * Get tax_id by organism name (it could be "unique" variant of name)
 
537
 * returns:
 
538
 *       tax_id if one node found
 
539
 *       0      no organism found
 
540
 *       -tax_id if more than one node found
 
541
 */
 
542
Int4 tax1_findTaxIdByName(CharPtr orgname)
 
543
{
 
544
    Int4 id= tax_getIdByName(orgname, NULL, 0);
 
545
 
 
546
    if(id < 1) {
 
547
        Int4 idu= tax_uniqueName(orgname, 0);
 
548
 
 
549
        if(idu > 0) id= idu;
 
550
    }
 
551
    return id;
 
552
}
 
553
 
 
554
 
 
555
/*************************************************************************
 
556
 * Get all tax_id by organism name (it could be "unique" variant of name)
 
557
 * returns:
 
558
 *       Number of tax ids found
 
559
 */
 
560
Int4 tax1_findAllTaxIdByName(CharPtr orgname, Int4 **Ids_out)
 
561
{
 
562
    Int4 id= tax1_findTaxIdByName(orgname);
 
563
    
 
564
    if(id > 0) {
 
565
        *Ids_out= MemNew(sizeof(Int4));
 
566
        if(*Ids_out != NULL) {
 
567
            **Ids_out= id;
 
568
            return 1;
 
569
        }
 
570
        else return 0;
 
571
    }
 
572
    
 
573
    if(id < 0) {
 
574
        return tax1_getAllTaxIdByName(orgname, Ids_out);
 
575
    }
 
576
   
 
577
    return 0;
 
578
}
 
579
 
 
580
Int2 tax1_getAllNames(Int4 tax_id, CharPtr **out_names, Boolean unique)
 
581
{
 
582
    TaxNamePtr nameList;
 
583
    Int2 n= tax_getOrgNames(tax_id, &nameList);
 
584
    Int2 i;
 
585
    CharPtr* names;
 
586
 
 
587
    if(n < 1) return 0;
 
588
 
 
589
    *out_names= names= MemNew(n*sizeof(CharPtr));
 
590
    if(names != NULL) {
 
591
        for(i= 0; i < n; i++) {
 
592
            if(unique && (nameList[i].unique_name != NULL) && (nameList[i].unique_name[0] != '\0')) {
 
593
                names[i]= nameList[i].unique_name;
 
594
                nameList[i].unique_name= NULL;
 
595
            }
 
596
            else {
 
597
                names[i]= nameList[i].name_txt;
 
598
                nameList[i].name_txt= NULL;
 
599
            }
 
600
        }
 
601
    }
 
602
        
 
603
    for(i= 0; i < n; i++) {
 
604
        if(nameList[i].name_txt != NULL) MemFree(nameList[i].name_txt);
 
605
        if(nameList[i].unique_name != NULL) MemFree(nameList[i].unique_name);
 
606
    }
 
607
    
 
608
    MemFree(nameList);
 
609
    return n;
 
610
}
 
611
 
 
612
 
 
613
CharPtr tax1_getGCName(Int2 gc_id)
 
614
{
 
615
    return tax_getGCName(gc_id);
 
616
}
 
617
 
 
618
static OrgRefPtr s_tax1_getOrgRef(Int4 tax_id, int* is_species, int* is_uncultured, NameListPtr* blast_name)
 
619
{
 
620
    OrgRefPtr orp;
 
621
 
 
622
    tax_id= getLiveId(tax_id);
 
623
    if(tax_id == 0) return NULL;
 
624
 
 
625
    if((orp= getFromBuff(tax_id, is_species, is_uncultured, blast_name)) != NULL) {
 
626
        /* OrgRef is already in buffer */
 
627
        return orp;
 
628
    }
 
629
 
 
630
    lockBuff(TAX_WRITE);
 
631
    loadInBuff(tax_id);
 
632
    unlockBuff();
 
633
 
 
634
    return getFromBuff(tax_id, is_species, is_uncultured, blast_name);
 
635
}
 
636
 
 
637
OrgRefPtr tax1m_getOrgRef(Int4 tax_id, int* is_species, int* is_uncultured, CharPtr* blast_name)
 
638
{
 
639
    NameListPtr blast_name_list= NULL;
 
640
    OrgRefPtr orp= s_tax1_getOrgRef(tax_id, is_species, is_uncultured, &blast_name_list);
 
641
    if((blast_name_list != NULL) && (blast_name != NULL)) {
 
642
        *blast_name= StringSave(blast_name_list->name);
 
643
    }
 
644
    return orp;
 
645
}
 
646
 
 
647
OrgRefPtr tax1_getOrgRef(Int4 tax_id, int* is_species, CharPtr div, CharPtr embl_cde)
 
648
{
 
649
    OrgRefPtr orp= s_tax1_getOrgRef(tax_id, is_species, NULL, NULL);
 
650
    if(embl_cde != NULL) *embl_cde= '\0';
 
651
    if((div != NULL) && (orp != NULL) && (orp->orgname != NULL) && (orp->orgname->div != NULL)) {
 
652
        StringCpy(div, orp->orgname->div);
 
653
    }
 
654
    
 
655
    return orp;
 
656
}
 
657
 
 
658
static ValNodePtr make_blast_name(NameListPtr bl)
 
659
{
 
660
    ValNodePtr list= NULL;
 
661
    ValNodePtr header= NULL;
 
662
 
 
663
    while(bl != NULL) {
 
664
        list= ValNodeNew(list);
 
665
        list->data.ptrvalue= StringSave(bl->name);
 
666
        if(header == NULL) header= list;
 
667
        bl= bl->next;
 
668
    }
 
669
    return header;
 
670
}
 
671
 
 
672
Taxon2DataPtr tax1m_getbyid(Int4 tax_id)
 
673
{
 
674
    Taxon2DataPtr res;
 
675
    OrgRefPtr db_orgRef;
 
676
    int is_species;
 
677
    int is_uncultured;
 
678
    NameListPtr bl;
 
679
 
 
680
    if(tax_id <= 0) return NULL;
 
681
    db_orgRef= s_tax1_getOrgRef(tax_id, &is_species, &is_uncultured, &bl);
 
682
    if(db_orgRef == NULL) return NULL; /* nothing found */
 
683
 
 
684
    res= Taxon2DataNew();
 
685
    /* make new orgref */
 
686
    res->org= OrgRefNew();
 
687
    res->org->db= NULL;
 
688
    res->org->orgname= NULL;
 
689
    res->is_species_level= is_species;
 
690
    res->is_uncultured= is_uncultured;
 
691
    res->blast_name= make_blast_name(bl);
 
692
 
 
693
    /* fill-up orgref based on db_orgRef */
 
694
    bldOrgRefOut(res->org, db_orgRef, getLiveId(tax_id));
 
695
    return res;
 
696
}
 
697
 
 
698
/* the old version of the same function */
 
699
Taxon1DataPtr tax1_getbyid(Int4 tax_id)
 
700
{
 
701
    Taxon1DataPtr res;
 
702
    OrgRefPtr db_orgRef;
 
703
    int is_species;
 
704
 
 
705
    if(tax_id <= 0) return NULL;
 
706
    db_orgRef= s_tax1_getOrgRef(tax_id, &is_species, NULL, NULL);
 
707
    if(db_orgRef == NULL) return NULL; /* nothing found */
 
708
 
 
709
    res= Taxon1DataNew();
 
710
    /* make new orgref */
 
711
    res->org= OrgRefNew();
 
712
    res->org->db= NULL;
 
713
    res->org->orgname= NULL;
 
714
    res->is_species_level= is_species;
 
715
    res->embl_code= NULL;
 
716
    res->div= (db_orgRef->orgname != NULL)? StringSave(db_orgRef->orgname->div) : NULL;
 
717
    
 
718
    /* fill-up orgref based on db_orgRef */
 
719
    bldOrgRefOut(res->org, db_orgRef, getLiveId(tax_id));
 
720
    return res;
 
721
}
 
722
 
 
723
/*************************************************************************/
 
724
/* return pointer to first non-blank character in str1 after prefix str2 */
 
725
/* if str2 is not prefix for str1 then return str1                       */
 
726
/*************************************************************************/
 
727
static CharPtr strTail(CharPtr str1, CharPtr str2)
 
728
{
 
729
    CharPtr c;
 
730
 
 
731
    if(StringStr(str1, str2) != str1) return str1;
 
732
 
 
733
    c= str1 + StringLen(str2);
 
734
 
 
735
    while((*c != '\0') && IS_WHITESP(*c)) c++;
 
736
 
 
737
    return c;
 
738
}
 
739
 
 
740
 
 
741
 
 
742
static OrgModPtr bldOrgMod(TreeCursorPtr cursor)
 
743
{
 
744
    TXC_TreeNodePtr parent= NULL;
 
745
    Uint2 s;
 
746
    TXC_TreeNodePtr me= tree_getNodeData(cursor, &s);
 
747
    TXC_TreeNodePtr tnp;
 
748
    TreeNodeId nid= tree_getId(cursor);
 
749
    Int2 rank, prank;
 
750
    OrgModPtr orgMdf= OrgModNew();
 
751
 
 
752
    while(tree_parent(cursor)) {
 
753
        if((tnp= tree_getNodeData(cursor, &s)) == NULL) continue;
 
754
        prank= tnp->flags & 0xFF;
 
755
        --prank;
 
756
        if((prank == SubspeciesRank) || 
 
757
           (prank == SpeciesRank) ||
 
758
           (prank == GenusRank)) {
 
759
            parent= tnp;
 
760
            break;
 
761
        }
 
762
    }
 
763
    tree_toNode(cursor, nid);
 
764
 
 
765
    if(parent != NULL) {
 
766
        orgMdf->subname= StringSave(strTail(me->node_label, parent->node_label));
 
767
    }
 
768
    else {
 
769
        orgMdf->subname= StringSave(me->node_label);
 
770
    }
 
771
 
 
772
    rank= me->flags & 0xFF;
 
773
 
 
774
    if(--rank == SubspeciesRank) {
 
775
        orgMdf->subtype= 22; /* subspecies */
 
776
    }
 
777
    else if(rank == tax_getRankId("varietas")) {
 
778
        orgMdf->subtype= 6; /* variety */
 
779
    }
 
780
    else if(rank == tax_getRankId("forma")) {
 
781
        orgMdf->subtype= 2; /* strain */
 
782
    }
 
783
    else if((parent != NULL) && (prank == SubspeciesRank)) {
 
784
        orgMdf->subtype= 2; /* strain */
 
785
    }
 
786
    else {
 
787
        orgMdf->subtype= 255; /* other */
 
788
    }
 
789
 
 
790
    orgMdf->attrib= NULL;
 
791
 
 
792
    return orgMdf;
 
793
}
 
794
 
 
795
 
 
796
/***************************************************************/  
 
797
/* if name is binomial name build the correspondent structures */
 
798
/* otherwise return 0                                          */
 
799
/***************************************************************/
 
800
static int binomialName(TreeCursorPtr cursor, OrgNamePtr onp)
 
801
{
 
802
    TXC_TreeNodePtr spec= NULL;
 
803
    TXC_TreeNodePtr subspec= NULL;
 
804
    TXC_TreeNodePtr genus= NULL;
 
805
    TXC_TreeNodePtr tnp;
 
806
    Uint2 s;
 
807
    TreeNodeId nid= tree_getId(cursor);
 
808
    Int2 rank;
 
809
    BinomialOrgNamePtr bName;
 
810
 
 
811
    do {
 
812
        tnp= tree_getNodeData(cursor, &s);
 
813
        if(tnp == NULL) continue;
 
814
        rank= tnp->flags & 0xFF;
 
815
        if(--rank == SubspeciesRank) subspec= tnp;
 
816
        else if(rank == SpeciesRank) spec= tnp;
 
817
        else if(rank == GenusRank) {
 
818
            genus= tnp;
 
819
            break;
 
820
        }
 
821
    }
 
822
    while(tree_parent(cursor));
 
823
 
 
824
    tree_toNode(cursor, nid);
 
825
 
 
826
    if(genus == NULL) {
 
827
        /* try to find subgenus */
 
828
        do {
 
829
            tnp= tree_getNodeData(cursor, &s);
 
830
            if(tnp == NULL) continue;
 
831
            rank= tnp->flags & 0xFF;
 
832
            if(--rank == (GenusRank + 1)) {
 
833
                genus= tnp;
 
834
                break;
 
835
            }
 
836
        }
 
837
        while(tree_parent(cursor));
 
838
        tree_toNode(cursor, nid);
 
839
    }
 
840
 
 
841
    if(genus == NULL) return 0; /* no genus - no binomial */
 
842
 
 
843
    onp->choice= 1; /*binomial*/
 
844
 
 
845
    onp->data= bName= BinomialOrgNameNew();
 
846
  
 
847
    bName->genus= StringSave(genus->node_label);
 
848
    
 
849
 
 
850
    if(spec != NULL) {
 
851
        /* we have a species in lineage */
 
852
        bName->species= StringSave(strTail(spec->node_label, genus->node_label));
 
853
 
 
854
        if(subspec != NULL) {
 
855
            /* we also have a subspecies in lineage */
 
856
            bName->subspecies= StringSave(strTail(subspec->node_label, spec->node_label));
 
857
        }
 
858
        else {
 
859
            bName->subspecies= NULL;
 
860
        }
 
861
        tnp= tree_getNodeData(cursor, &s);
 
862
 
 
863
        onp->mod= (tnp == spec)? NULL : bldOrgMod(cursor);    
 
864
        return 1;
 
865
    }
 
866
  
 
867
    /* no species in lineage */
 
868
 
 
869
    if(subspec != NULL) {
 
870
        /* we have no species but we have subspecies */
 
871
        bName->species= NULL;
 
872
        bName->subspecies= StringSave(strTail(subspec->node_label, genus->node_label));
 
873
        onp->mod= bldOrgMod(cursor);
 
874
        return 1;
 
875
    }
 
876
  
 
877
    /* we have no species, no subspecies but we are under species level (varietas or forma) */
 
878
 
 
879
    bName->species= NULL;
 
880
    bName->subspecies= NULL;
 
881
    onp->mod= bldOrgMod(cursor);
 
882
    return 1;
 
883
}
 
884
 
 
885
      
 
886
static void partialName(TreeCursorPtr cursor, OrgNamePtr onp)
 
887
{
 
888
    TaxElementPtr taxElem;
 
889
    Uint2 s;
 
890
    TXC_TreeNodePtr tnp= tree_getNodeData(cursor, &s);
 
891
    Int2 rank_id= tnp->flags & 0xFF;
 
892
 
 
893
    onp->choice= 5; /* partial */
 
894
    onp->data= taxElem= TaxElementNew();
 
895
  
 
896
    if(--rank_id == FamilyRank) {
 
897
        taxElem->fixed_level= 1; /* family */
 
898
        taxElem->level= NULL;
 
899
    }
 
900
    else if(rank_id == OrderRank) {
 
901
        taxElem->fixed_level= 2;
 
902
        taxElem->level= NULL;
 
903
    }
 
904
    else if(rank_id == ClassRank) {
 
905
        taxElem->fixed_level= 3;
 
906
        taxElem->level= NULL;
 
907
    }
 
908
    else {
 
909
        taxElem->fixed_level= 0;
 
910
        taxElem->level= StringSave(tax_getRank(rank_id));
 
911
    }
 
912
 
 
913
    taxElem->name= StringSave(tnp->node_label);
 
914
    taxElem->next= NULL;
 
915
}
 
916
 
 
917
  
 
918
/*****************************************************************
 
919
 * build synonyms valnodes
 
920
 * this routine include in valnodes synonyms and common synonyms
 
921
 */
 
922
static ValNodePtr bldSynValNodes(TaxNamePtr syn, Int2 n)
 
923
{
 
924
    ValNodePtr list= NULL;
 
925
    ValNodePtr header= NULL;
 
926
    Int2 i;
 
927
 
 
928
    for(i= 1; i < n; i++) {
 
929
        if((syn[i].class_cde == SYNONYM) || (syn[i].class_cde == COMMON_NAME)) {
 
930
            list= ValNodeNew(list);
 
931
            list->choice= (syn[i].class_cde == SYNONYM)? 1 : 0;
 
932
            list->data.ptrvalue= syn[i].name_txt;
 
933
            syn[i].name_txt= NULL;
 
934
            if(header == NULL) header= list;
 
935
        }
 
936
    }
 
937
    return header;
 
938
}
 
939
           
 
940
 
 
941
/**************************************************************************
 
942
 *
 
943
 *      FsTaxGetLineage
 
944
 *
 
945
 **************************************************************************/
 
946
 
 
947
static CharPtr bldLineage(TreeCursorPtr cursor, int* is_uncultured, NameListPtr* blast_name)
 
948
{
 
949
    TXC_TreeNodePtr tnp;
 
950
    Uint2 s;
 
951
    TreeNodeId nid= tree_getId(cursor);
 
952
    CharPtr lineage= NULL;
 
953
    CharPtr tmp, t;
 
954
    Int2 rank= 0;
 
955
    
 
956
 
 
957
    while(tree_parent(cursor)) {
 
958
        if((tnp= tree_getNodeData(cursor, &s)) != NULL) {
 
959
            if(tnp->tax_id < 2) break;
 
960
            if(tnp->flags & TXC_UNCULTURED) *is_uncultured= 1;
 
961
            if((tnp->flags & TXC_STHIDE) == 0) { /* we do have a blast name here */
 
962
                NameListPtr node= MemNew(sizeof(NameList));
 
963
                node->name= tnp->node_label + (StringLen(tnp->node_label) + 1);
 
964
                node->next= NULL;
 
965
                *blast_name= node;
 
966
                blast_name= &(node->next);
 
967
            }
 
968
            rank= tnp->flags & 0xFF;
 
969
            if(rank > SpeciesRank) {
 
970
                if(lineage != NULL) {
 
971
                  lineage = MemFree(lineage);
 
972
                }
 
973
                continue;
 
974
            }
 
975
 
 
976
            if((tnp->flags & TXC_GBHIDE) == 0) {
 
977
                s= StringLen(tnp->node_label);
 
978
                if(lineage != NULL) {
 
979
                    s+= StringLen(lineage) + 2;
 
980
                }
 
981
 
 
982
                tmp= MemNew(s+2);
 
983
                if(tmp == NULL) continue;
 
984
                t= StringMove(tmp, tnp->node_label);
 
985
                if(lineage != NULL) {
 
986
                    t= StringMove(t, "; ");
 
987
                    t= StringMove(t, lineage);
 
988
                    MemFree(lineage);
 
989
                }
 
990
                lineage= tmp;
 
991
            }
 
992
        }
 
993
    }
 
994
 
 
995
    tree_toNode(cursor, nid);
 
996
 
 
997
    return lineage;
 
998
}
 
999
 
 
1000
static ValNodePtr bldDBId(Int4 id)
 
1001
{
 
1002
    ValNodePtr dbnode;
 
1003
    DbtagPtr dbtag;
 
1004
    ObjectIdPtr object_id;
 
1005
 
 
1006
    /* populate tax_id */
 
1007
    dbnode= ValNodeNew(NULL);
 
1008
    dbnode->data.ptrvalue= dbtag= DbtagNew();
 
1009
    dbtag->db = StringSave("taxon");
 
1010
    dbtag->tag= object_id= ObjectIdNew();
 
1011
    object_id->str= NULL;
 
1012
    object_id->id = id;
 
1013
    return dbnode;
 
1014
}
 
1015
 
 
1016
static OrgNamePtr bldOrgName(TreeCursorPtr cursor, int* is_species_out, 
 
1017
                             int* is_uncultured, NameListPtr* blast_name)
 
1018
{
 
1019
    OrgNamePtr onp;
 
1020
    Uint2 s;
 
1021
    TXC_TreeNodePtr tnp= tree_getNodeData(cursor, &s);
 
1022
    CharPtr div_abbr;
 
1023
    Int2 rank_id;
 
1024
    int is_species;
 
1025
    Int2 div_id;
 
1026
    TreeNodeId nid= tree_getId(cursor);
 
1027
    Int2 rank;
 
1028
 
 
1029
    /*Int4 p_id, s_id;*/
 
1030
 
 
1031
    if(tnp == NULL) return NULL;
 
1032
 
 
1033
    *is_uncultured= ((tnp->flags & TXC_UNCULTURED) != 0)? 1 : 0;
 
1034
    if((tnp->flags & TXC_STHIDE) == 0) { /* we do have a blast name here */
 
1035
        NameListPtr node= MemNew(sizeof(NameList));
 
1036
        node->name= tnp->node_label + (StringLen(tnp->node_label) + 1);
 
1037
        node->next= NULL;
 
1038
        *blast_name= node;
 
1039
        blast_name= &(node->next);
 
1040
    }
 
1041
 
 
1042
    onp= OrgNameNew();
 
1043
 
 
1044
    rank_id= tnp->flags & 0xFF;
 
1045
    rank_id--;
 
1046
      
 
1047
    div_id= (tnp->flags >> 8) & 0x3F;
 
1048
    onp->gcode= (tnp->flags >> (8+6)) & 0x3F;
 
1049
    onp->mgcode= (tnp->flags >> (8+6+6)) & 0x3F;
 
1050
    onp->lineage= bldLineage(cursor, is_uncultured, blast_name);
 
1051
           
 
1052
    is_species= (rank_id >= SpeciesRank)? 1 : 0;
 
1053
    /* correct level by lineage if node has no rank */
 
1054
    if(rank_id < 0) {
 
1055
 
 
1056
        while(tree_parent(cursor)) {
 
1057
            tnp= tree_getNodeData(cursor, &s);
 
1058
            if(tnp != NULL) {
 
1059
                rank= tnp->flags & 0xFF;
 
1060
                if(rank != 0) {
 
1061
                    is_species= (rank >= SpeciesRank) ? 1 : 0;
 
1062
                    break;
 
1063
                }
 
1064
            }
 
1065
        }
 
1066
        tree_toNode(cursor, nid);
 
1067
        tnp= tree_getNodeData(cursor, &s);
 
1068
    }
 
1069
 
 
1070
    if(tax_getDivision(div_id, &div_abbr, NULL)) {
 
1071
        onp->div= StringSave(div_abbr);
 
1072
        /* StringCpy(div, div_abbr);*/
 
1073
    }
 
1074
    *is_species_out= is_species;
 
1075
 
 
1076
    if(is_species) {
 
1077
        /* we are on species level or below */
 
1078
             
 
1079
        /* check for viruses */
 
1080
        if((div_id == VRL_div) || (div_id == PHG_div)) {
 
1081
            /* this is a virus */
 
1082
            onp->choice= 2; /* virus */
 
1083
            if(rank_id == SpeciesRank) {
 
1084
                /* we are on species level */
 
1085
                onp->data= StringSave(tnp->node_label);
 
1086
                onp->mod= NULL;
 
1087
            }
 
1088
            else {
 
1089
                /* we are below species */
 
1090
                /* first try to find species or min rank which below species but above us */
 
1091
                TreeNodeId s_id;
 
1092
                
 
1093
                s_id.idi= 0;
 
1094
                while(tree_parent(cursor)) {
 
1095
                    tnp= tree_getNodeData(cursor, &s);
 
1096
                    if(tnp != NULL) {
 
1097
                        rank= tnp->flags & 0xFF;
 
1098
                        if(--rank >= SpeciesRank) {
 
1099
                            s_id= tree_getId(cursor);
 
1100
                            if(rank == SpeciesRank) break;
 
1101
                        }
 
1102
                        else if(rank >= 0) break;
 
1103
                    }
 
1104
                }
 
1105
                if(s_id.idi != 0) {
 
1106
                    /* we have species or something above us */
 
1107
                    tree_toNode(cursor, s_id);
 
1108
                }
 
1109
                else {
 
1110
                    /* no species above */
 
1111
                    tree_toNode(cursor, nid);
 
1112
                }
 
1113
                
 
1114
                tnp= tree_getNodeData(cursor, &s);
 
1115
                onp->data= StringSave(tnp->node_label);
 
1116
                if(s_id.idi != 0) {
 
1117
                    tree_toNode(cursor, nid);
 
1118
                }
 
1119
 
 
1120
                onp->mod= bldOrgMod(cursor);
 
1121
            }
 
1122
        }               
 
1123
        else if(!binomialName(cursor, onp)) {
 
1124
            /* name is not binomial: set partial */
 
1125
            partialName(cursor, onp);
 
1126
        }
 
1127
    }
 
1128
    else {
 
1129
        /* above species */
 
1130
        partialName(cursor, onp);
 
1131
    }
 
1132
 
 
1133
  return onp;
 
1134
}
 
1135
 
 
1136
 
 
1137
static Boolean bldOrgRef(Int4 id, OrgRefPtr orp, int* is_species, int* is_uncult, NameListPtr* bnl)
 
1138
{
 
1139
    TreeCursorPtr cursor= tree_openCursor(tax_tree, NULL, NULL);
 
1140
    TaxNamePtr nameList;
 
1141
    Int2 n, i; 
 
1142
    
 
1143
    if((cursor == NULL) || (!tc2_toNode(cursor, id))) return FALSE;
 
1144
 
 
1145
    *is_species= 0;
 
1146
    *is_uncult= 0;
 
1147
    *bnl= NULL;
 
1148
 
 
1149
    n= tax_getOrgNames(id, &nameList);
 
1150
 
 
1151
    if(n < 1) {
 
1152
        tree_closeCursor(cursor);
 
1153
        return FALSE;
 
1154
    }
 
1155
    
 
1156
    orp->taxname= nameList[0].name_txt;
 
1157
    nameList[0].name_txt= NULL;
 
1158
    
 
1159
 
 
1160
    /* fill-up preferred common name */
 
1161
    orp->common= NULL;
 
1162
    for(i= 1; i < n; i++) {
 
1163
        if(nameList[i].class_cde == PREF_COMMON) {
 
1164
            orp->common= nameList[i].name_txt;
 
1165
            nameList[i].name_txt= NULL;
 
1166
            break;
 
1167
        }
 
1168
    }
 
1169
 
 
1170
    /* fill-up synonyms */
 
1171
    orp->syn= bldSynValNodes(nameList, n);
 
1172
    for(i= 0; i < n; i++) {
 
1173
        if(nameList[i].name_txt != NULL) MemFree(nameList[i].name_txt);
 
1174
        if(nameList[i].unique_name != NULL) MemFree(nameList[i].unique_name);
 
1175
    }
 
1176
    
 
1177
    MemFree(nameList);
 
1178
 
 
1179
    orp->mod= NULL;
 
1180
    orp->db= bldDBId(id);
 
1181
    orp->orgname= bldOrgName(cursor, is_species, is_uncult, bnl);
 
1182
    
 
1183
 
 
1184
    tree_closeCursor(cursor);
 
1185
    return TRUE;        
 
1186
}
 
1187
  
 
1188
 
 
1189
static void loadInBuff(Int4 id)
 
1190
{
 
1191
    int i, k= -1;
 
1192
    Int4 t= my_timer + 1;
 
1193
    /*Int4 bt;*/
 
1194
  
 
1195
    for(i= 0; i < BUFF_SIZE; i++) {
 
1196
        if(or_buff[i].tax_id == 0) {
 
1197
            k= i;
 
1198
            break;
 
1199
        }
 
1200
        if(or_buff[i].timer < t) {
 
1201
            t= or_buff[i].timer;
 
1202
            k= i;
 
1203
        }
 
1204
    }
 
1205
 
 
1206
    if(k >= 0) {
 
1207
        if(or_buff[k].p_org_ref != NULL) {
 
1208
            OrgRefFree(or_buff[k].p_org_ref);
 
1209
            free_blast_name(or_buff[k].blast_name);
 
1210
        }
 
1211
            
 
1212
        or_buff[k].tax_id= id;
 
1213
        or_buff[k].p_org_ref= OrgRefNew();
 
1214
        or_buff[k].timer= ++my_timer;
 
1215
        or_buff[k].blast_name= NULL;
 
1216
        if(!bldOrgRef(id, or_buff[k].p_org_ref, &or_buff[k].is_species, 
 
1217
                      &or_buff[k].is_uncultured, &(or_buff[k].blast_name))) {
 
1218
            OrgRefFree(or_buff[k].p_org_ref);
 
1219
            or_buff[k].tax_id= 0;
 
1220
        }
 
1221
    }
 
1222
}
 
1223
 
 
1224
static OrgRefPtr getFromBuff(Int4 id, int* is_sp, int* is_uncult, NameListPtr* bnl)
 
1225
{
 
1226
    int i;
 
1227
    OrgRefPtr orp= NULL;
 
1228
 
 
1229
    lockBuff(TAX_READ);
 
1230
 
 
1231
    for(i= 0; i < BUFF_SIZE; i++) {
 
1232
        if(or_buff[i].tax_id == id) {
 
1233
            or_buff[i].timer= ++my_timer;
 
1234
            orp= or_buff[i].p_org_ref;
 
1235
            if(is_sp != NULL) *is_sp= or_buff[i].is_species;
 
1236
            if(is_uncult != NULL) *is_uncult= or_buff[i].is_uncultured;
 
1237
            if(bnl != NULL) *bnl= or_buff[i].blast_name;
 
1238
            break;
 
1239
        }
 
1240
    }
 
1241
    unlockBuff();
 
1242
    return orp;
 
1243
}
 
1244
 
 
1245
static OrgModPtr fixModifier(Int4 tax_id, OrgModPtr omp)
 
1246
{
 
1247
    _subspec src_ss;
 
1248
    _subspecPtr ss= NULL;
 
1249
 
 
1250
    memset(&src_ss, 0, sizeof(_subspec));
 
1251
 
 
1252
    if(omp->subtype < 2) {
 
1253
        omp->next= NULL;
 
1254
        OrgModFree(omp);
 
1255
        return NULL;
 
1256
    }
 
1257
      
 
1258
 
 
1259
    if((omp->subname != NULL) && (omp->subtype != 0)) {
 
1260
        src_ss.stype= omp->subtype;
 
1261
        src_ss.sname= omp->subname;
 
1262
        src_ss.rname= NULL;
 
1263
 
 
1264
        ss= tax_SSget(tax_id, &src_ss);
 
1265
    }
 
1266
 
 
1267
    if((ss != NULL) && (ss->r_id == tax_id) && (ss->stype == 0)) {
 
1268
        /* remove it */
 
1269
        if(ss->rname != NULL) MemFree(ss->rname);
 
1270
        omp->next= NULL;
 
1271
        OrgModFree(omp);
 
1272
        return NULL;
 
1273
    }
 
1274
 
 
1275
    if((ss != NULL) && (ss->r_id == tax_id) && (ss->stype != 0)) {              
 
1276
        MemFree(omp->subname);
 
1277
        omp->subname= src_ss.rname;
 
1278
        omp->subtype= src_ss.rtype;
 
1279
        return omp;
 
1280
    }
 
1281
 
 
1282
    if(src_ss.rname != NULL) MemFree(src_ss.rname);
 
1283
    return omp;
 
1284
}
 
1285
 
 
1286
static void CleanOrgMod(Int4 tax_id, OrgNamePtr onp)
 
1287
{
 
1288
    OrgModPtr omp, omp_p, omp_n;
 
1289
 
 
1290
    for(omp_p= NULL, omp= onp->mod; omp != NULL; omp= omp_n) {
 
1291
        omp_n= omp->next;
 
1292
        if((omp= fixModifier(tax_id, omp)) == NULL) {
 
1293
            /* exclude this modifier */
 
1294
            if(omp_p == NULL) {
 
1295
                onp->mod= omp_n;
 
1296
            }
 
1297
            else omp_p->next= omp_n;
 
1298
        }
 
1299
        else omp_p= omp;
 
1300
    }
 
1301
}
 
1302
            
 
1303
static void cleanOrgName(Int4 tax_id, OrgNamePtr onp)
 
1304
{
 
1305
    if(onp->lineage != NULL) MemFree(onp->lineage);
 
1306
    if(onp->div != NULL) MemFree(onp->div);
 
1307
#if 1
 
1308
    /* #if 0 means that we will trust to initial modifier */
 
1309
    if(onp->mod != NULL) CleanOrgMod(tax_id, onp);
 
1310
#endif
 
1311
    if(onp->next != NULL) OrgNameSetFree(onp->next);
 
1312
    if(onp->data != NULL) {
 
1313
        switch(onp->choice) {
 
1314
        case 1 : /* binomial name */
 
1315
            BinomialOrgNameFree(onp->data);
 
1316
            break;
 
1317
        case 2 : /* virus name */
 
1318
            MemFree(onp->data);
 
1319
            break;
 
1320
        case 5 : /* partial name */
 
1321
            TaxElementSetFree(onp->data);
 
1322
            break;
 
1323
        }
 
1324
    }
 
1325
}
 
1326
 
 
1327
  
 
1328
static BinomialOrgNamePtr copyBinomial(BinomialOrgNamePtr src)
 
1329
{
 
1330
    BinomialOrgNamePtr dst;
 
1331
 
 
1332
    if(src == NULL) return NULL;
 
1333
 
 
1334
    dst= BinomialOrgNameNew();
 
1335
    dst->genus= (src->genus != NULL)? StringSave(src->genus) : NULL;
 
1336
    dst->species= (src->species != NULL)? StringSave(src->species) : NULL;
 
1337
    dst->subspecies= (src->subspecies != NULL)? StringSave(src->subspecies) : NULL;
 
1338
 
 
1339
    return dst;
 
1340
}
 
1341
 
 
1342
static TaxElementPtr copyPartial(TaxElementPtr src)
 
1343
{
 
1344
    TaxElementPtr dst;
 
1345
 
 
1346
    if(src == NULL) return NULL;
 
1347
 
 
1348
    dst= TaxElementNew();
 
1349
    dst->fixed_level= src->fixed_level;
 
1350
    dst->level= (src->level != NULL)? StringSave(src->level) : NULL;
 
1351
    dst->name= (src->name != NULL)? StringSave(src->name) : NULL;
 
1352
    dst->next= (src->next != NULL)? copyPartial(src->next) : NULL;
 
1353
    return dst;
 
1354
}
 
1355
 
 
1356
static OrgModPtr copyOrgMod(OrgModPtr src)
 
1357
{
 
1358
#if 0
 
1359
    OrgModPtr dst;
 
1360
 
 
1361
    if(src == NULL) return NULL;
 
1362
 
 
1363
    dst= OrgModNew();
 
1364
    dst->subtype= src->subtype;
 
1365
    dst->subname= (src->subname != NULL)? StringSave(src->subname) : NULL;
 
1366
    dst->attrib= (src->attrib != NULL)? StringSave(src->attrib) : NULL;
 
1367
    dst->next= (src->next != NULL)? copyOrgMod(src->next) : NULL;
 
1368
 
 
1369
    return dst;
 
1370
#endif
 
1371
    return NULL;
 
1372
}
 
1373
  
 
1374
static ValNodePtr removeDbtag(ValNodePtr vnp)
 
1375
{
 
1376
    ValNodePtr vnn, vnf, vnl= NULL;
 
1377
    DbtagPtr dbtag;
 
1378
 
 
1379
    for(vnf= vnp; vnp != NULL; vnp= vnn) {
 
1380
        dbtag= vnp->data.ptrvalue;
 
1381
        vnn= vnp->next;
 
1382
        if(dbtag == NULL) return NULL;
 
1383
        if(StringCmp(dbtag->db, "taxon") == 0) {
 
1384
            /* taxon tag, remove it */
 
1385
            if(vnl == NULL) {
 
1386
                vnf= vnn;
 
1387
            }
 
1388
            else {
 
1389
                vnl->next= vnn;
 
1390
            }
 
1391
            DbtagFree(dbtag);
 
1392
            MemFree(vnp);
 
1393
        }
 
1394
        else {
 
1395
            vnl= vnp;
 
1396
        }
 
1397
    }
 
1398
    return vnf;
 
1399
}
 
1400
        
 
1401
 
 
1402
static void bldOrgRefOut(OrgRefPtr dst, OrgRefPtr src, Int4 tax_id)
 
1403
{
 
1404
    ValNodePtr vnp, vnl;
 
1405
    DbtagPtr dbtag;
 
1406
    ObjectIdPtr object_id;
 
1407
    OrgNamePtr onp;
 
1408
 
 
1409
    dst->taxname= StringSave(src->taxname);
 
1410
    dst->common= (src->common != NULL)? StringSave(src->common) : NULL;
 
1411
 
 
1412
    /* populate tax_id */
 
1413
    vnp= ValNodeNew(NULL);
 
1414
    if (dst->db != NULL) {
 
1415
        dst->db= removeDbtag(dst->db);
 
1416
    }
 
1417
    vnp->next= dst->db;
 
1418
    dst->db= vnp;
 
1419
    vnp->data.ptrvalue= dbtag= DbtagNew();
 
1420
    dbtag->db = StringSave("taxon");
 
1421
    dbtag->tag= object_id= ObjectIdNew();
 
1422
    object_id->str= NULL;
 
1423
    object_id->id = getLiveId(tax_id);
 
1424
    
 
1425
    /* copy the synonym list */
 
1426
    dst->syn= NULL; vnl= NULL;
 
1427
    if(we_want_synonyms) {
 
1428
        for(vnp= src->syn; vnp != NULL; vnp= vnp->next) {
 
1429
            vnl= ValNodeNew(vnl);
 
1430
            vnl->choice= vnp->choice;
 
1431
            vnl->data.ptrvalue= StringSave(vnp->data.ptrvalue);
 
1432
            if(dst->syn == NULL) dst->syn= vnl;
 
1433
        }
 
1434
    }
 
1435
  
 
1436
    /* copy orgname */
 
1437
    if(dst->orgname == NULL) dst->orgname= onp= OrgNameNew();
 
1438
    else onp= dst->orgname;
 
1439
 
 
1440
    onp->choice= src->orgname->choice;
 
1441
 
 
1442
    switch(src->orgname->choice) {
 
1443
    case 1 : /*binomial*/
 
1444
        onp->data= copyBinomial(src->orgname->data);
 
1445
        break;
 
1446
    case 2 : /* virus */
 
1447
        onp->data= (src->orgname->data != NULL)? StringSave(src->orgname->data) : NULL;
 
1448
        break;
 
1449
    case 5 : /* partial */
 
1450
        onp->data= copyPartial(src->orgname->data);
 
1451
        break;
 
1452
    default : /* can't handle */
 
1453
        onp->data= NULL;
 
1454
    }
 
1455
  
 
1456
    if(onp->mod == NULL) onp->mod= copyOrgMod(src->orgname->mod);
 
1457
    onp->lineage= (src->orgname->lineage != NULL)? StringSave(src->orgname->lineage) : NULL;
 
1458
    onp->gcode= src->orgname->gcode;
 
1459
    onp->mgcode= src->orgname->mgcode;
 
1460
    onp->div= StringSave(src->orgname->div);
 
1461
}
 
1462
 
 
1463
static void populateReplaced(OrgRefPtr orp, CharPtr oldName)
 
1464
{
 
1465
    OrgNamePtr onp;
 
1466
    OrgModPtr omp;
 
1467
 
 
1468
    if((orp->taxname != NULL) && (StringICmp(orp->taxname, oldName) == 0)) {
 
1469
        MemFree(oldName);
 
1470
        return;
 
1471
    }
 
1472
 
 
1473
    if((orp->common != NULL) && (StringICmp(orp->common, oldName) == 0)) {
 
1474
        MemFree(oldName);
 
1475
        return;
 
1476
    }
 
1477
 
 
1478
    /* organism name was changed */
 
1479
    onp= orp->orgname;
 
1480
    if(onp != NULL) {
 
1481
        omp= OrgModNew();
 
1482
        omp->next= onp->mod;
 
1483
        omp->subtype= 254;
 
1484
        omp->subname= oldName;
 
1485
        onp->mod= omp;
 
1486
    }
 
1487
    else {
 
1488
        MemFree(oldName);
 
1489
    }
 
1490
}
 
1491
 
 
1492
Taxon2DataPtr tax1m_lookup(OrgRefPtr inp_orgRef, int merge)
 
1493
{
 
1494
    Taxon2DataPtr res;
 
1495
    Int4 tax_id;
 
1496
    OrgRefPtr db_orgRef;
 
1497
    int is_species;
 
1498
    int is_uncultured;
 
1499
    NameListPtr bl;
 
1500
    Boolean need_search_name= TRUE;
 
1501
    CharPtr hit_name;
 
1502
 
 
1503
    tax_id= tax1_getTaxIdByOrgRef(inp_orgRef);
 
1504
    if(tax_id <= 0) return NULL;
 
1505
    db_orgRef= s_tax1_getOrgRef(tax_id, &is_species, &is_uncultured, &bl);
 
1506
    if(db_orgRef == NULL) return NULL;
 
1507
 
 
1508
    res= Taxon2DataNew();
 
1509
    res->is_species_level= is_species;
 
1510
    res->is_uncultured= is_uncultured;
 
1511
    res->blast_name= make_blast_name(bl);
 
1512
 
 
1513
    /* populate search name if necessary */
 
1514
    if(inp_orgRef->taxname != NULL) {
 
1515
        if((db_orgRef->taxname != NULL) && (StringICmp(inp_orgRef->taxname, db_orgRef->taxname) == 0)) {
 
1516
            need_search_name= FALSE;
 
1517
        }
 
1518
        else if((db_orgRef->common != NULL) && (StringICmp(inp_orgRef->taxname, db_orgRef->common) == 0)) {
 
1519
            need_search_name= FALSE;
 
1520
        }
 
1521
    }
 
1522
 
 
1523
    if(need_search_name && (inp_orgRef->common != NULL)) {
 
1524
        if((db_orgRef->taxname != NULL) && (StringICmp(inp_orgRef->common, db_orgRef->taxname) == 0)) {
 
1525
            need_search_name= FALSE;
 
1526
        }
 
1527
        else if((db_orgRef->common != NULL) && (StringICmp(inp_orgRef->common, db_orgRef->common) == 0)) {
 
1528
            need_search_name= FALSE;
 
1529
        }
 
1530
    }
 
1531
 
 
1532
    if(need_search_name && (inp_orgRef->orgname != NULL)) {
 
1533
        /* check if search name already exists */
 
1534
        OrgModPtr omp;
 
1535
 
 
1536
        for(omp= inp_orgRef->orgname->mod; omp != NULL; omp= omp->next) {
 
1537
            if(omp->subtype == 254) {
 
1538
                need_search_name= FALSE;
 
1539
                break;
 
1540
            }
 
1541
        }
 
1542
    }
 
1543
 
 
1544
    hit_name= NULL;
 
1545
    if(need_search_name) {
 
1546
        if((inp_orgRef->taxname != NULL) && (inp_orgRef->taxname[0] != '\0')) {
 
1547
            hit_name= StringSave(inp_orgRef->taxname);
 
1548
        }
 
1549
        else if((inp_orgRef->common != NULL) && (inp_orgRef->common[0] != '\0')) {
 
1550
            hit_name= StringSave(inp_orgRef->common);
 
1551
        }
 
1552
    }
 
1553
 
 
1554
    if(merge) {
 
1555
        /* we have to merge old orgref with the new one */
 
1556
        res->org= inp_orgRef;
 
1557
        /* clean-up old information */
 
1558
        if(inp_orgRef->taxname != NULL) MemFree(inp_orgRef->taxname);
 
1559
        if(inp_orgRef->common != NULL) MemFree(inp_orgRef->common);
 
1560
        if(inp_orgRef->syn != NULL) ValNodeFreeData(inp_orgRef->syn);
 
1561
        if(inp_orgRef->orgname != NULL) cleanOrgName(tax_id, inp_orgRef->orgname);
 
1562
    }
 
1563
    else {
 
1564
        /* make new orgref */
 
1565
        res->org= OrgRefNew();
 
1566
        res->org->db= NULL;
 
1567
        res->org->orgname= NULL;
 
1568
    }
 
1569
    /* fill-up orgref based on db_orgRef */
 
1570
    bldOrgRefOut(res->org, db_orgRef, tax_id);
 
1571
    if(need_search_name && (hit_name != NULL)) populateReplaced(res->org, hit_name);
 
1572
    return res;
 
1573
}
 
1574
 
 
1575
Taxon1DataPtr tax1_lookup(OrgRefPtr inp_orgRef, int merge)
 
1576
{
 
1577
    Taxon1DataPtr res;
 
1578
    Int4 tax_id;
 
1579
    OrgRefPtr db_orgRef;
 
1580
    int is_species;
 
1581
    Boolean need_search_name= TRUE;
 
1582
    CharPtr hit_name;
 
1583
 
 
1584
    tax_id= tax1_getTaxIdByOrgRef(inp_orgRef);
 
1585
    if(tax_id <= 0) return NULL;
 
1586
    db_orgRef= s_tax1_getOrgRef(tax_id, &is_species, NULL, NULL);
 
1587
    if(db_orgRef == NULL) return NULL;
 
1588
 
 
1589
    res= Taxon1DataNew();
 
1590
    res->is_species_level= is_species;
 
1591
    res->embl_code= NULL;
 
1592
    res->div= (db_orgRef->orgname != NULL)? StringSave(db_orgRef->orgname->div) : NULL;
 
1593
 
 
1594
    /* populate search name if necessary */
 
1595
    if(inp_orgRef->taxname != NULL) {
 
1596
        if((db_orgRef->taxname != NULL) && (StringICmp(inp_orgRef->taxname, db_orgRef->taxname) == 0)) {
 
1597
            need_search_name= FALSE;
 
1598
        }
 
1599
        else if((db_orgRef->common != NULL) && (StringICmp(inp_orgRef->taxname, db_orgRef->common) == 0)) {
 
1600
            need_search_name= FALSE;
 
1601
        }
 
1602
    }
 
1603
 
 
1604
    if(need_search_name && (inp_orgRef->common != NULL)) {
 
1605
        if((db_orgRef->taxname != NULL) && (StringICmp(inp_orgRef->common, db_orgRef->taxname) == 0)) {
 
1606
            need_search_name= FALSE;
 
1607
        }
 
1608
        else if((db_orgRef->common != NULL) && (StringICmp(inp_orgRef->common, db_orgRef->common) == 0)) {
 
1609
            need_search_name= FALSE;
 
1610
        }
 
1611
    }
 
1612
 
 
1613
    if(need_search_name && (inp_orgRef->orgname != NULL)) {
 
1614
        /* check if search name already exists */
 
1615
        OrgModPtr omp;
 
1616
 
 
1617
        for(omp= inp_orgRef->orgname->mod; omp != NULL; omp= omp->next) {
 
1618
            if(omp->subtype == 254) {
 
1619
                need_search_name= FALSE;
 
1620
                break;
 
1621
            }
 
1622
        }
 
1623
    }
 
1624
 
 
1625
    hit_name= NULL;
 
1626
    if(need_search_name) {
 
1627
        if((inp_orgRef->taxname != NULL) && (inp_orgRef->taxname[0] != '\0')) {
 
1628
            hit_name= StringSave(inp_orgRef->taxname);
 
1629
        }
 
1630
        else if((inp_orgRef->common != NULL) && (inp_orgRef->common[0] != '\0')) {
 
1631
            hit_name= StringSave(inp_orgRef->common);
 
1632
        }
 
1633
    }
 
1634
 
 
1635
    if(merge) {
 
1636
        /* we have to merge old orgref with the new one */
 
1637
        res->org= inp_orgRef;
 
1638
        /* clean-up old information */
 
1639
        if(inp_orgRef->taxname != NULL) MemFree(inp_orgRef->taxname);
 
1640
        if(inp_orgRef->common != NULL) MemFree(inp_orgRef->common);
 
1641
        if(inp_orgRef->syn != NULL) ValNodeFreeData(inp_orgRef->syn);
 
1642
        if(inp_orgRef->orgname != NULL) cleanOrgName(tax_id, inp_orgRef->orgname);
 
1643
    }
 
1644
    else {
 
1645
        /* make new orgref */
 
1646
        res->org= OrgRefNew();
 
1647
        res->org->db= NULL;
 
1648
        res->org->orgname= NULL;
 
1649
    }
 
1650
    /* fill-up orgref based on db_orgRef */
 
1651
    bldOrgRefOut(res->org, db_orgRef, tax_id);
 
1652
    if(need_search_name && (hit_name != NULL)) populateReplaced(res->org, hit_name);
 
1653
    return res;
 
1654
}
 
1655
  
 
1656
  
 
1657
Boolean tax1_init(void)
 
1658
{
 
1659
    return InitTaxDB();
 
1660
}
 
1661
 
 
1662
void tax1_fini(void)
 
1663
{
 
1664
    CloseTaxDB();
 
1665
}
 
1666
 
 
1667
TreePtr tax1e_getTaxTreePtr(void)
 
1668
{
 
1669
    return tax_tree;
 
1670
}
 
1671
 
 
1672
Boolean tax1e_invokeNode(Int4 tax_id)
 
1673
{
 
1674
    return tax_ptree_addNode(tax_tree, tax_id);
 
1675
}
 
1676
 
 
1677
Boolean tax1e_invokeChildren(Int4 tax_id)
 
1678
{
 
1679
    Boolean res= FALSE;
 
1680
 
 
1681
    TreeCursorPtr cursor= tree_openCursor(tax_tree, NULL, NULL);
 
1682
    if(tax_id < 0) {
 
1683
        res= TRUE;
 
1684
        tax_id= -tax_id;
 
1685
    }
 
1686
 
 
1687
    if((cursor == NULL) || (!tc2_toNode(cursor, tax_id))) return FALSE;
 
1688
 
 
1689
    res= res? tax_ptree_addSubtree(cursor) : tax_ptree_addChildren(cursor);
 
1690
 
 
1691
    tree_closeCursor(cursor);
 
1692
    return res;
 
1693
}
 
1694
 
 
1695
Boolean tax1e_toNode(TreeCursorPtr cursor, Int4 tax_id)
 
1696
{
 
1697
    return tc2_toNode(cursor, tax_id);
 
1698
}
 
1699
 
 
1700
Int4 tax1e_getTaxId(TreeCursorPtr cursor)
 
1701
{
 
1702
    Uint2 s;
 
1703
    TXC_TreeNodePtr tnp;
 
1704
    
 
1705
    tnp= tree_getNodeData(cursor, &s);
 
1706
 
 
1707
    return (tnp != NULL)? tnp->tax_id : 0;
 
1708
}
 
1709
 
 
1710
CharPtr tax1e_getTaxName(TreeCursorPtr cursor)
 
1711
{
 
1712
    Uint2 s;
 
1713
    TXC_TreeNodePtr tnp;
 
1714
    
 
1715
    tnp= tree_getNodeData(cursor, &s);
 
1716
 
 
1717
    return (tnp != NULL)? StringSave(tnp->node_label) : NULL;
 
1718
}
 
1719
    
 
1720
Int4 tax1_getTaxId4Str(CharPtr str, CharPtr* substring, Int4Ptr *Ids_out)
 
1721
{
 
1722
    CharPtr b, e;
 
1723
    Int4 tax_id;
 
1724
    /*Int4Ptr Ids;*/
 
1725
    int k;
 
1726
    char c;
 
1727
    
 
1728
    *substring= NULL;
 
1729
    tax_id= tax1_getTaxIdByName(str);
 
1730
 
 
1731
    if(tax_id > 1) {
 
1732
        *Ids_out= MemNew(sizeof(Int4));
 
1733
        **Ids_out= tax_id;
 
1734
        *substring= StringSave(str);
 
1735
        return 1;
 
1736
    }
 
1737
    else if(tax_id < 0) {
 
1738
        *substring= StringSave(str);
 
1739
        return tax1_getAllTaxIdByName(str, Ids_out);
 
1740
    }
 
1741
 
 
1742
    /* whole string matches nothing */
 
1743
    /* try the whole string inside first set of parenthesis */
 
1744
    for(b= str; *b != '\0'; b++) {
 
1745
        if(*b == '(') {
 
1746
            k= 0;
 
1747
            for(e= b+1; *e != '\0'; e++) {
 
1748
                if(*e == '(') {
 
1749
                    k++;
 
1750
                    continue;
 
1751
                }
 
1752
                if(*e == ')') {
 
1753
                    if(k > 0) {
 
1754
                        k--; 
 
1755
                        continue;
 
1756
                    }
 
1757
 
 
1758
                    *e= '\0';
 
1759
                    tax_id= tax1_getTaxIdByName(b+1);
 
1760
 
 
1761
                    if(tax_id > 1) {
 
1762
                        *substring= StringSave(b+1);
 
1763
                        *e= ')';
 
1764
                        *Ids_out= MemNew(sizeof(Int4));
 
1765
                        **Ids_out= tax_id;
 
1766
                        return 1;
 
1767
                    }
 
1768
                    else if(tax_id < 0) {
 
1769
                        *substring= StringSave(b+1);
 
1770
                        *e= ')';
 
1771
                        return tax1_getAllTaxIdByName(*substring, Ids_out);
 
1772
                    }
 
1773
 
 
1774
                    /* whole string won't help lets try truncate it at first comma*/
 
1775
                    *e= ')';
 
1776
                    for(e= b+1; *e != '\0'; e++) {
 
1777
                        if(*e == ',') {
 
1778
                            *e= '\0';
 
1779
                            tax_id= tax1_getTaxIdByName(b+1);
 
1780
 
 
1781
                            if(tax_id > 1) {
 
1782
                                *substring= StringSave(b+1);
 
1783
                                *e= ',';
 
1784
                                *Ids_out= MemNew(sizeof(Int4));
 
1785
                                **Ids_out= tax_id;
 
1786
                                return 1;
 
1787
                            }
 
1788
                            else if(tax_id < 0) {
 
1789
                                *substring= StringSave(b+1);
 
1790
                                *e= ',';
 
1791
                                return tax1_getAllTaxIdByName(*substring, Ids_out);
 
1792
                            }
 
1793
                            *e= ',';
 
1794
                            break;
 
1795
                        }
 
1796
                    }
 
1797
                    break;
 
1798
                }
 
1799
            }
 
1800
            break;
 
1801
        }
 
1802
    }
 
1803
                        
 
1804
    /* we still have got nothing */
 
1805
    /* try the substring before first '(' */
 
1806
    
 
1807
    if(*b == '(') {
 
1808
        /* we are staying on the first '(' */
 
1809
        *b= '\0';
 
1810
        
 
1811
        tax_id= tax1_getTaxIdByName(str);
 
1812
 
 
1813
        if(tax_id > 1) {
 
1814
            *Ids_out= MemNew(sizeof(Int4));
 
1815
            **Ids_out= tax_id;
 
1816
            *substring= StringSave(str);
 
1817
            *b= '(';
 
1818
            return 1;
 
1819
        }
 
1820
        else if(tax_id < 0) {
 
1821
            *substring= StringSave(str);
 
1822
            *b= '(';
 
1823
            return tax1_getAllTaxIdByName(*substring, Ids_out);
 
1824
        }
 
1825
        *b= '(';
 
1826
    }
 
1827
 
 
1828
    b= StringStr(str, "Organism");
 
1829
    if(b == NULL) b= StringStr(str, "organism");
 
1830
    if(b == NULL) b= StringStr(str, "ORGANISM");
 
1831
 
 
1832
    if(b != NULL) {
 
1833
        e= StringChr(b, ':');
 
1834
        if(e != NULL) {
 
1835
            b= e+1;
 
1836
            tax_id= tax1_getTaxIdByName(b);
 
1837
 
 
1838
            if(tax_id > 1) {
 
1839
                *Ids_out= MemNew(sizeof(Int4));
 
1840
                **Ids_out= tax_id;
 
1841
                *substring= StringSave(b);
 
1842
                return 1;
 
1843
            }
 
1844
            else if(tax_id < 0) {
 
1845
                *substring= StringSave(b);
 
1846
                return tax1_getAllTaxIdByName(*substring, Ids_out);
 
1847
            }
 
1848
        
 
1849
            /* if multiple lines  or ; , ( */
 
1850
            for(++e; *e != '\0'; e++) {
 
1851
                if((*e == '\n') || (*e == ';') || (*e == ',') || (*e == '(')) {
 
1852
                    c= *e;
 
1853
                    *e= '\0';
 
1854
                    tax_id= tax1_getTaxIdByName(b);
 
1855
 
 
1856
                    if(tax_id > 1) {
 
1857
                        *substring= StringSave(b);
 
1858
                        *e= c;
 
1859
                        *Ids_out= MemNew(sizeof(Int4));
 
1860
                        **Ids_out= tax_id;
 
1861
                        return 1;
 
1862
                    }
 
1863
                    else if(tax_id < 0) {
 
1864
                        *substring= StringSave(b);
 
1865
                        *e= c;
 
1866
                        return tax1_getAllTaxIdByName(*substring, Ids_out);
 
1867
                    }
 
1868
                    *e= c;
 
1869
                    break;
 
1870
                }
 
1871
            }
 
1872
        }
 
1873
    }
 
1874
    return 0;
 
1875
}    
 
1876
 
 
1877
static int nameCmp(CharPtr s1, CharPtr s2)
 
1878
{
 
1879
    if((s1 == NULL) && (s2 == NULL)) return 0;
 
1880
    if((s1 == NULL) || (s2 == NULL)) return 1;
 
1881
 
 
1882
    return strcmp(s1, s2);
 
1883
}
 
1884
 
 
1885
static Int4 storedTaxId(OrgRefPtr orp)
 
1886
{
 
1887
    ValNodePtr vnp;
 
1888
    DbtagPtr dbtag;
 
1889
    ObjectIdPtr object_id;
 
1890
 
 
1891
    for(vnp= orp->db; vnp != NULL; vnp= vnp->next) {
 
1892
        dbtag= vnp->data.ptrvalue;
 
1893
        if((dbtag != NULL) && (StringCmp(dbtag->db, "taxon") == 0)) {
 
1894
            ObjectIdPtr object_id= dbtag->tag;
 
1895
            return object_id->id;
 
1896
        }
 
1897
    }
 
1898
 
 
1899
    return 0;
 
1900
}
 
1901
 
 
1902
static Int4 OrgModCmp(OrgModPtr omp1, OrgModPtr omp2)
 
1903
{
 
1904
    OrgModPtr omp;
 
1905
    int found;
 
1906
 
 
1907
    if(omp2 == NULL) return 0;
 
1908
    if(omp1 == NULL) return 100;
 
1909
    
 
1910
    for(;omp2 != NULL; omp2= omp2->next) {
 
1911
        found= 0;
 
1912
        for(omp= omp1; omp != NULL; omp= omp->next) {
 
1913
            if((omp2->subtype == omp->subtype) &&
 
1914
               (nameCmp(omp2->subname, omp->subname) == 0)) {
 
1915
                found= 1;
 
1916
                break;
 
1917
            }
 
1918
        }
 
1919
        if(!found) return 100;
 
1920
    }
 
1921
    return 0;
 
1922
}
 
1923
 
 
1924
static Int4 OrgRefCmp(OrgRefPtr orp1, OrgRefPtr orp2)
 
1925
{
 
1926
    OrgNamePtr onp1= orp1->orgname;
 
1927
    OrgNamePtr onp2= orp2->orgname;
 
1928
 
 
1929
    if(onp1 == NULL) return 4;
 
1930
    if(onp2 == NULL) return -2;
 
1931
 
 
1932
    if(onp1->gcode != onp2->gcode) return 2;
 
1933
    if(onp1->mgcode != onp2->mgcode) return 3;
 
1934
 
 
1935
    if(nameCmp(orp1->taxname, orp2->taxname) != 0) return 10;
 
1936
 
 
1937
    if(nameCmp(onp1->lineage, onp2->lineage) != 0) return 20;
 
1938
 
 
1939
    if(nameCmp(orp1->common, orp2->common) != 0) return 30;
 
1940
 
 
1941
    if(onp1->choice != onp2->choice) return 40;
 
1942
 
 
1943
    if(nameCmp(onp1->div, onp2->div) != 0) return 50;
 
1944
 
 
1945
    return OrgModCmp(onp1->mod, onp2->mod);
 
1946
    
 
1947
}
 
1948
 
 
1949
Int4 tax1e_needUpdate(OrgRefPtr inp_orgRef)
 
1950
{
 
1951
    Taxon1DataPtr res;
 
1952
    Int4 tax_id;
 
1953
    OrgRefPtr db_orgRef;
 
1954
    int is_species;
 
1955
    Boolean need_search_name= TRUE;
 
1956
    CharPtr hit_name;
 
1957
 
 
1958
    tax_id= tax1_getTaxIdByOrgRef(inp_orgRef);
 
1959
    if(tax_id <= 0) return -1;
 
1960
 
 
1961
    if(tax_id != storedTaxId(inp_orgRef)) return 1;
 
1962
    
 
1963
    db_orgRef= s_tax1_getOrgRef(tax_id, NULL, NULL, NULL /*res->embl_code*/);
 
1964
    if(db_orgRef == NULL) {
 
1965
        return -2;
 
1966
    }
 
1967
 
 
1968
    return OrgRefCmp(inp_orgRef, db_orgRef);
 
1969
}
 
1970
 
 
1971
Boolean tax1_isAlive(void)
 
1972
{
 
1973
    return (tax1_getTaxIdByName("dog") > 1)? TRUE : FALSE;
 
1974
}
 
1975
 
 
1976
/***************************************************
 
1977
 * Get tax_id for given gi
 
1978
 * returns:
 
1979
 *       tax_id if found
 
1980
 *       0      if no data or error
 
1981
 */
 
1982
Int4 tax1_getTaxId4GI(Int4 gi)
 
1983
{
 
1984
    return tax_getTaxId4GI(gi);
 
1985
}
 
1986
 
 
1987
/***************************************************
 
1988
 * Get pointer to "blast" name
 
1989
 * Returns: the pointer on first blast name at or above this node in the lineage
 
1990
 * NOTE:
 
1991
 * This function does not make a copy of "blast" name, so, caller can not use
 
1992
 * MemFree function for returned pointer.
 
1993
 */
 
1994
CharPtr tax1m_getBlastName(Int4 tax_id)
 
1995
{
 
1996
    CharPtr res= NULL;
 
1997
    TreeCursorPtr cursor= tree_openCursor(tax_tree, NULL, NULL);
 
1998
 
 
1999
    if(tc2_toNode(cursor, tax_id)) {
 
2000
        TXC_TreeNodePtr tnp;
 
2001
        Uint2 s;
 
2002
        do{
 
2003
            tnp= tree_getNodeData(cursor, &s);
 
2004
            if((tnp != NULL) && ((tnp->flags & TXC_STHIDE) == 0)) { /* we do have a blast name here */
 
2005
                res= tnp->node_label + (StringLen(tnp->node_label) + 1);
 
2006
                break;
 
2007
            }
 
2008
        }
 
2009
        while(tree_parent(cursor));
 
2010
    }
 
2011
 
 
2012
    tree_closeCursor(cursor);
 
2013
    return res;
 
2014
}