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.bio.symbol; 022 023import java.util.HashMap; 024import java.util.Map; 025 026import org.biojava.bio.seq.DNATools; 027 028/** 029 * <p> 030 * A factory that is used to maintain associations between alphabets and 031 * preferred bit-packings for them. 032 * </p> 033 * 034 * <p> 035 * There are many ways to pack the symbols for an alphabet as binary. 036 * Different applications will wish to have different representations for 037 * reasons such as integration with external formats, whether to store 038 * ambiguity or not and what algorithms may be used on the bit-packed 039 * representation. Also, it has utility methods to arrange the bit-strings 040 * for symbols within a Java int primitive. 041 * </p> 042 * 043 * @author Matthew Pocock 044 * @author Thomas Down 045 */ 046public class PackingFactory { 047 private final static Map packForAlpha; 048 049 static { 050 packForAlpha = new HashMap(); 051 052 } 053 054 /** 055 * Get the default packing for an alphabet. 056 * 057 * @param alpha the FiniteAlphabet that will be bit-packed 058 * @param ambiguity true if the packing should store ambiguity and false 059 * if it can discard ambiguity information 060 * @throws IllegalAlphabetException if this combination of alphabet and 061 * ambiguity can not be handled 062 **/ 063 public static Packing getPacking(FiniteAlphabet alpha, boolean ambiguity) 064 throws IllegalAlphabetException { 065 Packing pack = (Packing) packForAlpha.get(alpha); 066 if(pack == null) { 067 if(alpha == DNATools.getDNA()) { 068 if(ambiguity) { 069 pack = new DNAAmbPack(); 070 } else { 071 pack = new DNANoAmbPack(DNATools.a()); 072 } 073 } else { 074 if(ambiguity) { 075 // can't handle this in the general case 076 throw new IllegalAlphabetException(); 077 } else { 078 pack = new IndexedNoAmbPack(AlphabetManager.getAlphabetIndex(alpha)); 079 } 080 } 081 } 082 return pack; 083 } 084 085 public static int primeWord( 086 SymbolList symList, 087 int wordLength, 088 Packing packing 089 ) throws IllegalSymbolException { 090 int word = 0; 091 for(int i = 0; i < wordLength; i++) { 092 int p = packing.pack(symList.symbolAt(i+1)); 093 word |= (int) ((int) p << (int) (i * packing.wordSize())); 094 } 095 return word; 096 } 097 098 public static int nextWord( 099 SymbolList symList, 100 int word, 101 int offset, 102 int wordLength, 103 Packing packing 104 ) throws IllegalSymbolException { 105 word = word >> (int) packing.wordSize(); 106 int p = packing.pack(symList.symbolAt(offset)); 107 word |= (int) p << ((int) (wordLength - 1) * packing.wordSize()); 108 return word; 109 } 110 111 public static void binary(long val) { 112 for(int i = 63; i >= 0; i--) { 113 System.out.print( ((((val >> i) & 1) == 1) ? 1 : 0) ); 114 } 115 System.out.println(); 116 } 117 public static void binary(int val) { 118 for(int i = 31; i >= 0; i--) { 119 System.out.print( ((((val >> i) & 1) == 1) ? 1 : 0) ); 120 } 121 System.out.println(); 122 } 123} 124