1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
|
/***********************************************/
/**
* @file loopFileAsciiTable.h
*
* @brief Loop over rows of a table containing strings.
*
* @author Norbert Zehentner
* @author Sebastian Strasser
* @date 2017-02-17
*
*/
/***********************************************/
#ifndef __GROOPS_LOOPFILEASCIITABLE__
#define __GROOPS_LOOPFILEASCIITABLE__
// Latex documentation
#ifdef DOCSTRING_Loop
static const char *docstringLoopFileAsciiTable = R"(
\subsection{FileAsciiTable}
Loop over rows of a table containing strings.
Each row must have the same number of columns.
)";
#endif
/***********************************************/
#include "base/import.h"
#include "files/fileStringTable.h"
#include "classes/loop/loop.h"
/***** CLASS ***********************************/
/** @brief Loop over rows of a table containing strings.
* @ingroup loopGroup
* @see Loop */
class LoopFileAsciiTable : public Loop
{
std::vector<std::vector<std::string>> stringTable;
std::vector<std::string> nameString;
std::string nameIndex, nameCount;
public:
LoopFileAsciiTable(Config &config);
UInt count() const override {return stringTable.size();}
Bool iteration(VariableList &varList) override;
};
/***********************************************/
/***** Inlines *********************************/
/***********************************************/
inline LoopFileAsciiTable::LoopFileAsciiTable(Config &config)
{
try
{
std::vector<FileName> fileNames;
UInt startRow, countRows = MAX_UINT;
readConfig(config, "inputfile", fileNames, Config::MUSTSET, "", "simple ASCII file with multiple columns (separated by whitespace)");
readConfig(config, "startLine", startRow, Config::DEFAULT, "0", "start at line startLine (counting from 0)");
readConfig(config, "countLines", countRows, Config::OPTIONAL, "", "read count lines (default: all)");
readConfig(config, "variableLoopString", nameString, Config::MUSTSET, "loopString", "1. variable name for the 1. column, next variable name for the 2. column, ... ");
readConfig(config, "variableLoopIndex", nameIndex, Config::OPTIONAL, "", "variable with index of current iteration (starts with zero)");
readConfig(config, "variableLoopCount", nameCount, Config::OPTIONAL, "", "variable with total number of iterations");
readConfigCondition(config);
if(isCreateSchema(config)) return;
for(auto &fileName : fileNames)
readFileStringTable(fileName, stringTable);
stringTable.erase(stringTable.begin(), stringTable.begin()+std::min(startRow, stringTable.size()));
stringTable.erase(stringTable.begin()+std::min(countRows, stringTable.size()), stringTable.end());
if(stringTable.size()>1)
{
const UInt columns = stringTable.at(0).size();
if(nameString.size() > columns)
throw(Exception("More variables than columns in the table"));
for(UInt i=1; i<stringTable.size(); i++)
if(stringTable.at(i).size() != columns)
throw(Exception("Varying number of columns in input file(s)"));
}
}
catch(std::exception &e)
{
GROOPS_RETHROW(e)
}
}
/***********************************************/
inline Bool LoopFileAsciiTable::iteration(VariableList &varList)
{
if(index() >= count())
return FALSE;
for(UInt i=0; i<nameString.size(); i++)
if(!nameString.at(i).empty())
varList.setVariable(nameString.at(i), stringTable.at(index()).at(i));
if(!nameIndex.empty()) varList.setVariable(nameIndex, index());
if(!nameCount.empty()) varList.setVariable(nameCount, count());
return checkCondition(varList);
}
/***********************************************/
#endif
|