View Javadoc
1   // ******************************************************************************
2   //
3   // Title:       Force Field X.
4   // Description: Force Field X - Software for Molecular Biophysics.
5   // Copyright:   Copyright (c) Michael J. Schnieders 2001-2024.
6   //
7   // This file is part of Force Field X.
8   //
9   // Force Field X is free software; you can redistribute it and/or modify it
10  // under the terms of the GNU General Public License version 3 as published by
11  // the Free Software Foundation.
12  //
13  // Force Field X is distributed in the hope that it will be useful, but WITHOUT
14  // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16  // details.
17  //
18  // You should have received a copy of the GNU General Public License along with
19  // Force Field X; if not, write to the Free Software Foundation, Inc., 59 Temple
20  // Place, Suite 330, Boston, MA 02111-1307 USA
21  //
22  // Linking this library statically or dynamically with other modules is making a
23  // combined work based on this library. Thus, the terms and conditions of the
24  // GNU General Public License cover the whole combination.
25  //
26  // As a special exception, the copyright holders of this library give you
27  // permission to link this library with independent modules to produce an
28  // executable, regardless of the license terms of these independent modules, and
29  // to copy and distribute the resulting executable under terms of your choice,
30  // provided that you also meet, for each linked independent module, the terms
31  // and conditions of the license of that module. An independent module is a
32  // module which is not derived from or based on this library. If you modify this
33  // library, you may extend this exception to your version of the library, but
34  // you are not obligated to do so. If you do not wish to do so, delete this
35  // exception statement from your version.
36  //
37  // ******************************************************************************
38  package ffx.potential.bonded;
39  
40  import java.io.Serial;
41  import java.util.Enumeration;
42  import java.util.List;
43  import javax.swing.tree.TreeNode;
44  import org.jogamp.java3d.BranchGroup;
45  
46  /**
47   * The Joint class contains the geometry produced by the FGroup Joiner method.
48   *
49   * @author Michael J. Schnieders
50   * @since 1.0
51   */
52  public class Joint extends MSNode {
53  
54    @Serial
55    private static final long serialVersionUID = 1L;
56  
57    /** First group forming this Joint */
58    private final MSGroup group1;
59    /** Second group forming this Joint */
60    private final MSGroup group2;
61  
62    /** Default Constructor */
63    public Joint() {
64      super("Joint");
65      group1 = group2 = null;
66    }
67  
68    /**
69     * Constructor for Joint.
70     *
71     * @param name a {@link java.lang.String} object.
72     */
73    public Joint(String name) {
74      super(name);
75      group1 = group2 = null;
76    }
77  
78    /**
79     * Constructs a Joint between Group 1 and Group 2.
80     *
81     * @param group1 a {@link ffx.potential.bonded.MSGroup} object.
82     * @param group2 a {@link ffx.potential.bonded.MSGroup} object.
83     * @param bondNode a {@link ffx.potential.bonded.MSNode} object.
84     * @param angleNode a {@link ffx.potential.bonded.MSNode} object.
85     * @param stretchBendNode a {@link ffx.potential.bonded.MSNode} object.
86     * @param ureyBradleyNode a {@link ffx.potential.bonded.MSNode} object.
87     * @param outOfPlaneNode a {@link ffx.potential.bonded.MSNode} object.
88     * @param torsionNode a {@link ffx.potential.bonded.MSNode} object.
89     * @param improperTorsionNode a {@link ffx.potential.bonded.MSNode} object.
90     * @param stretchTorsionNode a {@link ffx.potential.bonded.MSNode} object.
91     * @param angleTorsionNode a {@link ffx.potential.bonded.MSNode} object.
92     * @param piOrbitalTorsionNode a {@link ffx.potential.bonded.MSNode} object.
93     * @param torsionTorsionNode a {@link ffx.potential.bonded.MSNode} object.
94     */
95    public Joint(MSGroup group1, MSGroup group2, MSNode bondNode, MSNode angleNode,
96        MSNode stretchBendNode, MSNode ureyBradleyNode, MSNode outOfPlaneNode, MSNode torsionNode,
97        MSNode improperTorsionNode, MSNode stretchTorsionNode, MSNode angleTorsionNode,
98        MSNode piOrbitalTorsionNode, MSNode torsionTorsionNode) {
99      super(group1 + "  " + group2);
100     this.group1 = group1;
101     this.group2 = group2;
102     if (bondNode != null && bondNode.getChildCount() != 0) {
103       add(bondNode);
104     }
105     if (angleNode != null && angleNode.getChildCount() != 0) {
106       add(angleNode);
107     }
108     if (stretchBendNode != null && stretchBendNode.getChildCount() != 0) {
109       add(stretchBendNode);
110     }
111     if (ureyBradleyNode != null && ureyBradleyNode.getChildCount() != 0) {
112       add(ureyBradleyNode);
113     }
114     if (outOfPlaneNode != null && outOfPlaneNode.getChildCount() != 0) {
115       add(outOfPlaneNode);
116     }
117     if (torsionNode != null && torsionNode.getChildCount() != 0) {
118       add(torsionNode);
119     }
120     if (improperTorsionNode != null && improperTorsionNode.getChildCount() != 0) {
121       add(improperTorsionNode);
122     }
123     if (stretchTorsionNode != null && stretchTorsionNode.getChildCount() != 0) {
124       add(stretchTorsionNode);
125     }
126     if (angleTorsionNode != null && angleTorsionNode.getChildCount() != 0) {
127       add(angleTorsionNode);
128     }
129     if (piOrbitalTorsionNode != null && piOrbitalTorsionNode.getChildCount() != 0) {
130       add(piOrbitalTorsionNode);
131     }
132     if (torsionTorsionNode != null && torsionTorsionNode.getChildCount() != 0) {
133       add(torsionTorsionNode);
134     }
135     refresh(null, null, null, null, null,
136         null, null, null, null, null, null);
137   }
138 
139   /**
140    * merge
141    *
142    * @param j a {@link ffx.potential.bonded.Joint} object.
143    */
144   public void merge(Joint j) {
145     if (!((group1 == j.group1 && group2 == j.group2)
146         || (group2 == j.group1 && group1 == j.group2))) {
147       return;
148     }
149     refresh(j.getNode(Bond.class), j.getNode(Angle.class), j.getNode(StretchBend.class),
150         j.getNode(UreyBradley.class), j.getNode(OutOfPlaneBend.class), j.getNode(Torsion.class),
151         j.getNode(ImproperTorsion.class), j.getNode(StretchTorsion.class),
152         j.getNode(AngleTorsion.class), j.getNode(PiOrbitalTorsion.class),
153         j.getNode(TorsionTorsion.class));
154   }
155 
156   /**
157    * setColor
158    *
159    * @param newColorModel a {@link ffx.potential.bonded.RendererCache.ColorModel} object.
160    */
161   public void setColor(RendererCache.ColorModel newColorModel) {
162     MSNode bonds = getNode(Bond.class);
163     if (bonds == null) {
164       return;
165     }
166     for (Enumeration<TreeNode> e = bonds.children(); e.hasMoreElements(); ) {
167       Bond b = (Bond) e.nextElement();
168       b.setColor(b.getAtom(0));
169       b.setColor(b.getAtom(1));
170     }
171   }
172 
173   /** {@inheritDoc} */
174   @Override
175   public void setView(RendererCache.ViewModel newViewModel, List<BranchGroup> newShapes) {
176     MSNode bonds = getNode(Bond.class);
177     if (bonds == null) {
178       return;
179     }
180     for (Enumeration<TreeNode> e = bonds.children(); e.hasMoreElements(); ) {
181       Bond b = (Bond) e.nextElement();
182       b.setView(newViewModel, newShapes);
183     }
184   }
185 
186   /**
187    * {@inheritDoc}
188    *
189    * <p>Overridden toString method returns: "Joint: m1 Name - m2 Name"
190    */
191   @Override
192   public String toString() {
193     return getName();
194   }
195 
196   /**
197    * Refresh the Joint.
198    *
199    * @param bonds Bond node.
200    * @param angles Angle node.
201    * @param stretchBends StretchBend node.
202    * @param ureyBradleys UreyBradley node.
203    * @param outOfPlaneBends OutOfPlaneBend node.
204    * @param torsions Torsion node.
205    * @param improperTorsions ImproperTorsion node.
206    * @param stretchTorsions StretchTorsion node.
207    * @param angleTorsions AngleTorsion node.
208    * @param piOrbitalTorsions PiOrbitalTorsion node.
209    * @param torsionTorsions TorsionTorsion node.
210    */
211   private void refresh(MSNode bonds, MSNode angles, MSNode stretchBends, MSNode ureyBradleys,
212       MSNode outOfPlaneBends, MSNode torsions, MSNode improperTorsions, MSNode stretchTorsions,
213       MSNode angleTorsions, MSNode piOrbitalTorsions, MSNode torsionTorsions) {
214 
215     // Loop over all children of the Joint.
216     for (Enumeration<TreeNode> e = children(); e.hasMoreElements(); ) {
217       MSNode jointChild = (MSNode) e.nextElement();
218       if (jointChild.getChildCount() == 0) {
219         jointChild.removeFromParent();
220         continue;
221       }
222       MSNode node = (MSNode) jointChild.getChildAt(0);
223 
224       if (node instanceof Bond) {
225         addAll("Bonds", jointChild, bonds);
226         bonds = null;
227       } else if (node instanceof Angle) {
228         addAll("Angles", jointChild, angles);
229         angles = null;
230       } else if (node instanceof StretchBend) {
231         addAll("Stretch-Bends", jointChild, stretchBends);
232         stretchBends = null;
233       } else if (node instanceof UreyBradley) {
234         addAll("Urey-Bradleys", jointChild, ureyBradleys);
235         ureyBradleys = null;
236       } else if (node instanceof OutOfPlaneBend) {
237         addAll("Out-of-Plane Bends", jointChild, outOfPlaneBends);
238         outOfPlaneBends = null;
239       } else if (node instanceof Torsion) {
240         addAll("Torsional Angles", jointChild, torsions);
241         torsions = null;
242       } else if (node instanceof ImproperTorsion) {
243         addAll("Improper Torsions", jointChild, improperTorsions);
244         improperTorsions = null;
245       } else if (node instanceof StretchTorsion) {
246         addAll("Stretch-Torsions", jointChild, stretchTorsions);
247         stretchTorsions = null;
248       } else if (node instanceof AngleTorsion) {
249         addAll("Angle-Torsions", jointChild, angleTorsions);
250         angleTorsions = null;
251       } else if (node instanceof PiOrbitalTorsion) {
252         addAll("Pi-Orbital Torsions", jointChild, piOrbitalTorsions);
253         piOrbitalTorsions = null;
254       } else if (node instanceof TorsionTorsion) {
255         addAll("Torsion-Torsions", jointChild, torsionTorsions);
256         torsionTorsions = null;
257       }
258     }
259 
260     if (bonds != null) {
261       add(bonds);
262     }
263     if (angles != null) {
264       add(angles);
265     }
266     if (stretchBends != null) {
267       add(stretchBends);
268     }
269     if (ureyBradleys != null) {
270       add(ureyBradleys);
271     }
272     if (outOfPlaneBends != null) {
273       add(outOfPlaneBends);
274     }
275     if (torsions != null) {
276       add(torsions);
277     }
278     if (improperTorsions != null) {
279       add(improperTorsions);
280     }
281     if (stretchTorsions != null) {
282       add(stretchTorsions);
283     }
284     if (angleTorsions != null) {
285       add(angleTorsions);
286     }
287     if (piOrbitalTorsions != null) {
288       add(piOrbitalTorsions);
289     }
290     if (torsionTorsions != null) {
291       add(torsionTorsions);
292     }
293   }
294 
295   /**
296    * Add all the children of the node to the parent.
297    *
298    * @param name Name of the parent.
299    * @param parent Parent node.
300    * @param node Node to add.
301    */
302   private void addAll(String name, MSNode parent, MSNode node) {
303     if (node == null) {
304       return;
305     }
306     for (MSNode bond : node.getChildList()) {
307       parent.add(bond);
308     }
309     parent.setName(name + " (" + parent.getChildCount() + ")");
310   }
311 
312   /**
313    * Get the Joint node for the specified class.
314    *
315    * @param clazz The class of the bonded term to search for.
316    * @return The Joint node for the specified class.
317    */
318   private MSNode getNode(Class<? extends BondedTerm> clazz) {
319     for (Enumeration<TreeNode> e = children(); e.hasMoreElements(); ) {
320       MSNode m = (MSNode) e.nextElement();
321       TreeNode node = m.getChildAt(0);
322       if (node.getClass().equals(clazz)) {
323         return m;
324       }
325     }
326     return null;
327   }
328 
329 }