/* * This file is part of MoleculeViewer. * * MoleculeViewer is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * MoleculeViewer is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with MoleculeViewer. If not, see <http://www.gnu.org/licenses/>. */ package astex; /* Copyright Astex Technology Ltd. 1999 */ /* Copyright David Hall, Boston University, 2011 */ /* * 25-04-01 mjh * created */ import java.util.*; /** * Class for evaluating selection expressions. */ public class Selection { /** Residue names for aminoacids. */ public static List<String> aminoacidNames = new ArrayList<String>(30); /** Residue names for dna. */ public static List<String> dnaNames = new ArrayList<String>(15); /** Residue names for solvent. */ public static List<String> solventNames = new ArrayList<String>(5); /** Residue names for ions. */ public static List<String> ionNames = new ArrayList<String>(15); static { String names[] = { "aminoacid", "dna", "solvent", "ions" }; for(String name: names){ String value = (String)Settings.get("residue", name); if(value == null){ System.out.println("no residue definition for " + name); continue; } String residues[] = FILE.split(value, ","); if(residues == null) continue; for(int r = 0; r < residues.length; r++){ if("aminoacid".equals(name)){ aminoacidNames.add(residues[r]); }else if("dna".equals(name)){ dnaNames.add(residues[r]); }else if("solvent".equals(name)){ solventNames.add(residues[r]); }else if("ions".equals(name)){ ionNames.add(residues[r]); } } } } /** Generate a new selection mask. */ private static byte[] generateSelectionMask(MoleculeRenderer r){ int atomCount = r.getAtomCount(); // otherwise allocate one that is big enough // for a molecule twice as big. //return new byte[atomCount * 2]; return new byte[atomCount]; } public enum Operator { GT, GE, LT, LE, EQ, NE } /** Return a List from a selection mask. */ public static synchronized List<Atom> maskToList(MoleculeRenderer r, byte mask[]){ int atomCount = r.getAtomCount(); AtomIterator iterator = r.getAtomIterator(); int count = 0; ArrayList<Atom> selected = new ArrayList<Atom>(atomCount); while(iterator.hasMoreElements()){ Atom atom = iterator.getNextAtom(); if(mask[count++] > 0){ selected.add(atom); } } assert(count == atomCount); selected.trimToSize(); return selected; } /** Return a mask from a List. */ public static byte[] listToMask(MoleculeRenderer r, List<Atom> selectedAtoms){ int count = 0; AtomIterator iterator = r.getAtomIterator(); byte mask[] = generateSelectionMask(r); while(iterator.hasMoreElements()){ Atom atom = iterator.getNextAtom(); atom.setTemporarilySelected(false); } for(Atom a : selectedAtoms){ a.setTemporarilySelected(true); } iterator = r.getAtomIterator(); while(iterator.hasMoreElements()){ Atom atom = iterator.getNextAtom(); if(atom.isTemporarilySelected()){ mask[count] = 1; }else{ mask[count] = 0; } count++; } for(Atom a : selectedAtoms){ a.setTemporarilySelected(false); } return mask; } /** Select all the atoms. */ public static byte[] all(MoleculeRenderer r){ byte mask[] = generateSelectionMask(r); int atomCount = mask.length; for(int i = 0; i < atomCount; i++){ mask[i] = 1; } return mask; } /** Select all the atoms. */ public static byte[] none(MoleculeRenderer r){ byte mask[] = generateSelectionMask(r); int atomCount = mask.length; for(int i = 0; i < atomCount; i++){ mask[i] = 0; } return mask; } /** Select on the basis of an attribute. */ public static byte[] attribute(MoleculeRenderer r, int attribute, Operator operator, double value){ byte[] mask = generateSelectionMask(r); AtomIterator iterator = r.getAtomIterator(); int count = 0; while(iterator.hasMoreElements()){ Atom atom = iterator.getNextAtom(); double d = atom.getAttribute(attribute); switch(operator){ case GT: mask[count] = (byte)((d > value) ? 1 : 0); break; case GE: mask[count] = (byte)((d >= value) ? 1 : 0); break; case LT: mask[count] = (byte)((d < value) ? 1 : 0); break; case LE: mask[count] = (byte)((d <= value) ? 1 : 0); break; case EQ: mask[count] = (byte)((d == value) ? 1 : 0); break; case NE: mask[count] = (byte)((d != value) ? 1 : 0); break; default: System.out.println("attribute: unknown operator " + operator); break; } count++; } return mask; } /** Select a set of atoms on the basis of ids. */ public static byte[] residue(MoleculeRenderer r, List<Object> ids){ int minId = 1000000; int maxId = -1000000; int idCount = ids.size(); for(int i = 0; i < idCount; i++){ int range[] = (int[])ids.get(i); if(range[0] < minId){ minId = range[0]; } if(range[1] > maxId){ maxId = range[1]; } } byte[] mask = generateSelectionMask(r); int count = 0; // this can be done much more efficiently // by going through residues and setting blocks for(int m = 0; m < r.getMoleculeCount(); m++){ Molecule mol = r.getMolecule(m); int chainCount = mol.getChainCount(); for(int c = 0; c < chainCount; c++){ Chain chain = mol.getChain(c); int resCount = chain.getResidueCount(); for(int rid = 0; rid < resCount; rid++){ Residue res = chain.getResidue(rid); int number = res.getNumber(); int match = 0; if(number >= minId && number <= maxId){ // it could match for(int i = 0; i < idCount; i++){ int range[] = (int[])ids.get(i); if(number >= range[0] && number <= range[1]){ match = 1; break; } } } int residueAtomCount = res.getAtomCount(); if(match == 1){ for(int a = 0; a < residueAtomCount; a++){ mask[count] = (byte)match; count++; } }else{ count += residueAtomCount; } } } } return mask; } /** Select a set of atoms on the basis of ids. */ public static byte[] modulo(MoleculeRenderer r, int n){ byte[] mask = generateSelectionMask(r); int count = 0; // this can be done much more efficiently // by going through residues and setting blocks for(int m = 0; m < r.getMoleculeCount(); m++){ Molecule mol = r.getMolecule(m); int chainCount = mol.getChainCount(); for(int c = 0; c < chainCount; c++){ Chain chain = mol.getChain(c); int resCount = chain.getResidueCount(); for(int rid = 0; rid < resCount; rid++){ Residue res = chain.getResidue(rid); int number = res.getNumber(); int match = 0; if(number % n == 0){ match = 1; } int residueAtomCount = res.getAtomCount(); if(match == 1){ for(int a = 0; a < residueAtomCount; a++){ mask[count] = (byte)match; count++; } }else{ count += residueAtomCount; } } } } return mask; } /** Select a set of atoms on the basis of ids. */ public static byte[] composite(MoleculeRenderer r, List<Object> ids){ int idCount = ids.size(); byte[] mask = generateSelectionMask(r); for(int i = 0; i < idCount; i++){ StringBuilder chainBuffer = new StringBuilder(4); StringBuilder residueBuffer = new StringBuilder(4); StringBuilder insertionBuffer = new StringBuilder(1); String compositeString = (String)ids.get(i); int j; for(j = 0; j < compositeString.length(); j++){ char c = compositeString.charAt(j); if(c >= 'A' && c <= 'Z'){ chainBuffer.append(c); }else{ break; } } for(/* nothing */; j < compositeString.length(); j++){ char c = compositeString.charAt(j); if(c >= '0' && c <= '9'){ residueBuffer.append(c); }else{ break; } } for(/* nothing */; j < compositeString.length(); j++){ char c = compositeString.charAt(j); if(c >= 'A' && c <= 'Z'){ insertionBuffer.append(c); }else{ break; } } if(residueBuffer.length() == 0){ return mask; } byte chainMask[] = null; byte residueMask[] = null; byte insertionMask[] = null; List<Object> v = new ArrayList<Object>(1); if(chainBuffer.length() > 0){ v.clear(); v.add(chainBuffer.toString()); chainMask = chain(r, v); } if(residueBuffer.length() > 0){ int res[] = new int[2]; int resValue = FILE.readInteger(residueBuffer.toString()); res[0] = resValue; res[1] = resValue; v.clear(); v.add(res); residueMask = residue(r, v); } if(insertionBuffer.length() > 0){ insertionMask = insertion(r, insertionBuffer.toString()); } byte comp[] = null; if(chainMask != null){ comp = and(chainMask, residueMask); } if(comp == null){ comp = residueMask; } if(insertionMask != null){ comp = and(comp, insertionMask); } return comp; } return mask; } /** Select a set of atoms on the basis of ids. */ public static byte[] sequential(MoleculeRenderer r, List<Object> ids){ int minId = 1000000; int maxId = -1000000; int idCount = ids.size(); for(int i = 0; i < idCount; i++){ int range[] = (int[])ids.get(i); if(range[0] < minId){ minId = range[0]; } if(range[1] > maxId){ maxId = range[1]; } } byte[] mask = generateSelectionMask(r); int count = 0; // this can be done much more efficiently // by going through residues and setting blocks for(int m = 0; m < r.getMoleculeCount(); m++){ Molecule mol = r.getMolecule(m); int chainCount = mol.getChainCount(); for(int c = 0; c < chainCount; c++){ Chain chain = mol.getChain(c); int resCount = chain.getResidueCount(); for(int rid = 0; rid < resCount; rid++){ Residue res = chain.getResidue(rid); int number = res.getSequentialNumber(); int match = 0; if(number >= minId && number <= maxId){ // it could match for(int i = 0; i < idCount; i++){ int range[] = (int[])ids.get(i); if(number >= range[0] && number <= range[1]){ match = 1; break; } } } int residueAtomCount = res.getAtomCount(); if(match == 1){ for(int a = 0; a < residueAtomCount; a++){ mask[count] = (byte)match; count++; } }else{ count += residueAtomCount; } } } } return mask; } /** Select a set of atoms on the basis of insertion code. */ public static byte[] insertion(MoleculeRenderer r, String insertionCode){ char icode = insertionCode.charAt(0); byte[] mask = generateSelectionMask(r); int count = 0; // this can be done much more efficiently // by going through residues and setting blocks for(int m = 0; m < r.getMoleculeCount(); m++){ Molecule mol = r.getMolecule(m); int chainCount = mol.getChainCount(); for(int c = 0; c < chainCount; c++){ Chain chain = mol.getChain(c); int resCount = chain.getResidueCount(); for(int rid = 0; rid < resCount; rid++){ Residue res = chain.getResidue(rid); char thisInsertionCode = res.getInsertionCode(); int match = 0; if(thisInsertionCode == icode){ match = 1; } int residueAtomCount = res.getAtomCount(); if(match == 1){ // array should be cleared to 0's for(int a = 0; a < residueAtomCount; a++){ mask[count] = (byte)match; count++; } }else{ count += residueAtomCount; } } } } return mask; } /** Select a set of atoms on the basis of molecule name. */ public static byte[] molecule(MoleculeRenderer r, List<Object> ids){ int idCount = ids.size(); byte[] mask = generateSelectionMask(r); int count = 0; // this can be done much more efficiently int moleculeCount = r.getMoleculeCount(); for(int m = 0; m < moleculeCount; m++){ Molecule mol = r.getMolecule(m); byte matched = 0; for(int i = 0; i < idCount; i++){ String id = (String)ids.get(i); if(id.charAt(0) == '#'){ int molNumber = Integer.parseInt(id.substring(1)); if(molNumber == m){ matched = 1; break; } }else if(match.matches((String)ids.get(i), mol.getName())){ matched = 1; break; } } int atomCount = mol.getAtomCount(); if(matched == 1){ for(int a = 0; a < atomCount; a++){ mask[count++] = 1; } }else{ count += atomCount; } } return mask; } /** Select a set of atoms on the basis of molecule name. */ public static byte[] moleculeExact(MoleculeRenderer r, List<Object> ids){ int idCount = ids.size(); byte[] mask = generateSelectionMask(r); int count = 0; // this can be done much more efficiently int moleculeCount = r.getMoleculeCount(); for(int m = 0; m < moleculeCount; m++){ Molecule mol = r.getMolecule(m); byte matched = 0; for(int i = 0; i < idCount; i++){ if(((String)ids.get(i)).equals(mol.getName())){ matched = 1; break; } } int atomCount = mol.getAtomCount(); if(matched == 1){ for(int a = 0; a < atomCount; a++){ mask[count++] = 1; } }else{ count += atomCount; } } return mask; } /** Select a set of atoms on the basis of residue names. */ public static byte[] byresidue(MoleculeRenderer r, byte mask[]){ AtomIterator iterator = r.getAtomIterator(); int count = 0; while(iterator.hasMoreElements()){ Atom atom = iterator.getNextAtom(); if(mask[count] == 0){ atom.setTemporarilySelected(false); }else{ atom.setTemporarilySelected(true); } count++; } count = 0; int moleculeCount = r.getMoleculeCount(); for(int m = 0; m < moleculeCount; m++){ Molecule mol = r.getMolecule(m); int chainCount = mol.getChainCount(); for(int c = 0; c < chainCount; c++){ Chain chain = mol.getChain(c); int residueCount = chain.getResidueCount(); for(int rr = 0; rr < residueCount; rr++){ Residue residue = chain.getResidue(rr); int atomCount = residue.getAtomCount(); int residueSelected = 0; for(int a = 0; a < atomCount; a++){ Atom atom = residue.getAtom(a); if(atom.isTemporarilySelected()){ residueSelected = 1; break; } } for(int a = 0; a < atomCount; a++){ mask[count++] = (byte)residueSelected; } } } } return mask; } /** Select a set of atoms on the basis of residue names. */ public static byte[] bonded(MoleculeRenderer r, byte mask[]){ AtomIterator iterator = r.getAtomIterator(); int count = 0; while(iterator.hasMoreElements()){ Atom atom = iterator.getNextAtom(); atom.setTemporarilySelected(false); } iterator = r.getAtomIterator(); count = 0; while(iterator.hasMoreElements()){ Atom atom = iterator.getNextAtom(); if(mask[count] > 0){ int bondCount = atom.getBondCount(); for(int b = 0; b < bondCount; b++){ Atom bondedAtom = atom.getBondedAtom(b); bondedAtom.setTemporarilySelected(true); } } count++; } iterator = r.getAtomIterator(); count = 0; while(iterator.hasMoreElements()){ Atom atom = iterator.getNextAtom(); if(atom.isTemporarilySelected()){ mask[count] = 1; } count++; } return mask; } /** Select a set of atoms on the basis of residue names. */ public static byte[] name(MoleculeRenderer r, List<String> ids){ int idCount = ids.size(); byte[] mask = generateSelectionMask(r); int count = 0; // this can be done much more efficiently // by going through residues and setting blocks for(int m = 0; m < r.getMoleculeCount(); m++){ Molecule mol = r.getMolecule(m); int chainCount = mol.getChainCount(); for(int c = 0; c < chainCount; c++){ Chain chain = mol.getChain(c); int resCount = chain.getResidueCount(); for(int rid = 0; rid < resCount; rid++){ Residue res = chain.getResidue(rid); String name = res.getName(); int matched = 0; // it could match for(int i = 0; i < idCount; i++){ if(match.matches(ids.get(i), name)){ matched = 1; break; } } int residueAtomCount = res.getAtomCount(); if(matched == 1){ for(int a = 0; a < residueAtomCount; a++){ mask[count] = 1; count++; } }else{ count += residueAtomCount; } } } } return mask; } /** Select a set of atoms on the basis of residue names. */ public static byte[] chain(MoleculeRenderer r, List<Object> ids){ int idCount = ids.size(); byte[] mask = generateSelectionMask(r); AtomIterator iterator = r.getAtomIterator(); int count = 0; // this can be done much more efficiently // by going through residues and setting blocks while(iterator.hasMoreElements()){ Atom atom = iterator.getNextAtom(); Residue res = atom.getResidue(); Chain chain = res.getParent(); String name = chain.getName(); for(int i = 0; i < idCount; i++){ String chainId = (String)ids.get(i); if("_".equals(chainId)){ chainId = " "; } if(match.matches(chainId, name)){ mask[count] = 1; break; } } count++; } return mask; } /** Select a set of atoms on the basis of atom ids. */ public static byte[] atom(MoleculeRenderer r, List<Object> ids){ int idCount = ids.size(); byte[] mask = generateSelectionMask(r); AtomIterator iterator = r.getAtomIterator(); int count = 0; // this can be done much more efficiently // by going through residues and setting blocks while(iterator.hasMoreElements()){ Atom atom = iterator.getNextAtom(); String name = atom.getAtomLabel(); for(int i = 0; i < idCount; i++){ if(match.matches((String)ids.get(i), name)){ mask[count] = 1; break; } } count++; } return mask; } /** Select a set of atoms in a group. */ public static byte[] group(MoleculeRenderer r, HashSet<Atom> group){ byte[] mask = generateSelectionMask(r); AtomIterator iterator = r.getAtomIterator(); while(iterator.hasMoreElements()){ Atom atom = iterator.getNextAtom(); atom.setTemporarilySelected(false); } for (Atom atom: group){ atom.setTemporarilySelected(true); } int count = 0; iterator = r.getAtomIterator(); // this can be done much more efficiently // by going through residues and setting blocks while(iterator.hasMoreElements()){ Atom atom = iterator.getNextAtom(); if(atom.isTemporarilySelected()){ mask[count] = 1; }else{ mask[count] = 0; } count++; } return mask; } /** Select a set of atoms on the basis of ids. */ public static byte[] id(MoleculeRenderer r, List<Object> ids){ int minId = 1000000; int maxId = -1000000; int idCount = ids.size(); for(int i = 0; i < idCount; i++){ int range[] = (int[])ids.get(i); if(range[0] < minId){ minId = range[0]; } if(range[1] > maxId){ maxId = range[1]; } } byte[] mask = generateSelectionMask(r); AtomIterator iterator = r.getAtomIterator(); int count = 0; while(iterator.hasMoreElements()){ Atom atom = iterator.getNextAtom(); int number = atom.getId(); if(number >= minId && number <= maxId){ // it could match for(int i = 0; i < idCount; i++){ int range[] = (int[])ids.get(i); if(number >= range[0] && number <= range[1]){ mask[count] = 1; break; } } } count++; } return mask; } /** Select a set of atoms on the basis of elements. */ public static byte[] element(MoleculeRenderer r, List<Object> ids){ int minId = 1000000; int maxId = -1000000; int idCount = ids.size(); for(int i = 0; i < idCount; i++){ int range[] = (int[])ids.get(i); if(range[0] < minId){ minId = range[0]; } if(range[1] > maxId){ maxId = range[1]; } } byte[] mask = generateSelectionMask(r); AtomIterator iterator = r.getAtomIterator(); int count = 0; while(iterator.hasMoreElements()){ Atom atom = iterator.getNextAtom(); int number = atom.getElement(); if(number >= minId && number <= maxId){ // it could match for(int i = 0; i < idCount; i++){ int range[] = (int[])ids.get(i); if(number >= range[0] && number <= range[1]){ mask[count] = 1; break; } } } count++; } return mask; } /** Return the current selection. */ public static byte[] current(MoleculeRenderer r){ byte[] mask = generateSelectionMask(r); AtomIterator iterator = r.getAtomIterator(); int count = 0; while(iterator.hasMoreElements()){ Atom atom = iterator.getNextAtom(); if(atom.isSelected()){ mask[count] = 1; }else{ mask[count] = 0; } count++; } return mask; } /** Return atoms that have the specified property. */ public static byte[] property(MoleculeRenderer r, Atom.Attribute property){ byte[] mask = generateSelectionMask(r); AtomIterator iterator = r.getAtomIterator(); int count = 0; // this can be done much more efficiently // by going through residues and setting blocks while(iterator.hasMoreElements()){ Atom atom = iterator.getNextAtom(); if(atom.attributes.contains(property)){ mask[count] = 1; }else{ mask[count] = 0; } count++; } return mask; } /** * Return the atoms that are actively displayed. * Also check to see if the molecule that contains * the atom is displayed. * * Used to check the molecule display status as well * as the atom, but this was arguably wrong as it * could result in atoms in turned off molecueles * getting changed unexpectedly. */ public static byte[] displayed(MoleculeRenderer r){ byte[] mask = generateSelectionMask(r); AtomIterator iterator = r.getAtomIterator(); int count = 0; // this can be done much more efficiently // by going through residues and setting blocks while(iterator.hasMoreElements()){ Atom atom = iterator.getNextAtom(); if(atom.isDisplayed()){ mask[count] = 1; }else{ mask[count] = 0; } count++; } return mask; } /** Return the current selection. */ public static byte[] labelled(MoleculeRenderer r){ byte[] mask = generateSelectionMask(r); AtomIterator iterator = r.getAtomIterator(); int count = 0; // this can be done much more efficiently // by going through residues and setting blocks while(iterator.hasMoreElements()){ Atom atom = iterator.getNextAtom(); if(atom.isLabelled()){ mask[count] = 1; }else{ mask[count] = 0; } count++; } return mask; } /** * Return the default selection. * If any atoms are selected they are returned, * otherwise all atoms are returned. */ public static byte[] defaultSelection(MoleculeRenderer r){ byte[] mask = generateSelectionMask(r); AtomIterator iterator = r.getAtomIterator(); int count = 0; int selected = 0; // this can be done much more efficiently // by going through residues and setting blocks while(iterator.hasMoreElements()){ Atom atom = iterator.getNextAtom(); if(atom.isSelected()){ selected++; mask[count] = 1; }else{ mask[count] = 0; } count++; } if(selected == 0){ // nothing selected so return all. int maskCount = mask.length; for(int i = 0; i < maskCount; i++){ mask[i] = 1; } } return mask; } /** Return the current selection. */ public static byte[] wide(MoleculeRenderer r){ byte[] mask = generateSelectionMask(r); AtomIterator iterator = r.getAtomIterator(); int count = 0; // this can be done much more efficiently // by going through residues and setting blocks while(iterator.hasMoreElements()){ Atom atom = iterator.getNextAtom(); if(atom.isWide()){ mask[count] = 1; }else{ mask[count] = 0; } count++; } return mask; } /** Return a set of atoms withinin a sphere. */ public static byte[] sphere(MoleculeRenderer r, double rad, double x, double y, double z){ byte[] mask = generateSelectionMask(r); AtomIterator iterator = r.getAtomIterator(); int count = 0; double radSq = rad * rad; Point3d p = new Point3d(x, y, z); while(iterator.hasMoreElements()){ Atom atom = iterator.getNextAtom(); if(atom.distanceSquared(p) < radSq){ mask[count] = 1; }else{ mask[count] = 0; } count++; } return mask; } /** Return a set of atoms withinin a sphere. */ public static byte[] sphere(MoleculeRenderer r, double rad, byte sphereMask[]){ List<Atom> sphereSelection = maskToList(r, sphereMask); byte[] mask = generateSelectionMask(r); AtomIterator iterator = r.getAtomIterator(); int count = 0; double radSq = rad * rad; while(iterator.hasMoreElements()){ Atom atom = iterator.getNextAtom(); int inside = 0; for(Atom sphereAtom: sphereSelection){ if(atom.distanceSquared(sphereAtom) < radSq){ inside = 1; break; } } if(inside > 0){ mask[count] = 1; }else{ mask[count] = 0; } count++; } return mask; } /** Return a set of atoms withinin a tolerance of sum of vdw radii. */ public static byte[] contact(MoleculeRenderer r, double rad, byte sphereMask[]){ List<Atom> sphereSelection = maskToList(r, sphereMask); byte[] mask = generateSelectionMask(r); AtomIterator iterator = r.getAtomIterator(); int count = 0; while(iterator.hasMoreElements()){ Atom atom = iterator.getNextAtom(); double arad = atom.getVDWRadius() + rad; int inside = 0; for(Atom sphereAtom : sphereSelection){ double srad = sphereAtom.getVDWRadius(); double radSq = arad + srad; radSq *= radSq; if(atom.distanceSquared(sphereAtom) < radSq){ inside = 1; break; } } if(inside > 0){ mask[count] = 1; }else{ mask[count] = 0; } count++; } return mask; } /** Return a set of atoms in a connected graph. */ public static byte[] graph(MoleculeRenderer r, byte graphMask[]){ List<Atom> graphSelection = maskToList(r, graphMask); byte[] mask = generateSelectionMask(r); int count = 0; AtomIterator iterator = r.getAtomIterator(); while(iterator.hasMoreElements()){ Atom atom = iterator.getNextAtom(); atom.setTemporarilySelected(false); } for(Atom atom : graphSelection){ if(!atom.isTemporarilySelected()){ propagateGraph(atom); } } iterator = r.getAtomIterator(); while(iterator.hasMoreElements()){ Atom atom = iterator.getNextAtom(); if(atom.isTemporarilySelected()){ mask[count] = 1; }else{ mask[count] = 0; } count++; atom.setTemporarilySelected(false); } return mask; } /** Propagate the graph selection. */ private static void propagateGraph(Atom a){ int bondCount = a.getBondCount(); a.setTemporarilySelected(true); for(int i = 0; i < bondCount; i++){ Atom otherAtom = a.getBondedAtom(i); if(!otherAtom.isTemporarilySelected()){ propagateGraph(otherAtom); } } } /** And two selection masks together. */ public static byte[] and(byte mask1[], byte mask2[]){ int count = Math.min(mask1.length, mask2.length); for(int i = 0; i < count; i++){ if(mask1[i] > 0 && mask2[i] > 0){ mask1[i] = 1; }else{ mask1[i] = 0; } } // mask2 can just be garbage collected return mask1; } /** Or two selection masks together. */ public static byte[] or(byte mask1[], byte mask2[]){ int count = Math.min(mask1.length, mask2.length); for(int i = 0; i < count; i++){ if(mask1[i] > 0 || mask2[i] > 0){ mask1[i] = 1; }else{ mask1[i] = 0; } } // mask2 can just be garbage collected return mask1; } /** Not a selection mask. */ public static byte[] not(byte mask1[]){ int count = mask1.length; for(int i = 0; i < count; i++){ if(mask1[i] == 0){ mask1[i] = 1; }else{ mask1[i] = 0; } } return mask1; } /** Aminoacid expression. */ public static byte[] aminoacid(MoleculeRenderer r){ return name(r, aminoacidNames); } /** Solvent expression. */ public static byte[] solvent(MoleculeRenderer r){ return name(r, solventNames); } /** DNA expression. */ public static byte[] dna(MoleculeRenderer r){ return name(r, dnaNames); } /** Ions expression. */ public static byte[] ions(MoleculeRenderer r){ return name(r, ionNames); } }