Newer
Older
Ronald Fowler
committed
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidDataHandling/LoadMuonNexus.h"
Ronald Fowler
committed
#include "MantidDataObjects/Workspace2D.h"
#include "MantidKernel/UnitFactory.h"
#include "MantidKernel/ConfigService.h"
#include "MantidKernel/ArrayProperty.h"
Gigg, Martyn Anthony
committed
#include "MantidAPI/FileProperty.h"
Roman Tolchenov
committed
#include "MantidAPI/Progress.h"
#include "MantidAPI/SpectraDetectorMap.h"
#include "MantidKernel/TimeSeriesProperty.h"
Ronald Fowler
committed
Ronald Fowler
committed
#include <cmath>
#include <boost/shared_ptr.hpp>
#include "MantidNexus/MuonNexusReader.h"
#include "MantidNexus/NexusClasses.h"
#include "MantidNexus/NeXusFile.hpp"
#include "MantidNexus/NeXusException.hpp"
Ronald Fowler
committed
namespace Mantid
{
namespace DataHandling
Ronald Fowler
committed
{
// Register the algorithm into the algorithm factory
DECLARE_ALGORITHM(LoadMuonNexus)
Janik Zikovsky
committed
/// Sets documentation strings for this algorithm
void LoadMuonNexus::initDocs()
{
this->setWikiSummary("The LoadMuonNexus algorithm will read the given NeXus Muon data file Version 1 and use the results to populate the named workspace. LoadMuonNexus may be invoked by [[LoadNexus]] if it is given a NeXus file of this type. ");
this->setOptionalMessage("The LoadMuonNexus algorithm will read the given NeXus Muon data file Version 1 and use the results to populate the named workspace. LoadMuonNexus may be invoked by LoadNexus if it is given a NeXus file of this type.");
Janik Zikovsky
committed
}
Ronald Fowler
committed
using namespace Kernel;
using namespace API;
Gigg, Martyn Anthony
committed
using Geometry::IInstrument;
using namespace Mantid::NeXus;
Ronald Fowler
committed
/// Empty default constructor
LoadMuonNexus::LoadMuonNexus() :
Sofia Antony
committed
m_filename(), m_entrynumber(0), m_numberOfSpectra(0), m_numberOfPeriods(0), m_list(false),
m_interval(false), m_spec_list(), m_spec_min(0), m_spec_max(EMPTY_INT())
Ronald Fowler
committed
{}
/// Initialisation method.
void LoadMuonNexus::init()
{
Peterson, Peter
committed
declareProperty(new FileProperty("Filename", "", FileProperty::Load, ".nxs"),
Roman Tolchenov
committed
"The name of the Nexus file to load" );
Russell Taylor
committed
Roman Tolchenov
committed
declareProperty(new WorkspaceProperty<Workspace>("OutputWorkspace","",Direction::Output),
Steve Williams
committed
"The name of the workspace to be created as the output of the\n"
"algorithm. For multiperiod files, one workspace will be\n"
"generated for each period");
Sofia Antony
committed
Roman Tolchenov
committed
Gigg, Martyn Anthony
committed
BoundedValidator<int64_t> *mustBePositive = new BoundedValidator<int64_t>();
Ronald Fowler
committed
mustBePositive->setLower(0);
Gigg, Martyn Anthony
committed
declareProperty( "SpectrumMin",(int64_t)0, mustBePositive,
Steve Williams
committed
"Index number of the first spectrum to read, only used if\n"
"spectrum_max is set and only for single period data\n"
"(default 0)" );
Gigg, Martyn Anthony
committed
declareProperty( "SpectrumMax",(int64_t)EMPTY_INT(), mustBePositive->clone(),
Steve Williams
committed
"Index of last spectrum to read, only for single period data\n"
"(default the last spectrum)");
Roman Tolchenov
committed
Gigg, Martyn Anthony
committed
declareProperty(new ArrayProperty<specid_t>("SpectrumList"),
Steve Williams
committed
"Array, or comma separated list, of indexes of spectra to\n"
"load");
Steve Williams
committed
"Determines whether the spectra are automatically grouped\n"
"together based on the groupings in the NeXus file, only\n"
"for single period data (default no)");
Sofia Antony
committed
Gigg, Martyn Anthony
committed
declareProperty("EntryNumber", (int64_t)0, mustBePositive->clone(),
Roman Tolchenov
committed
"The particular entry number to read (default: Load all workspaces and creates a workspace group)");
Anders Markvardsen
committed
std::vector<std::string> FieldOptions;
FieldOptions.push_back("Transverse");
FieldOptions.push_back("Longitudinal");
declareProperty("MainFieldDirection","Transverse",new ListValidator(FieldOptions),
"Output the main field direction if specified in Nexus file (default Transverse)", Direction::Output);
declareProperty("TimeZero", 0.0, "Time zero in units of micro-seconds (default to 0.0)", Direction::Output);
declareProperty("FirstGoodData", 0.0, "First good data in units of micro-seconds (default to 0.0)", Direction::Output);
Ronald Fowler
committed
}
/** Executes the algorithm. Reading in the file and creating and populating
Roman Tolchenov
committed
* the output workspace
*
* @throw Exception::FileError If the Nexus file cannot be found/opened
* @throw std::invalid_argument If the optional properties are set to invalid values
*/
Ronald Fowler
committed
void LoadMuonNexus::exec()
{
Roman Tolchenov
committed
// Retrieve the filename from the properties
m_filename = getPropertyValue("Filename");
// Retrieve the entry number
m_entrynumber = getProperty("EntryNumber");
Ronald Fowler
committed
Roman Tolchenov
committed
106
107
108
109
110
111
112
113
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
MuonNexusReader nxload;
if (nxload.readFromFile(m_filename) != 0)
{
g_log.error("Unable to open file " + m_filename);
throw Exception::FileError("Unable to open File:" , m_filename);
}
// Read in the instrument name from the Nexus file
m_instrument_name = nxload.getInstrumentName();
// Read in the number of spectra in the Nexus file
m_numberOfSpectra = nxload.t_nsp1;
if(m_entrynumber!=0)
{
m_numberOfPeriods=1;
if(m_entrynumber>nxload.t_nper)
{
throw std::invalid_argument("Invalid Entry Number:Enter a valid number");
}
}
else
{
// Read the number of periods in this file
m_numberOfPeriods = nxload.t_nper;
}
// Need to extract the user-defined output workspace name
Property *ws = getProperty("OutputWorkspace");
std::string localWSName = ws->value();
// If multiperiod, will need to hold the Instrument, Sample & SpectraDetectorMap for copying
boost::shared_ptr<IInstrument> instrument;
boost::shared_ptr<Sample> sample;
// Call private method to validate the optional parameters, if set
checkOptionalProperties();
// Read the number of time channels (i.e. bins) from the Nexus file
const int channelsPerSpectrum = nxload.t_ntc1;
// Read in the time bin boundaries
const int lengthIn = channelsPerSpectrum + 1;
float* timeChannels = new float[lengthIn];
nxload.getTimeChannels(timeChannels, lengthIn);
// Put the read in array into a vector (inside a shared pointer)
boost::shared_ptr<MantidVec> timeChannelsVec
(new MantidVec(timeChannels, timeChannels + lengthIn));
// Calculate the size of a workspace, given its number of periods & spectra to read
Roman Tolchenov
committed
if( m_interval || m_list)
{
total_specs = m_spec_list.size();
if (m_interval)
Roman Tolchenov
committed
total_specs += (m_spec_max-m_spec_min+1);
m_spec_max += 1;
Roman Tolchenov
committed
}
else
{
total_specs = m_numberOfSpectra;
// for nexus return all spectra
m_spec_min = 0; // changed to 0 for NeXus, was 1 for Raw
m_spec_max = m_numberOfSpectra; // was +1?
}
Ronald Fowler
committed
Roman Tolchenov
committed
// Create the 2D workspace for the output
DataObjects::Workspace2D_sptr localWorkspace = boost::dynamic_pointer_cast<DataObjects::Workspace2D>
(WorkspaceFactory::Instance().create("Workspace2D",total_specs,lengthIn,lengthIn-1));
// Set the unit on the workspace to muon time, for now in the form of a Label Unit
boost::shared_ptr<Kernel::Units::Label> lblUnit =
boost::dynamic_pointer_cast<Kernel::Units::Label>(UnitFactory::Instance().create("Label"));
lblUnit->setLabel("Time","microsecond");
localWorkspace->getAxis(0)->unit() = lblUnit;
// Set y axis unit
Russell Taylor
committed
localWorkspace->setYUnit("Counts");
Roman Tolchenov
committed
WorkspaceGroup_sptr wsGrpSptr=WorkspaceGroup_sptr(new WorkspaceGroup);
if(m_numberOfPeriods>1)
Russell Taylor
committed
{
Roman Tolchenov
committed
setProperty("OutputWorkspace",boost::dynamic_pointer_cast<Workspace>(wsGrpSptr));
}
API::Progress progress(this,0.,1.,m_numberOfPeriods * total_specs);
// Loop over the number of periods in the Nexus file, putting each period in a separate workspace
for (int64_t period = 0; period < m_numberOfPeriods; ++period) {
Roman Tolchenov
committed
if(m_entrynumber!=0)
Ronald Fowler
committed
{
Roman Tolchenov
committed
period=m_entrynumber-1;
if(period!=0)
{
Roman Tolchenov
committed
runLoadInstrument(localWorkspace );
runLoadMappingTable(localWorkspace );
}
Roman Tolchenov
committed
if (period == 0)
Roman Tolchenov
committed
// Only run the sub-algorithms once
Roman Tolchenov
committed
runLoadInstrument(localWorkspace );
runLoadMappingTable(localWorkspace );
runLoadLog(localWorkspace );
localWorkspace->populateInstrumentParameters();
Ronald Fowler
committed
}
Roman Tolchenov
committed
else // We are working on a higher period of a multiperiod raw file
{
localWorkspace = boost::dynamic_pointer_cast<DataObjects::Workspace2D>
(WorkspaceFactory::Instance().create(localWorkspace));
//localWorkspace->newInstrumentParameters(); ???
Ronald Fowler
committed
Roman Tolchenov
committed
}
std::string outws("");
if(m_numberOfPeriods>1)
{
std::string outputWorkspace = "OutputWorkspace";
std::stringstream suffix;
suffix << (period+1);
outws =outputWorkspace+"_"+suffix.str();
std::string WSName = localWSName + "_" + suffix.str();
Steve Williams
committed
declareProperty(new WorkspaceProperty<Workspace>(outws,WSName,Direction::Output));
Roman Tolchenov
committed
if(wsGrpSptr)wsGrpSptr->add(WSName);
}
Roman Tolchenov
committed
{
// Shift the histogram to read if we're not in the first period
specid_t histToRead = static_cast<specid_t>(i + period*total_specs);
Roman Tolchenov
committed
loadData(timeChannelsVec,counter,histToRead,nxload,lengthIn-1,localWorkspace ); // added -1 for NeXus
counter++;
progress.report();
}
// Read in the spectra in the optional list parameter, if set
if (m_list)
{
Roman Tolchenov
committed
{
loadData(timeChannelsVec,counter,m_spec_list[i],nxload,lengthIn-1, localWorkspace );
counter++;
progress.report();
}
}
// Just a sanity check
assert(counter == size_t(total_specs) );
Roman Tolchenov
committed
bool autogroup = getProperty("AutoGroup");
if (autogroup)
{
//Get the groupings
Roman Tolchenov
committed
// use a map for mapping group number and output workspace index in case
// there are group numbers > number of groups
Roman Tolchenov
committed
m_groupings.resize(nxload.numDetectors);
bool thereAreZeroes = false;
for (int64_t i =0; i < static_cast<int64_t>(nxload.numDetectors); ++i)
Roman Tolchenov
committed
{
int64_t ig = static_cast<int64_t>(nxload.detectorGroupings[i]);
Roman Tolchenov
committed
if (ig == 0)
Roman Tolchenov
committed
thereAreZeroes = true;
continue;
Roman Tolchenov
committed
if (groups.find(ig) == groups.end())
Roman Tolchenov
committed
if (ig > max_group) max_group = ig;
}
if (thereAreZeroes)
for (int64_t i =0; i < static_cast<int64_t>(nxload.numDetectors); ++i)
int64_t ig = static_cast<int64_t>(nxload.detectorGroupings[i]);
Roman Tolchenov
committed
if (ig == 0)
{
ig = ++max_group;
Roman Tolchenov
committed
groups[ig] = groups.size();
}
int numHists = static_cast<int>(localWorkspace->getNumberHistograms());
size_t ngroups = groups.size(); // number of groups
Roman Tolchenov
committed
// to output groups in ascending order
{
int64_t i=0;
for(std::map<int64_t,int64_t>::iterator it=groups.begin();it!=groups.end();it++,i++)
Roman Tolchenov
committed
it->second = i;
g_log.information()<<"group "<<it->first<<": ";
bool first = true;
int64_t first_i = -1 * std::numeric_limits<int64_t>::max();
int64_t last_i = -1 * std::numeric_limits<int64_t>::max();
for(int64_t i=0;i<static_cast<int64_t>(numHists);i++)
Roman Tolchenov
committed
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
if (m_groupings[i] == it->first)
{
if (first)
{
first = false;
g_log.information()<<i;
first_i = i;
}
else
{
if (first_i >= 0)
{
if (i > last_i + 1)
{
g_log.information()<<'-'<<i;
first_i = -1;
}
}
else
{
g_log.information()<<','<<i;
first_i = i;
}
}
last_i = i;
}
else
Roman Tolchenov
committed
if (!first && first_i >= 0)
{
if (last_i > first_i)
g_log.information()<<'-'<<last_i;
first_i = -1;
}
Roman Tolchenov
committed
if (first_i >= 0 && last_i > first_i)
g_log.information()<<'-'<<last_i;
g_log.information()<<'\n';
}
}
Roman Tolchenov
committed
//Create a workspace with only two spectra for forward and back
DataObjects::Workspace2D_sptr groupedWS = boost::dynamic_pointer_cast<DataObjects::Workspace2D>
(API::WorkspaceFactory::Instance().create(localWorkspace, ngroups, localWorkspace->dataX(0).size(), localWorkspace->blocksize()));
boost::shared_array<specid_t> spec(new specid_t[numHists]);
boost::shared_array<detid_t> dets(new detid_t[numHists]);
Roman Tolchenov
committed
//Compile the groups
Roman Tolchenov
committed
{
specid_t k = static_cast<specid_t>(groups[ m_groupings[numHists*period + i] ]);
for (detid_t j = 0; j < static_cast<detid_t>(localWorkspace->blocksize()); ++j)
Roman Tolchenov
committed
{
groupedWS->dataY(k)[j] = groupedWS->dataY(k)[j] + localWorkspace->dataY(i)[j];
Roman Tolchenov
committed
//Add the errors in quadrature
groupedWS->dataE(k)[j]
= sqrt(pow(groupedWS->dataE(k)[j], 2) + pow(localWorkspace->dataE(i)[j], 2));
}
Roman Tolchenov
committed
//Copy all the X data
groupedWS->dataX(k) = localWorkspace->dataX(i);
spec[i] = k + 1;
dets[i] = i + 1;
}
Roman Tolchenov
committed
m_groupings.clear();
Roman Tolchenov
committed
// All two spectra
for(detid_t k=0; k<static_cast<detid_t>(ngroups); k++)
Roman Tolchenov
committed
{
groupedWS->getAxis(1)->spectraNo(k)= k + 1;
}
Gigg, Martyn Anthony
committed
groupedWS->replaceSpectraMap(new API::SpectraDetectorMap(spec.get(),dets.get(),numHists));
Roman Tolchenov
committed
// Assign the result to the output workspace property
if(m_numberOfPeriods>1)
Steve Williams
committed
setProperty(outws, boost::dynamic_pointer_cast<Workspace>(groupedWS));
Roman Tolchenov
committed
else
{
setProperty("OutputWorkspace",boost::dynamic_pointer_cast<Workspace>(groupedWS));
Sofia Antony
committed
Roman Tolchenov
committed
}
Roman Tolchenov
committed
}
else
{
// Assign the result to the output workspace property
if(m_numberOfPeriods>1)
Steve Williams
committed
setProperty(outws,boost::dynamic_pointer_cast<Workspace>(localWorkspace));
Roman Tolchenov
committed
else
{
setProperty("OutputWorkspace",boost::dynamic_pointer_cast<Workspace>(localWorkspace));
}
Sofia Antony
committed
Roman Tolchenov
committed
}
Roman Tolchenov
committed
} // loop over periods
Roman Tolchenov
committed
// Clean up
delete[] timeChannels;
Ronald Fowler
committed
}
Ronald Fowler
committed
/// Validates the optional 'spectra to read' properties, if they have been set
void LoadMuonNexus::checkOptionalProperties()
{
Steve Williams
committed
//read in the settings passed to the algorithm
m_spec_list = getProperty("SpectrumList");
m_spec_max = getProperty("SpectrumMax");
Steve Williams
committed
//Are we using a list of spectra or all the spectra in a range?
m_list = !m_spec_list.empty();
m_interval = (m_spec_max != EMPTY_INT());
if ( m_spec_max == EMPTY_INT() ) m_spec_max = 0;
Ronald Fowler
committed
// Check validity of spectra list property, if set
if ( m_list )
{
const specid_t minlist = *min_element(m_spec_list.begin(),m_spec_list.end());
const specid_t maxlist = *max_element(m_spec_list.begin(),m_spec_list.end());
Ronald Fowler
committed
if ( maxlist > m_numberOfSpectra || minlist == 0)
{
g_log.error("Invalid list of spectra");
throw std::invalid_argument("Inconsistent properties defined");
}
}
Roman Tolchenov
committed
Ronald Fowler
committed
// Check validity of spectra range, if set
if ( m_interval )
{
m_spec_min = getProperty("SpectrumMin");
Ronald Fowler
committed
if ( m_spec_max < m_spec_min || m_spec_max > m_numberOfSpectra )
{
g_log.error("Invalid Spectrum min/max properties");
throw std::invalid_argument("Inconsistent properties defined");
}
}
Ronald Fowler
committed
}
Roman Tolchenov
committed
Ronald Fowler
committed
/** Load in a single spectrum taken from a NeXus file
Janik Zikovsky
committed
* @param tcbs :: The vector containing the time bin boundaries
* @param hist :: The workspace index
* @param i :: The spectrum number
* @param nxload :: A reference to the MuonNeXusReader object
* @param lengthIn :: The number of elements in a spectrum
* @param localWorkspace :: A pointer to the workspace in which the data will be stored
Roman Tolchenov
committed
*/
void LoadMuonNexus::loadData(const MantidVecPtr::ptr_type& tcbs,size_t hist, specid_t& i,
MuonNexusReader& nxload, const int64_t lengthIn, DataObjects::Workspace2D_sptr localWorkspace)
Ronald Fowler
committed
{
// Read in a spectrum
// Put it into a vector, discarding the 1st entry, which is rubbish
// But note that the last (overflow) bin is kept
// For Nexus, not sure if above is the case, hence give all data for now
MantidVec& Y = localWorkspace->dataY(hist);
Russell Taylor
committed
Y.assign(nxload.counts + i * lengthIn, nxload.counts + i * lengthIn + lengthIn);
Ronald Fowler
committed
// Create and fill another vector for the errors, containing sqrt(count)
MantidVec& E = localWorkspace->dataE(hist);
typedef double (*uf)(double);
uf dblSqrt = std::sqrt;
std::transform(Y.begin(), Y.end(), E.begin(), dblSqrt);
Ronald Fowler
committed
// Populate the workspace. Loop starts from 1, hence i-1
localWorkspace->setX(hist, tcbs);
localWorkspace->getAxis(1)->spectraNo(hist)= static_cast<int>(hist) + 1;
Ronald Fowler
committed
}
Janik Zikovsky
committed
* @param localWorkspace :: The workspace details to use
*/
void LoadMuonNexus::loadRunDetails(DataObjects::Workspace2D_sptr localWorkspace)
{
API::Run & runDetails = localWorkspace->mutableRun();
Anders Markvardsen
committed
runDetails.addProperty("run_title", localWorkspace->getTitle(), true);
int numSpectra = static_cast<int>(localWorkspace->getNumberHistograms());
runDetails.addProperty("nspectra", numSpectra);
NXRoot root(m_filename);
std::string start_time = root.getString("run/start_time");
runDetails.addProperty("run_start", start_time);
std::string stop_time = root.getString("run/stop_time");
runDetails.addProperty("run_end", stop_time);
std::string dur = root.getString("run/duration");
runDetails.addProperty("dur", dur);
runDetails.addProperty("durunits", 1);
Ronald Fowler
committed
/// Run the sub-algorithm LoadInstrument (or LoadInstrumentFromNexus)
void LoadMuonNexus::runLoadInstrument(DataObjects::Workspace2D_sptr localWorkspace)
{
Roman Tolchenov
committed
IAlgorithm_sptr loadInst = createSubAlgorithm("LoadInstrument");
Roman Tolchenov
committed
Ronald Fowler
committed
// Now execute the sub-algorithm. Catch and log any error, but don't stop.
Ronald Fowler
committed
try
{
loadInst->setPropertyValue("InstrumentName", m_instrument_name);
Roman Tolchenov
committed
loadInst->setProperty<MatrixWorkspace_sptr> ("Workspace", localWorkspace);
Gigg, Martyn Anthony
committed
loadInst->setProperty("RewriteSpectraMap", false);
Roman Tolchenov
committed
loadInst->execute();
}
catch( std::invalid_argument&)
{
Roman Tolchenov
committed
g_log.information("Invalid argument to LoadInstrument sub-algorithm");
executionSuccessful = false;
Ronald Fowler
committed
}
Ronald Fowler
committed
{
Roman Tolchenov
committed
g_log.information("Unable to successfully run LoadInstrument sub-algorithm");
executionSuccessful = false;
Ronald Fowler
committed
}
// If loading instrument definition file fails, run LoadInstrumentFromNexus instead
// This does not work at present as the example files do not hold the necessary data
// but is a place holder. Hopefully the new version of Nexus Muon files should be more
// complete.
Ronald Fowler
committed
if ( ! loadInst->isExecuted() )
{
runLoadInstrumentFromNexus(localWorkspace);
}
}
Roman Tolchenov
committed
Ronald Fowler
committed
/// Run LoadInstrumentFromNexus as a sub-algorithm (only if loading from instrument definition file fails)
void LoadMuonNexus::runLoadInstrumentFromNexus(DataObjects::Workspace2D_sptr localWorkspace)
{
g_log.information() << "Instrument definition file not found. Attempt to load information about \n"
<< "the instrument from nexus data file.\n";
Ronald Fowler
committed
IAlgorithm_sptr loadInst = createSubAlgorithm("LoadInstrumentFromNexus");
Roman Tolchenov
committed
Ronald Fowler
committed
// Now execute the sub-algorithm. Catch and log any error, but don't stop.
Ronald Fowler
committed
try
{
Roman Tolchenov
committed
loadInst->setPropertyValue("Filename", m_filename);
loadInst->setProperty<MatrixWorkspace_sptr> ("Workspace", localWorkspace);
loadInst->execute();
}
catch( std::invalid_argument&)
{
Roman Tolchenov
committed
g_log.information("Invalid argument to LoadInstrument sub-algorithm");
executionSuccessful = false;
Ronald Fowler
committed
}
Ronald Fowler
committed
{
Roman Tolchenov
committed
g_log.information("Unable to successfully run LoadInstrument sub-algorithm");
executionSuccessful = false;
Ronald Fowler
committed
}
if ( !executionSuccessful ) g_log.error("No instrument definition loaded");
Ronald Fowler
committed
}
Roman Tolchenov
committed
/// Run the LoadMappingTable sub-algorithm to fill the SpectraToDetectorMap
void LoadMuonNexus::runLoadMappingTable(DataObjects::Workspace2D_sptr localWorkspace)
{
NXRoot root(m_filename);
NXInt number = root.openNXInt("run/instrument/detector/number");
Roman Tolchenov
committed
number.load();
detid_t ndet = static_cast<detid_t>(number[0]/m_numberOfPeriods);
boost::shared_array<detid_t> det(new detid_t[ndet]);
for(detid_t i=0;i<ndet;i++)
Gigg, Martyn Anthony
committed
{
Roman Tolchenov
committed
det[i] = i + 1;
Gigg, Martyn Anthony
committed
}
localWorkspace->replaceSpectraMap(new API::SpectraDetectorMap(det.get(),det.get(),ndet));
Ronald Fowler
committed
/// Run the LoadLog sub-algorithm
void LoadMuonNexus::runLoadLog(DataObjects::Workspace2D_sptr localWorkspace)
{
IAlgorithm_sptr loadLog = createSubAlgorithm("LoadMuonLog");
Ronald Fowler
committed
// Pass through the same input filename
loadLog->setPropertyValue("Filename",m_filename);
// Set the workspace property to be the same one filled above
Roman Tolchenov
committed
loadLog->setProperty<MatrixWorkspace_sptr>("Workspace",localWorkspace);
Ronald Fowler
committed
// Now execute the sub-algorithm. Catch and log any error, but don't stop.
try
{
loadLog->execute();
}
Ronald Fowler
committed
{
g_log.error("Unable to successfully run LoadLog sub-algorithm");
}
if ( ! loadLog->isExecuted() ) g_log.error("Unable to successfully run LoadLog sub-algorithm");
NXRoot root(m_filename);
Anders Markvardsen
committed
std::string start_time = root.getString("run/start_time");
NXChar orientation = root.openNXChar("run/instrument/detector/orientation");
try
{// some files have no data there
orientation.load();
// dump various Nexus numbers to outputs
Anders Markvardsen
committed
if (orientation[0] == 't')
{
Kernel::TimeSeriesProperty<double>* p = new Kernel::TimeSeriesProperty<double>("fromNexus");
p->addValue(start_time,-90.0);
localWorkspace->mutableRun().addLogData(p);
setProperty("MainFieldDirection", "Transverse");
}
else
{
setProperty("MainFieldDirection", "Longitudinal");
}
}
catch(...)
Anders Markvardsen
committed
{
setProperty("MainFieldDirection", "Longitudinal");
}
NXEntry entry = root.openEntry("run/histogram_data_1");
NXInfo info = entry.getDataSetInfo("time_zero");
Anders Markvardsen
committed
if (info.stat != NX_ERROR)
{
double dum = root.getFloat("run/histogram_data_1/time_zero");
setProperty("TimeZero", dum);
}
NXInfo infoResolution = entry.getDataSetInfo("resolution");
NXInt counts = root.openNXInt("run/histogram_data_1/counts");
Anders Markvardsen
committed
std::string firstGoodBin = counts.attributes("first_good_bin");
if ( !firstGoodBin.empty() && infoResolution.stat != NX_ERROR )
{
double bin = static_cast<double>(boost::lexical_cast<int>(firstGoodBin));
double bin_size = static_cast<double>(root.getInt("run/histogram_data_1/resolution"))/1000000.0;
setProperty("FirstGoodData", bin*bin_size);
}
NXEntry nxRun = root.openEntry("run");
Gigg, Martyn Anthony
committed
localWorkspace->setTitle(nxRun.getString("title"));
Steve Williams
committed
Gigg, Martyn Anthony
committed
std::string run_num = boost::lexical_cast<std::string>(nxRun.getInt("number"));
Steve Williams
committed
//The sample is left to delete the property
Gigg, Martyn Anthony
committed
localWorkspace->mutableRun().addLogData(new PropertyWithValue<std::string>("run_number", run_num));
}
Ronald Fowler
committed
Sofia Antony
committed
/**This method does a quick file type check by looking at the first 100 bytes of the file
* @param filePath- path of the file including name.
Janik Zikovsky
committed
* @param nread :: no.of bytes read
Gigg, Martyn Anthony
committed
* @param header :: The first 100 bytes of the file as a union
Sofia Antony
committed
* @return true if the given file is of type which can be loaded by this algorithm
*/
Gigg, Martyn Anthony
committed
bool LoadMuonNexus::quickFileCheck(const std::string& filePath,size_t nread,const file_header& header)
Sofia Antony
committed
{
std::string extn=extension(filePath);
bool bnexs(false);
(!extn.compare("nxs")||!extn.compare(".nx5"))?bnexs=true:bnexs=false;
/*
Gigg, Martyn Anthony
committed
* HDF files have magic cookie in the first 4 bytes
Sofia Antony
committed
*/
Gigg, Martyn Anthony
committed
if ( ((nread >= sizeof(unsigned)) && (ntohl(header.four_bytes) == g_hdf_cookie)) || bnexs )
Sofia Antony
committed
{
//hdf
return true;
}
Gigg, Martyn Anthony
committed
else if ( (nread >= sizeof(g_hdf5_signature)) &&
(!memcmp(header.full_hdr, g_hdf5_signature, sizeof(g_hdf5_signature))) )
Sofia Antony
committed
{
//hdf5
return true;
}
return false;
}
/**checks the file by opening it and reading few lines
Janik Zikovsky
committed
* @param filePath :: name of the file inluding its path
Sofia Antony
committed
* @return an integer value how much this algorithm can load the file
*/
int LoadMuonNexus::fileCheck(const std::string& filePath)
{
Gigg, Martyn Anthony
committed
using namespace ::NeXus;
int confidence(0);
try
Sofia Antony
committed
{
Gigg, Martyn Anthony
committed
::NeXus::File file = ::NeXus::File(filePath);
file.openPath("/run/analysis");
std::string analysisType = file.getStrData();
if( analysisType == "muonTD" )
{
// If all this succeeded then we'll assume this is an ISIS Muon NeXus file
confidence = 80;
}
file.close();
Sofia Antony
committed
}
Gigg, Martyn Anthony
committed
catch(::NeXus::Exception&)
Sofia Antony
committed
{
}
Gigg, Martyn Anthony
committed
return confidence;
Sofia Antony
committed
}
Ronald Fowler
committed
} // namespace DataHandling
} // namespace Mantid