Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
94acf04
DRR - Cpptraj: Add some debug info
Apr 5, 2018
c8ca79e
DRR - Cpptraj: Initial test of Quaternion rmsd. Quaternion driver cod…
Apr 6, 2018
a11f386
DRR - Cpptraj: Do the inner product using ordering preferred by cpptr…
Apr 6, 2018
5629be4
DRR - Cpptraj: Add version that does not care about rotation matrix
Apr 6, 2018
e3f9b9e
DRR - Cpptraj: add some debug info
Apr 6, 2018
aeb0de7
DRR - Cpptraj: Comment out unused functions
Apr 6, 2018
715c2af
DRR - Cpptraj: Add quaternion option to 2dRMS. Only about 1.04x faste…
Apr 9, 2018
ede223c
Merge branch 'master' into quat_rmsd.withMaster
Apr 11, 2022
a0a3f0d
Fix comments
drroe Apr 12, 2022
b8251a9
Add version where rotation matrix is not calculated.
drroe Apr 12, 2022
8a4baca
Start CoordCovarMatrix
drroe Apr 24, 2022
bfa4d31
Use atom mask
drroe Apr 24, 2022
e1f3531
Update comments
drroe Apr 24, 2022
5c49bc0
Add in translations to origin for tgt and ref
drroe Apr 24, 2022
d78dffa
Merge branch 'master' into quat_rmsd.withMaster
drroe May 28, 2022
e3768d5
Merge branch 'master' into quat_rmsd.withMaster
drroe Jun 17, 2022
6c1b716
Merge branch 'quat_rmsd.withMaster' of github.com:drroe/cpptraj into …
drroe Jun 18, 2022
184ea4a
Put coordinate covariance matrix calc into Matrix_3x3
drroe Jun 18, 2022
4272a44
Merge branch 'master' into quat_rmsd.withMaster
drroe Jun 25, 2022
4e02135
Convert to C++
drroe Jun 25, 2022
2cfde45
Add namespace to call
drroe Jun 25, 2022
7a3291a
Add test for 2drms with quaternion
drroe Jun 25, 2022
057f182
Add feedback for quat rmsd
drroe Jun 25, 2022
e026b65
Merge branch 'master' into quat_rmsd.withMaster
drroe Jul 19, 2022
a9e9bc9
Merge branch 'master' into quat_rmsd.withMaster
drroe Jul 23, 2022
aacb8d7
Remove unused CalcCovariance
drroe Jul 28, 2022
a6dba01
Remove CoordCovarMatrix class, unused
drroe Jul 28, 2022
2aa4dde
Update dependencies
drroe Jul 28, 2022
7a7644c
Initial incarnation of the quaternion rmsd cluster metric
drroe Jul 28, 2022
b621fde
Add qrmsd keyword
drroe Jul 28, 2022
3d14652
Try to use quat rmsd for clustering. Doesnt work yet.
drroe Jul 28, 2022
3b272d1
Fix DEBUG_CLUSTER
drroe Jul 28, 2022
43ba962
Ensure reference structures are centered
drroe Jul 29, 2022
d292db4
Start quaternion rmsd clustering test. Info not matching yet.
drroe Jul 29, 2022
215c2ca
QuaternionRMSD rotation vectors are in columns; need to apply inverse
drroe Jul 29, 2022
4bd9095
Get rid of minScore (unused and unneeded); add some more code docs.
drroe Jul 29, 2022
91b4f6b
Remove unused code
drroe Jul 29, 2022
e8fe62b
Add quaternion cluster test to cluster target
drroe Jul 29, 2022
746cbed
Fix typo
drroe Jul 29, 2022
2afb924
Add qrmsd citation info
drroe Jul 29, 2022
c42e00e
Add blurb about qcprot.c and authors to README
drroe Jul 29, 2022
2361d06
Use qrmsd keyword to be consistent with cluster
drroe Jul 29, 2022
1ab991f
Add qrmsd keyword to 2drms and cluster entries
drroe Jul 29, 2022
15c1b10
Remove unneeded debug print
drroe Jul 29, 2022
f3bc2e5
6.12.2. Revision bump for adding quaternion rmsd calc to 2drms and
drroe Jul 29, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -249,3 +249,5 @@ External code/libraries bundled with CPPTRAJ
* Support for reading DTR trajectories uses the VMD DTR plugin.

