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

生物技术

开发平台:

C/C++

  1.     // Allocate memory for out_seq
  2.     out_seq_data.resize(uLength);
  3.     // Get iterator for out_seq_data
  4.     string::iterator i_out = out_seq_data.begin();
  5.     // Declare iterator for in_seq_data and determine begin and end
  6.     vector<char>::const_iterator i_in;
  7.     vector<char>::const_iterator i_in_begin = in_seq_data.begin() + uBeginIdx;
  8.     vector<char>::const_iterator i_in_end = i_in_begin + uLength;
  9.     // Loop through input and convert to output
  10.     for(i_in = i_in_begin; i_in != i_in_end; ++i_in)
  11.         *(i_out++) =
  12.             m_NcbistdaaNcbieaa->m_Table[static_cast<unsigned char>(*i_in)];
  13.     return uLength;
  14. }
  15. // Function to convert ncbistdaa (byte) to iupacaa (byte)
  16. TSeqPos CSeqportUtil_implementation::MapNcbistdaaToIupacaa
  17. (const CSeq_data&  in_seq,
  18.  CSeq_data*        out_seq,
  19.  TSeqPos           uBeginIdx,
  20.  TSeqPos           uLength)
  21.     const
  22. {
  23.     // Get read-only reference to in_seq data
  24.     const vector<char>& in_seq_data = in_seq.GetNcbistdaa().Get();
  25.     // Get read & write reference to out_seq data
  26.     out_seq->Reset();
  27.     string& out_seq_data = out_seq->SetIupacaa().Set();
  28.     // If uBeginIdx beyond end of in_seq, return
  29.     if(uBeginIdx >= in_seq_data.size())
  30.         return 0;
  31.     // Adjust uBeginIdx and uLength
  32.     Adjust(&uBeginIdx, &uLength, in_seq_data.size(), 1, 1);
  33.     // Allocate memory for out_seq
  34.     out_seq_data.resize(uLength);
  35.     // Get iterator for out_seq_data
  36.     string::iterator i_out = out_seq_data.begin();
  37.     // Declare iterator for in_seq_data and determine begin and end
  38.     vector<char>::const_iterator i_in;
  39.     vector<char>::const_iterator i_in_begin = in_seq_data.begin() + uBeginIdx;
  40.     vector<char>::const_iterator i_in_end = i_in_begin + uLength;
  41.     // Loop through input and convert to output
  42.     for(i_in = i_in_begin; i_in != i_in_end; ++i_in)
  43.         (*(i_out++)) =
  44.             m_NcbistdaaIupacaa->m_Table[static_cast<unsigned char>(*i_in)];
  45.     return uLength;
  46. }
  47. */
  48. // Fast validation of iupacna sequence
  49. bool CSeqportUtil_implementation::FastValidateIupacna
  50. (const CSeq_data&  in_seq,
  51.  TSeqPos           uBeginIdx,
  52.  TSeqPos           uLength)
  53.     const
  54. {
  55.     // Get read-only reference to in_seq data
  56.     const string& in_seq_data = in_seq.GetIupacna().Get();
  57.     // Check that uBeginIdx is not beyond end of in_seq
  58.     if(uBeginIdx >= in_seq_data.size())
  59.         return true;
  60.     // Adjust uBeginIdx, uLength
  61.     Adjust(&uBeginIdx, &uLength, in_seq_data.size(), 1, 1);
  62.     // Declare in iterator on in_seq and determine begin and end
  63.     string::const_iterator itor;
  64.     string::const_iterator b_itor = in_seq_data.begin() + uBeginIdx;
  65.     string::const_iterator e_itor = b_itor + uLength;
  66.     // Perform Fast Validation
  67.     unsigned char ch = 'x00';
  68.     for(itor = b_itor; itor != e_itor; ++itor)
  69.         ch |= m_Iupacna->m_Table[static_cast<unsigned char>(*itor)];
  70.     // Return true if valid, otherwise false
  71.     return (ch != 255);
  72. }
  73. bool CSeqportUtil_implementation::FastValidateNcbieaa
  74. (const CSeq_data&  in_seq,
  75.  TSeqPos           uBeginIdx,
  76.  TSeqPos           uLength)
  77.     const
  78. {
  79.     // Get read-only reference to in_seq data
  80.     const string& in_seq_data = in_seq.GetNcbieaa().Get();
  81.     // Check that uBeginIdx is not beyond end of in_seq
  82.     if(uBeginIdx >= in_seq_data.size())
  83.         return true;
  84.     // Check that uBeginIdx is not beyond end of in_seq
  85.     if(uBeginIdx >= in_seq_data.size())
  86.         return true;
  87.     // Adjust uBeginIdx, uLength
  88.     Adjust(&uBeginIdx, &uLength, in_seq_data.size(), 1, 1);
  89.     // Declare in iterator on in_seq and determine begin and end
  90.     string::const_iterator itor;
  91.     string::const_iterator b_itor = in_seq_data.begin() + uBeginIdx;
  92.     string::const_iterator e_itor = b_itor + uLength;
  93.     // Perform Fast Validation
  94.     unsigned char ch = 'x00';
  95.     for(itor = b_itor; itor != e_itor; ++itor)
  96.         ch |= m_Ncbieaa->m_Table[static_cast<unsigned char>(*itor)];
  97.     // Return true if valid, otherwise false
  98.     return (ch != 255);
  99. }
  100. bool CSeqportUtil_implementation::FastValidateNcbistdaa
  101. (const CSeq_data&  in_seq,
  102.  TSeqPos           uBeginIdx,
  103.  TSeqPos           uLength)
  104.     const
  105. {
  106.     // Get read-only reference to in_seq data
  107.     const vector<char>& in_seq_data = in_seq.GetNcbistdaa().Get();
  108.     // Check that uBeginIdx is not beyond end of in_seq
  109.     if(uBeginIdx >= in_seq_data.size())
  110.         return true;
  111.     // Adjust uBeginIdx, uLength
  112.     Adjust(&uBeginIdx, &uLength, in_seq_data.size(), 1, 1);
  113.     // Declare in iterator on in_seq and determine begin and end
  114.     vector<char>::const_iterator itor;
  115.     vector<char>::const_iterator b_itor = in_seq_data.begin() + uBeginIdx;
  116.     vector<char>::const_iterator e_itor = b_itor + uLength;
  117.     // Perform Fast Validation
  118.     unsigned char ch = 'x00';
  119.     for(itor = b_itor; itor != e_itor; ++itor)
  120.         ch |= m_Ncbistdaa->m_Table[static_cast<unsigned char>(*itor)];
  121.     // Return true if valid, otherwise false
  122.     return (ch != 255);
  123. }
  124. bool CSeqportUtil_implementation::FastValidateIupacaa
  125. (const CSeq_data&  in_seq,
  126.  TSeqPos           uBeginIdx,
  127.  TSeqPos           uLength)
  128.     const
  129. {
  130.     // Get read-only reference to in_seq data
  131.     const string& in_seq_data = in_seq.GetIupacaa().Get();
  132.     // Check that uBeginIdx is not beyond end of in_seq
  133.     if(uBeginIdx >= in_seq_data.size())
  134.         return true;
  135.     // Adjust uBeginIdx, uLength
  136.     Adjust(&uBeginIdx, &uLength, in_seq_data.size(), 1, 1);
  137.     // Declare in iterator on in_seq and determine begin and end
  138.     string::const_iterator itor;
  139.     string::const_iterator b_itor = in_seq_data.begin() + uBeginIdx;
  140.     string::const_iterator e_itor = b_itor + uLength;
  141.     // Perform Fast Validation
  142.     unsigned char ch = 'x00';
  143.     for(itor=b_itor; itor!=e_itor; ++itor)
  144.         ch |= m_Iupacaa->m_Table[static_cast<unsigned char>(*itor)];
  145.     // Return true if valid, otherwise false
  146.     return (ch != 255);
  147. }
  148. void CSeqportUtil_implementation::ValidateIupacna
  149. (const CSeq_data&   in_seq,
  150.  vector<TSeqPos>*   badIdx,
  151.  TSeqPos            uBeginIdx,
  152.  TSeqPos            uLength)
  153.     const
  154. {
  155.     // Get read-only reference to in_seq data
  156.     const string& in_seq_data = in_seq.GetIupacna().Get();
  157.     // clear out_indices
  158.     badIdx->clear();
  159.     // Check that uBeginIdx is not beyond end of in_seq
  160.     if(uBeginIdx >= in_seq_data.size())
  161.         return;
  162.     // Adjust uBeginIdx, uLength
  163.     Adjust(&uBeginIdx, &uLength, in_seq_data.size(), 1, 1);
  164.     // Declare in iterator on in_seq and determine begin and end
  165.     string::const_iterator itor;
  166.     string::const_iterator b_itor = in_seq_data.begin() + uBeginIdx;
  167.     string::const_iterator e_itor = b_itor + uLength;
  168.     // Perform  Validation
  169.     TSeqPos nIdx = uBeginIdx;
  170.     for(itor = b_itor; itor != e_itor; ++itor)
  171.         if(m_Iupacna->m_Table[static_cast<unsigned char>(*itor)] == char(255))
  172.             badIdx->push_back(nIdx++);
  173.         else
  174.             nIdx++;
  175.     // Return list of bad indices
  176.     return;
  177. }
  178. void CSeqportUtil_implementation::ValidateNcbieaa
  179. (const CSeq_data&   in_seq,
  180.  vector<TSeqPos>*   badIdx,
  181.  TSeqPos            uBeginIdx,
  182.  TSeqPos            uLength)
  183.     const
  184. {
  185.     // Get read-only reference to in_seq data
  186.     const string& in_seq_data = in_seq.GetNcbieaa().Get();
  187.     // clear badIdx
  188.     badIdx->clear();
  189.     // Check that uBeginIdx is not beyond end of in_seq
  190.     if(uBeginIdx >= in_seq_data.size())
  191.         return;
  192.     // Adjust uBeginIdx, uLength
  193.     Adjust(&uBeginIdx, &uLength, in_seq_data.size(), 1, 1);
  194.     // Declare in iterator on in_seq and determine begin and end
  195.     string::const_iterator itor;
  196.     string::const_iterator b_itor = in_seq_data.begin() + uBeginIdx;
  197.     string::const_iterator e_itor = b_itor + uLength;
  198.     // Perform  Validation
  199.     TSeqPos nIdx = uBeginIdx;
  200.     for(itor = b_itor; itor != e_itor; ++itor)
  201.         if(m_Ncbieaa->m_Table[static_cast<unsigned char>(*itor)] == char(255))
  202.             badIdx->push_back(nIdx++);
  203.         else
  204.             nIdx++;
  205.     // Return vector of bad indices
  206.     return;
  207. }
  208. void CSeqportUtil_implementation::ValidateNcbistdaa
  209. (const CSeq_data&   in_seq,
  210.  vector<TSeqPos>*   badIdx,
  211.  TSeqPos            uBeginIdx,
  212.  TSeqPos            uLength)
  213.     const
  214. {
  215.     // Get read-only reference to in_seq data
  216.     const vector<char>& in_seq_data = in_seq.GetNcbistdaa().Get();
  217.     // Create a vector to return
  218.     badIdx->clear();
  219.     // Check that uBeginIdx is not beyond end of in_seq
  220.     if(uBeginIdx >= in_seq_data.size())
  221.         return;
  222.     // Adjust uBeginIdx, uLength
  223.     Adjust(&uBeginIdx, &uLength, in_seq_data.size(), 1, 1);
  224.     // Declare in iterator on in_seq and determine begin and end
  225.     vector<char>::const_iterator itor;
  226.     vector<char>::const_iterator b_itor = in_seq_data.begin() + uBeginIdx;
  227.     vector<char>::const_iterator e_itor = b_itor + uLength;
  228.     // Perform  Validation
  229.     TSeqPos nIdx = uBeginIdx;
  230.     for(itor=b_itor; itor!=e_itor; ++itor)
  231.         if(m_Ncbistdaa->m_Table[static_cast<unsigned char>(*itor)]==char(255))
  232.             badIdx->push_back(nIdx++);
  233.         else
  234.             nIdx++;
  235.     // Return vector of bad indices
  236.     return;
  237. }
  238. void CSeqportUtil_implementation::ValidateIupacaa
  239. (const CSeq_data&   in_seq,
  240.  vector<TSeqPos>*   badIdx,
  241.  TSeqPos            uBeginIdx,
  242.  TSeqPos            uLength)
  243.     const
  244. {
  245.     // Get read-only reference to in_seq data
  246.     const string& in_seq_data = in_seq.GetIupacaa().Get();
  247.     // Create a vector to return
  248.     badIdx->clear();
  249.     // Check that uBeginIdx is not beyond end of in_seq
  250.     if(uBeginIdx >= in_seq_data.size())
  251.         return;
  252.     // Adjust uBeginIdx, uLength
  253.     Adjust(&uBeginIdx, &uLength, in_seq_data.size(), 1, 1);
  254.     // Declare in iterator on in_seq and determine begin and end
  255.     string::const_iterator itor;
  256.     string::const_iterator b_itor = in_seq_data.begin() + uBeginIdx;
  257.     string::const_iterator e_itor = b_itor + uLength;
  258.     // Perform  Validation
  259.     TSeqPos nIdx = uBeginIdx;
  260.     for(itor=b_itor; itor!=e_itor; ++itor)
  261.         if(m_Iupacaa->m_Table[static_cast<unsigned char>(*itor)] == char(255))
  262.             badIdx->push_back(nIdx++);
  263.         else
  264.             nIdx++;
  265.     // Return vector of bad indices
  266.     return;
  267. }
  268. // Function to make copy of ncbi2na type sequences
  269. TSeqPos CSeqportUtil_implementation::GetNcbi2naCopy
  270. (const CSeq_data&  in_seq,
  271.  CSeq_data*        out_seq,
  272.  TSeqPos           uBeginIdx,
  273.  TSeqPos           uLength)
  274.     const
  275. {
  276.     // Get reference to out_seq data
  277.     out_seq->Reset();
  278.     vector<char>& out_seq_data = out_seq->SetNcbi2na().Set();
  279.     // Get reference to in_seq data
  280.     const vector<char>& in_seq_data = in_seq.GetNcbi2na().Get();
  281.     // Return if uBeginIdx is after end of in_seq
  282.     if(uBeginIdx >= 4 * in_seq_data.size())
  283.         return 0;
  284.     // Set uLength to actual valid length in out_seq
  285.     if( (uLength ==0) || ((uBeginIdx + uLength) > (4*in_seq_data.size() )) )
  286.         uLength = 4*in_seq_data.size() - uBeginIdx;
  287.     // Allocate memory for out_seq data
  288.     if((uLength % 4) == 0)
  289.         out_seq_data.resize(uLength/4);
  290.     else
  291.         out_seq_data.resize(uLength/4 + 1);
  292.     // Get iterator on out_seq_data
  293.     vector<char>::iterator i_out = out_seq_data.begin() - 1;
  294.     // Calculate amounts to shift bits
  295.     unsigned int lShift, rShift;
  296.     lShift = 2*(uBeginIdx % 4);
  297.     rShift = 8 - lShift;
  298.     // Get interators on in_seq
  299.     vector<char>::const_iterator i_in;
  300.     vector<char>::const_iterator i_in_begin =
  301.         in_seq_data.begin() + uBeginIdx/4;
  302.     // Determine number of input bytes to process
  303.     SIZE_TYPE uNumBytes = uLength/4;
  304.     if((uLength % 4) != 0)
  305.         ++uNumBytes;
  306.     // Prevent access beyond end of in_seq_data
  307.     bool bDoLastByte = false;
  308.     if((uBeginIdx/4 + uNumBytes) >= in_seq_data.size())
  309.         {
  310.             uNumBytes = in_seq_data.size() - uBeginIdx/4 - 1;
  311.             bDoLastByte = true;
  312.         }
  313.     vector<char>::const_iterator i_in_end = i_in_begin + uNumBytes;
  314.     // Loop through input sequence and copy to output sequence
  315.     if(lShift > 0)
  316.         for(i_in = i_in_begin; i_in != i_in_end; ++i_in)
  317.             (*(++i_out)) =
  318.                 ((*i_in) << lShift) | (((*(i_in+1)) & 255) >> rShift);
  319.     else
  320.         for(i_in = i_in_begin; i_in != i_in_end; ++i_in)
  321.             (*(++i_out)) = (*i_in);
  322.     // Handle last input byte if necessary
  323.     if(bDoLastByte)
  324.         (*(++i_out)) = (*i_in) << lShift;
  325.     return uLength;
  326. }
  327. // Function to make copy of ncbi4na type sequences
  328. TSeqPos CSeqportUtil_implementation::GetNcbi4naCopy
  329. (const CSeq_data&  in_seq,
  330.  CSeq_data*        out_seq,
  331.  TSeqPos           uBeginIdx,
  332.  TSeqPos           uLength)
  333.     const
  334. {
  335.     // Get reference to out_seq data
  336.     out_seq->Reset();
  337.     vector<char>& out_seq_data = out_seq->SetNcbi4na().Set();
  338.     // Get reference to in_seq data
  339.     const vector<char>& in_seq_data = in_seq.GetNcbi4na().Get();
  340.     // Return if uBeginIdx is after end of in_seq
  341.     if(uBeginIdx >= 2 * in_seq_data.size())
  342.         return 0;
  343.     // Set uLength to actual valid length in out_seq
  344.     if( (uLength ==0) || ((uBeginIdx + uLength) > (2*in_seq_data.size() )) )
  345.         uLength = 2*in_seq_data.size() - uBeginIdx;
  346.     // Allocate memory for out_seq data
  347.     if((uLength % 2) == 0)
  348.         out_seq_data.resize(uLength/2);
  349.     else
  350.         out_seq_data.resize(uLength/2 + 1);
  351.     // Get iterator on out_seq_data
  352.     vector<char>::iterator i_out = out_seq_data.begin() - 1;
  353.     // Calculate amounts to shift bits
  354.     unsigned int lShift, rShift;
  355.     lShift = 4*(uBeginIdx % 2);
  356.     rShift = 8 - lShift;
  357.     // Get interators on in_seq
  358.     vector<char>::const_iterator i_in;
  359.     vector<char>::const_iterator i_in_begin =
  360.         in_seq_data.begin() + uBeginIdx/2;
  361.     // Determine number of input bytes to process
  362.     SIZE_TYPE uNumBytes = uLength/2;
  363.     if((uLength % 2) != 0)
  364.         ++uNumBytes;
  365.     // Prevent access beyond end of in_seq_data
  366.     bool bDoLastByte = false;
  367.     if((uBeginIdx/2 + uNumBytes) >= in_seq_data.size())
  368.         {
  369.             uNumBytes = in_seq_data.size() - uBeginIdx/2 - 1;
  370.             bDoLastByte = true;
  371.         }
  372.     vector<char>::const_iterator i_in_end = i_in_begin + uNumBytes;
  373.     // Loop through input sequence and copy to output sequence
  374.     if(lShift > 0)
  375.         for(i_in = i_in_begin; i_in != i_in_end; ++i_in)
  376.             (*(++i_out)) =
  377.                 ((*i_in) << lShift) | (((*(i_in+1)) & 255) >> rShift);
  378.     else
  379.         for(i_in = i_in_begin; i_in != i_in_end; ++i_in)
  380.             (*(++i_out)) = (*i_in);
  381.     // Handle last input byte
  382.     if(bDoLastByte)
  383.         (*(++i_out)) = (*i_in) << lShift;
  384.     return uLength;
  385. }
  386. // Function to make copy of iupacna type sequences
  387. TSeqPos CSeqportUtil_implementation::GetIupacnaCopy
  388. (const CSeq_data& in_seq,
  389.  CSeq_data*       out_seq,
  390.  TSeqPos          uBeginIdx,
  391.  TSeqPos          uLength)
  392.     const
  393. {
  394.     // Get reference to out_seq data
  395.     out_seq->Reset();
  396.     string& out_seq_data = out_seq->SetIupacna().Set();
  397.     // Get reference to in_seq data
  398.     const string& in_seq_data = in_seq.GetIupacna().Get();
  399.     // Return if uBeginIdx is after end of in_seq
  400.     if(uBeginIdx >= in_seq_data.size())
  401.         return 0;
  402.     // Set uLength to actual valid length in out_seq
  403.     if( (uLength ==0) || ((uBeginIdx + uLength) > (in_seq_data.size() )) )
  404.         uLength = in_seq_data.size() - uBeginIdx;
  405.     // Allocate memory for out_seq data
  406.     out_seq_data.resize(uLength);
  407.     // Get iterator on out_seq_data
  408.     string::iterator i_out = out_seq_data.begin() - 1;
  409.     // Get interators on in_seq
  410.     string::const_iterator i_in;
  411.     string::const_iterator i_in_begin = in_seq_data.begin() + uBeginIdx;
  412.     string::const_iterator i_in_end = i_in_begin + uLength;
  413.     // Loop through input sequence and copy to output sequence
  414.     for(i_in = i_in_begin; i_in != i_in_end; ++i_in)
  415.         (*(++i_out)) = (*i_in);
  416.     return uLength;
  417. }
  418. // Function to make copy of ncbieaa type sequences
  419. TSeqPos CSeqportUtil_implementation::GetNcbieaaCopy
  420. (const CSeq_data&  in_seq,
  421.  CSeq_data*        out_seq,
  422.  TSeqPos           uBeginIdx,
  423.  TSeqPos           uLength)
  424.     const
  425. {
  426.     // Get reference to out_seq data
  427.     out_seq->Reset();
  428.     string& out_seq_data = out_seq->SetNcbieaa().Set();
  429.     // Get reference to in_seq data
  430.     const string& in_seq_data = in_seq.GetNcbieaa().Get();
  431.     // Return if uBeginIdx is after end of in_seq
  432.     if(uBeginIdx >= in_seq_data.size())
  433.         return 0;
  434.     // Set uLength to actual valid length in out_seq
  435.     if( (uLength ==0) || ((uBeginIdx + uLength) > (in_seq_data.size() )) )
  436.         uLength = in_seq_data.size() - uBeginIdx;
  437.     // Allocate memory for out_seq data
  438.     out_seq_data.resize(uLength);
  439.     // Get iterator on out_seq_data
  440.     string::iterator i_out = out_seq_data.begin() - 1;
  441.     // Get interators on in_seq
  442.     string::const_iterator i_in;
  443.     string::const_iterator i_in_begin = in_seq_data.begin() + uBeginIdx;
  444.     string::const_iterator i_in_end = i_in_begin + uLength;
  445.     // Loop through input sequence and copy to output sequence
  446.     for(i_in = i_in_begin; i_in != i_in_end; ++i_in)
  447.         (*(++i_out)) = (*i_in);
  448.     return uLength;
  449. }
  450. // Function to make copy of ncbistdaa type sequences
  451. TSeqPos CSeqportUtil_implementation::GetNcbistdaaCopy
  452. (const CSeq_data&  in_seq,
  453.  CSeq_data*        out_seq,
  454.  TSeqPos           uBeginIdx,
  455.  TSeqPos           uLength)
  456.     const
  457. {
  458.     // Get reference to out_seq data
  459.     out_seq->Reset();
  460.     vector<char>& out_seq_data = out_seq->SetNcbistdaa().Set();
  461.     // Get reference to in_seq data
  462.     const vector<char>& in_seq_data = in_seq.GetNcbistdaa().Get();
  463.     // Return if uBeginIdx is after end of in_seq
  464.     if(uBeginIdx >= in_seq_data.size())
  465.         return 0;
  466.     // Set uLength to actual valid length in out_seq
  467.     if( (uLength ==0) || ((uBeginIdx + uLength) > (in_seq_data.size() )) )
  468.         uLength = in_seq_data.size() - uBeginIdx;
  469.     // Allocate memory for out_seq data
  470.     out_seq_data.resize(uLength);
  471.     // Get iterator on out_seq_data
  472.     vector<char>::iterator i_out = out_seq_data.begin() - 1;
  473.     // Get interators on in_seq
  474.     vector<char>::const_iterator i_in;
  475.     vector<char>::const_iterator i_in_begin = in_seq_data.begin() + uBeginIdx;
  476.     vector<char>::const_iterator i_in_end = i_in_begin + uLength;
  477.     // Loop through input sequence and copy to output sequence
  478.     for(i_in = i_in_begin; i_in != i_in_end; ++i_in)
  479.         (*(++i_out)) = (*i_in);
  480.     return uLength;
  481. }
  482. // Function to make copy of iupacaa type sequences
  483. TSeqPos CSeqportUtil_implementation::GetIupacaaCopy
  484. (const CSeq_data&  in_seq,
  485.  CSeq_data*        out_seq,
  486.  TSeqPos           uBeginIdx,
  487.  TSeqPos           uLength)
  488.     const
  489. {
  490.     // Get reference to out_seq data
  491.     out_seq->Reset();
  492.     string& out_seq_data = out_seq->SetIupacaa().Set();
  493.     // Get reference to in_seq data
  494.     const string& in_seq_data = in_seq.GetIupacaa().Get();
  495.     // Return if uBeginIdx is after end of in_seq
  496.     if(uBeginIdx >= in_seq_data.size())
  497.         return 0;
  498.     // Set uLength to actual valid length in out_seq
  499.     if( (uLength ==0) || ((uBeginIdx + uLength) > (in_seq_data.size() )) )
  500.         uLength = in_seq_data.size() - uBeginIdx;
  501.     // Allocate memory for out_seq data
  502.     out_seq_data.resize(uLength);
  503.     // Get iterator on out_seq_data
  504.     string::iterator i_out = out_seq_data.begin() - 1;
  505.     // Get interators on in_seq
  506.     string::const_iterator i_in;
  507.     string::const_iterator i_in_begin = in_seq_data.begin() + uBeginIdx;
  508.     string::const_iterator i_in_end = i_in_begin + uLength;
  509.     // Loop through input sequence and copy to output sequence
  510.     for(i_in = i_in_begin; i_in != i_in_end; ++i_in)
  511.         (*(++i_out)) = (*i_in);
  512.     return uLength;
  513. }
  514. // Function to adjust uBeginIdx to lie on an in_seq byte boundary
  515. // and uLength to lie on on an out_seq byte boundary. Returns
  516. // overhang
  517. TSeqPos CSeqportUtil_implementation::Adjust
  518. (TSeqPos*  uBeginIdx,
  519.  TSeqPos*  uLength,
  520.  TSeqPos   uInSeqBytes,
  521.  TSeqPos   uInSeqsPerByte,
  522.  TSeqPos   uOutSeqsPerByte)
  523.     const
  524. {
  525.     // Adjust uBeginIdx and uLength to acceptable values
  526.     // If uLength = 0, assume convert to end of sequence
  527.     if(*uLength == 0)
  528.         *uLength = uInSeqsPerByte * uInSeqBytes;
  529.     // Ensure that uBeginIdx does not start at or after end of in_seq_data
  530.     if(*uBeginIdx >= uInSeqsPerByte * uInSeqBytes)
  531.         *uBeginIdx = uInSeqsPerByte * uInSeqBytes - uInSeqsPerByte;
  532.     // Ensure that uBeginIdx is a multiple of uInSeqsPerByte and adjust uLength
  533.     *uLength += *uBeginIdx % uInSeqsPerByte;
  534.     *uBeginIdx = uInSeqsPerByte * (*uBeginIdx/uInSeqsPerByte);
  535.     // Adjust uLength so as not to go beyond end of in_seq_data
  536.     if(*uLength > uInSeqsPerByte * uInSeqBytes - *uBeginIdx)
  537.         *uLength = uInSeqsPerByte * uInSeqBytes - *uBeginIdx;
  538.     // Adjust uLength down to multiple of uOutSeqsPerByte
  539.     // and calculate overhang (overhang handled separately at end)
  540.     TSeqPos uOverhang = *uLength % uOutSeqsPerByte;
  541.     *uLength = uOutSeqsPerByte * (*uLength / uOutSeqsPerByte);
  542.     return uOverhang;
  543. }
  544. // Loops through an ncbi4na input sequence and determines
  545. // the ambiguities that would result from conversion to an ncbi2na sequence
  546. // On return, out_seq contains the ncbi4na bases that become ambiguous and
  547. // out_indices contains the indices of the abiguous bases in in_seq
  548. TSeqPos CSeqportUtil_implementation::GetAmbigs_ncbi4na_ncbi2na
  549. (const CSeq_data&   in_seq,
  550.  CSeq_data*         out_seq,
  551.  vector<TSeqPos>*   out_indices,
  552.  TSeqPos            uBeginIdx,
  553.  TSeqPos            uLength)
  554.     const
  555. {
  556.     // Get read-only reference to in_seq data
  557.     const vector<char>& in_seq_data = in_seq.GetNcbi4na().Get();
  558.     // Get read & write reference to out_seq data
  559.     out_seq->Reset();
  560.     vector<char>& out_seq_data = out_seq->SetNcbi4na().Set();
  561.     // Adjust uBeginIdx and uLength, if necessary
  562.     if(uBeginIdx >= 2*in_seq_data.size())
  563.         return 0;
  564.     if((uLength == 0) || (((uBeginIdx + uLength) > 2*in_seq_data.size())))
  565.         uLength = 2*in_seq_data.size() - uBeginIdx;
  566.     // Save uBeginIdx and adjust uBeginIdx = 0 mod 2
  567.     TSeqPos uBeginSav = uBeginIdx;
  568.     TSeqPos uLenSav = uLength;
  569.     uLength += uBeginIdx % 2;
  570.     uBeginIdx = 2*(uBeginIdx/2);
  571.     // Allocate memory for out_seq_data and out_indices
  572.     // Note, these will be shrunk at the end to correspond
  573.     // to actual memory needed.  Note, in test cases, over 50% of the
  574.     // time spent in this method is spent in the next two
  575.     // statements and 3/4 of that is spent in the second statement.
  576.     out_seq_data.resize(uLength/2 + (uLength % 2));
  577.     out_indices->resize(uLength);
  578.     // Variable to track number of ambigs
  579.     TSeqPos uNumAmbigs = 0;
  580.     // Get iterators to input sequence
  581.     vector<char>::const_iterator i_in;
  582.     vector<char>::const_iterator i_in_begin =
  583.         in_seq_data.begin() + uBeginIdx/2;
  584.     vector<char>::const_iterator i_in_end =
  585.         i_in_begin + uLength/2 + (uLength % 2);
  586.     // Get iterators to out_seq_data and out_indices
  587.     vector<char>::iterator i_out_seq = out_seq_data.begin();
  588.     vector<TSeqPos>::iterator i_out_idx = out_indices->begin();
  589.     // Index of current input seq base
  590.     TSeqPos uIdx = uBeginIdx;
  591.     // Loop through input sequence looking for ambiguities
  592.     for(i_in = i_in_begin; i_in != i_in_end; ++i_in) {
  593.         switch (m_DetectAmbigNcbi4naNcbi2na->m_Table
  594.                 [static_cast<unsigned char>(*i_in)]) {
  595.         case 1:    // Low order input nible ambiguous
  596.             // Put low order input nible in low order output nible
  597.             if(uNumAmbigs & 1)
  598.                 {
  599.                     (*i_out_seq) |= (*i_in) & 'x0f';
  600.                     ++i_out_seq;
  601.                 }
  602.             // Put low order input nible in high order output nible
  603.             else
  604.                 (*i_out_seq) = (*i_in) << 4;
  605.             // Record input index that was ambiguous
  606.             (*i_out_idx) = uIdx + 1;
  607.             ++i_out_idx;
  608.             // Increment number of ambiguities
  609.             uNumAmbigs++;
  610.             break;
  611.         case 2:    // High order input nible ambiguous
  612.             // Put high order input nible in low order output nible
  613.             if(uNumAmbigs & 1)
  614.                 {
  615.                     (*i_out_seq) |= ((*i_in) >> 4) & 'x0f';
  616.                     ++i_out_seq;
  617.                 }
  618.             // Put high order input nible in high order output nible
  619.             else
  620.                 (*i_out_seq) = (*i_in) & 'xf0';
  621.             // Record input index that was ambiguous
  622.             (*i_out_idx) = uIdx;
  623.             ++i_out_idx;
  624.             // Increment number of ambiguities
  625.             uNumAmbigs++;
  626.             break;
  627.         case 3:    // Both input nibles ambiguous
  628.             // Put high order input nible in low order
  629.             // output nible, move to the next output byte
  630.             // and put the low order input nibble in the
  631.             // high order output nible.
  632.             if(uNumAmbigs & 1)
  633.                 {
  634.                     (*i_out_seq) |= ((*i_in) >> 4) & 'x0f';
  635.                     (*(++i_out_seq)) = (*i_in) << 4;
  636.                 }
  637.             // Put high order input nible in high order
  638.             // output nible, put low order input nible
  639.             // in low order output nible, and move to
  640.             // next output byte
  641.             else
  642.                 {
  643.                     (*i_out_seq) = (*i_in);
  644.                     ++i_out_seq;
  645.                 }
  646.             // Record indices that were ambiguous
  647.             (*i_out_idx) = uIdx;
  648.             (*(++i_out_idx)) = uIdx + 1;
  649.             ++i_out_idx;
  650.             // Increment the number of ambiguities
  651.             uNumAmbigs+=2;
  652.             break;
  653.         }
  654.         // Increment next input byte.
  655.         uIdx += 2;
  656.     }
  657.     // Shrink out_seq_data and out_indices to actual sizes needed
  658.     out_indices->resize(uNumAmbigs);
  659.     out_seq_data.resize(uNumAmbigs/2 + uNumAmbigs % 2);
  660.     // Check to ensure that ambigs outside of requested range are not included
  661.     TSeqPos uKeepBeg = 0;
  662.     TSeqPos uKeepLen = 0;
  663.     if((*out_indices)[0] < uBeginSav)
  664.         {
  665.             uKeepBeg = 1;
  666.             out_indices->erase(out_indices->begin(), out_indices->begin() + 1);
  667.         }
  668.     if((*out_indices)[out_indices->size()-1] >= uBeginSav + uLenSav)
  669.         {
  670.             out_indices->pop_back();
  671.             uKeepLen = out_indices->size();
  672.         }
  673.     if((uKeepBeg != 0) || (uKeepLen != 0))
  674.         uNumAmbigs = KeepNcbi4na(out_seq, uKeepBeg, uKeepLen);
  675.     return uNumAmbigs;
  676. }
  677. // Loops through an iupacna input sequence and determines
  678. // the ambiguities that would result from conversion to an ncbi2na sequence.
  679. // On return, out_seq contains the iupacna bases that become ambiguous and
  680. // out_indices contains the indices of the abiguous bases in in_seq. The
  681. // return is the number of ambiguities found.
  682. TSeqPos CSeqportUtil_implementation::GetAmbigs_iupacna_ncbi2na
  683. (const CSeq_data&   in_seq,
  684.  CSeq_data*         out_seq,
  685.  vector<TSeqPos>*   out_indices,
  686.  TSeqPos            uBeginIdx,
  687.  TSeqPos            uLength)
  688.     const
  689. {
  690.     // Get read-only reference to in_seq data
  691.     const string& in_seq_data = in_seq.GetIupacna().Get();
  692.     // Get read & write reference to out_seq data
  693.     out_seq->Reset();
  694.     string& out_seq_data = out_seq->SetIupacna().Set();
  695.     // Validate/adjust uBeginIdx and uLength
  696.     if(uBeginIdx >= in_seq_data.size())
  697.         return 0;
  698.     if((uLength == 0) || ((uBeginIdx + uLength) > in_seq_data.size()))
  699.         uLength = in_seq_data.size() - uBeginIdx;
  700.     // Allocate memory for out_seq_data and out_indices
  701.     // Note, these will be shrunk at the end to correspond
  702.     // to actual memory needed.
  703.     out_seq_data.resize(uLength);
  704.     out_indices->resize(uLength);
  705.     // Variable to track number of ambigs
  706.     TSeqPos uNumAmbigs = 0;
  707.     // Get iterators to input sequence
  708.     string::const_iterator i_in;
  709.     string::const_iterator i_in_begin = in_seq_data.begin() + uBeginIdx;
  710.     string::const_iterator i_in_end = i_in_begin + uLength;
  711.     // Get iterators to out_seq_data and out_indices
  712.     string::iterator i_out_seq = out_seq_data.begin();
  713.     vector<TSeqPos>::iterator i_out_idx = out_indices->begin();
  714.     // Index of current input seq base
  715.     TSeqPos uIdx = uBeginIdx;
  716.     // Loop through input sequence looking for ambiguities
  717.     for(i_in = i_in_begin; i_in != i_in_end; ++i_in)
  718.         {
  719.             if(m_DetectAmbigIupacnaNcbi2na->m_Table
  720.                [static_cast<unsigned char>(*i_in)] == 1)
  721.                 {
  722.                     (*i_out_seq) = (*i_in);
  723.                     ++i_out_seq;
  724.                     (*i_out_idx) = uIdx;
  725.                     ++i_out_idx;
  726.                     ++uNumAmbigs;
  727.                 }
  728.             ++uIdx;
  729.         }
  730.     out_seq_data.resize(uNumAmbigs);
  731.     out_indices->resize(uNumAmbigs);
  732.     return uNumAmbigs;
  733. }
  734. // Method to implement Keep for Ncbi2na. Returns length of
  735. // kept sequence
  736. TSeqPos CSeqportUtil_implementation::KeepNcbi2na
  737. (CSeq_data*   in_seq,
  738.  TSeqPos      uBeginIdx,
  739.  TSeqPos      uLength)
  740.     const
  741. {
  742.     // Get a reference to in_seq
  743.     vector<char>& in_seq_data = in_seq->SetNcbi2na().Set();
  744.     // If uBeginIdx past the end of in_seq, return empty in_seq
  745.     if(uBeginIdx >= in_seq_data.size()*4)
  746.         {
  747.             in_seq_data.clear();
  748.             return 0;
  749.         }
  750.     // If uLength == 0, Keep from uBeginIdx to end of in_seq
  751.     if(uLength == 0)
  752.         uLength = 4*in_seq_data.size() - uBeginIdx;
  753.     // If uLength goes beyond the end of the sequence, trim
  754.     // it back to the end of the sequence
  755.     if(uLength > (4*in_seq_data.size() - uBeginIdx))
  756.         uLength = 4*in_seq_data.size() - uBeginIdx;
  757.     // If entire sequence is being requested, just return
  758.     if((uBeginIdx == 0) && (uLength >= 4*in_seq_data.size()))
  759.         return uLength;
  760.     // Determine index in in_seq_data that holds uBeginIdx residue
  761.     TSeqPos uStart = uBeginIdx/4;
  762.     // Determine index within start byte
  763.     TSeqPos uStartInByte = 2 * (uBeginIdx % 4);
  764.     // Calculate masks
  765.     unsigned char rightMask = 0xff << uStartInByte;
  766.     unsigned char leftMask = ~rightMask;
  767.     // Determine index in in_seq_data that holds uBeginIdx + uLength
  768.     // residue
  769.     TSeqPos uEnd = (uBeginIdx + uLength - 1)/4;
  770.     // Get iterator for writting
  771.     vector<char>::iterator i_write;
  772.     // Determine begin and end of read
  773.     vector<char>::iterator i_read = in_seq_data.begin() + uStart;
  774.     vector<char>::iterator i_read_end = in_seq_data.begin() + uEnd;
  775.     // Loop through in_seq_data and copy data of desire
  776.     // sub sequence to begining of in_seq_data
  777.     for(i_write = in_seq_data.begin(); i_read != i_read_end; ++i_write) {
  778.         (*i_write) = (((*i_read) << uStartInByte) | leftMask) &
  779.             (((*(i_read+1)) >> (8-uStartInByte)) | rightMask);
  780.         ++i_read;
  781.     }
  782.     // Handle last byte
  783.     (*i_write) = (*i_read) << uStartInByte;
  784.     // Shrink in_seq to to size needed
  785.     TSeqPos uSize = uLength/4;
  786.     if((uLength % 4) != 0)
  787.         uSize++;
  788.     in_seq_data.resize(uSize);
  789.     return uLength;
  790. }
  791. // Method to implement Keep for Ncbi4na. Returns length of
  792. // kept sequence.
  793. TSeqPos CSeqportUtil_implementation::KeepNcbi4na
  794. (CSeq_data*   in_seq,
  795.  TSeqPos      uBeginIdx,
  796.  TSeqPos      uLength)
  797.     const
  798. {
  799.     // Get a reference to in_seq
  800.     vector<char>& in_seq_data = in_seq->SetNcbi4na().Set();
  801.     // If uBeginIdx past the end of in_seq, return empty in_seq
  802.     if(uBeginIdx >= in_seq_data.size()*2)
  803.         {
  804.             in_seq_data.clear();
  805.             return 0;
  806.         }
  807.     // If uLength == 0, Keep from uBeginIdx to end of in_seq
  808.     if(uLength == 0)
  809.         uLength = 2*in_seq_data.size() - uBeginIdx;
  810.     // If uLength goes beyond the end of the sequence, trim
  811.     // it back to the end of the sequence
  812.     if(uLength > (2*in_seq_data.size() - uBeginIdx))
  813.         uLength = 2*in_seq_data.size() - uBeginIdx;
  814.     // If entire sequence is being requested, just return
  815.     if((uBeginIdx == 0) && (uLength >= 2*in_seq_data.size()))
  816.         return uLength;
  817.     // Determine index in in_seq_data that holds uBeginIdx residue
  818.     TSeqPos uStart = uBeginIdx/2;
  819.     // Determine index within start byte
  820.     unsigned int uStartInByte = 4 * (uBeginIdx % 2);
  821.     // Calculate masks
  822.     unsigned char rightMask = 0xff << uStartInByte;
  823.     unsigned char leftMask = ~rightMask;
  824.     // Determine index in in_seq_data that holds uBeginIdx + uLength
  825.     // residue
  826.     TSeqPos uEnd = (uBeginIdx + uLength - 1)/2;
  827.     // Get iterator for writting
  828.     vector<char>::iterator i_write;
  829.     // Determine begin and end of read
  830.     vector<char>::iterator i_read = in_seq_data.begin() + uStart;
  831.     vector<char>::iterator i_read_end = in_seq_data.begin() + uEnd;
  832.     // Loop through in_seq_data and copy data of desire
  833.     // sub sequence to begining of in_seq_data
  834.     for(i_write = in_seq_data.begin(); i_read != i_read_end; ++i_write) {
  835.         (*i_write) = (((*i_read) << uStartInByte) | leftMask) &
  836.             (((*(i_read+1)) >> (8-uStartInByte)) | rightMask);
  837.         ++i_read;
  838.     }
  839.     // Handle last byte
  840.     (*i_write) = (*i_read) << uStartInByte;
  841.     // Shrink in_seq to to size needed
  842.     TSeqPos uSize = uLength/2;
  843.     if((uLength % 2) != 0)
  844.         uSize++;
  845.     in_seq_data.resize(uSize);
  846.     return uLength;
  847. }
  848. // Method to implement Keep for Iupacna. Return length
  849. // of kept sequence
  850. TSeqPos CSeqportUtil_implementation::KeepIupacna
  851. (CSeq_data*   in_seq,
  852.  TSeqPos      uBeginIdx,
  853.  TSeqPos      uLength)
  854.     const
  855. {
  856.     // Get a reference to in_seq
  857.     string& in_seq_data = in_seq->SetIupacna().Set();
  858.     // If uBeginIdx past end of in_seq, return empty in_seq
  859.     if(uBeginIdx >= in_seq_data.size())
  860.         {
  861.             in_seq_data.erase();
  862.             return 0;
  863.         }
  864.     // If uLength is 0, Keep from uBeginIdx to end of in_seq
  865.     if(uLength == 0)
  866.         uLength = in_seq_data.size() - uBeginIdx;
  867.     // Check that uLength does not go beyond end of in_seq
  868.     if((uBeginIdx + uLength) > in_seq_data.size())
  869.         uLength = in_seq_data.size() - uBeginIdx;
  870.     // If uBeginIdx == 0 and uLength == in_seq_data.size()
  871.     // just return as the entire sequence is being requested
  872.     if((uBeginIdx == 0) && (uLength >= in_seq_data.size()))
  873.         return uLength;
  874.     // Get two iterators on in_seq, one read and one write
  875.     string::iterator i_read;
  876.     string::iterator i_write;
  877.     // Determine begin and end of read
  878.     i_read = in_seq_data.begin() + uBeginIdx;
  879.     string::iterator i_read_end = i_read + uLength;
  880.     // Loop through in_seq for uLength bases
  881.     // and shift uBeginIdx to beginning
  882.     for(i_write = in_seq_data.begin(); i_read != i_read_end; ++i_write)
  883.         {
  884.             (*i_write) = (*i_read);
  885.             ++i_read;
  886.         }
  887.     // Resize in_seq_data to uLength
  888.     in_seq_data.resize(uLength);
  889.     return uLength;
  890. }
  891. // Method to implement Keep for Ncbieaa
  892. TSeqPos CSeqportUtil_implementation::KeepNcbieaa
  893. (CSeq_data*   in_seq,
  894.  TSeqPos      uBeginIdx,
  895.  TSeqPos      uLength)
  896.     const
  897. {
  898.     // Get a reference to in_seq
  899.     string& in_seq_data = in_seq->SetNcbieaa().Set();
  900.     // If uBeginIdx past end of in_seq, return empty in_seq
  901.     if(uBeginIdx >= in_seq_data.size())
  902.         {
  903.             in_seq_data.erase();
  904.             return 0;
  905.         }
  906.     // If uLength is 0, Keep from uBeginIdx to end of in_seq
  907.     if(uLength == 0)
  908.         uLength = in_seq_data.size() - uBeginIdx;
  909.     // Check that uLength does not go beyond end of in_seq
  910.     if((uBeginIdx + uLength) > in_seq_data.size())
  911.         uLength = in_seq_data.size() - uBeginIdx;
  912.     // If uBeginIdx == 0 and uLength == in_seq_data.size()
  913.     // just return as the entire sequence is being requested
  914.     if((uBeginIdx == 0) && (uLength >= in_seq_data.size()))
  915.         return uLength;
  916.     // Get two iterators on in_seq, one read and one write
  917.     string::iterator i_read;
  918.     string::iterator i_write;
  919.     // Determine begin and end of read
  920.     i_read = in_seq_data.begin() + uBeginIdx;
  921.     string::iterator i_read_end = i_read + uLength;
  922.     // Loop through in_seq for uLength bases
  923.     // and shift uBeginIdx to beginning
  924.     for(i_write = in_seq_data.begin(); i_read != i_read_end; ++i_write) {
  925.         (*i_write) = (*i_read);
  926.         ++i_read;
  927.     }
  928.     // Resize in_seq_data to uLength
  929.     in_seq_data.resize(uLength);
  930.     return uLength;
  931. }
  932. // Method to implement Keep for Ncbistdaa
  933. TSeqPos CSeqportUtil_implementation::KeepNcbistdaa
  934. (CSeq_data*   in_seq,
  935.  TSeqPos      uBeginIdx,
  936.  TSeqPos      uLength)
  937.     const
  938. {
  939.     // Get a reference to in_seq
  940.     vector<char>& in_seq_data = in_seq->SetNcbistdaa().Set();
  941.     // If uBeginIdx past end of in_seq, return empty in_seq
  942.     if(uBeginIdx >= in_seq_data.size())
  943.         {
  944.             in_seq_data.clear();
  945.             return 0;
  946.         }
  947.     // If uLength is 0, Keep from uBeginIdx to end of in_seq
  948.     if(uLength == 0)
  949.         uLength = in_seq_data.size() - uBeginIdx;
  950.     // Check that uLength does not go beyond end of in_seq
  951.     if((uBeginIdx + uLength) > in_seq_data.size())
  952.         uLength = in_seq_data.size() - uBeginIdx;
  953.     // If uBeginIdx == 0 and uLength == in_seq_data.size()
  954.     // just return as the entire sequence is being requested
  955.     if((uBeginIdx == 0) && (uLength >= in_seq_data.size()))
  956.         return uLength;
  957.     // Get two iterators on in_seq, one read and one write
  958.     vector<char>::iterator i_read;
  959.     vector<char>::iterator i_write;
  960.     // Determine begin and end of read
  961.     i_read = in_seq_data.begin() + uBeginIdx;
  962.     vector<char>::iterator i_read_end = i_read + uLength;
  963.     // Loop through in_seq for uLength bases
  964.     // and shift uBeginIdx to beginning
  965.     for(i_write = in_seq_data.begin(); i_read != i_read_end; ++i_write) {
  966.         (*i_write) = (*i_read);
  967.         ++i_read;
  968.     }
  969.     // Resize in_seq_data to uLength
  970.     in_seq_data.resize(uLength);
  971.     return uLength;
  972. }
  973. // Method to implement Keep for Iupacaa
  974. TSeqPos CSeqportUtil_implementation::KeepIupacaa
  975. (CSeq_data*   in_seq,
  976.  TSeqPos      uBeginIdx,
  977.  TSeqPos      uLength)
  978.     const
  979. {
  980.     // Get a reference to in_seq
  981.     string& in_seq_data = in_seq->SetIupacaa().Set();
  982.     // If uBeginIdx past end of in_seq, return empty in_seq
  983.     if (uBeginIdx >= in_seq_data.size()) {
  984.         in_seq_data.erase();
  985.         return 0;
  986.     }
  987.     // If uLength is 0, Keep from uBeginIdx to end of in_seq
  988.     if(uLength == 0)
  989.         uLength = in_seq_data.size() - uBeginIdx;
  990.     // Check that uLength does not go beyond end of in_seq
  991.     if((uBeginIdx + uLength) > in_seq_data.size())
  992.         uLength = in_seq_data.size() - uBeginIdx;
  993.     // If uBeginIdx == 0 and uLength == in_seq_data.size()
  994.     // just return as the entire sequence is being requested
  995.     if((uBeginIdx == 0) && (uLength >= in_seq_data.size()))
  996.         return uLength;
  997.     // Get two iterators on in_seq, one read and one write
  998.     string::iterator i_read;
  999.     string::iterator i_write;
  1000.     // Determine begin and end of read
  1001.     i_read = in_seq_data.begin() + uBeginIdx;
  1002.     string::iterator i_read_end = i_read + uLength;
  1003.     // Loop through in_seq for uLength bases
  1004.     // and shift uBeginIdx to beginning
  1005.     for(i_write = in_seq_data.begin(); i_read != i_read_end; ++i_write) {
  1006.         (*i_write) = (*i_read);
  1007.         ++i_read;
  1008.     }
  1009.     // Resize in_seq_data to uLength
  1010.     in_seq_data.resize(uLength);
  1011.     return uLength;
  1012. }
  1013. // Methods to complement na sequences
  1014. // In place methods
  1015. TSeqPos CSeqportUtil_implementation::ComplementIupacna
  1016. (CSeq_data*   in_seq,
  1017.  TSeqPos      uBeginIdx,
  1018.  TSeqPos      uLength)
  1019.     const
  1020. {
  1021.     // Keep just the part of in_seq that will be complemented
  1022.     TSeqPos uKept = KeepIupacna(in_seq, uBeginIdx, uLength);
  1023.     // Get in_seq data
  1024.     string& in_seq_data = in_seq->SetIupacna().Set();
  1025.     // Get an iterator to in_seq_data
  1026.     string::iterator i_data;
  1027.     // Get end of iteration--needed for performance
  1028.     string::iterator i_data_end = in_seq_data.end();
  1029.     // Loop through the input sequence and complement it
  1030.     for(i_data = in_seq_data.begin(); i_data != i_data_end; ++i_data)
  1031.         (*i_data) =
  1032.             m_Iupacna_complement->m_Table[static_cast<unsigned char>(*i_data)];
  1033.     return uKept;
  1034. }
  1035. TSeqPos CSeqportUtil_implementation::ComplementNcbi2na
  1036. (CSeq_data*   in_seq,
  1037.  TSeqPos      uBeginIdx,
  1038.  TSeqPos      uLength)
  1039.     const
  1040. {
  1041.     // Keep just the part of in_seq that will be complemented
  1042.     TSeqPos uKept = KeepNcbi2na(in_seq, uBeginIdx, uLength);
  1043.     // Get in_seq data
  1044.     vector<char>& in_seq_data = in_seq->SetNcbi2na().Set();
  1045.     // Get an iterator to in_seq_data
  1046.     vector<char>::iterator i_data;
  1047.     // Get end of iteration
  1048.     vector<char>::iterator i_data_end = in_seq_data.end();
  1049.     // Loop through the input sequence and complement it
  1050.     for(i_data = in_seq_data.begin(); i_data != i_data_end; ++i_data)
  1051.         (*i_data) =
  1052.             m_Ncbi2naComplement->m_Table[static_cast<unsigned char>(*i_data)];
  1053.     return uKept;
  1054. }
  1055. TSeqPos CSeqportUtil_implementation::ComplementNcbi4na
  1056. (CSeq_data*   in_seq,
  1057.  TSeqPos      uBeginIdx,
  1058.  TSeqPos      uLength)
  1059.     const
  1060. {
  1061.     // Keep just the part of in_seq that will be complemented
  1062.     TSeqPos uKept = KeepNcbi4na(in_seq, uBeginIdx, uLength);
  1063.     // Get in_seq data
  1064.     vector<char>& in_seq_data = in_seq->SetNcbi4na().Set();
  1065.     // Get an iterator to in_seq_data
  1066.     vector<char>::iterator i_data;
  1067.     // Get end of iteration--done for performance
  1068.     vector<char>::iterator i_data_end = in_seq_data.end();
  1069.     // Loop through the input sequence and complement it
  1070.     for(i_data = in_seq_data.begin(); i_data != i_data_end; ++i_data)
  1071.         (*i_data) =
  1072.             m_Ncbi4naComplement->m_Table[static_cast<unsigned char>(*i_data)];
  1073.     return uKept;
  1074. }
  1075. // Complement in copy methods
  1076. TSeqPos CSeqportUtil_implementation::ComplementIupacna
  1077. (const CSeq_data&  in_seq,
  1078.  CSeq_data*        out_seq,
  1079.  TSeqPos           uBeginIdx,
  1080.  TSeqPos           uLength)
  1081.     const
  1082. {
  1083.     TSeqPos uKept = GetIupacnaCopy(in_seq, out_seq, uBeginIdx, uLength);
  1084.     TSeqPos uIdx1 = 0, uIdx2 = 0;
  1085.     ComplementIupacna(out_seq, uIdx1, uIdx2);
  1086.     return uKept;
  1087. }
  1088. TSeqPos CSeqportUtil_implementation::ComplementNcbi2na
  1089. (const CSeq_data&  in_seq,
  1090.  CSeq_data*        out_seq,
  1091.  TSeqPos           uBeginIdx,
  1092.  TSeqPos           uLength)
  1093.     const
  1094. {
  1095.     TSeqPos uKept = GetNcbi2naCopy(in_seq, out_seq, uBeginIdx, uLength);
  1096.     TSeqPos uIdx1 = 0, uIdx2 = 0;
  1097.     ComplementNcbi2na(out_seq, uIdx1, uIdx2);
  1098.     return uKept;
  1099. }
  1100. TSeqPos CSeqportUtil_implementation::ComplementNcbi4na
  1101. (const CSeq_data&  in_seq,
  1102.  CSeq_data*        out_seq,
  1103.  TSeqPos           uBeginIdx,
  1104.  TSeqPos           uLength)
  1105.     const
  1106. {
  1107.     TSeqPos uKept = GetNcbi4naCopy(in_seq, out_seq, uBeginIdx, uLength);
  1108.     TSeqPos uIdx1 = 0, uIdx2 = 0;
  1109.     ComplementNcbi4na(out_seq, uIdx1, uIdx2);
  1110.     return uKept;
  1111. }
  1112. // Methods to reverse na sequences
  1113. // In place methods
  1114. TSeqPos CSeqportUtil_implementation::ReverseIupacna
  1115. (CSeq_data*  in_seq,
  1116.  TSeqPos     uBeginIdx,
  1117.  TSeqPos     uLength)
  1118.     const
  1119. {
  1120.     // Keep just the part of in_seq that will be reversed
  1121.     TSeqPos uKept = KeepIupacna(in_seq, uBeginIdx, uLength);
  1122.     // Get in_seq data
  1123.     string& in_seq_data = in_seq->SetIupacna().Set();
  1124.     // Reverse the order of the string
  1125.     reverse(in_seq_data.begin(), in_seq_data.end());
  1126.     return uKept;
  1127. }
  1128. TSeqPos CSeqportUtil_implementation::ReverseNcbi2na
  1129. (CSeq_data*  in_seq,
  1130.  TSeqPos     uBeginIdx,
  1131.  TSeqPos     uLength)
  1132.     const
  1133. {
  1134.     // Get a reference to in_seq data
  1135.     vector<char>& in_seq_data = in_seq->SetNcbi2na().Set();
  1136.     // Validate and adjust uBeginIdx and uLength
  1137.     if(uBeginIdx >= 4*in_seq_data.size())
  1138.         {
  1139.             in_seq_data.erase(in_seq_data.begin(), in_seq_data.end());
  1140.             return 0;
  1141.         }
  1142.     // If uLength is zero, set to end of sequence
  1143.     if(uLength == 0)
  1144.         uLength = 4*in_seq_data.size() - uBeginIdx;
  1145.     // Ensure that uLength not beyond end of sequence
  1146.     if((uBeginIdx + uLength) > (4 * in_seq_data.size()))
  1147.         uLength = 4*in_seq_data.size() - uBeginIdx;
  1148.     // Determine start and end bytes
  1149.     TSeqPos uStart = uBeginIdx/4;
  1150.     TSeqPos uEnd = uStart + (uLength - 1 +(uBeginIdx % 4))/4 + 1;
  1151.     // Declare an iterator and get end of sequence
  1152.     vector<char>::iterator i_in;
  1153.     vector<char>::iterator i_in_begin = in_seq_data.begin() + uStart;
  1154.     vector<char>::iterator i_in_end = in_seq_data.begin() + uEnd;
  1155.     // Loop through in_seq_data and reverse residues in each byte
  1156.     for(i_in = i_in_begin; i_in != i_in_end; ++i_in)
  1157.         (*i_in) = m_Ncbi2naRev->m_Table[static_cast<unsigned char>(*i_in)];
  1158.     // Reverse the bytes in the sequence
  1159.     reverse(i_in_begin, i_in_end);
  1160.     // Keep just the requested part of the sequence
  1161.     TSeqPos uJagged = 3 - ((uBeginIdx + uLength - 1) % 4) + 4*uStart;
  1162.     return KeepNcbi2na(in_seq, uJagged, uLength);
  1163. }
  1164. TSeqPos CSeqportUtil_implementation::ReverseNcbi4na
  1165. (CSeq_data*   in_seq,
  1166.  TSeqPos      uBeginIdx,
  1167.  TSeqPos      uLength)
  1168.     const
  1169. {
  1170.     // Get a reference to in_seq data
  1171.     vector<char>& in_seq_data = in_seq->SetNcbi4na().Set();
  1172.     // Validate and adjust uBeginIdx and uLength
  1173.     if(uBeginIdx >= 2*in_seq_data.size())
  1174.         {
  1175.             in_seq_data.erase(in_seq_data.begin(), in_seq_data.end());
  1176.             return 0;
  1177.         }
  1178.     // If uLength is zero, set to end of sequence
  1179.     if(uLength == 0)
  1180.         uLength = 2*in_seq_data.size() - uBeginIdx;
  1181.     // Ensure that uLength not beyond end of sequence
  1182.     if((uBeginIdx + uLength) > (2 * in_seq_data.size()))
  1183.         uLength = 2*in_seq_data.size() - uBeginIdx;
  1184.     // Determine start and end bytes
  1185.     TSeqPos uStart = uBeginIdx/2;
  1186.     TSeqPos uEnd = uStart + (uLength - 1 +(uBeginIdx % 2))/2 + 1;
  1187.     // Declare an iterator and get end of sequence
  1188.     vector<char>::iterator i_in;
  1189.     vector<char>::iterator i_in_begin = in_seq_data.begin() + uStart;
  1190.     vector<char>::iterator i_in_end = in_seq_data.begin() + uEnd;
  1191.     // Loop through in_seq_data and reverse residues in each byte
  1192.     for(i_in = i_in_begin; i_in != i_in_end; ++i_in)
  1193.         (*i_in) = m_Ncbi4naRev->m_Table[static_cast<unsigned char>(*i_in)];
  1194.     // Reverse the bytes in the sequence
  1195.     reverse(i_in_begin, i_in_end);
  1196.     // Keep just the requested part of the sequence
  1197.     TSeqPos uJagged = 1 - ((uBeginIdx + uLength - 1) % 2) + 2*uStart;
  1198.     return KeepNcbi4na(in_seq, uJagged, uLength);
  1199. }
  1200. // Reverse in copy methods
  1201. TSeqPos CSeqportUtil_implementation::ReverseIupacna
  1202. (const CSeq_data&  in_seq,
  1203.  CSeq_data*        out_seq,
  1204.  TSeqPos           uBeginIdx,
  1205.  TSeqPos           uLength)
  1206.     const
  1207. {
  1208.     GetIupacnaCopy(in_seq, out_seq, uBeginIdx, uLength);
  1209.     TSeqPos uIdx1 = 0, uIdx2 = uLength;
  1210.     return ReverseIupacna(out_seq, uIdx1, uIdx2);
  1211. }
  1212. TSeqPos CSeqportUtil_implementation::ReverseNcbi2na
  1213. (const CSeq_data&  in_seq,
  1214.  CSeq_data*        out_seq,
  1215.  TSeqPos           uBeginIdx,
  1216.  TSeqPos           uLength)
  1217.     const
  1218. {
  1219.     GetNcbi2naCopy(in_seq, out_seq, uBeginIdx, uLength);
  1220.     TSeqPos uIdx1 = 0, uIdx2 = uLength;
  1221.     return ReverseNcbi2na(out_seq, uIdx1, uIdx2);
  1222. }
  1223. TSeqPos CSeqportUtil_implementation::ReverseNcbi4na
  1224. (const CSeq_data&  in_seq,
  1225.  CSeq_data*        out_seq,
  1226.  TSeqPos           uBeginIdx,
  1227.  TSeqPos           uLength)
  1228.     const
  1229. {
  1230.     GetNcbi4naCopy(in_seq, out_seq, uBeginIdx, uLength);
  1231.     TSeqPos uIdx1 = 0, uIdx2 = uLength;
  1232.     return ReverseNcbi4na(out_seq, uIdx1, uIdx2);
  1233. }
  1234. // Methods to reverse-complement an na sequences
  1235. // In place methods
  1236. TSeqPos CSeqportUtil_implementation::ReverseComplementIupacna
  1237. (CSeq_data*        in_seq,
  1238.  TSeqPos           uBeginIdx,
  1239.  TSeqPos           uLength)
  1240.     const
  1241. {
  1242.     ReverseIupacna(in_seq, uBeginIdx, uLength);
  1243.     TSeqPos uIdx = 0;
  1244.     return ComplementIupacna(in_seq, uIdx, uLength);
  1245. }
  1246. TSeqPos CSeqportUtil_implementation::ReverseComplementNcbi2na
  1247. (CSeq_data*        in_seq,
  1248.  TSeqPos           uBeginIdx,
  1249.  TSeqPos           uLength)
  1250.     const
  1251. {
  1252.     ReverseNcbi2na(in_seq, uBeginIdx, uLength);
  1253.     TSeqPos uIdx = 0;
  1254.     return ComplementNcbi2na(in_seq, uIdx, uLength);
  1255. }
  1256. TSeqPos CSeqportUtil_implementation::ReverseComplementNcbi4na
  1257. (CSeq_data*        in_seq,
  1258.  TSeqPos           uBeginIdx,
  1259.  TSeqPos           uLength)
  1260.     const
  1261. {
  1262.     ReverseNcbi4na(in_seq, uBeginIdx, uLength);
  1263.     TSeqPos uIdx = 0;
  1264.     return ComplementNcbi4na(in_seq, uIdx, uLength);
  1265. }
  1266. // Reverse in copy methods
  1267. TSeqPos CSeqportUtil_implementation::ReverseComplementIupacna
  1268. (const CSeq_data&  in_seq,
  1269.  CSeq_data*        out_seq,
  1270.  TSeqPos           uBeginIdx,
  1271.  TSeqPos           uLength)
  1272.     const
  1273. {
  1274.     ReverseIupacna(in_seq, out_seq, uBeginIdx, uLength);
  1275.     TSeqPos uIdx = 0;
  1276.     return ComplementIupacna(out_seq, uIdx, uLength);
  1277. }
  1278. TSeqPos CSeqportUtil_implementation::ReverseComplementNcbi2na
  1279. (const CSeq_data&  in_seq,
  1280.  CSeq_data*        out_seq,
  1281.  TSeqPos           uBeginIdx,
  1282.  TSeqPos           uLength)
  1283.     const
  1284. {
  1285.     ReverseNcbi2na(in_seq, out_seq, uBeginIdx, uLength);
  1286.     TSeqPos uIdx = 0;
  1287.     return ComplementNcbi2na(out_seq, uIdx, uLength);
  1288. }
  1289. TSeqPos CSeqportUtil_implementation::ReverseComplementNcbi4na
  1290. (const CSeq_data&  in_seq,
  1291.  CSeq_data*        out_seq,
  1292.  TSeqPos           uBeginIdx,
  1293.  TSeqPos           uLength)
  1294.     const
  1295. {
  1296.     ReverseNcbi4na(in_seq, out_seq, uBeginIdx, uLength);
  1297.     TSeqPos uIdx = 0;
  1298.     return ComplementNcbi4na(out_seq, uIdx, uLength);
  1299. }
  1300. // Append methods
  1301. TSeqPos CSeqportUtil_implementation::AppendIupacna
  1302. (CSeq_data*        out_seq,
  1303.  const CSeq_data&  in_seq1,
  1304.  TSeqPos           uBeginIdx1,
  1305.  TSeqPos           uLength1,
  1306.  const CSeq_data&  in_seq2,
  1307.  TSeqPos           uBeginIdx2,
  1308.  TSeqPos           uLength2)
  1309.     const
  1310. {
  1311.     // Get references to in_seqs
  1312.     const string& in_seq1_data = in_seq1.GetIupacna().Get();
  1313.     const string& in_seq2_data = in_seq2.GetIupacna().Get();
  1314.     // Get a reference to out_seq
  1315.     out_seq->Reset();
  1316.     string& out_seq_data = out_seq->SetIupacna().Set();
  1317.     // Validate and Adjust uBeginIdx_ and uLength_
  1318.     if((uBeginIdx1 >= in_seq1_data.size()) &&
  1319.        (uBeginIdx2 >= in_seq2_data.size()))
  1320.         return 0;
  1321.     if(((uBeginIdx1 + uLength1) > in_seq1_data.size()) || uLength1 == 0)
  1322.         uLength1 = in_seq1_data.size() - uBeginIdx1;
  1323.     if(((uBeginIdx2 + uLength2) > in_seq2_data.size()) || uLength2 == 0)
  1324.         uLength2 = in_seq2_data.size() - uBeginIdx2;
  1325.     // Append the strings
  1326.     out_seq_data.append(in_seq1_data.substr(uBeginIdx1,uLength1));
  1327.     out_seq_data.append(in_seq2_data.substr(uBeginIdx2,uLength2));
  1328.     return uLength1 + uLength2;
  1329. }
  1330. TSeqPos CSeqportUtil_implementation::AppendNcbi2na
  1331. (CSeq_data*        out_seq,
  1332.  const CSeq_data&  in_seq1,
  1333.  TSeqPos           uBeginIdx1,
  1334.  TSeqPos           uLength1,
  1335.  const CSeq_data&  in_seq2,
  1336.  TSeqPos           uBeginIdx2,
  1337.  TSeqPos           uLength2)
  1338.     const
  1339. {
  1340.     // Get references to in_seqs
  1341.     const vector<char>& in_seq1_data = in_seq1.GetNcbi2na().Get();
  1342.     const vector<char>& in_seq2_data = in_seq2.GetNcbi2na().Get();
  1343.     // Get a reference to out_seq
  1344.     out_seq->Reset();
  1345.     vector<char>& out_seq_data = out_seq->SetNcbi2na().Set();
  1346.     // Handle case where both uBeginidx go beyond in_seq
  1347.     if((uBeginIdx1 >= 4*in_seq1_data.size()) &&
  1348.        (uBeginIdx2 >= 4*in_seq2_data.size()))
  1349.         return 0;
  1350.     // Handle case where uBeginIdx1 goes beyond end of in_seq1
  1351.     if(uBeginIdx1 >= 4*in_seq1_data.size())
  1352.         return GetNcbi2naCopy(in_seq2, out_seq, uBeginIdx2, uLength2);
  1353.     // Handle case where uBeginIdx2 goes beyond end of in_seq2
  1354.     if(uBeginIdx2 >= 4*in_seq2_data.size())
  1355.         return GetNcbi2naCopy(in_seq1, out_seq, uBeginIdx1, uLength1);
  1356.     // Validate and Adjust uBeginIdx_ and uLength_
  1357.     if(((uBeginIdx1 + uLength1) > 4*in_seq1_data.size()) || uLength1 == 0)
  1358.         uLength1 = 4*in_seq1_data.size() - uBeginIdx1;
  1359.     if(((uBeginIdx2 + uLength2) > 4*in_seq2_data.size()) || uLength2 == 0)
  1360.         uLength2 = 4*in_seq2_data.size() - uBeginIdx2;
  1361.     // Resize out_seq_data to hold appended sequence
  1362.     TSeqPos uTotalLength = uLength1 + uLength2;
  1363.     if((uTotalLength % 4) == 0)
  1364.         out_seq_data.resize(uTotalLength/4);
  1365.     else
  1366.         out_seq_data.resize(uTotalLength/4 + 1);
  1367.     // Calculate bit shifts required for in_seq1
  1368.     unsigned int lShift1 = 2*(uBeginIdx1 % 4);
  1369.     unsigned int rShift1 = 8 - lShift1;
  1370.     // Calculate bit shifts required for in_seq2
  1371.     unsigned int lShift2, rShift2, uCase;
  1372.     unsigned int uVacantIdx = 2*(uLength1 % 4);
  1373.     unsigned int uStartIdx = 2*(uBeginIdx2 % 4);
  1374.     if((uVacantIdx < uStartIdx) && (uVacantIdx > 0))
  1375.         {
  1376.             uCase = 0;
  1377.             lShift2 = uStartIdx - uVacantIdx;
  1378.             rShift2 = 8 - lShift2;
  1379.         }
  1380.     else if((uVacantIdx < uStartIdx) && (uVacantIdx == 0))
  1381.         {
  1382.             uCase = 1;
  1383.             lShift2 = uStartIdx;
  1384.             rShift2 = 8 - lShift2;
  1385.         }
  1386.     else if((uVacantIdx == uStartIdx) && (uVacantIdx > 0))
  1387.         {
  1388.             uCase = 2;
  1389.             lShift2 = 0;
  1390.             rShift2 = 8;
  1391.         }
  1392.     else if((uVacantIdx == uStartIdx) && (uVacantIdx == 0))
  1393.         {
  1394.             uCase = 3;
  1395.             lShift2 = 0;
  1396.             rShift2 = 8;
  1397.         }
  1398.     else
  1399.         {
  1400.             uCase = 4;
  1401.             rShift2 = uVacantIdx - uStartIdx;
  1402.             lShift2 = 8 - rShift2;
  1403.         }
  1404.     // Determine begin and end points for iterators.
  1405.     TSeqPos uStart1 = uBeginIdx1/4;
  1406.     TSeqPos uEnd1;
  1407.     if(((uBeginIdx1 + uLength1) % 4) == 0)
  1408.         uEnd1 = (uBeginIdx1 + uLength1)/4;
  1409.     else
  1410.         uEnd1 = (uBeginIdx1 + uLength1)/4 + 1;
  1411.     TSeqPos uStart2 = uBeginIdx2/4;
  1412.     TSeqPos uEnd2;
  1413.     if(((uBeginIdx2 + uLength2) % 4) == 0)
  1414.         uEnd2 = (uBeginIdx2 + uLength2)/4;
  1415.     else
  1416.         uEnd2 = (uBeginIdx2 + uLength2)/4 + 1;
  1417.     // Get begin and end positions on in_seqs
  1418.     vector<char>::const_iterator i_in1_begin = in_seq1_data.begin() + uStart1;
  1419.     vector<char>::const_iterator i_in1_end = in_seq1_data.begin() + uEnd1 - 1;
  1420.     vector<char>::const_iterator i_in2_begin = in_seq2_data.begin() + uStart2;
  1421.     vector<char>::const_iterator i_in2_end = in_seq2_data.begin() + uEnd2;
  1422.     // Declare iterators
  1423.     vector<char>::iterator i_out = out_seq_data.begin() - 1;
  1424.     vector<char>::const_iterator i_in1;
  1425.     vector<char>::const_iterator i_in2;
  1426.     // Insert in_seq1 into out_seq
  1427.     for(i_in1 = i_in1_begin; i_in1 != i_in1_end; ++i_in1)
  1428.         (*(++i_out)) = ((*i_in1) << lShift1) | ((*(i_in1+1) & 255) >> rShift1);
  1429.     // Handle last byte for in_seq1 if necessary
  1430.     TSeqPos uEndOutByte;
  1431.     if((uLength1 % 4) == 0)
  1432.         uEndOutByte = uLength1/4 - 1;
  1433.     else
  1434.         uEndOutByte = uLength1/4;
  1435.     if(i_out != (out_seq_data.begin() + uEndOutByte))
  1436.         (*(++i_out)) = (*i_in1) << lShift1;
  1437.     // Connect in_seq1 and in_seq2
  1438.     unsigned char uMask1 = 255 << (8 - 2*(uLength1 % 4));
  1439.     unsigned char uMask2 = 255 >> (2*(uBeginIdx2 % 4));
  1440.     TSeqPos uSeq2Inc = 1;
  1441.     switch (uCase) {
  1442.     case 0: // 0 < uVacantIdx < uStartIdx
  1443.         if((i_in2_begin + 1) == i_in2_end)
  1444.             {
  1445.                 (*i_out) &= uMask1;
  1446.                 (*i_out) |= ((*i_in2_begin) & uMask2) << lShift2;
  1447.                 return uTotalLength;
  1448.             }
  1449.         else
  1450.             {
  1451.                 (*i_out) &= uMask1;
  1452.                 (*i_out) |=
  1453.                     (((*i_in2_begin) & uMask2) << lShift2) |
  1454.                     (((*(i_in2_begin+1)) & 255) >> rShift2);
  1455.             }
  1456.         break;
  1457.     case 1: // 0 == uVacantIdx < uStartIdx
  1458.         if((i_in2_begin + 1) == i_in2_end)
  1459.             {
  1460.                 (*(++i_out)) = (*i_in2_begin) << lShift2;
  1461.                 return uTotalLength;
  1462.             }
  1463.         else
  1464.             {
  1465.                 (*(++i_out)) =
  1466.                     ((*i_in2_begin) << lShift2) |
  1467.                     (((*(i_in2_begin+1)) & 255) >> rShift2);
  1468.             }
  1469.         break;
  1470.     case 2: // uVacantIdx == uStartIdx > 0
  1471.         (*i_out) &= uMask1;
  1472.         (*i_out) |= (*i_in2_begin) & uMask2;
  1473.         if((i_in2_begin + 1) == i_in2_end)
  1474.             return uTotalLength;
  1475.         break;
  1476.     case 3: // uVacantIdx == uStartIdx == 0
  1477.         (*(++i_out)) = (*i_in2_begin);
  1478.         if((i_in2_begin + 1) == i_in2_end)
  1479.             return uTotalLength;
  1480.         break;
  1481.     case 4: // uVacantIdx > uStartIdx
  1482.         if((i_in2_begin + 1) == i_in2_end)
  1483.             {
  1484.                 (*i_out) &= uMask1;
  1485.                 (*i_out) |= ((*i_in2_begin) & uMask2) >> rShift2;
  1486.                 if(++i_out != out_seq_data.end())
  1487.                     (*i_out) = (*i_in2_begin) << lShift2;
  1488.                 return uTotalLength;
  1489.             }
  1490.         else
  1491.             {
  1492.                 (*i_out) &= uMask1;
  1493.                 (*i_out) |=
  1494.                     (((*i_in2_begin) & uMask2) >> rShift2) |
  1495.                     ((*(i_in2_begin+1) & ~uMask2) << lShift2);
  1496.                 uSeq2Inc = 0;
  1497.             }
  1498.     }
  1499.     // Insert in_seq2 into out_seq
  1500.     for(i_in2 = i_in2_begin+uSeq2Inc; (i_in2 != i_in2_end) &&
  1501.             ((i_in2+1) != i_in2_end); ++i_in2) {
  1502.         (*(++i_out)) = ((*i_in2) << lShift2) | ((*(i_in2+1) & 255) >> rShift2);
  1503.     }
  1504.     // Handle last byte for in_seq2, if there is one
  1505.     if((++i_out != out_seq_data.end()) && (i_in2 != i_in2_end))
  1506.         (*i_out) = (*i_in2) << lShift2;
  1507.     return uLength1 + uLength2;
  1508. }
  1509. TSeqPos CSeqportUtil_implementation::AppendNcbi4na
  1510. (CSeq_data*        out_seq,
  1511.  const CSeq_data&  in_seq1,
  1512.  TSeqPos           uBeginIdx1,
  1513.  TSeqPos           uLength1,
  1514.  const CSeq_data&  in_seq2,
  1515.  TSeqPos           uBeginIdx2,
  1516.  TSeqPos           uLength2)
  1517.     const
  1518. {
  1519.     // Get references to in_seqs
  1520.     const vector<char>& in_seq1_data = in_seq1.GetNcbi4na().Get();
  1521.     const vector<char>& in_seq2_data = in_seq2.GetNcbi4na().Get();
  1522.     // Get a reference to out_seq
  1523.     out_seq->Reset();
  1524.     vector<char>& out_seq_data = out_seq->SetNcbi4na().Set();
  1525.     // Handle both uBeginidx go beyond end of in_seq
  1526.     if((uBeginIdx1 >= 4*in_seq1_data.size()) &&
  1527.        (uBeginIdx2 >= 4*in_seq2_data.size()))
  1528.         return 0;
  1529.     // Handle case where uBeginIdx1 goes beyond end of in_seq1
  1530.     if(uBeginIdx1 >= 4*in_seq1_data.size())
  1531.         return GetNcbi4naCopy(in_seq2, out_seq, uBeginIdx2, uLength2);
  1532.     // Handle case where uBeginIdx2 goes beyond end of in_seq2
  1533.     if(uBeginIdx2 >= 4*in_seq2_data.size())
  1534.         return GetNcbi4naCopy(in_seq1, out_seq, uBeginIdx1, uLength1);
  1535.     // Validate and Adjust uBeginIdx_ and uLength_
  1536.     if(((uBeginIdx1 + uLength1) > 2*in_seq1_data.size()) || uLength1 == 0)
  1537.         uLength1 = 2*in_seq1_data.size() - uBeginIdx1;
  1538.     if(((uBeginIdx2 + uLength2) > 2*in_seq2_data.size()) || uLength2 == 0)
  1539.         uLength2 = 2*in_seq2_data.size() - uBeginIdx2;
  1540.     // Resize out_seq_data to hold appended sequence
  1541.     TSeqPos uTotalLength = uLength1 + uLength2;
  1542.     if((uTotalLength % 2) == 0)
  1543.         out_seq_data.resize(uTotalLength/2);
  1544.     else
  1545.         out_seq_data.resize(uTotalLength/2 + 1);
  1546.     // Calculate bit shifts required for in_seq1
  1547.     unsigned int lShift1 = 4*(uBeginIdx1 % 2);
  1548.     unsigned int rShift1 = 8 - lShift1;
  1549.     // Calculate bit shifts required for in_seq2
  1550.     unsigned int lShift2, rShift2, uCase;
  1551.     unsigned int uVacantIdx = 4*(uLength1 % 2);
  1552.     unsigned int uStartIdx = 4*(uBeginIdx2 % 2);
  1553.     if((uVacantIdx < uStartIdx))
  1554.         {
  1555.             uCase = 1;
  1556.             lShift2 = uStartIdx;
  1557.             rShift2 = 8 - lShift2;
  1558.         }
  1559.     else if((uVacantIdx == uStartIdx) && (uVacantIdx > 0))
  1560.         {
  1561.             uCase = 2;
  1562.             lShift2 = 0;
  1563.             rShift2 = 8;
  1564.         }
  1565.     else if((uVacantIdx == uStartIdx) && (uVacantIdx == 0))
  1566.         {
  1567.             uCase = 3;
  1568.             lShift2 = 0;
  1569.             rShift2 = 8;
  1570.         }
  1571.     else
  1572.         {
  1573.             uCase = 4;
  1574.             rShift2 = uVacantIdx - uStartIdx;
  1575.             lShift2 = 8 - rShift2;
  1576.         }
  1577.     // Determine begin and end points for iterators.
  1578.     TSeqPos uStart1 = uBeginIdx1/2;
  1579.     TSeqPos uEnd1;
  1580.     if(((uBeginIdx1 + uLength1) % 2) == 0)
  1581.         uEnd1 = (uBeginIdx1 + uLength1)/2;
  1582.     else
  1583.         uEnd1 = (uBeginIdx1 + uLength1)/2 + 1;
  1584.     TSeqPos uStart2 = uBeginIdx2/2;
  1585.     TSeqPos uEnd2;
  1586.     if(((uBeginIdx2 + uLength2) % 2) == 0)
  1587.         uEnd2 = (uBeginIdx2 + uLength2)/2;
  1588.     else
  1589.         uEnd2 = (uBeginIdx2 + uLength2)/2 + 1;
  1590.     // Get begin and end positions on in_seqs
  1591.     vector<char>::const_iterator i_in1_begin = in_seq1_data.begin() + uStart1;
  1592.     vector<char>::const_iterator i_in1_end = in_seq1_data.begin() + uEnd1 - 1;
  1593.     vector<char>::const_iterator i_in2_begin = in_seq2_data.begin() + uStart2;
  1594.     vector<char>::const_iterator i_in2_end = in_seq2_data.begin() + uEnd2;
  1595.     // Declare iterators
  1596.     vector<char>::iterator i_out = out_seq_data.begin() - 1;
  1597.     vector<char>::const_iterator i_in1;
  1598.     vector<char>::const_iterator i_in2;
  1599.     // Insert in_seq1 into out_seq
  1600.     for(i_in1 = i_in1_begin; i_in1 != i_in1_end; ++i_in1)
  1601.         (*(++i_out)) = ((*i_in1) << lShift1) | ((*(i_in1+1) & 255) >> rShift1);
  1602.     // Handle last byte for in_seq1 if necessary
  1603.     TSeqPos uEndOutByte;
  1604.     if((uLength1 % 2) == 0)
  1605.         uEndOutByte = uLength1/2 - 1;
  1606.     else
  1607.         uEndOutByte = uLength1/2;
  1608.     if(i_out != (out_seq_data.begin() + uEndOutByte))
  1609.         (*(++i_out)) = (*i_in1) << lShift1;
  1610.     // Connect in_seq1 and in_seq2
  1611.     unsigned char uMask1 = 255 << (8 - 4*(uLength1 % 2));
  1612.     unsigned char uMask2 = 255 >> (4*(uBeginIdx2 % 2));
  1613.     TSeqPos uSeq2Inc = 1;
  1614.     switch (uCase) {
  1615.     case 1: // 0 == uVacantIdx < uStartIdx
  1616.         if((i_in2_begin+1) == i_in2_end)
  1617.             {
  1618.                 (*(++i_out)) = (*i_in2_begin) << lShift2;
  1619.                 return uTotalLength;
  1620.             }
  1621.         else
  1622.             {
  1623.                 (*(++i_out)) =
  1624.                     ((*i_in2_begin) << lShift2) |
  1625.                     (((*(i_in2_begin+1)) & 255) >> rShift2);
  1626.             }
  1627.         break;
  1628.     case 2: // uVacantIdx == uStartIdx > 0
  1629.         (*i_out) &= uMask1;
  1630.         (*i_out) |= (*i_in2_begin) & uMask2;
  1631.         if((i_in2_begin+1) == i_in2_end)
  1632.             return uTotalLength;
  1633.         break;
  1634.     case 3: // uVacantIdx == uStartIdx == 0
  1635.         (*(++i_out)) = (*i_in2_begin);
  1636.         if((i_in2_begin+1) == i_in2_end)
  1637.             return uTotalLength;
  1638.         break;
  1639.     case 4: // uVacantIdx > uStartIdx
  1640.         if((i_in2_begin+1) == i_in2_end)
  1641.             {
  1642.                 (*i_out) &= uMask1;
  1643.                 (*i_out) |= ((*i_in2_begin) & uMask2) >> rShift2;
  1644.                 if(++i_out != out_seq_data.end())
  1645.                     (*i_out) = (*i_in2_begin) << lShift2;
  1646.                 return uTotalLength;
  1647.             }
  1648.         else
  1649.             {
  1650.                 (*i_out) &= uMask1;
  1651.                 (*i_out) |=
  1652.                     (((*i_in2_begin) & uMask2) >> rShift2) |
  1653.                     ((*(i_in2_begin+1) & ~uMask2) << lShift2);
  1654.                 uSeq2Inc = 0;
  1655.             }
  1656.     }
  1657.     // Insert in_seq2 into out_seq
  1658.     for(i_in2 = i_in2_begin+uSeq2Inc; (i_in2 != i_in2_end) &&
  1659.             ((i_in2+1) != i_in2_end); ++i_in2) {
  1660.         (*(++i_out)) =
  1661.             ((*i_in2) << lShift2) | ((*(i_in2+1) & 255) >> rShift2);
  1662.     }
  1663.     // Handle last byte for in_seq2, if there is one
  1664.     if((++i_out != out_seq_data.end()) && (i_in2 != i_in2_end))
  1665.         (*i_out) = (*i_in2) << lShift2;
  1666.     return uTotalLength;
  1667. }
  1668. TSeqPos CSeqportUtil_implementation::AppendNcbieaa
  1669. (CSeq_data*        out_seq,
  1670.  const CSeq_data&  in_seq1,
  1671.  TSeqPos           uBeginIdx1,
  1672.  TSeqPos           uLength1,
  1673.  const CSeq_data&  in_seq2,
  1674.  TSeqPos           uBeginIdx2,
  1675.  TSeqPos           uLength2)
  1676.     const
  1677. {
  1678.     // Get references to in_seqs
  1679.     const string& in_seq1_data = in_seq1.GetNcbieaa().Get();
  1680.     const string& in_seq2_data = in_seq2.GetNcbieaa().Get();
  1681.     // Get a reference to out_seq
  1682.     out_seq->Reset();
  1683.     string& out_seq_data = out_seq->SetNcbieaa().Set();
  1684.     // Validate and Adjust uBeginIdx_ and uLength_
  1685.     if((uBeginIdx1 >= in_seq1_data.size()) &&
  1686.        (uBeginIdx2 >= in_seq2_data.size()))
  1687.         {
  1688.             return 0;
  1689.         }
  1690.     if(((uBeginIdx1 + uLength1) > in_seq1_data.size()) || uLength1 == 0)
  1691.         uLength1 = in_seq1_data.size() - uBeginIdx1;
  1692.     if(((uBeginIdx2 + uLength2) > in_seq2_data.size()) || uLength2 == 0)
  1693.         uLength2 = in_seq2_data.size() - uBeginIdx2;
  1694.     // Append the strings
  1695.     out_seq_data.append(in_seq1_data.substr(uBeginIdx1,uLength1));
  1696.     out_seq_data.append(in_seq2_data.substr(uBeginIdx2,uLength2));
  1697.     return uLength1 + uLength2;
  1698. }
  1699. TSeqPos CSeqportUtil_implementation::AppendNcbistdaa
  1700. (CSeq_data*          out_seq,
  1701.  const CSeq_data&    in_seq1,
  1702.  TSeqPos             uBeginIdx1,
  1703.  TSeqPos             uLength1,
  1704.  const CSeq_data&    in_seq2,
  1705.  TSeqPos             uBeginIdx2,
  1706.  TSeqPos             uLength2)
  1707.     const
  1708. {
  1709.     // Get references to in_seqs
  1710.     const vector<char>& in_seq1_data = in_seq1.GetNcbistdaa().Get();
  1711.     const vector<char>& in_seq2_data = in_seq2.GetNcbistdaa().Get();
  1712.     // Get a reference to out_seq
  1713.     out_seq->Reset();
  1714.     vector<char>& out_seq_data = out_seq->SetNcbistdaa().Set();
  1715.     // Validate and Adjust uBeginIdx_ and uLength_
  1716.     if((uBeginIdx1 >= in_seq1_data.size()) &&
  1717.        (uBeginIdx2 >= in_seq2_data.size()))
  1718.         return 0;
  1719.     if(((uBeginIdx1 + uLength1) > in_seq1_data.size()) || uLength1 == 0)
  1720.         uLength1 = in_seq1_data.size() - uBeginIdx1;
  1721.     if(((uBeginIdx2 + uLength2) > in_seq2_data.size()) || uLength2 == 0)
  1722.         uLength2 = in_seq2_data.size() - uBeginIdx2;
  1723.     // Get begin and end positions on in_seqs
  1724.     vector<char>::const_iterator i_in1_begin =
  1725.         in_seq1_data.begin() + uBeginIdx1;
  1726.     vector<char>::const_iterator i_in1_end = i_in1_begin + uLength1;
  1727.     vector<char>::const_iterator i_in2_begin =
  1728.         in_seq2_data.begin() + uBeginIdx2;
  1729.     vector<char>::const_iterator i_in2_end = i_in2_begin + uLength2;
  1730.     // Insert the in_seqs into out_seq
  1731.     out_seq_data.insert(out_seq_data.end(), i_in1_begin, i_in1_end);
  1732.     out_seq_data.insert(out_seq_data.end(), i_in2_begin, i_in2_end);
  1733.     return uLength1 + uLength2;
  1734. }
  1735. TSeqPos CSeqportUtil_implementation::AppendIupacaa
  1736. (CSeq_data*          out_seq,
  1737.  const CSeq_data&    in_seq1,
  1738.  TSeqPos             uBeginIdx1,
  1739.  TSeqPos             uLength1,
  1740.  const CSeq_data&    in_seq2,
  1741.  TSeqPos             uBeginIdx2,
  1742.  TSeqPos             uLength2)
  1743.     const
  1744. {
  1745.     // Get references to in_seqs
  1746.     const string& in_seq1_data = in_seq1.GetIupacaa().Get();
  1747.     const string& in_seq2_data = in_seq2.GetIupacaa().Get();
  1748.     // Get a reference to out_seq
  1749.     out_seq->Reset();
  1750.     string& out_seq_data = out_seq->SetIupacaa().Set();
  1751.     // Validate and Adjust uBeginIdx_ and uLength_
  1752.     if((uBeginIdx1 >= in_seq1_data.size()) &&
  1753.        (uBeginIdx2 >= in_seq2_data.size()))
  1754.         {
  1755.             return 0;
  1756.         }
  1757.     if(((uBeginIdx1 + uLength1) > in_seq1_data.size()) || uLength1 == 0)
  1758.         uLength1 = in_seq1_data.size() - uBeginIdx1;
  1759.     if(((uBeginIdx2 + uLength2) > in_seq2_data.size()) || uLength2 == 0)
  1760.         uLength2 = in_seq2_data.size() - uBeginIdx2;
  1761.     // Append the strings
  1762.     out_seq_data.append(in_seq1_data.substr(uBeginIdx1,uLength1));
  1763.     out_seq_data.append(in_seq2_data.substr(uBeginIdx2,uLength2));
  1764.     return uLength1 + uLength2;
  1765. }
  1766. // Returns the 3 letter Iupacaa3 code for an ncbistdaa index
  1767. const string& CSeqportUtil_implementation::GetIupacaa3
  1768. (TIndex ncbistdaa)
  1769. {
  1770.     return GetCodeOrName(eSeq_code_type_iupacaa3, ncbistdaa, true);
  1771. }
  1772. // Returns true if code type is available
  1773. bool CSeqportUtil_implementation::IsCodeAvailable
  1774. (CSeq_data::E_Choice code_type)
  1775. {
  1776.     if (code_type == CSeq_data::e_not_set) {
  1777.         return false;
  1778.     } else {
  1779.         return IsCodeAvailable(EChoiceToESeq(code_type));
  1780.     }
  1781. }
  1782. // Return true if code type is available
  1783. bool CSeqportUtil_implementation::IsCodeAvailable (ESeq_code_type code_type)
  1784. {
  1785.     typedef list<CRef<CSeq_code_table> >      Ttables;
  1786.     
  1787.     // Iterate through Seq-code-set looking for code type
  1788.     ITERATE (Ttables, i_ct, m_SeqCodeSet->GetCodes()) {
  1789.         if((*i_ct)->GetCode() == code_type) {
  1790.             return true;  
  1791.         }
  1792.     }
  1793.     return false;
  1794. }
  1795. // Return a pair containing the first index (start-at) and last index 
  1796. // for code_type. 
  1797. CSeqportUtil::TPair  CSeqportUtil_implementation::GetCodeIndexFromTo
  1798. (CSeq_data::E_Choice code_type)
  1799. {
  1800.     return GetCodeIndexFromTo(EChoiceToESeq(code_type));
  1801. }
  1802. // Return a pair containing the first index (start-at) and last index 
  1803. // for code_type. 
  1804. CSeqportUtil::TPair CSeqportUtil_implementation::GetCodeIndexFromTo
  1805. (ESeq_code_type code_type)
  1806. {
  1807.     typedef list<CRef<CSeq_code_table> >      Ttables;
  1808.     
  1809.     // Iterate through Seq-code-set looking for code type
  1810.     TPair p;
  1811.     ITERATE (Ttables, i_ct, m_SeqCodeSet->GetCodes()) {
  1812.         if((*i_ct)->GetCode() == code_type) {
  1813.             if ( (*i_ct)->IsSetStart_at() ) {
  1814.                 p.first = static_cast<TIndex>((*i_ct)->GetStart_at());
  1815.             } else {
  1816.                 p.first = 0;
  1817.             }
  1818.             p.second = p.first + static_cast<TIndex>((*i_ct)->GetNum() - 1);
  1819.             return p;  
  1820.         }
  1821.     }
  1822.     throw CSeqportUtil::CBadType("GetCodeIndexFromTo");
  1823. }
  1824. // Converts CSeq_data::E_Choice type to ESeq_code_type
  1825. // and calls overloaded GetCodeOrName()
  1826. const string& CSeqportUtil_implementation::GetCodeOrName
  1827. (CSeq_data::E_Choice code_type, 
  1828.  TIndex              idx,
  1829.  bool                get_code) 
  1830.     return GetCodeOrName(EChoiceToESeq(code_type), idx, get_code);   
  1831. }
  1832. // Returns the code (symbol) of type code_type for index idx. 
  1833. const string& CSeqportUtil_implementation::GetCodeOrName
  1834. (ESeq_code_type code_type, 
  1835.  TIndex         idx,
  1836.  bool           get_code) 
  1837. {
  1838.     typedef list<CRef<CSeq_code_table> >      Ttables;
  1839.     typedef list<CRef<CSeq_code_table::C_E> > Tcodes;
  1840.     if ( !m_IndexString[get_code][code_type-1].size() ) {
  1841.         throw CSeqportUtil::CBadType("GetCodeOrName");
  1842.     }
  1843.     idx -= m_StartAt[code_type-1];
  1844.     if (idx >= m_IndexString[get_code][code_type-1].size()) {
  1845.         throw CSeqportUtil::CBadIndex(idx, "GetCodeOrName");
  1846.     }
  1847.     return m_IndexString[get_code][code_type-1][idx];
  1848.        
  1849. }
  1850. // Converts CSeq_data::E_Choice type to ESeq_code_type and call
  1851. // overloaded GetIndex();
  1852. CSeqportUtil::TIndex CSeqportUtil_implementation::GetIndex
  1853. (CSeq_data::E_Choice code_type, 
  1854.  const string&       code)
  1855. {
  1856.     return GetIndex(EChoiceToESeq(code_type), code);
  1857. }
  1858. // Get the index for code of type code_type. If not found, return -1
  1859. CSeqportUtil::TIndex CSeqportUtil_implementation::GetIndex
  1860. (ESeq_code_type code_type, 
  1861.  const string&  code)
  1862. {
  1863.     typedef list<CRef<CSeq_code_table> >      Ttables;
  1864.     typedef list<CRef<CSeq_code_table::C_E> > Tcodes;
  1865.     
  1866.     // Iterator to a map mapping a string code to a code index
  1867.     map<string, TIndex>::const_iterator pos;
  1868.     
  1869.     if ( !m_StringIndex[code_type-1].size() ) {
  1870.         throw CSeqportUtil::CBadType("GetIndex");
  1871.     }
  1872.     pos = m_StringIndex[code_type-1].find(code);
  1873.     if (pos != m_StringIndex[code_type-1].end()) {
  1874.         return pos->second;
  1875.     } else {
  1876.         throw CSeqportUtil::CBadSymbol(code, "GetIndex");
  1877.     }
  1878.     
  1879. }
  1880. // Gets complement of index for code type. Returns -1 if code
  1881. // type does not exist
  1882. CSeqportUtil::TIndex CSeqportUtil_implementation::GetIndexComplement
  1883. (CSeq_data::E_Choice code_type,
  1884.  TIndex              idx)
  1885. {
  1886.     return GetIndexComplement(EChoiceToESeq(code_type), idx);
  1887. }
  1888. // Returns the complement of the index for code_type. If code_type
  1889. // does not exist, or complements for code_type do not exist,
  1890. // returns -1
  1891. CSeqportUtil::TIndex CSeqportUtil_implementation::GetIndexComplement
  1892. (ESeq_code_type code_type,
  1893.  TIndex         idx)
  1894. {
  1895.   
  1896.     // Check that code is available
  1897.     if (!m_IndexComplement[code_type-1].size()) {
  1898.         throw CSeqportUtil::CBadType("GetIndexComplement");
  1899.     }
  1900.     
  1901.     // Check that idx is in range of code indices
  1902.     idx -= m_StartAt[code_type-1];
  1903.     if ( idx >= m_IndexComplement[code_type-1].size() ) {        
  1904.         throw CSeqportUtil::CBadIndex(idx, "GetIndexComplement");
  1905.     }
  1906.     
  1907.     // Return the index of the complement   
  1908.     return m_IndexComplement[code_type-1][idx];
  1909.  }
  1910. CSeqportUtil::TIndex CSeqportUtil_implementation::GetMapToIndex
  1911. (CSeq_data::E_Choice from_type,
  1912.  CSeq_data::E_Choice to_type,
  1913.  TIndex              from_idx)
  1914. {
  1915.     return GetMapToIndex(EChoiceToESeq(from_type), 
  1916.                          EChoiceToESeq(to_type),
  1917.                          from_idx);
  1918. }
  1919. CSeqportUtil::TIndex CSeqportUtil_implementation::GetMapToIndex
  1920. (ESeq_code_type from_type,
  1921.  ESeq_code_type to_type,
  1922.  TIndex            from_idx)
  1923. {
  1924.     CMap_table* Map = 0;
  1925.     
  1926.     if (from_type == eSeq_code_type_iupacna) {
  1927.         if (to_type == eSeq_code_type_ncbi2na) {
  1928.             Map = m_IupacnaNcbi2na.GetPointer();
  1929.         } else if (to_type == eSeq_code_type_ncbi4na) {
  1930.             Map = m_IupacnaNcbi4na.GetPointer();
  1931.         }
  1932.     } else if (from_type == eSeq_code_type_ncbi4na) {
  1933.         if (to_type == eSeq_code_type_iupacna) {
  1934.             Map = m_Ncbi4naIupacna.GetPointer();
  1935.         } else if (to_type == eSeq_code_type_ncbi2na) {
  1936.             Map = m_Ncbi4naNcbi2na.GetPointer();
  1937.         }
  1938.     } else if (from_type == eSeq_code_type_ncbi2na) {
  1939.         if (to_type == eSeq_code_type_iupacna) {
  1940.             Map = m_Ncbi2naIupacna.GetPointer();
  1941.         } else if (to_type == eSeq_code_type_ncbi4na) {
  1942.             Map = m_Ncbi2naNcbi4na.GetPointer();
  1943.         }
  1944.     } else if (from_type == eSeq_code_type_iupacaa) {
  1945.         if (to_type == eSeq_code_type_ncbieaa) {
  1946.             Map = m_IupacaaNcbieaa.GetPointer();
  1947.         } else if (to_type == eSeq_code_type_ncbistdaa) {
  1948.             Map = m_IupacaaNcbistdaa.GetPointer();
  1949.         }
  1950.     } else if (from_type == eSeq_code_type_ncbieaa) {
  1951.         if (to_type == eSeq_code_type_iupacaa) {
  1952.             Map = m_NcbieaaIupacaa.GetPointer();
  1953.         } else if (to_type == eSeq_code_type_ncbistdaa) {
  1954.             Map = m_NcbieaaNcbistdaa.GetPointer();
  1955.         }
  1956.     } else if (from_type == eSeq_code_type_ncbistdaa) {
  1957.         if (to_type == eSeq_code_type_iupacaa) {
  1958.             Map = m_NcbistdaaIupacaa.GetPointer();
  1959.         } else if (to_type == eSeq_code_type_ncbieaa) {
  1960.             Map = m_NcbistdaaNcbieaa.GetPointer();
  1961.         }
  1962.     }
  1963.     
  1964.     // Check that requested map is available
  1965.     if (!Map) {
  1966.         throw CSeqportUtil::CBadType("GetMapToIndex");
  1967.     }
  1968.     
  1969.     // Check that from_idx is within range of from_type
  1970.     if (from_idx - (*Map).m_StartAt >= (TIndex)(*Map).m_Size) {
  1971.         throw CSeqportUtil::CBadIndex(from_idx - (*Map).m_StartAt,
  1972.             "GetMapToIndex");
  1973.     }
  1974.     
  1975.     // Return map value
  1976.     return (*Map).m_Table[from_idx];
  1977.     
  1978. }
  1979. void CSeqportUtil_implementation::x_GetSeqFromSeqData
  1980. (const CSeq_data& data, 
  1981.  const string** str,
  1982.  const vector<char>** vec)
  1983.     const
  1984. {
  1985.     *str = 0;
  1986.     *vec = 0;
  1987.     switch ( data.Which() ) {
  1988.     case CSeq_data::e_Iupacna:
  1989.         *str = &(data.GetIupacna().Get());
  1990.         break;
  1991.     case CSeq_data::e_Ncbi2na:
  1992.         *vec = &(data.GetNcbi2na().Get());
  1993.         break;
  1994.     case CSeq_data::e_Ncbi4na:
  1995.         *vec = &(data.GetNcbi4na().Get());
  1996.         break;
  1997.     case CSeq_data::e_Ncbi8na:
  1998.         *vec = &(data.GetNcbi8na().Get());
  1999.         break;
  2000.     case CSeq_data::e_Iupacaa:
  2001.         *str = &(data.GetIupacaa().Get());
  2002.         break;
  2003.     case CSeq_data::e_Ncbi8aa:
  2004.         *vec = &(data.GetNcbi8aa().Get());
  2005.         break;
  2006.     case CSeq_data::e_Ncbieaa:
  2007.         *str = &(data.GetNcbieaa().Get());
  2008.         break;
  2009.     case CSeq_data::e_Ncbistdaa:
  2010.         *vec = &(data.GetNcbistdaa().Get());
  2011.         break;
  2012.     } // end of switch statemen
  2013. }
  2014. // same as above, but takes a non-const CSeq_data object.
  2015. void CSeqportUtil_implementation::x_GetSeqFromSeqData
  2016. (CSeq_data& data, 
  2017.  string** str,
  2018.  vector<char>** vec)
  2019.     const
  2020. {
  2021.     *str = 0;
  2022.     *vec = 0;
  2023.     switch ( data.Which() ) {
  2024.     case CSeq_data::e_Iupacna:
  2025.         *str = &(data.SetIupacna().Set());
  2026.         break;
  2027.     case CSeq_data::e_Ncbi2na:
  2028.         *vec = &(data.SetNcbi2na().Set());
  2029.         break;
  2030.     case CSeq_data::e_Ncbi4na:
  2031.         *vec = &(data.SetNcbi4na().Set());
  2032.         break;
  2033.     case CSeq_data::e_Ncbi8na:
  2034.         *vec = &(data.SetNcbi8na().Set());
  2035.         break;
  2036.     case CSeq_data::e_Iupacaa:
  2037.         *str = &(data.SetIupacaa().Set());
  2038.         break;
  2039.     case CSeq_data::e_Ncbi8aa:
  2040.         *vec = &(data.SetNcbi8aa().Set());
  2041.         break;
  2042.     case CSeq_data::e_Ncbieaa:
  2043.         *str = &(data.SetNcbieaa().Set());
  2044.         break;
  2045.     case CSeq_data::e_Ncbistdaa:
  2046.         *vec = &(data.SetNcbistdaa().Set());
  2047.         break;
  2048.     } // end of switch statemen
  2049. }
  2050. /////////////////////////////////////////////////////////////////////////////
  2051. //  CSeqportUtil_implementation::sm_StrAsnData  --  some very long and ugly string
  2052. //
  2053. // local copy of seqcode.prt sequence alphabet and conversion table ASN.1
  2054. const char* CSeqportUtil_implementation::sm_StrAsnData[] =
  2055. {
  2056.     "-- This is the set of NCBI sequence code tablesn",
  2057.     "-- J.Ostell  10/18/91n",
  2058.     "--n",
  2059.     "n",
  2060.     "Seq-code-set ::= {n",
  2061.     " codes {                              -- codesn",
  2062.     " {                                -- IUPACnan",
  2063.     " code iupacna ,n",
  2064.     " num 25 ,                     -- continuous 65-89n",
  2065.     " one-letter TRUE ,            -- all one letter codesn",
  2066.     " start-at 65 ,                -- starts with A, ASCII 65n",
  2067.     " table {n",
  2068.     " { symbol "A", name "Adenine" },n",
  2069.     " { symbol "B" , name "G or T or C" },n",
  2070.     " { symbol "C", name "Cytosine" },n",
  2071.     " { symbol "D", name "G or A or T" },n",
  2072.     " { symbol "", name "" },n",
  2073.     " { symbol "", name "" },n",
  2074.     " { symbol "G", name "Guanine" },n",
  2075.     " { symbol "H", name "A or C or T" } ,n",
  2076.     " { symbol "", name "" },n",
  2077.     " { symbol "", name "" },n",
  2078.     " { symbol "K", name "G or T" },n",
  2079.     " { symbol "", name ""},n",
  2080.     " { symbol "M", name "A or C" },n",
  2081.     " { symbol "N", name "A or G or C or T" } ,n",
  2082.     " { symbol "", name "" },n",
  2083.     " { symbol "", name "" },n",
  2084.     " { symbol "", name ""},n",
  2085.     " { symbol "R", name "G or A"},n",
  2086.     " { symbol "S", name "G or C"},n",
  2087.     " { symbol "T", name "Thymine"},n",
  2088.     " { symbol "", name ""},n",
  2089.     " { symbol "V", name "G or C or A"},n",
  2090.     " { symbol "W", name "A or T" },n",
  2091.     " { symbol "", name ""},n",
  2092.     " { symbol "Y", name "T or C"}n",
  2093.     " } ,                           -- end of tablen",
  2094.     " comps {                      -- complementsn",
  2095.     " 84,n",
  2096.     " 86,n",
  2097.     " 71,n",
  2098.     " 72,n",
  2099.     " 69,n",
  2100.     " 70,n",
  2101.     " 67,n",
  2102.     " 68,n",
  2103.     " 73,n",
  2104.     " 74,n",
  2105.     " 77,n",
  2106.     " 76,n",
  2107.     " 75,n",
  2108.     " 78,n",
  2109.     " 79,n",
  2110.     " 80,n",
  2111.     " 81,n",
  2112.     " 89,n",
  2113.     " 83,n",
  2114.     " 65,n",
  2115.     " 85,n",
  2116.     " 66,n",
  2117.     " 87,n",
  2118.     " 88,n",
  2119.     " 82n",
  2120.     " }n",
  2121.     " },n",
  2122.     " {                                -- IUPACaan",
  2123.     " code iupacaa ,n",
  2124.     " num 26 ,                     -- continuous 65-90n",
  2125.     " one-letter TRUE ,            -- all one letter codesn",
  2126.     " start-at 65 ,                -- starts with A, ASCII 65n",
  2127.     " table {n",
  2128.     " { symbol "A", name "Alanine" },n",
  2129.     " { symbol "B" , name "Asp or Asn" },n",
  2130.     " { symbol "C", name "Cysteine" },n",
  2131.     " { symbol "D", name "Aspartic Acid" },n",
  2132.     " { symbol "E", name "Glutamic Acid" },n",
  2133.     " { symbol "F", name "Phenylalanine" },n",
  2134.     " { symbol "G", name "Glycine" },n",
  2135.     " { symbol "H", name "Histidine" } ,n",
  2136.     " { symbol "I", name "Isoleucine" },n",
  2137.     " { symbol "", name "" },n",
  2138.     " { symbol "K", name "Lysine" },n",
  2139.     " { symbol "L", name "Leucine" },n",
  2140.     " { symbol "M", name "Methionine" },n",
  2141.     " { symbol "N", name "Asparagine" } ,n",
  2142.     " { symbol "", name "" },n",
  2143.     " { symbol "P", name "Proline" },n",
  2144.     " { symbol "Q", name "Glutamine"},n",
  2145.     " { symbol "R", name "Arginine"},n",
  2146.     " { symbol "S", name "Serine"},n",
  2147.     " { symbol "T", name "Threonine"},n",
  2148.     " { symbol "U", name "Selenocysteine"}, -- was emptyn"
  2149.     " { symbol "V", name "Valine"},n",
  2150.     " { symbol "W", name "Tryptophan" },n",
  2151.     " { symbol "X", name "Undetermined or atypical"},n",
  2152.     " { symbol "Y", name "Tyrosine"},n",
  2153.     " { symbol "Z", name "Glu or Gln" }n",
  2154.     " }                            -- end of table   n",
  2155.     " },n",
  2156.     " {                                -- IUPACeaan",
  2157.     " code ncbieaa ,n",
  2158.     " num 49 ,                     -- continuous 42-90n",
  2159.     " one-letter TRUE ,            -- all one letter codesn",
  2160.     " start-at 42 ,                -- starts with *, ASCII 42n",
  2161.     " table {n",
  2162.     " { symbol "*", name "Termination" } ,n",
  2163.     " { symbol "", name "" } ,n",
  2164.     " { symbol "", name "" } ,n",
  2165.     " { symbol "-", name "Gap" } ,n",
  2166.     " { symbol "", name "" } ,n",
  2167.     " { symbol "", name "" } ,n",
  2168.     " { symbol "", name "" } ,n",
  2169.     " { symbol "", name "" } ,n",
  2170.     " { symbol "", name "" } ,n",
  2171.     " { symbol "", name "" } ,n",
  2172.     " { symbol "", name "" } ,n",
  2173.     " { symbol "", name "" } ,n",
  2174.     " { symbol "", name "" } ,n",
  2175.     " { symbol "", name "" } ,n",
  2176.     " { symbol "", name "" } ,n",
  2177.     " { symbol "", name "" } ,n",
  2178.     " { symbol "", name "" } ,n",
  2179.     " { symbol "", name "" } ,n",
  2180.     " { symbol "", name "" } ,n",
  2181.     " { symbol "", name "" } ,n",
  2182.     " { symbol "", name "" } ,n",
  2183.     " { symbol "", name "" } ,n",
  2184.     " { symbol "", name "" } ,n",
  2185.     " { symbol "A", name "Alanine" },n",
  2186.     " { symbol "B" , name "Asp or Asn" },n",
  2187.     " { symbol "C", name "Cysteine" },n",
  2188.     " { symbol "D", name "Aspartic Acid" },n",
  2189.     " { symbol "E", name "Glutamic Acid" },n",
  2190.     " { symbol "F", name "Phenylalanine" },n",
  2191.     " { symbol "G", name "Glycine" },n",
  2192.     " { symbol "H", name "Histidine" } ,n",
  2193.     " { symbol "I", name "Isoleucine" },n",
  2194.     " { symbol "", name "" },n",
  2195.     " { symbol "K", name "Lysine" },n",
  2196.     " { symbol "L", name "Leucine" },n",
  2197.     " { symbol "M", name "Methionine" },n",
  2198.     " { symbol "N", name "Asparagine" } ,n",
  2199.     " { symbol "", name "" },n",
  2200.     " { symbol "P", name "Proline" },n",
  2201.     " { symbol "Q", name "Glutamine"},n",
  2202.     " { symbol "R", name "Arginine"},n",
  2203.     " { symbol "S", name "Serine"},n",
  2204.     " { symbol "T", name "Threonine"},n",
  2205.     " { symbol "U", name "Selenocysteine"},n",
  2206.     " { symbol "V", name "Valine"},n",
  2207.     " { symbol "W", name "Tryptophan" },n",
  2208.     " { symbol "X", name "Undetermined or atypical"},n",
  2209.     " { symbol "Y", name "Tyrosine"},n",
  2210.     " { symbol "Z", name "Glu or Gln" }n",
  2211.     " }                            -- end of tablen",
  2212.     " },n",
  2213.     " {                                -- IUPACaa3n",
  2214.     " code iupacaa3 ,n",
  2215.     " num 26 ,                     -- continuous 0-25n",
  2216.     " one-letter FALSE ,            -- all 3 letter codesn",
  2217.     " table {n",
  2218.     " { symbol "---", name "Gap" } ,n",
  2219.     " { symbol "Ala", name "Alanine" },n",
  2220.     " { symbol "Asx" , name "Asp or Asn" },n",
  2221.     " { symbol "Cys", name "Cysteine" },n",
  2222.     " { symbol "Asp", name "Aspartic Acid" },n",
  2223.     " { symbol "Glu", name "Glutamic Acid" },n",
  2224.     " { symbol "Phe", name "Phenylalanine" },n",
  2225.     " { symbol "Gly", name "Glycine" },n",
  2226.     " { symbol "His", name "Histidine" } ,n",
  2227.     " { symbol "Ile", name "Isoleucine" },n",
  2228.     " { symbol "Lys", name "Lysine" },n",
  2229.     " { symbol "Leu", name "Leucine" },n",
  2230.     " { symbol "Met", name "Methionine" },n",
  2231.     " { symbol "Asn", name "Asparagine" } ,n",
  2232.     " { symbol "Pro", name "Proline" },n",
  2233.     " { symbol "Gln", name "Glutamine"},n",
  2234.     " { symbol "Arg", name "Arginine"},n",
  2235.     " { symbol "Ser", name "Serine"},n",
  2236.     " { symbol "Thr", name "Threonine"},n",
  2237.     " { symbol "Val", name "Valine"},n",
  2238.     " { symbol "Trp", name "Tryptophan" },n",
  2239.     " { symbol "Xxx", name "Undetermined or atypical"},n",
  2240.     " { symbol "Tyr", name "Tyrosine"},n",
  2241.     " { symbol "Glx", name "Glu or Gln" },n",
  2242.     " { symbol "Sec", name "Selenocysteine"},n",
  2243.     " { symbol "Ter", name "Termination" } n",
  2244.     " }                            -- end of tablen",
  2245.     " },n",
  2246.     " {                                -- NCBIstdaan",
  2247.     " code ncbistdaa ,n",
  2248.     " num 26 ,                     -- continuous 0-25n",
  2249.     " one-letter TRUE ,            -- all one letter codesn",
  2250.     " table {n",
  2251.     " { symbol "-", name "Gap" } ,                -- 0n",
  2252.     " { symbol "A", name "Alanine" },             -- 1n",
  2253.     " { symbol "B" , name "Asp or Asn" },         -- 2n",
  2254.     " { symbol "C", name "Cysteine" },            -- 3n",
  2255.     " { symbol "D", name "Aspartic Acid" },       -- 4n",
  2256.     " { symbol "E", name "Glutamic Acid" },       -- 5n",
  2257.     " { symbol "F", name "Phenylalanine" },       -- 6n",
  2258.     " { symbol "G", name "Glycine" },             -- 7n",
  2259.     " { symbol "H", name "Histidine" } ,          -- 8n",
  2260.     " { symbol "I", name "Isoleucine" },          -- 9n",
  2261.     " { symbol "K", name "Lysine" },              -- 10n",
  2262.     " { symbol "L", name "Leucine" },             -- 11n",
  2263.     " { symbol "M", name "Methionine" },          -- 12n",
  2264.     " { symbol "N", name "Asparagine" } ,         -- 13n",
  2265.     " { symbol "P", name "Proline" },             -- 14n",
  2266.     " { symbol "Q", name "Glutamine"},            -- 15n",
  2267.     " { symbol "R", name "Arginine"},             -- 16n",
  2268.     " { symbol "S", name "Serine"},               -- 17n",
  2269.     " { symbol "T", name "Threoine"},             -- 18n",
  2270.     " { symbol "V", name "Valine"},               -- 19n",
  2271.     " { symbol "W", name "Tryptophan" },          -- 20n",
  2272.     " { symbol "X", name "Undetermined or atypical"},  -- 21n",
  2273.     " { symbol "Y", name "Tyrosine"},             -- 22n",
  2274.     " { symbol "Z", name "Glu or Gln" },          -- 23n",
  2275.     " { symbol "U", name "Selenocysteine"},       -- 24 n",
  2276.     " { symbol "*", name "Termination" }          -- 25n",
  2277.     " }                            -- end of table            n",
  2278.     " },n",
  2279.     " {                                -- NCBI2nan",
  2280.     " code ncbi2na ,n",
  2281.     " num 4 ,                     -- continuous 0-3n",
  2282.     " one-letter TRUE ,            -- all one letter codesn",
  2283.     " table {n",
  2284.     " { symbol "A", name "Adenine" },n",
  2285.     " { symbol "C", name "Cytosine" },n",
  2286.     " { symbol "G", name "Guanine" },n",
  2287.     " { symbol "T", name "Thymine/Uracil"}n",
  2288.     " } ,                          -- end of tablen",
  2289.     " comps {                      -- complementsn",
  2290.     " 3,n",
  2291.     " 2,n",
  2292.     " 1,n",
  2293.     " 0n",
  2294.     " }n",
  2295.     " },n",
  2296.     " {                                -- NCBI4nan",
  2297.     " code ncbi4na ,n",
  2298.     " num 16 ,                     -- continuous 0-15n",
  2299.     " one-letter TRUE ,            -- all one letter codesn",
  2300.     " table {n",
  2301.     " { symbol "-", name "Gap" } ,n",
  2302.     " { symbol "A", name "Adenine" },n",
  2303.     " { symbol "C", name "Cytosine" },n",
  2304.     " { symbol "M", name "A or C" },n",
  2305.     " { symbol "G", name "Guanine" },n",
  2306.     " { symbol "R", name "G or A"},n",
  2307.     " { symbol "S", name "G or C"},n",
  2308.     " { symbol "V", name "G or C or A"},n",
  2309.     " { symbol "T", name "Thymine/Uracil"},n",
  2310.     " { symbol "W", name "A or T" },n",
  2311.     " { symbol "Y", name "T or C"} ,n",
  2312.     " { symbol "H", name "A or C or T" } ,n",
  2313.     " { symbol "K", name "G or T" },n",
  2314.     " { symbol "D", name "G or A or T" },n",
  2315.     " { symbol "B" , name "G or T or C" },n",
  2316.     " { symbol "N", name "A or G or C or T" }n",
  2317.     " } ,                           -- end of tablen",
  2318.     " comps {                       -- complementsn",
  2319.     " 0 ,n",
  2320.     " 8 ,n",
  2321.     " 4 ,n",
  2322.     " 12,n",
  2323.     " 2 ,n",
  2324.     " 10,n",
  2325.     " 6 ,n",
  2326.     " 14,n",
  2327.     " 1 ,n",
  2328.     " 9 ,n",
  2329.     " 5 ,n",
  2330.     " 13,n",
  2331.     " 3 ,n",
  2332.     " 11,n",
  2333.     " 7 ,n",
  2334.     " 15n",
  2335.     " }n",
  2336.     " } n",
  2337.     " },                                -- end of codesn",
  2338.     " maps {n",
  2339.     " {n",
  2340.     " from iupacna ,n",
  2341.     " to ncbi2na ,n",
  2342.     " num 25 ,n",
  2343.     " start-at 65 ,n",
  2344.     " table {n",
  2345.     " 0,     -- A -> An",
  2346.     " 1,     -- B -> Cn",
  2347.     " 1,     -- C -> Cn",
  2348.     " 2,     -- D -> Gn",
  2349.     " 255,n",
  2350.     " 255,n",
  2351.     " 2,     -- G -> Gn",
  2352.     " 0,     -- H -> An",
  2353.     " 255,n",
  2354.     " 255,n",
  2355.     " 2,     -- K -> Gn",
  2356.     " 255,n",
  2357.     " 1,     -- M -> Cn",
  2358.     " 0,     -- N -> An",
  2359.     " 255,n",
  2360.     " 255,n",
  2361.     " 255,n",
  2362.     " 2,     -- R -> Gn",
  2363.     " 1,     -- S -> Cn",
  2364.     " 3,     -- T -> Tn",
  2365.     " 255,n",
  2366.     " 0,     -- V -> An",
  2367.     " 3,     -- W -> Tn",
  2368.     " 255,n",
  2369.     " 3 }    -- Y -> Tn",
  2370.     " }, n",
  2371.     " {n",
  2372.     " from iupacna ,n",
  2373.     " to ncbi4na ,n",
  2374.     " num 25 ,n",
  2375.     " start-at 65 ,n",
  2376.     " table {n",
  2377.     " 1,     -- An",
  2378.     " 14,    -- Bn",
  2379.     " 2,     -- Cn",
  2380.     " 13,    -- Dn",
  2381.     " 255,n",
  2382.     " 255,n",
  2383.     " 4,     -- Gn",
  2384.     " 11,    -- Hn",
  2385.     " 255,n",
  2386.     " 255,n",
  2387.     " 12,    -- Kn",
  2388.     " 255,n",
  2389.     " 3,     -- Mn",
  2390.     " 15,    -- Nn",
  2391.     " 255,n",
  2392.     " 255,n",
  2393.     " 255,n",
  2394.     " 5,     -- Rn",
  2395.     " 6,     -- Sn",
  2396.     " 8,     -- Tn",
  2397.     " 255,n",
  2398.     " 7,     -- Vn",
  2399.     " 9,     -- Wn",
  2400.     " 255,n",
  2401.     " 10 }   -- Yn",
  2402.     " }, n",
  2403.     " {n",
  2404.     " from ncbi2na ,n",
  2405.     " to iupacna ,n",
  2406.     " num 4 ,n",
  2407.     " table {n",
  2408.     " 65,     -- An",
  2409.     " 67,     -- Cn",
  2410.     " 71,     -- Gn",
  2411.     " 84 }    -- Tn",
  2412.     " } ,n",
  2413.     " {n",
  2414.     " from ncbi2na ,n",
  2415.     " to ncbi4na ,n",
  2416.     " num 4 ,n",
  2417.     " table {n",
  2418.     " 1,     -- An",
  2419.     " 2,     -- Cn",
  2420.     " 4,     -- Gn",
  2421.     " 8 }    -- Tn",
  2422.     " } , n",
  2423.     " {n",
  2424.     " from ncbi4na ,n",
  2425.     " to iupacna ,n",
  2426.     " num 16 ,n",
  2427.     " table {n",
  2428.     " 78,    -- gap -> Nn",
  2429.     " 65,    -- An",
  2430.     " 67,    -- Cn",
  2431.     " 77,    -- Mn",
  2432.     " 71,    -- Gn",
  2433.     " 82,    -- Rn",
  2434.     " 83,    -- Sn",
  2435.     " 86,    -- Vn",
  2436.     " 84,    -- Tn",
  2437.     " 87,    -- Wn",
  2438.     " 89,    -- Yn",
  2439.     " 72,    -- Hn",
  2440.     " 75,    -- Kn",
  2441.     " 68,    -- Dn",
  2442.     " 66,    -- Bn",
  2443.     " 78 }   -- Nn",
  2444.     " } ,n",
  2445.     " {n",
  2446.     " from ncbi4na ,n",
  2447.     " to ncbi2na ,n",
  2448.     " num 16 ,n",
  2449.     " table {n",
  2450.     " 3,    -- gap -> Tn",
  2451.     " 0,    -- A -> An",
  2452.     " 1,    -- C -> Cn",
  2453.     " 1,    -- M -> Cn",
  2454.     " 2,    -- G -> Gn",
  2455.     " 2,    -- R -> Gn",
  2456.     " 1,    -- S -> Cn",
  2457.     " 0,    -- V -> An",
  2458.     " 3,    -- T -> Tn",
  2459.     " 3,    -- W -> Tn",
  2460.     " 3,    -- Y -> Tn",
  2461.     " 0,    -- H -> An",
  2462.     " 2,    -- K -> Gn",
  2463.     " 2,    -- D -> Gn",
  2464.     " 1,    -- B -> Cn",
  2465.     " 0 }   -- N -> An",
  2466.     " }  ,n",
  2467.     " {n",
  2468.     " from iupacaa ,n",
  2469.     " to ncbieaa ,n",
  2470.     " num 26 ,n",
  2471.     " start-at 65 ,n",
  2472.     " table {n",
  2473.     " 65 ,    -- they map directlyn",
  2474.     " 66 ,n",
  2475.     " 67 ,n",
  2476.     " 68,n",
  2477.     " 69,n",
  2478.     " 70,n",
  2479.     " 71,n",
  2480.     " 72,n",
  2481.     " 73,n",
  2482.     " 255,  -- Jn",
  2483.     " 75,n",
  2484.     " 76,n",
  2485.     " 77,n",
  2486.     " 78,n",
  2487.     " 255,  -- On",
  2488.     " 80,n",
  2489.     " 81,n",
  2490.     " 82,n",
  2491.     " 83,n",
  2492.     " 84,n",
  2493.     " 85,  -- U - was 255n",
  2494.     " 86,n",
  2495.     " 87,n",
  2496.     " 88,n",
  2497.     " 89,n",
  2498.     " 90 }n",
  2499.     " }  ,n",
  2500.     " {n",
  2501.     " from ncbieaa ,n",
  2502.     " to iupacaa ,n",
  2503.     " num 49 ,n",
  2504.     " start-at 42 ,n",
  2505.     " table {n",
  2506.     " 88 ,   -- termination -> Xn",
  2507.     " 255,n",
  2508.     " 255,n",
  2509.     " 88,    -- Gap -> Xn",
  2510.     " 255,n",
  2511.     " 255,n",
  2512.     " 255,n",
  2513.     " 255,n",
  2514.     " 255,n",
  2515.     " 255,n",
  2516.     " 255,n",
  2517.     " 255,n",
  2518.     " 255,n",
  2519.     " 255,n",
  2520.     " 255,n",
  2521.     " 255,n",
  2522.     " 255,n",
  2523.     " 255,n",
  2524.     " 255,n",
  2525.     " 255,n",
  2526.     " 255,n",
  2527.     " 255,n",
  2528.     " 255,n",
  2529.     " 65 ,    -- from here they map directlyn",
  2530.     " 66 ,n",
  2531.     " 67 ,n",
  2532.     " 68,n",
  2533.     " 69,n",
  2534.     " 70,n",
  2535.     " 71,n",
  2536.     " 72,n",
  2537.     " 73,n",
  2538.     " 255,  -- Jn",
  2539.     " 75,n",
  2540.     " 76,n",
  2541.     " 77,n",
  2542.     " 78,n",
  2543.     " 255,  -- On",
  2544.     " 80,n",
  2545.     " 81,n",
  2546.     " 82,n",
  2547.     " 83,n",
  2548.     " 84,n",
  2549.     " 85,  -- U was -> Cn",
  2550.     " 86,n",
  2551.     " 87,n",
  2552.     " 88,n",
  2553.     " 89,n",
  2554.     " 90 }n",
  2555.     " } ,n",
  2556.     " {n",
  2557.     " from iupacaa ,n",
  2558.     " to ncbistdaa ,n",
  2559.     " num 26 ,n",
  2560.     " start-at 65 ,n",
  2561.     " table {n",
  2562.     " 1 ,    -- they map directlyn",
  2563.     " 2 ,n",
  2564.     " 3 ,n",
  2565.     " 4,n",
  2566.     " 5,n",
  2567.     " 6,n",
  2568.     " 7,n",
  2569.     " 8,n",
  2570.     " 9,n",
  2571.     " 255,  -- Jn",
  2572.     " 10,n",
  2573.     " 11,n",
  2574.     " 12,n",
  2575.     " 13,n",
  2576.     " 255,  -- On",
  2577.     " 14,n",
  2578.     " 15,n",
  2579.     " 16,n",
  2580.     " 17,n",
  2581.     " 18,n",
  2582.     " 24,  -- U - was 255n",
  2583.     " 19,n",
  2584.     " 20,n",
  2585.     " 21,n",
  2586.     " 22,n",
  2587.     " 23 }n",
  2588.     " } ,n",
  2589.     " {n",
  2590.     " from ncbieaa ,n",
  2591.     " to ncbistdaa ,n",
  2592.     " num 49 ,n",
  2593.     " start-at 42 ,n",
  2594.     " table {n",
  2595.     " 25,   -- terminationn",
  2596.     " 255,n",
  2597.     " 255,n",
  2598.     " 0,    -- Gapn",
  2599.     " 255,n",
  2600.     " 255,n",
  2601.     " 255,n",
  2602.     " 255,n",
  2603.     " 255,n",
  2604.     " 255,n",
  2605.     " 255,n",
  2606.     " 255,n",
  2607.     " 255,n",
  2608.     " 255,n",
  2609.     " 255,n",
  2610.     " 255,n",
  2611.     " 255,n",
  2612.     " 255,n",
  2613.     " 255,n",
  2614.     " 255,n",
  2615.     " 255,n",
  2616.     " 255,n",
  2617.     " 255,n",
  2618.     " 1 ,    -- they map directlyn",
  2619.     " 2 ,n",
  2620.     " 3 ,n",
  2621.     " 4,n",
  2622.     " 5,n",
  2623.     " 6,n",
  2624.     " 7,n",
  2625.     " 8,n",
  2626.     " 9,n",
  2627.     " 255,  -- Jn",
  2628.     " 10,n",
  2629.     " 11,n",
  2630.     " 12,n",
  2631.     " 13,n",
  2632.     " 255,  -- On",
  2633.     " 14,n",
  2634.     " 15,n",
  2635.     " 16,n",
  2636.     " 17,n",
  2637.     " 18,n",
  2638.     " 24,  -- Un",
  2639.     " 19,n",
  2640.     " 20,n",
  2641.     " 21,n",
  2642.     " 22,n",
  2643.     " 23 }n",
  2644.     " }  ,n",
  2645.     " {n",
  2646.     " from ncbistdaa ,n",
  2647.     " to ncbieaa ,n",
  2648.     " num 26 ,n",
  2649.     " table {n",
  2650.     " 45 ,  --   "-"n",
  2651.     " 65 ,    -- they map directly with holes for O and Jn",
  2652.     " 66 ,n",
  2653.     " 67 ,n",
  2654.     " 68,n",
  2655.     " 69,n",
  2656.     " 70,n",
  2657.     " 71,n",
  2658.     " 72,n",
  2659.     " 73,n",
  2660.     " 75,n",
  2661.     " 76,n",
  2662.     " 77,n",
  2663.     " 78,n",
  2664.     " 80,n",
  2665.     " 81,n",
  2666.     " 82,n",
  2667.     " 83,n",
  2668.     " 84,n",
  2669.     " 86,n",
  2670.     " 87,n",
  2671.     " 88,n",
  2672.     " 89,n",
  2673.     " 90,n",
  2674.     " 85,  -- Un",
  2675.     " 42}  -- *n",
  2676.     " } ,n",
  2677.     " {n",
  2678.     " from ncbistdaa ,n",
  2679.     " to iupacaa ,n",
  2680.     " num 26 ,n",
  2681.     " table {n",
  2682.     " 255 ,  --   "-"n",
  2683.     " 65 ,    -- they map directly with holes for O and Jn",
  2684.     " 66 ,n",
  2685.     " 67 ,n",
  2686.     " 68,n",
  2687.     " 69,n",
  2688.     " 70,n",
  2689.     " 71,n",
  2690.     " 72,n",
  2691.     " 73,n",
  2692.     " 75,n",
  2693.     " 76,n",
  2694.     " 77,n",
  2695.     " 78,n",
  2696.     " 80,n",
  2697.     " 81,n",
  2698.     " 82,n",
  2699.     " 83,n",
  2700.     " 84,n",
  2701.     " 86,n",
  2702.     " 87,n",
  2703.     " 88,n",
  2704.     " 89,n",
  2705.     " 90,n",
  2706.     " 85,  -- U - was 88n",
  2707.     " 255}  -- *n",
  2708.     " } n",
  2709.     " n",
  2710.     " }                                  -- end of mapsn",
  2711.     "-- end of seq-code-set -- }", // make sure '}' is last symbol of ASN text
  2712.     0  // to indicate that there is no more data
  2713. };
  2714. END_objects_SCOPE
  2715. END_NCBI_SCOPE
  2716. /*
  2717.  * ---------------------------------------------------------------------------
  2718.  * $Log: seqport_util.cpp,v $
  2719.  * Revision 1000.4  2004/06/01 19:33:29  gouriano
  2720.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R6.24
  2721.  *
  2722.  * Revision 6.24  2004/05/19 17:25:14  gorelenk
  2723.  * Added include of PCH - ncbi_pch.hpp
  2724.  *
  2725.  * Revision 6.23  2004/03/30 21:25:09  shomrat
  2726.  * Do not attempt to pack protein sequences
  2727.  *
  2728.  * Revision 6.22  2004/01/22 19:13:26  shomrat
  2729.  * fixed bug in complement tables
  2730.  *
  2731.  * Revision 6.21  2003/11/28 19:01:54  vasilche
  2732.  * Avoid calling CStreamUtils::Pushback() when constructing objects from text ASN.
  2733.  * Fixed warnings about conversion char -> unsigned char.
  2734.  *
  2735.  * Revision 6.20  2003/11/21 14:45:03  grichenk
  2736.  * Replaced runtime_error with CException
  2737.  *
  2738.  * Revision 6.19  2003/11/06 22:15:58  shomrat
  2739.  * fixed behavior for default length value
  2740.  *
  2741.  * Revision 6.18  2003/11/06 16:12:32  shomrat
  2742.  * changed seqport_util to use sequtil
  2743.  *
  2744.  * Revision 6.17  2003/06/04 17:03:11  rsmith
  2745.  * Move static mutex out of function to work around CW complex initialization bug.
  2746.  *
  2747.  * Revision 6.16  2003/03/11 15:53:25  kuznets
  2748.  * iterate -> ITERATE
  2749.  *
  2750.  * Revision 6.15  2003/01/30 22:50:30  kans
  2751.  * U (selenocysteine) is now valid in IUPAC alphabet
  2752.  *
  2753.  * Revision 6.14  2002/09/19 20:05:44  vasilche
  2754.  * Safe initialization of static mutexes
  2755.  *
  2756.  * Revision 6.13  2002/09/13 18:34:40  dicuccio
  2757.  * Fixed problem with static object instantiation and type information.
  2758.  * Broke the Seq-code-set ASN.1 blob into more easily editable lines (kans).
  2759.  *
  2760.  * Revision 6.12  2002/05/15 17:57:03  ucko
  2761.  * Make the recently introduced tables STL vectors rather than primitive
  2762.  * arrays to work around a GCC 3.0.4 optimizer bug.
  2763.  *
  2764.  * Revision 6.11  2002/05/14 15:15:16  clausen
  2765.  * Added IsCodeAvailable, GetCodeIndexFromTo, GetName, GetIndexComplement, GetMapToIndex
  2766.  *
  2767.  * Revision 6.10  2002/05/03 21:28:14  ucko
  2768.  * Introduce T(Signed)SeqPos.
  2769.  *
  2770.  * Revision 6.9  2002/04/25 19:37:03  clausen
  2771.  * Fixed bug in MapNcbi2naToNcbi4na that caused corrupiton of out_seq
  2772.  *
  2773.  * Revision 6.8  2002/03/27 19:53:18  grichenk
  2774.  * Fixed CR/LF problem in the source
  2775.  *
  2776.  * Revision 6.7  2002/01/12 07:40:22  vakatov
  2777.  * Fixed multiple dangerous typos ('&' instead of '&&' in IFs)
  2778.  *
  2779.  * Revision 6.6  2002/01/10 19:21:34  clausen
  2780.  * Added GetIupacaa3, GetCode, and GetIndex
  2781.  *
  2782.  * Revision 6.5  2001/10/17 18:35:33  clausen
  2783.  * Fixed machine dependencies in InitFastNcbi4naIupacna and InitFastNcbi2naNcbi4na
  2784.  *
  2785.  * Revision 6.4  2001/10/17 13:04:30  clausen
  2786.  * Fixed InitFastNcbi2naIupacna to remove hardware dependency
  2787.  *
  2788.  * Revision 6.3  2001/09/07 14:16:50  ucko
  2789.  * Cleaned up external interface.
  2790.  *
  2791.  * Revision 6.2  2001/09/06 20:43:32  ucko
  2792.  * Fix iterator types (caught by gcc 3.0.1).
  2793.  *
  2794.  * Revision 6.1  2001/08/24 00:34:23  vakatov
  2795.  * Initial revision
  2796.  *
  2797.  * ===========================================================================
  2798.  */