diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadRaw3.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadRaw3.h index c187996195bf..1203d8d98bfd 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadRaw3.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadRaw3.h @@ -93,6 +93,15 @@ namespace Mantid void separateMonitors(FILE* file,const int64_t& period,const std::vector& monitorList, DataObjects::Workspace2D_sptr ws_sptr,DataObjects::Workspace2D_sptr mws_sptr); + /// skip all spectra in a period + void skipPeriod(FILE* file,const int64_t& period); + /// return true if loading a selection of periods + bool isSelectedPeriods() const {return !m_periodList.empty(); } + /// check if a period should be loaded + bool isPeriodIncluded(int period) const; + /// get the previous period number + int getPreviousPeriod(int period) const; + ///sets optional properties void setOptionalProperties(); @@ -124,6 +133,8 @@ namespace Mantid std::vector > m_timeChannelsVec; /// total number of specs int64_t m_total_specs; + /// A list of periods to read. Each value is between 1 and m_numberOfPeriods + std::vector m_periodList; }; } // namespace DataHandling diff --git a/Code/Mantid/Framework/DataHandling/src/LoadRaw3.cpp b/Code/Mantid/Framework/DataHandling/src/LoadRaw3.cpp index 591fd93bbe16..375206e01fb8 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadRaw3.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadRaw3.cpp @@ -59,6 +59,9 @@ namespace Mantid declareProperty(new ArrayProperty ("SpectrumList"), "A comma-separated list of individual spectra to read. Only used if\n" "explicitly set."); + declareProperty(new ArrayProperty ("PeriodList"), + "A comma-separated list of individual periods to read. Only used if\n" + "explicitly set."); std::vector monitorOptions; monitorOptions.push_back("Include"); @@ -125,6 +128,9 @@ namespace Mantid // Get the time channel array(s) and store in a vector inside a shared pointer m_timeChannelsVec =getTimeChannels(m_noTimeRegimes,m_lengthIn); + // The first period to load + int firstPeriod = isSelectedPeriods() ? m_periodList.front() - 1 : 0; + // Create the 2D workspace for the output DataObjects::Workspace2D_sptr localWorkspace = createWorkspace(m_total_specs, m_lengthIn,m_lengthIn-1,title); @@ -140,7 +146,7 @@ namespace Mantid { runLoadLog(m_filename,localWorkspace, 0.4, 0.5); m_prog_start = 0.5; - const int period_number = 1; + const int period_number = firstPeriod + 1; createPeriodLogs(period_number, localWorkspace); } // Set the total proton charge for this run @@ -207,7 +213,17 @@ namespace Mantid // Loop over the number of periods in the raw file, putting each period in a separate workspace for (int period = 0; period < m_numberOfPeriods; ++period) { - if (period > 0) + //skipping the first spectra in each period + skipData(file, static_cast(period * (m_numberOfSpectra + 1))); + + // check for excluded periods + if ( !isPeriodIncluded( period ) ) + { + skipPeriod( file, period ); + continue; + } + + if (period > firstPeriod) { if(localWorkspace) { @@ -216,11 +232,10 @@ namespace Mantid if (bLoadlogFiles) { + const int period_number = period + 1; //remove previous period data std::stringstream prevPeriod; - prevPeriod << "PERIOD " << (period); - //std::string prevPeriod="PERIOD "+suffix.str(); - const int period_number = period + 1; + prevPeriod << "PERIOD " << (getPreviousPeriod(period_number)); if(localWorkspace) { Run& runObj = localWorkspace->mutableRun(); @@ -255,8 +270,6 @@ namespace Mantid } }//end of separate Monitors } - //skipping the first spectra in each period - skipData(file, static_cast(period * (m_numberOfSpectra + 1))); if (bexcludeMonitors) { @@ -467,6 +480,48 @@ namespace Mantid } } + + /** + * Skip all spectra in a period. + * @param file :: -pointer to file + * @param period :: period number + */ + void LoadRaw3::skipPeriod(FILE* file,const int64_t& period) + { + for (specid_t i = 1; i <= m_numberOfSpectra; ++i) + { + int64_t histToRead = i + period * (m_numberOfSpectra + 1); + skipData(file, histToRead); + } + } + + /** Check if a period should be loaded. + * @param period :: A period to check (0-based). + */ + bool LoadRaw3::isPeriodIncluded(int period) const + { + return !isSelectedPeriods() || std::find(m_periodList.begin(), m_periodList.end(), period + 1) != m_periodList.end(); + } + + /** + * Get the period number loaded before given. + * @param :: A period number being loaded (1-based). + */ + int LoadRaw3::getPreviousPeriod(int period) const + { + if ( isSelectedPeriods() ) + { + // find period number preceding the argument in the period list + auto pitr = std::find( m_periodList.begin(), m_periodList.end(), period ); + if ( pitr == m_periodList.end() || pitr == m_periodList.begin() ) + { + throw std::logic_error("Unexpected period number found."); + } + return *(--pitr); + } + return period - 1; + } + /// This sets the optional property to the LoadRawHelper class void LoadRaw3::setOptionalProperties() { @@ -474,7 +529,18 @@ namespace Mantid m_spec_list = getProperty("SpectrumList"); m_spec_max = getProperty("SpectrumMax"); m_spec_min = getProperty("SpectrumMin"); - + m_periodList = getProperty("PeriodList"); + if ( !m_periodList.empty() ) + { + // periods will be expected in ascending order + std::sort( m_periodList.begin(), m_periodList.end() ); + // check that the periods are within their range: 1 <= p <= m_numberOfPeriods + auto minmaxPair = std::minmax_element(m_periodList.begin(), m_periodList.end()); + if (*minmaxPair.first < 1 || *minmaxPair.second > m_numberOfPeriods ) + { + throw std::runtime_error("Values in PeriodList must be between 1 and total number of periods."); + } + } } /// This sets the progress taking account of progress time taken up by ChildAlgorithms diff --git a/Code/Mantid/Framework/DataHandling/test/LoadRaw3Test.h b/Code/Mantid/Framework/DataHandling/test/LoadRaw3Test.h index 3ce15e85d20b..e07e53026eba 100644 --- a/Code/Mantid/Framework/DataHandling/test/LoadRaw3Test.h +++ b/Code/Mantid/Framework/DataHandling/test/LoadRaw3Test.h @@ -972,6 +972,45 @@ class LoadRaw3Test : public CxxTest::TestSuite AnalysisDataService::Instance().remove(outputSpace); } + void test_loading_selected_periods() + { + LoadRaw3 loadAllPeriods; + loadAllPeriods.initialize(); + loadAllPeriods.setProperty("Filename", "CSP78173.raw"); + loadAllPeriods.setProperty("OutputWorkspace","allPeriods"); + loadAllPeriods.execute(); + auto allPeriods = AnalysisDataService::Instance().retrieveWS("allPeriods"); + TS_ASSERT_EQUALS( allPeriods->getNumberOfEntries(), 12 ); + + LoadRaw3 loadSelectedPeriods; + loadSelectedPeriods.initialize(); + loadSelectedPeriods.setProperty("Filename", "CSP78173.raw"); + loadSelectedPeriods.setProperty("OutputWorkspace","selectedPeriods"); + loadSelectedPeriods.setProperty("PeriodList","1,3-5"); + loadSelectedPeriods.execute(); + auto selectedPeriods = AnalysisDataService::Instance().retrieveWS("selectedPeriods"); + TS_ASSERT_EQUALS( selectedPeriods->getNumberOfEntries(), 4 ); + TS_ASSERT( AnalysisDataService::Instance().doesExist("selectedPeriods_1") ); + TS_ASSERT( AnalysisDataService::Instance().doesExist("selectedPeriods_3") ); + TS_ASSERT( AnalysisDataService::Instance().doesExist("selectedPeriods_4") ); + TS_ASSERT( AnalysisDataService::Instance().doesExist("selectedPeriods_5") ); + TS_ASSERT( ! AnalysisDataService::Instance().doesExist("selectedPeriods_2") ); + TS_ASSERT( ! AnalysisDataService::Instance().doesExist("selectedPeriods_6") ); + TS_ASSERT( ! AnalysisDataService::Instance().doesExist("selectedPeriods_7") ); + TS_ASSERT( ! AnalysisDataService::Instance().doesExist("selectedPeriods_8") ); + TS_ASSERT( ! AnalysisDataService::Instance().doesExist("selectedPeriods_9") ); + TS_ASSERT( ! AnalysisDataService::Instance().doesExist("selectedPeriods_10") ); + TS_ASSERT( ! AnalysisDataService::Instance().doesExist("selectedPeriods_11") ); + TS_ASSERT( ! AnalysisDataService::Instance().doesExist("selectedPeriods_12") ); + + TS_ASSERT_EQUALS( checkWorkspacesMatch( allPeriods->getItem(0), selectedPeriods->getItem(0) ), "" ); + TS_ASSERT_EQUALS( checkWorkspacesMatch( allPeriods->getItem(2), selectedPeriods->getItem(1) ), "" ); + TS_ASSERT_EQUALS( checkWorkspacesMatch( allPeriods->getItem(3), selectedPeriods->getItem(2) ), "" ); + TS_ASSERT_EQUALS( checkWorkspacesMatch( allPeriods->getItem(4), selectedPeriods->getItem(3) ), "" ); + + AnalysisDataService::Instance().clear(); + } + private: /// Helper method to run common set of tests on a workspace in a multi-period group. @@ -993,6 +1032,53 @@ class LoadRaw3Test : public CxxTest::TestSuite TSM_ASSERT_THROWS_NOTHING("period number series could not be found.", run.getLogData(stream.str())); } + /// Check that two matrix workspaces match + std::string checkWorkspacesMatch( Workspace_sptr workspace1, Workspace_sptr workspace2 ) + { + auto ws1 = boost::dynamic_pointer_cast( workspace1 ); + auto ws2 = boost::dynamic_pointer_cast( workspace2 ); + if ( !ws1 || !ws2 ) + { + return "At least one of the workspaces is not a MatrixWorkspace."; + } + if ( ws1->getNumberHistograms() != ws2->getNumberHistograms() ) + { + return "Workspaces have different numbers of histograms."; + } + if ( ws1->blocksize() != ws2->blocksize() ) + { + return "Workspaces have different numbers of bins."; + } + for(size_t i = 0; i < ws1->getNumberHistograms(); ++i) + { + auto &x1 = ws1->readX(i); + auto &x2 = ws2->readX(i); + if ( ! std::equal( x1.begin(), x1.end(), x2.begin() ) ) + { + return "Mismatch in x-values."; + } + auto &y1 = ws1->readY(i); + auto &y2 = ws2->readY(i); + if ( ! std::equal( y1.begin(), y1.end(), y2.begin() ) ) + { + return "Mismatch in y-values."; + } + auto &e1 = ws1->readE(i); + auto &e2 = ws2->readE(i); + if ( ! std::equal( e1.begin(), e1.end(), e2.begin() ) ) + { + return "Mismatch in error values."; + } + } + auto & ws1logs = ws1->run().getLogData(); + auto & ws2logs = ws2->run().getLogData(); + if ( ws1logs.size() != ws2logs.size() ) + { + return "Different numbers of logs"; + } + return ""; + } + LoadRaw3 loader,loader2,loader3; std::string inputFile; std::string outputSpace; diff --git a/Code/Mantid/MantidQt/CustomDialogs/src/LoadRawDialog.cpp b/Code/Mantid/MantidQt/CustomDialogs/src/LoadRawDialog.cpp index 7a5aabf135ce..ce126c57199a 100644 --- a/Code/Mantid/MantidQt/CustomDialogs/src/LoadRawDialog.cpp +++ b/Code/Mantid/MantidQt/CustomDialogs/src/LoadRawDialog.cpp @@ -96,19 +96,31 @@ void LoadRawDialog::initLayout() prop_line->addWidget(new QLabel("Start:")); prop_line->addWidget(text_field); tie(text_field, "SpectrumMin", prop_line); + text_field = new QLineEdit; text_field->setMaximumWidth(m_wsBox->fontMetrics().width("888888")); prop_line->addWidget(new QLabel("End:")); prop_line->addWidget(text_field); tie(text_field, "SpectrumMax", prop_line); + text_field = new QLineEdit; prop_line->addWidget(new QLabel("List:")); - prop_line->addWidget(text_field); - + prop_line->addWidget(text_field); tie(text_field, "SpectrumList", prop_line); + prop_line->addStretch(); groupbox->setLayout(prop_line); main_layout->addWidget(groupbox); + + //------------- Period properties --------------------- + prop_line = new QHBoxLayout; + text_field = new QLineEdit; + prop_line->addWidget(new QLabel("Periods:")); + prop_line->addWidget(text_field); + prop_line->addStretch(); + tie(text_field, "PeriodList", prop_line); + + main_layout->addLayout(prop_line); //------------- Cache option , log files options and Monitors Options --------------------- diff --git a/Code/Mantid/docs/source/algorithms/LoadRaw-v3.rst b/Code/Mantid/docs/source/algorithms/LoadRaw-v3.rst index 2c5dca8e16ad..cfb1bd677809 100644 --- a/Code/Mantid/docs/source/algorithms/LoadRaw-v3.rst +++ b/Code/Mantid/docs/source/algorithms/LoadRaw-v3.rst @@ -36,7 +36,10 @@ after the first one will have the period number appended (e.g. OutputWorkspace\_period). Each workspace will share the same `Instrument `__, SpectraToDetectorMap and `Sample `__ objects. If the optional 'spectrum' properties are -set for a multiperiod dataset, then they will ignored. +set for a multiperiod dataset, then they will be ignored. + +If PeriodList property isn't empty then only periods listed there will be +loaded. Subalgorithms used ##################