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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: splign_app.cpp,v $
  4.  * PRODUCTION Revision 1000.6  2004/06/01 18:05:26  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.24
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /* $Id: splign_app.cpp,v 1000.6 2004/06/01 18:05:26 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.  * Author:  Yuri Kapustin
  35.  *
  36.  * File Description: Splign application
  37.  *                   
  38. */
  39. #include <ncbi_pch.hpp>
  40. #include "splign_app.hpp"
  41. #include "splign_app_exception.hpp"
  42. #include <corelib/ncbistd.hpp>
  43. #include <serial/objostrasn.hpp>
  44. #include <serial/serial.hpp>
  45. #include <algo/align/nw_spliced_aligner16.hpp>
  46. #include <algo/align/nw_spliced_aligner32.hpp>
  47. #include <algo/align/splign/splign.hpp>
  48. #include <algo/align/splign/splign_simple.hpp>
  49. #include <algo/align/splign/splign_formatter.hpp>
  50. #include <objmgr/object_manager.hpp>
  51. #include <objmgr/scope.hpp>
  52. #include <objects/seq/Bioseq.hpp>
  53. #include <objects/seqalign/Seq_align.hpp>
  54. #include <objects/seqloc/Seq_loc.hpp>
  55. #include <algo/blast/api/bl2seq.hpp>
  56. #include <iostream>
  57. #include <memory>
  58. BEGIN_NCBI_SCOPE
  59. USING_SCOPE(objects);
  60. const char kQuality_high[] = "high";
  61. const char kQuality_low[] = "low";
  62. void CSplignApp::Init()
  63. {
  64.   HideStdArgs( fHideLogfile | fHideConffile | fHideVersion);
  65.   
  66.   auto_ptr<CArgDescriptions> argdescr(new CArgDescriptions);
  67.   string program_name ("Splign v.1.06");
  68. #ifdef GENOME_PIPELINE
  69.   program_name += 'p';
  70. #endif
  71.   argdescr->SetUsageContext(GetArguments().GetProgramName(), program_name);
  72.   argdescr->AddOptionalKey
  73.     ("index", "index",
  74.      "Batch mode index file (use -mkidx to generate).",
  75.      CArgDescriptions::eString);
  76.   argdescr->AddFlag ("mkidx", "Generate batch mode index and quit.", true);
  77.   
  78.   argdescr->AddOptionalKey
  79.     ("hits", "hits",
  80.      "Batch mode hit file. "
  81.      "This file defines the set of sequences to align and "
  82.      "is also used to guide alignments.",
  83.      CArgDescriptions::eString);
  84.   argdescr->AddOptionalKey
  85.     ("query", "query",
  86.      "FastA file with the spliced sequence. Use in pairwise mode only.",
  87.      CArgDescriptions::eString);
  88.   argdescr->AddOptionalKey
  89.     ("subj", "subj",
  90.      "FastA file with the genomic sequence. Use in pairwise mode only.",
  91.      CArgDescriptions::eString);
  92.   argdescr->AddDefaultKey
  93.     ("log", "log", "Splign log file",
  94.      CArgDescriptions::eString, "splign.log");
  95.   argdescr->AddOptionalKey
  96.     ("asn", "asn", "ASN.1 output file name", CArgDescriptions::eString);
  97.   argdescr->AddDefaultKey
  98.     ("strand", "strand", "Spliced sequence's strand.",
  99.      CArgDescriptions::eString, "plus");
  100.   argdescr->AddFlag ("noendgaps",
  101.      "Skip detection of unaligning regions at the ends.",
  102.                       true);
  103.   argdescr->AddFlag ("nopolya", "Assume no Poly(A) tail.",  true);
  104.   argdescr->AddDefaultKey
  105.     ("compartment_penalty", "compartment_penalty",
  106.      "Penalty to open a new compartment.",
  107.      CArgDescriptions::eDouble,
  108.      "0.75");
  109.  
  110.  argdescr->AddDefaultKey
  111.     ("min_query_cov", "min_query_cov",
  112.      "Min query coverage by initial Blast hits. "
  113.      "Queries with less coverage will not be aligned.",
  114.      CArgDescriptions::eDouble, "0.25");
  115.   argdescr->AddDefaultKey
  116.     ("min_idty", "identity",
  117.      "Minimal exon identity. Lower identity segments "
  118.      "will be marked as gaps.",
  119.      CArgDescriptions::eDouble, "0.75");
  120. #ifdef GENOME_PIPELINE
  121.   argdescr->AddDefaultKey
  122.     ("quality", "quality", "Genomic sequence quality.",
  123.      CArgDescriptions::eString, kQuality_high);
  124.   
  125.   argdescr->AddDefaultKey
  126.     ("Wm", "match", "match score",
  127.      CArgDescriptions::eInteger,
  128.      NStr::IntToString(CNWAligner::GetDefaultWm()).c_str());
  129.   
  130.   argdescr->AddDefaultKey
  131.     ("Wms", "mismatch", "mismatch score",
  132.      CArgDescriptions::eInteger,
  133.      NStr::IntToString(CNWAligner::GetDefaultWms()).c_str());
  134.   
  135.   argdescr->AddDefaultKey
  136.     ("Wg", "gap", "gap opening score",
  137.      CArgDescriptions::eInteger,
  138.      NStr::IntToString(CNWAligner::GetDefaultWg()).c_str());
  139.   
  140.   argdescr->AddDefaultKey
  141.     ("Ws", "space", "gap extension (space) score",
  142.      CArgDescriptions::eInteger,
  143.      NStr::IntToString(CNWAligner::GetDefaultWs()).c_str());
  144.   
  145.   argdescr->AddDefaultKey
  146.     ("Wi0", "Wi0", "Conventional intron (GT/AG) score",
  147.      CArgDescriptions::eInteger,
  148.      NStr::IntToString(CSplicedAligner16::GetDefaultWi(0)).c_str());
  149.   
  150.   argdescr->AddDefaultKey
  151.     ("Wi1", "Wi1", "Conventional intron (GC/AG) score",
  152.      CArgDescriptions::eInteger,
  153.      NStr::IntToString(CSplicedAligner16::GetDefaultWi(1)).c_str());
  154.   
  155.   argdescr->AddDefaultKey
  156.     ("Wi2", "Wi2", "Conventional intron (AT/AC) score",
  157.      CArgDescriptions::eInteger,
  158.      NStr::IntToString(CSplicedAligner16::GetDefaultWi(2)).c_str());
  159.   
  160.   argdescr->AddDefaultKey
  161.     ("Wi3", "Wi3", "Arbitrary intron score",
  162.      CArgDescriptions::eInteger,
  163.      NStr::IntToString(CSplicedAligner16::GetDefaultWi(3)).c_str());
  164.   
  165.   // restrictions
  166.   CArgAllow_Strings* constrain_errlevel = new CArgAllow_Strings;
  167.   constrain_errlevel->Allow(kQuality_low)->Allow(kQuality_high);
  168.   argdescr->SetConstraint("quality", constrain_errlevel);
  169.   
  170. #endif
  171.     
  172.   CArgAllow_Strings* constrain_strand = new CArgAllow_Strings;
  173.   constrain_strand->Allow("plus")->Allow("minus");
  174.   argdescr->SetConstraint("strand", constrain_strand);
  175.   CArgAllow* constrain01 = new CArgAllow_Doubles(0,1);
  176.   argdescr->SetConstraint("min_idty", constrain01);
  177.   argdescr->SetConstraint("compartment_penalty", constrain01);
  178.   argdescr->SetConstraint("min_query_cov", constrain01);
  179.     
  180.   SetupArgDescriptions(argdescr.release());
  181. }
  182. bool CSplignApp::x_GetNextPair(istream* ifs, vector<CHit>* hits)
  183. {
  184.   hits->clear();
  185.   if(!m_pending.size() && (!ifs || !*ifs) ) {
  186.     return false;
  187.   }
  188.   if(!m_pending.size()) {
  189.     string query, subj;
  190.     if(m_firstline.size()) {
  191.       CHit hit (m_firstline.c_str());
  192.       query = hit.m_Query;
  193.       subj  = hit.m_Subj;
  194.       m_pending.push_back(hit);
  195.     }
  196.     char buf [1024];
  197.     while(ifs) {
  198.       buf[0] = 0;
  199.       CT_POS_TYPE pos0 = ifs->tellg();
  200.       ifs->getline(buf, sizeof buf, 'n');
  201.       CT_POS_TYPE pos1 = ifs->tellg();
  202.       if(pos1 == pos0) break; // GCC hack
  203.       if(buf[0] == '#') continue; // skip comments
  204.       const char* p = buf; // skip leading spaces
  205.       while(*p == ' ' || *p == 't') ++p;
  206.       if(*p == 0) continue; // skip empty lines
  207.       CHit hit (p);
  208.       if(query.size() == 0) {
  209. query = hit.m_Query;
  210.       }
  211.       if(subj.size() == 0) {
  212. subj = hit.m_Subj;
  213.       }
  214.       if(hit.m_ai[0] > hit.m_ai[1]) {
  215.         NCBI_THROW(CSplignAppException,
  216.                    eBadData,
  217.                    "Hit with reversed query coordinates detected." );
  218.       }
  219.       if(hit.m_ai[2] == hit.m_ai[3]) { // skip single bases
  220.         continue;
  221.       }
  222.       if(hit.m_Query != query || hit.m_Subj != subj) {
  223. m_firstline = p;
  224. break;
  225.       }
  226.       m_pending.push_back(hit);
  227.     }
  228.   }
  229.   const size_t pending_size = m_pending.size();
  230.   if(pending_size) {
  231.     const string& query = m_pending[0].m_Query;
  232.     const string& subj  = m_pending[0].m_Subj;
  233.     size_t i = 1;
  234.     for(; i < pending_size; ++i) {
  235.       const CHit& h = m_pending[i];
  236.       if(h.m_Query != query || h.m_Subj != subj) {
  237.         break;
  238.       }
  239.     }
  240.     hits->resize(i);
  241.     copy(m_pending.begin(), m_pending.begin() + i, hits->begin());
  242.     m_pending.erase(m_pending.begin(), m_pending.begin() + i);
  243.   }
  244.   return hits->size() > 0;
  245. }
  246. void CSplignApp::x_LogStatus(size_t model_id, const string& query,
  247.                              const string& subj,
  248.      bool error, const string& msg)
  249. {
  250.   string error_tag (error? "Error: ": "");
  251.   if(model_id == 0) {
  252.     m_logstream << '-';
  253.   }
  254.   else {
  255.     m_logstream << model_id;
  256.   }
  257.   m_logstream << 't' << query << 't' << subj 
  258.               << 't' << error_tag << msg << endl;
  259. }
  260. istream* CSplignApp::x_GetPairwiseHitStream(
  261.                          CSeqLoaderPairwise& seq_loader) const
  262. {
  263.     vector<char> query, subj;
  264.     seq_loader.Load(seq_loader.GetQueryStringId(), &query, 0, kMax_UInt);
  265.     seq_loader.Load(seq_loader.GetSubjStringId(), &subj, 0, kMax_UInt);
  266.     
  267.     CRef<CObjectManager> objmgr(new CObjectManager);
  268.     CRef<CSeq_loc> seqloc_query;
  269.     CRef<CScope> scope_query;
  270.     {{
  271.     scope_query.Reset(new CScope(*objmgr));
  272.     scope_query->AddDefaults();
  273.     CRef<CSeq_entry> se (seq_loader.GetQuerySeqEntry());
  274.     scope_query->AddTopLevelSeqEntry(*se);
  275.     seqloc_query.Reset(new CSeq_loc);
  276.     seqloc_query->SetWhole().Assign(*(se->GetSeq().GetId().front()));
  277.     }}
  278.     CRef<CSeq_loc> seqloc_subj;
  279.     CRef<CScope> scope_subj;
  280.     {{
  281.     scope_subj.Reset(new CScope(*objmgr));
  282.     scope_subj->AddDefaults();
  283.     CRef<CSeq_entry> se (seq_loader.GetSubjSeqEntry());
  284.     scope_subj->AddTopLevelSeqEntry(*se);
  285.     seqloc_subj.Reset(new CSeq_loc);
  286.     seqloc_subj->SetWhole().Assign(*(se->GetSeq().GetId().front()));
  287.     }}
  288.     blast::CBl2Seq Blast(blast::SSeqLoc(seqloc_query.GetNonNullPointer(),
  289.                                         scope_query.GetNonNullPointer()),
  290.                          blast::SSeqLoc(seqloc_subj.GetNonNullPointer(),
  291.                                         scope_subj.GetNonNullPointer()),
  292.                          blast::eMegablast);
  293.     blast::TSeqAlignVector blast_output (Blast.Run());
  294.     if (!blast_output.empty() && blast_output.front().NotEmpty() &&
  295.         !blast_output.front()->Get().empty() &&
  296.         !blast_output.front()->Get().front()->
  297.           GetSegs().GetDisc().Get().empty()) {
  298.         
  299.         CNcbiOstrstream oss;
  300.         const CSeq_align_set::Tdata &sas =
  301.             blast_output.front()->Get().front()->GetSegs().GetDisc().Get();
  302.         ITERATE(CSeq_align_set::Tdata, sa_iter, sas) {
  303.             CHit hit (**sa_iter);
  304.             oss << hit << endl;
  305.         }
  306.         string str = CNcbiOstrstreamToString(oss);
  307.         CNcbiIstrstream* iss = new CNcbiIstrstream (str.c_str());
  308.         return iss;        
  309.     }
  310.     else {
  311.         return 0;
  312.     }
  313. }
  314. int CSplignApp::Run()
  315.   const CArgs& args = GetArgs();    
  316.   // check that modes aren't mixed
  317.   bool is_query = args["query"];
  318.   bool is_subj = args["subj"];
  319.   bool is_index = args["index"];
  320.   bool is_hits = args["hits"];
  321.   if(is_query ^ is_subj) {
  322.       NCBI_THROW(CSplignAppException,
  323.                  eBadParameter,
  324.                  "Both query and subj must be specified in pairwise mode." );
  325.   }
  326.   
  327.   if(is_query && (is_hits || is_index)) {
  328.       NCBI_THROW(CSplignAppException,
  329.                  eBadParameter,
  330.                  "Do not use -hits or -index in pairwise mode "
  331.                  "(i.e. with -query and -subj)." );
  332.   }
  333.   if(!is_query && !is_hits) {
  334.       NCBI_THROW(CSplignAppException,
  335.                  eBadParameter,
  336.                  "Either -query or -hits must be specified (but not both)");
  337.   }
  338.   if(is_hits ^ is_index) {
  339.       NCBI_THROW(CSplignAppException,
  340.                  eBadParameter,
  341.                  "When in batch mode, specify both -hits and -index");
  342.   }
  343.   
  344.   bool mode_pairwise = is_query;
  345.   // open log stream
  346.   m_logstream.open( args["log"].AsString().c_str() );
  347.   // open asn output stream, if any
  348.   auto_ptr<ofstream> asn_ofs (0);
  349.   if(args["asn"]) {
  350.       const string filename = args["asn"].AsString();
  351.       asn_ofs.reset(new ofstream (filename.c_str()));
  352.       if(!*asn_ofs) {
  353.           NCBI_THROW(CSplignAppException,
  354.                      eCannotOpenFile,
  355.                      "Cannot open output asn file." );
  356.       }
  357.   }
  358.   // aligner setup
  359.   string quality;
  360. #ifndef GENOME_PIPELINE
  361.   quality = kQuality_high;
  362. #else
  363.   quality = args["quality"].AsString();
  364. #endif
  365.   CRef<CSplicedAligner> aligner (  quality == kQuality_high ?
  366.     static_cast<CSplicedAligner*> (new CSplicedAligner16):
  367.     static_cast<CSplicedAligner*> (new CSplicedAligner32) );
  368. #if GENOME_PIPELINE
  369.   aligner->SetWm(args["Wm"].AsInteger());
  370.   aligner->SetWms(args["Wms"].AsInteger());
  371.   aligner->SetWg(args["Wg"].AsInteger());
  372.   aligner->SetWs(args["Ws"].AsInteger());
  373.   for(size_t i = 0, n = aligner->GetSpliceTypeCount(); i < n; ++i) {
  374.       string arg_name ("Wi");
  375.       arg_name += NStr::IntToString(i);
  376.       aligner->SetWi(i, args[arg_name.c_str()].AsInteger());
  377.   }
  378. #endif
  379.   // setup sequence loader
  380.   CRef<CSplignSeqAccessor> seq_loader;
  381.   if(mode_pairwise) {
  382.       const string query_filename (args["query"].AsString());
  383.       const string subj_filename  (args["subj"].AsString());
  384.       CSeqLoaderPairwise* pseqloader = 
  385.           new CSeqLoaderPairwise(query_filename, subj_filename);
  386.       seq_loader.Reset(pseqloader);
  387.   }
  388.   else {
  389.       CSeqLoader* pseqloader = new CSeqLoader;
  390.       pseqloader->Open(args["index"].AsString());
  391.       seq_loader.Reset(pseqloader);
  392.   }
  393.   // splign object setup
  394.   CSplign splign;
  395.   splign.SetPolyaDetection(!args["nopolya"]);
  396.   splign.SetMinExonIdentity(args["min_idty"].AsDouble());
  397.   splign.SetCompartmentPenalty(args["compartment_penalty"].AsDouble());
  398.   splign.SetMinQueryCoverage(args["min_query_cov"].AsDouble());
  399.   splign.SetStrand(args["strand"].AsString() == "plus");
  400.   splign.SetEndGapDetection(!(args["noendgaps"]));
  401.   splign.SetAligner(aligner);
  402.   splign.SetSeqAccessor(seq_loader);
  403.   splign.SetStartModelId(1);
  404.   // splign formatter object
  405.   CSplignFormatter formatter (splign);
  406.   // prepare input hit stream
  407.   auto_ptr<istream> hit_stream;
  408.   if(mode_pairwise) {
  409.       CSeqLoaderPairwise* pseq_loader_pw = 
  410.           static_cast<CSeqLoaderPairwise*>(seq_loader.GetNonNullPointer());
  411.       hit_stream.reset(x_GetPairwiseHitStream(*pseq_loader_pw));
  412.   }
  413.   else {
  414.       const string filename (args["hits"].AsString());
  415.       hit_stream.reset(new ifstream (filename.c_str()));
  416.   }
  417.   // iterate over input hits
  418.   vector<CHit> hits;
  419.   while(x_GetNextPair(hit_stream.get(), &hits) ) {
  420.     if(hits.size() == 0) {
  421.       continue;
  422.     }
  423.     const string query (hits[0].m_Query);
  424.     const string subj (hits[0].m_Subj);
  425.     splign.Run(&hits);
  426.     formatter.SetSeqIds(query, subj);
  427.     cout << formatter.AsText();
  428.     if(asn_ofs.get()) {
  429.         CRef<CSeq_align_set> sa_set = formatter.AsSeqAlignSet();
  430.         auto_ptr<CObjectOStream> os(CObjectOStream::Open(eSerial_AsnText,
  431.                                                          *asn_ofs));
  432.         *os << *sa_set;
  433.     }
  434.     ITERATE(vector<CSplign::SAlignedCompartment>, ii, splign.GetResult()) {
  435.       x_LogStatus(ii->m_id, query, subj, ii->m_error, ii->m_msg);
  436.     }
  437.     if(splign.GetResult().size() == 0) {
  438.       x_LogStatus(0, query, subj, true, "No compartment found");
  439.     }
  440.   }
  441.   return 0;
  442. }
  443. END_NCBI_SCOPE
  444.                      
  445. USING_NCBI_SCOPE;
  446. // make Splign index file
  447. void MakeIDX( istream* inp_istr, const size_t file_index, ostream* out_ostr )
  448. {
  449.     istream * inp = inp_istr? inp_istr: &cin;
  450.     ostream * out = out_ostr? out_ostr: &cout;
  451.     inp->unsetf(IOS_BASE::skipws);
  452.     char c0 = 'n', c;
  453.     while(inp->good()) {
  454.         c = inp->get();
  455.         if(c0 == 'n' && c == '>') {
  456.             CT_OFF_TYPE pos = inp->tellg() - CT_POS_TYPE(1);
  457.             string s;
  458.             *inp >> s;
  459.             *out << s << 't' << file_index << 't' << pos << endl;
  460.         }
  461.         c0 = c;
  462.     }
  463. }
  464. int main(int argc, const char* argv[]) 
  465. {
  466.     // pre-scan for mkidx
  467.     for(int i = 1; i < argc; ++i) {
  468.         if(0 == strcmp(argv[i], "-mkidx")) {
  469.             
  470.             if(i + 1 == argc) {
  471.                 char err_msg [] = 
  472.                     "ERROR: No FastA files specified to index. "
  473.                     "Please specify one or more FastA files after -mkidx. "
  474.                     "Your system may support wildcards "
  475.                     "to specify multiple files.";
  476.                 cerr << err_msg << endl;
  477.                 return 1;
  478.             }
  479.             else {
  480.                 ++i;
  481.             }
  482.             vector<string> fasta_filenames;
  483.             for(; i < argc; ++i) {
  484.                 fasta_filenames.push_back(argv[i]);
  485.                 // test
  486.                 ifstream ifs (argv[i]);
  487.                 if(ifs.fail()) {
  488.                     cerr << "ERROR: Unable to open " << argv[i] << endl;
  489.                     return 1;
  490.                 }
  491.             }
  492.             
  493.             // write the list of files
  494.             const size_t files_count = fasta_filenames.size();
  495.             cout << "# This file was generated by Splign." << endl;
  496.             cout << "$$$FI" << endl;
  497.             for(size_t k = 0; k < files_count; ++k) {
  498.                 cout << fasta_filenames[k] << 't' << k << endl;
  499.             }
  500.             cout << "$$$SI" << endl;
  501.             for(size_t k = 0; k < files_count; ++k) {
  502.                 ifstream ifs (fasta_filenames[k].c_str());
  503.                 MakeIDX(&ifs, k, &cout);
  504.             }
  505.             
  506.             return 0;
  507.         }
  508.     }
  509.     
  510.     return CSplignApp().AppMain(argc, argv, 0, eDS_Default, 0);
  511. }
  512. /*
  513.  * ===========================================================================
  514.  * $Log: splign_app.cpp,v $
  515.  * Revision 1000.6  2004/06/01 18:05:26  gouriano
  516.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.24
  517.  *
  518.  * Revision 1.24  2004/05/21 21:41:02  gorelenk
  519.  * Added PCH ncbi_pch.hpp
  520.  *
  521.  * Revision 1.23  2004/05/18 21:43:40  kapustin
  522.  * Code cleanup
  523.  *
  524.  * Revision 1.22  2004/05/10 16:40:12  kapustin
  525.  * Support a pairwise mode
  526.  *
  527.  * Revision 1.21  2004/05/04 15:23:45  ucko
  528.  * Split splign code out of xalgoalign into new xalgosplign.
  529.  *
  530.  * Revision 1.20  2004/04/30 15:00:47  kapustin
  531.  * Support ASN formatting
  532.  *
  533.  * Revision 1.19  2004/04/26 19:26:22  kapustin
  534.  * Count models from one
  535.  *
  536.  * Revision 1.18  2004/04/26 15:38:46  kapustin
  537.  * Add model_id as a CSplign member
  538.  *
  539.  * Revision 1.17  2004/04/23 14:33:32  kapustin
  540.  * *** empty log message ***
  541.  *
  542.  * Revision 1.15  2004/02/19 22:57:55  ucko
  543.  * Accommodate stricter implementations of CT_POS_TYPE.
  544.  *
  545.  * Revision 1.14  2004/02/18 16:04:53  kapustin
  546.  * Do not print PolyA and gap contents
  547.  *
  548.  * Revision 1.13  2003/12/15 20:16:58  kapustin
  549.  * GetNextQuery() ->GetNextPair()
  550.  *
  551.  * Revision 1.12  2003/12/09 13:21:47  ucko
  552.  * +<memory> for auto_ptr
  553.  *
  554.  * Revision 1.11  2003/12/04 20:08:22  kapustin
  555.  * Remove endgaps argument
  556.  *
  557.  * Revision 1.10  2003/12/04 19:26:37  kapustin
  558.  * Account for zero-length segment vector
  559.  *
  560.  * Revision 1.9  2003/12/03 19:47:02  kapustin
  561.  * Increase exon search scope at the ends
  562.  *
  563.  * Revision 1.8  2003/11/26 16:13:21  kapustin
  564.  * Determine subject after filtering for more accurate log reporting
  565.  *
  566.  * Revision 1.7  2003/11/21 16:04:18  kapustin
  567.  * Enable RLE for Poly(A) tail.
  568.  *
  569.  * Revision 1.6  2003/11/20 17:58:20  kapustin
  570.  * Make the code msvc6.0-friendly
  571.  *
  572.  * Revision 1.5  2003/11/20 14:38:10  kapustin
  573.  * Add -nopolya flag to suppress Poly(A) detection.
  574.  *
  575.  * Revision 1.4  2003/11/10 19:20:26  kapustin
  576.  * Generate encoded alignment transcript by default
  577.  *
  578.  * Revision 1.3  2003/11/05 20:32:11  kapustin
  579.  * Include source information into the index
  580.  *
  581.  * Revision 1.2  2003/10/31 19:43:15  kapustin
  582.  * Format and compatibility update
  583.  *
  584.  * Revision 1.1  2003/10/30 19:37:20  kapustin
  585.  * Initial toolkit revision
  586.  *
  587.  * ===========================================================================
  588.  */