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

« back to all changes in this revision

Viewing changes to tools/wwwbutl.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
 
/* $Id: wwwbutl.c,v 6.27 2001/09/06 20:24:34 dondosha Exp $
2
 
* ===========================================================================
3
 
*
4
 
*                            PUBLIC DOMAIN NOTICE
5
 
*               National Center for Biotechnology Information
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 have not placed any restriction on its use or reproduction.
13
 
*
14
 
*  Although all reasonable efforts have been taken to ensure the accuracy
15
 
*  and reliability of the software and data, the NLM and the U.S.
16
 
*  Government do not and cannot warrant the performance or results that
17
 
*  may be obtained by using this software or data. The NLM and the U.S.
18
 
*  Government disclaim all warranties, express or implied, including
19
 
*  warranties of performance, merchantability or fitness for any particular
20
 
*  purpose.
21
 
*
22
 
*  Please cite the author in any work or product based on this material.
23
 
*
24
 
* ===========================================================================
25
 
*
26
 
* File Name:  $RCSfile: wwwbutl.c,v $
27
 
*
28
 
* Author:  Sergei Shavirin
29
 
*
30
 
* Initial Version Creation Date: 04/21/2000
31
 
*
32
 
* $Revision: 6.27 $
33
 
*
34
 
* File Description:
35
 
*         WWW BLAST/PSI/PHI utilities
36
 
*
37
 
* $Log: wwwbutl.c,v $
38
 
* Revision 6.27  2001/09/06 20:24:34  dondosha
39
 
* Removed threshold_first
40
 
*
41
 
* Revision 6.26  2001/07/20 19:56:04  dondosha
42
 
* Scale cutoff_s2 for megablast if match reward not 1
43
 
*
44
 
* Revision 6.25  2001/02/16 15:53:17  dondosha
45
 
* Cosmetic change
46
 
*
47
 
* Revision 6.24  2001/01/05 18:18:28  dondosha
48
 
* Change reward and penalty scores depending on percent identity
49
 
*
50
 
* Revision 6.23  2001/01/05 18:07:15  dondosha
51
 
* Added handling of word size and percent identity fields for options creation
52
 
*
53
 
* Revision 6.22  2000/11/16 22:35:40  dondosha
54
 
* Added lower case masking option and endpoints results option
55
 
*
56
 
* Revision 6.21  2000/10/31 20:21:26  shavirin
57
 
* Fixed bug with RedoAlignmentCore filtering.
58
 
*
59
 
* Revision 6.20  2000/10/16 22:18:35  shavirin
60
 
* Added possibility to perform OOF blastx
61
 
*
62
 
* Revision 6.19  2000/10/16 20:26:35  shavirin
63
 
* Added possibility to rum RPS Blast.
64
 
*
65
 
* Revision 6.18  2000/09/28 16:32:53  dondosha
66
 
* Compiler warning fix
67
 
*
68
 
* Revision 6.17  2000/09/27 22:18:03  shavirin
69
 
* Added possibility to limit search to results of entrez query.
70
 
*
71
 
* Revision 6.16  2000/09/12 22:01:42  dondosha
72
 
* Use matrix returned from search during formatting
73
 
*
74
 
* Revision 6.15  2000/09/08 20:16:59  dondosha
75
 
* Print informative error messages for bad accessions, still do search if at least one accession is good
76
 
*
77
 
* Revision 6.14  2000/09/08 17:46:54  dondosha
78
 
* Allow multiple accessions in input
79
 
*
80
 
* Revision 6.13  2000/09/07 18:02:58  dondosha
81
 
* If query has many sequences, put them in a SeqLoc list
82
 
*
83
 
* Revision 6.12  2000/09/01 21:47:34  dondosha
84
 
* Make check for wordsize too small; add 4 to user-supplied wordsize for megablast
85
 
*
86
 
* Revision 6.11  2000/09/01 17:50:59  dondosha
87
 
* No part of SeqEntry can be freed before the very end
88
 
*
89
 
* Revision 6.10  2000/09/01 17:30:26  dondosha
90
 
* Small corrections for megablast with Entrez client
91
 
*
92
 
* Revision 6.9  2000/08/30 22:20:24  dondosha
93
 
* Small changes for megablast web page
94
 
*
95
 
* Revision 6.8  2000/08/28 20:17:42  dondosha
96
 
* Added functionality for megablast web page
97
 
*
98
 
* Revision 6.7  2000/08/10 18:17:19  shavirin
99
 
* Used correct (fake) Bioseq in printing alignmenets.
100
 
*
101
 
* Revision 6.6  2000/08/10 14:50:37  shavirin
102
 
* Fixed 64 dependent bug
103
 
*
104
 
* Revision 6.4  2000/08/09 20:49:01  shavirin
105
 
* Added support for S&W Blast and XML output.
106
 
*
107
 
* Revision 6.3  2000/07/31 20:39:23  shavirin
108
 
* Some formating changes from Haruna Cofer (haruna@detroit.sgi.com)
109
 
*
110
 
* Revision 6.2  2000/07/26 02:26:16  shavirin
111
 
* Changes in accordance to Alejandro's S&W Blast.
112
 
*
113
 
* Revision 6.1  2000/05/17 15:53:40  shavirin
114
 
* Initial revision.
115
 
*
116
 
*
117
 
* ==========================================================================
118
 
*/
119
 
 
120
 
#include <wwwblast.h>
121
 
 
122
 
static Int4 GlobalAlignNumber = 0; /* For PSI Blast printing ONLY !*/
123
 
 
124
 
void WWWBlastInfoFree(WWWBlastInfoPtr theInfo)
125
 
{
126
 
    Int4 i;
127
 
    WWWInfoFree(theInfo->info);
128
 
    BLASTOptionDelete(theInfo->options);
129
 
    MemFree(theInfo->database);
130
 
    MemFree(theInfo->program);
131
 
 
132
 
    for(i = 0; i < MAX_DB_NUM; i++) {
133
 
        MemFree(theInfo->blast_config->allow_db[i]);
134
 
    }
135
 
    MemFree(theInfo->blast_config);
136
 
 
137
 
    /* if(!theInfo->believe_query)
138
 
       fake_bsp = BlastDeleteFakeBioseq(fake_bsp); */
139
 
 
140
 
    MemFree(theInfo->blast_type);
141
 
    MemFree(theInfo->ConfigFile);
142
 
    SeqLocSetFree(theInfo->query_slp);
143
 
    MemFree(theInfo);
144
 
 
145
 
    return;
146
 
}
147
 
 
148
 
void WWWBlastErrMessage(BLASTErrCode error_code, CharPtr error_msg)
149
 
{
150
 
   WWWBlastErrMessageEx(error_code, error_msg, NULL);
151
 
}
152
 
 
153
 
void WWWBlastErrMessageEx(BLASTErrCode error_code, CharPtr error_msg,
154
 
                          CharPtr seq_info)
155
 
{
156
 
    CharPtr delim = "<BR>";
157
 
 
158
 
    if(error_code == BLASTNoError)
159
 
        return;
160
 
 
161
 
    fprintf(stdout, "<FONT color=red><h3>");
162
 
    fprintf(stdout, "Error %ld in submitting BLAST query", labs(error_code));
163
 
    if (seq_info)
164
 
       fprintf(stdout, "</h3></FONT> <BR> <b> Accession: %s </b> <BR> <HR>\n<b>", seq_info);
165
 
    else
166
 
       fprintf(stdout, "</h3></FONT><HR>\n<b>");
167
 
    fprintf(stdout, "Short error description:");
168
 
    
169
 
    fprintf(stdout, "</b><BR><BR>\n");
170
 
    switch(error_code) {
171
 
        
172
 
    case BLASTEntrez:
173
 
        
174
 
        fprintf(stdout,
175
 
                "Your input sequence may not be found in Entrez %s"
176
 
                "or Entrez access interface currently unavailable. %s"
177
 
                "Please send message to blast_help@ncbi.nlm.nih.gov %s"
178
 
                "with description of your query", 
179
 
                delim, delim, delim);
180
 
        break;
181
 
        
182
 
    case BLASTFastaToSE:
183
 
        
184
 
        fprintf(stdout,
185
 
                "Your input sequence formatted incorrectly. %s"
186
 
                "Please read blast help if you have problems with formatting %s"
187
 
                "or send request to blast help account.", 
188
 
                delim, delim);
189
 
        break;
190
 
        
191
 
    case BLASTErrNoSequence:
192
 
        
193
 
        fprintf(stdout,
194
 
                "Input sequence for the BLAST search, probably missing. %s"
195
 
                "Please see the blast help for a description %s"
196
 
                "of the FASTA sequence format.", 
197
 
                delim, delim);
198
 
        break;
199
 
        
200
 
    case BLASTErrCombination:
201
 
        
202
 
        fprintf(stdout, 
203
 
                "The combination of database and program, that you provided in your %s"
204
 
                "message is invalid or not acceptable by BLAST search system. %s"
205
 
                "Please look at current possible combinations in BLAST help. ",
206
 
                delim, delim);
207
 
        break;
208
 
        
209
 
    case BLASTErrAccType:
210
 
        
211
 
        fprintf(stdout, 
212
 
                "You specified a protein (or nucleotide) sequence identifier, %s"
213
 
                "but a nucleotide (or protein) sequence is required for your search.",
214
 
                delim);
215
 
        
216
 
        break;
217
 
        
218
 
    case BLASTErrDatalib:
219
 
        
220
 
        fprintf(stdout, "No database was specified.  ");
221
 
        break;
222
 
        
223
 
    case BLASTErrNoQueue:
224
 
        fprintf(stdout, 
225
 
                "Unable to accept more BLAST jobs right now, %s"
226
 
                "Queue overloaded. Please try again later.", 
227
 
                delim);
228
 
        break;
229
 
 
230
 
    case BLASTOptionStr:
231
 
        
232
 
        if(error_msg != NULL) {
233
 
            fprintf(stdout, "%s", error_msg);
234
 
        }
235
 
        break;
236
 
        
237
 
    case BLASTMiscError:
238
 
    default:
239
 
        
240
 
        if(error_msg != NULL) {
241
 
            fprintf(stdout, "%s %s", error_msg, delim);
242
 
        } else {
243
 
            fprintf(stdout, 
244
 
                    "There were some internal software problems while processing %s"
245
 
                    "your request. Please contact blast support with a full %s"
246
 
                    "description of your query to BLAST as soon as possible.",
247
 
                    delim, delim); 
248
 
        }
249
 
        break;
250
 
    }
251
 
    
252
 
    fprintf(stdout, "\n<HR>\n");
253
 
 
254
 
    printf("</BODY>\n");
255
 
    printf("</HTML>\n");
256
 
    fflush(stdout);
257
 
    return;
258
 
}
259
 
 
260
 
Boolean BLAST_Time(CharPtr string, Int4 len, time_t seconds)
261
 
{
262
 
    CharPtr chptr;
263
 
    
264
 
    if(string == NULL || len < 25)
265
 
        return FALSE;
266
 
    
267
 
    if(!seconds) {
268
 
        seconds = GetSecs();
269
 
    }
270
 
    
271
 
    if((chptr = ctime(&seconds)) != NULL) 
272
 
        StringCpy(string, chptr);
273
 
    
274
 
    string[24] = NULLB;
275
 
    return TRUE;
276
 
}
277
 
 
278
 
WWWBlastInfoPtr WWWBlastReadArgs(CharPtr type)
279
 
{
280
 
    WWWBlastInfoPtr theInfo;
281
 
    WWWErrorCode error = WWWErrOk; 
282
 
    Int4 index;
283
 
    CharPtr blast_type, hostname, chptr;
284
 
    Char tmp[256];
285
 
    FILE *log_fd;
286
 
 
287
 
    theInfo = MemNew(sizeof(WWWBlastInfo));
288
 
    
289
 
    if((error = WWWGetArgs(&theInfo->info)) != WWWErrOk) {
290
 
        WWWBlastErrMessage(BLASTMiscError, NULL);
291
 
        return NULL;    
292
 
    }
293
 
 
294
 
    if((chptr = WWWGetQuery(theInfo->info)) == NULL || *chptr == NULLB) {
295
 
        fprintf(stdout, "<META HTTP-EQUIV=\"Refresh\" "
296
 
                "CONTENT=\"2; URL=%s.html\">", type ? type : "blast");
297
 
        return NULL;
298
 
    }
299
 
    
300
 
#ifdef PRINT_ALL_INPUT  /* Printing out all coming data for debugging */
301
 
    for(index= 0; index < WWWGetNumEntries(theInfo->info); index ++) {
302
 
        printf("%s : %s<BR>", 
303
 
               WWWGetNameByIndex(theInfo->info, index), 
304
 
               WWWGetValueByIndex(theInfo->info, index));
305
 
    }
306
 
#endif
307
 
    
308
 
    if(getenv("DEBUG_COMMAND_LINE") != NULL) {
309
 
        FILE *fd;
310
 
        fd = FileOpen("/tmp/__web.in", "w");
311
 
        fprintf(fd, "%s", ((WWWInfoDataPtr)theInfo->info)->query);
312
 
        FileClose(fd);
313
 
    }
314
 
 
315
 
    /* Root path for PSI/PHI Blast images */ 
316
 
    theInfo->www_root_path = getenv("WWW_ROOT_PATH"); /* May be NULL */
317
 
    
318
 
    if ( !ErrSetLogfile ("/dev/null", ELOG_APPEND) ) {
319
 
        fprintf(stdout, "Cannot set logfile exiting....\n");
320
 
        return FALSE;
321
 
    } else {
322
 
        ErrSetOpts (ERR_CONTINUE, ERR_LOG_ON);
323
 
    }
324
 
    
325
 
    /* Config file with program/database relationsship */
326
 
    
327
 
    blast_type = WWWGetValueByName(theInfo->info, "WWW_BLAST_TYPE");
328
 
    
329
 
    if(blast_type == NULL || *blast_type == NULLB) {
330
 
        theInfo->blast_type = StringSave(type ? type : "blast");
331
 
        sprintf(tmp, "%s.rc", theInfo->blast_type); 
332
 
        theInfo->ConfigFile = StringSave(tmp);
333
 
    } else {
334
 
        sprintf(tmp, "%s.rc", blast_type);
335
 
        theInfo->blast_type = StringSave(blast_type);
336
 
        theInfo->ConfigFile = StringSave(tmp);
337
 
    }
338
 
    
339
 
    sprintf(tmp, "%s.log", blast_type == NULL? "wwwblast" : blast_type);
340
 
 
341
 
    log_fd = FileOpen(tmp, "a"); 
342
 
 
343
 
    if(log_fd == NULL) /* If log_fd == NULL - no problem */
344
 
        return theInfo;
345
 
    
346
 
    BLAST_Time(tmp, sizeof(tmp), 0);
347
 
 
348
 
    if((hostname = getenv("PROXIED_IP")) == NULL)
349
 
        hostname = WWWGetAddress(theInfo->info);
350
 
    
351
 
    fprintf(log_fd, "\n%d|%s|%s|%s",
352
 
            getpid(), tmp, hostname == NULL? "host_not_set" : hostname,
353
 
            WWWGetAgent(theInfo->info));
354
 
    
355
 
    FileClose(log_fd);
356
 
    
357
 
    return theInfo;
358
 
}
359
 
static Int4 GetLetterIndex(CharPtr letters, Char ch)
360
 
{
361
 
    Int4 index;
362
 
 
363
 
    for(index = 0; letters[index] != NULLB; index++) {
364
 
        if (letters[index] == ch) {
365
 
            return index;
366
 
        }
367
 
    }
368
 
    return -1;
369
 
}
370
 
static Boolean ParseInputString(CharPtr string, 
371
 
                                CharPtr letters, 
372
 
                                CharPtr PNTR *values_in,
373
 
                                CharPtr PNTR ErrorMessage)
374
 
{
375
 
    CharPtr chptr;
376
 
    Int4 i, index = 0, max_par_num;
377
 
    Char option[1024];
378
 
    CharPtr PNTR values;
379
 
    Char message[1024];
380
 
 
381
 
    if(string == NULL || letters == NULL || 
382
 
            *letters == '\0' || values_in == NULL) {
383
 
        return FALSE;
384
 
    }
385
 
 
386
 
    max_par_num = strlen(letters);
387
 
 
388
 
    values = (CharPtr PNTR)MemNew(max_par_num * sizeof(CharPtr));
389
 
    *values_in = values;
390
 
 
391
 
    chptr = string;
392
 
 
393
 
    while(1) {
394
 
        while(IS_WHITESP(*chptr)) /* Rolling spaces */
395
 
            chptr++;
396
 
 
397
 
        if(*chptr == NULLB)   /* Check for NULLB */
398
 
            break;
399
 
 
400
 
        if (*chptr != '-') {   /* Check for the option sign */
401
 
            sprintf(message, "Invalid input string started from \"%s\"", 
402
 
                    chptr);
403
 
            *ErrorMessage = StringSave(message);
404
 
            return FALSE;
405
 
        } else {
406
 
            chptr++;
407
 
        }
408
 
 
409
 
        /* checking index in options table */
410
 
 
411
 
        if((index = GetLetterIndex(letters, *chptr)) < 0) {
412
 
            sprintf(message, "Character \'%c\' is not a valid option", 
413
 
                    *chptr);
414
 
            *ErrorMessage = StringSave(message);
415
 
            return FALSE;
416
 
        }
417
 
 
418
 
        if(*chptr == NULLB)   /* Check for NULLB */
419
 
            break;
420
 
 
421
 
        while(!IS_WHITESP(*chptr)) { /* Finding first space */
422
 
            if(*chptr == NULLB)   /* Check for NULLB */
423
 
                break;
424
 
            chptr++;
425
 
        }
426
 
 
427
 
        while(IS_WHITESP(*chptr)) /* Rolling spaces */
428
 
            chptr++;
429
 
 
430
 
        if(*chptr == NULLB)   /* Check for NULLB */
431
 
            break;
432
 
 
433
 
        for(i=0; !IS_WHITESP(*chptr) && *chptr != NULLB; i++, chptr++) {
434
 
            option[i] = *chptr;
435
 
        }
436
 
 
437
 
        option[i] = NULLB;
438
 
 
439
 
        MemFree(values[index]);
440
 
        values[index] = StringSave(option);
441
 
    }
442
 
 
443
 
    return TRUE;
444
 
}
445
 
