1 /*  $Id: blastoptions_unit_test.cpp 518804 2016-11-08 04:18:18Z ucko $
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  * Authors: Christiam Camacho
27  *
28  */
29 
30 /** @file blastoptions_unit_test.cpp
31  * Unit tests for the BLAST options
32  */
33 
34 #include <ncbi_pch.hpp>
35 #include <corelib/test_boost.hpp>
36 #include <algo/blast/api/bl2seq.hpp>
37 #include "blast_setup.hpp"
38 #include "blast_objmgr_priv.hpp"
39 #include <algo/blast/core/blast_setup.h>
40 #include "test_objmgr.hpp"
41 #include <algo/blast/core/hspfilter_besthit.h>
42 #include <objects/blast/Blast4_parameter.hpp>
43 #include <objects/blast/Blast4_parameters.hpp>
44 
45 #ifndef SKIP_DOXYGEN_PROCESSING
46 
47 USING_NCBI_SCOPE;
48 USING_SCOPE(blast);
49 USING_SCOPE(objects);
50 
51 BOOST_AUTO_TEST_SUITE(blastoptions)
52 
BOOST_AUTO_TEST_CASE(TestTasksDefinitionsAndDocumentation)53 BOOST_AUTO_TEST_CASE(TestTasksDefinitionsAndDocumentation)
54 {
55     set<string> tasks = CBlastOptionsFactory::GetTasks();
56     ITERATE(set<string>, itr, tasks) {
57         string doc = CBlastOptionsFactory::GetDocumentation(*itr);
58         BOOST_CHECK(doc != "Unknown task");
59 
60         CRef<CBlastOptionsHandle> opt;
61         BOOST_CHECK_NO_THROW(opt.Reset(CBlastOptionsFactory::CreateTask(*itr)));
62     }
63 }
64 
BOOST_AUTO_TEST_CASE(RemoteOptionsTest)65 BOOST_AUTO_TEST_CASE( RemoteOptionsTest )
66 {
67      CBlastOptions opts(CBlastOptions::eRemote);
68      BOOST_CHECK_NO_THROW(opts.SetMaskAtHash());
69      BOOST_CHECK_NO_THROW(opts.SetDustFiltering());
70      BOOST_CHECK_NO_THROW(opts.SetSegFiltering());
71      BOOST_CHECK_NO_THROW(opts.SetRepeatFiltering());
72      BOOST_CHECK_NO_THROW(opts.SetRepeatFilteringDB("repeat/repeat_9606"));
73      BOOST_CHECK_NO_THROW(opts.SetFilterString("m L", false)); /* NCBI_FAKE_WARNING */
74 }
75 
BOOST_AUTO_TEST_CASE(BogusProgramWithCreate)76 BOOST_AUTO_TEST_CASE( BogusProgramWithCreate )
77 {
78     CRef<CBlastOptionsHandle> opts;
79     BOOST_CHECK_THROW(CBlastOptionsFactory::Create(eBlastNotSet),
80                       CBlastException);
81 }
82 
BOOST_AUTO_TEST_CASE(UnifiedPOptionsTest)83 BOOST_AUTO_TEST_CASE( UnifiedPOptionsTest )
84 {
85     CBlastOptions opts;
86 
87     BOOST_CHECK_EQUAL(opts.GetUnifiedP(), 0);
88     opts.SetUnifiedP(1);
89     BOOST_CHECK_EQUAL(opts.GetUnifiedP(), 1);
90     opts.SetUnifiedP();
91     BOOST_CHECK_EQUAL(opts.GetUnifiedP(), 0);
92 }
93 
BOOST_AUTO_TEST_CASE(GetSuggestedThresholdTest)94 BOOST_AUTO_TEST_CASE( GetSuggestedThresholdTest )
95 {
96     Int2 status=0;
97     double threshold;
98 
99     const int kThresholdSentinel = -33;
100 
101     threshold = kThresholdSentinel;
102     status = BLAST_GetSuggestedThreshold(eBlastTypeBlastn, "BLOSUM62", &threshold);
103     BOOST_CHECK_EQUAL(0, (int) status);
104     BOOST_CHECK_EQUAL(kThresholdSentinel, (int) threshold);
105 
106     status = BLAST_GetSuggestedThreshold(eBlastTypeBlastp, NULL, &threshold);
107     BOOST_CHECK_EQUAL(BLASTERR_INVALIDPARAM, (int) status);
108 
109     status = BLAST_GetSuggestedThreshold(eBlastTypeBlastp, "BLOSUM62", &threshold);
110     BOOST_CHECK_EQUAL(0, (int) status);
111     BOOST_CHECK_EQUAL(11, (int) threshold);
112 
113     status = BLAST_GetSuggestedThreshold(eBlastTypeBlastx, "BLOSUM62", &threshold);
114     BOOST_CHECK_EQUAL(0, (int) status);
115     BOOST_CHECK_EQUAL(12, (int) threshold);
116 
117     status = BLAST_GetSuggestedThreshold(eBlastTypeTblastn, "BLOSUM62", &threshold);
118     BOOST_CHECK_EQUAL(0, (int) status);
119     BOOST_CHECK_EQUAL(13, (int) threshold);
120 
121     status = BLAST_GetSuggestedThreshold(eBlastTypeTblastx, "BLOSUM62", &threshold);
122     BOOST_CHECK_EQUAL(0, (int) status);
123     BOOST_CHECK_EQUAL(13, (int) threshold);
124 
125     status = BLAST_GetSuggestedThreshold(eBlastTypeBlastp, "PAM30", &threshold);
126     BOOST_CHECK_EQUAL(0, (int) status);
127     BOOST_CHECK_EQUAL(16, (int) threshold);
128 
129     status = BLAST_GetSuggestedThreshold(eBlastTypeBlastp, "PAM140", &threshold);
130     BOOST_CHECK_EQUAL(0, (int) status);
131     BOOST_CHECK_EQUAL(11, (int) threshold);
132 }
133 
BOOST_AUTO_TEST_CASE(GetSuggestedWindowSizeTest)134 BOOST_AUTO_TEST_CASE( GetSuggestedWindowSizeTest )
135 {
136     Int2 status=0;
137     Int4 window_size;
138 
139     status = BLAST_GetSuggestedWindowSize(eBlastTypeBlastn, "BLOSUM62", &window_size);
140     BOOST_CHECK_EQUAL(0, (int) status);
141 
142     status = BLAST_GetSuggestedWindowSize(eBlastTypeBlastp, NULL, &window_size);
143     BOOST_CHECK_EQUAL(BLASTERR_INVALIDPARAM, (int) status);
144 
145     status = BLAST_GetSuggestedWindowSize(eBlastTypeBlastp, "BLOSUM62", &window_size);
146     BOOST_CHECK_EQUAL(0, (int) status);
147     BOOST_CHECK_EQUAL(40, window_size);
148 
149     status = BLAST_GetSuggestedWindowSize(eBlastTypeBlastx, "BLOSUM62", &window_size);
150     BOOST_CHECK_EQUAL(0, (int) status);
151     BOOST_CHECK_EQUAL(40, window_size);
152 
153     status = BLAST_GetSuggestedWindowSize(eBlastTypeBlastp, "BLOSUM80", &window_size);
154     BOOST_CHECK_EQUAL(0, (int) status);
155     BOOST_CHECK_EQUAL(25, window_size);
156 
157     status = BLAST_GetSuggestedWindowSize(eBlastTypeBlastp, "PAM140", &window_size);
158     BOOST_CHECK_EQUAL(0, (int) status);
159     BOOST_CHECK_EQUAL(40, window_size);
160 }
161 
BOOST_AUTO_TEST_CASE(GetProteinGapExistenceExtendParamsTest)162 BOOST_AUTO_TEST_CASE( GetProteinGapExistenceExtendParamsTest )
163 {
164     Int2 status=0;
165     Int4 existence=0, extension=0;
166 
167     status = BLAST_GetProteinGapExistenceExtendParams(NULL, &existence, &extension);
168     BOOST_CHECK_EQUAL(-1, (int) status);
169 
170     status = BLAST_GetProteinGapExistenceExtendParams("BLOSUM62", &existence, &extension);
171     BOOST_CHECK_EQUAL(0, (int) status);
172     BOOST_CHECK_EQUAL(11, existence);
173     BOOST_CHECK_EQUAL(1, extension);
174 
175     status = BLAST_GetProteinGapExistenceExtendParams("BLOSUM80", &existence, &extension);
176     BOOST_CHECK_EQUAL(0, (int) status);
177     BOOST_CHECK_EQUAL(10, existence);
178     BOOST_CHECK_EQUAL(1, extension);
179 
180     status = BLAST_GetProteinGapExistenceExtendParams("PAM250", &existence, &extension);
181     BOOST_CHECK_EQUAL(0, (int) status);
182     BOOST_CHECK_EQUAL(14, existence);
183     BOOST_CHECK_EQUAL(2, extension);
184 }
185 
BOOST_AUTO_TEST_CASE(GetNucleotideGapExistenceExtendParamsTest)186 BOOST_AUTO_TEST_CASE( GetNucleotideGapExistenceExtendParamsTest )
187 {
188     Int2 status=0;
189     int existence=-1, extension=-1;
190     int reward=0, penalty=0;
191 
192     reward = 0;
193     penalty = 3;
194     status = BLAST_GetNucleotideGapExistenceExtendParams(reward, penalty, &existence, &extension);
195     BOOST_CHECK_EQUAL(-1, (int) status);
196 
197     /* megablast linear values. */
198     reward = 1;
199     penalty = -3;
200     existence = 0;
201     extension = 0;
202     status = BLAST_GetNucleotideGapExistenceExtendParams(reward, penalty, &existence, &extension);
203     BOOST_CHECK_EQUAL(0, (int) status);
204     BOOST_CHECK_EQUAL(0, existence);
205     BOOST_CHECK_EQUAL(0, extension);
206 
207     reward = 1;
208     penalty = -3;
209     existence = -1;
210     extension = -1;
211     status = BLAST_GetNucleotideGapExistenceExtendParams(reward, penalty, &existence, &extension);
212     BOOST_CHECK_EQUAL(0, (int) status);
213     BOOST_CHECK_EQUAL(2, existence);
214     BOOST_CHECK_EQUAL(2, extension);
215 
216     reward = 2;
217     penalty = -5;
218     existence = -1;
219     extension = -1;
220     status = BLAST_GetNucleotideGapExistenceExtendParams(reward, penalty, &existence, &extension);
221     BOOST_CHECK_EQUAL(0, (int) status);
222     BOOST_CHECK_EQUAL(4, existence);
223     BOOST_CHECK_EQUAL(4, extension);
224 
225     reward = 1;
226     penalty = -2;
227     existence = -1;
228     extension = -1;
229     status = BLAST_GetNucleotideGapExistenceExtendParams(reward, penalty, &existence, &extension);
230     BOOST_CHECK_EQUAL(0, (int) status);
231     BOOST_CHECK_EQUAL(2, existence);
232     BOOST_CHECK_EQUAL(2, extension);
233 }
234 
BOOST_AUTO_TEST_CASE(FilterSetUpOptionsDustTest)235 BOOST_AUTO_TEST_CASE( FilterSetUpOptionsDustTest )
236 {
237     SBlastFilterOptions* filter_options;
238 
239     Int2 status = SBlastFilterOptionsNew(&filter_options, eDust);
240     BOOST_CHECK_EQUAL(0, (int) status);
241     BOOST_CHECK(filter_options);
242     BOOST_CHECK(filter_options->dustOptions);
243     BOOST_CHECK(filter_options->segOptions == NULL);
244     filter_options = SBlastFilterOptionsFree(filter_options);
245     BOOST_REQUIRE(filter_options == NULL);
246 }
247 
BOOST_AUTO_TEST_CASE(FilterSetUpOptionsSegTest)248 BOOST_AUTO_TEST_CASE( FilterSetUpOptionsSegTest )
249 {
250     SBlastFilterOptions* filter_options;
251 
252     Int2 status = SBlastFilterOptionsNew(&filter_options, eSeg);
253     BOOST_CHECK_EQUAL(0, (int) status);
254     BOOST_CHECK(filter_options);
255     BOOST_CHECK(filter_options->dustOptions == NULL);
256     BOOST_CHECK(filter_options->segOptions);
257     filter_options = SBlastFilterOptionsFree(filter_options);
258     BOOST_REQUIRE(filter_options == NULL);
259 }
260 
BOOST_AUTO_TEST_CASE(FilterSetUpOptionsNULLInput)261 BOOST_AUTO_TEST_CASE( FilterSetUpOptionsNULLInput )
262 {
263     Int2 status = SBlastFilterOptionsNew(NULL, eSeg);
264     BOOST_CHECK_EQUAL(1, (int) status);
265 }
266 
BOOST_AUTO_TEST_CASE(OptionsFreeNULLInput)267 BOOST_AUTO_TEST_CASE( OptionsFreeNULLInput )
268 {
269     SBlastFilterOptionsFree(NULL);
270     BlastQuerySetUpOptionsFree(NULL);
271     BlastInitialWordOptionsFree(NULL);
272     BlastExtensionOptionsFree(NULL);
273     BlastScoringOptionsFree(NULL);
274     BlastEffectiveLengthsOptionsFree(NULL);
275     LookupTableOptionsFree(NULL);
276     BlastHitSavingOptionsFree(NULL);
277     PSIBlastOptionsFree(NULL);
278     BlastDatabaseOptionsFree(NULL);
279 }
280 
281 // FIXME: good up to here
282 static void
s_FillSearchSpace(BlastQueryInfo * query_info,Int8 searchsp)283 s_FillSearchSpace(BlastQueryInfo *query_info, Int8 searchsp)
284 {
285     for (int i = query_info->first_context;
286                 i <= query_info->last_context; i++) {
287         if (query_info->contexts[i].query_length)
288             query_info->contexts[i].eff_searchsp = searchsp;
289     }
290 }
291 
292 // A helper function to setup the initial word parameters.
293 static BlastInitialWordParameters*
s_GetInitialWordParameters(EBlastProgramType program_number,BLAST_SequenceBlk * query_blk,BlastQueryInfo * query_info,BlastScoreBlk * sbp,const BlastInitialWordOptions * word_options,int subject_length,const BlastHitSavingParameters * hit_params)294 s_GetInitialWordParameters(EBlastProgramType program_number,
295                            BLAST_SequenceBlk* query_blk,
296                            BlastQueryInfo* query_info,
297                            BlastScoreBlk* sbp,
298                            const BlastInitialWordOptions* word_options,
299                            int subject_length,
300                            const BlastHitSavingParameters* hit_params)
301 {
302    BlastInitialWordParameters* word_params = NULL;
303    LookupTableWrap* lookup_wrap = NULL;
304    LookupTableOptions* lookup_options = NULL;
305    BlastSeqLoc* blast_seq_loc = BlastSeqLocNew(NULL, 0, query_info->contexts[0].query_length-1);
306    QuerySetUpOptions* query_options = NULL;
307    BlastQuerySetUpOptionsNew(&query_options);
308 
309    LookupTableOptionsNew(program_number, &lookup_options);
310    LookupTableWrapInit(query_blk, lookup_options, query_options, blast_seq_loc,
311                        sbp, &lookup_wrap, NULL, NULL, NULL);
312    BlastInitialWordParametersNew(program_number, word_options, hit_params,
313       lookup_wrap, sbp, query_info, subject_length, &word_params);
314 
315    blast_seq_loc = BlastSeqLocFree(blast_seq_loc);
316    BOOST_REQUIRE(blast_seq_loc == NULL);
317    lookup_wrap = LookupTableWrapFree(lookup_wrap);
318    BOOST_REQUIRE(lookup_wrap == NULL);
319    lookup_options = LookupTableOptionsFree(lookup_options);
320    BOOST_REQUIRE(lookup_options == NULL);
321    query_options = BlastQuerySetUpOptionsFree(query_options);
322    BOOST_REQUIRE(query_options == NULL);
323 
324    return word_params;
325 }
326 
BOOST_AUTO_TEST_CASE(testCalcLinkHSPCutoffs)327 BOOST_AUTO_TEST_CASE( testCalcLinkHSPCutoffs )
328 {
329     const EBlastProgramType kBlastProgram = eBlastTypeBlastp;
330     const Int4 kAvgSubjectLength = 335;
331     const Int4 kSpecificSubjectLength = 186;
332     const Int8 kDbLength = 703698559;
333     CSeq_id qid("gi|129295");
334     auto_ptr<SSeqLoc> qsl(
335         CTestObjMgr::Instance().CreateSSeqLoc(qid, eNa_strand_both));
336     CSeq_id sid("gi|129296");
337     auto_ptr<SSeqLoc> ssl(
338         CTestObjMgr::Instance().CreateSSeqLoc(sid, eNa_strand_both));
339 
340     CBl2Seq blaster(*qsl, *ssl, eBlastp);
341 
342     CBlastQueryInfo query_info;
343     CBLAST_SequenceBlk query_blk;
344     TSearchMessages blast_msg;
345 
346     const CBlastOptions& kOpts = blaster.GetOptionsHandle().GetOptions();
347     EBlastProgramType prog = kOpts.GetProgramType();
348     ENa_strand strand_opt = kOpts.GetStrandOption();
349 
350     SetupQueryInfo(const_cast<TSeqLocVector&>(blaster.GetQueries()),
351                    prog, strand_opt, &query_info);
352     SetupQueries(const_cast<TSeqLocVector&>(blaster.GetQueries()),
353                  query_info, &query_blk, prog, strand_opt, blast_msg);
354     ITERATE(TSearchMessages, m, blast_msg) {
355         BOOST_CHECK(m->empty());
356     }
357 
358     BlastScoringOptions* scoring_options;
359     BlastScoringOptionsNew(kBlastProgram, &scoring_options);
360     BLAST_FillScoringOptions(scoring_options, kBlastProgram, FALSE, 0, 0,
361           "BLOSUM62", -1, -1);
362     scoring_options->gapped_calculation = FALSE;
363 
364     BlastScoreBlk* sbp;
365     Blast_Message* blast_message = NULL;
366     BlastSetup_ScoreBlkInit(query_blk, query_info, scoring_options,
367                              kBlastProgram, &sbp, 1.0, &blast_message,
368                              &BlastFindMatrixPath);
369 
370     s_FillSearchSpace(query_info, 98483910471LL);
371 
372     BlastExtensionOptions* ext_options;
373     BlastExtensionOptionsNew(kBlastProgram, &ext_options,
374                              scoring_options->gapped_calculation);
375 
376     BlastHitSavingOptions* hit_options;
377     BlastHitSavingOptionsNew(kBlastProgram, &hit_options,
378                              scoring_options->gapped_calculation);
379     BOOST_CHECK(hit_options->do_sum_stats);
380 
381     BlastHitSavingParameters* hit_params;
382     BlastHitSavingParametersNew(kBlastProgram, hit_options, sbp, query_info, kAvgSubjectLength, 2, &hit_params);
383     BlastLinkHSPParameters* link_hsp_params = hit_params->link_hsp_params;
384 
385     BlastInitialWordOptions* word_options;
386     BlastInitialWordOptionsNew(kBlastProgram, &word_options);
387 
388     BlastInitialWordParameters* word_params = s_GetInitialWordParameters(kBlastProgram, query_blk,
389           query_info, sbp, word_options, kAvgSubjectLength, hit_params);
390 
391     CalculateLinkHSPCutoffs(kBlastProgram, query_info, sbp,
392                             link_hsp_params, word_params,
393                             kDbLength, kSpecificSubjectLength);
394 
395     BOOST_CHECK_EQUAL(36, link_hsp_params->cutoff_big_gap);
396     BOOST_CHECK_EQUAL(41, link_hsp_params->cutoff_small_gap);
397 
398     sbp = BlastScoreBlkFree(sbp);
399     BOOST_REQUIRE(sbp == NULL);
400     ext_options = BlastExtensionOptionsFree(ext_options);
401     BOOST_REQUIRE(ext_options == NULL);
402     scoring_options = BlastScoringOptionsFree(scoring_options);
403     BOOST_REQUIRE(scoring_options == NULL);
404     hit_params = BlastHitSavingParametersFree(hit_params);
405     BOOST_REQUIRE(hit_params == NULL);
406     hit_options = BlastHitSavingOptionsFree(hit_options);
407     BOOST_REQUIRE(hit_options == NULL);
408     word_params = BlastInitialWordParametersFree(word_params);
409     BOOST_REQUIRE(word_params == NULL);
410     word_options = BlastInitialWordOptionsFree(word_options);
411     BOOST_REQUIRE(word_options == NULL);
412     return;
413 }
414 
415 static BlastScoreBlk*
s_FillScoreBlkWithBadKbp(BlastQueryInfo * query_info)416 s_FillScoreBlkWithBadKbp(BlastQueryInfo* query_info) {
417 
418     BOOST_REQUIRE(query_info);
419     BlastScoreBlk* sbp = BlastScoreBlkNew(BLASTAA_SEQ_CODE, 2);
420 
421     sbp->kbp = sbp->kbp_std;
422 
423     Blast_KarlinBlk* kbp_bad = Blast_KarlinBlkNew();
424     kbp_bad->Lambda = -1.0;
425     kbp_bad->K = -1.0;
426     kbp_bad->logK = -1.0;
427     kbp_bad->H = -1.0;
428     sbp->kbp[0] = kbp_bad;
429     query_info->contexts[0].is_valid = FALSE;
430 
431     Blast_KarlinBlk* kbp_good = Blast_KarlinBlkNew();
432     kbp_good->Lambda = 1.1;
433     kbp_good->K = 1.1;
434     kbp_good->logK = 0.1;
435     kbp_good->H = 1.1;
436     sbp->kbp[1] = kbp_good;
437     query_info->contexts[1].is_valid = TRUE;
438 
439     return sbp;
440 }
441 
BOOST_AUTO_TEST_CASE(testBadKbpForLinkHSPCutoffs)442 BOOST_AUTO_TEST_CASE( testBadKbpForLinkHSPCutoffs )
443 {
444     const EBlastProgramType kBlastProgram = eBlastTypeTblastx;
445     const Int4 kAvgSubjectLength = 335;
446     const Int4 kSpecificSubjectLength = 186;
447     const Int8 kDbLength = 703698559;
448     const bool kIsGapped = true;
449 
450 
451     CBlastQueryInfo query_info(BlastQueryInfoNew(kBlastProgram, 1));
452     query_info->first_context = 0;
453     query_info->last_context = 1;
454     sfree(query_info->contexts);
455     query_info->contexts = (BlastContextInfo*) calloc(2, sizeof(BlastContextInfo));
456     query_info->contexts[query_info->last_context].query_offset = 300;
457     query_info->contexts[query_info->last_context].query_length = 300;
458 
459     BlastScoreBlk* sbp = s_FillScoreBlkWithBadKbp(query_info);
460 
461     s_FillSearchSpace(query_info, 98483910471LL);
462 
463     BlastExtensionOptions* ext_options;
464     BlastExtensionOptionsNew(kBlastProgram, &ext_options, kIsGapped);
465 
466     BlastHitSavingOptions* hit_options;
467     BlastHitSavingOptionsNew(kBlastProgram, &hit_options,
468                              kIsGapped);
469     BOOST_CHECK(hit_options->do_sum_stats);
470 
471     BlastHitSavingParameters* hit_params;
472     BlastHitSavingParametersNew(kBlastProgram, hit_options, sbp, query_info, kAvgSubjectLength, 0, &hit_params);
473     BlastLinkHSPParameters* link_hsp_params = hit_params->link_hsp_params;
474 
475     BlastInitialWordParameters word_params;
476     word_params.cutoff_score_min = 30;
477 
478     CalculateLinkHSPCutoffs(kBlastProgram, query_info, sbp,
479                             link_hsp_params, &word_params,
480                             kDbLength, kSpecificSubjectLength);
481 
482     BOOST_CHECK_EQUAL(11, link_hsp_params->cutoff_big_gap);
483     BOOST_CHECK_EQUAL(0, link_hsp_params->cutoff_small_gap);
484 
485     sbp = BlastScoreBlkFree(sbp);
486     BOOST_REQUIRE(sbp == NULL);
487     ext_options = BlastExtensionOptionsFree(ext_options);
488     BOOST_REQUIRE(ext_options == NULL);
489     hit_params = BlastHitSavingParametersFree(hit_params);
490     BOOST_REQUIRE(hit_params == NULL);
491     hit_options = BlastHitSavingOptionsFree(hit_options);
492     BOOST_REQUIRE(hit_options == NULL);
493     return;
494 }
495 
BOOST_AUTO_TEST_CASE(testCalcLinkHSPCutoffsSmallDB)496 BOOST_AUTO_TEST_CASE( testCalcLinkHSPCutoffsSmallDB )
497 {
498     const EBlastProgramType kBlastProgram = eBlastTypeBlastp;
499     const Int4 kAvgSubjectLength = 316;
500     const Int4 kSpecificSubjectLength = 21;
501     const Int8 kDbLength = 1358990;
502     CSeq_id qid("gi|129295");
503     auto_ptr<SSeqLoc> qsl(
504         CTestObjMgr::Instance().CreateSSeqLoc(qid, eNa_strand_both));
505     CSeq_id sid("gi|129296");
506     auto_ptr<SSeqLoc> ssl(
507         CTestObjMgr::Instance().CreateSSeqLoc(sid, eNa_strand_both));
508 
509     CBl2Seq blaster(*qsl, *ssl, eBlastp);
510 
511     CBlastQueryInfo query_info;
512     CBLAST_SequenceBlk query_blk;
513     TSearchMessages blast_msg;
514 
515     const CBlastOptions& kOpts = blaster.GetOptionsHandle().GetOptions();
516     EBlastProgramType prog = kOpts.GetProgramType();
517     ENa_strand strand_opt = kOpts.GetStrandOption();
518 
519     SetupQueryInfo(const_cast<TSeqLocVector&>(blaster.GetQueries()),
520                    prog, strand_opt, &query_info);
521     SetupQueries(const_cast<TSeqLocVector&>(blaster.GetQueries()),
522                  query_info, &query_blk, prog, strand_opt, blast_msg);
523     ITERATE(TSearchMessages, m, blast_msg) {
524         BOOST_CHECK(m->empty());
525     }
526 
527     BlastScoringOptions* scoring_options;
528     BlastScoringOptionsNew(kBlastProgram, &scoring_options);
529     BLAST_FillScoringOptions(scoring_options, kBlastProgram, FALSE, 0, 0,
530           "BLOSUM62", -1, -1);
531     scoring_options->gapped_calculation = FALSE;
532 
533     BlastScoreBlk* sbp = NULL;
534     Blast_Message* blast_message = NULL;
535     BlastSetup_ScoreBlkInit(query_blk, query_info, scoring_options,
536                             kBlastProgram, &sbp, 1.0, &blast_message,
537                             &BlastFindMatrixPath);
538 
539     s_FillSearchSpace(query_info, 218039195);
540 
541     BlastExtensionOptions* ext_options;
542     BlastExtensionOptionsNew(kBlastProgram, &ext_options,
543                              scoring_options->gapped_calculation);
544 
545     BlastHitSavingOptions* hit_options;
546     BlastHitSavingOptionsNew(kBlastProgram, &hit_options,
547                              scoring_options->gapped_calculation);
548 
549     BlastHitSavingParameters* hit_params;
550     BlastHitSavingParametersNew(kBlastProgram, hit_options, sbp, query_info, 0, 0, &hit_params);
551     BlastLinkHSPParameters* link_hsp_params = hit_params->link_hsp_params;
552 
553     BlastInitialWordOptions* word_options;
554     BlastInitialWordOptionsNew(kBlastProgram, &word_options);
555 
556     BlastInitialWordParameters* word_params = s_GetInitialWordParameters(kBlastProgram, query_blk,
557           query_info, sbp, word_options, kAvgSubjectLength, hit_params);
558 
559 
560     CalculateLinkHSPCutoffs(kBlastProgram, query_info, sbp,
561                             link_hsp_params, word_params,
562                             kDbLength, kSpecificSubjectLength);
563 
564     BOOST_CHECK_EQUAL(21, link_hsp_params->cutoff_big_gap);
565     BOOST_CHECK_EQUAL(0, link_hsp_params->cutoff_small_gap);
566 
567     sbp = BlastScoreBlkFree(sbp);
568     BOOST_REQUIRE(sbp == NULL);
569     ext_options = BlastExtensionOptionsFree(ext_options);
570     BOOST_REQUIRE(ext_options == NULL);
571     scoring_options = BlastScoringOptionsFree(scoring_options);
572     BOOST_REQUIRE(scoring_options == NULL);
573     hit_params = BlastHitSavingParametersFree(hit_params);
574     BOOST_REQUIRE(hit_params == NULL);
575     hit_options = BlastHitSavingOptionsFree(hit_options);
576     BOOST_REQUIRE(hit_options == NULL);
577     word_params = BlastInitialWordParametersFree(word_params);
578     BOOST_REQUIRE(word_params == NULL);
579     word_options = BlastInitialWordOptionsFree(word_options);
580     BOOST_REQUIRE(word_options == NULL);
581     return;
582 }
583 
BOOST_AUTO_TEST_CASE(testCalcLinkHSPResetGapProb)584 BOOST_AUTO_TEST_CASE( testCalcLinkHSPResetGapProb )
585 {
586     const EBlastProgramType kBlastProgram = eBlastTypeBlastp;
587     const Int4 kAvgSubjectLength = 335;
588     const Int4 kSpecificSubjectLength = 186;
589     const Int8 kDbLength = 703698559;
590     CSeq_id qid("gi|129295");
591     auto_ptr<SSeqLoc> qsl(
592         CTestObjMgr::Instance().CreateSSeqLoc(qid, eNa_strand_both));
593     CSeq_id sid("gi|129296");
594     auto_ptr<SSeqLoc> ssl(
595         CTestObjMgr::Instance().CreateSSeqLoc(sid, eNa_strand_both));
596 
597     CBl2Seq blaster(*qsl, *ssl, eBlastp);
598 
599     CBlastQueryInfo query_info;
600     CBLAST_SequenceBlk query_blk;
601     TSearchMessages blast_msg;
602 
603     const CBlastOptions& kOpts = blaster.GetOptionsHandle().GetOptions();
604     EBlastProgramType prog = kOpts.GetProgramType();
605     ENa_strand strand_opt = kOpts.GetStrandOption();
606 
607     SetupQueryInfo(const_cast<TSeqLocVector&>(blaster.GetQueries()),
608                    prog, strand_opt, &query_info);
609     SetupQueries(const_cast<TSeqLocVector&>(blaster.GetQueries()),
610                  query_info, &query_blk, prog, strand_opt, blast_msg);
611     ITERATE(TSearchMessages, m, blast_msg) {
612         BOOST_CHECK(m->empty());
613     }
614 
615     BlastScoringOptions* scoring_options;
616     BlastScoringOptionsNew(kBlastProgram, &scoring_options);
617     BLAST_FillScoringOptions(scoring_options, kBlastProgram, FALSE, 0, 0,
618           "BLOSUM62", -1, -1);
619     scoring_options->gapped_calculation = FALSE;
620 
621     BlastScoreBlk* sbp;
622     Blast_Message* blast_message = NULL;
623     BlastSetup_ScoreBlkInit(query_blk, query_info, scoring_options,
624                              kBlastProgram, &sbp, 1.0, &blast_message,
625                             &BlastFindMatrixPath);
626 
627     s_FillSearchSpace(query_info, 98483910471LL);
628 
629     BlastExtensionOptions* ext_options;
630     BlastExtensionOptionsNew(kBlastProgram, &ext_options,
631                              scoring_options->gapped_calculation);
632 
633     BlastHitSavingOptions* hit_options;
634     BlastHitSavingOptionsNew(kBlastProgram, &hit_options,
635                              scoring_options->gapped_calculation);
636     BOOST_CHECK(hit_options->do_sum_stats);
637 
638     BlastHitSavingParameters* hit_params;
639     BlastHitSavingParametersNew(kBlastProgram, hit_options, sbp, query_info, kAvgSubjectLength, 2, &hit_params);
640     BlastLinkHSPParameters* link_hsp_params = hit_params->link_hsp_params;
641 
642     BlastInitialWordOptions* word_options;
643     BlastInitialWordOptionsNew(kBlastProgram, &word_options);
644 
645     BlastInitialWordParameters* word_params = s_GetInitialWordParameters(kBlastProgram, query_blk,
646           query_info, sbp, word_options, kAvgSubjectLength, hit_params);
647 
648 
649     /* Reset gap_prob to zero to see that it's properly put back to correct values. */
650     link_hsp_params->gap_prob = 0.0;
651     link_hsp_params->gap_decay_rate = 0.5;
652 
653     CalculateLinkHSPCutoffs(kBlastProgram, query_info, sbp,
654                             link_hsp_params, word_params,
655                             kDbLength, kSpecificSubjectLength);
656 
657     BOOST_CHECK_EQUAL(5, (int) (10*link_hsp_params->gap_prob));
658     BOOST_CHECK_EQUAL(36, link_hsp_params->cutoff_big_gap);
659     BOOST_CHECK_EQUAL(41, link_hsp_params->cutoff_small_gap);
660 
661     query_blk = BlastSequenceBlkFree(query_blk);
662     BOOST_REQUIRE(query_blk == NULL);
663     sbp = BlastScoreBlkFree(sbp);
664     BOOST_REQUIRE(sbp == NULL);
665     scoring_options = BlastScoringOptionsFree(scoring_options);
666     BOOST_REQUIRE(scoring_options == NULL);
667     ext_options = BlastExtensionOptionsFree(ext_options);
668     BOOST_REQUIRE(ext_options == NULL);
669     hit_params = BlastHitSavingParametersFree(hit_params);
670     BOOST_REQUIRE(hit_params == NULL);
671     hit_options = BlastHitSavingOptionsFree(hit_options);
672     BOOST_REQUIRE(hit_options == NULL);
673     word_params = BlastInitialWordParametersFree(word_params);
674     BOOST_REQUIRE(word_params == NULL);
675     word_options = BlastInitialWordOptionsFree(word_options);
676     BOOST_REQUIRE(word_options == NULL);
677     return;
678 }
679 
BOOST_AUTO_TEST_CASE(testLargeWordSize)680 BOOST_AUTO_TEST_CASE( testLargeWordSize )
681 {
682     const EBlastProgramType kProgram = eBlastTypeBlastn;
683     const Boolean k_is_megablast = FALSE;
684     const int k_threshold = 0;
685     const int k_word_size = 100000;  /* Word-size bigger than INT2_MAX. */
686 
687     CBlastInitialWordOptions word_options;
688     BlastInitialWordOptionsNew(kProgram, &word_options);
689     CLookupTableOptions lookup_options;
690     LookupTableOptionsNew(kProgram, &lookup_options);
691     BLAST_FillLookupTableOptions(lookup_options, kProgram,
692                                  k_is_megablast, k_threshold, k_word_size);
693 
694     BOOST_CHECK_EQUAL(k_word_size, (int) lookup_options->word_size);
695 }
696 
MakeSomeInvalidKBP(Blast_KarlinBlk ** kbp_array,Int4 num,Int4 good_one,BlastQueryInfo * query_info)697 static void MakeSomeInvalidKBP(Blast_KarlinBlk** kbp_array,
698                                Int4 num,
699                                Int4 good_one,
700                                BlastQueryInfo* query_info)
701 {
702      Int4 index;
703 
704      BOOST_REQUIRE(num > good_one);
705 
706      for (index=0; index<num; index++)
707      {
708         Blast_KarlinBlk* kbp = NULL;
709         Blast_KarlinBlkFree(kbp_array[index]);
710         if (index != good_one)
711         {
712             kbp = Blast_KarlinBlkNew();
713             kbp->Lambda = -1;
714             kbp->K = -1;
715             kbp->H = -1;
716             query_info->contexts[index].is_valid = FALSE;
717         }
718         else
719         {
720             kbp = Blast_KarlinBlkNew();
721             kbp->Lambda = 1.37;
722             kbp->K = 0.71;
723             kbp->logK = -0.34;
724             kbp->H = 1.3;
725             query_info->contexts[index].is_valid = TRUE;
726         }
727         kbp_array[index] = kbp;
728      }
729      return;
730 }
731 
732 
BOOST_AUTO_TEST_CASE(testExtParamNewSomeInvalidKbp)733 BOOST_AUTO_TEST_CASE( testExtParamNewSomeInvalidKbp )
734 {
735     const int k_num_contexts=6;
736     const EBlastProgramType kBlastProgram=eBlastTypeBlastn;
737 
738     BlastExtensionOptions* ext_options;
739     BlastExtensionOptionsNew(kBlastProgram, &ext_options, true);
740     ext_options->gap_x_dropoff = 20;
741     ext_options->gap_x_dropoff_final = 20;
742 /*  FIXME
743     ext_options->gap_trigger = 20;
744 */
745 
746     CBlastQueryInfo query_info(BlastQueryInfoNew(eBlastTypeBlastx, 1));
747     BlastScoreBlk sb;
748     sb.kbp = (Blast_KarlinBlk**) calloc(k_num_contexts, sizeof(Blast_KarlinBlk*));
749     sb.kbp_gap = (Blast_KarlinBlk**) calloc(k_num_contexts, sizeof(Blast_KarlinBlk*));
750     MakeSomeInvalidKBP(sb.kbp, k_num_contexts, 4, query_info);
751     MakeSomeInvalidKBP(sb.kbp_gap, k_num_contexts, 4, query_info);
752     sb.scale_factor = 0.0;
753     sb.matrix_only_scoring = false;
754 
755     BlastExtensionParameters* ext_params;
756     BlastExtensionParametersNew(kBlastProgram, ext_options, &sb,
757                                 query_info, &ext_params);
758 
759 
760     BOOST_CHECK(ext_params->gap_x_dropoff > 0.0);
761     BOOST_CHECK(ext_params->gap_x_dropoff_final > 0.0);
762 /*  FIXME
763     BOOST_CHECK(ext_params->gap_trigger > 0.0);
764 */
765 
766     for (int index=query_info->first_context; index<=query_info->last_context; index++)
767     {
768        sb.kbp[index] = Blast_KarlinBlkFree(sb.kbp[index]);
769        sb.kbp_gap[index] = Blast_KarlinBlkFree(sb.kbp_gap[index]);
770     }
771     sfree(sb.kbp);
772     sfree(sb.kbp_gap);
773     ext_params = BlastExtensionParametersFree(ext_params);
774     BOOST_REQUIRE(ext_params == NULL);
775     ext_options = BlastExtensionOptionsFree(ext_options);
776     BOOST_REQUIRE(ext_options == NULL);
777 }
778 
MakeSomeValidKBP(Blast_KarlinBlk ** kbp_array,Int4 num,BlastQueryInfo * query_info)779 static void MakeSomeValidKBP(Blast_KarlinBlk** kbp_array, Int4 num,
780                              BlastQueryInfo* query_info)
781 {
782      for (Int4 index=0; index<num; index++)
783      {
784         Blast_KarlinBlk* kbp = NULL;
785         Blast_KarlinBlkFree(kbp_array[index]);
786         kbp = Blast_KarlinBlkNew();
787         kbp->Lambda = 1.30;
788         kbp->K = 0.71;
789         kbp->logK = -0.34;
790         kbp->H = 1.3;
791         kbp_array[index] = kbp;
792         query_info->contexts[index].is_valid = TRUE;
793      }
794      return;
795 }
796 
BOOST_AUTO_TEST_CASE(testExtensionParamsNew)797 BOOST_AUTO_TEST_CASE( testExtensionParamsNew )
798 {
799     const int k_num_contexts=6;
800     const EBlastProgramType kBlastProgram=eBlastTypeBlastn;
801 
802     BlastExtensionOptions* ext_options;
803     BlastExtensionOptionsNew(kBlastProgram, &ext_options, true);
804     ext_options->gap_x_dropoff = 20;
805     ext_options->gap_x_dropoff_final = 22;
806 
807     CBlastQueryInfo query_info(BlastQueryInfoNew(eBlastTypeBlastx, 1));
808     BlastScoreBlk sb;
809     sb.kbp = (Blast_KarlinBlk**) calloc(k_num_contexts, sizeof(Blast_KarlinBlk*));
810     sb.kbp_gap = (Blast_KarlinBlk**) calloc(k_num_contexts, sizeof(Blast_KarlinBlk*));
811     MakeSomeValidKBP(sb.kbp, k_num_contexts, query_info.Get());
812     MakeSomeValidKBP(sb.kbp_gap, k_num_contexts, query_info.Get());
813     sb.scale_factor = 0.0;
814     sb.matrix_only_scoring = FALSE;
815 
816 
817     BlastExtensionParameters* ext_params;
818     BlastExtensionParametersNew(kBlastProgram, ext_options, &sb,
819                                 query_info, &ext_params);
820 
821 
822     BOOST_CHECK_EQUAL(10, ext_params->gap_x_dropoff);
823     BOOST_CHECK_EQUAL(11, ext_params->gap_x_dropoff_final);
824 
825     ext_params = BlastExtensionParametersFree(ext_params);
826     BOOST_REQUIRE(ext_params == NULL);
827 
828     // gap_x_dropoff_final less than gap_x_dropoff, gap_x_dropoff_final should be adjusted.
829     ext_options->gap_x_dropoff = 25;
830     ext_options->gap_x_dropoff_final = 22;
831     BlastExtensionParametersNew(kBlastProgram, ext_options, &sb,
832                                 query_info, &ext_params);
833 
834 
835     BOOST_CHECK_EQUAL(13, ext_params->gap_x_dropoff);
836     BOOST_CHECK_EQUAL(13, ext_params->gap_x_dropoff_final);
837 
838     for (int index=query_info->first_context; index<=query_info->last_context; index++)
839     {
840        sb.kbp[index] = Blast_KarlinBlkFree(sb.kbp[index]);
841        sb.kbp_gap[index] = Blast_KarlinBlkFree(sb.kbp_gap[index]);
842     }
843     sfree(sb.kbp);
844     sfree(sb.kbp_gap);
845     ext_params = BlastExtensionParametersFree(ext_params);
846     BOOST_REQUIRE(ext_params == NULL);
847     ext_options = BlastExtensionOptionsFree(ext_options);
848     BOOST_REQUIRE(ext_options == NULL);
849    }
850 
BOOST_AUTO_TEST_CASE(testHitSavingParamNewSomeInvalidKbp)851 BOOST_AUTO_TEST_CASE( testHitSavingParamNewSomeInvalidKbp )
852 {
853     const EBlastProgramType kBlastProgram = eBlastTypeBlastn;
854     CSeq_id qid1("gi|555");
855     auto_ptr<SSeqLoc> qsl1(
856         CTestObjMgr::Instance().CreateSSeqLoc(qid1, eNa_strand_both));
857     CSeq_id qid2("gi|556");
858     auto_ptr<SSeqLoc> qsl2(
859         CTestObjMgr::Instance().CreateSSeqLoc(qid2, eNa_strand_both));
860     CSeq_id qid3("gi|557");
861     auto_ptr<SSeqLoc> qsl3(
862         CTestObjMgr::Instance().CreateSSeqLoc(qid3, eNa_strand_both));
863 
864     TSeqLocVector query_v;
865 
866     query_v.push_back(*qsl1);
867     query_v.push_back(*qsl2);
868     query_v.push_back(*qsl3);
869 
870     CBlastQueryInfo query_info;
871     CBLAST_SequenceBlk query_blk;
872     TSearchMessages blast_msg;
873     CRef<CBlastOptionsHandle> opts(CBlastOptionsFactory::Create(eBlastn));
874 
875     const CBlastOptions& kOpts = opts->GetOptions();
876     EBlastProgramType prog = kOpts.GetProgramType();
877     ENa_strand strand_opt = kOpts.GetStrandOption();
878 
879     SetupQueryInfo(query_v, prog, strand_opt, &query_info);
880     SetupQueries(query_v, query_info, &query_blk,
881                  prog, strand_opt, blast_msg);
882     ITERATE(TSearchMessages, m, blast_msg) {
883         BOOST_CHECK(m->empty());
884     }
885 
886     BlastScoringOptions* scoring_options;
887     BlastScoringOptionsNew(kBlastProgram, &scoring_options);
888     BLAST_FillScoringOptions(scoring_options, kBlastProgram, FALSE, 0, 0,
889           "BLOSUM62", -1, -1);
890 
891     BlastScoreBlk* sbp;
892     Blast_Message* blast_message = NULL;
893     BlastSetup_ScoreBlkInit(query_blk, query_info, scoring_options,
894                              kBlastProgram, &sbp, 1.0, &blast_message,
895                             &BlastFindMatrixPath);
896 
897     // Here we remove the valid KarlinBlks and put in some that might result from completely masked queries.
898     MakeSomeInvalidKBP(sbp->kbp,
899                        query_info->last_context+1,
900                        query_info->last_context-1,
901                        query_info.Get());
902     MakeSomeInvalidKBP(sbp->kbp_gap,
903                        query_info->last_context+1,
904                        query_info->last_context-1,
905                        query_info.Get());
906 
907     s_FillSearchSpace(query_info, 10000000LL);
908 
909     BlastExtensionOptions* ext_options;
910     BlastExtensionOptionsNew(kBlastProgram, &ext_options,
911                              scoring_options->gapped_calculation);
912 
913     BlastHitSavingOptions* hit_options;
914     BlastHitSavingOptionsNew(kBlastProgram, &hit_options,
915                              scoring_options->gapped_calculation);
916 
917     BlastHitSavingParameters* hit_params;
918     BlastHitSavingParametersNew(kBlastProgram, hit_options, sbp, query_info, 0, 0, &hit_params);
919 
920     BOOST_CHECK_EQUAL(10, hit_params->cutoff_score_min);
921 
922     scoring_options = BlastScoringOptionsFree(scoring_options);
923     BOOST_REQUIRE(scoring_options == NULL);
924     hit_params = BlastHitSavingParametersFree(hit_params);
925     BOOST_REQUIRE(hit_params == NULL);
926     hit_options = BlastHitSavingOptionsFree(hit_options);
927     BOOST_REQUIRE(hit_options == NULL);
928     ext_options = BlastExtensionOptionsFree(ext_options);
929     BOOST_REQUIRE(ext_options == NULL);
930     sbp = BlastScoreBlkFree(sbp);
931     BOOST_REQUIRE(sbp == NULL);
932 }
933 
934 // This simulates values calculated by for the human genomic database.
935 // the cutoff_score is larger than the score corresponding to an expect
936 // value of 10, so it gets set to that value.
BOOST_AUTO_TEST_CASE(testHitSavingParamNewGappedTblastnLargeSubjectSequence)937 BOOST_AUTO_TEST_CASE( testHitSavingParamNewGappedTblastnLargeSubjectSequence )
938 {
939     const EBlastProgramType kBlastProgram = eBlastTypeTblastn;
940     CSeq_id qid1("gi|3091");
941     auto_ptr<SSeqLoc> qsl1(
942         CTestObjMgr::Instance().CreateSSeqLoc(qid1, eNa_strand_both));
943 
944     TSeqLocVector query_v;
945     query_v.push_back(*qsl1);
946 
947     CBlastQueryInfo query_info;
948     CBLAST_SequenceBlk query_blk;
949     TSearchMessages blast_msg;
950     CRef<CBlastOptionsHandle> opts(CBlastOptionsFactory::Create(eTblastn));
951 
952     const CBlastOptions& kOpts = opts->GetOptions();
953     EBlastProgramType prog = kOpts.GetProgramType();
954     ENa_strand strand_opt = kOpts.GetStrandOption();
955 
956     SetupQueryInfo(query_v, prog, strand_opt, &query_info);
957     SetupQueries(query_v, query_info, &query_blk,
958                  prog, strand_opt, blast_msg);
959     ITERATE(TSearchMessages, m, blast_msg) {
960         BOOST_CHECK(m->empty());
961     }
962 
963 
964     BlastScoringOptions* scoring_options;
965     BlastScoringOptionsNew(kBlastProgram, &scoring_options);
966     BLAST_FillScoringOptions(scoring_options, kBlastProgram, FALSE, 0, 0,
967           "BLOSUM62", -1, -1);
968 
969     BlastScoreBlk* sbp;
970     Blast_Message* blast_message = NULL;
971     BlastSetup_ScoreBlkInit(query_blk, query_info, scoring_options,
972                              kBlastProgram, &sbp, 1.0, &blast_message,
973                             &BlastFindMatrixPath);
974 
975     s_FillSearchSpace(query_info, 481002014850LL);
976 
977     BlastExtensionOptions* ext_options;
978     BlastExtensionOptionsNew(kBlastProgram, &ext_options,
979                              scoring_options->gapped_calculation);
980 
981     BlastHitSavingOptions* hit_options;
982     BlastHitSavingOptionsNew(kBlastProgram, &hit_options,
983                              scoring_options->gapped_calculation);
984 
985     const int k_avg_subject_length=128199245;
986     BlastHitSavingParameters* hit_params;
987     BlastHitSavingParametersNew(kBlastProgram, hit_options, sbp, query_info, k_avg_subject_length, 2, &hit_params);
988 
989     BOOST_CHECK_EQUAL(66, hit_params->cutoff_score_min);
990     BOOST_CHECK_EQUAL(50, hit_params->prelim_evalue);
991 
992     scoring_options = BlastScoringOptionsFree(scoring_options);
993     BOOST_REQUIRE(scoring_options == NULL);
994     hit_params = BlastHitSavingParametersFree(hit_params);
995     BOOST_REQUIRE(hit_params == NULL);
996     hit_options = BlastHitSavingOptionsFree(hit_options);
997     BOOST_REQUIRE(hit_options == NULL);
998     ext_options = BlastExtensionOptionsFree(ext_options);
999     BOOST_REQUIRE(ext_options == NULL);
1000     sbp = BlastScoreBlkFree(sbp);
1001     BOOST_REQUIRE(sbp == NULL);
1002 }
1003 
1004 
1005 // This simulates values calculated by for the drosoph database.
1006 // the cutoff_score is between gap_trigger and the score corresponding
1007 // to an expect value of 10.
BOOST_AUTO_TEST_CASE(testHitSavingParamNewGappedTblastnMidsizeSubjectSequence)1008 BOOST_AUTO_TEST_CASE( testHitSavingParamNewGappedTblastnMidsizeSubjectSequence )
1009 {
1010     const EBlastProgramType kBlastProgram = eBlastTypeTblastn;
1011     CSeq_id qid1("gi|3091");
1012     auto_ptr<SSeqLoc> qsl1(
1013         CTestObjMgr::Instance().CreateSSeqLoc(qid1, eNa_strand_both));
1014 
1015     TSeqLocVector query_v;
1016     query_v.push_back(*qsl1);
1017 
1018     CBlastQueryInfo query_info;
1019     CBLAST_SequenceBlk query_blk;
1020     TSearchMessages blast_msg;
1021     CRef<CBlastOptionsHandle> opts(CBlastOptionsFactory::Create(eTblastn));
1022 
1023     const CBlastOptions& kOpts = opts->GetOptions();
1024     EBlastProgramType prog = kOpts.GetProgramType();
1025     ENa_strand strand_opt = kOpts.GetStrandOption();
1026 
1027     SetupQueryInfo(query_v, prog, strand_opt, &query_info);
1028     SetupQueries(query_v, query_info, &query_blk,
1029                  prog, strand_opt, blast_msg);
1030     ITERATE(TSearchMessages, m, blast_msg) {
1031         BOOST_CHECK(m->empty());
1032     }
1033 
1034     BlastScoringOptions* scoring_options;
1035     BlastScoringOptionsNew(kBlastProgram, &scoring_options);
1036     BLAST_FillScoringOptions(scoring_options, kBlastProgram, FALSE, 0, 0,
1037           "BLOSUM62", -1, -1);
1038 
1039     BlastScoreBlk* sbp;
1040     Blast_Message* blast_message = NULL;
1041     BlastSetup_ScoreBlkInit(query_blk, query_info, scoring_options,
1042                              kBlastProgram, &sbp, 1.0, &blast_message,
1043                             &BlastFindMatrixPath);
1044 
1045     s_FillSearchSpace(query_info, 20007999590LL);
1046 
1047     BlastExtensionOptions* ext_options;
1048     BlastExtensionOptionsNew(kBlastProgram, &ext_options,
1049                              scoring_options->gapped_calculation);
1050 
1051     BlastHitSavingOptions* hit_options;
1052     BlastHitSavingOptionsNew(kBlastProgram, &hit_options,
1053                              scoring_options->gapped_calculation);
1054 
1055     const int k_avg_subject_length=104833;
1056     BlastHitSavingParameters* hit_params;
1057     BlastHitSavingParametersNew(kBlastProgram, hit_options, sbp, query_info, k_avg_subject_length, 2, &hit_params);
1058 
1059     BOOST_CHECK_EQUAL(40, hit_params->cutoff_score_min);
1060     BOOST_CHECK_EQUAL(50, hit_params->prelim_evalue);
1061 
1062     scoring_options = BlastScoringOptionsFree(scoring_options);
1063     BOOST_REQUIRE(scoring_options == NULL);
1064     hit_params = BlastHitSavingParametersFree(hit_params);
1065     BOOST_REQUIRE(hit_params == NULL);
1066     hit_options = BlastHitSavingOptionsFree(hit_options);
1067     BOOST_REQUIRE(hit_options == NULL);
1068     ext_options = BlastExtensionOptionsFree(ext_options);
1069     BOOST_REQUIRE(ext_options == NULL);
1070     sbp = BlastScoreBlkFree(sbp);
1071     BOOST_REQUIRE(sbp == NULL);
1072 }
1073 
1074 // This checks that for repeated calls to BlastHitSavingParametersUpdate the
1075 // proper value for cutoff_score is returned.
BOOST_AUTO_TEST_CASE(testHitSavingParamUpdateMultipleCalls)1076 BOOST_AUTO_TEST_CASE( testHitSavingParamUpdateMultipleCalls )
1077 {
1078     const EBlastProgramType kBlastProgram = eBlastTypeTblastn;
1079     CSeq_id qid1("gi|3091");
1080     auto_ptr<SSeqLoc> qsl1(
1081         CTestObjMgr::Instance().CreateSSeqLoc(qid1, eNa_strand_both));
1082 
1083     TSeqLocVector query_v;
1084     query_v.push_back(*qsl1);
1085 
1086     CBlastQueryInfo query_info;
1087     CBLAST_SequenceBlk query_blk;
1088     TSearchMessages blast_msg;
1089     CRef<CBlastOptionsHandle> opts(CBlastOptionsFactory::Create(eTblastn));
1090 
1091     const CBlastOptions& kOpts = opts->GetOptions();
1092     EBlastProgramType prog = kOpts.GetProgramType();
1093     ENa_strand strand_opt = kOpts.GetStrandOption();
1094 
1095     SetupQueryInfo(query_v, prog, strand_opt, &query_info);
1096     SetupQueries(query_v, query_info, &query_blk,
1097                  prog, strand_opt, blast_msg);
1098     ITERATE(TSearchMessages, m, blast_msg) {
1099         BOOST_CHECK(m->empty());
1100     }
1101 
1102     BlastScoringOptions* scoring_options;
1103     BlastScoringOptionsNew(kBlastProgram, &scoring_options);
1104     BLAST_FillScoringOptions(scoring_options, kBlastProgram, FALSE, 0, 0,
1105           "BLOSUM62", -1, -1);
1106 
1107     BlastScoreBlk* sbp;
1108     Blast_Message* blast_message = NULL;
1109     BlastSetup_ScoreBlkInit(query_blk, query_info, scoring_options,
1110                              kBlastProgram, &sbp, 1.0, &blast_message,
1111                             &BlastFindMatrixPath);
1112 
1113     s_FillSearchSpace(query_info, 20007999590LL);
1114 
1115     BlastExtensionOptions* ext_options;
1116     BlastExtensionOptionsNew(kBlastProgram, &ext_options,
1117                              scoring_options->gapped_calculation);
1118 
1119     BlastHitSavingOptions* hit_options;
1120     BlastHitSavingOptionsNew(kBlastProgram, &hit_options,
1121                              scoring_options->gapped_calculation);
1122 
1123     const int k_avg_subject_length=104833;
1124     BlastHitSavingParameters* hit_params;
1125     BlastHitSavingParametersNew(kBlastProgram, hit_options, sbp, query_info, k_avg_subject_length, 2, &hit_params);
1126 
1127     BOOST_CHECK_EQUAL(40, hit_params->cutoff_score_min);
1128     BOOST_CHECK_EQUAL(40, hit_params->cutoffs[0].cutoff_score);
1129     BOOST_CHECK_EQUAL(40, hit_params->cutoffs[0].cutoff_score_max);
1130 
1131     s_FillSearchSpace(query_info, 2000799959LL);
1132 
1133     BlastHitSavingParametersUpdate(kBlastProgram, sbp, query_info, k_avg_subject_length, 2, hit_params);
1134     BOOST_CHECK_EQUAL(50, hit_params->prelim_evalue);
1135     BOOST_CHECK_EQUAL(40, hit_params->cutoff_score_min);
1136     BOOST_CHECK_EQUAL(40, hit_params->cutoffs[0].cutoff_score);
1137     BOOST_CHECK_EQUAL(40, hit_params->cutoffs[0].cutoff_score_max);
1138     //Check hit saving default
1139     BOOST_CHECK_EQUAL(0, hit_options->query_cov_hsp_perc);
1140     BOOST_CHECK_EQUAL(0, hit_options->max_hsps_per_subject);
1141     BOOST_CHECK_EQUAL(0, opts->GetQueryCovHspPerc());
1142     BOOST_CHECK_EQUAL(0, opts->GetMaxHspsPerSubject());
1143     opts->SetQueryCovHspPerc(55.2);
1144     opts->SetMaxHspsPerSubject(8);
1145     BOOST_CHECK_EQUAL(55.2, opts->GetQueryCovHspPerc());
1146     BOOST_CHECK_EQUAL(8, opts->GetMaxHspsPerSubject());
1147 
1148 
1149     scoring_options = BlastScoringOptionsFree(scoring_options);
1150     BOOST_REQUIRE(scoring_options == NULL);
1151     hit_params = BlastHitSavingParametersFree(hit_params);
1152     BOOST_REQUIRE(hit_params == NULL);
1153     hit_options = BlastHitSavingOptionsFree(hit_options);
1154     BOOST_REQUIRE(hit_options == NULL);
1155     ext_options = BlastExtensionOptionsFree(ext_options);
1156     BOOST_REQUIRE(ext_options == NULL);
1157     sbp = BlastScoreBlkFree(sbp);
1158     BOOST_REQUIRE(sbp == NULL);
1159 }
1160 
1161 // This simulates values calculated by for an EST database.
1162 // the cutoff_score is actually less than gap_trigger and gets
1163 // raised to that level.
BOOST_AUTO_TEST_CASE(testHitSavingParamNewGappedTblastnSmallSubjectSequence)1164 BOOST_AUTO_TEST_CASE( testHitSavingParamNewGappedTblastnSmallSubjectSequence )
1165 {
1166     const EBlastProgramType kBlastProgram = eBlastTypeTblastn;
1167     CSeq_id qid1("gi|17532675");
1168     auto_ptr<SSeqLoc> qsl1(
1169         CTestObjMgr::Instance().CreateSSeqLoc(qid1, eNa_strand_both));
1170 
1171     TSeqLocVector query_v;
1172     query_v.push_back(*qsl1);
1173 
1174     CBlastQueryInfo query_info;
1175     CBLAST_SequenceBlk query_blk;
1176     TSearchMessages blast_msg;
1177     CRef<CBlastOptionsHandle> opts(CBlastOptionsFactory::Create(eTblastn));
1178 
1179     const CBlastOptions& kOpts = opts->GetOptions();
1180     EBlastProgramType prog = kOpts.GetProgramType();
1181     ENa_strand strand_opt = kOpts.GetStrandOption();
1182 
1183     SetupQueryInfo(query_v, prog, strand_opt, &query_info);
1184     SetupQueries(query_v, query_info, &query_blk,
1185                  prog, strand_opt, blast_msg);
1186     ITERATE(TSearchMessages, m, blast_msg) {
1187         BOOST_CHECK(m->empty());
1188     }
1189 
1190     BlastScoringOptions* scoring_options;
1191     BlastScoringOptionsNew(kBlastProgram, &scoring_options);
1192     BLAST_FillScoringOptions(scoring_options, kBlastProgram, FALSE, 0, 0,
1193           "BLOSUM62", -1, -1);
1194 
1195     BlastScoreBlk* sbp;
1196     Blast_Message* blast_message = NULL;
1197     BlastSetup_ScoreBlkInit(query_blk, query_info, scoring_options,
1198                              kBlastProgram, &sbp, 1.0, &blast_message,
1199                             &BlastFindMatrixPath);
1200 
1201     s_FillSearchSpace(query_info, 1480902925051LL);
1202 
1203     BlastExtensionOptions* ext_options;
1204     BlastExtensionOptionsNew(kBlastProgram, &ext_options,
1205                              scoring_options->gapped_calculation);
1206 
1207     BlastHitSavingOptions* hit_options;
1208     BlastHitSavingOptionsNew(kBlastProgram, &hit_options,
1209                              scoring_options->gapped_calculation);
1210 
1211     const int k_avg_subject_length=523;
1212     BlastHitSavingParameters* hit_params;
1213     BlastHitSavingParametersNew(kBlastProgram, hit_options, sbp, query_info, k_avg_subject_length, 2, &hit_params);
1214 
1215     BOOST_CHECK_EQUAL(19, hit_params->cutoff_score_min);
1216     BOOST_CHECK_EQUAL(19, hit_params->cutoffs[0].cutoff_score);
1217     BOOST_CHECK_EQUAL(19, hit_params->cutoffs[0].cutoff_score_max);
1218 
1219     scoring_options = BlastScoringOptionsFree(scoring_options);
1220     BOOST_REQUIRE(scoring_options == NULL);
1221     hit_params = BlastHitSavingParametersFree(hit_params);
1222     BOOST_REQUIRE(hit_params == NULL);
1223     hit_options = BlastHitSavingOptionsFree(hit_options);
1224     BOOST_REQUIRE(hit_options == NULL);
1225     ext_options = BlastExtensionOptionsFree(ext_options);
1226     BOOST_REQUIRE(ext_options == NULL);
1227     sbp = BlastScoreBlkFree(sbp);
1228     BOOST_REQUIRE(sbp == NULL);
1229 }
1230 
1231 
BOOST_AUTO_TEST_CASE(testInitialWordParamNewSomeInvalidKbp)1232 BOOST_AUTO_TEST_CASE( testInitialWordParamNewSomeInvalidKbp )
1233 {
1234     const EBlastProgramType kBlastProgram = eBlastTypeBlastn;
1235     const Uint4 k_subject_length=10000;
1236     CSeq_id qid1("gi|555");
1237     auto_ptr<SSeqLoc> qsl1(
1238         CTestObjMgr::Instance().CreateSSeqLoc(qid1, eNa_strand_both));
1239     CSeq_id qid2("gi|556");
1240     auto_ptr<SSeqLoc> qsl2(
1241         CTestObjMgr::Instance().CreateSSeqLoc(qid2, eNa_strand_both));
1242     CSeq_id qid3("gi|557");
1243     auto_ptr<SSeqLoc> qsl3(
1244         CTestObjMgr::Instance().CreateSSeqLoc(qid3, eNa_strand_both));
1245 
1246     TSeqLocVector query_v;
1247 
1248     query_v.push_back(*qsl1);
1249     query_v.push_back(*qsl2);
1250     query_v.push_back(*qsl3);
1251 
1252     CBlastQueryInfo query_info;
1253     CBLAST_SequenceBlk query_blk;
1254     TSearchMessages blast_msg;
1255     CRef<CBlastOptionsHandle> opts(CBlastOptionsFactory::Create(eBlastn));
1256 
1257     const CBlastOptions& kOpts = opts->GetOptions();
1258     EBlastProgramType prog = kOpts.GetProgramType();
1259     ENa_strand strand_opt = kOpts.GetStrandOption();
1260 
1261     SetupQueryInfo(query_v, prog, strand_opt, &query_info);
1262     SetupQueries(query_v, query_info, &query_blk,
1263                  prog, strand_opt, blast_msg);
1264     ITERATE(TSearchMessages, m, blast_msg) {
1265         BOOST_CHECK(m->empty());
1266     }
1267 
1268     BlastScoringOptions* scoring_options;
1269     BlastScoringOptionsNew(kBlastProgram, &scoring_options);
1270     BLAST_FillScoringOptions(scoring_options, kBlastProgram, FALSE, 0, 0,
1271           "BLOSUM62", -1, -1);
1272 
1273     BlastScoreBlk* sbp;
1274     Blast_Message* blast_message = NULL;
1275     BlastSetup_ScoreBlkInit(query_blk, query_info, scoring_options,
1276                              kBlastProgram, &sbp, 1.0, &blast_message,
1277                             &BlastFindMatrixPath);
1278 
1279     // Here we remove the valid KarlinBlks and put in some that might result from completely masked queries.
1280     MakeSomeInvalidKBP(sbp->kbp, query_info->last_context+1,
1281                        query_info->last_context-1, query_info.Get());
1282     MakeSomeInvalidKBP(sbp->kbp_gap, query_info->last_context+1,
1283                        query_info->last_context-1, query_info.Get());
1284 
1285     s_FillSearchSpace(query_info, 1480902925051LL);
1286 
1287     BlastExtensionOptions* ext_options;
1288     BlastExtensionOptionsNew(kBlastProgram, &ext_options,
1289                              scoring_options->gapped_calculation);
1290 
1291     BlastHitSavingOptions* hit_options;
1292     BlastHitSavingOptionsNew(kBlastProgram, &hit_options,
1293                              scoring_options->gapped_calculation);
1294     BlastHitSavingParameters* hit_params;
1295     BlastHitSavingParametersNew(kBlastProgram, hit_options, sbp, query_info, 0, 0, &hit_params);
1296     hit_params->cutoff_score_min = 19;
1297 
1298     BlastInitialWordOptions* word_options;
1299     BlastInitialWordOptionsNew(kBlastProgram, &word_options);
1300     word_options->x_dropoff = 20;
1301 
1302     BlastInitialWordParameters* word_params = s_GetInitialWordParameters(kBlastProgram, query_blk,
1303           query_info, sbp, word_options, k_subject_length, hit_params);
1304 
1305     BOOST_CHECK_EQUAL(13, word_params->cutoff_score_min);
1306     BOOST_CHECK_EQUAL(11, word_params->x_dropoff_max);
1307 
1308     scoring_options = BlastScoringOptionsFree(scoring_options);
1309     BOOST_REQUIRE(scoring_options == NULL);
1310     hit_params = BlastHitSavingParametersFree(hit_params);
1311     BOOST_REQUIRE(hit_params == NULL);
1312     hit_options = BlastHitSavingOptionsFree(hit_options);
1313     BOOST_REQUIRE(hit_options == NULL);
1314     word_params = BlastInitialWordParametersFree(word_params);
1315     BOOST_REQUIRE(word_params == NULL);
1316     word_options = BlastInitialWordOptionsFree(word_options);
1317     BOOST_REQUIRE(word_options == NULL);
1318     ext_options = BlastExtensionOptionsFree(ext_options);
1319     BOOST_REQUIRE(ext_options == NULL);
1320     sbp = BlastScoreBlkFree(sbp);
1321     BOOST_REQUIRE(sbp == NULL);
1322 }
1323 
BOOST_AUTO_TEST_CASE(testRemoteFilterString)1324 BOOST_AUTO_TEST_CASE( testRemoteFilterString)
1325 {
1326        CBlastOptions opts(CBlastOptions::eRemote);
1327 
1328        opts.SetProgram(eBlastn);
1329        opts.SetFilterString("F", true);/* NCBI_FAKE_WARNING */
1330        // cerr << "dust filter" << (int) blast4_opts->GetParamByName("DustFiltering")->GetValue().GetBoolean() << '\n';
1331        BOOST_CHECK_EQUAL(false, opts.GetBlast4AlgoOpts()->GetParamByName("DustFiltering")->GetValue().GetBoolean());
1332        BOOST_CHECK_EQUAL(false, opts.GetBlast4AlgoOpts()->GetParamByName("RepeatFiltering")->GetValue().GetBoolean());
1333        opts.SetFilterString("T", true);/* NCBI_FAKE_WARNING */
1334        BOOST_CHECK_EQUAL(true, opts.GetBlast4AlgoOpts()->GetParamByName("DustFiltering")->GetValue().GetBoolean());
1335        BOOST_CHECK_EQUAL(false, opts.GetBlast4AlgoOpts()->GetParamByName("RepeatFiltering")->GetValue().GetBoolean());
1336 
1337        opts.SetProgram(eBlastp);
1338        opts.SetFilterString("F", true);/* NCBI_FAKE_WARNING */
1339        BOOST_CHECK_EQUAL(false, opts.GetBlast4AlgoOpts()->GetParamByName("SegFiltering")->GetValue().GetBoolean());
1340        opts.SetFilterString("T", true);/* NCBI_FAKE_WARNING */
1341        BOOST_CHECK_EQUAL(true, opts.GetBlast4AlgoOpts()->GetParamByName("SegFiltering")->GetValue().GetBoolean());
1342 
1343        opts.SetProgram(eBlastx);
1344        opts.SetFilterString("F", true);/* NCBI_FAKE_WARNING */
1345        BOOST_CHECK_EQUAL(false, opts.GetBlast4AlgoOpts()->GetParamByName("SegFiltering")->GetValue().GetBoolean());
1346        opts.SetFilterString("T", true);/* NCBI_FAKE_WARNING */
1347        BOOST_CHECK_EQUAL(true, opts.GetBlast4AlgoOpts()->GetParamByName("SegFiltering")->GetValue().GetBoolean());
1348 
1349        opts.SetProgram(eTblastn);
1350        opts.SetFilterString("F", true);/* NCBI_FAKE_WARNING */
1351        BOOST_CHECK_EQUAL(false, opts.GetBlast4AlgoOpts()->GetParamByName("SegFiltering")->GetValue().GetBoolean());
1352        opts.SetFilterString("T", true);/* NCBI_FAKE_WARNING */
1353        BOOST_CHECK_EQUAL(true, opts.GetBlast4AlgoOpts()->GetParamByName("SegFiltering")->GetValue().GetBoolean());
1354 
1355        opts.SetProgram(eTblastx);
1356        opts.SetFilterString("F", true);/* NCBI_FAKE_WARNING */
1357        BOOST_CHECK_EQUAL(false, opts.GetBlast4AlgoOpts()->GetParamByName("SegFiltering")->GetValue().GetBoolean());
1358        opts.SetFilterString("T", true);/* NCBI_FAKE_WARNING */
1359        BOOST_CHECK_EQUAL(true, opts.GetBlast4AlgoOpts()->GetParamByName("SegFiltering")->GetValue().GetBoolean());
1360 }
1361 
BOOST_AUTO_TEST_CASE(testNewFilteringDefaults)1362 BOOST_AUTO_TEST_CASE( testNewFilteringDefaults )
1363 {
1364     CRef<CBlastOptionsHandle> opts;
1365 
1366     opts = CBlastOptionsFactory::Create(eTblastn);
1367     BOOST_REQUIRE(opts.NotEmpty());
1368     char* filter_string = opts->GetFilterString(); /* NCBI_FAKE_WARNING */
1369     BOOST_CHECK_EQUAL(string("F"), string(filter_string));
1370     sfree(filter_string);
1371 
1372     opts = CBlastOptionsFactory::Create(eBlastp);
1373     BOOST_REQUIRE(opts.NotEmpty());
1374     filter_string = opts->GetFilterString(); /* NCBI_FAKE_WARNING */
1375     BOOST_CHECK_EQUAL(string("F"), string(filter_string));
1376     sfree(filter_string);
1377 }
1378 
BOOST_AUTO_TEST_CASE(testOptionsDeepCopy)1379 BOOST_AUTO_TEST_CASE( testOptionsDeepCopy )
1380 {
1381     CRef<CBlastOptionsHandle> optsHandle;
1382 
1383     optsHandle = CBlastOptionsFactory::Create(eBlastp);
1384     BOOST_REQUIRE(optsHandle.NotEmpty());
1385 
1386     optsHandle->SetFilterString("L;m;"); /* NCBI_FAKE_WARNING */
1387     optsHandle->SetDbLength(10000);
1388     optsHandle->SetOptions().SetPHIPattern("Y-S-[SA]-X-[LVIM]", false);
1389     optsHandle->SetOptions().SetQueryCovHspPerc(55.4);
1390     //optsHandle->GetOptions().DebugDumpText(NcbiCerr, "BLAST options - original", 1);
1391 
1392     CRef<CBlastOptions> optsClone = optsHandle->GetOptions().Clone();
1393     optsHandle.Reset();
1394     //optsClone->DebugDumpText(NcbiCerr, "BLAST options - clone", 1);
1395 
1396     BOOST_CHECK_EQUAL(optsClone->GetDbLength(), 10000);
1397     BOOST_CHECK_EQUAL(string(optsClone->GetFilterString()), string("L;m;")); /* NCBI_FAKE_WARNING */
1398     BOOST_CHECK_EQUAL(string(optsClone->GetPHIPattern()), string("Y-S-[SA]-X-[LVIM]"));
1399     BOOST_CHECK_EQUAL(optsClone->GetQueryCovHspPerc(), 55.4);
1400 
1401     // try setting and unsetting the best hit options (SB-339, issue #4)
1402     optsClone->SetBestHitScoreEdge(kBestHit_ScoreEdgeDflt);
1403     optsClone->SetBestHitOverhang(kBestHit_OverhangDflt);
1404     CRef<CBlastOptions> optsSnapshot = optsClone->Clone();
1405 
1406     optsClone->SetBestHitScoreEdge(kBestHit_ScoreEdgeDflt * 2);
1407     optsClone->SetBestHitOverhang(kBestHit_OverhangDflt * 2);
1408     BOOST_CHECK_CLOSE(optsClone->GetBestHitScoreEdge(), kBestHit_ScoreEdgeDflt * 2, 0.00000001);
1409     BOOST_CHECK_CLOSE(optsClone->GetBestHitOverhang(), kBestHit_OverhangDflt * 2, 0.00000001);
1410 
1411     optsClone = optsSnapshot;
1412     BOOST_CHECK_CLOSE(optsClone->GetBestHitScoreEdge(), kBestHit_ScoreEdgeDflt, 0.00000001);
1413     BOOST_CHECK_CLOSE(optsClone->GetBestHitOverhang(), kBestHit_OverhangDflt, 0.00000001);
1414 }
1415 
1416 BOOST_AUTO_TEST_SUITE_END()
1417 #endif /* SKIP_DOXYGEN_PROCESSING */
1418