|
NCBI Home IEB Home C Toolkit docs C++ Toolkit source browser C Toolkit source browser (2) |
NCBI C Toolkit Cross ReferenceC/algo/blast/api/blast_format.c |
source navigation diff markup identifier search freetext search file search |
1 /* $Id: blast_format.c,v 1.118 2009/06/16 20:39:39 madden 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 offical 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 * Author: Ilya Dondoshansky
27 *
28 */
29
30 /** @file blast_format.c
31 * Formatting of BLAST results (SeqAlign)
32 */
33
34 #ifndef SKIP_DOXYGEN_PROCESSING
35 static char const rcsid[] = "$Id: blast_format.c,v 1.118 2009/06/16 20:39:39 madden Exp $";
36 #endif /* SKIP_DOXYGEN_PROCESSING */
37
38 #include <algo/blast/api/blast_format.h>
39 #include <algo/blast/api/blast_seq.h>
40 #include <algo/blast/core/blast_filter.h>
41 #include <algo/blast/core/blast_util.h>
42 #include <algo/blast/api/blast_returns.h>
43 #include <algo/blast/api/blast_seq.h>
44 #include <algo/blast/composition_adjustment/composition_constants.h>
45 #include <readdb.h>
46 #include <txalign.h>
47 #include <blfmtutl.h>
48 #include <xmlblast.h>
49
50
51 /** @addtogroup CToolkitAlgoBlast
52 *
53 * @{
54 */
55
56 /** Allocate and initialize the formatting options structure.
57 * @param program_number Number of the BLAST program [in]
58 * @param align_view What kind of formatted output to show? [in]
59 * @param format_options_ptr The initialized structure [out]
60 */
61 static Int2
62 s_BlastFormattingOptionsNew(EBlastProgramType program_number,
63 EAlignView align_view,
64 BlastFormattingOptions** format_options_ptr)
65 {
66 BlastFormattingOptions* format_options;
67
68 /* For translated RPS blast, the query will be a
69 nucleotide sequence and subject sequences will
70 be protein; thus the formatting must behave as
71 if a blastx search was performed */
72
73 if (program_number == eBlastTypeRpsTblastn)
74 program_number = eBlastTypeBlastx;
75
76 if ((format_options = (BlastFormattingOptions*)
77 calloc(1, sizeof(BlastFormattingOptions))) == NULL)
78 return -1;
79 format_options->believe_query = FALSE;
80
81 if ((program_number == eBlastTypeBlastx ||
82 program_number == eBlastTypeTblastx)
83 && align_view > 0 && align_view < eAlignViewXml)
84 {
85 ErrPostEx(SEV_FATAL, 1, 0, "This alignment view option is not "
86 "supported for blastx or tblastx");
87 sfree(format_options);
88 return -1;
89 }
90
91
92 format_options->print_options = 0;
93 format_options->align_options = 0;
94 format_options->align_options += TXALIGN_COMPRESS;
95 format_options->align_options += TXALIGN_END_NUM;
96
97 if (align_view == eAlignViewPairwise)
98 {
99 format_options->align_options += TXALIGN_MATRIX_VAL;
100 format_options->align_options += TXALIGN_SHOW_QS;
101 }
102 else
103 {
104 format_options->align_options += TXALIGN_MASTER;
105 if (align_view == eAlignViewQueryAnchoredIdent ||
106 align_view == eAlignViewFlatQueryAnchoredIdent)
107 format_options->align_options += TXALIGN_MISMATCH;
108 if (align_view == eAlignViewFlatQueryAnchoredIdent ||
109 align_view == eAlignViewFlatQueryAnchoredNoIdent ||
110 align_view == eAlignViewFlatQueryAnchoredBluntEnds)
111 format_options->align_options += TXALIGN_FLAT_INS;
112 if (align_view == eAlignViewQueryAnchoredBluntEnds ||
113 align_view == eAlignViewFlatQueryAnchoredBluntEnds)
114 format_options->align_options += TXALIGN_BLUNT_END;
115 }
116
117 if (program_number == eBlastTypeBlastx)
118 format_options->align_options += TXALIGN_BLASTX_SPECIAL;
119
120 format_options->align_view = align_view;
121
122 *format_options_ptr = format_options;
123 return 0;
124 }
125
126 Int2
127 BlastPrintLogReport(FILE* outfp, Int4 num_processed)
128 {
129 if (!outfp)
130 return -1;
131
132 /* Index of the next query to be processed is equal to the number of
133 queries processed so far. */
134 fprintf(outfp, "#Mega BLAST run finished, processed %ld queries\n",
135 (long) num_processed);
136
137 return 0;
138 }
139
140 #define BXML_INCLUDE_QUERY 0x1
141
142 /** Creates the header part of an XML report for a BLAST search.
143 * @param program Program name [in]
144 * @param database Database name [in]
145 * @param query_loc Query Seq-loc [in]
146 * @param flags Flag to indicate whether query sequence should be included in
147 * the output. [in]
148 * @param search_param Search parameters [in]
149 */
150 static BlastOutput*
151 s_CreateBlastOutputHead(const char* program, const char* database,
152 SeqLoc* query_loc, Int4 flags,
153 const Blast_SearchParams* search_param)
154 {
155 BlastOutput* boutp;
156 Char buffer[1024];
157 char* program_to_use = NULL;
158
159 if((boutp = BlastOutputNew()) == NULL)
160 return FALSE;
161
162 if (strcmp(program, "rpsblast") == 0)
163 program_to_use = strdup("blastp");
164 else if (strcmp(program, "rpstblastn") == 0)
165 program_to_use = strdup("blastx");
166 else
167 program_to_use = strdup(program);
168
169 /* For optimization BLOSUM62 may be loaded ones */
170 if (query_loc) {
171 SeqId* sip = SeqLocId(query_loc);
172 Bioseq* bsp;
173 SeqIdWrite(sip, buffer, PRINTID_FASTA_LONG, sizeof(buffer));
174 boutp->query_ID = strdup(buffer);
175
176 bsp = BioseqLockById(sip);
177
178 if(bsp != NULL) {
179 if (BioseqGetTitle(bsp) != NULL)
180 boutp->query_def = strdup(BioseqGetTitle(bsp));
181 else
182 boutp->query_def = strdup("No definition line found");
183 }
184 BioseqUnlock(bsp);
185
186 boutp->query_len = SeqLocLen(query_loc);
187
188 if(flags & BXML_INCLUDE_QUERY) {
189 boutp->query_seq = (char *) calloc(boutp->query_len+1, 1);
190 SeqPortStreamLoc(query_loc,
191 STREAM_EXPAND_GAPS | STREAM_CORRECT_INVAL,
192 boutp->query_seq, NULL);
193 } else {
194 boutp->query_seq = NULL; /* Do we need sequence here??? */
195 }
196 }
197 /* Program name. Use the local version of the program. No need to copy it
198 since it was locally allocated. */
199 boutp->program = program_to_use;
200
201 /* Database name */
202 if (database)
203 boutp->db = strdup(database);
204
205 /* Version text */
206 sprintf(buffer, "%s %s [%s]", program_to_use, BlastGetVersionNumber(),
207 BlastGetReleaseDate());
208 boutp->version = strdup(buffer);
209
210 /* Reference */
211 boutp->reference = BlastGetReference(FALSE);
212
213 /* Filling parameters */
214 boutp->param = ParametersNew();
215 boutp->param->expect = search_param->expect;
216 boutp->param->gap_open = search_param->gap_open;
217 boutp->param->gap_extend = search_param->gap_extension;
218 if (search_param->matrix)
219 boutp->param->matrix = strdup(search_param->matrix);
220 boutp->param->sc_match = search_param->match;
221 boutp->param->sc_mismatch = search_param->mismatch;
222 boutp->param->include = search_param->ethresh;
223 if (search_param->filter_string)
224 boutp->param->filter = strdup(search_param->filter_string);
225
226 return boutp;
227 }
228
229 /** Finds ASN.1 type for printing appropriate parts of the XML output. */
230 #define MACRO_atp_find(atp,name)\
231 if((atp = AsnTypeFind(amp, #name))==NULL){\
232 ErrPostEx(SEV_ERROR,0,0,\
233 "Could not find type <%s>", #name);\
234 return NULL; \
235 }
236
237
238 /** Initializes the XML output structure and prints the XML output header.
239 * @param aip ASN.1 output stream [in]
240 * @param program BLAST program name [in]
241 * @param database BLAST database name [in]
242 * @param query_loc Query Seq-loc [in]
243 * @param flags Flag for query sequence inclusion [in]
244 * @param search_params BLAST search parameters [in]
245 * @return Initialized structure for printing XML output.
246 */
247 static MBXml*
248 s_MBXmlInit(AsnIo* aip, char* program, char* database,
249 SeqLoc* query_loc, Int4 flags, Blast_SearchParams* search_params)
250 {
251 MBXml* xmlp;
252 AsnModule* amp;
253 DataVal av;
254 AsnType* atp;
255 Boolean retval = FALSE;
256
257 AsnType* BLASTOUTPUT;
258 AsnType* BLASTOUTPUT_program;
259 AsnType* BLASTOUTPUT_version;
260 AsnType* BLASTOUTPUT_reference;
261 AsnType* BLASTOUTPUT_db;
262 AsnType* BLASTOUTPUT_query_ID;
263 AsnType* BLASTOUTPUT_query_def;
264 AsnType* BLASTOUTPUT_query_len;
265 AsnType* BLASTOUTPUT_query_seq;
266 AsnType* BLASTOUTPUT_param;
267 AsnType* BLASTOUTPUT_iterations;
268 AsnType* BLASTOUTPUT_iterations_E;
269 AsnType* BLASTOUTPUT_mbstat;
270
271 if (strcmp(program, "rpsblast") == 0)
272 program = "blastp";
273 else if (strcmp(program, "rpstblastn") == 0)
274 program = "blastx";
275
276 AsnSetXMLmodulePrefix("http://www.ncbi.nlm.nih.gov/dtd/");
277 xmlp = (MBXml*) MemNew(sizeof(MBXml));
278
279 xmlp->aip = aip;
280
281 if (! bxmlobjAsnLoad()) {
282 return NULL;
283 }
284
285 amp = AsnAllModPtr();
286
287 MACRO_atp_find(BLASTOUTPUT,BlastOutput);
288 MACRO_atp_find(BLASTOUTPUT_program,BlastOutput.program);
289 MACRO_atp_find(BLASTOUTPUT_version,BlastOutput.version);
290 MACRO_atp_find(BLASTOUTPUT_reference,BlastOutput.reference);
291 MACRO_atp_find(BLASTOUTPUT_db,BlastOutput.db);
292 MACRO_atp_find(BLASTOUTPUT_query_ID,BlastOutput.query-ID);
293 MACRO_atp_find(BLASTOUTPUT_query_def,BlastOutput.query-def);
294 MACRO_atp_find(BLASTOUTPUT_query_len,BlastOutput.query-len);
295 MACRO_atp_find(BLASTOUTPUT_query_seq,BlastOutput.query-seq);
296 MACRO_atp_find(BLASTOUTPUT_param,BlastOutput.param);
297 MACRO_atp_find(BLASTOUTPUT_iterations,BlastOutput.iterations);
298 MACRO_atp_find(BLASTOUTPUT_iterations_E,BlastOutput.iterations.E);
299 MACRO_atp_find(BLASTOUTPUT_mbstat,BlastOutput.mbstat);
300
301 /* Start of iterations structure */
302 xmlp->atp = BLASTOUTPUT_iterations_E;
303
304 /* Head of all BlastOutput structure */
305 xmlp->BlastOutput = BLASTOUTPUT;
306
307 /* Head of iterations strucure */
308 xmlp->BlastOutput_iterations = BLASTOUTPUT_iterations;
309
310 /* Head of the final statistics for Mega BLAST */
311 xmlp->BlastOutput_mbstat = BLASTOUTPUT_mbstat;
312
313 xmlp->boutp = s_CreateBlastOutputHead(program, database, query_loc, flags, search_params);
314
315 atp = AsnLinkType(NULL, BLASTOUTPUT); /* link local tree */
316
317 if (atp == NULL) {
318 return NULL;
319 }
320
321 if (! AsnOpenStruct(xmlp->aip, atp, (Pointer) xmlp->boutp)) {
322 return NULL;
323 }
324
325 if (xmlp->boutp->program != NULL) {
326 av.ptrvalue = xmlp->boutp -> program;
327 retval = AsnWrite(xmlp->aip, BLASTOUTPUT_program, &av);
328 }
329
330 if (xmlp->boutp->version != NULL) {
331 av.ptrvalue = xmlp->boutp->version;
332 retval = AsnWrite(xmlp->aip, BLASTOUTPUT_version, &av);
333 }
334
335 if (xmlp->boutp->reference != NULL) {
336 av.ptrvalue = xmlp->boutp->reference;
337 retval = AsnWrite(xmlp->aip, BLASTOUTPUT_reference, &av);
338 }
339
340 if (xmlp->boutp -> db != NULL) {
341 av.ptrvalue = xmlp->boutp->db;
342 retval = AsnWrite(xmlp->aip, BLASTOUTPUT_db, &av);
343 }
344
345 if (xmlp->boutp -> query_ID != NULL) {
346 av.ptrvalue = xmlp->boutp->query_ID;
347 retval = AsnWrite(xmlp->aip, BLASTOUTPUT_query_ID, &av);
348 }
349
350 if (xmlp->boutp->query_def != NULL) {
351 av.ptrvalue = xmlp->boutp->query_def;
352 retval = AsnWrite(xmlp->aip, BLASTOUTPUT_query_def, &av);
353 }
354
355 av.intvalue = xmlp->boutp->query_len;
356 retval = AsnWrite(xmlp->aip, BLASTOUTPUT_query_len, &av);
357
358 if (xmlp->boutp->query_seq != NULL) {
359 av.ptrvalue = xmlp->boutp->query_seq;
360 retval = AsnWrite(xmlp->aip, BLASTOUTPUT_query_seq, &av);
361 }
362
363 if (xmlp->boutp->param != NULL) {
364 if (!ParametersAsnWrite(xmlp->boutp->param,
365 xmlp->aip, BLASTOUTPUT_param)) {
366 return NULL;
367 }
368 }
369
370 if(!AsnOpenStruct(xmlp->aip, BLASTOUTPUT_iterations, NULL))
371 return NULL;
372
373 AsnIoFlush(xmlp->aip);
374
375 return xmlp;
376 }
377
378 /** Fills the Statistics ASN.1 generated structure for the XML report.
379 * @param sum_returns Search summary return data [in]
380 * @param ungapped Is this an ungapped search? [in]
381 * @return Populated structure.
382 */
383 static Statistics*
384 s_XMLBuildStatistics(Blast_SummaryReturn* sum_returns, Boolean ungapped)
385 {
386 Statistics* stat;
387 Blast_DatabaseStats* db_stats = sum_returns->db_stats;
388
389 stat = StatisticsNew();
390
391 stat->eff_space = (double) db_stats->eff_searchsp;
392 stat->hsp_len = db_stats->hsp_length;
393 stat->db_num= db_stats->dbnum;
394 stat->db_len = db_stats->dblength;
395
396 if(ungapped) {
397 if(sum_returns->ka_params != NULL) {
398 stat->lambda = sum_returns->ka_params->Lambda;
399 stat->kappa = sum_returns->ka_params->K;
400 stat->entropy = sum_returns->ka_params->H;
401 }
402 } else {
403 if(sum_returns->ka_params_gap != NULL) {
404 stat->lambda = sum_returns->ka_params_gap->Lambda;
405 stat->kappa = sum_returns->ka_params_gap->K;
406 stat->entropy = sum_returns->ka_params_gap->H;
407 }
408 }
409
410 return stat;
411 }
412
413 /** Fills the Iteration ASN.1 structure, for part of the BLAST XML report
414 * corresponding to one query.
415 * @param seqalign Seq-align list with results [in]
416 * @param sum_returns Search summary data [in]
417 * @param is_ooframe Was out-of-frame gapping used in this search? [in]
418 * @param ungapped Was this an ungapped search? [in]
419 * @param iter_num Index of this "iteration" (query). [in]
420 * @param message Error or warning message [in]
421 * @param query Query Bioseq [in]
422 * @param mask_loc List of masking locations [in]
423 * @return Populated structure.
424 */
425 static Iteration*
426 s_XMLBuildOneQueryIteration(SeqAlign* seqalign,
427 Blast_SummaryReturn* sum_returns,
428 Boolean is_ooframe, Boolean ungapped,
429 Int4 iter_num, char* message,
430 Bioseq* query, ValNode* mask_loc)
431 {
432 Iteration* iterp = IterationNew();
433 iterp->iter_num = iter_num;
434
435 if (query) {
436 char buffer[1024];
437 SeqIdWrite(query->id, buffer, PRINTID_FASTA_LONG, sizeof(buffer));
438 iterp->query_ID = strdup(buffer);
439
440 if(BioseqGetTitle(query) != NULL)
441 iterp->query_def = strdup(BioseqGetTitle(query));
442 else
443 iterp->query_def = strdup("No definition line found");
444
445 iterp->query_len = query->length;
446 }
447
448 if(seqalign != NULL) {
449 iterp->hits =
450 BXMLSeqAlignToHits(seqalign, ungapped, is_ooframe, mask_loc);
451 }
452
453 iterp->stat = s_XMLBuildStatistics(sum_returns, ungapped);
454
455 if (message)
456 iterp->message = strdup(message);
457
458 return iterp;
459 }
460
461 Int2 BlastFormattingInfoNew(EAlignView align_view,
462 const SBlastOptions* search_options,
463 const char* program_name, const char* db_name,
464 const char* outfile_name,
465 BlastFormattingInfo* *info_ptr)
466 {
467 BlastFormattingInfo* info;
468
469 if (!outfile_name || !info_ptr || !search_options ||
470 align_view >= eAlignViewMax)
471 return -1;
472
473 info = *info_ptr =
474 (BlastFormattingInfo*) calloc(1, sizeof(BlastFormattingInfo));
475
476 s_BlastFormattingOptionsNew(search_options->program, align_view,
477 &info->format_options);
478 info->search_options = search_options;
479 info->program_name = strdup(program_name);
480 if (db_name)
481 info->db_name = strdup(db_name);
482
483 if (align_view != eAlignViewXml && align_view < eAlignViewAsnText) {
484 FILE* outfp;
485 if ((outfp = FileOpen(outfile_name, "w")) == NULL)
486 {
487 ErrPostEx(SEV_WARNING, 0, 0, "Unable to open output file %s:", outfile_name);
488 return -1;
489 }
490 info->outfp = outfp;
491 } else {
492 char write_mode[3];
493 /* AsnIoOpen requires a non-const argument, so use a local variable. */
494 char* filename_copy = strdup(outfile_name);
495 if (align_view == eAlignViewXml)
496 strcpy(write_mode, "wx");
497 else if (align_view == eAlignViewAsnText)
498 strcpy(write_mode, "w");
499 else
500 strcpy(write_mode, "wb");
501
502 if ((info->aip = AsnIoOpen(filename_copy, write_mode)) == NULL)
503 {
504 ErrPostEx(SEV_WARNING, 0, 0, "Unable to open output file %s:", filename_copy);
505 return -1;
506 }
507 sfree(filename_copy);
508 }
509 info->is_seqalign_null = TRUE; /* will be updated in BLAST_FormatResults */
510 info->head_on_every_query = FALSE; /* One header for a file is the default. */
511 return 0;
512 }
513
514 Int2 BlastFormattingInfoNewBasic(EAlignView align_view,
515 const BLAST_SummaryOptions* basic_options,
516 SeqLoc* query_seqloc,
517 const char* outfile_name,
518 SBlastOptions* *advanced_options,
519 BlastFormattingInfo* *info_ptr)
520 {
521 Blast_SummaryReturn* extra_returns = Blast_SummaryReturnNew();
522 char* program_name = NULL;
523 Int2 status = 0;
524
525 Blast_SearchOptionsFromSummaryOptions(basic_options, query_seqloc,
526 extra_returns, advanced_options,
527 &program_name);
528
529 Blast_SummaryReturnFree(extra_returns);
530
531 status =
532 BlastFormattingInfoNew(align_view, *advanced_options, program_name,
533 NULL, outfile_name, info_ptr);
534 sfree(program_name);
535 return status;
536 }
537
538 void
539 BlastFormattingInfoSetUpOptions(BlastFormattingInfo* info, Int4 num_descriptions,
540 Int4 num_alignments, Boolean html,
541 Boolean is_megablast, Boolean show_gi,
542 Boolean believe_defline)
543 {
544 ASSERT(info && info->format_options && info->search_options);
545
546 info->format_options->number_of_descriptions = num_descriptions;
547 info->format_options->number_of_alignments = num_alignments;
548 info->format_options->html = html;
549 if (html) {
550 info->format_options->align_options += TXALIGN_HTML;
551 info->format_options->print_options += TXALIGN_HTML;
552 }
553 info->format_options->is_megablast = is_megablast;
554 if (show_gi) {
555 info->format_options->align_options += TXALIGN_SHOW_GI;
556 info->format_options->print_options += TXALIGN_SHOW_GI;
557 }
558
559 if (!info->search_options->score_options->gapped_calculation)
560 info->format_options->print_options += TXALIGN_SHOW_NO_OF_SEGS;
561
562 info->format_options->believe_query = believe_defline;
563 }
564
565 BlastFormattingInfo* BlastFormattingInfoFree(BlastFormattingInfo* info)
566 {
567 if (info->outfp)
568 FileClose(info->outfp);
569 /* Free the XML or ASN.1 i/o structure. Note that info->aip is set for
570 XML too, but it should not be freed twice. */
571 if (info->xmlp) {
572 Boolean ungapped =
573 !info->search_options->score_options->gapped_calculation;
574 MBXmlClose(info->xmlp, NULL, ungapped);
575 } else if (info->aip) {
576 AsnIoClose(info->aip);
577 }
578 sfree(info->program_name);
579 sfree(info->db_name);
580 sfree(info->format_options);
581 /* The remaining fields are not owned by the structure. */
582 sfree(info);
583
584 return NULL;
585 }
586
587 Uint1
588 GetOldAlignType(EBlastProgramType prog, Boolean* db_is_na)
589 {
590 Uint1 align_type = 0;
591
592 switch (prog) {
593 case eBlastTypeBlastp: case eBlastTypeRpsBlast: case eBlastTypePhiBlastp:
594 case eBlastTypePsiBlast:
595 align_type = 2;
596 *db_is_na = FALSE;
597 break;
598 case eBlastTypeBlastn: case eBlastTypePhiBlastn:
599 align_type = 1;
600 *db_is_na = TRUE;
601 break;
602 case eBlastTypeBlastx: case eBlastTypeRpsTblastn:
603 align_type = 3;
604 *db_is_na = FALSE;
605 break;
606 case eBlastTypePsiTblastn: case eBlastTypeTblastn:
607 align_type = 4;
608 *db_is_na = TRUE;
609 break;
610 case eBlastTypeTblastx:
611 align_type = 5;
612 *db_is_na = TRUE;
613 break;
614 default:
615 break;
616 }
617 return align_type;
618 }
619
620 /** Deletes matrix generated by s_LoadMatrix
621 * @param matrix data to be freed [in]
622 */
623 const int k_MatrixSize = 128;
624 static void s_DeleteMatrix(Int4** matrix)
625 {
626 int i;
627 if (matrix == NULL)
628 return;
629
630 for(i=0; i<k_MatrixSize; i++)
631 MemFree(matrix[i]);
632
633 MemFree(matrix);
634
635 return;
636 }
637
638 /** Adopted from api/jzcoll.c:load_default_matrix
639 * We take the compressed matrix and move it
640 * to a format that includes all ASCII letters,
641 * though most cells will be blank. this is understodd
642 * by txalign.c and does not seem worth fixing now.
643 * @param name matrix name (e.g., BLOSUM90) [in]
644 */
645 static Int4** s_LoadMatrix(const char* name)
646 {
647 Int4** ss;
648 int i, j;
649 int dim = 0;
650 const char* pchars = NULL;
651 SNCBIPackedScoreMatrix* pack_matrix =
652 NCBISM_GetStandardMatrix(name?name:BLAST_DEFAULT_MATRIX);
653
654 if (pack_matrix == NULL)
655 return NULL;
656
657 pchars = pack_matrix->symbols;
658 dim = strlen(pchars);
659
660 ss = (Int4**) MemNew((size_t)k_MatrixSize * sizeof (Int4*));
661 if (ss == NULL)
662 return NULL;
663
664 for(i = 0; i<k_MatrixSize; ++i)
665 ss[i] = (Int4*) MemNew((size_t)k_MatrixSize * sizeof (Int4));
666
667 for(i = 0; i < k_MatrixSize; i++)
668 for(j = 0; j < k_MatrixSize;j++)
669 ss[i][j] = -1000;
670
671 for(i = 0; i < dim; ++i)
672 for(j = 0; j < dim; ++j)
673 ss[pchars[i]][pchars[j]] = pack_matrix->scores[(i*dim)+j];
674
675 return ss;
676 }
677
678
679
680 static Int2
681 s_BLAST_PrintDatabaseInfo(const BlastFormattingInfo* format_info)
682 {
683 Int2 status = 0;
684 BlastFormattingOptions* format_options = format_info->format_options;
685
686 if (format_options->align_view < eAlignViewXml) {
687 if(format_info->db_name) {
688 EBlastProgramType prog = format_info->search_options->program;
689 const Boolean kDbIsProt =
690 (prog == eBlastTypeBlastp || prog == eBlastTypeBlastx ||
691 prog == eBlastTypeRpsBlast || prog == eBlastTypeRpsTblastn ||
692 prog == eBlastTypePhiBlastp);
693 init_buff_ex(90);
694 status =
695 PrintDbInformation(format_info->db_name, kDbIsProt, 70,
696 format_info->outfp, format_options->html);
697 free_buff();
698 }
699 }
700 return status;
701 }
702
703 /** Prints out the description of a query sequence, along
704 * with notification that the query has no hits
705 * @param slp The query Seq-loc
706 * @param format_options Options for formatting
707 * @param outfp File to which the output will be directed
708 */
709 static void
710 s_AcknowledgeEmptyResults(SeqLoc *slp,
711 BlastFormattingOptions* format_options,
712 const BlastFormattingInfo* format_info,
713 FILE *outfp)
714 {
715 Bioseq *bsp = BioseqLockById(SeqLocId(slp));
716
717 if (format_info->head_on_every_query == TRUE)
718 BLAST_PrintOutputHeader(format_info);
719
720 init_buff_ex(70);
721 AcknowledgeBlastQuery(bsp, 70, outfp,
722 format_options->believe_query, format_options->html);
723 free_buff();
724 BioseqUnlock(bsp);
725
726 if (format_info->head_on_every_query == TRUE)
727 {
728 s_BLAST_PrintDatabaseInfo(format_info);
729 fprintf(format_info->outfp, "%s", "Searching..................................................done\n\n");
730 }
731 fprintf(outfp, " ***** No hits found ******\n\n\n");
732 }
733
734 Int2 BLAST_FormatResults(SBlastSeqalignArray* seqalign_arr, Int4 num_queries,
735 SeqLoc* query_slp, SeqLoc* mask_loc_head,
736 BlastFormattingInfo* format_info,
737 Blast_SummaryReturn* sum_returns)
738 {
739 SeqLoc* mask_loc;
740 SeqLoc* next_mask_loc = NULL;
741 SeqLoc* tmp_loc = NULL;
742 Uint1 align_type;
743 Boolean db_is_na;
744 Int4 query_index;
745 SeqLoc* slp;
746 SeqLoc* mask_slp;
747 AsnIo* aip = NULL;
748 MBXml* xmlp = NULL;
749 FILE *outfp = NULL;
750 BlastFormattingOptions* format_options;
751 EAlignView align_view;
752 Boolean ungapped;
753
754 ASSERT(format_info && format_info->format_options &&
755 format_info->search_options && query_slp);
756
757 format_options = format_info->format_options;
758 align_view = format_options->align_view;
759 ungapped =
760 !format_info->search_options->score_options->gapped_calculation;
761
762 if (align_view == eAlignViewXml) {
763 const Int4 kXmlFlag = 0; /* Change to BXML_INCLUDE_QUERY if inclusion
764 of query sequence is desired in the XML
765 output header. */
766 xmlp = format_info->xmlp;
767 if (!xmlp) {
768 xmlp = format_info->xmlp =
769 s_MBXmlInit(format_info->aip, format_info->program_name,
770 format_info->db_name, query_slp, kXmlFlag,
771 sum_returns->search_params);
772 }
773 } else if (align_view == eAlignViewAsnText ||
774 align_view == eAlignViewAsnBinary)
775 aip = format_info->aip;
776 else
777 outfp = format_info->outfp;
778
779 align_type =
780 GetOldAlignType(format_info->search_options->program, &db_is_na);
781
782 if (format_info->db_name) {
783 /* Enable fetching from the BLAST database. */
784 ReadDBBioseqFetchEnable ("blast", format_info->db_name, db_is_na, TRUE);
785 /* If database is translated, set the genetic code for tranlation. */
786 if (Blast_SubjectIsTranslated(format_info->search_options->program)) {
787 ReadDBBioseqSetDbGeneticCode(format_info->search_options->
788 db_options->genetic_code);
789 }
790 }
791
792 if(format_info->search_options->score_options->is_ooframe) {
793 ErrPostEx(SEV_WARNING, 0, 0,
794 "Out-of-frame option selected, Expect values are only approximate and calculated not assuming out-of-frame alignments");
795 }
796
797
798 slp = query_slp;
799 mask_loc = mask_loc_head;
800
801 for (query_index=0; query_index<seqalign_arr->num_queries && slp; query_index++, slp=slp->next)
802 {
803 Bioseq* bsp = NULL;
804 SeqAlignPtr seqalign = seqalign_arr->array[query_index];
805 /* Find which query the current SeqAlign is for */
806 SeqId* query_id = TxGetQueryIdFromSeqAlign(seqalign);
807 if (seqalign == NULL)
808 {
809 if (align_view < eAlignViewXml)
810 s_AcknowledgeEmptyResults(slp, format_options, format_info, outfp); /* this query has no results. */
811 else if (align_view == eAlignViewXml)
812 {
813 /* Retrieve this query's Bioseq */
814 Iteration* iterp;
815 /* Call to TxGetQueryIdFromSeqAlign returned NULL. */
816 query_id = SeqLocId(slp);
817 bsp = BioseqLockById(query_id);
818 iterp = s_XMLBuildOneQueryIteration(NULL, sum_returns, FALSE, ungapped,
819 query_index+1+format_info->num_formatted,
820 "No hits found", bsp, NULL);
821 IterationAsnWrite(iterp, xmlp->aip, xmlp->atp);
822 AsnIoFlush(xmlp->aip);
823 IterationFree(iterp);
824 BioseqUnlock(bsp);
825 }
826 else if (align_view == eAlignViewTabularWithComments)
827 {
828 query_id = SeqLocId(slp);
829 bsp = BioseqLockById(query_id);
830 PrintTabularOutputHeader(format_info->db_name, bsp, NULL,
831 format_info->program_name,
832 0, format_options->believe_query, outfp);
833 BioseqUnlock(bsp);
834 }
835 continue;
836 }
837 format_info->is_seqalign_null = FALSE; /* reset flag, at least one query has seqalign */
838
839 /* Find the masking location for this query. Initialize next_mask_loc
840 to the current start of the chain, in case nothing for this query
841 will be found. */
842 next_mask_loc = mask_loc;
843 for ( ; mask_loc; mask_loc = mask_loc->next) {
844 mask_slp = (SeqLoc*) mask_loc->data.ptrvalue;
845 if (SeqIdComp(query_id, SeqLocId(mask_slp)) == SIC_YES) {
846 break;
847 }
848 }
849 /* Unlink the masking location for this query and save the next one */
850 if (mask_loc) {
851 for (next_mask_loc = mask_loc; next_mask_loc->next;
852 next_mask_loc = next_mask_loc->next) {
853 mask_slp = (SeqLoc*) next_mask_loc->next->data.ptrvalue;
854 if (SeqIdComp(query_id, SeqLocId(mask_slp))
855 != SIC_YES) {
856 break;
857 }
858 }
859 tmp_loc = next_mask_loc;
860 next_mask_loc = next_mask_loc->next;
861 tmp_loc->next = NULL;
862 }
863
864 /* On the next iteration we can start from the next query */
865
866 /* Retrieve this query's Bioseq */
867 bsp = BioseqLockById(query_id);
868
869 if (align_view < eAlignViewXml) {
870 if (format_info->head_on_every_query == TRUE)
871 BLAST_PrintOutputHeader(format_info);
872
873 init_buff_ex(70);
874 AcknowledgeBlastQuery(bsp, 70, outfp,
875 format_options->believe_query, format_options->html);
876 free_buff();
877
878 if (format_info->head_on_every_query == TRUE)
879 {
880 s_BLAST_PrintDatabaseInfo(format_info);
881 fprintf(format_info->outfp, "%s", "Searching..................................................done\n\n");
882 }
883 }
884 if (align_view == eAlignViewTabular ||
885 align_view == eAlignViewTabularWithComments) {
886 if (align_view == eAlignViewTabularWithComments)
887 PrintTabularOutputHeader(format_info->db_name, bsp, NULL,
888 format_info->program_name,
889 0, format_options->believe_query, outfp);
890
891 BlastPrintTabulatedResults(seqalign, bsp, NULL,
892 format_options->number_of_alignments, format_info->program_name,
893 ungapped, format_options->believe_query, 0, 0,
894 outfp, (Boolean)(align_view == eAlignViewTabularWithComments));
895 } else if(align_view == eAlignViewXml) {
896 Iteration* iterp;
897
898 ASSERT(xmlp && xmlp->aip);
899 /* The index of this "query iteration" is the query_index in the
900 current formatting round, plus the number of previously formatted
901 queries. */
902 iterp =
903 s_XMLBuildOneQueryIteration(seqalign, sum_returns, FALSE,
904 ungapped,
905 query_index+1+format_info->num_formatted,
906 NULL, bsp, mask_loc);
907 IterationAsnWrite(iterp, xmlp->aip, xmlp->atp);
908 AsnIoFlush(xmlp->aip);
909 IterationFree(iterp);
910 } else {
911 SeqAnnot* seqannot = SeqAnnotNew();
912 seqannot->type = 2;
913 AddAlignInfoToSeqAnnot(seqannot, align_type);
914 seqannot->data = seqalign;
915 if (aip) {
916 SeqAnnotAsnWrite((SeqAnnot*) seqannot, aip, NULL);
917 AsnIoReset(aip);
918 }
919 if (outfp) {
920 BlastPruneSapStruct* prune;
921 Int4** matrix = s_LoadMatrix(sum_returns->search_params->matrix);
922 ObjMgrSetHold();
923 init_buff_ex(85);
924 PrintDefLinesFromSeqAlignEx2(seqalign, 80, outfp,
925 format_options->print_options, FIRST_PASS, NULL,
926 format_options->number_of_descriptions, NULL, NULL);
927 free_buff();
928
929 /** @todo FIXME: note that by calling BlastPruneHitsFromSeqAlign
930 * we're making a COPY of the seqalign to print it out! Clearly
931 * this could use a better design */
932 prune = BlastPruneHitsFromSeqAlign(seqalign,
933 format_options->number_of_alignments, NULL);
934 seqannot->data = prune->sap;
935
936 if(format_info->search_options->score_options->is_ooframe) {
937 OOFShowBlastAlignment(prune->sap, mask_loc, outfp,
938 format_options->align_options, NULL);
939 } else if (align_view != eAlignViewPairwise) {
940 ShowTextAlignFromAnnot(seqannot, 60, outfp, NULL, NULL,
941 format_options->align_options, matrix, mask_loc, NULL);
942 } else {
943 ShowTextAlignFromAnnot(seqannot, 60, outfp, NULL, NULL,
944 format_options->align_options, matrix, mask_loc,
945 FormatScoreFunc);
946 }
947 s_DeleteMatrix(matrix);
948 seqannot->data = seqalign;
949 prune = BlastPruneSapStructDestruct(prune);
950 ObjMgrClearHold();
951 }
952 /* Set data to NULL, because we do not free Seq-align here. */
953 seqannot->data = NULL;
954 seqannot = SeqAnnotFree(seqannot);
955 }
956 BioseqUnlock(bsp);
957 /* Relink the mask locations so chain can be freed in the end.
958 The 'tmp_loc' variable points to the location that was unlinked. */
959 if (tmp_loc)
960 tmp_loc->next = next_mask_loc;
961
962 mask_loc = next_mask_loc;
963 ObjMgrFreeCache(0);
964
965 } /* End loop on seqaligns for different queries */
966
967 /* close BlastOutput_iterations openned in s_MBXmlInit; Rt ticket # 15135151 */
968 if((format_info->is_seqalign_null==TRUE) && (align_view == eAlignViewXml)) {
969 /* extra output only if no hits at all, otherwise "for loop" logic should take care*/
970 Iteration* iterp;
971 iterp = IterationNew();
972 iterp->iter_num = 1;
973 iterp->stat = s_XMLBuildStatistics(sum_returns, ungapped);
974
975 ASSERT(xmlp && xmlp->aip);
976 IterationAsnWrite(iterp, xmlp->aip, xmlp->atp);
977 AsnIoFlush(xmlp->aip);
978 IterationFree(iterp);
979
980 }
981
982 if (format_info->db_name) {
983 /* Free the database translation tables, if applicable. */
984 TransTableFreeAll();
985 ReadDBBioseqFetchDisable();
986 }
987
988 /* Update the count of the formatted queries. */
989 format_info->num_formatted += num_queries;
990
991 return 0;
992 }
993
994 /** Creates a list of SeqLoc structures with data about PHI BLAST pattern
995 * occurrences, to be used as features on Query Seq-locs.
996 * @param pattern_info Pattern information structure. [in]
997 * @param query_seqloc Query SeqLoc, needed to retrieve Seq-id. [in]
998 * @param seed_seqloc_ptr List of SeqLoc's with pattern data. [out]
999 */
1000 static Int2
1001 s_PHIBlastCreateSeedSeqLoc(const SPHIQueryInfo* pattern_info,
1002 SeqLoc* query_seqloc,
1003 SeqLoc** seed_seqloc_ptr)
1004 {
1005 Int4 index;
1006 for (index = 0; index < pattern_info->num_patterns; ++index) {
1007 const SPHIPatternInfo* this_occurrence =
1008 &pattern_info->occurrences[index];
1009 SeqInt* si = SeqIntNew();
1010 si->id = SeqIdDup(SeqLocId(query_seqloc));
1011 si->from = this_occurrence->offset;
1012 si->to = this_occurrence->offset + this_occurrence->length - 1;
1013 ValNodeAddPointer(seed_seqloc_ptr, SEQLOC_INT, si);
1014 }
1015 return 0;
1016 }
1017
1018 /** Produces part of the text report describing the PHI BLAST pattern
1019 * occurrences.
1020 * @param sum_returns Search summary return data [in]
1021 * @param outfp Output file stream [in]
1022 */
1023 static Int2
1024 s_PHIBlastFormatPatternInfo(Blast_SummaryReturn* sum_returns, FILE* outfp)
1025 {
1026 Int4 index;
1027 SPHIQueryInfo* pattern_info = sum_returns->pattern_info;
1028 double lenXprob =
1029 sum_returns->db_stats->eff_dblength * pattern_info->probability;
1030 Int8 db_patterns;
1031
1032 /* Get the pattern count in database from the diagnostics structure - it is
1033 equal to the number of "lookup" hits. */
1034 ASSERT(sum_returns->diagnostics && sum_returns->diagnostics->ungapped_stat);
1035 db_patterns = sum_returns->diagnostics->ungapped_stat->lookup_hits;
1036
1037 fprintf(outfp, "\n%d occurrence(s) of pattern in query\n",
1038 pattern_info->num_patterns);
1039 for (index = 0; index < pattern_info->num_patterns; ++index) {
1040 fprintf(outfp, "\n pattern %s\n at position %d of query sequence\n",
1041 sum_returns->search_params->pattern,
1042 pattern_info->occurrences[index].offset + 1);
1043 fprintf(outfp, "effective database length=%.1e\n",
1044 (double)sum_returns->db_stats->eff_dblength);
1045 fprintf(outfp, " pattern probability=%.1e\nlengthXprobability=%.1e\n",
1046 pattern_info->probability, lenXprob);
1047 fprintf(outfp,
1048 "\nNumber of occurrences of pattern in the database is %s\n",
1049 Nlm_Int8tostr(db_patterns, 0));
1050 fprintf(outfp, "WARNING: There may be more matching sequences with "
1051 "e-values below the threshold of %f\n",
1052 sum_returns->search_params->expect);
1053
1054 }
1055 return 0;
1056 }
1057
1058 Int2 PHIBlastFormatResults(ValNode* phivnps, SeqLoc* query_slp,
1059 const BlastFormattingInfo* format_info,
1060 Blast_SummaryReturn* sum_returns)
1061 {
1062 Boolean db_is_na;
1063 Bioseq* query_bsp = NULL;
1064 FILE *outfp = NULL;
1065 ValNode* pruneSeed = NULL;
1066 Uint1 featureOrder[FEATDEF_ANY];
1067 Uint1 groupOrder[FEATDEF_ANY];
1068 SeqLoc* seed_seqloc = NULL; /* SeqLoc containing pattern locations. */
1069 EBlastProgramType program;
1070 BlastFormattingOptions* format_options;
1071
1072 if (!format_info || !format_info->outfp || !query_slp)
1073 return -1;
1074
1075 format_options = format_info->format_options;
1076 program = format_info->search_options->program;
1077
1078 ASSERT(Blast_ProgramIsPhiBlast(program));
1079
1080 outfp = format_info->outfp;
1081
1082 s_PHIBlastFormatPatternInfo(sum_returns, outfp);
1083
1084 /* Old toolkit might have different values for program numbers, so
1085 use old toolkit function to determine alignment type. */
1086 if (program == eBlastTypePhiBlastn)
1087 db_is_na = TRUE;
1088 else
1089 db_is_na = FALSE;
1090
1091 if (format_info->db_name)
1092 ReadDBBioseqFetchEnable ("blast", format_info->db_name, db_is_na, TRUE);
1093
1094 pruneSeed =
1095 SeedPruneHitsFromSeedReturn(phivnps,
1096 format_options->number_of_descriptions);
1097
1098 s_PHIBlastCreateSeedSeqLoc(sum_returns->pattern_info, query_slp,
1099 &seed_seqloc);
1100
1101 PrintDefLinesExtra(pruneSeed, 80, outfp, format_options->print_options,
1102 FIRST_PASS, NULL, seed_seqloc);
1103
1104 if (format_options->number_of_alignments <
1105 format_options->number_of_descriptions) {
1106 pruneSeed =
1107 SeedPruneHitsFromSeedReturn(phivnps,
1108 format_options->number_of_alignments);
1109 }
1110
1111 query_bsp = BioseqLockById(SeqLocId(query_slp));
1112 memset(featureOrder, 0, sizeof(featureOrder));
1113 memset(groupOrder, 0, sizeof(groupOrder));
1114 featureOrder[FEATDEF_REGION] = 1;
1115 groupOrder[FEATDEF_REGION] = 1;
1116
1117 if (format_options->align_view != eAlignViewPairwise) {
1118 ShowTextAlignFromAnnotExtra(query_bsp, pruneSeed, seed_seqloc, 60, outfp,
1119 featureOrder, groupOrder,
1120 format_options->align_options, NULL, NULL,
1121 NULL);
1122 } else {
1123 ShowTextAlignFromAnnotExtra(query_bsp, pruneSeed, seed_seqloc, 60, outfp,
1124 featureOrder, groupOrder,
1125 format_options->align_options, NULL, NULL,
1126 FormatScoreFunc);
1127 }
1128
1129 SeqLocSetFree(seed_seqloc);
1130
1131 if (format_info->db_name)
1132 ReadDBBioseqFetchDisable();
1133
1134 return 0;
1135 }
1136
1137 ValNode* PHIBlastResultsFree(ValNode* phivnps)
1138 {
1139 ValNode* vnp;
1140
1141 for (vnp = phivnps; vnp; vnp = vnp->next)
1142 SeqAlignSetFree((SeqAlign*) vnp->data.ptrvalue);
1143 ValNodeFree(phivnps);
1144 return NULL;
1145 }
1146
1147 Int2 Blast_PrintOutputFooter(const BlastFormattingInfo* format_info,
1148 const Blast_SummaryReturn* sum_returns)
1149 {
1150 FILE *outfp;
1151 char* params_buffer=NULL;
1152 BlastFormattingOptions* format_options;
1153 EBlastProgramType program;
1154
1155 if (!format_info || !format_info->outfp || !sum_returns)
1156 return -1;
1157
1158 outfp = format_info->outfp;
1159
1160 format_options = format_info->format_options;
1161 program = format_info->search_options->program;
1162
1163 if (format_options->align_view >= eAlignViewXml)
1164 return 0;
1165
1166 if(format_options->html)
1167 fprintf(outfp, "<PRE>\n");
1168 init_buff_ex(85);
1169
1170 if (format_info->db_name) {
1171 const Boolean kDbIsProt =
1172 (program == eBlastTypeBlastp ||
1173 program == eBlastTypeBlastx ||
1174 program == eBlastTypePhiBlastp ||
1175 program == eBlastTypePsiBlast ||
1176 program == eBlastTypeRpsBlast ||
1177 program == eBlastTypeRpsTblastn);
1178 ReadDBFILE* rdfp = readdb_new(format_info->db_name, kDbIsProt);
1179 TxDfDbInfo* dbinfo_head,* dbinfo;
1180 dbinfo_head = Blast_GetDbInfo(rdfp);
1181 rdfp = readdb_destruct(rdfp);
1182
1183 for (dbinfo = dbinfo_head; dbinfo; dbinfo = dbinfo->next) {
1184 PrintDbReport((TxDfDbInfo*) dbinfo, 70, outfp);
1185 }
1186 dbinfo_head = TxDfDbInfoDestruct(dbinfo_head);
1187 }
1188
1189
1190 if (sum_returns->ka_params)
1191 {
1192 BLAST_KAParameters* ka_params=sum_returns->ka_params;
1193 PrintKAParameters(ka_params->Lambda, ka_params->K, ka_params->H, 70,
1194 outfp, FALSE);
1195 }
1196
1197
1198 if (sum_returns->ka_params_gap && sum_returns->search_params->gapped_search)
1199 {
1200 BLAST_KAParameters* ka_params=sum_returns->ka_params_gap;
1201 if (Blast_ProgramIsPhiBlast(program)) {
1202 PrintKAParametersExtra(ka_params->Lambda, ka_params->K, ka_params->H,
1203 ka_params->C, 70, outfp, TRUE);
1204 } else {
1205 PrintKAParameters(ka_params->Lambda, ka_params->K, ka_params->H, 70,
1206 outfp, TRUE);
1207 }
1208 }
1209 params_buffer =
1210 Blast_GetParametersBuffer(program, sum_returns);
1211 PrintTildeSepLines(params_buffer, 70, outfp);
1212 sfree(params_buffer);
1213
1214 if(format_options->html)
1215 fprintf(outfp, "</PRE>\n</BODY>\n</HTML>\n");
1216
1217 free_buff();
1218
1219 return 0;
1220 }
1221
1222 Int2
1223 BLAST_PrintOutputHeader(const BlastFormattingInfo* format_info)
1224 {
1225 Int2 status = 0;
1226 BlastFormattingOptions* format_options;
1227
1228 if (!format_info)
1229 return -1;
1230
1231 format_options = format_info->format_options;
1232
1233 if (format_options->align_view < eAlignViewXml) {
1234 if (format_options->html) {
1235 fprintf(format_info->outfp,
1236 "<HTML>\n<TITLE>BLAST Search Results</TITLE>\n");
1237 fprintf(format_info->outfp,
1238 "<BODY BGCOLOR=\"#FFFFFF\" LINK=\"#0000FF\" "
1239 "VLINK=\"#660099\" ALINK=\"#660099\">\n");
1240 fprintf(format_info->outfp, "<PRE>\n");
1241 }
1242 init_buff_ex(90);
1243 if (format_options->is_megablast) {
1244 BlastPrintVersionInfo("MEGABLAST", format_options->html, format_info->outfp);
1245 fprintf(format_info->outfp, "\n");
1246 MegaBlastPrintReference(format_options->html, 90, format_info->outfp);
1247 }
1248 else if (strcmp(format_info->program_name, "rpsblast") == 0 ||
1249 strcmp(format_info->program_name, "rpstblastn") == 0) {
1250 BlastPrintVersionInfo("RPS-BLAST", format_options->html, format_info->outfp);
1251 }
1252 else {
1253 BlastPrintVersionInfo(format_info->program_name, format_options->html,
1254 format_info->outfp);
1255 fprintf(format_info->outfp, "\n");
1256 BlastPrintReference(format_options->html, 90, format_info->outfp);
1257 }
1258 {{
1259 int comp_based_stats =
1260 format_info->search_options->ext_options->compositionBasedStats;
1261 if (comp_based_stats == eCompositionBasedStats) {
1262 CBStatisticsPrintReference(format_options->html, 90,
1263 TRUE, FALSE, format_info->outfp);
1264 } else if (comp_based_stats > eCompositionBasedStats) {
1265 CAdjustmentPrintReference(format_options->html, 90,
1266 format_info->outfp);
1267 }
1268 }}
1269 free_buff();
1270 fprintf(format_info->outfp, "\n");
1271
1272 if (format_info->head_on_every_query == FALSE)
1273 {
1274 status = s_BLAST_PrintDatabaseInfo(format_info);
1275 fprintf(format_info->outfp, "%s", "Searching..................................................done\n\n");
1276 }
1277 }
1278
1279 return status;
1280 }
1281
1282 #ifdef BUFFER_LENGTH
1283 #undef BUFFER_LENGTH
1284 #endif
1285
1286 /** Buffer length for printing sequence ids. */
1287 #define BUFFER_LENGTH 256
1288
1289 void
1290 Blast_SeqIdGetDefLine(SeqId* sip, char** buffer_ptr, Boolean ncbi_gi,
1291 Boolean accession_only, Boolean search_for_id)
1292 {
1293 char* seqid_buffer = NULL;
1294 Int4 gi = 0;
1295 Boolean numeric_id_type = FALSE;
1296
1297 *buffer_ptr = NULL;
1298
1299 if (sip == NULL)
1300 return;
1301
1302 /* Check for ad hoc ID's generated by formatdb if the user does not provide
1303 any. */
1304 if (search_for_id && (sip->choice != SEQID_GENERAL ||
1305 StringCmp(((Dbtag*)sip->data.ptrvalue)->db, "BL_ORD_ID")))
1306 {
1307 if ((!accession_only && !ncbi_gi) || sip->choice == SEQID_LOCAL) {
1308 seqid_buffer = (char*) malloc(BUFFER_LENGTH + 1);
1309 SeqIdWrite(sip, seqid_buffer, PRINTID_FASTA_LONG, BUFFER_LENGTH);
1310 } else if (accession_only) {
1311 seqid_buffer = (char*) malloc(BUFFER_LENGTH + 1);
1312 SeqIdWrite(SeqIdFindBestAccession(sip), seqid_buffer,
1313 PRINTID_TEXTID_ACC_VER, BUFFER_LENGTH);
1314 } else if (ncbi_gi) {
1315 numeric_id_type =
1316 GetAccessionFromSeqId(SeqIdFindBest(sip, SEQID_GI),
1317 &gi, &seqid_buffer);
1318 } else {
1319 numeric_id_type =
1320 GetAccessionFromSeqId(SeqIdFindBestAccession(sip),
1321 &gi, &seqid_buffer);
1322 }
1323 }
1324
1325 if (numeric_id_type && gi > 0) {
1326 seqid_buffer = (char*) malloc(16);
1327 sprintf(seqid_buffer, "%ld", (long) gi);
1328 }
1329 if (!seqid_buffer) {
1330 /* If it's still NULL make a last ditch effort to get info. */
1331 char* title=NULL;
1332 Bioseq* bsp = BioseqLockById(sip);
1333 if (bsp) {
1334 if (BioseqGetTitle(bsp) != NULL)
1335 title = strdup(BioseqGetTitle(bsp));
1336 else
1337 title = strdup("No definition line found");
1338 }
1339 BioseqUnlock(bsp);
1340
1341 if (title) /* Use first token as id. */
1342 seqid_buffer = StringTokMT(title, " \t\n\r", &title);
1343 }
1344 *buffer_ptr = seqid_buffer;
1345
1346 }
1347
1348 Int2
1349 Blast_SummaryReturnsPostError(Blast_SummaryReturn* sum_return)
1350 {
1351 SBlastMessage* error = NULL;
1352
1353 if (!sum_return)
1354 return -1;
1355
1356 /* If there was no error, there is nothing to post. */
1357 if (!sum_return->error)
1358 return 0;
1359
1360 error = sum_return->error;
1361
1362 ErrPostEx(error->sev, 0, 0, error->message);
1363
1364 return 0;
1365 }
1366 /* @} */
1367
1368 |
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more information. |