root/src/globalsearch/structure.h @ 06f244abd607a7c31b6ed64e2a2c378638e727d2

Revision 06f244abd607a7c31b6ed64e2a2c378638e727d2, 38.4 KB (checked in by David C. Lonie <loniedavid@…>, 13 months ago)

Added a preoptimization queue for MolecularXtals?.

  • Property mode set to 100644
Line 
1/**********************************************************************
2  Structure - Generic wrapper for Avogadro's molecule class
3
4  Copyright (C) 2009-2011 by David C. Lonie
5
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation version 2 of the License.
9
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  GNU General Public License for more details.
14 ***********************************************************************/
15
16#ifndef STRUCTURE_H
17#define STRUCTURE_H
18
19#include <avogadro/molecule.h>
20#include <avogadro/atom.h>
21
22#include <openbabel/math/vector3.h>
23#include <openbabel/mol.h>
24#include <openbabel/generic.h>
25
26#include <QtCore/QDebug>
27#include <QtCore/QDateTime>
28#include <QtCore/QHash>
29#include <QtCore/QTextStream>
30
31#include <vector>
32
33// source: http://en.wikipedia.org/wiki/Electronvolt
34#define EV_TO_KJ_PER_MOL 96.4853365
35#define KJ_PER_MOL_TO_EV 0.0103642692
36
37namespace GlobalSearch {
38
39  /**
40   * @class Structure structure.h <globalsearch/structure.h>
41   * @brief Generic molecule object.
42   * @author David C. Lonie
43   *
44   * The Structure class provides a generic data object for storing
45   * information about a molecule. It derives from Avogadro::Molecule,
46   * adding new functionality to help with common tasks during a
47   * global structure search.
48   */
49  class Structure : public Avogadro::Molecule
50  {
51    Q_OBJECT
52
53   public:
54
55    /**
56     * Constructor.
57     *
58     * @param parent The object parent.
59     */
60    Structure(QObject *parent = 0);
61
62    /**
63     * Copy constructor.
64     */
65    Structure(const Structure &other);
66
67    /**
68     * Explicit copy constructor for Molecules.
69     */
70    Structure(const Avogadro::Molecule &other);
71
72    /**
73     * Destructor.
74     */
75    virtual ~Structure();
76
77    /**
78     * Assignment operator. Makes a new structure with all Structure
79     * specific information copied from \a other.
80     * @sa copyStructure
81     */
82    Structure& operator=(const Structure& other);
83
84    /**
85     * Assignment operator. Makes a new structure with all Molecule
86     * specific information copied from \a other.
87     * @sa copyStructure
88     */
89    Structure& operator=(const Avogadro::Molecule& other);
90
91    /**
92     * Only update this structure's atoms, bonds, and residue information
93     * from \a other.
94     * @sa operator=
95     */
96    virtual Structure& copyStructure(const Structure &other);
97
98    /**
99     * Enum containing possible optimization statuses.
100     * @sa setStatus
101     * @sa getStatus
102     */
103    enum State {
104      /** Structure has completed all optimization steps */
105      Optimized = 0,
106      /** Structure has completed an optimization step but may still
107       * have some to complete. getCurrentOptStep() shows the step
108       * that has just completed. */
109      StepOptimized,
110      /** Structure is waiting to start an optimization
111       * step. getCurrentOptStep() shows the step it will start
112       * next. */
113      WaitingForOptimization,
114      /** Structure is currently queued or running an optimization
115       * step on the PBS server (if applicable). */
116      InProcess,
117       /** Structure has just been generated, and has not yet been
118        * initialized */
119      Empty,
120      /** The Structure has completed it's current optimization step,
121       * and the results of the calculation are being transferred
122       * and applied.*/
123      Updating,
124      /** The optimization is failing. */
125      Error,
126      /** The Structure has been submitted to the PBS server, but has
127       * not appeared in the queue yet. */
128      Submitted,
129      /** The Structure has been killed before finishing all
130       * optimization steps. */
131      Killed,
132      /** The Structure has been killed after finishing all
133       * optimization steps. */
134      Removed,
135      /** The Structure has been found to be a duplicate of
136       * another. The other structure's information can be found in
137       * getDuplicateString(). */
138      Duplicate,
139      /** The Structure is about to restart it's current optimization
140       * step. */
141      Restart,
142      /** The Structure is undergoing a preoptimization step. */
143      Preoptimizing
144    };
145
146    /** @return Whether or not the "best" offspring (an optimized mutation)
147     * has been generated for this structure.
148     */
149    bool hasBestOffspring() const {return m_hasBestOffspring;}
150
151    /** Whether the Structure has an enthalpy value set.
152     * @return true if enthalpy has been set, false otherwise
153     * @sa setEnthalpy
154     * @sa getEnthalpy
155     * @sa setPV
156     * @sa getPV
157     * @sa setEnergy
158     * @sa getEnergy
159     */
160    bool hasEnthalpy()  const {return m_hasEnthalpy;};
161
162    /** Return the energy value of the first conformer in eV. This is
163     * a convenience function.
164     *
165     * @note The energies of the other conformers are still available
166     * using energy(int). Be aware that energy(int) returns
167     * kcal/mol. The multiplicative factor EV_TO_KCAL_PER_MOL has been
168     * defined to aid conversion.
169     *
170     * @return The energy of the first conformer in eV.
171     * @sa setEnthalpy
172     * @sa hasEnthalpy
173     * @sa setPV
174     * @sa getPV
175     * @sa setEnergy
176     * @sa getEnergy
177     */
178    double getEnergy()  const {return energy(0) * KJ_PER_MOL_TO_EV;};
179
180    /** Return the enthalpy value of the first conformer in eV.
181     *
182     * @note If the enthalpy is not set but the energy is set, this
183     * function assumes that the system is at zero-pressure and
184     * returns the energy.
185     *
186     * @return The enthalpy of the first conformer in eV.
187     * @sa setEnthalpy
188     * @sa hasEnthalpy
189     * @sa setPV
190     * @sa getPV
191     * @sa setEnergy
192     * @sa getEnergy
193     */
194    double getEnthalpy()const {if (!m_hasEnthalpy) return getEnergy(); return m_enthalpy;};
195
196    /** Returns the value PV term from an enthalpy calculation (H = U
197     * + PV) in eV.
198     *
199     * @return The PV term in eV.
200     * @sa getEnthalpy
201     * @sa setEnthalpy
202     * @sa hasEnthalpy
203     * @sa setPV
204     * @sa setEnergy
205     * @sa getEnergy
206     */
207    double getPV()      const {return m_PV;};
208
209    /** Returns an energetic ranking set by setRank(uint).
210     * @return the energetic ranking.
211     * @sa setRank
212     */
213    uint getRank()      const {return m_rank;};
214
215    /** Returns the Job ID of the Structure's current running
216     * optimization. Returns zero is not running.
217     * @return Job ID of the structure's optimization process.
218     * @sa setJobID
219     */
220    uint getJobID()     const {return m_jobID;};
221
222    /** Returns the generation number of the structure. Only useful
223     * for genetic/evolutionary algorithms.
224     * @return Generation number
225     * @sa setGeneration
226     * @sa getIDNumber
227     * @sa getIndex
228     * @sa setIDNumber
229     * @sa setIndex
230     * @sa getIDString
231     */
232    uint getGeneration() const {return m_generation;};
233
234    /** Returns an ID number associated with the Structure.
235     *
236     * @note If a generation number is used as well, this may not be
237     * unique.
238     * @return Identification number
239     * @sa setGeneration
240     * @sa getGeneration
241     * @sa getIndex
242     * @sa setIDNumber
243     * @sa setIndex
244     * @sa getIDString
245     */
246    uint getIDNumber() const {return m_id;};
247
248    /** Returns a unique ID number associated with the Structure. This
249     * is typically assigned in order of introduction to a tracker.
250     *
251     * @return Unique identification number
252     * @sa setGeneration
253     * @sa getGeneration
254     * @sa getIndex
255     * @sa setIDNumber
256     * @sa getIDNumber
257     * @sa getIDString
258     */
259    int getIndex() const {return m_index;};
260
261    /** @return A string naming the Structure that this Structure is a
262     * duplicate of.
263     * @sa setDuplicateString
264     */
265    QString getDuplicateString() const {return m_dupString;};
266
267    /** @return a string describing the ancestory of the Structure.
268     * @sa setParents
269     */
270    QString getParents() const {return m_parents;};
271
272    /** @return The path on the remote server to write this Structure
273     * for optimization.
274     * @sa setRempath
275     */
276    QString getRempath() const {return m_rempath;};
277
278    /** @return The current status of the Structure.
279     * @sa setStatus
280     * @sa State
281     */
282    State getStatus()   const {return m_status;};
283
284    /** @return The current optimization step of the Structure.
285     * @sa setCurrentOptStep
286     */
287    uint getCurrentOptStep() {return m_currentOptStep;};
288
289    /** @return true if running, false otherwise. */
290    virtual bool isPreoptimizing() const {return false;}
291
292    /** @return The percentage completion of the preoptimization step.
293      * -1 if @a this is not Preoptimizing.
294      */
295    virtual int getPreOptProgress() const {return -1;}
296
297    /** @return Whether or not @a this needs to be preoptimized. */
298    virtual bool needsPreoptimization() const {return false;}
299
300    /** @return The number of times this Structure has failed the
301     * current optimization step.
302     * @sa setFailCount
303     * @sa addFailure
304     * @sa resetFailCount
305     */
306    uint getFailCount() { return m_failCount;};
307
308    /** @return The time that the current optimization step started.
309     * @sa getOptTimerEnd
310     * @sa startOptTimer
311     * @sa stopOptTimer
312     * @sa setOptTimerStart
313     * @sa setOptTimerEnd
314     * @sa getOptElapsed
315     */
316    QDateTime getOptTimerStart() const {return m_optStart;};
317
318    /** @return The time that the current optimization step ended.
319     * @sa getOptTimerStart
320     * @sa startOptTimer
321     * @sa stopOptTimer
322     * @sa setOptTimerStart
323     * @sa setOptTimerEnd
324     * @sa getOptElapsed
325     */
326    QDateTime getOptTimerEnd() const {return m_optEnd;};
327
328    /** Returns a unique identification string. Defaults to
329     * [generation]x[IDNumber]. Handy for debugging/error output.
330     * @return Unique identification string.
331     * @sa setGeneration
332     * @sa getGeneration
333     * @sa setIndex
334     * @sa getIndex
335     * @sa setIDNumber
336     * @sa getIDNumber
337     */
338    QString getIDString() const {
339      return tr("%1x%2").arg(getGeneration()).arg(getIDNumber());};
340
341    /** @return A header line for a results printout
342     * @sa getResultsEntry
343     * @sa OptBase::save
344     */
345    virtual QString getResultsHeader() const {
346      return QString("%1 %2 %3 %4 %5")
347        .arg("Rank", 6)
348        .arg("Gen", 6)
349        .arg("ID", 6)
350        .arg("Enthalpy", 10)
351        .arg("Status", 11);};
352
353    /** @return A structure-specific entry for a results printout
354     * @sa getResultsHeader
355     * @sa OptBase::save
356     */
357    virtual QString getResultsEntry() const;
358
359    /** @return a lookup table for mapping atoms indices between
360     * structure index (value) and the optimizer index (key).
361     */
362    QHash<int, int> * getOptimizerLookupTable()
363    {
364      return &m_optimizerLookup;
365    }
366
367    /** Reset the optimizer lookup table to set the optimizer indicies
368     * to the structure indices.
369     */
370    void resetOptimizerLookupTable()
371    {
372      m_optimizerLookup.clear();
373      for (int i = 0; i < m_atomList.size(); ++i)
374        m_optimizerLookup.insert(i,i);
375    }
376
377    /** Find the smallest separation between all atoms in the
378     * Structure.
379     *
380     * @return true if the operation makes sense for this Structure,
381     * false otherwise (i.e. fewer than two atoms present)
382     *
383     * @param list list of distances in Angstrom
384     * @sa getNearestNeighborDistance
385     * @sa getNearestNeighborHistogram
386     * @sa getNeighbors
387     */
388    virtual bool getNearestNeighborDistances(QList<double> * list) const;
389
390    /** Return a list of nearest neighbor distances for each atom in
391     * the Structure
392     *
393     * @return true if the operation makes sense for this Structure,
394     * false otherwise (i.e. fewer than two atoms present)
395     *
396     * @param shortest An empty double to be overwritten with the
397     * shortest interatomic distance.
398     * @sa getNearestNeighborDistance
399     * @sa getNearestNeighborHistogram
400     * @sa getNeighbors
401     */
402    virtual bool getShortestInteratomicDistance(double & shortest) const;
403
404    /** Find the distance to the nearest atom from a specified
405     * point.
406     *
407     * Useful for checking if an atom will be too close to another
408     * atom before adding it.
409     *
410     * @return true if the operation makes sense for this Structure,
411     * false otherwise (i.e. fewer than one atom present)
412     *
413     * @param x Cartesian coordinate
414     * @param y Cartesian coordinate
415     * @param z Cartesian coordinate
416     * @param shortest An empty double to be overwritten with the
417     * nearest neighbor distance.
418     * @sa getShortestInteratomicDistance
419     * @sa getNearestNeighborHistogram
420     * @sa getNeighbors
421     */
422    virtual bool getNearestNeighborDistance(const double x,
423                                            const double y,
424                                            const double z,
425                                            double & shortest) const;
426
427    /** Find the nearest neighbor distance of a specified atom.
428     *
429     * @return true if the operation makes sense for this Structure,
430     * false otherwise (i.e. fewer than one atom present)
431     *
432     * @param atom Atom of interest
433     * @param shortest An empty double to be overwritten with the
434     * nearest neighbor distance.
435     * @sa getShortestInteratomicDistance
436     * @sa getNearestNeighborHistogram
437     * @sa getNeighbors
438     */
439    virtual bool getNearestNeighborDistance(const Avogadro::Atom *atom,
440                                            double & shortest) const;
441
442    /**
443     * @return a list of all atoms within \a cutoff of
444     * (\a x,\a y,\a z) and, optionally, their \a distances.
445     */
446    QList<Avogadro::Atom*> getNeighbors (const double x,
447                                         const double y,
448                                         const double z,
449                                         const double cutoff,
450                                         QList<double> *distances = 0) const;
451
452    /**
453     * @overload
454     *
455     * @return a list of all atoms within \a cutoff of \a atom and,
456     *  optionally, their \a distances.
457     */
458    QList<Avogadro::Atom*> getNeighbors (const Avogadro::Atom *atom,
459                                         const double cutoff,
460                                         QList<double> *distances = 0) const;
461
462    /** Get the default histogram data.
463     */
464    virtual void getDefaultHistogram(QList<double> *dist, QList<double> *freq) const;
465
466    /** Get the default histogram data.
467     */
468    virtual void getDefaultHistogram(QList<QVariant> *dist, QList<QVariant> *freq) const;
469
470    /**
471     * @return True is histogram generation is pending.
472     */
473    virtual bool isHistogramGenerationPending() const {
474      return m_histogramGenerationPending;};
475
476    /** Generate data for a histogram of the distances between all
477     * atoms, or between one atom and all others.
478     *
479     * If the parameter atom is specified, the resulting data will
480     * represent the distance distribution between that atom and all
481     * others. If omitted (or NULL), a histogram of all interatomic
482     * distances is calculated.
483     *
484     * Useful for estimating the coordination number of an atom from
485     * a plot.
486     *
487     * @warning This algorithm is not thoroughly tested and should not
488     * be relied upon. It is merely an estimation.
489     *
490     * @return true if the operation makes sense for this Structure,
491     * false otherwise (i.e. fewer than one atom present)
492     *
493     * @param distance List of distance values for the histogram
494     * bins.
495     *
496     * @param frequency Number of Atoms within the corresponding
497     * distance bin.
498     *
499     * @param min Value of starting histogram distance.
500     * @param max Value of ending histogram distance.
501     * @param step Increment between bins.
502     * @param atom Optional: Atom to calculate distances from.
503     *
504     * @sa getShortestInteratomicDistance
505     * @sa requestHistogramGeneration
506     * @sa getNearestNeighborDistance
507     */
508    virtual bool generateIADHistogram(QList<double> * distance,
509                                      QList<double> * frequency,
510                                      double min = 0.0,
511                                      double max = 10.0,
512                                      double step = 0.01,
513                                      Avogadro::Atom *atom = 0) const;
514
515    /** Generate data for a histogram of the distances between all
516     * atoms, or between one atom and all others.
517     *
518     * If the parameter atom is specified, the resulting data will
519     * represent the distance distribution between that atom and all
520     * others. If omitted (or NULL), a histogram of all interatomic
521     * distances is calculated.
522     *
523     * Useful for estimating the coordination number of an atom from
524     * a plot.
525     *
526     * @warning This algorithm is not thoroughly tested and should not
527     * be relied upon. It is merely an estimation.
528     *
529     * @return true if the operation makes sense for this Structure,
530     * false otherwise (i.e. fewer than one atom present)
531     *
532     * @param distance List of distance values for the histogram
533     * bins.
534     *
535     * @param frequency Number of Atoms within the corresponding
536     * distance bin.
537     *
538     * @param min Value of starting histogram distance.
539     * @param max Value of ending histogram distance.
540     * @param step Increment between bins.
541     * @param atom Optional: Atom to calculate distances from.
542     *
543     * @sa getShortestInteratomicDistance
544     * @sa requestHistogramGeneration
545     * @sa getNearestNeighborDistance
546     */
547    virtual bool generateIADHistogram(QList<QVariant> * distance,
548                                      QList<QVariant> * frequency,
549                                      double min = 0.0,
550                                      double max = 10.0,
551                                      double step = 0.01,
552                                      Avogadro::Atom *atom = 0) const;
553
554    /** Add an atom to a random position in the Structure. If no other
555     * atoms exist in the Structure, the new atom is placed at
556     * (0,0,0).
557     *
558     * @return true if the atom was sucessfully added within the
559     * specified interatomic distances.
560     *
561     * @param atomicNumber Atomic number of atom to add.
562     *
563     * @param minIAD Smallest interatomic distance allowed (NULL or
564     * omit for no limit)
565     *
566     * @param maxIAD Largest interatomic distance allowed (NULL or
567     * omit for no limit)
568     *
569     * @param maxAttempts Maximum number of tries before giving up.
570     *
571     * @param atom Returns a pointer to the new atom.
572     */
573    virtual bool addAtomRandomly(uint atomicNumber,
574                                 double minIAD = 0.0,
575                                 double maxIAD = 0.0,
576                                 int maxAttempts = 1000,
577                                 Avogadro::Atom **atom = 0);
578
579    /** @return An alphabetized list of the atomic symbols for the
580     * atomic species present in the Structure.
581     * @sa getNumberOfAtomsAlpha
582     */
583    QList<QString> getSymbols() const;
584
585    /** @return A list of the number of species present that
586     * corresponds to the symbols listed in getSymbols().
587     * @sa getSymbols
588     */
589    QList<uint> getNumberOfAtomsAlpha() const;
590
591    /** @return A string formated "HH:MM:SS" indicating the amount of
592     * time spent in the current optimization step
593     *
594     * @sa setOptTimerStart
595     * @sa getOptTimerStart
596     * @sa setOptTimerEnd
597     * @sa getOptTimerEnd
598     * @sa startOptTimer
599     * @sa stopOptTimer
600     */
601    QString getOptElapsed() const;
602
603    /** A "fingerprint" hash of the structure. Returns "enthalpy" key
604     * with the enthalpy value as a double wrapped in a QVariant. May
605     * be extended in derived classes.
606     *
607     * Used for checking if two Structures are similar enough to be
608     * marked as duplicates.
609     *
610     * @return A hash of key/value pairs containing data that is
611     * representative of the Structure.
612     */
613    virtual QHash<QString, QVariant> getFingerprint() const;
614
615    /**
616     * Structure can track if it has changed since it was last checked
617     * in a duplicate finding routine. This is useful for cutting down
618     * on the number of comparisons needed.
619     *
620     * Must call setupConnections() before using this function.
621     * @sa setChangedSinceDupChecked()
622     */
623    bool hasChangedSinceDupChecked() {return m_updatedSinceDupChecked;};
624
625    /** Sort the listed structures by their enthalpies
626     *
627     * @param structures List of structures to sort
628     * @sa rankEnthalpies
629     * @sa sortAndRankByEnthalpy
630     */
631    static void sortByEnthalpy(QList<Structure*> *structures);
632
633    /** Rank the listed structures by their enthalpies
634     *
635     * @param structures List of structures to assign ranks
636     * @sa sortEnthalpies
637     * @sa sortAndRankByEnthalpy
638     * @sa setRank
639     * @sa getRank
640     */
641    static void rankByEnthalpy(const QList<Structure*> &structures);
642
643    /** Sort and rank the listed structures by their enthalpies
644     *
645     * @param structures List of structures to sort and assign rank
646     * @sa sortByEnthalpy
647     * @sa rankEnthalpies
648     * @sa setRank
649     * @sa getRank
650     */
651    static void sortAndRankByEnthalpy(QList<Structure*> *structures);
652
653  signals:
654    void preoptimizationStarted();
655    void preoptimizationFinished();
656
657   public slots:
658
659    /**
660     * Connect slots/signals within the molecule. This must be called
661     * AFTER moving the Structure to it's final thread.
662     */
663    virtual void setupConnections();
664
665    /**
666     * Set whether the default histogram generation should be
667     * performed (default is off)
668     */
669    virtual void enableAutoHistogramGeneration(bool);
670
671    /**
672     * Request that histogram data be regenerated. This is connected
673     * to Molecule::update() and calls
674     * generateDefaultHistogram(). This function is throttled to only
675     * run every 250 ms.
676     */
677    virtual void requestHistogramGeneration();
678
679    /**
680     * Generate default histogram data (0:10 A, 0.01 A step)
681     * @sa isHistogramGenerationPending()
682     * @sa getDefaultHistogram()
683     */
684    virtual void generateDefaultHistogram();
685
686    /**
687     * After calling setupConnections(), this will be called when the
688     * structure is update, atoms moved, added, etc...
689     */
690    virtual void structureChanged();
691
692    /**
693     * Compare two IAD histograms.
694     *
695     * Given two histograms over the same range with the same step,
696     * this function calculates an error value to measure the
697     * differences between the two. A boxcar smoothing is performed
698     * using a width of "smear", and an optional weight can be
699     * applied. The weight is a standard exponential decay with a
700     * halflife of "decay".
701     *
702     * @param d List of distances
703     * @param f1 First list of frequencies
704     * @param f2 Second list of frequencies
705     * @param decay Exponential decay parameter for lowering weight of large
706     * IADs
707     * @param smear Boxcar smoothing width in Angstroms
708     * @param error Return error value
709     *
710     * @return Whether or not the operation could be performed.
711     */
712    static bool compareIADDistributions(const std::vector<double> &d,
713                                        const std::vector<double> &f1,
714                                        const std::vector<double> &f2,
715                                        double decay,
716                                        double smear,
717                                        double *error);
718    /**
719     * Compare two IAD histograms.
720     *
721     * Given two histograms over the same range with the same step,
722     * this function calculates an error value to measure the
723     * differences between the two. A boxcar smoothing is performed
724     * using a width of "smear", and an optional weight can be
725     * applied. The weight is a standard exponential decay with a
726     * halflife of "decay".
727     *
728     * @param d List of distances
729     * @param f1 First list of frequencies
730     * @param f2 Second list of frequencies
731     * @param decay Exponential decay parameter for lowering weight of large
732     * IADs
733     * @param smear Boxcar smoothing width in Angstroms
734     * @param error Return error value
735     *
736     * @return Whether or not the operation could be performed.
737     */
738    static bool compareIADDistributions(const QList<double> &d,
739                                        const QList<double> &f1,
740                                        const QList<double> &f2,
741                                        double decay,
742                                        double smear,
743                                        double *error);
744
745    /**
746     * Compare two IAD histograms.
747     *
748     * Given two histograms over the same range with the same step,
749     * this function calculates an error value to measure the
750     * differences between the two. A boxcar smoothing is performed
751     * using a width of "smear", and an optional weight can be
752     * applied. The weight is a standard exponential decay with a
753     * halflife of "decay".
754     *
755     * @param d List of distances
756     * @param f1 First list of frequencies
757     * @param f2 Second list of frequencies
758     * @param decay Exponential decay parameter for lowering weight of large
759     * IADs
760     * @param smear Boxcar smoothing width in Angstroms
761     * @param error Return error value
762     *
763     * @return Whether or not the operation could be performed.
764     */
765    static bool compareIADDistributions(const QList<QVariant> &d,
766                                        const QList<QVariant> &f1,
767                                        const QList<QVariant> &f2,
768                                        double decay,
769                                        double smear,
770                                        double *error);
771
772    /**
773     * Write supplementary data about this Structure to a file. All
774     * data that is not stored in the OpenBabel-readable optimizer
775     * output file should be written here.
776     *
777     * If reimplementing this in a derived class, call
778     * writeStructureSettings(filename) to write inherited data.
779     * @param filename Filename to write data to.
780     * @sa writeStructureSettings
781     * @sa readSettings
782     */
783    virtual void writeSettings(const QString &filename) {
784      writeStructureSettings(filename);};
785
786    /**
787     * Read supplementary data about this Structure from a file. All
788     * data that is not stored in the OpenBabel-readable optimizer
789     * output file should be read here.
790     *
791     * If reimplementing this in a derived class, call
792     * readStructureSettings(filename) to read inherited data.
793     * @param filename Filename to read data from.
794     * @sa readStructureSettings
795     * @sa writeSettings
796     */
797    virtual void readSettings(const QString &filename) {
798      readStructureSettings(filename);};
799
800    /**
801     * Update the coordinates, enthalpy and/or energy, and optionally
802     * unit cell of the structure, without adding the data to the
803     * structure's history.
804     *
805     * @param atomicNums List of atomic numbers
806     * @param coords List of cartesian coordinates
807     * @param energy in eV
808     * @param enthalpy in eV
809     * @param cell Matrix of cell vectors (row vectors)
810     */
811    virtual void updateAndSkipHistory(const QList<unsigned int> &atomicNums,
812                                      const QList<Eigen::Vector3d> &coords,
813                                      const double energy = 0,
814                                      const double enthalpy = 0,
815                                      const Eigen::Matrix3d &cell = Eigen::Matrix3d::Zero());
816
817    /**
818     * Update the coordinates, enthalpy and/or energy, and optionally
819     * unit cell of the structure, appending the data to the
820     * structure's history.
821     *
822     * @param atomicNums List of atomic numbers
823     * @param coords List of cartesian coordinates
824     * @param energy in eV
825     * @param enthalpy in eV
826     * @param cell Matrix of cell vectors (row vectors)
827     */
828    virtual void updateAndAddToHistory(const QList<unsigned int> &atomicNums,
829                                       const QList<Eigen::Vector3d> &coords,
830                                       const double energy = 0,
831                                       const double enthalpy = 0,
832                                       const Eigen::Matrix3d &cell = Eigen::Matrix3d::Zero());
833
834    /**
835     * @param index Index of entry to remove from structure's history.
836     */
837    virtual void deleteFromHistory(unsigned int index);
838
839    /**
840     * This function is used to retrieve data from the structure's
841     * history. All non-zero pointers will be modified to contain the
842     * information at the specified index of the history.
843     *
844     * @param index Entry in history to return
845     *
846     * @param atomicNums Pointer to a list that will be filled with
847     * atomic numbers. Can be zero if this is not needed.
848     *
849     * @param coords Pointer to a list that will be filled with
850     * cartesian atomic coordinates. Can be zero if this is not
851     * needed.
852     *
853     * @param energy Pointer to a double that will contain the entry's
854     * energy in eV. Can be zero if this is not needed.
855     *
856     * @param enthalpy Pointer to a double that will contain the
857     * entry's enthalpy in eV. Can be zero if this is not needed.
858     *
859     * @param cell Pointer to an Eigen::Matrix3f filled with the unit
860     * cell vectors (row vectors). Can be zero if this is not needed.
861     *
862     * @note If the system is not periodic, the cell matrix will be a
863     * zero matrix. Use Eigen::Matrix3d::isZero() to test for a valid
864     * cell.
865     */
866    virtual void retrieveHistoryEntry(unsigned int index,
867                                      QList<unsigned int> *atomicNums,
868                                      QList<Eigen::Vector3d> *coords,
869                                      double *energy,
870                                      double *enthalpy,
871                                      Eigen::Matrix3d *cell);
872
873      /**
874       * @return Number of history entries available
875       */
876    virtual unsigned int sizeOfHistory() {return m_histEnergies.size();};
877
878    /** @param b Whether or not the "best" offspring (an optimized mutation)
879     * has been generated for this structure.
880     */
881    void setHasBestOffspring(bool b = true)
882    {
883      m_hasBestOffspring = b;
884    }
885
886    /** Set the enthalpy of the Structure.
887     * @param enthalpy The Structure's enthalpy
888     * @sa getEnthalpy
889     */
890    void setEnthalpy(double enthalpy) {m_hasEnthalpy = true; m_enthalpy = enthalpy;};
891
892    /** Set the PV term of the Structure's enthalpy (see getPV()).
893     * @param pv The PV term
894     * @sa getPV
895     */
896    void setPV(double pv) {m_PV = pv;};
897
898    /** Reset the Structure's enthalpy and PV term to zero and clear
899     * hasEnthalpy()
900     * @sa setEnthalpy
901     * @sa getEnthalpy
902     * @sa hasEnthalpy
903     * @sa setPV
904     * @sa getPV
905     */
906    void resetEnthalpy() {m_enthalpy=0; m_PV=0; m_hasEnthalpy=false;};
907
908    /** Reset the Structure's energy to zero
909     * @sa setEnergy
910     * @sa getEnergy
911     */
912    void resetEnergy() {std::vector<double> E; E.push_back(0); setEnergies(E);};
913
914    /** Determine and set the energy using a forcefield method from
915     * OpenBabel.
916     * @param ff A string identifying the forcefield to use (default: UFF).
917     */
918    void setOBEnergy(const QString &ff = QString("UFF"));
919
920    /** Set the Structure's energetic ranking.
921     * @param rank The Structure's energetic ranking.
922     * @sa getRank
923     */
924    void setRank(uint rank) {m_rank = rank;};
925
926    /** Set the Job ID of the current optimization process.
927     * @param id The current optimization process's Job ID.
928     * @sa getJobID
929     */
930    void setJobID(uint id) {m_jobID = id;};
931
932    /** Set the generation number of the Structure.
933     * @param gen The generation number.
934     * @sa setGeneration
935     * @sa getGeneration
936     * @sa setIndex
937     * @sa getIndex
938     * @sa setIDNumber
939     * @sa getIDNumber
940     * @sa getIDString
941     */
942    void setGeneration(uint gen) {m_generation = gen;};
943
944    /** Set the ID number associated with the Structure.
945     *
946     * @note If a generation number is used as well, this may not be
947     * unique.
948     * @return Identification number
949     * @sa setGeneration
950     * @sa getGeneration
951     * @sa setIndex
952     * @sa getIndex
953     * @sa getIDNumber
954     * @sa getIDString
955     */
956    void setIDNumber(uint id) {m_id = id;};
957
958    /** Set a unique ID number associated with the Structure. This
959     * is typically assigned in order of introduction to a tracker.
960     *
961     * @note If a generation number is used as well, this may not be
962     * unique.
963     * @param index Identification number
964     * @sa setGeneration
965     * @sa getGeneration
966     * @sa getIndex
967     * @sa setIDNumber
968     * @sa getIDNumber
969     * @sa getIDString
970     */
971    void setIndex(int index) {m_index = index;};
972
973    /** @param p A string describing the ancestory of the Structure.
974     * @sa getParents
975     */
976    void setParents(const QString & p) {m_parents = p;};
977
978    /** @param p The path on the remote server to write this Structure
979     * for optimization.
980     * @sa getRempath
981     */
982    void setRempath(const QString & p) {m_rempath = p;};
983
984    /** @param status The current status of the Structure.
985     * @sa getStatus
986     * @sa State
987     */
988    void setStatus(State status) {m_status = status;};
989
990    /** @param i The current optimization step of the Structure.
991     * @sa getCurrentOptStep
992     */
993    void setCurrentOptStep(uint i) {m_currentOptStep = i;};
994
995    /** @param count The number of times this Structure has failed the
996     * current optimization step.
997     * @sa addFailure
998     * @sa getFailCount
999     * @sa resetFailCount
1000     */
1001    void setFailCount(uint count) {m_failCount = count;};
1002
1003    /** Reset the number of times this Structure has failed the
1004     * current optimization step.
1005     *
1006     * @sa addFailure
1007     * @sa setFailCount
1008     * @sa getFailCount
1009     */
1010    void resetFailCount() {setFailCount(0);};
1011
1012    /** Increase the number of times this Structure has failed the
1013     * current optimization step by one.
1014     *
1015     * @sa resetFailCount
1016     * @sa setFailCount
1017     * @sa getFailCount
1018     */
1019    void addFailure() {setFailCount(getFailCount() + 1);};
1020
1021    /** @param s A string naming the Structure that this Structure is a
1022     * duplicate of.
1023     * @sa getDuplicateString
1024     */
1025    void setDuplicateString(const QString & s) {m_dupString = s;};
1026
1027    /**
1028     * Structure can track if it has changed since it was last checked
1029     * in a duplicate finding routine. This is useful for cutting down
1030     * on the number of comparisons needed.
1031     *
1032     * Must call setupConnections() before using this function.
1033     * @sa hasChangedSinceDupChecked()
1034     */
1035    void setChangedSinceDupChecked(bool b) {m_updatedSinceDupChecked = b;};
1036
1037    /** Record the current time as when the current optimization
1038     * process started.
1039     *
1040     * @sa setOptTimerStart
1041     * @sa getOptTimerStart
1042     * @sa setOptTimerEnd
1043     * @sa getOptTimerEnd
1044     * @sa stopOptTimer
1045     * @sa getOptElapsed
1046     */
1047    void startOptTimer() {
1048      m_optStart = QDateTime::currentDateTime(); m_optEnd = QDateTime();};
1049
1050    /** Record the current time as when the current optimization
1051     * process stopped.
1052     *
1053     * @sa setOptTimerStart
1054     * @sa getOptTimerStart
1055     * @sa setOptTimerEnd
1056     * @sa getOptTimerEnd
1057     * @sa startOptTimer
1058     * @sa getOptElapsed
1059     */
1060    void stopOptTimer() {
1061      if (m_optEnd.isNull()) m_optEnd = QDateTime::currentDateTime();};
1062
1063    /** @param d The time that the current optimization
1064     * process started.
1065     *
1066     * @sa getOptTimerStart
1067     * @sa setOptTimerEnd
1068     * @sa getOptTimerEnd
1069     * @sa startOptTimer
1070     * @sa stopOptTimer
1071     * @sa getOptElapsed
1072     */
1073    void setOptTimerStart(const QDateTime &d) {m_optStart = d;};
1074
1075    /** @param d The time that the current optimization
1076     * process stopped.
1077     *
1078     * @sa setOptTimerStart
1079     * @sa getOptTimerStart
1080     * @sa getOptTimerEnd
1081     * @sa startOptTimer
1082     * @sa stopOptTimer
1083     * @sa getOptElapsed
1084     */
1085    void setOptTimerEnd(const QDateTime &d) {m_optEnd = d;};
1086
1087
1088    /** @param b Whether or not @a this needs to be preoptimized. */
1089    virtual void setNeedsPreoptimization(bool b)
1090    {
1091      Q_UNUSED(b);
1092      qWarning() << "Preoptimization is not implemented for all structure "
1093                    "types. Call to Structure::setNeedsPreoptimization "
1094                    "ignored.";
1095    }
1096
1097    /** Abort the preoptimization running on this structure. */
1098    virtual void abortPreoptimization() const {};
1099
1100    /** Emits the preoptimizationStarted signal */
1101    void emitPreoptimizationStarted()
1102    {
1103      emit preoptimizationStarted();
1104    }
1105
1106    /** Emits the preoptimizationFinished signal */
1107    void emitPreoptimizationFinished()
1108    {
1109      emit preoptimizationFinished();
1110    }
1111
1112    /** Load data into Structure.
1113     * @attention Do not use this function in new code, as it has been
1114     * replaced by readSettings. Old code should be rewritten to use
1115     * readSettings as well.
1116     * @deprecated Use readSettings instead, and call this only as a
1117     * backup for outdates .state files
1118     * @param in QTextStream containing load data.
1119     * @sa readSettings
1120     */
1121    virtual void load(QTextStream &in);
1122
1123   protected slots:
1124    /**
1125     * Write data from the Structure class to a file.
1126     * @param filename Filename to write data to.
1127     * @sa writeSettings
1128     * @sa readSettings
1129     */
1130    void writeStructureSettings(const QString &filename);
1131
1132    /**
1133     * Read data concerning the Structure class from a file.
1134     * @param filename Filename to read data from.
1135     * @sa writeSettings
1136     * @sa readSettings
1137     */
1138    void readStructureSettings(const QString &filename);
1139
1140  protected:
1141    // skip Doxygen parsing
1142    /// \cond
1143    bool m_hasEnthalpy, m_updatedSinceDupChecked;
1144    bool m_histogramGenerationPending;
1145    bool m_hasBestOffspring;
1146    uint m_generation, m_id, m_rank, m_jobID, m_currentOptStep, m_failCount;
1147    QString m_parents, m_dupString, m_rempath;
1148    double m_enthalpy, m_PV;
1149    State m_status;
1150    QDateTime m_optStart, m_optEnd;
1151    int m_index;
1152    QList<QVariant> m_histogramDist, m_histogramFreq;
1153
1154    // History
1155    QList<QList<unsigned int> > m_histAtomicNums;
1156    QList<double> m_histEnthalpies;
1157    QList<double> m_histEnergies;
1158    QList<QList<Eigen::Vector3d> > m_histCoords;
1159    QList<Eigen::Matrix3d> m_histCells;
1160
1161    // Map <Structure atom index, optimizer atom index>
1162    QHash<int, int> m_optimizerLookup;
1163
1164    // End doxygen skip:
1165    /// \endcond
1166  };
1167
1168} // end namespace GlobalSearch
1169
1170#endif
Note: See TracBrowser for help on using the browser.