From d466b3fece4c77ff002c20a33af40001a8cf9c4e Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 21 Apr 2020 15:16:26 -0400 Subject: [PATCH 1/6] DRR - Start implementing dataset shift --- src/Exec_DataSetCmd.cpp | 67 +++++++++++++++++++++++++++++++++++++++-- src/Exec_DataSetCmd.h | 2 ++ 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/src/Exec_DataSetCmd.cpp b/src/Exec_DataSetCmd.cpp index 9c5f9fbae5..d3e4475d05 100644 --- a/src/Exec_DataSetCmd.cpp +++ b/src/Exec_DataSetCmd.cpp @@ -8,12 +8,14 @@ #include "DataSet_Mesh.h" #include "StringRoutines.h" +// Exec_DataSetCmd::Help() void Exec_DataSetCmd::Help() const { mprintf("\t{legend|makexy|vectorcoord|cat|make2d|droppoints|keeppoints|remove|\n" - "\t dim|outformat|invert|mode|type} \n"); + "\t dim|outformat|invert|shift|mode|type} \n"); mprintf(" Type 'help dataset ' for detailed subcommand help.\n"); } +// Exec_DataSetCmd::Help() void Exec_DataSetCmd::Help(ArgList& argIn) const { if (argIn.hasKey("legend")) { mprintf(" legend \n" @@ -51,6 +53,8 @@ void Exec_DataSetCmd::Help(ArgList& argIn) const { " general - Use 'double' or 'scientific', whichever is shortest.\n"); } else if (argIn.hasKey("invert")) { Help_InvertSets(); + } else if (argIn.hasKey("shift")) { + Help_Shift(); } else if (argIn.hasKey("mode")) { mprintf(" [mode ] [type ] [ ...]\n"); mprintf(" : "); @@ -111,7 +115,10 @@ Exec::RetType Exec_DataSetCmd::Execute(CpptrajState& State, ArgList& argIn) { } else if (argIn.hasKey("invert")) { // Invert set(s) X/Y, create new sets err = InvertSets(State, argIn); // --------------------------------------------- - } else { // Default: change mode/type for one or more sets. + } else if (argIn.hasKey("shift")) { // Shift data in set(s) that match criteria by offset + err = ShiftData(State, argIn); + // --------------------------------------------- + } else { // Default: change mode/type for one or more sets. err = ChangeModeType(State, argIn); } return err; @@ -941,3 +948,59 @@ Exec::RetType Exec_DataSetCmd::InvertSets(CpptrajState& State, ArgList& argIn) { return CpptrajState::OK; } + +// Exec_DataSetCmd::Help_Shift() +void Exec_DataSetCmd::Help_Shift() { + mprintf(" shift [above by ] [below by ] ... ...\n" + " Shift the values in given set(s) by an offset if the points meet\n" + " certain criteria.\n"); +} + +/** Apply an offset to data elements when a certain criterion is met. */ +Exec::RetType Exec_DataSetCmd::ShiftData(CpptrajState& State, ArgList& argIn) { + std::vector criteria; + std::vector vals; + std::vector offsets; + if (argIn.Contains("below")) { + criteria.push_back(LESS_THAN); + vals.push_back( argIn.getKeyDouble("below", 0) ); + if (!argIn.Contains("by")) { + mprinterr("Error: 'by ' argument missing for 'below'\n"); + return CpptrajState::ERR; + } + offsets.push_back( argIn.getKeyDouble("by", 0) ); + } + if (argIn.Contains("above")) { + criteria.push_back(GREATER_THAN); + vals.push_back( argIn.getKeyDouble("above", 0) ); + if (!argIn.Contains("by")) { + mprinterr("Error: 'by ' argument missing for 'above'\n"); + return CpptrajState::ERR; + } + offsets.push_back( argIn.getKeyDouble("by", 0) ); + } + if (criteria.empty()) { + mprinterr("Error: shift requires 'below by ' or 'above by \n"); + return CpptrajState::ERR; + } + // Sanity checks + if (criteria.size() != vals.size()) { + mprinterr("Error: Missing values for above/below; have %zu, expected %zu.\n", + vals.size(), criteria.size()); + return CpptrajState::ERR; + } + if (criteria.size() != offsets.size()) { + mprinterr("Error: Missing offsets for above/below; have %zu, expected %zu.\n", + offsets.size(), criteria.size()); + return CpptrajState::ERR; + } + for (unsigned int idx = 0; idx < criteria.size(); idx++) + { + if (criteria[idx] == LESS_THAN) + mprintf("\tValues below %g will be shifted by %g\n", vals[idx], offsets[idx]); + else if (criteria[idx] == GREATER_THAN) + mprintf("\tValues above %g will be shifted by %g\n", vals[idx], offsets[idx]); + } + + return CpptrajState::OK; +} diff --git a/src/Exec_DataSetCmd.h b/src/Exec_DataSetCmd.h index e2c49728f2..998bb741a5 100644 --- a/src/Exec_DataSetCmd.h +++ b/src/Exec_DataSetCmd.h @@ -33,5 +33,7 @@ class Exec_DataSetCmd : public Exec { RetType ChangeModeType(CpptrajState const&, ArgList&); static void Help_InvertSets(); RetType InvertSets(CpptrajState&, ArgList&); + static void Help_Shift(); + RetType ShiftData(CpptrajState&, ArgList&); }; #endif From 373a8bd5afd48c936f9459ab1b8aee8b54c094ce Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 21 Apr 2020 16:18:55 -0400 Subject: [PATCH 2/6] DRR - Ensure all data sets are modified. --- src/DataSet_1D.h | 2 ++ src/DataSet_Mesh.h | 5 +-- src/DataSet_double.h | 5 +-- src/DataSet_float.h | 5 +-- src/DataSet_integer.h | 1 + src/DataSet_pH.h | 1 + src/Exec_DataSetCmd.cpp | 69 +++++++++++++++++++++++++++++++---------- 7 files changed, 65 insertions(+), 23 deletions(-) diff --git a/src/DataSet_1D.h b/src/DataSet_1D.h index 1e5c2a6447..fb6fc779c3 100644 --- a/src/DataSet_1D.h +++ b/src/DataSet_1D.h @@ -20,6 +20,8 @@ class DataSet_1D : public DataSet { virtual double Xcrd(size_t) const = 0; /// \return Memory address at position cast to void *. TODO may not need this anymore. virtual const void* VoidPtr(size_t) const = 0; + /// Set Y value at given index + virtual void SetY(size_t, double) = 0; // ------------------------------------------- /// \return Average over set Y values double Avg() const { return Avg( 0 ); } diff --git a/src/DataSet_Mesh.h b/src/DataSet_Mesh.h index 6f3b8f9c76..dd9be5322e 100644 --- a/src/DataSet_Mesh.h +++ b/src/DataSet_Mesh.h @@ -28,9 +28,10 @@ class DataSet_Mesh : public DataSet_1D { int MemAlloc(SizeArray const&); void CopyBlock(size_t, const DataSet*, size_t, size_t); // ----- DataSet_1D functions ---------------- - double Dval(size_t idx) const { return mesh_y_[idx]; } - double Xcrd(size_t idx) const { return mesh_x_[idx]; } + double Dval(size_t idx) const { return mesh_y_[idx]; } + double Xcrd(size_t idx) const { return mesh_x_[idx]; } const void* VoidPtr(size_t) const; + void SetY(size_t idx, double y) { mesh_y_[idx] = y; } // ------------------------------------------- inline void AddXY(double,double); double X(int i) const { return mesh_x_[i]; } diff --git a/src/DataSet_double.h b/src/DataSet_double.h index 4232245fb5..b1cc6dd784 100644 --- a/src/DataSet_double.h +++ b/src/DataSet_double.h @@ -34,9 +34,10 @@ class DataSet_double : public DataSet_1D { int MemAlloc(SizeArray const&); void CopyBlock(size_t, const DataSet*, size_t, size_t); // ----- DataSet_1D functions ---------------- - double Dval(size_t idx) const { return Data_[idx]; } - double Xcrd(size_t idx) const { return Dim(0).Coord(idx); } + double Dval(size_t idx) const { return Data_[idx]; } + double Xcrd(size_t idx) const { return Dim(0).Coord(idx); } const void* VoidPtr(size_t idx) const { return (void*)(&(Data_[0])+idx); } + void SetY(size_t idx, double y) { Data_[idx] = y; } private: std::vector Data_; }; diff --git a/src/DataSet_float.h b/src/DataSet_float.h index 7bed6b349d..d03457a1b5 100644 --- a/src/DataSet_float.h +++ b/src/DataSet_float.h @@ -28,9 +28,10 @@ class DataSet_float : public DataSet_1D { int MemAlloc(SizeArray const&); void CopyBlock(size_t, const DataSet*, size_t, size_t); // ----- DataSet_1D functions ---------------- - double Dval(size_t idx) const { return (double)Data_[idx]; } - double Xcrd(size_t idx) const { return Dim(0).Coord(idx); } + double Dval(size_t idx) const { return (double)Data_[idx]; } + double Xcrd(size_t idx) const { return Dim(0).Coord(idx); } const void* VoidPtr(size_t idx) const { return (void*)(&(Data_[0])+idx); } + void SetY(size_t idx, double y) { Data_[idx] = (float)y; } // ------------------------------------------- float* Ptr() { return &(Data_[0]); } private: diff --git a/src/DataSet_integer.h b/src/DataSet_integer.h index 34fdbc8c09..9e0123fc2b 100644 --- a/src/DataSet_integer.h +++ b/src/DataSet_integer.h @@ -22,6 +22,7 @@ class DataSet_integer : public DataSet_1D { # endif // ----- DataSet_1D functions ---------------- double Xcrd(size_t idx) const { return Dim(0).Coord(idx); } + void SetY(size_t idx, double y) { SetElement(idx, (int)y); } // ------------------------------------------- //typedef std::vector::iterator iterator; //iterator begin() { return Data_.begin(); } diff --git a/src/DataSet_pH.h b/src/DataSet_pH.h index dd4f77076b..90e6ad3f0f 100644 --- a/src/DataSet_pH.h +++ b/src/DataSet_pH.h @@ -27,6 +27,7 @@ class DataSet_pH : public DataSet_1D { double Dval(size_t i) const { return (double)states_[i]; } double Xcrd(size_t idx) const { return Dim(0).Coord(idx); } const void* VoidPtr(size_t idx) const { return (void*)(&(states_[0])+idx); } + void SetY(size_t i, double y) { states_[i] = (int)y; } // ------------------------------------------- void Resize(size_t, int); void SetResidueInfo(Cph::CpRes const& r) { res_ = r; } diff --git a/src/Exec_DataSetCmd.cpp b/src/Exec_DataSetCmd.cpp index d3e4475d05..084240afb7 100644 --- a/src/Exec_DataSetCmd.cpp +++ b/src/Exec_DataSetCmd.cpp @@ -82,43 +82,43 @@ Exec::RetType Exec_DataSetCmd::Execute(CpptrajState& State, ArgList& argIn) { mprintf("\tChanging legend '%s' to '%s'\n", ds->legend(), legend.c_str()); ds->SetLegend( legend ); // --------------------------------------------- - } else if (argIn.hasKey("outformat")) { // Change double precision set output format + } else if (argIn.hasKey("outformat")) { // Change double precision set output format err = ChangeOutputFormat(State, argIn); // --------------------------------------------- - } else if (argIn.hasKey("remove")) { // Remove data sets by various criteria + } else if (argIn.hasKey("remove")) { // Remove data sets by various criteria err = Remove(State, argIn); // --------------------------------------------- - } else if (argIn.hasKey("makexy")) { // Combine values from two sets into 1 + } else if (argIn.hasKey("makexy")) { // Combine values from two sets into 1 err = MakeXY(State, argIn); // --------------------------------------------- - } else if (argIn.hasKey("make2d")) { // Create 2D matrix from 1D set + } else if (argIn.hasKey("make2d")) { // Create 2D matrix from 1D set err = Make2D(State, argIn); // --------------------------------------------- } else if (argIn.hasKey("vectorcoord")) { // Extract vector X/Y/Z coord as new set err = VectorCoord(State, argIn); // --------------------------------------------- - } else if (argIn.hasKey("filter")) { // Filter points in data set to make new data set + } else if (argIn.hasKey("filter")) { // Filter points in data set to make new data set err = Filter(State, argIn); // --------------------------------------------- - } else if (argIn.hasKey("cat")) { // Concatenate two or more data sets + } else if (argIn.hasKey("cat")) { // Concatenate two or more data sets err = Concatenate(State, argIn); // --------------------------------------------- - } else if (argIn.hasKey("droppoints")) { // Drop points from set + } else if (argIn.hasKey("droppoints")) { // Drop points from set err = ModifyPoints(State, argIn, true); // --------------------------------------------- - } else if (argIn.hasKey("keeppoints")) { // Keep points in set + } else if (argIn.hasKey("keeppoints")) { // Keep points in set err = ModifyPoints(State, argIn, false); // --------------------------------------------- - } else if (argIn.hasKey("dim")) { // Modify dimension of set(s) + } else if (argIn.hasKey("dim")) { // Modify dimension of set(s) err = ChangeDim(State, argIn); // --------------------------------------------- - } else if (argIn.hasKey("invert")) { // Invert set(s) X/Y, create new sets + } else if (argIn.hasKey("invert")) { // Invert set(s) X/Y, create new sets err = InvertSets(State, argIn); // --------------------------------------------- - } else if (argIn.hasKey("shift")) { // Shift data in set(s) that match criteria by offset + } else if (argIn.hasKey("shift")) { // Shift data in set(s) that match criteria by offset err = ShiftData(State, argIn); // --------------------------------------------- - } else { // Default: change mode/type for one or more sets. + } else { // Default: change mode/type for one or more sets. err = ChangeModeType(State, argIn); } return err; @@ -847,6 +847,7 @@ Exec::RetType Exec_DataSetCmd::ChangeModeType(CpptrajState const& State, ArgList return CpptrajState::OK; } +// Exec_DataSetCmd::Help_InvertSets() void Exec_DataSetCmd::Help_InvertSets() { mprintf(" invert ... name [legendset ]\n" " Given M input sets of length N, create N new sets of length M by\n" @@ -994,13 +995,47 @@ Exec::RetType Exec_DataSetCmd::ShiftData(CpptrajState& State, ArgList& argIn) { offsets.size(), criteria.size()); return CpptrajState::ERR; } - for (unsigned int idx = 0; idx < criteria.size(); idx++) + for (unsigned int ii = 0; ii < criteria.size(); ii++) { - if (criteria[idx] == LESS_THAN) - mprintf("\tValues below %g will be shifted by %g\n", vals[idx], offsets[idx]); - else if (criteria[idx] == GREATER_THAN) - mprintf("\tValues above %g will be shifted by %g\n", vals[idx], offsets[idx]); + if (criteria[ii] == LESS_THAN) + mprintf("\tValues below %g will be shifted by %g\n", vals[ii], offsets[ii]); + else if (criteria[ii] == GREATER_THAN) + mprintf("\tValues above %g will be shifted by %g\n", vals[ii], offsets[ii]); } + // Loop over all DataSet arguments + std::string ds_arg = argIn.GetStringNext(); + if (ds_arg.empty()) { + mprinterr("Error: No sets specfied.\n"); + return CpptrajState::ERR; + } + while (!ds_arg.empty()) { + DataSetList dsl = State.DSL().GetMultipleSets( ds_arg ); + for (DataSetList::const_iterator ds = dsl.begin(); ds != dsl.end(); ++ds) + { + if ((*ds)->Group() != DataSet::SCALAR_1D) { + mprintf("Warning: Set '%s' is not scalar 1D, skipping.\n", (*ds)->legend()); + } else { + DataSet_1D& set = static_cast( *(*ds) ); + mprintf("\t%s\n", set.legend()); + // Check value against all criteria, modify by offset if necessary + for (unsigned int idx = 0; idx < set.Size(); idx++) + { + double dval = set.Dval(idx); + mprintf("DBG: %u %g", idx, dval); + for (unsigned int ii = 0; ii < criteria.size(); ii++) + { + if (criteria[ii] == LESS_THAN && dval < vals[ii]) + dval += offsets[ii]; + else if (criteria[ii] == GREATER_THAN && dval > vals[ii]) + dval += offsets[ii]; + } + mprintf(" %g\n", dval); + set.SetY( idx, dval ); + } // END loop over set values + } + } // END loop over sets + ds_arg = argIn.GetStringNext(); + } // END loop over data set args return CpptrajState::OK; } From f552990cabd5391f5f399fbde23343e24f4251dc Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 21 Apr 2020 16:40:50 -0400 Subject: [PATCH 3/6] Start ensuring that modified sets are written --- src/DataFile.cpp | 15 +++++++++++++++ src/DataFile.h | 2 ++ src/DataFileList.cpp | 9 +++++++++ src/DataFileList.h | 4 ++++ src/Exec_DataSetCmd.cpp | 7 +++++++ src/Exec_DataSetCmd.h | 2 ++ 6 files changed, 39 insertions(+) diff --git a/src/DataFile.cpp b/src/DataFile.cpp index e832416ea6..3fefcf445a 100644 --- a/src/DataFile.cpp +++ b/src/DataFile.cpp @@ -364,6 +364,21 @@ int DataFile::RemoveDataSet(DataSet* dataIn) { return 0; } +/** \return True if this DataFile contains any of the sets in the given set list. + * Matches are determined via memory address. + */ +bool DataFile::ContainsAnyOfSets(std::vector const& setsIn) const { + for (std::vector::const_iterator ds0 = setsIn.begin(); + ds0 != setsIn.end(); ++ds0) + { + DataSet* tgt = *ds0; + for (DataSetList::const_iterator ds1 = SetList_.begin(); + ds1 != SetList_.end(); ++ds1) + if (tgt == *ds1) return true; + } + return false; +} + // GetPrecisionArg() static inline int GetPrecisionArg(std::string const& prec_str, int& width, int& prec) { diff --git a/src/DataFile.h b/src/DataFile.h index 0615488d1d..4da2653e06 100644 --- a/src/DataFile.h +++ b/src/DataFile.h @@ -62,6 +62,8 @@ class DataFile { int AddDataSet(DataSet*); /// Remove a set from the DataFile. int RemoveDataSet(DataSet*); + /// \return True if this DataFile contains any of the sets in given DataSetList + bool ContainsAnyOfSets(std::vector const&) const; /// Process DataFile-related arguments int ProcessArgs(ArgList&); int ProcessArgs(std::string const&); // TODO: Determine where this is used diff --git a/src/DataFileList.cpp b/src/DataFileList.cpp index a3b11ec7a5..fa9f17676e 100644 --- a/src/DataFileList.cpp +++ b/src/DataFileList.cpp @@ -382,6 +382,15 @@ void DataFileList::ResetWriteStatus() { (*df)->SetDFLwrite( true ); } +/** Check all DataFiles for sets in the given DataSetList. For DataFiles + * that contain any of these sets, reset their write status. + */ +void DataFileList::ResetWriteStatIfContain(std::vector const& setsIn) { + for (DFarray::iterator df = fileList_.begin(); df != fileList_.end(); ++df) + if ( (*df)->ContainsAnyOfSets( setsIn ) ) + (*df)->SetDFLwrite( true ); +} + // DataFileList::ProcessDataFileArgs() /** Process command relating to data files. */ int DataFileList::ProcessDataFileArgs(ArgList& dataArg) { diff --git a/src/DataFileList.h b/src/DataFileList.h index 83b83302e0..f3d564b19a 100644 --- a/src/DataFileList.h +++ b/src/DataFileList.h @@ -54,7 +54,11 @@ class DataFileList { void WriteAllDF(); /// \return true if DataFiles have not yet been written. bool UnwrittenData() const; + /// Reset the write status of all DataFiles so they will be written void ResetWriteStatus(); + /// Reset the write status of DataFiles containing any of the input sets. + void ResetWriteStatIfContain(std::vector const& dslIn); + /// Process any data file args int ProcessDataFileArgs(ArgList&); int Debug() const { return debug_; } int EnsembleNum() const { return ensembleNum_; } diff --git a/src/Exec_DataSetCmd.cpp b/src/Exec_DataSetCmd.cpp index 084240afb7..cb9c036ce7 100644 --- a/src/Exec_DataSetCmd.cpp +++ b/src/Exec_DataSetCmd.cpp @@ -74,6 +74,7 @@ void Exec_DataSetCmd::Help(ArgList& argIn) const { // Exec_DataSetCmd::Execute() Exec::RetType Exec_DataSetCmd::Execute(CpptrajState& State, ArgList& argIn) { + modifiedSets_.clear(); RetType err = CpptrajState::OK; if (argIn.Contains("legend")) { // Set legend for one data set std::string legend = argIn.GetStringKey("legend"); @@ -121,6 +122,11 @@ Exec::RetType Exec_DataSetCmd::Execute(CpptrajState& State, ArgList& argIn) { } else { // Default: change mode/type for one or more sets. err = ChangeModeType(State, argIn); } + // If any sets were modified, write out data again. + if (err == CpptrajState::OK && !modifiedSets_.empty()) { + State.DFL().ResetWriteStatIfContain( modifiedSets_ ); + State.DFL().WriteAllDF(); + } return err; } @@ -1032,6 +1038,7 @@ Exec::RetType Exec_DataSetCmd::ShiftData(CpptrajState& State, ArgList& argIn) { mprintf(" %g\n", dval); set.SetY( idx, dval ); } // END loop over set values + modifiedSets_.push_back( *ds ); } } // END loop over sets ds_arg = argIn.GetStringNext(); diff --git a/src/Exec_DataSetCmd.h b/src/Exec_DataSetCmd.h index 998bb741a5..d9f17149f1 100644 --- a/src/Exec_DataSetCmd.h +++ b/src/Exec_DataSetCmd.h @@ -35,5 +35,7 @@ class Exec_DataSetCmd : public Exec { RetType InvertSets(CpptrajState&, ArgList&); static void Help_Shift(); RetType ShiftData(CpptrajState&, ArgList&); + + std::vector modifiedSets_; }; #endif From b042b6dfff3e155b6d0e30f1a03d9394d2fab667 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 21 Apr 2020 16:44:53 -0400 Subject: [PATCH 4/6] Remove debug info --- src/Exec_DataSetCmd.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Exec_DataSetCmd.cpp b/src/Exec_DataSetCmd.cpp index cb9c036ce7..eb88c1cd15 100644 --- a/src/Exec_DataSetCmd.cpp +++ b/src/Exec_DataSetCmd.cpp @@ -1022,12 +1022,12 @@ Exec::RetType Exec_DataSetCmd::ShiftData(CpptrajState& State, ArgList& argIn) { mprintf("Warning: Set '%s' is not scalar 1D, skipping.\n", (*ds)->legend()); } else { DataSet_1D& set = static_cast( *(*ds) ); - mprintf("\t%s\n", set.legend()); + mprintf("\tModifying set: %s\n", set.legend()); // Check value against all criteria, modify by offset if necessary for (unsigned int idx = 0; idx < set.Size(); idx++) { double dval = set.Dval(idx); - mprintf("DBG: %u %g", idx, dval); + //mprintf("DBG: %u %g", idx, dval); for (unsigned int ii = 0; ii < criteria.size(); ii++) { if (criteria[ii] == LESS_THAN && dval < vals[ii]) @@ -1035,7 +1035,7 @@ Exec::RetType Exec_DataSetCmd::ShiftData(CpptrajState& State, ArgList& argIn) { else if (criteria[ii] == GREATER_THAN && dval > vals[ii]) dval += offsets[ii]; } - mprintf(" %g\n", dval); + //mprintf(" %g\n", dval); set.SetY( idx, dval ); } // END loop over set values modifiedSets_.push_back( *ds ); From a7e5acdbfdfdab21c4017ad44a9e780309547513 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 21 Apr 2020 16:50:40 -0400 Subject: [PATCH 5/6] Update manual and fix help. --- doc/cpptraj.lyx | 79 +++++++++++++++++++++++++++++++++++++++++ src/Exec_DataSetCmd.cpp | 2 +- 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/doc/cpptraj.lyx b/doc/cpptraj.lyx index 37d43d4546..e4f2a92ea6 100644 --- a/doc/cpptraj.lyx +++ b/doc/cpptraj.lyx @@ -7809,6 +7809,11 @@ dataset { legend | name [legendset ] | \end_layout +\begin_layout LyX-Code + shift [above by ] [below by ] + ... +\end_layout + \begin_layout LyX-Code [mode ] [type ] [ ...] \end_layout @@ -8180,6 +8185,61 @@ name> Inverted output set name. ] String data set containing legends \end_layout +\end_deeper +\begin_layout Description +shift +\begin_inset space ~ +\end_inset + + +\end_layout + +\begin_deeper +\begin_layout Description +[above +\begin_inset space ~ +\end_inset + + +\begin_inset space ~ +\end_inset + +by +\begin_inset space ~ +\end_inset + +] Values in set(s) above will be shifted by . +\end_layout + +\begin_layout Description +[below +\begin_inset space ~ +\end_inset + + +\begin_inset space ~ +\end_inset + +by +\begin_inset space ~ +\end_inset + +] Values in set(s) below will be shifted by . +\end_layout + +\begin_layout Description + +\begin_inset space ~ +\end_inset + +... + Set(s) to shift. +\end_layout + \end_deeper \begin_layout Description [mode @@ -9219,6 +9279,25 @@ dataset dim xdim label Simulation min 1 step 1 Inverted* writedata statecount.agr Inverted* \end_layout +\begin_layout Standard +The dataset shift command can be used for wrapping circular values, such + as torsions. + For example, to ensure a pucker has a range from 0 to 360 instead of -180 + to 180: +\end_layout + +\begin_layout LyX-Code +pucker Furanoid @C2 @C3 @C4 @C5 @O2 cremer out CremerF.dat amplitude +\end_layout + +\begin_layout LyX-Code +run +\end_layout + +\begin_layout LyX-Code +dataset shift Furanoid below 0 by 360 +\end_layout + \begin_layout Subsection debug | prnlev \end_layout diff --git a/src/Exec_DataSetCmd.cpp b/src/Exec_DataSetCmd.cpp index eb88c1cd15..b9f9d3390d 100644 --- a/src/Exec_DataSetCmd.cpp +++ b/src/Exec_DataSetCmd.cpp @@ -958,7 +958,7 @@ Exec::RetType Exec_DataSetCmd::InvertSets(CpptrajState& State, ArgList& argIn) { // Exec_DataSetCmd::Help_Shift() void Exec_DataSetCmd::Help_Shift() { - mprintf(" shift [above by ] [below by ] ... ...\n" + mprintf(" shift [above by ] [below by ] ...\n" " Shift the values in given set(s) by an offset if the points meet\n" " certain criteria.\n"); } From dd19ef5e1ed7de22b36b7dcf04688ddb00cffea0 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 21 Apr 2020 16:53:58 -0400 Subject: [PATCH 6/6] Revision bump for addition of 'dataset shift' --- src/Version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Version.h b/src/Version.h index dabc5ca42a..ad0bfc4585 100644 --- a/src/Version.h +++ b/src/Version.h @@ -12,7 +12,7 @@ * Whenever a number that precedes is incremented, all subsequent * numbers should be reset to 0. */ -#define CPPTRAJ_INTERNAL_VERSION "V4.25.12" +#define CPPTRAJ_INTERNAL_VERSION "V4.25.13" /// PYTRAJ relies on this #define CPPTRAJ_VERSION_STRING CPPTRAJ_INTERNAL_VERSION #endif