Newer
Older
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidAPI/AlgorithmFactory.h"
#include "MantidAPI/HistoryItem.h"
#include "MantidAPI/ScriptBuilder.h"
#include <boost/utility.hpp>
namespace Mantid
{
namespace API
{
using Mantid::Kernel::PropertyHistory_sptr;
using Mantid::Kernel::PropertyHistory_const_sptr;
ScriptBuilder::ScriptBuilder(boost::shared_ptr<HistoryView> view, std::string versionSpecificity)
: m_historyItems(view->getAlgorithmsList()), m_output(), m_versionSpecificity(versionSpecificity)
/**
* Build a python script for each algorithm included in the history view.
*
* @return a formatted python string of the history
*/
const std::string ScriptBuilder::build()
{
std::ostringstream os;
auto iter = m_historyItems.begin();
for( ; iter != m_historyItems.end(); ++iter)
{
writeHistoryToStream(os, iter);
}
return os.str();
}
/**
* Write out an algorithm to the script.
*
* If the entry is unrolled this will recurse and output the children of
* that entry instead. If not, it will just output the algorithm to the stream.
*
* @param os :: output string stream to append algorithms to.
* @param iter :: reference to the iterator pointing to the vector of history items
* @param depth :: count of how far we've recursed into the history
void ScriptBuilder::writeHistoryToStream(std::ostringstream& os, std::vector<HistoryItem>::const_iterator& iter, int depth)
{
auto algHistory = iter->getAlgorithmHistory();
if(iter->isUnrolled())
{
os << std::string(depth, '#');
os << " Child algorithms of " << algHistory->name() << "\n";
//don't create a line for the algorithm, just output its children
buildChildren(os, iter, depth+1);
os << std::string(depth, '#');
os << " End of child algorithms of " << algHistory->name() << "\n";
if(boost::next(iter) == m_historyItems.end()
|| !boost::next(iter)->isUnrolled())
{
os << "\n";
}
}
else
{
//create the string for this algorithm
os << buildAlgorithmString(algHistory) << "\n";
}
}
/**
* Iterate over each of the items children and output them to the script.
*
* This moves the iterator forward over each of the child records and writes them to
* the stream.
*
* @param os :: output string stream to append algorithms to.
* @param iter :: reference to the iterator pointing to the vector of history items
* @param depth :: count of how far we've recursed into the history
void ScriptBuilder::buildChildren(std::ostringstream& os, std::vector<HistoryItem>::const_iterator& iter, int depth)
{
size_t numChildren = iter->numberOfChildren();
++iter; //move to first child
for(size_t i = 0; i < numChildren && iter != m_historyItems.end(); ++i, ++iter)
writeHistoryToStream(os, iter, depth);
/**
* Build the script output for a single algorithm
*
* @param algHistory :: pointer to an algorithm history object
* @returns std::string to run this algorithm
*/
const std::string ScriptBuilder::buildAlgorithmString(AlgorithmHistory_const_sptr algHistory)
{
std::ostringstream properties;
const std::string name = algHistory->name();
std::string prop = "";
auto props = algHistory->getProperties();
for (auto propIter = props.begin(); propIter != props.end(); ++propIter)
{
prop = buildPropertyString(*propIter);
if(prop.length() > 0)
{
properties << prop << ", ";
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
//Three cases, we can either specify the version of every algorithm...
if(m_versionSpecificity == "all")
{
properties << "Version=" << algHistory->version() << ", ";
}
else if(m_versionSpecificity == "old")
{
//...or only specify algorithm versions when they're not the newest version
bool oldVersion = false;
std::vector<Algorithm_descriptor> descriptors = AlgorithmFactory::Instance().getDescriptors();
for(auto dit = descriptors.begin(); dit != descriptors.end(); ++dit)
{
//If a newer version of this algorithm exists, then this must be an old version.
if((*dit).name == algHistory->name() && (*dit).version > algHistory->version())
{
oldVersion = true;
break;
}
}
if(oldVersion)
{
properties << "Version=" << algHistory->version() << ", ";
}
}
//Third case is we never specify the version, so do nothing.
std::string propStr = properties.str();
if (propStr.length() > 0)
{
//remove trailing comma & space
propStr.erase(propStr.size()-1);
propStr.erase(propStr.size()-1);
}
return name + "(" + propStr + ")";
/**
* Build the script output for a single property
*
* @param propHistory :: reference to a property history object
* @returns std::string for this property
*/
const std::string ScriptBuilder::buildPropertyString(PropertyHistory_const_sptr propHistory)
if (!propHistory->isDefault())
if(propHistory->type() == "number")
{
prop = propHistory->name() + "=" + propHistory->value();
}
else if(propHistory->type() == "boolean")
{
std::string value = (propHistory->value() == "1" ? "True" : "False");
prop = propHistory->name() + "=" + value;
std::string opener = "='";
if (propHistory->value().find('\\') != std::string::npos )
{
opener= "=r'";
}
prop = propHistory->name() + opener + propHistory->value() + "'";
}
return prop;
}
} // namespace API
} // namespace Mantid