Newer
Older
Gigg, Martyn Anthony
committed
//----------------------
// Includes
//----------------------
#include "MantidQtCustomInterfaces/SANSRunWindow.h"
Gigg, Martyn Anthony
committed
#include "MantidQtCustomInterfaces/SANSUtilityDialogs.h"
Gigg, Martyn Anthony
committed
Gigg, Martyn Anthony
committed
#include "MantidKernel/ConfigService.h"
Gigg, Martyn Anthony
committed
#include "MantidKernel/Logger.h"
#include "MantidKernel/Exception.h"
#include "MantidAPI/FrameworkManager.h"
#include "MantidAPI/IAlgorithm.h"
Gigg, Martyn Anthony
committed
#include "MantidAPI/AnalysisDataService.h"
Gigg, Martyn Anthony
committed
#include "MantidAPI/MatrixWorkspace.h"
Gigg, Martyn Anthony
committed
#include "MantidAPI/WorkspaceGroup.h"
Gigg, Martyn Anthony
committed
#include "MantidAPI/IInstrument.h"
#include "MantidAPI/SpectraDetectorMap.h"
Gigg, Martyn Anthony
committed
#include "MantidGeometry/IObjComponent.h"
#include "MantidGeometry/V3D.h"
Gigg, Martyn Anthony
committed
Gigg, Martyn Anthony
committed
#include <QLineEdit>
#include <QFileDialog>
#include <QHash>
Gigg, Martyn Anthony
committed
#include <QTextStream>
Gigg, Martyn Anthony
committed
#include <QTreeWidgetItem>
Gigg, Martyn Anthony
committed
#include <QSettings>
Gigg, Martyn Anthony
committed
#include <QHBoxLayout>
#include <QMessageBox>
#include <QInputDialog>
#include <QRegExp>
Gigg, Martyn Anthony
committed
#include <QSignalMapper>
Gigg, Martyn Anthony
committed
//Add this class to the list of specialised dialogs in this namespace
namespace MantidQt
{
namespace CustomInterfaces
{
DECLARE_SUBWINDOW(SANSRunWindow);
}
}
using namespace MantidQt::CustomInterfaces;
Gigg, Martyn Anthony
committed
// Initialize the logger
Mantid::Kernel::Logger& SANSRunWindow::g_log = Mantid::Kernel::Logger::get("SANSRunWindow");
//----------------------------------------------
Gigg, Martyn Anthony
committed
// Public member functions
//----------------------------------------------
Gigg, Martyn Anthony
committed
///Constructor
SANSRunWindow::SANSRunWindow(QWidget *parent) :
Gigg, Martyn Anthony
committed
UserSubWindow(parent), m_data_dir(""), m_ins_defdir(""), m_last_dir(""), m_cfg_loaded(true), m_run_no_boxes(),
Gigg, Martyn Anthony
committed
m_period_lbls(), m_pycode_loqreduce(""), m_pycode_viewmask(""), m_run_changed(false), m_force_reload(false),
m_delete_observer(*this,&SANSRunWindow::handleMantidDeleteWorkspace),
Gigg, Martyn Anthony
committed
m_logvalues(), m_maskcorrections(), m_lastreducetype(-1)
Gigg, Martyn Anthony
committed
{
Gigg, Martyn Anthony
committed
m_reducemapper = new QSignalMapper(this);
Gigg, Martyn Anthony
committed
Mantid::API::AnalysisDataService::Instance().notificationCenter.addObserver(m_delete_observer);
Gigg, Martyn Anthony
committed
}
Gigg, Martyn Anthony
committed
SANSRunWindow::~SANSRunWindow()
{
Gigg, Martyn Anthony
committed
// Seems to crash on destruction of if I don't do this
Mantid::API::AnalysisDataService::Instance().notificationCenter.removeObserver(m_delete_observer);
Gigg, Martyn Anthony
committed
saveSettings();
}
//--------------------------------------------
Gigg, Martyn Anthony
committed
// Private member functions
//--------------------------------------------
Gigg, Martyn Anthony
committed
/**
* Set up the dialog layout
*/
Gigg, Martyn Anthony
committed
void SANSRunWindow::initLayout()
{
Gigg, Martyn Anthony
committed
g_log.debug("Initializing interface layout");
Gigg, Martyn Anthony
committed
m_uiForm.setupUi(this);
//Button connections
connect(m_uiForm.data_dirBtn, SIGNAL(clicked()), this, SLOT(selectDataDir()));
connect(m_uiForm.userfileBtn, SIGNAL(clicked()), this, SLOT(selectUserFile()));
Gigg, Martyn Anthony
committed
connect(m_uiForm.load_dataBtn, SIGNAL(clicked()), this, SLOT(handleLoadButtonClick()));
connect(m_uiForm.plotBtn, SIGNAL(clicked()), this, SLOT(handlePlotButtonClick()));
Gigg, Martyn Anthony
committed
connect(m_uiForm.runcentreBtn, SIGNAL(clicked()), this, SLOT(handleRunFindCentre()));
connect(m_uiForm.saveBtn, SIGNAL(clicked()), this, SLOT(handleSaveButtonClick()));
Gigg, Martyn Anthony
committed
// Disable most things so that load is the only thing that can be done
m_uiForm.oneDBtn->setEnabled(false);
Gigg, Martyn Anthony
committed
m_uiForm.twoDBtn->setEnabled(false);
Gigg, Martyn Anthony
committed
for( int i = 1; i < 4; ++i)
{
m_uiForm.tabWidget->setTabEnabled(i, false);
}
// Connect
connect(m_uiForm.tabWidget, SIGNAL(currentChanged(int)), this, SLOT(handleTabChange(int)));
Gigg, Martyn Anthony
committed
// Reduction buttons
connect(m_uiForm.oneDBtn, SIGNAL(clicked()), m_reducemapper, SLOT(map()));
m_reducemapper->setMapping(m_uiForm.oneDBtn, "1D");
connect(m_uiForm.twoDBtn, SIGNAL(clicked()), m_reducemapper, SLOT(map()));
m_reducemapper->setMapping(m_uiForm.twoDBtn, "2D");
connect(m_reducemapper, SIGNAL(mapped(const QString &)), this, SLOT(handleReduceButtonClick(const QString &)));
connect(m_uiForm.showMaskBtn, SIGNAL(clicked()), this, SLOT(handleShowMaskButtonClick()));
connect(m_uiForm.clear_log, SIGNAL(clicked()), m_uiForm.centre_logging, SLOT(clear()));
Gigg, Martyn Anthony
committed
Gigg, Martyn Anthony
committed
//Text edit map
m_run_no_boxes.insert(0, m_uiForm.sct_sample_edit);
m_run_no_boxes.insert(1, m_uiForm.sct_can_edit);
m_run_no_boxes.insert(2, m_uiForm.sct_bkgd_edit);
m_run_no_boxes.insert(3, m_uiForm.tra_sample_edit);
m_run_no_boxes.insert(4, m_uiForm.tra_can_edit);
m_run_no_boxes.insert(5, m_uiForm.tra_bkgd_edit);
m_run_no_boxes.insert(6, m_uiForm.direct_sample_edit);
m_run_no_boxes.insert(7, m_uiForm.direct_can_edit);
m_run_no_boxes.insert(8, m_uiForm.direct_bkgd_edit);
Gigg, Martyn Anthony
committed
//Connect each box's edited signal to flag if the box's text has changed
for( int idx = 0; idx < 9; ++idx )
{
Gigg, Martyn Anthony
committed
connect(m_run_no_boxes.value(idx), SIGNAL(textEdited(const QString&)), this, SLOT(forceDataReload()));
Gigg, Martyn Anthony
committed
}
Gigg, Martyn Anthony
committed
connect(m_uiForm.smpl_offset, SIGNAL(textEdited(const QString&)), this, SLOT(forceDataReload()));
Gigg, Martyn Anthony
committed
Gigg, Martyn Anthony
committed
//Period label hash. Each label has a buddy set to its corresponding text edit field
m_period_lbls.insert(0, m_uiForm.sct_prd_tot1);
m_period_lbls.insert(1, m_uiForm.sct_prd_tot2);
m_period_lbls.insert(2, m_uiForm.sct_prd_tot3);
m_period_lbls.insert(3, m_uiForm.tra_prd_tot1);
m_period_lbls.insert(4, m_uiForm.tra_prd_tot2);
m_period_lbls.insert(5, m_uiForm.tra_prd_tot3);
m_period_lbls.insert(6, m_uiForm.direct_prd_tot1);
m_period_lbls.insert(7, m_uiForm.direct_prd_tot2);
m_period_lbls.insert(8, m_uiForm.direct_prd_tot3);
Gigg, Martyn Anthony
committed
// Full workspace names as they appear in the service
m_workspace_names.clear();
Gigg, Martyn Anthony
committed
// Combo boxes
connect(m_uiForm.wav_dw_opt, SIGNAL(currentIndexChanged(int)), this,
Gigg, Martyn Anthony
committed
SLOT(handleStepComboChange(int)));
Gigg, Martyn Anthony
committed
connect(m_uiForm.q_dq_opt, SIGNAL(currentIndexChanged(int)), this,
Gigg, Martyn Anthony
committed
SLOT(handleStepComboChange(int)));
Gigg, Martyn Anthony
committed
connect(m_uiForm.qy_dqy_opt, SIGNAL(currentIndexChanged(int)), this,
Gigg, Martyn Anthony
committed
SLOT(handleStepComboChange(int)));
Gigg, Martyn Anthony
committed
connect(m_uiForm.inst_opt, SIGNAL(currentIndexChanged(int)), this,
SLOT(handleInstrumentChange(int)));
Gigg, Martyn Anthony
committed
// file extensions
m_uiForm.file_opt->setItemData(0, ".raw");
m_uiForm.file_opt->setItemData(1, ".nxs");
Gigg, Martyn Anthony
committed
readSettings();
}
/**
* Restore previous input
*/
void SANSRunWindow::readSettings()
{
Gigg, Martyn Anthony
committed
g_log.debug("Reading settings.");
Gigg, Martyn Anthony
committed
QSettings value_store;
value_store.beginGroup("CustomInterfaces/SANSRunWindow");
m_uiForm.datadir_edit->setText(value_store.value("data_dir").toString());
m_uiForm.userfile_edit->setText(value_store.value("user_file").toString());
Gigg, Martyn Anthony
committed
m_uiForm.inst_opt->setCurrentIndex(value_store.value("instrument", 0).toInt());
m_uiForm.file_opt->setCurrentIndex(value_store.value("fileextension", 0).toInt());
Gigg, Martyn Anthony
committed
value_store.endGroup();
Gigg, Martyn Anthony
committed
//The instrument definition directory
m_ins_defdir = QString::fromStdString(Mantid::Kernel::ConfigService::Instance().getString("instrumentDefinition.directory"));
Gigg, Martyn Anthony
committed
g_log.debug() << "Found previous data directory " << m_uiForm.datadir_edit->text().toStdString()
<< "\nFound previous user mask file" << m_uiForm.userfile_edit->text().toStdString()
<< "\nFound instrument definition directory " << m_ins_defdir.toStdString() << std::endl;
Gigg, Martyn Anthony
committed
// Setup for instrument
handleInstrumentChange(m_uiForm.inst_opt->currentIndex());
Gigg, Martyn Anthony
committed
}
Gigg, Martyn Anthony
committed
/**
* Save input for future use
*/
void SANSRunWindow::saveSettings()
{
QSettings value_store;
Gigg, Martyn Anthony
committed
value_store.beginGroup("CustomInterfaces/SANSRunWindow");
Gigg, Martyn Anthony
committed
if( !m_data_dir.isEmpty() )
{
value_store.setValue("data_dir", m_data_dir);
}
if( !m_uiForm.userfile_edit->text().isEmpty() )
{
value_store.setValue("user_file", m_uiForm.userfile_edit->text());
}
value_store.setValue("instrument", m_uiForm.inst_opt->currentIndex());
value_store.setValue("fileextension", m_uiForm.file_opt->currentIndex());
Gigg, Martyn Anthony
committed
value_store.endGroup();
}
Gigg, Martyn Anthony
committed
/**
* Load the data reduction template for the LOQ analysis. It is
* currently assumed that this resides in the SANS subdirectory
* pointed to by the pythonscripts.directory config varibale in
* Mantid.properties
*/
bool SANSRunWindow::readPyReductionTemplate()
{
QDir scriptsdir(QString::fromStdString(Mantid::Kernel::ConfigService::Instance().getString("pythonscripts.directory")));
Gigg, Martyn Anthony
committed
QString reduce_script = scriptsdir.absoluteFilePath("SANS/SANSReductionGUI.py");
Gigg, Martyn Anthony
committed
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
if( !QFileInfo(reduce_script).exists() )
{
showInformationBox("Error: Unable to load template script, " + reduce_script + " does not exist");
return false;
}
QFile py_script(reduce_script);
if( !py_script.open(QIODevice::ReadOnly) )
{
showInformationBox("Error: Unable to access template script, " + reduce_script);
return false;
}
QTextStream stream(&py_script);
m_pycode_loqreduce.clear();
while( !stream.atEnd() )
{
m_pycode_loqreduce.append(stream.readLine() + "\n");
}
py_script.close();
return true;
}
/**
* Load the mask template script for LOQ. It is
* currently assumed that this resides in the SANS subdirectory
* pointed to by the pythonscripts.directory config varibale in
* Mantid.properties
*/
bool SANSRunWindow::readPyViewMaskTemplate()
{
QDir scriptsdir(QString::fromStdString(Mantid::Kernel::ConfigService::Instance().getString("pythonscripts.directory")));
QString mask_script = scriptsdir.absoluteFilePath("SANS/SANSViewMask.py");
Gigg, Martyn Anthony
committed
if( !QFileInfo(mask_script).exists() )
{
showInformationBox("Error: Unable to load template script, " + mask_script + " does not exist");
return false;
}
QFile py_script(mask_script);
if( !py_script.open(QIODevice::ReadOnly) )
{
showInformationBox("Error: Unable to access template script, " + mask_script);
return false;
}
QTextStream stream(&py_script);
m_pycode_viewmask.clear();
while( !stream.atEnd() )
{
m_pycode_viewmask.append(stream.readLine() + "\n");
}
py_script.close();
return true;
}
Gigg, Martyn Anthony
committed
/**
* Load the user file specified in the text field
* @returns Boolean indicating whether we were successful or not
*/
bool SANSRunWindow::loadUserFile()
{
QString filetext = m_uiForm.userfile_edit->text();
if( filetext.isEmpty() ) return false;
if( QFileInfo(filetext).isRelative() )
{
Gigg, Martyn Anthony
committed
filetext = QDir(m_data_dir).absoluteFilePath(filetext);
Gigg, Martyn Anthony
committed
}
Gigg, Martyn Anthony
committed
Gigg, Martyn Anthony
committed
if( !QFileInfo(filetext).exists() ) return false;
Gigg, Martyn Anthony
committed
Gigg, Martyn Anthony
committed
QFile user_file(filetext);
if( !user_file.open(QIODevice::ReadOnly) ) return false;
//Clear the def masking info table.
int mask_table_count = m_uiForm.mask_table->rowCount();
for( int i = mask_table_count - 1; i >= 0; --i )
{
m_uiForm.mask_table->removeRow(i);
}
//Set a couple of things to default values that will get overwritten if present in the file
Gigg, Martyn Anthony
committed
handleInstrumentChange(m_uiForm.inst_opt->currentIndex());
m_uiForm.dist_mod_mon->setText("-");
Gigg, Martyn Anthony
committed
m_uiForm.smpl_offset->setText("0.0");
Gigg, Martyn Anthony
committed
//Setup mask file detector corrections
m_maskcorrections.clear();
m_maskcorrections["Front_Det_Z_corr"] = 0.0;
m_maskcorrections["Front_Det_Y_corr"] = 0.0;
m_maskcorrections["Front_Det_X_corr"] = 0.0;
m_maskcorrections["Front_Det_Rot_corr"] = 0.0;
m_maskcorrections["Rear_Det_Z_corr"] = 0.0;
m_maskcorrections["Rear_Det_X_corr"] = 0.0;
QDir work_dir = QDir(m_uiForm.datadir_edit->text());
Gigg, Martyn Anthony
committed
Gigg, Martyn Anthony
committed
QTextStream stream(&user_file);
QString data;
while( !stream.atEnd() )
{
QString com_line = stream.readLine();
//Skip comments lines
if( com_line.startsWith("!") ) continue;
Gigg, Martyn Anthony
committed
if( com_line.startsWith("L/") )
{
readLimits(com_line.section("/", 1));
}
else if( com_line.startsWith("MON") )
{
//Line has the form MON/FIELD=...
QString field = com_line.section("/", 1).section("=", 0, 0);
if( field.compare("length", Qt::CaseInsensitive) == 0 )
Gigg, Martyn Anthony
committed
{
QStringList line_items = com_line.section('=',1).split(' ');
if( line_items.count() == 2 )
{
m_uiForm.dist_mod_mon->setText(line_items[0]);
m_uiForm.monitor_spec->setText(line_items[1]);
}
Gigg, Martyn Anthony
committed
}
Gigg, Martyn Anthony
committed
{
QString filepath;
if( com_line.contains(']') ) filepath = com_line.section("]", 1);
else filepath = com_line.section('=',1);
//Check for relative or absolute path
if( QFileInfo(filepath).isRelative() )
{
Gigg, Martyn Anthony
committed
filepath = QFileInfo(user_file).absoluteDir().absoluteFilePath(filepath);
if( field.compare("direct", Qt::CaseInsensitive) == 0 )
{
m_uiForm.direct_file->setText(filepath);
}
else if( field.compare("hab", Qt::CaseInsensitive) == 0 )
{
m_uiForm.hab_file->setText(filepath);
}
else if( field.compare("flat", Qt::CaseInsensitive) == 0 )
{
m_uiForm.flat_file->setText(filepath);
}
else {}
Gigg, Martyn Anthony
committed
}
}
Gigg, Martyn Anthony
committed
else if( com_line.startsWith("set centre") )
{
m_uiForm.beam_x->setText(com_line.section(' ', 2, 2));
m_uiForm.beam_y->setText(com_line.section(' ', 3, 3));
}
else if( com_line.startsWith("set scales") )
{
Gigg, Martyn Anthony
committed
m_uiForm.scale_factor->setText(com_line.section(' ', 2, 2));
Gigg, Martyn Anthony
committed
}
else if( com_line.startsWith("mask", Qt::CaseInsensitive) )
{
QString col1_txt(""), col2_txt("");
QString type = com_line.section(' ',1);
//TIME mask - MASK/T start end
if( com_line.startsWith("mask/t", Qt::CaseInsensitive) )
Gigg, Martyn Anthony
committed
{
col1_txt = "Time";
Gigg, Martyn Anthony
committed
col2_txt = type;
Gigg, Martyn Anthony
committed
}
else
Gigg, Martyn Anthony
committed
{
if( type.startsWith('s', Qt::CaseInsensitive) )
col1_txt = "Spectrum";
col2_txt = type;
else if( type.startsWith('h', Qt::CaseInsensitive) || type.startsWith('v', Qt::CaseInsensitive) )
if( type.contains('+') )
{
col1_txt = "Box";
}
else
{
col1_txt = "Strip";
}
col2_txt = type;
else continue;
Gigg, Martyn Anthony
committed
}
int row = m_uiForm.mask_table->rowCount();
Gigg, Martyn Anthony
committed
//Insert line after last row
m_uiForm.mask_table->insertRow(row);
Gigg, Martyn Anthony
committed
QTableWidgetItem *item1 = new QTableWidgetItem(col1_txt);
QTableWidgetItem *item2 = new QTableWidgetItem(col2_txt);
m_uiForm.mask_table->setItem(row, 0, item1);
m_uiForm.mask_table->setItem(row, 1, item2);
Gigg, Martyn Anthony
committed
}
Gigg, Martyn Anthony
committed
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
else if( com_line.startsWith("DET/CORR", Qt::CaseInsensitive) )
{
QString det = com_line.section(' ',1, 1);
QString axis = com_line.section(' ',2, 2);
double value = com_line.section(' ',3, 3).toDouble();
QString key;
if( det.compare("rear", Qt::CaseInsensitive) == 0 )
{
if( axis.compare("x", Qt::CaseInsensitive) == 0 )
{
key = "Rear_Det_X_corr";
}
else
{
key = "Rear_Det_Z_corr";
}
}
else
{
if( axis.compare("x", Qt::CaseInsensitive) == 0 )
{
key = "Front_Det_X_corr";
}
else if( axis.compare("y", Qt::CaseInsensitive) == 0 )
{
key = "Front_Det_Y_corr";
}
else if( axis.compare("z", Qt::CaseInsensitive) == 0 )
{
key = "Front_Det_Z_corr";
}
else
{
key = "Front_Det_Rot_corr";
}
}
m_maskcorrections[key] = value;
}
else if(com_line.startsWith("SAMPLE/OFFSET"))
{
QString txt = com_line.section(' ', 1, 1);
m_uiForm.smpl_offset->setText(txt);
}
Gigg, Martyn Anthony
committed
else {}
Gigg, Martyn Anthony
committed
}
user_file.close();
Gigg, Martyn Anthony
committed
Gigg, Martyn Anthony
committed
// Phi values default to -90 and 90
Gigg, Martyn Anthony
committed
m_uiForm.phi_min->setText("-90");
m_uiForm.phi_max->setText("90");
Gigg, Martyn Anthony
committed
Gigg, Martyn Anthony
committed
m_cfg_loaded = true;
m_uiForm.userfileBtn->setText("Reload");
Gigg, Martyn Anthony
committed
m_uiForm.tabWidget->setTabEnabled(m_uiForm.tabWidget->count() - 1, true);
Gigg, Martyn Anthony
committed
// m_uiForm.tabWidget->setTabEnabled(1, true);
Gigg, Martyn Anthony
committed
return true;
}
/**
* Read a limit line from the user file
* @param com_line A line from the LOQ user file that started with "L/" (note that the tag has been removed)
*/
void SANSRunWindow::readLimits(const QString & com_line)
{
QStringList pieces = com_line.split('/');
QString quantity = pieces[0].section(' ', 0, 0);
QString min = pieces[0].section(' ', 1, 1);
QString max = pieces[0].section(' ', 2, 2);
QString step = pieces[0].section(' ', 3, 3);
Gigg, Martyn Anthony
committed
//Ensure all doubles come out with a '0.' not just '.' prefix
if( min.startsWith('.') ) min.prepend('0');
if( max.startsWith('.') ) max.prepend('0');
if( step.startsWith('.') ) step.prepend('0');
Gigg, Martyn Anthony
committed
if( quantity == "R" )
{
m_uiForm.rad_min->setText(min);
m_uiForm.rad_max->setText(max);
m_uiForm.rad_dr->setText(step);
Gigg, Martyn Anthony
committed
//Add mask values to table
int row = m_uiForm.mask_table->rowCount();
Gigg, Martyn Anthony
committed
//Insert line after last row
m_uiForm.mask_table->insertRow(row);
Gigg, Martyn Anthony
committed
QTableWidgetItem *item1 = new QTableWidgetItem("Beam stop");
QTableWidgetItem *item2 = new QTableWidgetItem("infinite-cylinder");
m_uiForm.mask_table->setItem(row, 0, item1);
m_uiForm.mask_table->setItem(row, 1, item2);
m_uiForm.mask_table->insertRow(++row);
Gigg, Martyn Anthony
committed
item1 = new QTableWidgetItem("Corners");
item2 = new QTableWidgetItem("infinite-cylinder");
m_uiForm.mask_table->setItem(row, 0, item1);
m_uiForm.mask_table->setItem(row, 1, item2);
Gigg, Martyn Anthony
committed
}
else if( quantity == "SP" )
{
m_uiForm.all_spec_min->setText(min);
m_uiForm.all_spec_max->setText(max);
Gigg, Martyn Anthony
committed
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
}
else
{
int opt_index(0);
if( pieces[1].compare("log", Qt::CaseInsensitive) == 0 )
{
opt_index = 1;
}
if( quantity == "WAV" )
{
m_uiForm.wav_min->setText(min);
m_uiForm.wav_max->setText(max);
m_uiForm.wav_dw->setText(step);
m_uiForm.wav_dw_opt->setCurrentIndex(opt_index);
if( opt_index == 0 ) m_uiForm.wav_step_lbl->setText("stepping");
else m_uiForm.wav_step_lbl->setText("dW / W");
}
else if( quantity == "Q" )
{
m_uiForm.q_min->setText(min);
m_uiForm.q_max->setText(max);
m_uiForm.q_dq->setText(step);
m_uiForm.q_dq_opt->setCurrentIndex(opt_index);
if( opt_index == 0 ) m_uiForm.q_step_lbl->setText("stepping");
else m_uiForm.q_step_lbl->setText("dQ / Q");
}
else if( quantity == "QXY" )
{
m_uiForm.qy_max->setText(max);
m_uiForm.qy_dqy->setText(step);
m_uiForm.qy_dqy_opt->setCurrentIndex(opt_index);
if( opt_index == 0 ) m_uiForm.qy_step_lbl->setText("stepping");
else m_uiForm.qy_step_lbl->setText("dQy / Qy");
}
else return;
}
Gigg, Martyn Anthony
committed
}
Gigg, Martyn Anthony
committed
/**
* Retrieve and set the component distances
* @param wsname The name of the workspace
* @param lms The result of the moderator-sample distance
* @param lsda The result of the sample-detector bank 1 distance
* @param lsdb The result of the sample-detector bank 2 distance
* @param lmm The moderator-monitor distance
Gigg, Martyn Anthony
committed
*/
void SANSRunWindow::componentDistances(const QString & wsname, double & lms, double & lsda, double & lsdb, double & lmm)
Gigg, Martyn Anthony
committed
{
if( !workspaceExists(wsname) ) return;
Mantid::API::MatrixWorkspace_sptr workspace_ptr = boost::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>
Gigg, Martyn Anthony
committed
(Mantid::API::AnalysisDataService::Instance().retrieve(wsname.toStdString()));
Mantid::API::IInstrument_sptr instr = workspace_ptr->getInstrument();
Gigg, Martyn Anthony
committed
if( instr == boost::shared_ptr<Mantid::API::IInstrument>() ) return;
Mantid::Geometry::IObjComponent_sptr source = instr->getSource();
Gigg, Martyn Anthony
committed
if( source == boost::shared_ptr<Mantid::Geometry::IObjComponent>() ) return;
Mantid::Geometry::IObjComponent_sptr sample = instr->getSample();
Gigg, Martyn Anthony
committed
if( sample == boost::shared_ptr<Mantid::Geometry::IObjComponent>() ) return;
lms = source->getPos().distance(sample->getPos()) * 1000.;
Gigg, Martyn Anthony
committed
//Find the main detector bank
std::string comp_name("main-detector-bank");
bool isS2D(false);
if( m_uiForm.inst_opt->currentIndex() == 1 )
{
isS2D = true;
Gigg, Martyn Anthony
committed
comp_name = "rear-detector";
boost::shared_ptr<Mantid::Geometry::IComponent> comp = instr->getComponentByName(comp_name);
Gigg, Martyn Anthony
committed
if( comp != boost::shared_ptr<Mantid::Geometry::IComponent>() )
{
lsda = sample->getPos().distance(comp->getPos()) * 1000.;
Gigg, Martyn Anthony
committed
}
comp_name = "HAB";
Gigg, Martyn Anthony
committed
if( isS2D ) comp_name = "front-detector";
comp = instr->getComponentByName(comp_name);
Gigg, Martyn Anthony
committed
if( comp != boost::shared_ptr<Mantid::Geometry::IComponent>() )
{
lsdb = sample->getPos().distance(comp->getPos()) * 1000.;
Gigg, Martyn Anthony
committed
}
if( lmm < 0.0 ) return;
Gigg, Martyn Anthony
committed
int monitor_spectrum = m_uiForm.monitor_spec->text().toInt();
std::vector<int> dets = workspace_ptr->spectraMap().getDetectors(monitor_spectrum);
if( dets.empty() ) return;
Mantid::Geometry::IDetector_sptr detector = instr->getDetector(dets[0]);
lmm = detector->getDistance(*source) * 1000.;
Gigg, Martyn Anthony
committed
Gigg, Martyn Anthony
committed
}
Gigg, Martyn Anthony
committed
/**
* Set the state of processing.
* @param running If we are processing then some interaction is disabled
Gigg, Martyn Anthony
committed
* @param type The reduction type, 0 = 1D and 1 = 2D
Gigg, Martyn Anthony
committed
*/
Gigg, Martyn Anthony
committed
void SANSRunWindow::setProcessingState(bool running, int type)
Gigg, Martyn Anthony
committed
{
Gigg, Martyn Anthony
committed
m_uiForm.load_dataBtn->setEnabled(!running);
m_uiForm.oneDBtn->setEnabled(!running);
m_uiForm.twoDBtn->setEnabled(!running);
m_uiForm.plotBtn->setEnabled(!running);
m_uiForm.saveBtn->setEnabled(!running);
Gigg, Martyn Anthony
committed
m_uiForm.runcentreBtn->setEnabled(!running);
Gigg, Martyn Anthony
committed
Gigg, Martyn Anthony
committed
if( running )
{
Gigg, Martyn Anthony
committed
if( type == 0 )
{
m_uiForm.oneDBtn->setText("Running ...");
}
Gigg, Martyn Anthony
committed
else if( type == 1 )
Gigg, Martyn Anthony
committed
{
m_uiForm.twoDBtn->setText("Running ...");
}
Gigg, Martyn Anthony
committed
else {}
Gigg, Martyn Anthony
committed
}
else
{
Gigg, Martyn Anthony
committed
m_uiForm.oneDBtn->setText("1D Reduce");
m_uiForm.twoDBtn->setText("2D Reduce");
Gigg, Martyn Anthony
committed
}
Gigg, Martyn Anthony
committed
for( int i = 0; i < 4; ++i)
{
if( i == m_uiForm.tabWidget->currentIndex() ) continue;
m_uiForm.tabWidget->setTabEnabled(i, !running);
}
QCoreApplication::processEvents();
Gigg, Martyn Anthony
committed
}
/**
* Does the workspace exist in the AnalysisDataService
* @param ws_name The name of the workspace
* @returns A boolean indicatingif the given workspace exists in the AnalysisDataService
*/
bool SANSRunWindow::workspaceExists(const QString & ws_name) const
{
return Mantid::API::AnalysisDataService::Instance().doesExist(ws_name.toStdString());
}
/**
* @returns A list of the currently available workspaces
*/
QStringList SANSRunWindow::currentWorkspaceList() const
{
std::set<std::string> ws_list = Mantid::API::AnalysisDataService::Instance().getObjectNames();
std::set<std::string>::const_iterator iend = ws_list.end();
QStringList current_list;
for( std::set<std::string>::const_iterator itr = ws_list.begin(); itr != iend; ++itr )
{
current_list.append(QString::fromStdString(*itr));
}
return current_list;
}
Gigg, Martyn Anthony
committed
/**
* Is the user file loaded
* @returns A boolean indicating whether the user file has been parsed in to the details tab
*/
bool SANSRunWindow::isUserFileLoaded() const
{
return m_cfg_loaded;
}
/**
* Get the path the the raw file indicated by the run number.This checks the given directory for the number
* given. Left-padding of zeroes is done as required.
Gigg, Martyn Anthony
committed
* @param data_dir The data directory
Gigg, Martyn Anthony
committed
* @param run_no The run number to search for
Gigg, Martyn Anthony
committed
* @param ext The file extension
Gigg, Martyn Anthony
committed
*/
Gigg, Martyn Anthony
committed
QString SANSRunWindow::getRawFilePath(const QString & data_dir, const QString & run_no, const QString & ext) const
Gigg, Martyn Anthony
committed
{
//Do a quick check for the existence of the file with these exact credentials
QDir directory(data_dir);
Gigg, Martyn Anthony
committed
QString prefix = m_uiForm.inst_opt->currentText();
QString filename = directory.absoluteFilePath(prefix + run_no + ext);
g_log.debug("Checking for run " + run_no.toStdString());
Gigg, Martyn Anthony
committed
if( QFileInfo(filename).exists() ) return filename;
// If nothing pad the number and check
QString padded_no = run_no.rightJustified(8, '0', true);
filename = directory.absoluteFilePath(prefix + padded_no + ext);
g_log.debug("Not found. Checking padded name " + filename.toStdString());
if( QFileInfo(filename).exists() ) return filename;
else return QString();
Gigg, Martyn Anthony
committed
}
/**
* Create the mask strings for spectra and times
Gigg, Martyn Anthony
committed
*/
void SANSRunWindow::createMaskStrings(QString & spectramask, QString & timemask) const
Gigg, Martyn Anthony
committed
{
spectramask = "";
timemask = "";
int nrows = m_uiForm.mask_table->rowCount();
Gigg, Martyn Anthony
committed
for( int r = 0; r < nrows; ++r )
{
QString detail = m_uiForm.mask_table->item(r, 1)->text();
if( detail == "infinite-cylinder" ) continue;
QString type = m_uiForm.mask_table->item(r, 0)->text();
if( type == "Time" )
{
timemask += detail + ";";
}
else
{
spectramask += detail + ",";
}
Gigg, Martyn Anthony
committed
}
QStringList guimask = m_uiForm.user_maskEdit->text().split(',');
QStringListIterator itr(guimask);
while(itr.hasNext())
{
QString item = itr.next();
if( item.startsWith('t', Qt::CaseInsensitive) )
{
timemask += item.section('t',1) + ";";
}
else
{
spectramask += item + ",";
}
}
Gigg, Martyn Anthony
committed
}
void SANSRunWindow::setupGeometryDetails()
{
// Reset the geometry box
resetGeometryDetailsBox();
const char format('f');
const int prec(3);
bool warn_user(false);
// LOQ
if( m_uiForm.inst_opt->currentIndex() == 0 )
{
QString wsname = m_workspace_names.value(0);
if( m_uiForm.sct_smp_prd->text() != "1" ) wsname += "_" + m_uiForm.sct_smp_prd->text();
// Set up distance information
double dist_ms_smp(0.0), dist_sample_mdb(0.0), dist_smp_hab(0.0), dist_mm(-1.0);
if( m_uiForm.dist_mod_mon->text() == "-" ) dist_mm = 0.0;
componentDistances(wsname, dist_ms_smp, dist_sample_mdb, dist_smp_hab, dist_mm);
m_uiForm.dist_sample_ms->setText(QString::number(dist_ms_smp, format, prec));
m_uiForm.dist_smp_mdb->setText(QString::number(dist_sample_mdb, format, prec));
m_uiForm.dist_smp_hab->setText(QString::number(dist_smp_hab, format, prec));
if( dist_mm > 0.0 )
{
m_uiForm.dist_mod_mon->setText(QString::number(dist_mm, format, prec));
}
wsname = m_workspace_names.value(1);
if( m_uiForm.sct_can_prd->text() != "1" ) wsname += "_" + m_uiForm.sct_can_prd->text();
double dist_ms_can(0.0), dist_can_mdb(0.0), dist_sd2_can(0.0);
// We only need the moderator-monitor from the sample so -1.0 flags not to calculate it
dist_mm = -1.0;
componentDistances(wsname, dist_ms_can, dist_can_mdb, dist_sd2_can, dist_mm);
m_uiForm.dist_can_ms->setText(QString::number(dist_ms_can, format, prec));
m_uiForm.dist_can_mdb->setText(QString::number(dist_can_mdb, format, prec));
m_uiForm.dist_can_hab->setText(QString::number(dist_sd2_can, format, prec));
if( dist_ms_can > 0.0 && abs(dist_ms_can - dist_ms_smp) > 5e-3 )
{
warn_user = true;
m_uiForm.dist_sample_ms->setText("<font color='red'>" + m_uiForm.dist_sample_ms->text() + "</font>");
m_uiForm.dist_can_ms->setText("<font color='red'>" + m_uiForm.dist_can_ms->text() + "</font>");
}
if( dist_can_mdb > 0.0 && abs(dist_can_mdb - dist_sample_mdb) > 5e-3 )
{
warn_user = true;
m_uiForm.dist_smp_mdb->setText("<font color='red'>" + m_uiForm.dist_smp_mdb->text() + "</font>");
m_uiForm.dist_can_mdb->setText("<font color='red'>" + m_uiForm.dist_can_mdb->text() + "</font>");
}
if( dist_sd2_can > 0.0 && abs(dist_sd2_can - dist_smp_hab) > 5e-3 )
{
warn_user = true;
m_uiForm.dist_smp_hab->setText("<font color='red'>" + m_uiForm.dist_smp_hab->text() + "</font>");
m_uiForm.dist_can_hab->setText("<font color='red'>" + m_uiForm.dist_can_hab->text() + "</font>");
}
wsname = m_workspace_names.value(2);
if( m_uiForm.sct_bkgd_prd->text() != "1" ) wsname += "_" + m_uiForm.sct_bkgd_prd->text();
double dist_ms_bckd(0.0), dist_sd1_bckd(0.0), dist_sd2_bckd(0.0);
componentDistances(wsname, dist_ms_bckd, dist_sd1_bckd, dist_sd2_bckd, dist_mm);
m_uiForm.dist_bkgd_ms->setText(QString::number(dist_ms_bckd, format, prec));
m_uiForm.dist_bkgd_mdb->setText(QString::number(dist_sd1_bckd, format, prec));
m_uiForm.dist_bkgd_hab->setText(QString::number(dist_sd2_bckd, format, prec));
QString wsname = m_workspace_names.value(0);
if( m_uiForm.sct_smp_prd->text() != "1" ) wsname += "_" + m_uiForm.sct_smp_prd->text();
double dummy(0.0), dist_ms_smp(0.0), dist_mm(-1.0);
if( m_uiForm.dist_mon_s2d->text() == "-" ) dist_mm = 0.0;
componentDistances(wsname, dist_ms_smp, dummy, dummy, dist_mm);
m_uiForm.dist_sample_ms_s2d->setText(QString::number(dist_ms_smp, format, prec));
if( dist_mm > 0.0 )
{
m_uiForm.dist_mon_s2d->setText(QString::number(dist_mm, format, prec));
}
//Sample run
//rear X
double smp_rearX = m_logvalues.value("Rear_Det_X") + m_maskcorrections.value("Rear_Det_X_corr");
m_uiForm.dist_smp_rearX->setText(formatDouble(smp_rearX, format, prec, "black"));
//rear Z
double smp_rearZ = m_logvalues.value("Rear_Det_Z") + m_maskcorrections.value("Rear_Det_Z_corr");
m_uiForm.dist_smp_rearZ->setText(formatDouble(smp_rearZ, format, prec, "black"));
//front X
double smp_frontX = m_logvalues.value("Front_Det_X") + m_maskcorrections.value("Front_Det_X_corr");
m_uiForm.dist_smp_frontX->setText(QString::number(smp_frontX, format, prec));
//front Z
double smp_frontZ = m_logvalues.value("Front_Det_Z") + m_maskcorrections.value("Front_Det_Z_corr");
m_uiForm.dist_smp_frontZ->setText(QString::number(smp_frontZ, format, prec));
//front rot
double smp_rot = m_logvalues.value("Front_Det_Rot") + m_maskcorrections.value("Front_Det_Rot_corr");
m_uiForm.smp_rot->setText(QString::number(smp_rot, format, prec));
wsname = m_workspace_names.value(1);
if( !wsname.isEmpty() )
if( m_uiForm.sct_can_prd->text() != "1" ) wsname += "_" + m_uiForm.sct_can_prd->text();
dist_ms_smp = 0.0;
dummy = -1.0;
componentDistances(wsname, dist_ms_smp, dummy, dummy, dummy);
m_uiForm.dist_can_ms_s2d->setText(QString::number(dist_ms_smp, format, prec));
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
//Get log values for this workspace
QHash<QString, double> logs = loadDetectorLogs(QDir(m_uiForm.datadir_edit->text()).absolutePath(), m_uiForm.sct_can_edit->text());
//rear X
double can_rearX = logs.value("Rear_Det_X") + m_maskcorrections.value("Rear_Det_X_corr");
//Check for differences above 5mm with sample
if( std::fabs(smp_rearX - can_rearX) > 5e-3 )
{
warn_user = true;
m_uiForm.dist_can_rearX->setText(formatDouble(can_rearX, format, prec, "red"));
m_uiForm.dist_smp_rearX->setText(formatDouble(smp_rearX, format, prec, "red"));
}
else
{
m_uiForm.dist_can_rearX->setText(formatDouble(can_rearX, format, prec, "black"));
}
//rear Z
double can_rearZ = logs.value("Rear_Det_Z") + m_maskcorrections.value("Rear_Det_Z_corr");
if( std::fabs(smp_rearZ - can_rearZ) > 5e-3 )
{
warn_user = true;
m_uiForm.dist_can_rearZ->setText(formatDouble(can_rearZ, format, prec, "red"));
m_uiForm.dist_smp_rearZ->setText(formatDouble(smp_rearZ, format, prec, "red"));
}
else
{
m_uiForm.dist_can_rearZ->setText(formatDouble(can_rearZ, format, prec, "black"));
}
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
//front X
double can_frontX = logs.value("Front_Det_X") + m_maskcorrections.value("Front_Det_X_corr");
if( std::fabs(smp_frontX - can_frontX) > 5e-3 )
{
warn_user = true;
m_uiForm.dist_can_frontX->setText(formatDouble(can_frontX, format, prec, "red"));
m_uiForm.dist_smp_frontX->setText(formatDouble(smp_frontX, format, prec, "red"));
}
else
{
m_uiForm.dist_can_frontX->setText(formatDouble(can_frontX, format, prec, "black"));
}
//front Z
double can_frontZ = logs.value("Front_Det_Z") + m_maskcorrections.value("Front_Det_Z_corr");
if( std::fabs(smp_frontZ - can_frontZ) > 5e-3 )
{
warn_user = true;
m_uiForm.dist_can_frontZ->setText(formatDouble(can_frontZ, format, prec, "red"));
m_uiForm.dist_smp_frontZ->setText(formatDouble(smp_frontZ, format, prec, "red"));
}
else
{
m_uiForm.dist_can_frontZ->setText(formatDouble(can_frontZ, format, prec, "black"));
}
//front rot
double can_rot = logs.value("Front_Det_Rot") + m_maskcorrections.value("Front_Det_Rot_corr");
if( std::fabs(smp_rot - can_rot) > 5e-3 )
{
warn_user = true;
m_uiForm.can_rot->setText(formatDouble(can_rot, format, prec, "red"));
m_uiForm.smp_rot->setText(formatDouble(smp_rot, format, prec, "red"));
}
else
{
m_uiForm.can_rot->setText(formatDouble(can_rot, format, prec, "black"));
}
}
// Background
wsname = m_workspace_names.value(2);
if( !wsname.isEmpty() )
if( m_uiForm.sct_bkgd_prd->text() != "1" ) wsname += "_" + m_uiForm.sct_bkgd_prd->text();
dist_ms_smp = 0.0;
componentDistances(wsname, dist_ms_smp, dummy, dummy, dummy);
m_uiForm.dist_bkgd_ms_s2d->setText(QString::number(dist_ms_smp, format, prec));
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
//Get log values for this workspace
QHash<QString, double> logs = loadDetectorLogs(QDir(m_uiForm.datadir_edit->text()).absolutePath(), m_uiForm.sct_bkgd_edit->text());
//rear X
double bkgd_rearX = logs.value("Rear_Det_X") + m_maskcorrections.value("Rear_Det_X_corr");
//Check for differences above 5mm with sample
if( std::fabs(smp_rearX - bkgd_rearX) > 5e-3 )
{
warn_user = true;
m_uiForm.dist_bkgd_rearX->setText(formatDouble(bkgd_rearX, format, prec, "red"));
m_uiForm.dist_smp_rearX->setText(formatDouble(smp_rearX, format, prec, "red"));
}
else
{
m_uiForm.dist_bkgd_rearX->setText(formatDouble(bkgd_rearX, format, prec, "black"));
}
//rear Z
double bkgd_rearZ = logs.value("Rear_Det_Z") + m_maskcorrections.value("Rear_Det_Z_corr");
if( std::fabs(smp_rearZ - bkgd_rearZ) > 5e-3 )
{
warn_user = true;
m_uiForm.dist_bkgd_rearZ->setText(formatDouble(bkgd_rearZ, format, prec, "red"));
m_uiForm.dist_smp_rearZ->setText(formatDouble(smp_rearZ, format, prec, "red"));
}
else
{
m_uiForm.dist_bkgd_rearZ->setText(formatDouble(bkgd_rearZ, format, prec, "black"));
}
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
//front X
double bkgd_frontX = logs.value("Front_Det_X") + m_maskcorrections.value("Front_Det_X_corr");
if( std::fabs(smp_frontX - bkgd_frontX) > 5e-3 )
{
warn_user = true;
m_uiForm.dist_bkgd_frontX->setText(formatDouble(bkgd_frontX, format, prec, "red"));
m_uiForm.dist_smp_frontX->setText(formatDouble(smp_frontX, format, prec, "red"));
}
else
{
m_uiForm.dist_bkgd_frontX->setText(formatDouble(bkgd_frontX, format, prec, "black"));
}
//front Z
double bkgd_frontZ = logs.value("Front_Det_Z") + m_maskcorrections.value("Front_Det_Z_corr");
if( std::fabs(smp_frontZ - bkgd_frontZ) > 5e-3 )
{
warn_user = true;
m_uiForm.dist_bkgd_frontZ->setText(formatDouble(bkgd_frontZ, format, prec, "red"));
m_uiForm.dist_smp_frontZ->setText(formatDouble(smp_frontZ, format, prec, "red"));
}
else
{
m_uiForm.dist_bkgd_frontZ->setText(formatDouble(bkgd_frontZ, format, prec, "black"));
}
//front rot
double bkgd_rot = logs.value("Front_Det_Rot") + m_maskcorrections.value("Front_Det_Rot_corr");
if( std::fabs(smp_rot - bkgd_rot) > 5e-3 )
{
warn_user = true;
m_uiForm.bkgd_rot->setText(formatDouble(bkgd_rot, format, prec, "red"));
m_uiForm.smp_rot->setText(formatDouble(smp_rot, format, prec, "red"));
}
else
{
m_uiForm.bkgd_rot->setText(formatDouble(bkgd_rot, format, prec, "black"));