Skip to content

Commit

Permalink
Re #9958. Selecting periods to load.
Browse files Browse the repository at this point in the history
  • Loading branch information
mantid-roman committed Sep 2, 2014
1 parent c7359d3 commit eea40bf
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 22 deletions.
Expand Up @@ -64,10 +64,10 @@ namespace Mantid
ILiveListener::RunStatus runStatus();
int runNumber() const;

void setSpectra(const std::vector<specid_t>& specList);

private:

void setSpectra(const std::vector<specid_t>& specList);
void setPeriods(const std::vector<specid_t>& periodList);
int getInt(const std::string& par) const;
std::string getString(const std::string& par) const;
void getFloatArray(const std::string& par, std::vector<float>& arr, const size_t dim);
Expand All @@ -78,6 +78,7 @@ namespace Mantid
void runLoadInstrument(boost::shared_ptr<API::MatrixWorkspace> localWorkspace, const std::string& iName);
void loadTimeRegimes();
int getTimeRegimeToLoad() const;
bool isPeriodIgnored(int period) const;
static double dblSqrt(double in);

/// is initialized
Expand Down
69 changes: 54 additions & 15 deletions Code/Mantid/Framework/LiveData/src/ISISHistoDataListener.cpp
Expand Up @@ -10,6 +10,7 @@
#include "MantidKernel/Exception.h"
#include "MantidKernel/UnitFactory.h"
#include "MantidKernel/ArrayProperty.h"
#include "MantidKernel/ArrayBoundedValidator.h"
#include "MantidKernel/WarningSuppressions.h"
#include "MantidGeometry/Instrument.h"

Expand Down Expand Up @@ -44,9 +45,12 @@ namespace LiveData
/// Constructor
ISISHistoDataListener::ISISHistoDataListener() : ILiveListener(), isInitilized(false), m_daeHandle( NULL ), m_timeRegime(-1)
{
declareProperty(new Kernel::ArrayProperty<specid_t>("SpectraList",""),
declareProperty(new Kernel::ArrayProperty<specid_t>("SpectraList"),
"An optional list of spectra to load. If blank, all available spectra will be loaded.");
declareProperty(new Kernel::ArrayProperty<specid_t>("Periods",""),

auto validator = boost::make_shared<Kernel::ArrayBoundedValidator<int>>();
validator->setLower( 1 );
declareProperty(new Kernel::ArrayProperty<int>("Periods",validator),
"An optional list of periods to load. If blank, all available periods will be loaded.");
}

Expand Down Expand Up @@ -77,16 +81,6 @@ namespace LiveData
bool ISISHistoDataListener::connect(const Poco::Net::SocketAddress& address)
{

// Set the spectra list to load
std::vector<specid_t> spectra = getProperty("SpectraList");
if ( !spectra.empty() )
{
setSpectra( spectra );
}

// Set the period list to load
m_periodList = getProperty("Periods");

m_daeName = address.toString();
// remove the port part
auto i = m_daeName.find(':');
Expand All @@ -107,6 +101,20 @@ namespace LiveData
m_numberOfPeriods = getInt("NPER");
g_log.debug() << "Number of periods " << m_numberOfPeriods << std::endl;

// Set the spectra list to load
std::vector<specid_t> spectra = getProperty("SpectraList");
if ( !spectra.empty() )
{
setSpectra( spectra );
}

// Set the period list to load
std::vector<int> periodList = getProperty("Periods");
if ( !periodList.empty() )
{
setPeriods( periodList );
}

loadSpectraMap();

loadTimeRegimes();
Expand Down Expand Up @@ -196,13 +204,17 @@ namespace LiveData
// cut the spectra numbers into chunks
std::vector<int> index, count;
calculateIndicesForReading(index, count);

int firstPeriod = m_periodList.empty() ? 0: m_periodList.front() - 1;

// create a workspace group in case the data are multiperiod
auto workspaceGroup = API::WorkspaceGroup_sptr( new API::WorkspaceGroup );
// loop over periods and spectra and fill in the output workspace
for(int period = 0; period < m_numberOfPeriods; ++period)
{
if ( period > 0 )
if ( isPeriodIgnored( period ) ) continue;

if ( period > firstPeriod )
{
// create a new matrix workspace similar to the previous, copy over the instrument info
localWorkspace = WorkspaceFactory::Instance().create( localWorkspace );
Expand All @@ -215,7 +227,7 @@ namespace LiveData
workspaceIndex += count[i];
}

if (period == 0)
if (period == firstPeriod)
{
// Only run the Child Algorithms once
runLoadInstrument( localWorkspace, getString("NAME") );
Expand All @@ -230,7 +242,7 @@ namespace LiveData
}
}

if ( m_numberOfPeriods > 1 )
if ( m_numberOfPeriods > 1 && (m_periodList.empty() || m_periodList.size() > 1) )
{
return workspaceGroup;
}
Expand Down Expand Up @@ -283,6 +295,22 @@ namespace LiveData
}
}

/** Sets a list of periods to be extracted. Default is reading all available periods.
* @param periodList :: A vector with period numbers.
*/
void ISISHistoDataListener::setPeriods(const std::vector<specid_t>& periodList)
{
// after listener has created its first workspace the period numbers cannot be changed
if ( !isInitilized )
{
m_periodList = periodList;
if ( *std::max_element( m_periodList.begin(), m_periodList.end() ) > m_numberOfPeriods )
{
throw std::invalid_argument( "Invalid period(s) specified. Maximum " + boost::lexical_cast<std::string>(m_numberOfPeriods) );
}
}
}

/**
* Read an array of floats from the DAE
* @param par :: Array name
Expand Down Expand Up @@ -601,5 +629,16 @@ namespace LiveData
return sqrt( in );
}

/**
* Check if a data period should be ignored.
* @param period :: Period to check.
* @return :: True to ignore the period.
*/
bool ISISHistoDataListener::isPeriodIgnored(int period) const
{
if ( m_periodList.empty() ) return false;
return std::find( m_periodList.begin(), m_periodList.end(), period + 1 ) == m_periodList.end();
}

} // namespace LiveData
} // namespace Mantid
76 changes: 71 additions & 5 deletions Code/Mantid/Framework/LiveData/test/ISISHistoDataListenerTest.h
Expand Up @@ -127,10 +127,10 @@ class ISISHistoDataListenerTest : public CxxTest::TestSuite

}