/* Set of functions to handle BLAST custom configuration file */
446
 
static BLASTConfigPtr BLASTConfigNew(void)
447
 
{
448
 
    BLASTConfigPtr config;
449
 
    
450
 
    if((config = (BLASTConfigPtr) MemNew(sizeof(BLASTConfig))) == NULL)
451
 
        return NULL;
452
 
    
453
 
    config->run_max = DEFAULT_RUN_MAX;
454
 
    config->queue_max = DEFAULT_QUEUE_MAX;
455
 
    config->num_cpu = NUM_CPU_TO_USE;
456
 
    MemSet(config->allow_db, 0, sizeof(CharPtr)*MAX_DB_NUM);
457
 
 
458
 
    return config;
459
 
}
460
 
static Int4 BLASTEatWs (FILE* fp)
461
 
{
462
 
    Int4 ch;
463
 
 
464
 
    while ((ch = fgetc (fp)) != EOF) {
465
 
        if (ch != ' ' && ch != '\t')
466
 
            return ch;
467
 
    }
468
 
    return ch;
469
 
}
470
 
 
471
 
static void BLASTConfigGetWord(CharPtr word, CharPtr line) 
472
 
{
473
 
    Int4 x = 0, y = 0;
474
 
    
475
 
    for(x=0; line[x] && IS_WHITESP(line[x]); x++);
476
 
 
477
 
    while(TRUE) {
478
 
        if(!(word[y] = line[x]))
479
 
            break;
480
 
        if(IS_WHITESP(line[x]))
481
 
            if((!x) || (line[x-1] != '\\'))
482
 
                break;
483
 
        if(line[x] != '\\') ++y;
484
 
        ++x;
485
 
    }
486
 
    word[y] = '\0';
487
 
 
488
 
    while(line[x] && IS_WHITESP(line[x])) ++x;
489
 
 
490
 
    for(y=0;(line[y] = line[x]);++x,++y);
491
 
}
492
 
static Int4 BLASTConfigGetLine (CharPtr s, Int4 n, FILE* fp)
493
 
{
494
 
    int   len = 0, ch;
495
 
 
496
 
    ch = BLASTEatWs(fp);
497
 
 
498
 
    while (TRUE) {
499
 
        if (ch == EOF || ch == '\n' || (len == n-1)) {
500
 
            if (len && s[len - 1] == ' ') s[len - 1] = '\0';
501
 
            else s[len] = '\0';
502
 
            return feof(fp) ? 1 : 0;
503
 
        }
504
 
        s[len++] = ch;
505
 
        ch = fgetc (fp);
506
 
 
507
 
        if (ch == '\t' || ch == ' ') {
508
 
            s[len++] = ch;
509
 
            ch = BLASTEatWs(fp);
510
 
        }
511
 
    }
512
 
}
513
 
 
514
 
#define MAX_LINE_SIZE 2048
515
 
static BLASTConfigPtr BLASTReadConfigFile(CharPtr filename, CharPtr program)
516
 
{
517
 
    FILE *fd;
518
 
    BLASTConfigPtr config;
519
 
    Char line[MAX_LINE_SIZE], word[MAX_LINE_SIZE];
520
 
    Int4 value, i;
521
 
    
522
 
    if(filename == NULL)
523
 
        return NULL;
524
 
    
525
 
    if((config = BLASTConfigNew()) == NULL)
526
 
        return NULL;
527
 
    
528
 
    if((fd = FileOpen(filename, "r")) == NULL)
529
 
        return NULL;
530
 
 
531
 
    while(!(BLASTConfigGetLine(line, MAX_LINE_SIZE, fd))) {
532
 
        if((line[0] != '#') && (line[0] != '\0')) {
533
 
            BLASTConfigGetWord(word, line);
534
 
 
535
 
            if(!StringICmp(word, "RunMaxProcesses") && 
536
 
                    (value = atoi(line)) != 0) {
537
 
                config->run_max = value;
538
 
            } else if(!StringICmp(word, "QueueMaxJobs") && 
539
 
                    (value = atoi(line)) != 0) {
540
 
                config->queue_max = value;
541
 
            } else if(!StringICmp(word, "NumCpuToUse") && 
542
 
                    (value = atoi(line)) != 0) {
543
 
                config->num_cpu = value;
544
 
            } else if(!StringICmp(word, "NiceValue") && 
545
 
                    (value = atoi(line)) != 0) {
546
 
                config->niceval = value;
547
 
            } else if(!StringICmp(word, program)) {
548
 
                for(i = 0 ; line[0] != NULLB && i < MAX_DB_NUM; i++) {
549
 
                    BLASTConfigGetWord(word, line);
550
 
                    config->allow_db[i] = StringSave(word);
551
 
                }
552
 
            }
553
 
        }
554
 
    }
555
 
 
556
 
    FileClose(fd);
557
 
    return config;
558
 
}
559
 
 
560
 
static Boolean ValidateCombinationsEx(WWWBlastInfoPtr theInfo, 
561
 
                                      CharPtr database)
562
 
{
563
 
    Int4 i;
564
 
    
565
 
    for(i = 0; theInfo->blast_config->allow_db[i] != NULL; i++) {
566
 
        if(!StringICmp(database, theInfo->blast_config->allow_db[i]))
567
 
            return TRUE;
568
 
    }
569
 
    return FALSE;
570
 
}
571
 
 
572
 
/* This will work if search require to choose few databases */
573
 
static Boolean WWWParseDatabases(WWWBlastInfoPtr theInfo)
574
 
{
575
 
    Int4  count, index;
576
 
    Boolean done, datalib_found;
577
 
    Char buffer[4096], buffer1[4096]; /* is 4096 always long enough? XXX */
578
 
    CharPtr ptr, chptr;
579
 
 
580
 
    count = WWWGetNumEntries(theInfo->info);
581
 
    datalib_found = FALSE;
582
 
    ptr = buffer;
583
 
    
584
 
    for (index=0; index<count; index++) {
585
 
        chptr = WWWGetNameByIndex(theInfo->info, index);
586
 
        if (StringCmp(chptr, "DATALIB") == 0) {
587
 
            datalib_found = TRUE;
588
 
            chptr = WWWGetValueByIndex(theInfo->info, index);
589
 
            done = FALSE;
590
 
            
591
 
            /* Parse string if multiple database names. */
592
 
            while (done == FALSE) { 
593
 
                done = readdb_parse_db_names(&chptr, buffer1);
594
 
                if (ValidateCombinationsEx(theInfo, buffer1) == TRUE) {
595
 
                    
596
 
                    CharPtr prefix = WWWGetValueByName(theInfo->info, "DB_DIR_PREFIX");
597
 
                    Char tmpbuf[1024];
598
 
                    
599
 
                    if (prefix) {
600
 
                        sprintf(tmpbuf, "%s%c%s", prefix, DIRDELIMCHR, buffer1);
601
 
                    } else {
602
 
                        sprintf(tmpbuf, "%s", buffer1);
603
 
                    }
604
 
                    
605
 
                    StringCpy(ptr, tmpbuf);
606
 
                    ptr += StringLen(tmpbuf);
607
 
                    *ptr = ' '; ptr++;
608
 
                } else {
609
 
                    WWWBlastErrMessage(BLASTErrCombination, NULL);
610
 
                    return FALSE;
611
 
                }
612
 
            }
613
 
        }
614
 
    }
615
 
    
616
 
    if (datalib_found) {
617
 
        ptr--;
618
 
        *ptr = NULLB;
619
 
        theInfo->database = StringSave(buffer);
620
 
    } else {
621
 
        WWWBlastErrMessage(BLASTErrDatalib, NULL);
622
 
        return FALSE;
623
 
    }
624
 
    
625
 
    /* Processing database aliases  */
626
 
    
627
 
    if(StringStr(theInfo->database, "E.coli") != NULL) {
628
 
        MemFree(theInfo->database);
629
 
        theInfo->database = StringSave("ecoli");
630
 
    }
631
 
 
632
 
    return TRUE;
633
 
}
634
 
#if defined(NCBI_CLIENT_SERVER) || defined (NCBI_ENTREZ_CLIENT)
635
 
 
636
 
static Int4 AccessionToGi (CharPtr string) 
637
 
{
638
 
    Char buffer[32];
639
 
    CharPtr chptr;
640
 
    Int2 version;
641
 
    Int4 gi, index;
642
 
    SeqIdPtr sip;
643
 
    TextSeqIdPtr tsip;
644
 
    PDBSeqIdPtr  psip;
645
 
    long tmplong;
646
 
    Boolean digit;
647
 
 
648
 
    for(chptr = string, digit = TRUE; *chptr != NULLB; chptr++) {
649
 
        if(!IS_DIGIT(*chptr)) {
650
 
            digit = FALSE;
651
 
            break;
652
 
        }
653
 
    }
654
 
        
655
 
    if(digit) {
656
 
        if((gi = atol(string)) > 0)
657
 
            return gi;
658
 
    }
659
 
 
660
 
    /* all letters in accesion should be upper */
661
 
    string = Nlm_StringUpper(string);
662
 
    
663
 
    gi = 0;
664
 
 
665
 
    if((sip = ValNodeNew (NULL)) == NULL)
666
 
        return -1;
667
 
    
668
 
    index = 0; version = 0;
669
 
    while (*string != '\0' && index < 16) {
670
 
        if (*string == '.')
671
 
            break;
672
 
        buffer[index] = *string;
673
 
        string++;
674
 
        index++;
675
 
    }
676
 
 
677
 
    buffer[index] = '\0';
678
 
    if (*string == '.' && *(string+1) != '\0') {
679
 
        sscanf((string+1), "%ld", &tmplong);
680
 
        version = (Int2) tmplong;
681
 
    }
682
 
    
683
 
    if((tsip = TextSeqIdNew ()) == NULL)
684
 
        return -1;
685
 
    
686
 
    tsip->accession = StringSave(buffer);
687
 
    tsip->version = version;
688
 
    
689
 
    /* GenBank, EMBL, and DDBJ. */
690
 
    sip->choice = SEQID_GENBANK;
691
 
    sip->data.ptrvalue = (Pointer) tsip;
692
 
    gi = ID1FindSeqId (sip);
693
 
    
694
 
    if (gi == 0) {
695
 
        /* SwissProt. */
696
 
        sip->choice = SEQID_SWISSPROT;
697
 
        gi = ID1FindSeqId (sip);
698
 
    } else {
699
 
        goto retpoint;
700
 
    }
701
 
 
702
 
    if (gi == 0) {
703
 
        /* PIR */
704
 
        sip->choice = SEQID_PIR;
705
 
        gi = ID1FindSeqId (sip);
706
 
    } else {
707
 
        goto retpoint;
708
 
    }
709
 
 
710
 
    if (gi == 0) {
711
 
        /* PRF */
712
 
        sip->choice = SEQID_PRF;
713
 
        gi = ID1FindSeqId (sip);
714
 
    } else {
715
 
        goto retpoint;
716
 
    }
717
 
 
718
 
    if (gi == 0) {
719
 
        /* OTHER, probably 'ref' */
720
 
        sip->choice = SEQID_OTHER;
721
 
        gi = ID1FindSeqId (sip);
722
 
    }
723
 
 
724
 
    if(gi != 0)
725
 
        goto retpoint;
726
 
 
727
 
    /* OK. We failed to find gi using string as TextSeqId. Now trying
728
 
       last time - with PDBSeqIdPtr */
729
 
 
730
 
    if((psip = PDBSeqIdNew()) == NULL)
731
 
        return -1;
732
 
    
733
 
    sip->choice = SEQID_PDB;
734
 
    sip->data.ptrvalue = psip;
735
 
    
736
 
    psip->mol = StringSave(buffer);
737
 
    psip->chain = version;
738
 
 
739
 
    gi = ID1FindSeqId (sip);
740
 
 
741
 
    SeqIdFree(sip);
742
 
 
743
 
 retpoint:
744
 
    TextSeqIdFree(tsip);
745
 
    return gi;
746
 
}
747
 
#endif
748
 
 
749
 
#define MAX_NUM_QUERIES 16383 /* == 1/2 INT2_MAX */
750
 
Boolean WWWCreateSearchOptions(WWWBlastInfoPtr theInfo)
751
 
