Clover icon

Coverage Report

  1. Project Clover database Wed Feb 4 2026 17:46:51 GMT
  2. Package jalview.analysis

File TreeBuilder.java

 

Coverage histogram

../../img/srcFileCovDistChart8.png
21% of files have more coverage

Code metrics

18
61
12
1
255
148
23
0.38
5.08
12
1.92

Classes

Class Line # Actions
TreeBuilder 41 61 23
0.802197880.2%
 

Contributing tests

This file is covered by 1 test. .

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
7    * Jalview is free software: you can redistribute it and/or
8    * modify it under the terms of the GNU General Public License
9    * as published by the Free Software Foundation, either version 3
10    * of the License, or (at your option) any later version.
11    *
12    * Jalview is distributed in the hope that it will be useful, but
13    * WITHOUT ANY WARRANTY; without even the implied warranty
14    * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15    * PURPOSE. See the GNU General Public License for more details.
16    *
17    * You should have received a copy of the GNU General Public License
18    * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19    * The Jalview Authors are detailed in the 'AUTHORS' file.
20    */
21    package jalview.analysis;
22   
23    import jalview.api.analysis.ScoreModelI;
24    import jalview.api.analysis.SimilarityParamsI;
25    import jalview.datamodel.AlignmentAnnotation;
26    import jalview.datamodel.AlignmentView;
27    import jalview.datamodel.BinaryNode;
28    import jalview.datamodel.CigarArray;
29    import jalview.datamodel.SeqCigar;
30    import jalview.datamodel.SequenceI;
31    import jalview.datamodel.SequenceNode;
32    import jalview.viewmodel.AlignmentViewport;
33   
34   
35    import java.util.ArrayList;
36    import java.util.BitSet;
37    import java.util.HashMap;
38    import java.util.List;
39    import java.util.Vector;
40   
 
