inprogress
[jalview.git] / forester / java / src / org / forester / surfacing / PrintableDomainSimilarity.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.surfacing;
28
29 import java.util.List;
30 import java.util.Map;
31 import java.util.SortedMap;
32 import java.util.SortedSet;
33 import java.util.TreeSet;
34
35 import org.forester.species.Species;
36 import org.forester.surfacing.DomainSimilarityCalculator.Detailedness;
37 import org.forester.util.ForesterUtil;
38
39 public class PrintableDomainSimilarity implements DomainSimilarity {
40
41     final public static String                                           SPECIES_SEPARATOR = "  ";
42     final private static char                                            TAB               = '\t';
43     final private static int                                             BEFORE            = -1;
44     final private static int                                             EQUAL             = 0;
45     final private static int                                             AFTER             = 1;
46     final private static String                                          NO_SPECIES        = "     ";
47     final private double                                                 _min;
48     final private double                                                 _max;
49     final private double                                                 _mean;
50     final private double                                                 _sd;
51     final private int                                                    _n;
52     private final int                                                    _max_difference_in_counts;
53     private final int                                                    _max_difference;
54     final private CombinableDomains                                      _combinable_domains;
55     final private SortedMap<Species, SpeciesSpecificDomainSimilariyData> _species_data;
56     final private DomainSimilaritySortField                              _sort_field;
57     private List<Species>                                                _species_order;
58     private final boolean                                                _sort_by_species_count_first;
59     private DomainSimilarityCalculator.Detailedness                      _detailedness;
60     private final boolean                                                _treat_as_binary_comparison;
61
62     /**
63      * If go_id_to_term_map not null, detailed GO information is written,
64      * only GO ids otherwise.
65      * 
66      * 
67      */
68     public PrintableDomainSimilarity( final CombinableDomains combinable_domains,
69                                       final double min,
70                                       final double max,
71                                       final double mean,
72                                       final double median,
73                                       final double sd,
74                                       final int n,
75                                       final int max_difference_in_counts,
76                                       final int max_difference,
77                                       final SortedMap<Species, SpeciesSpecificDomainSimilariyData> species_data,
78                                       final DomainSimilaritySortField sort_field,
79                                       final boolean sort_by_species_count_first,
80                                       final boolean treat_as_binary_comparison ) {
81         if ( combinable_domains == null ) {
82             throw new IllegalArgumentException( "attempt to use null combinable domains" );
83         }
84         if ( sort_field == null ) {
85             throw new IllegalArgumentException( "attempt to use null sorting" );
86         }
87         if ( species_data == null ) {
88             throw new IllegalArgumentException( "attempt to use null species data" );
89         }
90         if ( species_data.size() < 1 ) {
91             throw new IllegalArgumentException( "attempt to use empty species data" );
92         }
93         if ( n < 0 ) {
94             throw new IllegalArgumentException( "attempt to use N less than 0" );
95         }
96         if ( ( species_data.size() > 1 ) && ( n < 1 ) ) {
97             throw new IllegalArgumentException( "attempt to use N less than 1" );
98         }
99         if ( sd < 0.0 ) {
100             throw new IllegalArgumentException( "attempt to use negative SD" );
101         }
102         if ( max < min ) {
103             throw new IllegalArgumentException( "attempt to use max smaller than min" );
104         }
105         init();
106         _combinable_domains = combinable_domains;
107         _min = min;
108         _max = max;
109         _mean = mean;
110         _sd = sd;
111         _n = n;
112         _max_difference_in_counts = max_difference_in_counts;
113         _max_difference = max_difference;
114         _species_data = species_data;
115         _sort_field = sort_field;
116         _sort_by_species_count_first = sort_by_species_count_first;
117         _treat_as_binary_comparison = treat_as_binary_comparison;
118         final int s = species_data.size();
119         if ( ( ( s * s ) - s ) != ( getN() * 2 ) ) {
120             throw new IllegalArgumentException( "illegal species count and n: species count:" + s + ", n:" + _n
121                     + " for domain " + combinable_domains.getKeyDomain() );
122         }
123         if ( s > 2 ) {
124             if ( getMaximalDifferenceInCounts() < 0 ) {
125                 throw new IllegalArgumentException( "attempt to use negative max difference in counts with more than two species" );
126             }
127             if ( getMaximalDifference() < 0 ) {
128                 throw new IllegalArgumentException( "attempt to use negative max difference with more than two species" );
129             }
130         }
131     }
132
133     private void addSpeciesSpecificDomainData( final StringBuffer sb,
134                                                final Species species,
135                                                final boolean html,
136                                                final Map<String, Integer> tax_code_to_id_map ) {
137         if ( getDetaildness() != DomainSimilarityCalculator.Detailedness.BASIC ) {
138             sb.append( "[" );
139         }
140         if ( html ) {
141             sb.append( "<b>" );
142             final String tax_code = species.getSpeciesId();
143             if ( !ForesterUtil.isEmpty( tax_code )
144                     && ( ( tax_code_to_id_map != null ) && tax_code_to_id_map.containsKey( tax_code ) ) ) {
145                 sb.append( "<a href=\"" + SurfacingConstants.UNIPROT_TAXONOMY_ID_LINK
146                         + tax_code_to_id_map.get( tax_code ) + "\" target=\"taxonomy_window\">" + tax_code + "</a>" );
147             }
148             else {
149                 sb.append( tax_code );
150             }
151             sb.append( "</b>" );
152         }
153         else {
154             sb.append( species.getSpeciesId() );
155         }
156         if ( getDetaildness() != DomainSimilarityCalculator.Detailedness.BASIC ) {
157             sb.append( ":" );
158             sb.append( getSpeciesData().get( species ).toStringBuffer( getDetaildness(), html ) );
159             sb.append( "]" );
160         }
161         if ( html ) {
162             sb.append( "<br>" );
163         }
164         sb.append( PrintableDomainSimilarity.SPECIES_SEPARATOR );
165     }
166
167     private void boldEndIfSortedBy( final DomainSimilaritySortField sort_field, final StringBuffer sb ) {
168         if ( getSortField() == sort_field ) {
169             sb.append( "</b>" );
170         }
171     }
172
173     private void boldStartIfSortedBy( final DomainSimilaritySortField sort_field, final StringBuffer sb ) {
174         if ( getSortField() == sort_field ) {
175             sb.append( "<b>" );
176         }
177     }
178
179     private int compareByDomainId( final DomainSimilarity other ) {
180         return getDomainId().compareTo( other.getDomainId() );
181     }
182
183     private int compareBySpeciesCount( final DomainSimilarity domain_similarity ) {
184         final int s_this = getSpeciesData().size();
185         final int s_other = domain_similarity.getSpeciesData().size();
186         if ( s_this < s_other ) {
187             return PrintableDomainSimilarity.BEFORE;
188         }
189         else if ( s_this > s_other ) {
190             return PrintableDomainSimilarity.AFTER;
191         }
192         else {
193             return PrintableDomainSimilarity.EQUAL;
194         }
195     }
196
197     @Override
198     public int compareTo( final DomainSimilarity domain_similarity ) {
199         if ( this == domain_similarity ) {
200             return PrintableDomainSimilarity.EQUAL;
201         }
202         else if ( domain_similarity == null ) {
203             throw new IllegalArgumentException( "attempt to compare " + this.getClass() + " to null" );
204         }
205         else if ( domain_similarity.getClass() != this.getClass() ) {
206             throw new IllegalArgumentException( "attempt to compare " + this.getClass() + " to "
207                     + domain_similarity.getClass() );
208         }
209         switch ( getSortField() ) {
210             case MIN:
211                 if ( isSortBySpeciesCountFirst() ) {
212                     final int i = compareBySpeciesCount( domain_similarity );
213                     if ( i != PrintableDomainSimilarity.EQUAL ) {
214                         return i;
215                     }
216                 }
217                 if ( getMinimalSimilarityScore() < domain_similarity.getMinimalSimilarityScore() ) {
218                     return PrintableDomainSimilarity.BEFORE;
219                 }
220                 else if ( getMinimalSimilarityScore() > domain_similarity.getMinimalSimilarityScore() ) {
221                     return PrintableDomainSimilarity.AFTER;
222                 }
223                 else {
224                     return compareByDomainId( domain_similarity );
225                 }
226             case MAX:
227                 if ( isSortBySpeciesCountFirst() ) {
228                     final int i = compareBySpeciesCount( domain_similarity );
229                     if ( i != PrintableDomainSimilarity.EQUAL ) {
230                         return i;
231                     }
232                 }
233                 if ( getMaximalSimilarityScore() < domain_similarity.getMaximalSimilarityScore() ) {
234                     return PrintableDomainSimilarity.BEFORE;
235                 }
236                 else if ( getMaximalSimilarityScore() > domain_similarity.getMaximalSimilarityScore() ) {
237                     return PrintableDomainSimilarity.AFTER;
238                 }
239                 else {
240                     return compareByDomainId( domain_similarity );
241                 }
242             case MEAN:
243                 if ( isSortBySpeciesCountFirst() ) {
244                     final int i = compareBySpeciesCount( domain_similarity );
245                     if ( i != PrintableDomainSimilarity.EQUAL ) {
246                         return i;
247                     }
248                 }
249                 if ( getMeanSimilarityScore() < domain_similarity.getMeanSimilarityScore() ) {
250                     return PrintableDomainSimilarity.BEFORE;
251                 }
252                 else if ( getMeanSimilarityScore() > domain_similarity.getMeanSimilarityScore() ) {
253                     return PrintableDomainSimilarity.AFTER;
254                 }
255                 else {
256                     return compareByDomainId( domain_similarity );
257                 }
258             case SD:
259                 if ( isSortBySpeciesCountFirst() ) {
260                     final int i = compareBySpeciesCount( domain_similarity );
261                     if ( i != PrintableDomainSimilarity.EQUAL ) {
262                         return i;
263                     }
264                 }
265                 if ( getStandardDeviationOfSimilarityScore() < domain_similarity
266                         .getStandardDeviationOfSimilarityScore() ) {
267                     return PrintableDomainSimilarity.BEFORE;
268                 }
269                 else if ( getStandardDeviationOfSimilarityScore() > domain_similarity
270                         .getStandardDeviationOfSimilarityScore() ) {
271                     return PrintableDomainSimilarity.AFTER;
272                 }
273                 else {
274                     return compareByDomainId( domain_similarity );
275                 }
276             case MAX_DIFFERENCE:
277                 if ( isSortBySpeciesCountFirst() ) {
278                     final int i = compareBySpeciesCount( domain_similarity );
279                     if ( i != PrintableDomainSimilarity.EQUAL ) {
280                         return i;
281                     }
282                 }
283                 if ( getMaximalDifference() > domain_similarity.getMaximalDifference() ) {
284                     return PrintableDomainSimilarity.BEFORE;
285                 }
286                 else if ( getMaximalDifference() < domain_similarity.getMaximalDifference() ) {
287                     return PrintableDomainSimilarity.AFTER;
288                 }
289                 else {
290                     return compareByDomainId( domain_similarity );
291                 }
292             case ABS_MAX_COUNTS_DIFFERENCE:
293                 if ( isSortBySpeciesCountFirst() ) {
294                     final int i = compareBySpeciesCount( domain_similarity );
295                     if ( i != PrintableDomainSimilarity.EQUAL ) {
296                         return i;
297                     }
298                 }
299                 if ( Math.abs( getMaximalDifferenceInCounts() ) > Math.abs( domain_similarity
300                         .getMaximalDifferenceInCounts() ) ) {
301                     return PrintableDomainSimilarity.BEFORE;
302                 }
303                 else if ( Math.abs( getMaximalDifferenceInCounts() ) < Math.abs( domain_similarity
304                         .getMaximalDifferenceInCounts() ) ) {
305                     return PrintableDomainSimilarity.AFTER;
306                 }
307                 else {
308                     return compareByDomainId( domain_similarity );
309                 }
310             case MAX_COUNTS_DIFFERENCE:
311                 if ( getSpeciesData().size() != 2 ) {
312                     throw new RuntimeException( "attempt to sort by maximal difference with species not equal to two" );
313                 }
314                 if ( isSortBySpeciesCountFirst() ) {
315                     final int i = compareBySpeciesCount( domain_similarity );
316                     if ( i != PrintableDomainSimilarity.EQUAL ) {
317                         return i;
318                     }
319                 }
320                 if ( getMaximalDifferenceInCounts() > domain_similarity.getMaximalDifferenceInCounts() ) {
321                     return PrintableDomainSimilarity.BEFORE;
322                 }
323                 else if ( getMaximalDifferenceInCounts() < domain_similarity.getMaximalDifferenceInCounts() ) {
324                     return PrintableDomainSimilarity.AFTER;
325                 }
326                 else {
327                     return compareByDomainId( domain_similarity );
328                 }
329             case SPECIES_COUNT:
330                 final int i = compareBySpeciesCount( domain_similarity );
331                 if ( i != PrintableDomainSimilarity.EQUAL ) {
332                     return i;
333                 }
334                 else {
335                     return compareByDomainId( domain_similarity );
336                 }
337             case DOMAIN_ID:
338                 return compareByDomainId( domain_similarity );
339         }
340         throw new AssertionError( "Unknown sort method: " + getSortField() );
341     }
342
343     @Override
344     public SortedSet<String> getCombinableDomainIds( final Species species_of_combinable_domain ) {
345         final SortedSet<String> sorted_ids = new TreeSet<String>();
346         if ( getSpeciesData().containsKey( species_of_combinable_domain ) ) {
347             for( final String id : getSpeciesData().get( species_of_combinable_domain )
348                     .getCombinableDomainIdToCountsMap().keySet() ) {
349                 sorted_ids.add( id );
350             }
351         }
352         return sorted_ids;
353     }
354
355     private CombinableDomains getCombinableDomains() {
356         return _combinable_domains;
357     }
358
359     private DomainSimilarityCalculator.Detailedness getDetaildness() {
360         return _detailedness;
361     }
362
363     @Override
364     public String getDomainId() {
365         return getCombinableDomains().getKeyDomain();
366     }
367
368     @Override
369     public int getMaximalDifference() {
370         return _max_difference;
371     }
372
373     @Override
374     public int getMaximalDifferenceInCounts() {
375         return _max_difference_in_counts;
376     }
377
378     @Override
379     public double getMaximalSimilarityScore() {
380         return _max;
381     }
382
383     @Override
384     public double getMeanSimilarityScore() {
385         return _mean;
386     }
387
388     @Override
389     public double getMinimalSimilarityScore() {
390         return _min;
391     }
392
393     @Override
394     public int getN() {
395         return _n;
396     }
397
398     private DomainSimilaritySortField getSortField() {
399         return _sort_field;
400     }
401
402     @Override
403     public SortedSet<Species> getSpecies() {
404         final SortedSet<Species> species = new TreeSet<Species>();
405         for( final Species s : getSpeciesData().keySet() ) {
406             species.add( s );
407         }
408         return species;
409     }
410
411     public List<Species> getSpeciesCustomOrder() {
412         return _species_order;
413     }
414
415     @Override
416     public SortedMap<Species, SpeciesSpecificDomainSimilariyData> getSpeciesData() {
417         return _species_data;
418     }
419
420     private StringBuffer getSpeciesDataInAlphabeticalOrder( final boolean html,
421                                                             final Map<String, Integer> tax_code_to_id_map ) {
422         final StringBuffer sb = new StringBuffer();
423         for( final Species species : getSpeciesData().keySet() ) {
424             addSpeciesSpecificDomainData( sb, species, html, tax_code_to_id_map );
425         }
426         return sb;
427     }
428
429     private StringBuffer getSpeciesDataInCustomOrder( final boolean html, final Map<String, Integer> tax_code_to_id_map ) {
430         final StringBuffer sb = new StringBuffer();
431         for( final Species order_species : getSpeciesCustomOrder() ) {
432             if ( getSpeciesData().keySet().contains( order_species ) ) {
433                 addSpeciesSpecificDomainData( sb, order_species, html, tax_code_to_id_map );
434             }
435             else {
436                 sb.append( PrintableDomainSimilarity.NO_SPECIES );
437                 sb.append( PrintableDomainSimilarity.SPECIES_SEPARATOR );
438             }
439         }
440         return sb;
441     }
442
443     @Override
444     public double getStandardDeviationOfSimilarityScore() {
445         return _sd;
446     }
447
448     private void init() {
449         _detailedness = DomainSimilarityCalculator.Detailedness.PUNCTILIOUS;
450     }
451
452     private boolean isSortBySpeciesCountFirst() {
453         return _sort_by_species_count_first;
454     }
455
456     private boolean isTreatAsBinaryComparison() {
457         return _treat_as_binary_comparison;
458     }
459
460     public void setDetailedness( final Detailedness detailedness ) {
461         _detailedness = detailedness;
462     }
463
464     public void setSpeciesOrder( final List<Species> species_order ) {
465         if ( !species_order.containsAll( getSpeciesData().keySet() ) ) {
466             throw new IllegalArgumentException( "list to order species must contain all species of multiple combinable domains similarity" );
467         }
468         _species_order = species_order;
469     }
470
471     @Override
472     public StringBuffer toStringBuffer( final PrintableDomainSimilarity.PRINT_OPTION print_option,
473                                         final Map<String, Integer> tax_code_to_id_map ) {
474         switch ( print_option ) {
475             case SIMPLE_TAB_DELIMITED:
476                 return toStringBufferSimpleTabDelimited();
477             case HTML:
478                 return toStringBufferDetailedHTML( tax_code_to_id_map );
479             default:
480                 throw new AssertionError( "Unknown print option: " + print_option );
481         }
482     }
483
484     private StringBuffer toStringBufferDetailedHTML( final Map<String, Integer> tax_code_to_id_map ) {
485         final StringBuffer sb = new StringBuffer();
486         sb.append( "<tr>" );
487         sb.append( "<td>" );
488         boldStartIfSortedBy( DomainSimilaritySortField.DOMAIN_ID, sb );
489         sb.append( "<a href=\"" + SurfacingConstants.PFAM_FAMILY_ID_LINK + getDomainId() + "\" target=\"pfam_window\">"
490                 + getDomainId() + "</a>" );
491         boldEndIfSortedBy( DomainSimilaritySortField.DOMAIN_ID, sb );
492         sb.append( "<a name=\"" + getDomainId() + "\">" );
493         sb.append( "</td>" );
494         sb.append( "<td>" );
495         sb.append( "<a href=\"" + SurfacingConstants.GOOGLE_SCHOLAR_SEARCH + getDomainId()
496                 + "\" target=\"gs_window\">gs</a>" );
497         sb.append( "</td>" );
498         sb.append( "<td>" );
499         boldStartIfSortedBy( DomainSimilaritySortField.MEAN, sb );
500         sb.append( ForesterUtil.round( getMeanSimilarityScore(), 3 ) );
501         boldEndIfSortedBy( DomainSimilaritySortField.MEAN, sb );
502         sb.append( "</td>" );
503         if ( !isTreatAsBinaryComparison() ) {
504             sb.append( "<td>" );
505             sb.append( "(" );
506             boldStartIfSortedBy( DomainSimilaritySortField.SD, sb );
507             sb.append( ForesterUtil.round( getStandardDeviationOfSimilarityScore(), 3 ) );
508             boldEndIfSortedBy( DomainSimilaritySortField.SD, sb );
509             sb.append( ")" );
510             sb.append( "</td>" );
511             sb.append( "<td>" );
512             sb.append( "[" );
513             boldStartIfSortedBy( DomainSimilaritySortField.MIN, sb );
514             sb.append( ForesterUtil.round( getMinimalSimilarityScore(), 3 ) );
515             boldEndIfSortedBy( DomainSimilaritySortField.MIN, sb );
516             sb.append( "-" );
517             boldStartIfSortedBy( DomainSimilaritySortField.MAX, sb );
518             sb.append( ForesterUtil.round( getMaximalSimilarityScore(), 3 ) );
519             boldEndIfSortedBy( DomainSimilaritySortField.MAX, sb );
520             sb.append( "]" );
521             sb.append( "</td>" );
522         }
523         sb.append( "<td>" );
524         boldStartIfSortedBy( DomainSimilaritySortField.MAX_DIFFERENCE, sb );
525         sb.append( getMaximalDifference() );
526         boldEndIfSortedBy( DomainSimilaritySortField.MAX_DIFFERENCE, sb );
527         sb.append( "</td>" );
528         sb.append( "<td>" );
529         if ( isTreatAsBinaryComparison() ) {
530             boldStartIfSortedBy( DomainSimilaritySortField.MAX_COUNTS_DIFFERENCE, sb );
531             boldStartIfSortedBy( DomainSimilaritySortField.ABS_MAX_COUNTS_DIFFERENCE, sb );
532             sb.append( getMaximalDifferenceInCounts() );
533             boldEndIfSortedBy( DomainSimilaritySortField.ABS_MAX_COUNTS_DIFFERENCE, sb );
534             boldStartIfSortedBy( DomainSimilaritySortField.MAX_COUNTS_DIFFERENCE, sb );
535         }
536         else {
537             boldStartIfSortedBy( DomainSimilaritySortField.MAX_COUNTS_DIFFERENCE, sb );
538             boldStartIfSortedBy( DomainSimilaritySortField.ABS_MAX_COUNTS_DIFFERENCE, sb );
539             sb.append( Math.abs( getMaximalDifferenceInCounts() ) );
540             boldEndIfSortedBy( DomainSimilaritySortField.ABS_MAX_COUNTS_DIFFERENCE, sb );
541             boldStartIfSortedBy( DomainSimilaritySortField.MAX_COUNTS_DIFFERENCE, sb );
542         }
543         sb.append( "</td>" );
544         if ( !isTreatAsBinaryComparison() ) {
545             sb.append( "<td>" );
546             if ( ( getSortField() == DomainSimilaritySortField.SPECIES_COUNT ) || isSortBySpeciesCountFirst() ) {
547                 sb.append( "<b>" );
548             }
549             sb.append( getSpeciesData().size() );
550             if ( ( getSortField() == DomainSimilaritySortField.SPECIES_COUNT ) || isSortBySpeciesCountFirst() ) {
551                 sb.append( "</b>" );
552             }
553             sb.append( "</td>" );
554         }
555         if ( ( getSpeciesCustomOrder() == null ) || getSpeciesCustomOrder().isEmpty() ) {
556             sb.append( "<td>" );
557             sb.append( getSpeciesDataInAlphabeticalOrder( true, tax_code_to_id_map ) );
558             sb.append( "</td>" );
559         }
560         else {
561             sb.append( "<td>" );
562             sb.append( getSpeciesDataInCustomOrder( true, tax_code_to_id_map ) );
563             sb.append( "</td>" );
564         }
565         sb.append( "</tr>" );
566         return sb;
567     }
568
569     private StringBuffer toStringBufferSimpleTabDelimited() {
570         final StringBuffer sb = new StringBuffer();
571         sb.append( getDomainId() );
572         switch ( getSortField() ) {
573             case MIN:
574                 sb.append( TAB );
575                 sb.append( ForesterUtil.round( getMinimalSimilarityScore(), 3 ) );
576                 break;
577             case MAX:
578                 sb.append( TAB );
579                 sb.append( ForesterUtil.round( getMaximalSimilarityScore(), 3 ) );
580                 break;
581             case MEAN:
582                 sb.append( TAB );
583                 sb.append( ForesterUtil.round( getMeanSimilarityScore(), 3 ) );
584                 break;
585             case SD:
586                 sb.append( TAB );
587                 sb.append( ForesterUtil.round( getStandardDeviationOfSimilarityScore(), 3 ) );
588                 break;
589             case MAX_DIFFERENCE:
590                 sb.append( TAB );
591                 sb.append( getMaximalDifference() );
592             case ABS_MAX_COUNTS_DIFFERENCE:
593             case MAX_COUNTS_DIFFERENCE:
594                 sb.append( TAB );
595                 if ( isTreatAsBinaryComparison() ) {
596                     sb.append( getMaximalDifferenceInCounts() );
597                 }
598                 else {
599                     sb.append( Math.abs( getMaximalDifferenceInCounts() ) );
600                 }
601                 break;
602             case SPECIES_COUNT:
603                 sb.append( TAB );
604                 sb.append( getSpeciesData().size() );
605                 break;
606             case DOMAIN_ID:
607                 break;
608             default:
609                 throw new AssertionError( "Unknown sort method: " + getSortField() );
610         }
611         // ^^     if ( getGoAnnotationOutput() != DomainSimilarityCalculator.GoAnnotationOutput.NONE ) {
612         // ^^       sb.append( TAB );
613         // ^^       addGoInformation( sb, true, false );
614         // ^^   }
615         return sb;
616     }
617
618     public static enum PRINT_OPTION {
619         SIMPLE_TAB_DELIMITED, HTML;
620     }
621 }