com.actelion.research.chem.descriptor.flexophore.MolDistHistViz 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
/*
* Copyright (c) 1997 - 2016
* Actelion Pharmaceuticals Ltd.
* Gewerbestrasse 16
* CH-4123 Allschwil, Switzerland
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of the the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @author Modest v. Korff
*/
package com.actelion.research.chem.descriptor.flexophore;
import com.actelion.research.calc.ArrayUtilsCalc;
import com.actelion.research.chem.*;
import com.actelion.research.chem.descriptor.flexophore.calculator.StructureCalculator;
import com.actelion.research.chem.descriptor.flexophore.generator.ConstantsFlexophoreGenerator;
import com.actelion.research.chem.interactionstatistics.InteractionAtomTypeCalculator;
import com.actelion.research.chem.phesa.pharmacophore.PharmacophoreCalculator;
import com.actelion.research.chem.phesa.pharmacophore.pp.IPharmacophorePoint;
import com.actelion.research.util.graph.complete.ICompleteGraph;
import java.io.Serializable;
import java.util.*;
/**
* Class for Flexophore visualization and atom tracking. Information about corresponding atoms is stored in PPNodeViz.
*/
public class MolDistHistViz extends DistHist implements Serializable, IMolDistHist, ICompleteGraph {
private static final long serialVersionUID = 15052013;
public static final int DESCRIBE_ALL = 1;
/**
* Only mapped atoms are described.
*/
public static final int DESCRIBE_MAPPED = 2;
public static final int CAPACITY_INEVITABLE_PPPOINTS = 5;
public static final String TAG_VIZ_INFO_ENCODED = "Flexophore2VizInfo";
private static final int MIN_COUNTS_BLURR = 3;
private static final double RATIO_BLURR = 1.0/5.0;
private static transient MDHIndexTables indexTables;
/**
* Colors for visualization of the Flexophore mapping.
*/
public static transient final String [] COLORS = {
"aquamarine",
"blue",
"violet",
"cyan",
"green",
"lavender",
"lime",
"limegreen",
"linen",
"magenta",
"maroon",
"olive",
"purple",
"red",
"tan",
"turquoise",
"yellow"};
private List liPPNodeViz;
protected Molecule3D molecule3D;
private int flagsDescribe;
// Exclusive C nodes
private int numCNodes;
private int numHeteroNodes;
private boolean finalized;
private HashSet hsIndexInevitablePPPoints;
// List of the original distance table generated by the conformations.
private List liDistanceTable;
private byte modeFlexophore;
public MolDistHistViz() {
super();
molecule3D = null;
flagsDescribe = DESCRIBE_ALL;
liPPNodeViz = new ArrayList<>();
hsIndexInevitablePPPoints = new HashSet<>();
modeFlexophore = ConstantsFlexophore.MODE_SOFT_PPPOINTS;
}
public MolDistHistViz(int nNodes) {
initHistogramArray(nNodes);
flagsDescribe = DESCRIBE_ALL;
hsIndexInevitablePPPoints = new HashSet<>();
modeFlexophore = ConstantsFlexophore.MODE_SOFT_PPPOINTS;
}
public MolDistHistViz(int nNodes, Molecule3D molecule3D) {
initHistogramArray(nNodes);
flagsDescribe = DESCRIBE_ALL;
if(molecule3D!=null) {
this.molecule3D = new Molecule3D(molecule3D);
this.molecule3D.ensureHelperArrays(Molecule.cHelperRings);
}
hsIndexInevitablePPPoints = new HashSet<>();
modeFlexophore = ConstantsFlexophore.MODE_SOFT_PPPOINTS;
}
public MolDistHistViz(MolDistHistViz mdhv) {
hsIndexInevitablePPPoints = new HashSet();
mdhv.copy(this);
flagsDescribe = DESCRIBE_ALL;
modeFlexophore = mdhv.modeFlexophore;
}
public MolDistHistViz(MolDistHist mdh) {
if(mdh.getNumPPNodes()==0){
throw new RuntimeException("Empty object given into constructor.");
}
mdh.copy(this);
modeFlexophore = mdh.getModeFlexophore();
liPPNodeViz=new ArrayList(mdh.getNumPPNodes());
for (int i = 0; i < mdh.getNumPPNodes(); i++) {
PPNodeViz node = new PPNodeViz(mdh.getNode(i));
liPPNodeViz.add(node);
}
hsIndexInevitablePPPoints = new HashSet();
realize();
}
public static void createIndexTables(){
indexTables = MDHIndexTables.getInstance();
}
public void addInevitablePharmacophorePoint(int indexPPNode){
hsIndexInevitablePPPoints.add(indexPPNode);
}
public void removeInevitablePharmacophorePoint(int indexPPNode){
hsIndexInevitablePPPoints.remove(indexPPNode);
}
public void setModeFlexophore(byte modeFlexophore) {
this.modeFlexophore = modeFlexophore;
for (PPNodeViz n : liPPNodeViz) {
n.setModeFlexophore(modeFlexophore);
}
}
public void setMarkAll(boolean mark){
for (PPNodeViz n : liPPNodeViz) {
n.setMarked(mark);
}
}
public void setMark(int index, boolean mark){
liPPNodeViz.get(index).setMarked(mark);
}
public boolean isMarked(int index){
return liPPNodeViz.get(index).isMarked();
}
/**
*
* @param node
* @return index of the node.
*/
public int addNode(PPNodeViz node) {
int index = liPPNodeViz.size();
node.setIndex(liPPNodeViz.size());
node.setModeFlexophore(modeFlexophore);
liPPNodeViz.add(node);
if(liPPNodeViz.size()>getNumPPNodes()){
throw new RuntimeException("To many nodes added!");
}
finalized = false;
return index;
}
public boolean check(){
boolean bOK = true;
int nodes = getNumPPNodes();
for (int i = 0; i < nodes; i++) {
PPNode node = getNode(i);
int ats = node.getInteractionTypeCount();
for (int j = 0; j < ats; j++) {
int inttype = node.getInteractionType(j);
String s = InteractionAtomTypeCalculator.getString(inttype);
if(s.length()==0) {
bOK = false;
}
}
}
return bOK;
}
protected void initHistogramArray(int size) {
super.initHistogramArray(size);
liPPNodeViz = new ArrayList<>();
finalized = false;
}
public MolDistHistViz copy(){
return new MolDistHistViz(this);
}
/**
*
* @param copy This is written into copy.
*/
public void copy(MolDistHistViz copy){
super.copy(copy);
copy.flagsDescribe = flagsDescribe;
if(molecule3D !=null)
copy.molecule3D = new Molecule3D(molecule3D);
copy.liPPNodeViz = new ArrayList();
for (int i = 0; i < liPPNodeViz.size(); i++) {
copy.liPPNodeViz.add(new PPNodeViz(liPPNodeViz.get(i)));
}
// Exclusive C nodes
copy.numCNodes=numCNodes;
copy.numHeteroNodes=numHeteroNodes;
copy.finalized=finalized;
copy.hsIndexInevitablePPPoints.clear();
copy.hsIndexInevitablePPPoints.addAll(hsIndexInevitablePPPoints);
}
/**
* Recalculates the coordinates off the pharmacophore nodes.
* Has to be called after changing the coordinates for the Molecule3D.
*/
public void recalculateCoordPPPoints(){
for (PPNodeViz ppNodeViz : liPPNodeViz) {
List liIndexAts = ppNodeViz.getListIndexOriginalAtoms();
int [] arrAtIndex = new int [liIndexAts.size()];
for (int i = 0; i < arrAtIndex.length; i++) {
arrAtIndex[i]=liIndexAts.get(i);
}
Coordinates [] arrCoordinates = new Coordinates [arrAtIndex.length];
for (int i = 0; i < arrAtIndex.length; i++) {
double x = molecule3D.getAtomX(arrAtIndex[i]);
double y = molecule3D.getAtomY(arrAtIndex[i]);
double z = molecule3D.getAtomZ(arrAtIndex[i]);
arrCoordinates[i] = new Coordinates(x, y, z);
}
Coordinates coordCenter = Coordinates.createBarycenter(arrCoordinates);
ppNodeViz.setCoordinates(coordCenter.x, coordCenter.y, coordCenter.z);
}
}
public void resetInevitablePharmacophorePoints(){
hsIndexInevitablePPPoints.clear();
}
public void resetInfoColor(){
int size = getNumPPNodes();
for (int i = 0; i < size; i++) {
PPNodeViz node = getNode(i);
node.resetInfoColor();
}
}
/**
* This index is used to track the fate of the nodes
* MvK 17.07.2007
*
*/
public void createNodeIndex(){
for (int i = 0; i < getNumPPNodes(); i++) {
getNode(i).setIndex(i);
}
}
/**
*
* @param index 0 or 1
* @param bond index of the bond array
* @return the atom index
*/
public int getBondAtom(int index, int bond) {
return indexTables.getAtomPairsBondsTable(getNumPPNodes())[index][bond];
// return mArrAtPairsBonds[index][bond];
}
public int getConnAtom(int at, int index) {
if(index >= at)
index++;
return index;
}
public int getConnBond(int at, int index) {
return indexTables.getConnectionTable(getNumPPNodes())[at][index];
}
public int getIndexFromCoord(double x, double y, double z) {
int index = -1;
Coordinates c = new Coordinates(x, y, z);
for (int i = 0; i < getNumPPNodes(); i++) {
PPNodeViz ppNodeViz = getNode(i);
if(ppNodeViz.getCoordinates().equals(c)){
index = i;
break;
}
}
return index;
}
public int getInfo(int index) {
return ((PPNodeViz)getNode(index)).getMappingIndex();
}
public PPNodeViz getNode(int i){
return liPPNodeViz.get(i);
}
/**
*
* @return shallow copy.
*/
public List getNodes(){
return liPPNodeViz;
}
public void set(List liPPNodeViz) {
this.liPPNodeViz = liPPNodeViz;
calculate();
}
/**
*
* @param ff has to be the molecule the descriptor was derived from.
*/
public void set(Molecule3D ff ){
if(ff!=null)
molecule3D = new Molecule3D(ff);
}
public void setMappingIndex(int index, int info) {
getNode(index).setMappingIndex(info);
}
public void setSimilarityMappingNodes(int index, float similarityMappingNodes) {
getNode(index).setSimilarityMappingNodes(similarityMappingNodes);
}
public String getName() {
return molecule3D.getName();
}
public void setName(String name) {
molecule3D.setName(name);
}
public boolean isOnlyCarbon(int index){
PPNode node = getNode(index);
boolean bOnlyCarbon = true;
for (int i = 0; i < node.getInteractionTypeCount(); i++) {
if(node.getAtomicNo(i) != 6)
bOnlyCarbon = false;
}
return bOnlyCarbon;
}
private int calcNumHeteroNodes(){
int num=0;
for (int i = 0; i < getNumPPNodes(); i++) {
PPNode node = getNode(i);
if(node.hasHeteroAtom())
num++;
}
return num;
}
public void canonize(){
for (int i = 0; i < liPPNodeViz.size(); i++) {
liPPNodeViz.get(i).realize();
liPPNodeViz.get(i).sortInteractionTypes();
}
boolean fin=false;
while(!fin){
fin=true;
for (int i = 1; i < liPPNodeViz.size(); i++) {
int cmp = compareNodes(i, i-1);
if(cmp<0){
fin=false;
swapNodes(i, i-1);
}
}
}
for (int i = 0; i < liPPNodeViz.size(); i++) {
liPPNodeViz.get(i).setIndex(i);
}
}
private int compareNodes(int n1, int n2){
int cmp=0;
// cmp = PPNode.compare(mArrNode[n1], mArrNode[n2]);
PPNode pp1 = liPPNodeViz.get(n1);
PPNode pp2 = liPPNodeViz.get(n2);
cmp = pp1.compareTo(pp2);
if(cmp==0){
// Here we compare the histograms
int size = getNumPPNodes()-1;
List liN1 = new ArrayList(size);
List liN2 = new ArrayList(size);
for (int i = 0; i < liPPNodeViz.size(); i++) {
if(i!=n1){
liN1.add(getDistHist(n1, i));
}
if(i!=n2){
liN2.add(getDistHist(n2, i));
}
}
class CmpHists implements Comparator {
public int compare(byte [] arr1, byte [] arr2) {
int cmp = 0;
for (int i = 0; i < arr1.length; i++) {
if(arr1[i]>arr2[i]) {
cmp = 1;
break;
} else if(arr1[i]arr2[i]) {
cmp = 1;
break;
} else if(arr1[i] getInevitablePharmacophorePoints(){
List li = new ArrayList(hsIndexInevitablePPPoints);
return li;
}
protected HashSet getHashSetIndexInevitablePPPoints() {
return hsIndexInevitablePPPoints;
}
public int getNumInevitablePharmacophorePoints(){
return hsIndexInevitablePPPoints.size();
}
public boolean isInevitablePharmacophorePoint(int indexNode){
return hsIndexInevitablePPPoints.contains(indexNode);
}
public boolean isAliphatic(int indexNode) {
boolean aliphatic = true;
PPNodeViz node = getNode(indexNode);
if(modeFlexophore==ConstantsFlexophore.MODE_HARD_PPPOINTS){
if(PharmacophoreCalculator.LIPO_ID == node.get()[0]){
aliphatic=true;
}
} else {
for (int i = 0; i < node.getInteractionTypeCount(); i++) {
if (node.getAtomicNo(i) != 6) {
aliphatic = false;
break;
}
}
}
return aliphatic;
}
public boolean isAcceptor(int indexNode) {
boolean acceptor = false;
PPNodeViz node = getNode(indexNode);
if(modeFlexophore==ConstantsFlexophore.MODE_HARD_PPPOINTS){
if(IPharmacophorePoint.Functionality.ACCEPTOR.getIndex()==node.get()[0]){
acceptor=true;
}
} else {
for (int i = 0; i < node.getInteractionTypeCount(); i++) {
if (node.getAtomicNo(i) == 8 || node.getAtomicNo(i) == 7) {
acceptor = true;
break;
}
}
}
return acceptor;
}
public boolean isDonor(int indexNode) {
boolean donor = false;
PPNodeViz node = getNode(indexNode);
if(modeFlexophore==ConstantsFlexophore.MODE_HARD_PPPOINTS){
if(IPharmacophorePoint.Functionality.DONOR.getIndex()==node.get()[0]){
donor=true;
}
} else {
List liIndexAtom = node.getListIndexOriginalAtoms();
StereoMolecule mol = new Molecule3D(molecule3D);
mol.ensureHelperArrays(Molecule.cHelperRings);
for (int indexAtom : liIndexAtom) {
if (mol.getAtomicNo(indexAtom) == 8 || mol.getAtomicNo(indexAtom) == 7) {
if (mol.getAllHydrogens(indexAtom) > 0) {
donor = true;
break;
}
}
}
}
return donor;
}
public boolean isAromatic(int indexNode) {
boolean aromatic = false;
PPNodeViz node = getNode(indexNode);
if(modeFlexophore==ConstantsFlexophore.MODE_HARD_PPPOINTS){
if(IPharmacophorePoint.Functionality.AROM_RING.getIndex()==node.get()[0]){
aromatic=true;
}
}
return aromatic;
}
public boolean isChargePos(int indexNode) {
boolean charge = false;
PPNodeViz node = getNode(indexNode);
if(modeFlexophore==ConstantsFlexophore.MODE_HARD_PPPOINTS){
if(IPharmacophorePoint.Functionality.POS_CHARGE.getIndex()==node.get()[0]){
charge=true;
}
}
return charge;
}
public boolean isChargeNeg(int indexNode) {
boolean charge = false;
PPNodeViz node = getNode(indexNode);
if(modeFlexophore==ConstantsFlexophore.MODE_HARD_PPPOINTS){
if(IPharmacophorePoint.Functionality.NEG_CHARGE.getIndex()==node.get()[0]){
charge=true;
}
}
return charge;
}
private int calcNumCExclusiveNodes(){
int num=0;
for (int i = 0; i < getNumPPNodes(); i++) {
PPNodeViz node = getNode(i);
if(node.isCarbonExclusiveNode())
num++;
}
return num;
}
/**
* Canonizes the {@link MolDistHistViz}
* Must be called after changes in the nodes or distance histograms.
*/
public void realize() {
for(PPNodeViz node : liPPNodeViz){
node.realize();
}
canonize();
calculate();
finalized=true;
}
public void blurrSingleBinHistograms(){
int size = getNumPPNodes();
byte [] arr = new byte [ConstantsFlexophoreGenerator.BINS_HISTOGRAM];
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if(i==j)
continue;
arr = getDistHist(i, j, arr);
int occupied=0;
int counts=0;
for (int k = 0; k < arr.length; k++) {
if(arr[k]>0){
occupied++;
counts+=arr[k];
}
}
if(occupied==1){
if( counts >= MIN_COUNTS_BLURR){
blurrSingleBinHistogram(arr);
setDistHist(i, j, arr);
}
}
}
}
}
private void blurrSingleBinHistogram(byte [] arr){
int pos = -1;
for (int i = 0; i < arr.length; i++) {
if(arr[i]>0){
pos = i;
break;
}
}
int countCenter = arr[pos];
if((pos==0) || (pos == arr.length-1)){
byte countCenterBlurred = (byte)(countCenter - (countCenter*RATIO_BLURR));
byte countBlurredBuddy = (byte)(countCenter*RATIO_BLURR);
if(pos==0) {
arr[0]=countCenterBlurred;
arr[1]=countBlurredBuddy;
}else if(pos==arr.length-1) {
arr[arr.length-1]=countCenterBlurred;
arr[arr.length-2]=countBlurredBuddy;
}
} else {
byte countCenterBlurred = (byte)(countCenter - (2.0 * countCenter*RATIO_BLURR));
byte countBlurredBuddy = (byte)(countCenter*RATIO_BLURR);
arr[pos-1]=countBlurredBuddy;
arr[pos]=countCenterBlurred;
arr[pos+1]=countBlurredBuddy;
}
}
public void calculate() {
numCNodes = calcNumCExclusiveNodes();
numHeteroNodes = calcNumHeteroNodes();
}
/**
* Remove all atoms without connections.
* @param mol
* @return
*/
protected static Molecule3D finalizeMolecule(Molecule3D mol) {
Molecule3D molecule3DCpy = new Molecule3D(mol);
molecule3DCpy.ensureHelperArrays(Molecule.cHelperRings);
HashSet hsAt2Del = new HashSet();
for (int i = 0; i < molecule3DCpy.getAllAtoms(); i++) {
if(molecule3DCpy.getConnAtoms(i)==0)
hsAt2Del.add(i);
}
List liAt2Del = new ArrayList(hsAt2Del);
Collections.sort(liAt2Del);
Collections.reverse(liAt2Del);
for (Integer at : liAt2Del) {
molecule3DCpy.deleteAtom(at);
}
return molecule3DCpy;
}
/**
*
* @return deep object.
*/
public MolDistHist getMolDistHist(){
realize();
int nPPNodes = getNumPPNodes();
MolDistHist mdh = new MolDistHist(nPPNodes);
for (int i = 0; i < nPPNodes; i++) {
mdh.addNode(getNode(i));
}
for (int i = 0; i < nPPNodes ; i++) {
for (int j = i+1; j < nPPNodes ; j++) {
mdh.setDistHist(i, j, getDistHist(i,j));
}
}
return mdh;
}
public double getMaximumDistanceInPPPoint(int indexNode) {
double maxDist = 0;
PPNodeViz node = getNode(indexNode);
List liIndexAtom = node.getListIndexOriginalAtoms();
List liCoord = new ArrayList();
for (int atom : liIndexAtom) {
Coordinates coord = molecule3D.getCoordinates(atom);
liCoord.add(coord);
}
for (int i = 0; i < liCoord.size(); i++) {
Coordinates c1 = liCoord.get(i);
for (int j = i+1; j < liCoord.size(); j++) {
Coordinates c2 = liCoord.get(j);
double dist = c1.distance(c2);
if(dist>maxDist){
maxDist = dist;
}
}
}
return maxDist;
}
/**
* The atoms of the ff molecule contain the corresponding PPNode indices in the first field of the PPP vector.
* @return
*/
public Molecule3D getMolecule() {
if(molecule3D == null)
return null;
return molecule3D;
}
public Molecule3D getMoleculeRemovedUnrelatedAtoms() {
Molecule3D ff = finalizeMolecule(molecule3D);
// Adds all atom indices
HashSet hsIndexUnique = new HashSet();
for(int i=0; i < getNumPPNodes(); i++){
PPNodeViz node = (PPNodeViz)getNode(i);
List liOriginalIndex = node.getListIndexOriginalAtoms();
hsIndexUnique.addAll(liOriginalIndex);
// int indAtom = ff.addAtom(26);
// ff.setCoordinates(indAtom, node.getCoordinates());
// ff.addBond(indAtom, liOriginalIndex.get(0), Molecule.cBondTypeSingle);
// hsIndexUnique.add(indAtom);
}
List liInd = new ArrayList(hsIndexUnique);
HashSet hsIndexOnPath = new HashSet();
for (int i = 0; i < liInd.size(); i++) {
for (int j = i+1; j < liInd.size(); j++) {
int [] arrIndAtoms = StructureCalculator.getAtomsOnPath(ff, liInd.get(i), liInd.get(j));
for (int k = 0; k < arrIndAtoms.length; k++) {
hsIndexOnPath.add(arrIndAtoms[k]);
}
}
}
hsIndexUnique.addAll(hsIndexOnPath);
for (int i = ff.getAllAtoms()-1; i >= 0; i--) {
if(!hsIndexUnique.contains(i)){
ff.deleteAtom(i);
}
}
return ff;
}
public int hashCode() {
String s = toString();
s = s.replace(" ", "");
return s.hashCode();
}
public String toStringInevitable() {
StringBuilder sb = new StringBuilder();
sb.append("Index inevitable ");
for (int index : hsIndexInevitablePPPoints) {
sb.append(index + " ");
}
sb.append("\n");
sb.append("Num inevitable " + hsIndexInevitablePPPoints.size());
return sb.toString();
}
/**
*
* @return A canonized representation of the object.
*/
public String toString(){
if(!finalized)
realize();
StringBuffer b = new StringBuffer();
b.append("[");
for (int i = 0; i < getNumPPNodes(); i++) {
b.append(getNode(i).toString());
if(i liDistanceTable){
this.liDistanceTable = new ArrayList();
for (double[][] ds : liDistanceTable) {
float [][] arrDT = new float [ds.length][ds.length];
for (int i = 0; i < ds.length; i++) {
for (int j = 0; j < ds.length; j++) {
arrDT[i][j]=(float)ds[i][j];
}
}
this.liDistanceTable.add(arrDT);
}
}
public List getDistanceTables() {
return liDistanceTable;
}
protected static String formatDescription(String s){
StringTokenizer st = new StringTokenizer(s, ",");
HashSet set = new HashSet();
while(st.hasMoreTokens()) {
String tok = st.nextToken().trim();
if(!set.contains(tok)){
set.add(tok);
}
}
List li = new ArrayList(set);
Collections.sort(li);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < li.size(); i++) {
if(i>0 && i < li.size()-1){
sb.append(",");
}
sb.append(li.get(i));
}
return sb.toString();
}
/**
* Merges the histograms from mdh into mdhviz.
* @param mdhviz has new histograms afterwards.
* @param mdh stays unchanged.
* @deprecated
*/
public static void merge(MolDistHistViz mdhviz, MolDistHist mdh){
if(mdh.getNumPPNodes()!=mdhviz.getNumPPNodes()) {
throw new RuntimeException("Size differs.");
}
for (int i = 0; i < mdh.getNumPPNodes(); i++) {
if(!mdh.getNode(i).equalAtoms(mdhviz.getNode(i))){
throw new RuntimeException("Node " + i + " differs. "+mdh.getNode(i)+"<>"+mdhviz.getNode(i)+" "+mdh.getNode(i).getAtomicNo(i)+" "+mdhviz.getNode(i).getAtomicNo(i));
}
}
for (int i = 0; i < mdh.getNumPPNodes(); i++) {
for (int j = 1+i; j < mdh.getNumPPNodes(); j++) {
mdhviz.setDistHist(i, j, mdh.getDistHist(i, j));
}
}
}
/**
* Summarizes alkane cluster. The central node may not be a alkane cluster.
* The interaction types of the cluster members are added to the interaction
* types of the center node.
* @param mdh
* @param maxDistance
* @return
*/
public static MolDistHistViz summarizeAlkaneCluster(MolDistHistViz mdh, int maxDistance) {
List liCluster = mdh.getClusterCenter(maxDistance);
List liIndexNode = new ArrayList();
for (int i = 0; i < mdh.getNumPPNodes(); i++) {
liIndexNode.add(i);
}
for (int i = 0; i < liCluster.size(); i++) {
ClusterNode cluster = liCluster.get(i);
PPNodeViz nodeCenter = mdh.getNode(cluster.getIndexCenter());
List liIndexClusterNode = cluster.getClusterMember();
for (int j = liIndexClusterNode.size()-1; j >= 0; j--) {
PPNode node = mdh.getNode(liIndexClusterNode.get(j));
if(node.isCarbonExclusiveNode()) {
liIndexNode.remove(liIndexClusterNode.get(j));
int sizeNode = node.getInteractionTypeCount();
boolean added=false;
for (int k = 0; k < sizeNode; k++) {
int interactionIdNode = node.getInteractionType(k);
if(!nodeCenter.containsInteractionID(interactionIdNode)) {
nodeCenter.add(interactionIdNode);
added=true;
}
}
if(added)
nodeCenter.realize();
}
}
}
MolDistHistViz mdhSummary = new MolDistHistViz(liIndexNode.size(), mdh.getMolecule());
for (int i = 0; i < liIndexNode.size(); i++) {
mdhSummary.addNode(mdh.getNode(liIndexNode.get(i)));
}
for (int i = 0; i < liIndexNode.size(); i++) {
for (int j = i+1; j < liIndexNode.size(); j++) {
mdhSummary.setDistHist(i, j, mdh.getDistHist(liIndexNode.get(i), liIndexNode.get(j)));
}
}
if(mdh.getDistanceTables() != null){
List liDistanceArrayNodes = mdh.getDistanceTables();
List liDistanceArrayNodesSummary = new ArrayList();
for (float[][] arrDistanceNodes : liDistanceArrayNodes) {
float[][] arrDistanceNodesSummary = new float [liIndexNode.size()][liIndexNode.size()];
for (int i = 0; i < liIndexNode.size(); i++) {
for (int j = 0; j < liIndexNode.size(); j++) {
arrDistanceNodesSummary[i][j]=arrDistanceNodes[liIndexNode.get(i)][liIndexNode.get(j)];
}
}
liDistanceArrayNodesSummary.add(arrDistanceNodesSummary);
}
mdhSummary.liDistanceTable = liDistanceArrayNodesSummary;
}
mdhSummary.realize();
return mdhSummary;
}
}