41    public abstract class TreeBuilder extends TreeEngine
42    {
43    public static final String AVERAGE_DISTANCE = "AV";
44   
45    public static final String NEIGHBOUR_JOINING = "NJ";
46   
47    protected SequenceI[] sequences;
48   
49    protected List<String> labels;
50   
51    // Map to store node pos : annotation details
52    // (additional details from annotation property)
53    protected HashMap<Integer, String> annotationDetails;
54   
55    ArrayList<AlignmentAnnotation> ssAnnotationForSeqs;
56   
57    public AlignmentView seqData;
58   
59    private AlignmentView seqStrings;
60   
61    /**
62    * Constructor
63    *
64    * @param av
65    * @param sm
66    * @param scoreParameters
67    */
 
68  1 toggle public TreeBuilder(AlignmentViewport av, ScoreModelI sm,
69    SimilarityParamsI scoreParameters)
70    {
71  1 int start, end;
72  1 boolean selview = av.getSelectionGroup() != null
73    && av.getSelectionGroup().getSize() >= 1;
74  1 seqStrings = av.getAlignmentView(selview);
75    // FIXME @RENIA - we should check that there are enough annotation tracks to
76    // build a tree!
77  1 if (!selview)// && !sm.isSecondaryStructure())
78    {
79  0 start = 0;
80  0 end = av.getAlignment().getWidth();
81  0 this.sequences = av.getAlignment().getSequencesArray();
82    }
83    else
84    {
85  1 start = av.getSelectionGroup().getStartRes();
86  1 end = av.getSelectionGroup().getEndRes() + 1;
87  1 this.sequences = av.getSelectionGroup()
88    .getSequencesInOrder(av.getAlignment());
89    }
90   
91  1 init(seqStrings, start, end);
92   
93  1 computeTree(sm, scoreParameters);
94    }
95   
 
96  1 toggle public SequenceI[] getSequences()
97    {
98  1 return sequences;
99    }
100   
101    /**
102    *
103    * @return true if tree has real distances
104    */
 
105  1 toggle public boolean hasDistances()
106    {
107  1 return true;
108    }
109   
110    /**
111    *
112    * @return true if tree has real bootstrap values
113    */
 
114  1 toggle public boolean hasBootstrap()
115    {
116  1 return false;
117    }
118   
 
119  1 toggle public boolean hasRootDistance()
120    {
121  1 return true;
122    }
123   
 
124  1 toggle public List<String> getLabels(){
125  1 return this.labels;
126    }
127   
128    /**
129    * Initializes the data structures used to hold secondary structure
130    * and metadata during the tree building process.
131    */
 
132  1 toggle private void initAnnotationData() {
133  1 this.labels = new ArrayList<>();
134  1 this.annotationDetails = new HashMap<>();
135  1 this.ssAnnotationForSeqs = new ArrayList<>();
136    }
137   
138    /**
139    * Calculates the tree using the given score model and parameters, and the
140    * configured tree type
141    * <p>
142    * If the score model computes pairwise distance scores, then these are used
143    * directly to derive the tree
144    * <p>
145    * If the score model computes similarity scores, then the range of the scores
146    * is reversed to give a distance measure, and this is used to derive the tree
147    *
148    * @param sm
149    * @param scoreOptions
150    */
 
151  1 toggle protected void computeTree(ScoreModelI sm, SimilarityParamsI scoreOptions)
152    {
153  1 initAnnotationData();
154  1 sequences = sm.expandSeqData(sequences, seqData, scoreOptions,
155    labels, ssAnnotationForSeqs, annotationDetails);
156  1 noseqs = sequences.length;
157   
158  1 distances = sm.findDistances(seqData, scoreOptions);
159   
160  1 makeLeaves();
161   
162  1 noClus = clusters.size();
163   
164  1 cluster();
165    }
166   
 
167  1 toggle protected void init(AlignmentView seqView, int start, int end)
168    {
169  1 this.node = new Vector<BinaryNode>();
170  1 if (seqView != null)
171    {
172  1 this.seqData = seqView;
173    }
174    else
175    {
176  0 SeqCigar[] seqs = new SeqCigar[sequences.length];
177  0 for (int i = 0; i < sequences.length; i++)
178    {
179  0 seqs[i] = new SeqCigar(sequences[i], start, end);
180    }
181  0 CigarArray sdata = new CigarArray(seqs);
182  0 sdata.addOperation(CigarArray.M, end - start + 1);
183  0 this.seqData = new AlignmentView(sdata, start);
184    }
185   
186    /*
187    * count the non-null sequences
188    */
189  1 noseqs = 0;
190   
191  1 done = new BitSet();
192   
193  1 for (SequenceI seq : sequences)
194    {
195  15 if (seq != null)
196    {
197  15 noseqs++;
198    }
199    }
200    }
201   
202    /**
203    * Attaches annotation and metadata to a specific tree node.
204    * @param sn The SequenceNode (leaf) being processed
205    * @param index The index of the sequence in the alignment
206    */
 
207  18 toggle private void applyAnnotationsToNode(SequenceNode sn, int index) {
208  18 if (ssAnnotationForSeqs != null && index < ssAnnotationForSeqs.size()) {
209  18 AlignmentAnnotation aa = ssAnnotationForSeqs.get(index);
210  18 if (aa != null) {
211  4 sn.setAlignmentAnnotation(aa);
212   
213  4 String detail = annotationDetails.get(index);
214  4 if (detail != null && !detail.isEmpty()) {
215  0 sn.setAnnotationDetails(detail);
216    }
217    }
218    }
219    }
220   
221    /**
222    * Start by making a cluster for each individual sequence
223    */
 
224  1 toggle void makeLeaves()
225    {
226  1 clusters = new Vector<BitSet>();
227   
228  19 for (int i = 0; i < noseqs; i++)
229    {
230  18 SequenceNode sn = new SequenceNode();
231   
232  18 sn.setElement(sequences[i]);
233   
234  18 if (labels.size() == noseqs)
235    {
236  18 sn.setLabel(labels.get(i));
237    }
238   
239  18 applyAnnotationsToNode(sn, i);
240   
241  18 sn.setName(sequences[i].getName());
242   
243  18 node.addElement(sn);
244  18 BitSet bs = new BitSet();
245  18 bs.set(i);
246  18 clusters.addElement(bs);
247    }
248    }
249   
 
250  1 toggle public AlignmentView getOriginalData()
251    {
252  1 return seqStrings;
253    }
254   
255    }