Skip to content

Commit

Permalink
Fixes to documentation generators for PlumedToHTML (#1081)
Browse files Browse the repository at this point in the history
* Rewritten code for getting the descriptions of values so that we get keywords in a way that will work with LOAD

* Modified the way the documentation is got when you output the value dictionary in driver so that you can use action labels that have dots in them

Also added a warning to try to stop people from using dots in the labels for actions as it is not a great idea

* Changed names of actions created by the XAngles shortcut to ensure that an input on the nest continues working

* Fixed final problems with building nest inputs and ran astyle

---------

Co-authored-by: Gareth Aneurin Tribello <garethtribello@gareths-mbp.mp.qub.ac.uk>
  • Loading branch information
gtribello and Gareth Aneurin Tribello authored May 22, 2024
1 parent 2434e5c commit f9b0bd9
Show file tree
Hide file tree
Showing 8 changed files with 34 additions and 18 deletions.
27 changes: 16 additions & 11 deletions src/cltools/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
#include "core/ActionWithValue.h"
#include "core/ActionWithVirtualAtom.h"
#include "core/ActionShortcut.h"
#include "core/ActionRegister.h"
#include "tools/Communicator.h"
#include "tools/Random.h"
#include "tools/Pbc.h"
Expand Down Expand Up @@ -788,14 +787,17 @@ int Driver<real>::main(FILE* in,FILE*out,Communicator& pc) {
}
ActionWithValue* av=dynamic_cast<ActionWithValue*>(pp.get());
if( av && av->getNumberOfComponents()>0 ) {
Keywords keys; actionRegister().getKeywords( av->getName(), keys );
Keywords keys; p.getKeywordsForAction( av->getName(), keys );
if( firsta ) { valuefile.printf(" \"%s\" : {\n \"action\" : \"%s\"", av->getLabel().c_str(), keys.getDisplayName().c_str() ); firsta=false; }
else valuefile.printf(",\n \"%s\" : {\n \"action\" : \"%s\"", av->getLabel().c_str(), keys.getDisplayName().c_str() );
for(unsigned i=0; i<av->getNumberOfComponents(); ++i) {
Value* myval = av->copyOutput(i); std::string compname = myval->getName(), description; std::size_t dot=compname.find(".");
if( dot!=std::string::npos ) {
std::string cname = compname.substr(dot+1); description = av->getOutputComponentDescription( cname, keys );
} else description = keys.getOutputComponentDescription(".#!value");
Value* myval = av->copyOutput(i); std::string compname = myval->getName(), description;
if( av->getLabel()==compname ) {
description = keys.getOutputComponentDescription(".#!value");
} else {
std::size_t dot=compname.find(av->getLabel() + "."); std::string cname = compname.substr(dot + av->getLabel().length() + 1);
description = av->getOutputComponentDescription( cname, keys );
}
if( description.find("\\")!=std::string::npos ) error("found invalid backslash character in documentation for component " + compname + " in action " + av->getName() + " with label " + av->getLabel() );
valuefile.printf(",\n \"%s\" : { \"type\": \"%s\", \"description\": \"%s\" }", myval->getName().c_str(), myval->getValueType().c_str(), description.c_str() );
}
Expand All @@ -808,7 +810,7 @@ int Driver<real>::main(FILE* in,FILE*out,Communicator& pc) {

if( firsta ) { valuefile.printf(" \"shortcut_%s\" : {\n \"action\" : \"%s\"", as->getShortcutLabel().c_str(), as->getName().c_str() ); firsta=false; }
else valuefile.printf(",\n \"shortcut_%s\" : {\n \"action\" : \"%s\"", as->getShortcutLabel().c_str(), as->getName().c_str() );
Keywords keys; actionRegister().getKeywords( as->getName(), keys );
Keywords keys; p.getKeywordsForAction( as->getName(), keys );
for(unsigned i=0; i<cnames.size(); ++i) {
ActionWithValue* av2=p.getActionSet().selectWithLabel<ActionWithValue*>( cnames[i] );
if( !av2 ) plumed_merror("could not find value created by shortcut with name " + cnames[i] );
Expand All @@ -820,10 +822,13 @@ int Driver<real>::main(FILE* in,FILE*out,Communicator& pc) {
valuefile.printf(",\n \"%s\" : { \"type\": \"%s\", \"description\": \"%s\" }", myval->getName().c_str(), myval->getValueType().c_str(), description.c_str() );
} else {
for(unsigned j=0; j<av2->getNumberOfComponents(); ++j) {
Value* myval = av2->copyOutput(j); std::string compname = myval->getName(), description; std::size_t dot=compname.find(".");
if( dot!=std::string::npos ) {
std::string cname = compname.substr(dot+1); description = av2->getOutputComponentDescription( cname, keys );
} else plumed_merror("should not be outputting description of value from action when using shortcuts");
Value* myval = av2->copyOutput(j); std::string compname = myval->getName(), description;
if( av2->getLabel()==compname ) {
plumed_merror("should not be outputting description of value from action when using shortcuts");
} else {
std::size_t dot=compname.find(av2->getLabel() + "."); std::string cname = compname.substr(dot+av2->getLabel().length() + 1);
description = av2->getOutputComponentDescription( cname, keys );
}
if( description.find("\\")!=std::string::npos ) error("found invalid backslash character in documentation for component " + compname + " in action " + av2->getName() + " with label " + av2->getLabel() );
valuefile.printf(",\n \"%s\" : { \"type\": \"%s\", \"description\": \"%s\" }", myval->getName().c_str(), myval->getValueType().c_str(), description.c_str() );
}
Expand Down
2 changes: 1 addition & 1 deletion src/core/Action.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ Action::Action(const ActionOptions&ao):
if(label.length()==0) {
std::string s; Tools::convert(plumed.getActionSet().size()-plumed.getActionSet().select<ActionForInterface*>().size(),s);
label="@"+s;
}
} else if ( label.find(".")!=std::string::npos ) warning("using full stop in an action label should be avaoided as . has a special meaning in PLUMED action labels");
if( plumed.getActionSet().selectWithLabel<Action*>(label) ) error("label " + label + " has been already used");
if( !keywords.exists("NO_ACTION_LOG") ) log.printf(" with label %s\n",label.c_str());
if ( keywords.exists("UPDATE_FROM") ) parse("UPDATE_FROM",update_from);
Expand Down
4 changes: 4 additions & 0 deletions src/core/ActionRegister.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,8 @@ bool ActionRegister::getKeywords(const std::string& action, Keywords& keys) {
return false;
}

void ActionRegister::getKeywords(const std::vector<void*> & images, const std::string& action, Keywords& keys) {
auto content=get(images,action); keys.thisactname = action; content.keys(keys);
}

}
1 change: 1 addition & 0 deletions src/core/ActionRegister.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class ActionRegister:
bool printManual(const std::string& action, const bool& vimout, const bool& spellout);
/// Retrieve a keywords object for a particular action
bool getKeywords( const std::string& action, Keywords& keys );
void getKeywords(const std::vector<void*> & images, const std::string& action, Keywords& keys);
/// Print out a template command for an action
bool printTemplate(const std::string& action, bool include_optional);
std::vector<std::string> getActionNames() const;
Expand Down
1 change: 0 additions & 1 deletion src/core/ActionWithValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,6 @@ void ActionWithValue::addComponentWithDerivatives( const std::string& name, cons

std::string ActionWithValue::getOutputComponentDescription( const std::string& cname, const Keywords& keys ) const {
std::size_t und=cname.find_last_of("_"); std::size_t hyph=cname.find_first_of("-");
if( und!=std::string::npos && hyph!=std::string::npos ) plumed_merror("cannot use underscore and hyphen in name");
if( und!=std::string::npos ) return keys.getOutputComponentDescription(cname.substr(und)) + " This particular component measures this quantity for the input CV named " + cname.substr(0,und);
if( hyph!=std::string::npos ) return keys.getOutputComponentDescription(cname.substr(0,hyph)) + " This is the " + cname.substr(hyph+1) + "th of these quantities";
plumed_massert( keys.outputComponentExists(cname), "component " + cname + " does not exist in " + keys.getDisplayName() + " if the component names are customizable then you should override this function" );
Expand Down
4 changes: 4 additions & 0 deletions src/core/PlumedMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1488,6 +1488,10 @@ bool PlumedMain::parseOnlyMode() const {
return doParseOnly;
}

void PlumedMain::getKeywordsForAction( const std::string& action, Keywords& keys ) const {
actionRegister().getKeywords( dlloader.getHandles(), action, keys );
}

#ifdef __PLUMED_HAS_PYTHON
// This is here to stop cppcheck throwing an error
#endif
Expand Down
3 changes: 3 additions & 0 deletions src/core/PlumedMain.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class FileBase;
class TypesafePtr;
class IFile;
class Units;
class Keywords;
class DataPassingTools;

/**
Expand Down Expand Up @@ -523,6 +524,8 @@ class PlumedMain:
void plumedQuantityToMD( const std::string& unit, const double& eng, const TypesafePtr & m) const ;
/// Take a typesafe pointer from the MD code and convert it to a double
double MDQuantityToPLUMED( const std::string& unit, const TypesafePtr & m) const ;
/// Get the keywords for a particular action
void getKeywordsForAction( const std::string& action, Keywords& keys ) const ;
};

/////
Expand Down
10 changes: 5 additions & 5 deletions src/multicolvar/XAngle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ XAngle::XAngle(const ActionOptions& ao):
ActionShortcut(ao)
{
// Create distances
std::string dline = getShortcutLabel() + ": DISTANCE COMPONENTS";
std::string dline = getShortcutLabel() + "_dists: DISTANCE COMPONENTS";
for(unsigned i=1;; ++i) {
std::string atstring; parseNumbered("ATOMS",i,atstring);
if( atstring.length()==0 ) break;
Expand All @@ -85,11 +85,11 @@ XAngle::XAngle(const ActionOptions& ao):
}
readInputLine( dline );
// Normalize the vectors
readInputLine( getShortcutLabel() + "_norm2: COMBINE ARG=" + getShortcutLabel() + ".x" + "," + getShortcutLabel() + ".y," + getShortcutLabel() + ".z POWERS=2,2,2 PERIODIC=NO");
readInputLine( getShortcutLabel() + "_norm2: COMBINE ARG=" + getShortcutLabel() + "_dists.x" + "," + getShortcutLabel() + "_dists.y," + getShortcutLabel() + "_dists.z POWERS=2,2,2 PERIODIC=NO");
readInputLine( getShortcutLabel() + "_norm: CUSTOM ARG=" + getShortcutLabel() + "_norm2 FUNC=sqrt(x) PERIODIC=NO");
readInputLine( getShortcutLabel() + "_norm_x: CUSTOM ARG=" + getShortcutLabel() + ".x," + getShortcutLabel() + "_norm FUNC=x/y PERIODIC=NO");
readInputLine( getShortcutLabel() + "_norm_y: CUSTOM ARG=" + getShortcutLabel() + ".y," + getShortcutLabel() + "_norm FUNC=x/y PERIODIC=NO");
readInputLine( getShortcutLabel() + "_norm_z: CUSTOM ARG=" + getShortcutLabel() + ".z," + getShortcutLabel() + "_norm FUNC=x/y PERIODIC=NO");
readInputLine( getShortcutLabel() + "_norm_x: CUSTOM ARG=" + getShortcutLabel() + "_dists.x," + getShortcutLabel() + "_norm FUNC=x/y PERIODIC=NO");
readInputLine( getShortcutLabel() + "_norm_y: CUSTOM ARG=" + getShortcutLabel() + "_dists.y," + getShortcutLabel() + "_norm FUNC=x/y PERIODIC=NO");
readInputLine( getShortcutLabel() + "_norm_z: CUSTOM ARG=" + getShortcutLabel() + "_dists.z," + getShortcutLabel() + "_norm FUNC=x/y PERIODIC=NO");
// Now compute the angles with matheval
if( getName()=="XANGLES" ) readInputLine( getShortcutLabel() + "_ang: CUSTOM FUNC=acos(x) PERIODIC=NO ARG=" + getShortcutLabel() + "_norm_x");
if( getName()=="YANGLES" ) readInputLine( getShortcutLabel() + "_ang: CUSTOM FUNC=acos(x) PERIODIC=NO ARG=" + getShortcutLabel() + "_norm_y");
Expand Down

1 comment on commit f9b0bd9

@PlumedBot
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found broken examples in automatic/ANGLES.tmp
Found broken examples in automatic/ANN.tmp
Found broken examples in automatic/CAVITY.tmp
Found broken examples in automatic/CLASSICAL_MDS.tmp
Found broken examples in automatic/CLUSTER_DIAMETER.tmp
Found broken examples in automatic/CLUSTER_DISTRIBUTION.tmp
Found broken examples in automatic/CLUSTER_PROPERTIES.tmp
Found broken examples in automatic/CONSTANT.tmp
Found broken examples in automatic/CONTACT_MATRIX.tmp
Found broken examples in automatic/CONTACT_MATRIX_PROPER.tmp
Found broken examples in automatic/COORDINATIONNUMBER.tmp
Found broken examples in automatic/DFSCLUSTERING.tmp
Found broken examples in automatic/DISTANCE_FROM_CONTOUR.tmp
Found broken examples in automatic/EDS.tmp
Found broken examples in automatic/EMMI.tmp
Found broken examples in automatic/ENVIRONMENTSIMILARITY.tmp
Found broken examples in automatic/FIND_CONTOUR.tmp
Found broken examples in automatic/FIND_CONTOUR_SURFACE.tmp
Found broken examples in automatic/FIND_SPHERICAL_CONTOUR.tmp
Found broken examples in automatic/FOURIER_TRANSFORM.tmp
Found broken examples in automatic/FUNCPATHGENERAL.tmp
Found broken examples in automatic/FUNCPATHMSD.tmp
Found broken examples in automatic/FUNNEL.tmp
Found broken examples in automatic/FUNNEL_PS.tmp
Found broken examples in automatic/GHBFIX.tmp
Found broken examples in automatic/GPROPERTYMAP.tmp
Found broken examples in automatic/HBOND_MATRIX.tmp
Found broken examples in automatic/INCLUDE.tmp
Found broken examples in automatic/INCYLINDER.tmp
Found broken examples in automatic/INENVELOPE.tmp
Found broken examples in automatic/INTERPOLATE_GRID.tmp
Found broken examples in automatic/LOCAL_AVERAGE.tmp
Found broken examples in automatic/MAZE_OPTIMIZER_BIAS.tmp
Found broken examples in automatic/MAZE_RANDOM_ACCELERATION_MD.tmp
Found broken examples in automatic/MAZE_SIMULATED_ANNEALING.tmp
Found broken examples in automatic/MAZE_STEERED_MD.tmp
Found broken examples in automatic/MULTICOLVARDENS.tmp
Found broken examples in automatic/OUTPUT_CLUSTER.tmp
Found broken examples in automatic/PAMM.tmp
Found broken examples in automatic/PCA.tmp
Found broken examples in automatic/PCAVARS.tmp
Found broken examples in automatic/PIV.tmp
Found broken examples in automatic/PLUMED.tmp
Found broken examples in automatic/PYCVINTERFACE.tmp
Found broken examples in automatic/PYTHONFUNCTION.tmp
Found broken examples in automatic/Q3.tmp
Found broken examples in automatic/Q4.tmp
Found broken examples in automatic/Q6.tmp
Found broken examples in automatic/QUATERNION.tmp
Found broken examples in automatic/SIZESHAPE_POSITION_LINEAR_PROJ.tmp
Found broken examples in automatic/SIZESHAPE_POSITION_MAHA_DIST.tmp
Found broken examples in automatic/SPRINT.tmp
Found broken examples in automatic/TETRAHEDRALPORE.tmp
Found broken examples in automatic/TORSIONS.tmp
Found broken examples in automatic/WHAM_WEIGHTS.tmp
Found broken examples in AnalysisPP.md
Found broken examples in CollectiveVariablesPP.md
Found broken examples in MiscelaneousPP.md

Please sign in to comment.