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).");
declareProperty(new WorkspaceProperty<Workspace>("OutputWorkspace",
"",Direction::Output), "The name of the workspace that will be created, filled with the\n"
"read-in data and stored in the Analysis Data Service.");
BoundedValidator<int> *mustBePositive = new BoundedValidator<int>();
mustBePositive->setLower(1);
declareProperty("SpectrumMin", 1, mustBePositive);
declareProperty("SpectrumMax", EMPTY_INT(), mustBePositive->clone());
declareProperty(new ArrayProperty<int>("SpectrumList"));
Steve Williams
committed
declareProperty("EntryNumber", 0,
"Load a particular entry, if supported by the file format (default: Load all entries)");
/** checks this property exists in the list of algorithm properties.
*/
Sofia Antony
committed
struct hasProperty
{
/** constructor which takes 1 arguement.
Janik Zikovsky
committed
*@param name :: name of the property
Sofia Antony
committed
hasProperty(const std::string name):m_name(name){}
/**This method comapres teh property name
Janik Zikovsky
committed
*@param prop :: shared pointer to property
*@return true if the property exists in the list of properties.
*/
Sofia Antony
committed
bool operator()(Mantid::Kernel::Property* prop)
{
std::string name=prop->name();
return (!name.compare(m_name));
}
/// name of teh property
Sofia Antony
committed
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
API::IAlgorithm_sptr alg= getLoadAlgorithmfromFile(fileName);
if(!alg)
Sofia Antony
committed
throw std::runtime_error("Cannot load file " + fileName);
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
130
131
132
133
134
135
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
188
*@return filePath - path of the file
*/
API::IAlgorithm_sptr Load::getLoadAlgorithmfromFile(const std::string& filePath)
{
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;
}
}
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)
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