#ifdef _WIN32

void test_Receiving_multiperiod_data()
{

#ifdef _WIN32
FacilityHelper::ScopedFacilities loadTESTFacility("IDFs_for_UNIT_TESTING/UnitTestFacilities.xml", "TEST");

FakeISISHistoDAE dae;
Expand Down Expand Up @@ -238,10 +238,76 @@ class ISISHistoDataListenerTest : public CxxTest::TestSuite

dae.cancel();
res.wait();
#else
TS_ASSERT( true );
#endif
}

void test_Receiving_selected_periods()
{
FacilityHelper::ScopedFacilities loadTESTFacility("IDFs_for_UNIT_TESTING/UnitTestFacilities.xml", "TEST");

FakeISISHistoDAE dae;
dae.initialize();
dae.setProperty("NPeriods",4);
auto res = dae.executeAsync();

Kernel::PropertyManager props;
props.declareProperty(new Kernel::ArrayProperty<int>("Periods"));
std::vector<int> periods(2);
periods[0] = 2;
periods[1] = 3;
props.setProperty( "Periods", periods );

auto listener = Mantid::API::LiveListenerFactory::Instance().create("TESTHISTOLISTENER",true,&props);
TS_ASSERT( listener );
TSM_ASSERT("Listener has failed to connect", listener->isConnected() );
if (!listener->isConnected()) return;

auto outWS = listener->extractData();
auto group = boost::dynamic_pointer_cast<WorkspaceGroup>( outWS );
TS_ASSERT( group );
TS_ASSERT_EQUALS( group->size(), 2 );
auto ws1 = boost::dynamic_pointer_cast<MatrixWorkspace>( group->getItem(0) );
TS_ASSERT( ws1 );
auto ws2 = boost::dynamic_pointer_cast<MatrixWorkspace>( group->getItem(1) );
TS_ASSERT( ws2 );

auto y = ws1->readY( 2 );
TS_ASSERT_EQUALS( y[0], 1003 );
TS_ASSERT_EQUALS( y[5], 1003 );
TS_ASSERT_EQUALS( y[29], 1003 );

y = ws2->readY( 2 );
TS_ASSERT_EQUALS( y[0], 2003 );
TS_ASSERT_EQUALS( y[5], 2003 );
TS_ASSERT_EQUALS( y[29], 2003 );

dae.cancel();
res.wait();
}


void test_no_period()
{
FacilityHelper::ScopedFacilities loadTESTFacility("IDFs_for_UNIT_TESTING/UnitTestFacilities.xml", "TEST");

FakeISISHistoDAE dae;
dae.initialize();
dae.setProperty("NPeriods",4);
auto res = dae.executeAsync();

Kernel::PropertyManager props;
props.declareProperty(new Kernel::ArrayProperty<int>("Periods"));
std::vector<int> periods(2);
periods[0] = 2;
periods[1] = 5; // this period doesn't exist in dae
props.setProperty( "Periods", periods );

TS_ASSERT_THROWS( auto listener = Mantid::API::LiveListenerFactory::Instance().create("TESTHISTOLISTENER",true,&props), std::invalid_argument );

dae.cancel();
res.wait();
}

#endif
};


Expand Down

0 comments on commit eea40bf

Please sign in to comment.