{
752
 
    CharPtr chptr, ptr, sequence, outptr;
753
 
    SeqEntryPtr sep;
754
 
    Boolean gapped_set;
755
 
    CharPtr opt_str = "GErqeWvbKLY";
756
 
    BLAST_OptionsBlkPtr options;
757
 
    Char tmp[128];
758
 
    Int4 i, value;
759
 
    Boolean is_megablast = FALSE, mask_lower_case = FALSE;
760
 
    SeqLocPtr query_slp = NULL, query_lcase_mask = NULL;
761
 
    
762
 
    /* PROGRAM */
763
 
    
764
 
    if((chptr = WWWGetValueByName(theInfo->info, "PROGRAM")) != NULL) {
765
 
        theInfo->program = StringSave(chptr);
766
 
    } else {
767
 
        theInfo->program = StringSave("blastn");
768
 
        /*WWWBlastErrMessage(BLASTErrProgram, NULL);
769
 
          return FALSE;*/
770
 
    }
771
 
 
772
 
    /* Is it MEGABLAST? */
773
 
 
774
 
    if (WWWGetValueByName(theInfo->info, "MEGABLAST") != NULL)
775
 
       is_megablast = TRUE;
776
 
 
777
 
    /* Configuration file set program/database relations */
778
 
 
779
 
    if((theInfo->blast_config = 
780
 
        BLASTReadConfigFile(theInfo->ConfigFile, theInfo->program)) == NULL) {
781
 
        WWWBlastErrMessage(BLASTConfigFile, NULL);
782
 
        return FALSE;
783
 
    }
784
 
 
785
 
    /* DATALIB */
786
 
    if(!WWWParseDatabases(theInfo))
787
 
        return FALSE;
788
 
    
789
 
    /* SEQUENCE or SEQFILE */
790
 
    
791
 
    if((sequence = WWWGetValueByName(theInfo->info, "SEQUENCE")) == NULL ||
792
 
       sequence[0] == NULLB) {
793
 
        if((sequence = WWWGetValueByName(theInfo->info, "SEQFILE")) == NULL ||
794
 
           sequence[0] == NULLB) {
795
 
            WWWBlastErrMessage(BLASTErrNoSequence, NULL);
796
 
            return FALSE;
797
 
        }
798
 
    }
799
 
    
800
 
    theInfo->align_type = BlastGetTypes(theInfo->program, &theInfo->query_is_na, &theInfo->db_is_na);
801
 
#if defined(NCBI_CLIENT_SERVER) || defined (NCBI_ENTREZ_CLIENT)
802
 
    
803
 
    if((chptr = WWWGetValueByName(theInfo->info, "INPUT_TYPE")) != NULL && 
804
 
       !StringNICmp(chptr, "Accession", 9)) {
805
 
 
806
 
        Int4 i, gi, number, title_length, id_length, query_num = 0;
807
 
        CharPtr accession, new_defline;
808
 
        BioseqPtr bsp_tmp, query_bsp;
809
 
        SeqIdPtr sip;
810
 
        ObjectIdPtr  oid;
811
 
        SeqPortPtr spp;
812
 
        Int2 retval, buf_length=512;
813
 
        Uint1 buf[512];
814
 
        Char tmp[255];
815
 
        Boolean first_query = TRUE;
816
 
        Char delimiters[7];
817
 
 
818
 
        /* This is request by Accession/GI - asking ID */
819
 
        
820
 
        if (!ID1BioseqFetchEnable("web-blasts", TRUE)) {
821
 
            WWWBlastErrMessage(BLASTEntrez, NULL);
822
 
            return FALSE;
823
 
        }
824
 
        
825
 
        chptr = sequence;
826
 
        theInfo->query_slp = NULL;
827
 
        StrCpy(delimiters, " \t\n,;\r");
828
 
 
829
 
        while (outptr = StringTokMT(chptr, delimiters, &chptr)) {
830
 
 
831
 
           accession = outptr;
832
 
 
833
 
           /* Strip off non-alphanumerics, except for '_' (used in SP) and '.' (soon to be used by  the collaboration. */
834
 
           while (IS_ALPHANUM(*outptr) || *outptr == '_' || *outptr == '.')
835
 
              outptr++;
836
 
           *outptr = NULLB; 
837
 
           
838
 
           sip = NULL;
839
 
           gi = AccessionToGi(accession);
840
 
           
841
 
           if (gi > 0) {
842
 
              ValNodeAddInt(&sip, SEQID_GI, gi);
843
 
           } else {
844
 
              WWWBlastErrMessageEx(BLASTEntrez, NULL, accession);
845
 
              if (!theInfo->query_slp && !chptr) 
846
 
                 return FALSE;
847
 
              else continue;
848
 
           }    
849
 
           
850
 
           /* If id is not found - it is not found - ID1 is down? */
851
 
           
852
 
           if((bsp_tmp = BioseqLockById(sip)) == NULL) {
853
 
              WWWBlastErrMessageEx(BLASTEntrez, NULL, accession);
854
 
              if (!theInfo->query_slp && !chptr) 
855
 
                 return FALSE;
856
 
              else continue;
857
 
           }
858
 
           
859
 
           if (ISA_na(bsp_tmp->mol) != theInfo->query_is_na) {
860
 
              WWWBlastErrMessageEx(BLASTErrAccType, NULL, accession);
861
 
              if (!theInfo->query_slp && !chptr) 
862
 
                 return FALSE;
863
 
              else continue;
864
 
           }
865
 
           
866
 
           query_bsp = BioseqNew();
867
 
           query_bsp->length = bsp_tmp->length;
868
 
           query_bsp->mol = bsp_tmp->mol;
869
 
           query_bsp->repr = Seq_repr_raw;
870
 
           query_bsp->seq_data = BSNew(query_bsp->length);
871
 
           
872
 
           if (ISA_na(query_bsp->mol)) {
873
 
              spp = SeqPortNew(bsp_tmp, 0, -1, Seq_strand_plus, 
874
 
                               Seq_code_iupacna);
875
 
              query_bsp->seq_data_type = Seq_code_iupacna;
876
 
           } else {
877
 
              spp = SeqPortNew(bsp_tmp, 0, -1, Seq_strand_unknown, 
878
 
                               Seq_code_ncbieaa);
879
 
              query_bsp->seq_data_type = Seq_code_ncbieaa;
880
 
           }
881
 
           
882
 
           SeqPortSet_do_virtual(spp, TRUE);
883
 
           number = 0;
884
 
           while (number < query_bsp->length) {
885
 
              retval = SeqPortRead(spp, buf, buf_length);
886
 
              if (retval <= 0)
887
 
                 break;
888
 
              BSWrite(query_bsp->seq_data, buf, retval);
889
 
              number += retval;
890
 
           }
891
 
           
892
 
           SeqPortFree(spp);
893
 
           
894
 
           title_length = StringLen(BioseqGetTitle(bsp_tmp));
895
 
           SeqIdWrite(bsp_tmp->id, tmp, PRINTID_FASTA_LONG, 255);
896
 
           id_length = StringLen(tmp);
897
 
           title_length += id_length;
898
 
           title_length +=3;
899
 
           new_defline = (CharPtr) MemNew(title_length*sizeof(Char));
900
 
           StringCpy(new_defline, tmp);
901
 
           *(new_defline+id_length) = ' ';
902
 
           StringCpy(new_defline+id_length+1, BioseqGetTitle(bsp_tmp)); 
903
 
           *(new_defline+title_length-1) = NULLB;
904
 
           query_bsp->descr = ValNodeAddStr(NULL, Seq_descr_title, 
905
 
                                            new_defline);
906
 
           query_bsp->id = ValNodeNew(NULL);
907
 
           oid = ObjectIdNew();
908
 
           query_num++;
909
 
           oid->str = (CharPtr) Malloc(6);
910
 
           sprintf(oid->str, "%d", query_num);
911
 
           query_bsp->id->choice = SEQID_LOCAL;
912
 
           query_bsp->id->data.ptrvalue = (Pointer) oid;
913
 
        
914
 
           SeqMgrDeleteFromBioseqIndex(bsp_tmp);
915
 
           
916
 
           BioseqUnlock(bsp_tmp);
917
 
           
918
 
           BioseqPack(query_bsp);
919
 
           if (first_query) {
920
 
              theInfo->query_bsp = query_bsp;
921
 
              first_query = FALSE;
922
 
           }
923
 
        
924
 
           ValNodeAddPointer(&theInfo->query_slp, SEQLOC_WHOLE,
925
 
                             SeqIdSetDup(SeqIdFindBest(query_bsp->id,
926
 
                                                       SEQID_GI)));
927
 
        }        
928
 
        
929
 
        ID1BioseqFetchDisable();
930
 
    }
931
 
#endif
932
 
    
933
 
    /* LCASE_MASK */
934
 
    if (WWWGetValueByName(theInfo->info, "LCASE_MASK") != NULL)
935
 
       mask_lower_case = TRUE;
936
 
 
937
 
 
938
 
    /* Creating Bioseq */
939
 
        
940
 
    if (theInfo->query_bsp == NULL) {
941
 
          Int4 num_queries;
942
 
          BioseqPtr query_bsp = NULL;
943
 
          SeqLocPtr last_mask, mask_slp;
944
 
          Int2 ctr = 1;
945
 
          Char prefix[2];
946
 
          
947
 
          outptr = NULL;
948
 
          StrCpy(prefix, "");
949
 
          SeqMgrHoldIndexing(TRUE);
950
 
          mask_slp = last_mask = NULL;
951
 
          num_queries = 0;
952
 
          while ((sep=FastaToSeqBuffForDb(sequence, &outptr,
953
 
                                          theInfo->query_is_na, NULL,
954
 
                                          theInfo->believe_query, 
955
 
                                          prefix, &ctr, &mask_slp)) != NULL) {
956
 
             sequence = outptr;
957
 
             if (mask_slp) {
958
 
                if (!mask_lower_case)
959
 
                   SeqLocFree(mask_slp);
960
 
                else if (!last_mask)
961
 
                   query_lcase_mask = last_mask = mask_slp;
962
 
                else {
963
 
                   last_mask->next = mask_slp;
964
 
                   last_mask = last_mask->next;
965
 
                }
966
 
                mask_slp = NULL;
967
 
             }
968
 
             query_bsp = NULL;
969
 
             if (theInfo->query_is_na) 
970
 
                SeqEntryExplore(sep, &query_bsp, FindNuc);
971
 
             else
972
 
                SeqEntryExplore(sep, &query_bsp, FindProt);
973
 
             
974
 
             if (query_bsp == NULL) {
975
 
                ErrPostEx(SEV_FATAL, 0, 0, "Unable to obtain bioseq\n");
976
 
                return 2;
977
 
             }
978
 
             num_queries++;
979
 
             if (num_queries > MAX_NUM_QUERIES) {
980
 
                WWWBlastErrMessage(BLASTOptionStr, 
981
 
                                   "Maximal number of queries exceeded. At most 16383 are allowed");
982
 
                break;
983
 
             }
984
 
             if (!theInfo->query_slp) /* I.e. if first query */
985
 
                theInfo->query_bsp = query_bsp;
986
 
 
987
 
             ValNodeAddPointer(&theInfo->query_slp, SEQLOC_WHOLE,
988
 
                               SeqIdSetDup(SeqIdFindBest(query_bsp->id,
989
 
                                                         SEQID_GI)));
990
 
          }
991
 
          SeqMgrHoldIndexing(FALSE);
992
 
       } else if (is_megablast) 
993
 
          ValNodeAddPointer(&theInfo->query_slp, SEQLOC_WHOLE,
994
 
                            SeqIdSetDup(SeqIdFindBest(theInfo->query_bsp->id,
995
 
                                                      SEQID_GI)));
996
 
       
997
 
    /* The last check of Bioseq - if length of sequence too small ? */
998
 
    
999
 
    if(theInfo->query_bsp == NULL || 
1000
 
       theInfo->query_bsp->length <= 0) {
1001
 
        WWWBlastErrMessage(BLASTFastaToSE, NULL);
1002
 
        return FALSE;
1003
 
    }
1004
 
    
1005
 
    /* This will prevent from incorrect formating in case when input
1006
 
       sequence has valid SeqId, but in fact this SeqId do not correspond
1007
 
       to the real sequence  - XXX */
1008
 
 
1009
 
    if(!theInfo->believe_query)
1010
 
        theInfo->fake_bsp = BlastMakeFakeBioseq(theInfo->query_bsp, NULL);
1011
 
    else
1012
 
        theInfo->fake_bsp = theInfo->query_bsp;
1013
 
    
1014
 
    /* OVERVIEW */
1015
 
    
1016
 
    if (WWWGetValueByName(theInfo->info, "OVERVIEW") != NULL)
1017
 
        theInfo->show_overview = TRUE;
1018
 
 
1019
 
    /* UNGAPPED_ALIGNMENT */
1020
 
    gapped_set = TRUE;
1021
 
    if(WWWGetValueByName(theInfo->info, "UNGAPPED_ALIGNMENT") != NULL)
1022
 
        gapped_set = FALSE;
1023
 
 
1024
 
    if((options = BLASTOptionNew(theInfo->program, gapped_set)) == NULL) {
1025
 
        WWWBlastErrMessage(BLASTErrOptions, NULL);
1026
 
        return FALSE; 
1027
 
    }
1028
 
    
1029
 
    if (is_megablast) {
1030
 
       options->is_megablast_search = TRUE;
1031
 
       options->query_lcase_mask = query_lcase_mask;
1032
 
       /* WORD SIZE */
1033
 
       options->wordsize = 28;
1034
 
       if((chptr = WWWGetValueByName(theInfo->info, "WORD_SIZE")) != NULL &&
1035
 
          StringStr(chptr, "default") == NULL) {
1036
 
          options->wordsize = atoi(chptr);
1037
 
       }
1038
 
       options->gap_open = 0;
1039
 
       options->gap_extend = 0;
1040
 
       options->block_width = 0;
1041
 
       /* Mega BLAST with no traceback (endpoints only)? */
1042
 
       if (WWWGetValueByName(theInfo->info, "ENDPOINTS") != NULL)
1043
 
          options->no_traceback = TRUE;
1044
 
       if ((chptr = WWWGetValueByName(theInfo->info, "PERC_IDENT")) != NULL && 
1045
 
           StringStr(chptr, "default") == NULL)
1046
 
          options->perc_identity = (FloatLo) atof(chptr);
1047
 
    }
1048
 
 
1049
 
    theInfo->options = options;
1050
 
 
1051
 
    /* Set default values for matrix and gap parameters */
1052
 
    BLASTOptionSetGapParams (options, NULL, 0, 0);
1053
 
    
1054
 
    /* Read MAT_PARAM if set */
1055
 
    
1056
 
    if(StringICmp("blastn", theInfo->program) && 
1057
 
       (chptr = WWWGetValueByName(theInfo->info, "MAT_PARAM")) != NULL) {
1058
 
        Char    matrixname[64];
1059
 
        Int4    opencost, extendedcost;
1060
 
        /* Get matrix name and gap costs */
1061
 
        if (chptr[1] != '-' || chptr[2] != '-') {
1062
 
            sscanf(chptr, "%s\t %d\t %d", matrixname, &opencost, 
1063
 
                   &extendedcost);
1064
 
            /* set the parameters */
1065
 
            options->gap_open  = opencost;
1066
 
            options->gap_extend  = extendedcost;
1067
 
            if (options->matrix)
1068
 
                MemFree(options->matrix);
1069
 
            options->matrix = StringSave(matrixname);
1070
 
        }
1071
 
    } 
1072
 
 
1073
 
    if((chptr = WWWGetValueByName(theInfo->info, "GAP_OPEN")) != NULL &&
1074
 
            StringStr(chptr, "default") == NULL) {
1075
 
        options->gap_open = atoi(chptr);
1076
 
    }
1077
 
 
1078
 
    if((chptr = WWWGetValueByName(theInfo->info, "GAP_EXTEND")) != NULL &&
1079
 
            StringStr(chptr, "default") == NULL) {
1080
 
        options->gap_extend = atoi(chptr);
1081
 
    }
1082
 
 
1083
 
    if((chptr = WWWGetValueByName(theInfo->info, "GAP_VALUES")) != NULL &&
1084
 
            StringStr(chptr, "default") == NULL) {
1085
 
        sscanf(chptr, "%d,%d", &options->gap_open, &options->gap_extend);
1086
 
    }
1087
 
 
1088
 
    if((chptr = WWWGetValueByName(theInfo->info, "X_DROPOFF")) != NULL &&
1089
 
            StringStr(chptr, "default") == NULL) {
1090
 
        options->gap_x_dropoff = atoi(chptr);
1091
 
    }
1092
 
 
1093
 
    if (!StringICmp(theInfo->program, "blastn")) {
1094
 
       if (options->perc_identity > 98.0 || options->perc_identity <= 0) {
1095
 
          options->reward = 1;
1096
 
          options->penalty = -3;
1097
 
       } else if (options->perc_identity > 95.0) {
1098
 
          options->reward = 2;
1099
 
          options->penalty = -5;
1100
 
       } else if (options->perc_identity > 90.0) {
1101
 
          options->reward = 1;
1102
 
          options->penalty = -2;
1103
 
       } else if (options->perc_identity > 85.0) {
1104
 
          options->reward = 2;
1105
 
          options->penalty = -3;
1106
 
       } else if (options->perc_identity > 80.0) {
1107
 
          options->reward = 3;
1108
 
          options->penalty = -4;
1109
 
       } else if (options->perc_identity > 75.0) {
1110
 
          options->reward = 5;
1111
 
          options->penalty = -6;
1112
 
       } else {
1113
 
          options->reward = 1;
1114
 
          options->penalty = -1;
1115
 
       } 
1116
 
    }
1117
 
 
1118
 
    if((chptr = WWWGetValueByName(theInfo->info, "GAP_SIZE")) != NULL &&
1119
 
            StringStr(chptr, "default") == NULL) {
1120
 
        options->gap_size = atoi(chptr);
1121
 
    }
1122
 
 
1123
 
    if((chptr = WWWGetValueByName(theInfo->info, 
1124
 
            "WINDOW_SIZE")) != NULL &&
1125
 
            StringStr(chptr, "default") == NULL) {
1126
 
        options->window_size = atoi(chptr);
1127
 
    }
1128
 
 
1129
 
    /* For BLASTX we could set genetic code */
1130
 
 
1131
 
    if (!StringICmp(theInfo->program, "blastx")) {
1132
 
        BioSourcePtr source;
1133
 
        
1134
 
        options->genetic_code = 1;
1135
 
 
1136
 
        if((chptr = WWWGetValueByName(theInfo->info, 
1137
 
                "GENETIC_CODE")) != NULL &&
1138
 
                (StringStr(chptr, "default") == NULL)) {
1139
 
            chptr = StringChr(chptr, '(');
1140
 
            sscanf(chptr, "(%d", &value);
1141
 
            if(value != 0) {
1142
 
                options->genetic_code = value; 
1143
 
 
1144
 
                source = BioSourceNew();
1145
 
                source->org = OrgRefNew();
1146
 
                source->org->orgname = OrgNameNew();
1147
 
                source->org->orgname->gcode = options->genetic_code;
1148
 
                ValNodeAddPointer(&theInfo->query_bsp->descr, 
1149
 
                        Seq_descr_source, source);
1150
 
            }
1151
 
        }
1152
 
    }
1153
 
 
1154
 
    /* For BLASTX we could set genetic code */
1155
 
 
1156
 
    if (!StringICmp(theInfo->program, "blastx")) {
1157
 
        if((chptr = WWWGetValueByName(theInfo->info, "OOF_ALIGN")) != NULL) {
1158
 
            options->is_ooframe = TRUE;
1159
 
            options->shift_pen = atoi(chptr);
1160
 
 
1161
 
            if(options->shift_pen == 0) {
1162
 
                options->is_ooframe = FALSE;
1163
 
            }
1164
 
        }
1165
 
    }
1166
 
 
1167
 
    /* For TBLASTN and TBLASTX we could set DB_GENETIC_CODE */
1168
 
 
1169
 
    if (!StringICmp(theInfo->program, "tblastn") || 
1170
 
        !(StringICmp(theInfo->program, "tblastx"))) {
1171
 
        options->db_genetic_code = 1;
1172
 
        if((chptr = WWWGetValueByName(theInfo->info, 
1173
 
                                      "DB_GENETIC_CODE")) != NULL &&
1174
 
           (StringStr(chptr, "default") == NULL)) {
1175
 
            chptr = StringChr(chptr, '(');
1176
 
            sscanf(chptr, "(%d", &value);
1177
 
            if(value != 0) {
1178
 
                options->genetic_code = value; 
1179
 
            }      
1180
 
        }
1181
 
    }
1182
 
 
1183
 
    if((chptr = WWWGetValueByName(theInfo->info, 
1184
 
            "THRESHOLD_2")) != NULL &&
1185
 
            (StringStr(chptr, "default") == NULL)) {
1186
 
        options->threshold_second = atoi(chptr);
1187
 
    }
1188
 
 
1189
 
    if((chptr = WWWGetValueByName(theInfo->info, 
1190
 
            "REQUIRED_START")) != NULL &&
1191
 
            StringStr(chptr, "default") != NULL) {
1192
 
        options->required_start = atoi(chptr);
1193
 
    }
1194
 
 
1195
 
    if((chptr = WWWGetValueByName(theInfo->info, 
1196
 
            "REQUIRED_END")) != NULL &&
1197
 
            StringStr(chptr, "default") != NULL) {
1198
 
        options->required_end = atoi(chptr);
1199
 
    }
1200
 
 
1201
 
    if((chptr = WWWGetValueByName(theInfo->info, 
1202
 
            "DROPOFF_1")) != NULL &&
1203
 
            (StringStr(chptr, "default") == NULL)) {
1204
 
        options->dropoff_1st_pass = atof(chptr);
1205
 
    }
1206
 
 
1207
 
    if((chptr = WWWGetValueByName(theInfo->info, 
1208
 
            "CUTOFF")) != NULL &&
1209
 
            (StringStr(chptr, "default") == NULL)) {
1210
 
        options->cutoff_s = atof(chptr);
1211
 
    }
1212
 
 
1213
 
 
1214
 
    if((chptr = WWWGetValueByName(theInfo->info, 
1215
 
            "DROPOFF_2")) != NULL &&
1216
 
            (StringStr(chptr, "default") == NULL)) {
1217
 
        options->dropoff_2nd_pass = atof(chptr);
1218
 
    }
1219
 
 
1220
 
    /* MATRIX: */
1221
 
 
1222
 
    if((chptr = WWWGetValueByName(theInfo->info, 
1223
 
            "MATRIX")) != NULL &&
1224
 
            (StringStr(chptr, "default") == NULL)) {
1225
 
        options->matrix = StringSave(chptr);
1226
 
    }
1227
 
 
1228
 
    /* EXPECT */
1229
 
 
1230
 
    options->expect_value  = DEFAULT_EXPECT;
1231
 
 
1232
 
    if((chptr = WWWGetValueByName(theInfo->info, 
1233
 
            "EXPECT")) != NULL &&
1234
 
            StringStr(chptr, "default") == NULL) {
1235
 
        options->expect_value = atof(chptr);
1236
 
    }
1237
 
 
1238
 
    /* NUMBER OF BITS: */
1239
 
 
1240
 
    if((chptr = WWWGetValueByName(theInfo->info, 
1241
 
            "NUM_OF_BITS")) != NULL &&
1242
 
            (StringStr(chptr, "default") == NULL)) {
1243
 
        options->number_of_bits = atof(chptr);
1244
 
    }
1245
 
 
1246
 
    /* Parameters for Smith-Waterman BLAST */
1247
 
 
1248
 
    /* TWEAK_PARAMETERS */
1249
 
    
1250
 
    if (WWWGetValueByName(theInfo->info, "TWEAK_PARAMETERS") != NULL)
1251
 
        theInfo->options->tweak_parameters = TRUE;
1252
 
 
1253
 
    /* Adjustment of expect value and hitlist size */
1254
 
    if (theInfo->options->tweak_parameters) {
1255
 
        theInfo->options->hitlist_size *= 2; /*allows for extra matches*/
1256
 
        theInfo->options->original_expect_value = 
1257
 
            theInfo->options->expect_value;
1258
 
        if (theInfo->options->expect_value < 0.1) {
1259
 
            theInfo->options->expect_value = 
1260
 
                MIN(0.1, 10 * theInfo->options->expect_value);
1261
 
        }
1262
 
    }
1263
 
    
1264
 
    /* SMITH_WATERMAN */
1265
 
    
1266
 
    if (WWWGetValueByName(theInfo->info, "SMITH_WATERMAN") != NULL)
1267
 
        theInfo->options->smith_waterman = TRUE;
1268
 
 
1269
 
    /* RPSBLAST */
1270
 
 
1271
 
    if (WWWGetValueByName(theInfo->info, "RPSBLAST") != NULL)
1272
 
        theInfo->options->is_rps_blast = TRUE;
1273
 
 
1274
 
    /* ENTREZ_QUERY */
1275
 
    
1276
 
    if ((chptr = WWWGetValueByName(theInfo->info, "ENTREZ_QUERY")) != NULL) {
1277
 
        theInfo->options->entrez_query = StringSave(chptr);
1278
 
    
1279
 
#if defined(NCBI_CLIENT_SERVER) || defined (NCBI_ENTREZ_CLIENT)
1280
 
        {{
1281
 
            Int4Ptr uids;
1282
 
 
1283
 
            theInfo->gi_list_total = 
1284
 
                BLASTGetUidsFromQuery(chptr, &uids, theInfo->db_is_na, FALSE);
1285
 
 
1286
 
            if(theInfo->gi_list_total > 0) {
1287
 
 
1288
 
                theInfo->gi_list = MemNew(theInfo->gi_list_total*sizeof(BlastDoubleInt4));
1289
 
                for(i = 0; i < theInfo->gi_list_total; i++)
1290
 
                    theInfo->gi_list[i].gi = uids[i];
1291
 
            }
1292
 
        }}
1293
 
#endif
1294
 
    }
1295
 
    /* ----------------------------------- */
1296
 
 
1297
 
    /* Number of CPU to use in BLAST Search: */
1298
 
 
1299
 
    if(theInfo->blast_config->num_cpu != 0)
1300
 
        options->number_of_cpus = theInfo->blast_config->num_cpu;
1301
 
    else
1302
 
        options->number_of_cpus = NUM_CPU_TO_USE;
1303
 
 
1304
 
    /* CPU time limit. */
1305
 
    
1306
 
    options->cpu_limit = DEFAULT_CPU_LIMIT;
1307
 
 
1308
 
    /* FILTER: */
1309
 
 
1310
 
 
1311
 
    options->filter = FILTER_NONE;
1312
 
 
1313
 
    if(WWWGetMethod(theInfo->info) == WWW_GET ||
1314
 
            (chptr = WWWGetValueByName(theInfo->info, "FSET")) != NULL) {
1315
 
        if (!StringICmp(theInfo->program, "blastn")) {
1316
 
            options->filter = FILTER_DUST;
1317
 
        } else {
1318
 
            options->filter = FILTER_SEG;
1319
 
        }
1320
 
    }
1321
 
    
1322
 
    {
1323
 
        Char    tmpbuf[4096];
1324
 
        /* Filter settings */
1325
 
        int     i, num_entries = WWWGetNumEntries(theInfo->info);
1326
 
        
1327
 
        StringCpy(tmpbuf, "");
1328
 
 
1329
 
        for(i = 0; i < num_entries; i++) {
1330
 
            if((chptr = WWWGetNameByIndex(theInfo->info, i)) != NULL && 
1331
 
                    !StringICmp(chptr, "FILTER")) {
1332
 
 
1333
 
                chptr = WWWGetValueByIndex(theInfo->info, i);
1334
 
                /* add the filter */
1335
 
                StringCat(tmpbuf, chptr);
1336
 
                StringCat(tmpbuf, ";");
1337
 
            }
1338
 
        }
1339
 
        options->filter_string = StringSave(tmpbuf);
1340
 
    }
1341
 
 
1342
 
    /* DESCRIPTIONS: */
1343
 
 
1344
 
    theInfo->number_of_descriptions = DEFAULT_DESCRIPTIONS;
1345
 
 
1346
 
    if((chptr = WWWGetValueByName(theInfo->info, 
1347
 
                                  "DESCRIPTIONS")) != NULL && 
1348
 
       StringStr(chptr, "default") == NULL) {
1349
 
        theInfo->number_of_descriptions = atoi(chptr);
1350
 
    }
1351
 
    
1352
 
    /* ALIGNMENTS */
1353
 
    theInfo->number_of_alignments = DEFAULT_ALIGNMENTS;
1354
 
 
1355
 
    if((chptr = WWWGetValueByName(theInfo->info, "ALIGNMENTS")) != NULL &&
1356
 
       StringStr(chptr, "default") == NULL) {
1357
 
        theInfo->number_of_alignments = atoi(chptr);  
1358
 
    }
1359
 
    
1360
 
    /* Now processing OTHER_ADVANCED_OPTIONS */
1361
 
    
1362
 
    if((chptr = WWWGetValueByName(theInfo->info, 
1363
 
                                  "OTHER_ADVANCED")) != NULL) {
1364
 
        Int4 index;
1365
 
        CharPtr ErrorMessage = NULL;
1366
 
        CharPtr PNTR values = NULL;
1367
 
 
1368
 
        if(!ParseInputString(chptr, opt_str, 
1369
 
                             &values, &ErrorMessage)) {
1370
 
            
1371
 
            WWWBlastErrMessage(BLASTOptionStr, ErrorMessage);
1372
 
            return FALSE;
1373
 
        }
1374
 
        
1375
 
        /* -G  gap open cost */
1376
 
        
1377
 
        index = GetLetterIndex(opt_str, 'G');
1378
 
        if(values[index] != NULL) {
1379
 
            options->gap_open = atoi(values[index]);
1380
 
        }
1381
 
        
1382
 
        /* -E gap extend cost */
1383
 
        
1384
 
        index = GetLetterIndex(opt_str, 'E');
1385
 
        if(values[index] != NULL) {
1386
 
            options->gap_extend = atoi(values[index]);
1387
 
        }
1388
 
        
1389
 
        /* -q penalty for nucleotide mismatch. */
1390
 
 
1391
 
        index = GetLetterIndex(opt_str, 'q');
1392
 
        if(values[index] != NULL) {
1393
 
            options->penalty = atoi(values[index]);
1394
 
        }
1395
 
 
1396
 
        /* -r reward for nucleotide match. */
1397
 
 
1398
 
        index = GetLetterIndex(opt_str, 'r');
1399
 
        if(values[index] != NULL) {
1400
 
            options->reward = atoi(values[index]);
1401
 
        }
1402
 
 
1403
 
        /* -e expect value. */
1404
 
 
1405
 
        index = GetLetterIndex(opt_str, 'e');
1406
 
        if(values[index] != NULL) {
1407
 
            options->expect_value = atof(values[index]);
1408
 
        }
1409
 
 
1410
 
        /* -W wordsize. */
1411
 
 
1412
 
        index = GetLetterIndex(opt_str, 'W');
1413
 
        if(values[index] != NULL) {
1414
 
            options->wordsize = atoi(values[index]);
1415
 
            if (is_megablast) {
1416
 
               if (options->wordsize < 8)
1417
 
                  options->wordsize = 8;
1418
 
               options->cutoff_s2 = options->wordsize*options->reward;
1419
 
               options->wordsize += 4;
1420
 
            }
1421
 
        }
1422
 
 
1423
 
        /* -v Number of descriptions to print. */
1424
 
 
1425
 
        index = GetLetterIndex(opt_str, 'v');
1426
 
        if(values[index] != NULL) {
1427
 
            theInfo->number_of_descriptions = atoi(values[index]);
1428
 
        }
1429
 
 
1430
 
        /* -b Number of alignments to show. */
1431
 
 
1432
 
        index = GetLetterIndex(opt_str, 'b');
1433
 
        if(values[index] != NULL) {
1434
 
            theInfo->number_of_alignments = atoi(values[index]);
1435
 
        }
1436
 
 
1437
 
        /* -K Number of best hits from a region to keep. */
1438
 
 
1439
 
        index = GetLetterIndex(opt_str, 'K');
1440
 
        if(values[index] != NULL) {
1441
 
            options->hsp_range_max = atoi(values[index]);
1442
 
            if (options->hsp_range_max != 0)
1443
 
                   options->perform_culling = TRUE;
1444
 
        }
1445
 
 
1446
 
        /* -L Number of best hits from a region to keep. */
1447
 
 
1448
 
        index = GetLetterIndex(opt_str, 'L');
1449
 
        if(values[index] != NULL) {
1450
 
            options->block_width = atoi(values[index]);
1451
 
        }
1452
 
 
1453
 
        /* -Y effective search space. */
1454
 
 
1455
 
        index = GetLetterIndex(opt_str, 'Y');
1456
 
        if(values[index] != NULL) {
1457
 
            options->searchsp_eff = atof(values[index]);
1458
 
        }
1459
 
        
1460
 
        MemFree(values);
1461
 
    }
1462
 
        /*
1463
 
          options->hsp_range_max = 100*options->hitlist_size;
1464
 
          options->block_width = theInfo->bsp->length;
1465
 
          */
1466
 
 
1467
 
    options->perform_culling = FALSE;
1468
 
 
1469
 
 
1470
 
    /* Some values for PSI-Blast */
1471
 
    value = 0;
1472
 
    if((chptr = WWWGetValueByName(theInfo->info, "STEP_NUMBER")) != NULL)
1473
 
        value = atoi(chptr);
1474
 
    
1475
 
    sprintf(tmp, "PSI_BEGIN%d", value-1);
1476
 
    
1477
 
    if((chptr = WWWGetValueByName(theInfo->info, tmp)) != NULL)
1478
 
        options->required_start = atoi(chptr) - 1;
1479
 
    
1480
 
    sprintf(tmp, "PSI_END%d", value-1);
1481
 
    if((chptr = WWWGetValueByName(theInfo->info, tmp)) != NULL)
1482
 
        options->required_end = atoi(chptr) - 1;    
1483
 
    
1484
 
    if((chptr = WWWGetValueByName(theInfo->info, "E_THRESH")) != NULL)
1485
 
        options->ethresh = atof(chptr);
1486
 
    
1487
 
    if((chptr = WWWGetValueByName(theInfo->info, "PHI_BLAST")) != NULL) {
1488
 
        theInfo->is_phi_blast = TRUE;
1489
 
        options->number_of_cpus = 1;
1490
 
    }
1491
 
    
1492
 
    /* ------------------------ */
1493
 
 
1494
 
    /* HITLIST_SIZE: */
1495
 
    
1496
 
    theInfo->options->hitlist_size = MAX(theInfo->number_of_descriptions, 
1497
 
                                         theInfo->number_of_alignments);
1498
 
    
1499
 
    /* ALIGNMENT VIEWS */
1500
 
    
1501
 
    if((chptr = WWWGetValueByName(theInfo->info, 
1502
 
                                  "ALIGNMENT_VIEW")) != NULL &&
1503
 
       StringStr(chptr, "default") == NULL) {
1504
 
        theInfo->align_view = atoi(chptr);
1505
 
        
1506
 
        if(theInfo->align_view == 12) {
1507
 
            theInfo->xml_output = TRUE;
1508
 
        }
1509
 
    }
1510
 
 
1511
 
    if (WWWGetValueByName(theInfo->info, "XML_OUTPUT") != NULL)
1512
 
        theInfo->xml_output = TRUE;
1513
 
 
1514
 
    if(options->is_ooframe) {
1515
 
        theInfo->xml_output = FALSE;
1516
 
        theInfo->align_view = 0;
1517
 
    }
1518
 
 
1519
 
    if (WWWGetValueByName(theInfo->info, "NCBI_GI") != NULL)
1520
 
        theInfo->show_gi = TRUE;
1521
 
    
1522
 
    if (WWWGetValueByName(theInfo->info, "OVERVIEW") != NULL)
1523
 
        theInfo->show_overview = TRUE;
1524
 
 
1525
 
    if (WWWGetValueByName(theInfo->info, "TAX_BLAST") != NULL)
1526
 
        theInfo->show_tax_blast = TRUE;
1527
 
    
1528
 
    /* COLOR_SCHEMA */
1529
 
    if((chptr = WWWGetValueByName(theInfo->info, "COLOR_SCHEMA")) != NULL &&
1530
 
       StringStr(chptr, "No color schema") == NULL) {
1531
 
        theInfo->color_schema = atoi(chptr);  
1532
 
    }
1533
 
    /* Now seting print and align options for BLAST output printing */
1534
 
 
1535
 
    theInfo->print_options = 0;
1536
 
    theInfo->align_options = 0;
1537
 
    theInfo->align_options += TXALIGN_COMPRESS;
1538
 
    theInfo->align_options += TXALIGN_END_NUM;
1539
 
 
1540
 
    if (StringICmp("blastx", theInfo->program) == 0) {
1541
 
        theInfo->align_options += TXALIGN_BLASTX_SPECIAL;
1542
 
    }
1543
 
 
1544
 
    if (theInfo->show_gi) {
1545
 
        theInfo->align_options += TXALIGN_SHOW_GI;
1546
 
        theInfo->print_options += TXALIGN_SHOW_GI;
1547
 
    }
1548
 
 
1549
 
    if (!gapped_set)
1550
 
        theInfo->print_options += TXALIGN_SHOW_NO_OF_SEGS;
1551
 
    
1552
 
    if (theInfo->align_view) {
1553
 
        theInfo->align_options += TXALIGN_MASTER;
1554
 
        if (theInfo->align_view == 1 || theInfo->align_view == 3)
1555
 
            theInfo->align_options += TXALIGN_MISMATCH;
1556
 
        if (theInfo->align_view == 3 || theInfo->align_view == 4 || 
1557
 
            theInfo->align_view == 6)
1558
 
            theInfo->align_options += TXALIGN_FLAT_INS;
1559
 
        if (theInfo->align_view == 5 || theInfo->align_view == 6)
1560
 
            theInfo->align_options += TXALIGN_BLUNT_END;
1561
 
    } else {
1562
 
        theInfo->align_options += TXALIGN_MATRIX_VAL;
1563
 
        theInfo->align_options += TXALIGN_SHOW_QS;
1564
 
    }
1565
 
    
1566
 
    /* Always HTML in WWW case */
1567
 
    
1568
 
    theInfo->align_options += TXALIGN_HTML;
1569
 
    theInfo->print_options += TXALIGN_HTML;
1570
 
    
1571
 
    return TRUE;
1572
 
}
1573
 
 
1574
 
