org.openmolecules.chem.conf.gen.TorsionSetEncoder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of openchemlib Show documentation
Show all versions of openchemlib Show documentation
Open Source Chemistry Library
package org.openmolecules.chem.conf.gen;
import com.actelion.research.util.DoubleFormat;
public class TorsionSetEncoder {
private static final long[] BITS = { 0x00L, 0x01L, 0x03L, 0x07L, 0x0fL, 0x1fL, 0x3fL, 0x7fL };
private RigidFragment[] mRigidFragment;
private RotatableBond[] mRotatableBond;
private int mEncodingLongCount;
private int[] mEncodingBitCount;
private int[] mEncodingBitShift;
private int[] mEncodingLongIndex;
/**
* Creates a new encoder for TorsionSets (torsion and(!) rigid fragment indexes).
* The encoder is also used to encode elimination rules, which cover torsion indexes,
* but no rigid fragment indexes. Encoding of TorsionSets and EliminationRules
* facilitates fast matching of TorsionSets and sub-matching of EliminationRules.
* @param rigidFragment
* @param rotatableBond
*/
public TorsionSetEncoder(RigidFragment[] rigidFragment, RotatableBond[] rotatableBond) {
mRigidFragment = rigidFragment;
mRotatableBond = rotatableBond;
mEncodingBitCount = new int[rotatableBond.length+rigidFragment.length];
mEncodingBitShift = new int[rotatableBond.length+rigidFragment.length];
mEncodingLongIndex = new int[rotatableBond.length+rigidFragment.length];
int bitCount = 0;
int longIndex = 0;
int index = 0;
for (RotatableBond rb:rotatableBond) {
int bits = neededBits(rb.getTorsionCount());
if (bitCount + bits <= 64) {
mEncodingBitShift[index] = bitCount;
bitCount += bits;
}
else {
longIndex++;
mEncodingBitShift[index] = 0;
bitCount = 0;
}
mEncodingBitCount[index] = bits;
mEncodingLongIndex[index] = longIndex;
index++;
}
for (RigidFragment rf:rigidFragment) {
int bits = neededBits(rf.getConformerCount());
if (bitCount + bits <= 64) {
mEncodingBitShift[index] = bitCount;
bitCount += bits;
}
else {
longIndex++;
mEncodingBitShift[index] = 0;
bitCount = 0;
}
mEncodingBitCount[index] = bits;
mEncodingLongIndex[index] = longIndex;
index++;
}
mEncodingLongCount = longIndex+1;
}
public long[] encode(int[] torsionIndex, int[] conformerIndex) {
long[] mEncodedBits = new long[1 + mEncodingLongIndex[mEncodingLongIndex.length - 1]];
int i = 0;
for (int index:torsionIndex) {
mEncodedBits[mEncodingLongIndex[i]] += (index << mEncodingBitShift[i]);
i++;
}
for (int index:conformerIndex) {
mEncodedBits[mEncodingLongIndex[i]] += (index << mEncodingBitShift[i]);
i++;
}
return mEncodedBits;
}
public void encodeRule(int[] torsionIndex, int[] rotatableBondIndex, long[] mask, long[] data) {
for (int rb:rotatableBondIndex) {
data[mEncodingLongIndex[rb]] += (torsionIndex[rb] << mEncodingBitShift[rb]);
mask[mEncodingLongIndex[rb]] += (BITS[mEncodingBitCount[rb]] << mEncodingBitShift[rb]);
}
}
public int getEncodingLongCount() {
return mEncodingLongCount;
}
public boolean isMaskSet(TorsionSetEliminationRule rule, int torsionAndConformerIndex) {
return (rule.getMask()[mEncodingLongIndex[torsionAndConformerIndex]]
& (1L << mEncodingBitShift[torsionAndConformerIndex])) != 0L;
}
private int[] decodeRule(TorsionSetEliminationRule rule) {
int[] data = new int[mRotatableBond.length];
for (int rb=0; rb> mEncodingBitShift[rb]);
else
data[rb] = -1;
}
return data;
}
public String createRuleString(TorsionSetEliminationRule rule, BaseConformer baseConformer) {
StringBuilder sb = new StringBuilder();
int[] data = decodeRule(rule);
sb.append(" rb:");
int sl = sb.length();
for (int i=0; i 0) {
maxIndex >>= 1;
bits++;
}
return bits;
}
}