Newer
Older
#include "MantidDataHandling/EventWorkspaceCollection.h"
#include "MantidDataObjects/EventWorkspace.h"
#include "MantidKernel/UnitFactory.h"
Federico Montesino Pouzols
committed
#include "MantidAPI/Axis.h"
#include "MantidAPI/Run.h"
#include <vector>
#include <set>
#include <memory>
#include <boost/bind.hpp>
namespace Mantid {
namespace DataHandling {
using namespace Mantid::DataObjects;
using namespace Mantid::Kernel;
using namespace Mantid::API;
namespace {
/**
* Copy all logData properties from the 'from' workspace to the 'to'
* workspace. Does not use CopyLogs as a child algorithm (this is a
* simple copy and the workspace is not yet in the ADS).
*
* @param from source of log entries
* @param to workspace where to add the log entries
*/
void copyLogs(const EventWorkspace_sptr &from, EventWorkspace_sptr &to) {
// from the logs, get all the properties that don't overwrite any
// prop. already set in the sink workspace (like 'filename').
auto props = from->mutableRun().getLogData();
for (auto &prop : props) {
if (!to->mutableRun().hasProperty(prop->name())) {
to->mutableRun().addLogData(prop->clone());
}
}
}
}
//----------------------------------------------------------------------------------------------
/** Constructor
*/
EventWorkspaceCollection::EventWorkspaceCollection()
: m_WsVec(1, createEmptyEventWorkspace()) {}
//-----------------------------------------------------------------------------
/**
* Create a blank event workspace
* @returns A shared pointer to a new empty EventWorkspace object
*/
EventWorkspace_sptr
EventWorkspaceCollection::createEmptyEventWorkspace() const {
// Create the output workspace
EventWorkspace_sptr eventWS(new EventWorkspace());
// Make sure to initialize.
// We can use dummy numbers for arguments, for event workspace it doesn't
// matter
eventWS->initialize(1, 1, 1);
// Set the units
eventWS->getAxis(0)->unit() = UnitFactory::Instance().create("TOF");
eventWS->setYUnit("Counts");
return eventWS;
}
void EventWorkspaceCollection::setNPeriods(
size_t nPeriods,
std::unique_ptr<const TimeSeriesProperty<int>> &periodLog) {
// Create vector where size is the number of periods and initialize workspaces
// in each.
m_WsVec = std::vector<DataObjects::EventWorkspace_sptr>(nPeriods);
std::vector<int> periodNumbers = periodLog->valuesAsVector();
std::unordered_set<int> uniquePeriods(periodNumbers.begin(),
periodNumbers.end());
const bool addBoolTimeSeries = (uniquePeriods.size() == nPeriods);
for (size_t i = 0; i < m_WsVec.size(); ++i) {
const int periodNumber = int(i + 1);
m_WsVec[i] = createEmptyEventWorkspace();
m_WsVec[i]->copyExperimentInfoFrom(temp.get());
if (addBoolTimeSeries) {
std::stringstream buffer;
buffer << "period " << periodNumber;
auto *periodBoolLog = new Kernel::TimeSeriesProperty<bool>(buffer.str());
for (int j = 0; j < int(periodLog->size()); ++j) {
periodBoolLog->addValue(periodLog->nthTime(j),
periodNumber == periodLog->nthValue(j));
}
Run &mutableRun = m_WsVec[i]->mutableRun();
mutableRun.addProperty(periodBoolLog);
Kernel::PropertyWithValue<int> *currentPeriodProperty =
new Kernel::PropertyWithValue<int>("current_period", periodNumber);
mutableRun.addProperty(currentPeriodProperty);
copyLogs(
temp,
m_WsVec[i]); // Copy all logs from dummy workspace to period workspaces.
m_WsVec[i]->setInstrument(temp->getInstrument());
}
}
void EventWorkspaceCollection::reserveEventListAt(size_t wi, size_t size) {
ws->getSpectrum(wi).reserve(size);
size_t EventWorkspaceCollection::nPeriods() const { return m_WsVec.size(); }
DataObjects::EventWorkspace_sptr
EventWorkspaceCollection::getSingleHeldWorkspace() {
return m_WsVec.front();
}
API::Workspace_sptr EventWorkspaceCollection::combinedWorkspace() {
API::Workspace_sptr final;
if (this->nPeriods() == 1) {
final = getSingleHeldWorkspace();
} else {
auto wsg = boost::make_shared<API::WorkspaceGroup>();
for (auto &ws : m_WsVec) {
wsg->addWorkspace(ws);
final = wsg;
}
return final;
Geometry::Instrument_const_sptr
EventWorkspaceCollection::getInstrument() const {
return m_WsVec[0]->getInstrument();
const API::Run &EventWorkspaceCollection::run() const {
return m_WsVec[0]->run();
API::Run &EventWorkspaceCollection::mutableRun() {
return m_WsVec[0]->mutableRun();
API::Sample &EventWorkspaceCollection::mutableSample() {
return m_WsVec[0]->mutableSample();
}
EventList &EventWorkspaceCollection::getSpectrum(const size_t index) {
return m_WsVec[0]->getSpectrum(index);
const EventList &
EventWorkspaceCollection::getSpectrum(const size_t index) const {
return m_WsVec[0]->getSpectrum(index);
void EventWorkspaceCollection::setSpectrumNumbersFromUniqueSpectra(
const std::set<int> uniqueSpectra) {
// For each workspace, update all the spectrum numbers
for (auto &ws : m_WsVec) {
size_t counter = 0;
ws->getSpectrum(counter).setSpectrumNo(spectrum);
++counter;
}
}
}
void EventWorkspaceCollection::setSpectrumNumberForAllPeriods(
const size_t spectrumNumber, const specnum_t specid) {
for (auto &ws : m_WsVec) {
auto &spec = ws->getSpectrum(spectrumNumber);
spec.setSpectrumNo(specid);
void EventWorkspaceCollection::setDetectorIdsForAllPeriods(
const size_t spectrumNumber, const detid_t id) {
for (auto &ws : m_WsVec) {
auto &spec = ws->getSpectrum(spectrumNumber);
spec.setDetectorID(id);
Mantid::API::Axis *EventWorkspaceCollection::getAxis(const size_t &i) const {
return m_WsVec[0]->getAxis(i);
size_t EventWorkspaceCollection::getNumberHistograms() const {
return m_WsVec[0]->getNumberHistograms();
EventWorkspaceCollection::getSpectrum(const size_t workspace_index,
const size_t periodNumber) const {
return m_WsVec[periodNumber]->getSpectrum(workspace_index);
EventWorkspaceCollection::getSpectrum(const size_t workspace_index,
const size_t periodNumber) {
return m_WsVec[periodNumber]->getSpectrum(workspace_index);
std::vector<size_t> EventWorkspaceCollection::getSpectrumToWorkspaceIndexVector(
Mantid::specnum_t &offset) const {
return m_WsVec[0]->getSpectrumToWorkspaceIndexVector(offset);
std::vector<size_t>
EventWorkspaceCollection::getDetectorIDToWorkspaceIndexVector(
Mantid::specnum_t &offset, bool dothrow) const {
return m_WsVec[0]->getDetectorIDToWorkspaceIndexVector(offset, dothrow);
Kernel::DateAndTime EventWorkspaceCollection::getFirstPulseTime() const {
return m_WsVec[0]->getFirstPulseTime();
void EventWorkspaceCollection::setAllX(Kernel::cow_ptr<MantidVec> &x) {
for (auto &ws : m_WsVec) {
ws->setAllX(x);
size_t EventWorkspaceCollection::getNumberEvents() const {
return m_WsVec[0]->getNumberEvents(); // Should be the sum across all periods?
void EventWorkspaceCollection::resizeTo(const size_t size) {
for (auto &ws : m_WsVec) {
ws->resizeTo(size); // Creates the EventLists
void EventWorkspaceCollection::padSpectra(const std::vector<int32_t> &padding) {
for (auto &ws : m_WsVec) {
ws->padSpectra(padding); // Set detector ids and spectrum numbers
void EventWorkspaceCollection::setInstrument(
const Geometry::Instrument_const_sptr &inst) {
for (auto &ws : m_WsVec) {
ws->setInstrument(inst);
void EventWorkspaceCollection::setMonitorWorkspace(
const boost::shared_ptr<API::MatrixWorkspace> &monitorWS) {
for (auto &ws : m_WsVec) {
ws->setMonitorWorkspace(
monitorWS); // TODO, do we really set the same monitor on all periods???
}
void EventWorkspaceCollection::updateSpectraUsing(
const API::SpectrumDetectorMapping &map) {
for (auto &ws : m_WsVec) {
ws->updateSpectraUsing(map);
void EventWorkspaceCollection::populateInstrumentParameters() {
for (auto &ws : m_WsVec) {
ws->populateInstrumentParameters();
void EventWorkspaceCollection::setGeometryFlag(const int flag) {
for (auto &ws : m_WsVec) {
ws->mutableSample().setGeometryFlag(flag);
void EventWorkspaceCollection::setThickness(const float flag) {
for (auto &ws : m_WsVec) {
ws->mutableSample().setThickness(flag);
void EventWorkspaceCollection::setHeight(const float flag) {
for (auto &ws : m_WsVec) {
ws->mutableSample().setHeight(flag);
void EventWorkspaceCollection::setWidth(const float flag) {
for (auto &ws : m_WsVec) {
ws->mutableSample().setWidth(flag);
void EventWorkspaceCollection::setTitle(std::string title) {
for (auto &ws : m_WsVec) {
ws->setTitle(title);
void EventWorkspaceCollection::applyFilter(
boost::function<void(MatrixWorkspace_sptr)> func) {
//-----------------------------------------------------------------------------
/** Returns true if the EventWorkspace is safe for multithreaded operations.
*/
bool EventWorkspaceCollection::threadSafe() const {
// Since there is a mutex lock around sorting, EventWorkspaces are always
// safe.
return true;
}
} // namespace DataHandling
} // namespace Mantid