1 /* $Id: wwwblast.c,v 1.16 2011/12/19 18:41:34 gouriano 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: wwwblast.c,v $
27 *
28 * Author: Sergei Shavirin
29 *
30 * Initial Creation Date: 03/15/2000
31 *
32 * $Revision: 1.16 $
33 *
34 * File Description:
35 * Standalone WWW Blast CGI program.
36 *
37 * $Log: wwwblast.c,v $
38 * Revision 1.16 2011/12/19 18:41:34 gouriano
39 * Corrected printf formatting. NOJIRA
40 *
41 * Revision 1.15 2004/05/03 15:11:46 dondosha
42 * Added support for masking query in XML output
43 *
44 * Revision 1.14 2004/03/02 16:44:11 dondosha
45 * Do not print closing </form> for XML output
46 *
47 * Revision 1.13 2004/01/16 17:35:20 dondosha
48 * Fixed mouseover problems
49 *
50 * Revision 1.12 2003/11/20 22:19:35 dondosha
51 * Pass www_root_path to the PrintDefLines... function
52 *
53 * Revision 1.11 2003/11/20 20:10:52 dondosha
54 * Decide whether to print header only after the output type is determined
55 *
56 * Revision 1.10 2003/11/20 19:10:33 dondosha
57 * Do not print progress messages if XML output requested
58 *
59 * Revision 1.9 2003/11/05 22:40:28 dondosha
60 * Do not shift coordinates for tabular output if query is a subsequence - they are already shifted in the seqalign
61 *
62 * Revision 1.8 2003/06/04 16:12:51 dondosha
63 * Set db genetic code for formatting
64 *
65 * Revision 1.7 2003/05/13 22:00:37 dondosha
66 * More changes to make alternative links work
67 *
68 * Revision 1.6 2003/05/13 21:17:01 dondosha
69 * Pass www_blast_type to txalign in all cases
70 *
71 * Revision 1.5 2003/05/09 21:09:05 dondosha
72 * Removed unused variables
73 *
74 * Revision 1.4 2003/05/02 23:04:03 dondosha
75 * Fixed paths for non-standard setups, removed blast_form.map
76 *
77 * Revision 1.3 2003/04/29 15:55:56 dondosha
78 * Always use root path in links
79 *
80 * Revision 1.2 2003/02/10 21:48:53 dondosha
81 * Added support for multi-query XML output
82 *
83 * Revision 1.1 2002/12/02 18:05:53 dondosha
84 * Moved from different locations to a common one
85 *
86 * Revision 6.32 2002/06/19 22:50:17 dondosha
87 * Added all queries information for tabular output with multiple queries
88 *
89 * Revision 6.31 2002/06/18 21:14:28 dondosha
90 * Added return statement in the end of AppendMegaBlastHit
91 *
92 * Revision 6.30 2002/01/08 22:36:25 dondosha
93 * Added tabular output functionality
94 *
95 * Revision 6.29 2000/11/29 16:11:31 dondosha
96 * If multiple queries, send proper lower case mask to the search engine
97 *
98 * Revision 6.28 2000/11/17 14:40:04 dondosha
99 * Changed MegaBlastResultsNew call to MemNew
100 *
101 * Revision 6.27 2000/11/16 22:37:07 dondosha
102 * Added endpoint Mega BLAST results handling
103 *
104 * Revision 6.26 2000/10/31 20:18:52 shavirin
105 * Added printing of correct XML output when no hits found
106 * Added printing progeress messages to avoid browser timeout.
107 *
108 * Revision 6.25 2000/10/23 20:19:57 dondosha
109 * Open and close AsnIo outside calls to BXMLPrintOutput function
110 *
111 * Revision 6.24 2000/10/18 20:19:31 shavirin
112 * Added title for OOF Blastx.
113 *
114 * Revision 6.23 2000/10/16 22:18:17 shavirin
115 * Added possibility to perform OOF blastx
116 *
117 * Revision 6.22 2000/10/16 20:27:03 shavirin
118 * Added possibility to run RPS Blast.
119 *
120 * Revision 6.21 2000/09/28 16:48:20 dondosha
121 * Changed MegaBlast related code to get a single SeqAlignPtr from server
122 *
123 * Revision 6.20 2000/09/28 15:16:55 shavirin
124 * Added message if request was limited to results of Entrez query.
125 *
126 * Revision 6.19 2000/09/27 22:17:04 shavirin
127 * Added possibility to limit search to results of entrez query.
128 *
129 * Revision 6.18 2000/09/13 22:28:10 dondosha
130 * Removed extra </PRE> that is now printed in PrintDefLinesFromSeqAlign
131 *
132 * Revision 6.17 2000/09/13 20:47:51 dondosha
133 * Small cleanup with closures of html blocks
134 *
135 * Revision 6.16 2000/09/12 21:57:28 dondosha
136 * Pass the correct scoring matrix to ShowTextAlignFromAnnot
137 *
138 * Revision 6.15 2000/09/11 17:51:07 shavirin
139 * Removed redundant <PRE> tag.
140 *
141 * Revision 6.14 2000/09/08 20:18:12 dondosha
142 * Print the title, background and GIF image before creating options
143 *
144 * Revision 6.13 2000/09/08 14:49:28 dondosha
145 * Allow graphical overview with multiple queries
146 *
147 * Revision 6.12 2000/09/07 18:01:38 dondosha
148 * Pass a callback to the server from TraditionalBlastReportEngineWithImage; allow multiple queries for all BLAST searches
149 *
150 * Revision 6.11 2000/09/05 18:00:25 dondosha
151 * Added query acknowledgement for each query in WWWBlastDoSearch for megablast
152 *
153 * Revision 6.10 2000/09/01 17:55:14 dondosha
154 * Call SeqEntryLoad at the beginning; corrections for megablast page
155 *
156 * Revision 6.9 2000/08/30 22:22:35 dondosha
157 * Enhance function WWWBlastDoSearch to handle megablast search
158 *
159 * Revision 6.8 2000/08/28 20:20:59 dondosha
160 * Added functionality for megablast web page
161 *
162 * Revision 6.7 2000/08/09 20:30:30 shavirin
163 * Added possibility to print XML output.
164 *
165 * Revision 6.6 2000/07/31 20:44:12 shavirin
166 * Minor change (initialized variable) from Haruna Cofer (haruna@detroit.sgi.com)
167 *
168 * Revision 6.5 2000/05/17 15:50:51 shavirin
169 * Moved many functions to the wwwbutl.c file.
170 *
171 * Revision 6.4 2000/04/21 18:10:59 shavirin
172 * Added possibility to print Patrick's alignment.
173 *
174 * Revision 6.3 2000/03/28 14:44:20 shavirin
175 * Changed function ctime_r to ctime() for compatibility.
176 *
177 * Revision 6.2 2000/03/24 16:05:37 shavirin
178 * Added option to be used as NCBI client/server.
179 *
180 * Revision 6.1 2000/03/20 19:01:00 shavirin
181 * Initial revision.
182 *
183 *
184 * ==========================================================================
185 */
186
187 #include <wwwblast.h>
188 #include <xmlblast.h>
189
WWWTickCallback(Int4 sequence_number,Int4 number_of_positive_hits)190 static int LIBCALLBACK WWWTickCallback(Int4 sequence_number,
191 Int4 number_of_positive_hits)
192 {
193 if(!TestSTDOut()) {
194 return -1;
195 }
196
197 /* fprintf(stdout, "."); */
198
199 printf("<!-- Progress msg from the server %d %d-->\n",
200 sequence_number, number_of_positive_hits);
201
202 fflush(stdout);
203
204 return 1;
205 }
206
207 /* Callback in case of XML output should not print anything to the stdout */
WWWXMLTickCallback(Int4 sequence_number,Int4 number_of_positive_hits)208 static int LIBCALLBACK WWWXMLTickCallback(Int4 sequence_number,
209 Int4 number_of_positive_hits)
210 {
211 if(!TestSTDOut()) {
212 return -1;
213 }
214 fflush(stdout);
215
216 return 1;
217 }
218
get_number_alignment(SeqAlignPtr align)219 static Int4 get_number_alignment(SeqAlignPtr align)
220 {
221 Int4 num = 0;
222
223 while(align)
224 {
225 ++num;
226 align = align->next;
227 }
228
229 return num;
230 }
231 static void
PrintMotd(CharPtr string,FILE * fp,Boolean html_format)232 PrintMotd(CharPtr string, FILE *fp, Boolean html_format)
233
234 {
235 Char buffer[100];
236 CharPtr ptr;
237
238 if (string == NULL)
239 return;
240
241 buffer[0] = NULLB;
242 ptr = buffer;
243
244 if (html_format) {
245 fprintf(fp, "<PRE>\n");
246 }
247
248 while (*string != NULLB) {
249 if (*string == '~') {
250 *ptr = NULLB;
251 fprintf(fp, "%s\n", buffer);
252 buffer[0] = NULLB;
253 ptr = buffer;
254 string++;
255 if (*string == NULLB)
256 break;
257 } else {
258 *ptr=*string;
259 ptr++; string++;
260 }
261 }
262 *ptr = NULLB;
263 fprintf(fp, "%s\n", buffer);
264
265 if (html_format) {
266 fprintf(fp, "</PRE>\n");
267 }
268
269 fflush(fp);
270
271 return;
272 }
273 #ifdef NCBI_CLIENT_SERVER
274
275 static Boolean LIBCALLBACK
callback(BlastResponsePtr brp,Boolean PNTR cancel)276 callback (BlastResponsePtr brp, Boolean PNTR cancel)
277
278 {
279 fprintf(stdout, "</PRE>\n<PRE>");
280 return TRUE;
281 }
282
283 static Boolean
TraditionalBlastReportEngineWithImage(SeqLocPtr slp,BioseqPtr bsp,BlastNet3Hptr bl3hp,WWWBlastInfoPtr theInfo)284 TraditionalBlastReportEngineWithImage(SeqLocPtr slp, BioseqPtr bsp, BlastNet3Hptr bl3hp, WWWBlastInfoPtr theInfo)
285
286 {
287 BlastDbinfoPtr dbinfo;
288 BlastKABlkPtr ka_params=NULL, ka_params_gap=NULL;
289 BlastPruneSapStructPtr prune;
290 BLAST_MatrixPtr matrix;
291 Int4Ptr PNTR txmatrix;
292 Boolean query_is_na, db_is_na;
293 Boolean status;
294 CharPtr params_buffer=NULL;
295 Int4 number_of_hits_private=0, length;
296 SeqAlignPtr seqalign = NULL, sap, next_seqalign;
297 SeqAnnotPtr seqannot=NULL;
298 TxDfDbInfoPtr tx_dbinfo=NULL, tx_dbinfo_head;
299 ValNodePtr mask_loc = NULL, mask_loc_start, next_mask_loc = NULL;
300 SeqLocPtr mask_slp = NULL;
301 ValNodePtr other_returns, error_returns, vnp, vnp1=NULL;
302 Uint1 align_type;
303 Uint1 f_order[FEATDEF_ANY], g_order[FEATDEF_ANY];
304 /* Variables for multiple query output */
305 SeqLocPtr tmp_slp;
306 Boolean done = TRUE;
307 BLAST_OptionsBlkPtr options = theInfo->options;
308 CharPtr program = theInfo->program, database = theInfo->database;
309 Uint4 align_options = theInfo->align_options;
310 DenseSegPtr dsp, next_dsp;
311 AsnIoPtr xml_aip;
312 MegaBlastResultsPtr mb_results = NULL;
313 Boolean tabular_output = (theInfo->align_view == HitTable ||
314 theInfo->align_view == HitTableWithHeader);
315
316 MemSet((Pointer)(g_order), 0, (size_t)(FEATDEF_ANY* sizeof(Uint1)));
317 MemSet((Pointer)(f_order), 0, (size_t)(FEATDEF_ANY* sizeof(Uint1)));
318
319 if (bsp == NULL && slp == NULL)
320 return FALSE;
321
322 if (bl3hp == NULL || program == NULL || database == NULL)
323 return FALSE;
324
325 align_type = BlastGetTypes(program, &query_is_na, &db_is_na);
326
327 init_buff_ex(85);
328 dbinfo = BlastRequestDbInfo(bl3hp, database, !db_is_na);
329
330 if (dbinfo && !tabular_output &&
331 !(options->is_megablast_search && options->no_traceback))
332 PrintDbInformationBasic(database, !db_is_na, 70, dbinfo->definition, dbinfo->number_seqs, dbinfo->total_length, stdout, TRUE);
333 dbinfo = BlastDbinfoFree(dbinfo);
334 free_buff();
335
336 if (bsp)
337 seqalign = BlastBioseqNetCore(bl3hp, bsp, program, database, options, &other_returns, &error_returns, callback, NULL, &status);
338 else if (options->is_megablast_search) {
339 seqalign = MegaBlastSeqLocNetCore(bl3hp, slp, program, database, options, &other_returns, &error_returns, callback, &status);
340 } else
341 seqalign = BlastSeqLocNetCore(bl3hp, slp, program, database, options, &other_returns, &error_returns, callback, NULL, &status);
342
343
344 BlastErrorPrintExtra(error_returns, TRUE, stdout);
345
346 mask_loc = next_mask_loc = NULL;
347 matrix = NULL;
348 txmatrix = NULL;
349 for (vnp=other_returns; vnp; vnp = vnp->next) {
350 switch (vnp->choice) {
351 case BlastResponse_mbalign:
352 mb_results = (MegaBlastResultsPtr) vnp->data.ptrvalue;
353 break;
354 case TXDBINFO:
355 tx_dbinfo = (TxDfDbInfoPtr) vnp->data.ptrvalue;
356 break;
357 case TXKABLK_NOGAP:
358 ka_params = (BlastKABlkPtr) vnp->data.ptrvalue;
359 break;
360 case TXKABLK_GAP:
361 ka_params_gap = (BlastKABlkPtr) vnp->data.ptrvalue;
362 break;
363 case TXPARAMETERS:
364 params_buffer = (CharPtr) vnp->data.ptrvalue;
365 break;
366 case TXMATRIX:
367 matrix = (BLAST_MatrixPtr) vnp->data.ptrvalue;
368 if (matrix)
369 txmatrix = BlastMatrixToTxMatrix(matrix);
370 /*BLAST_MatrixDestruct(matrix);*/
371 break;
372 case SEQLOC_MASKING_NOTSET:
373 case SEQLOC_MASKING_PLUS1:
374 case SEQLOC_MASKING_PLUS2:
375 case SEQLOC_MASKING_PLUS3:
376 case SEQLOC_MASKING_MINUS1:
377 case SEQLOC_MASKING_MINUS2:
378 case SEQLOC_MASKING_MINUS3:
379 ValNodeAddPointer(&mask_loc, vnp->choice, vnp->data.ptrvalue);
380 break;
381 default:
382 break;
383 }
384 }
385
386 mask_loc_start = mask_loc;
387
388 /* If results come as alignment endpoints only from Mega BLAST */
389 if (mb_results) {
390 MegaBlastHitPtr mb_hit = mb_results->mbhits, next_hit;
391
392 while (mb_hit) {
393 fprintf(stdout, "%s\t%s\t%d\t%d\t%d\t%d\t%d\n", mb_hit->id1,
394 mb_hit->id2, mb_hit->query_offset, mb_hit->subject_offset,
395 mb_hit->query_end, mb_hit->subject_end, mb_hit->score);
396 mb_hit = mb_hit->next;
397 }
398 MegaBlastResultsFree(mb_results);
399 } else if (!seqalign) {
400 done = FALSE;
401 }
402
403 ReadDBBioseqFetchEnable ("blastall", database, db_is_na, TRUE);
404 ReadDBBioseqSetDbGeneticCode(theInfo->options->db_genetic_code);
405
406 tmp_slp = slp;
407
408 if(theInfo->xml_output)
409 xml_aip = AsnIoOpen("stdout", "wx");
410
411 if (tabular_output) {
412 if (theInfo->align_view == HitTableWithHeader)
413 PrintTabularOutputHeader(database, bsp, slp,
414 (options->is_megablast_search ? "megablast" : program),
415 0, FALSE, stdout);
416
417 BlastPrintTabulatedResults(seqalign, bsp, slp,
418 theInfo->number_of_alignments,
419 program,
420 !theInfo->options->gapped_calculation,
421 FALSE, 0, 0, stdout,
422 (theInfo->align_view == HitTableWithHeader));
423 SeqAlignSetFree(seqalign);
424 } else {
425 Int4 query_number = 1;
426 while (seqalign) {
427 if (!options->is_megablast_search)
428 next_seqalign = NULL;
429 else {
430 SeqIdPtr seqid = TxGetQueryIdFromSeqAlign(seqalign);
431 sap = seqalign;
432 while (sap != NULL) {
433 if (sap->next != NULL) {
434 if (SeqIdComp(seqid, TxGetQueryIdFromSeqAlign(sap->next)
435 != SIC_YES)) {
436 next_seqalign = sap->next;
437 sap->next = NULL;
438 }
439 } else {
440 next_seqalign = NULL;
441 }
442 sap = sap->next;
443 }
444 /* Find this query's SeqLoc and Bioseq */
445 while (tmp_slp && SeqIdComp(seqid, SeqLocId(tmp_slp)) != SIC_YES)
446 tmp_slp = tmp_slp->next;
447 if (tmp_slp == NULL) /* Should never happen */
448 break;
449 bsp = BioseqLockById(SeqLocId(tmp_slp));
450 init_buff_ex(85);
451 fprintf(stdout, "<HR><BR>");
452 AcknowledgeBlastQuery(bsp, 70, stdout, FALSE, TRUE);
453 free_buff();
454 BioseqUnlock(bsp);
455
456 /* Separate the mask locations list for this query. */
457 if (mask_loc) {
458 mask_slp = (SeqLocPtr) mask_loc->data.ptrvalue;
459 while (SeqIdComp(SeqLocId(mask_slp), seqid) != SIC_YES) {
460 mask_loc = mask_loc->next;
461 if (!mask_loc)
462 break;
463 mask_slp = (SeqLocPtr) mask_loc->data.ptrvalue;
464 }
465 if (mask_loc) {
466 next_mask_loc = mask_loc->next;
467 mask_loc->next = NULL;
468 }
469 }
470 }
471
472 if(theInfo->xml_output) {
473 printf("<PRE>");
474 BXMLPrintOutput(xml_aip, seqalign, options,
475 program, database,
476 bsp, other_returns, 0, NULL, mask_loc);
477 AsnIoReset(xml_aip);
478 printf("</PRE>");
479
480 } else {
481
482 seqannot = SeqAnnotNew();
483 seqannot->type = 2;
484 AddAlignInfoToSeqAnnot(seqannot, align_type);
485 seqannot->data = seqalign;
486
487 if(theInfo->show_overview) {
488 Char f_name[64], title[1024], href[64], form_name[16];
489 Int4 align_num;
490
491 sprintf(f_name, "%ld%ld.gif", (long)random(), (long)getpid());
492 sprintf(href, "nph-viewgif.cgi?");
493
494 align_num = get_number_alignment(seqalign);
495 sprintf(title,
496 "<H3><a href=\"%s/blast/docs/newoptions.html#graphical-overview\"> "
497 "Distribution of %ld Blast Hits on the Query Sequence</a> "
498 "</H3>\n", theInfo->www_root_path, (long)align_num);
499
500 /* Open HTML form */
501 sprintf(form_name, "BLASTFORM%ld", query_number);
502 fprintf(stdout, "<FORM NAME=\"%s\">\n", form_name);
503 fflush(stdout);
504
505 PrintOneAlignmentOverview(seqannot, stdout, form_name, href, f_name,
506 title, query_number);
507 ++query_number;
508 }
509
510 prune = BlastPruneHitsFromSeqAlign(seqalign, theInfo->number_of_descriptions, NULL);
511 ObjMgrSetHold();
512 init_buff_ex(85);
513
514 PrintDefLinesFromSeqAlignWithPath(prune->sap, 80, stdout,
515 theInfo->print_options, FIRST_PASS, NULL,
516 theInfo->number_of_descriptions, database,
517 theInfo->www_blast_type, theInfo->www_root_path);
518 free_buff();
519
520 prune = BlastPruneHitsFromSeqAlign(seqalign, theInfo->number_of_alignments, prune);
521 seqannot->data = prune->sap;
522
523 if(theInfo->color_schema != 0 &&
524 (!StringICmp(program, "blastn") ||
525 !StringICmp(program, "blastp"))) {
526
527 if(!DDV_DisplayBlastPairList(prune->sap, mask_loc, stdout,
528 query_is_na, align_options,
529 theInfo->color_schema)) {
530 fprintf(stdout,
531 "\n\n!!!\n "
532 " -------- Failure to print alignment... --------"
533 "\n!!!\n\n");
534 fflush(stdout);
535 }
536 } else {
537
538 if(options->is_ooframe) {
539 printf("<PRE>");
540 OOFShowBlastAlignment(seqalign, /*mask*/ NULL,
541 stdout, align_options, txmatrix);
542 } else {
543 if (align_options & TXALIGN_MASTER) {
544 ShowTextAlignFromAnnot2(seqannot, 60, stdout, f_order,
545 g_order, align_options, txmatrix, mask_loc, NULL,
546 NULL, theInfo->www_blast_type);
547 } else {
548 ShowTextAlignFromAnnot2(seqannot, 60, stdout, f_order,
549 g_order, align_options, txmatrix, mask_loc,
550 FormatScoreFunc, NULL, theInfo->www_blast_type);
551 }
552 }
553 }
554
555 seqannot->data = seqalign;
556 number_of_hits_private = prune->original_number;
557 prune = BlastPruneSapStructDestruct(prune);
558 ObjMgrClearHold();
559 ObjMgrFreeCache(0);
560 } /* If else xml_output */
561
562 if (options->is_megablast_search) {
563 tmp_slp = tmp_slp->next;
564
565 /* Reconnect the mask locations */
566 if (next_mask_loc) {
567 mask_loc->next = next_mask_loc;
568 mask_loc = next_mask_loc;
569 }
570 }
571
572 if (seqannot)
573 seqannot = SeqAnnotFree(seqannot);
574 seqalign = next_seqalign;
575 fprintf(stdout, "<PRE>\n</form>\n");
576 }
577 } /* End if not hit table */
578 if (!done) { /* seqalign == NULL */
579 if(theInfo->xml_output && !options->is_ooframe) {
580 BlastErrorMsgPtr error_msg;
581 CharPtr message;
582
583 if (error_returns == NULL) {
584 message = "No hits found";
585 } else {
586 error_msg = error_returns->data.ptrvalue;
587 message = error_msg->msg;
588 }
589
590 BXMLPrintOutput(xml_aip, NULL,
591 options, program, database,
592 bsp, other_returns, 0, message, NULL);
593
594 if (error_returns != NULL) {
595 MemFree(error_msg->msg);
596 MemFree(error_msg);
597 MemFree(error_returns);
598 }
599
600 AsnIoReset(xml_aip);
601 } else if (!tabular_output) {
602 fprintf(stdout, "\n\n ***** No hits found ******\n\n");
603 }
604 }
605 if(theInfo->xml_output)
606 xml_aip = AsnIoClose(xml_aip);
607
608 BLAST_MatrixDestruct(matrix);
609 if (txmatrix)
610 txmatrix = TxMatrixDestruct(txmatrix);
611
612 for (mask_loc = mask_loc_start; mask_loc; mask_loc = mask_loc->next) {
613 SeqLocSetFree(mask_loc->data.ptrvalue);
614 }
615 ValNodeFree(mask_loc_start);
616
617 init_buff_ex(85);
618 tx_dbinfo_head = tx_dbinfo;
619 if (!tabular_output &&
620 !(options->is_megablast_search && options->no_traceback)) {
621 while (tx_dbinfo) {
622 PrintDbReport(tx_dbinfo, 70, stdout);
623 tx_dbinfo = tx_dbinfo->next;
624 }
625 }
626 tx_dbinfo_head = TxDfDbInfoDestruct(tx_dbinfo_head);
627
628 if (ka_params) {
629 if (!tabular_output &&
630 !(options->is_megablast_search && options->no_traceback))
631 PrintKAParameters(ka_params->lambda, ka_params->k, ka_params->h,
632 70, stdout, FALSE);
633 MemFree(ka_params);
634 }
635 if (ka_params_gap) {
636 if (!tabular_output &&
637 !(options->is_megablast_search && options->no_traceback))
638 PrintKAParameters(ka_params_gap->lambda, ka_params_gap->k, ka_params_gap->h, 70, stdout, TRUE);
639 MemFree(ka_params_gap);
640 }
641
642 if (!tabular_output &&
643 !(options->is_megablast_search && options->no_traceback))
644 PrintTildeSepLines(params_buffer, 70, stdout);
645
646 printf("</PRE></BODY></HTML>\n");
647 MemFree(params_buffer);
648 free_buff();
649
650 other_returns = ValNodeFree(other_returns);
651
652 return status;
653 }
654
655 static Boolean
TraditionalBlastReportWithImage(BioseqPtr bsp,BlastNet3Hptr bl3hp,WWWBlastInfoPtr theInfo)656 TraditionalBlastReportWithImage(BioseqPtr bsp, BlastNet3Hptr bl3hp,
657 WWWBlastInfoPtr theInfo)
658 {
659 return TraditionalBlastReportEngineWithImage(NULL, bsp, bl3hp, theInfo);
660 }
661 static Boolean
TraditionalBlastReportLocWithImage(SeqLocPtr slp,BlastNet3Hptr bl3hp,WWWBlastInfoPtr theInfo)662 TraditionalBlastReportLocWithImage(SeqLocPtr slp, BlastNet3Hptr bl3hp,
663 WWWBlastInfoPtr theInfo)
664 {
665 return TraditionalBlastReportEngineWithImage(slp, NULL, bl3hp, theInfo);
666 }
667
WWWBlastDoClientSearch(WWWBlastInfoPtr theInfo)668 Boolean WWWBlastDoClientSearch(WWWBlastInfoPtr theInfo)
669 {
670 BlastNet3Hptr bl3hp;
671 BlastResponsePtr response;
672 BlastVersionPtr blast_version;
673 CharPtr date, motd, version;
674 Boolean status;
675
676 if(theInfo == NULL)
677 return FALSE;
678
679 if (!BlastInit("blastcl3", &bl3hp, &response)) {
680 WWWBlastErrMessage(BLASTErrClient, NULL);
681 return FALSE;
682 }
683
684 if (response && response->choice == BlastResponse_init) {
685 blast_version = response->data.ptrvalue;
686 version = blast_version->version;
687 date = blast_version->date;
688 } else {
689 WWWBlastErrMessage(BLASTErrClient, NULL);
690 return FALSE;
691 }
692
693 BlastNetBioseqFetchEnable(bl3hp, theInfo->database,
694 theInfo->db_is_na, TRUE);
695
696 #ifdef BLAST_PRINT_MOTD
697 motd = Blast3GetMotd(bl3hp);
698 PrintMotd(motd, stdout, TRUE);
699 motd = MemFree(motd);
700 #endif
701
702 if (!theInfo->options->is_megablast_search)
703 status = TraditionalBlastReportWithImage(theInfo->fake_bsp, bl3hp, theInfo);
704 else
705 status = TraditionalBlastReportLocWithImage(theInfo->query_slp, bl3hp, theInfo);
706 if (status == FALSE) {
707 WWWBlastErrMessage(BLASTErrServer, NULL);
708 return FALSE;
709 }
710
711 return TRUE;
712 }
713 #endif
714
715 #define BUFFER_LENGTH 255
716
717 static int LIBCALLBACK
AppendMegaBlastHit(VoidPtr ptr)718 AppendMegaBlastHit(VoidPtr ptr)
719 {
720 BlastSearchBlkPtr search = (BlastSearchBlkPtr) ptr;
721 SeqIdPtr subject_id, query_id;
722 CharPtr subject_descr, subject_buffer;
723 Int4 index, query_length;
724 Int2 context;
725 BLAST_HSPPtr hsp;
726 MegaBlastResultsPtr mb_results;
727 MegaBlastHitPtr new_hit, last_hit = NULL;
728
729 if (search->current_hitlist == NULL || search->current_hitlist->hspcnt <= 0) {
730 search->subject_info = BLASTSubjectInfoDestruct(search->subject_info);
731 return 0;
732 }
733
734 mb_results = (MegaBlastResultsPtr)
735 search->mb_endpoint_results->data.ptrvalue;
736 if (mb_results) {
737 for (last_hit = mb_results->mbhits; last_hit->next;
738 last_hit = last_hit->next);
739 }
740 readdb_get_descriptor(search->rdfp, search->subject_id, &subject_id,
741 &subject_descr);
742 if (subject_id->choice != SEQID_GENERAL) {
743 subject_buffer = (CharPtr) Malloc(BUFFER_LENGTH + 1);
744 SeqIdWrite(SeqIdFindBestAccession(subject_id), subject_buffer,
745 PRINTID_TEXTID_ACC_VER, BUFFER_LENGTH);
746 } else {
747 subject_buffer = StringTokMT(subject_descr, " ", &subject_descr);
748 subject_descr = subject_buffer;
749 }
750
751 for (index=0; index<search->current_hitlist->hspcnt; index++) {
752 hsp = search->current_hitlist->hsp_array[index];
753 if (hsp==NULL || (search->pbp->cutoff_e > 0 &&
754 hsp->evalue > search->pbp->cutoff_e))
755 continue;
756 new_hit = Malloc(sizeof(MegaBlastHit));
757 new_hit->next = NULL;
758 context = hsp->context;
759 query_id = search->qid_array[context/2];
760
761 new_hit->id2 = StringSave(subject_buffer);
762 if (query_id->choice == SEQID_LOCAL) {
763 BioseqPtr query_bsp = BioseqLockById(query_id);
764 CharPtr title = StringSave(BioseqGetTitle(query_bsp));
765 if (title) {
766 new_hit->id1 = StringTokMT(title, " ", &title);
767 } else {
768 Int4 query_gi;
769 Boolean numeric_query_id =
770 GetAccessionFromSeqId(query_bsp->id, &query_gi,
771 &new_hit->id1);
772 if (numeric_query_id) {
773 new_hit->id1 = Malloc(10);
774 sprintf(new_hit->id1, "%d", query_gi);
775 }
776 }
777 BioseqUnlock(query_bsp);
778 } else {
779 new_hit->id1 = (CharPtr) Malloc(BUFFER_LENGTH + 1);
780 SeqIdWrite(SeqIdFindBestAccession(query_id), new_hit->id1,
781 PRINTID_TEXTID_ACC_VER, BUFFER_LENGTH);
782 }
783 query_length = search->query_context_offsets[context+1] -
784 search->query_context_offsets[context] - 1;
785 if (context & 1) {
786 new_hit->query_end = query_length - hsp->query.offset;
787 new_hit->query_offset =
788 new_hit->query_end - hsp->query.length + 1;
789 } else {
790 new_hit->query_offset = hsp->query.offset + 1;
791 new_hit->query_end = new_hit->query_offset + hsp->query.length - 1;
792 }
793
794 new_hit->subject_offset = hsp->subject.offset + 1;
795 new_hit->subject_end = hsp->subject.end;
796
797 if (search->pbp->gap_open==0 && search->pbp->gap_extend==0)
798 new_hit->score = ((hsp->subject.length + hsp->query.length)*
799 search->sbp->reward / 2 - hsp->score) /
800 (search->sbp->reward - search->sbp->penalty);
801 else
802 new_hit->score = hsp->score;
803 if (last_hit == NULL) {
804 last_hit = new_hit;
805 mb_results = MemNew(sizeof(MegaBlastResults));
806 mb_results->mbhits = last_hit;
807 search->mb_endpoint_results->data.ptrvalue = mb_results;
808 } else {
809 last_hit->next = new_hit;
810 last_hit = last_hit->next;
811 }
812 }
813 return 0;
814 }
815
WWWBlastDoSearch(WWWBlastInfoPtr theInfo)816 Boolean WWWBlastDoSearch(WWWBlastInfoPtr theInfo)
817 {
818 SeqAlignPtr seqalign = NULL;
819 ValNodePtr mask_loc = NULL, mask_loc_start, next_mask_loc = NULL;
820 SeqLocPtr mask_slp = NULL;
821 ValNodePtr vnp, other_returns, error_returns;
822 TxDfDbInfoPtr dbinfo=NULL, dbinfo_head;
823 BLAST_KarlinBlkPtr ka_params=NULL, ka_params_gap=NULL;
824 BLAST_MatrixPtr matrix;
825 Int4Ptr PNTR txmatrix;
826 CharPtr params_buffer=NULL;
827 SeqAnnotPtr seqannot = NULL;
828 BlastPruneSapStructPtr prune;
829 SeqAlignPtr PNTR seqalignp = NULL;
830 Boolean is_megablast, done = FALSE, all_done = FALSE;
831 SeqLocPtr query_slp, query_lcase_mask, lcase_mask;
832 Int4 index;
833 AsnIoPtr xml_aip;
834 MegaBlastResultsPtr mb_results = NULL;
835 BLAST_OptionsBlkPtr options = theInfo->options;
836 Boolean tabular_output = (theInfo->align_view == HitTable ||
837 theInfo->align_view == HitTableWithHeader);
838 MBXmlPtr mbxp = NULL;
839 int LIBCALLBACK (*callback)(Int4, Int4);
840 Int4 query_number;
841
842 if(theInfo == NULL)
843 return FALSE;
844
845 is_megablast = options->is_megablast_search;
846
847 query_slp = theInfo->query_slp;
848 lcase_mask = query_lcase_mask = options->query_lcase_mask;
849
850 if(!theInfo->xml_output && !tabular_output &&
851 !(is_megablast && options->no_traceback)) {
852 PrintDbInformation(theInfo->database, !theInfo->db_is_na,
853 70, stdout, TRUE);
854 }
855
856 if(!tabular_output && options->entrez_query != NULL &&
857 theInfo->gi_list_total > 0) {
858
859 printf("Your search was limited by an Entrez query: '%s'\n"
860 "<!-- %d sequences-->\n<P>\n",
861 options->entrez_query,
862 theInfo->gi_list_total);
863 }
864
865 ReadDBBioseqFetchEnable ("blastall", theInfo->database,
866 theInfo->db_is_na, TRUE);
867
868 if(theInfo->xml_output)
869 xml_aip = AsnIoOpen("stdout", "wx");
870
871 while (!all_done) { /* Loop on complete BLAST searches */
872 if (!query_slp || is_megablast)
873 all_done = TRUE;
874
875 other_returns = NULL;
876 error_returns = NULL;
877
878 if(!theInfo->xml_output) {
879 printf("</PRE>\n");
880 callback = WWWTickCallback;
881 } else {
882 callback = WWWXMLTickCallback;
883 }
884
885 if (!is_megablast) {
886 if (SeqIdComp(SeqLocId(lcase_mask), SeqLocId(query_slp)) ==
887 SIC_YES) {
888 options->query_lcase_mask = (SeqLocPtr) ValNodeNew(NULL);
889 MemCpy(options->query_lcase_mask, lcase_mask, sizeof(SeqLoc));
890 options->query_lcase_mask->next = NULL;
891 lcase_mask = lcase_mask->next;
892 }
893 if (query_slp) {
894 seqalign = BioseqBlastEngineByLocEx(query_slp, theInfo->program, theInfo->database, options, &other_returns, &error_returns, callback, NULL, theInfo->gi_list, theInfo->gi_list_total);
895 } else {
896 seqalign = BioseqBlastEngineEx(theInfo->fake_bsp, theInfo->program, theInfo->database, options, &other_returns, &error_returns, callback, NULL, theInfo->gi_list, theInfo->gi_list_total);
897 }
898 } else {
899 if (options->no_traceback)
900 seqalignp = BioseqMegaBlastEngineByLoc(query_slp, theInfo->program, theInfo->database, options, &other_returns, &error_returns, callback, NULL, theInfo->gi_list, theInfo->gi_list_total, AppendMegaBlastHit);
901 else
902 seqalignp = BioseqMegaBlastEngineByLoc(query_slp, theInfo->program, theInfo->database, options, &other_returns, &error_returns, callback, NULL, theInfo->gi_list, theInfo->gi_list_total, NULL);
903 }
904
905 if(!theInfo->xml_output)
906 printf("<PRE>");
907
908 BlastErrorPrint(error_returns);
909
910 dbinfo = NULL;
911 ka_params = NULL;
912 ka_params_gap = NULL;
913 params_buffer = NULL;
914 mask_loc = NULL;
915 matrix = NULL;
916 txmatrix = NULL;
917 for (vnp=other_returns; vnp; vnp = vnp->next) {
918 switch (vnp->choice) {
919 case TXDBINFO:
920 dbinfo = vnp->data.ptrvalue;
921 break;
922 case TXKABLK_NOGAP:
923 ka_params = vnp->data.ptrvalue;
924 break;
925 case TXKABLK_GAP:
926 ka_params_gap = vnp->data.ptrvalue;
927 break;
928 case TXPARAMETERS:
929 params_buffer = vnp->data.ptrvalue;
930 break;
931 case TXMATRIX:
932 matrix = vnp->data.ptrvalue;
933 if (matrix)
934 txmatrix = (Int4Ptr PNTR) BlastMatrixToTxMatrix(matrix);
935 break;
936 case SEQLOC_MASKING_NOTSET:
937 case SEQLOC_MASKING_PLUS1:
938 case SEQLOC_MASKING_PLUS2:
939 case SEQLOC_MASKING_PLUS3:
940 case SEQLOC_MASKING_MINUS1:
941 case SEQLOC_MASKING_MINUS2:
942 case SEQLOC_MASKING_MINUS3:
943 ValNodeAddPointer(&mask_loc, vnp->choice, vnp->data.ptrvalue);
944 break;
945 case BlastResponse_mbalign:
946 mb_results = (MegaBlastResultsPtr) vnp->data.ptrvalue;
947 break;
948 default:
949 break;
950 }
951 }
952
953 fflush(stdout);
954
955 if (mb_results) {
956 /* Results come as alignment endpoints only from Mega BLAST */
957 MegaBlastHitPtr mb_hit = mb_results->mbhits, next_hit;
958
959 while (mb_hit) {
960 fprintf(stdout, "%s\t%s\t%d\t%d\t%d\t%d\t%d\n", mb_hit->id1,
961 mb_hit->id2, mb_hit->query_offset, mb_hit->subject_offset,
962 mb_hit->query_end, mb_hit->subject_end, mb_hit->score);
963 next_hit = mb_hit->next;
964 MemFree(mb_hit->id1);
965 MemFree(mb_hit->id2);
966 MemFree(mb_hit);
967 mb_hit = next_hit;
968 }
969 MemFree(mb_results);
970 done = TRUE;
971 } else
972 done = FALSE;
973
974 if (theInfo->xml_output && is_megablast) {
975 mbxp = PSIXmlInit(xml_aip, "megablast", theInfo->database,
976 options, theInfo->fake_bsp, 0);
977 }
978
979 ReadDBBioseqSetDbGeneticCode(theInfo->options->db_genetic_code);
980 query_number = 1;
981
982 mask_loc_start = mask_loc;
983
984 for (index=0; !done; index++) {
985 if (is_megablast)
986 seqalign = seqalignp[index];
987 else
988 done = TRUE;
989 if (seqalign) {
990 /* Separate the mask locations list for this query, if there
991 are multiple queries. */
992 if (mask_loc) {
993 SeqIdPtr seqid = TxGetQueryIdFromSeqAlign(seqalign);
994 mask_slp = (SeqLocPtr) mask_loc->data.ptrvalue;
995 while (SeqIdComp(SeqLocId(mask_slp), seqid) != SIC_YES) {
996 mask_loc = mask_loc->next;
997 if (!mask_loc)
998 break;
999 mask_slp = (SeqLocPtr) mask_loc->data.ptrvalue;
1000 }
1001 if (mask_loc) {
1002 next_mask_loc = mask_loc->next;
1003 mask_loc->next = NULL;
1004 }
1005 }
1006 if(theInfo->xml_output) {
1007 if (!is_megablast) {
1008 BXMLPrintOutput(xml_aip, seqalign, options,
1009 theInfo->program, theInfo->database,
1010 theInfo->fake_bsp, other_returns, 0, NULL, mask_loc);
1011 AsnIoReset(xml_aip);
1012 } else {
1013 IterationPtr iterp;
1014 BioseqPtr bsp = BioseqLockById(SeqLocId(query_slp));
1015
1016 iterp = BXMLBuildOneQueryIteration(seqalign,
1017 NULL, FALSE,
1018 !options->gapped_calculation, index,
1019 NULL, bsp, mask_loc);
1020 IterationAsnWrite(iterp, mbxp->aip, mbxp->atp);
1021 AsnIoFlush(mbxp->aip);
1022 IterationFree(iterp);
1023
1024 BioseqUnlock(bsp);
1025 }
1026 } else if (tabular_output) {
1027 if (theInfo->align_view == HitTableWithHeader)
1028 PrintTabularOutputHeader(theInfo->database,
1029 theInfo->fake_bsp, query_slp,
1030 (options->is_megablast_search ?
1031 "megablast" : theInfo->program),
1032 0, FALSE, stdout);
1033
1034 BlastPrintTabulatedResults(seqalign, theInfo->fake_bsp,
1035 query_slp, theInfo->number_of_alignments,
1036 theInfo->program,
1037 !theInfo->options->gapped_calculation, FALSE,
1038 0, 0, stdout,
1039 (theInfo->align_view == HitTableWithHeader));
1040 } else {
1041 seqannot = SeqAnnotNew();
1042 seqannot->type = 2;
1043 AddAlignInfoToSeqAnnot(seqannot, theInfo->align_type);
1044 seqannot->data = seqalign;
1045
1046 #if !defined(NCBI_CLIENT_SERVER) && defined (NCBI_ENTREZ_CLIENT)
1047 if(theInfo->show_tax_blast) {
1048 fprintf(stdout, "<a href=#taxblast>Taxonomy reports</a><BR>");
1049 }
1050 #endif
1051
1052 if (is_megablast || query_slp) {
1053 BioseqPtr bsp = BioseqLockById(SeqLocId(query_slp));
1054 init_buff_ex(85);
1055 fprintf(stdout, "<HR><BR>");
1056 AcknowledgeBlastQuery(bsp, 70, stdout, FALSE, TRUE);
1057 free_buff();
1058 BioseqUnlock(bsp);
1059 }
1060
1061 /* Now printing nice gif with alignment overview */
1062
1063 if(theInfo->show_overview) {
1064 Char f_name[64], title[1024], href[64], form_name[16];
1065 Int4 align_num;
1066
1067 sprintf(f_name, "%ld%ld.gif", (long)random(), (long)getpid());
1068 sprintf(href, "nph-viewgif.cgi?");
1069
1070 align_num = get_number_alignment(seqalign);
1071 sprintf(title,
1072 "<H3><a href=\"%s/blast/docs/newoptions.html#graphical-overview\"> "
1073 "Distribution of %ld Blast Hits on the Query Sequence</a> "
1074 "</H3>\n",
1075 theInfo->www_root_path, (long)align_num);
1076
1077
1078 /* Open HTML form */
1079 sprintf(form_name, "BLASTFORM%d", query_number);
1080 fprintf(stdout, "<FORM NAME=\"%s\">\n", form_name);
1081 fflush(stdout);
1082
1083 PrintOneAlignmentOverview(seqannot, stdout, form_name, href,
1084 f_name, title, query_number);
1085 ++query_number;
1086 }
1087
1088 prune = BlastPruneHitsFromSeqAlign(seqalign, theInfo->number_of_descriptions, NULL);
1089 ObjMgrSetHold();
1090 init_buff_ex(85);
1091 PrintDefLinesFromSeqAlignWithPath(prune->sap, 80, stdout,
1092 theInfo->print_options, FIRST_PASS, NULL, -1,
1093 NULL, theInfo->www_blast_type, theInfo->www_root_path);
1094 free_buff();
1095
1096 prune = BlastPruneHitsFromSeqAlign(seqalign, theInfo->number_of_alignments, prune);
1097 seqannot->data = prune->sap;
1098
1099 if(theInfo->color_schema != 0 &&
1100 (!StringICmp(theInfo->program, "blastn") ||
1101 !StringICmp(theInfo->program, "blastp"))) {
1102
1103 if(!DDV_DisplayBlastPairList(prune->sap, mask_loc, stdout,
1104 theInfo->query_is_na,
1105 theInfo->align_options,
1106 theInfo->color_schema)) {
1107 fprintf(stdout,
1108 "\n\n!!!\n "
1109 " -------- Failure to print alignment... --------"
1110 "\n!!!\n\n");
1111 fflush(stdout);
1112 }
1113 } else {
1114
1115 if(options->is_ooframe) {
1116 printf("<PRE>");
1117 OOFShowBlastAlignment(seqalign, /*mask*/ NULL,
1118 stdout, theInfo->align_options, txmatrix);
1119 } else {
1120 if (theInfo->align_view != 0) {
1121 ShowTextAlignFromAnnot2(seqannot, 60, stdout,
1122 NULL, NULL, theInfo->align_options,
1123 txmatrix, mask_loc, NULL, NULL,
1124 theInfo->www_blast_type);
1125 } else {
1126 ShowTextAlignFromAnnot2(seqannot, 60, stdout,
1127 NULL, NULL, theInfo->align_options,
1128 txmatrix, mask_loc, FormatScoreFunc,
1129 NULL, theInfo->www_blast_type);
1130 }
1131 }
1132 }
1133 seqannot->data = NULL; /* Don't want to delete seqalign yet */
1134 prune = BlastPruneSapStructDestruct(prune);
1135 ObjMgrClearHold();
1136 ObjMgrFreeCache(0);
1137 }
1138 /* Reconnect the mask locations, in case of multiple queries */
1139 if (next_mask_loc) {
1140 mask_loc->next = next_mask_loc;
1141 mask_loc = next_mask_loc;
1142 }
1143 } else if (!is_megablast) { /* while(seqalign) */
1144 /* seqalign == NULL */
1145
1146 if(theInfo->xml_output && !options->is_ooframe) {
1147 BlastErrorMsgPtr error_msg;
1148 CharPtr message;
1149
1150 if (error_returns == NULL) {
1151 message = "No hits found";
1152 } else {
1153 error_msg = error_returns->data.ptrvalue;
1154 message = error_msg->msg;
1155 }
1156
1157 BXMLPrintOutput(xml_aip, NULL,
1158 options, theInfo->program,
1159 theInfo->database,
1160 theInfo->fake_bsp, other_returns,
1161 0, message, NULL);
1162
1163 if (error_returns != NULL) {
1164 MemFree(error_msg->msg);
1165 MemFree(error_msg);
1166 MemFree(error_returns);
1167 }
1168
1169 AsnIoReset(xml_aip);
1170 } else {
1171 fprintf(stdout, "\n\n ***** No hits found ******\n\n");
1172 }
1173 }
1174
1175 if (is_megablast) {
1176 query_slp = query_slp->next;
1177 if (!query_slp)
1178 done = TRUE;
1179 }
1180 if(!theInfo->xml_output) {
1181 seqannot = SeqAnnotFree(seqannot);
1182 fprintf(stdout, "</form>\n");
1183 }
1184 }
1185
1186 matrix = BLAST_MatrixDestruct(matrix);
1187 if (txmatrix)
1188 txmatrix = (Int4Ptr PNTR) TxMatrixDestruct(txmatrix);
1189
1190 dbinfo_head = dbinfo;
1191 if(!theInfo->xml_output && !tabular_output &&
1192 !(is_megablast && options->no_traceback)) {
1193 fprintf(stdout, "<PRE>");
1194 init_buff_ex(85);
1195 while (dbinfo) {
1196 PrintDbReport(dbinfo, 70, stdout);
1197 dbinfo = dbinfo->next;
1198 }
1199 }
1200
1201 dbinfo_head = TxDfDbInfoDestruct(dbinfo_head);
1202
1203 if (ka_params) {
1204 if(!theInfo->xml_output && !tabular_output &&
1205 !(is_megablast && options->no_traceback)) {
1206 PrintKAParameters(ka_params->Lambda, ka_params->K,
1207 ka_params->H, 70, stdout, FALSE);
1208 }
1209 MemFree(ka_params);
1210 }
1211
1212 if (ka_params_gap) {
1213 if(!theInfo->xml_output && !tabular_output &&
1214 !(is_megablast && options->no_traceback)) {
1215 PrintKAParameters(ka_params_gap->Lambda, ka_params_gap->K,
1216 ka_params_gap->H, 70, stdout, TRUE);
1217 }
1218 MemFree(ka_params_gap);
1219 }
1220
1221 if(!theInfo->xml_output && !tabular_output &&
1222 !(is_megablast && options->no_traceback)) {
1223
1224 PrintTildeSepLines(params_buffer, 70, stdout);
1225
1226 #if !defined(NCBI_CLIENT_SERVER) && defined (NCBI_ENTREZ_CLIENT)
1227
1228 fprintf(stdout, "<HR>\n");
1229
1230 if( !tabular_output && theInfo->show_tax_blast) {
1231 TXBHtmlReport(seqalign, stdout, theInfo->query_is_na,
1232 theInfo->db_is_na, theInfo->database,
1233 NULL, NULL, theInfo->show_gi);
1234 }
1235
1236 #endif
1237 }
1238
1239 if (is_megablast) {
1240 Int4 i;
1241 for (i=0; i<index; i++)
1242 SeqAlignSetFree(seqalignp[i]);
1243 MemFree(seqalignp);
1244 } else if(seqalign != NULL)
1245 seqalign = SeqAlignSetFree(seqalign);
1246
1247 MemFree(params_buffer);
1248 free_buff();
1249
1250 for (mask_loc = mask_loc_start; mask_loc; mask_loc = mask_loc->next) {
1251 SeqLocSetFree(mask_loc->data.ptrvalue);
1252 }
1253 ValNodeFree(mask_loc_start);
1254
1255 other_returns = ValNodeFree(other_returns);
1256
1257 if (!is_megablast && query_slp) {
1258 query_slp = query_slp->next;
1259 if (!query_slp)
1260 all_done = TRUE;
1261 }
1262 } /* End of loop over all searches */
1263
1264 SeqLocSetFree(query_lcase_mask);
1265
1266 if (theInfo->xml_output) {
1267 if (is_megablast && mbxp != NULL)
1268 MBXmlClose(mbxp, other_returns, !options->gapped_calculation);
1269 }
1270 ReadDBBioseqFetchDisable();
1271
1272 if (!theInfo->xml_output)
1273 fprintf(stdout, "</PRE>\n</BODY>\n</HTML>\n");
1274
1275 return TRUE;
1276 }
1277
WWWBlastPrintTopHeader(WWWBlastInfoPtr theInfo)1278 static void WWWBlastPrintTopHeader(WWWBlastInfoPtr theInfo)
1279 {
1280 fprintf(stdout, "<HTML>\n");
1281 fprintf(stdout, "<TITLE>BLAST Search Results</TITLE>\n");
1282 fflush(stdout);
1283
1284 fprintf(stdout, "<BODY BGCOLOR=\"#FFFFFF\" LINK=\"#0000FF\" "
1285 "VLINK=\"#660099\" ALINK=\"#660099\">\n");
1286 fprintf(stdout, "<map name=img_map0>\n");
1287 fprintf(stdout, "<area shape=rect coords=2,1,48,21 "
1288 "href=\"http://www.ncbi.nlm.nih.gov\">\n");
1289 fprintf(stdout, "<area shape=rect coords=385,1,435,21 "
1290 "href=\"%s/blast/index.html\">\n", theInfo->www_root_path);
1291 fprintf(stdout, "<area shape=rect coords=436,1,486,21 "
1292 "href=\"http://www.ncbi.nlm.nih.gov/Entrez/\">\n");
1293 fprintf(stdout, "<area shape=rect coords=487,1,508,21 "
1294 "href=\"%s/blast/docs/blast_help.html\">\n", theInfo->www_root_path);
1295 fprintf(stdout, "</map>\n");
1296 fprintf(stdout, "<IMG USEMAP=#img_map0 WIDTH=509 HEIGHT=22 "
1297 "SRC=\"%s/blast/images/blast_results.gif\" ISMAP> \n",
1298 theInfo->www_root_path);
1299 }
1300
WWWBlastPrintHeader(WWWBlastInfoPtr theInfo)1301 void WWWBlastPrintHeader(WWWBlastInfoPtr theInfo)
1302 {
1303
1304 fprintf(stdout, "<PRE>\n");
1305 init_buff_ex(90);
1306 if (theInfo->options->is_megablast_search) {
1307 BlastPrintVersionInfo("megablast", TRUE, stdout);
1308 } else if (theInfo->options->is_rps_blast){
1309 BlastPrintVersionInfo("rps-blast", TRUE, stdout);
1310 } else if (theInfo->options->is_ooframe){
1311 BlastPrintVersionInfo("OOF BLASTX", TRUE, stdout);
1312 } else {
1313 BlastPrintVersionInfo(theInfo->program, TRUE, stdout);
1314 fprintf(stdout, "\n");
1315 BlastPrintReference(TRUE, 90, stdout);
1316 }
1317 fprintf(stdout, "\n");
1318 if (!theInfo->options->is_megablast_search && !theInfo->query_slp)
1319 AcknowledgeBlastQuery(theInfo->query_bsp, 70, stdout,
1320 theInfo->believe_query, TRUE);
1321 free_buff();
1322
1323 return;
1324 }
1325
Main(void)1326 Int2 Main(void)
1327 {
1328 WWWBlastInfoPtr theInfo;
1329
1330 UseLocalAsnloadDataAndErrMsg ();
1331
1332 if (! SeqEntryLoad())
1333 return 1;
1334
1335 ErrSetMessageLevel(SEV_WARNING);
1336
1337 /* This function will read posting data, set-up config file and
1338 write small message into logfile (if it exists) */
1339
1340 if((theInfo = WWWBlastReadArgs(NULL)) == NULL)
1341 return 1;
1342
1343 /* Read options into structure */
1344 if(!WWWCreateSearchOptions(theInfo)) {
1345 return 1;
1346 }
1347
1348 if (!theInfo->xml_output)
1349 WWWBlastPrintTopHeader(theInfo);
1350
1351 /* validate them */
1352 if(!WWWValidateOptions(theInfo)) {
1353 return 1;
1354 }
1355
1356 /* Print BLAST Header */
1357
1358 if(!theInfo->xml_output &&
1359 theInfo->align_view != HitTableWithHeader) {
1360 WWWBlastPrintHeader(theInfo);
1361 }
1362
1363 /* Do the search and Format output */
1364
1365 #ifdef NCBI_CLIENT_SERVER
1366 WWWBlastDoClientSearch(theInfo);
1367 #else
1368 WWWBlastDoSearch(theInfo);
1369 #endif
1370
1371 WWWBlastInfoFree(theInfo);
1372
1373 return 0;
1374 }
1375