Boolean WWWValidateOptions(WWWBlastInfoPtr theInfo)
1575
 
{
1576
 
    ValNodePtr error_return=NULL;
1577
 
    BlastErrorMsgPtr error_msg;
1578
 
    CharPtr msg = NULL;
1579
 
 
1580
 
    if(theInfo == NULL || theInfo->options == NULL)
1581
 
        return FALSE;
1582
 
    
1583
 
    if(BLASTOptionValidateEx(theInfo->options, theInfo->program, 
1584
 
                             &error_return) != 0) {
1585
 
        if (error_return) {
1586
 
            error_msg = (BlastErrorMsgPtr) error_return->data.ptrvalue;
1587
 
            msg = error_msg->msg;
1588
 
        }
1589
 
        WWWBlastErrMessage(BLASTErrOptions, msg);
1590
 
 
1591
 
        return FALSE;
1592
 
    }
1593
 
    return TRUE;
1594
 
}
1595
 
 
1596
 
/* Used for PSI/PHI Blast searches */
1597
 
 
1598
 
static Int1 S62ToInt(Uint1 ch)
1599
 
{
1600
 
    if(isupper(ch)) /* negative value */
1601
 
        return(64 - ch);
1602
 
    else if (isdigit(ch)) /* positive less than 10 */
1603
 
        return(ch - 48); 
1604
 
    else if (!isupper(ch)) /* positive more or eq  10 */
1605
 
        return(ch - 87);
1606
 
    return 0;
1607
 
}
1608
 
 
1609
 
static Uint1 IntTo62S(Int1 value)
1610
 
{
1611
 
    if(value < 0)
1612
 
        return(64-value);
1613
 
    else if (value < 10)
1614
 
        return(value + 48); 
1615
 
    else if (value < 36)
1616
 
        return(value + 87);
1617
 
    return 0;
1618
 
}
1619
 
 
1620
 
static Int4 BLASTCharTo4bits(Char ch)
1621
 
{
1622
 
    if(ch != '0')
1623
 
        ch = ch;
1624
 
    if ((ch >= 'A') && (ch <= 'F'))
1625
 
        return (((ch - 'A') + 10));
1626
 
    else if ((ch >= '0') && (ch <= '9'))
1627
 
        return ((ch - '0'));
1628
 
    else
1629
 
        return (Int4)(-1);
1630
 
}
1631
 
 
1632
 
static Char BLAST4bitsToChar(int value)
1633
 
{
1634
 
    if (value < 10)
1635
 
        return (Char)(value + '0');
1636
 
    else
1637
 
        return (Char)(value - 10 + 'A');
1638
 
}
1639
 
 
1640
 
static Nlm_FloatHi **BLASTDecodePosFreqs(CharPtr CHARPosFreqs,
1641
 
                                         Int4 length, Int4 size)
1642
 
