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"));
}
Sofia Antony
committed
struct hasProperty
{
hasProperty(const std::string name):m_name(name){}
bool operator()(Mantid::Kernel::Property* prop)
{
std::string name=prop->name();
return (!name.compare(m_name));
}
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);
Sofia Antony
committed
g_log.debug()<<"The sub algorithm name is "<<alg->name()<<std::endl;
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())
{
alg->setPropertyValue((*prop)->name(),getPropertyValue((*prop)->name()));
Sofia Antony
committed
Sofia Antony
committed
//execute the load sub algorithm
alg->execute();
//se the workspace
setOutputWorkspace(alg);
Sofia Antony
committed
114
115
116
117
118
119
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
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
/** get a shared pointer to the load algorithm with highest preference for loading
*@param filePath path of the file
*@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.
* @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.
*/
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
Sofia Antony
committed
*@param 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