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