{
1643
 
    Nlm_FloatHi **posFreqs;
1644
 
    register Int4 i, j, k = 0, l;
1645
 
    Nlm_FloatLo fvalue;
1646
 
    Uint4 ivalue = 0;
1647
 
    
1648
 
    if(CHARPosFreqs == NULL || CHARPosFreqs[0] == NULLB)
1649
 
        return NULL;
1650
 
    
1651
 
    posFreqs = (Nlm_FloatHi **) MemNew(sizeof(Nlm_FloatHi *)*(length+1));
1652
 
    
1653
 
    for(i = 0; i <= length; i++)
1654
 
        posFreqs[i] = (Nlm_FloatHi *) MemNew(sizeof(Nlm_FloatHi)*size);
1655
 
    
1656
 
    for(i = 0, k = 0; i <= length; i++) {
1657
 
        for(j =0; j < size; j++) {
1658
 
            for(l = 0; l < 8; l++, k++) {
1659
 
                ivalue += (BLASTCharTo4bits(CHARPosFreqs[k]) << (l * 4));
1660
 
                /* ivalue = ivalue << 4; */
1661
 
            }
1662
 
            
1663
 
            MemCpy(&fvalue, &ivalue, 4);
1664
 
            posFreqs[i][j] = (Nlm_FloatHi) fvalue; /* 4 bytes into 8 bytes */
1665
 
            ivalue = 0;
1666
 
        }
1667
 
    }
1668
 
    return posFreqs;
1669
 
}
1670
 
 
1671
 
static Int4Ptr PNTR Decode62Matrix(CharPtr Matrix62, Int4 length, Int4 size)
1672
 
{
1673
 
    Int4Ptr PNTR posMatrix;
1674
 
    register Int4 i, j, k = 0;
1675
 
 
1676
 
    if(Matrix62 == NULL || Matrix62[0] == NULLB)
1677
 
        return NULL;
1678
 
 
1679
 
    posMatrix = (Int4Ptr PNTR) MemNew(sizeof(Int4Ptr)*(length+1));
1680
 
 
1681
 
    for(i = 0; i <= length; i++)
1682
 
        posMatrix[i] = (Int4Ptr) MemNew(sizeof(Int4Ptr)*size);
1683
 
 
1684
 
    for(i = 0; i <= length; i++) {
1685
 
        for(j =0; j < size; j++) {
1686
 
            if(Matrix62[k] == 'z')
1687
 
                posMatrix[i][j] = BLAST_SCORE_MIN;
1688
 
            else if (Matrix62[k] == 'Z')
1689
 
                posMatrix[i][j] = BLAST_SCORE_MAX; 
1690
 
            else
1691
 
                posMatrix[i][j]= S62ToInt(Matrix62[k]);
1692
 
            k++;
1693
 
        }
1694
 
    }
1695
 
    return posMatrix;
1696
 
}
1697
 
static CharPtr BLASTEncodePosFreqs(Nlm_FloatHi **posFreqs, 
1698
 
                                   Int4 length, Int4 size)
1699
 
{    
1700
 
    Int4 i, j, k=0, ivalue, fmask, l;
1701
 
    CharPtr CHARPosFreqs;
1702
 
    Nlm_FloatLo fvalue;
1703
 
    Int2 tval;
1704
 
    
1705
 
    /* So... size of the buffer will be eq. to number of elements
1706
 
       in the posFreqs matrix times 8:  2 characters for every byte */
1707
 
    CHARPosFreqs = (CharPtr) MemNew((length+1)*(size+1)*sizeof(Nlm_FloatLo)*2);
1708
 
    
1709
 
    for(i = 0, k = 0; i <= length; i++) {
1710
 
        for(j =0; j < size; j++) {
1711
 
            fvalue = (Nlm_FloatLo) posFreqs[i][j]; /* truncation to 4 bytes */
1712
 
            fmask = 0xF;       /* 4 bits */
1713
 
            if(fvalue != 0.0)
1714
 
                j=j;
1715
 
            
1716
 
            MemCpy(&ivalue, &fvalue, 4);
1717
 
            for(l = 0; l < 8; l++, k++) {
1718
 
                CHARPosFreqs[k] = BLAST4bitsToChar((ivalue & fmask) >> l * 4);
1719
 
                fmask = fmask << 4;
1720
 
            }
1721
 
        }
1722
 
    }
1723
 
 
1724
 
    return CHARPosFreqs;
1725
 
}
1726
 
static CharPtr Encode62Matrix(Int4Ptr PNTR posMatrix, Int4 length, Int4 size)
1727
 
{
1728
 
    register Int4 i, j, k=0;
1729
 
    CharPtr Matrix62;
1730
 
 
1731
 
    Matrix62 = (CharPtr) MemNew((length+1)*size+1);
1732
 
 
1733
 
    for(i = 0; i <= length; i++) {
1734
 
        for(j =0; j < size; j++) {
1735
 
 
1736
 
            if(posMatrix[i][j] < -26)
1737
 
                Matrix62[k] = 'z';
1738
 
            else if (posMatrix[i][j] > 35)
1739
 
                Matrix62[k] = 'Z';
1740
 
            else
1741
 
                Matrix62[k] = IntTo62S(posMatrix[i][j]);
1742
 
 
1743
 
            k++;
1744
 
        }
1745
 
    }
1746
 
    return Matrix62;
1747
 
}
1748
 
 
1749
 
void BLASTPrintDataFree(BLASTPrintDataPtr data)
1750
 
{
1751
 
    GIListPtr glp, glp_next;
1752
 
    ValNodePtr vnp;
1753
 
 
1754
 
    if(data == NULL)
1755
 
        return;
1756
 
 
1757
 
    TxDfDbInfoDestruct(data->dbinfo);
1758
 
    MemFree(data->ka_params);
1759
 
    MemFree(data->ka_params_gap);
1760
 
    MemFree(data->buffer);
1761
 
    ValNodeFreeData(data->info_vnp);
1762
 
    
1763
 
    if(data->psidata != NULL) {
1764
 
        MemFree(data->psidata->matrix62);
1765
 
        MemFree(data->psidata->CHARPosFreqs);
1766
 
 
1767
 
        for(glp = data->psidata->PrevCheckedGIs; glp != NULL; glp = glp_next) {
1768
 
            glp_next = glp->next;
1769
 
            MemFree(glp);
1770
 
        }
1771
 
 
1772
 
        for(glp = data->psidata->PrevGoodGIs; glp != NULL; glp = glp_next) {
1773
 
            glp_next = glp->next;
1774
 
            MemFree(glp);
1775
 
        }
1776
 
        MemFree(data->psidata);
1777
 
    }
1778
 
    
1779
 
    if(data->seqalign != NULL)
1780
 
        SeqAlignSetFree(data->seqalign);
1781
 
    
1782
 
    SeqLocFree(data->seqloc);
1783
 
    
1784
 
    for(vnp = data->vnp; vnp != NULL; vnp=vnp->next) {
1785
 
        SeqAlignSetFree((SeqAlignPtr) vnp->data.ptrvalue);
1786
 
    }
1787
 
    
1788
 
    ValNodeFree(data->vnp);
1789
 
    
1790
 
    MemFree(data);
1791
 
    return;
1792
 
}
1793
 
 
1794
 
/* We got seqalign list, now divide it into two lists:
1795
 
   the first one will contain alignments with Evalue
1796
 
   better than threshold, other worse than threshold
1797
 
*/
1798
 
 
1799
 
Boolean 
1800
 
SplitSeqAlign(SeqAlignPtr seqalign, SeqAlignPtr *GoodSeqAlignment_ptr, 
1801
 
              SeqAlignPtr *BadSeqAlignment_ptr, SeqAlignPtr *lastGood_ptr, 
1802
 
              Int2Ptr *marks_ptr, Int2Ptr countBad_ptr, 
1803
 
              Int2Ptr countGood_ptr, Nlm_FloatHi ethresh_old)
1804
 
{
1805
 
    
1806
 
    Boolean first_time;
1807
 
    SeqIdPtr last_id, subject_id;
1808
 
    SeqAlignPtr         gsl, seqalign_var, last_seqalign;
1809
 
    SeqAlignPtr         BadSeqAlignments, GoodSeqAlignments, lastGood = NULL;
1810
 
    Nlm_FloatHi         bit_score, evalue;
1811
 
    Int2Ptr             marks;
1812
 
    Int2                countGood, countBad;
1813
 
    Int4                number, score;
1814
 
 
1815
 
    last_id = NULL;
1816
 
    first_time = TRUE;
1817
 
    GoodSeqAlignments = seqalign_var = seqalign;
1818
 
    
1819
 
    BadSeqAlignments = NULL;
1820
 
    while (seqalign_var) {
1821
 
        subject_id = SeqIdDup(TxGetSubjectIdFromSeqAlign(seqalign_var));
1822
 
        if (last_id == NULL || SeqIdComp(subject_id, last_id) == SIC_NO) {
1823
 
            SeqIdSetFree(last_id);
1824
 
            last_id = subject_id;
1825
 
            GetScoreAndEvalue(seqalign_var, &score, &bit_score, &evalue, &number);
1826
 
            if (evalue > ethresh_old) {
1827
 
                if (first_time == TRUE) {
1828
 
                    GoodSeqAlignments = NULL;
1829
 
                    lastGood = NULL;
1830
 
                    last_seqalign = NULL;       /* split the good and bad lists. */
1831
 
                } else {
1832
 
                    lastGood = last_seqalign;
1833
 
                    last_seqalign->next = NULL; /* split the good and bad lists. */
1834
 
                }
1835
 
                BadSeqAlignments = seqalign_var;
1836
 
                break;  
1837
 
            }
1838
 
        } else {
1839
 
            SeqIdSetFree(subject_id);
1840
 
        }
1841
 
 
1842
 
        first_time = FALSE;
1843
 
        last_seqalign = seqalign_var;
1844
 
        seqalign_var = seqalign_var->next;
1845
 
    }
1846
 
    
1847
 
    /* count number of good and bad alignments */
1848
 
    for (gsl = GoodSeqAlignments, countGood = 0; gsl; gsl = gsl->next, 
1849
 
             countGood++);
1850
 
    for (gsl = BadSeqAlignments, countBad = 0; gsl; gsl = gsl->next, 
1851
 
             countBad++);
1852
 
    
1853
 
    if (countGood + countBad)
1854
 
        /* allocate memo for marks array */
1855
 
        marks = (Int2Ptr) MemNew(sizeof(Int2) * (countGood + countBad));
1856
 
    else
1857
 
        marks = NULL;
1858
 
    
1859
 
    *GoodSeqAlignment_ptr = GoodSeqAlignments;
1860
 
    *BadSeqAlignment_ptr = BadSeqAlignments;
1861
 
    *lastGood_ptr = lastGood;
1862
 
    *marks_ptr = marks;
1863
 
    *countBad_ptr = countBad;
1864
 
    *countGood_ptr = countGood;
1865
 
    
1866
 
    return TRUE;
1867
 
}
1868
 
 
1869
 
Boolean TestSTDOut(void)
1870
 
{
1871
 
    if(write(1, "", 0) < 0) {
1872
 
        return FALSE;
1873
 
    }
1874
 
    return TRUE;
1875
 
}
1876
 
 
1877
 
static int LIBCALLBACK WWWTickCallback(Int4 sequence_number, 
1878
 
                                       Int4 number_of_positive_hits)
1879
 
{
1880
 
    if(!TestSTDOut()) {
1881
 
        return -1;
1882
 
    }
1883
 
    
1884
 
    /*    fprintf(stdout, "."); */
1885
 
 
1886
 
    printf("<!-- Progress msg from the server %d %d-->\n", 
1887
 
           sequence_number, number_of_positive_hits);
1888
 
 
1889
 
    fflush(stdout);
1890
 
    
1891
 
    return 1;
1892
 
}
1893
 
 
1894
 
static void PrintRequestHeader(WWWBlastInfoPtr theInfo)
1895
 
{
1896
 
    Char TimeNowStr[30], TimeModStr[30];
1897
 
    struct stat buf;
1898
 
 
1899
 
    printf("<HTML>\n");
1900
 
    printf("<HEAD>\n");
1901
 
    printf("<TITLE>BLAST Search Results </TITLE>\n");
1902
 
    printf("</HEAD>\n");
1903
 
    printf("<BODY BGCOLOR=\"#FFFFFF\" LINK=\"#0000FF\" "
1904
 
           "VLINK=\"#660099\" ALINK=\"#660099\">\n");
1905
 
    printf("<A HREF=\"%s/blast_form.map\">"
1906
 
           "<IMG SRC=\"%s/images/psi_blast.gif\" "
1907
 
           "BORDER=0 ISMAP></A>\n", 
1908
 
           theInfo->www_root_path == NULL? "/blast" : theInfo->www_root_path, 
1909
 
           theInfo->www_root_path == NULL? "/blast" : theInfo->www_root_path);
1910
 
    printf("<BR><BR><PRE>\n");
1911
 
   
1912
 
    init_buff_ex(90);
1913
 
 
1914
 
    BlastPrintVersionInfo(theInfo->program, TRUE, stdout);
1915
 
    fprintf(stdout, "\n");
1916
 
    
1917
 
    if (theInfo->is_phi_blast) {
1918
 
        BlastPrintPhiReference(TRUE, 90, stdout);
1919
 
    } else {
1920
 
        BlastPrintReference(TRUE, 90, stdout);
1921
 
    }
1922
 
    
1923
 
    fprintf(stdout, "\n");
1924
 
 
1925
 
    AcknowledgeBlastQuery(theInfo->query_bsp, 70, 
1926
 
                          stdout, theInfo->believe_query, TRUE);
1927
 
    
1928
 
    /*
1929
 
       dbinfo = GetDbInfoFromReadDb(search_data->database, 
1930
 
       !search_data->db_is_na);
1931
 
       PrintDbInformation(dbinfo, 70, search_data->outfp, 
1932
 
       search_data->html);
1933
 
     */
1934
 
 
1935
 
    PrintDbInformation(theInfo->database, !theInfo->db_is_na, 70, 
1936
 
                       stdout, TRUE);
1937
 
    free_buff();
1938
 
 
1939
 
    fprintf(stdout, "Searching please wait...");
1940
 
    
1941
 
    fflush(stdout);
1942
 
    
1943
 
    return;
1944
 
}
1945
 
 
1946
 
static ValNodePtr seed_core_private (BlastSearchBlkPtr search, CharPtr program_name, BLAST_OptionsBlkPtr options, SeqLocPtr *seqloc_ptr, CharPtr patfile, CharPtr pattern, Uint1Ptr query, Uint1Ptr unfilter_query, Int4 queryLength, Boolean show_diagnostics, Nlm_FloatHi *paramC, ValNodePtr PNTR info_vnp)
1947
 
     
1948
 
{
1949
 
    Boolean tmp_file_made = FALSE;
1950
 
    Char buffer[PATH_MAX];
1951
 
    ImpFeatPtr ifp;
1952
 
    Int4 hitlist_count, hspcnt, index, index1;
1953
 
    Int4 number_of_descriptions, number_of_alignments;
1954
 
    ObjectIdPtr obidp;
1955
 
    posSearchItems *posSearch;
1956
 
    SeqFeatPtr sfp;
1957
 
    SeqIdPtr subject_id;
1958
 
    SeqLocPtr next, seqloc;
1959
 
 
1960
 
    FILE *patfp; 
1961
 
    seedSearchItems *seedSearch;
1962
 
    Int4 program_flag;
1963
 
    Boolean is_dna = FALSE; /*cannot use DNA queries in blastpgp*/
1964
 
    Int4 i; /*index over characters*/
1965
 
    ValNodePtr vnp;
1966
 
    
1967
 
    
1968
 
    if (search == NULL)
1969
 
        return NULL;
1970
 
    
1971
 
    program_flag = convertProgramToFlag(program_name, &is_dna);
1972
 
    
1973
 
    if (options->isPatternSearch) {
1974
 
        if (pattern) {
1975
 
            /* open and fill a temporary file if there's a pattern. XXX */
1976
 
            TmpNam(buffer);
1977
 
            patfp = FileOpen(buffer, "w");
1978
 
            fprintf(patfp, "ID \n");
1979
 
            fprintf(patfp, "PA   %s\n", pattern);
1980
 
            fflush(patfp);
1981
 
            FileClose(patfp);
1982
 
            patfp = NULL;
1983
 
            tmp_file_made = TRUE;
1984
 
        }
1985
 
 
1986
 
        if (patfile)    /* If a file was give, use it. */
1987
 
            StringCpy(buffer, patfile);
1988
 
        if ((patfp = FileOpen(buffer, "r")) == NULL) {
1989
 
            ErrPostEx(SEV_FATAL, 0, 0, "blast: Unable to open pattern file %s\n", buffer);
1990
 
            return NULL;
1991
 
        }
1992
 
        seedSearch = (seedSearchItems *) MemNew(sizeof(seedSearchItems));
1993
 
        fillCandLambda(seedSearch, options->matrix, options);
1994
 
    } else {
1995
 
        ErrPostEx(SEV_FATAL, 0, 0, "Must be a pattern search");
1996
 
        return NULL;
1997
 
    }
1998
 
    
1999
 
    if (paramC)
2000
 
        *paramC = seedSearch->paramC;
2001
 
    
2002
 
    search->gap_align = GapAlignBlkNew(1,1);
2003
 
    search->gap_align->gap_open = options->gap_open;
2004
 
    search->gap_align->gap_extend = options->gap_extend;
2005
 
    search->gap_align->decline_align = (-(BLAST_SCORE_MIN));
2006
 
    search->gap_align->x_parameter = options->gap_x_dropoff
2007
 
        *NCBIMATH_LN2/seedSearch->paramLambda;
2008
 
    search->gap_align->matrix = search->sbp->matrix;
2009
 
    initProbs(seedSearch);
2010
 
    init_order(search->gap_align->matrix,program_flag,is_dna,seedSearch);
2011
 
 
2012
 
    for(i = 0; i < queryLength; i++)
2013
 
        query[i] = seedSearch->order[query[i]];
2014
 
    if (unfilter_query) {
2015
 
        for(i = 0; i < queryLength; i++)
2016
 
            unfilter_query[i] = seedSearch->order[unfilter_query[i]];
2017
 
    }
2018
 
    
2019
 
    seqloc = NULL;
2020
 
    posSearch = (posSearchItems *) MemNew(sizeof(posSearchItems));
2021
 
    
2022
 
    vnp = seedEngineCore(search, options, query, unfilter_query, readdb_get_filename(search->rdfp), patfile, program_flag, patfp, is_dna, FALSE, seedSearch, options->ethresh, 0.0, posSearch, &seqloc, show_diagnostics, info_vnp);
2023
 
    
2024
 
    if (tmp_file_made)  /* Remove temporary pattern file if it exists. */
2025
 
        FileRemove(buffer);
2026
 
    
2027
 
    MemFree(seedSearch);
2028
 
 
2029
 
    MemFree(posSearch->posResultSequences);
2030
 
    MemFree(posSearch);
2031
 
 
2032
 
    *seqloc_ptr = seqloc;
2033
 
    
2034
 
    return vnp;
2035
 
}
2036
 
 
2037
 
