1 /* $Id: blast_returns.c,v 1.39 2010/06/10 13:44:46 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 * Author: Ilya Dondoshansky
25 * ===========================================================================*/
26
27 /** @file blast_returns.c
28 * Manipulating data returned from BLAST other than Seq-aligns
29 */
30
31 #ifndef SKIP_DOXYGEN_PROCESSING
32 static char const rcsid[] = "$Id: blast_returns.c,v 1.39 2010/06/10 13:44:46 madden Exp $";
33 #endif /* SKIP_DOXYGEN_PROCESSING */
34
35 #include <algo/blast/api/blast_returns.h>
36 #include <algo/blast/api/blast_seq.h>
37 #include <algo/blast/core/blast_filter.h>
38 #include <algo/blast/core/blast_util.h>
39 #include <algo/blast/core/pattern.h>
40
41 /** @addtogroup CToolkitAlgoBlast
42 *
43 * @{
44 */
45
Blast_GetDbInfo(ReadDBFILE * rdfp)46 TxDfDbInfo* Blast_GetDbInfo(ReadDBFILE* rdfp)
47 {
48 TxDfDbInfo* dbinfo = NULL;
49 char* chptr = NULL;
50
51 if (!rdfp)
52 return NULL;
53
54 dbinfo = calloc(1, sizeof(TxDfDbInfo));
55
56 dbinfo->name = strdup(readdb_get_filename(rdfp));
57
58 if (((chptr = readdb_get_title(rdfp)) == NULL) && dbinfo->name)
59 dbinfo->definition = strdup(dbinfo->name);
60 else
61 dbinfo->definition = strdup(chptr);
62
63 dbinfo->date = strdup(readdb_get_date(rdfp));
64
65 dbinfo->is_protein = readdb_is_prot(rdfp);
66
67 readdb_get_totals_ex(rdfp, &dbinfo->total_length, &dbinfo->number_seqs, TRUE);
68
69 return dbinfo;
70 }
71
72 char*
Blast_GetParametersBuffer(EBlastProgramType program_number,const Blast_SummaryReturn * sum_returns)73 Blast_GetParametersBuffer(EBlastProgramType program_number,
74 const Blast_SummaryReturn* sum_returns)
75 {
76 char buffer[128];
77 char* ret_buffer=NULL;
78 Int2 ret_buffer_length=0;
79 BlastUngappedStats* ungapped_stats = NULL;
80 BlastGappedStats* gapped_stats = NULL;
81 BlastRawCutoffs* raw_cutoffs = NULL;
82 Blast_SearchParams* search_params=NULL;
83 Blast_DatabaseStats* db_stats = NULL;
84 BlastDiagnostics* diagnostics = NULL;
85
86
87 if (!sum_returns || !sum_returns->search_params || !sum_returns->db_stats)
88 return NULL;
89
90 search_params = sum_returns->search_params;
91 db_stats = sum_returns->db_stats;
92 diagnostics = sum_returns->diagnostics;
93
94 if (diagnostics) {
95 ungapped_stats = diagnostics->ungapped_stat;
96 gapped_stats = diagnostics->gapped_stat;
97 raw_cutoffs = diagnostics->cutoffs;
98 }
99
100 if (program_number == eBlastTypeBlastn ||
101 program_number == eBlastTypePhiBlastn)
102 {
103 sprintf(buffer, "Matrix: blastn matrix:%d %d", search_params->match, search_params->mismatch);
104 add_string_to_buffer(buffer, &ret_buffer, &ret_buffer_length);
105 }
106 else if (search_params->matrix)
107 {
108 sprintf(buffer, "Matrix: %s", search_params->matrix);
109 add_string_to_buffer(buffer, &ret_buffer, &ret_buffer_length);
110 }
111
112 if (search_params->gapped_search) {
113 if (search_params->gap_extension == 0 && program_number == eBlastTypeBlastn)
114 { /* Formula from PMID 10890397 applies if both gap values are zero. */
115 double gap_extension = (double) search_params->gap_extension;
116 gap_extension = -2*search_params->mismatch + search_params->match;
117 gap_extension /= 2.0;
118 sprintf(buffer, "Gap Penalties: Existence: %ld, Extension: %4.1f",
119 (long) search_params->gap_open, gap_extension);
120 }
121 else
122 {
123 sprintf(buffer, "Gap Penalties: Existence: %ld, Extension: %ld",
124 (long) search_params->gap_open, (long) search_params->gap_extension);
125 }
126 add_string_to_buffer(buffer, &ret_buffer, &ret_buffer_length);
127 }
128
129 sprintf(buffer, "Number of Sequences: %ld", (long) db_stats->dbnum);
130 add_string_to_buffer(buffer, &ret_buffer, &ret_buffer_length);
131
132 if (ungapped_stats) {
133 sprintf(buffer, "Number of Hits to DB: %s",
134 Nlm_Int8tostr(ungapped_stats->lookup_hits, 1));
135 add_string_to_buffer(buffer, &ret_buffer, &ret_buffer_length);
136
137 if (ungapped_stats->init_extends) {
138 sprintf(buffer, "Number of extensions: %ld",
139 (long) ungapped_stats->init_extends);
140 add_string_to_buffer(buffer, &ret_buffer, &ret_buffer_length);
141 }
142 if (ungapped_stats->good_init_extends) {
143 sprintf(buffer, "Number of successful extensions: %ld",
144 (long) ungapped_stats->good_init_extends);
145 add_string_to_buffer(buffer, &ret_buffer, &ret_buffer_length);
146 }
147 }
148
149 if (gapped_stats) {
150 if (search_params->expect > 0.1) {
151 sprintf(buffer, "Number of sequences better than %4.1f: %ld",
152 search_params->expect,
153 (long) gapped_stats->num_seqs_passed);
154 } else {
155 sprintf(buffer, "Number of sequences better than %3.1e: %ld",
156 search_params->expect,
157 (long) gapped_stats->num_seqs_passed);
158 }
159 add_string_to_buffer(buffer, &ret_buffer, &ret_buffer_length);
160
161 if (search_params->gapped_search) {
162 if (gapped_stats->seqs_ungapped_passed) {
163 sprintf(buffer,
164 "Number of HSP's better than %4.1f without gapping: %ld",
165 search_params->expect,
166 (long) gapped_stats->seqs_ungapped_passed);
167 add_string_to_buffer(buffer, &ret_buffer, &ret_buffer_length);
168 }
169 sprintf(buffer, "Number of HSP's gapped: %ld",
170 (long) gapped_stats->extensions);
171 add_string_to_buffer(buffer, &ret_buffer, &ret_buffer_length);
172 sprintf(buffer, "Number of HSP's successfully gapped: %ld",
173 (long) gapped_stats->good_extensions);
174 add_string_to_buffer(buffer, &ret_buffer, &ret_buffer_length);
175 }
176 }
177
178 /* Query length makes sense only for single query sequence. */
179 if (db_stats->qlen > 0) {
180 sprintf(buffer, "Length of query: %ld", (long)db_stats->qlen);
181 add_string_to_buffer(buffer, &ret_buffer, &ret_buffer_length);
182 }
183
184 sprintf(buffer, "Length of database: %s",
185 Nlm_Int8tostr (db_stats->dblength, 1));
186 add_string_to_buffer(buffer, &ret_buffer, &ret_buffer_length);
187
188 if (db_stats->qlen > 0) {
189 sprintf(buffer, "Length adjustment: %ld", (long) db_stats->hsp_length);
190 add_string_to_buffer(buffer, &ret_buffer, &ret_buffer_length);
191
192 sprintf(buffer, "Effective length of query: %ld",
193 (long) db_stats->eff_qlen);
194 add_string_to_buffer(buffer, &ret_buffer, &ret_buffer_length);
195
196 sprintf(buffer, "Effective length of database: %s",
197 Nlm_Int8tostr (db_stats->eff_dblength , 1));
198 add_string_to_buffer(buffer, &ret_buffer, &ret_buffer_length);
199 sprintf(buffer, "Effective search space: %8.0f",
200 (double) db_stats->eff_searchsp);
201 add_string_to_buffer(buffer, &ret_buffer, &ret_buffer_length);
202 sprintf(buffer, "Effective search space used: %8.0f",
203 (double) db_stats->eff_searchsp_used);
204 add_string_to_buffer(buffer, &ret_buffer, &ret_buffer_length);
205 }
206 if (search_params->threshold) {
207 if (search_params->threshold == floor(search_params->threshold))
208 sprintf(buffer, "Neighboring words threshold: %ld",
209 (long)search_params->threshold);
210 else
211 sprintf(buffer, "Neighboring words threshold: %.2f",
212 search_params->threshold);
213 add_string_to_buffer(buffer, &ret_buffer, &ret_buffer_length);
214 }
215 if (search_params->window_size) {
216 sprintf(buffer, "Window for multiple hits: %ld",
217 (long) search_params->window_size);
218 add_string_to_buffer(buffer, &ret_buffer, &ret_buffer_length);
219 }
220 if (raw_cutoffs) {
221 BLAST_KAParameters* ka_params_gap = sum_returns->ka_params_gap;
222 BLAST_KAParameters* ka_params = sum_returns->ka_params;
223
224 if (raw_cutoffs->x_drop_ungapped) {
225 sprintf(buffer, "X1: %ld (%4.1f bits)",
226 (long)raw_cutoffs->x_drop_ungapped,
227 (raw_cutoffs->x_drop_ungapped)*(ka_params->Lambda)/NCBIMATH_LN2);
228 add_string_to_buffer(buffer, &ret_buffer, &ret_buffer_length);
229 }
230 if (search_params->gapped_search) {
231 sprintf(buffer, "X2: %ld (%4.1f bits)",
232 (long)raw_cutoffs->x_drop_gap, raw_cutoffs->x_drop_gap*(ka_params_gap->Lambda)/NCBIMATH_LN2);
233 add_string_to_buffer(buffer, &ret_buffer, &ret_buffer_length);
234 sprintf(buffer, "X3: %ld (%4.1f bits)",
235 (long)raw_cutoffs->x_drop_gap_final,
236 raw_cutoffs->x_drop_gap_final*(ka_params_gap->Lambda) /
237 NCBIMATH_LN2);
238 add_string_to_buffer(buffer, &ret_buffer, &ret_buffer_length);
239
240 if (raw_cutoffs->ungapped_cutoff) {
241 sprintf(buffer, "S1: %ld (%4.1f bits)",
242 (long)raw_cutoffs->ungapped_cutoff,
243 ((raw_cutoffs->ungapped_cutoff*(ka_params->Lambda)) -
244 (log(ka_params->K)))/NCBIMATH_LN2);
245 add_string_to_buffer(buffer, &ret_buffer, &ret_buffer_length);
246 }
247 }
248 if (raw_cutoffs->cutoff_score) {
249 if (search_params->gapped_search) {
250 sprintf(buffer, "S2: %ld (%4.1f bits)",
251 (long) raw_cutoffs->cutoff_score,
252 (((raw_cutoffs->cutoff_score)*(ka_params_gap->Lambda)) -
253 (log(ka_params_gap->K)))/NCBIMATH_LN2);
254 } else {
255 sprintf(buffer, "S2: %ld (%4.1f bits)",
256 (long) raw_cutoffs->cutoff_score,
257 (((raw_cutoffs->cutoff_score)*(ka_params->Lambda)) -
258 (log(ka_params->K)))/NCBIMATH_LN2);
259 }
260 add_string_to_buffer(buffer, &ret_buffer, &ret_buffer_length);
261 }
262 }
263
264 return ret_buffer;
265 }
266
267 /** Save the Karlin-Altschul parameters calculated in the BLAST search.
268 * @param sbp Internal scoring block structure [in]
269 * @param query_info info about query for use in fetching
270 * Karlin-Altschul parameters [in]
271 * @param sum_returns Returns summary structure [out]
272 */
273 static void
s_SummaryKAParametersFill(const BlastScoreBlk * sbp,const BlastQueryInfo * query_info,Blast_SummaryReturn * sum_returns)274 s_SummaryKAParametersFill(const BlastScoreBlk* sbp, const BlastQueryInfo* query_info,
275 Blast_SummaryReturn* sum_returns)
276 {
277 Blast_KarlinBlk* kbp;
278 int index;
279 int context = -1;
280
281 if (!sbp || !query_info)
282 return;
283
284 for (index=query_info->first_context; index<=query_info->last_context; index++)
285 if (query_info->contexts[index].is_valid == TRUE)
286 {
287 context = index;
288 break;
289 }
290
291 if (sbp->kbp) {
292 sum_returns->ka_params =
293 (BLAST_KAParameters*) calloc(1, sizeof(BLAST_KAParameters));
294 if (context >= 0)
295 {
296 kbp = sbp->kbp[context];
297 sum_returns->ka_params->Lambda = kbp->Lambda;
298 sum_returns->ka_params->K = kbp->K;
299 sum_returns->ka_params->H = kbp->H;
300 }
301 else
302 {
303 sum_returns->ka_params->Lambda = -1.0;
304 sum_returns->ka_params->K = -1.0;
305 sum_returns->ka_params->H = -1.0;
306 }
307 }
308
309 if (sbp->kbp_gap) {
310 sum_returns->ka_params_gap =
311 (BLAST_KAParameters*) calloc(1, sizeof(BLAST_KAParameters));
312 if (context >= 0)
313 {
314 kbp = sbp->kbp_gap[context];
315 sum_returns->ka_params_gap->Lambda = kbp->Lambda;
316 sum_returns->ka_params_gap->K = kbp->K;
317 sum_returns->ka_params_gap->H = kbp->H;
318 sum_returns->ka_params_gap->C = kbp->paramC; /* Needed only in PHI BLAST */
319 }
320 else
321 {
322 sum_returns->ka_params_gap->Lambda = -1.0;
323 sum_returns->ka_params_gap->K = -1.0;
324 sum_returns->ka_params_gap->H = -1.0;
325 sum_returns->ka_params_gap->C = -1.0;
326 }
327 }
328 }
329
330 /** Frees Blast_DatabaseStats object
331 * @param db_stats object to be freed [in]
332 * @return NULL pointer
333 */
334 static Blast_DatabaseStats*
s_SummaryDBStatsFree(Blast_DatabaseStats * db_stats)335 s_SummaryDBStatsFree(Blast_DatabaseStats* db_stats)
336 {
337 sfree(db_stats);
338 return NULL;
339 }
340
341 /** Allocates and fills in Blast_DatabaseStats
342 * @param program_number blastn/blastp/etc. [in]
343 * @param eff_len_options pointer to effective length options [in]
344 * @param query_info information about query [in]
345 * @param seq_src Source of subject sequences [in]
346 * @param db_stats object to be returned [out]
347 * @return zero on success
348 */
349 static Int2
s_SummaryDBStatsFill(EBlastProgramType program_number,const BlastEffectiveLengthsOptions * eff_len_options,const BlastQueryInfo * query_info,const BlastSeqSrc * seq_src,Blast_DatabaseStats ** db_stats)350 s_SummaryDBStatsFill(EBlastProgramType program_number,
351 const BlastEffectiveLengthsOptions* eff_len_options,
352 const BlastQueryInfo* query_info, const BlastSeqSrc* seq_src,
353 Blast_DatabaseStats** db_stats)
354 {
355 Int8 total_length=0; /* total length of database. */
356 Int4 num_entries=0; /* number of entries in database. */
357 Int4 num_frames; /* number of frames allowed. */
358
359
360 ASSERT(db_stats);
361
362 *db_stats = (Blast_DatabaseStats*) calloc(1, sizeof(Blast_DatabaseStats));
363 if (*db_stats == NULL)
364 return -1;
365
366 if (eff_len_options->db_length) {
367 total_length = eff_len_options->db_length;
368 } else {
369 total_length = BlastSeqSrcGetTotLen(seq_src);
370
371 if (total_length == 0) {
372 /* If total length cannot be retrieved directly, calculate it by
373 adding individual sequence lengths. */
374 BlastSeqSrcIterator* itr = BlastSeqSrcIteratorNew();
375 Int4 oid;
376 while ( (oid = BlastSeqSrcIteratorNext(seq_src, itr))
377 != BLAST_SEQSRC_EOF) {
378 total_length += BlastSeqSrcGetSeqLen(seq_src, (void*) &oid);
379 }
380 itr = BlastSeqSrcIteratorFree(itr);
381 }
382 }
383
384 if (Blast_SubjectIsTranslated(program_number) ||
385 program_number == eBlastTypeRpsTblastn)
386 total_length /= 3;
387
388 (*db_stats)->dblength = total_length;
389
390
391 if (eff_len_options->dbseq_num)
392 num_entries = eff_len_options->dbseq_num;
393 else
394 num_entries = BlastSeqSrcGetNumSeqs(seq_src);
395
396 (*db_stats)->dbnum = num_entries;
397
398 if (program_number == eBlastTypeBlastx ||
399 program_number == eBlastTypeRpsTblastn ||
400 program_number == eBlastTypeTblastx)
401 num_frames = NUM_FRAMES;
402 else if (program_number == eBlastTypeBlastn ||
403 program_number == eBlastTypePhiBlastn)
404 num_frames = 2;
405 else
406 num_frames = 1;
407
408
409 if (query_info->last_context < num_frames) { /* Only one query here. */
410 Int4 qlen = query_info->contexts[query_info->first_context].query_length;
411 (*db_stats)->hsp_length =
412 query_info->contexts[query_info->first_context].length_adjustment;
413 /** FIXME: Should this be different for RPS BLAST? */
414 (*db_stats)->qlen = qlen;
415 (*db_stats)->eff_qlen = qlen - ((*db_stats)->hsp_length);
416 (*db_stats)->eff_dblength = total_length;
417 if (eff_len_options->db_length == 0) {
418 (*db_stats)->eff_dblength -= (Int8)num_entries *
419 ((*db_stats)->hsp_length);
420 }
421 (*db_stats)->eff_searchsp =
422 query_info->contexts[query_info->first_context].eff_searchsp;
423 if (eff_len_options &&
424 eff_len_options->num_searchspaces &&
425 eff_len_options->searchsp_eff[0])
426 (*db_stats)->eff_searchsp_used = eff_len_options->searchsp_eff[0];
427 else
428 (*db_stats)->eff_searchsp_used = (*db_stats)->eff_searchsp;
429 }
430
431 return 0;
432 }
433
434 /** Free Blast_SearchParams structure and underlying data
435 *
436 * @param search_params the object to be freed [in]
437 * @return NULL pointer
438 */
439 static Blast_SearchParams*
s_SummarySearchParamsFree(Blast_SearchParams * search_params)440 s_SummarySearchParamsFree(Blast_SearchParams* search_params)
441 {
442
443 if (search_params == NULL)
444 return NULL;
445
446 sfree(search_params->matrix);
447 sfree(search_params->entrez_query);
448 sfree(search_params->filter_string);
449 sfree(search_params->pattern);
450 sfree(search_params);
451
452 return NULL;
453 }
454
455 /** Allocated and fills some search parameters.
456 *
457 * @param program_number identifies blastn/blastp/etc. [in]
458 * @param score_options pointer to scoring options [in]
459 * @param lookup_options pointer to options for lookup table creation [in]
460 * @param hit_options options for saving and evaluating hits [in]
461 * @param query_setup options for filtering etc. [in]
462 * @param word_options options for processing initial hits [in]
463 * @param entrez_query limit search by this query [in]
464 * @param search_params object to be allocated and filled [out]
465 * @return zero on success
466 */
467 Int2
Blast_SearchParamsFill(EBlastProgramType program_number,const BlastScoringOptions * score_options,const LookupTableOptions * lookup_options,const BlastHitSavingOptions * hit_options,const QuerySetUpOptions * query_setup,const BlastInitialWordOptions * word_options,const char * entrez_query,Blast_SearchParams ** search_params)468 Blast_SearchParamsFill(EBlastProgramType program_number,
469 const BlastScoringOptions* score_options,
470 const LookupTableOptions* lookup_options,
471 const BlastHitSavingOptions* hit_options,
472 const QuerySetUpOptions* query_setup,
473 const BlastInitialWordOptions* word_options,
474 const char* entrez_query,
475 Blast_SearchParams** search_params)
476 {
477 Blast_SearchParams* search_params_lcl;
478
479 ASSERT(search_params);
480 ASSERT(score_options && lookup_options && hit_options && query_setup);
481
482 *search_params = search_params_lcl = (Blast_SearchParams*) calloc(1, sizeof(Blast_SearchParams));
483 if (search_params_lcl == NULL)
484 return -1;
485
486 if (program_number == eBlastTypeBlastn ||
487 program_number == eBlastTypePhiBlastn)
488 {
489 search_params_lcl->match = score_options->reward;
490 search_params_lcl->mismatch = score_options->penalty;
491 }
492 else if (score_options->matrix)
493 {
494 search_params_lcl->matrix = StringSave(score_options->matrix);
495 }
496
497 if (score_options->gapped_calculation)
498 {
499 search_params_lcl->gapped_search = TRUE;
500 search_params_lcl->gap_open = score_options->gap_open;
501 search_params_lcl->gap_extension = score_options->gap_extend;
502 }
503 else
504 search_params_lcl->gapped_search = FALSE;
505
506 if (query_setup && query_setup->filter_string)
507 search_params_lcl->filter_string = StringSave(query_setup->filter_string);
508 else
509 search_params_lcl->filter_string = StringSave("F");
510
511 search_params_lcl->expect = hit_options->expect_value;
512
513 if (lookup_options->phi_pattern)
514 search_params_lcl->pattern = StringSave(lookup_options->phi_pattern);
515
516 search_params_lcl->threshold = lookup_options->threshold;
517
518 search_params_lcl->window_size = word_options->window_size;
519
520 if (entrez_query)
521 search_params_lcl->entrez_query = StringSave(entrez_query);
522
523 return 0;
524 }
525
Blast_SummaryReturnNew()526 Blast_SummaryReturn* Blast_SummaryReturnNew()
527 {
528 return (Blast_SummaryReturn*) calloc(1, sizeof(Blast_SummaryReturn));
529 }
530
531 void
Blast_SummaryReturnClean(Blast_SummaryReturn * sum_returns)532 Blast_SummaryReturnClean(Blast_SummaryReturn* sum_returns)
533 {
534 if (sum_returns) {
535 sfree(sum_returns->ka_params);
536 sfree(sum_returns->ka_params_gap);
537 sum_returns->db_stats = s_SummaryDBStatsFree(sum_returns->db_stats);
538 sum_returns->search_params =
539 s_SummarySearchParamsFree(sum_returns->search_params);
540 sum_returns->diagnostics = Blast_DiagnosticsFree(sum_returns->diagnostics);
541 sum_returns->error = SBlastMessageFree(sum_returns->error);
542 sum_returns->pattern_info =
543 SPHIQueryInfoFree(sum_returns->pattern_info);
544 }
545 }
546
547 Blast_SummaryReturn*
Blast_SummaryReturnFree(Blast_SummaryReturn * sum_returns)548 Blast_SummaryReturnFree(Blast_SummaryReturn* sum_returns)
549 {
550 Blast_SummaryReturnClean(sum_returns);
551 sfree(sum_returns);
552 return NULL;
553 }
554
Blast_SummaryReturnFill(EBlastProgramType program_number,const BlastScoringOptions * score_options,const BlastScoreBlk * sbp,const LookupTableOptions * lookup_options,const BlastInitialWordOptions * word_options,const BlastExtensionOptions * ext_options,const BlastHitSavingOptions * hit_options,const BlastEffectiveLengthsOptions * eff_len_options,const QuerySetUpOptions * query_setup,const BlastQueryInfo * query_info,const BlastSeqSrc * seq_src,BlastDiagnostics ** diagnostics,Blast_SummaryReturn * sum_returns)555 Int2 Blast_SummaryReturnFill(EBlastProgramType program_number,
556 const BlastScoringOptions* score_options,
557 const BlastScoreBlk* sbp,
558 const LookupTableOptions* lookup_options,
559 const BlastInitialWordOptions* word_options,
560 const BlastExtensionOptions* ext_options,
561 const BlastHitSavingOptions* hit_options,
562 const BlastEffectiveLengthsOptions* eff_len_options,
563 const QuerySetUpOptions* query_setup,
564 const BlastQueryInfo* query_info,
565 const BlastSeqSrc* seq_src,
566 BlastDiagnostics** diagnostics,
567 Blast_SummaryReturn* sum_returns)
568 {
569 if (!sum_returns)
570 return -1;
571
572 if (score_options == NULL || sbp == NULL || lookup_options == NULL ||
573 word_options == NULL || ext_options == NULL || hit_options == NULL ||
574 eff_len_options == NULL || query_info == NULL)
575 return -1;
576
577 s_SummaryKAParametersFill(sbp, query_info, sum_returns);
578 s_SummaryDBStatsFill(program_number, eff_len_options, query_info,
579 seq_src, &(sum_returns->db_stats));
580
581 Blast_SearchParamsFill(program_number, score_options,
582 lookup_options, hit_options, query_setup, word_options,
583 NULL, &(sum_returns->search_params));
584 if (diagnostics)
585 {
586 sum_returns->diagnostics = *diagnostics;
587 *diagnostics = NULL;
588 }
589
590 if (Blast_ProgramIsPhiBlast(program_number)) {
591 /* Copy the pattern information structure. */
592 sum_returns->pattern_info =
593 SPHIQueryInfoCopy(query_info->pattern_info);
594 }
595
596 return 0;
597 }
598
599 /** Duplicates the Blast_SearchParams structure.
600 * @param params Search parameters structure [in]
601 * @return New copy of the search parameters structure.
602 */
603 static Blast_SearchParams*
s_SearchParamsDup(const Blast_SearchParams * params)604 s_SearchParamsDup(const Blast_SearchParams* params)
605 {
606 Blast_SearchParams* new_params;
607
608 if (!params)
609 return NULL;
610
611 new_params = (Blast_SearchParams*)
612 BlastMemDup(params, sizeof(Blast_SearchParams));
613 if (params->filter_string)
614 new_params->filter_string = strdup(params->filter_string);
615 if (params->matrix)
616 new_params->matrix = strdup(params->matrix);
617 if (params->pattern)
618 new_params->pattern = strdup(params->pattern);
619 if (params->entrez_query)
620 new_params->entrez_query = strdup(params->entrez_query);
621
622 return new_params;
623 }
624
Blast_SummaryReturnUpdate(const Blast_SummaryReturn * new_return,Blast_SummaryReturn ** full_return_out)625 int Blast_SummaryReturnUpdate(const Blast_SummaryReturn* new_return,
626 Blast_SummaryReturn* *full_return_out)
627 {
628 Blast_SummaryReturn* full_return;
629
630 if (!new_return)
631 return 0;
632 if (!full_return_out)
633 return -1;
634
635 /* If aggregate returns have not been allocated yet, do it here. Otherwise,
636 * remove all previously saved data, except for the diagnostics structure.
637 * Note that diagnostics structure must be allocated before the call to
638 * Blast_DiagnosticsUpdate.
639 */
640 if (*full_return_out == NULL) {
641 *full_return_out = full_return = Blast_SummaryReturnNew();
642 full_return->diagnostics = Blast_DiagnosticsInit();
643 } else {
644 BlastDiagnostics* diagnostics;
645 full_return = *full_return_out;
646 /* Save the diagnostics structure before cleaning the previous data. */
647 diagnostics = full_return->diagnostics;
648 full_return->diagnostics = NULL;
649 Blast_SummaryReturnClean(full_return);
650 full_return->diagnostics = diagnostics;
651 }
652
653 full_return->ka_params = (BLAST_KAParameters*)
654 BlastMemDup(new_return->ka_params, sizeof(BLAST_KAParameters));
655 full_return->ka_params_gap = (BLAST_KAParameters*)
656 BlastMemDup(new_return->ka_params_gap, sizeof(BLAST_KAParameters));
657 full_return->db_stats = (Blast_DatabaseStats*)
658 BlastMemDup(new_return->db_stats, sizeof(Blast_DatabaseStats));
659 full_return->search_params =
660 s_SearchParamsDup(new_return->search_params);
661
662 Blast_DiagnosticsUpdate(full_return->diagnostics, new_return->diagnostics);
663
664 if (new_return->error)
665 full_return->error = SBlastMessageDup(new_return->error);
666
667 full_return->pattern_info = SPHIQueryInfoCopy(new_return->pattern_info);
668
669 return 0;
670 }
671
672 /* @} */
673
674