diff --git a/Code/Mantid/Framework/DataHandling/src/LoadISISNexus2.cpp b/Code/Mantid/Framework/DataHandling/src/LoadISISNexus2.cpp index fddfef1e1385a8439e317da6dff4302b0a858ae6..585a52fb09c0e02d79c7ee191c1cb2f5ee798594 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadISISNexus2.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadISISNexus2.cpp @@ -52,8 +52,7 @@ LoadISISNexus2::LoadISISNexus2() m_load_selected_spectra(false), m_specInd2specNum_map(), m_spec2det_map(), m_entrynumber(0), m_tof_data(), m_proton_charge(0.), m_spec(), m_spec_end(NULL), m_monitors(), m_logCreator(), m_progress(), - m_cppFile() { -} + m_cppFile() {} /** * Return the confidence criteria for this algorithm can load the file @@ -231,14 +230,13 @@ void LoadISISNexus2::exec() { m_filename, local_workspace, "raw_data_1", this); if (m_load_selected_spectra) m_spec2det_map = SpectrumDetectorMapping(spec(), udet(), udet.dim0()); - else - if (bseparateMonitors) { - m_spec2det_map = SpectrumDetectorMapping(spec(), udet(), udet.dim0()); - local_workspace->updateSpectraUsing(m_spec2det_map); - }else{ - local_workspace->updateSpectraUsing( + else if (bseparateMonitors) { + m_spec2det_map = SpectrumDetectorMapping(spec(), udet(), udet.dim0()); + local_workspace->updateSpectraUsing(m_spec2det_map); + } else { + local_workspace->updateSpectraUsing( SpectrumDetectorMapping(spec(), udet(), udet.dim0())); - } + } if (!foundInstrument) { runLoadInstrument(local_workspace); @@ -263,7 +261,7 @@ void LoadISISNexus2::exec() { m_tof_data.reset(new MantidVec(timeBins(), timeBins() + x_length)); } int64_t firstentry = (m_entrynumber > 0) ? m_entrynumber : 1; - loadPeriodData(firstentry, entry, local_workspace,m_load_selected_spectra); + loadPeriodData(firstentry, entry, local_workspace, m_load_selected_spectra); // Clone the workspace at this point to provide a base object for future // workspace generation. @@ -273,9 +271,9 @@ void LoadISISNexus2::exec() { createPeriodLogs(firstentry, local_workspace); + WorkspaceGroup_sptr wksp_group(new WorkspaceGroup); if (m_detBlockInfo.numberOfPeriods > 1 && m_entrynumber == 0) { - WorkspaceGroup_sptr wksp_group(new WorkspaceGroup); wksp_group->setTitle(local_workspace->getTitle()); // This forms the name of the group @@ -289,7 +287,7 @@ void LoadISISNexus2::exec() { if (p > 1) { local_workspace = boost::dynamic_pointer_cast<DataObjects::Workspace2D>( WorkspaceFactory::Instance().create(period_free_workspace)); - loadPeriodData(p, entry, local_workspace,m_load_selected_spectra); + loadPeriodData(p, entry, local_workspace, m_load_selected_spectra); createPeriodLogs(p, local_workspace); // Check consistency of logs data for multi-period workspaces and raise // warnings where necessary. @@ -302,62 +300,99 @@ void LoadISISNexus2::exec() { boost::static_pointer_cast<Workspace>(local_workspace)); } // The group is the root property value - if (!bseparateMonitors) - setProperty("OutputWorkspace", - boost::dynamic_pointer_cast<Workspace>(wksp_group)); + setProperty("OutputWorkspace", + boost::dynamic_pointer_cast<Workspace>(wksp_group)); } else { - if (!bseparateMonitors) - setProperty("OutputWorkspace", - boost::dynamic_pointer_cast<Workspace>(local_workspace)); + setProperty("OutputWorkspace", + boost::dynamic_pointer_cast<Workspace>(local_workspace)); } //*************************************************************************************************** // Workspace or group of workspaces without monitors is loaded. Now we are // loading monitors separately. if (bseparateMonitors) { - setProperty("OutputWorkspace", - boost::dynamic_pointer_cast<Workspace>(local_workspace)); - if (m_detBlockInfo.numberOfPeriods > 1) { - g_log.error() << " Separate monitor workspace loading have not been " - "implemented for multiperiod workspaces. Performed " - "separate monitors loading\n"; - } else { - std::string wsName = getProperty("OutputWorkspace"); - if (m_monBlockInfo.numberOfSpectra == 0) { - g_log.information() << " no monitors to load for workspace: " << wsName - << std::endl; + std::string wsName = getPropertyValue("OutputWorkspace"); + if (m_monBlockInfo.numberOfSpectra > 0) { + x_length = m_monBlockInfo.numberOfChannels + 1; + // reset the size of the period free workspace to the monitor size + period_free_workspace = + boost::dynamic_pointer_cast<DataObjects::Workspace2D>( + WorkspaceFactory::Instance().create( + period_free_workspace, m_monBlockInfo.numberOfSpectra, + x_length, m_monBlockInfo.numberOfChannels)); + auto monitor_workspace = + boost::dynamic_pointer_cast<DataObjects::Workspace2D>( + WorkspaceFactory::Instance().create(period_free_workspace)); + + m_spectraBlocks.clear(); + m_specInd2specNum_map.clear(); + std::vector<int64_t> dummyS1; + // at the moment here we clear this map to enable possibility to load + // monitors from the spectra block (wiring table bug). + // if monitor's spectra present in the detectors block due to this bug + // should be read from monitors, this map should be dealt with properly. + ExcluedMonitorsSpectra.clear(); + buildSpectraInd2SpectraNumMap(true, m_monBlockInfo.spectraID_min, + m_monBlockInfo.spectraID_max, dummyS1, + ExcluedMonitorsSpectra); + // lo + prepareSpectraBlocks(m_monitors, m_specInd2specNum_map, m_monBlockInfo); + + int64_t firstentry = (m_entrynumber > 0) ? m_entrynumber : 1; + loadPeriodData(firstentry, entry, monitor_workspace, true); + local_workspace->setMonitorWorkspace(monitor_workspace); + + ISISRunLogs monLogCreator(monitor_workspace->run(), + m_detBlockInfo.numberOfPeriods); + monLogCreator.addPeriodLogs(1, monitor_workspace->mutableRun()); + + const std::string monitorPropBase = "MonitorWorkspace"; + const std::string monitorWsNameBase = wsName + "_monitors"; + if (m_detBlockInfo.numberOfPeriods > 1 && m_entrynumber == 0) { + WorkspaceGroup_sptr monitor_group(new WorkspaceGroup); + monitor_group->setTitle(monitor_workspace->getTitle()); + + for (int p = 1; p <= m_detBlockInfo.numberOfPeriods; ++p) { + std::ostringstream os; + os << "_" << p; + m_progress->report("Loading period " + os.str()); + if (p > 1) { + monitor_workspace = + boost::dynamic_pointer_cast<DataObjects::Workspace2D>( + WorkspaceFactory::Instance().create(period_free_workspace)); + loadPeriodData(p, entry, monitor_workspace, + m_load_selected_spectra); + monLogCreator.addPeriodLogs(p, monitor_workspace->mutableRun()); + // Check consistency of logs data for multi-period workspaces and + // raise + // warnings where necessary. + validateMultiPeriodLogs(monitor_workspace); + auto data_ws = boost::static_pointer_cast<API::MatrixWorkspace>( + wksp_group->getItem(p - 1)); + data_ws->setMonitorWorkspace(monitor_workspace); + } + declareProperty(new WorkspaceProperty<Workspace>( + monitorPropBase + os.str(), monitorWsNameBase + os.str(), + Direction::Output)); + monitor_group->addWorkspace(monitor_workspace); + setProperty(monitorPropBase + os.str(), + boost::static_pointer_cast<Workspace>(monitor_workspace)); + } + // The group is the root property value + declareProperty(new WorkspaceProperty<Workspace>( + monitorPropBase, monitorWsNameBase, Direction::Output)); + setProperty(monitorPropBase, + boost::dynamic_pointer_cast<Workspace>(monitor_group)); + } else { - x_length = m_monBlockInfo.numberOfChannels + 1; - DataObjects::Workspace2D_sptr monitor_workspace = - boost::dynamic_pointer_cast<DataObjects::Workspace2D>( - WorkspaceFactory::Instance().create( - local_workspace, m_monBlockInfo.numberOfSpectra, x_length, - m_monBlockInfo.numberOfChannels)); - local_workspace->setMonitorWorkspace(monitor_workspace); - - m_spectraBlocks.clear(); - m_specInd2specNum_map.clear(); - std::vector<int64_t> dummyS1; - // at the moment here we clear this map to enable possibility to load - // monitors from the spectra block (wiring table bug). - // if monitor's spectra present in the detectors block due to this bug - // should be read from monitors, this map should be dealt with properly. - ExcluedMonitorsSpectra.clear(); - buildSpectraInd2SpectraNumMap(true, m_monBlockInfo.spectraID_min, - m_monBlockInfo.spectraID_max, dummyS1, - ExcluedMonitorsSpectra); - // lo - prepareSpectraBlocks(m_monitors, m_specInd2specNum_map, m_monBlockInfo); - - int64_t firstentry = (m_entrynumber > 0) ? m_entrynumber : 1; - loadPeriodData(firstentry, entry, monitor_workspace,true); - - std::string monitorwsName = wsName + "_monitors"; declareProperty(new WorkspaceProperty<Workspace>( - "MonitorWorkspace", monitorwsName, Direction::Output)); - setProperty("MonitorWorkspace", + monitorPropBase, monitorWsNameBase, Direction::Output)); + setProperty(monitorPropBase, boost::static_pointer_cast<Workspace>(monitor_workspace)); } + } else { + g_log.information() << " no monitors to load for workspace: " << wsName + << std::endl; } } diff --git a/Code/Mantid/Framework/DataHandling/test/LoadISISNexusTest.h b/Code/Mantid/Framework/DataHandling/test/LoadISISNexusTest.h index 6c300c5785e0849c6931fff17419e315b69c4815..e1918cbf2cacbc9c7c82addcb29c45780fe3b6d8 100644 --- a/Code/Mantid/Framework/DataHandling/test/LoadISISNexusTest.h +++ b/Code/Mantid/Framework/DataHandling/test/LoadISISNexusTest.h @@ -18,6 +18,8 @@ #include "MantidDataHandling/LoadISISNexus.h" #include "MantidDataHandling/LoadISISNexus2.h" +#include <cmath> + using namespace Mantid::API; using namespace Mantid::Kernel; using namespace Mantid::DataHandling; @@ -46,7 +48,7 @@ private: // Helper method to check that the log data contains a specific period number entry. void checkPeriodLogData(MatrixWorkspace_sptr workspace, int expectedPeriodNumber) { - Property* p = NULL; + Property* p = NULL; TS_ASSERT_THROWS_NOTHING(p = fetchPeriodLog(workspace, expectedPeriodNumber)); TS_ASSERT(p != NULL) TSM_ASSERT_THROWS("Shouldn't have a period less than the expected entry", fetchPeriodLog(workspace, expectedPeriodNumber-1), Mantid::Kernel::Exception::NotFoundError); @@ -112,8 +114,8 @@ public: TS_ASSERT_EQUALS(mon_ws->readY(0)[3],0.); - const std::vector< Property* >& logs = mon_ws->run().getLogData(); + for(size_t i = 0; i < logs.size(); ++i) std::cerr << logs[i]->name() << "\n"; TS_ASSERT_EQUALS(logs.size(), 62); std::string header = mon_ws->run().getPropertyValueAsType<std::string>("run_header"); @@ -633,38 +635,62 @@ public: AnalysisDataService::Instance().remove("outWS"); } - void xestExecMonExcludedInTheEnd() + void testExecMultiPeriodMonitorSeparate() { - Mantid::API::FrameworkManager::Instance(); LoadISISNexus2 ld; + ld.setChild(true); ld.initialize(); - ld.setPropertyValue("Filename","MAPS00018314.nxs"); - ld.setPropertyValue("SpectrumMin","2"); - ld.setPropertyValue("SpectrumMax","10"); - ld.setPropertyValue("OutputWorkspace","outWS"); - ld.setPropertyValue("LoadMonitors","Separate"); // + ld.setPropertyValue("Filename","POLREF00004699.nxs"); + ld.setPropertyValue("OutputWorkspace","__unused_for_child"); + ld.setPropertyValue("LoadMonitors","Separate"); TS_ASSERT_THROWS_NOTHING(ld.execute()); TS_ASSERT(ld.isExecuted()); - - MatrixWorkspace_sptr ws = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>("outWS"); - TS_ASSERT_EQUALS(ws->blocksize(),2000); - TS_ASSERT_EQUALS(ws->getNumberHistograms(),9); - - MatrixWorkspace_sptr ws_mon = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>("outWS_monitors"); - TS_ASSERT(ws_mon) - - TS_ASSERT_EQUALS(ws_mon->blocksize(),2000); - TS_ASSERT_EQUALS(ws_mon->getNumberHistograms(),4); - TS_ASSERT_DELTA(ws_mon->readX(0)[0],10,1.e-8); - - - TS_ASSERT_EQUALS(ws_mon->getSpectrum(0)->getSpectrumNo(),41473); - TS_ASSERT_EQUALS(ws_mon->getSpectrum(3)->getSpectrumNo(),41476); - - - AnalysisDataService::Instance().remove("outWS"); - AnalysisDataService::Instance().remove("outWS_monitors"); + Workspace_sptr detWS = ld.getProperty("OutputWorkspace"); + auto detGroup = boost::dynamic_pointer_cast<WorkspaceGroup>(detWS); + TS_ASSERT(detGroup); + Workspace_sptr monWS = ld.getProperty("MonitorWorkspace"); + auto monGroup = boost::dynamic_pointer_cast<WorkspaceGroup>(monWS); + TS_ASSERT(monGroup); + + if(!(detGroup && monGroup)) return; + + TS_ASSERT_EQUALS(2, detGroup->size()); + TS_ASSERT_EQUALS(2, monGroup->size()); + + auto detWS0 = boost::dynamic_pointer_cast<MatrixWorkspace>(detGroup->getItem(0)); + TS_ASSERT_EQUALS(1000, detWS0->blocksize()); + TS_ASSERT_EQUALS(243, detWS0->getNumberHistograms()); + TS_ASSERT_DELTA(105, detWS0->readX(1)[1], 1e-08); + TS_ASSERT_DELTA(2, detWS0->readY(1)[1], 1e-08); + TS_ASSERT_DELTA(std::sqrt(2.0), detWS0->readE(1)[1], 1e-08); + TS_ASSERT_EQUALS(detWS0->getSpectrum(0)->getSpectrumNo(),4); + + auto monWS0 = boost::dynamic_pointer_cast<MatrixWorkspace>(monGroup->getItem(0)); + TS_ASSERT_EQUALS(1000, monWS0->blocksize()); + TS_ASSERT_EQUALS(3, monWS0->getNumberHistograms()); + TS_ASSERT_DELTA(105, monWS0->readX(1)[1], 1e-08); + TS_ASSERT_DELTA(12563.0, monWS0->readY(0)[1], 1e-08); + TS_ASSERT_DELTA(std::sqrt(12563.0), monWS0->readE(0)[1], 1e-08); + TS_ASSERT_EQUALS(monWS0->getSpectrum(0)->getSpectrumNo(),1); + TS_ASSERT_EQUALS(monWS0->getSpectrum(2)->getSpectrumNo(),3); + + auto monWS1 = boost::dynamic_pointer_cast<MatrixWorkspace>(monGroup->getItem(1)); + TS_ASSERT_EQUALS(1000, monWS1->blocksize()); + TS_ASSERT_EQUALS(3, monWS1->getNumberHistograms()); + TS_ASSERT_DELTA(105, monWS1->readX(1)[1], 1e-08); + TS_ASSERT_DELTA(12595.0, monWS1->readY(0)[1], 1e-08); + TS_ASSERT_DELTA(std::sqrt(12595.0), monWS1->readE(0)[1], 1e-08); + TS_ASSERT_EQUALS(monWS1->getSpectrum(0)->getSpectrumNo(),1); + TS_ASSERT_EQUALS(monWS1->getSpectrum(2)->getSpectrumNo(),3); + + // Same number of logs + const auto & monPeriod1Run = monWS0->run(); + const auto & monPeriod2Run = monWS1->run(); + TS_ASSERT_EQUALS(monPeriod1Run.getLogData().size(), monPeriod2Run.getLogData().size() ); + TS_ASSERT(monPeriod1Run.hasProperty("period 1")) + TS_ASSERT(monPeriod2Run.hasProperty("period 2")) + } };