static  BLAST_ScorePtr PNTR GetPSIMatrix(PSIDataPtr psidata, WWWBlastInfoPtr theInfo, Nlm_FloatHi *karlinK_out, Nlm_FloatHi ***posFreqs_out) {
2038
 
    
2039
 
    CharPtr     chptr, Matrix62_last=NULL, pattern;
2040
 
    Int4        i, j;
2041
 
    Nlm_FloatHi karlinK;
2042
 
    FILE *fd;
2043
 
    Int2        num_entries;
2044
 
    Int4 queryLength; /*length of query sequence*/
2045
 
    Int4 numSeqAligns;
2046
 
    SeqAlignPtr seqalign;
2047
 
    SeqAlignPtr *lastSeqAligns=NULL;
2048
 
    SeqLocPtr seg_slp; /*pointer to structure for seg filtering*/
2049
 
    Uint1Ptr query = NULL; /*query sequence read in*/
2050
 
    Uint1Ptr unfilter_query = NULL; /*needed if seg will filter query*/
2051
 
    ValNodePtr info_vnp, phi_vnp = NULL;
2052
 
    SeqLocPtr phi_seqloc = NULL;
2053
 
    Uint4      gi;
2054
 
    SeqIdPtr   sip, all_sip = NULL;
2055
 
 
2056
 
    BlastSearchBlkPtr search;
2057
 
    BLAST_ScorePtr PNTR posMatrix = NULL;
2058
 
    compactSearchItems *compactSearch = NULL;
2059
 
    posSearchItems *posSearch;
2060
 
    CharPtr CHARPosFreqs_last;
2061
 
    Nlm_FloatHi **posFreqs;
2062
 
 
2063
 
    /* first step; return NULL, means to use default matrix */
2064
 
    if (psidata->StepNumber == 0) 
2065
 
        return NULL;
2066
 
        
2067
 
    /* The second step;  means, that there is list of GI's to 
2068
 
       recalculate matrix 
2069
 
       using default or read matrix and list of seqaligns 
2070
 
       from limited search;  limited search -
2071
 
       search the query not in whole database but just
2072
 
       in subset specified byt the list of GI's
2073
 
     */
2074
 
 
2075
 
    /* Create list of SeqIdPtr for the limited search */
2076
 
 
2077
 
    num_entries = WWWGetNumEntries(theInfo->info);
2078
 
 
2079
 
    for(i = 0; i < num_entries; i++) {
2080
 
        GIListPtr       good_gil, checked_gil;
2081
 
        
2082
 
        if((chptr = WWWGetNameByIndex(theInfo->info, i)) != NULL && 
2083
 
           !StringICmp(chptr, "checked_GI")) {
2084
 
            
2085
 
            if((chptr = WWWGetValueByIndex(theInfo->info, i)) != NULL) {
2086
 
                gi = atoi(chptr);                
2087
 
                sip = ValNodeAddInt(NULL, SEQID_GI, gi);
2088
 
                ValNodeLink(&all_sip, sip);
2089
 
 
2090
 
                /* Create list of GI's, it will be used when we
2091
 
                   test convergence */
2092
 
                
2093
 
                if (!psidata->PrevCheckedGIs) {
2094
 
                    /* first one */
2095
 
                    checked_gil = (GIListPtr) MemNew(sizeof(GIList));
2096
 
                    checked_gil->gi = gi;
2097
 
                    checked_gil->next = NULL;
2098
 
                    psidata->PrevCheckedGIs = checked_gil;
2099
 
                } else {
2100
 
                    checked_gil->next = (GIListPtr) MemNew(sizeof(GIList));
2101
 
                    checked_gil = checked_gil->next;
2102
 
                    checked_gil->gi = gi;
2103
 
                    checked_gil->next = NULL;
2104
 
                }
2105
 
            }
2106
 
        } else if((chptr = WWWGetNameByIndex(theInfo->info, i)) != NULL && 
2107
 
                  !StringICmp(chptr, "good_GI")) {
2108
 
            
2109
 
            if((chptr = WWWGetValueByIndex(theInfo->info, i)) != NULL) {
2110
 
                gi = atoi(chptr);
2111
 
                
2112
 
                if (!psidata->PrevGoodGIs) {
2113
 
                    /* first one */
2114
 
                    good_gil = (GIListPtr) MemNew(sizeof(GIList));
2115
 
                    good_gil->gi = gi;
2116
 
                    good_gil->next = NULL;
2117
 
                    psidata->PrevGoodGIs = good_gil;
2118
 
                } else {
2119
 
                    good_gil->next = (GIListPtr) MemNew(sizeof(GIList));
2120
 
                    good_gil = good_gil->next;
2121
 
                    good_gil->gi = gi;
2122
 
                    good_gil->next = NULL;
2123
 
                }
2124
 
            }
2125
 
        }
2126
 
    }
2127
 
 
2128
 
    /* So this search will be limited to the list of gis */
2129
 
    theInfo->options->gilist = all_sip;
2130
 
    
2131
 
    /* Some additional parameters required for the matrix recalculation */
2132
 
    
2133
 
    theInfo->options->use_best_align = TRUE;
2134
 
    theInfo->options->use_real_db_size = TRUE;
2135
 
    
2136
 
    /* the search */
2137
 
 
2138
 
    if((search = BLASTSetUpSearchWithReadDb(theInfo->fake_bsp, theInfo->program, theInfo->query_bsp->length, theInfo->database, theInfo->options, WWWTickCallback ))  == NULL) {
2139
 
        return NULL;
2140
 
    } 
2141
 
    
2142
 
    search->positionBased = FALSE;
2143
 
    
2144
 
    if (psidata->StepNumber > 1) {
2145
 
        /* The third and rest of steps;  means, that
2146
 
           before we are recalculating matrix, we 
2147
 
           should read old matrix from the previous step;
2148
 
        */
2149
 
        
2150
 
        /* Read matrix from the previous step */
2151
 
        
2152
 
        Matrix62_last = WWWGetValueByName(theInfo->info, "PSI_MATRIX");
2153
 
        
2154
 
        /* Decode read matrix */
2155
 
        
2156
 
        if(Matrix62_last != NULL && Matrix62_last[0] != NULLB) {
2157
 
            search->positionBased = TRUE;
2158
 
            search->sbp->posMatrix = Decode62Matrix (Matrix62_last, search->context[0].query->length, search->sbp->alphabet_size);
2159
 
        }
2160
 
        
2161
 
        CHARPosFreqs_last = WWWGetValueByName(theInfo->info, "POS_FREQS");
2162
 
        
2163
 
        if(CHARPosFreqs_last != NULL && CHARPosFreqs_last[0] != NULLB) {
2164
 
            search->positionBased = TRUE;
2165
 
            search->sbp->posFreqs = BLASTDecodePosFreqs(CHARPosFreqs_last, search->context[0].query->length, search->sbp->alphabet_size);
2166
 
 
2167
 
#if 0
2168
 
        {{
2169
 
            FILE *fd;
2170
 
            fd = FileOpen("/tmp/new_freqs.float", "w");
2171
 
            for(i = 0; i <= search->context[0].query->length; i++) {
2172
 
                for(j =0; j < search->sbp->alphabet_size; j++) {        
2173
 
                    fprintf(fd, "%f ", search->sbp->posFreqs[i][j]);
2174
 
                }
2175
 
                fprintf(fd, "\n");
2176
 
            }
2177
 
        }}
2178
 
#endif
2179
 
 
2180
 
 
2181
 
        }
2182
 
        
2183
 
        if((chptr = WWWGetValueByName(theInfo->info, 
2184
 
                                      "PSI_KARLIN_K")) != NULL) {
2185
 
            karlinK = atof(chptr);
2186
 
            search->sbp->kbp_gap_psi[0]->K = karlinK;
2187
 
            search->sbp->kbp_gap_psi[0]->logK = log(karlinK);
2188
 
        }
2189
 
        
2190
 
    } /* end reread the matrix */    
2191
 
 
2192
 
    search->thr_info->tick_callback = NULL;
2193
 
    
2194
 
    pattern = WWWGetValueByName(theInfo->info, "PHI_PATTERN");
2195
 
    
2196
 
    /* If pattern is non-NULL, then it is a PHI-BLAST search. */
2197
 
    if (pattern) {
2198
 
        query = BlastGetSequenceFromBioseq(theInfo->fake_bsp, &queryLength);
2199
 
        seg_slp = BlastBioseqFilter(theInfo->fake_bsp, theInfo->options->filter_string);
2200
 
        unfilter_query = NULL;
2201
 
        if (seg_slp) {
2202
 
            unfilter_query = MemNew((queryLength + 1) * sizeof(Uint1));
2203
 
            for (i = 0; i < queryLength; i++)
2204
 
                unfilter_query[i] = query[i];
2205
 
            BlastMaskTheResidues(query,queryLength,21,seg_slp,FALSE, 0);
2206
 
        }
2207
 
        
2208
 
        theInfo->options->isPatternSearch = TRUE;
2209
 
        phi_vnp = seed_core_private(search, "patseedp", theInfo->options, &phi_seqloc, NULL, pattern, query, unfilter_query, queryLength, FALSE, NULL, &info_vnp);
2210
 
        ValNodeFreeData(info_vnp);
2211
 
 
2212
 
        MemFree(query);
2213
 
        MemFree(unfilter_query);
2214
 
        
2215
 
        seqalign = convertValNodeListToSeqAlignList(phi_vnp, &lastSeqAligns, &numSeqAligns);
2216
 
        ValNodeFree(phi_vnp);
2217
 
    } else {
2218
 
        seqalign = BioseqBlastEngineCore(search, theInfo->options, 
2219
 
                                         search->sbp->posMatrix);
2220
 
    }
2221
 
    
2222
 
    if(search->sbp->posMatrix != NULL) {
2223
 
        for(i = 0; i <= theInfo->fake_bsp->length; i++) {
2224
 
            MemFree(search->sbp->posMatrix[i]);
2225
 
        }    
2226
 
        MemFree(search->sbp->posMatrix);
2227
 
        search->sbp->posMatrix = NULL;
2228
 
    }
2229
 
 
2230
 
    /* Now finaly calculating matrix that will be used at this step */
2231
 
    
2232
 
    if(seqalign) {
2233
 
 
2234
 
        ReadDBBioseqFetchEnable("psiblast", theInfo->database, 
2235
 
                                FALSE, TRUE);
2236
 
        compactSearch = compactSearchNew(compactSearch);
2237
 
        copySearchItems(compactSearch, search, theInfo->options->matrix);
2238
 
 
2239
 
        compactSearch->pseudoCountConst = 7;
2240
 
 
2241
 
        if (search->sbp->posFreqs == NULL) {
2242
 
            search->sbp->posFreqs =  allocatePosFreqs(compactSearch->qlength, 
2243
 
                                                      compactSearch->alphabetSize);
2244
 
        }
2245
 
        
2246
 
        posMatrix = WposComputation(compactSearch, seqalign, 
2247
 
                                    search->sbp->posFreqs);
2248
 
 
2249
 
        /* We have to return posFreqs to the upper layer */
2250
 
        posFreqs =  allocatePosFreqs(compactSearch->qlength, 
2251
 
                                     compactSearch->alphabetSize);
2252
 
        copyPosFreqs(search->sbp->posFreqs, posFreqs, compactSearch->qlength, 
2253
 
                     compactSearch->alphabetSize);
2254
 
 
2255
 
        MemFree(compactSearch->standardProb);
2256
 
        MemFree(compactSearch);
2257
 
 
2258
 
        ReadDBBioseqFetchDisable();
2259
 
        
2260
 
        /* Encode matrix for the use in the next step*/
2261
 
        
2262
 
        psidata->matrix62 = Encode62Matrix(posMatrix, 
2263
 
                                           search->context[0].query->length, 
2264
 
                                           search->sbp->alphabet_size);
2265
 
 
2266
 
        psidata->CHARPosFreqs = BLASTEncodePosFreqs(posFreqs, search->context[0].query->length, search->sbp->alphabet_size);
2267
 
 
2268
 
#if 0
2269
 
        {{
2270
 
            FILE *fd;
2271
 
            fd = FileOpen("/tmp/old_freqs.float", "w");
2272
 
            for(i = 0; i <= search->context[0].query->length; i++) {
2273
 
                for(j =0; j < search->sbp->alphabet_size; j++) {        
2274
 
                    fprintf(fd, "%f ", posFreqs[i][j]);
2275
 
                }
2276
 
                fprintf(fd, "\n");
2277
 
            }
2278
 
            FileClose(fd);
2279
 
            fd = FileOpen("/tmp/old_freqs.buffer", "w");
2280
 
            fprintf(fd, "%s", psidata->CHARPosFreqs);
2281
 
            FileClose(fd);            
2282
 
        }}
2283
 
#endif
2284
 
    }
2285
 
    
2286
 
    *karlinK_out = search->sbp->kbp_gap_psi[0]->K;
2287
 
    *posFreqs_out = posFreqs;
2288
 
 
2289
 
    SeqAlignSetFree(seqalign);
2290
 
    SeqLocFree(phi_seqloc);
2291
 
    
2292
 
    search = BlastSearchBlkDestruct(search);
2293
 
 
2294
 
    theInfo->options->use_best_align = FALSE;
2295
 
    theInfo->options->use_real_db_size = FALSE;
2296
 
 
2297
 
    SeqIdSetFree(theInfo->options->gilist);
2298
 
    theInfo->options->gilist = NULL;
2299
 
    theInfo->options->isPatternSearch = FALSE;
2300
 
    
2301
 
    return posMatrix;
2302
 
} /* end of GetPSIMatrix() */
2303
 
 
2304
 
BLASTPrintDataPtr PSIBlastSearch(WWWBlastInfoPtr theInfo)
2305
 
{
2306
 
    BLASTPrintDataPtr print_data;
2307
 
    ValNodePtr vnp, other_returns= NULL;
2308
 
    Int4 i, num_entries;
2309
 
    PSIDataPtr psidata;
2310
 
    CharPtr    chptr;
2311
 
    Char       matrixname[64] = "BLOSUM62";
2312
 
    Int4       opencost = 0, extendedcost = 0;
2313
 
    BlastSearchBlkPtr search;
2314
 
    BLAST_ScorePtr PNTR posMatrix = NULL;
2315
 
    Nlm_FloatHi karlinK;
2316
 
    BLAST_MatrixPtr  matrix = NULL;
2317
 
    Nlm_FloatHi **posFreqs;
2318
 
    
2319
 
    if(theInfo == NULL)
2320
 
        return NULL;
2321
 
 
2322
 
    PrintRequestHeader(theInfo); 
2323
 
    print_data = (BLASTPrintDataPtr) MemNew(sizeof(BLASTPrintData));
2324
 
    
2325
 
    psidata = MemNew(sizeof(PSIData));
2326
 
    psidata->PrevGoodGIs = NULL;
2327
 
    psidata->PrevCheckedGIs = NULL;
2328
 
    
2329
 
    /* initialize the search */
2330
 
    theInfo->options->pseudoCountConst = 7;
2331
 
 
2332
 
    if((search = BLASTSetUpSearchWithReadDb(theInfo->fake_bsp, theInfo->program, theInfo->query_bsp->length, theInfo->database, theInfo->options, WWWTickCallback ))  == NULL) {
2333
 
        return NULL;
2334
 
    }
2335
 
 
2336
 
    /* Matrix and StepNumber for PSI-Blast */
2337
 
    
2338
 
    if((chptr = WWWGetValueByName(theInfo->info, "STEP_NUMBER")) != NULL)
2339
 
        psidata->StepNumber = atoi(chptr);
2340
 
    
2341
 
    if((posMatrix = GetPSIMatrix(psidata, theInfo, 
2342
 
                                 &karlinK, &posFreqs)) != NULL) {
2343
 
        search->positionBased = TRUE;
2344
 
        search->sbp->kbp_gap_psi[0]->K = karlinK;
2345
 
        search->sbp->kbp_gap_psi[0]->logK = log(karlinK);
2346
 
        search->sbp->posFreqs = posFreqs;
2347
 
    }
2348
 
    
2349
 
    search->sbp->posMatrix = posMatrix;
2350
 
    
2351
 
    search->thr_info->tick_callback = WWWTickCallback;
2352
 
 
2353
 
    ReadDBBioseqFetchEnable("psiblast", theInfo->database, 
2354
 
                            FALSE, TRUE);    
2355
 
    printf("</PRE>\n");
2356
 
    print_data->seqalign = BioseqBlastEngineCore(search, theInfo->options, posMatrix);
2357
 
 
2358
 
    ReadDBBioseqFetchDisable();
2359
 
 
2360
 
#if 0
2361
 
    if(seqalign) {
2362
 
 
2363
 
        ReadDBBioseqFetchEnable("psiblast", theInfo->database, 
2364
 
                                FALSE, TRUE);
2365
 
        compactSearch = compactSearchNew(compactSearch);
2366
 
        copySearchItems(compactSearch, search, theInfo->options->matrix);
2367
 
 
2368
 
        compactSearch->pseudoCountConst = 7;
2369
 
 
2370
 
        if (search->sbp->posFreqs == NULL) {
2371
 
            search->sbp->posFreqs =  allocatePosFreqs(compactSearch->qlength, 
2372
 
                                                      compactSearch->alphabetSize);
2373
 
        }
2374
 
        
2375
 
        posMatrix = WposComputation(compactSearch, seqalign, 
2376
 
                                    search->sbp->posFreqs);
2377
 
 
2378
 
        MemFree(compactSearch->standardProb);
2379
 
        MemFree(compactSearch);
2380
 
 
2381
 
        
2382
 
        /* Encode matrix for the use in the next step*/
2383
 
    }
2384
 
#endif
2385
 
 
2386
 
    if(posMatrix != NULL) {
2387
 
        for(i = 0; i <= theInfo->fake_bsp->length; i++) {
2388
 
            MemFree(posMatrix[i]);
2389
 
        }
2390
 
        
2391
 
        MemFree(posMatrix);
2392
 
        search->sbp->posMatrix = NULL;
2393
 
    }
2394
 
 
2395
 
    print_data->psidata = psidata;
2396
 
    
2397
 
    /*  Blast search */
2398
 
    
2399
 
    other_returns = BlastOtherReturnsPrepare(search);
2400
 
 
2401
 
    print_data->mask_loc = NULL;
2402
 
 
2403
 
    for (vnp=other_returns; vnp; vnp = vnp->next) {
2404
 
        switch (vnp->choice) {
2405
 
        case TXDBINFO:
2406
 
            print_data->dbinfo = vnp->data.ptrvalue;
2407
 
            break;
2408
 
        case TXKABLK_NOGAP:
2409
 
            print_data->ka_params = 
2410
 
                (BLAST_KarlinBlkPtr) vnp->data.ptrvalue;
2411
 
            break;
2412
 
        case TXKABLK_GAP:
2413
 
            print_data->ka_params_gap = 
2414
 
                (BLAST_KarlinBlkPtr) vnp->data.ptrvalue;
2415
 
            psidata->karlinK = print_data->ka_params_gap->K;
2416
 
            break;
2417
 
        case TXPARAMETERS:
2418
 
            print_data->buffer = vnp->data.ptrvalue;
2419
 
            break;
2420
 
        case TXMATRIX:
2421
 
            print_data->matrix = (BLAST_MatrixPtr) vnp->data.ptrvalue;
2422
 
            /*BLAST_MatrixDestruct(matrix);*/
2423
 
            vnp->data.ptrvalue = NULL;
2424
 
            break;
2425
 
        case SEQLOC_MASKING_NOTSET:
2426
 
        case SEQLOC_MASKING_PLUS1:
2427
 
        case SEQLOC_MASKING_PLUS2:
2428
 
        case SEQLOC_MASKING_PLUS3:
2429
 
        case SEQLOC_MASKING_MINUS1:
2430
 
        case SEQLOC_MASKING_MINUS2:
2431
 
        case SEQLOC_MASKING_MINUS3:
2432
 
            ValNodeAddPointer(&(print_data->mask_loc), vnp->choice, vnp->data.ptrvalue);
2433
 
            break;
2434
 
        default:
2435
 
            break;
2436
 
        }
2437
 
    }   
2438
 
 
2439
 
    ValNodeFree(other_returns);
2440
 
 
2441
 
    search = BlastSearchBlkDestruct(search);
2442
 
 
2443
 
    return print_data;
2444
 
}
2445
 
 
2446
 
