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