"README.md" did not exist on "6ca0b0ec05b805f9e08dffc4c6ea126c6baba902"
Newer
Older
Campbell, Stuart
committed
filter_time_start = Kernel::DateAndTime::minimum();
filter_time_stop = Kernel::DateAndTime::maximum();
if (pulseTimes.size() > 0)
{
//If not specified, use the limits of doubles. Otherwise, convert from seconds to absolute PulseTime
if (filter_time_start_sec != EMPTY_DBL())
{
filter_time_start = run_start + filter_time_start_sec;
Campbell, Stuart
committed
is_time_filtered = true;
}
if (filter_time_stop_sec != EMPTY_DBL())
{
filter_time_stop = run_start + filter_time_stop_sec;
Campbell, Stuart
committed
is_time_filtered = true;
}
//Silly values?
if (filter_time_stop < filter_time_start)
Gigg, Martyn Anthony
committed
{
std::string msg = "Your ";
if(monitors) msg += "monitor ";
msg += "filter for time's Stop value is smaller than the Start value.";
throw std::invalid_argument(msg);
}
Campbell, Stuart
committed
}
//Count the limits to time of flight
shortest_tof = static_cast<double>(std::numeric_limits<uint32_t>::max()) * 0.1;
longest_tof = 0.;
Janik Zikovsky
committed
Progress * prog2 = new Progress(this,0.3,1.0, bankNames.size()*3);
Campbell, Stuart
committed
Janik Zikovsky
committed
// Make the thread pool
ThreadScheduler * scheduler = new ThreadSchedulerLargestCost();
Janik Zikovsky
committed
ThreadPool pool(scheduler, 8);
Janik Zikovsky
committed
Mutex * diskIOMutex = new Mutex();
Gigg, Martyn Anthony
committed
for (size_t i=0; i < bankNames.size(); i++)
Campbell, Stuart
committed
{
Janik Zikovsky
committed
// We make tasks for loading
Gigg, Martyn Anthony
committed
pool.schedule( new LoadBankFromDiskTask(this,m_top_entry_name,bankNames[i],classType, pixelID_to_wi_map, prog2, diskIOMutex, scheduler) );
Campbell, Stuart
committed
}
Janik Zikovsky
committed
// Start and end all threads
pool.joinAll();
Janik Zikovsky
committed
delete diskIOMutex;
Janik Zikovsky
committed
delete prog2;
Campbell, Stuart
committed
Janik Zikovsky
committed
Campbell, Stuart
committed
//Don't need the map anymore.
delete pixelID_to_wi_map;
Campbell, Stuart
committed
if (is_time_filtered)
{
//Now filter out the run, using the DateAndTime type.
WS->mutableRun().filterByTime(filter_time_start, filter_time_stop);
}
//Info reporting
g_log.information() << "Read " << WS->getNumberEvents() << " events"
<< ". Shortest TOF: " << shortest_tof << " microsec; longest TOF: "
<< longest_tof << " microsec." << std::endl;
Janik Zikovsky
committed
if (shortest_tof < 0)
g_log.warning() << "The shortest TOF was negative! At least 1 event has an invalid time-of-flight." << std::endl;
Campbell, Stuart
committed
//Now, create a default X-vector for histogramming, with just 2 bins.
Kernel::cow_ptr<MantidVec> axis;
MantidVec& xRef = axis.access();
xRef.resize(2);
xRef[0] = shortest_tof - 1; //Just to make sure the bins hold it all
xRef[1] = longest_tof + 1;
//Set the binning axis using this.
WS->setAllX(axis);
// set more properties on the workspace
loadEntryMetadata(m_filename, WS, m_top_entry_name);
Gigg, Martyn Anthony
committed
}
Campbell, Stuart
committed
Gigg, Martyn Anthony
committed
//-----------------------------------------------------------------------------
/**
* Create a blank event workspace
* @returns A shared pointer to a new empty EventWorkspace object
*/
EventWorkspace_sptr LoadEventNexus::createEmptyEventWorkspace()
{
// 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);
Campbell, Stuart
committed
Gigg, Martyn Anthony
committed
// Set the units
eventWS->getAxis(0)->unit() = UnitFactory::Instance().create("TOF");
eventWS->setYUnit("Counts");
Janik Zikovsky
committed
Gigg, Martyn Anthony
committed
// Create a default "Universal" goniometer in the Run object
eventWS->mutableRun().getGoniometer().makeUniversalGoniometer();
return eventWS;
Campbell, Stuart
committed
}
//-----------------------------------------------------------------------------
Janik Zikovsky
committed
/** Load the run number and other meta data from the given bank */
void LoadEventNexus::loadEntryMetadata(const std::string &nexusfilename, Mantid::API::MatrixWorkspace_sptr WS,
const std::string &entry_name)
{
Campbell, Stuart
committed
// Open the file
::NeXus::File file(nexusfilename);
Campbell, Stuart
committed
file.openGroup(entry_name, "NXentry");
// get the title
file.openData("title");
if (file.getInfo().type == ::NeXus::CHAR) {
string title = file.getStrData();
if (!title.empty())
WS->setTitle(title);
}
file.closeData();
Janik Zikovsky
committed
// Get the run number
Campbell, Stuart
committed
file.openData("run_number");
string run("");
if (file.getInfo().type == ::NeXus::CHAR) {
run = file.getStrData();
}
if (!run.empty()) {
WS->mutableRun().addProperty("run_number", run);
}
file.closeData();
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
// get the duration
file.openData("duration");
std::vector<double> duration;
file.getDataCoerce(duration);
if (duration.size() == 1)
{
// get the units
std::vector<AttrInfo> infos = file.getAttrInfos();
std::string units("");
for (std::vector<AttrInfo>::const_iterator it = infos.begin(); it != infos.end(); it++)
{
if (it->name.compare("units") == 0)
{
units = file.getStrAttr(*it);
break;
}
}
// set the property
WS->mutableRun().addProperty("duration", duration[0], units);
}
file.closeData();
Campbell, Stuart
committed
// close the file
file.close();
}
//-----------------------------------------------------------------------------
Janik Zikovsky
committed
/** Load the instrument geometry file using info in the NXS file.
*
Campbell, Stuart
committed
* @param nexusfilename :: Used to pick the instrument.
* @param localWorkspace :: MatrixWorkspace in which to put the instrument geometry
Janik Zikovsky
committed
* @param top_entry_name :: entry name at the top of the NXS file
* @return true if successful
Campbell, Stuart
committed
*/
Janik Zikovsky
committed
bool LoadEventNexus::runLoadInstrument(const std::string &nexusfilename, MatrixWorkspace_sptr localWorkspace,
const std::string & top_entry_name, Algorithm * alg)
Campbell, Stuart
committed
{
Janik Zikovsky
committed
string instrument = "";
Campbell, Stuart
committed
// Get the instrument name
::NeXus::File nxfile(nexusfilename);
//Start with the base entry
Janik Zikovsky
committed
nxfile.openGroup(top_entry_name, "NXentry");
Campbell, Stuart
committed
// Open the instrument
nxfile.openGroup("instrument", "NXinstrument");
Janik Zikovsky
committed
try
{
Campbell, Stuart
committed
nxfile.openData("name");
instrument = nxfile.getStrData();
Janik Zikovsky
committed
alg->getLogger().debug() << "Instrument name read from NeXus file is " << instrument << std::endl;
Janik Zikovsky
committed
}
catch ( ::NeXus::Exception & e)
{
// Get the instrument name from the file instead
size_t n = nexusfilename.rfind('/');
if (n != std::string::npos)
{
std::string temp = nexusfilename.substr(n+1, nexusfilename.size()-n-1);
n = temp.find('_');
if (n != std::string::npos && n > 0)
{
instrument = temp.substr(0, n);
}
}
}
Campbell, Stuart
committed
if (instrument.compare("POWGEN3") == 0) // hack for powgen b/c of bad long name
Gigg, Martyn Anthony
committed
instrument = "POWGEN";
Janik Zikovsky
committed
if (instrument.compare("NOM") == 0) // hack for nomad
instrument = "NOMAD";
if (instrument.empty())
throw std::runtime_error("Could not find the instrument name in the NXS file or using the filename. Cannot load instrument!");
Campbell, Stuart
committed
// Now let's close the file as we don't need it anymore to load the instrument.
nxfile.close();
// do the actual work
Janik Zikovsky
committed
IAlgorithm_sptr loadInst= alg->createSubAlgorithm("LoadInstrument");
Campbell, Stuart
committed
// Now execute the sub-algorithm. Catch and log any error, but don't stop.
bool executionSuccessful(true);
try
{
loadInst->setPropertyValue("InstrumentName", instrument);
loadInst->setProperty<MatrixWorkspace_sptr> ("Workspace", localWorkspace);
Gigg, Martyn Anthony
committed
loadInst->setProperty("RewriteSpectraMap", false);
Campbell, Stuart
committed
loadInst->execute();
// Populate the instrument parameters in this workspace - this works around a bug
localWorkspace->populateInstrumentParameters();
} catch (std::invalid_argument& e)
{
Janik Zikovsky
committed
alg->getLogger().information() << "Invalid argument to LoadInstrument sub-algorithm : " << e.what() << std::endl;
Campbell, Stuart
committed
executionSuccessful = false;
} catch (std::runtime_error& e)
{
Janik Zikovsky
committed
alg->getLogger().information("Unable to successfully run LoadInstrument sub-algorithm");
alg->getLogger().information(e.what());
Campbell, Stuart
committed
executionSuccessful = false;
}
// If loading instrument definition file fails
if (!executionSuccessful)
{
Janik Zikovsky
committed
alg->getLogger().error() << "Error loading Instrument definition file\n";
Campbell, Stuart
committed
}
Janik Zikovsky
committed
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
return executionSuccessful;
}
//-----------------------------------------------------------------------------
/** Load the sample logs from the NXS file
*
* @param nexusfilename :: Used to pick the instrument.
* @param localWorkspace :: MatrixWorkspace in which to put the logs
* @param[out] pulseTimes :: vector of pulse times to fill
* @return true if successful
*/
bool LoadEventNexus::runLoadNexusLogs(const std::string &nexusfilename, API::MatrixWorkspace_sptr localWorkspace,
std::vector<Kernel::DateAndTime> & pulseTimes, Algorithm * alg)
{
// --------------------- Load DAS Logs -----------------
//The pulse times will be empty if not specified in the DAS logs.
pulseTimes.clear();
IAlgorithm_sptr loadLogs = alg->createSubAlgorithm("LoadNexusLogs");
// Now execute the sub-algorithm. Catch and log any error, but don't stop.
try
{
alg->getLogger().information() << "Loading logs from NeXus file..." << endl;
loadLogs->setPropertyValue("Filename", nexusfilename);
loadLogs->setProperty<MatrixWorkspace_sptr> ("Workspace", localWorkspace);
loadLogs->execute();
//If successful, we can try to load the pulse times
Freddie Akeroyd
committed
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
Kernel::TimeSeriesProperty<double> * log = 0;
// Freddie Akeroyd 11/10/2011
// current ISIS implementation contains an additional indirection between collected frames via an
// "event_frame_number" array in NXevent_data (which eliminates frames with no events).
// the proton_log is for all frames and so is longer than the event_index array, so we need to
// filter the proton_charge log based on event_frame_number
// This difference will be removed in future for compatibility with SNS, but the code below will allow current SANS2D files to load
std::vector<int> event_frame_number;
if (localWorkspace->mutableRun().hasProperty("proton_log"))
{
log = dynamic_cast<Kernel::TimeSeriesProperty<double> *>( localWorkspace->mutableRun().getProperty("proton_log") );
alg->getLogger().information() << "Using old ISIS proton_log and event_frame_number indirection..." << endl;
::NeXus::File file(nexusfilename);
try
{
file.openPath("/raw_data_1/detector_1_events/event_frame_number");
file.getData(event_frame_number);
}
catch(const ::NeXus::Exception& exc)
{
alg->getLogger().error() << "Unable to load event_frame_number: " << exc.what() << endl;
}
file.close();
}
else
{
log = dynamic_cast<Kernel::TimeSeriesProperty<double> *>( localWorkspace->mutableRun().getProperty("proton_charge") );
}
Janik Zikovsky
committed
std::vector<Kernel::DateAndTime> temp = log->timesAsVector();
pulseTimes.reserve(temp.size());
Janik Zikovsky
committed
// Warn if the pulse time found is below a minimum
size_t numBadTimes = 0;
Kernel::DateAndTime minDate("1991-01-01");
Freddie Akeroyd
committed
if (event_frame_number.size() > 0) // ISIS indirection - see above comments
{
Mantid::Kernel::DateAndTime tval;
for (size_t i =0; i < event_frame_number.size(); i++)
{
tval = temp[ event_frame_number[i] ];
pulseTimes.push_back( tval );
if (tval < minDate)
numBadTimes++;
}
}
else
{
for (size_t i =0; i < temp.size(); i++)
{
pulseTimes.push_back( temp[i] );
if (temp[i] < minDate)
numBadTimes++;
}
}
Janik Zikovsky
committed
Janik Zikovsky
committed
if (numBadTimes > 0)
alg->getLogger().warning() << "Found " << numBadTimes << " entries in the proton_charge sample log with invalid pulse time!\n";
Janik Zikovsky
committed
// Use the first pulse as the run_start time.
if (temp.size() > 0)
{
Kernel::DateAndTime run_start = localWorkspace->getFirstPulseTime();
// add the start of the run as a ISO8601 date/time string. The start = first non-zero time.
// (this is used in LoadInstrument to find the right instrument file to use).
Janik Zikovsky
committed
localWorkspace->mutableRun().addProperty("run_start", run_start.to_ISO8601_string(), true );
}
else
alg->getLogger().warning() << "Empty proton_charge sample log. You will not be able to filter by time.\n";
}
catch (...)
Campbell, Stuart
committed
{
Janik Zikovsky
committed
alg->getLogger().error() << "Error while loading Logs from SNS Nexus. Some sample logs may be missing." << std::endl;
return false;
Campbell, Stuart
committed
}
Janik Zikovsky
committed
return true;
Campbell, Stuart
committed
}
Janik Zikovsky
committed
Gigg, Martyn Anthony
committed
//-----------------------------------------------------------------------------
/**
* Create the required spectra mapping. If the file contains an isis_vms_compat block then
* the mapping is read from there, otherwise a 1:1 map with the instrument is created (along
* with the associated spectra axis)
* @param nxsfile :: The name of a nexus file to load the mapping from
* @param workspace :: The workspace to contain the spectra mapping
* @param bankName :: An optional bank name for loading a single bank
*/
void LoadEventNexus::createSpectraMapping(const std::string &nxsfile,
Janik Zikovsky
committed
API::MatrixWorkspace_sptr workspace, const bool monitorsOnly,
const std::string & bankName)
Gigg, Martyn Anthony
committed
{
Geometry::ISpectraDetectorMap *spectramap(NULL);
Gigg, Martyn Anthony
committed
this->event_id_is_spec = false;
Gigg, Martyn Anthony
committed
if( !monitorsOnly && !bankName.empty() )
Gigg, Martyn Anthony
committed
{
// Only build the map for the single bank
Russell Taylor
committed
std::vector<IDetector_const_sptr> dets;
Gigg, Martyn Anthony
committed
WS->getInstrument()->getDetectorsInBank(dets, bankName);
if (dets.size() > 0)
{
SpectraDetectorMap *singlebank = new API::SpectraDetectorMap;
// Make an event list for each.
for(size_t wi=0; wi < dets.size(); wi++)
{
const detid_t detID = dets[wi]->getID();
Gigg, Martyn Anthony
committed
singlebank->addSpectrumEntries(specid_t(wi+1), std::vector<detid_t>(1, detID));
Gigg, Martyn Anthony
committed
}
spectramap = singlebank;
g_log.debug() << "Populated spectra map for single bank " << bankName << "\n";
}
else
throw std::runtime_error("Could not find the bank named " + bankName + " as a component assembly in the instrument tree; or it did not contain any detectors.");
}
Gigg, Martyn Anthony
committed
else
Gigg, Martyn Anthony
committed
{
Janik Zikovsky
committed
spectramap = loadSpectraMapping(nxsfile, WS->getInstrument(), monitorsOnly, m_top_entry_name, g_log);
Gigg, Martyn Anthony
committed
// Did we load one? If so then the event ID is the spectrum number and not det ID
if( spectramap ) this->event_id_is_spec = true;
Gigg, Martyn Anthony
committed
}
Gigg, Martyn Anthony
committed
Gigg, Martyn Anthony
committed
if( !spectramap )
{
Gigg, Martyn Anthony
committed
g_log.debug() << "No custom spectra mapping found, continuing with default 1:1 mapping of spectrum:detectorID\n";
Gigg, Martyn Anthony
committed
// The default 1:1 will suffice but exclude the monitors as they are always in a separate workspace
workspace->rebuildSpectraMapping(false);
g_log.debug() << "Populated 1:1 spectra map for the whole instrument \n";
}
else
{
workspace->replaceAxis(1, new API::SpectraAxis(spectramap->nSpectra(), *spectramap));
Janik Zikovsky
committed
workspace->replaceSpectraMap(spectramap);
Gigg, Martyn Anthony
committed
}
}
Gigg, Martyn Anthony
committed
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
//-----------------------------------------------------------------------------
/**
* Returns whether the file contains monitors with events in them
* @returns True if the file contains monitors with event data, false otherwise
*/
bool LoadEventNexus::hasEventMonitors()
{
bool result(false);
// Determine whether to load histograms or events
try
{
::NeXus::File file(m_filename);
file.openPath(m_top_entry_name);
//Start with the base entry
typedef std::map<std::string,std::string> string_map_t;
//Now we want to go through and find the monitors
string_map_t entries = file.getEntries();
for( string_map_t::const_iterator it = entries.begin(); it != entries.end(); ++it)
{
if( it->second == "NXmonitor" )
{
file.openGroup(it->first, it->second);
break;
}
}
file.openData("event_id");
result = true;
file.close();
}
catch(::NeXus::Exception &)
{
result = false;
}
return result;
}
//-----------------------------------------------------------------------------
Campbell, Stuart
committed
/**
* Load the Monitors from the NeXus file into a workspace. The original
* workspace name is used and appended with _monitors.
*/
void LoadEventNexus::runLoadMonitors()
{
std::string mon_wsname = this->getProperty("OutputWorkspace");
mon_wsname.append("_monitors");
Gigg, Martyn Anthony
committed
IAlgorithm_sptr loadMonitors = this->createSubAlgorithm("LoadNexusMonitors");
Campbell, Stuart
committed
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
try
{
this->g_log.information() << "Loading monitors from NeXus file..."
<< std::endl;
loadMonitors->setPropertyValue("Filename", m_filename);
this->g_log.information() << "New workspace name for monitors: "
<< mon_wsname << std::endl;
loadMonitors->setPropertyValue("OutputWorkspace", mon_wsname);
loadMonitors->execute();
MatrixWorkspace_sptr mons = loadMonitors->getProperty("OutputWorkspace");
this->declareProperty(new WorkspaceProperty<>("MonitorWorkspace",
mon_wsname, Direction::Output), "Monitors from the Event NeXus file");
this->setProperty("MonitorWorkspace", mons);
}
catch (...)
{
this->g_log.error() << "Error while loading the monitors from the file. "
<< "File may contain no monitors." << std::endl;
}
}
Gigg, Martyn Anthony
committed
//
/**
* Load a spectra mapping from the given file. This currently checks for the existence of
* an isis_vms_compat block in the file, if it exists it pulls out the spectra mapping listed there
* @param file :: A filename
Gigg, Martyn Anthony
committed
* @param monitorsOnly :: If true then only the monitor spectra are loaded
Janik Zikovsky
committed
* @param entry_name :: name of the NXentry to open.
Gigg, Martyn Anthony
committed
* @returns A pointer to a new map or NULL if the block does not exist
Gigg, Martyn Anthony
committed
*/
Russell Taylor
committed
Geometry::ISpectraDetectorMap * LoadEventNexus::loadSpectraMapping(const std::string & filename, Geometry::Instrument_const_sptr inst,
Janik Zikovsky
committed
const bool monitorsOnly, const std::string entry_name, Mantid::Kernel::Logger & g_log)
Gigg, Martyn Anthony
committed
{
::NeXus::File file(filename);
try
{
Janik Zikovsky
committed
g_log.debug() << "Attempting to load custom spectra mapping from '" << entry_name << "/isis_vms_compat'.\n";
file.openPath(entry_name + "/isis_vms_compat");
Gigg, Martyn Anthony
committed
}
catch(::NeXus::Exception&)
{
Gigg, Martyn Anthony
committed
return NULL; // Doesn't exist
Gigg, Martyn Anthony
committed
}
API::SpectraDetectorMap *spectramap = new API::SpectraDetectorMap;
// UDET
file.openData("UDET");
std::vector<int32_t> udet;
file.getData(udet);
file.closeData();
// SPEC
file.openData("SPEC");
std::vector<int32_t> spec;
file.getData(spec);
file.closeData();
// Close
file.closeGroup();
file.close();
Gigg, Martyn Anthony
committed
// The spec array will contain a spectrum number for each udet but the spectrum number
Gigg, Martyn Anthony
committed
// may be the same for more that one detector
const size_t ndets(udet.size());
if( ndets != spec.size() )
Gigg, Martyn Anthony
committed
{
std::ostringstream os;
Gigg, Martyn Anthony
committed
os << "UDET/SPEC list size mismatch. UDET=" << udet.size() << ", SPEC=" << spec.size() << "\n";
Gigg, Martyn Anthony
committed
throw std::runtime_error(os.str());
}
Gigg, Martyn Anthony
committed
// Monitor filtering/selection
Janik Zikovsky
committed
const std::vector<detid_t> monitors = inst->getMonitors();
Gigg, Martyn Anthony
committed
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
if( monitorsOnly )
{
g_log.debug() << "Loading only monitor spectra from " << filename << "\n";
// Find the det_ids in the udet array.
const size_t nmons(monitors.size());
for( size_t i = 0; i < nmons; ++i )
{
// Find the index in the udet array
const detid_t & id = monitors[i];
std::vector<int32_t>::const_iterator it = std::find(udet.begin(), udet.end(), id);
if( it != udet.end() )
{
const specid_t & specNo = spec[it - udet.begin()];
spectramap->addSpectrumEntries(specid_t(specNo), std::vector<detid_t>(1, id));
}
}
}
else
{
g_log.debug() << "Loading only detector spectra from " << filename << "\n";
// We need to filter the monitors out as they are included in the block also. Here we assume that they
// occur in a contiguous block
spectramap->populate(spec.data(), udet.data(), ndets,
std::set<detid_t>(monitors.begin(), monitors.end()));
}
Gigg, Martyn Anthony
committed
g_log.debug() << "Found " << spectramap->nSpectra() << " unique spectra and a total of " << spectramap->nElements() << " elements\n";
Gigg, Martyn Anthony
committed
return spectramap;
Gigg, Martyn Anthony
committed
}
Gigg, Martyn Anthony
committed
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
/**
* Set the filters on TOF.
* @param monitors :: If true check the monitor properties else use the standard ones
*/
void LoadEventNexus::setTimeFilters(const bool monitors)
{
//Get the limits to the filter
std::string prefix("Filter");
if(monitors) prefix += "Mon";
filter_tof_min = getProperty(prefix + "ByTofMin");
filter_tof_max = getProperty(prefix + "ByTofMax");
if ( (filter_tof_min == EMPTY_DBL()) || (filter_tof_max == EMPTY_DBL()))
{
//Nothing specified. Include everything
filter_tof_min = -1e20;
filter_tof_max = +1e20;
}
else if ( (filter_tof_min != EMPTY_DBL()) || (filter_tof_max != EMPTY_DBL()))
{
//Both specified. Keep these values
}
else
{
std::string msg("You must specify both min & max or neither TOF filters");
if(monitors) msg = " for the monitors.";
throw std::invalid_argument(msg);
}
}
Campbell, Stuart
committed
} // namespace DataHandling
Campbell, Stuart
committed
} // namespace Mantid