BLASTPrintDataPtr PHIBlastSearch(WWWBlastInfoPtr theInfo)
2447
 
{
2448
 
    BLASTPrintDataPtr print_data;
2449
 
    ValNodePtr vnp, other_returns= NULL;
2450
 
    PSIDataPtr psidata;
2451
 
    Nlm_FloatHi paramC;
2452
 
    Int4 i, num_entries;
2453
 
    Int4 queryLength; /*length of query sequence*/
2454
 
    CharPtr chptr;
2455
 
    Char        matrixname[64] = "BLOSUM62";
2456
 
    Int4        opencost = 0, extendedcost = 0;
2457
 
    SeqLocPtr seqloc=NULL;
2458
 
    SeqLocPtr seg_slp; /*pointer to structure for seg filtering*/
2459
 
    Uint1Ptr query = NULL; /*query sequence read in*/
2460
 
    Uint1Ptr unfilter_query = NULL; /*needed if seg will filter query*/
2461
 
    ValNodePtr info_vnp;
2462
 
    BlastSearchBlkPtr search;
2463
 
    BLAST_MatrixPtr  matrix = NULL;
2464
 
 
2465
 
    if(theInfo == NULL)
2466
 
        return NULL;
2467
 
    
2468
 
    PrintRequestHeader(theInfo); 
2469
 
    print_data = (BLASTPrintDataPtr) MemNew(sizeof(BLASTPrintData));
2470
 
    
2471
 
    psidata = MemNew(sizeof(PSIData));
2472
 
    psidata->PrevGoodGIs = NULL;
2473
 
    psidata->PrevCheckedGIs = NULL;
2474
 
    
2475
 
    print_data->psidata = psidata;
2476
 
    
2477
 
    /* Get matrix name and gap costs */
2478
 
    
2479
 
    if((chptr = WWWGetValueByName(theInfo->info, "MAT_PARAM")) != NULL) {
2480
 
        if (chptr[1] != '-' || chptr[2] != '-')
2481
 
            sscanf(chptr, "%s\t %d\t %d", matrixname, &opencost, &extendedcost);
2482
 
    }
2483
 
 
2484
 
    /* Change matrix parameters */
2485
 
    
2486
 
    BLASTOptionSetGapParams (theInfo->options, matrixname, 
2487
 
                             opencost, extendedcost);
2488
 
    
2489
 
    chptr = WWWGetValueByName(theInfo->info, "PHI_PATTERN");
2490
 
    
2491
 
    /* Reguilar PHI-Blast search */
2492
 
    theInfo->options->isPatternSearch = TRUE;
2493
 
    
2494
 
    if((search = BLASTSetUpSearchWithReadDb(theInfo->fake_bsp, "blastp", theInfo->query_bsp->length, theInfo->database, theInfo->options, WWWTickCallback))  == NULL) {
2495
 
        return NULL;
2496
 
    }
2497
 
    
2498
 
    query = BlastGetSequenceFromBioseq(theInfo->fake_bsp, &queryLength);
2499
 
    seg_slp = BlastBioseqFilter(theInfo->fake_bsp, 
2500
 
                                theInfo->options->filter_string);
2501
 
    
2502
 
    unfilter_query = NULL;
2503
 
    if (seg_slp) {
2504
 
        unfilter_query = MemNew((queryLength + 1) * sizeof(Uint1));
2505
 
        for (i = 0; i < queryLength; i++)
2506
 
            unfilter_query[i] = query[i];
2507
 
        BlastMaskTheResidues(query,queryLength,21,seg_slp,FALSE, 0);
2508
 
    }
2509
 
    
2510
 
    print_data->vnp = seed_core_private(search, "patseedp", theInfo->options, &(print_data->seqloc), NULL, chptr, query, unfilter_query, queryLength, TRUE, &paramC, &info_vnp);
2511
 
    
2512
 
    print_data->info_vnp = info_vnp;
2513
 
    
2514
 
    MemFree(query);
2515
 
    MemFree(unfilter_query);
2516
 
    
2517
 
    /*  Blast search */
2518
 
    
2519
 
    other_returns = BlastOtherReturnsPrepare(search);
2520
 
    print_data->mask_loc = NULL;
2521
 
    for (vnp=other_returns; vnp; vnp = vnp->next) {
2522
 
        switch (vnp->choice) {
2523
 
        case TXDBINFO:
2524
 
            print_data->dbinfo = vnp->data.ptrvalue;
2525
 
            break;
2526
 
        case TXKABLK_GAP:
2527
 
            print_data->ka_params_gap = vnp->data.ptrvalue;
2528
 
            /* print_data->ka_params_gap->paramC = paramC; ?? */
2529
 
            break;
2530
 
        case TXKABLK_NOGAP:
2531
 
            print_data->ka_params = vnp->data.ptrvalue;
2532
 
            break;
2533
 
        case TXPARAMETERS:
2534
 
            print_data->buffer = vnp->data.ptrvalue;
2535
 
            break;
2536
 
        case TXMATRIX:
2537
 
            print_data->matrix = (BLAST_MatrixPtr) vnp->data.ptrvalue;
2538
 
            /*BLAST_MatrixDestruct(matrix);*/
2539
 
            vnp->data.ptrvalue = NULL;
2540
 
            break;
2541
 
        case SEQLOC_MASKING_NOTSET:
2542
 
        case SEQLOC_MASKING_PLUS1:
2543
 
        case SEQLOC_MASKING_PLUS2:
2544
 
        case SEQLOC_MASKING_PLUS3:
2545
 
        case SEQLOC_MASKING_MINUS1:
2546
 
        case SEQLOC_MASKING_MINUS2:
2547
 
        case SEQLOC_MASKING_MINUS3:
2548
 
            ValNodeAddPointer(&(print_data->mask_loc), vnp->choice, vnp->data.ptrvalue);
2549
 
            break;
2550
 
        default:
2551
 
            break;
2552
 
        }
2553
 
    }
2554
 
    
2555
 
    search = BlastSearchBlkDestruct(search);
2556
 
    
2557
 
    fflush(stdout);
2558
 
    return print_data;
2559
 
}
2560
 
 
2561
 
static  void    printSubmitButton(FILE* fp, Int4 step)
2562
 
{
2563
 
    fprintf(fp, "<INPUT TYPE=\"submit\" NAME=\"NEXT_I\" "
2564
 
            "VALUE=\"Run PSI-Blast iteration %d\">\n", 
2565
 
            step);
2566
 
}
2567
 
 
2568
 
static Int4 get_number_alignment(SeqAlignPtr align)
2569
 
{
2570
 
    Int4 num = 0;
2571
 
    
2572
 
    while(align) {
2573
 
        ++num;
2574
 
        align = align->next;
2575
 
    }
2576
 
    
2577
 
    return num;
2578
 
}
2579
 
 
2580
 
Boolean PHIPrintOutput(WWWBlastInfoPtr theInfo,
2581
 
        BLASTPrintDataPtr print_data, 
2582
 
        ValNodePtr vnp, Nlm_FloatHi ethresh_old)
2583
 
{
2584
 
    Uint4 align_options, print_options;
2585
 
    SeqAnnotPtr seqannot;
2586
 
    BlastTimeKeeper time_keeper;
2587
 
    BlastPruneSapStructPtr prune;
2588
 
    Uint1 f_order[FEATDEF_ANY], g_order[FEATDEF_ANY];
2589
 
    Char        hostname[30], buffer[32];
2590
 
    Char        href[1024];
2591
 
    CharPtr     chptr;
2592
 
    Char        f_name[64], title[1024];
2593
 
    Int4        align_num;
2594
 
    Int2        count, countBad, countGood;
2595
 
    Int2Ptr     marks;
2596
 
    Int4 numSeqAligns;
2597
 
    SeqAlignPtr seqalign;
2598
 
    SeqAlignPtr *lastSeqAligns=NULL;
2599
 
    SeqAlignPtr lastGood, BadSeqAlignments, GoodSeqAlignments;
2600
 
    SeqLocPtr   seqloc;
2601
 
    ValNodePtr  vnp_var;
2602
 
    Int4Ptr PNTR txmatrix;
2603
 
 
2604
 
    MemSet((Pointer)(g_order), 0, (size_t)(FEATDEF_ANY* sizeof(Uint1)));
2605
 
    MemSet((Pointer)(f_order), 0, (size_t)(FEATDEF_ANY* sizeof(Uint1)));
2606
 
    
2607
 
    if(print_data == NULL) {
2608
 
        WWWBlastErrMessage(BLASTMiscError, NULL);                
2609
 
        return FALSE;
2610
 
    }
2611
 
 
2612
 
    print_options = 0;
2613
 
    align_options = 0;
2614
 
 
2615
 
    align_options += TXALIGN_COMPRESS;
2616
 
    align_options += TXALIGN_END_NUM;
2617
 
 
2618
 
    if (theInfo->show_gi) {
2619
 
        align_options += TXALIGN_SHOW_GI;
2620
 
        print_options += TXALIGN_SHOW_GI;
2621
 
    }
2622
 
 
2623
 
    if (theInfo->options->gapped_calculation == FALSE)
2624
 
        print_options += TXALIGN_SHOW_NO_OF_SEGS;
2625
 
 
2626
 
 
2627
 
    if (theInfo->align_view) {
2628
 
        align_options += TXALIGN_MASTER;
2629
 
 
2630
 
        if (theInfo->align_view == 1 || theInfo->align_view == 3)
2631
 
            align_options += TXALIGN_MISMATCH;
2632
 
        
2633
 
        if (theInfo->align_view == 3 || theInfo->align_view == 4 || 
2634
 
            theInfo->align_view == 6)
2635
 
            align_options += TXALIGN_FLAT_INS;
2636
 
 
2637
 
        if (theInfo->align_view == 5 || theInfo->align_view == 6)
2638
 
            align_options += TXALIGN_BLUNT_END;
2639
 
    } else {
2640
 
        align_options += TXALIGN_MATRIX_VAL;
2641
 
        align_options += TXALIGN_SHOW_QS;
2642
 
    }
2643
 
 
2644
 
    /* align_options += TXALIGN_MATRIX_VAL;
2645
 
       align_options += TXALIGN_SHOW_QS; */
2646
 
 
2647
 
    align_options += TXALIGN_HTML;
2648
 
    print_options += TXALIGN_HTML; 
2649
 
 
2650
 
    ReadDBBioseqFetchEnable ("phiblast", 
2651
 
                             theInfo->database,  theInfo->db_is_na, TRUE);
2652
 
    
2653
 
    seqannot = SeqAnnotNew();
2654
 
    seqannot->type = 2;
2655
 
    AddAlignInfoToSeqAnnot(seqannot, theInfo->align_type);
2656
 
 
2657
 
    init_buff();
2658
 
 
2659
 
    /*    gethostname(hostname, sizeof(hostname)); */
2660
 
 
2661
 
    sprintf(href, "%s/nph-viewgif.cgi?", theInfo->www_root_path == NULL? "/blast" : theInfo->www_root_path);
2662
 
    
2663
 
    seqalign = convertValNodeListToSeqAlignList(print_data->vnp, &lastSeqAligns, &numSeqAligns);
2664
 
    seqannot->data = seqalign;
2665
 
    if (theInfo->show_overview) {
2666
 
        sprintf(f_name, "%ld%ld.gif", (long)random(), (long)getpid());
2667
 
        align_num = get_number_alignment((SeqAlignPtr)(seqannot->data)); 
2668
 
        sprintf(title, "<H3><a href=\"%s/docs/newoptions.html#graphical-overview\"> "
2669
 
                "Distribution of %ld Blast Hits on the Query Sequence</a></H3>\n", theInfo->www_root_path == NULL? "/blast" : theInfo->www_root_path, (long)align_num);  
2670
 
        
2671
 
        PrintAlignmentOverview(seqannot, stdout, "PSI_BLAST", href, f_name, title); 
2672
 
    }
2673
 
 
2674
 
    seqannot->data = NULL;
2675
 
    seqannot = SeqAnnotFree(seqannot);
2676
 
    
2677
 
    print_data->vnp = convertSeqAlignListToValNodeList(seqalign, lastSeqAligns, numSeqAligns);
2678
 
    
2679
 
    print_options += TXALIGN_DO_NOT_PRINT_TITLE; 
2680
 
    print_options += TXALIGN_CHECK_BOX;
2681
 
    if (print_data->psidata->StepNumber)
2682
 
        print_options += TXALIGN_NEW_GIF;
2683
 
    
2684
 
    /* submit button */
2685
 
    printSubmitButton(stdout, 
2686
 
                      print_data->psidata->StepNumber+1);
2687
 
    
2688
 
    if (print_data->psidata->StepNumber && theInfo->number_of_descriptions) {
2689
 
        printf("<HR><p><b>Legend:</b><p>\
2690
 
<IMG SRC=\"%s/images/new.gif\" WIDTH=25 HEIGHT=15> - means that \
2691
 
the alignment score was below the threshold on the previous iteration \
2692
 
<p>\
2693
 
<IMG SRC=\"%s/images/checked.gif\" WIDTH=15 HEIGHT=15> - means that \
2694
 
the alignment was checked on the previous iteration \
2695
 
</p>", theInfo->www_root_path == NULL? "/blast" : theInfo->www_root_path,
2696
 
               theInfo->www_root_path == NULL? "/blast" : theInfo->www_root_path);
2697
 
    }
2698
 
    
2699
 
    /*
2700
 
      if (theInfo->number_of_descriptions) {
2701
 
      if (print_data->psidata->StepNumber)
2702
 
      printf("\n<IMG SRC=\"/BLAST/bg.gif\" WIDTH=65 HEIGHT=15>");
2703
 
      printf("                                                                     Score    E");
2704
 
      printf("\nSequences producing significant alignments:");
2705
 
      if (print_data->psidata->StepNumber)
2706
 
      printf("<IMG SRC=\"/BLAST/bg.gif\" WIDTH=65 HEIGHT=15>");
2707
 
      printf("                          (bits) Value\n\n");
2708
 
      }
2709
 
    */
2710
 
    
2711
 
    vnp_var = vnp;
2712
 
    seqloc = print_data->seqloc;
2713
 
    marks = NULL;
2714
 
    while (vnp_var) {
2715
 
        SplitSeqAlign((SeqAlignPtr) vnp_var->data.ptrvalue, &GoodSeqAlignments, &BadSeqAlignments, &lastGood, &marks, 
2716
 
                      &countBad, &countGood, ethresh_old);
2717
 
        
2718
 
        printf("<HR><CENTER><b><FONT color=\"green\">"
2719
 
               "Sequences with pattern at position %d and E-value BETTER than threshold</FONT></b></CENTER>\n",
2720
 
               SeqLocStart(seqloc)+1);
2721
 
        
2722
 
        if (print_data->psidata->StepNumber)
2723
 
            printf("\n<IMG SRC=\"%s/images/bg.gif\" WIDTH=65 HEIGHT=15>", theInfo->www_root_path == NULL? "/blast" : theInfo->www_root_path);
2724
 
        printf("                                                                     Score    E");
2725
 
        printf("\nSequences producing significant alignments:");
2726
 
        if (print_data->psidata->StepNumber)
2727
 
            printf("<IMG SRC=\"%s/images/bg.gif\" WIDTH=65 HEIGHT=15>",
2728
 
                   theInfo->www_root_path == NULL? "/blast" : theInfo->www_root_path);
2729
 
        printf("                          (bits) Value\n\n");
2730
 
        
2731
 
        fflush(stdout);
2732
 
        print_options += TXALIGN_CHECK_BOX_CHECKED;
2733
 
        PrintDefLinesFromSeqAlignEx(GoodSeqAlignments, 80, stdout, print_options, FIRST_PASS, marks, theInfo->number_of_descriptions);
2734
 
        
2735
 
        print_options -= TXALIGN_CHECK_BOX_CHECKED;
2736
 
        
2737
 
        if (print_data->psidata->StepNumber == 0)
2738
 
            printf("<a name = Evalue> </a>");
2739
 
        
2740
 
        if (theInfo->number_of_descriptions > countGood && BadSeqAlignments) {
2741
 
            /* submit button */
2742
 
            printSubmitButton(stdout, print_data->psidata->StepNumber+1);
2743
 
            
2744
 
            printf("<HR><CENTER><b><FONT color=\"green\">"
2745
 
                   "Sequences with pattern at position %d and E-value WORSE than threshold</FONT></b></CENTER>\n", 
2746
 
                   SeqLocStart(seqloc)+1);
2747
 
            
2748
 
            PrintDefLinesFromSeqAlignEx(BadSeqAlignments, 80, stdout, print_options, FIRST_PASS, &marks[countGood], theInfo->number_of_descriptions - countGood);
2749
 
        }
2750
 
 
2751
 
        marks = MemFree(marks);
2752
 
        
2753
 
        /* merge lists */
2754
 
        if (lastGood)
2755
 
            lastGood->next = BadSeqAlignments;
2756
 
        
2757
 
        vnp_var = vnp_var->next;
2758
 
        seqloc = seqloc->next;
2759
 
    }
2760
 
    
2761
 
    if (theInfo->number_of_descriptions) {
2762
 
        /* submit button */
2763
 
        printSubmitButton(stdout, 
2764
 
                          print_data->psidata->StepNumber+1);
2765
 
    }
2766
 
    
2767
 
    free_buff();
2768
 
    fflush(stdout);
2769
 
 
2770
 
    GlobalAlignNumber = 0;
2771
 
 
2772
 
    fprintf(stdout, "<HR>");
2773
 
 
2774
 
    txmatrix = NULL;
2775
 
    if (print_data->matrix)
2776
 
       txmatrix = (Int4Ptr PNTR) BlastMatrixToTxMatrix(print_data->matrix);
2777
 
 
2778
 
    if (theInfo->number_of_alignments) {
2779
 
        fprintf(stdout, "<CENTER><b><FONT color=\"green\">"
2780
 
                "Alignments</FONT></b></CENTER>\n");
2781
 
        
2782
 
        f_order[FEATDEF_REGION] = 1;
2783
 
        g_order[FEATDEF_REGION] = 1;
2784
 
        if(theInfo->align_view == 0) {
2785
 
            ShowTextAlignFromAnnotExtra(theInfo->fake_bsp, 
2786
 
                                        print_data->vnp, 
2787
 
                                        print_data->seqloc, 60, 
2788
 
                                        stdout, 
2789
 
                                        f_order, g_order, align_options, 
2790
 
                                        txmatrix, print_data->mask_loc, 
2791
 
                                        FormatScoreFunc);
2792
 
        } else {
2793
 
            ShowTextAlignFromAnnotExtra(theInfo->fake_bsp, 
2794
 
                                        print_data->vnp, 
2795
 
                                        print_data->seqloc, 60, 
2796
 
                                        stdout, 
2797
 
                                        f_order, g_order, align_options, 
2798
 
                                        txmatrix, print_data->mask_loc, 
2799
 
                                        NULL);
2800
 
            printf("<P>\n");
2801
 
        }
2802
 
    }
2803
 
 
2804
 
    fflush(stdout);
2805
 
    ObjMgrClearHold(); 
2806
 
 
2807
 
    printf("<PRE>\n");
2808
 
 
2809
 
    BlastTimeFillStructure(&time_keeper);
2810
 
 
2811
 
    fprintf(stdout, "CPU time: %8.2f user secs.\t%8.2f sys. "
2812
 
            "secs\t%8.2f total secs.\n\n", 
2813
 
            time_keeper.user, time_keeper.system, time_keeper.total);    
2814
 
    
2815
 
    if (txmatrix)
2816
 
           txmatrix =  (Int4Ptr PNTR) TxMatrixDestruct(txmatrix);
2817
 
    print_data->matrix = BLAST_MatrixDestruct(print_data->matrix);
2818
 
 
2819
 
    init_buff();
2820
 
    PrintDbReport(print_data->dbinfo, 70, stdout);
2821
 
    
2822
 
    fflush(stdout);
2823
 
    if (print_data->ka_params_gap) {
2824
 
        PrintKAParameters(print_data->ka_params_gap->Lambda, 
2825
 
                          print_data->ka_params_gap->K, 
2826
 
                          print_data->ka_params_gap->H, 
2827
 
                          70, stdout, TRUE);
2828
 
    }
2829
 
    fflush(stdout);
2830
 
    
2831
 
    PGPOutTextMessages(print_data->info_vnp, stdout);
2832
 
 
2833
 
    PrintTildeSepLines(print_data->buffer, 70, stdout);
2834
 
    free_buff();
2835
 
 
2836
 
    fflush(stdout);
2837
 
 
2838
 
    ReadDBBioseqFetchDisable();
2839
 
 
2840
 
    return TRUE;
2841
 
}
2842
 
 
2843
 
