Newer
Older
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidDataHandling/Load.h"
Gigg, Martyn Anthony
committed
#include "MantidAPI/FileProperty.h"
#include "MantidKernel/ArrayProperty.h"
#include "MantidDataObjects/Workspace2D.h"
Sofia Antony
committed
#include "MantidAPI/IDataFileChecker.h"
#include "MantidAPI/LoadAlgorithmFactory.h"
#include<algorithm>
namespace Mantid
{
namespace DataHandling
{
// Register the algorithm into the algorithm factory
DECLARE_ALGORITHM(Load)
using namespace Kernel;
using namespace API;
/// Initialisation method.
void Load::init()
{
Sofia Antony
committed
std::vector<std::string> exts;
exts.push_back(".raw");
exts.push_back(".s*");
exts.push_back(".add");
exts.push_back(".nxs");
exts.push_back(".nx5");
exts.push_back(".xml");
exts.push_back(".n*");
exts.push_back(".dat");
exts.push_back(".txt");
exts.push_back(".csv");
exts.push_back(".spe");
Sofia Antony
committed
declareProperty(new FileProperty("Filename", "", FileProperty::Load, exts),
"The name of the file to read, including its full or relative\n"
"path. (N.B. case sensitive if running on Linux).");
Gigg, Martyn Anthony
committed
declareProperty(new WorkspaceProperty<Workspace>("OutputWorkspace", "",Direction::Output, true),
"The name of the workspace that will be created, filled with the\n"
"read-in data and stored in the Analysis Data Service.");
Gigg, Martyn Anthony
committed
declareProperty("FindLoader", false, "If true the algorithm will only be run as\n"
"far as is necessary to discover the concrete Load algorithm to use");
declareProperty("LoaderName", std::string(""), "A string containing the name of the concrete loader used",
Direction::Output);
Gigg, Martyn Anthony
committed
namespace
{
/**
* Checks this property exists in the list of algorithm properties.
*/
struct hasProperty
{
/** constructor which takes 1 arguement.
*@param name :: name of the property
*/
hasProperty(const std::string name):m_name(name){}
/**This method comapres teh property name
*@param prop :: shared pointer to property
*@return true if the property exists in the list of properties.
*/
bool operator()(Mantid::Kernel::Property* prop)
{
std::string name=prop->name();
return (!name.compare(m_name));
}
/// name of teh property
std::string m_name;
};
}
Sofia Antony
committed
/**
* Executes the algorithm.
*/
void Load::exec()
{
std::string fileName = getPropertyValue("Filename");
std::string::size_type i = fileName.find_last_of('.');
std::string ext = fileName.substr(i+1);
std::transform(ext.begin(),ext.end(),ext.begin(),tolower);
Sofia Antony
committed
//get the shared pointer to the specialised load algorithm to execute
Gigg, Martyn Anthony
committed
API::IAlgorithm_sptr alg= getFileLoader(fileName);
Sofia Antony
committed
if(!alg)
Sofia Antony
committed
throw std::runtime_error("Cannot load file " + fileName);
Gigg, Martyn Anthony
committed
bool findOnly = getProperty("FindLoader");
if( findOnly ) return;
g_log.information()<<"The sub load algorithm created to execute is "<<alg->name()<<" and it version is "<<alg->version()<<std::endl;
Sofia Antony
committed
double startProgress=0,endProgress=1;
// set the load algorithm as a child algorithm
initialiseLoadSubAlgorithm(alg,startProgress,endProgress,true,-1);
//get the list of properties for this algorithm
std::vector<Kernel::Property*> props=getProperties();
///get the list properties for the sub load algorithm
std::vector<Kernel::Property*>loader_props=alg->getProperties();
//loop through the properties of this algorithm
std::vector<Kernel::Property*>::iterator itr;
for (itr=props.begin();itr!=props.end();++itr)
{
std::vector<Mantid::Kernel::Property*>::iterator prop;
//if the load sub algorithm has the same property then set it.
prop=std::find_if(loader_props.begin(),loader_props.end(),hasProperty((*itr)->name()));
if(prop!=loader_props.end())
Sofia Antony
committed
alg->setPropertyValue((*prop)->name(),getPropertyValue((*prop)->name()));
Sofia Antony
committed
Sofia Antony
committed
//execute the load sub algorithm
Sofia Antony
committed
//se the workspace
setOutputWorkspace(alg);
Sofia Antony
committed
/** get a shared pointer to the load algorithm with highest preference for loading
Janik Zikovsky
committed
*@param filePath :: path of the file
Sofia Antony
committed
*@return filePath - path of the file
*/
Gigg, Martyn Anthony
committed
API::IAlgorithm_sptr Load::getFileLoader(const std::string& filePath)
Sofia Antony
committed
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
{
unsigned char* header_buffer = header_buffer_union.c;
int nread;
/* Open the file and read in the first bufferSize bytes - these will
* be used to determine the type of the file
*/
FILE* fp = fopen(filePath.c_str(), "rb");
if (fp == NULL)
{
throw Kernel::Exception::FileError("Unable to open the file:", filePath);
}
nread = fread((char*)header_buffer,sizeof(char), bufferSize,fp);
header_buffer[bufferSize] = '\0';
if (nread == -1)
{
fclose(fp);
}
if (fclose(fp) != 0)
{
}
int val=0;
API::IAlgorithm_sptr load;
// now get the name of algorithms registered in the loadAlgorithmfactory
std::vector<std::string> algnames=API::LoadAlgorithmFactory::Instance().getKeys();
std::map<std::string, boost::shared_ptr<DataHandling::IDataFileChecker> >loadalgs;
/// create load algorithms and store it in a map
std::vector<std::string>::const_iterator citr;
for (citr=algnames.begin();citr!=algnames.end();++citr)
{
loadalgs[*citr]= API::LoadAlgorithmFactory::Instance().create(*citr);
}
std::map<std::string, boost::shared_ptr<DataHandling::IDataFileChecker> >::const_iterator alg_itr;
//loop thorugh the map and do a quick check for each load algorithm by opening the file and look at it's first 100 bytes and extensions
//if quick check succeeds then do a filecheck again by opening the file and read the structure of the file
for (alg_itr=loadalgs.begin();alg_itr!=loadalgs.end();++alg_itr)
{
bool bcheck=alg_itr->second->quickFileCheck(filePath,nread,header_buffer);
if(!bcheck)
{
continue;
}
int ret=alg_itr->second->fileCheck(filePath);
if(ret>val)
{
// algorithm with highest preference will cached.
val=ret;
load=alg_itr->second;
}
}
Gigg, Martyn Anthony
committed
if( load )
{
setPropertyValue("LoaderName", load->name());
}
Sofia Antony
committed
return load;
}
/** This method set the algorithm as a child algorithm.
Janik Zikovsky
committed
* @param alg :: The shared pointer to a algorithm
* @param startProgress :: The percentage progress value of the overall algorithm where this child algorithm starts
* @param endProgress :: The percentage progress value of the overall algorithm where this child algorithm ends
* @param enableLogging :: Set to false to disable logging from the child algorithm
* @param version :: The version of the child algorithm to create. By default gives the latest version.
Sofia Antony
committed
*/
void Load::initialiseLoadSubAlgorithm(API::IAlgorithm_sptr alg, const double startProgress, const double endProgress,
const bool enableLogging, const int& version)
(void) version; // Avoid compiler warning.
Sofia Antony
committed
//set as a child
alg->initialize();
alg->setChild(true);
alg->setLogging(enableLogging);
// If output workspaces are nameless, give them a temporary name to satisfy validator
const std::vector< Property*> &props = alg->getProperties();
for (unsigned int i = 0; i < props.size(); ++i)
{
if (props[i]->direction() == 1 && dynamic_cast<IWorkspaceProperty*>(props[i]) )
{
if ( props[i]->value().empty() ) props[i]->setValue("ChildAlgOutput");
}
}
Sofia Antony
committed
if (startProgress >= 0 && endProgress > startProgress && endProgress <= 1.)
{
alg->addObserver(m_progressObserver);
alg->setChildStartProgress(startProgress);
alg->setChildEndProgress(endProgress);
}
Sofia Antony
committed
/**
* Set the output workspace(s) if the load's return workspace
* has type API::Workspace
Janik Zikovsky
committed
*@param load :: shared pointer to load algorithm
*/
void Load::setOutputWorkspace(API::IAlgorithm_sptr& load)
{
Sofia Antony
committed
try
Sofia Antony
committed
Workspace_sptr ws = load->getProperty("OutputWorkspace");
WorkspaceGroup_sptr wsg = boost::dynamic_pointer_cast<WorkspaceGroup>(ws);
if (wsg)
Sofia Antony
committed
setProperty("OutputWorkspace",ws);
std::vector<std::string> names = wsg->getNames();
for(size_t i = 0; i < names.size(); ++i)
{
std::ostringstream propName;
propName << "OutputWorkspace_" << (i+1);
DataObjects::Workspace2D_sptr memberwsws1 = load->getProperty(propName.str());
std::string memberwsName = load->getPropertyValue(propName.str());
declareProperty(new WorkspaceProperty<>(propName.str(),memberwsName,Direction::Output));
setProperty(propName.str(),boost::dynamic_pointer_cast<MatrixWorkspace>(memberwsws1));
}
}
else
{
setProperty("OutputWorkspace",ws);
Sofia Antony
committed
catch(std::runtime_error&)
{
MatrixWorkspace_sptr mws=load->getProperty("OutputWorkspace");
setProperty("OutputWorkspace",boost::dynamic_pointer_cast<Workspace>(mws));
}
Sofia Antony
committed
} // namespace DataHandling
} // namespace Mantid