Skip to content
Snippets Groups Projects
MDHWNexusLoadingPresenter.cpp 5.43 KiB
Newer Older
#include "MantidVatesAPI/MDHWNexusLoadingPresenter.h"
Harry Jeffery's avatar
Harry Jeffery committed
#include "MantidAPI/IMDHistoWorkspace.h"
#include "MantidVatesAPI/MDLoadingView.h"
#include "MantidVatesAPI/ProgressAction.h"
#include "MantidVatesAPI/vtkDataSetFactory.h"

#include "MantidGeometry/MDGeometry/MDGeometryXMLBuilder.h"

#include <nexus/NeXusFile.hpp>
#include <nexus/NeXusException.hpp>
#include "MantidAPI/AlgorithmManager.h"
#include <vtkUnstructuredGrid.h>

namespace Mantid
{
namespace VATES
{
/**
 * Constructor
 * @param view : MVP view
 * @param filename : name of file to load
 * @throw invalid_argument if file name is empty
 * @throw invalid_arument if view is null
 * @throw logic_error if cannot use the reader-presenter for this filetype.
 */
MDHWNexusLoadingPresenter::MDHWNexusLoadingPresenter(MDLoadingView* view, const std::string filename) : MDHWLoadingPresenter(view), m_filename(filename), m_wsTypeName("")
{
  if(this->m_filename.empty())
  {
    throw std::invalid_argument("File name is an empty string.");
  }
  if(NULL == this->m_view)
  {
    throw std::invalid_argument("View is NULL.");
  }
}

/**
 * Indicates whether this presenter is capable of handling the type of file that is attempted to be loaded.
 * @return false if the file cannot be read.
 */
bool MDHWNexusLoadingPresenter::canReadFile() const
{
  // Quick check based on extension.
  if(!canLoadFileBasedOnExtension(m_filename, ".nxs"))
  {
    return 0;
  }
  ::NeXus::File * file = NULL;

  file = new ::NeXus::File(this->m_filename);
  // MDHistoWorkspace file has a different name for the entry
  try
  {
    file->openGroup("MDHistoWorkspace", "NXentry");
    file->close();
    return 1;
  }
  catch(::NeXus::Exception &)
  {
    // If the entry name does not match, then it can't read the file.
    file->close();
    return 0;
  }
  return 0;
}

/**
 * Executes the underlying algorithm to create the MVP model.
 * @param factory : visualisation factory to use.
 * @param loadingProgressUpdate : Handler for GUI updates while algorithm progresses.
 * @param drawingProgressUpdate : Handler for GUI updates while vtkDataSetFactory::create occurs.
 */
vtkDataSet* MDHWNexusLoadingPresenter::execute(vtkDataSetFactory* factory, ProgressAction& loadingProgressUpdate, ProgressAction& drawingProgressUpdate)
{
  using namespace Mantid::API;
  using namespace Mantid::Geometry;

  if(this->shouldLoad() || !m_histoWs)
    this->loadWorkspace(loadingProgressUpdate);

  // Create visualisation in one-shot.
  vtkDataSet* visualDataSet = factory->oneStepCreate(m_histoWs, drawingProgressUpdate);

  // extractMetaData needs to be re-run here because the first execution
  // of this from ::executeLoadMetadata will not have ensured that all
  // dimensions have proper range extents set.
  this->extractMetadata(m_histoWs);
  this->appendMetadata(visualDataSet, m_histoWs->getName());
  return visualDataSet;
}

/**
 * Executes any meta-data loading required.
 */
void MDHWNexusLoadingPresenter::executeLoadMetadata()
{
  using namespace Mantid::API;
  
  if(this->shouldLoad() || !m_histoWs)
  {
    // no difference between loading just the metadata or the entire workspace.
    this->loadWorkspace();
  }
  m_wsTypeName = m_histoWs->id();
  // Call base-class extraction method.
  this->extractMetadata(m_histoWs);
}

/**
 * Destructor
 * @return
 */
MDHWNexusLoadingPresenter::~MDHWNexusLoadingPresenter()
{
  delete m_view;
}

/**
 * Getter for the workspace type name.
 * @return Workspace Type Name
 */
std::string MDHWNexusLoadingPresenter::getWorkspaceTypeName()
{
  return m_wsTypeName;
}
std::vector<int> MDHWNexusLoadingPresenter::getExtents()
{
  // Hack which only works in 3D. Needs to be updated for 4 dimensions!
  std::vector<int> extents(6, 0);

  if(this->shouldLoad() || !m_histoWs)
    this->loadWorkspace();
  if(m_histoWs)
  {
    extents[1] = m_histoWs->getDimension(0)->getNBins();
    extents[3] = m_histoWs->getDimension(1)->getNBins();
    extents[5] = m_histoWs->getDimension(2)->getNBins();
  }

  return extents;

}

void MDHWNexusLoadingPresenter::loadWorkspace()
{
  using namespace Mantid::API;
  AnalysisDataService::Instance().remove("MD_HISTO_WS_ID");

  IAlgorithm_sptr alg = AlgorithmManager::Instance().create("LoadMD");
  alg->initialize();
  alg->setPropertyValue("Filename", this->m_filename);
  alg->setPropertyValue("OutputWorkspace", "MD_HISTO_WS_ID");
  alg->setProperty("FileBackEnd", !this->m_view->getLoadInMemory()); //Load from file by default.
  alg->execute();
  Workspace_sptr result = AnalysisDataService::Instance().retrieve("MD_HISTO_WS_ID");
  m_histoWs = boost::dynamic_pointer_cast<Mantid::API::IMDHistoWorkspace>(result);
}
void MDHWNexusLoadingPresenter::loadWorkspace( ProgressAction& loadingProgressUpdate)
{
    using namespace Mantid::API;
    Poco::NObserver<ProgressAction, Mantid::API::Algorithm::ProgressNotification> observer(loadingProgressUpdate, &ProgressAction::handler);

    AnalysisDataService::Instance().remove("MD_HISTO_WS_ID");
    IAlgorithm_sptr alg = AlgorithmManager::Instance().create("LoadMD");
    alg->initialize();
    alg->setPropertyValue("Filename", this->m_filename);
    alg->setPropertyValue("OutputWorkspace", "MD_HISTO_WS_ID");
    alg->setProperty("FileBackEnd", !this->m_view->getLoadInMemory()); //Load from file by default.
    alg->addObserver(observer);
    alg->execute();
    alg->removeObserver(observer);
    Workspace_sptr result = AnalysisDataService::Instance().retrieve("MD_HISTO_WS_ID");
    m_histoWs = boost::dynamic_pointer_cast<Mantid::API::IMDHistoWorkspace>(result);