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