inprogress
[jalview.git] / forester / java / src / org / forester / protein / BasicProtein.java
1 // $Id:
2 //
3 // FORESTER -- software libraries and applications
4 // for evolutionary biology research and applications.
5 //
6 // Copyright (C) 2008-2009 Christian M. Zmasek
7 // Copyright (C) 2008-2009 Burnham Institute for Medical Research
8 // All rights reserved
9 //
10 // This library is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU Lesser General Public
12 // License as published by the Free Software Foundation; either
13 // version 2.1 of the License, or (at your option) any later version.
14 //
15 // This library is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 //
24 // Contact: phylosoft @ gmail . com
25 // WWW: https://sites.google.com/site/cmzmasek/home/software/forester
26
27 package org.forester.protein;
28
29 import java.util.ArrayList;
30 import java.util.Collections;
31 import java.util.Comparator;
32 import java.util.List;
33 import java.util.SortedSet;
34 import java.util.TreeSet;
35
36 import org.forester.species.BasicSpecies;
37 import org.forester.species.Species;
38 import org.forester.util.ForesterUtil;
39
40 // Note: when implementing any "equals" method need to keep in mind that
41 // proteins could have the same name and/or id!
42 public class BasicProtein implements Protein {
43
44     private final ProteinId          _id;
45     private final int                _length;
46     private final Species            _species;
47     private String                   _name;
48     private String                   _desc;
49     private String                   _accession;
50     private final List<Domain>       _protein_domains;
51     public static Comparator<Domain> DomainMidPositionComparator = new Comparator<Domain>() {
52
53                                                                      @Override
54                                                                      public int compare( final Domain d1,
55                                                                                          final Domain d2 ) {
56                                                                          final int m1 = ( d1.getTo() + d1.getFrom() );
57                                                                          final int m2 = ( d2.getTo() + d2.getFrom() );
58                                                                          return m1 < m2 ? -1 : m1 > m2 ? 1 : d1
59                                                                                  .getDomainId().getId()
60                                                                                  .compareTo( d2.getDomainId().getId() );
61                                                                      }
62                                                                  };
63
64     public BasicProtein( final String id_str, final String species_str, final int length ) {
65         if ( length < 0 ) {
66             throw new IllegalArgumentException( "attempt to create protein of length " + length );
67         }
68         if ( ForesterUtil.isEmpty( id_str ) ) {
69             throw new IllegalArgumentException( "attempt to create protein with null or empty identifier" );
70         }
71         if ( ForesterUtil.isEmpty( species_str ) ) {
72             throw new IllegalArgumentException( "attempt to create protein with null or empty species" );
73         }
74         _id = new ProteinId( id_str );
75         _species = new BasicSpecies( species_str );
76         _length = length;
77         _protein_domains = new ArrayList<Domain>();
78         init();
79     }
80
81     @Override
82     public void addProteinDomain( final Domain protein_domain ) {
83         getProteinDomains().add( protein_domain );
84     }
85
86     @Override
87     /**
88      * If in_nc_order is set to true, this returns true only and only if
89      * the order in List 'domains' and this protein (as determined by the start positions
90      * of the domains of this proteins, _not_ by their index) are the same
91      * (interspersing, 'other', domains in this are ignored). 
92      * If in_nc_order is set to false, this returns true only and only if
93      * this contains all domains listed in 'domains' (order and count do not matter).
94      * 
95      * @param domains a list of domain ids in a certain order.
96      * @param in_nc_order to consider order
97      * @return
98      */
99     public boolean contains( final List<DomainId> query_domain_ids, final boolean in_nc_order ) {
100         if ( !in_nc_order ) {
101             for( final DomainId query_domain_id : query_domain_ids ) {
102                 if ( !getProteinDomainIds().contains( query_domain_id ) ) {
103                     return false;
104                 }
105             }
106             return true;
107         }
108         else {
109             int current_start_position = -1;
110             I: for( final DomainId query_domain_id : query_domain_ids ) {
111                 if ( getProteinDomainIds().contains( query_domain_id ) ) {
112                     final List<Domain> found_domains = getProteinDomains( query_domain_id );
113                     final SortedSet<Integer> ordered_start_positions = new TreeSet<Integer>();
114                     for( final Domain found_domain : found_domains ) {
115                         ordered_start_positions.add( found_domain.getFrom() );
116                     }
117                     for( final int start_position : ordered_start_positions ) {
118                         if ( start_position > current_start_position ) {
119                             current_start_position = start_position;
120                             continue I;
121                         }
122                     }
123                     return false;
124                 }
125                 else {
126                     return false;
127                 }
128             }
129             return true;
130         }
131     }
132
133     @Override
134     public String getAccession() {
135         return _accession;
136     }
137
138     @Override
139     public String getDescription() {
140         return _desc;
141     }
142
143     @Override
144     public List<Domain> getDomainsSortedByPosition() {
145         final List<Domain> domains = new ArrayList<Domain>( getProteinDomains().size() );
146         for( final Domain domain : getProteinDomains() ) {
147             domains.add( domain );
148         }
149         Collections.sort( domains, DomainMidPositionComparator );
150         return domains;
151     }
152
153     @Override
154     public int getLength() {
155         return _length;
156     }
157
158     @Override
159     public String getName() {
160         return _name;
161     }
162
163     @Override
164     public int getNumberOfProteinDomains() {
165         return getProteinDomains().size();
166     }
167
168     @Override
169     public Domain getProteinDomain( final int index ) {
170         return _protein_domains.get( index );
171     }
172
173     @Override
174     public int getProteinDomainCount( final DomainId domain_id ) {
175         return getProteinDomains( domain_id ).size();
176     }
177
178     @Override
179     public List<Domain> getProteinDomains() {
180         return _protein_domains;
181     }
182
183     @Override
184     public List<Domain> getProteinDomains( final DomainId domain_id ) {
185         final List<Domain> domains = new ArrayList<Domain>();
186         for( final Domain domain : getProteinDomains() ) {
187             if ( domain.getDomainId().equals( domain_id ) ) {
188                 domains.add( domain );
189             }
190         }
191         return domains;
192     }
193
194     @Override
195     public ProteinId getProteinId() {
196         return _id;
197     }
198
199     @Override
200     public Species getSpecies() {
201         return _species;
202     }
203
204     public void setAccession( final String accession ) {
205         _accession = accession;
206     }
207
208     public void setDescription( final String description ) {
209         _desc = description;
210     }
211
212     public void setName( final String name ) {
213         _name = name;
214     }
215
216     public String toDomainArchitectureString( final String separator ) {
217         final StringBuilder sb = new StringBuilder();
218         boolean first = true;
219         for( final Domain d : getDomainsSortedByPosition() ) {
220             if ( first ) {
221                 first = false;
222             }
223             else {
224                 sb.append( separator );
225             }
226             sb.append( d.getDomainId().getId() );
227         }
228         return sb.toString();
229     }
230
231     public String toDomainArchitectureString( final String separator,
232                                               final int repeats_limit,
233                                               final String repeat_separator ) {
234         if ( repeats_limit < 3 ) {
235             throw new IllegalArgumentException( "repeats limit cannot be smaller than 3" );
236         }
237         final StringBuilder sb = new StringBuilder();
238         StringBuilder buffer = new StringBuilder();
239         String prev_id = "";
240         int counter = 1;
241         for( final Domain d : getDomainsSortedByPosition() ) {
242             final String id = d.getDomainId().getId();
243             if ( prev_id.equals( id ) ) {
244                 counter++;
245             }
246             else {
247                 counter = 1;
248                 sb.append( buffer );
249                 buffer = new StringBuilder();
250             }
251             if ( counter < repeats_limit ) {
252                 buffer.append( id );
253                 buffer.append( separator );
254             }
255             else if ( counter == repeats_limit ) {
256                 buffer = new StringBuilder();
257                 buffer.append( id );
258                 buffer.append( repeat_separator );
259                 buffer.append( id );
260                 buffer.append( repeat_separator );
261                 buffer.append( id );
262                 buffer.append( separator );
263             }
264             prev_id = id;
265         }
266         sb.append( buffer.substring( 0, buffer.length() - 1 ) );
267         return sb.toString();
268     }
269
270     @Override
271     public String toString() {
272         return toDomainArchitectureString( "~" );
273     }
274
275     private List<DomainId> getProteinDomainIds() {
276         final List<DomainId> ids = new ArrayList<DomainId>( getProteinDomains().size() );
277         for( final Domain domain : getProteinDomains() ) {
278             ids.add( domain.getDomainId() );
279         }
280         return ids;
281     }
282
283     private void init() {
284         _desc = "";
285         _accession = "";
286         _name = "";
287     }
288 }