/** Executes the algorithm. Reading in the file and creating and populating
 *  the output workspace
 *
 *  @throw Exception::FileError If the Nexus file cannot be found/opened
 *  @throw std::invalid_argument If the optional properties are set to invalid
 *values
 */
void LoadTOFRawNexus::exec() {
  // The input properties
  std::string filename = getPropertyValue("Filename");
  m_signalNo = getProperty("Signal");
  m_spec_min = getProperty("SpectrumMin");
  m_spec_max = getProperty("SpectrumMax");

  // Find the entry name we want.
  std::string entry_name = LoadTOFRawNexus::getEntryName(filename);

  // Count pixels and other setup
  auto prog = new Progress(this, 0.0, 1.0, 10);
  prog->doReport("Counting pixels");
  std::vector<std::string> bankNames;
  countPixels(filename, entry_name, bankNames);
  g_log.debug() << "Workspace found to have " << m_numPixels << " pixels and "
                << m_numBins << " bins" << std::endl;

  prog->setNumSteps(bankNames.size() + 5);

  prog->doReport("Creating workspace");
  // Start with a dummy WS just to hold the logs and load the instrument
  MatrixWorkspace_sptr WS = WorkspaceFactory::Instance().create(
      "Workspace2D", m_numPixels, m_numBins + 1, m_numBins);

  // Load the logs
  prog->doReport("Loading DAS logs");
  g_log.debug() << "Loading DAS logs" << std::endl;

  int nPeriods = 1; // Unused
  std::unique_ptr<const TimeSeriesProperty<int>> periodLog(
      new const TimeSeriesProperty<int>("period_log")); // Unused
  LoadEventNexus::runLoadNexusLogs<MatrixWorkspace_sptr>(
      filename, WS, *this, false, nPeriods, periodLog);

  // Load the instrument
  prog->report("Loading instrument");
  g_log.debug() << "Loading instrument" << std::endl;
  LoadEventNexus::runLoadInstrument<MatrixWorkspace_sptr>(filename, WS,
                                                          entry_name, this);

  // Load the meta data, but don't stop on errors
  prog->report("Loading metadata");
  g_log.debug() << "Loading metadata" << std::endl;
  try {
    LoadEventNexus::loadEntryMetadata(filename, WS, entry_name);
  } catch (std::exception &e) {
    g_log.warning() << "Error while loading meta data: " << e.what()
                    << std::endl;
  }

  // Set the spectrum number/detector ID at each spectrum. This is consistent
  // with LoadEventNexus for non-ISIS files.
  prog->report("Building Spectra Mapping");
  g_log.debug() << "Building Spectra Mapping" << std::endl;
  WS->rebuildSpectraMapping(false);
  // And map ID to WI
  g_log.debug() << "Mapping ID to WI" << std::endl;
  const auto id_to_wi = WS->getDetectorIDToWorkspaceIndexMap();

  // Load each bank sequentially
  // PARALLEL_FOR1(WS)
  for (auto bankName : bankNames) {
    //    PARALLEL_START_INTERUPT_REGION
    prog->report("Loading bank " + bankName);
    g_log.debug() << "Loading bank " << bankName << std::endl;
    loadBank(filename, entry_name, bankName, WS, id_to_wi);
    //    PARALLEL_END_INTERUPT_REGION
  }
  //  PARALLEL_CHECK_INTERUPT_REGION

  // Set some units
  if (m_xUnits == "Ang")
    WS->getAxis(0)->setUnit("dSpacing");
  else if (m_xUnits == "invAng")
    WS->getAxis(0)->setUnit("MomentumTransfer");
  else
    // Default to TOF for any other string
    WS->getAxis(0)->setUnit("TOF");
  WS->setYUnit("Counts");

  // Set to the output
  setProperty("OutputWorkspace", WS);

  delete prog;
}