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 * @return BlockImpl a BlockImpl instance linked to its parent BlockSet. 056 */ 057 public BlockImpl(BlockSet blockSet) { 058 059 parent = blockSet; 060 if (parent != null) 061 parent.getBlocks().add(this); 062 alignRes = null; 063 coreLength = -1; // Value -1 indicates not yet calculated. 064 alignResCounts = null; // Value null not yet calculated 065 } 066 067 /** 068 * Copy constructor. 069 * 070 * @param b 071 * BlockImpl object to be copied. 072 * @return BlockImpl an identical copy of the input BlockImpl object. 073 */ 074 public BlockImpl(BlockImpl b) { 075 076 super(b); // This copies the cached scores 077 this.parent = b.parent; 078 this.coreLength = b.coreLength; 079 080 this.alignRes = null; 081 if (b.alignRes != null) { 082 // Make a deep copy of everything 083 alignRes = new ArrayList<List<Integer>>(); 084 for (int k = 0; k < b.size(); k++) { 085 alignRes.add(new ArrayList<Integer>(b.alignRes.get(k))); 086 } 087 } 088 } 089 090 @Override 091 public Block clone() { 092 return new BlockImpl(this); 093 } 094 095 @Override 096 public void clear() { 097 super.clear(); 098 coreLength = -1; 099 alignResCounts = null; 100 } 101 102 @Override 103 public String toString() { 104 return "BlockImpl [alignRes=" + alignRes + ", coreLength=" + coreLength 105 + "]"; 106 } 107 108 @Override 109 public void setBlockSet(BlockSet parent) { 110 this.parent = parent; 111 } 112 113 @Override 114 public BlockSet getBlockSet() { 115 return parent; 116 } 117 118 @Override 119 public List<List<Integer>> getAlignRes() { 120 return alignRes; 121 } 122 123 @Override 124 public void setAlignRes(List<List<Integer>> alignRes) { 125 this.alignRes = alignRes; 126 } 127 128 @Override 129 public int length() { 130 if (alignRes == null) 131 return 0; 132 if (alignRes.size() == 0) 133 return 0; 134 return alignRes.get(0).size(); 135 } 136 137 @Override 138 public int size() { 139 return alignRes.size(); 140 } 141 142 @Override 143 public int getCoreLength() { 144 if (coreLength == -1) 145 updateCoreLength(); 146 return coreLength; 147 } 148 149 protected void updateCoreLength() { 150 coreLength = MultipleAlignmentTools.getCorePositions(this).size(); 151 } 152 153 @Override 154 public int getStartIndex(int str) { 155 int index = -1; 156 Integer start = null; 157 while (start == null && index < alignRes.get(str).size()) { 158 index++; 159 start = alignRes.get(str).get(index); 160 } 161 return index; 162 } 163 164 @Override 165 public int getStartResidue(int str) { 166 return alignRes.get(str).get(getStartIndex(str)); 167 } 168 169 @Override 170 public int getFinalIndex(int str) { 171 int index = alignRes.get(str).size(); 172 Integer end = null; 173 while (end == null && index >= 0) { 174 index--; 175 end = alignRes.get(str).get(index); 176 } 177 return index; 178 } 179 180 @Override 181 public int getFinalResidue(int str) { 182 return alignRes.get(str).get(getFinalIndex(str)); 183 } 184 185 @Override 186 public List<Integer> getAlignResCounts() { 187 188 if (alignResCounts != null) 189 return alignResCounts; 190 191 alignResCounts = new ArrayList<Integer>(size()); 192 for (int s = 0; s < size(); s++) { 193 int count = 0; 194 for (int r = 0; r < length(); r++) { 195 if (alignRes.get(s).get(r) != null) 196 count++; 197 } 198 alignResCounts.add(count); 199 } 200 return alignResCounts; 201 } 202 203}