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-2025.
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.terms;
39  
40  import ffx.potential.bonded.AngleTorsion;
41  import ffx.potential.bonded.BondedTerm;
42  
43  import java.util.ArrayList;
44  import java.util.Collection;
45  import java.util.Collections;
46  import java.util.List;
47  import java.util.logging.Logger;
48  
49  import static java.lang.String.format;
50  
51  /**
52   * Angle-Torsion potential energy term using {@link ffx.potential.bonded.AngleTorsion} instances.
53   */
54  public class AngleTorsionPotentialEnergy extends EnergyTerm {
55  
56    private static final Logger logger = Logger.getLogger(AngleTorsionPotentialEnergy.class.getName());
57  
58  
59    /**
60     * Internal list of AngleTorsion instances.
61     */
62    private final List<AngleTorsion> angleTorsions = new ArrayList<>();
63  
64    /**
65     * Create an AngleTorsionPotentialEnergy with the provided name.
66     *
67     * @param name Name for this term.
68     */
69    public AngleTorsionPotentialEnergy(String name) {
70      super(name);
71    }
72  
73    /**
74     * Create an AngleTorsionPotentialEnergy with the provided name and force group.
75     *
76     * @param name       Name for this term.
77     * @param forceGroup Integer force group identifier.
78     */
79    public AngleTorsionPotentialEnergy(String name, int forceGroup) {
80      super(name, forceGroup);
81    }
82  
83    /**
84     * Create an AngleTorsionPotentialEnergy initialized with a list of terms and force group.
85     *
86     * @param name          Name for this term.
87     * @param forceGroup    Force group identifier.
88     * @param angleTorsions List of AngleTorsion instances to add (null-safe).
89     */
90    public AngleTorsionPotentialEnergy(String name, int forceGroup, List<AngleTorsion> angleTorsions) {
91      super(name, forceGroup);
92      if (angleTorsions != null) {
93        Collections.sort(angleTorsions);
94        this.angleTorsions.addAll(angleTorsions);
95        logger.info(format("  Angle-Torsions:                    %10d", getNumberOfAngleTorsions()));
96      }
97    }
98  
99    /**
100    * {@inheritDoc}
101    */
102   @Override
103   public int getNumberOfTerms() {
104     return getNumberOfAngleTorsions();
105   }
106 
107   /**
108    * {@inheritDoc}
109    */
110   @Override
111   public BondedTerm[] getBondedTermsArray() {
112     return getAngleTorsionArray();
113   }
114 
115   /**
116    * Create an AngleTorsionPotentialEnergy initialized with a collection of terms.
117    *
118    * @param name          Name for this term (may be null).
119    * @param angleTorsions Collection of AngleTorsion instances to add (null-safe).
120    */
121   public AngleTorsionPotentialEnergy(String name, Collection<AngleTorsion> angleTorsions) {
122     super(name);
123     if (angleTorsions != null) {
124       this.angleTorsions.addAll(angleTorsions);
125     }
126   }
127 
128   /**
129    * Add an AngleTorsion to this term.
130    *
131    * @param angleTorsion AngleTorsion to add (ignored if null).
132    * @return true if it was added.
133    */
134   public boolean addAngleTorsion(AngleTorsion angleTorsion) {
135     if (angleTorsion == null) {
136       return false;
137     }
138     return angleTorsions.add(angleTorsion);
139   }
140 
141   /**
142    * Add an array of AngleTorsions to this term.
143    *
144    * @param angleTorsions Array of AngleTorsion instances to add.
145    * @return true if they were added.
146    */
147   public boolean addAngleTorsions(AngleTorsion[] angleTorsions) {
148     if (angleTorsions == null) {
149       return false;
150     }
151     Collections.addAll(this.angleTorsions, angleTorsions);
152     return true;
153   }
154 
155   /**
156    * Add a list of AngleTorsions to this term.
157    *
158    * @param angleTorsions List of AngleTorsion instances to add.
159    * @return true if they were added.
160    */
161   public boolean addAngleTorsions(List<AngleTorsion> angleTorsions) {
162     if (angleTorsions == null) {
163       return false;
164     }
165     this.angleTorsions.addAll(angleTorsions);
166     return true;
167   }
168 
169   /**
170    * Remove an AngleTorsion from this term.
171    *
172    * @param angleTorsion AngleTorsion to remove (ignored if null).
173    * @return true if it was present and removed.
174    */
175   public boolean removeAngleTorsion(AngleTorsion angleTorsion) {
176     if (angleTorsion == null) {
177       return false;
178     }
179     return angleTorsions.remove(angleTorsion);
180   }
181 
182   /**
183    * Get the AngleTorsion at a given index.
184    *
185    * @param index Index in the internal list.
186    * @return AngleTorsion at the specified index.
187    * @throws IndexOutOfBoundsException if index is invalid.
188    */
189   public AngleTorsion getAngleTorsion(int index) {
190     return angleTorsions.get(index);
191   }
192 
193   /**
194    * Get an unmodifiable view of the AngleTorsions in this term.
195    *
196    * @return Unmodifiable List of AngleTorsions.
197    */
198   public List<AngleTorsion> getAngleTorsions() {
199     return Collections.unmodifiableList(angleTorsions);
200   }
201 
202   /**
203    * Get an array of AngleTorsions in this term.
204    *
205    * @return Array of AngleTorsions.
206    */
207   public AngleTorsion[] getAngleTorsionArray() {
208     return angleTorsions.toArray(new AngleTorsion[0]);
209   }
210 
211   /**
212    * Get the number of AngleTorsions in this term.
213    *
214    * @return The number of AngleTorsions.
215    */
216   public int getNumberOfAngleTorsions() {
217     return angleTorsions.size();
218   }
219 
220   /**
221    * Log the details of Angle-Torsion interactions.
222    */
223   @Override
224   public void log() {
225     if (getNumberOfAngleTorsions() <= 0) {
226       return;
227     }
228     logger.info("\n Angle-Torsion Interactions:");
229     for (AngleTorsion angleTorsion : getAngleTorsions()) {
230       logger.info(" Angle-Torsion \t" + angleTorsion.toString());
231     }
232   }
233 
234   @Override
235   public String toPDBString() {
236     if (getNumberOfAngleTorsions() <= 0) {
237       return "";
238     }
239     return format("REMARK   3   %s %g (%d)\n", "ANGLE-TORSION              : ", getEnergy(), getNumberOfAngleTorsions());
240   }
241 
242   @Override
243   public String toString() {
244     return format("  %s %20.8f %12d %12.3f\n", "Angle-Torsion     ",
245         getEnergy(), getNumberOfAngleTorsions(), getTime());
246   }
247 }