001/*
002 *                    BioJava development code
003 *
004 * This code may be freely distributed and modified under the
005 * terms of the GNU Lesser General Public Licence.  This should
006 * be distributed with the code.  If you do not have a copy,
007 * see:
008 *
009 *      http://www.gnu.org/copyleft/lesser.html
010 *
011 * Copyright for this code is held jointly by the individual
012 * authors.  These should be listed in @author doc comments.
013 *
014 * For more information on the BioJava project and its aims,
015 * or to join the biojava-l mailing list, visit the home page
016 * at:
017 *
018 *      http://www.biojava.org/
019 *
020 */
021package org.biojava.nbio.structure.symmetry.utils;
022
023import java.io.BufferedReader;
024import java.io.IOException;
025import java.io.InputStream;
026import java.io.InputStreamReader;
027import java.io.Serializable;
028import java.net.URL;
029import java.util.*;
030
031
032public class BlastClustReader implements Serializable {
033
034        private static final long serialVersionUID = 1L;
035
036        private int sequenceIdentity = 0;
037        private List<List<String>> clusters = new ArrayList<List<String>>();
038        private static final String coreUrl = "ftp://resources.rcsb.org/sequence/clusters/";
039        private static List<Integer> seqIdentities = Arrays.asList(30, 40, 50, 70, 90, 95, 100);
040
041        public BlastClustReader(int sequenceIdentity)  {
042                this.sequenceIdentity = sequenceIdentity;
043        }
044
045        public List<List<String>> getPdbChainIdClusters() {
046                loadClusters(sequenceIdentity);
047                return clusters;
048        }
049
050        public Map<String,String> getRepresentatives(String pdbId) {
051                loadClusters(sequenceIdentity);
052                String pdbIdUc = pdbId.toUpperCase();
053
054                Map<String,String> representatives = new LinkedHashMap<String,String>();
055                for (List<String> cluster: clusters) {
056                        // map fist match to representative
057                        for (String chainId: cluster) {
058                                if (chainId.startsWith(pdbIdUc)) {
059                                        representatives.put(chainId, cluster.get(0));
060                                        break;
061                                }
062                        }
063                }
064                return representatives;
065        }
066
067        public String getRepresentativeChain(String pdbId, String chainId) {
068                loadClusters(sequenceIdentity);
069
070                String pdbChainId = pdbId.toUpperCase() + "." + chainId;
071
072                for (List<String> cluster: clusters) {
073                        if (cluster.contains(pdbChainId)) {
074                                return cluster.get(0);
075                        }
076                }
077                return "";
078        }
079
080        public int indexOf(String pdbId, String chainId) {
081                loadClusters(sequenceIdentity);
082
083                String pdbChainId = pdbId.toUpperCase() + "." + chainId;
084
085                for (int i = 0; i < clusters.size(); i++) {
086                        List<String> cluster = clusters.get(i);
087                        if (cluster.contains(pdbChainId)) {
088                                return i;
089                        }
090                }
091                return -1;
092        }
093
094        public List<List<String>> getPdbChainIdClusters(String pdbId) {
095                loadClusters(sequenceIdentity);
096                String pdbIdUpper = pdbId.toUpperCase();
097
098                List<List<String>> matches = new ArrayList<List<String>>();
099                for (List<String> cluster: clusters) {
100                        for (String chainId: cluster) {
101                                if (chainId.startsWith(pdbIdUpper)) {
102                                        matches.add(cluster);
103                                        break;
104                                }
105                        }
106                }
107                return matches;
108        }
109
110        public List<List<String>> getChainIdsInEntry(String pdbId) {
111                loadClusters(sequenceIdentity);
112
113                List<List<String>> matches = new ArrayList<List<String>>();
114                List<String> match = null;
115
116                for (List<String> cluster: clusters) {
117                        for (String chainId: cluster) {
118                                if (chainId.startsWith(pdbId)) {
119                                        if (match == null) {
120                                                match = new ArrayList<String>();
121                                        }
122                                        match.add(chainId.substring(5));
123                                }
124                        }
125                        if (match != null) {
126                                Collections.sort(match);
127                                matches.add(match);
128                                match = null;
129                        }
130                }
131                return matches;
132        }
133
134        private void loadClusters(int sequenceIdentity) {
135                // load clusters only once
136                if (clusters.size() > 0) {
137                        return;
138                }
139
140                if (!seqIdentities.contains(sequenceIdentity)) {
141                        System.err.println("Error: representative chains are not available for %sequence identity: "
142                                        + sequenceIdentity);
143                        return;
144                }
145
146                try {
147                        URL u = new URL(coreUrl + "bc-" + sequenceIdentity + ".out");
148                        InputStream stream = u.openStream();
149        //              URLConnection connection = u.openConnection();
150        //              connection.setConnectTimeout(60000);
151        //              InputStream stream = connection.getInputStream();
152
153                        if (stream != null) {
154                                BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
155
156                                String line = null;
157                                try {
158                                        while ((line = reader.readLine()) != null) {
159                                                line = line.replaceAll("_", ".");
160                                                List<String> cluster = Arrays.asList(line.split(" "));
161                                                clusters.add(cluster);
162                                        }
163                                        reader.close();
164                                        stream.close();
165                                } catch (IOException e) {
166                                        //e.printStackTrace();
167                                } finally {
168//                                      try {
169//                                              System.out.println("closing reader");
170//                                              reader.close();
171//                                              stream.close();
172//                                      } catch (IOException e) {
173//                                              e.printStackTrace();
174//                                      }
175                                }
176                        }
177
178                } catch (Exception e) {
179                        e.printStackTrace();
180                }
181
182                return;
183        }
184
185}
186