Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modernization/keywords #1183

Merged
merged 22 commits into from
Feb 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
79d2d40
Setting typo-safe types for keyword type and datatype for keywords
Iximiel Dec 18, 2024
02fe684
removed some friend declaration to hide implementation details
Iximiel Jan 20, 2025
65d52f2
made compontne in a struct, rempoved copyData
Iximiel Jan 20, 2025
7725fcf
structured also the keyword informations
Iximiel Jan 20, 2025
c525472
reorganization of some comments
Iximiel Jan 20, 2025
6b3a04a
Documenting better the bitmask enabler
Iximiel Jan 21, 2025
7c1a69d
adjusting the documentation
Iximiel Jan 21, 2025
fe51d70
using algorithms for isActionSuffixed
Iximiel Jan 21, 2025
dc2de18
adding constexpr to BitmaskEnum operations
Iximiel Jan 21, 2025
cb3e31e
added an example in Distance, modernized also Components declaration
Iximiel Jan 21, 2025
2f76d65
restoring the flavour of removeOutputComponent with no existance checks
Iximiel Jan 21, 2025
2705408
found some merge errors
Iximiel Jan 22, 2025
ebef017
Some small adjustments for reserveFlag
Iximiel Jan 22, 2025
46dc248
adding the erase/remove shortcut
Iximiel Jan 22, 2025
65e6864
grammar fix
Iximiel Jan 22, 2025
075f8a3
compacted the argument_type into the key struct
Iximiel Jan 22, 2025
a6a55af
compacted the add and reserve methods to simplify the life of future us
Iximiel Jan 22, 2025
0afe1f4
compacting also the atomtag into keyinfo
Iximiel Jan 22, 2025
1afbafb
updating the documentation
Iximiel Jan 23, 2025
eaebbfd
Now plumed check should not hang anymore
Iximiel Jan 27, 2025
96f5041
checked that the json did not change and that cppcheck passes
Iximiel Jan 27, 2025
a9c09f2
removing removeComponet
Iximiel Feb 3, 2025
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
16 changes: 7 additions & 9 deletions src/colvar/ColvarShortcut.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,9 @@ template <class T>
void ColvarShortcut<T>::registerKeywords(Keywords& keys ) {
T::registerKeywords( keys );
keys.remove("NO_ACTION_LOG");
unsigned nkeys = keys.size();
for(unsigned i=0; i<nkeys; ++i) {
if( keys.style( keys.get(i), "atoms" ) ) {
keys.reset_style( keys.get(i), "numbered" );
for (auto& key : keys.getKeys()) {
if( keys.style( key, "atoms" ) ) {
keys.reset_style( key, "numbered" );
}
}
keys.addActionNameSuffix("_SCALAR");
Expand All @@ -53,7 +52,6 @@ ColvarShortcut<T>::ColvarShortcut(const ActionOptions&ao):
Action(ao),
ActionShortcut(ao) {
bool scalar=true;
unsigned nkeys = keywords.size();
if( getName()=="MASS" || getName()=="CHARGE" || getName()=="POSITION" ) {
std::string inpt;
parse("ATOMS",inpt);
Expand All @@ -62,12 +60,12 @@ ColvarShortcut<T>::ColvarShortcut(const ActionOptions&ao):
scalar=false;
}
}
for(unsigned i=0; i<nkeys; ++i) {
if( keywords.style( keywords.get(i), "atoms" ) ) {
for (auto& key : keywords.getKeys()) {
if( keywords.style( key, "atoms" ) ) {
std::string inpt;
parseNumbered( keywords.get(i), 1, inpt );
parseNumbered( key, 1, inpt );
if( inpt.length()>0 ) {
readInputLine( getShortcutLabel() + ": " + getName() + "_VECTOR " + keywords.get(i) + "1=" + inpt + " " + convertInputLineToString() );
readInputLine( getShortcutLabel() + ": " + getName() + "_VECTOR " + key + "1=" + inpt + " " + convertInputLineToString() );
scalar=false;
break;
}
Expand Down
15 changes: 8 additions & 7 deletions src/colvar/Distance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,17 +152,18 @@ PLUMED_REGISTER_ACTION(DistanceMulti,"DISTANCE_VECTOR")
void Distance::registerKeywords( Keywords& keys ) {
Colvar::registerKeywords( keys );
keys.setDisplayName("DISTANCE");
constexpr auto scalarOrVector = Keywords::componentType::scalar | Keywords::componentType::vector;
keys.add("atoms","ATOMS","the pair of atom that we are calculating the distance between");
keys.addFlag("COMPONENTS",false,"calculate the x, y and z components of the distance separately and store them as label.x, label.y and label.z");
keys.addFlag("SCALED_COMPONENTS",false,"calculate the a, b and c scaled components of the distance separately and store them as label.a, label.b and label.c");
keys.addOutputComponent("x","COMPONENTS","scalar/vector","the x-component of the vector connecting the two atoms");
keys.addOutputComponent("y","COMPONENTS","scalar/vector","the y-component of the vector connecting the two atoms");
keys.addOutputComponent("z","COMPONENTS","scalar/vector","the z-component of the vector connecting the two atoms");
keys.addOutputComponent("a","SCALED_COMPONENTS","scalar/vector","the normalized projection on the first lattice vector of the vector connecting the two atoms");
keys.addOutputComponent("b","SCALED_COMPONENTS","scalar/vector","the normalized projection on the second lattice vector of the vector connecting the two atoms");
keys.addOutputComponent("c","SCALED_COMPONENTS","scalar/vector","the normalized projection on the third lattice vector of the vector connecting the two atoms");
keys.addOutputComponent("x","COMPONENTS",scalarOrVector,"the x-component of the vector connecting the two atoms");
keys.addOutputComponent("y","COMPONENTS",scalarOrVector,"the y-component of the vector connecting the two atoms");
keys.addOutputComponent("z","COMPONENTS",scalarOrVector,"the z-component of the vector connecting the two atoms");
keys.addOutputComponent("a","SCALED_COMPONENTS",scalarOrVector,"the normalized projection on the first lattice vector of the vector connecting the two atoms");
keys.addOutputComponent("b","SCALED_COMPONENTS",scalarOrVector,"the normalized projection on the second lattice vector of the vector connecting the two atoms");
keys.addOutputComponent("c","SCALED_COMPONENTS",scalarOrVector,"the normalized projection on the third lattice vector of the vector connecting the two atoms");
keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
keys.setValueDescription("scalar/vector","the DISTANCE between this pair of atoms");
keys.setValueDescription(scalarOrVector,"the DISTANCE between this pair of atoms");
}

Distance::Distance(const ActionOptions&ao):
Expand Down
4 changes: 2 additions & 2 deletions src/colvar/MultiColvarTemplate.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ void MultiColvarTemplate<T>::registerKeywords(Keywords& keys ) {
T::registerKeywords( keys );
unsigned nkeys = keys.size();
for(unsigned i=0; i<nkeys; ++i) {
if( keys.style( keys.get(i), "atoms" ) ) {
keys.reset_style( keys.get(i), "numbered" );
if( keys.style( keys.getKeyword(i), "atoms" ) ) {
keys.reset_style( keys.getKeyword(i), "numbered" );
}
}
if( keys.outputComponentExists(".#!value") ) {
Expand Down
12 changes: 8 additions & 4 deletions src/core/ActionRegister.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ std::unique_ptr<Action> ActionRegister::create(const std::vector<void*> & images

auto content=get(images,ao.line[0]);
Keywords keys;
keys.thisactname = ao.line[0];
//the name of the function is not clear but does `keys.thisactname = ao.line[0];`
keys.setDisplayName(ao.line[0]);
content.keys(keys);
ActionOptions nao( ao,keys );
auto fullPath=getFullPath(images,ao.line[0]);
Expand Down Expand Up @@ -85,7 +86,8 @@ bool ActionRegister::printTemplate(const std::string& action, bool include_optio
//no need to insert the try/catch block: check will ensure that action is known
if( check(action) ) {
Keywords keys;
keys.thisactname = action;
//the name of the function is not clear but does `keys.thisactname = action;`
keys.setDisplayName(action);
get(action).keys(keys);
keys.print_template(action, include_optional);
return true;
Expand All @@ -110,7 +112,8 @@ ActionRegister::ID ActionRegister::add(std::string key,creator_pointer cp,keywor
bool ActionRegister::getKeywords(const std::string& action, Keywords& keys) {
//no need to insert the try/catch block: check will ensure that action is known
if(check(action)) {
keys.thisactname = action;
//the name of the function is not clear but does `keys.thisactname = action;`
keys.setDisplayName(action);
get(action).keys(keys);
return true;
}
Expand All @@ -119,7 +122,8 @@ bool ActionRegister::getKeywords(const std::string& action, Keywords& keys) {

void ActionRegister::getKeywords(const std::vector<void*> & images, const std::string& action, Keywords& keys) {
auto content=get(images,action);
keys.thisactname = action;
//the name of the function is not clear but does `keys.thisactname = action;`
keys.setDisplayName(action);
content.keys(keys);
}

Expand Down
44 changes: 24 additions & 20 deletions src/core/ActionShortcut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ void ActionShortcut::registerKeywords( Keywords& keys ) {
}

void ActionShortcut::readShortcutKeywords( const Keywords& keys, std::map<std::string,std::string>& keymap ) {
for(unsigned i=0; i<keys.size(); ++i) {
std::string t, keyname = keys.get(i);
for (auto& keyname:keys.getKeys()) {
std::string t;
if( keys.style( keyname, "optional") || keys.style( keyname, "compulsory") ) {
parse(keyname,t);
if( t.length()>0 ) {
Expand Down Expand Up @@ -80,15 +80,11 @@ void ActionShortcut::readInputLine( const std::string& input, bool saveline ) {
std::vector<std::string> words=Tools::getWords(input);
Tools::interpretLabel(words);
// Check if this action name has been registered
bool founds=false, found = std::find(keywords.neededActions.begin(), keywords.neededActions.end(), words[0] )!=keywords.neededActions.end();
bool founds=false;
bool found = keywords.isActionNeeded(words[0]);
// Check if we are just calling something like SUM_VECTOR using just SUM.
if( !found && words[0].find(getName())!=std::string::npos ) {
for(unsigned j=0 ; j<keywords.actionNameSuffixes.size(); ++j) {
if( (getName() + keywords.actionNameSuffixes[j])==words[0] ) {
found=true;
break;
}
}
found =keywords.isActionSuffixed(words[0],getName());
founds=true;
}
if( found ) {
Expand Down Expand Up @@ -121,17 +117,25 @@ void ActionShortcut::readInputLine( const std::string& input, bool saveline ) {
std::string av_label = av->getLabel();
if( av_label == getShortcutLabel() && av->getNumberOfComponents()==1 ) {
savedOutputs.push_back( av_label );
plumed_massert( keywords.componentHasCorrectType(".#!value", (av->copyOutput(0))->getRank(), (av->copyOutput(0))->hasDerivatives() ), "documentation for type of value is incorrect");
plumed_massert( keywords.componentHasCorrectType(".#!value",
(av->copyOutput(0))->getRank(), (av->copyOutput(0))->hasDerivatives() ),
"documentation for type of value is incorrect");
} else {
for(unsigned i=0; i<keywords.cnames.size(); ++i) {
if( av_label == getShortcutLabel() + "_" + keywords.cnames[i] ) {
for(const auto& cname: keywords.getOutputComponents()) {
if( av_label == getShortcutLabel() + "_" + cname ) {
savedOutputs.push_back( av_label );
plumed_massert( keywords.componentHasCorrectType(keywords.cnames[i], (av->copyOutput(0))->getRank(), (av->copyOutput(0))->hasDerivatives() ), "documentation for type of component " + keywords.cnames[i] + " is incorrect");
} else if( keywords.getOutputComponentFlag(keywords.cnames[i])!="default" ) {
std::string thisflag = keywords.getOutputComponentFlag(keywords.cnames[i]);
if( keywords.numbered(thisflag) && av_label.find(getShortcutLabel() + "_" + keywords.cnames[i])!=std::string::npos ) {
plumed_massert( keywords.componentHasCorrectType(cname,
(av->copyOutput(0))->getRank(),
(av->copyOutput(0))->hasDerivatives() ),
"documentation for type of component " + cname + " is incorrect");
} else if( keywords.getOutputComponentFlag(cname)!="default" ) {
std::string thisflag = keywords.getOutputComponentFlag(cname);
if( keywords.numbered(thisflag) && av_label.find(getShortcutLabel() + "_" + cname)!=std::string::npos ) {
savedOutputs.push_back( av_label );
plumed_massert( keywords.componentHasCorrectType(keywords.cnames[i], (av->copyOutput(0))->getRank(), (av->copyOutput(0))->hasDerivatives() ), "documentation for type of component " + keywords.cnames[i] + " is incorrect");
plumed_massert( keywords.componentHasCorrectType(cname,
(av->copyOutput(0))->getRank(),
(av->copyOutput(0))->hasDerivatives() ),
"documentation for type of component " + cname + " is incorrect");
}
}
}
Expand Down Expand Up @@ -186,9 +190,9 @@ void ActionShortcut::addToSavedInputLines( const std::string& line ) {
Keywords thiskeys;
actionRegister().getKeywords( actname, thiskeys );
std::vector<std::string> numberedkeys;
for(unsigned i=0; i<thiskeys.size(); ++i ) {
if( thiskeys.numbered( thiskeys.getKeyword(i) ) ) {
numberedkeys.push_back( thiskeys.getKeyword(i) );
for (auto& keyname: thiskeys.getKeys()) {
if( thiskeys.numbered( keyname ) ) {
numberedkeys.push_back( keyname );
}
}
if( numberedkeys.size()>0 && actname!="CONCATENATE" ) {
Expand Down
4 changes: 2 additions & 2 deletions src/core/ActionWithArguments.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ void ActionWithArguments::registerKeywords(Keywords& keys) {

void ActionWithArguments::parseArgumentList(const std::string&key,std::vector<Value*>&arg) {
if( keywords.getArgumentType(key).length()==0 ) {
warning("keyword " + key + " for reading arguments should is registered using Keyword::add rather than Keyword::addInputKeyword. The keyword will thus not appear in the correct place in the manual");
warning("keyword " + key + " for reading arguments is registered using Keyword::add rather than Keyword::addInputKeyword. The keyword will thus not appear in the correct place in the manual");
}
std::string def;
std::vector<std::string> c;
Expand All @@ -67,7 +67,7 @@ void ActionWithArguments::parseArgumentList(const std::string&key,std::vector<Va

bool ActionWithArguments::parseArgumentList(const std::string&key,int i,std::vector<Value*>&arg) {
if( keywords.getArgumentType(key).length()==0 ) {
warning("keyword " + key + " for reading argument should is registered using Keyword::add rather than Keyword::addInputKeyword. The keyword will thus not appear in the correct place in the manual");
warning("keyword " + key + " for reading argument is registered using Keyword::add rather than Keyword::addInputKeyword. The keyword will thus not appear in the correct place in the manual");
}
std::vector<std::string> c;
arg.clear();
Expand Down
8 changes: 4 additions & 4 deletions src/core/CLTool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ bool CLTool::readCommandLineArgs( int argc, char**argv, FILE*out ) {

// Set all flags to default false
for(unsigned k=0; k<keywords.size(); ++k) {
thiskey=keywords.get(k);
thiskey=keywords.getKeyword(k);
if( keywords.style(thiskey,"flag") ) {
inputData.insert(std::pair<std::string,std::string>(thiskey,"false"));
}
Expand All @@ -96,7 +96,7 @@ bool CLTool::readCommandLineArgs( int argc, char**argv, FILE*out ) {
} else {
bool found=false;
for(unsigned k=0; k<keywords.size(); ++k) {
thiskey=keywords.get(k);
thiskey=keywords.getKeyword(k);
if( keywords.style(thiskey,"flag") ) {
if( a==thiskey ) {
found=true;
Expand Down Expand Up @@ -147,7 +147,7 @@ bool CLTool::readCommandLineArgs( int argc, char**argv, FILE*out ) {
void CLTool::setRemainingToDefault(FILE* out) {
std::string def, thiskey;
for(unsigned k=0; k<keywords.size(); ++k) {
thiskey=keywords.get(k);
thiskey=keywords.getKeyword(k);
if( keywords.style(thiskey,"compulsory") ) {
if( inputData.count(thiskey)==0 ) {
if( keywords.getDefaultValue(thiskey,def) ) {
Expand Down Expand Up @@ -218,7 +218,7 @@ bool CLTool::readInputFile( int argc, char**argv, FILE* in, FILE*out ) {
std::string keyword=buffer;
bool found=false;
for(unsigned i=0; i<keywords.size(); ++i) {
std::string thiskey=keywords.get(i);
std::string thiskey=keywords.getKeyword(i);
if(thiskey==keyword) {
found=true;
std::size_t keypos=line.find_first_of(keyword)+keyword.length();
Expand Down
2 changes: 1 addition & 1 deletion src/generic/DumpForces.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ void DumpForces::registerKeywords(Keywords& keys) {
Action::registerKeywords(keys);
ActionPilot::registerKeywords(keys);
ActionWithArguments::registerKeywords(keys);
keys.addInputKeyword("compulsory","ARG","scalar","the labels of the values whose forces should be output");
keys.addInputKeyword("compulsory","ARG",Keywords::argType::scalar,"the labels of the values whose forces should be output");
keys.add("compulsory","STRIDE","1","the frequency with which the forces should be output");
keys.add("compulsory","FILE","the name of the file on which to output the forces");
keys.add("compulsory","FMT","%15.10f","the format with which the derivatives should be output");
Expand Down
22 changes: 22 additions & 0 deletions src/tools/BitmaskEnum.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Copyright (c) 2024 The plumed team
(see the PEOPLE file at the root of the distribution for a list of names)

See http://www.plumed.org for more information.

This file is part of plumed, version 2.

plumed is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

plumed is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with plumed. If not, see <http://www.gnu.org/licenses/>.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
#include "BitmaskEnum.h"
Loading
Loading