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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: dust_app.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 18:06:43  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.4
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: dust_app.cpp,v 1000.2 2004/06/01 18:06:43 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:  Richa Agarwala
  35.  *
  36.  * File Description:
  37.  *   Program to read nucleotide FASTA and produce DUST'd version.
  38.  */
  39. #include <ncbi_pch.hpp>
  40. #include <corelib/ncbiapp.hpp>
  41. #include <corelib/ncbistr.hpp>
  42. #include <serial/serial.hpp>
  43. #include <serial/objistr.hpp>
  44. #include <serial/objostr.hpp>
  45. #include <serial/iterator.hpp>
  46. // Objects includes
  47. #include <corelib/ncbidbg.hpp>
  48. #include <objects/seq/Bioseq.hpp>
  49. #include <objects/seq/IUPACna.hpp>
  50. #include <objects/seq/Seq_data.hpp>
  51. #include <objects/seq/Seq_descr.hpp>
  52. #include <objects/seq/Seq_inst.hpp>
  53. #include <objects/seq/Seqdesc.hpp>
  54. #include <objects/seq/seqport_util.hpp>
  55. #include <objects/seqloc/Seq_id.hpp>
  56. #include <objects/seqloc/Seq_interval.hpp>
  57. #include <objects/seqloc/Seq_loc.hpp>
  58. #include <objects/seqset/Seq_entry.hpp>
  59. #include <algo/blast/core/blast_dust.h>
  60. #include <algo/blast/core/blast_filter.h>
  61. #include <objtools/readers/fasta.hpp> 
  62. #define FASTA_LEN 60
  63. USING_NCBI_SCOPE;
  64. using namespace objects;
  65. /////////////////////////////////////////////////////////////////////////////
  66. //  CDustApplication::
  67. class CDustApplication : public CNcbiApplication
  68. {
  69. public:
  70.     static const char * const USAGE_LINE;
  71. private:
  72.     virtual void Init(void);
  73.     virtual int  Run(void);
  74.     virtual void Exit(void);
  75. };
  76. /////////////////////////////////////////////////////////////////////////////
  77. //  Usage description
  78. const char * const
  79. CDustApplication::USAGE_LINE = "Dust nucleotide sequence";
  80. /////////////////////////////////////////////////////////////////////////////
  81. //  Get arguments
  82. void CDustApplication::Init(void)
  83. {
  84.     // Create command-line argument descriptions class
  85.     auto_ptr<CArgDescriptions> arg_desc(new CArgDescriptions);
  86.     // Specify USAGE context
  87.     arg_desc->SetUsageContext(GetArguments().GetProgramBasename(),
  88.                               USAGE_LINE);
  89.     // Describe the expected command-line arguments
  90.     arg_desc->AddKey("input", "Inputfile",
  91.                         "The input file", CArgDescriptions::eInputFile);
  92.     arg_desc->AddKey("output", "Outputfile",
  93.                         "The output file", CArgDescriptions::eOutputFile);
  94.     arg_desc->AddDefaultKey( "window", "window_size", "window size",
  95.                              CArgDescriptions::eInteger, "64" );
  96.     arg_desc->AddDefaultKey( "level", "level", "minimum level",
  97.                              CArgDescriptions::eInteger, "20" );
  98.     arg_desc->AddDefaultKey( "minwin", "minwin", "minimum window size reported",
  99.                              CArgDescriptions::eInteger, "4" );
  100.     arg_desc->AddDefaultKey( "linker", "linker", "link windows apart by <linker> bp",
  101.                              CArgDescriptions::eInteger, "1" );
  102.     arg_desc->AddDefaultKey("segments", "segments", "Print segments instead of FASTA", CArgDescriptions::eBoolean, "F");
  103.     // Setup arg.descriptions for this application
  104.     SetupArgDescriptions(arg_desc.release());
  105. }
  106. static string GetFastaDefline(const CBioseq & bioseq)
  107. {
  108.     string seq_id_description = 
  109.            CSeq_id::GetStringDescr(bioseq, CSeq_id::eFormat_FastA);
  110.     if ((seq_id_description.size() < 5) ||
  111.         (NStr::CompareCase(seq_id_description, 0, 4, "lcl|") != 0))
  112.     {
  113.         NcbiCerr << "Input Bioseq was not generated as a local entry" << endl;
  114.         exit(0);
  115.     }
  116.     // Take "lcl|" out of id and prefix it with ">"
  117.     string defline = ">"+ seq_id_description.substr(4,seq_id_description.size()-4);
  118.     // Add title if present
  119.     if (bioseq.CanGetDescr())
  120.     {
  121.         const CSeq_descr & title_seq = bioseq.GetDescr();
  122.         if (title_seq.CanGet())
  123.         {
  124.             const CSeq_descr_Base::Tdata & title = title_seq.Get();
  125.             if (!title.empty())
  126.             {
  127.                 CSeq_descr_Base::Tdata::const_iterator it = title.begin();
  128.                 CRef<CSeqdesc> ref_desc = *it;
  129.                 if (it != title.end())
  130.                 {
  131.                     defline.append(1, ' '); // space between id and title
  132.                     ref_desc->GetLabel(&defline, CSeqdesc::eContent);
  133.                 }
  134.             }
  135.         }
  136.     }
  137.     return defline;
  138. }
  139. int CDustApplication::Run(void)
  140. {
  141.     CRef<CSeq_entry> seq_entry;
  142.     TSeqPos i, start, end;
  143.     Uint1 *sequence;                // Sequnce in BLASTNA format
  144.     BlastSeqLoc* dust_loc = NULL;   // Regions that get DUST'd
  145.     BlastSeqLoc* temp_loc = NULL;   
  146.     // Get arguments
  147.     CArgs args = GetArgs();
  148.     Int2 window = args["window"].AsInteger();
  149.     Int2 level = args["level"].AsInteger();
  150.     Int2 minwin = args["minwin"].AsInteger();
  151.     Int2 linker = args["linker"].AsInteger();
  152.     Boolean PrintSegments = args["segments"].AsBoolean();
  153.     // Set flags for reading data
  154.     TReadFastaFlags flags = 0;
  155.     flags = fReadFasta_ForceType;
  156.     flags |= fReadFasta_AssumeNuc;
  157.     flags |= fReadFasta_OneSeq;
  158.     flags |= fReadFasta_NoParseID;
  159.     // Open files
  160.     CNcbiIfstream input_stream(args["input"].AsString().c_str(), IOS_BASE::in);
  161.     CNcbiOfstream output_stream(args["output"].AsString().c_str(), IOS_BASE::out);
  162.     // Read data
  163.     int counter = 0;
  164.     while (!input_stream.eof())
  165.     {
  166.         // Get one sequence from Fasta file
  167.         vector<CConstRef<CSeq_loc> > lcase_mask;
  168.         seq_entry = ReadFasta(input_stream, flags, &counter, &lcase_mask);
  169.         if (seq_entry->IsSeq() && seq_entry->GetSeq().IsNa())
  170.         {
  171.             const CBioseq & bioseq = seq_entry->GetSeq();
  172.             if (bioseq.CanGetInst() &&
  173.                 bioseq.GetInst().CanGetLength() &&
  174.                 bioseq.GetInst().CanGetSeq_data() )
  175.             {
  176.                 // Get sequence id
  177.                 string seq_id_description = 
  178.                        CSeq_id::GetStringDescr(bioseq, CSeq_id::eFormat_FastA);
  179.                 // Get defline
  180.                 string defline = GetFastaDefline(bioseq);
  181.     
  182.                 // Get sequence length
  183.                 TSeqPos seq_length = bioseq.GetInst().GetLength();
  184.     
  185.                 // Get nucleotide data for sequence
  186.                 const CSeq_data & seqdata = bioseq.GetInst().GetSeq_data();
  187.                 // Convert to Iupacna so don't have to worry about packing
  188.                 auto_ptr< CSeq_data > dest( new CSeq_data );
  189.                 CSeqportUtil::Convert(seqdata, dest.get(), CSeq_data::e_Iupacna,
  190.                                       0, seq_length);
  191.                 const string & data = dest->GetIupacna().Get();
  192.                 // Convert nucleotides to BLASTNA format
  193.                 sequence = (Uint1*) malloc(sizeof(Uint1)*seq_length);
  194.                 if (sequence == NULL)
  195.                 {
  196.                     NcbiCerr << "No space for storing sequence" << endl;
  197.                     exit(0);
  198.                 }
  199.                 for (i = 0; i < seq_length; i++)
  200.                     switch (data[i]) {
  201.                         case 'a': case 'A': sequence[i] = 0; break;
  202.                         case 'c': case 'C': sequence[i] = 1; break;
  203.                         case 'g': case 'G': sequence[i] = 2; break;
  204.                         case 't': case 'T': sequence[i] = 3; break;
  205.                         case 'r': case 'R': sequence[i] = 4; break;
  206.                         case 'y': case 'Y': sequence[i] = 5; break;
  207.                         case 'm': case 'M': sequence[i] = 6; break;
  208.                         case 'k': case 'K': sequence[i] = 7; break;
  209.                         case 'w': case 'W': sequence[i] = 8; break;
  210.                         case 's': case 'S': sequence[i] = 9; break;
  211.                         case 'b': case 'B': sequence[i] = 10; break;
  212.                         case 'd': case 'D': sequence[i] = 11; break;
  213.                         case 'h': case 'H': sequence[i] = 12; break;
  214.                         case 'v': case 'V': sequence[i] = 13; break;
  215.                         case 'n': case 'N': sequence[i] = 14; break;
  216.                         default: sequence[i] = 14;
  217.                                  NcbiCerr << "Warning: Position " << i+1 ;
  218.                                  NcbiCerr << " of sequence " << seq_id_description;
  219.                                  NcbiCerr << " is and invalid residue; treating it as N" << endl;
  220.                     }
  221.                 // Do dusting
  222.                 dust_loc = NULL;
  223.                 SeqBufferDust(sequence, seq_length, 0, level, window,
  224.                                minwin, linker, &dust_loc);
  225.                 if (PrintSegments)
  226.                 {
  227.                     for (temp_loc = dust_loc; temp_loc; temp_loc = temp_loc->next)
  228.                     {
  229.                         start = (TSeqPos) ((SSeqRange *) temp_loc->ptr)->left;
  230.                         end = (TSeqPos) ((SSeqRange *) temp_loc->ptr)->right;
  231.                         output_stream << seq_id_description << "t";
  232.                         output_stream << start+1 << "t" << end+1 << endl;
  233.                     }
  234.                 }
  235.                 else
  236.                 {
  237.                     output_stream << defline << endl;
  238.                     // Get copy of (const) data and mask DUST locations found
  239.                     string copy_data = data;
  240.                     for (temp_loc = dust_loc; temp_loc; temp_loc = temp_loc->next)
  241.                     {
  242.                         start = (TSeqPos) ((SSeqRange *) temp_loc->ptr)->left;
  243.                         end = (TSeqPos) ((SSeqRange *) temp_loc->ptr)->right;
  244.                         for (; start <= end; start++)
  245.                             copy_data[start] = tolower(copy_data[start]);
  246.                     }
  247.                     // Get lowercase positions
  248.                     if (lcase_mask[0].NotEmpty())
  249.                     {
  250.                         CConstRef<CSeq_loc> lowercase = lcase_mask[0];
  251.                         if (lowercase->IsPacked_int())
  252.                             ITERATE(list< CRef<CSeq_interval> >, itr, 
  253.                                     lowercase->GetPacked_int().Get())
  254.                             {
  255.                                 start = (TSeqPos) (*itr)->GetFrom();
  256.                                 end = (TSeqPos) (*itr)->GetTo();
  257.                                 for (; start < end; start++)
  258.                                     copy_data[start] = tolower(copy_data[start]);
  259.                             }
  260.                     }
  261.                     // Print result
  262.                     start = 0;
  263.                     TSeqPos copy_size = copy_data.size();
  264.                     while (start < copy_size)
  265.                     {
  266.                         end = ((start+FASTA_LEN) >= copy_size) ? copy_size : start+FASTA_LEN;
  267.                         output_stream << copy_data.substr(start, end-start) << endl;
  268.                         start = end;
  269.                     }
  270.                 }
  271.     
  272.                 free(sequence);
  273.                 BlastSeqLocFree(dust_loc);
  274.             }
  275.         }
  276.     }
  277.     return 0;
  278. }
  279. /////////////////////////////////////////////////////////////////////////////
  280. //  Cleanup
  281. void CDustApplication::Exit(void)
  282. {
  283.     SetDiagStream(0);
  284. }
  285. /////////////////////////////////////////////////////////////////////////////
  286. //  MAIN
  287. int main(int argc, const char* argv[])
  288. {
  289.     // Execute main application function
  290.     return CDustApplication().AppMain(argc, argv, 0, eDS_Default, 0);
  291. }