Boolean PSIPrintOutput(WWWBlastInfoPtr theInfo,
2844
 
        BLASTPrintDataPtr print_data, 
2845
 
        SeqAlignPtr BadSeqAlignments, SeqAlignPtr GoodSeqAlignments,
2846
 
        SeqAlignPtr lastGood,
2847
 
        Int2Ptr marks, Int2 countBad, Int2 countGood,
2848
 
        Nlm_FloatHi ethresh_old)
2849
 
{
2850
 
    Uint4 align_options, print_options;
2851
 
    SeqAnnotPtr seqannot;
2852
 
    BlastTimeKeeper time_keeper;
2853
 
    BlastPruneSapStructPtr prune;
2854
 
    Uint1 f_order[FEATDEF_ANY], g_order[FEATDEF_ANY];
2855
 
    Char        hostname[30], buffer[32];
2856
 
    Char        href[1024];
2857
 
    CharPtr     chptr;
2858
 
    Char        f_name[64], title[1024];
2859
 
    Int4        align_num;
2860
 
    Int2        count;
2861
 
    Int4Ptr PNTR txmatrix;
2862
 
 
2863
 
    MemSet((Pointer)(g_order), 0, (size_t)(FEATDEF_ANY* sizeof(Uint1)));
2864
 
    MemSet((Pointer)(f_order), 0, (size_t)(FEATDEF_ANY* sizeof(Uint1)));
2865
 
    
2866
 
    if(print_data == NULL) {
2867
 
        WWWBlastErrMessage(BLASTMiscError, NULL);                
2868
 
        return FALSE;
2869
 
    }
2870
 
    
2871
 
    print_options = 0;
2872
 
    align_options = 0;
2873
 
    
2874
 
    align_options += TXALIGN_COMPRESS;
2875
 
    align_options += TXALIGN_END_NUM;
2876
 
    
2877
 
    if (theInfo->show_gi) {
2878
 
        align_options += TXALIGN_SHOW_GI;
2879
 
        print_options += TXALIGN_SHOW_GI;
2880
 
    }
2881
 
    
2882
 
    if (theInfo->options->gapped_calculation == FALSE)
2883
 
        print_options += TXALIGN_SHOW_NO_OF_SEGS;
2884
 
    
2885
 
    if (theInfo->align_view) {
2886
 
        align_options += TXALIGN_MASTER;
2887
 
        
2888
 
        if (theInfo->align_view == 1 || theInfo->align_view == 3)
2889
 
            align_options += TXALIGN_MISMATCH;
2890
 
        
2891
 
        if (theInfo->align_view == 3 || theInfo->align_view == 4 || 
2892
 
            theInfo->align_view == 6)
2893
 
            align_options += TXALIGN_FLAT_INS;
2894
 
 
2895
 
        if (theInfo->align_view == 5 || theInfo->align_view == 6)
2896
 
            align_options += TXALIGN_BLUNT_END;
2897
 
    } else {
2898
 
        align_options += TXALIGN_MATRIX_VAL;
2899
 
        align_options += TXALIGN_SHOW_QS;
2900
 
    }
2901
 
    
2902
 
    /* align_options += TXALIGN_MATRIX_VAL;
2903
 
       align_options += TXALIGN_SHOW_QS; */
2904
 
 
2905
 
    align_options += TXALIGN_HTML;
2906
 
    print_options += TXALIGN_HTML; 
2907
 
 
2908
 
    ReadDBBioseqFetchEnable ("psiblast", 
2909
 
            theInfo->database, 
2910
 
            theInfo->db_is_na, 
2911
 
            TRUE);
2912
 
 
2913
 
    seqannot = SeqAnnotNew();
2914
 
    seqannot->type = 2;
2915
 
    AddAlignInfoToSeqAnnot(seqannot, theInfo->align_type);
2916
 
    seqannot->data = print_data->seqalign;
2917
 
 
2918
 
    init_buff();
2919
 
 
2920
 
    /* merge lists */
2921
 
    if (lastGood)
2922
 
        lastGood->next = BadSeqAlignments;
2923
 
    
2924
 
    /* gethostname(hostname, sizeof(hostname)); */
2925
 
    
2926
 
    sprintf(href, "%s/nph-viewgif.cgi?",
2927
 
            theInfo->www_root_path == NULL? "/blast" : theInfo->www_root_path);
2928
 
    
2929
 
    if (theInfo->show_overview) {
2930
 
        sprintf(f_name, "%ld%ld.gif", (long)random(), (long)getpid());
2931
 
        align_num = get_number_alignment((SeqAlignPtr)(seqannot->data)); 
2932
 
        sprintf(title, "<H3><a href=\"%s/docs/newoptions.html#graphical-overview\"> "
2933
 
                "Distribution of %ld Blast Hits on the Query Sequence</a></H3>\n", theInfo->www_root_path == NULL? "/blast" : theInfo->www_root_path, (long)align_num);  
2934
 
        
2935
 
        PrintAlignmentOverview(seqannot, stdout, "PSI_BLAST", href, f_name, title); 
2936
 
    }
2937
 
    
2938
 
    /* separate lists */
2939
 
    if (lastGood)
2940
 
        lastGood->next = NULL;
2941
 
    
2942
 
    print_options += TXALIGN_DO_NOT_PRINT_TITLE; 
2943
 
    print_options += TXALIGN_CHECK_BOX;
2944
 
    print_options += TXALIGN_CHECK_BOX_CHECKED;
2945
 
    if (print_data->psidata->StepNumber)
2946
 
        print_options += TXALIGN_NEW_GIF;
2947
 
    
2948
 
    /* submit button */
2949
 
    printSubmitButton(stdout, 
2950
 
                      print_data->psidata->StepNumber+1);
2951
 
    
2952
 
    if (print_data->psidata->StepNumber && theInfo->number_of_descriptions) {
2953
 
        printf("<HR><p><b>Legend:</b><p>\
2954
 
<IMG SRC=\"%s/images/new.gif\" WIDTH=25 HEIGHT=15> - means that \
2955
 
the alignment score was below the threshold on the previous iteration \
2956
 
<p>\
2957
 
<IMG SRC=\"%s/images/checked.gif\" WIDTH=15 HEIGHT=15> - means that \
2958
 
the alignment was checked on the previous iteration \
2959
 
</p>", theInfo->www_root_path == NULL? "/blast" : theInfo->www_root_path,
2960
 
               theInfo->www_root_path == NULL? "/blast" : theInfo->www_root_path);
2961
 
    }
2962
 
    
2963
 
    if (theInfo->number_of_descriptions) {
2964
 
        printf("<HR><CENTER><b><FONT color=\"green\">"
2965
 
               "Sequences with E-value BETTER than threshold </FONT></b></CENTER>\n");
2966
 
        if (print_data->psidata->StepNumber)
2967
 
            printf("\n<IMG SRC=\"%s/images/bg.gif\" WIDTH=65 HEIGHT=15>", theInfo->www_root_path == NULL? "/blast" : theInfo->www_root_path);
2968
 
        printf("                                                                     Score    E");
2969
 
        printf("\nSequences producing significant alignments:");
2970
 
        if (print_data->psidata->StepNumber)
2971
 
            printf("<IMG SRC=\"%s/images/bg.gif\" WIDTH=65 HEIGHT=15>", theInfo->www_root_path == NULL? "/blast" : theInfo->www_root_path);
2972
 
        printf("                          (bits) Value\n\n");
2973
 
    }
2974
 
    
2975
 
    PrintDefLinesFromSeqAlignEx(GoodSeqAlignments, 80, stdout, 
2976
 
                                print_options, FIRST_PASS, marks, theInfo->number_of_descriptions);
2977
 
    
2978
 
    print_options -= TXALIGN_CHECK_BOX_CHECKED;
2979
 
    
2980
 
    if (print_data->psidata->StepNumber == 0)
2981
 
        printf("<a name = Evalue> </a>");
2982
 
    
2983
 
    if (theInfo->number_of_descriptions > countGood && BadSeqAlignments) {
2984
 
 
2985
 
        printSubmitButton(stdout, 
2986
 
                          print_data->psidata->StepNumber+1);
2987
 
        
2988
 
        printf("<HR><CENTER><b><FONT color=\"green\">"
2989
 
               "Sequences with E-value WORSE than threshold </FONT></b></CENTER>\n");
2990
 
    
2991
 
        PrintDefLinesFromSeqAlignEx(BadSeqAlignments, 80, stdout, print_options, FIRST_PASS, &marks[countGood], theInfo->number_of_descriptions - countGood);
2992
 
    }
2993
 
 
2994
 
    if (theInfo->number_of_descriptions) {
2995
 
        printSubmitButton(stdout, 
2996
 
                          print_data->psidata->StepNumber+1);
2997
 
    }
2998
 
 
2999
 
    free_buff();
3000
 
    fflush(stdout);
3001
 
 
3002
 
    GlobalAlignNumber = 0;
3003
 
 
3004
 
    /* merge lists */
3005
 
    if (lastGood)
3006
 
        lastGood->next = BadSeqAlignments;
3007
 
 
3008
 
    prune = BlastPruneHitsFromSeqAlign((SeqAlignPtr) seqannot->data, theInfo->number_of_alignments, NULL);
3009
 
    seqannot->data = prune->sap;
3010
 
 
3011
 
    fprintf(stdout, "<HR>");
3012
 
 
3013
 
    txmatrix = NULL;
3014
 
    if (print_data->matrix)
3015
 
       txmatrix = (Int4Ptr PNTR) BlastMatrixToTxMatrix(print_data->matrix);
3016
 
 
3017
 
    if (theInfo->number_of_alignments) {
3018
 
        fprintf(stdout, "<CENTER><b><FONT color=\"green\">"
3019
 
                "Alignments</FONT></b></CENTER>\n");
3020
 
 
3021
 
        /* New DDV formating requested */
3022
 
        if(theInfo->color_schema != 0) {
3023
 
            if(!DDV_DisplayBlastPairList(prune->sap, print_data->mask_loc, 
3024
 
                                         stdout, 
3025
 
                                         theInfo->query_is_na, align_options, 
3026
 
                                         theInfo->color_schema)) { 
3027
 
                fprintf(stdout, 
3028
 
                        "\n\n!!!\n   "
3029
 
                        "    --------  Failure to print alignment...  --------"
3030
 
                        "\n!!!\n\n");
3031
 
                fflush(stdout);
3032
 
            }
3033
 
        } else {   /* Old type formating */
3034
 
            if (theInfo->align_view == 0) {
3035
 
                ShowTextAlignFromAnnot2(seqannot, 60, stdout, f_order,
3036
 
                                        g_order, align_options, txmatrix, 
3037
 
                                        print_data->mask_loc, 
3038
 
                                        FormatScoreFunc, theInfo->database, 
3039
 
                                        "psiblast");
3040
 
            } else { 
3041
 
                ShowTextAlignFromAnnot(seqannot, 60, stdout, f_order,
3042
 
                                       g_order, align_options, txmatrix, 
3043
 
                                       print_data->mask_loc, NULL);
3044
 
                printf("<P>\n");
3045
 
            }
3046
 
        }
3047
 
    }
3048
 
 
3049
 
    /* separate lists */
3050
 
    if (lastGood)
3051
 
        lastGood->next = NULL;
3052
 
 
3053
 
    fflush(stdout);
3054
 
    ObjMgrClearHold(); 
3055
 
 
3056
 
    prune = BlastPruneSapStructDestruct(prune);
3057
 
 
3058
 
    seqannot->data = NULL; 
3059
 
    seqannot = SeqAnnotFree(seqannot);
3060
 
 
3061
 
    printf("<PRE>\n");
3062
 
 
3063
 
    BlastTimeFillStructure(&time_keeper);
3064
 
 
3065
 
    fprintf(stdout, "CPU time: %8.2f user secs.\t%8.2f sys. "
3066
 
            "secs\t%8.2f total secs.\n\n", 
3067
 
            time_keeper.user, time_keeper.system, time_keeper.total);    
3068
 
 
3069
 
    print_data->matrix = BLAST_MatrixDestruct(print_data->matrix);
3070
 
    if (txmatrix)
3071
 
       txmatrix = (Int4Ptr PNTR) TxMatrixDestruct(txmatrix);
3072
 
 
3073
 
    init_buff();
3074
 
    PrintDbReport(print_data->dbinfo, 70, stdout);
3075
 
    
3076
 
    if (print_data->ka_params) {
3077
 
        PrintKAParameters(print_data->ka_params->Lambda, 
3078
 
                          print_data->ka_params->K, 
3079
 
                          print_data->ka_params->H, 70, 
3080
 
                          stdout, FALSE);
3081
 
    }
3082
 
    
3083
 
    if (print_data->ka_params_gap) {
3084
 
        PrintKAParameters(print_data->ka_params_gap->Lambda, 
3085
 
                          print_data->ka_params_gap->K, 
3086
 
                          print_data->ka_params_gap->H, 
3087
 
                          70, stdout, TRUE);
3088
 
    }
3089
 
 
3090
 
    PrintTildeSepLines(print_data->buffer, 70, stdout);
3091
 
    free_buff();
3092
 
    
3093
 
    fflush(stdout);
3094
 
 
3095
 
    ReadDBBioseqFetchDisable();
3096
 
 
3097
 
    return TRUE;
3098
 
}