* CPPTRAJ uses code for the [permuted congruent pseudo-random number generator](https://www.pcg-random.org/index.html) PCG32 by Melissa O'Neill and the [Xoshiro 128++ pseudo-random number generator](http://prng.di.unimi.it) by David Blackman and Sebastino Vigna.

* The code for quaternion RMSD calculation was adapted from code in [qcprot.c](https://theobald.brandeis.edu/qcp/qcprot.c) originally written by Douglas L. Theobald and Pu Lio (Brandeis University).
29 changes: 27 additions & 2 deletions doc/cpptraj.lyx
Original file line number Diff line number Diff line change
Expand Up @@ -42042,7 +42042,8 @@ cluster
\end_layout

\begin_layout LyX-Code
[{dme|rms|srmsd} [mass] [nofit] [<mask>]] [{euclid|manhattan}] [wgt <list>]
[{dme|rms|srmsd|qrmsd} [mass] [nofit] [<mask>]] [{euclid|manhattan}] [wgt
<list>]
\end_layout

\begin_layout LyX-Code
Expand Down Expand Up @@ -42580,6 +42581,26 @@ reference "subsec:cpptraj_symmrmsd"
[nofit] Do not fit structures onto each other prior to calculating RMSD.
\end_layout

\end_deeper
\begin_layout Description
qrmsd
\begin_inset space ~
\end_inset

[<mask>] For COORDS data, distance between coordinate frames calculated
using best-fit quaternion RMSD (can be 15-20% faster than regular RMSD)
using atoms in
\series bold
<mask>
\series default
.
\end_layout

\begin_deeper
\begin_layout Description
[mass] Mass-weight the RMSD.
\end_layout

\end_deeper
\begin_layout Description
dme
Expand Down Expand Up @@ -48322,7 +48343,7 @@ rms2d
\end_layout

\begin_layout LyX-Code
[dme | nofit | srmsd] [mass]
[{dme | nofit | srmsd | qrmsd}] [mass]
\end_layout

\begin_layout LyX-Code
Expand Down Expand Up @@ -48384,6 +48405,10 @@ reference "subsec:cpptraj_symmrmsd"
).
\end_layout

\begin_layout Description
[qrmsd] Use quaternion RMSD calculation (can be 15-20% faster).
\end_layout

\begin_layout Description
[mass] Mass-weight RMSD.
\end_layout
Expand Down
13 changes: 10 additions & 3 deletions src/Analysis_Rms2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "CpptrajStdio.h"
#include "ProgressBar.h"
#include "DataSet_Coords_TRJ.h"
#include "QuaternionRMSD.h"
#ifdef _OPENMP
# include <omp.h>
#endif
Expand All @@ -21,7 +22,7 @@ Analysis_Rms2d::Analysis_Rms2d() :

void Analysis_Rms2d::Help() const {
mprintf("\t[crdset <crd set>] [<name>] [<mask>] [out <filename>]\n"
"\t[dme | nofit | srmsd] [mass]\n"
"\t[{dme | nofit | srmsd | qrmsd}] [mass]\n"
"\t[reftraj <traj> [parm <parmname> | parmindex <#>] [<refmask>]]\n"
"\t[corr <corrfilename>]\n"
" Calculate RMSD between all frames in <crd set>, or between frames in\n"
Expand All @@ -30,7 +31,7 @@ void Analysis_Rms2d::Help() const {
}

const char* Analysis_Rms2d::ModeStrings_[] = {
"RMSD (fit)", "RMSD (no fitting)", "DME", "symmetry-corrected RMSD"
"RMSD (fit)", "RMSD (no fitting)", "DME", "symmetry-corrected RMSD", "quaternion RMSD"
};

// Analysis_Rms2d::Setup()
Expand All @@ -52,6 +53,8 @@ Analysis::RetType Analysis_Rms2d::Setup(ArgList& analyzeArgs, AnalysisSetup& set
mode_ = DME;
else if (analyzeArgs.hasKey("srmsd"))
mode_ = SRMSD;
else if (analyzeArgs.hasKey("qrmsd"))
mode_ = QUAT;
else
mode_ = RMS_FIT;
useMass_ = analyzeArgs.hasKey("mass");
Expand Down Expand Up @@ -138,6 +141,8 @@ Analysis::RetType Analysis_Rms2d::Setup(ArgList& analyzeArgs, AnalysisSetup& set
if (corrfile != 0)
mprintf("\tRMSD auto-correlation will be calculated and output to '%s'\n",
corrfile->DataFilename().full());
if (mode_ == QUAT)
PrintQrmsdCitation();

return Analysis::OK;
}
Expand Down Expand Up @@ -257,7 +262,7 @@ int Analysis_Rms2d::Calculate_2D() {
# endif
RefTraj_->GetFrame( nref, SelectedRef, RefMask_ );
// Select and pre-center reference atoms (if fitting)
if (mode_ == RMS_FIT || mode_ == SRMSD)
if (mode_ == QUAT || mode_ == RMS_FIT || mode_ == SRMSD)
SelectedRef.CenterOnOrigin(useMass_);
// LOOP OVER TARGET FRAMES
if (calculateFullMatrix)
Expand All @@ -272,6 +277,8 @@ int Analysis_Rms2d::Calculate_2D() {
case RMS_NOFIT: R = (float)SelectedTgt.RMSD_NoFit(SelectedRef, useMass_); break;
case DME: R = (float)SelectedTgt.DISTRMSD(SelectedRef); break;
case SRMSD: R = (float)SRMSD_.SymmRMSD_CenteredRef(SelectedTgt, SelectedRef); break;
case QUAT:
R = (float)QuaternionRMSD_CenteredRef(SelectedRef, SelectedTgt, useMass_); break;
}
rmsdataset_->SetElement(nref, ntgt, R);
// DEBUG
Expand Down
2 changes: 1 addition & 1 deletion src/Analysis_Rms2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class Analysis_Rms2d: public Analysis {
void CalcAutoCorr();

static const char* ModeStrings_[];
enum ModeType { RMS_FIT = 0, RMS_NOFIT, DME, SRMSD };
enum ModeType { RMS_FIT = 0, RMS_NOFIT, DME, SRMSD, QUAT };
ModeType mode_;
DataSet_Coords* TgtTraj_; ///< Hold coords from input frames.
bool useReferenceTraj_; ///< If true read from reference trajectory.
Expand Down
1 change: 1 addition & 0 deletions src/Cluster/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ target_sources(cpptraj_common_obj PRIVATE
${CMAKE_CURRENT_LIST_DIR}/List.cpp
${CMAKE_CURRENT_LIST_DIR}/MetricArray.cpp
${CMAKE_CURRENT_LIST_DIR}/Metric_DME.cpp
${CMAKE_CURRENT_LIST_DIR}/Metric_QuatRMSD.cpp
${CMAKE_CURRENT_LIST_DIR}/Metric_RMS.cpp
${CMAKE_CURRENT_LIST_DIR}/Metric_Scalar.cpp
${CMAKE_CURRENT_LIST_DIR}/Metric_SRMSD.cpp
Expand Down
2 changes: 1 addition & 1 deletion src/Cluster/Metric.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const int UNCLASSIFIED = -2;
/// Abstract base class for calculating distance between points or determining centroid.
class Metric {
public:
enum Type { RMS=0, DME, SRMSD, SCALAR, TORSION, MATRIX2D, UNKNOWN_METRIC };
enum Type { RMS=0, DME, SRMSD, SCALAR, TORSION, MATRIX2D, QRMSD, UNKNOWN_METRIC };
enum CentOpType { ADDFRAME=0, SUBTRACTFRAME };

/// CONSTRUCTOR
Expand Down
20 changes: 15 additions & 5 deletions src/Cluster/MetricArray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@
#include "../OnlineVarT.h" // for metric stats average
#include "../ProgressBar.h"
#include "../StringRoutines.h"
#include "../QuaternionRMSD.h" // for printing qrmsd citation
// Metric classes
#include "Metric_RMS.h"
#include "Metric_DME.h"
#include "Metric_Scalar.h"
#include "Metric_SRMSD.h"
#include "Metric_Torsion.h"
#include "Metric_QuatRMSD.h"

/** CONSTRUCTOR */
Cpptraj::Cluster::MetricArray::MetricArray() :
Expand Down Expand Up @@ -277,7 +279,8 @@ Cpptraj::Cluster::Metric const*
{
if ( (*it)->MetricType() == Metric::RMS ||
(*it)->MetricType() == Metric::DME ||
(*it)->MetricType() == Metric::SRMSD )
(*it)->MetricType() == Metric::SRMSD ||
(*it)->MetricType() == Metric::QRMSD )
return *it;
}
return 0;
Expand All @@ -291,6 +294,7 @@ Cpptraj::Cluster::Metric* Cpptraj::Cluster::MetricArray::AllocateMetric(Metric::
case Metric::RMS : met = new Metric_RMS(); break;
case Metric::DME : met = new Metric_DME(); break;
case Metric::SRMSD : met = new Metric_SRMSD(); break;
case Metric::QRMSD : met = new Metric_QuatRMSD(); break;
case Metric::SCALAR : met = new Metric_Scalar(); break;
case Metric::TORSION : met = new Metric_Torsion(); break;
default: mprinterr("Error: Unhandled Metric in AllocateMetric.\n");
Expand All @@ -300,7 +304,7 @@ Cpptraj::Cluster::Metric* Cpptraj::Cluster::MetricArray::AllocateMetric(Metric::

/** Recognized metric args. */
const char* Cpptraj::Cluster::MetricArray::MetricArgs_ =
"[{dme|rms|srmsd} [mass] [nofit] [<mask>]] [{euclid|manhattan}] [wgt <list>]";
"[{dme|rms|srmsd|qrmsd} [mass] [nofit] [<mask>]] [{euclid|manhattan}] [wgt <list>]";

/** Initialize with given sets and arguments. */
int Cpptraj::Cluster::MetricArray::initMetricArray(DataSetList const& setsToCluster, ArgList& analyzeArgs)
Expand All @@ -311,6 +315,7 @@ int Cpptraj::Cluster::MetricArray::initMetricArray(DataSetList const& setsToClus
int usedme = (int)analyzeArgs.hasKey("dme");
int userms = (int)analyzeArgs.hasKey("rms");
int usesrms = (int)analyzeArgs.hasKey("srmsd");
int useqrms = (int)analyzeArgs.hasKey("qrmsd");
bool useMass = analyzeArgs.hasKey("mass");
bool nofit = analyzeArgs.hasKey("nofit");
std::string maskExpr = analyzeArgs.GetMaskNext();
Expand All @@ -329,15 +334,18 @@ int Cpptraj::Cluster::MetricArray::initMetricArray(DataSetList const& setsToClus
std::string wgtArgStr = analyzeArgs.GetStringKey("wgt");

// Check args
if (usedme + userms + usesrms > 1) {
mprinterr("Error: Specify either 'dme', 'rms', or 'srmsd'.\n");
if (usedme + userms + usesrms + useqrms > 1) {
mprinterr("Error: Specify either 'dme', 'rms', 'srmsd', or 'qrmsd'.\n");
return 1;
}
Metric::Type coordsMetricType;
if (usedme) coordsMetricType = Metric::DME;
else if (userms) coordsMetricType = Metric::RMS;
else if (usesrms) coordsMetricType = Metric::SRMSD;
else coordsMetricType = Metric::RMS; // default
else if (useqrms) {
coordsMetricType = Metric::QRMSD;
PrintQrmsdCitation();
} else coordsMetricType = Metric::RMS; // default

// For each input set, set up the appropriate metric
for (DataSetList::const_iterator ds = setsToCluster.begin(); ds != setsToCluster.end(); ++ds)
Expand Down Expand Up @@ -373,6 +381,8 @@ int Cpptraj::Cluster::MetricArray::initMetricArray(DataSetList const& setsToClus
err = ((Metric_DME*)met)->Init((DataSet_Coords*)*ds, AtomMask(maskExpr)); break;
case Metric::SRMSD :
err = ((Metric_SRMSD*)met)->Init((DataSet_Coords*)*ds, AtomMask(maskExpr), nofit, useMass, debug_); break;
case Metric::QRMSD :
err = ((Metric_QuatRMSD*)met)->Init((DataSet_Coords*)*ds, AtomMask(maskExpr), useMass); break;
case Metric::SCALAR :
err = ((Metric_Scalar*)met)->Init((DataSet_1D*)*ds); break;
case Metric::TORSION :
Expand Down
Loading