cn3d_blast.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:24k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: cn3d_blast.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 18:28:09  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.34
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: cn3d_blast.cpp,v 1000.2 2004/06/01 18:28:09 gouriano Exp $
  10. * ===========================================================================
  11. *
  12. *                            PUBLIC DOMAIN NOTICE
  13. *               National Center for Biotechnology Information
  14. *
  15. *  This software/database is a "United States Government Work" under the
  16. *  terms of the United States Copyright Act.  It was written as part of
  17. *  the author's official duties as a United States Government employee and
  18. *  thus cannot be copyrighted.  This software/database is freely available
  19. *  to the public for use. The National Library of Medicine and the U.S.
  20. *  Government have not placed any restriction on its use or reproduction.
  21. *
  22. *  Although all reasonable efforts have been taken to ensure the accuracy
  23. *  and reliability of the software and data, the NLM and the U.S.
  24. *  Government do not and cannot warrant the performance or results that
  25. *  may be obtained by using this software or data. The NLM and the U.S.
  26. *  Government disclaim all warranties, express or implied, including
  27. *  warranties of performance, merchantability or fitness for any particular
  28. *  purpose.
  29. *
  30. *  Please cite the author in any work or product based on this material.
  31. *
  32. * ===========================================================================
  33. *
  34. * Authors:  Paul Thiessen
  35. *
  36. * File Description:
  37. *      module for aligning with BLAST and related algorithms
  38. *
  39. * ===========================================================================
  40. */
  41. #ifdef _MSC_VER
  42. #pragma warning(disable:4018)   // disable signed/unsigned mismatch warning in MSVC
  43. #endif
  44. #include <ncbi_pch.hpp>
  45. #include <corelib/ncbistd.hpp>
  46. #include <objects/seqalign/Seq_align.hpp>
  47. #include <objects/seqalign/Dense_seg.hpp>
  48. #include <objects/seqalign/Score.hpp>
  49. #include <objects/general/Object_id.hpp>
  50. #ifdef __WXMSW__
  51. #include <windows.h>
  52. #include <wx/msw/winundef.h>
  53. #endif
  54. #include <wx/wx.h>
  55. // C stuff
  56. #include <objseq.h>
  57. #include <blast.h>
  58. #include <blastkar.h>
  59. #include "cn3d_blast.hpp"
  60. #include "structure_set.hpp"
  61. #include "sequence_set.hpp"
  62. #include "block_multiple_alignment.hpp"
  63. #include "cn3d_tools.hpp"
  64. #include "asn_converter.hpp"
  65. #include "molecule_identifier.hpp"
  66. #include "cn3d_threader.hpp"
  67. // hack so I can catch memory leaks specific to this module, at the line where allocation occurs
  68. #ifdef _DEBUG
  69. #ifdef MemNew
  70. #undef MemNew
  71. #endif
  72. #define MemNew(sz) memset(malloc(sz), 0, (sz))
  73. #endif
  74. USING_NCBI_SCOPE;
  75. USING_SCOPE(objects);
  76. BEGIN_SCOPE(Cn3D)
  77. const string BLASTer::BLASTResidues = "-ABCDEFGHIKLMNPQRSTVWXYZU*";
  78. // gives BLAST residue number for a character (or # for 'X' if char not found)
  79. int LookupBLASTResidueNumberFromCharacter(char r)
  80. {
  81.     typedef map < char, int > Char2Int;
  82.     static Char2Int charMap;
  83.     if (charMap.size() == 0) {
  84.         for (int i=0; i<BLASTer::BLASTResidues.size(); ++i)
  85.             charMap[BLASTer::BLASTResidues[i]] = i;
  86.     }
  87.     Char2Int::const_iterator n = charMap.find(toupper(r));
  88.     if (n != charMap.end())
  89.         return n->second;
  90.     else
  91.         return charMap.find('X')->second;
  92. }
  93. // gives BLAST residue number for a threader residue number (or # for 'X' if char == -1)
  94. int LookupBLASTResidueNumberFromThreaderResidueNumber(char r)
  95. {
  96.     r = toupper(r);
  97.     return LookupBLASTResidueNumberFromCharacter(
  98.             (r >= 0 && r < Threader::ThreaderResidues.size()) ? Threader::ThreaderResidues[r] : 'X');
  99. }
  100. #ifdef _DEBUG
  101. #define PRINT_PSSM // for testing/debugging
  102. #endif
  103. static BLAST_OptionsBlkPtr CreateBlastOptionsBlk(void)
  104. {
  105.     BLAST_OptionsBlkPtr bob = BLASTOptionNew("blastp", true);
  106.     bob->db_length = 2717223;    // size of CDD database v1.62
  107.     bob->scalingFactor = 1.0;
  108.     return bob;
  109. }
  110. static void SetEffectiveSearchSpaceSize(BLAST_OptionsBlkPtr bob, Int4 queryLength)
  111. {
  112.     bob->searchsp_eff = BLASTCalculateSearchSpace(bob, 1, bob->db_length, queryLength);
  113. }
  114. void BLASTer::CreateNewPairwiseAlignmentsByBlast(const BlockMultipleAlignment *multiple,
  115.     const AlignmentList& toRealign, AlignmentList *newAlignments, bool usePSSM)
  116. {
  117.     if (usePSSM && !multiple) {
  118.         ERRORMSG("usePSSM true, but NULL multiple alignment");
  119.         return;
  120.     }
  121.     // set up BLAST stuff
  122.     BLAST_OptionsBlkPtr options = CreateBlastOptionsBlk();
  123.     if (!options) {
  124.         ERRORMSG("BLASTOptionNew() failed");
  125.         return;
  126.     }
  127.     // create Seq-loc intervals
  128.     SeqLocPtr masterSeqLoc = (SeqLocPtr) MemNew(sizeof(SeqLoc));
  129.     masterSeqLoc->choice = SEQLOC_INT;
  130.     SeqIntPtr masterSeqInt = SeqIntNew();
  131.     masterSeqLoc->data.ptrvalue = masterSeqInt;
  132.     if (multiple) {
  133.         BlockMultipleAlignment::UngappedAlignedBlockList uaBlocks;
  134.         multiple->GetUngappedAlignedBlocks(&uaBlocks);
  135.         if (uaBlocks.size() > 0) {
  136.             int excess = 0;
  137.             if (!RegistryGetInteger(REG_ADVANCED_SECTION, REG_FOOTPRINT_RES, &excess))
  138.                 WARNINGMSG("Can't get footprint excess residues from registry");
  139.             masterSeqInt->from = uaBlocks.front()->GetRangeOfRow(0)->from - excess;
  140.             if (masterSeqInt->from < 0)
  141.                 masterSeqInt->from = 0;
  142.             masterSeqInt->to = uaBlocks.back()->GetRangeOfRow(0)->to + excess;
  143.             if (masterSeqInt->to >= multiple->GetMaster()->Length())
  144.                 masterSeqInt->to = multiple->GetMaster()->Length() - 1;
  145.         } else {
  146.             masterSeqInt->from = 0;
  147.             masterSeqInt->to = multiple->GetMaster()->Length() - 1;
  148.         }
  149.     }
  150.     SeqLocPtr slaveSeqLoc = (SeqLocPtr) MemNew(sizeof(SeqLoc));
  151.     slaveSeqLoc->choice = SEQLOC_INT;
  152.     SeqIntPtr slaveSeqInt = SeqIntNew();
  153.     slaveSeqLoc->data.ptrvalue = slaveSeqInt;
  154.     // create BLAST_Matrix if using PSSM from multiple
  155.     const BLAST_Matrix *BLASTmatrix = NULL;
  156.     if (usePSSM) BLASTmatrix = multiple->GetPSSM();
  157.     string err;
  158.     AlignmentList::const_iterator s, se = toRealign.end();
  159.     for (s=toRealign.begin(); s!=se; ++s) {
  160.         if (multiple && (*s)->GetMaster() != multiple->GetMaster())
  161.             ERRORMSG("master sequence mismatch");
  162.         // get C Bioseq for master
  163.         const Sequence *masterSeq = multiple ? multiple->GetMaster() : (*s)->GetMaster();
  164.         Bioseq *masterBioseq = masterSeq->parentSet->GetOrCreateBioseq(masterSeq);
  165.         masterSeqInt->id = masterBioseq->id;
  166.         // override master alignment interval if specified
  167.         if (!multiple) {
  168.             if ((*s)->alignMasterFrom >= 0 && (*s)->alignMasterFrom < masterSeq->Length() &&
  169.                 (*s)->alignMasterTo >= 0 && (*s)->alignMasterTo < masterSeq->Length() &&
  170.                 (*s)->alignMasterFrom <= (*s)->alignMasterTo)
  171.             {
  172.                 masterSeqInt->from = (*s)->alignMasterFrom;
  173.                 masterSeqInt->to = (*s)->alignMasterTo;
  174.             } else {
  175.                 masterSeqInt->from = 0;
  176.                 masterSeqInt->to = masterSeq->Length() - 1;
  177.             }
  178.         }
  179.         // get C Bioseq for slave of each incoming (pairwise) alignment
  180.         const Sequence *slaveSeq = (*s)->GetSequenceOfRow(1);
  181.         Bioseq *slaveBioseq = slaveSeq->parentSet->GetOrCreateBioseq(slaveSeq);
  182.         // setup Seq-loc interval for slave
  183.         slaveSeqInt->id = slaveBioseq->id;
  184.         slaveSeqInt->from =
  185.             ((*s)->alignSlaveFrom >= 0 && (*s)->alignSlaveFrom < slaveSeq->Length()) ?
  186.                 (*s)->alignSlaveFrom : 0;
  187.         slaveSeqInt->to =
  188.             ((*s)->alignSlaveTo >= 0 && (*s)->alignSlaveTo < slaveSeq->Length()) ?
  189.                 (*s)->alignSlaveTo : slaveSeq->Length() - 1;
  190.         INFOMSG("for BLAST: master range " <<
  191.                 (masterSeqInt->from + 1) << " to " << (masterSeqInt->to + 1) << ", slave range " <<
  192.                 (slaveSeqInt->from + 1) << " to " << (slaveSeqInt->to + 1));
  193.         // set search space size
  194.         SetEffectiveSearchSpaceSize(options, slaveSeqInt->to - slaveSeqInt->from + 1);
  195.         INFOMSG("effective search space size: " << ((int) options->searchsp_eff));
  196.         // actually do the BLAST alignment
  197.         SeqAlign *salp = NULL;
  198.         if (usePSSM) {
  199.             INFOMSG("calling BlastTwoSequencesByLocWithCallback(); PSSM db_length "
  200.                 << (int) options->db_length << ", K " << BLASTmatrix->karlinK);
  201.             salp = BlastTwoSequencesByLocWithCallback(
  202.                 masterSeqLoc, slaveSeqLoc,
  203.                 "blastp", options,
  204.                 NULL, NULL, NULL,
  205.                 const_cast<BLAST_Matrix*>(BLASTmatrix));
  206.         } else {
  207.             INFOMSG("calling BlastTwoSequencesByLoc()");
  208.             salp = BlastTwoSequencesByLoc(masterSeqLoc, slaveSeqLoc, "blastp", options);
  209.         }
  210.         // create new alignment structure
  211.         BlockMultipleAlignment::SequenceList *seqs = new BlockMultipleAlignment::SequenceList(2);
  212.         (*seqs)[0] = masterSeq;
  213.         (*seqs)[1] = slaveSeq;
  214.         BlockMultipleAlignment *newAlignment =
  215.             new BlockMultipleAlignment(seqs, slaveSeq->parentSet->alignmentManager);
  216.         newAlignment->SetRowDouble(0, kMax_Double);
  217.         newAlignment->SetRowDouble(1, kMax_Double);
  218.         // process the result
  219.         if (!salp) {
  220.             WARNINGMSG("BLAST failed to find a significant alignment");
  221.         } else {
  222.             // convert C SeqAlign to C++ for convenience
  223. #ifdef _DEBUG
  224.             AsnIoPtr aip = AsnIoOpen("seqalign.txt", "w");
  225.             SeqAlignAsnWrite(salp, aip, NULL);
  226.             AsnIoFree(aip, true);
  227. #endif
  228.             CSeq_align sa;
  229.             bool okay = ConvertAsnFromCToCPP(salp, (AsnWriteFunc) SeqAlignAsnWrite, &sa, &err);
  230.             SeqAlignSetFree(salp);
  231.             if (!okay) {
  232.                 ERRORMSG("Conversion of SeqAlign to C++ object failed");
  233.                 continue;
  234.             }
  235.             // make sure the structure of this SeqAlign is what we expect
  236.             if (!sa.IsSetDim() || sa.GetDim() != 2 ||
  237.                 !sa.GetSegs().IsDenseg() || sa.GetSegs().GetDenseg().GetDim() != 2 ||
  238.                 !masterSeq->identifier->MatchesSeqId(*(sa.GetSegs().GetDenseg().GetIds().front())) ||
  239.                 !slaveSeq->identifier->MatchesSeqId(*(sa.GetSegs().GetDenseg().GetIds().back()))) {
  240.                 ERRORMSG("Confused by BLAST result format");
  241.                 continue;
  242.             }
  243.             // fill out with blocks from BLAST alignment
  244.             CDense_seg::TStarts::const_iterator iStart = sa.GetSegs().GetDenseg().GetStarts().begin();
  245.             CDense_seg::TLens::const_iterator iLen = sa.GetSegs().GetDenseg().GetLens().begin();
  246. #ifdef _DEBUG
  247.             int raw_pssm = 0, raw_bl62 = 0;
  248. #endif
  249.             for (int i=0; i<sa.GetSegs().GetDenseg().GetNumseg(); ++i) {
  250.                 int masterStart = *(iStart++), slaveStart = *(iStart++), len = *(iLen++);
  251.                 if (masterStart >= 0 && slaveStart >= 0 && len > 0) {
  252.                     UngappedAlignedBlock *newBlock = new UngappedAlignedBlock(newAlignment);
  253.                     newBlock->SetRangeOfRow(0, masterStart, masterStart + len - 1);
  254.                     newBlock->SetRangeOfRow(1, slaveStart, slaveStart + len - 1);
  255.                     newBlock->width = len;
  256.                     newAlignment->AddAlignedBlockAtEnd(newBlock);
  257. #ifdef _DEBUG
  258.                     // calculate score manually, to compare with that returned by BLAST
  259.                     for (int j=0; j<len; ++j) {
  260.                         if (usePSSM)
  261.                             raw_pssm += BLASTmatrix->matrix
  262.                                 [masterStart + j]
  263.                                 [LookupBLASTResidueNumberFromCharacter(
  264.                                     slaveSeq->sequenceString[slaveStart + j])];
  265.                         raw_bl62 += GetBLOSUM62Score(
  266.                             masterSeq->sequenceString[masterStart + j],
  267.                             slaveSeq->sequenceString[slaveStart + j]);
  268.                     }
  269. #endif
  270.                 }
  271. #ifdef _DEBUG
  272.                 else if ((masterStart < 0 || slaveStart < 0) && len > 0) {
  273.                     int gap = options->gap_open + options->gap_extend * len;
  274.                     if (usePSSM) raw_pssm -= gap;
  275.                     raw_bl62 -= gap;
  276.                 }
  277. #endif
  278.             }
  279. #ifdef _DEBUG
  280.             TRACEMSG("Calculated raw score by PSSM: " << raw_pssm);
  281.             TRACEMSG("Calculated raw score by BLOSUM62: " << raw_bl62);
  282. #endif
  283.             // get scores
  284.             if (sa.IsSetScore()) {
  285.                 wxString scores;
  286.                 scores.Printf("BLAST result for %s vs. %s:",
  287.                     masterSeq->identifier->ToString().c_str(),
  288.                     slaveSeq->identifier->ToString().c_str());
  289.                 CSeq_align::TScore::const_iterator sc, sce = sa.GetScore().end();
  290.                 for (sc=sa.GetScore().begin(); sc!=sce; ++sc) {
  291.                     if ((*sc)->IsSetId() && (*sc)->GetId().IsStr()) {
  292.                         // E-value (put in status line and double values)
  293.                         if ((*sc)->GetValue().IsReal() && (*sc)->GetId().GetStr() == "e_value") {
  294.                             newAlignment->SetRowDouble(0, (*sc)->GetValue().GetReal());
  295.                             newAlignment->SetRowDouble(1, (*sc)->GetValue().GetReal());
  296.                             wxString status;
  297.                             status.Printf("E-value %g", (*sc)->GetValue().GetReal());
  298.                             newAlignment->SetRowStatusLine(0, status.c_str());
  299.                             newAlignment->SetRowStatusLine(1, status.c_str());
  300.                             wxString tmp = scores;
  301.                             scores.Printf("%s E-value: %g", tmp.c_str(), (*sc)->GetValue().GetReal());
  302.                         }
  303.                         // raw score
  304.                         if ((*sc)->GetValue().IsInt() && (*sc)->GetId().GetStr() == "score") {
  305.                             wxString tmp = scores;
  306.                             scores.Printf("%s raw: %i", tmp.c_str(), (*sc)->GetValue().GetInt());
  307.                         }
  308.                         // bit score
  309.                         if ((*sc)->GetValue().IsReal() && (*sc)->GetId().GetStr() == "bit_score") {
  310.                             wxString tmp = scores;
  311.                             scores.Printf("%s bit score: %g", tmp.c_str(), (*sc)->GetValue().GetReal());
  312.                         }
  313.                     }
  314.                 }
  315.                 INFOMSG(scores.c_str());
  316.             }
  317.         }
  318.         // finalize and and add new alignment to list
  319.         if (newAlignment->AddUnalignedBlocks() && newAlignment->UpdateBlockMapAndColors(false)) {
  320.             newAlignments->push_back(newAlignment);
  321.         } else {
  322.             ERRORMSG("error finalizing alignment");
  323.             delete newAlignment;
  324.         }
  325.     }
  326.     BLASTOptionDelete(options);
  327.     masterSeqInt->id = NULL;    // don't free Seq-id, since it belongs to the Bioseq
  328.     SeqIntFree(masterSeqInt);
  329.     MemFree(masterSeqLoc);
  330.     slaveSeqInt->id = NULL;
  331.     SeqIntFree(slaveSeqInt);
  332.     MemFree(slaveSeqLoc);
  333. }
  334. void BLASTer::CalculateSelfHitScores(const BlockMultipleAlignment *multiple)
  335. {
  336.     if (!multiple) {
  337.         ERRORMSG("NULL multiple alignment");
  338.         return;
  339.     }
  340.     // set up BLAST stuff
  341.     BLAST_OptionsBlkPtr options = CreateBlastOptionsBlk();
  342.     if (!options) {
  343.         ERRORMSG("BLASTOptionNew() failed");
  344.         return;
  345.     }
  346.     // get master sequence
  347.     const Sequence *masterSeq = multiple->GetMaster();
  348.     Bioseq *masterBioseq = masterSeq->parentSet->GetOrCreateBioseq(masterSeq);
  349.     // create Seq-loc interval for master and slave
  350.     SeqLocPtr masterSeqLoc = (SeqLocPtr) MemNew(sizeof(SeqLoc));
  351.     masterSeqLoc->choice = SEQLOC_INT;
  352.     SeqIntPtr masterSeqInt = SeqIntNew();
  353.     masterSeqLoc->data.ptrvalue = masterSeqInt;
  354.     masterSeqInt->id = masterBioseq->id;
  355.     BlockMultipleAlignment::UngappedAlignedBlockList uaBlocks;
  356.     multiple->GetUngappedAlignedBlocks(&uaBlocks);
  357.     if (uaBlocks.size() == 0) {
  358.         ERRORMSG("Self-hit requires at least one aligned block");
  359.         return;
  360.     }
  361.     int excess = 0;
  362.     if (!RegistryGetInteger(REG_ADVANCED_SECTION, REG_FOOTPRINT_RES, &excess))
  363.         WARNINGMSG("Can't get footprint excess residues from registry");
  364.     masterSeqInt->from = uaBlocks.front()->GetRangeOfRow(0)->from - excess;
  365.     if (masterSeqInt->from < 0) masterSeqInt->from = 0;
  366.     masterSeqInt->to = uaBlocks.back()->GetRangeOfRow(0)->to + excess;
  367.     if (masterSeqInt->to >= masterSeq->Length()) masterSeqInt->to = masterSeq->Length() - 1;
  368.     SeqLocPtr slaveSeqLoc = (SeqLocPtr) MemNew(sizeof(SeqLoc));
  369.     slaveSeqLoc->choice = SEQLOC_INT;
  370.     SeqIntPtr slaveSeqInt = SeqIntNew();
  371.     slaveSeqLoc->data.ptrvalue = slaveSeqInt;
  372.     // create BLAST_Matrix if using PSSM from multiple
  373.     const BLAST_Matrix *BLASTmatrix = multiple->GetPSSM();
  374.     string err;
  375.     int row;
  376.     for (row=0; row<multiple->NRows(); ++row) {
  377.         // get C Bioseq for each slave
  378.         const Sequence *slaveSeq = multiple->GetSequenceOfRow(row);
  379.         Bioseq *slaveBioseq = slaveSeq->parentSet->GetOrCreateBioseq(slaveSeq);
  380.         // setup Seq-loc interval for slave
  381.         slaveSeqInt->id = slaveBioseq->id;
  382.         slaveSeqInt->from = uaBlocks.front()->GetRangeOfRow(row)->from - excess;
  383.         if (slaveSeqInt->from < 0) slaveSeqInt->from = 0;
  384.         slaveSeqInt->to = uaBlocks.back()->GetRangeOfRow(row)->to + excess;
  385.         if (slaveSeqInt->to >= slaveSeq->Length()) slaveSeqInt->to = slaveSeq->Length() - 1;
  386. //        TESTMSG("for BLAST: master range " <<
  387. //                (masterSeqInt->from + 1) << " to " << (masterSeqInt->to + 1) << ", slave range " <<
  388. //                (slaveSeqInt->from + 1) << " to " << (slaveSeqInt->to + 1));
  389.         // set search space size
  390.         SetEffectiveSearchSpaceSize(options, slaveSeqInt->to - slaveSeqInt->from + 1);
  391.         // actually do the BLAST alignment
  392. //        TRACEMSG("calling BlastTwoSequencesByLocWithCallback()");
  393.         SeqAlign *salp = BlastTwoSequencesByLocWithCallback(
  394.             masterSeqLoc, slaveSeqLoc,
  395.             "blastp", options,
  396.             NULL, NULL, NULL,
  397.             const_cast<BLAST_Matrix*>(BLASTmatrix));
  398. //        TRACEMSG("calling B2SPssmMultipleQueries()");
  399. //        SeqLocPtr target[1];
  400. //        target[0] = slaveSeqLoc;
  401. //        options->searchsp_eff = 0;
  402. //        SeqAlignPtr *psalp = B2SPssmMultipleQueries(masterSeqLoc,
  403. //            const_cast<BLAST_Matrix*>(BLASTmatrix), target, 1, options);
  404. //        SeqAlign *salp = psalp[0];
  405.         // process the result
  406.         double score = -1.0;
  407.         if (salp) {
  408.             // convert C SeqAlign to C++ for convenience
  409.             CSeq_align sa;
  410.             bool okay = ConvertAsnFromCToCPP(salp, (AsnWriteFunc) SeqAlignAsnWrite, &sa, &err);
  411.             SeqAlignSetFree(salp);
  412.             if (!okay) {
  413.                 ERRORMSG("Conversion of SeqAlign to C++ object failed");
  414.                 continue;
  415.             }
  416.             // get score
  417.             if (sa.IsSetScore()) {
  418.                 CSeq_align::TScore::const_iterator sc, sce = sa.GetScore().end();
  419.                 for (sc=sa.GetScore().begin(); sc!=sce; ++sc) {
  420.                     if ((*sc)->GetValue().IsReal() && (*sc)->IsSetId() &&
  421.                         (*sc)->GetId().IsStr() && (*sc)->GetId().GetStr() == "e_value") {
  422.                         score = (*sc)->GetValue().GetReal();
  423.                         break;
  424.                     }
  425.                 }
  426.             }
  427.             if (score < 0.0) ERRORMSG("Got back Seq-align with no E-value");
  428.         }
  429.         // set score in row
  430.         multiple->SetRowDouble(row, score);
  431.         wxString status;
  432.         if (score >= 0.0)
  433.             status.Printf("Self hit E-value: %g", score);
  434.         else
  435.             status = "No detectable self hit";
  436.         multiple->SetRowStatusLine(row, status.c_str());
  437.     }
  438.     // print out overall self-hit rate
  439.     int nSelfHits = 0;
  440.     static const double threshold = 0.01;
  441.     for (row=0; row<multiple->NRows(); ++row) {
  442.         if (multiple->GetRowDouble(row) >= 0.0 && multiple->GetRowDouble(row) <= threshold)
  443.             ++nSelfHits;
  444.     }
  445.     INFOMSG("Self hits with E-value <= " << setprecision(3) << threshold << ": "
  446.         << (100.0*nSelfHits/multiple->NRows()) << "% ("
  447.         << nSelfHits << '/' << multiple->NRows() << ')' << setprecision(6));
  448.     BLASTOptionDelete(options);
  449.     masterSeqInt->id = NULL;    // don't free Seq-id, since it belongs to the Bioseq
  450.     SeqIntFree(masterSeqInt);
  451.     MemFree(masterSeqLoc);
  452.     slaveSeqInt->id = NULL;
  453.     SeqIntFree(slaveSeqInt);
  454.     MemFree(slaveSeqLoc);
  455. }
  456. END_SCOPE(Cn3D)
  457. /*
  458. * ---------------------------------------------------------------------------
  459. * $Log: cn3d_blast.cpp,v $
  460. * Revision 1000.2  2004/06/01 18:28:09  gouriano
  461. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.34
  462. *
  463. * Revision 1.34  2004/05/21 21:41:39  gorelenk
  464. * Added PCH ncbi_pch.hpp
  465. *
  466. * Revision 1.33  2004/03/15 18:19:23  thiessen
  467. * prefer prefix vs. postfix ++/-- operators
  468. *
  469. * Revision 1.32  2004/02/19 17:04:49  thiessen
  470. * remove cn3d/ from include paths; add pragma to disable annoying msvc warning
  471. *
  472. * Revision 1.31  2003/07/14 18:37:07  thiessen
  473. * change GetUngappedAlignedBlocks() param types; other syntax changes
  474. *
  475. * Revision 1.30  2003/05/29 16:38:27  thiessen
  476. * set db length for CDD 1.62
  477. *
  478. * Revision 1.29  2003/02/03 19:20:02  thiessen
  479. * format changes: move CVS Log to bottom of file, remove std:: from .cpp files, and use new diagnostic macros
  480. *
  481. * Revision 1.28  2003/01/31 17:18:58  thiessen
  482. * many small additions and changes...
  483. *
  484. * Revision 1.27  2003/01/23 20:03:05  thiessen
  485. * add BLAST Neighbor algorithm
  486. *
  487. * Revision 1.26  2003/01/22 14:47:30  thiessen
  488. * cache PSSM in BlockMultipleAlignment
  489. *
  490. * Revision 1.25  2002/12/20 02:51:46  thiessen
  491. * fix Prinf to self problems
  492. *
  493. * Revision 1.24  2002/10/25 19:00:02  thiessen
  494. * retrieve VAST alignment from vastalign.cgi on structure import
  495. *
  496. * Revision 1.23  2002/09/19 14:21:03  thiessen
  497. * add search space size calculation to match scores with rpsblast (finally!)
  498. *
  499. * Revision 1.22  2002/09/05 17:39:53  thiessen
  500. * add bit score printout for BLAST/PSSM
  501. *
  502. * Revision 1.21  2002/09/05 13:04:33  thiessen
  503. * restore output stream precision
  504. *
  505. * Revision 1.20  2002/09/04 15:51:52  thiessen
  506. * turn off options->tweak_parameters
  507. *
  508. * Revision 1.19  2002/08/30 16:52:10  thiessen
  509. * progress on trying to match scores with RPS-BLAST
  510. *
  511. * Revision 1.18  2002/08/15 22:13:13  thiessen
  512. * update for wx2.3.2+ only; add structure pick dialog; fix MultitextDialog bug
  513. *
  514. * Revision 1.17  2002/08/01 12:51:36  thiessen
  515. * add E-value display to block aligner
  516. *
  517. * Revision 1.16  2002/07/26 15:28:45  thiessen
  518. * add Alejandro's block alignment algorithm
  519. *
  520. * Revision 1.15  2002/07/23 15:46:49  thiessen
  521. * print out more BLAST info; tweak save file name
  522. *
  523. * Revision 1.14  2002/07/12 13:24:10  thiessen
  524. * fixes for PSSM creation to agree with cddumper/RPSBLAST
  525. *
  526. * Revision 1.13  2002/06/17 19:31:54  thiessen
  527. * set db_length in blast options
  528. *
  529. * Revision 1.12  2002/06/13 14:54:07  thiessen
  530. * add sort by self-hit
  531. *
  532. * Revision 1.11  2002/06/13 13:32:39  thiessen
  533. * add self-hit calculation
  534. *
  535. * Revision 1.10  2002/05/22 17:17:08  thiessen
  536. * progress on BLAST interface ; change custom spin ctrl implementation
  537. *
  538. * Revision 1.9  2002/05/17 19:10:27  thiessen
  539. * preliminary range restriction for BLAST/PSSM
  540. *
  541. * Revision 1.8  2002/05/07 20:22:47  thiessen
  542. * fix for BLAST/PSSM
  543. *
  544. * Revision 1.7  2002/05/02 18:40:25  thiessen
  545. * do BLAST/PSSM for debug builds only, for testing
  546. *
  547. * Revision 1.6  2002/03/28 14:06:02  thiessen
  548. * preliminary BLAST/PSSM ; new CD startup style
  549. *
  550. * Revision 1.5  2001/11/27 16:26:07  thiessen
  551. * major update to data management system
  552. *
  553. * Revision 1.4  2001/10/18 19:57:32  thiessen
  554. * fix redundant creation of C bioseqs
  555. *
  556. * Revision 1.3  2001/09/27 15:37:58  thiessen
  557. * decouple sequence import and BLAST
  558. *
  559. * Revision 1.2  2001/09/19 22:55:39  thiessen
  560. * add preliminary net import and BLAST
  561. *
  562. * Revision 1.1  2001/09/18 03:10:45  thiessen
  563. * add preliminary sequence import pipeline
  564. *
  565. */