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