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.symmetry.internal;
022
023import java.util.ArrayList;
024import java.util.Collections;
025import java.util.List;
026import java.util.Set;
027
028/**
029 * A ResidueGroup is a set of residues that are part of a maximally connected
030 * component of the self-Alignment Graph in symmetry analysis.
031 * <p>
032 * This class provides an interface for comparing and combining them to refine
033 * self-Alignments into consistent MultipleAlignments of repeats.
034 *
035 * @author Aleix Lafita
036 * @since 4.2.0
037 *
038 */
039public class ResidueGroup {
040
041        private final List<Integer> residues;
042
043        /**
044         * Create a ResidueGroup object from a maximally connected component.
045         *
046         * @param component
047         *            set of residues connected
048         */
049        public ResidueGroup(Set<Integer> component) {
050                // Transform component into sorted List of residues
051                residues = new ArrayList<Integer>(component);
052                Collections.sort(residues);
053        }
054
055        /**
056         * The order of symmetry of the group is the number of connected residues.
057         *
058         * @return size of residues List
059         */
060        public int order() {
061                return residues.size();
062        }
063
064        /**
065         * Determine if two Residuegroups (maximally connected components of the
066         * alignment Graph) are compatible, based in the following criterion:
067         *
068         * <pre>
069         * Two maximally connected components of the self-alignment Graph are
070         * compatible if they can be combined in a consistent multiple alignment
071         * of repeats, i.e.there exists one residue in c1 between each sorted
072         * pair of residues in c2.
073         * </pre>
074         *
075         * Compatibility is an intransitive relation, which means that for three
076         * ResidueGroups {A,B,C}, if A is compatible with B and B is compatible with
077         * C, then A is not necessarily compatible with C.
078         *
079         * @param c2
080         *            second maximally connected component
081         * @return true if compatible, false otherwise
082         */
083        public boolean isCompatible(ResidueGroup other) {
084
085                // Same order needed is necessary
086                if (this.order() != other.order())
087                        return false;
088
089                // Use the method of the smallest ResidueGroup
090                if (this.residues.get(0) > other.residues.get(0))
091                        return other.isCompatible(this);
092
093                // Check for intercalation of residues
094                for (int i = 0; i < order() - 1; i++) {
095                        if (other.residues.get(i) > residues.get(i + 1))
096                                return false;
097                        if (residues.get(i) > other.residues.get(i + 1))
098                                return false;
099                }
100
101                return true;
102        }
103
104        /**
105         * Combine the ResidueGroup with the alignment block.
106         *
107         * @param alignRes
108         *            the alignment block, will be modified.
109         */
110        public void combineWith(List<List<Integer>> alignRes) {
111                for (int i = 0; i < order(); i++)
112                        alignRes.get(i).add(residues.get(i));
113        }
114
115}