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.align.multiple; 022 023import java.io.Serializable; 024import java.util.ArrayList; 025import java.util.List; 026 027import org.biojava.nbio.structure.align.multiple.util.MultipleAlignmentTools; 028 029/** 030 * General implementation of a {@link Block} that supports any type of 031 * sequential alignment with gaps. 032 * 033 * @author Aleix Lafita 034 * @since 4.1.0 035 * 036 */ 037public class BlockImpl extends AbstractScoresCache implements Serializable, 038 Block, Cloneable { 039 040 private static final long serialVersionUID = -5804042669466177641L; 041 042 private BlockSet parent; 043 private List<List<Integer>> alignRes; 044 045 // CACHE 046 private int coreLength; 047 private List<Integer> alignResCounts; 048 049 /** 050 * Constructor. Links also the parent to this instance, by adding the Block 051 * to the parent's list. 052 * 053 * @param blockSet 054 * the parent BlockSet of the BlockImpl instance. 055 */ 056 public BlockImpl(BlockSet blockSet) { 057 058 parent = blockSet; 059 if (parent != null) 060 parent.getBlocks().add(this); 061 alignRes = null; 062 coreLength = -1; // Value -1 indicates not yet calculated. 063 alignResCounts = null; // Value null not yet calculated 064 } 065 066 /** 067 * Copy constructor. 068 * 069 * @param b 070 * BlockImpl object to be copied. 071 */ 072 public BlockImpl(BlockImpl b) { 073 074 super(b); // This copies the cached scores 075 this.parent = b.parent; 076 this.coreLength = b.coreLength; 077 078 this.alignRes = null; 079 if (b.alignRes != null) { 080 // Make a deep copy of everything 081 alignRes = new ArrayList<>(); 082 for (int k = 0; k < b.size(); k++) { 083 alignRes.add(new ArrayList<Integer>(b.alignRes.get(k))); 084 } 085 } 086 } 087 088 @Override 089 public Block clone() { 090 return new BlockImpl(this); 091 } 092 093 @Override 094 public void clear() { 095 super.clear(); 096 coreLength = -1; 097 alignResCounts = null; 098 } 099 100 @Override 101 public String toString() { 102 return "BlockImpl [alignRes=" + alignRes + ", coreLength=" + coreLength 103 + "]"; 104 } 105 106 @Override 107 public void setBlockSet(BlockSet parent) { 108 this.parent = parent; 109 } 110 111 @Override 112 public BlockSet getBlockSet() { 113 return parent; 114 } 115 116 @Override 117 public List<List<Integer>> getAlignRes() { 118 return alignRes; 119 } 120 121 @Override 122 public void setAlignRes(List<List<Integer>> alignRes) { 123 this.alignRes = alignRes; 124 } 125 126 @Override 127 public int length() { 128 if (alignRes == null) 129 return 0; 130 if (alignRes.size() == 0) 131 return 0; 132 return alignRes.get(0).size(); 133 } 134 135 @Override 136 public int size() { 137 return alignRes.size(); 138 } 139 140 @Override 141 public int getCoreLength() { 142 if (coreLength == -1) 143 updateCoreLength(); 144 return coreLength; 145 } 146 147 protected void updateCoreLength() { 148 coreLength = MultipleAlignmentTools.getCorePositions(this).size(); 149 } 150 151 @Override 152 public int getStartIndex(int str) { 153 int index = -1; 154 Integer start = null; 155 while (start == null && index < alignRes.get(str).size()) { 156 index++; 157 start = alignRes.get(str).get(index); 158 } 159 return index; 160 } 161 162 @Override 163 public int getStartResidue(int str) { 164 return alignRes.get(str).get(getStartIndex(str)); 165 } 166 167 @Override 168 public int getFinalIndex(int str) { 169 int index = alignRes.get(str).size(); 170 Integer end = null; 171 while (end == null && index >= 0) { 172 index--; 173 end = alignRes.get(str).get(index); 174 } 175 return index; 176 } 177 178 @Override 179 public int getFinalResidue(int str) { 180 return alignRes.get(str).get(getFinalIndex(str)); 181 } 182 183 @Override 184 public List<Integer> getAlignResCounts() { 185 186 if (alignResCounts != null) 187 return alignResCounts; 188 189 alignResCounts = new ArrayList<>(size()); 190 for (int s = 0; s < size(); s++) { 191 int count = 0; 192 for (int r = 0; r < length(); r++) { 193 if (alignRes.get(s).get(r) != null) 194 count++; 195 } 196 alignResCounts.add(count); 197 } 198 return alignResCounts; 199 } 200 201}