001package com.hfg.bio.seq;
002
003import java.io.FilterInputStream;
004import java.io.InputStream;
005import java.io.IOException;
006import java.util.Map;
007import java.util.HashMap;
008
009
010//------------------------------------------------------------------------------
011/**
012 * Replaces nucleotides with their complementary nucleotide.
013 *
014 * @author J. Alex Taylor, hairyfatguy.com
015 */
016//------------------------------------------------------------------------------
017// com.hfg XML/HTML Coding Library
018//
019// This library is free software; you can redistribute it and/or
020// modify it under the terms of the GNU Lesser General Public
021// License as published by the Free Software Foundation; either
022// version 2.1 of the License, or (at your option) any later version.
023//
024// This library is distributed in the hope that it will be useful,
025// but WITHOUT ANY WARRANTY; without even the implied warranty of
026// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
027// Lesser General Public License for more details.
028//
029// You should have received a copy of the GNU Lesser General Public
030// License along with this library; if not, write to the Free Software
031// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
032//
033// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com
034// jataylor@hairyfatguy.com
035//------------------------------------------------------------------------------
036
037public class NucleicAcidComplementFilterInputStream extends FilterInputStream
038{
039
040    //##########################################################################
041    // PRIVATE FIELDS
042    //##########################################################################
043
044    private boolean mDone = false;
045
046    private static Map<String, String> sComplementMap = new HashMap<String, String>();
047
048    static
049    {
050        sComplementMap.put("A", "T");
051        sComplementMap.put("a", "t");
052        sComplementMap.put("T", "A");
053        sComplementMap.put("t", "a");
054        sComplementMap.put("C", "G");
055        sComplementMap.put("c", "g");
056        sComplementMap.put("G", "C");
057        sComplementMap.put("g", "c");
058        
059        sComplementMap.put("N", "N");
060        sComplementMap.put("n", "n");
061
062        sComplementMap.put("R", "Y");
063        sComplementMap.put("r", "y");
064        sComplementMap.put("Y", "R");
065        sComplementMap.put("y", "r");
066        sComplementMap.put("S", "S");
067        sComplementMap.put("s", "s");
068        sComplementMap.put("W", "W");
069        sComplementMap.put("w", "w");
070        sComplementMap.put("K", "M");
071        sComplementMap.put("k", "m");
072        sComplementMap.put("M", "K");
073        sComplementMap.put("m", "k");
074        sComplementMap.put("B", "V");
075        sComplementMap.put("b", "v");
076        sComplementMap.put("V", "B");
077        sComplementMap.put("v", "b");
078        sComplementMap.put("D", "H");
079        sComplementMap.put("d", "h");
080        sComplementMap.put("H", "D");
081        sComplementMap.put("h", "d");
082
083    }
084
085    //##########################################################################
086    // CONSTRUCTORS
087    //##########################################################################
088
089    //--------------------------------------------------------------------------
090    public NucleicAcidComplementFilterInputStream(InputStream inputStream)
091    {
092        super(inputStream);
093    }
094
095    //--------------------------------------------------------------------------
096    @Override
097    public int read()
098    throws IOException
099    {
100        int nucleotideChar = super.read();
101        int complement = nucleotideChar;
102        if (nucleotideChar != -1)
103        {
104            String complementString = sComplementMap.get((char)nucleotideChar + "");
105            if (complementString != null) complement = complementString.charAt(0);
106        }
107
108        return complement;
109    }
110
111    //--------------------------------------------------------------------------
112    @Override
113    public int read(byte[] b, int off, int len)
114    throws IOException
115    {
116        int bytesRead = 0;
117        if (!mDone)
118        {
119            for (int i = off; i < off + len; i++)
120            {
121                int byteRead = read();
122                if (-1 == byteRead)
123                {
124                    mDone = true;
125                    break;
126                }
127                else
128                {
129                    b[i] = (byte) byteRead;
130                    bytesRead++;
131                }
132            }
133
134            return bytesRead > 0 ? bytesRead : -1;
135        }
136
137        return -1;
138    }
139
140    //--------------------------------------------------------------------------
141    @Override
142    public int read(byte[] b)
143    throws IOException
144    {
145        return read(b, 0, b.length);
146    }
147}